Bluetooth: host: Require 128-bit encryption key for security level 4.

In Bluetooth 5 the definition of LE security mode 1, has changed.
LE Security Mode 1 level 4 requires authenticated LE Secure Connections
pairing with encryption using a 128-bit strength encryption key.
This also changes the behaviour when a security request and response
would end up with a security level that is lower than the one requested.
Before pairing would complete, and the link would disconnect with error
authentication failure. Instead a SMP will abort pairing with error code
authentication requirement, or encryption key size.

Signed-off-by: Joakim Andersson <joakim.andersson@nordicsemi.no>
This commit is contained in:
Joakim Andersson 2018-10-11 15:35:55 +02:00 committed by Johan Hedberg
commit c2d62a29f0
3 changed files with 24 additions and 4 deletions

View file

@ -968,7 +968,8 @@ static int start_security(struct bt_conn *conn)
if (conn->required_sec_level > BT_SECURITY_HIGH && if (conn->required_sec_level > BT_SECURITY_HIGH &&
!(conn->le.keys->flags & BT_KEYS_AUTHENTICATED) && !(conn->le.keys->flags & BT_KEYS_AUTHENTICATED) &&
!(conn->le.keys->keys & BT_KEYS_LTK_P256)) { !(conn->le.keys->keys & BT_KEYS_LTK_P256) &&
!(conn->le.keys->enc_size == BT_SMP_MAX_ENC_KEY_SIZE)) {
return bt_smp_send_pairing_req(conn); return bt_smp_send_pairing_req(conn);
} }

View file

@ -2697,7 +2697,8 @@ static void update_sec_level(struct bt_conn *conn)
} }
if (conn->le.keys && (conn->le.keys->flags & BT_KEYS_AUTHENTICATED)) { if (conn->le.keys && (conn->le.keys->flags & BT_KEYS_AUTHENTICATED)) {
if (conn->le.keys->flags & BT_KEYS_SC) { if (conn->le.keys->flags & BT_KEYS_SC &&
conn->le.keys->enc_size == BT_SMP_MAX_ENC_KEY_SIZE) {
conn->sec_level = BT_SECURITY_FIPS; conn->sec_level = BT_SECURITY_FIPS;
} else { } else {
conn->sec_level = BT_SECURITY_HIGH; conn->sec_level = BT_SECURITY_HIGH;

View file

@ -2380,6 +2380,7 @@ int bt_smp_send_security_req(struct bt_conn *conn)
static u8_t smp_pairing_req(struct bt_smp *smp, struct net_buf *buf) static u8_t smp_pairing_req(struct bt_smp *smp, struct net_buf *buf)
{ {
struct bt_conn *conn = smp->chan.chan.conn;
struct bt_smp_pairing *req = (void *)buf->data; struct bt_smp_pairing *req = (void *)buf->data;
struct bt_smp_pairing *rsp; struct bt_smp_pairing *rsp;
@ -2449,10 +2450,18 @@ static u8_t smp_pairing_req(struct bt_smp *smp, struct net_buf *buf)
smp->method = get_pair_method(smp, req->io_capability); smp->method = get_pair_method(smp, req->io_capability);
if (IS_ENABLED(CONFIG_BT_SMP_SC_ONLY) && smp->method == JUST_WORKS) { if ((IS_ENABLED(CONFIG_BT_SMP_SC_ONLY) ||
conn->required_sec_level == BT_SECURITY_FIPS) &&
smp->method == JUST_WORKS) {
return BT_SMP_ERR_AUTH_REQUIREMENTS; return BT_SMP_ERR_AUTH_REQUIREMENTS;
} }
if ((IS_ENABLED(CONFIG_BT_SMP_SC_ONLY) ||
conn->required_sec_level == BT_SECURITY_FIPS) &&
get_encryption_key_size(smp) != BT_SMP_MAX_ENC_KEY_SIZE) {
return BT_SMP_ERR_ENC_KEY_SIZE;
}
if ((DISPLAY_FIXED(smp) || smp->method == JUST_WORKS) && if ((DISPLAY_FIXED(smp) || smp->method == JUST_WORKS) &&
!atomic_test_bit(smp->flags, SMP_FLAG_SEC_REQ) && !atomic_test_bit(smp->flags, SMP_FLAG_SEC_REQ) &&
bt_auth && bt_auth->pairing_confirm) { bt_auth && bt_auth->pairing_confirm) {
@ -2560,6 +2569,7 @@ int bt_smp_send_pairing_req(struct bt_conn *conn)
static u8_t smp_pairing_rsp(struct bt_smp *smp, struct net_buf *buf) static u8_t smp_pairing_rsp(struct bt_smp *smp, struct net_buf *buf)
{ {
struct bt_conn *conn = smp->chan.chan.conn;
struct bt_smp_pairing *rsp = (void *)buf->data; struct bt_smp_pairing *rsp = (void *)buf->data;
struct bt_smp_pairing *req = (struct bt_smp_pairing *)&smp->preq[1]; struct bt_smp_pairing *req = (struct bt_smp_pairing *)&smp->preq[1];
@ -2602,10 +2612,18 @@ static u8_t smp_pairing_rsp(struct bt_smp *smp, struct net_buf *buf)
smp->method = get_pair_method(smp, rsp->io_capability); smp->method = get_pair_method(smp, rsp->io_capability);
if (IS_ENABLED(CONFIG_BT_SMP_SC_ONLY) && smp->method == JUST_WORKS) { if ((IS_ENABLED(CONFIG_BT_SMP_SC_ONLY) ||
conn->required_sec_level == BT_SECURITY_FIPS) &&
smp->method == JUST_WORKS) {
return BT_SMP_ERR_AUTH_REQUIREMENTS; return BT_SMP_ERR_AUTH_REQUIREMENTS;
} }
if ((IS_ENABLED(CONFIG_BT_SMP_SC_ONLY) ||
conn->required_sec_level == BT_SECURITY_FIPS) &&
get_encryption_key_size(smp) != BT_SMP_MAX_ENC_KEY_SIZE) {
return BT_SMP_ERR_ENC_KEY_SIZE;
}
smp->local_dist &= SEND_KEYS_SC; smp->local_dist &= SEND_KEYS_SC;
smp->remote_dist &= RECV_KEYS_SC; smp->remote_dist &= RECV_KEYS_SC;