Skip to content

Commit 59b047b

Browse files
xiaoyao888888Vudentz
authored andcommitted
Bluetooth: MGMT/SMP: Fix address type when using SMP over BREDR/LE
If two Bluetooth devices both support BR/EDR and BLE, and also support Secure Connections, then they only need to pair once. The LTK generated during the LE pairing process may be converted into a BR/EDR link key for BR/EDR transport, and conversely, a link key generated during the BR/EDR SSP pairing process can be converted into an LTK for LE transport. Hence, the link type of the link key and LTK is not fixed, they can be either an LE LINK or an ACL LINK. Currently, in the mgmt_new_irk/ltk/crsk/link_key functions, the link type is fixed, which could lead to incorrect address types being reported to the application layer. Therefore, it is necessary to add link_type/addr_type to the smp_irk/ltk/crsk and link_key, to ensure the generation of the correct address type. SMP over BREDR: Before Fix: > ACL Data RX: Handle 11 flags 0x02 dlen 12 BR/EDR SMP: Identity Address Information (0x09) len 7 Address: F8:7D:76:F2:12:F3 (OUI F8-7D-76) @ MGMT Event: New Identity Resolving Key (0x0018) plen 30 Random address: 00:00:00:00:00:00 (Non-Resolvable) LE Address: F8:7D:76:F2:12:F3 (OUI F8-7D-76) @ MGMT Event: New Long Term Key (0x000a) plen 37 LE Address: F8:7D:76:F2:12:F3 (OUI F8-7D-76) Key type: Authenticated key from P-256 (0x03) After Fix: > ACL Data RX: Handle 11 flags 0x02 dlen 12 BR/EDR SMP: Identity Address Information (0x09) len 7 Address: F8:7D:76:F2:12:F3 (OUI F8-7D-76) @ MGMT Event: New Identity Resolving Key (0x0018) plen 30 Random address: 00:00:00:00:00:00 (Non-Resolvable) BR/EDR Address: F8:7D:76:F2:12:F3 (OUI F8-7D-76) @ MGMT Event: New Long Term Key (0x000a) plen 37 BR/EDR Address: F8:7D:76:F2:12:F3 (OUI F8-7D-76) Key type: Authenticated key from P-256 (0x03) SMP over LE: Before Fix: @ MGMT Event: New Identity Resolving Key (0x0018) plen 30 Random address: 5F:5C:07:37:47:D5 (Resolvable) LE Address: F8:7D:76:F2:12:F3 (OUI F8-7D-76) @ MGMT Event: New Long Term Key (0x000a) plen 37 LE Address: F8:7D:76:F2:12:F3 (OUI F8-7D-76) Key type: Authenticated key from P-256 (0x03) @ MGMT Event: New Link Key (0x0009) plen 26 BR/EDR Address: F8:7D:76:F2:12:F3 (OUI F8-7D-76) Key type: Authenticated Combination key from P-256 (0x08) After Fix: @ MGMT Event: New Identity Resolving Key (0x0018) plen 30 Random address: 5E:03:1C:00:38:21 (Resolvable) LE Address: F8:7D:76:F2:12:F3 (OUI F8-7D-76) @ MGMT Event: New Long Term Key (0x000a) plen 37 LE Address: F8:7D:76:F2:12:F3 (OUI F8-7D-76) Key type: Authenticated key from P-256 (0x03) @ MGMT Event: New Link Key (0x0009) plen 26 Store hint: Yes (0x01) LE Address: F8:7D:76:F2:12:F3 (OUI F8-7D-76) Key type: Authenticated Combination key from P-256 (0x08) Cc: stable@vger.kernel.org Signed-off-by: Xiao Yao <xiaoyao@rock-chips.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
1 parent 78b99eb commit 59b047b

File tree

3 files changed

+30
-7
lines changed

3 files changed

+30
-7
lines changed

