blob: b952041bf4ac7e74908fe3716a475d44a8a7389a [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 Hedberg66bed1a2014-03-18 12:58:23 +020038static inline void swap128(const u8 src[16], u8 dst[16])
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030039{
40 int i;
41 for (i = 0; i < 16; i++)
42 dst[15 - i] = src[i];
43}
44
Johan Hedberg66bed1a2014-03-18 12:58:23 +020045static inline void swap56(const u8 src[7], u8 dst[7])
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030046{
47 int i;
48 for (i = 0; i < 7; i++)
49 dst[6 - i] = src[i];
50}
51
52static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
53{
54 struct blkcipher_desc desc;
55 struct scatterlist sg;
Johan Hedberg943a7322014-03-18 12:58:24 +020056 uint8_t tmp[16], data[16];
Johan Hedberg201a5922013-12-02 10:49:04 +020057 int err;
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030058
59 if (tfm == NULL) {
60 BT_ERR("tfm %p", tfm);
61 return -EINVAL;
62 }
63
64 desc.tfm = tfm;
65 desc.flags = 0;
66
Johan Hedberg943a7322014-03-18 12:58:24 +020067 /* The most significant octet of key corresponds to k[0] */
68 swap128(k, tmp);
69
70 err = crypto_blkcipher_setkey(tfm, tmp, 16);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030071 if (err) {
72 BT_ERR("cipher setkey failed: %d", err);
73 return err;
74 }
75
Johan Hedberg943a7322014-03-18 12:58:24 +020076 /* Most significant octet of plaintextData corresponds to data[0] */
77 swap128(r, data);
78
79 sg_init_one(&sg, data, 16);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030080
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030081 err = crypto_blkcipher_encrypt(&desc, &sg, &sg, 16);
82 if (err)
83 BT_ERR("Encrypt data error %d", err);
84
Johan Hedberg943a7322014-03-18 12:58:24 +020085 /* Most significant octet of encryptedData corresponds to data[0] */
86 swap128(data, r);
87
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030088 return err;
89}
90
Johan Hedberg60478052014-02-18 10:19:31 +020091static int smp_ah(struct crypto_blkcipher *tfm, u8 irk[16], u8 r[3], u8 res[3])
92{
Johan Hedberg943a7322014-03-18 12:58:24 +020093 u8 _res[16];
Johan Hedberg60478052014-02-18 10:19:31 +020094 int err;
95
96 /* r' = padding || r */
Johan Hedberg943a7322014-03-18 12:58:24 +020097 memcpy(_res, r, 3);
98 memset(_res + 3, 0, 13);
Johan Hedberg60478052014-02-18 10:19:31 +020099
Johan Hedberg943a7322014-03-18 12:58:24 +0200100 err = smp_e(tfm, irk, _res);
Johan Hedberg60478052014-02-18 10:19:31 +0200101 if (err) {
102 BT_ERR("Encrypt error");
103 return err;
104 }
105
106 /* The output of the random address function ah is:
107 * ah(h, r) = e(k, r') mod 2^24
108 * The output of the security function e is then truncated to 24 bits
109 * by taking the least significant 24 bits of the output of e as the
110 * result of ah.
111 */
Johan Hedberg943a7322014-03-18 12:58:24 +0200112 memcpy(res, _res, 3);
Johan Hedberg60478052014-02-18 10:19:31 +0200113
114 return 0;
115}
116
117bool smp_irk_matches(struct crypto_blkcipher *tfm, u8 irk[16],
118 bdaddr_t *bdaddr)
119{
120 u8 hash[3];
121 int err;
122
123 BT_DBG("RPA %pMR IRK %*phN", bdaddr, 16, irk);
124
125 err = smp_ah(tfm, irk, &bdaddr->b[3], hash);
126 if (err)
127 return false;
128
129 return !memcmp(bdaddr->b, hash, 3);
130}
131
Johan Hedbergb1e2b3a2014-02-23 19:42:19 +0200132int smp_generate_rpa(struct crypto_blkcipher *tfm, u8 irk[16], bdaddr_t *rpa)
133{
134 int err;
135
136 get_random_bytes(&rpa->b[3], 3);
137
138 rpa->b[5] &= 0x3f; /* Clear two most significant bits */
139 rpa->b[5] |= 0x40; /* Set second most significant bit */
140
141 err = smp_ah(tfm, irk, &rpa->b[3], rpa->b);
142 if (err < 0)
143 return err;
144
145 BT_DBG("RPA %pMR", rpa);
146
147 return 0;
148}
149
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300150static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16],
Marcel Holtmannf1560462013-10-13 05:43:25 -0700151 u8 preq[7], u8 pres[7], u8 _iat, bdaddr_t *ia,
152 u8 _rat, bdaddr_t *ra, u8 res[16])
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300153{
154 u8 p1[16], p2[16];
155 int err;
156
157 memset(p1, 0, 16);
158
159 /* p1 = pres || preq || _rat || _iat */
Johan Hedberg943a7322014-03-18 12:58:24 +0200160 p1[0] = _iat;
161 p1[1] = _rat;
162 memcpy(p1 + 2, preq, 7);
163 memcpy(p1 + 9, pres, 7);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300164
165 /* p2 = padding || ia || ra */
Johan Hedberg943a7322014-03-18 12:58:24 +0200166 memcpy(p2, ra, 6);
167 memcpy(p2 + 6, ia, 6);
168 memset(p2 + 12, 0, 4);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300169
170 /* res = r XOR p1 */
171 u128_xor((u128 *) res, (u128 *) r, (u128 *) p1);
172
173 /* res = e(k, res) */
174 err = smp_e(tfm, k, res);
175 if (err) {
176 BT_ERR("Encrypt data error");
177 return err;
178 }
179
180 /* res = res XOR p2 */
181 u128_xor((u128 *) res, (u128 *) res, (u128 *) p2);
182
183 /* res = e(k, res) */
184 err = smp_e(tfm, k, res);
185 if (err)
186 BT_ERR("Encrypt data error");
187
188 return err;
189}
190
Marcel Holtmannf1560462013-10-13 05:43:25 -0700191static int smp_s1(struct crypto_blkcipher *tfm, u8 k[16], u8 r1[16],
192 u8 r2[16], u8 _r[16])
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300193{
194 int err;
195
196 /* Just least significant octets from r1 and r2 are considered */
Johan Hedberg943a7322014-03-18 12:58:24 +0200197 memcpy(_r, r2, 8);
198 memcpy(_r + 8, r1, 8);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300199
200 err = smp_e(tfm, k, _r);
201 if (err)
202 BT_ERR("Encrypt data error");
203
204 return err;
205}
206
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300207static struct sk_buff *smp_build_cmd(struct l2cap_conn *conn, u8 code,
Marcel Holtmannf1560462013-10-13 05:43:25 -0700208 u16 dlen, void *data)
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300209{
210 struct sk_buff *skb;
211 struct l2cap_hdr *lh;
212 int len;
213
214 len = L2CAP_HDR_SIZE + sizeof(code) + dlen;
215
216 if (len > conn->mtu)
217 return NULL;
218
219 skb = bt_skb_alloc(len, GFP_ATOMIC);
220 if (!skb)
221 return NULL;
222
223 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
224 lh->len = cpu_to_le16(sizeof(code) + dlen);
Joe Perchesdcf4adb2014-03-12 10:52:35 -0700225 lh->cid = cpu_to_le16(L2CAP_CID_SMP);
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300226
227 memcpy(skb_put(skb, sizeof(code)), &code, sizeof(code));
228
229 memcpy(skb_put(skb, dlen), data, dlen);
230
231 return skb;
232}
233
234static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
235{
236 struct sk_buff *skb = smp_build_cmd(conn, code, len, data);
237
238 BT_DBG("code 0x%2.2x", code);
239
240 if (!skb)
241 return;
242
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200243 skb->priority = HCI_PRIO_MAX;
244 hci_send_acl(conn->hchan, skb, 0);
Vinicius Costa Gomese2dcd112011-08-19 21:06:50 -0300245
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -0200246 cancel_delayed_work_sync(&conn->security_timer);
Marcel Holtmann17b02e62012-03-01 14:32:37 -0800247 schedule_delayed_work(&conn->security_timer, SMP_TIMEOUT);
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300248}
249
Brian Gix2b64d152011-12-21 16:12:12 -0800250static __u8 authreq_to_seclevel(__u8 authreq)
251{
252 if (authreq & SMP_AUTH_MITM)
253 return BT_SECURITY_HIGH;
254 else
255 return BT_SECURITY_MEDIUM;
256}
257
258static __u8 seclevel_to_authreq(__u8 sec_level)
259{
260 switch (sec_level) {
261 case BT_SECURITY_HIGH:
262 return SMP_AUTH_MITM | SMP_AUTH_BONDING;
263 case BT_SECURITY_MEDIUM:
264 return SMP_AUTH_BONDING;
265 default:
266 return SMP_AUTH_NONE;
267 }
268}
269
Vinicius Costa Gomesb8e66ea2011-06-09 18:50:52 -0300270static void build_pairing_cmd(struct l2cap_conn *conn,
Marcel Holtmannf1560462013-10-13 05:43:25 -0700271 struct smp_cmd_pairing *req,
272 struct smp_cmd_pairing *rsp, __u8 authreq)
Vinicius Costa Gomesb8e66ea2011-06-09 18:50:52 -0300273{
Johan Hedbergfd349c02014-02-18 10:19:36 +0200274 struct smp_chan *smp = conn->smp_chan;
275 struct hci_conn *hcon = conn->hcon;
276 struct hci_dev *hdev = hcon->hdev;
277 u8 local_dist = 0, remote_dist = 0;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300278
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200279 if (test_bit(HCI_PAIRABLE, &conn->hcon->hdev->dev_flags)) {
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -0700280 local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
281 remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300282 authreq |= SMP_AUTH_BONDING;
Brian Gix2b64d152011-12-21 16:12:12 -0800283 } else {
284 authreq &= ~SMP_AUTH_BONDING;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300285 }
286
Johan Hedbergfd349c02014-02-18 10:19:36 +0200287 if (test_bit(HCI_RPA_RESOLVING, &hdev->dev_flags))
288 remote_dist |= SMP_DIST_ID_KEY;
289
Johan Hedberg863efaf2014-02-22 19:06:32 +0200290 if (test_bit(HCI_PRIVACY, &hdev->dev_flags))
291 local_dist |= SMP_DIST_ID_KEY;
292
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300293 if (rsp == NULL) {
294 req->io_capability = conn->hcon->io_capability;
295 req->oob_flag = SMP_OOB_NOT_PRESENT;
296 req->max_key_size = SMP_MAX_ENC_KEY_SIZE;
Johan Hedbergfd349c02014-02-18 10:19:36 +0200297 req->init_key_dist = local_dist;
298 req->resp_key_dist = remote_dist;
Johan Hedberg065a13e2012-10-11 16:26:06 +0200299 req->auth_req = (authreq & AUTH_REQ_MASK);
Johan Hedbergfd349c02014-02-18 10:19:36 +0200300
301 smp->remote_key_dist = remote_dist;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300302 return;
303 }
304
305 rsp->io_capability = conn->hcon->io_capability;
306 rsp->oob_flag = SMP_OOB_NOT_PRESENT;
307 rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE;
Johan Hedbergfd349c02014-02-18 10:19:36 +0200308 rsp->init_key_dist = req->init_key_dist & remote_dist;
309 rsp->resp_key_dist = req->resp_key_dist & local_dist;
Johan Hedberg065a13e2012-10-11 16:26:06 +0200310 rsp->auth_req = (authreq & AUTH_REQ_MASK);
Johan Hedbergfd349c02014-02-18 10:19:36 +0200311
312 smp->remote_key_dist = rsp->init_key_dist;
Vinicius Costa Gomesb8e66ea2011-06-09 18:50:52 -0300313}
314
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300315static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
316{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300317 struct smp_chan *smp = conn->smp_chan;
318
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300319 if ((max_key_size > SMP_MAX_ENC_KEY_SIZE) ||
Marcel Holtmannf1560462013-10-13 05:43:25 -0700320 (max_key_size < SMP_MIN_ENC_KEY_SIZE))
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300321 return SMP_ENC_KEY_SIZE;
322
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300323 smp->enc_key_size = max_key_size;
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300324
325 return 0;
326}
327
Johan Hedberg84794e12013-11-06 11:24:57 +0200328static void smp_failure(struct l2cap_conn *conn, u8 reason)
Brian Gix4f957a72011-11-23 08:28:36 -0800329{
Johan Hedbergbab73cb2012-02-09 16:07:29 +0200330 struct hci_conn *hcon = conn->hcon;
331
Johan Hedberg84794e12013-11-06 11:24:57 +0200332 if (reason)
Brian Gix4f957a72011-11-23 08:28:36 -0800333 smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
Marcel Holtmannf1560462013-10-13 05:43:25 -0700334 &reason);
Brian Gix4f957a72011-11-23 08:28:36 -0800335
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700336 clear_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags);
337 mgmt_auth_failed(hcon->hdev, &hcon->dst, hcon->type, hcon->dst_type,
338 HCI_ERROR_AUTH_FAILURE);
Vinicius Costa Gomesf1c09c02012-02-01 18:27:56 -0300339
Andre Guedes61a0cfb2012-08-01 20:34:15 -0300340 cancel_delayed_work_sync(&conn->security_timer);
341
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700342 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesf1c09c02012-02-01 18:27:56 -0300343 smp_chan_destroy(conn);
Brian Gix4f957a72011-11-23 08:28:36 -0800344}
345
Brian Gix2b64d152011-12-21 16:12:12 -0800346#define JUST_WORKS 0x00
347#define JUST_CFM 0x01
348#define REQ_PASSKEY 0x02
349#define CFM_PASSKEY 0x03
350#define REQ_OOB 0x04
351#define OVERLAP 0xFF
352
353static const u8 gen_method[5][5] = {
354 { JUST_WORKS, JUST_CFM, REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
355 { JUST_WORKS, JUST_CFM, REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
356 { CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
357 { JUST_WORKS, JUST_CFM, JUST_WORKS, JUST_WORKS, JUST_CFM },
358 { CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, OVERLAP },
359};
360
361static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
362 u8 local_io, u8 remote_io)
363{
364 struct hci_conn *hcon = conn->hcon;
365 struct smp_chan *smp = conn->smp_chan;
366 u8 method;
367 u32 passkey = 0;
368 int ret = 0;
369
370 /* Initialize key for JUST WORKS */
371 memset(smp->tk, 0, sizeof(smp->tk));
372 clear_bit(SMP_FLAG_TK_VALID, &smp->smp_flags);
373
374 BT_DBG("tk_request: auth:%d lcl:%d rem:%d", auth, local_io, remote_io);
375
376 /* If neither side wants MITM, use JUST WORKS */
377 /* If either side has unknown io_caps, use JUST WORKS */
378 /* Otherwise, look up method from the table */
379 if (!(auth & SMP_AUTH_MITM) ||
Marcel Holtmannf1560462013-10-13 05:43:25 -0700380 local_io > SMP_IO_KEYBOARD_DISPLAY ||
381 remote_io > SMP_IO_KEYBOARD_DISPLAY)
Brian Gix2b64d152011-12-21 16:12:12 -0800382 method = JUST_WORKS;
383 else
Ido Yarivb3ff53f2012-03-05 20:07:08 +0200384 method = gen_method[remote_io][local_io];
Brian Gix2b64d152011-12-21 16:12:12 -0800385
386 /* If not bonding, don't ask user to confirm a Zero TK */
387 if (!(auth & SMP_AUTH_BONDING) && method == JUST_CFM)
388 method = JUST_WORKS;
389
Johan Hedberga82505c2014-03-24 14:39:07 +0200390 /* Don't confirm locally initiated pairing attempts */
391 if (method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR,
392 &smp->smp_flags))
393 method = JUST_WORKS;
394
Brian Gix2b64d152011-12-21 16:12:12 -0800395 /* If Just Works, Continue with Zero TK */
396 if (method == JUST_WORKS) {
397 set_bit(SMP_FLAG_TK_VALID, &smp->smp_flags);
398 return 0;
399 }
400
401 /* Not Just Works/Confirm results in MITM Authentication */
402 if (method != JUST_CFM)
403 set_bit(SMP_FLAG_MITM_AUTH, &smp->smp_flags);
404
405 /* If both devices have Keyoard-Display I/O, the master
406 * Confirms and the slave Enters the passkey.
407 */
408 if (method == OVERLAP) {
409 if (hcon->link_mode & HCI_LM_MASTER)
410 method = CFM_PASSKEY;
411 else
412 method = REQ_PASSKEY;
413 }
414
Johan Hedberg01ad34d2014-03-19 14:14:53 +0200415 /* Generate random passkey. */
Brian Gix2b64d152011-12-21 16:12:12 -0800416 if (method == CFM_PASSKEY) {
Johan Hedberg943a7322014-03-18 12:58:24 +0200417 memset(smp->tk, 0, sizeof(smp->tk));
Brian Gix2b64d152011-12-21 16:12:12 -0800418 get_random_bytes(&passkey, sizeof(passkey));
419 passkey %= 1000000;
Johan Hedberg943a7322014-03-18 12:58:24 +0200420 put_unaligned_le32(passkey, smp->tk);
Brian Gix2b64d152011-12-21 16:12:12 -0800421 BT_DBG("PassKey: %d", passkey);
Johan Hedberg01ad34d2014-03-19 14:14:53 +0200422 set_bit(SMP_FLAG_TK_VALID, &smp->smp_flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800423 }
424
425 hci_dev_lock(hcon->hdev);
426
427 if (method == REQ_PASSKEY)
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700428 ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200429 hcon->type, hcon->dst_type);
Johan Hedberg4eb65e62014-03-24 14:39:05 +0200430 else if (method == JUST_CFM)
431 ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
432 hcon->type, hcon->dst_type,
433 passkey, 1);
Brian Gix2b64d152011-12-21 16:12:12 -0800434 else
Johan Hedberg01ad34d2014-03-19 14:14:53 +0200435 ret = mgmt_user_passkey_notify(hcon->hdev, &hcon->dst,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200436 hcon->type, hcon->dst_type,
Johan Hedberg39adbff2014-03-20 08:18:14 +0200437 passkey, 0);
Brian Gix2b64d152011-12-21 16:12:12 -0800438
439 hci_dev_unlock(hcon->hdev);
440
441 return ret;
442}
443
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300444static void confirm_work(struct work_struct *work)
445{
446 struct smp_chan *smp = container_of(work, struct smp_chan, confirm);
447 struct l2cap_conn *conn = smp->conn;
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200448 struct hci_dev *hdev = conn->hcon->hdev;
449 struct crypto_blkcipher *tfm = hdev->tfm_aes;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300450 struct smp_cmd_pairing_confirm cp;
451 int ret;
Johan Hedberg943a7322014-03-18 12:58:24 +0200452 u8 reason;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300453
454 BT_DBG("conn %p", conn);
455
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200456 /* Prevent mutual access to hdev->tfm_aes */
457 hci_dev_lock(hdev);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300458
Johan Hedbergb1cd5fd2014-02-28 12:54:17 +0200459 ret = smp_c1(tfm, smp->tk, smp->prnd, smp->preq, smp->prsp,
460 conn->hcon->init_addr_type, &conn->hcon->init_addr,
Johan Hedberg943a7322014-03-18 12:58:24 +0200461 conn->hcon->resp_addr_type, &conn->hcon->resp_addr,
462 cp.confirm_val);
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200463
464 hci_dev_unlock(hdev);
465
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300466 if (ret) {
467 reason = SMP_UNSPECIFIED;
468 goto error;
469 }
470
Brian Gix2b64d152011-12-21 16:12:12 -0800471 clear_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags);
472
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300473 smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
474
475 return;
476
477error:
Johan Hedberg84794e12013-11-06 11:24:57 +0200478 smp_failure(conn, reason);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300479}
480
481static void random_work(struct work_struct *work)
482{
483 struct smp_chan *smp = container_of(work, struct smp_chan, random);
484 struct l2cap_conn *conn = smp->conn;
485 struct hci_conn *hcon = conn->hcon;
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200486 struct hci_dev *hdev = hcon->hdev;
487 struct crypto_blkcipher *tfm = hdev->tfm_aes;
Johan Hedberg943a7322014-03-18 12:58:24 +0200488 u8 reason, confirm[16];
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300489 int ret;
490
491 if (IS_ERR_OR_NULL(tfm)) {
492 reason = SMP_UNSPECIFIED;
493 goto error;
494 }
495
496 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
497
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200498 /* Prevent mutual access to hdev->tfm_aes */
499 hci_dev_lock(hdev);
500
Johan Hedbergb1cd5fd2014-02-28 12:54:17 +0200501 ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp,
502 hcon->init_addr_type, &hcon->init_addr,
Johan Hedberg943a7322014-03-18 12:58:24 +0200503 hcon->resp_addr_type, &hcon->resp_addr, confirm);
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200504
505 hci_dev_unlock(hdev);
506
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300507 if (ret) {
508 reason = SMP_UNSPECIFIED;
509 goto error;
510 }
511
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300512 if (memcmp(smp->pcnf, confirm, sizeof(smp->pcnf)) != 0) {
513 BT_ERR("Pairing failed (confirmation values mismatch)");
514 reason = SMP_CONFIRM_FAILED;
515 goto error;
516 }
517
518 if (hcon->out) {
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -0800519 u8 stk[16];
520 __le64 rand = 0;
521 __le16 ediv = 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300522
Johan Hedberg943a7322014-03-18 12:58:24 +0200523 smp_s1(tfm, smp->tk, smp->rrnd, smp->prnd, stk);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300524
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300525 memset(stk + smp->enc_key_size, 0,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300526 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300527
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200528 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags)) {
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300529 reason = SMP_UNSPECIFIED;
530 goto error;
531 }
532
533 hci_le_start_enc(hcon, ediv, rand, stk);
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300534 hcon->enc_key_size = smp->enc_key_size;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300535 } else {
Johan Hedberg943a7322014-03-18 12:58:24 +0200536 u8 stk[16];
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -0800537 __le64 rand = 0;
538 __le16 ediv = 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300539
Johan Hedberg943a7322014-03-18 12:58:24 +0200540 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
541 smp->prnd);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300542
Johan Hedberg943a7322014-03-18 12:58:24 +0200543 smp_s1(tfm, smp->tk, smp->prnd, smp->rrnd, stk);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300544
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300545 memset(stk + smp->enc_key_size, 0,
Marcel Holtmannf1560462013-10-13 05:43:25 -0700546 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300547
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700548 hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
Johan Hedberg35d70272014-02-19 14:57:47 +0200549 HCI_SMP_STK_SLAVE, 0, stk, smp->enc_key_size,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300550 ediv, rand);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300551 }
552
553 return;
554
555error:
Johan Hedberg84794e12013-11-06 11:24:57 +0200556 smp_failure(conn, reason);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300557}
558
Johan Hedberge3098be2014-02-28 18:10:03 +0200559static void smp_reencrypt(struct work_struct *work)
560{
561 struct smp_chan *smp = container_of(work, struct smp_chan,
562 reencrypt.work);
563 struct l2cap_conn *conn = smp->conn;
564 struct hci_conn *hcon = conn->hcon;
565 struct smp_ltk *ltk = smp->ltk;
566
567 BT_DBG("");
568
569 hci_le_start_enc(hcon, ltk->ediv, ltk->rand, ltk->val);
570 hcon->enc_key_size = ltk->enc_size;
571}
572
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300573static 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
581 INIT_WORK(&smp->confirm, confirm_work);
582 INIT_WORK(&smp->random, random_work);
Johan Hedberge3098be2014-02-28 18:10:03 +0200583 INIT_DELAYED_WORK(&smp->reencrypt, smp_reencrypt);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300584
585 smp->conn = conn;
586 conn->smp_chan = smp;
Brian Gix2b64d152011-12-21 16:12:12 -0800587 conn->hcon->smp_conn = conn;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300588
589 hci_conn_hold(conn->hcon);
590
591 return smp;
592}
593
594void smp_chan_destroy(struct l2cap_conn *conn)
595{
Brian Gixc8eb9692011-11-23 08:28:35 -0800596 struct smp_chan *smp = conn->smp_chan;
Johan Hedbergf4a407b2014-02-18 21:41:34 +0200597 bool complete;
Brian Gixc8eb9692011-11-23 08:28:35 -0800598
Vinicius Costa Gomesf1c09c02012-02-01 18:27:56 -0300599 BUG_ON(!smp);
Brian Gixc8eb9692011-11-23 08:28:35 -0800600
Johan Hedberge3098be2014-02-28 18:10:03 +0200601 cancel_delayed_work_sync(&smp->reencrypt);
602
Johan Hedbergf4a407b2014-02-18 21:41:34 +0200603 complete = test_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
604 mgmt_smp_complete(conn->hcon, complete);
605
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -0700606 kfree(smp->csrk);
607 kfree(smp->slave_csrk);
608
Johan Hedberg759331d2014-02-28 10:10:16 +0200609 /* If pairing failed clean up any keys we might have */
610 if (!complete) {
611 if (smp->ltk) {
612 list_del(&smp->ltk->list);
613 kfree(smp->ltk);
614 }
615
616 if (smp->slave_ltk) {
617 list_del(&smp->slave_ltk->list);
618 kfree(smp->slave_ltk);
619 }
620
621 if (smp->remote_irk) {
622 list_del(&smp->remote_irk->list);
623 kfree(smp->remote_irk);
624 }
625 }
626
Brian Gixc8eb9692011-11-23 08:28:35 -0800627 kfree(smp);
628 conn->smp_chan = NULL;
Brian Gix2b64d152011-12-21 16:12:12 -0800629 conn->hcon->smp_conn = NULL;
David Herrmann76a68ba2013-04-06 20:28:37 +0200630 hci_conn_drop(conn->hcon);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300631}
632
Brian Gix2b64d152011-12-21 16:12:12 -0800633int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
634{
635 struct l2cap_conn *conn = hcon->smp_conn;
636 struct smp_chan *smp;
637 u32 value;
Brian Gix2b64d152011-12-21 16:12:12 -0800638
639 BT_DBG("");
640
641 if (!conn)
642 return -ENOTCONN;
643
644 smp = conn->smp_chan;
645
646 switch (mgmt_op) {
647 case MGMT_OP_USER_PASSKEY_REPLY:
648 value = le32_to_cpu(passkey);
Johan Hedberg943a7322014-03-18 12:58:24 +0200649 memset(smp->tk, 0, sizeof(smp->tk));
Brian Gix2b64d152011-12-21 16:12:12 -0800650 BT_DBG("PassKey: %d", value);
Johan Hedberg943a7322014-03-18 12:58:24 +0200651 put_unaligned_le32(value, smp->tk);
Brian Gix2b64d152011-12-21 16:12:12 -0800652 /* Fall Through */
653 case MGMT_OP_USER_CONFIRM_REPLY:
654 set_bit(SMP_FLAG_TK_VALID, &smp->smp_flags);
655 break;
656 case MGMT_OP_USER_PASSKEY_NEG_REPLY:
657 case MGMT_OP_USER_CONFIRM_NEG_REPLY:
Johan Hedberg84794e12013-11-06 11:24:57 +0200658 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
Brian Gix2b64d152011-12-21 16:12:12 -0800659 return 0;
660 default:
Johan Hedberg84794e12013-11-06 11:24:57 +0200661 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
Brian Gix2b64d152011-12-21 16:12:12 -0800662 return -EOPNOTSUPP;
663 }
664
665 /* If it is our turn to send Pairing Confirm, do so now */
666 if (test_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags))
667 queue_work(hcon->hdev->workqueue, &smp->confirm);
668
669 return 0;
670}
671
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300672static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300673{
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300674 struct smp_cmd_pairing rsp, *req = (void *) skb->data;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300675 struct smp_chan *smp;
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300676 u8 key_size;
Brian Gix2b64d152011-12-21 16:12:12 -0800677 u8 auth = SMP_AUTH_NONE;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300678 int ret;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300679
680 BT_DBG("conn %p", conn);
681
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200682 if (skb->len < sizeof(*req))
683 return SMP_UNSPECIFIED;
684
Brian Gix2b64d152011-12-21 16:12:12 -0800685 if (conn->hcon->link_mode & HCI_LM_MASTER)
686 return SMP_CMD_NOTSUPP;
687
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200688 if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags))
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300689 smp = smp_chan_create(conn);
Andrei Emeltchenkod08fd0e2012-07-19 17:03:43 +0300690 else
691 smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300692
Andrei Emeltchenkod08fd0e2012-07-19 17:03:43 +0300693 if (!smp)
694 return SMP_UNSPECIFIED;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300695
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300696 smp->preq[0] = SMP_CMD_PAIRING_REQ;
697 memcpy(&smp->preq[1], req, sizeof(*req));
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300698 skb_pull(skb, sizeof(*req));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300699
Brian Gix2b64d152011-12-21 16:12:12 -0800700 /* We didn't start the pairing, so match remote */
701 if (req->auth_req & SMP_AUTH_BONDING)
702 auth = req->auth_req;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300703
Ido Yarivfdde0a22012-03-05 20:09:38 +0200704 conn->hcon->pending_sec_level = authreq_to_seclevel(auth);
705
Brian Gix2b64d152011-12-21 16:12:12 -0800706 build_pairing_cmd(conn, req, &rsp, auth);
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300707
708 key_size = min(req->max_key_size, rsp.max_key_size);
709 if (check_enc_key_size(conn, key_size))
710 return SMP_ENC_KEY_SIZE;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300711
Johan Hedberge84a6b12013-12-02 10:49:03 +0200712 get_random_bytes(smp->prnd, sizeof(smp->prnd));
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300713
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300714 smp->prsp[0] = SMP_CMD_PAIRING_RSP;
715 memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300716
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300717 smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300718
Brian Gix2b64d152011-12-21 16:12:12 -0800719 /* Request setup of TK */
720 ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability);
721 if (ret)
722 return SMP_UNSPECIFIED;
723
Johan Hedbergedca7922014-03-24 15:54:11 +0200724 clear_bit(SMP_FLAG_INITIATOR, &smp->smp_flags);
725
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300726 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300727}
728
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300729static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300730{
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300731 struct smp_cmd_pairing *req, *rsp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300732 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300733 struct hci_dev *hdev = conn->hcon->hdev;
Brian Gix2b64d152011-12-21 16:12:12 -0800734 u8 key_size, auth = SMP_AUTH_NONE;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300735 int ret;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300736
737 BT_DBG("conn %p", conn);
738
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200739 if (skb->len < sizeof(*rsp))
740 return SMP_UNSPECIFIED;
741
Brian Gix2b64d152011-12-21 16:12:12 -0800742 if (!(conn->hcon->link_mode & HCI_LM_MASTER))
743 return SMP_CMD_NOTSUPP;
744
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300745 skb_pull(skb, sizeof(*rsp));
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300746
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300747 req = (void *) &smp->preq[1];
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300748
749 key_size = min(req->max_key_size, rsp->max_key_size);
750 if (check_enc_key_size(conn, key_size))
751 return SMP_ENC_KEY_SIZE;
752
Johan Hedberge84a6b12013-12-02 10:49:03 +0200753 get_random_bytes(smp->prnd, sizeof(smp->prnd));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300754
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300755 smp->prsp[0] = SMP_CMD_PAIRING_RSP;
756 memcpy(&smp->prsp[1], rsp, sizeof(*rsp));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300757
Johan Hedbergfdcc4be2014-03-14 10:53:50 +0200758 /* Update remote key distribution in case the remote cleared
759 * some bits that we had enabled in our request.
760 */
761 smp->remote_key_dist &= rsp->resp_key_dist;
762
Brian Gix2b64d152011-12-21 16:12:12 -0800763 if ((req->auth_req & SMP_AUTH_BONDING) &&
Marcel Holtmannf1560462013-10-13 05:43:25 -0700764 (rsp->auth_req & SMP_AUTH_BONDING))
Brian Gix2b64d152011-12-21 16:12:12 -0800765 auth = SMP_AUTH_BONDING;
766
767 auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM;
768
Johan Hedberg476585e2012-06-06 18:54:15 +0800769 ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability);
Brian Gix2b64d152011-12-21 16:12:12 -0800770 if (ret)
771 return SMP_UNSPECIFIED;
772
773 set_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags);
774
775 /* Can't compose response until we have been confirmed */
Johan Hedberg18e4aeb2014-03-19 14:14:51 +0200776 if (test_bit(SMP_FLAG_TK_VALID, &smp->smp_flags))
777 queue_work(hdev->workqueue, &smp->confirm);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300778
779 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300780}
781
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300782static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300783{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300784 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300785 struct hci_dev *hdev = conn->hcon->hdev;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300786
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300787 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
788
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200789 if (skb->len < sizeof(smp->pcnf))
790 return SMP_UNSPECIFIED;
791
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300792 memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf));
793 skb_pull(skb, sizeof(smp->pcnf));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300794
Johan Hedberg943a7322014-03-18 12:58:24 +0200795 if (conn->hcon->out)
796 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
797 smp->prnd);
798 else if (test_bit(SMP_FLAG_TK_VALID, &smp->smp_flags))
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300799 queue_work(hdev->workqueue, &smp->confirm);
Johan Hedberg943a7322014-03-18 12:58:24 +0200800 else
Brian Gix2b64d152011-12-21 16:12:12 -0800801 set_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300802
803 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300804}
805
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300806static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300807{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300808 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300809 struct hci_dev *hdev = conn->hcon->hdev;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300810
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300811 BT_DBG("conn %p", conn);
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300812
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200813 if (skb->len < sizeof(smp->rrnd))
814 return SMP_UNSPECIFIED;
815
Johan Hedberg943a7322014-03-18 12:58:24 +0200816 memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd));
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300817 skb_pull(skb, sizeof(smp->rrnd));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300818
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300819 queue_work(hdev->workqueue, &smp->random);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300820
821 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300822}
823
Johan Hedberg4dab7862012-06-07 14:58:37 +0800824static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300825{
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300826 struct smp_ltk *key;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300827 struct hci_conn *hcon = conn->hcon;
828
Johan Hedberg98a0b842014-01-30 19:40:00 -0800829 key = hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type,
830 hcon->out);
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300831 if (!key)
832 return 0;
833
Johan Hedberg4dab7862012-06-07 14:58:37 +0800834 if (sec_level > BT_SECURITY_MEDIUM && !key->authenticated)
835 return 0;
836
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200837 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300838 return 1;
839
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300840 hci_le_start_enc(hcon, key->ediv, key->rand, key->val);
841 hcon->enc_key_size = key->enc_size;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300842
843 return 1;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300844}
Marcel Holtmannf1560462013-10-13 05:43:25 -0700845
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300846static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300847{
848 struct smp_cmd_security_req *rp = (void *) skb->data;
849 struct smp_cmd_pairing cp;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300850 struct hci_conn *hcon = conn->hcon;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300851 struct smp_chan *smp;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300852
853 BT_DBG("conn %p", conn);
854
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200855 if (skb->len < sizeof(*rp))
856 return SMP_UNSPECIFIED;
857
Johan Hedberg86ca9ea2013-11-05 11:30:39 +0200858 if (!(conn->hcon->link_mode & HCI_LM_MASTER))
859 return SMP_CMD_NOTSUPP;
860
Brian Gix2b64d152011-12-21 16:12:12 -0800861 hcon->pending_sec_level = authreq_to_seclevel(rp->auth_req);
Vinicius Costa Gomesfeb45eb2011-08-25 20:02:35 -0300862
Johan Hedberg4dab7862012-06-07 14:58:37 +0800863 if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300864 return 0;
865
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200866 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300867 return 0;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300868
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300869 smp = smp_chan_create(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300870
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300871 skb_pull(skb, sizeof(*rp));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300872
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300873 memset(&cp, 0, sizeof(cp));
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300874 build_pairing_cmd(conn, &cp, NULL, rp->auth_req);
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300875
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300876 smp->preq[0] = SMP_CMD_PAIRING_REQ;
877 memcpy(&smp->preq[1], &cp, sizeof(cp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300878
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300879 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300880
Johan Hedbergedca7922014-03-24 15:54:11 +0200881 clear_bit(SMP_FLAG_INITIATOR, &smp->smp_flags);
882
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300883 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300884}
885
Johan Hedbergad32a2f2013-05-14 18:05:12 +0300886bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level)
887{
888 if (sec_level == BT_SECURITY_LOW)
889 return true;
890
891 if (hcon->sec_level >= sec_level)
892 return true;
893
894 return false;
895}
896
Vinicius Costa Gomescc110922012-08-23 21:32:43 -0300897int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300898{
Vinicius Costa Gomescc110922012-08-23 21:32:43 -0300899 struct l2cap_conn *conn = hcon->l2cap_data;
Johan Hedberg0a66cf22014-03-24 14:39:03 +0200900 struct smp_chan *smp;
Brian Gix2b64d152011-12-21 16:12:12 -0800901 __u8 authreq;
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300902
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -0300903 BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
904
Johan Hedberg0a66cf22014-03-24 14:39:03 +0200905 /* This may be NULL if there's an unexpected disconnection */
906 if (!conn)
907 return 1;
908
909 smp = conn->smp_chan;
910
Johan Hedberg757aee02013-04-24 13:05:32 +0300911 if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags))
Andre Guedes2e65c9d2011-06-30 19:20:56 -0300912 return 1;
913
Johan Hedbergad32a2f2013-05-14 18:05:12 +0300914 if (smp_sufficient_security(hcon, sec_level))
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300915 return 1;
916
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300917 if (hcon->link_mode & HCI_LM_MASTER)
Johan Hedberg4dab7862012-06-07 14:58:37 +0800918 if (smp_ltk_encrypt(conn, sec_level))
Vinicius Costa Gomes02bc7452011-07-07 18:59:41 -0300919 goto done;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300920
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200921 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300922 return 0;
923
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300924 smp = smp_chan_create(conn);
Brian Gix2b64d152011-12-21 16:12:12 -0800925 if (!smp)
926 return 1;
927
928 authreq = seclevel_to_authreq(sec_level);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300929
Johan Hedberg2e233642014-03-18 15:42:30 +0200930 /* hcon->auth_type is set by pair_device in mgmt.c. If the MITM
931 * flag is set we should also set it for the SMP request.
932 */
933 if ((hcon->auth_type & 0x01))
934 authreq |= SMP_AUTH_MITM;
935
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300936 if (hcon->link_mode & HCI_LM_MASTER) {
937 struct smp_cmd_pairing cp;
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300938
Brian Gix2b64d152011-12-21 16:12:12 -0800939 build_pairing_cmd(conn, &cp, NULL, authreq);
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300940 smp->preq[0] = SMP_CMD_PAIRING_REQ;
941 memcpy(&smp->preq[1], &cp, sizeof(cp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300942
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300943 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
944 } else {
945 struct smp_cmd_security_req cp;
Brian Gix2b64d152011-12-21 16:12:12 -0800946 cp.auth_req = authreq;
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300947 smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
948 }
949
Vinicius Costa Gomes02bc7452011-07-07 18:59:41 -0300950done:
Johan Hedbergedca7922014-03-24 15:54:11 +0200951 set_bit(SMP_FLAG_INITIATOR, &smp->smp_flags);
952
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300953 hcon->pending_sec_level = sec_level;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300954
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300955 return 0;
956}
957
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300958static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
959{
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300960 struct smp_cmd_encrypt_info *rp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300961 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300962
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200963 BT_DBG("conn %p", conn);
964
965 if (skb->len < sizeof(*rp))
966 return SMP_UNSPECIFIED;
967
Johan Hedberg6131ddc2014-02-18 10:19:37 +0200968 /* Ignore this PDU if it wasn't requested */
969 if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
970 return 0;
971
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300972 skb_pull(skb, sizeof(*rp));
973
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300974 memcpy(smp->tk, rp->ltk, sizeof(smp->tk));
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300975
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300976 return 0;
977}
978
979static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
980{
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300981 struct smp_cmd_master_ident *rp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300982 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300983 struct hci_dev *hdev = conn->hcon->hdev;
984 struct hci_conn *hcon = conn->hcon;
Johan Hedberg23d0e122014-02-19 14:57:46 +0200985 struct smp_ltk *ltk;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300986 u8 authenticated;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300987
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200988 BT_DBG("conn %p", conn);
989
990 if (skb->len < sizeof(*rp))
991 return SMP_UNSPECIFIED;
992
Johan Hedberg6131ddc2014-02-18 10:19:37 +0200993 /* Ignore this PDU if it wasn't requested */
994 if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
995 return 0;
996
Johan Hedberg9747a9f2014-02-26 23:33:43 +0200997 /* Mark the information as received */
998 smp->remote_key_dist &= ~SMP_DIST_ENC_KEY;
999
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001000 skb_pull(skb, sizeof(*rp));
1001
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001002 hci_dev_lock(hdev);
Marcel Holtmannce39fb42013-10-13 02:23:39 -07001003 authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
Johan Hedberg35d70272014-02-19 14:57:47 +02001004 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, HCI_SMP_LTK,
Johan Hedberg23d0e122014-02-19 14:57:46 +02001005 authenticated, smp->tk, smp->enc_key_size,
1006 rp->ediv, rp->rand);
1007 smp->ltk = ltk;
Johan Hedbergfd349c02014-02-18 10:19:36 +02001008 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001009 smp_distribute_keys(conn);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001010 hci_dev_unlock(hdev);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001011
1012 return 0;
1013}
1014
Johan Hedbergfd349c02014-02-18 10:19:36 +02001015static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
1016{
1017 struct smp_cmd_ident_info *info = (void *) skb->data;
1018 struct smp_chan *smp = conn->smp_chan;
1019
1020 BT_DBG("");
1021
1022 if (skb->len < sizeof(*info))
1023 return SMP_UNSPECIFIED;
1024
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001025 /* Ignore this PDU if it wasn't requested */
1026 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
1027 return 0;
1028
Johan Hedbergfd349c02014-02-18 10:19:36 +02001029 skb_pull(skb, sizeof(*info));
1030
1031 memcpy(smp->irk, info->irk, 16);
1032
1033 return 0;
1034}
1035
1036static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
1037 struct sk_buff *skb)
1038{
1039 struct smp_cmd_ident_addr_info *info = (void *) skb->data;
1040 struct smp_chan *smp = conn->smp_chan;
1041 struct hci_conn *hcon = conn->hcon;
1042 bdaddr_t rpa;
1043
1044 BT_DBG("");
1045
1046 if (skb->len < sizeof(*info))
1047 return SMP_UNSPECIFIED;
1048
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001049 /* Ignore this PDU if it wasn't requested */
1050 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
1051 return 0;
1052
Johan Hedberg9747a9f2014-02-26 23:33:43 +02001053 /* Mark the information as received */
1054 smp->remote_key_dist &= ~SMP_DIST_ID_KEY;
1055
Johan Hedbergfd349c02014-02-18 10:19:36 +02001056 skb_pull(skb, sizeof(*info));
1057
Johan Hedberga9a58f82014-02-25 22:24:37 +02001058 /* Strictly speaking the Core Specification (4.1) allows sending
1059 * an empty address which would force us to rely on just the IRK
1060 * as "identity information". However, since such
1061 * implementations are not known of and in order to not over
1062 * complicate our implementation, simply pretend that we never
1063 * received an IRK for such a device.
1064 */
1065 if (!bacmp(&info->bdaddr, BDADDR_ANY)) {
1066 BT_ERR("Ignoring IRK with no identity address");
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001067 smp_distribute_keys(conn);
Johan Hedberga9a58f82014-02-25 22:24:37 +02001068 return 0;
1069 }
1070
Johan Hedbergfd349c02014-02-18 10:19:36 +02001071 bacpy(&smp->id_addr, &info->bdaddr);
1072 smp->id_addr_type = info->addr_type;
1073
1074 if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type))
1075 bacpy(&rpa, &hcon->dst);
1076 else
1077 bacpy(&rpa, BDADDR_ANY);
1078
Johan Hedberg23d0e122014-02-19 14:57:46 +02001079 smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
1080 smp->id_addr_type, smp->irk, &rpa);
Johan Hedbergfd349c02014-02-18 10:19:36 +02001081
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001082 smp_distribute_keys(conn);
Johan Hedbergfd349c02014-02-18 10:19:36 +02001083
1084 return 0;
1085}
1086
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001087static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)
1088{
1089 struct smp_cmd_sign_info *rp = (void *) skb->data;
1090 struct smp_chan *smp = conn->smp_chan;
1091 struct hci_dev *hdev = conn->hcon->hdev;
1092 struct smp_csrk *csrk;
1093
1094 BT_DBG("conn %p", conn);
1095
1096 if (skb->len < sizeof(*rp))
1097 return SMP_UNSPECIFIED;
1098
1099 /* Ignore this PDU if it wasn't requested */
1100 if (!(smp->remote_key_dist & SMP_DIST_SIGN))
1101 return 0;
1102
1103 /* Mark the information as received */
1104 smp->remote_key_dist &= ~SMP_DIST_SIGN;
1105
1106 skb_pull(skb, sizeof(*rp));
1107
1108 hci_dev_lock(hdev);
1109 csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
1110 if (csrk) {
1111 csrk->master = 0x01;
1112 memcpy(csrk->val, rp->csrk, sizeof(csrk->val));
1113 }
1114 smp->csrk = csrk;
1115 if (!(smp->remote_key_dist & SMP_DIST_SIGN))
1116 smp_distribute_keys(conn);
1117 hci_dev_unlock(hdev);
1118
1119 return 0;
1120}
1121
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001122int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
1123{
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001124 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann92381f52013-10-03 01:23:08 -07001125 __u8 code, reason;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001126 int err = 0;
1127
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001128 if (hcon->type != LE_LINK) {
1129 kfree_skb(skb);
Johan Hedberg34327112013-10-16 11:37:01 +03001130 return 0;
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001131 }
1132
Marcel Holtmann92381f52013-10-03 01:23:08 -07001133 if (skb->len < 1) {
1134 kfree_skb(skb);
1135 return -EILSEQ;
1136 }
1137
Marcel Holtmann06ae3312013-10-18 03:43:00 -07001138 if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) {
Andre Guedes2e65c9d2011-06-30 19:20:56 -03001139 err = -ENOTSUPP;
1140 reason = SMP_PAIRING_NOTSUPP;
1141 goto done;
1142 }
1143
Marcel Holtmann92381f52013-10-03 01:23:08 -07001144 code = skb->data[0];
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001145 skb_pull(skb, sizeof(code));
1146
Johan Hedberg8cf9fa12013-01-29 10:44:23 -06001147 /*
1148 * The SMP context must be initialized for all other PDUs except
1149 * pairing and security requests. If we get any other PDU when
1150 * not initialized simply disconnect (done if this function
1151 * returns an error).
1152 */
1153 if (code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ &&
1154 !conn->smp_chan) {
1155 BT_ERR("Unexpected SMP command 0x%02x. Disconnecting.", code);
1156 kfree_skb(skb);
1157 return -ENOTSUPP;
1158 }
1159
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001160 switch (code) {
1161 case SMP_CMD_PAIRING_REQ:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001162 reason = smp_cmd_pairing_req(conn, skb);
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001163 break;
1164
1165 case SMP_CMD_PAIRING_FAIL:
Johan Hedberg84794e12013-11-06 11:24:57 +02001166 smp_failure(conn, 0);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001167 reason = 0;
1168 err = -EPERM;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001169 break;
1170
1171 case SMP_CMD_PAIRING_RSP:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001172 reason = smp_cmd_pairing_rsp(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001173 break;
1174
1175 case SMP_CMD_SECURITY_REQ:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001176 reason = smp_cmd_security_req(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001177 break;
1178
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001179 case SMP_CMD_PAIRING_CONFIRM:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001180 reason = smp_cmd_pairing_confirm(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001181 break;
1182
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001183 case SMP_CMD_PAIRING_RANDOM:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001184 reason = smp_cmd_pairing_random(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001185 break;
1186
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001187 case SMP_CMD_ENCRYPT_INFO:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001188 reason = smp_cmd_encrypt_info(conn, skb);
1189 break;
1190
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001191 case SMP_CMD_MASTER_IDENT:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001192 reason = smp_cmd_master_ident(conn, skb);
1193 break;
1194
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001195 case SMP_CMD_IDENT_INFO:
Johan Hedbergfd349c02014-02-18 10:19:36 +02001196 reason = smp_cmd_ident_info(conn, skb);
1197 break;
1198
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001199 case SMP_CMD_IDENT_ADDR_INFO:
Johan Hedbergfd349c02014-02-18 10:19:36 +02001200 reason = smp_cmd_ident_addr_info(conn, skb);
1201 break;
1202
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001203 case SMP_CMD_SIGN_INFO:
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001204 reason = smp_cmd_sign_info(conn, skb);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001205 break;
1206
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001207 default:
1208 BT_DBG("Unknown command code 0x%2.2x", code);
1209
1210 reason = SMP_CMD_NOTSUPP;
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -03001211 err = -EOPNOTSUPP;
1212 goto done;
1213 }
1214
1215done:
1216 if (reason)
Johan Hedberg84794e12013-11-06 11:24:57 +02001217 smp_failure(conn, reason);
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001218
1219 kfree_skb(skb);
1220 return err;
1221}
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001222
Johan Hedberg35d70272014-02-19 14:57:47 +02001223static void smp_notify_keys(struct l2cap_conn *conn)
1224{
1225 struct smp_chan *smp = conn->smp_chan;
1226 struct hci_conn *hcon = conn->hcon;
1227 struct hci_dev *hdev = hcon->hdev;
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001228 struct smp_cmd_pairing *req = (void *) &smp->preq[1];
1229 struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1];
1230 bool persistent;
Johan Hedberg35d70272014-02-19 14:57:47 +02001231
Johan Hedberg61b1a7f2014-03-20 12:54:16 +02001232 if (smp->remote_irk) {
Johan Hedberg95fbac82014-02-19 15:18:31 +02001233 mgmt_new_irk(hdev, smp->remote_irk);
Johan Hedberg61b1a7f2014-03-20 12:54:16 +02001234 /* Now that user space can be considered to know the
1235 * identity address track the connection based on it
1236 * from now on.
1237 */
1238 bacpy(&hcon->dst, &smp->remote_irk->bdaddr);
1239 hcon->dst_type = smp->remote_irk->addr_type;
1240 l2cap_conn_update_id_addr(hcon);
1241 }
Johan Hedberg95fbac82014-02-19 15:18:31 +02001242
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001243 /* The LTKs and CSRKs should be persistent only if both sides
1244 * had the bonding bit set in their authentication requests.
1245 */
1246 persistent = !!((req->auth_req & rsp->auth_req) & SMP_AUTH_BONDING);
1247
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001248 if (smp->csrk) {
1249 smp->csrk->bdaddr_type = hcon->dst_type;
1250 bacpy(&smp->csrk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001251 mgmt_new_csrk(hdev, smp->csrk, persistent);
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001252 }
1253
1254 if (smp->slave_csrk) {
1255 smp->slave_csrk->bdaddr_type = hcon->dst_type;
1256 bacpy(&smp->slave_csrk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001257 mgmt_new_csrk(hdev, smp->slave_csrk, persistent);
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001258 }
1259
Johan Hedberg35d70272014-02-19 14:57:47 +02001260 if (smp->ltk) {
1261 smp->ltk->bdaddr_type = hcon->dst_type;
1262 bacpy(&smp->ltk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001263 mgmt_new_ltk(hdev, smp->ltk, persistent);
Johan Hedberg35d70272014-02-19 14:57:47 +02001264 }
1265
1266 if (smp->slave_ltk) {
1267 smp->slave_ltk->bdaddr_type = hcon->dst_type;
1268 bacpy(&smp->slave_ltk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001269 mgmt_new_ltk(hdev, smp->slave_ltk, persistent);
Johan Hedberg35d70272014-02-19 14:57:47 +02001270 }
1271}
1272
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001273int smp_distribute_keys(struct l2cap_conn *conn)
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001274{
1275 struct smp_cmd_pairing *req, *rsp;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001276 struct smp_chan *smp = conn->smp_chan;
Johan Hedberg524237c2014-02-22 19:06:31 +02001277 struct hci_conn *hcon = conn->hcon;
1278 struct hci_dev *hdev = hcon->hdev;
Johan Hedberg38ccdc92014-02-28 18:10:02 +02001279 bool ltk_encrypt;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001280 __u8 *keydist;
1281
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001282 BT_DBG("conn %p", conn);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001283
Johan Hedberg524237c2014-02-22 19:06:31 +02001284 if (!test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001285 return 0;
1286
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001287 rsp = (void *) &smp->prsp[1];
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001288
1289 /* The responder sends its keys first */
Johan Hedbergefabba32014-02-26 23:33:44 +02001290 if (hcon->out && (smp->remote_key_dist & 0x07))
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001291 return 0;
1292
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001293 req = (void *) &smp->preq[1];
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001294
Johan Hedberg524237c2014-02-22 19:06:31 +02001295 if (hcon->out) {
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001296 keydist = &rsp->init_key_dist;
1297 *keydist &= req->init_key_dist;
1298 } else {
1299 keydist = &rsp->resp_key_dist;
1300 *keydist &= req->resp_key_dist;
1301 }
1302
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001303 BT_DBG("keydist 0x%x", *keydist);
1304
1305 if (*keydist & SMP_DIST_ENC_KEY) {
1306 struct smp_cmd_encrypt_info enc;
1307 struct smp_cmd_master_ident ident;
Johan Hedberg23d0e122014-02-19 14:57:46 +02001308 struct smp_ltk *ltk;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001309 u8 authenticated;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001310 __le16 ediv;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001311 __le64 rand;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001312
1313 get_random_bytes(enc.ltk, sizeof(enc.ltk));
1314 get_random_bytes(&ediv, sizeof(ediv));
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001315 get_random_bytes(&rand, sizeof(rand));
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001316
1317 smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
1318
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001319 authenticated = hcon->sec_level == BT_SECURITY_HIGH;
Johan Hedberg524237c2014-02-22 19:06:31 +02001320 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type,
Johan Hedberg35d70272014-02-19 14:57:47 +02001321 HCI_SMP_LTK_SLAVE, authenticated, enc.ltk,
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001322 smp->enc_key_size, ediv, rand);
Johan Hedberg23d0e122014-02-19 14:57:46 +02001323 smp->slave_ltk = ltk;
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001324
Andrei Emeltchenko58115372012-03-12 12:13:06 +02001325 ident.ediv = ediv;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001326 ident.rand = rand;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001327
1328 smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident);
1329
1330 *keydist &= ~SMP_DIST_ENC_KEY;
1331 }
1332
1333 if (*keydist & SMP_DIST_ID_KEY) {
1334 struct smp_cmd_ident_addr_info addrinfo;
1335 struct smp_cmd_ident_info idinfo;
1336
Johan Hedberg863efaf2014-02-22 19:06:32 +02001337 memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk));
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001338
1339 smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo);
1340
Johan Hedberg82d4b352014-02-23 19:42:18 +02001341 /* The hci_conn contains the local identity address
1342 * after the connection has been established.
1343 *
1344 * This is true even when the connection has been
1345 * established using a resolvable random address.
1346 */
Johan Hedberg524237c2014-02-22 19:06:31 +02001347 bacpy(&addrinfo.bdaddr, &hcon->src);
Johan Hedberg82d4b352014-02-23 19:42:18 +02001348 addrinfo.addr_type = hcon->src_type;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001349
1350 smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo),
Marcel Holtmannf1560462013-10-13 05:43:25 -07001351 &addrinfo);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001352
1353 *keydist &= ~SMP_DIST_ID_KEY;
1354 }
1355
1356 if (*keydist & SMP_DIST_SIGN) {
1357 struct smp_cmd_sign_info sign;
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001358 struct smp_csrk *csrk;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001359
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001360 /* Generate a new random key */
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001361 get_random_bytes(sign.csrk, sizeof(sign.csrk));
1362
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001363 csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
1364 if (csrk) {
1365 csrk->master = 0x00;
1366 memcpy(csrk->val, sign.csrk, sizeof(csrk->val));
1367 }
1368 smp->slave_csrk = csrk;
1369
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001370 smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign);
1371
1372 *keydist &= ~SMP_DIST_SIGN;
1373 }
1374
Johan Hedbergefabba32014-02-26 23:33:44 +02001375 /* If there are still keys to be received wait for them */
1376 if ((smp->remote_key_dist & 0x07))
1377 return 0;
1378
Johan Hedberg38ccdc92014-02-28 18:10:02 +02001379 /* Check if we should try to re-encrypt the link with the LTK.
1380 * SMP_FLAG_LTK_ENCRYPT flag is used to track whether we've
1381 * already tried this (in which case we shouldn't try again).
1382 *
1383 * The request will trigger an encryption key refresh event
1384 * which will cause a call to auth_cfm and eventually lead to
1385 * l2cap_core.c calling this smp_distribute_keys function again
1386 * and thereby completing the process.
1387 */
1388 if (smp->ltk)
1389 ltk_encrypt = !test_and_set_bit(SMP_FLAG_LTK_ENCRYPT,
1390 &smp->smp_flags);
1391 else
1392 ltk_encrypt = false;
Johan Hedbergefabba32014-02-26 23:33:44 +02001393
Johan Hedberg38ccdc92014-02-28 18:10:02 +02001394 /* Re-encrypt the link with LTK if possible */
1395 if (ltk_encrypt && hcon->out) {
Johan Hedberge3098be2014-02-28 18:10:03 +02001396 queue_delayed_work(hdev->req_workqueue, &smp->reencrypt,
1397 SMP_REENCRYPT_TIMEOUT);
Johan Hedberg38ccdc92014-02-28 18:10:02 +02001398 } else {
1399 clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags);
1400 cancel_delayed_work_sync(&conn->security_timer);
1401 set_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
1402 smp_notify_keys(conn);
1403 smp_chan_destroy(conn);
1404 }
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001405
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001406 return 0;
1407}