blob: df91ed28084f1f04f4d68b24566748911e856fda [file] [log] [blame]
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001/*
2 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License version 2 as
7 published by the Free Software Foundation;
8
9 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
10 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
12 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
13 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
18 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
19 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
20 SOFTWARE IS DISCLAIMED.
21*/
22
Gustavo Padovan8c520a52012-05-23 04:04:22 -030023#include <linux/crypto.h>
24#include <linux/scatterlist.h>
25#include <crypto/b128ops.h>
26
Anderson Brigliaeb492e02011-06-09 18:50:40 -030027#include <net/bluetooth/bluetooth.h>
28#include <net/bluetooth/hci_core.h>
29#include <net/bluetooth/l2cap.h>
Brian Gix2b64d152011-12-21 16:12:12 -080030#include <net/bluetooth/mgmt.h>
Marcel Holtmannac4b7232013-10-10 14:54:16 -070031
32#include "smp.h"
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030033
Marcel Holtmann17b02e62012-03-01 14:32:37 -080034#define SMP_TIMEOUT msecs_to_jiffies(30000)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -030035
Johan Hedberg065a13e2012-10-11 16:26:06 +020036#define AUTH_REQ_MASK 0x07
37
Johan Hedberg4bc58f52014-05-20 09:45:47 +030038#define SMP_FLAG_TK_VALID 1
39#define SMP_FLAG_CFM_PENDING 2
40#define SMP_FLAG_MITM_AUTH 3
41#define SMP_FLAG_COMPLETE 4
42#define SMP_FLAG_INITIATOR 5
43
44struct smp_chan {
45 struct l2cap_conn *conn;
46 u8 preq[7]; /* SMP Pairing Request */
47 u8 prsp[7]; /* SMP Pairing Response */
48 u8 prnd[16]; /* SMP Pairing Random (local) */
49 u8 rrnd[16]; /* SMP Pairing Random (remote) */
50 u8 pcnf[16]; /* SMP Pairing Confirm */
51 u8 tk[16]; /* SMP Temporary Key */
52 u8 enc_key_size;
53 u8 remote_key_dist;
54 bdaddr_t id_addr;
55 u8 id_addr_type;
56 u8 irk[16];
57 struct smp_csrk *csrk;
58 struct smp_csrk *slave_csrk;
59 struct smp_ltk *ltk;
60 struct smp_ltk *slave_ltk;
61 struct smp_irk *remote_irk;
62 unsigned long smp_flags;
63 struct work_struct confirm;
64 struct work_struct random;
65};
66
Johan Hedberg66bed1a2014-03-18 12:58:23 +020067static inline void swap128(const u8 src[16], u8 dst[16])
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030068{
69 int i;
70 for (i = 0; i < 16; i++)
71 dst[15 - i] = src[i];
72}
73
Johan Hedberg66bed1a2014-03-18 12:58:23 +020074static inline void swap56(const u8 src[7], u8 dst[7])
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030075{
76 int i;
77 for (i = 0; i < 7; i++)
78 dst[6 - i] = src[i];
79}
80
81static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
82{
83 struct blkcipher_desc desc;
84 struct scatterlist sg;
Johan Hedberg943a7322014-03-18 12:58:24 +020085 uint8_t tmp[16], data[16];
Johan Hedberg201a5922013-12-02 10:49:04 +020086 int err;
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030087
88 if (tfm == NULL) {
89 BT_ERR("tfm %p", tfm);
90 return -EINVAL;
91 }
92
93 desc.tfm = tfm;
94 desc.flags = 0;
95
Johan Hedberg943a7322014-03-18 12:58:24 +020096 /* The most significant octet of key corresponds to k[0] */
97 swap128(k, tmp);
98
99 err = crypto_blkcipher_setkey(tfm, tmp, 16);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300100 if (err) {
101 BT_ERR("cipher setkey failed: %d", err);
102 return err;
103 }
104
Johan Hedberg943a7322014-03-18 12:58:24 +0200105 /* Most significant octet of plaintextData corresponds to data[0] */
106 swap128(r, data);
107
108 sg_init_one(&sg, data, 16);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300109
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300110 err = crypto_blkcipher_encrypt(&desc, &sg, &sg, 16);
111 if (err)
112 BT_ERR("Encrypt data error %d", err);
113
Johan Hedberg943a7322014-03-18 12:58:24 +0200114 /* Most significant octet of encryptedData corresponds to data[0] */
115 swap128(data, r);
116
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300117 return err;
118}
119
Johan Hedberg60478052014-02-18 10:19:31 +0200120static int smp_ah(struct crypto_blkcipher *tfm, u8 irk[16], u8 r[3], u8 res[3])
121{
Johan Hedberg943a7322014-03-18 12:58:24 +0200122 u8 _res[16];
Johan Hedberg60478052014-02-18 10:19:31 +0200123 int err;
124
125 /* r' = padding || r */
Johan Hedberg943a7322014-03-18 12:58:24 +0200126 memcpy(_res, r, 3);
127 memset(_res + 3, 0, 13);
Johan Hedberg60478052014-02-18 10:19:31 +0200128
Johan Hedberg943a7322014-03-18 12:58:24 +0200129 err = smp_e(tfm, irk, _res);
Johan Hedberg60478052014-02-18 10:19:31 +0200130 if (err) {
131 BT_ERR("Encrypt error");
132 return err;
133 }
134
135 /* The output of the random address function ah is:
136 * ah(h, r) = e(k, r') mod 2^24
137 * The output of the security function e is then truncated to 24 bits
138 * by taking the least significant 24 bits of the output of e as the
139 * result of ah.
140 */
Johan Hedberg943a7322014-03-18 12:58:24 +0200141 memcpy(res, _res, 3);
Johan Hedberg60478052014-02-18 10:19:31 +0200142
143 return 0;
144}
145
146bool smp_irk_matches(struct crypto_blkcipher *tfm, u8 irk[16],
147 bdaddr_t *bdaddr)
148{
149 u8 hash[3];
150 int err;
151
152 BT_DBG("RPA %pMR IRK %*phN", bdaddr, 16, irk);
153
154 err = smp_ah(tfm, irk, &bdaddr->b[3], hash);
155 if (err)
156 return false;
157
158 return !memcmp(bdaddr->b, hash, 3);
159}
160
Johan Hedbergb1e2b3a2014-02-23 19:42:19 +0200161int smp_generate_rpa(struct crypto_blkcipher *tfm, u8 irk[16], bdaddr_t *rpa)
162{
163 int err;
164
165 get_random_bytes(&rpa->b[3], 3);
166
167 rpa->b[5] &= 0x3f; /* Clear two most significant bits */
168 rpa->b[5] |= 0x40; /* Set second most significant bit */
169
170 err = smp_ah(tfm, irk, &rpa->b[3], rpa->b);
171 if (err < 0)
172 return err;
173
174 BT_DBG("RPA %pMR", rpa);
175
176 return 0;
177}
178
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300179static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16],
Marcel Holtmannf1560462013-10-13 05:43:25 -0700180 u8 preq[7], u8 pres[7], u8 _iat, bdaddr_t *ia,
181 u8 _rat, bdaddr_t *ra, u8 res[16])
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300182{
183 u8 p1[16], p2[16];
184 int err;
185
186 memset(p1, 0, 16);
187
188 /* p1 = pres || preq || _rat || _iat */
Johan Hedberg943a7322014-03-18 12:58:24 +0200189 p1[0] = _iat;
190 p1[1] = _rat;
191 memcpy(p1 + 2, preq, 7);
192 memcpy(p1 + 9, pres, 7);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300193
194 /* p2 = padding || ia || ra */
Johan Hedberg943a7322014-03-18 12:58:24 +0200195 memcpy(p2, ra, 6);
196 memcpy(p2 + 6, ia, 6);
197 memset(p2 + 12, 0, 4);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300198
199 /* res = r XOR p1 */
200 u128_xor((u128 *) res, (u128 *) r, (u128 *) p1);
201
202 /* res = e(k, res) */
203 err = smp_e(tfm, k, res);
204 if (err) {
205 BT_ERR("Encrypt data error");
206 return err;
207 }
208
209 /* res = res XOR p2 */
210 u128_xor((u128 *) res, (u128 *) res, (u128 *) p2);
211
212 /* res = e(k, res) */
213 err = smp_e(tfm, k, res);
214 if (err)
215 BT_ERR("Encrypt data error");
216
217 return err;
218}
219
Marcel Holtmannf1560462013-10-13 05:43:25 -0700220static int smp_s1(struct crypto_blkcipher *tfm, u8 k[16], u8 r1[16],
221 u8 r2[16], u8 _r[16])
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300222{
223 int err;
224
225 /* Just least significant octets from r1 and r2 are considered */
Johan Hedberg943a7322014-03-18 12:58:24 +0200226 memcpy(_r, r2, 8);
227 memcpy(_r + 8, r1, 8);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300228
229 err = smp_e(tfm, k, _r);
230 if (err)
231 BT_ERR("Encrypt data error");
232
233 return err;
234}
235
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300236static struct sk_buff *smp_build_cmd(struct l2cap_conn *conn, u8 code,
Marcel Holtmannf1560462013-10-13 05:43:25 -0700237 u16 dlen, void *data)
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300238{
239 struct sk_buff *skb;
240 struct l2cap_hdr *lh;
241 int len;
242
243 len = L2CAP_HDR_SIZE + sizeof(code) + dlen;
244
245 if (len > conn->mtu)
246 return NULL;
247
248 skb = bt_skb_alloc(len, GFP_ATOMIC);
249 if (!skb)
250 return NULL;
251
252 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
253 lh->len = cpu_to_le16(sizeof(code) + dlen);
Joe Perchesdcf4adb2014-03-12 10:52:35 -0700254 lh->cid = cpu_to_le16(L2CAP_CID_SMP);
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300255
256 memcpy(skb_put(skb, sizeof(code)), &code, sizeof(code));
257
258 memcpy(skb_put(skb, dlen), data, dlen);
259
260 return skb;
261}
262
263static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
264{
265 struct sk_buff *skb = smp_build_cmd(conn, code, len, data);
266
267 BT_DBG("code 0x%2.2x", code);
268
269 if (!skb)
270 return;
271
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200272 skb->priority = HCI_PRIO_MAX;
273 hci_send_acl(conn->hchan, skb, 0);
Vinicius Costa Gomese2dcd112011-08-19 21:06:50 -0300274
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -0200275 cancel_delayed_work_sync(&conn->security_timer);
Marcel Holtmann17b02e62012-03-01 14:32:37 -0800276 schedule_delayed_work(&conn->security_timer, SMP_TIMEOUT);
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300277}
278
Brian Gix2b64d152011-12-21 16:12:12 -0800279static __u8 authreq_to_seclevel(__u8 authreq)
280{
281 if (authreq & SMP_AUTH_MITM)
282 return BT_SECURITY_HIGH;
283 else
284 return BT_SECURITY_MEDIUM;
285}
286
287static __u8 seclevel_to_authreq(__u8 sec_level)
288{
289 switch (sec_level) {
290 case BT_SECURITY_HIGH:
291 return SMP_AUTH_MITM | SMP_AUTH_BONDING;
292 case BT_SECURITY_MEDIUM:
293 return SMP_AUTH_BONDING;
294 default:
295 return SMP_AUTH_NONE;
296 }
297}
298
Vinicius Costa Gomesb8e66ea2011-06-09 18:50:52 -0300299static void build_pairing_cmd(struct l2cap_conn *conn,
Marcel Holtmannf1560462013-10-13 05:43:25 -0700300 struct smp_cmd_pairing *req,
301 struct smp_cmd_pairing *rsp, __u8 authreq)
Vinicius Costa Gomesb8e66ea2011-06-09 18:50:52 -0300302{
Johan Hedbergfd349c02014-02-18 10:19:36 +0200303 struct smp_chan *smp = conn->smp_chan;
304 struct hci_conn *hcon = conn->hcon;
305 struct hci_dev *hdev = hcon->hdev;
306 u8 local_dist = 0, remote_dist = 0;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300307
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200308 if (test_bit(HCI_PAIRABLE, &conn->hcon->hdev->dev_flags)) {
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -0700309 local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
310 remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300311 authreq |= SMP_AUTH_BONDING;
Brian Gix2b64d152011-12-21 16:12:12 -0800312 } else {
313 authreq &= ~SMP_AUTH_BONDING;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300314 }
315
Johan Hedbergfd349c02014-02-18 10:19:36 +0200316 if (test_bit(HCI_RPA_RESOLVING, &hdev->dev_flags))
317 remote_dist |= SMP_DIST_ID_KEY;
318
Johan Hedberg863efaf2014-02-22 19:06:32 +0200319 if (test_bit(HCI_PRIVACY, &hdev->dev_flags))
320 local_dist |= SMP_DIST_ID_KEY;
321
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300322 if (rsp == NULL) {
323 req->io_capability = conn->hcon->io_capability;
324 req->oob_flag = SMP_OOB_NOT_PRESENT;
325 req->max_key_size = SMP_MAX_ENC_KEY_SIZE;
Johan Hedbergfd349c02014-02-18 10:19:36 +0200326 req->init_key_dist = local_dist;
327 req->resp_key_dist = remote_dist;
Johan Hedberg065a13e2012-10-11 16:26:06 +0200328 req->auth_req = (authreq & AUTH_REQ_MASK);
Johan Hedbergfd349c02014-02-18 10:19:36 +0200329
330 smp->remote_key_dist = remote_dist;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300331 return;
332 }
333
334 rsp->io_capability = conn->hcon->io_capability;
335 rsp->oob_flag = SMP_OOB_NOT_PRESENT;
336 rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE;
Johan Hedbergfd349c02014-02-18 10:19:36 +0200337 rsp->init_key_dist = req->init_key_dist & remote_dist;
338 rsp->resp_key_dist = req->resp_key_dist & local_dist;
Johan Hedberg065a13e2012-10-11 16:26:06 +0200339 rsp->auth_req = (authreq & AUTH_REQ_MASK);
Johan Hedbergfd349c02014-02-18 10:19:36 +0200340
341 smp->remote_key_dist = rsp->init_key_dist;
Vinicius Costa Gomesb8e66ea2011-06-09 18:50:52 -0300342}
343
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300344static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
345{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300346 struct smp_chan *smp = conn->smp_chan;
347
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300348 if ((max_key_size > SMP_MAX_ENC_KEY_SIZE) ||
Marcel Holtmannf1560462013-10-13 05:43:25 -0700349 (max_key_size < SMP_MIN_ENC_KEY_SIZE))
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300350 return SMP_ENC_KEY_SIZE;
351
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300352 smp->enc_key_size = max_key_size;
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300353
354 return 0;
355}
356
Johan Hedberg84794e12013-11-06 11:24:57 +0200357static void smp_failure(struct l2cap_conn *conn, u8 reason)
Brian Gix4f957a72011-11-23 08:28:36 -0800358{
Johan Hedbergbab73cb2012-02-09 16:07:29 +0200359 struct hci_conn *hcon = conn->hcon;
360
Johan Hedberg84794e12013-11-06 11:24:57 +0200361 if (reason)
Brian Gix4f957a72011-11-23 08:28:36 -0800362 smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
Marcel Holtmannf1560462013-10-13 05:43:25 -0700363 &reason);
Brian Gix4f957a72011-11-23 08:28:36 -0800364
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700365 clear_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags);
366 mgmt_auth_failed(hcon->hdev, &hcon->dst, hcon->type, hcon->dst_type,
367 HCI_ERROR_AUTH_FAILURE);
Vinicius Costa Gomesf1c09c02012-02-01 18:27:56 -0300368
Andre Guedes61a0cfb2012-08-01 20:34:15 -0300369 cancel_delayed_work_sync(&conn->security_timer);
370
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700371 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesf1c09c02012-02-01 18:27:56 -0300372 smp_chan_destroy(conn);
Brian Gix4f957a72011-11-23 08:28:36 -0800373}
374
Brian Gix2b64d152011-12-21 16:12:12 -0800375#define JUST_WORKS 0x00
376#define JUST_CFM 0x01
377#define REQ_PASSKEY 0x02
378#define CFM_PASSKEY 0x03
379#define REQ_OOB 0x04
380#define OVERLAP 0xFF
381
382static const u8 gen_method[5][5] = {
383 { JUST_WORKS, JUST_CFM, REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
384 { JUST_WORKS, JUST_CFM, REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
385 { CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
386 { JUST_WORKS, JUST_CFM, JUST_WORKS, JUST_WORKS, JUST_CFM },
387 { CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, OVERLAP },
388};
389
390static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
391 u8 local_io, u8 remote_io)
392{
393 struct hci_conn *hcon = conn->hcon;
394 struct smp_chan *smp = conn->smp_chan;
395 u8 method;
396 u32 passkey = 0;
397 int ret = 0;
398
399 /* Initialize key for JUST WORKS */
400 memset(smp->tk, 0, sizeof(smp->tk));
401 clear_bit(SMP_FLAG_TK_VALID, &smp->smp_flags);
402
403 BT_DBG("tk_request: auth:%d lcl:%d rem:%d", auth, local_io, remote_io);
404
405 /* If neither side wants MITM, use JUST WORKS */
406 /* If either side has unknown io_caps, use JUST WORKS */
407 /* Otherwise, look up method from the table */
408 if (!(auth & SMP_AUTH_MITM) ||
Marcel Holtmannf1560462013-10-13 05:43:25 -0700409 local_io > SMP_IO_KEYBOARD_DISPLAY ||
410 remote_io > SMP_IO_KEYBOARD_DISPLAY)
Brian Gix2b64d152011-12-21 16:12:12 -0800411 method = JUST_WORKS;
412 else
Ido Yarivb3ff53f2012-03-05 20:07:08 +0200413 method = gen_method[remote_io][local_io];
Brian Gix2b64d152011-12-21 16:12:12 -0800414
415 /* If not bonding, don't ask user to confirm a Zero TK */
416 if (!(auth & SMP_AUTH_BONDING) && method == JUST_CFM)
417 method = JUST_WORKS;
418
Johan Hedberga82505c2014-03-24 14:39:07 +0200419 /* Don't confirm locally initiated pairing attempts */
420 if (method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR,
421 &smp->smp_flags))
422 method = JUST_WORKS;
423
Brian Gix2b64d152011-12-21 16:12:12 -0800424 /* If Just Works, Continue with Zero TK */
425 if (method == JUST_WORKS) {
426 set_bit(SMP_FLAG_TK_VALID, &smp->smp_flags);
427 return 0;
428 }
429
430 /* Not Just Works/Confirm results in MITM Authentication */
431 if (method != JUST_CFM)
432 set_bit(SMP_FLAG_MITM_AUTH, &smp->smp_flags);
433
434 /* If both devices have Keyoard-Display I/O, the master
435 * Confirms and the slave Enters the passkey.
436 */
437 if (method == OVERLAP) {
438 if (hcon->link_mode & HCI_LM_MASTER)
439 method = CFM_PASSKEY;
440 else
441 method = REQ_PASSKEY;
442 }
443
Johan Hedberg01ad34d2014-03-19 14:14:53 +0200444 /* Generate random passkey. */
Brian Gix2b64d152011-12-21 16:12:12 -0800445 if (method == CFM_PASSKEY) {
Johan Hedberg943a7322014-03-18 12:58:24 +0200446 memset(smp->tk, 0, sizeof(smp->tk));
Brian Gix2b64d152011-12-21 16:12:12 -0800447 get_random_bytes(&passkey, sizeof(passkey));
448 passkey %= 1000000;
Johan Hedberg943a7322014-03-18 12:58:24 +0200449 put_unaligned_le32(passkey, smp->tk);
Brian Gix2b64d152011-12-21 16:12:12 -0800450 BT_DBG("PassKey: %d", passkey);
Johan Hedberg01ad34d2014-03-19 14:14:53 +0200451 set_bit(SMP_FLAG_TK_VALID, &smp->smp_flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800452 }
453
454 hci_dev_lock(hcon->hdev);
455
456 if (method == REQ_PASSKEY)
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700457 ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200458 hcon->type, hcon->dst_type);
Johan Hedberg4eb65e62014-03-24 14:39:05 +0200459 else if (method == JUST_CFM)
460 ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
461 hcon->type, hcon->dst_type,
462 passkey, 1);
Brian Gix2b64d152011-12-21 16:12:12 -0800463 else
Johan Hedberg01ad34d2014-03-19 14:14:53 +0200464 ret = mgmt_user_passkey_notify(hcon->hdev, &hcon->dst,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200465 hcon->type, hcon->dst_type,
Johan Hedberg39adbff2014-03-20 08:18:14 +0200466 passkey, 0);
Brian Gix2b64d152011-12-21 16:12:12 -0800467
468 hci_dev_unlock(hcon->hdev);
469
470 return ret;
471}
472
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300473static void confirm_work(struct work_struct *work)
474{
475 struct smp_chan *smp = container_of(work, struct smp_chan, confirm);
476 struct l2cap_conn *conn = smp->conn;
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200477 struct hci_dev *hdev = conn->hcon->hdev;
478 struct crypto_blkcipher *tfm = hdev->tfm_aes;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300479 struct smp_cmd_pairing_confirm cp;
480 int ret;
Johan Hedberg943a7322014-03-18 12:58:24 +0200481 u8 reason;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300482
483 BT_DBG("conn %p", conn);
484
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200485 /* Prevent mutual access to hdev->tfm_aes */
486 hci_dev_lock(hdev);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300487
Johan Hedbergb1cd5fd2014-02-28 12:54:17 +0200488 ret = smp_c1(tfm, smp->tk, smp->prnd, smp->preq, smp->prsp,
489 conn->hcon->init_addr_type, &conn->hcon->init_addr,
Johan Hedberg943a7322014-03-18 12:58:24 +0200490 conn->hcon->resp_addr_type, &conn->hcon->resp_addr,
491 cp.confirm_val);
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200492
493 hci_dev_unlock(hdev);
494
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300495 if (ret) {
496 reason = SMP_UNSPECIFIED;
497 goto error;
498 }
499
Brian Gix2b64d152011-12-21 16:12:12 -0800500 clear_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags);
501
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300502 smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
503
504 return;
505
506error:
Johan Hedberg84794e12013-11-06 11:24:57 +0200507 smp_failure(conn, reason);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300508}
509
510static void random_work(struct work_struct *work)
511{
512 struct smp_chan *smp = container_of(work, struct smp_chan, random);
513 struct l2cap_conn *conn = smp->conn;
514 struct hci_conn *hcon = conn->hcon;
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200515 struct hci_dev *hdev = hcon->hdev;
516 struct crypto_blkcipher *tfm = hdev->tfm_aes;
Johan Hedberg943a7322014-03-18 12:58:24 +0200517 u8 reason, confirm[16];
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300518 int ret;
519
520 if (IS_ERR_OR_NULL(tfm)) {
521 reason = SMP_UNSPECIFIED;
522 goto error;
523 }
524
525 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
526
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200527 /* Prevent mutual access to hdev->tfm_aes */
528 hci_dev_lock(hdev);
529
Johan Hedbergb1cd5fd2014-02-28 12:54:17 +0200530 ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp,
531 hcon->init_addr_type, &hcon->init_addr,
Johan Hedberg943a7322014-03-18 12:58:24 +0200532 hcon->resp_addr_type, &hcon->resp_addr, confirm);
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200533
534 hci_dev_unlock(hdev);
535
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300536 if (ret) {
537 reason = SMP_UNSPECIFIED;
538 goto error;
539 }
540
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300541 if (memcmp(smp->pcnf, confirm, sizeof(smp->pcnf)) != 0) {
542 BT_ERR("Pairing failed (confirmation values mismatch)");
543 reason = SMP_CONFIRM_FAILED;
544 goto error;
545 }
546
547 if (hcon->out) {
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -0800548 u8 stk[16];
549 __le64 rand = 0;
550 __le16 ediv = 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300551
Johan Hedberg943a7322014-03-18 12:58:24 +0200552 smp_s1(tfm, smp->tk, smp->rrnd, smp->prnd, stk);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300553
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300554 memset(stk + smp->enc_key_size, 0,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300555 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300556
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200557 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags)) {
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300558 reason = SMP_UNSPECIFIED;
559 goto error;
560 }
561
562 hci_le_start_enc(hcon, ediv, rand, stk);
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300563 hcon->enc_key_size = smp->enc_key_size;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300564 } else {
Johan Hedberg943a7322014-03-18 12:58:24 +0200565 u8 stk[16];
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -0800566 __le64 rand = 0;
567 __le16 ediv = 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300568
Johan Hedberg943a7322014-03-18 12:58:24 +0200569 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
570 smp->prnd);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300571
Johan Hedberg943a7322014-03-18 12:58:24 +0200572 smp_s1(tfm, smp->tk, smp->prnd, smp->rrnd, stk);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300573
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300574 memset(stk + smp->enc_key_size, 0,
Marcel Holtmannf1560462013-10-13 05:43:25 -0700575 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300576
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700577 hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
Johan Hedberg35d70272014-02-19 14:57:47 +0200578 HCI_SMP_STK_SLAVE, 0, stk, smp->enc_key_size,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300579 ediv, rand);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300580 }
581
582 return;
583
584error:
Johan Hedberg84794e12013-11-06 11:24:57 +0200585 smp_failure(conn, reason);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300586}
587
588static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
589{
590 struct smp_chan *smp;
591
Marcel Holtmannf1560462013-10-13 05:43:25 -0700592 smp = kzalloc(sizeof(*smp), GFP_ATOMIC);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300593 if (!smp)
594 return NULL;
595
596 INIT_WORK(&smp->confirm, confirm_work);
597 INIT_WORK(&smp->random, random_work);
598
599 smp->conn = conn;
600 conn->smp_chan = smp;
Brian Gix2b64d152011-12-21 16:12:12 -0800601 conn->hcon->smp_conn = conn;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300602
603 hci_conn_hold(conn->hcon);
604
605 return smp;
606}
607
608void smp_chan_destroy(struct l2cap_conn *conn)
609{
Brian Gixc8eb9692011-11-23 08:28:35 -0800610 struct smp_chan *smp = conn->smp_chan;
Johan Hedbergf4a407be2014-02-18 21:41:34 +0200611 bool complete;
Brian Gixc8eb9692011-11-23 08:28:35 -0800612
Vinicius Costa Gomesf1c09c02012-02-01 18:27:56 -0300613 BUG_ON(!smp);
Brian Gixc8eb9692011-11-23 08:28:35 -0800614
Johan Hedbergf4a407be2014-02-18 21:41:34 +0200615 complete = test_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
616 mgmt_smp_complete(conn->hcon, complete);
617
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -0700618 kfree(smp->csrk);
619 kfree(smp->slave_csrk);
620
Johan Hedberg759331d2014-02-28 10:10:16 +0200621 /* If pairing failed clean up any keys we might have */
622 if (!complete) {
623 if (smp->ltk) {
624 list_del(&smp->ltk->list);
625 kfree(smp->ltk);
626 }
627
628 if (smp->slave_ltk) {
629 list_del(&smp->slave_ltk->list);
630 kfree(smp->slave_ltk);
631 }
632
633 if (smp->remote_irk) {
634 list_del(&smp->remote_irk->list);
635 kfree(smp->remote_irk);
636 }
637 }
638
Brian Gixc8eb9692011-11-23 08:28:35 -0800639 kfree(smp);
640 conn->smp_chan = NULL;
Brian Gix2b64d152011-12-21 16:12:12 -0800641 conn->hcon->smp_conn = NULL;
David Herrmann76a68ba2013-04-06 20:28:37 +0200642 hci_conn_drop(conn->hcon);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300643}
644
Brian Gix2b64d152011-12-21 16:12:12 -0800645int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
646{
647 struct l2cap_conn *conn = hcon->smp_conn;
648 struct smp_chan *smp;
649 u32 value;
Brian Gix2b64d152011-12-21 16:12:12 -0800650
651 BT_DBG("");
652
653 if (!conn)
654 return -ENOTCONN;
655
656 smp = conn->smp_chan;
657
658 switch (mgmt_op) {
659 case MGMT_OP_USER_PASSKEY_REPLY:
660 value = le32_to_cpu(passkey);
Johan Hedberg943a7322014-03-18 12:58:24 +0200661 memset(smp->tk, 0, sizeof(smp->tk));
Brian Gix2b64d152011-12-21 16:12:12 -0800662 BT_DBG("PassKey: %d", value);
Johan Hedberg943a7322014-03-18 12:58:24 +0200663 put_unaligned_le32(value, smp->tk);
Brian Gix2b64d152011-12-21 16:12:12 -0800664 /* Fall Through */
665 case MGMT_OP_USER_CONFIRM_REPLY:
666 set_bit(SMP_FLAG_TK_VALID, &smp->smp_flags);
667 break;
668 case MGMT_OP_USER_PASSKEY_NEG_REPLY:
669 case MGMT_OP_USER_CONFIRM_NEG_REPLY:
Johan Hedberg84794e12013-11-06 11:24:57 +0200670 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
Brian Gix2b64d152011-12-21 16:12:12 -0800671 return 0;
672 default:
Johan Hedberg84794e12013-11-06 11:24:57 +0200673 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
Brian Gix2b64d152011-12-21 16:12:12 -0800674 return -EOPNOTSUPP;
675 }
676
677 /* If it is our turn to send Pairing Confirm, do so now */
678 if (test_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags))
679 queue_work(hcon->hdev->workqueue, &smp->confirm);
680
681 return 0;
682}
683
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300684static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300685{
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300686 struct smp_cmd_pairing rsp, *req = (void *) skb->data;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300687 struct smp_chan *smp;
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300688 u8 key_size;
Brian Gix2b64d152011-12-21 16:12:12 -0800689 u8 auth = SMP_AUTH_NONE;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300690 int ret;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300691
692 BT_DBG("conn %p", conn);
693
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200694 if (skb->len < sizeof(*req))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300695 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200696
Brian Gix2b64d152011-12-21 16:12:12 -0800697 if (conn->hcon->link_mode & HCI_LM_MASTER)
698 return SMP_CMD_NOTSUPP;
699
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200700 if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags))
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300701 smp = smp_chan_create(conn);
Andrei Emeltchenkod08fd0e2012-07-19 17:03:43 +0300702 else
703 smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300704
Andrei Emeltchenkod08fd0e2012-07-19 17:03:43 +0300705 if (!smp)
706 return SMP_UNSPECIFIED;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300707
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300708 smp->preq[0] = SMP_CMD_PAIRING_REQ;
709 memcpy(&smp->preq[1], req, sizeof(*req));
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300710 skb_pull(skb, sizeof(*req));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300711
Brian Gix2b64d152011-12-21 16:12:12 -0800712 /* We didn't start the pairing, so match remote */
713 if (req->auth_req & SMP_AUTH_BONDING)
714 auth = req->auth_req;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300715
Ido Yarivfdde0a22012-03-05 20:09:38 +0200716 conn->hcon->pending_sec_level = authreq_to_seclevel(auth);
717
Brian Gix2b64d152011-12-21 16:12:12 -0800718 build_pairing_cmd(conn, req, &rsp, auth);
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300719
720 key_size = min(req->max_key_size, rsp.max_key_size);
721 if (check_enc_key_size(conn, key_size))
722 return SMP_ENC_KEY_SIZE;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300723
Johan Hedberge84a6b12013-12-02 10:49:03 +0200724 get_random_bytes(smp->prnd, sizeof(smp->prnd));
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300725
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300726 smp->prsp[0] = SMP_CMD_PAIRING_RSP;
727 memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300728
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300729 smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300730
Brian Gix2b64d152011-12-21 16:12:12 -0800731 /* Request setup of TK */
732 ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability);
733 if (ret)
734 return SMP_UNSPECIFIED;
735
Johan Hedbergedca7922014-03-24 15:54:11 +0200736 clear_bit(SMP_FLAG_INITIATOR, &smp->smp_flags);
737
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300738 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300739}
740
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300741static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300742{
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300743 struct smp_cmd_pairing *req, *rsp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300744 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300745 struct hci_dev *hdev = conn->hcon->hdev;
Brian Gix2b64d152011-12-21 16:12:12 -0800746 u8 key_size, auth = SMP_AUTH_NONE;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300747 int ret;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300748
749 BT_DBG("conn %p", conn);
750
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200751 if (skb->len < sizeof(*rsp))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300752 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200753
Brian Gix2b64d152011-12-21 16:12:12 -0800754 if (!(conn->hcon->link_mode & HCI_LM_MASTER))
755 return SMP_CMD_NOTSUPP;
756
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300757 skb_pull(skb, sizeof(*rsp));
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300758
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300759 req = (void *) &smp->preq[1];
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300760
761 key_size = min(req->max_key_size, rsp->max_key_size);
762 if (check_enc_key_size(conn, key_size))
763 return SMP_ENC_KEY_SIZE;
764
Johan Hedberge84a6b12013-12-02 10:49:03 +0200765 get_random_bytes(smp->prnd, sizeof(smp->prnd));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300766
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300767 smp->prsp[0] = SMP_CMD_PAIRING_RSP;
768 memcpy(&smp->prsp[1], rsp, sizeof(*rsp));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300769
Johan Hedbergfdcc4be2014-03-14 10:53:50 +0200770 /* Update remote key distribution in case the remote cleared
771 * some bits that we had enabled in our request.
772 */
773 smp->remote_key_dist &= rsp->resp_key_dist;
774
Brian Gix2b64d152011-12-21 16:12:12 -0800775 if ((req->auth_req & SMP_AUTH_BONDING) &&
Marcel Holtmannf1560462013-10-13 05:43:25 -0700776 (rsp->auth_req & SMP_AUTH_BONDING))
Brian Gix2b64d152011-12-21 16:12:12 -0800777 auth = SMP_AUTH_BONDING;
778
779 auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM;
780
Johan Hedberg476585e2012-06-06 18:54:15 +0800781 ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability);
Brian Gix2b64d152011-12-21 16:12:12 -0800782 if (ret)
783 return SMP_UNSPECIFIED;
784
785 set_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags);
786
787 /* Can't compose response until we have been confirmed */
Johan Hedberg18e4aeb2014-03-19 14:14:51 +0200788 if (test_bit(SMP_FLAG_TK_VALID, &smp->smp_flags))
789 queue_work(hdev->workqueue, &smp->confirm);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300790
791 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300792}
793
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300794static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300795{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300796 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300797 struct hci_dev *hdev = conn->hcon->hdev;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300798
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300799 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
800
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200801 if (skb->len < sizeof(smp->pcnf))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300802 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200803
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300804 memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf));
805 skb_pull(skb, sizeof(smp->pcnf));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300806
Johan Hedberg943a7322014-03-18 12:58:24 +0200807 if (conn->hcon->out)
808 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
809 smp->prnd);
810 else if (test_bit(SMP_FLAG_TK_VALID, &smp->smp_flags))
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300811 queue_work(hdev->workqueue, &smp->confirm);
Johan Hedberg943a7322014-03-18 12:58:24 +0200812 else
Brian Gix2b64d152011-12-21 16:12:12 -0800813 set_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300814
815 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300816}
817
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300818static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300819{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300820 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300821 struct hci_dev *hdev = conn->hcon->hdev;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300822
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300823 BT_DBG("conn %p", conn);
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300824
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200825 if (skb->len < sizeof(smp->rrnd))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300826 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200827
Johan Hedberg943a7322014-03-18 12:58:24 +0200828 memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd));
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300829 skb_pull(skb, sizeof(smp->rrnd));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300830
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300831 queue_work(hdev->workqueue, &smp->random);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300832
833 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300834}
835
Johan Hedberg4dab7862012-06-07 14:58:37 +0800836static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300837{
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300838 struct smp_ltk *key;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300839 struct hci_conn *hcon = conn->hcon;
840
Johan Hedberg98a0b842014-01-30 19:40:00 -0800841 key = hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type,
842 hcon->out);
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300843 if (!key)
844 return 0;
845
Johan Hedberg4dab7862012-06-07 14:58:37 +0800846 if (sec_level > BT_SECURITY_MEDIUM && !key->authenticated)
847 return 0;
848
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200849 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300850 return 1;
851
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300852 hci_le_start_enc(hcon, key->ediv, key->rand, key->val);
853 hcon->enc_key_size = key->enc_size;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300854
855 return 1;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300856}
Marcel Holtmannf1560462013-10-13 05:43:25 -0700857
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300858static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300859{
860 struct smp_cmd_security_req *rp = (void *) skb->data;
861 struct smp_cmd_pairing cp;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300862 struct hci_conn *hcon = conn->hcon;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300863 struct smp_chan *smp;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300864
865 BT_DBG("conn %p", conn);
866
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200867 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300868 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200869
Johan Hedberg86ca9ea2013-11-05 11:30:39 +0200870 if (!(conn->hcon->link_mode & HCI_LM_MASTER))
871 return SMP_CMD_NOTSUPP;
872
Brian Gix2b64d152011-12-21 16:12:12 -0800873 hcon->pending_sec_level = authreq_to_seclevel(rp->auth_req);
Vinicius Costa Gomesfeb45eb2011-08-25 20:02:35 -0300874
Johan Hedberg4dab7862012-06-07 14:58:37 +0800875 if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300876 return 0;
877
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200878 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300879 return 0;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300880
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300881 smp = smp_chan_create(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300882
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300883 skb_pull(skb, sizeof(*rp));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300884
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300885 memset(&cp, 0, sizeof(cp));
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300886 build_pairing_cmd(conn, &cp, NULL, rp->auth_req);
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300887
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300888 smp->preq[0] = SMP_CMD_PAIRING_REQ;
889 memcpy(&smp->preq[1], &cp, sizeof(cp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300890
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300891 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300892
Johan Hedbergedca7922014-03-24 15:54:11 +0200893 clear_bit(SMP_FLAG_INITIATOR, &smp->smp_flags);
894
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300895 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300896}
897
Johan Hedbergad32a2f2013-05-14 18:05:12 +0300898bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level)
899{
900 if (sec_level == BT_SECURITY_LOW)
901 return true;
902
903 if (hcon->sec_level >= sec_level)
904 return true;
905
906 return false;
907}
908
Vinicius Costa Gomescc110922012-08-23 21:32:43 -0300909int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300910{
Vinicius Costa Gomescc110922012-08-23 21:32:43 -0300911 struct l2cap_conn *conn = hcon->l2cap_data;
Johan Hedberg0a66cf22014-03-24 14:39:03 +0200912 struct smp_chan *smp;
Brian Gix2b64d152011-12-21 16:12:12 -0800913 __u8 authreq;
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300914
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -0300915 BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
916
Johan Hedberg0a66cf22014-03-24 14:39:03 +0200917 /* This may be NULL if there's an unexpected disconnection */
918 if (!conn)
919 return 1;
920
Johan Hedberg757aee02013-04-24 13:05:32 +0300921 if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags))
Andre Guedes2e65c9d2011-06-30 19:20:56 -0300922 return 1;
923
Johan Hedbergad32a2f2013-05-14 18:05:12 +0300924 if (smp_sufficient_security(hcon, sec_level))
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300925 return 1;
926
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300927 if (hcon->link_mode & HCI_LM_MASTER)
Johan Hedberg4dab7862012-06-07 14:58:37 +0800928 if (smp_ltk_encrypt(conn, sec_level))
Vinicius Costa Gomes02bc7452011-07-07 18:59:41 -0300929 goto done;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300930
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200931 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300932 return 0;
933
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300934 smp = smp_chan_create(conn);
Brian Gix2b64d152011-12-21 16:12:12 -0800935 if (!smp)
936 return 1;
937
938 authreq = seclevel_to_authreq(sec_level);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300939
Johan Hedberg2e233642014-03-18 15:42:30 +0200940 /* hcon->auth_type is set by pair_device in mgmt.c. If the MITM
941 * flag is set we should also set it for the SMP request.
942 */
943 if ((hcon->auth_type & 0x01))
944 authreq |= SMP_AUTH_MITM;
945
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300946 if (hcon->link_mode & HCI_LM_MASTER) {
947 struct smp_cmd_pairing cp;
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300948
Brian Gix2b64d152011-12-21 16:12:12 -0800949 build_pairing_cmd(conn, &cp, NULL, authreq);
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300950 smp->preq[0] = SMP_CMD_PAIRING_REQ;
951 memcpy(&smp->preq[1], &cp, sizeof(cp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300952
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300953 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
954 } else {
955 struct smp_cmd_security_req cp;
Brian Gix2b64d152011-12-21 16:12:12 -0800956 cp.auth_req = authreq;
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300957 smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
958 }
959
Johan Hedbergedca7922014-03-24 15:54:11 +0200960 set_bit(SMP_FLAG_INITIATOR, &smp->smp_flags);
961
Johan Hedberg61b3b2b2014-03-24 17:36:25 +0200962done:
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300963 hcon->pending_sec_level = sec_level;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300964
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300965 return 0;
966}
967
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300968static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
969{
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300970 struct smp_cmd_encrypt_info *rp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300971 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300972
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200973 BT_DBG("conn %p", conn);
974
975 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300976 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200977
Johan Hedberg6131ddc2014-02-18 10:19:37 +0200978 /* Ignore this PDU if it wasn't requested */
979 if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
980 return 0;
981
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300982 skb_pull(skb, sizeof(*rp));
983
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300984 memcpy(smp->tk, rp->ltk, sizeof(smp->tk));
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300985
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300986 return 0;
987}
988
989static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
990{
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300991 struct smp_cmd_master_ident *rp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300992 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300993 struct hci_dev *hdev = conn->hcon->hdev;
994 struct hci_conn *hcon = conn->hcon;
Johan Hedberg23d0e122014-02-19 14:57:46 +0200995 struct smp_ltk *ltk;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300996 u8 authenticated;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300997
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200998 BT_DBG("conn %p", conn);
999
1000 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001001 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +02001002
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001003 /* Ignore this PDU if it wasn't requested */
1004 if (!(smp->remote_key_dist & SMP_DIST_ENC_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_ENC_KEY;
1009
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001010 skb_pull(skb, sizeof(*rp));
1011
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001012 hci_dev_lock(hdev);
Marcel Holtmannce39fb42013-10-13 02:23:39 -07001013 authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
Johan Hedberg35d70272014-02-19 14:57:47 +02001014 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, HCI_SMP_LTK,
Johan Hedberg23d0e122014-02-19 14:57:46 +02001015 authenticated, smp->tk, smp->enc_key_size,
1016 rp->ediv, rp->rand);
1017 smp->ltk = ltk;
Johan Hedbergfd349c02014-02-18 10:19:36 +02001018 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001019 smp_distribute_keys(conn);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001020 hci_dev_unlock(hdev);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001021
1022 return 0;
1023}
1024
Johan Hedbergfd349c02014-02-18 10:19:36 +02001025static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
1026{
1027 struct smp_cmd_ident_info *info = (void *) skb->data;
1028 struct smp_chan *smp = conn->smp_chan;
1029
1030 BT_DBG("");
1031
1032 if (skb->len < sizeof(*info))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001033 return SMP_INVALID_PARAMS;
Johan Hedbergfd349c02014-02-18 10:19:36 +02001034
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001035 /* Ignore this PDU if it wasn't requested */
1036 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
1037 return 0;
1038
Johan Hedbergfd349c02014-02-18 10:19:36 +02001039 skb_pull(skb, sizeof(*info));
1040
1041 memcpy(smp->irk, info->irk, 16);
1042
1043 return 0;
1044}
1045
1046static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
1047 struct sk_buff *skb)
1048{
1049 struct smp_cmd_ident_addr_info *info = (void *) skb->data;
1050 struct smp_chan *smp = conn->smp_chan;
1051 struct hci_conn *hcon = conn->hcon;
1052 bdaddr_t rpa;
1053
1054 BT_DBG("");
1055
1056 if (skb->len < sizeof(*info))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001057 return SMP_INVALID_PARAMS;
Johan Hedbergfd349c02014-02-18 10:19:36 +02001058
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001059 /* Ignore this PDU if it wasn't requested */
1060 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
1061 return 0;
1062
Johan Hedberg9747a9f2014-02-26 23:33:43 +02001063 /* Mark the information as received */
1064 smp->remote_key_dist &= ~SMP_DIST_ID_KEY;
1065
Johan Hedbergfd349c02014-02-18 10:19:36 +02001066 skb_pull(skb, sizeof(*info));
1067
Johan Hedberga9a58f82014-02-25 22:24:37 +02001068 /* Strictly speaking the Core Specification (4.1) allows sending
1069 * an empty address which would force us to rely on just the IRK
1070 * as "identity information". However, since such
1071 * implementations are not known of and in order to not over
1072 * complicate our implementation, simply pretend that we never
1073 * received an IRK for such a device.
1074 */
1075 if (!bacmp(&info->bdaddr, BDADDR_ANY)) {
1076 BT_ERR("Ignoring IRK with no identity address");
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001077 smp_distribute_keys(conn);
Johan Hedberga9a58f82014-02-25 22:24:37 +02001078 return 0;
1079 }
1080
Johan Hedbergfd349c02014-02-18 10:19:36 +02001081 bacpy(&smp->id_addr, &info->bdaddr);
1082 smp->id_addr_type = info->addr_type;
1083
1084 if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type))
1085 bacpy(&rpa, &hcon->dst);
1086 else
1087 bacpy(&rpa, BDADDR_ANY);
1088
Johan Hedberg23d0e122014-02-19 14:57:46 +02001089 smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
1090 smp->id_addr_type, smp->irk, &rpa);
Johan Hedbergfd349c02014-02-18 10:19:36 +02001091
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001092 smp_distribute_keys(conn);
Johan Hedbergfd349c02014-02-18 10:19:36 +02001093
1094 return 0;
1095}
1096
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001097static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)
1098{
1099 struct smp_cmd_sign_info *rp = (void *) skb->data;
1100 struct smp_chan *smp = conn->smp_chan;
1101 struct hci_dev *hdev = conn->hcon->hdev;
1102 struct smp_csrk *csrk;
1103
1104 BT_DBG("conn %p", conn);
1105
1106 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001107 return SMP_INVALID_PARAMS;
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001108
1109 /* Ignore this PDU if it wasn't requested */
1110 if (!(smp->remote_key_dist & SMP_DIST_SIGN))
1111 return 0;
1112
1113 /* Mark the information as received */
1114 smp->remote_key_dist &= ~SMP_DIST_SIGN;
1115
1116 skb_pull(skb, sizeof(*rp));
1117
1118 hci_dev_lock(hdev);
1119 csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
1120 if (csrk) {
1121 csrk->master = 0x01;
1122 memcpy(csrk->val, rp->csrk, sizeof(csrk->val));
1123 }
1124 smp->csrk = csrk;
1125 if (!(smp->remote_key_dist & SMP_DIST_SIGN))
1126 smp_distribute_keys(conn);
1127 hci_dev_unlock(hdev);
1128
1129 return 0;
1130}
1131
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001132int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
1133{
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001134 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann92381f52013-10-03 01:23:08 -07001135 __u8 code, reason;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001136 int err = 0;
1137
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001138 if (hcon->type != LE_LINK) {
1139 kfree_skb(skb);
Johan Hedberg34327112013-10-16 11:37:01 +03001140 return 0;
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001141 }
1142
Marcel Holtmann92381f52013-10-03 01:23:08 -07001143 if (skb->len < 1) {
1144 kfree_skb(skb);
1145 return -EILSEQ;
1146 }
1147
Marcel Holtmann06ae3312013-10-18 03:43:00 -07001148 if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) {
Andre Guedes2e65c9d2011-06-30 19:20:56 -03001149 err = -ENOTSUPP;
1150 reason = SMP_PAIRING_NOTSUPP;
1151 goto done;
1152 }
1153
Marcel Holtmann92381f52013-10-03 01:23:08 -07001154 code = skb->data[0];
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001155 skb_pull(skb, sizeof(code));
1156
Johan Hedberg8cf9fa12013-01-29 10:44:23 -06001157 /*
1158 * The SMP context must be initialized for all other PDUs except
1159 * pairing and security requests. If we get any other PDU when
1160 * not initialized simply disconnect (done if this function
1161 * returns an error).
1162 */
1163 if (code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ &&
1164 !conn->smp_chan) {
1165 BT_ERR("Unexpected SMP command 0x%02x. Disconnecting.", code);
1166 kfree_skb(skb);
1167 return -ENOTSUPP;
1168 }
1169
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001170 switch (code) {
1171 case SMP_CMD_PAIRING_REQ:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001172 reason = smp_cmd_pairing_req(conn, skb);
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001173 break;
1174
1175 case SMP_CMD_PAIRING_FAIL:
Johan Hedberg84794e12013-11-06 11:24:57 +02001176 smp_failure(conn, 0);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001177 reason = 0;
1178 err = -EPERM;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001179 break;
1180
1181 case SMP_CMD_PAIRING_RSP:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001182 reason = smp_cmd_pairing_rsp(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001183 break;
1184
1185 case SMP_CMD_SECURITY_REQ:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001186 reason = smp_cmd_security_req(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001187 break;
1188
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001189 case SMP_CMD_PAIRING_CONFIRM:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001190 reason = smp_cmd_pairing_confirm(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001191 break;
1192
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001193 case SMP_CMD_PAIRING_RANDOM:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001194 reason = smp_cmd_pairing_random(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001195 break;
1196
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001197 case SMP_CMD_ENCRYPT_INFO:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001198 reason = smp_cmd_encrypt_info(conn, skb);
1199 break;
1200
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001201 case SMP_CMD_MASTER_IDENT:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001202 reason = smp_cmd_master_ident(conn, skb);
1203 break;
1204
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001205 case SMP_CMD_IDENT_INFO:
Johan Hedbergfd349c02014-02-18 10:19:36 +02001206 reason = smp_cmd_ident_info(conn, skb);
1207 break;
1208
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001209 case SMP_CMD_IDENT_ADDR_INFO:
Johan Hedbergfd349c02014-02-18 10:19:36 +02001210 reason = smp_cmd_ident_addr_info(conn, skb);
1211 break;
1212
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001213 case SMP_CMD_SIGN_INFO:
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001214 reason = smp_cmd_sign_info(conn, skb);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001215 break;
1216
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001217 default:
1218 BT_DBG("Unknown command code 0x%2.2x", code);
1219
1220 reason = SMP_CMD_NOTSUPP;
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -03001221 err = -EOPNOTSUPP;
1222 goto done;
1223 }
1224
1225done:
1226 if (reason)
Johan Hedberg84794e12013-11-06 11:24:57 +02001227 smp_failure(conn, reason);
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001228
1229 kfree_skb(skb);
1230 return err;
1231}
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001232
Johan Hedberg35d70272014-02-19 14:57:47 +02001233static void smp_notify_keys(struct l2cap_conn *conn)
1234{
1235 struct smp_chan *smp = conn->smp_chan;
1236 struct hci_conn *hcon = conn->hcon;
1237 struct hci_dev *hdev = hcon->hdev;
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001238 struct smp_cmd_pairing *req = (void *) &smp->preq[1];
1239 struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1];
1240 bool persistent;
Johan Hedberg35d70272014-02-19 14:57:47 +02001241
Johan Hedberg61b1a7f2014-03-20 12:54:16 +02001242 if (smp->remote_irk) {
Johan Hedberg95fbac82014-02-19 15:18:31 +02001243 mgmt_new_irk(hdev, smp->remote_irk);
Johan Hedberg61b1a7f2014-03-20 12:54:16 +02001244 /* Now that user space can be considered to know the
1245 * identity address track the connection based on it
1246 * from now on.
1247 */
1248 bacpy(&hcon->dst, &smp->remote_irk->bdaddr);
1249 hcon->dst_type = smp->remote_irk->addr_type;
1250 l2cap_conn_update_id_addr(hcon);
1251 }
Johan Hedberg95fbac82014-02-19 15:18:31 +02001252
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001253 /* The LTKs and CSRKs should be persistent only if both sides
1254 * had the bonding bit set in their authentication requests.
1255 */
1256 persistent = !!((req->auth_req & rsp->auth_req) & SMP_AUTH_BONDING);
1257
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001258 if (smp->csrk) {
1259 smp->csrk->bdaddr_type = hcon->dst_type;
1260 bacpy(&smp->csrk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001261 mgmt_new_csrk(hdev, smp->csrk, persistent);
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001262 }
1263
1264 if (smp->slave_csrk) {
1265 smp->slave_csrk->bdaddr_type = hcon->dst_type;
1266 bacpy(&smp->slave_csrk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001267 mgmt_new_csrk(hdev, smp->slave_csrk, persistent);
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001268 }
1269
Johan Hedberg35d70272014-02-19 14:57:47 +02001270 if (smp->ltk) {
1271 smp->ltk->bdaddr_type = hcon->dst_type;
1272 bacpy(&smp->ltk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001273 mgmt_new_ltk(hdev, smp->ltk, persistent);
Johan Hedberg35d70272014-02-19 14:57:47 +02001274 }
1275
1276 if (smp->slave_ltk) {
1277 smp->slave_ltk->bdaddr_type = hcon->dst_type;
1278 bacpy(&smp->slave_ltk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001279 mgmt_new_ltk(hdev, smp->slave_ltk, persistent);
Johan Hedberg35d70272014-02-19 14:57:47 +02001280 }
1281}
1282
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001283int smp_distribute_keys(struct l2cap_conn *conn)
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001284{
1285 struct smp_cmd_pairing *req, *rsp;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001286 struct smp_chan *smp = conn->smp_chan;
Johan Hedberg524237c2014-02-22 19:06:31 +02001287 struct hci_conn *hcon = conn->hcon;
1288 struct hci_dev *hdev = hcon->hdev;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001289 __u8 *keydist;
1290
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001291 BT_DBG("conn %p", conn);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001292
Johan Hedberg524237c2014-02-22 19:06:31 +02001293 if (!test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001294 return 0;
1295
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001296 rsp = (void *) &smp->prsp[1];
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001297
1298 /* The responder sends its keys first */
Johan Hedbergefabba32014-02-26 23:33:44 +02001299 if (hcon->out && (smp->remote_key_dist & 0x07))
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001300 return 0;
1301
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001302 req = (void *) &smp->preq[1];
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001303
Johan Hedberg524237c2014-02-22 19:06:31 +02001304 if (hcon->out) {
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001305 keydist = &rsp->init_key_dist;
1306 *keydist &= req->init_key_dist;
1307 } else {
1308 keydist = &rsp->resp_key_dist;
1309 *keydist &= req->resp_key_dist;
1310 }
1311
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001312 BT_DBG("keydist 0x%x", *keydist);
1313
1314 if (*keydist & SMP_DIST_ENC_KEY) {
1315 struct smp_cmd_encrypt_info enc;
1316 struct smp_cmd_master_ident ident;
Johan Hedberg23d0e122014-02-19 14:57:46 +02001317 struct smp_ltk *ltk;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001318 u8 authenticated;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001319 __le16 ediv;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001320 __le64 rand;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001321
1322 get_random_bytes(enc.ltk, sizeof(enc.ltk));
1323 get_random_bytes(&ediv, sizeof(ediv));
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001324 get_random_bytes(&rand, sizeof(rand));
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001325
1326 smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
1327
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001328 authenticated = hcon->sec_level == BT_SECURITY_HIGH;
Johan Hedberg524237c2014-02-22 19:06:31 +02001329 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type,
Johan Hedberg35d70272014-02-19 14:57:47 +02001330 HCI_SMP_LTK_SLAVE, authenticated, enc.ltk,
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001331 smp->enc_key_size, ediv, rand);
Johan Hedberg23d0e122014-02-19 14:57:46 +02001332 smp->slave_ltk = ltk;
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001333
Andrei Emeltchenko58115372012-03-12 12:13:06 +02001334 ident.ediv = ediv;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001335 ident.rand = rand;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001336
1337 smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident);
1338
1339 *keydist &= ~SMP_DIST_ENC_KEY;
1340 }
1341
1342 if (*keydist & SMP_DIST_ID_KEY) {
1343 struct smp_cmd_ident_addr_info addrinfo;
1344 struct smp_cmd_ident_info idinfo;
1345
Johan Hedberg863efaf2014-02-22 19:06:32 +02001346 memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk));
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001347
1348 smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo);
1349
Johan Hedberg82d4b352014-02-23 19:42:18 +02001350 /* The hci_conn contains the local identity address
1351 * after the connection has been established.
1352 *
1353 * This is true even when the connection has been
1354 * established using a resolvable random address.
1355 */
Johan Hedberg524237c2014-02-22 19:06:31 +02001356 bacpy(&addrinfo.bdaddr, &hcon->src);
Johan Hedberg82d4b352014-02-23 19:42:18 +02001357 addrinfo.addr_type = hcon->src_type;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001358
1359 smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo),
Marcel Holtmannf1560462013-10-13 05:43:25 -07001360 &addrinfo);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001361
1362 *keydist &= ~SMP_DIST_ID_KEY;
1363 }
1364
1365 if (*keydist & SMP_DIST_SIGN) {
1366 struct smp_cmd_sign_info sign;
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001367 struct smp_csrk *csrk;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001368
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001369 /* Generate a new random key */
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001370 get_random_bytes(sign.csrk, sizeof(sign.csrk));
1371
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001372 csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
1373 if (csrk) {
1374 csrk->master = 0x00;
1375 memcpy(csrk->val, sign.csrk, sizeof(csrk->val));
1376 }
1377 smp->slave_csrk = csrk;
1378
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001379 smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign);
1380
1381 *keydist &= ~SMP_DIST_SIGN;
1382 }
1383
Johan Hedbergefabba32014-02-26 23:33:44 +02001384 /* If there are still keys to be received wait for them */
1385 if ((smp->remote_key_dist & 0x07))
1386 return 0;
1387
Johan Hedberg1d98bf42014-03-24 14:39:08 +02001388 clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags);
1389 cancel_delayed_work_sync(&conn->security_timer);
1390 set_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
1391 smp_notify_keys(conn);
Johan Hedbergefabba32014-02-26 23:33:44 +02001392
Johan Hedberg1d98bf42014-03-24 14:39:08 +02001393 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001394
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001395 return 0;
1396}