Skip to content

Commit da448f1

Browse files
xiaoyao888888gregkh
authored andcommitted
Bluetooth: MGMT/SMP: Fix address type when using SMP over BREDR/LE
[ Upstream commit 59b047b ] 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: Sasha Levin <[email protected]>
1 parent 4bc9121 commit da448f1

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
@@ -174,6 +174,7 @@ struct blocked_key {
174174
struct smp_csrk {
175175
bdaddr_t bdaddr;
176176
u8 bdaddr_type;
177+
u8 link_type;
177178
u8 type;
178179
u8 val[16];
179180
};
@@ -183,6 +184,7 @@ struct smp_ltk {
183184
struct rcu_head rcu;
184185
bdaddr_t bdaddr;
185186
u8 bdaddr_type;
187+
u8 link_type;
186188
u8 authenticated;
187189
u8 type;
188190
u8 enc_size;
@@ -197,13 +199,16 @@ struct smp_irk {
197199
bdaddr_t rpa;
198200
bdaddr_t bdaddr;
199201
u8 addr_type;
202+
u8 link_type;
200203
u8 val[16];
201204
};
202205

203206
struct link_key {
204207
struct list_head list;
205208
struct rcu_head rcu;
206209
bdaddr_t bdaddr;
210+
u8 bdaddr_type;
211+
u8 link_type;
207212
u8 type;
208213
u8 val[HCI_LINK_KEY_SIZE];
209214
u8 pin_len;

net/bluetooth/mgmt.c

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

2376-
if (key->addr.type != BDADDR_BREDR || key->type > 0x08)
2376+
/* Considering SMP over BREDR/LE, there is no need to check addr_type */
2377+
if (key->type > 0x08)
23772378
return mgmt_cmd_status(sk, hdev->id,
23782379
MGMT_OP_LOAD_LINK_KEYS,
23792380
MGMT_STATUS_INVALID_PARAMS);
@@ -5914,6 +5915,7 @@ static int load_irks(struct sock *sk, struct hci_dev *hdev, void *cp_data,
59145915

59155916
for (i = 0; i < irk_count; i++) {
59165917
struct mgmt_irk_info *irk = &cp->irks[i];
5918+
u8 addr_type = le_addr_type(irk->addr.type);
59175919

59185920
if (hci_is_blocked_key(hdev,
59195921
HCI_BLOCKED_KEY_TYPE_IRK,
@@ -5923,8 +5925,12 @@ static int load_irks(struct sock *sk, struct hci_dev *hdev, void *cp_data,
59235925
continue;
59245926
}
59255927

5928+
/* When using SMP over BR/EDR, the addr type should be set to BREDR */
5929+
if (irk->addr.type == BDADDR_BREDR)
5930+
addr_type = BDADDR_BREDR;
5931+
59265932
hci_add_irk(hdev, &irk->addr.bdaddr,
5927-
le_addr_type(irk->addr.type), irk->val,
5933+
addr_type, irk->val,
59285934
BDADDR_ANY);
59295935
}
59305936

@@ -6005,6 +6011,7 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
60056011
for (i = 0; i < key_count; i++) {
60066012
struct mgmt_ltk_info *key = &cp->keys[i];
60076013
u8 type, authenticated;
6014+
u8 addr_type = le_addr_type(key->addr.type);
60086015

60096016
if (hci_is_blocked_key(hdev,
60106017
HCI_BLOCKED_KEY_TYPE_LTK,
@@ -6039,8 +6046,12 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
60396046
continue;
60406047
}
60416048

6049+
/* When using SMP over BR/EDR, the addr type should be set to BREDR */
6050+
if (key->addr.type == BDADDR_BREDR)
6051+
addr_type = BDADDR_BREDR;
6052+
60426053
hci_add_ltk(hdev, &key->addr.bdaddr,
6043-
le_addr_type(key->addr.type), type, authenticated,
6054+
addr_type, type, authenticated,
60446055
key->val, key->enc_size, key->ediv, key->rand);
60456056
}
60466057

@@ -8043,7 +8054,7 @@ void mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
80438054

80448055
ev.store_hint = persistent;
80458056
bacpy(&ev.key.addr.bdaddr, &key->bdaddr);
8046-
ev.key.addr.type = BDADDR_BREDR;
8057+
ev.key.addr.type = link_to_bdaddr(key->link_type, key->bdaddr_type);
80478058
ev.key.type = key->type;
80488059
memcpy(ev.key.val, key->val, HCI_LINK_KEY_SIZE);
80498060
ev.key.pin_len = key->pin_len;
@@ -8094,7 +8105,7 @@ void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, bool persistent)
80948105
ev.store_hint = persistent;
80958106

80968107
bacpy(&ev.key.addr.bdaddr, &key->bdaddr);
8097-
ev.key.addr.type = link_to_bdaddr(LE_LINK, key->bdaddr_type);
8108+
ev.key.addr.type = link_to_bdaddr(key->link_type, key->bdaddr_type);
80988109
ev.key.type = mgmt_ltk_type(key);
80998110
ev.key.enc_size = key->enc_size;
81008111
ev.key.ediv = key->ediv;
@@ -8123,7 +8134,7 @@ void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk, bool persistent)
81238134

81248135
bacpy(&ev.rpa, &irk->rpa);
81258136
bacpy(&ev.irk.addr.bdaddr, &irk->bdaddr);
8126-
ev.irk.addr.type = link_to_bdaddr(LE_LINK, irk->addr_type);
8137+
ev.irk.addr.type = link_to_bdaddr(irk->link_type, irk->addr_type);
81278138
memcpy(ev.irk.val, irk->val, sizeof(irk->val));
81288139

81298140
mgmt_event(MGMT_EV_NEW_IRK, hdev, &ev, sizeof(ev), NULL);
@@ -8152,7 +8163,7 @@ void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk,
81528163
ev.store_hint = persistent;
81538164

81548165
bacpy(&ev.key.addr.bdaddr, &csrk->bdaddr);
8155-
ev.key.addr.type = link_to_bdaddr(LE_LINK, csrk->bdaddr_type);
8166+
ev.key.addr.type = link_to_bdaddr(csrk->link_type, csrk->bdaddr_type);
81568167
ev.key.type = csrk->type;
81578168
memcpy(ev.key.val, csrk->val, sizeof(csrk->val));
81588169

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
@@ -1073,24 +1074,28 @@ static void smp_notify_keys(struct l2cap_conn *conn)
10731074
}
10741075

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

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

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

10931097
if (smp->responder_ltk) {
1098+
smp->responder_ltk->link_type = hcon->type;
10941099
smp->responder_ltk->bdaddr_type = hcon->dst_type;
10951100
bacpy(&smp->responder_ltk->bdaddr, &hcon->dst);
10961101
mgmt_new_ltk(hdev, smp->responder_ltk, persistent);
@@ -1110,6 +1115,8 @@ static void smp_notify_keys(struct l2cap_conn *conn)
11101115
key = hci_add_link_key(hdev, smp->conn->hcon, &hcon->dst,
11111116
smp->link_key, type, 0, &persistent);
11121117
if (key) {
1118+
key->link_type = hcon->type;
1119+
key->bdaddr_type = hcon->dst_type;
11131120
mgmt_new_link_key(hdev, key, persistent);
11141121

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

0 commit comments

Comments
 (0)