xref: /openbmc/linux/net/bluetooth/smp.c (revision 2fd36558)
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 
362fd36558SJohan Hedberg #define SMP_DEV(hdev) \
372fd36558SJohan Hedberg 	((struct smp_dev *)((struct l2cap_chan *)((hdev)->smp_data))->data)
382fd36558SJohan Hedberg 
39c7a3d57dSJohan Hedberg /* Low-level debug macros to be used for stuff that we don't want
40c7a3d57dSJohan Hedberg  * accidentially in dmesg, i.e. the values of the various crypto keys
41c7a3d57dSJohan Hedberg  * and the inputs & outputs of crypto functions.
42c7a3d57dSJohan Hedberg  */
43c7a3d57dSJohan Hedberg #ifdef DEBUG
44c7a3d57dSJohan Hedberg #define SMP_DBG(fmt, ...) printk(KERN_DEBUG "%s: " fmt, __func__, \
45c7a3d57dSJohan Hedberg 				 ##__VA_ARGS__)
46c7a3d57dSJohan Hedberg #else
47c7a3d57dSJohan Hedberg #define SMP_DBG(fmt, ...) no_printk(KERN_DEBUG "%s: " fmt, __func__, \
48c7a3d57dSJohan Hedberg 				    ##__VA_ARGS__)
49c7a3d57dSJohan Hedberg #endif
50c7a3d57dSJohan Hedberg 
51b28b4943SJohan Hedberg #define SMP_ALLOW_CMD(smp, code)	set_bit(code, &smp->allow_cmd)
52b28b4943SJohan Hedberg 
533b19146dSJohan Hedberg /* Keys which are not distributed with Secure Connections */
543b19146dSJohan Hedberg #define SMP_SC_NO_DIST (SMP_DIST_ENC_KEY | SMP_DIST_LINK_KEY);
553b19146dSJohan Hedberg 
5617b02e62SMarcel Holtmann #define SMP_TIMEOUT	msecs_to_jiffies(30000)
575d3de7dfSVinicius Costa Gomes 
58d7a5a11dSMarcel Holtmann #define AUTH_REQ_MASK(dev)	(hci_dev_test_flag(dev, HCI_SC_ENABLED) ? \
590edb14deSJohan Hedberg 				 0x1f : 0x07)
6088d3a8acSJohan Hedberg #define KEY_DIST_MASK		0x07
61065a13e2SJohan Hedberg 
62cbbbe3e2SJohan Hedberg /* Maximum message length that can be passed to aes_cmac */
63cbbbe3e2SJohan Hedberg #define CMAC_MSG_MAX	80
64cbbbe3e2SJohan Hedberg 
65533e35d4SJohan Hedberg enum {
66533e35d4SJohan Hedberg 	SMP_FLAG_TK_VALID,
67533e35d4SJohan Hedberg 	SMP_FLAG_CFM_PENDING,
68533e35d4SJohan Hedberg 	SMP_FLAG_MITM_AUTH,
69533e35d4SJohan Hedberg 	SMP_FLAG_COMPLETE,
70533e35d4SJohan Hedberg 	SMP_FLAG_INITIATOR,
7165668776SJohan Hedberg 	SMP_FLAG_SC,
72d8f8edbeSJohan Hedberg 	SMP_FLAG_REMOTE_PK,
73aeb7d461SJohan Hedberg 	SMP_FLAG_DEBUG_KEY,
7438606f14SJohan Hedberg 	SMP_FLAG_WAIT_USER,
75d3e54a87SJohan Hedberg 	SMP_FLAG_DHKEY_PENDING,
761a8bab4fSJohan Hedberg 	SMP_FLAG_REMOTE_OOB,
771a8bab4fSJohan Hedberg 	SMP_FLAG_LOCAL_OOB,
78533e35d4SJohan Hedberg };
794bc58f51SJohan Hedberg 
8088a479d9SMarcel Holtmann struct smp_dev {
8160a27d65SMarcel Holtmann 	/* Secure Connections OOB data */
8260a27d65SMarcel Holtmann 	u8			local_pk[64];
8360a27d65SMarcel Holtmann 	u8			local_sk[32];
84fb334feeSMarcel Holtmann 	u8			local_rand[16];
8560a27d65SMarcel Holtmann 	bool			debug_key;
8660a27d65SMarcel Holtmann 
872fd36558SJohan Hedberg 	u8			max_key_size;
882fd36558SJohan Hedberg 
8988a479d9SMarcel Holtmann 	struct crypto_blkcipher	*tfm_aes;
906e2dc6d1SMarcel Holtmann 	struct crypto_hash	*tfm_cmac;
9188a479d9SMarcel Holtmann };
9288a479d9SMarcel Holtmann 
934bc58f51SJohan Hedberg struct smp_chan {
944bc58f51SJohan Hedberg 	struct l2cap_conn	*conn;
95b68fda68SJohan Hedberg 	struct delayed_work	security_timer;
96b28b4943SJohan Hedberg 	unsigned long           allow_cmd; /* Bitmask of allowed commands */
97b68fda68SJohan Hedberg 
984bc58f51SJohan Hedberg 	u8		preq[7]; /* SMP Pairing Request */
994bc58f51SJohan Hedberg 	u8		prsp[7]; /* SMP Pairing Response */
1004bc58f51SJohan Hedberg 	u8		prnd[16]; /* SMP Pairing Random (local) */
1014bc58f51SJohan Hedberg 	u8		rrnd[16]; /* SMP Pairing Random (remote) */
1024bc58f51SJohan Hedberg 	u8		pcnf[16]; /* SMP Pairing Confirm */
1034bc58f51SJohan Hedberg 	u8		tk[16]; /* SMP Temporary Key */
104882fafadSJohan Hedberg 	u8		rr[16]; /* Remote OOB ra/rb value */
105882fafadSJohan Hedberg 	u8		lr[16]; /* Local OOB ra/rb value */
1064bc58f51SJohan Hedberg 	u8		enc_key_size;
1074bc58f51SJohan Hedberg 	u8		remote_key_dist;
1084bc58f51SJohan Hedberg 	bdaddr_t	id_addr;
1094bc58f51SJohan Hedberg 	u8		id_addr_type;
1104bc58f51SJohan Hedberg 	u8		irk[16];
1114bc58f51SJohan Hedberg 	struct smp_csrk	*csrk;
1124bc58f51SJohan Hedberg 	struct smp_csrk	*slave_csrk;
1134bc58f51SJohan Hedberg 	struct smp_ltk	*ltk;
1144bc58f51SJohan Hedberg 	struct smp_ltk	*slave_ltk;
1154bc58f51SJohan Hedberg 	struct smp_irk	*remote_irk;
1166a77083aSJohan Hedberg 	u8		*link_key;
1174a74d658SJohan Hedberg 	unsigned long	flags;
118783e0574SJohan Hedberg 	u8		method;
11938606f14SJohan Hedberg 	u8		passkey_round;
1206a7bd103SJohan Hedberg 
1213b19146dSJohan Hedberg 	/* Secure Connections variables */
1223b19146dSJohan Hedberg 	u8			local_pk[64];
1233b19146dSJohan Hedberg 	u8			local_sk[32];
124d8f8edbeSJohan Hedberg 	u8			remote_pk[64];
125d8f8edbeSJohan Hedberg 	u8			dhkey[32];
126760b018bSJohan Hedberg 	u8			mackey[16];
1273b19146dSJohan Hedberg 
1286a7bd103SJohan Hedberg 	struct crypto_blkcipher	*tfm_aes;
129407cecf6SJohan Hedberg 	struct crypto_hash	*tfm_cmac;
1304bc58f51SJohan Hedberg };
1314bc58f51SJohan Hedberg 
132aeb7d461SJohan Hedberg /* These debug key values are defined in the SMP section of the core
133aeb7d461SJohan Hedberg  * specification. debug_pk is the public debug key and debug_sk the
134aeb7d461SJohan Hedberg  * private debug key.
135aeb7d461SJohan Hedberg  */
136aeb7d461SJohan Hedberg static const u8 debug_pk[64] = {
137aeb7d461SJohan Hedberg 		0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc,
138aeb7d461SJohan Hedberg 		0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef,
139aeb7d461SJohan Hedberg 		0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e,
140aeb7d461SJohan Hedberg 		0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20,
141aeb7d461SJohan Hedberg 
142aeb7d461SJohan Hedberg 		0x8b, 0xd2, 0x89, 0x15, 0xd0, 0x8e, 0x1c, 0x74,
143aeb7d461SJohan Hedberg 		0x24, 0x30, 0xed, 0x8f, 0xc2, 0x45, 0x63, 0x76,
144aeb7d461SJohan Hedberg 		0x5c, 0x15, 0x52, 0x5a, 0xbf, 0x9a, 0x32, 0x63,
145aeb7d461SJohan Hedberg 		0x6d, 0xeb, 0x2a, 0x65, 0x49, 0x9c, 0x80, 0xdc,
146aeb7d461SJohan Hedberg };
147aeb7d461SJohan Hedberg 
148aeb7d461SJohan Hedberg static const u8 debug_sk[32] = {
149aeb7d461SJohan Hedberg 		0xbd, 0x1a, 0x3c, 0xcd, 0xa6, 0xb8, 0x99, 0x58,
150aeb7d461SJohan Hedberg 		0x99, 0xb7, 0x40, 0xeb, 0x7b, 0x60, 0xff, 0x4a,
151aeb7d461SJohan Hedberg 		0x50, 0x3f, 0x10, 0xd2, 0xe3, 0xb3, 0xc9, 0x74,
152aeb7d461SJohan Hedberg 		0x38, 0x5f, 0xc5, 0xa3, 0xd4, 0xf6, 0x49, 0x3f,
153aeb7d461SJohan Hedberg };
154aeb7d461SJohan Hedberg 
1558a2936f4SJohan Hedberg static inline void swap_buf(const u8 *src, u8 *dst, size_t len)
156d22ef0bcSAnderson Briglia {
1578a2936f4SJohan Hedberg 	size_t i;
158d22ef0bcSAnderson Briglia 
1598a2936f4SJohan Hedberg 	for (i = 0; i < len; i++)
1608a2936f4SJohan Hedberg 		dst[len - 1 - i] = src[i];
161d22ef0bcSAnderson Briglia }
162d22ef0bcSAnderson Briglia 
16306edf8deSJohan Hedberg /* The following functions map to the LE SC SMP crypto functions
16406edf8deSJohan Hedberg  * AES-CMAC, f4, f5, f6, g2 and h6.
16506edf8deSJohan Hedberg  */
16606edf8deSJohan Hedberg 
167cbbbe3e2SJohan Hedberg static int aes_cmac(struct crypto_hash *tfm, const u8 k[16], const u8 *m,
168cbbbe3e2SJohan Hedberg 		    size_t len, u8 mac[16])
169cbbbe3e2SJohan Hedberg {
170cbbbe3e2SJohan Hedberg 	uint8_t tmp[16], mac_msb[16], msg_msb[CMAC_MSG_MAX];
171cbbbe3e2SJohan Hedberg 	struct hash_desc desc;
172cbbbe3e2SJohan Hedberg 	struct scatterlist sg;
173cbbbe3e2SJohan Hedberg 	int err;
174cbbbe3e2SJohan Hedberg 
175cbbbe3e2SJohan Hedberg 	if (len > CMAC_MSG_MAX)
176cbbbe3e2SJohan Hedberg 		return -EFBIG;
177cbbbe3e2SJohan Hedberg 
178cbbbe3e2SJohan Hedberg 	if (!tfm) {
179cbbbe3e2SJohan Hedberg 		BT_ERR("tfm %p", tfm);
180cbbbe3e2SJohan Hedberg 		return -EINVAL;
181cbbbe3e2SJohan Hedberg 	}
182cbbbe3e2SJohan Hedberg 
183cbbbe3e2SJohan Hedberg 	desc.tfm = tfm;
184cbbbe3e2SJohan Hedberg 	desc.flags = 0;
185cbbbe3e2SJohan Hedberg 
186cbbbe3e2SJohan Hedberg 	crypto_hash_init(&desc);
187cbbbe3e2SJohan Hedberg 
188cbbbe3e2SJohan Hedberg 	/* Swap key and message from LSB to MSB */
189cbbbe3e2SJohan Hedberg 	swap_buf(k, tmp, 16);
190cbbbe3e2SJohan Hedberg 	swap_buf(m, msg_msb, len);
191cbbbe3e2SJohan Hedberg 
192c7a3d57dSJohan Hedberg 	SMP_DBG("msg (len %zu) %*phN", len, (int) len, m);
193c7a3d57dSJohan Hedberg 	SMP_DBG("key %16phN", k);
194cbbbe3e2SJohan Hedberg 
195cbbbe3e2SJohan Hedberg 	err = crypto_hash_setkey(tfm, tmp, 16);
196cbbbe3e2SJohan Hedberg 	if (err) {
197cbbbe3e2SJohan Hedberg 		BT_ERR("cipher setkey failed: %d", err);
198cbbbe3e2SJohan Hedberg 		return err;
199cbbbe3e2SJohan Hedberg 	}
200cbbbe3e2SJohan Hedberg 
201cbbbe3e2SJohan Hedberg 	sg_init_one(&sg, msg_msb, len);
202cbbbe3e2SJohan Hedberg 
203cbbbe3e2SJohan Hedberg 	err = crypto_hash_update(&desc, &sg, len);
204cbbbe3e2SJohan Hedberg 	if (err) {
205cbbbe3e2SJohan Hedberg 		BT_ERR("Hash update error %d", err);
206cbbbe3e2SJohan Hedberg 		return err;
207cbbbe3e2SJohan Hedberg 	}
208cbbbe3e2SJohan Hedberg 
209cbbbe3e2SJohan Hedberg 	err = crypto_hash_final(&desc, mac_msb);
210cbbbe3e2SJohan Hedberg 	if (err) {
211cbbbe3e2SJohan Hedberg 		BT_ERR("Hash final error %d", err);
212cbbbe3e2SJohan Hedberg 		return err;
213cbbbe3e2SJohan Hedberg 	}
214cbbbe3e2SJohan Hedberg 
215cbbbe3e2SJohan Hedberg 	swap_buf(mac_msb, mac, 16);
216cbbbe3e2SJohan Hedberg 
217c7a3d57dSJohan Hedberg 	SMP_DBG("mac %16phN", mac);
218cbbbe3e2SJohan Hedberg 
219cbbbe3e2SJohan Hedberg 	return 0;
220cbbbe3e2SJohan Hedberg }
221cbbbe3e2SJohan Hedberg 
222cbbbe3e2SJohan Hedberg static int smp_f4(struct crypto_hash *tfm_cmac, const u8 u[32], const u8 v[32],
223cbbbe3e2SJohan Hedberg 		  const u8 x[16], u8 z, u8 res[16])
224cbbbe3e2SJohan Hedberg {
225cbbbe3e2SJohan Hedberg 	u8 m[65];
226cbbbe3e2SJohan Hedberg 	int err;
227cbbbe3e2SJohan Hedberg 
228c7a3d57dSJohan Hedberg 	SMP_DBG("u %32phN", u);
229c7a3d57dSJohan Hedberg 	SMP_DBG("v %32phN", v);
230c7a3d57dSJohan Hedberg 	SMP_DBG("x %16phN z %02x", x, z);
231cbbbe3e2SJohan Hedberg 
232cbbbe3e2SJohan Hedberg 	m[0] = z;
233cbbbe3e2SJohan Hedberg 	memcpy(m + 1, v, 32);
234cbbbe3e2SJohan Hedberg 	memcpy(m + 33, u, 32);
235cbbbe3e2SJohan Hedberg 
236cbbbe3e2SJohan Hedberg 	err = aes_cmac(tfm_cmac, x, m, sizeof(m), res);
237cbbbe3e2SJohan Hedberg 	if (err)
238cbbbe3e2SJohan Hedberg 		return err;
239cbbbe3e2SJohan Hedberg 
240c7a3d57dSJohan Hedberg 	SMP_DBG("res %16phN", res);
241cbbbe3e2SJohan Hedberg 
242cbbbe3e2SJohan Hedberg 	return err;
243cbbbe3e2SJohan Hedberg }
244cbbbe3e2SJohan Hedberg 
2454da50de8SJohan Hedberg static int smp_f5(struct crypto_hash *tfm_cmac, const u8 w[32],
2464da50de8SJohan Hedberg 		  const u8 n1[16], const u8 n2[16], const u8 a1[7],
2474da50de8SJohan Hedberg 		  const u8 a2[7], u8 mackey[16], u8 ltk[16])
248760b018bSJohan Hedberg {
249760b018bSJohan Hedberg 	/* The btle, salt and length "magic" values are as defined in
250760b018bSJohan Hedberg 	 * the SMP section of the Bluetooth core specification. In ASCII
251760b018bSJohan Hedberg 	 * the btle value ends up being 'btle'. The salt is just a
252760b018bSJohan Hedberg 	 * random number whereas length is the value 256 in little
253760b018bSJohan Hedberg 	 * endian format.
254760b018bSJohan Hedberg 	 */
255760b018bSJohan Hedberg 	const u8 btle[4] = { 0x65, 0x6c, 0x74, 0x62 };
256760b018bSJohan Hedberg 	const u8 salt[16] = { 0xbe, 0x83, 0x60, 0x5a, 0xdb, 0x0b, 0x37, 0x60,
257760b018bSJohan Hedberg 			      0x38, 0xa5, 0xf5, 0xaa, 0x91, 0x83, 0x88, 0x6c };
258760b018bSJohan Hedberg 	const u8 length[2] = { 0x00, 0x01 };
259760b018bSJohan Hedberg 	u8 m[53], t[16];
260760b018bSJohan Hedberg 	int err;
261760b018bSJohan Hedberg 
262c7a3d57dSJohan Hedberg 	SMP_DBG("w %32phN", w);
263c7a3d57dSJohan Hedberg 	SMP_DBG("n1 %16phN n2 %16phN", n1, n2);
264c7a3d57dSJohan Hedberg 	SMP_DBG("a1 %7phN a2 %7phN", a1, a2);
265760b018bSJohan Hedberg 
266760b018bSJohan Hedberg 	err = aes_cmac(tfm_cmac, salt, w, 32, t);
267760b018bSJohan Hedberg 	if (err)
268760b018bSJohan Hedberg 		return err;
269760b018bSJohan Hedberg 
270c7a3d57dSJohan Hedberg 	SMP_DBG("t %16phN", t);
271760b018bSJohan Hedberg 
272760b018bSJohan Hedberg 	memcpy(m, length, 2);
273760b018bSJohan Hedberg 	memcpy(m + 2, a2, 7);
274760b018bSJohan Hedberg 	memcpy(m + 9, a1, 7);
275760b018bSJohan Hedberg 	memcpy(m + 16, n2, 16);
276760b018bSJohan Hedberg 	memcpy(m + 32, n1, 16);
277760b018bSJohan Hedberg 	memcpy(m + 48, btle, 4);
278760b018bSJohan Hedberg 
279760b018bSJohan Hedberg 	m[52] = 0; /* Counter */
280760b018bSJohan Hedberg 
281760b018bSJohan Hedberg 	err = aes_cmac(tfm_cmac, t, m, sizeof(m), mackey);
282760b018bSJohan Hedberg 	if (err)
283760b018bSJohan Hedberg 		return err;
284760b018bSJohan Hedberg 
285c7a3d57dSJohan Hedberg 	SMP_DBG("mackey %16phN", mackey);
286760b018bSJohan Hedberg 
287760b018bSJohan Hedberg 	m[52] = 1; /* Counter */
288760b018bSJohan Hedberg 
289760b018bSJohan Hedberg 	err = aes_cmac(tfm_cmac, t, m, sizeof(m), ltk);
290760b018bSJohan Hedberg 	if (err)
291760b018bSJohan Hedberg 		return err;
292760b018bSJohan Hedberg 
293c7a3d57dSJohan Hedberg 	SMP_DBG("ltk %16phN", ltk);
294760b018bSJohan Hedberg 
295760b018bSJohan Hedberg 	return 0;
296760b018bSJohan Hedberg }
297760b018bSJohan Hedberg 
298760b018bSJohan Hedberg static int smp_f6(struct crypto_hash *tfm_cmac, const u8 w[16],
2994da50de8SJohan Hedberg 		  const u8 n1[16], const u8 n2[16], const u8 r[16],
300760b018bSJohan Hedberg 		  const u8 io_cap[3], const u8 a1[7], const u8 a2[7],
301760b018bSJohan Hedberg 		  u8 res[16])
302760b018bSJohan Hedberg {
303760b018bSJohan Hedberg 	u8 m[65];
304760b018bSJohan Hedberg 	int err;
305760b018bSJohan Hedberg 
306c7a3d57dSJohan Hedberg 	SMP_DBG("w %16phN", w);
307c7a3d57dSJohan Hedberg 	SMP_DBG("n1 %16phN n2 %16phN", n1, n2);
308c7a3d57dSJohan Hedberg 	SMP_DBG("r %16phN io_cap %3phN a1 %7phN a2 %7phN", r, io_cap, a1, a2);
309760b018bSJohan Hedberg 
310760b018bSJohan Hedberg 	memcpy(m, a2, 7);
311760b018bSJohan Hedberg 	memcpy(m + 7, a1, 7);
312760b018bSJohan Hedberg 	memcpy(m + 14, io_cap, 3);
313760b018bSJohan Hedberg 	memcpy(m + 17, r, 16);
314760b018bSJohan Hedberg 	memcpy(m + 33, n2, 16);
315760b018bSJohan Hedberg 	memcpy(m + 49, n1, 16);
316760b018bSJohan Hedberg 
317760b018bSJohan Hedberg 	err = aes_cmac(tfm_cmac, w, m, sizeof(m), res);
318760b018bSJohan Hedberg 	if (err)
319760b018bSJohan Hedberg 		return err;
320760b018bSJohan Hedberg 
321203de21bSMarcel Holtmann 	SMP_DBG("res %16phN", res);
322760b018bSJohan Hedberg 
323760b018bSJohan Hedberg 	return err;
324760b018bSJohan Hedberg }
325760b018bSJohan Hedberg 
326191dc7feSJohan Hedberg static int smp_g2(struct crypto_hash *tfm_cmac, const u8 u[32], const u8 v[32],
327191dc7feSJohan Hedberg 		  const u8 x[16], const u8 y[16], u32 *val)
328191dc7feSJohan Hedberg {
329191dc7feSJohan Hedberg 	u8 m[80], tmp[16];
330191dc7feSJohan Hedberg 	int err;
331191dc7feSJohan Hedberg 
332c7a3d57dSJohan Hedberg 	SMP_DBG("u %32phN", u);
333c7a3d57dSJohan Hedberg 	SMP_DBG("v %32phN", v);
334c7a3d57dSJohan Hedberg 	SMP_DBG("x %16phN y %16phN", x, y);
335191dc7feSJohan Hedberg 
336191dc7feSJohan Hedberg 	memcpy(m, y, 16);
337191dc7feSJohan Hedberg 	memcpy(m + 16, v, 32);
338191dc7feSJohan Hedberg 	memcpy(m + 48, u, 32);
339191dc7feSJohan Hedberg 
340191dc7feSJohan Hedberg 	err = aes_cmac(tfm_cmac, x, m, sizeof(m), tmp);
341191dc7feSJohan Hedberg 	if (err)
342191dc7feSJohan Hedberg 		return err;
343191dc7feSJohan Hedberg 
344191dc7feSJohan Hedberg 	*val = get_unaligned_le32(tmp);
345191dc7feSJohan Hedberg 	*val %= 1000000;
346191dc7feSJohan Hedberg 
347c7a3d57dSJohan Hedberg 	SMP_DBG("val %06u", *val);
348191dc7feSJohan Hedberg 
349191dc7feSJohan Hedberg 	return 0;
350191dc7feSJohan Hedberg }
351191dc7feSJohan Hedberg 
35206edf8deSJohan Hedberg static int smp_h6(struct crypto_hash *tfm_cmac, const u8 w[16],
35306edf8deSJohan Hedberg 		  const u8 key_id[4], u8 res[16])
35406edf8deSJohan Hedberg {
35506edf8deSJohan Hedberg 	int err;
35606edf8deSJohan Hedberg 
35706edf8deSJohan Hedberg 	SMP_DBG("w %16phN key_id %4phN", w, key_id);
35806edf8deSJohan Hedberg 
35906edf8deSJohan Hedberg 	err = aes_cmac(tfm_cmac, w, key_id, 4, res);
36006edf8deSJohan Hedberg 	if (err)
36106edf8deSJohan Hedberg 		return err;
36206edf8deSJohan Hedberg 
36306edf8deSJohan Hedberg 	SMP_DBG("res %16phN", res);
36406edf8deSJohan Hedberg 
36506edf8deSJohan Hedberg 	return err;
36606edf8deSJohan Hedberg }
36706edf8deSJohan Hedberg 
36806edf8deSJohan Hedberg /* The following functions map to the legacy SMP crypto functions e, c1,
36906edf8deSJohan Hedberg  * s1 and ah.
37006edf8deSJohan Hedberg  */
37106edf8deSJohan Hedberg 
372d22ef0bcSAnderson Briglia static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
373d22ef0bcSAnderson Briglia {
374d22ef0bcSAnderson Briglia 	struct blkcipher_desc desc;
375d22ef0bcSAnderson Briglia 	struct scatterlist sg;
376943a732aSJohan Hedberg 	uint8_t tmp[16], data[16];
377201a5929SJohan Hedberg 	int err;
378d22ef0bcSAnderson Briglia 
379011c391aSJohan Hedberg 	SMP_DBG("k %16phN r %16phN", k, r);
380011c391aSJohan Hedberg 
3817f376cd6SJohan Hedberg 	if (!tfm) {
382d22ef0bcSAnderson Briglia 		BT_ERR("tfm %p", tfm);
383d22ef0bcSAnderson Briglia 		return -EINVAL;
384d22ef0bcSAnderson Briglia 	}
385d22ef0bcSAnderson Briglia 
386d22ef0bcSAnderson Briglia 	desc.tfm = tfm;
387d22ef0bcSAnderson Briglia 	desc.flags = 0;
388d22ef0bcSAnderson Briglia 
389943a732aSJohan Hedberg 	/* The most significant octet of key corresponds to k[0] */
3908a2936f4SJohan Hedberg 	swap_buf(k, tmp, 16);
391943a732aSJohan Hedberg 
392943a732aSJohan Hedberg 	err = crypto_blkcipher_setkey(tfm, tmp, 16);
393d22ef0bcSAnderson Briglia 	if (err) {
394d22ef0bcSAnderson Briglia 		BT_ERR("cipher setkey failed: %d", err);
395d22ef0bcSAnderson Briglia 		return err;
396d22ef0bcSAnderson Briglia 	}
397d22ef0bcSAnderson Briglia 
398943a732aSJohan Hedberg 	/* Most significant octet of plaintextData corresponds to data[0] */
3998a2936f4SJohan Hedberg 	swap_buf(r, data, 16);
400943a732aSJohan Hedberg 
401943a732aSJohan Hedberg 	sg_init_one(&sg, data, 16);
402d22ef0bcSAnderson Briglia 
403d22ef0bcSAnderson Briglia 	err = crypto_blkcipher_encrypt(&desc, &sg, &sg, 16);
404d22ef0bcSAnderson Briglia 	if (err)
405d22ef0bcSAnderson Briglia 		BT_ERR("Encrypt data error %d", err);
406d22ef0bcSAnderson Briglia 
407943a732aSJohan Hedberg 	/* Most significant octet of encryptedData corresponds to data[0] */
4088a2936f4SJohan Hedberg 	swap_buf(data, r, 16);
409943a732aSJohan Hedberg 
410011c391aSJohan Hedberg 	SMP_DBG("r %16phN", r);
411011c391aSJohan Hedberg 
412d22ef0bcSAnderson Briglia 	return err;
413d22ef0bcSAnderson Briglia }
414d22ef0bcSAnderson Briglia 
41506edf8deSJohan Hedberg static int smp_c1(struct crypto_blkcipher *tfm_aes, const u8 k[16],
41606edf8deSJohan Hedberg 		  const u8 r[16], const u8 preq[7], const u8 pres[7], u8 _iat,
41706edf8deSJohan Hedberg 		  const bdaddr_t *ia, u8 _rat, const bdaddr_t *ra, u8 res[16])
41806edf8deSJohan Hedberg {
41906edf8deSJohan Hedberg 	u8 p1[16], p2[16];
42006edf8deSJohan Hedberg 	int err;
42106edf8deSJohan Hedberg 
422011c391aSJohan Hedberg 	SMP_DBG("k %16phN r %16phN", k, r);
423011c391aSJohan Hedberg 	SMP_DBG("iat %u ia %6phN rat %u ra %6phN", _iat, ia, _rat, ra);
424011c391aSJohan Hedberg 	SMP_DBG("preq %7phN pres %7phN", preq, pres);
425011c391aSJohan Hedberg 
42606edf8deSJohan Hedberg 	memset(p1, 0, 16);
42706edf8deSJohan Hedberg 
42806edf8deSJohan Hedberg 	/* p1 = pres || preq || _rat || _iat */
42906edf8deSJohan Hedberg 	p1[0] = _iat;
43006edf8deSJohan Hedberg 	p1[1] = _rat;
43106edf8deSJohan Hedberg 	memcpy(p1 + 2, preq, 7);
43206edf8deSJohan Hedberg 	memcpy(p1 + 9, pres, 7);
43306edf8deSJohan Hedberg 
434011c391aSJohan Hedberg 	SMP_DBG("p1 %16phN", p1);
43506edf8deSJohan Hedberg 
43606edf8deSJohan Hedberg 	/* res = r XOR p1 */
43706edf8deSJohan Hedberg 	u128_xor((u128 *) res, (u128 *) r, (u128 *) p1);
43806edf8deSJohan Hedberg 
43906edf8deSJohan Hedberg 	/* res = e(k, res) */
44006edf8deSJohan Hedberg 	err = smp_e(tfm_aes, k, res);
44106edf8deSJohan Hedberg 	if (err) {
44206edf8deSJohan Hedberg 		BT_ERR("Encrypt data error");
44306edf8deSJohan Hedberg 		return err;
44406edf8deSJohan Hedberg 	}
44506edf8deSJohan Hedberg 
446011c391aSJohan Hedberg 	/* p2 = padding || ia || ra */
447011c391aSJohan Hedberg 	memcpy(p2, ra, 6);
448011c391aSJohan Hedberg 	memcpy(p2 + 6, ia, 6);
449011c391aSJohan Hedberg 	memset(p2 + 12, 0, 4);
450011c391aSJohan Hedberg 
451011c391aSJohan Hedberg 	SMP_DBG("p2 %16phN", p2);
452011c391aSJohan Hedberg 
45306edf8deSJohan Hedberg 	/* res = res XOR p2 */
45406edf8deSJohan Hedberg 	u128_xor((u128 *) res, (u128 *) res, (u128 *) p2);
45506edf8deSJohan Hedberg 
45606edf8deSJohan Hedberg 	/* res = e(k, res) */
45706edf8deSJohan Hedberg 	err = smp_e(tfm_aes, k, res);
45806edf8deSJohan Hedberg 	if (err)
45906edf8deSJohan Hedberg 		BT_ERR("Encrypt data error");
46006edf8deSJohan Hedberg 
46106edf8deSJohan Hedberg 	return err;
46206edf8deSJohan Hedberg }
46306edf8deSJohan Hedberg 
46406edf8deSJohan Hedberg static int smp_s1(struct crypto_blkcipher *tfm_aes, const u8 k[16],
46506edf8deSJohan Hedberg 		  const u8 r1[16], const u8 r2[16], u8 _r[16])
4666a77083aSJohan Hedberg {
4676a77083aSJohan Hedberg 	int err;
4686a77083aSJohan Hedberg 
46906edf8deSJohan Hedberg 	/* Just least significant octets from r1 and r2 are considered */
47006edf8deSJohan Hedberg 	memcpy(_r, r2, 8);
47106edf8deSJohan Hedberg 	memcpy(_r + 8, r1, 8);
4726a77083aSJohan Hedberg 
47306edf8deSJohan Hedberg 	err = smp_e(tfm_aes, k, _r);
4746a77083aSJohan Hedberg 	if (err)
47506edf8deSJohan Hedberg 		BT_ERR("Encrypt data error");
4766a77083aSJohan Hedberg 
4776a77083aSJohan Hedberg 	return err;
4786a77083aSJohan Hedberg }
4796a77083aSJohan Hedberg 
480cd082797SJohan Hedberg static int smp_ah(struct crypto_blkcipher *tfm, const u8 irk[16],
481cd082797SJohan Hedberg 		  const u8 r[3], u8 res[3])
48260478054SJohan Hedberg {
483943a732aSJohan Hedberg 	u8 _res[16];
48460478054SJohan Hedberg 	int err;
48560478054SJohan Hedberg 
48660478054SJohan Hedberg 	/* r' = padding || r */
487943a732aSJohan Hedberg 	memcpy(_res, r, 3);
488943a732aSJohan Hedberg 	memset(_res + 3, 0, 13);
48960478054SJohan Hedberg 
490943a732aSJohan Hedberg 	err = smp_e(tfm, irk, _res);
49160478054SJohan Hedberg 	if (err) {
49260478054SJohan Hedberg 		BT_ERR("Encrypt error");
49360478054SJohan Hedberg 		return err;
49460478054SJohan Hedberg 	}
49560478054SJohan Hedberg 
49660478054SJohan Hedberg 	/* The output of the random address function ah is:
49760478054SJohan Hedberg 	 *	ah(h, r) = e(k, r') mod 2^24
49860478054SJohan Hedberg 	 * The output of the security function e is then truncated to 24 bits
49960478054SJohan Hedberg 	 * by taking the least significant 24 bits of the output of e as the
50060478054SJohan Hedberg 	 * result of ah.
50160478054SJohan Hedberg 	 */
502943a732aSJohan Hedberg 	memcpy(res, _res, 3);
50360478054SJohan Hedberg 
50460478054SJohan Hedberg 	return 0;
50560478054SJohan Hedberg }
50660478054SJohan Hedberg 
507cd082797SJohan Hedberg bool smp_irk_matches(struct hci_dev *hdev, const u8 irk[16],
508cd082797SJohan Hedberg 		     const bdaddr_t *bdaddr)
50960478054SJohan Hedberg {
510defce9e8SJohan Hedberg 	struct l2cap_chan *chan = hdev->smp_data;
51188a479d9SMarcel Holtmann 	struct smp_dev *smp;
51260478054SJohan Hedberg 	u8 hash[3];
51360478054SJohan Hedberg 	int err;
51460478054SJohan Hedberg 
515defce9e8SJohan Hedberg 	if (!chan || !chan->data)
516defce9e8SJohan Hedberg 		return false;
517defce9e8SJohan Hedberg 
51888a479d9SMarcel Holtmann 	smp = chan->data;
519defce9e8SJohan Hedberg 
52060478054SJohan Hedberg 	BT_DBG("RPA %pMR IRK %*phN", bdaddr, 16, irk);
52160478054SJohan Hedberg 
52288a479d9SMarcel Holtmann 	err = smp_ah(smp->tfm_aes, irk, &bdaddr->b[3], hash);
52360478054SJohan Hedberg 	if (err)
52460478054SJohan Hedberg 		return false;
52560478054SJohan Hedberg 
52660478054SJohan Hedberg 	return !memcmp(bdaddr->b, hash, 3);
52760478054SJohan Hedberg }
52860478054SJohan Hedberg 
529cd082797SJohan Hedberg int smp_generate_rpa(struct hci_dev *hdev, const u8 irk[16], bdaddr_t *rpa)
530b1e2b3aeSJohan Hedberg {
531defce9e8SJohan Hedberg 	struct l2cap_chan *chan = hdev->smp_data;
53288a479d9SMarcel Holtmann 	struct smp_dev *smp;
533b1e2b3aeSJohan Hedberg 	int err;
534b1e2b3aeSJohan Hedberg 
535defce9e8SJohan Hedberg 	if (!chan || !chan->data)
536defce9e8SJohan Hedberg 		return -EOPNOTSUPP;
537defce9e8SJohan Hedberg 
53888a479d9SMarcel Holtmann 	smp = chan->data;
539defce9e8SJohan Hedberg 
540b1e2b3aeSJohan Hedberg 	get_random_bytes(&rpa->b[3], 3);
541b1e2b3aeSJohan Hedberg 
542b1e2b3aeSJohan Hedberg 	rpa->b[5] &= 0x3f;	/* Clear two most significant bits */
543b1e2b3aeSJohan Hedberg 	rpa->b[5] |= 0x40;	/* Set second most significant bit */
544b1e2b3aeSJohan Hedberg 
54588a479d9SMarcel Holtmann 	err = smp_ah(smp->tfm_aes, irk, &rpa->b[3], rpa->b);
546b1e2b3aeSJohan Hedberg 	if (err < 0)
547b1e2b3aeSJohan Hedberg 		return err;
548b1e2b3aeSJohan Hedberg 
549b1e2b3aeSJohan Hedberg 	BT_DBG("RPA %pMR", rpa);
550b1e2b3aeSJohan Hedberg 
551b1e2b3aeSJohan Hedberg 	return 0;
552b1e2b3aeSJohan Hedberg }
553b1e2b3aeSJohan Hedberg 
55460a27d65SMarcel Holtmann int smp_generate_oob(struct hci_dev *hdev, u8 hash[16], u8 rand[16])
55560a27d65SMarcel Holtmann {
55660a27d65SMarcel Holtmann 	struct l2cap_chan *chan = hdev->smp_data;
55760a27d65SMarcel Holtmann 	struct smp_dev *smp;
55860a27d65SMarcel Holtmann 	int err;
55960a27d65SMarcel Holtmann 
56060a27d65SMarcel Holtmann 	if (!chan || !chan->data)
56160a27d65SMarcel Holtmann 		return -EOPNOTSUPP;
56260a27d65SMarcel Holtmann 
56360a27d65SMarcel Holtmann 	smp = chan->data;
56460a27d65SMarcel Holtmann 
56560a27d65SMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS)) {
56660a27d65SMarcel Holtmann 		BT_DBG("Using debug keys");
56760a27d65SMarcel Holtmann 		memcpy(smp->local_pk, debug_pk, 64);
56860a27d65SMarcel Holtmann 		memcpy(smp->local_sk, debug_sk, 32);
56960a27d65SMarcel Holtmann 		smp->debug_key = true;
57060a27d65SMarcel Holtmann 	} else {
57160a27d65SMarcel Holtmann 		while (true) {
57260a27d65SMarcel Holtmann 			/* Generate local key pair for Secure Connections */
57360a27d65SMarcel Holtmann 			if (!ecc_make_key(smp->local_pk, smp->local_sk))
57460a27d65SMarcel Holtmann 				return -EIO;
57560a27d65SMarcel Holtmann 
57660a27d65SMarcel Holtmann 			/* This is unlikely, but we need to check that
57760a27d65SMarcel Holtmann 			 * we didn't accidentially generate a debug key.
57860a27d65SMarcel Holtmann 			 */
57960a27d65SMarcel Holtmann 			if (memcmp(smp->local_sk, debug_sk, 32))
58060a27d65SMarcel Holtmann 				break;
58160a27d65SMarcel Holtmann 		}
58260a27d65SMarcel Holtmann 		smp->debug_key = false;
58360a27d65SMarcel Holtmann 	}
58460a27d65SMarcel Holtmann 
58560a27d65SMarcel Holtmann 	SMP_DBG("OOB Public Key X: %32phN", smp->local_pk);
58660a27d65SMarcel Holtmann 	SMP_DBG("OOB Public Key Y: %32phN", smp->local_pk + 32);
58760a27d65SMarcel Holtmann 	SMP_DBG("OOB Private Key:  %32phN", smp->local_sk);
58860a27d65SMarcel Holtmann 
589fb334feeSMarcel Holtmann 	get_random_bytes(smp->local_rand, 16);
59060a27d65SMarcel Holtmann 
59160a27d65SMarcel Holtmann 	err = smp_f4(smp->tfm_cmac, smp->local_pk, smp->local_pk,
592fb334feeSMarcel Holtmann 		     smp->local_rand, 0, hash);
59360a27d65SMarcel Holtmann 	if (err < 0)
59460a27d65SMarcel Holtmann 		return err;
59560a27d65SMarcel Holtmann 
596fb334feeSMarcel Holtmann 	memcpy(rand, smp->local_rand, 16);
59760a27d65SMarcel Holtmann 
59860a27d65SMarcel Holtmann 	return 0;
59960a27d65SMarcel Holtmann }
60060a27d65SMarcel Holtmann 
601eb492e01SAnderson Briglia static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
602eb492e01SAnderson Briglia {
6035d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
604b68fda68SJohan Hedberg 	struct smp_chan *smp;
6055d88cc73SJohan Hedberg 	struct kvec iv[2];
6065d88cc73SJohan Hedberg 	struct msghdr msg;
6075d88cc73SJohan Hedberg 
6085d88cc73SJohan Hedberg 	if (!chan)
6095d88cc73SJohan Hedberg 		return;
610eb492e01SAnderson Briglia 
611eb492e01SAnderson Briglia 	BT_DBG("code 0x%2.2x", code);
612eb492e01SAnderson Briglia 
6135d88cc73SJohan Hedberg 	iv[0].iov_base = &code;
6145d88cc73SJohan Hedberg 	iv[0].iov_len = 1;
615eb492e01SAnderson Briglia 
6165d88cc73SJohan Hedberg 	iv[1].iov_base = data;
6175d88cc73SJohan Hedberg 	iv[1].iov_len = len;
6185d88cc73SJohan Hedberg 
6195d88cc73SJohan Hedberg 	memset(&msg, 0, sizeof(msg));
6205d88cc73SJohan Hedberg 
62117836394SAl Viro 	iov_iter_kvec(&msg.msg_iter, WRITE | ITER_KVEC, iv, 2, 1 + len);
6225d88cc73SJohan Hedberg 
6235d88cc73SJohan Hedberg 	l2cap_chan_send(chan, &msg, 1 + len);
624e2dcd113SVinicius Costa Gomes 
625b68fda68SJohan Hedberg 	if (!chan->data)
626b68fda68SJohan Hedberg 		return;
627b68fda68SJohan Hedberg 
628b68fda68SJohan Hedberg 	smp = chan->data;
629b68fda68SJohan Hedberg 
630b68fda68SJohan Hedberg 	cancel_delayed_work_sync(&smp->security_timer);
631b68fda68SJohan Hedberg 	schedule_delayed_work(&smp->security_timer, SMP_TIMEOUT);
632eb492e01SAnderson Briglia }
633eb492e01SAnderson Briglia 
634d2eb9e10SJohan Hedberg static u8 authreq_to_seclevel(u8 authreq)
6352b64d153SBrian Gix {
636d2eb9e10SJohan Hedberg 	if (authreq & SMP_AUTH_MITM) {
637d2eb9e10SJohan Hedberg 		if (authreq & SMP_AUTH_SC)
638d2eb9e10SJohan Hedberg 			return BT_SECURITY_FIPS;
6392b64d153SBrian Gix 		else
640d2eb9e10SJohan Hedberg 			return BT_SECURITY_HIGH;
641d2eb9e10SJohan Hedberg 	} else {
6422b64d153SBrian Gix 		return BT_SECURITY_MEDIUM;
6432b64d153SBrian Gix 	}
644d2eb9e10SJohan Hedberg }
6452b64d153SBrian Gix 
6462b64d153SBrian Gix static __u8 seclevel_to_authreq(__u8 sec_level)
6472b64d153SBrian Gix {
6482b64d153SBrian Gix 	switch (sec_level) {
649d2eb9e10SJohan Hedberg 	case BT_SECURITY_FIPS:
6502b64d153SBrian Gix 	case BT_SECURITY_HIGH:
6512b64d153SBrian Gix 		return SMP_AUTH_MITM | SMP_AUTH_BONDING;
6522b64d153SBrian Gix 	case BT_SECURITY_MEDIUM:
6532b64d153SBrian Gix 		return SMP_AUTH_BONDING;
6542b64d153SBrian Gix 	default:
6552b64d153SBrian Gix 		return SMP_AUTH_NONE;
6562b64d153SBrian Gix 	}
6572b64d153SBrian Gix }
6582b64d153SBrian Gix 
659b8e66eacSVinicius Costa Gomes static void build_pairing_cmd(struct l2cap_conn *conn,
66054790f73SVinicius Costa Gomes 			      struct smp_cmd_pairing *req,
661f1560463SMarcel Holtmann 			      struct smp_cmd_pairing *rsp, __u8 authreq)
662b8e66eacSVinicius Costa Gomes {
6635d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
6645d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
665fd349c02SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
666fd349c02SJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
66702b05bd8SJohan Hedberg 	u8 local_dist = 0, remote_dist = 0, oob_flag = SMP_OOB_NOT_PRESENT;
66854790f73SVinicius Costa Gomes 
669d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_BONDABLE)) {
6707ee4ea36SMarcel Holtmann 		local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
6717ee4ea36SMarcel Holtmann 		remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
67254790f73SVinicius Costa Gomes 		authreq |= SMP_AUTH_BONDING;
6732b64d153SBrian Gix 	} else {
6742b64d153SBrian Gix 		authreq &= ~SMP_AUTH_BONDING;
67554790f73SVinicius Costa Gomes 	}
67654790f73SVinicius Costa Gomes 
677d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_RPA_RESOLVING))
678fd349c02SJohan Hedberg 		remote_dist |= SMP_DIST_ID_KEY;
679fd349c02SJohan Hedberg 
680d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_PRIVACY))
681863efaf2SJohan Hedberg 		local_dist |= SMP_DIST_ID_KEY;
682863efaf2SJohan Hedberg 
683d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SC_ENABLED) &&
68402b05bd8SJohan Hedberg 	    (authreq & SMP_AUTH_SC)) {
68502b05bd8SJohan Hedberg 		struct oob_data *oob_data;
68602b05bd8SJohan Hedberg 		u8 bdaddr_type;
68702b05bd8SJohan Hedberg 
688d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_SSP_ENABLED)) {
689df8e1a4cSJohan Hedberg 			local_dist |= SMP_DIST_LINK_KEY;
690df8e1a4cSJohan Hedberg 			remote_dist |= SMP_DIST_LINK_KEY;
691df8e1a4cSJohan Hedberg 		}
69202b05bd8SJohan Hedberg 
69302b05bd8SJohan Hedberg 		if (hcon->dst_type == ADDR_LE_DEV_PUBLIC)
69402b05bd8SJohan Hedberg 			bdaddr_type = BDADDR_LE_PUBLIC;
69502b05bd8SJohan Hedberg 		else
69602b05bd8SJohan Hedberg 			bdaddr_type = BDADDR_LE_RANDOM;
69702b05bd8SJohan Hedberg 
69802b05bd8SJohan Hedberg 		oob_data = hci_find_remote_oob_data(hdev, &hcon->dst,
69902b05bd8SJohan Hedberg 						    bdaddr_type);
7004775a4eaSMarcel Holtmann 		if (oob_data && oob_data->present) {
7011a8bab4fSJohan Hedberg 			set_bit(SMP_FLAG_REMOTE_OOB, &smp->flags);
70202b05bd8SJohan Hedberg 			oob_flag = SMP_OOB_PRESENT;
703a29b0733SJohan Hedberg 			memcpy(smp->rr, oob_data->rand256, 16);
70402b05bd8SJohan Hedberg 			memcpy(smp->pcnf, oob_data->hash256, 16);
705bc07cd69SMarcel Holtmann 			SMP_DBG("OOB Remote Confirmation: %16phN", smp->pcnf);
706bc07cd69SMarcel Holtmann 			SMP_DBG("OOB Remote Random: %16phN", smp->rr);
70702b05bd8SJohan Hedberg 		}
70802b05bd8SJohan Hedberg 
709df8e1a4cSJohan Hedberg 	} else {
710df8e1a4cSJohan Hedberg 		authreq &= ~SMP_AUTH_SC;
711df8e1a4cSJohan Hedberg 	}
712df8e1a4cSJohan Hedberg 
71354790f73SVinicius Costa Gomes 	if (rsp == NULL) {
71454790f73SVinicius Costa Gomes 		req->io_capability = conn->hcon->io_capability;
71502b05bd8SJohan Hedberg 		req->oob_flag = oob_flag;
7162fd36558SJohan Hedberg 		req->max_key_size = SMP_DEV(hdev)->max_key_size;
717fd349c02SJohan Hedberg 		req->init_key_dist = local_dist;
718fd349c02SJohan Hedberg 		req->resp_key_dist = remote_dist;
7190edb14deSJohan Hedberg 		req->auth_req = (authreq & AUTH_REQ_MASK(hdev));
720fd349c02SJohan Hedberg 
721fd349c02SJohan Hedberg 		smp->remote_key_dist = remote_dist;
72254790f73SVinicius Costa Gomes 		return;
72354790f73SVinicius Costa Gomes 	}
72454790f73SVinicius Costa Gomes 
72554790f73SVinicius Costa Gomes 	rsp->io_capability = conn->hcon->io_capability;
72602b05bd8SJohan Hedberg 	rsp->oob_flag = oob_flag;
7272fd36558SJohan Hedberg 	rsp->max_key_size = SMP_DEV(hdev)->max_key_size;
728fd349c02SJohan Hedberg 	rsp->init_key_dist = req->init_key_dist & remote_dist;
729fd349c02SJohan Hedberg 	rsp->resp_key_dist = req->resp_key_dist & local_dist;
7300edb14deSJohan Hedberg 	rsp->auth_req = (authreq & AUTH_REQ_MASK(hdev));
731fd349c02SJohan Hedberg 
732fd349c02SJohan Hedberg 	smp->remote_key_dist = rsp->init_key_dist;
733b8e66eacSVinicius Costa Gomes }
734b8e66eacSVinicius Costa Gomes 
7353158c50cSVinicius Costa Gomes static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
7363158c50cSVinicius Costa Gomes {
7375d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
7382fd36558SJohan Hedberg 	struct hci_dev *hdev = conn->hcon->hdev;
7395d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
7401c1def09SVinicius Costa Gomes 
7412fd36558SJohan Hedberg 	if (max_key_size > SMP_DEV(hdev)->max_key_size ||
7422fd36558SJohan Hedberg 	    max_key_size < SMP_MIN_ENC_KEY_SIZE)
7433158c50cSVinicius Costa Gomes 		return SMP_ENC_KEY_SIZE;
7443158c50cSVinicius Costa Gomes 
745f7aa611aSVinicius Costa Gomes 	smp->enc_key_size = max_key_size;
7463158c50cSVinicius Costa Gomes 
7473158c50cSVinicius Costa Gomes 	return 0;
7483158c50cSVinicius Costa Gomes }
7493158c50cSVinicius Costa Gomes 
7506f48e260SJohan Hedberg static void smp_chan_destroy(struct l2cap_conn *conn)
7516f48e260SJohan Hedberg {
7526f48e260SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
7536f48e260SJohan Hedberg 	struct smp_chan *smp = chan->data;
754923e2414SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
7556f48e260SJohan Hedberg 	bool complete;
7566f48e260SJohan Hedberg 
7576f48e260SJohan Hedberg 	BUG_ON(!smp);
7586f48e260SJohan Hedberg 
7596f48e260SJohan Hedberg 	cancel_delayed_work_sync(&smp->security_timer);
7606f48e260SJohan Hedberg 
7616f48e260SJohan Hedberg 	complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags);
762923e2414SJohan Hedberg 	mgmt_smp_complete(hcon, complete);
7636f48e260SJohan Hedberg 
764276812ecSMarcel Holtmann 	kzfree(smp->csrk);
765276812ecSMarcel Holtmann 	kzfree(smp->slave_csrk);
766276812ecSMarcel Holtmann 	kzfree(smp->link_key);
7676f48e260SJohan Hedberg 
7686f48e260SJohan Hedberg 	crypto_free_blkcipher(smp->tfm_aes);
769407cecf6SJohan Hedberg 	crypto_free_hash(smp->tfm_cmac);
7706f48e260SJohan Hedberg 
771923e2414SJohan Hedberg 	/* Ensure that we don't leave any debug key around if debug key
772923e2414SJohan Hedberg 	 * support hasn't been explicitly enabled.
773923e2414SJohan Hedberg 	 */
774923e2414SJohan Hedberg 	if (smp->ltk && smp->ltk->type == SMP_LTK_P256_DEBUG &&
775d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hcon->hdev, HCI_KEEP_DEBUG_KEYS)) {
776923e2414SJohan Hedberg 		list_del_rcu(&smp->ltk->list);
777923e2414SJohan Hedberg 		kfree_rcu(smp->ltk, rcu);
778923e2414SJohan Hedberg 		smp->ltk = NULL;
779923e2414SJohan Hedberg 	}
780923e2414SJohan Hedberg 
7816f48e260SJohan Hedberg 	/* If pairing failed clean up any keys we might have */
7826f48e260SJohan Hedberg 	if (!complete) {
7836f48e260SJohan Hedberg 		if (smp->ltk) {
784970d0f1bSJohan Hedberg 			list_del_rcu(&smp->ltk->list);
785970d0f1bSJohan Hedberg 			kfree_rcu(smp->ltk, rcu);
7866f48e260SJohan Hedberg 		}
7876f48e260SJohan Hedberg 
7886f48e260SJohan Hedberg 		if (smp->slave_ltk) {
789970d0f1bSJohan Hedberg 			list_del_rcu(&smp->slave_ltk->list);
790970d0f1bSJohan Hedberg 			kfree_rcu(smp->slave_ltk, rcu);
7916f48e260SJohan Hedberg 		}
7926f48e260SJohan Hedberg 
7936f48e260SJohan Hedberg 		if (smp->remote_irk) {
794adae20cbSJohan Hedberg 			list_del_rcu(&smp->remote_irk->list);
795adae20cbSJohan Hedberg 			kfree_rcu(smp->remote_irk, rcu);
7966f48e260SJohan Hedberg 		}
7976f48e260SJohan Hedberg 	}
7986f48e260SJohan Hedberg 
7996f48e260SJohan Hedberg 	chan->data = NULL;
800276812ecSMarcel Holtmann 	kzfree(smp);
801923e2414SJohan Hedberg 	hci_conn_drop(hcon);
8026f48e260SJohan Hedberg }
8036f48e260SJohan Hedberg 
80484794e11SJohan Hedberg static void smp_failure(struct l2cap_conn *conn, u8 reason)
8054f957a76SBrian Gix {
806bab73cb6SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
807b68fda68SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
808bab73cb6SJohan Hedberg 
80984794e11SJohan Hedberg 	if (reason)
8104f957a76SBrian Gix 		smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
8114f957a76SBrian Gix 			     &reason);
8124f957a76SBrian Gix 
813ce39fb4eSMarcel Holtmann 	clear_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags);
814e1e930f5SJohan Hedberg 	mgmt_auth_failed(hcon, HCI_ERROR_AUTH_FAILURE);
815f1c09c07SVinicius Costa Gomes 
816fc75cc86SJohan Hedberg 	if (chan->data)
8174f957a76SBrian Gix 		smp_chan_destroy(conn);
8184f957a76SBrian Gix }
8194f957a76SBrian Gix 
8202b64d153SBrian Gix #define JUST_WORKS	0x00
8212b64d153SBrian Gix #define JUST_CFM	0x01
8222b64d153SBrian Gix #define REQ_PASSKEY	0x02
8232b64d153SBrian Gix #define CFM_PASSKEY	0x03
8242b64d153SBrian Gix #define REQ_OOB		0x04
8255e3d3d9bSJohan Hedberg #define DSP_PASSKEY	0x05
8262b64d153SBrian Gix #define OVERLAP		0xFF
8272b64d153SBrian Gix 
8282b64d153SBrian Gix static const u8 gen_method[5][5] = {
8292b64d153SBrian Gix 	{ JUST_WORKS,  JUST_CFM,    REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
8302b64d153SBrian Gix 	{ JUST_WORKS,  JUST_CFM,    REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
8312b64d153SBrian Gix 	{ CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
8322b64d153SBrian Gix 	{ JUST_WORKS,  JUST_CFM,    JUST_WORKS,  JUST_WORKS, JUST_CFM    },
8332b64d153SBrian Gix 	{ CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, OVERLAP     },
8342b64d153SBrian Gix };
8352b64d153SBrian Gix 
8365e3d3d9bSJohan Hedberg static const u8 sc_method[5][5] = {
8375e3d3d9bSJohan Hedberg 	{ JUST_WORKS,  JUST_CFM,    REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
8385e3d3d9bSJohan Hedberg 	{ JUST_WORKS,  CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
8395e3d3d9bSJohan Hedberg 	{ DSP_PASSKEY, DSP_PASSKEY, REQ_PASSKEY, JUST_WORKS, DSP_PASSKEY },
8405e3d3d9bSJohan Hedberg 	{ JUST_WORKS,  JUST_CFM,    JUST_WORKS,  JUST_WORKS, JUST_CFM    },
8415e3d3d9bSJohan Hedberg 	{ DSP_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
8425e3d3d9bSJohan Hedberg };
8435e3d3d9bSJohan Hedberg 
844581370ccSJohan Hedberg static u8 get_auth_method(struct smp_chan *smp, u8 local_io, u8 remote_io)
845581370ccSJohan Hedberg {
8462bcd4003SJohan Hedberg 	/* If either side has unknown io_caps, use JUST_CFM (which gets
8472bcd4003SJohan Hedberg 	 * converted later to JUST_WORKS if we're initiators.
8482bcd4003SJohan Hedberg 	 */
849581370ccSJohan Hedberg 	if (local_io > SMP_IO_KEYBOARD_DISPLAY ||
850581370ccSJohan Hedberg 	    remote_io > SMP_IO_KEYBOARD_DISPLAY)
8512bcd4003SJohan Hedberg 		return JUST_CFM;
852581370ccSJohan Hedberg 
8535e3d3d9bSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags))
8545e3d3d9bSJohan Hedberg 		return sc_method[remote_io][local_io];
8555e3d3d9bSJohan Hedberg 
856581370ccSJohan Hedberg 	return gen_method[remote_io][local_io];
857581370ccSJohan Hedberg }
858581370ccSJohan Hedberg 
8592b64d153SBrian Gix static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
8602b64d153SBrian Gix 						u8 local_io, u8 remote_io)
8612b64d153SBrian Gix {
8622b64d153SBrian Gix 	struct hci_conn *hcon = conn->hcon;
8635d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
8645d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
8652b64d153SBrian Gix 	u32 passkey = 0;
8662b64d153SBrian Gix 	int ret = 0;
8672b64d153SBrian Gix 
8682b64d153SBrian Gix 	/* Initialize key for JUST WORKS */
8692b64d153SBrian Gix 	memset(smp->tk, 0, sizeof(smp->tk));
8704a74d658SJohan Hedberg 	clear_bit(SMP_FLAG_TK_VALID, &smp->flags);
8712b64d153SBrian Gix 
8722b64d153SBrian Gix 	BT_DBG("tk_request: auth:%d lcl:%d rem:%d", auth, local_io, remote_io);
8732b64d153SBrian Gix 
8742bcd4003SJohan Hedberg 	/* If neither side wants MITM, either "just" confirm an incoming
8752bcd4003SJohan Hedberg 	 * request or use just-works for outgoing ones. The JUST_CFM
8762bcd4003SJohan Hedberg 	 * will be converted to JUST_WORKS if necessary later in this
8772bcd4003SJohan Hedberg 	 * function. If either side has MITM look up the method from the
8782bcd4003SJohan Hedberg 	 * table.
8792bcd4003SJohan Hedberg 	 */
880581370ccSJohan Hedberg 	if (!(auth & SMP_AUTH_MITM))
881783e0574SJohan Hedberg 		smp->method = JUST_CFM;
8822b64d153SBrian Gix 	else
883783e0574SJohan Hedberg 		smp->method = get_auth_method(smp, local_io, remote_io);
8842b64d153SBrian Gix 
885a82505c7SJohan Hedberg 	/* Don't confirm locally initiated pairing attempts */
886783e0574SJohan Hedberg 	if (smp->method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR,
887783e0574SJohan Hedberg 						&smp->flags))
888783e0574SJohan Hedberg 		smp->method = JUST_WORKS;
889a82505c7SJohan Hedberg 
89002f3e254SJohan Hedberg 	/* Don't bother user space with no IO capabilities */
891783e0574SJohan Hedberg 	if (smp->method == JUST_CFM &&
892783e0574SJohan Hedberg 	    hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
893783e0574SJohan Hedberg 		smp->method = JUST_WORKS;
89402f3e254SJohan Hedberg 
8952b64d153SBrian Gix 	/* If Just Works, Continue with Zero TK */
896783e0574SJohan Hedberg 	if (smp->method == JUST_WORKS) {
8974a74d658SJohan Hedberg 		set_bit(SMP_FLAG_TK_VALID, &smp->flags);
8982b64d153SBrian Gix 		return 0;
8992b64d153SBrian Gix 	}
9002b64d153SBrian Gix 
90119c5ce9cSJohan Hedberg 	/* If this function is used for SC -> legacy fallback we
90219c5ce9cSJohan Hedberg 	 * can only recover the just-works case.
90319c5ce9cSJohan Hedberg 	 */
90419c5ce9cSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags))
90519c5ce9cSJohan Hedberg 		return -EINVAL;
90619c5ce9cSJohan Hedberg 
9072b64d153SBrian Gix 	/* Not Just Works/Confirm results in MITM Authentication */
908783e0574SJohan Hedberg 	if (smp->method != JUST_CFM) {
9094a74d658SJohan Hedberg 		set_bit(SMP_FLAG_MITM_AUTH, &smp->flags);
9105eb596f5SJohan Hedberg 		if (hcon->pending_sec_level < BT_SECURITY_HIGH)
9115eb596f5SJohan Hedberg 			hcon->pending_sec_level = BT_SECURITY_HIGH;
9125eb596f5SJohan Hedberg 	}
9132b64d153SBrian Gix 
9142b64d153SBrian Gix 	/* If both devices have Keyoard-Display I/O, the master
9152b64d153SBrian Gix 	 * Confirms and the slave Enters the passkey.
9162b64d153SBrian Gix 	 */
917783e0574SJohan Hedberg 	if (smp->method == OVERLAP) {
91840bef302SJohan Hedberg 		if (hcon->role == HCI_ROLE_MASTER)
919783e0574SJohan Hedberg 			smp->method = CFM_PASSKEY;
9202b64d153SBrian Gix 		else
921783e0574SJohan Hedberg 			smp->method = REQ_PASSKEY;
9222b64d153SBrian Gix 	}
9232b64d153SBrian Gix 
92401ad34d2SJohan Hedberg 	/* Generate random passkey. */
925783e0574SJohan Hedberg 	if (smp->method == CFM_PASSKEY) {
926943a732aSJohan Hedberg 		memset(smp->tk, 0, sizeof(smp->tk));
9272b64d153SBrian Gix 		get_random_bytes(&passkey, sizeof(passkey));
9282b64d153SBrian Gix 		passkey %= 1000000;
929943a732aSJohan Hedberg 		put_unaligned_le32(passkey, smp->tk);
9302b64d153SBrian Gix 		BT_DBG("PassKey: %d", passkey);
9314a74d658SJohan Hedberg 		set_bit(SMP_FLAG_TK_VALID, &smp->flags);
9322b64d153SBrian Gix 	}
9332b64d153SBrian Gix 
934783e0574SJohan Hedberg 	if (smp->method == REQ_PASSKEY)
935ce39fb4eSMarcel Holtmann 		ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst,
936272d90dfSJohan Hedberg 						hcon->type, hcon->dst_type);
937783e0574SJohan Hedberg 	else if (smp->method == JUST_CFM)
9384eb65e66SJohan Hedberg 		ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
9394eb65e66SJohan Hedberg 						hcon->type, hcon->dst_type,
9404eb65e66SJohan Hedberg 						passkey, 1);
9412b64d153SBrian Gix 	else
94201ad34d2SJohan Hedberg 		ret = mgmt_user_passkey_notify(hcon->hdev, &hcon->dst,
943272d90dfSJohan Hedberg 						hcon->type, hcon->dst_type,
94439adbffeSJohan Hedberg 						passkey, 0);
9452b64d153SBrian Gix 
9462b64d153SBrian Gix 	return ret;
9472b64d153SBrian Gix }
9482b64d153SBrian Gix 
9491cc61144SJohan Hedberg static u8 smp_confirm(struct smp_chan *smp)
9508aab4757SVinicius Costa Gomes {
9518aab4757SVinicius Costa Gomes 	struct l2cap_conn *conn = smp->conn;
9528aab4757SVinicius Costa Gomes 	struct smp_cmd_pairing_confirm cp;
9538aab4757SVinicius Costa Gomes 	int ret;
9548aab4757SVinicius Costa Gomes 
9558aab4757SVinicius Costa Gomes 	BT_DBG("conn %p", conn);
9568aab4757SVinicius Costa Gomes 
957e491eaf3SJohan Hedberg 	ret = smp_c1(smp->tfm_aes, smp->tk, smp->prnd, smp->preq, smp->prsp,
958b1cd5fd9SJohan Hedberg 		     conn->hcon->init_addr_type, &conn->hcon->init_addr,
959943a732aSJohan Hedberg 		     conn->hcon->resp_addr_type, &conn->hcon->resp_addr,
960943a732aSJohan Hedberg 		     cp.confirm_val);
9611cc61144SJohan Hedberg 	if (ret)
9621cc61144SJohan Hedberg 		return SMP_UNSPECIFIED;
9638aab4757SVinicius Costa Gomes 
9644a74d658SJohan Hedberg 	clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
9652b64d153SBrian Gix 
9668aab4757SVinicius Costa Gomes 	smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
9678aab4757SVinicius Costa Gomes 
968b28b4943SJohan Hedberg 	if (conn->hcon->out)
969b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
970b28b4943SJohan Hedberg 	else
971b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
972b28b4943SJohan Hedberg 
9731cc61144SJohan Hedberg 	return 0;
9748aab4757SVinicius Costa Gomes }
9758aab4757SVinicius Costa Gomes 
976861580a9SJohan Hedberg static u8 smp_random(struct smp_chan *smp)
9778aab4757SVinicius Costa Gomes {
9788aab4757SVinicius Costa Gomes 	struct l2cap_conn *conn = smp->conn;
9798aab4757SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
980861580a9SJohan Hedberg 	u8 confirm[16];
9818aab4757SVinicius Costa Gomes 	int ret;
9828aab4757SVinicius Costa Gomes 
983ec70f36fSJohan Hedberg 	if (IS_ERR_OR_NULL(smp->tfm_aes))
984861580a9SJohan Hedberg 		return SMP_UNSPECIFIED;
9858aab4757SVinicius Costa Gomes 
9868aab4757SVinicius Costa Gomes 	BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
9878aab4757SVinicius Costa Gomes 
988e491eaf3SJohan Hedberg 	ret = smp_c1(smp->tfm_aes, smp->tk, smp->rrnd, smp->preq, smp->prsp,
989b1cd5fd9SJohan Hedberg 		     hcon->init_addr_type, &hcon->init_addr,
990943a732aSJohan Hedberg 		     hcon->resp_addr_type, &hcon->resp_addr, confirm);
991861580a9SJohan Hedberg 	if (ret)
992861580a9SJohan Hedberg 		return SMP_UNSPECIFIED;
9938aab4757SVinicius Costa Gomes 
9948aab4757SVinicius Costa Gomes 	if (memcmp(smp->pcnf, confirm, sizeof(smp->pcnf)) != 0) {
9958aab4757SVinicius Costa Gomes 		BT_ERR("Pairing failed (confirmation values mismatch)");
996861580a9SJohan Hedberg 		return SMP_CONFIRM_FAILED;
9978aab4757SVinicius Costa Gomes 	}
9988aab4757SVinicius Costa Gomes 
9998aab4757SVinicius Costa Gomes 	if (hcon->out) {
1000fe39c7b2SMarcel Holtmann 		u8 stk[16];
1001fe39c7b2SMarcel Holtmann 		__le64 rand = 0;
1002fe39c7b2SMarcel Holtmann 		__le16 ediv = 0;
10038aab4757SVinicius Costa Gomes 
1004e491eaf3SJohan Hedberg 		smp_s1(smp->tfm_aes, smp->tk, smp->rrnd, smp->prnd, stk);
10058aab4757SVinicius Costa Gomes 
1006861580a9SJohan Hedberg 		if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
1007861580a9SJohan Hedberg 			return SMP_UNSPECIFIED;
10088aab4757SVinicius Costa Gomes 
10098b76ce34SJohan Hedberg 		hci_le_start_enc(hcon, ediv, rand, stk, smp->enc_key_size);
1010f7aa611aSVinicius Costa Gomes 		hcon->enc_key_size = smp->enc_key_size;
1011fe59a05fSJohan Hedberg 		set_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags);
10128aab4757SVinicius Costa Gomes 	} else {
1013fff3490fSJohan Hedberg 		u8 stk[16], auth;
1014fe39c7b2SMarcel Holtmann 		__le64 rand = 0;
1015fe39c7b2SMarcel Holtmann 		__le16 ediv = 0;
10168aab4757SVinicius Costa Gomes 
1017943a732aSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
1018943a732aSJohan Hedberg 			     smp->prnd);
10198aab4757SVinicius Costa Gomes 
1020e491eaf3SJohan Hedberg 		smp_s1(smp->tfm_aes, smp->tk, smp->prnd, smp->rrnd, stk);
10218aab4757SVinicius Costa Gomes 
1022fff3490fSJohan Hedberg 		if (hcon->pending_sec_level == BT_SECURITY_HIGH)
1023fff3490fSJohan Hedberg 			auth = 1;
1024fff3490fSJohan Hedberg 		else
1025fff3490fSJohan Hedberg 			auth = 0;
1026fff3490fSJohan Hedberg 
10277d5843b7SJohan Hedberg 		/* Even though there's no _SLAVE suffix this is the
10287d5843b7SJohan Hedberg 		 * slave STK we're adding for later lookup (the master
10297d5843b7SJohan Hedberg 		 * STK never needs to be stored).
10307d5843b7SJohan Hedberg 		 */
1031ce39fb4eSMarcel Holtmann 		hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
10322ceba539SJohan Hedberg 			    SMP_STK, auth, stk, smp->enc_key_size, ediv, rand);
10338aab4757SVinicius Costa Gomes 	}
10348aab4757SVinicius Costa Gomes 
1035861580a9SJohan Hedberg 	return 0;
10368aab4757SVinicius Costa Gomes }
10378aab4757SVinicius Costa Gomes 
103844f1a7abSJohan Hedberg static void smp_notify_keys(struct l2cap_conn *conn)
103944f1a7abSJohan Hedberg {
104044f1a7abSJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
104144f1a7abSJohan Hedberg 	struct smp_chan *smp = chan->data;
104244f1a7abSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
104344f1a7abSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
104444f1a7abSJohan Hedberg 	struct smp_cmd_pairing *req = (void *) &smp->preq[1];
104544f1a7abSJohan Hedberg 	struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1];
104644f1a7abSJohan Hedberg 	bool persistent;
104744f1a7abSJohan Hedberg 
104844f1a7abSJohan Hedberg 	if (smp->remote_irk) {
104944f1a7abSJohan Hedberg 		mgmt_new_irk(hdev, smp->remote_irk);
105044f1a7abSJohan Hedberg 		/* Now that user space can be considered to know the
105144f1a7abSJohan Hedberg 		 * identity address track the connection based on it
1052b5ae344dSJohan Hedberg 		 * from now on (assuming this is an LE link).
105344f1a7abSJohan Hedberg 		 */
1054b5ae344dSJohan Hedberg 		if (hcon->type == LE_LINK) {
105544f1a7abSJohan Hedberg 			bacpy(&hcon->dst, &smp->remote_irk->bdaddr);
105644f1a7abSJohan Hedberg 			hcon->dst_type = smp->remote_irk->addr_type;
1057f3d82d0cSJohan Hedberg 			queue_work(hdev->workqueue, &conn->id_addr_update_work);
1058b5ae344dSJohan Hedberg 		}
105944f1a7abSJohan Hedberg 
106044f1a7abSJohan Hedberg 		/* When receiving an indentity resolving key for
106144f1a7abSJohan Hedberg 		 * a remote device that does not use a resolvable
106244f1a7abSJohan Hedberg 		 * private address, just remove the key so that
106344f1a7abSJohan Hedberg 		 * it is possible to use the controller white
106444f1a7abSJohan Hedberg 		 * list for scanning.
106544f1a7abSJohan Hedberg 		 *
106644f1a7abSJohan Hedberg 		 * Userspace will have been told to not store
106744f1a7abSJohan Hedberg 		 * this key at this point. So it is safe to
106844f1a7abSJohan Hedberg 		 * just remove it.
106944f1a7abSJohan Hedberg 		 */
107044f1a7abSJohan Hedberg 		if (!bacmp(&smp->remote_irk->rpa, BDADDR_ANY)) {
1071adae20cbSJohan Hedberg 			list_del_rcu(&smp->remote_irk->list);
1072adae20cbSJohan Hedberg 			kfree_rcu(smp->remote_irk, rcu);
107344f1a7abSJohan Hedberg 			smp->remote_irk = NULL;
107444f1a7abSJohan Hedberg 		}
107544f1a7abSJohan Hedberg 	}
107644f1a7abSJohan Hedberg 
1077b5ae344dSJohan Hedberg 	if (hcon->type == ACL_LINK) {
1078b5ae344dSJohan Hedberg 		if (hcon->key_type == HCI_LK_DEBUG_COMBINATION)
1079b5ae344dSJohan Hedberg 			persistent = false;
1080b5ae344dSJohan Hedberg 		else
1081b5ae344dSJohan Hedberg 			persistent = !test_bit(HCI_CONN_FLUSH_KEY,
1082b5ae344dSJohan Hedberg 					       &hcon->flags);
1083b5ae344dSJohan Hedberg 	} else {
108444f1a7abSJohan Hedberg 		/* The LTKs and CSRKs should be persistent only if both sides
108544f1a7abSJohan Hedberg 		 * had the bonding bit set in their authentication requests.
108644f1a7abSJohan Hedberg 		 */
1087b5ae344dSJohan Hedberg 		persistent = !!((req->auth_req & rsp->auth_req) &
1088b5ae344dSJohan Hedberg 				SMP_AUTH_BONDING);
1089b5ae344dSJohan Hedberg 	}
1090b5ae344dSJohan Hedberg 
109144f1a7abSJohan Hedberg 
109244f1a7abSJohan Hedberg 	if (smp->csrk) {
109344f1a7abSJohan Hedberg 		smp->csrk->bdaddr_type = hcon->dst_type;
109444f1a7abSJohan Hedberg 		bacpy(&smp->csrk->bdaddr, &hcon->dst);
109544f1a7abSJohan Hedberg 		mgmt_new_csrk(hdev, smp->csrk, persistent);
109644f1a7abSJohan Hedberg 	}
109744f1a7abSJohan Hedberg 
109844f1a7abSJohan Hedberg 	if (smp->slave_csrk) {
109944f1a7abSJohan Hedberg 		smp->slave_csrk->bdaddr_type = hcon->dst_type;
110044f1a7abSJohan Hedberg 		bacpy(&smp->slave_csrk->bdaddr, &hcon->dst);
110144f1a7abSJohan Hedberg 		mgmt_new_csrk(hdev, smp->slave_csrk, persistent);
110244f1a7abSJohan Hedberg 	}
110344f1a7abSJohan Hedberg 
110444f1a7abSJohan Hedberg 	if (smp->ltk) {
110544f1a7abSJohan Hedberg 		smp->ltk->bdaddr_type = hcon->dst_type;
110644f1a7abSJohan Hedberg 		bacpy(&smp->ltk->bdaddr, &hcon->dst);
110744f1a7abSJohan Hedberg 		mgmt_new_ltk(hdev, smp->ltk, persistent);
110844f1a7abSJohan Hedberg 	}
110944f1a7abSJohan Hedberg 
111044f1a7abSJohan Hedberg 	if (smp->slave_ltk) {
111144f1a7abSJohan Hedberg 		smp->slave_ltk->bdaddr_type = hcon->dst_type;
111244f1a7abSJohan Hedberg 		bacpy(&smp->slave_ltk->bdaddr, &hcon->dst);
111344f1a7abSJohan Hedberg 		mgmt_new_ltk(hdev, smp->slave_ltk, persistent);
111444f1a7abSJohan Hedberg 	}
11156a77083aSJohan Hedberg 
11166a77083aSJohan Hedberg 	if (smp->link_key) {
1117e3befab9SJohan Hedberg 		struct link_key *key;
1118e3befab9SJohan Hedberg 		u8 type;
1119e3befab9SJohan Hedberg 
1120e3befab9SJohan Hedberg 		if (test_bit(SMP_FLAG_DEBUG_KEY, &smp->flags))
1121e3befab9SJohan Hedberg 			type = HCI_LK_DEBUG_COMBINATION;
1122e3befab9SJohan Hedberg 		else if (hcon->sec_level == BT_SECURITY_FIPS)
1123e3befab9SJohan Hedberg 			type = HCI_LK_AUTH_COMBINATION_P256;
1124e3befab9SJohan Hedberg 		else
1125e3befab9SJohan Hedberg 			type = HCI_LK_UNAUTH_COMBINATION_P256;
1126e3befab9SJohan Hedberg 
1127e3befab9SJohan Hedberg 		key = hci_add_link_key(hdev, smp->conn->hcon, &hcon->dst,
1128e3befab9SJohan Hedberg 				       smp->link_key, type, 0, &persistent);
1129e3befab9SJohan Hedberg 		if (key) {
1130e3befab9SJohan Hedberg 			mgmt_new_link_key(hdev, key, persistent);
1131e3befab9SJohan Hedberg 
1132e3befab9SJohan Hedberg 			/* Don't keep debug keys around if the relevant
1133e3befab9SJohan Hedberg 			 * flag is not set.
1134e3befab9SJohan Hedberg 			 */
1135d7a5a11dSMarcel Holtmann 			if (!hci_dev_test_flag(hdev, HCI_KEEP_DEBUG_KEYS) &&
1136e3befab9SJohan Hedberg 			    key->type == HCI_LK_DEBUG_COMBINATION) {
1137e3befab9SJohan Hedberg 				list_del_rcu(&key->list);
1138e3befab9SJohan Hedberg 				kfree_rcu(key, rcu);
1139e3befab9SJohan Hedberg 			}
1140e3befab9SJohan Hedberg 		}
11416a77083aSJohan Hedberg 	}
11426a77083aSJohan Hedberg }
11436a77083aSJohan Hedberg 
1144d3e54a87SJohan Hedberg static void sc_add_ltk(struct smp_chan *smp)
1145d3e54a87SJohan Hedberg {
1146d3e54a87SJohan Hedberg 	struct hci_conn *hcon = smp->conn->hcon;
1147d3e54a87SJohan Hedberg 	u8 key_type, auth;
1148d3e54a87SJohan Hedberg 
1149d3e54a87SJohan Hedberg 	if (test_bit(SMP_FLAG_DEBUG_KEY, &smp->flags))
1150d3e54a87SJohan Hedberg 		key_type = SMP_LTK_P256_DEBUG;
1151d3e54a87SJohan Hedberg 	else
1152d3e54a87SJohan Hedberg 		key_type = SMP_LTK_P256;
1153d3e54a87SJohan Hedberg 
1154d3e54a87SJohan Hedberg 	if (hcon->pending_sec_level == BT_SECURITY_FIPS)
1155d3e54a87SJohan Hedberg 		auth = 1;
1156d3e54a87SJohan Hedberg 	else
1157d3e54a87SJohan Hedberg 		auth = 0;
1158d3e54a87SJohan Hedberg 
1159d3e54a87SJohan Hedberg 	smp->ltk = hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
1160d3e54a87SJohan Hedberg 			       key_type, auth, smp->tk, smp->enc_key_size,
1161d3e54a87SJohan Hedberg 			       0, 0);
1162d3e54a87SJohan Hedberg }
1163d3e54a87SJohan Hedberg 
11646a77083aSJohan Hedberg static void sc_generate_link_key(struct smp_chan *smp)
11656a77083aSJohan Hedberg {
11666a77083aSJohan Hedberg 	/* These constants are as specified in the core specification.
11676a77083aSJohan Hedberg 	 * In ASCII they spell out to 'tmp1' and 'lebr'.
11686a77083aSJohan Hedberg 	 */
11696a77083aSJohan Hedberg 	const u8 tmp1[4] = { 0x31, 0x70, 0x6d, 0x74 };
11706a77083aSJohan Hedberg 	const u8 lebr[4] = { 0x72, 0x62, 0x65, 0x6c };
11716a77083aSJohan Hedberg 
11726a77083aSJohan Hedberg 	smp->link_key = kzalloc(16, GFP_KERNEL);
11736a77083aSJohan Hedberg 	if (!smp->link_key)
11746a77083aSJohan Hedberg 		return;
11756a77083aSJohan Hedberg 
11766a77083aSJohan Hedberg 	if (smp_h6(smp->tfm_cmac, smp->tk, tmp1, smp->link_key)) {
1177276812ecSMarcel Holtmann 		kzfree(smp->link_key);
11786a77083aSJohan Hedberg 		smp->link_key = NULL;
11796a77083aSJohan Hedberg 		return;
11806a77083aSJohan Hedberg 	}
11816a77083aSJohan Hedberg 
11826a77083aSJohan Hedberg 	if (smp_h6(smp->tfm_cmac, smp->link_key, lebr, smp->link_key)) {
1183276812ecSMarcel Holtmann 		kzfree(smp->link_key);
11846a77083aSJohan Hedberg 		smp->link_key = NULL;
11856a77083aSJohan Hedberg 		return;
11866a77083aSJohan Hedberg 	}
118744f1a7abSJohan Hedberg }
118844f1a7abSJohan Hedberg 
1189b28b4943SJohan Hedberg static void smp_allow_key_dist(struct smp_chan *smp)
1190b28b4943SJohan Hedberg {
1191b28b4943SJohan Hedberg 	/* Allow the first expected phase 3 PDU. The rest of the PDUs
1192b28b4943SJohan Hedberg 	 * will be allowed in each PDU handler to ensure we receive
1193b28b4943SJohan Hedberg 	 * them in the correct order.
1194b28b4943SJohan Hedberg 	 */
1195b28b4943SJohan Hedberg 	if (smp->remote_key_dist & SMP_DIST_ENC_KEY)
1196b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_ENCRYPT_INFO);
1197b28b4943SJohan Hedberg 	else if (smp->remote_key_dist & SMP_DIST_ID_KEY)
1198b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO);
1199b28b4943SJohan Hedberg 	else if (smp->remote_key_dist & SMP_DIST_SIGN)
1200b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO);
1201b28b4943SJohan Hedberg }
1202b28b4943SJohan Hedberg 
1203b5ae344dSJohan Hedberg static void sc_generate_ltk(struct smp_chan *smp)
1204b5ae344dSJohan Hedberg {
1205b5ae344dSJohan Hedberg 	/* These constants are as specified in the core specification.
1206b5ae344dSJohan Hedberg 	 * In ASCII they spell out to 'tmp2' and 'brle'.
1207b5ae344dSJohan Hedberg 	 */
1208b5ae344dSJohan Hedberg 	const u8 tmp2[4] = { 0x32, 0x70, 0x6d, 0x74 };
1209b5ae344dSJohan Hedberg 	const u8 brle[4] = { 0x65, 0x6c, 0x72, 0x62 };
1210b5ae344dSJohan Hedberg 	struct hci_conn *hcon = smp->conn->hcon;
1211b5ae344dSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
1212b5ae344dSJohan Hedberg 	struct link_key *key;
1213b5ae344dSJohan Hedberg 
1214b5ae344dSJohan Hedberg 	key = hci_find_link_key(hdev, &hcon->dst);
1215b5ae344dSJohan Hedberg 	if (!key) {
1216b5ae344dSJohan Hedberg 		BT_ERR("%s No Link Key found to generate LTK", hdev->name);
1217b5ae344dSJohan Hedberg 		return;
1218b5ae344dSJohan Hedberg 	}
1219b5ae344dSJohan Hedberg 
1220b5ae344dSJohan Hedberg 	if (key->type == HCI_LK_DEBUG_COMBINATION)
1221b5ae344dSJohan Hedberg 		set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags);
1222b5ae344dSJohan Hedberg 
1223b5ae344dSJohan Hedberg 	if (smp_h6(smp->tfm_cmac, key->val, tmp2, smp->tk))
1224b5ae344dSJohan Hedberg 		return;
1225b5ae344dSJohan Hedberg 
1226b5ae344dSJohan Hedberg 	if (smp_h6(smp->tfm_cmac, smp->tk, brle, smp->tk))
1227b5ae344dSJohan Hedberg 		return;
1228b5ae344dSJohan Hedberg 
1229b5ae344dSJohan Hedberg 	sc_add_ltk(smp);
1230b5ae344dSJohan Hedberg }
1231b5ae344dSJohan Hedberg 
1232d6268e86SJohan Hedberg static void smp_distribute_keys(struct smp_chan *smp)
123344f1a7abSJohan Hedberg {
123444f1a7abSJohan Hedberg 	struct smp_cmd_pairing *req, *rsp;
123586d1407cSJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
123644f1a7abSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
123744f1a7abSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
123844f1a7abSJohan Hedberg 	__u8 *keydist;
123944f1a7abSJohan Hedberg 
124044f1a7abSJohan Hedberg 	BT_DBG("conn %p", conn);
124144f1a7abSJohan Hedberg 
124244f1a7abSJohan Hedberg 	rsp = (void *) &smp->prsp[1];
124344f1a7abSJohan Hedberg 
124444f1a7abSJohan Hedberg 	/* The responder sends its keys first */
1245b28b4943SJohan Hedberg 	if (hcon->out && (smp->remote_key_dist & KEY_DIST_MASK)) {
1246b28b4943SJohan Hedberg 		smp_allow_key_dist(smp);
124786d1407cSJohan Hedberg 		return;
1248b28b4943SJohan Hedberg 	}
124944f1a7abSJohan Hedberg 
125044f1a7abSJohan Hedberg 	req = (void *) &smp->preq[1];
125144f1a7abSJohan Hedberg 
125244f1a7abSJohan Hedberg 	if (hcon->out) {
125344f1a7abSJohan Hedberg 		keydist = &rsp->init_key_dist;
125444f1a7abSJohan Hedberg 		*keydist &= req->init_key_dist;
125544f1a7abSJohan Hedberg 	} else {
125644f1a7abSJohan Hedberg 		keydist = &rsp->resp_key_dist;
125744f1a7abSJohan Hedberg 		*keydist &= req->resp_key_dist;
125844f1a7abSJohan Hedberg 	}
125944f1a7abSJohan Hedberg 
12606a77083aSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
1261b5ae344dSJohan Hedberg 		if (hcon->type == LE_LINK && (*keydist & SMP_DIST_LINK_KEY))
12626a77083aSJohan Hedberg 			sc_generate_link_key(smp);
1263b5ae344dSJohan Hedberg 		if (hcon->type == ACL_LINK && (*keydist & SMP_DIST_ENC_KEY))
1264b5ae344dSJohan Hedberg 			sc_generate_ltk(smp);
12656a77083aSJohan Hedberg 
12666a77083aSJohan Hedberg 		/* Clear the keys which are generated but not distributed */
12676a77083aSJohan Hedberg 		*keydist &= ~SMP_SC_NO_DIST;
12686a77083aSJohan Hedberg 	}
12696a77083aSJohan Hedberg 
127044f1a7abSJohan Hedberg 	BT_DBG("keydist 0x%x", *keydist);
127144f1a7abSJohan Hedberg 
127244f1a7abSJohan Hedberg 	if (*keydist & SMP_DIST_ENC_KEY) {
127344f1a7abSJohan Hedberg 		struct smp_cmd_encrypt_info enc;
127444f1a7abSJohan Hedberg 		struct smp_cmd_master_ident ident;
127544f1a7abSJohan Hedberg 		struct smp_ltk *ltk;
127644f1a7abSJohan Hedberg 		u8 authenticated;
127744f1a7abSJohan Hedberg 		__le16 ediv;
127844f1a7abSJohan Hedberg 		__le64 rand;
127944f1a7abSJohan Hedberg 
12801fc62c52SJohan Hedberg 		/* Make sure we generate only the significant amount of
12811fc62c52SJohan Hedberg 		 * bytes based on the encryption key size, and set the rest
12821fc62c52SJohan Hedberg 		 * of the value to zeroes.
12831fc62c52SJohan Hedberg 		 */
12841fc62c52SJohan Hedberg 		get_random_bytes(enc.ltk, smp->enc_key_size);
12851fc62c52SJohan Hedberg 		memset(enc.ltk + smp->enc_key_size, 0,
12861fc62c52SJohan Hedberg 		       sizeof(enc.ltk) - smp->enc_key_size);
12871fc62c52SJohan Hedberg 
128844f1a7abSJohan Hedberg 		get_random_bytes(&ediv, sizeof(ediv));
128944f1a7abSJohan Hedberg 		get_random_bytes(&rand, sizeof(rand));
129044f1a7abSJohan Hedberg 
129144f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
129244f1a7abSJohan Hedberg 
129344f1a7abSJohan Hedberg 		authenticated = hcon->sec_level == BT_SECURITY_HIGH;
129444f1a7abSJohan Hedberg 		ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type,
129544f1a7abSJohan Hedberg 				  SMP_LTK_SLAVE, authenticated, enc.ltk,
129644f1a7abSJohan Hedberg 				  smp->enc_key_size, ediv, rand);
129744f1a7abSJohan Hedberg 		smp->slave_ltk = ltk;
129844f1a7abSJohan Hedberg 
129944f1a7abSJohan Hedberg 		ident.ediv = ediv;
130044f1a7abSJohan Hedberg 		ident.rand = rand;
130144f1a7abSJohan Hedberg 
130244f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident);
130344f1a7abSJohan Hedberg 
130444f1a7abSJohan Hedberg 		*keydist &= ~SMP_DIST_ENC_KEY;
130544f1a7abSJohan Hedberg 	}
130644f1a7abSJohan Hedberg 
130744f1a7abSJohan Hedberg 	if (*keydist & SMP_DIST_ID_KEY) {
130844f1a7abSJohan Hedberg 		struct smp_cmd_ident_addr_info addrinfo;
130944f1a7abSJohan Hedberg 		struct smp_cmd_ident_info idinfo;
131044f1a7abSJohan Hedberg 
131144f1a7abSJohan Hedberg 		memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk));
131244f1a7abSJohan Hedberg 
131344f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo);
131444f1a7abSJohan Hedberg 
131544f1a7abSJohan Hedberg 		/* The hci_conn contains the local identity address
131644f1a7abSJohan Hedberg 		 * after the connection has been established.
131744f1a7abSJohan Hedberg 		 *
131844f1a7abSJohan Hedberg 		 * This is true even when the connection has been
131944f1a7abSJohan Hedberg 		 * established using a resolvable random address.
132044f1a7abSJohan Hedberg 		 */
132144f1a7abSJohan Hedberg 		bacpy(&addrinfo.bdaddr, &hcon->src);
132244f1a7abSJohan Hedberg 		addrinfo.addr_type = hcon->src_type;
132344f1a7abSJohan Hedberg 
132444f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo),
132544f1a7abSJohan Hedberg 			     &addrinfo);
132644f1a7abSJohan Hedberg 
132744f1a7abSJohan Hedberg 		*keydist &= ~SMP_DIST_ID_KEY;
132844f1a7abSJohan Hedberg 	}
132944f1a7abSJohan Hedberg 
133044f1a7abSJohan Hedberg 	if (*keydist & SMP_DIST_SIGN) {
133144f1a7abSJohan Hedberg 		struct smp_cmd_sign_info sign;
133244f1a7abSJohan Hedberg 		struct smp_csrk *csrk;
133344f1a7abSJohan Hedberg 
133444f1a7abSJohan Hedberg 		/* Generate a new random key */
133544f1a7abSJohan Hedberg 		get_random_bytes(sign.csrk, sizeof(sign.csrk));
133644f1a7abSJohan Hedberg 
133744f1a7abSJohan Hedberg 		csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
133844f1a7abSJohan Hedberg 		if (csrk) {
13394cd3928aSJohan Hedberg 			if (hcon->sec_level > BT_SECURITY_MEDIUM)
13404cd3928aSJohan Hedberg 				csrk->type = MGMT_CSRK_LOCAL_AUTHENTICATED;
13414cd3928aSJohan Hedberg 			else
13424cd3928aSJohan Hedberg 				csrk->type = MGMT_CSRK_LOCAL_UNAUTHENTICATED;
134344f1a7abSJohan Hedberg 			memcpy(csrk->val, sign.csrk, sizeof(csrk->val));
134444f1a7abSJohan Hedberg 		}
134544f1a7abSJohan Hedberg 		smp->slave_csrk = csrk;
134644f1a7abSJohan Hedberg 
134744f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign);
134844f1a7abSJohan Hedberg 
134944f1a7abSJohan Hedberg 		*keydist &= ~SMP_DIST_SIGN;
135044f1a7abSJohan Hedberg 	}
135144f1a7abSJohan Hedberg 
135244f1a7abSJohan Hedberg 	/* If there are still keys to be received wait for them */
1353b28b4943SJohan Hedberg 	if (smp->remote_key_dist & KEY_DIST_MASK) {
1354b28b4943SJohan Hedberg 		smp_allow_key_dist(smp);
135586d1407cSJohan Hedberg 		return;
1356b28b4943SJohan Hedberg 	}
135744f1a7abSJohan Hedberg 
135844f1a7abSJohan Hedberg 	set_bit(SMP_FLAG_COMPLETE, &smp->flags);
135944f1a7abSJohan Hedberg 	smp_notify_keys(conn);
136044f1a7abSJohan Hedberg 
136144f1a7abSJohan Hedberg 	smp_chan_destroy(conn);
136244f1a7abSJohan Hedberg }
136344f1a7abSJohan Hedberg 
1364b68fda68SJohan Hedberg static void smp_timeout(struct work_struct *work)
1365b68fda68SJohan Hedberg {
1366b68fda68SJohan Hedberg 	struct smp_chan *smp = container_of(work, struct smp_chan,
1367b68fda68SJohan Hedberg 					    security_timer.work);
1368b68fda68SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
1369b68fda68SJohan Hedberg 
1370b68fda68SJohan Hedberg 	BT_DBG("conn %p", conn);
1371b68fda68SJohan Hedberg 
13721e91c29eSJohan Hedberg 	hci_disconnect(conn->hcon, HCI_ERROR_REMOTE_USER_TERM);
1373b68fda68SJohan Hedberg }
1374b68fda68SJohan Hedberg 
13758aab4757SVinicius Costa Gomes static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
13768aab4757SVinicius Costa Gomes {
13775d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
13788aab4757SVinicius Costa Gomes 	struct smp_chan *smp;
13798aab4757SVinicius Costa Gomes 
1380f1560463SMarcel Holtmann 	smp = kzalloc(sizeof(*smp), GFP_ATOMIC);
1381fc75cc86SJohan Hedberg 	if (!smp)
13828aab4757SVinicius Costa Gomes 		return NULL;
13838aab4757SVinicius Costa Gomes 
13846a7bd103SJohan Hedberg 	smp->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
13856a7bd103SJohan Hedberg 	if (IS_ERR(smp->tfm_aes)) {
13866a7bd103SJohan Hedberg 		BT_ERR("Unable to create ECB crypto context");
1387276812ecSMarcel Holtmann 		kzfree(smp);
13886a7bd103SJohan Hedberg 		return NULL;
13896a7bd103SJohan Hedberg 	}
13906a7bd103SJohan Hedberg 
1391407cecf6SJohan Hedberg 	smp->tfm_cmac = crypto_alloc_hash("cmac(aes)", 0, CRYPTO_ALG_ASYNC);
1392407cecf6SJohan Hedberg 	if (IS_ERR(smp->tfm_cmac)) {
1393407cecf6SJohan Hedberg 		BT_ERR("Unable to create CMAC crypto context");
1394407cecf6SJohan Hedberg 		crypto_free_blkcipher(smp->tfm_aes);
1395276812ecSMarcel Holtmann 		kzfree(smp);
1396407cecf6SJohan Hedberg 		return NULL;
1397407cecf6SJohan Hedberg 	}
1398407cecf6SJohan Hedberg 
13998aab4757SVinicius Costa Gomes 	smp->conn = conn;
14005d88cc73SJohan Hedberg 	chan->data = smp;
14018aab4757SVinicius Costa Gomes 
1402b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_FAIL);
1403b28b4943SJohan Hedberg 
1404b68fda68SJohan Hedberg 	INIT_DELAYED_WORK(&smp->security_timer, smp_timeout);
1405b68fda68SJohan Hedberg 
14068aab4757SVinicius Costa Gomes 	hci_conn_hold(conn->hcon);
14078aab4757SVinicius Costa Gomes 
14088aab4757SVinicius Costa Gomes 	return smp;
14098aab4757SVinicius Costa Gomes }
14108aab4757SVinicius Costa Gomes 
1411760b018bSJohan Hedberg static int sc_mackey_and_ltk(struct smp_chan *smp, u8 mackey[16], u8 ltk[16])
1412760b018bSJohan Hedberg {
1413760b018bSJohan Hedberg 	struct hci_conn *hcon = smp->conn->hcon;
1414760b018bSJohan Hedberg 	u8 *na, *nb, a[7], b[7];
1415760b018bSJohan Hedberg 
1416760b018bSJohan Hedberg 	if (hcon->out) {
1417760b018bSJohan Hedberg 		na   = smp->prnd;
1418760b018bSJohan Hedberg 		nb   = smp->rrnd;
1419760b018bSJohan Hedberg 	} else {
1420760b018bSJohan Hedberg 		na   = smp->rrnd;
1421760b018bSJohan Hedberg 		nb   = smp->prnd;
1422760b018bSJohan Hedberg 	}
1423760b018bSJohan Hedberg 
1424760b018bSJohan Hedberg 	memcpy(a, &hcon->init_addr, 6);
1425760b018bSJohan Hedberg 	memcpy(b, &hcon->resp_addr, 6);
1426760b018bSJohan Hedberg 	a[6] = hcon->init_addr_type;
1427760b018bSJohan Hedberg 	b[6] = hcon->resp_addr_type;
1428760b018bSJohan Hedberg 
1429760b018bSJohan Hedberg 	return smp_f5(smp->tfm_cmac, smp->dhkey, na, nb, a, b, mackey, ltk);
1430760b018bSJohan Hedberg }
1431760b018bSJohan Hedberg 
143238606f14SJohan Hedberg static void sc_dhkey_check(struct smp_chan *smp)
1433760b018bSJohan Hedberg {
1434760b018bSJohan Hedberg 	struct hci_conn *hcon = smp->conn->hcon;
1435760b018bSJohan Hedberg 	struct smp_cmd_dhkey_check check;
1436760b018bSJohan Hedberg 	u8 a[7], b[7], *local_addr, *remote_addr;
1437760b018bSJohan Hedberg 	u8 io_cap[3], r[16];
1438760b018bSJohan Hedberg 
1439760b018bSJohan Hedberg 	memcpy(a, &hcon->init_addr, 6);
1440760b018bSJohan Hedberg 	memcpy(b, &hcon->resp_addr, 6);
1441760b018bSJohan Hedberg 	a[6] = hcon->init_addr_type;
1442760b018bSJohan Hedberg 	b[6] = hcon->resp_addr_type;
1443760b018bSJohan Hedberg 
1444760b018bSJohan Hedberg 	if (hcon->out) {
1445760b018bSJohan Hedberg 		local_addr = a;
1446760b018bSJohan Hedberg 		remote_addr = b;
1447760b018bSJohan Hedberg 		memcpy(io_cap, &smp->preq[1], 3);
1448760b018bSJohan Hedberg 	} else {
1449760b018bSJohan Hedberg 		local_addr = b;
1450760b018bSJohan Hedberg 		remote_addr = a;
1451760b018bSJohan Hedberg 		memcpy(io_cap, &smp->prsp[1], 3);
1452760b018bSJohan Hedberg 	}
1453760b018bSJohan Hedberg 
1454dddd3059SJohan Hedberg 	memset(r, 0, sizeof(r));
1455dddd3059SJohan Hedberg 
1456dddd3059SJohan Hedberg 	if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY)
145738606f14SJohan Hedberg 		put_unaligned_le32(hcon->passkey_notify, r);
1458760b018bSJohan Hedberg 
1459a29b0733SJohan Hedberg 	if (smp->method == REQ_OOB)
1460a29b0733SJohan Hedberg 		memcpy(r, smp->rr, 16);
1461a29b0733SJohan Hedberg 
1462760b018bSJohan Hedberg 	smp_f6(smp->tfm_cmac, smp->mackey, smp->prnd, smp->rrnd, r, io_cap,
1463760b018bSJohan Hedberg 	       local_addr, remote_addr, check.e);
1464760b018bSJohan Hedberg 
1465760b018bSJohan Hedberg 	smp_send_cmd(smp->conn, SMP_CMD_DHKEY_CHECK, sizeof(check), &check);
1466dddd3059SJohan Hedberg }
1467dddd3059SJohan Hedberg 
146838606f14SJohan Hedberg static u8 sc_passkey_send_confirm(struct smp_chan *smp)
146938606f14SJohan Hedberg {
147038606f14SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
147138606f14SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
147238606f14SJohan Hedberg 	struct smp_cmd_pairing_confirm cfm;
147338606f14SJohan Hedberg 	u8 r;
147438606f14SJohan Hedberg 
147538606f14SJohan Hedberg 	r = ((hcon->passkey_notify >> smp->passkey_round) & 0x01);
147638606f14SJohan Hedberg 	r |= 0x80;
147738606f14SJohan Hedberg 
147838606f14SJohan Hedberg 	get_random_bytes(smp->prnd, sizeof(smp->prnd));
147938606f14SJohan Hedberg 
148038606f14SJohan Hedberg 	if (smp_f4(smp->tfm_cmac, smp->local_pk, smp->remote_pk, smp->prnd, r,
148138606f14SJohan Hedberg 		   cfm.confirm_val))
148238606f14SJohan Hedberg 		return SMP_UNSPECIFIED;
148338606f14SJohan Hedberg 
148438606f14SJohan Hedberg 	smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cfm), &cfm);
148538606f14SJohan Hedberg 
148638606f14SJohan Hedberg 	return 0;
148738606f14SJohan Hedberg }
148838606f14SJohan Hedberg 
148938606f14SJohan Hedberg static u8 sc_passkey_round(struct smp_chan *smp, u8 smp_op)
149038606f14SJohan Hedberg {
149138606f14SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
149238606f14SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
149338606f14SJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
149438606f14SJohan Hedberg 	u8 cfm[16], r;
149538606f14SJohan Hedberg 
149638606f14SJohan Hedberg 	/* Ignore the PDU if we've already done 20 rounds (0 - 19) */
149738606f14SJohan Hedberg 	if (smp->passkey_round >= 20)
149838606f14SJohan Hedberg 		return 0;
149938606f14SJohan Hedberg 
150038606f14SJohan Hedberg 	switch (smp_op) {
150138606f14SJohan Hedberg 	case SMP_CMD_PAIRING_RANDOM:
150238606f14SJohan Hedberg 		r = ((hcon->passkey_notify >> smp->passkey_round) & 0x01);
150338606f14SJohan Hedberg 		r |= 0x80;
150438606f14SJohan Hedberg 
150538606f14SJohan Hedberg 		if (smp_f4(smp->tfm_cmac, smp->remote_pk, smp->local_pk,
150638606f14SJohan Hedberg 			   smp->rrnd, r, cfm))
150738606f14SJohan Hedberg 			return SMP_UNSPECIFIED;
150838606f14SJohan Hedberg 
150938606f14SJohan Hedberg 		if (memcmp(smp->pcnf, cfm, 16))
151038606f14SJohan Hedberg 			return SMP_CONFIRM_FAILED;
151138606f14SJohan Hedberg 
151238606f14SJohan Hedberg 		smp->passkey_round++;
151338606f14SJohan Hedberg 
151438606f14SJohan Hedberg 		if (smp->passkey_round == 20) {
151538606f14SJohan Hedberg 			/* Generate MacKey and LTK */
151638606f14SJohan Hedberg 			if (sc_mackey_and_ltk(smp, smp->mackey, smp->tk))
151738606f14SJohan Hedberg 				return SMP_UNSPECIFIED;
151838606f14SJohan Hedberg 		}
151938606f14SJohan Hedberg 
152038606f14SJohan Hedberg 		/* The round is only complete when the initiator
152138606f14SJohan Hedberg 		 * receives pairing random.
152238606f14SJohan Hedberg 		 */
152338606f14SJohan Hedberg 		if (!hcon->out) {
152438606f14SJohan Hedberg 			smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM,
152538606f14SJohan Hedberg 				     sizeof(smp->prnd), smp->prnd);
1526d3e54a87SJohan Hedberg 			if (smp->passkey_round == 20)
152738606f14SJohan Hedberg 				SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
1528d3e54a87SJohan Hedberg 			else
152938606f14SJohan Hedberg 				SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
153038606f14SJohan Hedberg 			return 0;
153138606f14SJohan Hedberg 		}
153238606f14SJohan Hedberg 
153338606f14SJohan Hedberg 		/* Start the next round */
153438606f14SJohan Hedberg 		if (smp->passkey_round != 20)
153538606f14SJohan Hedberg 			return sc_passkey_round(smp, 0);
153638606f14SJohan Hedberg 
153738606f14SJohan Hedberg 		/* Passkey rounds are complete - start DHKey Check */
153838606f14SJohan Hedberg 		sc_dhkey_check(smp);
153938606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
154038606f14SJohan Hedberg 
154138606f14SJohan Hedberg 		break;
154238606f14SJohan Hedberg 
154338606f14SJohan Hedberg 	case SMP_CMD_PAIRING_CONFIRM:
154438606f14SJohan Hedberg 		if (test_bit(SMP_FLAG_WAIT_USER, &smp->flags)) {
154538606f14SJohan Hedberg 			set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
154638606f14SJohan Hedberg 			return 0;
154738606f14SJohan Hedberg 		}
154838606f14SJohan Hedberg 
154938606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
155038606f14SJohan Hedberg 
155138606f14SJohan Hedberg 		if (hcon->out) {
155238606f14SJohan Hedberg 			smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM,
155338606f14SJohan Hedberg 				     sizeof(smp->prnd), smp->prnd);
155438606f14SJohan Hedberg 			return 0;
155538606f14SJohan Hedberg 		}
155638606f14SJohan Hedberg 
155738606f14SJohan Hedberg 		return sc_passkey_send_confirm(smp);
155838606f14SJohan Hedberg 
155938606f14SJohan Hedberg 	case SMP_CMD_PUBLIC_KEY:
156038606f14SJohan Hedberg 	default:
156138606f14SJohan Hedberg 		/* Initiating device starts the round */
156238606f14SJohan Hedberg 		if (!hcon->out)
156338606f14SJohan Hedberg 			return 0;
156438606f14SJohan Hedberg 
156538606f14SJohan Hedberg 		BT_DBG("%s Starting passkey round %u", hdev->name,
156638606f14SJohan Hedberg 		       smp->passkey_round + 1);
156738606f14SJohan Hedberg 
156838606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
156938606f14SJohan Hedberg 
157038606f14SJohan Hedberg 		return sc_passkey_send_confirm(smp);
157138606f14SJohan Hedberg 	}
157238606f14SJohan Hedberg 
157338606f14SJohan Hedberg 	return 0;
157438606f14SJohan Hedberg }
157538606f14SJohan Hedberg 
1576dddd3059SJohan Hedberg static int sc_user_reply(struct smp_chan *smp, u16 mgmt_op, __le32 passkey)
1577dddd3059SJohan Hedberg {
157838606f14SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
157938606f14SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
158038606f14SJohan Hedberg 	u8 smp_op;
158138606f14SJohan Hedberg 
158238606f14SJohan Hedberg 	clear_bit(SMP_FLAG_WAIT_USER, &smp->flags);
158338606f14SJohan Hedberg 
1584dddd3059SJohan Hedberg 	switch (mgmt_op) {
1585dddd3059SJohan Hedberg 	case MGMT_OP_USER_PASSKEY_NEG_REPLY:
1586dddd3059SJohan Hedberg 		smp_failure(smp->conn, SMP_PASSKEY_ENTRY_FAILED);
1587dddd3059SJohan Hedberg 		return 0;
1588dddd3059SJohan Hedberg 	case MGMT_OP_USER_CONFIRM_NEG_REPLY:
1589dddd3059SJohan Hedberg 		smp_failure(smp->conn, SMP_NUMERIC_COMP_FAILED);
1590dddd3059SJohan Hedberg 		return 0;
159138606f14SJohan Hedberg 	case MGMT_OP_USER_PASSKEY_REPLY:
159238606f14SJohan Hedberg 		hcon->passkey_notify = le32_to_cpu(passkey);
159338606f14SJohan Hedberg 		smp->passkey_round = 0;
159438606f14SJohan Hedberg 
159538606f14SJohan Hedberg 		if (test_and_clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags))
159638606f14SJohan Hedberg 			smp_op = SMP_CMD_PAIRING_CONFIRM;
159738606f14SJohan Hedberg 		else
159838606f14SJohan Hedberg 			smp_op = 0;
159938606f14SJohan Hedberg 
160038606f14SJohan Hedberg 		if (sc_passkey_round(smp, smp_op))
160138606f14SJohan Hedberg 			return -EIO;
160238606f14SJohan Hedberg 
160338606f14SJohan Hedberg 		return 0;
1604dddd3059SJohan Hedberg 	}
1605dddd3059SJohan Hedberg 
1606d3e54a87SJohan Hedberg 	/* Initiator sends DHKey check first */
1607d3e54a87SJohan Hedberg 	if (hcon->out) {
160838606f14SJohan Hedberg 		sc_dhkey_check(smp);
1609d3e54a87SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
1610d3e54a87SJohan Hedberg 	} else if (test_and_clear_bit(SMP_FLAG_DHKEY_PENDING, &smp->flags)) {
1611d3e54a87SJohan Hedberg 		sc_dhkey_check(smp);
1612d3e54a87SJohan Hedberg 		sc_add_ltk(smp);
1613d3e54a87SJohan Hedberg 	}
1614760b018bSJohan Hedberg 
1615760b018bSJohan Hedberg 	return 0;
1616760b018bSJohan Hedberg }
1617760b018bSJohan Hedberg 
16182b64d153SBrian Gix int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
16192b64d153SBrian Gix {
1620b10e8017SJohan Hedberg 	struct l2cap_conn *conn = hcon->l2cap_data;
16215d88cc73SJohan Hedberg 	struct l2cap_chan *chan;
16222b64d153SBrian Gix 	struct smp_chan *smp;
16232b64d153SBrian Gix 	u32 value;
1624fc75cc86SJohan Hedberg 	int err;
16252b64d153SBrian Gix 
16262b64d153SBrian Gix 	BT_DBG("");
16272b64d153SBrian Gix 
1628fc75cc86SJohan Hedberg 	if (!conn)
16292b64d153SBrian Gix 		return -ENOTCONN;
16302b64d153SBrian Gix 
16315d88cc73SJohan Hedberg 	chan = conn->smp;
16325d88cc73SJohan Hedberg 	if (!chan)
16335d88cc73SJohan Hedberg 		return -ENOTCONN;
16345d88cc73SJohan Hedberg 
1635fc75cc86SJohan Hedberg 	l2cap_chan_lock(chan);
1636fc75cc86SJohan Hedberg 	if (!chan->data) {
1637fc75cc86SJohan Hedberg 		err = -ENOTCONN;
1638fc75cc86SJohan Hedberg 		goto unlock;
1639fc75cc86SJohan Hedberg 	}
1640fc75cc86SJohan Hedberg 
16415d88cc73SJohan Hedberg 	smp = chan->data;
16422b64d153SBrian Gix 
1643760b018bSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
1644760b018bSJohan Hedberg 		err = sc_user_reply(smp, mgmt_op, passkey);
1645760b018bSJohan Hedberg 		goto unlock;
1646760b018bSJohan Hedberg 	}
1647760b018bSJohan Hedberg 
16482b64d153SBrian Gix 	switch (mgmt_op) {
16492b64d153SBrian Gix 	case MGMT_OP_USER_PASSKEY_REPLY:
16502b64d153SBrian Gix 		value = le32_to_cpu(passkey);
1651943a732aSJohan Hedberg 		memset(smp->tk, 0, sizeof(smp->tk));
16522b64d153SBrian Gix 		BT_DBG("PassKey: %d", value);
1653943a732aSJohan Hedberg 		put_unaligned_le32(value, smp->tk);
16542b64d153SBrian Gix 		/* Fall Through */
16552b64d153SBrian Gix 	case MGMT_OP_USER_CONFIRM_REPLY:
16564a74d658SJohan Hedberg 		set_bit(SMP_FLAG_TK_VALID, &smp->flags);
16572b64d153SBrian Gix 		break;
16582b64d153SBrian Gix 	case MGMT_OP_USER_PASSKEY_NEG_REPLY:
16592b64d153SBrian Gix 	case MGMT_OP_USER_CONFIRM_NEG_REPLY:
166084794e11SJohan Hedberg 		smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
1661fc75cc86SJohan Hedberg 		err = 0;
1662fc75cc86SJohan Hedberg 		goto unlock;
16632b64d153SBrian Gix 	default:
166484794e11SJohan Hedberg 		smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
1665fc75cc86SJohan Hedberg 		err = -EOPNOTSUPP;
1666fc75cc86SJohan Hedberg 		goto unlock;
16672b64d153SBrian Gix 	}
16682b64d153SBrian Gix 
1669fc75cc86SJohan Hedberg 	err = 0;
1670fc75cc86SJohan Hedberg 
16712b64d153SBrian Gix 	/* If it is our turn to send Pairing Confirm, do so now */
16721cc61144SJohan Hedberg 	if (test_bit(SMP_FLAG_CFM_PENDING, &smp->flags)) {
16731cc61144SJohan Hedberg 		u8 rsp = smp_confirm(smp);
16741cc61144SJohan Hedberg 		if (rsp)
16751cc61144SJohan Hedberg 			smp_failure(conn, rsp);
16761cc61144SJohan Hedberg 	}
16772b64d153SBrian Gix 
1678fc75cc86SJohan Hedberg unlock:
1679fc75cc86SJohan Hedberg 	l2cap_chan_unlock(chan);
1680fc75cc86SJohan Hedberg 	return err;
16812b64d153SBrian Gix }
16822b64d153SBrian Gix 
1683b5ae344dSJohan Hedberg static void build_bredr_pairing_cmd(struct smp_chan *smp,
1684b5ae344dSJohan Hedberg 				    struct smp_cmd_pairing *req,
1685b5ae344dSJohan Hedberg 				    struct smp_cmd_pairing *rsp)
1686b5ae344dSJohan Hedberg {
1687b5ae344dSJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
1688b5ae344dSJohan Hedberg 	struct hci_dev *hdev = conn->hcon->hdev;
1689b5ae344dSJohan Hedberg 	u8 local_dist = 0, remote_dist = 0;
1690b5ae344dSJohan Hedberg 
1691d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_BONDABLE)) {
1692b5ae344dSJohan Hedberg 		local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
1693b5ae344dSJohan Hedberg 		remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
1694b5ae344dSJohan Hedberg 	}
1695b5ae344dSJohan Hedberg 
1696d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_RPA_RESOLVING))
1697b5ae344dSJohan Hedberg 		remote_dist |= SMP_DIST_ID_KEY;
1698b5ae344dSJohan Hedberg 
1699d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_PRIVACY))
1700b5ae344dSJohan Hedberg 		local_dist |= SMP_DIST_ID_KEY;
1701b5ae344dSJohan Hedberg 
1702b5ae344dSJohan Hedberg 	if (!rsp) {
1703b5ae344dSJohan Hedberg 		memset(req, 0, sizeof(*req));
1704b5ae344dSJohan Hedberg 
1705b5ae344dSJohan Hedberg 		req->init_key_dist   = local_dist;
1706b5ae344dSJohan Hedberg 		req->resp_key_dist   = remote_dist;
1707b5ae344dSJohan Hedberg 		req->max_key_size    = SMP_MAX_ENC_KEY_SIZE;
1708b5ae344dSJohan Hedberg 
1709b5ae344dSJohan Hedberg 		smp->remote_key_dist = remote_dist;
1710b5ae344dSJohan Hedberg 
1711b5ae344dSJohan Hedberg 		return;
1712b5ae344dSJohan Hedberg 	}
1713b5ae344dSJohan Hedberg 
1714b5ae344dSJohan Hedberg 	memset(rsp, 0, sizeof(*rsp));
1715b5ae344dSJohan Hedberg 
1716b5ae344dSJohan Hedberg 	rsp->max_key_size    = SMP_MAX_ENC_KEY_SIZE;
1717b5ae344dSJohan Hedberg 	rsp->init_key_dist   = req->init_key_dist & remote_dist;
1718b5ae344dSJohan Hedberg 	rsp->resp_key_dist   = req->resp_key_dist & local_dist;
1719b5ae344dSJohan Hedberg 
1720b5ae344dSJohan Hedberg 	smp->remote_key_dist = rsp->init_key_dist;
1721b5ae344dSJohan Hedberg }
1722b5ae344dSJohan Hedberg 
1723da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
172488ba43b6SAnderson Briglia {
17253158c50cSVinicius Costa Gomes 	struct smp_cmd_pairing rsp, *req = (void *) skb->data;
1726fc75cc86SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
1727b3c6410bSJohan Hedberg 	struct hci_dev *hdev = conn->hcon->hdev;
17288aab4757SVinicius Costa Gomes 	struct smp_chan *smp;
1729c7262e71SJohan Hedberg 	u8 key_size, auth, sec_level;
17308aab4757SVinicius Costa Gomes 	int ret;
173188ba43b6SAnderson Briglia 
173288ba43b6SAnderson Briglia 	BT_DBG("conn %p", conn);
173388ba43b6SAnderson Briglia 
1734c46b98beSJohan Hedberg 	if (skb->len < sizeof(*req))
173538e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1736c46b98beSJohan Hedberg 
173740bef302SJohan Hedberg 	if (conn->hcon->role != HCI_ROLE_SLAVE)
17382b64d153SBrian Gix 		return SMP_CMD_NOTSUPP;
17392b64d153SBrian Gix 
1740fc75cc86SJohan Hedberg 	if (!chan->data)
17418aab4757SVinicius Costa Gomes 		smp = smp_chan_create(conn);
1742fc75cc86SJohan Hedberg 	else
17435d88cc73SJohan Hedberg 		smp = chan->data;
1744d26a2345SVinicius Costa Gomes 
1745d08fd0e7SAndrei Emeltchenko 	if (!smp)
1746d08fd0e7SAndrei Emeltchenko 		return SMP_UNSPECIFIED;
1747d08fd0e7SAndrei Emeltchenko 
1748c05b9339SJohan Hedberg 	/* We didn't start the pairing, so match remote */
17490edb14deSJohan Hedberg 	auth = req->auth_req & AUTH_REQ_MASK(hdev);
1750c05b9339SJohan Hedberg 
1751d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BONDABLE) &&
1752c05b9339SJohan Hedberg 	    (auth & SMP_AUTH_BONDING))
1753b3c6410bSJohan Hedberg 		return SMP_PAIRING_NOTSUPP;
1754b3c6410bSJohan Hedberg 
1755d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SC_ONLY) && !(auth & SMP_AUTH_SC))
1756903b71c7SJohan Hedberg 		return SMP_AUTH_REQUIREMENTS;
1757903b71c7SJohan Hedberg 
17581c1def09SVinicius Costa Gomes 	smp->preq[0] = SMP_CMD_PAIRING_REQ;
17591c1def09SVinicius Costa Gomes 	memcpy(&smp->preq[1], req, sizeof(*req));
17603158c50cSVinicius Costa Gomes 	skb_pull(skb, sizeof(*req));
176188ba43b6SAnderson Briglia 
1762cb06d366SJohan Hedberg 	/* If the remote side's OOB flag is set it means it has
1763cb06d366SJohan Hedberg 	 * successfully received our local OOB data - therefore set the
1764cb06d366SJohan Hedberg 	 * flag to indicate that local OOB is in use.
1765cb06d366SJohan Hedberg 	 */
176658428563SJohan Hedberg 	if (req->oob_flag == SMP_OOB_PRESENT)
176758428563SJohan Hedberg 		set_bit(SMP_FLAG_LOCAL_OOB, &smp->flags);
176858428563SJohan Hedberg 
1769b5ae344dSJohan Hedberg 	/* SMP over BR/EDR requires special treatment */
1770b5ae344dSJohan Hedberg 	if (conn->hcon->type == ACL_LINK) {
1771b5ae344dSJohan Hedberg 		/* We must have a BR/EDR SC link */
177208f63cc5SMarcel Holtmann 		if (!test_bit(HCI_CONN_AES_CCM, &conn->hcon->flags) &&
1773b7cb93e5SMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP))
1774b5ae344dSJohan Hedberg 			return SMP_CROSS_TRANSP_NOT_ALLOWED;
1775b5ae344dSJohan Hedberg 
1776b5ae344dSJohan Hedberg 		set_bit(SMP_FLAG_SC, &smp->flags);
1777b5ae344dSJohan Hedberg 
1778b5ae344dSJohan Hedberg 		build_bredr_pairing_cmd(smp, req, &rsp);
1779b5ae344dSJohan Hedberg 
1780b5ae344dSJohan Hedberg 		key_size = min(req->max_key_size, rsp.max_key_size);
1781b5ae344dSJohan Hedberg 		if (check_enc_key_size(conn, key_size))
1782b5ae344dSJohan Hedberg 			return SMP_ENC_KEY_SIZE;
1783b5ae344dSJohan Hedberg 
1784b5ae344dSJohan Hedberg 		/* Clear bits which are generated but not distributed */
1785b5ae344dSJohan Hedberg 		smp->remote_key_dist &= ~SMP_SC_NO_DIST;
1786b5ae344dSJohan Hedberg 
1787b5ae344dSJohan Hedberg 		smp->prsp[0] = SMP_CMD_PAIRING_RSP;
1788b5ae344dSJohan Hedberg 		memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
1789b5ae344dSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
1790b5ae344dSJohan Hedberg 
1791b5ae344dSJohan Hedberg 		smp_distribute_keys(smp);
1792b5ae344dSJohan Hedberg 		return 0;
1793b5ae344dSJohan Hedberg 	}
1794b5ae344dSJohan Hedberg 
17955e3d3d9bSJohan Hedberg 	build_pairing_cmd(conn, req, &rsp, auth);
17965e3d3d9bSJohan Hedberg 
17975e3d3d9bSJohan Hedberg 	if (rsp.auth_req & SMP_AUTH_SC)
17985e3d3d9bSJohan Hedberg 		set_bit(SMP_FLAG_SC, &smp->flags);
17995e3d3d9bSJohan Hedberg 
18005be5e275SJohan Hedberg 	if (conn->hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
18011afc2a1aSJohan Hedberg 		sec_level = BT_SECURITY_MEDIUM;
18021afc2a1aSJohan Hedberg 	else
1803c7262e71SJohan Hedberg 		sec_level = authreq_to_seclevel(auth);
18041afc2a1aSJohan Hedberg 
1805c7262e71SJohan Hedberg 	if (sec_level > conn->hcon->pending_sec_level)
1806c7262e71SJohan Hedberg 		conn->hcon->pending_sec_level = sec_level;
1807fdde0a26SIdo Yariv 
180849c922bbSStephen Hemminger 	/* If we need MITM check that it can be achieved */
18092ed8f65cSJohan Hedberg 	if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
18102ed8f65cSJohan Hedberg 		u8 method;
18112ed8f65cSJohan Hedberg 
18122ed8f65cSJohan Hedberg 		method = get_auth_method(smp, conn->hcon->io_capability,
18132ed8f65cSJohan Hedberg 					 req->io_capability);
18142ed8f65cSJohan Hedberg 		if (method == JUST_WORKS || method == JUST_CFM)
18152ed8f65cSJohan Hedberg 			return SMP_AUTH_REQUIREMENTS;
18162ed8f65cSJohan Hedberg 	}
18172ed8f65cSJohan Hedberg 
18183158c50cSVinicius Costa Gomes 	key_size = min(req->max_key_size, rsp.max_key_size);
18193158c50cSVinicius Costa Gomes 	if (check_enc_key_size(conn, key_size))
18203158c50cSVinicius Costa Gomes 		return SMP_ENC_KEY_SIZE;
182188ba43b6SAnderson Briglia 
1822e84a6b13SJohan Hedberg 	get_random_bytes(smp->prnd, sizeof(smp->prnd));
18238aab4757SVinicius Costa Gomes 
18241c1def09SVinicius Costa Gomes 	smp->prsp[0] = SMP_CMD_PAIRING_RSP;
18251c1def09SVinicius Costa Gomes 	memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
1826f01ead31SAnderson Briglia 
18273158c50cSVinicius Costa Gomes 	smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
18283b19146dSJohan Hedberg 
18293b19146dSJohan Hedberg 	clear_bit(SMP_FLAG_INITIATOR, &smp->flags);
18303b19146dSJohan Hedberg 
183119c5ce9cSJohan Hedberg 	/* Strictly speaking we shouldn't allow Pairing Confirm for the
183219c5ce9cSJohan Hedberg 	 * SC case, however some implementations incorrectly copy RFU auth
183319c5ce9cSJohan Hedberg 	 * req bits from our security request, which may create a false
183419c5ce9cSJohan Hedberg 	 * positive SC enablement.
183519c5ce9cSJohan Hedberg 	 */
183619c5ce9cSJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
183719c5ce9cSJohan Hedberg 
18383b19146dSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
18393b19146dSJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PUBLIC_KEY);
18403b19146dSJohan Hedberg 		/* Clear bits which are generated but not distributed */
18413b19146dSJohan Hedberg 		smp->remote_key_dist &= ~SMP_SC_NO_DIST;
18423b19146dSJohan Hedberg 		/* Wait for Public Key from Initiating Device */
18433b19146dSJohan Hedberg 		return 0;
18443b19146dSJohan Hedberg 	}
1845da85e5e5SVinicius Costa Gomes 
18462b64d153SBrian Gix 	/* Request setup of TK */
18472b64d153SBrian Gix 	ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability);
18482b64d153SBrian Gix 	if (ret)
18492b64d153SBrian Gix 		return SMP_UNSPECIFIED;
18502b64d153SBrian Gix 
1851da85e5e5SVinicius Costa Gomes 	return 0;
185288ba43b6SAnderson Briglia }
185388ba43b6SAnderson Briglia 
18543b19146dSJohan Hedberg static u8 sc_send_public_key(struct smp_chan *smp)
18553b19146dSJohan Hedberg {
185670157ef5SJohan Hedberg 	struct hci_dev *hdev = smp->conn->hcon->hdev;
185770157ef5SJohan Hedberg 
18583b19146dSJohan Hedberg 	BT_DBG("");
18593b19146dSJohan Hedberg 
18601a8bab4fSJohan Hedberg 	if (test_bit(SMP_FLAG_LOCAL_OOB, &smp->flags)) {
186133d0c030SMarcel Holtmann 		struct l2cap_chan *chan = hdev->smp_data;
186233d0c030SMarcel Holtmann 		struct smp_dev *smp_dev;
186333d0c030SMarcel Holtmann 
186433d0c030SMarcel Holtmann 		if (!chan || !chan->data)
186533d0c030SMarcel Holtmann 			return SMP_UNSPECIFIED;
186633d0c030SMarcel Holtmann 
186733d0c030SMarcel Holtmann 		smp_dev = chan->data;
186833d0c030SMarcel Holtmann 
186933d0c030SMarcel Holtmann 		memcpy(smp->local_pk, smp_dev->local_pk, 64);
187033d0c030SMarcel Holtmann 		memcpy(smp->local_sk, smp_dev->local_sk, 32);
1871fb334feeSMarcel Holtmann 		memcpy(smp->lr, smp_dev->local_rand, 16);
187233d0c030SMarcel Holtmann 
187333d0c030SMarcel Holtmann 		if (smp_dev->debug_key)
187433d0c030SMarcel Holtmann 			set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags);
187533d0c030SMarcel Holtmann 
187633d0c030SMarcel Holtmann 		goto done;
187733d0c030SMarcel Holtmann 	}
187833d0c030SMarcel Holtmann 
1879d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS)) {
188070157ef5SJohan Hedberg 		BT_DBG("Using debug keys");
188170157ef5SJohan Hedberg 		memcpy(smp->local_pk, debug_pk, 64);
188270157ef5SJohan Hedberg 		memcpy(smp->local_sk, debug_sk, 32);
188370157ef5SJohan Hedberg 		set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags);
188470157ef5SJohan Hedberg 	} else {
18856c0dcc50SJohan Hedberg 		while (true) {
18863b19146dSJohan Hedberg 			/* Generate local key pair for Secure Connections */
18873b19146dSJohan Hedberg 			if (!ecc_make_key(smp->local_pk, smp->local_sk))
18883b19146dSJohan Hedberg 				return SMP_UNSPECIFIED;
18893b19146dSJohan Hedberg 
189070157ef5SJohan Hedberg 			/* This is unlikely, but we need to check that
189170157ef5SJohan Hedberg 			 * we didn't accidentially generate a debug key.
18926c0dcc50SJohan Hedberg 			 */
18936c0dcc50SJohan Hedberg 			if (memcmp(smp->local_sk, debug_sk, 32))
18946c0dcc50SJohan Hedberg 				break;
18956c0dcc50SJohan Hedberg 		}
189670157ef5SJohan Hedberg 	}
18976c0dcc50SJohan Hedberg 
189833d0c030SMarcel Holtmann done:
1899c7a3d57dSJohan Hedberg 	SMP_DBG("Local Public Key X: %32phN", smp->local_pk);
19008e4e2ee5SMarcel Holtmann 	SMP_DBG("Local Public Key Y: %32phN", smp->local_pk + 32);
1901c7a3d57dSJohan Hedberg 	SMP_DBG("Local Private Key:  %32phN", smp->local_sk);
19023b19146dSJohan Hedberg 
19033b19146dSJohan Hedberg 	smp_send_cmd(smp->conn, SMP_CMD_PUBLIC_KEY, 64, smp->local_pk);
19043b19146dSJohan Hedberg 
19053b19146dSJohan Hedberg 	return 0;
19063b19146dSJohan Hedberg }
19073b19146dSJohan Hedberg 
1908da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
190988ba43b6SAnderson Briglia {
19103158c50cSVinicius Costa Gomes 	struct smp_cmd_pairing *req, *rsp = (void *) skb->data;
19115d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
19125d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
19130edb14deSJohan Hedberg 	struct hci_dev *hdev = conn->hcon->hdev;
19143a7dbfb8SJohan Hedberg 	u8 key_size, auth;
19157d24ddccSAnderson Briglia 	int ret;
191688ba43b6SAnderson Briglia 
191788ba43b6SAnderson Briglia 	BT_DBG("conn %p", conn);
191888ba43b6SAnderson Briglia 
1919c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rsp))
192038e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1921c46b98beSJohan Hedberg 
192240bef302SJohan Hedberg 	if (conn->hcon->role != HCI_ROLE_MASTER)
19232b64d153SBrian Gix 		return SMP_CMD_NOTSUPP;
19242b64d153SBrian Gix 
19253158c50cSVinicius Costa Gomes 	skb_pull(skb, sizeof(*rsp));
1926da85e5e5SVinicius Costa Gomes 
19271c1def09SVinicius Costa Gomes 	req = (void *) &smp->preq[1];
19283158c50cSVinicius Costa Gomes 
19293158c50cSVinicius Costa Gomes 	key_size = min(req->max_key_size, rsp->max_key_size);
19303158c50cSVinicius Costa Gomes 	if (check_enc_key_size(conn, key_size))
19313158c50cSVinicius Costa Gomes 		return SMP_ENC_KEY_SIZE;
19323158c50cSVinicius Costa Gomes 
19330edb14deSJohan Hedberg 	auth = rsp->auth_req & AUTH_REQ_MASK(hdev);
1934c05b9339SJohan Hedberg 
1935d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SC_ONLY) && !(auth & SMP_AUTH_SC))
1936903b71c7SJohan Hedberg 		return SMP_AUTH_REQUIREMENTS;
1937903b71c7SJohan Hedberg 
1938cb06d366SJohan Hedberg 	/* If the remote side's OOB flag is set it means it has
1939cb06d366SJohan Hedberg 	 * successfully received our local OOB data - therefore set the
1940cb06d366SJohan Hedberg 	 * flag to indicate that local OOB is in use.
1941cb06d366SJohan Hedberg 	 */
194258428563SJohan Hedberg 	if (rsp->oob_flag == SMP_OOB_PRESENT)
194358428563SJohan Hedberg 		set_bit(SMP_FLAG_LOCAL_OOB, &smp->flags);
194458428563SJohan Hedberg 
1945b5ae344dSJohan Hedberg 	smp->prsp[0] = SMP_CMD_PAIRING_RSP;
1946b5ae344dSJohan Hedberg 	memcpy(&smp->prsp[1], rsp, sizeof(*rsp));
1947b5ae344dSJohan Hedberg 
1948b5ae344dSJohan Hedberg 	/* Update remote key distribution in case the remote cleared
1949b5ae344dSJohan Hedberg 	 * some bits that we had enabled in our request.
1950b5ae344dSJohan Hedberg 	 */
1951b5ae344dSJohan Hedberg 	smp->remote_key_dist &= rsp->resp_key_dist;
1952b5ae344dSJohan Hedberg 
1953b5ae344dSJohan Hedberg 	/* For BR/EDR this means we're done and can start phase 3 */
1954b5ae344dSJohan Hedberg 	if (conn->hcon->type == ACL_LINK) {
1955b5ae344dSJohan Hedberg 		/* Clear bits which are generated but not distributed */
1956b5ae344dSJohan Hedberg 		smp->remote_key_dist &= ~SMP_SC_NO_DIST;
1957b5ae344dSJohan Hedberg 		smp_distribute_keys(smp);
1958b5ae344dSJohan Hedberg 		return 0;
1959b5ae344dSJohan Hedberg 	}
1960b5ae344dSJohan Hedberg 
196165668776SJohan Hedberg 	if ((req->auth_req & SMP_AUTH_SC) && (auth & SMP_AUTH_SC))
196265668776SJohan Hedberg 		set_bit(SMP_FLAG_SC, &smp->flags);
1963d2eb9e10SJohan Hedberg 	else if (conn->hcon->pending_sec_level > BT_SECURITY_HIGH)
1964d2eb9e10SJohan Hedberg 		conn->hcon->pending_sec_level = BT_SECURITY_HIGH;
196565668776SJohan Hedberg 
196649c922bbSStephen Hemminger 	/* If we need MITM check that it can be achieved */
19672ed8f65cSJohan Hedberg 	if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
19682ed8f65cSJohan Hedberg 		u8 method;
19692ed8f65cSJohan Hedberg 
19702ed8f65cSJohan Hedberg 		method = get_auth_method(smp, req->io_capability,
19712ed8f65cSJohan Hedberg 					 rsp->io_capability);
19722ed8f65cSJohan Hedberg 		if (method == JUST_WORKS || method == JUST_CFM)
19732ed8f65cSJohan Hedberg 			return SMP_AUTH_REQUIREMENTS;
19742ed8f65cSJohan Hedberg 	}
19752ed8f65cSJohan Hedberg 
1976e84a6b13SJohan Hedberg 	get_random_bytes(smp->prnd, sizeof(smp->prnd));
19777d24ddccSAnderson Briglia 
1978fdcc4becSJohan Hedberg 	/* Update remote key distribution in case the remote cleared
1979fdcc4becSJohan Hedberg 	 * some bits that we had enabled in our request.
1980fdcc4becSJohan Hedberg 	 */
1981fdcc4becSJohan Hedberg 	smp->remote_key_dist &= rsp->resp_key_dist;
1982fdcc4becSJohan Hedberg 
19833b19146dSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
19843b19146dSJohan Hedberg 		/* Clear bits which are generated but not distributed */
19853b19146dSJohan Hedberg 		smp->remote_key_dist &= ~SMP_SC_NO_DIST;
19863b19146dSJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PUBLIC_KEY);
19873b19146dSJohan Hedberg 		return sc_send_public_key(smp);
19883b19146dSJohan Hedberg 	}
19893b19146dSJohan Hedberg 
1990c05b9339SJohan Hedberg 	auth |= req->auth_req;
19912b64d153SBrian Gix 
1992476585ecSJohan Hedberg 	ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability);
19932b64d153SBrian Gix 	if (ret)
19942b64d153SBrian Gix 		return SMP_UNSPECIFIED;
19952b64d153SBrian Gix 
19964a74d658SJohan Hedberg 	set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
19972b64d153SBrian Gix 
19982b64d153SBrian Gix 	/* Can't compose response until we have been confirmed */
19994a74d658SJohan Hedberg 	if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
20001cc61144SJohan Hedberg 		return smp_confirm(smp);
2001da85e5e5SVinicius Costa Gomes 
2002da85e5e5SVinicius Costa Gomes 	return 0;
200388ba43b6SAnderson Briglia }
200488ba43b6SAnderson Briglia 
2005dcee2b32SJohan Hedberg static u8 sc_check_confirm(struct smp_chan *smp)
2006dcee2b32SJohan Hedberg {
2007dcee2b32SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
2008dcee2b32SJohan Hedberg 
2009dcee2b32SJohan Hedberg 	BT_DBG("");
2010dcee2b32SJohan Hedberg 
201138606f14SJohan Hedberg 	if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY)
201238606f14SJohan Hedberg 		return sc_passkey_round(smp, SMP_CMD_PAIRING_CONFIRM);
201338606f14SJohan Hedberg 
2014dcee2b32SJohan Hedberg 	if (conn->hcon->out) {
2015dcee2b32SJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
2016dcee2b32SJohan Hedberg 			     smp->prnd);
2017dcee2b32SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
2018dcee2b32SJohan Hedberg 	}
2019dcee2b32SJohan Hedberg 
2020dcee2b32SJohan Hedberg 	return 0;
2021dcee2b32SJohan Hedberg }
2022dcee2b32SJohan Hedberg 
202319c5ce9cSJohan Hedberg /* Work-around for some implementations that incorrectly copy RFU bits
202419c5ce9cSJohan Hedberg  * from our security request and thereby create the impression that
202519c5ce9cSJohan Hedberg  * we're doing SC when in fact the remote doesn't support it.
202619c5ce9cSJohan Hedberg  */
202719c5ce9cSJohan Hedberg static int fixup_sc_false_positive(struct smp_chan *smp)
202819c5ce9cSJohan Hedberg {
202919c5ce9cSJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
203019c5ce9cSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
203119c5ce9cSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
203219c5ce9cSJohan Hedberg 	struct smp_cmd_pairing *req, *rsp;
203319c5ce9cSJohan Hedberg 	u8 auth;
203419c5ce9cSJohan Hedberg 
203519c5ce9cSJohan Hedberg 	/* The issue is only observed when we're in slave role */
203619c5ce9cSJohan Hedberg 	if (hcon->out)
203719c5ce9cSJohan Hedberg 		return SMP_UNSPECIFIED;
203819c5ce9cSJohan Hedberg 
203919c5ce9cSJohan Hedberg 	if (hci_dev_test_flag(hdev, HCI_SC_ONLY)) {
204019c5ce9cSJohan Hedberg 		BT_ERR("Refusing SMP SC -> legacy fallback in SC-only mode");
204119c5ce9cSJohan Hedberg 		return SMP_UNSPECIFIED;
204219c5ce9cSJohan Hedberg 	}
204319c5ce9cSJohan Hedberg 
204419c5ce9cSJohan Hedberg 	BT_ERR("Trying to fall back to legacy SMP");
204519c5ce9cSJohan Hedberg 
204619c5ce9cSJohan Hedberg 	req = (void *) &smp->preq[1];
204719c5ce9cSJohan Hedberg 	rsp = (void *) &smp->prsp[1];
204819c5ce9cSJohan Hedberg 
204919c5ce9cSJohan Hedberg 	/* Rebuild key dist flags which may have been cleared for SC */
205019c5ce9cSJohan Hedberg 	smp->remote_key_dist = (req->init_key_dist & rsp->resp_key_dist);
205119c5ce9cSJohan Hedberg 
205219c5ce9cSJohan Hedberg 	auth = req->auth_req & AUTH_REQ_MASK(hdev);
205319c5ce9cSJohan Hedberg 
205419c5ce9cSJohan Hedberg 	if (tk_request(conn, 0, auth, rsp->io_capability, req->io_capability)) {
205519c5ce9cSJohan Hedberg 		BT_ERR("Failed to fall back to legacy SMP");
205619c5ce9cSJohan Hedberg 		return SMP_UNSPECIFIED;
205719c5ce9cSJohan Hedberg 	}
205819c5ce9cSJohan Hedberg 
205919c5ce9cSJohan Hedberg 	clear_bit(SMP_FLAG_SC, &smp->flags);
206019c5ce9cSJohan Hedberg 
206119c5ce9cSJohan Hedberg 	return 0;
206219c5ce9cSJohan Hedberg }
206319c5ce9cSJohan Hedberg 
2064da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
206588ba43b6SAnderson Briglia {
20665d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
20675d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
20687d24ddccSAnderson Briglia 
206988ba43b6SAnderson Briglia 	BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
207088ba43b6SAnderson Briglia 
2071c46b98beSJohan Hedberg 	if (skb->len < sizeof(smp->pcnf))
207238e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2073c46b98beSJohan Hedberg 
20741c1def09SVinicius Costa Gomes 	memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf));
20751c1def09SVinicius Costa Gomes 	skb_pull(skb, sizeof(smp->pcnf));
20767d24ddccSAnderson Briglia 
207719c5ce9cSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
207819c5ce9cSJohan Hedberg 		int ret;
207919c5ce9cSJohan Hedberg 
208019c5ce9cSJohan Hedberg 		/* Public Key exchange must happen before any other steps */
208119c5ce9cSJohan Hedberg 		if (test_bit(SMP_FLAG_REMOTE_PK, &smp->flags))
2082dcee2b32SJohan Hedberg 			return sc_check_confirm(smp);
2083dcee2b32SJohan Hedberg 
208419c5ce9cSJohan Hedberg 		BT_ERR("Unexpected SMP Pairing Confirm");
208519c5ce9cSJohan Hedberg 
208619c5ce9cSJohan Hedberg 		ret = fixup_sc_false_positive(smp);
208719c5ce9cSJohan Hedberg 		if (ret)
208819c5ce9cSJohan Hedberg 			return ret;
208919c5ce9cSJohan Hedberg 	}
209019c5ce9cSJohan Hedberg 
2091b28b4943SJohan Hedberg 	if (conn->hcon->out) {
2092943a732aSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
2093943a732aSJohan Hedberg 			     smp->prnd);
2094b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
2095b28b4943SJohan Hedberg 		return 0;
2096b28b4943SJohan Hedberg 	}
2097b28b4943SJohan Hedberg 
2098b28b4943SJohan Hedberg 	if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
20991cc61144SJohan Hedberg 		return smp_confirm(smp);
2100983f9814SMarcel Holtmann 
21014a74d658SJohan Hedberg 	set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
2102da85e5e5SVinicius Costa Gomes 
2103da85e5e5SVinicius Costa Gomes 	return 0;
210488ba43b6SAnderson Briglia }
210588ba43b6SAnderson Briglia 
2106da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
210788ba43b6SAnderson Briglia {
21085d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
21095d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
2110191dc7feSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
2111191dc7feSJohan Hedberg 	u8 *pkax, *pkbx, *na, *nb;
2112191dc7feSJohan Hedberg 	u32 passkey;
2113191dc7feSJohan Hedberg 	int err;
21147d24ddccSAnderson Briglia 
21158aab4757SVinicius Costa Gomes 	BT_DBG("conn %p", conn);
21167d24ddccSAnderson Briglia 
2117c46b98beSJohan Hedberg 	if (skb->len < sizeof(smp->rrnd))
211838e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2119c46b98beSJohan Hedberg 
2120943a732aSJohan Hedberg 	memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd));
21218aab4757SVinicius Costa Gomes 	skb_pull(skb, sizeof(smp->rrnd));
212288ba43b6SAnderson Briglia 
2123191dc7feSJohan Hedberg 	if (!test_bit(SMP_FLAG_SC, &smp->flags))
2124861580a9SJohan Hedberg 		return smp_random(smp);
2125191dc7feSJohan Hedberg 
2126580039e8SJohan Hedberg 	if (hcon->out) {
2127580039e8SJohan Hedberg 		pkax = smp->local_pk;
2128580039e8SJohan Hedberg 		pkbx = smp->remote_pk;
2129580039e8SJohan Hedberg 		na   = smp->prnd;
2130580039e8SJohan Hedberg 		nb   = smp->rrnd;
2131580039e8SJohan Hedberg 	} else {
2132580039e8SJohan Hedberg 		pkax = smp->remote_pk;
2133580039e8SJohan Hedberg 		pkbx = smp->local_pk;
2134580039e8SJohan Hedberg 		na   = smp->rrnd;
2135580039e8SJohan Hedberg 		nb   = smp->prnd;
2136580039e8SJohan Hedberg 	}
2137580039e8SJohan Hedberg 
2138a29b0733SJohan Hedberg 	if (smp->method == REQ_OOB) {
2139a29b0733SJohan Hedberg 		if (!hcon->out)
2140a29b0733SJohan Hedberg 			smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM,
2141a29b0733SJohan Hedberg 				     sizeof(smp->prnd), smp->prnd);
2142a29b0733SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
2143a29b0733SJohan Hedberg 		goto mackey_and_ltk;
2144a29b0733SJohan Hedberg 	}
2145a29b0733SJohan Hedberg 
214638606f14SJohan Hedberg 	/* Passkey entry has special treatment */
214738606f14SJohan Hedberg 	if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY)
214838606f14SJohan Hedberg 		return sc_passkey_round(smp, SMP_CMD_PAIRING_RANDOM);
214938606f14SJohan Hedberg 
2150191dc7feSJohan Hedberg 	if (hcon->out) {
2151191dc7feSJohan Hedberg 		u8 cfm[16];
2152191dc7feSJohan Hedberg 
2153191dc7feSJohan Hedberg 		err = smp_f4(smp->tfm_cmac, smp->remote_pk, smp->local_pk,
2154191dc7feSJohan Hedberg 			     smp->rrnd, 0, cfm);
2155191dc7feSJohan Hedberg 		if (err)
2156191dc7feSJohan Hedberg 			return SMP_UNSPECIFIED;
2157191dc7feSJohan Hedberg 
2158191dc7feSJohan Hedberg 		if (memcmp(smp->pcnf, cfm, 16))
2159191dc7feSJohan Hedberg 			return SMP_CONFIRM_FAILED;
2160191dc7feSJohan Hedberg 	} else {
2161191dc7feSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
2162191dc7feSJohan Hedberg 			     smp->prnd);
2163191dc7feSJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
2164191dc7feSJohan Hedberg 	}
2165191dc7feSJohan Hedberg 
2166a29b0733SJohan Hedberg mackey_and_ltk:
2167760b018bSJohan Hedberg 	/* Generate MacKey and LTK */
2168760b018bSJohan Hedberg 	err = sc_mackey_and_ltk(smp, smp->mackey, smp->tk);
2169760b018bSJohan Hedberg 	if (err)
2170760b018bSJohan Hedberg 		return SMP_UNSPECIFIED;
2171760b018bSJohan Hedberg 
2172a29b0733SJohan Hedberg 	if (smp->method == JUST_WORKS || smp->method == REQ_OOB) {
2173dddd3059SJohan Hedberg 		if (hcon->out) {
217438606f14SJohan Hedberg 			sc_dhkey_check(smp);
2175dddd3059SJohan Hedberg 			SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
2176dddd3059SJohan Hedberg 		}
2177dddd3059SJohan Hedberg 		return 0;
2178dddd3059SJohan Hedberg 	}
2179dddd3059SJohan Hedberg 
218038606f14SJohan Hedberg 	err = smp_g2(smp->tfm_cmac, pkax, pkbx, na, nb, &passkey);
2181191dc7feSJohan Hedberg 	if (err)
2182191dc7feSJohan Hedberg 		return SMP_UNSPECIFIED;
2183191dc7feSJohan Hedberg 
218438606f14SJohan Hedberg 	err = mgmt_user_confirm_request(hcon->hdev, &hcon->dst, hcon->type,
218538606f14SJohan Hedberg 					hcon->dst_type, passkey, 0);
218638606f14SJohan Hedberg 	if (err)
218738606f14SJohan Hedberg 		return SMP_UNSPECIFIED;
218838606f14SJohan Hedberg 
218938606f14SJohan Hedberg 	set_bit(SMP_FLAG_WAIT_USER, &smp->flags);
219038606f14SJohan Hedberg 
2191191dc7feSJohan Hedberg 	return 0;
219288ba43b6SAnderson Briglia }
219388ba43b6SAnderson Briglia 
2194f81cd823SMarcel Holtmann static bool smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
2195988c5997SVinicius Costa Gomes {
2196c9839a11SVinicius Costa Gomes 	struct smp_ltk *key;
2197988c5997SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
2198988c5997SVinicius Costa Gomes 
2199f3a73d97SJohan Hedberg 	key = hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, hcon->role);
2200988c5997SVinicius Costa Gomes 	if (!key)
2201f81cd823SMarcel Holtmann 		return false;
2202988c5997SVinicius Costa Gomes 
2203a6f7833cSJohan Hedberg 	if (smp_ltk_sec_level(key) < sec_level)
2204f81cd823SMarcel Holtmann 		return false;
22054dab7864SJohan Hedberg 
220651a8efd7SJohan Hedberg 	if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
2207f81cd823SMarcel Holtmann 		return true;
2208988c5997SVinicius Costa Gomes 
22098b76ce34SJohan Hedberg 	hci_le_start_enc(hcon, key->ediv, key->rand, key->val, key->enc_size);
2210c9839a11SVinicius Costa Gomes 	hcon->enc_key_size = key->enc_size;
2211988c5997SVinicius Costa Gomes 
2212fe59a05fSJohan Hedberg 	/* We never store STKs for master role, so clear this flag */
2213fe59a05fSJohan Hedberg 	clear_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags);
2214fe59a05fSJohan Hedberg 
2215f81cd823SMarcel Holtmann 	return true;
2216988c5997SVinicius Costa Gomes }
2217f1560463SMarcel Holtmann 
221835dc6f83SJohan Hedberg bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level,
221935dc6f83SJohan Hedberg 			     enum smp_key_pref key_pref)
2220854f4727SJohan Hedberg {
2221854f4727SJohan Hedberg 	if (sec_level == BT_SECURITY_LOW)
2222854f4727SJohan Hedberg 		return true;
2223854f4727SJohan Hedberg 
222435dc6f83SJohan Hedberg 	/* If we're encrypted with an STK but the caller prefers using
222535dc6f83SJohan Hedberg 	 * LTK claim insufficient security. This way we allow the
222635dc6f83SJohan Hedberg 	 * connection to be re-encrypted with an LTK, even if the LTK
222735dc6f83SJohan Hedberg 	 * provides the same level of security. Only exception is if we
222835dc6f83SJohan Hedberg 	 * don't have an LTK (e.g. because of key distribution bits).
22299ab65d60SJohan Hedberg 	 */
223035dc6f83SJohan Hedberg 	if (key_pref == SMP_USE_LTK &&
223135dc6f83SJohan Hedberg 	    test_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags) &&
2232f3a73d97SJohan Hedberg 	    hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, hcon->role))
22339ab65d60SJohan Hedberg 		return false;
22349ab65d60SJohan Hedberg 
2235854f4727SJohan Hedberg 	if (hcon->sec_level >= sec_level)
2236854f4727SJohan Hedberg 		return true;
2237854f4727SJohan Hedberg 
2238854f4727SJohan Hedberg 	return false;
2239854f4727SJohan Hedberg }
2240854f4727SJohan Hedberg 
2241da85e5e5SVinicius Costa Gomes static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
224288ba43b6SAnderson Briglia {
224388ba43b6SAnderson Briglia 	struct smp_cmd_security_req *rp = (void *) skb->data;
224488ba43b6SAnderson Briglia 	struct smp_cmd_pairing cp;
2245f1cb9af5SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
22460edb14deSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
22478aab4757SVinicius Costa Gomes 	struct smp_chan *smp;
2248c05b9339SJohan Hedberg 	u8 sec_level, auth;
224988ba43b6SAnderson Briglia 
225088ba43b6SAnderson Briglia 	BT_DBG("conn %p", conn);
225188ba43b6SAnderson Briglia 
2252c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rp))
225338e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2254c46b98beSJohan Hedberg 
225540bef302SJohan Hedberg 	if (hcon->role != HCI_ROLE_MASTER)
225686ca9eacSJohan Hedberg 		return SMP_CMD_NOTSUPP;
225786ca9eacSJohan Hedberg 
22580edb14deSJohan Hedberg 	auth = rp->auth_req & AUTH_REQ_MASK(hdev);
2259c05b9339SJohan Hedberg 
2260d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SC_ONLY) && !(auth & SMP_AUTH_SC))
2261903b71c7SJohan Hedberg 		return SMP_AUTH_REQUIREMENTS;
2262903b71c7SJohan Hedberg 
22635be5e275SJohan Hedberg 	if (hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
22641afc2a1aSJohan Hedberg 		sec_level = BT_SECURITY_MEDIUM;
22651afc2a1aSJohan Hedberg 	else
2266c05b9339SJohan Hedberg 		sec_level = authreq_to_seclevel(auth);
22671afc2a1aSJohan Hedberg 
226835dc6f83SJohan Hedberg 	if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK))
2269854f4727SJohan Hedberg 		return 0;
2270854f4727SJohan Hedberg 
2271c7262e71SJohan Hedberg 	if (sec_level > hcon->pending_sec_level)
2272c7262e71SJohan Hedberg 		hcon->pending_sec_level = sec_level;
2273feb45eb5SVinicius Costa Gomes 
22744dab7864SJohan Hedberg 	if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
2275988c5997SVinicius Costa Gomes 		return 0;
2276988c5997SVinicius Costa Gomes 
22778aab4757SVinicius Costa Gomes 	smp = smp_chan_create(conn);
2278c29d2444SJohan Hedberg 	if (!smp)
2279c29d2444SJohan Hedberg 		return SMP_UNSPECIFIED;
2280d26a2345SVinicius Costa Gomes 
2281d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BONDABLE) &&
2282c05b9339SJohan Hedberg 	    (auth & SMP_AUTH_BONDING))
2283616d55beSJohan Hedberg 		return SMP_PAIRING_NOTSUPP;
2284616d55beSJohan Hedberg 
228588ba43b6SAnderson Briglia 	skb_pull(skb, sizeof(*rp));
228688ba43b6SAnderson Briglia 
2287da85e5e5SVinicius Costa Gomes 	memset(&cp, 0, sizeof(cp));
2288c05b9339SJohan Hedberg 	build_pairing_cmd(conn, &cp, NULL, auth);
228988ba43b6SAnderson Briglia 
22901c1def09SVinicius Costa Gomes 	smp->preq[0] = SMP_CMD_PAIRING_REQ;
22911c1def09SVinicius Costa Gomes 	memcpy(&smp->preq[1], &cp, sizeof(cp));
2292f01ead31SAnderson Briglia 
229388ba43b6SAnderson Briglia 	smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
2294b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP);
2295f1cb9af5SVinicius Costa Gomes 
2296da85e5e5SVinicius Costa Gomes 	return 0;
229788ba43b6SAnderson Briglia }
229888ba43b6SAnderson Briglia 
2299cc110922SVinicius Costa Gomes int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
2300eb492e01SAnderson Briglia {
2301cc110922SVinicius Costa Gomes 	struct l2cap_conn *conn = hcon->l2cap_data;
2302c68b7f12SJohan Hedberg 	struct l2cap_chan *chan;
23030a66cf20SJohan Hedberg 	struct smp_chan *smp;
23042b64d153SBrian Gix 	__u8 authreq;
2305fc75cc86SJohan Hedberg 	int ret;
2306eb492e01SAnderson Briglia 
23073a0259bbSVinicius Costa Gomes 	BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
23083a0259bbSVinicius Costa Gomes 
23090a66cf20SJohan Hedberg 	/* This may be NULL if there's an unexpected disconnection */
23100a66cf20SJohan Hedberg 	if (!conn)
23110a66cf20SJohan Hedberg 		return 1;
23120a66cf20SJohan Hedberg 
2313c68b7f12SJohan Hedberg 	chan = conn->smp;
2314c68b7f12SJohan Hedberg 
2315d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hcon->hdev, HCI_LE_ENABLED))
23162e65c9d2SAndre Guedes 		return 1;
23172e65c9d2SAndre Guedes 
231835dc6f83SJohan Hedberg 	if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK))
2319f1cb9af5SVinicius Costa Gomes 		return 1;
2320f1cb9af5SVinicius Costa Gomes 
2321c7262e71SJohan Hedberg 	if (sec_level > hcon->pending_sec_level)
2322c7262e71SJohan Hedberg 		hcon->pending_sec_level = sec_level;
2323c7262e71SJohan Hedberg 
232440bef302SJohan Hedberg 	if (hcon->role == HCI_ROLE_MASTER)
2325c7262e71SJohan Hedberg 		if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
2326c7262e71SJohan Hedberg 			return 0;
2327d26a2345SVinicius Costa Gomes 
2328fc75cc86SJohan Hedberg 	l2cap_chan_lock(chan);
2329fc75cc86SJohan Hedberg 
2330fc75cc86SJohan Hedberg 	/* If SMP is already in progress ignore this request */
2331fc75cc86SJohan Hedberg 	if (chan->data) {
2332fc75cc86SJohan Hedberg 		ret = 0;
2333fc75cc86SJohan Hedberg 		goto unlock;
2334fc75cc86SJohan Hedberg 	}
2335d26a2345SVinicius Costa Gomes 
23368aab4757SVinicius Costa Gomes 	smp = smp_chan_create(conn);
2337fc75cc86SJohan Hedberg 	if (!smp) {
2338fc75cc86SJohan Hedberg 		ret = 1;
2339fc75cc86SJohan Hedberg 		goto unlock;
2340fc75cc86SJohan Hedberg 	}
23412b64d153SBrian Gix 
23422b64d153SBrian Gix 	authreq = seclevel_to_authreq(sec_level);
2343d26a2345SVinicius Costa Gomes 
2344d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hcon->hdev, HCI_SC_ENABLED))
2345d2eb9e10SJohan Hedberg 		authreq |= SMP_AUTH_SC;
2346d2eb9e10SJohan Hedberg 
234779897d20SJohan Hedberg 	/* Require MITM if IO Capability allows or the security level
234879897d20SJohan Hedberg 	 * requires it.
23492e233644SJohan Hedberg 	 */
235079897d20SJohan Hedberg 	if (hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT ||
2351c7262e71SJohan Hedberg 	    hcon->pending_sec_level > BT_SECURITY_MEDIUM)
23522e233644SJohan Hedberg 		authreq |= SMP_AUTH_MITM;
23532e233644SJohan Hedberg 
235440bef302SJohan Hedberg 	if (hcon->role == HCI_ROLE_MASTER) {
2355d26a2345SVinicius Costa Gomes 		struct smp_cmd_pairing cp;
2356f01ead31SAnderson Briglia 
23572b64d153SBrian Gix 		build_pairing_cmd(conn, &cp, NULL, authreq);
23581c1def09SVinicius Costa Gomes 		smp->preq[0] = SMP_CMD_PAIRING_REQ;
23591c1def09SVinicius Costa Gomes 		memcpy(&smp->preq[1], &cp, sizeof(cp));
2360f01ead31SAnderson Briglia 
2361eb492e01SAnderson Briglia 		smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
2362b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP);
2363eb492e01SAnderson Briglia 	} else {
2364eb492e01SAnderson Briglia 		struct smp_cmd_security_req cp;
23652b64d153SBrian Gix 		cp.auth_req = authreq;
2366eb492e01SAnderson Briglia 		smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
2367b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_REQ);
2368eb492e01SAnderson Briglia 	}
2369eb492e01SAnderson Briglia 
23704a74d658SJohan Hedberg 	set_bit(SMP_FLAG_INITIATOR, &smp->flags);
2371fc75cc86SJohan Hedberg 	ret = 0;
2372edca792cSJohan Hedberg 
2373fc75cc86SJohan Hedberg unlock:
2374fc75cc86SJohan Hedberg 	l2cap_chan_unlock(chan);
2375fc75cc86SJohan Hedberg 	return ret;
2376eb492e01SAnderson Briglia }
2377eb492e01SAnderson Briglia 
23787034b911SVinicius Costa Gomes static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
23797034b911SVinicius Costa Gomes {
238016b90839SVinicius Costa Gomes 	struct smp_cmd_encrypt_info *rp = (void *) skb->data;
23815d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
23825d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
238316b90839SVinicius Costa Gomes 
2384c46b98beSJohan Hedberg 	BT_DBG("conn %p", conn);
2385c46b98beSJohan Hedberg 
2386c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rp))
238738e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2388c46b98beSJohan Hedberg 
2389b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_MASTER_IDENT);
23906131ddc8SJohan Hedberg 
239116b90839SVinicius Costa Gomes 	skb_pull(skb, sizeof(*rp));
239216b90839SVinicius Costa Gomes 
23931c1def09SVinicius Costa Gomes 	memcpy(smp->tk, rp->ltk, sizeof(smp->tk));
239416b90839SVinicius Costa Gomes 
23957034b911SVinicius Costa Gomes 	return 0;
23967034b911SVinicius Costa Gomes }
23977034b911SVinicius Costa Gomes 
23987034b911SVinicius Costa Gomes static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
23997034b911SVinicius Costa Gomes {
240016b90839SVinicius Costa Gomes 	struct smp_cmd_master_ident *rp = (void *) skb->data;
24015d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
24025d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
2403c9839a11SVinicius Costa Gomes 	struct hci_dev *hdev = conn->hcon->hdev;
2404c9839a11SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
240523d0e128SJohan Hedberg 	struct smp_ltk *ltk;
2406c9839a11SVinicius Costa Gomes 	u8 authenticated;
24077034b911SVinicius Costa Gomes 
2408c46b98beSJohan Hedberg 	BT_DBG("conn %p", conn);
2409c46b98beSJohan Hedberg 
2410c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rp))
241138e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2412c46b98beSJohan Hedberg 
24139747a9f3SJohan Hedberg 	/* Mark the information as received */
24149747a9f3SJohan Hedberg 	smp->remote_key_dist &= ~SMP_DIST_ENC_KEY;
24159747a9f3SJohan Hedberg 
2416b28b4943SJohan Hedberg 	if (smp->remote_key_dist & SMP_DIST_ID_KEY)
2417b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO);
2418196332f5SJohan Hedberg 	else if (smp->remote_key_dist & SMP_DIST_SIGN)
2419196332f5SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO);
2420b28b4943SJohan Hedberg 
242116b90839SVinicius Costa Gomes 	skb_pull(skb, sizeof(*rp));
242216b90839SVinicius Costa Gomes 
2423ce39fb4eSMarcel Holtmann 	authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
24242ceba539SJohan Hedberg 	ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, SMP_LTK,
2425ce39fb4eSMarcel Holtmann 			  authenticated, smp->tk, smp->enc_key_size,
242604124681SGustavo F. Padovan 			  rp->ediv, rp->rand);
242723d0e128SJohan Hedberg 	smp->ltk = ltk;
2428c6e81e9aSJohan Hedberg 	if (!(smp->remote_key_dist & KEY_DIST_MASK))
2429d6268e86SJohan Hedberg 		smp_distribute_keys(smp);
24307034b911SVinicius Costa Gomes 
24317034b911SVinicius Costa Gomes 	return 0;
24327034b911SVinicius Costa Gomes }
24337034b911SVinicius Costa Gomes 
2434fd349c02SJohan Hedberg static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
2435fd349c02SJohan Hedberg {
2436fd349c02SJohan Hedberg 	struct smp_cmd_ident_info *info = (void *) skb->data;
24375d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
24385d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
2439fd349c02SJohan Hedberg 
2440fd349c02SJohan Hedberg 	BT_DBG("");
2441fd349c02SJohan Hedberg 
2442fd349c02SJohan Hedberg 	if (skb->len < sizeof(*info))
244338e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2444fd349c02SJohan Hedberg 
2445b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_ADDR_INFO);
24466131ddc8SJohan Hedberg 
2447fd349c02SJohan Hedberg 	skb_pull(skb, sizeof(*info));
2448fd349c02SJohan Hedberg 
2449fd349c02SJohan Hedberg 	memcpy(smp->irk, info->irk, 16);
2450fd349c02SJohan Hedberg 
2451fd349c02SJohan Hedberg 	return 0;
2452fd349c02SJohan Hedberg }
2453fd349c02SJohan Hedberg 
2454fd349c02SJohan Hedberg static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
2455fd349c02SJohan Hedberg 				   struct sk_buff *skb)
2456fd349c02SJohan Hedberg {
2457fd349c02SJohan Hedberg 	struct smp_cmd_ident_addr_info *info = (void *) skb->data;
24585d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
24595d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
2460fd349c02SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
2461fd349c02SJohan Hedberg 	bdaddr_t rpa;
2462fd349c02SJohan Hedberg 
2463fd349c02SJohan Hedberg 	BT_DBG("");
2464fd349c02SJohan Hedberg 
2465fd349c02SJohan Hedberg 	if (skb->len < sizeof(*info))
246638e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2467fd349c02SJohan Hedberg 
24689747a9f3SJohan Hedberg 	/* Mark the information as received */
24699747a9f3SJohan Hedberg 	smp->remote_key_dist &= ~SMP_DIST_ID_KEY;
24709747a9f3SJohan Hedberg 
2471b28b4943SJohan Hedberg 	if (smp->remote_key_dist & SMP_DIST_SIGN)
2472b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO);
2473b28b4943SJohan Hedberg 
2474fd349c02SJohan Hedberg 	skb_pull(skb, sizeof(*info));
2475fd349c02SJohan Hedberg 
2476a9a58f86SJohan Hedberg 	/* Strictly speaking the Core Specification (4.1) allows sending
2477a9a58f86SJohan Hedberg 	 * an empty address which would force us to rely on just the IRK
2478a9a58f86SJohan Hedberg 	 * as "identity information". However, since such
2479a9a58f86SJohan Hedberg 	 * implementations are not known of and in order to not over
2480a9a58f86SJohan Hedberg 	 * complicate our implementation, simply pretend that we never
2481a9a58f86SJohan Hedberg 	 * received an IRK for such a device.
2482e12af489SJohan Hedberg 	 *
2483e12af489SJohan Hedberg 	 * The Identity Address must also be a Static Random or Public
2484e12af489SJohan Hedberg 	 * Address, which hci_is_identity_address() checks for.
2485a9a58f86SJohan Hedberg 	 */
2486e12af489SJohan Hedberg 	if (!bacmp(&info->bdaddr, BDADDR_ANY) ||
2487e12af489SJohan Hedberg 	    !hci_is_identity_address(&info->bdaddr, info->addr_type)) {
2488a9a58f86SJohan Hedberg 		BT_ERR("Ignoring IRK with no identity address");
248931dd624eSJohan Hedberg 		goto distribute;
2490a9a58f86SJohan Hedberg 	}
2491a9a58f86SJohan Hedberg 
2492fd349c02SJohan Hedberg 	bacpy(&smp->id_addr, &info->bdaddr);
2493fd349c02SJohan Hedberg 	smp->id_addr_type = info->addr_type;
2494fd349c02SJohan Hedberg 
2495fd349c02SJohan Hedberg 	if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type))
2496fd349c02SJohan Hedberg 		bacpy(&rpa, &hcon->dst);
2497fd349c02SJohan Hedberg 	else
2498fd349c02SJohan Hedberg 		bacpy(&rpa, BDADDR_ANY);
2499fd349c02SJohan Hedberg 
250023d0e128SJohan Hedberg 	smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
250123d0e128SJohan Hedberg 				      smp->id_addr_type, smp->irk, &rpa);
2502fd349c02SJohan Hedberg 
250331dd624eSJohan Hedberg distribute:
2504c6e81e9aSJohan Hedberg 	if (!(smp->remote_key_dist & KEY_DIST_MASK))
2505d6268e86SJohan Hedberg 		smp_distribute_keys(smp);
2506fd349c02SJohan Hedberg 
2507fd349c02SJohan Hedberg 	return 0;
2508fd349c02SJohan Hedberg }
2509fd349c02SJohan Hedberg 
25107ee4ea36SMarcel Holtmann static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)
25117ee4ea36SMarcel Holtmann {
25127ee4ea36SMarcel Holtmann 	struct smp_cmd_sign_info *rp = (void *) skb->data;
25135d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
25145d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
25157ee4ea36SMarcel Holtmann 	struct smp_csrk *csrk;
25167ee4ea36SMarcel Holtmann 
25177ee4ea36SMarcel Holtmann 	BT_DBG("conn %p", conn);
25187ee4ea36SMarcel Holtmann 
25197ee4ea36SMarcel Holtmann 	if (skb->len < sizeof(*rp))
252038e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
25217ee4ea36SMarcel Holtmann 
25227ee4ea36SMarcel Holtmann 	/* Mark the information as received */
25237ee4ea36SMarcel Holtmann 	smp->remote_key_dist &= ~SMP_DIST_SIGN;
25247ee4ea36SMarcel Holtmann 
25257ee4ea36SMarcel Holtmann 	skb_pull(skb, sizeof(*rp));
25267ee4ea36SMarcel Holtmann 
25277ee4ea36SMarcel Holtmann 	csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
25287ee4ea36SMarcel Holtmann 	if (csrk) {
25294cd3928aSJohan Hedberg 		if (conn->hcon->sec_level > BT_SECURITY_MEDIUM)
25304cd3928aSJohan Hedberg 			csrk->type = MGMT_CSRK_REMOTE_AUTHENTICATED;
25314cd3928aSJohan Hedberg 		else
25324cd3928aSJohan Hedberg 			csrk->type = MGMT_CSRK_REMOTE_UNAUTHENTICATED;
25337ee4ea36SMarcel Holtmann 		memcpy(csrk->val, rp->csrk, sizeof(csrk->val));
25347ee4ea36SMarcel Holtmann 	}
25357ee4ea36SMarcel Holtmann 	smp->csrk = csrk;
2536d6268e86SJohan Hedberg 	smp_distribute_keys(smp);
25377ee4ea36SMarcel Holtmann 
25387ee4ea36SMarcel Holtmann 	return 0;
25397ee4ea36SMarcel Holtmann }
25407ee4ea36SMarcel Holtmann 
25415e3d3d9bSJohan Hedberg static u8 sc_select_method(struct smp_chan *smp)
25425e3d3d9bSJohan Hedberg {
25435e3d3d9bSJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
25445e3d3d9bSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
25455e3d3d9bSJohan Hedberg 	struct smp_cmd_pairing *local, *remote;
25465e3d3d9bSJohan Hedberg 	u8 local_mitm, remote_mitm, local_io, remote_io, method;
25475e3d3d9bSJohan Hedberg 
25481a8bab4fSJohan Hedberg 	if (test_bit(SMP_FLAG_REMOTE_OOB, &smp->flags) ||
25491a8bab4fSJohan Hedberg 	    test_bit(SMP_FLAG_LOCAL_OOB, &smp->flags))
2550a29b0733SJohan Hedberg 		return REQ_OOB;
2551a29b0733SJohan Hedberg 
25525e3d3d9bSJohan Hedberg 	/* The preq/prsp contain the raw Pairing Request/Response PDUs
25535e3d3d9bSJohan Hedberg 	 * which are needed as inputs to some crypto functions. To get
25545e3d3d9bSJohan Hedberg 	 * the "struct smp_cmd_pairing" from them we need to skip the
25555e3d3d9bSJohan Hedberg 	 * first byte which contains the opcode.
25565e3d3d9bSJohan Hedberg 	 */
25575e3d3d9bSJohan Hedberg 	if (hcon->out) {
25585e3d3d9bSJohan Hedberg 		local = (void *) &smp->preq[1];
25595e3d3d9bSJohan Hedberg 		remote = (void *) &smp->prsp[1];
25605e3d3d9bSJohan Hedberg 	} else {
25615e3d3d9bSJohan Hedberg 		local = (void *) &smp->prsp[1];
25625e3d3d9bSJohan Hedberg 		remote = (void *) &smp->preq[1];
25635e3d3d9bSJohan Hedberg 	}
25645e3d3d9bSJohan Hedberg 
25655e3d3d9bSJohan Hedberg 	local_io = local->io_capability;
25665e3d3d9bSJohan Hedberg 	remote_io = remote->io_capability;
25675e3d3d9bSJohan Hedberg 
25685e3d3d9bSJohan Hedberg 	local_mitm = (local->auth_req & SMP_AUTH_MITM);
25695e3d3d9bSJohan Hedberg 	remote_mitm = (remote->auth_req & SMP_AUTH_MITM);
25705e3d3d9bSJohan Hedberg 
25715e3d3d9bSJohan Hedberg 	/* If either side wants MITM, look up the method from the table,
25725e3d3d9bSJohan Hedberg 	 * otherwise use JUST WORKS.
25735e3d3d9bSJohan Hedberg 	 */
25745e3d3d9bSJohan Hedberg 	if (local_mitm || remote_mitm)
25755e3d3d9bSJohan Hedberg 		method = get_auth_method(smp, local_io, remote_io);
25765e3d3d9bSJohan Hedberg 	else
25775e3d3d9bSJohan Hedberg 		method = JUST_WORKS;
25785e3d3d9bSJohan Hedberg 
25795e3d3d9bSJohan Hedberg 	/* Don't confirm locally initiated pairing attempts */
25805e3d3d9bSJohan Hedberg 	if (method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR, &smp->flags))
25815e3d3d9bSJohan Hedberg 		method = JUST_WORKS;
25825e3d3d9bSJohan Hedberg 
25835e3d3d9bSJohan Hedberg 	return method;
25845e3d3d9bSJohan Hedberg }
25855e3d3d9bSJohan Hedberg 
2586d8f8edbeSJohan Hedberg static int smp_cmd_public_key(struct l2cap_conn *conn, struct sk_buff *skb)
2587d8f8edbeSJohan Hedberg {
2588d8f8edbeSJohan Hedberg 	struct smp_cmd_public_key *key = (void *) skb->data;
2589d8f8edbeSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
2590d8f8edbeSJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
2591d8f8edbeSJohan Hedberg 	struct smp_chan *smp = chan->data;
25925e3d3d9bSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
2593cbbbe3e2SJohan Hedberg 	struct smp_cmd_pairing_confirm cfm;
2594d8f8edbeSJohan Hedberg 	int err;
2595d8f8edbeSJohan Hedberg 
2596d8f8edbeSJohan Hedberg 	BT_DBG("conn %p", conn);
2597d8f8edbeSJohan Hedberg 
2598d8f8edbeSJohan Hedberg 	if (skb->len < sizeof(*key))
2599d8f8edbeSJohan Hedberg 		return SMP_INVALID_PARAMS;
2600d8f8edbeSJohan Hedberg 
2601d8f8edbeSJohan Hedberg 	memcpy(smp->remote_pk, key, 64);
2602d8f8edbeSJohan Hedberg 
2603a8ca617cSJohan Hedberg 	if (test_bit(SMP_FLAG_REMOTE_OOB, &smp->flags)) {
2604a8ca617cSJohan Hedberg 		err = smp_f4(smp->tfm_cmac, smp->remote_pk, smp->remote_pk,
2605a8ca617cSJohan Hedberg 			     smp->rr, 0, cfm.confirm_val);
2606a8ca617cSJohan Hedberg 		if (err)
2607a8ca617cSJohan Hedberg 			return SMP_UNSPECIFIED;
2608a8ca617cSJohan Hedberg 
2609a8ca617cSJohan Hedberg 		if (memcmp(cfm.confirm_val, smp->pcnf, 16))
2610a8ca617cSJohan Hedberg 			return SMP_CONFIRM_FAILED;
2611a8ca617cSJohan Hedberg 	}
2612a8ca617cSJohan Hedberg 
2613d8f8edbeSJohan Hedberg 	/* Non-initiating device sends its public key after receiving
2614d8f8edbeSJohan Hedberg 	 * the key from the initiating device.
2615d8f8edbeSJohan Hedberg 	 */
2616d8f8edbeSJohan Hedberg 	if (!hcon->out) {
2617d8f8edbeSJohan Hedberg 		err = sc_send_public_key(smp);
2618d8f8edbeSJohan Hedberg 		if (err)
2619d8f8edbeSJohan Hedberg 			return err;
2620d8f8edbeSJohan Hedberg 	}
2621d8f8edbeSJohan Hedberg 
2622c7a3d57dSJohan Hedberg 	SMP_DBG("Remote Public Key X: %32phN", smp->remote_pk);
2623e091526dSMarcel Holtmann 	SMP_DBG("Remote Public Key Y: %32phN", smp->remote_pk + 32);
2624d8f8edbeSJohan Hedberg 
2625d8f8edbeSJohan Hedberg 	if (!ecdh_shared_secret(smp->remote_pk, smp->local_sk, smp->dhkey))
2626d8f8edbeSJohan Hedberg 		return SMP_UNSPECIFIED;
2627d8f8edbeSJohan Hedberg 
2628c7a3d57dSJohan Hedberg 	SMP_DBG("DHKey %32phN", smp->dhkey);
2629d8f8edbeSJohan Hedberg 
2630d8f8edbeSJohan Hedberg 	set_bit(SMP_FLAG_REMOTE_PK, &smp->flags);
2631d8f8edbeSJohan Hedberg 
26325e3d3d9bSJohan Hedberg 	smp->method = sc_select_method(smp);
26335e3d3d9bSJohan Hedberg 
26345e3d3d9bSJohan Hedberg 	BT_DBG("%s selected method 0x%02x", hdev->name, smp->method);
26355e3d3d9bSJohan Hedberg 
26365e3d3d9bSJohan Hedberg 	/* JUST_WORKS and JUST_CFM result in an unauthenticated key */
26375e3d3d9bSJohan Hedberg 	if (smp->method == JUST_WORKS || smp->method == JUST_CFM)
26385e3d3d9bSJohan Hedberg 		hcon->pending_sec_level = BT_SECURITY_MEDIUM;
26395e3d3d9bSJohan Hedberg 	else
26405e3d3d9bSJohan Hedberg 		hcon->pending_sec_level = BT_SECURITY_FIPS;
26415e3d3d9bSJohan Hedberg 
2642aeb7d461SJohan Hedberg 	if (!memcmp(debug_pk, smp->remote_pk, 64))
2643aeb7d461SJohan Hedberg 		set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags);
2644aeb7d461SJohan Hedberg 
264538606f14SJohan Hedberg 	if (smp->method == DSP_PASSKEY) {
264638606f14SJohan Hedberg 		get_random_bytes(&hcon->passkey_notify,
264738606f14SJohan Hedberg 				 sizeof(hcon->passkey_notify));
264838606f14SJohan Hedberg 		hcon->passkey_notify %= 1000000;
264938606f14SJohan Hedberg 		hcon->passkey_entered = 0;
265038606f14SJohan Hedberg 		smp->passkey_round = 0;
265138606f14SJohan Hedberg 		if (mgmt_user_passkey_notify(hdev, &hcon->dst, hcon->type,
265238606f14SJohan Hedberg 					     hcon->dst_type,
265338606f14SJohan Hedberg 					     hcon->passkey_notify,
265438606f14SJohan Hedberg 					     hcon->passkey_entered))
265538606f14SJohan Hedberg 			return SMP_UNSPECIFIED;
265638606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
265738606f14SJohan Hedberg 		return sc_passkey_round(smp, SMP_CMD_PUBLIC_KEY);
265838606f14SJohan Hedberg 	}
265938606f14SJohan Hedberg 
266094ea7257SJohan Hedberg 	if (smp->method == REQ_OOB) {
2661a29b0733SJohan Hedberg 		if (hcon->out)
2662a29b0733SJohan Hedberg 			smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM,
2663a29b0733SJohan Hedberg 				     sizeof(smp->prnd), smp->prnd);
2664a29b0733SJohan Hedberg 
2665a29b0733SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
2666a29b0733SJohan Hedberg 
2667a29b0733SJohan Hedberg 		return 0;
2668a29b0733SJohan Hedberg 	}
2669a29b0733SJohan Hedberg 
267038606f14SJohan Hedberg 	if (hcon->out)
267138606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
267238606f14SJohan Hedberg 
267338606f14SJohan Hedberg 	if (smp->method == REQ_PASSKEY) {
267438606f14SJohan Hedberg 		if (mgmt_user_passkey_request(hdev, &hcon->dst, hcon->type,
267538606f14SJohan Hedberg 					      hcon->dst_type))
267638606f14SJohan Hedberg 			return SMP_UNSPECIFIED;
267738606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
267838606f14SJohan Hedberg 		set_bit(SMP_FLAG_WAIT_USER, &smp->flags);
267938606f14SJohan Hedberg 		return 0;
268038606f14SJohan Hedberg 	}
268138606f14SJohan Hedberg 
2682cbbbe3e2SJohan Hedberg 	/* The Initiating device waits for the non-initiating device to
2683cbbbe3e2SJohan Hedberg 	 * send the confirm value.
2684cbbbe3e2SJohan Hedberg 	 */
2685cbbbe3e2SJohan Hedberg 	if (conn->hcon->out)
2686cbbbe3e2SJohan Hedberg 		return 0;
2687cbbbe3e2SJohan Hedberg 
2688cbbbe3e2SJohan Hedberg 	err = smp_f4(smp->tfm_cmac, smp->local_pk, smp->remote_pk, smp->prnd,
2689cbbbe3e2SJohan Hedberg 		     0, cfm.confirm_val);
2690cbbbe3e2SJohan Hedberg 	if (err)
2691cbbbe3e2SJohan Hedberg 		return SMP_UNSPECIFIED;
2692cbbbe3e2SJohan Hedberg 
2693cbbbe3e2SJohan Hedberg 	smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cfm), &cfm);
2694cbbbe3e2SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
2695cbbbe3e2SJohan Hedberg 
2696d8f8edbeSJohan Hedberg 	return 0;
2697d8f8edbeSJohan Hedberg }
2698d8f8edbeSJohan Hedberg 
26996433a9a2SJohan Hedberg static int smp_cmd_dhkey_check(struct l2cap_conn *conn, struct sk_buff *skb)
27006433a9a2SJohan Hedberg {
27016433a9a2SJohan Hedberg 	struct smp_cmd_dhkey_check *check = (void *) skb->data;
27026433a9a2SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
27036433a9a2SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
27046433a9a2SJohan Hedberg 	struct smp_chan *smp = chan->data;
27056433a9a2SJohan Hedberg 	u8 a[7], b[7], *local_addr, *remote_addr;
27066433a9a2SJohan Hedberg 	u8 io_cap[3], r[16], e[16];
27076433a9a2SJohan Hedberg 	int err;
27086433a9a2SJohan Hedberg 
27096433a9a2SJohan Hedberg 	BT_DBG("conn %p", conn);
27106433a9a2SJohan Hedberg 
27116433a9a2SJohan Hedberg 	if (skb->len < sizeof(*check))
27126433a9a2SJohan Hedberg 		return SMP_INVALID_PARAMS;
27136433a9a2SJohan Hedberg 
27146433a9a2SJohan Hedberg 	memcpy(a, &hcon->init_addr, 6);
27156433a9a2SJohan Hedberg 	memcpy(b, &hcon->resp_addr, 6);
27166433a9a2SJohan Hedberg 	a[6] = hcon->init_addr_type;
27176433a9a2SJohan Hedberg 	b[6] = hcon->resp_addr_type;
27186433a9a2SJohan Hedberg 
27196433a9a2SJohan Hedberg 	if (hcon->out) {
27206433a9a2SJohan Hedberg 		local_addr = a;
27216433a9a2SJohan Hedberg 		remote_addr = b;
27226433a9a2SJohan Hedberg 		memcpy(io_cap, &smp->prsp[1], 3);
27236433a9a2SJohan Hedberg 	} else {
27246433a9a2SJohan Hedberg 		local_addr = b;
27256433a9a2SJohan Hedberg 		remote_addr = a;
27266433a9a2SJohan Hedberg 		memcpy(io_cap, &smp->preq[1], 3);
27276433a9a2SJohan Hedberg 	}
27286433a9a2SJohan Hedberg 
27296433a9a2SJohan Hedberg 	memset(r, 0, sizeof(r));
27306433a9a2SJohan Hedberg 
273138606f14SJohan Hedberg 	if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY)
273238606f14SJohan Hedberg 		put_unaligned_le32(hcon->passkey_notify, r);
2733882fafadSJohan Hedberg 	else if (smp->method == REQ_OOB)
2734882fafadSJohan Hedberg 		memcpy(r, smp->lr, 16);
273538606f14SJohan Hedberg 
27366433a9a2SJohan Hedberg 	err = smp_f6(smp->tfm_cmac, smp->mackey, smp->rrnd, smp->prnd, r,
27376433a9a2SJohan Hedberg 		     io_cap, remote_addr, local_addr, e);
27386433a9a2SJohan Hedberg 	if (err)
27396433a9a2SJohan Hedberg 		return SMP_UNSPECIFIED;
27406433a9a2SJohan Hedberg 
27416433a9a2SJohan Hedberg 	if (memcmp(check->e, e, 16))
27426433a9a2SJohan Hedberg 		return SMP_DHKEY_CHECK_FAILED;
27436433a9a2SJohan Hedberg 
2744d3e54a87SJohan Hedberg 	if (!hcon->out) {
2745d3e54a87SJohan Hedberg 		if (test_bit(SMP_FLAG_WAIT_USER, &smp->flags)) {
2746d3e54a87SJohan Hedberg 			set_bit(SMP_FLAG_DHKEY_PENDING, &smp->flags);
2747d3e54a87SJohan Hedberg 			return 0;
2748d3e54a87SJohan Hedberg 		}
2749d378a2d7SJohan Hedberg 
2750d3e54a87SJohan Hedberg 		/* Slave sends DHKey check as response to master */
2751d3e54a87SJohan Hedberg 		sc_dhkey_check(smp);
2752d3e54a87SJohan Hedberg 	}
2753d378a2d7SJohan Hedberg 
2754d3e54a87SJohan Hedberg 	sc_add_ltk(smp);
27556433a9a2SJohan Hedberg 
27566433a9a2SJohan Hedberg 	if (hcon->out) {
27578b76ce34SJohan Hedberg 		hci_le_start_enc(hcon, 0, 0, smp->tk, smp->enc_key_size);
27586433a9a2SJohan Hedberg 		hcon->enc_key_size = smp->enc_key_size;
27596433a9a2SJohan Hedberg 	}
27606433a9a2SJohan Hedberg 
27616433a9a2SJohan Hedberg 	return 0;
27626433a9a2SJohan Hedberg }
27636433a9a2SJohan Hedberg 
27641408bb6eSJohan Hedberg static int smp_cmd_keypress_notify(struct l2cap_conn *conn,
27651408bb6eSJohan Hedberg 				   struct sk_buff *skb)
27661408bb6eSJohan Hedberg {
27671408bb6eSJohan Hedberg 	struct smp_cmd_keypress_notify *kp = (void *) skb->data;
27681408bb6eSJohan Hedberg 
27691408bb6eSJohan Hedberg 	BT_DBG("value 0x%02x", kp->value);
27701408bb6eSJohan Hedberg 
27711408bb6eSJohan Hedberg 	return 0;
27721408bb6eSJohan Hedberg }
27731408bb6eSJohan Hedberg 
27744befb867SJohan Hedberg static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb)
2775eb492e01SAnderson Briglia {
27765d88cc73SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
27777b9899dbSMarcel Holtmann 	struct hci_conn *hcon = conn->hcon;
2778b28b4943SJohan Hedberg 	struct smp_chan *smp;
277992381f5cSMarcel Holtmann 	__u8 code, reason;
2780eb492e01SAnderson Briglia 	int err = 0;
2781eb492e01SAnderson Briglia 
27828ae9b984SJohan Hedberg 	if (skb->len < 1)
278392381f5cSMarcel Holtmann 		return -EILSEQ;
278492381f5cSMarcel Holtmann 
2785d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hcon->hdev, HCI_LE_ENABLED)) {
27862e65c9d2SAndre Guedes 		reason = SMP_PAIRING_NOTSUPP;
27872e65c9d2SAndre Guedes 		goto done;
27882e65c9d2SAndre Guedes 	}
27892e65c9d2SAndre Guedes 
279092381f5cSMarcel Holtmann 	code = skb->data[0];
2791eb492e01SAnderson Briglia 	skb_pull(skb, sizeof(code));
2792eb492e01SAnderson Briglia 
2793b28b4943SJohan Hedberg 	smp = chan->data;
2794b28b4943SJohan Hedberg 
2795b28b4943SJohan Hedberg 	if (code > SMP_CMD_MAX)
2796b28b4943SJohan Hedberg 		goto drop;
2797b28b4943SJohan Hedberg 
279824bd0bd9SJohan Hedberg 	if (smp && !test_and_clear_bit(code, &smp->allow_cmd))
2799b28b4943SJohan Hedberg 		goto drop;
2800b28b4943SJohan Hedberg 
2801b28b4943SJohan Hedberg 	/* If we don't have a context the only allowed commands are
2802b28b4943SJohan Hedberg 	 * pairing request and security request.
28038cf9fa12SJohan Hedberg 	 */
2804b28b4943SJohan Hedberg 	if (!smp && code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ)
2805b28b4943SJohan Hedberg 		goto drop;
28068cf9fa12SJohan Hedberg 
2807eb492e01SAnderson Briglia 	switch (code) {
2808eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_REQ:
2809da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_req(conn, skb);
2810eb492e01SAnderson Briglia 		break;
2811eb492e01SAnderson Briglia 
2812eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_FAIL:
281384794e11SJohan Hedberg 		smp_failure(conn, 0);
2814da85e5e5SVinicius Costa Gomes 		err = -EPERM;
2815eb492e01SAnderson Briglia 		break;
2816eb492e01SAnderson Briglia 
2817eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_RSP:
2818da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_rsp(conn, skb);
281988ba43b6SAnderson Briglia 		break;
282088ba43b6SAnderson Briglia 
282188ba43b6SAnderson Briglia 	case SMP_CMD_SECURITY_REQ:
2822da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_security_req(conn, skb);
282388ba43b6SAnderson Briglia 		break;
282488ba43b6SAnderson Briglia 
2825eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_CONFIRM:
2826da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_confirm(conn, skb);
282788ba43b6SAnderson Briglia 		break;
282888ba43b6SAnderson Briglia 
2829eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_RANDOM:
2830da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_random(conn, skb);
283188ba43b6SAnderson Briglia 		break;
283288ba43b6SAnderson Briglia 
2833eb492e01SAnderson Briglia 	case SMP_CMD_ENCRYPT_INFO:
28347034b911SVinicius Costa Gomes 		reason = smp_cmd_encrypt_info(conn, skb);
28357034b911SVinicius Costa Gomes 		break;
28367034b911SVinicius Costa Gomes 
2837eb492e01SAnderson Briglia 	case SMP_CMD_MASTER_IDENT:
28387034b911SVinicius Costa Gomes 		reason = smp_cmd_master_ident(conn, skb);
28397034b911SVinicius Costa Gomes 		break;
28407034b911SVinicius Costa Gomes 
2841eb492e01SAnderson Briglia 	case SMP_CMD_IDENT_INFO:
2842fd349c02SJohan Hedberg 		reason = smp_cmd_ident_info(conn, skb);
2843fd349c02SJohan Hedberg 		break;
2844fd349c02SJohan Hedberg 
2845eb492e01SAnderson Briglia 	case SMP_CMD_IDENT_ADDR_INFO:
2846fd349c02SJohan Hedberg 		reason = smp_cmd_ident_addr_info(conn, skb);
2847fd349c02SJohan Hedberg 		break;
2848fd349c02SJohan Hedberg 
2849eb492e01SAnderson Briglia 	case SMP_CMD_SIGN_INFO:
28507ee4ea36SMarcel Holtmann 		reason = smp_cmd_sign_info(conn, skb);
28517034b911SVinicius Costa Gomes 		break;
28527034b911SVinicius Costa Gomes 
2853d8f8edbeSJohan Hedberg 	case SMP_CMD_PUBLIC_KEY:
2854d8f8edbeSJohan Hedberg 		reason = smp_cmd_public_key(conn, skb);
2855d8f8edbeSJohan Hedberg 		break;
2856d8f8edbeSJohan Hedberg 
28576433a9a2SJohan Hedberg 	case SMP_CMD_DHKEY_CHECK:
28586433a9a2SJohan Hedberg 		reason = smp_cmd_dhkey_check(conn, skb);
28596433a9a2SJohan Hedberg 		break;
28606433a9a2SJohan Hedberg 
28611408bb6eSJohan Hedberg 	case SMP_CMD_KEYPRESS_NOTIFY:
28621408bb6eSJohan Hedberg 		reason = smp_cmd_keypress_notify(conn, skb);
28631408bb6eSJohan Hedberg 		break;
28641408bb6eSJohan Hedberg 
2865eb492e01SAnderson Briglia 	default:
2866eb492e01SAnderson Briglia 		BT_DBG("Unknown command code 0x%2.2x", code);
2867eb492e01SAnderson Briglia 		reason = SMP_CMD_NOTSUPP;
28683a0259bbSVinicius Costa Gomes 		goto done;
28693a0259bbSVinicius Costa Gomes 	}
28703a0259bbSVinicius Costa Gomes 
28713a0259bbSVinicius Costa Gomes done:
28729b7b18efSJohan Hedberg 	if (!err) {
28733a0259bbSVinicius Costa Gomes 		if (reason)
287484794e11SJohan Hedberg 			smp_failure(conn, reason);
2875eb492e01SAnderson Briglia 		kfree_skb(skb);
28769b7b18efSJohan Hedberg 	}
28779b7b18efSJohan Hedberg 
2878eb492e01SAnderson Briglia 	return err;
2879b28b4943SJohan Hedberg 
2880b28b4943SJohan Hedberg drop:
2881b28b4943SJohan Hedberg 	BT_ERR("%s unexpected SMP command 0x%02x from %pMR", hcon->hdev->name,
2882b28b4943SJohan Hedberg 	       code, &hcon->dst);
2883b28b4943SJohan Hedberg 	kfree_skb(skb);
2884b28b4943SJohan Hedberg 	return 0;
2885eb492e01SAnderson Briglia }
28867034b911SVinicius Costa Gomes 
288770db83c4SJohan Hedberg static void smp_teardown_cb(struct l2cap_chan *chan, int err)
288870db83c4SJohan Hedberg {
288970db83c4SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
289070db83c4SJohan Hedberg 
289170db83c4SJohan Hedberg 	BT_DBG("chan %p", chan);
289270db83c4SJohan Hedberg 
2893fc75cc86SJohan Hedberg 	if (chan->data)
28945d88cc73SJohan Hedberg 		smp_chan_destroy(conn);
28955d88cc73SJohan Hedberg 
289670db83c4SJohan Hedberg 	conn->smp = NULL;
289770db83c4SJohan Hedberg 	l2cap_chan_put(chan);
289870db83c4SJohan Hedberg }
289970db83c4SJohan Hedberg 
2900b5ae344dSJohan Hedberg static void bredr_pairing(struct l2cap_chan *chan)
2901b5ae344dSJohan Hedberg {
2902b5ae344dSJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
2903b5ae344dSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
2904b5ae344dSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
2905b5ae344dSJohan Hedberg 	struct smp_cmd_pairing req;
2906b5ae344dSJohan Hedberg 	struct smp_chan *smp;
2907b5ae344dSJohan Hedberg 
2908b5ae344dSJohan Hedberg 	BT_DBG("chan %p", chan);
2909b5ae344dSJohan Hedberg 
2910b5ae344dSJohan Hedberg 	/* Only new pairings are interesting */
2911b5ae344dSJohan Hedberg 	if (!test_bit(HCI_CONN_NEW_LINK_KEY, &hcon->flags))
2912b5ae344dSJohan Hedberg 		return;
2913b5ae344dSJohan Hedberg 
2914b5ae344dSJohan Hedberg 	/* Don't bother if we're not encrypted */
2915b5ae344dSJohan Hedberg 	if (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags))
2916b5ae344dSJohan Hedberg 		return;
2917b5ae344dSJohan Hedberg 
2918b5ae344dSJohan Hedberg 	/* Only master may initiate SMP over BR/EDR */
2919b5ae344dSJohan Hedberg 	if (hcon->role != HCI_ROLE_MASTER)
2920b5ae344dSJohan Hedberg 		return;
2921b5ae344dSJohan Hedberg 
2922b5ae344dSJohan Hedberg 	/* Secure Connections support must be enabled */
2923d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_SC_ENABLED))
2924b5ae344dSJohan Hedberg 		return;
2925b5ae344dSJohan Hedberg 
2926b5ae344dSJohan Hedberg 	/* BR/EDR must use Secure Connections for SMP */
2927b5ae344dSJohan Hedberg 	if (!test_bit(HCI_CONN_AES_CCM, &hcon->flags) &&
2928b7cb93e5SMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP))
2929b5ae344dSJohan Hedberg 		return;
2930b5ae344dSJohan Hedberg 
2931b5ae344dSJohan Hedberg 	/* If our LE support is not enabled don't do anything */
2932d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED))
2933b5ae344dSJohan Hedberg 		return;
2934b5ae344dSJohan Hedberg 
2935b5ae344dSJohan Hedberg 	/* Don't bother if remote LE support is not enabled */
2936b5ae344dSJohan Hedberg 	if (!lmp_host_le_capable(hcon))
2937b5ae344dSJohan Hedberg 		return;
2938b5ae344dSJohan Hedberg 
2939b5ae344dSJohan Hedberg 	/* Remote must support SMP fixed chan for BR/EDR */
2940b5ae344dSJohan Hedberg 	if (!(conn->remote_fixed_chan & L2CAP_FC_SMP_BREDR))
2941b5ae344dSJohan Hedberg 		return;
2942b5ae344dSJohan Hedberg 
2943b5ae344dSJohan Hedberg 	/* Don't bother if SMP is already ongoing */
2944b5ae344dSJohan Hedberg 	if (chan->data)
2945b5ae344dSJohan Hedberg 		return;
2946b5ae344dSJohan Hedberg 
2947b5ae344dSJohan Hedberg 	smp = smp_chan_create(conn);
2948b5ae344dSJohan Hedberg 	if (!smp) {
2949b5ae344dSJohan Hedberg 		BT_ERR("%s unable to create SMP context for BR/EDR",
2950b5ae344dSJohan Hedberg 		       hdev->name);
2951b5ae344dSJohan Hedberg 		return;
2952b5ae344dSJohan Hedberg 	}
2953b5ae344dSJohan Hedberg 
2954b5ae344dSJohan Hedberg 	set_bit(SMP_FLAG_SC, &smp->flags);
2955b5ae344dSJohan Hedberg 
2956b5ae344dSJohan Hedberg 	BT_DBG("%s starting SMP over BR/EDR", hdev->name);
2957b5ae344dSJohan Hedberg 
2958b5ae344dSJohan Hedberg 	/* Prepare and send the BR/EDR SMP Pairing Request */
2959b5ae344dSJohan Hedberg 	build_bredr_pairing_cmd(smp, &req, NULL);
2960b5ae344dSJohan Hedberg 
2961b5ae344dSJohan Hedberg 	smp->preq[0] = SMP_CMD_PAIRING_REQ;
2962b5ae344dSJohan Hedberg 	memcpy(&smp->preq[1], &req, sizeof(req));
2963b5ae344dSJohan Hedberg 
2964b5ae344dSJohan Hedberg 	smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(req), &req);
2965b5ae344dSJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP);
2966b5ae344dSJohan Hedberg }
2967b5ae344dSJohan Hedberg 
296844f1a7abSJohan Hedberg static void smp_resume_cb(struct l2cap_chan *chan)
296944f1a7abSJohan Hedberg {
2970b68fda68SJohan Hedberg 	struct smp_chan *smp = chan->data;
297144f1a7abSJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
297244f1a7abSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
297344f1a7abSJohan Hedberg 
297444f1a7abSJohan Hedberg 	BT_DBG("chan %p", chan);
297544f1a7abSJohan Hedberg 
2976b5ae344dSJohan Hedberg 	if (hcon->type == ACL_LINK) {
2977b5ae344dSJohan Hedberg 		bredr_pairing(chan);
2978ef8efe4bSJohan Hedberg 		return;
2979b5ae344dSJohan Hedberg 	}
2980ef8efe4bSJohan Hedberg 
298186d1407cSJohan Hedberg 	if (!smp)
298286d1407cSJohan Hedberg 		return;
2983b68fda68SJohan Hedberg 
298484bc0db5SJohan Hedberg 	if (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags))
298584bc0db5SJohan Hedberg 		return;
298684bc0db5SJohan Hedberg 
2987b68fda68SJohan Hedberg 	cancel_delayed_work(&smp->security_timer);
298886d1407cSJohan Hedberg 
2989d6268e86SJohan Hedberg 	smp_distribute_keys(smp);
299044f1a7abSJohan Hedberg }
299144f1a7abSJohan Hedberg 
299270db83c4SJohan Hedberg static void smp_ready_cb(struct l2cap_chan *chan)
299370db83c4SJohan Hedberg {
299470db83c4SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
2995b5ae344dSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
299670db83c4SJohan Hedberg 
299770db83c4SJohan Hedberg 	BT_DBG("chan %p", chan);
299870db83c4SJohan Hedberg 
299970db83c4SJohan Hedberg 	conn->smp = chan;
300070db83c4SJohan Hedberg 	l2cap_chan_hold(chan);
3001b5ae344dSJohan Hedberg 
3002b5ae344dSJohan Hedberg 	if (hcon->type == ACL_LINK && test_bit(HCI_CONN_ENCRYPT, &hcon->flags))
3003b5ae344dSJohan Hedberg 		bredr_pairing(chan);
300470db83c4SJohan Hedberg }
300570db83c4SJohan Hedberg 
30064befb867SJohan Hedberg static int smp_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
30074befb867SJohan Hedberg {
30084befb867SJohan Hedberg 	int err;
30094befb867SJohan Hedberg 
30104befb867SJohan Hedberg 	BT_DBG("chan %p", chan);
30114befb867SJohan Hedberg 
30124befb867SJohan Hedberg 	err = smp_sig_channel(chan, skb);
30134befb867SJohan Hedberg 	if (err) {
3014b68fda68SJohan Hedberg 		struct smp_chan *smp = chan->data;
30154befb867SJohan Hedberg 
3016b68fda68SJohan Hedberg 		if (smp)
3017b68fda68SJohan Hedberg 			cancel_delayed_work_sync(&smp->security_timer);
30184befb867SJohan Hedberg 
30191e91c29eSJohan Hedberg 		hci_disconnect(chan->conn->hcon, HCI_ERROR_AUTH_FAILURE);
30204befb867SJohan Hedberg 	}
30214befb867SJohan Hedberg 
30224befb867SJohan Hedberg 	return err;
30234befb867SJohan Hedberg }
30244befb867SJohan Hedberg 
302570db83c4SJohan Hedberg static struct sk_buff *smp_alloc_skb_cb(struct l2cap_chan *chan,
302670db83c4SJohan Hedberg 					unsigned long hdr_len,
302770db83c4SJohan Hedberg 					unsigned long len, int nb)
302870db83c4SJohan Hedberg {
302970db83c4SJohan Hedberg 	struct sk_buff *skb;
303070db83c4SJohan Hedberg 
303170db83c4SJohan Hedberg 	skb = bt_skb_alloc(hdr_len + len, GFP_KERNEL);
303270db83c4SJohan Hedberg 	if (!skb)
303370db83c4SJohan Hedberg 		return ERR_PTR(-ENOMEM);
303470db83c4SJohan Hedberg 
303570db83c4SJohan Hedberg 	skb->priority = HCI_PRIO_MAX;
3036a4368ff3SJohan Hedberg 	bt_cb(skb)->l2cap.chan = chan;
303770db83c4SJohan Hedberg 
303870db83c4SJohan Hedberg 	return skb;
303970db83c4SJohan Hedberg }
304070db83c4SJohan Hedberg 
304170db83c4SJohan Hedberg static const struct l2cap_ops smp_chan_ops = {
304270db83c4SJohan Hedberg 	.name			= "Security Manager",
304370db83c4SJohan Hedberg 	.ready			= smp_ready_cb,
30445d88cc73SJohan Hedberg 	.recv			= smp_recv_cb,
304570db83c4SJohan Hedberg 	.alloc_skb		= smp_alloc_skb_cb,
304670db83c4SJohan Hedberg 	.teardown		= smp_teardown_cb,
304744f1a7abSJohan Hedberg 	.resume			= smp_resume_cb,
304870db83c4SJohan Hedberg 
304970db83c4SJohan Hedberg 	.new_connection		= l2cap_chan_no_new_connection,
305070db83c4SJohan Hedberg 	.state_change		= l2cap_chan_no_state_change,
305170db83c4SJohan Hedberg 	.close			= l2cap_chan_no_close,
305270db83c4SJohan Hedberg 	.defer			= l2cap_chan_no_defer,
305370db83c4SJohan Hedberg 	.suspend		= l2cap_chan_no_suspend,
305470db83c4SJohan Hedberg 	.set_shutdown		= l2cap_chan_no_set_shutdown,
305570db83c4SJohan Hedberg 	.get_sndtimeo		= l2cap_chan_no_get_sndtimeo,
305670db83c4SJohan Hedberg };
305770db83c4SJohan Hedberg 
305870db83c4SJohan Hedberg static inline struct l2cap_chan *smp_new_conn_cb(struct l2cap_chan *pchan)
305970db83c4SJohan Hedberg {
306070db83c4SJohan Hedberg 	struct l2cap_chan *chan;
306170db83c4SJohan Hedberg 
306270db83c4SJohan Hedberg 	BT_DBG("pchan %p", pchan);
306370db83c4SJohan Hedberg 
306470db83c4SJohan Hedberg 	chan = l2cap_chan_create();
306570db83c4SJohan Hedberg 	if (!chan)
306670db83c4SJohan Hedberg 		return NULL;
306770db83c4SJohan Hedberg 
306870db83c4SJohan Hedberg 	chan->chan_type	= pchan->chan_type;
306970db83c4SJohan Hedberg 	chan->ops	= &smp_chan_ops;
307070db83c4SJohan Hedberg 	chan->scid	= pchan->scid;
307170db83c4SJohan Hedberg 	chan->dcid	= chan->scid;
307270db83c4SJohan Hedberg 	chan->imtu	= pchan->imtu;
307370db83c4SJohan Hedberg 	chan->omtu	= pchan->omtu;
307470db83c4SJohan Hedberg 	chan->mode	= pchan->mode;
307570db83c4SJohan Hedberg 
3076abe84903SJohan Hedberg 	/* Other L2CAP channels may request SMP routines in order to
3077abe84903SJohan Hedberg 	 * change the security level. This means that the SMP channel
3078abe84903SJohan Hedberg 	 * lock must be considered in its own category to avoid lockdep
3079abe84903SJohan Hedberg 	 * warnings.
3080abe84903SJohan Hedberg 	 */
3081abe84903SJohan Hedberg 	atomic_set(&chan->nesting, L2CAP_NESTING_SMP);
3082abe84903SJohan Hedberg 
308370db83c4SJohan Hedberg 	BT_DBG("created chan %p", chan);
308470db83c4SJohan Hedberg 
308570db83c4SJohan Hedberg 	return chan;
308670db83c4SJohan Hedberg }
308770db83c4SJohan Hedberg 
308870db83c4SJohan Hedberg static const struct l2cap_ops smp_root_chan_ops = {
308970db83c4SJohan Hedberg 	.name			= "Security Manager Root",
309070db83c4SJohan Hedberg 	.new_connection		= smp_new_conn_cb,
309170db83c4SJohan Hedberg 
309270db83c4SJohan Hedberg 	/* None of these are implemented for the root channel */
309370db83c4SJohan Hedberg 	.close			= l2cap_chan_no_close,
309470db83c4SJohan Hedberg 	.alloc_skb		= l2cap_chan_no_alloc_skb,
309570db83c4SJohan Hedberg 	.recv			= l2cap_chan_no_recv,
309670db83c4SJohan Hedberg 	.state_change		= l2cap_chan_no_state_change,
309770db83c4SJohan Hedberg 	.teardown		= l2cap_chan_no_teardown,
309870db83c4SJohan Hedberg 	.ready			= l2cap_chan_no_ready,
309970db83c4SJohan Hedberg 	.defer			= l2cap_chan_no_defer,
310070db83c4SJohan Hedberg 	.suspend		= l2cap_chan_no_suspend,
310170db83c4SJohan Hedberg 	.resume			= l2cap_chan_no_resume,
310270db83c4SJohan Hedberg 	.set_shutdown		= l2cap_chan_no_set_shutdown,
310370db83c4SJohan Hedberg 	.get_sndtimeo		= l2cap_chan_no_get_sndtimeo,
310470db83c4SJohan Hedberg };
310570db83c4SJohan Hedberg 
3106ef8efe4bSJohan Hedberg static struct l2cap_chan *smp_add_cid(struct hci_dev *hdev, u16 cid)
3107711eafe3SJohan Hedberg {
310870db83c4SJohan Hedberg 	struct l2cap_chan *chan;
310988a479d9SMarcel Holtmann 	struct smp_dev *smp;
3110defce9e8SJohan Hedberg 	struct crypto_blkcipher *tfm_aes;
31116e2dc6d1SMarcel Holtmann 	struct crypto_hash *tfm_cmac;
311270db83c4SJohan Hedberg 
3113ef8efe4bSJohan Hedberg 	if (cid == L2CAP_CID_SMP_BREDR) {
311488a479d9SMarcel Holtmann 		smp = NULL;
3115ef8efe4bSJohan Hedberg 		goto create_chan;
3116ef8efe4bSJohan Hedberg 	}
3117711eafe3SJohan Hedberg 
311888a479d9SMarcel Holtmann 	smp = kzalloc(sizeof(*smp), GFP_KERNEL);
311988a479d9SMarcel Holtmann 	if (!smp)
312088a479d9SMarcel Holtmann 		return ERR_PTR(-ENOMEM);
312188a479d9SMarcel Holtmann 
312288a479d9SMarcel Holtmann 	tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
3123defce9e8SJohan Hedberg 	if (IS_ERR(tfm_aes)) {
312488a479d9SMarcel Holtmann 		BT_ERR("Unable to create ECB crypto context");
312588a479d9SMarcel Holtmann 		kzfree(smp);
3126fe700771SFengguang Wu 		return ERR_CAST(tfm_aes);
3127711eafe3SJohan Hedberg 	}
3128711eafe3SJohan Hedberg 
31296e2dc6d1SMarcel Holtmann 	tfm_cmac = crypto_alloc_hash("cmac(aes)", 0, CRYPTO_ALG_ASYNC);
31306e2dc6d1SMarcel Holtmann 	if (IS_ERR(tfm_cmac)) {
31316e2dc6d1SMarcel Holtmann 		BT_ERR("Unable to create CMAC crypto context");
31326e2dc6d1SMarcel Holtmann 		crypto_free_blkcipher(tfm_aes);
31336e2dc6d1SMarcel Holtmann 		kzfree(smp);
31346e2dc6d1SMarcel Holtmann 		return ERR_CAST(tfm_cmac);
31356e2dc6d1SMarcel Holtmann 	}
31366e2dc6d1SMarcel Holtmann 
313788a479d9SMarcel Holtmann 	smp->tfm_aes = tfm_aes;
31386e2dc6d1SMarcel Holtmann 	smp->tfm_cmac = tfm_cmac;
31392fd36558SJohan Hedberg 	smp->max_key_size = SMP_MAX_ENC_KEY_SIZE;
314088a479d9SMarcel Holtmann 
3141ef8efe4bSJohan Hedberg create_chan:
314270db83c4SJohan Hedberg 	chan = l2cap_chan_create();
314370db83c4SJohan Hedberg 	if (!chan) {
314463511f6dSMarcel Holtmann 		if (smp) {
314588a479d9SMarcel Holtmann 			crypto_free_blkcipher(smp->tfm_aes);
31466e2dc6d1SMarcel Holtmann 			crypto_free_hash(smp->tfm_cmac);
314788a479d9SMarcel Holtmann 			kzfree(smp);
314863511f6dSMarcel Holtmann 		}
3149ef8efe4bSJohan Hedberg 		return ERR_PTR(-ENOMEM);
315070db83c4SJohan Hedberg 	}
315170db83c4SJohan Hedberg 
315288a479d9SMarcel Holtmann 	chan->data = smp;
3153defce9e8SJohan Hedberg 
3154ef8efe4bSJohan Hedberg 	l2cap_add_scid(chan, cid);
315570db83c4SJohan Hedberg 
315670db83c4SJohan Hedberg 	l2cap_chan_set_defaults(chan);
315770db83c4SJohan Hedberg 
3158157029baSMarcel Holtmann 	if (cid == L2CAP_CID_SMP) {
315939e3e744SJohan Hedberg 		u8 bdaddr_type;
316039e3e744SJohan Hedberg 
316139e3e744SJohan Hedberg 		hci_copy_identity_address(hdev, &chan->src, &bdaddr_type);
316239e3e744SJohan Hedberg 
316339e3e744SJohan Hedberg 		if (bdaddr_type == ADDR_LE_DEV_PUBLIC)
316470db83c4SJohan Hedberg 			chan->src_type = BDADDR_LE_PUBLIC;
316539e3e744SJohan Hedberg 		else
316639e3e744SJohan Hedberg 			chan->src_type = BDADDR_LE_RANDOM;
3167157029baSMarcel Holtmann 	} else {
3168157029baSMarcel Holtmann 		bacpy(&chan->src, &hdev->bdaddr);
3169ef8efe4bSJohan Hedberg 		chan->src_type = BDADDR_BREDR;
3170157029baSMarcel Holtmann 	}
3171157029baSMarcel Holtmann 
317270db83c4SJohan Hedberg 	chan->state = BT_LISTEN;
317370db83c4SJohan Hedberg 	chan->mode = L2CAP_MODE_BASIC;
317470db83c4SJohan Hedberg 	chan->imtu = L2CAP_DEFAULT_MTU;
317570db83c4SJohan Hedberg 	chan->ops = &smp_root_chan_ops;
317670db83c4SJohan Hedberg 
3177abe84903SJohan Hedberg 	/* Set correct nesting level for a parent/listening channel */
3178abe84903SJohan Hedberg 	atomic_set(&chan->nesting, L2CAP_NESTING_PARENT);
3179abe84903SJohan Hedberg 
3180ef8efe4bSJohan Hedberg 	return chan;
3181711eafe3SJohan Hedberg }
3182711eafe3SJohan Hedberg 
3183ef8efe4bSJohan Hedberg static void smp_del_chan(struct l2cap_chan *chan)
3184711eafe3SJohan Hedberg {
318588a479d9SMarcel Holtmann 	struct smp_dev *smp;
318670db83c4SJohan Hedberg 
3187ef8efe4bSJohan Hedberg 	BT_DBG("chan %p", chan);
3188711eafe3SJohan Hedberg 
318988a479d9SMarcel Holtmann 	smp = chan->data;
319088a479d9SMarcel Holtmann 	if (smp) {
3191defce9e8SJohan Hedberg 		chan->data = NULL;
319288a479d9SMarcel Holtmann 		if (smp->tfm_aes)
319388a479d9SMarcel Holtmann 			crypto_free_blkcipher(smp->tfm_aes);
31946e2dc6d1SMarcel Holtmann 		if (smp->tfm_cmac)
31956e2dc6d1SMarcel Holtmann 			crypto_free_hash(smp->tfm_cmac);
319688a479d9SMarcel Holtmann 		kzfree(smp);
3197711eafe3SJohan Hedberg 	}
319870db83c4SJohan Hedberg 
319970db83c4SJohan Hedberg 	l2cap_chan_put(chan);
3200711eafe3SJohan Hedberg }
3201ef8efe4bSJohan Hedberg 
3202300acfdeSMarcel Holtmann static ssize_t force_bredr_smp_read(struct file *file,
3203300acfdeSMarcel Holtmann 				    char __user *user_buf,
3204300acfdeSMarcel Holtmann 				    size_t count, loff_t *ppos)
3205300acfdeSMarcel Holtmann {
3206300acfdeSMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
3207300acfdeSMarcel Holtmann 	char buf[3];
3208300acfdeSMarcel Holtmann 
3209b7cb93e5SMarcel Holtmann 	buf[0] = hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP) ? 'Y': 'N';
3210300acfdeSMarcel Holtmann 	buf[1] = '\n';
3211300acfdeSMarcel Holtmann 	buf[2] = '\0';
3212300acfdeSMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
3213300acfdeSMarcel Holtmann }
3214300acfdeSMarcel Holtmann 
3215300acfdeSMarcel Holtmann static ssize_t force_bredr_smp_write(struct file *file,
3216300acfdeSMarcel Holtmann 				     const char __user *user_buf,
3217300acfdeSMarcel Holtmann 				     size_t count, loff_t *ppos)
3218300acfdeSMarcel Holtmann {
3219300acfdeSMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
3220300acfdeSMarcel Holtmann 	char buf[32];
3221300acfdeSMarcel Holtmann 	size_t buf_size = min(count, (sizeof(buf)-1));
3222300acfdeSMarcel Holtmann 	bool enable;
3223300acfdeSMarcel Holtmann 
3224300acfdeSMarcel Holtmann 	if (copy_from_user(buf, user_buf, buf_size))
3225300acfdeSMarcel Holtmann 		return -EFAULT;
3226300acfdeSMarcel Holtmann 
3227300acfdeSMarcel Holtmann 	buf[buf_size] = '\0';
3228300acfdeSMarcel Holtmann 	if (strtobool(buf, &enable))
3229300acfdeSMarcel Holtmann 		return -EINVAL;
3230300acfdeSMarcel Holtmann 
3231b7cb93e5SMarcel Holtmann 	if (enable == hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP))
3232300acfdeSMarcel Holtmann 		return -EALREADY;
3233300acfdeSMarcel Holtmann 
3234300acfdeSMarcel Holtmann 	if (enable) {
3235300acfdeSMarcel Holtmann 		struct l2cap_chan *chan;
3236300acfdeSMarcel Holtmann 
3237300acfdeSMarcel Holtmann 		chan = smp_add_cid(hdev, L2CAP_CID_SMP_BREDR);
3238300acfdeSMarcel Holtmann 		if (IS_ERR(chan))
3239300acfdeSMarcel Holtmann 			return PTR_ERR(chan);
3240300acfdeSMarcel Holtmann 
3241300acfdeSMarcel Holtmann 		hdev->smp_bredr_data = chan;
3242300acfdeSMarcel Holtmann 	} else {
3243300acfdeSMarcel Holtmann 		struct l2cap_chan *chan;
3244300acfdeSMarcel Holtmann 
3245300acfdeSMarcel Holtmann 		chan = hdev->smp_bredr_data;
3246300acfdeSMarcel Holtmann 		hdev->smp_bredr_data = NULL;
3247300acfdeSMarcel Holtmann 		smp_del_chan(chan);
3248300acfdeSMarcel Holtmann 	}
3249300acfdeSMarcel Holtmann 
3250b7cb93e5SMarcel Holtmann 	hci_dev_change_flag(hdev, HCI_FORCE_BREDR_SMP);
3251300acfdeSMarcel Holtmann 
3252300acfdeSMarcel Holtmann 	return count;
3253300acfdeSMarcel Holtmann }
3254300acfdeSMarcel Holtmann 
3255300acfdeSMarcel Holtmann static const struct file_operations force_bredr_smp_fops = {
3256300acfdeSMarcel Holtmann 	.open		= simple_open,
3257300acfdeSMarcel Holtmann 	.read		= force_bredr_smp_read,
3258300acfdeSMarcel Holtmann 	.write		= force_bredr_smp_write,
3259300acfdeSMarcel Holtmann 	.llseek		= default_llseek,
3260300acfdeSMarcel Holtmann };
3261300acfdeSMarcel Holtmann 
32622fd36558SJohan Hedberg static ssize_t le_max_key_size_read(struct file *file,
32632fd36558SJohan Hedberg 				     char __user *user_buf,
32642fd36558SJohan Hedberg 				     size_t count, loff_t *ppos)
32652fd36558SJohan Hedberg {
32662fd36558SJohan Hedberg 	struct hci_dev *hdev = file->private_data;
32672fd36558SJohan Hedberg 	char buf[4];
32682fd36558SJohan Hedberg 
32692fd36558SJohan Hedberg 	snprintf(buf, sizeof(buf), "%2u\n", SMP_DEV(hdev)->max_key_size);
32702fd36558SJohan Hedberg 
32712fd36558SJohan Hedberg 	return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
32722fd36558SJohan Hedberg }
32732fd36558SJohan Hedberg 
32742fd36558SJohan Hedberg static ssize_t le_max_key_size_write(struct file *file,
32752fd36558SJohan Hedberg 				      const char __user *user_buf,
32762fd36558SJohan Hedberg 				      size_t count, loff_t *ppos)
32772fd36558SJohan Hedberg {
32782fd36558SJohan Hedberg 	struct hci_dev *hdev = file->private_data;
32792fd36558SJohan Hedberg 	char buf[32];
32802fd36558SJohan Hedberg 	size_t buf_size = min(count, (sizeof(buf) - 1));
32812fd36558SJohan Hedberg 	u8 key_size;
32822fd36558SJohan Hedberg 
32832fd36558SJohan Hedberg 	if (copy_from_user(buf, user_buf, buf_size))
32842fd36558SJohan Hedberg 		return -EFAULT;
32852fd36558SJohan Hedberg 
32862fd36558SJohan Hedberg 	buf[buf_size] = '\0';
32872fd36558SJohan Hedberg 
32882fd36558SJohan Hedberg 	sscanf(buf, "%hhu", &key_size);
32892fd36558SJohan Hedberg 
32902fd36558SJohan Hedberg 	if (key_size > SMP_MAX_ENC_KEY_SIZE || key_size < SMP_MIN_ENC_KEY_SIZE)
32912fd36558SJohan Hedberg 		return -EINVAL;
32922fd36558SJohan Hedberg 
32932fd36558SJohan Hedberg 	SMP_DEV(hdev)->max_key_size = key_size;
32942fd36558SJohan Hedberg 
32952fd36558SJohan Hedberg 	return count;
32962fd36558SJohan Hedberg }
32972fd36558SJohan Hedberg 
32982fd36558SJohan Hedberg static const struct file_operations le_max_key_size_fops = {
32992fd36558SJohan Hedberg 	.open		= simple_open,
33002fd36558SJohan Hedberg 	.read		= le_max_key_size_read,
33012fd36558SJohan Hedberg 	.write		= le_max_key_size_write,
33022fd36558SJohan Hedberg 	.llseek		= default_llseek,
33032fd36558SJohan Hedberg };
33042fd36558SJohan Hedberg 
3305ef8efe4bSJohan Hedberg int smp_register(struct hci_dev *hdev)
3306ef8efe4bSJohan Hedberg {
3307ef8efe4bSJohan Hedberg 	struct l2cap_chan *chan;
3308ef8efe4bSJohan Hedberg 
3309ef8efe4bSJohan Hedberg 	BT_DBG("%s", hdev->name);
3310ef8efe4bSJohan Hedberg 
33117e7ec445SMarcel Holtmann 	/* If the controller does not support Low Energy operation, then
33127e7ec445SMarcel Holtmann 	 * there is also no need to register any SMP channel.
33137e7ec445SMarcel Holtmann 	 */
33147e7ec445SMarcel Holtmann 	if (!lmp_le_capable(hdev))
33157e7ec445SMarcel Holtmann 		return 0;
33167e7ec445SMarcel Holtmann 
33172b8df323SMarcel Holtmann 	if (WARN_ON(hdev->smp_data)) {
33182b8df323SMarcel Holtmann 		chan = hdev->smp_data;
33192b8df323SMarcel Holtmann 		hdev->smp_data = NULL;
33202b8df323SMarcel Holtmann 		smp_del_chan(chan);
33212b8df323SMarcel Holtmann 	}
33222b8df323SMarcel Holtmann 
3323ef8efe4bSJohan Hedberg 	chan = smp_add_cid(hdev, L2CAP_CID_SMP);
3324ef8efe4bSJohan Hedberg 	if (IS_ERR(chan))
3325ef8efe4bSJohan Hedberg 		return PTR_ERR(chan);
3326ef8efe4bSJohan Hedberg 
3327ef8efe4bSJohan Hedberg 	hdev->smp_data = chan;
3328ef8efe4bSJohan Hedberg 
33292fd36558SJohan Hedberg 	debugfs_create_file("le_max_key_size", 0644, hdev->debugfs, hdev,
33302fd36558SJohan Hedberg 			    &le_max_key_size_fops);
33312fd36558SJohan Hedberg 
3332300acfdeSMarcel Holtmann 	/* If the controller does not support BR/EDR Secure Connections
3333300acfdeSMarcel Holtmann 	 * feature, then the BR/EDR SMP channel shall not be present.
3334300acfdeSMarcel Holtmann 	 *
3335300acfdeSMarcel Holtmann 	 * To test this with Bluetooth 4.0 controllers, create a debugfs
3336300acfdeSMarcel Holtmann 	 * switch that allows forcing BR/EDR SMP support and accepting
3337300acfdeSMarcel Holtmann 	 * cross-transport pairing on non-AES encrypted connections.
3338300acfdeSMarcel Holtmann 	 */
3339300acfdeSMarcel Holtmann 	if (!lmp_sc_capable(hdev)) {
3340300acfdeSMarcel Holtmann 		debugfs_create_file("force_bredr_smp", 0644, hdev->debugfs,
3341300acfdeSMarcel Holtmann 				    hdev, &force_bredr_smp_fops);
3342ef8efe4bSJohan Hedberg 		return 0;
3343300acfdeSMarcel Holtmann 	}
3344ef8efe4bSJohan Hedberg 
33452b8df323SMarcel Holtmann 	if (WARN_ON(hdev->smp_bredr_data)) {
33462b8df323SMarcel Holtmann 		chan = hdev->smp_bredr_data;
33472b8df323SMarcel Holtmann 		hdev->smp_bredr_data = NULL;
33482b8df323SMarcel Holtmann 		smp_del_chan(chan);
33492b8df323SMarcel Holtmann 	}
33502b8df323SMarcel Holtmann 
3351ef8efe4bSJohan Hedberg 	chan = smp_add_cid(hdev, L2CAP_CID_SMP_BREDR);
3352ef8efe4bSJohan Hedberg 	if (IS_ERR(chan)) {
3353ef8efe4bSJohan Hedberg 		int err = PTR_ERR(chan);
3354ef8efe4bSJohan Hedberg 		chan = hdev->smp_data;
3355ef8efe4bSJohan Hedberg 		hdev->smp_data = NULL;
3356ef8efe4bSJohan Hedberg 		smp_del_chan(chan);
3357ef8efe4bSJohan Hedberg 		return err;
3358ef8efe4bSJohan Hedberg 	}
3359ef8efe4bSJohan Hedberg 
3360ef8efe4bSJohan Hedberg 	hdev->smp_bredr_data = chan;
3361ef8efe4bSJohan Hedberg 
3362ef8efe4bSJohan Hedberg 	return 0;
3363ef8efe4bSJohan Hedberg }
3364ef8efe4bSJohan Hedberg 
3365ef8efe4bSJohan Hedberg void smp_unregister(struct hci_dev *hdev)
3366ef8efe4bSJohan Hedberg {
3367ef8efe4bSJohan Hedberg 	struct l2cap_chan *chan;
3368ef8efe4bSJohan Hedberg 
3369ef8efe4bSJohan Hedberg 	if (hdev->smp_bredr_data) {
3370ef8efe4bSJohan Hedberg 		chan = hdev->smp_bredr_data;
3371ef8efe4bSJohan Hedberg 		hdev->smp_bredr_data = NULL;
3372ef8efe4bSJohan Hedberg 		smp_del_chan(chan);
3373ef8efe4bSJohan Hedberg 	}
3374ef8efe4bSJohan Hedberg 
3375ef8efe4bSJohan Hedberg 	if (hdev->smp_data) {
3376ef8efe4bSJohan Hedberg 		chan = hdev->smp_data;
3377ef8efe4bSJohan Hedberg 		hdev->smp_data = NULL;
3378ef8efe4bSJohan Hedberg 		smp_del_chan(chan);
3379ef8efe4bSJohan Hedberg 	}
3380ef8efe4bSJohan Hedberg }
33810a2b0f04SJohan Hedberg 
33820a2b0f04SJohan Hedberg #if IS_ENABLED(CONFIG_BT_SELFTEST_SMP)
33830a2b0f04SJohan Hedberg 
3384cfc4198eSJohan Hedberg static int __init test_ah(struct crypto_blkcipher *tfm_aes)
3385cfc4198eSJohan Hedberg {
3386cfc4198eSJohan Hedberg 	const u8 irk[16] = {
3387cfc4198eSJohan Hedberg 			0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34,
3388cfc4198eSJohan Hedberg 			0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec };
3389cfc4198eSJohan Hedberg 	const u8 r[3] = { 0x94, 0x81, 0x70 };
3390cfc4198eSJohan Hedberg 	const u8 exp[3] = { 0xaa, 0xfb, 0x0d };
3391cfc4198eSJohan Hedberg 	u8 res[3];
3392cfc4198eSJohan Hedberg 	int err;
3393cfc4198eSJohan Hedberg 
3394cfc4198eSJohan Hedberg 	err = smp_ah(tfm_aes, irk, r, res);
3395cfc4198eSJohan Hedberg 	if (err)
3396cfc4198eSJohan Hedberg 		return err;
3397cfc4198eSJohan Hedberg 
3398cfc4198eSJohan Hedberg 	if (memcmp(res, exp, 3))
3399cfc4198eSJohan Hedberg 		return -EINVAL;
3400cfc4198eSJohan Hedberg 
3401cfc4198eSJohan Hedberg 	return 0;
3402cfc4198eSJohan Hedberg }
3403cfc4198eSJohan Hedberg 
3404cfc4198eSJohan Hedberg static int __init test_c1(struct crypto_blkcipher *tfm_aes)
3405cfc4198eSJohan Hedberg {
3406cfc4198eSJohan Hedberg 	const u8 k[16] = {
3407cfc4198eSJohan Hedberg 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3408cfc4198eSJohan Hedberg 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
3409cfc4198eSJohan Hedberg 	const u8 r[16] = {
3410cfc4198eSJohan Hedberg 			0xe0, 0x2e, 0x70, 0xc6, 0x4e, 0x27, 0x88, 0x63,
3411cfc4198eSJohan Hedberg 			0x0e, 0x6f, 0xad, 0x56, 0x21, 0xd5, 0x83, 0x57 };
3412cfc4198eSJohan Hedberg 	const u8 preq[7] = { 0x01, 0x01, 0x00, 0x00, 0x10, 0x07, 0x07 };
3413cfc4198eSJohan Hedberg 	const u8 pres[7] = { 0x02, 0x03, 0x00, 0x00, 0x08, 0x00, 0x05 };
3414cfc4198eSJohan Hedberg 	const u8 _iat = 0x01;
3415cfc4198eSJohan Hedberg 	const u8 _rat = 0x00;
3416cfc4198eSJohan Hedberg 	const bdaddr_t ra = { { 0xb6, 0xb5, 0xb4, 0xb3, 0xb2, 0xb1 } };
3417cfc4198eSJohan Hedberg 	const bdaddr_t ia = { { 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1 } };
3418cfc4198eSJohan Hedberg 	const u8 exp[16] = {
3419cfc4198eSJohan Hedberg 			0x86, 0x3b, 0xf1, 0xbe, 0xc5, 0x4d, 0xa7, 0xd2,
3420cfc4198eSJohan Hedberg 			0xea, 0x88, 0x89, 0x87, 0xef, 0x3f, 0x1e, 0x1e };
3421cfc4198eSJohan Hedberg 	u8 res[16];
3422cfc4198eSJohan Hedberg 	int err;
3423cfc4198eSJohan Hedberg 
3424cfc4198eSJohan Hedberg 	err = smp_c1(tfm_aes, k, r, preq, pres, _iat, &ia, _rat, &ra, res);
3425cfc4198eSJohan Hedberg 	if (err)
3426cfc4198eSJohan Hedberg 		return err;
3427cfc4198eSJohan Hedberg 
3428cfc4198eSJohan Hedberg 	if (memcmp(res, exp, 16))
3429cfc4198eSJohan Hedberg 		return -EINVAL;
3430cfc4198eSJohan Hedberg 
3431cfc4198eSJohan Hedberg 	return 0;
3432cfc4198eSJohan Hedberg }
3433cfc4198eSJohan Hedberg 
3434cfc4198eSJohan Hedberg static int __init test_s1(struct crypto_blkcipher *tfm_aes)
3435cfc4198eSJohan Hedberg {
3436cfc4198eSJohan Hedberg 	const u8 k[16] = {
3437cfc4198eSJohan Hedberg 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3438cfc4198eSJohan Hedberg 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
3439cfc4198eSJohan Hedberg 	const u8 r1[16] = {
3440cfc4198eSJohan Hedberg 			0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 };
3441cfc4198eSJohan Hedberg 	const u8 r2[16] = {
3442cfc4198eSJohan Hedberg 			0x00, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99 };
3443cfc4198eSJohan Hedberg 	const u8 exp[16] = {
3444cfc4198eSJohan Hedberg 			0x62, 0xa0, 0x6d, 0x79, 0xae, 0x16, 0x42, 0x5b,
3445cfc4198eSJohan Hedberg 			0x9b, 0xf4, 0xb0, 0xe8, 0xf0, 0xe1, 0x1f, 0x9a };
3446cfc4198eSJohan Hedberg 	u8 res[16];
3447cfc4198eSJohan Hedberg 	int err;
3448cfc4198eSJohan Hedberg 
3449cfc4198eSJohan Hedberg 	err = smp_s1(tfm_aes, k, r1, r2, res);
3450cfc4198eSJohan Hedberg 	if (err)
3451cfc4198eSJohan Hedberg 		return err;
3452cfc4198eSJohan Hedberg 
3453cfc4198eSJohan Hedberg 	if (memcmp(res, exp, 16))
3454cfc4198eSJohan Hedberg 		return -EINVAL;
3455cfc4198eSJohan Hedberg 
3456cfc4198eSJohan Hedberg 	return 0;
3457cfc4198eSJohan Hedberg }
3458cfc4198eSJohan Hedberg 
3459fb2969a3SJohan Hedberg static int __init test_f4(struct crypto_hash *tfm_cmac)
3460fb2969a3SJohan Hedberg {
3461fb2969a3SJohan Hedberg 	const u8 u[32] = {
3462fb2969a3SJohan Hedberg 			0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc,
3463fb2969a3SJohan Hedberg 			0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef,
3464fb2969a3SJohan Hedberg 			0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e,
3465fb2969a3SJohan Hedberg 			0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20 };
3466fb2969a3SJohan Hedberg 	const u8 v[32] = {
3467fb2969a3SJohan Hedberg 			0xfd, 0xc5, 0x7f, 0xf4, 0x49, 0xdd, 0x4f, 0x6b,
3468fb2969a3SJohan Hedberg 			0xfb, 0x7c, 0x9d, 0xf1, 0xc2, 0x9a, 0xcb, 0x59,
3469fb2969a3SJohan Hedberg 			0x2a, 0xe7, 0xd4, 0xee, 0xfb, 0xfc, 0x0a, 0x90,
3470fb2969a3SJohan Hedberg 			0x9a, 0xbb, 0xf6, 0x32, 0x3d, 0x8b, 0x18, 0x55 };
3471fb2969a3SJohan Hedberg 	const u8 x[16] = {
3472fb2969a3SJohan Hedberg 			0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff,
3473fb2969a3SJohan Hedberg 			0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 };
3474fb2969a3SJohan Hedberg 	const u8 z = 0x00;
3475fb2969a3SJohan Hedberg 	const u8 exp[16] = {
3476fb2969a3SJohan Hedberg 			0x2d, 0x87, 0x74, 0xa9, 0xbe, 0xa1, 0xed, 0xf1,
3477fb2969a3SJohan Hedberg 			0x1c, 0xbd, 0xa9, 0x07, 0xf1, 0x16, 0xc9, 0xf2 };
3478fb2969a3SJohan Hedberg 	u8 res[16];
3479fb2969a3SJohan Hedberg 	int err;
3480fb2969a3SJohan Hedberg 
3481fb2969a3SJohan Hedberg 	err = smp_f4(tfm_cmac, u, v, x, z, res);
3482fb2969a3SJohan Hedberg 	if (err)
3483fb2969a3SJohan Hedberg 		return err;
3484fb2969a3SJohan Hedberg 
3485fb2969a3SJohan Hedberg 	if (memcmp(res, exp, 16))
3486fb2969a3SJohan Hedberg 		return -EINVAL;
3487fb2969a3SJohan Hedberg 
3488fb2969a3SJohan Hedberg 	return 0;
3489fb2969a3SJohan Hedberg }
3490fb2969a3SJohan Hedberg 
3491fb2969a3SJohan Hedberg static int __init test_f5(struct crypto_hash *tfm_cmac)
3492fb2969a3SJohan Hedberg {
3493fb2969a3SJohan Hedberg 	const u8 w[32] = {
3494fb2969a3SJohan Hedberg 			0x98, 0xa6, 0xbf, 0x73, 0xf3, 0x34, 0x8d, 0x86,
3495fb2969a3SJohan Hedberg 			0xf1, 0x66, 0xf8, 0xb4, 0x13, 0x6b, 0x79, 0x99,
3496fb2969a3SJohan Hedberg 			0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34,
3497fb2969a3SJohan Hedberg 			0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec };
3498fb2969a3SJohan Hedberg 	const u8 n1[16] = {
3499fb2969a3SJohan Hedberg 			0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff,
3500fb2969a3SJohan Hedberg 			0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 };
3501fb2969a3SJohan Hedberg 	const u8 n2[16] = {
3502fb2969a3SJohan Hedberg 			0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21,
3503fb2969a3SJohan Hedberg 			0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6 };
3504fb2969a3SJohan Hedberg 	const u8 a1[7] = { 0xce, 0xbf, 0x37, 0x37, 0x12, 0x56, 0x00 };
3505fb2969a3SJohan Hedberg 	const u8 a2[7] = { 0xc1, 0xcf, 0x2d, 0x70, 0x13, 0xa7, 0x00 };
3506fb2969a3SJohan Hedberg 	const u8 exp_ltk[16] = {
3507fb2969a3SJohan Hedberg 			0x38, 0x0a, 0x75, 0x94, 0xb5, 0x22, 0x05, 0x98,
3508fb2969a3SJohan Hedberg 			0x23, 0xcd, 0xd7, 0x69, 0x11, 0x79, 0x86, 0x69 };
3509fb2969a3SJohan Hedberg 	const u8 exp_mackey[16] = {
3510fb2969a3SJohan Hedberg 			0x20, 0x6e, 0x63, 0xce, 0x20, 0x6a, 0x3f, 0xfd,
3511fb2969a3SJohan Hedberg 			0x02, 0x4a, 0x08, 0xa1, 0x76, 0xf1, 0x65, 0x29 };
3512fb2969a3SJohan Hedberg 	u8 mackey[16], ltk[16];
3513fb2969a3SJohan Hedberg 	int err;
3514fb2969a3SJohan Hedberg 
3515fb2969a3SJohan Hedberg 	err = smp_f5(tfm_cmac, w, n1, n2, a1, a2, mackey, ltk);
3516fb2969a3SJohan Hedberg 	if (err)
3517fb2969a3SJohan Hedberg 		return err;
3518fb2969a3SJohan Hedberg 
3519fb2969a3SJohan Hedberg 	if (memcmp(mackey, exp_mackey, 16))
3520fb2969a3SJohan Hedberg 		return -EINVAL;
3521fb2969a3SJohan Hedberg 
3522fb2969a3SJohan Hedberg 	if (memcmp(ltk, exp_ltk, 16))
3523fb2969a3SJohan Hedberg 		return -EINVAL;
3524fb2969a3SJohan Hedberg 
3525fb2969a3SJohan Hedberg 	return 0;
3526fb2969a3SJohan Hedberg }
3527fb2969a3SJohan Hedberg 
3528fb2969a3SJohan Hedberg static int __init test_f6(struct crypto_hash *tfm_cmac)
3529fb2969a3SJohan Hedberg {
3530fb2969a3SJohan Hedberg 	const u8 w[16] = {
3531fb2969a3SJohan Hedberg 			0x20, 0x6e, 0x63, 0xce, 0x20, 0x6a, 0x3f, 0xfd,
3532fb2969a3SJohan Hedberg 			0x02, 0x4a, 0x08, 0xa1, 0x76, 0xf1, 0x65, 0x29 };
3533fb2969a3SJohan Hedberg 	const u8 n1[16] = {
3534fb2969a3SJohan Hedberg 			0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff,
3535fb2969a3SJohan Hedberg 			0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 };
3536fb2969a3SJohan Hedberg 	const u8 n2[16] = {
3537fb2969a3SJohan Hedberg 			0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21,
3538fb2969a3SJohan Hedberg 			0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6 };
3539fb2969a3SJohan Hedberg 	const u8 r[16] = {
3540fb2969a3SJohan Hedberg 			0xc8, 0x0f, 0x2d, 0x0c, 0xd2, 0x42, 0xda, 0x08,
3541fb2969a3SJohan Hedberg 			0x54, 0xbb, 0x53, 0xb4, 0x3b, 0x34, 0xa3, 0x12 };
3542fb2969a3SJohan Hedberg 	const u8 io_cap[3] = { 0x02, 0x01, 0x01 };
3543fb2969a3SJohan Hedberg 	const u8 a1[7] = { 0xce, 0xbf, 0x37, 0x37, 0x12, 0x56, 0x00 };
3544fb2969a3SJohan Hedberg 	const u8 a2[7] = { 0xc1, 0xcf, 0x2d, 0x70, 0x13, 0xa7, 0x00 };
3545fb2969a3SJohan Hedberg 	const u8 exp[16] = {
3546fb2969a3SJohan Hedberg 			0x61, 0x8f, 0x95, 0xda, 0x09, 0x0b, 0x6c, 0xd2,
3547fb2969a3SJohan Hedberg 			0xc5, 0xe8, 0xd0, 0x9c, 0x98, 0x73, 0xc4, 0xe3 };
3548fb2969a3SJohan Hedberg 	u8 res[16];
3549fb2969a3SJohan Hedberg 	int err;
3550fb2969a3SJohan Hedberg 
3551fb2969a3SJohan Hedberg 	err = smp_f6(tfm_cmac, w, n1, n2, r, io_cap, a1, a2, res);
3552fb2969a3SJohan Hedberg 	if (err)
3553fb2969a3SJohan Hedberg 		return err;
3554fb2969a3SJohan Hedberg 
3555fb2969a3SJohan Hedberg 	if (memcmp(res, exp, 16))
3556fb2969a3SJohan Hedberg 		return -EINVAL;
3557fb2969a3SJohan Hedberg 
3558fb2969a3SJohan Hedberg 	return 0;
3559fb2969a3SJohan Hedberg }
3560fb2969a3SJohan Hedberg 
3561fb2969a3SJohan Hedberg static int __init test_g2(struct crypto_hash *tfm_cmac)
3562fb2969a3SJohan Hedberg {
3563fb2969a3SJohan Hedberg 	const u8 u[32] = {
3564fb2969a3SJohan Hedberg 			0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc,
3565fb2969a3SJohan Hedberg 			0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef,
3566fb2969a3SJohan Hedberg 			0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e,
3567fb2969a3SJohan Hedberg 			0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20 };
3568fb2969a3SJohan Hedberg 	const u8 v[32] = {
3569fb2969a3SJohan Hedberg 			0xfd, 0xc5, 0x7f, 0xf4, 0x49, 0xdd, 0x4f, 0x6b,
3570fb2969a3SJohan Hedberg 			0xfb, 0x7c, 0x9d, 0xf1, 0xc2, 0x9a, 0xcb, 0x59,
3571fb2969a3SJohan Hedberg 			0x2a, 0xe7, 0xd4, 0xee, 0xfb, 0xfc, 0x0a, 0x90,
3572fb2969a3SJohan Hedberg 			0x9a, 0xbb, 0xf6, 0x32, 0x3d, 0x8b, 0x18, 0x55 };
3573fb2969a3SJohan Hedberg 	const u8 x[16] = {
3574fb2969a3SJohan Hedberg 			0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff,
3575fb2969a3SJohan Hedberg 			0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 };
3576fb2969a3SJohan Hedberg 	const u8 y[16] = {
3577fb2969a3SJohan Hedberg 			0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21,
3578fb2969a3SJohan Hedberg 			0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6 };
3579fb2969a3SJohan Hedberg 	const u32 exp_val = 0x2f9ed5ba % 1000000;
3580fb2969a3SJohan Hedberg 	u32 val;
3581fb2969a3SJohan Hedberg 	int err;
3582fb2969a3SJohan Hedberg 
3583fb2969a3SJohan Hedberg 	err = smp_g2(tfm_cmac, u, v, x, y, &val);
3584fb2969a3SJohan Hedberg 	if (err)
3585fb2969a3SJohan Hedberg 		return err;
3586fb2969a3SJohan Hedberg 
3587fb2969a3SJohan Hedberg 	if (val != exp_val)
3588fb2969a3SJohan Hedberg 		return -EINVAL;
3589fb2969a3SJohan Hedberg 
3590fb2969a3SJohan Hedberg 	return 0;
3591fb2969a3SJohan Hedberg }
3592fb2969a3SJohan Hedberg 
3593fb2969a3SJohan Hedberg static int __init test_h6(struct crypto_hash *tfm_cmac)
3594fb2969a3SJohan Hedberg {
3595fb2969a3SJohan Hedberg 	const u8 w[16] = {
3596fb2969a3SJohan Hedberg 			0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34,
3597fb2969a3SJohan Hedberg 			0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec };
3598fb2969a3SJohan Hedberg 	const u8 key_id[4] = { 0x72, 0x62, 0x65, 0x6c };
3599fb2969a3SJohan Hedberg 	const u8 exp[16] = {
3600fb2969a3SJohan Hedberg 			0x99, 0x63, 0xb1, 0x80, 0xe2, 0xa9, 0xd3, 0xe8,
3601fb2969a3SJohan Hedberg 			0x1c, 0xc9, 0x6d, 0xe7, 0x02, 0xe1, 0x9a, 0x2d };
3602fb2969a3SJohan Hedberg 	u8 res[16];
3603fb2969a3SJohan Hedberg 	int err;
3604fb2969a3SJohan Hedberg 
3605fb2969a3SJohan Hedberg 	err = smp_h6(tfm_cmac, w, key_id, res);
3606fb2969a3SJohan Hedberg 	if (err)
3607fb2969a3SJohan Hedberg 		return err;
3608fb2969a3SJohan Hedberg 
3609fb2969a3SJohan Hedberg 	if (memcmp(res, exp, 16))
3610fb2969a3SJohan Hedberg 		return -EINVAL;
3611fb2969a3SJohan Hedberg 
3612fb2969a3SJohan Hedberg 	return 0;
3613fb2969a3SJohan Hedberg }
3614fb2969a3SJohan Hedberg 
361564dd374eSMarcel Holtmann static char test_smp_buffer[32];
361664dd374eSMarcel Holtmann 
361764dd374eSMarcel Holtmann static ssize_t test_smp_read(struct file *file, char __user *user_buf,
361864dd374eSMarcel Holtmann 			     size_t count, loff_t *ppos)
361964dd374eSMarcel Holtmann {
362064dd374eSMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, test_smp_buffer,
362164dd374eSMarcel Holtmann 				       strlen(test_smp_buffer));
362264dd374eSMarcel Holtmann }
362364dd374eSMarcel Holtmann 
362464dd374eSMarcel Holtmann static const struct file_operations test_smp_fops = {
362564dd374eSMarcel Holtmann 	.open		= simple_open,
362664dd374eSMarcel Holtmann 	.read		= test_smp_read,
362764dd374eSMarcel Holtmann 	.llseek		= default_llseek,
362864dd374eSMarcel Holtmann };
362964dd374eSMarcel Holtmann 
36300a2b0f04SJohan Hedberg static int __init run_selftests(struct crypto_blkcipher *tfm_aes,
36310a2b0f04SJohan Hedberg 				struct crypto_hash *tfm_cmac)
36320a2b0f04SJohan Hedberg {
3633255047b0SMarcel Holtmann 	ktime_t calltime, delta, rettime;
3634255047b0SMarcel Holtmann 	unsigned long long duration;
3635cfc4198eSJohan Hedberg 	int err;
3636cfc4198eSJohan Hedberg 
3637255047b0SMarcel Holtmann 	calltime = ktime_get();
3638255047b0SMarcel Holtmann 
3639cfc4198eSJohan Hedberg 	err = test_ah(tfm_aes);
3640cfc4198eSJohan Hedberg 	if (err) {
3641cfc4198eSJohan Hedberg 		BT_ERR("smp_ah test failed");
364264dd374eSMarcel Holtmann 		goto done;
3643cfc4198eSJohan Hedberg 	}
3644cfc4198eSJohan Hedberg 
3645cfc4198eSJohan Hedberg 	err = test_c1(tfm_aes);
3646cfc4198eSJohan Hedberg 	if (err) {
3647cfc4198eSJohan Hedberg 		BT_ERR("smp_c1 test failed");
364864dd374eSMarcel Holtmann 		goto done;
3649cfc4198eSJohan Hedberg 	}
3650cfc4198eSJohan Hedberg 
3651cfc4198eSJohan Hedberg 	err = test_s1(tfm_aes);
3652cfc4198eSJohan Hedberg 	if (err) {
3653cfc4198eSJohan Hedberg 		BT_ERR("smp_s1 test failed");
365464dd374eSMarcel Holtmann 		goto done;
3655cfc4198eSJohan Hedberg 	}
3656cfc4198eSJohan Hedberg 
3657fb2969a3SJohan Hedberg 	err = test_f4(tfm_cmac);
3658fb2969a3SJohan Hedberg 	if (err) {
3659fb2969a3SJohan Hedberg 		BT_ERR("smp_f4 test failed");
366064dd374eSMarcel Holtmann 		goto done;
3661fb2969a3SJohan Hedberg 	}
3662fb2969a3SJohan Hedberg 
3663fb2969a3SJohan Hedberg 	err = test_f5(tfm_cmac);
3664fb2969a3SJohan Hedberg 	if (err) {
3665fb2969a3SJohan Hedberg 		BT_ERR("smp_f5 test failed");
366664dd374eSMarcel Holtmann 		goto done;
3667fb2969a3SJohan Hedberg 	}
3668fb2969a3SJohan Hedberg 
3669fb2969a3SJohan Hedberg 	err = test_f6(tfm_cmac);
3670fb2969a3SJohan Hedberg 	if (err) {
3671fb2969a3SJohan Hedberg 		BT_ERR("smp_f6 test failed");
367264dd374eSMarcel Holtmann 		goto done;
3673fb2969a3SJohan Hedberg 	}
3674fb2969a3SJohan Hedberg 
3675fb2969a3SJohan Hedberg 	err = test_g2(tfm_cmac);
3676fb2969a3SJohan Hedberg 	if (err) {
3677fb2969a3SJohan Hedberg 		BT_ERR("smp_g2 test failed");
367864dd374eSMarcel Holtmann 		goto done;
3679fb2969a3SJohan Hedberg 	}
3680fb2969a3SJohan Hedberg 
3681fb2969a3SJohan Hedberg 	err = test_h6(tfm_cmac);
3682fb2969a3SJohan Hedberg 	if (err) {
3683fb2969a3SJohan Hedberg 		BT_ERR("smp_h6 test failed");
368464dd374eSMarcel Holtmann 		goto done;
3685fb2969a3SJohan Hedberg 	}
3686fb2969a3SJohan Hedberg 
3687255047b0SMarcel Holtmann 	rettime = ktime_get();
3688255047b0SMarcel Holtmann 	delta = ktime_sub(rettime, calltime);
3689255047b0SMarcel Holtmann 	duration = (unsigned long long) ktime_to_ns(delta) >> 10;
3690255047b0SMarcel Holtmann 
36915ced2464SMarcel Holtmann 	BT_INFO("SMP test passed in %llu usecs", duration);
36920a2b0f04SJohan Hedberg 
369364dd374eSMarcel Holtmann done:
369464dd374eSMarcel Holtmann 	if (!err)
369564dd374eSMarcel Holtmann 		snprintf(test_smp_buffer, sizeof(test_smp_buffer),
369664dd374eSMarcel Holtmann 			 "PASS (%llu usecs)\n", duration);
369764dd374eSMarcel Holtmann 	else
369864dd374eSMarcel Holtmann 		snprintf(test_smp_buffer, sizeof(test_smp_buffer), "FAIL\n");
369964dd374eSMarcel Holtmann 
370064dd374eSMarcel Holtmann 	debugfs_create_file("selftest_smp", 0444, bt_debugfs, NULL,
370164dd374eSMarcel Holtmann 			    &test_smp_fops);
370264dd374eSMarcel Holtmann 
370364dd374eSMarcel Holtmann 	return err;
37040a2b0f04SJohan Hedberg }
37050a2b0f04SJohan Hedberg 
37060a2b0f04SJohan Hedberg int __init bt_selftest_smp(void)
37070a2b0f04SJohan Hedberg {
37080a2b0f04SJohan Hedberg 	struct crypto_blkcipher *tfm_aes;
37090a2b0f04SJohan Hedberg 	struct crypto_hash *tfm_cmac;
37100a2b0f04SJohan Hedberg 	int err;
37110a2b0f04SJohan Hedberg 
37120a2b0f04SJohan Hedberg 	tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
37130a2b0f04SJohan Hedberg 	if (IS_ERR(tfm_aes)) {
37140a2b0f04SJohan Hedberg 		BT_ERR("Unable to create ECB crypto context");
37150a2b0f04SJohan Hedberg 		return PTR_ERR(tfm_aes);
37160a2b0f04SJohan Hedberg 	}
37170a2b0f04SJohan Hedberg 
37180a2b0f04SJohan Hedberg 	tfm_cmac = crypto_alloc_hash("cmac(aes)", 0, CRYPTO_ALG_ASYNC);
37190a2b0f04SJohan Hedberg 	if (IS_ERR(tfm_cmac)) {
37200a2b0f04SJohan Hedberg 		BT_ERR("Unable to create CMAC crypto context");
37210a2b0f04SJohan Hedberg 		crypto_free_blkcipher(tfm_aes);
37220a2b0f04SJohan Hedberg 		return PTR_ERR(tfm_cmac);
37230a2b0f04SJohan Hedberg 	}
37240a2b0f04SJohan Hedberg 
37250a2b0f04SJohan Hedberg 	err = run_selftests(tfm_aes, tfm_cmac);
37260a2b0f04SJohan Hedberg 
37270a2b0f04SJohan Hedberg 	crypto_free_hash(tfm_cmac);
37280a2b0f04SJohan Hedberg 	crypto_free_blkcipher(tfm_aes);
37290a2b0f04SJohan Hedberg 
37300a2b0f04SJohan Hedberg 	return err;
37310a2b0f04SJohan Hedberg }
37320a2b0f04SJohan Hedberg 
37330a2b0f04SJohan Hedberg #endif
3734