Bluetooth: SMP: Fix peripheral security request with authenticated keys
The call to bt_conn_security will send a SMP security request for peripheral, and for central it will initiate LL encryption. A call to bt_conn_security with no IO capabilities but authenticated keys has been distributed, would succeed on central side, but fail on peripheral side with error code -22. The keys could have been either: - Preprogrammed - IO capabilities may have changed. - OOB bonding may been used. Fix so that Peripheral can send a security request if the bond information is already established. Signed-off-by: Joakim Andersson <joakim.andersson@nordicsemi.no>
This commit is contained in:
parent
4eb85176e3
commit
c2ee00f737
3 changed files with 35 additions and 26 deletions
|
@ -1005,33 +1005,9 @@ static int start_security(struct bt_conn *conn)
|
|||
#if defined(CONFIG_BT_CENTRAL) && defined(CONFIG_BT_SMP)
|
||||
case BT_HCI_ROLE_MASTER:
|
||||
{
|
||||
if (!conn->le.keys) {
|
||||
conn->le.keys = bt_keys_find(BT_KEYS_LTK_P256,
|
||||
conn->id, &conn->le.dst);
|
||||
if (!conn->le.keys) {
|
||||
conn->le.keys = bt_keys_find(BT_KEYS_LTK,
|
||||
conn->id,
|
||||
&conn->le.dst);
|
||||
}
|
||||
}
|
||||
|
||||
if (!conn->le.keys ||
|
||||
!(conn->le.keys->keys & (BT_KEYS_LTK | BT_KEYS_LTK_P256))) {
|
||||
if (!bt_smp_keys_check(conn)) {
|
||||
return bt_smp_send_pairing_req(conn);
|
||||
}
|
||||
|
||||
if (conn->required_sec_level > BT_SECURITY_MEDIUM &&
|
||||
!(conn->le.keys->flags & BT_KEYS_AUTHENTICATED)) {
|
||||
return bt_smp_send_pairing_req(conn);
|
||||
}
|
||||
|
||||
if (conn->required_sec_level > BT_SECURITY_HIGH &&
|
||||
!(conn->le.keys->flags & BT_KEYS_AUTHENTICATED) &&
|
||||
!(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);
|
||||
}
|
||||
|
||||
/* LE SC LTK and legacy master LTK are stored in same place */
|
||||
return bt_conn_le_start_encryption(conn,
|
||||
conn->le.keys->ltk.rand,
|
||||
|
|
|
@ -2384,7 +2384,7 @@ int bt_smp_send_security_req(struct bt_conn *conn)
|
|||
}
|
||||
|
||||
/* early verify if required sec level if reachable */
|
||||
if (!sec_level_reachable(conn)) {
|
||||
if (!(sec_level_reachable(conn) || bt_smp_keys_check(conn))) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -4845,6 +4845,38 @@ bool bt_smp_get_tk(struct bt_conn *conn, u8_t *tk)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool bt_smp_keys_check(struct bt_conn *conn)
|
||||
{
|
||||
if (!conn->le.keys) {
|
||||
conn->le.keys = bt_keys_find(BT_KEYS_LTK_P256,
|
||||
conn->id, &conn->le.dst);
|
||||
if (!conn->le.keys) {
|
||||
conn->le.keys = bt_keys_find(BT_KEYS_LTK,
|
||||
conn->id,
|
||||
&conn->le.dst);
|
||||
}
|
||||
}
|
||||
|
||||
if (!conn->le.keys ||
|
||||
!(conn->le.keys->keys & (BT_KEYS_LTK | BT_KEYS_LTK_P256))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (conn->required_sec_level > BT_SECURITY_MEDIUM &&
|
||||
!(conn->le.keys->flags & BT_KEYS_AUTHENTICATED)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (conn->required_sec_level > BT_SECURITY_HIGH &&
|
||||
!(conn->le.keys->flags & BT_KEYS_AUTHENTICATED) &&
|
||||
!(conn->le.keys->keys & BT_KEYS_LTK_P256) &&
|
||||
!(conn->le.keys->enc_size == BT_SMP_MAX_ENC_KEY_SIZE)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int bt_smp_accept(struct bt_conn *conn, struct bt_l2cap_chan **chan)
|
||||
{
|
||||
int i;
|
||||
|
|
|
@ -127,6 +127,7 @@ int bt_smp_send_pairing_req(struct bt_conn *conn);
|
|||
int bt_smp_send_security_req(struct bt_conn *conn);
|
||||
void bt_smp_update_keys(struct bt_conn *conn);
|
||||
bool bt_smp_get_tk(struct bt_conn *conn, u8_t *tk);
|
||||
bool bt_smp_keys_check(struct bt_conn *conn);
|
||||
|
||||
int bt_smp_br_send_pairing_req(struct bt_conn *conn);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue