blob: 72c5aa05a489537289273f599d3c8affa5649a87 [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 Hedberg533e35d2014-06-16 19:25:18 +030038enum {
39 SMP_FLAG_TK_VALID,
40 SMP_FLAG_CFM_PENDING,
41 SMP_FLAG_MITM_AUTH,
42 SMP_FLAG_COMPLETE,
43 SMP_FLAG_INITIATOR,
44};
Johan Hedberg4bc58f52014-05-20 09:45:47 +030045
46struct smp_chan {
47 struct l2cap_conn *conn;
48 u8 preq[7]; /* SMP Pairing Request */
49 u8 prsp[7]; /* SMP Pairing Response */
50 u8 prnd[16]; /* SMP Pairing Random (local) */
51 u8 rrnd[16]; /* SMP Pairing Random (remote) */
52 u8 pcnf[16]; /* SMP Pairing Confirm */
53 u8 tk[16]; /* SMP Temporary Key */
54 u8 enc_key_size;
55 u8 remote_key_dist;
56 bdaddr_t id_addr;
57 u8 id_addr_type;
58 u8 irk[16];
59 struct smp_csrk *csrk;
60 struct smp_csrk *slave_csrk;
61 struct smp_ltk *ltk;
62 struct smp_ltk *slave_ltk;
63 struct smp_irk *remote_irk;
Johan Hedberg4a74d652014-05-20 09:45:50 +030064 unsigned long flags;
Johan Hedberg4bc58f52014-05-20 09:45:47 +030065};
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
Johan Hedberg581370c2014-06-17 13:07:38 +0300390static u8 get_auth_method(struct smp_chan *smp, u8 local_io, u8 remote_io)
391{
392 /* If either side has unknown io_caps, use JUST WORKS */
393 if (local_io > SMP_IO_KEYBOARD_DISPLAY ||
394 remote_io > SMP_IO_KEYBOARD_DISPLAY)
395 return JUST_WORKS;
396
397 return gen_method[remote_io][local_io];
398}
399
Brian Gix2b64d152011-12-21 16:12:12 -0800400static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
401 u8 local_io, u8 remote_io)
402{
403 struct hci_conn *hcon = conn->hcon;
404 struct smp_chan *smp = conn->smp_chan;
405 u8 method;
406 u32 passkey = 0;
407 int ret = 0;
408
409 /* Initialize key for JUST WORKS */
410 memset(smp->tk, 0, sizeof(smp->tk));
Johan Hedberg4a74d652014-05-20 09:45:50 +0300411 clear_bit(SMP_FLAG_TK_VALID, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800412
413 BT_DBG("tk_request: auth:%d lcl:%d rem:%d", auth, local_io, remote_io);
414
415 /* If neither side wants MITM, use JUST WORKS */
Brian Gix2b64d152011-12-21 16:12:12 -0800416 /* Otherwise, look up method from the table */
Johan Hedberg581370c2014-06-17 13:07:38 +0300417 if (!(auth & SMP_AUTH_MITM))
Brian Gix2b64d152011-12-21 16:12:12 -0800418 method = JUST_WORKS;
419 else
Johan Hedberg581370c2014-06-17 13:07:38 +0300420 method = get_auth_method(smp, local_io, remote_io);
Brian Gix2b64d152011-12-21 16:12:12 -0800421
422 /* If not bonding, don't ask user to confirm a Zero TK */
423 if (!(auth & SMP_AUTH_BONDING) && method == JUST_CFM)
424 method = JUST_WORKS;
425
Johan Hedberga82505c2014-03-24 14:39:07 +0200426 /* Don't confirm locally initiated pairing attempts */
Johan Hedberg4a74d652014-05-20 09:45:50 +0300427 if (method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR, &smp->flags))
Johan Hedberga82505c2014-03-24 14:39:07 +0200428 method = JUST_WORKS;
429
Brian Gix2b64d152011-12-21 16:12:12 -0800430 /* If Just Works, Continue with Zero TK */
431 if (method == JUST_WORKS) {
Johan Hedberg4a74d652014-05-20 09:45:50 +0300432 set_bit(SMP_FLAG_TK_VALID, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800433 return 0;
434 }
435
436 /* Not Just Works/Confirm results in MITM Authentication */
437 if (method != JUST_CFM)
Johan Hedberg4a74d652014-05-20 09:45:50 +0300438 set_bit(SMP_FLAG_MITM_AUTH, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800439
440 /* If both devices have Keyoard-Display I/O, the master
441 * Confirms and the slave Enters the passkey.
442 */
443 if (method == OVERLAP) {
444 if (hcon->link_mode & HCI_LM_MASTER)
445 method = CFM_PASSKEY;
446 else
447 method = REQ_PASSKEY;
448 }
449
Johan Hedberg01ad34d2014-03-19 14:14:53 +0200450 /* Generate random passkey. */
Brian Gix2b64d152011-12-21 16:12:12 -0800451 if (method == CFM_PASSKEY) {
Johan Hedberg943a7322014-03-18 12:58:24 +0200452 memset(smp->tk, 0, sizeof(smp->tk));
Brian Gix2b64d152011-12-21 16:12:12 -0800453 get_random_bytes(&passkey, sizeof(passkey));
454 passkey %= 1000000;
Johan Hedberg943a7322014-03-18 12:58:24 +0200455 put_unaligned_le32(passkey, smp->tk);
Brian Gix2b64d152011-12-21 16:12:12 -0800456 BT_DBG("PassKey: %d", passkey);
Johan Hedberg4a74d652014-05-20 09:45:50 +0300457 set_bit(SMP_FLAG_TK_VALID, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800458 }
459
460 hci_dev_lock(hcon->hdev);
461
462 if (method == REQ_PASSKEY)
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700463 ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200464 hcon->type, hcon->dst_type);
Johan Hedberg4eb65e62014-03-24 14:39:05 +0200465 else if (method == JUST_CFM)
466 ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
467 hcon->type, hcon->dst_type,
468 passkey, 1);
Brian Gix2b64d152011-12-21 16:12:12 -0800469 else
Johan Hedberg01ad34d2014-03-19 14:14:53 +0200470 ret = mgmt_user_passkey_notify(hcon->hdev, &hcon->dst,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200471 hcon->type, hcon->dst_type,
Johan Hedberg39adbff2014-03-20 08:18:14 +0200472 passkey, 0);
Brian Gix2b64d152011-12-21 16:12:12 -0800473
474 hci_dev_unlock(hcon->hdev);
475
476 return ret;
477}
478
Johan Hedberg1cc61142014-05-20 09:45:52 +0300479static u8 smp_confirm(struct smp_chan *smp)
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300480{
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300481 struct l2cap_conn *conn = smp->conn;
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200482 struct hci_dev *hdev = conn->hcon->hdev;
483 struct crypto_blkcipher *tfm = hdev->tfm_aes;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300484 struct smp_cmd_pairing_confirm cp;
485 int ret;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300486
487 BT_DBG("conn %p", conn);
488
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200489 /* Prevent mutual access to hdev->tfm_aes */
490 hci_dev_lock(hdev);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300491
Johan Hedbergb1cd5fd2014-02-28 12:54:17 +0200492 ret = smp_c1(tfm, smp->tk, smp->prnd, smp->preq, smp->prsp,
493 conn->hcon->init_addr_type, &conn->hcon->init_addr,
Johan Hedberg943a7322014-03-18 12:58:24 +0200494 conn->hcon->resp_addr_type, &conn->hcon->resp_addr,
495 cp.confirm_val);
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200496
497 hci_dev_unlock(hdev);
498
Johan Hedberg1cc61142014-05-20 09:45:52 +0300499 if (ret)
500 return SMP_UNSPECIFIED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300501
Johan Hedberg4a74d652014-05-20 09:45:50 +0300502 clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800503
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300504 smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
505
Johan Hedberg1cc61142014-05-20 09:45:52 +0300506 return 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300507}
508
Johan Hedberg861580a2014-05-20 09:45:51 +0300509static u8 smp_random(struct smp_chan *smp)
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300510{
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300511 struct l2cap_conn *conn = smp->conn;
512 struct hci_conn *hcon = conn->hcon;
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200513 struct hci_dev *hdev = hcon->hdev;
514 struct crypto_blkcipher *tfm = hdev->tfm_aes;
Johan Hedberg861580a2014-05-20 09:45:51 +0300515 u8 confirm[16];
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300516 int ret;
517
Johan Hedberg861580a2014-05-20 09:45:51 +0300518 if (IS_ERR_OR_NULL(tfm))
519 return SMP_UNSPECIFIED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300520
521 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
522
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200523 /* Prevent mutual access to hdev->tfm_aes */
524 hci_dev_lock(hdev);
525
Johan Hedbergb1cd5fd2014-02-28 12:54:17 +0200526 ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp,
527 hcon->init_addr_type, &hcon->init_addr,
Johan Hedberg943a7322014-03-18 12:58:24 +0200528 hcon->resp_addr_type, &hcon->resp_addr, confirm);
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200529
530 hci_dev_unlock(hdev);
531
Johan Hedberg861580a2014-05-20 09:45:51 +0300532 if (ret)
533 return SMP_UNSPECIFIED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300534
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300535 if (memcmp(smp->pcnf, confirm, sizeof(smp->pcnf)) != 0) {
536 BT_ERR("Pairing failed (confirmation values mismatch)");
Johan Hedberg861580a2014-05-20 09:45:51 +0300537 return SMP_CONFIRM_FAILED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300538 }
539
540 if (hcon->out) {
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -0800541 u8 stk[16];
542 __le64 rand = 0;
543 __le16 ediv = 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300544
Johan Hedberg943a7322014-03-18 12:58:24 +0200545 smp_s1(tfm, smp->tk, smp->rrnd, smp->prnd, stk);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300546
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300547 memset(stk + smp->enc_key_size, 0,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300548 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300549
Johan Hedberg861580a2014-05-20 09:45:51 +0300550 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
551 return SMP_UNSPECIFIED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300552
553 hci_le_start_enc(hcon, ediv, rand, stk);
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300554 hcon->enc_key_size = smp->enc_key_size;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300555 } else {
Johan Hedbergfff34902014-06-10 15:19:50 +0300556 u8 stk[16], auth;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -0800557 __le64 rand = 0;
558 __le16 ediv = 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300559
Johan Hedberg943a7322014-03-18 12:58:24 +0200560 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
561 smp->prnd);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300562
Johan Hedberg943a7322014-03-18 12:58:24 +0200563 smp_s1(tfm, smp->tk, smp->prnd, smp->rrnd, stk);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300564
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300565 memset(stk + smp->enc_key_size, 0,
Marcel Holtmannf1560462013-10-13 05:43:25 -0700566 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300567
Johan Hedbergfff34902014-06-10 15:19:50 +0300568 if (hcon->pending_sec_level == BT_SECURITY_HIGH)
569 auth = 1;
570 else
571 auth = 0;
572
Johan Hedberg7d5843b2014-06-16 19:25:15 +0300573 /* Even though there's no _SLAVE suffix this is the
574 * slave STK we're adding for later lookup (the master
575 * STK never needs to be stored).
576 */
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700577 hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
Johan Hedberg2ceba532014-06-16 19:25:16 +0300578 SMP_STK, auth, stk, smp->enc_key_size, ediv, rand);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300579 }
580
Johan Hedberg861580a2014-05-20 09:45:51 +0300581 return 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300582}
583
584static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
585{
586 struct smp_chan *smp;
587
Marcel Holtmannf1560462013-10-13 05:43:25 -0700588 smp = kzalloc(sizeof(*smp), GFP_ATOMIC);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300589 if (!smp)
590 return NULL;
591
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300592 smp->conn = conn;
593 conn->smp_chan = smp;
Brian Gix2b64d152011-12-21 16:12:12 -0800594 conn->hcon->smp_conn = conn;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300595
596 hci_conn_hold(conn->hcon);
597
598 return smp;
599}
600
601void smp_chan_destroy(struct l2cap_conn *conn)
602{
Brian Gixc8eb9692011-11-23 08:28:35 -0800603 struct smp_chan *smp = conn->smp_chan;
Johan Hedbergf4a407b2014-02-18 21:41:34 +0200604 bool complete;
Brian Gixc8eb9692011-11-23 08:28:35 -0800605
Vinicius Costa Gomesf1c09c02012-02-01 18:27:56 -0300606 BUG_ON(!smp);
Brian Gixc8eb9692011-11-23 08:28:35 -0800607
Johan Hedberg4a74d652014-05-20 09:45:50 +0300608 complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags);
Johan Hedbergf4a407b2014-02-18 21:41:34 +0200609 mgmt_smp_complete(conn->hcon, complete);
610
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -0700611 kfree(smp->csrk);
612 kfree(smp->slave_csrk);
613
Johan Hedberg759331d2014-02-28 10:10:16 +0200614 /* If pairing failed clean up any keys we might have */
615 if (!complete) {
616 if (smp->ltk) {
617 list_del(&smp->ltk->list);
618 kfree(smp->ltk);
619 }
620
621 if (smp->slave_ltk) {
622 list_del(&smp->slave_ltk->list);
623 kfree(smp->slave_ltk);
624 }
625
626 if (smp->remote_irk) {
627 list_del(&smp->remote_irk->list);
628 kfree(smp->remote_irk);
629 }
630 }
631
Brian Gixc8eb9692011-11-23 08:28:35 -0800632 kfree(smp);
633 conn->smp_chan = NULL;
Brian Gix2b64d152011-12-21 16:12:12 -0800634 conn->hcon->smp_conn = NULL;
David Herrmann76a68ba2013-04-06 20:28:37 +0200635 hci_conn_drop(conn->hcon);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300636}
637
Brian Gix2b64d152011-12-21 16:12:12 -0800638int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
639{
640 struct l2cap_conn *conn = hcon->smp_conn;
641 struct smp_chan *smp;
642 u32 value;
Brian Gix2b64d152011-12-21 16:12:12 -0800643
644 BT_DBG("");
645
646 if (!conn)
647 return -ENOTCONN;
648
649 smp = conn->smp_chan;
650
651 switch (mgmt_op) {
652 case MGMT_OP_USER_PASSKEY_REPLY:
653 value = le32_to_cpu(passkey);
Johan Hedberg943a7322014-03-18 12:58:24 +0200654 memset(smp->tk, 0, sizeof(smp->tk));
Brian Gix2b64d152011-12-21 16:12:12 -0800655 BT_DBG("PassKey: %d", value);
Johan Hedberg943a7322014-03-18 12:58:24 +0200656 put_unaligned_le32(value, smp->tk);
Brian Gix2b64d152011-12-21 16:12:12 -0800657 /* Fall Through */
658 case MGMT_OP_USER_CONFIRM_REPLY:
Johan Hedberg4a74d652014-05-20 09:45:50 +0300659 set_bit(SMP_FLAG_TK_VALID, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800660 break;
661 case MGMT_OP_USER_PASSKEY_NEG_REPLY:
662 case MGMT_OP_USER_CONFIRM_NEG_REPLY:
Johan Hedberg84794e12013-11-06 11:24:57 +0200663 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
Brian Gix2b64d152011-12-21 16:12:12 -0800664 return 0;
665 default:
Johan Hedberg84794e12013-11-06 11:24:57 +0200666 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
Brian Gix2b64d152011-12-21 16:12:12 -0800667 return -EOPNOTSUPP;
668 }
669
670 /* If it is our turn to send Pairing Confirm, do so now */
Johan Hedberg1cc61142014-05-20 09:45:52 +0300671 if (test_bit(SMP_FLAG_CFM_PENDING, &smp->flags)) {
672 u8 rsp = smp_confirm(smp);
673 if (rsp)
674 smp_failure(conn, rsp);
675 }
Brian Gix2b64d152011-12-21 16:12:12 -0800676
677 return 0;
678}
679
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300680static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300681{
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300682 struct smp_cmd_pairing rsp, *req = (void *) skb->data;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300683 struct smp_chan *smp;
Johan Hedbergc7262e72014-06-17 13:07:37 +0300684 u8 key_size, auth, sec_level;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300685 int ret;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300686
687 BT_DBG("conn %p", conn);
688
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200689 if (skb->len < sizeof(*req))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300690 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200691
Brian Gix2b64d152011-12-21 16:12:12 -0800692 if (conn->hcon->link_mode & HCI_LM_MASTER)
693 return SMP_CMD_NOTSUPP;
694
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200695 if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags))
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300696 smp = smp_chan_create(conn);
Andrei Emeltchenkod08fd0e2012-07-19 17:03:43 +0300697 else
698 smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300699
Andrei Emeltchenkod08fd0e2012-07-19 17:03:43 +0300700 if (!smp)
701 return SMP_UNSPECIFIED;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300702
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300703 smp->preq[0] = SMP_CMD_PAIRING_REQ;
704 memcpy(&smp->preq[1], req, sizeof(*req));
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300705 skb_pull(skb, sizeof(*req));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300706
Brian Gix2b64d152011-12-21 16:12:12 -0800707 /* We didn't start the pairing, so match remote */
Johan Hedberg1ef35822014-05-20 09:45:48 +0300708 auth = req->auth_req;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300709
Johan Hedbergc7262e72014-06-17 13:07:37 +0300710 sec_level = authreq_to_seclevel(auth);
711 if (sec_level > conn->hcon->pending_sec_level)
712 conn->hcon->pending_sec_level = sec_level;
Ido Yarivfdde0a22012-03-05 20:09:38 +0200713
Johan Hedberg2ed8f652014-06-17 13:07:39 +0300714 /* If we need MITM check that it can be acheived */
715 if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
716 u8 method;
717
718 method = get_auth_method(smp, conn->hcon->io_capability,
719 req->io_capability);
720 if (method == JUST_WORKS || method == JUST_CFM)
721 return SMP_AUTH_REQUIREMENTS;
722 }
723
Brian Gix2b64d152011-12-21 16:12:12 -0800724 build_pairing_cmd(conn, req, &rsp, auth);
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300725
726 key_size = min(req->max_key_size, rsp.max_key_size);
727 if (check_enc_key_size(conn, key_size))
728 return SMP_ENC_KEY_SIZE;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300729
Johan Hedberge84a6b12013-12-02 10:49:03 +0200730 get_random_bytes(smp->prnd, sizeof(smp->prnd));
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300731
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300732 smp->prsp[0] = SMP_CMD_PAIRING_RSP;
733 memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300734
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300735 smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300736
Brian Gix2b64d152011-12-21 16:12:12 -0800737 /* Request setup of TK */
738 ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability);
739 if (ret)
740 return SMP_UNSPECIFIED;
741
Johan Hedberg4a74d652014-05-20 09:45:50 +0300742 clear_bit(SMP_FLAG_INITIATOR, &smp->flags);
Johan Hedbergedca7922014-03-24 15:54:11 +0200743
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300744 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300745}
746
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300747static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300748{
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300749 struct smp_cmd_pairing *req, *rsp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300750 struct smp_chan *smp = conn->smp_chan;
Brian Gix2b64d152011-12-21 16:12:12 -0800751 u8 key_size, auth = SMP_AUTH_NONE;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300752 int ret;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300753
754 BT_DBG("conn %p", conn);
755
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200756 if (skb->len < sizeof(*rsp))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300757 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200758
Brian Gix2b64d152011-12-21 16:12:12 -0800759 if (!(conn->hcon->link_mode & HCI_LM_MASTER))
760 return SMP_CMD_NOTSUPP;
761
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300762 skb_pull(skb, sizeof(*rsp));
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300763
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300764 req = (void *) &smp->preq[1];
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300765
766 key_size = min(req->max_key_size, rsp->max_key_size);
767 if (check_enc_key_size(conn, key_size))
768 return SMP_ENC_KEY_SIZE;
769
Johan Hedberg2ed8f652014-06-17 13:07:39 +0300770 /* If we need MITM check that it can be acheived */
771 if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
772 u8 method;
773
774 method = get_auth_method(smp, req->io_capability,
775 rsp->io_capability);
776 if (method == JUST_WORKS || method == JUST_CFM)
777 return SMP_AUTH_REQUIREMENTS;
778 }
779
Johan Hedberge84a6b12013-12-02 10:49:03 +0200780 get_random_bytes(smp->prnd, sizeof(smp->prnd));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300781
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300782 smp->prsp[0] = SMP_CMD_PAIRING_RSP;
783 memcpy(&smp->prsp[1], rsp, sizeof(*rsp));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300784
Johan Hedbergfdcc4be2014-03-14 10:53:50 +0200785 /* Update remote key distribution in case the remote cleared
786 * some bits that we had enabled in our request.
787 */
788 smp->remote_key_dist &= rsp->resp_key_dist;
789
Brian Gix2b64d152011-12-21 16:12:12 -0800790 if ((req->auth_req & SMP_AUTH_BONDING) &&
Marcel Holtmannf1560462013-10-13 05:43:25 -0700791 (rsp->auth_req & SMP_AUTH_BONDING))
Brian Gix2b64d152011-12-21 16:12:12 -0800792 auth = SMP_AUTH_BONDING;
793
794 auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM;
795
Johan Hedberg476585e2012-06-06 18:54:15 +0800796 ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability);
Brian Gix2b64d152011-12-21 16:12:12 -0800797 if (ret)
798 return SMP_UNSPECIFIED;
799
Johan Hedberg4a74d652014-05-20 09:45:50 +0300800 set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800801
802 /* Can't compose response until we have been confirmed */
Johan Hedberg4a74d652014-05-20 09:45:50 +0300803 if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
Johan Hedberg1cc61142014-05-20 09:45:52 +0300804 return smp_confirm(smp);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300805
806 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300807}
808
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300809static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300810{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300811 struct smp_chan *smp = conn->smp_chan;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300812
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300813 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
814
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200815 if (skb->len < sizeof(smp->pcnf))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300816 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200817
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300818 memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf));
819 skb_pull(skb, sizeof(smp->pcnf));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300820
Johan Hedberg943a7322014-03-18 12:58:24 +0200821 if (conn->hcon->out)
822 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
823 smp->prnd);
Johan Hedberg4a74d652014-05-20 09:45:50 +0300824 else if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
Johan Hedberg1cc61142014-05-20 09:45:52 +0300825 return smp_confirm(smp);
Johan Hedberg943a7322014-03-18 12:58:24 +0200826 else
Johan Hedberg4a74d652014-05-20 09:45:50 +0300827 set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300828
829 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300830}
831
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300832static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300833{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300834 struct smp_chan *smp = conn->smp_chan;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300835
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300836 BT_DBG("conn %p", conn);
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300837
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200838 if (skb->len < sizeof(smp->rrnd))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300839 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200840
Johan Hedberg943a7322014-03-18 12:58:24 +0200841 memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd));
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300842 skb_pull(skb, sizeof(smp->rrnd));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300843
Johan Hedberg861580a2014-05-20 09:45:51 +0300844 return smp_random(smp);
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300845}
846
Johan Hedberg4dab7862012-06-07 14:58:37 +0800847static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300848{
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300849 struct smp_ltk *key;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300850 struct hci_conn *hcon = conn->hcon;
851
Johan Hedberg98a0b842014-01-30 19:40:00 -0800852 key = hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type,
853 hcon->out);
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300854 if (!key)
855 return 0;
856
Johan Hedberg4dab7862012-06-07 14:58:37 +0800857 if (sec_level > BT_SECURITY_MEDIUM && !key->authenticated)
858 return 0;
859
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200860 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300861 return 1;
862
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300863 hci_le_start_enc(hcon, key->ediv, key->rand, key->val);
864 hcon->enc_key_size = key->enc_size;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300865
866 return 1;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300867}
Marcel Holtmannf1560462013-10-13 05:43:25 -0700868
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300869static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300870{
871 struct smp_cmd_security_req *rp = (void *) skb->data;
872 struct smp_cmd_pairing cp;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300873 struct hci_conn *hcon = conn->hcon;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300874 struct smp_chan *smp;
Johan Hedbergc7262e72014-06-17 13:07:37 +0300875 u8 sec_level;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300876
877 BT_DBG("conn %p", conn);
878
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200879 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300880 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200881
Johan Hedberg86ca9ea2013-11-05 11:30:39 +0200882 if (!(conn->hcon->link_mode & HCI_LM_MASTER))
883 return SMP_CMD_NOTSUPP;
884
Johan Hedbergc7262e72014-06-17 13:07:37 +0300885 sec_level = authreq_to_seclevel(rp->auth_req);
886 if (sec_level > hcon->pending_sec_level)
887 hcon->pending_sec_level = sec_level;
Vinicius Costa Gomesfeb45eb2011-08-25 20:02:35 -0300888
Johan Hedberg4dab7862012-06-07 14:58:37 +0800889 if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300890 return 0;
891
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200892 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300893 return 0;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300894
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300895 smp = smp_chan_create(conn);
Johan Hedbergc29d2442014-06-16 19:25:14 +0300896 if (!smp)
897 return SMP_UNSPECIFIED;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300898
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300899 skb_pull(skb, sizeof(*rp));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300900
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300901 memset(&cp, 0, sizeof(cp));
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300902 build_pairing_cmd(conn, &cp, NULL, rp->auth_req);
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300903
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300904 smp->preq[0] = SMP_CMD_PAIRING_REQ;
905 memcpy(&smp->preq[1], &cp, sizeof(cp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300906
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300907 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300908
Johan Hedberg4a74d652014-05-20 09:45:50 +0300909 clear_bit(SMP_FLAG_INITIATOR, &smp->flags);
Johan Hedbergedca7922014-03-24 15:54:11 +0200910
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300911 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300912}
913
Johan Hedbergad32a2f2013-05-14 18:05:12 +0300914bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level)
915{
916 if (sec_level == BT_SECURITY_LOW)
917 return true;
918
919 if (hcon->sec_level >= sec_level)
920 return true;
921
922 return false;
923}
924
Vinicius Costa Gomescc110922012-08-23 21:32:43 -0300925int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300926{
Vinicius Costa Gomescc110922012-08-23 21:32:43 -0300927 struct l2cap_conn *conn = hcon->l2cap_data;
Johan Hedberg0a66cf22014-03-24 14:39:03 +0200928 struct smp_chan *smp;
Brian Gix2b64d152011-12-21 16:12:12 -0800929 __u8 authreq;
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300930
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -0300931 BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
932
Johan Hedberg0a66cf22014-03-24 14:39:03 +0200933 /* This may be NULL if there's an unexpected disconnection */
934 if (!conn)
935 return 1;
936
Johan Hedberg757aee02013-04-24 13:05:32 +0300937 if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags))
Andre Guedes2e65c9d2011-06-30 19:20:56 -0300938 return 1;
939
Johan Hedbergad32a2f2013-05-14 18:05:12 +0300940 if (smp_sufficient_security(hcon, sec_level))
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300941 return 1;
942
Johan Hedbergc7262e72014-06-17 13:07:37 +0300943 if (sec_level > hcon->pending_sec_level)
944 hcon->pending_sec_level = sec_level;
945
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300946 if (hcon->link_mode & HCI_LM_MASTER)
Johan Hedbergc7262e72014-06-17 13:07:37 +0300947 if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
948 return 0;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300949
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200950 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300951 return 0;
952
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300953 smp = smp_chan_create(conn);
Brian Gix2b64d152011-12-21 16:12:12 -0800954 if (!smp)
955 return 1;
956
957 authreq = seclevel_to_authreq(sec_level);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300958
Johan Hedberg79897d22014-06-01 09:45:24 +0300959 /* Require MITM if IO Capability allows or the security level
960 * requires it.
Johan Hedberg2e233642014-03-18 15:42:30 +0200961 */
Johan Hedberg79897d22014-06-01 09:45:24 +0300962 if (hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT ||
Johan Hedbergc7262e72014-06-17 13:07:37 +0300963 hcon->pending_sec_level > BT_SECURITY_MEDIUM)
Johan Hedberg2e233642014-03-18 15:42:30 +0200964 authreq |= SMP_AUTH_MITM;
965
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300966 if (hcon->link_mode & HCI_LM_MASTER) {
967 struct smp_cmd_pairing cp;
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300968
Brian Gix2b64d152011-12-21 16:12:12 -0800969 build_pairing_cmd(conn, &cp, NULL, authreq);
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300970 smp->preq[0] = SMP_CMD_PAIRING_REQ;
971 memcpy(&smp->preq[1], &cp, sizeof(cp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300972
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300973 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
974 } else {
975 struct smp_cmd_security_req cp;
Brian Gix2b64d152011-12-21 16:12:12 -0800976 cp.auth_req = authreq;
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300977 smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
978 }
979
Johan Hedberg4a74d652014-05-20 09:45:50 +0300980 set_bit(SMP_FLAG_INITIATOR, &smp->flags);
Johan Hedbergedca7922014-03-24 15:54:11 +0200981
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300982 return 0;
983}
984
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300985static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
986{
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300987 struct smp_cmd_encrypt_info *rp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300988 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300989
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200990 BT_DBG("conn %p", conn);
991
992 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300993 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200994
Johan Hedberg6131ddc2014-02-18 10:19:37 +0200995 /* Ignore this PDU if it wasn't requested */
996 if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
997 return 0;
998
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300999 skb_pull(skb, sizeof(*rp));
1000
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001001 memcpy(smp->tk, rp->ltk, sizeof(smp->tk));
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001002
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001003 return 0;
1004}
1005
1006static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
1007{
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001008 struct smp_cmd_master_ident *rp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001009 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001010 struct hci_dev *hdev = conn->hcon->hdev;
1011 struct hci_conn *hcon = conn->hcon;
Johan Hedberg23d0e122014-02-19 14:57:46 +02001012 struct smp_ltk *ltk;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001013 u8 authenticated;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001014
Johan Hedbergc46b98b2014-02-18 10:19:29 +02001015 BT_DBG("conn %p", conn);
1016
1017 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001018 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +02001019
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001020 /* Ignore this PDU if it wasn't requested */
1021 if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
1022 return 0;
1023
Johan Hedberg9747a9f2014-02-26 23:33:43 +02001024 /* Mark the information as received */
1025 smp->remote_key_dist &= ~SMP_DIST_ENC_KEY;
1026
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001027 skb_pull(skb, sizeof(*rp));
1028
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001029 hci_dev_lock(hdev);
Marcel Holtmannce39fb42013-10-13 02:23:39 -07001030 authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
Johan Hedberg2ceba532014-06-16 19:25:16 +03001031 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, SMP_LTK,
Johan Hedberg23d0e122014-02-19 14:57:46 +02001032 authenticated, smp->tk, smp->enc_key_size,
1033 rp->ediv, rp->rand);
1034 smp->ltk = ltk;
Johan Hedbergfd349c02014-02-18 10:19:36 +02001035 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001036 smp_distribute_keys(conn);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001037 hci_dev_unlock(hdev);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001038
1039 return 0;
1040}
1041
Johan Hedbergfd349c02014-02-18 10:19:36 +02001042static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
1043{
1044 struct smp_cmd_ident_info *info = (void *) skb->data;
1045 struct smp_chan *smp = conn->smp_chan;
1046
1047 BT_DBG("");
1048
1049 if (skb->len < sizeof(*info))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001050 return SMP_INVALID_PARAMS;
Johan Hedbergfd349c02014-02-18 10:19:36 +02001051
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001052 /* Ignore this PDU if it wasn't requested */
1053 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
1054 return 0;
1055
Johan Hedbergfd349c02014-02-18 10:19:36 +02001056 skb_pull(skb, sizeof(*info));
1057
1058 memcpy(smp->irk, info->irk, 16);
1059
1060 return 0;
1061}
1062
1063static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
1064 struct sk_buff *skb)
1065{
1066 struct smp_cmd_ident_addr_info *info = (void *) skb->data;
1067 struct smp_chan *smp = conn->smp_chan;
1068 struct hci_conn *hcon = conn->hcon;
1069 bdaddr_t rpa;
1070
1071 BT_DBG("");
1072
1073 if (skb->len < sizeof(*info))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001074 return SMP_INVALID_PARAMS;
Johan Hedbergfd349c02014-02-18 10:19:36 +02001075
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001076 /* Ignore this PDU if it wasn't requested */
1077 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
1078 return 0;
1079
Johan Hedberg9747a9f2014-02-26 23:33:43 +02001080 /* Mark the information as received */
1081 smp->remote_key_dist &= ~SMP_DIST_ID_KEY;
1082
Johan Hedbergfd349c02014-02-18 10:19:36 +02001083 skb_pull(skb, sizeof(*info));
1084
Johan Hedberga9a58f82014-02-25 22:24:37 +02001085 /* Strictly speaking the Core Specification (4.1) allows sending
1086 * an empty address which would force us to rely on just the IRK
1087 * as "identity information". However, since such
1088 * implementations are not known of and in order to not over
1089 * complicate our implementation, simply pretend that we never
1090 * received an IRK for such a device.
1091 */
1092 if (!bacmp(&info->bdaddr, BDADDR_ANY)) {
1093 BT_ERR("Ignoring IRK with no identity address");
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001094 smp_distribute_keys(conn);
Johan Hedberga9a58f82014-02-25 22:24:37 +02001095 return 0;
1096 }
1097
Johan Hedbergfd349c02014-02-18 10:19:36 +02001098 bacpy(&smp->id_addr, &info->bdaddr);
1099 smp->id_addr_type = info->addr_type;
1100
1101 if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type))
1102 bacpy(&rpa, &hcon->dst);
1103 else
1104 bacpy(&rpa, BDADDR_ANY);
1105
Johan Hedberg23d0e122014-02-19 14:57:46 +02001106 smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
1107 smp->id_addr_type, smp->irk, &rpa);
Johan Hedbergfd349c02014-02-18 10:19:36 +02001108
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001109 smp_distribute_keys(conn);
Johan Hedbergfd349c02014-02-18 10:19:36 +02001110
1111 return 0;
1112}
1113
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001114static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)
1115{
1116 struct smp_cmd_sign_info *rp = (void *) skb->data;
1117 struct smp_chan *smp = conn->smp_chan;
1118 struct hci_dev *hdev = conn->hcon->hdev;
1119 struct smp_csrk *csrk;
1120
1121 BT_DBG("conn %p", conn);
1122
1123 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001124 return SMP_INVALID_PARAMS;
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001125
1126 /* Ignore this PDU if it wasn't requested */
1127 if (!(smp->remote_key_dist & SMP_DIST_SIGN))
1128 return 0;
1129
1130 /* Mark the information as received */
1131 smp->remote_key_dist &= ~SMP_DIST_SIGN;
1132
1133 skb_pull(skb, sizeof(*rp));
1134
1135 hci_dev_lock(hdev);
1136 csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
1137 if (csrk) {
1138 csrk->master = 0x01;
1139 memcpy(csrk->val, rp->csrk, sizeof(csrk->val));
1140 }
1141 smp->csrk = csrk;
1142 if (!(smp->remote_key_dist & SMP_DIST_SIGN))
1143 smp_distribute_keys(conn);
1144 hci_dev_unlock(hdev);
1145
1146 return 0;
1147}
1148
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001149int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
1150{
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001151 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann92381f52013-10-03 01:23:08 -07001152 __u8 code, reason;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001153 int err = 0;
1154
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001155 if (hcon->type != LE_LINK) {
1156 kfree_skb(skb);
Johan Hedberg34327112013-10-16 11:37:01 +03001157 return 0;
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001158 }
1159
Marcel Holtmann92381f52013-10-03 01:23:08 -07001160 if (skb->len < 1) {
1161 kfree_skb(skb);
1162 return -EILSEQ;
1163 }
1164
Marcel Holtmann06ae3312013-10-18 03:43:00 -07001165 if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) {
Andre Guedes2e65c9d2011-06-30 19:20:56 -03001166 err = -ENOTSUPP;
1167 reason = SMP_PAIRING_NOTSUPP;
1168 goto done;
1169 }
1170
Marcel Holtmann92381f52013-10-03 01:23:08 -07001171 code = skb->data[0];
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001172 skb_pull(skb, sizeof(code));
1173
Johan Hedberg8cf9fa12013-01-29 10:44:23 -06001174 /*
1175 * The SMP context must be initialized for all other PDUs except
1176 * pairing and security requests. If we get any other PDU when
1177 * not initialized simply disconnect (done if this function
1178 * returns an error).
1179 */
1180 if (code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ &&
1181 !conn->smp_chan) {
1182 BT_ERR("Unexpected SMP command 0x%02x. Disconnecting.", code);
1183 kfree_skb(skb);
1184 return -ENOTSUPP;
1185 }
1186
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001187 switch (code) {
1188 case SMP_CMD_PAIRING_REQ:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001189 reason = smp_cmd_pairing_req(conn, skb);
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001190 break;
1191
1192 case SMP_CMD_PAIRING_FAIL:
Johan Hedberg84794e12013-11-06 11:24:57 +02001193 smp_failure(conn, 0);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001194 reason = 0;
1195 err = -EPERM;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001196 break;
1197
1198 case SMP_CMD_PAIRING_RSP:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001199 reason = smp_cmd_pairing_rsp(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001200 break;
1201
1202 case SMP_CMD_SECURITY_REQ:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001203 reason = smp_cmd_security_req(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001204 break;
1205
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001206 case SMP_CMD_PAIRING_CONFIRM:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001207 reason = smp_cmd_pairing_confirm(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001208 break;
1209
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001210 case SMP_CMD_PAIRING_RANDOM:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001211 reason = smp_cmd_pairing_random(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001212 break;
1213
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001214 case SMP_CMD_ENCRYPT_INFO:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001215 reason = smp_cmd_encrypt_info(conn, skb);
1216 break;
1217
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001218 case SMP_CMD_MASTER_IDENT:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001219 reason = smp_cmd_master_ident(conn, skb);
1220 break;
1221
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001222 case SMP_CMD_IDENT_INFO:
Johan Hedbergfd349c02014-02-18 10:19:36 +02001223 reason = smp_cmd_ident_info(conn, skb);
1224 break;
1225
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001226 case SMP_CMD_IDENT_ADDR_INFO:
Johan Hedbergfd349c02014-02-18 10:19:36 +02001227 reason = smp_cmd_ident_addr_info(conn, skb);
1228 break;
1229
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001230 case SMP_CMD_SIGN_INFO:
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001231 reason = smp_cmd_sign_info(conn, skb);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001232 break;
1233
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001234 default:
1235 BT_DBG("Unknown command code 0x%2.2x", code);
1236
1237 reason = SMP_CMD_NOTSUPP;
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -03001238 err = -EOPNOTSUPP;
1239 goto done;
1240 }
1241
1242done:
1243 if (reason)
Johan Hedberg84794e12013-11-06 11:24:57 +02001244 smp_failure(conn, reason);
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001245
1246 kfree_skb(skb);
1247 return err;
1248}
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001249
Johan Hedberg35d70272014-02-19 14:57:47 +02001250static void smp_notify_keys(struct l2cap_conn *conn)
1251{
1252 struct smp_chan *smp = conn->smp_chan;
1253 struct hci_conn *hcon = conn->hcon;
1254 struct hci_dev *hdev = hcon->hdev;
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001255 struct smp_cmd_pairing *req = (void *) &smp->preq[1];
1256 struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1];
1257 bool persistent;
Johan Hedberg35d70272014-02-19 14:57:47 +02001258
Johan Hedberg61b1a7f2014-03-20 12:54:16 +02001259 if (smp->remote_irk) {
Johan Hedberg95fbac82014-02-19 15:18:31 +02001260 mgmt_new_irk(hdev, smp->remote_irk);
Johan Hedberg61b1a7f2014-03-20 12:54:16 +02001261 /* Now that user space can be considered to know the
1262 * identity address track the connection based on it
1263 * from now on.
1264 */
1265 bacpy(&hcon->dst, &smp->remote_irk->bdaddr);
1266 hcon->dst_type = smp->remote_irk->addr_type;
1267 l2cap_conn_update_id_addr(hcon);
1268 }
Johan Hedberg95fbac82014-02-19 15:18:31 +02001269
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001270 /* The LTKs and CSRKs should be persistent only if both sides
1271 * had the bonding bit set in their authentication requests.
1272 */
1273 persistent = !!((req->auth_req & rsp->auth_req) & SMP_AUTH_BONDING);
1274
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001275 if (smp->csrk) {
1276 smp->csrk->bdaddr_type = hcon->dst_type;
1277 bacpy(&smp->csrk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001278 mgmt_new_csrk(hdev, smp->csrk, persistent);
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001279 }
1280
1281 if (smp->slave_csrk) {
1282 smp->slave_csrk->bdaddr_type = hcon->dst_type;
1283 bacpy(&smp->slave_csrk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001284 mgmt_new_csrk(hdev, smp->slave_csrk, persistent);
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001285 }
1286
Johan Hedberg35d70272014-02-19 14:57:47 +02001287 if (smp->ltk) {
1288 smp->ltk->bdaddr_type = hcon->dst_type;
1289 bacpy(&smp->ltk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001290 mgmt_new_ltk(hdev, smp->ltk, persistent);
Johan Hedberg35d70272014-02-19 14:57:47 +02001291 }
1292
1293 if (smp->slave_ltk) {
1294 smp->slave_ltk->bdaddr_type = hcon->dst_type;
1295 bacpy(&smp->slave_ltk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001296 mgmt_new_ltk(hdev, smp->slave_ltk, persistent);
Johan Hedberg35d70272014-02-19 14:57:47 +02001297 }
1298}
1299
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001300int smp_distribute_keys(struct l2cap_conn *conn)
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001301{
1302 struct smp_cmd_pairing *req, *rsp;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001303 struct smp_chan *smp = conn->smp_chan;
Johan Hedberg524237c2014-02-22 19:06:31 +02001304 struct hci_conn *hcon = conn->hcon;
1305 struct hci_dev *hdev = hcon->hdev;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001306 __u8 *keydist;
1307
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001308 BT_DBG("conn %p", conn);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001309
Johan Hedberg524237c2014-02-22 19:06:31 +02001310 if (!test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001311 return 0;
1312
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001313 rsp = (void *) &smp->prsp[1];
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001314
1315 /* The responder sends its keys first */
Johan Hedbergefabba32014-02-26 23:33:44 +02001316 if (hcon->out && (smp->remote_key_dist & 0x07))
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001317 return 0;
1318
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001319 req = (void *) &smp->preq[1];
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001320
Johan Hedberg524237c2014-02-22 19:06:31 +02001321 if (hcon->out) {
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001322 keydist = &rsp->init_key_dist;
1323 *keydist &= req->init_key_dist;
1324 } else {
1325 keydist = &rsp->resp_key_dist;
1326 *keydist &= req->resp_key_dist;
1327 }
1328
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001329 BT_DBG("keydist 0x%x", *keydist);
1330
1331 if (*keydist & SMP_DIST_ENC_KEY) {
1332 struct smp_cmd_encrypt_info enc;
1333 struct smp_cmd_master_ident ident;
Johan Hedberg23d0e122014-02-19 14:57:46 +02001334 struct smp_ltk *ltk;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001335 u8 authenticated;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001336 __le16 ediv;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001337 __le64 rand;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001338
1339 get_random_bytes(enc.ltk, sizeof(enc.ltk));
1340 get_random_bytes(&ediv, sizeof(ediv));
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001341 get_random_bytes(&rand, sizeof(rand));
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001342
1343 smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
1344
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001345 authenticated = hcon->sec_level == BT_SECURITY_HIGH;
Johan Hedberg524237c2014-02-22 19:06:31 +02001346 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type,
Johan Hedberg2ceba532014-06-16 19:25:16 +03001347 SMP_LTK_SLAVE, authenticated, enc.ltk,
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001348 smp->enc_key_size, ediv, rand);
Johan Hedberg23d0e122014-02-19 14:57:46 +02001349 smp->slave_ltk = ltk;
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001350
Andrei Emeltchenko58115372012-03-12 12:13:06 +02001351 ident.ediv = ediv;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001352 ident.rand = rand;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001353
1354 smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident);
1355
1356 *keydist &= ~SMP_DIST_ENC_KEY;
1357 }
1358
1359 if (*keydist & SMP_DIST_ID_KEY) {
1360 struct smp_cmd_ident_addr_info addrinfo;
1361 struct smp_cmd_ident_info idinfo;
1362
Johan Hedberg863efaf2014-02-22 19:06:32 +02001363 memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk));
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001364
1365 smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo);
1366
Johan Hedberg82d4b352014-02-23 19:42:18 +02001367 /* The hci_conn contains the local identity address
1368 * after the connection has been established.
1369 *
1370 * This is true even when the connection has been
1371 * established using a resolvable random address.
1372 */
Johan Hedberg524237c2014-02-22 19:06:31 +02001373 bacpy(&addrinfo.bdaddr, &hcon->src);
Johan Hedberg82d4b352014-02-23 19:42:18 +02001374 addrinfo.addr_type = hcon->src_type;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001375
1376 smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo),
Marcel Holtmannf1560462013-10-13 05:43:25 -07001377 &addrinfo);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001378
1379 *keydist &= ~SMP_DIST_ID_KEY;
1380 }
1381
1382 if (*keydist & SMP_DIST_SIGN) {
1383 struct smp_cmd_sign_info sign;
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001384 struct smp_csrk *csrk;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001385
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001386 /* Generate a new random key */
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001387 get_random_bytes(sign.csrk, sizeof(sign.csrk));
1388
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001389 csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
1390 if (csrk) {
1391 csrk->master = 0x00;
1392 memcpy(csrk->val, sign.csrk, sizeof(csrk->val));
1393 }
1394 smp->slave_csrk = csrk;
1395
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001396 smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign);
1397
1398 *keydist &= ~SMP_DIST_SIGN;
1399 }
1400
Johan Hedbergefabba32014-02-26 23:33:44 +02001401 /* If there are still keys to be received wait for them */
1402 if ((smp->remote_key_dist & 0x07))
1403 return 0;
1404
Johan Hedberg1d98bf42014-03-24 14:39:08 +02001405 clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags);
1406 cancel_delayed_work_sync(&conn->security_timer);
Johan Hedberg4a74d652014-05-20 09:45:50 +03001407 set_bit(SMP_FLAG_COMPLETE, &smp->flags);
Johan Hedberg1d98bf42014-03-24 14:39:08 +02001408 smp_notify_keys(conn);
Johan Hedbergefabba32014-02-26 23:33:44 +02001409
Johan Hedberg1d98bf42014-03-24 14:39:08 +02001410 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001411
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001412 return 0;
1413}