blob: fa782d7b495bbceef84eed9b853048934621d4be [file] [log] [blame]
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001/*
2 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License version 2 as
7 published by the Free Software Foundation;
8
9 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
10 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
12 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
13 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
18 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
19 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
20 SOFTWARE IS DISCLAIMED.
21*/
22
Gustavo Padovan8c520a52012-05-23 04:04:22 -030023#include <linux/crypto.h>
24#include <linux/scatterlist.h>
25#include <crypto/b128ops.h>
26
Anderson Brigliaeb492e02011-06-09 18:50:40 -030027#include <net/bluetooth/bluetooth.h>
28#include <net/bluetooth/hci_core.h>
29#include <net/bluetooth/l2cap.h>
Brian Gix2b64d152011-12-21 16:12:12 -080030#include <net/bluetooth/mgmt.h>
Marcel Holtmannac4b7232013-10-10 14:54:16 -070031
32#include "smp.h"
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030033
Marcel Holtmann17b02e62012-03-01 14:32:37 -080034#define SMP_TIMEOUT msecs_to_jiffies(30000)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -030035
Johan Hedberg065a13e2012-10-11 16:26:06 +020036#define AUTH_REQ_MASK 0x07
37
Johan Hedberg4bc58f52014-05-20 09:45:47 +030038#define SMP_FLAG_TK_VALID 1
39#define SMP_FLAG_CFM_PENDING 2
40#define SMP_FLAG_MITM_AUTH 3
41#define SMP_FLAG_COMPLETE 4
42#define SMP_FLAG_INITIATOR 5
43
44struct smp_chan {
45 struct l2cap_conn *conn;
46 u8 preq[7]; /* SMP Pairing Request */
47 u8 prsp[7]; /* SMP Pairing Response */
48 u8 prnd[16]; /* SMP Pairing Random (local) */
49 u8 rrnd[16]; /* SMP Pairing Random (remote) */
50 u8 pcnf[16]; /* SMP Pairing Confirm */
51 u8 tk[16]; /* SMP Temporary Key */
52 u8 enc_key_size;
53 u8 remote_key_dist;
54 bdaddr_t id_addr;
55 u8 id_addr_type;
56 u8 irk[16];
57 struct smp_csrk *csrk;
58 struct smp_csrk *slave_csrk;
59 struct smp_ltk *ltk;
60 struct smp_ltk *slave_ltk;
61 struct smp_irk *remote_irk;
Johan Hedberg4a74d652014-05-20 09:45:50 +030062 unsigned long flags;
Johan Hedberg4bc58f52014-05-20 09:45:47 +030063};
64
Johan Hedberg66bed1a2014-03-18 12:58:23 +020065static inline void swap128(const u8 src[16], u8 dst[16])
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030066{
67 int i;
68 for (i = 0; i < 16; i++)
69 dst[15 - i] = src[i];
70}
71
Johan Hedberg66bed1a2014-03-18 12:58:23 +020072static inline void swap56(const u8 src[7], u8 dst[7])
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030073{
74 int i;
75 for (i = 0; i < 7; i++)
76 dst[6 - i] = src[i];
77}
78
79static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
80{
81 struct blkcipher_desc desc;
82 struct scatterlist sg;
Johan Hedberg943a7322014-03-18 12:58:24 +020083 uint8_t tmp[16], data[16];
Johan Hedberg201a5922013-12-02 10:49:04 +020084 int err;
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030085
86 if (tfm == NULL) {
87 BT_ERR("tfm %p", tfm);
88 return -EINVAL;
89 }
90
91 desc.tfm = tfm;
92 desc.flags = 0;
93
Johan Hedberg943a7322014-03-18 12:58:24 +020094 /* The most significant octet of key corresponds to k[0] */
95 swap128(k, tmp);
96
97 err = crypto_blkcipher_setkey(tfm, tmp, 16);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030098 if (err) {
99 BT_ERR("cipher setkey failed: %d", err);
100 return err;
101 }
102
Johan Hedberg943a7322014-03-18 12:58:24 +0200103 /* Most significant octet of plaintextData corresponds to data[0] */
104 swap128(r, data);
105
106 sg_init_one(&sg, data, 16);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300107
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300108 err = crypto_blkcipher_encrypt(&desc, &sg, &sg, 16);
109 if (err)
110 BT_ERR("Encrypt data error %d", err);
111
Johan Hedberg943a7322014-03-18 12:58:24 +0200112 /* Most significant octet of encryptedData corresponds to data[0] */
113 swap128(data, r);
114
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300115 return err;
116}
117
Johan Hedberg60478052014-02-18 10:19:31 +0200118static int smp_ah(struct crypto_blkcipher *tfm, u8 irk[16], u8 r[3], u8 res[3])
119{
Johan Hedberg943a7322014-03-18 12:58:24 +0200120 u8 _res[16];
Johan Hedberg60478052014-02-18 10:19:31 +0200121 int err;
122
123 /* r' = padding || r */
Johan Hedberg943a7322014-03-18 12:58:24 +0200124 memcpy(_res, r, 3);
125 memset(_res + 3, 0, 13);
Johan Hedberg60478052014-02-18 10:19:31 +0200126
Johan Hedberg943a7322014-03-18 12:58:24 +0200127 err = smp_e(tfm, irk, _res);
Johan Hedberg60478052014-02-18 10:19:31 +0200128 if (err) {
129 BT_ERR("Encrypt error");
130 return err;
131 }
132
133 /* The output of the random address function ah is:
134 * ah(h, r) = e(k, r') mod 2^24
135 * The output of the security function e is then truncated to 24 bits
136 * by taking the least significant 24 bits of the output of e as the
137 * result of ah.
138 */
Johan Hedberg943a7322014-03-18 12:58:24 +0200139 memcpy(res, _res, 3);
Johan Hedberg60478052014-02-18 10:19:31 +0200140
141 return 0;
142}
143
144bool smp_irk_matches(struct crypto_blkcipher *tfm, u8 irk[16],
145 bdaddr_t *bdaddr)
146{
147 u8 hash[3];
148 int err;
149
150 BT_DBG("RPA %pMR IRK %*phN", bdaddr, 16, irk);
151
152 err = smp_ah(tfm, irk, &bdaddr->b[3], hash);
153 if (err)
154 return false;
155
156 return !memcmp(bdaddr->b, hash, 3);
157}
158
Johan Hedbergb1e2b3a2014-02-23 19:42:19 +0200159int smp_generate_rpa(struct crypto_blkcipher *tfm, u8 irk[16], bdaddr_t *rpa)
160{
161 int err;
162
163 get_random_bytes(&rpa->b[3], 3);
164
165 rpa->b[5] &= 0x3f; /* Clear two most significant bits */
166 rpa->b[5] |= 0x40; /* Set second most significant bit */
167
168 err = smp_ah(tfm, irk, &rpa->b[3], rpa->b);
169 if (err < 0)
170 return err;
171
172 BT_DBG("RPA %pMR", rpa);
173
174 return 0;
175}
176
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300177static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16],
Marcel Holtmannf1560462013-10-13 05:43:25 -0700178 u8 preq[7], u8 pres[7], u8 _iat, bdaddr_t *ia,
179 u8 _rat, bdaddr_t *ra, u8 res[16])
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300180{
181 u8 p1[16], p2[16];
182 int err;
183
184 memset(p1, 0, 16);
185
186 /* p1 = pres || preq || _rat || _iat */
Johan Hedberg943a7322014-03-18 12:58:24 +0200187 p1[0] = _iat;
188 p1[1] = _rat;
189 memcpy(p1 + 2, preq, 7);
190 memcpy(p1 + 9, pres, 7);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300191
192 /* p2 = padding || ia || ra */
Johan Hedberg943a7322014-03-18 12:58:24 +0200193 memcpy(p2, ra, 6);
194 memcpy(p2 + 6, ia, 6);
195 memset(p2 + 12, 0, 4);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300196
197 /* res = r XOR p1 */
198 u128_xor((u128 *) res, (u128 *) r, (u128 *) p1);
199
200 /* res = e(k, res) */
201 err = smp_e(tfm, k, res);
202 if (err) {
203 BT_ERR("Encrypt data error");
204 return err;
205 }
206
207 /* res = res XOR p2 */
208 u128_xor((u128 *) res, (u128 *) res, (u128 *) p2);
209
210 /* res = e(k, res) */
211 err = smp_e(tfm, k, res);
212 if (err)
213 BT_ERR("Encrypt data error");
214
215 return err;
216}
217
Marcel Holtmannf1560462013-10-13 05:43:25 -0700218static int smp_s1(struct crypto_blkcipher *tfm, u8 k[16], u8 r1[16],
219 u8 r2[16], u8 _r[16])
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300220{
221 int err;
222
223 /* Just least significant octets from r1 and r2 are considered */
Johan Hedberg943a7322014-03-18 12:58:24 +0200224 memcpy(_r, r2, 8);
225 memcpy(_r + 8, r1, 8);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300226
227 err = smp_e(tfm, k, _r);
228 if (err)
229 BT_ERR("Encrypt data error");
230
231 return err;
232}
233
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300234static struct sk_buff *smp_build_cmd(struct l2cap_conn *conn, u8 code,
Marcel Holtmannf1560462013-10-13 05:43:25 -0700235 u16 dlen, void *data)
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300236{
237 struct sk_buff *skb;
238 struct l2cap_hdr *lh;
239 int len;
240
241 len = L2CAP_HDR_SIZE + sizeof(code) + dlen;
242
243 if (len > conn->mtu)
244 return NULL;
245
246 skb = bt_skb_alloc(len, GFP_ATOMIC);
247 if (!skb)
248 return NULL;
249
250 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
251 lh->len = cpu_to_le16(sizeof(code) + dlen);
Joe Perchesdcf4adb2014-03-12 10:52:35 -0700252 lh->cid = cpu_to_le16(L2CAP_CID_SMP);
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300253
254 memcpy(skb_put(skb, sizeof(code)), &code, sizeof(code));
255
256 memcpy(skb_put(skb, dlen), data, dlen);
257
258 return skb;
259}
260
261static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
262{
263 struct sk_buff *skb = smp_build_cmd(conn, code, len, data);
264
265 BT_DBG("code 0x%2.2x", code);
266
267 if (!skb)
268 return;
269
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200270 skb->priority = HCI_PRIO_MAX;
271 hci_send_acl(conn->hchan, skb, 0);
Vinicius Costa Gomese2dcd112011-08-19 21:06:50 -0300272
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -0200273 cancel_delayed_work_sync(&conn->security_timer);
Marcel Holtmann17b02e62012-03-01 14:32:37 -0800274 schedule_delayed_work(&conn->security_timer, SMP_TIMEOUT);
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300275}
276
Brian Gix2b64d152011-12-21 16:12:12 -0800277static __u8 authreq_to_seclevel(__u8 authreq)
278{
279 if (authreq & SMP_AUTH_MITM)
280 return BT_SECURITY_HIGH;
281 else
282 return BT_SECURITY_MEDIUM;
283}
284
285static __u8 seclevel_to_authreq(__u8 sec_level)
286{
287 switch (sec_level) {
288 case BT_SECURITY_HIGH:
289 return SMP_AUTH_MITM | SMP_AUTH_BONDING;
290 case BT_SECURITY_MEDIUM:
291 return SMP_AUTH_BONDING;
292 default:
293 return SMP_AUTH_NONE;
294 }
295}
296
Vinicius Costa Gomesb8e66ea2011-06-09 18:50:52 -0300297static void build_pairing_cmd(struct l2cap_conn *conn,
Marcel Holtmannf1560462013-10-13 05:43:25 -0700298 struct smp_cmd_pairing *req,
299 struct smp_cmd_pairing *rsp, __u8 authreq)
Vinicius Costa Gomesb8e66ea2011-06-09 18:50:52 -0300300{
Johan Hedbergfd349c02014-02-18 10:19:36 +0200301 struct smp_chan *smp = conn->smp_chan;
302 struct hci_conn *hcon = conn->hcon;
303 struct hci_dev *hdev = hcon->hdev;
304 u8 local_dist = 0, remote_dist = 0;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300305
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200306 if (test_bit(HCI_PAIRABLE, &conn->hcon->hdev->dev_flags)) {
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -0700307 local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
308 remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300309 authreq |= SMP_AUTH_BONDING;
Brian Gix2b64d152011-12-21 16:12:12 -0800310 } else {
311 authreq &= ~SMP_AUTH_BONDING;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300312 }
313
Johan Hedbergfd349c02014-02-18 10:19:36 +0200314 if (test_bit(HCI_RPA_RESOLVING, &hdev->dev_flags))
315 remote_dist |= SMP_DIST_ID_KEY;
316
Johan Hedberg863efaf2014-02-22 19:06:32 +0200317 if (test_bit(HCI_PRIVACY, &hdev->dev_flags))
318 local_dist |= SMP_DIST_ID_KEY;
319
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300320 if (rsp == NULL) {
321 req->io_capability = conn->hcon->io_capability;
322 req->oob_flag = SMP_OOB_NOT_PRESENT;
323 req->max_key_size = SMP_MAX_ENC_KEY_SIZE;
Johan Hedbergfd349c02014-02-18 10:19:36 +0200324 req->init_key_dist = local_dist;
325 req->resp_key_dist = remote_dist;
Johan Hedberg065a13e2012-10-11 16:26:06 +0200326 req->auth_req = (authreq & AUTH_REQ_MASK);
Johan Hedbergfd349c02014-02-18 10:19:36 +0200327
328 smp->remote_key_dist = remote_dist;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300329 return;
330 }
331
332 rsp->io_capability = conn->hcon->io_capability;
333 rsp->oob_flag = SMP_OOB_NOT_PRESENT;
334 rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE;
Johan Hedbergfd349c02014-02-18 10:19:36 +0200335 rsp->init_key_dist = req->init_key_dist & remote_dist;
336 rsp->resp_key_dist = req->resp_key_dist & local_dist;
Johan Hedberg065a13e2012-10-11 16:26:06 +0200337 rsp->auth_req = (authreq & AUTH_REQ_MASK);
Johan Hedbergfd349c02014-02-18 10:19:36 +0200338
339 smp->remote_key_dist = rsp->init_key_dist;
Vinicius Costa Gomesb8e66ea2011-06-09 18:50:52 -0300340}
341
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300342static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
343{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300344 struct smp_chan *smp = conn->smp_chan;
345
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300346 if ((max_key_size > SMP_MAX_ENC_KEY_SIZE) ||
Marcel Holtmannf1560462013-10-13 05:43:25 -0700347 (max_key_size < SMP_MIN_ENC_KEY_SIZE))
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300348 return SMP_ENC_KEY_SIZE;
349
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300350 smp->enc_key_size = max_key_size;
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300351
352 return 0;
353}
354
Johan Hedberg84794e12013-11-06 11:24:57 +0200355static void smp_failure(struct l2cap_conn *conn, u8 reason)
Brian Gix4f957a72011-11-23 08:28:36 -0800356{
Johan Hedbergbab73cb2012-02-09 16:07:29 +0200357 struct hci_conn *hcon = conn->hcon;
358
Johan Hedberg84794e12013-11-06 11:24:57 +0200359 if (reason)
Brian Gix4f957a72011-11-23 08:28:36 -0800360 smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
Marcel Holtmannf1560462013-10-13 05:43:25 -0700361 &reason);
Brian Gix4f957a72011-11-23 08:28:36 -0800362
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700363 clear_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags);
364 mgmt_auth_failed(hcon->hdev, &hcon->dst, hcon->type, hcon->dst_type,
365 HCI_ERROR_AUTH_FAILURE);
Vinicius Costa Gomesf1c09c02012-02-01 18:27:56 -0300366
Andre Guedes61a0cfb2012-08-01 20:34:15 -0300367 cancel_delayed_work_sync(&conn->security_timer);
368
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700369 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesf1c09c02012-02-01 18:27:56 -0300370 smp_chan_destroy(conn);
Brian Gix4f957a72011-11-23 08:28:36 -0800371}
372
Brian Gix2b64d152011-12-21 16:12:12 -0800373#define JUST_WORKS 0x00
374#define JUST_CFM 0x01
375#define REQ_PASSKEY 0x02
376#define CFM_PASSKEY 0x03
377#define REQ_OOB 0x04
378#define OVERLAP 0xFF
379
380static const u8 gen_method[5][5] = {
381 { JUST_WORKS, JUST_CFM, REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
382 { JUST_WORKS, JUST_CFM, REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
383 { CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
384 { JUST_WORKS, JUST_CFM, JUST_WORKS, JUST_WORKS, JUST_CFM },
385 { CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, OVERLAP },
386};
387
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));
Johan Hedberg4a74d652014-05-20 09:45:50 +0300399 clear_bit(SMP_FLAG_TK_VALID, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800400
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 */
Johan Hedberg4a74d652014-05-20 09:45:50 +0300418 if (method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR, &smp->flags))
Johan Hedberga82505c2014-03-24 14:39:07 +0200419 method = JUST_WORKS;
420
Brian Gix2b64d152011-12-21 16:12:12 -0800421 /* If Just Works, Continue with Zero TK */
422 if (method == JUST_WORKS) {
Johan Hedberg4a74d652014-05-20 09:45:50 +0300423 set_bit(SMP_FLAG_TK_VALID, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800424 return 0;
425 }
426
427 /* Not Just Works/Confirm results in MITM Authentication */
428 if (method != JUST_CFM)
Johan Hedberg4a74d652014-05-20 09:45:50 +0300429 set_bit(SMP_FLAG_MITM_AUTH, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800430
431 /* If both devices have Keyoard-Display I/O, the master
432 * Confirms and the slave Enters the passkey.
433 */
434 if (method == OVERLAP) {
435 if (hcon->link_mode & HCI_LM_MASTER)
436 method = CFM_PASSKEY;
437 else
438 method = REQ_PASSKEY;
439 }
440
Johan Hedberg01ad34d2014-03-19 14:14:53 +0200441 /* Generate random passkey. */
Brian Gix2b64d152011-12-21 16:12:12 -0800442 if (method == CFM_PASSKEY) {
Johan Hedberg943a7322014-03-18 12:58:24 +0200443 memset(smp->tk, 0, sizeof(smp->tk));
Brian Gix2b64d152011-12-21 16:12:12 -0800444 get_random_bytes(&passkey, sizeof(passkey));
445 passkey %= 1000000;
Johan Hedberg943a7322014-03-18 12:58:24 +0200446 put_unaligned_le32(passkey, smp->tk);
Brian Gix2b64d152011-12-21 16:12:12 -0800447 BT_DBG("PassKey: %d", passkey);
Johan Hedberg4a74d652014-05-20 09:45:50 +0300448 set_bit(SMP_FLAG_TK_VALID, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800449 }
450
451 hci_dev_lock(hcon->hdev);
452
453 if (method == REQ_PASSKEY)
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700454 ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200455 hcon->type, hcon->dst_type);
Johan Hedberg4eb65e62014-03-24 14:39:05 +0200456 else if (method == JUST_CFM)
457 ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
458 hcon->type, hcon->dst_type,
459 passkey, 1);
Brian Gix2b64d152011-12-21 16:12:12 -0800460 else
Johan Hedberg01ad34d2014-03-19 14:14:53 +0200461 ret = mgmt_user_passkey_notify(hcon->hdev, &hcon->dst,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200462 hcon->type, hcon->dst_type,
Johan Hedberg39adbff2014-03-20 08:18:14 +0200463 passkey, 0);
Brian Gix2b64d152011-12-21 16:12:12 -0800464
465 hci_dev_unlock(hcon->hdev);
466
467 return ret;
468}
469
Johan Hedberg9dd4dd22014-05-20 09:45:49 +0300470static void smp_confirm(struct smp_chan *smp)
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300471{
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300472 struct l2cap_conn *conn = smp->conn;
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200473 struct hci_dev *hdev = conn->hcon->hdev;
474 struct crypto_blkcipher *tfm = hdev->tfm_aes;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300475 struct smp_cmd_pairing_confirm cp;
476 int ret;
Johan Hedberg943a7322014-03-18 12:58:24 +0200477 u8 reason;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300478
479 BT_DBG("conn %p", conn);
480
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200481 /* Prevent mutual access to hdev->tfm_aes */
482 hci_dev_lock(hdev);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300483
Johan Hedbergb1cd5fd2014-02-28 12:54:17 +0200484 ret = smp_c1(tfm, smp->tk, smp->prnd, smp->preq, smp->prsp,
485 conn->hcon->init_addr_type, &conn->hcon->init_addr,
Johan Hedberg943a7322014-03-18 12:58:24 +0200486 conn->hcon->resp_addr_type, &conn->hcon->resp_addr,
487 cp.confirm_val);
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200488
489 hci_dev_unlock(hdev);
490
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300491 if (ret) {
492 reason = SMP_UNSPECIFIED;
493 goto error;
494 }
495
Johan Hedberg4a74d652014-05-20 09:45:50 +0300496 clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800497
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300498 smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
499
500 return;
501
502error:
Johan Hedberg84794e12013-11-06 11:24:57 +0200503 smp_failure(conn, reason);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300504}
505
Johan Hedberg861580a2014-05-20 09:45:51 +0300506static u8 smp_random(struct smp_chan *smp)
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300507{
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300508 struct l2cap_conn *conn = smp->conn;
509 struct hci_conn *hcon = conn->hcon;
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200510 struct hci_dev *hdev = hcon->hdev;
511 struct crypto_blkcipher *tfm = hdev->tfm_aes;
Johan Hedberg861580a2014-05-20 09:45:51 +0300512 u8 confirm[16];
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300513 int ret;
514
Johan Hedberg861580a2014-05-20 09:45:51 +0300515 if (IS_ERR_OR_NULL(tfm))
516 return SMP_UNSPECIFIED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300517
518 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
519
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200520 /* Prevent mutual access to hdev->tfm_aes */
521 hci_dev_lock(hdev);
522
Johan Hedbergb1cd5fd2014-02-28 12:54:17 +0200523 ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp,
524 hcon->init_addr_type, &hcon->init_addr,
Johan Hedberg943a7322014-03-18 12:58:24 +0200525 hcon->resp_addr_type, &hcon->resp_addr, confirm);
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200526
527 hci_dev_unlock(hdev);
528
Johan Hedberg861580a2014-05-20 09:45:51 +0300529 if (ret)
530 return SMP_UNSPECIFIED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300531
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300532 if (memcmp(smp->pcnf, confirm, sizeof(smp->pcnf)) != 0) {
533 BT_ERR("Pairing failed (confirmation values mismatch)");
Johan Hedberg861580a2014-05-20 09:45:51 +0300534 return SMP_CONFIRM_FAILED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300535 }
536
537 if (hcon->out) {
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -0800538 u8 stk[16];
539 __le64 rand = 0;
540 __le16 ediv = 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300541
Johan Hedberg943a7322014-03-18 12:58:24 +0200542 smp_s1(tfm, smp->tk, smp->rrnd, smp->prnd, stk);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300543
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300544 memset(stk + smp->enc_key_size, 0,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300545 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300546
Johan Hedberg861580a2014-05-20 09:45:51 +0300547 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
548 return SMP_UNSPECIFIED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300549
550 hci_le_start_enc(hcon, ediv, rand, stk);
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300551 hcon->enc_key_size = smp->enc_key_size;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300552 } else {
Johan Hedberg943a7322014-03-18 12:58:24 +0200553 u8 stk[16];
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -0800554 __le64 rand = 0;
555 __le16 ediv = 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300556
Johan Hedberg943a7322014-03-18 12:58:24 +0200557 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
558 smp->prnd);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300559
Johan Hedberg943a7322014-03-18 12:58:24 +0200560 smp_s1(tfm, smp->tk, smp->prnd, smp->rrnd, stk);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300561
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300562 memset(stk + smp->enc_key_size, 0,
Marcel Holtmannf1560462013-10-13 05:43:25 -0700563 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300564
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700565 hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
Johan Hedberg35d70272014-02-19 14:57:47 +0200566 HCI_SMP_STK_SLAVE, 0, stk, smp->enc_key_size,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300567 ediv, rand);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300568 }
569
Johan Hedberg861580a2014-05-20 09:45:51 +0300570 return 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300571}
572
573static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
574{
575 struct smp_chan *smp;
576
Marcel Holtmannf1560462013-10-13 05:43:25 -0700577 smp = kzalloc(sizeof(*smp), GFP_ATOMIC);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300578 if (!smp)
579 return NULL;
580
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300581 smp->conn = conn;
582 conn->smp_chan = smp;
Brian Gix2b64d152011-12-21 16:12:12 -0800583 conn->hcon->smp_conn = conn;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300584
585 hci_conn_hold(conn->hcon);
586
587 return smp;
588}
589
590void smp_chan_destroy(struct l2cap_conn *conn)
591{
Brian Gixc8eb9692011-11-23 08:28:35 -0800592 struct smp_chan *smp = conn->smp_chan;
Johan Hedbergf4a407be2014-02-18 21:41:34 +0200593 bool complete;
Brian Gixc8eb9692011-11-23 08:28:35 -0800594
Vinicius Costa Gomesf1c09c02012-02-01 18:27:56 -0300595 BUG_ON(!smp);
Brian Gixc8eb9692011-11-23 08:28:35 -0800596
Johan Hedberg4a74d652014-05-20 09:45:50 +0300597 complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags);
Johan Hedbergf4a407be2014-02-18 21:41:34 +0200598 mgmt_smp_complete(conn->hcon, complete);
599
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -0700600 kfree(smp->csrk);
601 kfree(smp->slave_csrk);
602
Johan Hedberg759331d2014-02-28 10:10:16 +0200603 /* If pairing failed clean up any keys we might have */
604 if (!complete) {
605 if (smp->ltk) {
606 list_del(&smp->ltk->list);
607 kfree(smp->ltk);
608 }
609
610 if (smp->slave_ltk) {
611 list_del(&smp->slave_ltk->list);
612 kfree(smp->slave_ltk);
613 }
614
615 if (smp->remote_irk) {
616 list_del(&smp->remote_irk->list);
617 kfree(smp->remote_irk);
618 }
619 }
620
Brian Gixc8eb9692011-11-23 08:28:35 -0800621 kfree(smp);
622 conn->smp_chan = NULL;
Brian Gix2b64d152011-12-21 16:12:12 -0800623 conn->hcon->smp_conn = NULL;
David Herrmann76a68ba2013-04-06 20:28:37 +0200624 hci_conn_drop(conn->hcon);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300625}
626
Brian Gix2b64d152011-12-21 16:12:12 -0800627int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
628{
629 struct l2cap_conn *conn = hcon->smp_conn;
630 struct smp_chan *smp;
631 u32 value;
Brian Gix2b64d152011-12-21 16:12:12 -0800632
633 BT_DBG("");
634
635 if (!conn)
636 return -ENOTCONN;
637
638 smp = conn->smp_chan;
639
640 switch (mgmt_op) {
641 case MGMT_OP_USER_PASSKEY_REPLY:
642 value = le32_to_cpu(passkey);
Johan Hedberg943a7322014-03-18 12:58:24 +0200643 memset(smp->tk, 0, sizeof(smp->tk));
Brian Gix2b64d152011-12-21 16:12:12 -0800644 BT_DBG("PassKey: %d", value);
Johan Hedberg943a7322014-03-18 12:58:24 +0200645 put_unaligned_le32(value, smp->tk);
Brian Gix2b64d152011-12-21 16:12:12 -0800646 /* Fall Through */
647 case MGMT_OP_USER_CONFIRM_REPLY:
Johan Hedberg4a74d652014-05-20 09:45:50 +0300648 set_bit(SMP_FLAG_TK_VALID, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800649 break;
650 case MGMT_OP_USER_PASSKEY_NEG_REPLY:
651 case MGMT_OP_USER_CONFIRM_NEG_REPLY:
Johan Hedberg84794e12013-11-06 11:24:57 +0200652 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
Brian Gix2b64d152011-12-21 16:12:12 -0800653 return 0;
654 default:
Johan Hedberg84794e12013-11-06 11:24:57 +0200655 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
Brian Gix2b64d152011-12-21 16:12:12 -0800656 return -EOPNOTSUPP;
657 }
658
659 /* If it is our turn to send Pairing Confirm, do so now */
Johan Hedberg4a74d652014-05-20 09:45:50 +0300660 if (test_bit(SMP_FLAG_CFM_PENDING, &smp->flags))
Johan Hedberg9dd4dd22014-05-20 09:45:49 +0300661 smp_confirm(smp);
Brian Gix2b64d152011-12-21 16:12:12 -0800662
663 return 0;
664}
665
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300666static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300667{
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300668 struct smp_cmd_pairing rsp, *req = (void *) skb->data;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300669 struct smp_chan *smp;
Johan Hedberg1ef35822014-05-20 09:45:48 +0300670 u8 key_size, auth;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300671 int ret;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300672
673 BT_DBG("conn %p", conn);
674
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200675 if (skb->len < sizeof(*req))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300676 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200677
Brian Gix2b64d152011-12-21 16:12:12 -0800678 if (conn->hcon->link_mode & HCI_LM_MASTER)
679 return SMP_CMD_NOTSUPP;
680
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200681 if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags))
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300682 smp = smp_chan_create(conn);
Andrei Emeltchenkod08fd0e2012-07-19 17:03:43 +0300683 else
684 smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300685
Andrei Emeltchenkod08fd0e2012-07-19 17:03:43 +0300686 if (!smp)
687 return SMP_UNSPECIFIED;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300688
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300689 smp->preq[0] = SMP_CMD_PAIRING_REQ;
690 memcpy(&smp->preq[1], req, sizeof(*req));
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300691 skb_pull(skb, sizeof(*req));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300692
Brian Gix2b64d152011-12-21 16:12:12 -0800693 /* We didn't start the pairing, so match remote */
Johan Hedberg1ef35822014-05-20 09:45:48 +0300694 auth = req->auth_req;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300695
Ido Yarivfdde0a22012-03-05 20:09:38 +0200696 conn->hcon->pending_sec_level = authreq_to_seclevel(auth);
697
Brian Gix2b64d152011-12-21 16:12:12 -0800698 build_pairing_cmd(conn, req, &rsp, auth);
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300699
700 key_size = min(req->max_key_size, rsp.max_key_size);
701 if (check_enc_key_size(conn, key_size))
702 return SMP_ENC_KEY_SIZE;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300703
Johan Hedberge84a6b12013-12-02 10:49:03 +0200704 get_random_bytes(smp->prnd, sizeof(smp->prnd));
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300705
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300706 smp->prsp[0] = SMP_CMD_PAIRING_RSP;
707 memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300708
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300709 smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300710
Brian Gix2b64d152011-12-21 16:12:12 -0800711 /* Request setup of TK */
712 ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability);
713 if (ret)
714 return SMP_UNSPECIFIED;
715
Johan Hedberg4a74d652014-05-20 09:45:50 +0300716 clear_bit(SMP_FLAG_INITIATOR, &smp->flags);
Johan Hedbergedca7922014-03-24 15:54:11 +0200717
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300718 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300719}
720
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300721static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300722{
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300723 struct smp_cmd_pairing *req, *rsp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300724 struct smp_chan *smp = conn->smp_chan;
Brian Gix2b64d152011-12-21 16:12:12 -0800725 u8 key_size, auth = SMP_AUTH_NONE;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300726 int ret;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300727
728 BT_DBG("conn %p", conn);
729
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200730 if (skb->len < sizeof(*rsp))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300731 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200732
Brian Gix2b64d152011-12-21 16:12:12 -0800733 if (!(conn->hcon->link_mode & HCI_LM_MASTER))
734 return SMP_CMD_NOTSUPP;
735
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300736 skb_pull(skb, sizeof(*rsp));
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300737
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300738 req = (void *) &smp->preq[1];
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300739
740 key_size = min(req->max_key_size, rsp->max_key_size);
741 if (check_enc_key_size(conn, key_size))
742 return SMP_ENC_KEY_SIZE;
743
Johan Hedberge84a6b12013-12-02 10:49:03 +0200744 get_random_bytes(smp->prnd, sizeof(smp->prnd));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300745
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300746 smp->prsp[0] = SMP_CMD_PAIRING_RSP;
747 memcpy(&smp->prsp[1], rsp, sizeof(*rsp));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300748
Johan Hedbergfdcc4be2014-03-14 10:53:50 +0200749 /* Update remote key distribution in case the remote cleared
750 * some bits that we had enabled in our request.
751 */
752 smp->remote_key_dist &= rsp->resp_key_dist;
753
Brian Gix2b64d152011-12-21 16:12:12 -0800754 if ((req->auth_req & SMP_AUTH_BONDING) &&
Marcel Holtmannf1560462013-10-13 05:43:25 -0700755 (rsp->auth_req & SMP_AUTH_BONDING))
Brian Gix2b64d152011-12-21 16:12:12 -0800756 auth = SMP_AUTH_BONDING;
757
758 auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM;
759
Johan Hedberg476585e2012-06-06 18:54:15 +0800760 ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability);
Brian Gix2b64d152011-12-21 16:12:12 -0800761 if (ret)
762 return SMP_UNSPECIFIED;
763
Johan Hedberg4a74d652014-05-20 09:45:50 +0300764 set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800765
766 /* Can't compose response until we have been confirmed */
Johan Hedberg4a74d652014-05-20 09:45:50 +0300767 if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
Johan Hedberg9dd4dd22014-05-20 09:45:49 +0300768 smp_confirm(smp);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300769
770 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300771}
772
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300773static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300774{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300775 struct smp_chan *smp = conn->smp_chan;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300776
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300777 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
778
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200779 if (skb->len < sizeof(smp->pcnf))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300780 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200781
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300782 memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf));
783 skb_pull(skb, sizeof(smp->pcnf));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300784
Johan Hedberg943a7322014-03-18 12:58:24 +0200785 if (conn->hcon->out)
786 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
787 smp->prnd);
Johan Hedberg4a74d652014-05-20 09:45:50 +0300788 else if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
Johan Hedberg9dd4dd22014-05-20 09:45:49 +0300789 smp_confirm(smp);
Johan Hedberg943a7322014-03-18 12:58:24 +0200790 else
Johan Hedberg4a74d652014-05-20 09:45:50 +0300791 set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300792
793 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300794}
795
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300796static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300797{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300798 struct smp_chan *smp = conn->smp_chan;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300799
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300800 BT_DBG("conn %p", conn);
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300801
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200802 if (skb->len < sizeof(smp->rrnd))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300803 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200804
Johan Hedberg943a7322014-03-18 12:58:24 +0200805 memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd));
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300806 skb_pull(skb, sizeof(smp->rrnd));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300807
Johan Hedberg861580a2014-05-20 09:45:51 +0300808 return smp_random(smp);
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300809}
810
Johan Hedberg4dab7862012-06-07 14:58:37 +0800811static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300812{
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300813 struct smp_ltk *key;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300814 struct hci_conn *hcon = conn->hcon;
815
Johan Hedberg98a0b842014-01-30 19:40:00 -0800816 key = hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type,
817 hcon->out);
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300818 if (!key)
819 return 0;
820
Johan Hedberg4dab7862012-06-07 14:58:37 +0800821 if (sec_level > BT_SECURITY_MEDIUM && !key->authenticated)
822 return 0;
823
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200824 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300825 return 1;
826
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300827 hci_le_start_enc(hcon, key->ediv, key->rand, key->val);
828 hcon->enc_key_size = key->enc_size;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300829
830 return 1;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300831}
Marcel Holtmannf1560462013-10-13 05:43:25 -0700832
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300833static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300834{
835 struct smp_cmd_security_req *rp = (void *) skb->data;
836 struct smp_cmd_pairing cp;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300837 struct hci_conn *hcon = conn->hcon;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300838 struct smp_chan *smp;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300839
840 BT_DBG("conn %p", conn);
841
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200842 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300843 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200844
Johan Hedberg86ca9ea2013-11-05 11:30:39 +0200845 if (!(conn->hcon->link_mode & HCI_LM_MASTER))
846 return SMP_CMD_NOTSUPP;
847
Brian Gix2b64d152011-12-21 16:12:12 -0800848 hcon->pending_sec_level = authreq_to_seclevel(rp->auth_req);
Vinicius Costa Gomesfeb45eb2011-08-25 20:02:35 -0300849
Johan Hedberg4dab7862012-06-07 14:58:37 +0800850 if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300851 return 0;
852
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200853 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300854 return 0;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300855
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300856 smp = smp_chan_create(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300857
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300858 skb_pull(skb, sizeof(*rp));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300859
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300860 memset(&cp, 0, sizeof(cp));
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300861 build_pairing_cmd(conn, &cp, NULL, rp->auth_req);
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300862
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300863 smp->preq[0] = SMP_CMD_PAIRING_REQ;
864 memcpy(&smp->preq[1], &cp, sizeof(cp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300865
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300866 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300867
Johan Hedberg4a74d652014-05-20 09:45:50 +0300868 clear_bit(SMP_FLAG_INITIATOR, &smp->flags);
Johan Hedbergedca7922014-03-24 15:54:11 +0200869
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300870 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300871}
872
Johan Hedbergad32a2f2013-05-14 18:05:12 +0300873bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level)
874{
875 if (sec_level == BT_SECURITY_LOW)
876 return true;
877
878 if (hcon->sec_level >= sec_level)
879 return true;
880
881 return false;
882}
883
Vinicius Costa Gomescc110922012-08-23 21:32:43 -0300884int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300885{
Vinicius Costa Gomescc110922012-08-23 21:32:43 -0300886 struct l2cap_conn *conn = hcon->l2cap_data;
Johan Hedberg0a66cf22014-03-24 14:39:03 +0200887 struct smp_chan *smp;
Brian Gix2b64d152011-12-21 16:12:12 -0800888 __u8 authreq;
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300889
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -0300890 BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
891
Johan Hedberg0a66cf22014-03-24 14:39:03 +0200892 /* This may be NULL if there's an unexpected disconnection */
893 if (!conn)
894 return 1;
895
Johan Hedberg757aee02013-04-24 13:05:32 +0300896 if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags))
Andre Guedes2e65c9d2011-06-30 19:20:56 -0300897 return 1;
898
Johan Hedbergad32a2f2013-05-14 18:05:12 +0300899 if (smp_sufficient_security(hcon, sec_level))
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300900 return 1;
901
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300902 if (hcon->link_mode & HCI_LM_MASTER)
Johan Hedberg4dab7862012-06-07 14:58:37 +0800903 if (smp_ltk_encrypt(conn, sec_level))
Vinicius Costa Gomes02bc7452011-07-07 18:59:41 -0300904 goto done;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300905
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200906 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300907 return 0;
908
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300909 smp = smp_chan_create(conn);
Brian Gix2b64d152011-12-21 16:12:12 -0800910 if (!smp)
911 return 1;
912
913 authreq = seclevel_to_authreq(sec_level);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300914
Johan Hedberg2e233642014-03-18 15:42:30 +0200915 /* hcon->auth_type is set by pair_device in mgmt.c. If the MITM
916 * flag is set we should also set it for the SMP request.
917 */
918 if ((hcon->auth_type & 0x01))
919 authreq |= SMP_AUTH_MITM;
920
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300921 if (hcon->link_mode & HCI_LM_MASTER) {
922 struct smp_cmd_pairing cp;
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300923
Brian Gix2b64d152011-12-21 16:12:12 -0800924 build_pairing_cmd(conn, &cp, NULL, authreq);
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300925 smp->preq[0] = SMP_CMD_PAIRING_REQ;
926 memcpy(&smp->preq[1], &cp, sizeof(cp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300927
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300928 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
929 } else {
930 struct smp_cmd_security_req cp;
Brian Gix2b64d152011-12-21 16:12:12 -0800931 cp.auth_req = authreq;
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300932 smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
933 }
934
Johan Hedberg4a74d652014-05-20 09:45:50 +0300935 set_bit(SMP_FLAG_INITIATOR, &smp->flags);
Johan Hedbergedca7922014-03-24 15:54:11 +0200936
Johan Hedberg61b3b2b2014-03-24 17:36:25 +0200937done:
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300938 hcon->pending_sec_level = sec_level;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300939
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300940 return 0;
941}
942
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300943static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
944{
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300945 struct smp_cmd_encrypt_info *rp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300946 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300947
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200948 BT_DBG("conn %p", conn);
949
950 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300951 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200952
Johan Hedberg6131ddc2014-02-18 10:19:37 +0200953 /* Ignore this PDU if it wasn't requested */
954 if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
955 return 0;
956
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300957 skb_pull(skb, sizeof(*rp));
958
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300959 memcpy(smp->tk, rp->ltk, sizeof(smp->tk));
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300960
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300961 return 0;
962}
963
964static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
965{
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300966 struct smp_cmd_master_ident *rp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300967 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300968 struct hci_dev *hdev = conn->hcon->hdev;
969 struct hci_conn *hcon = conn->hcon;
Johan Hedberg23d0e122014-02-19 14:57:46 +0200970 struct smp_ltk *ltk;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300971 u8 authenticated;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300972
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200973 BT_DBG("conn %p", conn);
974
975 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300976 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200977
Johan Hedberg6131ddc2014-02-18 10:19:37 +0200978 /* Ignore this PDU if it wasn't requested */
979 if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
980 return 0;
981
Johan Hedberg9747a9f2014-02-26 23:33:43 +0200982 /* Mark the information as received */
983 smp->remote_key_dist &= ~SMP_DIST_ENC_KEY;
984
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300985 skb_pull(skb, sizeof(*rp));
986
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300987 hci_dev_lock(hdev);
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700988 authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
Johan Hedberg35d70272014-02-19 14:57:47 +0200989 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, HCI_SMP_LTK,
Johan Hedberg23d0e122014-02-19 14:57:46 +0200990 authenticated, smp->tk, smp->enc_key_size,
991 rp->ediv, rp->rand);
992 smp->ltk = ltk;
Johan Hedbergfd349c02014-02-18 10:19:36 +0200993 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
Johan Hedberg4bd6d382014-02-26 23:33:45 +0200994 smp_distribute_keys(conn);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300995 hci_dev_unlock(hdev);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300996
997 return 0;
998}
999
Johan Hedbergfd349c02014-02-18 10:19:36 +02001000static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
1001{
1002 struct smp_cmd_ident_info *info = (void *) skb->data;
1003 struct smp_chan *smp = conn->smp_chan;
1004
1005 BT_DBG("");
1006
1007 if (skb->len < sizeof(*info))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001008 return SMP_INVALID_PARAMS;
Johan Hedbergfd349c02014-02-18 10:19:36 +02001009
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001010 /* Ignore this PDU if it wasn't requested */
1011 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
1012 return 0;
1013
Johan Hedbergfd349c02014-02-18 10:19:36 +02001014 skb_pull(skb, sizeof(*info));
1015
1016 memcpy(smp->irk, info->irk, 16);
1017
1018 return 0;
1019}
1020
1021static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
1022 struct sk_buff *skb)
1023{
1024 struct smp_cmd_ident_addr_info *info = (void *) skb->data;
1025 struct smp_chan *smp = conn->smp_chan;
1026 struct hci_conn *hcon = conn->hcon;
1027 bdaddr_t rpa;
1028
1029 BT_DBG("");
1030
1031 if (skb->len < sizeof(*info))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001032 return SMP_INVALID_PARAMS;
Johan Hedbergfd349c02014-02-18 10:19:36 +02001033
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001034 /* Ignore this PDU if it wasn't requested */
1035 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
1036 return 0;
1037
Johan Hedberg9747a9f2014-02-26 23:33:43 +02001038 /* Mark the information as received */
1039 smp->remote_key_dist &= ~SMP_DIST_ID_KEY;
1040
Johan Hedbergfd349c02014-02-18 10:19:36 +02001041 skb_pull(skb, sizeof(*info));
1042
Johan Hedberga9a58f82014-02-25 22:24:37 +02001043 /* Strictly speaking the Core Specification (4.1) allows sending
1044 * an empty address which would force us to rely on just the IRK
1045 * as "identity information". However, since such
1046 * implementations are not known of and in order to not over
1047 * complicate our implementation, simply pretend that we never
1048 * received an IRK for such a device.
1049 */
1050 if (!bacmp(&info->bdaddr, BDADDR_ANY)) {
1051 BT_ERR("Ignoring IRK with no identity address");
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001052 smp_distribute_keys(conn);
Johan Hedberga9a58f82014-02-25 22:24:37 +02001053 return 0;
1054 }
1055
Johan Hedbergfd349c02014-02-18 10:19:36 +02001056 bacpy(&smp->id_addr, &info->bdaddr);
1057 smp->id_addr_type = info->addr_type;
1058
1059 if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type))
1060 bacpy(&rpa, &hcon->dst);
1061 else
1062 bacpy(&rpa, BDADDR_ANY);
1063
Johan Hedberg23d0e122014-02-19 14:57:46 +02001064 smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
1065 smp->id_addr_type, smp->irk, &rpa);
Johan Hedbergfd349c02014-02-18 10:19:36 +02001066
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001067 smp_distribute_keys(conn);
Johan Hedbergfd349c02014-02-18 10:19:36 +02001068
1069 return 0;
1070}
1071
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001072static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)
1073{
1074 struct smp_cmd_sign_info *rp = (void *) skb->data;
1075 struct smp_chan *smp = conn->smp_chan;
1076 struct hci_dev *hdev = conn->hcon->hdev;
1077 struct smp_csrk *csrk;
1078
1079 BT_DBG("conn %p", conn);
1080
1081 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001082 return SMP_INVALID_PARAMS;
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001083
1084 /* Ignore this PDU if it wasn't requested */
1085 if (!(smp->remote_key_dist & SMP_DIST_SIGN))
1086 return 0;
1087
1088 /* Mark the information as received */
1089 smp->remote_key_dist &= ~SMP_DIST_SIGN;
1090
1091 skb_pull(skb, sizeof(*rp));
1092
1093 hci_dev_lock(hdev);
1094 csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
1095 if (csrk) {
1096 csrk->master = 0x01;
1097 memcpy(csrk->val, rp->csrk, sizeof(csrk->val));
1098 }
1099 smp->csrk = csrk;
1100 if (!(smp->remote_key_dist & SMP_DIST_SIGN))
1101 smp_distribute_keys(conn);
1102 hci_dev_unlock(hdev);
1103
1104 return 0;
1105}
1106
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001107int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
1108{
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001109 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann92381f52013-10-03 01:23:08 -07001110 __u8 code, reason;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001111 int err = 0;
1112
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001113 if (hcon->type != LE_LINK) {
1114 kfree_skb(skb);
Johan Hedberg34327112013-10-16 11:37:01 +03001115 return 0;
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001116 }
1117
Marcel Holtmann92381f52013-10-03 01:23:08 -07001118 if (skb->len < 1) {
1119 kfree_skb(skb);
1120 return -EILSEQ;
1121 }
1122
Marcel Holtmann06ae3312013-10-18 03:43:00 -07001123 if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) {
Andre Guedes2e65c9d2011-06-30 19:20:56 -03001124 err = -ENOTSUPP;
1125 reason = SMP_PAIRING_NOTSUPP;
1126 goto done;
1127 }
1128
Marcel Holtmann92381f52013-10-03 01:23:08 -07001129 code = skb->data[0];
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001130 skb_pull(skb, sizeof(code));
1131
Johan Hedberg8cf9fa12013-01-29 10:44:23 -06001132 /*
1133 * The SMP context must be initialized for all other PDUs except
1134 * pairing and security requests. If we get any other PDU when
1135 * not initialized simply disconnect (done if this function
1136 * returns an error).
1137 */
1138 if (code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ &&
1139 !conn->smp_chan) {
1140 BT_ERR("Unexpected SMP command 0x%02x. Disconnecting.", code);
1141 kfree_skb(skb);
1142 return -ENOTSUPP;
1143 }
1144
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001145 switch (code) {
1146 case SMP_CMD_PAIRING_REQ:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001147 reason = smp_cmd_pairing_req(conn, skb);
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001148 break;
1149
1150 case SMP_CMD_PAIRING_FAIL:
Johan Hedberg84794e12013-11-06 11:24:57 +02001151 smp_failure(conn, 0);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001152 reason = 0;
1153 err = -EPERM;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001154 break;
1155
1156 case SMP_CMD_PAIRING_RSP:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001157 reason = smp_cmd_pairing_rsp(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001158 break;
1159
1160 case SMP_CMD_SECURITY_REQ:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001161 reason = smp_cmd_security_req(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001162 break;
1163
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001164 case SMP_CMD_PAIRING_CONFIRM:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001165 reason = smp_cmd_pairing_confirm(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001166 break;
1167
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001168 case SMP_CMD_PAIRING_RANDOM:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001169 reason = smp_cmd_pairing_random(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001170 break;
1171
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001172 case SMP_CMD_ENCRYPT_INFO:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001173 reason = smp_cmd_encrypt_info(conn, skb);
1174 break;
1175
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001176 case SMP_CMD_MASTER_IDENT:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001177 reason = smp_cmd_master_ident(conn, skb);
1178 break;
1179
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001180 case SMP_CMD_IDENT_INFO:
Johan Hedbergfd349c02014-02-18 10:19:36 +02001181 reason = smp_cmd_ident_info(conn, skb);
1182 break;
1183
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001184 case SMP_CMD_IDENT_ADDR_INFO:
Johan Hedbergfd349c02014-02-18 10:19:36 +02001185 reason = smp_cmd_ident_addr_info(conn, skb);
1186 break;
1187
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001188 case SMP_CMD_SIGN_INFO:
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001189 reason = smp_cmd_sign_info(conn, skb);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001190 break;
1191
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001192 default:
1193 BT_DBG("Unknown command code 0x%2.2x", code);
1194
1195 reason = SMP_CMD_NOTSUPP;
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -03001196 err = -EOPNOTSUPP;
1197 goto done;
1198 }
1199
1200done:
1201 if (reason)
Johan Hedberg84794e12013-11-06 11:24:57 +02001202 smp_failure(conn, reason);
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001203
1204 kfree_skb(skb);
1205 return err;
1206}
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001207
Johan Hedberg35d70272014-02-19 14:57:47 +02001208static void smp_notify_keys(struct l2cap_conn *conn)
1209{
1210 struct smp_chan *smp = conn->smp_chan;
1211 struct hci_conn *hcon = conn->hcon;
1212 struct hci_dev *hdev = hcon->hdev;
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001213 struct smp_cmd_pairing *req = (void *) &smp->preq[1];
1214 struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1];
1215 bool persistent;
Johan Hedberg35d70272014-02-19 14:57:47 +02001216
Johan Hedberg61b1a7f2014-03-20 12:54:16 +02001217 if (smp->remote_irk) {
Johan Hedberg95fbac82014-02-19 15:18:31 +02001218 mgmt_new_irk(hdev, smp->remote_irk);
Johan Hedberg61b1a7f2014-03-20 12:54:16 +02001219 /* Now that user space can be considered to know the
1220 * identity address track the connection based on it
1221 * from now on.
1222 */
1223 bacpy(&hcon->dst, &smp->remote_irk->bdaddr);
1224 hcon->dst_type = smp->remote_irk->addr_type;
1225 l2cap_conn_update_id_addr(hcon);
1226 }
Johan Hedberg95fbac82014-02-19 15:18:31 +02001227
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001228 /* The LTKs and CSRKs should be persistent only if both sides
1229 * had the bonding bit set in their authentication requests.
1230 */
1231 persistent = !!((req->auth_req & rsp->auth_req) & SMP_AUTH_BONDING);
1232
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001233 if (smp->csrk) {
1234 smp->csrk->bdaddr_type = hcon->dst_type;
1235 bacpy(&smp->csrk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001236 mgmt_new_csrk(hdev, smp->csrk, persistent);
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001237 }
1238
1239 if (smp->slave_csrk) {
1240 smp->slave_csrk->bdaddr_type = hcon->dst_type;
1241 bacpy(&smp->slave_csrk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001242 mgmt_new_csrk(hdev, smp->slave_csrk, persistent);
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001243 }
1244
Johan Hedberg35d70272014-02-19 14:57:47 +02001245 if (smp->ltk) {
1246 smp->ltk->bdaddr_type = hcon->dst_type;
1247 bacpy(&smp->ltk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001248 mgmt_new_ltk(hdev, smp->ltk, persistent);
Johan Hedberg35d70272014-02-19 14:57:47 +02001249 }
1250
1251 if (smp->slave_ltk) {
1252 smp->slave_ltk->bdaddr_type = hcon->dst_type;
1253 bacpy(&smp->slave_ltk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001254 mgmt_new_ltk(hdev, smp->slave_ltk, persistent);
Johan Hedberg35d70272014-02-19 14:57:47 +02001255 }
1256}
1257
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001258int smp_distribute_keys(struct l2cap_conn *conn)
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001259{
1260 struct smp_cmd_pairing *req, *rsp;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001261 struct smp_chan *smp = conn->smp_chan;
Johan Hedberg524237c2014-02-22 19:06:31 +02001262 struct hci_conn *hcon = conn->hcon;
1263 struct hci_dev *hdev = hcon->hdev;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001264 __u8 *keydist;
1265
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001266 BT_DBG("conn %p", conn);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001267
Johan Hedberg524237c2014-02-22 19:06:31 +02001268 if (!test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001269 return 0;
1270
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001271 rsp = (void *) &smp->prsp[1];
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001272
1273 /* The responder sends its keys first */
Johan Hedbergefabba32014-02-26 23:33:44 +02001274 if (hcon->out && (smp->remote_key_dist & 0x07))
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001275 return 0;
1276
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001277 req = (void *) &smp->preq[1];
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001278
Johan Hedberg524237c2014-02-22 19:06:31 +02001279 if (hcon->out) {
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001280 keydist = &rsp->init_key_dist;
1281 *keydist &= req->init_key_dist;
1282 } else {
1283 keydist = &rsp->resp_key_dist;
1284 *keydist &= req->resp_key_dist;
1285 }
1286
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001287 BT_DBG("keydist 0x%x", *keydist);
1288
1289 if (*keydist & SMP_DIST_ENC_KEY) {
1290 struct smp_cmd_encrypt_info enc;
1291 struct smp_cmd_master_ident ident;
Johan Hedberg23d0e122014-02-19 14:57:46 +02001292 struct smp_ltk *ltk;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001293 u8 authenticated;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001294 __le16 ediv;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001295 __le64 rand;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001296
1297 get_random_bytes(enc.ltk, sizeof(enc.ltk));
1298 get_random_bytes(&ediv, sizeof(ediv));
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001299 get_random_bytes(&rand, sizeof(rand));
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001300
1301 smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
1302
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001303 authenticated = hcon->sec_level == BT_SECURITY_HIGH;
Johan Hedberg524237c2014-02-22 19:06:31 +02001304 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type,
Johan Hedberg35d70272014-02-19 14:57:47 +02001305 HCI_SMP_LTK_SLAVE, authenticated, enc.ltk,
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001306 smp->enc_key_size, ediv, rand);
Johan Hedberg23d0e122014-02-19 14:57:46 +02001307 smp->slave_ltk = ltk;
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001308
Andrei Emeltchenko58115372012-03-12 12:13:06 +02001309 ident.ediv = ediv;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001310 ident.rand = rand;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001311
1312 smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident);
1313
1314 *keydist &= ~SMP_DIST_ENC_KEY;
1315 }
1316
1317 if (*keydist & SMP_DIST_ID_KEY) {
1318 struct smp_cmd_ident_addr_info addrinfo;
1319 struct smp_cmd_ident_info idinfo;
1320
Johan Hedberg863efaf2014-02-22 19:06:32 +02001321 memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk));
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001322
1323 smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo);
1324
Johan Hedberg82d4b352014-02-23 19:42:18 +02001325 /* The hci_conn contains the local identity address
1326 * after the connection has been established.
1327 *
1328 * This is true even when the connection has been
1329 * established using a resolvable random address.
1330 */
Johan Hedberg524237c2014-02-22 19:06:31 +02001331 bacpy(&addrinfo.bdaddr, &hcon->src);
Johan Hedberg82d4b352014-02-23 19:42:18 +02001332 addrinfo.addr_type = hcon->src_type;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001333
1334 smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo),
Marcel Holtmannf1560462013-10-13 05:43:25 -07001335 &addrinfo);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001336
1337 *keydist &= ~SMP_DIST_ID_KEY;
1338 }
1339
1340 if (*keydist & SMP_DIST_SIGN) {
1341 struct smp_cmd_sign_info sign;
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001342 struct smp_csrk *csrk;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001343
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001344 /* Generate a new random key */
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001345 get_random_bytes(sign.csrk, sizeof(sign.csrk));
1346
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001347 csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
1348 if (csrk) {
1349 csrk->master = 0x00;
1350 memcpy(csrk->val, sign.csrk, sizeof(csrk->val));
1351 }
1352 smp->slave_csrk = csrk;
1353
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001354 smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign);
1355
1356 *keydist &= ~SMP_DIST_SIGN;
1357 }
1358
Johan Hedbergefabba32014-02-26 23:33:44 +02001359 /* If there are still keys to be received wait for them */
1360 if ((smp->remote_key_dist & 0x07))
1361 return 0;
1362
Johan Hedberg1d98bf42014-03-24 14:39:08 +02001363 clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags);
1364 cancel_delayed_work_sync(&conn->security_timer);
Johan Hedberg4a74d652014-05-20 09:45:50 +03001365 set_bit(SMP_FLAG_COMPLETE, &smp->flags);
Johan Hedberg1d98bf42014-03-24 14:39:08 +02001366 smp_notify_keys(conn);
Johan Hedbergefabba32014-02-26 23:33:44 +02001367
Johan Hedberg1d98bf42014-03-24 14:39:08 +02001368 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001369
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001370 return 0;
1371}