Revert "Bluetooth: MGMT/SMP: Fix address type when using SMP over BREDR/LE"

This reverts commit 59b047bc which
breaks compatibility with commands like:

bluetoothd[46328]: @ MGMT Command: Load.. (0x0013) plen 74  {0x0001} [hci0]
        Keys: 2
        BR/EDR Address: C0:DC:DA:A5:E5:47 (Samsung Electronics Co.,Ltd)
        Key type: Authenticated key from P-256 (0x03)
        Central: 0x00
        Encryption size: 16
        Diversifier[2]: 0000
        Randomizer[8]: 0000000000000000
        Key[16]: 6ed96089bd9765be2f2c971b0b95f624
        LE Address: D7:2A:DE:1E:73:A2 (Static)
        Key type: Unauthenticated key from P-256 (0x02)
        Central: 0x00
        Encryption size: 16
        Diversifier[2]: 0000
        Randomizer[8]: 0000000000000000
        Key[16]: 87dd2546ededda380ffcdc0a8faa4597
@ MGMT Event: Command Status (0x0002) plen 3                {0x0001} [hci0]
      Load Long Term Keys (0x0013)
        Status: Invalid Parameters (0x0d)

Cc: stable@vger.kernel.org
Link: https://github.com/bluez/bluez/issues/875
Fixes: 59b047bc ("Bluetooth: MGMT/SMP: Fix address type when using SMP over BREDR/LE")
Signed-off-by: default avatarLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
parent 227a0cdf
...@@ -186,7 +186,6 @@ struct blocked_key { ...@@ -186,7 +186,6 @@ struct blocked_key {
struct smp_csrk { struct smp_csrk {
bdaddr_t bdaddr; bdaddr_t bdaddr;
u8 bdaddr_type; u8 bdaddr_type;
u8 link_type;
u8 type; u8 type;
u8 val[16]; u8 val[16];
}; };
...@@ -196,7 +195,6 @@ struct smp_ltk { ...@@ -196,7 +195,6 @@ struct smp_ltk {
struct rcu_head rcu; struct rcu_head rcu;
bdaddr_t bdaddr; bdaddr_t bdaddr;
u8 bdaddr_type; u8 bdaddr_type;
u8 link_type;
u8 authenticated; u8 authenticated;
u8 type; u8 type;
u8 enc_size; u8 enc_size;
...@@ -211,7 +209,6 @@ struct smp_irk { ...@@ -211,7 +209,6 @@ struct smp_irk {
bdaddr_t rpa; bdaddr_t rpa;
bdaddr_t bdaddr; bdaddr_t bdaddr;
u8 addr_type; u8 addr_type;
u8 link_type;
u8 val[16]; u8 val[16];
}; };
...@@ -219,8 +216,6 @@ struct link_key { ...@@ -219,8 +216,6 @@ struct link_key {
struct list_head list; struct list_head list;
struct rcu_head rcu; struct rcu_head rcu;
bdaddr_t bdaddr; bdaddr_t bdaddr;
u8 bdaddr_type;
u8 link_type;
u8 type; u8 type;
u8 val[HCI_LINK_KEY_SIZE]; u8 val[HCI_LINK_KEY_SIZE];
u8 pin_len; u8 pin_len;
......
...@@ -2833,8 +2833,7 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data, ...@@ -2833,8 +2833,7 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data,
for (i = 0; i < key_count; i++) { for (i = 0; i < key_count; i++) {
struct mgmt_link_key_info *key = &cp->keys[i]; struct mgmt_link_key_info *key = &cp->keys[i];
/* Considering SMP over BREDR/LE, there is no need to check addr_type */ if (key->addr.type != BDADDR_BREDR || key->type > 0x08)
if (key->type > 0x08)
return mgmt_cmd_status(sk, hdev->id, return mgmt_cmd_status(sk, hdev->id,
MGMT_OP_LOAD_LINK_KEYS, MGMT_OP_LOAD_LINK_KEYS,
MGMT_STATUS_INVALID_PARAMS); MGMT_STATUS_INVALID_PARAMS);
...@@ -7089,7 +7088,6 @@ static int load_irks(struct sock *sk, struct hci_dev *hdev, void *cp_data, ...@@ -7089,7 +7088,6 @@ static int load_irks(struct sock *sk, struct hci_dev *hdev, void *cp_data,
for (i = 0; i < irk_count; i++) { for (i = 0; i < irk_count; i++) {
struct mgmt_irk_info *irk = &cp->irks[i]; struct mgmt_irk_info *irk = &cp->irks[i];
u8 addr_type = le_addr_type(irk->addr.type);
if (hci_is_blocked_key(hdev, if (hci_is_blocked_key(hdev,
HCI_BLOCKED_KEY_TYPE_IRK, HCI_BLOCKED_KEY_TYPE_IRK,
...@@ -7099,12 +7097,8 @@ static int load_irks(struct sock *sk, struct hci_dev *hdev, void *cp_data, ...@@ -7099,12 +7097,8 @@ static int load_irks(struct sock *sk, struct hci_dev *hdev, void *cp_data,
continue; continue;
} }
/* When using SMP over BR/EDR, the addr type should be set to BREDR */
if (irk->addr.type == BDADDR_BREDR)
addr_type = BDADDR_BREDR;
hci_add_irk(hdev, &irk->addr.bdaddr, hci_add_irk(hdev, &irk->addr.bdaddr,
addr_type, irk->val, le_addr_type(irk->addr.type), irk->val,
BDADDR_ANY); BDADDR_ANY);
} }
...@@ -7185,7 +7179,6 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev, ...@@ -7185,7 +7179,6 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
for (i = 0; i < key_count; i++) { for (i = 0; i < key_count; i++) {
struct mgmt_ltk_info *key = &cp->keys[i]; struct mgmt_ltk_info *key = &cp->keys[i];
u8 type, authenticated; u8 type, authenticated;
u8 addr_type = le_addr_type(key->addr.type);
if (hci_is_blocked_key(hdev, if (hci_is_blocked_key(hdev,
HCI_BLOCKED_KEY_TYPE_LTK, HCI_BLOCKED_KEY_TYPE_LTK,
...@@ -7220,12 +7213,8 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev, ...@@ -7220,12 +7213,8 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
continue; continue;
} }
/* When using SMP over BR/EDR, the addr type should be set to BREDR */
if (key->addr.type == BDADDR_BREDR)
addr_type = BDADDR_BREDR;
hci_add_ltk(hdev, &key->addr.bdaddr, hci_add_ltk(hdev, &key->addr.bdaddr,
addr_type, type, authenticated, le_addr_type(key->addr.type), type, authenticated,
key->val, key->enc_size, key->ediv, key->rand); key->val, key->enc_size, key->ediv, key->rand);
} }
...@@ -9519,7 +9508,7 @@ void mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, ...@@ -9519,7 +9508,7 @@ void mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
ev.store_hint = persistent; ev.store_hint = persistent;
bacpy(&ev.key.addr.bdaddr, &key->bdaddr); bacpy(&ev.key.addr.bdaddr, &key->bdaddr);
ev.key.addr.type = link_to_bdaddr(key->link_type, key->bdaddr_type); ev.key.addr.type = BDADDR_BREDR;
ev.key.type = key->type; ev.key.type = key->type;
memcpy(ev.key.val, key->val, HCI_LINK_KEY_SIZE); memcpy(ev.key.val, key->val, HCI_LINK_KEY_SIZE);
ev.key.pin_len = key->pin_len; ev.key.pin_len = key->pin_len;
...@@ -9570,7 +9559,7 @@ void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, bool persistent) ...@@ -9570,7 +9559,7 @@ void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, bool persistent)
ev.store_hint = persistent; ev.store_hint = persistent;
bacpy(&ev.key.addr.bdaddr, &key->bdaddr); bacpy(&ev.key.addr.bdaddr, &key->bdaddr);
ev.key.addr.type = link_to_bdaddr(key->link_type, key->bdaddr_type); ev.key.addr.type = link_to_bdaddr(LE_LINK, key->bdaddr_type);
ev.key.type = mgmt_ltk_type(key); ev.key.type = mgmt_ltk_type(key);
ev.key.enc_size = key->enc_size; ev.key.enc_size = key->enc_size;
ev.key.ediv = key->ediv; ev.key.ediv = key->ediv;
...@@ -9599,7 +9588,7 @@ void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk, bool persistent) ...@@ -9599,7 +9588,7 @@ void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk, bool persistent)
bacpy(&ev.rpa, &irk->rpa); bacpy(&ev.rpa, &irk->rpa);
bacpy(&ev.irk.addr.bdaddr, &irk->bdaddr); bacpy(&ev.irk.addr.bdaddr, &irk->bdaddr);
ev.irk.addr.type = link_to_bdaddr(irk->link_type, irk->addr_type); ev.irk.addr.type = link_to_bdaddr(LE_LINK, irk->addr_type);
memcpy(ev.irk.val, irk->val, sizeof(irk->val)); memcpy(ev.irk.val, irk->val, sizeof(irk->val));
mgmt_event(MGMT_EV_NEW_IRK, hdev, &ev, sizeof(ev), NULL); mgmt_event(MGMT_EV_NEW_IRK, hdev, &ev, sizeof(ev), NULL);
...@@ -9628,7 +9617,7 @@ void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk, ...@@ -9628,7 +9617,7 @@ void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk,
ev.store_hint = persistent; ev.store_hint = persistent;
bacpy(&ev.key.addr.bdaddr, &csrk->bdaddr); bacpy(&ev.key.addr.bdaddr, &csrk->bdaddr);
ev.key.addr.type = link_to_bdaddr(csrk->link_type, csrk->bdaddr_type); ev.key.addr.type = link_to_bdaddr(LE_LINK, csrk->bdaddr_type);
ev.key.type = csrk->type; ev.key.type = csrk->type;
memcpy(ev.key.val, csrk->val, sizeof(csrk->val)); memcpy(ev.key.val, csrk->val, sizeof(csrk->val));
......
...@@ -1060,7 +1060,6 @@ static void smp_notify_keys(struct l2cap_conn *conn) ...@@ -1060,7 +1060,6 @@ static void smp_notify_keys(struct l2cap_conn *conn)
} }
if (smp->remote_irk) { if (smp->remote_irk) {
smp->remote_irk->link_type = hcon->type;
mgmt_new_irk(hdev, smp->remote_irk, persistent); mgmt_new_irk(hdev, smp->remote_irk, persistent);
/* Now that user space can be considered to know the /* Now that user space can be considered to know the
...@@ -1080,28 +1079,24 @@ static void smp_notify_keys(struct l2cap_conn *conn) ...@@ -1080,28 +1079,24 @@ static void smp_notify_keys(struct l2cap_conn *conn)
} }
if (smp->csrk) { if (smp->csrk) {
smp->csrk->link_type = hcon->type;
smp->csrk->bdaddr_type = hcon->dst_type; smp->csrk->bdaddr_type = hcon->dst_type;
bacpy(&smp->csrk->bdaddr, &hcon->dst); bacpy(&smp->csrk->bdaddr, &hcon->dst);
mgmt_new_csrk(hdev, smp->csrk, persistent); mgmt_new_csrk(hdev, smp->csrk, persistent);
} }
if (smp->responder_csrk) { if (smp->responder_csrk) {
smp->responder_csrk->link_type = hcon->type;
smp->responder_csrk->bdaddr_type = hcon->dst_type; smp->responder_csrk->bdaddr_type = hcon->dst_type;
bacpy(&smp->responder_csrk->bdaddr, &hcon->dst); bacpy(&smp->responder_csrk->bdaddr, &hcon->dst);
mgmt_new_csrk(hdev, smp->responder_csrk, persistent); mgmt_new_csrk(hdev, smp->responder_csrk, persistent);
} }
if (smp->ltk) { if (smp->ltk) {
smp->ltk->link_type = hcon->type;
smp->ltk->bdaddr_type = hcon->dst_type; smp->ltk->bdaddr_type = hcon->dst_type;
bacpy(&smp->ltk->bdaddr, &hcon->dst); bacpy(&smp->ltk->bdaddr, &hcon->dst);
mgmt_new_ltk(hdev, smp->ltk, persistent); mgmt_new_ltk(hdev, smp->ltk, persistent);
} }
if (smp->responder_ltk) { if (smp->responder_ltk) {
smp->responder_ltk->link_type = hcon->type;
smp->responder_ltk->bdaddr_type = hcon->dst_type; smp->responder_ltk->bdaddr_type = hcon->dst_type;
bacpy(&smp->responder_ltk->bdaddr, &hcon->dst); bacpy(&smp->responder_ltk->bdaddr, &hcon->dst);
mgmt_new_ltk(hdev, smp->responder_ltk, persistent); mgmt_new_ltk(hdev, smp->responder_ltk, persistent);
...@@ -1121,8 +1116,6 @@ static void smp_notify_keys(struct l2cap_conn *conn) ...@@ -1121,8 +1116,6 @@ static void smp_notify_keys(struct l2cap_conn *conn)
key = hci_add_link_key(hdev, smp->conn->hcon, &hcon->dst, key = hci_add_link_key(hdev, smp->conn->hcon, &hcon->dst,
smp->link_key, type, 0, &persistent); smp->link_key, type, 0, &persistent);
if (key) { if (key) {
key->link_type = hcon->type;
key->bdaddr_type = hcon->dst_type;
mgmt_new_link_key(hdev, key, persistent); mgmt_new_link_key(hdev, key, persistent);
/* Don't keep debug keys around if the relevant /* Don't keep debug keys around if the relevant
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment