Skip to content

Commit 39347d6

Browse files
xiaoyao888888gregkh
authored andcommitted
Bluetooth: MGMT/SMP: Fix address type when using SMP over BREDR/LE
commit 59b047b upstream. 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: [email protected] Signed-off-by: Xiao Yao <[email protected]> Signed-off-by: Luiz Augusto von Dentz <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent e14a7eb commit 39347d6

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
@@ -187,6 +187,7 @@ struct blocked_key {
187187
struct smp_csrk {
188188
bdaddr_t bdaddr;
189189
u8 bdaddr_type;
190+
u8 link_type;
190191
u8 type;
191192
u8 val[16];
192193
};
@@ -196,6 +197,7 @@ struct smp_ltk {
196197
struct rcu_head rcu;
197198
bdaddr_t bdaddr;
198199
u8 bdaddr_type;
200+
u8 link_type;
199201
u8 authenticated;
200202
u8 type;
201203
u8 enc_size;
@@ -210,13 +212,16 @@ struct smp_irk {
210212
bdaddr_t rpa;
211213
bdaddr_t bdaddr;
212214
u8 addr_type;
215+
u8 link_type;
213216
u8 val[16];
214217
};
215218

216219
struct link_key {
217220
struct list_head list;
218221
struct rcu_head rcu;
219222
bdaddr_t bdaddr;
223+
u8 bdaddr_type;
224+
u8 link_type;
220225
u8 type;
221226
u8 val[HCI_LINK_KEY_SIZE];
222227
u8 pin_len;

net/bluetooth/mgmt.c

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

2886-
if (key->addr.type != BDADDR_BREDR || key->type > 0x08)
2886+
/* Considering SMP over BREDR/LE, there is no need to check addr_type */
2887+
if (key->type > 0x08)
28872888
return mgmt_cmd_status(sk, hdev->id,
28882889
MGMT_OP_LOAD_LINK_KEYS,
28892890
MGMT_STATUS_INVALID_PARAMS);
@@ -7129,6 +7130,7 @@ static int load_irks(struct sock *sk, struct hci_dev *hdev, void *cp_data,
71297130

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

71337135
if (hci_is_blocked_key(hdev,
71347136
HCI_BLOCKED_KEY_TYPE_IRK,
@@ -7138,8 +7140,12 @@ static int load_irks(struct sock *sk, struct hci_dev *hdev, void *cp_data,
71387140
continue;
71397141
}
71407142

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

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

72247231
if (hci_is_blocked_key(hdev,
72257232
HCI_BLOCKED_KEY_TYPE_LTK,
@@ -7254,8 +7261,12 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
72547261
continue;
72557262
}
72567263

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

@@ -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
@@ -1058,6 +1058,7 @@ static void smp_notify_keys(struct l2cap_conn *conn)
10581058
}
10591059

10601060
if (smp->remote_irk) {
1061+
smp->remote_irk->link_type = hcon->type;
10611062
mgmt_new_irk(hdev, smp->remote_irk, persistent);
10621063

10631064
/* Now that user space can be considered to know the
@@ -1072,24 +1073,28 @@ static void smp_notify_keys(struct l2cap_conn *conn)
10721073
}
10731074

10741075
if (smp->csrk) {
1076+
smp->csrk->link_type = hcon->type;
10751077
smp->csrk->bdaddr_type = hcon->dst_type;
10761078
bacpy(&smp->csrk->bdaddr, &hcon->dst);
10771079
mgmt_new_csrk(hdev, smp->csrk, persistent);
10781080
}
10791081

10801082
if (smp->responder_csrk) {
1083+
smp->responder_csrk->link_type = hcon->type;
10811084
smp->responder_csrk->bdaddr_type = hcon->dst_type;
10821085
bacpy(&smp->responder_csrk->bdaddr, &hcon->dst);
10831086
mgmt_new_csrk(hdev, smp->responder_csrk, persistent);
10841087
}
10851088

10861089
if (smp->ltk) {
1090+
smp->ltk->link_type = hcon->type;
10871091
smp->ltk->bdaddr_type = hcon->dst_type;
10881092
bacpy(&smp->ltk->bdaddr, &hcon->dst);
10891093
mgmt_new_ltk(hdev, smp->ltk, persistent);
10901094
}
10911095

10921096
if (smp->responder_ltk) {
1097+
smp->responder_ltk->link_type = hcon->type;
10931098
smp->responder_ltk->bdaddr_type = hcon->dst_type;
10941099
bacpy(&smp->responder_ltk->bdaddr, &hcon->dst);
10951100
mgmt_new_ltk(hdev, smp->responder_ltk, persistent);
@@ -1109,6 +1114,8 @@ static void smp_notify_keys(struct l2cap_conn *conn)
11091114
key = hci_add_link_key(hdev, smp->conn->hcon, &hcon->dst,
11101115
smp->link_key, type, 0, &persistent);
11111116
if (key) {
1117+
key->link_type = hcon->type;
1118+
key->bdaddr_type = hcon->dst_type;
11121119
mgmt_new_link_key(hdev, key, persistent);
11131120

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

0 commit comments

Comments
 (0)