blob: 13919ff82e055f51f0eb32ce0c1f1fa94b105c91 [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);
Brian Gix2b64d152011-12-21 16:12:12 -0800425 else
Johan Hedberg01ad34d2014-03-19 14:14:53 +0200426 ret = mgmt_user_passkey_notify(hcon->hdev, &hcon->dst,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200427 hcon->type, hcon->dst_type,
Johan Hedberg39adbff2014-03-20 08:18:14 +0200428 passkey, 0);
Brian Gix2b64d152011-12-21 16:12:12 -0800429
430 hci_dev_unlock(hcon->hdev);
431
432 return ret;
433}
434
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300435static void confirm_work(struct work_struct *work)
436{
437 struct smp_chan *smp = container_of(work, struct smp_chan, confirm);
438 struct l2cap_conn *conn = smp->conn;
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200439 struct hci_dev *hdev = conn->hcon->hdev;
440 struct crypto_blkcipher *tfm = hdev->tfm_aes;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300441 struct smp_cmd_pairing_confirm cp;
442 int ret;
Johan Hedberg943a7322014-03-18 12:58:24 +0200443 u8 reason;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300444
445 BT_DBG("conn %p", conn);
446
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200447 /* Prevent mutual access to hdev->tfm_aes */
448 hci_dev_lock(hdev);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300449
Johan Hedbergb1cd5fd2014-02-28 12:54:17 +0200450 ret = smp_c1(tfm, smp->tk, smp->prnd, smp->preq, smp->prsp,
451 conn->hcon->init_addr_type, &conn->hcon->init_addr,
Johan Hedberg943a7322014-03-18 12:58:24 +0200452 conn->hcon->resp_addr_type, &conn->hcon->resp_addr,
453 cp.confirm_val);
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200454
455 hci_dev_unlock(hdev);
456
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300457 if (ret) {
458 reason = SMP_UNSPECIFIED;
459 goto error;
460 }
461
Brian Gix2b64d152011-12-21 16:12:12 -0800462 clear_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags);
463
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300464 smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
465
466 return;
467
468error:
Johan Hedberg84794e12013-11-06 11:24:57 +0200469 smp_failure(conn, reason);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300470}
471
472static void random_work(struct work_struct *work)
473{
474 struct smp_chan *smp = container_of(work, struct smp_chan, random);
475 struct l2cap_conn *conn = smp->conn;
476 struct hci_conn *hcon = conn->hcon;
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200477 struct hci_dev *hdev = hcon->hdev;
478 struct crypto_blkcipher *tfm = hdev->tfm_aes;
Johan Hedberg943a7322014-03-18 12:58:24 +0200479 u8 reason, confirm[16];
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300480 int ret;
481
482 if (IS_ERR_OR_NULL(tfm)) {
483 reason = SMP_UNSPECIFIED;
484 goto error;
485 }
486
487 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
488
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200489 /* Prevent mutual access to hdev->tfm_aes */
490 hci_dev_lock(hdev);
491
Johan Hedbergb1cd5fd2014-02-28 12:54:17 +0200492 ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp,
493 hcon->init_addr_type, &hcon->init_addr,
Johan Hedberg943a7322014-03-18 12:58:24 +0200494 hcon->resp_addr_type, &hcon->resp_addr, confirm);
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200495
496 hci_dev_unlock(hdev);
497
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300498 if (ret) {
499 reason = SMP_UNSPECIFIED;
500 goto error;
501 }
502
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300503 if (memcmp(smp->pcnf, confirm, sizeof(smp->pcnf)) != 0) {
504 BT_ERR("Pairing failed (confirmation values mismatch)");
505 reason = SMP_CONFIRM_FAILED;
506 goto error;
507 }
508
509 if (hcon->out) {
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -0800510 u8 stk[16];
511 __le64 rand = 0;
512 __le16 ediv = 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300513
Johan Hedberg943a7322014-03-18 12:58:24 +0200514 smp_s1(tfm, smp->tk, smp->rrnd, smp->prnd, stk);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300515
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300516 memset(stk + smp->enc_key_size, 0,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300517 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300518
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200519 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags)) {
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300520 reason = SMP_UNSPECIFIED;
521 goto error;
522 }
523
524 hci_le_start_enc(hcon, ediv, rand, stk);
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300525 hcon->enc_key_size = smp->enc_key_size;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300526 } else {
Johan Hedberg943a7322014-03-18 12:58:24 +0200527 u8 stk[16];
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -0800528 __le64 rand = 0;
529 __le16 ediv = 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300530
Johan Hedberg943a7322014-03-18 12:58:24 +0200531 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
532 smp->prnd);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300533
Johan Hedberg943a7322014-03-18 12:58:24 +0200534 smp_s1(tfm, smp->tk, smp->prnd, smp->rrnd, stk);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300535
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300536 memset(stk + smp->enc_key_size, 0,
Marcel Holtmannf1560462013-10-13 05:43:25 -0700537 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300538
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700539 hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
Johan Hedberg35d70272014-02-19 14:57:47 +0200540 HCI_SMP_STK_SLAVE, 0, stk, smp->enc_key_size,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300541 ediv, rand);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300542 }
543
544 return;
545
546error:
Johan Hedberg84794e12013-11-06 11:24:57 +0200547 smp_failure(conn, reason);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300548}
549
Johan Hedberge3098be2014-02-28 18:10:03 +0200550static void smp_reencrypt(struct work_struct *work)
551{
552 struct smp_chan *smp = container_of(work, struct smp_chan,
553 reencrypt.work);
554 struct l2cap_conn *conn = smp->conn;
555 struct hci_conn *hcon = conn->hcon;
556 struct smp_ltk *ltk = smp->ltk;
557
558 BT_DBG("");
559
560 hci_le_start_enc(hcon, ltk->ediv, ltk->rand, ltk->val);
561 hcon->enc_key_size = ltk->enc_size;
562}
563
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300564static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
565{
566 struct smp_chan *smp;
567
Marcel Holtmannf1560462013-10-13 05:43:25 -0700568 smp = kzalloc(sizeof(*smp), GFP_ATOMIC);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300569 if (!smp)
570 return NULL;
571
572 INIT_WORK(&smp->confirm, confirm_work);
573 INIT_WORK(&smp->random, random_work);
Johan Hedberge3098be2014-02-28 18:10:03 +0200574 INIT_DELAYED_WORK(&smp->reencrypt, smp_reencrypt);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300575
576 smp->conn = conn;
577 conn->smp_chan = smp;
Brian Gix2b64d152011-12-21 16:12:12 -0800578 conn->hcon->smp_conn = conn;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300579
580 hci_conn_hold(conn->hcon);
581
582 return smp;
583}
584
585void smp_chan_destroy(struct l2cap_conn *conn)
586{
Brian Gixc8eb9692011-11-23 08:28:35 -0800587 struct smp_chan *smp = conn->smp_chan;
Johan Hedbergf4a407b2014-02-18 21:41:34 +0200588 bool complete;
Brian Gixc8eb9692011-11-23 08:28:35 -0800589
Vinicius Costa Gomesf1c09c02012-02-01 18:27:56 -0300590 BUG_ON(!smp);
Brian Gixc8eb9692011-11-23 08:28:35 -0800591
Johan Hedberge3098be2014-02-28 18:10:03 +0200592 cancel_delayed_work_sync(&smp->reencrypt);
593
Johan Hedbergf4a407b2014-02-18 21:41:34 +0200594 complete = test_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
595 mgmt_smp_complete(conn->hcon, complete);
596
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -0700597 kfree(smp->csrk);
598 kfree(smp->slave_csrk);
599
Johan Hedberg759331d2014-02-28 10:10:16 +0200600 /* If pairing failed clean up any keys we might have */
601 if (!complete) {
602 if (smp->ltk) {
603 list_del(&smp->ltk->list);
604 kfree(smp->ltk);
605 }
606
607 if (smp->slave_ltk) {
608 list_del(&smp->slave_ltk->list);
609 kfree(smp->slave_ltk);
610 }
611
612 if (smp->remote_irk) {
613 list_del(&smp->remote_irk->list);
614 kfree(smp->remote_irk);
615 }
616 }
617
Brian Gixc8eb9692011-11-23 08:28:35 -0800618 kfree(smp);
619 conn->smp_chan = NULL;
Brian Gix2b64d152011-12-21 16:12:12 -0800620 conn->hcon->smp_conn = NULL;
David Herrmann76a68ba2013-04-06 20:28:37 +0200621 hci_conn_drop(conn->hcon);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300622}
623
Brian Gix2b64d152011-12-21 16:12:12 -0800624int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
625{
626 struct l2cap_conn *conn = hcon->smp_conn;
627 struct smp_chan *smp;
628 u32 value;
Brian Gix2b64d152011-12-21 16:12:12 -0800629
630 BT_DBG("");
631
632 if (!conn)
633 return -ENOTCONN;
634
635 smp = conn->smp_chan;
636
637 switch (mgmt_op) {
638 case MGMT_OP_USER_PASSKEY_REPLY:
639 value = le32_to_cpu(passkey);
Johan Hedberg943a7322014-03-18 12:58:24 +0200640 memset(smp->tk, 0, sizeof(smp->tk));
Brian Gix2b64d152011-12-21 16:12:12 -0800641 BT_DBG("PassKey: %d", value);
Johan Hedberg943a7322014-03-18 12:58:24 +0200642 put_unaligned_le32(value, smp->tk);
Brian Gix2b64d152011-12-21 16:12:12 -0800643 /* Fall Through */
644 case MGMT_OP_USER_CONFIRM_REPLY:
645 set_bit(SMP_FLAG_TK_VALID, &smp->smp_flags);
646 break;
647 case MGMT_OP_USER_PASSKEY_NEG_REPLY:
648 case MGMT_OP_USER_CONFIRM_NEG_REPLY:
Johan Hedberg84794e12013-11-06 11:24:57 +0200649 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
Brian Gix2b64d152011-12-21 16:12:12 -0800650 return 0;
651 default:
Johan Hedberg84794e12013-11-06 11:24:57 +0200652 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
Brian Gix2b64d152011-12-21 16:12:12 -0800653 return -EOPNOTSUPP;
654 }
655
656 /* If it is our turn to send Pairing Confirm, do so now */
657 if (test_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags))
658 queue_work(hcon->hdev->workqueue, &smp->confirm);
659
660 return 0;
661}
662
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300663static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300664{
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300665 struct smp_cmd_pairing rsp, *req = (void *) skb->data;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300666 struct smp_chan *smp;
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300667 u8 key_size;
Brian Gix2b64d152011-12-21 16:12:12 -0800668 u8 auth = SMP_AUTH_NONE;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300669 int ret;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300670
671 BT_DBG("conn %p", conn);
672
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200673 if (skb->len < sizeof(*req))
674 return SMP_UNSPECIFIED;
675
Brian Gix2b64d152011-12-21 16:12:12 -0800676 if (conn->hcon->link_mode & HCI_LM_MASTER)
677 return SMP_CMD_NOTSUPP;
678
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200679 if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags))
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300680 smp = smp_chan_create(conn);
Andrei Emeltchenkod08fd0e2012-07-19 17:03:43 +0300681 else
682 smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300683
Andrei Emeltchenkod08fd0e2012-07-19 17:03:43 +0300684 if (!smp)
685 return SMP_UNSPECIFIED;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300686
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300687 smp->preq[0] = SMP_CMD_PAIRING_REQ;
688 memcpy(&smp->preq[1], req, sizeof(*req));
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300689 skb_pull(skb, sizeof(*req));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300690
Brian Gix2b64d152011-12-21 16:12:12 -0800691 /* We didn't start the pairing, so match remote */
692 if (req->auth_req & SMP_AUTH_BONDING)
693 auth = req->auth_req;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300694
Ido Yarivfdde0a22012-03-05 20:09:38 +0200695 conn->hcon->pending_sec_level = authreq_to_seclevel(auth);
696
Brian Gix2b64d152011-12-21 16:12:12 -0800697 build_pairing_cmd(conn, req, &rsp, auth);
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300698
699 key_size = min(req->max_key_size, rsp.max_key_size);
700 if (check_enc_key_size(conn, key_size))
701 return SMP_ENC_KEY_SIZE;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300702
Johan Hedberge84a6b12013-12-02 10:49:03 +0200703 get_random_bytes(smp->prnd, sizeof(smp->prnd));
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300704
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300705 smp->prsp[0] = SMP_CMD_PAIRING_RSP;
706 memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300707
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300708 smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300709
Brian Gix2b64d152011-12-21 16:12:12 -0800710 /* Request setup of TK */
711 ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability);
712 if (ret)
713 return SMP_UNSPECIFIED;
714
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300715 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300716}
717
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300718static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300719{
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300720 struct smp_cmd_pairing *req, *rsp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300721 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300722 struct hci_dev *hdev = conn->hcon->hdev;
Brian Gix2b64d152011-12-21 16:12:12 -0800723 u8 key_size, auth = SMP_AUTH_NONE;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300724 int ret;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300725
726 BT_DBG("conn %p", conn);
727
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200728 if (skb->len < sizeof(*rsp))
729 return SMP_UNSPECIFIED;
730
Brian Gix2b64d152011-12-21 16:12:12 -0800731 if (!(conn->hcon->link_mode & HCI_LM_MASTER))
732 return SMP_CMD_NOTSUPP;
733
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300734 skb_pull(skb, sizeof(*rsp));
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300735
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300736 req = (void *) &smp->preq[1];
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300737
738 key_size = min(req->max_key_size, rsp->max_key_size);
739 if (check_enc_key_size(conn, key_size))
740 return SMP_ENC_KEY_SIZE;
741
Johan Hedberge84a6b12013-12-02 10:49:03 +0200742 get_random_bytes(smp->prnd, sizeof(smp->prnd));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300743
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300744 smp->prsp[0] = SMP_CMD_PAIRING_RSP;
745 memcpy(&smp->prsp[1], rsp, sizeof(*rsp));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300746
Johan Hedbergfdcc4be2014-03-14 10:53:50 +0200747 /* Update remote key distribution in case the remote cleared
748 * some bits that we had enabled in our request.
749 */
750 smp->remote_key_dist &= rsp->resp_key_dist;
751
Brian Gix2b64d152011-12-21 16:12:12 -0800752 if ((req->auth_req & SMP_AUTH_BONDING) &&
Marcel Holtmannf1560462013-10-13 05:43:25 -0700753 (rsp->auth_req & SMP_AUTH_BONDING))
Brian Gix2b64d152011-12-21 16:12:12 -0800754 auth = SMP_AUTH_BONDING;
755
756 auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM;
757
Johan Hedberg476585e2012-06-06 18:54:15 +0800758 ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability);
Brian Gix2b64d152011-12-21 16:12:12 -0800759 if (ret)
760 return SMP_UNSPECIFIED;
761
762 set_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags);
763
764 /* Can't compose response until we have been confirmed */
Johan Hedberg18e4aeb2014-03-19 14:14:51 +0200765 if (test_bit(SMP_FLAG_TK_VALID, &smp->smp_flags))
766 queue_work(hdev->workqueue, &smp->confirm);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300767
768 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300769}
770
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300771static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300772{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300773 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300774 struct hci_dev *hdev = conn->hcon->hdev;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300775
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300776 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
777
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200778 if (skb->len < sizeof(smp->pcnf))
779 return SMP_UNSPECIFIED;
780
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300781 memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf));
782 skb_pull(skb, sizeof(smp->pcnf));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300783
Johan Hedberg943a7322014-03-18 12:58:24 +0200784 if (conn->hcon->out)
785 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
786 smp->prnd);
787 else if (test_bit(SMP_FLAG_TK_VALID, &smp->smp_flags))
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300788 queue_work(hdev->workqueue, &smp->confirm);
Johan Hedberg943a7322014-03-18 12:58:24 +0200789 else
Brian Gix2b64d152011-12-21 16:12:12 -0800790 set_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300791
792 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300793}
794
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300795static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300796{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300797 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300798 struct hci_dev *hdev = conn->hcon->hdev;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300799
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300800 BT_DBG("conn %p", conn);
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300801
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200802 if (skb->len < sizeof(smp->rrnd))
803 return SMP_UNSPECIFIED;
804
Johan Hedberg943a7322014-03-18 12:58:24 +0200805 memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd));
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300806 skb_pull(skb, sizeof(smp->rrnd));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300807
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300808 queue_work(hdev->workqueue, &smp->random);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300809
810 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300811}
812
Johan Hedberg4dab7862012-06-07 14:58:37 +0800813static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300814{
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300815 struct smp_ltk *key;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300816 struct hci_conn *hcon = conn->hcon;
817
Johan Hedberg98a0b842014-01-30 19:40:00 -0800818 key = hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type,
819 hcon->out);
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300820 if (!key)
821 return 0;
822
Johan Hedberg4dab7862012-06-07 14:58:37 +0800823 if (sec_level > BT_SECURITY_MEDIUM && !key->authenticated)
824 return 0;
825
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200826 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300827 return 1;
828
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300829 hci_le_start_enc(hcon, key->ediv, key->rand, key->val);
830 hcon->enc_key_size = key->enc_size;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300831
832 return 1;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300833}
Marcel Holtmannf1560462013-10-13 05:43:25 -0700834
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300835static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300836{
837 struct smp_cmd_security_req *rp = (void *) skb->data;
838 struct smp_cmd_pairing cp;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300839 struct hci_conn *hcon = conn->hcon;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300840 struct smp_chan *smp;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300841
842 BT_DBG("conn %p", conn);
843
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200844 if (skb->len < sizeof(*rp))
845 return SMP_UNSPECIFIED;
846
Johan Hedberg86ca9ea2013-11-05 11:30:39 +0200847 if (!(conn->hcon->link_mode & HCI_LM_MASTER))
848 return SMP_CMD_NOTSUPP;
849
Brian Gix2b64d152011-12-21 16:12:12 -0800850 hcon->pending_sec_level = authreq_to_seclevel(rp->auth_req);
Vinicius Costa Gomesfeb45eb2011-08-25 20:02:35 -0300851
Johan Hedberg4dab7862012-06-07 14:58:37 +0800852 if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300853 return 0;
854
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200855 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300856 return 0;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300857
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300858 smp = smp_chan_create(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300859
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300860 skb_pull(skb, sizeof(*rp));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300861
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300862 memset(&cp, 0, sizeof(cp));
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300863 build_pairing_cmd(conn, &cp, NULL, rp->auth_req);
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300864
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300865 smp->preq[0] = SMP_CMD_PAIRING_REQ;
866 memcpy(&smp->preq[1], &cp, sizeof(cp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300867
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300868 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300869
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300870 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300871}
872
Johan Hedbergad32a2f2013-05-14 18:05:12 +0300873bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level)
874{
875 if (sec_level == BT_SECURITY_LOW)
876 return true;
877
878 if (hcon->sec_level >= sec_level)
879 return true;
880
881 return false;
882}
883
Vinicius Costa Gomescc110922012-08-23 21:32:43 -0300884int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300885{
Vinicius Costa Gomescc110922012-08-23 21:32:43 -0300886 struct l2cap_conn *conn = hcon->l2cap_data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300887 struct smp_chan *smp = conn->smp_chan;
Brian Gix2b64d152011-12-21 16:12:12 -0800888 __u8 authreq;
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300889
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -0300890 BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
891
Johan Hedberg757aee02013-04-24 13:05:32 +0300892 if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags))
Andre Guedes2e65c9d2011-06-30 19:20:56 -0300893 return 1;
894
Johan Hedbergad32a2f2013-05-14 18:05:12 +0300895 if (smp_sufficient_security(hcon, sec_level))
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300896 return 1;
897
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300898 if (hcon->link_mode & HCI_LM_MASTER)
Johan Hedberg4dab7862012-06-07 14:58:37 +0800899 if (smp_ltk_encrypt(conn, sec_level))
Vinicius Costa Gomes02bc7452011-07-07 18:59:41 -0300900 goto done;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300901
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200902 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300903 return 0;
904
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300905 smp = smp_chan_create(conn);
Brian Gix2b64d152011-12-21 16:12:12 -0800906 if (!smp)
907 return 1;
908
909 authreq = seclevel_to_authreq(sec_level);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300910
Johan Hedberg2e233642014-03-18 15:42:30 +0200911 /* hcon->auth_type is set by pair_device in mgmt.c. If the MITM
912 * flag is set we should also set it for the SMP request.
913 */
914 if ((hcon->auth_type & 0x01))
915 authreq |= SMP_AUTH_MITM;
916
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300917 if (hcon->link_mode & HCI_LM_MASTER) {
918 struct smp_cmd_pairing cp;
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300919
Brian Gix2b64d152011-12-21 16:12:12 -0800920 build_pairing_cmd(conn, &cp, NULL, authreq);
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300921 smp->preq[0] = SMP_CMD_PAIRING_REQ;
922 memcpy(&smp->preq[1], &cp, sizeof(cp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300923
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300924 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
925 } else {
926 struct smp_cmd_security_req cp;
Brian Gix2b64d152011-12-21 16:12:12 -0800927 cp.auth_req = authreq;
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300928 smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
929 }
930
Vinicius Costa Gomes02bc7452011-07-07 18:59:41 -0300931done:
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300932 hcon->pending_sec_level = sec_level;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300933
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300934 return 0;
935}
936
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300937static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
938{
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300939 struct smp_cmd_encrypt_info *rp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300940 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300941
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200942 BT_DBG("conn %p", conn);
943
944 if (skb->len < sizeof(*rp))
945 return SMP_UNSPECIFIED;
946
Johan Hedberg6131ddc2014-02-18 10:19:37 +0200947 /* Ignore this PDU if it wasn't requested */
948 if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
949 return 0;
950
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300951 skb_pull(skb, sizeof(*rp));
952
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300953 memcpy(smp->tk, rp->ltk, sizeof(smp->tk));
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300954
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300955 return 0;
956}
957
958static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
959{
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300960 struct smp_cmd_master_ident *rp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300961 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300962 struct hci_dev *hdev = conn->hcon->hdev;
963 struct hci_conn *hcon = conn->hcon;
Johan Hedberg23d0e122014-02-19 14:57:46 +0200964 struct smp_ltk *ltk;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300965 u8 authenticated;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300966
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200967 BT_DBG("conn %p", conn);
968
969 if (skb->len < sizeof(*rp))
970 return SMP_UNSPECIFIED;
971
Johan Hedberg6131ddc2014-02-18 10:19:37 +0200972 /* Ignore this PDU if it wasn't requested */
973 if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
974 return 0;
975
Johan Hedberg9747a9f2014-02-26 23:33:43 +0200976 /* Mark the information as received */
977 smp->remote_key_dist &= ~SMP_DIST_ENC_KEY;
978
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300979 skb_pull(skb, sizeof(*rp));
980
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300981 hci_dev_lock(hdev);
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700982 authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
Johan Hedberg35d70272014-02-19 14:57:47 +0200983 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, HCI_SMP_LTK,
Johan Hedberg23d0e122014-02-19 14:57:46 +0200984 authenticated, smp->tk, smp->enc_key_size,
985 rp->ediv, rp->rand);
986 smp->ltk = ltk;
Johan Hedbergfd349c02014-02-18 10:19:36 +0200987 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
Johan Hedberg4bd6d382014-02-26 23:33:45 +0200988 smp_distribute_keys(conn);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300989 hci_dev_unlock(hdev);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300990
991 return 0;
992}
993
Johan Hedbergfd349c02014-02-18 10:19:36 +0200994static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
995{
996 struct smp_cmd_ident_info *info = (void *) skb->data;
997 struct smp_chan *smp = conn->smp_chan;
998
999 BT_DBG("");
1000
1001 if (skb->len < sizeof(*info))
1002 return SMP_UNSPECIFIED;
1003
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001004 /* Ignore this PDU if it wasn't requested */
1005 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
1006 return 0;
1007
Johan Hedbergfd349c02014-02-18 10:19:36 +02001008 skb_pull(skb, sizeof(*info));
1009
1010 memcpy(smp->irk, info->irk, 16);
1011
1012 return 0;
1013}
1014
1015static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
1016 struct sk_buff *skb)
1017{
1018 struct smp_cmd_ident_addr_info *info = (void *) skb->data;
1019 struct smp_chan *smp = conn->smp_chan;
1020 struct hci_conn *hcon = conn->hcon;
1021 bdaddr_t rpa;
1022
1023 BT_DBG("");
1024
1025 if (skb->len < sizeof(*info))
1026 return SMP_UNSPECIFIED;
1027
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001028 /* Ignore this PDU if it wasn't requested */
1029 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
1030 return 0;
1031
Johan Hedberg9747a9f2014-02-26 23:33:43 +02001032 /* Mark the information as received */
1033 smp->remote_key_dist &= ~SMP_DIST_ID_KEY;
1034
Johan Hedbergfd349c02014-02-18 10:19:36 +02001035 skb_pull(skb, sizeof(*info));
1036
Johan Hedberga9a58f82014-02-25 22:24:37 +02001037 /* Strictly speaking the Core Specification (4.1) allows sending
1038 * an empty address which would force us to rely on just the IRK
1039 * as "identity information". However, since such
1040 * implementations are not known of and in order to not over
1041 * complicate our implementation, simply pretend that we never
1042 * received an IRK for such a device.
1043 */
1044 if (!bacmp(&info->bdaddr, BDADDR_ANY)) {
1045 BT_ERR("Ignoring IRK with no identity address");
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001046 smp_distribute_keys(conn);
Johan Hedberga9a58f82014-02-25 22:24:37 +02001047 return 0;
1048 }
1049
Johan Hedbergfd349c02014-02-18 10:19:36 +02001050 bacpy(&smp->id_addr, &info->bdaddr);
1051 smp->id_addr_type = info->addr_type;
1052
1053 if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type))
1054 bacpy(&rpa, &hcon->dst);
1055 else
1056 bacpy(&rpa, BDADDR_ANY);
1057
Johan Hedberg23d0e122014-02-19 14:57:46 +02001058 smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
1059 smp->id_addr_type, smp->irk, &rpa);
Johan Hedbergfd349c02014-02-18 10:19:36 +02001060
Johan Hedberg68d6f6d2014-02-18 21:41:32 +02001061 /* Track the connection based on the Identity Address from now on */
1062 bacpy(&hcon->dst, &smp->id_addr);
1063 hcon->dst_type = smp->id_addr_type;
1064
Johan Hedberg387a33e2014-02-18 21:41:33 +02001065 l2cap_conn_update_id_addr(hcon);
1066
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001067 smp_distribute_keys(conn);
Johan Hedbergfd349c02014-02-18 10:19:36 +02001068
1069 return 0;
1070}
1071
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001072static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)
1073{
1074 struct smp_cmd_sign_info *rp = (void *) skb->data;
1075 struct smp_chan *smp = conn->smp_chan;
1076 struct hci_dev *hdev = conn->hcon->hdev;
1077 struct smp_csrk *csrk;
1078
1079 BT_DBG("conn %p", conn);
1080
1081 if (skb->len < sizeof(*rp))
1082 return SMP_UNSPECIFIED;
1083
1084 /* Ignore this PDU if it wasn't requested */
1085 if (!(smp->remote_key_dist & SMP_DIST_SIGN))
1086 return 0;
1087
1088 /* Mark the information as received */
1089 smp->remote_key_dist &= ~SMP_DIST_SIGN;
1090
1091 skb_pull(skb, sizeof(*rp));
1092
1093 hci_dev_lock(hdev);
1094 csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
1095 if (csrk) {
1096 csrk->master = 0x01;
1097 memcpy(csrk->val, rp->csrk, sizeof(csrk->val));
1098 }
1099 smp->csrk = csrk;
1100 if (!(smp->remote_key_dist & SMP_DIST_SIGN))
1101 smp_distribute_keys(conn);
1102 hci_dev_unlock(hdev);
1103
1104 return 0;
1105}
1106
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001107int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
1108{
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001109 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann92381f52013-10-03 01:23:08 -07001110 __u8 code, reason;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001111 int err = 0;
1112
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001113 if (hcon->type != LE_LINK) {
1114 kfree_skb(skb);
Johan Hedberg34327112013-10-16 11:37:01 +03001115 return 0;
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001116 }
1117
Marcel Holtmann92381f52013-10-03 01:23:08 -07001118 if (skb->len < 1) {
1119 kfree_skb(skb);
1120 return -EILSEQ;
1121 }
1122
Marcel Holtmann06ae3312013-10-18 03:43:00 -07001123 if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) {
Andre Guedes2e65c9d2011-06-30 19:20:56 -03001124 err = -ENOTSUPP;
1125 reason = SMP_PAIRING_NOTSUPP;
1126 goto done;
1127 }
1128
Marcel Holtmann92381f52013-10-03 01:23:08 -07001129 code = skb->data[0];
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001130 skb_pull(skb, sizeof(code));
1131
Johan Hedberg8cf9fa12013-01-29 10:44:23 -06001132 /*
1133 * The SMP context must be initialized for all other PDUs except
1134 * pairing and security requests. If we get any other PDU when
1135 * not initialized simply disconnect (done if this function
1136 * returns an error).
1137 */
1138 if (code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ &&
1139 !conn->smp_chan) {
1140 BT_ERR("Unexpected SMP command 0x%02x. Disconnecting.", code);
1141 kfree_skb(skb);
1142 return -ENOTSUPP;
1143 }
1144
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001145 switch (code) {
1146 case SMP_CMD_PAIRING_REQ:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001147 reason = smp_cmd_pairing_req(conn, skb);
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001148 break;
1149
1150 case SMP_CMD_PAIRING_FAIL:
Johan Hedberg84794e12013-11-06 11:24:57 +02001151 smp_failure(conn, 0);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001152 reason = 0;
1153 err = -EPERM;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001154 break;
1155
1156 case SMP_CMD_PAIRING_RSP:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001157 reason = smp_cmd_pairing_rsp(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001158 break;
1159
1160 case SMP_CMD_SECURITY_REQ:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001161 reason = smp_cmd_security_req(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001162 break;
1163
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001164 case SMP_CMD_PAIRING_CONFIRM:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001165 reason = smp_cmd_pairing_confirm(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001166 break;
1167
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001168 case SMP_CMD_PAIRING_RANDOM:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001169 reason = smp_cmd_pairing_random(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001170 break;
1171
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001172 case SMP_CMD_ENCRYPT_INFO:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001173 reason = smp_cmd_encrypt_info(conn, skb);
1174 break;
1175
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001176 case SMP_CMD_MASTER_IDENT:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001177 reason = smp_cmd_master_ident(conn, skb);
1178 break;
1179
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001180 case SMP_CMD_IDENT_INFO:
Johan Hedbergfd349c02014-02-18 10:19:36 +02001181 reason = smp_cmd_ident_info(conn, skb);
1182 break;
1183
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001184 case SMP_CMD_IDENT_ADDR_INFO:
Johan Hedbergfd349c02014-02-18 10:19:36 +02001185 reason = smp_cmd_ident_addr_info(conn, skb);
1186 break;
1187
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001188 case SMP_CMD_SIGN_INFO:
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001189 reason = smp_cmd_sign_info(conn, skb);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001190 break;
1191
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001192 default:
1193 BT_DBG("Unknown command code 0x%2.2x", code);
1194
1195 reason = SMP_CMD_NOTSUPP;
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -03001196 err = -EOPNOTSUPP;
1197 goto done;
1198 }
1199
1200done:
1201 if (reason)
Johan Hedberg84794e12013-11-06 11:24:57 +02001202 smp_failure(conn, reason);
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001203
1204 kfree_skb(skb);
1205 return err;
1206}
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001207
Johan Hedberg35d70272014-02-19 14:57:47 +02001208static void smp_notify_keys(struct l2cap_conn *conn)
1209{
1210 struct smp_chan *smp = conn->smp_chan;
1211 struct hci_conn *hcon = conn->hcon;
1212 struct hci_dev *hdev = hcon->hdev;
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001213 struct smp_cmd_pairing *req = (void *) &smp->preq[1];
1214 struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1];
1215 bool persistent;
Johan Hedberg35d70272014-02-19 14:57:47 +02001216
Johan Hedberg95fbac82014-02-19 15:18:31 +02001217 if (smp->remote_irk)
1218 mgmt_new_irk(hdev, smp->remote_irk);
1219
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001220 /* The LTKs and CSRKs should be persistent only if both sides
1221 * had the bonding bit set in their authentication requests.
1222 */
1223 persistent = !!((req->auth_req & rsp->auth_req) & SMP_AUTH_BONDING);
1224
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001225 if (smp->csrk) {
1226 smp->csrk->bdaddr_type = hcon->dst_type;
1227 bacpy(&smp->csrk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001228 mgmt_new_csrk(hdev, smp->csrk, persistent);
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001229 }
1230
1231 if (smp->slave_csrk) {
1232 smp->slave_csrk->bdaddr_type = hcon->dst_type;
1233 bacpy(&smp->slave_csrk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001234 mgmt_new_csrk(hdev, smp->slave_csrk, persistent);
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001235 }
1236
Johan Hedberg35d70272014-02-19 14:57:47 +02001237 if (smp->ltk) {
1238 smp->ltk->bdaddr_type = hcon->dst_type;
1239 bacpy(&smp->ltk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001240 mgmt_new_ltk(hdev, smp->ltk, persistent);
Johan Hedberg35d70272014-02-19 14:57:47 +02001241 }
1242
1243 if (smp->slave_ltk) {
1244 smp->slave_ltk->bdaddr_type = hcon->dst_type;
1245 bacpy(&smp->slave_ltk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001246 mgmt_new_ltk(hdev, smp->slave_ltk, persistent);
Johan Hedberg35d70272014-02-19 14:57:47 +02001247 }
1248}
1249
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001250int smp_distribute_keys(struct l2cap_conn *conn)
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001251{
1252 struct smp_cmd_pairing *req, *rsp;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001253 struct smp_chan *smp = conn->smp_chan;
Johan Hedberg524237c2014-02-22 19:06:31 +02001254 struct hci_conn *hcon = conn->hcon;
1255 struct hci_dev *hdev = hcon->hdev;
Johan Hedberg38ccdc92014-02-28 18:10:02 +02001256 bool ltk_encrypt;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001257 __u8 *keydist;
1258
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001259 BT_DBG("conn %p", conn);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001260
Johan Hedberg524237c2014-02-22 19:06:31 +02001261 if (!test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001262 return 0;
1263
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001264 rsp = (void *) &smp->prsp[1];
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001265
1266 /* The responder sends its keys first */
Johan Hedbergefabba32014-02-26 23:33:44 +02001267 if (hcon->out && (smp->remote_key_dist & 0x07))
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001268 return 0;
1269
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001270 req = (void *) &smp->preq[1];
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001271
Johan Hedberg524237c2014-02-22 19:06:31 +02001272 if (hcon->out) {
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001273 keydist = &rsp->init_key_dist;
1274 *keydist &= req->init_key_dist;
1275 } else {
1276 keydist = &rsp->resp_key_dist;
1277 *keydist &= req->resp_key_dist;
1278 }
1279
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001280 BT_DBG("keydist 0x%x", *keydist);
1281
1282 if (*keydist & SMP_DIST_ENC_KEY) {
1283 struct smp_cmd_encrypt_info enc;
1284 struct smp_cmd_master_ident ident;
Johan Hedberg23d0e122014-02-19 14:57:46 +02001285 struct smp_ltk *ltk;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001286 u8 authenticated;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001287 __le16 ediv;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001288 __le64 rand;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001289
1290 get_random_bytes(enc.ltk, sizeof(enc.ltk));
1291 get_random_bytes(&ediv, sizeof(ediv));
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001292 get_random_bytes(&rand, sizeof(rand));
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001293
1294 smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
1295
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001296 authenticated = hcon->sec_level == BT_SECURITY_HIGH;
Johan Hedberg524237c2014-02-22 19:06:31 +02001297 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type,
Johan Hedberg35d70272014-02-19 14:57:47 +02001298 HCI_SMP_LTK_SLAVE, authenticated, enc.ltk,
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001299 smp->enc_key_size, ediv, rand);
Johan Hedberg23d0e122014-02-19 14:57:46 +02001300 smp->slave_ltk = ltk;
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001301
Andrei Emeltchenko58115372012-03-12 12:13:06 +02001302 ident.ediv = ediv;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001303 ident.rand = rand;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001304
1305 smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident);
1306
1307 *keydist &= ~SMP_DIST_ENC_KEY;
1308 }
1309
1310 if (*keydist & SMP_DIST_ID_KEY) {
1311 struct smp_cmd_ident_addr_info addrinfo;
1312 struct smp_cmd_ident_info idinfo;
1313
Johan Hedberg863efaf2014-02-22 19:06:32 +02001314 memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk));
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001315
1316 smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo);
1317
Johan Hedberg82d4b352014-02-23 19:42:18 +02001318 /* The hci_conn contains the local identity address
1319 * after the connection has been established.
1320 *
1321 * This is true even when the connection has been
1322 * established using a resolvable random address.
1323 */
Johan Hedberg524237c2014-02-22 19:06:31 +02001324 bacpy(&addrinfo.bdaddr, &hcon->src);
Johan Hedberg82d4b352014-02-23 19:42:18 +02001325 addrinfo.addr_type = hcon->src_type;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001326
1327 smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo),
Marcel Holtmannf1560462013-10-13 05:43:25 -07001328 &addrinfo);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001329
1330 *keydist &= ~SMP_DIST_ID_KEY;
1331 }
1332
1333 if (*keydist & SMP_DIST_SIGN) {
1334 struct smp_cmd_sign_info sign;
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001335 struct smp_csrk *csrk;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001336
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001337 /* Generate a new random key */
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001338 get_random_bytes(sign.csrk, sizeof(sign.csrk));
1339
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001340 csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
1341 if (csrk) {
1342 csrk->master = 0x00;
1343 memcpy(csrk->val, sign.csrk, sizeof(csrk->val));
1344 }
1345 smp->slave_csrk = csrk;
1346
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001347 smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign);
1348
1349 *keydist &= ~SMP_DIST_SIGN;
1350 }
1351
Johan Hedbergefabba32014-02-26 23:33:44 +02001352 /* If there are still keys to be received wait for them */
1353 if ((smp->remote_key_dist & 0x07))
1354 return 0;
1355
Johan Hedberg38ccdc92014-02-28 18:10:02 +02001356 /* Check if we should try to re-encrypt the link with the LTK.
1357 * SMP_FLAG_LTK_ENCRYPT flag is used to track whether we've
1358 * already tried this (in which case we shouldn't try again).
1359 *
1360 * The request will trigger an encryption key refresh event
1361 * which will cause a call to auth_cfm and eventually lead to
1362 * l2cap_core.c calling this smp_distribute_keys function again
1363 * and thereby completing the process.
1364 */
1365 if (smp->ltk)
1366 ltk_encrypt = !test_and_set_bit(SMP_FLAG_LTK_ENCRYPT,
1367 &smp->smp_flags);
1368 else
1369 ltk_encrypt = false;
Johan Hedbergefabba32014-02-26 23:33:44 +02001370
Johan Hedberg38ccdc92014-02-28 18:10:02 +02001371 /* Re-encrypt the link with LTK if possible */
1372 if (ltk_encrypt && hcon->out) {
Johan Hedberge3098be2014-02-28 18:10:03 +02001373 queue_delayed_work(hdev->req_workqueue, &smp->reencrypt,
1374 SMP_REENCRYPT_TIMEOUT);
Johan Hedberg38ccdc92014-02-28 18:10:02 +02001375 } else {
1376 clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags);
1377 cancel_delayed_work_sync(&conn->security_timer);
1378 set_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
1379 smp_notify_keys(conn);
1380 smp_chan_destroy(conn);
1381 }
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001382
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001383 return 0;
1384}