blob: b9cac1deb19fcc0dcf01fefced71dc0ef70134b8 [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;
Johan Hedberg4a74d652014-05-20 09:45:50 +030062 unsigned long flags;
Johan Hedberg4bc58f52014-05-20 09:45:47 +030063};
64
Johan Hedberg66bed1a2014-03-18 12:58:23 +020065static inline void swap128(const u8 src[16], u8 dst[16])
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030066{
67 int i;
68 for (i = 0; i < 16; i++)
69 dst[15 - i] = src[i];
70}
71
Johan Hedberg66bed1a2014-03-18 12:58:23 +020072static inline void swap56(const u8 src[7], u8 dst[7])
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030073{
74 int i;
75 for (i = 0; i < 7; i++)
76 dst[6 - i] = src[i];
77}
78
79static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
80{
81 struct blkcipher_desc desc;
82 struct scatterlist sg;
Johan Hedberg943a7322014-03-18 12:58:24 +020083 uint8_t tmp[16], data[16];
Johan Hedberg201a5922013-12-02 10:49:04 +020084 int err;
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030085
86 if (tfm == NULL) {
87 BT_ERR("tfm %p", tfm);
88 return -EINVAL;
89 }
90
91 desc.tfm = tfm;
92 desc.flags = 0;
93
Johan Hedberg943a7322014-03-18 12:58:24 +020094 /* The most significant octet of key corresponds to k[0] */
95 swap128(k, tmp);
96
97 err = crypto_blkcipher_setkey(tfm, tmp, 16);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030098 if (err) {
99 BT_ERR("cipher setkey failed: %d", err);
100 return err;
101 }
102
Johan Hedberg943a7322014-03-18 12:58:24 +0200103 /* Most significant octet of plaintextData corresponds to data[0] */
104 swap128(r, data);
105
106 sg_init_one(&sg, data, 16);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300107
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300108 err = crypto_blkcipher_encrypt(&desc, &sg, &sg, 16);
109 if (err)
110 BT_ERR("Encrypt data error %d", err);
111
Johan Hedberg943a7322014-03-18 12:58:24 +0200112 /* Most significant octet of encryptedData corresponds to data[0] */
113 swap128(data, r);
114
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300115 return err;
116}
117
Johan Hedberg60478052014-02-18 10:19:31 +0200118static int smp_ah(struct crypto_blkcipher *tfm, u8 irk[16], u8 r[3], u8 res[3])
119{
Johan Hedberg943a7322014-03-18 12:58:24 +0200120 u8 _res[16];
Johan Hedberg60478052014-02-18 10:19:31 +0200121 int err;
122
123 /* r' = padding || r */
Johan Hedberg943a7322014-03-18 12:58:24 +0200124 memcpy(_res, r, 3);
125 memset(_res + 3, 0, 13);
Johan Hedberg60478052014-02-18 10:19:31 +0200126
Johan Hedberg943a7322014-03-18 12:58:24 +0200127 err = smp_e(tfm, irk, _res);
Johan Hedberg60478052014-02-18 10:19:31 +0200128 if (err) {
129 BT_ERR("Encrypt error");
130 return err;
131 }
132
133 /* The output of the random address function ah is:
134 * ah(h, r) = e(k, r') mod 2^24
135 * The output of the security function e is then truncated to 24 bits
136 * by taking the least significant 24 bits of the output of e as the
137 * result of ah.
138 */
Johan Hedberg943a7322014-03-18 12:58:24 +0200139 memcpy(res, _res, 3);
Johan Hedberg60478052014-02-18 10:19:31 +0200140
141 return 0;
142}
143
144bool smp_irk_matches(struct crypto_blkcipher *tfm, u8 irk[16],
145 bdaddr_t *bdaddr)
146{
147 u8 hash[3];
148 int err;
149
150 BT_DBG("RPA %pMR IRK %*phN", bdaddr, 16, irk);
151
152 err = smp_ah(tfm, irk, &bdaddr->b[3], hash);
153 if (err)
154 return false;
155
156 return !memcmp(bdaddr->b, hash, 3);
157}
158
Johan Hedbergb1e2b3a2014-02-23 19:42:19 +0200159int smp_generate_rpa(struct crypto_blkcipher *tfm, u8 irk[16], bdaddr_t *rpa)
160{
161 int err;
162
163 get_random_bytes(&rpa->b[3], 3);
164
165 rpa->b[5] &= 0x3f; /* Clear two most significant bits */
166 rpa->b[5] |= 0x40; /* Set second most significant bit */
167
168 err = smp_ah(tfm, irk, &rpa->b[3], rpa->b);
169 if (err < 0)
170 return err;
171
172 BT_DBG("RPA %pMR", rpa);
173
174 return 0;
175}
176
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300177static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16],
Marcel Holtmannf1560462013-10-13 05:43:25 -0700178 u8 preq[7], u8 pres[7], u8 _iat, bdaddr_t *ia,
179 u8 _rat, bdaddr_t *ra, u8 res[16])
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300180{
181 u8 p1[16], p2[16];
182 int err;
183
184 memset(p1, 0, 16);
185
186 /* p1 = pres || preq || _rat || _iat */
Johan Hedberg943a7322014-03-18 12:58:24 +0200187 p1[0] = _iat;
188 p1[1] = _rat;
189 memcpy(p1 + 2, preq, 7);
190 memcpy(p1 + 9, pres, 7);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300191
192 /* p2 = padding || ia || ra */
Johan Hedberg943a7322014-03-18 12:58:24 +0200193 memcpy(p2, ra, 6);
194 memcpy(p2 + 6, ia, 6);
195 memset(p2 + 12, 0, 4);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300196
197 /* res = r XOR p1 */
198 u128_xor((u128 *) res, (u128 *) r, (u128 *) p1);
199
200 /* res = e(k, res) */
201 err = smp_e(tfm, k, res);
202 if (err) {
203 BT_ERR("Encrypt data error");
204 return err;
205 }
206
207 /* res = res XOR p2 */
208 u128_xor((u128 *) res, (u128 *) res, (u128 *) p2);
209
210 /* res = e(k, res) */
211 err = smp_e(tfm, k, res);
212 if (err)
213 BT_ERR("Encrypt data error");
214
215 return err;
216}
217
Marcel Holtmannf1560462013-10-13 05:43:25 -0700218static int smp_s1(struct crypto_blkcipher *tfm, u8 k[16], u8 r1[16],
219 u8 r2[16], u8 _r[16])
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300220{
221 int err;
222
223 /* Just least significant octets from r1 and r2 are considered */
Johan Hedberg943a7322014-03-18 12:58:24 +0200224 memcpy(_r, r2, 8);
225 memcpy(_r + 8, r1, 8);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300226
227 err = smp_e(tfm, k, _r);
228 if (err)
229 BT_ERR("Encrypt data error");
230
231 return err;
232}
233
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300234static struct sk_buff *smp_build_cmd(struct l2cap_conn *conn, u8 code,
Marcel Holtmannf1560462013-10-13 05:43:25 -0700235 u16 dlen, void *data)
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300236{
237 struct sk_buff *skb;
238 struct l2cap_hdr *lh;
239 int len;
240
241 len = L2CAP_HDR_SIZE + sizeof(code) + dlen;
242
243 if (len > conn->mtu)
244 return NULL;
245
246 skb = bt_skb_alloc(len, GFP_ATOMIC);
247 if (!skb)
248 return NULL;
249
250 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
251 lh->len = cpu_to_le16(sizeof(code) + dlen);
Joe Perchesdcf4adb2014-03-12 10:52:35 -0700252 lh->cid = cpu_to_le16(L2CAP_CID_SMP);
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300253
254 memcpy(skb_put(skb, sizeof(code)), &code, sizeof(code));
255
256 memcpy(skb_put(skb, dlen), data, dlen);
257
258 return skb;
259}
260
261static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
262{
263 struct sk_buff *skb = smp_build_cmd(conn, code, len, data);
264
265 BT_DBG("code 0x%2.2x", code);
266
267 if (!skb)
268 return;
269
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200270 skb->priority = HCI_PRIO_MAX;
271 hci_send_acl(conn->hchan, skb, 0);
Vinicius Costa Gomese2dcd112011-08-19 21:06:50 -0300272
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -0200273 cancel_delayed_work_sync(&conn->security_timer);
Marcel Holtmann17b02e62012-03-01 14:32:37 -0800274 schedule_delayed_work(&conn->security_timer, SMP_TIMEOUT);
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300275}
276
Brian Gix2b64d152011-12-21 16:12:12 -0800277static __u8 authreq_to_seclevel(__u8 authreq)
278{
279 if (authreq & SMP_AUTH_MITM)
280 return BT_SECURITY_HIGH;
281 else
282 return BT_SECURITY_MEDIUM;
283}
284
285static __u8 seclevel_to_authreq(__u8 sec_level)
286{
287 switch (sec_level) {
288 case BT_SECURITY_HIGH:
289 return SMP_AUTH_MITM | SMP_AUTH_BONDING;
290 case BT_SECURITY_MEDIUM:
291 return SMP_AUTH_BONDING;
292 default:
293 return SMP_AUTH_NONE;
294 }
295}
296
Vinicius Costa Gomesb8e66ea2011-06-09 18:50:52 -0300297static void build_pairing_cmd(struct l2cap_conn *conn,
Marcel Holtmannf1560462013-10-13 05:43:25 -0700298 struct smp_cmd_pairing *req,
299 struct smp_cmd_pairing *rsp, __u8 authreq)
Vinicius Costa Gomesb8e66ea2011-06-09 18:50:52 -0300300{
Johan Hedbergfd349c02014-02-18 10:19:36 +0200301 struct smp_chan *smp = conn->smp_chan;
302 struct hci_conn *hcon = conn->hcon;
303 struct hci_dev *hdev = hcon->hdev;
304 u8 local_dist = 0, remote_dist = 0;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300305
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200306 if (test_bit(HCI_PAIRABLE, &conn->hcon->hdev->dev_flags)) {
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -0700307 local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
308 remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300309 authreq |= SMP_AUTH_BONDING;
Brian Gix2b64d152011-12-21 16:12:12 -0800310 } else {
311 authreq &= ~SMP_AUTH_BONDING;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300312 }
313
Johan Hedbergfd349c02014-02-18 10:19:36 +0200314 if (test_bit(HCI_RPA_RESOLVING, &hdev->dev_flags))
315 remote_dist |= SMP_DIST_ID_KEY;
316
Johan Hedberg863efaf2014-02-22 19:06:32 +0200317 if (test_bit(HCI_PRIVACY, &hdev->dev_flags))
318 local_dist |= SMP_DIST_ID_KEY;
319
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300320 if (rsp == NULL) {
321 req->io_capability = conn->hcon->io_capability;
322 req->oob_flag = SMP_OOB_NOT_PRESENT;
323 req->max_key_size = SMP_MAX_ENC_KEY_SIZE;
Johan Hedbergfd349c02014-02-18 10:19:36 +0200324 req->init_key_dist = local_dist;
325 req->resp_key_dist = remote_dist;
Johan Hedberg065a13e2012-10-11 16:26:06 +0200326 req->auth_req = (authreq & AUTH_REQ_MASK);
Johan Hedbergfd349c02014-02-18 10:19:36 +0200327
328 smp->remote_key_dist = remote_dist;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300329 return;
330 }
331
332 rsp->io_capability = conn->hcon->io_capability;
333 rsp->oob_flag = SMP_OOB_NOT_PRESENT;
334 rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE;
Johan Hedbergfd349c02014-02-18 10:19:36 +0200335 rsp->init_key_dist = req->init_key_dist & remote_dist;
336 rsp->resp_key_dist = req->resp_key_dist & local_dist;
Johan Hedberg065a13e2012-10-11 16:26:06 +0200337 rsp->auth_req = (authreq & AUTH_REQ_MASK);
Johan Hedbergfd349c02014-02-18 10:19:36 +0200338
339 smp->remote_key_dist = rsp->init_key_dist;
Vinicius Costa Gomesb8e66ea2011-06-09 18:50:52 -0300340}
341
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300342static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
343{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300344 struct smp_chan *smp = conn->smp_chan;
345
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300346 if ((max_key_size > SMP_MAX_ENC_KEY_SIZE) ||
Marcel Holtmannf1560462013-10-13 05:43:25 -0700347 (max_key_size < SMP_MIN_ENC_KEY_SIZE))
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300348 return SMP_ENC_KEY_SIZE;
349
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300350 smp->enc_key_size = max_key_size;
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300351
352 return 0;
353}
354
Johan Hedberg84794e12013-11-06 11:24:57 +0200355static void smp_failure(struct l2cap_conn *conn, u8 reason)
Brian Gix4f957a72011-11-23 08:28:36 -0800356{
Johan Hedbergbab73cb2012-02-09 16:07:29 +0200357 struct hci_conn *hcon = conn->hcon;
358
Johan Hedberg84794e12013-11-06 11:24:57 +0200359 if (reason)
Brian Gix4f957a72011-11-23 08:28:36 -0800360 smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
Marcel Holtmannf1560462013-10-13 05:43:25 -0700361 &reason);
Brian Gix4f957a72011-11-23 08:28:36 -0800362
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700363 clear_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags);
364 mgmt_auth_failed(hcon->hdev, &hcon->dst, hcon->type, hcon->dst_type,
365 HCI_ERROR_AUTH_FAILURE);
Vinicius Costa Gomesf1c09c02012-02-01 18:27:56 -0300366
Andre Guedes61a0cfb2012-08-01 20:34:15 -0300367 cancel_delayed_work_sync(&conn->security_timer);
368
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700369 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesf1c09c02012-02-01 18:27:56 -0300370 smp_chan_destroy(conn);
Brian Gix4f957a72011-11-23 08:28:36 -0800371}
372
Brian Gix2b64d152011-12-21 16:12:12 -0800373#define JUST_WORKS 0x00
374#define JUST_CFM 0x01
375#define REQ_PASSKEY 0x02
376#define CFM_PASSKEY 0x03
377#define REQ_OOB 0x04
378#define OVERLAP 0xFF
379
380static const u8 gen_method[5][5] = {
381 { JUST_WORKS, JUST_CFM, REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
382 { JUST_WORKS, JUST_CFM, REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
383 { CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
384 { JUST_WORKS, JUST_CFM, JUST_WORKS, JUST_WORKS, JUST_CFM },
385 { CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, OVERLAP },
386};
387
Johan Hedberg581370c2014-06-17 13:07:38 +0300388static u8 get_auth_method(struct smp_chan *smp, u8 local_io, u8 remote_io)
389{
390 /* If either side has unknown io_caps, use JUST WORKS */
391 if (local_io > SMP_IO_KEYBOARD_DISPLAY ||
392 remote_io > SMP_IO_KEYBOARD_DISPLAY)
393 return JUST_WORKS;
394
395 return gen_method[remote_io][local_io];
396}
397
Brian Gix2b64d152011-12-21 16:12:12 -0800398static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
399 u8 local_io, u8 remote_io)
400{
401 struct hci_conn *hcon = conn->hcon;
402 struct smp_chan *smp = conn->smp_chan;
403 u8 method;
404 u32 passkey = 0;
405 int ret = 0;
406
407 /* Initialize key for JUST WORKS */
408 memset(smp->tk, 0, sizeof(smp->tk));
Johan Hedberg4a74d652014-05-20 09:45:50 +0300409 clear_bit(SMP_FLAG_TK_VALID, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800410
411 BT_DBG("tk_request: auth:%d lcl:%d rem:%d", auth, local_io, remote_io);
412
413 /* If neither side wants MITM, use JUST WORKS */
Brian Gix2b64d152011-12-21 16:12:12 -0800414 /* Otherwise, look up method from the table */
Johan Hedberg581370c2014-06-17 13:07:38 +0300415 if (!(auth & SMP_AUTH_MITM))
Brian Gix2b64d152011-12-21 16:12:12 -0800416 method = JUST_WORKS;
417 else
Johan Hedberg581370c2014-06-17 13:07:38 +0300418 method = get_auth_method(smp, local_io, remote_io);
Brian Gix2b64d152011-12-21 16:12:12 -0800419
420 /* If not bonding, don't ask user to confirm a Zero TK */
421 if (!(auth & SMP_AUTH_BONDING) && method == JUST_CFM)
422 method = JUST_WORKS;
423
Johan Hedberga82505c2014-03-24 14:39:07 +0200424 /* Don't confirm locally initiated pairing attempts */
Johan Hedberg4a74d652014-05-20 09:45:50 +0300425 if (method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR, &smp->flags))
Johan Hedberga82505c2014-03-24 14:39:07 +0200426 method = JUST_WORKS;
427
Brian Gix2b64d152011-12-21 16:12:12 -0800428 /* If Just Works, Continue with Zero TK */
429 if (method == JUST_WORKS) {
Johan Hedberg4a74d652014-05-20 09:45:50 +0300430 set_bit(SMP_FLAG_TK_VALID, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800431 return 0;
432 }
433
434 /* Not Just Works/Confirm results in MITM Authentication */
435 if (method != JUST_CFM)
Johan Hedberg4a74d652014-05-20 09:45:50 +0300436 set_bit(SMP_FLAG_MITM_AUTH, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800437
438 /* If both devices have Keyoard-Display I/O, the master
439 * Confirms and the slave Enters the passkey.
440 */
441 if (method == OVERLAP) {
442 if (hcon->link_mode & HCI_LM_MASTER)
443 method = CFM_PASSKEY;
444 else
445 method = REQ_PASSKEY;
446 }
447
Johan Hedberg01ad34d2014-03-19 14:14:53 +0200448 /* Generate random passkey. */
Brian Gix2b64d152011-12-21 16:12:12 -0800449 if (method == CFM_PASSKEY) {
Johan Hedberg943a7322014-03-18 12:58:24 +0200450 memset(smp->tk, 0, sizeof(smp->tk));
Brian Gix2b64d152011-12-21 16:12:12 -0800451 get_random_bytes(&passkey, sizeof(passkey));
452 passkey %= 1000000;
Johan Hedberg943a7322014-03-18 12:58:24 +0200453 put_unaligned_le32(passkey, smp->tk);
Brian Gix2b64d152011-12-21 16:12:12 -0800454 BT_DBG("PassKey: %d", passkey);
Johan Hedberg4a74d652014-05-20 09:45:50 +0300455 set_bit(SMP_FLAG_TK_VALID, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800456 }
457
458 hci_dev_lock(hcon->hdev);
459
460 if (method == REQ_PASSKEY)
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700461 ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200462 hcon->type, hcon->dst_type);
Johan Hedberg4eb65e62014-03-24 14:39:05 +0200463 else if (method == JUST_CFM)
464 ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
465 hcon->type, hcon->dst_type,
466 passkey, 1);
Brian Gix2b64d152011-12-21 16:12:12 -0800467 else
Johan Hedberg01ad34d2014-03-19 14:14:53 +0200468 ret = mgmt_user_passkey_notify(hcon->hdev, &hcon->dst,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200469 hcon->type, hcon->dst_type,
Johan Hedberg39adbff2014-03-20 08:18:14 +0200470 passkey, 0);
Brian Gix2b64d152011-12-21 16:12:12 -0800471
472 hci_dev_unlock(hcon->hdev);
473
474 return ret;
475}
476
Johan Hedberg1cc61142014-05-20 09:45:52 +0300477static u8 smp_confirm(struct smp_chan *smp)
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300478{
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300479 struct l2cap_conn *conn = smp->conn;
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200480 struct hci_dev *hdev = conn->hcon->hdev;
481 struct crypto_blkcipher *tfm = hdev->tfm_aes;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300482 struct smp_cmd_pairing_confirm cp;
483 int ret;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300484
485 BT_DBG("conn %p", conn);
486
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200487 /* Prevent mutual access to hdev->tfm_aes */
488 hci_dev_lock(hdev);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300489
Johan Hedbergb1cd5fd2014-02-28 12:54:17 +0200490 ret = smp_c1(tfm, smp->tk, smp->prnd, smp->preq, smp->prsp,
491 conn->hcon->init_addr_type, &conn->hcon->init_addr,
Johan Hedberg943a7322014-03-18 12:58:24 +0200492 conn->hcon->resp_addr_type, &conn->hcon->resp_addr,
493 cp.confirm_val);
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200494
495 hci_dev_unlock(hdev);
496
Johan Hedberg1cc61142014-05-20 09:45:52 +0300497 if (ret)
498 return SMP_UNSPECIFIED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300499
Johan Hedberg4a74d652014-05-20 09:45:50 +0300500 clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800501
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300502 smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
503
Johan Hedberg1cc61142014-05-20 09:45:52 +0300504 return 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300505}
506
Johan Hedberg861580a2014-05-20 09:45:51 +0300507static u8 smp_random(struct smp_chan *smp)
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300508{
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300509 struct l2cap_conn *conn = smp->conn;
510 struct hci_conn *hcon = conn->hcon;
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200511 struct hci_dev *hdev = hcon->hdev;
512 struct crypto_blkcipher *tfm = hdev->tfm_aes;
Johan Hedberg861580a2014-05-20 09:45:51 +0300513 u8 confirm[16];
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300514 int ret;
515
Johan Hedberg861580a2014-05-20 09:45:51 +0300516 if (IS_ERR_OR_NULL(tfm))
517 return SMP_UNSPECIFIED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300518
519 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
520
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200521 /* Prevent mutual access to hdev->tfm_aes */
522 hci_dev_lock(hdev);
523
Johan Hedbergb1cd5fd2014-02-28 12:54:17 +0200524 ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp,
525 hcon->init_addr_type, &hcon->init_addr,
Johan Hedberg943a7322014-03-18 12:58:24 +0200526 hcon->resp_addr_type, &hcon->resp_addr, confirm);
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200527
528 hci_dev_unlock(hdev);
529
Johan Hedberg861580a2014-05-20 09:45:51 +0300530 if (ret)
531 return SMP_UNSPECIFIED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300532
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300533 if (memcmp(smp->pcnf, confirm, sizeof(smp->pcnf)) != 0) {
534 BT_ERR("Pairing failed (confirmation values mismatch)");
Johan Hedberg861580a2014-05-20 09:45:51 +0300535 return SMP_CONFIRM_FAILED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300536 }
537
538 if (hcon->out) {
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -0800539 u8 stk[16];
540 __le64 rand = 0;
541 __le16 ediv = 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300542
Johan Hedberg943a7322014-03-18 12:58:24 +0200543 smp_s1(tfm, smp->tk, smp->rrnd, smp->prnd, stk);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300544
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300545 memset(stk + smp->enc_key_size, 0,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300546 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300547
Johan Hedberg861580a2014-05-20 09:45:51 +0300548 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
549 return SMP_UNSPECIFIED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300550
551 hci_le_start_enc(hcon, ediv, rand, stk);
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300552 hcon->enc_key_size = smp->enc_key_size;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300553 } else {
Johan Hedbergfff34902014-06-10 15:19:50 +0300554 u8 stk[16], auth;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -0800555 __le64 rand = 0;
556 __le16 ediv = 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300557
Johan Hedberg943a7322014-03-18 12:58:24 +0200558 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
559 smp->prnd);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300560
Johan Hedberg943a7322014-03-18 12:58:24 +0200561 smp_s1(tfm, smp->tk, smp->prnd, smp->rrnd, stk);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300562
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300563 memset(stk + smp->enc_key_size, 0,
Marcel Holtmannf1560462013-10-13 05:43:25 -0700564 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300565
Johan Hedbergfff34902014-06-10 15:19:50 +0300566 if (hcon->pending_sec_level == BT_SECURITY_HIGH)
567 auth = 1;
568 else
569 auth = 0;
570
Johan Hedberg7d5843b2014-06-16 19:25:15 +0300571 /* Even though there's no _SLAVE suffix this is the
572 * slave STK we're adding for later lookup (the master
573 * STK never needs to be stored).
574 */
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700575 hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
Johan Hedberg7d5843b2014-06-16 19:25:15 +0300576 HCI_SMP_STK, auth, stk, smp->enc_key_size,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300577 ediv, rand);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300578 }
579
Johan Hedberg861580a2014-05-20 09:45:51 +0300580 return 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300581}
582
583static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
584{
585 struct smp_chan *smp;
586
Marcel Holtmannf1560462013-10-13 05:43:25 -0700587 smp = kzalloc(sizeof(*smp), GFP_ATOMIC);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300588 if (!smp)
589 return NULL;
590
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300591 smp->conn = conn;
592 conn->smp_chan = smp;
Brian Gix2b64d152011-12-21 16:12:12 -0800593 conn->hcon->smp_conn = conn;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300594
595 hci_conn_hold(conn->hcon);
596
597 return smp;
598}
599
600void smp_chan_destroy(struct l2cap_conn *conn)
601{
Brian Gixc8eb9692011-11-23 08:28:35 -0800602 struct smp_chan *smp = conn->smp_chan;
Johan Hedbergf4a407b2014-02-18 21:41:34 +0200603 bool complete;
Brian Gixc8eb9692011-11-23 08:28:35 -0800604
Vinicius Costa Gomesf1c09c02012-02-01 18:27:56 -0300605 BUG_ON(!smp);
Brian Gixc8eb9692011-11-23 08:28:35 -0800606
Johan Hedberg4a74d652014-05-20 09:45:50 +0300607 complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags);
Johan Hedbergf4a407b2014-02-18 21:41:34 +0200608 mgmt_smp_complete(conn->hcon, complete);
609
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -0700610 kfree(smp->csrk);
611 kfree(smp->slave_csrk);
612
Johan Hedberg759331d2014-02-28 10:10:16 +0200613 /* If pairing failed clean up any keys we might have */
614 if (!complete) {
615 if (smp->ltk) {
616 list_del(&smp->ltk->list);
617 kfree(smp->ltk);
618 }
619
620 if (smp->slave_ltk) {
621 list_del(&smp->slave_ltk->list);
622 kfree(smp->slave_ltk);
623 }
624
625 if (smp->remote_irk) {
626 list_del(&smp->remote_irk->list);
627 kfree(smp->remote_irk);
628 }
629 }
630
Brian Gixc8eb9692011-11-23 08:28:35 -0800631 kfree(smp);
632 conn->smp_chan = NULL;
Brian Gix2b64d152011-12-21 16:12:12 -0800633 conn->hcon->smp_conn = NULL;
David Herrmann76a68ba2013-04-06 20:28:37 +0200634 hci_conn_drop(conn->hcon);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300635}
636
Brian Gix2b64d152011-12-21 16:12:12 -0800637int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
638{
639 struct l2cap_conn *conn = hcon->smp_conn;
640 struct smp_chan *smp;
641 u32 value;
Brian Gix2b64d152011-12-21 16:12:12 -0800642
643 BT_DBG("");
644
645 if (!conn)
646 return -ENOTCONN;
647
648 smp = conn->smp_chan;
649
650 switch (mgmt_op) {
651 case MGMT_OP_USER_PASSKEY_REPLY:
652 value = le32_to_cpu(passkey);
Johan Hedberg943a7322014-03-18 12:58:24 +0200653 memset(smp->tk, 0, sizeof(smp->tk));
Brian Gix2b64d152011-12-21 16:12:12 -0800654 BT_DBG("PassKey: %d", value);
Johan Hedberg943a7322014-03-18 12:58:24 +0200655 put_unaligned_le32(value, smp->tk);
Brian Gix2b64d152011-12-21 16:12:12 -0800656 /* Fall Through */
657 case MGMT_OP_USER_CONFIRM_REPLY:
Johan Hedberg4a74d652014-05-20 09:45:50 +0300658 set_bit(SMP_FLAG_TK_VALID, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800659 break;
660 case MGMT_OP_USER_PASSKEY_NEG_REPLY:
661 case MGMT_OP_USER_CONFIRM_NEG_REPLY:
Johan Hedberg84794e12013-11-06 11:24:57 +0200662 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
Brian Gix2b64d152011-12-21 16:12:12 -0800663 return 0;
664 default:
Johan Hedberg84794e12013-11-06 11:24:57 +0200665 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
Brian Gix2b64d152011-12-21 16:12:12 -0800666 return -EOPNOTSUPP;
667 }
668
669 /* If it is our turn to send Pairing Confirm, do so now */
Johan Hedberg1cc61142014-05-20 09:45:52 +0300670 if (test_bit(SMP_FLAG_CFM_PENDING, &smp->flags)) {
671 u8 rsp = smp_confirm(smp);
672 if (rsp)
673 smp_failure(conn, rsp);
674 }
Brian Gix2b64d152011-12-21 16:12:12 -0800675
676 return 0;
677}
678
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300679static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300680{
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300681 struct smp_cmd_pairing rsp, *req = (void *) skb->data;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300682 struct smp_chan *smp;
Johan Hedbergc7262e72014-06-17 13:07:37 +0300683 u8 key_size, auth, sec_level;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300684 int ret;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300685
686 BT_DBG("conn %p", conn);
687
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200688 if (skb->len < sizeof(*req))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300689 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200690
Brian Gix2b64d152011-12-21 16:12:12 -0800691 if (conn->hcon->link_mode & HCI_LM_MASTER)
692 return SMP_CMD_NOTSUPP;
693
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200694 if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags))
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300695 smp = smp_chan_create(conn);
Andrei Emeltchenkod08fd0e2012-07-19 17:03:43 +0300696 else
697 smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300698
Andrei Emeltchenkod08fd0e2012-07-19 17:03:43 +0300699 if (!smp)
700 return SMP_UNSPECIFIED;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300701
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300702 smp->preq[0] = SMP_CMD_PAIRING_REQ;
703 memcpy(&smp->preq[1], req, sizeof(*req));
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300704 skb_pull(skb, sizeof(*req));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300705
Brian Gix2b64d152011-12-21 16:12:12 -0800706 /* We didn't start the pairing, so match remote */
Johan Hedberg1ef35822014-05-20 09:45:48 +0300707 auth = req->auth_req;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300708
Johan Hedbergc7262e72014-06-17 13:07:37 +0300709 sec_level = authreq_to_seclevel(auth);
710 if (sec_level > conn->hcon->pending_sec_level)
711 conn->hcon->pending_sec_level = sec_level;
Ido Yarivfdde0a22012-03-05 20:09:38 +0200712
Johan Hedberg2ed8f652014-06-17 13:07:39 +0300713 /* If we need MITM check that it can be acheived */
714 if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
715 u8 method;
716
717 method = get_auth_method(smp, conn->hcon->io_capability,
718 req->io_capability);
719 if (method == JUST_WORKS || method == JUST_CFM)
720 return SMP_AUTH_REQUIREMENTS;
721 }
722
Brian Gix2b64d152011-12-21 16:12:12 -0800723 build_pairing_cmd(conn, req, &rsp, auth);
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300724
725 key_size = min(req->max_key_size, rsp.max_key_size);
726 if (check_enc_key_size(conn, key_size))
727 return SMP_ENC_KEY_SIZE;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300728
Johan Hedberge84a6b12013-12-02 10:49:03 +0200729 get_random_bytes(smp->prnd, sizeof(smp->prnd));
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300730
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300731 smp->prsp[0] = SMP_CMD_PAIRING_RSP;
732 memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300733
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300734 smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300735
Brian Gix2b64d152011-12-21 16:12:12 -0800736 /* Request setup of TK */
737 ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability);
738 if (ret)
739 return SMP_UNSPECIFIED;
740
Johan Hedberg4a74d652014-05-20 09:45:50 +0300741 clear_bit(SMP_FLAG_INITIATOR, &smp->flags);
Johan Hedbergedca7922014-03-24 15:54:11 +0200742
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300743 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300744}
745
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300746static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300747{
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300748 struct smp_cmd_pairing *req, *rsp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300749 struct smp_chan *smp = conn->smp_chan;
Brian Gix2b64d152011-12-21 16:12:12 -0800750 u8 key_size, auth = SMP_AUTH_NONE;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300751 int ret;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300752
753 BT_DBG("conn %p", conn);
754
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200755 if (skb->len < sizeof(*rsp))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300756 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200757
Brian Gix2b64d152011-12-21 16:12:12 -0800758 if (!(conn->hcon->link_mode & HCI_LM_MASTER))
759 return SMP_CMD_NOTSUPP;
760
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300761 skb_pull(skb, sizeof(*rsp));
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300762
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300763 req = (void *) &smp->preq[1];
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300764
765 key_size = min(req->max_key_size, rsp->max_key_size);
766 if (check_enc_key_size(conn, key_size))
767 return SMP_ENC_KEY_SIZE;
768
Johan Hedberg2ed8f652014-06-17 13:07:39 +0300769 /* If we need MITM check that it can be acheived */
770 if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
771 u8 method;
772
773 method = get_auth_method(smp, req->io_capability,
774 rsp->io_capability);
775 if (method == JUST_WORKS || method == JUST_CFM)
776 return SMP_AUTH_REQUIREMENTS;
777 }
778
Johan Hedberge84a6b12013-12-02 10:49:03 +0200779 get_random_bytes(smp->prnd, sizeof(smp->prnd));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300780
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300781 smp->prsp[0] = SMP_CMD_PAIRING_RSP;
782 memcpy(&smp->prsp[1], rsp, sizeof(*rsp));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300783
Johan Hedbergfdcc4be2014-03-14 10:53:50 +0200784 /* Update remote key distribution in case the remote cleared
785 * some bits that we had enabled in our request.
786 */
787 smp->remote_key_dist &= rsp->resp_key_dist;
788
Brian Gix2b64d152011-12-21 16:12:12 -0800789 if ((req->auth_req & SMP_AUTH_BONDING) &&
Marcel Holtmannf1560462013-10-13 05:43:25 -0700790 (rsp->auth_req & SMP_AUTH_BONDING))
Brian Gix2b64d152011-12-21 16:12:12 -0800791 auth = SMP_AUTH_BONDING;
792
793 auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM;
794
Johan Hedberg476585e2012-06-06 18:54:15 +0800795 ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability);
Brian Gix2b64d152011-12-21 16:12:12 -0800796 if (ret)
797 return SMP_UNSPECIFIED;
798
Johan Hedberg4a74d652014-05-20 09:45:50 +0300799 set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800800
801 /* Can't compose response until we have been confirmed */
Johan Hedberg4a74d652014-05-20 09:45:50 +0300802 if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
Johan Hedberg1cc61142014-05-20 09:45:52 +0300803 return smp_confirm(smp);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300804
805 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300806}
807
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300808static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300809{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300810 struct smp_chan *smp = conn->smp_chan;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300811
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300812 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
813
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200814 if (skb->len < sizeof(smp->pcnf))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300815 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200816
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300817 memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf));
818 skb_pull(skb, sizeof(smp->pcnf));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300819
Johan Hedberg943a7322014-03-18 12:58:24 +0200820 if (conn->hcon->out)
821 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
822 smp->prnd);
Johan Hedberg4a74d652014-05-20 09:45:50 +0300823 else if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
Johan Hedberg1cc61142014-05-20 09:45:52 +0300824 return smp_confirm(smp);
Johan Hedberg943a7322014-03-18 12:58:24 +0200825 else
Johan Hedberg4a74d652014-05-20 09:45:50 +0300826 set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300827
828 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300829}
830
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300831static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300832{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300833 struct smp_chan *smp = conn->smp_chan;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300834
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300835 BT_DBG("conn %p", conn);
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300836
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200837 if (skb->len < sizeof(smp->rrnd))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300838 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200839
Johan Hedberg943a7322014-03-18 12:58:24 +0200840 memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd));
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300841 skb_pull(skb, sizeof(smp->rrnd));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300842
Johan Hedberg861580a2014-05-20 09:45:51 +0300843 return smp_random(smp);
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300844}
845
Johan Hedberg4dab7862012-06-07 14:58:37 +0800846static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300847{
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300848 struct smp_ltk *key;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300849 struct hci_conn *hcon = conn->hcon;
850
Johan Hedberg98a0b842014-01-30 19:40:00 -0800851 key = hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type,
852 hcon->out);
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300853 if (!key)
854 return 0;
855
Johan Hedberg4dab7862012-06-07 14:58:37 +0800856 if (sec_level > BT_SECURITY_MEDIUM && !key->authenticated)
857 return 0;
858
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200859 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300860 return 1;
861
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300862 hci_le_start_enc(hcon, key->ediv, key->rand, key->val);
863 hcon->enc_key_size = key->enc_size;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300864
865 return 1;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300866}
Marcel Holtmannf1560462013-10-13 05:43:25 -0700867
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300868static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300869{
870 struct smp_cmd_security_req *rp = (void *) skb->data;
871 struct smp_cmd_pairing cp;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300872 struct hci_conn *hcon = conn->hcon;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300873 struct smp_chan *smp;
Johan Hedbergc7262e72014-06-17 13:07:37 +0300874 u8 sec_level;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300875
876 BT_DBG("conn %p", conn);
877
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200878 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300879 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200880
Johan Hedberg86ca9ea2013-11-05 11:30:39 +0200881 if (!(conn->hcon->link_mode & HCI_LM_MASTER))
882 return SMP_CMD_NOTSUPP;
883
Johan Hedbergc7262e72014-06-17 13:07:37 +0300884 sec_level = authreq_to_seclevel(rp->auth_req);
885 if (sec_level > hcon->pending_sec_level)
886 hcon->pending_sec_level = sec_level;
Vinicius Costa Gomesfeb45eb2011-08-25 20:02:35 -0300887
Johan Hedberg4dab7862012-06-07 14:58:37 +0800888 if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300889 return 0;
890
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200891 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300892 return 0;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300893
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300894 smp = smp_chan_create(conn);
Johan Hedbergc29d2442014-06-16 19:25:14 +0300895 if (!smp)
896 return SMP_UNSPECIFIED;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300897
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300898 skb_pull(skb, sizeof(*rp));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300899
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300900 memset(&cp, 0, sizeof(cp));
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300901 build_pairing_cmd(conn, &cp, NULL, rp->auth_req);
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300902
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300903 smp->preq[0] = SMP_CMD_PAIRING_REQ;
904 memcpy(&smp->preq[1], &cp, sizeof(cp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300905
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300906 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300907
Johan Hedberg4a74d652014-05-20 09:45:50 +0300908 clear_bit(SMP_FLAG_INITIATOR, &smp->flags);
Johan Hedbergedca7922014-03-24 15:54:11 +0200909
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300910 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300911}
912
Johan Hedbergad32a2f2013-05-14 18:05:12 +0300913bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level)
914{
915 if (sec_level == BT_SECURITY_LOW)
916 return true;
917
918 if (hcon->sec_level >= sec_level)
919 return true;
920
921 return false;
922}
923
Vinicius Costa Gomescc110922012-08-23 21:32:43 -0300924int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300925{
Vinicius Costa Gomescc110922012-08-23 21:32:43 -0300926 struct l2cap_conn *conn = hcon->l2cap_data;
Johan Hedberg0a66cf22014-03-24 14:39:03 +0200927 struct smp_chan *smp;
Brian Gix2b64d152011-12-21 16:12:12 -0800928 __u8 authreq;
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300929
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -0300930 BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
931
Johan Hedberg0a66cf22014-03-24 14:39:03 +0200932 /* This may be NULL if there's an unexpected disconnection */
933 if (!conn)
934 return 1;
935
Johan Hedberg757aee02013-04-24 13:05:32 +0300936 if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags))
Andre Guedes2e65c9d2011-06-30 19:20:56 -0300937 return 1;
938
Johan Hedbergad32a2f2013-05-14 18:05:12 +0300939 if (smp_sufficient_security(hcon, sec_level))
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300940 return 1;
941
Johan Hedbergc7262e72014-06-17 13:07:37 +0300942 if (sec_level > hcon->pending_sec_level)
943 hcon->pending_sec_level = sec_level;
944
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300945 if (hcon->link_mode & HCI_LM_MASTER)
Johan Hedbergc7262e72014-06-17 13:07:37 +0300946 if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
947 return 0;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300948
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200949 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300950 return 0;
951
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300952 smp = smp_chan_create(conn);
Brian Gix2b64d152011-12-21 16:12:12 -0800953 if (!smp)
954 return 1;
955
956 authreq = seclevel_to_authreq(sec_level);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300957
Johan Hedberg79897d22014-06-01 09:45:24 +0300958 /* Require MITM if IO Capability allows or the security level
959 * requires it.
Johan Hedberg2e233642014-03-18 15:42:30 +0200960 */
Johan Hedberg79897d22014-06-01 09:45:24 +0300961 if (hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT ||
Johan Hedbergc7262e72014-06-17 13:07:37 +0300962 hcon->pending_sec_level > BT_SECURITY_MEDIUM)
Johan Hedberg2e233642014-03-18 15:42:30 +0200963 authreq |= SMP_AUTH_MITM;
964
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300965 if (hcon->link_mode & HCI_LM_MASTER) {
966 struct smp_cmd_pairing cp;
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300967
Brian Gix2b64d152011-12-21 16:12:12 -0800968 build_pairing_cmd(conn, &cp, NULL, authreq);
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300969 smp->preq[0] = SMP_CMD_PAIRING_REQ;
970 memcpy(&smp->preq[1], &cp, sizeof(cp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300971
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300972 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
973 } else {
974 struct smp_cmd_security_req cp;
Brian Gix2b64d152011-12-21 16:12:12 -0800975 cp.auth_req = authreq;
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300976 smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
977 }
978
Johan Hedberg4a74d652014-05-20 09:45:50 +0300979 set_bit(SMP_FLAG_INITIATOR, &smp->flags);
Johan Hedbergedca7922014-03-24 15:54:11 +0200980
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300981 return 0;
982}
983
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300984static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
985{
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300986 struct smp_cmd_encrypt_info *rp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300987 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300988
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200989 BT_DBG("conn %p", conn);
990
991 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300992 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200993
Johan Hedberg6131ddc2014-02-18 10:19:37 +0200994 /* Ignore this PDU if it wasn't requested */
995 if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
996 return 0;
997
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300998 skb_pull(skb, sizeof(*rp));
999
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001000 memcpy(smp->tk, rp->ltk, sizeof(smp->tk));
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001001
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001002 return 0;
1003}
1004
1005static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
1006{
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001007 struct smp_cmd_master_ident *rp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001008 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001009 struct hci_dev *hdev = conn->hcon->hdev;
1010 struct hci_conn *hcon = conn->hcon;
Johan Hedberg23d0e122014-02-19 14:57:46 +02001011 struct smp_ltk *ltk;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001012 u8 authenticated;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001013
Johan Hedbergc46b98b2014-02-18 10:19:29 +02001014 BT_DBG("conn %p", conn);
1015
1016 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001017 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +02001018
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001019 /* Ignore this PDU if it wasn't requested */
1020 if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
1021 return 0;
1022
Johan Hedberg9747a9f2014-02-26 23:33:43 +02001023 /* Mark the information as received */
1024 smp->remote_key_dist &= ~SMP_DIST_ENC_KEY;
1025
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001026 skb_pull(skb, sizeof(*rp));
1027
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001028 hci_dev_lock(hdev);
Marcel Holtmannce39fb42013-10-13 02:23:39 -07001029 authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
Johan Hedberg35d70272014-02-19 14:57:47 +02001030 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, HCI_SMP_LTK,
Johan Hedberg23d0e122014-02-19 14:57:46 +02001031 authenticated, smp->tk, smp->enc_key_size,
1032 rp->ediv, rp->rand);
1033 smp->ltk = ltk;
Johan Hedbergfd349c02014-02-18 10:19:36 +02001034 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001035 smp_distribute_keys(conn);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001036 hci_dev_unlock(hdev);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001037
1038 return 0;
1039}
1040
Johan Hedbergfd349c02014-02-18 10:19:36 +02001041static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
1042{
1043 struct smp_cmd_ident_info *info = (void *) skb->data;
1044 struct smp_chan *smp = conn->smp_chan;
1045
1046 BT_DBG("");
1047
1048 if (skb->len < sizeof(*info))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001049 return SMP_INVALID_PARAMS;
Johan Hedbergfd349c02014-02-18 10:19:36 +02001050
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001051 /* Ignore this PDU if it wasn't requested */
1052 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
1053 return 0;
1054
Johan Hedbergfd349c02014-02-18 10:19:36 +02001055 skb_pull(skb, sizeof(*info));
1056
1057 memcpy(smp->irk, info->irk, 16);
1058
1059 return 0;
1060}
1061
1062static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
1063 struct sk_buff *skb)
1064{
1065 struct smp_cmd_ident_addr_info *info = (void *) skb->data;
1066 struct smp_chan *smp = conn->smp_chan;
1067 struct hci_conn *hcon = conn->hcon;
1068 bdaddr_t rpa;
1069
1070 BT_DBG("");
1071
1072 if (skb->len < sizeof(*info))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001073 return SMP_INVALID_PARAMS;
Johan Hedbergfd349c02014-02-18 10:19:36 +02001074
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001075 /* Ignore this PDU if it wasn't requested */
1076 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
1077 return 0;
1078
Johan Hedberg9747a9f2014-02-26 23:33:43 +02001079 /* Mark the information as received */
1080 smp->remote_key_dist &= ~SMP_DIST_ID_KEY;
1081
Johan Hedbergfd349c02014-02-18 10:19:36 +02001082 skb_pull(skb, sizeof(*info));
1083
Johan Hedberga9a58f82014-02-25 22:24:37 +02001084 /* Strictly speaking the Core Specification (4.1) allows sending
1085 * an empty address which would force us to rely on just the IRK
1086 * as "identity information". However, since such
1087 * implementations are not known of and in order to not over
1088 * complicate our implementation, simply pretend that we never
1089 * received an IRK for such a device.
1090 */
1091 if (!bacmp(&info->bdaddr, BDADDR_ANY)) {
1092 BT_ERR("Ignoring IRK with no identity address");
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001093 smp_distribute_keys(conn);
Johan Hedberga9a58f82014-02-25 22:24:37 +02001094 return 0;
1095 }
1096
Johan Hedbergfd349c02014-02-18 10:19:36 +02001097 bacpy(&smp->id_addr, &info->bdaddr);
1098 smp->id_addr_type = info->addr_type;
1099
1100 if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type))
1101 bacpy(&rpa, &hcon->dst);
1102 else
1103 bacpy(&rpa, BDADDR_ANY);
1104
Johan Hedberg23d0e122014-02-19 14:57:46 +02001105 smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
1106 smp->id_addr_type, smp->irk, &rpa);
Johan Hedbergfd349c02014-02-18 10:19:36 +02001107
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001108 smp_distribute_keys(conn);
Johan Hedbergfd349c02014-02-18 10:19:36 +02001109
1110 return 0;
1111}
1112
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001113static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)
1114{
1115 struct smp_cmd_sign_info *rp = (void *) skb->data;
1116 struct smp_chan *smp = conn->smp_chan;
1117 struct hci_dev *hdev = conn->hcon->hdev;
1118 struct smp_csrk *csrk;
1119
1120 BT_DBG("conn %p", conn);
1121
1122 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001123 return SMP_INVALID_PARAMS;
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001124
1125 /* Ignore this PDU if it wasn't requested */
1126 if (!(smp->remote_key_dist & SMP_DIST_SIGN))
1127 return 0;
1128
1129 /* Mark the information as received */
1130 smp->remote_key_dist &= ~SMP_DIST_SIGN;
1131
1132 skb_pull(skb, sizeof(*rp));
1133
1134 hci_dev_lock(hdev);
1135 csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
1136 if (csrk) {
1137 csrk->master = 0x01;
1138 memcpy(csrk->val, rp->csrk, sizeof(csrk->val));
1139 }
1140 smp->csrk = csrk;
1141 if (!(smp->remote_key_dist & SMP_DIST_SIGN))
1142 smp_distribute_keys(conn);
1143 hci_dev_unlock(hdev);
1144
1145 return 0;
1146}
1147
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001148int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
1149{
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001150 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann92381f52013-10-03 01:23:08 -07001151 __u8 code, reason;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001152 int err = 0;
1153
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001154 if (hcon->type != LE_LINK) {
1155 kfree_skb(skb);
Johan Hedberg34327112013-10-16 11:37:01 +03001156 return 0;
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001157 }
1158
Marcel Holtmann92381f52013-10-03 01:23:08 -07001159 if (skb->len < 1) {
1160 kfree_skb(skb);
1161 return -EILSEQ;
1162 }
1163
Marcel Holtmann06ae3312013-10-18 03:43:00 -07001164 if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) {
Andre Guedes2e65c9d2011-06-30 19:20:56 -03001165 err = -ENOTSUPP;
1166 reason = SMP_PAIRING_NOTSUPP;
1167 goto done;
1168 }
1169
Marcel Holtmann92381f52013-10-03 01:23:08 -07001170 code = skb->data[0];
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001171 skb_pull(skb, sizeof(code));
1172
Johan Hedberg8cf9fa12013-01-29 10:44:23 -06001173 /*
1174 * The SMP context must be initialized for all other PDUs except
1175 * pairing and security requests. If we get any other PDU when
1176 * not initialized simply disconnect (done if this function
1177 * returns an error).
1178 */
1179 if (code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ &&
1180 !conn->smp_chan) {
1181 BT_ERR("Unexpected SMP command 0x%02x. Disconnecting.", code);
1182 kfree_skb(skb);
1183 return -ENOTSUPP;
1184 }
1185
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001186 switch (code) {
1187 case SMP_CMD_PAIRING_REQ:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001188 reason = smp_cmd_pairing_req(conn, skb);
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001189 break;
1190
1191 case SMP_CMD_PAIRING_FAIL:
Johan Hedberg84794e12013-11-06 11:24:57 +02001192 smp_failure(conn, 0);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001193 reason = 0;
1194 err = -EPERM;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001195 break;
1196
1197 case SMP_CMD_PAIRING_RSP:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001198 reason = smp_cmd_pairing_rsp(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001199 break;
1200
1201 case SMP_CMD_SECURITY_REQ:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001202 reason = smp_cmd_security_req(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001203 break;
1204
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001205 case SMP_CMD_PAIRING_CONFIRM:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001206 reason = smp_cmd_pairing_confirm(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001207 break;
1208
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001209 case SMP_CMD_PAIRING_RANDOM:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001210 reason = smp_cmd_pairing_random(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001211 break;
1212
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001213 case SMP_CMD_ENCRYPT_INFO:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001214 reason = smp_cmd_encrypt_info(conn, skb);
1215 break;
1216
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001217 case SMP_CMD_MASTER_IDENT:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001218 reason = smp_cmd_master_ident(conn, skb);
1219 break;
1220
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001221 case SMP_CMD_IDENT_INFO:
Johan Hedbergfd349c02014-02-18 10:19:36 +02001222 reason = smp_cmd_ident_info(conn, skb);
1223 break;
1224
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001225 case SMP_CMD_IDENT_ADDR_INFO:
Johan Hedbergfd349c02014-02-18 10:19:36 +02001226 reason = smp_cmd_ident_addr_info(conn, skb);
1227 break;
1228
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001229 case SMP_CMD_SIGN_INFO:
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001230 reason = smp_cmd_sign_info(conn, skb);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001231 break;
1232
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001233 default:
1234 BT_DBG("Unknown command code 0x%2.2x", code);
1235
1236 reason = SMP_CMD_NOTSUPP;
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -03001237 err = -EOPNOTSUPP;
1238 goto done;
1239 }
1240
1241done:
1242 if (reason)
Johan Hedberg84794e12013-11-06 11:24:57 +02001243 smp_failure(conn, reason);
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001244
1245 kfree_skb(skb);
1246 return err;
1247}
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001248
Johan Hedberg35d70272014-02-19 14:57:47 +02001249static void smp_notify_keys(struct l2cap_conn *conn)
1250{
1251 struct smp_chan *smp = conn->smp_chan;
1252 struct hci_conn *hcon = conn->hcon;
1253 struct hci_dev *hdev = hcon->hdev;
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001254 struct smp_cmd_pairing *req = (void *) &smp->preq[1];
1255 struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1];
1256 bool persistent;
Johan Hedberg35d70272014-02-19 14:57:47 +02001257
Johan Hedberg61b1a7f2014-03-20 12:54:16 +02001258 if (smp->remote_irk) {
Johan Hedberg95fbac82014-02-19 15:18:31 +02001259 mgmt_new_irk(hdev, smp->remote_irk);
Johan Hedberg61b1a7f2014-03-20 12:54:16 +02001260 /* Now that user space can be considered to know the
1261 * identity address track the connection based on it
1262 * from now on.
1263 */
1264 bacpy(&hcon->dst, &smp->remote_irk->bdaddr);
1265 hcon->dst_type = smp->remote_irk->addr_type;
1266 l2cap_conn_update_id_addr(hcon);
1267 }
Johan Hedberg95fbac82014-02-19 15:18:31 +02001268
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001269 /* The LTKs and CSRKs should be persistent only if both sides
1270 * had the bonding bit set in their authentication requests.
1271 */
1272 persistent = !!((req->auth_req & rsp->auth_req) & SMP_AUTH_BONDING);
1273
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001274 if (smp->csrk) {
1275 smp->csrk->bdaddr_type = hcon->dst_type;
1276 bacpy(&smp->csrk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001277 mgmt_new_csrk(hdev, smp->csrk, persistent);
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001278 }
1279
1280 if (smp->slave_csrk) {
1281 smp->slave_csrk->bdaddr_type = hcon->dst_type;
1282 bacpy(&smp->slave_csrk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001283 mgmt_new_csrk(hdev, smp->slave_csrk, persistent);
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001284 }
1285
Johan Hedberg35d70272014-02-19 14:57:47 +02001286 if (smp->ltk) {
1287 smp->ltk->bdaddr_type = hcon->dst_type;
1288 bacpy(&smp->ltk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001289 mgmt_new_ltk(hdev, smp->ltk, persistent);
Johan Hedberg35d70272014-02-19 14:57:47 +02001290 }
1291
1292 if (smp->slave_ltk) {
1293 smp->slave_ltk->bdaddr_type = hcon->dst_type;
1294 bacpy(&smp->slave_ltk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001295 mgmt_new_ltk(hdev, smp->slave_ltk, persistent);
Johan Hedberg35d70272014-02-19 14:57:47 +02001296 }
1297}
1298
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001299int smp_distribute_keys(struct l2cap_conn *conn)
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001300{
1301 struct smp_cmd_pairing *req, *rsp;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001302 struct smp_chan *smp = conn->smp_chan;
Johan Hedberg524237c2014-02-22 19:06:31 +02001303 struct hci_conn *hcon = conn->hcon;
1304 struct hci_dev *hdev = hcon->hdev;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001305 __u8 *keydist;
1306
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001307 BT_DBG("conn %p", conn);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001308
Johan Hedberg524237c2014-02-22 19:06:31 +02001309 if (!test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001310 return 0;
1311
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001312 rsp = (void *) &smp->prsp[1];
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001313
1314 /* The responder sends its keys first */
Johan Hedbergefabba32014-02-26 23:33:44 +02001315 if (hcon->out && (smp->remote_key_dist & 0x07))
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001316 return 0;
1317
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001318 req = (void *) &smp->preq[1];
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001319
Johan Hedberg524237c2014-02-22 19:06:31 +02001320 if (hcon->out) {
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001321 keydist = &rsp->init_key_dist;
1322 *keydist &= req->init_key_dist;
1323 } else {
1324 keydist = &rsp->resp_key_dist;
1325 *keydist &= req->resp_key_dist;
1326 }
1327
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001328 BT_DBG("keydist 0x%x", *keydist);
1329
1330 if (*keydist & SMP_DIST_ENC_KEY) {
1331 struct smp_cmd_encrypt_info enc;
1332 struct smp_cmd_master_ident ident;
Johan Hedberg23d0e122014-02-19 14:57:46 +02001333 struct smp_ltk *ltk;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001334 u8 authenticated;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001335 __le16 ediv;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001336 __le64 rand;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001337
1338 get_random_bytes(enc.ltk, sizeof(enc.ltk));
1339 get_random_bytes(&ediv, sizeof(ediv));
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001340 get_random_bytes(&rand, sizeof(rand));
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001341
1342 smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
1343
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001344 authenticated = hcon->sec_level == BT_SECURITY_HIGH;
Johan Hedberg524237c2014-02-22 19:06:31 +02001345 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type,
Johan Hedberg35d70272014-02-19 14:57:47 +02001346 HCI_SMP_LTK_SLAVE, authenticated, enc.ltk,
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001347 smp->enc_key_size, ediv, rand);
Johan Hedberg23d0e122014-02-19 14:57:46 +02001348 smp->slave_ltk = ltk;
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001349
Andrei Emeltchenko58115372012-03-12 12:13:06 +02001350 ident.ediv = ediv;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001351 ident.rand = rand;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001352
1353 smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident);
1354
1355 *keydist &= ~SMP_DIST_ENC_KEY;
1356 }
1357
1358 if (*keydist & SMP_DIST_ID_KEY) {
1359 struct smp_cmd_ident_addr_info addrinfo;
1360 struct smp_cmd_ident_info idinfo;
1361
Johan Hedberg863efaf2014-02-22 19:06:32 +02001362 memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk));
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001363
1364 smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo);
1365
Johan Hedberg82d4b352014-02-23 19:42:18 +02001366 /* The hci_conn contains the local identity address
1367 * after the connection has been established.
1368 *
1369 * This is true even when the connection has been
1370 * established using a resolvable random address.
1371 */
Johan Hedberg524237c2014-02-22 19:06:31 +02001372 bacpy(&addrinfo.bdaddr, &hcon->src);
Johan Hedberg82d4b352014-02-23 19:42:18 +02001373 addrinfo.addr_type = hcon->src_type;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001374
1375 smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo),
Marcel Holtmannf1560462013-10-13 05:43:25 -07001376 &addrinfo);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001377
1378 *keydist &= ~SMP_DIST_ID_KEY;
1379 }
1380
1381 if (*keydist & SMP_DIST_SIGN) {
1382 struct smp_cmd_sign_info sign;
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001383 struct smp_csrk *csrk;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001384
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001385 /* Generate a new random key */
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001386 get_random_bytes(sign.csrk, sizeof(sign.csrk));
1387
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001388 csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
1389 if (csrk) {
1390 csrk->master = 0x00;
1391 memcpy(csrk->val, sign.csrk, sizeof(csrk->val));
1392 }
1393 smp->slave_csrk = csrk;
1394
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001395 smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign);
1396
1397 *keydist &= ~SMP_DIST_SIGN;
1398 }
1399
Johan Hedbergefabba32014-02-26 23:33:44 +02001400 /* If there are still keys to be received wait for them */
1401 if ((smp->remote_key_dist & 0x07))
1402 return 0;
1403
Johan Hedberg1d98bf42014-03-24 14:39:08 +02001404 clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags);
1405 cancel_delayed_work_sync(&conn->security_timer);
Johan Hedberg4a74d652014-05-20 09:45:50 +03001406 set_bit(SMP_FLAG_COMPLETE, &smp->flags);
Johan Hedberg1d98bf42014-03-24 14:39:08 +02001407 smp_notify_keys(conn);
Johan Hedbergefabba32014-02-26 23:33:44 +02001408
Johan Hedberg1d98bf42014-03-24 14:39:08 +02001409 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001410
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001411 return 0;
1412}