xref: /openbmc/linux/net/bluetooth/smp.c (revision d8f8edbe)
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 
323b19146dSJohan Hedberg #include "ecc.h"
33ac4b7236SMarcel Holtmann #include "smp.h"
34d22ef0bcSAnderson Briglia 
35b28b4943SJohan Hedberg #define SMP_ALLOW_CMD(smp, code)	set_bit(code, &smp->allow_cmd)
36b28b4943SJohan Hedberg 
373b19146dSJohan Hedberg /* Keys which are not distributed with Secure Connections */
383b19146dSJohan Hedberg #define SMP_SC_NO_DIST (SMP_DIST_ENC_KEY | SMP_DIST_LINK_KEY);
393b19146dSJohan Hedberg 
4017b02e62SMarcel Holtmann #define SMP_TIMEOUT	msecs_to_jiffies(30000)
415d3de7dfSVinicius Costa Gomes 
420edb14deSJohan Hedberg #define AUTH_REQ_MASK(dev)	(test_bit(HCI_SC_ENABLED, &(dev)->dev_flags) ? \
430edb14deSJohan Hedberg 				 0x1f : 0x07)
4488d3a8acSJohan Hedberg #define KEY_DIST_MASK		0x07
45065a13e2SJohan Hedberg 
46533e35d4SJohan Hedberg enum {
47533e35d4SJohan Hedberg 	SMP_FLAG_TK_VALID,
48533e35d4SJohan Hedberg 	SMP_FLAG_CFM_PENDING,
49533e35d4SJohan Hedberg 	SMP_FLAG_MITM_AUTH,
50533e35d4SJohan Hedberg 	SMP_FLAG_COMPLETE,
51533e35d4SJohan Hedberg 	SMP_FLAG_INITIATOR,
5265668776SJohan Hedberg 	SMP_FLAG_SC,
53d8f8edbeSJohan Hedberg 	SMP_FLAG_REMOTE_PK,
54533e35d4SJohan Hedberg };
554bc58f51SJohan Hedberg 
564bc58f51SJohan Hedberg struct smp_chan {
574bc58f51SJohan Hedberg 	struct l2cap_conn	*conn;
58b68fda68SJohan Hedberg 	struct delayed_work	security_timer;
59b28b4943SJohan Hedberg 	unsigned long           allow_cmd; /* Bitmask of allowed commands */
60b68fda68SJohan Hedberg 
614bc58f51SJohan Hedberg 	u8		preq[7]; /* SMP Pairing Request */
624bc58f51SJohan Hedberg 	u8		prsp[7]; /* SMP Pairing Response */
634bc58f51SJohan Hedberg 	u8		prnd[16]; /* SMP Pairing Random (local) */
644bc58f51SJohan Hedberg 	u8		rrnd[16]; /* SMP Pairing Random (remote) */
654bc58f51SJohan Hedberg 	u8		pcnf[16]; /* SMP Pairing Confirm */
664bc58f51SJohan Hedberg 	u8		tk[16]; /* SMP Temporary Key */
674bc58f51SJohan Hedberg 	u8		enc_key_size;
684bc58f51SJohan Hedberg 	u8		remote_key_dist;
694bc58f51SJohan Hedberg 	bdaddr_t	id_addr;
704bc58f51SJohan Hedberg 	u8		id_addr_type;
714bc58f51SJohan Hedberg 	u8		irk[16];
724bc58f51SJohan Hedberg 	struct smp_csrk	*csrk;
734bc58f51SJohan Hedberg 	struct smp_csrk	*slave_csrk;
744bc58f51SJohan Hedberg 	struct smp_ltk	*ltk;
754bc58f51SJohan Hedberg 	struct smp_ltk	*slave_ltk;
764bc58f51SJohan Hedberg 	struct smp_irk	*remote_irk;
774a74d658SJohan Hedberg 	unsigned long	flags;
786a7bd103SJohan Hedberg 
793b19146dSJohan Hedberg 	/* Secure Connections variables */
803b19146dSJohan Hedberg 	u8			local_pk[64];
813b19146dSJohan Hedberg 	u8			local_sk[32];
82d8f8edbeSJohan Hedberg 	u8			remote_pk[64];
83d8f8edbeSJohan Hedberg 	u8			dhkey[32];
843b19146dSJohan Hedberg 
856a7bd103SJohan Hedberg 	struct crypto_blkcipher	*tfm_aes;
86407cecf6SJohan Hedberg 	struct crypto_hash	*tfm_cmac;
874bc58f51SJohan Hedberg };
884bc58f51SJohan Hedberg 
898a2936f4SJohan Hedberg static inline void swap_buf(const u8 *src, u8 *dst, size_t len)
90d22ef0bcSAnderson Briglia {
918a2936f4SJohan Hedberg 	size_t i;
92d22ef0bcSAnderson Briglia 
938a2936f4SJohan Hedberg 	for (i = 0; i < len; i++)
948a2936f4SJohan Hedberg 		dst[len - 1 - i] = src[i];
95d22ef0bcSAnderson Briglia }
96d22ef0bcSAnderson Briglia 
97d22ef0bcSAnderson Briglia static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
98d22ef0bcSAnderson Briglia {
99d22ef0bcSAnderson Briglia 	struct blkcipher_desc desc;
100d22ef0bcSAnderson Briglia 	struct scatterlist sg;
101943a732aSJohan Hedberg 	uint8_t tmp[16], data[16];
102201a5929SJohan Hedberg 	int err;
103d22ef0bcSAnderson Briglia 
104d22ef0bcSAnderson Briglia 	if (tfm == NULL) {
105d22ef0bcSAnderson Briglia 		BT_ERR("tfm %p", tfm);
106d22ef0bcSAnderson Briglia 		return -EINVAL;
107d22ef0bcSAnderson Briglia 	}
108d22ef0bcSAnderson Briglia 
109d22ef0bcSAnderson Briglia 	desc.tfm = tfm;
110d22ef0bcSAnderson Briglia 	desc.flags = 0;
111d22ef0bcSAnderson Briglia 
112943a732aSJohan Hedberg 	/* The most significant octet of key corresponds to k[0] */
1138a2936f4SJohan Hedberg 	swap_buf(k, tmp, 16);
114943a732aSJohan Hedberg 
115943a732aSJohan Hedberg 	err = crypto_blkcipher_setkey(tfm, tmp, 16);
116d22ef0bcSAnderson Briglia 	if (err) {
117d22ef0bcSAnderson Briglia 		BT_ERR("cipher setkey failed: %d", err);
118d22ef0bcSAnderson Briglia 		return err;
119d22ef0bcSAnderson Briglia 	}
120d22ef0bcSAnderson Briglia 
121943a732aSJohan Hedberg 	/* Most significant octet of plaintextData corresponds to data[0] */
1228a2936f4SJohan Hedberg 	swap_buf(r, data, 16);
123943a732aSJohan Hedberg 
124943a732aSJohan Hedberg 	sg_init_one(&sg, data, 16);
125d22ef0bcSAnderson Briglia 
126d22ef0bcSAnderson Briglia 	err = crypto_blkcipher_encrypt(&desc, &sg, &sg, 16);
127d22ef0bcSAnderson Briglia 	if (err)
128d22ef0bcSAnderson Briglia 		BT_ERR("Encrypt data error %d", err);
129d22ef0bcSAnderson Briglia 
130943a732aSJohan Hedberg 	/* Most significant octet of encryptedData corresponds to data[0] */
1318a2936f4SJohan Hedberg 	swap_buf(data, r, 16);
132943a732aSJohan Hedberg 
133d22ef0bcSAnderson Briglia 	return err;
134d22ef0bcSAnderson Briglia }
135d22ef0bcSAnderson Briglia 
13660478054SJohan Hedberg static int smp_ah(struct crypto_blkcipher *tfm, u8 irk[16], u8 r[3], u8 res[3])
13760478054SJohan Hedberg {
138943a732aSJohan Hedberg 	u8 _res[16];
13960478054SJohan Hedberg 	int err;
14060478054SJohan Hedberg 
14160478054SJohan Hedberg 	/* r' = padding || r */
142943a732aSJohan Hedberg 	memcpy(_res, r, 3);
143943a732aSJohan Hedberg 	memset(_res + 3, 0, 13);
14460478054SJohan Hedberg 
145943a732aSJohan Hedberg 	err = smp_e(tfm, irk, _res);
14660478054SJohan Hedberg 	if (err) {
14760478054SJohan Hedberg 		BT_ERR("Encrypt error");
14860478054SJohan Hedberg 		return err;
14960478054SJohan Hedberg 	}
15060478054SJohan Hedberg 
15160478054SJohan Hedberg 	/* The output of the random address function ah is:
15260478054SJohan Hedberg 	 *	ah(h, r) = e(k, r') mod 2^24
15360478054SJohan Hedberg 	 * The output of the security function e is then truncated to 24 bits
15460478054SJohan Hedberg 	 * by taking the least significant 24 bits of the output of e as the
15560478054SJohan Hedberg 	 * result of ah.
15660478054SJohan Hedberg 	 */
157943a732aSJohan Hedberg 	memcpy(res, _res, 3);
15860478054SJohan Hedberg 
15960478054SJohan Hedberg 	return 0;
16060478054SJohan Hedberg }
16160478054SJohan Hedberg 
162defce9e8SJohan Hedberg bool smp_irk_matches(struct hci_dev *hdev, u8 irk[16], bdaddr_t *bdaddr)
16360478054SJohan Hedberg {
164defce9e8SJohan Hedberg 	struct l2cap_chan *chan = hdev->smp_data;
165defce9e8SJohan Hedberg 	struct crypto_blkcipher *tfm;
16660478054SJohan Hedberg 	u8 hash[3];
16760478054SJohan Hedberg 	int err;
16860478054SJohan Hedberg 
169defce9e8SJohan Hedberg 	if (!chan || !chan->data)
170defce9e8SJohan Hedberg 		return false;
171defce9e8SJohan Hedberg 
172defce9e8SJohan Hedberg 	tfm = chan->data;
173defce9e8SJohan Hedberg 
17460478054SJohan Hedberg 	BT_DBG("RPA %pMR IRK %*phN", bdaddr, 16, irk);
17560478054SJohan Hedberg 
17660478054SJohan Hedberg 	err = smp_ah(tfm, irk, &bdaddr->b[3], hash);
17760478054SJohan Hedberg 	if (err)
17860478054SJohan Hedberg 		return false;
17960478054SJohan Hedberg 
18060478054SJohan Hedberg 	return !memcmp(bdaddr->b, hash, 3);
18160478054SJohan Hedberg }
18260478054SJohan Hedberg 
183defce9e8SJohan Hedberg int smp_generate_rpa(struct hci_dev *hdev, u8 irk[16], bdaddr_t *rpa)
184b1e2b3aeSJohan Hedberg {
185defce9e8SJohan Hedberg 	struct l2cap_chan *chan = hdev->smp_data;
186defce9e8SJohan Hedberg 	struct crypto_blkcipher *tfm;
187b1e2b3aeSJohan Hedberg 	int err;
188b1e2b3aeSJohan Hedberg 
189defce9e8SJohan Hedberg 	if (!chan || !chan->data)
190defce9e8SJohan Hedberg 		return -EOPNOTSUPP;
191defce9e8SJohan Hedberg 
192defce9e8SJohan Hedberg 	tfm = chan->data;
193defce9e8SJohan Hedberg 
194b1e2b3aeSJohan Hedberg 	get_random_bytes(&rpa->b[3], 3);
195b1e2b3aeSJohan Hedberg 
196b1e2b3aeSJohan Hedberg 	rpa->b[5] &= 0x3f;	/* Clear two most significant bits */
197b1e2b3aeSJohan Hedberg 	rpa->b[5] |= 0x40;	/* Set second most significant bit */
198b1e2b3aeSJohan Hedberg 
199b1e2b3aeSJohan Hedberg 	err = smp_ah(tfm, irk, &rpa->b[3], rpa->b);
200b1e2b3aeSJohan Hedberg 	if (err < 0)
201b1e2b3aeSJohan Hedberg 		return err;
202b1e2b3aeSJohan Hedberg 
203b1e2b3aeSJohan Hedberg 	BT_DBG("RPA %pMR", rpa);
204b1e2b3aeSJohan Hedberg 
205b1e2b3aeSJohan Hedberg 	return 0;
206b1e2b3aeSJohan Hedberg }
207b1e2b3aeSJohan Hedberg 
208e491eaf3SJohan Hedberg static int smp_c1(struct crypto_blkcipher *tfm_aes, u8 k[16], u8 r[16],
209e491eaf3SJohan Hedberg 		  u8 preq[7], u8 pres[7], u8 _iat, bdaddr_t *ia, u8 _rat,
210e491eaf3SJohan Hedberg 		  bdaddr_t *ra, u8 res[16])
211d22ef0bcSAnderson Briglia {
212d22ef0bcSAnderson Briglia 	u8 p1[16], p2[16];
213d22ef0bcSAnderson Briglia 	int err;
214d22ef0bcSAnderson Briglia 
215d22ef0bcSAnderson Briglia 	memset(p1, 0, 16);
216d22ef0bcSAnderson Briglia 
217d22ef0bcSAnderson Briglia 	/* p1 = pres || preq || _rat || _iat */
218943a732aSJohan Hedberg 	p1[0] = _iat;
219943a732aSJohan Hedberg 	p1[1] = _rat;
220943a732aSJohan Hedberg 	memcpy(p1 + 2, preq, 7);
221943a732aSJohan Hedberg 	memcpy(p1 + 9, pres, 7);
222d22ef0bcSAnderson Briglia 
223d22ef0bcSAnderson Briglia 	/* p2 = padding || ia || ra */
224943a732aSJohan Hedberg 	memcpy(p2, ra, 6);
225943a732aSJohan Hedberg 	memcpy(p2 + 6, ia, 6);
226943a732aSJohan Hedberg 	memset(p2 + 12, 0, 4);
227d22ef0bcSAnderson Briglia 
228d22ef0bcSAnderson Briglia 	/* res = r XOR p1 */
229d22ef0bcSAnderson Briglia 	u128_xor((u128 *) res, (u128 *) r, (u128 *) p1);
230d22ef0bcSAnderson Briglia 
231d22ef0bcSAnderson Briglia 	/* res = e(k, res) */
232e491eaf3SJohan Hedberg 	err = smp_e(tfm_aes, k, res);
233d22ef0bcSAnderson Briglia 	if (err) {
234d22ef0bcSAnderson Briglia 		BT_ERR("Encrypt data error");
235d22ef0bcSAnderson Briglia 		return err;
236d22ef0bcSAnderson Briglia 	}
237d22ef0bcSAnderson Briglia 
238d22ef0bcSAnderson Briglia 	/* res = res XOR p2 */
239d22ef0bcSAnderson Briglia 	u128_xor((u128 *) res, (u128 *) res, (u128 *) p2);
240d22ef0bcSAnderson Briglia 
241d22ef0bcSAnderson Briglia 	/* res = e(k, res) */
242e491eaf3SJohan Hedberg 	err = smp_e(tfm_aes, k, res);
243d22ef0bcSAnderson Briglia 	if (err)
244d22ef0bcSAnderson Briglia 		BT_ERR("Encrypt data error");
245d22ef0bcSAnderson Briglia 
246d22ef0bcSAnderson Briglia 	return err;
247d22ef0bcSAnderson Briglia }
248d22ef0bcSAnderson Briglia 
249e491eaf3SJohan Hedberg static int smp_s1(struct crypto_blkcipher *tfm_aes, u8 k[16], u8 r1[16],
250e491eaf3SJohan Hedberg 		  u8 r2[16], u8 _r[16])
251d22ef0bcSAnderson Briglia {
252d22ef0bcSAnderson Briglia 	int err;
253d22ef0bcSAnderson Briglia 
254d22ef0bcSAnderson Briglia 	/* Just least significant octets from r1 and r2 are considered */
255943a732aSJohan Hedberg 	memcpy(_r, r2, 8);
256943a732aSJohan Hedberg 	memcpy(_r + 8, r1, 8);
257d22ef0bcSAnderson Briglia 
258e491eaf3SJohan Hedberg 	err = smp_e(tfm_aes, k, _r);
259d22ef0bcSAnderson Briglia 	if (err)
260d22ef0bcSAnderson Briglia 		BT_ERR("Encrypt data error");
261d22ef0bcSAnderson Briglia 
262d22ef0bcSAnderson Briglia 	return err;
263d22ef0bcSAnderson Briglia }
264d22ef0bcSAnderson Briglia 
265eb492e01SAnderson Briglia static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
266eb492e01SAnderson Briglia {
2675d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
268b68fda68SJohan Hedberg 	struct smp_chan *smp;
2695d88cc73SJohan Hedberg 	struct kvec iv[2];
2705d88cc73SJohan Hedberg 	struct msghdr msg;
2715d88cc73SJohan Hedberg 
2725d88cc73SJohan Hedberg 	if (!chan)
2735d88cc73SJohan Hedberg 		return;
274eb492e01SAnderson Briglia 
275eb492e01SAnderson Briglia 	BT_DBG("code 0x%2.2x", code);
276eb492e01SAnderson Briglia 
2775d88cc73SJohan Hedberg 	iv[0].iov_base = &code;
2785d88cc73SJohan Hedberg 	iv[0].iov_len = 1;
279eb492e01SAnderson Briglia 
2805d88cc73SJohan Hedberg 	iv[1].iov_base = data;
2815d88cc73SJohan Hedberg 	iv[1].iov_len = len;
2825d88cc73SJohan Hedberg 
2835d88cc73SJohan Hedberg 	memset(&msg, 0, sizeof(msg));
2845d88cc73SJohan Hedberg 
2855d88cc73SJohan Hedberg 	msg.msg_iov = (struct iovec *) &iv;
2865d88cc73SJohan Hedberg 	msg.msg_iovlen = 2;
2875d88cc73SJohan Hedberg 
2885d88cc73SJohan Hedberg 	l2cap_chan_send(chan, &msg, 1 + len);
289e2dcd113SVinicius Costa Gomes 
290b68fda68SJohan Hedberg 	if (!chan->data)
291b68fda68SJohan Hedberg 		return;
292b68fda68SJohan Hedberg 
293b68fda68SJohan Hedberg 	smp = chan->data;
294b68fda68SJohan Hedberg 
295b68fda68SJohan Hedberg 	cancel_delayed_work_sync(&smp->security_timer);
296b68fda68SJohan Hedberg 	schedule_delayed_work(&smp->security_timer, SMP_TIMEOUT);
297eb492e01SAnderson Briglia }
298eb492e01SAnderson Briglia 
299d2eb9e10SJohan Hedberg static u8 authreq_to_seclevel(u8 authreq)
3002b64d153SBrian Gix {
301d2eb9e10SJohan Hedberg 	if (authreq & SMP_AUTH_MITM) {
302d2eb9e10SJohan Hedberg 		if (authreq & SMP_AUTH_SC)
303d2eb9e10SJohan Hedberg 			return BT_SECURITY_FIPS;
3042b64d153SBrian Gix 		else
305d2eb9e10SJohan Hedberg 			return BT_SECURITY_HIGH;
306d2eb9e10SJohan Hedberg 	} else {
3072b64d153SBrian Gix 		return BT_SECURITY_MEDIUM;
3082b64d153SBrian Gix 	}
309d2eb9e10SJohan Hedberg }
3102b64d153SBrian Gix 
3112b64d153SBrian Gix static __u8 seclevel_to_authreq(__u8 sec_level)
3122b64d153SBrian Gix {
3132b64d153SBrian Gix 	switch (sec_level) {
314d2eb9e10SJohan Hedberg 	case BT_SECURITY_FIPS:
3152b64d153SBrian Gix 	case BT_SECURITY_HIGH:
3162b64d153SBrian Gix 		return SMP_AUTH_MITM | SMP_AUTH_BONDING;
3172b64d153SBrian Gix 	case BT_SECURITY_MEDIUM:
3182b64d153SBrian Gix 		return SMP_AUTH_BONDING;
3192b64d153SBrian Gix 	default:
3202b64d153SBrian Gix 		return SMP_AUTH_NONE;
3212b64d153SBrian Gix 	}
3222b64d153SBrian Gix }
3232b64d153SBrian Gix 
324b8e66eacSVinicius Costa Gomes static void build_pairing_cmd(struct l2cap_conn *conn,
32554790f73SVinicius Costa Gomes 			      struct smp_cmd_pairing *req,
326f1560463SMarcel Holtmann 			      struct smp_cmd_pairing *rsp, __u8 authreq)
327b8e66eacSVinicius Costa Gomes {
3285d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
3295d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
330fd349c02SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
331fd349c02SJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
332fd349c02SJohan Hedberg 	u8 local_dist = 0, remote_dist = 0;
33354790f73SVinicius Costa Gomes 
334b6ae8457SJohan Hedberg 	if (test_bit(HCI_BONDABLE, &conn->hcon->hdev->dev_flags)) {
3357ee4ea36SMarcel Holtmann 		local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
3367ee4ea36SMarcel Holtmann 		remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
33754790f73SVinicius Costa Gomes 		authreq |= SMP_AUTH_BONDING;
3382b64d153SBrian Gix 	} else {
3392b64d153SBrian Gix 		authreq &= ~SMP_AUTH_BONDING;
34054790f73SVinicius Costa Gomes 	}
34154790f73SVinicius Costa Gomes 
342fd349c02SJohan Hedberg 	if (test_bit(HCI_RPA_RESOLVING, &hdev->dev_flags))
343fd349c02SJohan Hedberg 		remote_dist |= SMP_DIST_ID_KEY;
344fd349c02SJohan Hedberg 
345863efaf2SJohan Hedberg 	if (test_bit(HCI_PRIVACY, &hdev->dev_flags))
346863efaf2SJohan Hedberg 		local_dist |= SMP_DIST_ID_KEY;
347863efaf2SJohan Hedberg 
348df8e1a4cSJohan Hedberg 	if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) {
349df8e1a4cSJohan Hedberg 		if ((authreq & SMP_AUTH_SC) &&
350df8e1a4cSJohan Hedberg 		    test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
351df8e1a4cSJohan Hedberg 			local_dist |= SMP_DIST_LINK_KEY;
352df8e1a4cSJohan Hedberg 			remote_dist |= SMP_DIST_LINK_KEY;
353df8e1a4cSJohan Hedberg 		}
354df8e1a4cSJohan Hedberg 	} else {
355df8e1a4cSJohan Hedberg 		authreq &= ~SMP_AUTH_SC;
356df8e1a4cSJohan Hedberg 	}
357df8e1a4cSJohan Hedberg 
35854790f73SVinicius Costa Gomes 	if (rsp == NULL) {
35954790f73SVinicius Costa Gomes 		req->io_capability = conn->hcon->io_capability;
36054790f73SVinicius Costa Gomes 		req->oob_flag = SMP_OOB_NOT_PRESENT;
36154790f73SVinicius Costa Gomes 		req->max_key_size = SMP_MAX_ENC_KEY_SIZE;
362fd349c02SJohan Hedberg 		req->init_key_dist = local_dist;
363fd349c02SJohan Hedberg 		req->resp_key_dist = remote_dist;
3640edb14deSJohan Hedberg 		req->auth_req = (authreq & AUTH_REQ_MASK(hdev));
365fd349c02SJohan Hedberg 
366fd349c02SJohan Hedberg 		smp->remote_key_dist = remote_dist;
36754790f73SVinicius Costa Gomes 		return;
36854790f73SVinicius Costa Gomes 	}
36954790f73SVinicius Costa Gomes 
37054790f73SVinicius Costa Gomes 	rsp->io_capability = conn->hcon->io_capability;
37154790f73SVinicius Costa Gomes 	rsp->oob_flag = SMP_OOB_NOT_PRESENT;
37254790f73SVinicius Costa Gomes 	rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE;
373fd349c02SJohan Hedberg 	rsp->init_key_dist = req->init_key_dist & remote_dist;
374fd349c02SJohan Hedberg 	rsp->resp_key_dist = req->resp_key_dist & local_dist;
3750edb14deSJohan Hedberg 	rsp->auth_req = (authreq & AUTH_REQ_MASK(hdev));
376fd349c02SJohan Hedberg 
377fd349c02SJohan Hedberg 	smp->remote_key_dist = rsp->init_key_dist;
378b8e66eacSVinicius Costa Gomes }
379b8e66eacSVinicius Costa Gomes 
3803158c50cSVinicius Costa Gomes static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
3813158c50cSVinicius Costa Gomes {
3825d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
3835d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
3841c1def09SVinicius Costa Gomes 
3853158c50cSVinicius Costa Gomes 	if ((max_key_size > SMP_MAX_ENC_KEY_SIZE) ||
3863158c50cSVinicius Costa Gomes 	    (max_key_size < SMP_MIN_ENC_KEY_SIZE))
3873158c50cSVinicius Costa Gomes 		return SMP_ENC_KEY_SIZE;
3883158c50cSVinicius Costa Gomes 
389f7aa611aSVinicius Costa Gomes 	smp->enc_key_size = max_key_size;
3903158c50cSVinicius Costa Gomes 
3913158c50cSVinicius Costa Gomes 	return 0;
3923158c50cSVinicius Costa Gomes }
3933158c50cSVinicius Costa Gomes 
3946f48e260SJohan Hedberg static void smp_chan_destroy(struct l2cap_conn *conn)
3956f48e260SJohan Hedberg {
3966f48e260SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
3976f48e260SJohan Hedberg 	struct smp_chan *smp = chan->data;
3986f48e260SJohan Hedberg 	bool complete;
3996f48e260SJohan Hedberg 
4006f48e260SJohan Hedberg 	BUG_ON(!smp);
4016f48e260SJohan Hedberg 
4026f48e260SJohan Hedberg 	cancel_delayed_work_sync(&smp->security_timer);
4036f48e260SJohan Hedberg 
4046f48e260SJohan Hedberg 	complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags);
4056f48e260SJohan Hedberg 	mgmt_smp_complete(conn->hcon, complete);
4066f48e260SJohan Hedberg 
4076f48e260SJohan Hedberg 	kfree(smp->csrk);
4086f48e260SJohan Hedberg 	kfree(smp->slave_csrk);
4096f48e260SJohan Hedberg 
4106f48e260SJohan Hedberg 	crypto_free_blkcipher(smp->tfm_aes);
411407cecf6SJohan Hedberg 	crypto_free_hash(smp->tfm_cmac);
4126f48e260SJohan Hedberg 
4136f48e260SJohan Hedberg 	/* If pairing failed clean up any keys we might have */
4146f48e260SJohan Hedberg 	if (!complete) {
4156f48e260SJohan Hedberg 		if (smp->ltk) {
416970d0f1bSJohan Hedberg 			list_del_rcu(&smp->ltk->list);
417970d0f1bSJohan Hedberg 			kfree_rcu(smp->ltk, rcu);
4186f48e260SJohan Hedberg 		}
4196f48e260SJohan Hedberg 
4206f48e260SJohan Hedberg 		if (smp->slave_ltk) {
421970d0f1bSJohan Hedberg 			list_del_rcu(&smp->slave_ltk->list);
422970d0f1bSJohan Hedberg 			kfree_rcu(smp->slave_ltk, rcu);
4236f48e260SJohan Hedberg 		}
4246f48e260SJohan Hedberg 
4256f48e260SJohan Hedberg 		if (smp->remote_irk) {
426adae20cbSJohan Hedberg 			list_del_rcu(&smp->remote_irk->list);
427adae20cbSJohan Hedberg 			kfree_rcu(smp->remote_irk, rcu);
4286f48e260SJohan Hedberg 		}
4296f48e260SJohan Hedberg 	}
4306f48e260SJohan Hedberg 
4316f48e260SJohan Hedberg 	chan->data = NULL;
4326f48e260SJohan Hedberg 	kfree(smp);
4336f48e260SJohan Hedberg 	hci_conn_drop(conn->hcon);
4346f48e260SJohan Hedberg }
4356f48e260SJohan Hedberg 
43684794e11SJohan Hedberg static void smp_failure(struct l2cap_conn *conn, u8 reason)
4374f957a76SBrian Gix {
438bab73cb6SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
439b68fda68SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
440bab73cb6SJohan Hedberg 
44184794e11SJohan Hedberg 	if (reason)
4424f957a76SBrian Gix 		smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
4434f957a76SBrian Gix 			     &reason);
4444f957a76SBrian Gix 
445ce39fb4eSMarcel Holtmann 	clear_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags);
446e1e930f5SJohan Hedberg 	mgmt_auth_failed(hcon, HCI_ERROR_AUTH_FAILURE);
447f1c09c07SVinicius Costa Gomes 
448fc75cc86SJohan Hedberg 	if (chan->data)
4494f957a76SBrian Gix 		smp_chan_destroy(conn);
4504f957a76SBrian Gix }
4514f957a76SBrian Gix 
4522b64d153SBrian Gix #define JUST_WORKS	0x00
4532b64d153SBrian Gix #define JUST_CFM	0x01
4542b64d153SBrian Gix #define REQ_PASSKEY	0x02
4552b64d153SBrian Gix #define CFM_PASSKEY	0x03
4562b64d153SBrian Gix #define REQ_OOB		0x04
4572b64d153SBrian Gix #define OVERLAP		0xFF
4582b64d153SBrian Gix 
4592b64d153SBrian Gix static const u8 gen_method[5][5] = {
4602b64d153SBrian Gix 	{ JUST_WORKS,  JUST_CFM,    REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
4612b64d153SBrian Gix 	{ JUST_WORKS,  JUST_CFM,    REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
4622b64d153SBrian Gix 	{ CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
4632b64d153SBrian Gix 	{ JUST_WORKS,  JUST_CFM,    JUST_WORKS,  JUST_WORKS, JUST_CFM    },
4642b64d153SBrian Gix 	{ CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, OVERLAP     },
4652b64d153SBrian Gix };
4662b64d153SBrian Gix 
467581370ccSJohan Hedberg static u8 get_auth_method(struct smp_chan *smp, u8 local_io, u8 remote_io)
468581370ccSJohan Hedberg {
4692bcd4003SJohan Hedberg 	/* If either side has unknown io_caps, use JUST_CFM (which gets
4702bcd4003SJohan Hedberg 	 * converted later to JUST_WORKS if we're initiators.
4712bcd4003SJohan Hedberg 	 */
472581370ccSJohan Hedberg 	if (local_io > SMP_IO_KEYBOARD_DISPLAY ||
473581370ccSJohan Hedberg 	    remote_io > SMP_IO_KEYBOARD_DISPLAY)
4742bcd4003SJohan Hedberg 		return JUST_CFM;
475581370ccSJohan Hedberg 
476581370ccSJohan Hedberg 	return gen_method[remote_io][local_io];
477581370ccSJohan Hedberg }
478581370ccSJohan Hedberg 
4792b64d153SBrian Gix static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
4802b64d153SBrian Gix 						u8 local_io, u8 remote_io)
4812b64d153SBrian Gix {
4822b64d153SBrian Gix 	struct hci_conn *hcon = conn->hcon;
4835d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
4845d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
4852b64d153SBrian Gix 	u8 method;
4862b64d153SBrian Gix 	u32 passkey = 0;
4872b64d153SBrian Gix 	int ret = 0;
4882b64d153SBrian Gix 
4892b64d153SBrian Gix 	/* Initialize key for JUST WORKS */
4902b64d153SBrian Gix 	memset(smp->tk, 0, sizeof(smp->tk));
4914a74d658SJohan Hedberg 	clear_bit(SMP_FLAG_TK_VALID, &smp->flags);
4922b64d153SBrian Gix 
4932b64d153SBrian Gix 	BT_DBG("tk_request: auth:%d lcl:%d rem:%d", auth, local_io, remote_io);
4942b64d153SBrian Gix 
4952bcd4003SJohan Hedberg 	/* If neither side wants MITM, either "just" confirm an incoming
4962bcd4003SJohan Hedberg 	 * request or use just-works for outgoing ones. The JUST_CFM
4972bcd4003SJohan Hedberg 	 * will be converted to JUST_WORKS if necessary later in this
4982bcd4003SJohan Hedberg 	 * function. If either side has MITM look up the method from the
4992bcd4003SJohan Hedberg 	 * table.
5002bcd4003SJohan Hedberg 	 */
501581370ccSJohan Hedberg 	if (!(auth & SMP_AUTH_MITM))
5022bcd4003SJohan Hedberg 		method = JUST_CFM;
5032b64d153SBrian Gix 	else
504581370ccSJohan Hedberg 		method = get_auth_method(smp, local_io, remote_io);
5052b64d153SBrian Gix 
506a82505c7SJohan Hedberg 	/* Don't confirm locally initiated pairing attempts */
5074a74d658SJohan Hedberg 	if (method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR, &smp->flags))
508a82505c7SJohan Hedberg 		method = JUST_WORKS;
509a82505c7SJohan Hedberg 
51002f3e254SJohan Hedberg 	/* Don't bother user space with no IO capabilities */
51102f3e254SJohan Hedberg 	if (method == JUST_CFM && hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
51202f3e254SJohan Hedberg 		method = JUST_WORKS;
51302f3e254SJohan Hedberg 
5142b64d153SBrian Gix 	/* If Just Works, Continue with Zero TK */
5152b64d153SBrian Gix 	if (method == JUST_WORKS) {
5164a74d658SJohan Hedberg 		set_bit(SMP_FLAG_TK_VALID, &smp->flags);
5172b64d153SBrian Gix 		return 0;
5182b64d153SBrian Gix 	}
5192b64d153SBrian Gix 
5202b64d153SBrian Gix 	/* Not Just Works/Confirm results in MITM Authentication */
5215eb596f5SJohan Hedberg 	if (method != JUST_CFM) {
5224a74d658SJohan Hedberg 		set_bit(SMP_FLAG_MITM_AUTH, &smp->flags);
5235eb596f5SJohan Hedberg 		if (hcon->pending_sec_level < BT_SECURITY_HIGH)
5245eb596f5SJohan Hedberg 			hcon->pending_sec_level = BT_SECURITY_HIGH;
5255eb596f5SJohan Hedberg 	}
5262b64d153SBrian Gix 
5272b64d153SBrian Gix 	/* If both devices have Keyoard-Display I/O, the master
5282b64d153SBrian Gix 	 * Confirms and the slave Enters the passkey.
5292b64d153SBrian Gix 	 */
5302b64d153SBrian Gix 	if (method == OVERLAP) {
53140bef302SJohan Hedberg 		if (hcon->role == HCI_ROLE_MASTER)
5322b64d153SBrian Gix 			method = CFM_PASSKEY;
5332b64d153SBrian Gix 		else
5342b64d153SBrian Gix 			method = REQ_PASSKEY;
5352b64d153SBrian Gix 	}
5362b64d153SBrian Gix 
53701ad34d2SJohan Hedberg 	/* Generate random passkey. */
5382b64d153SBrian Gix 	if (method == CFM_PASSKEY) {
539943a732aSJohan Hedberg 		memset(smp->tk, 0, sizeof(smp->tk));
5402b64d153SBrian Gix 		get_random_bytes(&passkey, sizeof(passkey));
5412b64d153SBrian Gix 		passkey %= 1000000;
542943a732aSJohan Hedberg 		put_unaligned_le32(passkey, smp->tk);
5432b64d153SBrian Gix 		BT_DBG("PassKey: %d", passkey);
5444a74d658SJohan Hedberg 		set_bit(SMP_FLAG_TK_VALID, &smp->flags);
5452b64d153SBrian Gix 	}
5462b64d153SBrian Gix 
5472b64d153SBrian Gix 	if (method == REQ_PASSKEY)
548ce39fb4eSMarcel Holtmann 		ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst,
549272d90dfSJohan Hedberg 						hcon->type, hcon->dst_type);
5504eb65e66SJohan Hedberg 	else if (method == JUST_CFM)
5514eb65e66SJohan Hedberg 		ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
5524eb65e66SJohan Hedberg 						hcon->type, hcon->dst_type,
5534eb65e66SJohan Hedberg 						passkey, 1);
5542b64d153SBrian Gix 	else
55501ad34d2SJohan Hedberg 		ret = mgmt_user_passkey_notify(hcon->hdev, &hcon->dst,
556272d90dfSJohan Hedberg 						hcon->type, hcon->dst_type,
55739adbffeSJohan Hedberg 						passkey, 0);
5582b64d153SBrian Gix 
5592b64d153SBrian Gix 	return ret;
5602b64d153SBrian Gix }
5612b64d153SBrian Gix 
5621cc61144SJohan Hedberg static u8 smp_confirm(struct smp_chan *smp)
5638aab4757SVinicius Costa Gomes {
5648aab4757SVinicius Costa Gomes 	struct l2cap_conn *conn = smp->conn;
5658aab4757SVinicius Costa Gomes 	struct smp_cmd_pairing_confirm cp;
5668aab4757SVinicius Costa Gomes 	int ret;
5678aab4757SVinicius Costa Gomes 
5688aab4757SVinicius Costa Gomes 	BT_DBG("conn %p", conn);
5698aab4757SVinicius Costa Gomes 
570e491eaf3SJohan Hedberg 	ret = smp_c1(smp->tfm_aes, smp->tk, smp->prnd, smp->preq, smp->prsp,
571b1cd5fd9SJohan Hedberg 		     conn->hcon->init_addr_type, &conn->hcon->init_addr,
572943a732aSJohan Hedberg 		     conn->hcon->resp_addr_type, &conn->hcon->resp_addr,
573943a732aSJohan Hedberg 		     cp.confirm_val);
5741cc61144SJohan Hedberg 	if (ret)
5751cc61144SJohan Hedberg 		return SMP_UNSPECIFIED;
5768aab4757SVinicius Costa Gomes 
5774a74d658SJohan Hedberg 	clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
5782b64d153SBrian Gix 
5798aab4757SVinicius Costa Gomes 	smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
5808aab4757SVinicius Costa Gomes 
581b28b4943SJohan Hedberg 	if (conn->hcon->out)
582b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
583b28b4943SJohan Hedberg 	else
584b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
585b28b4943SJohan Hedberg 
5861cc61144SJohan Hedberg 	return 0;
5878aab4757SVinicius Costa Gomes }
5888aab4757SVinicius Costa Gomes 
589861580a9SJohan Hedberg static u8 smp_random(struct smp_chan *smp)
5908aab4757SVinicius Costa Gomes {
5918aab4757SVinicius Costa Gomes 	struct l2cap_conn *conn = smp->conn;
5928aab4757SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
593861580a9SJohan Hedberg 	u8 confirm[16];
5948aab4757SVinicius Costa Gomes 	int ret;
5958aab4757SVinicius Costa Gomes 
596ec70f36fSJohan Hedberg 	if (IS_ERR_OR_NULL(smp->tfm_aes))
597861580a9SJohan Hedberg 		return SMP_UNSPECIFIED;
5988aab4757SVinicius Costa Gomes 
5998aab4757SVinicius Costa Gomes 	BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
6008aab4757SVinicius Costa Gomes 
601e491eaf3SJohan Hedberg 	ret = smp_c1(smp->tfm_aes, smp->tk, smp->rrnd, smp->preq, smp->prsp,
602b1cd5fd9SJohan Hedberg 		     hcon->init_addr_type, &hcon->init_addr,
603943a732aSJohan Hedberg 		     hcon->resp_addr_type, &hcon->resp_addr, confirm);
604861580a9SJohan Hedberg 	if (ret)
605861580a9SJohan Hedberg 		return SMP_UNSPECIFIED;
6068aab4757SVinicius Costa Gomes 
6078aab4757SVinicius Costa Gomes 	if (memcmp(smp->pcnf, confirm, sizeof(smp->pcnf)) != 0) {
6088aab4757SVinicius Costa Gomes 		BT_ERR("Pairing failed (confirmation values mismatch)");
609861580a9SJohan Hedberg 		return SMP_CONFIRM_FAILED;
6108aab4757SVinicius Costa Gomes 	}
6118aab4757SVinicius Costa Gomes 
6128aab4757SVinicius Costa Gomes 	if (hcon->out) {
613fe39c7b2SMarcel Holtmann 		u8 stk[16];
614fe39c7b2SMarcel Holtmann 		__le64 rand = 0;
615fe39c7b2SMarcel Holtmann 		__le16 ediv = 0;
6168aab4757SVinicius Costa Gomes 
617e491eaf3SJohan Hedberg 		smp_s1(smp->tfm_aes, smp->tk, smp->rrnd, smp->prnd, stk);
6188aab4757SVinicius Costa Gomes 
619f7aa611aSVinicius Costa Gomes 		memset(stk + smp->enc_key_size, 0,
620f7aa611aSVinicius Costa Gomes 		       SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
6218aab4757SVinicius Costa Gomes 
622861580a9SJohan Hedberg 		if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
623861580a9SJohan Hedberg 			return SMP_UNSPECIFIED;
6248aab4757SVinicius Costa Gomes 
6258aab4757SVinicius Costa Gomes 		hci_le_start_enc(hcon, ediv, rand, stk);
626f7aa611aSVinicius Costa Gomes 		hcon->enc_key_size = smp->enc_key_size;
627fe59a05fSJohan Hedberg 		set_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags);
6288aab4757SVinicius Costa Gomes 	} else {
629fff3490fSJohan Hedberg 		u8 stk[16], auth;
630fe39c7b2SMarcel Holtmann 		__le64 rand = 0;
631fe39c7b2SMarcel Holtmann 		__le16 ediv = 0;
6328aab4757SVinicius Costa Gomes 
633943a732aSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
634943a732aSJohan Hedberg 			     smp->prnd);
6358aab4757SVinicius Costa Gomes 
636e491eaf3SJohan Hedberg 		smp_s1(smp->tfm_aes, smp->tk, smp->prnd, smp->rrnd, stk);
6378aab4757SVinicius Costa Gomes 
638f7aa611aSVinicius Costa Gomes 		memset(stk + smp->enc_key_size, 0,
639f7aa611aSVinicius Costa Gomes 		       SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
6408aab4757SVinicius Costa Gomes 
641fff3490fSJohan Hedberg 		if (hcon->pending_sec_level == BT_SECURITY_HIGH)
642fff3490fSJohan Hedberg 			auth = 1;
643fff3490fSJohan Hedberg 		else
644fff3490fSJohan Hedberg 			auth = 0;
645fff3490fSJohan Hedberg 
6467d5843b7SJohan Hedberg 		/* Even though there's no _SLAVE suffix this is the
6477d5843b7SJohan Hedberg 		 * slave STK we're adding for later lookup (the master
6487d5843b7SJohan Hedberg 		 * STK never needs to be stored).
6497d5843b7SJohan Hedberg 		 */
650ce39fb4eSMarcel Holtmann 		hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
6512ceba539SJohan Hedberg 			    SMP_STK, auth, stk, smp->enc_key_size, ediv, rand);
6528aab4757SVinicius Costa Gomes 	}
6538aab4757SVinicius Costa Gomes 
654861580a9SJohan Hedberg 	return 0;
6558aab4757SVinicius Costa Gomes }
6568aab4757SVinicius Costa Gomes 
65744f1a7abSJohan Hedberg static void smp_notify_keys(struct l2cap_conn *conn)
65844f1a7abSJohan Hedberg {
65944f1a7abSJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
66044f1a7abSJohan Hedberg 	struct smp_chan *smp = chan->data;
66144f1a7abSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
66244f1a7abSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
66344f1a7abSJohan Hedberg 	struct smp_cmd_pairing *req = (void *) &smp->preq[1];
66444f1a7abSJohan Hedberg 	struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1];
66544f1a7abSJohan Hedberg 	bool persistent;
66644f1a7abSJohan Hedberg 
66744f1a7abSJohan Hedberg 	if (smp->remote_irk) {
66844f1a7abSJohan Hedberg 		mgmt_new_irk(hdev, smp->remote_irk);
66944f1a7abSJohan Hedberg 		/* Now that user space can be considered to know the
67044f1a7abSJohan Hedberg 		 * identity address track the connection based on it
67144f1a7abSJohan Hedberg 		 * from now on.
67244f1a7abSJohan Hedberg 		 */
67344f1a7abSJohan Hedberg 		bacpy(&hcon->dst, &smp->remote_irk->bdaddr);
67444f1a7abSJohan Hedberg 		hcon->dst_type = smp->remote_irk->addr_type;
675f3d82d0cSJohan Hedberg 		queue_work(hdev->workqueue, &conn->id_addr_update_work);
67644f1a7abSJohan Hedberg 
67744f1a7abSJohan Hedberg 		/* When receiving an indentity resolving key for
67844f1a7abSJohan Hedberg 		 * a remote device that does not use a resolvable
67944f1a7abSJohan Hedberg 		 * private address, just remove the key so that
68044f1a7abSJohan Hedberg 		 * it is possible to use the controller white
68144f1a7abSJohan Hedberg 		 * list for scanning.
68244f1a7abSJohan Hedberg 		 *
68344f1a7abSJohan Hedberg 		 * Userspace will have been told to not store
68444f1a7abSJohan Hedberg 		 * this key at this point. So it is safe to
68544f1a7abSJohan Hedberg 		 * just remove it.
68644f1a7abSJohan Hedberg 		 */
68744f1a7abSJohan Hedberg 		if (!bacmp(&smp->remote_irk->rpa, BDADDR_ANY)) {
688adae20cbSJohan Hedberg 			list_del_rcu(&smp->remote_irk->list);
689adae20cbSJohan Hedberg 			kfree_rcu(smp->remote_irk, rcu);
69044f1a7abSJohan Hedberg 			smp->remote_irk = NULL;
69144f1a7abSJohan Hedberg 		}
69244f1a7abSJohan Hedberg 	}
69344f1a7abSJohan Hedberg 
69444f1a7abSJohan Hedberg 	/* The LTKs and CSRKs should be persistent only if both sides
69544f1a7abSJohan Hedberg 	 * had the bonding bit set in their authentication requests.
69644f1a7abSJohan Hedberg 	 */
69744f1a7abSJohan Hedberg 	persistent = !!((req->auth_req & rsp->auth_req) & SMP_AUTH_BONDING);
69844f1a7abSJohan Hedberg 
69944f1a7abSJohan Hedberg 	if (smp->csrk) {
70044f1a7abSJohan Hedberg 		smp->csrk->bdaddr_type = hcon->dst_type;
70144f1a7abSJohan Hedberg 		bacpy(&smp->csrk->bdaddr, &hcon->dst);
70244f1a7abSJohan Hedberg 		mgmt_new_csrk(hdev, smp->csrk, persistent);
70344f1a7abSJohan Hedberg 	}
70444f1a7abSJohan Hedberg 
70544f1a7abSJohan Hedberg 	if (smp->slave_csrk) {
70644f1a7abSJohan Hedberg 		smp->slave_csrk->bdaddr_type = hcon->dst_type;
70744f1a7abSJohan Hedberg 		bacpy(&smp->slave_csrk->bdaddr, &hcon->dst);
70844f1a7abSJohan Hedberg 		mgmt_new_csrk(hdev, smp->slave_csrk, persistent);
70944f1a7abSJohan Hedberg 	}
71044f1a7abSJohan Hedberg 
71144f1a7abSJohan Hedberg 	if (smp->ltk) {
71244f1a7abSJohan Hedberg 		smp->ltk->bdaddr_type = hcon->dst_type;
71344f1a7abSJohan Hedberg 		bacpy(&smp->ltk->bdaddr, &hcon->dst);
71444f1a7abSJohan Hedberg 		mgmt_new_ltk(hdev, smp->ltk, persistent);
71544f1a7abSJohan Hedberg 	}
71644f1a7abSJohan Hedberg 
71744f1a7abSJohan Hedberg 	if (smp->slave_ltk) {
71844f1a7abSJohan Hedberg 		smp->slave_ltk->bdaddr_type = hcon->dst_type;
71944f1a7abSJohan Hedberg 		bacpy(&smp->slave_ltk->bdaddr, &hcon->dst);
72044f1a7abSJohan Hedberg 		mgmt_new_ltk(hdev, smp->slave_ltk, persistent);
72144f1a7abSJohan Hedberg 	}
72244f1a7abSJohan Hedberg }
72344f1a7abSJohan Hedberg 
724b28b4943SJohan Hedberg static void smp_allow_key_dist(struct smp_chan *smp)
725b28b4943SJohan Hedberg {
726b28b4943SJohan Hedberg 	/* Allow the first expected phase 3 PDU. The rest of the PDUs
727b28b4943SJohan Hedberg 	 * will be allowed in each PDU handler to ensure we receive
728b28b4943SJohan Hedberg 	 * them in the correct order.
729b28b4943SJohan Hedberg 	 */
730b28b4943SJohan Hedberg 	if (smp->remote_key_dist & SMP_DIST_ENC_KEY)
731b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_ENCRYPT_INFO);
732b28b4943SJohan Hedberg 	else if (smp->remote_key_dist & SMP_DIST_ID_KEY)
733b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO);
734b28b4943SJohan Hedberg 	else if (smp->remote_key_dist & SMP_DIST_SIGN)
735b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO);
736b28b4943SJohan Hedberg }
737b28b4943SJohan Hedberg 
738d6268e86SJohan Hedberg static void smp_distribute_keys(struct smp_chan *smp)
73944f1a7abSJohan Hedberg {
74044f1a7abSJohan Hedberg 	struct smp_cmd_pairing *req, *rsp;
74186d1407cSJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
74244f1a7abSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
74344f1a7abSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
74444f1a7abSJohan Hedberg 	__u8 *keydist;
74544f1a7abSJohan Hedberg 
74644f1a7abSJohan Hedberg 	BT_DBG("conn %p", conn);
74744f1a7abSJohan Hedberg 
74844f1a7abSJohan Hedberg 	rsp = (void *) &smp->prsp[1];
74944f1a7abSJohan Hedberg 
75044f1a7abSJohan Hedberg 	/* The responder sends its keys first */
751b28b4943SJohan Hedberg 	if (hcon->out && (smp->remote_key_dist & KEY_DIST_MASK)) {
752b28b4943SJohan Hedberg 		smp_allow_key_dist(smp);
75386d1407cSJohan Hedberg 		return;
754b28b4943SJohan Hedberg 	}
75544f1a7abSJohan Hedberg 
75644f1a7abSJohan Hedberg 	req = (void *) &smp->preq[1];
75744f1a7abSJohan Hedberg 
75844f1a7abSJohan Hedberg 	if (hcon->out) {
75944f1a7abSJohan Hedberg 		keydist = &rsp->init_key_dist;
76044f1a7abSJohan Hedberg 		*keydist &= req->init_key_dist;
76144f1a7abSJohan Hedberg 	} else {
76244f1a7abSJohan Hedberg 		keydist = &rsp->resp_key_dist;
76344f1a7abSJohan Hedberg 		*keydist &= req->resp_key_dist;
76444f1a7abSJohan Hedberg 	}
76544f1a7abSJohan Hedberg 
76644f1a7abSJohan Hedberg 	BT_DBG("keydist 0x%x", *keydist);
76744f1a7abSJohan Hedberg 
76844f1a7abSJohan Hedberg 	if (*keydist & SMP_DIST_ENC_KEY) {
76944f1a7abSJohan Hedberg 		struct smp_cmd_encrypt_info enc;
77044f1a7abSJohan Hedberg 		struct smp_cmd_master_ident ident;
77144f1a7abSJohan Hedberg 		struct smp_ltk *ltk;
77244f1a7abSJohan Hedberg 		u8 authenticated;
77344f1a7abSJohan Hedberg 		__le16 ediv;
77444f1a7abSJohan Hedberg 		__le64 rand;
77544f1a7abSJohan Hedberg 
77644f1a7abSJohan Hedberg 		get_random_bytes(enc.ltk, sizeof(enc.ltk));
77744f1a7abSJohan Hedberg 		get_random_bytes(&ediv, sizeof(ediv));
77844f1a7abSJohan Hedberg 		get_random_bytes(&rand, sizeof(rand));
77944f1a7abSJohan Hedberg 
78044f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
78144f1a7abSJohan Hedberg 
78244f1a7abSJohan Hedberg 		authenticated = hcon->sec_level == BT_SECURITY_HIGH;
78344f1a7abSJohan Hedberg 		ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type,
78444f1a7abSJohan Hedberg 				  SMP_LTK_SLAVE, authenticated, enc.ltk,
78544f1a7abSJohan Hedberg 				  smp->enc_key_size, ediv, rand);
78644f1a7abSJohan Hedberg 		smp->slave_ltk = ltk;
78744f1a7abSJohan Hedberg 
78844f1a7abSJohan Hedberg 		ident.ediv = ediv;
78944f1a7abSJohan Hedberg 		ident.rand = rand;
79044f1a7abSJohan Hedberg 
79144f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident);
79244f1a7abSJohan Hedberg 
79344f1a7abSJohan Hedberg 		*keydist &= ~SMP_DIST_ENC_KEY;
79444f1a7abSJohan Hedberg 	}
79544f1a7abSJohan Hedberg 
79644f1a7abSJohan Hedberg 	if (*keydist & SMP_DIST_ID_KEY) {
79744f1a7abSJohan Hedberg 		struct smp_cmd_ident_addr_info addrinfo;
79844f1a7abSJohan Hedberg 		struct smp_cmd_ident_info idinfo;
79944f1a7abSJohan Hedberg 
80044f1a7abSJohan Hedberg 		memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk));
80144f1a7abSJohan Hedberg 
80244f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo);
80344f1a7abSJohan Hedberg 
80444f1a7abSJohan Hedberg 		/* The hci_conn contains the local identity address
80544f1a7abSJohan Hedberg 		 * after the connection has been established.
80644f1a7abSJohan Hedberg 		 *
80744f1a7abSJohan Hedberg 		 * This is true even when the connection has been
80844f1a7abSJohan Hedberg 		 * established using a resolvable random address.
80944f1a7abSJohan Hedberg 		 */
81044f1a7abSJohan Hedberg 		bacpy(&addrinfo.bdaddr, &hcon->src);
81144f1a7abSJohan Hedberg 		addrinfo.addr_type = hcon->src_type;
81244f1a7abSJohan Hedberg 
81344f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo),
81444f1a7abSJohan Hedberg 			     &addrinfo);
81544f1a7abSJohan Hedberg 
81644f1a7abSJohan Hedberg 		*keydist &= ~SMP_DIST_ID_KEY;
81744f1a7abSJohan Hedberg 	}
81844f1a7abSJohan Hedberg 
81944f1a7abSJohan Hedberg 	if (*keydist & SMP_DIST_SIGN) {
82044f1a7abSJohan Hedberg 		struct smp_cmd_sign_info sign;
82144f1a7abSJohan Hedberg 		struct smp_csrk *csrk;
82244f1a7abSJohan Hedberg 
82344f1a7abSJohan Hedberg 		/* Generate a new random key */
82444f1a7abSJohan Hedberg 		get_random_bytes(sign.csrk, sizeof(sign.csrk));
82544f1a7abSJohan Hedberg 
82644f1a7abSJohan Hedberg 		csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
82744f1a7abSJohan Hedberg 		if (csrk) {
82844f1a7abSJohan Hedberg 			csrk->master = 0x00;
82944f1a7abSJohan Hedberg 			memcpy(csrk->val, sign.csrk, sizeof(csrk->val));
83044f1a7abSJohan Hedberg 		}
83144f1a7abSJohan Hedberg 		smp->slave_csrk = csrk;
83244f1a7abSJohan Hedberg 
83344f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign);
83444f1a7abSJohan Hedberg 
83544f1a7abSJohan Hedberg 		*keydist &= ~SMP_DIST_SIGN;
83644f1a7abSJohan Hedberg 	}
83744f1a7abSJohan Hedberg 
83844f1a7abSJohan Hedberg 	/* If there are still keys to be received wait for them */
839b28b4943SJohan Hedberg 	if (smp->remote_key_dist & KEY_DIST_MASK) {
840b28b4943SJohan Hedberg 		smp_allow_key_dist(smp);
84186d1407cSJohan Hedberg 		return;
842b28b4943SJohan Hedberg 	}
84344f1a7abSJohan Hedberg 
84444f1a7abSJohan Hedberg 	set_bit(SMP_FLAG_COMPLETE, &smp->flags);
84544f1a7abSJohan Hedberg 	smp_notify_keys(conn);
84644f1a7abSJohan Hedberg 
84744f1a7abSJohan Hedberg 	smp_chan_destroy(conn);
84844f1a7abSJohan Hedberg }
84944f1a7abSJohan Hedberg 
850b68fda68SJohan Hedberg static void smp_timeout(struct work_struct *work)
851b68fda68SJohan Hedberg {
852b68fda68SJohan Hedberg 	struct smp_chan *smp = container_of(work, struct smp_chan,
853b68fda68SJohan Hedberg 					    security_timer.work);
854b68fda68SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
855b68fda68SJohan Hedberg 
856b68fda68SJohan Hedberg 	BT_DBG("conn %p", conn);
857b68fda68SJohan Hedberg 
8581e91c29eSJohan Hedberg 	hci_disconnect(conn->hcon, HCI_ERROR_REMOTE_USER_TERM);
859b68fda68SJohan Hedberg }
860b68fda68SJohan Hedberg 
8618aab4757SVinicius Costa Gomes static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
8628aab4757SVinicius Costa Gomes {
8635d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
8648aab4757SVinicius Costa Gomes 	struct smp_chan *smp;
8658aab4757SVinicius Costa Gomes 
866f1560463SMarcel Holtmann 	smp = kzalloc(sizeof(*smp), GFP_ATOMIC);
867fc75cc86SJohan Hedberg 	if (!smp)
8688aab4757SVinicius Costa Gomes 		return NULL;
8698aab4757SVinicius Costa Gomes 
8706a7bd103SJohan Hedberg 	smp->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
8716a7bd103SJohan Hedberg 	if (IS_ERR(smp->tfm_aes)) {
8726a7bd103SJohan Hedberg 		BT_ERR("Unable to create ECB crypto context");
8736a7bd103SJohan Hedberg 		kfree(smp);
8746a7bd103SJohan Hedberg 		return NULL;
8756a7bd103SJohan Hedberg 	}
8766a7bd103SJohan Hedberg 
877407cecf6SJohan Hedberg 	smp->tfm_cmac = crypto_alloc_hash("cmac(aes)", 0, CRYPTO_ALG_ASYNC);
878407cecf6SJohan Hedberg 	if (IS_ERR(smp->tfm_cmac)) {
879407cecf6SJohan Hedberg 		BT_ERR("Unable to create CMAC crypto context");
880407cecf6SJohan Hedberg 		crypto_free_blkcipher(smp->tfm_aes);
881407cecf6SJohan Hedberg 		kfree(smp);
882407cecf6SJohan Hedberg 		return NULL;
883407cecf6SJohan Hedberg 	}
884407cecf6SJohan Hedberg 
8858aab4757SVinicius Costa Gomes 	smp->conn = conn;
8865d88cc73SJohan Hedberg 	chan->data = smp;
8878aab4757SVinicius Costa Gomes 
888b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_FAIL);
889b28b4943SJohan Hedberg 
890b68fda68SJohan Hedberg 	INIT_DELAYED_WORK(&smp->security_timer, smp_timeout);
891b68fda68SJohan Hedberg 
8928aab4757SVinicius Costa Gomes 	hci_conn_hold(conn->hcon);
8938aab4757SVinicius Costa Gomes 
8948aab4757SVinicius Costa Gomes 	return smp;
8958aab4757SVinicius Costa Gomes }
8968aab4757SVinicius Costa Gomes 
8972b64d153SBrian Gix int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
8982b64d153SBrian Gix {
899b10e8017SJohan Hedberg 	struct l2cap_conn *conn = hcon->l2cap_data;
9005d88cc73SJohan Hedberg 	struct l2cap_chan *chan;
9012b64d153SBrian Gix 	struct smp_chan *smp;
9022b64d153SBrian Gix 	u32 value;
903fc75cc86SJohan Hedberg 	int err;
9042b64d153SBrian Gix 
9052b64d153SBrian Gix 	BT_DBG("");
9062b64d153SBrian Gix 
907fc75cc86SJohan Hedberg 	if (!conn)
9082b64d153SBrian Gix 		return -ENOTCONN;
9092b64d153SBrian Gix 
9105d88cc73SJohan Hedberg 	chan = conn->smp;
9115d88cc73SJohan Hedberg 	if (!chan)
9125d88cc73SJohan Hedberg 		return -ENOTCONN;
9135d88cc73SJohan Hedberg 
914fc75cc86SJohan Hedberg 	l2cap_chan_lock(chan);
915fc75cc86SJohan Hedberg 	if (!chan->data) {
916fc75cc86SJohan Hedberg 		err = -ENOTCONN;
917fc75cc86SJohan Hedberg 		goto unlock;
918fc75cc86SJohan Hedberg 	}
919fc75cc86SJohan Hedberg 
9205d88cc73SJohan Hedberg 	smp = chan->data;
9212b64d153SBrian Gix 
9222b64d153SBrian Gix 	switch (mgmt_op) {
9232b64d153SBrian Gix 	case MGMT_OP_USER_PASSKEY_REPLY:
9242b64d153SBrian Gix 		value = le32_to_cpu(passkey);
925943a732aSJohan Hedberg 		memset(smp->tk, 0, sizeof(smp->tk));
9262b64d153SBrian Gix 		BT_DBG("PassKey: %d", value);
927943a732aSJohan Hedberg 		put_unaligned_le32(value, smp->tk);
9282b64d153SBrian Gix 		/* Fall Through */
9292b64d153SBrian Gix 	case MGMT_OP_USER_CONFIRM_REPLY:
9304a74d658SJohan Hedberg 		set_bit(SMP_FLAG_TK_VALID, &smp->flags);
9312b64d153SBrian Gix 		break;
9322b64d153SBrian Gix 	case MGMT_OP_USER_PASSKEY_NEG_REPLY:
9332b64d153SBrian Gix 	case MGMT_OP_USER_CONFIRM_NEG_REPLY:
93484794e11SJohan Hedberg 		smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
935fc75cc86SJohan Hedberg 		err = 0;
936fc75cc86SJohan Hedberg 		goto unlock;
9372b64d153SBrian Gix 	default:
93884794e11SJohan Hedberg 		smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
939fc75cc86SJohan Hedberg 		err = -EOPNOTSUPP;
940fc75cc86SJohan Hedberg 		goto unlock;
9412b64d153SBrian Gix 	}
9422b64d153SBrian Gix 
943fc75cc86SJohan Hedberg 	err = 0;
944fc75cc86SJohan Hedberg 
9452b64d153SBrian Gix 	/* If it is our turn to send Pairing Confirm, do so now */
9461cc61144SJohan Hedberg 	if (test_bit(SMP_FLAG_CFM_PENDING, &smp->flags)) {
9471cc61144SJohan Hedberg 		u8 rsp = smp_confirm(smp);
9481cc61144SJohan Hedberg 		if (rsp)
9491cc61144SJohan Hedberg 			smp_failure(conn, rsp);
9501cc61144SJohan Hedberg 	}
9512b64d153SBrian Gix 
952fc75cc86SJohan Hedberg unlock:
953fc75cc86SJohan Hedberg 	l2cap_chan_unlock(chan);
954fc75cc86SJohan Hedberg 	return err;
9552b64d153SBrian Gix }
9562b64d153SBrian Gix 
957da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
95888ba43b6SAnderson Briglia {
9593158c50cSVinicius Costa Gomes 	struct smp_cmd_pairing rsp, *req = (void *) skb->data;
960fc75cc86SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
961b3c6410bSJohan Hedberg 	struct hci_dev *hdev = conn->hcon->hdev;
9628aab4757SVinicius Costa Gomes 	struct smp_chan *smp;
963c7262e71SJohan Hedberg 	u8 key_size, auth, sec_level;
9648aab4757SVinicius Costa Gomes 	int ret;
96588ba43b6SAnderson Briglia 
96688ba43b6SAnderson Briglia 	BT_DBG("conn %p", conn);
96788ba43b6SAnderson Briglia 
968c46b98beSJohan Hedberg 	if (skb->len < sizeof(*req))
96938e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
970c46b98beSJohan Hedberg 
97140bef302SJohan Hedberg 	if (conn->hcon->role != HCI_ROLE_SLAVE)
9722b64d153SBrian Gix 		return SMP_CMD_NOTSUPP;
9732b64d153SBrian Gix 
974fc75cc86SJohan Hedberg 	if (!chan->data)
9758aab4757SVinicius Costa Gomes 		smp = smp_chan_create(conn);
976fc75cc86SJohan Hedberg 	else
9775d88cc73SJohan Hedberg 		smp = chan->data;
978d26a2345SVinicius Costa Gomes 
979d08fd0e7SAndrei Emeltchenko 	if (!smp)
980d08fd0e7SAndrei Emeltchenko 		return SMP_UNSPECIFIED;
981d08fd0e7SAndrei Emeltchenko 
982c05b9339SJohan Hedberg 	/* We didn't start the pairing, so match remote */
9830edb14deSJohan Hedberg 	auth = req->auth_req & AUTH_REQ_MASK(hdev);
984c05b9339SJohan Hedberg 
985b6ae8457SJohan Hedberg 	if (!test_bit(HCI_BONDABLE, &hdev->dev_flags) &&
986c05b9339SJohan Hedberg 	    (auth & SMP_AUTH_BONDING))
987b3c6410bSJohan Hedberg 		return SMP_PAIRING_NOTSUPP;
988b3c6410bSJohan Hedberg 
9891c1def09SVinicius Costa Gomes 	smp->preq[0] = SMP_CMD_PAIRING_REQ;
9901c1def09SVinicius Costa Gomes 	memcpy(&smp->preq[1], req, sizeof(*req));
9913158c50cSVinicius Costa Gomes 	skb_pull(skb, sizeof(*req));
99288ba43b6SAnderson Briglia 
9935be5e275SJohan Hedberg 	if (conn->hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
9941afc2a1aSJohan Hedberg 		sec_level = BT_SECURITY_MEDIUM;
9951afc2a1aSJohan Hedberg 	else
996c7262e71SJohan Hedberg 		sec_level = authreq_to_seclevel(auth);
9971afc2a1aSJohan Hedberg 
998c7262e71SJohan Hedberg 	if (sec_level > conn->hcon->pending_sec_level)
999c7262e71SJohan Hedberg 		conn->hcon->pending_sec_level = sec_level;
1000fdde0a26SIdo Yariv 
100149c922bbSStephen Hemminger 	/* If we need MITM check that it can be achieved */
10022ed8f65cSJohan Hedberg 	if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
10032ed8f65cSJohan Hedberg 		u8 method;
10042ed8f65cSJohan Hedberg 
10052ed8f65cSJohan Hedberg 		method = get_auth_method(smp, conn->hcon->io_capability,
10062ed8f65cSJohan Hedberg 					 req->io_capability);
10072ed8f65cSJohan Hedberg 		if (method == JUST_WORKS || method == JUST_CFM)
10082ed8f65cSJohan Hedberg 			return SMP_AUTH_REQUIREMENTS;
10092ed8f65cSJohan Hedberg 	}
10102ed8f65cSJohan Hedberg 
10112b64d153SBrian Gix 	build_pairing_cmd(conn, req, &rsp, auth);
10123158c50cSVinicius Costa Gomes 
101365668776SJohan Hedberg 	if (rsp.auth_req & SMP_AUTH_SC)
101465668776SJohan Hedberg 		set_bit(SMP_FLAG_SC, &smp->flags);
101565668776SJohan Hedberg 
10163158c50cSVinicius Costa Gomes 	key_size = min(req->max_key_size, rsp.max_key_size);
10173158c50cSVinicius Costa Gomes 	if (check_enc_key_size(conn, key_size))
10183158c50cSVinicius Costa Gomes 		return SMP_ENC_KEY_SIZE;
101988ba43b6SAnderson Briglia 
1020e84a6b13SJohan Hedberg 	get_random_bytes(smp->prnd, sizeof(smp->prnd));
10218aab4757SVinicius Costa Gomes 
10221c1def09SVinicius Costa Gomes 	smp->prsp[0] = SMP_CMD_PAIRING_RSP;
10231c1def09SVinicius Costa Gomes 	memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
1024f01ead31SAnderson Briglia 
10253158c50cSVinicius Costa Gomes 	smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
10263b19146dSJohan Hedberg 
10273b19146dSJohan Hedberg 	clear_bit(SMP_FLAG_INITIATOR, &smp->flags);
10283b19146dSJohan Hedberg 
10293b19146dSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
10303b19146dSJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PUBLIC_KEY);
10313b19146dSJohan Hedberg 		/* Clear bits which are generated but not distributed */
10323b19146dSJohan Hedberg 		smp->remote_key_dist &= ~SMP_SC_NO_DIST;
10333b19146dSJohan Hedberg 		/* Wait for Public Key from Initiating Device */
10343b19146dSJohan Hedberg 		return 0;
10353b19146dSJohan Hedberg 	} else {
1036b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
10373b19146dSJohan Hedberg 	}
1038da85e5e5SVinicius Costa Gomes 
10392b64d153SBrian Gix 	/* Request setup of TK */
10402b64d153SBrian Gix 	ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability);
10412b64d153SBrian Gix 	if (ret)
10422b64d153SBrian Gix 		return SMP_UNSPECIFIED;
10432b64d153SBrian Gix 
1044da85e5e5SVinicius Costa Gomes 	return 0;
104588ba43b6SAnderson Briglia }
104688ba43b6SAnderson Briglia 
10473b19146dSJohan Hedberg static u8 sc_send_public_key(struct smp_chan *smp)
10483b19146dSJohan Hedberg {
10493b19146dSJohan Hedberg 	BT_DBG("");
10503b19146dSJohan Hedberg 
10513b19146dSJohan Hedberg 	/* Generate local key pair for Secure Connections */
10523b19146dSJohan Hedberg 	if (!ecc_make_key(smp->local_pk, smp->local_sk))
10533b19146dSJohan Hedberg 		return SMP_UNSPECIFIED;
10543b19146dSJohan Hedberg 
10553b19146dSJohan Hedberg 	BT_DBG("Local Public Key X: %32phN", smp->local_pk);
10563b19146dSJohan Hedberg 	BT_DBG("Local Public Key Y: %32phN", &smp->local_pk[32]);
10573b19146dSJohan Hedberg 	BT_DBG("Local Private Key:  %32phN", smp->local_sk);
10583b19146dSJohan Hedberg 
10593b19146dSJohan Hedberg 	smp_send_cmd(smp->conn, SMP_CMD_PUBLIC_KEY, 64, smp->local_pk);
10603b19146dSJohan Hedberg 
10613b19146dSJohan Hedberg 	return 0;
10623b19146dSJohan Hedberg }
10633b19146dSJohan Hedberg 
1064da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
106588ba43b6SAnderson Briglia {
10663158c50cSVinicius Costa Gomes 	struct smp_cmd_pairing *req, *rsp = (void *) skb->data;
10675d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
10685d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
10690edb14deSJohan Hedberg 	struct hci_dev *hdev = conn->hcon->hdev;
10703a7dbfb8SJohan Hedberg 	u8 key_size, auth;
10717d24ddccSAnderson Briglia 	int ret;
107288ba43b6SAnderson Briglia 
107388ba43b6SAnderson Briglia 	BT_DBG("conn %p", conn);
107488ba43b6SAnderson Briglia 
1075c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rsp))
107638e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1077c46b98beSJohan Hedberg 
107840bef302SJohan Hedberg 	if (conn->hcon->role != HCI_ROLE_MASTER)
10792b64d153SBrian Gix 		return SMP_CMD_NOTSUPP;
10802b64d153SBrian Gix 
10813158c50cSVinicius Costa Gomes 	skb_pull(skb, sizeof(*rsp));
1082da85e5e5SVinicius Costa Gomes 
10831c1def09SVinicius Costa Gomes 	req = (void *) &smp->preq[1];
10843158c50cSVinicius Costa Gomes 
10853158c50cSVinicius Costa Gomes 	key_size = min(req->max_key_size, rsp->max_key_size);
10863158c50cSVinicius Costa Gomes 	if (check_enc_key_size(conn, key_size))
10873158c50cSVinicius Costa Gomes 		return SMP_ENC_KEY_SIZE;
10883158c50cSVinicius Costa Gomes 
10890edb14deSJohan Hedberg 	auth = rsp->auth_req & AUTH_REQ_MASK(hdev);
1090c05b9339SJohan Hedberg 
109165668776SJohan Hedberg 	if ((req->auth_req & SMP_AUTH_SC) && (auth & SMP_AUTH_SC))
109265668776SJohan Hedberg 		set_bit(SMP_FLAG_SC, &smp->flags);
1093d2eb9e10SJohan Hedberg 	else if (conn->hcon->pending_sec_level > BT_SECURITY_HIGH)
1094d2eb9e10SJohan Hedberg 		conn->hcon->pending_sec_level = BT_SECURITY_HIGH;
109565668776SJohan Hedberg 
109649c922bbSStephen Hemminger 	/* If we need MITM check that it can be achieved */
10972ed8f65cSJohan Hedberg 	if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
10982ed8f65cSJohan Hedberg 		u8 method;
10992ed8f65cSJohan Hedberg 
11002ed8f65cSJohan Hedberg 		method = get_auth_method(smp, req->io_capability,
11012ed8f65cSJohan Hedberg 					 rsp->io_capability);
11022ed8f65cSJohan Hedberg 		if (method == JUST_WORKS || method == JUST_CFM)
11032ed8f65cSJohan Hedberg 			return SMP_AUTH_REQUIREMENTS;
11042ed8f65cSJohan Hedberg 	}
11052ed8f65cSJohan Hedberg 
1106e84a6b13SJohan Hedberg 	get_random_bytes(smp->prnd, sizeof(smp->prnd));
11077d24ddccSAnderson Briglia 
11088aab4757SVinicius Costa Gomes 	smp->prsp[0] = SMP_CMD_PAIRING_RSP;
11098aab4757SVinicius Costa Gomes 	memcpy(&smp->prsp[1], rsp, sizeof(*rsp));
11107d24ddccSAnderson Briglia 
1111fdcc4becSJohan Hedberg 	/* Update remote key distribution in case the remote cleared
1112fdcc4becSJohan Hedberg 	 * some bits that we had enabled in our request.
1113fdcc4becSJohan Hedberg 	 */
1114fdcc4becSJohan Hedberg 	smp->remote_key_dist &= rsp->resp_key_dist;
1115fdcc4becSJohan Hedberg 
11163b19146dSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
11173b19146dSJohan Hedberg 		/* Clear bits which are generated but not distributed */
11183b19146dSJohan Hedberg 		smp->remote_key_dist &= ~SMP_SC_NO_DIST;
11193b19146dSJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PUBLIC_KEY);
11203b19146dSJohan Hedberg 		return sc_send_public_key(smp);
11213b19146dSJohan Hedberg 	}
11223b19146dSJohan Hedberg 
1123c05b9339SJohan Hedberg 	auth |= req->auth_req;
11242b64d153SBrian Gix 
1125476585ecSJohan Hedberg 	ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability);
11262b64d153SBrian Gix 	if (ret)
11272b64d153SBrian Gix 		return SMP_UNSPECIFIED;
11282b64d153SBrian Gix 
11294a74d658SJohan Hedberg 	set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
11302b64d153SBrian Gix 
11312b64d153SBrian Gix 	/* Can't compose response until we have been confirmed */
11324a74d658SJohan Hedberg 	if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
11331cc61144SJohan Hedberg 		return smp_confirm(smp);
1134da85e5e5SVinicius Costa Gomes 
1135da85e5e5SVinicius Costa Gomes 	return 0;
113688ba43b6SAnderson Briglia }
113788ba43b6SAnderson Briglia 
1138da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
113988ba43b6SAnderson Briglia {
11405d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
11415d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
11427d24ddccSAnderson Briglia 
114388ba43b6SAnderson Briglia 	BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
114488ba43b6SAnderson Briglia 
1145c46b98beSJohan Hedberg 	if (skb->len < sizeof(smp->pcnf))
114638e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1147c46b98beSJohan Hedberg 
11481c1def09SVinicius Costa Gomes 	memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf));
11491c1def09SVinicius Costa Gomes 	skb_pull(skb, sizeof(smp->pcnf));
11507d24ddccSAnderson Briglia 
1151b28b4943SJohan Hedberg 	if (conn->hcon->out) {
1152943a732aSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
1153943a732aSJohan Hedberg 			     smp->prnd);
1154b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
1155b28b4943SJohan Hedberg 		return 0;
1156b28b4943SJohan Hedberg 	}
1157b28b4943SJohan Hedberg 
1158b28b4943SJohan Hedberg 	if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
11591cc61144SJohan Hedberg 		return smp_confirm(smp);
1160943a732aSJohan Hedberg 	else
11614a74d658SJohan Hedberg 		set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
1162da85e5e5SVinicius Costa Gomes 
1163da85e5e5SVinicius Costa Gomes 	return 0;
116488ba43b6SAnderson Briglia }
116588ba43b6SAnderson Briglia 
1166da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
116788ba43b6SAnderson Briglia {
11685d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
11695d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
11707d24ddccSAnderson Briglia 
11718aab4757SVinicius Costa Gomes 	BT_DBG("conn %p", conn);
11727d24ddccSAnderson Briglia 
1173c46b98beSJohan Hedberg 	if (skb->len < sizeof(smp->rrnd))
117438e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1175c46b98beSJohan Hedberg 
1176943a732aSJohan Hedberg 	memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd));
11778aab4757SVinicius Costa Gomes 	skb_pull(skb, sizeof(smp->rrnd));
117888ba43b6SAnderson Briglia 
1179861580a9SJohan Hedberg 	return smp_random(smp);
118088ba43b6SAnderson Briglia }
118188ba43b6SAnderson Briglia 
1182f81cd823SMarcel Holtmann static bool smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
1183988c5997SVinicius Costa Gomes {
1184c9839a11SVinicius Costa Gomes 	struct smp_ltk *key;
1185988c5997SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
1186988c5997SVinicius Costa Gomes 
1187f3a73d97SJohan Hedberg 	key = hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, hcon->role);
1188988c5997SVinicius Costa Gomes 	if (!key)
1189f81cd823SMarcel Holtmann 		return false;
1190988c5997SVinicius Costa Gomes 
1191a6f7833cSJohan Hedberg 	if (smp_ltk_sec_level(key) < sec_level)
1192f81cd823SMarcel Holtmann 		return false;
11934dab7864SJohan Hedberg 
119451a8efd7SJohan Hedberg 	if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
1195f81cd823SMarcel Holtmann 		return true;
1196988c5997SVinicius Costa Gomes 
1197c9839a11SVinicius Costa Gomes 	hci_le_start_enc(hcon, key->ediv, key->rand, key->val);
1198c9839a11SVinicius Costa Gomes 	hcon->enc_key_size = key->enc_size;
1199988c5997SVinicius Costa Gomes 
1200fe59a05fSJohan Hedberg 	/* We never store STKs for master role, so clear this flag */
1201fe59a05fSJohan Hedberg 	clear_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags);
1202fe59a05fSJohan Hedberg 
1203f81cd823SMarcel Holtmann 	return true;
1204988c5997SVinicius Costa Gomes }
1205f1560463SMarcel Holtmann 
120635dc6f83SJohan Hedberg bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level,
120735dc6f83SJohan Hedberg 			     enum smp_key_pref key_pref)
1208854f4727SJohan Hedberg {
1209854f4727SJohan Hedberg 	if (sec_level == BT_SECURITY_LOW)
1210854f4727SJohan Hedberg 		return true;
1211854f4727SJohan Hedberg 
121235dc6f83SJohan Hedberg 	/* If we're encrypted with an STK but the caller prefers using
121335dc6f83SJohan Hedberg 	 * LTK claim insufficient security. This way we allow the
121435dc6f83SJohan Hedberg 	 * connection to be re-encrypted with an LTK, even if the LTK
121535dc6f83SJohan Hedberg 	 * provides the same level of security. Only exception is if we
121635dc6f83SJohan Hedberg 	 * don't have an LTK (e.g. because of key distribution bits).
12179ab65d60SJohan Hedberg 	 */
121835dc6f83SJohan Hedberg 	if (key_pref == SMP_USE_LTK &&
121935dc6f83SJohan Hedberg 	    test_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags) &&
1220f3a73d97SJohan Hedberg 	    hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, hcon->role))
12219ab65d60SJohan Hedberg 		return false;
12229ab65d60SJohan Hedberg 
1223854f4727SJohan Hedberg 	if (hcon->sec_level >= sec_level)
1224854f4727SJohan Hedberg 		return true;
1225854f4727SJohan Hedberg 
1226854f4727SJohan Hedberg 	return false;
1227854f4727SJohan Hedberg }
1228854f4727SJohan Hedberg 
1229da85e5e5SVinicius Costa Gomes static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
123088ba43b6SAnderson Briglia {
123188ba43b6SAnderson Briglia 	struct smp_cmd_security_req *rp = (void *) skb->data;
123288ba43b6SAnderson Briglia 	struct smp_cmd_pairing cp;
1233f1cb9af5SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
12340edb14deSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
12358aab4757SVinicius Costa Gomes 	struct smp_chan *smp;
1236c05b9339SJohan Hedberg 	u8 sec_level, auth;
123788ba43b6SAnderson Briglia 
123888ba43b6SAnderson Briglia 	BT_DBG("conn %p", conn);
123988ba43b6SAnderson Briglia 
1240c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rp))
124138e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1242c46b98beSJohan Hedberg 
124340bef302SJohan Hedberg 	if (hcon->role != HCI_ROLE_MASTER)
124486ca9eacSJohan Hedberg 		return SMP_CMD_NOTSUPP;
124586ca9eacSJohan Hedberg 
12460edb14deSJohan Hedberg 	auth = rp->auth_req & AUTH_REQ_MASK(hdev);
1247c05b9339SJohan Hedberg 
12485be5e275SJohan Hedberg 	if (hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
12491afc2a1aSJohan Hedberg 		sec_level = BT_SECURITY_MEDIUM;
12501afc2a1aSJohan Hedberg 	else
1251c05b9339SJohan Hedberg 		sec_level = authreq_to_seclevel(auth);
12521afc2a1aSJohan Hedberg 
125335dc6f83SJohan Hedberg 	if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK))
1254854f4727SJohan Hedberg 		return 0;
1255854f4727SJohan Hedberg 
1256c7262e71SJohan Hedberg 	if (sec_level > hcon->pending_sec_level)
1257c7262e71SJohan Hedberg 		hcon->pending_sec_level = sec_level;
1258feb45eb5SVinicius Costa Gomes 
12594dab7864SJohan Hedberg 	if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
1260988c5997SVinicius Costa Gomes 		return 0;
1261988c5997SVinicius Costa Gomes 
12628aab4757SVinicius Costa Gomes 	smp = smp_chan_create(conn);
1263c29d2444SJohan Hedberg 	if (!smp)
1264c29d2444SJohan Hedberg 		return SMP_UNSPECIFIED;
1265d26a2345SVinicius Costa Gomes 
1266b6ae8457SJohan Hedberg 	if (!test_bit(HCI_BONDABLE, &hcon->hdev->dev_flags) &&
1267c05b9339SJohan Hedberg 	    (auth & SMP_AUTH_BONDING))
1268616d55beSJohan Hedberg 		return SMP_PAIRING_NOTSUPP;
1269616d55beSJohan Hedberg 
127088ba43b6SAnderson Briglia 	skb_pull(skb, sizeof(*rp));
127188ba43b6SAnderson Briglia 
1272da85e5e5SVinicius Costa Gomes 	memset(&cp, 0, sizeof(cp));
1273c05b9339SJohan Hedberg 	build_pairing_cmd(conn, &cp, NULL, auth);
127488ba43b6SAnderson Briglia 
12751c1def09SVinicius Costa Gomes 	smp->preq[0] = SMP_CMD_PAIRING_REQ;
12761c1def09SVinicius Costa Gomes 	memcpy(&smp->preq[1], &cp, sizeof(cp));
1277f01ead31SAnderson Briglia 
127888ba43b6SAnderson Briglia 	smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
1279b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP);
1280f1cb9af5SVinicius Costa Gomes 
1281da85e5e5SVinicius Costa Gomes 	return 0;
128288ba43b6SAnderson Briglia }
128388ba43b6SAnderson Briglia 
1284cc110922SVinicius Costa Gomes int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
1285eb492e01SAnderson Briglia {
1286cc110922SVinicius Costa Gomes 	struct l2cap_conn *conn = hcon->l2cap_data;
1287c68b7f12SJohan Hedberg 	struct l2cap_chan *chan;
12880a66cf20SJohan Hedberg 	struct smp_chan *smp;
12892b64d153SBrian Gix 	__u8 authreq;
1290fc75cc86SJohan Hedberg 	int ret;
1291eb492e01SAnderson Briglia 
12923a0259bbSVinicius Costa Gomes 	BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
12933a0259bbSVinicius Costa Gomes 
12940a66cf20SJohan Hedberg 	/* This may be NULL if there's an unexpected disconnection */
12950a66cf20SJohan Hedberg 	if (!conn)
12960a66cf20SJohan Hedberg 		return 1;
12970a66cf20SJohan Hedberg 
1298c68b7f12SJohan Hedberg 	chan = conn->smp;
1299c68b7f12SJohan Hedberg 
1300757aee0fSJohan Hedberg 	if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags))
13012e65c9d2SAndre Guedes 		return 1;
13022e65c9d2SAndre Guedes 
130335dc6f83SJohan Hedberg 	if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK))
1304f1cb9af5SVinicius Costa Gomes 		return 1;
1305f1cb9af5SVinicius Costa Gomes 
1306c7262e71SJohan Hedberg 	if (sec_level > hcon->pending_sec_level)
1307c7262e71SJohan Hedberg 		hcon->pending_sec_level = sec_level;
1308c7262e71SJohan Hedberg 
130940bef302SJohan Hedberg 	if (hcon->role == HCI_ROLE_MASTER)
1310c7262e71SJohan Hedberg 		if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
1311c7262e71SJohan Hedberg 			return 0;
1312d26a2345SVinicius Costa Gomes 
1313fc75cc86SJohan Hedberg 	l2cap_chan_lock(chan);
1314fc75cc86SJohan Hedberg 
1315fc75cc86SJohan Hedberg 	/* If SMP is already in progress ignore this request */
1316fc75cc86SJohan Hedberg 	if (chan->data) {
1317fc75cc86SJohan Hedberg 		ret = 0;
1318fc75cc86SJohan Hedberg 		goto unlock;
1319fc75cc86SJohan Hedberg 	}
1320d26a2345SVinicius Costa Gomes 
13218aab4757SVinicius Costa Gomes 	smp = smp_chan_create(conn);
1322fc75cc86SJohan Hedberg 	if (!smp) {
1323fc75cc86SJohan Hedberg 		ret = 1;
1324fc75cc86SJohan Hedberg 		goto unlock;
1325fc75cc86SJohan Hedberg 	}
13262b64d153SBrian Gix 
13272b64d153SBrian Gix 	authreq = seclevel_to_authreq(sec_level);
1328d26a2345SVinicius Costa Gomes 
1329d2eb9e10SJohan Hedberg 	if (test_bit(HCI_SC_ENABLED, &hcon->hdev->dev_flags))
1330d2eb9e10SJohan Hedberg 		authreq |= SMP_AUTH_SC;
1331d2eb9e10SJohan Hedberg 
133279897d20SJohan Hedberg 	/* Require MITM if IO Capability allows or the security level
133379897d20SJohan Hedberg 	 * requires it.
13342e233644SJohan Hedberg 	 */
133579897d20SJohan Hedberg 	if (hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT ||
1336c7262e71SJohan Hedberg 	    hcon->pending_sec_level > BT_SECURITY_MEDIUM)
13372e233644SJohan Hedberg 		authreq |= SMP_AUTH_MITM;
13382e233644SJohan Hedberg 
133940bef302SJohan Hedberg 	if (hcon->role == HCI_ROLE_MASTER) {
1340d26a2345SVinicius Costa Gomes 		struct smp_cmd_pairing cp;
1341f01ead31SAnderson Briglia 
13422b64d153SBrian Gix 		build_pairing_cmd(conn, &cp, NULL, authreq);
13431c1def09SVinicius Costa Gomes 		smp->preq[0] = SMP_CMD_PAIRING_REQ;
13441c1def09SVinicius Costa Gomes 		memcpy(&smp->preq[1], &cp, sizeof(cp));
1345f01ead31SAnderson Briglia 
1346eb492e01SAnderson Briglia 		smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
1347b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP);
1348eb492e01SAnderson Briglia 	} else {
1349eb492e01SAnderson Briglia 		struct smp_cmd_security_req cp;
13502b64d153SBrian Gix 		cp.auth_req = authreq;
1351eb492e01SAnderson Briglia 		smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
1352b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_REQ);
1353eb492e01SAnderson Briglia 	}
1354eb492e01SAnderson Briglia 
13554a74d658SJohan Hedberg 	set_bit(SMP_FLAG_INITIATOR, &smp->flags);
1356fc75cc86SJohan Hedberg 	ret = 0;
1357edca792cSJohan Hedberg 
1358fc75cc86SJohan Hedberg unlock:
1359fc75cc86SJohan Hedberg 	l2cap_chan_unlock(chan);
1360fc75cc86SJohan Hedberg 	return ret;
1361eb492e01SAnderson Briglia }
1362eb492e01SAnderson Briglia 
13637034b911SVinicius Costa Gomes static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
13647034b911SVinicius Costa Gomes {
136516b90839SVinicius Costa Gomes 	struct smp_cmd_encrypt_info *rp = (void *) skb->data;
13665d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
13675d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
136816b90839SVinicius Costa Gomes 
1369c46b98beSJohan Hedberg 	BT_DBG("conn %p", conn);
1370c46b98beSJohan Hedberg 
1371c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rp))
137238e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1373c46b98beSJohan Hedberg 
1374b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_MASTER_IDENT);
13756131ddc8SJohan Hedberg 
137616b90839SVinicius Costa Gomes 	skb_pull(skb, sizeof(*rp));
137716b90839SVinicius Costa Gomes 
13781c1def09SVinicius Costa Gomes 	memcpy(smp->tk, rp->ltk, sizeof(smp->tk));
137916b90839SVinicius Costa Gomes 
13807034b911SVinicius Costa Gomes 	return 0;
13817034b911SVinicius Costa Gomes }
13827034b911SVinicius Costa Gomes 
13837034b911SVinicius Costa Gomes static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
13847034b911SVinicius Costa Gomes {
138516b90839SVinicius Costa Gomes 	struct smp_cmd_master_ident *rp = (void *) skb->data;
13865d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
13875d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
1388c9839a11SVinicius Costa Gomes 	struct hci_dev *hdev = conn->hcon->hdev;
1389c9839a11SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
139023d0e128SJohan Hedberg 	struct smp_ltk *ltk;
1391c9839a11SVinicius Costa Gomes 	u8 authenticated;
13927034b911SVinicius Costa Gomes 
1393c46b98beSJohan Hedberg 	BT_DBG("conn %p", conn);
1394c46b98beSJohan Hedberg 
1395c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rp))
139638e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1397c46b98beSJohan Hedberg 
13989747a9f3SJohan Hedberg 	/* Mark the information as received */
13999747a9f3SJohan Hedberg 	smp->remote_key_dist &= ~SMP_DIST_ENC_KEY;
14009747a9f3SJohan Hedberg 
1401b28b4943SJohan Hedberg 	if (smp->remote_key_dist & SMP_DIST_ID_KEY)
1402b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO);
1403196332f5SJohan Hedberg 	else if (smp->remote_key_dist & SMP_DIST_SIGN)
1404196332f5SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO);
1405b28b4943SJohan Hedberg 
140616b90839SVinicius Costa Gomes 	skb_pull(skb, sizeof(*rp));
140716b90839SVinicius Costa Gomes 
1408ce39fb4eSMarcel Holtmann 	authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
14092ceba539SJohan Hedberg 	ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, SMP_LTK,
1410ce39fb4eSMarcel Holtmann 			  authenticated, smp->tk, smp->enc_key_size,
141104124681SGustavo F. Padovan 			  rp->ediv, rp->rand);
141223d0e128SJohan Hedberg 	smp->ltk = ltk;
1413c6e81e9aSJohan Hedberg 	if (!(smp->remote_key_dist & KEY_DIST_MASK))
1414d6268e86SJohan Hedberg 		smp_distribute_keys(smp);
14157034b911SVinicius Costa Gomes 
14167034b911SVinicius Costa Gomes 	return 0;
14177034b911SVinicius Costa Gomes }
14187034b911SVinicius Costa Gomes 
1419fd349c02SJohan Hedberg static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
1420fd349c02SJohan Hedberg {
1421fd349c02SJohan Hedberg 	struct smp_cmd_ident_info *info = (void *) skb->data;
14225d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
14235d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
1424fd349c02SJohan Hedberg 
1425fd349c02SJohan Hedberg 	BT_DBG("");
1426fd349c02SJohan Hedberg 
1427fd349c02SJohan Hedberg 	if (skb->len < sizeof(*info))
142838e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1429fd349c02SJohan Hedberg 
1430b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_ADDR_INFO);
14316131ddc8SJohan Hedberg 
1432fd349c02SJohan Hedberg 	skb_pull(skb, sizeof(*info));
1433fd349c02SJohan Hedberg 
1434fd349c02SJohan Hedberg 	memcpy(smp->irk, info->irk, 16);
1435fd349c02SJohan Hedberg 
1436fd349c02SJohan Hedberg 	return 0;
1437fd349c02SJohan Hedberg }
1438fd349c02SJohan Hedberg 
1439fd349c02SJohan Hedberg static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
1440fd349c02SJohan Hedberg 				   struct sk_buff *skb)
1441fd349c02SJohan Hedberg {
1442fd349c02SJohan Hedberg 	struct smp_cmd_ident_addr_info *info = (void *) skb->data;
14435d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
14445d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
1445fd349c02SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
1446fd349c02SJohan Hedberg 	bdaddr_t rpa;
1447fd349c02SJohan Hedberg 
1448fd349c02SJohan Hedberg 	BT_DBG("");
1449fd349c02SJohan Hedberg 
1450fd349c02SJohan Hedberg 	if (skb->len < sizeof(*info))
145138e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1452fd349c02SJohan Hedberg 
14539747a9f3SJohan Hedberg 	/* Mark the information as received */
14549747a9f3SJohan Hedberg 	smp->remote_key_dist &= ~SMP_DIST_ID_KEY;
14559747a9f3SJohan Hedberg 
1456b28b4943SJohan Hedberg 	if (smp->remote_key_dist & SMP_DIST_SIGN)
1457b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO);
1458b28b4943SJohan Hedberg 
1459fd349c02SJohan Hedberg 	skb_pull(skb, sizeof(*info));
1460fd349c02SJohan Hedberg 
1461a9a58f86SJohan Hedberg 	/* Strictly speaking the Core Specification (4.1) allows sending
1462a9a58f86SJohan Hedberg 	 * an empty address which would force us to rely on just the IRK
1463a9a58f86SJohan Hedberg 	 * as "identity information". However, since such
1464a9a58f86SJohan Hedberg 	 * implementations are not known of and in order to not over
1465a9a58f86SJohan Hedberg 	 * complicate our implementation, simply pretend that we never
1466a9a58f86SJohan Hedberg 	 * received an IRK for such a device.
1467a9a58f86SJohan Hedberg 	 */
1468a9a58f86SJohan Hedberg 	if (!bacmp(&info->bdaddr, BDADDR_ANY)) {
1469a9a58f86SJohan Hedberg 		BT_ERR("Ignoring IRK with no identity address");
147031dd624eSJohan Hedberg 		goto distribute;
1471a9a58f86SJohan Hedberg 	}
1472a9a58f86SJohan Hedberg 
1473fd349c02SJohan Hedberg 	bacpy(&smp->id_addr, &info->bdaddr);
1474fd349c02SJohan Hedberg 	smp->id_addr_type = info->addr_type;
1475fd349c02SJohan Hedberg 
1476fd349c02SJohan Hedberg 	if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type))
1477fd349c02SJohan Hedberg 		bacpy(&rpa, &hcon->dst);
1478fd349c02SJohan Hedberg 	else
1479fd349c02SJohan Hedberg 		bacpy(&rpa, BDADDR_ANY);
1480fd349c02SJohan Hedberg 
148123d0e128SJohan Hedberg 	smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
148223d0e128SJohan Hedberg 				      smp->id_addr_type, smp->irk, &rpa);
1483fd349c02SJohan Hedberg 
148431dd624eSJohan Hedberg distribute:
1485c6e81e9aSJohan Hedberg 	if (!(smp->remote_key_dist & KEY_DIST_MASK))
1486d6268e86SJohan Hedberg 		smp_distribute_keys(smp);
1487fd349c02SJohan Hedberg 
1488fd349c02SJohan Hedberg 	return 0;
1489fd349c02SJohan Hedberg }
1490fd349c02SJohan Hedberg 
14917ee4ea36SMarcel Holtmann static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)
14927ee4ea36SMarcel Holtmann {
14937ee4ea36SMarcel Holtmann 	struct smp_cmd_sign_info *rp = (void *) skb->data;
14945d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
14955d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
14967ee4ea36SMarcel Holtmann 	struct smp_csrk *csrk;
14977ee4ea36SMarcel Holtmann 
14987ee4ea36SMarcel Holtmann 	BT_DBG("conn %p", conn);
14997ee4ea36SMarcel Holtmann 
15007ee4ea36SMarcel Holtmann 	if (skb->len < sizeof(*rp))
150138e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
15027ee4ea36SMarcel Holtmann 
15037ee4ea36SMarcel Holtmann 	/* Mark the information as received */
15047ee4ea36SMarcel Holtmann 	smp->remote_key_dist &= ~SMP_DIST_SIGN;
15057ee4ea36SMarcel Holtmann 
15067ee4ea36SMarcel Holtmann 	skb_pull(skb, sizeof(*rp));
15077ee4ea36SMarcel Holtmann 
15087ee4ea36SMarcel Holtmann 	csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
15097ee4ea36SMarcel Holtmann 	if (csrk) {
15107ee4ea36SMarcel Holtmann 		csrk->master = 0x01;
15117ee4ea36SMarcel Holtmann 		memcpy(csrk->val, rp->csrk, sizeof(csrk->val));
15127ee4ea36SMarcel Holtmann 	}
15137ee4ea36SMarcel Holtmann 	smp->csrk = csrk;
1514d6268e86SJohan Hedberg 	smp_distribute_keys(smp);
15157ee4ea36SMarcel Holtmann 
15167ee4ea36SMarcel Holtmann 	return 0;
15177ee4ea36SMarcel Holtmann }
15187ee4ea36SMarcel Holtmann 
1519d8f8edbeSJohan Hedberg static int smp_cmd_public_key(struct l2cap_conn *conn, struct sk_buff *skb)
1520d8f8edbeSJohan Hedberg {
1521d8f8edbeSJohan Hedberg 	struct smp_cmd_public_key *key = (void *) skb->data;
1522d8f8edbeSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
1523d8f8edbeSJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
1524d8f8edbeSJohan Hedberg 	struct smp_chan *smp = chan->data;
1525d8f8edbeSJohan Hedberg 	int err;
1526d8f8edbeSJohan Hedberg 
1527d8f8edbeSJohan Hedberg 	BT_DBG("conn %p", conn);
1528d8f8edbeSJohan Hedberg 
1529d8f8edbeSJohan Hedberg 	if (skb->len < sizeof(*key))
1530d8f8edbeSJohan Hedberg 		return SMP_INVALID_PARAMS;
1531d8f8edbeSJohan Hedberg 
1532d8f8edbeSJohan Hedberg 	memcpy(smp->remote_pk, key, 64);
1533d8f8edbeSJohan Hedberg 
1534d8f8edbeSJohan Hedberg 	/* Non-initiating device sends its public key after receiving
1535d8f8edbeSJohan Hedberg 	 * the key from the initiating device.
1536d8f8edbeSJohan Hedberg 	 */
1537d8f8edbeSJohan Hedberg 	if (!hcon->out) {
1538d8f8edbeSJohan Hedberg 		err = sc_send_public_key(smp);
1539d8f8edbeSJohan Hedberg 		if (err)
1540d8f8edbeSJohan Hedberg 			return err;
1541d8f8edbeSJohan Hedberg 	}
1542d8f8edbeSJohan Hedberg 
1543d8f8edbeSJohan Hedberg 	BT_DBG("Remote Public Key X: %32phN", smp->remote_pk);
1544d8f8edbeSJohan Hedberg 	BT_DBG("Remote Public Key Y: %32phN", &smp->remote_pk[32]);
1545d8f8edbeSJohan Hedberg 
1546d8f8edbeSJohan Hedberg 	if (!ecdh_shared_secret(smp->remote_pk, smp->local_sk, smp->dhkey))
1547d8f8edbeSJohan Hedberg 		return SMP_UNSPECIFIED;
1548d8f8edbeSJohan Hedberg 
1549d8f8edbeSJohan Hedberg 	BT_DBG("DHKey %32phN", smp->dhkey);
1550d8f8edbeSJohan Hedberg 
1551d8f8edbeSJohan Hedberg 	set_bit(SMP_FLAG_REMOTE_PK, &smp->flags);
1552d8f8edbeSJohan Hedberg 
1553d8f8edbeSJohan Hedberg 	return 0;
1554d8f8edbeSJohan Hedberg }
1555d8f8edbeSJohan Hedberg 
15564befb867SJohan Hedberg static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb)
1557eb492e01SAnderson Briglia {
15585d88cc73SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
15597b9899dbSMarcel Holtmann 	struct hci_conn *hcon = conn->hcon;
1560b28b4943SJohan Hedberg 	struct smp_chan *smp;
156192381f5cSMarcel Holtmann 	__u8 code, reason;
1562eb492e01SAnderson Briglia 	int err = 0;
1563eb492e01SAnderson Briglia 
15647b9899dbSMarcel Holtmann 	if (hcon->type != LE_LINK) {
15657b9899dbSMarcel Holtmann 		kfree_skb(skb);
15663432711fSJohan Hedberg 		return 0;
15677b9899dbSMarcel Holtmann 	}
15687b9899dbSMarcel Holtmann 
15698ae9b984SJohan Hedberg 	if (skb->len < 1)
157092381f5cSMarcel Holtmann 		return -EILSEQ;
157192381f5cSMarcel Holtmann 
157206ae3314SMarcel Holtmann 	if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) {
15732e65c9d2SAndre Guedes 		reason = SMP_PAIRING_NOTSUPP;
15742e65c9d2SAndre Guedes 		goto done;
15752e65c9d2SAndre Guedes 	}
15762e65c9d2SAndre Guedes 
157792381f5cSMarcel Holtmann 	code = skb->data[0];
1578eb492e01SAnderson Briglia 	skb_pull(skb, sizeof(code));
1579eb492e01SAnderson Briglia 
1580b28b4943SJohan Hedberg 	smp = chan->data;
1581b28b4943SJohan Hedberg 
1582b28b4943SJohan Hedberg 	if (code > SMP_CMD_MAX)
1583b28b4943SJohan Hedberg 		goto drop;
1584b28b4943SJohan Hedberg 
158524bd0bd9SJohan Hedberg 	if (smp && !test_and_clear_bit(code, &smp->allow_cmd))
1586b28b4943SJohan Hedberg 		goto drop;
1587b28b4943SJohan Hedberg 
1588b28b4943SJohan Hedberg 	/* If we don't have a context the only allowed commands are
1589b28b4943SJohan Hedberg 	 * pairing request and security request.
15908cf9fa12SJohan Hedberg 	 */
1591b28b4943SJohan Hedberg 	if (!smp && code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ)
1592b28b4943SJohan Hedberg 		goto drop;
15938cf9fa12SJohan Hedberg 
1594eb492e01SAnderson Briglia 	switch (code) {
1595eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_REQ:
1596da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_req(conn, skb);
1597eb492e01SAnderson Briglia 		break;
1598eb492e01SAnderson Briglia 
1599eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_FAIL:
160084794e11SJohan Hedberg 		smp_failure(conn, 0);
1601da85e5e5SVinicius Costa Gomes 		err = -EPERM;
1602eb492e01SAnderson Briglia 		break;
1603eb492e01SAnderson Briglia 
1604eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_RSP:
1605da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_rsp(conn, skb);
160688ba43b6SAnderson Briglia 		break;
160788ba43b6SAnderson Briglia 
160888ba43b6SAnderson Briglia 	case SMP_CMD_SECURITY_REQ:
1609da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_security_req(conn, skb);
161088ba43b6SAnderson Briglia 		break;
161188ba43b6SAnderson Briglia 
1612eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_CONFIRM:
1613da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_confirm(conn, skb);
161488ba43b6SAnderson Briglia 		break;
161588ba43b6SAnderson Briglia 
1616eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_RANDOM:
1617da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_random(conn, skb);
161888ba43b6SAnderson Briglia 		break;
161988ba43b6SAnderson Briglia 
1620eb492e01SAnderson Briglia 	case SMP_CMD_ENCRYPT_INFO:
16217034b911SVinicius Costa Gomes 		reason = smp_cmd_encrypt_info(conn, skb);
16227034b911SVinicius Costa Gomes 		break;
16237034b911SVinicius Costa Gomes 
1624eb492e01SAnderson Briglia 	case SMP_CMD_MASTER_IDENT:
16257034b911SVinicius Costa Gomes 		reason = smp_cmd_master_ident(conn, skb);
16267034b911SVinicius Costa Gomes 		break;
16277034b911SVinicius Costa Gomes 
1628eb492e01SAnderson Briglia 	case SMP_CMD_IDENT_INFO:
1629fd349c02SJohan Hedberg 		reason = smp_cmd_ident_info(conn, skb);
1630fd349c02SJohan Hedberg 		break;
1631fd349c02SJohan Hedberg 
1632eb492e01SAnderson Briglia 	case SMP_CMD_IDENT_ADDR_INFO:
1633fd349c02SJohan Hedberg 		reason = smp_cmd_ident_addr_info(conn, skb);
1634fd349c02SJohan Hedberg 		break;
1635fd349c02SJohan Hedberg 
1636eb492e01SAnderson Briglia 	case SMP_CMD_SIGN_INFO:
16377ee4ea36SMarcel Holtmann 		reason = smp_cmd_sign_info(conn, skb);
16387034b911SVinicius Costa Gomes 		break;
16397034b911SVinicius Costa Gomes 
1640d8f8edbeSJohan Hedberg 	case SMP_CMD_PUBLIC_KEY:
1641d8f8edbeSJohan Hedberg 		reason = smp_cmd_public_key(conn, skb);
1642d8f8edbeSJohan Hedberg 		break;
1643d8f8edbeSJohan Hedberg 
1644eb492e01SAnderson Briglia 	default:
1645eb492e01SAnderson Briglia 		BT_DBG("Unknown command code 0x%2.2x", code);
1646eb492e01SAnderson Briglia 		reason = SMP_CMD_NOTSUPP;
16473a0259bbSVinicius Costa Gomes 		goto done;
16483a0259bbSVinicius Costa Gomes 	}
16493a0259bbSVinicius Costa Gomes 
16503a0259bbSVinicius Costa Gomes done:
16519b7b18efSJohan Hedberg 	if (!err) {
16523a0259bbSVinicius Costa Gomes 		if (reason)
165384794e11SJohan Hedberg 			smp_failure(conn, reason);
1654eb492e01SAnderson Briglia 		kfree_skb(skb);
16559b7b18efSJohan Hedberg 	}
16569b7b18efSJohan Hedberg 
1657eb492e01SAnderson Briglia 	return err;
1658b28b4943SJohan Hedberg 
1659b28b4943SJohan Hedberg drop:
1660b28b4943SJohan Hedberg 	BT_ERR("%s unexpected SMP command 0x%02x from %pMR", hcon->hdev->name,
1661b28b4943SJohan Hedberg 	       code, &hcon->dst);
1662b28b4943SJohan Hedberg 	kfree_skb(skb);
1663b28b4943SJohan Hedberg 	return 0;
1664eb492e01SAnderson Briglia }
16657034b911SVinicius Costa Gomes 
166670db83c4SJohan Hedberg static void smp_teardown_cb(struct l2cap_chan *chan, int err)
166770db83c4SJohan Hedberg {
166870db83c4SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
166970db83c4SJohan Hedberg 
167070db83c4SJohan Hedberg 	BT_DBG("chan %p", chan);
167170db83c4SJohan Hedberg 
1672fc75cc86SJohan Hedberg 	if (chan->data)
16735d88cc73SJohan Hedberg 		smp_chan_destroy(conn);
16745d88cc73SJohan Hedberg 
167570db83c4SJohan Hedberg 	conn->smp = NULL;
167670db83c4SJohan Hedberg 	l2cap_chan_put(chan);
167770db83c4SJohan Hedberg }
167870db83c4SJohan Hedberg 
167944f1a7abSJohan Hedberg static void smp_resume_cb(struct l2cap_chan *chan)
168044f1a7abSJohan Hedberg {
1681b68fda68SJohan Hedberg 	struct smp_chan *smp = chan->data;
168244f1a7abSJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
168344f1a7abSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
168444f1a7abSJohan Hedberg 
168544f1a7abSJohan Hedberg 	BT_DBG("chan %p", chan);
168644f1a7abSJohan Hedberg 
168786d1407cSJohan Hedberg 	if (!smp)
168886d1407cSJohan Hedberg 		return;
1689b68fda68SJohan Hedberg 
169084bc0db5SJohan Hedberg 	if (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags))
169184bc0db5SJohan Hedberg 		return;
169284bc0db5SJohan Hedberg 
1693b68fda68SJohan Hedberg 	cancel_delayed_work(&smp->security_timer);
169486d1407cSJohan Hedberg 
1695d6268e86SJohan Hedberg 	smp_distribute_keys(smp);
169644f1a7abSJohan Hedberg }
169744f1a7abSJohan Hedberg 
169870db83c4SJohan Hedberg static void smp_ready_cb(struct l2cap_chan *chan)
169970db83c4SJohan Hedberg {
170070db83c4SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
170170db83c4SJohan Hedberg 
170270db83c4SJohan Hedberg 	BT_DBG("chan %p", chan);
170370db83c4SJohan Hedberg 
170470db83c4SJohan Hedberg 	conn->smp = chan;
170570db83c4SJohan Hedberg 	l2cap_chan_hold(chan);
170670db83c4SJohan Hedberg }
170770db83c4SJohan Hedberg 
17084befb867SJohan Hedberg static int smp_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
17094befb867SJohan Hedberg {
17104befb867SJohan Hedberg 	int err;
17114befb867SJohan Hedberg 
17124befb867SJohan Hedberg 	BT_DBG("chan %p", chan);
17134befb867SJohan Hedberg 
17144befb867SJohan Hedberg 	err = smp_sig_channel(chan, skb);
17154befb867SJohan Hedberg 	if (err) {
1716b68fda68SJohan Hedberg 		struct smp_chan *smp = chan->data;
17174befb867SJohan Hedberg 
1718b68fda68SJohan Hedberg 		if (smp)
1719b68fda68SJohan Hedberg 			cancel_delayed_work_sync(&smp->security_timer);
17204befb867SJohan Hedberg 
17211e91c29eSJohan Hedberg 		hci_disconnect(chan->conn->hcon, HCI_ERROR_AUTH_FAILURE);
17224befb867SJohan Hedberg 	}
17234befb867SJohan Hedberg 
17244befb867SJohan Hedberg 	return err;
17254befb867SJohan Hedberg }
17264befb867SJohan Hedberg 
172770db83c4SJohan Hedberg static struct sk_buff *smp_alloc_skb_cb(struct l2cap_chan *chan,
172870db83c4SJohan Hedberg 					unsigned long hdr_len,
172970db83c4SJohan Hedberg 					unsigned long len, int nb)
173070db83c4SJohan Hedberg {
173170db83c4SJohan Hedberg 	struct sk_buff *skb;
173270db83c4SJohan Hedberg 
173370db83c4SJohan Hedberg 	skb = bt_skb_alloc(hdr_len + len, GFP_KERNEL);
173470db83c4SJohan Hedberg 	if (!skb)
173570db83c4SJohan Hedberg 		return ERR_PTR(-ENOMEM);
173670db83c4SJohan Hedberg 
173770db83c4SJohan Hedberg 	skb->priority = HCI_PRIO_MAX;
173870db83c4SJohan Hedberg 	bt_cb(skb)->chan = chan;
173970db83c4SJohan Hedberg 
174070db83c4SJohan Hedberg 	return skb;
174170db83c4SJohan Hedberg }
174270db83c4SJohan Hedberg 
174370db83c4SJohan Hedberg static const struct l2cap_ops smp_chan_ops = {
174470db83c4SJohan Hedberg 	.name			= "Security Manager",
174570db83c4SJohan Hedberg 	.ready			= smp_ready_cb,
17465d88cc73SJohan Hedberg 	.recv			= smp_recv_cb,
174770db83c4SJohan Hedberg 	.alloc_skb		= smp_alloc_skb_cb,
174870db83c4SJohan Hedberg 	.teardown		= smp_teardown_cb,
174944f1a7abSJohan Hedberg 	.resume			= smp_resume_cb,
175070db83c4SJohan Hedberg 
175170db83c4SJohan Hedberg 	.new_connection		= l2cap_chan_no_new_connection,
175270db83c4SJohan Hedberg 	.state_change		= l2cap_chan_no_state_change,
175370db83c4SJohan Hedberg 	.close			= l2cap_chan_no_close,
175470db83c4SJohan Hedberg 	.defer			= l2cap_chan_no_defer,
175570db83c4SJohan Hedberg 	.suspend		= l2cap_chan_no_suspend,
175670db83c4SJohan Hedberg 	.set_shutdown		= l2cap_chan_no_set_shutdown,
175770db83c4SJohan Hedberg 	.get_sndtimeo		= l2cap_chan_no_get_sndtimeo,
175870db83c4SJohan Hedberg 	.memcpy_fromiovec	= l2cap_chan_no_memcpy_fromiovec,
175970db83c4SJohan Hedberg };
176070db83c4SJohan Hedberg 
176170db83c4SJohan Hedberg static inline struct l2cap_chan *smp_new_conn_cb(struct l2cap_chan *pchan)
176270db83c4SJohan Hedberg {
176370db83c4SJohan Hedberg 	struct l2cap_chan *chan;
176470db83c4SJohan Hedberg 
176570db83c4SJohan Hedberg 	BT_DBG("pchan %p", pchan);
176670db83c4SJohan Hedberg 
176770db83c4SJohan Hedberg 	chan = l2cap_chan_create();
176870db83c4SJohan Hedberg 	if (!chan)
176970db83c4SJohan Hedberg 		return NULL;
177070db83c4SJohan Hedberg 
177170db83c4SJohan Hedberg 	chan->chan_type	= pchan->chan_type;
177270db83c4SJohan Hedberg 	chan->ops	= &smp_chan_ops;
177370db83c4SJohan Hedberg 	chan->scid	= pchan->scid;
177470db83c4SJohan Hedberg 	chan->dcid	= chan->scid;
177570db83c4SJohan Hedberg 	chan->imtu	= pchan->imtu;
177670db83c4SJohan Hedberg 	chan->omtu	= pchan->omtu;
177770db83c4SJohan Hedberg 	chan->mode	= pchan->mode;
177870db83c4SJohan Hedberg 
1779abe84903SJohan Hedberg 	/* Other L2CAP channels may request SMP routines in order to
1780abe84903SJohan Hedberg 	 * change the security level. This means that the SMP channel
1781abe84903SJohan Hedberg 	 * lock must be considered in its own category to avoid lockdep
1782abe84903SJohan Hedberg 	 * warnings.
1783abe84903SJohan Hedberg 	 */
1784abe84903SJohan Hedberg 	atomic_set(&chan->nesting, L2CAP_NESTING_SMP);
1785abe84903SJohan Hedberg 
178670db83c4SJohan Hedberg 	BT_DBG("created chan %p", chan);
178770db83c4SJohan Hedberg 
178870db83c4SJohan Hedberg 	return chan;
178970db83c4SJohan Hedberg }
179070db83c4SJohan Hedberg 
179170db83c4SJohan Hedberg static const struct l2cap_ops smp_root_chan_ops = {
179270db83c4SJohan Hedberg 	.name			= "Security Manager Root",
179370db83c4SJohan Hedberg 	.new_connection		= smp_new_conn_cb,
179470db83c4SJohan Hedberg 
179570db83c4SJohan Hedberg 	/* None of these are implemented for the root channel */
179670db83c4SJohan Hedberg 	.close			= l2cap_chan_no_close,
179770db83c4SJohan Hedberg 	.alloc_skb		= l2cap_chan_no_alloc_skb,
179870db83c4SJohan Hedberg 	.recv			= l2cap_chan_no_recv,
179970db83c4SJohan Hedberg 	.state_change		= l2cap_chan_no_state_change,
180070db83c4SJohan Hedberg 	.teardown		= l2cap_chan_no_teardown,
180170db83c4SJohan Hedberg 	.ready			= l2cap_chan_no_ready,
180270db83c4SJohan Hedberg 	.defer			= l2cap_chan_no_defer,
180370db83c4SJohan Hedberg 	.suspend		= l2cap_chan_no_suspend,
180470db83c4SJohan Hedberg 	.resume			= l2cap_chan_no_resume,
180570db83c4SJohan Hedberg 	.set_shutdown		= l2cap_chan_no_set_shutdown,
180670db83c4SJohan Hedberg 	.get_sndtimeo		= l2cap_chan_no_get_sndtimeo,
180770db83c4SJohan Hedberg 	.memcpy_fromiovec	= l2cap_chan_no_memcpy_fromiovec,
180870db83c4SJohan Hedberg };
180970db83c4SJohan Hedberg 
1810711eafe3SJohan Hedberg int smp_register(struct hci_dev *hdev)
1811711eafe3SJohan Hedberg {
181270db83c4SJohan Hedberg 	struct l2cap_chan *chan;
1813defce9e8SJohan Hedberg 	struct crypto_blkcipher	*tfm_aes;
181470db83c4SJohan Hedberg 
1815711eafe3SJohan Hedberg 	BT_DBG("%s", hdev->name);
1816711eafe3SJohan Hedberg 
1817adae20cbSJohan Hedberg 	tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, 0);
1818defce9e8SJohan Hedberg 	if (IS_ERR(tfm_aes)) {
1819defce9e8SJohan Hedberg 		int err = PTR_ERR(tfm_aes);
1820711eafe3SJohan Hedberg 		BT_ERR("Unable to create crypto context");
1821711eafe3SJohan Hedberg 		return err;
1822711eafe3SJohan Hedberg 	}
1823711eafe3SJohan Hedberg 
182470db83c4SJohan Hedberg 	chan = l2cap_chan_create();
182570db83c4SJohan Hedberg 	if (!chan) {
1826defce9e8SJohan Hedberg 		crypto_free_blkcipher(tfm_aes);
182770db83c4SJohan Hedberg 		return -ENOMEM;
182870db83c4SJohan Hedberg 	}
182970db83c4SJohan Hedberg 
1830defce9e8SJohan Hedberg 	chan->data = tfm_aes;
1831defce9e8SJohan Hedberg 
18325d88cc73SJohan Hedberg 	l2cap_add_scid(chan, L2CAP_CID_SMP);
183370db83c4SJohan Hedberg 
183470db83c4SJohan Hedberg 	l2cap_chan_set_defaults(chan);
183570db83c4SJohan Hedberg 
183670db83c4SJohan Hedberg 	bacpy(&chan->src, &hdev->bdaddr);
183770db83c4SJohan Hedberg 	chan->src_type = BDADDR_LE_PUBLIC;
183870db83c4SJohan Hedberg 	chan->state = BT_LISTEN;
183970db83c4SJohan Hedberg 	chan->mode = L2CAP_MODE_BASIC;
184070db83c4SJohan Hedberg 	chan->imtu = L2CAP_DEFAULT_MTU;
184170db83c4SJohan Hedberg 	chan->ops = &smp_root_chan_ops;
184270db83c4SJohan Hedberg 
1843abe84903SJohan Hedberg 	/* Set correct nesting level for a parent/listening channel */
1844abe84903SJohan Hedberg 	atomic_set(&chan->nesting, L2CAP_NESTING_PARENT);
1845abe84903SJohan Hedberg 
184670db83c4SJohan Hedberg 	hdev->smp_data = chan;
184770db83c4SJohan Hedberg 
1848711eafe3SJohan Hedberg 	return 0;
1849711eafe3SJohan Hedberg }
1850711eafe3SJohan Hedberg 
1851711eafe3SJohan Hedberg void smp_unregister(struct hci_dev *hdev)
1852711eafe3SJohan Hedberg {
185370db83c4SJohan Hedberg 	struct l2cap_chan *chan = hdev->smp_data;
1854defce9e8SJohan Hedberg 	struct crypto_blkcipher *tfm_aes;
185570db83c4SJohan Hedberg 
185670db83c4SJohan Hedberg 	if (!chan)
185770db83c4SJohan Hedberg 		return;
185870db83c4SJohan Hedberg 
185970db83c4SJohan Hedberg 	BT_DBG("%s chan %p", hdev->name, chan);
1860711eafe3SJohan Hedberg 
1861defce9e8SJohan Hedberg 	tfm_aes = chan->data;
1862defce9e8SJohan Hedberg 	if (tfm_aes) {
1863defce9e8SJohan Hedberg 		chan->data = NULL;
1864defce9e8SJohan Hedberg 		crypto_free_blkcipher(tfm_aes);
1865711eafe3SJohan Hedberg 	}
186670db83c4SJohan Hedberg 
186770db83c4SJohan Hedberg 	hdev->smp_data = NULL;
186870db83c4SJohan Hedberg 	l2cap_chan_put(chan);
1869711eafe3SJohan Hedberg }
1870