blob: 55c41de2f5a03c1a1f6de41ca722c7568d511b3d [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 Hedberga8b2d5c2012-01-08 23:11:15 +0200310 if (test_bit(HCI_PAIRABLE, &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{
394 /* If either side has unknown io_caps, use JUST WORKS */
395 if (local_io > SMP_IO_KEYBOARD_DISPLAY ||
396 remote_io > SMP_IO_KEYBOARD_DISPLAY)
397 return JUST_WORKS;
398
399 return gen_method[remote_io][local_io];
400}
401
Brian Gix2b64d152011-12-21 16:12:12 -0800402static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
403 u8 local_io, u8 remote_io)
404{
405 struct hci_conn *hcon = conn->hcon;
406 struct smp_chan *smp = conn->smp_chan;
407 u8 method;
408 u32 passkey = 0;
409 int ret = 0;
410
411 /* Initialize key for JUST WORKS */
412 memset(smp->tk, 0, sizeof(smp->tk));
Johan Hedberg4a74d652014-05-20 09:45:50 +0300413 clear_bit(SMP_FLAG_TK_VALID, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800414
415 BT_DBG("tk_request: auth:%d lcl:%d rem:%d", auth, local_io, remote_io);
416
417 /* If neither side wants MITM, use JUST WORKS */
Brian Gix2b64d152011-12-21 16:12:12 -0800418 /* Otherwise, look up method from the table */
Johan Hedberg581370c2014-06-17 13:07:38 +0300419 if (!(auth & SMP_AUTH_MITM))
Brian Gix2b64d152011-12-21 16:12:12 -0800420 method = JUST_WORKS;
421 else
Johan Hedberg581370c2014-06-17 13:07:38 +0300422 method = get_auth_method(smp, local_io, remote_io);
Brian Gix2b64d152011-12-21 16:12:12 -0800423
424 /* If not bonding, don't ask user to confirm a Zero TK */
425 if (!(auth & SMP_AUTH_BONDING) && method == JUST_CFM)
426 method = JUST_WORKS;
427
Johan Hedberga82505c2014-03-24 14:39:07 +0200428 /* Don't confirm locally initiated pairing attempts */
Johan Hedberg4a74d652014-05-20 09:45:50 +0300429 if (method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR, &smp->flags))
Johan Hedberga82505c2014-03-24 14:39:07 +0200430 method = JUST_WORKS;
431
Brian Gix2b64d152011-12-21 16:12:12 -0800432 /* If Just Works, Continue with Zero TK */
433 if (method == JUST_WORKS) {
Johan Hedberg4a74d652014-05-20 09:45:50 +0300434 set_bit(SMP_FLAG_TK_VALID, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800435 return 0;
436 }
437
438 /* Not Just Works/Confirm results in MITM Authentication */
439 if (method != JUST_CFM)
Johan Hedberg4a74d652014-05-20 09:45:50 +0300440 set_bit(SMP_FLAG_MITM_AUTH, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800441
442 /* If both devices have Keyoard-Display I/O, the master
443 * Confirms and the slave Enters the passkey.
444 */
445 if (method == OVERLAP) {
Johan Hedberg4dae2792014-06-24 17:03:50 +0300446 if (test_bit(HCI_CONN_MASTER, &hcon->flags))
Brian Gix2b64d152011-12-21 16:12:12 -0800447 method = CFM_PASSKEY;
448 else
449 method = REQ_PASSKEY;
450 }
451
Johan Hedberg01ad34d2014-03-19 14:14:53 +0200452 /* Generate random passkey. */
Brian Gix2b64d152011-12-21 16:12:12 -0800453 if (method == CFM_PASSKEY) {
Johan Hedberg943a7322014-03-18 12:58:24 +0200454 memset(smp->tk, 0, sizeof(smp->tk));
Brian Gix2b64d152011-12-21 16:12:12 -0800455 get_random_bytes(&passkey, sizeof(passkey));
456 passkey %= 1000000;
Johan Hedberg943a7322014-03-18 12:58:24 +0200457 put_unaligned_le32(passkey, smp->tk);
Brian Gix2b64d152011-12-21 16:12:12 -0800458 BT_DBG("PassKey: %d", passkey);
Johan Hedberg4a74d652014-05-20 09:45:50 +0300459 set_bit(SMP_FLAG_TK_VALID, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800460 }
461
462 hci_dev_lock(hcon->hdev);
463
464 if (method == REQ_PASSKEY)
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700465 ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200466 hcon->type, hcon->dst_type);
Johan Hedberg4eb65e62014-03-24 14:39:05 +0200467 else if (method == JUST_CFM)
468 ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
469 hcon->type, hcon->dst_type,
470 passkey, 1);
Brian Gix2b64d152011-12-21 16:12:12 -0800471 else
Johan Hedberg01ad34d2014-03-19 14:14:53 +0200472 ret = mgmt_user_passkey_notify(hcon->hdev, &hcon->dst,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200473 hcon->type, hcon->dst_type,
Johan Hedberg39adbff2014-03-20 08:18:14 +0200474 passkey, 0);
Brian Gix2b64d152011-12-21 16:12:12 -0800475
476 hci_dev_unlock(hcon->hdev);
477
478 return ret;
479}
480
Johan Hedberg1cc61142014-05-20 09:45:52 +0300481static u8 smp_confirm(struct smp_chan *smp)
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300482{
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300483 struct l2cap_conn *conn = smp->conn;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300484 struct smp_cmd_pairing_confirm cp;
485 int ret;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300486
487 BT_DBG("conn %p", conn);
488
Johan Hedbergec70f362014-06-27 14:23:04 +0300489 ret = smp_c1(smp, smp->tk, smp->prnd, smp->preq, smp->prsp,
Johan Hedbergb1cd5fd2014-02-28 12:54:17 +0200490 conn->hcon->init_addr_type, &conn->hcon->init_addr,
Johan Hedberg943a7322014-03-18 12:58:24 +0200491 conn->hcon->resp_addr_type, &conn->hcon->resp_addr,
492 cp.confirm_val);
Johan Hedberg1cc61142014-05-20 09:45:52 +0300493 if (ret)
494 return SMP_UNSPECIFIED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300495
Johan Hedberg4a74d652014-05-20 09:45:50 +0300496 clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800497
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300498 smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
499
Johan Hedberg1cc61142014-05-20 09:45:52 +0300500 return 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300501}
502
Johan Hedberg861580a2014-05-20 09:45:51 +0300503static u8 smp_random(struct smp_chan *smp)
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300504{
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300505 struct l2cap_conn *conn = smp->conn;
506 struct hci_conn *hcon = conn->hcon;
Johan Hedberg861580a2014-05-20 09:45:51 +0300507 u8 confirm[16];
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300508 int ret;
509
Johan Hedbergec70f362014-06-27 14:23:04 +0300510 if (IS_ERR_OR_NULL(smp->tfm_aes))
Johan Hedberg861580a2014-05-20 09:45:51 +0300511 return SMP_UNSPECIFIED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300512
513 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
514
Johan Hedbergec70f362014-06-27 14:23:04 +0300515 ret = smp_c1(smp, smp->tk, smp->rrnd, smp->preq, smp->prsp,
Johan Hedbergb1cd5fd2014-02-28 12:54:17 +0200516 hcon->init_addr_type, &hcon->init_addr,
Johan Hedberg943a7322014-03-18 12:58:24 +0200517 hcon->resp_addr_type, &hcon->resp_addr, confirm);
Johan Hedberg861580a2014-05-20 09:45:51 +0300518 if (ret)
519 return SMP_UNSPECIFIED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300520
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300521 if (memcmp(smp->pcnf, confirm, sizeof(smp->pcnf)) != 0) {
522 BT_ERR("Pairing failed (confirmation values mismatch)");
Johan Hedberg861580a2014-05-20 09:45:51 +0300523 return SMP_CONFIRM_FAILED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300524 }
525
526 if (hcon->out) {
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -0800527 u8 stk[16];
528 __le64 rand = 0;
529 __le16 ediv = 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300530
Johan Hedbergec70f362014-06-27 14:23:04 +0300531 smp_s1(smp, smp->tk, smp->rrnd, smp->prnd, stk);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300532
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300533 memset(stk + smp->enc_key_size, 0,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300534 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300535
Johan Hedberg861580a2014-05-20 09:45:51 +0300536 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
537 return SMP_UNSPECIFIED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300538
539 hci_le_start_enc(hcon, ediv, rand, stk);
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300540 hcon->enc_key_size = smp->enc_key_size;
Johan Hedbergfe59a052014-07-01 19:14:12 +0300541 set_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300542 } else {
Johan Hedbergfff34902014-06-10 15:19:50 +0300543 u8 stk[16], auth;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -0800544 __le64 rand = 0;
545 __le16 ediv = 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300546
Johan Hedberg943a7322014-03-18 12:58:24 +0200547 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
548 smp->prnd);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300549
Johan Hedbergec70f362014-06-27 14:23:04 +0300550 smp_s1(smp, smp->tk, smp->prnd, smp->rrnd, stk);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300551
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300552 memset(stk + smp->enc_key_size, 0,
Marcel Holtmannf1560462013-10-13 05:43:25 -0700553 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300554
Johan Hedbergfff34902014-06-10 15:19:50 +0300555 if (hcon->pending_sec_level == BT_SECURITY_HIGH)
556 auth = 1;
557 else
558 auth = 0;
559
Johan Hedberg7d5843b2014-06-16 19:25:15 +0300560 /* Even though there's no _SLAVE suffix this is the
561 * slave STK we're adding for later lookup (the master
562 * STK never needs to be stored).
563 */
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700564 hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
Johan Hedberg2ceba532014-06-16 19:25:16 +0300565 SMP_STK, auth, stk, smp->enc_key_size, ediv, rand);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300566 }
567
Johan Hedberg861580a2014-05-20 09:45:51 +0300568 return 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300569}
570
571static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
572{
573 struct smp_chan *smp;
574
Marcel Holtmannf1560462013-10-13 05:43:25 -0700575 smp = kzalloc(sizeof(*smp), GFP_ATOMIC);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300576 if (!smp)
577 return NULL;
578
Johan Hedberg6a7bd102014-06-27 14:23:03 +0300579 smp->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
580 if (IS_ERR(smp->tfm_aes)) {
581 BT_ERR("Unable to create ECB crypto context");
582 kfree(smp);
583 return NULL;
584 }
585
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300586 smp->conn = conn;
587 conn->smp_chan = smp;
588
589 hci_conn_hold(conn->hcon);
590
591 return smp;
592}
593
594void smp_chan_destroy(struct l2cap_conn *conn)
595{
Brian Gixc8eb9692011-11-23 08:28:35 -0800596 struct smp_chan *smp = conn->smp_chan;
Johan Hedbergf4a407b2014-02-18 21:41:34 +0200597 bool complete;
Brian Gixc8eb9692011-11-23 08:28:35 -0800598
Vinicius Costa Gomesf1c09c02012-02-01 18:27:56 -0300599 BUG_ON(!smp);
Brian Gixc8eb9692011-11-23 08:28:35 -0800600
Johan Hedberg4a74d652014-05-20 09:45:50 +0300601 complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags);
Johan Hedbergf4a407b2014-02-18 21:41:34 +0200602 mgmt_smp_complete(conn->hcon, complete);
603
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -0700604 kfree(smp->csrk);
605 kfree(smp->slave_csrk);
606
Johan Hedberg6a7bd102014-06-27 14:23:03 +0300607 crypto_free_blkcipher(smp->tfm_aes);
608
Johan Hedberg759331d2014-02-28 10:10:16 +0200609 /* If pairing failed clean up any keys we might have */
610 if (!complete) {
611 if (smp->ltk) {
612 list_del(&smp->ltk->list);
613 kfree(smp->ltk);
614 }
615
616 if (smp->slave_ltk) {
617 list_del(&smp->slave_ltk->list);
618 kfree(smp->slave_ltk);
619 }
620
621 if (smp->remote_irk) {
622 list_del(&smp->remote_irk->list);
623 kfree(smp->remote_irk);
624 }
625 }
626
Brian Gixc8eb9692011-11-23 08:28:35 -0800627 kfree(smp);
628 conn->smp_chan = NULL;
David Herrmann76a68ba2013-04-06 20:28:37 +0200629 hci_conn_drop(conn->hcon);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300630}
631
Brian Gix2b64d152011-12-21 16:12:12 -0800632int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
633{
Johan Hedbergb10e8012014-06-27 14:23:07 +0300634 struct l2cap_conn *conn = hcon->l2cap_data;
Brian Gix2b64d152011-12-21 16:12:12 -0800635 struct smp_chan *smp;
636 u32 value;
Brian Gix2b64d152011-12-21 16:12:12 -0800637
638 BT_DBG("");
639
Johan Hedberg642ac772014-06-27 14:23:06 +0300640 if (!conn || !test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Brian Gix2b64d152011-12-21 16:12:12 -0800641 return -ENOTCONN;
642
643 smp = conn->smp_chan;
644
645 switch (mgmt_op) {
646 case MGMT_OP_USER_PASSKEY_REPLY:
647 value = le32_to_cpu(passkey);
Johan Hedberg943a7322014-03-18 12:58:24 +0200648 memset(smp->tk, 0, sizeof(smp->tk));
Brian Gix2b64d152011-12-21 16:12:12 -0800649 BT_DBG("PassKey: %d", value);
Johan Hedberg943a7322014-03-18 12:58:24 +0200650 put_unaligned_le32(value, smp->tk);
Brian Gix2b64d152011-12-21 16:12:12 -0800651 /* Fall Through */
652 case MGMT_OP_USER_CONFIRM_REPLY:
Johan Hedberg4a74d652014-05-20 09:45:50 +0300653 set_bit(SMP_FLAG_TK_VALID, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800654 break;
655 case MGMT_OP_USER_PASSKEY_NEG_REPLY:
656 case MGMT_OP_USER_CONFIRM_NEG_REPLY:
Johan Hedberg84794e12013-11-06 11:24:57 +0200657 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
Brian Gix2b64d152011-12-21 16:12:12 -0800658 return 0;
659 default:
Johan Hedberg84794e12013-11-06 11:24:57 +0200660 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
Brian Gix2b64d152011-12-21 16:12:12 -0800661 return -EOPNOTSUPP;
662 }
663
664 /* If it is our turn to send Pairing Confirm, do so now */
Johan Hedberg1cc61142014-05-20 09:45:52 +0300665 if (test_bit(SMP_FLAG_CFM_PENDING, &smp->flags)) {
666 u8 rsp = smp_confirm(smp);
667 if (rsp)
668 smp_failure(conn, rsp);
669 }
Brian Gix2b64d152011-12-21 16:12:12 -0800670
671 return 0;
672}
673
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300674static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300675{
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300676 struct smp_cmd_pairing rsp, *req = (void *) skb->data;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300677 struct smp_chan *smp;
Johan Hedbergc7262e72014-06-17 13:07:37 +0300678 u8 key_size, auth, sec_level;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300679 int ret;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300680
681 BT_DBG("conn %p", conn);
682
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200683 if (skb->len < sizeof(*req))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300684 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200685
Johan Hedberg4dae2792014-06-24 17:03:50 +0300686 if (test_bit(HCI_CONN_MASTER, &conn->hcon->flags))
Brian Gix2b64d152011-12-21 16:12:12 -0800687 return SMP_CMD_NOTSUPP;
688
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200689 if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags))
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300690 smp = smp_chan_create(conn);
Andrei Emeltchenkod08fd0e2012-07-19 17:03:43 +0300691 else
692 smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300693
Andrei Emeltchenkod08fd0e2012-07-19 17:03:43 +0300694 if (!smp)
695 return SMP_UNSPECIFIED;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300696
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300697 smp->preq[0] = SMP_CMD_PAIRING_REQ;
698 memcpy(&smp->preq[1], req, sizeof(*req));
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300699 skb_pull(skb, sizeof(*req));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300700
Brian Gix2b64d152011-12-21 16:12:12 -0800701 /* We didn't start the pairing, so match remote */
Johan Hedberg1ef35822014-05-20 09:45:48 +0300702 auth = req->auth_req;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300703
Johan Hedbergc7262e72014-06-17 13:07:37 +0300704 sec_level = authreq_to_seclevel(auth);
705 if (sec_level > conn->hcon->pending_sec_level)
706 conn->hcon->pending_sec_level = sec_level;
Ido Yarivfdde0a22012-03-05 20:09:38 +0200707
Johan Hedberg2ed8f652014-06-17 13:07:39 +0300708 /* If we need MITM check that it can be acheived */
709 if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
710 u8 method;
711
712 method = get_auth_method(smp, conn->hcon->io_capability,
713 req->io_capability);
714 if (method == JUST_WORKS || method == JUST_CFM)
715 return SMP_AUTH_REQUIREMENTS;
716 }
717
Brian Gix2b64d152011-12-21 16:12:12 -0800718 build_pairing_cmd(conn, req, &rsp, auth);
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300719
720 key_size = min(req->max_key_size, rsp.max_key_size);
721 if (check_enc_key_size(conn, key_size))
722 return SMP_ENC_KEY_SIZE;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300723
Johan Hedberge84a6b12013-12-02 10:49:03 +0200724 get_random_bytes(smp->prnd, sizeof(smp->prnd));
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300725
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300726 smp->prsp[0] = SMP_CMD_PAIRING_RSP;
727 memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300728
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300729 smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300730
Brian Gix2b64d152011-12-21 16:12:12 -0800731 /* Request setup of TK */
732 ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability);
733 if (ret)
734 return SMP_UNSPECIFIED;
735
Johan Hedberg4a74d652014-05-20 09:45:50 +0300736 clear_bit(SMP_FLAG_INITIATOR, &smp->flags);
Johan Hedbergedca7922014-03-24 15:54:11 +0200737
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300738 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300739}
740
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300741static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300742{
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300743 struct smp_cmd_pairing *req, *rsp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300744 struct smp_chan *smp = conn->smp_chan;
Brian Gix2b64d152011-12-21 16:12:12 -0800745 u8 key_size, auth = SMP_AUTH_NONE;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300746 int ret;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300747
748 BT_DBG("conn %p", conn);
749
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200750 if (skb->len < sizeof(*rsp))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300751 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200752
Johan Hedberg4dae2792014-06-24 17:03:50 +0300753 if (!test_bit(HCI_CONN_MASTER, &conn->hcon->flags))
Brian Gix2b64d152011-12-21 16:12:12 -0800754 return SMP_CMD_NOTSUPP;
755
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300756 skb_pull(skb, sizeof(*rsp));
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300757
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300758 req = (void *) &smp->preq[1];
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300759
760 key_size = min(req->max_key_size, rsp->max_key_size);
761 if (check_enc_key_size(conn, key_size))
762 return SMP_ENC_KEY_SIZE;
763
Johan Hedberg2ed8f652014-06-17 13:07:39 +0300764 /* If we need MITM check that it can be acheived */
765 if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
766 u8 method;
767
768 method = get_auth_method(smp, req->io_capability,
769 rsp->io_capability);
770 if (method == JUST_WORKS || method == JUST_CFM)
771 return SMP_AUTH_REQUIREMENTS;
772 }
773
Johan Hedberge84a6b12013-12-02 10:49:03 +0200774 get_random_bytes(smp->prnd, sizeof(smp->prnd));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300775
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300776 smp->prsp[0] = SMP_CMD_PAIRING_RSP;
777 memcpy(&smp->prsp[1], rsp, sizeof(*rsp));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300778
Johan Hedbergfdcc4be2014-03-14 10:53:50 +0200779 /* Update remote key distribution in case the remote cleared
780 * some bits that we had enabled in our request.
781 */
782 smp->remote_key_dist &= rsp->resp_key_dist;
783
Brian Gix2b64d152011-12-21 16:12:12 -0800784 if ((req->auth_req & SMP_AUTH_BONDING) &&
Marcel Holtmannf1560462013-10-13 05:43:25 -0700785 (rsp->auth_req & SMP_AUTH_BONDING))
Brian Gix2b64d152011-12-21 16:12:12 -0800786 auth = SMP_AUTH_BONDING;
787
788 auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM;
789
Johan Hedberg476585e2012-06-06 18:54:15 +0800790 ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability);
Brian Gix2b64d152011-12-21 16:12:12 -0800791 if (ret)
792 return SMP_UNSPECIFIED;
793
Johan Hedberg4a74d652014-05-20 09:45:50 +0300794 set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800795
796 /* Can't compose response until we have been confirmed */
Johan Hedberg4a74d652014-05-20 09:45:50 +0300797 if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
Johan Hedberg1cc61142014-05-20 09:45:52 +0300798 return smp_confirm(smp);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300799
800 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300801}
802
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300803static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300804{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300805 struct smp_chan *smp = conn->smp_chan;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300806
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300807 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
808
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200809 if (skb->len < sizeof(smp->pcnf))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300810 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200811
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300812 memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf));
813 skb_pull(skb, sizeof(smp->pcnf));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300814
Johan Hedberg943a7322014-03-18 12:58:24 +0200815 if (conn->hcon->out)
816 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
817 smp->prnd);
Johan Hedberg4a74d652014-05-20 09:45:50 +0300818 else if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
Johan Hedberg1cc61142014-05-20 09:45:52 +0300819 return smp_confirm(smp);
Johan Hedberg943a7322014-03-18 12:58:24 +0200820 else
Johan Hedberg4a74d652014-05-20 09:45:50 +0300821 set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
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_random(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300827{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300828 struct smp_chan *smp = conn->smp_chan;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300829
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300830 BT_DBG("conn %p", conn);
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300831
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200832 if (skb->len < sizeof(smp->rrnd))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300833 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200834
Johan Hedberg943a7322014-03-18 12:58:24 +0200835 memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd));
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300836 skb_pull(skb, sizeof(smp->rrnd));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300837
Johan Hedberg861580a2014-05-20 09:45:51 +0300838 return smp_random(smp);
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300839}
840
Marcel Holtmannf81cd822014-07-01 10:59:24 +0200841static bool smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300842{
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300843 struct smp_ltk *key;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300844 struct hci_conn *hcon = conn->hcon;
845
Johan Hedberg98a0b842014-01-30 19:40:00 -0800846 key = hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type,
847 hcon->out);
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300848 if (!key)
Marcel Holtmannf81cd822014-07-01 10:59:24 +0200849 return false;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300850
Johan Hedberg4dab7862012-06-07 14:58:37 +0800851 if (sec_level > BT_SECURITY_MEDIUM && !key->authenticated)
Marcel Holtmannf81cd822014-07-01 10:59:24 +0200852 return false;
Johan Hedberg4dab7862012-06-07 14:58:37 +0800853
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200854 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
Marcel Holtmannf81cd822014-07-01 10:59:24 +0200855 return true;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300856
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300857 hci_le_start_enc(hcon, key->ediv, key->rand, key->val);
858 hcon->enc_key_size = key->enc_size;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300859
Johan Hedbergfe59a052014-07-01 19:14:12 +0300860 /* We never store STKs for master role, so clear this flag */
861 clear_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags);
862
Marcel Holtmannf81cd822014-07-01 10:59:24 +0200863 return true;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300864}
Marcel Holtmannf1560462013-10-13 05:43:25 -0700865
Johan Hedberg854f4722014-07-01 18:40:20 +0300866bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level)
867{
868 if (sec_level == BT_SECURITY_LOW)
869 return true;
870
Johan Hedberg9ab65d602014-07-01 19:14:13 +0300871 /* If we're encrypted with an STK always claim insufficient
872 * security. This way we allow the connection to be re-encrypted
873 * with an LTK, even if the LTK provides the same level of
874 * security.
875 */
876 if (test_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags))
877 return false;
878
Johan Hedberg854f4722014-07-01 18:40:20 +0300879 if (hcon->sec_level >= sec_level)
880 return true;
881
882 return false;
883}
884
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300885static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300886{
887 struct smp_cmd_security_req *rp = (void *) skb->data;
888 struct smp_cmd_pairing cp;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300889 struct hci_conn *hcon = conn->hcon;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300890 struct smp_chan *smp;
Johan Hedbergc7262e72014-06-17 13:07:37 +0300891 u8 sec_level;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300892
893 BT_DBG("conn %p", conn);
894
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200895 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300896 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200897
Johan Hedberg4dae2792014-06-24 17:03:50 +0300898 if (!test_bit(HCI_CONN_MASTER, &conn->hcon->flags))
Johan Hedberg86ca9ea2013-11-05 11:30:39 +0200899 return SMP_CMD_NOTSUPP;
900
Johan Hedbergc7262e72014-06-17 13:07:37 +0300901 sec_level = authreq_to_seclevel(rp->auth_req);
Johan Hedberg854f4722014-07-01 18:40:20 +0300902 if (smp_sufficient_security(hcon, sec_level))
903 return 0;
904
Johan Hedbergc7262e72014-06-17 13:07:37 +0300905 if (sec_level > hcon->pending_sec_level)
906 hcon->pending_sec_level = sec_level;
Vinicius Costa Gomesfeb45eb2011-08-25 20:02:35 -0300907
Johan Hedberg4dab7862012-06-07 14:58:37 +0800908 if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300909 return 0;
910
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200911 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300912 return 0;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300913
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300914 smp = smp_chan_create(conn);
Johan Hedbergc29d2442014-06-16 19:25:14 +0300915 if (!smp)
916 return SMP_UNSPECIFIED;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300917
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300918 skb_pull(skb, sizeof(*rp));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300919
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300920 memset(&cp, 0, sizeof(cp));
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300921 build_pairing_cmd(conn, &cp, NULL, rp->auth_req);
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300922
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300923 smp->preq[0] = SMP_CMD_PAIRING_REQ;
924 memcpy(&smp->preq[1], &cp, sizeof(cp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300925
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300926 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300927
Johan Hedberg4a74d652014-05-20 09:45:50 +0300928 clear_bit(SMP_FLAG_INITIATOR, &smp->flags);
Johan Hedbergedca7922014-03-24 15:54:11 +0200929
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300930 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300931}
932
Vinicius Costa Gomescc110922012-08-23 21:32:43 -0300933int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300934{
Vinicius Costa Gomescc110922012-08-23 21:32:43 -0300935 struct l2cap_conn *conn = hcon->l2cap_data;
Johan Hedberg0a66cf22014-03-24 14:39:03 +0200936 struct smp_chan *smp;
Brian Gix2b64d152011-12-21 16:12:12 -0800937 __u8 authreq;
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300938
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -0300939 BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
940
Johan Hedberg0a66cf22014-03-24 14:39:03 +0200941 /* This may be NULL if there's an unexpected disconnection */
942 if (!conn)
943 return 1;
944
Johan Hedberg757aee02013-04-24 13:05:32 +0300945 if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags))
Andre Guedes2e65c9d2011-06-30 19:20:56 -0300946 return 1;
947
Johan Hedbergad32a2f2013-05-14 18:05:12 +0300948 if (smp_sufficient_security(hcon, sec_level))
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300949 return 1;
950
Johan Hedbergc7262e72014-06-17 13:07:37 +0300951 if (sec_level > hcon->pending_sec_level)
952 hcon->pending_sec_level = sec_level;
953
Johan Hedberg4dae2792014-06-24 17:03:50 +0300954 if (test_bit(HCI_CONN_MASTER, &hcon->flags))
Johan Hedbergc7262e72014-06-17 13:07:37 +0300955 if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
956 return 0;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300957
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200958 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300959 return 0;
960
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300961 smp = smp_chan_create(conn);
Brian Gix2b64d152011-12-21 16:12:12 -0800962 if (!smp)
963 return 1;
964
965 authreq = seclevel_to_authreq(sec_level);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300966
Johan Hedberg79897d22014-06-01 09:45:24 +0300967 /* Require MITM if IO Capability allows or the security level
968 * requires it.
Johan Hedberg2e233642014-03-18 15:42:30 +0200969 */
Johan Hedberg79897d22014-06-01 09:45:24 +0300970 if (hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT ||
Johan Hedbergc7262e72014-06-17 13:07:37 +0300971 hcon->pending_sec_level > BT_SECURITY_MEDIUM)
Johan Hedberg2e233642014-03-18 15:42:30 +0200972 authreq |= SMP_AUTH_MITM;
973
Johan Hedberg4dae2792014-06-24 17:03:50 +0300974 if (test_bit(HCI_CONN_MASTER, &hcon->flags)) {
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300975 struct smp_cmd_pairing cp;
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300976
Brian Gix2b64d152011-12-21 16:12:12 -0800977 build_pairing_cmd(conn, &cp, NULL, authreq);
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300978 smp->preq[0] = SMP_CMD_PAIRING_REQ;
979 memcpy(&smp->preq[1], &cp, sizeof(cp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300980
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300981 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
982 } else {
983 struct smp_cmd_security_req cp;
Brian Gix2b64d152011-12-21 16:12:12 -0800984 cp.auth_req = authreq;
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300985 smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
986 }
987
Johan Hedberg4a74d652014-05-20 09:45:50 +0300988 set_bit(SMP_FLAG_INITIATOR, &smp->flags);
Johan Hedbergedca7922014-03-24 15:54:11 +0200989
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300990 return 0;
991}
992
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300993static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
994{
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300995 struct smp_cmd_encrypt_info *rp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300996 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300997
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200998 BT_DBG("conn %p", conn);
999
1000 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001001 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +02001002
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001003 /* Ignore this PDU if it wasn't requested */
1004 if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
1005 return 0;
1006
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001007 skb_pull(skb, sizeof(*rp));
1008
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001009 memcpy(smp->tk, rp->ltk, sizeof(smp->tk));
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001010
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001011 return 0;
1012}
1013
1014static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
1015{
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001016 struct smp_cmd_master_ident *rp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001017 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001018 struct hci_dev *hdev = conn->hcon->hdev;
1019 struct hci_conn *hcon = conn->hcon;
Johan Hedberg23d0e122014-02-19 14:57:46 +02001020 struct smp_ltk *ltk;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001021 u8 authenticated;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001022
Johan Hedbergc46b98b2014-02-18 10:19:29 +02001023 BT_DBG("conn %p", conn);
1024
1025 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001026 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +02001027
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001028 /* Ignore this PDU if it wasn't requested */
1029 if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
1030 return 0;
1031
Johan Hedberg9747a9f2014-02-26 23:33:43 +02001032 /* Mark the information as received */
1033 smp->remote_key_dist &= ~SMP_DIST_ENC_KEY;
1034
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001035 skb_pull(skb, sizeof(*rp));
1036
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001037 hci_dev_lock(hdev);
Marcel Holtmannce39fb42013-10-13 02:23:39 -07001038 authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
Johan Hedberg2ceba532014-06-16 19:25:16 +03001039 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, SMP_LTK,
Johan Hedberg23d0e122014-02-19 14:57:46 +02001040 authenticated, smp->tk, smp->enc_key_size,
1041 rp->ediv, rp->rand);
1042 smp->ltk = ltk;
Johan Hedbergfd349c02014-02-18 10:19:36 +02001043 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001044 smp_distribute_keys(conn);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001045 hci_dev_unlock(hdev);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001046
1047 return 0;
1048}
1049
Johan Hedbergfd349c02014-02-18 10:19:36 +02001050static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
1051{
1052 struct smp_cmd_ident_info *info = (void *) skb->data;
1053 struct smp_chan *smp = conn->smp_chan;
1054
1055 BT_DBG("");
1056
1057 if (skb->len < sizeof(*info))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001058 return SMP_INVALID_PARAMS;
Johan Hedbergfd349c02014-02-18 10:19:36 +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_ID_KEY))
1062 return 0;
1063
Johan Hedbergfd349c02014-02-18 10:19:36 +02001064 skb_pull(skb, sizeof(*info));
1065
1066 memcpy(smp->irk, info->irk, 16);
1067
1068 return 0;
1069}
1070
1071static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
1072 struct sk_buff *skb)
1073{
1074 struct smp_cmd_ident_addr_info *info = (void *) skb->data;
1075 struct smp_chan *smp = conn->smp_chan;
1076 struct hci_conn *hcon = conn->hcon;
1077 bdaddr_t rpa;
1078
1079 BT_DBG("");
1080
1081 if (skb->len < sizeof(*info))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001082 return SMP_INVALID_PARAMS;
Johan Hedbergfd349c02014-02-18 10:19:36 +02001083
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001084 /* Ignore this PDU if it wasn't requested */
1085 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
1086 return 0;
1087
Johan Hedberg9747a9f2014-02-26 23:33:43 +02001088 /* Mark the information as received */
1089 smp->remote_key_dist &= ~SMP_DIST_ID_KEY;
1090
Johan Hedbergfd349c02014-02-18 10:19:36 +02001091 skb_pull(skb, sizeof(*info));
1092
Johan Hedberg31dd6242014-06-27 14:23:02 +03001093 hci_dev_lock(hcon->hdev);
1094
Johan Hedberga9a58f82014-02-25 22:24:37 +02001095 /* Strictly speaking the Core Specification (4.1) allows sending
1096 * an empty address which would force us to rely on just the IRK
1097 * as "identity information". However, since such
1098 * implementations are not known of and in order to not over
1099 * complicate our implementation, simply pretend that we never
1100 * received an IRK for such a device.
1101 */
1102 if (!bacmp(&info->bdaddr, BDADDR_ANY)) {
1103 BT_ERR("Ignoring IRK with no identity address");
Johan Hedberg31dd6242014-06-27 14:23:02 +03001104 goto distribute;
Johan Hedberga9a58f82014-02-25 22:24:37 +02001105 }
1106
Johan Hedbergfd349c02014-02-18 10:19:36 +02001107 bacpy(&smp->id_addr, &info->bdaddr);
1108 smp->id_addr_type = info->addr_type;
1109
1110 if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type))
1111 bacpy(&rpa, &hcon->dst);
1112 else
1113 bacpy(&rpa, BDADDR_ANY);
1114
Johan Hedberg23d0e122014-02-19 14:57:46 +02001115 smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
1116 smp->id_addr_type, smp->irk, &rpa);
Johan Hedbergfd349c02014-02-18 10:19:36 +02001117
Johan Hedberg31dd6242014-06-27 14:23:02 +03001118distribute:
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001119 smp_distribute_keys(conn);
Johan Hedbergfd349c02014-02-18 10:19:36 +02001120
Johan Hedberg31dd6242014-06-27 14:23:02 +03001121 hci_dev_unlock(hcon->hdev);
1122
Johan Hedbergfd349c02014-02-18 10:19:36 +02001123 return 0;
1124}
1125
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001126static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)
1127{
1128 struct smp_cmd_sign_info *rp = (void *) skb->data;
1129 struct smp_chan *smp = conn->smp_chan;
1130 struct hci_dev *hdev = conn->hcon->hdev;
1131 struct smp_csrk *csrk;
1132
1133 BT_DBG("conn %p", conn);
1134
1135 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001136 return SMP_INVALID_PARAMS;
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001137
1138 /* Ignore this PDU if it wasn't requested */
1139 if (!(smp->remote_key_dist & SMP_DIST_SIGN))
1140 return 0;
1141
1142 /* Mark the information as received */
1143 smp->remote_key_dist &= ~SMP_DIST_SIGN;
1144
1145 skb_pull(skb, sizeof(*rp));
1146
1147 hci_dev_lock(hdev);
1148 csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
1149 if (csrk) {
1150 csrk->master = 0x01;
1151 memcpy(csrk->val, rp->csrk, sizeof(csrk->val));
1152 }
1153 smp->csrk = csrk;
1154 if (!(smp->remote_key_dist & SMP_DIST_SIGN))
1155 smp_distribute_keys(conn);
1156 hci_dev_unlock(hdev);
1157
1158 return 0;
1159}
1160
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001161int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
1162{
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001163 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann92381f52013-10-03 01:23:08 -07001164 __u8 code, reason;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001165 int err = 0;
1166
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001167 if (hcon->type != LE_LINK) {
1168 kfree_skb(skb);
Johan Hedberg34327112013-10-16 11:37:01 +03001169 return 0;
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001170 }
1171
Marcel Holtmann92381f52013-10-03 01:23:08 -07001172 if (skb->len < 1) {
1173 kfree_skb(skb);
1174 return -EILSEQ;
1175 }
1176
Marcel Holtmann06ae3312013-10-18 03:43:00 -07001177 if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) {
Andre Guedes2e65c9d2011-06-30 19:20:56 -03001178 err = -ENOTSUPP;
1179 reason = SMP_PAIRING_NOTSUPP;
1180 goto done;
1181 }
1182
Marcel Holtmann92381f52013-10-03 01:23:08 -07001183 code = skb->data[0];
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001184 skb_pull(skb, sizeof(code));
1185
Johan Hedberg8cf9fa12013-01-29 10:44:23 -06001186 /*
1187 * The SMP context must be initialized for all other PDUs except
1188 * pairing and security requests. If we get any other PDU when
1189 * not initialized simply disconnect (done if this function
1190 * returns an error).
1191 */
1192 if (code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ &&
1193 !conn->smp_chan) {
1194 BT_ERR("Unexpected SMP command 0x%02x. Disconnecting.", code);
1195 kfree_skb(skb);
1196 return -ENOTSUPP;
1197 }
1198
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001199 switch (code) {
1200 case SMP_CMD_PAIRING_REQ:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001201 reason = smp_cmd_pairing_req(conn, skb);
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001202 break;
1203
1204 case SMP_CMD_PAIRING_FAIL:
Johan Hedberg84794e12013-11-06 11:24:57 +02001205 smp_failure(conn, 0);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001206 reason = 0;
1207 err = -EPERM;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001208 break;
1209
1210 case SMP_CMD_PAIRING_RSP:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001211 reason = smp_cmd_pairing_rsp(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001212 break;
1213
1214 case SMP_CMD_SECURITY_REQ:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001215 reason = smp_cmd_security_req(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001216 break;
1217
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001218 case SMP_CMD_PAIRING_CONFIRM:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001219 reason = smp_cmd_pairing_confirm(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001220 break;
1221
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001222 case SMP_CMD_PAIRING_RANDOM:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001223 reason = smp_cmd_pairing_random(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001224 break;
1225
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001226 case SMP_CMD_ENCRYPT_INFO:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001227 reason = smp_cmd_encrypt_info(conn, skb);
1228 break;
1229
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001230 case SMP_CMD_MASTER_IDENT:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001231 reason = smp_cmd_master_ident(conn, skb);
1232 break;
1233
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001234 case SMP_CMD_IDENT_INFO:
Johan Hedbergfd349c02014-02-18 10:19:36 +02001235 reason = smp_cmd_ident_info(conn, skb);
1236 break;
1237
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001238 case SMP_CMD_IDENT_ADDR_INFO:
Johan Hedbergfd349c02014-02-18 10:19:36 +02001239 reason = smp_cmd_ident_addr_info(conn, skb);
1240 break;
1241
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001242 case SMP_CMD_SIGN_INFO:
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001243 reason = smp_cmd_sign_info(conn, skb);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001244 break;
1245
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001246 default:
1247 BT_DBG("Unknown command code 0x%2.2x", code);
1248
1249 reason = SMP_CMD_NOTSUPP;
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -03001250 err = -EOPNOTSUPP;
1251 goto done;
1252 }
1253
1254done:
1255 if (reason)
Johan Hedberg84794e12013-11-06 11:24:57 +02001256 smp_failure(conn, reason);
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001257
1258 kfree_skb(skb);
1259 return err;
1260}
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001261
Johan Hedberg35d70272014-02-19 14:57:47 +02001262static void smp_notify_keys(struct l2cap_conn *conn)
1263{
1264 struct smp_chan *smp = conn->smp_chan;
1265 struct hci_conn *hcon = conn->hcon;
1266 struct hci_dev *hdev = hcon->hdev;
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001267 struct smp_cmd_pairing *req = (void *) &smp->preq[1];
1268 struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1];
1269 bool persistent;
Johan Hedberg35d70272014-02-19 14:57:47 +02001270
Johan Hedberg61b1a7f2014-03-20 12:54:16 +02001271 if (smp->remote_irk) {
Johan Hedberg95fbac82014-02-19 15:18:31 +02001272 mgmt_new_irk(hdev, smp->remote_irk);
Johan Hedberg61b1a7f2014-03-20 12:54:16 +02001273 /* Now that user space can be considered to know the
1274 * identity address track the connection based on it
1275 * from now on.
1276 */
1277 bacpy(&hcon->dst, &smp->remote_irk->bdaddr);
1278 hcon->dst_type = smp->remote_irk->addr_type;
1279 l2cap_conn_update_id_addr(hcon);
1280 }
Johan Hedberg95fbac82014-02-19 15:18:31 +02001281
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001282 /* The LTKs and CSRKs should be persistent only if both sides
1283 * had the bonding bit set in their authentication requests.
1284 */
1285 persistent = !!((req->auth_req & rsp->auth_req) & SMP_AUTH_BONDING);
1286
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001287 if (smp->csrk) {
1288 smp->csrk->bdaddr_type = hcon->dst_type;
1289 bacpy(&smp->csrk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001290 mgmt_new_csrk(hdev, smp->csrk, persistent);
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001291 }
1292
1293 if (smp->slave_csrk) {
1294 smp->slave_csrk->bdaddr_type = hcon->dst_type;
1295 bacpy(&smp->slave_csrk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001296 mgmt_new_csrk(hdev, smp->slave_csrk, persistent);
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001297 }
1298
Johan Hedberg35d70272014-02-19 14:57:47 +02001299 if (smp->ltk) {
1300 smp->ltk->bdaddr_type = hcon->dst_type;
1301 bacpy(&smp->ltk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001302 mgmt_new_ltk(hdev, smp->ltk, persistent);
Johan Hedberg35d70272014-02-19 14:57:47 +02001303 }
1304
1305 if (smp->slave_ltk) {
1306 smp->slave_ltk->bdaddr_type = hcon->dst_type;
1307 bacpy(&smp->slave_ltk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001308 mgmt_new_ltk(hdev, smp->slave_ltk, persistent);
Johan Hedberg35d70272014-02-19 14:57:47 +02001309 }
1310}
1311
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001312int smp_distribute_keys(struct l2cap_conn *conn)
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001313{
1314 struct smp_cmd_pairing *req, *rsp;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001315 struct smp_chan *smp = conn->smp_chan;
Johan Hedberg524237c2014-02-22 19:06:31 +02001316 struct hci_conn *hcon = conn->hcon;
1317 struct hci_dev *hdev = hcon->hdev;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001318 __u8 *keydist;
1319
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001320 BT_DBG("conn %p", conn);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001321
Johan Hedberg524237c2014-02-22 19:06:31 +02001322 if (!test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001323 return 0;
1324
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001325 rsp = (void *) &smp->prsp[1];
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001326
1327 /* The responder sends its keys first */
Johan Hedbergefabba32014-02-26 23:33:44 +02001328 if (hcon->out && (smp->remote_key_dist & 0x07))
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001329 return 0;
1330
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001331 req = (void *) &smp->preq[1];
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001332
Johan Hedberg524237c2014-02-22 19:06:31 +02001333 if (hcon->out) {
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001334 keydist = &rsp->init_key_dist;
1335 *keydist &= req->init_key_dist;
1336 } else {
1337 keydist = &rsp->resp_key_dist;
1338 *keydist &= req->resp_key_dist;
1339 }
1340
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001341 BT_DBG("keydist 0x%x", *keydist);
1342
1343 if (*keydist & SMP_DIST_ENC_KEY) {
1344 struct smp_cmd_encrypt_info enc;
1345 struct smp_cmd_master_ident ident;
Johan Hedberg23d0e122014-02-19 14:57:46 +02001346 struct smp_ltk *ltk;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001347 u8 authenticated;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001348 __le16 ediv;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001349 __le64 rand;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001350
1351 get_random_bytes(enc.ltk, sizeof(enc.ltk));
1352 get_random_bytes(&ediv, sizeof(ediv));
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001353 get_random_bytes(&rand, sizeof(rand));
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001354
1355 smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
1356
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001357 authenticated = hcon->sec_level == BT_SECURITY_HIGH;
Johan Hedberg524237c2014-02-22 19:06:31 +02001358 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type,
Johan Hedberg2ceba532014-06-16 19:25:16 +03001359 SMP_LTK_SLAVE, authenticated, enc.ltk,
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001360 smp->enc_key_size, ediv, rand);
Johan Hedberg23d0e122014-02-19 14:57:46 +02001361 smp->slave_ltk = ltk;
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001362
Andrei Emeltchenko58115372012-03-12 12:13:06 +02001363 ident.ediv = ediv;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001364 ident.rand = rand;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001365
1366 smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident);
1367
1368 *keydist &= ~SMP_DIST_ENC_KEY;
1369 }
1370
1371 if (*keydist & SMP_DIST_ID_KEY) {
1372 struct smp_cmd_ident_addr_info addrinfo;
1373 struct smp_cmd_ident_info idinfo;
1374
Johan Hedberg863efaf2014-02-22 19:06:32 +02001375 memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk));
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001376
1377 smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo);
1378
Johan Hedberg82d4b352014-02-23 19:42:18 +02001379 /* The hci_conn contains the local identity address
1380 * after the connection has been established.
1381 *
1382 * This is true even when the connection has been
1383 * established using a resolvable random address.
1384 */
Johan Hedberg524237c2014-02-22 19:06:31 +02001385 bacpy(&addrinfo.bdaddr, &hcon->src);
Johan Hedberg82d4b352014-02-23 19:42:18 +02001386 addrinfo.addr_type = hcon->src_type;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001387
1388 smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo),
Marcel Holtmannf1560462013-10-13 05:43:25 -07001389 &addrinfo);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001390
1391 *keydist &= ~SMP_DIST_ID_KEY;
1392 }
1393
1394 if (*keydist & SMP_DIST_SIGN) {
1395 struct smp_cmd_sign_info sign;
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001396 struct smp_csrk *csrk;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001397
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001398 /* Generate a new random key */
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001399 get_random_bytes(sign.csrk, sizeof(sign.csrk));
1400
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001401 csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
1402 if (csrk) {
1403 csrk->master = 0x00;
1404 memcpy(csrk->val, sign.csrk, sizeof(csrk->val));
1405 }
1406 smp->slave_csrk = csrk;
1407
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001408 smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign);
1409
1410 *keydist &= ~SMP_DIST_SIGN;
1411 }
1412
Johan Hedbergefabba32014-02-26 23:33:44 +02001413 /* If there are still keys to be received wait for them */
1414 if ((smp->remote_key_dist & 0x07))
1415 return 0;
1416
Johan Hedberg1d98bf42014-03-24 14:39:08 +02001417 clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags);
1418 cancel_delayed_work_sync(&conn->security_timer);
Johan Hedberg4a74d652014-05-20 09:45:50 +03001419 set_bit(SMP_FLAG_COMPLETE, &smp->flags);
Johan Hedberg1d98bf42014-03-24 14:39:08 +02001420 smp_notify_keys(conn);
Johan Hedbergefabba32014-02-26 23:33:44 +02001421
Johan Hedberg1d98bf42014-03-24 14:39:08 +02001422 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001423
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001424 return 0;
1425}