diff options
-rw-r--r-- | include/net/bluetooth/amp.h | 2 | ||||
-rw-r--r-- | net/bluetooth/Kconfig | 1 | ||||
-rw-r--r-- | net/bluetooth/amp.c | 45 |
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); | |||
32 | struct hci_conn *phylink_add(struct hci_dev *hdev, struct amp_mgr *mgr, | 32 | struct hci_conn *phylink_add(struct hci_dev *hdev, struct amp_mgr *mgr, |
33 | u8 remote_id); | 33 | u8 remote_id); |
34 | 34 | ||
35 | int phylink_gen_key(struct hci_conn *hcon, u8 *data, u8 *len, u8 *type); | ||
36 | |||
35 | void amp_read_loc_info(struct hci_dev *hdev, struct amp_mgr *mgr); | 37 | void amp_read_loc_info(struct hci_dev *hdev, struct amp_mgr *mgr); |
36 | void amp_read_loc_assoc_frag(struct hci_dev *hdev, u8 phy_handle); | 38 | void amp_read_loc_assoc_frag(struct hci_dev *hdev, u8 phy_handle); |
37 | void amp_read_loc_assoc(struct hci_dev *hdev, struct amp_mgr *mgr); | 39 | void 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 | ||
164 | int 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 | |||
164 | void amp_read_loc_assoc_frag(struct hci_dev *hdev, u8 phy_handle) | 209 | void 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; |