xref: /openbmc/linux/net/bluetooth/smp.c (revision 4befb867)
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;
484bc58f51SJohan Hedberg 	u8		preq[7]; /* SMP Pairing Request */
494bc58f51SJohan Hedberg 	u8		prsp[7]; /* SMP Pairing Response */
504bc58f51SJohan Hedberg 	u8		prnd[16]; /* SMP Pairing Random (local) */
514bc58f51SJohan Hedberg 	u8		rrnd[16]; /* SMP Pairing Random (remote) */
524bc58f51SJohan Hedberg 	u8		pcnf[16]; /* SMP Pairing Confirm */
534bc58f51SJohan Hedberg 	u8		tk[16]; /* SMP Temporary Key */
544bc58f51SJohan Hedberg 	u8		enc_key_size;
554bc58f51SJohan Hedberg 	u8		remote_key_dist;
564bc58f51SJohan Hedberg 	bdaddr_t	id_addr;
574bc58f51SJohan Hedberg 	u8		id_addr_type;
584bc58f51SJohan Hedberg 	u8		irk[16];
594bc58f51SJohan Hedberg 	struct smp_csrk	*csrk;
604bc58f51SJohan Hedberg 	struct smp_csrk	*slave_csrk;
614bc58f51SJohan Hedberg 	struct smp_ltk	*ltk;
624bc58f51SJohan Hedberg 	struct smp_ltk	*slave_ltk;
634bc58f51SJohan Hedberg 	struct smp_irk	*remote_irk;
644a74d658SJohan Hedberg 	unsigned long	flags;
656a7bd103SJohan Hedberg 
666a7bd103SJohan Hedberg 	struct crypto_blkcipher	*tfm_aes;
674bc58f51SJohan Hedberg };
684bc58f51SJohan Hedberg 
698a2936f4SJohan Hedberg static inline void swap_buf(const u8 *src, u8 *dst, size_t len)
70d22ef0bcSAnderson Briglia {
718a2936f4SJohan Hedberg 	size_t i;
72d22ef0bcSAnderson Briglia 
738a2936f4SJohan Hedberg 	for (i = 0; i < len; i++)
748a2936f4SJohan Hedberg 		dst[len - 1 - i] = src[i];
75d22ef0bcSAnderson Briglia }
76d22ef0bcSAnderson Briglia 
77d22ef0bcSAnderson Briglia static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
78d22ef0bcSAnderson Briglia {
79d22ef0bcSAnderson Briglia 	struct blkcipher_desc desc;
80d22ef0bcSAnderson Briglia 	struct scatterlist sg;
81943a732aSJohan Hedberg 	uint8_t tmp[16], data[16];
82201a5929SJohan Hedberg 	int err;
83d22ef0bcSAnderson Briglia 
84d22ef0bcSAnderson Briglia 	if (tfm == NULL) {
85d22ef0bcSAnderson Briglia 		BT_ERR("tfm %p", tfm);
86d22ef0bcSAnderson Briglia 		return -EINVAL;
87d22ef0bcSAnderson Briglia 	}
88d22ef0bcSAnderson Briglia 
89d22ef0bcSAnderson Briglia 	desc.tfm = tfm;
90d22ef0bcSAnderson Briglia 	desc.flags = 0;
91d22ef0bcSAnderson Briglia 
92943a732aSJohan Hedberg 	/* The most significant octet of key corresponds to k[0] */
938a2936f4SJohan Hedberg 	swap_buf(k, tmp, 16);
94943a732aSJohan Hedberg 
95943a732aSJohan Hedberg 	err = crypto_blkcipher_setkey(tfm, tmp, 16);
96d22ef0bcSAnderson Briglia 	if (err) {
97d22ef0bcSAnderson Briglia 		BT_ERR("cipher setkey failed: %d", err);
98d22ef0bcSAnderson Briglia 		return err;
99d22ef0bcSAnderson Briglia 	}
100d22ef0bcSAnderson Briglia 
101943a732aSJohan Hedberg 	/* Most significant octet of plaintextData corresponds to data[0] */
1028a2936f4SJohan Hedberg 	swap_buf(r, data, 16);
103943a732aSJohan Hedberg 
104943a732aSJohan Hedberg 	sg_init_one(&sg, data, 16);
105d22ef0bcSAnderson Briglia 
106d22ef0bcSAnderson Briglia 	err = crypto_blkcipher_encrypt(&desc, &sg, &sg, 16);
107d22ef0bcSAnderson Briglia 	if (err)
108d22ef0bcSAnderson Briglia 		BT_ERR("Encrypt data error %d", err);
109d22ef0bcSAnderson Briglia 
110943a732aSJohan Hedberg 	/* Most significant octet of encryptedData corresponds to data[0] */
1118a2936f4SJohan Hedberg 	swap_buf(data, r, 16);
112943a732aSJohan Hedberg 
113d22ef0bcSAnderson Briglia 	return err;
114d22ef0bcSAnderson Briglia }
115d22ef0bcSAnderson Briglia 
11660478054SJohan Hedberg static int smp_ah(struct crypto_blkcipher *tfm, u8 irk[16], u8 r[3], u8 res[3])
11760478054SJohan Hedberg {
118943a732aSJohan Hedberg 	u8 _res[16];
11960478054SJohan Hedberg 	int err;
12060478054SJohan Hedberg 
12160478054SJohan Hedberg 	/* r' = padding || r */
122943a732aSJohan Hedberg 	memcpy(_res, r, 3);
123943a732aSJohan Hedberg 	memset(_res + 3, 0, 13);
12460478054SJohan Hedberg 
125943a732aSJohan Hedberg 	err = smp_e(tfm, irk, _res);
12660478054SJohan Hedberg 	if (err) {
12760478054SJohan Hedberg 		BT_ERR("Encrypt error");
12860478054SJohan Hedberg 		return err;
12960478054SJohan Hedberg 	}
13060478054SJohan Hedberg 
13160478054SJohan Hedberg 	/* The output of the random address function ah is:
13260478054SJohan Hedberg 	 *	ah(h, r) = e(k, r') mod 2^24
13360478054SJohan Hedberg 	 * The output of the security function e is then truncated to 24 bits
13460478054SJohan Hedberg 	 * by taking the least significant 24 bits of the output of e as the
13560478054SJohan Hedberg 	 * result of ah.
13660478054SJohan Hedberg 	 */
137943a732aSJohan Hedberg 	memcpy(res, _res, 3);
13860478054SJohan Hedberg 
13960478054SJohan Hedberg 	return 0;
14060478054SJohan Hedberg }
14160478054SJohan Hedberg 
142defce9e8SJohan Hedberg bool smp_irk_matches(struct hci_dev *hdev, u8 irk[16], bdaddr_t *bdaddr)
14360478054SJohan Hedberg {
144defce9e8SJohan Hedberg 	struct l2cap_chan *chan = hdev->smp_data;
145defce9e8SJohan Hedberg 	struct crypto_blkcipher *tfm;
14660478054SJohan Hedberg 	u8 hash[3];
14760478054SJohan Hedberg 	int err;
14860478054SJohan Hedberg 
149defce9e8SJohan Hedberg 	if (!chan || !chan->data)
150defce9e8SJohan Hedberg 		return false;
151defce9e8SJohan Hedberg 
152defce9e8SJohan Hedberg 	tfm = chan->data;
153defce9e8SJohan Hedberg 
15460478054SJohan Hedberg 	BT_DBG("RPA %pMR IRK %*phN", bdaddr, 16, irk);
15560478054SJohan Hedberg 
15660478054SJohan Hedberg 	err = smp_ah(tfm, irk, &bdaddr->b[3], hash);
15760478054SJohan Hedberg 	if (err)
15860478054SJohan Hedberg 		return false;
15960478054SJohan Hedberg 
16060478054SJohan Hedberg 	return !memcmp(bdaddr->b, hash, 3);
16160478054SJohan Hedberg }
16260478054SJohan Hedberg 
163defce9e8SJohan Hedberg int smp_generate_rpa(struct hci_dev *hdev, u8 irk[16], bdaddr_t *rpa)
164b1e2b3aeSJohan Hedberg {
165defce9e8SJohan Hedberg 	struct l2cap_chan *chan = hdev->smp_data;
166defce9e8SJohan Hedberg 	struct crypto_blkcipher *tfm;
167b1e2b3aeSJohan Hedberg 	int err;
168b1e2b3aeSJohan Hedberg 
169defce9e8SJohan Hedberg 	if (!chan || !chan->data)
170defce9e8SJohan Hedberg 		return -EOPNOTSUPP;
171defce9e8SJohan Hedberg 
172defce9e8SJohan Hedberg 	tfm = chan->data;
173defce9e8SJohan Hedberg 
174b1e2b3aeSJohan Hedberg 	get_random_bytes(&rpa->b[3], 3);
175b1e2b3aeSJohan Hedberg 
176b1e2b3aeSJohan Hedberg 	rpa->b[5] &= 0x3f;	/* Clear two most significant bits */
177b1e2b3aeSJohan Hedberg 	rpa->b[5] |= 0x40;	/* Set second most significant bit */
178b1e2b3aeSJohan Hedberg 
179b1e2b3aeSJohan Hedberg 	err = smp_ah(tfm, irk, &rpa->b[3], rpa->b);
180b1e2b3aeSJohan Hedberg 	if (err < 0)
181b1e2b3aeSJohan Hedberg 		return err;
182b1e2b3aeSJohan Hedberg 
183b1e2b3aeSJohan Hedberg 	BT_DBG("RPA %pMR", rpa);
184b1e2b3aeSJohan Hedberg 
185b1e2b3aeSJohan Hedberg 	return 0;
186b1e2b3aeSJohan Hedberg }
187b1e2b3aeSJohan Hedberg 
188ec70f36fSJohan Hedberg static int smp_c1(struct smp_chan *smp, u8 k[16], u8 r[16], u8 preq[7],
189ec70f36fSJohan Hedberg 		  u8 pres[7], u8 _iat, bdaddr_t *ia, u8 _rat, bdaddr_t *ra,
190ec70f36fSJohan Hedberg 		  u8 res[16])
191d22ef0bcSAnderson Briglia {
192ec70f36fSJohan Hedberg 	struct hci_dev *hdev = smp->conn->hcon->hdev;
193d22ef0bcSAnderson Briglia 	u8 p1[16], p2[16];
194d22ef0bcSAnderson Briglia 	int err;
195d22ef0bcSAnderson Briglia 
196ec70f36fSJohan Hedberg 	BT_DBG("%s", hdev->name);
197ec70f36fSJohan Hedberg 
198d22ef0bcSAnderson Briglia 	memset(p1, 0, 16);
199d22ef0bcSAnderson Briglia 
200d22ef0bcSAnderson Briglia 	/* p1 = pres || preq || _rat || _iat */
201943a732aSJohan Hedberg 	p1[0] = _iat;
202943a732aSJohan Hedberg 	p1[1] = _rat;
203943a732aSJohan Hedberg 	memcpy(p1 + 2, preq, 7);
204943a732aSJohan Hedberg 	memcpy(p1 + 9, pres, 7);
205d22ef0bcSAnderson Briglia 
206d22ef0bcSAnderson Briglia 	/* p2 = padding || ia || ra */
207943a732aSJohan Hedberg 	memcpy(p2, ra, 6);
208943a732aSJohan Hedberg 	memcpy(p2 + 6, ia, 6);
209943a732aSJohan Hedberg 	memset(p2 + 12, 0, 4);
210d22ef0bcSAnderson Briglia 
211d22ef0bcSAnderson Briglia 	/* res = r XOR p1 */
212d22ef0bcSAnderson Briglia 	u128_xor((u128 *) res, (u128 *) r, (u128 *) p1);
213d22ef0bcSAnderson Briglia 
214d22ef0bcSAnderson Briglia 	/* res = e(k, res) */
215ec70f36fSJohan Hedberg 	err = smp_e(smp->tfm_aes, k, res);
216d22ef0bcSAnderson Briglia 	if (err) {
217d22ef0bcSAnderson Briglia 		BT_ERR("Encrypt data error");
218d22ef0bcSAnderson Briglia 		return err;
219d22ef0bcSAnderson Briglia 	}
220d22ef0bcSAnderson Briglia 
221d22ef0bcSAnderson Briglia 	/* res = res XOR p2 */
222d22ef0bcSAnderson Briglia 	u128_xor((u128 *) res, (u128 *) res, (u128 *) p2);
223d22ef0bcSAnderson Briglia 
224d22ef0bcSAnderson Briglia 	/* res = e(k, res) */
225ec70f36fSJohan Hedberg 	err = smp_e(smp->tfm_aes, k, res);
226d22ef0bcSAnderson Briglia 	if (err)
227d22ef0bcSAnderson Briglia 		BT_ERR("Encrypt data error");
228d22ef0bcSAnderson Briglia 
229d22ef0bcSAnderson Briglia 	return err;
230d22ef0bcSAnderson Briglia }
231d22ef0bcSAnderson Briglia 
232ec70f36fSJohan Hedberg static int smp_s1(struct smp_chan *smp, u8 k[16], u8 r1[16], u8 r2[16],
233ec70f36fSJohan Hedberg 		  u8 _r[16])
234d22ef0bcSAnderson Briglia {
235ec70f36fSJohan Hedberg 	struct hci_dev *hdev = smp->conn->hcon->hdev;
236d22ef0bcSAnderson Briglia 	int err;
237d22ef0bcSAnderson Briglia 
238ec70f36fSJohan Hedberg 	BT_DBG("%s", hdev->name);
239ec70f36fSJohan Hedberg 
240d22ef0bcSAnderson Briglia 	/* Just least significant octets from r1 and r2 are considered */
241943a732aSJohan Hedberg 	memcpy(_r, r2, 8);
242943a732aSJohan Hedberg 	memcpy(_r + 8, r1, 8);
243d22ef0bcSAnderson Briglia 
244ec70f36fSJohan Hedberg 	err = smp_e(smp->tfm_aes, k, _r);
245d22ef0bcSAnderson Briglia 	if (err)
246d22ef0bcSAnderson Briglia 		BT_ERR("Encrypt data error");
247d22ef0bcSAnderson Briglia 
248d22ef0bcSAnderson Briglia 	return err;
249d22ef0bcSAnderson Briglia }
250d22ef0bcSAnderson Briglia 
251eb492e01SAnderson Briglia static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
252eb492e01SAnderson Briglia {
2535d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
2545d88cc73SJohan Hedberg 	struct kvec iv[2];
2555d88cc73SJohan Hedberg 	struct msghdr msg;
2565d88cc73SJohan Hedberg 
2575d88cc73SJohan Hedberg 	if (!chan)
2585d88cc73SJohan Hedberg 		return;
259eb492e01SAnderson Briglia 
260eb492e01SAnderson Briglia 	BT_DBG("code 0x%2.2x", code);
261eb492e01SAnderson Briglia 
2625d88cc73SJohan Hedberg 	iv[0].iov_base = &code;
2635d88cc73SJohan Hedberg 	iv[0].iov_len = 1;
264eb492e01SAnderson Briglia 
2655d88cc73SJohan Hedberg 	iv[1].iov_base = data;
2665d88cc73SJohan Hedberg 	iv[1].iov_len = len;
2675d88cc73SJohan Hedberg 
2685d88cc73SJohan Hedberg 	memset(&msg, 0, sizeof(msg));
2695d88cc73SJohan Hedberg 
2705d88cc73SJohan Hedberg 	msg.msg_iov = (struct iovec *) &iv;
2715d88cc73SJohan Hedberg 	msg.msg_iovlen = 2;
2725d88cc73SJohan Hedberg 
2735d88cc73SJohan Hedberg 	l2cap_chan_send(chan, &msg, 1 + len);
274e2dcd113SVinicius Costa Gomes 
2756c9d42a1SGustavo F. Padovan 	cancel_delayed_work_sync(&conn->security_timer);
27617b02e62SMarcel Holtmann 	schedule_delayed_work(&conn->security_timer, SMP_TIMEOUT);
277eb492e01SAnderson Briglia }
278eb492e01SAnderson Briglia 
2792b64d153SBrian Gix static __u8 authreq_to_seclevel(__u8 authreq)
2802b64d153SBrian Gix {
2812b64d153SBrian Gix 	if (authreq & SMP_AUTH_MITM)
2822b64d153SBrian Gix 		return BT_SECURITY_HIGH;
2832b64d153SBrian Gix 	else
2842b64d153SBrian Gix 		return BT_SECURITY_MEDIUM;
2852b64d153SBrian Gix }
2862b64d153SBrian Gix 
2872b64d153SBrian Gix static __u8 seclevel_to_authreq(__u8 sec_level)
2882b64d153SBrian Gix {
2892b64d153SBrian Gix 	switch (sec_level) {
2902b64d153SBrian Gix 	case BT_SECURITY_HIGH:
2912b64d153SBrian Gix 		return SMP_AUTH_MITM | SMP_AUTH_BONDING;
2922b64d153SBrian Gix 	case BT_SECURITY_MEDIUM:
2932b64d153SBrian Gix 		return SMP_AUTH_BONDING;
2942b64d153SBrian Gix 	default:
2952b64d153SBrian Gix 		return SMP_AUTH_NONE;
2962b64d153SBrian Gix 	}
2972b64d153SBrian Gix }
2982b64d153SBrian Gix 
299b8e66eacSVinicius Costa Gomes static void build_pairing_cmd(struct l2cap_conn *conn,
30054790f73SVinicius Costa Gomes 			      struct smp_cmd_pairing *req,
301f1560463SMarcel Holtmann 			      struct smp_cmd_pairing *rsp, __u8 authreq)
302b8e66eacSVinicius Costa Gomes {
3035d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
3045d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
305fd349c02SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
306fd349c02SJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
307fd349c02SJohan Hedberg 	u8 local_dist = 0, remote_dist = 0;
30854790f73SVinicius Costa Gomes 
309b6ae8457SJohan Hedberg 	if (test_bit(HCI_BONDABLE, &conn->hcon->hdev->dev_flags)) {
3107ee4ea36SMarcel Holtmann 		local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
3117ee4ea36SMarcel Holtmann 		remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
31254790f73SVinicius Costa Gomes 		authreq |= SMP_AUTH_BONDING;
3132b64d153SBrian Gix 	} else {
3142b64d153SBrian Gix 		authreq &= ~SMP_AUTH_BONDING;
31554790f73SVinicius Costa Gomes 	}
31654790f73SVinicius Costa Gomes 
317fd349c02SJohan Hedberg 	if (test_bit(HCI_RPA_RESOLVING, &hdev->dev_flags))
318fd349c02SJohan Hedberg 		remote_dist |= SMP_DIST_ID_KEY;
319fd349c02SJohan Hedberg 
320863efaf2SJohan Hedberg 	if (test_bit(HCI_PRIVACY, &hdev->dev_flags))
321863efaf2SJohan Hedberg 		local_dist |= SMP_DIST_ID_KEY;
322863efaf2SJohan Hedberg 
32354790f73SVinicius Costa Gomes 	if (rsp == NULL) {
32454790f73SVinicius Costa Gomes 		req->io_capability = conn->hcon->io_capability;
32554790f73SVinicius Costa Gomes 		req->oob_flag = SMP_OOB_NOT_PRESENT;
32654790f73SVinicius Costa Gomes 		req->max_key_size = SMP_MAX_ENC_KEY_SIZE;
327fd349c02SJohan Hedberg 		req->init_key_dist = local_dist;
328fd349c02SJohan Hedberg 		req->resp_key_dist = remote_dist;
329065a13e2SJohan Hedberg 		req->auth_req = (authreq & AUTH_REQ_MASK);
330fd349c02SJohan Hedberg 
331fd349c02SJohan Hedberg 		smp->remote_key_dist = remote_dist;
33254790f73SVinicius Costa Gomes 		return;
33354790f73SVinicius Costa Gomes 	}
33454790f73SVinicius Costa Gomes 
33554790f73SVinicius Costa Gomes 	rsp->io_capability = conn->hcon->io_capability;
33654790f73SVinicius Costa Gomes 	rsp->oob_flag = SMP_OOB_NOT_PRESENT;
33754790f73SVinicius Costa Gomes 	rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE;
338fd349c02SJohan Hedberg 	rsp->init_key_dist = req->init_key_dist & remote_dist;
339fd349c02SJohan Hedberg 	rsp->resp_key_dist = req->resp_key_dist & local_dist;
340065a13e2SJohan Hedberg 	rsp->auth_req = (authreq & AUTH_REQ_MASK);
341fd349c02SJohan Hedberg 
342fd349c02SJohan Hedberg 	smp->remote_key_dist = rsp->init_key_dist;
343b8e66eacSVinicius Costa Gomes }
344b8e66eacSVinicius Costa Gomes 
3453158c50cSVinicius Costa Gomes static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
3463158c50cSVinicius Costa Gomes {
3475d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
3485d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
3491c1def09SVinicius Costa Gomes 
3503158c50cSVinicius Costa Gomes 	if ((max_key_size > SMP_MAX_ENC_KEY_SIZE) ||
3513158c50cSVinicius Costa Gomes 	    (max_key_size < SMP_MIN_ENC_KEY_SIZE))
3523158c50cSVinicius Costa Gomes 		return SMP_ENC_KEY_SIZE;
3533158c50cSVinicius Costa Gomes 
354f7aa611aSVinicius Costa Gomes 	smp->enc_key_size = max_key_size;
3553158c50cSVinicius Costa Gomes 
3563158c50cSVinicius Costa Gomes 	return 0;
3573158c50cSVinicius Costa Gomes }
3583158c50cSVinicius Costa Gomes 
35984794e11SJohan Hedberg static void smp_failure(struct l2cap_conn *conn, u8 reason)
3604f957a76SBrian Gix {
361bab73cb6SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
362bab73cb6SJohan Hedberg 
36384794e11SJohan Hedberg 	if (reason)
3644f957a76SBrian Gix 		smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
3654f957a76SBrian Gix 			     &reason);
3664f957a76SBrian Gix 
367ce39fb4eSMarcel Holtmann 	clear_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags);
368ce39fb4eSMarcel Holtmann 	mgmt_auth_failed(hcon->hdev, &hcon->dst, hcon->type, hcon->dst_type,
369ce39fb4eSMarcel Holtmann 			 HCI_ERROR_AUTH_FAILURE);
370f1c09c07SVinicius Costa Gomes 
3716c9d42a1SGustavo F. Padovan 	cancel_delayed_work_sync(&conn->security_timer);
37261a0cfb0SAndre Guedes 
373ce39fb4eSMarcel Holtmann 	if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
3744f957a76SBrian Gix 		smp_chan_destroy(conn);
3754f957a76SBrian Gix }
3764f957a76SBrian Gix 
3772b64d153SBrian Gix #define JUST_WORKS	0x00
3782b64d153SBrian Gix #define JUST_CFM	0x01
3792b64d153SBrian Gix #define REQ_PASSKEY	0x02
3802b64d153SBrian Gix #define CFM_PASSKEY	0x03
3812b64d153SBrian Gix #define REQ_OOB		0x04
3822b64d153SBrian Gix #define OVERLAP		0xFF
3832b64d153SBrian Gix 
3842b64d153SBrian Gix static const u8 gen_method[5][5] = {
3852b64d153SBrian Gix 	{ JUST_WORKS,  JUST_CFM,    REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
3862b64d153SBrian Gix 	{ JUST_WORKS,  JUST_CFM,    REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
3872b64d153SBrian Gix 	{ CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
3882b64d153SBrian Gix 	{ JUST_WORKS,  JUST_CFM,    JUST_WORKS,  JUST_WORKS, JUST_CFM    },
3892b64d153SBrian Gix 	{ CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, OVERLAP     },
3902b64d153SBrian Gix };
3912b64d153SBrian Gix 
392581370ccSJohan Hedberg static u8 get_auth_method(struct smp_chan *smp, u8 local_io, u8 remote_io)
393581370ccSJohan Hedberg {
3942bcd4003SJohan Hedberg 	/* If either side has unknown io_caps, use JUST_CFM (which gets
3952bcd4003SJohan Hedberg 	 * converted later to JUST_WORKS if we're initiators.
3962bcd4003SJohan Hedberg 	 */
397581370ccSJohan Hedberg 	if (local_io > SMP_IO_KEYBOARD_DISPLAY ||
398581370ccSJohan Hedberg 	    remote_io > SMP_IO_KEYBOARD_DISPLAY)
3992bcd4003SJohan Hedberg 		return JUST_CFM;
400581370ccSJohan Hedberg 
401581370ccSJohan Hedberg 	return gen_method[remote_io][local_io];
402581370ccSJohan Hedberg }
403581370ccSJohan Hedberg 
4042b64d153SBrian Gix static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
4052b64d153SBrian Gix 						u8 local_io, u8 remote_io)
4062b64d153SBrian Gix {
4072b64d153SBrian Gix 	struct hci_conn *hcon = conn->hcon;
4085d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
4095d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
4102b64d153SBrian Gix 	u8 method;
4112b64d153SBrian Gix 	u32 passkey = 0;
4122b64d153SBrian Gix 	int ret = 0;
4132b64d153SBrian Gix 
4142b64d153SBrian Gix 	/* Initialize key for JUST WORKS */
4152b64d153SBrian Gix 	memset(smp->tk, 0, sizeof(smp->tk));
4164a74d658SJohan Hedberg 	clear_bit(SMP_FLAG_TK_VALID, &smp->flags);
4172b64d153SBrian Gix 
4182b64d153SBrian Gix 	BT_DBG("tk_request: auth:%d lcl:%d rem:%d", auth, local_io, remote_io);
4192b64d153SBrian Gix 
4202bcd4003SJohan Hedberg 	/* If neither side wants MITM, either "just" confirm an incoming
4212bcd4003SJohan Hedberg 	 * request or use just-works for outgoing ones. The JUST_CFM
4222bcd4003SJohan Hedberg 	 * will be converted to JUST_WORKS if necessary later in this
4232bcd4003SJohan Hedberg 	 * function. If either side has MITM look up the method from the
4242bcd4003SJohan Hedberg 	 * table.
4252bcd4003SJohan Hedberg 	 */
426581370ccSJohan Hedberg 	if (!(auth & SMP_AUTH_MITM))
4272bcd4003SJohan Hedberg 		method = JUST_CFM;
4282b64d153SBrian Gix 	else
429581370ccSJohan Hedberg 		method = get_auth_method(smp, local_io, remote_io);
4302b64d153SBrian Gix 
431a82505c7SJohan Hedberg 	/* Don't confirm locally initiated pairing attempts */
4324a74d658SJohan Hedberg 	if (method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR, &smp->flags))
433a82505c7SJohan Hedberg 		method = JUST_WORKS;
434a82505c7SJohan Hedberg 
43502f3e254SJohan Hedberg 	/* Don't bother user space with no IO capabilities */
43602f3e254SJohan Hedberg 	if (method == JUST_CFM && hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
43702f3e254SJohan Hedberg 		method = JUST_WORKS;
43802f3e254SJohan Hedberg 
4392b64d153SBrian Gix 	/* If Just Works, Continue with Zero TK */
4402b64d153SBrian Gix 	if (method == JUST_WORKS) {
4414a74d658SJohan Hedberg 		set_bit(SMP_FLAG_TK_VALID, &smp->flags);
4422b64d153SBrian Gix 		return 0;
4432b64d153SBrian Gix 	}
4442b64d153SBrian Gix 
4452b64d153SBrian Gix 	/* Not Just Works/Confirm results in MITM Authentication */
4462b64d153SBrian Gix 	if (method != JUST_CFM)
4474a74d658SJohan Hedberg 		set_bit(SMP_FLAG_MITM_AUTH, &smp->flags);
4482b64d153SBrian Gix 
4492b64d153SBrian Gix 	/* If both devices have Keyoard-Display I/O, the master
4502b64d153SBrian Gix 	 * Confirms and the slave Enters the passkey.
4512b64d153SBrian Gix 	 */
4522b64d153SBrian Gix 	if (method == OVERLAP) {
45340bef302SJohan Hedberg 		if (hcon->role == HCI_ROLE_MASTER)
4542b64d153SBrian Gix 			method = CFM_PASSKEY;
4552b64d153SBrian Gix 		else
4562b64d153SBrian Gix 			method = REQ_PASSKEY;
4572b64d153SBrian Gix 	}
4582b64d153SBrian Gix 
45901ad34d2SJohan Hedberg 	/* Generate random passkey. */
4602b64d153SBrian Gix 	if (method == CFM_PASSKEY) {
461943a732aSJohan Hedberg 		memset(smp->tk, 0, sizeof(smp->tk));
4622b64d153SBrian Gix 		get_random_bytes(&passkey, sizeof(passkey));
4632b64d153SBrian Gix 		passkey %= 1000000;
464943a732aSJohan Hedberg 		put_unaligned_le32(passkey, smp->tk);
4652b64d153SBrian Gix 		BT_DBG("PassKey: %d", passkey);
4664a74d658SJohan Hedberg 		set_bit(SMP_FLAG_TK_VALID, &smp->flags);
4672b64d153SBrian Gix 	}
4682b64d153SBrian Gix 
4692b64d153SBrian Gix 	hci_dev_lock(hcon->hdev);
4702b64d153SBrian Gix 
4712b64d153SBrian Gix 	if (method == REQ_PASSKEY)
472ce39fb4eSMarcel Holtmann 		ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst,
473272d90dfSJohan Hedberg 						hcon->type, hcon->dst_type);
4744eb65e66SJohan Hedberg 	else if (method == JUST_CFM)
4754eb65e66SJohan Hedberg 		ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
4764eb65e66SJohan Hedberg 						hcon->type, hcon->dst_type,
4774eb65e66SJohan Hedberg 						passkey, 1);
4782b64d153SBrian Gix 	else
47901ad34d2SJohan Hedberg 		ret = mgmt_user_passkey_notify(hcon->hdev, &hcon->dst,
480272d90dfSJohan Hedberg 						hcon->type, hcon->dst_type,
48139adbffeSJohan Hedberg 						passkey, 0);
4822b64d153SBrian Gix 
4832b64d153SBrian Gix 	hci_dev_unlock(hcon->hdev);
4842b64d153SBrian Gix 
4852b64d153SBrian Gix 	return ret;
4862b64d153SBrian Gix }
4872b64d153SBrian Gix 
4881cc61144SJohan Hedberg static u8 smp_confirm(struct smp_chan *smp)
4898aab4757SVinicius Costa Gomes {
4908aab4757SVinicius Costa Gomes 	struct l2cap_conn *conn = smp->conn;
4918aab4757SVinicius Costa Gomes 	struct smp_cmd_pairing_confirm cp;
4928aab4757SVinicius Costa Gomes 	int ret;
4938aab4757SVinicius Costa Gomes 
4948aab4757SVinicius Costa Gomes 	BT_DBG("conn %p", conn);
4958aab4757SVinicius Costa Gomes 
496ec70f36fSJohan Hedberg 	ret = smp_c1(smp, smp->tk, smp->prnd, smp->preq, smp->prsp,
497b1cd5fd9SJohan Hedberg 		     conn->hcon->init_addr_type, &conn->hcon->init_addr,
498943a732aSJohan Hedberg 		     conn->hcon->resp_addr_type, &conn->hcon->resp_addr,
499943a732aSJohan Hedberg 		     cp.confirm_val);
5001cc61144SJohan Hedberg 	if (ret)
5011cc61144SJohan Hedberg 		return SMP_UNSPECIFIED;
5028aab4757SVinicius Costa Gomes 
5034a74d658SJohan Hedberg 	clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
5042b64d153SBrian Gix 
5058aab4757SVinicius Costa Gomes 	smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
5068aab4757SVinicius Costa Gomes 
5071cc61144SJohan Hedberg 	return 0;
5088aab4757SVinicius Costa Gomes }
5098aab4757SVinicius Costa Gomes 
510861580a9SJohan Hedberg static u8 smp_random(struct smp_chan *smp)
5118aab4757SVinicius Costa Gomes {
5128aab4757SVinicius Costa Gomes 	struct l2cap_conn *conn = smp->conn;
5138aab4757SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
514861580a9SJohan Hedberg 	u8 confirm[16];
5158aab4757SVinicius Costa Gomes 	int ret;
5168aab4757SVinicius Costa Gomes 
517ec70f36fSJohan Hedberg 	if (IS_ERR_OR_NULL(smp->tfm_aes))
518861580a9SJohan Hedberg 		return SMP_UNSPECIFIED;
5198aab4757SVinicius Costa Gomes 
5208aab4757SVinicius Costa Gomes 	BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
5218aab4757SVinicius Costa Gomes 
522ec70f36fSJohan Hedberg 	ret = smp_c1(smp, smp->tk, smp->rrnd, smp->preq, smp->prsp,
523b1cd5fd9SJohan Hedberg 		     hcon->init_addr_type, &hcon->init_addr,
524943a732aSJohan Hedberg 		     hcon->resp_addr_type, &hcon->resp_addr, confirm);
525861580a9SJohan Hedberg 	if (ret)
526861580a9SJohan Hedberg 		return SMP_UNSPECIFIED;
5278aab4757SVinicius Costa Gomes 
5288aab4757SVinicius Costa Gomes 	if (memcmp(smp->pcnf, confirm, sizeof(smp->pcnf)) != 0) {
5298aab4757SVinicius Costa Gomes 		BT_ERR("Pairing failed (confirmation values mismatch)");
530861580a9SJohan Hedberg 		return SMP_CONFIRM_FAILED;
5318aab4757SVinicius Costa Gomes 	}
5328aab4757SVinicius Costa Gomes 
5338aab4757SVinicius Costa Gomes 	if (hcon->out) {
534fe39c7b2SMarcel Holtmann 		u8 stk[16];
535fe39c7b2SMarcel Holtmann 		__le64 rand = 0;
536fe39c7b2SMarcel Holtmann 		__le16 ediv = 0;
5378aab4757SVinicius Costa Gomes 
538ec70f36fSJohan Hedberg 		smp_s1(smp, smp->tk, smp->rrnd, smp->prnd, stk);
5398aab4757SVinicius Costa Gomes 
540f7aa611aSVinicius Costa Gomes 		memset(stk + smp->enc_key_size, 0,
541f7aa611aSVinicius Costa Gomes 		       SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
5428aab4757SVinicius Costa Gomes 
543861580a9SJohan Hedberg 		if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
544861580a9SJohan Hedberg 			return SMP_UNSPECIFIED;
5458aab4757SVinicius Costa Gomes 
5468aab4757SVinicius Costa Gomes 		hci_le_start_enc(hcon, ediv, rand, stk);
547f7aa611aSVinicius Costa Gomes 		hcon->enc_key_size = smp->enc_key_size;
548fe59a05fSJohan Hedberg 		set_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags);
5498aab4757SVinicius Costa Gomes 	} else {
550fff3490fSJohan Hedberg 		u8 stk[16], auth;
551fe39c7b2SMarcel Holtmann 		__le64 rand = 0;
552fe39c7b2SMarcel Holtmann 		__le16 ediv = 0;
5538aab4757SVinicius Costa Gomes 
554943a732aSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
555943a732aSJohan Hedberg 			     smp->prnd);
5568aab4757SVinicius Costa Gomes 
557ec70f36fSJohan Hedberg 		smp_s1(smp, smp->tk, smp->prnd, smp->rrnd, stk);
5588aab4757SVinicius Costa Gomes 
559f7aa611aSVinicius Costa Gomes 		memset(stk + smp->enc_key_size, 0,
560f7aa611aSVinicius Costa Gomes 		       SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
5618aab4757SVinicius Costa Gomes 
562fff3490fSJohan Hedberg 		if (hcon->pending_sec_level == BT_SECURITY_HIGH)
563fff3490fSJohan Hedberg 			auth = 1;
564fff3490fSJohan Hedberg 		else
565fff3490fSJohan Hedberg 			auth = 0;
566fff3490fSJohan Hedberg 
5677d5843b7SJohan Hedberg 		/* Even though there's no _SLAVE suffix this is the
5687d5843b7SJohan Hedberg 		 * slave STK we're adding for later lookup (the master
5697d5843b7SJohan Hedberg 		 * STK never needs to be stored).
5707d5843b7SJohan Hedberg 		 */
571ce39fb4eSMarcel Holtmann 		hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
5722ceba539SJohan Hedberg 			    SMP_STK, auth, stk, smp->enc_key_size, ediv, rand);
5738aab4757SVinicius Costa Gomes 	}
5748aab4757SVinicius Costa Gomes 
575861580a9SJohan Hedberg 	return 0;
5768aab4757SVinicius Costa Gomes }
5778aab4757SVinicius Costa Gomes 
57844f1a7abSJohan Hedberg static void smp_notify_keys(struct l2cap_conn *conn)
57944f1a7abSJohan Hedberg {
58044f1a7abSJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
58144f1a7abSJohan Hedberg 	struct smp_chan *smp = chan->data;
58244f1a7abSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
58344f1a7abSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
58444f1a7abSJohan Hedberg 	struct smp_cmd_pairing *req = (void *) &smp->preq[1];
58544f1a7abSJohan Hedberg 	struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1];
58644f1a7abSJohan Hedberg 	bool persistent;
58744f1a7abSJohan Hedberg 
58844f1a7abSJohan Hedberg 	if (smp->remote_irk) {
58944f1a7abSJohan Hedberg 		mgmt_new_irk(hdev, smp->remote_irk);
59044f1a7abSJohan Hedberg 		/* Now that user space can be considered to know the
59144f1a7abSJohan Hedberg 		 * identity address track the connection based on it
59244f1a7abSJohan Hedberg 		 * from now on.
59344f1a7abSJohan Hedberg 		 */
59444f1a7abSJohan Hedberg 		bacpy(&hcon->dst, &smp->remote_irk->bdaddr);
59544f1a7abSJohan Hedberg 		hcon->dst_type = smp->remote_irk->addr_type;
59644f1a7abSJohan Hedberg 		l2cap_conn_update_id_addr(hcon);
59744f1a7abSJohan Hedberg 
59844f1a7abSJohan Hedberg 		/* When receiving an indentity resolving key for
59944f1a7abSJohan Hedberg 		 * a remote device that does not use a resolvable
60044f1a7abSJohan Hedberg 		 * private address, just remove the key so that
60144f1a7abSJohan Hedberg 		 * it is possible to use the controller white
60244f1a7abSJohan Hedberg 		 * list for scanning.
60344f1a7abSJohan Hedberg 		 *
60444f1a7abSJohan Hedberg 		 * Userspace will have been told to not store
60544f1a7abSJohan Hedberg 		 * this key at this point. So it is safe to
60644f1a7abSJohan Hedberg 		 * just remove it.
60744f1a7abSJohan Hedberg 		 */
60844f1a7abSJohan Hedberg 		if (!bacmp(&smp->remote_irk->rpa, BDADDR_ANY)) {
60944f1a7abSJohan Hedberg 			list_del(&smp->remote_irk->list);
61044f1a7abSJohan Hedberg 			kfree(smp->remote_irk);
61144f1a7abSJohan Hedberg 			smp->remote_irk = NULL;
61244f1a7abSJohan Hedberg 		}
61344f1a7abSJohan Hedberg 	}
61444f1a7abSJohan Hedberg 
61544f1a7abSJohan Hedberg 	/* The LTKs and CSRKs should be persistent only if both sides
61644f1a7abSJohan Hedberg 	 * had the bonding bit set in their authentication requests.
61744f1a7abSJohan Hedberg 	 */
61844f1a7abSJohan Hedberg 	persistent = !!((req->auth_req & rsp->auth_req) & SMP_AUTH_BONDING);
61944f1a7abSJohan Hedberg 
62044f1a7abSJohan Hedberg 	if (smp->csrk) {
62144f1a7abSJohan Hedberg 		smp->csrk->bdaddr_type = hcon->dst_type;
62244f1a7abSJohan Hedberg 		bacpy(&smp->csrk->bdaddr, &hcon->dst);
62344f1a7abSJohan Hedberg 		mgmt_new_csrk(hdev, smp->csrk, persistent);
62444f1a7abSJohan Hedberg 	}
62544f1a7abSJohan Hedberg 
62644f1a7abSJohan Hedberg 	if (smp->slave_csrk) {
62744f1a7abSJohan Hedberg 		smp->slave_csrk->bdaddr_type = hcon->dst_type;
62844f1a7abSJohan Hedberg 		bacpy(&smp->slave_csrk->bdaddr, &hcon->dst);
62944f1a7abSJohan Hedberg 		mgmt_new_csrk(hdev, smp->slave_csrk, persistent);
63044f1a7abSJohan Hedberg 	}
63144f1a7abSJohan Hedberg 
63244f1a7abSJohan Hedberg 	if (smp->ltk) {
63344f1a7abSJohan Hedberg 		smp->ltk->bdaddr_type = hcon->dst_type;
63444f1a7abSJohan Hedberg 		bacpy(&smp->ltk->bdaddr, &hcon->dst);
63544f1a7abSJohan Hedberg 		mgmt_new_ltk(hdev, smp->ltk, persistent);
63644f1a7abSJohan Hedberg 	}
63744f1a7abSJohan Hedberg 
63844f1a7abSJohan Hedberg 	if (smp->slave_ltk) {
63944f1a7abSJohan Hedberg 		smp->slave_ltk->bdaddr_type = hcon->dst_type;
64044f1a7abSJohan Hedberg 		bacpy(&smp->slave_ltk->bdaddr, &hcon->dst);
64144f1a7abSJohan Hedberg 		mgmt_new_ltk(hdev, smp->slave_ltk, persistent);
64244f1a7abSJohan Hedberg 	}
64344f1a7abSJohan Hedberg }
64444f1a7abSJohan Hedberg 
64544f1a7abSJohan Hedberg static int smp_distribute_keys(struct l2cap_conn *conn)
64644f1a7abSJohan Hedberg {
64744f1a7abSJohan Hedberg 	struct smp_cmd_pairing *req, *rsp;
64844f1a7abSJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
64944f1a7abSJohan Hedberg 	struct smp_chan *smp = chan->data;
65044f1a7abSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
65144f1a7abSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
65244f1a7abSJohan Hedberg 	__u8 *keydist;
65344f1a7abSJohan Hedberg 
65444f1a7abSJohan Hedberg 	BT_DBG("conn %p", conn);
65544f1a7abSJohan Hedberg 
65644f1a7abSJohan Hedberg 	if (!test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
65744f1a7abSJohan Hedberg 		return 0;
65844f1a7abSJohan Hedberg 
65944f1a7abSJohan Hedberg 	rsp = (void *) &smp->prsp[1];
66044f1a7abSJohan Hedberg 
66144f1a7abSJohan Hedberg 	/* The responder sends its keys first */
66244f1a7abSJohan Hedberg 	if (hcon->out && (smp->remote_key_dist & 0x07))
66344f1a7abSJohan Hedberg 		return 0;
66444f1a7abSJohan Hedberg 
66544f1a7abSJohan Hedberg 	req = (void *) &smp->preq[1];
66644f1a7abSJohan Hedberg 
66744f1a7abSJohan Hedberg 	if (hcon->out) {
66844f1a7abSJohan Hedberg 		keydist = &rsp->init_key_dist;
66944f1a7abSJohan Hedberg 		*keydist &= req->init_key_dist;
67044f1a7abSJohan Hedberg 	} else {
67144f1a7abSJohan Hedberg 		keydist = &rsp->resp_key_dist;
67244f1a7abSJohan Hedberg 		*keydist &= req->resp_key_dist;
67344f1a7abSJohan Hedberg 	}
67444f1a7abSJohan Hedberg 
67544f1a7abSJohan Hedberg 	BT_DBG("keydist 0x%x", *keydist);
67644f1a7abSJohan Hedberg 
67744f1a7abSJohan Hedberg 	if (*keydist & SMP_DIST_ENC_KEY) {
67844f1a7abSJohan Hedberg 		struct smp_cmd_encrypt_info enc;
67944f1a7abSJohan Hedberg 		struct smp_cmd_master_ident ident;
68044f1a7abSJohan Hedberg 		struct smp_ltk *ltk;
68144f1a7abSJohan Hedberg 		u8 authenticated;
68244f1a7abSJohan Hedberg 		__le16 ediv;
68344f1a7abSJohan Hedberg 		__le64 rand;
68444f1a7abSJohan Hedberg 
68544f1a7abSJohan Hedberg 		get_random_bytes(enc.ltk, sizeof(enc.ltk));
68644f1a7abSJohan Hedberg 		get_random_bytes(&ediv, sizeof(ediv));
68744f1a7abSJohan Hedberg 		get_random_bytes(&rand, sizeof(rand));
68844f1a7abSJohan Hedberg 
68944f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
69044f1a7abSJohan Hedberg 
69144f1a7abSJohan Hedberg 		authenticated = hcon->sec_level == BT_SECURITY_HIGH;
69244f1a7abSJohan Hedberg 		ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type,
69344f1a7abSJohan Hedberg 				  SMP_LTK_SLAVE, authenticated, enc.ltk,
69444f1a7abSJohan Hedberg 				  smp->enc_key_size, ediv, rand);
69544f1a7abSJohan Hedberg 		smp->slave_ltk = ltk;
69644f1a7abSJohan Hedberg 
69744f1a7abSJohan Hedberg 		ident.ediv = ediv;
69844f1a7abSJohan Hedberg 		ident.rand = rand;
69944f1a7abSJohan Hedberg 
70044f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident);
70144f1a7abSJohan Hedberg 
70244f1a7abSJohan Hedberg 		*keydist &= ~SMP_DIST_ENC_KEY;
70344f1a7abSJohan Hedberg 	}
70444f1a7abSJohan Hedberg 
70544f1a7abSJohan Hedberg 	if (*keydist & SMP_DIST_ID_KEY) {
70644f1a7abSJohan Hedberg 		struct smp_cmd_ident_addr_info addrinfo;
70744f1a7abSJohan Hedberg 		struct smp_cmd_ident_info idinfo;
70844f1a7abSJohan Hedberg 
70944f1a7abSJohan Hedberg 		memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk));
71044f1a7abSJohan Hedberg 
71144f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo);
71244f1a7abSJohan Hedberg 
71344f1a7abSJohan Hedberg 		/* The hci_conn contains the local identity address
71444f1a7abSJohan Hedberg 		 * after the connection has been established.
71544f1a7abSJohan Hedberg 		 *
71644f1a7abSJohan Hedberg 		 * This is true even when the connection has been
71744f1a7abSJohan Hedberg 		 * established using a resolvable random address.
71844f1a7abSJohan Hedberg 		 */
71944f1a7abSJohan Hedberg 		bacpy(&addrinfo.bdaddr, &hcon->src);
72044f1a7abSJohan Hedberg 		addrinfo.addr_type = hcon->src_type;
72144f1a7abSJohan Hedberg 
72244f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo),
72344f1a7abSJohan Hedberg 			     &addrinfo);
72444f1a7abSJohan Hedberg 
72544f1a7abSJohan Hedberg 		*keydist &= ~SMP_DIST_ID_KEY;
72644f1a7abSJohan Hedberg 	}
72744f1a7abSJohan Hedberg 
72844f1a7abSJohan Hedberg 	if (*keydist & SMP_DIST_SIGN) {
72944f1a7abSJohan Hedberg 		struct smp_cmd_sign_info sign;
73044f1a7abSJohan Hedberg 		struct smp_csrk *csrk;
73144f1a7abSJohan Hedberg 
73244f1a7abSJohan Hedberg 		/* Generate a new random key */
73344f1a7abSJohan Hedberg 		get_random_bytes(sign.csrk, sizeof(sign.csrk));
73444f1a7abSJohan Hedberg 
73544f1a7abSJohan Hedberg 		csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
73644f1a7abSJohan Hedberg 		if (csrk) {
73744f1a7abSJohan Hedberg 			csrk->master = 0x00;
73844f1a7abSJohan Hedberg 			memcpy(csrk->val, sign.csrk, sizeof(csrk->val));
73944f1a7abSJohan Hedberg 		}
74044f1a7abSJohan Hedberg 		smp->slave_csrk = csrk;
74144f1a7abSJohan Hedberg 
74244f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign);
74344f1a7abSJohan Hedberg 
74444f1a7abSJohan Hedberg 		*keydist &= ~SMP_DIST_SIGN;
74544f1a7abSJohan Hedberg 	}
74644f1a7abSJohan Hedberg 
74744f1a7abSJohan Hedberg 	/* If there are still keys to be received wait for them */
74844f1a7abSJohan Hedberg 	if ((smp->remote_key_dist & 0x07))
74944f1a7abSJohan Hedberg 		return 0;
75044f1a7abSJohan Hedberg 
75144f1a7abSJohan Hedberg 	clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags);
75244f1a7abSJohan Hedberg 	cancel_delayed_work_sync(&conn->security_timer);
75344f1a7abSJohan Hedberg 	set_bit(SMP_FLAG_COMPLETE, &smp->flags);
75444f1a7abSJohan Hedberg 	smp_notify_keys(conn);
75544f1a7abSJohan Hedberg 
75644f1a7abSJohan Hedberg 	smp_chan_destroy(conn);
75744f1a7abSJohan Hedberg 
75844f1a7abSJohan Hedberg 	return 0;
75944f1a7abSJohan Hedberg }
76044f1a7abSJohan Hedberg 
7618aab4757SVinicius Costa Gomes static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
7628aab4757SVinicius Costa Gomes {
7635d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
7648aab4757SVinicius Costa Gomes 	struct smp_chan *smp;
7658aab4757SVinicius Costa Gomes 
766f1560463SMarcel Holtmann 	smp = kzalloc(sizeof(*smp), GFP_ATOMIC);
767616d55beSJohan Hedberg 	if (!smp) {
768616d55beSJohan Hedberg 		clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags);
7698aab4757SVinicius Costa Gomes 		return NULL;
770616d55beSJohan Hedberg 	}
7718aab4757SVinicius Costa Gomes 
7726a7bd103SJohan Hedberg 	smp->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
7736a7bd103SJohan Hedberg 	if (IS_ERR(smp->tfm_aes)) {
7746a7bd103SJohan Hedberg 		BT_ERR("Unable to create ECB crypto context");
7756a7bd103SJohan Hedberg 		kfree(smp);
776616d55beSJohan Hedberg 		clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags);
7776a7bd103SJohan Hedberg 		return NULL;
7786a7bd103SJohan Hedberg 	}
7796a7bd103SJohan Hedberg 
7808aab4757SVinicius Costa Gomes 	smp->conn = conn;
7815d88cc73SJohan Hedberg 	chan->data = smp;
7828aab4757SVinicius Costa Gomes 
7838aab4757SVinicius Costa Gomes 	hci_conn_hold(conn->hcon);
7848aab4757SVinicius Costa Gomes 
7858aab4757SVinicius Costa Gomes 	return smp;
7868aab4757SVinicius Costa Gomes }
7878aab4757SVinicius Costa Gomes 
7888aab4757SVinicius Costa Gomes void smp_chan_destroy(struct l2cap_conn *conn)
7898aab4757SVinicius Costa Gomes {
7905d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
7915d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
792f4a407beSJohan Hedberg 	bool complete;
793c8eb9690SBrian Gix 
794f1c09c07SVinicius Costa Gomes 	BUG_ON(!smp);
795c8eb9690SBrian Gix 
7964a74d658SJohan Hedberg 	complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags);
797f4a407beSJohan Hedberg 	mgmt_smp_complete(conn->hcon, complete);
798f4a407beSJohan Hedberg 
7997ee4ea36SMarcel Holtmann 	kfree(smp->csrk);
8007ee4ea36SMarcel Holtmann 	kfree(smp->slave_csrk);
8017ee4ea36SMarcel Holtmann 
8026a7bd103SJohan Hedberg 	crypto_free_blkcipher(smp->tfm_aes);
8036a7bd103SJohan Hedberg 
804759331d7SJohan Hedberg 	/* If pairing failed clean up any keys we might have */
805759331d7SJohan Hedberg 	if (!complete) {
806759331d7SJohan Hedberg 		if (smp->ltk) {
807759331d7SJohan Hedberg 			list_del(&smp->ltk->list);
808759331d7SJohan Hedberg 			kfree(smp->ltk);
809759331d7SJohan Hedberg 		}
810759331d7SJohan Hedberg 
811759331d7SJohan Hedberg 		if (smp->slave_ltk) {
812759331d7SJohan Hedberg 			list_del(&smp->slave_ltk->list);
813759331d7SJohan Hedberg 			kfree(smp->slave_ltk);
814759331d7SJohan Hedberg 		}
815759331d7SJohan Hedberg 
816759331d7SJohan Hedberg 		if (smp->remote_irk) {
817759331d7SJohan Hedberg 			list_del(&smp->remote_irk->list);
818759331d7SJohan Hedberg 			kfree(smp->remote_irk);
819759331d7SJohan Hedberg 		}
820759331d7SJohan Hedberg 	}
821759331d7SJohan Hedberg 
8225d88cc73SJohan Hedberg 	chan->data = NULL;
823c8eb9690SBrian Gix 	kfree(smp);
82476a68ba0SDavid Herrmann 	hci_conn_drop(conn->hcon);
8258aab4757SVinicius Costa Gomes }
8268aab4757SVinicius Costa Gomes 
8272b64d153SBrian Gix int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
8282b64d153SBrian Gix {
829b10e8017SJohan Hedberg 	struct l2cap_conn *conn = hcon->l2cap_data;
8305d88cc73SJohan Hedberg 	struct l2cap_chan *chan;
8312b64d153SBrian Gix 	struct smp_chan *smp;
8322b64d153SBrian Gix 	u32 value;
8332b64d153SBrian Gix 
8342b64d153SBrian Gix 	BT_DBG("");
8352b64d153SBrian Gix 
836642ac774SJohan Hedberg 	if (!conn || !test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
8372b64d153SBrian Gix 		return -ENOTCONN;
8382b64d153SBrian Gix 
8395d88cc73SJohan Hedberg 	chan = conn->smp;
8405d88cc73SJohan Hedberg 	if (!chan)
8415d88cc73SJohan Hedberg 		return -ENOTCONN;
8425d88cc73SJohan Hedberg 
8435d88cc73SJohan Hedberg 	smp = chan->data;
8442b64d153SBrian Gix 
8452b64d153SBrian Gix 	switch (mgmt_op) {
8462b64d153SBrian Gix 	case MGMT_OP_USER_PASSKEY_REPLY:
8472b64d153SBrian Gix 		value = le32_to_cpu(passkey);
848943a732aSJohan Hedberg 		memset(smp->tk, 0, sizeof(smp->tk));
8492b64d153SBrian Gix 		BT_DBG("PassKey: %d", value);
850943a732aSJohan Hedberg 		put_unaligned_le32(value, smp->tk);
8512b64d153SBrian Gix 		/* Fall Through */
8522b64d153SBrian Gix 	case MGMT_OP_USER_CONFIRM_REPLY:
8534a74d658SJohan Hedberg 		set_bit(SMP_FLAG_TK_VALID, &smp->flags);
8542b64d153SBrian Gix 		break;
8552b64d153SBrian Gix 	case MGMT_OP_USER_PASSKEY_NEG_REPLY:
8562b64d153SBrian Gix 	case MGMT_OP_USER_CONFIRM_NEG_REPLY:
85784794e11SJohan Hedberg 		smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
8582b64d153SBrian Gix 		return 0;
8592b64d153SBrian Gix 	default:
86084794e11SJohan Hedberg 		smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
8612b64d153SBrian Gix 		return -EOPNOTSUPP;
8622b64d153SBrian Gix 	}
8632b64d153SBrian Gix 
8642b64d153SBrian Gix 	/* If it is our turn to send Pairing Confirm, do so now */
8651cc61144SJohan Hedberg 	if (test_bit(SMP_FLAG_CFM_PENDING, &smp->flags)) {
8661cc61144SJohan Hedberg 		u8 rsp = smp_confirm(smp);
8671cc61144SJohan Hedberg 		if (rsp)
8681cc61144SJohan Hedberg 			smp_failure(conn, rsp);
8691cc61144SJohan Hedberg 	}
8702b64d153SBrian Gix 
8712b64d153SBrian Gix 	return 0;
8722b64d153SBrian Gix }
8732b64d153SBrian Gix 
874da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
87588ba43b6SAnderson Briglia {
8763158c50cSVinicius Costa Gomes 	struct smp_cmd_pairing rsp, *req = (void *) skb->data;
877b3c6410bSJohan Hedberg 	struct hci_dev *hdev = conn->hcon->hdev;
8788aab4757SVinicius Costa Gomes 	struct smp_chan *smp;
879c7262e71SJohan Hedberg 	u8 key_size, auth, sec_level;
8808aab4757SVinicius Costa Gomes 	int ret;
88188ba43b6SAnderson Briglia 
88288ba43b6SAnderson Briglia 	BT_DBG("conn %p", conn);
88388ba43b6SAnderson Briglia 
884c46b98beSJohan Hedberg 	if (skb->len < sizeof(*req))
88538e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
886c46b98beSJohan Hedberg 
88740bef302SJohan Hedberg 	if (conn->hcon->role != HCI_ROLE_SLAVE)
8882b64d153SBrian Gix 		return SMP_CMD_NOTSUPP;
8892b64d153SBrian Gix 
8905d88cc73SJohan Hedberg 	if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
8918aab4757SVinicius Costa Gomes 		smp = smp_chan_create(conn);
8925d88cc73SJohan Hedberg 	} else {
8935d88cc73SJohan Hedberg 		struct l2cap_chan *chan = conn->smp;
8945d88cc73SJohan Hedberg 		smp = chan->data;
8955d88cc73SJohan Hedberg 	}
896d26a2345SVinicius Costa Gomes 
897d08fd0e7SAndrei Emeltchenko 	if (!smp)
898d08fd0e7SAndrei Emeltchenko 		return SMP_UNSPECIFIED;
899d08fd0e7SAndrei Emeltchenko 
900b6ae8457SJohan Hedberg 	if (!test_bit(HCI_BONDABLE, &hdev->dev_flags) &&
901b3c6410bSJohan Hedberg 	    (req->auth_req & SMP_AUTH_BONDING))
902b3c6410bSJohan Hedberg 		return SMP_PAIRING_NOTSUPP;
903b3c6410bSJohan Hedberg 
9041c1def09SVinicius Costa Gomes 	smp->preq[0] = SMP_CMD_PAIRING_REQ;
9051c1def09SVinicius Costa Gomes 	memcpy(&smp->preq[1], req, sizeof(*req));
9063158c50cSVinicius Costa Gomes 	skb_pull(skb, sizeof(*req));
90788ba43b6SAnderson Briglia 
9082b64d153SBrian Gix 	/* We didn't start the pairing, so match remote */
9092b64d153SBrian Gix 	auth = req->auth_req;
910da85e5e5SVinicius Costa Gomes 
911c7262e71SJohan Hedberg 	sec_level = authreq_to_seclevel(auth);
912c7262e71SJohan Hedberg 	if (sec_level > conn->hcon->pending_sec_level)
913c7262e71SJohan Hedberg 		conn->hcon->pending_sec_level = sec_level;
914fdde0a26SIdo Yariv 
9152ed8f65cSJohan Hedberg 	/* If we need MITM check that it can be acheived */
9162ed8f65cSJohan Hedberg 	if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
9172ed8f65cSJohan Hedberg 		u8 method;
9182ed8f65cSJohan Hedberg 
9192ed8f65cSJohan Hedberg 		method = get_auth_method(smp, conn->hcon->io_capability,
9202ed8f65cSJohan Hedberg 					 req->io_capability);
9212ed8f65cSJohan Hedberg 		if (method == JUST_WORKS || method == JUST_CFM)
9222ed8f65cSJohan Hedberg 			return SMP_AUTH_REQUIREMENTS;
9232ed8f65cSJohan Hedberg 	}
9242ed8f65cSJohan Hedberg 
9252b64d153SBrian Gix 	build_pairing_cmd(conn, req, &rsp, auth);
9263158c50cSVinicius Costa Gomes 
9273158c50cSVinicius Costa Gomes 	key_size = min(req->max_key_size, rsp.max_key_size);
9283158c50cSVinicius Costa Gomes 	if (check_enc_key_size(conn, key_size))
9293158c50cSVinicius Costa Gomes 		return SMP_ENC_KEY_SIZE;
93088ba43b6SAnderson Briglia 
931e84a6b13SJohan Hedberg 	get_random_bytes(smp->prnd, sizeof(smp->prnd));
9328aab4757SVinicius Costa Gomes 
9331c1def09SVinicius Costa Gomes 	smp->prsp[0] = SMP_CMD_PAIRING_RSP;
9341c1def09SVinicius Costa Gomes 	memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
935f01ead31SAnderson Briglia 
9363158c50cSVinicius Costa Gomes 	smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
937da85e5e5SVinicius Costa Gomes 
9382b64d153SBrian Gix 	/* Request setup of TK */
9392b64d153SBrian Gix 	ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability);
9402b64d153SBrian Gix 	if (ret)
9412b64d153SBrian Gix 		return SMP_UNSPECIFIED;
9422b64d153SBrian Gix 
943da85e5e5SVinicius Costa Gomes 	return 0;
94488ba43b6SAnderson Briglia }
94588ba43b6SAnderson Briglia 
946da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
94788ba43b6SAnderson Briglia {
9483158c50cSVinicius Costa Gomes 	struct smp_cmd_pairing *req, *rsp = (void *) skb->data;
9495d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
9505d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
9512b64d153SBrian Gix 	u8 key_size, auth = SMP_AUTH_NONE;
9527d24ddccSAnderson Briglia 	int ret;
95388ba43b6SAnderson Briglia 
95488ba43b6SAnderson Briglia 	BT_DBG("conn %p", conn);
95588ba43b6SAnderson Briglia 
956c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rsp))
95738e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
958c46b98beSJohan Hedberg 
95940bef302SJohan Hedberg 	if (conn->hcon->role != HCI_ROLE_MASTER)
9602b64d153SBrian Gix 		return SMP_CMD_NOTSUPP;
9612b64d153SBrian Gix 
9623158c50cSVinicius Costa Gomes 	skb_pull(skb, sizeof(*rsp));
963da85e5e5SVinicius Costa Gomes 
9641c1def09SVinicius Costa Gomes 	req = (void *) &smp->preq[1];
9653158c50cSVinicius Costa Gomes 
9663158c50cSVinicius Costa Gomes 	key_size = min(req->max_key_size, rsp->max_key_size);
9673158c50cSVinicius Costa Gomes 	if (check_enc_key_size(conn, key_size))
9683158c50cSVinicius Costa Gomes 		return SMP_ENC_KEY_SIZE;
9693158c50cSVinicius Costa Gomes 
9702ed8f65cSJohan Hedberg 	/* If we need MITM check that it can be acheived */
9712ed8f65cSJohan Hedberg 	if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
9722ed8f65cSJohan Hedberg 		u8 method;
9732ed8f65cSJohan Hedberg 
9742ed8f65cSJohan Hedberg 		method = get_auth_method(smp, req->io_capability,
9752ed8f65cSJohan Hedberg 					 rsp->io_capability);
9762ed8f65cSJohan Hedberg 		if (method == JUST_WORKS || method == JUST_CFM)
9772ed8f65cSJohan Hedberg 			return SMP_AUTH_REQUIREMENTS;
9782ed8f65cSJohan Hedberg 	}
9792ed8f65cSJohan Hedberg 
980e84a6b13SJohan Hedberg 	get_random_bytes(smp->prnd, sizeof(smp->prnd));
9817d24ddccSAnderson Briglia 
9828aab4757SVinicius Costa Gomes 	smp->prsp[0] = SMP_CMD_PAIRING_RSP;
9838aab4757SVinicius Costa Gomes 	memcpy(&smp->prsp[1], rsp, sizeof(*rsp));
9847d24ddccSAnderson Briglia 
985fdcc4becSJohan Hedberg 	/* Update remote key distribution in case the remote cleared
986fdcc4becSJohan Hedberg 	 * some bits that we had enabled in our request.
987fdcc4becSJohan Hedberg 	 */
988fdcc4becSJohan Hedberg 	smp->remote_key_dist &= rsp->resp_key_dist;
989fdcc4becSJohan Hedberg 
9902b64d153SBrian Gix 	if ((req->auth_req & SMP_AUTH_BONDING) &&
9912b64d153SBrian Gix 	    (rsp->auth_req & SMP_AUTH_BONDING))
9922b64d153SBrian Gix 		auth = SMP_AUTH_BONDING;
9932b64d153SBrian Gix 
9942b64d153SBrian Gix 	auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM;
9952b64d153SBrian Gix 
996476585ecSJohan Hedberg 	ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability);
9972b64d153SBrian Gix 	if (ret)
9982b64d153SBrian Gix 		return SMP_UNSPECIFIED;
9992b64d153SBrian Gix 
10004a74d658SJohan Hedberg 	set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
10012b64d153SBrian Gix 
10022b64d153SBrian Gix 	/* Can't compose response until we have been confirmed */
10034a74d658SJohan Hedberg 	if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
10041cc61144SJohan Hedberg 		return smp_confirm(smp);
1005da85e5e5SVinicius Costa Gomes 
1006da85e5e5SVinicius Costa Gomes 	return 0;
100788ba43b6SAnderson Briglia }
100888ba43b6SAnderson Briglia 
1009da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
101088ba43b6SAnderson Briglia {
10115d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
10125d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
10137d24ddccSAnderson Briglia 
101488ba43b6SAnderson Briglia 	BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
101588ba43b6SAnderson Briglia 
1016c46b98beSJohan Hedberg 	if (skb->len < sizeof(smp->pcnf))
101738e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1018c46b98beSJohan Hedberg 
10191c1def09SVinicius Costa Gomes 	memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf));
10201c1def09SVinicius Costa Gomes 	skb_pull(skb, sizeof(smp->pcnf));
10217d24ddccSAnderson Briglia 
1022943a732aSJohan Hedberg 	if (conn->hcon->out)
1023943a732aSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
1024943a732aSJohan Hedberg 			     smp->prnd);
10254a74d658SJohan Hedberg 	else if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
10261cc61144SJohan Hedberg 		return smp_confirm(smp);
1027943a732aSJohan Hedberg 	else
10284a74d658SJohan Hedberg 		set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
1029da85e5e5SVinicius Costa Gomes 
1030da85e5e5SVinicius Costa Gomes 	return 0;
103188ba43b6SAnderson Briglia }
103288ba43b6SAnderson Briglia 
1033da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
103488ba43b6SAnderson Briglia {
10355d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
10365d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
10377d24ddccSAnderson Briglia 
10388aab4757SVinicius Costa Gomes 	BT_DBG("conn %p", conn);
10397d24ddccSAnderson Briglia 
1040c46b98beSJohan Hedberg 	if (skb->len < sizeof(smp->rrnd))
104138e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1042c46b98beSJohan Hedberg 
1043943a732aSJohan Hedberg 	memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd));
10448aab4757SVinicius Costa Gomes 	skb_pull(skb, sizeof(smp->rrnd));
104588ba43b6SAnderson Briglia 
1046861580a9SJohan Hedberg 	return smp_random(smp);
104788ba43b6SAnderson Briglia }
104888ba43b6SAnderson Briglia 
1049f81cd823SMarcel Holtmann static bool smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
1050988c5997SVinicius Costa Gomes {
1051c9839a11SVinicius Costa Gomes 	struct smp_ltk *key;
1052988c5997SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
1053988c5997SVinicius Costa Gomes 
105498a0b845SJohan Hedberg 	key = hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type,
1055e804d25dSJohan Hedberg 				   hcon->role);
1056988c5997SVinicius Costa Gomes 	if (!key)
1057f81cd823SMarcel Holtmann 		return false;
1058988c5997SVinicius Costa Gomes 
10594dab7864SJohan Hedberg 	if (sec_level > BT_SECURITY_MEDIUM && !key->authenticated)
1060f81cd823SMarcel Holtmann 		return false;
10614dab7864SJohan Hedberg 
106251a8efd7SJohan Hedberg 	if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
1063f81cd823SMarcel Holtmann 		return true;
1064988c5997SVinicius Costa Gomes 
1065c9839a11SVinicius Costa Gomes 	hci_le_start_enc(hcon, key->ediv, key->rand, key->val);
1066c9839a11SVinicius Costa Gomes 	hcon->enc_key_size = key->enc_size;
1067988c5997SVinicius Costa Gomes 
1068fe59a05fSJohan Hedberg 	/* We never store STKs for master role, so clear this flag */
1069fe59a05fSJohan Hedberg 	clear_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags);
1070fe59a05fSJohan Hedberg 
1071f81cd823SMarcel Holtmann 	return true;
1072988c5997SVinicius Costa Gomes }
1073f1560463SMarcel Holtmann 
1074854f4727SJohan Hedberg bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level)
1075854f4727SJohan Hedberg {
1076854f4727SJohan Hedberg 	if (sec_level == BT_SECURITY_LOW)
1077854f4727SJohan Hedberg 		return true;
1078854f4727SJohan Hedberg 
10799ab65d60SJohan Hedberg 	/* If we're encrypted with an STK always claim insufficient
10809ab65d60SJohan Hedberg 	 * security. This way we allow the connection to be re-encrypted
10819ab65d60SJohan Hedberg 	 * with an LTK, even if the LTK provides the same level of
1082b2d5e254SJohan Hedberg 	 * security. Only exception is if we don't have an LTK (e.g.
1083b2d5e254SJohan Hedberg 	 * because of key distribution bits).
10849ab65d60SJohan Hedberg 	 */
1085b2d5e254SJohan Hedberg 	if (test_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags) &&
1086b2d5e254SJohan Hedberg 	    hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type,
1087e804d25dSJohan Hedberg 				 hcon->role))
10889ab65d60SJohan Hedberg 		return false;
10899ab65d60SJohan Hedberg 
1090854f4727SJohan Hedberg 	if (hcon->sec_level >= sec_level)
1091854f4727SJohan Hedberg 		return true;
1092854f4727SJohan Hedberg 
1093854f4727SJohan Hedberg 	return false;
1094854f4727SJohan Hedberg }
1095854f4727SJohan Hedberg 
1096da85e5e5SVinicius Costa Gomes static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
109788ba43b6SAnderson Briglia {
109888ba43b6SAnderson Briglia 	struct smp_cmd_security_req *rp = (void *) skb->data;
109988ba43b6SAnderson Briglia 	struct smp_cmd_pairing cp;
1100f1cb9af5SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
11018aab4757SVinicius Costa Gomes 	struct smp_chan *smp;
1102c7262e71SJohan Hedberg 	u8 sec_level;
110388ba43b6SAnderson Briglia 
110488ba43b6SAnderson Briglia 	BT_DBG("conn %p", conn);
110588ba43b6SAnderson Briglia 
1106c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rp))
110738e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1108c46b98beSJohan Hedberg 
110940bef302SJohan Hedberg 	if (hcon->role != HCI_ROLE_MASTER)
111086ca9eacSJohan Hedberg 		return SMP_CMD_NOTSUPP;
111186ca9eacSJohan Hedberg 
1112c7262e71SJohan Hedberg 	sec_level = authreq_to_seclevel(rp->auth_req);
1113854f4727SJohan Hedberg 	if (smp_sufficient_security(hcon, sec_level))
1114854f4727SJohan Hedberg 		return 0;
1115854f4727SJohan Hedberg 
1116c7262e71SJohan Hedberg 	if (sec_level > hcon->pending_sec_level)
1117c7262e71SJohan Hedberg 		hcon->pending_sec_level = sec_level;
1118feb45eb5SVinicius Costa Gomes 
11194dab7864SJohan Hedberg 	if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
1120988c5997SVinicius Costa Gomes 		return 0;
1121988c5997SVinicius Costa Gomes 
112251a8efd7SJohan Hedberg 	if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
1123da85e5e5SVinicius Costa Gomes 		return 0;
1124f1cb9af5SVinicius Costa Gomes 
11258aab4757SVinicius Costa Gomes 	smp = smp_chan_create(conn);
1126c29d2444SJohan Hedberg 	if (!smp)
1127c29d2444SJohan Hedberg 		return SMP_UNSPECIFIED;
1128d26a2345SVinicius Costa Gomes 
1129b6ae8457SJohan Hedberg 	if (!test_bit(HCI_BONDABLE, &hcon->hdev->dev_flags) &&
1130616d55beSJohan Hedberg 	    (rp->auth_req & SMP_AUTH_BONDING))
1131616d55beSJohan Hedberg 		return SMP_PAIRING_NOTSUPP;
1132616d55beSJohan Hedberg 
113388ba43b6SAnderson Briglia 	skb_pull(skb, sizeof(*rp));
113488ba43b6SAnderson Briglia 
1135da85e5e5SVinicius Costa Gomes 	memset(&cp, 0, sizeof(cp));
113654790f73SVinicius Costa Gomes 	build_pairing_cmd(conn, &cp, NULL, rp->auth_req);
113788ba43b6SAnderson Briglia 
11381c1def09SVinicius Costa Gomes 	smp->preq[0] = SMP_CMD_PAIRING_REQ;
11391c1def09SVinicius Costa Gomes 	memcpy(&smp->preq[1], &cp, sizeof(cp));
1140f01ead31SAnderson Briglia 
114188ba43b6SAnderson Briglia 	smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
1142f1cb9af5SVinicius Costa Gomes 
1143da85e5e5SVinicius Costa Gomes 	return 0;
114488ba43b6SAnderson Briglia }
114588ba43b6SAnderson Briglia 
1146cc110922SVinicius Costa Gomes int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
1147eb492e01SAnderson Briglia {
1148cc110922SVinicius Costa Gomes 	struct l2cap_conn *conn = hcon->l2cap_data;
11490a66cf20SJohan Hedberg 	struct smp_chan *smp;
11502b64d153SBrian Gix 	__u8 authreq;
1151eb492e01SAnderson Briglia 
11523a0259bbSVinicius Costa Gomes 	BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
11533a0259bbSVinicius Costa Gomes 
11540a66cf20SJohan Hedberg 	/* This may be NULL if there's an unexpected disconnection */
11550a66cf20SJohan Hedberg 	if (!conn)
11560a66cf20SJohan Hedberg 		return 1;
11570a66cf20SJohan Hedberg 
1158757aee0fSJohan Hedberg 	if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags))
11592e65c9d2SAndre Guedes 		return 1;
11602e65c9d2SAndre Guedes 
1161ad32a2f5SJohan Hedberg 	if (smp_sufficient_security(hcon, sec_level))
1162f1cb9af5SVinicius Costa Gomes 		return 1;
1163f1cb9af5SVinicius Costa Gomes 
1164c7262e71SJohan Hedberg 	if (sec_level > hcon->pending_sec_level)
1165c7262e71SJohan Hedberg 		hcon->pending_sec_level = sec_level;
1166c7262e71SJohan Hedberg 
116740bef302SJohan Hedberg 	if (hcon->role == HCI_ROLE_MASTER)
1168c7262e71SJohan Hedberg 		if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
1169c7262e71SJohan Hedberg 			return 0;
1170d26a2345SVinicius Costa Gomes 
117151a8efd7SJohan Hedberg 	if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
1172d26a2345SVinicius Costa Gomes 		return 0;
1173d26a2345SVinicius Costa Gomes 
11748aab4757SVinicius Costa Gomes 	smp = smp_chan_create(conn);
11752b64d153SBrian Gix 	if (!smp)
11762b64d153SBrian Gix 		return 1;
11772b64d153SBrian Gix 
11782b64d153SBrian Gix 	authreq = seclevel_to_authreq(sec_level);
1179d26a2345SVinicius Costa Gomes 
118079897d20SJohan Hedberg 	/* Require MITM if IO Capability allows or the security level
118179897d20SJohan Hedberg 	 * requires it.
11822e233644SJohan Hedberg 	 */
118379897d20SJohan Hedberg 	if (hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT ||
1184c7262e71SJohan Hedberg 	    hcon->pending_sec_level > BT_SECURITY_MEDIUM)
11852e233644SJohan Hedberg 		authreq |= SMP_AUTH_MITM;
11862e233644SJohan Hedberg 
118740bef302SJohan Hedberg 	if (hcon->role == HCI_ROLE_MASTER) {
1188d26a2345SVinicius Costa Gomes 		struct smp_cmd_pairing cp;
1189f01ead31SAnderson Briglia 
11902b64d153SBrian Gix 		build_pairing_cmd(conn, &cp, NULL, authreq);
11911c1def09SVinicius Costa Gomes 		smp->preq[0] = SMP_CMD_PAIRING_REQ;
11921c1def09SVinicius Costa Gomes 		memcpy(&smp->preq[1], &cp, sizeof(cp));
1193f01ead31SAnderson Briglia 
1194eb492e01SAnderson Briglia 		smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
1195eb492e01SAnderson Briglia 	} else {
1196eb492e01SAnderson Briglia 		struct smp_cmd_security_req cp;
11972b64d153SBrian Gix 		cp.auth_req = authreq;
1198eb492e01SAnderson Briglia 		smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
1199eb492e01SAnderson Briglia 	}
1200eb492e01SAnderson Briglia 
12014a74d658SJohan Hedberg 	set_bit(SMP_FLAG_INITIATOR, &smp->flags);
1202edca792cSJohan Hedberg 
1203eb492e01SAnderson Briglia 	return 0;
1204eb492e01SAnderson Briglia }
1205eb492e01SAnderson Briglia 
12067034b911SVinicius Costa Gomes static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
12077034b911SVinicius Costa Gomes {
120816b90839SVinicius Costa Gomes 	struct smp_cmd_encrypt_info *rp = (void *) skb->data;
12095d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
12105d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
121116b90839SVinicius Costa Gomes 
1212c46b98beSJohan Hedberg 	BT_DBG("conn %p", conn);
1213c46b98beSJohan Hedberg 
1214c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rp))
121538e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1216c46b98beSJohan Hedberg 
12176131ddc8SJohan Hedberg 	/* Ignore this PDU if it wasn't requested */
12186131ddc8SJohan Hedberg 	if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
12196131ddc8SJohan Hedberg 		return 0;
12206131ddc8SJohan Hedberg 
122116b90839SVinicius Costa Gomes 	skb_pull(skb, sizeof(*rp));
122216b90839SVinicius Costa Gomes 
12231c1def09SVinicius Costa Gomes 	memcpy(smp->tk, rp->ltk, sizeof(smp->tk));
122416b90839SVinicius Costa Gomes 
12257034b911SVinicius Costa Gomes 	return 0;
12267034b911SVinicius Costa Gomes }
12277034b911SVinicius Costa Gomes 
12287034b911SVinicius Costa Gomes static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
12297034b911SVinicius Costa Gomes {
123016b90839SVinicius Costa Gomes 	struct smp_cmd_master_ident *rp = (void *) skb->data;
12315d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
12325d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
1233c9839a11SVinicius Costa Gomes 	struct hci_dev *hdev = conn->hcon->hdev;
1234c9839a11SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
123523d0e128SJohan Hedberg 	struct smp_ltk *ltk;
1236c9839a11SVinicius Costa Gomes 	u8 authenticated;
12377034b911SVinicius Costa Gomes 
1238c46b98beSJohan Hedberg 	BT_DBG("conn %p", conn);
1239c46b98beSJohan Hedberg 
1240c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rp))
124138e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1242c46b98beSJohan Hedberg 
12436131ddc8SJohan Hedberg 	/* Ignore this PDU if it wasn't requested */
12446131ddc8SJohan Hedberg 	if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
12456131ddc8SJohan Hedberg 		return 0;
12466131ddc8SJohan Hedberg 
12479747a9f3SJohan Hedberg 	/* Mark the information as received */
12489747a9f3SJohan Hedberg 	smp->remote_key_dist &= ~SMP_DIST_ENC_KEY;
12499747a9f3SJohan Hedberg 
125016b90839SVinicius Costa Gomes 	skb_pull(skb, sizeof(*rp));
125116b90839SVinicius Costa Gomes 
1252c9839a11SVinicius Costa Gomes 	hci_dev_lock(hdev);
1253ce39fb4eSMarcel Holtmann 	authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
12542ceba539SJohan Hedberg 	ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, SMP_LTK,
1255ce39fb4eSMarcel Holtmann 			  authenticated, smp->tk, smp->enc_key_size,
125604124681SGustavo F. Padovan 			  rp->ediv, rp->rand);
125723d0e128SJohan Hedberg 	smp->ltk = ltk;
1258fd349c02SJohan Hedberg 	if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
12594bd6d38eSJohan Hedberg 		smp_distribute_keys(conn);
1260c9839a11SVinicius Costa Gomes 	hci_dev_unlock(hdev);
12617034b911SVinicius Costa Gomes 
12627034b911SVinicius Costa Gomes 	return 0;
12637034b911SVinicius Costa Gomes }
12647034b911SVinicius Costa Gomes 
1265fd349c02SJohan Hedberg static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
1266fd349c02SJohan Hedberg {
1267fd349c02SJohan Hedberg 	struct smp_cmd_ident_info *info = (void *) skb->data;
12685d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
12695d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
1270fd349c02SJohan Hedberg 
1271fd349c02SJohan Hedberg 	BT_DBG("");
1272fd349c02SJohan Hedberg 
1273fd349c02SJohan Hedberg 	if (skb->len < sizeof(*info))
127438e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1275fd349c02SJohan Hedberg 
12766131ddc8SJohan Hedberg 	/* Ignore this PDU if it wasn't requested */
12776131ddc8SJohan Hedberg 	if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
12786131ddc8SJohan Hedberg 		return 0;
12796131ddc8SJohan Hedberg 
1280fd349c02SJohan Hedberg 	skb_pull(skb, sizeof(*info));
1281fd349c02SJohan Hedberg 
1282fd349c02SJohan Hedberg 	memcpy(smp->irk, info->irk, 16);
1283fd349c02SJohan Hedberg 
1284fd349c02SJohan Hedberg 	return 0;
1285fd349c02SJohan Hedberg }
1286fd349c02SJohan Hedberg 
1287fd349c02SJohan Hedberg static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
1288fd349c02SJohan Hedberg 				   struct sk_buff *skb)
1289fd349c02SJohan Hedberg {
1290fd349c02SJohan Hedberg 	struct smp_cmd_ident_addr_info *info = (void *) skb->data;
12915d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
12925d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
1293fd349c02SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
1294fd349c02SJohan Hedberg 	bdaddr_t rpa;
1295fd349c02SJohan Hedberg 
1296fd349c02SJohan Hedberg 	BT_DBG("");
1297fd349c02SJohan Hedberg 
1298fd349c02SJohan Hedberg 	if (skb->len < sizeof(*info))
129938e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1300fd349c02SJohan Hedberg 
13016131ddc8SJohan Hedberg 	/* Ignore this PDU if it wasn't requested */
13026131ddc8SJohan Hedberg 	if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
13036131ddc8SJohan Hedberg 		return 0;
13046131ddc8SJohan Hedberg 
13059747a9f3SJohan Hedberg 	/* Mark the information as received */
13069747a9f3SJohan Hedberg 	smp->remote_key_dist &= ~SMP_DIST_ID_KEY;
13079747a9f3SJohan Hedberg 
1308fd349c02SJohan Hedberg 	skb_pull(skb, sizeof(*info));
1309fd349c02SJohan Hedberg 
131031dd624eSJohan Hedberg 	hci_dev_lock(hcon->hdev);
131131dd624eSJohan Hedberg 
1312a9a58f86SJohan Hedberg 	/* Strictly speaking the Core Specification (4.1) allows sending
1313a9a58f86SJohan Hedberg 	 * an empty address which would force us to rely on just the IRK
1314a9a58f86SJohan Hedberg 	 * as "identity information". However, since such
1315a9a58f86SJohan Hedberg 	 * implementations are not known of and in order to not over
1316a9a58f86SJohan Hedberg 	 * complicate our implementation, simply pretend that we never
1317a9a58f86SJohan Hedberg 	 * received an IRK for such a device.
1318a9a58f86SJohan Hedberg 	 */
1319a9a58f86SJohan Hedberg 	if (!bacmp(&info->bdaddr, BDADDR_ANY)) {
1320a9a58f86SJohan Hedberg 		BT_ERR("Ignoring IRK with no identity address");
132131dd624eSJohan Hedberg 		goto distribute;
1322a9a58f86SJohan Hedberg 	}
1323a9a58f86SJohan Hedberg 
1324fd349c02SJohan Hedberg 	bacpy(&smp->id_addr, &info->bdaddr);
1325fd349c02SJohan Hedberg 	smp->id_addr_type = info->addr_type;
1326fd349c02SJohan Hedberg 
1327fd349c02SJohan Hedberg 	if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type))
1328fd349c02SJohan Hedberg 		bacpy(&rpa, &hcon->dst);
1329fd349c02SJohan Hedberg 	else
1330fd349c02SJohan Hedberg 		bacpy(&rpa, BDADDR_ANY);
1331fd349c02SJohan Hedberg 
133223d0e128SJohan Hedberg 	smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
133323d0e128SJohan Hedberg 				      smp->id_addr_type, smp->irk, &rpa);
1334fd349c02SJohan Hedberg 
133531dd624eSJohan Hedberg distribute:
13364bd6d38eSJohan Hedberg 	smp_distribute_keys(conn);
1337fd349c02SJohan Hedberg 
133831dd624eSJohan Hedberg 	hci_dev_unlock(hcon->hdev);
133931dd624eSJohan Hedberg 
1340fd349c02SJohan Hedberg 	return 0;
1341fd349c02SJohan Hedberg }
1342fd349c02SJohan Hedberg 
13437ee4ea36SMarcel Holtmann static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)
13447ee4ea36SMarcel Holtmann {
13457ee4ea36SMarcel Holtmann 	struct smp_cmd_sign_info *rp = (void *) skb->data;
13465d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
13475d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
13487ee4ea36SMarcel Holtmann 	struct hci_dev *hdev = conn->hcon->hdev;
13497ee4ea36SMarcel Holtmann 	struct smp_csrk *csrk;
13507ee4ea36SMarcel Holtmann 
13517ee4ea36SMarcel Holtmann 	BT_DBG("conn %p", conn);
13527ee4ea36SMarcel Holtmann 
13537ee4ea36SMarcel Holtmann 	if (skb->len < sizeof(*rp))
135438e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
13557ee4ea36SMarcel Holtmann 
13567ee4ea36SMarcel Holtmann 	/* Ignore this PDU if it wasn't requested */
13577ee4ea36SMarcel Holtmann 	if (!(smp->remote_key_dist & SMP_DIST_SIGN))
13587ee4ea36SMarcel Holtmann 		return 0;
13597ee4ea36SMarcel Holtmann 
13607ee4ea36SMarcel Holtmann 	/* Mark the information as received */
13617ee4ea36SMarcel Holtmann 	smp->remote_key_dist &= ~SMP_DIST_SIGN;
13627ee4ea36SMarcel Holtmann 
13637ee4ea36SMarcel Holtmann 	skb_pull(skb, sizeof(*rp));
13647ee4ea36SMarcel Holtmann 
13657ee4ea36SMarcel Holtmann 	hci_dev_lock(hdev);
13667ee4ea36SMarcel Holtmann 	csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
13677ee4ea36SMarcel Holtmann 	if (csrk) {
13687ee4ea36SMarcel Holtmann 		csrk->master = 0x01;
13697ee4ea36SMarcel Holtmann 		memcpy(csrk->val, rp->csrk, sizeof(csrk->val));
13707ee4ea36SMarcel Holtmann 	}
13717ee4ea36SMarcel Holtmann 	smp->csrk = csrk;
13727ee4ea36SMarcel Holtmann 	smp_distribute_keys(conn);
13737ee4ea36SMarcel Holtmann 	hci_dev_unlock(hdev);
13747ee4ea36SMarcel Holtmann 
13757ee4ea36SMarcel Holtmann 	return 0;
13767ee4ea36SMarcel Holtmann }
13777ee4ea36SMarcel Holtmann 
13784befb867SJohan Hedberg static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb)
1379eb492e01SAnderson Briglia {
13805d88cc73SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
13817b9899dbSMarcel Holtmann 	struct hci_conn *hcon = conn->hcon;
138292381f5cSMarcel Holtmann 	__u8 code, reason;
1383eb492e01SAnderson Briglia 	int err = 0;
1384eb492e01SAnderson Briglia 
13857b9899dbSMarcel Holtmann 	if (hcon->type != LE_LINK) {
13867b9899dbSMarcel Holtmann 		kfree_skb(skb);
13873432711fSJohan Hedberg 		return 0;
13887b9899dbSMarcel Holtmann 	}
13897b9899dbSMarcel Holtmann 
139092381f5cSMarcel Holtmann 	if (skb->len < 1) {
139192381f5cSMarcel Holtmann 		kfree_skb(skb);
139292381f5cSMarcel Holtmann 		return -EILSEQ;
139392381f5cSMarcel Holtmann 	}
139492381f5cSMarcel Holtmann 
139506ae3314SMarcel Holtmann 	if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) {
1396beb19e4cSJohan Hedberg 		err = -EOPNOTSUPP;
13972e65c9d2SAndre Guedes 		reason = SMP_PAIRING_NOTSUPP;
13982e65c9d2SAndre Guedes 		goto done;
13992e65c9d2SAndre Guedes 	}
14002e65c9d2SAndre Guedes 
140192381f5cSMarcel Holtmann 	code = skb->data[0];
1402eb492e01SAnderson Briglia 	skb_pull(skb, sizeof(code));
1403eb492e01SAnderson Briglia 
14048cf9fa12SJohan Hedberg 	/*
14058cf9fa12SJohan Hedberg 	 * The SMP context must be initialized for all other PDUs except
14068cf9fa12SJohan Hedberg 	 * pairing and security requests. If we get any other PDU when
14078cf9fa12SJohan Hedberg 	 * not initialized simply disconnect (done if this function
14088cf9fa12SJohan Hedberg 	 * returns an error).
14098cf9fa12SJohan Hedberg 	 */
14108cf9fa12SJohan Hedberg 	if (code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ &&
1411d3368605SJohan Hedberg 	    !test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
14128cf9fa12SJohan Hedberg 		BT_ERR("Unexpected SMP command 0x%02x. Disconnecting.", code);
14138cf9fa12SJohan Hedberg 		kfree_skb(skb);
1414beb19e4cSJohan Hedberg 		return -EOPNOTSUPP;
14158cf9fa12SJohan Hedberg 	}
14168cf9fa12SJohan Hedberg 
1417eb492e01SAnderson Briglia 	switch (code) {
1418eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_REQ:
1419da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_req(conn, skb);
1420eb492e01SAnderson Briglia 		break;
1421eb492e01SAnderson Briglia 
1422eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_FAIL:
142384794e11SJohan Hedberg 		smp_failure(conn, 0);
1424da85e5e5SVinicius Costa Gomes 		reason = 0;
1425da85e5e5SVinicius Costa Gomes 		err = -EPERM;
1426eb492e01SAnderson Briglia 		break;
1427eb492e01SAnderson Briglia 
1428eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_RSP:
1429da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_rsp(conn, skb);
143088ba43b6SAnderson Briglia 		break;
143188ba43b6SAnderson Briglia 
143288ba43b6SAnderson Briglia 	case SMP_CMD_SECURITY_REQ:
1433da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_security_req(conn, skb);
143488ba43b6SAnderson Briglia 		break;
143588ba43b6SAnderson Briglia 
1436eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_CONFIRM:
1437da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_confirm(conn, skb);
143888ba43b6SAnderson Briglia 		break;
143988ba43b6SAnderson Briglia 
1440eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_RANDOM:
1441da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_random(conn, skb);
144288ba43b6SAnderson Briglia 		break;
144388ba43b6SAnderson Briglia 
1444eb492e01SAnderson Briglia 	case SMP_CMD_ENCRYPT_INFO:
14457034b911SVinicius Costa Gomes 		reason = smp_cmd_encrypt_info(conn, skb);
14467034b911SVinicius Costa Gomes 		break;
14477034b911SVinicius Costa Gomes 
1448eb492e01SAnderson Briglia 	case SMP_CMD_MASTER_IDENT:
14497034b911SVinicius Costa Gomes 		reason = smp_cmd_master_ident(conn, skb);
14507034b911SVinicius Costa Gomes 		break;
14517034b911SVinicius Costa Gomes 
1452eb492e01SAnderson Briglia 	case SMP_CMD_IDENT_INFO:
1453fd349c02SJohan Hedberg 		reason = smp_cmd_ident_info(conn, skb);
1454fd349c02SJohan Hedberg 		break;
1455fd349c02SJohan Hedberg 
1456eb492e01SAnderson Briglia 	case SMP_CMD_IDENT_ADDR_INFO:
1457fd349c02SJohan Hedberg 		reason = smp_cmd_ident_addr_info(conn, skb);
1458fd349c02SJohan Hedberg 		break;
1459fd349c02SJohan Hedberg 
1460eb492e01SAnderson Briglia 	case SMP_CMD_SIGN_INFO:
14617ee4ea36SMarcel Holtmann 		reason = smp_cmd_sign_info(conn, skb);
14627034b911SVinicius Costa Gomes 		break;
14637034b911SVinicius Costa Gomes 
1464eb492e01SAnderson Briglia 	default:
1465eb492e01SAnderson Briglia 		BT_DBG("Unknown command code 0x%2.2x", code);
1466eb492e01SAnderson Briglia 
1467eb492e01SAnderson Briglia 		reason = SMP_CMD_NOTSUPP;
14683a0259bbSVinicius Costa Gomes 		err = -EOPNOTSUPP;
14693a0259bbSVinicius Costa Gomes 		goto done;
14703a0259bbSVinicius Costa Gomes 	}
14713a0259bbSVinicius Costa Gomes 
14723a0259bbSVinicius Costa Gomes done:
14733a0259bbSVinicius Costa Gomes 	if (reason)
147484794e11SJohan Hedberg 		smp_failure(conn, reason);
1475eb492e01SAnderson Briglia 
1476eb492e01SAnderson Briglia 	kfree_skb(skb);
1477eb492e01SAnderson Briglia 	return err;
1478eb492e01SAnderson Briglia }
14797034b911SVinicius Costa Gomes 
148070db83c4SJohan Hedberg static void smp_teardown_cb(struct l2cap_chan *chan, int err)
148170db83c4SJohan Hedberg {
148270db83c4SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
148370db83c4SJohan Hedberg 
148470db83c4SJohan Hedberg 	BT_DBG("chan %p", chan);
148570db83c4SJohan Hedberg 
14865d88cc73SJohan Hedberg 	if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
14875d88cc73SJohan Hedberg 		cancel_delayed_work_sync(&conn->security_timer);
14885d88cc73SJohan Hedberg 		smp_chan_destroy(conn);
14895d88cc73SJohan Hedberg 	}
14905d88cc73SJohan Hedberg 
149170db83c4SJohan Hedberg 	conn->smp = NULL;
149270db83c4SJohan Hedberg 	l2cap_chan_put(chan);
149370db83c4SJohan Hedberg }
149470db83c4SJohan Hedberg 
149544f1a7abSJohan Hedberg static void smp_resume_cb(struct l2cap_chan *chan)
149644f1a7abSJohan Hedberg {
149744f1a7abSJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
149844f1a7abSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
149944f1a7abSJohan Hedberg 
150044f1a7abSJohan Hedberg 	BT_DBG("chan %p", chan);
150144f1a7abSJohan Hedberg 
150244f1a7abSJohan Hedberg 	if (test_bit(HCI_CONN_ENCRYPT, &hcon->flags))
150344f1a7abSJohan Hedberg 		smp_distribute_keys(conn);
150444f1a7abSJohan Hedberg 	cancel_delayed_work(&conn->security_timer);
150544f1a7abSJohan Hedberg }
150644f1a7abSJohan Hedberg 
150770db83c4SJohan Hedberg static void smp_ready_cb(struct l2cap_chan *chan)
150870db83c4SJohan Hedberg {
150970db83c4SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
151070db83c4SJohan Hedberg 
151170db83c4SJohan Hedberg 	BT_DBG("chan %p", chan);
151270db83c4SJohan Hedberg 
151370db83c4SJohan Hedberg 	conn->smp = chan;
151470db83c4SJohan Hedberg 	l2cap_chan_hold(chan);
151570db83c4SJohan Hedberg }
151670db83c4SJohan Hedberg 
15174befb867SJohan Hedberg static int smp_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
15184befb867SJohan Hedberg {
15194befb867SJohan Hedberg 	int err;
15204befb867SJohan Hedberg 
15214befb867SJohan Hedberg 	BT_DBG("chan %p", chan);
15224befb867SJohan Hedberg 
15234befb867SJohan Hedberg 	err = smp_sig_channel(chan, skb);
15244befb867SJohan Hedberg 	if (err) {
15254befb867SJohan Hedberg 		struct l2cap_conn *conn = chan->conn;
15264befb867SJohan Hedberg 
15274befb867SJohan Hedberg 		cancel_delayed_work_sync(&conn->security_timer);
15284befb867SJohan Hedberg 
15294befb867SJohan Hedberg 		l2cap_conn_shutdown(chan->conn, -err);
15304befb867SJohan Hedberg 	}
15314befb867SJohan Hedberg 
15324befb867SJohan Hedberg 	return err;
15334befb867SJohan Hedberg }
15344befb867SJohan Hedberg 
153570db83c4SJohan Hedberg static struct sk_buff *smp_alloc_skb_cb(struct l2cap_chan *chan,
153670db83c4SJohan Hedberg 					unsigned long hdr_len,
153770db83c4SJohan Hedberg 					unsigned long len, int nb)
153870db83c4SJohan Hedberg {
153970db83c4SJohan Hedberg 	struct sk_buff *skb;
154070db83c4SJohan Hedberg 
154170db83c4SJohan Hedberg 	skb = bt_skb_alloc(hdr_len + len, GFP_KERNEL);
154270db83c4SJohan Hedberg 	if (!skb)
154370db83c4SJohan Hedberg 		return ERR_PTR(-ENOMEM);
154470db83c4SJohan Hedberg 
154570db83c4SJohan Hedberg 	skb->priority = HCI_PRIO_MAX;
154670db83c4SJohan Hedberg 	bt_cb(skb)->chan = chan;
154770db83c4SJohan Hedberg 
154870db83c4SJohan Hedberg 	return skb;
154970db83c4SJohan Hedberg }
155070db83c4SJohan Hedberg 
155170db83c4SJohan Hedberg static const struct l2cap_ops smp_chan_ops = {
155270db83c4SJohan Hedberg 	.name			= "Security Manager",
155370db83c4SJohan Hedberg 	.ready			= smp_ready_cb,
15545d88cc73SJohan Hedberg 	.recv			= smp_recv_cb,
155570db83c4SJohan Hedberg 	.alloc_skb		= smp_alloc_skb_cb,
155670db83c4SJohan Hedberg 	.teardown		= smp_teardown_cb,
155744f1a7abSJohan Hedberg 	.resume			= smp_resume_cb,
155870db83c4SJohan Hedberg 
155970db83c4SJohan Hedberg 	.new_connection		= l2cap_chan_no_new_connection,
156070db83c4SJohan Hedberg 	.state_change		= l2cap_chan_no_state_change,
156170db83c4SJohan Hedberg 	.close			= l2cap_chan_no_close,
156270db83c4SJohan Hedberg 	.defer			= l2cap_chan_no_defer,
156370db83c4SJohan Hedberg 	.suspend		= l2cap_chan_no_suspend,
156470db83c4SJohan Hedberg 	.set_shutdown		= l2cap_chan_no_set_shutdown,
156570db83c4SJohan Hedberg 	.get_sndtimeo		= l2cap_chan_no_get_sndtimeo,
156670db83c4SJohan Hedberg 	.memcpy_fromiovec	= l2cap_chan_no_memcpy_fromiovec,
156770db83c4SJohan Hedberg };
156870db83c4SJohan Hedberg 
156970db83c4SJohan Hedberg static inline struct l2cap_chan *smp_new_conn_cb(struct l2cap_chan *pchan)
157070db83c4SJohan Hedberg {
157170db83c4SJohan Hedberg 	struct l2cap_chan *chan;
157270db83c4SJohan Hedberg 
157370db83c4SJohan Hedberg 	BT_DBG("pchan %p", pchan);
157470db83c4SJohan Hedberg 
157570db83c4SJohan Hedberg 	chan = l2cap_chan_create();
157670db83c4SJohan Hedberg 	if (!chan)
157770db83c4SJohan Hedberg 		return NULL;
157870db83c4SJohan Hedberg 
157970db83c4SJohan Hedberg 	chan->chan_type	= pchan->chan_type;
158070db83c4SJohan Hedberg 	chan->ops	= &smp_chan_ops;
158170db83c4SJohan Hedberg 	chan->scid	= pchan->scid;
158270db83c4SJohan Hedberg 	chan->dcid	= chan->scid;
158370db83c4SJohan Hedberg 	chan->imtu	= pchan->imtu;
158470db83c4SJohan Hedberg 	chan->omtu	= pchan->omtu;
158570db83c4SJohan Hedberg 	chan->mode	= pchan->mode;
158670db83c4SJohan Hedberg 
158770db83c4SJohan Hedberg 	BT_DBG("created chan %p", chan);
158870db83c4SJohan Hedberg 
158970db83c4SJohan Hedberg 	return chan;
159070db83c4SJohan Hedberg }
159170db83c4SJohan Hedberg 
159270db83c4SJohan Hedberg static const struct l2cap_ops smp_root_chan_ops = {
159370db83c4SJohan Hedberg 	.name			= "Security Manager Root",
159470db83c4SJohan Hedberg 	.new_connection		= smp_new_conn_cb,
159570db83c4SJohan Hedberg 
159670db83c4SJohan Hedberg 	/* None of these are implemented for the root channel */
159770db83c4SJohan Hedberg 	.close			= l2cap_chan_no_close,
159870db83c4SJohan Hedberg 	.alloc_skb		= l2cap_chan_no_alloc_skb,
159970db83c4SJohan Hedberg 	.recv			= l2cap_chan_no_recv,
160070db83c4SJohan Hedberg 	.state_change		= l2cap_chan_no_state_change,
160170db83c4SJohan Hedberg 	.teardown		= l2cap_chan_no_teardown,
160270db83c4SJohan Hedberg 	.ready			= l2cap_chan_no_ready,
160370db83c4SJohan Hedberg 	.defer			= l2cap_chan_no_defer,
160470db83c4SJohan Hedberg 	.suspend		= l2cap_chan_no_suspend,
160570db83c4SJohan Hedberg 	.resume			= l2cap_chan_no_resume,
160670db83c4SJohan Hedberg 	.set_shutdown		= l2cap_chan_no_set_shutdown,
160770db83c4SJohan Hedberg 	.get_sndtimeo		= l2cap_chan_no_get_sndtimeo,
160870db83c4SJohan Hedberg 	.memcpy_fromiovec	= l2cap_chan_no_memcpy_fromiovec,
160970db83c4SJohan Hedberg };
161070db83c4SJohan Hedberg 
1611711eafe3SJohan Hedberg int smp_register(struct hci_dev *hdev)
1612711eafe3SJohan Hedberg {
161370db83c4SJohan Hedberg 	struct l2cap_chan *chan;
1614defce9e8SJohan Hedberg 	struct crypto_blkcipher	*tfm_aes;
161570db83c4SJohan Hedberg 
1616711eafe3SJohan Hedberg 	BT_DBG("%s", hdev->name);
1617711eafe3SJohan Hedberg 
1618defce9e8SJohan Hedberg 	tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
1619defce9e8SJohan Hedberg 	if (IS_ERR(tfm_aes)) {
1620defce9e8SJohan Hedberg 		int err = PTR_ERR(tfm_aes);
1621711eafe3SJohan Hedberg 		BT_ERR("Unable to create crypto context");
1622711eafe3SJohan Hedberg 		return err;
1623711eafe3SJohan Hedberg 	}
1624711eafe3SJohan Hedberg 
162570db83c4SJohan Hedberg 	chan = l2cap_chan_create();
162670db83c4SJohan Hedberg 	if (!chan) {
1627defce9e8SJohan Hedberg 		crypto_free_blkcipher(tfm_aes);
162870db83c4SJohan Hedberg 		return -ENOMEM;
162970db83c4SJohan Hedberg 	}
163070db83c4SJohan Hedberg 
1631defce9e8SJohan Hedberg 	chan->data = tfm_aes;
1632defce9e8SJohan Hedberg 
16335d88cc73SJohan Hedberg 	l2cap_add_scid(chan, L2CAP_CID_SMP);
163470db83c4SJohan Hedberg 
163570db83c4SJohan Hedberg 	l2cap_chan_set_defaults(chan);
163670db83c4SJohan Hedberg 
163770db83c4SJohan Hedberg 	bacpy(&chan->src, &hdev->bdaddr);
163870db83c4SJohan Hedberg 	chan->src_type = BDADDR_LE_PUBLIC;
163970db83c4SJohan Hedberg 	chan->state = BT_LISTEN;
164070db83c4SJohan Hedberg 	chan->mode = L2CAP_MODE_BASIC;
164170db83c4SJohan Hedberg 	chan->imtu = L2CAP_DEFAULT_MTU;
164270db83c4SJohan Hedberg 	chan->ops = &smp_root_chan_ops;
164370db83c4SJohan Hedberg 
164470db83c4SJohan Hedberg 	hdev->smp_data = chan;
164570db83c4SJohan Hedberg 
1646711eafe3SJohan Hedberg 	return 0;
1647711eafe3SJohan Hedberg }
1648711eafe3SJohan Hedberg 
1649711eafe3SJohan Hedberg void smp_unregister(struct hci_dev *hdev)
1650711eafe3SJohan Hedberg {
165170db83c4SJohan Hedberg 	struct l2cap_chan *chan = hdev->smp_data;
1652defce9e8SJohan Hedberg 	struct crypto_blkcipher *tfm_aes;
165370db83c4SJohan Hedberg 
165470db83c4SJohan Hedberg 	if (!chan)
165570db83c4SJohan Hedberg 		return;
165670db83c4SJohan Hedberg 
165770db83c4SJohan Hedberg 	BT_DBG("%s chan %p", hdev->name, chan);
1658711eafe3SJohan Hedberg 
1659defce9e8SJohan Hedberg 	tfm_aes = chan->data;
1660defce9e8SJohan Hedberg 	if (tfm_aes) {
1661defce9e8SJohan Hedberg 		chan->data = NULL;
1662defce9e8SJohan Hedberg 		crypto_free_blkcipher(tfm_aes);
1663711eafe3SJohan Hedberg 	}
166470db83c4SJohan Hedberg 
166570db83c4SJohan Hedberg 	hdev->smp_data = NULL;
166670db83c4SJohan Hedberg 	l2cap_chan_put(chan);
1667711eafe3SJohan Hedberg }
1668