Skip to content

Commit 6b8fbfa

Browse files
joerchannashif
authored andcommitted
Bluetooth: host: Set error in security changed when not required level
Set the error in the security changed callback when the encryption has not reached the required security level. Terminate the pairing procedure in SMP on failure to avoid the security changed callback being called twice in this case. Signed-off-by: Joakim Andersson <[email protected]>
1 parent 09eb7e0 commit 6b8fbfa

File tree

2 files changed

+46
-23
lines changed

2 files changed

+46
-23
lines changed

subsys/bluetooth/host/hci_core.c

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3582,13 +3582,8 @@ void bt_id_del(struct bt_keys *keys)
35823582
bt_adv_foreach(adv_unpause_enabled, NULL);
35833583
}
35843584

3585-
static void update_sec_level(struct bt_conn *conn)
3585+
static bool update_sec_level(struct bt_conn *conn)
35863586
{
3587-
if (!conn->encrypt) {
3588-
conn->sec_level = BT_SECURITY_L1;
3589-
return;
3590-
}
3591-
35923587
if (conn->le.keys && (conn->le.keys->flags & BT_KEYS_AUTHENTICATED)) {
35933588
if (conn->le.keys->flags & BT_KEYS_SC &&
35943589
conn->le.keys->enc_size == BT_SMP_MAX_ENC_KEY_SIZE) {
@@ -3600,10 +3595,7 @@ static void update_sec_level(struct bt_conn *conn)
36003595
conn->sec_level = BT_SECURITY_L2;
36013596
}
36023597

3603-
if (conn->required_sec_level > conn->sec_level) {
3604-
BT_ERR("Failed to set required security level");
3605-
bt_conn_disconnect(conn, BT_HCI_ERR_AUTH_FAIL);
3606-
}
3598+
return !(conn->required_sec_level > conn->sec_level);
36073599
}
36083600
#endif /* CONFIG_BT_SMP */
36093601

@@ -3612,6 +3604,7 @@ static void hci_encrypt_change(struct net_buf *buf)
36123604
{
36133605
struct bt_hci_evt_encrypt_change *evt = (void *)buf->data;
36143606
uint16_t handle = sys_le16_to_cpu(evt->handle);
3607+
uint8_t status = evt->status;
36153608
struct bt_conn *conn;
36163609

36173610
BT_DBG("status 0x%02x handle %u encrypt 0x%02x", evt->status, handle,
@@ -3623,9 +3616,9 @@ static void hci_encrypt_change(struct net_buf *buf)
36233616
return;
36243617
}
36253618

3626-
if (evt->status) {
3627-
bt_conn_security_changed(conn, evt->status,
3628-
bt_security_err_get(evt->status));
3619+
if (status) {
3620+
bt_conn_security_changed(conn, status,
3621+
bt_security_err_get(status));
36293622
bt_conn_unref(conn);
36303623
return;
36313624
}
@@ -3645,7 +3638,10 @@ static void hci_encrypt_change(struct net_buf *buf)
36453638
if (conn->encrypt) {
36463639
bt_smp_update_keys(conn);
36473640
}
3648-
update_sec_level(conn);
3641+
3642+
if (!update_sec_level(conn)) {
3643+
status = BT_HCI_ERR_AUTH_FAIL;
3644+
}
36493645
}
36503646
#endif /* CONFIG_BT_SMP */
36513647
#if defined(CONFIG_BT_BREDR)
@@ -3668,14 +3664,20 @@ static void hci_encrypt_change(struct net_buf *buf)
36683664
}
36693665
#endif /* CONFIG_BT_BREDR */
36703666

3671-
bt_conn_security_changed(conn, evt->status, BT_SECURITY_ERR_SUCCESS);
3667+
bt_conn_security_changed(conn, status, bt_security_err_get(status));
3668+
3669+
if (status) {
3670+
BT_ERR("Failed to set required security level");
3671+
bt_conn_disconnect(conn, status);
3672+
}
36723673

36733674
bt_conn_unref(conn);
36743675
}
36753676