include/net/bluetooth/hci_core.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ struct blocked_key {
189189
struct smp_csrk {
190190
bdaddr_t bdaddr;
191191
u8 bdaddr_type;
192+
u8 link_type;
192193
u8 type;
193194
u8 val[16];
194195
};
@@ -198,6 +199,7 @@ struct smp_ltk {
198199
struct rcu_head rcu;
199200
bdaddr_t bdaddr;
200201
u8 bdaddr_type;
202+
u8 link_type;
201203
u8 authenticated;
202204
u8 type;
203205
u8 enc_size;
@@ -212,13 +214,16 @@ struct smp_irk {
212214
bdaddr_t rpa;
213215
bdaddr_t bdaddr;
214216
u8 addr_type;
217+
u8 link_type;
215218
u8 val[16];
216219
};
217220

218221
struct link_key {
219222
struct list_head list;
220223
struct rcu_head rcu;
221224
bdaddr_t bdaddr;
225+
u8 bdaddr_type;
226+
u8 link_type;
222227
u8 type;
223228
u8 val[HCI_LINK_KEY_SIZE];
224229
u8 pin_len;

net/bluetooth/mgmt.c

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2897,7 +2897,8 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data,
28972897
for (i = 0; i < key_count; i++) {
28982898
struct mgmt_link_key_info *key = &cp->keys[i];
28992899

2900-
if (key->addr.type != BDADDR_BREDR || key->type > 0x08)
2900+
/* Considering SMP over BREDR/LE, there is no need to check addr_type */
2901+
if (key->type > 0x08)
29012902
return mgmt_cmd_status(sk, hdev->id,
29022903
MGMT_OP_LOAD_LINK_KEYS,
29032904
MGMT_STATUS_INVALID_PARAMS);
@@ -7130,6 +7131,7 @@ static int load_irks(struct sock *sk, struct hci_dev *hdev, void *cp_data,
71307131

71317132
for (i = 0; i < irk_count; i++) {
71327133
struct mgmt_irk_info *irk = &cp->irks[i];
7134+
u8 addr_type = le_addr_type(irk->addr.type);
71337135

71347136
if (hci_is_blocked_key(hdev,
71357137
HCI_BLOCKED_KEY_TYPE_IRK,
@@ -7139,8 +7141,12 @@ static int load_irks(struct sock *sk, struct hci_dev *hdev, void *cp_data,
71397141
continue;
71407142
}
71417143

7144+
/* When using SMP over BR/EDR, the addr type should be set to BREDR */
7145+
if (irk->addr.type == BDADDR_BREDR)
7146+
addr_type = BDADDR_BREDR;
7147+
71427148
hci_add_irk(hdev, &irk->addr.bdaddr,
7143-
le_addr_type(irk->addr.type), irk->val,
7149+
addr_type, irk->val,
71447150
BDADDR_ANY);
71457151
}
71467152

@@ -7221,6 +7227,7 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
72217227
for (i = 0; i < key_count; i++) {
72227228
struct mgmt_ltk_info *key = &cp->keys[i];
72237229
u8 type, authenticated;
7230+
u8 addr_type = le_addr_type(key->addr.type);
72247231

72257232
if (hci_is_blocked_key(hdev,
72267233
HCI_BLOCKED_KEY_TYPE_LTK,
@@ -7255,8 +7262,12 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
72557262
continue;
72567263
}
72577264

7265+
/* When using SMP over BR/EDR, the addr type should be set to BREDR */
7266+
if (key->addr.type == BDADDR_BREDR)
7267+
addr_type = BDADDR_BREDR;
7268+
72587269
hci_add_ltk(hdev, &key->addr.bdaddr,
7259-
le_addr_type(key->addr.type), type, authenticated,
7270+
addr_type, type, authenticated,
72607271
key->val, key->enc_size, key->ediv, key->rand);
72617272
}
72627273

@@ -9523,7 +9534,7 @@ void mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
95239534

95249535
ev.store_hint = persistent;
95259536
bacpy(&ev.key.addr.bdaddr, &key->bdaddr);
9526-
ev.key.addr.type = BDADDR_BREDR;
9537+
ev.key.addr.type = link_to_bdaddr(key->link_type, key->bdaddr_type);
95279538
ev.key.type = key->type;
95289539
memcpy(ev.key.val, key->val, HCI_LINK_KEY_SIZE);
95299540
ev.key.pin_len = key->pin_len;
@@ -9574,7 +9585,7 @@ void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, bool persistent)
95749585
ev.store_hint = persistent;
95759586

95769587
bacpy(&ev.key.addr.bdaddr, &key->bdaddr);
9577-
ev.key.addr.type = link_to_bdaddr(LE_LINK, key->bdaddr_type);
9588+
ev.key.addr.type = link_to_bdaddr(key->link_type, key->bdaddr_type);
95789589
ev.key.type = mgmt_ltk_type(key);
95799590
ev.key.enc_size = key->enc_size;
95809591
ev.key.ediv = key->ediv;
@@ -9603,7 +9614,7 @@ void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk, bool persistent)
96039614

96049615
bacpy(&ev.rpa, &irk->rpa);
96059616
bacpy(&ev.irk.addr.bdaddr, &irk->bdaddr);
9606-
ev.irk.addr.type = link_to_bdaddr(LE_LINK, irk->addr_type);
9617+
ev.irk.addr.type = link_to_bdaddr(irk->link_type, irk->addr_type);
96079618
memcpy(ev.irk.val, irk->val, sizeof(irk->val));
96089619

96099620
mgmt_event(MGMT_EV_NEW_IRK, hdev, &ev, sizeof(ev), NULL);
@@ -9632,7 +9643,7 @@ void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk,
96329643
ev.store_hint = persistent;
96339644

96349645
bacpy(&ev.key.addr.bdaddr, &csrk->bdaddr);
9635-
ev.key.addr.type = link_to_bdaddr(LE_LINK, csrk->bdaddr_type);
9646+
ev.key.addr.type = link_to_bdaddr(csrk->link_type, csrk->bdaddr_type);
96369647
ev.key.type = csrk->type;
96379648
memcpy(ev.key.val, csrk->val, sizeof(csrk->val));
96389649

net/bluetooth/smp.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1059,6 +1059,7 @@ static void smp_notify_keys(struct l2cap_conn *conn)
10591059
}
10601060

10611061
if (smp->remote_irk) {
1062+
smp->remote_irk->link_type = hcon->type;
10621063
mgmt_new_irk(hdev, smp->remote_irk, persistent);
10631064

10641065
/* Now that user space can be considered to know the
@@ -1078,24 +1079,28 @@ static void smp_notify_keys(struct l2cap_conn *conn)
10781079
}
10791080

10801081
if (smp->csrk) {
1082+
smp->csrk->link_type = hcon->type;
10811083
smp->csrk->bdaddr_type = hcon->dst_type;
10821084
bacpy(&smp->csrk->bdaddr, &hcon->dst);
10831085
mgmt_new_csrk(hdev, smp->csrk, persistent);
10841086
}
10851087

10861088
if (smp->responder_csrk) {
1089+
smp->responder_csrk->link_type = hcon->type;
10871090
smp->responder_csrk->bdaddr_type = hcon->dst_type;
10881091
bacpy(&smp->responder_csrk->bdaddr, &hcon->dst);
10891092
mgmt_new_csrk(hdev, smp->responder_csrk, persistent);
10901093
}
10911094

10921095
if (smp->ltk) {
1096+
smp->ltk->link_type = hcon->type;
10931097
smp->ltk->bdaddr_type = hcon->dst_type;
10941098
bacpy(&smp->ltk->bdaddr, &hcon->dst);
10951099
mgmt_new_ltk(hdev, smp->ltk, persistent);
10961100
}
10971101

10981102
if (smp->responder_ltk) {
1103+
smp->responder_ltk->link_type = hcon->type;
10991104
smp->responder_ltk->bdaddr_type = hcon->dst_type;
11001105
bacpy(&smp->responder_ltk->bdaddr, &hcon->dst);
11011106
mgmt_new_ltk(hdev, smp->responder_ltk, persistent);
@@ -1115,6 +1120,8 @@ static void smp_notify_keys(struct l2cap_conn *conn)
11151120
key = hci_add_link_key(hdev, smp->conn->hcon, &hcon->dst,
11161121
smp->link_key, type, 0, &persistent);
11171122
if (key) {
1123+
key->link_type = hcon->type;
1124+
key->bdaddr_type = hcon->dst_type;
11181125
mgmt_new_link_key(hdev, key, persistent);
11191126

11201127
/* Don't keep debug keys around if the relevant

0 commit comments

Comments
 (0)