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:
parent
3f71772555
commit
c2d62a29f0
3 changed files with 24 additions and 4 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue