blob: fd32943008030332bc523e12a8d2e9a560381f04 [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
142bool smp_irk_matches(struct crypto_blkcipher *tfm, u8 irk[16],
143 bdaddr_t *bdaddr)
144{
145 u8 hash[3];
146 int err;
147
148 BT_DBG("RPA %pMR IRK %*phN", bdaddr, 16, irk);
149
150 err = smp_ah(tfm, irk, &bdaddr->b[3], hash);
151 if (err)
152 return false;
153
154 return !memcmp(bdaddr->b, hash, 3);
155}
156
Johan Hedbergb1e2b3a2014-02-23 19:42:19 +0200157int smp_generate_rpa(struct crypto_blkcipher *tfm, u8 irk[16], bdaddr_t *rpa)
158{
159 int err;
160
161 get_random_bytes(&rpa->b[3], 3);
162
163 rpa->b[5] &= 0x3f; /* Clear two most significant bits */
164 rpa->b[5] |= 0x40; /* Set second most significant bit */
165
166 err = smp_ah(tfm, irk, &rpa->b[3], rpa->b);
167 if (err < 0)
168 return err;
169
170 BT_DBG("RPA %pMR", rpa);
171
172 return 0;
173}
174
Johan Hedbergec70f362014-06-27 14:23:04 +0300175static int smp_c1(struct smp_chan *smp, u8 k[16], u8 r[16], u8 preq[7],
176 u8 pres[7], u8 _iat, bdaddr_t *ia, u8 _rat, bdaddr_t *ra,
177 u8 res[16])
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300178{
Johan Hedbergec70f362014-06-27 14:23:04 +0300179 struct hci_dev *hdev = smp->conn->hcon->hdev;
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300180 u8 p1[16], p2[16];
181 int err;
182
Johan Hedbergec70f362014-06-27 14:23:04 +0300183 BT_DBG("%s", hdev->name);
184
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300185 memset(p1, 0, 16);
186
187 /* p1 = pres || preq || _rat || _iat */
Johan Hedberg943a7322014-03-18 12:58:24 +0200188 p1[0] = _iat;
189 p1[1] = _rat;
190 memcpy(p1 + 2, preq, 7);
191 memcpy(p1 + 9, pres, 7);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300192
193 /* p2 = padding || ia || ra */
Johan Hedberg943a7322014-03-18 12:58:24 +0200194 memcpy(p2, ra, 6);
195 memcpy(p2 + 6, ia, 6);
196 memset(p2 + 12, 0, 4);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300197
198 /* res = r XOR p1 */
199 u128_xor((u128 *) res, (u128 *) r, (u128 *) p1);
200
201 /* res = e(k, res) */
Johan Hedbergec70f362014-06-27 14:23:04 +0300202 err = smp_e(smp->tfm_aes, k, res);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300203 if (err) {
204 BT_ERR("Encrypt data error");
205 return err;
206 }
207
208 /* res = res XOR p2 */
209 u128_xor((u128 *) res, (u128 *) res, (u128 *) p2);
210
211 /* res = e(k, res) */
Johan Hedbergec70f362014-06-27 14:23:04 +0300212 err = smp_e(smp->tfm_aes, k, res);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300213 if (err)
214 BT_ERR("Encrypt data error");
215
216 return err;
217}
218
Johan Hedbergec70f362014-06-27 14:23:04 +0300219static int smp_s1(struct smp_chan *smp, u8 k[16], u8 r1[16], u8 r2[16],
220 u8 _r[16])
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300221{
Johan Hedbergec70f362014-06-27 14:23:04 +0300222 struct hci_dev *hdev = smp->conn->hcon->hdev;
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300223 int err;
224
Johan Hedbergec70f362014-06-27 14:23:04 +0300225 BT_DBG("%s", hdev->name);
226
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300227 /* Just least significant octets from r1 and r2 are considered */
Johan Hedberg943a7322014-03-18 12:58:24 +0200228 memcpy(_r, r2, 8);
229 memcpy(_r + 8, r1, 8);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300230
Johan Hedbergec70f362014-06-27 14:23:04 +0300231 err = smp_e(smp->tfm_aes, k, _r);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300232 if (err)
233 BT_ERR("Encrypt data error");
234
235 return err;
236}
237
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300238static struct sk_buff *smp_build_cmd(struct l2cap_conn *conn, u8 code,
Marcel Holtmannf1560462013-10-13 05:43:25 -0700239 u16 dlen, void *data)
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300240{
241 struct sk_buff *skb;
242 struct l2cap_hdr *lh;
243 int len;
244
245 len = L2CAP_HDR_SIZE + sizeof(code) + dlen;
246
247 if (len > conn->mtu)
248 return NULL;
249
250 skb = bt_skb_alloc(len, GFP_ATOMIC);
251 if (!skb)
252 return NULL;
253
254 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
255 lh->len = cpu_to_le16(sizeof(code) + dlen);
Joe Perchesdcf4adb2014-03-12 10:52:35 -0700256 lh->cid = cpu_to_le16(L2CAP_CID_SMP);
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300257
258 memcpy(skb_put(skb, sizeof(code)), &code, sizeof(code));
259
260 memcpy(skb_put(skb, dlen), data, dlen);
261
262 return skb;
263}
264
265static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
266{
267 struct sk_buff *skb = smp_build_cmd(conn, code, len, data);
268
269 BT_DBG("code 0x%2.2x", code);
270
271 if (!skb)
272 return;
273
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200274 skb->priority = HCI_PRIO_MAX;
275 hci_send_acl(conn->hchan, skb, 0);
Vinicius Costa Gomese2dcd112011-08-19 21:06:50 -0300276
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -0200277 cancel_delayed_work_sync(&conn->security_timer);
Marcel Holtmann17b02e62012-03-01 14:32:37 -0800278 schedule_delayed_work(&conn->security_timer, SMP_TIMEOUT);
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300279}
280
Brian Gix2b64d152011-12-21 16:12:12 -0800281static __u8 authreq_to_seclevel(__u8 authreq)
282{
283 if (authreq & SMP_AUTH_MITM)
284 return BT_SECURITY_HIGH;
285 else
286 return BT_SECURITY_MEDIUM;
287}
288
289static __u8 seclevel_to_authreq(__u8 sec_level)
290{
291 switch (sec_level) {
292 case BT_SECURITY_HIGH:
293 return SMP_AUTH_MITM | SMP_AUTH_BONDING;
294 case BT_SECURITY_MEDIUM:
295 return SMP_AUTH_BONDING;
296 default:
297 return SMP_AUTH_NONE;
298 }
299}
300
Vinicius Costa Gomesb8e66ea2011-06-09 18:50:52 -0300301static void build_pairing_cmd(struct l2cap_conn *conn,
Marcel Holtmannf1560462013-10-13 05:43:25 -0700302 struct smp_cmd_pairing *req,
303 struct smp_cmd_pairing *rsp, __u8 authreq)
Vinicius Costa Gomesb8e66ea2011-06-09 18:50:52 -0300304{
Johan Hedbergfd349c02014-02-18 10:19:36 +0200305 struct smp_chan *smp = conn->smp_chan;
306 struct hci_conn *hcon = conn->hcon;
307 struct hci_dev *hdev = hcon->hdev;
308 u8 local_dist = 0, remote_dist = 0;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300309
Johan Hedbergb6ae8452014-07-30 09:22:22 +0300310 if (test_bit(HCI_BONDABLE, &conn->hcon->hdev->dev_flags)) {
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -0700311 local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
312 remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300313 authreq |= SMP_AUTH_BONDING;
Brian Gix2b64d152011-12-21 16:12:12 -0800314 } else {
315 authreq &= ~SMP_AUTH_BONDING;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300316 }
317
Johan Hedbergfd349c02014-02-18 10:19:36 +0200318 if (test_bit(HCI_RPA_RESOLVING, &hdev->dev_flags))
319 remote_dist |= SMP_DIST_ID_KEY;
320
Johan Hedberg863efaf2014-02-22 19:06:32 +0200321 if (test_bit(HCI_PRIVACY, &hdev->dev_flags))
322 local_dist |= SMP_DIST_ID_KEY;
323
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300324 if (rsp == NULL) {
325 req->io_capability = conn->hcon->io_capability;
326 req->oob_flag = SMP_OOB_NOT_PRESENT;
327 req->max_key_size = SMP_MAX_ENC_KEY_SIZE;
Johan Hedbergfd349c02014-02-18 10:19:36 +0200328 req->init_key_dist = local_dist;
329 req->resp_key_dist = remote_dist;
Johan Hedberg065a13e2012-10-11 16:26:06 +0200330 req->auth_req = (authreq & AUTH_REQ_MASK);
Johan Hedbergfd349c02014-02-18 10:19:36 +0200331
332 smp->remote_key_dist = remote_dist;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300333 return;
334 }
335
336 rsp->io_capability = conn->hcon->io_capability;
337 rsp->oob_flag = SMP_OOB_NOT_PRESENT;
338 rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE;
Johan Hedbergfd349c02014-02-18 10:19:36 +0200339 rsp->init_key_dist = req->init_key_dist & remote_dist;
340 rsp->resp_key_dist = req->resp_key_dist & local_dist;
Johan Hedberg065a13e2012-10-11 16:26:06 +0200341 rsp->auth_req = (authreq & AUTH_REQ_MASK);
Johan Hedbergfd349c02014-02-18 10:19:36 +0200342
343 smp->remote_key_dist = rsp->init_key_dist;
Vinicius Costa Gomesb8e66ea2011-06-09 18:50:52 -0300344}
345
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300346static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
347{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300348 struct smp_chan *smp = conn->smp_chan;
349
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300350 if ((max_key_size > SMP_MAX_ENC_KEY_SIZE) ||
Marcel Holtmannf1560462013-10-13 05:43:25 -0700351 (max_key_size < SMP_MIN_ENC_KEY_SIZE))
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300352 return SMP_ENC_KEY_SIZE;
353
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300354 smp->enc_key_size = max_key_size;
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300355
356 return 0;
357}
358
Johan Hedberg84794e12013-11-06 11:24:57 +0200359static void smp_failure(struct l2cap_conn *conn, u8 reason)
Brian Gix4f957a72011-11-23 08:28:36 -0800360{
Johan Hedbergbab73cb2012-02-09 16:07:29 +0200361 struct hci_conn *hcon = conn->hcon;
362
Johan Hedberg84794e12013-11-06 11:24:57 +0200363 if (reason)
Brian Gix4f957a72011-11-23 08:28:36 -0800364 smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
Marcel Holtmannf1560462013-10-13 05:43:25 -0700365 &reason);
Brian Gix4f957a72011-11-23 08:28:36 -0800366
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700367 clear_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags);
368 mgmt_auth_failed(hcon->hdev, &hcon->dst, hcon->type, hcon->dst_type,
369 HCI_ERROR_AUTH_FAILURE);
Vinicius Costa Gomesf1c09c02012-02-01 18:27:56 -0300370
Andre Guedes61a0cfb2012-08-01 20:34:15 -0300371 cancel_delayed_work_sync(&conn->security_timer);
372
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700373 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesf1c09c02012-02-01 18:27:56 -0300374 smp_chan_destroy(conn);
Brian Gix4f957a72011-11-23 08:28:36 -0800375}
376
Brian Gix2b64d152011-12-21 16:12:12 -0800377#define JUST_WORKS 0x00
378#define JUST_CFM 0x01
379#define REQ_PASSKEY 0x02
380#define CFM_PASSKEY 0x03
381#define REQ_OOB 0x04
382#define OVERLAP 0xFF
383
384static const u8 gen_method[5][5] = {
385 { JUST_WORKS, JUST_CFM, REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
386 { JUST_WORKS, JUST_CFM, REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
387 { CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
388 { JUST_WORKS, JUST_CFM, JUST_WORKS, JUST_WORKS, JUST_CFM },
389 { CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, OVERLAP },
390};
391
Johan Hedberg581370c2014-06-17 13:07:38 +0300392static u8 get_auth_method(struct smp_chan *smp, u8 local_io, u8 remote_io)
393{
Johan Hedberg2bcd4002014-07-09 19:18:09 +0300394 /* If either side has unknown io_caps, use JUST_CFM (which gets
395 * converted later to JUST_WORKS if we're initiators.
396 */
Johan Hedberg581370c2014-06-17 13:07:38 +0300397 if (local_io > SMP_IO_KEYBOARD_DISPLAY ||
398 remote_io > SMP_IO_KEYBOARD_DISPLAY)
Johan Hedberg2bcd4002014-07-09 19:18:09 +0300399 return JUST_CFM;
Johan Hedberg581370c2014-06-17 13:07:38 +0300400
401 return gen_method[remote_io][local_io];
402}
403
Brian Gix2b64d152011-12-21 16:12:12 -0800404static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
405 u8 local_io, u8 remote_io)
406{
407 struct hci_conn *hcon = conn->hcon;
408 struct smp_chan *smp = conn->smp_chan;
409 u8 method;
410 u32 passkey = 0;
411 int ret = 0;
412
413 /* Initialize key for JUST WORKS */
414 memset(smp->tk, 0, sizeof(smp->tk));
Johan Hedberg4a74d652014-05-20 09:45:50 +0300415 clear_bit(SMP_FLAG_TK_VALID, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800416
417 BT_DBG("tk_request: auth:%d lcl:%d rem:%d", auth, local_io, remote_io);
418
Johan Hedberg2bcd4002014-07-09 19:18:09 +0300419 /* If neither side wants MITM, either "just" confirm an incoming
420 * request or use just-works for outgoing ones. The JUST_CFM
421 * will be converted to JUST_WORKS if necessary later in this
422 * function. If either side has MITM look up the method from the
423 * table.
424 */
Johan Hedberg581370c2014-06-17 13:07:38 +0300425 if (!(auth & SMP_AUTH_MITM))
Johan Hedberg2bcd4002014-07-09 19:18:09 +0300426 method = JUST_CFM;
Brian Gix2b64d152011-12-21 16:12:12 -0800427 else
Johan Hedberg581370c2014-06-17 13:07:38 +0300428 method = get_auth_method(smp, local_io, remote_io);
Brian Gix2b64d152011-12-21 16:12:12 -0800429
Johan Hedberga82505c2014-03-24 14:39:07 +0200430 /* Don't confirm locally initiated pairing attempts */
Johan Hedberg4a74d652014-05-20 09:45:50 +0300431 if (method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR, &smp->flags))
Johan Hedberga82505c2014-03-24 14:39:07 +0200432 method = JUST_WORKS;
433
Johan Hedberg02f3e252014-07-16 15:09:13 +0300434 /* Don't bother user space with no IO capabilities */
435 if (method == JUST_CFM && hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
436 method = JUST_WORKS;
437
Brian Gix2b64d152011-12-21 16:12:12 -0800438 /* If Just Works, Continue with Zero TK */
439 if (method == JUST_WORKS) {
Johan Hedberg4a74d652014-05-20 09:45:50 +0300440 set_bit(SMP_FLAG_TK_VALID, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800441 return 0;
442 }
443
444 /* Not Just Works/Confirm results in MITM Authentication */
445 if (method != JUST_CFM)
Johan Hedberg4a74d652014-05-20 09:45:50 +0300446 set_bit(SMP_FLAG_MITM_AUTH, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800447
448 /* If both devices have Keyoard-Display I/O, the master
449 * Confirms and the slave Enters the passkey.
450 */
451 if (method == OVERLAP) {
Johan Hedberg40bef302014-07-16 11:42:27 +0300452 if (hcon->role == HCI_ROLE_MASTER)
Brian Gix2b64d152011-12-21 16:12:12 -0800453 method = CFM_PASSKEY;
454 else
455 method = REQ_PASSKEY;
456 }
457
Johan Hedberg01ad34d2014-03-19 14:14:53 +0200458 /* Generate random passkey. */
Brian Gix2b64d152011-12-21 16:12:12 -0800459 if (method == CFM_PASSKEY) {
Johan Hedberg943a7322014-03-18 12:58:24 +0200460 memset(smp->tk, 0, sizeof(smp->tk));
Brian Gix2b64d152011-12-21 16:12:12 -0800461 get_random_bytes(&passkey, sizeof(passkey));
462 passkey %= 1000000;
Johan Hedberg943a7322014-03-18 12:58:24 +0200463 put_unaligned_le32(passkey, smp->tk);
Brian Gix2b64d152011-12-21 16:12:12 -0800464 BT_DBG("PassKey: %d", passkey);
Johan Hedberg4a74d652014-05-20 09:45:50 +0300465 set_bit(SMP_FLAG_TK_VALID, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800466 }
467
468 hci_dev_lock(hcon->hdev);
469
470 if (method == REQ_PASSKEY)
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700471 ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200472 hcon->type, hcon->dst_type);
Johan Hedberg4eb65e62014-03-24 14:39:05 +0200473 else if (method == JUST_CFM)
474 ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
475 hcon->type, hcon->dst_type,
476 passkey, 1);
Brian Gix2b64d152011-12-21 16:12:12 -0800477 else
Johan Hedberg01ad34d2014-03-19 14:14:53 +0200478 ret = mgmt_user_passkey_notify(hcon->hdev, &hcon->dst,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200479 hcon->type, hcon->dst_type,
Johan Hedberg39adbff2014-03-20 08:18:14 +0200480 passkey, 0);
Brian Gix2b64d152011-12-21 16:12:12 -0800481
482 hci_dev_unlock(hcon->hdev);
483
484 return ret;
485}
486
Johan Hedberg1cc61142014-05-20 09:45:52 +0300487static u8 smp_confirm(struct smp_chan *smp)
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300488{
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300489 struct l2cap_conn *conn = smp->conn;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300490 struct smp_cmd_pairing_confirm cp;
491 int ret;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300492
493 BT_DBG("conn %p", conn);
494
Johan Hedbergec70f362014-06-27 14:23:04 +0300495 ret = smp_c1(smp, smp->tk, smp->prnd, smp->preq, smp->prsp,
Johan Hedbergb1cd5fd2014-02-28 12:54:17 +0200496 conn->hcon->init_addr_type, &conn->hcon->init_addr,
Johan Hedberg943a7322014-03-18 12:58:24 +0200497 conn->hcon->resp_addr_type, &conn->hcon->resp_addr,
498 cp.confirm_val);
Johan Hedberg1cc61142014-05-20 09:45:52 +0300499 if (ret)
500 return SMP_UNSPECIFIED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300501
Johan Hedberg4a74d652014-05-20 09:45:50 +0300502 clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800503
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300504 smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
505
Johan Hedberg1cc61142014-05-20 09:45:52 +0300506 return 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300507}
508
Johan Hedberg861580a2014-05-20 09:45:51 +0300509static u8 smp_random(struct smp_chan *smp)
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300510{
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300511 struct l2cap_conn *conn = smp->conn;
512 struct hci_conn *hcon = conn->hcon;
Johan Hedberg861580a2014-05-20 09:45:51 +0300513 u8 confirm[16];
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300514 int ret;
515
Johan Hedbergec70f362014-06-27 14:23:04 +0300516 if (IS_ERR_OR_NULL(smp->tfm_aes))
Johan Hedberg861580a2014-05-20 09:45:51 +0300517 return SMP_UNSPECIFIED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300518
519 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
520
Johan Hedbergec70f362014-06-27 14:23:04 +0300521 ret = smp_c1(smp, smp->tk, smp->rrnd, smp->preq, smp->prsp,
Johan Hedbergb1cd5fd2014-02-28 12:54:17 +0200522 hcon->init_addr_type, &hcon->init_addr,
Johan Hedberg943a7322014-03-18 12:58:24 +0200523 hcon->resp_addr_type, &hcon->resp_addr, confirm);
Johan Hedberg861580a2014-05-20 09:45:51 +0300524 if (ret)
525 return SMP_UNSPECIFIED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300526
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300527 if (memcmp(smp->pcnf, confirm, sizeof(smp->pcnf)) != 0) {
528 BT_ERR("Pairing failed (confirmation values mismatch)");
Johan Hedberg861580a2014-05-20 09:45:51 +0300529 return SMP_CONFIRM_FAILED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300530 }
531
532 if (hcon->out) {
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -0800533 u8 stk[16];
534 __le64 rand = 0;
535 __le16 ediv = 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300536
Johan Hedbergec70f362014-06-27 14:23:04 +0300537 smp_s1(smp, smp->tk, smp->rrnd, smp->prnd, stk);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300538
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300539 memset(stk + smp->enc_key_size, 0,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300540 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300541
Johan Hedberg861580a2014-05-20 09:45:51 +0300542 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
543 return SMP_UNSPECIFIED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300544
545 hci_le_start_enc(hcon, ediv, rand, stk);
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300546 hcon->enc_key_size = smp->enc_key_size;
Johan Hedbergfe59a052014-07-01 19:14:12 +0300547 set_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300548 } else {
Johan Hedbergfff34902014-06-10 15:19:50 +0300549 u8 stk[16], auth;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -0800550 __le64 rand = 0;
551 __le16 ediv = 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300552
Johan Hedberg943a7322014-03-18 12:58:24 +0200553 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
554 smp->prnd);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300555
Johan Hedbergec70f362014-06-27 14:23:04 +0300556 smp_s1(smp, smp->tk, smp->prnd, smp->rrnd, stk);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300557
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300558 memset(stk + smp->enc_key_size, 0,
Marcel Holtmannf1560462013-10-13 05:43:25 -0700559 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300560
Johan Hedbergfff34902014-06-10 15:19:50 +0300561 if (hcon->pending_sec_level == BT_SECURITY_HIGH)
562 auth = 1;
563 else
564 auth = 0;
565
Johan Hedberg7d5843b2014-06-16 19:25:15 +0300566 /* Even though there's no _SLAVE suffix this is the
567 * slave STK we're adding for later lookup (the master
568 * STK never needs to be stored).
569 */
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700570 hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
Johan Hedberg2ceba532014-06-16 19:25:16 +0300571 SMP_STK, auth, stk, smp->enc_key_size, ediv, rand);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300572 }
573
Johan Hedberg861580a2014-05-20 09:45:51 +0300574 return 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300575}
576
577static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
578{
579 struct smp_chan *smp;
580
Marcel Holtmannf1560462013-10-13 05:43:25 -0700581 smp = kzalloc(sizeof(*smp), GFP_ATOMIC);
Johan Hedberg616d55b2014-07-29 14:18:48 +0300582 if (!smp) {
583 clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300584 return NULL;
Johan Hedberg616d55b2014-07-29 14:18:48 +0300585 }
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300586
Johan Hedberg6a7bd102014-06-27 14:23:03 +0300587 smp->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
588 if (IS_ERR(smp->tfm_aes)) {
589 BT_ERR("Unable to create ECB crypto context");
590 kfree(smp);
Johan Hedberg616d55b2014-07-29 14:18:48 +0300591 clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags);
Johan Hedberg6a7bd102014-06-27 14:23:03 +0300592 return NULL;
593 }
594
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300595 smp->conn = conn;
596 conn->smp_chan = smp;
597
598 hci_conn_hold(conn->hcon);
599
600 return smp;
601}
602
603void smp_chan_destroy(struct l2cap_conn *conn)
604{
Brian Gixc8eb9692011-11-23 08:28:35 -0800605 struct smp_chan *smp = conn->smp_chan;
Johan Hedbergf4a407b2014-02-18 21:41:34 +0200606 bool complete;
Brian Gixc8eb9692011-11-23 08:28:35 -0800607
Vinicius Costa Gomesf1c09c02012-02-01 18:27:56 -0300608 BUG_ON(!smp);
Brian Gixc8eb9692011-11-23 08:28:35 -0800609
Johan Hedberg4a74d652014-05-20 09:45:50 +0300610 complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags);
Johan Hedbergf4a407b2014-02-18 21:41:34 +0200611 mgmt_smp_complete(conn->hcon, complete);
612
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -0700613 kfree(smp->csrk);
614 kfree(smp->slave_csrk);
615
Johan Hedberg6a7bd102014-06-27 14:23:03 +0300616 crypto_free_blkcipher(smp->tfm_aes);
617
Johan Hedberg759331d2014-02-28 10:10:16 +0200618 /* If pairing failed clean up any keys we might have */
619 if (!complete) {
620 if (smp->ltk) {
621 list_del(&smp->ltk->list);
622 kfree(smp->ltk);
623 }
624
625 if (smp->slave_ltk) {
626 list_del(&smp->slave_ltk->list);
627 kfree(smp->slave_ltk);
628 }
629
630 if (smp->remote_irk) {
631 list_del(&smp->remote_irk->list);
632 kfree(smp->remote_irk);
633 }
634 }
635
Brian Gixc8eb9692011-11-23 08:28:35 -0800636 kfree(smp);
637 conn->smp_chan = NULL;
David Herrmann76a68ba2013-04-06 20:28:37 +0200638 hci_conn_drop(conn->hcon);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300639}
640
Brian Gix2b64d152011-12-21 16:12:12 -0800641int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
642{
Johan Hedbergb10e8012014-06-27 14:23:07 +0300643 struct l2cap_conn *conn = hcon->l2cap_data;
Brian Gix2b64d152011-12-21 16:12:12 -0800644 struct smp_chan *smp;
645 u32 value;
Brian Gix2b64d152011-12-21 16:12:12 -0800646
647 BT_DBG("");
648
Johan Hedberg642ac772014-06-27 14:23:06 +0300649 if (!conn || !test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Brian Gix2b64d152011-12-21 16:12:12 -0800650 return -ENOTCONN;
651
652 smp = conn->smp_chan;
653
654 switch (mgmt_op) {
655 case MGMT_OP_USER_PASSKEY_REPLY:
656 value = le32_to_cpu(passkey);
Johan Hedberg943a7322014-03-18 12:58:24 +0200657 memset(smp->tk, 0, sizeof(smp->tk));
Brian Gix2b64d152011-12-21 16:12:12 -0800658 BT_DBG("PassKey: %d", value);
Johan Hedberg943a7322014-03-18 12:58:24 +0200659 put_unaligned_le32(value, smp->tk);
Brian Gix2b64d152011-12-21 16:12:12 -0800660 /* Fall Through */
661 case MGMT_OP_USER_CONFIRM_REPLY:
Johan Hedberg4a74d652014-05-20 09:45:50 +0300662 set_bit(SMP_FLAG_TK_VALID, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800663 break;
664 case MGMT_OP_USER_PASSKEY_NEG_REPLY:
665 case MGMT_OP_USER_CONFIRM_NEG_REPLY:
Johan Hedberg84794e12013-11-06 11:24:57 +0200666 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
Brian Gix2b64d152011-12-21 16:12:12 -0800667 return 0;
668 default:
Johan Hedberg84794e12013-11-06 11:24:57 +0200669 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
Brian Gix2b64d152011-12-21 16:12:12 -0800670 return -EOPNOTSUPP;
671 }
672
673 /* If it is our turn to send Pairing Confirm, do so now */
Johan Hedberg1cc61142014-05-20 09:45:52 +0300674 if (test_bit(SMP_FLAG_CFM_PENDING, &smp->flags)) {
675 u8 rsp = smp_confirm(smp);
676 if (rsp)
677 smp_failure(conn, rsp);
678 }
Brian Gix2b64d152011-12-21 16:12:12 -0800679
680 return 0;
681}
682
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300683static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300684{
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300685 struct smp_cmd_pairing rsp, *req = (void *) skb->data;
Johan Hedbergb3c64102014-07-10 11:02:07 +0300686 struct hci_dev *hdev = conn->hcon->hdev;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300687 struct smp_chan *smp;
Johan Hedbergc7262e72014-06-17 13:07:37 +0300688 u8 key_size, auth, sec_level;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300689 int ret;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300690
691 BT_DBG("conn %p", conn);
692
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200693 if (skb->len < sizeof(*req))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300694 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200695
Johan Hedberg40bef302014-07-16 11:42:27 +0300696 if (conn->hcon->role != HCI_ROLE_SLAVE)
Brian Gix2b64d152011-12-21 16:12:12 -0800697 return SMP_CMD_NOTSUPP;
698
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200699 if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags))
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300700 smp = smp_chan_create(conn);
Andrei Emeltchenkod08fd0e2012-07-19 17:03:43 +0300701 else
702 smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300703
Andrei Emeltchenkod08fd0e2012-07-19 17:03:43 +0300704 if (!smp)
705 return SMP_UNSPECIFIED;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300706
Johan Hedbergb6ae8452014-07-30 09:22:22 +0300707 if (!test_bit(HCI_BONDABLE, &hdev->dev_flags) &&
Johan Hedbergb3c64102014-07-10 11:02:07 +0300708 (req->auth_req & SMP_AUTH_BONDING))
709 return SMP_PAIRING_NOTSUPP;
710
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300711 smp->preq[0] = SMP_CMD_PAIRING_REQ;
712 memcpy(&smp->preq[1], req, sizeof(*req));
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300713 skb_pull(skb, sizeof(*req));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300714
Brian Gix2b64d152011-12-21 16:12:12 -0800715 /* We didn't start the pairing, so match remote */
Johan Hedberg1ef35822014-05-20 09:45:48 +0300716 auth = req->auth_req;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300717
Johan Hedbergc7262e72014-06-17 13:07:37 +0300718 sec_level = authreq_to_seclevel(auth);
719 if (sec_level > conn->hcon->pending_sec_level)
720 conn->hcon->pending_sec_level = sec_level;
Ido Yarivfdde0a22012-03-05 20:09:38 +0200721
Johan Hedberg2ed8f652014-06-17 13:07:39 +0300722 /* If we need MITM check that it can be acheived */
723 if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
724 u8 method;
725
726 method = get_auth_method(smp, conn->hcon->io_capability,
727 req->io_capability);
728 if (method == JUST_WORKS || method == JUST_CFM)
729 return SMP_AUTH_REQUIREMENTS;
730 }
731
Brian Gix2b64d152011-12-21 16:12:12 -0800732 build_pairing_cmd(conn, req, &rsp, auth);
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300733
734 key_size = min(req->max_key_size, rsp.max_key_size);
735 if (check_enc_key_size(conn, key_size))
736 return SMP_ENC_KEY_SIZE;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300737
Johan Hedberge84a6b12013-12-02 10:49:03 +0200738 get_random_bytes(smp->prnd, sizeof(smp->prnd));
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300739
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300740 smp->prsp[0] = SMP_CMD_PAIRING_RSP;
741 memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300742
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300743 smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300744
Brian Gix2b64d152011-12-21 16:12:12 -0800745 /* Request setup of TK */
746 ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability);
747 if (ret)
748 return SMP_UNSPECIFIED;
749
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300750 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300751}
752
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300753static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300754{
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300755 struct smp_cmd_pairing *req, *rsp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300756 struct smp_chan *smp = conn->smp_chan;
Brian Gix2b64d152011-12-21 16:12:12 -0800757 u8 key_size, auth = SMP_AUTH_NONE;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300758 int ret;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300759
760 BT_DBG("conn %p", conn);
761
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200762 if (skb->len < sizeof(*rsp))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300763 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200764
Johan Hedberg40bef302014-07-16 11:42:27 +0300765 if (conn->hcon->role != HCI_ROLE_MASTER)
Brian Gix2b64d152011-12-21 16:12:12 -0800766 return SMP_CMD_NOTSUPP;
767
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300768 skb_pull(skb, sizeof(*rsp));
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300769
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300770 req = (void *) &smp->preq[1];
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300771
772 key_size = min(req->max_key_size, rsp->max_key_size);
773 if (check_enc_key_size(conn, key_size))
774 return SMP_ENC_KEY_SIZE;
775
Johan Hedberg2ed8f652014-06-17 13:07:39 +0300776 /* If we need MITM check that it can be acheived */
777 if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
778 u8 method;
779
780 method = get_auth_method(smp, req->io_capability,
781 rsp->io_capability);
782 if (method == JUST_WORKS || method == JUST_CFM)
783 return SMP_AUTH_REQUIREMENTS;
784 }
785
Johan Hedberge84a6b12013-12-02 10:49:03 +0200786 get_random_bytes(smp->prnd, sizeof(smp->prnd));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300787
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300788 smp->prsp[0] = SMP_CMD_PAIRING_RSP;
789 memcpy(&smp->prsp[1], rsp, sizeof(*rsp));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300790
Johan Hedbergfdcc4be2014-03-14 10:53:50 +0200791 /* Update remote key distribution in case the remote cleared
792 * some bits that we had enabled in our request.
793 */
794 smp->remote_key_dist &= rsp->resp_key_dist;
795
Brian Gix2b64d152011-12-21 16:12:12 -0800796 if ((req->auth_req & SMP_AUTH_BONDING) &&
Marcel Holtmannf1560462013-10-13 05:43:25 -0700797 (rsp->auth_req & SMP_AUTH_BONDING))
Brian Gix2b64d152011-12-21 16:12:12 -0800798 auth = SMP_AUTH_BONDING;
799
800 auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM;
801
Johan Hedberg476585e2012-06-06 18:54:15 +0800802 ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability);
Brian Gix2b64d152011-12-21 16:12:12 -0800803 if (ret)
804 return SMP_UNSPECIFIED;
805
Johan Hedberg4a74d652014-05-20 09:45:50 +0300806 set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800807
808 /* Can't compose response until we have been confirmed */
Johan Hedberg4a74d652014-05-20 09:45:50 +0300809 if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
Johan Hedberg1cc61142014-05-20 09:45:52 +0300810 return smp_confirm(smp);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300811
812 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300813}
814
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300815static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300816{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300817 struct smp_chan *smp = conn->smp_chan;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300818
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300819 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
820
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200821 if (skb->len < sizeof(smp->pcnf))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300822 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200823
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300824 memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf));
825 skb_pull(skb, sizeof(smp->pcnf));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300826
Johan Hedberg943a7322014-03-18 12:58:24 +0200827 if (conn->hcon->out)
828 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
829 smp->prnd);
Johan Hedberg4a74d652014-05-20 09:45:50 +0300830 else if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
Johan Hedberg1cc61142014-05-20 09:45:52 +0300831 return smp_confirm(smp);
Johan Hedberg943a7322014-03-18 12:58:24 +0200832 else
Johan Hedberg4a74d652014-05-20 09:45:50 +0300833 set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300834
835 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300836}
837
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300838static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300839{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300840 struct smp_chan *smp = conn->smp_chan;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300841
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300842 BT_DBG("conn %p", conn);
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300843
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200844 if (skb->len < sizeof(smp->rrnd))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300845 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200846
Johan Hedberg943a7322014-03-18 12:58:24 +0200847 memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd));
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300848 skb_pull(skb, sizeof(smp->rrnd));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300849
Johan Hedberg861580a2014-05-20 09:45:51 +0300850 return smp_random(smp);
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300851}
852
Marcel Holtmannf81cd822014-07-01 10:59:24 +0200853static bool smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300854{
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300855 struct smp_ltk *key;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300856 struct hci_conn *hcon = conn->hcon;
857
Johan Hedberg98a0b842014-01-30 19:40:00 -0800858 key = hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type,
Johan Hedberge804d252014-07-16 11:42:28 +0300859 hcon->role);
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300860 if (!key)
Marcel Holtmannf81cd822014-07-01 10:59:24 +0200861 return false;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300862
Johan Hedberg4dab7862012-06-07 14:58:37 +0800863 if (sec_level > BT_SECURITY_MEDIUM && !key->authenticated)
Marcel Holtmannf81cd822014-07-01 10:59:24 +0200864 return false;
Johan Hedberg4dab7862012-06-07 14:58:37 +0800865
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200866 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
Marcel Holtmannf81cd822014-07-01 10:59:24 +0200867 return true;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300868
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300869 hci_le_start_enc(hcon, key->ediv, key->rand, key->val);
870 hcon->enc_key_size = key->enc_size;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300871
Johan Hedbergfe59a052014-07-01 19:14:12 +0300872 /* We never store STKs for master role, so clear this flag */
873 clear_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags);
874
Marcel Holtmannf81cd822014-07-01 10:59:24 +0200875 return true;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300876}
Marcel Holtmannf1560462013-10-13 05:43:25 -0700877
Johan Hedberg854f4722014-07-01 18:40:20 +0300878bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level)
879{
880 if (sec_level == BT_SECURITY_LOW)
881 return true;
882
Johan Hedberg9ab65d602014-07-01 19:14:13 +0300883 /* If we're encrypted with an STK always claim insufficient
884 * security. This way we allow the connection to be re-encrypted
885 * with an LTK, even if the LTK provides the same level of
Johan Hedbergb2d5e252014-07-14 14:34:55 +0300886 * security. Only exception is if we don't have an LTK (e.g.
887 * because of key distribution bits).
Johan Hedberg9ab65d602014-07-01 19:14:13 +0300888 */
Johan Hedbergb2d5e252014-07-14 14:34:55 +0300889 if (test_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags) &&
890 hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type,
Johan Hedberge804d252014-07-16 11:42:28 +0300891 hcon->role))
Johan Hedberg9ab65d602014-07-01 19:14:13 +0300892 return false;
893
Johan Hedberg854f4722014-07-01 18:40:20 +0300894 if (hcon->sec_level >= sec_level)
895 return true;
896
897 return false;
898}
899
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300900static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300901{
902 struct smp_cmd_security_req *rp = (void *) skb->data;
903 struct smp_cmd_pairing cp;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300904 struct hci_conn *hcon = conn->hcon;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300905 struct smp_chan *smp;
Johan Hedbergc7262e72014-06-17 13:07:37 +0300906 u8 sec_level;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300907
908 BT_DBG("conn %p", conn);
909
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200910 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300911 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200912
Johan Hedberg40bef302014-07-16 11:42:27 +0300913 if (hcon->role != HCI_ROLE_MASTER)
Johan Hedberg86ca9ea2013-11-05 11:30:39 +0200914 return SMP_CMD_NOTSUPP;
915
Johan Hedbergc7262e72014-06-17 13:07:37 +0300916 sec_level = authreq_to_seclevel(rp->auth_req);
Johan Hedberg854f4722014-07-01 18:40:20 +0300917 if (smp_sufficient_security(hcon, sec_level))
918 return 0;
919
Johan Hedbergc7262e72014-06-17 13:07:37 +0300920 if (sec_level > hcon->pending_sec_level)
921 hcon->pending_sec_level = sec_level;
Vinicius Costa Gomesfeb45eb2011-08-25 20:02:35 -0300922
Johan Hedberg4dab7862012-06-07 14:58:37 +0800923 if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300924 return 0;
925
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200926 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300927 return 0;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300928
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300929 smp = smp_chan_create(conn);
Johan Hedbergc29d2442014-06-16 19:25:14 +0300930 if (!smp)
931 return SMP_UNSPECIFIED;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300932
Johan Hedbergb6ae8452014-07-30 09:22:22 +0300933 if (!test_bit(HCI_BONDABLE, &hcon->hdev->dev_flags) &&
Johan Hedberg616d55b2014-07-29 14:18:48 +0300934 (rp->auth_req & SMP_AUTH_BONDING))
935 return SMP_PAIRING_NOTSUPP;
936
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300937 skb_pull(skb, sizeof(*rp));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300938
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300939 memset(&cp, 0, sizeof(cp));
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300940 build_pairing_cmd(conn, &cp, NULL, rp->auth_req);
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300941
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300942 smp->preq[0] = SMP_CMD_PAIRING_REQ;
943 memcpy(&smp->preq[1], &cp, sizeof(cp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300944
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300945 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300946
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300947 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300948}
949
Vinicius Costa Gomescc110922012-08-23 21:32:43 -0300950int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300951{
Vinicius Costa Gomescc110922012-08-23 21:32:43 -0300952 struct l2cap_conn *conn = hcon->l2cap_data;
Johan Hedberg0a66cf22014-03-24 14:39:03 +0200953 struct smp_chan *smp;
Brian Gix2b64d152011-12-21 16:12:12 -0800954 __u8 authreq;
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300955
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -0300956 BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
957
Johan Hedberg0a66cf22014-03-24 14:39:03 +0200958 /* This may be NULL if there's an unexpected disconnection */
959 if (!conn)
960 return 1;
961
Johan Hedberg757aee02013-04-24 13:05:32 +0300962 if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags))
Andre Guedes2e65c9d2011-06-30 19:20:56 -0300963 return 1;
964
Johan Hedbergad32a2f2013-05-14 18:05:12 +0300965 if (smp_sufficient_security(hcon, sec_level))
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300966 return 1;
967
Johan Hedbergc7262e72014-06-17 13:07:37 +0300968 if (sec_level > hcon->pending_sec_level)
969 hcon->pending_sec_level = sec_level;
970
Johan Hedberg40bef302014-07-16 11:42:27 +0300971 if (hcon->role == HCI_ROLE_MASTER)
Johan Hedbergc7262e72014-06-17 13:07:37 +0300972 if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
973 return 0;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300974
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200975 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300976 return 0;
977
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300978 smp = smp_chan_create(conn);
Brian Gix2b64d152011-12-21 16:12:12 -0800979 if (!smp)
980 return 1;
981
982 authreq = seclevel_to_authreq(sec_level);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300983
Johan Hedberg79897d22014-06-01 09:45:24 +0300984 /* Require MITM if IO Capability allows or the security level
985 * requires it.
Johan Hedberg2e233642014-03-18 15:42:30 +0200986 */
Johan Hedberg79897d22014-06-01 09:45:24 +0300987 if (hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT ||
Johan Hedbergc7262e72014-06-17 13:07:37 +0300988 hcon->pending_sec_level > BT_SECURITY_MEDIUM)
Johan Hedberg2e233642014-03-18 15:42:30 +0200989 authreq |= SMP_AUTH_MITM;
990
Johan Hedberg40bef302014-07-16 11:42:27 +0300991 if (hcon->role == HCI_ROLE_MASTER) {
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300992 struct smp_cmd_pairing cp;
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300993
Brian Gix2b64d152011-12-21 16:12:12 -0800994 build_pairing_cmd(conn, &cp, NULL, authreq);
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300995 smp->preq[0] = SMP_CMD_PAIRING_REQ;
996 memcpy(&smp->preq[1], &cp, sizeof(cp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300997
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300998 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
999 } else {
1000 struct smp_cmd_security_req cp;
Brian Gix2b64d152011-12-21 16:12:12 -08001001 cp.auth_req = authreq;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001002 smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
1003 }
1004
Johan Hedberg4a74d652014-05-20 09:45:50 +03001005 set_bit(SMP_FLAG_INITIATOR, &smp->flags);
Johan Hedbergedca7922014-03-24 15:54:11 +02001006
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001007 return 0;
1008}
1009
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001010static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
1011{
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001012 struct smp_cmd_encrypt_info *rp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001013 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001014
Johan Hedbergc46b98b2014-02-18 10:19:29 +02001015 BT_DBG("conn %p", conn);
1016
1017 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001018 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +02001019
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001020 /* Ignore this PDU if it wasn't requested */
1021 if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
1022 return 0;
1023
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001024 skb_pull(skb, sizeof(*rp));
1025
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001026 memcpy(smp->tk, rp->ltk, sizeof(smp->tk));
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001027
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001028 return 0;
1029}
1030
1031static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
1032{
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001033 struct smp_cmd_master_ident *rp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001034 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001035 struct hci_dev *hdev = conn->hcon->hdev;
1036 struct hci_conn *hcon = conn->hcon;
Johan Hedberg23d0e122014-02-19 14:57:46 +02001037 struct smp_ltk *ltk;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001038 u8 authenticated;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001039
Johan Hedbergc46b98b2014-02-18 10:19:29 +02001040 BT_DBG("conn %p", conn);
1041
1042 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001043 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +02001044
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001045 /* Ignore this PDU if it wasn't requested */
1046 if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
1047 return 0;
1048
Johan Hedberg9747a9f2014-02-26 23:33:43 +02001049 /* Mark the information as received */
1050 smp->remote_key_dist &= ~SMP_DIST_ENC_KEY;
1051
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001052 skb_pull(skb, sizeof(*rp));
1053
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001054 hci_dev_lock(hdev);
Marcel Holtmannce39fb42013-10-13 02:23:39 -07001055 authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
Johan Hedberg2ceba532014-06-16 19:25:16 +03001056 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, SMP_LTK,
Johan Hedberg23d0e122014-02-19 14:57:46 +02001057 authenticated, smp->tk, smp->enc_key_size,
1058 rp->ediv, rp->rand);
1059 smp->ltk = ltk;
Johan Hedbergfd349c02014-02-18 10:19:36 +02001060 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001061 smp_distribute_keys(conn);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001062 hci_dev_unlock(hdev);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001063
1064 return 0;
1065}
1066
Johan Hedbergfd349c02014-02-18 10:19:36 +02001067static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
1068{
1069 struct smp_cmd_ident_info *info = (void *) skb->data;
1070 struct smp_chan *smp = conn->smp_chan;
1071
1072 BT_DBG("");
1073
1074 if (skb->len < sizeof(*info))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001075 return SMP_INVALID_PARAMS;
Johan Hedbergfd349c02014-02-18 10:19:36 +02001076
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001077 /* Ignore this PDU if it wasn't requested */
1078 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
1079 return 0;
1080
Johan Hedbergfd349c02014-02-18 10:19:36 +02001081 skb_pull(skb, sizeof(*info));
1082
1083 memcpy(smp->irk, info->irk, 16);
1084
1085 return 0;
1086}
1087
1088static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
1089 struct sk_buff *skb)
1090{
1091 struct smp_cmd_ident_addr_info *info = (void *) skb->data;
1092 struct smp_chan *smp = conn->smp_chan;
1093 struct hci_conn *hcon = conn->hcon;
1094 bdaddr_t rpa;
1095
1096 BT_DBG("");
1097
1098 if (skb->len < sizeof(*info))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001099 return SMP_INVALID_PARAMS;
Johan Hedbergfd349c02014-02-18 10:19:36 +02001100
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001101 /* Ignore this PDU if it wasn't requested */
1102 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
1103 return 0;
1104
Johan Hedberg9747a9f2014-02-26 23:33:43 +02001105 /* Mark the information as received */
1106 smp->remote_key_dist &= ~SMP_DIST_ID_KEY;
1107
Johan Hedbergfd349c02014-02-18 10:19:36 +02001108 skb_pull(skb, sizeof(*info));
1109
Johan Hedberg31dd6242014-06-27 14:23:02 +03001110 hci_dev_lock(hcon->hdev);
1111
Johan Hedberga9a58f82014-02-25 22:24:37 +02001112 /* Strictly speaking the Core Specification (4.1) allows sending
1113 * an empty address which would force us to rely on just the IRK
1114 * as "identity information". However, since such
1115 * implementations are not known of and in order to not over
1116 * complicate our implementation, simply pretend that we never
1117 * received an IRK for such a device.
1118 */
1119 if (!bacmp(&info->bdaddr, BDADDR_ANY)) {
1120 BT_ERR("Ignoring IRK with no identity address");
Johan Hedberg31dd6242014-06-27 14:23:02 +03001121 goto distribute;
Johan Hedberga9a58f82014-02-25 22:24:37 +02001122 }
1123
Johan Hedbergfd349c02014-02-18 10:19:36 +02001124 bacpy(&smp->id_addr, &info->bdaddr);
1125 smp->id_addr_type = info->addr_type;
1126
1127 if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type))
1128 bacpy(&rpa, &hcon->dst);
1129 else
1130 bacpy(&rpa, BDADDR_ANY);
1131
Johan Hedberg23d0e122014-02-19 14:57:46 +02001132 smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
1133 smp->id_addr_type, smp->irk, &rpa);
Johan Hedbergfd349c02014-02-18 10:19:36 +02001134
Johan Hedberg31dd6242014-06-27 14:23:02 +03001135distribute:
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001136 smp_distribute_keys(conn);
Johan Hedbergfd349c02014-02-18 10:19:36 +02001137
Johan Hedberg31dd6242014-06-27 14:23:02 +03001138 hci_dev_unlock(hcon->hdev);
1139
Johan Hedbergfd349c02014-02-18 10:19:36 +02001140 return 0;
1141}
1142
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001143static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)
1144{
1145 struct smp_cmd_sign_info *rp = (void *) skb->data;
1146 struct smp_chan *smp = conn->smp_chan;
1147 struct hci_dev *hdev = conn->hcon->hdev;
1148 struct smp_csrk *csrk;
1149
1150 BT_DBG("conn %p", conn);
1151
1152 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001153 return SMP_INVALID_PARAMS;
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001154
1155 /* Ignore this PDU if it wasn't requested */
1156 if (!(smp->remote_key_dist & SMP_DIST_SIGN))
1157 return 0;
1158
1159 /* Mark the information as received */
1160 smp->remote_key_dist &= ~SMP_DIST_SIGN;
1161
1162 skb_pull(skb, sizeof(*rp));
1163
1164 hci_dev_lock(hdev);
1165 csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
1166 if (csrk) {
1167 csrk->master = 0x01;
1168 memcpy(csrk->val, rp->csrk, sizeof(csrk->val));
1169 }
1170 smp->csrk = csrk;
1171 if (!(smp->remote_key_dist & SMP_DIST_SIGN))
1172 smp_distribute_keys(conn);
1173 hci_dev_unlock(hdev);
1174
1175 return 0;
1176}
1177
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001178int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
1179{
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001180 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann92381f52013-10-03 01:23:08 -07001181 __u8 code, reason;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001182 int err = 0;
1183
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001184 if (hcon->type != LE_LINK) {
1185 kfree_skb(skb);
Johan Hedberg34327112013-10-16 11:37:01 +03001186 return 0;
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001187 }
1188
Marcel Holtmann92381f52013-10-03 01:23:08 -07001189 if (skb->len < 1) {
1190 kfree_skb(skb);
1191 return -EILSEQ;
1192 }
1193
Marcel Holtmann06ae3312013-10-18 03:43:00 -07001194 if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) {
Johan Hedbergbeb19e42014-07-18 11:15:26 +03001195 err = -EOPNOTSUPP;
Andre Guedes2e65c9d2011-06-30 19:20:56 -03001196 reason = SMP_PAIRING_NOTSUPP;
1197 goto done;
1198 }
1199
Marcel Holtmann92381f52013-10-03 01:23:08 -07001200 code = skb->data[0];
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001201 skb_pull(skb, sizeof(code));
1202
Johan Hedberg8cf9fa12013-01-29 10:44:23 -06001203 /*
1204 * The SMP context must be initialized for all other PDUs except
1205 * pairing and security requests. If we get any other PDU when
1206 * not initialized simply disconnect (done if this function
1207 * returns an error).
1208 */
1209 if (code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ &&
1210 !conn->smp_chan) {
1211 BT_ERR("Unexpected SMP command 0x%02x. Disconnecting.", code);
1212 kfree_skb(skb);
Johan Hedbergbeb19e42014-07-18 11:15:26 +03001213 return -EOPNOTSUPP;
Johan Hedberg8cf9fa12013-01-29 10:44:23 -06001214 }
1215
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001216 switch (code) {
1217 case SMP_CMD_PAIRING_REQ:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001218 reason = smp_cmd_pairing_req(conn, skb);
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001219 break;
1220
1221 case SMP_CMD_PAIRING_FAIL:
Johan Hedberg84794e12013-11-06 11:24:57 +02001222 smp_failure(conn, 0);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001223 reason = 0;
1224 err = -EPERM;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001225 break;
1226
1227 case SMP_CMD_PAIRING_RSP:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001228 reason = smp_cmd_pairing_rsp(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001229 break;
1230
1231 case SMP_CMD_SECURITY_REQ:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001232 reason = smp_cmd_security_req(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001233 break;
1234
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001235 case SMP_CMD_PAIRING_CONFIRM:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001236 reason = smp_cmd_pairing_confirm(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001237 break;
1238
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001239 case SMP_CMD_PAIRING_RANDOM:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001240 reason = smp_cmd_pairing_random(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001241 break;
1242
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001243 case SMP_CMD_ENCRYPT_INFO:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001244 reason = smp_cmd_encrypt_info(conn, skb);
1245 break;
1246
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001247 case SMP_CMD_MASTER_IDENT:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001248 reason = smp_cmd_master_ident(conn, skb);
1249 break;
1250
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001251 case SMP_CMD_IDENT_INFO:
Johan Hedbergfd349c02014-02-18 10:19:36 +02001252 reason = smp_cmd_ident_info(conn, skb);
1253 break;
1254
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001255 case SMP_CMD_IDENT_ADDR_INFO:
Johan Hedbergfd349c02014-02-18 10:19:36 +02001256 reason = smp_cmd_ident_addr_info(conn, skb);
1257 break;
1258
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001259 case SMP_CMD_SIGN_INFO:
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001260 reason = smp_cmd_sign_info(conn, skb);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001261 break;
1262
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001263 default:
1264 BT_DBG("Unknown command code 0x%2.2x", code);
1265
1266 reason = SMP_CMD_NOTSUPP;
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -03001267 err = -EOPNOTSUPP;
1268 goto done;
1269 }
1270
1271done:
1272 if (reason)
Johan Hedberg84794e12013-11-06 11:24:57 +02001273 smp_failure(conn, reason);
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001274
1275 kfree_skb(skb);
1276 return err;
1277}
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001278
Johan Hedberg35d70272014-02-19 14:57:47 +02001279static void smp_notify_keys(struct l2cap_conn *conn)
1280{
1281 struct smp_chan *smp = conn->smp_chan;
1282 struct hci_conn *hcon = conn->hcon;
1283 struct hci_dev *hdev = hcon->hdev;
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001284 struct smp_cmd_pairing *req = (void *) &smp->preq[1];
1285 struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1];
1286 bool persistent;
Johan Hedberg35d70272014-02-19 14:57:47 +02001287
Johan Hedberg61b1a7f2014-03-20 12:54:16 +02001288 if (smp->remote_irk) {
Johan Hedberg95fbac82014-02-19 15:18:31 +02001289 mgmt_new_irk(hdev, smp->remote_irk);
Johan Hedberg61b1a7f2014-03-20 12:54:16 +02001290 /* Now that user space can be considered to know the
1291 * identity address track the connection based on it
1292 * from now on.
1293 */
1294 bacpy(&hcon->dst, &smp->remote_irk->bdaddr);
1295 hcon->dst_type = smp->remote_irk->addr_type;
1296 l2cap_conn_update_id_addr(hcon);
Marcel Holtmann66d8e832014-07-24 15:20:58 +02001297
1298 /* When receiving an indentity resolving key for
1299 * a remote device that does not use a resolvable
1300 * private address, just remove the key so that
1301 * it is possible to use the controller white
1302 * list for scanning.
1303 *
1304 * Userspace will have been told to not store
1305 * this key at this point. So it is safe to
1306 * just remove it.
1307 */
1308 if (!bacmp(&smp->remote_irk->rpa, BDADDR_ANY)) {
1309 list_del(&smp->remote_irk->list);
1310 kfree(smp->remote_irk);
1311 smp->remote_irk = NULL;
1312 }
Johan Hedberg61b1a7f2014-03-20 12:54:16 +02001313 }
Johan Hedberg95fbac82014-02-19 15:18:31 +02001314
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001315 /* The LTKs and CSRKs should be persistent only if both sides
1316 * had the bonding bit set in their authentication requests.
1317 */
1318 persistent = !!((req->auth_req & rsp->auth_req) & SMP_AUTH_BONDING);
1319
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001320 if (smp->csrk) {
1321 smp->csrk->bdaddr_type = hcon->dst_type;
1322 bacpy(&smp->csrk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001323 mgmt_new_csrk(hdev, smp->csrk, persistent);
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001324 }
1325
1326 if (smp->slave_csrk) {
1327 smp->slave_csrk->bdaddr_type = hcon->dst_type;
1328 bacpy(&smp->slave_csrk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001329 mgmt_new_csrk(hdev, smp->slave_csrk, persistent);
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001330 }
1331
Johan Hedberg35d70272014-02-19 14:57:47 +02001332 if (smp->ltk) {
1333 smp->ltk->bdaddr_type = hcon->dst_type;
1334 bacpy(&smp->ltk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001335 mgmt_new_ltk(hdev, smp->ltk, persistent);
Johan Hedberg35d70272014-02-19 14:57:47 +02001336 }
1337
1338 if (smp->slave_ltk) {
1339 smp->slave_ltk->bdaddr_type = hcon->dst_type;
1340 bacpy(&smp->slave_ltk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001341 mgmt_new_ltk(hdev, smp->slave_ltk, persistent);
Johan Hedberg35d70272014-02-19 14:57:47 +02001342 }
1343}
1344
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001345int smp_distribute_keys(struct l2cap_conn *conn)
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001346{
1347 struct smp_cmd_pairing *req, *rsp;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001348 struct smp_chan *smp = conn->smp_chan;
Johan Hedberg524237c2014-02-22 19:06:31 +02001349 struct hci_conn *hcon = conn->hcon;
1350 struct hci_dev *hdev = hcon->hdev;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001351 __u8 *keydist;
1352
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001353 BT_DBG("conn %p", conn);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001354
Johan Hedberg524237c2014-02-22 19:06:31 +02001355 if (!test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001356 return 0;
1357
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001358 rsp = (void *) &smp->prsp[1];
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001359
1360 /* The responder sends its keys first */
Johan Hedbergefabba32014-02-26 23:33:44 +02001361 if (hcon->out && (smp->remote_key_dist & 0x07))
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001362 return 0;
1363
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001364 req = (void *) &smp->preq[1];
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001365
Johan Hedberg524237c2014-02-22 19:06:31 +02001366 if (hcon->out) {
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001367 keydist = &rsp->init_key_dist;
1368 *keydist &= req->init_key_dist;
1369 } else {
1370 keydist = &rsp->resp_key_dist;
1371 *keydist &= req->resp_key_dist;
1372 }
1373
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001374 BT_DBG("keydist 0x%x", *keydist);
1375
1376 if (*keydist & SMP_DIST_ENC_KEY) {
1377 struct smp_cmd_encrypt_info enc;
1378 struct smp_cmd_master_ident ident;
Johan Hedberg23d0e122014-02-19 14:57:46 +02001379 struct smp_ltk *ltk;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001380 u8 authenticated;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001381 __le16 ediv;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001382 __le64 rand;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001383
1384 get_random_bytes(enc.ltk, sizeof(enc.ltk));
1385 get_random_bytes(&ediv, sizeof(ediv));
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001386 get_random_bytes(&rand, sizeof(rand));
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001387
1388 smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
1389
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001390 authenticated = hcon->sec_level == BT_SECURITY_HIGH;
Johan Hedberg524237c2014-02-22 19:06:31 +02001391 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type,
Johan Hedberg2ceba532014-06-16 19:25:16 +03001392 SMP_LTK_SLAVE, authenticated, enc.ltk,
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001393 smp->enc_key_size, ediv, rand);
Johan Hedberg23d0e122014-02-19 14:57:46 +02001394 smp->slave_ltk = ltk;
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001395
Andrei Emeltchenko58115372012-03-12 12:13:06 +02001396 ident.ediv = ediv;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001397 ident.rand = rand;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001398
1399 smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident);
1400
1401 *keydist &= ~SMP_DIST_ENC_KEY;
1402 }
1403
1404 if (*keydist & SMP_DIST_ID_KEY) {
1405 struct smp_cmd_ident_addr_info addrinfo;
1406 struct smp_cmd_ident_info idinfo;
1407
Johan Hedberg863efaf2014-02-22 19:06:32 +02001408 memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk));
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001409
1410 smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo);
1411
Johan Hedberg82d4b352014-02-23 19:42:18 +02001412 /* The hci_conn contains the local identity address
1413 * after the connection has been established.
1414 *
1415 * This is true even when the connection has been
1416 * established using a resolvable random address.
1417 */
Johan Hedberg524237c2014-02-22 19:06:31 +02001418 bacpy(&addrinfo.bdaddr, &hcon->src);
Johan Hedberg82d4b352014-02-23 19:42:18 +02001419 addrinfo.addr_type = hcon->src_type;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001420
1421 smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo),
Marcel Holtmannf1560462013-10-13 05:43:25 -07001422 &addrinfo);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001423
1424 *keydist &= ~SMP_DIST_ID_KEY;
1425 }
1426
1427 if (*keydist & SMP_DIST_SIGN) {
1428 struct smp_cmd_sign_info sign;
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001429 struct smp_csrk *csrk;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001430
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001431 /* Generate a new random key */
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001432 get_random_bytes(sign.csrk, sizeof(sign.csrk));
1433
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001434 csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
1435 if (csrk) {
1436 csrk->master = 0x00;
1437 memcpy(csrk->val, sign.csrk, sizeof(csrk->val));
1438 }
1439 smp->slave_csrk = csrk;
1440
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001441 smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign);
1442
1443 *keydist &= ~SMP_DIST_SIGN;
1444 }
1445
Johan Hedbergefabba32014-02-26 23:33:44 +02001446 /* If there are still keys to be received wait for them */
1447 if ((smp->remote_key_dist & 0x07))
1448 return 0;
1449
Johan Hedberg1d98bf42014-03-24 14:39:08 +02001450 clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags);
1451 cancel_delayed_work_sync(&conn->security_timer);
Johan Hedberg4a74d652014-05-20 09:45:50 +03001452 set_bit(SMP_FLAG_COMPLETE, &smp->flags);
Johan Hedberg1d98bf42014-03-24 14:39:08 +02001453 smp_notify_keys(conn);
Johan Hedbergefabba32014-02-26 23:33:44 +02001454
Johan Hedberg1d98bf42014-03-24 14:39:08 +02001455 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001456
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001457 return 0;
1458}