Bluetooth: host: Allow to disable legacy pairing.

Add option to disable legacy pairing and only use secure connection.
If legacy pairing was requested pairing will be denied with status
insufficient authenticated

Signed-off-by: Joakim Andersson <joakim.andersson@nordicsemi.no>
This commit is contained in:
Joakim Andersson 2018-10-11 13:39:44 +02:00 committed by Johan Hedberg
commit 912cdc0b8e
4 changed files with 39 additions and 29 deletions

View file

@ -284,8 +284,18 @@ config BT_SIGNING
This option enables data signing which is used for transferring This option enables data signing which is used for transferring
authenticated data in an unencrypted connection. authenticated data in an unencrypted connection.
config BT_SMP_SC_PAIR_ONLY
bool "Disable legacy pairing"
help
This option disables LE legacy pairing and forces LE secure connection
pairing. All Security Mode 1 levels can be used with legacy pairing
disabled, but pairing with devices that do not support secure
connections pairing will not be supported.
To force a higher security level use "Secure Connections Only Mode"
config BT_SMP_SC_ONLY config BT_SMP_SC_ONLY
bool "Secure Connections Only Mode" bool "Secure Connections Only Mode"
select BT_SMP_SC_PAIR_ONLY
help help
This option enables support for Secure Connection Only Mode. In this This option enables support for Secure Connection Only Mode. In this
mode device shall only use Security Mode 1 Level 4 with exception mode device shall only use Security Mode 1 Level 4 with exception

View file

@ -2919,7 +2919,7 @@ static void le_ltk_request(struct net_buf *buf)
goto done; goto done;
} }
#if !defined(CONFIG_BT_SMP_SC_ONLY) #if !defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
if (conn->le.keys && (conn->le.keys->keys & BT_KEYS_SLAVE_LTK) && if (conn->le.keys && (conn->le.keys->keys & BT_KEYS_SLAVE_LTK) &&
!memcmp(conn->le.keys->slave_ltk.rand, &evt->rand, 8) && !memcmp(conn->le.keys->slave_ltk.rand, &evt->rand, 8) &&
!memcmp(conn->le.keys->slave_ltk.ediv, &evt->ediv, 2)) { !memcmp(conn->le.keys->slave_ltk.ediv, &evt->ediv, 2)) {
@ -2944,7 +2944,7 @@ static void le_ltk_request(struct net_buf *buf)
bt_hci_cmd_send(BT_HCI_OP_LE_LTK_REQ_REPLY, buf); bt_hci_cmd_send(BT_HCI_OP_LE_LTK_REQ_REPLY, buf);
goto done; goto done;
} }
#endif /* !CONFIG_BT_SMP_SC_ONLY */ #endif /* !CONFIG_BT_SMP_SC_PAIR_ONLY */
le_ltk_neg_reply(evt->handle); le_ltk_neg_reply(evt->handle);

View file

@ -56,9 +56,9 @@ struct bt_keys {
struct bt_csrk local_csrk; struct bt_csrk local_csrk;
struct bt_csrk remote_csrk; struct bt_csrk remote_csrk;
#endif /* BT_SIGNING */ #endif /* BT_SIGNING */
#if !defined(CONFIG_BT_SMP_SC_ONLY) #if !defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
struct bt_ltk slave_ltk; struct bt_ltk slave_ltk;
#endif /* CONFIG_BT_SMP_SC_ONLY */ #endif /* CONFIG_BT_SMP_SC_PAIR_ONLY */
}; };
#define BT_KEYS_STORAGE_LEN (sizeof(struct bt_keys) - \ #define BT_KEYS_STORAGE_LEN (sizeof(struct bt_keys) - \

View file

