blob: f2829a7932e24162063596d0057b590a8e225aa2 [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 Hedberg1cc61142014-05-20 09:45:52 +0300470static u8 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;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300477
478 BT_DBG("conn %p", conn);
479
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200480 /* Prevent mutual access to hdev->tfm_aes */
481 hci_dev_lock(hdev);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300482
Johan Hedbergb1cd5fd2014-02-28 12:54:17 +0200483 ret = smp_c1(tfm, smp->tk, smp->prnd, smp->preq, smp->prsp,
484 conn->hcon->init_addr_type, &conn->hcon->init_addr,
Johan Hedberg943a7322014-03-18 12:58:24 +0200485 conn->hcon->resp_addr_type, &conn->hcon->resp_addr,
486 cp.confirm_val);
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200487
488 hci_dev_unlock(hdev);
489
Johan Hedberg1cc61142014-05-20 09:45:52 +0300490 if (ret)
491 return SMP_UNSPECIFIED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300492
Johan Hedberg4a74d652014-05-20 09:45:50 +0300493 clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800494
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300495 smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
496
Johan Hedberg1cc61142014-05-20 09:45:52 +0300497 return 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300498}
499
Johan Hedberg861580a2014-05-20 09:45:51 +0300500static u8 smp_random(struct smp_chan *smp)
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300501{
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300502 struct l2cap_conn *conn = smp->conn;
503 struct hci_conn *hcon = conn->hcon;
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200504 struct hci_dev *hdev = hcon->hdev;
505 struct crypto_blkcipher *tfm = hdev->tfm_aes;
Johan Hedberg861580a2014-05-20 09:45:51 +0300506 u8 confirm[16];
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300507 int ret;
508
Johan Hedberg861580a2014-05-20 09:45:51 +0300509 if (IS_ERR_OR_NULL(tfm))
510 return SMP_UNSPECIFIED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300511
512 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
513
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200514 /* Prevent mutual access to hdev->tfm_aes */
515 hci_dev_lock(hdev);
516
Johan Hedbergb1cd5fd2014-02-28 12:54:17 +0200517 ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp,
518 hcon->init_addr_type, &hcon->init_addr,
Johan Hedberg943a7322014-03-18 12:58:24 +0200519 hcon->resp_addr_type, &hcon->resp_addr, confirm);
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200520
521 hci_dev_unlock(hdev);
522
Johan Hedberg861580a2014-05-20 09:45:51 +0300523 if (ret)
524 return SMP_UNSPECIFIED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300525
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300526 if (memcmp(smp->pcnf, confirm, sizeof(smp->pcnf)) != 0) {
527 BT_ERR("Pairing failed (confirmation values mismatch)");
Johan Hedberg861580a2014-05-20 09:45:51 +0300528 return SMP_CONFIRM_FAILED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300529 }
530
531 if (hcon->out) {
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -0800532 u8 stk[16];
533 __le64 rand = 0;
534 __le16 ediv = 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300535
Johan Hedberg943a7322014-03-18 12:58:24 +0200536 smp_s1(tfm, smp->tk, smp->rrnd, smp->prnd, stk);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300537
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300538 memset(stk + smp->enc_key_size, 0,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300539 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300540
Johan Hedberg861580a2014-05-20 09:45:51 +0300541 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
542 return SMP_UNSPECIFIED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300543
544 hci_le_start_enc(hcon, ediv, rand, stk);
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300545 hcon->enc_key_size = smp->enc_key_size;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300546 } else {
Johan Hedbergfff34902014-06-10 15:19:50 +0300547 u8 stk[16], auth;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -0800548 __le64 rand = 0;
549 __le16 ediv = 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300550
Johan Hedberg943a7322014-03-18 12:58:24 +0200551 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
552 smp->prnd);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300553
Johan Hedberg943a7322014-03-18 12:58:24 +0200554 smp_s1(tfm, smp->tk, smp->prnd, smp->rrnd, stk);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300555
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300556 memset(stk + smp->enc_key_size, 0,
Marcel Holtmannf1560462013-10-13 05:43:25 -0700557 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300558
Johan Hedbergfff34902014-06-10 15:19:50 +0300559 if (hcon->pending_sec_level == BT_SECURITY_HIGH)
560 auth = 1;
561 else
562 auth = 0;
563
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700564 hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
Johan Hedbergfff34902014-06-10 15:19:50 +0300565 HCI_SMP_STK_SLAVE, auth, stk, smp->enc_key_size,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300566 ediv, rand);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300567 }
568
Johan Hedberg861580a2014-05-20 09:45:51 +0300569 return 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300570}
571
572static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
573{
574 struct smp_chan *smp;
575
Marcel Holtmannf1560462013-10-13 05:43:25 -0700576 smp = kzalloc(sizeof(*smp), GFP_ATOMIC);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300577 if (!smp)
578 return NULL;
579
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300580 smp->conn = conn;
581 conn->smp_chan = smp;
Brian Gix2b64d152011-12-21 16:12:12 -0800582 conn->hcon->smp_conn = conn;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300583
584 hci_conn_hold(conn->hcon);
585
586 return smp;
587}
588
589void smp_chan_destroy(struct l2cap_conn *conn)
590{
Brian Gixc8eb9692011-11-23 08:28:35 -0800591 struct smp_chan *smp = conn->smp_chan;
Johan Hedbergf4a407b2014-02-18 21:41:34 +0200592 bool complete;
Brian Gixc8eb9692011-11-23 08:28:35 -0800593
Vinicius Costa Gomesf1c09c02012-02-01 18:27:56 -0300594 BUG_ON(!smp);
Brian Gixc8eb9692011-11-23 08:28:35 -0800595
Johan Hedberg4a74d652014-05-20 09:45:50 +0300596 complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags);
Johan Hedbergf4a407b2014-02-18 21:41:34 +0200597 mgmt_smp_complete(conn->hcon, complete);
598
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -0700599 kfree(smp->csrk);
600 kfree(smp->slave_csrk);
601
Johan Hedberg759331d2014-02-28 10:10:16 +0200602 /* If pairing failed clean up any keys we might have */
603 if (!complete) {
604 if (smp->ltk) {
605 list_del(&smp->ltk->list);
606 kfree(smp->ltk);
607 }
608
609 if (smp->slave_ltk) {
610 list_del(&smp->slave_ltk->list);
611 kfree(smp->slave_ltk);
612 }
613
614 if (smp->remote_irk) {
615 list_del(&smp->remote_irk->list);
616 kfree(smp->remote_irk);
617 }
618 }
619
Brian Gixc8eb9692011-11-23 08:28:35 -0800620 kfree(smp);
621 conn->smp_chan = NULL;
Brian Gix2b64d152011-12-21 16:12:12 -0800622 conn->hcon->smp_conn = NULL;
David Herrmann76a68ba2013-04-06 20:28:37 +0200623 hci_conn_drop(conn->hcon);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300624}
625
Brian Gix2b64d152011-12-21 16:12:12 -0800626int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
627{
628 struct l2cap_conn *conn = hcon->smp_conn;
629 struct smp_chan *smp;
630 u32 value;
Brian Gix2b64d152011-12-21 16:12:12 -0800631
632 BT_DBG("");
633
634 if (!conn)
635 return -ENOTCONN;
636
637 smp = conn->smp_chan;
638
639 switch (mgmt_op) {
640 case MGMT_OP_USER_PASSKEY_REPLY:
641 value = le32_to_cpu(passkey);
Johan Hedberg943a7322014-03-18 12:58:24 +0200642 memset(smp->tk, 0, sizeof(smp->tk));
Brian Gix2b64d152011-12-21 16:12:12 -0800643 BT_DBG("PassKey: %d", value);
Johan Hedberg943a7322014-03-18 12:58:24 +0200644 put_unaligned_le32(value, smp->tk);
Brian Gix2b64d152011-12-21 16:12:12 -0800645 /* Fall Through */
646 case MGMT_OP_USER_CONFIRM_REPLY:
Johan Hedberg4a74d652014-05-20 09:45:50 +0300647 set_bit(SMP_FLAG_TK_VALID, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800648 break;
649 case MGMT_OP_USER_PASSKEY_NEG_REPLY:
650 case MGMT_OP_USER_CONFIRM_NEG_REPLY:
Johan Hedberg84794e12013-11-06 11:24:57 +0200651 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
Brian Gix2b64d152011-12-21 16:12:12 -0800652 return 0;
653 default:
Johan Hedberg84794e12013-11-06 11:24:57 +0200654 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
Brian Gix2b64d152011-12-21 16:12:12 -0800655 return -EOPNOTSUPP;
656 }
657
658 /* If it is our turn to send Pairing Confirm, do so now */
Johan Hedberg1cc61142014-05-20 09:45:52 +0300659 if (test_bit(SMP_FLAG_CFM_PENDING, &smp->flags)) {
660 u8 rsp = smp_confirm(smp);
661 if (rsp)
662 smp_failure(conn, rsp);
663 }
Brian Gix2b64d152011-12-21 16:12:12 -0800664
665 return 0;
666}
667
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300668static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300669{
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300670 struct smp_cmd_pairing rsp, *req = (void *) skb->data;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300671 struct smp_chan *smp;
Johan Hedberg1ef35822014-05-20 09:45:48 +0300672 u8 key_size, auth;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300673 int ret;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300674
675 BT_DBG("conn %p", conn);
676
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200677 if (skb->len < sizeof(*req))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300678 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200679
Brian Gix2b64d152011-12-21 16:12:12 -0800680 if (conn->hcon->link_mode & HCI_LM_MASTER)
681 return SMP_CMD_NOTSUPP;
682
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200683 if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags))
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300684 smp = smp_chan_create(conn);
Andrei Emeltchenkod08fd0e2012-07-19 17:03:43 +0300685 else
686 smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300687
Andrei Emeltchenkod08fd0e2012-07-19 17:03:43 +0300688 if (!smp)
689 return SMP_UNSPECIFIED;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300690
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300691 smp->preq[0] = SMP_CMD_PAIRING_REQ;
692 memcpy(&smp->preq[1], req, sizeof(*req));
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300693 skb_pull(skb, sizeof(*req));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300694
Brian Gix2b64d152011-12-21 16:12:12 -0800695 /* We didn't start the pairing, so match remote */
Johan Hedberg1ef35822014-05-20 09:45:48 +0300696 auth = req->auth_req;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300697
Ido Yarivfdde0a22012-03-05 20:09:38 +0200698 conn->hcon->pending_sec_level = authreq_to_seclevel(auth);
699
Brian Gix2b64d152011-12-21 16:12:12 -0800700 build_pairing_cmd(conn, req, &rsp, auth);
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300701
702 key_size = min(req->max_key_size, rsp.max_key_size);
703 if (check_enc_key_size(conn, key_size))
704 return SMP_ENC_KEY_SIZE;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300705
Johan Hedberge84a6b12013-12-02 10:49:03 +0200706 get_random_bytes(smp->prnd, sizeof(smp->prnd));
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300707
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300708 smp->prsp[0] = SMP_CMD_PAIRING_RSP;
709 memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300710
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300711 smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300712
Brian Gix2b64d152011-12-21 16:12:12 -0800713 /* Request setup of TK */
714 ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability);
715 if (ret)
716 return SMP_UNSPECIFIED;
717
Johan Hedberg4a74d652014-05-20 09:45:50 +0300718 clear_bit(SMP_FLAG_INITIATOR, &smp->flags);
Johan Hedbergedca7922014-03-24 15:54:11 +0200719
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300720 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300721}
722
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300723static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300724{
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300725 struct smp_cmd_pairing *req, *rsp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300726 struct smp_chan *smp = conn->smp_chan;
Brian Gix2b64d152011-12-21 16:12:12 -0800727 u8 key_size, auth = SMP_AUTH_NONE;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300728 int ret;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300729
730 BT_DBG("conn %p", conn);
731
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200732 if (skb->len < sizeof(*rsp))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300733 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200734
Brian Gix2b64d152011-12-21 16:12:12 -0800735 if (!(conn->hcon->link_mode & HCI_LM_MASTER))
736 return SMP_CMD_NOTSUPP;
737
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300738 skb_pull(skb, sizeof(*rsp));
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300739
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300740 req = (void *) &smp->preq[1];
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300741
742 key_size = min(req->max_key_size, rsp->max_key_size);
743 if (check_enc_key_size(conn, key_size))
744 return SMP_ENC_KEY_SIZE;
745
Johan Hedberge84a6b12013-12-02 10:49:03 +0200746 get_random_bytes(smp->prnd, sizeof(smp->prnd));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300747
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300748 smp->prsp[0] = SMP_CMD_PAIRING_RSP;
749 memcpy(&smp->prsp[1], rsp, sizeof(*rsp));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300750
Johan Hedbergfdcc4be2014-03-14 10:53:50 +0200751 /* Update remote key distribution in case the remote cleared
752 * some bits that we had enabled in our request.
753 */
754 smp->remote_key_dist &= rsp->resp_key_dist;
755
Brian Gix2b64d152011-12-21 16:12:12 -0800756 if ((req->auth_req & SMP_AUTH_BONDING) &&
Marcel Holtmannf1560462013-10-13 05:43:25 -0700757 (rsp->auth_req & SMP_AUTH_BONDING))
Brian Gix2b64d152011-12-21 16:12:12 -0800758 auth = SMP_AUTH_BONDING;
759
760 auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM;
761
Johan Hedberg476585e2012-06-06 18:54:15 +0800762 ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability);
Brian Gix2b64d152011-12-21 16:12:12 -0800763 if (ret)
764 return SMP_UNSPECIFIED;
765
Johan Hedberg4a74d652014-05-20 09:45:50 +0300766 set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800767
768 /* Can't compose response until we have been confirmed */
Johan Hedberg4a74d652014-05-20 09:45:50 +0300769 if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
Johan Hedberg1cc61142014-05-20 09:45:52 +0300770 return smp_confirm(smp);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300771
772 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300773}
774
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300775static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300776{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300777 struct smp_chan *smp = conn->smp_chan;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300778
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300779 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
780
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200781 if (skb->len < sizeof(smp->pcnf))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300782 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200783
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300784 memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf));
785 skb_pull(skb, sizeof(smp->pcnf));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300786
Johan Hedberg943a7322014-03-18 12:58:24 +0200787 if (conn->hcon->out)
788 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
789 smp->prnd);
Johan Hedberg4a74d652014-05-20 09:45:50 +0300790 else if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
Johan Hedberg1cc61142014-05-20 09:45:52 +0300791 return smp_confirm(smp);
Johan Hedberg943a7322014-03-18 12:58:24 +0200792 else
Johan Hedberg4a74d652014-05-20 09:45:50 +0300793 set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300794
795 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300796}
797
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300798static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300799{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300800 struct smp_chan *smp = conn->smp_chan;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300801
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300802 BT_DBG("conn %p", conn);
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300803
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200804 if (skb->len < sizeof(smp->rrnd))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300805 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200806
Johan Hedberg943a7322014-03-18 12:58:24 +0200807 memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd));
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300808 skb_pull(skb, sizeof(smp->rrnd));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300809
Johan Hedberg861580a2014-05-20 09:45:51 +0300810 return smp_random(smp);
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300811}
812
Johan Hedberg4dab7862012-06-07 14:58:37 +0800813static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300814{
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300815 struct smp_ltk *key;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300816 struct hci_conn *hcon = conn->hcon;
817
Johan Hedberg98a0b842014-01-30 19:40:00 -0800818 key = hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type,
819 hcon->out);
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300820 if (!key)
821 return 0;
822
Johan Hedberg4dab7862012-06-07 14:58:37 +0800823 if (sec_level > BT_SECURITY_MEDIUM && !key->authenticated)
824 return 0;
825
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200826 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300827 return 1;
828
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300829 hci_le_start_enc(hcon, key->ediv, key->rand, key->val);
830 hcon->enc_key_size = key->enc_size;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300831
832 return 1;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300833}
Marcel Holtmannf1560462013-10-13 05:43:25 -0700834
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300835static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300836{
837 struct smp_cmd_security_req *rp = (void *) skb->data;
838 struct smp_cmd_pairing cp;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300839 struct hci_conn *hcon = conn->hcon;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300840 struct smp_chan *smp;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300841
842 BT_DBG("conn %p", conn);
843
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200844 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300845 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200846
Johan Hedberg86ca9ea2013-11-05 11:30:39 +0200847 if (!(conn->hcon->link_mode & HCI_LM_MASTER))
848 return SMP_CMD_NOTSUPP;
849
Brian Gix2b64d152011-12-21 16:12:12 -0800850 hcon->pending_sec_level = authreq_to_seclevel(rp->auth_req);
Vinicius Costa Gomesfeb45eb2011-08-25 20:02:35 -0300851
Johan Hedberg4dab7862012-06-07 14:58:37 +0800852 if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300853 return 0;
854
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200855 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300856 return 0;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300857
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300858 smp = smp_chan_create(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300859
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300860 skb_pull(skb, sizeof(*rp));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300861
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300862 memset(&cp, 0, sizeof(cp));
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300863 build_pairing_cmd(conn, &cp, NULL, rp->auth_req);
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300864
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300865 smp->preq[0] = SMP_CMD_PAIRING_REQ;
866 memcpy(&smp->preq[1], &cp, sizeof(cp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300867
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300868 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300869
Johan Hedberg4a74d652014-05-20 09:45:50 +0300870 clear_bit(SMP_FLAG_INITIATOR, &smp->flags);
Johan Hedbergedca7922014-03-24 15:54:11 +0200871
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300872 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300873}
874
Johan Hedbergad32a2f2013-05-14 18:05:12 +0300875bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level)
876{
877 if (sec_level == BT_SECURITY_LOW)
878 return true;
879
880 if (hcon->sec_level >= sec_level)
881 return true;
882
883 return false;
884}
885
Vinicius Costa Gomescc110922012-08-23 21:32:43 -0300886int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300887{
Vinicius Costa Gomescc110922012-08-23 21:32:43 -0300888 struct l2cap_conn *conn = hcon->l2cap_data;
Johan Hedberg0a66cf22014-03-24 14:39:03 +0200889 struct smp_chan *smp;
Brian Gix2b64d152011-12-21 16:12:12 -0800890 __u8 authreq;
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300891
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -0300892 BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
893
Johan Hedberg0a66cf22014-03-24 14:39:03 +0200894 /* This may be NULL if there's an unexpected disconnection */
895 if (!conn)
896 return 1;
897
Johan Hedberg757aee02013-04-24 13:05:32 +0300898 if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags))
Andre Guedes2e65c9d2011-06-30 19:20:56 -0300899 return 1;
900
Johan Hedbergad32a2f2013-05-14 18:05:12 +0300901 if (smp_sufficient_security(hcon, sec_level))
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300902 return 1;
903
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300904 if (hcon->link_mode & HCI_LM_MASTER)
Johan Hedberg4dab7862012-06-07 14:58:37 +0800905 if (smp_ltk_encrypt(conn, sec_level))
Vinicius Costa Gomes02bc7452011-07-07 18:59:41 -0300906 goto done;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300907
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200908 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300909 return 0;
910
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300911 smp = smp_chan_create(conn);
Brian Gix2b64d152011-12-21 16:12:12 -0800912 if (!smp)
913 return 1;
914
915 authreq = seclevel_to_authreq(sec_level);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300916
Johan Hedberg79897d22014-06-01 09:45:24 +0300917 /* Require MITM if IO Capability allows or the security level
918 * requires it.
Johan Hedberg2e233642014-03-18 15:42:30 +0200919 */
Johan Hedberg79897d22014-06-01 09:45:24 +0300920 if (hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT ||
921 sec_level > BT_SECURITY_MEDIUM)
Johan Hedberg2e233642014-03-18 15:42:30 +0200922 authreq |= SMP_AUTH_MITM;
923
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300924 if (hcon->link_mode & HCI_LM_MASTER) {
925 struct smp_cmd_pairing cp;
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300926
Brian Gix2b64d152011-12-21 16:12:12 -0800927 build_pairing_cmd(conn, &cp, NULL, authreq);
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300928 smp->preq[0] = SMP_CMD_PAIRING_REQ;
929 memcpy(&smp->preq[1], &cp, sizeof(cp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300930
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300931 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
932 } else {
933 struct smp_cmd_security_req cp;
Brian Gix2b64d152011-12-21 16:12:12 -0800934 cp.auth_req = authreq;
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300935 smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
936 }
937
Johan Hedberg4a74d652014-05-20 09:45:50 +0300938 set_bit(SMP_FLAG_INITIATOR, &smp->flags);
Johan Hedbergedca7922014-03-24 15:54:11 +0200939
Johan Hedberg61b3b2b2014-03-24 17:36:25 +0200940done:
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300941 hcon->pending_sec_level = sec_level;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300942
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300943 return 0;
944}
945
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300946static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
947{
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300948 struct smp_cmd_encrypt_info *rp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300949 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300950
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200951 BT_DBG("conn %p", conn);
952
953 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300954 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200955
Johan Hedberg6131ddc2014-02-18 10:19:37 +0200956 /* Ignore this PDU if it wasn't requested */
957 if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
958 return 0;
959
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300960 skb_pull(skb, sizeof(*rp));
961
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300962 memcpy(smp->tk, rp->ltk, sizeof(smp->tk));
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300963
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300964 return 0;
965}
966
967static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
968{
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300969 struct smp_cmd_master_ident *rp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300970 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300971 struct hci_dev *hdev = conn->hcon->hdev;
972 struct hci_conn *hcon = conn->hcon;
Johan Hedberg23d0e122014-02-19 14:57:46 +0200973 struct smp_ltk *ltk;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300974 u8 authenticated;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300975
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200976 BT_DBG("conn %p", conn);
977
978 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300979 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200980
Johan Hedberg6131ddc2014-02-18 10:19:37 +0200981 /* Ignore this PDU if it wasn't requested */
982 if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
983 return 0;
984
Johan Hedberg9747a9f2014-02-26 23:33:43 +0200985 /* Mark the information as received */
986 smp->remote_key_dist &= ~SMP_DIST_ENC_KEY;
987
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300988 skb_pull(skb, sizeof(*rp));
989
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300990 hci_dev_lock(hdev);
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700991 authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
Johan Hedberg35d70272014-02-19 14:57:47 +0200992 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, HCI_SMP_LTK,
Johan Hedberg23d0e122014-02-19 14:57:46 +0200993 authenticated, smp->tk, smp->enc_key_size,
994 rp->ediv, rp->rand);
995 smp->ltk = ltk;
Johan Hedbergfd349c02014-02-18 10:19:36 +0200996 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
Johan Hedberg4bd6d382014-02-26 23:33:45 +0200997 smp_distribute_keys(conn);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300998 hci_dev_unlock(hdev);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300999
1000 return 0;
1001}
1002
Johan Hedbergfd349c02014-02-18 10:19:36 +02001003static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
1004{
1005 struct smp_cmd_ident_info *info = (void *) skb->data;
1006 struct smp_chan *smp = conn->smp_chan;
1007
1008 BT_DBG("");
1009
1010 if (skb->len < sizeof(*info))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001011 return SMP_INVALID_PARAMS;
Johan Hedbergfd349c02014-02-18 10:19:36 +02001012
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001013 /* Ignore this PDU if it wasn't requested */
1014 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
1015 return 0;
1016
Johan Hedbergfd349c02014-02-18 10:19:36 +02001017 skb_pull(skb, sizeof(*info));
1018
1019 memcpy(smp->irk, info->irk, 16);
1020
1021 return 0;
1022}
1023
1024static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
1025 struct sk_buff *skb)
1026{
1027 struct smp_cmd_ident_addr_info *info = (void *) skb->data;
1028 struct smp_chan *smp = conn->smp_chan;
1029 struct hci_conn *hcon = conn->hcon;
1030 bdaddr_t rpa;
1031
1032 BT_DBG("");
1033
1034 if (skb->len < sizeof(*info))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001035 return SMP_INVALID_PARAMS;
Johan Hedbergfd349c02014-02-18 10:19:36 +02001036
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001037 /* Ignore this PDU if it wasn't requested */
1038 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
1039 return 0;
1040
Johan Hedberg9747a9f2014-02-26 23:33:43 +02001041 /* Mark the information as received */
1042 smp->remote_key_dist &= ~SMP_DIST_ID_KEY;
1043
Johan Hedbergfd349c02014-02-18 10:19:36 +02001044 skb_pull(skb, sizeof(*info));
1045
Johan Hedberga9a58f82014-02-25 22:24:37 +02001046 /* Strictly speaking the Core Specification (4.1) allows sending
1047 * an empty address which would force us to rely on just the IRK
1048 * as "identity information". However, since such
1049 * implementations are not known of and in order to not over
1050 * complicate our implementation, simply pretend that we never
1051 * received an IRK for such a device.
1052 */
1053 if (!bacmp(&info->bdaddr, BDADDR_ANY)) {
1054 BT_ERR("Ignoring IRK with no identity address");
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001055 smp_distribute_keys(conn);
Johan Hedberga9a58f82014-02-25 22:24:37 +02001056 return 0;
1057 }
1058
Johan Hedbergfd349c02014-02-18 10:19:36 +02001059 bacpy(&smp->id_addr, &info->bdaddr);
1060 smp->id_addr_type = info->addr_type;
1061
1062 if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type))
1063 bacpy(&rpa, &hcon->dst);
1064 else
1065 bacpy(&rpa, BDADDR_ANY);
1066
Johan Hedberg23d0e122014-02-19 14:57:46 +02001067 smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
1068 smp->id_addr_type, smp->irk, &rpa);
Johan Hedbergfd349c02014-02-18 10:19:36 +02001069
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001070 smp_distribute_keys(conn);
Johan Hedbergfd349c02014-02-18 10:19:36 +02001071
1072 return 0;
1073}
1074
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001075static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)
1076{
1077 struct smp_cmd_sign_info *rp = (void *) skb->data;
1078 struct smp_chan *smp = conn->smp_chan;
1079 struct hci_dev *hdev = conn->hcon->hdev;
1080 struct smp_csrk *csrk;
1081
1082 BT_DBG("conn %p", conn);
1083
1084 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001085 return SMP_INVALID_PARAMS;
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001086
1087 /* Ignore this PDU if it wasn't requested */
1088 if (!(smp->remote_key_dist & SMP_DIST_SIGN))
1089 return 0;
1090
1091 /* Mark the information as received */
1092 smp->remote_key_dist &= ~SMP_DIST_SIGN;
1093
1094 skb_pull(skb, sizeof(*rp));
1095
1096 hci_dev_lock(hdev);
1097 csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
1098 if (csrk) {
1099 csrk->master = 0x01;
1100 memcpy(csrk->val, rp->csrk, sizeof(csrk->val));
1101 }
1102 smp->csrk = csrk;
1103 if (!(smp->remote_key_dist & SMP_DIST_SIGN))
1104 smp_distribute_keys(conn);
1105 hci_dev_unlock(hdev);
1106
1107 return 0;
1108}
1109
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001110int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
1111{
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001112 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann92381f52013-10-03 01:23:08 -07001113 __u8 code, reason;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001114 int err = 0;
1115
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001116 if (hcon->type != LE_LINK) {
1117 kfree_skb(skb);
Johan Hedberg34327112013-10-16 11:37:01 +03001118 return 0;
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001119 }
1120
Marcel Holtmann92381f52013-10-03 01:23:08 -07001121 if (skb->len < 1) {
1122 kfree_skb(skb);
1123 return -EILSEQ;
1124 }
1125
Marcel Holtmann06ae3312013-10-18 03:43:00 -07001126 if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) {
Andre Guedes2e65c9d2011-06-30 19:20:56 -03001127 err = -ENOTSUPP;
1128 reason = SMP_PAIRING_NOTSUPP;
1129 goto done;
1130 }
1131
Marcel Holtmann92381f52013-10-03 01:23:08 -07001132 code = skb->data[0];
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001133 skb_pull(skb, sizeof(code));
1134
Johan Hedberg8cf9fa12013-01-29 10:44:23 -06001135 /*
1136 * The SMP context must be initialized for all other PDUs except
1137 * pairing and security requests. If we get any other PDU when
1138 * not initialized simply disconnect (done if this function
1139 * returns an error).
1140 */
1141 if (code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ &&
1142 !conn->smp_chan) {
1143 BT_ERR("Unexpected SMP command 0x%02x. Disconnecting.", code);
1144 kfree_skb(skb);
1145 return -ENOTSUPP;
1146 }
1147
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001148 switch (code) {
1149 case SMP_CMD_PAIRING_REQ:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001150 reason = smp_cmd_pairing_req(conn, skb);
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001151 break;
1152
1153 case SMP_CMD_PAIRING_FAIL:
Johan Hedberg84794e12013-11-06 11:24:57 +02001154 smp_failure(conn, 0);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001155 reason = 0;
1156 err = -EPERM;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001157 break;
1158
1159 case SMP_CMD_PAIRING_RSP:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001160 reason = smp_cmd_pairing_rsp(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001161 break;
1162
1163 case SMP_CMD_SECURITY_REQ:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001164 reason = smp_cmd_security_req(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001165 break;
1166
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001167 case SMP_CMD_PAIRING_CONFIRM:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001168 reason = smp_cmd_pairing_confirm(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001169 break;
1170
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001171 case SMP_CMD_PAIRING_RANDOM:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001172 reason = smp_cmd_pairing_random(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001173 break;
1174
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001175 case SMP_CMD_ENCRYPT_INFO:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001176 reason = smp_cmd_encrypt_info(conn, skb);
1177 break;
1178
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001179 case SMP_CMD_MASTER_IDENT:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001180 reason = smp_cmd_master_ident(conn, skb);
1181 break;
1182
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001183 case SMP_CMD_IDENT_INFO:
Johan Hedbergfd349c02014-02-18 10:19:36 +02001184 reason = smp_cmd_ident_info(conn, skb);
1185 break;
1186
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001187 case SMP_CMD_IDENT_ADDR_INFO:
Johan Hedbergfd349c02014-02-18 10:19:36 +02001188 reason = smp_cmd_ident_addr_info(conn, skb);
1189 break;
1190
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001191 case SMP_CMD_SIGN_INFO:
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001192 reason = smp_cmd_sign_info(conn, skb);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001193 break;
1194
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001195 default:
1196 BT_DBG("Unknown command code 0x%2.2x", code);
1197
1198 reason = SMP_CMD_NOTSUPP;
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -03001199 err = -EOPNOTSUPP;
1200 goto done;
1201 }
1202
1203done:
1204 if (reason)
Johan Hedberg84794e12013-11-06 11:24:57 +02001205 smp_failure(conn, reason);
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001206
1207 kfree_skb(skb);
1208 return err;
1209}
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001210
Johan Hedberg35d70272014-02-19 14:57:47 +02001211static void smp_notify_keys(struct l2cap_conn *conn)
1212{
1213 struct smp_chan *smp = conn->smp_chan;
1214 struct hci_conn *hcon = conn->hcon;
1215 struct hci_dev *hdev = hcon->hdev;
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001216 struct smp_cmd_pairing *req = (void *) &smp->preq[1];
1217 struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1];
1218 bool persistent;
Johan Hedberg35d70272014-02-19 14:57:47 +02001219
Johan Hedberg61b1a7f2014-03-20 12:54:16 +02001220 if (smp->remote_irk) {
Johan Hedberg95fbac82014-02-19 15:18:31 +02001221 mgmt_new_irk(hdev, smp->remote_irk);
Johan Hedberg61b1a7f2014-03-20 12:54:16 +02001222 /* Now that user space can be considered to know the
1223 * identity address track the connection based on it
1224 * from now on.
1225 */
1226 bacpy(&hcon->dst, &smp->remote_irk->bdaddr);
1227 hcon->dst_type = smp->remote_irk->addr_type;
1228 l2cap_conn_update_id_addr(hcon);
1229 }
Johan Hedberg95fbac82014-02-19 15:18:31 +02001230
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001231 /* The LTKs and CSRKs should be persistent only if both sides
1232 * had the bonding bit set in their authentication requests.
1233 */
1234 persistent = !!((req->auth_req & rsp->auth_req) & SMP_AUTH_BONDING);
1235
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001236 if (smp->csrk) {
1237 smp->csrk->bdaddr_type = hcon->dst_type;
1238 bacpy(&smp->csrk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001239 mgmt_new_csrk(hdev, smp->csrk, persistent);
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001240 }
1241
1242 if (smp->slave_csrk) {
1243 smp->slave_csrk->bdaddr_type = hcon->dst_type;
1244 bacpy(&smp->slave_csrk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001245 mgmt_new_csrk(hdev, smp->slave_csrk, persistent);
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001246 }
1247
Johan Hedberg35d70272014-02-19 14:57:47 +02001248 if (smp->ltk) {
1249 smp->ltk->bdaddr_type = hcon->dst_type;
1250 bacpy(&smp->ltk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001251 mgmt_new_ltk(hdev, smp->ltk, persistent);
Johan Hedberg35d70272014-02-19 14:57:47 +02001252 }
1253
1254 if (smp->slave_ltk) {
1255 smp->slave_ltk->bdaddr_type = hcon->dst_type;
1256 bacpy(&smp->slave_ltk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001257 mgmt_new_ltk(hdev, smp->slave_ltk, persistent);
Johan Hedberg35d70272014-02-19 14:57:47 +02001258 }
1259}
1260
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001261int smp_distribute_keys(struct l2cap_conn *conn)
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001262{
1263 struct smp_cmd_pairing *req, *rsp;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001264 struct smp_chan *smp = conn->smp_chan;
Johan Hedberg524237c2014-02-22 19:06:31 +02001265 struct hci_conn *hcon = conn->hcon;
1266 struct hci_dev *hdev = hcon->hdev;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001267 __u8 *keydist;
1268
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001269 BT_DBG("conn %p", conn);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001270
Johan Hedberg524237c2014-02-22 19:06:31 +02001271 if (!test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001272 return 0;
1273
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001274 rsp = (void *) &smp->prsp[1];
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001275
1276 /* The responder sends its keys first */
Johan Hedbergefabba32014-02-26 23:33:44 +02001277 if (hcon->out && (smp->remote_key_dist & 0x07))
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001278 return 0;
1279
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001280 req = (void *) &smp->preq[1];
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001281
Johan Hedberg524237c2014-02-22 19:06:31 +02001282 if (hcon->out) {
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001283 keydist = &rsp->init_key_dist;
1284 *keydist &= req->init_key_dist;
1285 } else {
1286 keydist = &rsp->resp_key_dist;
1287 *keydist &= req->resp_key_dist;
1288 }
1289
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001290 BT_DBG("keydist 0x%x", *keydist);
1291
1292 if (*keydist & SMP_DIST_ENC_KEY) {
1293 struct smp_cmd_encrypt_info enc;
1294 struct smp_cmd_master_ident ident;
Johan Hedberg23d0e122014-02-19 14:57:46 +02001295 struct smp_ltk *ltk;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001296 u8 authenticated;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001297 __le16 ediv;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001298 __le64 rand;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001299
1300 get_random_bytes(enc.ltk, sizeof(enc.ltk));
1301 get_random_bytes(&ediv, sizeof(ediv));
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001302 get_random_bytes(&rand, sizeof(rand));
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001303
1304 smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
1305
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001306 authenticated = hcon->sec_level == BT_SECURITY_HIGH;
Johan Hedberg524237c2014-02-22 19:06:31 +02001307 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type,
Johan Hedberg35d70272014-02-19 14:57:47 +02001308 HCI_SMP_LTK_SLAVE, authenticated, enc.ltk,
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001309 smp->enc_key_size, ediv, rand);
Johan Hedberg23d0e122014-02-19 14:57:46 +02001310 smp->slave_ltk = ltk;
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001311
Andrei Emeltchenko58115372012-03-12 12:13:06 +02001312 ident.ediv = ediv;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001313 ident.rand = rand;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001314
1315 smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident);
1316
1317 *keydist &= ~SMP_DIST_ENC_KEY;
1318 }
1319
1320 if (*keydist & SMP_DIST_ID_KEY) {
1321 struct smp_cmd_ident_addr_info addrinfo;
1322 struct smp_cmd_ident_info idinfo;
1323
Johan Hedberg863efaf2014-02-22 19:06:32 +02001324 memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk));
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001325
1326 smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo);
1327
Johan Hedberg82d4b352014-02-23 19:42:18 +02001328 /* The hci_conn contains the local identity address
1329 * after the connection has been established.
1330 *
1331 * This is true even when the connection has been
1332 * established using a resolvable random address.
1333 */
Johan Hedberg524237c2014-02-22 19:06:31 +02001334 bacpy(&addrinfo.bdaddr, &hcon->src);
Johan Hedberg82d4b352014-02-23 19:42:18 +02001335 addrinfo.addr_type = hcon->src_type;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001336
1337 smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo),
Marcel Holtmannf1560462013-10-13 05:43:25 -07001338 &addrinfo);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001339
1340 *keydist &= ~SMP_DIST_ID_KEY;
1341 }
1342
1343 if (*keydist & SMP_DIST_SIGN) {
1344 struct smp_cmd_sign_info sign;
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001345 struct smp_csrk *csrk;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001346
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001347 /* Generate a new random key */
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001348 get_random_bytes(sign.csrk, sizeof(sign.csrk));
1349
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001350 csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
1351 if (csrk) {
1352 csrk->master = 0x00;
1353 memcpy(csrk->val, sign.csrk, sizeof(csrk->val));
1354 }
1355 smp->slave_csrk = csrk;
1356
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001357 smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign);
1358
1359 *keydist &= ~SMP_DIST_SIGN;
1360 }
1361
Johan Hedbergefabba32014-02-26 23:33:44 +02001362 /* If there are still keys to be received wait for them */
1363 if ((smp->remote_key_dist & 0x07))
1364 return 0;
1365
Johan Hedberg1d98bf42014-03-24 14:39:08 +02001366 clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags);
1367 cancel_delayed_work_sync(&conn->security_timer);
Johan Hedberg4a74d652014-05-20 09:45:50 +03001368 set_bit(SMP_FLAG_COMPLETE, &smp->flags);
Johan Hedberg1d98bf42014-03-24 14:39:08 +02001369 smp_notify_keys(conn);
Johan Hedbergefabba32014-02-26 23:33:44 +02001370
Johan Hedberg1d98bf42014-03-24 14:39:08 +02001371 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001372
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001373 return 0;
1374}