diff --git a/net/bluetooth/keys.c b/net/bluetooth/keys.c index 47627f6bbb2..d1a3c9b5cce 100644 --- a/net/bluetooth/keys.c +++ b/net/bluetooth/keys.c @@ -53,8 +53,7 @@ struct bt_keys *bt_keys_get_addr(const bt_addr_le_t *addr) if (!bt_addr_le_cmp(&keys->addr, BT_ADDR_LE_ANY)) { bt_addr_le_copy(&keys->addr, addr); - BT_DBG("created %p for %s", keys, - bt_addr_le_str(addr)); + BT_DBG("created %p for %s", keys, bt_addr_le_str(addr)); return keys; } } @@ -178,3 +177,88 @@ struct bt_keys *bt_keys_find_addr(const bt_addr_le_t *addr) return NULL; } + +#if defined(CONFIG_BLUETOOTH_BREDR) +static struct bt_keys *bt_keys_get_addr_br(const bt_addr_t *addr) +{ + struct bt_keys *keys; + int i; + + BT_DBG("%s", bt_addr_str(addr)); + + for (i = 0; i < ARRAY_SIZE(key_pool); i++) { + keys = &key_pool[i]; + + /* + * When both LE and BR/EDR keys are for the same device, + * the bt_addr_le_t is the public address, i.e. the same + * as the BR/EDR address. + */ + if (keys->addr.type == BT_ADDR_LE_PUBLIC && + !bt_addr_cmp((const bt_addr_t *)keys->addr.val, addr)) { + return keys; + } + + /* + * BT_ADDR_LE_ANY has the same type of as BT_ADDR_LE_PUBLIC + * value. No need to make redudant comparision against + * BT_ADDR_LE_PUBLIC. + */ + if (!bt_addr_le_cmp(&keys->addr, BT_ADDR_LE_ANY)) { + bt_addr_copy((bt_addr_t *)keys->addr.val, addr); + BT_DBG("created %p for %s", keys, bt_addr_str(addr)); + return keys; + } + } + + BT_DBG("unable to create keys for %s", bt_addr_str(addr)); + + return NULL; +} + +struct bt_keys *bt_keys_find_link_key(const bt_addr_t *addr) +{ + struct bt_keys *keys; + int i; + + BT_DBG("%s", bt_addr_str(addr)); + + for (i = 0; i < ARRAY_SIZE(key_pool); i++) { + keys = &key_pool[i]; + + /* + * When both LE and BR/EDR keys are for the same device, + * the bt_addr_le_t is the public address, i.e. the same + * as the BR/EDR address. + */ + if (keys->addr.type == BT_ADDR_LE_PUBLIC && + (keys->keys & BT_KEYS_LINK_KEY) && + !bt_addr_cmp((const bt_addr_t *)keys->addr.val, addr)) { + return keys; + } + } + + return NULL; +} + +struct bt_keys *bt_keys_get_link_key(const bt_addr_t *addr) +{ + struct bt_keys *keys; + + BT_DBG("%s", bt_addr_str(addr)); + + keys = bt_keys_find_link_key(addr); + if (keys) { + return keys; + } + + keys = bt_keys_get_addr_br(addr); + if (!keys) { + return NULL; + } + + bt_keys_add_type(keys, BT_KEYS_LINK_KEY); + + return keys; +} +#endif /* CONFIG_BLUETOOTH_BREDR */ diff --git a/net/bluetooth/keys.h b/net/bluetooth/keys.h index f83d7a0281c..aa6ac0e2536 100644 --- a/net/bluetooth/keys.h +++ b/net/bluetooth/keys.h @@ -16,7 +16,7 @@ * limitations under the License. */ -#if defined(CONFIG_BLUETOOTH_SMP) +#if defined(CONFIG_BLUETOOTH_SMP) || defined(CONFIG_BLUETOOTH_BREDR) enum { BT_KEYS_SLAVE_LTK = (1 << 0), BT_KEYS_IRK = (1 << 1), @@ -24,10 +24,12 @@ enum { BT_KEYS_LOCAL_CSRK = (1 << 3), BT_KEYS_REMOTE_CSRK = (1 << 4), BT_KEYS_LTK_P256 = (1 << 5), + BT_KEYS_LINK_KEY = (1 << 6), BT_KEYS_ALL = (BT_KEYS_SLAVE_LTK | BT_KEYS_IRK | \ BT_KEYS_LTK | BT_KEYS_LOCAL_CSRK | \ - BT_KEYS_REMOTE_CSRK | BT_KEYS_LTK_P256), + BT_KEYS_REMOTE_CSRK | BT_KEYS_LTK_P256 | \ + BT_KEYS_LINK_KEY), }; enum { @@ -50,12 +52,21 @@ struct bt_csrk { uint32_t cnt; }; +#if defined(CONFIG_BLUETOOTH_BREDR) +struct bt_link_key { + uint8_t val[16]; +}; +#endif /* CONFIG_BLUETOOTH_BREDR */ + struct bt_keys { bt_addr_le_t addr; +#if defined(CONFIG_BLUETOOTH_SMP) uint8_t enc_size; +#endif atomic_t flags; uint16_t keys; +#if defined(CONFIG_BLUETOOTH_SMP) #if !defined(CONFIG_BLUETOOTH_SMP_SC_ONLY) struct bt_ltk slave_ltk; #endif /* CONFIG_BLUETOOTH_SMP_SC_ONLY */ @@ -65,8 +76,18 @@ struct bt_keys { struct bt_csrk local_csrk; struct bt_csrk remote_csrk; #endif /* BLUETOOTH_SIGNING */ +#endif /* CONFIG_BLUETOOTH_SMP */ + +#if defined(CONFIG_BLUETOOTH_BREDR) + struct bt_link_key link_key; +#endif /* CONFIG_BLUETOOTH_BREDR */ }; +#if defined(CONFIG_BLUETOOTH_BREDR) +struct bt_keys *bt_keys_get_link_key(const bt_addr_t *addr); +struct bt_keys *bt_keys_find_link_key(const bt_addr_t *addr); +#endif /* CONFIG_BLUETOOTH_BREDR */ + struct bt_keys *bt_keys_get_addr(const bt_addr_le_t *addr); struct bt_keys *bt_keys_get_type(int type, const bt_addr_le_t *addr); void bt_keys_add_type(struct bt_keys *keys, int type); @@ -79,4 +100,4 @@ static inline struct bt_keys *bt_keys_find_addr(const bt_addr_le_t *addr) { return NULL; } -#endif /* CONFIG_BLUETOOTH_SMP */ +#endif /* CONFIG_BLUETOOTH_SMP || CONFIG_BLUETOOTH_BREDR */