xref: /openbmc/linux/net/bluetooth/smp.c (revision e491eaf3)
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 
34b28b4943SJohan Hedberg #define SMP_ALLOW_CMD(smp, code)	set_bit(code, &smp->allow_cmd)
35b28b4943SJohan Hedberg 
3617b02e62SMarcel Holtmann #define SMP_TIMEOUT	msecs_to_jiffies(30000)
375d3de7dfSVinicius Costa Gomes 
38065a13e2SJohan Hedberg #define AUTH_REQ_MASK   0x07
3988d3a8acSJohan Hedberg #define KEY_DIST_MASK	0x07
40065a13e2SJohan Hedberg 
41533e35d4SJohan Hedberg enum {
42533e35d4SJohan Hedberg 	SMP_FLAG_TK_VALID,
43533e35d4SJohan Hedberg 	SMP_FLAG_CFM_PENDING,
44533e35d4SJohan Hedberg 	SMP_FLAG_MITM_AUTH,
45533e35d4SJohan Hedberg 	SMP_FLAG_COMPLETE,
46533e35d4SJohan Hedberg 	SMP_FLAG_INITIATOR,
47533e35d4SJohan Hedberg };
484bc58f51SJohan Hedberg 
494bc58f51SJohan Hedberg struct smp_chan {
504bc58f51SJohan Hedberg 	struct l2cap_conn	*conn;
51b68fda68SJohan Hedberg 	struct delayed_work	security_timer;
52b28b4943SJohan Hedberg 	unsigned long           allow_cmd; /* Bitmask of allowed commands */
53b68fda68SJohan Hedberg 
544bc58f51SJohan Hedberg 	u8		preq[7]; /* SMP Pairing Request */
554bc58f51SJohan Hedberg 	u8		prsp[7]; /* SMP Pairing Response */
564bc58f51SJohan Hedberg 	u8		prnd[16]; /* SMP Pairing Random (local) */
574bc58f51SJohan Hedberg 	u8		rrnd[16]; /* SMP Pairing Random (remote) */
584bc58f51SJohan Hedberg 	u8		pcnf[16]; /* SMP Pairing Confirm */
594bc58f51SJohan Hedberg 	u8		tk[16]; /* SMP Temporary Key */
604bc58f51SJohan Hedberg 	u8		enc_key_size;
614bc58f51SJohan Hedberg 	u8		remote_key_dist;
624bc58f51SJohan Hedberg 	bdaddr_t	id_addr;
634bc58f51SJohan Hedberg 	u8		id_addr_type;
644bc58f51SJohan Hedberg 	u8		irk[16];
654bc58f51SJohan Hedberg 	struct smp_csrk	*csrk;
664bc58f51SJohan Hedberg 	struct smp_csrk	*slave_csrk;
674bc58f51SJohan Hedberg 	struct smp_ltk	*ltk;
684bc58f51SJohan Hedberg 	struct smp_ltk	*slave_ltk;
694bc58f51SJohan Hedberg 	struct smp_irk	*remote_irk;
704a74d658SJohan Hedberg 	unsigned long	flags;
716a7bd103SJohan Hedberg 
726a7bd103SJohan Hedberg 	struct crypto_blkcipher	*tfm_aes;
734bc58f51SJohan Hedberg };
744bc58f51SJohan Hedberg 
758a2936f4SJohan Hedberg static inline void swap_buf(const u8 *src, u8 *dst, size_t len)
76d22ef0bcSAnderson Briglia {
778a2936f4SJohan Hedberg 	size_t i;
78d22ef0bcSAnderson Briglia 
798a2936f4SJohan Hedberg 	for (i = 0; i < len; i++)
808a2936f4SJohan Hedberg 		dst[len - 1 - i] = src[i];
81d22ef0bcSAnderson Briglia }
82d22ef0bcSAnderson Briglia 
83d22ef0bcSAnderson Briglia static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
84d22ef0bcSAnderson Briglia {
85d22ef0bcSAnderson Briglia 	struct blkcipher_desc desc;
86d22ef0bcSAnderson Briglia 	struct scatterlist sg;
87943a732aSJohan Hedberg 	uint8_t tmp[16], data[16];
88201a5929SJohan Hedberg 	int err;
89d22ef0bcSAnderson Briglia 
90d22ef0bcSAnderson Briglia 	if (tfm == NULL) {
91d22ef0bcSAnderson Briglia 		BT_ERR("tfm %p", tfm);
92d22ef0bcSAnderson Briglia 		return -EINVAL;
93d22ef0bcSAnderson Briglia 	}
94d22ef0bcSAnderson Briglia 
95d22ef0bcSAnderson Briglia 	desc.tfm = tfm;
96d22ef0bcSAnderson Briglia 	desc.flags = 0;
97d22ef0bcSAnderson Briglia 
98943a732aSJohan Hedberg 	/* The most significant octet of key corresponds to k[0] */
998a2936f4SJohan Hedberg 	swap_buf(k, tmp, 16);
100943a732aSJohan Hedberg 
101943a732aSJohan Hedberg 	err = crypto_blkcipher_setkey(tfm, tmp, 16);
102d22ef0bcSAnderson Briglia 	if (err) {
103d22ef0bcSAnderson Briglia 		BT_ERR("cipher setkey failed: %d", err);
104d22ef0bcSAnderson Briglia 		return err;
105d22ef0bcSAnderson Briglia 	}
106d22ef0bcSAnderson Briglia 
107943a732aSJohan Hedberg 	/* Most significant octet of plaintextData corresponds to data[0] */
1088a2936f4SJohan Hedberg 	swap_buf(r, data, 16);
109943a732aSJohan Hedberg 
110943a732aSJohan Hedberg 	sg_init_one(&sg, data, 16);
111d22ef0bcSAnderson Briglia 
112d22ef0bcSAnderson Briglia 	err = crypto_blkcipher_encrypt(&desc, &sg, &sg, 16);
113d22ef0bcSAnderson Briglia 	if (err)
114d22ef0bcSAnderson Briglia 		BT_ERR("Encrypt data error %d", err);
115d22ef0bcSAnderson Briglia 
116943a732aSJohan Hedberg 	/* Most significant octet of encryptedData corresponds to data[0] */
1178a2936f4SJohan Hedberg 	swap_buf(data, r, 16);
118943a732aSJohan Hedberg 
119d22ef0bcSAnderson Briglia 	return err;
120d22ef0bcSAnderson Briglia }
121d22ef0bcSAnderson Briglia 
12260478054SJohan Hedberg static int smp_ah(struct crypto_blkcipher *tfm, u8 irk[16], u8 r[3], u8 res[3])
12360478054SJohan Hedberg {
124943a732aSJohan Hedberg 	u8 _res[16];
12560478054SJohan Hedberg 	int err;
12660478054SJohan Hedberg 
12760478054SJohan Hedberg 	/* r' = padding || r */
128943a732aSJohan Hedberg 	memcpy(_res, r, 3);
129943a732aSJohan Hedberg 	memset(_res + 3, 0, 13);
13060478054SJohan Hedberg 
131943a732aSJohan Hedberg 	err = smp_e(tfm, irk, _res);
13260478054SJohan Hedberg 	if (err) {
13360478054SJohan Hedberg 		BT_ERR("Encrypt error");
13460478054SJohan Hedberg 		return err;
13560478054SJohan Hedberg 	}
13660478054SJohan Hedberg 
13760478054SJohan Hedberg 	/* The output of the random address function ah is:
13860478054SJohan Hedberg 	 *	ah(h, r) = e(k, r') mod 2^24
13960478054SJohan Hedberg 	 * The output of the security function e is then truncated to 24 bits
14060478054SJohan Hedberg 	 * by taking the least significant 24 bits of the output of e as the
14160478054SJohan Hedberg 	 * result of ah.
14260478054SJohan Hedberg 	 */
143943a732aSJohan Hedberg 	memcpy(res, _res, 3);
14460478054SJohan Hedberg 
14560478054SJohan Hedberg 	return 0;
14660478054SJohan Hedberg }
14760478054SJohan Hedberg 
148defce9e8SJohan Hedberg bool smp_irk_matches(struct hci_dev *hdev, u8 irk[16], bdaddr_t *bdaddr)
14960478054SJohan Hedberg {
150defce9e8SJohan Hedberg 	struct l2cap_chan *chan = hdev->smp_data;
151defce9e8SJohan Hedberg 	struct crypto_blkcipher *tfm;
15260478054SJohan Hedberg 	u8 hash[3];
15360478054SJohan Hedberg 	int err;
15460478054SJohan Hedberg 
155defce9e8SJohan Hedberg 	if (!chan || !chan->data)
156defce9e8SJohan Hedberg 		return false;
157defce9e8SJohan Hedberg 
158defce9e8SJohan Hedberg 	tfm = chan->data;
159defce9e8SJohan Hedberg 
16060478054SJohan Hedberg 	BT_DBG("RPA %pMR IRK %*phN", bdaddr, 16, irk);
16160478054SJohan Hedberg 
16260478054SJohan Hedberg 	err = smp_ah(tfm, irk, &bdaddr->b[3], hash);
16360478054SJohan Hedberg 	if (err)
16460478054SJohan Hedberg 		return false;
16560478054SJohan Hedberg 
16660478054SJohan Hedberg 	return !memcmp(bdaddr->b, hash, 3);
16760478054SJohan Hedberg }
16860478054SJohan Hedberg 
169defce9e8SJohan Hedberg int smp_generate_rpa(struct hci_dev *hdev, u8 irk[16], bdaddr_t *rpa)
170b1e2b3aeSJohan Hedberg {
171defce9e8SJohan Hedberg 	struct l2cap_chan *chan = hdev->smp_data;
172defce9e8SJohan Hedberg 	struct crypto_blkcipher *tfm;
173b1e2b3aeSJohan Hedberg 	int err;
174b1e2b3aeSJohan Hedberg 
175defce9e8SJohan Hedberg 	if (!chan || !chan->data)
176defce9e8SJohan Hedberg 		return -EOPNOTSUPP;
177defce9e8SJohan Hedberg 
178defce9e8SJohan Hedberg 	tfm = chan->data;
179defce9e8SJohan Hedberg 
180b1e2b3aeSJohan Hedberg 	get_random_bytes(&rpa->b[3], 3);
181b1e2b3aeSJohan Hedberg 
182b1e2b3aeSJohan Hedberg 	rpa->b[5] &= 0x3f;	/* Clear two most significant bits */
183b1e2b3aeSJohan Hedberg 	rpa->b[5] |= 0x40;	/* Set second most significant bit */
184b1e2b3aeSJohan Hedberg 
185b1e2b3aeSJohan Hedberg 	err = smp_ah(tfm, irk, &rpa->b[3], rpa->b);
186b1e2b3aeSJohan Hedberg 	if (err < 0)
187b1e2b3aeSJohan Hedberg 		return err;
188b1e2b3aeSJohan Hedberg 
189b1e2b3aeSJohan Hedberg 	BT_DBG("RPA %pMR", rpa);
190b1e2b3aeSJohan Hedberg 
191b1e2b3aeSJohan Hedberg 	return 0;
192b1e2b3aeSJohan Hedberg }
193b1e2b3aeSJohan Hedberg 
194e491eaf3SJohan Hedberg static int smp_c1(struct crypto_blkcipher *tfm_aes, u8 k[16], u8 r[16],
195e491eaf3SJohan Hedberg 		  u8 preq[7], u8 pres[7], u8 _iat, bdaddr_t *ia, u8 _rat,
196e491eaf3SJohan Hedberg 		  bdaddr_t *ra, u8 res[16])
197d22ef0bcSAnderson Briglia {
198d22ef0bcSAnderson Briglia 	u8 p1[16], p2[16];
199d22ef0bcSAnderson Briglia 	int err;
200d22ef0bcSAnderson Briglia 
201d22ef0bcSAnderson Briglia 	memset(p1, 0, 16);
202d22ef0bcSAnderson Briglia 
203d22ef0bcSAnderson Briglia 	/* p1 = pres || preq || _rat || _iat */
204943a732aSJohan Hedberg 	p1[0] = _iat;
205943a732aSJohan Hedberg 	p1[1] = _rat;
206943a732aSJohan Hedberg 	memcpy(p1 + 2, preq, 7);
207943a732aSJohan Hedberg 	memcpy(p1 + 9, pres, 7);
208d22ef0bcSAnderson Briglia 
209d22ef0bcSAnderson Briglia 	/* p2 = padding || ia || ra */
210943a732aSJohan Hedberg 	memcpy(p2, ra, 6);
211943a732aSJohan Hedberg 	memcpy(p2 + 6, ia, 6);
212943a732aSJohan Hedberg 	memset(p2 + 12, 0, 4);
213d22ef0bcSAnderson Briglia 
214d22ef0bcSAnderson Briglia 	/* res = r XOR p1 */
215d22ef0bcSAnderson Briglia 	u128_xor((u128 *) res, (u128 *) r, (u128 *) p1);
216d22ef0bcSAnderson Briglia 
217d22ef0bcSAnderson Briglia 	/* res = e(k, res) */
218e491eaf3SJohan Hedberg 	err = smp_e(tfm_aes, k, res);
219d22ef0bcSAnderson Briglia 	if (err) {
220d22ef0bcSAnderson Briglia 		BT_ERR("Encrypt data error");
221d22ef0bcSAnderson Briglia 		return err;
222d22ef0bcSAnderson Briglia 	}
223d22ef0bcSAnderson Briglia 
224d22ef0bcSAnderson Briglia 	/* res = res XOR p2 */
225d22ef0bcSAnderson Briglia 	u128_xor((u128 *) res, (u128 *) res, (u128 *) p2);
226d22ef0bcSAnderson Briglia 
227d22ef0bcSAnderson Briglia 	/* res = e(k, res) */
228e491eaf3SJohan Hedberg 	err = smp_e(tfm_aes, k, res);
229d22ef0bcSAnderson Briglia 	if (err)
230d22ef0bcSAnderson Briglia 		BT_ERR("Encrypt data error");
231d22ef0bcSAnderson Briglia 
232d22ef0bcSAnderson Briglia 	return err;
233d22ef0bcSAnderson Briglia }
234d22ef0bcSAnderson Briglia 
235e491eaf3SJohan Hedberg static int smp_s1(struct crypto_blkcipher *tfm_aes, u8 k[16], u8 r1[16],
236e491eaf3SJohan Hedberg 		  u8 r2[16], u8 _r[16])
237d22ef0bcSAnderson Briglia {
238d22ef0bcSAnderson Briglia 	int err;
239d22ef0bcSAnderson Briglia 
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 
244e491eaf3SJohan Hedberg 	err = smp_e(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;
254b68fda68SJohan Hedberg 	struct smp_chan *smp;
2555d88cc73SJohan Hedberg 	struct kvec iv[2];
2565d88cc73SJohan Hedberg 	struct msghdr msg;
2575d88cc73SJohan Hedberg 
2585d88cc73SJohan Hedberg 	if (!chan)
2595d88cc73SJohan Hedberg 		return;
260eb492e01SAnderson Briglia 
261eb492e01SAnderson Briglia 	BT_DBG("code 0x%2.2x", code);
262eb492e01SAnderson Briglia 
2635d88cc73SJohan Hedberg 	iv[0].iov_base = &code;
2645d88cc73SJohan Hedberg 	iv[0].iov_len = 1;
265eb492e01SAnderson Briglia 
2665d88cc73SJohan Hedberg 	iv[1].iov_base = data;
2675d88cc73SJohan Hedberg 	iv[1].iov_len = len;
2685d88cc73SJohan Hedberg 
2695d88cc73SJohan Hedberg 	memset(&msg, 0, sizeof(msg));
2705d88cc73SJohan Hedberg 
2715d88cc73SJohan Hedberg 	msg.msg_iov = (struct iovec *) &iv;
2725d88cc73SJohan Hedberg 	msg.msg_iovlen = 2;
2735d88cc73SJohan Hedberg 
2745d88cc73SJohan Hedberg 	l2cap_chan_send(chan, &msg, 1 + len);
275e2dcd113SVinicius Costa Gomes 
276b68fda68SJohan Hedberg 	if (!chan->data)
277b68fda68SJohan Hedberg 		return;
278b68fda68SJohan Hedberg 
279b68fda68SJohan Hedberg 	smp = chan->data;
280b68fda68SJohan Hedberg 
281b68fda68SJohan Hedberg 	cancel_delayed_work_sync(&smp->security_timer);
282b68fda68SJohan Hedberg 	schedule_delayed_work(&smp->security_timer, SMP_TIMEOUT);
283eb492e01SAnderson Briglia }
284eb492e01SAnderson Briglia 
2852b64d153SBrian Gix static __u8 authreq_to_seclevel(__u8 authreq)
2862b64d153SBrian Gix {
2872b64d153SBrian Gix 	if (authreq & SMP_AUTH_MITM)
2882b64d153SBrian Gix 		return BT_SECURITY_HIGH;
2892b64d153SBrian Gix 	else
2902b64d153SBrian Gix 		return BT_SECURITY_MEDIUM;
2912b64d153SBrian Gix }
2922b64d153SBrian Gix 
2932b64d153SBrian Gix static __u8 seclevel_to_authreq(__u8 sec_level)
2942b64d153SBrian Gix {
2952b64d153SBrian Gix 	switch (sec_level) {
2962b64d153SBrian Gix 	case BT_SECURITY_HIGH:
2972b64d153SBrian Gix 		return SMP_AUTH_MITM | SMP_AUTH_BONDING;
2982b64d153SBrian Gix 	case BT_SECURITY_MEDIUM:
2992b64d153SBrian Gix 		return SMP_AUTH_BONDING;
3002b64d153SBrian Gix 	default:
3012b64d153SBrian Gix 		return SMP_AUTH_NONE;
3022b64d153SBrian Gix 	}
3032b64d153SBrian Gix }
3042b64d153SBrian Gix 
305b8e66eacSVinicius Costa Gomes static void build_pairing_cmd(struct l2cap_conn *conn,
30654790f73SVinicius Costa Gomes 			      struct smp_cmd_pairing *req,
307f1560463SMarcel Holtmann 			      struct smp_cmd_pairing *rsp, __u8 authreq)
308b8e66eacSVinicius Costa Gomes {
3095d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
3105d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
311fd349c02SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
312fd349c02SJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
313fd349c02SJohan Hedberg 	u8 local_dist = 0, remote_dist = 0;
31454790f73SVinicius Costa Gomes 
315b6ae8457SJohan Hedberg 	if (test_bit(HCI_BONDABLE, &conn->hcon->hdev->dev_flags)) {
3167ee4ea36SMarcel Holtmann 		local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
3177ee4ea36SMarcel Holtmann 		remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
31854790f73SVinicius Costa Gomes 		authreq |= SMP_AUTH_BONDING;
3192b64d153SBrian Gix 	} else {
3202b64d153SBrian Gix 		authreq &= ~SMP_AUTH_BONDING;
32154790f73SVinicius Costa Gomes 	}
32254790f73SVinicius Costa Gomes 
323fd349c02SJohan Hedberg 	if (test_bit(HCI_RPA_RESOLVING, &hdev->dev_flags))
324fd349c02SJohan Hedberg 		remote_dist |= SMP_DIST_ID_KEY;
325fd349c02SJohan Hedberg 
326863efaf2SJohan Hedberg 	if (test_bit(HCI_PRIVACY, &hdev->dev_flags))
327863efaf2SJohan Hedberg 		local_dist |= SMP_DIST_ID_KEY;
328863efaf2SJohan Hedberg 
32954790f73SVinicius Costa Gomes 	if (rsp == NULL) {
33054790f73SVinicius Costa Gomes 		req->io_capability = conn->hcon->io_capability;
33154790f73SVinicius Costa Gomes 		req->oob_flag = SMP_OOB_NOT_PRESENT;
33254790f73SVinicius Costa Gomes 		req->max_key_size = SMP_MAX_ENC_KEY_SIZE;
333fd349c02SJohan Hedberg 		req->init_key_dist = local_dist;
334fd349c02SJohan Hedberg 		req->resp_key_dist = remote_dist;
335065a13e2SJohan Hedberg 		req->auth_req = (authreq & AUTH_REQ_MASK);
336fd349c02SJohan Hedberg 
337fd349c02SJohan Hedberg 		smp->remote_key_dist = remote_dist;
33854790f73SVinicius Costa Gomes 		return;
33954790f73SVinicius Costa Gomes 	}
34054790f73SVinicius Costa Gomes 
34154790f73SVinicius Costa Gomes 	rsp->io_capability = conn->hcon->io_capability;
34254790f73SVinicius Costa Gomes 	rsp->oob_flag = SMP_OOB_NOT_PRESENT;
34354790f73SVinicius Costa Gomes 	rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE;
344fd349c02SJohan Hedberg 	rsp->init_key_dist = req->init_key_dist & remote_dist;
345fd349c02SJohan Hedberg 	rsp->resp_key_dist = req->resp_key_dist & local_dist;
346065a13e2SJohan Hedberg 	rsp->auth_req = (authreq & AUTH_REQ_MASK);
347fd349c02SJohan Hedberg 
348fd349c02SJohan Hedberg 	smp->remote_key_dist = rsp->init_key_dist;
349b8e66eacSVinicius Costa Gomes }
350b8e66eacSVinicius Costa Gomes 
3513158c50cSVinicius Costa Gomes static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
3523158c50cSVinicius Costa Gomes {
3535d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
3545d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
3551c1def09SVinicius Costa Gomes 
3563158c50cSVinicius Costa Gomes 	if ((max_key_size > SMP_MAX_ENC_KEY_SIZE) ||
3573158c50cSVinicius Costa Gomes 	    (max_key_size < SMP_MIN_ENC_KEY_SIZE))
3583158c50cSVinicius Costa Gomes 		return SMP_ENC_KEY_SIZE;
3593158c50cSVinicius Costa Gomes 
360f7aa611aSVinicius Costa Gomes 	smp->enc_key_size = max_key_size;
3613158c50cSVinicius Costa Gomes 
3623158c50cSVinicius Costa Gomes 	return 0;
3633158c50cSVinicius Costa Gomes }
3643158c50cSVinicius Costa Gomes 
3656f48e260SJohan Hedberg static void smp_chan_destroy(struct l2cap_conn *conn)
3666f48e260SJohan Hedberg {
3676f48e260SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
3686f48e260SJohan Hedberg 	struct smp_chan *smp = chan->data;
3696f48e260SJohan Hedberg 	bool complete;
3706f48e260SJohan Hedberg 
3716f48e260SJohan Hedberg 	BUG_ON(!smp);
3726f48e260SJohan Hedberg 
3736f48e260SJohan Hedberg 	cancel_delayed_work_sync(&smp->security_timer);
3746f48e260SJohan Hedberg 
3756f48e260SJohan Hedberg 	complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags);
3766f48e260SJohan Hedberg 	mgmt_smp_complete(conn->hcon, complete);
3776f48e260SJohan Hedberg 
3786f48e260SJohan Hedberg 	kfree(smp->csrk);
3796f48e260SJohan Hedberg 	kfree(smp->slave_csrk);
3806f48e260SJohan Hedberg 
3816f48e260SJohan Hedberg 	crypto_free_blkcipher(smp->tfm_aes);
3826f48e260SJohan Hedberg 
3836f48e260SJohan Hedberg 	/* If pairing failed clean up any keys we might have */
3846f48e260SJohan Hedberg 	if (!complete) {
3856f48e260SJohan Hedberg 		if (smp->ltk) {
3866f48e260SJohan Hedberg 			list_del(&smp->ltk->list);
3876f48e260SJohan Hedberg 			kfree(smp->ltk);
3886f48e260SJohan Hedberg 		}
3896f48e260SJohan Hedberg 
3906f48e260SJohan Hedberg 		if (smp->slave_ltk) {
3916f48e260SJohan Hedberg 			list_del(&smp->slave_ltk->list);
3926f48e260SJohan Hedberg 			kfree(smp->slave_ltk);
3936f48e260SJohan Hedberg 		}
3946f48e260SJohan Hedberg 
3956f48e260SJohan Hedberg 		if (smp->remote_irk) {
3966f48e260SJohan Hedberg 			list_del(&smp->remote_irk->list);
3976f48e260SJohan Hedberg 			kfree(smp->remote_irk);
3986f48e260SJohan Hedberg 		}
3996f48e260SJohan Hedberg 	}
4006f48e260SJohan Hedberg 
4016f48e260SJohan Hedberg 	chan->data = NULL;
4026f48e260SJohan Hedberg 	kfree(smp);
4036f48e260SJohan Hedberg 	hci_conn_drop(conn->hcon);
4046f48e260SJohan Hedberg }
4056f48e260SJohan Hedberg 
40684794e11SJohan Hedberg static void smp_failure(struct l2cap_conn *conn, u8 reason)
4074f957a76SBrian Gix {
408bab73cb6SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
409b68fda68SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
410bab73cb6SJohan Hedberg 
41184794e11SJohan Hedberg 	if (reason)
4124f957a76SBrian Gix 		smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
4134f957a76SBrian Gix 			     &reason);
4144f957a76SBrian Gix 
415ce39fb4eSMarcel Holtmann 	clear_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags);
416e1e930f5SJohan Hedberg 	mgmt_auth_failed(hcon, HCI_ERROR_AUTH_FAILURE);
417f1c09c07SVinicius Costa Gomes 
418fc75cc86SJohan Hedberg 	if (chan->data)
4194f957a76SBrian Gix 		smp_chan_destroy(conn);
4204f957a76SBrian Gix }
4214f957a76SBrian Gix 
4222b64d153SBrian Gix #define JUST_WORKS	0x00
4232b64d153SBrian Gix #define JUST_CFM	0x01
4242b64d153SBrian Gix #define REQ_PASSKEY	0x02
4252b64d153SBrian Gix #define CFM_PASSKEY	0x03
4262b64d153SBrian Gix #define REQ_OOB		0x04
4272b64d153SBrian Gix #define OVERLAP		0xFF
4282b64d153SBrian Gix 
4292b64d153SBrian Gix static const u8 gen_method[5][5] = {
4302b64d153SBrian Gix 	{ JUST_WORKS,  JUST_CFM,    REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
4312b64d153SBrian Gix 	{ JUST_WORKS,  JUST_CFM,    REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
4322b64d153SBrian Gix 	{ CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
4332b64d153SBrian Gix 	{ JUST_WORKS,  JUST_CFM,    JUST_WORKS,  JUST_WORKS, JUST_CFM    },
4342b64d153SBrian Gix 	{ CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, OVERLAP     },
4352b64d153SBrian Gix };
4362b64d153SBrian Gix 
437581370ccSJohan Hedberg static u8 get_auth_method(struct smp_chan *smp, u8 local_io, u8 remote_io)
438581370ccSJohan Hedberg {
4392bcd4003SJohan Hedberg 	/* If either side has unknown io_caps, use JUST_CFM (which gets
4402bcd4003SJohan Hedberg 	 * converted later to JUST_WORKS if we're initiators.
4412bcd4003SJohan Hedberg 	 */
442581370ccSJohan Hedberg 	if (local_io > SMP_IO_KEYBOARD_DISPLAY ||
443581370ccSJohan Hedberg 	    remote_io > SMP_IO_KEYBOARD_DISPLAY)
4442bcd4003SJohan Hedberg 		return JUST_CFM;
445581370ccSJohan Hedberg 
446581370ccSJohan Hedberg 	return gen_method[remote_io][local_io];
447581370ccSJohan Hedberg }
448581370ccSJohan Hedberg 
4492b64d153SBrian Gix static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
4502b64d153SBrian Gix 						u8 local_io, u8 remote_io)
4512b64d153SBrian Gix {
4522b64d153SBrian Gix 	struct hci_conn *hcon = conn->hcon;
4535d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
4545d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
4552b64d153SBrian Gix 	u8 method;
4562b64d153SBrian Gix 	u32 passkey = 0;
4572b64d153SBrian Gix 	int ret = 0;
4582b64d153SBrian Gix 
4592b64d153SBrian Gix 	/* Initialize key for JUST WORKS */
4602b64d153SBrian Gix 	memset(smp->tk, 0, sizeof(smp->tk));
4614a74d658SJohan Hedberg 	clear_bit(SMP_FLAG_TK_VALID, &smp->flags);
4622b64d153SBrian Gix 
4632b64d153SBrian Gix 	BT_DBG("tk_request: auth:%d lcl:%d rem:%d", auth, local_io, remote_io);
4642b64d153SBrian Gix 
4652bcd4003SJohan Hedberg 	/* If neither side wants MITM, either "just" confirm an incoming
4662bcd4003SJohan Hedberg 	 * request or use just-works for outgoing ones. The JUST_CFM
4672bcd4003SJohan Hedberg 	 * will be converted to JUST_WORKS if necessary later in this
4682bcd4003SJohan Hedberg 	 * function. If either side has MITM look up the method from the
4692bcd4003SJohan Hedberg 	 * table.
4702bcd4003SJohan Hedberg 	 */
471581370ccSJohan Hedberg 	if (!(auth & SMP_AUTH_MITM))
4722bcd4003SJohan Hedberg 		method = JUST_CFM;
4732b64d153SBrian Gix 	else
474581370ccSJohan Hedberg 		method = get_auth_method(smp, local_io, remote_io);
4752b64d153SBrian Gix 
476a82505c7SJohan Hedberg 	/* Don't confirm locally initiated pairing attempts */
4774a74d658SJohan Hedberg 	if (method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR, &smp->flags))
478a82505c7SJohan Hedberg 		method = JUST_WORKS;
479a82505c7SJohan Hedberg 
48002f3e254SJohan Hedberg 	/* Don't bother user space with no IO capabilities */
48102f3e254SJohan Hedberg 	if (method == JUST_CFM && hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
48202f3e254SJohan Hedberg 		method = JUST_WORKS;
48302f3e254SJohan Hedberg 
4842b64d153SBrian Gix 	/* If Just Works, Continue with Zero TK */
4852b64d153SBrian Gix 	if (method == JUST_WORKS) {
4864a74d658SJohan Hedberg 		set_bit(SMP_FLAG_TK_VALID, &smp->flags);
4872b64d153SBrian Gix 		return 0;
4882b64d153SBrian Gix 	}
4892b64d153SBrian Gix 
4902b64d153SBrian Gix 	/* Not Just Works/Confirm results in MITM Authentication */
4915eb596f5SJohan Hedberg 	if (method != JUST_CFM) {
4924a74d658SJohan Hedberg 		set_bit(SMP_FLAG_MITM_AUTH, &smp->flags);
4935eb596f5SJohan Hedberg 		if (hcon->pending_sec_level < BT_SECURITY_HIGH)
4945eb596f5SJohan Hedberg 			hcon->pending_sec_level = BT_SECURITY_HIGH;
4955eb596f5SJohan Hedberg 	}
4962b64d153SBrian Gix 
4972b64d153SBrian Gix 	/* If both devices have Keyoard-Display I/O, the master
4982b64d153SBrian Gix 	 * Confirms and the slave Enters the passkey.
4992b64d153SBrian Gix 	 */
5002b64d153SBrian Gix 	if (method == OVERLAP) {
50140bef302SJohan Hedberg 		if (hcon->role == HCI_ROLE_MASTER)
5022b64d153SBrian Gix 			method = CFM_PASSKEY;
5032b64d153SBrian Gix 		else
5042b64d153SBrian Gix 			method = REQ_PASSKEY;
5052b64d153SBrian Gix 	}
5062b64d153SBrian Gix 
50701ad34d2SJohan Hedberg 	/* Generate random passkey. */
5082b64d153SBrian Gix 	if (method == CFM_PASSKEY) {
509943a732aSJohan Hedberg 		memset(smp->tk, 0, sizeof(smp->tk));
5102b64d153SBrian Gix 		get_random_bytes(&passkey, sizeof(passkey));
5112b64d153SBrian Gix 		passkey %= 1000000;
512943a732aSJohan Hedberg 		put_unaligned_le32(passkey, smp->tk);
5132b64d153SBrian Gix 		BT_DBG("PassKey: %d", passkey);
5144a74d658SJohan Hedberg 		set_bit(SMP_FLAG_TK_VALID, &smp->flags);
5152b64d153SBrian Gix 	}
5162b64d153SBrian Gix 
5172b64d153SBrian Gix 	hci_dev_lock(hcon->hdev);
5182b64d153SBrian Gix 
5192b64d153SBrian Gix 	if (method == REQ_PASSKEY)
520ce39fb4eSMarcel Holtmann 		ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst,
521272d90dfSJohan Hedberg 						hcon->type, hcon->dst_type);
5224eb65e66SJohan Hedberg 	else if (method == JUST_CFM)
5234eb65e66SJohan Hedberg 		ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
5244eb65e66SJohan Hedberg 						hcon->type, hcon->dst_type,
5254eb65e66SJohan Hedberg 						passkey, 1);
5262b64d153SBrian Gix 	else
52701ad34d2SJohan Hedberg 		ret = mgmt_user_passkey_notify(hcon->hdev, &hcon->dst,
528272d90dfSJohan Hedberg 						hcon->type, hcon->dst_type,
52939adbffeSJohan Hedberg 						passkey, 0);
5302b64d153SBrian Gix 
5312b64d153SBrian Gix 	hci_dev_unlock(hcon->hdev);
5322b64d153SBrian Gix 
5332b64d153SBrian Gix 	return ret;
5342b64d153SBrian Gix }
5352b64d153SBrian Gix 
5361cc61144SJohan Hedberg static u8 smp_confirm(struct smp_chan *smp)
5378aab4757SVinicius Costa Gomes {
5388aab4757SVinicius Costa Gomes 	struct l2cap_conn *conn = smp->conn;
5398aab4757SVinicius Costa Gomes 	struct smp_cmd_pairing_confirm cp;
5408aab4757SVinicius Costa Gomes 	int ret;
5418aab4757SVinicius Costa Gomes 
5428aab4757SVinicius Costa Gomes 	BT_DBG("conn %p", conn);
5438aab4757SVinicius Costa Gomes 
544e491eaf3SJohan Hedberg 	ret = smp_c1(smp->tfm_aes, smp->tk, smp->prnd, smp->preq, smp->prsp,
545b1cd5fd9SJohan Hedberg 		     conn->hcon->init_addr_type, &conn->hcon->init_addr,
546943a732aSJohan Hedberg 		     conn->hcon->resp_addr_type, &conn->hcon->resp_addr,
547943a732aSJohan Hedberg 		     cp.confirm_val);
5481cc61144SJohan Hedberg 	if (ret)
5491cc61144SJohan Hedberg 		return SMP_UNSPECIFIED;
5508aab4757SVinicius Costa Gomes 
5514a74d658SJohan Hedberg 	clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
5522b64d153SBrian Gix 
5538aab4757SVinicius Costa Gomes 	smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
5548aab4757SVinicius Costa Gomes 
555b28b4943SJohan Hedberg 	if (conn->hcon->out)
556b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
557b28b4943SJohan Hedberg 	else
558b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
559b28b4943SJohan Hedberg 
5601cc61144SJohan Hedberg 	return 0;
5618aab4757SVinicius Costa Gomes }
5628aab4757SVinicius Costa Gomes 
563861580a9SJohan Hedberg static u8 smp_random(struct smp_chan *smp)
5648aab4757SVinicius Costa Gomes {
5658aab4757SVinicius Costa Gomes 	struct l2cap_conn *conn = smp->conn;
5668aab4757SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
567861580a9SJohan Hedberg 	u8 confirm[16];
5688aab4757SVinicius Costa Gomes 	int ret;
5698aab4757SVinicius Costa Gomes 
570ec70f36fSJohan Hedberg 	if (IS_ERR_OR_NULL(smp->tfm_aes))
571861580a9SJohan Hedberg 		return SMP_UNSPECIFIED;
5728aab4757SVinicius Costa Gomes 
5738aab4757SVinicius Costa Gomes 	BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
5748aab4757SVinicius Costa Gomes 
575e491eaf3SJohan Hedberg 	ret = smp_c1(smp->tfm_aes, smp->tk, smp->rrnd, smp->preq, smp->prsp,
576b1cd5fd9SJohan Hedberg 		     hcon->init_addr_type, &hcon->init_addr,
577943a732aSJohan Hedberg 		     hcon->resp_addr_type, &hcon->resp_addr, confirm);
578861580a9SJohan Hedberg 	if (ret)
579861580a9SJohan Hedberg 		return SMP_UNSPECIFIED;
5808aab4757SVinicius Costa Gomes 
5818aab4757SVinicius Costa Gomes 	if (memcmp(smp->pcnf, confirm, sizeof(smp->pcnf)) != 0) {
5828aab4757SVinicius Costa Gomes 		BT_ERR("Pairing failed (confirmation values mismatch)");
583861580a9SJohan Hedberg 		return SMP_CONFIRM_FAILED;
5848aab4757SVinicius Costa Gomes 	}
5858aab4757SVinicius Costa Gomes 
5868aab4757SVinicius Costa Gomes 	if (hcon->out) {
587fe39c7b2SMarcel Holtmann 		u8 stk[16];
588fe39c7b2SMarcel Holtmann 		__le64 rand = 0;
589fe39c7b2SMarcel Holtmann 		__le16 ediv = 0;
5908aab4757SVinicius Costa Gomes 
591e491eaf3SJohan Hedberg 		smp_s1(smp->tfm_aes, smp->tk, smp->rrnd, smp->prnd, stk);
5928aab4757SVinicius Costa Gomes 
593f7aa611aSVinicius Costa Gomes 		memset(stk + smp->enc_key_size, 0,
594f7aa611aSVinicius Costa Gomes 		       SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
5958aab4757SVinicius Costa Gomes 
596861580a9SJohan Hedberg 		if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
597861580a9SJohan Hedberg 			return SMP_UNSPECIFIED;
5988aab4757SVinicius Costa Gomes 
5998aab4757SVinicius Costa Gomes 		hci_le_start_enc(hcon, ediv, rand, stk);
600f7aa611aSVinicius Costa Gomes 		hcon->enc_key_size = smp->enc_key_size;
601fe59a05fSJohan Hedberg 		set_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags);
6028aab4757SVinicius Costa Gomes 	} else {
603fff3490fSJohan Hedberg 		u8 stk[16], auth;
604fe39c7b2SMarcel Holtmann 		__le64 rand = 0;
605fe39c7b2SMarcel Holtmann 		__le16 ediv = 0;
6068aab4757SVinicius Costa Gomes 
607943a732aSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
608943a732aSJohan Hedberg 			     smp->prnd);
6098aab4757SVinicius Costa Gomes 
610e491eaf3SJohan Hedberg 		smp_s1(smp->tfm_aes, smp->tk, smp->prnd, smp->rrnd, stk);
6118aab4757SVinicius Costa Gomes 
612f7aa611aSVinicius Costa Gomes 		memset(stk + smp->enc_key_size, 0,
613f7aa611aSVinicius Costa Gomes 		       SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
6148aab4757SVinicius Costa Gomes 
615fff3490fSJohan Hedberg 		if (hcon->pending_sec_level == BT_SECURITY_HIGH)
616fff3490fSJohan Hedberg 			auth = 1;
617fff3490fSJohan Hedberg 		else
618fff3490fSJohan Hedberg 			auth = 0;
619fff3490fSJohan Hedberg 
6207d5843b7SJohan Hedberg 		/* Even though there's no _SLAVE suffix this is the
6217d5843b7SJohan Hedberg 		 * slave STK we're adding for later lookup (the master
6227d5843b7SJohan Hedberg 		 * STK never needs to be stored).
6237d5843b7SJohan Hedberg 		 */
624ce39fb4eSMarcel Holtmann 		hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
6252ceba539SJohan Hedberg 			    SMP_STK, auth, stk, smp->enc_key_size, ediv, rand);
6268aab4757SVinicius Costa Gomes 	}
6278aab4757SVinicius Costa Gomes 
628861580a9SJohan Hedberg 	return 0;
6298aab4757SVinicius Costa Gomes }
6308aab4757SVinicius Costa Gomes 
63144f1a7abSJohan Hedberg static void smp_notify_keys(struct l2cap_conn *conn)
63244f1a7abSJohan Hedberg {
63344f1a7abSJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
63444f1a7abSJohan Hedberg 	struct smp_chan *smp = chan->data;
63544f1a7abSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
63644f1a7abSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
63744f1a7abSJohan Hedberg 	struct smp_cmd_pairing *req = (void *) &smp->preq[1];
63844f1a7abSJohan Hedberg 	struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1];
63944f1a7abSJohan Hedberg 	bool persistent;
64044f1a7abSJohan Hedberg 
64144f1a7abSJohan Hedberg 	if (smp->remote_irk) {
64244f1a7abSJohan Hedberg 		mgmt_new_irk(hdev, smp->remote_irk);
64344f1a7abSJohan Hedberg 		/* Now that user space can be considered to know the
64444f1a7abSJohan Hedberg 		 * identity address track the connection based on it
64544f1a7abSJohan Hedberg 		 * from now on.
64644f1a7abSJohan Hedberg 		 */
64744f1a7abSJohan Hedberg 		bacpy(&hcon->dst, &smp->remote_irk->bdaddr);
64844f1a7abSJohan Hedberg 		hcon->dst_type = smp->remote_irk->addr_type;
649f3d82d0cSJohan Hedberg 		queue_work(hdev->workqueue, &conn->id_addr_update_work);
65044f1a7abSJohan Hedberg 
65144f1a7abSJohan Hedberg 		/* When receiving an indentity resolving key for
65244f1a7abSJohan Hedberg 		 * a remote device that does not use a resolvable
65344f1a7abSJohan Hedberg 		 * private address, just remove the key so that
65444f1a7abSJohan Hedberg 		 * it is possible to use the controller white
65544f1a7abSJohan Hedberg 		 * list for scanning.
65644f1a7abSJohan Hedberg 		 *
65744f1a7abSJohan Hedberg 		 * Userspace will have been told to not store
65844f1a7abSJohan Hedberg 		 * this key at this point. So it is safe to
65944f1a7abSJohan Hedberg 		 * just remove it.
66044f1a7abSJohan Hedberg 		 */
66144f1a7abSJohan Hedberg 		if (!bacmp(&smp->remote_irk->rpa, BDADDR_ANY)) {
66244f1a7abSJohan Hedberg 			list_del(&smp->remote_irk->list);
66344f1a7abSJohan Hedberg 			kfree(smp->remote_irk);
66444f1a7abSJohan Hedberg 			smp->remote_irk = NULL;
66544f1a7abSJohan Hedberg 		}
66644f1a7abSJohan Hedberg 	}
66744f1a7abSJohan Hedberg 
66844f1a7abSJohan Hedberg 	/* The LTKs and CSRKs should be persistent only if both sides
66944f1a7abSJohan Hedberg 	 * had the bonding bit set in their authentication requests.
67044f1a7abSJohan Hedberg 	 */
67144f1a7abSJohan Hedberg 	persistent = !!((req->auth_req & rsp->auth_req) & SMP_AUTH_BONDING);
67244f1a7abSJohan Hedberg 
67344f1a7abSJohan Hedberg 	if (smp->csrk) {
67444f1a7abSJohan Hedberg 		smp->csrk->bdaddr_type = hcon->dst_type;
67544f1a7abSJohan Hedberg 		bacpy(&smp->csrk->bdaddr, &hcon->dst);
67644f1a7abSJohan Hedberg 		mgmt_new_csrk(hdev, smp->csrk, persistent);
67744f1a7abSJohan Hedberg 	}
67844f1a7abSJohan Hedberg 
67944f1a7abSJohan Hedberg 	if (smp->slave_csrk) {
68044f1a7abSJohan Hedberg 		smp->slave_csrk->bdaddr_type = hcon->dst_type;
68144f1a7abSJohan Hedberg 		bacpy(&smp->slave_csrk->bdaddr, &hcon->dst);
68244f1a7abSJohan Hedberg 		mgmt_new_csrk(hdev, smp->slave_csrk, persistent);
68344f1a7abSJohan Hedberg 	}
68444f1a7abSJohan Hedberg 
68544f1a7abSJohan Hedberg 	if (smp->ltk) {
68644f1a7abSJohan Hedberg 		smp->ltk->bdaddr_type = hcon->dst_type;
68744f1a7abSJohan Hedberg 		bacpy(&smp->ltk->bdaddr, &hcon->dst);
68844f1a7abSJohan Hedberg 		mgmt_new_ltk(hdev, smp->ltk, persistent);
68944f1a7abSJohan Hedberg 	}
69044f1a7abSJohan Hedberg 
69144f1a7abSJohan Hedberg 	if (smp->slave_ltk) {
69244f1a7abSJohan Hedberg 		smp->slave_ltk->bdaddr_type = hcon->dst_type;
69344f1a7abSJohan Hedberg 		bacpy(&smp->slave_ltk->bdaddr, &hcon->dst);
69444f1a7abSJohan Hedberg 		mgmt_new_ltk(hdev, smp->slave_ltk, persistent);
69544f1a7abSJohan Hedberg 	}
69644f1a7abSJohan Hedberg }
69744f1a7abSJohan Hedberg 
698b28b4943SJohan Hedberg static void smp_allow_key_dist(struct smp_chan *smp)
699b28b4943SJohan Hedberg {
700b28b4943SJohan Hedberg 	/* Allow the first expected phase 3 PDU. The rest of the PDUs
701b28b4943SJohan Hedberg 	 * will be allowed in each PDU handler to ensure we receive
702b28b4943SJohan Hedberg 	 * them in the correct order.
703b28b4943SJohan Hedberg 	 */
704b28b4943SJohan Hedberg 	if (smp->remote_key_dist & SMP_DIST_ENC_KEY)
705b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_ENCRYPT_INFO);
706b28b4943SJohan Hedberg 	else if (smp->remote_key_dist & SMP_DIST_ID_KEY)
707b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO);
708b28b4943SJohan Hedberg 	else if (smp->remote_key_dist & SMP_DIST_SIGN)
709b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO);
710b28b4943SJohan Hedberg }
711b28b4943SJohan Hedberg 
712d6268e86SJohan Hedberg static void smp_distribute_keys(struct smp_chan *smp)
71344f1a7abSJohan Hedberg {
71444f1a7abSJohan Hedberg 	struct smp_cmd_pairing *req, *rsp;
71586d1407cSJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
71644f1a7abSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
71744f1a7abSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
71844f1a7abSJohan Hedberg 	__u8 *keydist;
71944f1a7abSJohan Hedberg 
72044f1a7abSJohan Hedberg 	BT_DBG("conn %p", conn);
72144f1a7abSJohan Hedberg 
72244f1a7abSJohan Hedberg 	rsp = (void *) &smp->prsp[1];
72344f1a7abSJohan Hedberg 
72444f1a7abSJohan Hedberg 	/* The responder sends its keys first */
725b28b4943SJohan Hedberg 	if (hcon->out && (smp->remote_key_dist & KEY_DIST_MASK)) {
726b28b4943SJohan Hedberg 		smp_allow_key_dist(smp);
72786d1407cSJohan Hedberg 		return;
728b28b4943SJohan Hedberg 	}
72944f1a7abSJohan Hedberg 
73044f1a7abSJohan Hedberg 	req = (void *) &smp->preq[1];
73144f1a7abSJohan Hedberg 
73244f1a7abSJohan Hedberg 	if (hcon->out) {
73344f1a7abSJohan Hedberg 		keydist = &rsp->init_key_dist;
73444f1a7abSJohan Hedberg 		*keydist &= req->init_key_dist;
73544f1a7abSJohan Hedberg 	} else {
73644f1a7abSJohan Hedberg 		keydist = &rsp->resp_key_dist;
73744f1a7abSJohan Hedberg 		*keydist &= req->resp_key_dist;
73844f1a7abSJohan Hedberg 	}
73944f1a7abSJohan Hedberg 
74044f1a7abSJohan Hedberg 	BT_DBG("keydist 0x%x", *keydist);
74144f1a7abSJohan Hedberg 
74244f1a7abSJohan Hedberg 	if (*keydist & SMP_DIST_ENC_KEY) {
74344f1a7abSJohan Hedberg 		struct smp_cmd_encrypt_info enc;
74444f1a7abSJohan Hedberg 		struct smp_cmd_master_ident ident;
74544f1a7abSJohan Hedberg 		struct smp_ltk *ltk;
74644f1a7abSJohan Hedberg 		u8 authenticated;
74744f1a7abSJohan Hedberg 		__le16 ediv;
74844f1a7abSJohan Hedberg 		__le64 rand;
74944f1a7abSJohan Hedberg 
75044f1a7abSJohan Hedberg 		get_random_bytes(enc.ltk, sizeof(enc.ltk));
75144f1a7abSJohan Hedberg 		get_random_bytes(&ediv, sizeof(ediv));
75244f1a7abSJohan Hedberg 		get_random_bytes(&rand, sizeof(rand));
75344f1a7abSJohan Hedberg 
75444f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
75544f1a7abSJohan Hedberg 
75644f1a7abSJohan Hedberg 		authenticated = hcon->sec_level == BT_SECURITY_HIGH;
75744f1a7abSJohan Hedberg 		ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type,
75844f1a7abSJohan Hedberg 				  SMP_LTK_SLAVE, authenticated, enc.ltk,
75944f1a7abSJohan Hedberg 				  smp->enc_key_size, ediv, rand);
76044f1a7abSJohan Hedberg 		smp->slave_ltk = ltk;
76144f1a7abSJohan Hedberg 
76244f1a7abSJohan Hedberg 		ident.ediv = ediv;
76344f1a7abSJohan Hedberg 		ident.rand = rand;
76444f1a7abSJohan Hedberg 
76544f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident);
76644f1a7abSJohan Hedberg 
76744f1a7abSJohan Hedberg 		*keydist &= ~SMP_DIST_ENC_KEY;
76844f1a7abSJohan Hedberg 	}
76944f1a7abSJohan Hedberg 
77044f1a7abSJohan Hedberg 	if (*keydist & SMP_DIST_ID_KEY) {
77144f1a7abSJohan Hedberg 		struct smp_cmd_ident_addr_info addrinfo;
77244f1a7abSJohan Hedberg 		struct smp_cmd_ident_info idinfo;
77344f1a7abSJohan Hedberg 
77444f1a7abSJohan Hedberg 		memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk));
77544f1a7abSJohan Hedberg 
77644f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo);
77744f1a7abSJohan Hedberg 
77844f1a7abSJohan Hedberg 		/* The hci_conn contains the local identity address
77944f1a7abSJohan Hedberg 		 * after the connection has been established.
78044f1a7abSJohan Hedberg 		 *
78144f1a7abSJohan Hedberg 		 * This is true even when the connection has been
78244f1a7abSJohan Hedberg 		 * established using a resolvable random address.
78344f1a7abSJohan Hedberg 		 */
78444f1a7abSJohan Hedberg 		bacpy(&addrinfo.bdaddr, &hcon->src);
78544f1a7abSJohan Hedberg 		addrinfo.addr_type = hcon->src_type;
78644f1a7abSJohan Hedberg 
78744f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo),
78844f1a7abSJohan Hedberg 			     &addrinfo);
78944f1a7abSJohan Hedberg 
79044f1a7abSJohan Hedberg 		*keydist &= ~SMP_DIST_ID_KEY;
79144f1a7abSJohan Hedberg 	}
79244f1a7abSJohan Hedberg 
79344f1a7abSJohan Hedberg 	if (*keydist & SMP_DIST_SIGN) {
79444f1a7abSJohan Hedberg 		struct smp_cmd_sign_info sign;
79544f1a7abSJohan Hedberg 		struct smp_csrk *csrk;
79644f1a7abSJohan Hedberg 
79744f1a7abSJohan Hedberg 		/* Generate a new random key */
79844f1a7abSJohan Hedberg 		get_random_bytes(sign.csrk, sizeof(sign.csrk));
79944f1a7abSJohan Hedberg 
80044f1a7abSJohan Hedberg 		csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
80144f1a7abSJohan Hedberg 		if (csrk) {
80244f1a7abSJohan Hedberg 			csrk->master = 0x00;
80344f1a7abSJohan Hedberg 			memcpy(csrk->val, sign.csrk, sizeof(csrk->val));
80444f1a7abSJohan Hedberg 		}
80544f1a7abSJohan Hedberg 		smp->slave_csrk = csrk;
80644f1a7abSJohan Hedberg 
80744f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign);
80844f1a7abSJohan Hedberg 
80944f1a7abSJohan Hedberg 		*keydist &= ~SMP_DIST_SIGN;
81044f1a7abSJohan Hedberg 	}
81144f1a7abSJohan Hedberg 
81244f1a7abSJohan Hedberg 	/* If there are still keys to be received wait for them */
813b28b4943SJohan Hedberg 	if (smp->remote_key_dist & KEY_DIST_MASK) {
814b28b4943SJohan Hedberg 		smp_allow_key_dist(smp);
81586d1407cSJohan Hedberg 		return;
816b28b4943SJohan Hedberg 	}
81744f1a7abSJohan Hedberg 
81844f1a7abSJohan Hedberg 	set_bit(SMP_FLAG_COMPLETE, &smp->flags);
81944f1a7abSJohan Hedberg 	smp_notify_keys(conn);
82044f1a7abSJohan Hedberg 
82144f1a7abSJohan Hedberg 	smp_chan_destroy(conn);
82244f1a7abSJohan Hedberg }
82344f1a7abSJohan Hedberg 
824b68fda68SJohan Hedberg static void smp_timeout(struct work_struct *work)
825b68fda68SJohan Hedberg {
826b68fda68SJohan Hedberg 	struct smp_chan *smp = container_of(work, struct smp_chan,
827b68fda68SJohan Hedberg 					    security_timer.work);
828b68fda68SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
829b68fda68SJohan Hedberg 
830b68fda68SJohan Hedberg 	BT_DBG("conn %p", conn);
831b68fda68SJohan Hedberg 
8321e91c29eSJohan Hedberg 	hci_disconnect(conn->hcon, HCI_ERROR_REMOTE_USER_TERM);
833b68fda68SJohan Hedberg }
834b68fda68SJohan Hedberg 
8358aab4757SVinicius Costa Gomes static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
8368aab4757SVinicius Costa Gomes {
8375d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
8388aab4757SVinicius Costa Gomes 	struct smp_chan *smp;
8398aab4757SVinicius Costa Gomes 
840f1560463SMarcel Holtmann 	smp = kzalloc(sizeof(*smp), GFP_ATOMIC);
841fc75cc86SJohan Hedberg 	if (!smp)
8428aab4757SVinicius Costa Gomes 		return NULL;
8438aab4757SVinicius Costa Gomes 
8446a7bd103SJohan Hedberg 	smp->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
8456a7bd103SJohan Hedberg 	if (IS_ERR(smp->tfm_aes)) {
8466a7bd103SJohan Hedberg 		BT_ERR("Unable to create ECB crypto context");
8476a7bd103SJohan Hedberg 		kfree(smp);
8486a7bd103SJohan Hedberg 		return NULL;
8496a7bd103SJohan Hedberg 	}
8506a7bd103SJohan Hedberg 
8518aab4757SVinicius Costa Gomes 	smp->conn = conn;
8525d88cc73SJohan Hedberg 	chan->data = smp;
8538aab4757SVinicius Costa Gomes 
854b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_FAIL);
855b28b4943SJohan Hedberg 
856b68fda68SJohan Hedberg 	INIT_DELAYED_WORK(&smp->security_timer, smp_timeout);
857b68fda68SJohan Hedberg 
8588aab4757SVinicius Costa Gomes 	hci_conn_hold(conn->hcon);
8598aab4757SVinicius Costa Gomes 
8608aab4757SVinicius Costa Gomes 	return smp;
8618aab4757SVinicius Costa Gomes }
8628aab4757SVinicius Costa Gomes 
8632b64d153SBrian Gix int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
8642b64d153SBrian Gix {
865b10e8017SJohan Hedberg 	struct l2cap_conn *conn = hcon->l2cap_data;
8665d88cc73SJohan Hedberg 	struct l2cap_chan *chan;
8672b64d153SBrian Gix 	struct smp_chan *smp;
8682b64d153SBrian Gix 	u32 value;
869fc75cc86SJohan Hedberg 	int err;
8702b64d153SBrian Gix 
8712b64d153SBrian Gix 	BT_DBG("");
8722b64d153SBrian Gix 
873fc75cc86SJohan Hedberg 	if (!conn)
8742b64d153SBrian Gix 		return -ENOTCONN;
8752b64d153SBrian Gix 
8765d88cc73SJohan Hedberg 	chan = conn->smp;
8775d88cc73SJohan Hedberg 	if (!chan)
8785d88cc73SJohan Hedberg 		return -ENOTCONN;
8795d88cc73SJohan Hedberg 
880fc75cc86SJohan Hedberg 	l2cap_chan_lock(chan);
881fc75cc86SJohan Hedberg 	if (!chan->data) {
882fc75cc86SJohan Hedberg 		err = -ENOTCONN;
883fc75cc86SJohan Hedberg 		goto unlock;
884fc75cc86SJohan Hedberg 	}
885fc75cc86SJohan Hedberg 
8865d88cc73SJohan Hedberg 	smp = chan->data;
8872b64d153SBrian Gix 
8882b64d153SBrian Gix 	switch (mgmt_op) {
8892b64d153SBrian Gix 	case MGMT_OP_USER_PASSKEY_REPLY:
8902b64d153SBrian Gix 		value = le32_to_cpu(passkey);
891943a732aSJohan Hedberg 		memset(smp->tk, 0, sizeof(smp->tk));
8922b64d153SBrian Gix 		BT_DBG("PassKey: %d", value);
893943a732aSJohan Hedberg 		put_unaligned_le32(value, smp->tk);
8942b64d153SBrian Gix 		/* Fall Through */
8952b64d153SBrian Gix 	case MGMT_OP_USER_CONFIRM_REPLY:
8964a74d658SJohan Hedberg 		set_bit(SMP_FLAG_TK_VALID, &smp->flags);
8972b64d153SBrian Gix 		break;
8982b64d153SBrian Gix 	case MGMT_OP_USER_PASSKEY_NEG_REPLY:
8992b64d153SBrian Gix 	case MGMT_OP_USER_CONFIRM_NEG_REPLY:
90084794e11SJohan Hedberg 		smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
901fc75cc86SJohan Hedberg 		err = 0;
902fc75cc86SJohan Hedberg 		goto unlock;
9032b64d153SBrian Gix 	default:
90484794e11SJohan Hedberg 		smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
905fc75cc86SJohan Hedberg 		err = -EOPNOTSUPP;
906fc75cc86SJohan Hedberg 		goto unlock;
9072b64d153SBrian Gix 	}
9082b64d153SBrian Gix 
909fc75cc86SJohan Hedberg 	err = 0;
910fc75cc86SJohan Hedberg 
9112b64d153SBrian Gix 	/* If it is our turn to send Pairing Confirm, do so now */
9121cc61144SJohan Hedberg 	if (test_bit(SMP_FLAG_CFM_PENDING, &smp->flags)) {
9131cc61144SJohan Hedberg 		u8 rsp = smp_confirm(smp);
9141cc61144SJohan Hedberg 		if (rsp)
9151cc61144SJohan Hedberg 			smp_failure(conn, rsp);
9161cc61144SJohan Hedberg 	}
9172b64d153SBrian Gix 
918fc75cc86SJohan Hedberg unlock:
919fc75cc86SJohan Hedberg 	l2cap_chan_unlock(chan);
920fc75cc86SJohan Hedberg 	return err;
9212b64d153SBrian Gix }
9222b64d153SBrian Gix 
923da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
92488ba43b6SAnderson Briglia {
9253158c50cSVinicius Costa Gomes 	struct smp_cmd_pairing rsp, *req = (void *) skb->data;
926fc75cc86SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
927b3c6410bSJohan Hedberg 	struct hci_dev *hdev = conn->hcon->hdev;
9288aab4757SVinicius Costa Gomes 	struct smp_chan *smp;
929c7262e71SJohan Hedberg 	u8 key_size, auth, sec_level;
9308aab4757SVinicius Costa Gomes 	int ret;
93188ba43b6SAnderson Briglia 
93288ba43b6SAnderson Briglia 	BT_DBG("conn %p", conn);
93388ba43b6SAnderson Briglia 
934c46b98beSJohan Hedberg 	if (skb->len < sizeof(*req))
93538e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
936c46b98beSJohan Hedberg 
93740bef302SJohan Hedberg 	if (conn->hcon->role != HCI_ROLE_SLAVE)
9382b64d153SBrian Gix 		return SMP_CMD_NOTSUPP;
9392b64d153SBrian Gix 
940fc75cc86SJohan Hedberg 	if (!chan->data)
9418aab4757SVinicius Costa Gomes 		smp = smp_chan_create(conn);
942fc75cc86SJohan Hedberg 	else
9435d88cc73SJohan Hedberg 		smp = chan->data;
944d26a2345SVinicius Costa Gomes 
945d08fd0e7SAndrei Emeltchenko 	if (!smp)
946d08fd0e7SAndrei Emeltchenko 		return SMP_UNSPECIFIED;
947d08fd0e7SAndrei Emeltchenko 
948c05b9339SJohan Hedberg 	/* We didn't start the pairing, so match remote */
949c05b9339SJohan Hedberg 	auth = req->auth_req & AUTH_REQ_MASK;
950c05b9339SJohan Hedberg 
951b6ae8457SJohan Hedberg 	if (!test_bit(HCI_BONDABLE, &hdev->dev_flags) &&
952c05b9339SJohan Hedberg 	    (auth & SMP_AUTH_BONDING))
953b3c6410bSJohan Hedberg 		return SMP_PAIRING_NOTSUPP;
954b3c6410bSJohan Hedberg 
9551c1def09SVinicius Costa Gomes 	smp->preq[0] = SMP_CMD_PAIRING_REQ;
9561c1def09SVinicius Costa Gomes 	memcpy(&smp->preq[1], req, sizeof(*req));
9573158c50cSVinicius Costa Gomes 	skb_pull(skb, sizeof(*req));
95888ba43b6SAnderson Briglia 
9595be5e275SJohan Hedberg 	if (conn->hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
9601afc2a1aSJohan Hedberg 		sec_level = BT_SECURITY_MEDIUM;
9611afc2a1aSJohan Hedberg 	else
962c7262e71SJohan Hedberg 		sec_level = authreq_to_seclevel(auth);
9631afc2a1aSJohan Hedberg 
964c7262e71SJohan Hedberg 	if (sec_level > conn->hcon->pending_sec_level)
965c7262e71SJohan Hedberg 		conn->hcon->pending_sec_level = sec_level;
966fdde0a26SIdo Yariv 
9672ed8f65cSJohan Hedberg 	/* If we need MITM check that it can be acheived */
9682ed8f65cSJohan Hedberg 	if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
9692ed8f65cSJohan Hedberg 		u8 method;
9702ed8f65cSJohan Hedberg 
9712ed8f65cSJohan Hedberg 		method = get_auth_method(smp, conn->hcon->io_capability,
9722ed8f65cSJohan Hedberg 					 req->io_capability);
9732ed8f65cSJohan Hedberg 		if (method == JUST_WORKS || method == JUST_CFM)
9742ed8f65cSJohan Hedberg 			return SMP_AUTH_REQUIREMENTS;
9752ed8f65cSJohan Hedberg 	}
9762ed8f65cSJohan Hedberg 
9772b64d153SBrian Gix 	build_pairing_cmd(conn, req, &rsp, auth);
9783158c50cSVinicius Costa Gomes 
9793158c50cSVinicius Costa Gomes 	key_size = min(req->max_key_size, rsp.max_key_size);
9803158c50cSVinicius Costa Gomes 	if (check_enc_key_size(conn, key_size))
9813158c50cSVinicius Costa Gomes 		return SMP_ENC_KEY_SIZE;
98288ba43b6SAnderson Briglia 
983e84a6b13SJohan Hedberg 	get_random_bytes(smp->prnd, sizeof(smp->prnd));
9848aab4757SVinicius Costa Gomes 
9851c1def09SVinicius Costa Gomes 	smp->prsp[0] = SMP_CMD_PAIRING_RSP;
9861c1def09SVinicius Costa Gomes 	memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
987f01ead31SAnderson Briglia 
9883158c50cSVinicius Costa Gomes 	smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
989b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
990da85e5e5SVinicius Costa Gomes 
9912b64d153SBrian Gix 	/* Request setup of TK */
9922b64d153SBrian Gix 	ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability);
9932b64d153SBrian Gix 	if (ret)
9942b64d153SBrian Gix 		return SMP_UNSPECIFIED;
9952b64d153SBrian Gix 
996da85e5e5SVinicius Costa Gomes 	return 0;
99788ba43b6SAnderson Briglia }
99888ba43b6SAnderson Briglia 
999da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
100088ba43b6SAnderson Briglia {
10013158c50cSVinicius Costa Gomes 	struct smp_cmd_pairing *req, *rsp = (void *) skb->data;
10025d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
10035d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
10043a7dbfb8SJohan Hedberg 	u8 key_size, auth;
10057d24ddccSAnderson Briglia 	int ret;
100688ba43b6SAnderson Briglia 
100788ba43b6SAnderson Briglia 	BT_DBG("conn %p", conn);
100888ba43b6SAnderson Briglia 
1009c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rsp))
101038e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1011c46b98beSJohan Hedberg 
101240bef302SJohan Hedberg 	if (conn->hcon->role != HCI_ROLE_MASTER)
10132b64d153SBrian Gix 		return SMP_CMD_NOTSUPP;
10142b64d153SBrian Gix 
10153158c50cSVinicius Costa Gomes 	skb_pull(skb, sizeof(*rsp));
1016da85e5e5SVinicius Costa Gomes 
10171c1def09SVinicius Costa Gomes 	req = (void *) &smp->preq[1];
10183158c50cSVinicius Costa Gomes 
10193158c50cSVinicius Costa Gomes 	key_size = min(req->max_key_size, rsp->max_key_size);
10203158c50cSVinicius Costa Gomes 	if (check_enc_key_size(conn, key_size))
10213158c50cSVinicius Costa Gomes 		return SMP_ENC_KEY_SIZE;
10223158c50cSVinicius Costa Gomes 
1023c05b9339SJohan Hedberg 	auth = rsp->auth_req & AUTH_REQ_MASK;
1024c05b9339SJohan Hedberg 
10252ed8f65cSJohan Hedberg 	/* If we need MITM check that it can be acheived */
10262ed8f65cSJohan Hedberg 	if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
10272ed8f65cSJohan Hedberg 		u8 method;
10282ed8f65cSJohan Hedberg 
10292ed8f65cSJohan Hedberg 		method = get_auth_method(smp, req->io_capability,
10302ed8f65cSJohan Hedberg 					 rsp->io_capability);
10312ed8f65cSJohan Hedberg 		if (method == JUST_WORKS || method == JUST_CFM)
10322ed8f65cSJohan Hedberg 			return SMP_AUTH_REQUIREMENTS;
10332ed8f65cSJohan Hedberg 	}
10342ed8f65cSJohan Hedberg 
1035e84a6b13SJohan Hedberg 	get_random_bytes(smp->prnd, sizeof(smp->prnd));
10367d24ddccSAnderson Briglia 
10378aab4757SVinicius Costa Gomes 	smp->prsp[0] = SMP_CMD_PAIRING_RSP;
10388aab4757SVinicius Costa Gomes 	memcpy(&smp->prsp[1], rsp, sizeof(*rsp));
10397d24ddccSAnderson Briglia 
1040fdcc4becSJohan Hedberg 	/* Update remote key distribution in case the remote cleared
1041fdcc4becSJohan Hedberg 	 * some bits that we had enabled in our request.
1042fdcc4becSJohan Hedberg 	 */
1043fdcc4becSJohan Hedberg 	smp->remote_key_dist &= rsp->resp_key_dist;
1044fdcc4becSJohan Hedberg 
1045c05b9339SJohan Hedberg 	auth |= req->auth_req;
10462b64d153SBrian Gix 
1047476585ecSJohan Hedberg 	ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability);
10482b64d153SBrian Gix 	if (ret)
10492b64d153SBrian Gix 		return SMP_UNSPECIFIED;
10502b64d153SBrian Gix 
10514a74d658SJohan Hedberg 	set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
10522b64d153SBrian Gix 
10532b64d153SBrian Gix 	/* Can't compose response until we have been confirmed */
10544a74d658SJohan Hedberg 	if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
10551cc61144SJohan Hedberg 		return smp_confirm(smp);
1056da85e5e5SVinicius Costa Gomes 
1057da85e5e5SVinicius Costa Gomes 	return 0;
105888ba43b6SAnderson Briglia }
105988ba43b6SAnderson Briglia 
1060da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
106188ba43b6SAnderson Briglia {
10625d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
10635d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
10647d24ddccSAnderson Briglia 
106588ba43b6SAnderson Briglia 	BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
106688ba43b6SAnderson Briglia 
1067c46b98beSJohan Hedberg 	if (skb->len < sizeof(smp->pcnf))
106838e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1069c46b98beSJohan Hedberg 
10701c1def09SVinicius Costa Gomes 	memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf));
10711c1def09SVinicius Costa Gomes 	skb_pull(skb, sizeof(smp->pcnf));
10727d24ddccSAnderson Briglia 
1073b28b4943SJohan Hedberg 	if (conn->hcon->out) {
1074943a732aSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
1075943a732aSJohan Hedberg 			     smp->prnd);
1076b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
1077b28b4943SJohan Hedberg 		return 0;
1078b28b4943SJohan Hedberg 	}
1079b28b4943SJohan Hedberg 
1080b28b4943SJohan Hedberg 	if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
10811cc61144SJohan Hedberg 		return smp_confirm(smp);
1082943a732aSJohan Hedberg 	else
10834a74d658SJohan Hedberg 		set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
1084da85e5e5SVinicius Costa Gomes 
1085da85e5e5SVinicius Costa Gomes 	return 0;
108688ba43b6SAnderson Briglia }
108788ba43b6SAnderson Briglia 
1088da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
108988ba43b6SAnderson Briglia {
10905d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
10915d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
10927d24ddccSAnderson Briglia 
10938aab4757SVinicius Costa Gomes 	BT_DBG("conn %p", conn);
10947d24ddccSAnderson Briglia 
1095c46b98beSJohan Hedberg 	if (skb->len < sizeof(smp->rrnd))
109638e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1097c46b98beSJohan Hedberg 
1098943a732aSJohan Hedberg 	memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd));
10998aab4757SVinicius Costa Gomes 	skb_pull(skb, sizeof(smp->rrnd));
110088ba43b6SAnderson Briglia 
1101861580a9SJohan Hedberg 	return smp_random(smp);
110288ba43b6SAnderson Briglia }
110388ba43b6SAnderson Briglia 
1104f81cd823SMarcel Holtmann static bool smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
1105988c5997SVinicius Costa Gomes {
1106c9839a11SVinicius Costa Gomes 	struct smp_ltk *key;
1107988c5997SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
1108988c5997SVinicius Costa Gomes 
110998a0b845SJohan Hedberg 	key = hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type,
1110e804d25dSJohan Hedberg 				   hcon->role);
1111988c5997SVinicius Costa Gomes 	if (!key)
1112f81cd823SMarcel Holtmann 		return false;
1113988c5997SVinicius Costa Gomes 
1114a6f7833cSJohan Hedberg 	if (smp_ltk_sec_level(key) < sec_level)
1115f81cd823SMarcel Holtmann 		return false;
11164dab7864SJohan Hedberg 
111751a8efd7SJohan Hedberg 	if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
1118f81cd823SMarcel Holtmann 		return true;
1119988c5997SVinicius Costa Gomes 
1120c9839a11SVinicius Costa Gomes 	hci_le_start_enc(hcon, key->ediv, key->rand, key->val);
1121c9839a11SVinicius Costa Gomes 	hcon->enc_key_size = key->enc_size;
1122988c5997SVinicius Costa Gomes 
1123fe59a05fSJohan Hedberg 	/* We never store STKs for master role, so clear this flag */
1124fe59a05fSJohan Hedberg 	clear_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags);
1125fe59a05fSJohan Hedberg 
1126f81cd823SMarcel Holtmann 	return true;
1127988c5997SVinicius Costa Gomes }
1128f1560463SMarcel Holtmann 
1129854f4727SJohan Hedberg bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level)
1130854f4727SJohan Hedberg {
1131854f4727SJohan Hedberg 	if (sec_level == BT_SECURITY_LOW)
1132854f4727SJohan Hedberg 		return true;
1133854f4727SJohan Hedberg 
11349ab65d60SJohan Hedberg 	/* If we're encrypted with an STK always claim insufficient
11359ab65d60SJohan Hedberg 	 * security. This way we allow the connection to be re-encrypted
11369ab65d60SJohan Hedberg 	 * with an LTK, even if the LTK provides the same level of
1137b2d5e254SJohan Hedberg 	 * security. Only exception is if we don't have an LTK (e.g.
1138b2d5e254SJohan Hedberg 	 * because of key distribution bits).
11399ab65d60SJohan Hedberg 	 */
1140b2d5e254SJohan Hedberg 	if (test_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags) &&
1141b2d5e254SJohan Hedberg 	    hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type,
1142e804d25dSJohan Hedberg 				 hcon->role))
11439ab65d60SJohan Hedberg 		return false;
11449ab65d60SJohan Hedberg 
1145854f4727SJohan Hedberg 	if (hcon->sec_level >= sec_level)
1146854f4727SJohan Hedberg 		return true;
1147854f4727SJohan Hedberg 
1148854f4727SJohan Hedberg 	return false;
1149854f4727SJohan Hedberg }
1150854f4727SJohan Hedberg 
1151da85e5e5SVinicius Costa Gomes static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
115288ba43b6SAnderson Briglia {
115388ba43b6SAnderson Briglia 	struct smp_cmd_security_req *rp = (void *) skb->data;
115488ba43b6SAnderson Briglia 	struct smp_cmd_pairing cp;
1155f1cb9af5SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
11568aab4757SVinicius Costa Gomes 	struct smp_chan *smp;
1157c05b9339SJohan Hedberg 	u8 sec_level, auth;
115888ba43b6SAnderson Briglia 
115988ba43b6SAnderson Briglia 	BT_DBG("conn %p", conn);
116088ba43b6SAnderson Briglia 
1161c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rp))
116238e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1163c46b98beSJohan Hedberg 
116440bef302SJohan Hedberg 	if (hcon->role != HCI_ROLE_MASTER)
116586ca9eacSJohan Hedberg 		return SMP_CMD_NOTSUPP;
116686ca9eacSJohan Hedberg 
1167c05b9339SJohan Hedberg 	auth = rp->auth_req & AUTH_REQ_MASK;
1168c05b9339SJohan Hedberg 
11695be5e275SJohan Hedberg 	if (hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
11701afc2a1aSJohan Hedberg 		sec_level = BT_SECURITY_MEDIUM;
11711afc2a1aSJohan Hedberg 	else
1172c05b9339SJohan Hedberg 		sec_level = authreq_to_seclevel(auth);
11731afc2a1aSJohan Hedberg 
1174854f4727SJohan Hedberg 	if (smp_sufficient_security(hcon, sec_level))
1175854f4727SJohan Hedberg 		return 0;
1176854f4727SJohan Hedberg 
1177c7262e71SJohan Hedberg 	if (sec_level > hcon->pending_sec_level)
1178c7262e71SJohan Hedberg 		hcon->pending_sec_level = sec_level;
1179feb45eb5SVinicius Costa Gomes 
11804dab7864SJohan Hedberg 	if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
1181988c5997SVinicius Costa Gomes 		return 0;
1182988c5997SVinicius Costa Gomes 
11838aab4757SVinicius Costa Gomes 	smp = smp_chan_create(conn);
1184c29d2444SJohan Hedberg 	if (!smp)
1185c29d2444SJohan Hedberg 		return SMP_UNSPECIFIED;
1186d26a2345SVinicius Costa Gomes 
1187b6ae8457SJohan Hedberg 	if (!test_bit(HCI_BONDABLE, &hcon->hdev->dev_flags) &&
1188c05b9339SJohan Hedberg 	    (auth & SMP_AUTH_BONDING))
1189616d55beSJohan Hedberg 		return SMP_PAIRING_NOTSUPP;
1190616d55beSJohan Hedberg 
119188ba43b6SAnderson Briglia 	skb_pull(skb, sizeof(*rp));
119288ba43b6SAnderson Briglia 
1193da85e5e5SVinicius Costa Gomes 	memset(&cp, 0, sizeof(cp));
1194c05b9339SJohan Hedberg 	build_pairing_cmd(conn, &cp, NULL, auth);
119588ba43b6SAnderson Briglia 
11961c1def09SVinicius Costa Gomes 	smp->preq[0] = SMP_CMD_PAIRING_REQ;
11971c1def09SVinicius Costa Gomes 	memcpy(&smp->preq[1], &cp, sizeof(cp));
1198f01ead31SAnderson Briglia 
119988ba43b6SAnderson Briglia 	smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
1200b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP);
1201f1cb9af5SVinicius Costa Gomes 
1202da85e5e5SVinicius Costa Gomes 	return 0;
120388ba43b6SAnderson Briglia }
120488ba43b6SAnderson Briglia 
1205cc110922SVinicius Costa Gomes int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
1206eb492e01SAnderson Briglia {
1207cc110922SVinicius Costa Gomes 	struct l2cap_conn *conn = hcon->l2cap_data;
1208c68b7f12SJohan Hedberg 	struct l2cap_chan *chan;
12090a66cf20SJohan Hedberg 	struct smp_chan *smp;
12102b64d153SBrian Gix 	__u8 authreq;
1211fc75cc86SJohan Hedberg 	int ret;
1212eb492e01SAnderson Briglia 
12133a0259bbSVinicius Costa Gomes 	BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
12143a0259bbSVinicius Costa Gomes 
12150a66cf20SJohan Hedberg 	/* This may be NULL if there's an unexpected disconnection */
12160a66cf20SJohan Hedberg 	if (!conn)
12170a66cf20SJohan Hedberg 		return 1;
12180a66cf20SJohan Hedberg 
1219c68b7f12SJohan Hedberg 	chan = conn->smp;
1220c68b7f12SJohan Hedberg 
1221757aee0fSJohan Hedberg 	if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags))
12222e65c9d2SAndre Guedes 		return 1;
12232e65c9d2SAndre Guedes 
1224ad32a2f5SJohan Hedberg 	if (smp_sufficient_security(hcon, sec_level))
1225f1cb9af5SVinicius Costa Gomes 		return 1;
1226f1cb9af5SVinicius Costa Gomes 
1227c7262e71SJohan Hedberg 	if (sec_level > hcon->pending_sec_level)
1228c7262e71SJohan Hedberg 		hcon->pending_sec_level = sec_level;
1229c7262e71SJohan Hedberg 
123040bef302SJohan Hedberg 	if (hcon->role == HCI_ROLE_MASTER)
1231c7262e71SJohan Hedberg 		if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
1232c7262e71SJohan Hedberg 			return 0;
1233d26a2345SVinicius Costa Gomes 
1234fc75cc86SJohan Hedberg 	l2cap_chan_lock(chan);
1235fc75cc86SJohan Hedberg 
1236fc75cc86SJohan Hedberg 	/* If SMP is already in progress ignore this request */
1237fc75cc86SJohan Hedberg 	if (chan->data) {
1238fc75cc86SJohan Hedberg 		ret = 0;
1239fc75cc86SJohan Hedberg 		goto unlock;
1240fc75cc86SJohan Hedberg 	}
1241d26a2345SVinicius Costa Gomes 
12428aab4757SVinicius Costa Gomes 	smp = smp_chan_create(conn);
1243fc75cc86SJohan Hedberg 	if (!smp) {
1244fc75cc86SJohan Hedberg 		ret = 1;
1245fc75cc86SJohan Hedberg 		goto unlock;
1246fc75cc86SJohan Hedberg 	}
12472b64d153SBrian Gix 
12482b64d153SBrian Gix 	authreq = seclevel_to_authreq(sec_level);
1249d26a2345SVinicius Costa Gomes 
125079897d20SJohan Hedberg 	/* Require MITM if IO Capability allows or the security level
125179897d20SJohan Hedberg 	 * requires it.
12522e233644SJohan Hedberg 	 */
125379897d20SJohan Hedberg 	if (hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT ||
1254c7262e71SJohan Hedberg 	    hcon->pending_sec_level > BT_SECURITY_MEDIUM)
12552e233644SJohan Hedberg 		authreq |= SMP_AUTH_MITM;
12562e233644SJohan Hedberg 
125740bef302SJohan Hedberg 	if (hcon->role == HCI_ROLE_MASTER) {
1258d26a2345SVinicius Costa Gomes 		struct smp_cmd_pairing cp;
1259f01ead31SAnderson Briglia 
12602b64d153SBrian Gix 		build_pairing_cmd(conn, &cp, NULL, authreq);
12611c1def09SVinicius Costa Gomes 		smp->preq[0] = SMP_CMD_PAIRING_REQ;
12621c1def09SVinicius Costa Gomes 		memcpy(&smp->preq[1], &cp, sizeof(cp));
1263f01ead31SAnderson Briglia 
1264eb492e01SAnderson Briglia 		smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
1265b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP);
1266eb492e01SAnderson Briglia 	} else {
1267eb492e01SAnderson Briglia 		struct smp_cmd_security_req cp;
12682b64d153SBrian Gix 		cp.auth_req = authreq;
1269eb492e01SAnderson Briglia 		smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
1270b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_REQ);
1271eb492e01SAnderson Briglia 	}
1272eb492e01SAnderson Briglia 
12734a74d658SJohan Hedberg 	set_bit(SMP_FLAG_INITIATOR, &smp->flags);
1274fc75cc86SJohan Hedberg 	ret = 0;
1275edca792cSJohan Hedberg 
1276fc75cc86SJohan Hedberg unlock:
1277fc75cc86SJohan Hedberg 	l2cap_chan_unlock(chan);
1278fc75cc86SJohan Hedberg 	return ret;
1279eb492e01SAnderson Briglia }
1280eb492e01SAnderson Briglia 
12817034b911SVinicius Costa Gomes static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
12827034b911SVinicius Costa Gomes {
128316b90839SVinicius Costa Gomes 	struct smp_cmd_encrypt_info *rp = (void *) skb->data;
12845d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
12855d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
128616b90839SVinicius Costa Gomes 
1287c46b98beSJohan Hedberg 	BT_DBG("conn %p", conn);
1288c46b98beSJohan Hedberg 
1289c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rp))
129038e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1291c46b98beSJohan Hedberg 
1292b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_MASTER_IDENT);
12936131ddc8SJohan Hedberg 
129416b90839SVinicius Costa Gomes 	skb_pull(skb, sizeof(*rp));
129516b90839SVinicius Costa Gomes 
12961c1def09SVinicius Costa Gomes 	memcpy(smp->tk, rp->ltk, sizeof(smp->tk));
129716b90839SVinicius Costa Gomes 
12987034b911SVinicius Costa Gomes 	return 0;
12997034b911SVinicius Costa Gomes }
13007034b911SVinicius Costa Gomes 
13017034b911SVinicius Costa Gomes static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
13027034b911SVinicius Costa Gomes {
130316b90839SVinicius Costa Gomes 	struct smp_cmd_master_ident *rp = (void *) skb->data;
13045d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
13055d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
1306c9839a11SVinicius Costa Gomes 	struct hci_dev *hdev = conn->hcon->hdev;
1307c9839a11SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
130823d0e128SJohan Hedberg 	struct smp_ltk *ltk;
1309c9839a11SVinicius Costa Gomes 	u8 authenticated;
13107034b911SVinicius Costa Gomes 
1311c46b98beSJohan Hedberg 	BT_DBG("conn %p", conn);
1312c46b98beSJohan Hedberg 
1313c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rp))
131438e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1315c46b98beSJohan Hedberg 
13169747a9f3SJohan Hedberg 	/* Mark the information as received */
13179747a9f3SJohan Hedberg 	smp->remote_key_dist &= ~SMP_DIST_ENC_KEY;
13189747a9f3SJohan Hedberg 
1319b28b4943SJohan Hedberg 	if (smp->remote_key_dist & SMP_DIST_ID_KEY)
1320b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO);
1321196332f5SJohan Hedberg 	else if (smp->remote_key_dist & SMP_DIST_SIGN)
1322196332f5SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO);
1323b28b4943SJohan Hedberg 
132416b90839SVinicius Costa Gomes 	skb_pull(skb, sizeof(*rp));
132516b90839SVinicius Costa Gomes 
1326c9839a11SVinicius Costa Gomes 	hci_dev_lock(hdev);
1327ce39fb4eSMarcel Holtmann 	authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
13282ceba539SJohan Hedberg 	ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, SMP_LTK,
1329ce39fb4eSMarcel Holtmann 			  authenticated, smp->tk, smp->enc_key_size,
133004124681SGustavo F. Padovan 			  rp->ediv, rp->rand);
133123d0e128SJohan Hedberg 	smp->ltk = ltk;
1332c6e81e9aSJohan Hedberg 	if (!(smp->remote_key_dist & KEY_DIST_MASK))
1333d6268e86SJohan Hedberg 		smp_distribute_keys(smp);
1334c9839a11SVinicius Costa Gomes 	hci_dev_unlock(hdev);
13357034b911SVinicius Costa Gomes 
13367034b911SVinicius Costa Gomes 	return 0;
13377034b911SVinicius Costa Gomes }
13387034b911SVinicius Costa Gomes 
1339fd349c02SJohan Hedberg static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
1340fd349c02SJohan Hedberg {
1341fd349c02SJohan Hedberg 	struct smp_cmd_ident_info *info = (void *) skb->data;
13425d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
13435d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
1344fd349c02SJohan Hedberg 
1345fd349c02SJohan Hedberg 	BT_DBG("");
1346fd349c02SJohan Hedberg 
1347fd349c02SJohan Hedberg 	if (skb->len < sizeof(*info))
134838e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1349fd349c02SJohan Hedberg 
1350b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_ADDR_INFO);
13516131ddc8SJohan Hedberg 
1352fd349c02SJohan Hedberg 	skb_pull(skb, sizeof(*info));
1353fd349c02SJohan Hedberg 
1354fd349c02SJohan Hedberg 	memcpy(smp->irk, info->irk, 16);
1355fd349c02SJohan Hedberg 
1356fd349c02SJohan Hedberg 	return 0;
1357fd349c02SJohan Hedberg }
1358fd349c02SJohan Hedberg 
1359fd349c02SJohan Hedberg static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
1360fd349c02SJohan Hedberg 				   struct sk_buff *skb)
1361fd349c02SJohan Hedberg {
1362fd349c02SJohan Hedberg 	struct smp_cmd_ident_addr_info *info = (void *) skb->data;
13635d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
13645d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
1365fd349c02SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
1366fd349c02SJohan Hedberg 	bdaddr_t rpa;
1367fd349c02SJohan Hedberg 
1368fd349c02SJohan Hedberg 	BT_DBG("");
1369fd349c02SJohan Hedberg 
1370fd349c02SJohan Hedberg 	if (skb->len < sizeof(*info))
137138e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1372fd349c02SJohan Hedberg 
13739747a9f3SJohan Hedberg 	/* Mark the information as received */
13749747a9f3SJohan Hedberg 	smp->remote_key_dist &= ~SMP_DIST_ID_KEY;
13759747a9f3SJohan Hedberg 
1376b28b4943SJohan Hedberg 	if (smp->remote_key_dist & SMP_DIST_SIGN)
1377b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO);
1378b28b4943SJohan Hedberg 
1379fd349c02SJohan Hedberg 	skb_pull(skb, sizeof(*info));
1380fd349c02SJohan Hedberg 
138131dd624eSJohan Hedberg 	hci_dev_lock(hcon->hdev);
138231dd624eSJohan Hedberg 
1383a9a58f86SJohan Hedberg 	/* Strictly speaking the Core Specification (4.1) allows sending
1384a9a58f86SJohan Hedberg 	 * an empty address which would force us to rely on just the IRK
1385a9a58f86SJohan Hedberg 	 * as "identity information". However, since such
1386a9a58f86SJohan Hedberg 	 * implementations are not known of and in order to not over
1387a9a58f86SJohan Hedberg 	 * complicate our implementation, simply pretend that we never
1388a9a58f86SJohan Hedberg 	 * received an IRK for such a device.
1389a9a58f86SJohan Hedberg 	 */
1390a9a58f86SJohan Hedberg 	if (!bacmp(&info->bdaddr, BDADDR_ANY)) {
1391a9a58f86SJohan Hedberg 		BT_ERR("Ignoring IRK with no identity address");
139231dd624eSJohan Hedberg 		goto distribute;
1393a9a58f86SJohan Hedberg 	}
1394a9a58f86SJohan Hedberg 
1395fd349c02SJohan Hedberg 	bacpy(&smp->id_addr, &info->bdaddr);
1396fd349c02SJohan Hedberg 	smp->id_addr_type = info->addr_type;
1397fd349c02SJohan Hedberg 
1398fd349c02SJohan Hedberg 	if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type))
1399fd349c02SJohan Hedberg 		bacpy(&rpa, &hcon->dst);
1400fd349c02SJohan Hedberg 	else
1401fd349c02SJohan Hedberg 		bacpy(&rpa, BDADDR_ANY);
1402fd349c02SJohan Hedberg 
140323d0e128SJohan Hedberg 	smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
140423d0e128SJohan Hedberg 				      smp->id_addr_type, smp->irk, &rpa);
1405fd349c02SJohan Hedberg 
140631dd624eSJohan Hedberg distribute:
1407c6e81e9aSJohan Hedberg 	if (!(smp->remote_key_dist & KEY_DIST_MASK))
1408d6268e86SJohan Hedberg 		smp_distribute_keys(smp);
1409fd349c02SJohan Hedberg 
141031dd624eSJohan Hedberg 	hci_dev_unlock(hcon->hdev);
141131dd624eSJohan Hedberg 
1412fd349c02SJohan Hedberg 	return 0;
1413fd349c02SJohan Hedberg }
1414fd349c02SJohan Hedberg 
14157ee4ea36SMarcel Holtmann static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)
14167ee4ea36SMarcel Holtmann {
14177ee4ea36SMarcel Holtmann 	struct smp_cmd_sign_info *rp = (void *) skb->data;
14185d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
14195d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
14207ee4ea36SMarcel Holtmann 	struct hci_dev *hdev = conn->hcon->hdev;
14217ee4ea36SMarcel Holtmann 	struct smp_csrk *csrk;
14227ee4ea36SMarcel Holtmann 
14237ee4ea36SMarcel Holtmann 	BT_DBG("conn %p", conn);
14247ee4ea36SMarcel Holtmann 
14257ee4ea36SMarcel Holtmann 	if (skb->len < sizeof(*rp))
142638e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
14277ee4ea36SMarcel Holtmann 
14287ee4ea36SMarcel Holtmann 	/* Mark the information as received */
14297ee4ea36SMarcel Holtmann 	smp->remote_key_dist &= ~SMP_DIST_SIGN;
14307ee4ea36SMarcel Holtmann 
14317ee4ea36SMarcel Holtmann 	skb_pull(skb, sizeof(*rp));
14327ee4ea36SMarcel Holtmann 
14337ee4ea36SMarcel Holtmann 	hci_dev_lock(hdev);
14347ee4ea36SMarcel Holtmann 	csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
14357ee4ea36SMarcel Holtmann 	if (csrk) {
14367ee4ea36SMarcel Holtmann 		csrk->master = 0x01;
14377ee4ea36SMarcel Holtmann 		memcpy(csrk->val, rp->csrk, sizeof(csrk->val));
14387ee4ea36SMarcel Holtmann 	}
14397ee4ea36SMarcel Holtmann 	smp->csrk = csrk;
1440d6268e86SJohan Hedberg 	smp_distribute_keys(smp);
14417ee4ea36SMarcel Holtmann 	hci_dev_unlock(hdev);
14427ee4ea36SMarcel Holtmann 
14437ee4ea36SMarcel Holtmann 	return 0;
14447ee4ea36SMarcel Holtmann }
14457ee4ea36SMarcel Holtmann 
14464befb867SJohan Hedberg static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb)
1447eb492e01SAnderson Briglia {
14485d88cc73SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
14497b9899dbSMarcel Holtmann 	struct hci_conn *hcon = conn->hcon;
1450b28b4943SJohan Hedberg 	struct smp_chan *smp;
145192381f5cSMarcel Holtmann 	__u8 code, reason;
1452eb492e01SAnderson Briglia 	int err = 0;
1453eb492e01SAnderson Briglia 
14547b9899dbSMarcel Holtmann 	if (hcon->type != LE_LINK) {
14557b9899dbSMarcel Holtmann 		kfree_skb(skb);
14563432711fSJohan Hedberg 		return 0;
14577b9899dbSMarcel Holtmann 	}
14587b9899dbSMarcel Holtmann 
14598ae9b984SJohan Hedberg 	if (skb->len < 1)
146092381f5cSMarcel Holtmann 		return -EILSEQ;
146192381f5cSMarcel Holtmann 
146206ae3314SMarcel Holtmann 	if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) {
14632e65c9d2SAndre Guedes 		reason = SMP_PAIRING_NOTSUPP;
14642e65c9d2SAndre Guedes 		goto done;
14652e65c9d2SAndre Guedes 	}
14662e65c9d2SAndre Guedes 
146792381f5cSMarcel Holtmann 	code = skb->data[0];
1468eb492e01SAnderson Briglia 	skb_pull(skb, sizeof(code));
1469eb492e01SAnderson Briglia 
1470b28b4943SJohan Hedberg 	smp = chan->data;
1471b28b4943SJohan Hedberg 
1472b28b4943SJohan Hedberg 	if (code > SMP_CMD_MAX)
1473b28b4943SJohan Hedberg 		goto drop;
1474b28b4943SJohan Hedberg 
147524bd0bd9SJohan Hedberg 	if (smp && !test_and_clear_bit(code, &smp->allow_cmd))
1476b28b4943SJohan Hedberg 		goto drop;
1477b28b4943SJohan Hedberg 
1478b28b4943SJohan Hedberg 	/* If we don't have a context the only allowed commands are
1479b28b4943SJohan Hedberg 	 * pairing request and security request.
14808cf9fa12SJohan Hedberg 	 */
1481b28b4943SJohan Hedberg 	if (!smp && code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ)
1482b28b4943SJohan Hedberg 		goto drop;
14838cf9fa12SJohan Hedberg 
1484eb492e01SAnderson Briglia 	switch (code) {
1485eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_REQ:
1486da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_req(conn, skb);
1487eb492e01SAnderson Briglia 		break;
1488eb492e01SAnderson Briglia 
1489eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_FAIL:
149084794e11SJohan Hedberg 		smp_failure(conn, 0);
1491da85e5e5SVinicius Costa Gomes 		err = -EPERM;
1492eb492e01SAnderson Briglia 		break;
1493eb492e01SAnderson Briglia 
1494eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_RSP:
1495da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_rsp(conn, skb);
149688ba43b6SAnderson Briglia 		break;
149788ba43b6SAnderson Briglia 
149888ba43b6SAnderson Briglia 	case SMP_CMD_SECURITY_REQ:
1499da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_security_req(conn, skb);
150088ba43b6SAnderson Briglia 		break;
150188ba43b6SAnderson Briglia 
1502eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_CONFIRM:
1503da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_confirm(conn, skb);
150488ba43b6SAnderson Briglia 		break;
150588ba43b6SAnderson Briglia 
1506eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_RANDOM:
1507da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_random(conn, skb);
150888ba43b6SAnderson Briglia 		break;
150988ba43b6SAnderson Briglia 
1510eb492e01SAnderson Briglia 	case SMP_CMD_ENCRYPT_INFO:
15117034b911SVinicius Costa Gomes 		reason = smp_cmd_encrypt_info(conn, skb);
15127034b911SVinicius Costa Gomes 		break;
15137034b911SVinicius Costa Gomes 
1514eb492e01SAnderson Briglia 	case SMP_CMD_MASTER_IDENT:
15157034b911SVinicius Costa Gomes 		reason = smp_cmd_master_ident(conn, skb);
15167034b911SVinicius Costa Gomes 		break;
15177034b911SVinicius Costa Gomes 
1518eb492e01SAnderson Briglia 	case SMP_CMD_IDENT_INFO:
1519fd349c02SJohan Hedberg 		reason = smp_cmd_ident_info(conn, skb);
1520fd349c02SJohan Hedberg 		break;
1521fd349c02SJohan Hedberg 
1522eb492e01SAnderson Briglia 	case SMP_CMD_IDENT_ADDR_INFO:
1523fd349c02SJohan Hedberg 		reason = smp_cmd_ident_addr_info(conn, skb);
1524fd349c02SJohan Hedberg 		break;
1525fd349c02SJohan Hedberg 
1526eb492e01SAnderson Briglia 	case SMP_CMD_SIGN_INFO:
15277ee4ea36SMarcel Holtmann 		reason = smp_cmd_sign_info(conn, skb);
15287034b911SVinicius Costa Gomes 		break;
15297034b911SVinicius Costa Gomes 
1530eb492e01SAnderson Briglia 	default:
1531eb492e01SAnderson Briglia 		BT_DBG("Unknown command code 0x%2.2x", code);
1532eb492e01SAnderson Briglia 		reason = SMP_CMD_NOTSUPP;
15333a0259bbSVinicius Costa Gomes 		goto done;
15343a0259bbSVinicius Costa Gomes 	}
15353a0259bbSVinicius Costa Gomes 
15363a0259bbSVinicius Costa Gomes done:
15379b7b18efSJohan Hedberg 	if (!err) {
15383a0259bbSVinicius Costa Gomes 		if (reason)
153984794e11SJohan Hedberg 			smp_failure(conn, reason);
1540eb492e01SAnderson Briglia 		kfree_skb(skb);
15419b7b18efSJohan Hedberg 	}
15429b7b18efSJohan Hedberg 
1543eb492e01SAnderson Briglia 	return err;
1544b28b4943SJohan Hedberg 
1545b28b4943SJohan Hedberg drop:
1546b28b4943SJohan Hedberg 	BT_ERR("%s unexpected SMP command 0x%02x from %pMR", hcon->hdev->name,
1547b28b4943SJohan Hedberg 	       code, &hcon->dst);
1548b28b4943SJohan Hedberg 	kfree_skb(skb);
1549b28b4943SJohan Hedberg 	return 0;
1550eb492e01SAnderson Briglia }
15517034b911SVinicius Costa Gomes 
155270db83c4SJohan Hedberg static void smp_teardown_cb(struct l2cap_chan *chan, int err)
155370db83c4SJohan Hedberg {
155470db83c4SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
155570db83c4SJohan Hedberg 
155670db83c4SJohan Hedberg 	BT_DBG("chan %p", chan);
155770db83c4SJohan Hedberg 
1558fc75cc86SJohan Hedberg 	if (chan->data)
15595d88cc73SJohan Hedberg 		smp_chan_destroy(conn);
15605d88cc73SJohan Hedberg 
156170db83c4SJohan Hedberg 	conn->smp = NULL;
156270db83c4SJohan Hedberg 	l2cap_chan_put(chan);
156370db83c4SJohan Hedberg }
156470db83c4SJohan Hedberg 
156544f1a7abSJohan Hedberg static void smp_resume_cb(struct l2cap_chan *chan)
156644f1a7abSJohan Hedberg {
1567b68fda68SJohan Hedberg 	struct smp_chan *smp = chan->data;
156844f1a7abSJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
156944f1a7abSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
157044f1a7abSJohan Hedberg 
157144f1a7abSJohan Hedberg 	BT_DBG("chan %p", chan);
157244f1a7abSJohan Hedberg 
157386d1407cSJohan Hedberg 	if (!smp)
157486d1407cSJohan Hedberg 		return;
1575b68fda68SJohan Hedberg 
157684bc0db5SJohan Hedberg 	if (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags))
157784bc0db5SJohan Hedberg 		return;
157884bc0db5SJohan Hedberg 
1579b68fda68SJohan Hedberg 	cancel_delayed_work(&smp->security_timer);
158086d1407cSJohan Hedberg 
1581d6268e86SJohan Hedberg 	smp_distribute_keys(smp);
158244f1a7abSJohan Hedberg }
158344f1a7abSJohan Hedberg 
158470db83c4SJohan Hedberg static void smp_ready_cb(struct l2cap_chan *chan)
158570db83c4SJohan Hedberg {
158670db83c4SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
158770db83c4SJohan Hedberg 
158870db83c4SJohan Hedberg 	BT_DBG("chan %p", chan);
158970db83c4SJohan Hedberg 
159070db83c4SJohan Hedberg 	conn->smp = chan;
159170db83c4SJohan Hedberg 	l2cap_chan_hold(chan);
159270db83c4SJohan Hedberg }
159370db83c4SJohan Hedberg 
15944befb867SJohan Hedberg static int smp_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
15954befb867SJohan Hedberg {
15964befb867SJohan Hedberg 	int err;
15974befb867SJohan Hedberg 
15984befb867SJohan Hedberg 	BT_DBG("chan %p", chan);
15994befb867SJohan Hedberg 
16004befb867SJohan Hedberg 	err = smp_sig_channel(chan, skb);
16014befb867SJohan Hedberg 	if (err) {
1602b68fda68SJohan Hedberg 		struct smp_chan *smp = chan->data;
16034befb867SJohan Hedberg 
1604b68fda68SJohan Hedberg 		if (smp)
1605b68fda68SJohan Hedberg 			cancel_delayed_work_sync(&smp->security_timer);
16064befb867SJohan Hedberg 
16071e91c29eSJohan Hedberg 		hci_disconnect(chan->conn->hcon, HCI_ERROR_AUTH_FAILURE);
16084befb867SJohan Hedberg 	}
16094befb867SJohan Hedberg 
16104befb867SJohan Hedberg 	return err;
16114befb867SJohan Hedberg }
16124befb867SJohan Hedberg 
161370db83c4SJohan Hedberg static struct sk_buff *smp_alloc_skb_cb(struct l2cap_chan *chan,
161470db83c4SJohan Hedberg 					unsigned long hdr_len,
161570db83c4SJohan Hedberg 					unsigned long len, int nb)
161670db83c4SJohan Hedberg {
161770db83c4SJohan Hedberg 	struct sk_buff *skb;
161870db83c4SJohan Hedberg 
161970db83c4SJohan Hedberg 	skb = bt_skb_alloc(hdr_len + len, GFP_KERNEL);
162070db83c4SJohan Hedberg 	if (!skb)
162170db83c4SJohan Hedberg 		return ERR_PTR(-ENOMEM);
162270db83c4SJohan Hedberg 
162370db83c4SJohan Hedberg 	skb->priority = HCI_PRIO_MAX;
162470db83c4SJohan Hedberg 	bt_cb(skb)->chan = chan;
162570db83c4SJohan Hedberg 
162670db83c4SJohan Hedberg 	return skb;
162770db83c4SJohan Hedberg }
162870db83c4SJohan Hedberg 
162970db83c4SJohan Hedberg static const struct l2cap_ops smp_chan_ops = {
163070db83c4SJohan Hedberg 	.name			= "Security Manager",
163170db83c4SJohan Hedberg 	.ready			= smp_ready_cb,
16325d88cc73SJohan Hedberg 	.recv			= smp_recv_cb,
163370db83c4SJohan Hedberg 	.alloc_skb		= smp_alloc_skb_cb,
163470db83c4SJohan Hedberg 	.teardown		= smp_teardown_cb,
163544f1a7abSJohan Hedberg 	.resume			= smp_resume_cb,
163670db83c4SJohan Hedberg 
163770db83c4SJohan Hedberg 	.new_connection		= l2cap_chan_no_new_connection,
163870db83c4SJohan Hedberg 	.state_change		= l2cap_chan_no_state_change,
163970db83c4SJohan Hedberg 	.close			= l2cap_chan_no_close,
164070db83c4SJohan Hedberg 	.defer			= l2cap_chan_no_defer,
164170db83c4SJohan Hedberg 	.suspend		= l2cap_chan_no_suspend,
164270db83c4SJohan Hedberg 	.set_shutdown		= l2cap_chan_no_set_shutdown,
164370db83c4SJohan Hedberg 	.get_sndtimeo		= l2cap_chan_no_get_sndtimeo,
164470db83c4SJohan Hedberg 	.memcpy_fromiovec	= l2cap_chan_no_memcpy_fromiovec,
164570db83c4SJohan Hedberg };
164670db83c4SJohan Hedberg 
164770db83c4SJohan Hedberg static inline struct l2cap_chan *smp_new_conn_cb(struct l2cap_chan *pchan)
164870db83c4SJohan Hedberg {
164970db83c4SJohan Hedberg 	struct l2cap_chan *chan;
165070db83c4SJohan Hedberg 
165170db83c4SJohan Hedberg 	BT_DBG("pchan %p", pchan);
165270db83c4SJohan Hedberg 
165370db83c4SJohan Hedberg 	chan = l2cap_chan_create();
165470db83c4SJohan Hedberg 	if (!chan)
165570db83c4SJohan Hedberg 		return NULL;
165670db83c4SJohan Hedberg 
165770db83c4SJohan Hedberg 	chan->chan_type	= pchan->chan_type;
165870db83c4SJohan Hedberg 	chan->ops	= &smp_chan_ops;
165970db83c4SJohan Hedberg 	chan->scid	= pchan->scid;
166070db83c4SJohan Hedberg 	chan->dcid	= chan->scid;
166170db83c4SJohan Hedberg 	chan->imtu	= pchan->imtu;
166270db83c4SJohan Hedberg 	chan->omtu	= pchan->omtu;
166370db83c4SJohan Hedberg 	chan->mode	= pchan->mode;
166470db83c4SJohan Hedberg 
166570db83c4SJohan Hedberg 	BT_DBG("created chan %p", chan);
166670db83c4SJohan Hedberg 
166770db83c4SJohan Hedberg 	return chan;
166870db83c4SJohan Hedberg }
166970db83c4SJohan Hedberg 
167070db83c4SJohan Hedberg static const struct l2cap_ops smp_root_chan_ops = {
167170db83c4SJohan Hedberg 	.name			= "Security Manager Root",
167270db83c4SJohan Hedberg 	.new_connection		= smp_new_conn_cb,
167370db83c4SJohan Hedberg 
167470db83c4SJohan Hedberg 	/* None of these are implemented for the root channel */
167570db83c4SJohan Hedberg 	.close			= l2cap_chan_no_close,
167670db83c4SJohan Hedberg 	.alloc_skb		= l2cap_chan_no_alloc_skb,
167770db83c4SJohan Hedberg 	.recv			= l2cap_chan_no_recv,
167870db83c4SJohan Hedberg 	.state_change		= l2cap_chan_no_state_change,
167970db83c4SJohan Hedberg 	.teardown		= l2cap_chan_no_teardown,
168070db83c4SJohan Hedberg 	.ready			= l2cap_chan_no_ready,
168170db83c4SJohan Hedberg 	.defer			= l2cap_chan_no_defer,
168270db83c4SJohan Hedberg 	.suspend		= l2cap_chan_no_suspend,
168370db83c4SJohan Hedberg 	.resume			= l2cap_chan_no_resume,
168470db83c4SJohan Hedberg 	.set_shutdown		= l2cap_chan_no_set_shutdown,
168570db83c4SJohan Hedberg 	.get_sndtimeo		= l2cap_chan_no_get_sndtimeo,
168670db83c4SJohan Hedberg 	.memcpy_fromiovec	= l2cap_chan_no_memcpy_fromiovec,
168770db83c4SJohan Hedberg };
168870db83c4SJohan Hedberg 
1689711eafe3SJohan Hedberg int smp_register(struct hci_dev *hdev)
1690711eafe3SJohan Hedberg {
169170db83c4SJohan Hedberg 	struct l2cap_chan *chan;
1692defce9e8SJohan Hedberg 	struct crypto_blkcipher	*tfm_aes;
169370db83c4SJohan Hedberg 
1694711eafe3SJohan Hedberg 	BT_DBG("%s", hdev->name);
1695711eafe3SJohan Hedberg 
1696defce9e8SJohan Hedberg 	tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
1697defce9e8SJohan Hedberg 	if (IS_ERR(tfm_aes)) {
1698defce9e8SJohan Hedberg 		int err = PTR_ERR(tfm_aes);
1699711eafe3SJohan Hedberg 		BT_ERR("Unable to create crypto context");
1700711eafe3SJohan Hedberg 		return err;
1701711eafe3SJohan Hedberg 	}
1702711eafe3SJohan Hedberg 
170370db83c4SJohan Hedberg 	chan = l2cap_chan_create();
170470db83c4SJohan Hedberg 	if (!chan) {
1705defce9e8SJohan Hedberg 		crypto_free_blkcipher(tfm_aes);
170670db83c4SJohan Hedberg 		return -ENOMEM;
170770db83c4SJohan Hedberg 	}
170870db83c4SJohan Hedberg 
1709defce9e8SJohan Hedberg 	chan->data = tfm_aes;
1710defce9e8SJohan Hedberg 
17115d88cc73SJohan Hedberg 	l2cap_add_scid(chan, L2CAP_CID_SMP);
171270db83c4SJohan Hedberg 
171370db83c4SJohan Hedberg 	l2cap_chan_set_defaults(chan);
171470db83c4SJohan Hedberg 
171570db83c4SJohan Hedberg 	bacpy(&chan->src, &hdev->bdaddr);
171670db83c4SJohan Hedberg 	chan->src_type = BDADDR_LE_PUBLIC;
171770db83c4SJohan Hedberg 	chan->state = BT_LISTEN;
171870db83c4SJohan Hedberg 	chan->mode = L2CAP_MODE_BASIC;
171970db83c4SJohan Hedberg 	chan->imtu = L2CAP_DEFAULT_MTU;
172070db83c4SJohan Hedberg 	chan->ops = &smp_root_chan_ops;
172170db83c4SJohan Hedberg 
172270db83c4SJohan Hedberg 	hdev->smp_data = chan;
172370db83c4SJohan Hedberg 
1724711eafe3SJohan Hedberg 	return 0;
1725711eafe3SJohan Hedberg }
1726711eafe3SJohan Hedberg 
1727711eafe3SJohan Hedberg void smp_unregister(struct hci_dev *hdev)
1728711eafe3SJohan Hedberg {
172970db83c4SJohan Hedberg 	struct l2cap_chan *chan = hdev->smp_data;
1730defce9e8SJohan Hedberg 	struct crypto_blkcipher *tfm_aes;
173170db83c4SJohan Hedberg 
173270db83c4SJohan Hedberg 	if (!chan)
173370db83c4SJohan Hedberg 		return;
173470db83c4SJohan Hedberg 
173570db83c4SJohan Hedberg 	BT_DBG("%s chan %p", hdev->name, chan);
1736711eafe3SJohan Hedberg 
1737defce9e8SJohan Hedberg 	tfm_aes = chan->data;
1738defce9e8SJohan Hedberg 	if (tfm_aes) {
1739defce9e8SJohan Hedberg 		chan->data = NULL;
1740defce9e8SJohan Hedberg 		crypto_free_blkcipher(tfm_aes);
1741711eafe3SJohan Hedberg 	}
174270db83c4SJohan Hedberg 
174370db83c4SJohan Hedberg 	hdev->smp_data = NULL;
174470db83c4SJohan Hedberg 	l2cap_chan_put(chan);
1745711eafe3SJohan Hedberg }
1746