blob: 6925fc4caaeec27ff04157898855189607e4fd46 [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 Hedberg533e35d2014-06-16 19:25:18 +030038enum {
39 SMP_FLAG_TK_VALID,
40 SMP_FLAG_CFM_PENDING,
41 SMP_FLAG_MITM_AUTH,
42 SMP_FLAG_COMPLETE,
43 SMP_FLAG_INITIATOR,
44};
Johan Hedberg4bc58f52014-05-20 09:45:47 +030045
46struct smp_chan {
47 struct l2cap_conn *conn;
48 u8 preq[7]; /* SMP Pairing Request */
49 u8 prsp[7]; /* SMP Pairing Response */
50 u8 prnd[16]; /* SMP Pairing Random (local) */
51 u8 rrnd[16]; /* SMP Pairing Random (remote) */
52 u8 pcnf[16]; /* SMP Pairing Confirm */
53 u8 tk[16]; /* SMP Temporary Key */
54 u8 enc_key_size;
55 u8 remote_key_dist;
56 bdaddr_t id_addr;
57 u8 id_addr_type;
58 u8 irk[16];
59 struct smp_csrk *csrk;
60 struct smp_csrk *slave_csrk;
61 struct smp_ltk *ltk;
62 struct smp_ltk *slave_ltk;
63 struct smp_irk *remote_irk;
Johan Hedberg4a74d652014-05-20 09:45:50 +030064 unsigned long flags;
Johan Hedberg6a7bd102014-06-27 14:23:03 +030065
66 struct crypto_blkcipher *tfm_aes;
Johan Hedberg4bc58f52014-05-20 09:45:47 +030067};
68
Johan Hedberg8a2936f2014-06-16 19:25:19 +030069static inline void swap_buf(const u8 *src, u8 *dst, size_t len)
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030070{
Johan Hedberg8a2936f2014-06-16 19:25:19 +030071 size_t i;
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030072
Johan Hedberg8a2936f2014-06-16 19:25:19 +030073 for (i = 0; i < len; i++)
74 dst[len - 1 - i] = src[i];
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030075}
76
77static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
78{
79 struct blkcipher_desc desc;
80 struct scatterlist sg;
Johan Hedberg943a7322014-03-18 12:58:24 +020081 uint8_t tmp[16], data[16];
Johan Hedberg201a5922013-12-02 10:49:04 +020082 int err;
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030083
84 if (tfm == NULL) {
85 BT_ERR("tfm %p", tfm);
86 return -EINVAL;
87 }
88
89 desc.tfm = tfm;
90 desc.flags = 0;
91
Johan Hedberg943a7322014-03-18 12:58:24 +020092 /* The most significant octet of key corresponds to k[0] */
Johan Hedberg8a2936f2014-06-16 19:25:19 +030093 swap_buf(k, tmp, 16);
Johan Hedberg943a7322014-03-18 12:58:24 +020094
95 err = crypto_blkcipher_setkey(tfm, tmp, 16);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -030096 if (err) {
97 BT_ERR("cipher setkey failed: %d", err);
98 return err;
99 }
100
Johan Hedberg943a7322014-03-18 12:58:24 +0200101 /* Most significant octet of plaintextData corresponds to data[0] */
Johan Hedberg8a2936f2014-06-16 19:25:19 +0300102 swap_buf(r, data, 16);
Johan Hedberg943a7322014-03-18 12:58:24 +0200103
104 sg_init_one(&sg, data, 16);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300105
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300106 err = crypto_blkcipher_encrypt(&desc, &sg, &sg, 16);
107 if (err)
108 BT_ERR("Encrypt data error %d", err);
109
Johan Hedberg943a7322014-03-18 12:58:24 +0200110 /* Most significant octet of encryptedData corresponds to data[0] */
Johan Hedberg8a2936f2014-06-16 19:25:19 +0300111 swap_buf(data, r, 16);
Johan Hedberg943a7322014-03-18 12:58:24 +0200112
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300113 return err;
114}
115
Johan Hedberg60478052014-02-18 10:19:31 +0200116static int smp_ah(struct crypto_blkcipher *tfm, u8 irk[16], u8 r[3], u8 res[3])
117{
Johan Hedberg943a7322014-03-18 12:58:24 +0200118 u8 _res[16];
Johan Hedberg60478052014-02-18 10:19:31 +0200119 int err;
120
121 /* r' = padding || r */
Johan Hedberg943a7322014-03-18 12:58:24 +0200122 memcpy(_res, r, 3);
123 memset(_res + 3, 0, 13);
Johan Hedberg60478052014-02-18 10:19:31 +0200124
Johan Hedberg943a7322014-03-18 12:58:24 +0200125 err = smp_e(tfm, irk, _res);
Johan Hedberg60478052014-02-18 10:19:31 +0200126 if (err) {
127 BT_ERR("Encrypt error");
128 return err;
129 }
130
131 /* The output of the random address function ah is:
132 * ah(h, r) = e(k, r') mod 2^24
133 * The output of the security function e is then truncated to 24 bits
134 * by taking the least significant 24 bits of the output of e as the
135 * result of ah.
136 */
Johan Hedberg943a7322014-03-18 12:58:24 +0200137 memcpy(res, _res, 3);
Johan Hedberg60478052014-02-18 10:19:31 +0200138
139 return 0;
140}
141
Johan Hedbergdefce9e2014-08-08 09:37:17 +0300142bool smp_irk_matches(struct hci_dev *hdev, u8 irk[16], bdaddr_t *bdaddr)
Johan Hedberg60478052014-02-18 10:19:31 +0200143{
Johan Hedbergdefce9e2014-08-08 09:37:17 +0300144 struct l2cap_chan *chan = hdev->smp_data;
145 struct crypto_blkcipher *tfm;
Johan Hedberg60478052014-02-18 10:19:31 +0200146 u8 hash[3];
147 int err;
148
Johan Hedbergdefce9e2014-08-08 09:37:17 +0300149 if (!chan || !chan->data)
150 return false;
151
152 tfm = chan->data;
153
Johan Hedberg60478052014-02-18 10:19:31 +0200154 BT_DBG("RPA %pMR IRK %*phN", bdaddr, 16, irk);
155
156 err = smp_ah(tfm, irk, &bdaddr->b[3], hash);
157 if (err)
158 return false;
159
160 return !memcmp(bdaddr->b, hash, 3);
161}
162
Johan Hedbergdefce9e2014-08-08 09:37:17 +0300163int smp_generate_rpa(struct hci_dev *hdev, u8 irk[16], bdaddr_t *rpa)
Johan Hedbergb1e2b3a2014-02-23 19:42:19 +0200164{
Johan Hedbergdefce9e2014-08-08 09:37:17 +0300165 struct l2cap_chan *chan = hdev->smp_data;
166 struct crypto_blkcipher *tfm;
Johan Hedbergb1e2b3a2014-02-23 19:42:19 +0200167 int err;
168
Johan Hedbergdefce9e2014-08-08 09:37:17 +0300169 if (!chan || !chan->data)
170 return -EOPNOTSUPP;
171
172 tfm = chan->data;
173
Johan Hedbergb1e2b3a2014-02-23 19:42:19 +0200174 get_random_bytes(&rpa->b[3], 3);
175
176 rpa->b[5] &= 0x3f; /* Clear two most significant bits */
177 rpa->b[5] |= 0x40; /* Set second most significant bit */
178
179 err = smp_ah(tfm, irk, &rpa->b[3], rpa->b);
180 if (err < 0)
181 return err;
182
183 BT_DBG("RPA %pMR", rpa);
184
185 return 0;
186}
187
Johan Hedbergec70f362014-06-27 14:23:04 +0300188static int smp_c1(struct smp_chan *smp, u8 k[16], u8 r[16], u8 preq[7],
189 u8 pres[7], u8 _iat, bdaddr_t *ia, u8 _rat, bdaddr_t *ra,
190 u8 res[16])
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300191{
Johan Hedbergec70f362014-06-27 14:23:04 +0300192 struct hci_dev *hdev = smp->conn->hcon->hdev;
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300193 u8 p1[16], p2[16];
194 int err;
195
Johan Hedbergec70f362014-06-27 14:23:04 +0300196 BT_DBG("%s", hdev->name);
197
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300198 memset(p1, 0, 16);
199
200 /* p1 = pres || preq || _rat || _iat */
Johan Hedberg943a7322014-03-18 12:58:24 +0200201 p1[0] = _iat;
202 p1[1] = _rat;
203 memcpy(p1 + 2, preq, 7);
204 memcpy(p1 + 9, pres, 7);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300205
206 /* p2 = padding || ia || ra */
Johan Hedberg943a7322014-03-18 12:58:24 +0200207 memcpy(p2, ra, 6);
208 memcpy(p2 + 6, ia, 6);
209 memset(p2 + 12, 0, 4);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300210
211 /* res = r XOR p1 */
212 u128_xor((u128 *) res, (u128 *) r, (u128 *) p1);
213
214 /* res = e(k, res) */
Johan Hedbergec70f362014-06-27 14:23:04 +0300215 err = smp_e(smp->tfm_aes, k, res);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300216 if (err) {
217 BT_ERR("Encrypt data error");
218 return err;
219 }
220
221 /* res = res XOR p2 */
222 u128_xor((u128 *) res, (u128 *) res, (u128 *) p2);
223
224 /* res = e(k, res) */
Johan Hedbergec70f362014-06-27 14:23:04 +0300225 err = smp_e(smp->tfm_aes, k, res);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300226 if (err)
227 BT_ERR("Encrypt data error");
228
229 return err;
230}
231
Johan Hedbergec70f362014-06-27 14:23:04 +0300232static int smp_s1(struct smp_chan *smp, u8 k[16], u8 r1[16], u8 r2[16],
233 u8 _r[16])
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300234{
Johan Hedbergec70f362014-06-27 14:23:04 +0300235 struct hci_dev *hdev = smp->conn->hcon->hdev;
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300236 int err;
237
Johan Hedbergec70f362014-06-27 14:23:04 +0300238 BT_DBG("%s", hdev->name);
239
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300240 /* Just least significant octets from r1 and r2 are considered */
Johan Hedberg943a7322014-03-18 12:58:24 +0200241 memcpy(_r, r2, 8);
242 memcpy(_r + 8, r1, 8);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300243
Johan Hedbergec70f362014-06-27 14:23:04 +0300244 err = smp_e(smp->tfm_aes, k, _r);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300245 if (err)
246 BT_ERR("Encrypt data error");
247
248 return err;
249}
250
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300251static struct sk_buff *smp_build_cmd(struct l2cap_conn *conn, u8 code,
Marcel Holtmannf1560462013-10-13 05:43:25 -0700252 u16 dlen, void *data)
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300253{
254 struct sk_buff *skb;
255 struct l2cap_hdr *lh;
256 int len;
257
258 len = L2CAP_HDR_SIZE + sizeof(code) + dlen;
259
260 if (len > conn->mtu)
261 return NULL;
262
263 skb = bt_skb_alloc(len, GFP_ATOMIC);
264 if (!skb)
265 return NULL;
266
267 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
268 lh->len = cpu_to_le16(sizeof(code) + dlen);
Joe Perchesdcf4adb2014-03-12 10:52:35 -0700269 lh->cid = cpu_to_le16(L2CAP_CID_SMP);
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300270
271 memcpy(skb_put(skb, sizeof(code)), &code, sizeof(code));
272
273 memcpy(skb_put(skb, dlen), data, dlen);
274
275 return skb;
276}
277
278static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
279{
280 struct sk_buff *skb = smp_build_cmd(conn, code, len, data);
281
282 BT_DBG("code 0x%2.2x", code);
283
284 if (!skb)
285 return;
286
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200287 skb->priority = HCI_PRIO_MAX;
288 hci_send_acl(conn->hchan, skb, 0);
Vinicius Costa Gomese2dcd112011-08-19 21:06:50 -0300289
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -0200290 cancel_delayed_work_sync(&conn->security_timer);
Marcel Holtmann17b02e62012-03-01 14:32:37 -0800291 schedule_delayed_work(&conn->security_timer, SMP_TIMEOUT);
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300292}
293
Brian Gix2b64d152011-12-21 16:12:12 -0800294static __u8 authreq_to_seclevel(__u8 authreq)
295{
296 if (authreq & SMP_AUTH_MITM)
297 return BT_SECURITY_HIGH;
298 else
299 return BT_SECURITY_MEDIUM;
300}
301
302static __u8 seclevel_to_authreq(__u8 sec_level)
303{
304 switch (sec_level) {
305 case BT_SECURITY_HIGH:
306 return SMP_AUTH_MITM | SMP_AUTH_BONDING;
307 case BT_SECURITY_MEDIUM:
308 return SMP_AUTH_BONDING;
309 default:
310 return SMP_AUTH_NONE;
311 }
312}
313
Vinicius Costa Gomesb8e66ea2011-06-09 18:50:52 -0300314static void build_pairing_cmd(struct l2cap_conn *conn,
Marcel Holtmannf1560462013-10-13 05:43:25 -0700315 struct smp_cmd_pairing *req,
316 struct smp_cmd_pairing *rsp, __u8 authreq)
Vinicius Costa Gomesb8e66ea2011-06-09 18:50:52 -0300317{
Johan Hedbergfd349c02014-02-18 10:19:36 +0200318 struct smp_chan *smp = conn->smp_chan;
319 struct hci_conn *hcon = conn->hcon;
320 struct hci_dev *hdev = hcon->hdev;
321 u8 local_dist = 0, remote_dist = 0;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300322
Johan Hedbergb6ae8452014-07-30 09:22:22 +0300323 if (test_bit(HCI_BONDABLE, &conn->hcon->hdev->dev_flags)) {
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -0700324 local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
325 remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300326 authreq |= SMP_AUTH_BONDING;
Brian Gix2b64d152011-12-21 16:12:12 -0800327 } else {
328 authreq &= ~SMP_AUTH_BONDING;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300329 }
330
Johan Hedbergfd349c02014-02-18 10:19:36 +0200331 if (test_bit(HCI_RPA_RESOLVING, &hdev->dev_flags))
332 remote_dist |= SMP_DIST_ID_KEY;
333
Johan Hedberg863efaf2014-02-22 19:06:32 +0200334 if (test_bit(HCI_PRIVACY, &hdev->dev_flags))
335 local_dist |= SMP_DIST_ID_KEY;
336
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300337 if (rsp == NULL) {
338 req->io_capability = conn->hcon->io_capability;
339 req->oob_flag = SMP_OOB_NOT_PRESENT;
340 req->max_key_size = SMP_MAX_ENC_KEY_SIZE;
Johan Hedbergfd349c02014-02-18 10:19:36 +0200341 req->init_key_dist = local_dist;
342 req->resp_key_dist = remote_dist;
Johan Hedberg065a13e2012-10-11 16:26:06 +0200343 req->auth_req = (authreq & AUTH_REQ_MASK);
Johan Hedbergfd349c02014-02-18 10:19:36 +0200344
345 smp->remote_key_dist = remote_dist;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300346 return;
347 }
348
349 rsp->io_capability = conn->hcon->io_capability;
350 rsp->oob_flag = SMP_OOB_NOT_PRESENT;
351 rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE;
Johan Hedbergfd349c02014-02-18 10:19:36 +0200352 rsp->init_key_dist = req->init_key_dist & remote_dist;
353 rsp->resp_key_dist = req->resp_key_dist & local_dist;
Johan Hedberg065a13e2012-10-11 16:26:06 +0200354 rsp->auth_req = (authreq & AUTH_REQ_MASK);
Johan Hedbergfd349c02014-02-18 10:19:36 +0200355
356 smp->remote_key_dist = rsp->init_key_dist;
Vinicius Costa Gomesb8e66ea2011-06-09 18:50:52 -0300357}
358
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300359static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
360{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300361 struct smp_chan *smp = conn->smp_chan;
362
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300363 if ((max_key_size > SMP_MAX_ENC_KEY_SIZE) ||
Marcel Holtmannf1560462013-10-13 05:43:25 -0700364 (max_key_size < SMP_MIN_ENC_KEY_SIZE))
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300365 return SMP_ENC_KEY_SIZE;
366
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300367 smp->enc_key_size = max_key_size;
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300368
369 return 0;
370}
371
Johan Hedberg84794e12013-11-06 11:24:57 +0200372static void smp_failure(struct l2cap_conn *conn, u8 reason)
Brian Gix4f957a72011-11-23 08:28:36 -0800373{
Johan Hedbergbab73cb2012-02-09 16:07:29 +0200374 struct hci_conn *hcon = conn->hcon;
375
Johan Hedberg84794e12013-11-06 11:24:57 +0200376 if (reason)
Brian Gix4f957a72011-11-23 08:28:36 -0800377 smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
Marcel Holtmannf1560462013-10-13 05:43:25 -0700378 &reason);
Brian Gix4f957a72011-11-23 08:28:36 -0800379
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700380 clear_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags);
381 mgmt_auth_failed(hcon->hdev, &hcon->dst, hcon->type, hcon->dst_type,
382 HCI_ERROR_AUTH_FAILURE);
Vinicius Costa Gomesf1c09c02012-02-01 18:27:56 -0300383
Andre Guedes61a0cfb2012-08-01 20:34:15 -0300384 cancel_delayed_work_sync(&conn->security_timer);
385
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700386 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesf1c09c02012-02-01 18:27:56 -0300387 smp_chan_destroy(conn);
Brian Gix4f957a72011-11-23 08:28:36 -0800388}
389
Brian Gix2b64d152011-12-21 16:12:12 -0800390#define JUST_WORKS 0x00
391#define JUST_CFM 0x01
392#define REQ_PASSKEY 0x02
393#define CFM_PASSKEY 0x03
394#define REQ_OOB 0x04
395#define OVERLAP 0xFF
396
397static const u8 gen_method[5][5] = {
398 { JUST_WORKS, JUST_CFM, REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
399 { JUST_WORKS, JUST_CFM, REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
400 { CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
401 { JUST_WORKS, JUST_CFM, JUST_WORKS, JUST_WORKS, JUST_CFM },
402 { CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, OVERLAP },
403};
404
Johan Hedberg581370c2014-06-17 13:07:38 +0300405static u8 get_auth_method(struct smp_chan *smp, u8 local_io, u8 remote_io)
406{
Johan Hedberg2bcd4002014-07-09 19:18:09 +0300407 /* If either side has unknown io_caps, use JUST_CFM (which gets
408 * converted later to JUST_WORKS if we're initiators.
409 */
Johan Hedberg581370c2014-06-17 13:07:38 +0300410 if (local_io > SMP_IO_KEYBOARD_DISPLAY ||
411 remote_io > SMP_IO_KEYBOARD_DISPLAY)
Johan Hedberg2bcd4002014-07-09 19:18:09 +0300412 return JUST_CFM;
Johan Hedberg581370c2014-06-17 13:07:38 +0300413
414 return gen_method[remote_io][local_io];
415}
416
Brian Gix2b64d152011-12-21 16:12:12 -0800417static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
418 u8 local_io, u8 remote_io)
419{
420 struct hci_conn *hcon = conn->hcon;
421 struct smp_chan *smp = conn->smp_chan;
422 u8 method;
423 u32 passkey = 0;
424 int ret = 0;
425
426 /* Initialize key for JUST WORKS */
427 memset(smp->tk, 0, sizeof(smp->tk));
Johan Hedberg4a74d652014-05-20 09:45:50 +0300428 clear_bit(SMP_FLAG_TK_VALID, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800429
430 BT_DBG("tk_request: auth:%d lcl:%d rem:%d", auth, local_io, remote_io);
431
Johan Hedberg2bcd4002014-07-09 19:18:09 +0300432 /* If neither side wants MITM, either "just" confirm an incoming
433 * request or use just-works for outgoing ones. The JUST_CFM
434 * will be converted to JUST_WORKS if necessary later in this
435 * function. If either side has MITM look up the method from the
436 * table.
437 */
Johan Hedberg581370c2014-06-17 13:07:38 +0300438 if (!(auth & SMP_AUTH_MITM))
Johan Hedberg2bcd4002014-07-09 19:18:09 +0300439 method = JUST_CFM;
Brian Gix2b64d152011-12-21 16:12:12 -0800440 else
Johan Hedberg581370c2014-06-17 13:07:38 +0300441 method = get_auth_method(smp, local_io, remote_io);
Brian Gix2b64d152011-12-21 16:12:12 -0800442
Johan Hedberga82505c2014-03-24 14:39:07 +0200443 /* Don't confirm locally initiated pairing attempts */
Johan Hedberg4a74d652014-05-20 09:45:50 +0300444 if (method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR, &smp->flags))
Johan Hedberga82505c2014-03-24 14:39:07 +0200445 method = JUST_WORKS;
446
Johan Hedberg02f3e252014-07-16 15:09:13 +0300447 /* Don't bother user space with no IO capabilities */
448 if (method == JUST_CFM && hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
449 method = JUST_WORKS;
450
Brian Gix2b64d152011-12-21 16:12:12 -0800451 /* If Just Works, Continue with Zero TK */
452 if (method == JUST_WORKS) {
Johan Hedberg4a74d652014-05-20 09:45:50 +0300453 set_bit(SMP_FLAG_TK_VALID, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800454 return 0;
455 }
456
457 /* Not Just Works/Confirm results in MITM Authentication */
458 if (method != JUST_CFM)
Johan Hedberg4a74d652014-05-20 09:45:50 +0300459 set_bit(SMP_FLAG_MITM_AUTH, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800460
461 /* If both devices have Keyoard-Display I/O, the master
462 * Confirms and the slave Enters the passkey.
463 */
464 if (method == OVERLAP) {
Johan Hedberg40bef302014-07-16 11:42:27 +0300465 if (hcon->role == HCI_ROLE_MASTER)
Brian Gix2b64d152011-12-21 16:12:12 -0800466 method = CFM_PASSKEY;
467 else
468 method = REQ_PASSKEY;
469 }
470
Johan Hedberg01ad34d2014-03-19 14:14:53 +0200471 /* Generate random passkey. */
Brian Gix2b64d152011-12-21 16:12:12 -0800472 if (method == CFM_PASSKEY) {
Johan Hedberg943a7322014-03-18 12:58:24 +0200473 memset(smp->tk, 0, sizeof(smp->tk));
Brian Gix2b64d152011-12-21 16:12:12 -0800474 get_random_bytes(&passkey, sizeof(passkey));
475 passkey %= 1000000;
Johan Hedberg943a7322014-03-18 12:58:24 +0200476 put_unaligned_le32(passkey, smp->tk);
Brian Gix2b64d152011-12-21 16:12:12 -0800477 BT_DBG("PassKey: %d", passkey);
Johan Hedberg4a74d652014-05-20 09:45:50 +0300478 set_bit(SMP_FLAG_TK_VALID, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800479 }
480
481 hci_dev_lock(hcon->hdev);
482
483 if (method == REQ_PASSKEY)
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700484 ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200485 hcon->type, hcon->dst_type);
Johan Hedberg4eb65e62014-03-24 14:39:05 +0200486 else if (method == JUST_CFM)
487 ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
488 hcon->type, hcon->dst_type,
489 passkey, 1);
Brian Gix2b64d152011-12-21 16:12:12 -0800490 else
Johan Hedberg01ad34d2014-03-19 14:14:53 +0200491 ret = mgmt_user_passkey_notify(hcon->hdev, &hcon->dst,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200492 hcon->type, hcon->dst_type,
Johan Hedberg39adbff2014-03-20 08:18:14 +0200493 passkey, 0);
Brian Gix2b64d152011-12-21 16:12:12 -0800494
495 hci_dev_unlock(hcon->hdev);
496
497 return ret;
498}
499
Johan Hedberg1cc61142014-05-20 09:45:52 +0300500static u8 smp_confirm(struct smp_chan *smp)
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300501{
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300502 struct l2cap_conn *conn = smp->conn;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300503 struct smp_cmd_pairing_confirm cp;
504 int ret;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300505
506 BT_DBG("conn %p", conn);
507
Johan Hedbergec70f362014-06-27 14:23:04 +0300508 ret = smp_c1(smp, smp->tk, smp->prnd, smp->preq, smp->prsp,
Johan Hedbergb1cd5fd2014-02-28 12:54:17 +0200509 conn->hcon->init_addr_type, &conn->hcon->init_addr,
Johan Hedberg943a7322014-03-18 12:58:24 +0200510 conn->hcon->resp_addr_type, &conn->hcon->resp_addr,
511 cp.confirm_val);
Johan Hedberg1cc61142014-05-20 09:45:52 +0300512 if (ret)
513 return SMP_UNSPECIFIED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300514
Johan Hedberg4a74d652014-05-20 09:45:50 +0300515 clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800516
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300517 smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
518
Johan Hedberg1cc61142014-05-20 09:45:52 +0300519 return 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300520}
521
Johan Hedberg861580a2014-05-20 09:45:51 +0300522static u8 smp_random(struct smp_chan *smp)
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300523{
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300524 struct l2cap_conn *conn = smp->conn;
525 struct hci_conn *hcon = conn->hcon;
Johan Hedberg861580a2014-05-20 09:45:51 +0300526 u8 confirm[16];
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300527 int ret;
528
Johan Hedbergec70f362014-06-27 14:23:04 +0300529 if (IS_ERR_OR_NULL(smp->tfm_aes))
Johan Hedberg861580a2014-05-20 09:45:51 +0300530 return SMP_UNSPECIFIED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300531
532 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
533
Johan Hedbergec70f362014-06-27 14:23:04 +0300534 ret = smp_c1(smp, smp->tk, smp->rrnd, smp->preq, smp->prsp,
Johan Hedbergb1cd5fd2014-02-28 12:54:17 +0200535 hcon->init_addr_type, &hcon->init_addr,
Johan Hedberg943a7322014-03-18 12:58:24 +0200536 hcon->resp_addr_type, &hcon->resp_addr, confirm);
Johan Hedberg861580a2014-05-20 09:45:51 +0300537 if (ret)
538 return SMP_UNSPECIFIED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300539
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300540 if (memcmp(smp->pcnf, confirm, sizeof(smp->pcnf)) != 0) {
541 BT_ERR("Pairing failed (confirmation values mismatch)");
Johan Hedberg861580a2014-05-20 09:45:51 +0300542 return SMP_CONFIRM_FAILED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300543 }
544
545 if (hcon->out) {
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -0800546 u8 stk[16];
547 __le64 rand = 0;
548 __le16 ediv = 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300549
Johan Hedbergec70f362014-06-27 14:23:04 +0300550 smp_s1(smp, smp->tk, smp->rrnd, smp->prnd, stk);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300551
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300552 memset(stk + smp->enc_key_size, 0,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300553 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300554
Johan Hedberg861580a2014-05-20 09:45:51 +0300555 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
556 return SMP_UNSPECIFIED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300557
558 hci_le_start_enc(hcon, ediv, rand, stk);
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300559 hcon->enc_key_size = smp->enc_key_size;
Johan Hedbergfe59a052014-07-01 19:14:12 +0300560 set_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300561 } else {
Johan Hedbergfff34902014-06-10 15:19:50 +0300562 u8 stk[16], auth;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -0800563 __le64 rand = 0;
564 __le16 ediv = 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300565
Johan Hedberg943a7322014-03-18 12:58:24 +0200566 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
567 smp->prnd);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300568
Johan Hedbergec70f362014-06-27 14:23:04 +0300569 smp_s1(smp, smp->tk, smp->prnd, smp->rrnd, stk);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300570
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300571 memset(stk + smp->enc_key_size, 0,
Marcel Holtmannf1560462013-10-13 05:43:25 -0700572 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300573
Johan Hedbergfff34902014-06-10 15:19:50 +0300574 if (hcon->pending_sec_level == BT_SECURITY_HIGH)
575 auth = 1;
576 else
577 auth = 0;
578
Johan Hedberg7d5843b2014-06-16 19:25:15 +0300579 /* Even though there's no _SLAVE suffix this is the
580 * slave STK we're adding for later lookup (the master
581 * STK never needs to be stored).
582 */
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700583 hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
Johan Hedberg2ceba532014-06-16 19:25:16 +0300584 SMP_STK, auth, stk, smp->enc_key_size, ediv, rand);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300585 }
586
Johan Hedberg861580a2014-05-20 09:45:51 +0300587 return 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300588}
589
590static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
591{
592 struct smp_chan *smp;
593
Marcel Holtmannf1560462013-10-13 05:43:25 -0700594 smp = kzalloc(sizeof(*smp), GFP_ATOMIC);
Johan Hedberg616d55be42014-07-29 14:18:48 +0300595 if (!smp) {
596 clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300597 return NULL;
Johan Hedberg616d55be42014-07-29 14:18:48 +0300598 }
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300599
Johan Hedberg6a7bd102014-06-27 14:23:03 +0300600 smp->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
601 if (IS_ERR(smp->tfm_aes)) {
602 BT_ERR("Unable to create ECB crypto context");
603 kfree(smp);
Johan Hedberg616d55be42014-07-29 14:18:48 +0300604 clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags);
Johan Hedberg6a7bd102014-06-27 14:23:03 +0300605 return NULL;
606 }
607
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300608 smp->conn = conn;
609 conn->smp_chan = smp;
610
611 hci_conn_hold(conn->hcon);
612
613 return smp;
614}
615
616void smp_chan_destroy(struct l2cap_conn *conn)
617{
Brian Gixc8eb9692011-11-23 08:28:35 -0800618 struct smp_chan *smp = conn->smp_chan;
Johan Hedbergf4a407b2014-02-18 21:41:34 +0200619 bool complete;
Brian Gixc8eb9692011-11-23 08:28:35 -0800620
Vinicius Costa Gomesf1c09c02012-02-01 18:27:56 -0300621 BUG_ON(!smp);
Brian Gixc8eb9692011-11-23 08:28:35 -0800622
Johan Hedberg4a74d652014-05-20 09:45:50 +0300623 complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags);
Johan Hedbergf4a407b2014-02-18 21:41:34 +0200624 mgmt_smp_complete(conn->hcon, complete);
625
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -0700626 kfree(smp->csrk);
627 kfree(smp->slave_csrk);
628
Johan Hedberg6a7bd102014-06-27 14:23:03 +0300629 crypto_free_blkcipher(smp->tfm_aes);
630
Johan Hedberg759331d2014-02-28 10:10:16 +0200631 /* If pairing failed clean up any keys we might have */
632 if (!complete) {
633 if (smp->ltk) {
634 list_del(&smp->ltk->list);
635 kfree(smp->ltk);
636 }
637
638 if (smp->slave_ltk) {
639 list_del(&smp->slave_ltk->list);
640 kfree(smp->slave_ltk);
641 }
642
643 if (smp->remote_irk) {
644 list_del(&smp->remote_irk->list);
645 kfree(smp->remote_irk);
646 }
647 }
648
Brian Gixc8eb9692011-11-23 08:28:35 -0800649 kfree(smp);
650 conn->smp_chan = NULL;
David Herrmann76a68ba2013-04-06 20:28:37 +0200651 hci_conn_drop(conn->hcon);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300652}
653
Brian Gix2b64d152011-12-21 16:12:12 -0800654int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
655{
Johan Hedbergb10e8012014-06-27 14:23:07 +0300656 struct l2cap_conn *conn = hcon->l2cap_data;
Brian Gix2b64d152011-12-21 16:12:12 -0800657 struct smp_chan *smp;
658 u32 value;
Brian Gix2b64d152011-12-21 16:12:12 -0800659
660 BT_DBG("");
661
Johan Hedberg642ac772014-06-27 14:23:06 +0300662 if (!conn || !test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Brian Gix2b64d152011-12-21 16:12:12 -0800663 return -ENOTCONN;
664
665 smp = conn->smp_chan;
666
667 switch (mgmt_op) {
668 case MGMT_OP_USER_PASSKEY_REPLY:
669 value = le32_to_cpu(passkey);
Johan Hedberg943a7322014-03-18 12:58:24 +0200670 memset(smp->tk, 0, sizeof(smp->tk));
Brian Gix2b64d152011-12-21 16:12:12 -0800671 BT_DBG("PassKey: %d", value);
Johan Hedberg943a7322014-03-18 12:58:24 +0200672 put_unaligned_le32(value, smp->tk);
Brian Gix2b64d152011-12-21 16:12:12 -0800673 /* Fall Through */
674 case MGMT_OP_USER_CONFIRM_REPLY:
Johan Hedberg4a74d652014-05-20 09:45:50 +0300675 set_bit(SMP_FLAG_TK_VALID, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800676 break;
677 case MGMT_OP_USER_PASSKEY_NEG_REPLY:
678 case MGMT_OP_USER_CONFIRM_NEG_REPLY:
Johan Hedberg84794e12013-11-06 11:24:57 +0200679 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
Brian Gix2b64d152011-12-21 16:12:12 -0800680 return 0;
681 default:
Johan Hedberg84794e12013-11-06 11:24:57 +0200682 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
Brian Gix2b64d152011-12-21 16:12:12 -0800683 return -EOPNOTSUPP;
684 }
685
686 /* If it is our turn to send Pairing Confirm, do so now */
Johan Hedberg1cc61142014-05-20 09:45:52 +0300687 if (test_bit(SMP_FLAG_CFM_PENDING, &smp->flags)) {
688 u8 rsp = smp_confirm(smp);
689 if (rsp)
690 smp_failure(conn, rsp);
691 }
Brian Gix2b64d152011-12-21 16:12:12 -0800692
693 return 0;
694}
695
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300696static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300697{
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300698 struct smp_cmd_pairing rsp, *req = (void *) skb->data;
Johan Hedbergb3c64102014-07-10 11:02:07 +0300699 struct hci_dev *hdev = conn->hcon->hdev;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300700 struct smp_chan *smp;
Johan Hedbergc7262e72014-06-17 13:07:37 +0300701 u8 key_size, auth, sec_level;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300702 int ret;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300703
704 BT_DBG("conn %p", conn);
705
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200706 if (skb->len < sizeof(*req))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300707 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200708
Johan Hedberg40bef302014-07-16 11:42:27 +0300709 if (conn->hcon->role != HCI_ROLE_SLAVE)
Brian Gix2b64d152011-12-21 16:12:12 -0800710 return SMP_CMD_NOTSUPP;
711
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200712 if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags))
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300713 smp = smp_chan_create(conn);
Andrei Emeltchenkod08fd0e2012-07-19 17:03:43 +0300714 else
715 smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300716
Andrei Emeltchenkod08fd0e2012-07-19 17:03:43 +0300717 if (!smp)
718 return SMP_UNSPECIFIED;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300719
Johan Hedbergb6ae8452014-07-30 09:22:22 +0300720 if (!test_bit(HCI_BONDABLE, &hdev->dev_flags) &&
Johan Hedbergb3c64102014-07-10 11:02:07 +0300721 (req->auth_req & SMP_AUTH_BONDING))
722 return SMP_PAIRING_NOTSUPP;
723
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300724 smp->preq[0] = SMP_CMD_PAIRING_REQ;
725 memcpy(&smp->preq[1], req, sizeof(*req));
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300726 skb_pull(skb, sizeof(*req));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300727
Brian Gix2b64d152011-12-21 16:12:12 -0800728 /* We didn't start the pairing, so match remote */
Johan Hedberg1ef35822014-05-20 09:45:48 +0300729 auth = req->auth_req;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300730
Johan Hedbergc7262e72014-06-17 13:07:37 +0300731 sec_level = authreq_to_seclevel(auth);
732 if (sec_level > conn->hcon->pending_sec_level)
733 conn->hcon->pending_sec_level = sec_level;
Ido Yarivfdde0a22012-03-05 20:09:38 +0200734
Johan Hedberg2ed8f652014-06-17 13:07:39 +0300735 /* If we need MITM check that it can be acheived */
736 if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
737 u8 method;
738
739 method = get_auth_method(smp, conn->hcon->io_capability,
740 req->io_capability);
741 if (method == JUST_WORKS || method == JUST_CFM)
742 return SMP_AUTH_REQUIREMENTS;
743 }
744
Brian Gix2b64d152011-12-21 16:12:12 -0800745 build_pairing_cmd(conn, req, &rsp, auth);
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300746
747 key_size = min(req->max_key_size, rsp.max_key_size);
748 if (check_enc_key_size(conn, key_size))
749 return SMP_ENC_KEY_SIZE;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300750
Johan Hedberge84a6b12013-12-02 10:49:03 +0200751 get_random_bytes(smp->prnd, sizeof(smp->prnd));
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300752
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300753 smp->prsp[0] = SMP_CMD_PAIRING_RSP;
754 memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300755
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300756 smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300757
Brian Gix2b64d152011-12-21 16:12:12 -0800758 /* Request setup of TK */
759 ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability);
760 if (ret)
761 return SMP_UNSPECIFIED;
762
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300763 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300764}
765
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300766static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300767{
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300768 struct smp_cmd_pairing *req, *rsp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300769 struct smp_chan *smp = conn->smp_chan;
Brian Gix2b64d152011-12-21 16:12:12 -0800770 u8 key_size, auth = SMP_AUTH_NONE;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300771 int ret;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300772
773 BT_DBG("conn %p", conn);
774
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200775 if (skb->len < sizeof(*rsp))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300776 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200777
Johan Hedberg40bef302014-07-16 11:42:27 +0300778 if (conn->hcon->role != HCI_ROLE_MASTER)
Brian Gix2b64d152011-12-21 16:12:12 -0800779 return SMP_CMD_NOTSUPP;
780
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300781 skb_pull(skb, sizeof(*rsp));
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300782
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300783 req = (void *) &smp->preq[1];
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300784
785 key_size = min(req->max_key_size, rsp->max_key_size);
786 if (check_enc_key_size(conn, key_size))
787 return SMP_ENC_KEY_SIZE;
788
Johan Hedberg2ed8f652014-06-17 13:07:39 +0300789 /* If we need MITM check that it can be acheived */
790 if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
791 u8 method;
792
793 method = get_auth_method(smp, req->io_capability,
794 rsp->io_capability);
795 if (method == JUST_WORKS || method == JUST_CFM)
796 return SMP_AUTH_REQUIREMENTS;
797 }
798
Johan Hedberge84a6b12013-12-02 10:49:03 +0200799 get_random_bytes(smp->prnd, sizeof(smp->prnd));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300800
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300801 smp->prsp[0] = SMP_CMD_PAIRING_RSP;
802 memcpy(&smp->prsp[1], rsp, sizeof(*rsp));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300803
Johan Hedbergfdcc4be2014-03-14 10:53:50 +0200804 /* Update remote key distribution in case the remote cleared
805 * some bits that we had enabled in our request.
806 */
807 smp->remote_key_dist &= rsp->resp_key_dist;
808
Brian Gix2b64d152011-12-21 16:12:12 -0800809 if ((req->auth_req & SMP_AUTH_BONDING) &&
Marcel Holtmannf1560462013-10-13 05:43:25 -0700810 (rsp->auth_req & SMP_AUTH_BONDING))
Brian Gix2b64d152011-12-21 16:12:12 -0800811 auth = SMP_AUTH_BONDING;
812
813 auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM;
814
Johan Hedberg476585e2012-06-06 18:54:15 +0800815 ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability);
Brian Gix2b64d152011-12-21 16:12:12 -0800816 if (ret)
817 return SMP_UNSPECIFIED;
818
Johan Hedberg4a74d652014-05-20 09:45:50 +0300819 set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800820
821 /* Can't compose response until we have been confirmed */
Johan Hedberg4a74d652014-05-20 09:45:50 +0300822 if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
Johan Hedberg1cc61142014-05-20 09:45:52 +0300823 return smp_confirm(smp);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300824
825 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300826}
827
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300828static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300829{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300830 struct smp_chan *smp = conn->smp_chan;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300831
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300832 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
833
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200834 if (skb->len < sizeof(smp->pcnf))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300835 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200836
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300837 memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf));
838 skb_pull(skb, sizeof(smp->pcnf));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300839
Johan Hedberg943a7322014-03-18 12:58:24 +0200840 if (conn->hcon->out)
841 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
842 smp->prnd);
Johan Hedberg4a74d652014-05-20 09:45:50 +0300843 else if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
Johan Hedberg1cc61142014-05-20 09:45:52 +0300844 return smp_confirm(smp);
Johan Hedberg943a7322014-03-18 12:58:24 +0200845 else
Johan Hedberg4a74d652014-05-20 09:45:50 +0300846 set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300847
848 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300849}
850
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300851static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300852{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300853 struct smp_chan *smp = conn->smp_chan;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300854
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300855 BT_DBG("conn %p", conn);
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300856
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200857 if (skb->len < sizeof(smp->rrnd))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300858 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200859
Johan Hedberg943a7322014-03-18 12:58:24 +0200860 memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd));
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300861 skb_pull(skb, sizeof(smp->rrnd));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300862
Johan Hedberg861580a2014-05-20 09:45:51 +0300863 return smp_random(smp);
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300864}
865
Marcel Holtmannf81cd822014-07-01 10:59:24 +0200866static bool smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300867{
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300868 struct smp_ltk *key;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300869 struct hci_conn *hcon = conn->hcon;
870
Johan Hedberg98a0b842014-01-30 19:40:00 -0800871 key = hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type,
Johan Hedberge804d252014-07-16 11:42:28 +0300872 hcon->role);
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300873 if (!key)
Marcel Holtmannf81cd822014-07-01 10:59:24 +0200874 return false;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300875
Johan Hedberg4dab7862012-06-07 14:58:37 +0800876 if (sec_level > BT_SECURITY_MEDIUM && !key->authenticated)
Marcel Holtmannf81cd822014-07-01 10:59:24 +0200877 return false;
Johan Hedberg4dab7862012-06-07 14:58:37 +0800878
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200879 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
Marcel Holtmannf81cd822014-07-01 10:59:24 +0200880 return true;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300881
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300882 hci_le_start_enc(hcon, key->ediv, key->rand, key->val);
883 hcon->enc_key_size = key->enc_size;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300884
Johan Hedbergfe59a052014-07-01 19:14:12 +0300885 /* We never store STKs for master role, so clear this flag */
886 clear_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags);
887
Marcel Holtmannf81cd822014-07-01 10:59:24 +0200888 return true;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300889}
Marcel Holtmannf1560462013-10-13 05:43:25 -0700890
Johan Hedberg854f4722014-07-01 18:40:20 +0300891bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level)
892{
893 if (sec_level == BT_SECURITY_LOW)
894 return true;
895
Johan Hedberg9ab65d602014-07-01 19:14:13 +0300896 /* If we're encrypted with an STK always claim insufficient
897 * security. This way we allow the connection to be re-encrypted
898 * with an LTK, even if the LTK provides the same level of
Johan Hedbergb2d5e252014-07-14 14:34:55 +0300899 * security. Only exception is if we don't have an LTK (e.g.
900 * because of key distribution bits).
Johan Hedberg9ab65d602014-07-01 19:14:13 +0300901 */
Johan Hedbergb2d5e252014-07-14 14:34:55 +0300902 if (test_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags) &&
903 hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type,
Johan Hedberge804d252014-07-16 11:42:28 +0300904 hcon->role))
Johan Hedberg9ab65d602014-07-01 19:14:13 +0300905 return false;
906
Johan Hedberg854f4722014-07-01 18:40:20 +0300907 if (hcon->sec_level >= sec_level)
908 return true;
909
910 return false;
911}
912
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300913static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300914{
915 struct smp_cmd_security_req *rp = (void *) skb->data;
916 struct smp_cmd_pairing cp;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300917 struct hci_conn *hcon = conn->hcon;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300918 struct smp_chan *smp;
Johan Hedbergc7262e72014-06-17 13:07:37 +0300919 u8 sec_level;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300920
921 BT_DBG("conn %p", conn);
922
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200923 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300924 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200925
Johan Hedberg40bef302014-07-16 11:42:27 +0300926 if (hcon->role != HCI_ROLE_MASTER)
Johan Hedberg86ca9ea2013-11-05 11:30:39 +0200927 return SMP_CMD_NOTSUPP;
928
Johan Hedbergc7262e72014-06-17 13:07:37 +0300929 sec_level = authreq_to_seclevel(rp->auth_req);
Johan Hedberg854f4722014-07-01 18:40:20 +0300930 if (smp_sufficient_security(hcon, sec_level))
931 return 0;
932
Johan Hedbergc7262e72014-06-17 13:07:37 +0300933 if (sec_level > hcon->pending_sec_level)
934 hcon->pending_sec_level = sec_level;
Vinicius Costa Gomesfeb45eb2011-08-25 20:02:35 -0300935
Johan Hedberg4dab7862012-06-07 14:58:37 +0800936 if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300937 return 0;
938
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200939 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300940 return 0;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300941
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300942 smp = smp_chan_create(conn);
Johan Hedbergc29d2442014-06-16 19:25:14 +0300943 if (!smp)
944 return SMP_UNSPECIFIED;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300945
Johan Hedbergb6ae8452014-07-30 09:22:22 +0300946 if (!test_bit(HCI_BONDABLE, &hcon->hdev->dev_flags) &&
Johan Hedberg616d55be42014-07-29 14:18:48 +0300947 (rp->auth_req & SMP_AUTH_BONDING))
948 return SMP_PAIRING_NOTSUPP;
949
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300950 skb_pull(skb, sizeof(*rp));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300951
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300952 memset(&cp, 0, sizeof(cp));
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300953 build_pairing_cmd(conn, &cp, NULL, rp->auth_req);
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300954
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300955 smp->preq[0] = SMP_CMD_PAIRING_REQ;
956 memcpy(&smp->preq[1], &cp, sizeof(cp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300957
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300958 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300959
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300960 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300961}
962
Vinicius Costa Gomescc110922012-08-23 21:32:43 -0300963int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300964{
Vinicius Costa Gomescc110922012-08-23 21:32:43 -0300965 struct l2cap_conn *conn = hcon->l2cap_data;
Johan Hedberg0a66cf22014-03-24 14:39:03 +0200966 struct smp_chan *smp;
Brian Gix2b64d152011-12-21 16:12:12 -0800967 __u8 authreq;
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300968
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -0300969 BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
970
Johan Hedberg0a66cf22014-03-24 14:39:03 +0200971 /* This may be NULL if there's an unexpected disconnection */
972 if (!conn)
973 return 1;
974
Johan Hedberg757aee02013-04-24 13:05:32 +0300975 if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags))
Andre Guedes2e65c9d2011-06-30 19:20:56 -0300976 return 1;
977
Johan Hedbergad32a2f2013-05-14 18:05:12 +0300978 if (smp_sufficient_security(hcon, sec_level))
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300979 return 1;
980
Johan Hedbergc7262e72014-06-17 13:07:37 +0300981 if (sec_level > hcon->pending_sec_level)
982 hcon->pending_sec_level = sec_level;
983
Johan Hedberg40bef302014-07-16 11:42:27 +0300984 if (hcon->role == HCI_ROLE_MASTER)
Johan Hedbergc7262e72014-06-17 13:07:37 +0300985 if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
986 return 0;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300987
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200988 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300989 return 0;
990
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300991 smp = smp_chan_create(conn);
Brian Gix2b64d152011-12-21 16:12:12 -0800992 if (!smp)
993 return 1;
994
995 authreq = seclevel_to_authreq(sec_level);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300996
Johan Hedberg79897d22014-06-01 09:45:24 +0300997 /* Require MITM if IO Capability allows or the security level
998 * requires it.
Johan Hedberg2e233642014-03-18 15:42:30 +0200999 */
Johan Hedberg79897d22014-06-01 09:45:24 +03001000 if (hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT ||
Johan Hedbergc7262e72014-06-17 13:07:37 +03001001 hcon->pending_sec_level > BT_SECURITY_MEDIUM)
Johan Hedberg2e233642014-03-18 15:42:30 +02001002 authreq |= SMP_AUTH_MITM;
1003
Johan Hedberg40bef302014-07-16 11:42:27 +03001004 if (hcon->role == HCI_ROLE_MASTER) {
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001005 struct smp_cmd_pairing cp;
Anderson Brigliaf01ead32011-06-09 18:50:45 -03001006
Brian Gix2b64d152011-12-21 16:12:12 -08001007 build_pairing_cmd(conn, &cp, NULL, authreq);
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001008 smp->preq[0] = SMP_CMD_PAIRING_REQ;
1009 memcpy(&smp->preq[1], &cp, sizeof(cp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -03001010
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001011 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
1012 } else {
1013 struct smp_cmd_security_req cp;
Brian Gix2b64d152011-12-21 16:12:12 -08001014 cp.auth_req = authreq;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001015 smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
1016 }
1017
Johan Hedberg4a74d652014-05-20 09:45:50 +03001018 set_bit(SMP_FLAG_INITIATOR, &smp->flags);
Johan Hedbergedca7922014-03-24 15:54:11 +02001019
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001020 return 0;
1021}
1022
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001023static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
1024{
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001025 struct smp_cmd_encrypt_info *rp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001026 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001027
Johan Hedbergc46b98b2014-02-18 10:19:29 +02001028 BT_DBG("conn %p", conn);
1029
1030 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001031 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +02001032
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001033 /* Ignore this PDU if it wasn't requested */
1034 if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
1035 return 0;
1036
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001037 skb_pull(skb, sizeof(*rp));
1038
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001039 memcpy(smp->tk, rp->ltk, sizeof(smp->tk));
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001040
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001041 return 0;
1042}
1043
1044static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
1045{
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001046 struct smp_cmd_master_ident *rp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001047 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001048 struct hci_dev *hdev = conn->hcon->hdev;
1049 struct hci_conn *hcon = conn->hcon;
Johan Hedberg23d0e122014-02-19 14:57:46 +02001050 struct smp_ltk *ltk;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001051 u8 authenticated;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001052
Johan Hedbergc46b98b2014-02-18 10:19:29 +02001053 BT_DBG("conn %p", conn);
1054
1055 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001056 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +02001057
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001058 /* Ignore this PDU if it wasn't requested */
1059 if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
1060 return 0;
1061
Johan Hedberg9747a9f2014-02-26 23:33:43 +02001062 /* Mark the information as received */
1063 smp->remote_key_dist &= ~SMP_DIST_ENC_KEY;
1064
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001065 skb_pull(skb, sizeof(*rp));
1066
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001067 hci_dev_lock(hdev);
Marcel Holtmannce39fb42013-10-13 02:23:39 -07001068 authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
Johan Hedberg2ceba532014-06-16 19:25:16 +03001069 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, SMP_LTK,
Johan Hedberg23d0e122014-02-19 14:57:46 +02001070 authenticated, smp->tk, smp->enc_key_size,
1071 rp->ediv, rp->rand);
1072 smp->ltk = ltk;
Johan Hedbergfd349c02014-02-18 10:19:36 +02001073 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001074 smp_distribute_keys(conn);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001075 hci_dev_unlock(hdev);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001076
1077 return 0;
1078}
1079
Johan Hedbergfd349c02014-02-18 10:19:36 +02001080static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
1081{
1082 struct smp_cmd_ident_info *info = (void *) skb->data;
1083 struct smp_chan *smp = conn->smp_chan;
1084
1085 BT_DBG("");
1086
1087 if (skb->len < sizeof(*info))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001088 return SMP_INVALID_PARAMS;
Johan Hedbergfd349c02014-02-18 10:19:36 +02001089
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001090 /* Ignore this PDU if it wasn't requested */
1091 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
1092 return 0;
1093
Johan Hedbergfd349c02014-02-18 10:19:36 +02001094 skb_pull(skb, sizeof(*info));
1095
1096 memcpy(smp->irk, info->irk, 16);
1097
1098 return 0;
1099}
1100
1101static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
1102 struct sk_buff *skb)
1103{
1104 struct smp_cmd_ident_addr_info *info = (void *) skb->data;
1105 struct smp_chan *smp = conn->smp_chan;
1106 struct hci_conn *hcon = conn->hcon;
1107 bdaddr_t rpa;
1108
1109 BT_DBG("");
1110
1111 if (skb->len < sizeof(*info))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001112 return SMP_INVALID_PARAMS;
Johan Hedbergfd349c02014-02-18 10:19:36 +02001113
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001114 /* Ignore this PDU if it wasn't requested */
1115 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
1116 return 0;
1117
Johan Hedberg9747a9f2014-02-26 23:33:43 +02001118 /* Mark the information as received */
1119 smp->remote_key_dist &= ~SMP_DIST_ID_KEY;
1120
Johan Hedbergfd349c02014-02-18 10:19:36 +02001121 skb_pull(skb, sizeof(*info));
1122
Johan Hedberg31dd6242014-06-27 14:23:02 +03001123 hci_dev_lock(hcon->hdev);
1124
Johan Hedberga9a58f82014-02-25 22:24:37 +02001125 /* Strictly speaking the Core Specification (4.1) allows sending
1126 * an empty address which would force us to rely on just the IRK
1127 * as "identity information". However, since such
1128 * implementations are not known of and in order to not over
1129 * complicate our implementation, simply pretend that we never
1130 * received an IRK for such a device.
1131 */
1132 if (!bacmp(&info->bdaddr, BDADDR_ANY)) {
1133 BT_ERR("Ignoring IRK with no identity address");
Johan Hedberg31dd6242014-06-27 14:23:02 +03001134 goto distribute;
Johan Hedberga9a58f82014-02-25 22:24:37 +02001135 }
1136
Johan Hedbergfd349c02014-02-18 10:19:36 +02001137 bacpy(&smp->id_addr, &info->bdaddr);
1138 smp->id_addr_type = info->addr_type;
1139
1140 if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type))
1141 bacpy(&rpa, &hcon->dst);
1142 else
1143 bacpy(&rpa, BDADDR_ANY);
1144
Johan Hedberg23d0e122014-02-19 14:57:46 +02001145 smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
1146 smp->id_addr_type, smp->irk, &rpa);
Johan Hedbergfd349c02014-02-18 10:19:36 +02001147
Johan Hedberg31dd6242014-06-27 14:23:02 +03001148distribute:
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001149 smp_distribute_keys(conn);
Johan Hedbergfd349c02014-02-18 10:19:36 +02001150
Johan Hedberg31dd6242014-06-27 14:23:02 +03001151 hci_dev_unlock(hcon->hdev);
1152
Johan Hedbergfd349c02014-02-18 10:19:36 +02001153 return 0;
1154}
1155
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001156static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)
1157{
1158 struct smp_cmd_sign_info *rp = (void *) skb->data;
1159 struct smp_chan *smp = conn->smp_chan;
1160 struct hci_dev *hdev = conn->hcon->hdev;
1161 struct smp_csrk *csrk;
1162
1163 BT_DBG("conn %p", conn);
1164
1165 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001166 return SMP_INVALID_PARAMS;
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001167
1168 /* Ignore this PDU if it wasn't requested */
1169 if (!(smp->remote_key_dist & SMP_DIST_SIGN))
1170 return 0;
1171
1172 /* Mark the information as received */
1173 smp->remote_key_dist &= ~SMP_DIST_SIGN;
1174
1175 skb_pull(skb, sizeof(*rp));
1176
1177 hci_dev_lock(hdev);
1178 csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
1179 if (csrk) {
1180 csrk->master = 0x01;
1181 memcpy(csrk->val, rp->csrk, sizeof(csrk->val));
1182 }
1183 smp->csrk = csrk;
Johan Hedberg5fcb9342014-08-07 10:03:31 +03001184 smp_distribute_keys(conn);
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001185 hci_dev_unlock(hdev);
1186
1187 return 0;
1188}
1189
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001190int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
1191{
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001192 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann92381f52013-10-03 01:23:08 -07001193 __u8 code, reason;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001194 int err = 0;
1195
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001196 if (hcon->type != LE_LINK) {
1197 kfree_skb(skb);
Johan Hedberg34327112013-10-16 11:37:01 +03001198 return 0;
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001199 }
1200
Marcel Holtmann92381f52013-10-03 01:23:08 -07001201 if (skb->len < 1) {
1202 kfree_skb(skb);
1203 return -EILSEQ;
1204 }
1205
Marcel Holtmann06ae3312013-10-18 03:43:00 -07001206 if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) {
Johan Hedbergbeb19e42014-07-18 11:15:26 +03001207 err = -EOPNOTSUPP;
Andre Guedes2e65c9d2011-06-30 19:20:56 -03001208 reason = SMP_PAIRING_NOTSUPP;
1209 goto done;
1210 }
1211
Marcel Holtmann92381f52013-10-03 01:23:08 -07001212 code = skb->data[0];
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001213 skb_pull(skb, sizeof(code));
1214
Johan Hedberg8cf9fa12013-01-29 10:44:23 -06001215 /*
1216 * The SMP context must be initialized for all other PDUs except
1217 * pairing and security requests. If we get any other PDU when
1218 * not initialized simply disconnect (done if this function
1219 * returns an error).
1220 */
1221 if (code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ &&
Johan Hedbergd3368602014-08-08 09:28:05 +03001222 !test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Johan Hedberg8cf9fa12013-01-29 10:44:23 -06001223 BT_ERR("Unexpected SMP command 0x%02x. Disconnecting.", code);
1224 kfree_skb(skb);
Johan Hedbergbeb19e42014-07-18 11:15:26 +03001225 return -EOPNOTSUPP;
Johan Hedberg8cf9fa12013-01-29 10:44:23 -06001226 }
1227
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001228 switch (code) {
1229 case SMP_CMD_PAIRING_REQ:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001230 reason = smp_cmd_pairing_req(conn, skb);
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001231 break;
1232
1233 case SMP_CMD_PAIRING_FAIL:
Johan Hedberg84794e12013-11-06 11:24:57 +02001234 smp_failure(conn, 0);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001235 reason = 0;
1236 err = -EPERM;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001237 break;
1238
1239 case SMP_CMD_PAIRING_RSP:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001240 reason = smp_cmd_pairing_rsp(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001241 break;
1242
1243 case SMP_CMD_SECURITY_REQ:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001244 reason = smp_cmd_security_req(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001245 break;
1246
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001247 case SMP_CMD_PAIRING_CONFIRM:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001248 reason = smp_cmd_pairing_confirm(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001249 break;
1250
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001251 case SMP_CMD_PAIRING_RANDOM:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001252 reason = smp_cmd_pairing_random(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001253 break;
1254
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001255 case SMP_CMD_ENCRYPT_INFO:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001256 reason = smp_cmd_encrypt_info(conn, skb);
1257 break;
1258
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001259 case SMP_CMD_MASTER_IDENT:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001260 reason = smp_cmd_master_ident(conn, skb);
1261 break;
1262
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001263 case SMP_CMD_IDENT_INFO:
Johan Hedbergfd349c02014-02-18 10:19:36 +02001264 reason = smp_cmd_ident_info(conn, skb);
1265 break;
1266
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001267 case SMP_CMD_IDENT_ADDR_INFO:
Johan Hedbergfd349c02014-02-18 10:19:36 +02001268 reason = smp_cmd_ident_addr_info(conn, skb);
1269 break;
1270
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001271 case SMP_CMD_SIGN_INFO:
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001272 reason = smp_cmd_sign_info(conn, skb);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001273 break;
1274
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001275 default:
1276 BT_DBG("Unknown command code 0x%2.2x", code);
1277
1278 reason = SMP_CMD_NOTSUPP;
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -03001279 err = -EOPNOTSUPP;
1280 goto done;
1281 }
1282
1283done:
1284 if (reason)
Johan Hedberg84794e12013-11-06 11:24:57 +02001285 smp_failure(conn, reason);
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001286
1287 kfree_skb(skb);
1288 return err;
1289}
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001290
Johan Hedberg35d70272014-02-19 14:57:47 +02001291static void smp_notify_keys(struct l2cap_conn *conn)
1292{
1293 struct smp_chan *smp = conn->smp_chan;
1294 struct hci_conn *hcon = conn->hcon;
1295 struct hci_dev *hdev = hcon->hdev;
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001296 struct smp_cmd_pairing *req = (void *) &smp->preq[1];
1297 struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1];
1298 bool persistent;
Johan Hedberg35d70272014-02-19 14:57:47 +02001299
Johan Hedberg61b1a7f2014-03-20 12:54:16 +02001300 if (smp->remote_irk) {
Johan Hedberg95fbac82014-02-19 15:18:31 +02001301 mgmt_new_irk(hdev, smp->remote_irk);
Johan Hedberg61b1a7f2014-03-20 12:54:16 +02001302 /* Now that user space can be considered to know the
1303 * identity address track the connection based on it
1304 * from now on.
1305 */
1306 bacpy(&hcon->dst, &smp->remote_irk->bdaddr);
1307 hcon->dst_type = smp->remote_irk->addr_type;
1308 l2cap_conn_update_id_addr(hcon);
Marcel Holtmann66d8e832014-07-24 15:20:58 +02001309
1310 /* When receiving an indentity resolving key for
1311 * a remote device that does not use a resolvable
1312 * private address, just remove the key so that
1313 * it is possible to use the controller white
1314 * list for scanning.
1315 *
1316 * Userspace will have been told to not store
1317 * this key at this point. So it is safe to
1318 * just remove it.
1319 */
1320 if (!bacmp(&smp->remote_irk->rpa, BDADDR_ANY)) {
1321 list_del(&smp->remote_irk->list);
1322 kfree(smp->remote_irk);
1323 smp->remote_irk = NULL;
1324 }
Johan Hedberg61b1a7f2014-03-20 12:54:16 +02001325 }
Johan Hedberg95fbac82014-02-19 15:18:31 +02001326
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001327 /* The LTKs and CSRKs should be persistent only if both sides
1328 * had the bonding bit set in their authentication requests.
1329 */
1330 persistent = !!((req->auth_req & rsp->auth_req) & SMP_AUTH_BONDING);
1331
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001332 if (smp->csrk) {
1333 smp->csrk->bdaddr_type = hcon->dst_type;
1334 bacpy(&smp->csrk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001335 mgmt_new_csrk(hdev, smp->csrk, persistent);
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001336 }
1337
1338 if (smp->slave_csrk) {
1339 smp->slave_csrk->bdaddr_type = hcon->dst_type;
1340 bacpy(&smp->slave_csrk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001341 mgmt_new_csrk(hdev, smp->slave_csrk, persistent);
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001342 }
1343
Johan Hedberg35d70272014-02-19 14:57:47 +02001344 if (smp->ltk) {
1345 smp->ltk->bdaddr_type = hcon->dst_type;
1346 bacpy(&smp->ltk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001347 mgmt_new_ltk(hdev, smp->ltk, persistent);
Johan Hedberg35d70272014-02-19 14:57:47 +02001348 }
1349
1350 if (smp->slave_ltk) {
1351 smp->slave_ltk->bdaddr_type = hcon->dst_type;
1352 bacpy(&smp->slave_ltk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001353 mgmt_new_ltk(hdev, smp->slave_ltk, persistent);
Johan Hedberg35d70272014-02-19 14:57:47 +02001354 }
1355}
1356
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001357int smp_distribute_keys(struct l2cap_conn *conn)
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001358{
1359 struct smp_cmd_pairing *req, *rsp;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001360 struct smp_chan *smp = conn->smp_chan;
Johan Hedberg524237c2014-02-22 19:06:31 +02001361 struct hci_conn *hcon = conn->hcon;
1362 struct hci_dev *hdev = hcon->hdev;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001363 __u8 *keydist;
1364
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001365 BT_DBG("conn %p", conn);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001366
Johan Hedberg524237c2014-02-22 19:06:31 +02001367 if (!test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001368 return 0;
1369
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001370 rsp = (void *) &smp->prsp[1];
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001371
1372 /* The responder sends its keys first */
Johan Hedbergefabba32014-02-26 23:33:44 +02001373 if (hcon->out && (smp->remote_key_dist & 0x07))
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001374 return 0;
1375
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001376 req = (void *) &smp->preq[1];
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001377
Johan Hedberg524237c2014-02-22 19:06:31 +02001378 if (hcon->out) {
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001379 keydist = &rsp->init_key_dist;
1380 *keydist &= req->init_key_dist;
1381 } else {
1382 keydist = &rsp->resp_key_dist;
1383 *keydist &= req->resp_key_dist;
1384 }
1385
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001386 BT_DBG("keydist 0x%x", *keydist);
1387
1388 if (*keydist & SMP_DIST_ENC_KEY) {
1389 struct smp_cmd_encrypt_info enc;
1390 struct smp_cmd_master_ident ident;
Johan Hedberg23d0e122014-02-19 14:57:46 +02001391 struct smp_ltk *ltk;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001392 u8 authenticated;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001393 __le16 ediv;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001394 __le64 rand;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001395
1396 get_random_bytes(enc.ltk, sizeof(enc.ltk));
1397 get_random_bytes(&ediv, sizeof(ediv));
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001398 get_random_bytes(&rand, sizeof(rand));
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001399
1400 smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
1401
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001402 authenticated = hcon->sec_level == BT_SECURITY_HIGH;
Johan Hedberg524237c2014-02-22 19:06:31 +02001403 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type,
Johan Hedberg2ceba532014-06-16 19:25:16 +03001404 SMP_LTK_SLAVE, authenticated, enc.ltk,
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001405 smp->enc_key_size, ediv, rand);
Johan Hedberg23d0e122014-02-19 14:57:46 +02001406 smp->slave_ltk = ltk;
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001407
Andrei Emeltchenko58115372012-03-12 12:13:06 +02001408 ident.ediv = ediv;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001409 ident.rand = rand;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001410
1411 smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident);
1412
1413 *keydist &= ~SMP_DIST_ENC_KEY;
1414 }
1415
1416 if (*keydist & SMP_DIST_ID_KEY) {
1417 struct smp_cmd_ident_addr_info addrinfo;
1418 struct smp_cmd_ident_info idinfo;
1419
Johan Hedberg863efaf2014-02-22 19:06:32 +02001420 memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk));
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001421
1422 smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo);
1423
Johan Hedberg82d4b352014-02-23 19:42:18 +02001424 /* The hci_conn contains the local identity address
1425 * after the connection has been established.
1426 *
1427 * This is true even when the connection has been
1428 * established using a resolvable random address.
1429 */
Johan Hedberg524237c2014-02-22 19:06:31 +02001430 bacpy(&addrinfo.bdaddr, &hcon->src);
Johan Hedberg82d4b352014-02-23 19:42:18 +02001431 addrinfo.addr_type = hcon->src_type;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001432
1433 smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo),
Marcel Holtmannf1560462013-10-13 05:43:25 -07001434 &addrinfo);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001435
1436 *keydist &= ~SMP_DIST_ID_KEY;
1437 }
1438
1439 if (*keydist & SMP_DIST_SIGN) {
1440 struct smp_cmd_sign_info sign;
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001441 struct smp_csrk *csrk;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001442
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001443 /* Generate a new random key */
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001444 get_random_bytes(sign.csrk, sizeof(sign.csrk));
1445
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001446 csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
1447 if (csrk) {
1448 csrk->master = 0x00;
1449 memcpy(csrk->val, sign.csrk, sizeof(csrk->val));
1450 }
1451 smp->slave_csrk = csrk;
1452
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001453 smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign);
1454
1455 *keydist &= ~SMP_DIST_SIGN;
1456 }
1457
Johan Hedbergefabba32014-02-26 23:33:44 +02001458 /* If there are still keys to be received wait for them */
1459 if ((smp->remote_key_dist & 0x07))
1460 return 0;
1461
Johan Hedberg1d98bf42014-03-24 14:39:08 +02001462 clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags);
1463 cancel_delayed_work_sync(&conn->security_timer);
Johan Hedberg4a74d652014-05-20 09:45:50 +03001464 set_bit(SMP_FLAG_COMPLETE, &smp->flags);
Johan Hedberg1d98bf42014-03-24 14:39:08 +02001465 smp_notify_keys(conn);
Johan Hedbergefabba32014-02-26 23:33:44 +02001466
Johan Hedberg1d98bf42014-03-24 14:39:08 +02001467 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001468
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001469 return 0;
1470}
Johan Hedberg711eafe2014-08-08 09:32:52 +03001471
Johan Hedberg70db83c2014-08-08 09:37:16 +03001472static void smp_teardown_cb(struct l2cap_chan *chan, int err)
1473{
1474 struct l2cap_conn *conn = chan->conn;
1475
1476 BT_DBG("chan %p", chan);
1477
1478 conn->smp = NULL;
1479 l2cap_chan_put(chan);
1480}
1481
1482static void smp_ready_cb(struct l2cap_chan *chan)
1483{
1484 struct l2cap_conn *conn = chan->conn;
1485
1486 BT_DBG("chan %p", chan);
1487
1488 conn->smp = chan;
1489 l2cap_chan_hold(chan);
1490}
1491
1492static struct sk_buff *smp_alloc_skb_cb(struct l2cap_chan *chan,
1493 unsigned long hdr_len,
1494 unsigned long len, int nb)
1495{
1496 struct sk_buff *skb;
1497
1498 skb = bt_skb_alloc(hdr_len + len, GFP_KERNEL);
1499 if (!skb)
1500 return ERR_PTR(-ENOMEM);
1501
1502 skb->priority = HCI_PRIO_MAX;
1503 bt_cb(skb)->chan = chan;
1504
1505 return skb;
1506}
1507
1508static const struct l2cap_ops smp_chan_ops = {
1509 .name = "Security Manager",
1510 .ready = smp_ready_cb,
1511 .alloc_skb = smp_alloc_skb_cb,
1512 .teardown = smp_teardown_cb,
1513
1514 .new_connection = l2cap_chan_no_new_connection,
1515 .recv = l2cap_chan_no_recv,
1516 .state_change = l2cap_chan_no_state_change,
1517 .close = l2cap_chan_no_close,
1518 .defer = l2cap_chan_no_defer,
1519 .suspend = l2cap_chan_no_suspend,
1520 .resume = l2cap_chan_no_resume,
1521 .set_shutdown = l2cap_chan_no_set_shutdown,
1522 .get_sndtimeo = l2cap_chan_no_get_sndtimeo,
1523 .memcpy_fromiovec = l2cap_chan_no_memcpy_fromiovec,
1524};
1525
1526static inline struct l2cap_chan *smp_new_conn_cb(struct l2cap_chan *pchan)
1527{
1528 struct l2cap_chan *chan;
1529
1530 BT_DBG("pchan %p", pchan);
1531
1532 chan = l2cap_chan_create();
1533 if (!chan)
1534 return NULL;
1535
1536 chan->chan_type = pchan->chan_type;
1537 chan->ops = &smp_chan_ops;
1538 chan->scid = pchan->scid;
1539 chan->dcid = chan->scid;
1540 chan->imtu = pchan->imtu;
1541 chan->omtu = pchan->omtu;
1542 chan->mode = pchan->mode;
1543
1544 BT_DBG("created chan %p", chan);
1545
1546 return chan;
1547}
1548
1549static const struct l2cap_ops smp_root_chan_ops = {
1550 .name = "Security Manager Root",
1551 .new_connection = smp_new_conn_cb,
1552
1553 /* None of these are implemented for the root channel */
1554 .close = l2cap_chan_no_close,
1555 .alloc_skb = l2cap_chan_no_alloc_skb,
1556 .recv = l2cap_chan_no_recv,
1557 .state_change = l2cap_chan_no_state_change,
1558 .teardown = l2cap_chan_no_teardown,
1559 .ready = l2cap_chan_no_ready,
1560 .defer = l2cap_chan_no_defer,
1561 .suspend = l2cap_chan_no_suspend,
1562 .resume = l2cap_chan_no_resume,
1563 .set_shutdown = l2cap_chan_no_set_shutdown,
1564 .get_sndtimeo = l2cap_chan_no_get_sndtimeo,
1565 .memcpy_fromiovec = l2cap_chan_no_memcpy_fromiovec,
1566};
1567
Johan Hedberg711eafe2014-08-08 09:32:52 +03001568int smp_register(struct hci_dev *hdev)
1569{
Johan Hedberg70db83c2014-08-08 09:37:16 +03001570 struct l2cap_chan *chan;
Johan Hedbergdefce9e2014-08-08 09:37:17 +03001571 struct crypto_blkcipher *tfm_aes;
Johan Hedberg70db83c2014-08-08 09:37:16 +03001572
Johan Hedberg711eafe2014-08-08 09:32:52 +03001573 BT_DBG("%s", hdev->name);
1574
Johan Hedbergdefce9e2014-08-08 09:37:17 +03001575 tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
1576 if (IS_ERR(tfm_aes)) {
1577 int err = PTR_ERR(tfm_aes);
Johan Hedberg711eafe2014-08-08 09:32:52 +03001578 BT_ERR("Unable to create crypto context");
Johan Hedberg711eafe2014-08-08 09:32:52 +03001579 return err;
1580 }
1581
Johan Hedberg70db83c2014-08-08 09:37:16 +03001582 chan = l2cap_chan_create();
1583 if (!chan) {
Johan Hedbergdefce9e2014-08-08 09:37:17 +03001584 crypto_free_blkcipher(tfm_aes);
Johan Hedberg70db83c2014-08-08 09:37:16 +03001585 return -ENOMEM;
1586 }
1587
Johan Hedbergdefce9e2014-08-08 09:37:17 +03001588 chan->data = tfm_aes;
1589
Johan Hedberg70db83c2014-08-08 09:37:16 +03001590 /* FIXME: Using reserved 0x1f value for now - to be changed to
1591 * L2CAP_CID_SMP once all functionality is in place.
1592 */
1593 l2cap_add_scid(chan, 0x1f);
1594
1595 l2cap_chan_set_defaults(chan);
1596
1597 bacpy(&chan->src, &hdev->bdaddr);
1598 chan->src_type = BDADDR_LE_PUBLIC;
1599 chan->state = BT_LISTEN;
1600 chan->mode = L2CAP_MODE_BASIC;
1601 chan->imtu = L2CAP_DEFAULT_MTU;
1602 chan->ops = &smp_root_chan_ops;
1603
1604 hdev->smp_data = chan;
1605
Johan Hedberg711eafe2014-08-08 09:32:52 +03001606 return 0;
1607}
1608
1609void smp_unregister(struct hci_dev *hdev)
1610{
Johan Hedberg70db83c2014-08-08 09:37:16 +03001611 struct l2cap_chan *chan = hdev->smp_data;
Johan Hedbergdefce9e2014-08-08 09:37:17 +03001612 struct crypto_blkcipher *tfm_aes;
Johan Hedberg70db83c2014-08-08 09:37:16 +03001613
1614 if (!chan)
1615 return;
1616
1617 BT_DBG("%s chan %p", hdev->name, chan);
Johan Hedberg711eafe2014-08-08 09:32:52 +03001618
Johan Hedbergdefce9e2014-08-08 09:37:17 +03001619 tfm_aes = chan->data;
1620 if (tfm_aes) {
1621 chan->data = NULL;
1622 crypto_free_blkcipher(tfm_aes);
Johan Hedberg711eafe2014-08-08 09:32:52 +03001623 }
Johan Hedberg70db83c2014-08-08 09:37:16 +03001624
1625 hdev->smp_data = NULL;
1626 l2cap_chan_put(chan);
Johan Hedberg711eafe2014-08-08 09:32:52 +03001627}