blob: 0de98fe23330c90936e7d0d4cb3c16e70814c8f6 [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) {
520 u8 stk[16], rand[8];
521 __le16 ediv;
522
523 memset(rand, 0, sizeof(rand));
524 ediv = 0;
525
526 smp_s1(tfm, smp->tk, smp->rrnd, smp->prnd, key);
527 swap128(key, stk);
528
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300529 memset(stk + smp->enc_key_size, 0,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300530 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300531
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200532 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags)) {
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300533 reason = SMP_UNSPECIFIED;
534 goto error;
535 }
536
537 hci_le_start_enc(hcon, ediv, rand, stk);
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300538 hcon->enc_key_size = smp->enc_key_size;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300539 } else {
540 u8 stk[16], r[16], rand[8];
541 __le16 ediv;
542
543 memset(rand, 0, sizeof(rand));
544 ediv = 0;
545
546 swap128(smp->prnd, r);
547 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(r), r);
548
549 smp_s1(tfm, smp->tk, smp->prnd, smp->rrnd, key);
550 swap128(key, stk);
551
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300552 memset(stk + smp->enc_key_size, 0,
Marcel Holtmannf1560462013-10-13 05:43:25 -0700553 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300554
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700555 hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
Johan Hedberg35d70272014-02-19 14:57:47 +0200556 HCI_SMP_STK_SLAVE, 0, stk, smp->enc_key_size,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300557 ediv, rand);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300558 }
559
560 return;
561
562error:
Johan Hedberg84794e12013-11-06 11:24:57 +0200563 smp_failure(conn, reason);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300564}
565
566static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
567{
568 struct smp_chan *smp;
569
Marcel Holtmannf1560462013-10-13 05:43:25 -0700570 smp = kzalloc(sizeof(*smp), GFP_ATOMIC);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300571 if (!smp)
572 return NULL;
573
574 INIT_WORK(&smp->confirm, confirm_work);
575 INIT_WORK(&smp->random, random_work);
576
577 smp->conn = conn;
578 conn->smp_chan = smp;
Brian Gix2b64d152011-12-21 16:12:12 -0800579 conn->hcon->smp_conn = conn;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300580
581 hci_conn_hold(conn->hcon);
582
583 return smp;
584}
585
586void smp_chan_destroy(struct l2cap_conn *conn)
587{
Brian Gixc8eb9692011-11-23 08:28:35 -0800588 struct smp_chan *smp = conn->smp_chan;
Johan Hedbergf4a407b2014-02-18 21:41:34 +0200589 bool complete;
Brian Gixc8eb9692011-11-23 08:28:35 -0800590
Vinicius Costa Gomesf1c09c02012-02-01 18:27:56 -0300591 BUG_ON(!smp);
Brian Gixc8eb9692011-11-23 08:28:35 -0800592
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
Brian Gixc8eb9692011-11-23 08:28:35 -0800596 kfree(smp);
597 conn->smp_chan = NULL;
Brian Gix2b64d152011-12-21 16:12:12 -0800598 conn->hcon->smp_conn = NULL;
David Herrmann76a68ba2013-04-06 20:28:37 +0200599 hci_conn_drop(conn->hcon);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300600}
601
Brian Gix2b64d152011-12-21 16:12:12 -0800602int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
603{
604 struct l2cap_conn *conn = hcon->smp_conn;
605 struct smp_chan *smp;
606 u32 value;
607 u8 key[16];
608
609 BT_DBG("");
610
611 if (!conn)
612 return -ENOTCONN;
613
614 smp = conn->smp_chan;
615
616 switch (mgmt_op) {
617 case MGMT_OP_USER_PASSKEY_REPLY:
618 value = le32_to_cpu(passkey);
619 memset(key, 0, sizeof(key));
620 BT_DBG("PassKey: %d", value);
621 put_unaligned_le32(value, key);
622 swap128(key, smp->tk);
623 /* Fall Through */
624 case MGMT_OP_USER_CONFIRM_REPLY:
625 set_bit(SMP_FLAG_TK_VALID, &smp->smp_flags);
626 break;
627 case MGMT_OP_USER_PASSKEY_NEG_REPLY:
628 case MGMT_OP_USER_CONFIRM_NEG_REPLY:
Johan Hedberg84794e12013-11-06 11:24:57 +0200629 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
Brian Gix2b64d152011-12-21 16:12:12 -0800630 return 0;
631 default:
Johan Hedberg84794e12013-11-06 11:24:57 +0200632 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
Brian Gix2b64d152011-12-21 16:12:12 -0800633 return -EOPNOTSUPP;
634 }
635
636 /* If it is our turn to send Pairing Confirm, do so now */
637 if (test_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags))
638 queue_work(hcon->hdev->workqueue, &smp->confirm);
639
640 return 0;
641}
642
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300643static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300644{
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300645 struct smp_cmd_pairing rsp, *req = (void *) skb->data;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300646 struct smp_chan *smp;
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300647 u8 key_size;
Brian Gix2b64d152011-12-21 16:12:12 -0800648 u8 auth = SMP_AUTH_NONE;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300649 int ret;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300650
651 BT_DBG("conn %p", conn);
652
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200653 if (skb->len < sizeof(*req))
654 return SMP_UNSPECIFIED;
655
Brian Gix2b64d152011-12-21 16:12:12 -0800656 if (conn->hcon->link_mode & HCI_LM_MASTER)
657 return SMP_CMD_NOTSUPP;
658
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200659 if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags))
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300660 smp = smp_chan_create(conn);
Andrei Emeltchenkod08fd0e2012-07-19 17:03:43 +0300661 else
662 smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300663
Andrei Emeltchenkod08fd0e2012-07-19 17:03:43 +0300664 if (!smp)
665 return SMP_UNSPECIFIED;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300666
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300667 smp->preq[0] = SMP_CMD_PAIRING_REQ;
668 memcpy(&smp->preq[1], req, sizeof(*req));
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300669 skb_pull(skb, sizeof(*req));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300670
Brian Gix2b64d152011-12-21 16:12:12 -0800671 /* We didn't start the pairing, so match remote */
672 if (req->auth_req & SMP_AUTH_BONDING)
673 auth = req->auth_req;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300674
Ido Yarivfdde0a22012-03-05 20:09:38 +0200675 conn->hcon->pending_sec_level = authreq_to_seclevel(auth);
676
Brian Gix2b64d152011-12-21 16:12:12 -0800677 build_pairing_cmd(conn, req, &rsp, auth);
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300678
679 key_size = min(req->max_key_size, rsp.max_key_size);
680 if (check_enc_key_size(conn, key_size))
681 return SMP_ENC_KEY_SIZE;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300682
Johan Hedberge84a6b12013-12-02 10:49:03 +0200683 get_random_bytes(smp->prnd, sizeof(smp->prnd));
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300684
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300685 smp->prsp[0] = SMP_CMD_PAIRING_RSP;
686 memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300687
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300688 smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300689
Brian Gix2b64d152011-12-21 16:12:12 -0800690 /* Request setup of TK */
691 ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability);
692 if (ret)
693 return SMP_UNSPECIFIED;
694
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300695 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300696}
697
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300698static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300699{
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300700 struct smp_cmd_pairing *req, *rsp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300701 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300702 struct hci_dev *hdev = conn->hcon->hdev;
Brian Gix2b64d152011-12-21 16:12:12 -0800703 u8 key_size, auth = SMP_AUTH_NONE;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300704 int ret;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300705
706 BT_DBG("conn %p", conn);
707
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200708 if (skb->len < sizeof(*rsp))
709 return SMP_UNSPECIFIED;
710
Brian Gix2b64d152011-12-21 16:12:12 -0800711 if (!(conn->hcon->link_mode & HCI_LM_MASTER))
712 return SMP_CMD_NOTSUPP;
713
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300714 skb_pull(skb, sizeof(*rsp));
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300715
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300716 req = (void *) &smp->preq[1];
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300717
718 key_size = min(req->max_key_size, rsp->max_key_size);
719 if (check_enc_key_size(conn, key_size))
720 return SMP_ENC_KEY_SIZE;
721
Johan Hedberge84a6b12013-12-02 10:49:03 +0200722 get_random_bytes(smp->prnd, sizeof(smp->prnd));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300723
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300724 smp->prsp[0] = SMP_CMD_PAIRING_RSP;
725 memcpy(&smp->prsp[1], rsp, sizeof(*rsp));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300726
Brian Gix2b64d152011-12-21 16:12:12 -0800727 if ((req->auth_req & SMP_AUTH_BONDING) &&
Marcel Holtmannf1560462013-10-13 05:43:25 -0700728 (rsp->auth_req & SMP_AUTH_BONDING))
Brian Gix2b64d152011-12-21 16:12:12 -0800729 auth = SMP_AUTH_BONDING;
730
731 auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM;
732
Johan Hedberg476585e2012-06-06 18:54:15 +0800733 ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability);
Brian Gix2b64d152011-12-21 16:12:12 -0800734 if (ret)
735 return SMP_UNSPECIFIED;
736
737 set_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags);
738
739 /* Can't compose response until we have been confirmed */
740 if (!test_bit(SMP_FLAG_TK_VALID, &smp->smp_flags))
741 return 0;
742
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300743 queue_work(hdev->workqueue, &smp->confirm);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300744
745 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300746}
747
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300748static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300749{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300750 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300751 struct hci_dev *hdev = conn->hcon->hdev;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300752
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300753 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
754
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200755 if (skb->len < sizeof(smp->pcnf))
756 return SMP_UNSPECIFIED;
757
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300758 memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf));
759 skb_pull(skb, sizeof(smp->pcnf));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300760
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300761 if (conn->hcon->out) {
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300762 u8 random[16];
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300763
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300764 swap128(smp->prnd, random);
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300765 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(random),
Marcel Holtmannf1560462013-10-13 05:43:25 -0700766 random);
Brian Gix2b64d152011-12-21 16:12:12 -0800767 } else if (test_bit(SMP_FLAG_TK_VALID, &smp->smp_flags)) {
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300768 queue_work(hdev->workqueue, &smp->confirm);
Brian Gix2b64d152011-12-21 16:12:12 -0800769 } else {
770 set_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags);
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300771 }
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300772
773 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300774}
775
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300776static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300777{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300778 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300779 struct hci_dev *hdev = conn->hcon->hdev;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300780
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300781 BT_DBG("conn %p", conn);
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300782
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200783 if (skb->len < sizeof(smp->rrnd))
784 return SMP_UNSPECIFIED;
785
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300786 swap128(skb->data, smp->rrnd);
787 skb_pull(skb, sizeof(smp->rrnd));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300788
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300789 queue_work(hdev->workqueue, &smp->random);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300790
791 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300792}
793
Johan Hedberg4dab7862012-06-07 14:58:37 +0800794static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300795{
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300796 struct smp_ltk *key;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300797 struct hci_conn *hcon = conn->hcon;
798
Johan Hedberg98a0b842014-01-30 19:40:00 -0800799 key = hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type,
800 hcon->out);
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300801 if (!key)
802 return 0;
803
Johan Hedberg4dab7862012-06-07 14:58:37 +0800804 if (sec_level > BT_SECURITY_MEDIUM && !key->authenticated)
805 return 0;
806
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200807 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300808 return 1;
809
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300810 hci_le_start_enc(hcon, key->ediv, key->rand, key->val);
811 hcon->enc_key_size = key->enc_size;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300812
813 return 1;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300814}
Marcel Holtmannf1560462013-10-13 05:43:25 -0700815
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300816static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300817{
818 struct smp_cmd_security_req *rp = (void *) skb->data;
819 struct smp_cmd_pairing cp;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300820 struct hci_conn *hcon = conn->hcon;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300821 struct smp_chan *smp;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300822
823 BT_DBG("conn %p", conn);
824
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200825 if (skb->len < sizeof(*rp))
826 return SMP_UNSPECIFIED;
827
Johan Hedberg86ca9ea2013-11-05 11:30:39 +0200828 if (!(conn->hcon->link_mode & HCI_LM_MASTER))
829 return SMP_CMD_NOTSUPP;
830
Brian Gix2b64d152011-12-21 16:12:12 -0800831 hcon->pending_sec_level = authreq_to_seclevel(rp->auth_req);
Vinicius Costa Gomesfeb45eb2011-08-25 20:02:35 -0300832
Johan Hedberg4dab7862012-06-07 14:58:37 +0800833 if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300834 return 0;
835
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200836 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300837 return 0;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300838
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300839 smp = smp_chan_create(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300840
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300841 skb_pull(skb, sizeof(*rp));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300842
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300843 memset(&cp, 0, sizeof(cp));
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300844 build_pairing_cmd(conn, &cp, NULL, rp->auth_req);
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300845
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300846 smp->preq[0] = SMP_CMD_PAIRING_REQ;
847 memcpy(&smp->preq[1], &cp, sizeof(cp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300848
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300849 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300850
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300851 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300852}
853
Johan Hedbergad32a2f2013-05-14 18:05:12 +0300854bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level)
855{
856 if (sec_level == BT_SECURITY_LOW)
857 return true;
858
859 if (hcon->sec_level >= sec_level)
860 return true;
861
862 return false;
863}
864
Vinicius Costa Gomescc110922012-08-23 21:32:43 -0300865int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300866{
Vinicius Costa Gomescc110922012-08-23 21:32:43 -0300867 struct l2cap_conn *conn = hcon->l2cap_data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300868 struct smp_chan *smp = conn->smp_chan;
Brian Gix2b64d152011-12-21 16:12:12 -0800869 __u8 authreq;
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300870
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -0300871 BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
872
Johan Hedberg757aee02013-04-24 13:05:32 +0300873 if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags))
Andre Guedes2e65c9d2011-06-30 19:20:56 -0300874 return 1;
875
Johan Hedbergad32a2f2013-05-14 18:05:12 +0300876 if (smp_sufficient_security(hcon, sec_level))
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300877 return 1;
878
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300879 if (hcon->link_mode & HCI_LM_MASTER)
Johan Hedberg4dab7862012-06-07 14:58:37 +0800880 if (smp_ltk_encrypt(conn, sec_level))
Vinicius Costa Gomes02bc7452011-07-07 18:59:41 -0300881 goto done;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300882
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200883 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300884 return 0;
885
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300886 smp = smp_chan_create(conn);
Brian Gix2b64d152011-12-21 16:12:12 -0800887 if (!smp)
888 return 1;
889
890 authreq = seclevel_to_authreq(sec_level);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300891
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300892 if (hcon->link_mode & HCI_LM_MASTER) {
893 struct smp_cmd_pairing cp;
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300894
Brian Gix2b64d152011-12-21 16:12:12 -0800895 build_pairing_cmd(conn, &cp, NULL, authreq);
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300896 smp->preq[0] = SMP_CMD_PAIRING_REQ;
897 memcpy(&smp->preq[1], &cp, sizeof(cp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300898
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300899 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
900 } else {
901 struct smp_cmd_security_req cp;
Brian Gix2b64d152011-12-21 16:12:12 -0800902 cp.auth_req = authreq;
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300903 smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
904 }
905
Vinicius Costa Gomes02bc7452011-07-07 18:59:41 -0300906done:
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300907 hcon->pending_sec_level = sec_level;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300908
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300909 return 0;
910}
911
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300912static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
913{
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300914 struct smp_cmd_encrypt_info *rp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300915 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300916
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200917 BT_DBG("conn %p", conn);
918
919 if (skb->len < sizeof(*rp))
920 return SMP_UNSPECIFIED;
921
Johan Hedberg6131ddc2014-02-18 10:19:37 +0200922 /* Ignore this PDU if it wasn't requested */
923 if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
924 return 0;
925
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300926 skb_pull(skb, sizeof(*rp));
927
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300928 memcpy(smp->tk, rp->ltk, sizeof(smp->tk));
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300929
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300930 return 0;
931}
932
933static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
934{
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300935 struct smp_cmd_master_ident *rp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300936 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300937 struct hci_dev *hdev = conn->hcon->hdev;
938 struct hci_conn *hcon = conn->hcon;
Johan Hedberg23d0e122014-02-19 14:57:46 +0200939 struct smp_ltk *ltk;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300940 u8 authenticated;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300941
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200942 BT_DBG("conn %p", conn);
943
944 if (skb->len < sizeof(*rp))
945 return SMP_UNSPECIFIED;
946
Johan Hedberg6131ddc2014-02-18 10:19:37 +0200947 /* Ignore this PDU if it wasn't requested */
948 if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
949 return 0;
950
Johan Hedberg9747a9f2014-02-26 23:33:43 +0200951 /* Mark the information as received */
952 smp->remote_key_dist &= ~SMP_DIST_ENC_KEY;
953
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300954 skb_pull(skb, sizeof(*rp));
955
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300956 hci_dev_lock(hdev);
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700957 authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
Johan Hedberg35d70272014-02-19 14:57:47 +0200958 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, HCI_SMP_LTK,
Johan Hedberg23d0e122014-02-19 14:57:46 +0200959 authenticated, smp->tk, smp->enc_key_size,
960 rp->ediv, rp->rand);
961 smp->ltk = ltk;
Johan Hedbergfd349c02014-02-18 10:19:36 +0200962 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
Johan Hedberg4bd6d382014-02-26 23:33:45 +0200963 smp_distribute_keys(conn);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300964 hci_dev_unlock(hdev);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300965
966 return 0;
967}
968
Johan Hedbergfd349c02014-02-18 10:19:36 +0200969static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
970{
971 struct smp_cmd_ident_info *info = (void *) skb->data;
972 struct smp_chan *smp = conn->smp_chan;
973
974 BT_DBG("");
975
976 if (skb->len < sizeof(*info))
977 return SMP_UNSPECIFIED;
978
Johan Hedberg6131ddc2014-02-18 10:19:37 +0200979 /* Ignore this PDU if it wasn't requested */
980 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
981 return 0;
982
Johan Hedbergfd349c02014-02-18 10:19:36 +0200983 skb_pull(skb, sizeof(*info));
984
985 memcpy(smp->irk, info->irk, 16);
986
987 return 0;
988}
989
990static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
991 struct sk_buff *skb)
992{
993 struct smp_cmd_ident_addr_info *info = (void *) skb->data;
994 struct smp_chan *smp = conn->smp_chan;
995 struct hci_conn *hcon = conn->hcon;
996 bdaddr_t rpa;
997
998 BT_DBG("");
999
1000 if (skb->len < sizeof(*info))
1001 return SMP_UNSPECIFIED;
1002
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001003 /* Ignore this PDU if it wasn't requested */
1004 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
1005 return 0;
1006
Johan Hedberg9747a9f2014-02-26 23:33:43 +02001007 /* Mark the information as received */
1008 smp->remote_key_dist &= ~SMP_DIST_ID_KEY;
1009
Johan Hedbergfd349c02014-02-18 10:19:36 +02001010 skb_pull(skb, sizeof(*info));
1011
Johan Hedberga9a58f82014-02-25 22:24:37 +02001012 /* Strictly speaking the Core Specification (4.1) allows sending
1013 * an empty address which would force us to rely on just the IRK
1014 * as "identity information". However, since such
1015 * implementations are not known of and in order to not over
1016 * complicate our implementation, simply pretend that we never
1017 * received an IRK for such a device.
1018 */
1019 if (!bacmp(&info->bdaddr, BDADDR_ANY)) {
1020 BT_ERR("Ignoring IRK with no identity address");
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001021 smp_distribute_keys(conn);
Johan Hedberga9a58f82014-02-25 22:24:37 +02001022 return 0;
1023 }
1024
Johan Hedbergfd349c02014-02-18 10:19:36 +02001025 bacpy(&smp->id_addr, &info->bdaddr);
1026 smp->id_addr_type = info->addr_type;
1027
1028 if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type))
1029 bacpy(&rpa, &hcon->dst);
1030 else
1031 bacpy(&rpa, BDADDR_ANY);
1032
Johan Hedberg23d0e122014-02-19 14:57:46 +02001033 smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
1034 smp->id_addr_type, smp->irk, &rpa);
Johan Hedbergfd349c02014-02-18 10:19:36 +02001035
Johan Hedberg68d6f6d2014-02-18 21:41:32 +02001036 /* Track the connection based on the Identity Address from now on */
1037 bacpy(&hcon->dst, &smp->id_addr);
1038 hcon->dst_type = smp->id_addr_type;
1039
Johan Hedberg387a33e2014-02-18 21:41:33 +02001040 l2cap_conn_update_id_addr(hcon);
1041
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001042 smp_distribute_keys(conn);
Johan Hedbergfd349c02014-02-18 10:19:36 +02001043
1044 return 0;
1045}
1046
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001047int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
1048{
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001049 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann92381f52013-10-03 01:23:08 -07001050 __u8 code, reason;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001051 int err = 0;
1052
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001053 if (hcon->type != LE_LINK) {
1054 kfree_skb(skb);
Johan Hedberg34327112013-10-16 11:37:01 +03001055 return 0;
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001056 }
1057
Marcel Holtmann92381f52013-10-03 01:23:08 -07001058 if (skb->len < 1) {
1059 kfree_skb(skb);
1060 return -EILSEQ;
1061 }
1062
Marcel Holtmann06ae3312013-10-18 03:43:00 -07001063 if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) {
Andre Guedes2e65c9d2011-06-30 19:20:56 -03001064 err = -ENOTSUPP;
1065 reason = SMP_PAIRING_NOTSUPP;
1066 goto done;
1067 }
1068
Marcel Holtmann92381f52013-10-03 01:23:08 -07001069 code = skb->data[0];
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001070 skb_pull(skb, sizeof(code));
1071
Johan Hedberg8cf9fa12013-01-29 10:44:23 -06001072 /*
1073 * The SMP context must be initialized for all other PDUs except
1074 * pairing and security requests. If we get any other PDU when
1075 * not initialized simply disconnect (done if this function
1076 * returns an error).
1077 */
1078 if (code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ &&
1079 !conn->smp_chan) {
1080 BT_ERR("Unexpected SMP command 0x%02x. Disconnecting.", code);
1081 kfree_skb(skb);
1082 return -ENOTSUPP;
1083 }
1084
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001085 switch (code) {
1086 case SMP_CMD_PAIRING_REQ:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001087 reason = smp_cmd_pairing_req(conn, skb);
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001088 break;
1089
1090 case SMP_CMD_PAIRING_FAIL:
Johan Hedberg84794e12013-11-06 11:24:57 +02001091 smp_failure(conn, 0);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001092 reason = 0;
1093 err = -EPERM;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001094 break;
1095
1096 case SMP_CMD_PAIRING_RSP:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001097 reason = smp_cmd_pairing_rsp(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001098 break;
1099
1100 case SMP_CMD_SECURITY_REQ:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001101 reason = smp_cmd_security_req(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001102 break;
1103
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001104 case SMP_CMD_PAIRING_CONFIRM:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001105 reason = smp_cmd_pairing_confirm(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001106 break;
1107
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001108 case SMP_CMD_PAIRING_RANDOM:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001109 reason = smp_cmd_pairing_random(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001110 break;
1111
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001112 case SMP_CMD_ENCRYPT_INFO:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001113 reason = smp_cmd_encrypt_info(conn, skb);
1114 break;
1115
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001116 case SMP_CMD_MASTER_IDENT:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001117 reason = smp_cmd_master_ident(conn, skb);
1118 break;
1119
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001120 case SMP_CMD_IDENT_INFO:
Johan Hedbergfd349c02014-02-18 10:19:36 +02001121 reason = smp_cmd_ident_info(conn, skb);
1122 break;
1123
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001124 case SMP_CMD_IDENT_ADDR_INFO:
Johan Hedbergfd349c02014-02-18 10:19:36 +02001125 reason = smp_cmd_ident_addr_info(conn, skb);
1126 break;
1127
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001128 case SMP_CMD_SIGN_INFO:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001129 /* Just ignored */
1130 reason = 0;
1131 break;
1132
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001133 default:
1134 BT_DBG("Unknown command code 0x%2.2x", code);
1135
1136 reason = SMP_CMD_NOTSUPP;
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -03001137 err = -EOPNOTSUPP;
1138 goto done;
1139 }
1140
1141done:
1142 if (reason)
Johan Hedberg84794e12013-11-06 11:24:57 +02001143 smp_failure(conn, reason);
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001144
1145 kfree_skb(skb);
1146 return err;
1147}
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001148
Johan Hedberg35d70272014-02-19 14:57:47 +02001149static void smp_notify_keys(struct l2cap_conn *conn)
1150{
1151 struct smp_chan *smp = conn->smp_chan;
1152 struct hci_conn *hcon = conn->hcon;
1153 struct hci_dev *hdev = hcon->hdev;
1154
Johan Hedberg95fbac82014-02-19 15:18:31 +02001155 if (smp->remote_irk)
1156 mgmt_new_irk(hdev, smp->remote_irk);
1157
Johan Hedberg35d70272014-02-19 14:57:47 +02001158 if (smp->ltk) {
1159 smp->ltk->bdaddr_type = hcon->dst_type;
1160 bacpy(&smp->ltk->bdaddr, &hcon->dst);
1161 mgmt_new_ltk(hdev, smp->ltk);
1162 }
1163
1164 if (smp->slave_ltk) {
1165 smp->slave_ltk->bdaddr_type = hcon->dst_type;
1166 bacpy(&smp->slave_ltk->bdaddr, &hcon->dst);
1167 mgmt_new_ltk(hdev, smp->slave_ltk);
1168 }
1169}
1170
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001171int smp_distribute_keys(struct l2cap_conn *conn)
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001172{
1173 struct smp_cmd_pairing *req, *rsp;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001174 struct smp_chan *smp = conn->smp_chan;
Johan Hedberg524237c2014-02-22 19:06:31 +02001175 struct hci_conn *hcon = conn->hcon;
1176 struct hci_dev *hdev = hcon->hdev;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001177 __u8 *keydist;
1178
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001179 BT_DBG("conn %p", conn);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001180
Johan Hedberg524237c2014-02-22 19:06:31 +02001181 if (!test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001182 return 0;
1183
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001184 rsp = (void *) &smp->prsp[1];
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001185
1186 /* The responder sends its keys first */
Johan Hedbergefabba32014-02-26 23:33:44 +02001187 if (hcon->out && (smp->remote_key_dist & 0x07))
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001188 return 0;
1189
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001190 req = (void *) &smp->preq[1];
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001191
Johan Hedberg524237c2014-02-22 19:06:31 +02001192 if (hcon->out) {
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001193 keydist = &rsp->init_key_dist;
1194 *keydist &= req->init_key_dist;
1195 } else {
1196 keydist = &rsp->resp_key_dist;
1197 *keydist &= req->resp_key_dist;
1198 }
1199
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001200 BT_DBG("keydist 0x%x", *keydist);
1201
1202 if (*keydist & SMP_DIST_ENC_KEY) {
1203 struct smp_cmd_encrypt_info enc;
1204 struct smp_cmd_master_ident ident;
Johan Hedberg23d0e122014-02-19 14:57:46 +02001205 struct smp_ltk *ltk;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001206 u8 authenticated;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001207 __le16 ediv;
1208
1209 get_random_bytes(enc.ltk, sizeof(enc.ltk));
1210 get_random_bytes(&ediv, sizeof(ediv));
1211 get_random_bytes(ident.rand, sizeof(ident.rand));
1212
1213 smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
1214
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001215 authenticated = hcon->sec_level == BT_SECURITY_HIGH;
Johan Hedberg524237c2014-02-22 19:06:31 +02001216 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type,
Johan Hedberg35d70272014-02-19 14:57:47 +02001217 HCI_SMP_LTK_SLAVE, authenticated, enc.ltk,
1218 smp->enc_key_size, ediv, ident.rand);
Johan Hedberg23d0e122014-02-19 14:57:46 +02001219 smp->slave_ltk = ltk;
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001220
Andrei Emeltchenko58115372012-03-12 12:13:06 +02001221 ident.ediv = ediv;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001222
1223 smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident);
1224
1225 *keydist &= ~SMP_DIST_ENC_KEY;
1226 }
1227
1228 if (*keydist & SMP_DIST_ID_KEY) {
1229 struct smp_cmd_ident_addr_info addrinfo;
1230 struct smp_cmd_ident_info idinfo;
1231
Johan Hedberg863efaf2014-02-22 19:06:32 +02001232 memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk));
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001233
1234 smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo);
1235
Johan Hedberg82d4b352014-02-23 19:42:18 +02001236 /* The hci_conn contains the local identity address
1237 * after the connection has been established.
1238 *
1239 * This is true even when the connection has been
1240 * established using a resolvable random address.
1241 */
Johan Hedberg524237c2014-02-22 19:06:31 +02001242 bacpy(&addrinfo.bdaddr, &hcon->src);
Johan Hedberg82d4b352014-02-23 19:42:18 +02001243 addrinfo.addr_type = hcon->src_type;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001244
1245 smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo),
Marcel Holtmannf1560462013-10-13 05:43:25 -07001246 &addrinfo);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001247
1248 *keydist &= ~SMP_DIST_ID_KEY;
1249 }
1250
1251 if (*keydist & SMP_DIST_SIGN) {
1252 struct smp_cmd_sign_info sign;
1253
1254 /* Send a dummy key */
1255 get_random_bytes(sign.csrk, sizeof(sign.csrk));
1256
1257 smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign);
1258
1259 *keydist &= ~SMP_DIST_SIGN;
1260 }
1261
Johan Hedbergefabba32014-02-26 23:33:44 +02001262 /* If there are still keys to be received wait for them */
1263 if ((smp->remote_key_dist & 0x07))
1264 return 0;
1265
1266 clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags);
1267 cancel_delayed_work_sync(&conn->security_timer);
1268 set_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
1269 smp_notify_keys(conn);
1270
1271 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001272
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001273 return 0;
1274}