xref: /openbmc/linux/net/bluetooth/smp.c (revision 88a479d9)
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 
23300acfdeSMarcel Holtmann #include <linux/debugfs.h>
248c520a59SGustavo Padovan #include <linux/crypto.h>
258c520a59SGustavo Padovan #include <linux/scatterlist.h>
268c520a59SGustavo Padovan #include <crypto/b128ops.h>
278c520a59SGustavo Padovan 
28eb492e01SAnderson Briglia #include <net/bluetooth/bluetooth.h>
29eb492e01SAnderson Briglia #include <net/bluetooth/hci_core.h>
30eb492e01SAnderson Briglia #include <net/bluetooth/l2cap.h>
312b64d153SBrian Gix #include <net/bluetooth/mgmt.h>
32ac4b7236SMarcel Holtmann 
333b19146dSJohan Hedberg #include "ecc.h"
34ac4b7236SMarcel Holtmann #include "smp.h"
35d22ef0bcSAnderson Briglia 
36c7a3d57dSJohan Hedberg /* Low-level debug macros to be used for stuff that we don't want
37c7a3d57dSJohan Hedberg  * accidentially in dmesg, i.e. the values of the various crypto keys
38c7a3d57dSJohan Hedberg  * and the inputs & outputs of crypto functions.
39c7a3d57dSJohan Hedberg  */
40c7a3d57dSJohan Hedberg #ifdef DEBUG
41c7a3d57dSJohan Hedberg #define SMP_DBG(fmt, ...) printk(KERN_DEBUG "%s: " fmt, __func__, \
42c7a3d57dSJohan Hedberg 				 ##__VA_ARGS__)
43c7a3d57dSJohan Hedberg #else
44c7a3d57dSJohan Hedberg #define SMP_DBG(fmt, ...) no_printk(KERN_DEBUG "%s: " fmt, __func__, \
45c7a3d57dSJohan Hedberg 				    ##__VA_ARGS__)
46c7a3d57dSJohan Hedberg #endif
47c7a3d57dSJohan Hedberg 
48b28b4943SJohan Hedberg #define SMP_ALLOW_CMD(smp, code)	set_bit(code, &smp->allow_cmd)
49b28b4943SJohan Hedberg 
503b19146dSJohan Hedberg /* Keys which are not distributed with Secure Connections */
513b19146dSJohan Hedberg #define SMP_SC_NO_DIST (SMP_DIST_ENC_KEY | SMP_DIST_LINK_KEY);
523b19146dSJohan Hedberg 
5317b02e62SMarcel Holtmann #define SMP_TIMEOUT	msecs_to_jiffies(30000)
545d3de7dfSVinicius Costa Gomes 
55d7a5a11dSMarcel Holtmann #define AUTH_REQ_MASK(dev)	(hci_dev_test_flag(dev, HCI_SC_ENABLED) ? \
560edb14deSJohan Hedberg 				 0x1f : 0x07)
5788d3a8acSJohan Hedberg #define KEY_DIST_MASK		0x07
58065a13e2SJohan Hedberg 
59cbbbe3e2SJohan Hedberg /* Maximum message length that can be passed to aes_cmac */
60cbbbe3e2SJohan Hedberg #define CMAC_MSG_MAX	80
61cbbbe3e2SJohan Hedberg 
62533e35d4SJohan Hedberg enum {
63533e35d4SJohan Hedberg 	SMP_FLAG_TK_VALID,
64533e35d4SJohan Hedberg 	SMP_FLAG_CFM_PENDING,
65533e35d4SJohan Hedberg 	SMP_FLAG_MITM_AUTH,
66533e35d4SJohan Hedberg 	SMP_FLAG_COMPLETE,
67533e35d4SJohan Hedberg 	SMP_FLAG_INITIATOR,
6865668776SJohan Hedberg 	SMP_FLAG_SC,
69d8f8edbeSJohan Hedberg 	SMP_FLAG_REMOTE_PK,
70aeb7d461SJohan Hedberg 	SMP_FLAG_DEBUG_KEY,
7138606f14SJohan Hedberg 	SMP_FLAG_WAIT_USER,
72d3e54a87SJohan Hedberg 	SMP_FLAG_DHKEY_PENDING,
7302b05bd8SJohan Hedberg 	SMP_FLAG_OOB,
74533e35d4SJohan Hedberg };
754bc58f51SJohan Hedberg 
7688a479d9SMarcel Holtmann struct smp_dev {
7788a479d9SMarcel Holtmann 	struct crypto_blkcipher	*tfm_aes;
7888a479d9SMarcel Holtmann };
7988a479d9SMarcel Holtmann 
804bc58f51SJohan Hedberg struct smp_chan {
814bc58f51SJohan Hedberg 	struct l2cap_conn	*conn;
82b68fda68SJohan Hedberg 	struct delayed_work	security_timer;
83b28b4943SJohan Hedberg 	unsigned long           allow_cmd; /* Bitmask of allowed commands */
84b68fda68SJohan Hedberg 
854bc58f51SJohan Hedberg 	u8		preq[7]; /* SMP Pairing Request */
864bc58f51SJohan Hedberg 	u8		prsp[7]; /* SMP Pairing Response */
874bc58f51SJohan Hedberg 	u8		prnd[16]; /* SMP Pairing Random (local) */
884bc58f51SJohan Hedberg 	u8		rrnd[16]; /* SMP Pairing Random (remote) */
894bc58f51SJohan Hedberg 	u8		pcnf[16]; /* SMP Pairing Confirm */
904bc58f51SJohan Hedberg 	u8		tk[16]; /* SMP Temporary Key */
91a29b0733SJohan Hedberg 	u8		rr[16];
924bc58f51SJohan Hedberg 	u8		enc_key_size;
934bc58f51SJohan Hedberg 	u8		remote_key_dist;
944bc58f51SJohan Hedberg 	bdaddr_t	id_addr;
954bc58f51SJohan Hedberg 	u8		id_addr_type;
964bc58f51SJohan Hedberg 	u8		irk[16];
974bc58f51SJohan Hedberg 	struct smp_csrk	*csrk;
984bc58f51SJohan Hedberg 	struct smp_csrk	*slave_csrk;
994bc58f51SJohan Hedberg 	struct smp_ltk	*ltk;
1004bc58f51SJohan Hedberg 	struct smp_ltk	*slave_ltk;
1014bc58f51SJohan Hedberg 	struct smp_irk	*remote_irk;
1026a77083aSJohan Hedberg 	u8		*link_key;
1034a74d658SJohan Hedberg 	unsigned long	flags;
104783e0574SJohan Hedberg 	u8		method;
10538606f14SJohan Hedberg 	u8		passkey_round;
1066a7bd103SJohan Hedberg 
1073b19146dSJohan Hedberg 	/* Secure Connections variables */
1083b19146dSJohan Hedberg 	u8			local_pk[64];
1093b19146dSJohan Hedberg 	u8			local_sk[32];
110d8f8edbeSJohan Hedberg 	u8			remote_pk[64];
111d8f8edbeSJohan Hedberg 	u8			dhkey[32];
112760b018bSJohan Hedberg 	u8			mackey[16];
1133b19146dSJohan Hedberg 
1146a7bd103SJohan Hedberg 	struct crypto_blkcipher	*tfm_aes;
115407cecf6SJohan Hedberg 	struct crypto_hash	*tfm_cmac;
1164bc58f51SJohan Hedberg };
1174bc58f51SJohan Hedberg 
118aeb7d461SJohan Hedberg /* These debug key values are defined in the SMP section of the core
119aeb7d461SJohan Hedberg  * specification. debug_pk is the public debug key and debug_sk the
120aeb7d461SJohan Hedberg  * private debug key.
121aeb7d461SJohan Hedberg  */
122aeb7d461SJohan Hedberg static const u8 debug_pk[64] = {
123aeb7d461SJohan Hedberg 		0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc,
124aeb7d461SJohan Hedberg 		0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef,
125aeb7d461SJohan Hedberg 		0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e,
126aeb7d461SJohan Hedberg 		0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20,
127aeb7d461SJohan Hedberg 
128aeb7d461SJohan Hedberg 		0x8b, 0xd2, 0x89, 0x15, 0xd0, 0x8e, 0x1c, 0x74,
129aeb7d461SJohan Hedberg 		0x24, 0x30, 0xed, 0x8f, 0xc2, 0x45, 0x63, 0x76,
130aeb7d461SJohan Hedberg 		0x5c, 0x15, 0x52, 0x5a, 0xbf, 0x9a, 0x32, 0x63,
131aeb7d461SJohan Hedberg 		0x6d, 0xeb, 0x2a, 0x65, 0x49, 0x9c, 0x80, 0xdc,
132aeb7d461SJohan Hedberg };
133aeb7d461SJohan Hedberg 
134aeb7d461SJohan Hedberg static const u8 debug_sk[32] = {
135aeb7d461SJohan Hedberg 		0xbd, 0x1a, 0x3c, 0xcd, 0xa6, 0xb8, 0x99, 0x58,
136aeb7d461SJohan Hedberg 		0x99, 0xb7, 0x40, 0xeb, 0x7b, 0x60, 0xff, 0x4a,
137aeb7d461SJohan Hedberg 		0x50, 0x3f, 0x10, 0xd2, 0xe3, 0xb3, 0xc9, 0x74,
138aeb7d461SJohan Hedberg 		0x38, 0x5f, 0xc5, 0xa3, 0xd4, 0xf6, 0x49, 0x3f,
139aeb7d461SJohan Hedberg };
140aeb7d461SJohan Hedberg 
1418a2936f4SJohan Hedberg static inline void swap_buf(const u8 *src, u8 *dst, size_t len)
142d22ef0bcSAnderson Briglia {
1438a2936f4SJohan Hedberg 	size_t i;
144d22ef0bcSAnderson Briglia 
1458a2936f4SJohan Hedberg 	for (i = 0; i < len; i++)
1468a2936f4SJohan Hedberg 		dst[len - 1 - i] = src[i];
147d22ef0bcSAnderson Briglia }
148d22ef0bcSAnderson Briglia 
14906edf8deSJohan Hedberg /* The following functions map to the LE SC SMP crypto functions
15006edf8deSJohan Hedberg  * AES-CMAC, f4, f5, f6, g2 and h6.
15106edf8deSJohan Hedberg  */
15206edf8deSJohan Hedberg 
153cbbbe3e2SJohan Hedberg static int aes_cmac(struct crypto_hash *tfm, const u8 k[16], const u8 *m,
154cbbbe3e2SJohan Hedberg 		    size_t len, u8 mac[16])
155cbbbe3e2SJohan Hedberg {
156cbbbe3e2SJohan Hedberg 	uint8_t tmp[16], mac_msb[16], msg_msb[CMAC_MSG_MAX];
157cbbbe3e2SJohan Hedberg 	struct hash_desc desc;
158cbbbe3e2SJohan Hedberg 	struct scatterlist sg;
159cbbbe3e2SJohan Hedberg 	int err;
160cbbbe3e2SJohan Hedberg 
161cbbbe3e2SJohan Hedberg 	if (len > CMAC_MSG_MAX)
162cbbbe3e2SJohan Hedberg 		return -EFBIG;
163cbbbe3e2SJohan Hedberg 
164cbbbe3e2SJohan Hedberg 	if (!tfm) {
165cbbbe3e2SJohan Hedberg 		BT_ERR("tfm %p", tfm);
166cbbbe3e2SJohan Hedberg 		return -EINVAL;
167cbbbe3e2SJohan Hedberg 	}
168cbbbe3e2SJohan Hedberg 
169cbbbe3e2SJohan Hedberg 	desc.tfm = tfm;
170cbbbe3e2SJohan Hedberg 	desc.flags = 0;
171cbbbe3e2SJohan Hedberg 
172cbbbe3e2SJohan Hedberg 	crypto_hash_init(&desc);
173cbbbe3e2SJohan Hedberg 
174cbbbe3e2SJohan Hedberg 	/* Swap key and message from LSB to MSB */
175cbbbe3e2SJohan Hedberg 	swap_buf(k, tmp, 16);
176cbbbe3e2SJohan Hedberg 	swap_buf(m, msg_msb, len);
177cbbbe3e2SJohan Hedberg 
178c7a3d57dSJohan Hedberg 	SMP_DBG("msg (len %zu) %*phN", len, (int) len, m);
179c7a3d57dSJohan Hedberg 	SMP_DBG("key %16phN", k);
180cbbbe3e2SJohan Hedberg 
181cbbbe3e2SJohan Hedberg 	err = crypto_hash_setkey(tfm, tmp, 16);
182cbbbe3e2SJohan Hedberg 	if (err) {
183cbbbe3e2SJohan Hedberg 		BT_ERR("cipher setkey failed: %d", err);
184cbbbe3e2SJohan Hedberg 		return err;
185cbbbe3e2SJohan Hedberg 	}
186cbbbe3e2SJohan Hedberg 
187cbbbe3e2SJohan Hedberg 	sg_init_one(&sg, msg_msb, len);
188cbbbe3e2SJohan Hedberg 
189cbbbe3e2SJohan Hedberg 	err = crypto_hash_update(&desc, &sg, len);
190cbbbe3e2SJohan Hedberg 	if (err) {
191cbbbe3e2SJohan Hedberg 		BT_ERR("Hash update error %d", err);
192cbbbe3e2SJohan Hedberg 		return err;
193cbbbe3e2SJohan Hedberg 	}
194cbbbe3e2SJohan Hedberg 
195cbbbe3e2SJohan Hedberg 	err = crypto_hash_final(&desc, mac_msb);
196cbbbe3e2SJohan Hedberg 	if (err) {
197cbbbe3e2SJohan Hedberg 		BT_ERR("Hash final error %d", err);
198cbbbe3e2SJohan Hedberg 		return err;
199cbbbe3e2SJohan Hedberg 	}
200cbbbe3e2SJohan Hedberg 
201cbbbe3e2SJohan Hedberg 	swap_buf(mac_msb, mac, 16);
202cbbbe3e2SJohan Hedberg 
203c7a3d57dSJohan Hedberg 	SMP_DBG("mac %16phN", mac);
204cbbbe3e2SJohan Hedberg 
205cbbbe3e2SJohan Hedberg 	return 0;
206cbbbe3e2SJohan Hedberg }
207cbbbe3e2SJohan Hedberg 
208cbbbe3e2SJohan Hedberg static int smp_f4(struct crypto_hash *tfm_cmac, const u8 u[32], const u8 v[32],
209cbbbe3e2SJohan Hedberg 		  const u8 x[16], u8 z, u8 res[16])
210cbbbe3e2SJohan Hedberg {
211cbbbe3e2SJohan Hedberg 	u8 m[65];
212cbbbe3e2SJohan Hedberg 	int err;
213cbbbe3e2SJohan Hedberg 
214c7a3d57dSJohan Hedberg 	SMP_DBG("u %32phN", u);
215c7a3d57dSJohan Hedberg 	SMP_DBG("v %32phN", v);
216c7a3d57dSJohan Hedberg 	SMP_DBG("x %16phN z %02x", x, z);
217cbbbe3e2SJohan Hedberg 
218cbbbe3e2SJohan Hedberg 	m[0] = z;
219cbbbe3e2SJohan Hedberg 	memcpy(m + 1, v, 32);
220cbbbe3e2SJohan Hedberg 	memcpy(m + 33, u, 32);
221cbbbe3e2SJohan Hedberg 
222cbbbe3e2SJohan Hedberg 	err = aes_cmac(tfm_cmac, x, m, sizeof(m), res);
223cbbbe3e2SJohan Hedberg 	if (err)
224cbbbe3e2SJohan Hedberg 		return err;
225cbbbe3e2SJohan Hedberg 
226c7a3d57dSJohan Hedberg 	SMP_DBG("res %16phN", res);
227cbbbe3e2SJohan Hedberg 
228cbbbe3e2SJohan Hedberg 	return err;
229cbbbe3e2SJohan Hedberg }
230cbbbe3e2SJohan Hedberg 
2314da50de8SJohan Hedberg static int smp_f5(struct crypto_hash *tfm_cmac, const u8 w[32],
2324da50de8SJohan Hedberg 		  const u8 n1[16], const u8 n2[16], const u8 a1[7],
2334da50de8SJohan Hedberg 		  const u8 a2[7], u8 mackey[16], u8 ltk[16])
234760b018bSJohan Hedberg {
235760b018bSJohan Hedberg 	/* The btle, salt and length "magic" values are as defined in
236760b018bSJohan Hedberg 	 * the SMP section of the Bluetooth core specification. In ASCII
237760b018bSJohan Hedberg 	 * the btle value ends up being 'btle'. The salt is just a
238760b018bSJohan Hedberg 	 * random number whereas length is the value 256 in little
239760b018bSJohan Hedberg 	 * endian format.
240760b018bSJohan Hedberg 	 */
241760b018bSJohan Hedberg 	const u8 btle[4] = { 0x65, 0x6c, 0x74, 0x62 };
242760b018bSJohan Hedberg 	const u8 salt[16] = { 0xbe, 0x83, 0x60, 0x5a, 0xdb, 0x0b, 0x37, 0x60,
243760b018bSJohan Hedberg 			      0x38, 0xa5, 0xf5, 0xaa, 0x91, 0x83, 0x88, 0x6c };
244760b018bSJohan Hedberg 	const u8 length[2] = { 0x00, 0x01 };
245760b018bSJohan Hedberg 	u8 m[53], t[16];
246760b018bSJohan Hedberg 	int err;
247760b018bSJohan Hedberg 
248c7a3d57dSJohan Hedberg 	SMP_DBG("w %32phN", w);
249c7a3d57dSJohan Hedberg 	SMP_DBG("n1 %16phN n2 %16phN", n1, n2);
250c7a3d57dSJohan Hedberg 	SMP_DBG("a1 %7phN a2 %7phN", a1, a2);
251760b018bSJohan Hedberg 
252760b018bSJohan Hedberg 	err = aes_cmac(tfm_cmac, salt, w, 32, t);
253760b018bSJohan Hedberg 	if (err)
254760b018bSJohan Hedberg 		return err;
255760b018bSJohan Hedberg 
256c7a3d57dSJohan Hedberg 	SMP_DBG("t %16phN", t);
257760b018bSJohan Hedberg 
258760b018bSJohan Hedberg 	memcpy(m, length, 2);
259760b018bSJohan Hedberg 	memcpy(m + 2, a2, 7);
260760b018bSJohan Hedberg 	memcpy(m + 9, a1, 7);
261760b018bSJohan Hedberg 	memcpy(m + 16, n2, 16);
262760b018bSJohan Hedberg 	memcpy(m + 32, n1, 16);
263760b018bSJohan Hedberg 	memcpy(m + 48, btle, 4);
264760b018bSJohan Hedberg 
265760b018bSJohan Hedberg 	m[52] = 0; /* Counter */
266760b018bSJohan Hedberg 
267760b018bSJohan Hedberg 	err = aes_cmac(tfm_cmac, t, m, sizeof(m), mackey);
268760b018bSJohan Hedberg 	if (err)
269760b018bSJohan Hedberg 		return err;
270760b018bSJohan Hedberg 
271c7a3d57dSJohan Hedberg 	SMP_DBG("mackey %16phN", mackey);
272760b018bSJohan Hedberg 
273760b018bSJohan Hedberg 	m[52] = 1; /* Counter */
274760b018bSJohan Hedberg 
275760b018bSJohan Hedberg 	err = aes_cmac(tfm_cmac, t, m, sizeof(m), ltk);
276760b018bSJohan Hedberg 	if (err)
277760b018bSJohan Hedberg 		return err;
278760b018bSJohan Hedberg 
279c7a3d57dSJohan Hedberg 	SMP_DBG("ltk %16phN", ltk);
280760b018bSJohan Hedberg 
281760b018bSJohan Hedberg 	return 0;
282760b018bSJohan Hedberg }
283760b018bSJohan Hedberg 
284760b018bSJohan Hedberg static int smp_f6(struct crypto_hash *tfm_cmac, const u8 w[16],
2854da50de8SJohan Hedberg 		  const u8 n1[16], const u8 n2[16], const u8 r[16],
286760b018bSJohan Hedberg 		  const u8 io_cap[3], const u8 a1[7], const u8 a2[7],
287760b018bSJohan Hedberg 		  u8 res[16])
288760b018bSJohan Hedberg {
289760b018bSJohan Hedberg 	u8 m[65];
290760b018bSJohan Hedberg 	int err;
291760b018bSJohan Hedberg 
292c7a3d57dSJohan Hedberg 	SMP_DBG("w %16phN", w);
293c7a3d57dSJohan Hedberg 	SMP_DBG("n1 %16phN n2 %16phN", n1, n2);
294c7a3d57dSJohan Hedberg 	SMP_DBG("r %16phN io_cap %3phN a1 %7phN a2 %7phN", r, io_cap, a1, a2);
295760b018bSJohan Hedberg 
296760b018bSJohan Hedberg 	memcpy(m, a2, 7);
297760b018bSJohan Hedberg 	memcpy(m + 7, a1, 7);
298760b018bSJohan Hedberg 	memcpy(m + 14, io_cap, 3);
299760b018bSJohan Hedberg 	memcpy(m + 17, r, 16);
300760b018bSJohan Hedberg 	memcpy(m + 33, n2, 16);
301760b018bSJohan Hedberg 	memcpy(m + 49, n1, 16);
302760b018bSJohan Hedberg 
303760b018bSJohan Hedberg 	err = aes_cmac(tfm_cmac, w, m, sizeof(m), res);
304760b018bSJohan Hedberg 	if (err)
305760b018bSJohan Hedberg 		return err;
306760b018bSJohan Hedberg 
307203de21bSMarcel Holtmann 	SMP_DBG("res %16phN", res);
308760b018bSJohan Hedberg 
309760b018bSJohan Hedberg 	return err;
310760b018bSJohan Hedberg }
311760b018bSJohan Hedberg 
312191dc7feSJohan Hedberg static int smp_g2(struct crypto_hash *tfm_cmac, const u8 u[32], const u8 v[32],
313191dc7feSJohan Hedberg 		  const u8 x[16], const u8 y[16], u32 *val)
314191dc7feSJohan Hedberg {
315191dc7feSJohan Hedberg 	u8 m[80], tmp[16];
316191dc7feSJohan Hedberg 	int err;
317191dc7feSJohan Hedberg 
318c7a3d57dSJohan Hedberg 	SMP_DBG("u %32phN", u);
319c7a3d57dSJohan Hedberg 	SMP_DBG("v %32phN", v);
320c7a3d57dSJohan Hedberg 	SMP_DBG("x %16phN y %16phN", x, y);
321191dc7feSJohan Hedberg 
322191dc7feSJohan Hedberg 	memcpy(m, y, 16);
323191dc7feSJohan Hedberg 	memcpy(m + 16, v, 32);
324191dc7feSJohan Hedberg 	memcpy(m + 48, u, 32);
325191dc7feSJohan Hedberg 
326191dc7feSJohan Hedberg 	err = aes_cmac(tfm_cmac, x, m, sizeof(m), tmp);
327191dc7feSJohan Hedberg 	if (err)
328191dc7feSJohan Hedberg 		return err;
329191dc7feSJohan Hedberg 
330191dc7feSJohan Hedberg 	*val = get_unaligned_le32(tmp);
331191dc7feSJohan Hedberg 	*val %= 1000000;
332191dc7feSJohan Hedberg 
333c7a3d57dSJohan Hedberg 	SMP_DBG("val %06u", *val);
334191dc7feSJohan Hedberg 
335191dc7feSJohan Hedberg 	return 0;
336191dc7feSJohan Hedberg }
337191dc7feSJohan Hedberg 
33806edf8deSJohan Hedberg static int smp_h6(struct crypto_hash *tfm_cmac, const u8 w[16],
33906edf8deSJohan Hedberg 		  const u8 key_id[4], u8 res[16])
34006edf8deSJohan Hedberg {
34106edf8deSJohan Hedberg 	int err;
34206edf8deSJohan Hedberg 
34306edf8deSJohan Hedberg 	SMP_DBG("w %16phN key_id %4phN", w, key_id);
34406edf8deSJohan Hedberg 
34506edf8deSJohan Hedberg 	err = aes_cmac(tfm_cmac, w, key_id, 4, res);
34606edf8deSJohan Hedberg 	if (err)
34706edf8deSJohan Hedberg 		return err;
34806edf8deSJohan Hedberg 
34906edf8deSJohan Hedberg 	SMP_DBG("res %16phN", res);
35006edf8deSJohan Hedberg 
35106edf8deSJohan Hedberg 	return err;
35206edf8deSJohan Hedberg }
35306edf8deSJohan Hedberg 
35406edf8deSJohan Hedberg /* The following functions map to the legacy SMP crypto functions e, c1,
35506edf8deSJohan Hedberg  * s1 and ah.
35606edf8deSJohan Hedberg  */
35706edf8deSJohan Hedberg 
358d22ef0bcSAnderson Briglia static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
359d22ef0bcSAnderson Briglia {
360d22ef0bcSAnderson Briglia 	struct blkcipher_desc desc;
361d22ef0bcSAnderson Briglia 	struct scatterlist sg;
362943a732aSJohan Hedberg 	uint8_t tmp[16], data[16];
363201a5929SJohan Hedberg 	int err;
364d22ef0bcSAnderson Briglia 
3657f376cd6SJohan Hedberg 	if (!tfm) {
366d22ef0bcSAnderson Briglia 		BT_ERR("tfm %p", tfm);
367d22ef0bcSAnderson Briglia 		return -EINVAL;
368d22ef0bcSAnderson Briglia 	}
369d22ef0bcSAnderson Briglia 
370d22ef0bcSAnderson Briglia 	desc.tfm = tfm;
371d22ef0bcSAnderson Briglia 	desc.flags = 0;
372d22ef0bcSAnderson Briglia 
373943a732aSJohan Hedberg 	/* The most significant octet of key corresponds to k[0] */
3748a2936f4SJohan Hedberg 	swap_buf(k, tmp, 16);
375943a732aSJohan Hedberg 
376943a732aSJohan Hedberg 	err = crypto_blkcipher_setkey(tfm, tmp, 16);
377d22ef0bcSAnderson Briglia 	if (err) {
378d22ef0bcSAnderson Briglia 		BT_ERR("cipher setkey failed: %d", err);
379d22ef0bcSAnderson Briglia 		return err;
380d22ef0bcSAnderson Briglia 	}
381d22ef0bcSAnderson Briglia 
382943a732aSJohan Hedberg 	/* Most significant octet of plaintextData corresponds to data[0] */
3838a2936f4SJohan Hedberg 	swap_buf(r, data, 16);
384943a732aSJohan Hedberg 
385943a732aSJohan Hedberg 	sg_init_one(&sg, data, 16);
386d22ef0bcSAnderson Briglia 
387d22ef0bcSAnderson Briglia 	err = crypto_blkcipher_encrypt(&desc, &sg, &sg, 16);
388d22ef0bcSAnderson Briglia 	if (err)
389d22ef0bcSAnderson Briglia 		BT_ERR("Encrypt data error %d", err);
390d22ef0bcSAnderson Briglia 
391943a732aSJohan Hedberg 	/* Most significant octet of encryptedData corresponds to data[0] */
3928a2936f4SJohan Hedberg 	swap_buf(data, r, 16);
393943a732aSJohan Hedberg 
394d22ef0bcSAnderson Briglia 	return err;
395d22ef0bcSAnderson Briglia }
396d22ef0bcSAnderson Briglia 
39706edf8deSJohan Hedberg static int smp_c1(struct crypto_blkcipher *tfm_aes, const u8 k[16],
39806edf8deSJohan Hedberg 		  const u8 r[16], const u8 preq[7], const u8 pres[7], u8 _iat,
39906edf8deSJohan Hedberg 		  const bdaddr_t *ia, u8 _rat, const bdaddr_t *ra, u8 res[16])
40006edf8deSJohan Hedberg {
40106edf8deSJohan Hedberg 	u8 p1[16], p2[16];
40206edf8deSJohan Hedberg 	int err;
40306edf8deSJohan Hedberg 
40406edf8deSJohan Hedberg 	memset(p1, 0, 16);
40506edf8deSJohan Hedberg 
40606edf8deSJohan Hedberg 	/* p1 = pres || preq || _rat || _iat */
40706edf8deSJohan Hedberg 	p1[0] = _iat;
40806edf8deSJohan Hedberg 	p1[1] = _rat;
40906edf8deSJohan Hedberg 	memcpy(p1 + 2, preq, 7);
41006edf8deSJohan Hedberg 	memcpy(p1 + 9, pres, 7);
41106edf8deSJohan Hedberg 
41206edf8deSJohan Hedberg 	/* p2 = padding || ia || ra */
41306edf8deSJohan Hedberg 	memcpy(p2, ra, 6);
41406edf8deSJohan Hedberg 	memcpy(p2 + 6, ia, 6);
41506edf8deSJohan Hedberg 	memset(p2 + 12, 0, 4);
41606edf8deSJohan Hedberg 
41706edf8deSJohan Hedberg 	/* res = r XOR p1 */
41806edf8deSJohan Hedberg 	u128_xor((u128 *) res, (u128 *) r, (u128 *) p1);
41906edf8deSJohan Hedberg 
42006edf8deSJohan Hedberg 	/* res = e(k, res) */
42106edf8deSJohan Hedberg 	err = smp_e(tfm_aes, k, res);
42206edf8deSJohan Hedberg 	if (err) {
42306edf8deSJohan Hedberg 		BT_ERR("Encrypt data error");
42406edf8deSJohan Hedberg 		return err;
42506edf8deSJohan Hedberg 	}
42606edf8deSJohan Hedberg 
42706edf8deSJohan Hedberg 	/* res = res XOR p2 */
42806edf8deSJohan Hedberg 	u128_xor((u128 *) res, (u128 *) res, (u128 *) p2);
42906edf8deSJohan Hedberg 
43006edf8deSJohan Hedberg 	/* res = e(k, res) */
43106edf8deSJohan Hedberg 	err = smp_e(tfm_aes, k, res);
43206edf8deSJohan Hedberg 	if (err)
43306edf8deSJohan Hedberg 		BT_ERR("Encrypt data error");
43406edf8deSJohan Hedberg 
43506edf8deSJohan Hedberg 	return err;
43606edf8deSJohan Hedberg }
43706edf8deSJohan Hedberg 
43806edf8deSJohan Hedberg static int smp_s1(struct crypto_blkcipher *tfm_aes, const u8 k[16],
43906edf8deSJohan Hedberg 		  const u8 r1[16], const u8 r2[16], u8 _r[16])
4406a77083aSJohan Hedberg {
4416a77083aSJohan Hedberg 	int err;
4426a77083aSJohan Hedberg 
44306edf8deSJohan Hedberg 	/* Just least significant octets from r1 and r2 are considered */
44406edf8deSJohan Hedberg 	memcpy(_r, r2, 8);
44506edf8deSJohan Hedberg 	memcpy(_r + 8, r1, 8);
4466a77083aSJohan Hedberg 
44706edf8deSJohan Hedberg 	err = smp_e(tfm_aes, k, _r);
4486a77083aSJohan Hedberg 	if (err)
44906edf8deSJohan Hedberg 		BT_ERR("Encrypt data error");
4506a77083aSJohan Hedberg 
4516a77083aSJohan Hedberg 	return err;
4526a77083aSJohan Hedberg }
4536a77083aSJohan Hedberg 
454cd082797SJohan Hedberg static int smp_ah(struct crypto_blkcipher *tfm, const u8 irk[16],
455cd082797SJohan Hedberg 		  const u8 r[3], u8 res[3])
45660478054SJohan Hedberg {
457943a732aSJohan Hedberg 	u8 _res[16];
45860478054SJohan Hedberg 	int err;
45960478054SJohan Hedberg 
46060478054SJohan Hedberg 	/* r' = padding || r */
461943a732aSJohan Hedberg 	memcpy(_res, r, 3);
462943a732aSJohan Hedberg 	memset(_res + 3, 0, 13);
46360478054SJohan Hedberg 
464943a732aSJohan Hedberg 	err = smp_e(tfm, irk, _res);
46560478054SJohan Hedberg 	if (err) {
46660478054SJohan Hedberg 		BT_ERR("Encrypt error");
46760478054SJohan Hedberg 		return err;
46860478054SJohan Hedberg 	}
46960478054SJohan Hedberg 
47060478054SJohan Hedberg 	/* The output of the random address function ah is:
47160478054SJohan Hedberg 	 *	ah(h, r) = e(k, r') mod 2^24
47260478054SJohan Hedberg 	 * The output of the security function e is then truncated to 24 bits
47360478054SJohan Hedberg 	 * by taking the least significant 24 bits of the output of e as the
47460478054SJohan Hedberg 	 * result of ah.
47560478054SJohan Hedberg 	 */
476943a732aSJohan Hedberg 	memcpy(res, _res, 3);
47760478054SJohan Hedberg 
47860478054SJohan Hedberg 	return 0;
47960478054SJohan Hedberg }
48060478054SJohan Hedberg 
481cd082797SJohan Hedberg bool smp_irk_matches(struct hci_dev *hdev, const u8 irk[16],
482cd082797SJohan Hedberg 		     const bdaddr_t *bdaddr)
48360478054SJohan Hedberg {
484defce9e8SJohan Hedberg 	struct l2cap_chan *chan = hdev->smp_data;
48588a479d9SMarcel Holtmann 	struct smp_dev *smp;
48660478054SJohan Hedberg 	u8 hash[3];
48760478054SJohan Hedberg 	int err;
48860478054SJohan Hedberg 
489defce9e8SJohan Hedberg 	if (!chan || !chan->data)
490defce9e8SJohan Hedberg 		return false;
491defce9e8SJohan Hedberg 
49288a479d9SMarcel Holtmann 	smp = chan->data;
493defce9e8SJohan Hedberg 
49460478054SJohan Hedberg 	BT_DBG("RPA %pMR IRK %*phN", bdaddr, 16, irk);
49560478054SJohan Hedberg 
49688a479d9SMarcel Holtmann 	err = smp_ah(smp->tfm_aes, irk, &bdaddr->b[3], hash);
49760478054SJohan Hedberg 	if (err)
49860478054SJohan Hedberg 		return false;
49960478054SJohan Hedberg 
50060478054SJohan Hedberg 	return !memcmp(bdaddr->b, hash, 3);
50160478054SJohan Hedberg }
50260478054SJohan Hedberg 
503cd082797SJohan Hedberg int smp_generate_rpa(struct hci_dev *hdev, const u8 irk[16], bdaddr_t *rpa)
504b1e2b3aeSJohan Hedberg {
505defce9e8SJohan Hedberg 	struct l2cap_chan *chan = hdev->smp_data;
50688a479d9SMarcel Holtmann 	struct smp_dev *smp;
507b1e2b3aeSJohan Hedberg 	int err;
508b1e2b3aeSJohan Hedberg 
509defce9e8SJohan Hedberg 	if (!chan || !chan->data)
510defce9e8SJohan Hedberg 		return -EOPNOTSUPP;
511defce9e8SJohan Hedberg 
51288a479d9SMarcel Holtmann 	smp = chan->data;
513defce9e8SJohan Hedberg 
514b1e2b3aeSJohan Hedberg 	get_random_bytes(&rpa->b[3], 3);
515b1e2b3aeSJohan Hedberg 
516b1e2b3aeSJohan Hedberg 	rpa->b[5] &= 0x3f;	/* Clear two most significant bits */
517b1e2b3aeSJohan Hedberg 	rpa->b[5] |= 0x40;	/* Set second most significant bit */
518b1e2b3aeSJohan Hedberg 
51988a479d9SMarcel Holtmann 	err = smp_ah(smp->tfm_aes, irk, &rpa->b[3], rpa->b);
520b1e2b3aeSJohan Hedberg 	if (err < 0)
521b1e2b3aeSJohan Hedberg 		return err;
522b1e2b3aeSJohan Hedberg 
523b1e2b3aeSJohan Hedberg 	BT_DBG("RPA %pMR", rpa);
524b1e2b3aeSJohan Hedberg 
525b1e2b3aeSJohan Hedberg 	return 0;
526b1e2b3aeSJohan Hedberg }
527b1e2b3aeSJohan Hedberg 
528eb492e01SAnderson Briglia static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
529eb492e01SAnderson Briglia {
5305d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
531b68fda68SJohan Hedberg 	struct smp_chan *smp;
5325d88cc73SJohan Hedberg 	struct kvec iv[2];
5335d88cc73SJohan Hedberg 	struct msghdr msg;
5345d88cc73SJohan Hedberg 
5355d88cc73SJohan Hedberg 	if (!chan)
5365d88cc73SJohan Hedberg 		return;
537eb492e01SAnderson Briglia 
538eb492e01SAnderson Briglia 	BT_DBG("code 0x%2.2x", code);
539eb492e01SAnderson Briglia 
5405d88cc73SJohan Hedberg 	iv[0].iov_base = &code;
5415d88cc73SJohan Hedberg 	iv[0].iov_len = 1;
542eb492e01SAnderson Briglia 
5435d88cc73SJohan Hedberg 	iv[1].iov_base = data;
5445d88cc73SJohan Hedberg 	iv[1].iov_len = len;
5455d88cc73SJohan Hedberg 
5465d88cc73SJohan Hedberg 	memset(&msg, 0, sizeof(msg));
5475d88cc73SJohan Hedberg 
54817836394SAl Viro 	iov_iter_kvec(&msg.msg_iter, WRITE | ITER_KVEC, iv, 2, 1 + len);
5495d88cc73SJohan Hedberg 
5505d88cc73SJohan Hedberg 	l2cap_chan_send(chan, &msg, 1 + len);
551e2dcd113SVinicius Costa Gomes 
552b68fda68SJohan Hedberg 	if (!chan->data)
553b68fda68SJohan Hedberg 		return;
554b68fda68SJohan Hedberg 
555b68fda68SJohan Hedberg 	smp = chan->data;
556b68fda68SJohan Hedberg 
557b68fda68SJohan Hedberg 	cancel_delayed_work_sync(&smp->security_timer);
558b68fda68SJohan Hedberg 	schedule_delayed_work(&smp->security_timer, SMP_TIMEOUT);
559eb492e01SAnderson Briglia }
560eb492e01SAnderson Briglia 
561d2eb9e10SJohan Hedberg static u8 authreq_to_seclevel(u8 authreq)
5622b64d153SBrian Gix {
563d2eb9e10SJohan Hedberg 	if (authreq & SMP_AUTH_MITM) {
564d2eb9e10SJohan Hedberg 		if (authreq & SMP_AUTH_SC)
565d2eb9e10SJohan Hedberg 			return BT_SECURITY_FIPS;
5662b64d153SBrian Gix 		else
567d2eb9e10SJohan Hedberg 			return BT_SECURITY_HIGH;
568d2eb9e10SJohan Hedberg 	} else {
5692b64d153SBrian Gix 		return BT_SECURITY_MEDIUM;
5702b64d153SBrian Gix 	}
571d2eb9e10SJohan Hedberg }
5722b64d153SBrian Gix 
5732b64d153SBrian Gix static __u8 seclevel_to_authreq(__u8 sec_level)
5742b64d153SBrian Gix {
5752b64d153SBrian Gix 	switch (sec_level) {
576d2eb9e10SJohan Hedberg 	case BT_SECURITY_FIPS:
5772b64d153SBrian Gix 	case BT_SECURITY_HIGH:
5782b64d153SBrian Gix 		return SMP_AUTH_MITM | SMP_AUTH_BONDING;
5792b64d153SBrian Gix 	case BT_SECURITY_MEDIUM:
5802b64d153SBrian Gix 		return SMP_AUTH_BONDING;
5812b64d153SBrian Gix 	default:
5822b64d153SBrian Gix 		return SMP_AUTH_NONE;
5832b64d153SBrian Gix 	}
5842b64d153SBrian Gix }
5852b64d153SBrian Gix 
586b8e66eacSVinicius Costa Gomes static void build_pairing_cmd(struct l2cap_conn *conn,
58754790f73SVinicius Costa Gomes 			      struct smp_cmd_pairing *req,
588f1560463SMarcel Holtmann 			      struct smp_cmd_pairing *rsp, __u8 authreq)
589b8e66eacSVinicius Costa Gomes {
5905d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
5915d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
592fd349c02SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
593fd349c02SJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
59402b05bd8SJohan Hedberg 	u8 local_dist = 0, remote_dist = 0, oob_flag = SMP_OOB_NOT_PRESENT;
59554790f73SVinicius Costa Gomes 
596d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_BONDABLE)) {
5977ee4ea36SMarcel Holtmann 		local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
5987ee4ea36SMarcel Holtmann 		remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
59954790f73SVinicius Costa Gomes 		authreq |= SMP_AUTH_BONDING;
6002b64d153SBrian Gix 	} else {
6012b64d153SBrian Gix 		authreq &= ~SMP_AUTH_BONDING;
60254790f73SVinicius Costa Gomes 	}
60354790f73SVinicius Costa Gomes 
604d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_RPA_RESOLVING))
605fd349c02SJohan Hedberg 		remote_dist |= SMP_DIST_ID_KEY;
606fd349c02SJohan Hedberg 
607d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_PRIVACY))
608863efaf2SJohan Hedberg 		local_dist |= SMP_DIST_ID_KEY;
609863efaf2SJohan Hedberg 
610d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SC_ENABLED) &&
61102b05bd8SJohan Hedberg 	    (authreq & SMP_AUTH_SC)) {
61202b05bd8SJohan Hedberg 		struct oob_data *oob_data;
61302b05bd8SJohan Hedberg 		u8 bdaddr_type;
61402b05bd8SJohan Hedberg 
615d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_SSP_ENABLED)) {
616df8e1a4cSJohan Hedberg 			local_dist |= SMP_DIST_LINK_KEY;
617df8e1a4cSJohan Hedberg 			remote_dist |= SMP_DIST_LINK_KEY;
618df8e1a4cSJohan Hedberg 		}
61902b05bd8SJohan Hedberg 
62002b05bd8SJohan Hedberg 		if (hcon->dst_type == ADDR_LE_DEV_PUBLIC)
62102b05bd8SJohan Hedberg 			bdaddr_type = BDADDR_LE_PUBLIC;
62202b05bd8SJohan Hedberg 		else
62302b05bd8SJohan Hedberg 			bdaddr_type = BDADDR_LE_RANDOM;
62402b05bd8SJohan Hedberg 
62502b05bd8SJohan Hedberg 		oob_data = hci_find_remote_oob_data(hdev, &hcon->dst,
62602b05bd8SJohan Hedberg 						    bdaddr_type);
6274775a4eaSMarcel Holtmann 		if (oob_data && oob_data->present) {
62802b05bd8SJohan Hedberg 			set_bit(SMP_FLAG_OOB, &smp->flags);
62902b05bd8SJohan Hedberg 			oob_flag = SMP_OOB_PRESENT;
630a29b0733SJohan Hedberg 			memcpy(smp->rr, oob_data->rand256, 16);
63102b05bd8SJohan Hedberg 			memcpy(smp->pcnf, oob_data->hash256, 16);
63202b05bd8SJohan Hedberg 		}
63302b05bd8SJohan Hedberg 
634df8e1a4cSJohan Hedberg 	} else {
635df8e1a4cSJohan Hedberg 		authreq &= ~SMP_AUTH_SC;
636df8e1a4cSJohan Hedberg 	}
637df8e1a4cSJohan Hedberg 
63854790f73SVinicius Costa Gomes 	if (rsp == NULL) {
63954790f73SVinicius Costa Gomes 		req->io_capability = conn->hcon->io_capability;
64002b05bd8SJohan Hedberg 		req->oob_flag = oob_flag;
64154790f73SVinicius Costa Gomes 		req->max_key_size = SMP_MAX_ENC_KEY_SIZE;
642fd349c02SJohan Hedberg 		req->init_key_dist = local_dist;
643fd349c02SJohan Hedberg 		req->resp_key_dist = remote_dist;
6440edb14deSJohan Hedberg 		req->auth_req = (authreq & AUTH_REQ_MASK(hdev));
645fd349c02SJohan Hedberg 
646fd349c02SJohan Hedberg 		smp->remote_key_dist = remote_dist;
64754790f73SVinicius Costa Gomes 		return;
64854790f73SVinicius Costa Gomes 	}
64954790f73SVinicius Costa Gomes 
65054790f73SVinicius Costa Gomes 	rsp->io_capability = conn->hcon->io_capability;
65102b05bd8SJohan Hedberg 	rsp->oob_flag = oob_flag;
65254790f73SVinicius Costa Gomes 	rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE;
653fd349c02SJohan Hedberg 	rsp->init_key_dist = req->init_key_dist & remote_dist;
654fd349c02SJohan Hedberg 	rsp->resp_key_dist = req->resp_key_dist & local_dist;
6550edb14deSJohan Hedberg 	rsp->auth_req = (authreq & AUTH_REQ_MASK(hdev));
656fd349c02SJohan Hedberg 
657fd349c02SJohan Hedberg 	smp->remote_key_dist = rsp->init_key_dist;
658b8e66eacSVinicius Costa Gomes }
659b8e66eacSVinicius Costa Gomes 
6603158c50cSVinicius Costa Gomes static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
6613158c50cSVinicius Costa Gomes {
6625d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
6635d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
6641c1def09SVinicius Costa Gomes 
6653158c50cSVinicius Costa Gomes 	if ((max_key_size > SMP_MAX_ENC_KEY_SIZE) ||
6663158c50cSVinicius Costa Gomes 	    (max_key_size < SMP_MIN_ENC_KEY_SIZE))
6673158c50cSVinicius Costa Gomes 		return SMP_ENC_KEY_SIZE;
6683158c50cSVinicius Costa Gomes 
669f7aa611aSVinicius Costa Gomes 	smp->enc_key_size = max_key_size;
6703158c50cSVinicius Costa Gomes 
6713158c50cSVinicius Costa Gomes 	return 0;
6723158c50cSVinicius Costa Gomes }
6733158c50cSVinicius Costa Gomes 
6746f48e260SJohan Hedberg static void smp_chan_destroy(struct l2cap_conn *conn)
6756f48e260SJohan Hedberg {
6766f48e260SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
6776f48e260SJohan Hedberg 	struct smp_chan *smp = chan->data;
678923e2414SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
6796f48e260SJohan Hedberg 	bool complete;
6806f48e260SJohan Hedberg 
6816f48e260SJohan Hedberg 	BUG_ON(!smp);
6826f48e260SJohan Hedberg 
6836f48e260SJohan Hedberg 	cancel_delayed_work_sync(&smp->security_timer);
6846f48e260SJohan Hedberg 
6856f48e260SJohan Hedberg 	complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags);
686923e2414SJohan Hedberg 	mgmt_smp_complete(hcon, complete);
6876f48e260SJohan Hedberg 
688276812ecSMarcel Holtmann 	kzfree(smp->csrk);
689276812ecSMarcel Holtmann 	kzfree(smp->slave_csrk);
690276812ecSMarcel Holtmann 	kzfree(smp->link_key);
6916f48e260SJohan Hedberg 
6926f48e260SJohan Hedberg 	crypto_free_blkcipher(smp->tfm_aes);
693407cecf6SJohan Hedberg 	crypto_free_hash(smp->tfm_cmac);
6946f48e260SJohan Hedberg 
695923e2414SJohan Hedberg 	/* Ensure that we don't leave any debug key around if debug key
696923e2414SJohan Hedberg 	 * support hasn't been explicitly enabled.
697923e2414SJohan Hedberg 	 */
698923e2414SJohan Hedberg 	if (smp->ltk && smp->ltk->type == SMP_LTK_P256_DEBUG &&
699d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hcon->hdev, HCI_KEEP_DEBUG_KEYS)) {
700923e2414SJohan Hedberg 		list_del_rcu(&smp->ltk->list);
701923e2414SJohan Hedberg 		kfree_rcu(smp->ltk, rcu);
702923e2414SJohan Hedberg 		smp->ltk = NULL;
703923e2414SJohan Hedberg 	}
704923e2414SJohan Hedberg 
7056f48e260SJohan Hedberg 	/* If pairing failed clean up any keys we might have */
7066f48e260SJohan Hedberg 	if (!complete) {
7076f48e260SJohan Hedberg 		if (smp->ltk) {
708970d0f1bSJohan Hedberg 			list_del_rcu(&smp->ltk->list);
709970d0f1bSJohan Hedberg 			kfree_rcu(smp->ltk, rcu);
7106f48e260SJohan Hedberg 		}
7116f48e260SJohan Hedberg 
7126f48e260SJohan Hedberg 		if (smp->slave_ltk) {
713970d0f1bSJohan Hedberg 			list_del_rcu(&smp->slave_ltk->list);
714970d0f1bSJohan Hedberg 			kfree_rcu(smp->slave_ltk, rcu);
7156f48e260SJohan Hedberg 		}
7166f48e260SJohan Hedberg 
7176f48e260SJohan Hedberg 		if (smp->remote_irk) {
718adae20cbSJohan Hedberg 			list_del_rcu(&smp->remote_irk->list);
719adae20cbSJohan Hedberg 			kfree_rcu(smp->remote_irk, rcu);
7206f48e260SJohan Hedberg 		}
7216f48e260SJohan Hedberg 	}
7226f48e260SJohan Hedberg 
7236f48e260SJohan Hedberg 	chan->data = NULL;
724276812ecSMarcel Holtmann 	kzfree(smp);
725923e2414SJohan Hedberg 	hci_conn_drop(hcon);
7266f48e260SJohan Hedberg }
7276f48e260SJohan Hedberg 
72884794e11SJohan Hedberg static void smp_failure(struct l2cap_conn *conn, u8 reason)
7294f957a76SBrian Gix {
730bab73cb6SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
731b68fda68SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
732bab73cb6SJohan Hedberg 
73384794e11SJohan Hedberg 	if (reason)
7344f957a76SBrian Gix 		smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
7354f957a76SBrian Gix 			     &reason);
7364f957a76SBrian Gix 
737ce39fb4eSMarcel Holtmann 	clear_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags);
738e1e930f5SJohan Hedberg 	mgmt_auth_failed(hcon, HCI_ERROR_AUTH_FAILURE);
739f1c09c07SVinicius Costa Gomes 
740fc75cc86SJohan Hedberg 	if (chan->data)
7414f957a76SBrian Gix 		smp_chan_destroy(conn);
7424f957a76SBrian Gix }
7434f957a76SBrian Gix 
7442b64d153SBrian Gix #define JUST_WORKS	0x00
7452b64d153SBrian Gix #define JUST_CFM	0x01
7462b64d153SBrian Gix #define REQ_PASSKEY	0x02
7472b64d153SBrian Gix #define CFM_PASSKEY	0x03
7482b64d153SBrian Gix #define REQ_OOB		0x04
7495e3d3d9bSJohan Hedberg #define DSP_PASSKEY	0x05
7502b64d153SBrian Gix #define OVERLAP		0xFF
7512b64d153SBrian Gix 
7522b64d153SBrian Gix static const u8 gen_method[5][5] = {
7532b64d153SBrian Gix 	{ JUST_WORKS,  JUST_CFM,    REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
7542b64d153SBrian Gix 	{ JUST_WORKS,  JUST_CFM,    REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
7552b64d153SBrian Gix 	{ CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
7562b64d153SBrian Gix 	{ JUST_WORKS,  JUST_CFM,    JUST_WORKS,  JUST_WORKS, JUST_CFM    },
7572b64d153SBrian Gix 	{ CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, OVERLAP     },
7582b64d153SBrian Gix };
7592b64d153SBrian Gix 
7605e3d3d9bSJohan Hedberg static const u8 sc_method[5][5] = {
7615e3d3d9bSJohan Hedberg 	{ JUST_WORKS,  JUST_CFM,    REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
7625e3d3d9bSJohan Hedberg 	{ JUST_WORKS,  CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
7635e3d3d9bSJohan Hedberg 	{ DSP_PASSKEY, DSP_PASSKEY, REQ_PASSKEY, JUST_WORKS, DSP_PASSKEY },
7645e3d3d9bSJohan Hedberg 	{ JUST_WORKS,  JUST_CFM,    JUST_WORKS,  JUST_WORKS, JUST_CFM    },
7655e3d3d9bSJohan Hedberg 	{ DSP_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
7665e3d3d9bSJohan Hedberg };
7675e3d3d9bSJohan Hedberg 
768581370ccSJohan Hedberg static u8 get_auth_method(struct smp_chan *smp, u8 local_io, u8 remote_io)
769581370ccSJohan Hedberg {
7702bcd4003SJohan Hedberg 	/* If either side has unknown io_caps, use JUST_CFM (which gets
7712bcd4003SJohan Hedberg 	 * converted later to JUST_WORKS if we're initiators.
7722bcd4003SJohan Hedberg 	 */
773581370ccSJohan Hedberg 	if (local_io > SMP_IO_KEYBOARD_DISPLAY ||
774581370ccSJohan Hedberg 	    remote_io > SMP_IO_KEYBOARD_DISPLAY)
7752bcd4003SJohan Hedberg 		return JUST_CFM;
776581370ccSJohan Hedberg 
7775e3d3d9bSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags))
7785e3d3d9bSJohan Hedberg 		return sc_method[remote_io][local_io];
7795e3d3d9bSJohan Hedberg 
780581370ccSJohan Hedberg 	return gen_method[remote_io][local_io];
781581370ccSJohan Hedberg }
782581370ccSJohan Hedberg 
7832b64d153SBrian Gix static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
7842b64d153SBrian Gix 						u8 local_io, u8 remote_io)
7852b64d153SBrian Gix {
7862b64d153SBrian Gix 	struct hci_conn *hcon = conn->hcon;
7875d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
7885d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
7892b64d153SBrian Gix 	u32 passkey = 0;
7902b64d153SBrian Gix 	int ret = 0;
7912b64d153SBrian Gix 
7922b64d153SBrian Gix 	/* Initialize key for JUST WORKS */
7932b64d153SBrian Gix 	memset(smp->tk, 0, sizeof(smp->tk));
7944a74d658SJohan Hedberg 	clear_bit(SMP_FLAG_TK_VALID, &smp->flags);
7952b64d153SBrian Gix 
7962b64d153SBrian Gix 	BT_DBG("tk_request: auth:%d lcl:%d rem:%d", auth, local_io, remote_io);
7972b64d153SBrian Gix 
7982bcd4003SJohan Hedberg 	/* If neither side wants MITM, either "just" confirm an incoming
7992bcd4003SJohan Hedberg 	 * request or use just-works for outgoing ones. The JUST_CFM
8002bcd4003SJohan Hedberg 	 * will be converted to JUST_WORKS if necessary later in this
8012bcd4003SJohan Hedberg 	 * function. If either side has MITM look up the method from the
8022bcd4003SJohan Hedberg 	 * table.
8032bcd4003SJohan Hedberg 	 */
804581370ccSJohan Hedberg 	if (!(auth & SMP_AUTH_MITM))
805783e0574SJohan Hedberg 		smp->method = JUST_CFM;
8062b64d153SBrian Gix 	else
807783e0574SJohan Hedberg 		smp->method = get_auth_method(smp, local_io, remote_io);
8082b64d153SBrian Gix 
809a82505c7SJohan Hedberg 	/* Don't confirm locally initiated pairing attempts */
810783e0574SJohan Hedberg 	if (smp->method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR,
811783e0574SJohan Hedberg 						&smp->flags))
812783e0574SJohan Hedberg 		smp->method = JUST_WORKS;
813a82505c7SJohan Hedberg 
81402f3e254SJohan Hedberg 	/* Don't bother user space with no IO capabilities */
815783e0574SJohan Hedberg 	if (smp->method == JUST_CFM &&
816783e0574SJohan Hedberg 	    hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
817783e0574SJohan Hedberg 		smp->method = JUST_WORKS;
81802f3e254SJohan Hedberg 
8192b64d153SBrian Gix 	/* If Just Works, Continue with Zero TK */
820783e0574SJohan Hedberg 	if (smp->method == JUST_WORKS) {
8214a74d658SJohan Hedberg 		set_bit(SMP_FLAG_TK_VALID, &smp->flags);
8222b64d153SBrian Gix 		return 0;
8232b64d153SBrian Gix 	}
8242b64d153SBrian Gix 
8252b64d153SBrian Gix 	/* Not Just Works/Confirm results in MITM Authentication */
826783e0574SJohan Hedberg 	if (smp->method != JUST_CFM) {
8274a74d658SJohan Hedberg 		set_bit(SMP_FLAG_MITM_AUTH, &smp->flags);
8285eb596f5SJohan Hedberg 		if (hcon->pending_sec_level < BT_SECURITY_HIGH)
8295eb596f5SJohan Hedberg 			hcon->pending_sec_level = BT_SECURITY_HIGH;
8305eb596f5SJohan Hedberg 	}
8312b64d153SBrian Gix 
8322b64d153SBrian Gix 	/* If both devices have Keyoard-Display I/O, the master
8332b64d153SBrian Gix 	 * Confirms and the slave Enters the passkey.
8342b64d153SBrian Gix 	 */
835783e0574SJohan Hedberg 	if (smp->method == OVERLAP) {
83640bef302SJohan Hedberg 		if (hcon->role == HCI_ROLE_MASTER)
837783e0574SJohan Hedberg 			smp->method = CFM_PASSKEY;
8382b64d153SBrian Gix 		else
839783e0574SJohan Hedberg 			smp->method = REQ_PASSKEY;
8402b64d153SBrian Gix 	}
8412b64d153SBrian Gix 
84201ad34d2SJohan Hedberg 	/* Generate random passkey. */
843783e0574SJohan Hedberg 	if (smp->method == CFM_PASSKEY) {
844943a732aSJohan Hedberg 		memset(smp->tk, 0, sizeof(smp->tk));
8452b64d153SBrian Gix 		get_random_bytes(&passkey, sizeof(passkey));
8462b64d153SBrian Gix 		passkey %= 1000000;
847943a732aSJohan Hedberg 		put_unaligned_le32(passkey, smp->tk);
8482b64d153SBrian Gix 		BT_DBG("PassKey: %d", passkey);
8494a74d658SJohan Hedberg 		set_bit(SMP_FLAG_TK_VALID, &smp->flags);
8502b64d153SBrian Gix 	}
8512b64d153SBrian Gix 
852783e0574SJohan Hedberg 	if (smp->method == REQ_PASSKEY)
853ce39fb4eSMarcel Holtmann 		ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst,
854272d90dfSJohan Hedberg 						hcon->type, hcon->dst_type);
855783e0574SJohan Hedberg 	else if (smp->method == JUST_CFM)
8564eb65e66SJohan Hedberg 		ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
8574eb65e66SJohan Hedberg 						hcon->type, hcon->dst_type,
8584eb65e66SJohan Hedberg 						passkey, 1);
8592b64d153SBrian Gix 	else
86001ad34d2SJohan Hedberg 		ret = mgmt_user_passkey_notify(hcon->hdev, &hcon->dst,
861272d90dfSJohan Hedberg 						hcon->type, hcon->dst_type,
86239adbffeSJohan Hedberg 						passkey, 0);
8632b64d153SBrian Gix 
8642b64d153SBrian Gix 	return ret;
8652b64d153SBrian Gix }
8662b64d153SBrian Gix 
8671cc61144SJohan Hedberg static u8 smp_confirm(struct smp_chan *smp)
8688aab4757SVinicius Costa Gomes {
8698aab4757SVinicius Costa Gomes 	struct l2cap_conn *conn = smp->conn;
8708aab4757SVinicius Costa Gomes 	struct smp_cmd_pairing_confirm cp;
8718aab4757SVinicius Costa Gomes 	int ret;
8728aab4757SVinicius Costa Gomes 
8738aab4757SVinicius Costa Gomes 	BT_DBG("conn %p", conn);
8748aab4757SVinicius Costa Gomes 
875e491eaf3SJohan Hedberg 	ret = smp_c1(smp->tfm_aes, smp->tk, smp->prnd, smp->preq, smp->prsp,
876b1cd5fd9SJohan Hedberg 		     conn->hcon->init_addr_type, &conn->hcon->init_addr,
877943a732aSJohan Hedberg 		     conn->hcon->resp_addr_type, &conn->hcon->resp_addr,
878943a732aSJohan Hedberg 		     cp.confirm_val);
8791cc61144SJohan Hedberg 	if (ret)
8801cc61144SJohan Hedberg 		return SMP_UNSPECIFIED;
8818aab4757SVinicius Costa Gomes 
8824a74d658SJohan Hedberg 	clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
8832b64d153SBrian Gix 
8848aab4757SVinicius Costa Gomes 	smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
8858aab4757SVinicius Costa Gomes 
886b28b4943SJohan Hedberg 	if (conn->hcon->out)
887b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
888b28b4943SJohan Hedberg 	else
889b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
890b28b4943SJohan Hedberg 
8911cc61144SJohan Hedberg 	return 0;
8928aab4757SVinicius Costa Gomes }
8938aab4757SVinicius Costa Gomes 
894861580a9SJohan Hedberg static u8 smp_random(struct smp_chan *smp)
8958aab4757SVinicius Costa Gomes {
8968aab4757SVinicius Costa Gomes 	struct l2cap_conn *conn = smp->conn;
8978aab4757SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
898861580a9SJohan Hedberg 	u8 confirm[16];
8998aab4757SVinicius Costa Gomes 	int ret;
9008aab4757SVinicius Costa Gomes 
901ec70f36fSJohan Hedberg 	if (IS_ERR_OR_NULL(smp->tfm_aes))
902861580a9SJohan Hedberg 		return SMP_UNSPECIFIED;
9038aab4757SVinicius Costa Gomes 
9048aab4757SVinicius Costa Gomes 	BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
9058aab4757SVinicius Costa Gomes 
906e491eaf3SJohan Hedberg 	ret = smp_c1(smp->tfm_aes, smp->tk, smp->rrnd, smp->preq, smp->prsp,
907b1cd5fd9SJohan Hedberg 		     hcon->init_addr_type, &hcon->init_addr,
908943a732aSJohan Hedberg 		     hcon->resp_addr_type, &hcon->resp_addr, confirm);
909861580a9SJohan Hedberg 	if (ret)
910861580a9SJohan Hedberg 		return SMP_UNSPECIFIED;
9118aab4757SVinicius Costa Gomes 
9128aab4757SVinicius Costa Gomes 	if (memcmp(smp->pcnf, confirm, sizeof(smp->pcnf)) != 0) {
9138aab4757SVinicius Costa Gomes 		BT_ERR("Pairing failed (confirmation values mismatch)");
914861580a9SJohan Hedberg 		return SMP_CONFIRM_FAILED;
9158aab4757SVinicius Costa Gomes 	}
9168aab4757SVinicius Costa Gomes 
9178aab4757SVinicius Costa Gomes 	if (hcon->out) {
918fe39c7b2SMarcel Holtmann 		u8 stk[16];
919fe39c7b2SMarcel Holtmann 		__le64 rand = 0;
920fe39c7b2SMarcel Holtmann 		__le16 ediv = 0;
9218aab4757SVinicius Costa Gomes 
922e491eaf3SJohan Hedberg 		smp_s1(smp->tfm_aes, smp->tk, smp->rrnd, smp->prnd, stk);
9238aab4757SVinicius Costa Gomes 
924f7aa611aSVinicius Costa Gomes 		memset(stk + smp->enc_key_size, 0,
925f7aa611aSVinicius Costa Gomes 		       SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
9268aab4757SVinicius Costa Gomes 
927861580a9SJohan Hedberg 		if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
928861580a9SJohan Hedberg 			return SMP_UNSPECIFIED;
9298aab4757SVinicius Costa Gomes 
9308aab4757SVinicius Costa Gomes 		hci_le_start_enc(hcon, ediv, rand, stk);
931f7aa611aSVinicius Costa Gomes 		hcon->enc_key_size = smp->enc_key_size;
932fe59a05fSJohan Hedberg 		set_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags);
9338aab4757SVinicius Costa Gomes 	} else {
934fff3490fSJohan Hedberg 		u8 stk[16], auth;
935fe39c7b2SMarcel Holtmann 		__le64 rand = 0;
936fe39c7b2SMarcel Holtmann 		__le16 ediv = 0;
9378aab4757SVinicius Costa Gomes 
938943a732aSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
939943a732aSJohan Hedberg 			     smp->prnd);
9408aab4757SVinicius Costa Gomes 
941e491eaf3SJohan Hedberg 		smp_s1(smp->tfm_aes, smp->tk, smp->prnd, smp->rrnd, stk);
9428aab4757SVinicius Costa Gomes 
943f7aa611aSVinicius Costa Gomes 		memset(stk + smp->enc_key_size, 0,
944f7aa611aSVinicius Costa Gomes 		       SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
9458aab4757SVinicius Costa Gomes 
946fff3490fSJohan Hedberg 		if (hcon->pending_sec_level == BT_SECURITY_HIGH)
947fff3490fSJohan Hedberg 			auth = 1;
948fff3490fSJohan Hedberg 		else
949fff3490fSJohan Hedberg 			auth = 0;
950fff3490fSJohan Hedberg 
9517d5843b7SJohan Hedberg 		/* Even though there's no _SLAVE suffix this is the
9527d5843b7SJohan Hedberg 		 * slave STK we're adding for later lookup (the master
9537d5843b7SJohan Hedberg 		 * STK never needs to be stored).
9547d5843b7SJohan Hedberg 		 */
955ce39fb4eSMarcel Holtmann 		hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
9562ceba539SJohan Hedberg 			    SMP_STK, auth, stk, smp->enc_key_size, ediv, rand);
9578aab4757SVinicius Costa Gomes 	}
9588aab4757SVinicius Costa Gomes 
959861580a9SJohan Hedberg 	return 0;
9608aab4757SVinicius Costa Gomes }
9618aab4757SVinicius Costa Gomes 
96244f1a7abSJohan Hedberg static void smp_notify_keys(struct l2cap_conn *conn)
96344f1a7abSJohan Hedberg {
96444f1a7abSJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
96544f1a7abSJohan Hedberg 	struct smp_chan *smp = chan->data;
96644f1a7abSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
96744f1a7abSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
96844f1a7abSJohan Hedberg 	struct smp_cmd_pairing *req = (void *) &smp->preq[1];
96944f1a7abSJohan Hedberg 	struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1];
97044f1a7abSJohan Hedberg 	bool persistent;
97144f1a7abSJohan Hedberg 
97244f1a7abSJohan Hedberg 	if (smp->remote_irk) {
97344f1a7abSJohan Hedberg 		mgmt_new_irk(hdev, smp->remote_irk);
97444f1a7abSJohan Hedberg 		/* Now that user space can be considered to know the
97544f1a7abSJohan Hedberg 		 * identity address track the connection based on it
976b5ae344dSJohan Hedberg 		 * from now on (assuming this is an LE link).
97744f1a7abSJohan Hedberg 		 */
978b5ae344dSJohan Hedberg 		if (hcon->type == LE_LINK) {
97944f1a7abSJohan Hedberg 			bacpy(&hcon->dst, &smp->remote_irk->bdaddr);
98044f1a7abSJohan Hedberg 			hcon->dst_type = smp->remote_irk->addr_type;
981f3d82d0cSJohan Hedberg 			queue_work(hdev->workqueue, &conn->id_addr_update_work);
982b5ae344dSJohan Hedberg 		}
98344f1a7abSJohan Hedberg 
98444f1a7abSJohan Hedberg 		/* When receiving an indentity resolving key for
98544f1a7abSJohan Hedberg 		 * a remote device that does not use a resolvable
98644f1a7abSJohan Hedberg 		 * private address, just remove the key so that
98744f1a7abSJohan Hedberg 		 * it is possible to use the controller white
98844f1a7abSJohan Hedberg 		 * list for scanning.
98944f1a7abSJohan Hedberg 		 *
99044f1a7abSJohan Hedberg 		 * Userspace will have been told to not store
99144f1a7abSJohan Hedberg 		 * this key at this point. So it is safe to
99244f1a7abSJohan Hedberg 		 * just remove it.
99344f1a7abSJohan Hedberg 		 */
99444f1a7abSJohan Hedberg 		if (!bacmp(&smp->remote_irk->rpa, BDADDR_ANY)) {
995adae20cbSJohan Hedberg 			list_del_rcu(&smp->remote_irk->list);
996adae20cbSJohan Hedberg 			kfree_rcu(smp->remote_irk, rcu);
99744f1a7abSJohan Hedberg 			smp->remote_irk = NULL;
99844f1a7abSJohan Hedberg 		}
99944f1a7abSJohan Hedberg 	}
100044f1a7abSJohan Hedberg 
1001b5ae344dSJohan Hedberg 	if (hcon->type == ACL_LINK) {
1002b5ae344dSJohan Hedberg 		if (hcon->key_type == HCI_LK_DEBUG_COMBINATION)
1003b5ae344dSJohan Hedberg 			persistent = false;
1004b5ae344dSJohan Hedberg 		else
1005b5ae344dSJohan Hedberg 			persistent = !test_bit(HCI_CONN_FLUSH_KEY,
1006b5ae344dSJohan Hedberg 					       &hcon->flags);
1007b5ae344dSJohan Hedberg 	} else {
100844f1a7abSJohan Hedberg 		/* The LTKs and CSRKs should be persistent only if both sides
100944f1a7abSJohan Hedberg 		 * had the bonding bit set in their authentication requests.
101044f1a7abSJohan Hedberg 		 */
1011b5ae344dSJohan Hedberg 		persistent = !!((req->auth_req & rsp->auth_req) &
1012b5ae344dSJohan Hedberg 				SMP_AUTH_BONDING);
1013b5ae344dSJohan Hedberg 	}
1014b5ae344dSJohan Hedberg 
101544f1a7abSJohan Hedberg 
101644f1a7abSJohan Hedberg 	if (smp->csrk) {
101744f1a7abSJohan Hedberg 		smp->csrk->bdaddr_type = hcon->dst_type;
101844f1a7abSJohan Hedberg 		bacpy(&smp->csrk->bdaddr, &hcon->dst);
101944f1a7abSJohan Hedberg 		mgmt_new_csrk(hdev, smp->csrk, persistent);
102044f1a7abSJohan Hedberg 	}
102144f1a7abSJohan Hedberg 
102244f1a7abSJohan Hedberg 	if (smp->slave_csrk) {
102344f1a7abSJohan Hedberg 		smp->slave_csrk->bdaddr_type = hcon->dst_type;
102444f1a7abSJohan Hedberg 		bacpy(&smp->slave_csrk->bdaddr, &hcon->dst);
102544f1a7abSJohan Hedberg 		mgmt_new_csrk(hdev, smp->slave_csrk, persistent);
102644f1a7abSJohan Hedberg 	}
102744f1a7abSJohan Hedberg 
102844f1a7abSJohan Hedberg 	if (smp->ltk) {
102944f1a7abSJohan Hedberg 		smp->ltk->bdaddr_type = hcon->dst_type;
103044f1a7abSJohan Hedberg 		bacpy(&smp->ltk->bdaddr, &hcon->dst);
103144f1a7abSJohan Hedberg 		mgmt_new_ltk(hdev, smp->ltk, persistent);
103244f1a7abSJohan Hedberg 	}
103344f1a7abSJohan Hedberg 
103444f1a7abSJohan Hedberg 	if (smp->slave_ltk) {
103544f1a7abSJohan Hedberg 		smp->slave_ltk->bdaddr_type = hcon->dst_type;
103644f1a7abSJohan Hedberg 		bacpy(&smp->slave_ltk->bdaddr, &hcon->dst);
103744f1a7abSJohan Hedberg 		mgmt_new_ltk(hdev, smp->slave_ltk, persistent);
103844f1a7abSJohan Hedberg 	}
10396a77083aSJohan Hedberg 
10406a77083aSJohan Hedberg 	if (smp->link_key) {
1041e3befab9SJohan Hedberg 		struct link_key *key;
1042e3befab9SJohan Hedberg 		u8 type;
1043e3befab9SJohan Hedberg 
1044e3befab9SJohan Hedberg 		if (test_bit(SMP_FLAG_DEBUG_KEY, &smp->flags))
1045e3befab9SJohan Hedberg 			type = HCI_LK_DEBUG_COMBINATION;
1046e3befab9SJohan Hedberg 		else if (hcon->sec_level == BT_SECURITY_FIPS)
1047e3befab9SJohan Hedberg 			type = HCI_LK_AUTH_COMBINATION_P256;
1048e3befab9SJohan Hedberg 		else
1049e3befab9SJohan Hedberg 			type = HCI_LK_UNAUTH_COMBINATION_P256;
1050e3befab9SJohan Hedberg 
1051e3befab9SJohan Hedberg 		key = hci_add_link_key(hdev, smp->conn->hcon, &hcon->dst,
1052e3befab9SJohan Hedberg 				       smp->link_key, type, 0, &persistent);
1053e3befab9SJohan Hedberg 		if (key) {
1054e3befab9SJohan Hedberg 			mgmt_new_link_key(hdev, key, persistent);
1055e3befab9SJohan Hedberg 
1056e3befab9SJohan Hedberg 			/* Don't keep debug keys around if the relevant
1057e3befab9SJohan Hedberg 			 * flag is not set.
1058e3befab9SJohan Hedberg 			 */
1059d7a5a11dSMarcel Holtmann 			if (!hci_dev_test_flag(hdev, HCI_KEEP_DEBUG_KEYS) &&
1060e3befab9SJohan Hedberg 			    key->type == HCI_LK_DEBUG_COMBINATION) {
1061e3befab9SJohan Hedberg 				list_del_rcu(&key->list);
1062e3befab9SJohan Hedberg 				kfree_rcu(key, rcu);
1063e3befab9SJohan Hedberg 			}
1064e3befab9SJohan Hedberg 		}
10656a77083aSJohan Hedberg 	}
10666a77083aSJohan Hedberg }
10676a77083aSJohan Hedberg 
1068d3e54a87SJohan Hedberg static void sc_add_ltk(struct smp_chan *smp)
1069d3e54a87SJohan Hedberg {
1070d3e54a87SJohan Hedberg 	struct hci_conn *hcon = smp->conn->hcon;
1071d3e54a87SJohan Hedberg 	u8 key_type, auth;
1072d3e54a87SJohan Hedberg 
1073d3e54a87SJohan Hedberg 	if (test_bit(SMP_FLAG_DEBUG_KEY, &smp->flags))
1074d3e54a87SJohan Hedberg 		key_type = SMP_LTK_P256_DEBUG;
1075d3e54a87SJohan Hedberg 	else
1076d3e54a87SJohan Hedberg 		key_type = SMP_LTK_P256;
1077d3e54a87SJohan Hedberg 
1078d3e54a87SJohan Hedberg 	if (hcon->pending_sec_level == BT_SECURITY_FIPS)
1079d3e54a87SJohan Hedberg 		auth = 1;
1080d3e54a87SJohan Hedberg 	else
1081d3e54a87SJohan Hedberg 		auth = 0;
1082d3e54a87SJohan Hedberg 
1083d3e54a87SJohan Hedberg 	memset(smp->tk + smp->enc_key_size, 0,
1084d3e54a87SJohan Hedberg 	       SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
1085d3e54a87SJohan Hedberg 
1086d3e54a87SJohan Hedberg 	smp->ltk = hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
1087d3e54a87SJohan Hedberg 			       key_type, auth, smp->tk, smp->enc_key_size,
1088d3e54a87SJohan Hedberg 			       0, 0);
1089d3e54a87SJohan Hedberg }
1090d3e54a87SJohan Hedberg 
10916a77083aSJohan Hedberg static void sc_generate_link_key(struct smp_chan *smp)
10926a77083aSJohan Hedberg {
10936a77083aSJohan Hedberg 	/* These constants are as specified in the core specification.
10946a77083aSJohan Hedberg 	 * In ASCII they spell out to 'tmp1' and 'lebr'.
10956a77083aSJohan Hedberg 	 */
10966a77083aSJohan Hedberg 	const u8 tmp1[4] = { 0x31, 0x70, 0x6d, 0x74 };
10976a77083aSJohan Hedberg 	const u8 lebr[4] = { 0x72, 0x62, 0x65, 0x6c };
10986a77083aSJohan Hedberg 
10996a77083aSJohan Hedberg 	smp->link_key = kzalloc(16, GFP_KERNEL);
11006a77083aSJohan Hedberg 	if (!smp->link_key)
11016a77083aSJohan Hedberg 		return;
11026a77083aSJohan Hedberg 
11036a77083aSJohan Hedberg 	if (smp_h6(smp->tfm_cmac, smp->tk, tmp1, smp->link_key)) {
1104276812ecSMarcel Holtmann 		kzfree(smp->link_key);
11056a77083aSJohan Hedberg 		smp->link_key = NULL;
11066a77083aSJohan Hedberg 		return;
11076a77083aSJohan Hedberg 	}
11086a77083aSJohan Hedberg 
11096a77083aSJohan Hedberg 	if (smp_h6(smp->tfm_cmac, smp->link_key, lebr, smp->link_key)) {
1110276812ecSMarcel Holtmann 		kzfree(smp->link_key);
11116a77083aSJohan Hedberg 		smp->link_key = NULL;
11126a77083aSJohan Hedberg 		return;
11136a77083aSJohan Hedberg 	}
111444f1a7abSJohan Hedberg }
111544f1a7abSJohan Hedberg 
1116b28b4943SJohan Hedberg static void smp_allow_key_dist(struct smp_chan *smp)
1117b28b4943SJohan Hedberg {
1118b28b4943SJohan Hedberg 	/* Allow the first expected phase 3 PDU. The rest of the PDUs
1119b28b4943SJohan Hedberg 	 * will be allowed in each PDU handler to ensure we receive
1120b28b4943SJohan Hedberg 	 * them in the correct order.
1121b28b4943SJohan Hedberg 	 */
1122b28b4943SJohan Hedberg 	if (smp->remote_key_dist & SMP_DIST_ENC_KEY)
1123b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_ENCRYPT_INFO);
1124b28b4943SJohan Hedberg 	else if (smp->remote_key_dist & SMP_DIST_ID_KEY)
1125b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO);
1126b28b4943SJohan Hedberg 	else if (smp->remote_key_dist & SMP_DIST_SIGN)
1127b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO);
1128b28b4943SJohan Hedberg }
1129b28b4943SJohan Hedberg 
1130b5ae344dSJohan Hedberg static void sc_generate_ltk(struct smp_chan *smp)
1131b5ae344dSJohan Hedberg {
1132b5ae344dSJohan Hedberg 	/* These constants are as specified in the core specification.
1133b5ae344dSJohan Hedberg 	 * In ASCII they spell out to 'tmp2' and 'brle'.
1134b5ae344dSJohan Hedberg 	 */
1135b5ae344dSJohan Hedberg 	const u8 tmp2[4] = { 0x32, 0x70, 0x6d, 0x74 };
1136b5ae344dSJohan Hedberg 	const u8 brle[4] = { 0x65, 0x6c, 0x72, 0x62 };
1137b5ae344dSJohan Hedberg 	struct hci_conn *hcon = smp->conn->hcon;
1138b5ae344dSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
1139b5ae344dSJohan Hedberg 	struct link_key *key;
1140b5ae344dSJohan Hedberg 
1141b5ae344dSJohan Hedberg 	key = hci_find_link_key(hdev, &hcon->dst);
1142b5ae344dSJohan Hedberg 	if (!key) {
1143b5ae344dSJohan Hedberg 		BT_ERR("%s No Link Key found to generate LTK", hdev->name);
1144b5ae344dSJohan Hedberg 		return;
1145b5ae344dSJohan Hedberg 	}
1146b5ae344dSJohan Hedberg 
1147b5ae344dSJohan Hedberg 	if (key->type == HCI_LK_DEBUG_COMBINATION)
1148b5ae344dSJohan Hedberg 		set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags);
1149b5ae344dSJohan Hedberg 
1150b5ae344dSJohan Hedberg 	if (smp_h6(smp->tfm_cmac, key->val, tmp2, smp->tk))
1151b5ae344dSJohan Hedberg 		return;
1152b5ae344dSJohan Hedberg 
1153b5ae344dSJohan Hedberg 	if (smp_h6(smp->tfm_cmac, smp->tk, brle, smp->tk))
1154b5ae344dSJohan Hedberg 		return;
1155b5ae344dSJohan Hedberg 
1156b5ae344dSJohan Hedberg 	sc_add_ltk(smp);
1157b5ae344dSJohan Hedberg }
1158b5ae344dSJohan Hedberg 
1159d6268e86SJohan Hedberg static void smp_distribute_keys(struct smp_chan *smp)
116044f1a7abSJohan Hedberg {
116144f1a7abSJohan Hedberg 	struct smp_cmd_pairing *req, *rsp;
116286d1407cSJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
116344f1a7abSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
116444f1a7abSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
116544f1a7abSJohan Hedberg 	__u8 *keydist;
116644f1a7abSJohan Hedberg 
116744f1a7abSJohan Hedberg 	BT_DBG("conn %p", conn);
116844f1a7abSJohan Hedberg 
116944f1a7abSJohan Hedberg 	rsp = (void *) &smp->prsp[1];
117044f1a7abSJohan Hedberg 
117144f1a7abSJohan Hedberg 	/* The responder sends its keys first */
1172b28b4943SJohan Hedberg 	if (hcon->out && (smp->remote_key_dist & KEY_DIST_MASK)) {
1173b28b4943SJohan Hedberg 		smp_allow_key_dist(smp);
117486d1407cSJohan Hedberg 		return;
1175b28b4943SJohan Hedberg 	}
117644f1a7abSJohan Hedberg 
117744f1a7abSJohan Hedberg 	req = (void *) &smp->preq[1];
117844f1a7abSJohan Hedberg 
117944f1a7abSJohan Hedberg 	if (hcon->out) {
118044f1a7abSJohan Hedberg 		keydist = &rsp->init_key_dist;
118144f1a7abSJohan Hedberg 		*keydist &= req->init_key_dist;
118244f1a7abSJohan Hedberg 	} else {
118344f1a7abSJohan Hedberg 		keydist = &rsp->resp_key_dist;
118444f1a7abSJohan Hedberg 		*keydist &= req->resp_key_dist;
118544f1a7abSJohan Hedberg 	}
118644f1a7abSJohan Hedberg 
11876a77083aSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
1188b5ae344dSJohan Hedberg 		if (hcon->type == LE_LINK && (*keydist & SMP_DIST_LINK_KEY))
11896a77083aSJohan Hedberg 			sc_generate_link_key(smp);
1190b5ae344dSJohan Hedberg 		if (hcon->type == ACL_LINK && (*keydist & SMP_DIST_ENC_KEY))
1191b5ae344dSJohan Hedberg 			sc_generate_ltk(smp);
11926a77083aSJohan Hedberg 
11936a77083aSJohan Hedberg 		/* Clear the keys which are generated but not distributed */
11946a77083aSJohan Hedberg 		*keydist &= ~SMP_SC_NO_DIST;
11956a77083aSJohan Hedberg 	}
11966a77083aSJohan Hedberg 
119744f1a7abSJohan Hedberg 	BT_DBG("keydist 0x%x", *keydist);
119844f1a7abSJohan Hedberg 
119944f1a7abSJohan Hedberg 	if (*keydist & SMP_DIST_ENC_KEY) {
120044f1a7abSJohan Hedberg 		struct smp_cmd_encrypt_info enc;
120144f1a7abSJohan Hedberg 		struct smp_cmd_master_ident ident;
120244f1a7abSJohan Hedberg 		struct smp_ltk *ltk;
120344f1a7abSJohan Hedberg 		u8 authenticated;
120444f1a7abSJohan Hedberg 		__le16 ediv;
120544f1a7abSJohan Hedberg 		__le64 rand;
120644f1a7abSJohan Hedberg 
120744f1a7abSJohan Hedberg 		get_random_bytes(enc.ltk, sizeof(enc.ltk));
120844f1a7abSJohan Hedberg 		get_random_bytes(&ediv, sizeof(ediv));
120944f1a7abSJohan Hedberg 		get_random_bytes(&rand, sizeof(rand));
121044f1a7abSJohan Hedberg 
121144f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
121244f1a7abSJohan Hedberg 
121344f1a7abSJohan Hedberg 		authenticated = hcon->sec_level == BT_SECURITY_HIGH;
121444f1a7abSJohan Hedberg 		ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type,
121544f1a7abSJohan Hedberg 				  SMP_LTK_SLAVE, authenticated, enc.ltk,
121644f1a7abSJohan Hedberg 				  smp->enc_key_size, ediv, rand);
121744f1a7abSJohan Hedberg 		smp->slave_ltk = ltk;
121844f1a7abSJohan Hedberg 
121944f1a7abSJohan Hedberg 		ident.ediv = ediv;
122044f1a7abSJohan Hedberg 		ident.rand = rand;
122144f1a7abSJohan Hedberg 
122244f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident);
122344f1a7abSJohan Hedberg 
122444f1a7abSJohan Hedberg 		*keydist &= ~SMP_DIST_ENC_KEY;
122544f1a7abSJohan Hedberg 	}
122644f1a7abSJohan Hedberg 
122744f1a7abSJohan Hedberg 	if (*keydist & SMP_DIST_ID_KEY) {
122844f1a7abSJohan Hedberg 		struct smp_cmd_ident_addr_info addrinfo;
122944f1a7abSJohan Hedberg 		struct smp_cmd_ident_info idinfo;
123044f1a7abSJohan Hedberg 
123144f1a7abSJohan Hedberg 		memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk));
123244f1a7abSJohan Hedberg 
123344f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo);
123444f1a7abSJohan Hedberg 
123544f1a7abSJohan Hedberg 		/* The hci_conn contains the local identity address
123644f1a7abSJohan Hedberg 		 * after the connection has been established.
123744f1a7abSJohan Hedberg 		 *
123844f1a7abSJohan Hedberg 		 * This is true even when the connection has been
123944f1a7abSJohan Hedberg 		 * established using a resolvable random address.
124044f1a7abSJohan Hedberg 		 */
124144f1a7abSJohan Hedberg 		bacpy(&addrinfo.bdaddr, &hcon->src);
124244f1a7abSJohan Hedberg 		addrinfo.addr_type = hcon->src_type;
124344f1a7abSJohan Hedberg 
124444f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo),
124544f1a7abSJohan Hedberg 			     &addrinfo);
124644f1a7abSJohan Hedberg 
124744f1a7abSJohan Hedberg 		*keydist &= ~SMP_DIST_ID_KEY;
124844f1a7abSJohan Hedberg 	}
124944f1a7abSJohan Hedberg 
125044f1a7abSJohan Hedberg 	if (*keydist & SMP_DIST_SIGN) {
125144f1a7abSJohan Hedberg 		struct smp_cmd_sign_info sign;
125244f1a7abSJohan Hedberg 		struct smp_csrk *csrk;
125344f1a7abSJohan Hedberg 
125444f1a7abSJohan Hedberg 		/* Generate a new random key */
125544f1a7abSJohan Hedberg 		get_random_bytes(sign.csrk, sizeof(sign.csrk));
125644f1a7abSJohan Hedberg 
125744f1a7abSJohan Hedberg 		csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
125844f1a7abSJohan Hedberg 		if (csrk) {
12594cd3928aSJohan Hedberg 			if (hcon->sec_level > BT_SECURITY_MEDIUM)
12604cd3928aSJohan Hedberg 				csrk->type = MGMT_CSRK_LOCAL_AUTHENTICATED;
12614cd3928aSJohan Hedberg 			else
12624cd3928aSJohan Hedberg 				csrk->type = MGMT_CSRK_LOCAL_UNAUTHENTICATED;
126344f1a7abSJohan Hedberg 			memcpy(csrk->val, sign.csrk, sizeof(csrk->val));
126444f1a7abSJohan Hedberg 		}
126544f1a7abSJohan Hedberg 		smp->slave_csrk = csrk;
126644f1a7abSJohan Hedberg 
126744f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign);
126844f1a7abSJohan Hedberg 
126944f1a7abSJohan Hedberg 		*keydist &= ~SMP_DIST_SIGN;
127044f1a7abSJohan Hedberg 	}
127144f1a7abSJohan Hedberg 
127244f1a7abSJohan Hedberg 	/* If there are still keys to be received wait for them */
1273b28b4943SJohan Hedberg 	if (smp->remote_key_dist & KEY_DIST_MASK) {
1274b28b4943SJohan Hedberg 		smp_allow_key_dist(smp);
127586d1407cSJohan Hedberg 		return;
1276b28b4943SJohan Hedberg 	}
127744f1a7abSJohan Hedberg 
127844f1a7abSJohan Hedberg 	set_bit(SMP_FLAG_COMPLETE, &smp->flags);
127944f1a7abSJohan Hedberg 	smp_notify_keys(conn);
128044f1a7abSJohan Hedberg 
128144f1a7abSJohan Hedberg 	smp_chan_destroy(conn);
128244f1a7abSJohan Hedberg }
128344f1a7abSJohan Hedberg 
1284b68fda68SJohan Hedberg static void smp_timeout(struct work_struct *work)
1285b68fda68SJohan Hedberg {
1286b68fda68SJohan Hedberg 	struct smp_chan *smp = container_of(work, struct smp_chan,
1287b68fda68SJohan Hedberg 					    security_timer.work);
1288b68fda68SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
1289b68fda68SJohan Hedberg 
1290b68fda68SJohan Hedberg 	BT_DBG("conn %p", conn);
1291b68fda68SJohan Hedberg 
12921e91c29eSJohan Hedberg 	hci_disconnect(conn->hcon, HCI_ERROR_REMOTE_USER_TERM);
1293b68fda68SJohan Hedberg }
1294b68fda68SJohan Hedberg 
12958aab4757SVinicius Costa Gomes static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
12968aab4757SVinicius Costa Gomes {
12975d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
12988aab4757SVinicius Costa Gomes 	struct smp_chan *smp;
12998aab4757SVinicius Costa Gomes 
1300f1560463SMarcel Holtmann 	smp = kzalloc(sizeof(*smp), GFP_ATOMIC);
1301fc75cc86SJohan Hedberg 	if (!smp)
13028aab4757SVinicius Costa Gomes 		return NULL;
13038aab4757SVinicius Costa Gomes 
13046a7bd103SJohan Hedberg 	smp->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
13056a7bd103SJohan Hedberg 	if (IS_ERR(smp->tfm_aes)) {
13066a7bd103SJohan Hedberg 		BT_ERR("Unable to create ECB crypto context");
1307276812ecSMarcel Holtmann 		kzfree(smp);
13086a7bd103SJohan Hedberg 		return NULL;
13096a7bd103SJohan Hedberg 	}
13106a7bd103SJohan Hedberg 
1311407cecf6SJohan Hedberg 	smp->tfm_cmac = crypto_alloc_hash("cmac(aes)", 0, CRYPTO_ALG_ASYNC);
1312407cecf6SJohan Hedberg 	if (IS_ERR(smp->tfm_cmac)) {
1313407cecf6SJohan Hedberg 		BT_ERR("Unable to create CMAC crypto context");
1314407cecf6SJohan Hedberg 		crypto_free_blkcipher(smp->tfm_aes);
1315276812ecSMarcel Holtmann 		kzfree(smp);
1316407cecf6SJohan Hedberg 		return NULL;
1317407cecf6SJohan Hedberg 	}
1318407cecf6SJohan Hedberg 
13198aab4757SVinicius Costa Gomes 	smp->conn = conn;
13205d88cc73SJohan Hedberg 	chan->data = smp;
13218aab4757SVinicius Costa Gomes 
1322b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_FAIL);
1323b28b4943SJohan Hedberg 
1324b68fda68SJohan Hedberg 	INIT_DELAYED_WORK(&smp->security_timer, smp_timeout);
1325b68fda68SJohan Hedberg 
13268aab4757SVinicius Costa Gomes 	hci_conn_hold(conn->hcon);
13278aab4757SVinicius Costa Gomes 
13288aab4757SVinicius Costa Gomes 	return smp;
13298aab4757SVinicius Costa Gomes }
13308aab4757SVinicius Costa Gomes 
1331760b018bSJohan Hedberg static int sc_mackey_and_ltk(struct smp_chan *smp, u8 mackey[16], u8 ltk[16])
1332760b018bSJohan Hedberg {
1333760b018bSJohan Hedberg 	struct hci_conn *hcon = smp->conn->hcon;
1334760b018bSJohan Hedberg 	u8 *na, *nb, a[7], b[7];
1335760b018bSJohan Hedberg 
1336760b018bSJohan Hedberg 	if (hcon->out) {
1337760b018bSJohan Hedberg 		na   = smp->prnd;
1338760b018bSJohan Hedberg 		nb   = smp->rrnd;
1339760b018bSJohan Hedberg 	} else {
1340760b018bSJohan Hedberg 		na   = smp->rrnd;
1341760b018bSJohan Hedberg 		nb   = smp->prnd;
1342760b018bSJohan Hedberg 	}
1343760b018bSJohan Hedberg 
1344760b018bSJohan Hedberg 	memcpy(a, &hcon->init_addr, 6);
1345760b018bSJohan Hedberg 	memcpy(b, &hcon->resp_addr, 6);
1346760b018bSJohan Hedberg 	a[6] = hcon->init_addr_type;
1347760b018bSJohan Hedberg 	b[6] = hcon->resp_addr_type;
1348760b018bSJohan Hedberg 
1349760b018bSJohan Hedberg 	return smp_f5(smp->tfm_cmac, smp->dhkey, na, nb, a, b, mackey, ltk);
1350760b018bSJohan Hedberg }
1351760b018bSJohan Hedberg 
135238606f14SJohan Hedberg static void sc_dhkey_check(struct smp_chan *smp)
1353760b018bSJohan Hedberg {
1354760b018bSJohan Hedberg 	struct hci_conn *hcon = smp->conn->hcon;
1355760b018bSJohan Hedberg 	struct smp_cmd_dhkey_check check;
1356760b018bSJohan Hedberg 	u8 a[7], b[7], *local_addr, *remote_addr;
1357760b018bSJohan Hedberg 	u8 io_cap[3], r[16];
1358760b018bSJohan Hedberg 
1359760b018bSJohan Hedberg 	memcpy(a, &hcon->init_addr, 6);
1360760b018bSJohan Hedberg 	memcpy(b, &hcon->resp_addr, 6);
1361760b018bSJohan Hedberg 	a[6] = hcon->init_addr_type;
1362760b018bSJohan Hedberg 	b[6] = hcon->resp_addr_type;
1363760b018bSJohan Hedberg 
1364760b018bSJohan Hedberg 	if (hcon->out) {
1365760b018bSJohan Hedberg 		local_addr = a;
1366760b018bSJohan Hedberg 		remote_addr = b;
1367760b018bSJohan Hedberg 		memcpy(io_cap, &smp->preq[1], 3);
1368760b018bSJohan Hedberg 	} else {
1369760b018bSJohan Hedberg 		local_addr = b;
1370760b018bSJohan Hedberg 		remote_addr = a;
1371760b018bSJohan Hedberg 		memcpy(io_cap, &smp->prsp[1], 3);
1372760b018bSJohan Hedberg 	}
1373760b018bSJohan Hedberg 
1374dddd3059SJohan Hedberg 	memset(r, 0, sizeof(r));
1375dddd3059SJohan Hedberg 
1376dddd3059SJohan Hedberg 	if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY)
137738606f14SJohan Hedberg 		put_unaligned_le32(hcon->passkey_notify, r);
1378760b018bSJohan Hedberg 
1379a29b0733SJohan Hedberg 	if (smp->method == REQ_OOB)
1380a29b0733SJohan Hedberg 		memcpy(r, smp->rr, 16);
1381a29b0733SJohan Hedberg 
1382760b018bSJohan Hedberg 	smp_f6(smp->tfm_cmac, smp->mackey, smp->prnd, smp->rrnd, r, io_cap,
1383760b018bSJohan Hedberg 	       local_addr, remote_addr, check.e);
1384760b018bSJohan Hedberg 
1385760b018bSJohan Hedberg 	smp_send_cmd(smp->conn, SMP_CMD_DHKEY_CHECK, sizeof(check), &check);
1386dddd3059SJohan Hedberg }
1387dddd3059SJohan Hedberg 
138838606f14SJohan Hedberg static u8 sc_passkey_send_confirm(struct smp_chan *smp)
138938606f14SJohan Hedberg {
139038606f14SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
139138606f14SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
139238606f14SJohan Hedberg 	struct smp_cmd_pairing_confirm cfm;
139338606f14SJohan Hedberg 	u8 r;
139438606f14SJohan Hedberg 
139538606f14SJohan Hedberg 	r = ((hcon->passkey_notify >> smp->passkey_round) & 0x01);
139638606f14SJohan Hedberg 	r |= 0x80;
139738606f14SJohan Hedberg 
139838606f14SJohan Hedberg 	get_random_bytes(smp->prnd, sizeof(smp->prnd));
139938606f14SJohan Hedberg 
140038606f14SJohan Hedberg 	if (smp_f4(smp->tfm_cmac, smp->local_pk, smp->remote_pk, smp->prnd, r,
140138606f14SJohan Hedberg 		   cfm.confirm_val))
140238606f14SJohan Hedberg 		return SMP_UNSPECIFIED;
140338606f14SJohan Hedberg 
140438606f14SJohan Hedberg 	smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cfm), &cfm);
140538606f14SJohan Hedberg 
140638606f14SJohan Hedberg 	return 0;
140738606f14SJohan Hedberg }
140838606f14SJohan Hedberg 
140938606f14SJohan Hedberg static u8 sc_passkey_round(struct smp_chan *smp, u8 smp_op)
141038606f14SJohan Hedberg {
141138606f14SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
141238606f14SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
141338606f14SJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
141438606f14SJohan Hedberg 	u8 cfm[16], r;
141538606f14SJohan Hedberg 
141638606f14SJohan Hedberg 	/* Ignore the PDU if we've already done 20 rounds (0 - 19) */
141738606f14SJohan Hedberg 	if (smp->passkey_round >= 20)
141838606f14SJohan Hedberg 		return 0;
141938606f14SJohan Hedberg 
142038606f14SJohan Hedberg 	switch (smp_op) {
142138606f14SJohan Hedberg 	case SMP_CMD_PAIRING_RANDOM:
142238606f14SJohan Hedberg 		r = ((hcon->passkey_notify >> smp->passkey_round) & 0x01);
142338606f14SJohan Hedberg 		r |= 0x80;
142438606f14SJohan Hedberg 
142538606f14SJohan Hedberg 		if (smp_f4(smp->tfm_cmac, smp->remote_pk, smp->local_pk,
142638606f14SJohan Hedberg 			   smp->rrnd, r, cfm))
142738606f14SJohan Hedberg 			return SMP_UNSPECIFIED;
142838606f14SJohan Hedberg 
142938606f14SJohan Hedberg 		if (memcmp(smp->pcnf, cfm, 16))
143038606f14SJohan Hedberg 			return SMP_CONFIRM_FAILED;
143138606f14SJohan Hedberg 
143238606f14SJohan Hedberg 		smp->passkey_round++;
143338606f14SJohan Hedberg 
143438606f14SJohan Hedberg 		if (smp->passkey_round == 20) {
143538606f14SJohan Hedberg 			/* Generate MacKey and LTK */
143638606f14SJohan Hedberg 			if (sc_mackey_and_ltk(smp, smp->mackey, smp->tk))
143738606f14SJohan Hedberg 				return SMP_UNSPECIFIED;
143838606f14SJohan Hedberg 		}
143938606f14SJohan Hedberg 
144038606f14SJohan Hedberg 		/* The round is only complete when the initiator
144138606f14SJohan Hedberg 		 * receives pairing random.
144238606f14SJohan Hedberg 		 */
144338606f14SJohan Hedberg 		if (!hcon->out) {
144438606f14SJohan Hedberg 			smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM,
144538606f14SJohan Hedberg 				     sizeof(smp->prnd), smp->prnd);
1446d3e54a87SJohan Hedberg 			if (smp->passkey_round == 20)
144738606f14SJohan Hedberg 				SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
1448d3e54a87SJohan Hedberg 			else
144938606f14SJohan Hedberg 				SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
145038606f14SJohan Hedberg 			return 0;
145138606f14SJohan Hedberg 		}
145238606f14SJohan Hedberg 
145338606f14SJohan Hedberg 		/* Start the next round */
145438606f14SJohan Hedberg 		if (smp->passkey_round != 20)
145538606f14SJohan Hedberg 			return sc_passkey_round(smp, 0);
145638606f14SJohan Hedberg 
145738606f14SJohan Hedberg 		/* Passkey rounds are complete - start DHKey Check */
145838606f14SJohan Hedberg 		sc_dhkey_check(smp);
145938606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
146038606f14SJohan Hedberg 
146138606f14SJohan Hedberg 		break;
146238606f14SJohan Hedberg 
146338606f14SJohan Hedberg 	case SMP_CMD_PAIRING_CONFIRM:
146438606f14SJohan Hedberg 		if (test_bit(SMP_FLAG_WAIT_USER, &smp->flags)) {
146538606f14SJohan Hedberg 			set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
146638606f14SJohan Hedberg 			return 0;
146738606f14SJohan Hedberg 		}
146838606f14SJohan Hedberg 
146938606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
147038606f14SJohan Hedberg 
147138606f14SJohan Hedberg 		if (hcon->out) {
147238606f14SJohan Hedberg 			smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM,
147338606f14SJohan Hedberg 				     sizeof(smp->prnd), smp->prnd);
147438606f14SJohan Hedberg 			return 0;
147538606f14SJohan Hedberg 		}
147638606f14SJohan Hedberg 
147738606f14SJohan Hedberg 		return sc_passkey_send_confirm(smp);
147838606f14SJohan Hedberg 
147938606f14SJohan Hedberg 	case SMP_CMD_PUBLIC_KEY:
148038606f14SJohan Hedberg 	default:
148138606f14SJohan Hedberg 		/* Initiating device starts the round */
148238606f14SJohan Hedberg 		if (!hcon->out)
148338606f14SJohan Hedberg 			return 0;
148438606f14SJohan Hedberg 
148538606f14SJohan Hedberg 		BT_DBG("%s Starting passkey round %u", hdev->name,
148638606f14SJohan Hedberg 		       smp->passkey_round + 1);
148738606f14SJohan Hedberg 
148838606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
148938606f14SJohan Hedberg 
149038606f14SJohan Hedberg 		return sc_passkey_send_confirm(smp);
149138606f14SJohan Hedberg 	}
149238606f14SJohan Hedberg 
149338606f14SJohan Hedberg 	return 0;
149438606f14SJohan Hedberg }
149538606f14SJohan Hedberg 
1496dddd3059SJohan Hedberg static int sc_user_reply(struct smp_chan *smp, u16 mgmt_op, __le32 passkey)
1497dddd3059SJohan Hedberg {
149838606f14SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
149938606f14SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
150038606f14SJohan Hedberg 	u8 smp_op;
150138606f14SJohan Hedberg 
150238606f14SJohan Hedberg 	clear_bit(SMP_FLAG_WAIT_USER, &smp->flags);
150338606f14SJohan Hedberg 
1504dddd3059SJohan Hedberg 	switch (mgmt_op) {
1505dddd3059SJohan Hedberg 	case MGMT_OP_USER_PASSKEY_NEG_REPLY:
1506dddd3059SJohan Hedberg 		smp_failure(smp->conn, SMP_PASSKEY_ENTRY_FAILED);
1507dddd3059SJohan Hedberg 		return 0;
1508dddd3059SJohan Hedberg 	case MGMT_OP_USER_CONFIRM_NEG_REPLY:
1509dddd3059SJohan Hedberg 		smp_failure(smp->conn, SMP_NUMERIC_COMP_FAILED);
1510dddd3059SJohan Hedberg 		return 0;
151138606f14SJohan Hedberg 	case MGMT_OP_USER_PASSKEY_REPLY:
151238606f14SJohan Hedberg 		hcon->passkey_notify = le32_to_cpu(passkey);
151338606f14SJohan Hedberg 		smp->passkey_round = 0;
151438606f14SJohan Hedberg 
151538606f14SJohan Hedberg 		if (test_and_clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags))
151638606f14SJohan Hedberg 			smp_op = SMP_CMD_PAIRING_CONFIRM;
151738606f14SJohan Hedberg 		else
151838606f14SJohan Hedberg 			smp_op = 0;
151938606f14SJohan Hedberg 
152038606f14SJohan Hedberg 		if (sc_passkey_round(smp, smp_op))
152138606f14SJohan Hedberg 			return -EIO;
152238606f14SJohan Hedberg 
152338606f14SJohan Hedberg 		return 0;
1524dddd3059SJohan Hedberg 	}
1525dddd3059SJohan Hedberg 
1526d3e54a87SJohan Hedberg 	/* Initiator sends DHKey check first */
1527d3e54a87SJohan Hedberg 	if (hcon->out) {
152838606f14SJohan Hedberg 		sc_dhkey_check(smp);
1529d3e54a87SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
1530d3e54a87SJohan Hedberg 	} else if (test_and_clear_bit(SMP_FLAG_DHKEY_PENDING, &smp->flags)) {
1531d3e54a87SJohan Hedberg 		sc_dhkey_check(smp);
1532d3e54a87SJohan Hedberg 		sc_add_ltk(smp);
1533d3e54a87SJohan Hedberg 	}
1534760b018bSJohan Hedberg 
1535760b018bSJohan Hedberg 	return 0;
1536760b018bSJohan Hedberg }
1537760b018bSJohan Hedberg 
15382b64d153SBrian Gix int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
15392b64d153SBrian Gix {
1540b10e8017SJohan Hedberg 	struct l2cap_conn *conn = hcon->l2cap_data;
15415d88cc73SJohan Hedberg 	struct l2cap_chan *chan;
15422b64d153SBrian Gix 	struct smp_chan *smp;
15432b64d153SBrian Gix 	u32 value;
1544fc75cc86SJohan Hedberg 	int err;
15452b64d153SBrian Gix 
15462b64d153SBrian Gix 	BT_DBG("");
15472b64d153SBrian Gix 
1548fc75cc86SJohan Hedberg 	if (!conn)
15492b64d153SBrian Gix 		return -ENOTCONN;
15502b64d153SBrian Gix 
15515d88cc73SJohan Hedberg 	chan = conn->smp;
15525d88cc73SJohan Hedberg 	if (!chan)
15535d88cc73SJohan Hedberg 		return -ENOTCONN;
15545d88cc73SJohan Hedberg 
1555fc75cc86SJohan Hedberg 	l2cap_chan_lock(chan);
1556fc75cc86SJohan Hedberg 	if (!chan->data) {
1557fc75cc86SJohan Hedberg 		err = -ENOTCONN;
1558fc75cc86SJohan Hedberg 		goto unlock;
1559fc75cc86SJohan Hedberg 	}
1560fc75cc86SJohan Hedberg 
15615d88cc73SJohan Hedberg 	smp = chan->data;
15622b64d153SBrian Gix 
1563760b018bSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
1564760b018bSJohan Hedberg 		err = sc_user_reply(smp, mgmt_op, passkey);
1565760b018bSJohan Hedberg 		goto unlock;
1566760b018bSJohan Hedberg 	}
1567760b018bSJohan Hedberg 
15682b64d153SBrian Gix 	switch (mgmt_op) {
15692b64d153SBrian Gix 	case MGMT_OP_USER_PASSKEY_REPLY:
15702b64d153SBrian Gix 		value = le32_to_cpu(passkey);
1571943a732aSJohan Hedberg 		memset(smp->tk, 0, sizeof(smp->tk));
15722b64d153SBrian Gix 		BT_DBG("PassKey: %d", value);
1573943a732aSJohan Hedberg 		put_unaligned_le32(value, smp->tk);
15742b64d153SBrian Gix 		/* Fall Through */
15752b64d153SBrian Gix 	case MGMT_OP_USER_CONFIRM_REPLY:
15764a74d658SJohan Hedberg 		set_bit(SMP_FLAG_TK_VALID, &smp->flags);
15772b64d153SBrian Gix 		break;
15782b64d153SBrian Gix 	case MGMT_OP_USER_PASSKEY_NEG_REPLY:
15792b64d153SBrian Gix 	case MGMT_OP_USER_CONFIRM_NEG_REPLY:
158084794e11SJohan Hedberg 		smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
1581fc75cc86SJohan Hedberg 		err = 0;
1582fc75cc86SJohan Hedberg 		goto unlock;
15832b64d153SBrian Gix 	default:
158484794e11SJohan Hedberg 		smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
1585fc75cc86SJohan Hedberg 		err = -EOPNOTSUPP;
1586fc75cc86SJohan Hedberg 		goto unlock;
15872b64d153SBrian Gix 	}
15882b64d153SBrian Gix 
1589fc75cc86SJohan Hedberg 	err = 0;
1590fc75cc86SJohan Hedberg 
15912b64d153SBrian Gix 	/* If it is our turn to send Pairing Confirm, do so now */
15921cc61144SJohan Hedberg 	if (test_bit(SMP_FLAG_CFM_PENDING, &smp->flags)) {
15931cc61144SJohan Hedberg 		u8 rsp = smp_confirm(smp);
15941cc61144SJohan Hedberg 		if (rsp)
15951cc61144SJohan Hedberg 			smp_failure(conn, rsp);
15961cc61144SJohan Hedberg 	}
15972b64d153SBrian Gix 
1598fc75cc86SJohan Hedberg unlock:
1599fc75cc86SJohan Hedberg 	l2cap_chan_unlock(chan);
1600fc75cc86SJohan Hedberg 	return err;
16012b64d153SBrian Gix }
16022b64d153SBrian Gix 
1603b5ae344dSJohan Hedberg static void build_bredr_pairing_cmd(struct smp_chan *smp,
1604b5ae344dSJohan Hedberg 				    struct smp_cmd_pairing *req,
1605b5ae344dSJohan Hedberg 				    struct smp_cmd_pairing *rsp)
1606b5ae344dSJohan Hedberg {
1607b5ae344dSJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
1608b5ae344dSJohan Hedberg 	struct hci_dev *hdev = conn->hcon->hdev;
1609b5ae344dSJohan Hedberg 	u8 local_dist = 0, remote_dist = 0;
1610b5ae344dSJohan Hedberg 
1611d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_BONDABLE)) {
1612b5ae344dSJohan Hedberg 		local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
1613b5ae344dSJohan Hedberg 		remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
1614b5ae344dSJohan Hedberg 	}
1615b5ae344dSJohan Hedberg 
1616d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_RPA_RESOLVING))
1617b5ae344dSJohan Hedberg 		remote_dist |= SMP_DIST_ID_KEY;
1618b5ae344dSJohan Hedberg 
1619d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_PRIVACY))
1620b5ae344dSJohan Hedberg 		local_dist |= SMP_DIST_ID_KEY;
1621b5ae344dSJohan Hedberg 
1622b5ae344dSJohan Hedberg 	if (!rsp) {
1623b5ae344dSJohan Hedberg 		memset(req, 0, sizeof(*req));
1624b5ae344dSJohan Hedberg 
1625b5ae344dSJohan Hedberg 		req->init_key_dist   = local_dist;
1626b5ae344dSJohan Hedberg 		req->resp_key_dist   = remote_dist;
1627b5ae344dSJohan Hedberg 		req->max_key_size    = SMP_MAX_ENC_KEY_SIZE;
1628b5ae344dSJohan Hedberg 
1629b5ae344dSJohan Hedberg 		smp->remote_key_dist = remote_dist;
1630b5ae344dSJohan Hedberg 
1631b5ae344dSJohan Hedberg 		return;
1632b5ae344dSJohan Hedberg 	}
1633b5ae344dSJohan Hedberg 
1634b5ae344dSJohan Hedberg 	memset(rsp, 0, sizeof(*rsp));
1635b5ae344dSJohan Hedberg 
1636b5ae344dSJohan Hedberg 	rsp->max_key_size    = SMP_MAX_ENC_KEY_SIZE;
1637b5ae344dSJohan Hedberg 	rsp->init_key_dist   = req->init_key_dist & remote_dist;
1638b5ae344dSJohan Hedberg 	rsp->resp_key_dist   = req->resp_key_dist & local_dist;
1639b5ae344dSJohan Hedberg 
1640b5ae344dSJohan Hedberg 	smp->remote_key_dist = rsp->init_key_dist;
1641b5ae344dSJohan Hedberg }
1642b5ae344dSJohan Hedberg 
1643da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
164488ba43b6SAnderson Briglia {
16453158c50cSVinicius Costa Gomes 	struct smp_cmd_pairing rsp, *req = (void *) skb->data;
1646fc75cc86SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
1647b3c6410bSJohan Hedberg 	struct hci_dev *hdev = conn->hcon->hdev;
16488aab4757SVinicius Costa Gomes 	struct smp_chan *smp;
1649c7262e71SJohan Hedberg 	u8 key_size, auth, sec_level;
16508aab4757SVinicius Costa Gomes 	int ret;
165188ba43b6SAnderson Briglia 
165288ba43b6SAnderson Briglia 	BT_DBG("conn %p", conn);
165388ba43b6SAnderson Briglia 
1654c46b98beSJohan Hedberg 	if (skb->len < sizeof(*req))
165538e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1656c46b98beSJohan Hedberg 
165740bef302SJohan Hedberg 	if (conn->hcon->role != HCI_ROLE_SLAVE)
16582b64d153SBrian Gix 		return SMP_CMD_NOTSUPP;
16592b64d153SBrian Gix 
1660fc75cc86SJohan Hedberg 	if (!chan->data)
16618aab4757SVinicius Costa Gomes 		smp = smp_chan_create(conn);
1662fc75cc86SJohan Hedberg 	else
16635d88cc73SJohan Hedberg 		smp = chan->data;
1664d26a2345SVinicius Costa Gomes 
1665d08fd0e7SAndrei Emeltchenko 	if (!smp)
1666d08fd0e7SAndrei Emeltchenko 		return SMP_UNSPECIFIED;
1667d08fd0e7SAndrei Emeltchenko 
1668c05b9339SJohan Hedberg 	/* We didn't start the pairing, so match remote */
16690edb14deSJohan Hedberg 	auth = req->auth_req & AUTH_REQ_MASK(hdev);
1670c05b9339SJohan Hedberg 
1671d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BONDABLE) &&
1672c05b9339SJohan Hedberg 	    (auth & SMP_AUTH_BONDING))
1673b3c6410bSJohan Hedberg 		return SMP_PAIRING_NOTSUPP;
1674b3c6410bSJohan Hedberg 
1675d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SC_ONLY) && !(auth & SMP_AUTH_SC))
1676903b71c7SJohan Hedberg 		return SMP_AUTH_REQUIREMENTS;
1677903b71c7SJohan Hedberg 
16781c1def09SVinicius Costa Gomes 	smp->preq[0] = SMP_CMD_PAIRING_REQ;
16791c1def09SVinicius Costa Gomes 	memcpy(&smp->preq[1], req, sizeof(*req));
16803158c50cSVinicius Costa Gomes 	skb_pull(skb, sizeof(*req));
168188ba43b6SAnderson Briglia 
1682b5ae344dSJohan Hedberg 	/* SMP over BR/EDR requires special treatment */
1683b5ae344dSJohan Hedberg 	if (conn->hcon->type == ACL_LINK) {
1684b5ae344dSJohan Hedberg 		/* We must have a BR/EDR SC link */
168508f63cc5SMarcel Holtmann 		if (!test_bit(HCI_CONN_AES_CCM, &conn->hcon->flags) &&
1686b7cb93e5SMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP))
1687b5ae344dSJohan Hedberg 			return SMP_CROSS_TRANSP_NOT_ALLOWED;
1688b5ae344dSJohan Hedberg 
1689b5ae344dSJohan Hedberg 		set_bit(SMP_FLAG_SC, &smp->flags);
1690b5ae344dSJohan Hedberg 
1691b5ae344dSJohan Hedberg 		build_bredr_pairing_cmd(smp, req, &rsp);
1692b5ae344dSJohan Hedberg 
1693b5ae344dSJohan Hedberg 		key_size = min(req->max_key_size, rsp.max_key_size);
1694b5ae344dSJohan Hedberg 		if (check_enc_key_size(conn, key_size))
1695b5ae344dSJohan Hedberg 			return SMP_ENC_KEY_SIZE;
1696b5ae344dSJohan Hedberg 
1697b5ae344dSJohan Hedberg 		/* Clear bits which are generated but not distributed */
1698b5ae344dSJohan Hedberg 		smp->remote_key_dist &= ~SMP_SC_NO_DIST;
1699b5ae344dSJohan Hedberg 
1700b5ae344dSJohan Hedberg 		smp->prsp[0] = SMP_CMD_PAIRING_RSP;
1701b5ae344dSJohan Hedberg 		memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
1702b5ae344dSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
1703b5ae344dSJohan Hedberg 
1704b5ae344dSJohan Hedberg 		smp_distribute_keys(smp);
1705b5ae344dSJohan Hedberg 		return 0;
1706b5ae344dSJohan Hedberg 	}
1707b5ae344dSJohan Hedberg 
17085e3d3d9bSJohan Hedberg 	build_pairing_cmd(conn, req, &rsp, auth);
17095e3d3d9bSJohan Hedberg 
17105e3d3d9bSJohan Hedberg 	if (rsp.auth_req & SMP_AUTH_SC)
17115e3d3d9bSJohan Hedberg 		set_bit(SMP_FLAG_SC, &smp->flags);
17125e3d3d9bSJohan Hedberg 
17135be5e275SJohan Hedberg 	if (conn->hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
17141afc2a1aSJohan Hedberg 		sec_level = BT_SECURITY_MEDIUM;
17151afc2a1aSJohan Hedberg 	else
1716c7262e71SJohan Hedberg 		sec_level = authreq_to_seclevel(auth);
17171afc2a1aSJohan Hedberg 
1718c7262e71SJohan Hedberg 	if (sec_level > conn->hcon->pending_sec_level)
1719c7262e71SJohan Hedberg 		conn->hcon->pending_sec_level = sec_level;
1720fdde0a26SIdo Yariv 
172149c922bbSStephen Hemminger 	/* If we need MITM check that it can be achieved */
17222ed8f65cSJohan Hedberg 	if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
17232ed8f65cSJohan Hedberg 		u8 method;
17242ed8f65cSJohan Hedberg 
17252ed8f65cSJohan Hedberg 		method = get_auth_method(smp, conn->hcon->io_capability,
17262ed8f65cSJohan Hedberg 					 req->io_capability);
17272ed8f65cSJohan Hedberg 		if (method == JUST_WORKS || method == JUST_CFM)
17282ed8f65cSJohan Hedberg 			return SMP_AUTH_REQUIREMENTS;
17292ed8f65cSJohan Hedberg 	}
17302ed8f65cSJohan Hedberg 
17313158c50cSVinicius Costa Gomes 	key_size = min(req->max_key_size, rsp.max_key_size);
17323158c50cSVinicius Costa Gomes 	if (check_enc_key_size(conn, key_size))
17333158c50cSVinicius Costa Gomes 		return SMP_ENC_KEY_SIZE;
173488ba43b6SAnderson Briglia 
1735e84a6b13SJohan Hedberg 	get_random_bytes(smp->prnd, sizeof(smp->prnd));
17368aab4757SVinicius Costa Gomes 
17371c1def09SVinicius Costa Gomes 	smp->prsp[0] = SMP_CMD_PAIRING_RSP;
17381c1def09SVinicius Costa Gomes 	memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
1739f01ead31SAnderson Briglia 
17403158c50cSVinicius Costa Gomes 	smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
17413b19146dSJohan Hedberg 
17423b19146dSJohan Hedberg 	clear_bit(SMP_FLAG_INITIATOR, &smp->flags);
17433b19146dSJohan Hedberg 
17443b19146dSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
17453b19146dSJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PUBLIC_KEY);
17463b19146dSJohan Hedberg 		/* Clear bits which are generated but not distributed */
17473b19146dSJohan Hedberg 		smp->remote_key_dist &= ~SMP_SC_NO_DIST;
17483b19146dSJohan Hedberg 		/* Wait for Public Key from Initiating Device */
17493b19146dSJohan Hedberg 		return 0;
17503b19146dSJohan Hedberg 	}
1751da85e5e5SVinicius Costa Gomes 
1752983f9814SMarcel Holtmann 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
1753983f9814SMarcel Holtmann 
17542b64d153SBrian Gix 	/* Request setup of TK */
17552b64d153SBrian Gix 	ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability);
17562b64d153SBrian Gix 	if (ret)
17572b64d153SBrian Gix 		return SMP_UNSPECIFIED;
17582b64d153SBrian Gix 
1759da85e5e5SVinicius Costa Gomes 	return 0;
176088ba43b6SAnderson Briglia }
176188ba43b6SAnderson Briglia 
17623b19146dSJohan Hedberg static u8 sc_send_public_key(struct smp_chan *smp)
17633b19146dSJohan Hedberg {
176470157ef5SJohan Hedberg 	struct hci_dev *hdev = smp->conn->hcon->hdev;
176570157ef5SJohan Hedberg 
17663b19146dSJohan Hedberg 	BT_DBG("");
17673b19146dSJohan Hedberg 
1768d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS)) {
176970157ef5SJohan Hedberg 		BT_DBG("Using debug keys");
177070157ef5SJohan Hedberg 		memcpy(smp->local_pk, debug_pk, 64);
177170157ef5SJohan Hedberg 		memcpy(smp->local_sk, debug_sk, 32);
177270157ef5SJohan Hedberg 		set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags);
177370157ef5SJohan Hedberg 	} else {
17746c0dcc50SJohan Hedberg 		while (true) {
17753b19146dSJohan Hedberg 			/* Generate local key pair for Secure Connections */
17763b19146dSJohan Hedberg 			if (!ecc_make_key(smp->local_pk, smp->local_sk))
17773b19146dSJohan Hedberg 				return SMP_UNSPECIFIED;
17783b19146dSJohan Hedberg 
177970157ef5SJohan Hedberg 			/* This is unlikely, but we need to check that
178070157ef5SJohan Hedberg 			 * we didn't accidentially generate a debug key.
17816c0dcc50SJohan Hedberg 			 */
17826c0dcc50SJohan Hedberg 			if (memcmp(smp->local_sk, debug_sk, 32))
17836c0dcc50SJohan Hedberg 				break;
17846c0dcc50SJohan Hedberg 		}
178570157ef5SJohan Hedberg 	}
17866c0dcc50SJohan Hedberg 
1787c7a3d57dSJohan Hedberg 	SMP_DBG("Local Public Key X: %32phN", smp->local_pk);
1788c7a3d57dSJohan Hedberg 	SMP_DBG("Local Public Key Y: %32phN", &smp->local_pk[32]);
1789c7a3d57dSJohan Hedberg 	SMP_DBG("Local Private Key:  %32phN", smp->local_sk);
17903b19146dSJohan Hedberg 
17913b19146dSJohan Hedberg 	smp_send_cmd(smp->conn, SMP_CMD_PUBLIC_KEY, 64, smp->local_pk);
17923b19146dSJohan Hedberg 
17933b19146dSJohan Hedberg 	return 0;
17943b19146dSJohan Hedberg }
17953b19146dSJohan Hedberg 
1796da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
179788ba43b6SAnderson Briglia {
17983158c50cSVinicius Costa Gomes 	struct smp_cmd_pairing *req, *rsp = (void *) skb->data;
17995d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
18005d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
18010edb14deSJohan Hedberg 	struct hci_dev *hdev = conn->hcon->hdev;
18023a7dbfb8SJohan Hedberg 	u8 key_size, auth;
18037d24ddccSAnderson Briglia 	int ret;
180488ba43b6SAnderson Briglia 
180588ba43b6SAnderson Briglia 	BT_DBG("conn %p", conn);
180688ba43b6SAnderson Briglia 
1807c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rsp))
180838e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1809c46b98beSJohan Hedberg 
181040bef302SJohan Hedberg 	if (conn->hcon->role != HCI_ROLE_MASTER)
18112b64d153SBrian Gix 		return SMP_CMD_NOTSUPP;
18122b64d153SBrian Gix 
18133158c50cSVinicius Costa Gomes 	skb_pull(skb, sizeof(*rsp));
1814da85e5e5SVinicius Costa Gomes 
18151c1def09SVinicius Costa Gomes 	req = (void *) &smp->preq[1];
18163158c50cSVinicius Costa Gomes 
18173158c50cSVinicius Costa Gomes 	key_size = min(req->max_key_size, rsp->max_key_size);
18183158c50cSVinicius Costa Gomes 	if (check_enc_key_size(conn, key_size))
18193158c50cSVinicius Costa Gomes 		return SMP_ENC_KEY_SIZE;
18203158c50cSVinicius Costa Gomes 
18210edb14deSJohan Hedberg 	auth = rsp->auth_req & AUTH_REQ_MASK(hdev);
1822c05b9339SJohan Hedberg 
1823d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SC_ONLY) && !(auth & SMP_AUTH_SC))
1824903b71c7SJohan Hedberg 		return SMP_AUTH_REQUIREMENTS;
1825903b71c7SJohan Hedberg 
1826b5ae344dSJohan Hedberg 	smp->prsp[0] = SMP_CMD_PAIRING_RSP;
1827b5ae344dSJohan Hedberg 	memcpy(&smp->prsp[1], rsp, sizeof(*rsp));
1828b5ae344dSJohan Hedberg 
1829b5ae344dSJohan Hedberg 	/* Update remote key distribution in case the remote cleared
1830b5ae344dSJohan Hedberg 	 * some bits that we had enabled in our request.
1831b5ae344dSJohan Hedberg 	 */
1832b5ae344dSJohan Hedberg 	smp->remote_key_dist &= rsp->resp_key_dist;
1833b5ae344dSJohan Hedberg 
1834b5ae344dSJohan Hedberg 	/* For BR/EDR this means we're done and can start phase 3 */
1835b5ae344dSJohan Hedberg 	if (conn->hcon->type == ACL_LINK) {
1836b5ae344dSJohan Hedberg 		/* Clear bits which are generated but not distributed */
1837b5ae344dSJohan Hedberg 		smp->remote_key_dist &= ~SMP_SC_NO_DIST;
1838b5ae344dSJohan Hedberg 		smp_distribute_keys(smp);
1839b5ae344dSJohan Hedberg 		return 0;
1840b5ae344dSJohan Hedberg 	}
1841b5ae344dSJohan Hedberg 
184265668776SJohan Hedberg 	if ((req->auth_req & SMP_AUTH_SC) && (auth & SMP_AUTH_SC))
184365668776SJohan Hedberg 		set_bit(SMP_FLAG_SC, &smp->flags);
1844d2eb9e10SJohan Hedberg 	else if (conn->hcon->pending_sec_level > BT_SECURITY_HIGH)
1845d2eb9e10SJohan Hedberg 		conn->hcon->pending_sec_level = BT_SECURITY_HIGH;
184665668776SJohan Hedberg 
184749c922bbSStephen Hemminger 	/* If we need MITM check that it can be achieved */
18482ed8f65cSJohan Hedberg 	if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
18492ed8f65cSJohan Hedberg 		u8 method;
18502ed8f65cSJohan Hedberg 
18512ed8f65cSJohan Hedberg 		method = get_auth_method(smp, req->io_capability,
18522ed8f65cSJohan Hedberg 					 rsp->io_capability);
18532ed8f65cSJohan Hedberg 		if (method == JUST_WORKS || method == JUST_CFM)
18542ed8f65cSJohan Hedberg 			return SMP_AUTH_REQUIREMENTS;
18552ed8f65cSJohan Hedberg 	}
18562ed8f65cSJohan Hedberg 
1857e84a6b13SJohan Hedberg 	get_random_bytes(smp->prnd, sizeof(smp->prnd));
18587d24ddccSAnderson Briglia 
1859fdcc4becSJohan Hedberg 	/* Update remote key distribution in case the remote cleared
1860fdcc4becSJohan Hedberg 	 * some bits that we had enabled in our request.
1861fdcc4becSJohan Hedberg 	 */
1862fdcc4becSJohan Hedberg 	smp->remote_key_dist &= rsp->resp_key_dist;
1863fdcc4becSJohan Hedberg 
18643b19146dSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
18653b19146dSJohan Hedberg 		/* Clear bits which are generated but not distributed */
18663b19146dSJohan Hedberg 		smp->remote_key_dist &= ~SMP_SC_NO_DIST;
18673b19146dSJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PUBLIC_KEY);
18683b19146dSJohan Hedberg 		return sc_send_public_key(smp);
18693b19146dSJohan Hedberg 	}
18703b19146dSJohan Hedberg 
1871c05b9339SJohan Hedberg 	auth |= req->auth_req;
18722b64d153SBrian Gix 
1873476585ecSJohan Hedberg 	ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability);
18742b64d153SBrian Gix 	if (ret)
18752b64d153SBrian Gix 		return SMP_UNSPECIFIED;
18762b64d153SBrian Gix 
18774a74d658SJohan Hedberg 	set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
18782b64d153SBrian Gix 
18792b64d153SBrian Gix 	/* Can't compose response until we have been confirmed */
18804a74d658SJohan Hedberg 	if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
18811cc61144SJohan Hedberg 		return smp_confirm(smp);
1882da85e5e5SVinicius Costa Gomes 
1883da85e5e5SVinicius Costa Gomes 	return 0;
188488ba43b6SAnderson Briglia }
188588ba43b6SAnderson Briglia 
1886dcee2b32SJohan Hedberg static u8 sc_check_confirm(struct smp_chan *smp)
1887dcee2b32SJohan Hedberg {
1888dcee2b32SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
1889dcee2b32SJohan Hedberg 
1890dcee2b32SJohan Hedberg 	BT_DBG("");
1891dcee2b32SJohan Hedberg 
1892dcee2b32SJohan Hedberg 	/* Public Key exchange must happen before any other steps */
1893dcee2b32SJohan Hedberg 	if (!test_bit(SMP_FLAG_REMOTE_PK, &smp->flags))
1894dcee2b32SJohan Hedberg 		return SMP_UNSPECIFIED;
1895dcee2b32SJohan Hedberg 
189638606f14SJohan Hedberg 	if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY)
189738606f14SJohan Hedberg 		return sc_passkey_round(smp, SMP_CMD_PAIRING_CONFIRM);
189838606f14SJohan Hedberg 
1899dcee2b32SJohan Hedberg 	if (conn->hcon->out) {
1900dcee2b32SJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
1901dcee2b32SJohan Hedberg 			     smp->prnd);
1902dcee2b32SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
1903dcee2b32SJohan Hedberg 	}
1904dcee2b32SJohan Hedberg 
1905dcee2b32SJohan Hedberg 	return 0;
1906dcee2b32SJohan Hedberg }
1907dcee2b32SJohan Hedberg 
1908da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
190988ba43b6SAnderson Briglia {
19105d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
19115d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
19127d24ddccSAnderson Briglia 
191388ba43b6SAnderson Briglia 	BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
191488ba43b6SAnderson Briglia 
1915c46b98beSJohan Hedberg 	if (skb->len < sizeof(smp->pcnf))
191638e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1917c46b98beSJohan Hedberg 
19181c1def09SVinicius Costa Gomes 	memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf));
19191c1def09SVinicius Costa Gomes 	skb_pull(skb, sizeof(smp->pcnf));
19207d24ddccSAnderson Briglia 
1921dcee2b32SJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags))
1922dcee2b32SJohan Hedberg 		return sc_check_confirm(smp);
1923dcee2b32SJohan Hedberg 
1924b28b4943SJohan Hedberg 	if (conn->hcon->out) {
1925943a732aSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
1926943a732aSJohan Hedberg 			     smp->prnd);
1927b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
1928b28b4943SJohan Hedberg 		return 0;
1929b28b4943SJohan Hedberg 	}
1930b28b4943SJohan Hedberg 
1931b28b4943SJohan Hedberg 	if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
19321cc61144SJohan Hedberg 		return smp_confirm(smp);
1933983f9814SMarcel Holtmann 
19344a74d658SJohan Hedberg 	set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
1935da85e5e5SVinicius Costa Gomes 
1936da85e5e5SVinicius Costa Gomes 	return 0;
193788ba43b6SAnderson Briglia }
193888ba43b6SAnderson Briglia 
1939da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
194088ba43b6SAnderson Briglia {
19415d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
19425d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
1943191dc7feSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
1944191dc7feSJohan Hedberg 	u8 *pkax, *pkbx, *na, *nb;
1945191dc7feSJohan Hedberg 	u32 passkey;
1946191dc7feSJohan Hedberg 	int err;
19477d24ddccSAnderson Briglia 
19488aab4757SVinicius Costa Gomes 	BT_DBG("conn %p", conn);
19497d24ddccSAnderson Briglia 
1950c46b98beSJohan Hedberg 	if (skb->len < sizeof(smp->rrnd))
195138e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1952c46b98beSJohan Hedberg 
1953943a732aSJohan Hedberg 	memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd));
19548aab4757SVinicius Costa Gomes 	skb_pull(skb, sizeof(smp->rrnd));
195588ba43b6SAnderson Briglia 
1956191dc7feSJohan Hedberg 	if (!test_bit(SMP_FLAG_SC, &smp->flags))
1957861580a9SJohan Hedberg 		return smp_random(smp);
1958191dc7feSJohan Hedberg 
1959580039e8SJohan Hedberg 	if (hcon->out) {
1960580039e8SJohan Hedberg 		pkax = smp->local_pk;
1961580039e8SJohan Hedberg 		pkbx = smp->remote_pk;
1962580039e8SJohan Hedberg 		na   = smp->prnd;
1963580039e8SJohan Hedberg 		nb   = smp->rrnd;
1964580039e8SJohan Hedberg 	} else {
1965580039e8SJohan Hedberg 		pkax = smp->remote_pk;
1966580039e8SJohan Hedberg 		pkbx = smp->local_pk;
1967580039e8SJohan Hedberg 		na   = smp->rrnd;
1968580039e8SJohan Hedberg 		nb   = smp->prnd;
1969580039e8SJohan Hedberg 	}
1970580039e8SJohan Hedberg 
1971a29b0733SJohan Hedberg 	if (smp->method == REQ_OOB) {
1972a29b0733SJohan Hedberg 		if (!hcon->out)
1973a29b0733SJohan Hedberg 			smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM,
1974a29b0733SJohan Hedberg 				     sizeof(smp->prnd), smp->prnd);
1975a29b0733SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
1976a29b0733SJohan Hedberg 		goto mackey_and_ltk;
1977a29b0733SJohan Hedberg 	}
1978a29b0733SJohan Hedberg 
197938606f14SJohan Hedberg 	/* Passkey entry has special treatment */
198038606f14SJohan Hedberg 	if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY)
198138606f14SJohan Hedberg 		return sc_passkey_round(smp, SMP_CMD_PAIRING_RANDOM);
198238606f14SJohan Hedberg 
1983191dc7feSJohan Hedberg 	if (hcon->out) {
1984191dc7feSJohan Hedberg 		u8 cfm[16];
1985191dc7feSJohan Hedberg 
1986191dc7feSJohan Hedberg 		err = smp_f4(smp->tfm_cmac, smp->remote_pk, smp->local_pk,
1987191dc7feSJohan Hedberg 			     smp->rrnd, 0, cfm);
1988191dc7feSJohan Hedberg 		if (err)
1989191dc7feSJohan Hedberg 			return SMP_UNSPECIFIED;
1990191dc7feSJohan Hedberg 
1991191dc7feSJohan Hedberg 		if (memcmp(smp->pcnf, cfm, 16))
1992191dc7feSJohan Hedberg 			return SMP_CONFIRM_FAILED;
1993191dc7feSJohan Hedberg 	} else {
1994191dc7feSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
1995191dc7feSJohan Hedberg 			     smp->prnd);
1996191dc7feSJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
1997191dc7feSJohan Hedberg 	}
1998191dc7feSJohan Hedberg 
1999a29b0733SJohan Hedberg mackey_and_ltk:
2000760b018bSJohan Hedberg 	/* Generate MacKey and LTK */
2001760b018bSJohan Hedberg 	err = sc_mackey_and_ltk(smp, smp->mackey, smp->tk);
2002760b018bSJohan Hedberg 	if (err)
2003760b018bSJohan Hedberg 		return SMP_UNSPECIFIED;
2004760b018bSJohan Hedberg 
2005a29b0733SJohan Hedberg 	if (smp->method == JUST_WORKS || smp->method == REQ_OOB) {
2006dddd3059SJohan Hedberg 		if (hcon->out) {
200738606f14SJohan Hedberg 			sc_dhkey_check(smp);
2008dddd3059SJohan Hedberg 			SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
2009dddd3059SJohan Hedberg 		}
2010dddd3059SJohan Hedberg 		return 0;
2011dddd3059SJohan Hedberg 	}
2012dddd3059SJohan Hedberg 
201338606f14SJohan Hedberg 	err = smp_g2(smp->tfm_cmac, pkax, pkbx, na, nb, &passkey);
2014191dc7feSJohan Hedberg 	if (err)
2015191dc7feSJohan Hedberg 		return SMP_UNSPECIFIED;
2016191dc7feSJohan Hedberg 
201738606f14SJohan Hedberg 	err = mgmt_user_confirm_request(hcon->hdev, &hcon->dst, hcon->type,
201838606f14SJohan Hedberg 					hcon->dst_type, passkey, 0);
201938606f14SJohan Hedberg 	if (err)
202038606f14SJohan Hedberg 		return SMP_UNSPECIFIED;
202138606f14SJohan Hedberg 
202238606f14SJohan Hedberg 	set_bit(SMP_FLAG_WAIT_USER, &smp->flags);
202338606f14SJohan Hedberg 
2024191dc7feSJohan Hedberg 	return 0;
202588ba43b6SAnderson Briglia }
202688ba43b6SAnderson Briglia 
2027f81cd823SMarcel Holtmann static bool smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
2028988c5997SVinicius Costa Gomes {
2029c9839a11SVinicius Costa Gomes 	struct smp_ltk *key;
2030988c5997SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
2031988c5997SVinicius Costa Gomes 
2032f3a73d97SJohan Hedberg 	key = hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, hcon->role);
2033988c5997SVinicius Costa Gomes 	if (!key)
2034f81cd823SMarcel Holtmann 		return false;
2035988c5997SVinicius Costa Gomes 
2036a6f7833cSJohan Hedberg 	if (smp_ltk_sec_level(key) < sec_level)
2037f81cd823SMarcel Holtmann 		return false;
20384dab7864SJohan Hedberg 
203951a8efd7SJohan Hedberg 	if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
2040f81cd823SMarcel Holtmann 		return true;
2041988c5997SVinicius Costa Gomes 
2042c9839a11SVinicius Costa Gomes 	hci_le_start_enc(hcon, key->ediv, key->rand, key->val);
2043c9839a11SVinicius Costa Gomes 	hcon->enc_key_size = key->enc_size;
2044988c5997SVinicius Costa Gomes 
2045fe59a05fSJohan Hedberg 	/* We never store STKs for master role, so clear this flag */
2046fe59a05fSJohan Hedberg 	clear_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags);
2047fe59a05fSJohan Hedberg 
2048f81cd823SMarcel Holtmann 	return true;
2049988c5997SVinicius Costa Gomes }
2050f1560463SMarcel Holtmann 
205135dc6f83SJohan Hedberg bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level,
205235dc6f83SJohan Hedberg 			     enum smp_key_pref key_pref)
2053854f4727SJohan Hedberg {
2054854f4727SJohan Hedberg 	if (sec_level == BT_SECURITY_LOW)
2055854f4727SJohan Hedberg 		return true;
2056854f4727SJohan Hedberg 
205735dc6f83SJohan Hedberg 	/* If we're encrypted with an STK but the caller prefers using
205835dc6f83SJohan Hedberg 	 * LTK claim insufficient security. This way we allow the
205935dc6f83SJohan Hedberg 	 * connection to be re-encrypted with an LTK, even if the LTK
206035dc6f83SJohan Hedberg 	 * provides the same level of security. Only exception is if we
206135dc6f83SJohan Hedberg 	 * don't have an LTK (e.g. because of key distribution bits).
20629ab65d60SJohan Hedberg 	 */
206335dc6f83SJohan Hedberg 	if (key_pref == SMP_USE_LTK &&
206435dc6f83SJohan Hedberg 	    test_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags) &&
2065f3a73d97SJohan Hedberg 	    hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, hcon->role))
20669ab65d60SJohan Hedberg 		return false;
20679ab65d60SJohan Hedberg 
2068854f4727SJohan Hedberg 	if (hcon->sec_level >= sec_level)
2069854f4727SJohan Hedberg 		return true;
2070854f4727SJohan Hedberg 
2071854f4727SJohan Hedberg 	return false;
2072854f4727SJohan Hedberg }
2073854f4727SJohan Hedberg 
2074da85e5e5SVinicius Costa Gomes static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
207588ba43b6SAnderson Briglia {
207688ba43b6SAnderson Briglia 	struct smp_cmd_security_req *rp = (void *) skb->data;
207788ba43b6SAnderson Briglia 	struct smp_cmd_pairing cp;
2078f1cb9af5SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
20790edb14deSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
20808aab4757SVinicius Costa Gomes 	struct smp_chan *smp;
2081c05b9339SJohan Hedberg 	u8 sec_level, auth;
208288ba43b6SAnderson Briglia 
208388ba43b6SAnderson Briglia 	BT_DBG("conn %p", conn);
208488ba43b6SAnderson Briglia 
2085c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rp))
208638e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2087c46b98beSJohan Hedberg 
208840bef302SJohan Hedberg 	if (hcon->role != HCI_ROLE_MASTER)
208986ca9eacSJohan Hedberg 		return SMP_CMD_NOTSUPP;
209086ca9eacSJohan Hedberg 
20910edb14deSJohan Hedberg 	auth = rp->auth_req & AUTH_REQ_MASK(hdev);
2092c05b9339SJohan Hedberg 
2093d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SC_ONLY) && !(auth & SMP_AUTH_SC))
2094903b71c7SJohan Hedberg 		return SMP_AUTH_REQUIREMENTS;
2095903b71c7SJohan Hedberg 
20965be5e275SJohan Hedberg 	if (hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
20971afc2a1aSJohan Hedberg 		sec_level = BT_SECURITY_MEDIUM;
20981afc2a1aSJohan Hedberg 	else
2099c05b9339SJohan Hedberg 		sec_level = authreq_to_seclevel(auth);
21001afc2a1aSJohan Hedberg 
210135dc6f83SJohan Hedberg 	if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK))
2102854f4727SJohan Hedberg 		return 0;
2103854f4727SJohan Hedberg 
2104c7262e71SJohan Hedberg 	if (sec_level > hcon->pending_sec_level)
2105c7262e71SJohan Hedberg 		hcon->pending_sec_level = sec_level;
2106feb45eb5SVinicius Costa Gomes 
21074dab7864SJohan Hedberg 	if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
2108988c5997SVinicius Costa Gomes 		return 0;
2109988c5997SVinicius Costa Gomes 
21108aab4757SVinicius Costa Gomes 	smp = smp_chan_create(conn);
2111c29d2444SJohan Hedberg 	if (!smp)
2112c29d2444SJohan Hedberg 		return SMP_UNSPECIFIED;
2113d26a2345SVinicius Costa Gomes 
2114d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BONDABLE) &&
2115c05b9339SJohan Hedberg 	    (auth & SMP_AUTH_BONDING))
2116616d55beSJohan Hedberg 		return SMP_PAIRING_NOTSUPP;
2117616d55beSJohan Hedberg 
211888ba43b6SAnderson Briglia 	skb_pull(skb, sizeof(*rp));
211988ba43b6SAnderson Briglia 
2120da85e5e5SVinicius Costa Gomes 	memset(&cp, 0, sizeof(cp));
2121c05b9339SJohan Hedberg 	build_pairing_cmd(conn, &cp, NULL, auth);
212288ba43b6SAnderson Briglia 
21231c1def09SVinicius Costa Gomes 	smp->preq[0] = SMP_CMD_PAIRING_REQ;
21241c1def09SVinicius Costa Gomes 	memcpy(&smp->preq[1], &cp, sizeof(cp));
2125f01ead31SAnderson Briglia 
212688ba43b6SAnderson Briglia 	smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
2127b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP);
2128f1cb9af5SVinicius Costa Gomes 
2129da85e5e5SVinicius Costa Gomes 	return 0;
213088ba43b6SAnderson Briglia }
213188ba43b6SAnderson Briglia 
2132cc110922SVinicius Costa Gomes int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
2133eb492e01SAnderson Briglia {
2134cc110922SVinicius Costa Gomes 	struct l2cap_conn *conn = hcon->l2cap_data;
2135c68b7f12SJohan Hedberg 	struct l2cap_chan *chan;
21360a66cf20SJohan Hedberg 	struct smp_chan *smp;
21372b64d153SBrian Gix 	__u8 authreq;
2138fc75cc86SJohan Hedberg 	int ret;
2139eb492e01SAnderson Briglia 
21403a0259bbSVinicius Costa Gomes 	BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
21413a0259bbSVinicius Costa Gomes 
21420a66cf20SJohan Hedberg 	/* This may be NULL if there's an unexpected disconnection */
21430a66cf20SJohan Hedberg 	if (!conn)
21440a66cf20SJohan Hedberg 		return 1;
21450a66cf20SJohan Hedberg 
2146c68b7f12SJohan Hedberg 	chan = conn->smp;
2147c68b7f12SJohan Hedberg 
2148d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hcon->hdev, HCI_LE_ENABLED))
21492e65c9d2SAndre Guedes 		return 1;
21502e65c9d2SAndre Guedes 
215135dc6f83SJohan Hedberg 	if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK))
2152f1cb9af5SVinicius Costa Gomes 		return 1;
2153f1cb9af5SVinicius Costa Gomes 
2154c7262e71SJohan Hedberg 	if (sec_level > hcon->pending_sec_level)
2155c7262e71SJohan Hedberg 		hcon->pending_sec_level = sec_level;
2156c7262e71SJohan Hedberg 
215740bef302SJohan Hedberg 	if (hcon->role == HCI_ROLE_MASTER)
2158c7262e71SJohan Hedberg 		if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
2159c7262e71SJohan Hedberg 			return 0;
2160d26a2345SVinicius Costa Gomes 
2161fc75cc86SJohan Hedberg 	l2cap_chan_lock(chan);
2162fc75cc86SJohan Hedberg 
2163fc75cc86SJohan Hedberg 	/* If SMP is already in progress ignore this request */
2164fc75cc86SJohan Hedberg 	if (chan->data) {
2165fc75cc86SJohan Hedberg 		ret = 0;
2166fc75cc86SJohan Hedberg 		goto unlock;
2167fc75cc86SJohan Hedberg 	}
2168d26a2345SVinicius Costa Gomes 
21698aab4757SVinicius Costa Gomes 	smp = smp_chan_create(conn);
2170fc75cc86SJohan Hedberg 	if (!smp) {
2171fc75cc86SJohan Hedberg 		ret = 1;
2172fc75cc86SJohan Hedberg 		goto unlock;
2173fc75cc86SJohan Hedberg 	}
21742b64d153SBrian Gix 
21752b64d153SBrian Gix 	authreq = seclevel_to_authreq(sec_level);
2176d26a2345SVinicius Costa Gomes 
2177d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hcon->hdev, HCI_SC_ENABLED))
2178d2eb9e10SJohan Hedberg 		authreq |= SMP_AUTH_SC;
2179d2eb9e10SJohan Hedberg 
218079897d20SJohan Hedberg 	/* Require MITM if IO Capability allows or the security level
218179897d20SJohan Hedberg 	 * requires it.
21822e233644SJohan Hedberg 	 */
218379897d20SJohan Hedberg 	if (hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT ||
2184c7262e71SJohan Hedberg 	    hcon->pending_sec_level > BT_SECURITY_MEDIUM)
21852e233644SJohan Hedberg 		authreq |= SMP_AUTH_MITM;
21862e233644SJohan Hedberg 
218740bef302SJohan Hedberg 	if (hcon->role == HCI_ROLE_MASTER) {
2188d26a2345SVinicius Costa Gomes 		struct smp_cmd_pairing cp;
2189f01ead31SAnderson Briglia 
21902b64d153SBrian Gix 		build_pairing_cmd(conn, &cp, NULL, authreq);
21911c1def09SVinicius Costa Gomes 		smp->preq[0] = SMP_CMD_PAIRING_REQ;
21921c1def09SVinicius Costa Gomes 		memcpy(&smp->preq[1], &cp, sizeof(cp));
2193f01ead31SAnderson Briglia 
2194eb492e01SAnderson Briglia 		smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
2195b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP);
2196eb492e01SAnderson Briglia 	} else {
2197eb492e01SAnderson Briglia 		struct smp_cmd_security_req cp;
21982b64d153SBrian Gix 		cp.auth_req = authreq;
2199eb492e01SAnderson Briglia 		smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
2200b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_REQ);
2201eb492e01SAnderson Briglia 	}
2202eb492e01SAnderson Briglia 
22034a74d658SJohan Hedberg 	set_bit(SMP_FLAG_INITIATOR, &smp->flags);
2204fc75cc86SJohan Hedberg 	ret = 0;
2205edca792cSJohan Hedberg 
2206fc75cc86SJohan Hedberg unlock:
2207fc75cc86SJohan Hedberg 	l2cap_chan_unlock(chan);
2208fc75cc86SJohan Hedberg 	return ret;
2209eb492e01SAnderson Briglia }
2210eb492e01SAnderson Briglia 
22117034b911SVinicius Costa Gomes static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
22127034b911SVinicius Costa Gomes {
221316b90839SVinicius Costa Gomes 	struct smp_cmd_encrypt_info *rp = (void *) skb->data;
22145d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
22155d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
221616b90839SVinicius Costa Gomes 
2217c46b98beSJohan Hedberg 	BT_DBG("conn %p", conn);
2218c46b98beSJohan Hedberg 
2219c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rp))
222038e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2221c46b98beSJohan Hedberg 
2222b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_MASTER_IDENT);
22236131ddc8SJohan Hedberg 
222416b90839SVinicius Costa Gomes 	skb_pull(skb, sizeof(*rp));
222516b90839SVinicius Costa Gomes 
22261c1def09SVinicius Costa Gomes 	memcpy(smp->tk, rp->ltk, sizeof(smp->tk));
222716b90839SVinicius Costa Gomes 
22287034b911SVinicius Costa Gomes 	return 0;
22297034b911SVinicius Costa Gomes }
22307034b911SVinicius Costa Gomes 
22317034b911SVinicius Costa Gomes static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
22327034b911SVinicius Costa Gomes {
223316b90839SVinicius Costa Gomes 	struct smp_cmd_master_ident *rp = (void *) skb->data;
22345d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
22355d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
2236c9839a11SVinicius Costa Gomes 	struct hci_dev *hdev = conn->hcon->hdev;
2237c9839a11SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
223823d0e128SJohan Hedberg 	struct smp_ltk *ltk;
2239c9839a11SVinicius Costa Gomes 	u8 authenticated;
22407034b911SVinicius Costa Gomes 
2241c46b98beSJohan Hedberg 	BT_DBG("conn %p", conn);
2242c46b98beSJohan Hedberg 
2243c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rp))
224438e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2245c46b98beSJohan Hedberg 
22469747a9f3SJohan Hedberg 	/* Mark the information as received */
22479747a9f3SJohan Hedberg 	smp->remote_key_dist &= ~SMP_DIST_ENC_KEY;
22489747a9f3SJohan Hedberg 
2249b28b4943SJohan Hedberg 	if (smp->remote_key_dist & SMP_DIST_ID_KEY)
2250b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO);
2251196332f5SJohan Hedberg 	else if (smp->remote_key_dist & SMP_DIST_SIGN)
2252196332f5SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO);
2253b28b4943SJohan Hedberg 
225416b90839SVinicius Costa Gomes 	skb_pull(skb, sizeof(*rp));
225516b90839SVinicius Costa Gomes 
2256ce39fb4eSMarcel Holtmann 	authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
22572ceba539SJohan Hedberg 	ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, SMP_LTK,
2258ce39fb4eSMarcel Holtmann 			  authenticated, smp->tk, smp->enc_key_size,
225904124681SGustavo F. Padovan 			  rp->ediv, rp->rand);
226023d0e128SJohan Hedberg 	smp->ltk = ltk;
2261c6e81e9aSJohan Hedberg 	if (!(smp->remote_key_dist & KEY_DIST_MASK))
2262d6268e86SJohan Hedberg 		smp_distribute_keys(smp);
22637034b911SVinicius Costa Gomes 
22647034b911SVinicius Costa Gomes 	return 0;
22657034b911SVinicius Costa Gomes }
22667034b911SVinicius Costa Gomes 
2267fd349c02SJohan Hedberg static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
2268fd349c02SJohan Hedberg {
2269fd349c02SJohan Hedberg 	struct smp_cmd_ident_info *info = (void *) skb->data;
22705d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
22715d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
2272fd349c02SJohan Hedberg 
2273fd349c02SJohan Hedberg 	BT_DBG("");
2274fd349c02SJohan Hedberg 
2275fd349c02SJohan Hedberg 	if (skb->len < sizeof(*info))
227638e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2277fd349c02SJohan Hedberg 
2278b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_ADDR_INFO);
22796131ddc8SJohan Hedberg 
2280fd349c02SJohan Hedberg 	skb_pull(skb, sizeof(*info));
2281fd349c02SJohan Hedberg 
2282fd349c02SJohan Hedberg 	memcpy(smp->irk, info->irk, 16);
2283fd349c02SJohan Hedberg 
2284fd349c02SJohan Hedberg 	return 0;
2285fd349c02SJohan Hedberg }
2286fd349c02SJohan Hedberg 
2287fd349c02SJohan Hedberg static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
2288fd349c02SJohan Hedberg 				   struct sk_buff *skb)
2289fd349c02SJohan Hedberg {
2290fd349c02SJohan Hedberg 	struct smp_cmd_ident_addr_info *info = (void *) skb->data;
22915d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
22925d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
2293fd349c02SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
2294fd349c02SJohan Hedberg 	bdaddr_t rpa;
2295fd349c02SJohan Hedberg 
2296fd349c02SJohan Hedberg 	BT_DBG("");
2297fd349c02SJohan Hedberg 
2298fd349c02SJohan Hedberg 	if (skb->len < sizeof(*info))
229938e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2300fd349c02SJohan Hedberg 
23019747a9f3SJohan Hedberg 	/* Mark the information as received */
23029747a9f3SJohan Hedberg 	smp->remote_key_dist &= ~SMP_DIST_ID_KEY;
23039747a9f3SJohan Hedberg 
2304b28b4943SJohan Hedberg 	if (smp->remote_key_dist & SMP_DIST_SIGN)
2305b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO);
2306b28b4943SJohan Hedberg 
2307fd349c02SJohan Hedberg 	skb_pull(skb, sizeof(*info));
2308fd349c02SJohan Hedberg 
2309a9a58f86SJohan Hedberg 	/* Strictly speaking the Core Specification (4.1) allows sending
2310a9a58f86SJohan Hedberg 	 * an empty address which would force us to rely on just the IRK
2311a9a58f86SJohan Hedberg 	 * as "identity information". However, since such
2312a9a58f86SJohan Hedberg 	 * implementations are not known of and in order to not over
2313a9a58f86SJohan Hedberg 	 * complicate our implementation, simply pretend that we never
2314a9a58f86SJohan Hedberg 	 * received an IRK for such a device.
2315e12af489SJohan Hedberg 	 *
2316e12af489SJohan Hedberg 	 * The Identity Address must also be a Static Random or Public
2317e12af489SJohan Hedberg 	 * Address, which hci_is_identity_address() checks for.
2318a9a58f86SJohan Hedberg 	 */
2319e12af489SJohan Hedberg 	if (!bacmp(&info->bdaddr, BDADDR_ANY) ||
2320e12af489SJohan Hedberg 	    !hci_is_identity_address(&info->bdaddr, info->addr_type)) {
2321a9a58f86SJohan Hedberg 		BT_ERR("Ignoring IRK with no identity address");
232231dd624eSJohan Hedberg 		goto distribute;
2323a9a58f86SJohan Hedberg 	}
2324a9a58f86SJohan Hedberg 
2325fd349c02SJohan Hedberg 	bacpy(&smp->id_addr, &info->bdaddr);
2326fd349c02SJohan Hedberg 	smp->id_addr_type = info->addr_type;
2327fd349c02SJohan Hedberg 
2328fd349c02SJohan Hedberg 	if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type))
2329fd349c02SJohan Hedberg 		bacpy(&rpa, &hcon->dst);
2330fd349c02SJohan Hedberg 	else
2331fd349c02SJohan Hedberg 		bacpy(&rpa, BDADDR_ANY);
2332fd349c02SJohan Hedberg 
233323d0e128SJohan Hedberg 	smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
233423d0e128SJohan Hedberg 				      smp->id_addr_type, smp->irk, &rpa);
2335fd349c02SJohan Hedberg 
233631dd624eSJohan Hedberg distribute:
2337c6e81e9aSJohan Hedberg 	if (!(smp->remote_key_dist & KEY_DIST_MASK))
2338d6268e86SJohan Hedberg 		smp_distribute_keys(smp);
2339fd349c02SJohan Hedberg 
2340fd349c02SJohan Hedberg 	return 0;
2341fd349c02SJohan Hedberg }
2342fd349c02SJohan Hedberg 
23437ee4ea36SMarcel Holtmann static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)
23447ee4ea36SMarcel Holtmann {
23457ee4ea36SMarcel Holtmann 	struct smp_cmd_sign_info *rp = (void *) skb->data;
23465d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
23475d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
23487ee4ea36SMarcel Holtmann 	struct smp_csrk *csrk;
23497ee4ea36SMarcel Holtmann 
23507ee4ea36SMarcel Holtmann 	BT_DBG("conn %p", conn);
23517ee4ea36SMarcel Holtmann 
23527ee4ea36SMarcel Holtmann 	if (skb->len < sizeof(*rp))
235338e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
23547ee4ea36SMarcel Holtmann 
23557ee4ea36SMarcel Holtmann 	/* Mark the information as received */
23567ee4ea36SMarcel Holtmann 	smp->remote_key_dist &= ~SMP_DIST_SIGN;
23577ee4ea36SMarcel Holtmann 
23587ee4ea36SMarcel Holtmann 	skb_pull(skb, sizeof(*rp));
23597ee4ea36SMarcel Holtmann 
23607ee4ea36SMarcel Holtmann 	csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
23617ee4ea36SMarcel Holtmann 	if (csrk) {
23624cd3928aSJohan Hedberg 		if (conn->hcon->sec_level > BT_SECURITY_MEDIUM)
23634cd3928aSJohan Hedberg 			csrk->type = MGMT_CSRK_REMOTE_AUTHENTICATED;
23644cd3928aSJohan Hedberg 		else
23654cd3928aSJohan Hedberg 			csrk->type = MGMT_CSRK_REMOTE_UNAUTHENTICATED;
23667ee4ea36SMarcel Holtmann 		memcpy(csrk->val, rp->csrk, sizeof(csrk->val));
23677ee4ea36SMarcel Holtmann 	}
23687ee4ea36SMarcel Holtmann 	smp->csrk = csrk;
2369d6268e86SJohan Hedberg 	smp_distribute_keys(smp);
23707ee4ea36SMarcel Holtmann 
23717ee4ea36SMarcel Holtmann 	return 0;
23727ee4ea36SMarcel Holtmann }
23737ee4ea36SMarcel Holtmann 
23745e3d3d9bSJohan Hedberg static u8 sc_select_method(struct smp_chan *smp)
23755e3d3d9bSJohan Hedberg {
23765e3d3d9bSJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
23775e3d3d9bSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
23785e3d3d9bSJohan Hedberg 	struct smp_cmd_pairing *local, *remote;
23795e3d3d9bSJohan Hedberg 	u8 local_mitm, remote_mitm, local_io, remote_io, method;
23805e3d3d9bSJohan Hedberg 
2381a29b0733SJohan Hedberg 	if (test_bit(SMP_FLAG_OOB, &smp->flags))
2382a29b0733SJohan Hedberg 		return REQ_OOB;
2383a29b0733SJohan Hedberg 
23845e3d3d9bSJohan Hedberg 	/* The preq/prsp contain the raw Pairing Request/Response PDUs
23855e3d3d9bSJohan Hedberg 	 * which are needed as inputs to some crypto functions. To get
23865e3d3d9bSJohan Hedberg 	 * the "struct smp_cmd_pairing" from them we need to skip the
23875e3d3d9bSJohan Hedberg 	 * first byte which contains the opcode.
23885e3d3d9bSJohan Hedberg 	 */
23895e3d3d9bSJohan Hedberg 	if (hcon->out) {
23905e3d3d9bSJohan Hedberg 		local = (void *) &smp->preq[1];
23915e3d3d9bSJohan Hedberg 		remote = (void *) &smp->prsp[1];
23925e3d3d9bSJohan Hedberg 	} else {
23935e3d3d9bSJohan Hedberg 		local = (void *) &smp->prsp[1];
23945e3d3d9bSJohan Hedberg 		remote = (void *) &smp->preq[1];
23955e3d3d9bSJohan Hedberg 	}
23965e3d3d9bSJohan Hedberg 
23975e3d3d9bSJohan Hedberg 	local_io = local->io_capability;
23985e3d3d9bSJohan Hedberg 	remote_io = remote->io_capability;
23995e3d3d9bSJohan Hedberg 
24005e3d3d9bSJohan Hedberg 	local_mitm = (local->auth_req & SMP_AUTH_MITM);
24015e3d3d9bSJohan Hedberg 	remote_mitm = (remote->auth_req & SMP_AUTH_MITM);
24025e3d3d9bSJohan Hedberg 
24035e3d3d9bSJohan Hedberg 	/* If either side wants MITM, look up the method from the table,
24045e3d3d9bSJohan Hedberg 	 * otherwise use JUST WORKS.
24055e3d3d9bSJohan Hedberg 	 */
24065e3d3d9bSJohan Hedberg 	if (local_mitm || remote_mitm)
24075e3d3d9bSJohan Hedberg 		method = get_auth_method(smp, local_io, remote_io);
24085e3d3d9bSJohan Hedberg 	else
24095e3d3d9bSJohan Hedberg 		method = JUST_WORKS;
24105e3d3d9bSJohan Hedberg 
24115e3d3d9bSJohan Hedberg 	/* Don't confirm locally initiated pairing attempts */
24125e3d3d9bSJohan Hedberg 	if (method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR, &smp->flags))
24135e3d3d9bSJohan Hedberg 		method = JUST_WORKS;
24145e3d3d9bSJohan Hedberg 
24155e3d3d9bSJohan Hedberg 	return method;
24165e3d3d9bSJohan Hedberg }
24175e3d3d9bSJohan Hedberg 
2418d8f8edbeSJohan Hedberg static int smp_cmd_public_key(struct l2cap_conn *conn, struct sk_buff *skb)
2419d8f8edbeSJohan Hedberg {
2420d8f8edbeSJohan Hedberg 	struct smp_cmd_public_key *key = (void *) skb->data;
2421d8f8edbeSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
2422d8f8edbeSJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
2423d8f8edbeSJohan Hedberg 	struct smp_chan *smp = chan->data;
24245e3d3d9bSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
2425cbbbe3e2SJohan Hedberg 	struct smp_cmd_pairing_confirm cfm;
2426d8f8edbeSJohan Hedberg 	int err;
2427d8f8edbeSJohan Hedberg 
2428d8f8edbeSJohan Hedberg 	BT_DBG("conn %p", conn);
2429d8f8edbeSJohan Hedberg 
2430d8f8edbeSJohan Hedberg 	if (skb->len < sizeof(*key))
2431d8f8edbeSJohan Hedberg 		return SMP_INVALID_PARAMS;
2432d8f8edbeSJohan Hedberg 
2433d8f8edbeSJohan Hedberg 	memcpy(smp->remote_pk, key, 64);
2434d8f8edbeSJohan Hedberg 
2435d8f8edbeSJohan Hedberg 	/* Non-initiating device sends its public key after receiving
2436d8f8edbeSJohan Hedberg 	 * the key from the initiating device.
2437d8f8edbeSJohan Hedberg 	 */
2438d8f8edbeSJohan Hedberg 	if (!hcon->out) {
2439d8f8edbeSJohan Hedberg 		err = sc_send_public_key(smp);
2440d8f8edbeSJohan Hedberg 		if (err)
2441d8f8edbeSJohan Hedberg 			return err;
2442d8f8edbeSJohan Hedberg 	}
2443d8f8edbeSJohan Hedberg 
2444c7a3d57dSJohan Hedberg 	SMP_DBG("Remote Public Key X: %32phN", smp->remote_pk);
2445c7a3d57dSJohan Hedberg 	SMP_DBG("Remote Public Key Y: %32phN", &smp->remote_pk[32]);
2446d8f8edbeSJohan Hedberg 
2447d8f8edbeSJohan Hedberg 	if (!ecdh_shared_secret(smp->remote_pk, smp->local_sk, smp->dhkey))
2448d8f8edbeSJohan Hedberg 		return SMP_UNSPECIFIED;
2449d8f8edbeSJohan Hedberg 
2450c7a3d57dSJohan Hedberg 	SMP_DBG("DHKey %32phN", smp->dhkey);
2451d8f8edbeSJohan Hedberg 
2452d8f8edbeSJohan Hedberg 	set_bit(SMP_FLAG_REMOTE_PK, &smp->flags);
2453d8f8edbeSJohan Hedberg 
24545e3d3d9bSJohan Hedberg 	smp->method = sc_select_method(smp);
24555e3d3d9bSJohan Hedberg 
24565e3d3d9bSJohan Hedberg 	BT_DBG("%s selected method 0x%02x", hdev->name, smp->method);
24575e3d3d9bSJohan Hedberg 
24585e3d3d9bSJohan Hedberg 	/* JUST_WORKS and JUST_CFM result in an unauthenticated key */
24595e3d3d9bSJohan Hedberg 	if (smp->method == JUST_WORKS || smp->method == JUST_CFM)
24605e3d3d9bSJohan Hedberg 		hcon->pending_sec_level = BT_SECURITY_MEDIUM;
24615e3d3d9bSJohan Hedberg 	else
24625e3d3d9bSJohan Hedberg 		hcon->pending_sec_level = BT_SECURITY_FIPS;
24635e3d3d9bSJohan Hedberg 
2464aeb7d461SJohan Hedberg 	if (!memcmp(debug_pk, smp->remote_pk, 64))
2465aeb7d461SJohan Hedberg 		set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags);
2466aeb7d461SJohan Hedberg 
246738606f14SJohan Hedberg 	if (smp->method == DSP_PASSKEY) {
246838606f14SJohan Hedberg 		get_random_bytes(&hcon->passkey_notify,
246938606f14SJohan Hedberg 				 sizeof(hcon->passkey_notify));
247038606f14SJohan Hedberg 		hcon->passkey_notify %= 1000000;
247138606f14SJohan Hedberg 		hcon->passkey_entered = 0;
247238606f14SJohan Hedberg 		smp->passkey_round = 0;
247338606f14SJohan Hedberg 		if (mgmt_user_passkey_notify(hdev, &hcon->dst, hcon->type,
247438606f14SJohan Hedberg 					     hcon->dst_type,
247538606f14SJohan Hedberg 					     hcon->passkey_notify,
247638606f14SJohan Hedberg 					     hcon->passkey_entered))
247738606f14SJohan Hedberg 			return SMP_UNSPECIFIED;
247838606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
247938606f14SJohan Hedberg 		return sc_passkey_round(smp, SMP_CMD_PUBLIC_KEY);
248038606f14SJohan Hedberg 	}
248138606f14SJohan Hedberg 
2482a29b0733SJohan Hedberg 	if (smp->method == REQ_OOB) {
2483a29b0733SJohan Hedberg 		err = smp_f4(smp->tfm_cmac, smp->remote_pk, smp->remote_pk,
2484a29b0733SJohan Hedberg 			     smp->rr, 0, cfm.confirm_val);
2485a29b0733SJohan Hedberg 		if (err)
2486a29b0733SJohan Hedberg 			return SMP_UNSPECIFIED;
2487a29b0733SJohan Hedberg 
2488a29b0733SJohan Hedberg 		if (memcmp(cfm.confirm_val, smp->pcnf, 16))
2489a29b0733SJohan Hedberg 			return SMP_CONFIRM_FAILED;
2490a29b0733SJohan Hedberg 
2491a29b0733SJohan Hedberg 		if (hcon->out)
2492a29b0733SJohan Hedberg 			smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM,
2493a29b0733SJohan Hedberg 				     sizeof(smp->prnd), smp->prnd);
2494a29b0733SJohan Hedberg 
2495a29b0733SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
2496a29b0733SJohan Hedberg 
2497a29b0733SJohan Hedberg 		return 0;
2498a29b0733SJohan Hedberg 	}
2499a29b0733SJohan Hedberg 
250038606f14SJohan Hedberg 	if (hcon->out)
250138606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
250238606f14SJohan Hedberg 
250338606f14SJohan Hedberg 	if (smp->method == REQ_PASSKEY) {
250438606f14SJohan Hedberg 		if (mgmt_user_passkey_request(hdev, &hcon->dst, hcon->type,
250538606f14SJohan Hedberg 					      hcon->dst_type))
250638606f14SJohan Hedberg 			return SMP_UNSPECIFIED;
250738606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
250838606f14SJohan Hedberg 		set_bit(SMP_FLAG_WAIT_USER, &smp->flags);
250938606f14SJohan Hedberg 		return 0;
251038606f14SJohan Hedberg 	}
251138606f14SJohan Hedberg 
2512cbbbe3e2SJohan Hedberg 	/* The Initiating device waits for the non-initiating device to
2513cbbbe3e2SJohan Hedberg 	 * send the confirm value.
2514cbbbe3e2SJohan Hedberg 	 */
2515cbbbe3e2SJohan Hedberg 	if (conn->hcon->out)
2516cbbbe3e2SJohan Hedberg 		return 0;
2517cbbbe3e2SJohan Hedberg 
2518cbbbe3e2SJohan Hedberg 	err = smp_f4(smp->tfm_cmac, smp->local_pk, smp->remote_pk, smp->prnd,
2519cbbbe3e2SJohan Hedberg 		     0, cfm.confirm_val);
2520cbbbe3e2SJohan Hedberg 	if (err)
2521cbbbe3e2SJohan Hedberg 		return SMP_UNSPECIFIED;
2522cbbbe3e2SJohan Hedberg 
2523cbbbe3e2SJohan Hedberg 	smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cfm), &cfm);
2524cbbbe3e2SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
2525cbbbe3e2SJohan Hedberg 
2526d8f8edbeSJohan Hedberg 	return 0;
2527d8f8edbeSJohan Hedberg }
2528d8f8edbeSJohan Hedberg 
25296433a9a2SJohan Hedberg static int smp_cmd_dhkey_check(struct l2cap_conn *conn, struct sk_buff *skb)
25306433a9a2SJohan Hedberg {
25316433a9a2SJohan Hedberg 	struct smp_cmd_dhkey_check *check = (void *) skb->data;
25326433a9a2SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
25336433a9a2SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
25346433a9a2SJohan Hedberg 	struct smp_chan *smp = chan->data;
25356433a9a2SJohan Hedberg 	u8 a[7], b[7], *local_addr, *remote_addr;
25366433a9a2SJohan Hedberg 	u8 io_cap[3], r[16], e[16];
25376433a9a2SJohan Hedberg 	int err;
25386433a9a2SJohan Hedberg 
25396433a9a2SJohan Hedberg 	BT_DBG("conn %p", conn);
25406433a9a2SJohan Hedberg 
25416433a9a2SJohan Hedberg 	if (skb->len < sizeof(*check))
25426433a9a2SJohan Hedberg 		return SMP_INVALID_PARAMS;
25436433a9a2SJohan Hedberg 
25446433a9a2SJohan Hedberg 	memcpy(a, &hcon->init_addr, 6);
25456433a9a2SJohan Hedberg 	memcpy(b, &hcon->resp_addr, 6);
25466433a9a2SJohan Hedberg 	a[6] = hcon->init_addr_type;
25476433a9a2SJohan Hedberg 	b[6] = hcon->resp_addr_type;
25486433a9a2SJohan Hedberg 
25496433a9a2SJohan Hedberg 	if (hcon->out) {
25506433a9a2SJohan Hedberg 		local_addr = a;
25516433a9a2SJohan Hedberg 		remote_addr = b;
25526433a9a2SJohan Hedberg 		memcpy(io_cap, &smp->prsp[1], 3);
25536433a9a2SJohan Hedberg 	} else {
25546433a9a2SJohan Hedberg 		local_addr = b;
25556433a9a2SJohan Hedberg 		remote_addr = a;
25566433a9a2SJohan Hedberg 		memcpy(io_cap, &smp->preq[1], 3);
25576433a9a2SJohan Hedberg 	}
25586433a9a2SJohan Hedberg 
25596433a9a2SJohan Hedberg 	memset(r, 0, sizeof(r));
25606433a9a2SJohan Hedberg 
256138606f14SJohan Hedberg 	if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY)
256238606f14SJohan Hedberg 		put_unaligned_le32(hcon->passkey_notify, r);
256338606f14SJohan Hedberg 
25646433a9a2SJohan Hedberg 	err = smp_f6(smp->tfm_cmac, smp->mackey, smp->rrnd, smp->prnd, r,
25656433a9a2SJohan Hedberg 		     io_cap, remote_addr, local_addr, e);
25666433a9a2SJohan Hedberg 	if (err)
25676433a9a2SJohan Hedberg 		return SMP_UNSPECIFIED;
25686433a9a2SJohan Hedberg 
25696433a9a2SJohan Hedberg 	if (memcmp(check->e, e, 16))
25706433a9a2SJohan Hedberg 		return SMP_DHKEY_CHECK_FAILED;
25716433a9a2SJohan Hedberg 
2572d3e54a87SJohan Hedberg 	if (!hcon->out) {
2573d3e54a87SJohan Hedberg 		if (test_bit(SMP_FLAG_WAIT_USER, &smp->flags)) {
2574d3e54a87SJohan Hedberg 			set_bit(SMP_FLAG_DHKEY_PENDING, &smp->flags);
2575d3e54a87SJohan Hedberg 			return 0;
2576d3e54a87SJohan Hedberg 		}
2577d378a2d7SJohan Hedberg 
2578d3e54a87SJohan Hedberg 		/* Slave sends DHKey check as response to master */
2579d3e54a87SJohan Hedberg 		sc_dhkey_check(smp);
2580d3e54a87SJohan Hedberg 	}
2581d378a2d7SJohan Hedberg 
2582d3e54a87SJohan Hedberg 	sc_add_ltk(smp);
25836433a9a2SJohan Hedberg 
25846433a9a2SJohan Hedberg 	if (hcon->out) {
25856433a9a2SJohan Hedberg 		hci_le_start_enc(hcon, 0, 0, smp->tk);
25866433a9a2SJohan Hedberg 		hcon->enc_key_size = smp->enc_key_size;
25876433a9a2SJohan Hedberg 	}
25886433a9a2SJohan Hedberg 
25896433a9a2SJohan Hedberg 	return 0;
25906433a9a2SJohan Hedberg }
25916433a9a2SJohan Hedberg 
25921408bb6eSJohan Hedberg static int smp_cmd_keypress_notify(struct l2cap_conn *conn,
25931408bb6eSJohan Hedberg 				   struct sk_buff *skb)
25941408bb6eSJohan Hedberg {
25951408bb6eSJohan Hedberg 	struct smp_cmd_keypress_notify *kp = (void *) skb->data;
25961408bb6eSJohan Hedberg 
25971408bb6eSJohan Hedberg 	BT_DBG("value 0x%02x", kp->value);
25981408bb6eSJohan Hedberg 
25991408bb6eSJohan Hedberg 	return 0;
26001408bb6eSJohan Hedberg }
26011408bb6eSJohan Hedberg 
26024befb867SJohan Hedberg static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb)
2603eb492e01SAnderson Briglia {
26045d88cc73SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
26057b9899dbSMarcel Holtmann 	struct hci_conn *hcon = conn->hcon;
2606b28b4943SJohan Hedberg 	struct smp_chan *smp;
260792381f5cSMarcel Holtmann 	__u8 code, reason;
2608eb492e01SAnderson Briglia 	int err = 0;
2609eb492e01SAnderson Briglia 
26108ae9b984SJohan Hedberg 	if (skb->len < 1)
261192381f5cSMarcel Holtmann 		return -EILSEQ;
261292381f5cSMarcel Holtmann 
2613d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hcon->hdev, HCI_LE_ENABLED)) {
26142e65c9d2SAndre Guedes 		reason = SMP_PAIRING_NOTSUPP;
26152e65c9d2SAndre Guedes 		goto done;
26162e65c9d2SAndre Guedes 	}
26172e65c9d2SAndre Guedes 
261892381f5cSMarcel Holtmann 	code = skb->data[0];
2619eb492e01SAnderson Briglia 	skb_pull(skb, sizeof(code));
2620eb492e01SAnderson Briglia 
2621b28b4943SJohan Hedberg 	smp = chan->data;
2622b28b4943SJohan Hedberg 
2623b28b4943SJohan Hedberg 	if (code > SMP_CMD_MAX)
2624b28b4943SJohan Hedberg 		goto drop;
2625b28b4943SJohan Hedberg 
262624bd0bd9SJohan Hedberg 	if (smp && !test_and_clear_bit(code, &smp->allow_cmd))
2627b28b4943SJohan Hedberg 		goto drop;
2628b28b4943SJohan Hedberg 
2629b28b4943SJohan Hedberg 	/* If we don't have a context the only allowed commands are
2630b28b4943SJohan Hedberg 	 * pairing request and security request.
26318cf9fa12SJohan Hedberg 	 */
2632b28b4943SJohan Hedberg 	if (!smp && code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ)
2633b28b4943SJohan Hedberg 		goto drop;
26348cf9fa12SJohan Hedberg 
2635eb492e01SAnderson Briglia 	switch (code) {
2636eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_REQ:
2637da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_req(conn, skb);
2638eb492e01SAnderson Briglia 		break;
2639eb492e01SAnderson Briglia 
2640eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_FAIL:
264184794e11SJohan Hedberg 		smp_failure(conn, 0);
2642da85e5e5SVinicius Costa Gomes 		err = -EPERM;
2643eb492e01SAnderson Briglia 		break;
2644eb492e01SAnderson Briglia 
2645eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_RSP:
2646da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_rsp(conn, skb);
264788ba43b6SAnderson Briglia 		break;
264888ba43b6SAnderson Briglia 
264988ba43b6SAnderson Briglia 	case SMP_CMD_SECURITY_REQ:
2650da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_security_req(conn, skb);
265188ba43b6SAnderson Briglia 		break;
265288ba43b6SAnderson Briglia 
2653eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_CONFIRM:
2654da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_confirm(conn, skb);
265588ba43b6SAnderson Briglia 		break;
265688ba43b6SAnderson Briglia 
2657eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_RANDOM:
2658da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_random(conn, skb);
265988ba43b6SAnderson Briglia 		break;
266088ba43b6SAnderson Briglia 
2661eb492e01SAnderson Briglia 	case SMP_CMD_ENCRYPT_INFO:
26627034b911SVinicius Costa Gomes 		reason = smp_cmd_encrypt_info(conn, skb);
26637034b911SVinicius Costa Gomes 		break;
26647034b911SVinicius Costa Gomes 
2665eb492e01SAnderson Briglia 	case SMP_CMD_MASTER_IDENT:
26667034b911SVinicius Costa Gomes 		reason = smp_cmd_master_ident(conn, skb);
26677034b911SVinicius Costa Gomes 		break;
26687034b911SVinicius Costa Gomes 
2669eb492e01SAnderson Briglia 	case SMP_CMD_IDENT_INFO:
2670fd349c02SJohan Hedberg 		reason = smp_cmd_ident_info(conn, skb);
2671fd349c02SJohan Hedberg 		break;
2672fd349c02SJohan Hedberg 
2673eb492e01SAnderson Briglia 	case SMP_CMD_IDENT_ADDR_INFO:
2674fd349c02SJohan Hedberg 		reason = smp_cmd_ident_addr_info(conn, skb);
2675fd349c02SJohan Hedberg 		break;
2676fd349c02SJohan Hedberg 
2677eb492e01SAnderson Briglia 	case SMP_CMD_SIGN_INFO:
26787ee4ea36SMarcel Holtmann 		reason = smp_cmd_sign_info(conn, skb);
26797034b911SVinicius Costa Gomes 		break;
26807034b911SVinicius Costa Gomes 
2681d8f8edbeSJohan Hedberg 	case SMP_CMD_PUBLIC_KEY:
2682d8f8edbeSJohan Hedberg 		reason = smp_cmd_public_key(conn, skb);
2683d8f8edbeSJohan Hedberg 		break;
2684d8f8edbeSJohan Hedberg 
26856433a9a2SJohan Hedberg 	case SMP_CMD_DHKEY_CHECK:
26866433a9a2SJohan Hedberg 		reason = smp_cmd_dhkey_check(conn, skb);
26876433a9a2SJohan Hedberg 		break;
26886433a9a2SJohan Hedberg 
26891408bb6eSJohan Hedberg 	case SMP_CMD_KEYPRESS_NOTIFY:
26901408bb6eSJohan Hedberg 		reason = smp_cmd_keypress_notify(conn, skb);
26911408bb6eSJohan Hedberg 		break;
26921408bb6eSJohan Hedberg 
2693eb492e01SAnderson Briglia 	default:
2694eb492e01SAnderson Briglia 		BT_DBG("Unknown command code 0x%2.2x", code);
2695eb492e01SAnderson Briglia 		reason = SMP_CMD_NOTSUPP;
26963a0259bbSVinicius Costa Gomes 		goto done;
26973a0259bbSVinicius Costa Gomes 	}
26983a0259bbSVinicius Costa Gomes 
26993a0259bbSVinicius Costa Gomes done:
27009b7b18efSJohan Hedberg 	if (!err) {
27013a0259bbSVinicius Costa Gomes 		if (reason)
270284794e11SJohan Hedberg 			smp_failure(conn, reason);
2703eb492e01SAnderson Briglia 		kfree_skb(skb);
27049b7b18efSJohan Hedberg 	}
27059b7b18efSJohan Hedberg 
2706eb492e01SAnderson Briglia 	return err;
2707b28b4943SJohan Hedberg 
2708b28b4943SJohan Hedberg drop:
2709b28b4943SJohan Hedberg 	BT_ERR("%s unexpected SMP command 0x%02x from %pMR", hcon->hdev->name,
2710b28b4943SJohan Hedberg 	       code, &hcon->dst);
2711b28b4943SJohan Hedberg 	kfree_skb(skb);
2712b28b4943SJohan Hedberg 	return 0;
2713eb492e01SAnderson Briglia }
27147034b911SVinicius Costa Gomes 
271570db83c4SJohan Hedberg static void smp_teardown_cb(struct l2cap_chan *chan, int err)
271670db83c4SJohan Hedberg {
271770db83c4SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
271870db83c4SJohan Hedberg 
271970db83c4SJohan Hedberg 	BT_DBG("chan %p", chan);
272070db83c4SJohan Hedberg 
2721fc75cc86SJohan Hedberg 	if (chan->data)
27225d88cc73SJohan Hedberg 		smp_chan_destroy(conn);
27235d88cc73SJohan Hedberg 
272470db83c4SJohan Hedberg 	conn->smp = NULL;
272570db83c4SJohan Hedberg 	l2cap_chan_put(chan);
272670db83c4SJohan Hedberg }
272770db83c4SJohan Hedberg 
2728b5ae344dSJohan Hedberg static void bredr_pairing(struct l2cap_chan *chan)
2729b5ae344dSJohan Hedberg {
2730b5ae344dSJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
2731b5ae344dSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
2732b5ae344dSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
2733b5ae344dSJohan Hedberg 	struct smp_cmd_pairing req;
2734b5ae344dSJohan Hedberg 	struct smp_chan *smp;
2735b5ae344dSJohan Hedberg 
2736b5ae344dSJohan Hedberg 	BT_DBG("chan %p", chan);
2737b5ae344dSJohan Hedberg 
2738b5ae344dSJohan Hedberg 	/* Only new pairings are interesting */
2739b5ae344dSJohan Hedberg 	if (!test_bit(HCI_CONN_NEW_LINK_KEY, &hcon->flags))
2740b5ae344dSJohan Hedberg 		return;
2741b5ae344dSJohan Hedberg 
2742b5ae344dSJohan Hedberg 	/* Don't bother if we're not encrypted */
2743b5ae344dSJohan Hedberg 	if (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags))
2744b5ae344dSJohan Hedberg 		return;
2745b5ae344dSJohan Hedberg 
2746b5ae344dSJohan Hedberg 	/* Only master may initiate SMP over BR/EDR */
2747b5ae344dSJohan Hedberg 	if (hcon->role != HCI_ROLE_MASTER)
2748b5ae344dSJohan Hedberg 		return;
2749b5ae344dSJohan Hedberg 
2750b5ae344dSJohan Hedberg 	/* Secure Connections support must be enabled */
2751d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_SC_ENABLED))
2752b5ae344dSJohan Hedberg 		return;
2753b5ae344dSJohan Hedberg 
2754b5ae344dSJohan Hedberg 	/* BR/EDR must use Secure Connections for SMP */
2755b5ae344dSJohan Hedberg 	if (!test_bit(HCI_CONN_AES_CCM, &hcon->flags) &&
2756b7cb93e5SMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP))
2757b5ae344dSJohan Hedberg 		return;
2758b5ae344dSJohan Hedberg 
2759b5ae344dSJohan Hedberg 	/* If our LE support is not enabled don't do anything */
2760d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED))
2761b5ae344dSJohan Hedberg 		return;
2762b5ae344dSJohan Hedberg 
2763b5ae344dSJohan Hedberg 	/* Don't bother if remote LE support is not enabled */
2764b5ae344dSJohan Hedberg 	if (!lmp_host_le_capable(hcon))
2765b5ae344dSJohan Hedberg 		return;
2766b5ae344dSJohan Hedberg 
2767b5ae344dSJohan Hedberg 	/* Remote must support SMP fixed chan for BR/EDR */
2768b5ae344dSJohan Hedberg 	if (!(conn->remote_fixed_chan & L2CAP_FC_SMP_BREDR))
2769b5ae344dSJohan Hedberg 		return;
2770b5ae344dSJohan Hedberg 
2771b5ae344dSJohan Hedberg 	/* Don't bother if SMP is already ongoing */
2772b5ae344dSJohan Hedberg 	if (chan->data)
2773b5ae344dSJohan Hedberg 		return;
2774b5ae344dSJohan Hedberg 
2775b5ae344dSJohan Hedberg 	smp = smp_chan_create(conn);
2776b5ae344dSJohan Hedberg 	if (!smp) {
2777b5ae344dSJohan Hedberg 		BT_ERR("%s unable to create SMP context for BR/EDR",
2778b5ae344dSJohan Hedberg 		       hdev->name);
2779b5ae344dSJohan Hedberg 		return;
2780b5ae344dSJohan Hedberg 	}
2781b5ae344dSJohan Hedberg 
2782b5ae344dSJohan Hedberg 	set_bit(SMP_FLAG_SC, &smp->flags);
2783b5ae344dSJohan Hedberg 
2784b5ae344dSJohan Hedberg 	BT_DBG("%s starting SMP over BR/EDR", hdev->name);
2785b5ae344dSJohan Hedberg 
2786b5ae344dSJohan Hedberg 	/* Prepare and send the BR/EDR SMP Pairing Request */
2787b5ae344dSJohan Hedberg 	build_bredr_pairing_cmd(smp, &req, NULL);
2788b5ae344dSJohan Hedberg 
2789b5ae344dSJohan Hedberg 	smp->preq[0] = SMP_CMD_PAIRING_REQ;
2790b5ae344dSJohan Hedberg 	memcpy(&smp->preq[1], &req, sizeof(req));
2791b5ae344dSJohan Hedberg 
2792b5ae344dSJohan Hedberg 	smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(req), &req);
2793b5ae344dSJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP);
2794b5ae344dSJohan Hedberg }
2795b5ae344dSJohan Hedberg 
279644f1a7abSJohan Hedberg static void smp_resume_cb(struct l2cap_chan *chan)
279744f1a7abSJohan Hedberg {
2798b68fda68SJohan Hedberg 	struct smp_chan *smp = chan->data;
279944f1a7abSJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
280044f1a7abSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
280144f1a7abSJohan Hedberg 
280244f1a7abSJohan Hedberg 	BT_DBG("chan %p", chan);
280344f1a7abSJohan Hedberg 
2804b5ae344dSJohan Hedberg 	if (hcon->type == ACL_LINK) {
2805b5ae344dSJohan Hedberg 		bredr_pairing(chan);
2806ef8efe4bSJohan Hedberg 		return;
2807b5ae344dSJohan Hedberg 	}
2808ef8efe4bSJohan Hedberg 
280986d1407cSJohan Hedberg 	if (!smp)
281086d1407cSJohan Hedberg 		return;
2811b68fda68SJohan Hedberg 
281284bc0db5SJohan Hedberg 	if (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags))
281384bc0db5SJohan Hedberg 		return;
281484bc0db5SJohan Hedberg 
2815b68fda68SJohan Hedberg 	cancel_delayed_work(&smp->security_timer);
281686d1407cSJohan Hedberg 
2817d6268e86SJohan Hedberg 	smp_distribute_keys(smp);
281844f1a7abSJohan Hedberg }
281944f1a7abSJohan Hedberg 
282070db83c4SJohan Hedberg static void smp_ready_cb(struct l2cap_chan *chan)
282170db83c4SJohan Hedberg {
282270db83c4SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
2823b5ae344dSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
282470db83c4SJohan Hedberg 
282570db83c4SJohan Hedberg 	BT_DBG("chan %p", chan);
282670db83c4SJohan Hedberg 
282770db83c4SJohan Hedberg 	conn->smp = chan;
282870db83c4SJohan Hedberg 	l2cap_chan_hold(chan);
2829b5ae344dSJohan Hedberg 
2830b5ae344dSJohan Hedberg 	if (hcon->type == ACL_LINK && test_bit(HCI_CONN_ENCRYPT, &hcon->flags))
2831b5ae344dSJohan Hedberg 		bredr_pairing(chan);
283270db83c4SJohan Hedberg }
283370db83c4SJohan Hedberg 
28344befb867SJohan Hedberg static int smp_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
28354befb867SJohan Hedberg {
28364befb867SJohan Hedberg 	int err;
28374befb867SJohan Hedberg 
28384befb867SJohan Hedberg 	BT_DBG("chan %p", chan);
28394befb867SJohan Hedberg 
28404befb867SJohan Hedberg 	err = smp_sig_channel(chan, skb);
28414befb867SJohan Hedberg 	if (err) {
2842b68fda68SJohan Hedberg 		struct smp_chan *smp = chan->data;
28434befb867SJohan Hedberg 
2844b68fda68SJohan Hedberg 		if (smp)
2845b68fda68SJohan Hedberg 			cancel_delayed_work_sync(&smp->security_timer);
28464befb867SJohan Hedberg 
28471e91c29eSJohan Hedberg 		hci_disconnect(chan->conn->hcon, HCI_ERROR_AUTH_FAILURE);
28484befb867SJohan Hedberg 	}
28494befb867SJohan Hedberg 
28504befb867SJohan Hedberg 	return err;
28514befb867SJohan Hedberg }
28524befb867SJohan Hedberg 
285370db83c4SJohan Hedberg static struct sk_buff *smp_alloc_skb_cb(struct l2cap_chan *chan,
285470db83c4SJohan Hedberg 					unsigned long hdr_len,
285570db83c4SJohan Hedberg 					unsigned long len, int nb)
285670db83c4SJohan Hedberg {
285770db83c4SJohan Hedberg 	struct sk_buff *skb;
285870db83c4SJohan Hedberg 
285970db83c4SJohan Hedberg 	skb = bt_skb_alloc(hdr_len + len, GFP_KERNEL);
286070db83c4SJohan Hedberg 	if (!skb)
286170db83c4SJohan Hedberg 		return ERR_PTR(-ENOMEM);
286270db83c4SJohan Hedberg 
286370db83c4SJohan Hedberg 	skb->priority = HCI_PRIO_MAX;
286470db83c4SJohan Hedberg 	bt_cb(skb)->chan = chan;
286570db83c4SJohan Hedberg 
286670db83c4SJohan Hedberg 	return skb;
286770db83c4SJohan Hedberg }
286870db83c4SJohan Hedberg 
286970db83c4SJohan Hedberg static const struct l2cap_ops smp_chan_ops = {
287070db83c4SJohan Hedberg 	.name			= "Security Manager",
287170db83c4SJohan Hedberg 	.ready			= smp_ready_cb,
28725d88cc73SJohan Hedberg 	.recv			= smp_recv_cb,
287370db83c4SJohan Hedberg 	.alloc_skb		= smp_alloc_skb_cb,
287470db83c4SJohan Hedberg 	.teardown		= smp_teardown_cb,
287544f1a7abSJohan Hedberg 	.resume			= smp_resume_cb,
287670db83c4SJohan Hedberg 
287770db83c4SJohan Hedberg 	.new_connection		= l2cap_chan_no_new_connection,
287870db83c4SJohan Hedberg 	.state_change		= l2cap_chan_no_state_change,
287970db83c4SJohan Hedberg 	.close			= l2cap_chan_no_close,
288070db83c4SJohan Hedberg 	.defer			= l2cap_chan_no_defer,
288170db83c4SJohan Hedberg 	.suspend		= l2cap_chan_no_suspend,
288270db83c4SJohan Hedberg 	.set_shutdown		= l2cap_chan_no_set_shutdown,
288370db83c4SJohan Hedberg 	.get_sndtimeo		= l2cap_chan_no_get_sndtimeo,
288470db83c4SJohan Hedberg };
288570db83c4SJohan Hedberg 
288670db83c4SJohan Hedberg static inline struct l2cap_chan *smp_new_conn_cb(struct l2cap_chan *pchan)
288770db83c4SJohan Hedberg {
288870db83c4SJohan Hedberg 	struct l2cap_chan *chan;
288970db83c4SJohan Hedberg 
289070db83c4SJohan Hedberg 	BT_DBG("pchan %p", pchan);
289170db83c4SJohan Hedberg 
289270db83c4SJohan Hedberg 	chan = l2cap_chan_create();
289370db83c4SJohan Hedberg 	if (!chan)
289470db83c4SJohan Hedberg 		return NULL;
289570db83c4SJohan Hedberg 
289670db83c4SJohan Hedberg 	chan->chan_type	= pchan->chan_type;
289770db83c4SJohan Hedberg 	chan->ops	= &smp_chan_ops;
289870db83c4SJohan Hedberg 	chan->scid	= pchan->scid;
289970db83c4SJohan Hedberg 	chan->dcid	= chan->scid;
290070db83c4SJohan Hedberg 	chan->imtu	= pchan->imtu;
290170db83c4SJohan Hedberg 	chan->omtu	= pchan->omtu;
290270db83c4SJohan Hedberg 	chan->mode	= pchan->mode;
290370db83c4SJohan Hedberg 
2904abe84903SJohan Hedberg 	/* Other L2CAP channels may request SMP routines in order to
2905abe84903SJohan Hedberg 	 * change the security level. This means that the SMP channel
2906abe84903SJohan Hedberg 	 * lock must be considered in its own category to avoid lockdep
2907abe84903SJohan Hedberg 	 * warnings.
2908abe84903SJohan Hedberg 	 */
2909abe84903SJohan Hedberg 	atomic_set(&chan->nesting, L2CAP_NESTING_SMP);
2910abe84903SJohan Hedberg 
291170db83c4SJohan Hedberg 	BT_DBG("created chan %p", chan);
291270db83c4SJohan Hedberg 
291370db83c4SJohan Hedberg 	return chan;
291470db83c4SJohan Hedberg }
291570db83c4SJohan Hedberg 
291670db83c4SJohan Hedberg static const struct l2cap_ops smp_root_chan_ops = {
291770db83c4SJohan Hedberg 	.name			= "Security Manager Root",
291870db83c4SJohan Hedberg 	.new_connection		= smp_new_conn_cb,
291970db83c4SJohan Hedberg 
292070db83c4SJohan Hedberg 	/* None of these are implemented for the root channel */
292170db83c4SJohan Hedberg 	.close			= l2cap_chan_no_close,
292270db83c4SJohan Hedberg 	.alloc_skb		= l2cap_chan_no_alloc_skb,
292370db83c4SJohan Hedberg 	.recv			= l2cap_chan_no_recv,
292470db83c4SJohan Hedberg 	.state_change		= l2cap_chan_no_state_change,
292570db83c4SJohan Hedberg 	.teardown		= l2cap_chan_no_teardown,
292670db83c4SJohan Hedberg 	.ready			= l2cap_chan_no_ready,
292770db83c4SJohan Hedberg 	.defer			= l2cap_chan_no_defer,
292870db83c4SJohan Hedberg 	.suspend		= l2cap_chan_no_suspend,
292970db83c4SJohan Hedberg 	.resume			= l2cap_chan_no_resume,
293070db83c4SJohan Hedberg 	.set_shutdown		= l2cap_chan_no_set_shutdown,
293170db83c4SJohan Hedberg 	.get_sndtimeo		= l2cap_chan_no_get_sndtimeo,
293270db83c4SJohan Hedberg };
293370db83c4SJohan Hedberg 
2934ef8efe4bSJohan Hedberg static struct l2cap_chan *smp_add_cid(struct hci_dev *hdev, u16 cid)
2935711eafe3SJohan Hedberg {
293670db83c4SJohan Hedberg 	struct l2cap_chan *chan;
293788a479d9SMarcel Holtmann 	struct smp_dev *smp;
2938defce9e8SJohan Hedberg 	struct crypto_blkcipher *tfm_aes;
293970db83c4SJohan Hedberg 
2940ef8efe4bSJohan Hedberg 	if (cid == L2CAP_CID_SMP_BREDR) {
294188a479d9SMarcel Holtmann 		smp = NULL;
2942ef8efe4bSJohan Hedberg 		goto create_chan;
2943ef8efe4bSJohan Hedberg 	}
2944711eafe3SJohan Hedberg 
294588a479d9SMarcel Holtmann 	smp = kzalloc(sizeof(*smp), GFP_KERNEL);
294688a479d9SMarcel Holtmann 	if (!smp)
294788a479d9SMarcel Holtmann 		return ERR_PTR(-ENOMEM);
294888a479d9SMarcel Holtmann 
294988a479d9SMarcel Holtmann 	tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
2950defce9e8SJohan Hedberg 	if (IS_ERR(tfm_aes)) {
295188a479d9SMarcel Holtmann 		BT_ERR("Unable to create ECB crypto context");
295288a479d9SMarcel Holtmann 		kzfree(smp);
2953fe700771SFengguang Wu 		return ERR_CAST(tfm_aes);
2954711eafe3SJohan Hedberg 	}
2955711eafe3SJohan Hedberg 
295688a479d9SMarcel Holtmann 	smp->tfm_aes = tfm_aes;
295788a479d9SMarcel Holtmann 
2958ef8efe4bSJohan Hedberg create_chan:
295970db83c4SJohan Hedberg 	chan = l2cap_chan_create();
296070db83c4SJohan Hedberg 	if (!chan) {
296188a479d9SMarcel Holtmann 		crypto_free_blkcipher(smp->tfm_aes);
296288a479d9SMarcel Holtmann 		kzfree(smp);
2963ef8efe4bSJohan Hedberg 		return ERR_PTR(-ENOMEM);
296470db83c4SJohan Hedberg 	}
296570db83c4SJohan Hedberg 
296688a479d9SMarcel Holtmann 	chan->data = smp;
2967defce9e8SJohan Hedberg 
2968ef8efe4bSJohan Hedberg 	l2cap_add_scid(chan, cid);
296970db83c4SJohan Hedberg 
297070db83c4SJohan Hedberg 	l2cap_chan_set_defaults(chan);
297170db83c4SJohan Hedberg 
2972157029baSMarcel Holtmann 	if (cid == L2CAP_CID_SMP) {
297339e3e744SJohan Hedberg 		u8 bdaddr_type;
297439e3e744SJohan Hedberg 
297539e3e744SJohan Hedberg 		hci_copy_identity_address(hdev, &chan->src, &bdaddr_type);
297639e3e744SJohan Hedberg 
297739e3e744SJohan Hedberg 		if (bdaddr_type == ADDR_LE_DEV_PUBLIC)
297870db83c4SJohan Hedberg 			chan->src_type = BDADDR_LE_PUBLIC;
297939e3e744SJohan Hedberg 		else
298039e3e744SJohan Hedberg 			chan->src_type = BDADDR_LE_RANDOM;
2981157029baSMarcel Holtmann 	} else {
2982157029baSMarcel Holtmann 		bacpy(&chan->src, &hdev->bdaddr);
2983ef8efe4bSJohan Hedberg 		chan->src_type = BDADDR_BREDR;
2984157029baSMarcel Holtmann 	}
2985157029baSMarcel Holtmann 
298670db83c4SJohan Hedberg 	chan->state = BT_LISTEN;
298770db83c4SJohan Hedberg 	chan->mode = L2CAP_MODE_BASIC;
298870db83c4SJohan Hedberg 	chan->imtu = L2CAP_DEFAULT_MTU;
298970db83c4SJohan Hedberg 	chan->ops = &smp_root_chan_ops;
299070db83c4SJohan Hedberg 
2991abe84903SJohan Hedberg 	/* Set correct nesting level for a parent/listening channel */
2992abe84903SJohan Hedberg 	atomic_set(&chan->nesting, L2CAP_NESTING_PARENT);
2993abe84903SJohan Hedberg 
2994ef8efe4bSJohan Hedberg 	return chan;
2995711eafe3SJohan Hedberg }
2996711eafe3SJohan Hedberg 
2997ef8efe4bSJohan Hedberg static void smp_del_chan(struct l2cap_chan *chan)
2998711eafe3SJohan Hedberg {
299988a479d9SMarcel Holtmann 	struct smp_dev *smp;
300070db83c4SJohan Hedberg 
3001ef8efe4bSJohan Hedberg 	BT_DBG("chan %p", chan);
3002711eafe3SJohan Hedberg 
300388a479d9SMarcel Holtmann 	smp = chan->data;
300488a479d9SMarcel Holtmann 	if (smp) {
3005defce9e8SJohan Hedberg 		chan->data = NULL;
300688a479d9SMarcel Holtmann 		if (smp->tfm_aes)
300788a479d9SMarcel Holtmann 			crypto_free_blkcipher(smp->tfm_aes);
300888a479d9SMarcel Holtmann 		kzfree(smp);
3009711eafe3SJohan Hedberg 	}
301070db83c4SJohan Hedberg 
301170db83c4SJohan Hedberg 	l2cap_chan_put(chan);
3012711eafe3SJohan Hedberg }
3013ef8efe4bSJohan Hedberg 
3014300acfdeSMarcel Holtmann static ssize_t force_bredr_smp_read(struct file *file,
3015300acfdeSMarcel Holtmann 				    char __user *user_buf,
3016300acfdeSMarcel Holtmann 				    size_t count, loff_t *ppos)
3017300acfdeSMarcel Holtmann {
3018300acfdeSMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
3019300acfdeSMarcel Holtmann 	char buf[3];
3020300acfdeSMarcel Holtmann 
3021b7cb93e5SMarcel Holtmann 	buf[0] = hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP) ? 'Y': 'N';
3022300acfdeSMarcel Holtmann 	buf[1] = '\n';
3023300acfdeSMarcel Holtmann 	buf[2] = '\0';
3024300acfdeSMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
3025300acfdeSMarcel Holtmann }
3026300acfdeSMarcel Holtmann 
3027300acfdeSMarcel Holtmann static ssize_t force_bredr_smp_write(struct file *file,
3028300acfdeSMarcel Holtmann 				     const char __user *user_buf,
3029300acfdeSMarcel Holtmann 				     size_t count, loff_t *ppos)
3030300acfdeSMarcel Holtmann {
3031300acfdeSMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
3032300acfdeSMarcel Holtmann 	char buf[32];
3033300acfdeSMarcel Holtmann 	size_t buf_size = min(count, (sizeof(buf)-1));
3034300acfdeSMarcel Holtmann 	bool enable;
3035300acfdeSMarcel Holtmann 
3036300acfdeSMarcel Holtmann 	if (copy_from_user(buf, user_buf, buf_size))
3037300acfdeSMarcel Holtmann 		return -EFAULT;
3038300acfdeSMarcel Holtmann 
3039300acfdeSMarcel Holtmann 	buf[buf_size] = '\0';
3040300acfdeSMarcel Holtmann 	if (strtobool(buf, &enable))
3041300acfdeSMarcel Holtmann 		return -EINVAL;
3042300acfdeSMarcel Holtmann 
3043b7cb93e5SMarcel Holtmann 	if (enable == hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP))
3044300acfdeSMarcel Holtmann 		return -EALREADY;
3045300acfdeSMarcel Holtmann 
3046300acfdeSMarcel Holtmann 	if (enable) {
3047300acfdeSMarcel Holtmann 		struct l2cap_chan *chan;
3048300acfdeSMarcel Holtmann 
3049300acfdeSMarcel Holtmann 		chan = smp_add_cid(hdev, L2CAP_CID_SMP_BREDR);
3050300acfdeSMarcel Holtmann 		if (IS_ERR(chan))
3051300acfdeSMarcel Holtmann 			return PTR_ERR(chan);
3052300acfdeSMarcel Holtmann 
3053300acfdeSMarcel Holtmann 		hdev->smp_bredr_data = chan;
3054300acfdeSMarcel Holtmann 	} else {
3055300acfdeSMarcel Holtmann 		struct l2cap_chan *chan;
3056300acfdeSMarcel Holtmann 
3057300acfdeSMarcel Holtmann 		chan = hdev->smp_bredr_data;
3058300acfdeSMarcel Holtmann 		hdev->smp_bredr_data = NULL;
3059300acfdeSMarcel Holtmann 		smp_del_chan(chan);
3060300acfdeSMarcel Holtmann 	}
3061300acfdeSMarcel Holtmann 
3062b7cb93e5SMarcel Holtmann 	hci_dev_change_flag(hdev, HCI_FORCE_BREDR_SMP);
3063300acfdeSMarcel Holtmann 
3064300acfdeSMarcel Holtmann 	return count;
3065300acfdeSMarcel Holtmann }
3066300acfdeSMarcel Holtmann 
3067300acfdeSMarcel Holtmann static const struct file_operations force_bredr_smp_fops = {
3068300acfdeSMarcel Holtmann 	.open		= simple_open,
3069300acfdeSMarcel Holtmann 	.read		= force_bredr_smp_read,
3070300acfdeSMarcel Holtmann 	.write		= force_bredr_smp_write,
3071300acfdeSMarcel Holtmann 	.llseek		= default_llseek,
3072300acfdeSMarcel Holtmann };
3073300acfdeSMarcel Holtmann 
3074ef8efe4bSJohan Hedberg int smp_register(struct hci_dev *hdev)
3075ef8efe4bSJohan Hedberg {
3076ef8efe4bSJohan Hedberg 	struct l2cap_chan *chan;
3077ef8efe4bSJohan Hedberg 
3078ef8efe4bSJohan Hedberg 	BT_DBG("%s", hdev->name);
3079ef8efe4bSJohan Hedberg 
30807e7ec445SMarcel Holtmann 	/* If the controller does not support Low Energy operation, then
30817e7ec445SMarcel Holtmann 	 * there is also no need to register any SMP channel.
30827e7ec445SMarcel Holtmann 	 */
30837e7ec445SMarcel Holtmann 	if (!lmp_le_capable(hdev))
30847e7ec445SMarcel Holtmann 		return 0;
30857e7ec445SMarcel Holtmann 
30862b8df323SMarcel Holtmann 	if (WARN_ON(hdev->smp_data)) {
30872b8df323SMarcel Holtmann 		chan = hdev->smp_data;
30882b8df323SMarcel Holtmann 		hdev->smp_data = NULL;
30892b8df323SMarcel Holtmann 		smp_del_chan(chan);
30902b8df323SMarcel Holtmann 	}
30912b8df323SMarcel Holtmann 
3092ef8efe4bSJohan Hedberg 	chan = smp_add_cid(hdev, L2CAP_CID_SMP);
3093ef8efe4bSJohan Hedberg 	if (IS_ERR(chan))
3094ef8efe4bSJohan Hedberg 		return PTR_ERR(chan);
3095ef8efe4bSJohan Hedberg 
3096ef8efe4bSJohan Hedberg 	hdev->smp_data = chan;
3097ef8efe4bSJohan Hedberg 
3098300acfdeSMarcel Holtmann 	/* If the controller does not support BR/EDR Secure Connections
3099300acfdeSMarcel Holtmann 	 * feature, then the BR/EDR SMP channel shall not be present.
3100300acfdeSMarcel Holtmann 	 *
3101300acfdeSMarcel Holtmann 	 * To test this with Bluetooth 4.0 controllers, create a debugfs
3102300acfdeSMarcel Holtmann 	 * switch that allows forcing BR/EDR SMP support and accepting
3103300acfdeSMarcel Holtmann 	 * cross-transport pairing on non-AES encrypted connections.
3104300acfdeSMarcel Holtmann 	 */
3105300acfdeSMarcel Holtmann 	if (!lmp_sc_capable(hdev)) {
3106300acfdeSMarcel Holtmann 		debugfs_create_file("force_bredr_smp", 0644, hdev->debugfs,
3107300acfdeSMarcel Holtmann 				    hdev, &force_bredr_smp_fops);
3108ef8efe4bSJohan Hedberg 		return 0;
3109300acfdeSMarcel Holtmann 	}
3110ef8efe4bSJohan Hedberg 
31112b8df323SMarcel Holtmann 	if (WARN_ON(hdev->smp_bredr_data)) {
31122b8df323SMarcel Holtmann 		chan = hdev->smp_bredr_data;
31132b8df323SMarcel Holtmann 		hdev->smp_bredr_data = NULL;
31142b8df323SMarcel Holtmann 		smp_del_chan(chan);
31152b8df323SMarcel Holtmann 	}
31162b8df323SMarcel Holtmann 
3117ef8efe4bSJohan Hedberg 	chan = smp_add_cid(hdev, L2CAP_CID_SMP_BREDR);
3118ef8efe4bSJohan Hedberg 	if (IS_ERR(chan)) {
3119ef8efe4bSJohan Hedberg 		int err = PTR_ERR(chan);
3120ef8efe4bSJohan Hedberg 		chan = hdev->smp_data;
3121ef8efe4bSJohan Hedberg 		hdev->smp_data = NULL;
3122ef8efe4bSJohan Hedberg 		smp_del_chan(chan);
3123ef8efe4bSJohan Hedberg 		return err;
3124ef8efe4bSJohan Hedberg 	}
3125ef8efe4bSJohan Hedberg 
3126ef8efe4bSJohan Hedberg 	hdev->smp_bredr_data = chan;
3127ef8efe4bSJohan Hedberg 
3128ef8efe4bSJohan Hedberg 	return 0;
3129ef8efe4bSJohan Hedberg }
3130ef8efe4bSJohan Hedberg 
3131ef8efe4bSJohan Hedberg void smp_unregister(struct hci_dev *hdev)
3132ef8efe4bSJohan Hedberg {
3133ef8efe4bSJohan Hedberg 	struct l2cap_chan *chan;
3134ef8efe4bSJohan Hedberg 
3135ef8efe4bSJohan Hedberg 	if (hdev->smp_bredr_data) {
3136ef8efe4bSJohan Hedberg 		chan = hdev->smp_bredr_data;
3137ef8efe4bSJohan Hedberg 		hdev->smp_bredr_data = NULL;
3138ef8efe4bSJohan Hedberg 		smp_del_chan(chan);
3139ef8efe4bSJohan Hedberg 	}
3140ef8efe4bSJohan Hedberg 
3141ef8efe4bSJohan Hedberg 	if (hdev->smp_data) {
3142ef8efe4bSJohan Hedberg 		chan = hdev->smp_data;
3143ef8efe4bSJohan Hedberg 		hdev->smp_data = NULL;
3144ef8efe4bSJohan Hedberg 		smp_del_chan(chan);
3145ef8efe4bSJohan Hedberg 	}
3146ef8efe4bSJohan Hedberg }
31470a2b0f04SJohan Hedberg 
31480a2b0f04SJohan Hedberg #if IS_ENABLED(CONFIG_BT_SELFTEST_SMP)
31490a2b0f04SJohan Hedberg 
3150cfc4198eSJohan Hedberg static int __init test_ah(struct crypto_blkcipher *tfm_aes)
3151cfc4198eSJohan Hedberg {
3152cfc4198eSJohan Hedberg 	const u8 irk[16] = {
3153cfc4198eSJohan Hedberg 			0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34,
3154cfc4198eSJohan Hedberg 			0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec };
3155cfc4198eSJohan Hedberg 	const u8 r[3] = { 0x94, 0x81, 0x70 };
3156cfc4198eSJohan Hedberg 	const u8 exp[3] = { 0xaa, 0xfb, 0x0d };
3157cfc4198eSJohan Hedberg 	u8 res[3];
3158cfc4198eSJohan Hedberg 	int err;
3159cfc4198eSJohan Hedberg 
3160cfc4198eSJohan Hedberg 	err = smp_ah(tfm_aes, irk, r, res);
3161cfc4198eSJohan Hedberg 	if (err)
3162cfc4198eSJohan Hedberg 		return err;
3163cfc4198eSJohan Hedberg 
3164cfc4198eSJohan Hedberg 	if (memcmp(res, exp, 3))
3165cfc4198eSJohan Hedberg 		return -EINVAL;
3166cfc4198eSJohan Hedberg 
3167cfc4198eSJohan Hedberg 	return 0;
3168cfc4198eSJohan Hedberg }
3169cfc4198eSJohan Hedberg 
3170cfc4198eSJohan Hedberg static int __init test_c1(struct crypto_blkcipher *tfm_aes)
3171cfc4198eSJohan Hedberg {
3172cfc4198eSJohan Hedberg 	const u8 k[16] = {
3173cfc4198eSJohan Hedberg 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3174cfc4198eSJohan Hedberg 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
3175cfc4198eSJohan Hedberg 	const u8 r[16] = {
3176cfc4198eSJohan Hedberg 			0xe0, 0x2e, 0x70, 0xc6, 0x4e, 0x27, 0x88, 0x63,
3177cfc4198eSJohan Hedberg 			0x0e, 0x6f, 0xad, 0x56, 0x21, 0xd5, 0x83, 0x57 };
3178cfc4198eSJohan Hedberg 	const u8 preq[7] = { 0x01, 0x01, 0x00, 0x00, 0x10, 0x07, 0x07 };
3179cfc4198eSJohan Hedberg 	const u8 pres[7] = { 0x02, 0x03, 0x00, 0x00, 0x08, 0x00, 0x05 };
3180cfc4198eSJohan Hedberg 	const u8 _iat = 0x01;
3181cfc4198eSJohan Hedberg 	const u8 _rat = 0x00;
3182cfc4198eSJohan Hedberg 	const bdaddr_t ra = { { 0xb6, 0xb5, 0xb4, 0xb3, 0xb2, 0xb1 } };
3183cfc4198eSJohan Hedberg 	const bdaddr_t ia = { { 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1 } };
3184cfc4198eSJohan Hedberg 	const u8 exp[16] = {
3185cfc4198eSJohan Hedberg 			0x86, 0x3b, 0xf1, 0xbe, 0xc5, 0x4d, 0xa7, 0xd2,
3186cfc4198eSJohan Hedberg 			0xea, 0x88, 0x89, 0x87, 0xef, 0x3f, 0x1e, 0x1e };
3187cfc4198eSJohan Hedberg 	u8 res[16];
3188cfc4198eSJohan Hedberg 	int err;
3189cfc4198eSJohan Hedberg 
3190cfc4198eSJohan Hedberg 	err = smp_c1(tfm_aes, k, r, preq, pres, _iat, &ia, _rat, &ra, res);
3191cfc4198eSJohan Hedberg 	if (err)
3192cfc4198eSJohan Hedberg 		return err;
3193cfc4198eSJohan Hedberg 
3194cfc4198eSJohan Hedberg 	if (memcmp(res, exp, 16))
3195cfc4198eSJohan Hedberg 		return -EINVAL;
3196cfc4198eSJohan Hedberg 
3197cfc4198eSJohan Hedberg 	return 0;
3198cfc4198eSJohan Hedberg }
3199cfc4198eSJohan Hedberg 
3200cfc4198eSJohan Hedberg static int __init test_s1(struct crypto_blkcipher *tfm_aes)
3201cfc4198eSJohan Hedberg {
3202cfc4198eSJohan Hedberg 	const u8 k[16] = {
3203cfc4198eSJohan Hedberg 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3204cfc4198eSJohan Hedberg 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
3205cfc4198eSJohan Hedberg 	const u8 r1[16] = {
3206cfc4198eSJohan Hedberg 			0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 };
3207cfc4198eSJohan Hedberg 	const u8 r2[16] = {
3208cfc4198eSJohan Hedberg 			0x00, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99 };
3209cfc4198eSJohan Hedberg 	const u8 exp[16] = {
3210cfc4198eSJohan Hedberg 			0x62, 0xa0, 0x6d, 0x79, 0xae, 0x16, 0x42, 0x5b,
3211cfc4198eSJohan Hedberg 			0x9b, 0xf4, 0xb0, 0xe8, 0xf0, 0xe1, 0x1f, 0x9a };
3212cfc4198eSJohan Hedberg 	u8 res[16];
3213cfc4198eSJohan Hedberg 	int err;
3214cfc4198eSJohan Hedberg 
3215cfc4198eSJohan Hedberg 	err = smp_s1(tfm_aes, k, r1, r2, res);
3216cfc4198eSJohan Hedberg 	if (err)
3217cfc4198eSJohan Hedberg 		return err;
3218cfc4198eSJohan Hedberg 
3219cfc4198eSJohan Hedberg 	if (memcmp(res, exp, 16))
3220cfc4198eSJohan Hedberg 		return -EINVAL;
3221cfc4198eSJohan Hedberg 
3222cfc4198eSJohan Hedberg 	return 0;
3223cfc4198eSJohan Hedberg }
3224cfc4198eSJohan Hedberg 
3225fb2969a3SJohan Hedberg static int __init test_f4(struct crypto_hash *tfm_cmac)
3226fb2969a3SJohan Hedberg {
3227fb2969a3SJohan Hedberg 	const u8 u[32] = {
3228fb2969a3SJohan Hedberg 			0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc,
3229fb2969a3SJohan Hedberg 			0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef,
3230fb2969a3SJohan Hedberg 			0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e,
3231fb2969a3SJohan Hedberg 			0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20 };
3232fb2969a3SJohan Hedberg 	const u8 v[32] = {
3233fb2969a3SJohan Hedberg 			0xfd, 0xc5, 0x7f, 0xf4, 0x49, 0xdd, 0x4f, 0x6b,
3234fb2969a3SJohan Hedberg 			0xfb, 0x7c, 0x9d, 0xf1, 0xc2, 0x9a, 0xcb, 0x59,
3235fb2969a3SJohan Hedberg 			0x2a, 0xe7, 0xd4, 0xee, 0xfb, 0xfc, 0x0a, 0x90,
3236fb2969a3SJohan Hedberg 			0x9a, 0xbb, 0xf6, 0x32, 0x3d, 0x8b, 0x18, 0x55 };
3237fb2969a3SJohan Hedberg 	const u8 x[16] = {
3238fb2969a3SJohan Hedberg 			0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff,
3239fb2969a3SJohan Hedberg 			0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 };
3240fb2969a3SJohan Hedberg 	const u8 z = 0x00;
3241fb2969a3SJohan Hedberg 	const u8 exp[16] = {
3242fb2969a3SJohan Hedberg 			0x2d, 0x87, 0x74, 0xa9, 0xbe, 0xa1, 0xed, 0xf1,
3243fb2969a3SJohan Hedberg 			0x1c, 0xbd, 0xa9, 0x07, 0xf1, 0x16, 0xc9, 0xf2 };
3244fb2969a3SJohan Hedberg 	u8 res[16];
3245fb2969a3SJohan Hedberg 	int err;
3246fb2969a3SJohan Hedberg 
3247fb2969a3SJohan Hedberg 	err = smp_f4(tfm_cmac, u, v, x, z, res);
3248fb2969a3SJohan Hedberg 	if (err)
3249fb2969a3SJohan Hedberg 		return err;
3250fb2969a3SJohan Hedberg 
3251fb2969a3SJohan Hedberg 	if (memcmp(res, exp, 16))
3252fb2969a3SJohan Hedberg 		return -EINVAL;
3253fb2969a3SJohan Hedberg 
3254fb2969a3SJohan Hedberg 	return 0;
3255fb2969a3SJohan Hedberg }
3256fb2969a3SJohan Hedberg 
3257fb2969a3SJohan Hedberg static int __init test_f5(struct crypto_hash *tfm_cmac)
3258fb2969a3SJohan Hedberg {
3259fb2969a3SJohan Hedberg 	const u8 w[32] = {
3260fb2969a3SJohan Hedberg 			0x98, 0xa6, 0xbf, 0x73, 0xf3, 0x34, 0x8d, 0x86,
3261fb2969a3SJohan Hedberg 			0xf1, 0x66, 0xf8, 0xb4, 0x13, 0x6b, 0x79, 0x99,
3262fb2969a3SJohan Hedberg 			0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34,
3263fb2969a3SJohan Hedberg 			0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec };
3264fb2969a3SJohan Hedberg 	const u8 n1[16] = {
3265fb2969a3SJohan Hedberg 			0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff,
3266fb2969a3SJohan Hedberg 			0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 };
3267fb2969a3SJohan Hedberg 	const u8 n2[16] = {
3268fb2969a3SJohan Hedberg 			0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21,
3269fb2969a3SJohan Hedberg 			0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6 };
3270fb2969a3SJohan Hedberg 	const u8 a1[7] = { 0xce, 0xbf, 0x37, 0x37, 0x12, 0x56, 0x00 };
3271fb2969a3SJohan Hedberg 	const u8 a2[7] = { 0xc1, 0xcf, 0x2d, 0x70, 0x13, 0xa7, 0x00 };
3272fb2969a3SJohan Hedberg 	const u8 exp_ltk[16] = {
3273fb2969a3SJohan Hedberg 			0x38, 0x0a, 0x75, 0x94, 0xb5, 0x22, 0x05, 0x98,
3274fb2969a3SJohan Hedberg 			0x23, 0xcd, 0xd7, 0x69, 0x11, 0x79, 0x86, 0x69 };
3275fb2969a3SJohan Hedberg 	const u8 exp_mackey[16] = {
3276fb2969a3SJohan Hedberg 			0x20, 0x6e, 0x63, 0xce, 0x20, 0x6a, 0x3f, 0xfd,
3277fb2969a3SJohan Hedberg 			0x02, 0x4a, 0x08, 0xa1, 0x76, 0xf1, 0x65, 0x29 };
3278fb2969a3SJohan Hedberg 	u8 mackey[16], ltk[16];
3279fb2969a3SJohan Hedberg 	int err;
3280fb2969a3SJohan Hedberg 
3281fb2969a3SJohan Hedberg 	err = smp_f5(tfm_cmac, w, n1, n2, a1, a2, mackey, ltk);
3282fb2969a3SJohan Hedberg 	if (err)
3283fb2969a3SJohan Hedberg 		return err;
3284fb2969a3SJohan Hedberg 
3285fb2969a3SJohan Hedberg 	if (memcmp(mackey, exp_mackey, 16))
3286fb2969a3SJohan Hedberg 		return -EINVAL;
3287fb2969a3SJohan Hedberg 
3288fb2969a3SJohan Hedberg 	if (memcmp(ltk, exp_ltk, 16))
3289fb2969a3SJohan Hedberg 		return -EINVAL;
3290fb2969a3SJohan Hedberg 
3291fb2969a3SJohan Hedberg 	return 0;
3292fb2969a3SJohan Hedberg }
3293fb2969a3SJohan Hedberg 
3294fb2969a3SJohan Hedberg static int __init test_f6(struct crypto_hash *tfm_cmac)
3295fb2969a3SJohan Hedberg {
3296fb2969a3SJohan Hedberg 	const u8 w[16] = {
3297fb2969a3SJohan Hedberg 			0x20, 0x6e, 0x63, 0xce, 0x20, 0x6a, 0x3f, 0xfd,
3298fb2969a3SJohan Hedberg 			0x02, 0x4a, 0x08, 0xa1, 0x76, 0xf1, 0x65, 0x29 };
3299fb2969a3SJohan Hedberg 	const u8 n1[16] = {
3300fb2969a3SJohan Hedberg 			0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff,
3301fb2969a3SJohan Hedberg 			0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 };
3302fb2969a3SJohan Hedberg 	const u8 n2[16] = {
3303fb2969a3SJohan Hedberg 			0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21,
3304fb2969a3SJohan Hedberg 			0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6 };
3305fb2969a3SJohan Hedberg 	const u8 r[16] = {
3306fb2969a3SJohan Hedberg 			0xc8, 0x0f, 0x2d, 0x0c, 0xd2, 0x42, 0xda, 0x08,
3307fb2969a3SJohan Hedberg 			0x54, 0xbb, 0x53, 0xb4, 0x3b, 0x34, 0xa3, 0x12 };
3308fb2969a3SJohan Hedberg 	const u8 io_cap[3] = { 0x02, 0x01, 0x01 };
3309fb2969a3SJohan Hedberg 	const u8 a1[7] = { 0xce, 0xbf, 0x37, 0x37, 0x12, 0x56, 0x00 };
3310fb2969a3SJohan Hedberg 	const u8 a2[7] = { 0xc1, 0xcf, 0x2d, 0x70, 0x13, 0xa7, 0x00 };
3311fb2969a3SJohan Hedberg 	const u8 exp[16] = {
3312fb2969a3SJohan Hedberg 			0x61, 0x8f, 0x95, 0xda, 0x09, 0x0b, 0x6c, 0xd2,
3313fb2969a3SJohan Hedberg 			0xc5, 0xe8, 0xd0, 0x9c, 0x98, 0x73, 0xc4, 0xe3 };
3314fb2969a3SJohan Hedberg 	u8 res[16];
3315fb2969a3SJohan Hedberg 	int err;
3316fb2969a3SJohan Hedberg 
3317fb2969a3SJohan Hedberg 	err = smp_f6(tfm_cmac, w, n1, n2, r, io_cap, a1, a2, res);
3318fb2969a3SJohan Hedberg 	if (err)
3319fb2969a3SJohan Hedberg 		return err;
3320fb2969a3SJohan Hedberg 
3321fb2969a3SJohan Hedberg 	if (memcmp(res, exp, 16))
3322fb2969a3SJohan Hedberg 		return -EINVAL;
3323fb2969a3SJohan Hedberg 
3324fb2969a3SJohan Hedberg 	return 0;
3325fb2969a3SJohan Hedberg }
3326fb2969a3SJohan Hedberg 
3327fb2969a3SJohan Hedberg static int __init test_g2(struct crypto_hash *tfm_cmac)
3328fb2969a3SJohan Hedberg {
3329fb2969a3SJohan Hedberg 	const u8 u[32] = {
3330fb2969a3SJohan Hedberg 			0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc,
3331fb2969a3SJohan Hedberg 			0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef,
3332fb2969a3SJohan Hedberg 			0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e,
3333fb2969a3SJohan Hedberg 			0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20 };
3334fb2969a3SJohan Hedberg 	const u8 v[32] = {
3335fb2969a3SJohan Hedberg 			0xfd, 0xc5, 0x7f, 0xf4, 0x49, 0xdd, 0x4f, 0x6b,
3336fb2969a3SJohan Hedberg 			0xfb, 0x7c, 0x9d, 0xf1, 0xc2, 0x9a, 0xcb, 0x59,
3337fb2969a3SJohan Hedberg 			0x2a, 0xe7, 0xd4, 0xee, 0xfb, 0xfc, 0x0a, 0x90,
3338fb2969a3SJohan Hedberg 			0x9a, 0xbb, 0xf6, 0x32, 0x3d, 0x8b, 0x18, 0x55 };
3339fb2969a3SJohan Hedberg 	const u8 x[16] = {
3340fb2969a3SJohan Hedberg 			0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff,
3341fb2969a3SJohan Hedberg 			0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 };
3342fb2969a3SJohan Hedberg 	const u8 y[16] = {
3343fb2969a3SJohan Hedberg 			0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21,
3344fb2969a3SJohan Hedberg 			0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6 };
3345fb2969a3SJohan Hedberg 	const u32 exp_val = 0x2f9ed5ba % 1000000;
3346fb2969a3SJohan Hedberg 	u32 val;
3347fb2969a3SJohan Hedberg 	int err;
3348fb2969a3SJohan Hedberg 
3349fb2969a3SJohan Hedberg 	err = smp_g2(tfm_cmac, u, v, x, y, &val);
3350fb2969a3SJohan Hedberg 	if (err)
3351fb2969a3SJohan Hedberg 		return err;
3352fb2969a3SJohan Hedberg 
3353fb2969a3SJohan Hedberg 	if (val != exp_val)
3354fb2969a3SJohan Hedberg 		return -EINVAL;
3355fb2969a3SJohan Hedberg 
3356fb2969a3SJohan Hedberg 	return 0;
3357fb2969a3SJohan Hedberg }
3358fb2969a3SJohan Hedberg 
3359fb2969a3SJohan Hedberg static int __init test_h6(struct crypto_hash *tfm_cmac)
3360fb2969a3SJohan Hedberg {
3361fb2969a3SJohan Hedberg 	const u8 w[16] = {
3362fb2969a3SJohan Hedberg 			0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34,
3363fb2969a3SJohan Hedberg 			0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec };
3364fb2969a3SJohan Hedberg 	const u8 key_id[4] = { 0x72, 0x62, 0x65, 0x6c };
3365fb2969a3SJohan Hedberg 	const u8 exp[16] = {
3366fb2969a3SJohan Hedberg 			0x99, 0x63, 0xb1, 0x80, 0xe2, 0xa9, 0xd3, 0xe8,
3367fb2969a3SJohan Hedberg 			0x1c, 0xc9, 0x6d, 0xe7, 0x02, 0xe1, 0x9a, 0x2d };
3368fb2969a3SJohan Hedberg 	u8 res[16];
3369fb2969a3SJohan Hedberg 	int err;
3370fb2969a3SJohan Hedberg 
3371fb2969a3SJohan Hedberg 	err = smp_h6(tfm_cmac, w, key_id, res);
3372fb2969a3SJohan Hedberg 	if (err)
3373fb2969a3SJohan Hedberg 		return err;
3374fb2969a3SJohan Hedberg 
3375fb2969a3SJohan Hedberg 	if (memcmp(res, exp, 16))
3376fb2969a3SJohan Hedberg 		return -EINVAL;
3377fb2969a3SJohan Hedberg 
3378fb2969a3SJohan Hedberg 	return 0;
3379fb2969a3SJohan Hedberg }
3380fb2969a3SJohan Hedberg 
33810a2b0f04SJohan Hedberg static int __init run_selftests(struct crypto_blkcipher *tfm_aes,
33820a2b0f04SJohan Hedberg 				struct crypto_hash *tfm_cmac)
33830a2b0f04SJohan Hedberg {
3384255047b0SMarcel Holtmann 	ktime_t calltime, delta, rettime;
3385255047b0SMarcel Holtmann 	unsigned long long duration;
3386cfc4198eSJohan Hedberg 	int err;
3387cfc4198eSJohan Hedberg 
3388255047b0SMarcel Holtmann 	calltime = ktime_get();
3389255047b0SMarcel Holtmann 
3390cfc4198eSJohan Hedberg 	err = test_ah(tfm_aes);
3391cfc4198eSJohan Hedberg 	if (err) {
3392cfc4198eSJohan Hedberg 		BT_ERR("smp_ah test failed");
3393cfc4198eSJohan Hedberg 		return err;
3394cfc4198eSJohan Hedberg 	}
3395cfc4198eSJohan Hedberg 
3396cfc4198eSJohan Hedberg 	err = test_c1(tfm_aes);
3397cfc4198eSJohan Hedberg 	if (err) {
3398cfc4198eSJohan Hedberg 		BT_ERR("smp_c1 test failed");
3399cfc4198eSJohan Hedberg 		return err;
3400cfc4198eSJohan Hedberg 	}
3401cfc4198eSJohan Hedberg 
3402cfc4198eSJohan Hedberg 	err = test_s1(tfm_aes);
3403cfc4198eSJohan Hedberg 	if (err) {
3404cfc4198eSJohan Hedberg 		BT_ERR("smp_s1 test failed");
3405cfc4198eSJohan Hedberg 		return err;
3406cfc4198eSJohan Hedberg 	}
3407cfc4198eSJohan Hedberg 
3408fb2969a3SJohan Hedberg 	err = test_f4(tfm_cmac);
3409fb2969a3SJohan Hedberg 	if (err) {
3410fb2969a3SJohan Hedberg 		BT_ERR("smp_f4 test failed");
3411fb2969a3SJohan Hedberg 		return err;
3412fb2969a3SJohan Hedberg 	}
3413fb2969a3SJohan Hedberg 
3414fb2969a3SJohan Hedberg 	err = test_f5(tfm_cmac);
3415fb2969a3SJohan Hedberg 	if (err) {
3416fb2969a3SJohan Hedberg 		BT_ERR("smp_f5 test failed");
3417fb2969a3SJohan Hedberg 		return err;
3418fb2969a3SJohan Hedberg 	}
3419fb2969a3SJohan Hedberg 
3420fb2969a3SJohan Hedberg 	err = test_f6(tfm_cmac);
3421fb2969a3SJohan Hedberg 	if (err) {
3422fb2969a3SJohan Hedberg 		BT_ERR("smp_f6 test failed");
3423fb2969a3SJohan Hedberg 		return err;
3424fb2969a3SJohan Hedberg 	}
3425fb2969a3SJohan Hedberg 
3426fb2969a3SJohan Hedberg 	err = test_g2(tfm_cmac);
3427fb2969a3SJohan Hedberg 	if (err) {
3428fb2969a3SJohan Hedberg 		BT_ERR("smp_g2 test failed");
3429fb2969a3SJohan Hedberg 		return err;
3430fb2969a3SJohan Hedberg 	}
3431fb2969a3SJohan Hedberg 
3432fb2969a3SJohan Hedberg 	err = test_h6(tfm_cmac);
3433fb2969a3SJohan Hedberg 	if (err) {
3434fb2969a3SJohan Hedberg 		BT_ERR("smp_h6 test failed");
3435fb2969a3SJohan Hedberg 		return err;
3436fb2969a3SJohan Hedberg 	}
3437fb2969a3SJohan Hedberg 
3438255047b0SMarcel Holtmann 	rettime = ktime_get();
3439255047b0SMarcel Holtmann 	delta = ktime_sub(rettime, calltime);
3440255047b0SMarcel Holtmann 	duration = (unsigned long long) ktime_to_ns(delta) >> 10;
3441255047b0SMarcel Holtmann 
34425ced2464SMarcel Holtmann 	BT_INFO("SMP test passed in %llu usecs", duration);
34430a2b0f04SJohan Hedberg 
34440a2b0f04SJohan Hedberg 	return 0;
34450a2b0f04SJohan Hedberg }
34460a2b0f04SJohan Hedberg 
34470a2b0f04SJohan Hedberg int __init bt_selftest_smp(void)
34480a2b0f04SJohan Hedberg {
34490a2b0f04SJohan Hedberg 	struct crypto_blkcipher *tfm_aes;
34500a2b0f04SJohan Hedberg 	struct crypto_hash *tfm_cmac;
34510a2b0f04SJohan Hedberg 	int err;
34520a2b0f04SJohan Hedberg 
34530a2b0f04SJohan Hedberg 	tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
34540a2b0f04SJohan Hedberg 	if (IS_ERR(tfm_aes)) {
34550a2b0f04SJohan Hedberg 		BT_ERR("Unable to create ECB crypto context");
34560a2b0f04SJohan Hedberg 		return PTR_ERR(tfm_aes);
34570a2b0f04SJohan Hedberg 	}
34580a2b0f04SJohan Hedberg 
34590a2b0f04SJohan Hedberg 	tfm_cmac = crypto_alloc_hash("cmac(aes)", 0, CRYPTO_ALG_ASYNC);
34600a2b0f04SJohan Hedberg 	if (IS_ERR(tfm_cmac)) {
34610a2b0f04SJohan Hedberg 		BT_ERR("Unable to create CMAC crypto context");
34620a2b0f04SJohan Hedberg 		crypto_free_blkcipher(tfm_aes);
34630a2b0f04SJohan Hedberg 		return PTR_ERR(tfm_cmac);
34640a2b0f04SJohan Hedberg 	}
34650a2b0f04SJohan Hedberg 
34660a2b0f04SJohan Hedberg 	err = run_selftests(tfm_aes, tfm_cmac);
34670a2b0f04SJohan Hedberg 
34680a2b0f04SJohan Hedberg 	crypto_free_hash(tfm_cmac);
34690a2b0f04SJohan Hedberg 	crypto_free_blkcipher(tfm_aes);
34700a2b0f04SJohan Hedberg 
34710a2b0f04SJohan Hedberg 	return err;
34720a2b0f04SJohan Hedberg }
34730a2b0f04SJohan Hedberg 
34740a2b0f04SJohan Hedberg #endif
3475