xref: /openbmc/linux/net/bluetooth/smp.c (revision b68fda68)
1eb492e01SAnderson Briglia /*
2eb492e01SAnderson Briglia    BlueZ - Bluetooth protocol stack for Linux
3eb492e01SAnderson Briglia    Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4eb492e01SAnderson Briglia 
5eb492e01SAnderson Briglia    This program is free software; you can redistribute it and/or modify
6eb492e01SAnderson Briglia    it under the terms of the GNU General Public License version 2 as
7eb492e01SAnderson Briglia    published by the Free Software Foundation;
8eb492e01SAnderson Briglia 
9eb492e01SAnderson Briglia    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
10eb492e01SAnderson Briglia    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11eb492e01SAnderson Briglia    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
12eb492e01SAnderson Briglia    IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
13eb492e01SAnderson Briglia    CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
14eb492e01SAnderson Briglia    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15eb492e01SAnderson Briglia    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16eb492e01SAnderson Briglia    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17eb492e01SAnderson Briglia 
18eb492e01SAnderson Briglia    ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
19eb492e01SAnderson Briglia    COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
20eb492e01SAnderson Briglia    SOFTWARE IS DISCLAIMED.
21eb492e01SAnderson Briglia */
22eb492e01SAnderson Briglia 
238c520a59SGustavo Padovan #include <linux/crypto.h>
248c520a59SGustavo Padovan #include <linux/scatterlist.h>
258c520a59SGustavo Padovan #include <crypto/b128ops.h>
268c520a59SGustavo Padovan 
27eb492e01SAnderson Briglia #include <net/bluetooth/bluetooth.h>
28eb492e01SAnderson Briglia #include <net/bluetooth/hci_core.h>
29eb492e01SAnderson Briglia #include <net/bluetooth/l2cap.h>
302b64d153SBrian Gix #include <net/bluetooth/mgmt.h>
31ac4b7236SMarcel Holtmann 
32ac4b7236SMarcel Holtmann #include "smp.h"
33d22ef0bcSAnderson Briglia 
3417b02e62SMarcel Holtmann #define SMP_TIMEOUT	msecs_to_jiffies(30000)
355d3de7dfSVinicius Costa Gomes 
36065a13e2SJohan Hedberg #define AUTH_REQ_MASK   0x07
37065a13e2SJohan Hedberg 
38533e35d4SJohan Hedberg enum {
39533e35d4SJohan Hedberg 	SMP_FLAG_TK_VALID,
40533e35d4SJohan Hedberg 	SMP_FLAG_CFM_PENDING,
41533e35d4SJohan Hedberg 	SMP_FLAG_MITM_AUTH,
42533e35d4SJohan Hedberg 	SMP_FLAG_COMPLETE,
43533e35d4SJohan Hedberg 	SMP_FLAG_INITIATOR,
44533e35d4SJohan Hedberg };
454bc58f51SJohan Hedberg 
464bc58f51SJohan Hedberg struct smp_chan {
474bc58f51SJohan Hedberg 	struct l2cap_conn	*conn;
48b68fda68SJohan Hedberg 	struct delayed_work	security_timer;
49b68fda68SJohan Hedberg 
504bc58f51SJohan Hedberg 	u8		preq[7]; /* SMP Pairing Request */
514bc58f51SJohan Hedberg 	u8		prsp[7]; /* SMP Pairing Response */
524bc58f51SJohan Hedberg 	u8		prnd[16]; /* SMP Pairing Random (local) */
534bc58f51SJohan Hedberg 	u8		rrnd[16]; /* SMP Pairing Random (remote) */
544bc58f51SJohan Hedberg 	u8		pcnf[16]; /* SMP Pairing Confirm */
554bc58f51SJohan Hedberg 	u8		tk[16]; /* SMP Temporary Key */
564bc58f51SJohan Hedberg 	u8		enc_key_size;
574bc58f51SJohan Hedberg 	u8		remote_key_dist;
584bc58f51SJohan Hedberg 	bdaddr_t	id_addr;
594bc58f51SJohan Hedberg 	u8		id_addr_type;
604bc58f51SJohan Hedberg 	u8		irk[16];
614bc58f51SJohan Hedberg 	struct smp_csrk	*csrk;
624bc58f51SJohan Hedberg 	struct smp_csrk	*slave_csrk;
634bc58f51SJohan Hedberg 	struct smp_ltk	*ltk;
644bc58f51SJohan Hedberg 	struct smp_ltk	*slave_ltk;
654bc58f51SJohan Hedberg 	struct smp_irk	*remote_irk;
664a74d658SJohan Hedberg 	unsigned long	flags;
676a7bd103SJohan Hedberg 
686a7bd103SJohan Hedberg 	struct crypto_blkcipher	*tfm_aes;
694bc58f51SJohan Hedberg };
704bc58f51SJohan Hedberg 
718a2936f4SJohan Hedberg static inline void swap_buf(const u8 *src, u8 *dst, size_t len)
72d22ef0bcSAnderson Briglia {
738a2936f4SJohan Hedberg 	size_t i;
74d22ef0bcSAnderson Briglia 
758a2936f4SJohan Hedberg 	for (i = 0; i < len; i++)
768a2936f4SJohan Hedberg 		dst[len - 1 - i] = src[i];
77d22ef0bcSAnderson Briglia }
78d22ef0bcSAnderson Briglia 
79d22ef0bcSAnderson Briglia static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
80d22ef0bcSAnderson Briglia {
81d22ef0bcSAnderson Briglia 	struct blkcipher_desc desc;
82d22ef0bcSAnderson Briglia 	struct scatterlist sg;
83943a732aSJohan Hedberg 	uint8_t tmp[16], data[16];
84201a5929SJohan Hedberg 	int err;
85d22ef0bcSAnderson Briglia 
86d22ef0bcSAnderson Briglia 	if (tfm == NULL) {
87d22ef0bcSAnderson Briglia 		BT_ERR("tfm %p", tfm);
88d22ef0bcSAnderson Briglia 		return -EINVAL;
89d22ef0bcSAnderson Briglia 	}
90d22ef0bcSAnderson Briglia 
91d22ef0bcSAnderson Briglia 	desc.tfm = tfm;
92d22ef0bcSAnderson Briglia 	desc.flags = 0;
93d22ef0bcSAnderson Briglia 
94943a732aSJohan Hedberg 	/* The most significant octet of key corresponds to k[0] */
958a2936f4SJohan Hedberg 	swap_buf(k, tmp, 16);
96943a732aSJohan Hedberg 
97943a732aSJohan Hedberg 	err = crypto_blkcipher_setkey(tfm, tmp, 16);
98d22ef0bcSAnderson Briglia 	if (err) {
99d22ef0bcSAnderson Briglia 		BT_ERR("cipher setkey failed: %d", err);
100d22ef0bcSAnderson Briglia 		return err;
101d22ef0bcSAnderson Briglia 	}
102d22ef0bcSAnderson Briglia 
103943a732aSJohan Hedberg 	/* Most significant octet of plaintextData corresponds to data[0] */
1048a2936f4SJohan Hedberg 	swap_buf(r, data, 16);
105943a732aSJohan Hedberg 
106943a732aSJohan Hedberg 	sg_init_one(&sg, data, 16);
107d22ef0bcSAnderson Briglia 
108d22ef0bcSAnderson Briglia 	err = crypto_blkcipher_encrypt(&desc, &sg, &sg, 16);
109d22ef0bcSAnderson Briglia 	if (err)
110d22ef0bcSAnderson Briglia 		BT_ERR("Encrypt data error %d", err);
111d22ef0bcSAnderson Briglia 
112943a732aSJohan Hedberg 	/* Most significant octet of encryptedData corresponds to data[0] */
1138a2936f4SJohan Hedberg 	swap_buf(data, r, 16);
114943a732aSJohan Hedberg 
115d22ef0bcSAnderson Briglia 	return err;
116d22ef0bcSAnderson Briglia }
117d22ef0bcSAnderson Briglia 
11860478054SJohan Hedberg static int smp_ah(struct crypto_blkcipher *tfm, u8 irk[16], u8 r[3], u8 res[3])
11960478054SJohan Hedberg {
120943a732aSJohan Hedberg 	u8 _res[16];
12160478054SJohan Hedberg 	int err;
12260478054SJohan Hedberg 
12360478054SJohan Hedberg 	/* r' = padding || r */
124943a732aSJohan Hedberg 	memcpy(_res, r, 3);
125943a732aSJohan Hedberg 	memset(_res + 3, 0, 13);
12660478054SJohan Hedberg 
127943a732aSJohan Hedberg 	err = smp_e(tfm, irk, _res);
12860478054SJohan Hedberg 	if (err) {
12960478054SJohan Hedberg 		BT_ERR("Encrypt error");
13060478054SJohan Hedberg 		return err;
13160478054SJohan Hedberg 	}
13260478054SJohan Hedberg 
13360478054SJohan Hedberg 	/* The output of the random address function ah is:
13460478054SJohan Hedberg 	 *	ah(h, r) = e(k, r') mod 2^24
13560478054SJohan Hedberg 	 * The output of the security function e is then truncated to 24 bits
13660478054SJohan Hedberg 	 * by taking the least significant 24 bits of the output of e as the
13760478054SJohan Hedberg 	 * result of ah.
13860478054SJohan Hedberg 	 */
139943a732aSJohan Hedberg 	memcpy(res, _res, 3);
14060478054SJohan Hedberg 
14160478054SJohan Hedberg 	return 0;
14260478054SJohan Hedberg }
14360478054SJohan Hedberg 
144defce9e8SJohan Hedberg bool smp_irk_matches(struct hci_dev *hdev, u8 irk[16], bdaddr_t *bdaddr)
14560478054SJohan Hedberg {
146defce9e8SJohan Hedberg 	struct l2cap_chan *chan = hdev->smp_data;
147defce9e8SJohan Hedberg 	struct crypto_blkcipher *tfm;
14860478054SJohan Hedberg 	u8 hash[3];
14960478054SJohan Hedberg 	int err;
15060478054SJohan Hedberg 
151defce9e8SJohan Hedberg 	if (!chan || !chan->data)
152defce9e8SJohan Hedberg 		return false;
153defce9e8SJohan Hedberg 
154defce9e8SJohan Hedberg 	tfm = chan->data;
155defce9e8SJohan Hedberg 
15660478054SJohan Hedberg 	BT_DBG("RPA %pMR IRK %*phN", bdaddr, 16, irk);
15760478054SJohan Hedberg 
15860478054SJohan Hedberg 	err = smp_ah(tfm, irk, &bdaddr->b[3], hash);
15960478054SJohan Hedberg 	if (err)
16060478054SJohan Hedberg 		return false;
16160478054SJohan Hedberg 
16260478054SJohan Hedberg 	return !memcmp(bdaddr->b, hash, 3);
16360478054SJohan Hedberg }
16460478054SJohan Hedberg 
165defce9e8SJohan Hedberg int smp_generate_rpa(struct hci_dev *hdev, u8 irk[16], bdaddr_t *rpa)
166b1e2b3aeSJohan Hedberg {
167defce9e8SJohan Hedberg 	struct l2cap_chan *chan = hdev->smp_data;
168defce9e8SJohan Hedberg 	struct crypto_blkcipher *tfm;
169b1e2b3aeSJohan Hedberg 	int err;
170b1e2b3aeSJohan Hedberg 
171defce9e8SJohan Hedberg 	if (!chan || !chan->data)
172defce9e8SJohan Hedberg 		return -EOPNOTSUPP;
173defce9e8SJohan Hedberg 
174defce9e8SJohan Hedberg 	tfm = chan->data;
175defce9e8SJohan Hedberg 
176b1e2b3aeSJohan Hedberg 	get_random_bytes(&rpa->b[3], 3);
177b1e2b3aeSJohan Hedberg 
178b1e2b3aeSJohan Hedberg 	rpa->b[5] &= 0x3f;	/* Clear two most significant bits */
179b1e2b3aeSJohan Hedberg 	rpa->b[5] |= 0x40;	/* Set second most significant bit */
180b1e2b3aeSJohan Hedberg 
181b1e2b3aeSJohan Hedberg 	err = smp_ah(tfm, irk, &rpa->b[3], rpa->b);
182b1e2b3aeSJohan Hedberg 	if (err < 0)
183b1e2b3aeSJohan Hedberg 		return err;
184b1e2b3aeSJohan Hedberg 
185b1e2b3aeSJohan Hedberg 	BT_DBG("RPA %pMR", rpa);
186b1e2b3aeSJohan Hedberg 
187b1e2b3aeSJohan Hedberg 	return 0;
188b1e2b3aeSJohan Hedberg }
189b1e2b3aeSJohan Hedberg 
190ec70f36fSJohan Hedberg static int smp_c1(struct smp_chan *smp, u8 k[16], u8 r[16], u8 preq[7],
191ec70f36fSJohan Hedberg 		  u8 pres[7], u8 _iat, bdaddr_t *ia, u8 _rat, bdaddr_t *ra,
192ec70f36fSJohan Hedberg 		  u8 res[16])
193d22ef0bcSAnderson Briglia {
194ec70f36fSJohan Hedberg 	struct hci_dev *hdev = smp->conn->hcon->hdev;
195d22ef0bcSAnderson Briglia 	u8 p1[16], p2[16];
196d22ef0bcSAnderson Briglia 	int err;
197d22ef0bcSAnderson Briglia 
198ec70f36fSJohan Hedberg 	BT_DBG("%s", hdev->name);
199ec70f36fSJohan Hedberg 
200d22ef0bcSAnderson Briglia 	memset(p1, 0, 16);
201d22ef0bcSAnderson Briglia 
202d22ef0bcSAnderson Briglia 	/* p1 = pres || preq || _rat || _iat */
203943a732aSJohan Hedberg 	p1[0] = _iat;
204943a732aSJohan Hedberg 	p1[1] = _rat;
205943a732aSJohan Hedberg 	memcpy(p1 + 2, preq, 7);
206943a732aSJohan Hedberg 	memcpy(p1 + 9, pres, 7);
207d22ef0bcSAnderson Briglia 
208d22ef0bcSAnderson Briglia 	/* p2 = padding || ia || ra */
209943a732aSJohan Hedberg 	memcpy(p2, ra, 6);
210943a732aSJohan Hedberg 	memcpy(p2 + 6, ia, 6);
211943a732aSJohan Hedberg 	memset(p2 + 12, 0, 4);
212d22ef0bcSAnderson Briglia 
213d22ef0bcSAnderson Briglia 	/* res = r XOR p1 */
214d22ef0bcSAnderson Briglia 	u128_xor((u128 *) res, (u128 *) r, (u128 *) p1);
215d22ef0bcSAnderson Briglia 
216d22ef0bcSAnderson Briglia 	/* res = e(k, res) */
217ec70f36fSJohan Hedberg 	err = smp_e(smp->tfm_aes, k, res);
218d22ef0bcSAnderson Briglia 	if (err) {
219d22ef0bcSAnderson Briglia 		BT_ERR("Encrypt data error");
220d22ef0bcSAnderson Briglia 		return err;
221d22ef0bcSAnderson Briglia 	}
222d22ef0bcSAnderson Briglia 
223d22ef0bcSAnderson Briglia 	/* res = res XOR p2 */
224d22ef0bcSAnderson Briglia 	u128_xor((u128 *) res, (u128 *) res, (u128 *) p2);
225d22ef0bcSAnderson Briglia 
226d22ef0bcSAnderson Briglia 	/* res = e(k, res) */
227ec70f36fSJohan Hedberg 	err = smp_e(smp->tfm_aes, k, res);
228d22ef0bcSAnderson Briglia 	if (err)
229d22ef0bcSAnderson Briglia 		BT_ERR("Encrypt data error");
230d22ef0bcSAnderson Briglia 
231d22ef0bcSAnderson Briglia 	return err;
232d22ef0bcSAnderson Briglia }
233d22ef0bcSAnderson Briglia 
234ec70f36fSJohan Hedberg static int smp_s1(struct smp_chan *smp, u8 k[16], u8 r1[16], u8 r2[16],
235ec70f36fSJohan Hedberg 		  u8 _r[16])
236d22ef0bcSAnderson Briglia {
237ec70f36fSJohan Hedberg 	struct hci_dev *hdev = smp->conn->hcon->hdev;
238d22ef0bcSAnderson Briglia 	int err;
239d22ef0bcSAnderson Briglia 
240ec70f36fSJohan Hedberg 	BT_DBG("%s", hdev->name);
241ec70f36fSJohan Hedberg 
242d22ef0bcSAnderson Briglia 	/* Just least significant octets from r1 and r2 are considered */
243943a732aSJohan Hedberg 	memcpy(_r, r2, 8);
244943a732aSJohan Hedberg 	memcpy(_r + 8, r1, 8);
245d22ef0bcSAnderson Briglia 
246ec70f36fSJohan Hedberg 	err = smp_e(smp->tfm_aes, k, _r);
247d22ef0bcSAnderson Briglia 	if (err)
248d22ef0bcSAnderson Briglia 		BT_ERR("Encrypt data error");
249d22ef0bcSAnderson Briglia 
250d22ef0bcSAnderson Briglia 	return err;
251d22ef0bcSAnderson Briglia }
252d22ef0bcSAnderson Briglia 
253eb492e01SAnderson Briglia static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
254eb492e01SAnderson Briglia {
2555d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
256b68fda68SJohan Hedberg 	struct smp_chan *smp;
2575d88cc73SJohan Hedberg 	struct kvec iv[2];
2585d88cc73SJohan Hedberg 	struct msghdr msg;
2595d88cc73SJohan Hedberg 
2605d88cc73SJohan Hedberg 	if (!chan)
2615d88cc73SJohan Hedberg 		return;
262eb492e01SAnderson Briglia 
263eb492e01SAnderson Briglia 	BT_DBG("code 0x%2.2x", code);
264eb492e01SAnderson Briglia 
2655d88cc73SJohan Hedberg 	iv[0].iov_base = &code;
2665d88cc73SJohan Hedberg 	iv[0].iov_len = 1;
267eb492e01SAnderson Briglia 
2685d88cc73SJohan Hedberg 	iv[1].iov_base = data;
2695d88cc73SJohan Hedberg 	iv[1].iov_len = len;
2705d88cc73SJohan Hedberg 
2715d88cc73SJohan Hedberg 	memset(&msg, 0, sizeof(msg));
2725d88cc73SJohan Hedberg 
2735d88cc73SJohan Hedberg 	msg.msg_iov = (struct iovec *) &iv;
2745d88cc73SJohan Hedberg 	msg.msg_iovlen = 2;
2755d88cc73SJohan Hedberg 
2765d88cc73SJohan Hedberg 	l2cap_chan_send(chan, &msg, 1 + len);
277e2dcd113SVinicius Costa Gomes 
278b68fda68SJohan Hedberg 	if (!chan->data)
279b68fda68SJohan Hedberg 		return;
280b68fda68SJohan Hedberg 
281b68fda68SJohan Hedberg 	smp = chan->data;
282b68fda68SJohan Hedberg 
283b68fda68SJohan Hedberg 	cancel_delayed_work_sync(&smp->security_timer);
284b68fda68SJohan Hedberg 	if (test_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags))
285b68fda68SJohan Hedberg 		schedule_delayed_work(&smp->security_timer, SMP_TIMEOUT);
286eb492e01SAnderson Briglia }
287eb492e01SAnderson Briglia 
2882b64d153SBrian Gix static __u8 authreq_to_seclevel(__u8 authreq)
2892b64d153SBrian Gix {
2902b64d153SBrian Gix 	if (authreq & SMP_AUTH_MITM)
2912b64d153SBrian Gix 		return BT_SECURITY_HIGH;
2922b64d153SBrian Gix 	else
2932b64d153SBrian Gix 		return BT_SECURITY_MEDIUM;
2942b64d153SBrian Gix }
2952b64d153SBrian Gix 
2962b64d153SBrian Gix static __u8 seclevel_to_authreq(__u8 sec_level)
2972b64d153SBrian Gix {
2982b64d153SBrian Gix 	switch (sec_level) {
2992b64d153SBrian Gix 	case BT_SECURITY_HIGH:
3002b64d153SBrian Gix 		return SMP_AUTH_MITM | SMP_AUTH_BONDING;
3012b64d153SBrian Gix 	case BT_SECURITY_MEDIUM:
3022b64d153SBrian Gix 		return SMP_AUTH_BONDING;
3032b64d153SBrian Gix 	default:
3042b64d153SBrian Gix 		return SMP_AUTH_NONE;
3052b64d153SBrian Gix 	}
3062b64d153SBrian Gix }
3072b64d153SBrian Gix 
308b8e66eacSVinicius Costa Gomes static void build_pairing_cmd(struct l2cap_conn *conn,
30954790f73SVinicius Costa Gomes 			      struct smp_cmd_pairing *req,
310f1560463SMarcel Holtmann 			      struct smp_cmd_pairing *rsp, __u8 authreq)
311b8e66eacSVinicius Costa Gomes {
3125d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
3135d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
314fd349c02SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
315fd349c02SJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
316fd349c02SJohan Hedberg 	u8 local_dist = 0, remote_dist = 0;
31754790f73SVinicius Costa Gomes 
318b6ae8457SJohan Hedberg 	if (test_bit(HCI_BONDABLE, &conn->hcon->hdev->dev_flags)) {
3197ee4ea36SMarcel Holtmann 		local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
3207ee4ea36SMarcel Holtmann 		remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
32154790f73SVinicius Costa Gomes 		authreq |= SMP_AUTH_BONDING;
3222b64d153SBrian Gix 	} else {
3232b64d153SBrian Gix 		authreq &= ~SMP_AUTH_BONDING;
32454790f73SVinicius Costa Gomes 	}
32554790f73SVinicius Costa Gomes 
326fd349c02SJohan Hedberg 	if (test_bit(HCI_RPA_RESOLVING, &hdev->dev_flags))
327fd349c02SJohan Hedberg 		remote_dist |= SMP_DIST_ID_KEY;
328fd349c02SJohan Hedberg 
329863efaf2SJohan Hedberg 	if (test_bit(HCI_PRIVACY, &hdev->dev_flags))
330863efaf2SJohan Hedberg 		local_dist |= SMP_DIST_ID_KEY;
331863efaf2SJohan Hedberg 
33254790f73SVinicius Costa Gomes 	if (rsp == NULL) {
33354790f73SVinicius Costa Gomes 		req->io_capability = conn->hcon->io_capability;
33454790f73SVinicius Costa Gomes 		req->oob_flag = SMP_OOB_NOT_PRESENT;
33554790f73SVinicius Costa Gomes 		req->max_key_size = SMP_MAX_ENC_KEY_SIZE;
336fd349c02SJohan Hedberg 		req->init_key_dist = local_dist;
337fd349c02SJohan Hedberg 		req->resp_key_dist = remote_dist;
338065a13e2SJohan Hedberg 		req->auth_req = (authreq & AUTH_REQ_MASK);
339fd349c02SJohan Hedberg 
340fd349c02SJohan Hedberg 		smp->remote_key_dist = remote_dist;
34154790f73SVinicius Costa Gomes 		return;
34254790f73SVinicius Costa Gomes 	}
34354790f73SVinicius Costa Gomes 
34454790f73SVinicius Costa Gomes 	rsp->io_capability = conn->hcon->io_capability;
34554790f73SVinicius Costa Gomes 	rsp->oob_flag = SMP_OOB_NOT_PRESENT;
34654790f73SVinicius Costa Gomes 	rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE;
347fd349c02SJohan Hedberg 	rsp->init_key_dist = req->init_key_dist & remote_dist;
348fd349c02SJohan Hedberg 	rsp->resp_key_dist = req->resp_key_dist & local_dist;
349065a13e2SJohan Hedberg 	rsp->auth_req = (authreq & AUTH_REQ_MASK);
350fd349c02SJohan Hedberg 
351fd349c02SJohan Hedberg 	smp->remote_key_dist = rsp->init_key_dist;
352b8e66eacSVinicius Costa Gomes }
353b8e66eacSVinicius Costa Gomes 
3543158c50cSVinicius Costa Gomes static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
3553158c50cSVinicius Costa Gomes {
3565d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
3575d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
3581c1def09SVinicius Costa Gomes 
3593158c50cSVinicius Costa Gomes 	if ((max_key_size > SMP_MAX_ENC_KEY_SIZE) ||
3603158c50cSVinicius Costa Gomes 	    (max_key_size < SMP_MIN_ENC_KEY_SIZE))
3613158c50cSVinicius Costa Gomes 		return SMP_ENC_KEY_SIZE;
3623158c50cSVinicius Costa Gomes 
363f7aa611aSVinicius Costa Gomes 	smp->enc_key_size = max_key_size;
3643158c50cSVinicius Costa Gomes 
3653158c50cSVinicius Costa Gomes 	return 0;
3663158c50cSVinicius Costa Gomes }
3673158c50cSVinicius Costa Gomes 
36884794e11SJohan Hedberg static void smp_failure(struct l2cap_conn *conn, u8 reason)
3694f957a76SBrian Gix {
370bab73cb6SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
371b68fda68SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
372b68fda68SJohan Hedberg 	struct smp_chan *smp;
373bab73cb6SJohan Hedberg 
37484794e11SJohan Hedberg 	if (reason)
3754f957a76SBrian Gix 		smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
3764f957a76SBrian Gix 			     &reason);
3774f957a76SBrian Gix 
378ce39fb4eSMarcel Holtmann 	clear_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags);
379ce39fb4eSMarcel Holtmann 	mgmt_auth_failed(hcon->hdev, &hcon->dst, hcon->type, hcon->dst_type,
380ce39fb4eSMarcel Holtmann 			 HCI_ERROR_AUTH_FAILURE);
381f1c09c07SVinicius Costa Gomes 
382b68fda68SJohan Hedberg 	if (!chan->data)
383b68fda68SJohan Hedberg 		return;
384b68fda68SJohan Hedberg 
385b68fda68SJohan Hedberg 	smp = chan->data;
386b68fda68SJohan Hedberg 
387b68fda68SJohan Hedberg 	cancel_delayed_work_sync(&smp->security_timer);
38861a0cfb0SAndre Guedes 
389ce39fb4eSMarcel Holtmann 	if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
3904f957a76SBrian Gix 		smp_chan_destroy(conn);
3914f957a76SBrian Gix }
3924f957a76SBrian Gix 
3932b64d153SBrian Gix #define JUST_WORKS	0x00
3942b64d153SBrian Gix #define JUST_CFM	0x01
3952b64d153SBrian Gix #define REQ_PASSKEY	0x02
3962b64d153SBrian Gix #define CFM_PASSKEY	0x03
3972b64d153SBrian Gix #define REQ_OOB		0x04
3982b64d153SBrian Gix #define OVERLAP		0xFF
3992b64d153SBrian Gix 
4002b64d153SBrian Gix static const u8 gen_method[5][5] = {
4012b64d153SBrian Gix 	{ JUST_WORKS,  JUST_CFM,    REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
4022b64d153SBrian Gix 	{ JUST_WORKS,  JUST_CFM,    REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
4032b64d153SBrian Gix 	{ CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
4042b64d153SBrian Gix 	{ JUST_WORKS,  JUST_CFM,    JUST_WORKS,  JUST_WORKS, JUST_CFM    },
4052b64d153SBrian Gix 	{ CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, OVERLAP     },
4062b64d153SBrian Gix };
4072b64d153SBrian Gix 
408581370ccSJohan Hedberg static u8 get_auth_method(struct smp_chan *smp, u8 local_io, u8 remote_io)
409581370ccSJohan Hedberg {
4102bcd4003SJohan Hedberg 	/* If either side has unknown io_caps, use JUST_CFM (which gets
4112bcd4003SJohan Hedberg 	 * converted later to JUST_WORKS if we're initiators.
4122bcd4003SJohan Hedberg 	 */
413581370ccSJohan Hedberg 	if (local_io > SMP_IO_KEYBOARD_DISPLAY ||
414581370ccSJohan Hedberg 	    remote_io > SMP_IO_KEYBOARD_DISPLAY)
4152bcd4003SJohan Hedberg 		return JUST_CFM;
416581370ccSJohan Hedberg 
417581370ccSJohan Hedberg 	return gen_method[remote_io][local_io];
418581370ccSJohan Hedberg }
419581370ccSJohan Hedberg 
4202b64d153SBrian Gix static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
4212b64d153SBrian Gix 						u8 local_io, u8 remote_io)
4222b64d153SBrian Gix {
4232b64d153SBrian Gix 	struct hci_conn *hcon = conn->hcon;
4245d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
4255d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
4262b64d153SBrian Gix 	u8 method;
4272b64d153SBrian Gix 	u32 passkey = 0;
4282b64d153SBrian Gix 	int ret = 0;
4292b64d153SBrian Gix 
4302b64d153SBrian Gix 	/* Initialize key for JUST WORKS */
4312b64d153SBrian Gix 	memset(smp->tk, 0, sizeof(smp->tk));
4324a74d658SJohan Hedberg 	clear_bit(SMP_FLAG_TK_VALID, &smp->flags);
4332b64d153SBrian Gix 
4342b64d153SBrian Gix 	BT_DBG("tk_request: auth:%d lcl:%d rem:%d", auth, local_io, remote_io);
4352b64d153SBrian Gix 
4362bcd4003SJohan Hedberg 	/* If neither side wants MITM, either "just" confirm an incoming
4372bcd4003SJohan Hedberg 	 * request or use just-works for outgoing ones. The JUST_CFM
4382bcd4003SJohan Hedberg 	 * will be converted to JUST_WORKS if necessary later in this
4392bcd4003SJohan Hedberg 	 * function. If either side has MITM look up the method from the
4402bcd4003SJohan Hedberg 	 * table.
4412bcd4003SJohan Hedberg 	 */
442581370ccSJohan Hedberg 	if (!(auth & SMP_AUTH_MITM))
4432bcd4003SJohan Hedberg 		method = JUST_CFM;
4442b64d153SBrian Gix 	else
445581370ccSJohan Hedberg 		method = get_auth_method(smp, local_io, remote_io);
4462b64d153SBrian Gix 
447a82505c7SJohan Hedberg 	/* Don't confirm locally initiated pairing attempts */
4484a74d658SJohan Hedberg 	if (method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR, &smp->flags))
449a82505c7SJohan Hedberg 		method = JUST_WORKS;
450a82505c7SJohan Hedberg 
45102f3e254SJohan Hedberg 	/* Don't bother user space with no IO capabilities */
45202f3e254SJohan Hedberg 	if (method == JUST_CFM && hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
45302f3e254SJohan Hedberg 		method = JUST_WORKS;
45402f3e254SJohan Hedberg 
4552b64d153SBrian Gix 	/* If Just Works, Continue with Zero TK */
4562b64d153SBrian Gix 	if (method == JUST_WORKS) {
4574a74d658SJohan Hedberg 		set_bit(SMP_FLAG_TK_VALID, &smp->flags);
4582b64d153SBrian Gix 		return 0;
4592b64d153SBrian Gix 	}
4602b64d153SBrian Gix 
4612b64d153SBrian Gix 	/* Not Just Works/Confirm results in MITM Authentication */
4622b64d153SBrian Gix 	if (method != JUST_CFM)
4634a74d658SJohan Hedberg 		set_bit(SMP_FLAG_MITM_AUTH, &smp->flags);
4642b64d153SBrian Gix 
4652b64d153SBrian Gix 	/* If both devices have Keyoard-Display I/O, the master
4662b64d153SBrian Gix 	 * Confirms and the slave Enters the passkey.
4672b64d153SBrian Gix 	 */
4682b64d153SBrian Gix 	if (method == OVERLAP) {
46940bef302SJohan Hedberg 		if (hcon->role == HCI_ROLE_MASTER)
4702b64d153SBrian Gix 			method = CFM_PASSKEY;
4712b64d153SBrian Gix 		else
4722b64d153SBrian Gix 			method = REQ_PASSKEY;
4732b64d153SBrian Gix 	}
4742b64d153SBrian Gix 
47501ad34d2SJohan Hedberg 	/* Generate random passkey. */
4762b64d153SBrian Gix 	if (method == CFM_PASSKEY) {
477943a732aSJohan Hedberg 		memset(smp->tk, 0, sizeof(smp->tk));
4782b64d153SBrian Gix 		get_random_bytes(&passkey, sizeof(passkey));
4792b64d153SBrian Gix 		passkey %= 1000000;
480943a732aSJohan Hedberg 		put_unaligned_le32(passkey, smp->tk);
4812b64d153SBrian Gix 		BT_DBG("PassKey: %d", passkey);
4824a74d658SJohan Hedberg 		set_bit(SMP_FLAG_TK_VALID, &smp->flags);
4832b64d153SBrian Gix 	}
4842b64d153SBrian Gix 
4852b64d153SBrian Gix 	hci_dev_lock(hcon->hdev);
4862b64d153SBrian Gix 
4872b64d153SBrian Gix 	if (method == REQ_PASSKEY)
488ce39fb4eSMarcel Holtmann 		ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst,
489272d90dfSJohan Hedberg 						hcon->type, hcon->dst_type);
4904eb65e66SJohan Hedberg 	else if (method == JUST_CFM)
4914eb65e66SJohan Hedberg 		ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
4924eb65e66SJohan Hedberg 						hcon->type, hcon->dst_type,
4934eb65e66SJohan Hedberg 						passkey, 1);
4942b64d153SBrian Gix 	else
49501ad34d2SJohan Hedberg 		ret = mgmt_user_passkey_notify(hcon->hdev, &hcon->dst,
496272d90dfSJohan Hedberg 						hcon->type, hcon->dst_type,
49739adbffeSJohan Hedberg 						passkey, 0);
4982b64d153SBrian Gix 
4992b64d153SBrian Gix 	hci_dev_unlock(hcon->hdev);
5002b64d153SBrian Gix 
5012b64d153SBrian Gix 	return ret;
5022b64d153SBrian Gix }
5032b64d153SBrian Gix 
5041cc61144SJohan Hedberg static u8 smp_confirm(struct smp_chan *smp)
5058aab4757SVinicius Costa Gomes {
5068aab4757SVinicius Costa Gomes 	struct l2cap_conn *conn = smp->conn;
5078aab4757SVinicius Costa Gomes 	struct smp_cmd_pairing_confirm cp;
5088aab4757SVinicius Costa Gomes 	int ret;
5098aab4757SVinicius Costa Gomes 
5108aab4757SVinicius Costa Gomes 	BT_DBG("conn %p", conn);
5118aab4757SVinicius Costa Gomes 
512ec70f36fSJohan Hedberg 	ret = smp_c1(smp, smp->tk, smp->prnd, smp->preq, smp->prsp,
513b1cd5fd9SJohan Hedberg 		     conn->hcon->init_addr_type, &conn->hcon->init_addr,
514943a732aSJohan Hedberg 		     conn->hcon->resp_addr_type, &conn->hcon->resp_addr,
515943a732aSJohan Hedberg 		     cp.confirm_val);
5161cc61144SJohan Hedberg 	if (ret)
5171cc61144SJohan Hedberg 		return SMP_UNSPECIFIED;
5188aab4757SVinicius Costa Gomes 
5194a74d658SJohan Hedberg 	clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
5202b64d153SBrian Gix 
5218aab4757SVinicius Costa Gomes 	smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
5228aab4757SVinicius Costa Gomes 
5231cc61144SJohan Hedberg 	return 0;
5248aab4757SVinicius Costa Gomes }
5258aab4757SVinicius Costa Gomes 
526861580a9SJohan Hedberg static u8 smp_random(struct smp_chan *smp)
5278aab4757SVinicius Costa Gomes {
5288aab4757SVinicius Costa Gomes 	struct l2cap_conn *conn = smp->conn;
5298aab4757SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
530861580a9SJohan Hedberg 	u8 confirm[16];
5318aab4757SVinicius Costa Gomes 	int ret;
5328aab4757SVinicius Costa Gomes 
533ec70f36fSJohan Hedberg 	if (IS_ERR_OR_NULL(smp->tfm_aes))
534861580a9SJohan Hedberg 		return SMP_UNSPECIFIED;
5358aab4757SVinicius Costa Gomes 
5368aab4757SVinicius Costa Gomes 	BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
5378aab4757SVinicius Costa Gomes 
538ec70f36fSJohan Hedberg 	ret = smp_c1(smp, smp->tk, smp->rrnd, smp->preq, smp->prsp,
539b1cd5fd9SJohan Hedberg 		     hcon->init_addr_type, &hcon->init_addr,
540943a732aSJohan Hedberg 		     hcon->resp_addr_type, &hcon->resp_addr, confirm);
541861580a9SJohan Hedberg 	if (ret)
542861580a9SJohan Hedberg 		return SMP_UNSPECIFIED;
5438aab4757SVinicius Costa Gomes 
5448aab4757SVinicius Costa Gomes 	if (memcmp(smp->pcnf, confirm, sizeof(smp->pcnf)) != 0) {
5458aab4757SVinicius Costa Gomes 		BT_ERR("Pairing failed (confirmation values mismatch)");
546861580a9SJohan Hedberg 		return SMP_CONFIRM_FAILED;
5478aab4757SVinicius Costa Gomes 	}
5488aab4757SVinicius Costa Gomes 
5498aab4757SVinicius Costa Gomes 	if (hcon->out) {
550fe39c7b2SMarcel Holtmann 		u8 stk[16];
551fe39c7b2SMarcel Holtmann 		__le64 rand = 0;
552fe39c7b2SMarcel Holtmann 		__le16 ediv = 0;
5538aab4757SVinicius Costa Gomes 
554ec70f36fSJohan Hedberg 		smp_s1(smp, smp->tk, smp->rrnd, smp->prnd, stk);
5558aab4757SVinicius Costa Gomes 
556f7aa611aSVinicius Costa Gomes 		memset(stk + smp->enc_key_size, 0,
557f7aa611aSVinicius Costa Gomes 		       SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
5588aab4757SVinicius Costa Gomes 
559861580a9SJohan Hedberg 		if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
560861580a9SJohan Hedberg 			return SMP_UNSPECIFIED;
5618aab4757SVinicius Costa Gomes 
5628aab4757SVinicius Costa Gomes 		hci_le_start_enc(hcon, ediv, rand, stk);
563f7aa611aSVinicius Costa Gomes 		hcon->enc_key_size = smp->enc_key_size;
564fe59a05fSJohan Hedberg 		set_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags);
5658aab4757SVinicius Costa Gomes 	} else {
566fff3490fSJohan Hedberg 		u8 stk[16], auth;
567fe39c7b2SMarcel Holtmann 		__le64 rand = 0;
568fe39c7b2SMarcel Holtmann 		__le16 ediv = 0;
5698aab4757SVinicius Costa Gomes 
570943a732aSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
571943a732aSJohan Hedberg 			     smp->prnd);
5728aab4757SVinicius Costa Gomes 
573ec70f36fSJohan Hedberg 		smp_s1(smp, smp->tk, smp->prnd, smp->rrnd, stk);
5748aab4757SVinicius Costa Gomes 
575f7aa611aSVinicius Costa Gomes 		memset(stk + smp->enc_key_size, 0,
576f7aa611aSVinicius Costa Gomes 		       SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
5778aab4757SVinicius Costa Gomes 
578fff3490fSJohan Hedberg 		if (hcon->pending_sec_level == BT_SECURITY_HIGH)
579fff3490fSJohan Hedberg 			auth = 1;
580fff3490fSJohan Hedberg 		else
581fff3490fSJohan Hedberg 			auth = 0;
582fff3490fSJohan Hedberg 
5837d5843b7SJohan Hedberg 		/* Even though there's no _SLAVE suffix this is the
5847d5843b7SJohan Hedberg 		 * slave STK we're adding for later lookup (the master
5857d5843b7SJohan Hedberg 		 * STK never needs to be stored).
5867d5843b7SJohan Hedberg 		 */
587ce39fb4eSMarcel Holtmann 		hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
5882ceba539SJohan Hedberg 			    SMP_STK, auth, stk, smp->enc_key_size, ediv, rand);
5898aab4757SVinicius Costa Gomes 	}
5908aab4757SVinicius Costa Gomes 
591861580a9SJohan Hedberg 	return 0;
5928aab4757SVinicius Costa Gomes }
5938aab4757SVinicius Costa Gomes 
59444f1a7abSJohan Hedberg static void smp_notify_keys(struct l2cap_conn *conn)
59544f1a7abSJohan Hedberg {
59644f1a7abSJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
59744f1a7abSJohan Hedberg 	struct smp_chan *smp = chan->data;
59844f1a7abSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
59944f1a7abSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
60044f1a7abSJohan Hedberg 	struct smp_cmd_pairing *req = (void *) &smp->preq[1];
60144f1a7abSJohan Hedberg 	struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1];
60244f1a7abSJohan Hedberg 	bool persistent;
60344f1a7abSJohan Hedberg 
60444f1a7abSJohan Hedberg 	if (smp->remote_irk) {
60544f1a7abSJohan Hedberg 		mgmt_new_irk(hdev, smp->remote_irk);
60644f1a7abSJohan Hedberg 		/* Now that user space can be considered to know the
60744f1a7abSJohan Hedberg 		 * identity address track the connection based on it
60844f1a7abSJohan Hedberg 		 * from now on.
60944f1a7abSJohan Hedberg 		 */
61044f1a7abSJohan Hedberg 		bacpy(&hcon->dst, &smp->remote_irk->bdaddr);
61144f1a7abSJohan Hedberg 		hcon->dst_type = smp->remote_irk->addr_type;
61244f1a7abSJohan Hedberg 		l2cap_conn_update_id_addr(hcon);
61344f1a7abSJohan Hedberg 
61444f1a7abSJohan Hedberg 		/* When receiving an indentity resolving key for
61544f1a7abSJohan Hedberg 		 * a remote device that does not use a resolvable
61644f1a7abSJohan Hedberg 		 * private address, just remove the key so that
61744f1a7abSJohan Hedberg 		 * it is possible to use the controller white
61844f1a7abSJohan Hedberg 		 * list for scanning.
61944f1a7abSJohan Hedberg 		 *
62044f1a7abSJohan Hedberg 		 * Userspace will have been told to not store
62144f1a7abSJohan Hedberg 		 * this key at this point. So it is safe to
62244f1a7abSJohan Hedberg 		 * just remove it.
62344f1a7abSJohan Hedberg 		 */
62444f1a7abSJohan Hedberg 		if (!bacmp(&smp->remote_irk->rpa, BDADDR_ANY)) {
62544f1a7abSJohan Hedberg 			list_del(&smp->remote_irk->list);
62644f1a7abSJohan Hedberg 			kfree(smp->remote_irk);
62744f1a7abSJohan Hedberg 			smp->remote_irk = NULL;
62844f1a7abSJohan Hedberg 		}
62944f1a7abSJohan Hedberg 	}
63044f1a7abSJohan Hedberg 
63144f1a7abSJohan Hedberg 	/* The LTKs and CSRKs should be persistent only if both sides
63244f1a7abSJohan Hedberg 	 * had the bonding bit set in their authentication requests.
63344f1a7abSJohan Hedberg 	 */
63444f1a7abSJohan Hedberg 	persistent = !!((req->auth_req & rsp->auth_req) & SMP_AUTH_BONDING);
63544f1a7abSJohan Hedberg 
63644f1a7abSJohan Hedberg 	if (smp->csrk) {
63744f1a7abSJohan Hedberg 		smp->csrk->bdaddr_type = hcon->dst_type;
63844f1a7abSJohan Hedberg 		bacpy(&smp->csrk->bdaddr, &hcon->dst);
63944f1a7abSJohan Hedberg 		mgmt_new_csrk(hdev, smp->csrk, persistent);
64044f1a7abSJohan Hedberg 	}
64144f1a7abSJohan Hedberg 
64244f1a7abSJohan Hedberg 	if (smp->slave_csrk) {
64344f1a7abSJohan Hedberg 		smp->slave_csrk->bdaddr_type = hcon->dst_type;
64444f1a7abSJohan Hedberg 		bacpy(&smp->slave_csrk->bdaddr, &hcon->dst);
64544f1a7abSJohan Hedberg 		mgmt_new_csrk(hdev, smp->slave_csrk, persistent);
64644f1a7abSJohan Hedberg 	}
64744f1a7abSJohan Hedberg 
64844f1a7abSJohan Hedberg 	if (smp->ltk) {
64944f1a7abSJohan Hedberg 		smp->ltk->bdaddr_type = hcon->dst_type;
65044f1a7abSJohan Hedberg 		bacpy(&smp->ltk->bdaddr, &hcon->dst);
65144f1a7abSJohan Hedberg 		mgmt_new_ltk(hdev, smp->ltk, persistent);
65244f1a7abSJohan Hedberg 	}
65344f1a7abSJohan Hedberg 
65444f1a7abSJohan Hedberg 	if (smp->slave_ltk) {
65544f1a7abSJohan Hedberg 		smp->slave_ltk->bdaddr_type = hcon->dst_type;
65644f1a7abSJohan Hedberg 		bacpy(&smp->slave_ltk->bdaddr, &hcon->dst);
65744f1a7abSJohan Hedberg 		mgmt_new_ltk(hdev, smp->slave_ltk, persistent);
65844f1a7abSJohan Hedberg 	}
65944f1a7abSJohan Hedberg }
66044f1a7abSJohan Hedberg 
66144f1a7abSJohan Hedberg static int smp_distribute_keys(struct l2cap_conn *conn)
66244f1a7abSJohan Hedberg {
66344f1a7abSJohan Hedberg 	struct smp_cmd_pairing *req, *rsp;
66444f1a7abSJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
66544f1a7abSJohan Hedberg 	struct smp_chan *smp = chan->data;
66644f1a7abSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
66744f1a7abSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
66844f1a7abSJohan Hedberg 	__u8 *keydist;
66944f1a7abSJohan Hedberg 
67044f1a7abSJohan Hedberg 	BT_DBG("conn %p", conn);
67144f1a7abSJohan Hedberg 
67244f1a7abSJohan Hedberg 	if (!test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
67344f1a7abSJohan Hedberg 		return 0;
67444f1a7abSJohan Hedberg 
67544f1a7abSJohan Hedberg 	rsp = (void *) &smp->prsp[1];
67644f1a7abSJohan Hedberg 
67744f1a7abSJohan Hedberg 	/* The responder sends its keys first */
67844f1a7abSJohan Hedberg 	if (hcon->out && (smp->remote_key_dist & 0x07))
67944f1a7abSJohan Hedberg 		return 0;
68044f1a7abSJohan Hedberg 
68144f1a7abSJohan Hedberg 	req = (void *) &smp->preq[1];
68244f1a7abSJohan Hedberg 
68344f1a7abSJohan Hedberg 	if (hcon->out) {
68444f1a7abSJohan Hedberg 		keydist = &rsp->init_key_dist;
68544f1a7abSJohan Hedberg 		*keydist &= req->init_key_dist;
68644f1a7abSJohan Hedberg 	} else {
68744f1a7abSJohan Hedberg 		keydist = &rsp->resp_key_dist;
68844f1a7abSJohan Hedberg 		*keydist &= req->resp_key_dist;
68944f1a7abSJohan Hedberg 	}
69044f1a7abSJohan Hedberg 
69144f1a7abSJohan Hedberg 	BT_DBG("keydist 0x%x", *keydist);
69244f1a7abSJohan Hedberg 
69344f1a7abSJohan Hedberg 	if (*keydist & SMP_DIST_ENC_KEY) {
69444f1a7abSJohan Hedberg 		struct smp_cmd_encrypt_info enc;
69544f1a7abSJohan Hedberg 		struct smp_cmd_master_ident ident;
69644f1a7abSJohan Hedberg 		struct smp_ltk *ltk;
69744f1a7abSJohan Hedberg 		u8 authenticated;
69844f1a7abSJohan Hedberg 		__le16 ediv;
69944f1a7abSJohan Hedberg 		__le64 rand;
70044f1a7abSJohan Hedberg 
70144f1a7abSJohan Hedberg 		get_random_bytes(enc.ltk, sizeof(enc.ltk));
70244f1a7abSJohan Hedberg 		get_random_bytes(&ediv, sizeof(ediv));
70344f1a7abSJohan Hedberg 		get_random_bytes(&rand, sizeof(rand));
70444f1a7abSJohan Hedberg 
70544f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
70644f1a7abSJohan Hedberg 
70744f1a7abSJohan Hedberg 		authenticated = hcon->sec_level == BT_SECURITY_HIGH;
70844f1a7abSJohan Hedberg 		ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type,
70944f1a7abSJohan Hedberg 				  SMP_LTK_SLAVE, authenticated, enc.ltk,
71044f1a7abSJohan Hedberg 				  smp->enc_key_size, ediv, rand);
71144f1a7abSJohan Hedberg 		smp->slave_ltk = ltk;
71244f1a7abSJohan Hedberg 
71344f1a7abSJohan Hedberg 		ident.ediv = ediv;
71444f1a7abSJohan Hedberg 		ident.rand = rand;
71544f1a7abSJohan Hedberg 
71644f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident);
71744f1a7abSJohan Hedberg 
71844f1a7abSJohan Hedberg 		*keydist &= ~SMP_DIST_ENC_KEY;
71944f1a7abSJohan Hedberg 	}
72044f1a7abSJohan Hedberg 
72144f1a7abSJohan Hedberg 	if (*keydist & SMP_DIST_ID_KEY) {
72244f1a7abSJohan Hedberg 		struct smp_cmd_ident_addr_info addrinfo;
72344f1a7abSJohan Hedberg 		struct smp_cmd_ident_info idinfo;
72444f1a7abSJohan Hedberg 
72544f1a7abSJohan Hedberg 		memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk));
72644f1a7abSJohan Hedberg 
72744f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo);
72844f1a7abSJohan Hedberg 
72944f1a7abSJohan Hedberg 		/* The hci_conn contains the local identity address
73044f1a7abSJohan Hedberg 		 * after the connection has been established.
73144f1a7abSJohan Hedberg 		 *
73244f1a7abSJohan Hedberg 		 * This is true even when the connection has been
73344f1a7abSJohan Hedberg 		 * established using a resolvable random address.
73444f1a7abSJohan Hedberg 		 */
73544f1a7abSJohan Hedberg 		bacpy(&addrinfo.bdaddr, &hcon->src);
73644f1a7abSJohan Hedberg 		addrinfo.addr_type = hcon->src_type;
73744f1a7abSJohan Hedberg 
73844f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo),
73944f1a7abSJohan Hedberg 			     &addrinfo);
74044f1a7abSJohan Hedberg 
74144f1a7abSJohan Hedberg 		*keydist &= ~SMP_DIST_ID_KEY;
74244f1a7abSJohan Hedberg 	}
74344f1a7abSJohan Hedberg 
74444f1a7abSJohan Hedberg 	if (*keydist & SMP_DIST_SIGN) {
74544f1a7abSJohan Hedberg 		struct smp_cmd_sign_info sign;
74644f1a7abSJohan Hedberg 		struct smp_csrk *csrk;
74744f1a7abSJohan Hedberg 
74844f1a7abSJohan Hedberg 		/* Generate a new random key */
74944f1a7abSJohan Hedberg 		get_random_bytes(sign.csrk, sizeof(sign.csrk));
75044f1a7abSJohan Hedberg 
75144f1a7abSJohan Hedberg 		csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
75244f1a7abSJohan Hedberg 		if (csrk) {
75344f1a7abSJohan Hedberg 			csrk->master = 0x00;
75444f1a7abSJohan Hedberg 			memcpy(csrk->val, sign.csrk, sizeof(csrk->val));
75544f1a7abSJohan Hedberg 		}
75644f1a7abSJohan Hedberg 		smp->slave_csrk = csrk;
75744f1a7abSJohan Hedberg 
75844f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign);
75944f1a7abSJohan Hedberg 
76044f1a7abSJohan Hedberg 		*keydist &= ~SMP_DIST_SIGN;
76144f1a7abSJohan Hedberg 	}
76244f1a7abSJohan Hedberg 
76344f1a7abSJohan Hedberg 	/* If there are still keys to be received wait for them */
76444f1a7abSJohan Hedberg 	if ((smp->remote_key_dist & 0x07))
76544f1a7abSJohan Hedberg 		return 0;
76644f1a7abSJohan Hedberg 
76744f1a7abSJohan Hedberg 	clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags);
768b68fda68SJohan Hedberg 	cancel_delayed_work_sync(&smp->security_timer);
76944f1a7abSJohan Hedberg 	set_bit(SMP_FLAG_COMPLETE, &smp->flags);
77044f1a7abSJohan Hedberg 	smp_notify_keys(conn);
77144f1a7abSJohan Hedberg 
77244f1a7abSJohan Hedberg 	smp_chan_destroy(conn);
77344f1a7abSJohan Hedberg 
77444f1a7abSJohan Hedberg 	return 0;
77544f1a7abSJohan Hedberg }
77644f1a7abSJohan Hedberg 
777b68fda68SJohan Hedberg static void smp_timeout(struct work_struct *work)
778b68fda68SJohan Hedberg {
779b68fda68SJohan Hedberg 	struct smp_chan *smp = container_of(work, struct smp_chan,
780b68fda68SJohan Hedberg 					    security_timer.work);
781b68fda68SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
782b68fda68SJohan Hedberg 
783b68fda68SJohan Hedberg 	BT_DBG("conn %p", conn);
784b68fda68SJohan Hedberg 
785b68fda68SJohan Hedberg 	l2cap_conn_shutdown(conn, ETIMEDOUT);
786b68fda68SJohan Hedberg }
787b68fda68SJohan Hedberg 
7888aab4757SVinicius Costa Gomes static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
7898aab4757SVinicius Costa Gomes {
7905d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
7918aab4757SVinicius Costa Gomes 	struct smp_chan *smp;
7928aab4757SVinicius Costa Gomes 
793f1560463SMarcel Holtmann 	smp = kzalloc(sizeof(*smp), GFP_ATOMIC);
794616d55beSJohan Hedberg 	if (!smp) {
795616d55beSJohan Hedberg 		clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags);
7968aab4757SVinicius Costa Gomes 		return NULL;
797616d55beSJohan Hedberg 	}
7988aab4757SVinicius Costa Gomes 
7996a7bd103SJohan Hedberg 	smp->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
8006a7bd103SJohan Hedberg 	if (IS_ERR(smp->tfm_aes)) {
8016a7bd103SJohan Hedberg 		BT_ERR("Unable to create ECB crypto context");
8026a7bd103SJohan Hedberg 		kfree(smp);
803616d55beSJohan Hedberg 		clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags);
8046a7bd103SJohan Hedberg 		return NULL;
8056a7bd103SJohan Hedberg 	}
8066a7bd103SJohan Hedberg 
8078aab4757SVinicius Costa Gomes 	smp->conn = conn;
8085d88cc73SJohan Hedberg 	chan->data = smp;
8098aab4757SVinicius Costa Gomes 
810b68fda68SJohan Hedberg 	INIT_DELAYED_WORK(&smp->security_timer, smp_timeout);
811b68fda68SJohan Hedberg 
8128aab4757SVinicius Costa Gomes 	hci_conn_hold(conn->hcon);
8138aab4757SVinicius Costa Gomes 
8148aab4757SVinicius Costa Gomes 	return smp;
8158aab4757SVinicius Costa Gomes }
8168aab4757SVinicius Costa Gomes 
8178aab4757SVinicius Costa Gomes void smp_chan_destroy(struct l2cap_conn *conn)
8188aab4757SVinicius Costa Gomes {
8195d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
8205d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
821f4a407beSJohan Hedberg 	bool complete;
822c8eb9690SBrian Gix 
823f1c09c07SVinicius Costa Gomes 	BUG_ON(!smp);
824c8eb9690SBrian Gix 
8254a74d658SJohan Hedberg 	complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags);
826f4a407beSJohan Hedberg 	mgmt_smp_complete(conn->hcon, complete);
827f4a407beSJohan Hedberg 
8287ee4ea36SMarcel Holtmann 	kfree(smp->csrk);
8297ee4ea36SMarcel Holtmann 	kfree(smp->slave_csrk);
8307ee4ea36SMarcel Holtmann 
8316a7bd103SJohan Hedberg 	crypto_free_blkcipher(smp->tfm_aes);
8326a7bd103SJohan Hedberg 
833759331d7SJohan Hedberg 	/* If pairing failed clean up any keys we might have */
834759331d7SJohan Hedberg 	if (!complete) {
835759331d7SJohan Hedberg 		if (smp->ltk) {
836759331d7SJohan Hedberg 			list_del(&smp->ltk->list);
837759331d7SJohan Hedberg 			kfree(smp->ltk);
838759331d7SJohan Hedberg 		}
839759331d7SJohan Hedberg 
840759331d7SJohan Hedberg 		if (smp->slave_ltk) {
841759331d7SJohan Hedberg 			list_del(&smp->slave_ltk->list);
842759331d7SJohan Hedberg 			kfree(smp->slave_ltk);
843759331d7SJohan Hedberg 		}
844759331d7SJohan Hedberg 
845759331d7SJohan Hedberg 		if (smp->remote_irk) {
846759331d7SJohan Hedberg 			list_del(&smp->remote_irk->list);
847759331d7SJohan Hedberg 			kfree(smp->remote_irk);
848759331d7SJohan Hedberg 		}
849759331d7SJohan Hedberg 	}
850759331d7SJohan Hedberg 
8515d88cc73SJohan Hedberg 	chan->data = NULL;
852c8eb9690SBrian Gix 	kfree(smp);
85376a68ba0SDavid Herrmann 	hci_conn_drop(conn->hcon);
8548aab4757SVinicius Costa Gomes }
8558aab4757SVinicius Costa Gomes 
8562b64d153SBrian Gix int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
8572b64d153SBrian Gix {
858b10e8017SJohan Hedberg 	struct l2cap_conn *conn = hcon->l2cap_data;
8595d88cc73SJohan Hedberg 	struct l2cap_chan *chan;
8602b64d153SBrian Gix 	struct smp_chan *smp;
8612b64d153SBrian Gix 	u32 value;
8622b64d153SBrian Gix 
8632b64d153SBrian Gix 	BT_DBG("");
8642b64d153SBrian Gix 
865642ac774SJohan Hedberg 	if (!conn || !test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
8662b64d153SBrian Gix 		return -ENOTCONN;
8672b64d153SBrian Gix 
8685d88cc73SJohan Hedberg 	chan = conn->smp;
8695d88cc73SJohan Hedberg 	if (!chan)
8705d88cc73SJohan Hedberg 		return -ENOTCONN;
8715d88cc73SJohan Hedberg 
8725d88cc73SJohan Hedberg 	smp = chan->data;
8732b64d153SBrian Gix 
8742b64d153SBrian Gix 	switch (mgmt_op) {
8752b64d153SBrian Gix 	case MGMT_OP_USER_PASSKEY_REPLY:
8762b64d153SBrian Gix 		value = le32_to_cpu(passkey);
877943a732aSJohan Hedberg 		memset(smp->tk, 0, sizeof(smp->tk));
8782b64d153SBrian Gix 		BT_DBG("PassKey: %d", value);
879943a732aSJohan Hedberg 		put_unaligned_le32(value, smp->tk);
8802b64d153SBrian Gix 		/* Fall Through */
8812b64d153SBrian Gix 	case MGMT_OP_USER_CONFIRM_REPLY:
8824a74d658SJohan Hedberg 		set_bit(SMP_FLAG_TK_VALID, &smp->flags);
8832b64d153SBrian Gix 		break;
8842b64d153SBrian Gix 	case MGMT_OP_USER_PASSKEY_NEG_REPLY:
8852b64d153SBrian Gix 	case MGMT_OP_USER_CONFIRM_NEG_REPLY:
88684794e11SJohan Hedberg 		smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
8872b64d153SBrian Gix 		return 0;
8882b64d153SBrian Gix 	default:
88984794e11SJohan Hedberg 		smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
8902b64d153SBrian Gix 		return -EOPNOTSUPP;
8912b64d153SBrian Gix 	}
8922b64d153SBrian Gix 
8932b64d153SBrian Gix 	/* If it is our turn to send Pairing Confirm, do so now */
8941cc61144SJohan Hedberg 	if (test_bit(SMP_FLAG_CFM_PENDING, &smp->flags)) {
8951cc61144SJohan Hedberg 		u8 rsp = smp_confirm(smp);
8961cc61144SJohan Hedberg 		if (rsp)
8971cc61144SJohan Hedberg 			smp_failure(conn, rsp);
8981cc61144SJohan Hedberg 	}
8992b64d153SBrian Gix 
9002b64d153SBrian Gix 	return 0;
9012b64d153SBrian Gix }
9022b64d153SBrian Gix 
903da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
90488ba43b6SAnderson Briglia {
9053158c50cSVinicius Costa Gomes 	struct smp_cmd_pairing rsp, *req = (void *) skb->data;
906b3c6410bSJohan Hedberg 	struct hci_dev *hdev = conn->hcon->hdev;
9078aab4757SVinicius Costa Gomes 	struct smp_chan *smp;
908c7262e71SJohan Hedberg 	u8 key_size, auth, sec_level;
9098aab4757SVinicius Costa Gomes 	int ret;
91088ba43b6SAnderson Briglia 
91188ba43b6SAnderson Briglia 	BT_DBG("conn %p", conn);
91288ba43b6SAnderson Briglia 
913c46b98beSJohan Hedberg 	if (skb->len < sizeof(*req))
91438e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
915c46b98beSJohan Hedberg 
91640bef302SJohan Hedberg 	if (conn->hcon->role != HCI_ROLE_SLAVE)
9172b64d153SBrian Gix 		return SMP_CMD_NOTSUPP;
9182b64d153SBrian Gix 
9195d88cc73SJohan Hedberg 	if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
9208aab4757SVinicius Costa Gomes 		smp = smp_chan_create(conn);
9215d88cc73SJohan Hedberg 	} else {
9225d88cc73SJohan Hedberg 		struct l2cap_chan *chan = conn->smp;
9235d88cc73SJohan Hedberg 		smp = chan->data;
9245d88cc73SJohan Hedberg 	}
925d26a2345SVinicius Costa Gomes 
926d08fd0e7SAndrei Emeltchenko 	if (!smp)
927d08fd0e7SAndrei Emeltchenko 		return SMP_UNSPECIFIED;
928d08fd0e7SAndrei Emeltchenko 
929b6ae8457SJohan Hedberg 	if (!test_bit(HCI_BONDABLE, &hdev->dev_flags) &&
930b3c6410bSJohan Hedberg 	    (req->auth_req & SMP_AUTH_BONDING))
931b3c6410bSJohan Hedberg 		return SMP_PAIRING_NOTSUPP;
932b3c6410bSJohan Hedberg 
9331c1def09SVinicius Costa Gomes 	smp->preq[0] = SMP_CMD_PAIRING_REQ;
9341c1def09SVinicius Costa Gomes 	memcpy(&smp->preq[1], req, sizeof(*req));
9353158c50cSVinicius Costa Gomes 	skb_pull(skb, sizeof(*req));
93688ba43b6SAnderson Briglia 
9372b64d153SBrian Gix 	/* We didn't start the pairing, so match remote */
9382b64d153SBrian Gix 	auth = req->auth_req;
939da85e5e5SVinicius Costa Gomes 
940c7262e71SJohan Hedberg 	sec_level = authreq_to_seclevel(auth);
941c7262e71SJohan Hedberg 	if (sec_level > conn->hcon->pending_sec_level)
942c7262e71SJohan Hedberg 		conn->hcon->pending_sec_level = sec_level;
943fdde0a26SIdo Yariv 
9442ed8f65cSJohan Hedberg 	/* If we need MITM check that it can be acheived */
9452ed8f65cSJohan Hedberg 	if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
9462ed8f65cSJohan Hedberg 		u8 method;
9472ed8f65cSJohan Hedberg 
9482ed8f65cSJohan Hedberg 		method = get_auth_method(smp, conn->hcon->io_capability,
9492ed8f65cSJohan Hedberg 					 req->io_capability);
9502ed8f65cSJohan Hedberg 		if (method == JUST_WORKS || method == JUST_CFM)
9512ed8f65cSJohan Hedberg 			return SMP_AUTH_REQUIREMENTS;
9522ed8f65cSJohan Hedberg 	}
9532ed8f65cSJohan Hedberg 
9542b64d153SBrian Gix 	build_pairing_cmd(conn, req, &rsp, auth);
9553158c50cSVinicius Costa Gomes 
9563158c50cSVinicius Costa Gomes 	key_size = min(req->max_key_size, rsp.max_key_size);
9573158c50cSVinicius Costa Gomes 	if (check_enc_key_size(conn, key_size))
9583158c50cSVinicius Costa Gomes 		return SMP_ENC_KEY_SIZE;
95988ba43b6SAnderson Briglia 
960e84a6b13SJohan Hedberg 	get_random_bytes(smp->prnd, sizeof(smp->prnd));
9618aab4757SVinicius Costa Gomes 
9621c1def09SVinicius Costa Gomes 	smp->prsp[0] = SMP_CMD_PAIRING_RSP;
9631c1def09SVinicius Costa Gomes 	memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
964f01ead31SAnderson Briglia 
9653158c50cSVinicius Costa Gomes 	smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
966da85e5e5SVinicius Costa Gomes 
9672b64d153SBrian Gix 	/* Request setup of TK */
9682b64d153SBrian Gix 	ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability);
9692b64d153SBrian Gix 	if (ret)
9702b64d153SBrian Gix 		return SMP_UNSPECIFIED;
9712b64d153SBrian Gix 
972da85e5e5SVinicius Costa Gomes 	return 0;
97388ba43b6SAnderson Briglia }
97488ba43b6SAnderson Briglia 
975da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
97688ba43b6SAnderson Briglia {
9773158c50cSVinicius Costa Gomes 	struct smp_cmd_pairing *req, *rsp = (void *) skb->data;
9785d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
9795d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
9802b64d153SBrian Gix 	u8 key_size, auth = SMP_AUTH_NONE;
9817d24ddccSAnderson Briglia 	int ret;
98288ba43b6SAnderson Briglia 
98388ba43b6SAnderson Briglia 	BT_DBG("conn %p", conn);
98488ba43b6SAnderson Briglia 
985c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rsp))
98638e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
987c46b98beSJohan Hedberg 
98840bef302SJohan Hedberg 	if (conn->hcon->role != HCI_ROLE_MASTER)
9892b64d153SBrian Gix 		return SMP_CMD_NOTSUPP;
9902b64d153SBrian Gix 
9913158c50cSVinicius Costa Gomes 	skb_pull(skb, sizeof(*rsp));
992da85e5e5SVinicius Costa Gomes 
9931c1def09SVinicius Costa Gomes 	req = (void *) &smp->preq[1];
9943158c50cSVinicius Costa Gomes 
9953158c50cSVinicius Costa Gomes 	key_size = min(req->max_key_size, rsp->max_key_size);
9963158c50cSVinicius Costa Gomes 	if (check_enc_key_size(conn, key_size))
9973158c50cSVinicius Costa Gomes 		return SMP_ENC_KEY_SIZE;
9983158c50cSVinicius Costa Gomes 
9992ed8f65cSJohan Hedberg 	/* If we need MITM check that it can be acheived */
10002ed8f65cSJohan Hedberg 	if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
10012ed8f65cSJohan Hedberg 		u8 method;
10022ed8f65cSJohan Hedberg 
10032ed8f65cSJohan Hedberg 		method = get_auth_method(smp, req->io_capability,
10042ed8f65cSJohan Hedberg 					 rsp->io_capability);
10052ed8f65cSJohan Hedberg 		if (method == JUST_WORKS || method == JUST_CFM)
10062ed8f65cSJohan Hedberg 			return SMP_AUTH_REQUIREMENTS;
10072ed8f65cSJohan Hedberg 	}
10082ed8f65cSJohan Hedberg 
1009e84a6b13SJohan Hedberg 	get_random_bytes(smp->prnd, sizeof(smp->prnd));
10107d24ddccSAnderson Briglia 
10118aab4757SVinicius Costa Gomes 	smp->prsp[0] = SMP_CMD_PAIRING_RSP;
10128aab4757SVinicius Costa Gomes 	memcpy(&smp->prsp[1], rsp, sizeof(*rsp));
10137d24ddccSAnderson Briglia 
1014fdcc4becSJohan Hedberg 	/* Update remote key distribution in case the remote cleared
1015fdcc4becSJohan Hedberg 	 * some bits that we had enabled in our request.
1016fdcc4becSJohan Hedberg 	 */
1017fdcc4becSJohan Hedberg 	smp->remote_key_dist &= rsp->resp_key_dist;
1018fdcc4becSJohan Hedberg 
10192b64d153SBrian Gix 	if ((req->auth_req & SMP_AUTH_BONDING) &&
10202b64d153SBrian Gix 	    (rsp->auth_req & SMP_AUTH_BONDING))
10212b64d153SBrian Gix 		auth = SMP_AUTH_BONDING;
10222b64d153SBrian Gix 
10232b64d153SBrian Gix 	auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM;
10242b64d153SBrian Gix 
1025476585ecSJohan Hedberg 	ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability);
10262b64d153SBrian Gix 	if (ret)
10272b64d153SBrian Gix 		return SMP_UNSPECIFIED;
10282b64d153SBrian Gix 
10294a74d658SJohan Hedberg 	set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
10302b64d153SBrian Gix 
10312b64d153SBrian Gix 	/* Can't compose response until we have been confirmed */
10324a74d658SJohan Hedberg 	if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
10331cc61144SJohan Hedberg 		return smp_confirm(smp);
1034da85e5e5SVinicius Costa Gomes 
1035da85e5e5SVinicius Costa Gomes 	return 0;
103688ba43b6SAnderson Briglia }
103788ba43b6SAnderson Briglia 
1038da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
103988ba43b6SAnderson Briglia {
10405d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
10415d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
10427d24ddccSAnderson Briglia 
104388ba43b6SAnderson Briglia 	BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
104488ba43b6SAnderson Briglia 
1045c46b98beSJohan Hedberg 	if (skb->len < sizeof(smp->pcnf))
104638e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1047c46b98beSJohan Hedberg 
10481c1def09SVinicius Costa Gomes 	memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf));
10491c1def09SVinicius Costa Gomes 	skb_pull(skb, sizeof(smp->pcnf));
10507d24ddccSAnderson Briglia 
1051943a732aSJohan Hedberg 	if (conn->hcon->out)
1052943a732aSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
1053943a732aSJohan Hedberg 			     smp->prnd);
10544a74d658SJohan Hedberg 	else if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
10551cc61144SJohan Hedberg 		return smp_confirm(smp);
1056943a732aSJohan Hedberg 	else
10574a74d658SJohan Hedberg 		set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
1058da85e5e5SVinicius Costa Gomes 
1059da85e5e5SVinicius Costa Gomes 	return 0;
106088ba43b6SAnderson Briglia }
106188ba43b6SAnderson Briglia 
1062da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
106388ba43b6SAnderson Briglia {
10645d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
10655d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
10667d24ddccSAnderson Briglia 
10678aab4757SVinicius Costa Gomes 	BT_DBG("conn %p", conn);
10687d24ddccSAnderson Briglia 
1069c46b98beSJohan Hedberg 	if (skb->len < sizeof(smp->rrnd))
107038e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1071c46b98beSJohan Hedberg 
1072943a732aSJohan Hedberg 	memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd));
10738aab4757SVinicius Costa Gomes 	skb_pull(skb, sizeof(smp->rrnd));
107488ba43b6SAnderson Briglia 
1075861580a9SJohan Hedberg 	return smp_random(smp);
107688ba43b6SAnderson Briglia }
107788ba43b6SAnderson Briglia 
1078f81cd823SMarcel Holtmann static bool smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
1079988c5997SVinicius Costa Gomes {
1080c9839a11SVinicius Costa Gomes 	struct smp_ltk *key;
1081988c5997SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
1082988c5997SVinicius Costa Gomes 
108398a0b845SJohan Hedberg 	key = hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type,
1084e804d25dSJohan Hedberg 				   hcon->role);
1085988c5997SVinicius Costa Gomes 	if (!key)
1086f81cd823SMarcel Holtmann 		return false;
1087988c5997SVinicius Costa Gomes 
10884dab7864SJohan Hedberg 	if (sec_level > BT_SECURITY_MEDIUM && !key->authenticated)
1089f81cd823SMarcel Holtmann 		return false;
10904dab7864SJohan Hedberg 
109151a8efd7SJohan Hedberg 	if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
1092f81cd823SMarcel Holtmann 		return true;
1093988c5997SVinicius Costa Gomes 
1094c9839a11SVinicius Costa Gomes 	hci_le_start_enc(hcon, key->ediv, key->rand, key->val);
1095c9839a11SVinicius Costa Gomes 	hcon->enc_key_size = key->enc_size;
1096988c5997SVinicius Costa Gomes 
1097fe59a05fSJohan Hedberg 	/* We never store STKs for master role, so clear this flag */
1098fe59a05fSJohan Hedberg 	clear_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags);
1099fe59a05fSJohan Hedberg 
1100f81cd823SMarcel Holtmann 	return true;
1101988c5997SVinicius Costa Gomes }
1102f1560463SMarcel Holtmann 
1103854f4727SJohan Hedberg bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level)
1104854f4727SJohan Hedberg {
1105854f4727SJohan Hedberg 	if (sec_level == BT_SECURITY_LOW)
1106854f4727SJohan Hedberg 		return true;
1107854f4727SJohan Hedberg 
11089ab65d60SJohan Hedberg 	/* If we're encrypted with an STK always claim insufficient
11099ab65d60SJohan Hedberg 	 * security. This way we allow the connection to be re-encrypted
11109ab65d60SJohan Hedberg 	 * with an LTK, even if the LTK provides the same level of
1111b2d5e254SJohan Hedberg 	 * security. Only exception is if we don't have an LTK (e.g.
1112b2d5e254SJohan Hedberg 	 * because of key distribution bits).
11139ab65d60SJohan Hedberg 	 */
1114b2d5e254SJohan Hedberg 	if (test_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags) &&
1115b2d5e254SJohan Hedberg 	    hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type,
1116e804d25dSJohan Hedberg 				 hcon->role))
11179ab65d60SJohan Hedberg 		return false;
11189ab65d60SJohan Hedberg 
1119854f4727SJohan Hedberg 	if (hcon->sec_level >= sec_level)
1120854f4727SJohan Hedberg 		return true;
1121854f4727SJohan Hedberg 
1122854f4727SJohan Hedberg 	return false;
1123854f4727SJohan Hedberg }
1124854f4727SJohan Hedberg 
1125da85e5e5SVinicius Costa Gomes static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
112688ba43b6SAnderson Briglia {
112788ba43b6SAnderson Briglia 	struct smp_cmd_security_req *rp = (void *) skb->data;
112888ba43b6SAnderson Briglia 	struct smp_cmd_pairing cp;
1129f1cb9af5SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
11308aab4757SVinicius Costa Gomes 	struct smp_chan *smp;
1131c7262e71SJohan Hedberg 	u8 sec_level;
113288ba43b6SAnderson Briglia 
113388ba43b6SAnderson Briglia 	BT_DBG("conn %p", conn);
113488ba43b6SAnderson Briglia 
1135c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rp))
113638e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1137c46b98beSJohan Hedberg 
113840bef302SJohan Hedberg 	if (hcon->role != HCI_ROLE_MASTER)
113986ca9eacSJohan Hedberg 		return SMP_CMD_NOTSUPP;
114086ca9eacSJohan Hedberg 
1141c7262e71SJohan Hedberg 	sec_level = authreq_to_seclevel(rp->auth_req);
1142854f4727SJohan Hedberg 	if (smp_sufficient_security(hcon, sec_level))
1143854f4727SJohan Hedberg 		return 0;
1144854f4727SJohan Hedberg 
1145c7262e71SJohan Hedberg 	if (sec_level > hcon->pending_sec_level)
1146c7262e71SJohan Hedberg 		hcon->pending_sec_level = sec_level;
1147feb45eb5SVinicius Costa Gomes 
11484dab7864SJohan Hedberg 	if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
1149988c5997SVinicius Costa Gomes 		return 0;
1150988c5997SVinicius Costa Gomes 
115151a8efd7SJohan Hedberg 	if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
1152da85e5e5SVinicius Costa Gomes 		return 0;
1153f1cb9af5SVinicius Costa Gomes 
11548aab4757SVinicius Costa Gomes 	smp = smp_chan_create(conn);
1155c29d2444SJohan Hedberg 	if (!smp)
1156c29d2444SJohan Hedberg 		return SMP_UNSPECIFIED;
1157d26a2345SVinicius Costa Gomes 
1158b6ae8457SJohan Hedberg 	if (!test_bit(HCI_BONDABLE, &hcon->hdev->dev_flags) &&
1159616d55beSJohan Hedberg 	    (rp->auth_req & SMP_AUTH_BONDING))
1160616d55beSJohan Hedberg 		return SMP_PAIRING_NOTSUPP;
1161616d55beSJohan Hedberg 
116288ba43b6SAnderson Briglia 	skb_pull(skb, sizeof(*rp));
116388ba43b6SAnderson Briglia 
1164da85e5e5SVinicius Costa Gomes 	memset(&cp, 0, sizeof(cp));
116554790f73SVinicius Costa Gomes 	build_pairing_cmd(conn, &cp, NULL, rp->auth_req);
116688ba43b6SAnderson Briglia 
11671c1def09SVinicius Costa Gomes 	smp->preq[0] = SMP_CMD_PAIRING_REQ;
11681c1def09SVinicius Costa Gomes 	memcpy(&smp->preq[1], &cp, sizeof(cp));
1169f01ead31SAnderson Briglia 
117088ba43b6SAnderson Briglia 	smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
1171f1cb9af5SVinicius Costa Gomes 
1172da85e5e5SVinicius Costa Gomes 	return 0;
117388ba43b6SAnderson Briglia }
117488ba43b6SAnderson Briglia 
1175cc110922SVinicius Costa Gomes int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
1176eb492e01SAnderson Briglia {
1177cc110922SVinicius Costa Gomes 	struct l2cap_conn *conn = hcon->l2cap_data;
11780a66cf20SJohan Hedberg 	struct smp_chan *smp;
11792b64d153SBrian Gix 	__u8 authreq;
1180eb492e01SAnderson Briglia 
11813a0259bbSVinicius Costa Gomes 	BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
11823a0259bbSVinicius Costa Gomes 
11830a66cf20SJohan Hedberg 	/* This may be NULL if there's an unexpected disconnection */
11840a66cf20SJohan Hedberg 	if (!conn)
11850a66cf20SJohan Hedberg 		return 1;
11860a66cf20SJohan Hedberg 
1187757aee0fSJohan Hedberg 	if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags))
11882e65c9d2SAndre Guedes 		return 1;
11892e65c9d2SAndre Guedes 
1190ad32a2f5SJohan Hedberg 	if (smp_sufficient_security(hcon, sec_level))
1191f1cb9af5SVinicius Costa Gomes 		return 1;
1192f1cb9af5SVinicius Costa Gomes 
1193c7262e71SJohan Hedberg 	if (sec_level > hcon->pending_sec_level)
1194c7262e71SJohan Hedberg 		hcon->pending_sec_level = sec_level;
1195c7262e71SJohan Hedberg 
119640bef302SJohan Hedberg 	if (hcon->role == HCI_ROLE_MASTER)
1197c7262e71SJohan Hedberg 		if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
1198c7262e71SJohan Hedberg 			return 0;
1199d26a2345SVinicius Costa Gomes 
120051a8efd7SJohan Hedberg 	if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
1201d26a2345SVinicius Costa Gomes 		return 0;
1202d26a2345SVinicius Costa Gomes 
12038aab4757SVinicius Costa Gomes 	smp = smp_chan_create(conn);
12042b64d153SBrian Gix 	if (!smp)
12052b64d153SBrian Gix 		return 1;
12062b64d153SBrian Gix 
12072b64d153SBrian Gix 	authreq = seclevel_to_authreq(sec_level);
1208d26a2345SVinicius Costa Gomes 
120979897d20SJohan Hedberg 	/* Require MITM if IO Capability allows or the security level
121079897d20SJohan Hedberg 	 * requires it.
12112e233644SJohan Hedberg 	 */
121279897d20SJohan Hedberg 	if (hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT ||
1213c7262e71SJohan Hedberg 	    hcon->pending_sec_level > BT_SECURITY_MEDIUM)
12142e233644SJohan Hedberg 		authreq |= SMP_AUTH_MITM;
12152e233644SJohan Hedberg 
121640bef302SJohan Hedberg 	if (hcon->role == HCI_ROLE_MASTER) {
1217d26a2345SVinicius Costa Gomes 		struct smp_cmd_pairing cp;
1218f01ead31SAnderson Briglia 
12192b64d153SBrian Gix 		build_pairing_cmd(conn, &cp, NULL, authreq);
12201c1def09SVinicius Costa Gomes 		smp->preq[0] = SMP_CMD_PAIRING_REQ;
12211c1def09SVinicius Costa Gomes 		memcpy(&smp->preq[1], &cp, sizeof(cp));
1222f01ead31SAnderson Briglia 
1223eb492e01SAnderson Briglia 		smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
1224eb492e01SAnderson Briglia 	} else {
1225eb492e01SAnderson Briglia 		struct smp_cmd_security_req cp;
12262b64d153SBrian Gix 		cp.auth_req = authreq;
1227eb492e01SAnderson Briglia 		smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
1228eb492e01SAnderson Briglia 	}
1229eb492e01SAnderson Briglia 
12304a74d658SJohan Hedberg 	set_bit(SMP_FLAG_INITIATOR, &smp->flags);
1231edca792cSJohan Hedberg 
1232eb492e01SAnderson Briglia 	return 0;
1233eb492e01SAnderson Briglia }
1234eb492e01SAnderson Briglia 
12357034b911SVinicius Costa Gomes static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
12367034b911SVinicius Costa Gomes {
123716b90839SVinicius Costa Gomes 	struct smp_cmd_encrypt_info *rp = (void *) skb->data;
12385d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
12395d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
124016b90839SVinicius Costa Gomes 
1241c46b98beSJohan Hedberg 	BT_DBG("conn %p", conn);
1242c46b98beSJohan Hedberg 
1243c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rp))
124438e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1245c46b98beSJohan Hedberg 
12466131ddc8SJohan Hedberg 	/* Ignore this PDU if it wasn't requested */
12476131ddc8SJohan Hedberg 	if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
12486131ddc8SJohan Hedberg 		return 0;
12496131ddc8SJohan Hedberg 
125016b90839SVinicius Costa Gomes 	skb_pull(skb, sizeof(*rp));
125116b90839SVinicius Costa Gomes 
12521c1def09SVinicius Costa Gomes 	memcpy(smp->tk, rp->ltk, sizeof(smp->tk));
125316b90839SVinicius Costa Gomes 
12547034b911SVinicius Costa Gomes 	return 0;
12557034b911SVinicius Costa Gomes }
12567034b911SVinicius Costa Gomes 
12577034b911SVinicius Costa Gomes static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
12587034b911SVinicius Costa Gomes {
125916b90839SVinicius Costa Gomes 	struct smp_cmd_master_ident *rp = (void *) skb->data;
12605d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
12615d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
1262c9839a11SVinicius Costa Gomes 	struct hci_dev *hdev = conn->hcon->hdev;
1263c9839a11SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
126423d0e128SJohan Hedberg 	struct smp_ltk *ltk;
1265c9839a11SVinicius Costa Gomes 	u8 authenticated;
12667034b911SVinicius Costa Gomes 
1267c46b98beSJohan Hedberg 	BT_DBG("conn %p", conn);
1268c46b98beSJohan Hedberg 
1269c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rp))
127038e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1271c46b98beSJohan Hedberg 
12726131ddc8SJohan Hedberg 	/* Ignore this PDU if it wasn't requested */
12736131ddc8SJohan Hedberg 	if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
12746131ddc8SJohan Hedberg 		return 0;
12756131ddc8SJohan Hedberg 
12769747a9f3SJohan Hedberg 	/* Mark the information as received */
12779747a9f3SJohan Hedberg 	smp->remote_key_dist &= ~SMP_DIST_ENC_KEY;
12789747a9f3SJohan Hedberg 
127916b90839SVinicius Costa Gomes 	skb_pull(skb, sizeof(*rp));
128016b90839SVinicius Costa Gomes 
1281c9839a11SVinicius Costa Gomes 	hci_dev_lock(hdev);
1282ce39fb4eSMarcel Holtmann 	authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
12832ceba539SJohan Hedberg 	ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, SMP_LTK,
1284ce39fb4eSMarcel Holtmann 			  authenticated, smp->tk, smp->enc_key_size,
128504124681SGustavo F. Padovan 			  rp->ediv, rp->rand);
128623d0e128SJohan Hedberg 	smp->ltk = ltk;
1287fd349c02SJohan Hedberg 	if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
12884bd6d38eSJohan Hedberg 		smp_distribute_keys(conn);
1289c9839a11SVinicius Costa Gomes 	hci_dev_unlock(hdev);
12907034b911SVinicius Costa Gomes 
12917034b911SVinicius Costa Gomes 	return 0;
12927034b911SVinicius Costa Gomes }
12937034b911SVinicius Costa Gomes 
1294fd349c02SJohan Hedberg static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
1295fd349c02SJohan Hedberg {
1296fd349c02SJohan Hedberg 	struct smp_cmd_ident_info *info = (void *) skb->data;
12975d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
12985d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
1299fd349c02SJohan Hedberg 
1300fd349c02SJohan Hedberg 	BT_DBG("");
1301fd349c02SJohan Hedberg 
1302fd349c02SJohan Hedberg 	if (skb->len < sizeof(*info))
130338e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1304fd349c02SJohan Hedberg 
13056131ddc8SJohan Hedberg 	/* Ignore this PDU if it wasn't requested */
13066131ddc8SJohan Hedberg 	if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
13076131ddc8SJohan Hedberg 		return 0;
13086131ddc8SJohan Hedberg 
1309fd349c02SJohan Hedberg 	skb_pull(skb, sizeof(*info));
1310fd349c02SJohan Hedberg 
1311fd349c02SJohan Hedberg 	memcpy(smp->irk, info->irk, 16);
1312fd349c02SJohan Hedberg 
1313fd349c02SJohan Hedberg 	return 0;
1314fd349c02SJohan Hedberg }
1315fd349c02SJohan Hedberg 
1316fd349c02SJohan Hedberg static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
1317fd349c02SJohan Hedberg 				   struct sk_buff *skb)
1318fd349c02SJohan Hedberg {
1319fd349c02SJohan Hedberg 	struct smp_cmd_ident_addr_info *info = (void *) skb->data;
13205d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
13215d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
1322fd349c02SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
1323fd349c02SJohan Hedberg 	bdaddr_t rpa;
1324fd349c02SJohan Hedberg 
1325fd349c02SJohan Hedberg 	BT_DBG("");
1326fd349c02SJohan Hedberg 
1327fd349c02SJohan Hedberg 	if (skb->len < sizeof(*info))
132838e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1329fd349c02SJohan Hedberg 
13306131ddc8SJohan Hedberg 	/* Ignore this PDU if it wasn't requested */
13316131ddc8SJohan Hedberg 	if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
13326131ddc8SJohan Hedberg 		return 0;
13336131ddc8SJohan Hedberg 
13349747a9f3SJohan Hedberg 	/* Mark the information as received */
13359747a9f3SJohan Hedberg 	smp->remote_key_dist &= ~SMP_DIST_ID_KEY;
13369747a9f3SJohan Hedberg 
1337fd349c02SJohan Hedberg 	skb_pull(skb, sizeof(*info));
1338fd349c02SJohan Hedberg 
133931dd624eSJohan Hedberg 	hci_dev_lock(hcon->hdev);
134031dd624eSJohan Hedberg 
1341a9a58f86SJohan Hedberg 	/* Strictly speaking the Core Specification (4.1) allows sending
1342a9a58f86SJohan Hedberg 	 * an empty address which would force us to rely on just the IRK
1343a9a58f86SJohan Hedberg 	 * as "identity information". However, since such
1344a9a58f86SJohan Hedberg 	 * implementations are not known of and in order to not over
1345a9a58f86SJohan Hedberg 	 * complicate our implementation, simply pretend that we never
1346a9a58f86SJohan Hedberg 	 * received an IRK for such a device.
1347a9a58f86SJohan Hedberg 	 */
1348a9a58f86SJohan Hedberg 	if (!bacmp(&info->bdaddr, BDADDR_ANY)) {
1349a9a58f86SJohan Hedberg 		BT_ERR("Ignoring IRK with no identity address");
135031dd624eSJohan Hedberg 		goto distribute;
1351a9a58f86SJohan Hedberg 	}
1352a9a58f86SJohan Hedberg 
1353fd349c02SJohan Hedberg 	bacpy(&smp->id_addr, &info->bdaddr);
1354fd349c02SJohan Hedberg 	smp->id_addr_type = info->addr_type;
1355fd349c02SJohan Hedberg 
1356fd349c02SJohan Hedberg 	if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type))
1357fd349c02SJohan Hedberg 		bacpy(&rpa, &hcon->dst);
1358fd349c02SJohan Hedberg 	else
1359fd349c02SJohan Hedberg 		bacpy(&rpa, BDADDR_ANY);
1360fd349c02SJohan Hedberg 
136123d0e128SJohan Hedberg 	smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
136223d0e128SJohan Hedberg 				      smp->id_addr_type, smp->irk, &rpa);
1363fd349c02SJohan Hedberg 
136431dd624eSJohan Hedberg distribute:
13654bd6d38eSJohan Hedberg 	smp_distribute_keys(conn);
1366fd349c02SJohan Hedberg 
136731dd624eSJohan Hedberg 	hci_dev_unlock(hcon->hdev);
136831dd624eSJohan Hedberg 
1369fd349c02SJohan Hedberg 	return 0;
1370fd349c02SJohan Hedberg }
1371fd349c02SJohan Hedberg 
13727ee4ea36SMarcel Holtmann static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)
13737ee4ea36SMarcel Holtmann {
13747ee4ea36SMarcel Holtmann 	struct smp_cmd_sign_info *rp = (void *) skb->data;
13755d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
13765d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
13777ee4ea36SMarcel Holtmann 	struct hci_dev *hdev = conn->hcon->hdev;
13787ee4ea36SMarcel Holtmann 	struct smp_csrk *csrk;
13797ee4ea36SMarcel Holtmann 
13807ee4ea36SMarcel Holtmann 	BT_DBG("conn %p", conn);
13817ee4ea36SMarcel Holtmann 
13827ee4ea36SMarcel Holtmann 	if (skb->len < sizeof(*rp))
138338e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
13847ee4ea36SMarcel Holtmann 
13857ee4ea36SMarcel Holtmann 	/* Ignore this PDU if it wasn't requested */
13867ee4ea36SMarcel Holtmann 	if (!(smp->remote_key_dist & SMP_DIST_SIGN))
13877ee4ea36SMarcel Holtmann 		return 0;
13887ee4ea36SMarcel Holtmann 
13897ee4ea36SMarcel Holtmann 	/* Mark the information as received */
13907ee4ea36SMarcel Holtmann 	smp->remote_key_dist &= ~SMP_DIST_SIGN;
13917ee4ea36SMarcel Holtmann 
13927ee4ea36SMarcel Holtmann 	skb_pull(skb, sizeof(*rp));
13937ee4ea36SMarcel Holtmann 
13947ee4ea36SMarcel Holtmann 	hci_dev_lock(hdev);
13957ee4ea36SMarcel Holtmann 	csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
13967ee4ea36SMarcel Holtmann 	if (csrk) {
13977ee4ea36SMarcel Holtmann 		csrk->master = 0x01;
13987ee4ea36SMarcel Holtmann 		memcpy(csrk->val, rp->csrk, sizeof(csrk->val));
13997ee4ea36SMarcel Holtmann 	}
14007ee4ea36SMarcel Holtmann 	smp->csrk = csrk;
14017ee4ea36SMarcel Holtmann 	smp_distribute_keys(conn);
14027ee4ea36SMarcel Holtmann 	hci_dev_unlock(hdev);
14037ee4ea36SMarcel Holtmann 
14047ee4ea36SMarcel Holtmann 	return 0;
14057ee4ea36SMarcel Holtmann }
14067ee4ea36SMarcel Holtmann 
14074befb867SJohan Hedberg static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb)
1408eb492e01SAnderson Briglia {
14095d88cc73SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
14107b9899dbSMarcel Holtmann 	struct hci_conn *hcon = conn->hcon;
141192381f5cSMarcel Holtmann 	__u8 code, reason;
1412eb492e01SAnderson Briglia 	int err = 0;
1413eb492e01SAnderson Briglia 
14147b9899dbSMarcel Holtmann 	if (hcon->type != LE_LINK) {
14157b9899dbSMarcel Holtmann 		kfree_skb(skb);
14163432711fSJohan Hedberg 		return 0;
14177b9899dbSMarcel Holtmann 	}
14187b9899dbSMarcel Holtmann 
14198ae9b984SJohan Hedberg 	if (skb->len < 1)
142092381f5cSMarcel Holtmann 		return -EILSEQ;
142192381f5cSMarcel Holtmann 
142206ae3314SMarcel Holtmann 	if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) {
1423beb19e4cSJohan Hedberg 		err = -EOPNOTSUPP;
14242e65c9d2SAndre Guedes 		reason = SMP_PAIRING_NOTSUPP;
14252e65c9d2SAndre Guedes 		goto done;
14262e65c9d2SAndre Guedes 	}
14272e65c9d2SAndre Guedes 
142892381f5cSMarcel Holtmann 	code = skb->data[0];
1429eb492e01SAnderson Briglia 	skb_pull(skb, sizeof(code));
1430eb492e01SAnderson Briglia 
14318cf9fa12SJohan Hedberg 	/*
14328cf9fa12SJohan Hedberg 	 * The SMP context must be initialized for all other PDUs except
14338cf9fa12SJohan Hedberg 	 * pairing and security requests. If we get any other PDU when
14348cf9fa12SJohan Hedberg 	 * not initialized simply disconnect (done if this function
14358cf9fa12SJohan Hedberg 	 * returns an error).
14368cf9fa12SJohan Hedberg 	 */
14378cf9fa12SJohan Hedberg 	if (code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ &&
1438d3368605SJohan Hedberg 	    !test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
14398cf9fa12SJohan Hedberg 		BT_ERR("Unexpected SMP command 0x%02x. Disconnecting.", code);
14408ae9b984SJohan Hedberg 		reason = SMP_CMD_NOTSUPP;
14418ae9b984SJohan Hedberg 		err = -EOPNOTSUPP;
14428ae9b984SJohan Hedberg 		goto done;
14438cf9fa12SJohan Hedberg 	}
14448cf9fa12SJohan Hedberg 
1445eb492e01SAnderson Briglia 	switch (code) {
1446eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_REQ:
1447da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_req(conn, skb);
1448eb492e01SAnderson Briglia 		break;
1449eb492e01SAnderson Briglia 
1450eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_FAIL:
145184794e11SJohan Hedberg 		smp_failure(conn, 0);
1452da85e5e5SVinicius Costa Gomes 		reason = 0;
1453da85e5e5SVinicius Costa Gomes 		err = -EPERM;
1454eb492e01SAnderson Briglia 		break;
1455eb492e01SAnderson Briglia 
1456eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_RSP:
1457da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_rsp(conn, skb);
145888ba43b6SAnderson Briglia 		break;
145988ba43b6SAnderson Briglia 
146088ba43b6SAnderson Briglia 	case SMP_CMD_SECURITY_REQ:
1461da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_security_req(conn, skb);
146288ba43b6SAnderson Briglia 		break;
146388ba43b6SAnderson Briglia 
1464eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_CONFIRM:
1465da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_confirm(conn, skb);
146688ba43b6SAnderson Briglia 		break;
146788ba43b6SAnderson Briglia 
1468eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_RANDOM:
1469da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_random(conn, skb);
147088ba43b6SAnderson Briglia 		break;
147188ba43b6SAnderson Briglia 
1472eb492e01SAnderson Briglia 	case SMP_CMD_ENCRYPT_INFO:
14737034b911SVinicius Costa Gomes 		reason = smp_cmd_encrypt_info(conn, skb);
14747034b911SVinicius Costa Gomes 		break;
14757034b911SVinicius Costa Gomes 
1476eb492e01SAnderson Briglia 	case SMP_CMD_MASTER_IDENT:
14777034b911SVinicius Costa Gomes 		reason = smp_cmd_master_ident(conn, skb);
14787034b911SVinicius Costa Gomes 		break;
14797034b911SVinicius Costa Gomes 
1480eb492e01SAnderson Briglia 	case SMP_CMD_IDENT_INFO:
1481fd349c02SJohan Hedberg 		reason = smp_cmd_ident_info(conn, skb);
1482fd349c02SJohan Hedberg 		break;
1483fd349c02SJohan Hedberg 
1484eb492e01SAnderson Briglia 	case SMP_CMD_IDENT_ADDR_INFO:
1485fd349c02SJohan Hedberg 		reason = smp_cmd_ident_addr_info(conn, skb);
1486fd349c02SJohan Hedberg 		break;
1487fd349c02SJohan Hedberg 
1488eb492e01SAnderson Briglia 	case SMP_CMD_SIGN_INFO:
14897ee4ea36SMarcel Holtmann 		reason = smp_cmd_sign_info(conn, skb);
14907034b911SVinicius Costa Gomes 		break;
14917034b911SVinicius Costa Gomes 
1492eb492e01SAnderson Briglia 	default:
1493eb492e01SAnderson Briglia 		BT_DBG("Unknown command code 0x%2.2x", code);
1494eb492e01SAnderson Briglia 
1495eb492e01SAnderson Briglia 		reason = SMP_CMD_NOTSUPP;
14963a0259bbSVinicius Costa Gomes 		err = -EOPNOTSUPP;
14973a0259bbSVinicius Costa Gomes 		goto done;
14983a0259bbSVinicius Costa Gomes 	}
14993a0259bbSVinicius Costa Gomes 
15003a0259bbSVinicius Costa Gomes done:
15013a0259bbSVinicius Costa Gomes 	if (reason)
150284794e11SJohan Hedberg 		smp_failure(conn, reason);
15038ae9b984SJohan Hedberg 	if (!err)
1504eb492e01SAnderson Briglia 		kfree_skb(skb);
1505eb492e01SAnderson Briglia 	return err;
1506eb492e01SAnderson Briglia }
15077034b911SVinicius Costa Gomes 
150870db83c4SJohan Hedberg static void smp_teardown_cb(struct l2cap_chan *chan, int err)
150970db83c4SJohan Hedberg {
151070db83c4SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
1511b68fda68SJohan Hedberg 	struct smp_chan *smp = chan->data;
151270db83c4SJohan Hedberg 
151370db83c4SJohan Hedberg 	BT_DBG("chan %p", chan);
151470db83c4SJohan Hedberg 
15155d88cc73SJohan Hedberg 	if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1516b68fda68SJohan Hedberg 		cancel_delayed_work_sync(&smp->security_timer);
15175d88cc73SJohan Hedberg 		smp_chan_destroy(conn);
15185d88cc73SJohan Hedberg 	}
15195d88cc73SJohan Hedberg 
152070db83c4SJohan Hedberg 	conn->smp = NULL;
152170db83c4SJohan Hedberg 	l2cap_chan_put(chan);
152270db83c4SJohan Hedberg }
152370db83c4SJohan Hedberg 
152444f1a7abSJohan Hedberg static void smp_resume_cb(struct l2cap_chan *chan)
152544f1a7abSJohan Hedberg {
1526b68fda68SJohan Hedberg 	struct smp_chan *smp = chan->data;
152744f1a7abSJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
152844f1a7abSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
152944f1a7abSJohan Hedberg 
153044f1a7abSJohan Hedberg 	BT_DBG("chan %p", chan);
153144f1a7abSJohan Hedberg 
153244f1a7abSJohan Hedberg 	if (test_bit(HCI_CONN_ENCRYPT, &hcon->flags))
153344f1a7abSJohan Hedberg 		smp_distribute_keys(conn);
1534b68fda68SJohan Hedberg 
1535b68fda68SJohan Hedberg 	if (smp)
1536b68fda68SJohan Hedberg 		cancel_delayed_work(&smp->security_timer);
153744f1a7abSJohan Hedberg }
153844f1a7abSJohan Hedberg 
153970db83c4SJohan Hedberg static void smp_ready_cb(struct l2cap_chan *chan)
154070db83c4SJohan Hedberg {
154170db83c4SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
154270db83c4SJohan Hedberg 
154370db83c4SJohan Hedberg 	BT_DBG("chan %p", chan);
154470db83c4SJohan Hedberg 
154570db83c4SJohan Hedberg 	conn->smp = chan;
154670db83c4SJohan Hedberg 	l2cap_chan_hold(chan);
154770db83c4SJohan Hedberg }
154870db83c4SJohan Hedberg 
15494befb867SJohan Hedberg static int smp_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
15504befb867SJohan Hedberg {
15514befb867SJohan Hedberg 	int err;
15524befb867SJohan Hedberg 
15534befb867SJohan Hedberg 	BT_DBG("chan %p", chan);
15544befb867SJohan Hedberg 
15554befb867SJohan Hedberg 	err = smp_sig_channel(chan, skb);
15564befb867SJohan Hedberg 	if (err) {
1557b68fda68SJohan Hedberg 		struct smp_chan *smp = chan->data;
15584befb867SJohan Hedberg 
1559b68fda68SJohan Hedberg 		if (smp)
1560b68fda68SJohan Hedberg 			cancel_delayed_work_sync(&smp->security_timer);
15614befb867SJohan Hedberg 
15624befb867SJohan Hedberg 		l2cap_conn_shutdown(chan->conn, -err);
15634befb867SJohan Hedberg 	}
15644befb867SJohan Hedberg 
15654befb867SJohan Hedberg 	return err;
15664befb867SJohan Hedberg }
15674befb867SJohan Hedberg 
156870db83c4SJohan Hedberg static struct sk_buff *smp_alloc_skb_cb(struct l2cap_chan *chan,
156970db83c4SJohan Hedberg 					unsigned long hdr_len,
157070db83c4SJohan Hedberg 					unsigned long len, int nb)
157170db83c4SJohan Hedberg {
157270db83c4SJohan Hedberg 	struct sk_buff *skb;
157370db83c4SJohan Hedberg 
157470db83c4SJohan Hedberg 	skb = bt_skb_alloc(hdr_len + len, GFP_KERNEL);
157570db83c4SJohan Hedberg 	if (!skb)
157670db83c4SJohan Hedberg 		return ERR_PTR(-ENOMEM);
157770db83c4SJohan Hedberg 
157870db83c4SJohan Hedberg 	skb->priority = HCI_PRIO_MAX;
157970db83c4SJohan Hedberg 	bt_cb(skb)->chan = chan;
158070db83c4SJohan Hedberg 
158170db83c4SJohan Hedberg 	return skb;
158270db83c4SJohan Hedberg }
158370db83c4SJohan Hedberg 
158470db83c4SJohan Hedberg static const struct l2cap_ops smp_chan_ops = {
158570db83c4SJohan Hedberg 	.name			= "Security Manager",
158670db83c4SJohan Hedberg 	.ready			= smp_ready_cb,
15875d88cc73SJohan Hedberg 	.recv			= smp_recv_cb,
158870db83c4SJohan Hedberg 	.alloc_skb		= smp_alloc_skb_cb,
158970db83c4SJohan Hedberg 	.teardown		= smp_teardown_cb,
159044f1a7abSJohan Hedberg 	.resume			= smp_resume_cb,
159170db83c4SJohan Hedberg 
159270db83c4SJohan Hedberg 	.new_connection		= l2cap_chan_no_new_connection,
159370db83c4SJohan Hedberg 	.state_change		= l2cap_chan_no_state_change,
159470db83c4SJohan Hedberg 	.close			= l2cap_chan_no_close,
159570db83c4SJohan Hedberg 	.defer			= l2cap_chan_no_defer,
159670db83c4SJohan Hedberg 	.suspend		= l2cap_chan_no_suspend,
159770db83c4SJohan Hedberg 	.set_shutdown		= l2cap_chan_no_set_shutdown,
159870db83c4SJohan Hedberg 	.get_sndtimeo		= l2cap_chan_no_get_sndtimeo,
159970db83c4SJohan Hedberg 	.memcpy_fromiovec	= l2cap_chan_no_memcpy_fromiovec,
160070db83c4SJohan Hedberg };
160170db83c4SJohan Hedberg 
160270db83c4SJohan Hedberg static inline struct l2cap_chan *smp_new_conn_cb(struct l2cap_chan *pchan)
160370db83c4SJohan Hedberg {
160470db83c4SJohan Hedberg 	struct l2cap_chan *chan;
160570db83c4SJohan Hedberg 
160670db83c4SJohan Hedberg 	BT_DBG("pchan %p", pchan);
160770db83c4SJohan Hedberg 
160870db83c4SJohan Hedberg 	chan = l2cap_chan_create();
160970db83c4SJohan Hedberg 	if (!chan)
161070db83c4SJohan Hedberg 		return NULL;
161170db83c4SJohan Hedberg 
161270db83c4SJohan Hedberg 	chan->chan_type	= pchan->chan_type;
161370db83c4SJohan Hedberg 	chan->ops	= &smp_chan_ops;
161470db83c4SJohan Hedberg 	chan->scid	= pchan->scid;
161570db83c4SJohan Hedberg 	chan->dcid	= chan->scid;
161670db83c4SJohan Hedberg 	chan->imtu	= pchan->imtu;
161770db83c4SJohan Hedberg 	chan->omtu	= pchan->omtu;
161870db83c4SJohan Hedberg 	chan->mode	= pchan->mode;
161970db83c4SJohan Hedberg 
162070db83c4SJohan Hedberg 	BT_DBG("created chan %p", chan);
162170db83c4SJohan Hedberg 
162270db83c4SJohan Hedberg 	return chan;
162370db83c4SJohan Hedberg }
162470db83c4SJohan Hedberg 
162570db83c4SJohan Hedberg static const struct l2cap_ops smp_root_chan_ops = {
162670db83c4SJohan Hedberg 	.name			= "Security Manager Root",
162770db83c4SJohan Hedberg 	.new_connection		= smp_new_conn_cb,
162870db83c4SJohan Hedberg 
162970db83c4SJohan Hedberg 	/* None of these are implemented for the root channel */
163070db83c4SJohan Hedberg 	.close			= l2cap_chan_no_close,
163170db83c4SJohan Hedberg 	.alloc_skb		= l2cap_chan_no_alloc_skb,
163270db83c4SJohan Hedberg 	.recv			= l2cap_chan_no_recv,
163370db83c4SJohan Hedberg 	.state_change		= l2cap_chan_no_state_change,
163470db83c4SJohan Hedberg 	.teardown		= l2cap_chan_no_teardown,
163570db83c4SJohan Hedberg 	.ready			= l2cap_chan_no_ready,
163670db83c4SJohan Hedberg 	.defer			= l2cap_chan_no_defer,
163770db83c4SJohan Hedberg 	.suspend		= l2cap_chan_no_suspend,
163870db83c4SJohan Hedberg 	.resume			= l2cap_chan_no_resume,
163970db83c4SJohan Hedberg 	.set_shutdown		= l2cap_chan_no_set_shutdown,
164070db83c4SJohan Hedberg 	.get_sndtimeo		= l2cap_chan_no_get_sndtimeo,
164170db83c4SJohan Hedberg 	.memcpy_fromiovec	= l2cap_chan_no_memcpy_fromiovec,
164270db83c4SJohan Hedberg };
164370db83c4SJohan Hedberg 
1644711eafe3SJohan Hedberg int smp_register(struct hci_dev *hdev)
1645711eafe3SJohan Hedberg {
164670db83c4SJohan Hedberg 	struct l2cap_chan *chan;
1647defce9e8SJohan Hedberg 	struct crypto_blkcipher	*tfm_aes;
164870db83c4SJohan Hedberg 
1649711eafe3SJohan Hedberg 	BT_DBG("%s", hdev->name);
1650711eafe3SJohan Hedberg 
1651defce9e8SJohan Hedberg 	tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
1652defce9e8SJohan Hedberg 	if (IS_ERR(tfm_aes)) {
1653defce9e8SJohan Hedberg 		int err = PTR_ERR(tfm_aes);
1654711eafe3SJohan Hedberg 		BT_ERR("Unable to create crypto context");
1655711eafe3SJohan Hedberg 		return err;
1656711eafe3SJohan Hedberg 	}
1657711eafe3SJohan Hedberg 
165870db83c4SJohan Hedberg 	chan = l2cap_chan_create();
165970db83c4SJohan Hedberg 	if (!chan) {
1660defce9e8SJohan Hedberg 		crypto_free_blkcipher(tfm_aes);
166170db83c4SJohan Hedberg 		return -ENOMEM;
166270db83c4SJohan Hedberg 	}
166370db83c4SJohan Hedberg 
1664defce9e8SJohan Hedberg 	chan->data = tfm_aes;
1665defce9e8SJohan Hedberg 
16665d88cc73SJohan Hedberg 	l2cap_add_scid(chan, L2CAP_CID_SMP);
166770db83c4SJohan Hedberg 
166870db83c4SJohan Hedberg 	l2cap_chan_set_defaults(chan);
166970db83c4SJohan Hedberg 
167070db83c4SJohan Hedberg 	bacpy(&chan->src, &hdev->bdaddr);
167170db83c4SJohan Hedberg 	chan->src_type = BDADDR_LE_PUBLIC;
167270db83c4SJohan Hedberg 	chan->state = BT_LISTEN;
167370db83c4SJohan Hedberg 	chan->mode = L2CAP_MODE_BASIC;
167470db83c4SJohan Hedberg 	chan->imtu = L2CAP_DEFAULT_MTU;
167570db83c4SJohan Hedberg 	chan->ops = &smp_root_chan_ops;
167670db83c4SJohan Hedberg 
167770db83c4SJohan Hedberg 	hdev->smp_data = chan;
167870db83c4SJohan Hedberg 
1679711eafe3SJohan Hedberg 	return 0;
1680711eafe3SJohan Hedberg }
1681711eafe3SJohan Hedberg 
1682711eafe3SJohan Hedberg void smp_unregister(struct hci_dev *hdev)
1683711eafe3SJohan Hedberg {
168470db83c4SJohan Hedberg 	struct l2cap_chan *chan = hdev->smp_data;
1685defce9e8SJohan Hedberg 	struct crypto_blkcipher *tfm_aes;
168670db83c4SJohan Hedberg 
168770db83c4SJohan Hedberg 	if (!chan)
168870db83c4SJohan Hedberg 		return;
168970db83c4SJohan Hedberg 
169070db83c4SJohan Hedberg 	BT_DBG("%s chan %p", hdev->name, chan);
1691711eafe3SJohan Hedberg 
1692defce9e8SJohan Hedberg 	tfm_aes = chan->data;
1693defce9e8SJohan Hedberg 	if (tfm_aes) {
1694defce9e8SJohan Hedberg 		chan->data = NULL;
1695defce9e8SJohan Hedberg 		crypto_free_blkcipher(tfm_aes);
1696711eafe3SJohan Hedberg 	}
169770db83c4SJohan Hedberg 
169870db83c4SJohan Hedberg 	hdev->smp_data = NULL;
169970db83c4SJohan Hedberg 	l2cap_chan_put(chan);
1700711eafe3SJohan Hedberg }
1701