blob: 8a1b1bf7955544ac7abf7e81db44f651aaf433ff [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);
Joe Perchesdcf4adb2014-03-12 10:52:35 -0700221 lh->cid = 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)) {
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -0700276 local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
277 remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
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
Johan Hedbergb1cd5fd2014-02-28 12:54:17 +0200448 ret = smp_c1(tfm, smp->tk, smp->prnd, smp->preq, smp->prsp,
449 conn->hcon->init_addr_type, &conn->hcon->init_addr,
450 conn->hcon->resp_addr_type, &conn->hcon->resp_addr, res);
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200451
452 hci_dev_unlock(hdev);
453
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300454 if (ret) {
455 reason = SMP_UNSPECIFIED;
456 goto error;
457 }
458
Brian Gix2b64d152011-12-21 16:12:12 -0800459 clear_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags);
460
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300461 swap128(res, cp.confirm_val);
462 smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
463
464 return;
465
466error:
Johan Hedberg84794e12013-11-06 11:24:57 +0200467 smp_failure(conn, reason);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300468}
469
470static void random_work(struct work_struct *work)
471{
472 struct smp_chan *smp = container_of(work, struct smp_chan, random);
473 struct l2cap_conn *conn = smp->conn;
474 struct hci_conn *hcon = conn->hcon;
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200475 struct hci_dev *hdev = hcon->hdev;
476 struct crypto_blkcipher *tfm = hdev->tfm_aes;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300477 u8 reason, confirm[16], res[16], key[16];
478 int ret;
479
480 if (IS_ERR_OR_NULL(tfm)) {
481 reason = SMP_UNSPECIFIED;
482 goto error;
483 }
484
485 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
486
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200487 /* Prevent mutual access to hdev->tfm_aes */
488 hci_dev_lock(hdev);
489
Johan Hedbergb1cd5fd2014-02-28 12:54:17 +0200490 ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp,
491 hcon->init_addr_type, &hcon->init_addr,
492 hcon->resp_addr_type, &hcon->resp_addr, res);
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200493
494 hci_dev_unlock(hdev);
495
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300496 if (ret) {
497 reason = SMP_UNSPECIFIED;
498 goto error;
499 }
500
501 swap128(res, confirm);
502
503 if (memcmp(smp->pcnf, confirm, sizeof(smp->pcnf)) != 0) {
504 BT_ERR("Pairing failed (confirmation values mismatch)");
505 reason = SMP_CONFIRM_FAILED;
506 goto error;
507 }
508
509 if (hcon->out) {
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -0800510 u8 stk[16];
511 __le64 rand = 0;
512 __le16 ediv = 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300513
514 smp_s1(tfm, smp->tk, smp->rrnd, smp->prnd, key);
515 swap128(key, stk);
516
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300517 memset(stk + smp->enc_key_size, 0,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300518 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300519
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200520 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags)) {
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300521 reason = SMP_UNSPECIFIED;
522 goto error;
523 }
524
525 hci_le_start_enc(hcon, ediv, rand, stk);
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300526 hcon->enc_key_size = smp->enc_key_size;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300527 } else {
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -0800528 u8 stk[16], r[16];
529 __le64 rand = 0;
530 __le16 ediv = 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300531
532 swap128(smp->prnd, r);
533 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(r), r);
534
535 smp_s1(tfm, smp->tk, smp->prnd, smp->rrnd, key);
536 swap128(key, stk);
537
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300538 memset(stk + smp->enc_key_size, 0,
Marcel Holtmannf1560462013-10-13 05:43:25 -0700539 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300540
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700541 hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
Johan Hedberg35d70272014-02-19 14:57:47 +0200542 HCI_SMP_STK_SLAVE, 0, stk, smp->enc_key_size,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300543 ediv, rand);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300544 }
545
546 return;
547
548error:
Johan Hedberg84794e12013-11-06 11:24:57 +0200549 smp_failure(conn, reason);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300550}
551
Johan Hedberge3098be2014-02-28 18:10:03 +0200552static void smp_reencrypt(struct work_struct *work)
553{
554 struct smp_chan *smp = container_of(work, struct smp_chan,
555 reencrypt.work);
556 struct l2cap_conn *conn = smp->conn;
557 struct hci_conn *hcon = conn->hcon;
558 struct smp_ltk *ltk = smp->ltk;
559
560 BT_DBG("");
561
562 hci_le_start_enc(hcon, ltk->ediv, ltk->rand, ltk->val);
563 hcon->enc_key_size = ltk->enc_size;
564}
565
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300566static 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);
Johan Hedberge3098be2014-02-28 18:10:03 +0200576 INIT_DELAYED_WORK(&smp->reencrypt, smp_reencrypt);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300577
578 smp->conn = conn;
579 conn->smp_chan = smp;
Brian Gix2b64d152011-12-21 16:12:12 -0800580 conn->hcon->smp_conn = conn;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300581
582 hci_conn_hold(conn->hcon);
583
584 return smp;
585}
586
587void smp_chan_destroy(struct l2cap_conn *conn)
588{
Brian Gixc8eb9692011-11-23 08:28:35 -0800589 struct smp_chan *smp = conn->smp_chan;
Johan Hedbergf4a407b2014-02-18 21:41:34 +0200590 bool complete;
Brian Gixc8eb9692011-11-23 08:28:35 -0800591
Vinicius Costa Gomesf1c09c02012-02-01 18:27:56 -0300592 BUG_ON(!smp);
Brian Gixc8eb9692011-11-23 08:28:35 -0800593
Johan Hedberge3098be2014-02-28 18:10:03 +0200594 cancel_delayed_work_sync(&smp->reencrypt);
595
Johan Hedbergf4a407b2014-02-18 21:41:34 +0200596 complete = test_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
597 mgmt_smp_complete(conn->hcon, complete);
598
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -0700599 kfree(smp->csrk);
600 kfree(smp->slave_csrk);
601
Johan Hedberg759331d2014-02-28 10:10:16 +0200602 /* If pairing failed clean up any keys we might have */
603 if (!complete) {
604 if (smp->ltk) {
605 list_del(&smp->ltk->list);
606 kfree(smp->ltk);
607 }
608
609 if (smp->slave_ltk) {
610 list_del(&smp->slave_ltk->list);
611 kfree(smp->slave_ltk);
612 }
613
614 if (smp->remote_irk) {
615 list_del(&smp->remote_irk->list);
616 kfree(smp->remote_irk);
617 }
618 }
619
Brian Gixc8eb9692011-11-23 08:28:35 -0800620 kfree(smp);
621 conn->smp_chan = NULL;
Brian Gix2b64d152011-12-21 16:12:12 -0800622 conn->hcon->smp_conn = NULL;
David Herrmann76a68ba2013-04-06 20:28:37 +0200623 hci_conn_drop(conn->hcon);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300624}
625
Brian Gix2b64d152011-12-21 16:12:12 -0800626int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
627{
628 struct l2cap_conn *conn = hcon->smp_conn;
629 struct smp_chan *smp;
630 u32 value;
631 u8 key[16];
632
633 BT_DBG("");
634
635 if (!conn)
636 return -ENOTCONN;
637
638 smp = conn->smp_chan;
639
640 switch (mgmt_op) {
641 case MGMT_OP_USER_PASSKEY_REPLY:
642 value = le32_to_cpu(passkey);
643 memset(key, 0, sizeof(key));
644 BT_DBG("PassKey: %d", value);
645 put_unaligned_le32(value, key);
646 swap128(key, smp->tk);
647 /* Fall Through */
648 case MGMT_OP_USER_CONFIRM_REPLY:
649 set_bit(SMP_FLAG_TK_VALID, &smp->smp_flags);
650 break;
651 case MGMT_OP_USER_PASSKEY_NEG_REPLY:
652 case MGMT_OP_USER_CONFIRM_NEG_REPLY:
Johan Hedberg84794e12013-11-06 11:24:57 +0200653 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
Brian Gix2b64d152011-12-21 16:12:12 -0800654 return 0;
655 default:
Johan Hedberg84794e12013-11-06 11:24:57 +0200656 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
Brian Gix2b64d152011-12-21 16:12:12 -0800657 return -EOPNOTSUPP;
658 }
659
660 /* If it is our turn to send Pairing Confirm, do so now */
661 if (test_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags))
662 queue_work(hcon->hdev->workqueue, &smp->confirm);
663
664 return 0;
665}
666
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300667static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300668{
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300669 struct smp_cmd_pairing rsp, *req = (void *) skb->data;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300670 struct smp_chan *smp;
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300671 u8 key_size;
Brian Gix2b64d152011-12-21 16:12:12 -0800672 u8 auth = SMP_AUTH_NONE;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300673 int ret;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300674
675 BT_DBG("conn %p", conn);
676
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200677 if (skb->len < sizeof(*req))
678 return SMP_UNSPECIFIED;
679
Brian Gix2b64d152011-12-21 16:12:12 -0800680 if (conn->hcon->link_mode & HCI_LM_MASTER)
681 return SMP_CMD_NOTSUPP;
682
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200683 if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags))
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300684 smp = smp_chan_create(conn);
Andrei Emeltchenkod08fd0e2012-07-19 17:03:43 +0300685 else
686 smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300687
Andrei Emeltchenkod08fd0e2012-07-19 17:03:43 +0300688 if (!smp)
689 return SMP_UNSPECIFIED;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300690
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300691 smp->preq[0] = SMP_CMD_PAIRING_REQ;
692 memcpy(&smp->preq[1], req, sizeof(*req));
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300693 skb_pull(skb, sizeof(*req));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300694
Brian Gix2b64d152011-12-21 16:12:12 -0800695 /* We didn't start the pairing, so match remote */
696 if (req->auth_req & SMP_AUTH_BONDING)
697 auth = req->auth_req;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300698
Ido Yarivfdde0a22012-03-05 20:09:38 +0200699 conn->hcon->pending_sec_level = authreq_to_seclevel(auth);
700
Brian Gix2b64d152011-12-21 16:12:12 -0800701 build_pairing_cmd(conn, req, &rsp, auth);
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300702
703 key_size = min(req->max_key_size, rsp.max_key_size);
704 if (check_enc_key_size(conn, key_size))
705 return SMP_ENC_KEY_SIZE;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300706
Johan Hedberge84a6b12013-12-02 10:49:03 +0200707 get_random_bytes(smp->prnd, sizeof(smp->prnd));
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300708
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300709 smp->prsp[0] = SMP_CMD_PAIRING_RSP;
710 memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300711
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300712 smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300713
Brian Gix2b64d152011-12-21 16:12:12 -0800714 /* Request setup of TK */
715 ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability);
716 if (ret)
717 return SMP_UNSPECIFIED;
718
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300719 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300720}
721
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300722static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300723{
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300724 struct smp_cmd_pairing *req, *rsp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300725 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300726 struct hci_dev *hdev = conn->hcon->hdev;
Brian Gix2b64d152011-12-21 16:12:12 -0800727 u8 key_size, auth = SMP_AUTH_NONE;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300728 int ret;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300729
730 BT_DBG("conn %p", conn);
731
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200732 if (skb->len < sizeof(*rsp))
733 return SMP_UNSPECIFIED;
734
Brian Gix2b64d152011-12-21 16:12:12 -0800735 if (!(conn->hcon->link_mode & HCI_LM_MASTER))
736 return SMP_CMD_NOTSUPP;
737
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300738 skb_pull(skb, sizeof(*rsp));
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300739
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300740 req = (void *) &smp->preq[1];
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300741
742 key_size = min(req->max_key_size, rsp->max_key_size);
743 if (check_enc_key_size(conn, key_size))
744 return SMP_ENC_KEY_SIZE;
745
Johan Hedberge84a6b12013-12-02 10:49:03 +0200746 get_random_bytes(smp->prnd, sizeof(smp->prnd));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300747
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300748 smp->prsp[0] = SMP_CMD_PAIRING_RSP;
749 memcpy(&smp->prsp[1], rsp, sizeof(*rsp));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300750
Johan Hedbergfdcc4be2014-03-14 10:53:50 +0200751 /* Update remote key distribution in case the remote cleared
752 * some bits that we had enabled in our request.
753 */
754 smp->remote_key_dist &= rsp->resp_key_dist;
755
Brian Gix2b64d152011-12-21 16:12:12 -0800756 if ((req->auth_req & SMP_AUTH_BONDING) &&
Marcel Holtmannf1560462013-10-13 05:43:25 -0700757 (rsp->auth_req & SMP_AUTH_BONDING))
Brian Gix2b64d152011-12-21 16:12:12 -0800758 auth = SMP_AUTH_BONDING;
759
760 auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM;
761
Johan Hedberg476585e2012-06-06 18:54:15 +0800762 ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability);
Brian Gix2b64d152011-12-21 16:12:12 -0800763 if (ret)
764 return SMP_UNSPECIFIED;
765
766 set_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags);
767
768 /* Can't compose response until we have been confirmed */
769 if (!test_bit(SMP_FLAG_TK_VALID, &smp->smp_flags))
770 return 0;
771
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300772 queue_work(hdev->workqueue, &smp->confirm);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300773
774 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300775}
776
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300777static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300778{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300779 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300780 struct hci_dev *hdev = conn->hcon->hdev;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300781
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300782 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
783
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200784 if (skb->len < sizeof(smp->pcnf))
785 return SMP_UNSPECIFIED;
786
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300787 memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf));
788 skb_pull(skb, sizeof(smp->pcnf));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300789
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300790 if (conn->hcon->out) {
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300791 u8 random[16];
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300792
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300793 swap128(smp->prnd, random);
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300794 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(random),
Marcel Holtmannf1560462013-10-13 05:43:25 -0700795 random);
Brian Gix2b64d152011-12-21 16:12:12 -0800796 } else if (test_bit(SMP_FLAG_TK_VALID, &smp->smp_flags)) {
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300797 queue_work(hdev->workqueue, &smp->confirm);
Brian Gix2b64d152011-12-21 16:12:12 -0800798 } else {
799 set_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags);
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300800 }
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300801
802 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300803}
804
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300805static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300806{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300807 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300808 struct hci_dev *hdev = conn->hcon->hdev;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300809
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300810 BT_DBG("conn %p", conn);
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300811
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200812 if (skb->len < sizeof(smp->rrnd))
813 return SMP_UNSPECIFIED;
814
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300815 swap128(skb->data, smp->rrnd);
816 skb_pull(skb, sizeof(smp->rrnd));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300817
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300818 queue_work(hdev->workqueue, &smp->random);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300819
820 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300821}
822
Johan Hedberg4dab7862012-06-07 14:58:37 +0800823static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300824{
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300825 struct smp_ltk *key;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300826 struct hci_conn *hcon = conn->hcon;
827
Johan Hedberg98a0b842014-01-30 19:40:00 -0800828 key = hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type,
829 hcon->out);
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300830 if (!key)
831 return 0;
832
Johan Hedberg4dab7862012-06-07 14:58:37 +0800833 if (sec_level > BT_SECURITY_MEDIUM && !key->authenticated)
834 return 0;
835
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200836 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300837 return 1;
838
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300839 hci_le_start_enc(hcon, key->ediv, key->rand, key->val);
840 hcon->enc_key_size = key->enc_size;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300841
842 return 1;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300843}
Marcel Holtmannf1560462013-10-13 05:43:25 -0700844
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300845static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300846{
847 struct smp_cmd_security_req *rp = (void *) skb->data;
848 struct smp_cmd_pairing cp;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300849 struct hci_conn *hcon = conn->hcon;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300850 struct smp_chan *smp;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300851
852 BT_DBG("conn %p", conn);
853
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200854 if (skb->len < sizeof(*rp))
855 return SMP_UNSPECIFIED;
856
Johan Hedberg86ca9ea2013-11-05 11:30:39 +0200857 if (!(conn->hcon->link_mode & HCI_LM_MASTER))
858 return SMP_CMD_NOTSUPP;
859
Brian Gix2b64d152011-12-21 16:12:12 -0800860 hcon->pending_sec_level = authreq_to_seclevel(rp->auth_req);
Vinicius Costa Gomesfeb45eb2011-08-25 20:02:35 -0300861
Johan Hedberg4dab7862012-06-07 14:58:37 +0800862 if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300863 return 0;
864
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200865 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300866 return 0;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300867
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300868 smp = smp_chan_create(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300869
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300870 skb_pull(skb, sizeof(*rp));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300871
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300872 memset(&cp, 0, sizeof(cp));
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300873 build_pairing_cmd(conn, &cp, NULL, rp->auth_req);
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300874
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300875 smp->preq[0] = SMP_CMD_PAIRING_REQ;
876 memcpy(&smp->preq[1], &cp, sizeof(cp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300877
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300878 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300879
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300880 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300881}
882
Johan Hedbergad32a2f2013-05-14 18:05:12 +0300883bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level)
884{
885 if (sec_level == BT_SECURITY_LOW)
886 return true;
887
888 if (hcon->sec_level >= sec_level)
889 return true;
890
891 return false;
892}
893
Vinicius Costa Gomescc110922012-08-23 21:32:43 -0300894int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300895{
Vinicius Costa Gomescc110922012-08-23 21:32:43 -0300896 struct l2cap_conn *conn = hcon->l2cap_data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300897 struct smp_chan *smp = conn->smp_chan;
Brian Gix2b64d152011-12-21 16:12:12 -0800898 __u8 authreq;
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300899
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -0300900 BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
901
Johan Hedberg757aee02013-04-24 13:05:32 +0300902 if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags))
Andre Guedes2e65c9d2011-06-30 19:20:56 -0300903 return 1;
904
Johan Hedbergad32a2f2013-05-14 18:05:12 +0300905 if (smp_sufficient_security(hcon, sec_level))
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300906 return 1;
907
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300908 if (hcon->link_mode & HCI_LM_MASTER)
Johan Hedberg4dab7862012-06-07 14:58:37 +0800909 if (smp_ltk_encrypt(conn, sec_level))
Vinicius Costa Gomes02bc7452011-07-07 18:59:41 -0300910 goto done;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300911
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200912 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300913 return 0;
914
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300915 smp = smp_chan_create(conn);
Brian Gix2b64d152011-12-21 16:12:12 -0800916 if (!smp)
917 return 1;
918
919 authreq = seclevel_to_authreq(sec_level);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300920
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300921 if (hcon->link_mode & HCI_LM_MASTER) {
922 struct smp_cmd_pairing cp;
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300923
Brian Gix2b64d152011-12-21 16:12:12 -0800924 build_pairing_cmd(conn, &cp, NULL, authreq);
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300925 smp->preq[0] = SMP_CMD_PAIRING_REQ;
926 memcpy(&smp->preq[1], &cp, sizeof(cp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300927
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300928 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
929 } else {
930 struct smp_cmd_security_req cp;
Brian Gix2b64d152011-12-21 16:12:12 -0800931 cp.auth_req = authreq;
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300932 smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
933 }
934
Vinicius Costa Gomes02bc7452011-07-07 18:59:41 -0300935done:
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300936 hcon->pending_sec_level = sec_level;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300937
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300938 return 0;
939}
940
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300941static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
942{
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300943 struct smp_cmd_encrypt_info *rp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300944 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300945
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200946 BT_DBG("conn %p", conn);
947
948 if (skb->len < sizeof(*rp))
949 return SMP_UNSPECIFIED;
950
Johan Hedberg6131ddc2014-02-18 10:19:37 +0200951 /* Ignore this PDU if it wasn't requested */
952 if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
953 return 0;
954
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300955 skb_pull(skb, sizeof(*rp));
956
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300957 memcpy(smp->tk, rp->ltk, sizeof(smp->tk));
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300958
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300959 return 0;
960}
961
962static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
963{
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300964 struct smp_cmd_master_ident *rp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300965 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300966 struct hci_dev *hdev = conn->hcon->hdev;
967 struct hci_conn *hcon = conn->hcon;
Johan Hedberg23d0e122014-02-19 14:57:46 +0200968 struct smp_ltk *ltk;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300969 u8 authenticated;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300970
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200971 BT_DBG("conn %p", conn);
972
973 if (skb->len < sizeof(*rp))
974 return SMP_UNSPECIFIED;
975
Johan Hedberg6131ddc2014-02-18 10:19:37 +0200976 /* Ignore this PDU if it wasn't requested */
977 if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
978 return 0;
979
Johan Hedberg9747a9f2014-02-26 23:33:43 +0200980 /* Mark the information as received */
981 smp->remote_key_dist &= ~SMP_DIST_ENC_KEY;
982
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300983 skb_pull(skb, sizeof(*rp));
984
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300985 hci_dev_lock(hdev);
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700986 authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
Johan Hedberg35d70272014-02-19 14:57:47 +0200987 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, HCI_SMP_LTK,
Johan Hedberg23d0e122014-02-19 14:57:46 +0200988 authenticated, smp->tk, smp->enc_key_size,
989 rp->ediv, rp->rand);
990 smp->ltk = ltk;
Johan Hedbergfd349c02014-02-18 10:19:36 +0200991 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
Johan Hedberg4bd6d382014-02-26 23:33:45 +0200992 smp_distribute_keys(conn);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300993 hci_dev_unlock(hdev);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300994
995 return 0;
996}
997
Johan Hedbergfd349c02014-02-18 10:19:36 +0200998static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
999{
1000 struct smp_cmd_ident_info *info = (void *) skb->data;
1001 struct smp_chan *smp = conn->smp_chan;
1002
1003 BT_DBG("");
1004
1005 if (skb->len < sizeof(*info))
1006 return SMP_UNSPECIFIED;
1007
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001008 /* Ignore this PDU if it wasn't requested */
1009 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
1010 return 0;
1011
Johan Hedbergfd349c02014-02-18 10:19:36 +02001012 skb_pull(skb, sizeof(*info));
1013
1014 memcpy(smp->irk, info->irk, 16);
1015
1016 return 0;
1017}
1018
1019static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
1020 struct sk_buff *skb)
1021{
1022 struct smp_cmd_ident_addr_info *info = (void *) skb->data;
1023 struct smp_chan *smp = conn->smp_chan;
1024 struct hci_conn *hcon = conn->hcon;
1025 bdaddr_t rpa;
1026
1027 BT_DBG("");
1028
1029 if (skb->len < sizeof(*info))
1030 return SMP_UNSPECIFIED;
1031
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001032 /* Ignore this PDU if it wasn't requested */
1033 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
1034 return 0;
1035
Johan Hedberg9747a9f2014-02-26 23:33:43 +02001036 /* Mark the information as received */
1037 smp->remote_key_dist &= ~SMP_DIST_ID_KEY;
1038
Johan Hedbergfd349c02014-02-18 10:19:36 +02001039 skb_pull(skb, sizeof(*info));
1040
Johan Hedberga9a58f82014-02-25 22:24:37 +02001041 /* Strictly speaking the Core Specification (4.1) allows sending
1042 * an empty address which would force us to rely on just the IRK
1043 * as "identity information". However, since such
1044 * implementations are not known of and in order to not over
1045 * complicate our implementation, simply pretend that we never
1046 * received an IRK for such a device.
1047 */
1048 if (!bacmp(&info->bdaddr, BDADDR_ANY)) {
1049 BT_ERR("Ignoring IRK with no identity address");
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001050 smp_distribute_keys(conn);
Johan Hedberga9a58f82014-02-25 22:24:37 +02001051 return 0;
1052 }
1053
Johan Hedbergfd349c02014-02-18 10:19:36 +02001054 bacpy(&smp->id_addr, &info->bdaddr);
1055 smp->id_addr_type = info->addr_type;
1056
1057 if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type))
1058 bacpy(&rpa, &hcon->dst);
1059 else
1060 bacpy(&rpa, BDADDR_ANY);
1061
Johan Hedberg23d0e122014-02-19 14:57:46 +02001062 smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
1063 smp->id_addr_type, smp->irk, &rpa);
Johan Hedbergfd349c02014-02-18 10:19:36 +02001064
Johan Hedberg68d6f6d2014-02-18 21:41:32 +02001065 /* Track the connection based on the Identity Address from now on */
1066 bacpy(&hcon->dst, &smp->id_addr);
1067 hcon->dst_type = smp->id_addr_type;
1068
Johan Hedberg387a33e2014-02-18 21:41:33 +02001069 l2cap_conn_update_id_addr(hcon);
1070
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001071 smp_distribute_keys(conn);
Johan Hedbergfd349c02014-02-18 10:19:36 +02001072
1073 return 0;
1074}
1075
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001076static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)
1077{
1078 struct smp_cmd_sign_info *rp = (void *) skb->data;
1079 struct smp_chan *smp = conn->smp_chan;
1080 struct hci_dev *hdev = conn->hcon->hdev;
1081 struct smp_csrk *csrk;
1082
1083 BT_DBG("conn %p", conn);
1084
1085 if (skb->len < sizeof(*rp))
1086 return SMP_UNSPECIFIED;
1087
1088 /* Ignore this PDU if it wasn't requested */
1089 if (!(smp->remote_key_dist & SMP_DIST_SIGN))
1090 return 0;
1091
1092 /* Mark the information as received */
1093 smp->remote_key_dist &= ~SMP_DIST_SIGN;
1094
1095 skb_pull(skb, sizeof(*rp));
1096
1097 hci_dev_lock(hdev);
1098 csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
1099 if (csrk) {
1100 csrk->master = 0x01;
1101 memcpy(csrk->val, rp->csrk, sizeof(csrk->val));
1102 }
1103 smp->csrk = csrk;
1104 if (!(smp->remote_key_dist & SMP_DIST_SIGN))
1105 smp_distribute_keys(conn);
1106 hci_dev_unlock(hdev);
1107
1108 return 0;
1109}
1110
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001111int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
1112{
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001113 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann92381f52013-10-03 01:23:08 -07001114 __u8 code, reason;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001115 int err = 0;
1116
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001117 if (hcon->type != LE_LINK) {
1118 kfree_skb(skb);
Johan Hedberg34327112013-10-16 11:37:01 +03001119 return 0;
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001120 }
1121
Marcel Holtmann92381f52013-10-03 01:23:08 -07001122 if (skb->len < 1) {
1123 kfree_skb(skb);
1124 return -EILSEQ;
1125 }
1126
Marcel Holtmann06ae3312013-10-18 03:43:00 -07001127 if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) {
Andre Guedes2e65c9d2011-06-30 19:20:56 -03001128 err = -ENOTSUPP;
1129 reason = SMP_PAIRING_NOTSUPP;
1130 goto done;
1131 }
1132
Marcel Holtmann92381f52013-10-03 01:23:08 -07001133 code = skb->data[0];
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001134 skb_pull(skb, sizeof(code));
1135
Johan Hedberg8cf9fa12013-01-29 10:44:23 -06001136 /*
1137 * The SMP context must be initialized for all other PDUs except
1138 * pairing and security requests. If we get any other PDU when
1139 * not initialized simply disconnect (done if this function
1140 * returns an error).
1141 */
1142 if (code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ &&
1143 !conn->smp_chan) {
1144 BT_ERR("Unexpected SMP command 0x%02x. Disconnecting.", code);
1145 kfree_skb(skb);
1146 return -ENOTSUPP;
1147 }
1148
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001149 switch (code) {
1150 case SMP_CMD_PAIRING_REQ:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001151 reason = smp_cmd_pairing_req(conn, skb);
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001152 break;
1153
1154 case SMP_CMD_PAIRING_FAIL:
Johan Hedberg84794e12013-11-06 11:24:57 +02001155 smp_failure(conn, 0);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001156 reason = 0;
1157 err = -EPERM;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001158 break;
1159
1160 case SMP_CMD_PAIRING_RSP:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001161 reason = smp_cmd_pairing_rsp(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001162 break;
1163
1164 case SMP_CMD_SECURITY_REQ:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001165 reason = smp_cmd_security_req(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001166 break;
1167
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001168 case SMP_CMD_PAIRING_CONFIRM:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001169 reason = smp_cmd_pairing_confirm(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001170 break;
1171
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001172 case SMP_CMD_PAIRING_RANDOM:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001173 reason = smp_cmd_pairing_random(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001174 break;
1175
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001176 case SMP_CMD_ENCRYPT_INFO:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001177 reason = smp_cmd_encrypt_info(conn, skb);
1178 break;
1179
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001180 case SMP_CMD_MASTER_IDENT:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001181 reason = smp_cmd_master_ident(conn, skb);
1182 break;
1183
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001184 case SMP_CMD_IDENT_INFO:
Johan Hedbergfd349c02014-02-18 10:19:36 +02001185 reason = smp_cmd_ident_info(conn, skb);
1186 break;
1187
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001188 case SMP_CMD_IDENT_ADDR_INFO:
Johan Hedbergfd349c02014-02-18 10:19:36 +02001189 reason = smp_cmd_ident_addr_info(conn, skb);
1190 break;
1191
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001192 case SMP_CMD_SIGN_INFO:
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001193 reason = smp_cmd_sign_info(conn, skb);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001194 break;
1195
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001196 default:
1197 BT_DBG("Unknown command code 0x%2.2x", code);
1198
1199 reason = SMP_CMD_NOTSUPP;
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -03001200 err = -EOPNOTSUPP;
1201 goto done;
1202 }
1203
1204done:
1205 if (reason)
Johan Hedberg84794e12013-11-06 11:24:57 +02001206 smp_failure(conn, reason);
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001207
1208 kfree_skb(skb);
1209 return err;
1210}
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001211
Johan Hedberg35d70272014-02-19 14:57:47 +02001212static void smp_notify_keys(struct l2cap_conn *conn)
1213{
1214 struct smp_chan *smp = conn->smp_chan;
1215 struct hci_conn *hcon = conn->hcon;
1216 struct hci_dev *hdev = hcon->hdev;
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001217 struct smp_cmd_pairing *req = (void *) &smp->preq[1];
1218 struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1];
1219 bool persistent;
Johan Hedberg35d70272014-02-19 14:57:47 +02001220
Johan Hedberg95fbac82014-02-19 15:18:31 +02001221 if (smp->remote_irk)
1222 mgmt_new_irk(hdev, smp->remote_irk);
1223
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001224 /* The LTKs and CSRKs should be persistent only if both sides
1225 * had the bonding bit set in their authentication requests.
1226 */
1227 persistent = !!((req->auth_req & rsp->auth_req) & SMP_AUTH_BONDING);
1228
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001229 if (smp->csrk) {
1230 smp->csrk->bdaddr_type = hcon->dst_type;
1231 bacpy(&smp->csrk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001232 mgmt_new_csrk(hdev, smp->csrk, persistent);
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001233 }
1234
1235 if (smp->slave_csrk) {
1236 smp->slave_csrk->bdaddr_type = hcon->dst_type;
1237 bacpy(&smp->slave_csrk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001238 mgmt_new_csrk(hdev, smp->slave_csrk, persistent);
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001239 }
1240
Johan Hedberg35d70272014-02-19 14:57:47 +02001241 if (smp->ltk) {
1242 smp->ltk->bdaddr_type = hcon->dst_type;
1243 bacpy(&smp->ltk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001244 mgmt_new_ltk(hdev, smp->ltk, persistent);
Johan Hedberg35d70272014-02-19 14:57:47 +02001245 }
1246
1247 if (smp->slave_ltk) {
1248 smp->slave_ltk->bdaddr_type = hcon->dst_type;
1249 bacpy(&smp->slave_ltk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001250 mgmt_new_ltk(hdev, smp->slave_ltk, persistent);
Johan Hedberg35d70272014-02-19 14:57:47 +02001251 }
1252}
1253
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001254int smp_distribute_keys(struct l2cap_conn *conn)
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001255{
1256 struct smp_cmd_pairing *req, *rsp;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001257 struct smp_chan *smp = conn->smp_chan;
Johan Hedberg524237c2014-02-22 19:06:31 +02001258 struct hci_conn *hcon = conn->hcon;
1259 struct hci_dev *hdev = hcon->hdev;
Johan Hedberg38ccdc92014-02-28 18:10:02 +02001260 bool ltk_encrypt;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001261 __u8 *keydist;
1262
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001263 BT_DBG("conn %p", conn);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001264
Johan Hedberg524237c2014-02-22 19:06:31 +02001265 if (!test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001266 return 0;
1267
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001268 rsp = (void *) &smp->prsp[1];
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001269
1270 /* The responder sends its keys first */
Johan Hedbergefabba32014-02-26 23:33:44 +02001271 if (hcon->out && (smp->remote_key_dist & 0x07))
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001272 return 0;
1273
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001274 req = (void *) &smp->preq[1];
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001275
Johan Hedberg524237c2014-02-22 19:06:31 +02001276 if (hcon->out) {
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001277 keydist = &rsp->init_key_dist;
1278 *keydist &= req->init_key_dist;
1279 } else {
1280 keydist = &rsp->resp_key_dist;
1281 *keydist &= req->resp_key_dist;
1282 }
1283
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001284 BT_DBG("keydist 0x%x", *keydist);
1285
1286 if (*keydist & SMP_DIST_ENC_KEY) {
1287 struct smp_cmd_encrypt_info enc;
1288 struct smp_cmd_master_ident ident;
Johan Hedberg23d0e122014-02-19 14:57:46 +02001289 struct smp_ltk *ltk;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001290 u8 authenticated;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001291 __le16 ediv;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001292 __le64 rand;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001293
1294 get_random_bytes(enc.ltk, sizeof(enc.ltk));
1295 get_random_bytes(&ediv, sizeof(ediv));
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001296 get_random_bytes(&rand, sizeof(rand));
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001297
1298 smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
1299
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001300 authenticated = hcon->sec_level == BT_SECURITY_HIGH;
Johan Hedberg524237c2014-02-22 19:06:31 +02001301 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type,
Johan Hedberg35d70272014-02-19 14:57:47 +02001302 HCI_SMP_LTK_SLAVE, authenticated, enc.ltk,
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001303 smp->enc_key_size, ediv, rand);
Johan Hedberg23d0e122014-02-19 14:57:46 +02001304 smp->slave_ltk = ltk;
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001305
Andrei Emeltchenko58115372012-03-12 12:13:06 +02001306 ident.ediv = ediv;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001307 ident.rand = rand;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001308
1309 smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident);
1310
1311 *keydist &= ~SMP_DIST_ENC_KEY;
1312 }
1313
1314 if (*keydist & SMP_DIST_ID_KEY) {
1315 struct smp_cmd_ident_addr_info addrinfo;
1316 struct smp_cmd_ident_info idinfo;
1317
Johan Hedberg863efaf2014-02-22 19:06:32 +02001318 memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk));
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001319
1320 smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo);
1321
Johan Hedberg82d4b352014-02-23 19:42:18 +02001322 /* The hci_conn contains the local identity address
1323 * after the connection has been established.
1324 *
1325 * This is true even when the connection has been
1326 * established using a resolvable random address.
1327 */
Johan Hedberg524237c2014-02-22 19:06:31 +02001328 bacpy(&addrinfo.bdaddr, &hcon->src);
Johan Hedberg82d4b352014-02-23 19:42:18 +02001329 addrinfo.addr_type = hcon->src_type;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001330
1331 smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo),
Marcel Holtmannf1560462013-10-13 05:43:25 -07001332 &addrinfo);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001333
1334 *keydist &= ~SMP_DIST_ID_KEY;
1335 }
1336
1337 if (*keydist & SMP_DIST_SIGN) {
1338 struct smp_cmd_sign_info sign;
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001339 struct smp_csrk *csrk;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001340
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001341 /* Generate a new random key */
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001342 get_random_bytes(sign.csrk, sizeof(sign.csrk));
1343
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001344 csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
1345 if (csrk) {
1346 csrk->master = 0x00;
1347 memcpy(csrk->val, sign.csrk, sizeof(csrk->val));
1348 }
1349 smp->slave_csrk = csrk;
1350
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001351 smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign);
1352
1353 *keydist &= ~SMP_DIST_SIGN;
1354 }
1355
Johan Hedbergefabba32014-02-26 23:33:44 +02001356 /* If there are still keys to be received wait for them */
1357 if ((smp->remote_key_dist & 0x07))
1358 return 0;
1359
Johan Hedberg38ccdc92014-02-28 18:10:02 +02001360 /* Check if we should try to re-encrypt the link with the LTK.
1361 * SMP_FLAG_LTK_ENCRYPT flag is used to track whether we've
1362 * already tried this (in which case we shouldn't try again).
1363 *
1364 * The request will trigger an encryption key refresh event
1365 * which will cause a call to auth_cfm and eventually lead to
1366 * l2cap_core.c calling this smp_distribute_keys function again
1367 * and thereby completing the process.
1368 */
1369 if (smp->ltk)
1370 ltk_encrypt = !test_and_set_bit(SMP_FLAG_LTK_ENCRYPT,
1371 &smp->smp_flags);
1372 else
1373 ltk_encrypt = false;
Johan Hedbergefabba32014-02-26 23:33:44 +02001374
Johan Hedberg38ccdc92014-02-28 18:10:02 +02001375 /* Re-encrypt the link with LTK if possible */
1376 if (ltk_encrypt && hcon->out) {
Johan Hedberge3098be2014-02-28 18:10:03 +02001377 queue_delayed_work(hdev->req_workqueue, &smp->reencrypt,
1378 SMP_REENCRYPT_TIMEOUT);
Johan Hedberg38ccdc92014-02-28 18:10:02 +02001379 } else {
1380 clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags);
1381 cancel_delayed_work_sync(&conn->security_timer);
1382 set_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
1383 smp_notify_keys(conn);
1384 smp_chan_destroy(conn);
1385 }
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001386
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001387 return 0;
1388}