Skip to content

Commit 2ae9e27

Browse files
joerchannashif
authored andcommitted
Bluetooth: SMP: Re-pairing cannot lower the security level of the bond
Make sure that a new pairing procedure with an existing bond does not result in a security with weaker security properties. Signed-off-by: Joakim Andersson <[email protected]>
1 parent abe47b7 commit 2ae9e27

File tree

1 file changed

+67
-12
lines changed
  • subsys/bluetooth/host

1 file changed

+67
-12
lines changed

subsys/bluetooth/host/smp.c

Lines changed: 67 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -294,10 +294,20 @@ static u8_t get_io_capa(void)
294294
}
295295
}
296296

297+
#if !defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
298+
static u8_t legacy_get_pair_method(struct bt_smp *smp, u8_t remote_io);
299+
#endif
300+
297301
static u8_t get_pair_method(struct bt_smp *smp, u8_t remote_io)
298302
{
299303
struct bt_smp_pairing *req, *rsp;
300304

305+
#if !defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
306+
if (!atomic_test_bit(smp->flags, SMP_FLAG_SC)) {
307+
return legacy_get_pair_method(smp, remote_io);
308+
}
309+
#endif
310+
301311
if (remote_io > BT_SMP_IO_KEYBOARD_DISPLAY)
302312
return JUST_WORKS;
303313

@@ -541,6 +551,39 @@ static u8_t get_encryption_key_size(struct bt_smp *smp)
541551
return MIN(req->max_key_size, rsp->max_key_size);
542552
}
543553

554+
/* Check that if a new pairing procedure with an existing bond will not lower
555+
* the established security level of the bond.
556+
*/
557+
bool update_keys_check(struct bt_smp *smp)
558+
{
559+
struct bt_conn *conn = smp->chan.chan.conn;
560+
561+
if (!conn->le.keys) {
562+
conn->le.keys = bt_keys_get_addr(conn->id, &conn->le.dst);
563+
}
564+
565+
if (!conn->le.keys ||
566+
!(conn->le.keys->keys & (BT_KEYS_LTK_P256 | BT_KEYS_LTK))) {
567+
return true;
568+
}
569+
570+
if (conn->le.keys->enc_size > get_encryption_key_size(smp)) {
571+
return false;
572+
}
573+
574+
if ((conn->le.keys->keys & BT_KEYS_LTK_P256) &&
575+
!atomic_test_bit(smp->flags, SMP_FLAG_SC)) {
576+
return false;
577+
}
578+
579+
if ((conn->le.keys->flags & BT_KEYS_AUTHENTICATED) &&
580+
smp->method == JUST_WORKS) {
581+
return false;
582+
}
583+
584+
return true;
585+
}
586+
544587
#if defined(CONFIG_BT_PRIVACY) || defined(CONFIG_BT_SIGNING) || \
545588
!defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
546589
/* For TX callbacks */
@@ -2001,14 +2044,12 @@ static u8_t legacy_send_pairing_confirm(struct bt_smp *smp)
20012044
}
20022045

