blob: 744f678ac3e8a9a7ea52607fbc7654f3a5f4da84 [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 void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
252{
Johan Hedberg5d88cc72014-08-08 09:37:18 +0300253 struct l2cap_chan *chan = conn->smp;
254 struct kvec iv[2];
255 struct msghdr msg;
256
257 if (!chan)
258 return;
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300259
260 BT_DBG("code 0x%2.2x", code);
261
Johan Hedberg5d88cc72014-08-08 09:37:18 +0300262 iv[0].iov_base = &code;
263 iv[0].iov_len = 1;
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300264
Johan Hedberg5d88cc72014-08-08 09:37:18 +0300265 iv[1].iov_base = data;
266 iv[1].iov_len = len;
267
268 memset(&msg, 0, sizeof(msg));
269
270 msg.msg_iov = (struct iovec *) &iv;
271 msg.msg_iovlen = 2;
272
273 l2cap_chan_send(chan, &msg, 1 + len);
Vinicius Costa Gomese2dcd112011-08-19 21:06:50 -0300274
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -0200275 cancel_delayed_work_sync(&conn->security_timer);
Marcel Holtmann17b02e62012-03-01 14:32:37 -0800276 schedule_delayed_work(&conn->security_timer, SMP_TIMEOUT);
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300277}
278
Brian Gix2b64d152011-12-21 16:12:12 -0800279static __u8 authreq_to_seclevel(__u8 authreq)
280{
281 if (authreq & SMP_AUTH_MITM)
282 return BT_SECURITY_HIGH;
283 else
284 return BT_SECURITY_MEDIUM;
285}
286
287static __u8 seclevel_to_authreq(__u8 sec_level)
288{
289 switch (sec_level) {
290 case BT_SECURITY_HIGH:
291 return SMP_AUTH_MITM | SMP_AUTH_BONDING;
292 case BT_SECURITY_MEDIUM:
293 return SMP_AUTH_BONDING;
294 default:
295 return SMP_AUTH_NONE;
296 }
297}
298
Vinicius Costa Gomesb8e66ea2011-06-09 18:50:52 -0300299static void build_pairing_cmd(struct l2cap_conn *conn,
Marcel Holtmannf1560462013-10-13 05:43:25 -0700300 struct smp_cmd_pairing *req,
301 struct smp_cmd_pairing *rsp, __u8 authreq)
Vinicius Costa Gomesb8e66ea2011-06-09 18:50:52 -0300302{
Johan Hedberg5d88cc72014-08-08 09:37:18 +0300303 struct l2cap_chan *chan = conn->smp;
304 struct smp_chan *smp = chan->data;
Johan Hedbergfd349c02014-02-18 10:19:36 +0200305 struct hci_conn *hcon = conn->hcon;
306 struct hci_dev *hdev = hcon->hdev;
307 u8 local_dist = 0, remote_dist = 0;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300308
Johan Hedbergb6ae8452014-07-30 09:22:22 +0300309 if (test_bit(HCI_BONDABLE, &conn->hcon->hdev->dev_flags)) {
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -0700310 local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
311 remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300312 authreq |= SMP_AUTH_BONDING;
Brian Gix2b64d152011-12-21 16:12:12 -0800313 } else {
314 authreq &= ~SMP_AUTH_BONDING;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300315 }
316
Johan Hedbergfd349c02014-02-18 10:19:36 +0200317 if (test_bit(HCI_RPA_RESOLVING, &hdev->dev_flags))
318 remote_dist |= SMP_DIST_ID_KEY;
319
Johan Hedberg863efaf2014-02-22 19:06:32 +0200320 if (test_bit(HCI_PRIVACY, &hdev->dev_flags))
321 local_dist |= SMP_DIST_ID_KEY;
322
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300323 if (rsp == NULL) {
324 req->io_capability = conn->hcon->io_capability;
325 req->oob_flag = SMP_OOB_NOT_PRESENT;
326 req->max_key_size = SMP_MAX_ENC_KEY_SIZE;
Johan Hedbergfd349c02014-02-18 10:19:36 +0200327 req->init_key_dist = local_dist;
328 req->resp_key_dist = remote_dist;
Johan Hedberg065a13e2012-10-11 16:26:06 +0200329 req->auth_req = (authreq & AUTH_REQ_MASK);
Johan Hedbergfd349c02014-02-18 10:19:36 +0200330
331 smp->remote_key_dist = remote_dist;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300332 return;
333 }
334
335 rsp->io_capability = conn->hcon->io_capability;
336 rsp->oob_flag = SMP_OOB_NOT_PRESENT;
337 rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE;
Johan Hedbergfd349c02014-02-18 10:19:36 +0200338 rsp->init_key_dist = req->init_key_dist & remote_dist;
339 rsp->resp_key_dist = req->resp_key_dist & local_dist;
Johan Hedberg065a13e2012-10-11 16:26:06 +0200340 rsp->auth_req = (authreq & AUTH_REQ_MASK);
Johan Hedbergfd349c02014-02-18 10:19:36 +0200341
342 smp->remote_key_dist = rsp->init_key_dist;
Vinicius Costa Gomesb8e66ea2011-06-09 18:50:52 -0300343}
344
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300345static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
346{
Johan Hedberg5d88cc72014-08-08 09:37:18 +0300347 struct l2cap_chan *chan = conn->smp;
348 struct smp_chan *smp = chan->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300349
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;
Johan Hedberg5d88cc72014-08-08 09:37:18 +0300408 struct l2cap_chan *chan = conn->smp;
409 struct smp_chan *smp = chan->data;
Brian Gix2b64d152011-12-21 16:12:12 -0800410 u8 method;
411 u32 passkey = 0;
412 int ret = 0;
413
414 /* Initialize key for JUST WORKS */
415 memset(smp->tk, 0, sizeof(smp->tk));
Johan Hedberg4a74d652014-05-20 09:45:50 +0300416 clear_bit(SMP_FLAG_TK_VALID, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800417
418 BT_DBG("tk_request: auth:%d lcl:%d rem:%d", auth, local_io, remote_io);
419
Johan Hedberg2bcd4002014-07-09 19:18:09 +0300420 /* If neither side wants MITM, either "just" confirm an incoming
421 * request or use just-works for outgoing ones. The JUST_CFM
422 * will be converted to JUST_WORKS if necessary later in this
423 * function. If either side has MITM look up the method from the
424 * table.
425 */
Johan Hedberg581370c2014-06-17 13:07:38 +0300426 if (!(auth & SMP_AUTH_MITM))
Johan Hedberg2bcd4002014-07-09 19:18:09 +0300427 method = JUST_CFM;
Brian Gix2b64d152011-12-21 16:12:12 -0800428 else
Johan Hedberg581370c2014-06-17 13:07:38 +0300429 method = get_auth_method(smp, local_io, remote_io);
Brian Gix2b64d152011-12-21 16:12:12 -0800430
Johan Hedberga82505c2014-03-24 14:39:07 +0200431 /* Don't confirm locally initiated pairing attempts */
Johan Hedberg4a74d652014-05-20 09:45:50 +0300432 if (method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR, &smp->flags))
Johan Hedberga82505c2014-03-24 14:39:07 +0200433 method = JUST_WORKS;
434
Johan Hedberg02f3e252014-07-16 15:09:13 +0300435 /* Don't bother user space with no IO capabilities */
436 if (method == JUST_CFM && hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
437 method = JUST_WORKS;
438
Brian Gix2b64d152011-12-21 16:12:12 -0800439 /* If Just Works, Continue with Zero TK */
440 if (method == JUST_WORKS) {
Johan Hedberg4a74d652014-05-20 09:45:50 +0300441 set_bit(SMP_FLAG_TK_VALID, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800442 return 0;
443 }
444
445 /* Not Just Works/Confirm results in MITM Authentication */
446 if (method != JUST_CFM)
Johan Hedberg4a74d652014-05-20 09:45:50 +0300447 set_bit(SMP_FLAG_MITM_AUTH, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800448
449 /* If both devices have Keyoard-Display I/O, the master
450 * Confirms and the slave Enters the passkey.
451 */
452 if (method == OVERLAP) {
Johan Hedberg40bef302014-07-16 11:42:27 +0300453 if (hcon->role == HCI_ROLE_MASTER)
Brian Gix2b64d152011-12-21 16:12:12 -0800454 method = CFM_PASSKEY;
455 else
456 method = REQ_PASSKEY;
457 }
458
Johan Hedberg01ad34d2014-03-19 14:14:53 +0200459 /* Generate random passkey. */
Brian Gix2b64d152011-12-21 16:12:12 -0800460 if (method == CFM_PASSKEY) {
Johan Hedberg943a7322014-03-18 12:58:24 +0200461 memset(smp->tk, 0, sizeof(smp->tk));
Brian Gix2b64d152011-12-21 16:12:12 -0800462 get_random_bytes(&passkey, sizeof(passkey));
463 passkey %= 1000000;
Johan Hedberg943a7322014-03-18 12:58:24 +0200464 put_unaligned_le32(passkey, smp->tk);
Brian Gix2b64d152011-12-21 16:12:12 -0800465 BT_DBG("PassKey: %d", passkey);
Johan Hedberg4a74d652014-05-20 09:45:50 +0300466 set_bit(SMP_FLAG_TK_VALID, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800467 }
468
469 hci_dev_lock(hcon->hdev);
470
471 if (method == REQ_PASSKEY)
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700472 ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200473 hcon->type, hcon->dst_type);
Johan Hedberg4eb65e62014-03-24 14:39:05 +0200474 else if (method == JUST_CFM)
475 ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
476 hcon->type, hcon->dst_type,
477 passkey, 1);
Brian Gix2b64d152011-12-21 16:12:12 -0800478 else
Johan Hedberg01ad34d2014-03-19 14:14:53 +0200479 ret = mgmt_user_passkey_notify(hcon->hdev, &hcon->dst,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200480 hcon->type, hcon->dst_type,
Johan Hedberg39adbff2014-03-20 08:18:14 +0200481 passkey, 0);
Brian Gix2b64d152011-12-21 16:12:12 -0800482
483 hci_dev_unlock(hcon->hdev);
484
485 return ret;
486}
487
Johan Hedberg1cc61142014-05-20 09:45:52 +0300488static u8 smp_confirm(struct smp_chan *smp)
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300489{
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300490 struct l2cap_conn *conn = smp->conn;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300491 struct smp_cmd_pairing_confirm cp;
492 int ret;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300493
494 BT_DBG("conn %p", conn);
495
Johan Hedbergec70f362014-06-27 14:23:04 +0300496 ret = smp_c1(smp, smp->tk, smp->prnd, smp->preq, smp->prsp,
Johan Hedbergb1cd5fd2014-02-28 12:54:17 +0200497 conn->hcon->init_addr_type, &conn->hcon->init_addr,
Johan Hedberg943a7322014-03-18 12:58:24 +0200498 conn->hcon->resp_addr_type, &conn->hcon->resp_addr,
499 cp.confirm_val);
Johan Hedberg1cc61142014-05-20 09:45:52 +0300500 if (ret)
501 return SMP_UNSPECIFIED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300502
Johan Hedberg4a74d652014-05-20 09:45:50 +0300503 clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800504
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300505 smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
506
Johan Hedberg1cc61142014-05-20 09:45:52 +0300507 return 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300508}
509
Johan Hedberg861580a2014-05-20 09:45:51 +0300510static u8 smp_random(struct smp_chan *smp)
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300511{
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300512 struct l2cap_conn *conn = smp->conn;
513 struct hci_conn *hcon = conn->hcon;
Johan Hedberg861580a2014-05-20 09:45:51 +0300514 u8 confirm[16];
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300515 int ret;
516
Johan Hedbergec70f362014-06-27 14:23:04 +0300517 if (IS_ERR_OR_NULL(smp->tfm_aes))
Johan Hedberg861580a2014-05-20 09:45:51 +0300518 return SMP_UNSPECIFIED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300519
520 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
521
Johan Hedbergec70f362014-06-27 14:23:04 +0300522 ret = smp_c1(smp, smp->tk, smp->rrnd, smp->preq, smp->prsp,
Johan Hedbergb1cd5fd2014-02-28 12:54:17 +0200523 hcon->init_addr_type, &hcon->init_addr,
Johan Hedberg943a7322014-03-18 12:58:24 +0200524 hcon->resp_addr_type, &hcon->resp_addr, confirm);
Johan Hedberg861580a2014-05-20 09:45:51 +0300525 if (ret)
526 return SMP_UNSPECIFIED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300527
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300528 if (memcmp(smp->pcnf, confirm, sizeof(smp->pcnf)) != 0) {
529 BT_ERR("Pairing failed (confirmation values mismatch)");
Johan Hedberg861580a2014-05-20 09:45:51 +0300530 return SMP_CONFIRM_FAILED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300531 }
532
533 if (hcon->out) {
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -0800534 u8 stk[16];
535 __le64 rand = 0;
536 __le16 ediv = 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300537
Johan Hedbergec70f362014-06-27 14:23:04 +0300538 smp_s1(smp, smp->tk, smp->rrnd, smp->prnd, stk);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300539
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300540 memset(stk + smp->enc_key_size, 0,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300541 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300542
Johan Hedberg861580a2014-05-20 09:45:51 +0300543 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
544 return SMP_UNSPECIFIED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300545
546 hci_le_start_enc(hcon, ediv, rand, stk);
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300547 hcon->enc_key_size = smp->enc_key_size;
Johan Hedbergfe59a052014-07-01 19:14:12 +0300548 set_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300549 } else {
Johan Hedbergfff34902014-06-10 15:19:50 +0300550 u8 stk[16], auth;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -0800551 __le64 rand = 0;
552 __le16 ediv = 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300553
Johan Hedberg943a7322014-03-18 12:58:24 +0200554 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
555 smp->prnd);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300556
Johan Hedbergec70f362014-06-27 14:23:04 +0300557 smp_s1(smp, smp->tk, smp->prnd, smp->rrnd, stk);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300558
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300559 memset(stk + smp->enc_key_size, 0,
Marcel Holtmannf1560462013-10-13 05:43:25 -0700560 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300561
Johan Hedbergfff34902014-06-10 15:19:50 +0300562 if (hcon->pending_sec_level == BT_SECURITY_HIGH)
563 auth = 1;
564 else
565 auth = 0;
566
Johan Hedberg7d5843b2014-06-16 19:25:15 +0300567 /* Even though there's no _SLAVE suffix this is the
568 * slave STK we're adding for later lookup (the master
569 * STK never needs to be stored).
570 */
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700571 hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
Johan Hedberg2ceba532014-06-16 19:25:16 +0300572 SMP_STK, auth, stk, smp->enc_key_size, ediv, rand);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300573 }
574
Johan Hedberg861580a2014-05-20 09:45:51 +0300575 return 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300576}
577
578static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
579{
Johan Hedberg5d88cc72014-08-08 09:37:18 +0300580 struct l2cap_chan *chan = conn->smp;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300581 struct smp_chan *smp;
582
Marcel Holtmannf1560462013-10-13 05:43:25 -0700583 smp = kzalloc(sizeof(*smp), GFP_ATOMIC);
Johan Hedberg616d55b2014-07-29 14:18:48 +0300584 if (!smp) {
585 clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300586 return NULL;
Johan Hedberg616d55b2014-07-29 14:18:48 +0300587 }
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300588
Johan Hedberg6a7bd102014-06-27 14:23:03 +0300589 smp->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
590 if (IS_ERR(smp->tfm_aes)) {
591 BT_ERR("Unable to create ECB crypto context");
592 kfree(smp);
Johan Hedberg616d55b2014-07-29 14:18:48 +0300593 clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags);
Johan Hedberg6a7bd102014-06-27 14:23:03 +0300594 return NULL;
595 }
596
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300597 smp->conn = conn;
Johan Hedberg5d88cc72014-08-08 09:37:18 +0300598 chan->data = smp;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300599
600 hci_conn_hold(conn->hcon);
601
602 return smp;
603}
604
605void smp_chan_destroy(struct l2cap_conn *conn)
606{
Johan Hedberg5d88cc72014-08-08 09:37:18 +0300607 struct l2cap_chan *chan = conn->smp;
608 struct smp_chan *smp = chan->data;
Johan Hedbergf4a407b2014-02-18 21:41:34 +0200609 bool complete;
Brian Gixc8eb9692011-11-23 08:28:35 -0800610
Vinicius Costa Gomesf1c09c02012-02-01 18:27:56 -0300611 BUG_ON(!smp);
Brian Gixc8eb9692011-11-23 08:28:35 -0800612
Johan Hedberg4a74d652014-05-20 09:45:50 +0300613 complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags);
Johan Hedbergf4a407b2014-02-18 21:41:34 +0200614 mgmt_smp_complete(conn->hcon, complete);
615
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -0700616 kfree(smp->csrk);
617 kfree(smp->slave_csrk);
618
Johan Hedberg6a7bd102014-06-27 14:23:03 +0300619 crypto_free_blkcipher(smp->tfm_aes);
620
Johan Hedberg759331d2014-02-28 10:10:16 +0200621 /* If pairing failed clean up any keys we might have */
622 if (!complete) {
623 if (smp->ltk) {
624 list_del(&smp->ltk->list);
625 kfree(smp->ltk);
626 }
627
628 if (smp->slave_ltk) {
629 list_del(&smp->slave_ltk->list);
630 kfree(smp->slave_ltk);
631 }
632
633 if (smp->remote_irk) {
634 list_del(&smp->remote_irk->list);
635 kfree(smp->remote_irk);
636 }
637 }
638
Johan Hedberg5d88cc72014-08-08 09:37:18 +0300639 chan->data = NULL;
Brian Gixc8eb9692011-11-23 08:28:35 -0800640 kfree(smp);
David Herrmann76a68ba2013-04-06 20:28:37 +0200641 hci_conn_drop(conn->hcon);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300642}
643
Brian Gix2b64d152011-12-21 16:12:12 -0800644int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
645{
Johan Hedbergb10e8012014-06-27 14:23:07 +0300646 struct l2cap_conn *conn = hcon->l2cap_data;
Johan Hedberg5d88cc72014-08-08 09:37:18 +0300647 struct l2cap_chan *chan;
Brian Gix2b64d152011-12-21 16:12:12 -0800648 struct smp_chan *smp;
649 u32 value;
Brian Gix2b64d152011-12-21 16:12:12 -0800650
651 BT_DBG("");
652
Johan Hedberg642ac772014-06-27 14:23:06 +0300653 if (!conn || !test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Brian Gix2b64d152011-12-21 16:12:12 -0800654 return -ENOTCONN;
655
Johan Hedberg5d88cc72014-08-08 09:37:18 +0300656 chan = conn->smp;
657 if (!chan)
658 return -ENOTCONN;
659
660 smp = chan->data;
Brian Gix2b64d152011-12-21 16:12:12 -0800661
662 switch (mgmt_op) {
663 case MGMT_OP_USER_PASSKEY_REPLY:
664 value = le32_to_cpu(passkey);
Johan Hedberg943a7322014-03-18 12:58:24 +0200665 memset(smp->tk, 0, sizeof(smp->tk));
Brian Gix2b64d152011-12-21 16:12:12 -0800666 BT_DBG("PassKey: %d", value);
Johan Hedberg943a7322014-03-18 12:58:24 +0200667 put_unaligned_le32(value, smp->tk);
Brian Gix2b64d152011-12-21 16:12:12 -0800668 /* Fall Through */
669 case MGMT_OP_USER_CONFIRM_REPLY:
Johan Hedberg4a74d652014-05-20 09:45:50 +0300670 set_bit(SMP_FLAG_TK_VALID, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800671 break;
672 case MGMT_OP_USER_PASSKEY_NEG_REPLY:
673 case MGMT_OP_USER_CONFIRM_NEG_REPLY:
Johan Hedberg84794e12013-11-06 11:24:57 +0200674 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
Brian Gix2b64d152011-12-21 16:12:12 -0800675 return 0;
676 default:
Johan Hedberg84794e12013-11-06 11:24:57 +0200677 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
Brian Gix2b64d152011-12-21 16:12:12 -0800678 return -EOPNOTSUPP;
679 }
680
681 /* If it is our turn to send Pairing Confirm, do so now */
Johan Hedberg1cc61142014-05-20 09:45:52 +0300682 if (test_bit(SMP_FLAG_CFM_PENDING, &smp->flags)) {
683 u8 rsp = smp_confirm(smp);
684 if (rsp)
685 smp_failure(conn, rsp);
686 }
Brian Gix2b64d152011-12-21 16:12:12 -0800687
688 return 0;
689}
690
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300691static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300692{
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300693 struct smp_cmd_pairing rsp, *req = (void *) skb->data;
Johan Hedbergb3c64102014-07-10 11:02:07 +0300694 struct hci_dev *hdev = conn->hcon->hdev;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300695 struct smp_chan *smp;
Johan Hedbergc7262e72014-06-17 13:07:37 +0300696 u8 key_size, auth, sec_level;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300697 int ret;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300698
699 BT_DBG("conn %p", conn);
700
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200701 if (skb->len < sizeof(*req))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300702 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200703
Johan Hedberg40bef302014-07-16 11:42:27 +0300704 if (conn->hcon->role != HCI_ROLE_SLAVE)
Brian Gix2b64d152011-12-21 16:12:12 -0800705 return SMP_CMD_NOTSUPP;
706
Johan Hedberg5d88cc72014-08-08 09:37:18 +0300707 if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300708 smp = smp_chan_create(conn);
Johan Hedberg5d88cc72014-08-08 09:37:18 +0300709 } else {
710 struct l2cap_chan *chan = conn->smp;
711 smp = chan->data;
712 }
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300713
Andrei Emeltchenkod08fd0e2012-07-19 17:03:43 +0300714 if (!smp)
715 return SMP_UNSPECIFIED;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300716
Johan Hedbergb6ae8452014-07-30 09:22:22 +0300717 if (!test_bit(HCI_BONDABLE, &hdev->dev_flags) &&
Johan Hedbergb3c64102014-07-10 11:02:07 +0300718 (req->auth_req & SMP_AUTH_BONDING))
719 return SMP_PAIRING_NOTSUPP;
720
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300721 smp->preq[0] = SMP_CMD_PAIRING_REQ;
722 memcpy(&smp->preq[1], req, sizeof(*req));
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300723 skb_pull(skb, sizeof(*req));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300724
Brian Gix2b64d152011-12-21 16:12:12 -0800725 /* We didn't start the pairing, so match remote */
Johan Hedberg1ef35822014-05-20 09:45:48 +0300726 auth = req->auth_req;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300727
Johan Hedbergc7262e72014-06-17 13:07:37 +0300728 sec_level = authreq_to_seclevel(auth);
729 if (sec_level > conn->hcon->pending_sec_level)
730 conn->hcon->pending_sec_level = sec_level;
Ido Yarivfdde0a22012-03-05 20:09:38 +0200731
Johan Hedberg2ed8f652014-06-17 13:07:39 +0300732 /* If we need MITM check that it can be acheived */
733 if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
734 u8 method;
735
736 method = get_auth_method(smp, conn->hcon->io_capability,
737 req->io_capability);
738 if (method == JUST_WORKS || method == JUST_CFM)
739 return SMP_AUTH_REQUIREMENTS;
740 }
741
Brian Gix2b64d152011-12-21 16:12:12 -0800742 build_pairing_cmd(conn, req, &rsp, auth);
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300743
744 key_size = min(req->max_key_size, rsp.max_key_size);
745 if (check_enc_key_size(conn, key_size))
746 return SMP_ENC_KEY_SIZE;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300747
Johan Hedberge84a6b12013-12-02 10:49:03 +0200748 get_random_bytes(smp->prnd, sizeof(smp->prnd));
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300749
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300750 smp->prsp[0] = SMP_CMD_PAIRING_RSP;
751 memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300752
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300753 smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300754
Brian Gix2b64d152011-12-21 16:12:12 -0800755 /* Request setup of TK */
756 ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability);
757 if (ret)
758 return SMP_UNSPECIFIED;
759
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300760 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300761}
762
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300763static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300764{
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300765 struct smp_cmd_pairing *req, *rsp = (void *) skb->data;
Johan Hedberg5d88cc72014-08-08 09:37:18 +0300766 struct l2cap_chan *chan = conn->smp;
767 struct smp_chan *smp = chan->data;
Brian Gix2b64d152011-12-21 16:12:12 -0800768 u8 key_size, auth = SMP_AUTH_NONE;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300769 int ret;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300770
771 BT_DBG("conn %p", conn);
772
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200773 if (skb->len < sizeof(*rsp))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300774 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200775
Johan Hedberg40bef302014-07-16 11:42:27 +0300776 if (conn->hcon->role != HCI_ROLE_MASTER)
Brian Gix2b64d152011-12-21 16:12:12 -0800777 return SMP_CMD_NOTSUPP;
778
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300779 skb_pull(skb, sizeof(*rsp));
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300780
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300781 req = (void *) &smp->preq[1];
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300782
783 key_size = min(req->max_key_size, rsp->max_key_size);
784 if (check_enc_key_size(conn, key_size))
785 return SMP_ENC_KEY_SIZE;
786
Johan Hedberg2ed8f652014-06-17 13:07:39 +0300787 /* If we need MITM check that it can be acheived */
788 if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
789 u8 method;
790
791 method = get_auth_method(smp, req->io_capability,
792 rsp->io_capability);
793 if (method == JUST_WORKS || method == JUST_CFM)
794 return SMP_AUTH_REQUIREMENTS;
795 }
796
Johan Hedberge84a6b12013-12-02 10:49:03 +0200797 get_random_bytes(smp->prnd, sizeof(smp->prnd));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300798
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300799 smp->prsp[0] = SMP_CMD_PAIRING_RSP;
800 memcpy(&smp->prsp[1], rsp, sizeof(*rsp));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300801
Johan Hedbergfdcc4be2014-03-14 10:53:50 +0200802 /* Update remote key distribution in case the remote cleared
803 * some bits that we had enabled in our request.
804 */
805 smp->remote_key_dist &= rsp->resp_key_dist;
806
Brian Gix2b64d152011-12-21 16:12:12 -0800807 if ((req->auth_req & SMP_AUTH_BONDING) &&
Marcel Holtmannf1560462013-10-13 05:43:25 -0700808 (rsp->auth_req & SMP_AUTH_BONDING))
Brian Gix2b64d152011-12-21 16:12:12 -0800809 auth = SMP_AUTH_BONDING;
810
811 auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM;
812
Johan Hedberg476585e2012-06-06 18:54:15 +0800813 ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability);
Brian Gix2b64d152011-12-21 16:12:12 -0800814 if (ret)
815 return SMP_UNSPECIFIED;
816
Johan Hedberg4a74d652014-05-20 09:45:50 +0300817 set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800818
819 /* Can't compose response until we have been confirmed */
Johan Hedberg4a74d652014-05-20 09:45:50 +0300820 if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
Johan Hedberg1cc61142014-05-20 09:45:52 +0300821 return smp_confirm(smp);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300822
823 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300824}
825
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300826static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300827{
Johan Hedberg5d88cc72014-08-08 09:37:18 +0300828 struct l2cap_chan *chan = conn->smp;
829 struct smp_chan *smp = chan->data;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300830
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300831 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
832
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200833 if (skb->len < sizeof(smp->pcnf))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300834 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200835
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300836 memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf));
837 skb_pull(skb, sizeof(smp->pcnf));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300838
Johan Hedberg943a7322014-03-18 12:58:24 +0200839 if (conn->hcon->out)
840 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
841 smp->prnd);
Johan Hedberg4a74d652014-05-20 09:45:50 +0300842 else if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
Johan Hedberg1cc61142014-05-20 09:45:52 +0300843 return smp_confirm(smp);
Johan Hedberg943a7322014-03-18 12:58:24 +0200844 else
Johan Hedberg4a74d652014-05-20 09:45:50 +0300845 set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300846
847 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300848}
849
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300850static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300851{
Johan Hedberg5d88cc72014-08-08 09:37:18 +0300852 struct l2cap_chan *chan = conn->smp;
853 struct smp_chan *smp = chan->data;
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 Hedberg616d55b2014-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;
Johan Hedberg5d88cc72014-08-08 09:37:18 +03001026 struct l2cap_chan *chan = conn->smp;
1027 struct smp_chan *smp = chan->data;
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001028
Johan Hedbergc46b98b2014-02-18 10:19:29 +02001029 BT_DBG("conn %p", conn);
1030
1031 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001032 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +02001033
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001034 /* Ignore this PDU if it wasn't requested */
1035 if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
1036 return 0;
1037
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001038 skb_pull(skb, sizeof(*rp));
1039
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001040 memcpy(smp->tk, rp->ltk, sizeof(smp->tk));
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001041
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001042 return 0;
1043}
1044
1045static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
1046{
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001047 struct smp_cmd_master_ident *rp = (void *) skb->data;
Johan Hedberg5d88cc72014-08-08 09:37:18 +03001048 struct l2cap_chan *chan = conn->smp;
1049 struct smp_chan *smp = chan->data;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001050 struct hci_dev *hdev = conn->hcon->hdev;
1051 struct hci_conn *hcon = conn->hcon;
Johan Hedberg23d0e122014-02-19 14:57:46 +02001052 struct smp_ltk *ltk;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001053 u8 authenticated;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001054
Johan Hedbergc46b98b2014-02-18 10:19:29 +02001055 BT_DBG("conn %p", conn);
1056
1057 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001058 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +02001059
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001060 /* Ignore this PDU if it wasn't requested */
1061 if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
1062 return 0;
1063
Johan Hedberg9747a9f2014-02-26 23:33:43 +02001064 /* Mark the information as received */
1065 smp->remote_key_dist &= ~SMP_DIST_ENC_KEY;
1066
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001067 skb_pull(skb, sizeof(*rp));
1068
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001069 hci_dev_lock(hdev);
Marcel Holtmannce39fb42013-10-13 02:23:39 -07001070 authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
Johan Hedberg2ceba532014-06-16 19:25:16 +03001071 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, SMP_LTK,
Johan Hedberg23d0e122014-02-19 14:57:46 +02001072 authenticated, smp->tk, smp->enc_key_size,
1073 rp->ediv, rp->rand);
1074 smp->ltk = ltk;
Johan Hedbergfd349c02014-02-18 10:19:36 +02001075 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001076 smp_distribute_keys(conn);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001077 hci_dev_unlock(hdev);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001078
1079 return 0;
1080}
1081
Johan Hedbergfd349c02014-02-18 10:19:36 +02001082static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
1083{
1084 struct smp_cmd_ident_info *info = (void *) skb->data;
Johan Hedberg5d88cc72014-08-08 09:37:18 +03001085 struct l2cap_chan *chan = conn->smp;
1086 struct smp_chan *smp = chan->data;
Johan Hedbergfd349c02014-02-18 10:19:36 +02001087
1088 BT_DBG("");
1089
1090 if (skb->len < sizeof(*info))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001091 return SMP_INVALID_PARAMS;
Johan Hedbergfd349c02014-02-18 10:19:36 +02001092
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001093 /* Ignore this PDU if it wasn't requested */
1094 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
1095 return 0;
1096
Johan Hedbergfd349c02014-02-18 10:19:36 +02001097 skb_pull(skb, sizeof(*info));
1098
1099 memcpy(smp->irk, info->irk, 16);
1100
1101 return 0;
1102}
1103
1104static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
1105 struct sk_buff *skb)
1106{
1107 struct smp_cmd_ident_addr_info *info = (void *) skb->data;
Johan Hedberg5d88cc72014-08-08 09:37:18 +03001108 struct l2cap_chan *chan = conn->smp;
1109 struct smp_chan *smp = chan->data;
Johan Hedbergfd349c02014-02-18 10:19:36 +02001110 struct hci_conn *hcon = conn->hcon;
1111 bdaddr_t rpa;
1112
1113 BT_DBG("");
1114
1115 if (skb->len < sizeof(*info))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001116 return SMP_INVALID_PARAMS;
Johan Hedbergfd349c02014-02-18 10:19:36 +02001117
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001118 /* Ignore this PDU if it wasn't requested */
1119 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
1120 return 0;
1121
Johan Hedberg9747a9f2014-02-26 23:33:43 +02001122 /* Mark the information as received */
1123 smp->remote_key_dist &= ~SMP_DIST_ID_KEY;
1124
Johan Hedbergfd349c02014-02-18 10:19:36 +02001125 skb_pull(skb, sizeof(*info));
1126
Johan Hedberg31dd6242014-06-27 14:23:02 +03001127 hci_dev_lock(hcon->hdev);
1128
Johan Hedberga9a58f82014-02-25 22:24:37 +02001129 /* Strictly speaking the Core Specification (4.1) allows sending
1130 * an empty address which would force us to rely on just the IRK
1131 * as "identity information". However, since such
1132 * implementations are not known of and in order to not over
1133 * complicate our implementation, simply pretend that we never
1134 * received an IRK for such a device.
1135 */
1136 if (!bacmp(&info->bdaddr, BDADDR_ANY)) {
1137 BT_ERR("Ignoring IRK with no identity address");
Johan Hedberg31dd6242014-06-27 14:23:02 +03001138 goto distribute;
Johan Hedberga9a58f82014-02-25 22:24:37 +02001139 }
1140
Johan Hedbergfd349c02014-02-18 10:19:36 +02001141 bacpy(&smp->id_addr, &info->bdaddr);
1142 smp->id_addr_type = info->addr_type;
1143
1144 if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type))
1145 bacpy(&rpa, &hcon->dst);
1146 else
1147 bacpy(&rpa, BDADDR_ANY);
1148
Johan Hedberg23d0e122014-02-19 14:57:46 +02001149 smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
1150 smp->id_addr_type, smp->irk, &rpa);
Johan Hedbergfd349c02014-02-18 10:19:36 +02001151
Johan Hedberg31dd6242014-06-27 14:23:02 +03001152distribute:
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001153 smp_distribute_keys(conn);
Johan Hedbergfd349c02014-02-18 10:19:36 +02001154
Johan Hedberg31dd6242014-06-27 14:23:02 +03001155 hci_dev_unlock(hcon->hdev);
1156
Johan Hedbergfd349c02014-02-18 10:19:36 +02001157 return 0;
1158}
1159
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001160static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)
1161{
1162 struct smp_cmd_sign_info *rp = (void *) skb->data;
Johan Hedberg5d88cc72014-08-08 09:37:18 +03001163 struct l2cap_chan *chan = conn->smp;
1164 struct smp_chan *smp = chan->data;
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001165 struct hci_dev *hdev = conn->hcon->hdev;
1166 struct smp_csrk *csrk;
1167
1168 BT_DBG("conn %p", conn);
1169
1170 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001171 return SMP_INVALID_PARAMS;
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001172
1173 /* Ignore this PDU if it wasn't requested */
1174 if (!(smp->remote_key_dist & SMP_DIST_SIGN))
1175 return 0;
1176
1177 /* Mark the information as received */
1178 smp->remote_key_dist &= ~SMP_DIST_SIGN;
1179
1180 skb_pull(skb, sizeof(*rp));
1181
1182 hci_dev_lock(hdev);
1183 csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
1184 if (csrk) {
1185 csrk->master = 0x01;
1186 memcpy(csrk->val, rp->csrk, sizeof(csrk->val));
1187 }
1188 smp->csrk = csrk;
Johan Hedberg5fcb9342014-08-07 10:03:31 +03001189 smp_distribute_keys(conn);
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001190 hci_dev_unlock(hdev);
1191
1192 return 0;
1193}
1194
Johan Hedberg5d88cc72014-08-08 09:37:18 +03001195static int smp_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001196{
Johan Hedberg5d88cc72014-08-08 09:37:18 +03001197 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001198 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann92381f52013-10-03 01:23:08 -07001199 __u8 code, reason;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001200 int err = 0;
1201
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001202 if (hcon->type != LE_LINK) {
1203 kfree_skb(skb);
Johan Hedberg34327112013-10-16 11:37:01 +03001204 return 0;
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001205 }
1206
Marcel Holtmann92381f52013-10-03 01:23:08 -07001207 if (skb->len < 1) {
1208 kfree_skb(skb);
1209 return -EILSEQ;
1210 }
1211
Marcel Holtmann06ae3312013-10-18 03:43:00 -07001212 if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) {
Johan Hedbergbeb19e42014-07-18 11:15:26 +03001213 err = -EOPNOTSUPP;
Andre Guedes2e65c9d2011-06-30 19:20:56 -03001214 reason = SMP_PAIRING_NOTSUPP;
1215 goto done;
1216 }
1217
Marcel Holtmann92381f52013-10-03 01:23:08 -07001218 code = skb->data[0];
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001219 skb_pull(skb, sizeof(code));
1220
Johan Hedberg8cf9fa12013-01-29 10:44:23 -06001221 /*
1222 * The SMP context must be initialized for all other PDUs except
1223 * pairing and security requests. If we get any other PDU when
1224 * not initialized simply disconnect (done if this function
1225 * returns an error).
1226 */
1227 if (code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ &&
Johan Hedbergd3368602014-08-08 09:28:05 +03001228 !test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Johan Hedberg8cf9fa12013-01-29 10:44:23 -06001229 BT_ERR("Unexpected SMP command 0x%02x. Disconnecting.", code);
1230 kfree_skb(skb);
Johan Hedbergbeb19e42014-07-18 11:15:26 +03001231 return -EOPNOTSUPP;
Johan Hedberg8cf9fa12013-01-29 10:44:23 -06001232 }
1233
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001234 switch (code) {
1235 case SMP_CMD_PAIRING_REQ:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001236 reason = smp_cmd_pairing_req(conn, skb);
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001237 break;
1238
1239 case SMP_CMD_PAIRING_FAIL:
Johan Hedberg84794e12013-11-06 11:24:57 +02001240 smp_failure(conn, 0);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001241 reason = 0;
1242 err = -EPERM;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001243 break;
1244
1245 case SMP_CMD_PAIRING_RSP:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001246 reason = smp_cmd_pairing_rsp(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001247 break;
1248
1249 case SMP_CMD_SECURITY_REQ:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001250 reason = smp_cmd_security_req(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001251 break;
1252
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001253 case SMP_CMD_PAIRING_CONFIRM:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001254 reason = smp_cmd_pairing_confirm(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001255 break;
1256
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001257 case SMP_CMD_PAIRING_RANDOM:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001258 reason = smp_cmd_pairing_random(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001259 break;
1260
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001261 case SMP_CMD_ENCRYPT_INFO:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001262 reason = smp_cmd_encrypt_info(conn, skb);
1263 break;
1264
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001265 case SMP_CMD_MASTER_IDENT:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001266 reason = smp_cmd_master_ident(conn, skb);
1267 break;
1268
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001269 case SMP_CMD_IDENT_INFO:
Johan Hedbergfd349c02014-02-18 10:19:36 +02001270 reason = smp_cmd_ident_info(conn, skb);
1271 break;
1272
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001273 case SMP_CMD_IDENT_ADDR_INFO:
Johan Hedbergfd349c02014-02-18 10:19:36 +02001274 reason = smp_cmd_ident_addr_info(conn, skb);
1275 break;
1276
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001277 case SMP_CMD_SIGN_INFO:
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001278 reason = smp_cmd_sign_info(conn, skb);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001279 break;
1280
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001281 default:
1282 BT_DBG("Unknown command code 0x%2.2x", code);
1283
1284 reason = SMP_CMD_NOTSUPP;
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -03001285 err = -EOPNOTSUPP;
1286 goto done;
1287 }
1288
1289done:
1290 if (reason)
Johan Hedberg84794e12013-11-06 11:24:57 +02001291 smp_failure(conn, reason);
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001292
1293 kfree_skb(skb);
1294 return err;
1295}
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001296
Johan Hedberg35d70272014-02-19 14:57:47 +02001297static void smp_notify_keys(struct l2cap_conn *conn)
1298{
Johan Hedberg5d88cc72014-08-08 09:37:18 +03001299 struct l2cap_chan *chan = conn->smp;
1300 struct smp_chan *smp = chan->data;
Johan Hedberg35d70272014-02-19 14:57:47 +02001301 struct hci_conn *hcon = conn->hcon;
1302 struct hci_dev *hdev = hcon->hdev;
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001303 struct smp_cmd_pairing *req = (void *) &smp->preq[1];
1304 struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1];
1305 bool persistent;
Johan Hedberg35d70272014-02-19 14:57:47 +02001306
Johan Hedberg61b1a7f2014-03-20 12:54:16 +02001307 if (smp->remote_irk) {
Johan Hedberg95fbac82014-02-19 15:18:31 +02001308 mgmt_new_irk(hdev, smp->remote_irk);
Johan Hedberg61b1a7f2014-03-20 12:54:16 +02001309 /* Now that user space can be considered to know the
1310 * identity address track the connection based on it
1311 * from now on.
1312 */
1313 bacpy(&hcon->dst, &smp->remote_irk->bdaddr);
1314 hcon->dst_type = smp->remote_irk->addr_type;
1315 l2cap_conn_update_id_addr(hcon);
Marcel Holtmann66d8e832014-07-24 15:20:58 +02001316
1317 /* When receiving an indentity resolving key for
1318 * a remote device that does not use a resolvable
1319 * private address, just remove the key so that
1320 * it is possible to use the controller white
1321 * list for scanning.
1322 *
1323 * Userspace will have been told to not store
1324 * this key at this point. So it is safe to
1325 * just remove it.
1326 */
1327 if (!bacmp(&smp->remote_irk->rpa, BDADDR_ANY)) {
1328 list_del(&smp->remote_irk->list);
1329 kfree(smp->remote_irk);
1330 smp->remote_irk = NULL;
1331 }
Johan Hedberg61b1a7f2014-03-20 12:54:16 +02001332 }
Johan Hedberg95fbac82014-02-19 15:18:31 +02001333
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001334 /* The LTKs and CSRKs should be persistent only if both sides
1335 * had the bonding bit set in their authentication requests.
1336 */
1337 persistent = !!((req->auth_req & rsp->auth_req) & SMP_AUTH_BONDING);
1338
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001339 if (smp->csrk) {
1340 smp->csrk->bdaddr_type = hcon->dst_type;
1341 bacpy(&smp->csrk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001342 mgmt_new_csrk(hdev, smp->csrk, persistent);
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001343 }
1344
1345 if (smp->slave_csrk) {
1346 smp->slave_csrk->bdaddr_type = hcon->dst_type;
1347 bacpy(&smp->slave_csrk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001348 mgmt_new_csrk(hdev, smp->slave_csrk, persistent);
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001349 }
1350
Johan Hedberg35d70272014-02-19 14:57:47 +02001351 if (smp->ltk) {
1352 smp->ltk->bdaddr_type = hcon->dst_type;
1353 bacpy(&smp->ltk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001354 mgmt_new_ltk(hdev, smp->ltk, persistent);
Johan Hedberg35d70272014-02-19 14:57:47 +02001355 }
1356
1357 if (smp->slave_ltk) {
1358 smp->slave_ltk->bdaddr_type = hcon->dst_type;
1359 bacpy(&smp->slave_ltk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001360 mgmt_new_ltk(hdev, smp->slave_ltk, persistent);
Johan Hedberg35d70272014-02-19 14:57:47 +02001361 }
1362}
1363
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001364int smp_distribute_keys(struct l2cap_conn *conn)
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001365{
1366 struct smp_cmd_pairing *req, *rsp;
Johan Hedberg5d88cc72014-08-08 09:37:18 +03001367 struct l2cap_chan *chan = conn->smp;
1368 struct smp_chan *smp = chan->data;
Johan Hedberg524237c2014-02-22 19:06:31 +02001369 struct hci_conn *hcon = conn->hcon;
1370 struct hci_dev *hdev = hcon->hdev;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001371 __u8 *keydist;
1372
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001373 BT_DBG("conn %p", conn);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001374
Johan Hedberg524237c2014-02-22 19:06:31 +02001375 if (!test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001376 return 0;
1377
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001378 rsp = (void *) &smp->prsp[1];
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001379
1380 /* The responder sends its keys first */
Johan Hedbergefabba32014-02-26 23:33:44 +02001381 if (hcon->out && (smp->remote_key_dist & 0x07))
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001382 return 0;
1383
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001384 req = (void *) &smp->preq[1];
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001385
Johan Hedberg524237c2014-02-22 19:06:31 +02001386 if (hcon->out) {
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001387 keydist = &rsp->init_key_dist;
1388 *keydist &= req->init_key_dist;
1389 } else {
1390 keydist = &rsp->resp_key_dist;
1391 *keydist &= req->resp_key_dist;
1392 }
1393
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001394 BT_DBG("keydist 0x%x", *keydist);
1395
1396 if (*keydist & SMP_DIST_ENC_KEY) {
1397 struct smp_cmd_encrypt_info enc;
1398 struct smp_cmd_master_ident ident;
Johan Hedberg23d0e122014-02-19 14:57:46 +02001399 struct smp_ltk *ltk;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001400 u8 authenticated;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001401 __le16 ediv;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001402 __le64 rand;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001403
1404 get_random_bytes(enc.ltk, sizeof(enc.ltk));
1405 get_random_bytes(&ediv, sizeof(ediv));
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001406 get_random_bytes(&rand, sizeof(rand));
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001407
1408 smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
1409
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001410 authenticated = hcon->sec_level == BT_SECURITY_HIGH;
Johan Hedberg524237c2014-02-22 19:06:31 +02001411 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type,
Johan Hedberg2ceba532014-06-16 19:25:16 +03001412 SMP_LTK_SLAVE, authenticated, enc.ltk,
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001413 smp->enc_key_size, ediv, rand);
Johan Hedberg23d0e122014-02-19 14:57:46 +02001414 smp->slave_ltk = ltk;
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001415
Andrei Emeltchenko58115372012-03-12 12:13:06 +02001416 ident.ediv = ediv;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001417 ident.rand = rand;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001418
1419 smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident);
1420
1421 *keydist &= ~SMP_DIST_ENC_KEY;
1422 }
1423
1424 if (*keydist & SMP_DIST_ID_KEY) {
1425 struct smp_cmd_ident_addr_info addrinfo;
1426 struct smp_cmd_ident_info idinfo;
1427
Johan Hedberg863efaf2014-02-22 19:06:32 +02001428 memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk));
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001429
1430 smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo);
1431
Johan Hedberg82d4b352014-02-23 19:42:18 +02001432 /* The hci_conn contains the local identity address
1433 * after the connection has been established.
1434 *
1435 * This is true even when the connection has been
1436 * established using a resolvable random address.
1437 */
Johan Hedberg524237c2014-02-22 19:06:31 +02001438 bacpy(&addrinfo.bdaddr, &hcon->src);
Johan Hedberg82d4b352014-02-23 19:42:18 +02001439 addrinfo.addr_type = hcon->src_type;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001440
1441 smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo),
Marcel Holtmannf1560462013-10-13 05:43:25 -07001442 &addrinfo);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001443
1444 *keydist &= ~SMP_DIST_ID_KEY;
1445 }
1446
1447 if (*keydist & SMP_DIST_SIGN) {
1448 struct smp_cmd_sign_info sign;
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001449 struct smp_csrk *csrk;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001450
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001451 /* Generate a new random key */
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001452 get_random_bytes(sign.csrk, sizeof(sign.csrk));
1453
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001454 csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
1455 if (csrk) {
1456 csrk->master = 0x00;
1457 memcpy(csrk->val, sign.csrk, sizeof(csrk->val));
1458 }
1459 smp->slave_csrk = csrk;
1460
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001461 smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign);
1462
1463 *keydist &= ~SMP_DIST_SIGN;
1464 }
1465
Johan Hedbergefabba32014-02-26 23:33:44 +02001466 /* If there are still keys to be received wait for them */
1467 if ((smp->remote_key_dist & 0x07))
1468 return 0;
1469
Johan Hedberg1d98bf42014-03-24 14:39:08 +02001470 clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags);
1471 cancel_delayed_work_sync(&conn->security_timer);
Johan Hedberg4a74d652014-05-20 09:45:50 +03001472 set_bit(SMP_FLAG_COMPLETE, &smp->flags);
Johan Hedberg1d98bf42014-03-24 14:39:08 +02001473 smp_notify_keys(conn);
Johan Hedbergefabba32014-02-26 23:33:44 +02001474
Johan Hedberg1d98bf42014-03-24 14:39:08 +02001475 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001476
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001477 return 0;
1478}
Johan Hedberg711eafe2014-08-08 09:32:52 +03001479
Johan Hedberg70db83c2014-08-08 09:37:16 +03001480static void smp_teardown_cb(struct l2cap_chan *chan, int err)
1481{
1482 struct l2cap_conn *conn = chan->conn;
1483
1484 BT_DBG("chan %p", chan);
1485
Johan Hedberg5d88cc72014-08-08 09:37:18 +03001486 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1487 cancel_delayed_work_sync(&conn->security_timer);
1488 smp_chan_destroy(conn);
1489 }
1490
Johan Hedberg70db83c2014-08-08 09:37:16 +03001491 conn->smp = NULL;
1492 l2cap_chan_put(chan);
1493}
1494
1495static void smp_ready_cb(struct l2cap_chan *chan)
1496{
1497 struct l2cap_conn *conn = chan->conn;
1498
1499 BT_DBG("chan %p", chan);
1500
1501 conn->smp = chan;
1502 l2cap_chan_hold(chan);
1503}
1504
1505static struct sk_buff *smp_alloc_skb_cb(struct l2cap_chan *chan,
1506 unsigned long hdr_len,
1507 unsigned long len, int nb)
1508{
1509 struct sk_buff *skb;
1510
1511 skb = bt_skb_alloc(hdr_len + len, GFP_KERNEL);
1512 if (!skb)
1513 return ERR_PTR(-ENOMEM);
1514
1515 skb->priority = HCI_PRIO_MAX;
1516 bt_cb(skb)->chan = chan;
1517
1518 return skb;
1519}
1520
1521static const struct l2cap_ops smp_chan_ops = {
1522 .name = "Security Manager",
1523 .ready = smp_ready_cb,
Johan Hedberg5d88cc72014-08-08 09:37:18 +03001524 .recv = smp_recv_cb,
Johan Hedberg70db83c2014-08-08 09:37:16 +03001525 .alloc_skb = smp_alloc_skb_cb,
1526 .teardown = smp_teardown_cb,
1527
1528 .new_connection = l2cap_chan_no_new_connection,
Johan Hedberg70db83c2014-08-08 09:37:16 +03001529 .state_change = l2cap_chan_no_state_change,
1530 .close = l2cap_chan_no_close,
1531 .defer = l2cap_chan_no_defer,
1532 .suspend = l2cap_chan_no_suspend,
1533 .resume = l2cap_chan_no_resume,
1534 .set_shutdown = l2cap_chan_no_set_shutdown,
1535 .get_sndtimeo = l2cap_chan_no_get_sndtimeo,
1536 .memcpy_fromiovec = l2cap_chan_no_memcpy_fromiovec,
1537};
1538
1539static inline struct l2cap_chan *smp_new_conn_cb(struct l2cap_chan *pchan)
1540{
1541 struct l2cap_chan *chan;
1542
1543 BT_DBG("pchan %p", pchan);
1544
1545 chan = l2cap_chan_create();
1546 if (!chan)
1547 return NULL;
1548
1549 chan->chan_type = pchan->chan_type;
1550 chan->ops = &smp_chan_ops;
1551 chan->scid = pchan->scid;
1552 chan->dcid = chan->scid;
1553 chan->imtu = pchan->imtu;
1554 chan->omtu = pchan->omtu;
1555 chan->mode = pchan->mode;
1556
1557 BT_DBG("created chan %p", chan);
1558
1559 return chan;
1560}
1561
1562static const struct l2cap_ops smp_root_chan_ops = {
1563 .name = "Security Manager Root",
1564 .new_connection = smp_new_conn_cb,
1565
1566 /* None of these are implemented for the root channel */
1567 .close = l2cap_chan_no_close,
1568 .alloc_skb = l2cap_chan_no_alloc_skb,
1569 .recv = l2cap_chan_no_recv,
1570 .state_change = l2cap_chan_no_state_change,
1571 .teardown = l2cap_chan_no_teardown,
1572 .ready = l2cap_chan_no_ready,
1573 .defer = l2cap_chan_no_defer,
1574 .suspend = l2cap_chan_no_suspend,
1575 .resume = l2cap_chan_no_resume,
1576 .set_shutdown = l2cap_chan_no_set_shutdown,
1577 .get_sndtimeo = l2cap_chan_no_get_sndtimeo,
1578 .memcpy_fromiovec = l2cap_chan_no_memcpy_fromiovec,
1579};
1580
Johan Hedberg711eafe2014-08-08 09:32:52 +03001581int smp_register(struct hci_dev *hdev)
1582{
Johan Hedberg70db83c2014-08-08 09:37:16 +03001583 struct l2cap_chan *chan;
Johan Hedbergdefce9e2014-08-08 09:37:17 +03001584 struct crypto_blkcipher *tfm_aes;
Johan Hedberg70db83c2014-08-08 09:37:16 +03001585
Johan Hedberg711eafe2014-08-08 09:32:52 +03001586 BT_DBG("%s", hdev->name);
1587
Johan Hedbergdefce9e2014-08-08 09:37:17 +03001588 tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
1589 if (IS_ERR(tfm_aes)) {
1590 int err = PTR_ERR(tfm_aes);
Johan Hedberg711eafe2014-08-08 09:32:52 +03001591 BT_ERR("Unable to create crypto context");
Johan Hedberg711eafe2014-08-08 09:32:52 +03001592 return err;
1593 }
1594
Johan Hedberg70db83c2014-08-08 09:37:16 +03001595 chan = l2cap_chan_create();
1596 if (!chan) {
Johan Hedbergdefce9e2014-08-08 09:37:17 +03001597 crypto_free_blkcipher(tfm_aes);
Johan Hedberg70db83c2014-08-08 09:37:16 +03001598 return -ENOMEM;
1599 }
1600
Johan Hedbergdefce9e2014-08-08 09:37:17 +03001601 chan->data = tfm_aes;
1602
Johan Hedberg5d88cc72014-08-08 09:37:18 +03001603 l2cap_add_scid(chan, L2CAP_CID_SMP);
Johan Hedberg70db83c2014-08-08 09:37:16 +03001604
1605 l2cap_chan_set_defaults(chan);
1606
1607 bacpy(&chan->src, &hdev->bdaddr);
1608 chan->src_type = BDADDR_LE_PUBLIC;
1609 chan->state = BT_LISTEN;
1610 chan->mode = L2CAP_MODE_BASIC;
1611 chan->imtu = L2CAP_DEFAULT_MTU;
1612 chan->ops = &smp_root_chan_ops;
1613
1614 hdev->smp_data = chan;
1615
Johan Hedberg711eafe2014-08-08 09:32:52 +03001616 return 0;
1617}
1618
1619void smp_unregister(struct hci_dev *hdev)
1620{
Johan Hedberg70db83c2014-08-08 09:37:16 +03001621 struct l2cap_chan *chan = hdev->smp_data;
Johan Hedbergdefce9e2014-08-08 09:37:17 +03001622 struct crypto_blkcipher *tfm_aes;
Johan Hedberg70db83c2014-08-08 09:37:16 +03001623
1624 if (!chan)
1625 return;
1626
1627 BT_DBG("%s chan %p", hdev->name, chan);
Johan Hedberg711eafe2014-08-08 09:32:52 +03001628
Johan Hedbergdefce9e2014-08-08 09:37:17 +03001629 tfm_aes = chan->data;
1630 if (tfm_aes) {
1631 chan->data = NULL;
1632 crypto_free_blkcipher(tfm_aes);
Johan Hedberg711eafe2014-08-08 09:32:52 +03001633 }
Johan Hedberg70db83c2014-08-08 09:37:16 +03001634
1635 hdev->smp_data = NULL;
1636 l2cap_chan_put(chan);
Johan Hedberg711eafe2014-08-08 09:32:52 +03001637}