36763677
static void hci_encrypt_key_refresh_complete(struct net_buf *buf)
36773678
{
36783679
struct bt_hci_evt_encrypt_key_refresh_complete *evt = (void *)buf->data;
3680+
uint8_t status = evt->status;
36793681
struct bt_conn *conn;
36803682
uint16_t handle;
36813683

@@ -3689,9 +3691,9 @@ static void hci_encrypt_key_refresh_complete(struct net_buf *buf)
36893691
return;
36903692
}
36913693

3692-
if (evt->status) {
3693-
bt_conn_security_changed(conn, evt->status,
3694-
bt_security_err_get(evt->status));
3694+
if (status) {
3695+
bt_conn_security_changed(conn, status,
3696+
bt_security_err_get(status));
36953697
bt_conn_unref(conn);
36963698
return;
36973699
}
@@ -3705,7 +3707,10 @@ static void hci_encrypt_key_refresh_complete(struct net_buf *buf)
37053707
#if defined(CONFIG_BT_SMP)
37063708
if (conn->type == BT_CONN_TYPE_LE) {
37073709
bt_smp_update_keys(conn);
3708-
update_sec_level(conn);
3710+
3711+
if (!update_sec_level(conn)) {
3712+
status = BT_HCI_ERR_AUTH_FAIL;
3713+
}
37093714
}
37103715
#endif /* CONFIG_BT_SMP */
37113716
#if defined(CONFIG_BT_BREDR)
@@ -3717,7 +3722,12 @@ static void hci_encrypt_key_refresh_complete(struct net_buf *buf)
37173722
}
37183723
#endif /* CONFIG_BT_BREDR */
37193724

3720-
bt_conn_security_changed(conn, evt->status, BT_SECURITY_ERR_SUCCESS);
3725+
bt_conn_security_changed(conn, status, bt_security_err_get(status));
3726+
if (status) {
3727+
BT_ERR("Failed to set required security level");
3728+
bt_conn_disconnect(conn, status);
3729+
}
3730+
37213731
bt_conn_unref(conn);
37223732
}
37233733
#endif /* CONFIG_BT_SMP || CONFIG_BT_BREDR */

subsys/bluetooth/host/smp.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,6 @@ static enum bt_security_err security_err_get(uint8_t smp_err)
439439
}
440440
}
441441

442-
#if defined(CONFIG_BT_SMP_APP_PAIRING_ACCEPT)
443442
static uint8_t smp_err_get(enum bt_security_err auth_err)
444443
{
445444
switch (auth_err) {
@@ -464,7 +463,6 @@ static uint8_t smp_err_get(enum bt_security_err auth_err)
464463
return 0;
465464
}
466465
}
467-
#endif /* CONFIG_BT_SMP_APP_PAIRING_ACCEPT */
468466

469467
static struct net_buf *smp_create_pdu(struct bt_smp *smp, uint8_t op, size_t len)
470468
{
@@ -4536,9 +4534,24 @@ static void bt_smp_encrypt_change(struct bt_l2cap_chan *chan,
45364534
BT_DBG("chan %p conn %p handle %u encrypt 0x%02x hci status 0x%02x",
45374535
chan, conn, conn->handle, conn->encrypt, hci_status);
45384536

4539-
atomic_clear_bit(smp->flags, SMP_FLAG_ENC_PENDING);
4537+
if (!atomic_test_and_clear_bit(smp->flags, SMP_FLAG_ENC_PENDING)) {
4538+
/* We where not waiting for encryption procedure.
4539+
* This happens when encrypt change is called to notify that
4540+
* security has failed before starting encryption.
4541+
*/
4542+
return;
4543+
}
45404544

45414545
if (hci_status) {
4546+
if (atomic_test_bit(smp->flags, SMP_FLAG_PAIRING)) {
4547+
uint8_t smp_err = smp_err_get(
4548+
bt_security_err_get(hci_status));
4549+
4550+
/* Fail as if it happened during key distribution */
4551+
atomic_set_bit(smp->flags, SMP_FLAG_KEYS_DISTR);
4552+
smp_pairing_complete(smp, smp_err);
4553+
}
4554+
45424555
return;
45434556
}
45444557

0 commit comments

Comments
 (0)