blob: 1b28f5fd798ffbb8002a3f4c89c6acd451aa5c50 [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
390 /* If Just Works, Continue with Zero TK */
391 if (method == JUST_WORKS) {
392 set_bit(SMP_FLAG_TK_VALID, &smp->smp_flags);
393 return 0;
394 }
395
396 /* Not Just Works/Confirm results in MITM Authentication */
397 if (method != JUST_CFM)
398 set_bit(SMP_FLAG_MITM_AUTH, &smp->smp_flags);
399
400 /* If both devices have Keyoard-Display I/O, the master
401 * Confirms and the slave Enters the passkey.
402 */
403 if (method == OVERLAP) {
404 if (hcon->link_mode & HCI_LM_MASTER)
405 method = CFM_PASSKEY;
406 else
407 method = REQ_PASSKEY;
408 }
409
Johan Hedberg01ad34d2014-03-19 14:14:53 +0200410 /* Generate random passkey. */
Brian Gix2b64d152011-12-21 16:12:12 -0800411 if (method == CFM_PASSKEY) {
Johan Hedberg943a7322014-03-18 12:58:24 +0200412 memset(smp->tk, 0, sizeof(smp->tk));
Brian Gix2b64d152011-12-21 16:12:12 -0800413 get_random_bytes(&passkey, sizeof(passkey));
414 passkey %= 1000000;
Johan Hedberg943a7322014-03-18 12:58:24 +0200415 put_unaligned_le32(passkey, smp->tk);
Brian Gix2b64d152011-12-21 16:12:12 -0800416 BT_DBG("PassKey: %d", passkey);
Johan Hedberg01ad34d2014-03-19 14:14:53 +0200417 set_bit(SMP_FLAG_TK_VALID, &smp->smp_flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800418 }
419
420 hci_dev_lock(hcon->hdev);
421
422 if (method == REQ_PASSKEY)
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700423 ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200424 hcon->type, hcon->dst_type);
Johan Hedberg4eb65e62014-03-24 14:39:05 +0200425 else if (method == JUST_CFM)
426 ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
427 hcon->type, hcon->dst_type,
428 passkey, 1);
Brian Gix2b64d152011-12-21 16:12:12 -0800429 else
Johan Hedberg01ad34d2014-03-19 14:14:53 +0200430 ret = mgmt_user_passkey_notify(hcon->hdev, &hcon->dst,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200431 hcon->type, hcon->dst_type,
Johan Hedberg39adbff2014-03-20 08:18:14 +0200432 passkey, 0);
Brian Gix2b64d152011-12-21 16:12:12 -0800433
434 hci_dev_unlock(hcon->hdev);
435
436 return ret;
437}
438
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300439static void confirm_work(struct work_struct *work)
440{
441 struct smp_chan *smp = container_of(work, struct smp_chan, confirm);
442 struct l2cap_conn *conn = smp->conn;
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200443 struct hci_dev *hdev = conn->hcon->hdev;
444 struct crypto_blkcipher *tfm = hdev->tfm_aes;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300445 struct smp_cmd_pairing_confirm cp;
446 int ret;
Johan Hedberg943a7322014-03-18 12:58:24 +0200447 u8 reason;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300448
449 BT_DBG("conn %p", conn);
450
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200451 /* Prevent mutual access to hdev->tfm_aes */
452 hci_dev_lock(hdev);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300453
Johan Hedbergb1cd5fd2014-02-28 12:54:17 +0200454 ret = smp_c1(tfm, smp->tk, smp->prnd, smp->preq, smp->prsp,
455 conn->hcon->init_addr_type, &conn->hcon->init_addr,
Johan Hedberg943a7322014-03-18 12:58:24 +0200456 conn->hcon->resp_addr_type, &conn->hcon->resp_addr,
457 cp.confirm_val);
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200458
459 hci_dev_unlock(hdev);
460
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300461 if (ret) {
462 reason = SMP_UNSPECIFIED;
463 goto error;
464 }
465
Brian Gix2b64d152011-12-21 16:12:12 -0800466 clear_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags);
467
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300468 smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
469
470 return;
471
472error:
Johan Hedberg84794e12013-11-06 11:24:57 +0200473 smp_failure(conn, reason);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300474}
475
476static void random_work(struct work_struct *work)
477{
478 struct smp_chan *smp = container_of(work, struct smp_chan, random);
479 struct l2cap_conn *conn = smp->conn;
480 struct hci_conn *hcon = conn->hcon;
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200481 struct hci_dev *hdev = hcon->hdev;
482 struct crypto_blkcipher *tfm = hdev->tfm_aes;
Johan Hedberg943a7322014-03-18 12:58:24 +0200483 u8 reason, confirm[16];
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300484 int ret;
485
486 if (IS_ERR_OR_NULL(tfm)) {
487 reason = SMP_UNSPECIFIED;
488 goto error;
489 }
490
491 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
492
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200493 /* Prevent mutual access to hdev->tfm_aes */
494 hci_dev_lock(hdev);
495
Johan Hedbergb1cd5fd2014-02-28 12:54:17 +0200496 ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp,
497 hcon->init_addr_type, &hcon->init_addr,
Johan Hedberg943a7322014-03-18 12:58:24 +0200498 hcon->resp_addr_type, &hcon->resp_addr, confirm);
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200499
500 hci_dev_unlock(hdev);
501
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300502 if (ret) {
503 reason = SMP_UNSPECIFIED;
504 goto error;
505 }
506
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300507 if (memcmp(smp->pcnf, confirm, sizeof(smp->pcnf)) != 0) {
508 BT_ERR("Pairing failed (confirmation values mismatch)");
509 reason = SMP_CONFIRM_FAILED;
510 goto error;
511 }
512
513 if (hcon->out) {
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -0800514 u8 stk[16];
515 __le64 rand = 0;
516 __le16 ediv = 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300517
Johan Hedberg943a7322014-03-18 12:58:24 +0200518 smp_s1(tfm, smp->tk, smp->rrnd, smp->prnd, stk);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300519
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300520 memset(stk + smp->enc_key_size, 0,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300521 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300522
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200523 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags)) {
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300524 reason = SMP_UNSPECIFIED;
525 goto error;
526 }
527
528 hci_le_start_enc(hcon, ediv, rand, stk);
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300529 hcon->enc_key_size = smp->enc_key_size;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300530 } else {
Johan Hedberg943a7322014-03-18 12:58:24 +0200531 u8 stk[16];
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -0800532 __le64 rand = 0;
533 __le16 ediv = 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300534
Johan Hedberg943a7322014-03-18 12:58:24 +0200535 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
536 smp->prnd);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300537
Johan Hedberg943a7322014-03-18 12:58:24 +0200538 smp_s1(tfm, smp->tk, smp->prnd, smp->rrnd, stk);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300539
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300540 memset(stk + smp->enc_key_size, 0,
Marcel Holtmannf1560462013-10-13 05:43:25 -0700541 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300542
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700543 hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
Johan Hedberg35d70272014-02-19 14:57:47 +0200544 HCI_SMP_STK_SLAVE, 0, stk, smp->enc_key_size,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300545 ediv, rand);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300546 }
547
548 return;
549
550error:
Johan Hedberg84794e12013-11-06 11:24:57 +0200551 smp_failure(conn, reason);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300552}
553
Johan Hedberge3098be2014-02-28 18:10:03 +0200554static void smp_reencrypt(struct work_struct *work)
555{
556 struct smp_chan *smp = container_of(work, struct smp_chan,
557 reencrypt.work);
558 struct l2cap_conn *conn = smp->conn;
559 struct hci_conn *hcon = conn->hcon;
560 struct smp_ltk *ltk = smp->ltk;
561
562 BT_DBG("");
563
564 hci_le_start_enc(hcon, ltk->ediv, ltk->rand, ltk->val);
565 hcon->enc_key_size = ltk->enc_size;
566}
567
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300568static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
569{
570 struct smp_chan *smp;
571
Marcel Holtmannf1560462013-10-13 05:43:25 -0700572 smp = kzalloc(sizeof(*smp), GFP_ATOMIC);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300573 if (!smp)
574 return NULL;
575
576 INIT_WORK(&smp->confirm, confirm_work);
577 INIT_WORK(&smp->random, random_work);
Johan Hedberge3098be2014-02-28 18:10:03 +0200578 INIT_DELAYED_WORK(&smp->reencrypt, smp_reencrypt);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300579
580 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 Hedberge3098be2014-02-28 18:10:03 +0200596 cancel_delayed_work_sync(&smp->reencrypt);
597
Johan Hedbergf4a407b2014-02-18 21:41:34 +0200598 complete = test_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
599 mgmt_smp_complete(conn->hcon, complete);
600
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -0700601 kfree(smp->csrk);
602 kfree(smp->slave_csrk);
603
Johan Hedberg759331d2014-02-28 10:10:16 +0200604 /* If pairing failed clean up any keys we might have */
605 if (!complete) {
606 if (smp->ltk) {
607 list_del(&smp->ltk->list);
608 kfree(smp->ltk);
609 }
610
611 if (smp->slave_ltk) {
612 list_del(&smp->slave_ltk->list);
613 kfree(smp->slave_ltk);
614 }
615
616 if (smp->remote_irk) {
617 list_del(&smp->remote_irk->list);
618 kfree(smp->remote_irk);
619 }
620 }
621
Brian Gixc8eb9692011-11-23 08:28:35 -0800622 kfree(smp);
623 conn->smp_chan = NULL;
Brian Gix2b64d152011-12-21 16:12:12 -0800624 conn->hcon->smp_conn = NULL;
David Herrmann76a68ba2013-04-06 20:28:37 +0200625 hci_conn_drop(conn->hcon);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300626}
627
Brian Gix2b64d152011-12-21 16:12:12 -0800628int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
629{
630 struct l2cap_conn *conn = hcon->smp_conn;
631 struct smp_chan *smp;
632 u32 value;
Brian Gix2b64d152011-12-21 16:12:12 -0800633
634 BT_DBG("");
635
636 if (!conn)
637 return -ENOTCONN;
638
639 smp = conn->smp_chan;
640
641 switch (mgmt_op) {
642 case MGMT_OP_USER_PASSKEY_REPLY:
643 value = le32_to_cpu(passkey);
Johan Hedberg943a7322014-03-18 12:58:24 +0200644 memset(smp->tk, 0, sizeof(smp->tk));
Brian Gix2b64d152011-12-21 16:12:12 -0800645 BT_DBG("PassKey: %d", value);
Johan Hedberg943a7322014-03-18 12:58:24 +0200646 put_unaligned_le32(value, smp->tk);
Brian Gix2b64d152011-12-21 16:12:12 -0800647 /* Fall Through */
648 case MGMT_OP_USER_CONFIRM_REPLY:
649 set_bit(SMP_FLAG_TK_VALID, &smp->smp_flags);
650 break;
651 case MGMT_OP_USER_PASSKEY_NEG_REPLY:
652 case MGMT_OP_USER_CONFIRM_NEG_REPLY:
Johan Hedberg84794e12013-11-06 11:24:57 +0200653 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
Brian Gix2b64d152011-12-21 16:12:12 -0800654 return 0;
655 default:
Johan Hedberg84794e12013-11-06 11:24:57 +0200656 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
Brian Gix2b64d152011-12-21 16:12:12 -0800657 return -EOPNOTSUPP;
658 }
659
660 /* If it is our turn to send Pairing Confirm, do so now */
661 if (test_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags))
662 queue_work(hcon->hdev->workqueue, &smp->confirm);
663
664 return 0;
665}
666
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300667static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300668{
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300669 struct smp_cmd_pairing rsp, *req = (void *) skb->data;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300670 struct smp_chan *smp;
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300671 u8 key_size;
Brian Gix2b64d152011-12-21 16:12:12 -0800672 u8 auth = SMP_AUTH_NONE;
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))
678 return SMP_UNSPECIFIED;
679
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 */
696 if (req->auth_req & SMP_AUTH_BONDING)
697 auth = req->auth_req;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300698
Ido Yarivfdde0a22012-03-05 20:09:38 +0200699 conn->hcon->pending_sec_level = authreq_to_seclevel(auth);
700
Brian Gix2b64d152011-12-21 16:12:12 -0800701 build_pairing_cmd(conn, req, &rsp, auth);
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300702
703 key_size = min(req->max_key_size, rsp.max_key_size);
704 if (check_enc_key_size(conn, key_size))
705 return SMP_ENC_KEY_SIZE;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300706
Johan Hedberge84a6b12013-12-02 10:49:03 +0200707 get_random_bytes(smp->prnd, sizeof(smp->prnd));
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300708
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300709 smp->prsp[0] = SMP_CMD_PAIRING_RSP;
710 memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300711
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300712 smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300713
Brian Gix2b64d152011-12-21 16:12:12 -0800714 /* Request setup of TK */
715 ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability);
716 if (ret)
717 return SMP_UNSPECIFIED;
718
Johan Hedbergedca7922014-03-24 15:54:11 +0200719 clear_bit(SMP_FLAG_INITIATOR, &smp->smp_flags);
720
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300721 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300722}
723
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300724static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300725{
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300726 struct smp_cmd_pairing *req, *rsp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300727 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300728 struct hci_dev *hdev = conn->hcon->hdev;
Brian Gix2b64d152011-12-21 16:12:12 -0800729 u8 key_size, auth = SMP_AUTH_NONE;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300730 int ret;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300731
732 BT_DBG("conn %p", conn);
733
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200734 if (skb->len < sizeof(*rsp))
735 return SMP_UNSPECIFIED;
736
Brian Gix2b64d152011-12-21 16:12:12 -0800737 if (!(conn->hcon->link_mode & HCI_LM_MASTER))
738 return SMP_CMD_NOTSUPP;
739
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300740 skb_pull(skb, sizeof(*rsp));
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300741
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300742 req = (void *) &smp->preq[1];
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300743
744 key_size = min(req->max_key_size, rsp->max_key_size);
745 if (check_enc_key_size(conn, key_size))
746 return SMP_ENC_KEY_SIZE;
747
Johan Hedberge84a6b12013-12-02 10:49:03 +0200748 get_random_bytes(smp->prnd, sizeof(smp->prnd));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300749
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300750 smp->prsp[0] = SMP_CMD_PAIRING_RSP;
751 memcpy(&smp->prsp[1], rsp, sizeof(*rsp));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300752
Johan Hedbergfdcc4be2014-03-14 10:53:50 +0200753 /* Update remote key distribution in case the remote cleared
754 * some bits that we had enabled in our request.
755 */
756 smp->remote_key_dist &= rsp->resp_key_dist;
757
Brian Gix2b64d152011-12-21 16:12:12 -0800758 if ((req->auth_req & SMP_AUTH_BONDING) &&
Marcel Holtmannf1560462013-10-13 05:43:25 -0700759 (rsp->auth_req & SMP_AUTH_BONDING))
Brian Gix2b64d152011-12-21 16:12:12 -0800760 auth = SMP_AUTH_BONDING;
761
762 auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM;
763
Johan Hedberg476585e2012-06-06 18:54:15 +0800764 ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability);
Brian Gix2b64d152011-12-21 16:12:12 -0800765 if (ret)
766 return SMP_UNSPECIFIED;
767
768 set_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags);
769
770 /* Can't compose response until we have been confirmed */
Johan Hedberg18e4aeb2014-03-19 14:14:51 +0200771 if (test_bit(SMP_FLAG_TK_VALID, &smp->smp_flags))
772 queue_work(hdev->workqueue, &smp->confirm);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300773
774 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300775}
776
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300777static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300778{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300779 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300780 struct hci_dev *hdev = conn->hcon->hdev;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300781
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300782 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
783
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200784 if (skb->len < sizeof(smp->pcnf))
785 return SMP_UNSPECIFIED;
786
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300787 memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf));
788 skb_pull(skb, sizeof(smp->pcnf));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300789
Johan Hedberg943a7322014-03-18 12:58:24 +0200790 if (conn->hcon->out)
791 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
792 smp->prnd);
793 else if (test_bit(SMP_FLAG_TK_VALID, &smp->smp_flags))
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300794 queue_work(hdev->workqueue, &smp->confirm);
Johan Hedberg943a7322014-03-18 12:58:24 +0200795 else
Brian Gix2b64d152011-12-21 16:12:12 -0800796 set_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300797
798 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300799}
800
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300801static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300802{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300803 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300804 struct hci_dev *hdev = conn->hcon->hdev;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300805
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300806 BT_DBG("conn %p", conn);
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300807
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200808 if (skb->len < sizeof(smp->rrnd))
809 return SMP_UNSPECIFIED;
810
Johan Hedberg943a7322014-03-18 12:58:24 +0200811 memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd));
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300812 skb_pull(skb, sizeof(smp->rrnd));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300813
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300814 queue_work(hdev->workqueue, &smp->random);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300815
816 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300817}
818
Johan Hedberg4dab7862012-06-07 14:58:37 +0800819static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300820{
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300821 struct smp_ltk *key;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300822 struct hci_conn *hcon = conn->hcon;
823
Johan Hedberg98a0b842014-01-30 19:40:00 -0800824 key = hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type,
825 hcon->out);
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300826 if (!key)
827 return 0;
828
Johan Hedberg4dab7862012-06-07 14:58:37 +0800829 if (sec_level > BT_SECURITY_MEDIUM && !key->authenticated)
830 return 0;
831
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200832 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300833 return 1;
834
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300835 hci_le_start_enc(hcon, key->ediv, key->rand, key->val);
836 hcon->enc_key_size = key->enc_size;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300837
838 return 1;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300839}
Marcel Holtmannf1560462013-10-13 05:43:25 -0700840
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300841static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300842{
843 struct smp_cmd_security_req *rp = (void *) skb->data;
844 struct smp_cmd_pairing cp;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300845 struct hci_conn *hcon = conn->hcon;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300846 struct smp_chan *smp;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300847
848 BT_DBG("conn %p", conn);
849
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200850 if (skb->len < sizeof(*rp))
851 return SMP_UNSPECIFIED;
852
Johan Hedberg86ca9ea2013-11-05 11:30:39 +0200853 if (!(conn->hcon->link_mode & HCI_LM_MASTER))
854 return SMP_CMD_NOTSUPP;
855
Brian Gix2b64d152011-12-21 16:12:12 -0800856 hcon->pending_sec_level = authreq_to_seclevel(rp->auth_req);
Vinicius Costa Gomesfeb45eb2011-08-25 20:02:35 -0300857
Johan Hedberg4dab7862012-06-07 14:58:37 +0800858 if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300859 return 0;
860
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200861 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300862 return 0;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300863
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300864 smp = smp_chan_create(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300865
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300866 skb_pull(skb, sizeof(*rp));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300867
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300868 memset(&cp, 0, sizeof(cp));
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300869 build_pairing_cmd(conn, &cp, NULL, rp->auth_req);
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300870
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300871 smp->preq[0] = SMP_CMD_PAIRING_REQ;
872 memcpy(&smp->preq[1], &cp, sizeof(cp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300873
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300874 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300875
Johan Hedbergedca7922014-03-24 15:54:11 +0200876 clear_bit(SMP_FLAG_INITIATOR, &smp->smp_flags);
877
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300878 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300879}
880
Johan Hedbergad32a2f2013-05-14 18:05:12 +0300881bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level)
882{
883 if (sec_level == BT_SECURITY_LOW)
884 return true;
885
886 if (hcon->sec_level >= sec_level)
887 return true;
888
889 return false;
890}
891
Vinicius Costa Gomescc110922012-08-23 21:32:43 -0300892int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300893{
Vinicius Costa Gomescc110922012-08-23 21:32:43 -0300894 struct l2cap_conn *conn = hcon->l2cap_data;
Johan Hedberg0a66cf22014-03-24 14:39:03 +0200895 struct smp_chan *smp;
Brian Gix2b64d152011-12-21 16:12:12 -0800896 __u8 authreq;
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300897
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -0300898 BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
899
Johan Hedberg0a66cf22014-03-24 14:39:03 +0200900 /* This may be NULL if there's an unexpected disconnection */
901 if (!conn)
902 return 1;
903
904 smp = conn->smp_chan;
905
Johan Hedberg757aee02013-04-24 13:05:32 +0300906 if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags))
Andre Guedes2e65c9d2011-06-30 19:20:56 -0300907 return 1;
908
Johan Hedbergad32a2f2013-05-14 18:05:12 +0300909 if (smp_sufficient_security(hcon, sec_level))
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300910 return 1;
911
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300912 if (hcon->link_mode & HCI_LM_MASTER)
Johan Hedberg4dab7862012-06-07 14:58:37 +0800913 if (smp_ltk_encrypt(conn, sec_level))
Vinicius Costa Gomes02bc7452011-07-07 18:59:41 -0300914 goto done;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300915
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200916 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300917 return 0;
918
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300919 smp = smp_chan_create(conn);
Brian Gix2b64d152011-12-21 16:12:12 -0800920 if (!smp)
921 return 1;
922
923 authreq = seclevel_to_authreq(sec_level);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300924
Johan Hedberg2e233642014-03-18 15:42:30 +0200925 /* hcon->auth_type is set by pair_device in mgmt.c. If the MITM
926 * flag is set we should also set it for the SMP request.
927 */
928 if ((hcon->auth_type & 0x01))
929 authreq |= SMP_AUTH_MITM;
930
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300931 if (hcon->link_mode & HCI_LM_MASTER) {
932 struct smp_cmd_pairing cp;
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300933
Brian Gix2b64d152011-12-21 16:12:12 -0800934 build_pairing_cmd(conn, &cp, NULL, authreq);
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300935 smp->preq[0] = SMP_CMD_PAIRING_REQ;
936 memcpy(&smp->preq[1], &cp, sizeof(cp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300937
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300938 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
939 } else {
940 struct smp_cmd_security_req cp;
Brian Gix2b64d152011-12-21 16:12:12 -0800941 cp.auth_req = authreq;
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300942 smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
943 }
944
Vinicius Costa Gomes02bc7452011-07-07 18:59:41 -0300945done:
Johan Hedbergedca7922014-03-24 15:54:11 +0200946 set_bit(SMP_FLAG_INITIATOR, &smp->smp_flags);
947
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300948 hcon->pending_sec_level = sec_level;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300949
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300950 return 0;
951}
952
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300953static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
954{
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300955 struct smp_cmd_encrypt_info *rp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300956 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300957
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200958 BT_DBG("conn %p", conn);
959
960 if (skb->len < sizeof(*rp))
961 return SMP_UNSPECIFIED;
962
Johan Hedberg6131ddc2014-02-18 10:19:37 +0200963 /* Ignore this PDU if it wasn't requested */
964 if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
965 return 0;
966
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300967 skb_pull(skb, sizeof(*rp));
968
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300969 memcpy(smp->tk, rp->ltk, sizeof(smp->tk));
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300970
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300971 return 0;
972}
973
974static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
975{
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300976 struct smp_cmd_master_ident *rp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300977 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300978 struct hci_dev *hdev = conn->hcon->hdev;
979 struct hci_conn *hcon = conn->hcon;
Johan Hedberg23d0e122014-02-19 14:57:46 +0200980 struct smp_ltk *ltk;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300981 u8 authenticated;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300982
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200983 BT_DBG("conn %p", conn);
984
985 if (skb->len < sizeof(*rp))
986 return SMP_UNSPECIFIED;
987
Johan Hedberg6131ddc2014-02-18 10:19:37 +0200988 /* Ignore this PDU if it wasn't requested */
989 if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
990 return 0;
991
Johan Hedberg9747a9f2014-02-26 23:33:43 +0200992 /* Mark the information as received */
993 smp->remote_key_dist &= ~SMP_DIST_ENC_KEY;
994
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300995 skb_pull(skb, sizeof(*rp));
996
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300997 hci_dev_lock(hdev);
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700998 authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
Johan Hedberg35d70272014-02-19 14:57:47 +0200999 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, HCI_SMP_LTK,
Johan Hedberg23d0e122014-02-19 14:57:46 +02001000 authenticated, smp->tk, smp->enc_key_size,
1001 rp->ediv, rp->rand);
1002 smp->ltk = ltk;
Johan Hedbergfd349c02014-02-18 10:19:36 +02001003 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001004 smp_distribute_keys(conn);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001005 hci_dev_unlock(hdev);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001006
1007 return 0;
1008}
1009
Johan Hedbergfd349c02014-02-18 10:19:36 +02001010static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
1011{
1012 struct smp_cmd_ident_info *info = (void *) skb->data;
1013 struct smp_chan *smp = conn->smp_chan;
1014
1015 BT_DBG("");
1016
1017 if (skb->len < sizeof(*info))
1018 return SMP_UNSPECIFIED;
1019
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001020 /* Ignore this PDU if it wasn't requested */
1021 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
1022 return 0;
1023
Johan Hedbergfd349c02014-02-18 10:19:36 +02001024 skb_pull(skb, sizeof(*info));
1025
1026 memcpy(smp->irk, info->irk, 16);
1027
1028 return 0;
1029}
1030
1031static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
1032 struct sk_buff *skb)
1033{
1034 struct smp_cmd_ident_addr_info *info = (void *) skb->data;
1035 struct smp_chan *smp = conn->smp_chan;
1036 struct hci_conn *hcon = conn->hcon;
1037 bdaddr_t rpa;
1038
1039 BT_DBG("");
1040
1041 if (skb->len < sizeof(*info))
1042 return SMP_UNSPECIFIED;
1043
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001044 /* Ignore this PDU if it wasn't requested */
1045 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
1046 return 0;
1047
Johan Hedberg9747a9f2014-02-26 23:33:43 +02001048 /* Mark the information as received */
1049 smp->remote_key_dist &= ~SMP_DIST_ID_KEY;
1050
Johan Hedbergfd349c02014-02-18 10:19:36 +02001051 skb_pull(skb, sizeof(*info));
1052
Johan Hedberga9a58f82014-02-25 22:24:37 +02001053 /* Strictly speaking the Core Specification (4.1) allows sending
1054 * an empty address which would force us to rely on just the IRK
1055 * as "identity information". However, since such
1056 * implementations are not known of and in order to not over
1057 * complicate our implementation, simply pretend that we never
1058 * received an IRK for such a device.
1059 */
1060 if (!bacmp(&info->bdaddr, BDADDR_ANY)) {
1061 BT_ERR("Ignoring IRK with no identity address");
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001062 smp_distribute_keys(conn);
Johan Hedberga9a58f82014-02-25 22:24:37 +02001063 return 0;
1064 }
1065
Johan Hedbergfd349c02014-02-18 10:19:36 +02001066 bacpy(&smp->id_addr, &info->bdaddr);
1067 smp->id_addr_type = info->addr_type;
1068
1069 if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type))
1070 bacpy(&rpa, &hcon->dst);
1071 else
1072 bacpy(&rpa, BDADDR_ANY);
1073
Johan Hedberg23d0e122014-02-19 14:57:46 +02001074 smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
1075 smp->id_addr_type, smp->irk, &rpa);
Johan Hedbergfd349c02014-02-18 10:19:36 +02001076
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001077 smp_distribute_keys(conn);
Johan Hedbergfd349c02014-02-18 10:19:36 +02001078
1079 return 0;
1080}
1081
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001082static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)
1083{
1084 struct smp_cmd_sign_info *rp = (void *) skb->data;
1085 struct smp_chan *smp = conn->smp_chan;
1086 struct hci_dev *hdev = conn->hcon->hdev;
1087 struct smp_csrk *csrk;
1088
1089 BT_DBG("conn %p", conn);
1090
1091 if (skb->len < sizeof(*rp))
1092 return SMP_UNSPECIFIED;
1093
1094 /* Ignore this PDU if it wasn't requested */
1095 if (!(smp->remote_key_dist & SMP_DIST_SIGN))
1096 return 0;
1097
1098 /* Mark the information as received */
1099 smp->remote_key_dist &= ~SMP_DIST_SIGN;
1100
1101 skb_pull(skb, sizeof(*rp));
1102
1103 hci_dev_lock(hdev);
1104 csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
1105 if (csrk) {
1106 csrk->master = 0x01;
1107 memcpy(csrk->val, rp->csrk, sizeof(csrk->val));
1108 }
1109 smp->csrk = csrk;
1110 if (!(smp->remote_key_dist & SMP_DIST_SIGN))
1111 smp_distribute_keys(conn);
1112 hci_dev_unlock(hdev);
1113
1114 return 0;
1115}
1116
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001117int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
1118{
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001119 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann92381f52013-10-03 01:23:08 -07001120 __u8 code, reason;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001121 int err = 0;
1122
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001123 if (hcon->type != LE_LINK) {
1124 kfree_skb(skb);
Johan Hedberg34327112013-10-16 11:37:01 +03001125 return 0;
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001126 }
1127
Marcel Holtmann92381f52013-10-03 01:23:08 -07001128 if (skb->len < 1) {
1129 kfree_skb(skb);
1130 return -EILSEQ;
1131 }
1132
Marcel Holtmann06ae3312013-10-18 03:43:00 -07001133 if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) {
Andre Guedes2e65c9d2011-06-30 19:20:56 -03001134 err = -ENOTSUPP;
1135 reason = SMP_PAIRING_NOTSUPP;
1136 goto done;
1137 }
1138
Marcel Holtmann92381f52013-10-03 01:23:08 -07001139 code = skb->data[0];
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001140 skb_pull(skb, sizeof(code));
1141
Johan Hedberg8cf9fa12013-01-29 10:44:23 -06001142 /*
1143 * The SMP context must be initialized for all other PDUs except
1144 * pairing and security requests. If we get any other PDU when
1145 * not initialized simply disconnect (done if this function
1146 * returns an error).
1147 */
1148 if (code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ &&
1149 !conn->smp_chan) {
1150 BT_ERR("Unexpected SMP command 0x%02x. Disconnecting.", code);
1151 kfree_skb(skb);
1152 return -ENOTSUPP;
1153 }
1154
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001155 switch (code) {
1156 case SMP_CMD_PAIRING_REQ:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001157 reason = smp_cmd_pairing_req(conn, skb);
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001158 break;
1159
1160 case SMP_CMD_PAIRING_FAIL:
Johan Hedberg84794e12013-11-06 11:24:57 +02001161 smp_failure(conn, 0);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001162 reason = 0;
1163 err = -EPERM;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001164 break;
1165
1166 case SMP_CMD_PAIRING_RSP:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001167 reason = smp_cmd_pairing_rsp(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001168 break;
1169
1170 case SMP_CMD_SECURITY_REQ:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001171 reason = smp_cmd_security_req(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001172 break;
1173
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001174 case SMP_CMD_PAIRING_CONFIRM:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001175 reason = smp_cmd_pairing_confirm(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001176 break;
1177
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001178 case SMP_CMD_PAIRING_RANDOM:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001179 reason = smp_cmd_pairing_random(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001180 break;
1181
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001182 case SMP_CMD_ENCRYPT_INFO:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001183 reason = smp_cmd_encrypt_info(conn, skb);
1184 break;
1185
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001186 case SMP_CMD_MASTER_IDENT:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001187 reason = smp_cmd_master_ident(conn, skb);
1188 break;
1189
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001190 case SMP_CMD_IDENT_INFO:
Johan Hedbergfd349c02014-02-18 10:19:36 +02001191 reason = smp_cmd_ident_info(conn, skb);
1192 break;
1193
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001194 case SMP_CMD_IDENT_ADDR_INFO:
Johan Hedbergfd349c02014-02-18 10:19:36 +02001195 reason = smp_cmd_ident_addr_info(conn, skb);
1196 break;
1197
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001198 case SMP_CMD_SIGN_INFO:
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001199 reason = smp_cmd_sign_info(conn, skb);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001200 break;
1201
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001202 default:
1203 BT_DBG("Unknown command code 0x%2.2x", code);
1204
1205 reason = SMP_CMD_NOTSUPP;
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -03001206 err = -EOPNOTSUPP;
1207 goto done;
1208 }
1209
1210done:
1211 if (reason)
Johan Hedberg84794e12013-11-06 11:24:57 +02001212 smp_failure(conn, reason);
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001213
1214 kfree_skb(skb);
1215 return err;
1216}
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001217
Johan Hedberg35d70272014-02-19 14:57:47 +02001218static void smp_notify_keys(struct l2cap_conn *conn)
1219{
1220 struct smp_chan *smp = conn->smp_chan;
1221 struct hci_conn *hcon = conn->hcon;
1222 struct hci_dev *hdev = hcon->hdev;
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001223 struct smp_cmd_pairing *req = (void *) &smp->preq[1];
1224 struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1];
1225 bool persistent;
Johan Hedberg35d70272014-02-19 14:57:47 +02001226
Johan Hedberg61b1a7f2014-03-20 12:54:16 +02001227 if (smp->remote_irk) {
Johan Hedberg95fbac82014-02-19 15:18:31 +02001228 mgmt_new_irk(hdev, smp->remote_irk);
Johan Hedberg61b1a7f2014-03-20 12:54:16 +02001229 /* Now that user space can be considered to know the
1230 * identity address track the connection based on it
1231 * from now on.
1232 */
1233 bacpy(&hcon->dst, &smp->remote_irk->bdaddr);
1234 hcon->dst_type = smp->remote_irk->addr_type;
1235 l2cap_conn_update_id_addr(hcon);
1236 }
Johan Hedberg95fbac82014-02-19 15:18:31 +02001237
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001238 /* The LTKs and CSRKs should be persistent only if both sides
1239 * had the bonding bit set in their authentication requests.
1240 */
1241 persistent = !!((req->auth_req & rsp->auth_req) & SMP_AUTH_BONDING);
1242
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001243 if (smp->csrk) {
1244 smp->csrk->bdaddr_type = hcon->dst_type;
1245 bacpy(&smp->csrk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001246 mgmt_new_csrk(hdev, smp->csrk, persistent);
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001247 }
1248
1249 if (smp->slave_csrk) {
1250 smp->slave_csrk->bdaddr_type = hcon->dst_type;
1251 bacpy(&smp->slave_csrk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001252 mgmt_new_csrk(hdev, smp->slave_csrk, persistent);
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001253 }
1254
Johan Hedberg35d70272014-02-19 14:57:47 +02001255 if (smp->ltk) {
1256 smp->ltk->bdaddr_type = hcon->dst_type;
1257 bacpy(&smp->ltk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001258 mgmt_new_ltk(hdev, smp->ltk, persistent);
Johan Hedberg35d70272014-02-19 14:57:47 +02001259 }
1260
1261 if (smp->slave_ltk) {
1262 smp->slave_ltk->bdaddr_type = hcon->dst_type;
1263 bacpy(&smp->slave_ltk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001264 mgmt_new_ltk(hdev, smp->slave_ltk, persistent);
Johan Hedberg35d70272014-02-19 14:57:47 +02001265 }
1266}
1267
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001268int smp_distribute_keys(struct l2cap_conn *conn)
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001269{
1270 struct smp_cmd_pairing *req, *rsp;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001271 struct smp_chan *smp = conn->smp_chan;
Johan Hedberg524237c2014-02-22 19:06:31 +02001272 struct hci_conn *hcon = conn->hcon;
1273 struct hci_dev *hdev = hcon->hdev;
Johan Hedberg38ccdc92014-02-28 18:10:02 +02001274 bool ltk_encrypt;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001275 __u8 *keydist;
1276
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001277 BT_DBG("conn %p", conn);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001278
Johan Hedberg524237c2014-02-22 19:06:31 +02001279 if (!test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001280 return 0;
1281
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001282 rsp = (void *) &smp->prsp[1];
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001283
1284 /* The responder sends its keys first */
Johan Hedbergefabba32014-02-26 23:33:44 +02001285 if (hcon->out && (smp->remote_key_dist & 0x07))
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001286 return 0;
1287
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001288 req = (void *) &smp->preq[1];
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001289
Johan Hedberg524237c2014-02-22 19:06:31 +02001290 if (hcon->out) {
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001291 keydist = &rsp->init_key_dist;
1292 *keydist &= req->init_key_dist;
1293 } else {
1294 keydist = &rsp->resp_key_dist;
1295 *keydist &= req->resp_key_dist;
1296 }
1297
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001298 BT_DBG("keydist 0x%x", *keydist);
1299
1300 if (*keydist & SMP_DIST_ENC_KEY) {
1301 struct smp_cmd_encrypt_info enc;
1302 struct smp_cmd_master_ident ident;
Johan Hedberg23d0e122014-02-19 14:57:46 +02001303 struct smp_ltk *ltk;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001304 u8 authenticated;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001305 __le16 ediv;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001306 __le64 rand;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001307
1308 get_random_bytes(enc.ltk, sizeof(enc.ltk));
1309 get_random_bytes(&ediv, sizeof(ediv));
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001310 get_random_bytes(&rand, sizeof(rand));
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001311
1312 smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
1313
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001314 authenticated = hcon->sec_level == BT_SECURITY_HIGH;
Johan Hedberg524237c2014-02-22 19:06:31 +02001315 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type,
Johan Hedberg35d70272014-02-19 14:57:47 +02001316 HCI_SMP_LTK_SLAVE, authenticated, enc.ltk,
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001317 smp->enc_key_size, ediv, rand);
Johan Hedberg23d0e122014-02-19 14:57:46 +02001318 smp->slave_ltk = ltk;
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001319
Andrei Emeltchenko58115372012-03-12 12:13:06 +02001320 ident.ediv = ediv;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001321 ident.rand = rand;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001322
1323 smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident);
1324
1325 *keydist &= ~SMP_DIST_ENC_KEY;
1326 }
1327
1328 if (*keydist & SMP_DIST_ID_KEY) {
1329 struct smp_cmd_ident_addr_info addrinfo;
1330 struct smp_cmd_ident_info idinfo;
1331
Johan Hedberg863efaf2014-02-22 19:06:32 +02001332 memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk));
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001333
1334 smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo);
1335
Johan Hedberg82d4b352014-02-23 19:42:18 +02001336 /* The hci_conn contains the local identity address
1337 * after the connection has been established.
1338 *
1339 * This is true even when the connection has been
1340 * established using a resolvable random address.
1341 */
Johan Hedberg524237c2014-02-22 19:06:31 +02001342 bacpy(&addrinfo.bdaddr, &hcon->src);
Johan Hedberg82d4b352014-02-23 19:42:18 +02001343 addrinfo.addr_type = hcon->src_type;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001344
1345 smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo),
Marcel Holtmannf1560462013-10-13 05:43:25 -07001346 &addrinfo);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001347
1348 *keydist &= ~SMP_DIST_ID_KEY;
1349 }
1350
1351 if (*keydist & SMP_DIST_SIGN) {
1352 struct smp_cmd_sign_info sign;
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001353 struct smp_csrk *csrk;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001354
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001355 /* Generate a new random key */
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001356 get_random_bytes(sign.csrk, sizeof(sign.csrk));
1357
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001358 csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
1359 if (csrk) {
1360 csrk->master = 0x00;
1361 memcpy(csrk->val, sign.csrk, sizeof(csrk->val));
1362 }
1363 smp->slave_csrk = csrk;
1364
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001365 smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign);
1366
1367 *keydist &= ~SMP_DIST_SIGN;
1368 }
1369
Johan Hedbergefabba32014-02-26 23:33:44 +02001370 /* If there are still keys to be received wait for them */
1371 if ((smp->remote_key_dist & 0x07))
1372 return 0;
1373
Johan Hedberg38ccdc92014-02-28 18:10:02 +02001374 /* Check if we should try to re-encrypt the link with the LTK.
1375 * SMP_FLAG_LTK_ENCRYPT flag is used to track whether we've
1376 * already tried this (in which case we shouldn't try again).
1377 *
1378 * The request will trigger an encryption key refresh event
1379 * which will cause a call to auth_cfm and eventually lead to
1380 * l2cap_core.c calling this smp_distribute_keys function again
1381 * and thereby completing the process.
1382 */
1383 if (smp->ltk)
1384 ltk_encrypt = !test_and_set_bit(SMP_FLAG_LTK_ENCRYPT,
1385 &smp->smp_flags);
1386 else
1387 ltk_encrypt = false;
Johan Hedbergefabba32014-02-26 23:33:44 +02001388
Johan Hedberg38ccdc92014-02-28 18:10:02 +02001389 /* Re-encrypt the link with LTK if possible */
1390 if (ltk_encrypt && hcon->out) {
Johan Hedberge3098be2014-02-28 18:10:03 +02001391 queue_delayed_work(hdev->req_workqueue, &smp->reencrypt,
1392 SMP_REENCRYPT_TIMEOUT);
Johan Hedberg38ccdc92014-02-28 18:10:02 +02001393 } else {
1394 clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags);
1395 cancel_delayed_work_sync(&conn->security_timer);
1396 set_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
1397 smp_notify_keys(conn);
1398 smp_chan_destroy(conn);
1399 }
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001400
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001401 return 0;
1402}