@ -186,7 +186,7 @@ static unsigned int fixed_passkey = BT_PASSKEY_INVALID;
fixed_passkey != BT_PASSKEY_INVALID && \ fixed_passkey != BT_PASSKEY_INVALID && \
(smp)->method == PASSKEY_DISPLAY) (smp)->method == PASSKEY_DISPLAY)
#if !defined(CONFIG_BT_SMP_SC_ONLY) #if !defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
/* based on table 2.8 Core Spec 2.3.5.1 Vol. 3 Part H */ /* based on table 2.8 Core Spec 2.3.5.1 Vol. 3 Part H */
static const u8_t gen_method_legacy[5 /* remote */][5 /* local */] = { static const u8_t gen_method_legacy[5 /* remote */][5 /* local */] = {
{ JUST_WORKS, JUST_WORKS, PASSKEY_INPUT, JUST_WORKS, PASSKEY_INPUT }, { JUST_WORKS, JUST_WORKS, PASSKEY_INPUT, JUST_WORKS, PASSKEY_INPUT },
@ -197,7 +197,7 @@ static const u8_t gen_method_legacy[5 /* remote */][5 /* local */] = {
{ PASSKEY_DISPLAY, PASSKEY_DISPLAY, PASSKEY_INPUT, JUST_WORKS, { PASSKEY_DISPLAY, PASSKEY_DISPLAY, PASSKEY_INPUT, JUST_WORKS,
PASSKEY_ROLE }, PASSKEY_ROLE },
}; };
#endif /* CONFIG_BT_SMP_SC_ONLY */ #endif /* CONFIG_BT_SMP_SC_PAIR_ONLY */
/* based on table 2.8 Core Spec 2.3.5.1 Vol. 3 Part H */ /* based on table 2.8 Core Spec 2.3.5.1 Vol. 3 Part H */
static const u8_t gen_method_sc[5 /* remote */][5 /* local */] = { static const u8_t gen_method_sc[5 /* remote */][5 /* local */] = {
@ -542,7 +542,7 @@ static u8_t get_encryption_key_size(struct bt_smp *smp)
} }
#if defined(CONFIG_BT_PRIVACY) || defined(CONFIG_BT_SIGNING) || \ #if defined(CONFIG_BT_PRIVACY) || defined(CONFIG_BT_SIGNING) || \
!defined(CONFIG_BT_SMP_SC_ONLY) !defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
/* For TX callbacks */ /* For TX callbacks */
static void smp_pairing_complete(struct bt_smp *smp, u8_t status); static void smp_pairing_complete(struct bt_smp *smp, u8_t status);
#if defined(CONFIG_BT_BREDR) #if defined(CONFIG_BT_BREDR)
@ -1607,7 +1607,7 @@ static u8_t smp_send_pairing_random(struct bt_smp *smp)
return 0; return 0;
} }
#if !defined(CONFIG_BT_SMP_SC_ONLY) #if !defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
static void xor_128(const u8_t p[16], const u8_t q[16], u8_t r[16]) static void xor_128(const u8_t p[16], const u8_t q[16], u8_t r[16])
{ {
size_t len = 16; size_t len = 16;
@ -1658,7 +1658,7 @@ static int smp_c1(const u8_t k[16], const u8_t r[16],
return bt_encrypt_le(k, enc_data, enc_data); return bt_encrypt_le(k, enc_data, enc_data);
} }
#endif /* !CONFIG_BT_SMP_SC_ONLY */ #endif /* !CONFIG_BT_SMP_SC_PAIR_ONLY */
static u8_t smp_send_pairing_confirm(struct bt_smp *smp) static u8_t smp_send_pairing_confirm(struct bt_smp *smp)
{ {
@ -1707,7 +1707,7 @@ static u8_t smp_send_pairing_confirm(struct bt_smp *smp)
return 0; return 0;
} }
#if !defined(CONFIG_BT_SMP_SC_ONLY) #if !defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
static void ident_sent(struct bt_conn *conn) static void ident_sent(struct bt_conn *conn)
{ {
smp_check_complete(conn, BT_SMP_DIST_ENC_KEY); smp_check_complete(conn, BT_SMP_DIST_ENC_KEY);
@ -1772,7 +1772,7 @@ static void legacy_distribute_keys(struct bt_smp *smp)
} }
} }
} }
#endif /* !CONFIG_BT_SMP_SC_ONLY */ #endif /* !CONFIG_BT_SMP_SC_PAIR_ONLY */
static void bt_smp_distribute_keys(struct bt_smp *smp) static void bt_smp_distribute_keys(struct bt_smp *smp)
{ {
@ -1784,12 +1784,12 @@ static void bt_smp_distribute_keys(struct bt_smp *smp)
return; return;
} }
#if !defined(CONFIG_BT_SMP_SC_ONLY) #if !defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
/* Distribute legacy pairing specific keys */ /* Distribute legacy pairing specific keys */
if (!atomic_test_bit(smp->flags, SMP_FLAG_SC)) { if (!atomic_test_bit(smp->flags, SMP_FLAG_SC)) {
legacy_distribute_keys(smp); legacy_distribute_keys(smp);
} }
#endif /* !CONFIG_BT_SMP_SC_ONLY */ #endif /* !CONFIG_BT_SMP_SC_PAIR_ONLY */
#if defined(CONFIG_BT_PRIVACY) #if defined(CONFIG_BT_PRIVACY)
if (smp->local_dist & BT_SMP_DIST_ID_KEY) { if (smp->local_dist & BT_SMP_DIST_ID_KEY) {
@ -1871,7 +1871,7 @@ static u8_t send_pairing_rsp(struct bt_smp *smp)
} }
#endif /* CONFIG_BT_PERIPHERAL */ #endif /* CONFIG_BT_PERIPHERAL */
#if !defined(CONFIG_BT_SMP_SC_ONLY) #if !defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
static int smp_s1(const u8_t k[16], const u8_t r1[16], static int smp_s1(const u8_t k[16], const u8_t r1[16],
const u8_t r2[16], u8_t out[16]) const u8_t r2[16], u8_t out[16])
{ {
@ -2250,7 +2250,7 @@ static u8_t smp_master_ident(struct bt_smp *smp, struct net_buf *buf)
{ {
return BT_SMP_ERR_CMD_NOTSUPP; return BT_SMP_ERR_CMD_NOTSUPP;
} }
#endif /* !CONFIG_BT_SMP_SC_ONLY */ #endif /* !CONFIG_BT_SMP_SC_PAIR_ONLY */
static int _smp_init(struct bt_smp *smp) static int _smp_init(struct bt_smp *smp)
{ {
@ -2439,11 +2439,11 @@ static u8_t smp_pairing_req(struct bt_smp *smp, struct net_buf *buf)
atomic_set_bit(smp->flags, SMP_FLAG_PAIRING); atomic_set_bit(smp->flags, SMP_FLAG_PAIRING);
if (!atomic_test_bit(smp->flags, SMP_FLAG_SC)) { if (!atomic_test_bit(smp->flags, SMP_FLAG_SC)) {
#if defined(CONFIG_BT_SMP_SC_ONLY) #if defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
return BT_SMP_ERR_AUTH_REQUIREMENTS; return BT_SMP_ERR_AUTH_REQUIREMENTS;
#else #else
return legacy_pairing_req(smp, req->io_capability); return legacy_pairing_req(smp, req->io_capability);
#endif /* CONFIG_BT_SMP_SC_ONLY */ #endif /* CONFIG_BT_SMP_SC_PAIR_ONLY */
} }
smp->method = get_pair_method(smp, req->io_capability); smp->method = get_pair_method(smp, req->io_capability);
@ -2592,11 +2592,11 @@ static u8_t smp_pairing_rsp(struct bt_smp *smp, struct net_buf *buf)
} }
if (!atomic_test_bit(smp->flags, SMP_FLAG_SC)) { if (!atomic_test_bit(smp->flags, SMP_FLAG_SC)) {
#if defined(CONFIG_BT_SMP_SC_ONLY) #if defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
return BT_SMP_ERR_AUTH_REQUIREMENTS; return BT_SMP_ERR_AUTH_REQUIREMENTS;
#else #else
return legacy_pairing_rsp(smp, rsp->io_capability); return legacy_pairing_rsp(smp, rsp->io_capability);
#endif /* CONFIG_BT_SMP_SC_ONLY */ #endif /* CONFIG_BT_SMP_SC_PAIR_ONLY */
} }
smp->method = get_pair_method(smp, rsp->io_capability); smp->method = get_pair_method(smp, rsp->io_capability);
@ -2651,11 +2651,11 @@ static u8_t smp_pairing_confirm(struct bt_smp *smp, struct net_buf *buf)
return 0; return 0;
} }
#if !defined(CONFIG_BT_SMP_SC_ONLY) #if !defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
if (!atomic_test_bit(smp->flags, SMP_FLAG_SC)) { if (!atomic_test_bit(smp->flags, SMP_FLAG_SC)) {
return legacy_pairing_confirm(smp); return legacy_pairing_confirm(smp);
} }
#endif /* !CONFIG_BT_SMP_SC_ONLY */ #endif /* !CONFIG_BT_SMP_SC_PAIR_ONLY */
switch (smp->method) { switch (smp->method) {
case PASSKEY_DISPLAY: case PASSKEY_DISPLAY:
@ -2900,11 +2900,11 @@ static u8_t smp_pairing_random(struct bt_smp *smp, struct net_buf *buf)
memcpy(smp->rrnd, req->val, sizeof(smp->rrnd)); memcpy(smp->rrnd, req->val, sizeof(smp->rrnd));
#if !defined(CONFIG_BT_SMP_SC_ONLY) #if !defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
if (!atomic_test_bit(smp->flags, SMP_FLAG_SC)) { if (!atomic_test_bit(smp->flags, SMP_FLAG_SC)) {
return legacy_pairing_random(smp); return legacy_pairing_random(smp);
} }
#endif /* !CONFIG_BT_SMP_SC_ONLY */ #endif /* !CONFIG_BT_SMP_SC_PAIR_ONLY */
#if defined(CONFIG_BT_CENTRAL) #if defined(CONFIG_BT_CENTRAL)
if (smp->chan.chan.conn->role == BT_HCI_ROLE_MASTER) { if (smp->chan.chan.conn->role == BT_HCI_ROLE_MASTER) {
@ -4240,12 +4240,12 @@ int bt_smp_auth_passkey_entry(struct bt_conn *conn, unsigned int passkey)
return -EINVAL; return -EINVAL;
} }
#if !defined(CONFIG_BT_SMP_SC_ONLY) #if !defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
if (!atomic_test_bit(smp->flags, SMP_FLAG_SC)) { if (!atomic_test_bit(smp->flags, SMP_FLAG_SC)) {
legacy_passkey_entry(smp, passkey); legacy_passkey_entry(smp, passkey);
return 0; return 0;
} }
#endif /* !CONFIG_BT_SMP_SC_ONLY */ #endif /* !CONFIG_BT_SMP_SC_PAIR_ONLY */
smp->passkey = sys_cpu_to_le32(passkey); smp->passkey = sys_cpu_to_le32(passkey);
@ -4346,7 +4346,7 @@ int bt_smp_auth_cancel(struct bt_conn *conn)
} }
} }
#if !defined(CONFIG_BT_SMP_SC_ONLY) #if !defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
int bt_smp_auth_pairing_confirm(struct bt_conn *conn) int bt_smp_auth_pairing_confirm(struct bt_conn *conn)
{ {
struct bt_smp *smp; struct bt_smp *smp;
@ -4398,7 +4398,7 @@ int bt_smp_auth_pairing_confirm(struct bt_conn *conn)
/* confirm_pairing will never be called in LE SC only mode */ /* confirm_pairing will never be called in LE SC only mode */
return -EINVAL; return -EINVAL;
} }
#endif /* !CONFIG_BT_SMP_SC_ONLY */ #endif /* !CONFIG_BT_SMP_SC_PAIR_ONLY */
#if defined(CONFIG_BT_FIXED_PASSKEY) #if defined(CONFIG_BT_FIXED_PASSKEY)
int bt_passkey_set(unsigned int passkey) int bt_passkey_set(unsigned int passkey)
@ -4578,8 +4578,8 @@ int bt_smp_init(void)
}; };
sc_supported = le_sc_supported(); sc_supported = le_sc_supported();
if (IS_ENABLED(CONFIG_BT_SMP_SC_ONLY) && !sc_supported) { if (IS_ENABLED(CONFIG_BT_SMP_SC_PAIR_ONLY) && !sc_supported) {
BT_ERR("SC Only Mode selected but LE SC not supported"); BT_ERR("SC Pair Only Mode selected but LE SC not supported");
return -ENOENT; return -ENOENT;
} }