Skip to content

Commit 865f1f4

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 0974347 commit 865f1f4

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
@@ -1060,6 +1060,7 @@ static void smp_notify_keys(struct l2cap_conn *conn)
10601060
}
10611061

10621062
if (smp->remote_irk) {
1063+
smp->remote_irk->link_type = hcon->type;
10631064
mgmt_new_irk(hdev, smp->remote_irk, persistent);
10641065

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

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

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

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

10991103
if (smp->responder_ltk) {
1104+
smp->responder_ltk->link_type = hcon->type;
11001105
smp->responder_ltk->bdaddr_type = hcon->dst_type;
11011106
bacpy(&smp->responder_ltk->bdaddr, &hcon->dst);
11021107
mgmt_new_ltk(hdev, smp->responder_ltk, persistent);
@@ -1116,6 +1121,8 @@ static void smp_notify_keys(struct l2cap_conn *conn)
11161121
key = hci_add_link_key(hdev, smp->conn->hcon, &hcon->dst,
11171122
smp->link_key, type, 0, &persistent);
11181123
if (key) {
1124+
key->link_type = hcon->type;
1125+
key->bdaddr_type = hcon->dst_type;
11191126
mgmt_new_link_key(hdev, key, persistent);
11201127

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

0 commit comments

Comments
 (0)