blob: efb73fdf710d9919023ad5a7d86cafd8322f48cf [file] [log] [blame]
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001/*
2 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License version 2 as
7 published by the Free Software Foundation;
8
9 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
10 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
12 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
13 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
18 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
19 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
20 SOFTWARE IS DISCLAIMED.
21*/
22
Gustavo Padovan8c520a52012-05-23 04:04:22 -030023#include <linux/crypto.h>
24#include <linux/scatterlist.h>
25#include <crypto/b128ops.h>
26
Anderson Brigliaeb492e02011-06-09 18:50:40 -030027#include <net/bluetooth/bluetooth.h>
28#include <net/bluetooth/hci_core.h>
29#include <net/bluetooth/l2cap.h>
Brian Gix2b64d152011-12-21 16:12:12 -080030#include <net/bluetooth/mgmt.h>
Marcel Holtmannac4b7232013-10-10 14:54:16 -070031
32#include "smp.h"
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030033
Marcel Holtmann17b02e62012-03-01 14:32:37 -080034#define SMP_TIMEOUT msecs_to_jiffies(30000)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -030035
Johan Hedberg065a13e2012-10-11 16:26:06 +020036#define AUTH_REQ_MASK 0x07
37
Johan Hedberg4bc58f52014-05-20 09:45:47 +030038#define SMP_FLAG_TK_VALID 1
39#define SMP_FLAG_CFM_PENDING 2
40#define SMP_FLAG_MITM_AUTH 3
41#define SMP_FLAG_COMPLETE 4
42#define SMP_FLAG_INITIATOR 5
43
44struct smp_chan {
45 struct l2cap_conn *conn;
46 u8 preq[7]; /* SMP Pairing Request */
47 u8 prsp[7]; /* SMP Pairing Response */
48 u8 prnd[16]; /* SMP Pairing Random (local) */
49 u8 rrnd[16]; /* SMP Pairing Random (remote) */
50 u8 pcnf[16]; /* SMP Pairing Confirm */
51 u8 tk[16]; /* SMP Temporary Key */
52 u8 enc_key_size;
53 u8 remote_key_dist;
54 bdaddr_t id_addr;
55 u8 id_addr_type;
56 u8 irk[16];
57 struct smp_csrk *csrk;
58 struct smp_csrk *slave_csrk;
59 struct smp_ltk *ltk;
60 struct smp_ltk *slave_ltk;
61 struct smp_irk *remote_irk;
62 unsigned long smp_flags;
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
388static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
389 u8 local_io, u8 remote_io)
390{
391 struct hci_conn *hcon = conn->hcon;
392 struct smp_chan *smp = conn->smp_chan;
393 u8 method;
394 u32 passkey = 0;
395 int ret = 0;
396
397 /* Initialize key for JUST WORKS */
398 memset(smp->tk, 0, sizeof(smp->tk));
399 clear_bit(SMP_FLAG_TK_VALID, &smp->smp_flags);
400
401 BT_DBG("tk_request: auth:%d lcl:%d rem:%d", auth, local_io, remote_io);
402
403 /* If neither side wants MITM, use JUST WORKS */
404 /* If either side has unknown io_caps, use JUST WORKS */
405 /* Otherwise, look up method from the table */
406 if (!(auth & SMP_AUTH_MITM) ||
Marcel Holtmannf1560462013-10-13 05:43:25 -0700407 local_io > SMP_IO_KEYBOARD_DISPLAY ||
408 remote_io > SMP_IO_KEYBOARD_DISPLAY)
Brian Gix2b64d152011-12-21 16:12:12 -0800409 method = JUST_WORKS;
410 else
Ido Yarivb3ff53f2012-03-05 20:07:08 +0200411 method = gen_method[remote_io][local_io];
Brian Gix2b64d152011-12-21 16:12:12 -0800412
413 /* If not bonding, don't ask user to confirm a Zero TK */
414 if (!(auth & SMP_AUTH_BONDING) && method == JUST_CFM)
415 method = JUST_WORKS;
416
Johan Hedberga82505c2014-03-24 14:39:07 +0200417 /* Don't confirm locally initiated pairing attempts */
418 if (method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR,
419 &smp->smp_flags))
420 method = JUST_WORKS;
421
Brian Gix2b64d152011-12-21 16:12:12 -0800422 /* If Just Works, Continue with Zero TK */
423 if (method == JUST_WORKS) {
424 set_bit(SMP_FLAG_TK_VALID, &smp->smp_flags);
425 return 0;
426 }
427
428 /* Not Just Works/Confirm results in MITM Authentication */
429 if (method != JUST_CFM)
430 set_bit(SMP_FLAG_MITM_AUTH, &smp->smp_flags);
431
432 /* If both devices have Keyoard-Display I/O, the master
433 * Confirms and the slave Enters the passkey.
434 */
435 if (method == OVERLAP) {
436 if (hcon->link_mode & HCI_LM_MASTER)
437 method = CFM_PASSKEY;
438 else
439 method = REQ_PASSKEY;
440 }
441
Johan Hedberg01ad34d2014-03-19 14:14:53 +0200442 /* Generate random passkey. */
Brian Gix2b64d152011-12-21 16:12:12 -0800443 if (method == CFM_PASSKEY) {
Johan Hedberg943a7322014-03-18 12:58:24 +0200444 memset(smp->tk, 0, sizeof(smp->tk));
Brian Gix2b64d152011-12-21 16:12:12 -0800445 get_random_bytes(&passkey, sizeof(passkey));
446 passkey %= 1000000;
Johan Hedberg943a7322014-03-18 12:58:24 +0200447 put_unaligned_le32(passkey, smp->tk);
Brian Gix2b64d152011-12-21 16:12:12 -0800448 BT_DBG("PassKey: %d", passkey);
Johan Hedberg01ad34d2014-03-19 14:14:53 +0200449 set_bit(SMP_FLAG_TK_VALID, &smp->smp_flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800450 }
451
452 hci_dev_lock(hcon->hdev);
453
454 if (method == REQ_PASSKEY)
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700455 ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200456 hcon->type, hcon->dst_type);
Johan Hedberg4eb65e62014-03-24 14:39:05 +0200457 else if (method == JUST_CFM)
458 ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
459 hcon->type, hcon->dst_type,
460 passkey, 1);
Brian Gix2b64d152011-12-21 16:12:12 -0800461 else
Johan Hedberg01ad34d2014-03-19 14:14:53 +0200462 ret = mgmt_user_passkey_notify(hcon->hdev, &hcon->dst,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200463 hcon->type, hcon->dst_type,
Johan Hedberg39adbff2014-03-20 08:18:14 +0200464 passkey, 0);
Brian Gix2b64d152011-12-21 16:12:12 -0800465
466 hci_dev_unlock(hcon->hdev);
467
468 return ret;
469}
470
Johan Hedberg9dd4dd22014-05-20 09:45:49 +0300471static void smp_confirm(struct smp_chan *smp)
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300472{
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300473 struct l2cap_conn *conn = smp->conn;
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200474 struct hci_dev *hdev = conn->hcon->hdev;
475 struct crypto_blkcipher *tfm = hdev->tfm_aes;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300476 struct smp_cmd_pairing_confirm cp;
477 int ret;
Johan Hedberg943a7322014-03-18 12:58:24 +0200478 u8 reason;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300479
480 BT_DBG("conn %p", conn);
481
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200482 /* Prevent mutual access to hdev->tfm_aes */
483 hci_dev_lock(hdev);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300484
Johan Hedbergb1cd5fd2014-02-28 12:54:17 +0200485 ret = smp_c1(tfm, smp->tk, smp->prnd, smp->preq, smp->prsp,
486 conn->hcon->init_addr_type, &conn->hcon->init_addr,
Johan Hedberg943a7322014-03-18 12:58:24 +0200487 conn->hcon->resp_addr_type, &conn->hcon->resp_addr,
488 cp.confirm_val);
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200489
490 hci_dev_unlock(hdev);
491
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300492 if (ret) {
493 reason = SMP_UNSPECIFIED;
494 goto error;
495 }
496
Brian Gix2b64d152011-12-21 16:12:12 -0800497 clear_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags);
498
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300499 smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
500
501 return;
502
503error:
Johan Hedberg84794e12013-11-06 11:24:57 +0200504 smp_failure(conn, reason);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300505}
506
Johan Hedberg9dd4dd22014-05-20 09:45:49 +0300507static void 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 Hedberg943a7322014-03-18 12:58:24 +0200513 u8 reason, confirm[16];
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300514 int ret;
515
516 if (IS_ERR_OR_NULL(tfm)) {
517 reason = SMP_UNSPECIFIED;
518 goto error;
519 }
520
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
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300532 if (ret) {
533 reason = SMP_UNSPECIFIED;
534 goto error;
535 }
536
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300537 if (memcmp(smp->pcnf, confirm, sizeof(smp->pcnf)) != 0) {
538 BT_ERR("Pairing failed (confirmation values mismatch)");
539 reason = SMP_CONFIRM_FAILED;
540 goto error;
541 }
542
543 if (hcon->out) {
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -0800544 u8 stk[16];
545 __le64 rand = 0;
546 __le16 ediv = 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300547
Johan Hedberg943a7322014-03-18 12:58:24 +0200548 smp_s1(tfm, smp->tk, smp->rrnd, smp->prnd, stk);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300549
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300550 memset(stk + smp->enc_key_size, 0,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300551 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300552
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200553 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags)) {
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300554 reason = SMP_UNSPECIFIED;
555 goto error;
556 }
557
558 hci_le_start_enc(hcon, ediv, rand, stk);
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300559 hcon->enc_key_size = smp->enc_key_size;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300560 } else {
Johan Hedberg943a7322014-03-18 12:58:24 +0200561 u8 stk[16];
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -0800562 __le64 rand = 0;
563 __le16 ediv = 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300564
Johan Hedberg943a7322014-03-18 12:58:24 +0200565 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
566 smp->prnd);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300567
Johan Hedberg943a7322014-03-18 12:58:24 +0200568 smp_s1(tfm, smp->tk, smp->prnd, smp->rrnd, stk);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300569
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300570 memset(stk + smp->enc_key_size, 0,
Marcel Holtmannf1560462013-10-13 05:43:25 -0700571 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300572
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700573 hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
Johan Hedberg35d70272014-02-19 14:57:47 +0200574 HCI_SMP_STK_SLAVE, 0, stk, smp->enc_key_size,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300575 ediv, rand);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300576 }
577
578 return;
579
580error:
Johan Hedberg84794e12013-11-06 11:24:57 +0200581 smp_failure(conn, reason);
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 Hedbergf4a407be2014-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 Hedbergf4a407be2014-02-18 21:41:34 +0200608 complete = test_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
609 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:
659 set_bit(SMP_FLAG_TK_VALID, &smp->smp_flags);
660 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 */
671 if (test_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags))
Johan Hedberg9dd4dd22014-05-20 09:45:49 +0300672 smp_confirm(smp);
Brian Gix2b64d152011-12-21 16:12:12 -0800673
674 return 0;
675}
676
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300677static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300678{
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300679 struct smp_cmd_pairing rsp, *req = (void *) skb->data;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300680 struct smp_chan *smp;
Johan Hedberg1ef35822014-05-20 09:45:48 +0300681 u8 key_size, auth;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300682 int ret;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300683
684 BT_DBG("conn %p", conn);
685
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200686 if (skb->len < sizeof(*req))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300687 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200688
Brian Gix2b64d152011-12-21 16:12:12 -0800689 if (conn->hcon->link_mode & HCI_LM_MASTER)
690 return SMP_CMD_NOTSUPP;
691
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200692 if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags))
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300693 smp = smp_chan_create(conn);
Andrei Emeltchenkod08fd0e2012-07-19 17:03:43 +0300694 else
695 smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300696
Andrei Emeltchenkod08fd0e2012-07-19 17:03:43 +0300697 if (!smp)
698 return SMP_UNSPECIFIED;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300699
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300700 smp->preq[0] = SMP_CMD_PAIRING_REQ;
701 memcpy(&smp->preq[1], req, sizeof(*req));
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300702 skb_pull(skb, sizeof(*req));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300703
Brian Gix2b64d152011-12-21 16:12:12 -0800704 /* We didn't start the pairing, so match remote */
Johan Hedberg1ef35822014-05-20 09:45:48 +0300705 auth = req->auth_req;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300706
Ido Yarivfdde0a22012-03-05 20:09:38 +0200707 conn->hcon->pending_sec_level = authreq_to_seclevel(auth);
708
Brian Gix2b64d152011-12-21 16:12:12 -0800709 build_pairing_cmd(conn, req, &rsp, auth);
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300710
711 key_size = min(req->max_key_size, rsp.max_key_size);
712 if (check_enc_key_size(conn, key_size))
713 return SMP_ENC_KEY_SIZE;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300714
Johan Hedberge84a6b12013-12-02 10:49:03 +0200715 get_random_bytes(smp->prnd, sizeof(smp->prnd));
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300716
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300717 smp->prsp[0] = SMP_CMD_PAIRING_RSP;
718 memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300719
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300720 smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300721
Brian Gix2b64d152011-12-21 16:12:12 -0800722 /* Request setup of TK */
723 ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability);
724 if (ret)
725 return SMP_UNSPECIFIED;
726
Johan Hedbergedca7922014-03-24 15:54:11 +0200727 clear_bit(SMP_FLAG_INITIATOR, &smp->smp_flags);
728
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300729 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300730}
731
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300732static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300733{
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300734 struct smp_cmd_pairing *req, *rsp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300735 struct smp_chan *smp = conn->smp_chan;
Brian Gix2b64d152011-12-21 16:12:12 -0800736 u8 key_size, auth = SMP_AUTH_NONE;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300737 int ret;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300738
739 BT_DBG("conn %p", conn);
740
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200741 if (skb->len < sizeof(*rsp))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300742 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200743
Brian Gix2b64d152011-12-21 16:12:12 -0800744 if (!(conn->hcon->link_mode & HCI_LM_MASTER))
745 return SMP_CMD_NOTSUPP;
746
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300747 skb_pull(skb, sizeof(*rsp));
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300748
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300749 req = (void *) &smp->preq[1];
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300750
751 key_size = min(req->max_key_size, rsp->max_key_size);
752 if (check_enc_key_size(conn, key_size))
753 return SMP_ENC_KEY_SIZE;
754
Johan Hedberge84a6b12013-12-02 10:49:03 +0200755 get_random_bytes(smp->prnd, sizeof(smp->prnd));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300756
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300757 smp->prsp[0] = SMP_CMD_PAIRING_RSP;
758 memcpy(&smp->prsp[1], rsp, sizeof(*rsp));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300759
Johan Hedbergfdcc4be2014-03-14 10:53:50 +0200760 /* Update remote key distribution in case the remote cleared
761 * some bits that we had enabled in our request.
762 */
763 smp->remote_key_dist &= rsp->resp_key_dist;
764
Brian Gix2b64d152011-12-21 16:12:12 -0800765 if ((req->auth_req & SMP_AUTH_BONDING) &&
Marcel Holtmannf1560462013-10-13 05:43:25 -0700766 (rsp->auth_req & SMP_AUTH_BONDING))
Brian Gix2b64d152011-12-21 16:12:12 -0800767 auth = SMP_AUTH_BONDING;
768
769 auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM;
770
Johan Hedberg476585e2012-06-06 18:54:15 +0800771 ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability);
Brian Gix2b64d152011-12-21 16:12:12 -0800772 if (ret)
773 return SMP_UNSPECIFIED;
774
775 set_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags);
776
777 /* Can't compose response until we have been confirmed */
Johan Hedberg18e4aeb2014-03-19 14:14:51 +0200778 if (test_bit(SMP_FLAG_TK_VALID, &smp->smp_flags))
Johan Hedberg9dd4dd22014-05-20 09:45:49 +0300779 smp_confirm(smp);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300780
781 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300782}
783
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300784static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300785{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300786 struct smp_chan *smp = conn->smp_chan;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300787
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300788 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
789
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200790 if (skb->len < sizeof(smp->pcnf))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300791 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200792
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300793 memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf));
794 skb_pull(skb, sizeof(smp->pcnf));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300795
Johan Hedberg943a7322014-03-18 12:58:24 +0200796 if (conn->hcon->out)
797 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
798 smp->prnd);
799 else if (test_bit(SMP_FLAG_TK_VALID, &smp->smp_flags))
Johan Hedberg9dd4dd22014-05-20 09:45:49 +0300800 smp_confirm(smp);
Johan Hedberg943a7322014-03-18 12:58:24 +0200801 else
Brian Gix2b64d152011-12-21 16:12:12 -0800802 set_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300803
804 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300805}
806
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300807static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300808{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300809 struct smp_chan *smp = conn->smp_chan;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300810
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300811 BT_DBG("conn %p", conn);
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300812
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200813 if (skb->len < sizeof(smp->rrnd))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300814 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200815
Johan Hedberg943a7322014-03-18 12:58:24 +0200816 memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd));
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300817 skb_pull(skb, sizeof(smp->rrnd));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300818
Johan Hedberg9dd4dd22014-05-20 09:45:49 +0300819 smp_random(smp);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300820
821 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300822}
823
Johan Hedberg4dab7862012-06-07 14:58:37 +0800824static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300825{
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300826 struct smp_ltk *key;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300827 struct hci_conn *hcon = conn->hcon;
828
Johan Hedberg98a0b842014-01-30 19:40:00 -0800829 key = hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type,
830 hcon->out);
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300831 if (!key)
832 return 0;
833
Johan Hedberg4dab7862012-06-07 14:58:37 +0800834 if (sec_level > BT_SECURITY_MEDIUM && !key->authenticated)
835 return 0;
836
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200837 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300838 return 1;
839
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300840 hci_le_start_enc(hcon, key->ediv, key->rand, key->val);
841 hcon->enc_key_size = key->enc_size;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300842
843 return 1;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300844}
Marcel Holtmannf1560462013-10-13 05:43:25 -0700845
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300846static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300847{
848 struct smp_cmd_security_req *rp = (void *) skb->data;
849 struct smp_cmd_pairing cp;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300850 struct hci_conn *hcon = conn->hcon;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300851 struct smp_chan *smp;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300852
853 BT_DBG("conn %p", conn);
854
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200855 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300856 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200857
Johan Hedberg86ca9ea2013-11-05 11:30:39 +0200858 if (!(conn->hcon->link_mode & HCI_LM_MASTER))
859 return SMP_CMD_NOTSUPP;
860
Brian Gix2b64d152011-12-21 16:12:12 -0800861 hcon->pending_sec_level = authreq_to_seclevel(rp->auth_req);
Vinicius Costa Gomesfeb45eb2011-08-25 20:02:35 -0300862
Johan Hedberg4dab7862012-06-07 14:58:37 +0800863 if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300864 return 0;
865
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200866 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300867 return 0;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300868
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300869 smp = smp_chan_create(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300870
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300871 skb_pull(skb, sizeof(*rp));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300872
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300873 memset(&cp, 0, sizeof(cp));
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300874 build_pairing_cmd(conn, &cp, NULL, rp->auth_req);
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300875
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300876 smp->preq[0] = SMP_CMD_PAIRING_REQ;
877 memcpy(&smp->preq[1], &cp, sizeof(cp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300878
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300879 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300880
Johan Hedbergedca7922014-03-24 15:54:11 +0200881 clear_bit(SMP_FLAG_INITIATOR, &smp->smp_flags);
882
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300883 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300884}
885
Johan Hedbergad32a2f2013-05-14 18:05:12 +0300886bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level)
887{
888 if (sec_level == BT_SECURITY_LOW)
889 return true;
890
891 if (hcon->sec_level >= sec_level)
892 return true;
893
894 return false;
895}
896
Vinicius Costa Gomescc110922012-08-23 21:32:43 -0300897int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300898{
Vinicius Costa Gomescc110922012-08-23 21:32:43 -0300899 struct l2cap_conn *conn = hcon->l2cap_data;
Johan Hedberg0a66cf22014-03-24 14:39:03 +0200900 struct smp_chan *smp;
Brian Gix2b64d152011-12-21 16:12:12 -0800901 __u8 authreq;
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300902
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -0300903 BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
904
Johan Hedberg0a66cf22014-03-24 14:39:03 +0200905 /* This may be NULL if there's an unexpected disconnection */
906 if (!conn)
907 return 1;
908
Johan Hedberg757aee02013-04-24 13:05:32 +0300909 if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags))
Andre Guedes2e65c9d2011-06-30 19:20:56 -0300910 return 1;
911
Johan Hedbergad32a2f2013-05-14 18:05:12 +0300912 if (smp_sufficient_security(hcon, sec_level))
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300913 return 1;
914
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300915 if (hcon->link_mode & HCI_LM_MASTER)
Johan Hedberg4dab7862012-06-07 14:58:37 +0800916 if (smp_ltk_encrypt(conn, sec_level))
Vinicius Costa Gomes02bc7452011-07-07 18:59:41 -0300917 goto done;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300918
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200919 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300920 return 0;
921
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300922 smp = smp_chan_create(conn);
Brian Gix2b64d152011-12-21 16:12:12 -0800923 if (!smp)
924 return 1;
925
926 authreq = seclevel_to_authreq(sec_level);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300927
Johan Hedberg2e233642014-03-18 15:42:30 +0200928 /* hcon->auth_type is set by pair_device in mgmt.c. If the MITM
929 * flag is set we should also set it for the SMP request.
930 */
931 if ((hcon->auth_type & 0x01))
932 authreq |= SMP_AUTH_MITM;
933
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300934 if (hcon->link_mode & HCI_LM_MASTER) {
935 struct smp_cmd_pairing cp;
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300936
Brian Gix2b64d152011-12-21 16:12:12 -0800937 build_pairing_cmd(conn, &cp, NULL, authreq);
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300938 smp->preq[0] = SMP_CMD_PAIRING_REQ;
939 memcpy(&smp->preq[1], &cp, sizeof(cp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300940
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300941 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
942 } else {
943 struct smp_cmd_security_req cp;
Brian Gix2b64d152011-12-21 16:12:12 -0800944 cp.auth_req = authreq;
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300945 smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
946 }
947
Johan Hedbergedca7922014-03-24 15:54:11 +0200948 set_bit(SMP_FLAG_INITIATOR, &smp->smp_flags);
949
Johan Hedberg61b3b2b2014-03-24 17:36:25 +0200950done:
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300951 hcon->pending_sec_level = sec_level;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300952
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300953 return 0;
954}
955
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300956static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
957{
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300958 struct smp_cmd_encrypt_info *rp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300959 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300960
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200961 BT_DBG("conn %p", conn);
962
963 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300964 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200965
Johan Hedberg6131ddc2014-02-18 10:19:37 +0200966 /* Ignore this PDU if it wasn't requested */
967 if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
968 return 0;
969
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300970 skb_pull(skb, sizeof(*rp));
971
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300972 memcpy(smp->tk, rp->ltk, sizeof(smp->tk));
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300973
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300974 return 0;
975}
976
977static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
978{
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300979 struct smp_cmd_master_ident *rp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300980 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300981 struct hci_dev *hdev = conn->hcon->hdev;
982 struct hci_conn *hcon = conn->hcon;
Johan Hedberg23d0e122014-02-19 14:57:46 +0200983 struct smp_ltk *ltk;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300984 u8 authenticated;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300985
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200986 BT_DBG("conn %p", conn);
987
988 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300989 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200990
Johan Hedberg6131ddc2014-02-18 10:19:37 +0200991 /* Ignore this PDU if it wasn't requested */
992 if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
993 return 0;
994
Johan Hedberg9747a9f2014-02-26 23:33:43 +0200995 /* Mark the information as received */
996 smp->remote_key_dist &= ~SMP_DIST_ENC_KEY;
997
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300998 skb_pull(skb, sizeof(*rp));
999
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001000 hci_dev_lock(hdev);
Marcel Holtmannce39fb42013-10-13 02:23:39 -07001001 authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
Johan Hedberg35d70272014-02-19 14:57:47 +02001002 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, HCI_SMP_LTK,
Johan Hedberg23d0e122014-02-19 14:57:46 +02001003 authenticated, smp->tk, smp->enc_key_size,
1004 rp->ediv, rp->rand);
1005 smp->ltk = ltk;
Johan Hedbergfd349c02014-02-18 10:19:36 +02001006 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001007 smp_distribute_keys(conn);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001008 hci_dev_unlock(hdev);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001009
1010 return 0;
1011}
1012
Johan Hedbergfd349c02014-02-18 10:19:36 +02001013static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
1014{
1015 struct smp_cmd_ident_info *info = (void *) skb->data;
1016 struct smp_chan *smp = conn->smp_chan;
1017
1018 BT_DBG("");
1019
1020 if (skb->len < sizeof(*info))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001021 return SMP_INVALID_PARAMS;
Johan Hedbergfd349c02014-02-18 10:19:36 +02001022
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001023 /* Ignore this PDU if it wasn't requested */
1024 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
1025 return 0;
1026
Johan Hedbergfd349c02014-02-18 10:19:36 +02001027 skb_pull(skb, sizeof(*info));
1028
1029 memcpy(smp->irk, info->irk, 16);
1030
1031 return 0;
1032}
1033
1034static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
1035 struct sk_buff *skb)
1036{
1037 struct smp_cmd_ident_addr_info *info = (void *) skb->data;
1038 struct smp_chan *smp = conn->smp_chan;
1039 struct hci_conn *hcon = conn->hcon;
1040 bdaddr_t rpa;
1041
1042 BT_DBG("");
1043
1044 if (skb->len < sizeof(*info))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001045 return SMP_INVALID_PARAMS;
Johan Hedbergfd349c02014-02-18 10:19:36 +02001046
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001047 /* Ignore this PDU if it wasn't requested */
1048 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
1049 return 0;
1050
Johan Hedberg9747a9f2014-02-26 23:33:43 +02001051 /* Mark the information as received */
1052 smp->remote_key_dist &= ~SMP_DIST_ID_KEY;
1053
Johan Hedbergfd349c02014-02-18 10:19:36 +02001054 skb_pull(skb, sizeof(*info));
1055
Johan Hedberga9a58f82014-02-25 22:24:37 +02001056 /* Strictly speaking the Core Specification (4.1) allows sending
1057 * an empty address which would force us to rely on just the IRK
1058 * as "identity information". However, since such
1059 * implementations are not known of and in order to not over
1060 * complicate our implementation, simply pretend that we never
1061 * received an IRK for such a device.
1062 */
1063 if (!bacmp(&info->bdaddr, BDADDR_ANY)) {
1064 BT_ERR("Ignoring IRK with no identity address");
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001065 smp_distribute_keys(conn);
Johan Hedberga9a58f82014-02-25 22:24:37 +02001066 return 0;
1067 }
1068
Johan Hedbergfd349c02014-02-18 10:19:36 +02001069 bacpy(&smp->id_addr, &info->bdaddr);
1070 smp->id_addr_type = info->addr_type;
1071
1072 if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type))
1073 bacpy(&rpa, &hcon->dst);
1074 else
1075 bacpy(&rpa, BDADDR_ANY);
1076
Johan Hedberg23d0e122014-02-19 14:57:46 +02001077 smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
1078 smp->id_addr_type, smp->irk, &rpa);
Johan Hedbergfd349c02014-02-18 10:19:36 +02001079
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001080 smp_distribute_keys(conn);
Johan Hedbergfd349c02014-02-18 10:19:36 +02001081
1082 return 0;
1083}
1084
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001085static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)
1086{
1087 struct smp_cmd_sign_info *rp = (void *) skb->data;
1088 struct smp_chan *smp = conn->smp_chan;
1089 struct hci_dev *hdev = conn->hcon->hdev;
1090 struct smp_csrk *csrk;
1091
1092 BT_DBG("conn %p", conn);
1093
1094 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001095 return SMP_INVALID_PARAMS;
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001096
1097 /* Ignore this PDU if it wasn't requested */
1098 if (!(smp->remote_key_dist & SMP_DIST_SIGN))
1099 return 0;
1100
1101 /* Mark the information as received */
1102 smp->remote_key_dist &= ~SMP_DIST_SIGN;
1103
1104 skb_pull(skb, sizeof(*rp));
1105
1106 hci_dev_lock(hdev);
1107 csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
1108 if (csrk) {
1109 csrk->master = 0x01;
1110 memcpy(csrk->val, rp->csrk, sizeof(csrk->val));
1111 }
1112 smp->csrk = csrk;
1113 if (!(smp->remote_key_dist & SMP_DIST_SIGN))
1114 smp_distribute_keys(conn);
1115 hci_dev_unlock(hdev);
1116
1117 return 0;
1118}
1119
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001120int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
1121{
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001122 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann92381f52013-10-03 01:23:08 -07001123 __u8 code, reason;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001124 int err = 0;
1125
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001126 if (hcon->type != LE_LINK) {
1127 kfree_skb(skb);
Johan Hedberg34327112013-10-16 11:37:01 +03001128 return 0;
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001129 }
1130
Marcel Holtmann92381f52013-10-03 01:23:08 -07001131 if (skb->len < 1) {
1132 kfree_skb(skb);
1133 return -EILSEQ;
1134 }
1135
Marcel Holtmann06ae3312013-10-18 03:43:00 -07001136 if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) {
Andre Guedes2e65c9d2011-06-30 19:20:56 -03001137 err = -ENOTSUPP;
1138 reason = SMP_PAIRING_NOTSUPP;
1139 goto done;
1140 }
1141
Marcel Holtmann92381f52013-10-03 01:23:08 -07001142 code = skb->data[0];
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001143 skb_pull(skb, sizeof(code));
1144
Johan Hedberg8cf9fa12013-01-29 10:44:23 -06001145 /*
1146 * The SMP context must be initialized for all other PDUs except
1147 * pairing and security requests. If we get any other PDU when
1148 * not initialized simply disconnect (done if this function
1149 * returns an error).
1150 */
1151 if (code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ &&
1152 !conn->smp_chan) {
1153 BT_ERR("Unexpected SMP command 0x%02x. Disconnecting.", code);
1154 kfree_skb(skb);
1155 return -ENOTSUPP;
1156 }
1157
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001158 switch (code) {
1159 case SMP_CMD_PAIRING_REQ:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001160 reason = smp_cmd_pairing_req(conn, skb);
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001161 break;
1162
1163 case SMP_CMD_PAIRING_FAIL:
Johan Hedberg84794e12013-11-06 11:24:57 +02001164 smp_failure(conn, 0);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001165 reason = 0;
1166 err = -EPERM;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001167 break;
1168
1169 case SMP_CMD_PAIRING_RSP:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001170 reason = smp_cmd_pairing_rsp(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001171 break;
1172
1173 case SMP_CMD_SECURITY_REQ:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001174 reason = smp_cmd_security_req(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001175 break;
1176
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001177 case SMP_CMD_PAIRING_CONFIRM:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001178 reason = smp_cmd_pairing_confirm(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001179 break;
1180
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001181 case SMP_CMD_PAIRING_RANDOM:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001182 reason = smp_cmd_pairing_random(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001183 break;
1184
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001185 case SMP_CMD_ENCRYPT_INFO:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001186 reason = smp_cmd_encrypt_info(conn, skb);
1187 break;
1188
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001189 case SMP_CMD_MASTER_IDENT:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001190 reason = smp_cmd_master_ident(conn, skb);
1191 break;
1192
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001193 case SMP_CMD_IDENT_INFO:
Johan Hedbergfd349c02014-02-18 10:19:36 +02001194 reason = smp_cmd_ident_info(conn, skb);
1195 break;
1196
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001197 case SMP_CMD_IDENT_ADDR_INFO:
Johan Hedbergfd349c02014-02-18 10:19:36 +02001198 reason = smp_cmd_ident_addr_info(conn, skb);
1199 break;
1200
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001201 case SMP_CMD_SIGN_INFO:
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001202 reason = smp_cmd_sign_info(conn, skb);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001203 break;
1204
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001205 default:
1206 BT_DBG("Unknown command code 0x%2.2x", code);
1207
1208 reason = SMP_CMD_NOTSUPP;
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -03001209 err = -EOPNOTSUPP;
1210 goto done;
1211 }
1212
1213done:
1214 if (reason)
Johan Hedberg84794e12013-11-06 11:24:57 +02001215 smp_failure(conn, reason);
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001216
1217 kfree_skb(skb);
1218 return err;
1219}
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001220
Johan Hedberg35d70272014-02-19 14:57:47 +02001221static void smp_notify_keys(struct l2cap_conn *conn)
1222{
1223 struct smp_chan *smp = conn->smp_chan;
1224 struct hci_conn *hcon = conn->hcon;
1225 struct hci_dev *hdev = hcon->hdev;
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001226 struct smp_cmd_pairing *req = (void *) &smp->preq[1];
1227 struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1];
1228 bool persistent;
Johan Hedberg35d70272014-02-19 14:57:47 +02001229
Johan Hedberg61b1a7f2014-03-20 12:54:16 +02001230 if (smp->remote_irk) {
Johan Hedberg95fbac82014-02-19 15:18:31 +02001231 mgmt_new_irk(hdev, smp->remote_irk);
Johan Hedberg61b1a7f2014-03-20 12:54:16 +02001232 /* Now that user space can be considered to know the
1233 * identity address track the connection based on it
1234 * from now on.
1235 */
1236 bacpy(&hcon->dst, &smp->remote_irk->bdaddr);
1237 hcon->dst_type = smp->remote_irk->addr_type;
1238 l2cap_conn_update_id_addr(hcon);
1239 }
Johan Hedberg95fbac82014-02-19 15:18:31 +02001240
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001241 /* The LTKs and CSRKs should be persistent only if both sides
1242 * had the bonding bit set in their authentication requests.
1243 */
1244 persistent = !!((req->auth_req & rsp->auth_req) & SMP_AUTH_BONDING);
1245
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001246 if (smp->csrk) {
1247 smp->csrk->bdaddr_type = hcon->dst_type;
1248 bacpy(&smp->csrk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001249 mgmt_new_csrk(hdev, smp->csrk, persistent);
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001250 }
1251
1252 if (smp->slave_csrk) {
1253 smp->slave_csrk->bdaddr_type = hcon->dst_type;
1254 bacpy(&smp->slave_csrk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001255 mgmt_new_csrk(hdev, smp->slave_csrk, persistent);
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001256 }
1257
Johan Hedberg35d70272014-02-19 14:57:47 +02001258 if (smp->ltk) {
1259 smp->ltk->bdaddr_type = hcon->dst_type;
1260 bacpy(&smp->ltk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001261 mgmt_new_ltk(hdev, smp->ltk, persistent);
Johan Hedberg35d70272014-02-19 14:57:47 +02001262 }
1263
1264 if (smp->slave_ltk) {
1265 smp->slave_ltk->bdaddr_type = hcon->dst_type;
1266 bacpy(&smp->slave_ltk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001267 mgmt_new_ltk(hdev, smp->slave_ltk, persistent);
Johan Hedberg35d70272014-02-19 14:57:47 +02001268 }
1269}
1270
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001271int smp_distribute_keys(struct l2cap_conn *conn)
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001272{
1273 struct smp_cmd_pairing *req, *rsp;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001274 struct smp_chan *smp = conn->smp_chan;
Johan Hedberg524237c2014-02-22 19:06:31 +02001275 struct hci_conn *hcon = conn->hcon;
1276 struct hci_dev *hdev = hcon->hdev;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001277 __u8 *keydist;
1278
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001279 BT_DBG("conn %p", conn);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001280
Johan Hedberg524237c2014-02-22 19:06:31 +02001281 if (!test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001282 return 0;
1283
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001284 rsp = (void *) &smp->prsp[1];
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001285
1286 /* The responder sends its keys first */
Johan Hedbergefabba32014-02-26 23:33:44 +02001287 if (hcon->out && (smp->remote_key_dist & 0x07))
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001288 return 0;
1289
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001290 req = (void *) &smp->preq[1];
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001291
Johan Hedberg524237c2014-02-22 19:06:31 +02001292 if (hcon->out) {
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001293 keydist = &rsp->init_key_dist;
1294 *keydist &= req->init_key_dist;
1295 } else {
1296 keydist = &rsp->resp_key_dist;
1297 *keydist &= req->resp_key_dist;
1298 }
1299
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001300 BT_DBG("keydist 0x%x", *keydist);
1301
1302 if (*keydist & SMP_DIST_ENC_KEY) {
1303 struct smp_cmd_encrypt_info enc;
1304 struct smp_cmd_master_ident ident;
Johan Hedberg23d0e122014-02-19 14:57:46 +02001305 struct smp_ltk *ltk;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001306 u8 authenticated;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001307 __le16 ediv;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001308 __le64 rand;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001309
1310 get_random_bytes(enc.ltk, sizeof(enc.ltk));
1311 get_random_bytes(&ediv, sizeof(ediv));
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001312 get_random_bytes(&rand, sizeof(rand));
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001313
1314 smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
1315
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001316 authenticated = hcon->sec_level == BT_SECURITY_HIGH;
Johan Hedberg524237c2014-02-22 19:06:31 +02001317 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type,
Johan Hedberg35d70272014-02-19 14:57:47 +02001318 HCI_SMP_LTK_SLAVE, authenticated, enc.ltk,
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001319 smp->enc_key_size, ediv, rand);
Johan Hedberg23d0e122014-02-19 14:57:46 +02001320 smp->slave_ltk = ltk;
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001321
Andrei Emeltchenko58115372012-03-12 12:13:06 +02001322 ident.ediv = ediv;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001323 ident.rand = rand;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001324
1325 smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident);
1326
1327 *keydist &= ~SMP_DIST_ENC_KEY;
1328 }
1329
1330 if (*keydist & SMP_DIST_ID_KEY) {
1331 struct smp_cmd_ident_addr_info addrinfo;
1332 struct smp_cmd_ident_info idinfo;
1333
Johan Hedberg863efaf2014-02-22 19:06:32 +02001334 memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk));
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001335
1336 smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo);
1337
Johan Hedberg82d4b352014-02-23 19:42:18 +02001338 /* The hci_conn contains the local identity address
1339 * after the connection has been established.
1340 *
1341 * This is true even when the connection has been
1342 * established using a resolvable random address.
1343 */
Johan Hedberg524237c2014-02-22 19:06:31 +02001344 bacpy(&addrinfo.bdaddr, &hcon->src);
Johan Hedberg82d4b352014-02-23 19:42:18 +02001345 addrinfo.addr_type = hcon->src_type;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001346
1347 smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo),
Marcel Holtmannf1560462013-10-13 05:43:25 -07001348 &addrinfo);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001349
1350 *keydist &= ~SMP_DIST_ID_KEY;
1351 }
1352
1353 if (*keydist & SMP_DIST_SIGN) {
1354 struct smp_cmd_sign_info sign;
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001355 struct smp_csrk *csrk;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001356
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001357 /* Generate a new random key */
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001358 get_random_bytes(sign.csrk, sizeof(sign.csrk));
1359
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001360 csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
1361 if (csrk) {
1362 csrk->master = 0x00;
1363 memcpy(csrk->val, sign.csrk, sizeof(csrk->val));
1364 }
1365 smp->slave_csrk = csrk;
1366
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001367 smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign);
1368
1369 *keydist &= ~SMP_DIST_SIGN;
1370 }
1371
Johan Hedbergefabba32014-02-26 23:33:44 +02001372 /* If there are still keys to be received wait for them */
1373 if ((smp->remote_key_dist & 0x07))
1374 return 0;
1375
Johan Hedberg1d98bf42014-03-24 14:39:08 +02001376 clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags);
1377 cancel_delayed_work_sync(&conn->security_timer);
1378 set_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
1379 smp_notify_keys(conn);
Johan Hedbergefabba32014-02-26 23:33:44 +02001380
Johan Hedberg1d98bf42014-03-24 14:39:08 +02001381 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001382
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001383 return 0;
1384}