blob: 39ca9616d2de6804a6d65d894adfe9affc6cf814 [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
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300175static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16],
Marcel Holtmannf1560462013-10-13 05:43:25 -0700176 u8 preq[7], u8 pres[7], u8 _iat, bdaddr_t *ia,
177 u8 _rat, bdaddr_t *ra, u8 res[16])
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300178{
179 u8 p1[16], p2[16];
180 int err;
181
182 memset(p1, 0, 16);
183
184 /* p1 = pres || preq || _rat || _iat */
Johan Hedberg943a7322014-03-18 12:58:24 +0200185 p1[0] = _iat;
186 p1[1] = _rat;
187 memcpy(p1 + 2, preq, 7);
188 memcpy(p1 + 9, pres, 7);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300189
190 /* p2 = padding || ia || ra */
Johan Hedberg943a7322014-03-18 12:58:24 +0200191 memcpy(p2, ra, 6);
192 memcpy(p2 + 6, ia, 6);
193 memset(p2 + 12, 0, 4);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300194
195 /* res = r XOR p1 */
196 u128_xor((u128 *) res, (u128 *) r, (u128 *) p1);
197
198 /* res = e(k, res) */
199 err = smp_e(tfm, k, res);
200 if (err) {
201 BT_ERR("Encrypt data error");
202 return err;
203 }
204
205 /* res = res XOR p2 */
206 u128_xor((u128 *) res, (u128 *) res, (u128 *) p2);
207
208 /* res = e(k, res) */
209 err = smp_e(tfm, k, res);
210 if (err)
211 BT_ERR("Encrypt data error");
212
213 return err;
214}
215
Marcel Holtmannf1560462013-10-13 05:43:25 -0700216static int smp_s1(struct crypto_blkcipher *tfm, u8 k[16], u8 r1[16],
217 u8 r2[16], u8 _r[16])
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300218{
219 int err;
220
221 /* Just least significant octets from r1 and r2 are considered */
Johan Hedberg943a7322014-03-18 12:58:24 +0200222 memcpy(_r, r2, 8);
223 memcpy(_r + 8, r1, 8);
Anderson Brigliad22ef0b2011-06-09 18:50:44 -0300224
225 err = smp_e(tfm, k, _r);
226 if (err)
227 BT_ERR("Encrypt data error");
228
229 return err;
230}
231
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300232static struct sk_buff *smp_build_cmd(struct l2cap_conn *conn, u8 code,
Marcel Holtmannf1560462013-10-13 05:43:25 -0700233 u16 dlen, void *data)
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300234{
235 struct sk_buff *skb;
236 struct l2cap_hdr *lh;
237 int len;
238
239 len = L2CAP_HDR_SIZE + sizeof(code) + dlen;
240
241 if (len > conn->mtu)
242 return NULL;
243
244 skb = bt_skb_alloc(len, GFP_ATOMIC);
245 if (!skb)
246 return NULL;
247
248 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
249 lh->len = cpu_to_le16(sizeof(code) + dlen);
Joe Perchesdcf4adb2014-03-12 10:52:35 -0700250 lh->cid = cpu_to_le16(L2CAP_CID_SMP);
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300251
252 memcpy(skb_put(skb, sizeof(code)), &code, sizeof(code));
253
254 memcpy(skb_put(skb, dlen), data, dlen);
255
256 return skb;
257}
258
259static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
260{
261 struct sk_buff *skb = smp_build_cmd(conn, code, len, data);
262
263 BT_DBG("code 0x%2.2x", code);
264
265 if (!skb)
266 return;
267
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200268 skb->priority = HCI_PRIO_MAX;
269 hci_send_acl(conn->hchan, skb, 0);
Vinicius Costa Gomese2dcd112011-08-19 21:06:50 -0300270
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -0200271 cancel_delayed_work_sync(&conn->security_timer);
Marcel Holtmann17b02e62012-03-01 14:32:37 -0800272 schedule_delayed_work(&conn->security_timer, SMP_TIMEOUT);
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300273}
274
Brian Gix2b64d152011-12-21 16:12:12 -0800275static __u8 authreq_to_seclevel(__u8 authreq)
276{
277 if (authreq & SMP_AUTH_MITM)
278 return BT_SECURITY_HIGH;
279 else
280 return BT_SECURITY_MEDIUM;
281}
282
283static __u8 seclevel_to_authreq(__u8 sec_level)
284{
285 switch (sec_level) {
286 case BT_SECURITY_HIGH:
287 return SMP_AUTH_MITM | SMP_AUTH_BONDING;
288 case BT_SECURITY_MEDIUM:
289 return SMP_AUTH_BONDING;
290 default:
291 return SMP_AUTH_NONE;
292 }
293}
294
Vinicius Costa Gomesb8e66ea2011-06-09 18:50:52 -0300295static void build_pairing_cmd(struct l2cap_conn *conn,
Marcel Holtmannf1560462013-10-13 05:43:25 -0700296 struct smp_cmd_pairing *req,
297 struct smp_cmd_pairing *rsp, __u8 authreq)
Vinicius Costa Gomesb8e66ea2011-06-09 18:50:52 -0300298{
Johan Hedbergfd349c02014-02-18 10:19:36 +0200299 struct smp_chan *smp = conn->smp_chan;
300 struct hci_conn *hcon = conn->hcon;
301 struct hci_dev *hdev = hcon->hdev;
302 u8 local_dist = 0, remote_dist = 0;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300303
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200304 if (test_bit(HCI_PAIRABLE, &conn->hcon->hdev->dev_flags)) {
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -0700305 local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
306 remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300307 authreq |= SMP_AUTH_BONDING;
Brian Gix2b64d152011-12-21 16:12:12 -0800308 } else {
309 authreq &= ~SMP_AUTH_BONDING;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300310 }
311
Johan Hedbergfd349c02014-02-18 10:19:36 +0200312 if (test_bit(HCI_RPA_RESOLVING, &hdev->dev_flags))
313 remote_dist |= SMP_DIST_ID_KEY;
314
Johan Hedberg863efaf2014-02-22 19:06:32 +0200315 if (test_bit(HCI_PRIVACY, &hdev->dev_flags))
316 local_dist |= SMP_DIST_ID_KEY;
317
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300318 if (rsp == NULL) {
319 req->io_capability = conn->hcon->io_capability;
320 req->oob_flag = SMP_OOB_NOT_PRESENT;
321 req->max_key_size = SMP_MAX_ENC_KEY_SIZE;
Johan Hedbergfd349c02014-02-18 10:19:36 +0200322 req->init_key_dist = local_dist;
323 req->resp_key_dist = remote_dist;
Johan Hedberg065a13e2012-10-11 16:26:06 +0200324 req->auth_req = (authreq & AUTH_REQ_MASK);
Johan Hedbergfd349c02014-02-18 10:19:36 +0200325
326 smp->remote_key_dist = remote_dist;
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300327 return;
328 }
329
330 rsp->io_capability = conn->hcon->io_capability;
331 rsp->oob_flag = SMP_OOB_NOT_PRESENT;
332 rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE;
Johan Hedbergfd349c02014-02-18 10:19:36 +0200333 rsp->init_key_dist = req->init_key_dist & remote_dist;
334 rsp->resp_key_dist = req->resp_key_dist & local_dist;
Johan Hedberg065a13e2012-10-11 16:26:06 +0200335 rsp->auth_req = (authreq & AUTH_REQ_MASK);
Johan Hedbergfd349c02014-02-18 10:19:36 +0200336
337 smp->remote_key_dist = rsp->init_key_dist;
Vinicius Costa Gomesb8e66ea2011-06-09 18:50:52 -0300338}
339
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300340static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
341{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300342 struct smp_chan *smp = conn->smp_chan;
343
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300344 if ((max_key_size > SMP_MAX_ENC_KEY_SIZE) ||
Marcel Holtmannf1560462013-10-13 05:43:25 -0700345 (max_key_size < SMP_MIN_ENC_KEY_SIZE))
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300346 return SMP_ENC_KEY_SIZE;
347
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300348 smp->enc_key_size = max_key_size;
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300349
350 return 0;
351}
352
Johan Hedberg84794e12013-11-06 11:24:57 +0200353static void smp_failure(struct l2cap_conn *conn, u8 reason)
Brian Gix4f957a72011-11-23 08:28:36 -0800354{
Johan Hedbergbab73cb2012-02-09 16:07:29 +0200355 struct hci_conn *hcon = conn->hcon;
356
Johan Hedberg84794e12013-11-06 11:24:57 +0200357 if (reason)
Brian Gix4f957a72011-11-23 08:28:36 -0800358 smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
Marcel Holtmannf1560462013-10-13 05:43:25 -0700359 &reason);
Brian Gix4f957a72011-11-23 08:28:36 -0800360
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700361 clear_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags);
362 mgmt_auth_failed(hcon->hdev, &hcon->dst, hcon->type, hcon->dst_type,
363 HCI_ERROR_AUTH_FAILURE);
Vinicius Costa Gomesf1c09c02012-02-01 18:27:56 -0300364
Andre Guedes61a0cfb2012-08-01 20:34:15 -0300365 cancel_delayed_work_sync(&conn->security_timer);
366
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700367 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesf1c09c02012-02-01 18:27:56 -0300368 smp_chan_destroy(conn);
Brian Gix4f957a72011-11-23 08:28:36 -0800369}
370
Brian Gix2b64d152011-12-21 16:12:12 -0800371#define JUST_WORKS 0x00
372#define JUST_CFM 0x01
373#define REQ_PASSKEY 0x02
374#define CFM_PASSKEY 0x03
375#define REQ_OOB 0x04
376#define OVERLAP 0xFF
377
378static const u8 gen_method[5][5] = {
379 { JUST_WORKS, JUST_CFM, REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
380 { JUST_WORKS, JUST_CFM, REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
381 { CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
382 { JUST_WORKS, JUST_CFM, JUST_WORKS, JUST_WORKS, JUST_CFM },
383 { CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, OVERLAP },
384};
385
Johan Hedberg581370c2014-06-17 13:07:38 +0300386static u8 get_auth_method(struct smp_chan *smp, u8 local_io, u8 remote_io)
387{
388 /* If either side has unknown io_caps, use JUST WORKS */
389 if (local_io > SMP_IO_KEYBOARD_DISPLAY ||
390 remote_io > SMP_IO_KEYBOARD_DISPLAY)
391 return JUST_WORKS;
392
393 return gen_method[remote_io][local_io];
394}
395
Brian Gix2b64d152011-12-21 16:12:12 -0800396static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
397 u8 local_io, u8 remote_io)
398{
399 struct hci_conn *hcon = conn->hcon;
400 struct smp_chan *smp = conn->smp_chan;
401 u8 method;
402 u32 passkey = 0;
403 int ret = 0;
404
405 /* Initialize key for JUST WORKS */
406 memset(smp->tk, 0, sizeof(smp->tk));
Johan Hedberg4a74d652014-05-20 09:45:50 +0300407 clear_bit(SMP_FLAG_TK_VALID, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800408
409 BT_DBG("tk_request: auth:%d lcl:%d rem:%d", auth, local_io, remote_io);
410
411 /* If neither side wants MITM, use JUST WORKS */
Brian Gix2b64d152011-12-21 16:12:12 -0800412 /* Otherwise, look up method from the table */
Johan Hedberg581370c2014-06-17 13:07:38 +0300413 if (!(auth & SMP_AUTH_MITM))
Brian Gix2b64d152011-12-21 16:12:12 -0800414 method = JUST_WORKS;
415 else
Johan Hedberg581370c2014-06-17 13:07:38 +0300416 method = get_auth_method(smp, local_io, remote_io);
Brian Gix2b64d152011-12-21 16:12:12 -0800417
418 /* If not bonding, don't ask user to confirm a Zero TK */
419 if (!(auth & SMP_AUTH_BONDING) && method == JUST_CFM)
420 method = JUST_WORKS;
421
Johan Hedberga82505c2014-03-24 14:39:07 +0200422 /* Don't confirm locally initiated pairing attempts */
Johan Hedberg4a74d652014-05-20 09:45:50 +0300423 if (method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR, &smp->flags))
Johan Hedberga82505c2014-03-24 14:39:07 +0200424 method = JUST_WORKS;
425
Brian Gix2b64d152011-12-21 16:12:12 -0800426 /* If Just Works, Continue with Zero TK */
427 if (method == JUST_WORKS) {
Johan Hedberg4a74d652014-05-20 09:45:50 +0300428 set_bit(SMP_FLAG_TK_VALID, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800429 return 0;
430 }
431
432 /* Not Just Works/Confirm results in MITM Authentication */
433 if (method != JUST_CFM)
Johan Hedberg4a74d652014-05-20 09:45:50 +0300434 set_bit(SMP_FLAG_MITM_AUTH, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800435
436 /* If both devices have Keyoard-Display I/O, the master
437 * Confirms and the slave Enters the passkey.
438 */
439 if (method == OVERLAP) {
Johan Hedberg4dae2792014-06-24 17:03:50 +0300440 if (test_bit(HCI_CONN_MASTER, &hcon->flags))
Brian Gix2b64d152011-12-21 16:12:12 -0800441 method = CFM_PASSKEY;
442 else
443 method = REQ_PASSKEY;
444 }
445
Johan Hedberg01ad34d2014-03-19 14:14:53 +0200446 /* Generate random passkey. */
Brian Gix2b64d152011-12-21 16:12:12 -0800447 if (method == CFM_PASSKEY) {
Johan Hedberg943a7322014-03-18 12:58:24 +0200448 memset(smp->tk, 0, sizeof(smp->tk));
Brian Gix2b64d152011-12-21 16:12:12 -0800449 get_random_bytes(&passkey, sizeof(passkey));
450 passkey %= 1000000;
Johan Hedberg943a7322014-03-18 12:58:24 +0200451 put_unaligned_le32(passkey, smp->tk);
Brian Gix2b64d152011-12-21 16:12:12 -0800452 BT_DBG("PassKey: %d", passkey);
Johan Hedberg4a74d652014-05-20 09:45:50 +0300453 set_bit(SMP_FLAG_TK_VALID, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800454 }
455
456 hci_dev_lock(hcon->hdev);
457
458 if (method == REQ_PASSKEY)
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700459 ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200460 hcon->type, hcon->dst_type);
Johan Hedberg4eb65e62014-03-24 14:39:05 +0200461 else if (method == JUST_CFM)
462 ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
463 hcon->type, hcon->dst_type,
464 passkey, 1);
Brian Gix2b64d152011-12-21 16:12:12 -0800465 else
Johan Hedberg01ad34d2014-03-19 14:14:53 +0200466 ret = mgmt_user_passkey_notify(hcon->hdev, &hcon->dst,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200467 hcon->type, hcon->dst_type,
Johan Hedberg39adbff2014-03-20 08:18:14 +0200468 passkey, 0);
Brian Gix2b64d152011-12-21 16:12:12 -0800469
470 hci_dev_unlock(hcon->hdev);
471
472 return ret;
473}
474
Johan Hedberg1cc61142014-05-20 09:45:52 +0300475static u8 smp_confirm(struct smp_chan *smp)
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300476{
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300477 struct l2cap_conn *conn = smp->conn;
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200478 struct hci_dev *hdev = conn->hcon->hdev;
479 struct crypto_blkcipher *tfm = hdev->tfm_aes;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300480 struct smp_cmd_pairing_confirm cp;
481 int ret;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300482
483 BT_DBG("conn %p", conn);
484
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200485 /* Prevent mutual access to hdev->tfm_aes */
486 hci_dev_lock(hdev);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300487
Johan Hedbergb1cd5fd2014-02-28 12:54:17 +0200488 ret = smp_c1(tfm, smp->tk, smp->prnd, smp->preq, smp->prsp,
489 conn->hcon->init_addr_type, &conn->hcon->init_addr,
Johan Hedberg943a7322014-03-18 12:58:24 +0200490 conn->hcon->resp_addr_type, &conn->hcon->resp_addr,
491 cp.confirm_val);
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200492
493 hci_dev_unlock(hdev);
494
Johan Hedberg1cc61142014-05-20 09:45:52 +0300495 if (ret)
496 return SMP_UNSPECIFIED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300497
Johan Hedberg4a74d652014-05-20 09:45:50 +0300498 clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800499
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300500 smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
501
Johan Hedberg1cc61142014-05-20 09:45:52 +0300502 return 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300503}
504
Johan Hedberg861580a2014-05-20 09:45:51 +0300505static u8 smp_random(struct smp_chan *smp)
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300506{
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300507 struct l2cap_conn *conn = smp->conn;
508 struct hci_conn *hcon = conn->hcon;
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200509 struct hci_dev *hdev = hcon->hdev;
510 struct crypto_blkcipher *tfm = hdev->tfm_aes;
Johan Hedberg861580a2014-05-20 09:45:51 +0300511 u8 confirm[16];
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300512 int ret;
513
Johan Hedberg861580a2014-05-20 09:45:51 +0300514 if (IS_ERR_OR_NULL(tfm))
515 return SMP_UNSPECIFIED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300516
517 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
518
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200519 /* Prevent mutual access to hdev->tfm_aes */
520 hci_dev_lock(hdev);
521
Johan Hedbergb1cd5fd2014-02-28 12:54:17 +0200522 ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp,
523 hcon->init_addr_type, &hcon->init_addr,
Johan Hedberg943a7322014-03-18 12:58:24 +0200524 hcon->resp_addr_type, &hcon->resp_addr, confirm);
Johan Hedberg893ce8b2014-02-18 21:41:31 +0200525
526 hci_dev_unlock(hdev);
527
Johan Hedberg861580a2014-05-20 09:45:51 +0300528 if (ret)
529 return SMP_UNSPECIFIED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300530
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300531 if (memcmp(smp->pcnf, confirm, sizeof(smp->pcnf)) != 0) {
532 BT_ERR("Pairing failed (confirmation values mismatch)");
Johan Hedberg861580a2014-05-20 09:45:51 +0300533 return SMP_CONFIRM_FAILED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300534 }
535
536 if (hcon->out) {
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -0800537 u8 stk[16];
538 __le64 rand = 0;
539 __le16 ediv = 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300540
Johan Hedberg943a7322014-03-18 12:58:24 +0200541 smp_s1(tfm, smp->tk, smp->rrnd, smp->prnd, stk);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300542
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300543 memset(stk + smp->enc_key_size, 0,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300544 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300545
Johan Hedberg861580a2014-05-20 09:45:51 +0300546 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
547 return SMP_UNSPECIFIED;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300548
549 hci_le_start_enc(hcon, ediv, rand, stk);
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300550 hcon->enc_key_size = smp->enc_key_size;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300551 } else {
Johan Hedbergfff34902014-06-10 15:19:50 +0300552 u8 stk[16], auth;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -0800553 __le64 rand = 0;
554 __le16 ediv = 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300555
Johan Hedberg943a7322014-03-18 12:58:24 +0200556 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
557 smp->prnd);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300558
Johan Hedberg943a7322014-03-18 12:58:24 +0200559 smp_s1(tfm, smp->tk, smp->prnd, smp->rrnd, stk);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300560
Vinicius Costa Gomesf7aa6112012-01-30 19:29:12 -0300561 memset(stk + smp->enc_key_size, 0,
Marcel Holtmannf1560462013-10-13 05:43:25 -0700562 SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300563
Johan Hedbergfff34902014-06-10 15:19:50 +0300564 if (hcon->pending_sec_level == BT_SECURITY_HIGH)
565 auth = 1;
566 else
567 auth = 0;
568
Johan Hedberg7d5843b2014-06-16 19:25:15 +0300569 /* Even though there's no _SLAVE suffix this is the
570 * slave STK we're adding for later lookup (the master
571 * STK never needs to be stored).
572 */
Marcel Holtmannce39fb42013-10-13 02:23:39 -0700573 hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
Johan Hedberg2ceba532014-06-16 19:25:16 +0300574 SMP_STK, auth, stk, smp->enc_key_size, ediv, rand);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300575 }
576
Johan Hedberg861580a2014-05-20 09:45:51 +0300577 return 0;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300578}
579
580static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
581{
582 struct smp_chan *smp;
583
Marcel Holtmannf1560462013-10-13 05:43:25 -0700584 smp = kzalloc(sizeof(*smp), GFP_ATOMIC);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300585 if (!smp)
586 return NULL;
587
Johan Hedberg6a7bd102014-06-27 14:23:03 +0300588 smp->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
589 if (IS_ERR(smp->tfm_aes)) {
590 BT_ERR("Unable to create ECB crypto context");
591 kfree(smp);
592 return NULL;
593 }
594
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300595 smp->conn = conn;
596 conn->smp_chan = smp;
Brian Gix2b64d152011-12-21 16:12:12 -0800597 conn->hcon->smp_conn = conn;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300598
599 hci_conn_hold(conn->hcon);
600
601 return smp;
602}
603
604void smp_chan_destroy(struct l2cap_conn *conn)
605{
Brian Gixc8eb9692011-11-23 08:28:35 -0800606 struct smp_chan *smp = conn->smp_chan;
Johan Hedbergf4a407b2014-02-18 21:41:34 +0200607 bool complete;
Brian Gixc8eb9692011-11-23 08:28:35 -0800608
Vinicius Costa Gomesf1c09c02012-02-01 18:27:56 -0300609 BUG_ON(!smp);
Brian Gixc8eb9692011-11-23 08:28:35 -0800610
Johan Hedberg4a74d652014-05-20 09:45:50 +0300611 complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags);
Johan Hedbergf4a407b2014-02-18 21:41:34 +0200612 mgmt_smp_complete(conn->hcon, complete);
613
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -0700614 kfree(smp->csrk);
615 kfree(smp->slave_csrk);
616
Johan Hedberg6a7bd102014-06-27 14:23:03 +0300617 crypto_free_blkcipher(smp->tfm_aes);
618
Johan Hedberg759331d2014-02-28 10:10:16 +0200619 /* If pairing failed clean up any keys we might have */
620 if (!complete) {
621 if (smp->ltk) {
622 list_del(&smp->ltk->list);
623 kfree(smp->ltk);
624 }
625
626 if (smp->slave_ltk) {
627 list_del(&smp->slave_ltk->list);
628 kfree(smp->slave_ltk);
629 }
630
631 if (smp->remote_irk) {
632 list_del(&smp->remote_irk->list);
633 kfree(smp->remote_irk);
634 }
635 }
636
Brian Gixc8eb9692011-11-23 08:28:35 -0800637 kfree(smp);
638 conn->smp_chan = NULL;
Brian Gix2b64d152011-12-21 16:12:12 -0800639 conn->hcon->smp_conn = NULL;
David Herrmann76a68ba2013-04-06 20:28:37 +0200640 hci_conn_drop(conn->hcon);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300641}
642
Brian Gix2b64d152011-12-21 16:12:12 -0800643int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
644{
645 struct l2cap_conn *conn = hcon->smp_conn;
646 struct smp_chan *smp;
647 u32 value;
Brian Gix2b64d152011-12-21 16:12:12 -0800648
649 BT_DBG("");
650
651 if (!conn)
652 return -ENOTCONN;
653
654 smp = conn->smp_chan;
655
656 switch (mgmt_op) {
657 case MGMT_OP_USER_PASSKEY_REPLY:
658 value = le32_to_cpu(passkey);
Johan Hedberg943a7322014-03-18 12:58:24 +0200659 memset(smp->tk, 0, sizeof(smp->tk));
Brian Gix2b64d152011-12-21 16:12:12 -0800660 BT_DBG("PassKey: %d", value);
Johan Hedberg943a7322014-03-18 12:58:24 +0200661 put_unaligned_le32(value, smp->tk);
Brian Gix2b64d152011-12-21 16:12:12 -0800662 /* Fall Through */
663 case MGMT_OP_USER_CONFIRM_REPLY:
Johan Hedberg4a74d652014-05-20 09:45:50 +0300664 set_bit(SMP_FLAG_TK_VALID, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800665 break;
666 case MGMT_OP_USER_PASSKEY_NEG_REPLY:
667 case MGMT_OP_USER_CONFIRM_NEG_REPLY:
Johan Hedberg84794e12013-11-06 11:24:57 +0200668 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
Brian Gix2b64d152011-12-21 16:12:12 -0800669 return 0;
670 default:
Johan Hedberg84794e12013-11-06 11:24:57 +0200671 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
Brian Gix2b64d152011-12-21 16:12:12 -0800672 return -EOPNOTSUPP;
673 }
674
675 /* If it is our turn to send Pairing Confirm, do so now */
Johan Hedberg1cc61142014-05-20 09:45:52 +0300676 if (test_bit(SMP_FLAG_CFM_PENDING, &smp->flags)) {
677 u8 rsp = smp_confirm(smp);
678 if (rsp)
679 smp_failure(conn, rsp);
680 }
Brian Gix2b64d152011-12-21 16:12:12 -0800681
682 return 0;
683}
684
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300685static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300686{
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300687 struct smp_cmd_pairing rsp, *req = (void *) skb->data;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300688 struct smp_chan *smp;
Johan Hedbergc7262e72014-06-17 13:07:37 +0300689 u8 key_size, auth, sec_level;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300690 int ret;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300691
692 BT_DBG("conn %p", conn);
693
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200694 if (skb->len < sizeof(*req))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300695 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200696
Johan Hedberg4dae2792014-06-24 17:03:50 +0300697 if (test_bit(HCI_CONN_MASTER, &conn->hcon->flags))
Brian Gix2b64d152011-12-21 16:12:12 -0800698 return SMP_CMD_NOTSUPP;
699
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200700 if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags))
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300701 smp = smp_chan_create(conn);
Andrei Emeltchenkod08fd0e2012-07-19 17:03:43 +0300702 else
703 smp = conn->smp_chan;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300704
Andrei Emeltchenkod08fd0e2012-07-19 17:03:43 +0300705 if (!smp)
706 return SMP_UNSPECIFIED;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300707
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300708 smp->preq[0] = SMP_CMD_PAIRING_REQ;
709 memcpy(&smp->preq[1], req, sizeof(*req));
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300710 skb_pull(skb, sizeof(*req));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300711
Brian Gix2b64d152011-12-21 16:12:12 -0800712 /* We didn't start the pairing, so match remote */
Johan Hedberg1ef35822014-05-20 09:45:48 +0300713 auth = req->auth_req;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300714
Johan Hedbergc7262e72014-06-17 13:07:37 +0300715 sec_level = authreq_to_seclevel(auth);
716 if (sec_level > conn->hcon->pending_sec_level)
717 conn->hcon->pending_sec_level = sec_level;
Ido Yarivfdde0a22012-03-05 20:09:38 +0200718
Johan Hedberg2ed8f652014-06-17 13:07:39 +0300719 /* If we need MITM check that it can be acheived */
720 if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
721 u8 method;
722
723 method = get_auth_method(smp, conn->hcon->io_capability,
724 req->io_capability);
725 if (method == JUST_WORKS || method == JUST_CFM)
726 return SMP_AUTH_REQUIREMENTS;
727 }
728
Brian Gix2b64d152011-12-21 16:12:12 -0800729 build_pairing_cmd(conn, req, &rsp, auth);
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300730
731 key_size = min(req->max_key_size, rsp.max_key_size);
732 if (check_enc_key_size(conn, key_size))
733 return SMP_ENC_KEY_SIZE;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300734
Johan Hedberge84a6b12013-12-02 10:49:03 +0200735 get_random_bytes(smp->prnd, sizeof(smp->prnd));
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300736
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300737 smp->prsp[0] = SMP_CMD_PAIRING_RSP;
738 memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300739
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300740 smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300741
Brian Gix2b64d152011-12-21 16:12:12 -0800742 /* Request setup of TK */
743 ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability);
744 if (ret)
745 return SMP_UNSPECIFIED;
746
Johan Hedberg4a74d652014-05-20 09:45:50 +0300747 clear_bit(SMP_FLAG_INITIATOR, &smp->flags);
Johan Hedbergedca7922014-03-24 15:54:11 +0200748
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300749 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300750}
751
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300752static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300753{
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300754 struct smp_cmd_pairing *req, *rsp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300755 struct smp_chan *smp = conn->smp_chan;
Brian Gix2b64d152011-12-21 16:12:12 -0800756 u8 key_size, auth = SMP_AUTH_NONE;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300757 int ret;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300758
759 BT_DBG("conn %p", conn);
760
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200761 if (skb->len < sizeof(*rsp))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300762 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200763
Johan Hedberg4dae2792014-06-24 17:03:50 +0300764 if (!test_bit(HCI_CONN_MASTER, &conn->hcon->flags))
Brian Gix2b64d152011-12-21 16:12:12 -0800765 return SMP_CMD_NOTSUPP;
766
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300767 skb_pull(skb, sizeof(*rsp));
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300768
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300769 req = (void *) &smp->preq[1];
Vinicius Costa Gomes3158c502011-06-14 13:37:42 -0300770
771 key_size = min(req->max_key_size, rsp->max_key_size);
772 if (check_enc_key_size(conn, key_size))
773 return SMP_ENC_KEY_SIZE;
774
Johan Hedberg2ed8f652014-06-17 13:07:39 +0300775 /* If we need MITM check that it can be acheived */
776 if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
777 u8 method;
778
779 method = get_auth_method(smp, req->io_capability,
780 rsp->io_capability);
781 if (method == JUST_WORKS || method == JUST_CFM)
782 return SMP_AUTH_REQUIREMENTS;
783 }
784
Johan Hedberge84a6b12013-12-02 10:49:03 +0200785 get_random_bytes(smp->prnd, sizeof(smp->prnd));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300786
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300787 smp->prsp[0] = SMP_CMD_PAIRING_RSP;
788 memcpy(&smp->prsp[1], rsp, sizeof(*rsp));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300789
Johan Hedbergfdcc4be2014-03-14 10:53:50 +0200790 /* Update remote key distribution in case the remote cleared
791 * some bits that we had enabled in our request.
792 */
793 smp->remote_key_dist &= rsp->resp_key_dist;
794
Brian Gix2b64d152011-12-21 16:12:12 -0800795 if ((req->auth_req & SMP_AUTH_BONDING) &&
Marcel Holtmannf1560462013-10-13 05:43:25 -0700796 (rsp->auth_req & SMP_AUTH_BONDING))
Brian Gix2b64d152011-12-21 16:12:12 -0800797 auth = SMP_AUTH_BONDING;
798
799 auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM;
800
Johan Hedberg476585e2012-06-06 18:54:15 +0800801 ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability);
Brian Gix2b64d152011-12-21 16:12:12 -0800802 if (ret)
803 return SMP_UNSPECIFIED;
804
Johan Hedberg4a74d652014-05-20 09:45:50 +0300805 set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
Brian Gix2b64d152011-12-21 16:12:12 -0800806
807 /* Can't compose response until we have been confirmed */
Johan Hedberg4a74d652014-05-20 09:45:50 +0300808 if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
Johan Hedberg1cc61142014-05-20 09:45:52 +0300809 return smp_confirm(smp);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300810
811 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300812}
813
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300814static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300815{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300816 struct smp_chan *smp = conn->smp_chan;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300817
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300818 BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
819
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200820 if (skb->len < sizeof(smp->pcnf))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300821 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200822
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300823 memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf));
824 skb_pull(skb, sizeof(smp->pcnf));
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300825
Johan Hedberg943a7322014-03-18 12:58:24 +0200826 if (conn->hcon->out)
827 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
828 smp->prnd);
Johan Hedberg4a74d652014-05-20 09:45:50 +0300829 else if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
Johan Hedberg1cc61142014-05-20 09:45:52 +0300830 return smp_confirm(smp);
Johan Hedberg943a7322014-03-18 12:58:24 +0200831 else
Johan Hedberg4a74d652014-05-20 09:45:50 +0300832 set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300833
834 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300835}
836
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300837static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300838{
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300839 struct smp_chan *smp = conn->smp_chan;
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300840
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300841 BT_DBG("conn %p", conn);
Anderson Briglia7d24ddc2011-06-09 18:50:46 -0300842
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200843 if (skb->len < sizeof(smp->rrnd))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300844 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200845
Johan Hedberg943a7322014-03-18 12:58:24 +0200846 memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd));
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300847 skb_pull(skb, sizeof(smp->rrnd));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300848
Johan Hedberg861580a2014-05-20 09:45:51 +0300849 return smp_random(smp);
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300850}
851
Johan Hedberg4dab7862012-06-07 14:58:37 +0800852static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300853{
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300854 struct smp_ltk *key;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300855 struct hci_conn *hcon = conn->hcon;
856
Johan Hedberg98a0b842014-01-30 19:40:00 -0800857 key = hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type,
858 hcon->out);
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300859 if (!key)
860 return 0;
861
Johan Hedberg4dab7862012-06-07 14:58:37 +0800862 if (sec_level > BT_SECURITY_MEDIUM && !key->authenticated)
863 return 0;
864
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200865 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300866 return 1;
867
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -0300868 hci_le_start_enc(hcon, key->ediv, key->rand, key->val);
869 hcon->enc_key_size = key->enc_size;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300870
871 return 1;
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300872}
Marcel Holtmannf1560462013-10-13 05:43:25 -0700873
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300874static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300875{
876 struct smp_cmd_security_req *rp = (void *) skb->data;
877 struct smp_cmd_pairing cp;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300878 struct hci_conn *hcon = conn->hcon;
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300879 struct smp_chan *smp;
Johan Hedbergc7262e72014-06-17 13:07:37 +0300880 u8 sec_level;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300881
882 BT_DBG("conn %p", conn);
883
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200884 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300885 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200886
Johan Hedberg4dae2792014-06-24 17:03:50 +0300887 if (!test_bit(HCI_CONN_MASTER, &conn->hcon->flags))
Johan Hedberg86ca9ea2013-11-05 11:30:39 +0200888 return SMP_CMD_NOTSUPP;
889
Johan Hedbergc7262e72014-06-17 13:07:37 +0300890 sec_level = authreq_to_seclevel(rp->auth_req);
891 if (sec_level > hcon->pending_sec_level)
892 hcon->pending_sec_level = sec_level;
Vinicius Costa Gomesfeb45eb2011-08-25 20:02:35 -0300893
Johan Hedberg4dab7862012-06-07 14:58:37 +0800894 if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
Vinicius Costa Gomes988c5992011-08-25 20:02:28 -0300895 return 0;
896
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200897 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300898 return 0;
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300899
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300900 smp = smp_chan_create(conn);
Johan Hedbergc29d2442014-06-16 19:25:14 +0300901 if (!smp)
902 return SMP_UNSPECIFIED;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300903
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300904 skb_pull(skb, sizeof(*rp));
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300905
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300906 memset(&cp, 0, sizeof(cp));
Vinicius Costa Gomes54790f72011-07-07 18:59:38 -0300907 build_pairing_cmd(conn, &cp, NULL, rp->auth_req);
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300908
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300909 smp->preq[0] = SMP_CMD_PAIRING_REQ;
910 memcpy(&smp->preq[1], &cp, sizeof(cp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300911
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300912 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300913
Johan Hedberg4a74d652014-05-20 09:45:50 +0300914 clear_bit(SMP_FLAG_INITIATOR, &smp->flags);
Johan Hedbergedca7922014-03-24 15:54:11 +0200915
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -0300916 return 0;
Anderson Briglia88ba43b2011-06-09 18:50:42 -0300917}
918
Johan Hedbergad32a2f2013-05-14 18:05:12 +0300919bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level)
920{
921 if (sec_level == BT_SECURITY_LOW)
922 return true;
923
924 if (hcon->sec_level >= sec_level)
925 return true;
926
927 return false;
928}
929
Vinicius Costa Gomescc110922012-08-23 21:32:43 -0300930int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300931{
Vinicius Costa Gomescc110922012-08-23 21:32:43 -0300932 struct l2cap_conn *conn = hcon->l2cap_data;
Johan Hedberg0a66cf22014-03-24 14:39:03 +0200933 struct smp_chan *smp;
Brian Gix2b64d152011-12-21 16:12:12 -0800934 __u8 authreq;
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300935
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -0300936 BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
937
Johan Hedberg0a66cf22014-03-24 14:39:03 +0200938 /* This may be NULL if there's an unexpected disconnection */
939 if (!conn)
940 return 1;
941
Johan Hedberg757aee02013-04-24 13:05:32 +0300942 if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags))
Andre Guedes2e65c9d2011-06-30 19:20:56 -0300943 return 1;
944
Johan Hedbergad32a2f2013-05-14 18:05:12 +0300945 if (smp_sufficient_security(hcon, sec_level))
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -0300946 return 1;
947
Johan Hedbergc7262e72014-06-17 13:07:37 +0300948 if (sec_level > hcon->pending_sec_level)
949 hcon->pending_sec_level = sec_level;
950
Johan Hedberg4dae2792014-06-24 17:03:50 +0300951 if (test_bit(HCI_CONN_MASTER, &hcon->flags))
Johan Hedbergc7262e72014-06-17 13:07:37 +0300952 if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
953 return 0;
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300954
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200955 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300956 return 0;
957
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -0300958 smp = smp_chan_create(conn);
Brian Gix2b64d152011-12-21 16:12:12 -0800959 if (!smp)
960 return 1;
961
962 authreq = seclevel_to_authreq(sec_level);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300963
Johan Hedberg79897d22014-06-01 09:45:24 +0300964 /* Require MITM if IO Capability allows or the security level
965 * requires it.
Johan Hedberg2e233642014-03-18 15:42:30 +0200966 */
Johan Hedberg79897d22014-06-01 09:45:24 +0300967 if (hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT ||
Johan Hedbergc7262e72014-06-17 13:07:37 +0300968 hcon->pending_sec_level > BT_SECURITY_MEDIUM)
Johan Hedberg2e233642014-03-18 15:42:30 +0200969 authreq |= SMP_AUTH_MITM;
970
Johan Hedberg4dae2792014-06-24 17:03:50 +0300971 if (test_bit(HCI_CONN_MASTER, &hcon->flags)) {
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -0300972 struct smp_cmd_pairing cp;
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300973
Brian Gix2b64d152011-12-21 16:12:12 -0800974 build_pairing_cmd(conn, &cp, NULL, authreq);
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300975 smp->preq[0] = SMP_CMD_PAIRING_REQ;
976 memcpy(&smp->preq[1], &cp, sizeof(cp));
Anderson Brigliaf01ead32011-06-09 18:50:45 -0300977
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300978 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
979 } else {
980 struct smp_cmd_security_req cp;
Brian Gix2b64d152011-12-21 16:12:12 -0800981 cp.auth_req = authreq;
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300982 smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
983 }
984
Johan Hedberg4a74d652014-05-20 09:45:50 +0300985 set_bit(SMP_FLAG_INITIATOR, &smp->flags);
Johan Hedbergedca7922014-03-24 15:54:11 +0200986
Anderson Brigliaeb492e02011-06-09 18:50:40 -0300987 return 0;
988}
989
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -0300990static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
991{
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300992 struct smp_cmd_encrypt_info *rp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -0300993 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -0300994
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200995 BT_DBG("conn %p", conn);
996
997 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +0300998 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +0200999
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001000 /* Ignore this PDU if it wasn't requested */
1001 if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
1002 return 0;
1003
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001004 skb_pull(skb, sizeof(*rp));
1005
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001006 memcpy(smp->tk, rp->ltk, sizeof(smp->tk));
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001007
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001008 return 0;
1009}
1010
1011static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
1012{
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001013 struct smp_cmd_master_ident *rp = (void *) skb->data;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001014 struct smp_chan *smp = conn->smp_chan;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001015 struct hci_dev *hdev = conn->hcon->hdev;
1016 struct hci_conn *hcon = conn->hcon;
Johan Hedberg23d0e122014-02-19 14:57:46 +02001017 struct smp_ltk *ltk;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001018 u8 authenticated;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001019
Johan Hedbergc46b98b2014-02-18 10:19:29 +02001020 BT_DBG("conn %p", conn);
1021
1022 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001023 return SMP_INVALID_PARAMS;
Johan Hedbergc46b98b2014-02-18 10:19:29 +02001024
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001025 /* Ignore this PDU if it wasn't requested */
1026 if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
1027 return 0;
1028
Johan Hedberg9747a9f2014-02-26 23:33:43 +02001029 /* Mark the information as received */
1030 smp->remote_key_dist &= ~SMP_DIST_ENC_KEY;
1031
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001032 skb_pull(skb, sizeof(*rp));
1033
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001034 hci_dev_lock(hdev);
Marcel Holtmannce39fb42013-10-13 02:23:39 -07001035 authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
Johan Hedberg2ceba532014-06-16 19:25:16 +03001036 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, SMP_LTK,
Johan Hedberg23d0e122014-02-19 14:57:46 +02001037 authenticated, smp->tk, smp->enc_key_size,
1038 rp->ediv, rp->rand);
1039 smp->ltk = ltk;
Johan Hedbergfd349c02014-02-18 10:19:36 +02001040 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001041 smp_distribute_keys(conn);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001042 hci_dev_unlock(hdev);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001043
1044 return 0;
1045}
1046
Johan Hedbergfd349c02014-02-18 10:19:36 +02001047static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
1048{
1049 struct smp_cmd_ident_info *info = (void *) skb->data;
1050 struct smp_chan *smp = conn->smp_chan;
1051
1052 BT_DBG("");
1053
1054 if (skb->len < sizeof(*info))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001055 return SMP_INVALID_PARAMS;
Johan Hedbergfd349c02014-02-18 10:19:36 +02001056
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001057 /* Ignore this PDU if it wasn't requested */
1058 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
1059 return 0;
1060
Johan Hedbergfd349c02014-02-18 10:19:36 +02001061 skb_pull(skb, sizeof(*info));
1062
1063 memcpy(smp->irk, info->irk, 16);
1064
1065 return 0;
1066}
1067
1068static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
1069 struct sk_buff *skb)
1070{
1071 struct smp_cmd_ident_addr_info *info = (void *) skb->data;
1072 struct smp_chan *smp = conn->smp_chan;
1073 struct hci_conn *hcon = conn->hcon;
1074 bdaddr_t rpa;
1075
1076 BT_DBG("");
1077
1078 if (skb->len < sizeof(*info))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001079 return SMP_INVALID_PARAMS;
Johan Hedbergfd349c02014-02-18 10:19:36 +02001080
Johan Hedberg6131ddc2014-02-18 10:19:37 +02001081 /* Ignore this PDU if it wasn't requested */
1082 if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
1083 return 0;
1084
Johan Hedberg9747a9f2014-02-26 23:33:43 +02001085 /* Mark the information as received */
1086 smp->remote_key_dist &= ~SMP_DIST_ID_KEY;
1087
Johan Hedbergfd349c02014-02-18 10:19:36 +02001088 skb_pull(skb, sizeof(*info));
1089
Johan Hedberg31dd6242014-06-27 14:23:02 +03001090 hci_dev_lock(hcon->hdev);
1091
Johan Hedberga9a58f82014-02-25 22:24:37 +02001092 /* Strictly speaking the Core Specification (4.1) allows sending
1093 * an empty address which would force us to rely on just the IRK
1094 * as "identity information". However, since such
1095 * implementations are not known of and in order to not over
1096 * complicate our implementation, simply pretend that we never
1097 * received an IRK for such a device.
1098 */
1099 if (!bacmp(&info->bdaddr, BDADDR_ANY)) {
1100 BT_ERR("Ignoring IRK with no identity address");
Johan Hedberg31dd6242014-06-27 14:23:02 +03001101 goto distribute;
Johan Hedberga9a58f82014-02-25 22:24:37 +02001102 }
1103
Johan Hedbergfd349c02014-02-18 10:19:36 +02001104 bacpy(&smp->id_addr, &info->bdaddr);
1105 smp->id_addr_type = info->addr_type;
1106
1107 if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type))
1108 bacpy(&rpa, &hcon->dst);
1109 else
1110 bacpy(&rpa, BDADDR_ANY);
1111
Johan Hedberg23d0e122014-02-19 14:57:46 +02001112 smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
1113 smp->id_addr_type, smp->irk, &rpa);
Johan Hedbergfd349c02014-02-18 10:19:36 +02001114
Johan Hedberg31dd6242014-06-27 14:23:02 +03001115distribute:
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001116 smp_distribute_keys(conn);
Johan Hedbergfd349c02014-02-18 10:19:36 +02001117
Johan Hedberg31dd6242014-06-27 14:23:02 +03001118 hci_dev_unlock(hcon->hdev);
1119
Johan Hedbergfd349c02014-02-18 10:19:36 +02001120 return 0;
1121}
1122
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001123static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)
1124{
1125 struct smp_cmd_sign_info *rp = (void *) skb->data;
1126 struct smp_chan *smp = conn->smp_chan;
1127 struct hci_dev *hdev = conn->hcon->hdev;
1128 struct smp_csrk *csrk;
1129
1130 BT_DBG("conn %p", conn);
1131
1132 if (skb->len < sizeof(*rp))
Johan Hedberg38e4a912014-05-08 14:19:11 +03001133 return SMP_INVALID_PARAMS;
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001134
1135 /* Ignore this PDU if it wasn't requested */
1136 if (!(smp->remote_key_dist & SMP_DIST_SIGN))
1137 return 0;
1138
1139 /* Mark the information as received */
1140 smp->remote_key_dist &= ~SMP_DIST_SIGN;
1141
1142 skb_pull(skb, sizeof(*rp));
1143
1144 hci_dev_lock(hdev);
1145 csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
1146 if (csrk) {
1147 csrk->master = 0x01;
1148 memcpy(csrk->val, rp->csrk, sizeof(csrk->val));
1149 }
1150 smp->csrk = csrk;
1151 if (!(smp->remote_key_dist & SMP_DIST_SIGN))
1152 smp_distribute_keys(conn);
1153 hci_dev_unlock(hdev);
1154
1155 return 0;
1156}
1157
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001158int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
1159{
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001160 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann92381f52013-10-03 01:23:08 -07001161 __u8 code, reason;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001162 int err = 0;
1163
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001164 if (hcon->type != LE_LINK) {
1165 kfree_skb(skb);
Johan Hedberg34327112013-10-16 11:37:01 +03001166 return 0;
Marcel Holtmann7b9899d2013-10-03 00:00:57 -07001167 }
1168
Marcel Holtmann92381f52013-10-03 01:23:08 -07001169 if (skb->len < 1) {
1170 kfree_skb(skb);
1171 return -EILSEQ;
1172 }
1173
Marcel Holtmann06ae3312013-10-18 03:43:00 -07001174 if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) {
Andre Guedes2e65c9d2011-06-30 19:20:56 -03001175 err = -ENOTSUPP;
1176 reason = SMP_PAIRING_NOTSUPP;
1177 goto done;
1178 }
1179
Marcel Holtmann92381f52013-10-03 01:23:08 -07001180 code = skb->data[0];
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001181 skb_pull(skb, sizeof(code));
1182
Johan Hedberg8cf9fa12013-01-29 10:44:23 -06001183 /*
1184 * The SMP context must be initialized for all other PDUs except
1185 * pairing and security requests. If we get any other PDU when
1186 * not initialized simply disconnect (done if this function
1187 * returns an error).
1188 */
1189 if (code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ &&
1190 !conn->smp_chan) {
1191 BT_ERR("Unexpected SMP command 0x%02x. Disconnecting.", code);
1192 kfree_skb(skb);
1193 return -ENOTSUPP;
1194 }
1195
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001196 switch (code) {
1197 case SMP_CMD_PAIRING_REQ:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001198 reason = smp_cmd_pairing_req(conn, skb);
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001199 break;
1200
1201 case SMP_CMD_PAIRING_FAIL:
Johan Hedberg84794e12013-11-06 11:24:57 +02001202 smp_failure(conn, 0);
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001203 reason = 0;
1204 err = -EPERM;
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001205 break;
1206
1207 case SMP_CMD_PAIRING_RSP:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001208 reason = smp_cmd_pairing_rsp(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001209 break;
1210
1211 case SMP_CMD_SECURITY_REQ:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001212 reason = smp_cmd_security_req(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001213 break;
1214
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001215 case SMP_CMD_PAIRING_CONFIRM:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001216 reason = smp_cmd_pairing_confirm(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001217 break;
1218
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001219 case SMP_CMD_PAIRING_RANDOM:
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001220 reason = smp_cmd_pairing_random(conn, skb);
Anderson Briglia88ba43b2011-06-09 18:50:42 -03001221 break;
1222
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001223 case SMP_CMD_ENCRYPT_INFO:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001224 reason = smp_cmd_encrypt_info(conn, skb);
1225 break;
1226
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001227 case SMP_CMD_MASTER_IDENT:
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001228 reason = smp_cmd_master_ident(conn, skb);
1229 break;
1230
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001231 case SMP_CMD_IDENT_INFO:
Johan Hedbergfd349c02014-02-18 10:19:36 +02001232 reason = smp_cmd_ident_info(conn, skb);
1233 break;
1234
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001235 case SMP_CMD_IDENT_ADDR_INFO:
Johan Hedbergfd349c02014-02-18 10:19:36 +02001236 reason = smp_cmd_ident_addr_info(conn, skb);
1237 break;
1238
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001239 case SMP_CMD_SIGN_INFO:
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001240 reason = smp_cmd_sign_info(conn, skb);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001241 break;
1242
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001243 default:
1244 BT_DBG("Unknown command code 0x%2.2x", code);
1245
1246 reason = SMP_CMD_NOTSUPP;
Vinicius Costa Gomes3a0259b2011-06-09 18:50:43 -03001247 err = -EOPNOTSUPP;
1248 goto done;
1249 }
1250
1251done:
1252 if (reason)
Johan Hedberg84794e12013-11-06 11:24:57 +02001253 smp_failure(conn, reason);
Anderson Brigliaeb492e02011-06-09 18:50:40 -03001254
1255 kfree_skb(skb);
1256 return err;
1257}
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001258
Johan Hedberg35d70272014-02-19 14:57:47 +02001259static void smp_notify_keys(struct l2cap_conn *conn)
1260{
1261 struct smp_chan *smp = conn->smp_chan;
1262 struct hci_conn *hcon = conn->hcon;
1263 struct hci_dev *hdev = hcon->hdev;
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001264 struct smp_cmd_pairing *req = (void *) &smp->preq[1];
1265 struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1];
1266 bool persistent;
Johan Hedberg35d70272014-02-19 14:57:47 +02001267
Johan Hedberg61b1a7f2014-03-20 12:54:16 +02001268 if (smp->remote_irk) {
Johan Hedberg95fbac82014-02-19 15:18:31 +02001269 mgmt_new_irk(hdev, smp->remote_irk);
Johan Hedberg61b1a7f2014-03-20 12:54:16 +02001270 /* Now that user space can be considered to know the
1271 * identity address track the connection based on it
1272 * from now on.
1273 */
1274 bacpy(&hcon->dst, &smp->remote_irk->bdaddr);
1275 hcon->dst_type = smp->remote_irk->addr_type;
1276 l2cap_conn_update_id_addr(hcon);
1277 }
Johan Hedberg95fbac82014-02-19 15:18:31 +02001278
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001279 /* The LTKs and CSRKs should be persistent only if both sides
1280 * had the bonding bit set in their authentication requests.
1281 */
1282 persistent = !!((req->auth_req & rsp->auth_req) & SMP_AUTH_BONDING);
1283
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001284 if (smp->csrk) {
1285 smp->csrk->bdaddr_type = hcon->dst_type;
1286 bacpy(&smp->csrk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001287 mgmt_new_csrk(hdev, smp->csrk, persistent);
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001288 }
1289
1290 if (smp->slave_csrk) {
1291 smp->slave_csrk->bdaddr_type = hcon->dst_type;
1292 bacpy(&smp->slave_csrk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001293 mgmt_new_csrk(hdev, smp->slave_csrk, persistent);
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001294 }
1295
Johan Hedberg35d70272014-02-19 14:57:47 +02001296 if (smp->ltk) {
1297 smp->ltk->bdaddr_type = hcon->dst_type;
1298 bacpy(&smp->ltk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001299 mgmt_new_ltk(hdev, smp->ltk, persistent);
Johan Hedberg35d70272014-02-19 14:57:47 +02001300 }
1301
1302 if (smp->slave_ltk) {
1303 smp->slave_ltk->bdaddr_type = hcon->dst_type;
1304 bacpy(&smp->slave_ltk->bdaddr, &hcon->dst);
Marcel Holtmann53ac6ab2014-03-09 23:38:42 -07001305 mgmt_new_ltk(hdev, smp->slave_ltk, persistent);
Johan Hedberg35d70272014-02-19 14:57:47 +02001306 }
1307}
1308
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001309int smp_distribute_keys(struct l2cap_conn *conn)
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001310{
1311 struct smp_cmd_pairing *req, *rsp;
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001312 struct smp_chan *smp = conn->smp_chan;
Johan Hedberg524237c2014-02-22 19:06:31 +02001313 struct hci_conn *hcon = conn->hcon;
1314 struct hci_dev *hdev = hcon->hdev;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001315 __u8 *keydist;
1316
Johan Hedberg4bd6d382014-02-26 23:33:45 +02001317 BT_DBG("conn %p", conn);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001318
Johan Hedberg524237c2014-02-22 19:06:31 +02001319 if (!test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001320 return 0;
1321
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001322 rsp = (void *) &smp->prsp[1];
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001323
1324 /* The responder sends its keys first */
Johan Hedbergefabba32014-02-26 23:33:44 +02001325 if (hcon->out && (smp->remote_key_dist & 0x07))
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001326 return 0;
1327
Vinicius Costa Gomes1c1def02011-09-05 14:31:30 -03001328 req = (void *) &smp->preq[1];
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001329
Johan Hedberg524237c2014-02-22 19:06:31 +02001330 if (hcon->out) {
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001331 keydist = &rsp->init_key_dist;
1332 *keydist &= req->init_key_dist;
1333 } else {
1334 keydist = &rsp->resp_key_dist;
1335 *keydist &= req->resp_key_dist;
1336 }
1337
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001338 BT_DBG("keydist 0x%x", *keydist);
1339
1340 if (*keydist & SMP_DIST_ENC_KEY) {
1341 struct smp_cmd_encrypt_info enc;
1342 struct smp_cmd_master_ident ident;
Johan Hedberg23d0e122014-02-19 14:57:46 +02001343 struct smp_ltk *ltk;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001344 u8 authenticated;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001345 __le16 ediv;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001346 __le64 rand;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001347
1348 get_random_bytes(enc.ltk, sizeof(enc.ltk));
1349 get_random_bytes(&ediv, sizeof(ediv));
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001350 get_random_bytes(&rand, sizeof(rand));
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001351
1352 smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
1353
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03001354 authenticated = hcon->sec_level == BT_SECURITY_HIGH;
Johan Hedberg524237c2014-02-22 19:06:31 +02001355 ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type,
Johan Hedberg2ceba532014-06-16 19:25:16 +03001356 SMP_LTK_SLAVE, authenticated, enc.ltk,
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001357 smp->enc_key_size, ediv, rand);
Johan Hedberg23d0e122014-02-19 14:57:46 +02001358 smp->slave_ltk = ltk;
Vinicius Costa Gomes16b90832011-07-07 18:59:39 -03001359
Andrei Emeltchenko58115372012-03-12 12:13:06 +02001360 ident.ediv = ediv;
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08001361 ident.rand = rand;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001362
1363 smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident);
1364
1365 *keydist &= ~SMP_DIST_ENC_KEY;
1366 }
1367
1368 if (*keydist & SMP_DIST_ID_KEY) {
1369 struct smp_cmd_ident_addr_info addrinfo;
1370 struct smp_cmd_ident_info idinfo;
1371
Johan Hedberg863efaf2014-02-22 19:06:32 +02001372 memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk));
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001373
1374 smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo);
1375
Johan Hedberg82d4b352014-02-23 19:42:18 +02001376 /* The hci_conn contains the local identity address
1377 * after the connection has been established.
1378 *
1379 * This is true even when the connection has been
1380 * established using a resolvable random address.
1381 */
Johan Hedberg524237c2014-02-22 19:06:31 +02001382 bacpy(&addrinfo.bdaddr, &hcon->src);
Johan Hedberg82d4b352014-02-23 19:42:18 +02001383 addrinfo.addr_type = hcon->src_type;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001384
1385 smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo),
Marcel Holtmannf1560462013-10-13 05:43:25 -07001386 &addrinfo);
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001387
1388 *keydist &= ~SMP_DIST_ID_KEY;
1389 }
1390
1391 if (*keydist & SMP_DIST_SIGN) {
1392 struct smp_cmd_sign_info sign;
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001393 struct smp_csrk *csrk;
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001394
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001395 /* Generate a new random key */
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001396 get_random_bytes(sign.csrk, sizeof(sign.csrk));
1397
Marcel Holtmann7ee4ea32014-03-09 12:19:17 -07001398 csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
1399 if (csrk) {
1400 csrk->master = 0x00;
1401 memcpy(csrk->val, sign.csrk, sizeof(csrk->val));
1402 }
1403 smp->slave_csrk = csrk;
1404
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001405 smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign);
1406
1407 *keydist &= ~SMP_DIST_SIGN;
1408 }
1409
Johan Hedbergefabba32014-02-26 23:33:44 +02001410 /* If there are still keys to be received wait for them */
1411 if ((smp->remote_key_dist & 0x07))
1412 return 0;
1413
Johan Hedberg1d98bf42014-03-24 14:39:08 +02001414 clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags);
1415 cancel_delayed_work_sync(&conn->security_timer);
Johan Hedberg4a74d652014-05-20 09:45:50 +03001416 set_bit(SMP_FLAG_COMPLETE, &smp->flags);
Johan Hedberg1d98bf42014-03-24 14:39:08 +02001417 smp_notify_keys(conn);
Johan Hedbergefabba32014-02-26 23:33:44 +02001418
Johan Hedberg1d98bf42014-03-24 14:39:08 +02001419 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001420
Vinicius Costa Gomes7034b912011-07-07 18:59:34 -03001421 return 0;
1422}