Skip to content

Commit 1e8e1a8

Browse files
joerchancarlescufi
authored andcommitted
[nrf fromtree] Bluetooth: host: Fail pairing if remote cannot meet ...
required security Fail after pairing request and response have been exchanged if the selected pairing method would not result in the required security level. This avoids the case where we would discover this after having encrypted the connection and disconnect instead. This was partially attempted but lacked checking for authentication requirement when L3 was required, as well as skipping the check if L4 was required but remote did not support Secure Connections since the check was after we had taken the legacy branch. Signed-off-by: Joakim Andersson <[email protected]> (cherry picked from commit 2b3a2c8) Signed-off-by: Joakim Andersson <[email protected]>
1 parent 4be1d91 commit 1e8e1a8

File tree

1 file changed

+46
-39
lines changed
  • subsys/bluetooth/host

1 file changed

+46
-39
lines changed

subsys/bluetooth/host/smp.c

Lines changed: 46 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2697,6 +2697,35 @@ static uint8_t get_auth(struct bt_conn *conn, uint8_t auth)
26972697
return auth;
26982698
}
26992699

2700+
static uint8_t remote_sec_level_reachable(struct bt_smp *smp)
2701+
{
2702+
struct bt_conn *conn = smp->chan.chan.conn;
2703+
2704+
switch (conn->required_sec_level) {
2705+
case BT_SECURITY_L1:
2706+
case BT_SECURITY_L2:
2707+
return 0;
2708+
2709+
case BT_SECURITY_L4:
2710+
if (get_encryption_key_size(smp) != BT_SMP_MAX_ENC_KEY_SIZE) {
2711+
return BT_SMP_ERR_ENC_KEY_SIZE;
2712+
}
2713+
2714+
if (!atomic_test_bit(smp->flags, SMP_FLAG_SC)) {
2715+
return BT_SMP_ERR_AUTH_REQUIREMENTS;
2716+
}
2717+
__fallthrough;
2718+
case BT_SECURITY_L3:
2719+
if (smp->method == JUST_WORKS) {
2720+
return BT_SMP_ERR_AUTH_REQUIREMENTS;
2721+
}
2722+
2723+
return 0;
2724+
default:
2725+
return BT_SMP_ERR_UNSPECIFIED;
2726+
}
2727+
}
2728+
27002729
static bool sec_level_reachable(struct bt_conn *conn)
27012730
{
27022731
switch (conn->required_sec_level) {
@@ -2877,6 +2906,7 @@ static uint8_t smp_pairing_req(struct bt_smp *smp, struct net_buf *buf)
28772906
struct bt_conn *conn = smp->chan.chan.conn;
28782907
struct bt_smp_pairing *req = (void *)buf->data;
28792908
struct bt_smp_pairing *rsp;
2909+
uint8_t err;
28802910

28812911
BT_DBG("");
28822912

@@ -2954,15 +2984,17 @@ static uint8_t smp_pairing_req(struct bt_smp *smp, struct net_buf *buf)
29542984
return BT_SMP_ERR_AUTH_REQUIREMENTS;
29552985
}
29562986

2987+
err = remote_sec_level_reachable(smp);
2988+
if (err) {
2989+
return err;
2990+
}
2991+
29572992
if (!atomic_test_bit(smp->flags, SMP_FLAG_SC)) {
29582993
#if defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
29592994
return BT_SMP_ERR_AUTH_REQUIREMENTS;
29602995
#else
29612996
if (IS_ENABLED(CONFIG_BT_SMP_APP_PAIRING_ACCEPT)) {
2962-
uint8_t err;
2963-
2964-
err = smp_pairing_accept_query(smp->chan.chan.conn,
2965-
req);
2997+
err = smp_pairing_accept_query(conn, req);
29662998
if (err) {
29672999
return err;
29683000
}
@@ -2972,22 +3004,8 @@ static uint8_t smp_pairing_req(struct bt_smp *smp, struct net_buf *buf)
29723004
#endif /* CONFIG_BT_SMP_SC_PAIR_ONLY */
29733005
}
29743006

2975-
if ((IS_ENABLED(CONFIG_BT_SMP_SC_ONLY) ||
2976-
conn->required_sec_level == BT_SECURITY_L4) &&
2977-
smp->method == JUST_WORKS) {
2978-
return BT_SMP_ERR_AUTH_REQUIREMENTS;
2979-
}
2980-
2981-
if ((IS_ENABLED(CONFIG_BT_SMP_SC_ONLY) ||
2982-
conn->required_sec_level == BT_SECURITY_L4) &&
2983-
get_encryption_key_size(smp) != BT_SMP_MAX_ENC_KEY_SIZE) {
2984-
return BT_SMP_ERR_ENC_KEY_SIZE;
2985-
}
2986-
29873007
if (IS_ENABLED(CONFIG_BT_SMP_APP_PAIRING_ACCEPT)) {
2988-
uint8_t err;
2989-
2990-
err = smp_pairing_accept_query(smp->chan.chan.conn, req);
3008+
err = smp_pairing_accept_query(conn, req);
29913009
if (err) {
29923010
return err;
29933011
}
@@ -2997,7 +3015,7 @@ static uint8_t smp_pairing_req(struct bt_smp *smp, struct net_buf *buf)
29973015
!atomic_test_bit(smp->flags, SMP_FLAG_SEC_REQ) &&
29983016
bt_auth && bt_auth->pairing_confirm) {
29993017
atomic_set_bit(smp->flags, SMP_FLAG_USER);
3000-
bt_auth->pairing_confirm(smp->chan.chan.conn);
3018+
bt_auth->pairing_confirm(conn);
30013019
return 0;
30023020
}
30033021

@@ -3116,6 +3134,7 @@ static uint8_t smp_pairing_rsp(struct bt_smp *smp, struct net_buf *buf)
31163134
struct bt_conn *conn = smp->chan.chan.conn;
31173135
struct bt_smp_pairing *rsp = (void *)buf->data;
31183136
struct bt_smp_pairing *req = (struct bt_smp_pairing *)&smp->preq[1];
3137+
uint8_t err;
31193138

31203139
BT_DBG("");
31213140

@@ -3156,15 +3175,17 @@ static uint8_t smp_pairing_rsp(struct bt_smp *smp, struct net_buf *buf)
31563175
return BT_SMP_ERR_AUTH_REQUIREMENTS;
31573176
}
31583177

3178+
err = remote_sec_level_reachable(smp);
3179+
if (err) {
3180+
return err;
3181+
}
3182+
31593183
if (!atomic_test_bit(smp->flags, SMP_FLAG_SC)) {
31603184
#if defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
31613185
return BT_SMP_ERR_AUTH_REQUIREMENTS;
31623186
#else
31633187
if (IS_ENABLED(CONFIG_BT_SMP_APP_PAIRING_ACCEPT)) {
3164-
uint8_t err;
3165-
3166-
err = smp_pairing_accept_query(smp->chan.chan.conn,
3167-
rsp);
3188+
err = smp_pairing_accept_query(conn, rsp);
31683189
if (err) {
31693190
return err;
31703191
}
@@ -3174,25 +3195,11 @@ static uint8_t smp_pairing_rsp(struct bt_smp *smp, struct net_buf *buf)
31743195
#endif /* CONFIG_BT_SMP_SC_PAIR_ONLY */
31753196
}
31763197

3177-
if ((IS_ENABLED(CONFIG_BT_SMP_SC_ONLY) ||
3178-
conn->required_sec_level == BT_SECURITY_L4) &&
3179-
smp->method == JUST_WORKS) {
3180-
return BT_SMP_ERR_AUTH_REQUIREMENTS;
3181-
}
3182-
3183-
if ((IS_ENABLED(CONFIG_BT_SMP_SC_ONLY) ||
3184-
conn->required_sec_level == BT_SECURITY_L4) &&
3185-
get_encryption_key_size(smp) != BT_SMP_MAX_ENC_KEY_SIZE) {
3186-
return BT_SMP_ERR_ENC_KEY_SIZE;
3187-
}
3188-
31893198
smp->local_dist &= SEND_KEYS_SC;
31903199
smp->remote_dist &= RECV_KEYS_SC;
31913200

31923201
if (IS_ENABLED(CONFIG_BT_SMP_APP_PAIRING_ACCEPT)) {
3193-
uint8_t err;
3194-
3195-
err = smp_pairing_accept_query(smp->chan.chan.conn, rsp);
3202+
err = smp_pairing_accept_query(conn, rsp);
31963203
if (err) {
31973204
return err;
31983205
}

0 commit comments

Comments
 (0)