Skip to content

Commit 2b3a2c8

Browse files
joerchannashif
authored andcommitted
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]>
1 parent 6b8fbfa commit 2b3a2c8

File tree

1 file changed

+44
-36
lines changed
  • subsys/bluetooth/host

1 file changed

+44
-36
lines changed

subsys/bluetooth/host/smp.c

Lines changed: 44 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2724,6 +2724,35 @@ static uint8_t get_auth(struct bt_conn *conn, uint8_t auth)
27242724
return auth;
27252725
}
27262726

2727+
static uint8_t remote_sec_level_reachable(struct bt_smp *smp)
2728+
{
2729+
struct bt_conn *conn = smp->chan.chan.conn;
2730+
2731+
switch (conn->required_sec_level) {
2732+
case BT_SECURITY_L1:
2733+
case BT_SECURITY_L2:
2734+
return 0;
2735+
2736+
case BT_SECURITY_L4:
2737+
if (get_encryption_key_size(smp) != BT_SMP_MAX_ENC_KEY_SIZE) {
2738+
return BT_SMP_ERR_ENC_KEY_SIZE;
2739+
}
2740+
2741+
if (!atomic_test_bit(smp->flags, SMP_FLAG_SC)) {
2742+
return BT_SMP_ERR_AUTH_REQUIREMENTS;
2743+
}
2744+
__fallthrough;
2745+
case BT_SECURITY_L3:
2746+
if (smp->method == JUST_WORKS) {
2747+
return BT_SMP_ERR_AUTH_REQUIREMENTS;
2748+
}
2749+
2750+
return 0;
2751+
default:
2752+
return BT_SMP_ERR_UNSPECIFIED;
2753+
}
2754+
}
2755+
27272756
static bool sec_level_reachable(struct bt_conn *conn)
27282757
{
27292758
switch (conn->required_sec_level) {
@@ -2905,6 +2934,7 @@ static uint8_t smp_pairing_req(struct bt_smp *smp, struct net_buf *buf)
29052934
struct bt_conn *conn = smp->chan.chan.conn;
29062935
struct bt_smp_pairing *req = (void *)buf->data;
29072936
struct bt_smp_pairing *rsp;
2937+
uint8_t err;
29082938

29092939
BT_DBG("");
29102940

@@ -2982,15 +3012,17 @@ static uint8_t smp_pairing_req(struct bt_smp *smp, struct net_buf *buf)
29823012
return BT_SMP_ERR_AUTH_REQUIREMENTS;
29833013
}
29843014

3015+
err = remote_sec_level_reachable(smp);
3016+
if (err) {
3017+
return err;
3018+
}
3019+
29853020
if (!atomic_test_bit(smp->flags, SMP_FLAG_SC)) {
29863021
#if defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
29873022
return BT_SMP_ERR_AUTH_REQUIREMENTS;
29883023
#else
29893024
if (IS_ENABLED(CONFIG_BT_SMP_APP_PAIRING_ACCEPT)) {
2990-
uint8_t err;
2991-
2992-
err = smp_pairing_accept_query(smp->chan.chan.conn,
2993-
req);
3025+
err = smp_pairing_accept_query(conn, req);
29943026
if (err) {
29953027
return err;
29963028
}
@@ -3000,22 +3032,8 @@ static uint8_t smp_pairing_req(struct bt_smp *smp, struct net_buf *buf)
30003032
#endif /* CONFIG_BT_SMP_SC_PAIR_ONLY */
30013033
}
30023034

3003-
if ((IS_ENABLED(CONFIG_BT_SMP_SC_ONLY) ||
3004-
conn->required_sec_level == BT_SECURITY_L4) &&
3005-
smp->method == JUST_WORKS) {
3006-
return BT_SMP_ERR_AUTH_REQUIREMENTS;
3007-
}
3008-
3009-
if ((IS_ENABLED(CONFIG_BT_SMP_SC_ONLY) ||
3010-
conn->required_sec_level == BT_SECURITY_L4) &&
3011-
get_encryption_key_size(smp) != BT_SMP_MAX_ENC_KEY_SIZE) {
3012-
return BT_SMP_ERR_ENC_KEY_SIZE;
3013-
}
3014-
30153035
if (IS_ENABLED(CONFIG_BT_SMP_APP_PAIRING_ACCEPT)) {
3016-
uint8_t err;
3017-
3018-
err = smp_pairing_accept_query(smp->chan.chan.conn, req);
3036+
err = smp_pairing_accept_query(conn, req);
30193037
if (err) {
30203038
return err;
30213039
}
@@ -3025,7 +3043,7 @@ static uint8_t smp_pairing_req(struct bt_smp *smp, struct net_buf *buf)
30253043
!atomic_test_bit(smp->flags, SMP_FLAG_SEC_REQ) &&
30263044
bt_auth && bt_auth->pairing_confirm) {
30273045
atomic_set_bit(smp->flags, SMP_FLAG_USER);
3028-
bt_auth->pairing_confirm(smp->chan.chan.conn);
3046+
bt_auth->pairing_confirm(conn);
30293047
return 0;
30303048
}
30313049

@@ -3151,6 +3169,7 @@ static uint8_t smp_pairing_rsp(struct bt_smp *smp, struct net_buf *buf)
31513169
struct bt_conn *conn = smp->chan.chan.conn;
31523170
struct bt_smp_pairing *rsp = (void *)buf->data;
31533171
struct bt_smp_pairing *req = (struct bt_smp_pairing *)&smp->preq[1];
3172+
uint8_t err;
31543173

31553174
BT_DBG("");
31563175

@@ -3191,13 +3210,16 @@ static uint8_t smp_pairing_rsp(struct bt_smp *smp, struct net_buf *buf)
31913210
return BT_SMP_ERR_AUTH_REQUIREMENTS;
31923211
}
31933212

3213+
err = remote_sec_level_reachable(smp);
3214+
if (err) {
3215+
return err;
3216+
}
3217+
31943218
if (!atomic_test_bit(smp->flags, SMP_FLAG_SC)) {
31953219
#if defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
31963220
return BT_SMP_ERR_AUTH_REQUIREMENTS;
31973221
#else
31983222
if (IS_ENABLED(CONFIG_BT_SMP_APP_PAIRING_ACCEPT)) {
3199-
uint8_t err;
3200-
32013223
err = smp_pairing_accept_query(conn, rsp);
32023224
if (err) {
32033225
return err;
@@ -3208,24 +3230,10 @@ static uint8_t smp_pairing_rsp(struct bt_smp *smp, struct net_buf *buf)
32083230
#endif /* CONFIG_BT_SMP_SC_PAIR_ONLY */
32093231
}
32103232

3211-
if ((IS_ENABLED(CONFIG_BT_SMP_SC_ONLY) ||
3212-
conn->required_sec_level == BT_SECURITY_L4) &&
3213-
smp->method == JUST_WORKS) {
3214-
return BT_SMP_ERR_AUTH_REQUIREMENTS;
3215-
}
3216-
3217-
if ((IS_ENABLED(CONFIG_BT_SMP_SC_ONLY) ||
3218-
conn->required_sec_level == BT_SECURITY_L4) &&
3219-
get_encryption_key_size(smp) != BT_SMP_MAX_ENC_KEY_SIZE) {
3220-
return BT_SMP_ERR_ENC_KEY_SIZE;
3221-
}
3222-
32233233
smp->local_dist &= SEND_KEYS_SC;
32243234
smp->remote_dist &= RECV_KEYS_SC;
32253235

32263236
if (IS_ENABLED(CONFIG_BT_SMP_APP_PAIRING_ACCEPT)) {
3227-
uint8_t err;
3228-
32293237
err = smp_pairing_accept_query(conn, rsp);
32303238
if (err) {
32313239
return err;

0 commit comments

Comments
 (0)