blob: f1cb6a32e93f1ea6f6d5276dab055fa33f49f86f [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
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030038static inline void swap128(u8 src[16], u8 dst[16])
39{
40 int i;
41 for (i = 0; i < 16; i++)
42 dst[15 - i] = src[i];
43}
44
45static inline void swap56(u8 src[7], u8 dst[7])
46{
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 Hedberg201a5922013-12-02 10:49:04 +020056 int err;
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030057
58 if (tfm == NULL) {
59 BT_ERR("tfm %p", tfm);
60 return -EINVAL;
61 }
62
63 desc.tfm = tfm;
64 desc.flags = 0;
65
66 err = crypto_blkcipher_setkey(tfm, k, 16);
67 if (err) {
68 BT_ERR("cipher setkey failed: %d", err);
69 return err;
70 }
71
72 sg_init_one(&sg, r, 16);
73
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030074 err = crypto_blkcipher_encrypt(&desc, &sg, &sg, 16);
75 if (err)
76 BT_ERR("Encrypt data error %d", err);
77
78 return err;
79}
80
Johan Hedberg60478052014-02-18 10:19:31 +020081static int smp_ah(struct crypto_blkcipher *tfm, u8 irk[16], u8 r[3], u8 res[3])
82{
83 u8 _res[16], k[16];
84 int err;
85
86 /* r' = padding || r */
87 memset(_res, 0, 13);
88 _res[13] = r[2];
89 _res[14] = r[1];
90 _res[15] = r[0];
91
92 swap128(irk, k);
93 err = smp_e(tfm, k, _res);
94 if (err) {
95 BT_ERR("Encrypt error");
96 return err;
97 }
98
99 /* The output of the random address function ah is:
100 * ah(h, r) = e(k, r') mod 2^24
101 * The output of the security function e is then truncated to 24 bits
102 * by taking the least significant 24 bits of the output of e as the
103 * result of ah.
104 */
105 res[0] = _res[15];
106 res[1] = _res[14];
107 res[2] = _res[13];
108
109 return 0;
110}
111
112bool smp_irk_matches(struct crypto_blkcipher *tfm, u8 irk[16],
113 bdaddr_t *bdaddr)
114{
115 u8 hash[3];
116 int err;
117
118 BT_DBG("RPA %pMR IRK %*phN", bdaddr, 16, irk);
119
120 err = smp_ah(tfm, irk, &bdaddr->b[3], hash);
121 if (err)
122 return false;
123
124 return !memcmp(bdaddr->b, hash, 3);
125}
126
Johan Hedbergb1e2b3a2014-02-23 19:42:19 +0200127int smp_generate_rpa(struct crypto_blkcipher *tfm, u8 irk[16], bdaddr_t *rpa)
128{
129 int err;
130
131 get_random_bytes(&rpa->b[3], 3);
132
133 rpa->b[5] &= 0x3f; /* Clear two most significant bits */
134 rpa->b[5] |= 0x40; /* Set second most significant bit */
135
136 err = smp_ah(tfm, irk, &rpa->b[3], rpa->b);
137 if (err < 0)
138 return err;
139
140 BT_DBG("RPA %pMR", rpa);
141
142 return 0;
143}
144
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300145static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16],
Marcel Holtmannf1560462013-10-13 05:43:25 -0700146 u8 preq[7], u8 pres[7], u8 _iat, bdaddr_t *ia,
147 u8 _rat, bdaddr_t *ra, u8 res[16])
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300148{
149 u8 p1[16], p2[16];
150 int err;
151
152 memset(p1, 0, 16);
153
154 /* p1 = pres || preq || _rat || _iat */
155 swap56(pres, p1);
156 swap56(preq, p1 + 7);
157 p1[14] = _rat;
158 p1[15] = _iat;
159
160 memset(p2, 0, 16);
161
162 /* p2 = padding || ia || ra */
163 baswap((bdaddr_t *) (p2 + 4), ia);
164 baswap((bdaddr_t *) (p2 + 10), ra);
165
166 /* res = r XOR p1 */
167 u128_xor((u128 *) res, (u128 *) r, (u128 *) p1);
168
169 /* res = e(k, res) */
170 err = smp_e(tfm, k, res);
171 if (err) {
172 BT_ERR("Encrypt data error");
173 return err;
174 }
175
176 /* res = res XOR p2 */
177 u128_xor((u128 *) res, (u128 *) res, (u128 *) p2);
178
179 /* res = e(k, res) */
180 err = smp_e(tfm, k, res);
181 if (err)
182 BT_ERR("Encrypt data error");
183
184 return err;
185}
186
Marcel Holtmannf1560462013-10-13 05:43:25 -0700187static int smp_s1(struct crypto_blkcipher *tfm, u8 k[16], u8 r1[16],
188 u8 r2[16], u8 _r[16])
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300189{
190 int err;
191
192 /* Just least significant octets from r1 and r2 are considered */
193 memcpy(_r, r1 + 8, 8);
194 memcpy(_r + 8, r2 + 8, 8);
195
196 err = smp_e(tfm, k, _r);
197 if (err)
198 BT_ERR("Encrypt data error");
199
200 return err;
201}
202
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300203static struct sk_buff *smp_build_cmd(struct l2cap_conn *conn, u8 code,
Marcel Holtmannf1560462013-10-13 05:43:25 -0700204 u16 dlen, void *data)
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300205{
206 struct sk_buff *skb;
207 struct l2cap_hdr *lh;
208 int len;
209
210 len = L2CAP_HDR_SIZE + sizeof(code) + dlen;
211
212 if (len > conn->mtu)
213 return NULL;
214
215 skb = bt_skb_alloc(len, GFP_ATOMIC);
216 if (!skb)
217 return NULL;
218
219 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
220 lh->len = cpu_to_le16(sizeof(code) + dlen);
Syam Sidhardhand8aece22012-10-10 22:09:28 +0530221 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SMP);
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300222
223 memcpy(skb_put(skb, sizeof(code)), &code, sizeof(code));
224
225 memcpy(skb_put(skb, dlen), data, dlen);
226
227 return skb;
228}
229
230static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
231{
232 struct sk_buff *skb = smp_build_cmd(conn, code, len, data);
233
234 BT_DBG("code 0x%2.2x", code);
235
236 if (!skb)
237 return;
238
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200239 skb->priority = HCI_PRIO_MAX;
240 hci_send_acl(conn->hchan, skb, 0);
Vinicius Costa Gomese2dcd112011-08-19 21:06:50 -0300241
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -0200242 cancel_delayed_work_sync(&conn->security_timer);
Marcel Holtmann17b02e62012-03-01 14:32:37 -0800243 schedule_delayed_work(&conn->security_timer, SMP_TIMEOUT);
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300244}
245
Brian Gix2b64d152011-12-21 16:12:12 -0800246static __u8 authreq_to_seclevel(__u8 authreq)
247{
248 if (authreq & SMP_AUTH_MITM)
249 return BT_SECURITY_HIGH;
250 else
251 return BT_SECURITY_MEDIUM;
252}
253
254static __u8 seclevel_to_authreq(__u8 sec_level)
255{
256 switch (sec_level) {
257 case BT_SECURITY_HIGH:
258 return SMP_AUTH_MITM | SMP_AUTH_BONDING;
259 case BT_SECURITY_MEDIUM:
260 return SMP_AUTH_BONDING;
261 default:
262 return SMP_AUTH_NONE;
263 }
264}
265
Vinicius Costa Gomesb8e66ea2011-06-09 18:50:52 -0300266static void build_pairing_cmd(struct l2cap_conn *conn,
Marcel Holtmannf1560462013-10-13 05:43:25 -0700267 struct smp_cmd_pairing *req,
268 struct smp_cmd_pairing *rsp, __u8 authreq)
Vinicius Costa Gomesb8e66ea2011-06-09 18:50:52 -0300269{
Johan Hedbergfd349c02014-02-18 10:19:36 +0200270 struct smp_chan *smp = conn->smp_chan;
271 struct hci_conn *hcon = conn->hcon;
272 struct hci_dev *hdev = hcon->hdev;
273 u8 local_dist = 0, remote_dist = 0;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300274
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200275 if (test_bit(HCI_PAIRABLE, &conn->hcon->hdev->dev_flags)) {
Johan Hedbergfd349c02014-02-18 10:19:36 +0200276 local_dist = SMP_DIST_ENC_KEY;
277 remote_dist = SMP_DIST_ENC_KEY;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300278 authreq |= SMP_AUTH_BONDING;
Brian Gix2b64d152011-12-21 16:12:12 -0800279 } else {
280 authreq &= ~SMP_AUTH_BONDING;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300281 }
282
Johan Hedbergfd349c02014-02-18 10:19:36 +0200283 if (test_bit(HCI_RPA_RESOLVING, &hdev->dev_flags))
284 remote_dist |= SMP_DIST_ID_KEY;
285
Johan Hedberg863efaf2014-02-22 19:06:32 +0200286 if (test_bit(HCI_PRIVACY, &hdev->dev_flags))
287 local_dist |= SMP_DIST_ID_KEY;
288
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300289 if (rsp == NULL) {
290 req->io_capability = conn->hcon->io_capability;
291 req->oob_flag = SMP_OOB_NOT_PRESENT;
292 req->max_key_size = SMP_MAX_ENC_KEY_SIZE;
Johan Hedbergfd349c02014-02-18 10:19:36 +0200293 req->init_key_dist = local_dist;
294 req->resp_key_dist = remote_dist;
Johan Hedberg065a13e2012-10-11 16:26:06 +0200295 req->auth_req = (authreq & AUTH_REQ_MASK);
Johan Hedbergfd349c02014-02-18 10:19:36 +0200296
297 smp->remote_key_dist = remote_dist;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300298 return;
299 }
300
301 rsp->io_capability = conn->hcon->io_capability;
302 rsp->oob_flag = SMP_OOB_NOT_PRESENT;
303 rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE;
Johan Hedbergfd349c02014-02-18 10:19:36 +0200304 rsp->init_key_dist = req->init_key_dist & remote_dist;
305 rsp->resp_key_dist = req->resp_key_dist & local_dist;
Johan Hedberg065a13e2012-10-11 16:26:06 +0200306 rsp->auth_req = (authreq & AUTH_REQ_MASK);
Johan Hedbergfd349c02014-02-18 10:19:36 +0200307
308 smp->remote_key_dist = rsp->init_key_dist;
Vinicius Costa Gomesb8e66ea2011-06-09 18:50:52 -0300309}
310
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300311static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
312{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300313 struct smp_chan *smp = conn->smp_chan;
314
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300315 if ((max_key_size > SMP_MAX_ENC_KEY_SIZE) ||
Marcel Holtmannf1560462013-10-13 05:43:25 -0700316 (max_key_size < SMP_MIN_ENC_KEY_SIZE))
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300317 return SMP_ENC_KEY_SIZE;
318
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300319 smp->enc_key_size = max_key_size;
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300320
321 return 0;
322}
323
Johan Hedberg84794e12013-11-06 11:24:57 +0200324static void smp_failure(struct l2cap_conn *conn, u8 reason)
Brian Gix4f957a72011-11-23 08:28:36 -0800325{
Johan Hedbergbab73cb2012-02-09 16:07:29 +0200326 struct hci_conn *hcon = conn->hcon;
327
Johan Hedberg84794e12013-11-06 11:24:57 +0200328 if (reason)
Brian Gix4f957a72011-11-23 08:28:36 -0800329 smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
Marcel Holtmannf1560462013-10-13 05:43:25 -0700330 &reason);
Brian Gix4f957a72011-11-23 08:28:36 -0800331
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700332 clear_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags);
333 mgmt_auth_failed(hcon->hdev, &hcon->dst, hcon->type, hcon->dst_type,
334 HCI_ERROR_AUTH_FAILURE);
Vinicius Costa Gomesf1c09c02012-02-01 18:27:56 -0300335
Andre Guedes61a0cfb2012-08-01 20:34:15 -0300336 cancel_delayed_work_sync(&conn->security_timer);
337
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700338 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesf1c09c02012-02-01 18:27:56 -0300339 smp_chan_destroy(conn);
Brian Gix4f957a72011-11-23 08:28:36 -0800340}
341
Brian Gix2b64d152011-12-21 16:12:12 -0800342#define JUST_WORKS 0x00
343#define JUST_CFM 0x01
344#define REQ_PASSKEY 0x02
345#define CFM_PASSKEY 0x03
346#define REQ_OOB 0x04
347#define OVERLAP 0xFF
348
349static const u8 gen_method[5][5] = {
350 { JUST_WORKS, JUST_CFM, REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
351 { JUST_WORKS, JUST_CFM, REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
352 { CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
353 { JUST_WORKS, JUST_CFM, JUST_WORKS, JUST_WORKS, JUST_CFM },
354 { CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, OVERLAP },
355};
356
357static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
358 u8 local_io, u8 remote_io)
359{
360 struct hci_conn *hcon = conn->hcon;
361 struct smp_chan *smp = conn->smp_chan;
362 u8 method;
363 u32 passkey = 0;
364 int ret = 0;
365
366 /* Initialize key for JUST WORKS */
367 memset(smp->tk, 0, sizeof(smp->tk));
368 clear_bit(SMP_FLAG_TK_VALID, &smp->smp_flags);
369
370 BT_DBG("tk_request: auth:%d lcl:%d rem:%d", auth, local_io, remote_io);
371
372 /* If neither side wants MITM, use JUST WORKS */
373 /* If either side has unknown io_caps, use JUST WORKS */
374 /* Otherwise, look up method from the table */
375 if (!(auth & SMP_AUTH_MITM) ||
Marcel Holtmannf1560462013-10-13 05:43:25 -0700376 local_io > SMP_IO_KEYBOARD_DISPLAY ||
377 remote_io > SMP_IO_KEYBOARD_DISPLAY)
Brian Gix2b64d152011-12-21 16:12:12 -0800378 method = JUST_WORKS;
379 else
Ido Yarivb3ff53f2012-03-05 20:07:08 +0200380 method = gen_method[remote_io][local_io];
Brian Gix2b64d152011-12-21 16:12:12 -0800381
382 /* If not bonding, don't ask user to confirm a Zero TK */
383 if (!(auth & SMP_AUTH_BONDING) && method == JUST_CFM)
384 method = JUST_WORKS;
385
386 /* If Just Works, Continue with Zero TK */
387 if (method == JUST_WORKS) {
388 set_bit(SMP_FLAG_TK_VALID, &smp->smp_flags);
389 return 0;
390 }
391
392 /* Not Just Works/Confirm results in MITM Authentication */
393 if (method != JUST_CFM)
394 set_bit(SMP_FLAG_MITM_AUTH, &smp->smp_flags);
395
396 /* If both devices have Keyoard-Display I/O, the master
397 * Confirms and the slave Enters the passkey.
398 */
399 if (method == OVERLAP) {
400 if (hcon->link_mode & HCI_LM_MASTER)
401 method = CFM_PASSKEY;
402 else
403 method = REQ_PASSKEY;
404 }
405
406 /* Generate random passkey. Not valid until confirmed. */
407 if (method == CFM_PASSKEY) {
408 u8 key[16];
409
410 memset(key, 0, sizeof(key));
411 get_random_bytes(&passkey, sizeof(passkey));
412 passkey %= 1000000;
413 put_unaligned_le32(passkey, key);
414 swap128(key, smp->tk);
415 BT_DBG("PassKey: %d", passkey);
416 }
417
418 hci_dev_lock(hcon->hdev);
419
420 if (method == REQ_PASSKEY)
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700421 ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200422 hcon->type, hcon->dst_type);
Brian Gix2b64d152011-12-21 16:12:12 -0800423 else
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700424 ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200425 hcon->type, hcon->dst_type,
Brian Gix2b64d152011-12-21 16:12:12 -0800426 cpu_to_le32(passkey), 0);
427
428 hci_dev_unlock(hcon->hdev);
429
430 return ret;
431}
432
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300433static void confirm_work(struct work_struct *work)
434{
435 struct smp_chan *smp = container_of(work, struct smp_chan, confirm);
436 struct l2cap_conn *conn = smp->conn;
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200437 struct hci_dev *hdev = conn->hcon->hdev;
438 struct crypto_blkcipher *tfm = hdev->tfm_aes;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300439 struct smp_cmd_pairing_confirm cp;
440 int ret;
441 u8 res[16], reason;
442
443 BT_DBG("conn %p", conn);
444
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200445 /* Prevent mutual access to hdev->tfm_aes */
446 hci_dev_lock(hdev);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300447
448 if (conn->hcon->out)
Marcel Holtmannc8462ca2013-10-13 05:24:02 -0700449 ret = smp_c1(tfm, smp->tk, smp->prnd, smp->preq, smp->prsp,
450 conn->hcon->src_type, &conn->hcon->src,
451 conn->hcon->dst_type, &conn->hcon->dst, res);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300452 else
453 ret = smp_c1(tfm, smp->tk, smp->prnd, smp->preq, smp->prsp,
Marcel Holtmannc8462ca2013-10-13 05:24:02 -0700454 conn->hcon->dst_type, &conn->hcon->dst,
455 conn->hcon->src_type, &conn->hcon->src, res);
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200456
457 hci_dev_unlock(hdev);
458
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300459 if (ret) {
460 reason = SMP_UNSPECIFIED;
461 goto error;
462 }
463
Brian Gix2b64d152011-12-21 16:12:12 -0800464 clear_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags);
465
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300466 swap128(res, cp.confirm_val);
467 smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
468
469 return;
470
471error:
Johan Hedberg84794e12013-11-06 11:24:57 +0200472 smp_failure(conn, reason);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300473}
474
475static void random_work(struct work_struct *work)
476{
477 struct smp_chan *smp = container_of(work, struct smp_chan, random);
478 struct l2cap_conn *conn = smp->conn;
479 struct hci_conn *hcon = conn->hcon;
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200480 struct hci_dev *hdev = hcon->hdev;
481 struct crypto_blkcipher *tfm = hdev->tfm_aes;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300482 u8 reason, confirm[16], res[16], key[16];
483 int ret;
484
485 if (IS_ERR_OR_NULL(tfm)) {
486 reason = SMP_UNSPECIFIED;
487 goto error;
488 }
489
490 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
491
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200492 /* Prevent mutual access to hdev->tfm_aes */
493 hci_dev_lock(hdev);
494
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300495 if (hcon->out)
Marcel Holtmannc8462ca2013-10-13 05:24:02 -0700496 ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp,
497 hcon->src_type, &hcon->src,
498 hcon->dst_type, &hcon->dst, res);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300499 else
500 ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp,
Marcel Holtmannc8462ca2013-10-13 05:24:02 -0700501 hcon->dst_type, &hcon->dst,
502 hcon->src_type, &hcon->src, res);
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200503
504 hci_dev_unlock(hdev);
505
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300506 if (ret) {
507 reason = SMP_UNSPECIFIED;
508 goto error;
509 }
510
511 swap128(res, confirm);
512
513 if (memcmp(smp->pcnf, confirm, sizeof(smp->pcnf)) != 0) {
514 BT_ERR("Pairing failed (confirmation values mismatch)");
515 reason = SMP_CONFIRM_FAILED;
516 goto error;
517 }
518
519 if (hcon->out) {
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -0800520 u8 stk[16];
521 __le64 rand = 0;
522 __le16 ediv = 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300523
524 smp_s1(tfm, smp->tk, smp->rrnd, smp->prnd, key);
525 swap128(key, stk);
526
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300527 memset(stk + smp->enc_key_size, 0,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300528 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300529
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200530 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags)) {
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300531 reason = SMP_UNSPECIFIED;
532 goto error;
533 }
534
535 hci_le_start_enc(hcon, ediv, rand, stk);
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300536 hcon->enc_key_size = smp->enc_key_size;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300537 } else {
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -0800538 u8 stk[16], r[16];
539 __le64 rand = 0;
540 __le16 ediv = 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300541
542 swap128(smp->prnd, r);
543 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(r), r);
544
545 smp_s1(tfm, smp->tk, smp->prnd, smp->rrnd, key);
546 swap128(key, stk);
547
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300548 memset(stk + smp->enc_key_size, 0,
Marcel Holtmannf1560462013-10-13 05:43:25 -0700549 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300550
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700551 hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
Johan Hedberg35d70272014-02-19 14:57:47 +0200552 HCI_SMP_STK_SLAVE, 0, stk, smp->enc_key_size,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300553 ediv, rand);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300554 }
555
556 return;
557
558error:
Johan Hedberg84794e12013-11-06 11:24:57 +0200559 smp_failure(conn, reason);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300560}
561
562static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
563{
564 struct smp_chan *smp;
565
Marcel Holtmannf1560462013-10-13 05:43:25 -0700566 smp = kzalloc(sizeof(*smp), GFP_ATOMIC);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300567 if (!smp)
568 return NULL;
569
570 INIT_WORK(&smp->confirm, confirm_work);
571 INIT_WORK(&smp->random, random_work);
572
573 smp->conn = conn;
574 conn->smp_chan = smp;
Brian Gix2b64d152011-12-21 16:12:12 -0800575 conn->hcon->smp_conn = conn;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300576
577 hci_conn_hold(conn->hcon);
578
579 return smp;
580}
581
582void smp_chan_destroy(struct l2cap_conn *conn)
583{
Brian Gixc8eb9692011-11-23 08:28:35 -0800584 struct smp_chan *smp = conn->smp_chan;
Johan Hedbergf4a407be2014-02-18 21:41:34 +0200585 bool complete;
Brian Gixc8eb9692011-11-23 08:28:35 -0800586
Vinicius Costa Gomesf1c09c02012-02-01 18:27:56 -0300587 BUG_ON(!smp);
Brian Gixc8eb9692011-11-23 08:28:35 -0800588
Johan Hedbergf4a407be2014-02-18 21:41:34 +0200589 complete = test_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
590 mgmt_smp_complete(conn->hcon, complete);
591
Johan Hedberg759331d2014-02-28 10:10:16 +0200592 /* If pairing failed clean up any keys we might have */
593 if (!complete) {
594 if (smp->ltk) {
595 list_del(&smp->ltk->list);
596 kfree(smp->ltk);
597 }
598
599 if (smp->slave_ltk) {
600 list_del(&smp->slave_ltk->list);
601 kfree(smp->slave_ltk);
602 }
603
604 if (smp->remote_irk) {
605 list_del(&smp->remote_irk->list);
606 kfree(smp->remote_irk);
607 }
608 }
609
Brian Gixc8eb9692011-11-23 08:28:35 -0800610 kfree(smp);
611 conn->smp_chan = NULL;
Brian Gix2b64d152011-12-21 16:12:12 -0800612 conn->hcon->smp_conn = NULL;
David Herrmann76a68ba2013-04-06 20:28:37 +0200613 hci_conn_drop(conn->hcon);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300614}
615
Brian Gix2b64d152011-12-21 16:12:12 -0800616int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
617{
618 struct l2cap_conn *conn = hcon->smp_conn;
619 struct smp_chan *smp;
620 u32 value;
621 u8 key[16];
622
623 BT_DBG("");
624
625 if (!conn)
626 return -ENOTCONN;
627
628 smp = conn->smp_chan;
629
630 switch (mgmt_op) {
631 case MGMT_OP_USER_PASSKEY_REPLY:
632 value = le32_to_cpu(passkey);
633 memset(key, 0, sizeof(key));
634 BT_DBG("PassKey: %d", value);
635 put_unaligned_le32(value, key);
636 swap128(key, smp->tk);
637 /* Fall Through */
638 case MGMT_OP_USER_CONFIRM_REPLY:
639 set_bit(SMP_FLAG_TK_VALID, &smp->smp_flags);
640 break;
641 case MGMT_OP_USER_PASSKEY_NEG_REPLY:
642 case MGMT_OP_USER_CONFIRM_NEG_REPLY:
Johan Hedberg84794e12013-11-06 11:24:57 +0200643 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
Brian Gix2b64d152011-12-21 16:12:12 -0800644 return 0;
645 default:
Johan Hedberg84794e12013-11-06 11:24:57 +0200646 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
Brian Gix2b64d152011-12-21 16:12:12 -0800647 return -EOPNOTSUPP;
648 }
649
650 /* If it is our turn to send Pairing Confirm, do so now */
651 if (test_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags))
652 queue_work(hcon->hdev->workqueue, &smp->confirm);
653
654 return 0;
655}
656
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300657static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300658{
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300659 struct smp_cmd_pairing rsp, *req = (void *) skb->data;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300660 struct smp_chan *smp;
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300661 u8 key_size;
Brian Gix2b64d152011-12-21 16:12:12 -0800662 u8 auth = SMP_AUTH_NONE;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300663 int ret;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300664
665 BT_DBG("conn %p", conn);
666
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200667 if (skb->len < sizeof(*req))
668 return SMP_UNSPECIFIED;
669
Brian Gix2b64d152011-12-21 16:12:12 -0800670 if (conn->hcon->link_mode & HCI_LM_MASTER)
671 return SMP_CMD_NOTSUPP;
672
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200673 if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags))
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300674 smp = smp_chan_create(conn);
Andrei Emeltchenkod08fd0e2012-07-19 17:03:43 +0300675 else
676 smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300677
Andrei Emeltchenkod08fd0e2012-07-19 17:03:43 +0300678 if (!smp)
679 return SMP_UNSPECIFIED;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300680
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300681 smp->preq[0] = SMP_CMD_PAIRING_REQ;
682 memcpy(&smp->preq[1], req, sizeof(*req));
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300683 skb_pull(skb, sizeof(*req));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300684
Brian Gix2b64d152011-12-21 16:12:12 -0800685 /* We didn't start the pairing, so match remote */
686 if (req->auth_req & SMP_AUTH_BONDING)
687 auth = req->auth_req;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300688
Ido Yarivfdde0a22012-03-05 20:09:38 +0200689 conn->hcon->pending_sec_level = authreq_to_seclevel(auth);
690
Brian Gix2b64d152011-12-21 16:12:12 -0800691 build_pairing_cmd(conn, req, &rsp, auth);
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300692
693 key_size = min(req->max_key_size, rsp.max_key_size);
694 if (check_enc_key_size(conn, key_size))
695 return SMP_ENC_KEY_SIZE;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300696
Johan Hedberge84a6b12013-12-02 10:49:03 +0200697 get_random_bytes(smp->prnd, sizeof(smp->prnd));
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300698
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300699 smp->prsp[0] = SMP_CMD_PAIRING_RSP;
700 memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300701
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300702 smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300703
Brian Gix2b64d152011-12-21 16:12:12 -0800704 /* Request setup of TK */
705 ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability);
706 if (ret)
707 return SMP_UNSPECIFIED;
708
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300709 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300710}
711
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300712static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300713{
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300714 struct smp_cmd_pairing *req, *rsp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300715 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300716 struct hci_dev *hdev = conn->hcon->hdev;
Brian Gix2b64d152011-12-21 16:12:12 -0800717 u8 key_size, auth = SMP_AUTH_NONE;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300718 int ret;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300719
720 BT_DBG("conn %p", conn);
721
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200722 if (skb->len < sizeof(*rsp))
723 return SMP_UNSPECIFIED;
724
Brian Gix2b64d152011-12-21 16:12:12 -0800725 if (!(conn->hcon->link_mode & HCI_LM_MASTER))
726 return SMP_CMD_NOTSUPP;
727
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300728 skb_pull(skb, sizeof(*rsp));
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300729
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300730 req = (void *) &smp->preq[1];
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300731
732 key_size = min(req->max_key_size, rsp->max_key_size);
733 if (check_enc_key_size(conn, key_size))
734 return SMP_ENC_KEY_SIZE;
735
Johan Hedberge84a6b12013-12-02 10:49:03 +0200736 get_random_bytes(smp->prnd, sizeof(smp->prnd));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300737
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300738 smp->prsp[0] = SMP_CMD_PAIRING_RSP;
739 memcpy(&smp->prsp[1], rsp, sizeof(*rsp));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300740
Brian Gix2b64d152011-12-21 16:12:12 -0800741 if ((req->auth_req & SMP_AUTH_BONDING) &&
Marcel Holtmannf1560462013-10-13 05:43:25 -0700742 (rsp->auth_req & SMP_AUTH_BONDING))
Brian Gix2b64d152011-12-21 16:12:12 -0800743 auth = SMP_AUTH_BONDING;
744
745 auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM;
746
Johan Hedberg476585e2012-06-06 18:54:15 +0800747 ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability);
Brian Gix2b64d152011-12-21 16:12:12 -0800748 if (ret)
749 return SMP_UNSPECIFIED;
750
751 set_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags);
752
753 /* Can't compose response until we have been confirmed */
754 if (!test_bit(SMP_FLAG_TK_VALID, &smp->smp_flags))
755 return 0;
756
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300757 queue_work(hdev->workqueue, &smp->confirm);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300758
759 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300760}
761
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300762static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300763{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300764 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300765 struct hci_dev *hdev = conn->hcon->hdev;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300766
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300767 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
768
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200769 if (skb->len < sizeof(smp->pcnf))
770 return SMP_UNSPECIFIED;
771
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300772 memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf));
773 skb_pull(skb, sizeof(smp->pcnf));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300774
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300775 if (conn->hcon->out) {
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300776 u8 random[16];
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300777
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300778 swap128(smp->prnd, random);
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300779 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(random),
Marcel Holtmannf1560462013-10-13 05:43:25 -0700780 random);
Brian Gix2b64d152011-12-21 16:12:12 -0800781 } else if (test_bit(SMP_FLAG_TK_VALID, &smp->smp_flags)) {
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300782 queue_work(hdev->workqueue, &smp->confirm);
Brian Gix2b64d152011-12-21 16:12:12 -0800783 } else {
784 set_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags);
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300785 }
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300786
787 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300788}
789
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300790static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300791{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300792 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300793 struct hci_dev *hdev = conn->hcon->hdev;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300794
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300795 BT_DBG("conn %p", conn);
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300796
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200797 if (skb->len < sizeof(smp->rrnd))
798 return SMP_UNSPECIFIED;
799
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300800 swap128(skb->data, smp->rrnd);
801 skb_pull(skb, sizeof(smp->rrnd));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300802
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300803 queue_work(hdev->workqueue, &smp->random);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300804
805 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300806}
807
Johan Hedberg4dab7862012-06-07 14:58:37 +0800808static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300809{
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300810 struct smp_ltk *key;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300811 struct hci_conn *hcon = conn->hcon;
812
Johan Hedberg98a0b842014-01-30 19:40:00 -0800813 key = hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type,
814 hcon->out);
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300815 if (!key)
816 return 0;
817
Johan Hedberg4dab7862012-06-07 14:58:37 +0800818 if (sec_level > BT_SECURITY_MEDIUM && !key->authenticated)
819 return 0;
820
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200821 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300822 return 1;
823
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300824 hci_le_start_enc(hcon, key->ediv, key->rand, key->val);
825 hcon->enc_key_size = key->enc_size;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300826
827 return 1;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300828}
Marcel Holtmannf1560462013-10-13 05:43:25 -0700829
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300830static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300831{
832 struct smp_cmd_security_req *rp = (void *) skb->data;
833 struct smp_cmd_pairing cp;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300834 struct hci_conn *hcon = conn->hcon;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300835 struct smp_chan *smp;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300836
837 BT_DBG("conn %p", conn);
838
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200839 if (skb->len < sizeof(*rp))
840 return SMP_UNSPECIFIED;
841
Johan Hedberg86ca9ea2013-11-05 11:30:39 +0200842 if (!(conn->hcon->link_mode & HCI_LM_MASTER))
843 return SMP_CMD_NOTSUPP;
844
Brian Gix2b64d152011-12-21 16:12:12 -0800845 hcon->pending_sec_level = authreq_to_seclevel(rp->auth_req);
Vinicius Costa Gomesfeb45eb2011-08-25 20:02:35 -0300846
Johan Hedberg4dab7862012-06-07 14:58:37 +0800847 if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300848 return 0;
849
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200850 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300851 return 0;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300852
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300853 smp = smp_chan_create(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300854
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300855 skb_pull(skb, sizeof(*rp));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300856
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300857 memset(&cp, 0, sizeof(cp));
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300858 build_pairing_cmd(conn, &cp, NULL, rp->auth_req);
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300859
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300860 smp->preq[0] = SMP_CMD_PAIRING_REQ;
861 memcpy(&smp->preq[1], &cp, sizeof(cp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300862
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300863 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300864
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300865 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300866}
867
Johan Hedbergad32a2f2013-05-14 18:05:12 +0300868bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level)
869{
870 if (sec_level == BT_SECURITY_LOW)
871 return true;
872
873 if (hcon->sec_level >= sec_level)
874 return true;
875
876 return false;
877}
878
Vinicius Costa Gomescc110922012-08-23 21:32:43 -0300879int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300880{
Vinicius Costa Gomescc110922012-08-23 21:32:43 -0300881 struct l2cap_conn *conn = hcon->l2cap_data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300882 struct smp_chan *smp = conn->smp_chan;
Brian Gix2b64d152011-12-21 16:12:12 -0800883 __u8 authreq;
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300884
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -0300885 BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
886
Johan Hedberg757aee02013-04-24 13:05:32 +0300887 if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags))
Andre Guedes2e65c9d2011-06-30 19:20:56 -0300888 return 1;
889
Johan Hedbergad32a2f2013-05-14 18:05:12 +0300890 if (smp_sufficient_security(hcon, sec_level))
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300891 return 1;
892
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300893 if (hcon->link_mode & HCI_LM_MASTER)
Johan Hedberg4dab7862012-06-07 14:58:37 +0800894 if (smp_ltk_encrypt(conn, sec_level))
Vinicius Costa Gomes02bc7452011-07-07 18:59:41 -0300895 goto done;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300896
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200897 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300898 return 0;
899
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300900 smp = smp_chan_create(conn);
Brian Gix2b64d152011-12-21 16:12:12 -0800901 if (!smp)
902 return 1;
903
904 authreq = seclevel_to_authreq(sec_level);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300905
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300906 if (hcon->link_mode & HCI_LM_MASTER) {
907 struct smp_cmd_pairing cp;
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300908
Brian Gix2b64d152011-12-21 16:12:12 -0800909 build_pairing_cmd(conn, &cp, NULL, authreq);
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300910 smp->preq[0] = SMP_CMD_PAIRING_REQ;
911 memcpy(&smp->preq[1], &cp, sizeof(cp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300912
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300913 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
914 } else {
915 struct smp_cmd_security_req cp;
Brian Gix2b64d152011-12-21 16:12:12 -0800916 cp.auth_req = authreq;
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300917 smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
918 }
919
Vinicius Costa Gomes02bc7452011-07-07 18:59:41 -0300920done:
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300921 hcon->pending_sec_level = sec_level;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300922
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300923 return 0;
924}
925
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300926static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
927{
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300928 struct smp_cmd_encrypt_info *rp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300929 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300930
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200931 BT_DBG("conn %p", conn);
932
933 if (skb->len < sizeof(*rp))
934 return SMP_UNSPECIFIED;
935
Johan Hedberg6131ddc2014-02-18 10:19:37 +0200936 /* Ignore this PDU if it wasn't requested */
937 if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
938 return 0;
939
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300940 skb_pull(skb, sizeof(*rp));
941
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300942 memcpy(smp->tk, rp->ltk, sizeof(smp->tk));
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300943
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300944 return 0;
945}
946
947static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
948{
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300949 struct smp_cmd_master_ident *rp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300950 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300951 struct hci_dev *hdev = conn->hcon->hdev;
952 struct hci_conn *hcon = conn->hcon;
Johan Hedberg23d0e122014-02-19 14:57:46 +0200953 struct smp_ltk *ltk;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300954 u8 authenticated;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300955
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200956 BT_DBG("conn %p", conn);
957
958 if (skb->len < sizeof(*rp))
959 return SMP_UNSPECIFIED;
960
Johan Hedberg6131ddc2014-02-18 10:19:37 +0200961 /* Ignore this PDU if it wasn't requested */
962 if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
963 return 0;
964
Johan Hedberg9747a9f2014-02-26 23:33:43 +0200965 /* Mark the information as received */
966 smp->remote_key_dist &= ~SMP_DIST_ENC_KEY;
967
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300968 skb_pull(skb, sizeof(*rp));
969
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300970 hci_dev_lock(hdev);
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700971 authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
Johan Hedberg35d70272014-02-19 14:57:47 +0200972 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, HCI_SMP_LTK,
Johan Hedberg23d0e122014-02-19 14:57:46 +0200973 authenticated, smp->tk, smp->enc_key_size,
974 rp->ediv, rp->rand);
975 smp->ltk = ltk;
Johan Hedbergfd349c02014-02-18 10:19:36 +0200976 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
Johan Hedberg4bd6d382014-02-26 23:33:45 +0200977 smp_distribute_keys(conn);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300978 hci_dev_unlock(hdev);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300979
980 return 0;
981}
982
Johan Hedbergfd349c02014-02-18 10:19:36 +0200983static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
984{
985 struct smp_cmd_ident_info *info = (void *) skb->data;
986 struct smp_chan *smp = conn->smp_chan;
987
988 BT_DBG("");
989
990 if (skb->len < sizeof(*info))
991 return SMP_UNSPECIFIED;
992
Johan Hedberg6131ddc2014-02-18 10:19:37 +0200993 /* Ignore this PDU if it wasn't requested */
994 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
995 return 0;
996
Johan Hedbergfd349c02014-02-18 10:19:36 +0200997 skb_pull(skb, sizeof(*info));
998
999 memcpy(smp->irk, info->irk, 16);
1000
1001 return 0;
1002}
1003
1004static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
1005 struct sk_buff *skb)
1006{
1007 struct smp_cmd_ident_addr_info *info = (void *) skb->data;
1008 struct smp_chan *smp = conn->smp_chan;
1009 struct hci_conn *hcon = conn->hcon;
1010 bdaddr_t rpa;
1011
1012 BT_DBG("");
1013
1014 if (skb->len < sizeof(*info))
1015 return SMP_UNSPECIFIED;
1016
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001017 /* Ignore this PDU if it wasn't requested */
1018 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
1019 return 0;
1020
Johan Hedberg9747a9f2014-02-26 23:33:43 +02001021 /* Mark the information as received */
1022 smp->remote_key_dist &= ~SMP_DIST_ID_KEY;
1023
Johan Hedbergfd349c02014-02-18 10:19:36 +02001024 skb_pull(skb, sizeof(*info));
1025
Johan Hedberga9a58f82014-02-25 22:24:37 +02001026 /* Strictly speaking the Core Specification (4.1) allows sending
1027 * an empty address which would force us to rely on just the IRK
1028 * as "identity information". However, since such
1029 * implementations are not known of and in order to not over
1030 * complicate our implementation, simply pretend that we never
1031 * received an IRK for such a device.
1032 */
1033 if (!bacmp(&info->bdaddr, BDADDR_ANY)) {
1034 BT_ERR("Ignoring IRK with no identity address");
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001035 smp_distribute_keys(conn);
Johan Hedberga9a58f82014-02-25 22:24:37 +02001036 return 0;
1037 }
1038
Johan Hedbergfd349c02014-02-18 10:19:36 +02001039 bacpy(&smp->id_addr, &info->bdaddr);
1040 smp->id_addr_type = info->addr_type;
1041
1042 if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type))
1043 bacpy(&rpa, &hcon->dst);
1044 else
1045 bacpy(&rpa, BDADDR_ANY);
1046
Johan Hedberg23d0e122014-02-19 14:57:46 +02001047 smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
1048 smp->id_addr_type, smp->irk, &rpa);
Johan Hedbergfd349c02014-02-18 10:19:36 +02001049
Johan Hedberg68d6f6d2014-02-18 21:41:32 +02001050 /* Track the connection based on the Identity Address from now on */
1051 bacpy(&hcon->dst, &smp->id_addr);
1052 hcon->dst_type = smp->id_addr_type;
1053
Johan Hedberg387a33e2014-02-18 21:41:33 +02001054 l2cap_conn_update_id_addr(hcon);
1055
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001056 smp_distribute_keys(conn);
Johan Hedbergfd349c02014-02-18 10:19:36 +02001057
1058 return 0;
1059}
1060
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001061int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
1062{
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001063 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann92381f52013-10-03 01:23:08 -07001064 __u8 code, reason;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001065 int err = 0;
1066
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001067 if (hcon->type != LE_LINK) {
1068 kfree_skb(skb);
Johan Hedberg34327112013-10-16 11:37:01 +03001069 return 0;
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001070 }
1071
Marcel Holtmann92381f52013-10-03 01:23:08 -07001072 if (skb->len < 1) {
1073 kfree_skb(skb);
1074 return -EILSEQ;
1075 }
1076
Marcel Holtmann06ae3312013-10-18 03:43:00 -07001077 if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) {
Andre Guedes2e65c9d2011-06-30 19:20:56 -03001078 err = -ENOTSUPP;
1079 reason = SMP_PAIRING_NOTSUPP;
1080 goto done;
1081 }
1082
Marcel Holtmann92381f52013-10-03 01:23:08 -07001083 code = skb->data[0];
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001084 skb_pull(skb, sizeof(code));
1085
Johan Hedberg8cf9fa12013-01-29 10:44:23 -06001086 /*
1087 * The SMP context must be initialized for all other PDUs except
1088 * pairing and security requests. If we get any other PDU when
1089 * not initialized simply disconnect (done if this function
1090 * returns an error).
1091 */
1092 if (code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ &&
1093 !conn->smp_chan) {
1094 BT_ERR("Unexpected SMP command 0x%02x. Disconnecting.", code);
1095 kfree_skb(skb);
1096 return -ENOTSUPP;
1097 }
1098
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001099 switch (code) {
1100 case SMP_CMD_PAIRING_REQ:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001101 reason = smp_cmd_pairing_req(conn, skb);
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001102 break;
1103
1104 case SMP_CMD_PAIRING_FAIL:
Johan Hedberg84794e12013-11-06 11:24:57 +02001105 smp_failure(conn, 0);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001106 reason = 0;
1107 err = -EPERM;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001108 break;
1109
1110 case SMP_CMD_PAIRING_RSP:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001111 reason = smp_cmd_pairing_rsp(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001112 break;
1113
1114 case SMP_CMD_SECURITY_REQ:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001115 reason = smp_cmd_security_req(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001116 break;
1117
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001118 case SMP_CMD_PAIRING_CONFIRM:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001119 reason = smp_cmd_pairing_confirm(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001120 break;
1121
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001122 case SMP_CMD_PAIRING_RANDOM:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001123 reason = smp_cmd_pairing_random(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001124 break;
1125
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001126 case SMP_CMD_ENCRYPT_INFO:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001127 reason = smp_cmd_encrypt_info(conn, skb);
1128 break;
1129
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001130 case SMP_CMD_MASTER_IDENT:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001131 reason = smp_cmd_master_ident(conn, skb);
1132 break;
1133
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001134 case SMP_CMD_IDENT_INFO:
Johan Hedbergfd349c02014-02-18 10:19:36 +02001135 reason = smp_cmd_ident_info(conn, skb);
1136 break;
1137
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001138 case SMP_CMD_IDENT_ADDR_INFO:
Johan Hedbergfd349c02014-02-18 10:19:36 +02001139 reason = smp_cmd_ident_addr_info(conn, skb);
1140 break;
1141
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001142 case SMP_CMD_SIGN_INFO:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001143 /* Just ignored */
1144 reason = 0;
1145 break;
1146
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001147 default:
1148 BT_DBG("Unknown command code 0x%2.2x", code);
1149
1150 reason = SMP_CMD_NOTSUPP;
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -03001151 err = -EOPNOTSUPP;
1152 goto done;
1153 }
1154
1155done:
1156 if (reason)
Johan Hedberg84794e12013-11-06 11:24:57 +02001157 smp_failure(conn, reason);
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001158
1159 kfree_skb(skb);
1160 return err;
1161}
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001162
Johan Hedberg35d70272014-02-19 14:57:47 +02001163static void smp_notify_keys(struct l2cap_conn *conn)
1164{
1165 struct smp_chan *smp = conn->smp_chan;
1166 struct hci_conn *hcon = conn->hcon;
1167 struct hci_dev *hdev = hcon->hdev;
1168
Johan Hedberg95fbac82014-02-19 15:18:31 +02001169 if (smp->remote_irk)
1170 mgmt_new_irk(hdev, smp->remote_irk);
1171
Johan Hedberg35d70272014-02-19 14:57:47 +02001172 if (smp->ltk) {
1173 smp->ltk->bdaddr_type = hcon->dst_type;
1174 bacpy(&smp->ltk->bdaddr, &hcon->dst);
1175 mgmt_new_ltk(hdev, smp->ltk);
1176 }
1177
1178 if (smp->slave_ltk) {
1179 smp->slave_ltk->bdaddr_type = hcon->dst_type;
1180 bacpy(&smp->slave_ltk->bdaddr, &hcon->dst);
1181 mgmt_new_ltk(hdev, smp->slave_ltk);
1182 }
1183}
1184
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001185int smp_distribute_keys(struct l2cap_conn *conn)
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001186{
1187 struct smp_cmd_pairing *req, *rsp;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001188 struct smp_chan *smp = conn->smp_chan;
Johan Hedberg524237c2014-02-22 19:06:31 +02001189 struct hci_conn *hcon = conn->hcon;
1190 struct hci_dev *hdev = hcon->hdev;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001191 __u8 *keydist;
1192
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001193 BT_DBG("conn %p", conn);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001194
Johan Hedberg524237c2014-02-22 19:06:31 +02001195 if (!test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001196 return 0;
1197
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001198 rsp = (void *) &smp->prsp[1];
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001199
1200 /* The responder sends its keys first */
Johan Hedbergefabba32014-02-26 23:33:44 +02001201 if (hcon->out && (smp->remote_key_dist & 0x07))
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001202 return 0;
1203
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001204 req = (void *) &smp->preq[1];
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001205
Johan Hedberg524237c2014-02-22 19:06:31 +02001206 if (hcon->out) {
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001207 keydist = &rsp->init_key_dist;
1208 *keydist &= req->init_key_dist;
1209 } else {
1210 keydist = &rsp->resp_key_dist;
1211 *keydist &= req->resp_key_dist;
1212 }
1213
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001214 BT_DBG("keydist 0x%x", *keydist);
1215
1216 if (*keydist & SMP_DIST_ENC_KEY) {
1217 struct smp_cmd_encrypt_info enc;
1218 struct smp_cmd_master_ident ident;
Johan Hedberg23d0e122014-02-19 14:57:46 +02001219 struct smp_ltk *ltk;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001220 u8 authenticated;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001221 __le16 ediv;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001222 __le64 rand;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001223
1224 get_random_bytes(enc.ltk, sizeof(enc.ltk));
1225 get_random_bytes(&ediv, sizeof(ediv));
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001226 get_random_bytes(&rand, sizeof(rand));
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001227
1228 smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
1229
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001230 authenticated = hcon->sec_level == BT_SECURITY_HIGH;
Johan Hedberg524237c2014-02-22 19:06:31 +02001231 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type,
Johan Hedberg35d70272014-02-19 14:57:47 +02001232 HCI_SMP_LTK_SLAVE, authenticated, enc.ltk,
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001233 smp->enc_key_size, ediv, rand);
Johan Hedberg23d0e122014-02-19 14:57:46 +02001234 smp->slave_ltk = ltk;
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001235
Andrei Emeltchenko58115372012-03-12 12:13:06 +02001236 ident.ediv = ediv;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001237 ident.rand = rand;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001238
1239 smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident);
1240
1241 *keydist &= ~SMP_DIST_ENC_KEY;
1242 }
1243
1244 if (*keydist & SMP_DIST_ID_KEY) {
1245 struct smp_cmd_ident_addr_info addrinfo;
1246 struct smp_cmd_ident_info idinfo;
1247
Johan Hedberg863efaf2014-02-22 19:06:32 +02001248 memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk));
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001249
1250 smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo);
1251
Johan Hedberg82d4b352014-02-23 19:42:18 +02001252 /* The hci_conn contains the local identity address
1253 * after the connection has been established.
1254 *
1255 * This is true even when the connection has been
1256 * established using a resolvable random address.
1257 */
Johan Hedberg524237c2014-02-22 19:06:31 +02001258 bacpy(&addrinfo.bdaddr, &hcon->src);
Johan Hedberg82d4b352014-02-23 19:42:18 +02001259 addrinfo.addr_type = hcon->src_type;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001260
1261 smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo),
Marcel Holtmannf1560462013-10-13 05:43:25 -07001262 &addrinfo);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001263
1264 *keydist &= ~SMP_DIST_ID_KEY;
1265 }
1266
1267 if (*keydist & SMP_DIST_SIGN) {
1268 struct smp_cmd_sign_info sign;
1269
1270 /* Send a dummy key */
1271 get_random_bytes(sign.csrk, sizeof(sign.csrk));
1272
1273 smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign);
1274
1275 *keydist &= ~SMP_DIST_SIGN;
1276 }
1277
Johan Hedbergefabba32014-02-26 23:33:44 +02001278 /* If there are still keys to be received wait for them */
1279 if ((smp->remote_key_dist & 0x07))
1280 return 0;
1281
1282 clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags);
1283 cancel_delayed_work_sync(&conn->security_timer);
1284 set_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
1285 smp_notify_keys(conn);
1286
1287 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001288
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001289 return 0;
1290}