Bluetooth: SMP: Clear keys on SMP Timeout and Pairing Failed

Those two indicate SMP failure, so while in keys distribution phase,
if we receive Pairing Failed, or there is SMP Timeout, the keys
distributed so far shall considered as invalid and cleared.
Another flag SMP_FLAG_KEYS_DISTRO is needed to save the old keys
if this failure appears before distribution of new keys.

Change-Id: I9a917740c02955aa149170b84ae547f5c8c4b7ad
Signed-off-by: Mariusz Skamra <mariusz.skamra@tieto.com>
This commit is contained in:
Mariusz Skamra 2016-02-22 16:08:05 +01:00 committed by Gerrit Code Review
commit a7ad7dcf16

View file

@ -77,6 +77,7 @@ enum pairing_method {
enum {
SMP_FLAG_CFM_DELAYED, /* if confirm should be send when TK is valid */
SMP_FLAG_ENC_PENDING, /* if waiting for an encryption change event */
SMP_FLAG_KEYS_DISTR, /* if keys distribution phase is in progress */
SMP_FLAG_PAIRING, /* if pairing is in progress */
SMP_FLAG_TIMEOUT, /* if SMP timeout occurred */
SMP_FLAG_SC, /* if LE Secure Connections is used */
@ -585,6 +586,15 @@ static void smp_timeout(int arg1, int arg2)
smp->timeout = NULL;
/*
* If SMP timeout occurred during key distribution we should assume
* pairing failed and don't store any keys from this pairing.
*/
if (atomic_test_bit(&smp->flags, SMP_FLAG_KEYS_DISTR) &&
smp->chan.conn->keys) {
bt_keys_clear(smp->chan.conn->keys, BT_KEYS_ALL);
}
smp_reset(smp);
atomic_set_bit(&smp->flags, SMP_FLAG_TIMEOUT);
@ -1965,6 +1975,15 @@ static uint8_t smp_pairing_failed(struct bt_smp *smp, struct net_buf *buf)
break;
}
/*
* Pairing Failed command may be sent at any time during the pairing,
* so if there are any keys distributed, shall be cleared.
*/
if (atomic_test_bit(&smp->flags, SMP_FLAG_KEYS_DISTR) &&
smp->chan.conn->keys) {
bt_keys_clear(smp->chan.conn->keys, BT_KEYS_ALL);
}
smp_reset(smp);
/* return no error to avoid sending Pairing Failed in response */
@ -2586,6 +2605,8 @@ static void bt_smp_encrypt_change(struct bt_l2cap_chan *chan)
atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_SIGNING_INFO);
}
atomic_set_bit(&smp->flags, SMP_FLAG_KEYS_DISTR);
#if defined(CONFIG_BLUETOOTH_CENTRAL)
/* Slave distributes it's keys first */
if (conn->role == BT_HCI_ROLE_MASTER && smp->remote_dist) {