aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/bluetooth/amp.h2
-rw-r--r--net/bluetooth/Kconfig1
-rw-r--r--net/bluetooth/amp.c45
3 files changed, 48 insertions, 0 deletions
diff --git a/include/net/bluetooth/amp.h b/include/net/bluetooth/amp.h
index f57854f0786d..763b4635c304 100644
--- a/include/net/bluetooth/amp.h
+++ b/include/net/bluetooth/amp.h
@@ -32,6 +32,8 @@ void amp_ctrl_list_flush(struct amp_mgr *mgr);
32struct hci_conn *phylink_add(struct hci_dev *hdev, struct amp_mgr *mgr, 32struct hci_conn *phylink_add(struct hci_dev *hdev, struct amp_mgr *mgr,
33 u8 remote_id); 33 u8 remote_id);
34 34
35int phylink_gen_key(struct hci_conn *hcon, u8 *data, u8 *len, u8 *type);
36
35void amp_read_loc_info(struct hci_dev *hdev, struct amp_mgr *mgr); 37void amp_read_loc_info(struct hci_dev *hdev, struct amp_mgr *mgr);
36void amp_read_loc_assoc_frag(struct hci_dev *hdev, u8 phy_handle); 38void amp_read_loc_assoc_frag(struct hci_dev *hdev, u8 phy_handle);
37void amp_read_loc_assoc(struct hci_dev *hdev, struct amp_mgr *mgr); 39void amp_read_loc_assoc(struct hci_dev *hdev, struct amp_mgr *mgr);
diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig
index 3537d385035e..1c11d0dcd863 100644
--- a/net/bluetooth/Kconfig
+++ b/net/bluetooth/Kconfig
@@ -11,6 +11,7 @@ menuconfig BT
11 select CRYPTO_BLKCIPHER 11 select CRYPTO_BLKCIPHER
12 select CRYPTO_AES 12 select CRYPTO_AES
13 select CRYPTO_ECB 13 select CRYPTO_ECB
14 select CRYPTO_SHA256
14 help 15 help
15 Bluetooth is low-cost, low-power, short-range wireless technology. 16 Bluetooth is low-cost, low-power, short-range wireless technology.
16 It was designed as a replacement for cables and other short-range 17 It was designed as a replacement for cables and other short-range
diff --git a/net/bluetooth/amp.c b/net/bluetooth/amp.c
index ea4d5ffc1151..67bc2c2f8783 100644
--- a/net/bluetooth/amp.c
+++ b/net/bluetooth/amp.c
@@ -161,6 +161,51 @@ static int hmac_sha256(u8 *key, u8 ksize, char *plaintext, u8 psize, u8 *output)
161 return ret; 161 return ret;
162} 162}
163 163
164int phylink_gen_key(struct hci_conn *conn, u8 *data, u8 *len, u8 *type)
165{
166 struct hci_dev *hdev = conn->hdev;
167 struct link_key *key;
168 u8 keybuf[HCI_AMP_LINK_KEY_SIZE];
169 u8 gamp_key[HCI_AMP_LINK_KEY_SIZE];
170 int err;
171
172 if (!hci_conn_check_link_mode(conn))
173 return -EACCES;
174
175 BT_DBG("conn %p key_type %d", conn, conn->key_type);
176
177 /* Legacy key */
178 if (conn->key_type < 3) {
179 BT_ERR("Legacy key type %d", conn->key_type);
180 return -EACCES;
181 }
182
183 *type = conn->key_type;
184 *len = HCI_AMP_LINK_KEY_SIZE;
185
186 key = hci_find_link_key(hdev, &conn->dst);
187
188 /* BR/EDR Link Key concatenated together with itself */
189 memcpy(&keybuf[0], key->val, HCI_LINK_KEY_SIZE);
190 memcpy(&keybuf[HCI_LINK_KEY_SIZE], key->val, HCI_LINK_KEY_SIZE);
191
192 /* Derive Generic AMP Link Key (gamp) */
193 err = hmac_sha256(keybuf, HCI_AMP_LINK_KEY_SIZE, "gamp", 4, gamp_key);
194 if (err) {
195 BT_ERR("Could not derive Generic AMP Key: err %d", err);
196 return err;
197 }
198
199 if (conn->key_type == HCI_LK_DEBUG_COMBINATION) {
200 BT_DBG("Use Generic AMP Key (gamp)");
201 memcpy(data, gamp_key, HCI_AMP_LINK_KEY_SIZE);
202 return err;
203 }
204
205 /* Derive Dedicated AMP Link Key: "802b" is 802.11 PAL keyID */
206 return hmac_sha256(gamp_key, HCI_AMP_LINK_KEY_SIZE, "802b", 4, data);
207}
208
164void amp_read_loc_assoc_frag(struct hci_dev *hdev, u8 phy_handle) 209void amp_read_loc_assoc_frag(struct hci_dev *hdev, u8 phy_handle)
165{ 210{
166 struct hci_cp_read_local_amp_assoc cp; 211 struct hci_cp_read_local_amp_assoc cp;