blob: 6f29430c29c4702bfeafb519be9dda6e3ce21379 [file] [log] [blame]
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001/*
2 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License version 2 as
7 published by the Free Software Foundation;
8
9 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
10 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
12 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
13 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
18 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
19 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
20 SOFTWARE IS DISCLAIMED.
21*/
22
Gustavo Padovan8c520a52012-05-23 04:04:22 -030023#include <linux/crypto.h>
24#include <linux/scatterlist.h>
25#include <crypto/b128ops.h>
26
Anderson Brigliaeb492e02011-06-09 18:50:40 -030027#include <net/bluetooth/bluetooth.h>
28#include <net/bluetooth/hci_core.h>
29#include <net/bluetooth/l2cap.h>
Brian Gix2b64d152011-12-21 16:12:12 -080030#include <net/bluetooth/mgmt.h>
Marcel Holtmannac4b7232013-10-10 14:54:16 -070031
32#include "smp.h"
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030033
Marcel Holtmann17b02e62012-03-01 14:32:37 -080034#define SMP_TIMEOUT msecs_to_jiffies(30000)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -030035
Johan Hedberg065a13e2012-10-11 16:26:06 +020036#define AUTH_REQ_MASK 0x07
37
Johan Hedberg66bed1a2014-03-18 12:58:23 +020038static inline void swap128(const u8 src[16], u8 dst[16])
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030039{
40 int i;
41 for (i = 0; i < 16; i++)
42 dst[15 - i] = src[i];
43}
44
Johan Hedberg66bed1a2014-03-18 12:58:23 +020045static inline void swap56(const u8 src[7], u8 dst[7])
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030046{
47 int i;
48 for (i = 0; i < 7; i++)
49 dst[6 - i] = src[i];
50}
51
52static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
53{
54 struct blkcipher_desc desc;
55 struct scatterlist sg;
Johan Hedberg943a7322014-03-18 12:58:24 +020056 uint8_t tmp[16], data[16];
Johan Hedberg201a5922013-12-02 10:49:04 +020057 int err;
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030058
59 if (tfm == NULL) {
60 BT_ERR("tfm %p", tfm);
61 return -EINVAL;
62 }
63
64 desc.tfm = tfm;
65 desc.flags = 0;
66
Johan Hedberg943a7322014-03-18 12:58:24 +020067 /* The most significant octet of key corresponds to k[0] */
68 swap128(k, tmp);
69
70 err = crypto_blkcipher_setkey(tfm, tmp, 16);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030071 if (err) {
72 BT_ERR("cipher setkey failed: %d", err);
73 return err;
74 }
75
Johan Hedberg943a7322014-03-18 12:58:24 +020076 /* Most significant octet of plaintextData corresponds to data[0] */
77 swap128(r, data);
78
79 sg_init_one(&sg, data, 16);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030080
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030081 err = crypto_blkcipher_encrypt(&desc, &sg, &sg, 16);
82 if (err)
83 BT_ERR("Encrypt data error %d", err);
84
Johan Hedberg943a7322014-03-18 12:58:24 +020085 /* Most significant octet of encryptedData corresponds to data[0] */
86 swap128(data, r);
87
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030088 return err;
89}
90
Johan Hedberg60478052014-02-18 10:19:31 +020091static int smp_ah(struct crypto_blkcipher *tfm, u8 irk[16], u8 r[3], u8 res[3])
92{
Johan Hedberg943a7322014-03-18 12:58:24 +020093 u8 _res[16];
Johan Hedberg60478052014-02-18 10:19:31 +020094 int err;
95
96 /* r' = padding || r */
Johan Hedberg943a7322014-03-18 12:58:24 +020097 memcpy(_res, r, 3);
98 memset(_res + 3, 0, 13);
Johan Hedberg60478052014-02-18 10:19:31 +020099
Johan Hedberg943a7322014-03-18 12:58:24 +0200100 err = smp_e(tfm, irk, _res);
Johan Hedberg60478052014-02-18 10:19:31 +0200101 if (err) {
102 BT_ERR("Encrypt error");
103 return err;
104 }
105
106 /* The output of the random address function ah is:
107 * ah(h, r) = e(k, r') mod 2^24
108 * The output of the security function e is then truncated to 24 bits
109 * by taking the least significant 24 bits of the output of e as the
110 * result of ah.
111 */
Johan Hedberg943a7322014-03-18 12:58:24 +0200112 memcpy(res, _res, 3);
Johan Hedberg60478052014-02-18 10:19:31 +0200113
114 return 0;
115}
116
117bool smp_irk_matches(struct crypto_blkcipher *tfm, u8 irk[16],
118 bdaddr_t *bdaddr)
119{
120 u8 hash[3];
121 int err;
122
123 BT_DBG("RPA %pMR IRK %*phN", bdaddr, 16, irk);
124
125 err = smp_ah(tfm, irk, &bdaddr->b[3], hash);
126 if (err)
127 return false;
128
129 return !memcmp(bdaddr->b, hash, 3);
130}
131
Johan Hedbergb1e2b3a2014-02-23 19:42:19 +0200132int smp_generate_rpa(struct crypto_blkcipher *tfm, u8 irk[16], bdaddr_t *rpa)
133{
134 int err;
135
136 get_random_bytes(&rpa->b[3], 3);
137
138 rpa->b[5] &= 0x3f; /* Clear two most significant bits */
139 rpa->b[5] |= 0x40; /* Set second most significant bit */
140
141 err = smp_ah(tfm, irk, &rpa->b[3], rpa->b);
142 if (err < 0)
143 return err;
144
145 BT_DBG("RPA %pMR", rpa);
146
147 return 0;
148}
149
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300150static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16],
Marcel Holtmannf1560462013-10-13 05:43:25 -0700151 u8 preq[7], u8 pres[7], u8 _iat, bdaddr_t *ia,
152 u8 _rat, bdaddr_t *ra, u8 res[16])
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300153{
154 u8 p1[16], p2[16];
155 int err;
156
157 memset(p1, 0, 16);
158
159 /* p1 = pres || preq || _rat || _iat */
Johan Hedberg943a7322014-03-18 12:58:24 +0200160 p1[0] = _iat;
161 p1[1] = _rat;
162 memcpy(p1 + 2, preq, 7);
163 memcpy(p1 + 9, pres, 7);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300164
165 /* p2 = padding || ia || ra */
Johan Hedberg943a7322014-03-18 12:58:24 +0200166 memcpy(p2, ra, 6);
167 memcpy(p2 + 6, ia, 6);
168 memset(p2 + 12, 0, 4);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300169
170 /* res = r XOR p1 */
171 u128_xor((u128 *) res, (u128 *) r, (u128 *) p1);
172
173 /* res = e(k, res) */
174 err = smp_e(tfm, k, res);
175 if (err) {
176 BT_ERR("Encrypt data error");
177 return err;
178 }
179
180 /* res = res XOR p2 */
181 u128_xor((u128 *) res, (u128 *) res, (u128 *) p2);
182
183 /* res = e(k, res) */
184 err = smp_e(tfm, k, res);
185 if (err)
186 BT_ERR("Encrypt data error");
187
188 return err;
189}
190
Marcel Holtmannf1560462013-10-13 05:43:25 -0700191static int smp_s1(struct crypto_blkcipher *tfm, u8 k[16], u8 r1[16],
192 u8 r2[16], u8 _r[16])
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300193{
194 int err;
195
196 /* Just least significant octets from r1 and r2 are considered */
Johan Hedberg943a7322014-03-18 12:58:24 +0200197 memcpy(_r, r2, 8);
198 memcpy(_r + 8, r1, 8);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300199
200 err = smp_e(tfm, k, _r);
201 if (err)
202 BT_ERR("Encrypt data error");
203
204 return err;
205}
206
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300207static struct sk_buff *smp_build_cmd(struct l2cap_conn *conn, u8 code,
Marcel Holtmannf1560462013-10-13 05:43:25 -0700208 u16 dlen, void *data)
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300209{
210 struct sk_buff *skb;
211 struct l2cap_hdr *lh;
212 int len;
213
214 len = L2CAP_HDR_SIZE + sizeof(code) + dlen;
215
216 if (len > conn->mtu)
217 return NULL;
218
219 skb = bt_skb_alloc(len, GFP_ATOMIC);
220 if (!skb)
221 return NULL;
222
223 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
224 lh->len = cpu_to_le16(sizeof(code) + dlen);
Joe Perchesdcf4adb2014-03-12 10:52:35 -0700225 lh->cid = cpu_to_le16(L2CAP_CID_SMP);
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300226
227 memcpy(skb_put(skb, sizeof(code)), &code, sizeof(code));
228
229 memcpy(skb_put(skb, dlen), data, dlen);
230
231 return skb;
232}
233
234static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
235{
236 struct sk_buff *skb = smp_build_cmd(conn, code, len, data);
237
238 BT_DBG("code 0x%2.2x", code);
239
240 if (!skb)
241 return;
242
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200243 skb->priority = HCI_PRIO_MAX;
244 hci_send_acl(conn->hchan, skb, 0);
Vinicius Costa Gomese2dcd112011-08-19 21:06:50 -0300245
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -0200246 cancel_delayed_work_sync(&conn->security_timer);
Marcel Holtmann17b02e62012-03-01 14:32:37 -0800247 schedule_delayed_work(&conn->security_timer, SMP_TIMEOUT);
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300248}
249
Brian Gix2b64d152011-12-21 16:12:12 -0800250static __u8 authreq_to_seclevel(__u8 authreq)
251{
252 if (authreq & SMP_AUTH_MITM)
253 return BT_SECURITY_HIGH;
254 else
255 return BT_SECURITY_MEDIUM;
256}
257
258static __u8 seclevel_to_authreq(__u8 sec_level)
259{
260 switch (sec_level) {
261 case BT_SECURITY_HIGH:
262 return SMP_AUTH_MITM | SMP_AUTH_BONDING;
263 case BT_SECURITY_MEDIUM:
264 return SMP_AUTH_BONDING;
265 default:
266 return SMP_AUTH_NONE;
267 }
268}
269
Vinicius Costa Gomesb8e66ea2011-06-09 18:50:52 -0300270static void build_pairing_cmd(struct l2cap_conn *conn,
Marcel Holtmannf1560462013-10-13 05:43:25 -0700271 struct smp_cmd_pairing *req,
272 struct smp_cmd_pairing *rsp, __u8 authreq)
Vinicius Costa Gomesb8e66ea2011-06-09 18:50:52 -0300273{
Johan Hedbergfd349c02014-02-18 10:19:36 +0200274 struct smp_chan *smp = conn->smp_chan;
275 struct hci_conn *hcon = conn->hcon;
276 struct hci_dev *hdev = hcon->hdev;
277 u8 local_dist = 0, remote_dist = 0;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300278
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200279 if (test_bit(HCI_PAIRABLE, &conn->hcon->hdev->dev_flags)) {
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -0700280 local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
281 remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300282 authreq |= SMP_AUTH_BONDING;
Brian Gix2b64d152011-12-21 16:12:12 -0800283 } else {
284 authreq &= ~SMP_AUTH_BONDING;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300285 }
286
Johan Hedbergfd349c02014-02-18 10:19:36 +0200287 if (test_bit(HCI_RPA_RESOLVING, &hdev->dev_flags))
288 remote_dist |= SMP_DIST_ID_KEY;
289
Johan Hedberg863efaf2014-02-22 19:06:32 +0200290 if (test_bit(HCI_PRIVACY, &hdev->dev_flags))
291 local_dist |= SMP_DIST_ID_KEY;
292
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300293 if (rsp == NULL) {
294 req->io_capability = conn->hcon->io_capability;
295 req->oob_flag = SMP_OOB_NOT_PRESENT;
296 req->max_key_size = SMP_MAX_ENC_KEY_SIZE;
Johan Hedbergfd349c02014-02-18 10:19:36 +0200297 req->init_key_dist = local_dist;
298 req->resp_key_dist = remote_dist;
Johan Hedberg065a13e2012-10-11 16:26:06 +0200299 req->auth_req = (authreq & AUTH_REQ_MASK);
Johan Hedbergfd349c02014-02-18 10:19:36 +0200300
301 smp->remote_key_dist = remote_dist;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300302 return;
303 }
304
305 rsp->io_capability = conn->hcon->io_capability;
306 rsp->oob_flag = SMP_OOB_NOT_PRESENT;
307 rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE;
Johan Hedbergfd349c02014-02-18 10:19:36 +0200308 rsp->init_key_dist = req->init_key_dist & remote_dist;
309 rsp->resp_key_dist = req->resp_key_dist & local_dist;
Johan Hedberg065a13e2012-10-11 16:26:06 +0200310 rsp->auth_req = (authreq & AUTH_REQ_MASK);
Johan Hedbergfd349c02014-02-18 10:19:36 +0200311
312 smp->remote_key_dist = rsp->init_key_dist;
Vinicius Costa Gomesb8e66ea2011-06-09 18:50:52 -0300313}
314
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300315static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
316{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300317 struct smp_chan *smp = conn->smp_chan;
318
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300319 if ((max_key_size > SMP_MAX_ENC_KEY_SIZE) ||
Marcel Holtmannf1560462013-10-13 05:43:25 -0700320 (max_key_size < SMP_MIN_ENC_KEY_SIZE))
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300321 return SMP_ENC_KEY_SIZE;
322
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300323 smp->enc_key_size = max_key_size;
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300324
325 return 0;
326}
327
Johan Hedberg84794e12013-11-06 11:24:57 +0200328static void smp_failure(struct l2cap_conn *conn, u8 reason)
Brian Gix4f957a72011-11-23 08:28:36 -0800329{
Johan Hedbergbab73cb2012-02-09 16:07:29 +0200330 struct hci_conn *hcon = conn->hcon;
331
Johan Hedberg84794e12013-11-06 11:24:57 +0200332 if (reason)
Brian Gix4f957a72011-11-23 08:28:36 -0800333 smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
Marcel Holtmannf1560462013-10-13 05:43:25 -0700334 &reason);
Brian Gix4f957a72011-11-23 08:28:36 -0800335
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700336 clear_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags);
337 mgmt_auth_failed(hcon->hdev, &hcon->dst, hcon->type, hcon->dst_type,
338 HCI_ERROR_AUTH_FAILURE);
Vinicius Costa Gomesf1c09c02012-02-01 18:27:56 -0300339
Andre Guedes61a0cfb2012-08-01 20:34:15 -0300340 cancel_delayed_work_sync(&conn->security_timer);
341
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700342 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesf1c09c02012-02-01 18:27:56 -0300343 smp_chan_destroy(conn);
Brian Gix4f957a72011-11-23 08:28:36 -0800344}
345
Brian Gix2b64d152011-12-21 16:12:12 -0800346#define JUST_WORKS 0x00
347#define JUST_CFM 0x01
348#define REQ_PASSKEY 0x02
349#define CFM_PASSKEY 0x03
350#define REQ_OOB 0x04
351#define OVERLAP 0xFF
352
353static const u8 gen_method[5][5] = {
354 { JUST_WORKS, JUST_CFM, REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
355 { JUST_WORKS, JUST_CFM, REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
356 { CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
357 { JUST_WORKS, JUST_CFM, JUST_WORKS, JUST_WORKS, JUST_CFM },
358 { CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, OVERLAP },
359};
360
361static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
362 u8 local_io, u8 remote_io)
363{
364 struct hci_conn *hcon = conn->hcon;
365 struct smp_chan *smp = conn->smp_chan;
366 u8 method;
367 u32 passkey = 0;
368 int ret = 0;
369
370 /* Initialize key for JUST WORKS */
371 memset(smp->tk, 0, sizeof(smp->tk));
372 clear_bit(SMP_FLAG_TK_VALID, &smp->smp_flags);
373
374 BT_DBG("tk_request: auth:%d lcl:%d rem:%d", auth, local_io, remote_io);
375
376 /* If neither side wants MITM, use JUST WORKS */
377 /* If either side has unknown io_caps, use JUST WORKS */
378 /* Otherwise, look up method from the table */
379 if (!(auth & SMP_AUTH_MITM) ||
Marcel Holtmannf1560462013-10-13 05:43:25 -0700380 local_io > SMP_IO_KEYBOARD_DISPLAY ||
381 remote_io > SMP_IO_KEYBOARD_DISPLAY)
Brian Gix2b64d152011-12-21 16:12:12 -0800382 method = JUST_WORKS;
383 else
Ido Yarivb3ff53f2012-03-05 20:07:08 +0200384 method = gen_method[remote_io][local_io];
Brian Gix2b64d152011-12-21 16:12:12 -0800385
386 /* If not bonding, don't ask user to confirm a Zero TK */
387 if (!(auth & SMP_AUTH_BONDING) && method == JUST_CFM)
388 method = JUST_WORKS;
389
390 /* If Just Works, Continue with Zero TK */
391 if (method == JUST_WORKS) {
392 set_bit(SMP_FLAG_TK_VALID, &smp->smp_flags);
393 return 0;
394 }
395
396 /* Not Just Works/Confirm results in MITM Authentication */
397 if (method != JUST_CFM)
398 set_bit(SMP_FLAG_MITM_AUTH, &smp->smp_flags);
399
400 /* If both devices have Keyoard-Display I/O, the master
401 * Confirms and the slave Enters the passkey.
402 */
403 if (method == OVERLAP) {
404 if (hcon->link_mode & HCI_LM_MASTER)
405 method = CFM_PASSKEY;
406 else
407 method = REQ_PASSKEY;
408 }
409
410 /* Generate random passkey. Not valid until confirmed. */
411 if (method == CFM_PASSKEY) {
Johan Hedberg943a7322014-03-18 12:58:24 +0200412 memset(smp->tk, 0, sizeof(smp->tk));
Brian Gix2b64d152011-12-21 16:12:12 -0800413 get_random_bytes(&passkey, sizeof(passkey));
414 passkey %= 1000000;
Johan Hedberg943a7322014-03-18 12:58:24 +0200415 put_unaligned_le32(passkey, smp->tk);
Brian Gix2b64d152011-12-21 16:12:12 -0800416 BT_DBG("PassKey: %d", passkey);
417 }
418
419 hci_dev_lock(hcon->hdev);
420
421 if (method == REQ_PASSKEY)
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700422 ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200423 hcon->type, hcon->dst_type);
Brian Gix2b64d152011-12-21 16:12:12 -0800424 else
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700425 ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200426 hcon->type, hcon->dst_type,
Brian Gix2b64d152011-12-21 16:12:12 -0800427 cpu_to_le32(passkey), 0);
428
429 hci_dev_unlock(hcon->hdev);
430
431 return ret;
432}
433
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300434static void confirm_work(struct work_struct *work)
435{
436 struct smp_chan *smp = container_of(work, struct smp_chan, confirm);
437 struct l2cap_conn *conn = smp->conn;
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200438 struct hci_dev *hdev = conn->hcon->hdev;
439 struct crypto_blkcipher *tfm = hdev->tfm_aes;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300440 struct smp_cmd_pairing_confirm cp;
441 int ret;
Johan Hedberg943a7322014-03-18 12:58:24 +0200442 u8 reason;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300443
444 BT_DBG("conn %p", conn);
445
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200446 /* Prevent mutual access to hdev->tfm_aes */
447 hci_dev_lock(hdev);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300448
Johan Hedbergb1cd5fd2014-02-28 12:54:17 +0200449 ret = smp_c1(tfm, smp->tk, smp->prnd, smp->preq, smp->prsp,
450 conn->hcon->init_addr_type, &conn->hcon->init_addr,
Johan Hedberg943a7322014-03-18 12:58:24 +0200451 conn->hcon->resp_addr_type, &conn->hcon->resp_addr,
452 cp.confirm_val);
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200453
454 hci_dev_unlock(hdev);
455
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300456 if (ret) {
457 reason = SMP_UNSPECIFIED;
458 goto error;
459 }
460
Brian Gix2b64d152011-12-21 16:12:12 -0800461 clear_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags);
462
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300463 smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
464
465 return;
466
467error:
Johan Hedberg84794e12013-11-06 11:24:57 +0200468 smp_failure(conn, reason);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300469}
470
471static void random_work(struct work_struct *work)
472{
473 struct smp_chan *smp = container_of(work, struct smp_chan, random);
474 struct l2cap_conn *conn = smp->conn;
475 struct hci_conn *hcon = conn->hcon;
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200476 struct hci_dev *hdev = hcon->hdev;
477 struct crypto_blkcipher *tfm = hdev->tfm_aes;
Johan Hedberg943a7322014-03-18 12:58:24 +0200478 u8 reason, confirm[16];
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300479 int ret;
480
481 if (IS_ERR_OR_NULL(tfm)) {
482 reason = SMP_UNSPECIFIED;
483 goto error;
484 }
485
486 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
487
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200488 /* Prevent mutual access to hdev->tfm_aes */
489 hci_dev_lock(hdev);
490
Johan Hedbergb1cd5fd2014-02-28 12:54:17 +0200491 ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp,
492 hcon->init_addr_type, &hcon->init_addr,
Johan Hedberg943a7322014-03-18 12:58:24 +0200493 hcon->resp_addr_type, &hcon->resp_addr, confirm);
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200494
495 hci_dev_unlock(hdev);
496
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300497 if (ret) {
498 reason = SMP_UNSPECIFIED;
499 goto error;
500 }
501
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300502 if (memcmp(smp->pcnf, confirm, sizeof(smp->pcnf)) != 0) {
503 BT_ERR("Pairing failed (confirmation values mismatch)");
504 reason = SMP_CONFIRM_FAILED;
505 goto error;
506 }
507
508 if (hcon->out) {
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -0800509 u8 stk[16];
510 __le64 rand = 0;
511 __le16 ediv = 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300512
Johan Hedberg943a7322014-03-18 12:58:24 +0200513 smp_s1(tfm, smp->tk, smp->rrnd, smp->prnd, stk);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300514
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300515 memset(stk + smp->enc_key_size, 0,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300516 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300517
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200518 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags)) {
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300519 reason = SMP_UNSPECIFIED;
520 goto error;
521 }
522
523 hci_le_start_enc(hcon, ediv, rand, stk);
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300524 hcon->enc_key_size = smp->enc_key_size;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300525 } else {
Johan Hedberg943a7322014-03-18 12:58:24 +0200526 u8 stk[16];
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -0800527 __le64 rand = 0;
528 __le16 ediv = 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300529
Johan Hedberg943a7322014-03-18 12:58:24 +0200530 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
531 smp->prnd);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300532
Johan Hedberg943a7322014-03-18 12:58:24 +0200533 smp_s1(tfm, smp->tk, smp->prnd, smp->rrnd, stk);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300534
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300535 memset(stk + smp->enc_key_size, 0,
Marcel Holtmannf1560462013-10-13 05:43:25 -0700536 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300537
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700538 hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
Johan Hedberg35d70272014-02-19 14:57:47 +0200539 HCI_SMP_STK_SLAVE, 0, stk, smp->enc_key_size,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300540 ediv, rand);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300541 }
542
543 return;
544
545error:
Johan Hedberg84794e12013-11-06 11:24:57 +0200546 smp_failure(conn, reason);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300547}
548
Johan Hedberge3098be2014-02-28 18:10:03 +0200549static void smp_reencrypt(struct work_struct *work)
550{
551 struct smp_chan *smp = container_of(work, struct smp_chan,
552 reencrypt.work);
553 struct l2cap_conn *conn = smp->conn;
554 struct hci_conn *hcon = conn->hcon;
555 struct smp_ltk *ltk = smp->ltk;
556
557 BT_DBG("");
558
559 hci_le_start_enc(hcon, ltk->ediv, ltk->rand, ltk->val);
560 hcon->enc_key_size = ltk->enc_size;
561}
562
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300563static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
564{
565 struct smp_chan *smp;
566
Marcel Holtmannf1560462013-10-13 05:43:25 -0700567 smp = kzalloc(sizeof(*smp), GFP_ATOMIC);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300568 if (!smp)
569 return NULL;
570
571 INIT_WORK(&smp->confirm, confirm_work);
572 INIT_WORK(&smp->random, random_work);
Johan Hedberge3098be2014-02-28 18:10:03 +0200573 INIT_DELAYED_WORK(&smp->reencrypt, smp_reencrypt);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300574
575 smp->conn = conn;
576 conn->smp_chan = smp;
Brian Gix2b64d152011-12-21 16:12:12 -0800577 conn->hcon->smp_conn = conn;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300578
579 hci_conn_hold(conn->hcon);
580
581 return smp;
582}
583
584void smp_chan_destroy(struct l2cap_conn *conn)
585{
Brian Gixc8eb9692011-11-23 08:28:35 -0800586 struct smp_chan *smp = conn->smp_chan;
Johan Hedbergf4a407b2014-02-18 21:41:34 +0200587 bool complete;
Brian Gixc8eb9692011-11-23 08:28:35 -0800588
Vinicius Costa Gomesf1c09c02012-02-01 18:27:56 -0300589 BUG_ON(!smp);
Brian Gixc8eb9692011-11-23 08:28:35 -0800590
Johan Hedberge3098be2014-02-28 18:10:03 +0200591 cancel_delayed_work_sync(&smp->reencrypt);
592
Johan Hedbergf4a407b2014-02-18 21:41:34 +0200593 complete = test_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
594 mgmt_smp_complete(conn->hcon, complete);
595
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -0700596 kfree(smp->csrk);
597 kfree(smp->slave_csrk);
598
Johan Hedberg759331d2014-02-28 10:10:16 +0200599 /* If pairing failed clean up any keys we might have */
600 if (!complete) {
601 if (smp->ltk) {
602 list_del(&smp->ltk->list);
603 kfree(smp->ltk);
604 }
605
606 if (smp->slave_ltk) {
607 list_del(&smp->slave_ltk->list);
608 kfree(smp->slave_ltk);
609 }
610
611 if (smp->remote_irk) {
612 list_del(&smp->remote_irk->list);
613 kfree(smp->remote_irk);
614 }
615 }
616
Brian Gixc8eb9692011-11-23 08:28:35 -0800617 kfree(smp);
618 conn->smp_chan = NULL;
Brian Gix2b64d152011-12-21 16:12:12 -0800619 conn->hcon->smp_conn = NULL;
David Herrmann76a68ba2013-04-06 20:28:37 +0200620 hci_conn_drop(conn->hcon);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300621}
622
Brian Gix2b64d152011-12-21 16:12:12 -0800623int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
624{
625 struct l2cap_conn *conn = hcon->smp_conn;
626 struct smp_chan *smp;
627 u32 value;
Brian Gix2b64d152011-12-21 16:12:12 -0800628
629 BT_DBG("");
630
631 if (!conn)
632 return -ENOTCONN;
633
634 smp = conn->smp_chan;
635
636 switch (mgmt_op) {
637 case MGMT_OP_USER_PASSKEY_REPLY:
638 value = le32_to_cpu(passkey);
Johan Hedberg943a7322014-03-18 12:58:24 +0200639 memset(smp->tk, 0, sizeof(smp->tk));
Brian Gix2b64d152011-12-21 16:12:12 -0800640 BT_DBG("PassKey: %d", value);
Johan Hedberg943a7322014-03-18 12:58:24 +0200641 put_unaligned_le32(value, smp->tk);
Brian Gix2b64d152011-12-21 16:12:12 -0800642 /* Fall Through */
643 case MGMT_OP_USER_CONFIRM_REPLY:
644 set_bit(SMP_FLAG_TK_VALID, &smp->smp_flags);
645 break;
646 case MGMT_OP_USER_PASSKEY_NEG_REPLY:
647 case MGMT_OP_USER_CONFIRM_NEG_REPLY:
Johan Hedberg84794e12013-11-06 11:24:57 +0200648 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
Brian Gix2b64d152011-12-21 16:12:12 -0800649 return 0;
650 default:
Johan Hedberg84794e12013-11-06 11:24:57 +0200651 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
Brian Gix2b64d152011-12-21 16:12:12 -0800652 return -EOPNOTSUPP;
653 }
654
655 /* If it is our turn to send Pairing Confirm, do so now */
656 if (test_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags))
657 queue_work(hcon->hdev->workqueue, &smp->confirm);
658
659 return 0;
660}
661
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300662static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300663{
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300664 struct smp_cmd_pairing rsp, *req = (void *) skb->data;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300665 struct smp_chan *smp;
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300666 u8 key_size;
Brian Gix2b64d152011-12-21 16:12:12 -0800667 u8 auth = SMP_AUTH_NONE;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300668 int ret;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300669
670 BT_DBG("conn %p", conn);
671
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200672 if (skb->len < sizeof(*req))
673 return SMP_UNSPECIFIED;
674
Brian Gix2b64d152011-12-21 16:12:12 -0800675 if (conn->hcon->link_mode & HCI_LM_MASTER)
676 return SMP_CMD_NOTSUPP;
677
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200678 if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags))
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300679 smp = smp_chan_create(conn);
Andrei Emeltchenkod08fd0e2012-07-19 17:03:43 +0300680 else
681 smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300682
Andrei Emeltchenkod08fd0e2012-07-19 17:03:43 +0300683 if (!smp)
684 return SMP_UNSPECIFIED;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300685
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300686 smp->preq[0] = SMP_CMD_PAIRING_REQ;
687 memcpy(&smp->preq[1], req, sizeof(*req));
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300688 skb_pull(skb, sizeof(*req));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300689
Brian Gix2b64d152011-12-21 16:12:12 -0800690 /* We didn't start the pairing, so match remote */
691 if (req->auth_req & SMP_AUTH_BONDING)
692 auth = req->auth_req;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300693
Ido Yarivfdde0a22012-03-05 20:09:38 +0200694 conn->hcon->pending_sec_level = authreq_to_seclevel(auth);
695
Brian Gix2b64d152011-12-21 16:12:12 -0800696 build_pairing_cmd(conn, req, &rsp, auth);
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300697
698 key_size = min(req->max_key_size, rsp.max_key_size);
699 if (check_enc_key_size(conn, key_size))
700 return SMP_ENC_KEY_SIZE;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300701
Johan Hedberge84a6b12013-12-02 10:49:03 +0200702 get_random_bytes(smp->prnd, sizeof(smp->prnd));
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300703
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300704 smp->prsp[0] = SMP_CMD_PAIRING_RSP;
705 memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300706
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300707 smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300708
Brian Gix2b64d152011-12-21 16:12:12 -0800709 /* Request setup of TK */
710 ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability);
711 if (ret)
712 return SMP_UNSPECIFIED;
713
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300714 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300715}
716
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300717static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300718{
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300719 struct smp_cmd_pairing *req, *rsp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300720 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300721 struct hci_dev *hdev = conn->hcon->hdev;
Brian Gix2b64d152011-12-21 16:12:12 -0800722 u8 key_size, auth = SMP_AUTH_NONE;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300723 int ret;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300724
725 BT_DBG("conn %p", conn);
726
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200727 if (skb->len < sizeof(*rsp))
728 return SMP_UNSPECIFIED;
729
Brian Gix2b64d152011-12-21 16:12:12 -0800730 if (!(conn->hcon->link_mode & HCI_LM_MASTER))
731 return SMP_CMD_NOTSUPP;
732
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300733 skb_pull(skb, sizeof(*rsp));
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300734
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300735 req = (void *) &smp->preq[1];
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300736
737 key_size = min(req->max_key_size, rsp->max_key_size);
738 if (check_enc_key_size(conn, key_size))
739 return SMP_ENC_KEY_SIZE;
740
Johan Hedberge84a6b12013-12-02 10:49:03 +0200741 get_random_bytes(smp->prnd, sizeof(smp->prnd));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300742
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300743 smp->prsp[0] = SMP_CMD_PAIRING_RSP;
744 memcpy(&smp->prsp[1], rsp, sizeof(*rsp));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300745
Johan Hedbergfdcc4be2014-03-14 10:53:50 +0200746 /* Update remote key distribution in case the remote cleared
747 * some bits that we had enabled in our request.
748 */
749 smp->remote_key_dist &= rsp->resp_key_dist;
750
Brian Gix2b64d152011-12-21 16:12:12 -0800751 if ((req->auth_req & SMP_AUTH_BONDING) &&
Marcel Holtmannf1560462013-10-13 05:43:25 -0700752 (rsp->auth_req & SMP_AUTH_BONDING))
Brian Gix2b64d152011-12-21 16:12:12 -0800753 auth = SMP_AUTH_BONDING;
754
755 auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM;
756
Johan Hedberg476585e2012-06-06 18:54:15 +0800757 ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability);
Brian Gix2b64d152011-12-21 16:12:12 -0800758 if (ret)
759 return SMP_UNSPECIFIED;
760
761 set_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags);
762
763 /* Can't compose response until we have been confirmed */
764 if (!test_bit(SMP_FLAG_TK_VALID, &smp->smp_flags))
765 return 0;
766
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300767 queue_work(hdev->workqueue, &smp->confirm);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300768
769 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300770}
771
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300772static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300773{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300774 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300775 struct hci_dev *hdev = conn->hcon->hdev;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300776
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300777 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
778
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200779 if (skb->len < sizeof(smp->pcnf))
780 return SMP_UNSPECIFIED;
781
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300782 memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf));
783 skb_pull(skb, sizeof(smp->pcnf));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300784
Johan Hedberg943a7322014-03-18 12:58:24 +0200785 if (conn->hcon->out)
786 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
787 smp->prnd);
788 else if (test_bit(SMP_FLAG_TK_VALID, &smp->smp_flags))
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300789 queue_work(hdev->workqueue, &smp->confirm);
Johan Hedberg943a7322014-03-18 12:58:24 +0200790 else
Brian Gix2b64d152011-12-21 16:12:12 -0800791 set_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300792
793 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300794}
795
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300796static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300797{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300798 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300799 struct hci_dev *hdev = conn->hcon->hdev;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300800
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300801 BT_DBG("conn %p", conn);
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300802
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200803 if (skb->len < sizeof(smp->rrnd))
804 return SMP_UNSPECIFIED;
805
Johan Hedberg943a7322014-03-18 12:58:24 +0200806 memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd));
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300807 skb_pull(skb, sizeof(smp->rrnd));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300808
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300809 queue_work(hdev->workqueue, &smp->random);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300810
811 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300812}
813
Johan Hedberg4dab7862012-06-07 14:58:37 +0800814static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300815{
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300816 struct smp_ltk *key;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300817 struct hci_conn *hcon = conn->hcon;
818
Johan Hedberg98a0b842014-01-30 19:40:00 -0800819 key = hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type,
820 hcon->out);
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300821 if (!key)
822 return 0;
823
Johan Hedberg4dab7862012-06-07 14:58:37 +0800824 if (sec_level > BT_SECURITY_MEDIUM && !key->authenticated)
825 return 0;
826
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200827 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300828 return 1;
829
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300830 hci_le_start_enc(hcon, key->ediv, key->rand, key->val);
831 hcon->enc_key_size = key->enc_size;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300832
833 return 1;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300834}
Marcel Holtmannf1560462013-10-13 05:43:25 -0700835
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300836static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300837{
838 struct smp_cmd_security_req *rp = (void *) skb->data;
839 struct smp_cmd_pairing cp;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300840 struct hci_conn *hcon = conn->hcon;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300841 struct smp_chan *smp;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300842
843 BT_DBG("conn %p", conn);
844
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200845 if (skb->len < sizeof(*rp))
846 return SMP_UNSPECIFIED;
847
Johan Hedberg86ca9ea2013-11-05 11:30:39 +0200848 if (!(conn->hcon->link_mode & HCI_LM_MASTER))
849 return SMP_CMD_NOTSUPP;
850
Brian Gix2b64d152011-12-21 16:12:12 -0800851 hcon->pending_sec_level = authreq_to_seclevel(rp->auth_req);
Vinicius Costa Gomesfeb45eb2011-08-25 20:02:35 -0300852
Johan Hedberg4dab7862012-06-07 14:58:37 +0800853 if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300854 return 0;
855
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200856 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300857 return 0;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300858
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300859 smp = smp_chan_create(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300860
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300861 skb_pull(skb, sizeof(*rp));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300862
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300863 memset(&cp, 0, sizeof(cp));
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300864 build_pairing_cmd(conn, &cp, NULL, rp->auth_req);
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300865
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300866 smp->preq[0] = SMP_CMD_PAIRING_REQ;
867 memcpy(&smp->preq[1], &cp, sizeof(cp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300868
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300869 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300870
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300871 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300872}
873
Johan Hedbergad32a2f2013-05-14 18:05:12 +0300874bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level)
875{
876 if (sec_level == BT_SECURITY_LOW)
877 return true;
878
879 if (hcon->sec_level >= sec_level)
880 return true;
881
882 return false;
883}
884
Vinicius Costa Gomescc110922012-08-23 21:32:43 -0300885int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300886{
Vinicius Costa Gomescc110922012-08-23 21:32:43 -0300887 struct l2cap_conn *conn = hcon->l2cap_data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300888 struct smp_chan *smp = conn->smp_chan;
Brian Gix2b64d152011-12-21 16:12:12 -0800889 __u8 authreq;
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300890
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -0300891 BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
892
Johan Hedberg757aee02013-04-24 13:05:32 +0300893 if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags))
Andre Guedes2e65c9d2011-06-30 19:20:56 -0300894 return 1;
895
Johan Hedbergad32a2f2013-05-14 18:05:12 +0300896 if (smp_sufficient_security(hcon, sec_level))
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300897 return 1;
898
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300899 if (hcon->link_mode & HCI_LM_MASTER)
Johan Hedberg4dab7862012-06-07 14:58:37 +0800900 if (smp_ltk_encrypt(conn, sec_level))
Vinicius Costa Gomes02bc7452011-07-07 18:59:41 -0300901 goto done;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300902
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200903 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300904 return 0;
905
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300906 smp = smp_chan_create(conn);
Brian Gix2b64d152011-12-21 16:12:12 -0800907 if (!smp)
908 return 1;
909
910 authreq = seclevel_to_authreq(sec_level);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300911
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300912 if (hcon->link_mode & HCI_LM_MASTER) {
913 struct smp_cmd_pairing cp;
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300914
Brian Gix2b64d152011-12-21 16:12:12 -0800915 build_pairing_cmd(conn, &cp, NULL, authreq);
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300916 smp->preq[0] = SMP_CMD_PAIRING_REQ;
917 memcpy(&smp->preq[1], &cp, sizeof(cp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300918
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300919 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
920 } else {
921 struct smp_cmd_security_req cp;
Brian Gix2b64d152011-12-21 16:12:12 -0800922 cp.auth_req = authreq;
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300923 smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
924 }
925
Vinicius Costa Gomes02bc7452011-07-07 18:59:41 -0300926done:
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300927 hcon->pending_sec_level = sec_level;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300928
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300929 return 0;
930}
931
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300932static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
933{
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300934 struct smp_cmd_encrypt_info *rp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300935 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300936
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200937 BT_DBG("conn %p", conn);
938
939 if (skb->len < sizeof(*rp))
940 return SMP_UNSPECIFIED;
941
Johan Hedberg6131ddc2014-02-18 10:19:37 +0200942 /* Ignore this PDU if it wasn't requested */
943 if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
944 return 0;
945
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300946 skb_pull(skb, sizeof(*rp));
947
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300948 memcpy(smp->tk, rp->ltk, sizeof(smp->tk));
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300949
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300950 return 0;
951}
952
953static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
954{
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300955 struct smp_cmd_master_ident *rp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300956 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300957 struct hci_dev *hdev = conn->hcon->hdev;
958 struct hci_conn *hcon = conn->hcon;
Johan Hedberg23d0e122014-02-19 14:57:46 +0200959 struct smp_ltk *ltk;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300960 u8 authenticated;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300961
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200962 BT_DBG("conn %p", conn);
963
964 if (skb->len < sizeof(*rp))
965 return SMP_UNSPECIFIED;
966
Johan Hedberg6131ddc2014-02-18 10:19:37 +0200967 /* Ignore this PDU if it wasn't requested */
968 if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
969 return 0;
970
Johan Hedberg9747a9f2014-02-26 23:33:43 +0200971 /* Mark the information as received */
972 smp->remote_key_dist &= ~SMP_DIST_ENC_KEY;
973
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300974 skb_pull(skb, sizeof(*rp));
975
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300976 hci_dev_lock(hdev);
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700977 authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
Johan Hedberg35d70272014-02-19 14:57:47 +0200978 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, HCI_SMP_LTK,
Johan Hedberg23d0e122014-02-19 14:57:46 +0200979 authenticated, smp->tk, smp->enc_key_size,
980 rp->ediv, rp->rand);
981 smp->ltk = ltk;
Johan Hedbergfd349c02014-02-18 10:19:36 +0200982 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
Johan Hedberg4bd6d382014-02-26 23:33:45 +0200983 smp_distribute_keys(conn);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300984 hci_dev_unlock(hdev);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300985
986 return 0;
987}
988
Johan Hedbergfd349c02014-02-18 10:19:36 +0200989static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
990{
991 struct smp_cmd_ident_info *info = (void *) skb->data;
992 struct smp_chan *smp = conn->smp_chan;
993
994 BT_DBG("");
995
996 if (skb->len < sizeof(*info))
997 return SMP_UNSPECIFIED;
998
Johan Hedberg6131ddc2014-02-18 10:19:37 +0200999 /* Ignore this PDU if it wasn't requested */
1000 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
1001 return 0;
1002
Johan Hedbergfd349c02014-02-18 10:19:36 +02001003 skb_pull(skb, sizeof(*info));
1004
1005 memcpy(smp->irk, info->irk, 16);
1006
1007 return 0;
1008}
1009
1010static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
1011 struct sk_buff *skb)
1012{
1013 struct smp_cmd_ident_addr_info *info = (void *) skb->data;
1014 struct smp_chan *smp = conn->smp_chan;
1015 struct hci_conn *hcon = conn->hcon;
1016 bdaddr_t rpa;
1017
1018 BT_DBG("");
1019
1020 if (skb->len < sizeof(*info))
1021 return SMP_UNSPECIFIED;
1022
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001023 /* Ignore this PDU if it wasn't requested */
1024 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
1025 return 0;
1026
Johan Hedberg9747a9f2014-02-26 23:33:43 +02001027 /* Mark the information as received */
1028 smp->remote_key_dist &= ~SMP_DIST_ID_KEY;
1029
Johan Hedbergfd349c02014-02-18 10:19:36 +02001030 skb_pull(skb, sizeof(*info));
1031
Johan Hedberga9a58f82014-02-25 22:24:37 +02001032 /* Strictly speaking the Core Specification (4.1) allows sending
1033 * an empty address which would force us to rely on just the IRK
1034 * as "identity information". However, since such
1035 * implementations are not known of and in order to not over
1036 * complicate our implementation, simply pretend that we never
1037 * received an IRK for such a device.
1038 */
1039 if (!bacmp(&info->bdaddr, BDADDR_ANY)) {
1040 BT_ERR("Ignoring IRK with no identity address");
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001041 smp_distribute_keys(conn);
Johan Hedberga9a58f82014-02-25 22:24:37 +02001042 return 0;
1043 }
1044
Johan Hedbergfd349c02014-02-18 10:19:36 +02001045 bacpy(&smp->id_addr, &info->bdaddr);
1046 smp->id_addr_type = info->addr_type;
1047
1048 if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type))
1049 bacpy(&rpa, &hcon->dst);
1050 else
1051 bacpy(&rpa, BDADDR_ANY);
1052
Johan Hedberg23d0e122014-02-19 14:57:46 +02001053 smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
1054 smp->id_addr_type, smp->irk, &rpa);
Johan Hedbergfd349c02014-02-18 10:19:36 +02001055
Johan Hedberg68d6f6d2014-02-18 21:41:32 +02001056 /* Track the connection based on the Identity Address from now on */
1057 bacpy(&hcon->dst, &smp->id_addr);
1058 hcon->dst_type = smp->id_addr_type;
1059
Johan Hedberg387a33e2014-02-18 21:41:33 +02001060 l2cap_conn_update_id_addr(hcon);
1061
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001062 smp_distribute_keys(conn);
Johan Hedbergfd349c02014-02-18 10:19:36 +02001063
1064 return 0;
1065}
1066
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001067static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)
1068{
1069 struct smp_cmd_sign_info *rp = (void *) skb->data;
1070 struct smp_chan *smp = conn->smp_chan;
1071 struct hci_dev *hdev = conn->hcon->hdev;
1072 struct smp_csrk *csrk;
1073
1074 BT_DBG("conn %p", conn);
1075
1076 if (skb->len < sizeof(*rp))
1077 return SMP_UNSPECIFIED;
1078
1079 /* Ignore this PDU if it wasn't requested */
1080 if (!(smp->remote_key_dist & SMP_DIST_SIGN))
1081 return 0;
1082
1083 /* Mark the information as received */
1084 smp->remote_key_dist &= ~SMP_DIST_SIGN;
1085
1086 skb_pull(skb, sizeof(*rp));
1087
1088 hci_dev_lock(hdev);
1089 csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
1090 if (csrk) {
1091 csrk->master = 0x01;
1092 memcpy(csrk->val, rp->csrk, sizeof(csrk->val));
1093 }
1094 smp->csrk = csrk;
1095 if (!(smp->remote_key_dist & SMP_DIST_SIGN))
1096 smp_distribute_keys(conn);
1097 hci_dev_unlock(hdev);
1098
1099 return 0;
1100}
1101
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001102int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
1103{
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001104 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann92381f52013-10-03 01:23:08 -07001105 __u8 code, reason;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001106 int err = 0;
1107
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001108 if (hcon->type != LE_LINK) {
1109 kfree_skb(skb);
Johan Hedberg34327112013-10-16 11:37:01 +03001110 return 0;
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001111 }
1112
Marcel Holtmann92381f52013-10-03 01:23:08 -07001113 if (skb->len < 1) {
1114 kfree_skb(skb);
1115 return -EILSEQ;
1116 }
1117
Marcel Holtmann06ae3312013-10-18 03:43:00 -07001118 if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) {
Andre Guedes2e65c9d2011-06-30 19:20:56 -03001119 err = -ENOTSUPP;
1120 reason = SMP_PAIRING_NOTSUPP;
1121 goto done;
1122 }
1123
Marcel Holtmann92381f52013-10-03 01:23:08 -07001124 code = skb->data[0];
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001125 skb_pull(skb, sizeof(code));
1126
Johan Hedberg8cf9fa12013-01-29 10:44:23 -06001127 /*
1128 * The SMP context must be initialized for all other PDUs except
1129 * pairing and security requests. If we get any other PDU when
1130 * not initialized simply disconnect (done if this function
1131 * returns an error).
1132 */
1133 if (code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ &&
1134 !conn->smp_chan) {
1135 BT_ERR("Unexpected SMP command 0x%02x. Disconnecting.", code);
1136 kfree_skb(skb);
1137 return -ENOTSUPP;
1138 }
1139
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001140 switch (code) {
1141 case SMP_CMD_PAIRING_REQ:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001142 reason = smp_cmd_pairing_req(conn, skb);
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001143 break;
1144
1145 case SMP_CMD_PAIRING_FAIL:
Johan Hedberg84794e12013-11-06 11:24:57 +02001146 smp_failure(conn, 0);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001147 reason = 0;
1148 err = -EPERM;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001149 break;
1150
1151 case SMP_CMD_PAIRING_RSP:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001152 reason = smp_cmd_pairing_rsp(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001153 break;
1154
1155 case SMP_CMD_SECURITY_REQ:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001156 reason = smp_cmd_security_req(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001157 break;
1158
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001159 case SMP_CMD_PAIRING_CONFIRM:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001160 reason = smp_cmd_pairing_confirm(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001161 break;
1162
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001163 case SMP_CMD_PAIRING_RANDOM:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001164 reason = smp_cmd_pairing_random(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001165 break;
1166
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001167 case SMP_CMD_ENCRYPT_INFO:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001168 reason = smp_cmd_encrypt_info(conn, skb);
1169 break;
1170
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001171 case SMP_CMD_MASTER_IDENT:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001172 reason = smp_cmd_master_ident(conn, skb);
1173 break;
1174
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001175 case SMP_CMD_IDENT_INFO:
Johan Hedbergfd349c02014-02-18 10:19:36 +02001176 reason = smp_cmd_ident_info(conn, skb);
1177 break;
1178
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001179 case SMP_CMD_IDENT_ADDR_INFO:
Johan Hedbergfd349c02014-02-18 10:19:36 +02001180 reason = smp_cmd_ident_addr_info(conn, skb);
1181 break;
1182
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001183 case SMP_CMD_SIGN_INFO:
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001184 reason = smp_cmd_sign_info(conn, skb);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001185 break;
1186
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001187 default:
1188 BT_DBG("Unknown command code 0x%2.2x", code);
1189
1190 reason = SMP_CMD_NOTSUPP;
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -03001191 err = -EOPNOTSUPP;
1192 goto done;
1193 }
1194
1195done:
1196 if (reason)
Johan Hedberg84794e12013-11-06 11:24:57 +02001197 smp_failure(conn, reason);
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001198
1199 kfree_skb(skb);
1200 return err;
1201}
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001202
Johan Hedberg35d70272014-02-19 14:57:47 +02001203static void smp_notify_keys(struct l2cap_conn *conn)
1204{
1205 struct smp_chan *smp = conn->smp_chan;
1206 struct hci_conn *hcon = conn->hcon;
1207 struct hci_dev *hdev = hcon->hdev;
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001208 struct smp_cmd_pairing *req = (void *) &smp->preq[1];
1209 struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1];
1210 bool persistent;
Johan Hedberg35d70272014-02-19 14:57:47 +02001211
Johan Hedberg95fbac82014-02-19 15:18:31 +02001212 if (smp->remote_irk)
1213 mgmt_new_irk(hdev, smp->remote_irk);
1214
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001215 /* The LTKs and CSRKs should be persistent only if both sides
1216 * had the bonding bit set in their authentication requests.
1217 */
1218 persistent = !!((req->auth_req & rsp->auth_req) & SMP_AUTH_BONDING);
1219
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001220 if (smp->csrk) {
1221 smp->csrk->bdaddr_type = hcon->dst_type;
1222 bacpy(&smp->csrk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001223 mgmt_new_csrk(hdev, smp->csrk, persistent);
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001224 }
1225
1226 if (smp->slave_csrk) {
1227 smp->slave_csrk->bdaddr_type = hcon->dst_type;
1228 bacpy(&smp->slave_csrk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001229 mgmt_new_csrk(hdev, smp->slave_csrk, persistent);
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001230 }
1231
Johan Hedberg35d70272014-02-19 14:57:47 +02001232 if (smp->ltk) {
1233 smp->ltk->bdaddr_type = hcon->dst_type;
1234 bacpy(&smp->ltk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001235 mgmt_new_ltk(hdev, smp->ltk, persistent);
Johan Hedberg35d70272014-02-19 14:57:47 +02001236 }
1237
1238 if (smp->slave_ltk) {
1239 smp->slave_ltk->bdaddr_type = hcon->dst_type;
1240 bacpy(&smp->slave_ltk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001241 mgmt_new_ltk(hdev, smp->slave_ltk, persistent);
Johan Hedberg35d70272014-02-19 14:57:47 +02001242 }
1243}
1244
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001245int smp_distribute_keys(struct l2cap_conn *conn)
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001246{
1247 struct smp_cmd_pairing *req, *rsp;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001248 struct smp_chan *smp = conn->smp_chan;
Johan Hedberg524237c2014-02-22 19:06:31 +02001249 struct hci_conn *hcon = conn->hcon;
1250 struct hci_dev *hdev = hcon->hdev;
Johan Hedberg38ccdc92014-02-28 18:10:02 +02001251 bool ltk_encrypt;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001252 __u8 *keydist;
1253
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001254 BT_DBG("conn %p", conn);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001255
Johan Hedberg524237c2014-02-22 19:06:31 +02001256 if (!test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001257 return 0;
1258
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001259 rsp = (void *) &smp->prsp[1];
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001260
1261 /* The responder sends its keys first */
Johan Hedbergefabba32014-02-26 23:33:44 +02001262 if (hcon->out && (smp->remote_key_dist & 0x07))
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001263 return 0;
1264
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001265 req = (void *) &smp->preq[1];
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001266
Johan Hedberg524237c2014-02-22 19:06:31 +02001267 if (hcon->out) {
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001268 keydist = &rsp->init_key_dist;
1269 *keydist &= req->init_key_dist;
1270 } else {
1271 keydist = &rsp->resp_key_dist;
1272 *keydist &= req->resp_key_dist;
1273 }
1274
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001275 BT_DBG("keydist 0x%x", *keydist);
1276
1277 if (*keydist & SMP_DIST_ENC_KEY) {
1278 struct smp_cmd_encrypt_info enc;
1279 struct smp_cmd_master_ident ident;
Johan Hedberg23d0e122014-02-19 14:57:46 +02001280 struct smp_ltk *ltk;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001281 u8 authenticated;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001282 __le16 ediv;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001283 __le64 rand;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001284
1285 get_random_bytes(enc.ltk, sizeof(enc.ltk));
1286 get_random_bytes(&ediv, sizeof(ediv));
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001287 get_random_bytes(&rand, sizeof(rand));
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001288
1289 smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
1290
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001291 authenticated = hcon->sec_level == BT_SECURITY_HIGH;
Johan Hedberg524237c2014-02-22 19:06:31 +02001292 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type,
Johan Hedberg35d70272014-02-19 14:57:47 +02001293 HCI_SMP_LTK_SLAVE, authenticated, enc.ltk,
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001294 smp->enc_key_size, ediv, rand);
Johan Hedberg23d0e122014-02-19 14:57:46 +02001295 smp->slave_ltk = ltk;
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001296
Andrei Emeltchenko58115372012-03-12 12:13:06 +02001297 ident.ediv = ediv;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001298 ident.rand = rand;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001299
1300 smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident);
1301
1302 *keydist &= ~SMP_DIST_ENC_KEY;
1303 }
1304
1305 if (*keydist & SMP_DIST_ID_KEY) {
1306 struct smp_cmd_ident_addr_info addrinfo;
1307 struct smp_cmd_ident_info idinfo;
1308
Johan Hedberg863efaf2014-02-22 19:06:32 +02001309 memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk));
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001310
1311 smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo);
1312
Johan Hedberg82d4b352014-02-23 19:42:18 +02001313 /* The hci_conn contains the local identity address
1314 * after the connection has been established.
1315 *
1316 * This is true even when the connection has been
1317 * established using a resolvable random address.
1318 */
Johan Hedberg524237c2014-02-22 19:06:31 +02001319 bacpy(&addrinfo.bdaddr, &hcon->src);
Johan Hedberg82d4b352014-02-23 19:42:18 +02001320 addrinfo.addr_type = hcon->src_type;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001321
1322 smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo),
Marcel Holtmannf1560462013-10-13 05:43:25 -07001323 &addrinfo);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001324
1325 *keydist &= ~SMP_DIST_ID_KEY;
1326 }
1327
1328 if (*keydist & SMP_DIST_SIGN) {
1329 struct smp_cmd_sign_info sign;
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001330 struct smp_csrk *csrk;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001331
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001332 /* Generate a new random key */
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001333 get_random_bytes(sign.csrk, sizeof(sign.csrk));
1334
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001335 csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
1336 if (csrk) {
1337 csrk->master = 0x00;
1338 memcpy(csrk->val, sign.csrk, sizeof(csrk->val));
1339 }
1340 smp->slave_csrk = csrk;
1341
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001342 smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign);
1343
1344 *keydist &= ~SMP_DIST_SIGN;
1345 }
1346
Johan Hedbergefabba32014-02-26 23:33:44 +02001347 /* If there are still keys to be received wait for them */
1348 if ((smp->remote_key_dist & 0x07))
1349 return 0;
1350
Johan Hedberg38ccdc92014-02-28 18:10:02 +02001351 /* Check if we should try to re-encrypt the link with the LTK.
1352 * SMP_FLAG_LTK_ENCRYPT flag is used to track whether we've
1353 * already tried this (in which case we shouldn't try again).
1354 *
1355 * The request will trigger an encryption key refresh event
1356 * which will cause a call to auth_cfm and eventually lead to
1357 * l2cap_core.c calling this smp_distribute_keys function again
1358 * and thereby completing the process.
1359 */
1360 if (smp->ltk)
1361 ltk_encrypt = !test_and_set_bit(SMP_FLAG_LTK_ENCRYPT,
1362 &smp->smp_flags);
1363 else
1364 ltk_encrypt = false;
Johan Hedbergefabba32014-02-26 23:33:44 +02001365
Johan Hedberg38ccdc92014-02-28 18:10:02 +02001366 /* Re-encrypt the link with LTK if possible */
1367 if (ltk_encrypt && hcon->out) {
Johan Hedberge3098be2014-02-28 18:10:03 +02001368 queue_delayed_work(hdev->req_workqueue, &smp->reencrypt,
1369 SMP_REENCRYPT_TIMEOUT);
Johan Hedberg38ccdc92014-02-28 18:10:02 +02001370 } else {
1371 clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags);
1372 cancel_delayed_work_sync(&conn->security_timer);
1373 set_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
1374 smp_notify_keys(conn);
1375 smp_chan_destroy(conn);
1376 }
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001377
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001378 return 0;
1379}