20032046
#if defined(CONFIG_BT_PERIPHERAL)
2004-
static u8_t legacy_pairing_req(struct bt_smp *smp, u8_t remote_io)
2047+
static u8_t legacy_pairing_req(struct bt_smp *smp)
20052048
{
20062049
u8_t ret;
20072050

20082051
BT_DBG("");
20092052

2010-
smp->method = legacy_get_pair_method(smp, remote_io);
2011-
20122053
/* ask for consent if pairing is not due to sending SecReq*/
20132054
if ((DISPLAY_FIXED(smp) || smp->method == JUST_WORKS) &&
20142055
!atomic_test_bit(smp->flags, SMP_FLAG_SEC_REQ) &&
@@ -2207,14 +2248,12 @@ static u8_t smp_master_ident(struct bt_smp *smp, struct net_buf *buf)
22072248
}
22082249

22092250
#if defined(CONFIG_BT_CENTRAL)
2210-
static u8_t legacy_pairing_rsp(struct bt_smp *smp, u8_t remote_io)
2251+
static u8_t legacy_pairing_rsp(struct bt_smp *smp)
22112252
{
22122253
u8_t ret;
22132254

22142255
BT_DBG("");
22152256

2216-
smp->method = legacy_get_pair_method(smp, remote_io);
2217-
22182257
/* ask for consent if this is due to received SecReq */
22192258
if ((DISPLAY_FIXED(smp) || smp->method == JUST_WORKS) &&
22202259
atomic_test_bit(smp->flags, SMP_FLAG_SEC_REQ) &&
@@ -2442,16 +2481,20 @@ static u8_t smp_pairing_req(struct bt_smp *smp, struct net_buf *buf)
24422481

24432482
atomic_set_bit(smp->flags, SMP_FLAG_PAIRING);
24442483

2484+
smp->method = get_pair_method(smp, req->io_capability);
2485+
2486+
if (!update_keys_check(smp)) {
2487+
return BT_SMP_ERR_AUTH_REQUIREMENTS;
2488+
}
2489+
24452490
if (!atomic_test_bit(smp->flags, SMP_FLAG_SC)) {
24462491
#if defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
24472492
return BT_SMP_ERR_AUTH_REQUIREMENTS;
24482493
#else
2449-
return legacy_pairing_req(smp, req->io_capability);
2494+
return legacy_pairing_req(smp);
24502495
#endif /* CONFIG_BT_SMP_SC_PAIR_ONLY */
24512496
}
24522497

2453-
smp->method = get_pair_method(smp, req->io_capability);
2454-
24552498
if ((IS_ENABLED(CONFIG_BT_SMP_SC_ONLY) ||
24562499
conn->required_sec_level == BT_SECURITY_FIPS) &&
24572500
smp->method == JUST_WORKS) {
@@ -2604,16 +2647,20 @@ static u8_t smp_pairing_rsp(struct bt_smp *smp, struct net_buf *buf)
26042647
atomic_set_bit(smp->flags, SMP_FLAG_BOND);
26052648
}
26062649

2650+
smp->method = get_pair_method(smp, rsp->io_capability);
2651+
2652+
if (!update_keys_check(smp)) {
2653+
return BT_SMP_ERR_AUTH_REQUIREMENTS;
2654+
}
2655+
26072656
if (!atomic_test_bit(smp->flags, SMP_FLAG_SC)) {
26082657
#if defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
26092658
return BT_SMP_ERR_AUTH_REQUIREMENTS;
26102659
#else
2611-
return legacy_pairing_rsp(smp, rsp->io_capability);
2660+
return legacy_pairing_rsp(smp);
26122661
#endif /* CONFIG_BT_SMP_SC_PAIR_ONLY */
26132662
}
26142663

2615-
smp->method = get_pair_method(smp, rsp->io_capability);
2616-
26172664
if ((IS_ENABLED(CONFIG_BT_SMP_SC_ONLY) ||
26182665
conn->required_sec_level == BT_SECURITY_FIPS) &&
26192666
smp->method == JUST_WORKS) {
@@ -3368,6 +3415,14 @@ static u8_t smp_public_key(struct bt_smp *smp, struct net_buf *buf)
33683415
if (memcmp(smp->pkey, sc_debug_public_key, 64) == 0) {
33693416
BT_INFO("Remote is using Debug Public key");
33703417
atomic_set_bit(smp->flags, SMP_FLAG_SC_DEBUG_KEY);
3418+
3419+
/* Don't allow a bond established without debug key to be
3420+
* updated using LTK generated from debug key.
3421+
*/
3422+
if (smp->chan.chan.conn->le.keys &&
3423+
!(smp->chan.chan.conn->le.keys->flags & BT_KEYS_DEBUG)) {
3424+
return BT_SMP_ERR_AUTH_REQUIREMENTS;
3425+
}
33713426
}
33723427

33733428
if (IS_ENABLED(CONFIG_BT_CENTRAL) &&

0 commit comments

Comments
 (0)