xref: /openbmc/linux/net/bluetooth/smp.c (revision 865f1f43)
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/scatterlist.h>
25a4770e11SAndy Lutomirski #include <linux/crypto.h>
2628a220aaSArd Biesheuvel #include <crypto/aes.h>
27329d8230SJason A. Donenfeld #include <crypto/algapi.h>
2871af2f6bSHerbert Xu #include <crypto/hash.h>
2947eb2ac8STudor Ambarus #include <crypto/kpp.h>
308c520a59SGustavo Padovan 
31eb492e01SAnderson Briglia #include <net/bluetooth/bluetooth.h>
32eb492e01SAnderson Briglia #include <net/bluetooth/hci_core.h>
33eb492e01SAnderson Briglia #include <net/bluetooth/l2cap.h>
342b64d153SBrian Gix #include <net/bluetooth/mgmt.h>
35ac4b7236SMarcel Holtmann 
3658771c1cSSalvatore Benedetto #include "ecdh_helper.h"
37ac4b7236SMarcel Holtmann #include "smp.h"
38d22ef0bcSAnderson Briglia 
392fd36558SJohan Hedberg #define SMP_DEV(hdev) \
402fd36558SJohan Hedberg 	((struct smp_dev *)((struct l2cap_chan *)((hdev)->smp_data))->data)
412fd36558SJohan Hedberg 
42c7a3d57dSJohan Hedberg /* Low-level debug macros to be used for stuff that we don't want
4391641b79SZheng Yongjun  * accidentally in dmesg, i.e. the values of the various crypto keys
44c7a3d57dSJohan Hedberg  * and the inputs & outputs of crypto functions.
45c7a3d57dSJohan Hedberg  */
46c7a3d57dSJohan Hedberg #ifdef DEBUG
47c7a3d57dSJohan Hedberg #define SMP_DBG(fmt, ...) printk(KERN_DEBUG "%s: " fmt, __func__, \
48c7a3d57dSJohan Hedberg 				 ##__VA_ARGS__)
49c7a3d57dSJohan Hedberg #else
50c7a3d57dSJohan Hedberg #define SMP_DBG(fmt, ...) no_printk(KERN_DEBUG "%s: " fmt, __func__, \
51c7a3d57dSJohan Hedberg 				    ##__VA_ARGS__)
52c7a3d57dSJohan Hedberg #endif
53c7a3d57dSJohan Hedberg 
54b28b4943SJohan Hedberg #define SMP_ALLOW_CMD(smp, code)	set_bit(code, &smp->allow_cmd)
55b28b4943SJohan Hedberg 
563b19146dSJohan Hedberg /* Keys which are not distributed with Secure Connections */
57c29fb5f6SMeng Yu #define SMP_SC_NO_DIST (SMP_DIST_ENC_KEY | SMP_DIST_LINK_KEY)
583b19146dSJohan Hedberg 
5917b02e62SMarcel Holtmann #define SMP_TIMEOUT	msecs_to_jiffies(30000)
605d3de7dfSVinicius Costa Gomes 
61b8b23001SLuiz Augusto von Dentz #define ID_ADDR_TIMEOUT	msecs_to_jiffies(200)
62b8b23001SLuiz Augusto von Dentz 
63d7a5a11dSMarcel Holtmann #define AUTH_REQ_MASK(dev)	(hci_dev_test_flag(dev, HCI_SC_ENABLED) ? \
64a62da6f1SJohan Hedberg 				 0x3f : 0x07)
6588d3a8acSJohan Hedberg #define KEY_DIST_MASK		0x07
66065a13e2SJohan Hedberg 
67cbbbe3e2SJohan Hedberg /* Maximum message length that can be passed to aes_cmac */
68cbbbe3e2SJohan Hedberg #define CMAC_MSG_MAX	80
69cbbbe3e2SJohan Hedberg 
70533e35d4SJohan Hedberg enum {
71533e35d4SJohan Hedberg 	SMP_FLAG_TK_VALID,
72533e35d4SJohan Hedberg 	SMP_FLAG_CFM_PENDING,
73533e35d4SJohan Hedberg 	SMP_FLAG_MITM_AUTH,
74533e35d4SJohan Hedberg 	SMP_FLAG_COMPLETE,
75533e35d4SJohan Hedberg 	SMP_FLAG_INITIATOR,
7665668776SJohan Hedberg 	SMP_FLAG_SC,
77d8f8edbeSJohan Hedberg 	SMP_FLAG_REMOTE_PK,
78aeb7d461SJohan Hedberg 	SMP_FLAG_DEBUG_KEY,
7938606f14SJohan Hedberg 	SMP_FLAG_WAIT_USER,
80d3e54a87SJohan Hedberg 	SMP_FLAG_DHKEY_PENDING,
811a8bab4fSJohan Hedberg 	SMP_FLAG_REMOTE_OOB,
821a8bab4fSJohan Hedberg 	SMP_FLAG_LOCAL_OOB,
83a62da6f1SJohan Hedberg 	SMP_FLAG_CT2,
84533e35d4SJohan Hedberg };
854bc58f51SJohan Hedberg 
8688a479d9SMarcel Holtmann struct smp_dev {
8760a27d65SMarcel Holtmann 	/* Secure Connections OOB data */
8894f14e47SJohan Hedberg 	bool			local_oob;
8960a27d65SMarcel Holtmann 	u8			local_pk[64];
90fb334feeSMarcel Holtmann 	u8			local_rand[16];
9160a27d65SMarcel Holtmann 	bool			debug_key;
9260a27d65SMarcel Holtmann 
9371af2f6bSHerbert Xu 	struct crypto_shash	*tfm_cmac;
9447eb2ac8STudor Ambarus 	struct crypto_kpp	*tfm_ecdh;
9588a479d9SMarcel Holtmann };
9688a479d9SMarcel Holtmann 
974bc58f51SJohan Hedberg struct smp_chan {
984bc58f51SJohan Hedberg 	struct l2cap_conn	*conn;
99b68fda68SJohan Hedberg 	struct delayed_work	security_timer;
100b28b4943SJohan Hedberg 	unsigned long           allow_cmd; /* Bitmask of allowed commands */
101b68fda68SJohan Hedberg 
1024bc58f51SJohan Hedberg 	u8		preq[7]; /* SMP Pairing Request */
1034bc58f51SJohan Hedberg 	u8		prsp[7]; /* SMP Pairing Response */
1044bc58f51SJohan Hedberg 	u8		prnd[16]; /* SMP Pairing Random (local) */
1054bc58f51SJohan Hedberg 	u8		rrnd[16]; /* SMP Pairing Random (remote) */
1064bc58f51SJohan Hedberg 	u8		pcnf[16]; /* SMP Pairing Confirm */
1074bc58f51SJohan Hedberg 	u8		tk[16]; /* SMP Temporary Key */
108882fafadSJohan Hedberg 	u8		rr[16]; /* Remote OOB ra/rb value */
109882fafadSJohan Hedberg 	u8		lr[16]; /* Local OOB ra/rb value */
1104bc58f51SJohan Hedberg 	u8		enc_key_size;
1114bc58f51SJohan Hedberg 	u8		remote_key_dist;
1124bc58f51SJohan Hedberg 	bdaddr_t	id_addr;
1134bc58f51SJohan Hedberg 	u8		id_addr_type;
1144bc58f51SJohan Hedberg 	u8		irk[16];
1154bc58f51SJohan Hedberg 	struct smp_csrk	*csrk;
116fad646e1SArchie Pusaka 	struct smp_csrk	*responder_csrk;
1174bc58f51SJohan Hedberg 	struct smp_ltk	*ltk;
118fad646e1SArchie Pusaka 	struct smp_ltk	*responder_ltk;
1194bc58f51SJohan Hedberg 	struct smp_irk	*remote_irk;
1206a77083aSJohan Hedberg 	u8		*link_key;
1214a74d658SJohan Hedberg 	unsigned long	flags;
122783e0574SJohan Hedberg 	u8		method;
12338606f14SJohan Hedberg 	u8		passkey_round;
1246a7bd103SJohan Hedberg 
1253b19146dSJohan Hedberg 	/* Secure Connections variables */
1263b19146dSJohan Hedberg 	u8			local_pk[64];
127d8f8edbeSJohan Hedberg 	u8			remote_pk[64];
128d8f8edbeSJohan Hedberg 	u8			dhkey[32];
129760b018bSJohan Hedberg 	u8			mackey[16];
1303b19146dSJohan Hedberg 
13171af2f6bSHerbert Xu 	struct crypto_shash	*tfm_cmac;
13247eb2ac8STudor Ambarus 	struct crypto_kpp	*tfm_ecdh;
1334bc58f51SJohan Hedberg };
1344bc58f51SJohan Hedberg 
135aeb7d461SJohan Hedberg /* These debug key values are defined in the SMP section of the core
136aeb7d461SJohan Hedberg  * specification. debug_pk is the public debug key and debug_sk the
137aeb7d461SJohan Hedberg  * private debug key.
138aeb7d461SJohan Hedberg  */
139aeb7d461SJohan Hedberg static const u8 debug_pk[64] = {
140aeb7d461SJohan Hedberg 		0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc,
141aeb7d461SJohan Hedberg 		0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef,
142aeb7d461SJohan Hedberg 		0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e,
143aeb7d461SJohan Hedberg 		0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20,
144aeb7d461SJohan Hedberg 
145aeb7d461SJohan Hedberg 		0x8b, 0xd2, 0x89, 0x15, 0xd0, 0x8e, 0x1c, 0x74,
146aeb7d461SJohan Hedberg 		0x24, 0x30, 0xed, 0x8f, 0xc2, 0x45, 0x63, 0x76,
147aeb7d461SJohan Hedberg 		0x5c, 0x15, 0x52, 0x5a, 0xbf, 0x9a, 0x32, 0x63,
148aeb7d461SJohan Hedberg 		0x6d, 0xeb, 0x2a, 0x65, 0x49, 0x9c, 0x80, 0xdc,
149aeb7d461SJohan Hedberg };
150aeb7d461SJohan Hedberg 
151aeb7d461SJohan Hedberg static const u8 debug_sk[32] = {
152aeb7d461SJohan Hedberg 		0xbd, 0x1a, 0x3c, 0xcd, 0xa6, 0xb8, 0x99, 0x58,
153aeb7d461SJohan Hedberg 		0x99, 0xb7, 0x40, 0xeb, 0x7b, 0x60, 0xff, 0x4a,
154aeb7d461SJohan Hedberg 		0x50, 0x3f, 0x10, 0xd2, 0xe3, 0xb3, 0xc9, 0x74,
155aeb7d461SJohan Hedberg 		0x38, 0x5f, 0xc5, 0xa3, 0xd4, 0xf6, 0x49, 0x3f,
156aeb7d461SJohan Hedberg };
157aeb7d461SJohan Hedberg 
swap_buf(const u8 * src,u8 * dst,size_t len)1588a2936f4SJohan Hedberg static inline void swap_buf(const u8 *src, u8 *dst, size_t len)
159d22ef0bcSAnderson Briglia {
1608a2936f4SJohan Hedberg 	size_t i;
161d22ef0bcSAnderson Briglia 
1628a2936f4SJohan Hedberg 	for (i = 0; i < len; i++)
1638a2936f4SJohan Hedberg 		dst[len - 1 - i] = src[i];
164d22ef0bcSAnderson Briglia }
165d22ef0bcSAnderson Briglia 
16606edf8deSJohan Hedberg /* The following functions map to the LE SC SMP crypto functions
16706edf8deSJohan Hedberg  * AES-CMAC, f4, f5, f6, g2 and h6.
16806edf8deSJohan Hedberg  */
16906edf8deSJohan Hedberg 
aes_cmac(struct crypto_shash * tfm,const u8 k[16],const u8 * m,size_t len,u8 mac[16])17071af2f6bSHerbert Xu static int aes_cmac(struct crypto_shash *tfm, const u8 k[16], const u8 *m,
171cbbbe3e2SJohan Hedberg 		    size_t len, u8 mac[16])
172cbbbe3e2SJohan Hedberg {
173cbbbe3e2SJohan Hedberg 	uint8_t tmp[16], mac_msb[16], msg_msb[CMAC_MSG_MAX];
174cbbbe3e2SJohan Hedberg 	int err;
175cbbbe3e2SJohan Hedberg 
176cbbbe3e2SJohan Hedberg 	if (len > CMAC_MSG_MAX)
177cbbbe3e2SJohan Hedberg 		return -EFBIG;
178cbbbe3e2SJohan Hedberg 
179cbbbe3e2SJohan Hedberg 	if (!tfm) {
180cbbbe3e2SJohan Hedberg 		BT_ERR("tfm %p", tfm);
181cbbbe3e2SJohan Hedberg 		return -EINVAL;
182cbbbe3e2SJohan Hedberg 	}
183cbbbe3e2SJohan Hedberg 
184cbbbe3e2SJohan Hedberg 	/* Swap key and message from LSB to MSB */
185cbbbe3e2SJohan Hedberg 	swap_buf(k, tmp, 16);
186cbbbe3e2SJohan Hedberg 	swap_buf(m, msg_msb, len);
187cbbbe3e2SJohan Hedberg 
188c7a3d57dSJohan Hedberg 	SMP_DBG("msg (len %zu) %*phN", len, (int) len, m);
189c7a3d57dSJohan Hedberg 	SMP_DBG("key %16phN", k);
190cbbbe3e2SJohan Hedberg 
19171af2f6bSHerbert Xu 	err = crypto_shash_setkey(tfm, tmp, 16);
192cbbbe3e2SJohan Hedberg 	if (err) {
193cbbbe3e2SJohan Hedberg 		BT_ERR("cipher setkey failed: %d", err);
194cbbbe3e2SJohan Hedberg 		return err;
195cbbbe3e2SJohan Hedberg 	}
196cbbbe3e2SJohan Hedberg 
197ec0bf6edSEric Biggers 	err = crypto_shash_tfm_digest(tfm, msg_msb, len, mac_msb);
198cbbbe3e2SJohan Hedberg 	if (err) {
19971af2f6bSHerbert Xu 		BT_ERR("Hash computation error %d", err);
200cbbbe3e2SJohan Hedberg 		return err;
201cbbbe3e2SJohan Hedberg 	}
202cbbbe3e2SJohan Hedberg 
203cbbbe3e2SJohan Hedberg 	swap_buf(mac_msb, mac, 16);
204cbbbe3e2SJohan Hedberg 
205c7a3d57dSJohan Hedberg 	SMP_DBG("mac %16phN", mac);
206cbbbe3e2SJohan Hedberg 
207cbbbe3e2SJohan Hedberg 	return 0;
208cbbbe3e2SJohan Hedberg }
209cbbbe3e2SJohan Hedberg 
smp_f4(struct crypto_shash * tfm_cmac,const u8 u[32],const u8 v[32],const u8 x[16],u8 z,u8 res[16])21071af2f6bSHerbert Xu static int smp_f4(struct crypto_shash *tfm_cmac, const u8 u[32],
21171af2f6bSHerbert Xu 		  const u8 v[32], const u8 x[16], u8 z, u8 res[16])
212cbbbe3e2SJohan Hedberg {
213cbbbe3e2SJohan Hedberg 	u8 m[65];
214cbbbe3e2SJohan Hedberg 	int err;
215cbbbe3e2SJohan Hedberg 
216c7a3d57dSJohan Hedberg 	SMP_DBG("u %32phN", u);
217c7a3d57dSJohan Hedberg 	SMP_DBG("v %32phN", v);
218c7a3d57dSJohan Hedberg 	SMP_DBG("x %16phN z %02x", x, z);
219cbbbe3e2SJohan Hedberg 
220cbbbe3e2SJohan Hedberg 	m[0] = z;
221cbbbe3e2SJohan Hedberg 	memcpy(m + 1, v, 32);
222cbbbe3e2SJohan Hedberg 	memcpy(m + 33, u, 32);
223cbbbe3e2SJohan Hedberg 
224cbbbe3e2SJohan Hedberg 	err = aes_cmac(tfm_cmac, x, m, sizeof(m), res);
225cbbbe3e2SJohan Hedberg 	if (err)
226cbbbe3e2SJohan Hedberg 		return err;
227cbbbe3e2SJohan Hedberg 
228c7a3d57dSJohan Hedberg 	SMP_DBG("res %16phN", res);
229cbbbe3e2SJohan Hedberg 
230cbbbe3e2SJohan Hedberg 	return err;
231cbbbe3e2SJohan Hedberg }
232cbbbe3e2SJohan Hedberg 
smp_f5(struct crypto_shash * tfm_cmac,const u8 w[32],const u8 n1[16],const u8 n2[16],const u8 a1[7],const u8 a2[7],u8 mackey[16],u8 ltk[16])23371af2f6bSHerbert Xu static int smp_f5(struct crypto_shash *tfm_cmac, const u8 w[32],
2344da50de8SJohan Hedberg 		  const u8 n1[16], const u8 n2[16], const u8 a1[7],
2354da50de8SJohan Hedberg 		  const u8 a2[7], u8 mackey[16], u8 ltk[16])
236760b018bSJohan Hedberg {
237760b018bSJohan Hedberg 	/* The btle, salt and length "magic" values are as defined in
238760b018bSJohan Hedberg 	 * the SMP section of the Bluetooth core specification. In ASCII
239760b018bSJohan Hedberg 	 * the btle value ends up being 'btle'. The salt is just a
240760b018bSJohan Hedberg 	 * random number whereas length is the value 256 in little
241760b018bSJohan Hedberg 	 * endian format.
242760b018bSJohan Hedberg 	 */
243760b018bSJohan Hedberg 	const u8 btle[4] = { 0x65, 0x6c, 0x74, 0x62 };
244760b018bSJohan Hedberg 	const u8 salt[16] = { 0xbe, 0x83, 0x60, 0x5a, 0xdb, 0x0b, 0x37, 0x60,
245760b018bSJohan Hedberg 			      0x38, 0xa5, 0xf5, 0xaa, 0x91, 0x83, 0x88, 0x6c };
246760b018bSJohan Hedberg 	const u8 length[2] = { 0x00, 0x01 };
247760b018bSJohan Hedberg 	u8 m[53], t[16];
248760b018bSJohan Hedberg 	int err;
249760b018bSJohan Hedberg 
250c7a3d57dSJohan Hedberg 	SMP_DBG("w %32phN", w);
251c7a3d57dSJohan Hedberg 	SMP_DBG("n1 %16phN n2 %16phN", n1, n2);
252c7a3d57dSJohan Hedberg 	SMP_DBG("a1 %7phN a2 %7phN", a1, a2);
253760b018bSJohan Hedberg 
254760b018bSJohan Hedberg 	err = aes_cmac(tfm_cmac, salt, w, 32, t);
255760b018bSJohan Hedberg 	if (err)
256760b018bSJohan Hedberg 		return err;
257760b018bSJohan Hedberg 
258c7a3d57dSJohan Hedberg 	SMP_DBG("t %16phN", t);
259760b018bSJohan Hedberg 
260760b018bSJohan Hedberg 	memcpy(m, length, 2);
261760b018bSJohan Hedberg 	memcpy(m + 2, a2, 7);
262760b018bSJohan Hedberg 	memcpy(m + 9, a1, 7);
263760b018bSJohan Hedberg 	memcpy(m + 16, n2, 16);
264760b018bSJohan Hedberg 	memcpy(m + 32, n1, 16);
265760b018bSJohan Hedberg 	memcpy(m + 48, btle, 4);
266760b018bSJohan Hedberg 
267760b018bSJohan Hedberg 	m[52] = 0; /* Counter */
268760b018bSJohan Hedberg 
269760b018bSJohan Hedberg 	err = aes_cmac(tfm_cmac, t, m, sizeof(m), mackey);
270760b018bSJohan Hedberg 	if (err)
271760b018bSJohan Hedberg 		return err;
272760b018bSJohan Hedberg 
273c7a3d57dSJohan Hedberg 	SMP_DBG("mackey %16phN", mackey);
274760b018bSJohan Hedberg 
275760b018bSJohan Hedberg 	m[52] = 1; /* Counter */
276760b018bSJohan Hedberg 
277760b018bSJohan Hedberg 	err = aes_cmac(tfm_cmac, t, m, sizeof(m), ltk);
278760b018bSJohan Hedberg 	if (err)
279760b018bSJohan Hedberg 		return err;
280760b018bSJohan Hedberg 
281c7a3d57dSJohan Hedberg 	SMP_DBG("ltk %16phN", ltk);
282760b018bSJohan Hedberg 
283760b018bSJohan Hedberg 	return 0;
284760b018bSJohan Hedberg }
285760b018bSJohan Hedberg 
smp_f6(struct crypto_shash * tfm_cmac,const u8 w[16],const u8 n1[16],const u8 n2[16],const u8 r[16],const u8 io_cap[3],const u8 a1[7],const u8 a2[7],u8 res[16])28671af2f6bSHerbert Xu static int smp_f6(struct crypto_shash *tfm_cmac, const u8 w[16],
2874da50de8SJohan Hedberg 		  const u8 n1[16], const u8 n2[16], const u8 r[16],
288760b018bSJohan Hedberg 		  const u8 io_cap[3], const u8 a1[7], const u8 a2[7],
289760b018bSJohan Hedberg 		  u8 res[16])
290760b018bSJohan Hedberg {
291760b018bSJohan Hedberg 	u8 m[65];
292760b018bSJohan Hedberg 	int err;
293760b018bSJohan Hedberg 
294c7a3d57dSJohan Hedberg 	SMP_DBG("w %16phN", w);
295c7a3d57dSJohan Hedberg 	SMP_DBG("n1 %16phN n2 %16phN", n1, n2);
296c7a3d57dSJohan Hedberg 	SMP_DBG("r %16phN io_cap %3phN a1 %7phN a2 %7phN", r, io_cap, a1, a2);
297760b018bSJohan Hedberg 
298760b018bSJohan Hedberg 	memcpy(m, a2, 7);
299760b018bSJohan Hedberg 	memcpy(m + 7, a1, 7);
300760b018bSJohan Hedberg 	memcpy(m + 14, io_cap, 3);
301760b018bSJohan Hedberg 	memcpy(m + 17, r, 16);
302760b018bSJohan Hedberg 	memcpy(m + 33, n2, 16);
303760b018bSJohan Hedberg 	memcpy(m + 49, n1, 16);
304760b018bSJohan Hedberg 
305760b018bSJohan Hedberg 	err = aes_cmac(tfm_cmac, w, m, sizeof(m), res);
306760b018bSJohan Hedberg 	if (err)
307760b018bSJohan Hedberg 		return err;
308760b018bSJohan Hedberg 
309203de21bSMarcel Holtmann 	SMP_DBG("res %16phN", res);
310760b018bSJohan Hedberg 
311760b018bSJohan Hedberg 	return err;
312760b018bSJohan Hedberg }
313760b018bSJohan Hedberg 
smp_g2(struct crypto_shash * tfm_cmac,const u8 u[32],const u8 v[32],const u8 x[16],const u8 y[16],u32 * val)31471af2f6bSHerbert Xu static int smp_g2(struct crypto_shash *tfm_cmac, const u8 u[32], const u8 v[32],
315191dc7feSJohan Hedberg 		  const u8 x[16], const u8 y[16], u32 *val)
316191dc7feSJohan Hedberg {
317191dc7feSJohan Hedberg 	u8 m[80], tmp[16];
318191dc7feSJohan Hedberg 	int err;
319191dc7feSJohan Hedberg 
320c7a3d57dSJohan Hedberg 	SMP_DBG("u %32phN", u);
321c7a3d57dSJohan Hedberg 	SMP_DBG("v %32phN", v);
322c7a3d57dSJohan Hedberg 	SMP_DBG("x %16phN y %16phN", x, y);
323191dc7feSJohan Hedberg 
324191dc7feSJohan Hedberg 	memcpy(m, y, 16);
325191dc7feSJohan Hedberg 	memcpy(m + 16, v, 32);
326191dc7feSJohan Hedberg 	memcpy(m + 48, u, 32);
327191dc7feSJohan Hedberg 
328191dc7feSJohan Hedberg 	err = aes_cmac(tfm_cmac, x, m, sizeof(m), tmp);
329191dc7feSJohan Hedberg 	if (err)
330191dc7feSJohan Hedberg 		return err;
331191dc7feSJohan Hedberg 
332191dc7feSJohan Hedberg 	*val = get_unaligned_le32(tmp);
333191dc7feSJohan Hedberg 	*val %= 1000000;
334191dc7feSJohan Hedberg 
335c7a3d57dSJohan Hedberg 	SMP_DBG("val %06u", *val);
336191dc7feSJohan Hedberg 
337191dc7feSJohan Hedberg 	return 0;
338191dc7feSJohan Hedberg }
339191dc7feSJohan Hedberg 
smp_h6(struct crypto_shash * tfm_cmac,const u8 w[16],const u8 key_id[4],u8 res[16])34071af2f6bSHerbert Xu static int smp_h6(struct crypto_shash *tfm_cmac, const u8 w[16],
34106edf8deSJohan Hedberg 		  const u8 key_id[4], u8 res[16])
34206edf8deSJohan Hedberg {
34306edf8deSJohan Hedberg 	int err;
34406edf8deSJohan Hedberg 
34506edf8deSJohan Hedberg 	SMP_DBG("w %16phN key_id %4phN", w, key_id);
34606edf8deSJohan Hedberg 
34706edf8deSJohan Hedberg 	err = aes_cmac(tfm_cmac, w, key_id, 4, res);
34806edf8deSJohan Hedberg 	if (err)
34906edf8deSJohan Hedberg 		return err;
35006edf8deSJohan Hedberg 
35106edf8deSJohan Hedberg 	SMP_DBG("res %16phN", res);
35206edf8deSJohan Hedberg 
35306edf8deSJohan Hedberg 	return err;
35406edf8deSJohan Hedberg }
35506edf8deSJohan Hedberg 
smp_h7(struct crypto_shash * tfm_cmac,const u8 w[16],const u8 salt[16],u8 res[16])356a62da6f1SJohan Hedberg static int smp_h7(struct crypto_shash *tfm_cmac, const u8 w[16],
357a62da6f1SJohan Hedberg 		  const u8 salt[16], u8 res[16])
358a62da6f1SJohan Hedberg {
359a62da6f1SJohan Hedberg 	int err;
360a62da6f1SJohan Hedberg 
361a62da6f1SJohan Hedberg 	SMP_DBG("w %16phN salt %16phN", w, salt);
362a62da6f1SJohan Hedberg 
363a62da6f1SJohan Hedberg 	err = aes_cmac(tfm_cmac, salt, w, 16, res);
364a62da6f1SJohan Hedberg 	if (err)
365a62da6f1SJohan Hedberg 		return err;
366a62da6f1SJohan Hedberg 
367a62da6f1SJohan Hedberg 	SMP_DBG("res %16phN", res);
368a62da6f1SJohan Hedberg 
369a62da6f1SJohan Hedberg 	return err;
370a62da6f1SJohan Hedberg }
371a62da6f1SJohan Hedberg 
37206edf8deSJohan Hedberg /* The following functions map to the legacy SMP crypto functions e, c1,
37306edf8deSJohan Hedberg  * s1 and ah.
37406edf8deSJohan Hedberg  */
37506edf8deSJohan Hedberg 
smp_e(const u8 * k,u8 * r)37628a220aaSArd Biesheuvel static int smp_e(const u8 *k, u8 *r)
377d22ef0bcSAnderson Briglia {
37828a220aaSArd Biesheuvel 	struct crypto_aes_ctx ctx;
379943a732aSJohan Hedberg 	uint8_t tmp[16], data[16];
380201a5929SJohan Hedberg 	int err;
381d22ef0bcSAnderson Briglia 
382011c391aSJohan Hedberg 	SMP_DBG("k %16phN r %16phN", k, r);
383011c391aSJohan Hedberg 
384943a732aSJohan Hedberg 	/* The most significant octet of key corresponds to k[0] */
3858a2936f4SJohan Hedberg 	swap_buf(k, tmp, 16);
386943a732aSJohan Hedberg 
38728a220aaSArd Biesheuvel 	err = aes_expandkey(&ctx, tmp, 16);
388d22ef0bcSAnderson Briglia 	if (err) {
389d22ef0bcSAnderson Briglia 		BT_ERR("cipher setkey failed: %d", err);
390d22ef0bcSAnderson Briglia 		return err;
391d22ef0bcSAnderson Briglia 	}
392d22ef0bcSAnderson Briglia 
393943a732aSJohan Hedberg 	/* Most significant octet of plaintextData corresponds to data[0] */
3948a2936f4SJohan Hedberg 	swap_buf(r, data, 16);
395943a732aSJohan Hedberg 
39628a220aaSArd Biesheuvel 	aes_encrypt(&ctx, data, data);
397d22ef0bcSAnderson Briglia 
398943a732aSJohan Hedberg 	/* Most significant octet of encryptedData corresponds to data[0] */
3998a2936f4SJohan Hedberg 	swap_buf(data, r, 16);
400943a732aSJohan Hedberg 
401011c391aSJohan Hedberg 	SMP_DBG("r %16phN", r);
402011c391aSJohan Hedberg 
40328a220aaSArd Biesheuvel 	memzero_explicit(&ctx, sizeof(ctx));
404d22ef0bcSAnderson Briglia 	return err;
405d22ef0bcSAnderson Briglia }
406d22ef0bcSAnderson Briglia 
smp_c1(const u8 k[16],const u8 r[16],const u8 preq[7],const u8 pres[7],u8 _iat,const bdaddr_t * ia,u8 _rat,const bdaddr_t * ra,u8 res[16])40728a220aaSArd Biesheuvel static int smp_c1(const u8 k[16],
40806edf8deSJohan Hedberg 		  const u8 r[16], const u8 preq[7], const u8 pres[7], u8 _iat,
40906edf8deSJohan Hedberg 		  const bdaddr_t *ia, u8 _rat, const bdaddr_t *ra, u8 res[16])
41006edf8deSJohan Hedberg {
41106edf8deSJohan Hedberg 	u8 p1[16], p2[16];
41206edf8deSJohan Hedberg 	int err;
41306edf8deSJohan Hedberg 
414011c391aSJohan Hedberg 	SMP_DBG("k %16phN r %16phN", k, r);
415011c391aSJohan Hedberg 	SMP_DBG("iat %u ia %6phN rat %u ra %6phN", _iat, ia, _rat, ra);
416011c391aSJohan Hedberg 	SMP_DBG("preq %7phN pres %7phN", preq, pres);
417011c391aSJohan Hedberg 
41806edf8deSJohan Hedberg 	memset(p1, 0, 16);
41906edf8deSJohan Hedberg 
42006edf8deSJohan Hedberg 	/* p1 = pres || preq || _rat || _iat */
42106edf8deSJohan Hedberg 	p1[0] = _iat;
42206edf8deSJohan Hedberg 	p1[1] = _rat;
42306edf8deSJohan Hedberg 	memcpy(p1 + 2, preq, 7);
42406edf8deSJohan Hedberg 	memcpy(p1 + 9, pres, 7);
42506edf8deSJohan Hedberg 
426011c391aSJohan Hedberg 	SMP_DBG("p1 %16phN", p1);
42706edf8deSJohan Hedberg 
42806edf8deSJohan Hedberg 	/* res = r XOR p1 */
429ef0bb5adSArd Biesheuvel 	crypto_xor_cpy(res, r, p1, sizeof(p1));
43006edf8deSJohan Hedberg 
43106edf8deSJohan Hedberg 	/* res = e(k, res) */
43228a220aaSArd Biesheuvel 	err = smp_e(k, res);
43306edf8deSJohan Hedberg 	if (err) {
43406edf8deSJohan Hedberg 		BT_ERR("Encrypt data error");
43506edf8deSJohan Hedberg 		return err;
43606edf8deSJohan Hedberg 	}
43706edf8deSJohan Hedberg 
438011c391aSJohan Hedberg 	/* p2 = padding || ia || ra */
439011c391aSJohan Hedberg 	memcpy(p2, ra, 6);
440011c391aSJohan Hedberg 	memcpy(p2 + 6, ia, 6);
441011c391aSJohan Hedberg 	memset(p2 + 12, 0, 4);
442011c391aSJohan Hedberg 
443011c391aSJohan Hedberg 	SMP_DBG("p2 %16phN", p2);
444011c391aSJohan Hedberg 
44506edf8deSJohan Hedberg 	/* res = res XOR p2 */
446ef0bb5adSArd Biesheuvel 	crypto_xor(res, p2, sizeof(p2));
44706edf8deSJohan Hedberg 
44806edf8deSJohan Hedberg 	/* res = e(k, res) */
44928a220aaSArd Biesheuvel 	err = smp_e(k, res);
45006edf8deSJohan Hedberg 	if (err)
45106edf8deSJohan Hedberg 		BT_ERR("Encrypt data error");
45206edf8deSJohan Hedberg 
45306edf8deSJohan Hedberg 	return err;
45406edf8deSJohan Hedberg }
45506edf8deSJohan Hedberg 
smp_s1(const u8 k[16],const u8 r1[16],const u8 r2[16],u8 _r[16])45628a220aaSArd Biesheuvel static int smp_s1(const u8 k[16],
45706edf8deSJohan Hedberg 		  const u8 r1[16], const u8 r2[16], u8 _r[16])
4586a77083aSJohan Hedberg {
4596a77083aSJohan Hedberg 	int err;
4606a77083aSJohan Hedberg 
46106edf8deSJohan Hedberg 	/* Just least significant octets from r1 and r2 are considered */
46206edf8deSJohan Hedberg 	memcpy(_r, r2, 8);
46306edf8deSJohan Hedberg 	memcpy(_r + 8, r1, 8);
4646a77083aSJohan Hedberg 
46528a220aaSArd Biesheuvel 	err = smp_e(k, _r);
4666a77083aSJohan Hedberg 	if (err)
46706edf8deSJohan Hedberg 		BT_ERR("Encrypt data error");
4686a77083aSJohan Hedberg 
4696a77083aSJohan Hedberg 	return err;
4706a77083aSJohan Hedberg }
4716a77083aSJohan Hedberg 
smp_ah(const u8 irk[16],const u8 r[3],u8 res[3])47228a220aaSArd Biesheuvel static int smp_ah(const u8 irk[16], const u8 r[3], u8 res[3])
47360478054SJohan Hedberg {
474943a732aSJohan Hedberg 	u8 _res[16];
47560478054SJohan Hedberg 	int err;
47660478054SJohan Hedberg 
47760478054SJohan Hedberg 	/* r' = padding || r */
478943a732aSJohan Hedberg 	memcpy(_res, r, 3);
479943a732aSJohan Hedberg 	memset(_res + 3, 0, 13);
48060478054SJohan Hedberg 
48128a220aaSArd Biesheuvel 	err = smp_e(irk, _res);
48260478054SJohan Hedberg 	if (err) {
48360478054SJohan Hedberg 		BT_ERR("Encrypt error");
48460478054SJohan Hedberg 		return err;
48560478054SJohan Hedberg 	}
48660478054SJohan Hedberg 
48760478054SJohan Hedberg 	/* The output of the random address function ah is:
488c5080d42SMarcel Holtmann 	 *	ah(k, r) = e(k, r') mod 2^24
48960478054SJohan Hedberg 	 * The output of the security function e is then truncated to 24 bits
49060478054SJohan Hedberg 	 * by taking the least significant 24 bits of the output of e as the
49160478054SJohan Hedberg 	 * result of ah.
49260478054SJohan Hedberg 	 */
493943a732aSJohan Hedberg 	memcpy(res, _res, 3);
49460478054SJohan Hedberg 
49560478054SJohan Hedberg 	return 0;
49660478054SJohan Hedberg }
49760478054SJohan Hedberg 
smp_irk_matches(struct hci_dev * hdev,const u8 irk[16],const bdaddr_t * bdaddr)498cd082797SJohan Hedberg bool smp_irk_matches(struct hci_dev *hdev, const u8 irk[16],
499cd082797SJohan Hedberg 		     const bdaddr_t *bdaddr)
50060478054SJohan Hedberg {
501defce9e8SJohan Hedberg 	struct l2cap_chan *chan = hdev->smp_data;
50260478054SJohan Hedberg 	u8 hash[3];
50360478054SJohan Hedberg 	int err;
50460478054SJohan Hedberg 
505defce9e8SJohan Hedberg 	if (!chan || !chan->data)
506defce9e8SJohan Hedberg 		return false;
507defce9e8SJohan Hedberg 
50856860245SMarcel Holtmann 	bt_dev_dbg(hdev, "RPA %pMR IRK %*phN", bdaddr, 16, irk);
50960478054SJohan Hedberg 
51028a220aaSArd Biesheuvel 	err = smp_ah(irk, &bdaddr->b[3], hash);
51160478054SJohan Hedberg 	if (err)
51260478054SJohan Hedberg 		return false;
51360478054SJohan Hedberg 
514329d8230SJason A. Donenfeld 	return !crypto_memneq(bdaddr->b, hash, 3);
51560478054SJohan Hedberg }
51660478054SJohan Hedberg 
smp_generate_rpa(struct hci_dev * hdev,const u8 irk[16],bdaddr_t * rpa)517cd082797SJohan Hedberg int smp_generate_rpa(struct hci_dev *hdev, const u8 irk[16], bdaddr_t *rpa)
518b1e2b3aeSJohan Hedberg {
519defce9e8SJohan Hedberg 	struct l2cap_chan *chan = hdev->smp_data;
520b1e2b3aeSJohan Hedberg 	int err;
521b1e2b3aeSJohan Hedberg 
522defce9e8SJohan Hedberg 	if (!chan || !chan->data)
523defce9e8SJohan Hedberg 		return -EOPNOTSUPP;
524defce9e8SJohan Hedberg 
525b1e2b3aeSJohan Hedberg 	get_random_bytes(&rpa->b[3], 3);
526b1e2b3aeSJohan Hedberg 
527b1e2b3aeSJohan Hedberg 	rpa->b[5] &= 0x3f;	/* Clear two most significant bits */
528b1e2b3aeSJohan Hedberg 	rpa->b[5] |= 0x40;	/* Set second most significant bit */
529b1e2b3aeSJohan Hedberg 
53028a220aaSArd Biesheuvel 	err = smp_ah(irk, &rpa->b[3], rpa->b);
531b1e2b3aeSJohan Hedberg 	if (err < 0)
532b1e2b3aeSJohan Hedberg 		return err;
533b1e2b3aeSJohan Hedberg 
53456860245SMarcel Holtmann 	bt_dev_dbg(hdev, "RPA %pMR", rpa);
535b1e2b3aeSJohan Hedberg 
536b1e2b3aeSJohan Hedberg 	return 0;
537b1e2b3aeSJohan Hedberg }
538b1e2b3aeSJohan Hedberg 
smp_generate_oob(struct hci_dev * hdev,u8 hash[16],u8 rand[16])53960a27d65SMarcel Holtmann int smp_generate_oob(struct hci_dev *hdev, u8 hash[16], u8 rand[16])
54060a27d65SMarcel Holtmann {
54160a27d65SMarcel Holtmann 	struct l2cap_chan *chan = hdev->smp_data;
54260a27d65SMarcel Holtmann 	struct smp_dev *smp;
54360a27d65SMarcel Holtmann 	int err;
54460a27d65SMarcel Holtmann 
54560a27d65SMarcel Holtmann 	if (!chan || !chan->data)
54660a27d65SMarcel Holtmann 		return -EOPNOTSUPP;
54760a27d65SMarcel Holtmann 
54860a27d65SMarcel Holtmann 	smp = chan->data;
54960a27d65SMarcel Holtmann 
55060a27d65SMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS)) {
55156860245SMarcel Holtmann 		bt_dev_dbg(hdev, "Using debug keys");
552c0153b0bSTudor Ambarus 		err = set_ecdh_privkey(smp->tfm_ecdh, debug_sk);
553c0153b0bSTudor Ambarus 		if (err)
554c0153b0bSTudor Ambarus 			return err;
55560a27d65SMarcel Holtmann 		memcpy(smp->local_pk, debug_pk, 64);
55660a27d65SMarcel Holtmann 		smp->debug_key = true;
55760a27d65SMarcel Holtmann 	} else {
55860a27d65SMarcel Holtmann 		while (true) {
559c0153b0bSTudor Ambarus 			/* Generate key pair for Secure Connections */
560c0153b0bSTudor Ambarus 			err = generate_ecdh_keys(smp->tfm_ecdh, smp->local_pk);
561a2976416STudor Ambarus 			if (err)
562a2976416STudor Ambarus 				return err;
56360a27d65SMarcel Holtmann 
56460a27d65SMarcel Holtmann 			/* This is unlikely, but we need to check that
56591641b79SZheng Yongjun 			 * we didn't accidentally generate a debug key.
56660a27d65SMarcel Holtmann 			 */
567c0153b0bSTudor Ambarus 			if (crypto_memneq(smp->local_pk, debug_pk, 64))
56860a27d65SMarcel Holtmann 				break;
56960a27d65SMarcel Holtmann 		}
57060a27d65SMarcel Holtmann 		smp->debug_key = false;
57160a27d65SMarcel Holtmann 	}
57260a27d65SMarcel Holtmann 
57360a27d65SMarcel Holtmann 	SMP_DBG("OOB Public Key X: %32phN", smp->local_pk);
57460a27d65SMarcel Holtmann 	SMP_DBG("OOB Public Key Y: %32phN", smp->local_pk + 32);
57560a27d65SMarcel Holtmann 
576fb334feeSMarcel Holtmann 	get_random_bytes(smp->local_rand, 16);
57760a27d65SMarcel Holtmann 
57860a27d65SMarcel Holtmann 	err = smp_f4(smp->tfm_cmac, smp->local_pk, smp->local_pk,
579fb334feeSMarcel Holtmann 		     smp->local_rand, 0, hash);
58060a27d65SMarcel Holtmann 	if (err < 0)
58160a27d65SMarcel Holtmann 		return err;
58260a27d65SMarcel Holtmann 
583fb334feeSMarcel Holtmann 	memcpy(rand, smp->local_rand, 16);
58460a27d65SMarcel Holtmann 
58594f14e47SJohan Hedberg 	smp->local_oob = true;
58694f14e47SJohan Hedberg 
58760a27d65SMarcel Holtmann 	return 0;
58860a27d65SMarcel Holtmann }
58960a27d65SMarcel Holtmann 
smp_send_cmd(struct l2cap_conn * conn,u8 code,u16 len,void * data)590eb492e01SAnderson Briglia static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
591eb492e01SAnderson Briglia {
5925d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
593b68fda68SJohan Hedberg 	struct smp_chan *smp;
5945d88cc73SJohan Hedberg 	struct kvec iv[2];
5955d88cc73SJohan Hedberg 	struct msghdr msg;
5965d88cc73SJohan Hedberg 
5975d88cc73SJohan Hedberg 	if (!chan)
5985d88cc73SJohan Hedberg 		return;
599eb492e01SAnderson Briglia 
6002e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(conn->hcon->hdev, "code 0x%2.2x", code);
601eb492e01SAnderson Briglia 
6025d88cc73SJohan Hedberg 	iv[0].iov_base = &code;
6035d88cc73SJohan Hedberg 	iv[0].iov_len = 1;
604eb492e01SAnderson Briglia 
6055d88cc73SJohan Hedberg 	iv[1].iov_base = data;
6065d88cc73SJohan Hedberg 	iv[1].iov_len = len;
6075d88cc73SJohan Hedberg 
6085d88cc73SJohan Hedberg 	memset(&msg, 0, sizeof(msg));
6095d88cc73SJohan Hedberg 
610de4eda9dSAl Viro 	iov_iter_kvec(&msg.msg_iter, ITER_SOURCE, iv, 2, 1 + len);
6115d88cc73SJohan Hedberg 
6125d88cc73SJohan Hedberg 	l2cap_chan_send(chan, &msg, 1 + len);
613e2dcd113SVinicius Costa Gomes 
614b68fda68SJohan Hedberg 	if (!chan->data)
615b68fda68SJohan Hedberg 		return;
616b68fda68SJohan Hedberg 
617b68fda68SJohan Hedberg 	smp = chan->data;
618b68fda68SJohan Hedberg 
619b68fda68SJohan Hedberg 	cancel_delayed_work_sync(&smp->security_timer);
620b68fda68SJohan Hedberg 	schedule_delayed_work(&smp->security_timer, SMP_TIMEOUT);
621eb492e01SAnderson Briglia }
622eb492e01SAnderson Briglia 
authreq_to_seclevel(u8 authreq)623d2eb9e10SJohan Hedberg static u8 authreq_to_seclevel(u8 authreq)
6242b64d153SBrian Gix {
625d2eb9e10SJohan Hedberg 	if (authreq & SMP_AUTH_MITM) {
626d2eb9e10SJohan Hedberg 		if (authreq & SMP_AUTH_SC)
627d2eb9e10SJohan Hedberg 			return BT_SECURITY_FIPS;
6282b64d153SBrian Gix 		else
629d2eb9e10SJohan Hedberg 			return BT_SECURITY_HIGH;
630d2eb9e10SJohan Hedberg 	} else {
6312b64d153SBrian Gix 		return BT_SECURITY_MEDIUM;
6322b64d153SBrian Gix 	}
633d2eb9e10SJohan Hedberg }
6342b64d153SBrian Gix 
seclevel_to_authreq(__u8 sec_level)6352b64d153SBrian Gix static __u8 seclevel_to_authreq(__u8 sec_level)
6362b64d153SBrian Gix {
6372b64d153SBrian Gix 	switch (sec_level) {
638d2eb9e10SJohan Hedberg 	case BT_SECURITY_FIPS:
6392b64d153SBrian Gix 	case BT_SECURITY_HIGH:
6402b64d153SBrian Gix 		return SMP_AUTH_MITM | SMP_AUTH_BONDING;
6412b64d153SBrian Gix 	case BT_SECURITY_MEDIUM:
6422b64d153SBrian Gix 		return SMP_AUTH_BONDING;
6432b64d153SBrian Gix 	default:
6442b64d153SBrian Gix 		return SMP_AUTH_NONE;
6452b64d153SBrian Gix 	}
6462b64d153SBrian Gix }
6472b64d153SBrian Gix 
build_pairing_cmd(struct l2cap_conn * conn,struct smp_cmd_pairing * req,struct smp_cmd_pairing * rsp,__u8 authreq)648b8e66eacSVinicius Costa Gomes static void build_pairing_cmd(struct l2cap_conn *conn,
64954790f73SVinicius Costa Gomes 			      struct smp_cmd_pairing *req,
650f1560463SMarcel Holtmann 			      struct smp_cmd_pairing *rsp, __u8 authreq)
651b8e66eacSVinicius Costa Gomes {
6525d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
6535d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
654fd349c02SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
655fd349c02SJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
65602b05bd8SJohan Hedberg 	u8 local_dist = 0, remote_dist = 0, oob_flag = SMP_OOB_NOT_PRESENT;
65754790f73SVinicius Costa Gomes 
658d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_BONDABLE)) {
6597ee4ea36SMarcel Holtmann 		local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
6607ee4ea36SMarcel Holtmann 		remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
66154790f73SVinicius Costa Gomes 		authreq |= SMP_AUTH_BONDING;
6622b64d153SBrian Gix 	} else {
6632b64d153SBrian Gix 		authreq &= ~SMP_AUTH_BONDING;
66454790f73SVinicius Costa Gomes 	}
66554790f73SVinicius Costa Gomes 
666d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_RPA_RESOLVING))
667fd349c02SJohan Hedberg 		remote_dist |= SMP_DIST_ID_KEY;
668fd349c02SJohan Hedberg 
669d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_PRIVACY))
670863efaf2SJohan Hedberg 		local_dist |= SMP_DIST_ID_KEY;
671863efaf2SJohan Hedberg 
672d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SC_ENABLED) &&
67302b05bd8SJohan Hedberg 	    (authreq & SMP_AUTH_SC)) {
67402b05bd8SJohan Hedberg 		struct oob_data *oob_data;
67502b05bd8SJohan Hedberg 		u8 bdaddr_type;
67602b05bd8SJohan Hedberg 
677d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_SSP_ENABLED)) {
678df8e1a4cSJohan Hedberg 			local_dist |= SMP_DIST_LINK_KEY;
679df8e1a4cSJohan Hedberg 			remote_dist |= SMP_DIST_LINK_KEY;
680df8e1a4cSJohan Hedberg 		}
68102b05bd8SJohan Hedberg 
68202b05bd8SJohan Hedberg 		if (hcon->dst_type == ADDR_LE_DEV_PUBLIC)
68302b05bd8SJohan Hedberg 			bdaddr_type = BDADDR_LE_PUBLIC;
68402b05bd8SJohan Hedberg 		else
68502b05bd8SJohan Hedberg 			bdaddr_type = BDADDR_LE_RANDOM;
68602b05bd8SJohan Hedberg 
68702b05bd8SJohan Hedberg 		oob_data = hci_find_remote_oob_data(hdev, &hcon->dst,
68802b05bd8SJohan Hedberg 						    bdaddr_type);
6894775a4eaSMarcel Holtmann 		if (oob_data && oob_data->present) {
6901a8bab4fSJohan Hedberg 			set_bit(SMP_FLAG_REMOTE_OOB, &smp->flags);
69102b05bd8SJohan Hedberg 			oob_flag = SMP_OOB_PRESENT;
692a29b0733SJohan Hedberg 			memcpy(smp->rr, oob_data->rand256, 16);
69302b05bd8SJohan Hedberg 			memcpy(smp->pcnf, oob_data->hash256, 16);
694bc07cd69SMarcel Holtmann 			SMP_DBG("OOB Remote Confirmation: %16phN", smp->pcnf);
695bc07cd69SMarcel Holtmann 			SMP_DBG("OOB Remote Random: %16phN", smp->rr);
69602b05bd8SJohan Hedberg 		}
69702b05bd8SJohan Hedberg 
698df8e1a4cSJohan Hedberg 	} else {
699df8e1a4cSJohan Hedberg 		authreq &= ~SMP_AUTH_SC;
700df8e1a4cSJohan Hedberg 	}
701df8e1a4cSJohan Hedberg 
70254790f73SVinicius Costa Gomes 	if (rsp == NULL) {
70354790f73SVinicius Costa Gomes 		req->io_capability = conn->hcon->io_capability;
70402b05bd8SJohan Hedberg 		req->oob_flag = oob_flag;
70530d65e08SMatias Karhumaa 		req->max_key_size = hdev->le_max_key_size;
706fd349c02SJohan Hedberg 		req->init_key_dist = local_dist;
707fd349c02SJohan Hedberg 		req->resp_key_dist = remote_dist;
7080edb14deSJohan Hedberg 		req->auth_req = (authreq & AUTH_REQ_MASK(hdev));
709fd349c02SJohan Hedberg 
710fd349c02SJohan Hedberg 		smp->remote_key_dist = remote_dist;
71154790f73SVinicius Costa Gomes 		return;
71254790f73SVinicius Costa Gomes 	}
71354790f73SVinicius Costa Gomes 
71454790f73SVinicius Costa Gomes 	rsp->io_capability = conn->hcon->io_capability;
71502b05bd8SJohan Hedberg 	rsp->oob_flag = oob_flag;
71630d65e08SMatias Karhumaa 	rsp->max_key_size = hdev->le_max_key_size;
717fd349c02SJohan Hedberg 	rsp->init_key_dist = req->init_key_dist & remote_dist;
718fd349c02SJohan Hedberg 	rsp->resp_key_dist = req->resp_key_dist & local_dist;
7190edb14deSJohan Hedberg 	rsp->auth_req = (authreq & AUTH_REQ_MASK(hdev));
720fd349c02SJohan Hedberg 
721fd349c02SJohan Hedberg 	smp->remote_key_dist = rsp->init_key_dist;
722b8e66eacSVinicius Costa Gomes }
723b8e66eacSVinicius Costa Gomes 
check_enc_key_size(struct l2cap_conn * conn,__u8 max_key_size)7243158c50cSVinicius Costa Gomes static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
7253158c50cSVinicius Costa Gomes {
7265d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
7272fd36558SJohan Hedberg 	struct hci_dev *hdev = conn->hcon->hdev;
7285d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
7291c1def09SVinicius Costa Gomes 
73049c06c9eSŁukasz Rymanowski 	if (conn->hcon->pending_sec_level == BT_SECURITY_FIPS &&
73149c06c9eSŁukasz Rymanowski 	    max_key_size != SMP_MAX_ENC_KEY_SIZE)
73249c06c9eSŁukasz Rymanowski 		return SMP_ENC_KEY_SIZE;
73349c06c9eSŁukasz Rymanowski 
73430d65e08SMatias Karhumaa 	if (max_key_size > hdev->le_max_key_size ||
7352fd36558SJohan Hedberg 	    max_key_size < SMP_MIN_ENC_KEY_SIZE)
7363158c50cSVinicius Costa Gomes 		return SMP_ENC_KEY_SIZE;
7373158c50cSVinicius Costa Gomes 
738f7aa611aSVinicius Costa Gomes 	smp->enc_key_size = max_key_size;
7393158c50cSVinicius Costa Gomes 
7403158c50cSVinicius Costa Gomes 	return 0;
7413158c50cSVinicius Costa Gomes }
7423158c50cSVinicius Costa Gomes 
smp_chan_destroy(struct l2cap_conn * conn)7436f48e260SJohan Hedberg static void smp_chan_destroy(struct l2cap_conn *conn)
7446f48e260SJohan Hedberg {
7456f48e260SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
7466f48e260SJohan Hedberg 	struct smp_chan *smp = chan->data;
747923e2414SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
7486f48e260SJohan Hedberg 	bool complete;
7496f48e260SJohan Hedberg 
7506f48e260SJohan Hedberg 	BUG_ON(!smp);
7516f48e260SJohan Hedberg 
7526f48e260SJohan Hedberg 	cancel_delayed_work_sync(&smp->security_timer);
7536f48e260SJohan Hedberg 
7546f48e260SJohan Hedberg 	complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags);
755923e2414SJohan Hedberg 	mgmt_smp_complete(hcon, complete);
7566f48e260SJohan Hedberg 
757453431a5SWaiman Long 	kfree_sensitive(smp->csrk);
758fad646e1SArchie Pusaka 	kfree_sensitive(smp->responder_csrk);
759453431a5SWaiman Long 	kfree_sensitive(smp->link_key);
7606f48e260SJohan Hedberg 
76171af2f6bSHerbert Xu 	crypto_free_shash(smp->tfm_cmac);
76247eb2ac8STudor Ambarus 	crypto_free_kpp(smp->tfm_ecdh);
7636f48e260SJohan Hedberg 
764923e2414SJohan Hedberg 	/* Ensure that we don't leave any debug key around if debug key
765923e2414SJohan Hedberg 	 * support hasn't been explicitly enabled.
766923e2414SJohan Hedberg 	 */
767923e2414SJohan Hedberg 	if (smp->ltk && smp->ltk->type == SMP_LTK_P256_DEBUG &&
768d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hcon->hdev, HCI_KEEP_DEBUG_KEYS)) {
769923e2414SJohan Hedberg 		list_del_rcu(&smp->ltk->list);
770923e2414SJohan Hedberg 		kfree_rcu(smp->ltk, rcu);
771923e2414SJohan Hedberg 		smp->ltk = NULL;
772923e2414SJohan Hedberg 	}
773923e2414SJohan Hedberg 
7746f48e260SJohan Hedberg 	/* If pairing failed clean up any keys we might have */
7756f48e260SJohan Hedberg 	if (!complete) {
7766f48e260SJohan Hedberg 		if (smp->ltk) {
777970d0f1bSJohan Hedberg 			list_del_rcu(&smp->ltk->list);
778970d0f1bSJohan Hedberg 			kfree_rcu(smp->ltk, rcu);
7796f48e260SJohan Hedberg 		}
7806f48e260SJohan Hedberg 
781fad646e1SArchie Pusaka 		if (smp->responder_ltk) {
782fad646e1SArchie Pusaka 			list_del_rcu(&smp->responder_ltk->list);
783fad646e1SArchie Pusaka 			kfree_rcu(smp->responder_ltk, rcu);
7846f48e260SJohan Hedberg 		}
7856f48e260SJohan Hedberg 
7866f48e260SJohan Hedberg 		if (smp->remote_irk) {
787adae20cbSJohan Hedberg 			list_del_rcu(&smp->remote_irk->list);
788adae20cbSJohan Hedberg 			kfree_rcu(smp->remote_irk, rcu);
7896f48e260SJohan Hedberg 		}
7906f48e260SJohan Hedberg 	}
7916f48e260SJohan Hedberg 
7926f48e260SJohan Hedberg 	chan->data = NULL;
793453431a5SWaiman Long 	kfree_sensitive(smp);
794923e2414SJohan Hedberg 	hci_conn_drop(hcon);
7956f48e260SJohan Hedberg }
7966f48e260SJohan Hedberg 
smp_failure(struct l2cap_conn * conn,u8 reason)79784794e11SJohan Hedberg static void smp_failure(struct l2cap_conn *conn, u8 reason)
7984f957a76SBrian Gix {
799bab73cb6SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
800b68fda68SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
801bab73cb6SJohan Hedberg 
80284794e11SJohan Hedberg 	if (reason)
8034f957a76SBrian Gix 		smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
8044f957a76SBrian Gix 			     &reason);
8054f957a76SBrian Gix 
806e1e930f5SJohan Hedberg 	mgmt_auth_failed(hcon, HCI_ERROR_AUTH_FAILURE);
807f1c09c07SVinicius Costa Gomes 
808fc75cc86SJohan Hedberg 	if (chan->data)
8094f957a76SBrian Gix 		smp_chan_destroy(conn);
8104f957a76SBrian Gix }
8114f957a76SBrian Gix 
8122b64d153SBrian Gix #define JUST_WORKS	0x00
8132b64d153SBrian Gix #define JUST_CFM	0x01
8142b64d153SBrian Gix #define REQ_PASSKEY	0x02
8152b64d153SBrian Gix #define CFM_PASSKEY	0x03
8162b64d153SBrian Gix #define REQ_OOB		0x04
8175e3d3d9bSJohan Hedberg #define DSP_PASSKEY	0x05
8182b64d153SBrian Gix #define OVERLAP		0xFF
8192b64d153SBrian Gix 
8202b64d153SBrian Gix static const u8 gen_method[5][5] = {
8212b64d153SBrian Gix 	{ JUST_WORKS,  JUST_CFM,    REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
8222b64d153SBrian Gix 	{ JUST_WORKS,  JUST_CFM,    REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
8232b64d153SBrian Gix 	{ CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
8242b64d153SBrian Gix 	{ JUST_WORKS,  JUST_CFM,    JUST_WORKS,  JUST_WORKS, JUST_CFM    },
8252b64d153SBrian Gix 	{ CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, OVERLAP     },
8262b64d153SBrian Gix };
8272b64d153SBrian Gix 
8285e3d3d9bSJohan Hedberg static const u8 sc_method[5][5] = {
8295e3d3d9bSJohan Hedberg 	{ JUST_WORKS,  JUST_CFM,    REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
8305e3d3d9bSJohan Hedberg 	{ JUST_WORKS,  CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
8315e3d3d9bSJohan Hedberg 	{ DSP_PASSKEY, DSP_PASSKEY, REQ_PASSKEY, JUST_WORKS, DSP_PASSKEY },
8325e3d3d9bSJohan Hedberg 	{ JUST_WORKS,  JUST_CFM,    JUST_WORKS,  JUST_WORKS, JUST_CFM    },
8335e3d3d9bSJohan Hedberg 	{ DSP_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
8345e3d3d9bSJohan Hedberg };
8355e3d3d9bSJohan Hedberg 
get_auth_method(struct smp_chan * smp,u8 local_io,u8 remote_io)836581370ccSJohan Hedberg static u8 get_auth_method(struct smp_chan *smp, u8 local_io, u8 remote_io)
837581370ccSJohan Hedberg {
8382bcd4003SJohan Hedberg 	/* If either side has unknown io_caps, use JUST_CFM (which gets
8392bcd4003SJohan Hedberg 	 * converted later to JUST_WORKS if we're initiators.
8402bcd4003SJohan Hedberg 	 */
841581370ccSJohan Hedberg 	if (local_io > SMP_IO_KEYBOARD_DISPLAY ||
842581370ccSJohan Hedberg 	    remote_io > SMP_IO_KEYBOARD_DISPLAY)
8432bcd4003SJohan Hedberg 		return JUST_CFM;
844581370ccSJohan Hedberg 
8455e3d3d9bSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags))
8465e3d3d9bSJohan Hedberg 		return sc_method[remote_io][local_io];
8475e3d3d9bSJohan Hedberg 
848581370ccSJohan Hedberg 	return gen_method[remote_io][local_io];
849581370ccSJohan Hedberg }
850581370ccSJohan Hedberg 
tk_request(struct l2cap_conn * conn,u8 remote_oob,u8 auth,u8 local_io,u8 remote_io)8512b64d153SBrian Gix static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
8522b64d153SBrian Gix 						u8 local_io, u8 remote_io)
8532b64d153SBrian Gix {
8542b64d153SBrian Gix 	struct hci_conn *hcon = conn->hcon;
8555d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
8565d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
8572b64d153SBrian Gix 	u32 passkey = 0;
858d1d900f8SGuenter Roeck 	int ret;
8592b64d153SBrian Gix 
8602b64d153SBrian Gix 	/* Initialize key for JUST WORKS */
8612b64d153SBrian Gix 	memset(smp->tk, 0, sizeof(smp->tk));
8624a74d658SJohan Hedberg 	clear_bit(SMP_FLAG_TK_VALID, &smp->flags);
8632b64d153SBrian Gix 
86483b4b195SKai Ye 	bt_dev_dbg(hcon->hdev, "auth:%u lcl:%u rem:%u", auth, local_io,
8652e1614f7SLuiz Augusto von Dentz 		   remote_io);
8662b64d153SBrian Gix 
8672bcd4003SJohan Hedberg 	/* If neither side wants MITM, either "just" confirm an incoming
8682bcd4003SJohan Hedberg 	 * request or use just-works for outgoing ones. The JUST_CFM
8692bcd4003SJohan Hedberg 	 * will be converted to JUST_WORKS if necessary later in this
8702bcd4003SJohan Hedberg 	 * function. If either side has MITM look up the method from the
8712bcd4003SJohan Hedberg 	 * table.
8722bcd4003SJohan Hedberg 	 */
873581370ccSJohan Hedberg 	if (!(auth & SMP_AUTH_MITM))
874783e0574SJohan Hedberg 		smp->method = JUST_CFM;
8752b64d153SBrian Gix 	else
876783e0574SJohan Hedberg 		smp->method = get_auth_method(smp, local_io, remote_io);
8772b64d153SBrian Gix 
878a82505c7SJohan Hedberg 	/* Don't confirm locally initiated pairing attempts */
879783e0574SJohan Hedberg 	if (smp->method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR,
880783e0574SJohan Hedberg 						&smp->flags))
881783e0574SJohan Hedberg 		smp->method = JUST_WORKS;
882a82505c7SJohan Hedberg 
88302f3e254SJohan Hedberg 	/* Don't bother user space with no IO capabilities */
884783e0574SJohan Hedberg 	if (smp->method == JUST_CFM &&
885783e0574SJohan Hedberg 	    hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
886783e0574SJohan Hedberg 		smp->method = JUST_WORKS;
88702f3e254SJohan Hedberg 
88892516cd9SSonny Sasaka 	/* If Just Works, Continue with Zero TK and ask user-space for
88992516cd9SSonny Sasaka 	 * confirmation */
890783e0574SJohan Hedberg 	if (smp->method == JUST_WORKS) {
891d1d900f8SGuenter Roeck 		ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
89292516cd9SSonny Sasaka 						hcon->type,
89392516cd9SSonny Sasaka 						hcon->dst_type,
89492516cd9SSonny Sasaka 						passkey, 1);
895d1d900f8SGuenter Roeck 		if (ret)
896d1d900f8SGuenter Roeck 			return ret;
89792516cd9SSonny Sasaka 		set_bit(SMP_FLAG_WAIT_USER, &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 
91474be523cSArchie Pusaka 	/* If both devices have Keyboard-Display I/O, the initiator
91574be523cSArchie Pusaka 	 * Confirms and the responder 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);
93083b4b195SKai Ye 		bt_dev_dbg(hcon->hdev, "PassKey: %u", 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 
smp_confirm(struct smp_chan * smp)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 
9552e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(conn->hcon->hdev, "conn %p", conn);
9568aab4757SVinicius Costa Gomes 
95728a220aaSArd Biesheuvel 	ret = smp_c1(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 
smp_random(struct smp_chan * smp)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 
9832e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(conn->hcon->hdev, "conn %p %s", conn,
984fad646e1SArchie Pusaka 		   conn->hcon->out ? "initiator" : "responder");
9858aab4757SVinicius Costa Gomes 
98628a220aaSArd Biesheuvel 	ret = smp_c1(smp->tk, smp->rrnd, smp->preq, smp->prsp,
987b1cd5fd9SJohan Hedberg 		     hcon->init_addr_type, &hcon->init_addr,
988943a732aSJohan Hedberg 		     hcon->resp_addr_type, &hcon->resp_addr, confirm);
989861580a9SJohan Hedberg 	if (ret)
990861580a9SJohan Hedberg 		return SMP_UNSPECIFIED;
9918aab4757SVinicius Costa Gomes 
992329d8230SJason A. Donenfeld 	if (crypto_memneq(smp->pcnf, confirm, sizeof(smp->pcnf))) {
9932064ee33SMarcel Holtmann 		bt_dev_err(hcon->hdev, "pairing failed "
9942064ee33SMarcel Holtmann 			   "(confirmation values mismatch)");
995861580a9SJohan Hedberg 		return SMP_CONFIRM_FAILED;
9968aab4757SVinicius Costa Gomes 	}
9978aab4757SVinicius Costa Gomes 
9988aab4757SVinicius Costa Gomes 	if (hcon->out) {
999fe39c7b2SMarcel Holtmann 		u8 stk[16];
1000fe39c7b2SMarcel Holtmann 		__le64 rand = 0;
1001fe39c7b2SMarcel Holtmann 		__le16 ediv = 0;
10028aab4757SVinicius Costa Gomes 
100328a220aaSArd Biesheuvel 		smp_s1(smp->tk, smp->rrnd, smp->prnd, stk);
10048aab4757SVinicius Costa Gomes 
1005861580a9SJohan Hedberg 		if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
1006861580a9SJohan Hedberg 			return SMP_UNSPECIFIED;
10078aab4757SVinicius Costa Gomes 
10088b76ce34SJohan Hedberg 		hci_le_start_enc(hcon, ediv, rand, stk, smp->enc_key_size);
1009f7aa611aSVinicius Costa Gomes 		hcon->enc_key_size = smp->enc_key_size;
1010fe59a05fSJohan Hedberg 		set_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags);
10118aab4757SVinicius Costa Gomes 	} else {
1012fff3490fSJohan Hedberg 		u8 stk[16], auth;
1013fe39c7b2SMarcel Holtmann 		__le64 rand = 0;
1014fe39c7b2SMarcel Holtmann 		__le16 ediv = 0;
10158aab4757SVinicius Costa Gomes 
1016943a732aSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
1017943a732aSJohan Hedberg 			     smp->prnd);
10188aab4757SVinicius Costa Gomes 
101928a220aaSArd Biesheuvel 		smp_s1(smp->tk, smp->prnd, smp->rrnd, stk);
10208aab4757SVinicius Costa Gomes 
1021fff3490fSJohan Hedberg 		if (hcon->pending_sec_level == BT_SECURITY_HIGH)
1022fff3490fSJohan Hedberg 			auth = 1;
1023fff3490fSJohan Hedberg 		else
1024fff3490fSJohan Hedberg 			auth = 0;
1025fff3490fSJohan Hedberg 
1026fad646e1SArchie Pusaka 		/* Even though there's no _RESPONDER suffix this is the
1027fad646e1SArchie Pusaka 		 * responder STK we're adding for later lookup (the initiator
10287d5843b7SJohan Hedberg 		 * STK never needs to be stored).
10297d5843b7SJohan Hedberg 		 */
1030ce39fb4eSMarcel Holtmann 		hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
10312ceba539SJohan Hedberg 			    SMP_STK, auth, stk, smp->enc_key_size, ediv, rand);
10328aab4757SVinicius Costa Gomes 	}
10338aab4757SVinicius Costa Gomes 
1034861580a9SJohan Hedberg 	return 0;
10358aab4757SVinicius Costa Gomes }
10368aab4757SVinicius Costa Gomes 
smp_notify_keys(struct l2cap_conn * conn)103744f1a7abSJohan Hedberg static void smp_notify_keys(struct l2cap_conn *conn)
103844f1a7abSJohan Hedberg {
103944f1a7abSJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
104044f1a7abSJohan Hedberg 	struct smp_chan *smp = chan->data;
104144f1a7abSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
104244f1a7abSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
104344f1a7abSJohan Hedberg 	struct smp_cmd_pairing *req = (void *) &smp->preq[1];
104444f1a7abSJohan Hedberg 	struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1];
104544f1a7abSJohan Hedberg 	bool persistent;
104644f1a7abSJohan Hedberg 
1047cad20c27SJohan Hedberg 	if (hcon->type == ACL_LINK) {
1048cad20c27SJohan Hedberg 		if (hcon->key_type == HCI_LK_DEBUG_COMBINATION)
1049cad20c27SJohan Hedberg 			persistent = false;
1050cad20c27SJohan Hedberg 		else
1051cad20c27SJohan Hedberg 			persistent = !test_bit(HCI_CONN_FLUSH_KEY,
1052cad20c27SJohan Hedberg 					       &hcon->flags);
1053cad20c27SJohan Hedberg 	} else {
1054cad20c27SJohan Hedberg 		/* The LTKs, IRKs and CSRKs should be persistent only if
1055cad20c27SJohan Hedberg 		 * both sides had the bonding bit set in their
1056cad20c27SJohan Hedberg 		 * authentication requests.
1057cad20c27SJohan Hedberg 		 */
1058cad20c27SJohan Hedberg 		persistent = !!((req->auth_req & rsp->auth_req) &
1059cad20c27SJohan Hedberg 				SMP_AUTH_BONDING);
1060cad20c27SJohan Hedberg 	}
1061cad20c27SJohan Hedberg 
106244f1a7abSJohan Hedberg 	if (smp->remote_irk) {
1063*865f1f43SXiao Yao 		smp->remote_irk->link_type = hcon->type;
1064cad20c27SJohan Hedberg 		mgmt_new_irk(hdev, smp->remote_irk, persistent);
1065cad20c27SJohan Hedberg 
106644f1a7abSJohan Hedberg 		/* Now that user space can be considered to know the
106744f1a7abSJohan Hedberg 		 * identity address track the connection based on it
1068b5ae344dSJohan Hedberg 		 * from now on (assuming this is an LE link).
106944f1a7abSJohan Hedberg 		 */
1070b5ae344dSJohan Hedberg 		if (hcon->type == LE_LINK) {
107144f1a7abSJohan Hedberg 			bacpy(&hcon->dst, &smp->remote_irk->bdaddr);
107244f1a7abSJohan Hedberg 			hcon->dst_type = smp->remote_irk->addr_type;
1073b8b23001SLuiz Augusto von Dentz 			/* Use a short delay to make sure the new address is
1074b8b23001SLuiz Augusto von Dentz 			 * propagated _before_ the channels.
1075b8b23001SLuiz Augusto von Dentz 			 */
1076b8b23001SLuiz Augusto von Dentz 			queue_delayed_work(hdev->workqueue,
1077b8b23001SLuiz Augusto von Dentz 					   &conn->id_addr_timer,
1078b8b23001SLuiz Augusto von Dentz 					   ID_ADDR_TIMEOUT);
1079b5ae344dSJohan Hedberg 		}
108044f1a7abSJohan Hedberg 	}
108144f1a7abSJohan Hedberg 
108244f1a7abSJohan Hedberg 	if (smp->csrk) {
1083*865f1f43SXiao Yao 		smp->csrk->link_type = hcon->type;
108444f1a7abSJohan Hedberg 		smp->csrk->bdaddr_type = hcon->dst_type;
108544f1a7abSJohan Hedberg 		bacpy(&smp->csrk->bdaddr, &hcon->dst);
108644f1a7abSJohan Hedberg 		mgmt_new_csrk(hdev, smp->csrk, persistent);
108744f1a7abSJohan Hedberg 	}
108844f1a7abSJohan Hedberg 
1089fad646e1SArchie Pusaka 	if (smp->responder_csrk) {
1090*865f1f43SXiao Yao 		smp->responder_csrk->link_type = hcon->type;
1091fad646e1SArchie Pusaka 		smp->responder_csrk->bdaddr_type = hcon->dst_type;
1092fad646e1SArchie Pusaka 		bacpy(&smp->responder_csrk->bdaddr, &hcon->dst);
1093fad646e1SArchie Pusaka 		mgmt_new_csrk(hdev, smp->responder_csrk, persistent);
109444f1a7abSJohan Hedberg 	}
109544f1a7abSJohan Hedberg 
109644f1a7abSJohan Hedberg 	if (smp->ltk) {
1097*865f1f43SXiao Yao 		smp->ltk->link_type = hcon->type;
109844f1a7abSJohan Hedberg 		smp->ltk->bdaddr_type = hcon->dst_type;
109944f1a7abSJohan Hedberg 		bacpy(&smp->ltk->bdaddr, &hcon->dst);
110044f1a7abSJohan Hedberg 		mgmt_new_ltk(hdev, smp->ltk, persistent);
110144f1a7abSJohan Hedberg 	}
110244f1a7abSJohan Hedberg 
1103fad646e1SArchie Pusaka 	if (smp->responder_ltk) {
1104*865f1f43SXiao Yao 		smp->responder_ltk->link_type = hcon->type;
1105fad646e1SArchie Pusaka 		smp->responder_ltk->bdaddr_type = hcon->dst_type;
1106fad646e1SArchie Pusaka 		bacpy(&smp->responder_ltk->bdaddr, &hcon->dst);
1107fad646e1SArchie Pusaka 		mgmt_new_ltk(hdev, smp->responder_ltk, persistent);
110844f1a7abSJohan Hedberg 	}
11096a77083aSJohan Hedberg 
11106a77083aSJohan Hedberg 	if (smp->link_key) {
1111e3befab9SJohan Hedberg 		struct link_key *key;
1112e3befab9SJohan Hedberg 		u8 type;
1113e3befab9SJohan Hedberg 
1114e3befab9SJohan Hedberg 		if (test_bit(SMP_FLAG_DEBUG_KEY, &smp->flags))
1115e3befab9SJohan Hedberg 			type = HCI_LK_DEBUG_COMBINATION;
1116e3befab9SJohan Hedberg 		else if (hcon->sec_level == BT_SECURITY_FIPS)
1117e3befab9SJohan Hedberg 			type = HCI_LK_AUTH_COMBINATION_P256;
1118e3befab9SJohan Hedberg 		else
1119e3befab9SJohan Hedberg 			type = HCI_LK_UNAUTH_COMBINATION_P256;
1120e3befab9SJohan Hedberg 
1121e3befab9SJohan Hedberg 		key = hci_add_link_key(hdev, smp->conn->hcon, &hcon->dst,
1122e3befab9SJohan Hedberg 				       smp->link_key, type, 0, &persistent);
1123e3befab9SJohan Hedberg 		if (key) {
1124*865f1f43SXiao Yao 			key->link_type = hcon->type;
1125*865f1f43SXiao Yao 			key->bdaddr_type = hcon->dst_type;
1126e3befab9SJohan Hedberg 			mgmt_new_link_key(hdev, key, persistent);
1127e3befab9SJohan Hedberg 
1128e3befab9SJohan Hedberg 			/* Don't keep debug keys around if the relevant
1129e3befab9SJohan Hedberg 			 * flag is not set.
1130e3befab9SJohan Hedberg 			 */
1131d7a5a11dSMarcel Holtmann 			if (!hci_dev_test_flag(hdev, HCI_KEEP_DEBUG_KEYS) &&
1132e3befab9SJohan Hedberg 			    key->type == HCI_LK_DEBUG_COMBINATION) {
1133e3befab9SJohan Hedberg 				list_del_rcu(&key->list);
1134e3befab9SJohan Hedberg 				kfree_rcu(key, rcu);
1135e3befab9SJohan Hedberg 			}
1136e3befab9SJohan Hedberg 		}
11376a77083aSJohan Hedberg 	}
11386a77083aSJohan Hedberg }
11396a77083aSJohan Hedberg 
sc_add_ltk(struct smp_chan * smp)1140d3e54a87SJohan Hedberg static void sc_add_ltk(struct smp_chan *smp)
1141d3e54a87SJohan Hedberg {
1142d3e54a87SJohan Hedberg 	struct hci_conn *hcon = smp->conn->hcon;
1143d3e54a87SJohan Hedberg 	u8 key_type, auth;
1144d3e54a87SJohan Hedberg 
1145d3e54a87SJohan Hedberg 	if (test_bit(SMP_FLAG_DEBUG_KEY, &smp->flags))
1146d3e54a87SJohan Hedberg 		key_type = SMP_LTK_P256_DEBUG;
1147d3e54a87SJohan Hedberg 	else
1148d3e54a87SJohan Hedberg 		key_type = SMP_LTK_P256;
1149d3e54a87SJohan Hedberg 
1150d3e54a87SJohan Hedberg 	if (hcon->pending_sec_level == BT_SECURITY_FIPS)
1151d3e54a87SJohan Hedberg 		auth = 1;
1152d3e54a87SJohan Hedberg 	else
1153d3e54a87SJohan Hedberg 		auth = 0;
1154d3e54a87SJohan Hedberg 
1155d3e54a87SJohan Hedberg 	smp->ltk = hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
1156d3e54a87SJohan Hedberg 			       key_type, auth, smp->tk, smp->enc_key_size,
1157d3e54a87SJohan Hedberg 			       0, 0);
1158d3e54a87SJohan Hedberg }
1159d3e54a87SJohan Hedberg 
sc_generate_link_key(struct smp_chan * smp)11606a77083aSJohan Hedberg static void sc_generate_link_key(struct smp_chan *smp)
11616a77083aSJohan Hedberg {
1162a62da6f1SJohan Hedberg 	/* From core spec. Spells out in ASCII as 'lebr'. */
11636a77083aSJohan Hedberg 	const u8 lebr[4] = { 0x72, 0x62, 0x65, 0x6c };
11646a77083aSJohan Hedberg 
11656a77083aSJohan Hedberg 	smp->link_key = kzalloc(16, GFP_KERNEL);
11666a77083aSJohan Hedberg 	if (!smp->link_key)
11676a77083aSJohan Hedberg 		return;
11686a77083aSJohan Hedberg 
1169a62da6f1SJohan Hedberg 	if (test_bit(SMP_FLAG_CT2, &smp->flags)) {
1170151129dfSChristophe JAILLET 		/* SALT = 0x000000000000000000000000746D7031 */
1171a62da6f1SJohan Hedberg 		const u8 salt[16] = { 0x31, 0x70, 0x6d, 0x74 };
1172a62da6f1SJohan Hedberg 
1173a62da6f1SJohan Hedberg 		if (smp_h7(smp->tfm_cmac, smp->tk, salt, smp->link_key)) {
1174453431a5SWaiman Long 			kfree_sensitive(smp->link_key);
1175a62da6f1SJohan Hedberg 			smp->link_key = NULL;
1176a62da6f1SJohan Hedberg 			return;
1177a62da6f1SJohan Hedberg 		}
1178a62da6f1SJohan Hedberg 	} else {
1179a62da6f1SJohan Hedberg 		/* From core spec. Spells out in ASCII as 'tmp1'. */
1180a62da6f1SJohan Hedberg 		const u8 tmp1[4] = { 0x31, 0x70, 0x6d, 0x74 };
1181a62da6f1SJohan Hedberg 
11826a77083aSJohan Hedberg 		if (smp_h6(smp->tfm_cmac, smp->tk, tmp1, smp->link_key)) {
1183453431a5SWaiman Long 			kfree_sensitive(smp->link_key);
11846a77083aSJohan Hedberg 			smp->link_key = NULL;
11856a77083aSJohan Hedberg 			return;
11866a77083aSJohan Hedberg 		}
1187a62da6f1SJohan Hedberg 	}
11886a77083aSJohan Hedberg 
11896a77083aSJohan Hedberg 	if (smp_h6(smp->tfm_cmac, smp->link_key, lebr, smp->link_key)) {
1190453431a5SWaiman Long 		kfree_sensitive(smp->link_key);
11916a77083aSJohan Hedberg 		smp->link_key = NULL;
11926a77083aSJohan Hedberg 		return;
11936a77083aSJohan Hedberg 	}
119444f1a7abSJohan Hedberg }
119544f1a7abSJohan Hedberg 
smp_allow_key_dist(struct smp_chan * smp)1196b28b4943SJohan Hedberg static void smp_allow_key_dist(struct smp_chan *smp)
1197b28b4943SJohan Hedberg {
1198b28b4943SJohan Hedberg 	/* Allow the first expected phase 3 PDU. The rest of the PDUs
1199b28b4943SJohan Hedberg 	 * will be allowed in each PDU handler to ensure we receive
1200b28b4943SJohan Hedberg 	 * them in the correct order.
1201b28b4943SJohan Hedberg 	 */
1202b28b4943SJohan Hedberg 	if (smp->remote_key_dist & SMP_DIST_ENC_KEY)
1203b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_ENCRYPT_INFO);
1204b28b4943SJohan Hedberg 	else if (smp->remote_key_dist & SMP_DIST_ID_KEY)
1205b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO);
1206b28b4943SJohan Hedberg 	else if (smp->remote_key_dist & SMP_DIST_SIGN)
1207b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO);
1208b28b4943SJohan Hedberg }
1209b28b4943SJohan Hedberg 
sc_generate_ltk(struct smp_chan * smp)1210b5ae344dSJohan Hedberg static void sc_generate_ltk(struct smp_chan *smp)
1211b5ae344dSJohan Hedberg {
1212a62da6f1SJohan Hedberg 	/* From core spec. Spells out in ASCII as 'brle'. */
1213b5ae344dSJohan Hedberg 	const u8 brle[4] = { 0x65, 0x6c, 0x72, 0x62 };
1214b5ae344dSJohan Hedberg 	struct hci_conn *hcon = smp->conn->hcon;
1215b5ae344dSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
1216b5ae344dSJohan Hedberg 	struct link_key *key;
1217b5ae344dSJohan Hedberg 
1218b5ae344dSJohan Hedberg 	key = hci_find_link_key(hdev, &hcon->dst);
1219b5ae344dSJohan Hedberg 	if (!key) {
12202064ee33SMarcel Holtmann 		bt_dev_err(hdev, "no Link Key found to generate LTK");
1221b5ae344dSJohan Hedberg 		return;
1222b5ae344dSJohan Hedberg 	}
1223b5ae344dSJohan Hedberg 
1224b5ae344dSJohan Hedberg 	if (key->type == HCI_LK_DEBUG_COMBINATION)
1225b5ae344dSJohan Hedberg 		set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags);
1226b5ae344dSJohan Hedberg 
1227a62da6f1SJohan Hedberg 	if (test_bit(SMP_FLAG_CT2, &smp->flags)) {
1228151129dfSChristophe JAILLET 		/* SALT = 0x000000000000000000000000746D7032 */
1229a62da6f1SJohan Hedberg 		const u8 salt[16] = { 0x32, 0x70, 0x6d, 0x74 };
1230a62da6f1SJohan Hedberg 
1231a62da6f1SJohan Hedberg 		if (smp_h7(smp->tfm_cmac, key->val, salt, smp->tk))
1232a62da6f1SJohan Hedberg 			return;
1233a62da6f1SJohan Hedberg 	} else {
1234a62da6f1SJohan Hedberg 		/* From core spec. Spells out in ASCII as 'tmp2'. */
1235a62da6f1SJohan Hedberg 		const u8 tmp2[4] = { 0x32, 0x70, 0x6d, 0x74 };
1236a62da6f1SJohan Hedberg 
1237b5ae344dSJohan Hedberg 		if (smp_h6(smp->tfm_cmac, key->val, tmp2, smp->tk))
1238b5ae344dSJohan Hedberg 			return;
1239a62da6f1SJohan Hedberg 	}
1240b5ae344dSJohan Hedberg 
1241b5ae344dSJohan Hedberg 	if (smp_h6(smp->tfm_cmac, smp->tk, brle, smp->tk))
1242b5ae344dSJohan Hedberg 		return;
1243b5ae344dSJohan Hedberg 
1244b5ae344dSJohan Hedberg 	sc_add_ltk(smp);
1245b5ae344dSJohan Hedberg }
1246b5ae344dSJohan Hedberg 
smp_distribute_keys(struct smp_chan * smp)1247d6268e86SJohan Hedberg static void smp_distribute_keys(struct smp_chan *smp)
124844f1a7abSJohan Hedberg {
124944f1a7abSJohan Hedberg 	struct smp_cmd_pairing *req, *rsp;
125086d1407cSJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
125144f1a7abSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
125244f1a7abSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
125344f1a7abSJohan Hedberg 	__u8 *keydist;
125444f1a7abSJohan Hedberg 
12552e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "conn %p", conn);
125644f1a7abSJohan Hedberg 
125744f1a7abSJohan Hedberg 	rsp = (void *) &smp->prsp[1];
125844f1a7abSJohan Hedberg 
125944f1a7abSJohan Hedberg 	/* The responder sends its keys first */
1260b28b4943SJohan Hedberg 	if (hcon->out && (smp->remote_key_dist & KEY_DIST_MASK)) {
1261b28b4943SJohan Hedberg 		smp_allow_key_dist(smp);
126286d1407cSJohan Hedberg 		return;
1263b28b4943SJohan Hedberg 	}
126444f1a7abSJohan Hedberg 
126544f1a7abSJohan Hedberg 	req = (void *) &smp->preq[1];
126644f1a7abSJohan Hedberg 
126744f1a7abSJohan Hedberg 	if (hcon->out) {
126844f1a7abSJohan Hedberg 		keydist = &rsp->init_key_dist;
126944f1a7abSJohan Hedberg 		*keydist &= req->init_key_dist;
127044f1a7abSJohan Hedberg 	} else {
127144f1a7abSJohan Hedberg 		keydist = &rsp->resp_key_dist;
127244f1a7abSJohan Hedberg 		*keydist &= req->resp_key_dist;
127344f1a7abSJohan Hedberg 	}
127444f1a7abSJohan Hedberg 
12756a77083aSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
1276b5ae344dSJohan Hedberg 		if (hcon->type == LE_LINK && (*keydist & SMP_DIST_LINK_KEY))
12776a77083aSJohan Hedberg 			sc_generate_link_key(smp);
1278b5ae344dSJohan Hedberg 		if (hcon->type == ACL_LINK && (*keydist & SMP_DIST_ENC_KEY))
1279b5ae344dSJohan Hedberg 			sc_generate_ltk(smp);
12806a77083aSJohan Hedberg 
12816a77083aSJohan Hedberg 		/* Clear the keys which are generated but not distributed */
12826a77083aSJohan Hedberg 		*keydist &= ~SMP_SC_NO_DIST;
12836a77083aSJohan Hedberg 	}
12846a77083aSJohan Hedberg 
12852e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "keydist 0x%x", *keydist);
128644f1a7abSJohan Hedberg 
128744f1a7abSJohan Hedberg 	if (*keydist & SMP_DIST_ENC_KEY) {
128844f1a7abSJohan Hedberg 		struct smp_cmd_encrypt_info enc;
1289fad646e1SArchie Pusaka 		struct smp_cmd_initiator_ident ident;
129044f1a7abSJohan Hedberg 		struct smp_ltk *ltk;
129144f1a7abSJohan Hedberg 		u8 authenticated;
129244f1a7abSJohan Hedberg 		__le16 ediv;
129344f1a7abSJohan Hedberg 		__le64 rand;
129444f1a7abSJohan Hedberg 
12951fc62c52SJohan Hedberg 		/* Make sure we generate only the significant amount of
12961fc62c52SJohan Hedberg 		 * bytes based on the encryption key size, and set the rest
12971fc62c52SJohan Hedberg 		 * of the value to zeroes.
12981fc62c52SJohan Hedberg 		 */
12991fc62c52SJohan Hedberg 		get_random_bytes(enc.ltk, smp->enc_key_size);
13001fc62c52SJohan Hedberg 		memset(enc.ltk + smp->enc_key_size, 0,
13011fc62c52SJohan Hedberg 		       sizeof(enc.ltk) - smp->enc_key_size);
13021fc62c52SJohan Hedberg 
130344f1a7abSJohan Hedberg 		get_random_bytes(&ediv, sizeof(ediv));
130444f1a7abSJohan Hedberg 		get_random_bytes(&rand, sizeof(rand));
130544f1a7abSJohan Hedberg 
130644f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
130744f1a7abSJohan Hedberg 
130844f1a7abSJohan Hedberg 		authenticated = hcon->sec_level == BT_SECURITY_HIGH;
130944f1a7abSJohan Hedberg 		ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type,
1310fad646e1SArchie Pusaka 				  SMP_LTK_RESPONDER, authenticated, enc.ltk,
131144f1a7abSJohan Hedberg 				  smp->enc_key_size, ediv, rand);
1312fad646e1SArchie Pusaka 		smp->responder_ltk = ltk;
131344f1a7abSJohan Hedberg 
131444f1a7abSJohan Hedberg 		ident.ediv = ediv;
131544f1a7abSJohan Hedberg 		ident.rand = rand;
131644f1a7abSJohan Hedberg 
1317fad646e1SArchie Pusaka 		smp_send_cmd(conn, SMP_CMD_INITIATOR_IDENT, sizeof(ident),
1318fad646e1SArchie Pusaka 			     &ident);
131944f1a7abSJohan Hedberg 
132044f1a7abSJohan Hedberg 		*keydist &= ~SMP_DIST_ENC_KEY;
132144f1a7abSJohan Hedberg 	}
132244f1a7abSJohan Hedberg 
132344f1a7abSJohan Hedberg 	if (*keydist & SMP_DIST_ID_KEY) {
132444f1a7abSJohan Hedberg 		struct smp_cmd_ident_addr_info addrinfo;
132544f1a7abSJohan Hedberg 		struct smp_cmd_ident_info idinfo;
132644f1a7abSJohan Hedberg 
132744f1a7abSJohan Hedberg 		memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk));
132844f1a7abSJohan Hedberg 
132944f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo);
133044f1a7abSJohan Hedberg 
133144f1a7abSJohan Hedberg 		/* The hci_conn contains the local identity address
133244f1a7abSJohan Hedberg 		 * after the connection has been established.
133344f1a7abSJohan Hedberg 		 *
133444f1a7abSJohan Hedberg 		 * This is true even when the connection has been
133544f1a7abSJohan Hedberg 		 * established using a resolvable random address.
133644f1a7abSJohan Hedberg 		 */
133744f1a7abSJohan Hedberg 		bacpy(&addrinfo.bdaddr, &hcon->src);
133844f1a7abSJohan Hedberg 		addrinfo.addr_type = hcon->src_type;
133944f1a7abSJohan Hedberg 
134044f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo),
134144f1a7abSJohan Hedberg 			     &addrinfo);
134244f1a7abSJohan Hedberg 
134344f1a7abSJohan Hedberg 		*keydist &= ~SMP_DIST_ID_KEY;
134444f1a7abSJohan Hedberg 	}
134544f1a7abSJohan Hedberg 
134644f1a7abSJohan Hedberg 	if (*keydist & SMP_DIST_SIGN) {
134744f1a7abSJohan Hedberg 		struct smp_cmd_sign_info sign;
134844f1a7abSJohan Hedberg 		struct smp_csrk *csrk;
134944f1a7abSJohan Hedberg 
135044f1a7abSJohan Hedberg 		/* Generate a new random key */
135144f1a7abSJohan Hedberg 		get_random_bytes(sign.csrk, sizeof(sign.csrk));
135244f1a7abSJohan Hedberg 
135344f1a7abSJohan Hedberg 		csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
135444f1a7abSJohan Hedberg 		if (csrk) {
13554cd3928aSJohan Hedberg 			if (hcon->sec_level > BT_SECURITY_MEDIUM)
13564cd3928aSJohan Hedberg 				csrk->type = MGMT_CSRK_LOCAL_AUTHENTICATED;
13574cd3928aSJohan Hedberg 			else
13584cd3928aSJohan Hedberg 				csrk->type = MGMT_CSRK_LOCAL_UNAUTHENTICATED;
135944f1a7abSJohan Hedberg 			memcpy(csrk->val, sign.csrk, sizeof(csrk->val));
136044f1a7abSJohan Hedberg 		}
1361fad646e1SArchie Pusaka 		smp->responder_csrk = csrk;
136244f1a7abSJohan Hedberg 
136344f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign);
136444f1a7abSJohan Hedberg 
136544f1a7abSJohan Hedberg 		*keydist &= ~SMP_DIST_SIGN;
136644f1a7abSJohan Hedberg 	}
136744f1a7abSJohan Hedberg 
136844f1a7abSJohan Hedberg 	/* If there are still keys to be received wait for them */
1369b28b4943SJohan Hedberg 	if (smp->remote_key_dist & KEY_DIST_MASK) {
1370b28b4943SJohan Hedberg 		smp_allow_key_dist(smp);
137186d1407cSJohan Hedberg 		return;
1372b28b4943SJohan Hedberg 	}
137344f1a7abSJohan Hedberg 
137444f1a7abSJohan Hedberg 	set_bit(SMP_FLAG_COMPLETE, &smp->flags);
137544f1a7abSJohan Hedberg 	smp_notify_keys(conn);
137644f1a7abSJohan Hedberg 
137744f1a7abSJohan Hedberg 	smp_chan_destroy(conn);
137844f1a7abSJohan Hedberg }
137944f1a7abSJohan Hedberg 
smp_timeout(struct work_struct * work)1380b68fda68SJohan Hedberg static void smp_timeout(struct work_struct *work)
1381b68fda68SJohan Hedberg {
1382b68fda68SJohan Hedberg 	struct smp_chan *smp = container_of(work, struct smp_chan,
1383b68fda68SJohan Hedberg 					    security_timer.work);
1384b68fda68SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
1385b68fda68SJohan Hedberg 
13862e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(conn->hcon->hdev, "conn %p", conn);
1387b68fda68SJohan Hedberg 
13881e91c29eSJohan Hedberg 	hci_disconnect(conn->hcon, HCI_ERROR_REMOTE_USER_TERM);
1389b68fda68SJohan Hedberg }
1390b68fda68SJohan Hedberg 
smp_chan_create(struct l2cap_conn * conn)13918aab4757SVinicius Costa Gomes static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
13928aab4757SVinicius Costa Gomes {
13932e1614f7SLuiz Augusto von Dentz 	struct hci_conn *hcon = conn->hcon;
13945d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
13958aab4757SVinicius Costa Gomes 	struct smp_chan *smp;
13968aab4757SVinicius Costa Gomes 
1397f1560463SMarcel Holtmann 	smp = kzalloc(sizeof(*smp), GFP_ATOMIC);
1398fc75cc86SJohan Hedberg 	if (!smp)
13998aab4757SVinicius Costa Gomes 		return NULL;
14008aab4757SVinicius Costa Gomes 
140171af2f6bSHerbert Xu 	smp->tfm_cmac = crypto_alloc_shash("cmac(aes)", 0, 0);
1402407cecf6SJohan Hedberg 	if (IS_ERR(smp->tfm_cmac)) {
14032e1614f7SLuiz Augusto von Dentz 		bt_dev_err(hcon->hdev, "Unable to create CMAC crypto context");
140428a220aaSArd Biesheuvel 		goto zfree_smp;
140547eb2ac8STudor Ambarus 	}
140647eb2ac8STudor Ambarus 
14076763f5eaSMeng Yu 	smp->tfm_ecdh = crypto_alloc_kpp("ecdh-nist-p256", 0, 0);
140847eb2ac8STudor Ambarus 	if (IS_ERR(smp->tfm_ecdh)) {
14092e1614f7SLuiz Augusto von Dentz 		bt_dev_err(hcon->hdev, "Unable to create ECDH crypto context");
141047eb2ac8STudor Ambarus 		goto free_shash;
1411407cecf6SJohan Hedberg 	}
1412407cecf6SJohan Hedberg 
14138aab4757SVinicius Costa Gomes 	smp->conn = conn;
14145d88cc73SJohan Hedberg 	chan->data = smp;
14158aab4757SVinicius Costa Gomes 
1416b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_FAIL);
1417b28b4943SJohan Hedberg 
1418b68fda68SJohan Hedberg 	INIT_DELAYED_WORK(&smp->security_timer, smp_timeout);
1419b68fda68SJohan Hedberg 
14202e1614f7SLuiz Augusto von Dentz 	hci_conn_hold(hcon);
14218aab4757SVinicius Costa Gomes 
14228aab4757SVinicius Costa Gomes 	return smp;
142347eb2ac8STudor Ambarus 
142447eb2ac8STudor Ambarus free_shash:
142547eb2ac8STudor Ambarus 	crypto_free_shash(smp->tfm_cmac);
142647eb2ac8STudor Ambarus zfree_smp:
1427453431a5SWaiman Long 	kfree_sensitive(smp);
142847eb2ac8STudor Ambarus 	return NULL;
14298aab4757SVinicius Costa Gomes }
14308aab4757SVinicius Costa Gomes 
sc_mackey_and_ltk(struct smp_chan * smp,u8 mackey[16],u8 ltk[16])1431760b018bSJohan Hedberg static int sc_mackey_and_ltk(struct smp_chan *smp, u8 mackey[16], u8 ltk[16])
1432760b018bSJohan Hedberg {
1433760b018bSJohan Hedberg 	struct hci_conn *hcon = smp->conn->hcon;
1434760b018bSJohan Hedberg 	u8 *na, *nb, a[7], b[7];
1435760b018bSJohan Hedberg 
1436760b018bSJohan Hedberg 	if (hcon->out) {
1437760b018bSJohan Hedberg 		na   = smp->prnd;
1438760b018bSJohan Hedberg 		nb   = smp->rrnd;
1439760b018bSJohan Hedberg 	} else {
1440760b018bSJohan Hedberg 		na   = smp->rrnd;
1441760b018bSJohan Hedberg 		nb   = smp->prnd;
1442760b018bSJohan Hedberg 	}
1443760b018bSJohan Hedberg 
1444760b018bSJohan Hedberg 	memcpy(a, &hcon->init_addr, 6);
1445760b018bSJohan Hedberg 	memcpy(b, &hcon->resp_addr, 6);
1446760b018bSJohan Hedberg 	a[6] = hcon->init_addr_type;
1447760b018bSJohan Hedberg 	b[6] = hcon->resp_addr_type;
1448760b018bSJohan Hedberg 
1449760b018bSJohan Hedberg 	return smp_f5(smp->tfm_cmac, smp->dhkey, na, nb, a, b, mackey, ltk);
1450760b018bSJohan Hedberg }
1451760b018bSJohan Hedberg 
sc_dhkey_check(struct smp_chan * smp)145238606f14SJohan Hedberg static void sc_dhkey_check(struct smp_chan *smp)
1453760b018bSJohan Hedberg {
1454760b018bSJohan Hedberg 	struct hci_conn *hcon = smp->conn->hcon;
1455760b018bSJohan Hedberg 	struct smp_cmd_dhkey_check check;
1456760b018bSJohan Hedberg 	u8 a[7], b[7], *local_addr, *remote_addr;
1457760b018bSJohan Hedberg 	u8 io_cap[3], r[16];
1458760b018bSJohan Hedberg 
1459760b018bSJohan Hedberg 	memcpy(a, &hcon->init_addr, 6);
1460760b018bSJohan Hedberg 	memcpy(b, &hcon->resp_addr, 6);
1461760b018bSJohan Hedberg 	a[6] = hcon->init_addr_type;
1462760b018bSJohan Hedberg 	b[6] = hcon->resp_addr_type;
1463760b018bSJohan Hedberg 
1464760b018bSJohan Hedberg 	if (hcon->out) {
1465760b018bSJohan Hedberg 		local_addr = a;
1466760b018bSJohan Hedberg 		remote_addr = b;
1467760b018bSJohan Hedberg 		memcpy(io_cap, &smp->preq[1], 3);
1468760b018bSJohan Hedberg 	} else {
1469760b018bSJohan Hedberg 		local_addr = b;
1470760b018bSJohan Hedberg 		remote_addr = a;
1471760b018bSJohan Hedberg 		memcpy(io_cap, &smp->prsp[1], 3);
1472760b018bSJohan Hedberg 	}
1473760b018bSJohan Hedberg 
1474dddd3059SJohan Hedberg 	memset(r, 0, sizeof(r));
1475dddd3059SJohan Hedberg 
1476dddd3059SJohan Hedberg 	if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY)
147738606f14SJohan Hedberg 		put_unaligned_le32(hcon->passkey_notify, r);
1478760b018bSJohan Hedberg 
1479a29b0733SJohan Hedberg 	if (smp->method == REQ_OOB)
1480a29b0733SJohan Hedberg 		memcpy(r, smp->rr, 16);
1481a29b0733SJohan Hedberg 
1482760b018bSJohan Hedberg 	smp_f6(smp->tfm_cmac, smp->mackey, smp->prnd, smp->rrnd, r, io_cap,
1483760b018bSJohan Hedberg 	       local_addr, remote_addr, check.e);
1484760b018bSJohan Hedberg 
1485760b018bSJohan Hedberg 	smp_send_cmd(smp->conn, SMP_CMD_DHKEY_CHECK, sizeof(check), &check);
1486dddd3059SJohan Hedberg }
1487dddd3059SJohan Hedberg 
sc_passkey_send_confirm(struct smp_chan * smp)148838606f14SJohan Hedberg static u8 sc_passkey_send_confirm(struct smp_chan *smp)
148938606f14SJohan Hedberg {
149038606f14SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
149138606f14SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
149238606f14SJohan Hedberg 	struct smp_cmd_pairing_confirm cfm;
149338606f14SJohan Hedberg 	u8 r;
149438606f14SJohan Hedberg 
149538606f14SJohan Hedberg 	r = ((hcon->passkey_notify >> smp->passkey_round) & 0x01);
149638606f14SJohan Hedberg 	r |= 0x80;
149738606f14SJohan Hedberg 
149838606f14SJohan Hedberg 	get_random_bytes(smp->prnd, sizeof(smp->prnd));
149938606f14SJohan Hedberg 
150038606f14SJohan Hedberg 	if (smp_f4(smp->tfm_cmac, smp->local_pk, smp->remote_pk, smp->prnd, r,
150138606f14SJohan Hedberg 		   cfm.confirm_val))
150238606f14SJohan Hedberg 		return SMP_UNSPECIFIED;
150338606f14SJohan Hedberg 
150438606f14SJohan Hedberg 	smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cfm), &cfm);
150538606f14SJohan Hedberg 
150638606f14SJohan Hedberg 	return 0;
150738606f14SJohan Hedberg }
150838606f14SJohan Hedberg 
sc_passkey_round(struct smp_chan * smp,u8 smp_op)150938606f14SJohan Hedberg static u8 sc_passkey_round(struct smp_chan *smp, u8 smp_op)
151038606f14SJohan Hedberg {
151138606f14SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
151238606f14SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
151338606f14SJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
151438606f14SJohan Hedberg 	u8 cfm[16], r;
151538606f14SJohan Hedberg 
151638606f14SJohan Hedberg 	/* Ignore the PDU if we've already done 20 rounds (0 - 19) */
151738606f14SJohan Hedberg 	if (smp->passkey_round >= 20)
151838606f14SJohan Hedberg 		return 0;
151938606f14SJohan Hedberg 
152038606f14SJohan Hedberg 	switch (smp_op) {
152138606f14SJohan Hedberg 	case SMP_CMD_PAIRING_RANDOM:
152238606f14SJohan Hedberg 		r = ((hcon->passkey_notify >> smp->passkey_round) & 0x01);
152338606f14SJohan Hedberg 		r |= 0x80;
152438606f14SJohan Hedberg 
152538606f14SJohan Hedberg 		if (smp_f4(smp->tfm_cmac, smp->remote_pk, smp->local_pk,
152638606f14SJohan Hedberg 			   smp->rrnd, r, cfm))
152738606f14SJohan Hedberg 			return SMP_UNSPECIFIED;
152838606f14SJohan Hedberg 
1529329d8230SJason A. Donenfeld 		if (crypto_memneq(smp->pcnf, cfm, 16))
153038606f14SJohan Hedberg 			return SMP_CONFIRM_FAILED;
153138606f14SJohan Hedberg 
153238606f14SJohan Hedberg 		smp->passkey_round++;
153338606f14SJohan Hedberg 
153438606f14SJohan Hedberg 		if (smp->passkey_round == 20) {
153538606f14SJohan Hedberg 			/* Generate MacKey and LTK */
153638606f14SJohan Hedberg 			if (sc_mackey_and_ltk(smp, smp->mackey, smp->tk))
153738606f14SJohan Hedberg 				return SMP_UNSPECIFIED;
153838606f14SJohan Hedberg 		}
153938606f14SJohan Hedberg 
154038606f14SJohan Hedberg 		/* The round is only complete when the initiator
154138606f14SJohan Hedberg 		 * receives pairing random.
154238606f14SJohan Hedberg 		 */
154338606f14SJohan Hedberg 		if (!hcon->out) {
154438606f14SJohan Hedberg 			smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM,
154538606f14SJohan Hedberg 				     sizeof(smp->prnd), smp->prnd);
1546d3e54a87SJohan Hedberg 			if (smp->passkey_round == 20)
154738606f14SJohan Hedberg 				SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
1548d3e54a87SJohan Hedberg 			else
154938606f14SJohan Hedberg 				SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
155038606f14SJohan Hedberg 			return 0;
155138606f14SJohan Hedberg 		}
155238606f14SJohan Hedberg 
155338606f14SJohan Hedberg 		/* Start the next round */
155438606f14SJohan Hedberg 		if (smp->passkey_round != 20)
155538606f14SJohan Hedberg 			return sc_passkey_round(smp, 0);
155638606f14SJohan Hedberg 
155738606f14SJohan Hedberg 		/* Passkey rounds are complete - start DHKey Check */
155838606f14SJohan Hedberg 		sc_dhkey_check(smp);
155938606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
156038606f14SJohan Hedberg 
156138606f14SJohan Hedberg 		break;
156238606f14SJohan Hedberg 
156338606f14SJohan Hedberg 	case SMP_CMD_PAIRING_CONFIRM:
156438606f14SJohan Hedberg 		if (test_bit(SMP_FLAG_WAIT_USER, &smp->flags)) {
156538606f14SJohan Hedberg 			set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
156638606f14SJohan Hedberg 			return 0;
156738606f14SJohan Hedberg 		}
156838606f14SJohan Hedberg 
156938606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
157038606f14SJohan Hedberg 
157138606f14SJohan Hedberg 		if (hcon->out) {
157238606f14SJohan Hedberg 			smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM,
157338606f14SJohan Hedberg 				     sizeof(smp->prnd), smp->prnd);
157438606f14SJohan Hedberg 			return 0;
157538606f14SJohan Hedberg 		}
157638606f14SJohan Hedberg 
157738606f14SJohan Hedberg 		return sc_passkey_send_confirm(smp);
157838606f14SJohan Hedberg 
157938606f14SJohan Hedberg 	case SMP_CMD_PUBLIC_KEY:
158038606f14SJohan Hedberg 	default:
158138606f14SJohan Hedberg 		/* Initiating device starts the round */
158238606f14SJohan Hedberg 		if (!hcon->out)
158338606f14SJohan Hedberg 			return 0;
158438606f14SJohan Hedberg 
15852e1614f7SLuiz Augusto von Dentz 		bt_dev_dbg(hdev, "Starting passkey round %u",
158638606f14SJohan Hedberg 			   smp->passkey_round + 1);
158738606f14SJohan Hedberg 
158838606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
158938606f14SJohan Hedberg 
159038606f14SJohan Hedberg 		return sc_passkey_send_confirm(smp);
159138606f14SJohan Hedberg 	}
159238606f14SJohan Hedberg 
159338606f14SJohan Hedberg 	return 0;
159438606f14SJohan Hedberg }
159538606f14SJohan Hedberg 
sc_user_reply(struct smp_chan * smp,u16 mgmt_op,__le32 passkey)1596dddd3059SJohan Hedberg static int sc_user_reply(struct smp_chan *smp, u16 mgmt_op, __le32 passkey)
1597dddd3059SJohan Hedberg {
159838606f14SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
159938606f14SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
160038606f14SJohan Hedberg 	u8 smp_op;
160138606f14SJohan Hedberg 
160238606f14SJohan Hedberg 	clear_bit(SMP_FLAG_WAIT_USER, &smp->flags);
160338606f14SJohan Hedberg 
1604dddd3059SJohan Hedberg 	switch (mgmt_op) {
1605dddd3059SJohan Hedberg 	case MGMT_OP_USER_PASSKEY_NEG_REPLY:
1606dddd3059SJohan Hedberg 		smp_failure(smp->conn, SMP_PASSKEY_ENTRY_FAILED);
1607dddd3059SJohan Hedberg 		return 0;
1608dddd3059SJohan Hedberg 	case MGMT_OP_USER_CONFIRM_NEG_REPLY:
1609dddd3059SJohan Hedberg 		smp_failure(smp->conn, SMP_NUMERIC_COMP_FAILED);
1610dddd3059SJohan Hedberg 		return 0;
161138606f14SJohan Hedberg 	case MGMT_OP_USER_PASSKEY_REPLY:
161238606f14SJohan Hedberg 		hcon->passkey_notify = le32_to_cpu(passkey);
161338606f14SJohan Hedberg 		smp->passkey_round = 0;
161438606f14SJohan Hedberg 
161538606f14SJohan Hedberg 		if (test_and_clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags))
161638606f14SJohan Hedberg 			smp_op = SMP_CMD_PAIRING_CONFIRM;
161738606f14SJohan Hedberg 		else
161838606f14SJohan Hedberg 			smp_op = 0;
161938606f14SJohan Hedberg 
162038606f14SJohan Hedberg 		if (sc_passkey_round(smp, smp_op))
162138606f14SJohan Hedberg 			return -EIO;
162238606f14SJohan Hedberg 
162338606f14SJohan Hedberg 		return 0;
1624dddd3059SJohan Hedberg 	}
1625dddd3059SJohan Hedberg 
1626d3e54a87SJohan Hedberg 	/* Initiator sends DHKey check first */
1627d3e54a87SJohan Hedberg 	if (hcon->out) {
162838606f14SJohan Hedberg 		sc_dhkey_check(smp);
1629d3e54a87SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
1630d3e54a87SJohan Hedberg 	} else if (test_and_clear_bit(SMP_FLAG_DHKEY_PENDING, &smp->flags)) {
1631d3e54a87SJohan Hedberg 		sc_dhkey_check(smp);
1632d3e54a87SJohan Hedberg 		sc_add_ltk(smp);
1633d3e54a87SJohan Hedberg 	}
1634760b018bSJohan Hedberg 
1635760b018bSJohan Hedberg 	return 0;
1636760b018bSJohan Hedberg }
1637760b018bSJohan Hedberg 
smp_user_confirm_reply(struct hci_conn * hcon,u16 mgmt_op,__le32 passkey)16382b64d153SBrian Gix int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
16392b64d153SBrian Gix {
1640b10e8017SJohan Hedberg 	struct l2cap_conn *conn = hcon->l2cap_data;
16415d88cc73SJohan Hedberg 	struct l2cap_chan *chan;
16422b64d153SBrian Gix 	struct smp_chan *smp;
16432b64d153SBrian Gix 	u32 value;
1644fc75cc86SJohan Hedberg 	int err;
16452b64d153SBrian Gix 
1646fc75cc86SJohan Hedberg 	if (!conn)
16472b64d153SBrian Gix 		return -ENOTCONN;
16482b64d153SBrian Gix 
16490ae8ef67SLuiz Augusto von Dentz 	bt_dev_dbg(conn->hcon->hdev, "");
16500ae8ef67SLuiz Augusto von Dentz 
16515d88cc73SJohan Hedberg 	chan = conn->smp;
16525d88cc73SJohan Hedberg 	if (!chan)
16535d88cc73SJohan Hedberg 		return -ENOTCONN;
16545d88cc73SJohan Hedberg 
1655fc75cc86SJohan Hedberg 	l2cap_chan_lock(chan);
1656fc75cc86SJohan Hedberg 	if (!chan->data) {
1657fc75cc86SJohan Hedberg 		err = -ENOTCONN;
1658fc75cc86SJohan Hedberg 		goto unlock;
1659fc75cc86SJohan Hedberg 	}
1660fc75cc86SJohan Hedberg 
16615d88cc73SJohan Hedberg 	smp = chan->data;
16622b64d153SBrian Gix 
1663760b018bSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
1664760b018bSJohan Hedberg 		err = sc_user_reply(smp, mgmt_op, passkey);
1665760b018bSJohan Hedberg 		goto unlock;
1666760b018bSJohan Hedberg 	}
1667760b018bSJohan Hedberg 
16682b64d153SBrian Gix 	switch (mgmt_op) {
16692b64d153SBrian Gix 	case MGMT_OP_USER_PASSKEY_REPLY:
16702b64d153SBrian Gix 		value = le32_to_cpu(passkey);
1671943a732aSJohan Hedberg 		memset(smp->tk, 0, sizeof(smp->tk));
167283b4b195SKai Ye 		bt_dev_dbg(conn->hcon->hdev, "PassKey: %u", value);
1673943a732aSJohan Hedberg 		put_unaligned_le32(value, smp->tk);
167419186c7bSGustavo A. R. Silva 		fallthrough;
16752b64d153SBrian Gix 	case MGMT_OP_USER_CONFIRM_REPLY:
16764a74d658SJohan Hedberg 		set_bit(SMP_FLAG_TK_VALID, &smp->flags);
16772b64d153SBrian Gix 		break;
16782b64d153SBrian Gix 	case MGMT_OP_USER_PASSKEY_NEG_REPLY:
16792b64d153SBrian Gix 	case MGMT_OP_USER_CONFIRM_NEG_REPLY:
168084794e11SJohan Hedberg 		smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
1681fc75cc86SJohan Hedberg 		err = 0;
1682fc75cc86SJohan Hedberg 		goto unlock;
16832b64d153SBrian Gix 	default:
168484794e11SJohan Hedberg 		smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
1685fc75cc86SJohan Hedberg 		err = -EOPNOTSUPP;
1686fc75cc86SJohan Hedberg 		goto unlock;
16872b64d153SBrian Gix 	}
16882b64d153SBrian Gix 
1689fc75cc86SJohan Hedberg 	err = 0;
1690fc75cc86SJohan Hedberg 
16912b64d153SBrian Gix 	/* If it is our turn to send Pairing Confirm, do so now */
16921cc61144SJohan Hedberg 	if (test_bit(SMP_FLAG_CFM_PENDING, &smp->flags)) {
16931cc61144SJohan Hedberg 		u8 rsp = smp_confirm(smp);
16941cc61144SJohan Hedberg 		if (rsp)
16951cc61144SJohan Hedberg 			smp_failure(conn, rsp);
16961cc61144SJohan Hedberg 	}
16972b64d153SBrian Gix 
1698fc75cc86SJohan Hedberg unlock:
1699fc75cc86SJohan Hedberg 	l2cap_chan_unlock(chan);
1700fc75cc86SJohan Hedberg 	return err;
17012b64d153SBrian Gix }
17022b64d153SBrian Gix 
build_bredr_pairing_cmd(struct smp_chan * smp,struct smp_cmd_pairing * req,struct smp_cmd_pairing * rsp)1703b5ae344dSJohan Hedberg static void build_bredr_pairing_cmd(struct smp_chan *smp,
1704b5ae344dSJohan Hedberg 				    struct smp_cmd_pairing *req,
1705b5ae344dSJohan Hedberg 				    struct smp_cmd_pairing *rsp)
1706b5ae344dSJohan Hedberg {
1707b5ae344dSJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
1708b5ae344dSJohan Hedberg 	struct hci_dev *hdev = conn->hcon->hdev;
1709b5ae344dSJohan Hedberg 	u8 local_dist = 0, remote_dist = 0;
1710b5ae344dSJohan Hedberg 
1711d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_BONDABLE)) {
1712b5ae344dSJohan Hedberg 		local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
1713b5ae344dSJohan Hedberg 		remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
1714b5ae344dSJohan Hedberg 	}
1715b5ae344dSJohan Hedberg 
1716d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_RPA_RESOLVING))
1717b5ae344dSJohan Hedberg 		remote_dist |= SMP_DIST_ID_KEY;
1718b5ae344dSJohan Hedberg 
1719d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_PRIVACY))
1720b5ae344dSJohan Hedberg 		local_dist |= SMP_DIST_ID_KEY;
1721b5ae344dSJohan Hedberg 
1722b5ae344dSJohan Hedberg 	if (!rsp) {
1723b5ae344dSJohan Hedberg 		memset(req, 0, sizeof(*req));
1724b5ae344dSJohan Hedberg 
1725a62da6f1SJohan Hedberg 		req->auth_req        = SMP_AUTH_CT2;
1726b5ae344dSJohan Hedberg 		req->init_key_dist   = local_dist;
1727b5ae344dSJohan Hedberg 		req->resp_key_dist   = remote_dist;
1728e3f6a257SJohan Hedberg 		req->max_key_size    = conn->hcon->enc_key_size;
1729b5ae344dSJohan Hedberg 
1730b5ae344dSJohan Hedberg 		smp->remote_key_dist = remote_dist;
1731b5ae344dSJohan Hedberg 
1732b5ae344dSJohan Hedberg 		return;
1733b5ae344dSJohan Hedberg 	}
1734b5ae344dSJohan Hedberg 
1735b5ae344dSJohan Hedberg 	memset(rsp, 0, sizeof(*rsp));
1736b5ae344dSJohan Hedberg 
1737a62da6f1SJohan Hedberg 	rsp->auth_req        = SMP_AUTH_CT2;
1738e3f6a257SJohan Hedberg 	rsp->max_key_size    = conn->hcon->enc_key_size;
1739b5ae344dSJohan Hedberg 	rsp->init_key_dist   = req->init_key_dist & remote_dist;
1740b5ae344dSJohan Hedberg 	rsp->resp_key_dist   = req->resp_key_dist & local_dist;
1741b5ae344dSJohan Hedberg 
1742b5ae344dSJohan Hedberg 	smp->remote_key_dist = rsp->init_key_dist;
1743b5ae344dSJohan Hedberg }
1744b5ae344dSJohan Hedberg 
smp_cmd_pairing_req(struct l2cap_conn * conn,struct sk_buff * skb)1745da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
174688ba43b6SAnderson Briglia {
17473158c50cSVinicius Costa Gomes 	struct smp_cmd_pairing rsp, *req = (void *) skb->data;
1748fc75cc86SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
1749b3c6410bSJohan Hedberg 	struct hci_dev *hdev = conn->hcon->hdev;
17508aab4757SVinicius Costa Gomes 	struct smp_chan *smp;
1751c7262e71SJohan Hedberg 	u8 key_size, auth, sec_level;
17528aab4757SVinicius Costa Gomes 	int ret;
175388ba43b6SAnderson Briglia 
17542e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "conn %p", conn);
175588ba43b6SAnderson Briglia 
1756c46b98beSJohan Hedberg 	if (skb->len < sizeof(*req))
175738e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1758c46b98beSJohan Hedberg 
175940bef302SJohan Hedberg 	if (conn->hcon->role != HCI_ROLE_SLAVE)
17602b64d153SBrian Gix 		return SMP_CMD_NOTSUPP;
17612b64d153SBrian Gix 
1762fc75cc86SJohan Hedberg 	if (!chan->data)
17638aab4757SVinicius Costa Gomes 		smp = smp_chan_create(conn);
1764fc75cc86SJohan Hedberg 	else
17655d88cc73SJohan Hedberg 		smp = chan->data;
1766d26a2345SVinicius Costa Gomes 
1767d08fd0e7SAndrei Emeltchenko 	if (!smp)
1768d08fd0e7SAndrei Emeltchenko 		return SMP_UNSPECIFIED;
1769d08fd0e7SAndrei Emeltchenko 
1770c05b9339SJohan Hedberg 	/* We didn't start the pairing, so match remote */
17710edb14deSJohan Hedberg 	auth = req->auth_req & AUTH_REQ_MASK(hdev);
1772c05b9339SJohan Hedberg 
1773d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BONDABLE) &&
1774c05b9339SJohan Hedberg 	    (auth & SMP_AUTH_BONDING))
1775b3c6410bSJohan Hedberg 		return SMP_PAIRING_NOTSUPP;
1776b3c6410bSJohan Hedberg 
1777d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SC_ONLY) && !(auth & SMP_AUTH_SC))
1778903b71c7SJohan Hedberg 		return SMP_AUTH_REQUIREMENTS;
1779903b71c7SJohan Hedberg 
17801c1def09SVinicius Costa Gomes 	smp->preq[0] = SMP_CMD_PAIRING_REQ;
17811c1def09SVinicius Costa Gomes 	memcpy(&smp->preq[1], req, sizeof(*req));
17823158c50cSVinicius Costa Gomes 	skb_pull(skb, sizeof(*req));
178388ba43b6SAnderson Briglia 
1784cb06d366SJohan Hedberg 	/* If the remote side's OOB flag is set it means it has
1785cb06d366SJohan Hedberg 	 * successfully received our local OOB data - therefore set the
1786cb06d366SJohan Hedberg 	 * flag to indicate that local OOB is in use.
1787cb06d366SJohan Hedberg 	 */
178894f14e47SJohan Hedberg 	if (req->oob_flag == SMP_OOB_PRESENT && SMP_DEV(hdev)->local_oob)
178958428563SJohan Hedberg 		set_bit(SMP_FLAG_LOCAL_OOB, &smp->flags);
179058428563SJohan Hedberg 
1791b5ae344dSJohan Hedberg 	/* SMP over BR/EDR requires special treatment */
1792b5ae344dSJohan Hedberg 	if (conn->hcon->type == ACL_LINK) {
1793b5ae344dSJohan Hedberg 		/* We must have a BR/EDR SC link */
179408f63cc5SMarcel Holtmann 		if (!test_bit(HCI_CONN_AES_CCM, &conn->hcon->flags) &&
1795b7cb93e5SMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP))
1796b5ae344dSJohan Hedberg 			return SMP_CROSS_TRANSP_NOT_ALLOWED;
1797b5ae344dSJohan Hedberg 
1798b5ae344dSJohan Hedberg 		set_bit(SMP_FLAG_SC, &smp->flags);
1799b5ae344dSJohan Hedberg 
1800b5ae344dSJohan Hedberg 		build_bredr_pairing_cmd(smp, req, &rsp);
1801b5ae344dSJohan Hedberg 
1802a62da6f1SJohan Hedberg 		if (req->auth_req & SMP_AUTH_CT2)
1803a62da6f1SJohan Hedberg 			set_bit(SMP_FLAG_CT2, &smp->flags);
1804a62da6f1SJohan Hedberg 
1805b5ae344dSJohan Hedberg 		key_size = min(req->max_key_size, rsp.max_key_size);
1806b5ae344dSJohan Hedberg 		if (check_enc_key_size(conn, key_size))
1807b5ae344dSJohan Hedberg 			return SMP_ENC_KEY_SIZE;
1808b5ae344dSJohan Hedberg 
1809b5ae344dSJohan Hedberg 		/* Clear bits which are generated but not distributed */
1810b5ae344dSJohan Hedberg 		smp->remote_key_dist &= ~SMP_SC_NO_DIST;
1811b5ae344dSJohan Hedberg 
1812b5ae344dSJohan Hedberg 		smp->prsp[0] = SMP_CMD_PAIRING_RSP;
1813b5ae344dSJohan Hedberg 		memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
1814b5ae344dSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
1815b5ae344dSJohan Hedberg 
1816b5ae344dSJohan Hedberg 		smp_distribute_keys(smp);
1817b5ae344dSJohan Hedberg 		return 0;
1818b5ae344dSJohan Hedberg 	}
1819b5ae344dSJohan Hedberg 
18205e3d3d9bSJohan Hedberg 	build_pairing_cmd(conn, req, &rsp, auth);
18215e3d3d9bSJohan Hedberg 
1822a62da6f1SJohan Hedberg 	if (rsp.auth_req & SMP_AUTH_SC) {
18235e3d3d9bSJohan Hedberg 		set_bit(SMP_FLAG_SC, &smp->flags);
18245e3d3d9bSJohan Hedberg 
1825a62da6f1SJohan Hedberg 		if (rsp.auth_req & SMP_AUTH_CT2)
1826a62da6f1SJohan Hedberg 			set_bit(SMP_FLAG_CT2, &smp->flags);
1827a62da6f1SJohan Hedberg 	}
1828a62da6f1SJohan Hedberg 
18295be5e275SJohan Hedberg 	if (conn->hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
18301afc2a1aSJohan Hedberg 		sec_level = BT_SECURITY_MEDIUM;
18311afc2a1aSJohan Hedberg 	else
1832c7262e71SJohan Hedberg 		sec_level = authreq_to_seclevel(auth);
18331afc2a1aSJohan Hedberg 
1834c7262e71SJohan Hedberg 	if (sec_level > conn->hcon->pending_sec_level)
1835c7262e71SJohan Hedberg 		conn->hcon->pending_sec_level = sec_level;
1836fdde0a26SIdo Yariv 
183749c922bbSStephen Hemminger 	/* If we need MITM check that it can be achieved */
18382ed8f65cSJohan Hedberg 	if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
18392ed8f65cSJohan Hedberg 		u8 method;
18402ed8f65cSJohan Hedberg 
18412ed8f65cSJohan Hedberg 		method = get_auth_method(smp, conn->hcon->io_capability,
18422ed8f65cSJohan Hedberg 					 req->io_capability);
18432ed8f65cSJohan Hedberg 		if (method == JUST_WORKS || method == JUST_CFM)
18442ed8f65cSJohan Hedberg 			return SMP_AUTH_REQUIREMENTS;
18452ed8f65cSJohan Hedberg 	}
18462ed8f65cSJohan Hedberg 
18473158c50cSVinicius Costa Gomes 	key_size = min(req->max_key_size, rsp.max_key_size);
18483158c50cSVinicius Costa Gomes 	if (check_enc_key_size(conn, key_size))
18493158c50cSVinicius Costa Gomes 		return SMP_ENC_KEY_SIZE;
185088ba43b6SAnderson Briglia 
1851e84a6b13SJohan Hedberg 	get_random_bytes(smp->prnd, sizeof(smp->prnd));
18528aab4757SVinicius Costa Gomes 
18531c1def09SVinicius Costa Gomes 	smp->prsp[0] = SMP_CMD_PAIRING_RSP;
18541c1def09SVinicius Costa Gomes 	memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
1855f01ead31SAnderson Briglia 
18563158c50cSVinicius Costa Gomes 	smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
18573b19146dSJohan Hedberg 
18583b19146dSJohan Hedberg 	clear_bit(SMP_FLAG_INITIATOR, &smp->flags);
18593b19146dSJohan Hedberg 
186019c5ce9cSJohan Hedberg 	/* Strictly speaking we shouldn't allow Pairing Confirm for the
186119c5ce9cSJohan Hedberg 	 * SC case, however some implementations incorrectly copy RFU auth
186219c5ce9cSJohan Hedberg 	 * req bits from our security request, which may create a false
186319c5ce9cSJohan Hedberg 	 * positive SC enablement.
186419c5ce9cSJohan Hedberg 	 */
186519c5ce9cSJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
186619c5ce9cSJohan Hedberg 
18673b19146dSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
18683b19146dSJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PUBLIC_KEY);
18693b19146dSJohan Hedberg 		/* Clear bits which are generated but not distributed */
18703b19146dSJohan Hedberg 		smp->remote_key_dist &= ~SMP_SC_NO_DIST;
18713b19146dSJohan Hedberg 		/* Wait for Public Key from Initiating Device */
18723b19146dSJohan Hedberg 		return 0;
18733b19146dSJohan Hedberg 	}
1874da85e5e5SVinicius Costa Gomes 
18752b64d153SBrian Gix 	/* Request setup of TK */
18762b64d153SBrian Gix 	ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability);
18772b64d153SBrian Gix 	if (ret)
18782b64d153SBrian Gix 		return SMP_UNSPECIFIED;
18792b64d153SBrian Gix 
1880da85e5e5SVinicius Costa Gomes 	return 0;
188188ba43b6SAnderson Briglia }
188288ba43b6SAnderson Briglia 
sc_send_public_key(struct smp_chan * smp)18833b19146dSJohan Hedberg static u8 sc_send_public_key(struct smp_chan *smp)
18843b19146dSJohan Hedberg {
188570157ef5SJohan Hedberg 	struct hci_dev *hdev = smp->conn->hcon->hdev;
188670157ef5SJohan Hedberg 
188756860245SMarcel Holtmann 	bt_dev_dbg(hdev, "");
18883b19146dSJohan Hedberg 
18891a8bab4fSJohan Hedberg 	if (test_bit(SMP_FLAG_LOCAL_OOB, &smp->flags)) {
189033d0c030SMarcel Holtmann 		struct l2cap_chan *chan = hdev->smp_data;
189133d0c030SMarcel Holtmann 		struct smp_dev *smp_dev;
189233d0c030SMarcel Holtmann 
189333d0c030SMarcel Holtmann 		if (!chan || !chan->data)
189433d0c030SMarcel Holtmann 			return SMP_UNSPECIFIED;
189533d0c030SMarcel Holtmann 
189633d0c030SMarcel Holtmann 		smp_dev = chan->data;
189733d0c030SMarcel Holtmann 
189833d0c030SMarcel Holtmann 		memcpy(smp->local_pk, smp_dev->local_pk, 64);
1899fb334feeSMarcel Holtmann 		memcpy(smp->lr, smp_dev->local_rand, 16);
190033d0c030SMarcel Holtmann 
190133d0c030SMarcel Holtmann 		if (smp_dev->debug_key)
190233d0c030SMarcel Holtmann 			set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags);
190333d0c030SMarcel Holtmann 
190433d0c030SMarcel Holtmann 		goto done;
190533d0c030SMarcel Holtmann 	}
190633d0c030SMarcel Holtmann 
1907d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS)) {
19082e1614f7SLuiz Augusto von Dentz 		bt_dev_dbg(hdev, "Using debug keys");
1909c0153b0bSTudor Ambarus 		if (set_ecdh_privkey(smp->tfm_ecdh, debug_sk))
1910c0153b0bSTudor Ambarus 			return SMP_UNSPECIFIED;
191170157ef5SJohan Hedberg 		memcpy(smp->local_pk, debug_pk, 64);
191270157ef5SJohan Hedberg 		set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags);
191370157ef5SJohan Hedberg 	} else {
19146c0dcc50SJohan Hedberg 		while (true) {
1915c0153b0bSTudor Ambarus 			/* Generate key pair for Secure Connections */
1916c0153b0bSTudor Ambarus 			if (generate_ecdh_keys(smp->tfm_ecdh, smp->local_pk))
19173b19146dSJohan Hedberg 				return SMP_UNSPECIFIED;
19183b19146dSJohan Hedberg 
191970157ef5SJohan Hedberg 			/* This is unlikely, but we need to check that
192091641b79SZheng Yongjun 			 * we didn't accidentally generate a debug key.
19216c0dcc50SJohan Hedberg 			 */
1922c0153b0bSTudor Ambarus 			if (crypto_memneq(smp->local_pk, debug_pk, 64))
19236c0dcc50SJohan Hedberg 				break;
19246c0dcc50SJohan Hedberg 		}
192570157ef5SJohan Hedberg 	}
19266c0dcc50SJohan Hedberg 
192733d0c030SMarcel Holtmann done:
1928c7a3d57dSJohan Hedberg 	SMP_DBG("Local Public Key X: %32phN", smp->local_pk);
19298e4e2ee5SMarcel Holtmann 	SMP_DBG("Local Public Key Y: %32phN", smp->local_pk + 32);
19303b19146dSJohan Hedberg 
19313b19146dSJohan Hedberg 	smp_send_cmd(smp->conn, SMP_CMD_PUBLIC_KEY, 64, smp->local_pk);
19323b19146dSJohan Hedberg 
19333b19146dSJohan Hedberg 	return 0;
19343b19146dSJohan Hedberg }
19353b19146dSJohan Hedberg 
smp_cmd_pairing_rsp(struct l2cap_conn * conn,struct sk_buff * skb)1936da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
193788ba43b6SAnderson Briglia {
19383158c50cSVinicius Costa Gomes 	struct smp_cmd_pairing *req, *rsp = (void *) skb->data;
19395d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
19405d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
19410edb14deSJohan Hedberg 	struct hci_dev *hdev = conn->hcon->hdev;
19423a7dbfb8SJohan Hedberg 	u8 key_size, auth;
19437d24ddccSAnderson Briglia 	int ret;
194488ba43b6SAnderson Briglia 
19452e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "conn %p", conn);
194688ba43b6SAnderson Briglia 
1947c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rsp))
194838e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1949c46b98beSJohan Hedberg 
195040bef302SJohan Hedberg 	if (conn->hcon->role != HCI_ROLE_MASTER)
19512b64d153SBrian Gix 		return SMP_CMD_NOTSUPP;
19522b64d153SBrian Gix 
19533158c50cSVinicius Costa Gomes 	skb_pull(skb, sizeof(*rsp));
1954da85e5e5SVinicius Costa Gomes 
19551c1def09SVinicius Costa Gomes 	req = (void *) &smp->preq[1];
19563158c50cSVinicius Costa Gomes 
19573158c50cSVinicius Costa Gomes 	key_size = min(req->max_key_size, rsp->max_key_size);
19583158c50cSVinicius Costa Gomes 	if (check_enc_key_size(conn, key_size))
19593158c50cSVinicius Costa Gomes 		return SMP_ENC_KEY_SIZE;
19603158c50cSVinicius Costa Gomes 
19610edb14deSJohan Hedberg 	auth = rsp->auth_req & AUTH_REQ_MASK(hdev);
1962c05b9339SJohan Hedberg 
1963d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SC_ONLY) && !(auth & SMP_AUTH_SC))
1964903b71c7SJohan Hedberg 		return SMP_AUTH_REQUIREMENTS;
1965903b71c7SJohan Hedberg 
1966cb06d366SJohan Hedberg 	/* If the remote side's OOB flag is set it means it has
1967cb06d366SJohan Hedberg 	 * successfully received our local OOB data - therefore set the
1968cb06d366SJohan Hedberg 	 * flag to indicate that local OOB is in use.
1969cb06d366SJohan Hedberg 	 */
197094f14e47SJohan Hedberg 	if (rsp->oob_flag == SMP_OOB_PRESENT && SMP_DEV(hdev)->local_oob)
197158428563SJohan Hedberg 		set_bit(SMP_FLAG_LOCAL_OOB, &smp->flags);
197258428563SJohan Hedberg 
1973b5ae344dSJohan Hedberg 	smp->prsp[0] = SMP_CMD_PAIRING_RSP;
1974b5ae344dSJohan Hedberg 	memcpy(&smp->prsp[1], rsp, sizeof(*rsp));
1975b5ae344dSJohan Hedberg 
1976b5ae344dSJohan Hedberg 	/* Update remote key distribution in case the remote cleared
1977b5ae344dSJohan Hedberg 	 * some bits that we had enabled in our request.
1978b5ae344dSJohan Hedberg 	 */
1979b5ae344dSJohan Hedberg 	smp->remote_key_dist &= rsp->resp_key_dist;
1980b5ae344dSJohan Hedberg 
1981a62da6f1SJohan Hedberg 	if ((req->auth_req & SMP_AUTH_CT2) && (auth & SMP_AUTH_CT2))
1982a62da6f1SJohan Hedberg 		set_bit(SMP_FLAG_CT2, &smp->flags);
1983a62da6f1SJohan Hedberg 
1984b5ae344dSJohan Hedberg 	/* For BR/EDR this means we're done and can start phase 3 */
1985b5ae344dSJohan Hedberg 	if (conn->hcon->type == ACL_LINK) {
1986b5ae344dSJohan Hedberg 		/* Clear bits which are generated but not distributed */
1987b5ae344dSJohan Hedberg 		smp->remote_key_dist &= ~SMP_SC_NO_DIST;
1988b5ae344dSJohan Hedberg 		smp_distribute_keys(smp);
1989b5ae344dSJohan Hedberg 		return 0;
1990b5ae344dSJohan Hedberg 	}
1991b5ae344dSJohan Hedberg 
199265668776SJohan Hedberg 	if ((req->auth_req & SMP_AUTH_SC) && (auth & SMP_AUTH_SC))
199365668776SJohan Hedberg 		set_bit(SMP_FLAG_SC, &smp->flags);
1994d2eb9e10SJohan Hedberg 	else if (conn->hcon->pending_sec_level > BT_SECURITY_HIGH)
1995d2eb9e10SJohan Hedberg 		conn->hcon->pending_sec_level = BT_SECURITY_HIGH;
199665668776SJohan Hedberg 
199749c922bbSStephen Hemminger 	/* If we need MITM check that it can be achieved */
19982ed8f65cSJohan Hedberg 	if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
19992ed8f65cSJohan Hedberg 		u8 method;
20002ed8f65cSJohan Hedberg 
20012ed8f65cSJohan Hedberg 		method = get_auth_method(smp, req->io_capability,
20022ed8f65cSJohan Hedberg 					 rsp->io_capability);
20032ed8f65cSJohan Hedberg 		if (method == JUST_WORKS || method == JUST_CFM)
20042ed8f65cSJohan Hedberg 			return SMP_AUTH_REQUIREMENTS;
20052ed8f65cSJohan Hedberg 	}
20062ed8f65cSJohan Hedberg 
2007e84a6b13SJohan Hedberg 	get_random_bytes(smp->prnd, sizeof(smp->prnd));
20087d24ddccSAnderson Briglia 
2009fdcc4becSJohan Hedberg 	/* Update remote key distribution in case the remote cleared
2010fdcc4becSJohan Hedberg 	 * some bits that we had enabled in our request.
2011fdcc4becSJohan Hedberg 	 */
2012fdcc4becSJohan Hedberg 	smp->remote_key_dist &= rsp->resp_key_dist;
2013fdcc4becSJohan Hedberg 
20143b19146dSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
20153b19146dSJohan Hedberg 		/* Clear bits which are generated but not distributed */
20163b19146dSJohan Hedberg 		smp->remote_key_dist &= ~SMP_SC_NO_DIST;
20173b19146dSJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PUBLIC_KEY);
20183b19146dSJohan Hedberg 		return sc_send_public_key(smp);
20193b19146dSJohan Hedberg 	}
20203b19146dSJohan Hedberg 
2021c05b9339SJohan Hedberg 	auth |= req->auth_req;
20222b64d153SBrian Gix 
2023476585ecSJohan Hedberg 	ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability);
20242b64d153SBrian Gix 	if (ret)
20252b64d153SBrian Gix 		return SMP_UNSPECIFIED;
20262b64d153SBrian Gix 
20274a74d658SJohan Hedberg 	set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
20282b64d153SBrian Gix 
20292b64d153SBrian Gix 	/* Can't compose response until we have been confirmed */
20304a74d658SJohan Hedberg 	if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
20311cc61144SJohan Hedberg 		return smp_confirm(smp);
2032da85e5e5SVinicius Costa Gomes 
2033da85e5e5SVinicius Costa Gomes 	return 0;
203488ba43b6SAnderson Briglia }
203588ba43b6SAnderson Briglia 
sc_check_confirm(struct smp_chan * smp)2036dcee2b32SJohan Hedberg static u8 sc_check_confirm(struct smp_chan *smp)
2037dcee2b32SJohan Hedberg {
2038dcee2b32SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
2039dcee2b32SJohan Hedberg 
20402e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(conn->hcon->hdev, "");
2041dcee2b32SJohan Hedberg 
204238606f14SJohan Hedberg 	if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY)
204338606f14SJohan Hedberg 		return sc_passkey_round(smp, SMP_CMD_PAIRING_CONFIRM);
204438606f14SJohan Hedberg 
2045dcee2b32SJohan Hedberg 	if (conn->hcon->out) {
2046dcee2b32SJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
2047dcee2b32SJohan Hedberg 			     smp->prnd);
2048dcee2b32SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
2049dcee2b32SJohan Hedberg 	}
2050dcee2b32SJohan Hedberg 
2051dcee2b32SJohan Hedberg 	return 0;
2052dcee2b32SJohan Hedberg }
2053dcee2b32SJohan Hedberg 
205419c5ce9cSJohan Hedberg /* Work-around for some implementations that incorrectly copy RFU bits
205519c5ce9cSJohan Hedberg  * from our security request and thereby create the impression that
205619c5ce9cSJohan Hedberg  * we're doing SC when in fact the remote doesn't support it.
205719c5ce9cSJohan Hedberg  */
fixup_sc_false_positive(struct smp_chan * smp)205819c5ce9cSJohan Hedberg static int fixup_sc_false_positive(struct smp_chan *smp)
205919c5ce9cSJohan Hedberg {
206019c5ce9cSJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
206119c5ce9cSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
206219c5ce9cSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
206319c5ce9cSJohan Hedberg 	struct smp_cmd_pairing *req, *rsp;
206419c5ce9cSJohan Hedberg 	u8 auth;
206519c5ce9cSJohan Hedberg 
2066fad646e1SArchie Pusaka 	/* The issue is only observed when we're in responder role */
206719c5ce9cSJohan Hedberg 	if (hcon->out)
206819c5ce9cSJohan Hedberg 		return SMP_UNSPECIFIED;
206919c5ce9cSJohan Hedberg 
207019c5ce9cSJohan Hedberg 	if (hci_dev_test_flag(hdev, HCI_SC_ONLY)) {
20712064ee33SMarcel Holtmann 		bt_dev_err(hdev, "refusing legacy fallback in SC-only mode");
207219c5ce9cSJohan Hedberg 		return SMP_UNSPECIFIED;
207319c5ce9cSJohan Hedberg 	}
207419c5ce9cSJohan Hedberg 
20752064ee33SMarcel Holtmann 	bt_dev_err(hdev, "trying to fall back to legacy SMP");
207619c5ce9cSJohan Hedberg 
207719c5ce9cSJohan Hedberg 	req = (void *) &smp->preq[1];
207819c5ce9cSJohan Hedberg 	rsp = (void *) &smp->prsp[1];
207919c5ce9cSJohan Hedberg 
208019c5ce9cSJohan Hedberg 	/* Rebuild key dist flags which may have been cleared for SC */
208119c5ce9cSJohan Hedberg 	smp->remote_key_dist = (req->init_key_dist & rsp->resp_key_dist);
208219c5ce9cSJohan Hedberg 
208319c5ce9cSJohan Hedberg 	auth = req->auth_req & AUTH_REQ_MASK(hdev);
208419c5ce9cSJohan Hedberg 
208519c5ce9cSJohan Hedberg 	if (tk_request(conn, 0, auth, rsp->io_capability, req->io_capability)) {
20862064ee33SMarcel Holtmann 		bt_dev_err(hdev, "failed to fall back to legacy SMP");
208719c5ce9cSJohan Hedberg 		return SMP_UNSPECIFIED;
208819c5ce9cSJohan Hedberg 	}
208919c5ce9cSJohan Hedberg 
209019c5ce9cSJohan Hedberg 	clear_bit(SMP_FLAG_SC, &smp->flags);
209119c5ce9cSJohan Hedberg 
209219c5ce9cSJohan Hedberg 	return 0;
209319c5ce9cSJohan Hedberg }
209419c5ce9cSJohan Hedberg 
smp_cmd_pairing_confirm(struct l2cap_conn * conn,struct sk_buff * skb)2095da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
209688ba43b6SAnderson Briglia {
20975d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
20985d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
20992e1614f7SLuiz Augusto von Dentz 	struct hci_conn *hcon = conn->hcon;
21002e1614f7SLuiz Augusto von Dentz 	struct hci_dev *hdev = hcon->hdev;
21017d24ddccSAnderson Briglia 
2102fad646e1SArchie Pusaka 	bt_dev_dbg(hdev, "conn %p %s", conn,
2103fad646e1SArchie Pusaka 		   hcon->out ? "initiator" : "responder");
210488ba43b6SAnderson Briglia 
2105c46b98beSJohan Hedberg 	if (skb->len < sizeof(smp->pcnf))
210638e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2107c46b98beSJohan Hedberg 
21081c1def09SVinicius Costa Gomes 	memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf));
21091c1def09SVinicius Costa Gomes 	skb_pull(skb, sizeof(smp->pcnf));
21107d24ddccSAnderson Briglia 
211119c5ce9cSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
211219c5ce9cSJohan Hedberg 		int ret;
211319c5ce9cSJohan Hedberg 
211419c5ce9cSJohan Hedberg 		/* Public Key exchange must happen before any other steps */
211519c5ce9cSJohan Hedberg 		if (test_bit(SMP_FLAG_REMOTE_PK, &smp->flags))
2116dcee2b32SJohan Hedberg 			return sc_check_confirm(smp);
2117dcee2b32SJohan Hedberg 
21182e1614f7SLuiz Augusto von Dentz 		bt_dev_err(hdev, "Unexpected SMP Pairing Confirm");
211919c5ce9cSJohan Hedberg 
212019c5ce9cSJohan Hedberg 		ret = fixup_sc_false_positive(smp);
212119c5ce9cSJohan Hedberg 		if (ret)
212219c5ce9cSJohan Hedberg 			return ret;
212319c5ce9cSJohan Hedberg 	}
212419c5ce9cSJohan Hedberg 
2125b28b4943SJohan Hedberg 	if (conn->hcon->out) {
2126943a732aSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
2127943a732aSJohan Hedberg 			     smp->prnd);
2128b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
2129b28b4943SJohan Hedberg 		return 0;
2130b28b4943SJohan Hedberg 	}
2131b28b4943SJohan Hedberg 
2132b28b4943SJohan Hedberg 	if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
21331cc61144SJohan Hedberg 		return smp_confirm(smp);
2134983f9814SMarcel Holtmann 
21354a74d658SJohan Hedberg 	set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
2136da85e5e5SVinicius Costa Gomes 
2137da85e5e5SVinicius Costa Gomes 	return 0;
213888ba43b6SAnderson Briglia }
213988ba43b6SAnderson Briglia 
smp_cmd_pairing_random(struct l2cap_conn * conn,struct sk_buff * skb)2140da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
214188ba43b6SAnderson Briglia {
21425d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
21435d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
2144191dc7feSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
2145eed467b5SHoward Chung 	u8 *pkax, *pkbx, *na, *nb, confirm_hint;
2146191dc7feSJohan Hedberg 	u32 passkey;
2147191dc7feSJohan Hedberg 	int err;
21487d24ddccSAnderson Briglia 
21492e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hcon->hdev, "conn %p", conn);
21507d24ddccSAnderson Briglia 
2151c46b98beSJohan Hedberg 	if (skb->len < sizeof(smp->rrnd))
215238e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2153c46b98beSJohan Hedberg 
2154943a732aSJohan Hedberg 	memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd));
21558aab4757SVinicius Costa Gomes 	skb_pull(skb, sizeof(smp->rrnd));
215688ba43b6SAnderson Briglia 
2157191dc7feSJohan Hedberg 	if (!test_bit(SMP_FLAG_SC, &smp->flags))
2158861580a9SJohan Hedberg 		return smp_random(smp);
2159191dc7feSJohan Hedberg 
2160580039e8SJohan Hedberg 	if (hcon->out) {
2161580039e8SJohan Hedberg 		pkax = smp->local_pk;
2162580039e8SJohan Hedberg 		pkbx = smp->remote_pk;
2163580039e8SJohan Hedberg 		na   = smp->prnd;
2164580039e8SJohan Hedberg 		nb   = smp->rrnd;
2165580039e8SJohan Hedberg 	} else {
2166580039e8SJohan Hedberg 		pkax = smp->remote_pk;
2167580039e8SJohan Hedberg 		pkbx = smp->local_pk;
2168580039e8SJohan Hedberg 		na   = smp->rrnd;
2169580039e8SJohan Hedberg 		nb   = smp->prnd;
2170580039e8SJohan Hedberg 	}
2171580039e8SJohan Hedberg 
2172a29b0733SJohan Hedberg 	if (smp->method == REQ_OOB) {
2173a29b0733SJohan Hedberg 		if (!hcon->out)
2174a29b0733SJohan Hedberg 			smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM,
2175a29b0733SJohan Hedberg 				     sizeof(smp->prnd), smp->prnd);
2176a29b0733SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
2177a29b0733SJohan Hedberg 		goto mackey_and_ltk;
2178a29b0733SJohan Hedberg 	}
2179a29b0733SJohan Hedberg 
218038606f14SJohan Hedberg 	/* Passkey entry has special treatment */
218138606f14SJohan Hedberg 	if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY)
218238606f14SJohan Hedberg 		return sc_passkey_round(smp, SMP_CMD_PAIRING_RANDOM);
218338606f14SJohan Hedberg 
2184191dc7feSJohan Hedberg 	if (hcon->out) {
2185191dc7feSJohan Hedberg 		u8 cfm[16];
2186191dc7feSJohan Hedberg 
2187191dc7feSJohan Hedberg 		err = smp_f4(smp->tfm_cmac, smp->remote_pk, smp->local_pk,
2188191dc7feSJohan Hedberg 			     smp->rrnd, 0, cfm);
2189191dc7feSJohan Hedberg 		if (err)
2190191dc7feSJohan Hedberg 			return SMP_UNSPECIFIED;
2191191dc7feSJohan Hedberg 
2192329d8230SJason A. Donenfeld 		if (crypto_memneq(smp->pcnf, cfm, 16))
2193191dc7feSJohan Hedberg 			return SMP_CONFIRM_FAILED;
2194191dc7feSJohan Hedberg 	} else {
2195191dc7feSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
2196191dc7feSJohan Hedberg 			     smp->prnd);
2197191dc7feSJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
2198cee5f20fSHoward Chung 
2199cee5f20fSHoward Chung 		/* Only Just-Works pairing requires extra checks */
2200cee5f20fSHoward Chung 		if (smp->method != JUST_WORKS)
2201cee5f20fSHoward Chung 			goto mackey_and_ltk;
2202cee5f20fSHoward Chung 
2203cee5f20fSHoward Chung 		/* If there already exists long term key in local host, leave
2204cee5f20fSHoward Chung 		 * the decision to user space since the remote device could
2205cee5f20fSHoward Chung 		 * be legitimate or malicious.
2206cee5f20fSHoward Chung 		 */
2207cee5f20fSHoward Chung 		if (hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
2208cee5f20fSHoward Chung 				 hcon->role)) {
2209eed467b5SHoward Chung 			/* Set passkey to 0. The value can be any number since
2210eed467b5SHoward Chung 			 * it'll be ignored anyway.
2211eed467b5SHoward Chung 			 */
2212eed467b5SHoward Chung 			passkey = 0;
2213eed467b5SHoward Chung 			confirm_hint = 1;
2214eed467b5SHoward Chung 			goto confirm;
2215cee5f20fSHoward Chung 		}
2216191dc7feSJohan Hedberg 	}
2217191dc7feSJohan Hedberg 
2218a29b0733SJohan Hedberg mackey_and_ltk:
2219760b018bSJohan Hedberg 	/* Generate MacKey and LTK */
2220760b018bSJohan Hedberg 	err = sc_mackey_and_ltk(smp, smp->mackey, smp->tk);
2221760b018bSJohan Hedberg 	if (err)
2222760b018bSJohan Hedberg 		return SMP_UNSPECIFIED;
2223760b018bSJohan Hedberg 
2224ffee202aSSonny Sasaka 	if (smp->method == REQ_OOB) {
2225dddd3059SJohan Hedberg 		if (hcon->out) {
222638606f14SJohan Hedberg 			sc_dhkey_check(smp);
2227dddd3059SJohan Hedberg 			SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
2228dddd3059SJohan Hedberg 		}
2229dddd3059SJohan Hedberg 		return 0;
2230dddd3059SJohan Hedberg 	}
2231dddd3059SJohan Hedberg 
223238606f14SJohan Hedberg 	err = smp_g2(smp->tfm_cmac, pkax, pkbx, na, nb, &passkey);
2233191dc7feSJohan Hedberg 	if (err)
2234191dc7feSJohan Hedberg 		return SMP_UNSPECIFIED;
2235191dc7feSJohan Hedberg 
2236eed467b5SHoward Chung 	confirm_hint = 0;
2237eed467b5SHoward Chung 
2238eed467b5SHoward Chung confirm:
2239ffee202aSSonny Sasaka 	if (smp->method == JUST_WORKS)
2240ffee202aSSonny Sasaka 		confirm_hint = 1;
2241ffee202aSSonny Sasaka 
224238606f14SJohan Hedberg 	err = mgmt_user_confirm_request(hcon->hdev, &hcon->dst, hcon->type,
2243eed467b5SHoward Chung 					hcon->dst_type, passkey, confirm_hint);
224438606f14SJohan Hedberg 	if (err)
224538606f14SJohan Hedberg 		return SMP_UNSPECIFIED;
224638606f14SJohan Hedberg 
224738606f14SJohan Hedberg 	set_bit(SMP_FLAG_WAIT_USER, &smp->flags);
224838606f14SJohan Hedberg 
2249191dc7feSJohan Hedberg 	return 0;
225088ba43b6SAnderson Briglia }
225188ba43b6SAnderson Briglia 
smp_ltk_encrypt(struct l2cap_conn * conn,u8 sec_level)2252f81cd823SMarcel Holtmann static bool smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
2253988c5997SVinicius Costa Gomes {
2254c9839a11SVinicius Costa Gomes 	struct smp_ltk *key;
2255988c5997SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
2256988c5997SVinicius Costa Gomes 
2257f3a73d97SJohan Hedberg 	key = hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, hcon->role);
2258988c5997SVinicius Costa Gomes 	if (!key)
2259f81cd823SMarcel Holtmann 		return false;
2260988c5997SVinicius Costa Gomes 
2261a6f7833cSJohan Hedberg 	if (smp_ltk_sec_level(key) < sec_level)
2262f81cd823SMarcel Holtmann 		return false;
22634dab7864SJohan Hedberg 
226451a8efd7SJohan Hedberg 	if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
2265f81cd823SMarcel Holtmann 		return true;
2266988c5997SVinicius Costa Gomes 
22678b76ce34SJohan Hedberg 	hci_le_start_enc(hcon, key->ediv, key->rand, key->val, key->enc_size);
2268c9839a11SVinicius Costa Gomes 	hcon->enc_key_size = key->enc_size;
2269988c5997SVinicius Costa Gomes 
2270fad646e1SArchie Pusaka 	/* We never store STKs for initiator role, so clear this flag */
2271fe59a05fSJohan Hedberg 	clear_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags);
2272fe59a05fSJohan Hedberg 
2273f81cd823SMarcel Holtmann 	return true;
2274988c5997SVinicius Costa Gomes }
2275f1560463SMarcel Holtmann 
smp_sufficient_security(struct hci_conn * hcon,u8 sec_level,enum smp_key_pref key_pref)227635dc6f83SJohan Hedberg bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level,
227735dc6f83SJohan Hedberg 			     enum smp_key_pref key_pref)
2278854f4727SJohan Hedberg {
2279854f4727SJohan Hedberg 	if (sec_level == BT_SECURITY_LOW)
2280854f4727SJohan Hedberg 		return true;
2281854f4727SJohan Hedberg 
228235dc6f83SJohan Hedberg 	/* If we're encrypted with an STK but the caller prefers using
228335dc6f83SJohan Hedberg 	 * LTK claim insufficient security. This way we allow the
228435dc6f83SJohan Hedberg 	 * connection to be re-encrypted with an LTK, even if the LTK
228535dc6f83SJohan Hedberg 	 * provides the same level of security. Only exception is if we
228635dc6f83SJohan Hedberg 	 * don't have an LTK (e.g. because of key distribution bits).
22879ab65d60SJohan Hedberg 	 */
228835dc6f83SJohan Hedberg 	if (key_pref == SMP_USE_LTK &&
228935dc6f83SJohan Hedberg 	    test_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags) &&
2290f3a73d97SJohan Hedberg 	    hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, hcon->role))
22919ab65d60SJohan Hedberg 		return false;
22929ab65d60SJohan Hedberg 
2293854f4727SJohan Hedberg 	if (hcon->sec_level >= sec_level)
2294854f4727SJohan Hedberg 		return true;
2295854f4727SJohan Hedberg 
2296854f4727SJohan Hedberg 	return false;
2297854f4727SJohan Hedberg }
2298854f4727SJohan Hedberg 
smp_cmd_security_req(struct l2cap_conn * conn,struct sk_buff * skb)2299da85e5e5SVinicius Costa Gomes static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
230088ba43b6SAnderson Briglia {
230188ba43b6SAnderson Briglia 	struct smp_cmd_security_req *rp = (void *) skb->data;
230288ba43b6SAnderson Briglia 	struct smp_cmd_pairing cp;
2303f1cb9af5SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
23040edb14deSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
23058aab4757SVinicius Costa Gomes 	struct smp_chan *smp;
2306c05b9339SJohan Hedberg 	u8 sec_level, auth;
230788ba43b6SAnderson Briglia 
23082e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "conn %p", conn);
230988ba43b6SAnderson Briglia 
2310c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rp))
231138e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2312c46b98beSJohan Hedberg 
231340bef302SJohan Hedberg 	if (hcon->role != HCI_ROLE_MASTER)
231486ca9eacSJohan Hedberg 		return SMP_CMD_NOTSUPP;
231586ca9eacSJohan Hedberg 
23160edb14deSJohan Hedberg 	auth = rp->auth_req & AUTH_REQ_MASK(hdev);
2317c05b9339SJohan Hedberg 
2318d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SC_ONLY) && !(auth & SMP_AUTH_SC))
2319903b71c7SJohan Hedberg 		return SMP_AUTH_REQUIREMENTS;
2320903b71c7SJohan Hedberg 
23215be5e275SJohan Hedberg 	if (hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
23221afc2a1aSJohan Hedberg 		sec_level = BT_SECURITY_MEDIUM;
23231afc2a1aSJohan Hedberg 	else
2324c05b9339SJohan Hedberg 		sec_level = authreq_to_seclevel(auth);
23251afc2a1aSJohan Hedberg 
232664e759f5SSzymon Janc 	if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK)) {
232764e759f5SSzymon Janc 		/* If link is already encrypted with sufficient security we
232864e759f5SSzymon Janc 		 * still need refresh encryption as per Core Spec 5.0 Vol 3,
232964e759f5SSzymon Janc 		 * Part H 2.4.6
233064e759f5SSzymon Janc 		 */
233164e759f5SSzymon Janc 		smp_ltk_encrypt(conn, hcon->sec_level);
2332854f4727SJohan Hedberg 		return 0;
233364e759f5SSzymon Janc 	}
2334854f4727SJohan Hedberg 
2335c7262e71SJohan Hedberg 	if (sec_level > hcon->pending_sec_level)
2336c7262e71SJohan Hedberg 		hcon->pending_sec_level = sec_level;
2337feb45eb5SVinicius Costa Gomes 
23384dab7864SJohan Hedberg 	if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
2339988c5997SVinicius Costa Gomes 		return 0;
2340988c5997SVinicius Costa Gomes 
23418aab4757SVinicius Costa Gomes 	smp = smp_chan_create(conn);
2342c29d2444SJohan Hedberg 	if (!smp)
2343c29d2444SJohan Hedberg 		return SMP_UNSPECIFIED;
2344d26a2345SVinicius Costa Gomes 
2345d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BONDABLE) &&
2346c05b9339SJohan Hedberg 	    (auth & SMP_AUTH_BONDING))
2347616d55beSJohan Hedberg 		return SMP_PAIRING_NOTSUPP;
2348616d55beSJohan Hedberg 
234988ba43b6SAnderson Briglia 	skb_pull(skb, sizeof(*rp));
235088ba43b6SAnderson Briglia 
2351da85e5e5SVinicius Costa Gomes 	memset(&cp, 0, sizeof(cp));
2352c05b9339SJohan Hedberg 	build_pairing_cmd(conn, &cp, NULL, auth);
235388ba43b6SAnderson Briglia 
23541c1def09SVinicius Costa Gomes 	smp->preq[0] = SMP_CMD_PAIRING_REQ;
23551c1def09SVinicius Costa Gomes 	memcpy(&smp->preq[1], &cp, sizeof(cp));
2356f01ead31SAnderson Briglia 
235788ba43b6SAnderson Briglia 	smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
2358b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP);
2359f1cb9af5SVinicius Costa Gomes 
2360da85e5e5SVinicius Costa Gomes 	return 0;
236188ba43b6SAnderson Briglia }
236288ba43b6SAnderson Briglia 
smp_conn_security(struct hci_conn * hcon,__u8 sec_level)2363cc110922SVinicius Costa Gomes int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
2364eb492e01SAnderson Briglia {
2365cc110922SVinicius Costa Gomes 	struct l2cap_conn *conn = hcon->l2cap_data;
2366c68b7f12SJohan Hedberg 	struct l2cap_chan *chan;
23670a66cf20SJohan Hedberg 	struct smp_chan *smp;
23682b64d153SBrian Gix 	__u8 authreq;
2369fc75cc86SJohan Hedberg 	int ret;
2370eb492e01SAnderson Briglia 
23712e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hcon->hdev, "conn %p hcon %p level 0x%2.2x", conn, hcon,
23722e1614f7SLuiz Augusto von Dentz 		   sec_level);
23733a0259bbSVinicius Costa Gomes 
23740a66cf20SJohan Hedberg 	/* This may be NULL if there's an unexpected disconnection */
23750a66cf20SJohan Hedberg 	if (!conn)
23760a66cf20SJohan Hedberg 		return 1;
23770a66cf20SJohan Hedberg 
2378d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hcon->hdev, HCI_LE_ENABLED))
23792e65c9d2SAndre Guedes 		return 1;
23802e65c9d2SAndre Guedes 
238135dc6f83SJohan Hedberg 	if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK))
2382f1cb9af5SVinicius Costa Gomes 		return 1;
2383f1cb9af5SVinicius Costa Gomes 
2384c7262e71SJohan Hedberg 	if (sec_level > hcon->pending_sec_level)
2385c7262e71SJohan Hedberg 		hcon->pending_sec_level = sec_level;
2386c7262e71SJohan Hedberg 
238740bef302SJohan Hedberg 	if (hcon->role == HCI_ROLE_MASTER)
2388c7262e71SJohan Hedberg 		if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
2389c7262e71SJohan Hedberg 			return 0;
2390d26a2345SVinicius Costa Gomes 
2391d8949aadSJohan Hedberg 	chan = conn->smp;
2392d8949aadSJohan Hedberg 	if (!chan) {
23932064ee33SMarcel Holtmann 		bt_dev_err(hcon->hdev, "security requested but not available");
2394d8949aadSJohan Hedberg 		return 1;
2395d8949aadSJohan Hedberg 	}
2396d8949aadSJohan Hedberg 
2397fc75cc86SJohan Hedberg 	l2cap_chan_lock(chan);
2398fc75cc86SJohan Hedberg 
2399fc75cc86SJohan Hedberg 	/* If SMP is already in progress ignore this request */
2400fc75cc86SJohan Hedberg 	if (chan->data) {
2401fc75cc86SJohan Hedberg 		ret = 0;
2402fc75cc86SJohan Hedberg 		goto unlock;
2403fc75cc86SJohan Hedberg 	}
2404d26a2345SVinicius Costa Gomes 
24058aab4757SVinicius Costa Gomes 	smp = smp_chan_create(conn);
2406fc75cc86SJohan Hedberg 	if (!smp) {
2407fc75cc86SJohan Hedberg 		ret = 1;
2408fc75cc86SJohan Hedberg 		goto unlock;
2409fc75cc86SJohan Hedberg 	}
24102b64d153SBrian Gix 
24112b64d153SBrian Gix 	authreq = seclevel_to_authreq(sec_level);
2412d26a2345SVinicius Costa Gomes 
2413a62da6f1SJohan Hedberg 	if (hci_dev_test_flag(hcon->hdev, HCI_SC_ENABLED)) {
2414d2eb9e10SJohan Hedberg 		authreq |= SMP_AUTH_SC;
2415a62da6f1SJohan Hedberg 		if (hci_dev_test_flag(hcon->hdev, HCI_SSP_ENABLED))
2416a62da6f1SJohan Hedberg 			authreq |= SMP_AUTH_CT2;
2417a62da6f1SJohan Hedberg 	}
2418d2eb9e10SJohan Hedberg 
2419c2aa30dbSArchie Pusaka 	/* Don't attempt to set MITM if setting is overridden by debugfs
2420c2aa30dbSArchie Pusaka 	 * Needed to pass certification test SM/MAS/PKE/BV-01-C
2421c2aa30dbSArchie Pusaka 	 */
2422c2aa30dbSArchie Pusaka 	if (!hci_dev_test_flag(hcon->hdev, HCI_FORCE_NO_MITM)) {
242379897d20SJohan Hedberg 		/* Require MITM if IO Capability allows or the security level
242479897d20SJohan Hedberg 		 * requires it.
24252e233644SJohan Hedberg 		 */
242679897d20SJohan Hedberg 		if (hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT ||
2427c7262e71SJohan Hedberg 		    hcon->pending_sec_level > BT_SECURITY_MEDIUM)
24282e233644SJohan Hedberg 			authreq |= SMP_AUTH_MITM;
2429c2aa30dbSArchie Pusaka 	}
24302e233644SJohan Hedberg 
243140bef302SJohan Hedberg 	if (hcon->role == HCI_ROLE_MASTER) {
2432d26a2345SVinicius Costa Gomes 		struct smp_cmd_pairing cp;
2433f01ead31SAnderson Briglia 
24342b64d153SBrian Gix 		build_pairing_cmd(conn, &cp, NULL, authreq);
24351c1def09SVinicius Costa Gomes 		smp->preq[0] = SMP_CMD_PAIRING_REQ;
24361c1def09SVinicius Costa Gomes 		memcpy(&smp->preq[1], &cp, sizeof(cp));
2437f01ead31SAnderson Briglia 
2438eb492e01SAnderson Briglia 		smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
2439b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP);
2440eb492e01SAnderson Briglia 	} else {
2441eb492e01SAnderson Briglia 		struct smp_cmd_security_req cp;
24422b64d153SBrian Gix 		cp.auth_req = authreq;
2443eb492e01SAnderson Briglia 		smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
2444b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_REQ);
2445eb492e01SAnderson Briglia 	}
2446eb492e01SAnderson Briglia 
24474a74d658SJohan Hedberg 	set_bit(SMP_FLAG_INITIATOR, &smp->flags);
2448fc75cc86SJohan Hedberg 	ret = 0;
2449edca792cSJohan Hedberg 
2450fc75cc86SJohan Hedberg unlock:
2451fc75cc86SJohan Hedberg 	l2cap_chan_unlock(chan);
2452fc75cc86SJohan Hedberg 	return ret;
2453eb492e01SAnderson Briglia }
2454eb492e01SAnderson Briglia 
smp_cancel_and_remove_pairing(struct hci_dev * hdev,bdaddr_t * bdaddr,u8 addr_type)2455cb28c306SMatias Karhumaa int smp_cancel_and_remove_pairing(struct hci_dev *hdev, bdaddr_t *bdaddr,
2456cb28c306SMatias Karhumaa 				  u8 addr_type)
2457c81d555aSJohan Hedberg {
2458cb28c306SMatias Karhumaa 	struct hci_conn *hcon;
2459cb28c306SMatias Karhumaa 	struct l2cap_conn *conn;
2460c81d555aSJohan Hedberg 	struct l2cap_chan *chan;
2461c81d555aSJohan Hedberg 	struct smp_chan *smp;
2462cb28c306SMatias Karhumaa 	int err;
2463c81d555aSJohan Hedberg 
2464cb28c306SMatias Karhumaa 	err = hci_remove_ltk(hdev, bdaddr, addr_type);
2465cb28c306SMatias Karhumaa 	hci_remove_irk(hdev, bdaddr, addr_type);
2466cb28c306SMatias Karhumaa 
2467cb28c306SMatias Karhumaa 	hcon = hci_conn_hash_lookup_le(hdev, bdaddr, addr_type);
2468cb28c306SMatias Karhumaa 	if (!hcon)
2469cb28c306SMatias Karhumaa 		goto done;
2470cb28c306SMatias Karhumaa 
2471cb28c306SMatias Karhumaa 	conn = hcon->l2cap_data;
2472c81d555aSJohan Hedberg 	if (!conn)
2473cb28c306SMatias Karhumaa 		goto done;
2474c81d555aSJohan Hedberg 
2475c81d555aSJohan Hedberg 	chan = conn->smp;
2476c81d555aSJohan Hedberg 	if (!chan)
2477cb28c306SMatias Karhumaa 		goto done;
2478c81d555aSJohan Hedberg 
2479c81d555aSJohan Hedberg 	l2cap_chan_lock(chan);
2480c81d555aSJohan Hedberg 
2481c81d555aSJohan Hedberg 	smp = chan->data;
2482c81d555aSJohan Hedberg 	if (smp) {
2483cb28c306SMatias Karhumaa 		/* Set keys to NULL to make sure smp_failure() does not try to
2484cb28c306SMatias Karhumaa 		 * remove and free already invalidated rcu list entries. */
2485cb28c306SMatias Karhumaa 		smp->ltk = NULL;
2486fad646e1SArchie Pusaka 		smp->responder_ltk = NULL;
2487cb28c306SMatias Karhumaa 		smp->remote_irk = NULL;
2488cb28c306SMatias Karhumaa 
2489c81d555aSJohan Hedberg 		if (test_bit(SMP_FLAG_COMPLETE, &smp->flags))
2490c81d555aSJohan Hedberg 			smp_failure(conn, 0);
2491c81d555aSJohan Hedberg 		else
2492c81d555aSJohan Hedberg 			smp_failure(conn, SMP_UNSPECIFIED);
2493cb28c306SMatias Karhumaa 		err = 0;
2494c81d555aSJohan Hedberg 	}
2495c81d555aSJohan Hedberg 
2496c81d555aSJohan Hedberg 	l2cap_chan_unlock(chan);
2497cb28c306SMatias Karhumaa 
2498cb28c306SMatias Karhumaa done:
2499cb28c306SMatias Karhumaa 	return err;
2500c81d555aSJohan Hedberg }
2501c81d555aSJohan Hedberg 
smp_cmd_encrypt_info(struct l2cap_conn * conn,struct sk_buff * skb)25027034b911SVinicius Costa Gomes static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
25037034b911SVinicius Costa Gomes {
250416b90839SVinicius Costa Gomes 	struct smp_cmd_encrypt_info *rp = (void *) skb->data;
25055d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
25065d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
250716b90839SVinicius Costa Gomes 
25082e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(conn->hcon->hdev, "conn %p", conn);
2509c46b98beSJohan Hedberg 
2510c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rp))
251138e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2512c46b98beSJohan Hedberg 
2513600a8749SAlain Michaud 	/* Pairing is aborted if any blocked keys are distributed */
2514600a8749SAlain Michaud 	if (hci_is_blocked_key(conn->hcon->hdev, HCI_BLOCKED_KEY_TYPE_LTK,
2515600a8749SAlain Michaud 			       rp->ltk)) {
2516600a8749SAlain Michaud 		bt_dev_warn_ratelimited(conn->hcon->hdev,
2517600a8749SAlain Michaud 					"LTK blocked for %pMR",
2518600a8749SAlain Michaud 					&conn->hcon->dst);
2519600a8749SAlain Michaud 		return SMP_INVALID_PARAMS;
2520600a8749SAlain Michaud 	}
2521600a8749SAlain Michaud 
2522fad646e1SArchie Pusaka 	SMP_ALLOW_CMD(smp, SMP_CMD_INITIATOR_IDENT);
25236131ddc8SJohan Hedberg 
252416b90839SVinicius Costa Gomes 	skb_pull(skb, sizeof(*rp));
252516b90839SVinicius Costa Gomes 
25261c1def09SVinicius Costa Gomes 	memcpy(smp->tk, rp->ltk, sizeof(smp->tk));
252716b90839SVinicius Costa Gomes 
25287034b911SVinicius Costa Gomes 	return 0;
25297034b911SVinicius Costa Gomes }
25307034b911SVinicius Costa Gomes 
smp_cmd_initiator_ident(struct l2cap_conn * conn,struct sk_buff * skb)2531fad646e1SArchie Pusaka static int smp_cmd_initiator_ident(struct l2cap_conn *conn, struct sk_buff *skb)
25327034b911SVinicius Costa Gomes {
2533fad646e1SArchie Pusaka 	struct smp_cmd_initiator_ident *rp = (void *)skb->data;
25345d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
25355d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
2536c9839a11SVinicius Costa Gomes 	struct hci_dev *hdev = conn->hcon->hdev;
2537c9839a11SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
253823d0e128SJohan Hedberg 	struct smp_ltk *ltk;
2539c9839a11SVinicius Costa Gomes 	u8 authenticated;
25407034b911SVinicius Costa Gomes 
25412e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "conn %p", conn);
2542c46b98beSJohan Hedberg 
2543c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rp))
254438e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2545c46b98beSJohan Hedberg 
25469747a9f3SJohan Hedberg 	/* Mark the information as received */
25479747a9f3SJohan Hedberg 	smp->remote_key_dist &= ~SMP_DIST_ENC_KEY;
25489747a9f3SJohan Hedberg 
2549b28b4943SJohan Hedberg 	if (smp->remote_key_dist & SMP_DIST_ID_KEY)
2550b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO);
2551196332f5SJohan Hedberg 	else if (smp->remote_key_dist & SMP_DIST_SIGN)
2552196332f5SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO);
2553b28b4943SJohan Hedberg 
255416b90839SVinicius Costa Gomes 	skb_pull(skb, sizeof(*rp));
255516b90839SVinicius Costa Gomes 
2556ce39fb4eSMarcel Holtmann 	authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
25572ceba539SJohan Hedberg 	ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, SMP_LTK,
2558ce39fb4eSMarcel Holtmann 			  authenticated, smp->tk, smp->enc_key_size,
255904124681SGustavo F. Padovan 			  rp->ediv, rp->rand);
256023d0e128SJohan Hedberg 	smp->ltk = ltk;
2561c6e81e9aSJohan Hedberg 	if (!(smp->remote_key_dist & KEY_DIST_MASK))
2562d6268e86SJohan Hedberg 		smp_distribute_keys(smp);
25637034b911SVinicius Costa Gomes 
25647034b911SVinicius Costa Gomes 	return 0;
25657034b911SVinicius Costa Gomes }
25667034b911SVinicius Costa Gomes 
smp_cmd_ident_info(struct l2cap_conn * conn,struct sk_buff * skb)2567fd349c02SJohan Hedberg static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
2568fd349c02SJohan Hedberg {
2569fd349c02SJohan Hedberg 	struct smp_cmd_ident_info *info = (void *) skb->data;
25705d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
25715d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
2572fd349c02SJohan Hedberg 
25732e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(conn->hcon->hdev, "");
2574fd349c02SJohan Hedberg 
2575fd349c02SJohan Hedberg 	if (skb->len < sizeof(*info))
257638e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2577fd349c02SJohan Hedberg 
2578600a8749SAlain Michaud 	/* Pairing is aborted if any blocked keys are distributed */
2579600a8749SAlain Michaud 	if (hci_is_blocked_key(conn->hcon->hdev, HCI_BLOCKED_KEY_TYPE_IRK,
2580600a8749SAlain Michaud 			       info->irk)) {
2581600a8749SAlain Michaud 		bt_dev_warn_ratelimited(conn->hcon->hdev,
2582600a8749SAlain Michaud 					"Identity key blocked for %pMR",
2583600a8749SAlain Michaud 					&conn->hcon->dst);
2584600a8749SAlain Michaud 		return SMP_INVALID_PARAMS;
2585600a8749SAlain Michaud 	}
2586600a8749SAlain Michaud 
2587b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_ADDR_INFO);
25886131ddc8SJohan Hedberg 
2589fd349c02SJohan Hedberg 	skb_pull(skb, sizeof(*info));
2590fd349c02SJohan Hedberg 
2591fd349c02SJohan Hedberg 	memcpy(smp->irk, info->irk, 16);
2592fd349c02SJohan Hedberg 
2593fd349c02SJohan Hedberg 	return 0;
2594fd349c02SJohan Hedberg }
2595fd349c02SJohan Hedberg 
smp_cmd_ident_addr_info(struct l2cap_conn * conn,struct sk_buff * skb)2596fd349c02SJohan Hedberg static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
2597fd349c02SJohan Hedberg 				   struct sk_buff *skb)
2598fd349c02SJohan Hedberg {
2599fd349c02SJohan Hedberg 	struct smp_cmd_ident_addr_info *info = (void *) skb->data;
26005d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
26015d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
2602fd349c02SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
2603fd349c02SJohan Hedberg 	bdaddr_t rpa;
2604fd349c02SJohan Hedberg 
26052e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hcon->hdev, "");
2606fd349c02SJohan Hedberg 
2607fd349c02SJohan Hedberg 	if (skb->len < sizeof(*info))
260838e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2609fd349c02SJohan Hedberg 
26109747a9f3SJohan Hedberg 	/* Mark the information as received */
26119747a9f3SJohan Hedberg 	smp->remote_key_dist &= ~SMP_DIST_ID_KEY;
26129747a9f3SJohan Hedberg 
2613b28b4943SJohan Hedberg 	if (smp->remote_key_dist & SMP_DIST_SIGN)
2614b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO);
2615b28b4943SJohan Hedberg 
2616fd349c02SJohan Hedberg 	skb_pull(skb, sizeof(*info));
2617fd349c02SJohan Hedberg 
2618a9a58f86SJohan Hedberg 	/* Strictly speaking the Core Specification (4.1) allows sending
2619a9a58f86SJohan Hedberg 	 * an empty address which would force us to rely on just the IRK
2620a9a58f86SJohan Hedberg 	 * as "identity information". However, since such
2621a9a58f86SJohan Hedberg 	 * implementations are not known of and in order to not over
2622a9a58f86SJohan Hedberg 	 * complicate our implementation, simply pretend that we never
2623a9a58f86SJohan Hedberg 	 * received an IRK for such a device.
2624e12af489SJohan Hedberg 	 *
2625e12af489SJohan Hedberg 	 * The Identity Address must also be a Static Random or Public
2626e12af489SJohan Hedberg 	 * Address, which hci_is_identity_address() checks for.
2627a9a58f86SJohan Hedberg 	 */
2628e12af489SJohan Hedberg 	if (!bacmp(&info->bdaddr, BDADDR_ANY) ||
2629e12af489SJohan Hedberg 	    !hci_is_identity_address(&info->bdaddr, info->addr_type)) {
26302064ee33SMarcel Holtmann 		bt_dev_err(hcon->hdev, "ignoring IRK with no identity address");
263131dd624eSJohan Hedberg 		goto distribute;
2632a9a58f86SJohan Hedberg 	}
2633a9a58f86SJohan Hedberg 
26341d87b88bSSzymon Janc 	/* Drop IRK if peer is using identity address during pairing but is
26351d87b88bSSzymon Janc 	 * providing different address as identity information.
26361d87b88bSSzymon Janc 	 *
26371d87b88bSSzymon Janc 	 * Microsoft Surface Precision Mouse is known to have this bug.
26381d87b88bSSzymon Janc 	 */
26391d87b88bSSzymon Janc 	if (hci_is_identity_address(&hcon->dst, hcon->dst_type) &&
26401d87b88bSSzymon Janc 	    (bacmp(&info->bdaddr, &hcon->dst) ||
26411d87b88bSSzymon Janc 	     info->addr_type != hcon->dst_type)) {
26421d87b88bSSzymon Janc 		bt_dev_err(hcon->hdev,
26431d87b88bSSzymon Janc 			   "ignoring IRK with invalid identity address");
26441d87b88bSSzymon Janc 		goto distribute;
26451d87b88bSSzymon Janc 	}
26461d87b88bSSzymon Janc 
2647fd349c02SJohan Hedberg 	bacpy(&smp->id_addr, &info->bdaddr);
2648fd349c02SJohan Hedberg 	smp->id_addr_type = info->addr_type;
2649fd349c02SJohan Hedberg 
2650fd349c02SJohan Hedberg 	if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type))
2651fd349c02SJohan Hedberg 		bacpy(&rpa, &hcon->dst);
2652fd349c02SJohan Hedberg 	else
2653fd349c02SJohan Hedberg 		bacpy(&rpa, BDADDR_ANY);
2654fd349c02SJohan Hedberg 
265523d0e128SJohan Hedberg 	smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
265623d0e128SJohan Hedberg 				      smp->id_addr_type, smp->irk, &rpa);
2657fd349c02SJohan Hedberg 
265831dd624eSJohan Hedberg distribute:
2659c6e81e9aSJohan Hedberg 	if (!(smp->remote_key_dist & KEY_DIST_MASK))
2660d6268e86SJohan Hedberg 		smp_distribute_keys(smp);
2661fd349c02SJohan Hedberg 
2662fd349c02SJohan Hedberg 	return 0;
2663fd349c02SJohan Hedberg }
2664fd349c02SJohan Hedberg 
smp_cmd_sign_info(struct l2cap_conn * conn,struct sk_buff * skb)26657ee4ea36SMarcel Holtmann static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)
26667ee4ea36SMarcel Holtmann {
26677ee4ea36SMarcel Holtmann 	struct smp_cmd_sign_info *rp = (void *) skb->data;
26685d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
26695d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
26707ee4ea36SMarcel Holtmann 	struct smp_csrk *csrk;
26717ee4ea36SMarcel Holtmann 
26722e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(conn->hcon->hdev, "conn %p", conn);
26737ee4ea36SMarcel Holtmann 
26747ee4ea36SMarcel Holtmann 	if (skb->len < sizeof(*rp))
267538e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
26767ee4ea36SMarcel Holtmann 
26777ee4ea36SMarcel Holtmann 	/* Mark the information as received */
26787ee4ea36SMarcel Holtmann 	smp->remote_key_dist &= ~SMP_DIST_SIGN;
26797ee4ea36SMarcel Holtmann 
26807ee4ea36SMarcel Holtmann 	skb_pull(skb, sizeof(*rp));
26817ee4ea36SMarcel Holtmann 
26827ee4ea36SMarcel Holtmann 	csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
26837ee4ea36SMarcel Holtmann 	if (csrk) {
26844cd3928aSJohan Hedberg 		if (conn->hcon->sec_level > BT_SECURITY_MEDIUM)
26854cd3928aSJohan Hedberg 			csrk->type = MGMT_CSRK_REMOTE_AUTHENTICATED;
26864cd3928aSJohan Hedberg 		else
26874cd3928aSJohan Hedberg 			csrk->type = MGMT_CSRK_REMOTE_UNAUTHENTICATED;
26887ee4ea36SMarcel Holtmann 		memcpy(csrk->val, rp->csrk, sizeof(csrk->val));
26897ee4ea36SMarcel Holtmann 	}
26907ee4ea36SMarcel Holtmann 	smp->csrk = csrk;
2691d6268e86SJohan Hedberg 	smp_distribute_keys(smp);
26927ee4ea36SMarcel Holtmann 
26937ee4ea36SMarcel Holtmann 	return 0;
26947ee4ea36SMarcel Holtmann }
26957ee4ea36SMarcel Holtmann 
sc_select_method(struct smp_chan * smp)26965e3d3d9bSJohan Hedberg static u8 sc_select_method(struct smp_chan *smp)
26975e3d3d9bSJohan Hedberg {
26985e3d3d9bSJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
26995e3d3d9bSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
27005e3d3d9bSJohan Hedberg 	struct smp_cmd_pairing *local, *remote;
27015e3d3d9bSJohan Hedberg 	u8 local_mitm, remote_mitm, local_io, remote_io, method;
27025e3d3d9bSJohan Hedberg 
27031a8bab4fSJohan Hedberg 	if (test_bit(SMP_FLAG_REMOTE_OOB, &smp->flags) ||
27041a8bab4fSJohan Hedberg 	    test_bit(SMP_FLAG_LOCAL_OOB, &smp->flags))
2705a29b0733SJohan Hedberg 		return REQ_OOB;
2706a29b0733SJohan Hedberg 
27075e3d3d9bSJohan Hedberg 	/* The preq/prsp contain the raw Pairing Request/Response PDUs
27085e3d3d9bSJohan Hedberg 	 * which are needed as inputs to some crypto functions. To get
27095e3d3d9bSJohan Hedberg 	 * the "struct smp_cmd_pairing" from them we need to skip the
27105e3d3d9bSJohan Hedberg 	 * first byte which contains the opcode.
27115e3d3d9bSJohan Hedberg 	 */
27125e3d3d9bSJohan Hedberg 	if (hcon->out) {
27135e3d3d9bSJohan Hedberg 		local = (void *) &smp->preq[1];
27145e3d3d9bSJohan Hedberg 		remote = (void *) &smp->prsp[1];
27155e3d3d9bSJohan Hedberg 	} else {
27165e3d3d9bSJohan Hedberg 		local = (void *) &smp->prsp[1];
27175e3d3d9bSJohan Hedberg 		remote = (void *) &smp->preq[1];
27185e3d3d9bSJohan Hedberg 	}
27195e3d3d9bSJohan Hedberg 
27205e3d3d9bSJohan Hedberg 	local_io = local->io_capability;
27215e3d3d9bSJohan Hedberg 	remote_io = remote->io_capability;
27225e3d3d9bSJohan Hedberg 
27235e3d3d9bSJohan Hedberg 	local_mitm = (local->auth_req & SMP_AUTH_MITM);
27245e3d3d9bSJohan Hedberg 	remote_mitm = (remote->auth_req & SMP_AUTH_MITM);
27255e3d3d9bSJohan Hedberg 
27265e3d3d9bSJohan Hedberg 	/* If either side wants MITM, look up the method from the table,
27275e3d3d9bSJohan Hedberg 	 * otherwise use JUST WORKS.
27285e3d3d9bSJohan Hedberg 	 */
27295e3d3d9bSJohan Hedberg 	if (local_mitm || remote_mitm)
27305e3d3d9bSJohan Hedberg 		method = get_auth_method(smp, local_io, remote_io);
27315e3d3d9bSJohan Hedberg 	else
27325e3d3d9bSJohan Hedberg 		method = JUST_WORKS;
27335e3d3d9bSJohan Hedberg 
27345e3d3d9bSJohan Hedberg 	/* Don't confirm locally initiated pairing attempts */
27355e3d3d9bSJohan Hedberg 	if (method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR, &smp->flags))
27365e3d3d9bSJohan Hedberg 		method = JUST_WORKS;
27375e3d3d9bSJohan Hedberg 
27385e3d3d9bSJohan Hedberg 	return method;
27395e3d3d9bSJohan Hedberg }
27405e3d3d9bSJohan Hedberg 
smp_cmd_public_key(struct l2cap_conn * conn,struct sk_buff * skb)2741d8f8edbeSJohan Hedberg static int smp_cmd_public_key(struct l2cap_conn *conn, struct sk_buff *skb)
2742d8f8edbeSJohan Hedberg {
2743d8f8edbeSJohan Hedberg 	struct smp_cmd_public_key *key = (void *) skb->data;
2744d8f8edbeSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
2745d8f8edbeSJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
2746d8f8edbeSJohan Hedberg 	struct smp_chan *smp = chan->data;
27475e3d3d9bSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
2748c0153b0bSTudor Ambarus 	struct crypto_kpp *tfm_ecdh;
2749cbbbe3e2SJohan Hedberg 	struct smp_cmd_pairing_confirm cfm;
2750d8f8edbeSJohan Hedberg 	int err;
2751d8f8edbeSJohan Hedberg 
27522e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "conn %p", conn);
2753d8f8edbeSJohan Hedberg 
2754d8f8edbeSJohan Hedberg 	if (skb->len < sizeof(*key))
2755d8f8edbeSJohan Hedberg 		return SMP_INVALID_PARAMS;
2756d8f8edbeSJohan Hedberg 
27576d19628fSLuiz Augusto von Dentz 	/* Check if remote and local public keys are the same and debug key is
27586d19628fSLuiz Augusto von Dentz 	 * not in use.
27596d19628fSLuiz Augusto von Dentz 	 */
27606d19628fSLuiz Augusto von Dentz 	if (!test_bit(SMP_FLAG_DEBUG_KEY, &smp->flags) &&
27616d19628fSLuiz Augusto von Dentz 	    !crypto_memneq(key, smp->local_pk, 64)) {
27626d19628fSLuiz Augusto von Dentz 		bt_dev_err(hdev, "Remote and local public keys are identical");
27636d19628fSLuiz Augusto von Dentz 		return SMP_UNSPECIFIED;
27646d19628fSLuiz Augusto von Dentz 	}
27656d19628fSLuiz Augusto von Dentz 
2766d8f8edbeSJohan Hedberg 	memcpy(smp->remote_pk, key, 64);
2767d8f8edbeSJohan Hedberg 
2768a8ca617cSJohan Hedberg 	if (test_bit(SMP_FLAG_REMOTE_OOB, &smp->flags)) {
2769a8ca617cSJohan Hedberg 		err = smp_f4(smp->tfm_cmac, smp->remote_pk, smp->remote_pk,
2770a8ca617cSJohan Hedberg 			     smp->rr, 0, cfm.confirm_val);
2771a8ca617cSJohan Hedberg 		if (err)
2772a8ca617cSJohan Hedberg 			return SMP_UNSPECIFIED;
2773a8ca617cSJohan Hedberg 
2774329d8230SJason A. Donenfeld 		if (crypto_memneq(cfm.confirm_val, smp->pcnf, 16))
2775a8ca617cSJohan Hedberg 			return SMP_CONFIRM_FAILED;
2776a8ca617cSJohan Hedberg 	}
2777a8ca617cSJohan Hedberg 
2778d8f8edbeSJohan Hedberg 	/* Non-initiating device sends its public key after receiving
2779d8f8edbeSJohan Hedberg 	 * the key from the initiating device.
2780d8f8edbeSJohan Hedberg 	 */
2781d8f8edbeSJohan Hedberg 	if (!hcon->out) {
2782d8f8edbeSJohan Hedberg 		err = sc_send_public_key(smp);
2783d8f8edbeSJohan Hedberg 		if (err)
2784d8f8edbeSJohan Hedberg 			return err;
2785d8f8edbeSJohan Hedberg 	}
2786d8f8edbeSJohan Hedberg 
2787c7a3d57dSJohan Hedberg 	SMP_DBG("Remote Public Key X: %32phN", smp->remote_pk);
2788e091526dSMarcel Holtmann 	SMP_DBG("Remote Public Key Y: %32phN", smp->remote_pk + 32);
2789d8f8edbeSJohan Hedberg 
2790c0153b0bSTudor Ambarus 	/* Compute the shared secret on the same crypto tfm on which the private
2791c0153b0bSTudor Ambarus 	 * key was set/generated.
2792c0153b0bSTudor Ambarus 	 */
2793c0153b0bSTudor Ambarus 	if (test_bit(SMP_FLAG_LOCAL_OOB, &smp->flags)) {
27944ba5175fSMatias Karhumaa 		struct l2cap_chan *hchan = hdev->smp_data;
27954ba5175fSMatias Karhumaa 		struct smp_dev *smp_dev;
27964ba5175fSMatias Karhumaa 
27974ba5175fSMatias Karhumaa 		if (!hchan || !hchan->data)
27984ba5175fSMatias Karhumaa 			return SMP_UNSPECIFIED;
27994ba5175fSMatias Karhumaa 
28004ba5175fSMatias Karhumaa 		smp_dev = hchan->data;
2801c0153b0bSTudor Ambarus 
2802c0153b0bSTudor Ambarus 		tfm_ecdh = smp_dev->tfm_ecdh;
2803c0153b0bSTudor Ambarus 	} else {
2804c0153b0bSTudor Ambarus 		tfm_ecdh = smp->tfm_ecdh;
2805c0153b0bSTudor Ambarus 	}
2806c0153b0bSTudor Ambarus 
2807c0153b0bSTudor Ambarus 	if (compute_ecdh_secret(tfm_ecdh, smp->remote_pk, smp->dhkey))
2808d8f8edbeSJohan Hedberg 		return SMP_UNSPECIFIED;
2809d8f8edbeSJohan Hedberg 
2810c7a3d57dSJohan Hedberg 	SMP_DBG("DHKey %32phN", smp->dhkey);
2811d8f8edbeSJohan Hedberg 
2812d8f8edbeSJohan Hedberg 	set_bit(SMP_FLAG_REMOTE_PK, &smp->flags);
2813d8f8edbeSJohan Hedberg 
28145e3d3d9bSJohan Hedberg 	smp->method = sc_select_method(smp);
28155e3d3d9bSJohan Hedberg 
28162e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "selected method 0x%02x", smp->method);
28175e3d3d9bSJohan Hedberg 
28185e3d3d9bSJohan Hedberg 	/* JUST_WORKS and JUST_CFM result in an unauthenticated key */
28195e3d3d9bSJohan Hedberg 	if (smp->method == JUST_WORKS || smp->method == JUST_CFM)
28205e3d3d9bSJohan Hedberg 		hcon->pending_sec_level = BT_SECURITY_MEDIUM;
28215e3d3d9bSJohan Hedberg 	else
28225e3d3d9bSJohan Hedberg 		hcon->pending_sec_level = BT_SECURITY_FIPS;
28235e3d3d9bSJohan Hedberg 
2824329d8230SJason A. Donenfeld 	if (!crypto_memneq(debug_pk, smp->remote_pk, 64))
2825aeb7d461SJohan Hedberg 		set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags);
2826aeb7d461SJohan Hedberg 
282738606f14SJohan Hedberg 	if (smp->method == DSP_PASSKEY) {
282838606f14SJohan Hedberg 		get_random_bytes(&hcon->passkey_notify,
282938606f14SJohan Hedberg 				 sizeof(hcon->passkey_notify));
283038606f14SJohan Hedberg 		hcon->passkey_notify %= 1000000;
283138606f14SJohan Hedberg 		hcon->passkey_entered = 0;
283238606f14SJohan Hedberg 		smp->passkey_round = 0;
283338606f14SJohan Hedberg 		if (mgmt_user_passkey_notify(hdev, &hcon->dst, hcon->type,
283438606f14SJohan Hedberg 					     hcon->dst_type,
283538606f14SJohan Hedberg 					     hcon->passkey_notify,
283638606f14SJohan Hedberg 					     hcon->passkey_entered))
283738606f14SJohan Hedberg 			return SMP_UNSPECIFIED;
283838606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
283938606f14SJohan Hedberg 		return sc_passkey_round(smp, SMP_CMD_PUBLIC_KEY);
284038606f14SJohan Hedberg 	}
284138606f14SJohan Hedberg 
284294ea7257SJohan Hedberg 	if (smp->method == REQ_OOB) {
2843a29b0733SJohan Hedberg 		if (hcon->out)
2844a29b0733SJohan Hedberg 			smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM,
2845a29b0733SJohan Hedberg 				     sizeof(smp->prnd), smp->prnd);
2846a29b0733SJohan Hedberg 
2847a29b0733SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
2848a29b0733SJohan Hedberg 
2849a29b0733SJohan Hedberg 		return 0;
2850a29b0733SJohan Hedberg 	}
2851a29b0733SJohan Hedberg 
285238606f14SJohan Hedberg 	if (hcon->out)
285338606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
285438606f14SJohan Hedberg 
285538606f14SJohan Hedberg 	if (smp->method == REQ_PASSKEY) {
285638606f14SJohan Hedberg 		if (mgmt_user_passkey_request(hdev, &hcon->dst, hcon->type,
285738606f14SJohan Hedberg 					      hcon->dst_type))
285838606f14SJohan Hedberg 			return SMP_UNSPECIFIED;
285938606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
286038606f14SJohan Hedberg 		set_bit(SMP_FLAG_WAIT_USER, &smp->flags);
286138606f14SJohan Hedberg 		return 0;
286238606f14SJohan Hedberg 	}
286338606f14SJohan Hedberg 
2864cbbbe3e2SJohan Hedberg 	/* The Initiating device waits for the non-initiating device to
2865cbbbe3e2SJohan Hedberg 	 * send the confirm value.
2866cbbbe3e2SJohan Hedberg 	 */
2867cbbbe3e2SJohan Hedberg 	if (conn->hcon->out)
2868cbbbe3e2SJohan Hedberg 		return 0;
2869cbbbe3e2SJohan Hedberg 
2870cbbbe3e2SJohan Hedberg 	err = smp_f4(smp->tfm_cmac, smp->local_pk, smp->remote_pk, smp->prnd,
2871cbbbe3e2SJohan Hedberg 		     0, cfm.confirm_val);
2872cbbbe3e2SJohan Hedberg 	if (err)
2873cbbbe3e2SJohan Hedberg 		return SMP_UNSPECIFIED;
2874cbbbe3e2SJohan Hedberg 
2875cbbbe3e2SJohan Hedberg 	smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cfm), &cfm);
2876cbbbe3e2SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
2877cbbbe3e2SJohan Hedberg 
2878d8f8edbeSJohan Hedberg 	return 0;
2879d8f8edbeSJohan Hedberg }
2880d8f8edbeSJohan Hedberg 
smp_cmd_dhkey_check(struct l2cap_conn * conn,struct sk_buff * skb)28816433a9a2SJohan Hedberg static int smp_cmd_dhkey_check(struct l2cap_conn *conn, struct sk_buff *skb)
28826433a9a2SJohan Hedberg {
28836433a9a2SJohan Hedberg 	struct smp_cmd_dhkey_check *check = (void *) skb->data;
28846433a9a2SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
28856433a9a2SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
28866433a9a2SJohan Hedberg 	struct smp_chan *smp = chan->data;
28876433a9a2SJohan Hedberg 	u8 a[7], b[7], *local_addr, *remote_addr;
28886433a9a2SJohan Hedberg 	u8 io_cap[3], r[16], e[16];
28896433a9a2SJohan Hedberg 	int err;
28906433a9a2SJohan Hedberg 
28912e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hcon->hdev, "conn %p", conn);
28926433a9a2SJohan Hedberg 
28936433a9a2SJohan Hedberg 	if (skb->len < sizeof(*check))
28946433a9a2SJohan Hedberg 		return SMP_INVALID_PARAMS;
28956433a9a2SJohan Hedberg 
28966433a9a2SJohan Hedberg 	memcpy(a, &hcon->init_addr, 6);
28976433a9a2SJohan Hedberg 	memcpy(b, &hcon->resp_addr, 6);
28986433a9a2SJohan Hedberg 	a[6] = hcon->init_addr_type;
28996433a9a2SJohan Hedberg 	b[6] = hcon->resp_addr_type;
29006433a9a2SJohan Hedberg 
29016433a9a2SJohan Hedberg 	if (hcon->out) {
29026433a9a2SJohan Hedberg 		local_addr = a;
29036433a9a2SJohan Hedberg 		remote_addr = b;
29046433a9a2SJohan Hedberg 		memcpy(io_cap, &smp->prsp[1], 3);
29056433a9a2SJohan Hedberg 	} else {
29066433a9a2SJohan Hedberg 		local_addr = b;
29076433a9a2SJohan Hedberg 		remote_addr = a;
29086433a9a2SJohan Hedberg 		memcpy(io_cap, &smp->preq[1], 3);
29096433a9a2SJohan Hedberg 	}
29106433a9a2SJohan Hedberg 
29116433a9a2SJohan Hedberg 	memset(r, 0, sizeof(r));
29126433a9a2SJohan Hedberg 
291338606f14SJohan Hedberg 	if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY)
291438606f14SJohan Hedberg 		put_unaligned_le32(hcon->passkey_notify, r);
2915882fafadSJohan Hedberg 	else if (smp->method == REQ_OOB)
2916882fafadSJohan Hedberg 		memcpy(r, smp->lr, 16);
291738606f14SJohan Hedberg 
29186433a9a2SJohan Hedberg 	err = smp_f6(smp->tfm_cmac, smp->mackey, smp->rrnd, smp->prnd, r,
29196433a9a2SJohan Hedberg 		     io_cap, remote_addr, local_addr, e);
29206433a9a2SJohan Hedberg 	if (err)
29216433a9a2SJohan Hedberg 		return SMP_UNSPECIFIED;
29226433a9a2SJohan Hedberg 
2923329d8230SJason A. Donenfeld 	if (crypto_memneq(check->e, e, 16))
29246433a9a2SJohan Hedberg 		return SMP_DHKEY_CHECK_FAILED;
29256433a9a2SJohan Hedberg 
2926d3e54a87SJohan Hedberg 	if (!hcon->out) {
2927d3e54a87SJohan Hedberg 		if (test_bit(SMP_FLAG_WAIT_USER, &smp->flags)) {
2928d3e54a87SJohan Hedberg 			set_bit(SMP_FLAG_DHKEY_PENDING, &smp->flags);
2929d3e54a87SJohan Hedberg 			return 0;
2930d3e54a87SJohan Hedberg 		}
2931d378a2d7SJohan Hedberg 
2932fad646e1SArchie Pusaka 		/* Responder sends DHKey check as response to initiator */
2933d3e54a87SJohan Hedberg 		sc_dhkey_check(smp);
2934d3e54a87SJohan Hedberg 	}
2935d378a2d7SJohan Hedberg 
2936d3e54a87SJohan Hedberg 	sc_add_ltk(smp);
29376433a9a2SJohan Hedberg 
29386433a9a2SJohan Hedberg 	if (hcon->out) {
29398b76ce34SJohan Hedberg 		hci_le_start_enc(hcon, 0, 0, smp->tk, smp->enc_key_size);
29406433a9a2SJohan Hedberg 		hcon->enc_key_size = smp->enc_key_size;
29416433a9a2SJohan Hedberg 	}
29426433a9a2SJohan Hedberg 
29436433a9a2SJohan Hedberg 	return 0;
29446433a9a2SJohan Hedberg }
29456433a9a2SJohan Hedberg 
smp_cmd_keypress_notify(struct l2cap_conn * conn,struct sk_buff * skb)29461408bb6eSJohan Hedberg static int smp_cmd_keypress_notify(struct l2cap_conn *conn,
29471408bb6eSJohan Hedberg 				   struct sk_buff *skb)
29481408bb6eSJohan Hedberg {
29491408bb6eSJohan Hedberg 	struct smp_cmd_keypress_notify *kp = (void *) skb->data;
29501408bb6eSJohan Hedberg 
29512e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(conn->hcon->hdev, "value 0x%02x", kp->value);
29521408bb6eSJohan Hedberg 
29531408bb6eSJohan Hedberg 	return 0;
29541408bb6eSJohan Hedberg }
29551408bb6eSJohan Hedberg 
smp_sig_channel(struct l2cap_chan * chan,struct sk_buff * skb)29564befb867SJohan Hedberg static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb)
2957eb492e01SAnderson Briglia {
29585d88cc73SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
29597b9899dbSMarcel Holtmann 	struct hci_conn *hcon = conn->hcon;
2960b28b4943SJohan Hedberg 	struct smp_chan *smp;
296192381f5cSMarcel Holtmann 	__u8 code, reason;
2962eb492e01SAnderson Briglia 	int err = 0;
2963eb492e01SAnderson Briglia 
29648ae9b984SJohan Hedberg 	if (skb->len < 1)
296592381f5cSMarcel Holtmann 		return -EILSEQ;
296692381f5cSMarcel Holtmann 
2967d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hcon->hdev, HCI_LE_ENABLED)) {
29682e65c9d2SAndre Guedes 		reason = SMP_PAIRING_NOTSUPP;
29692e65c9d2SAndre Guedes 		goto done;
29702e65c9d2SAndre Guedes 	}
29712e65c9d2SAndre Guedes 
297292381f5cSMarcel Holtmann 	code = skb->data[0];
2973eb492e01SAnderson Briglia 	skb_pull(skb, sizeof(code));
2974eb492e01SAnderson Briglia 
2975b28b4943SJohan Hedberg 	smp = chan->data;
2976b28b4943SJohan Hedberg 
2977b28b4943SJohan Hedberg 	if (code > SMP_CMD_MAX)
2978b28b4943SJohan Hedberg 		goto drop;
2979b28b4943SJohan Hedberg 
298024bd0bd9SJohan Hedberg 	if (smp && !test_and_clear_bit(code, &smp->allow_cmd))
2981b28b4943SJohan Hedberg 		goto drop;
2982b28b4943SJohan Hedberg 
2983b28b4943SJohan Hedberg 	/* If we don't have a context the only allowed commands are
2984b28b4943SJohan Hedberg 	 * pairing request and security request.
29858cf9fa12SJohan Hedberg 	 */
2986b28b4943SJohan Hedberg 	if (!smp && code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ)
2987b28b4943SJohan Hedberg 		goto drop;
29888cf9fa12SJohan Hedberg 
2989eb492e01SAnderson Briglia 	switch (code) {
2990eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_REQ:
2991da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_req(conn, skb);
2992eb492e01SAnderson Briglia 		break;
2993eb492e01SAnderson Briglia 
2994eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_FAIL:
299584794e11SJohan Hedberg 		smp_failure(conn, 0);
2996da85e5e5SVinicius Costa Gomes 		err = -EPERM;
2997eb492e01SAnderson Briglia 		break;
2998eb492e01SAnderson Briglia 
2999eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_RSP:
3000da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_rsp(conn, skb);
300188ba43b6SAnderson Briglia 		break;
300288ba43b6SAnderson Briglia 
300388ba43b6SAnderson Briglia 	case SMP_CMD_SECURITY_REQ:
3004da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_security_req(conn, skb);
300588ba43b6SAnderson Briglia 		break;
300688ba43b6SAnderson Briglia 
3007eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_CONFIRM:
3008da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_confirm(conn, skb);
300988ba43b6SAnderson Briglia 		break;
301088ba43b6SAnderson Briglia 
3011eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_RANDOM:
3012da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_random(conn, skb);
301388ba43b6SAnderson Briglia 		break;
301488ba43b6SAnderson Briglia 
3015eb492e01SAnderson Briglia 	case SMP_CMD_ENCRYPT_INFO:
30167034b911SVinicius Costa Gomes 		reason = smp_cmd_encrypt_info(conn, skb);
30177034b911SVinicius Costa Gomes 		break;
30187034b911SVinicius Costa Gomes 
3019fad646e1SArchie Pusaka 	case SMP_CMD_INITIATOR_IDENT:
3020fad646e1SArchie Pusaka 		reason = smp_cmd_initiator_ident(conn, skb);
30217034b911SVinicius Costa Gomes 		break;
30227034b911SVinicius Costa Gomes 
3023eb492e01SAnderson Briglia 	case SMP_CMD_IDENT_INFO:
3024fd349c02SJohan Hedberg 		reason = smp_cmd_ident_info(conn, skb);
3025fd349c02SJohan Hedberg 		break;
3026fd349c02SJohan Hedberg 
3027eb492e01SAnderson Briglia 	case SMP_CMD_IDENT_ADDR_INFO:
3028fd349c02SJohan Hedberg 		reason = smp_cmd_ident_addr_info(conn, skb);
3029fd349c02SJohan Hedberg 		break;
3030fd349c02SJohan Hedberg 
3031eb492e01SAnderson Briglia 	case SMP_CMD_SIGN_INFO:
30327ee4ea36SMarcel Holtmann 		reason = smp_cmd_sign_info(conn, skb);
30337034b911SVinicius Costa Gomes 		break;
30347034b911SVinicius Costa Gomes 
3035d8f8edbeSJohan Hedberg 	case SMP_CMD_PUBLIC_KEY:
3036d8f8edbeSJohan Hedberg 		reason = smp_cmd_public_key(conn, skb);
3037d8f8edbeSJohan Hedberg 		break;
3038d8f8edbeSJohan Hedberg 
30396433a9a2SJohan Hedberg 	case SMP_CMD_DHKEY_CHECK:
30406433a9a2SJohan Hedberg 		reason = smp_cmd_dhkey_check(conn, skb);
30416433a9a2SJohan Hedberg 		break;
30426433a9a2SJohan Hedberg 
30431408bb6eSJohan Hedberg 	case SMP_CMD_KEYPRESS_NOTIFY:
30441408bb6eSJohan Hedberg 		reason = smp_cmd_keypress_notify(conn, skb);
30451408bb6eSJohan Hedberg 		break;
30461408bb6eSJohan Hedberg 
3047eb492e01SAnderson Briglia 	default:
30482e1614f7SLuiz Augusto von Dentz 		bt_dev_dbg(hcon->hdev, "Unknown command code 0x%2.2x", code);
3049eb492e01SAnderson Briglia 		reason = SMP_CMD_NOTSUPP;
30503a0259bbSVinicius Costa Gomes 		goto done;
30513a0259bbSVinicius Costa Gomes 	}
30523a0259bbSVinicius Costa Gomes 
30533a0259bbSVinicius Costa Gomes done:
30549b7b18efSJohan Hedberg 	if (!err) {
30553a0259bbSVinicius Costa Gomes 		if (reason)
305684794e11SJohan Hedberg 			smp_failure(conn, reason);
3057eb492e01SAnderson Briglia 		kfree_skb(skb);
30589b7b18efSJohan Hedberg 	}
30599b7b18efSJohan Hedberg 
3060eb492e01SAnderson Briglia 	return err;
3061b28b4943SJohan Hedberg 
3062b28b4943SJohan Hedberg drop:
30632064ee33SMarcel Holtmann 	bt_dev_err(hcon->hdev, "unexpected SMP command 0x%02x from %pMR",
3064b28b4943SJohan Hedberg 		   code, &hcon->dst);
3065b28b4943SJohan Hedberg 	kfree_skb(skb);
3066b28b4943SJohan Hedberg 	return 0;
3067eb492e01SAnderson Briglia }
30687034b911SVinicius Costa Gomes 
smp_teardown_cb(struct l2cap_chan * chan,int err)306970db83c4SJohan Hedberg static void smp_teardown_cb(struct l2cap_chan *chan, int err)
307070db83c4SJohan Hedberg {
307170db83c4SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
307270db83c4SJohan Hedberg 
30732e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(conn->hcon->hdev, "chan %p", chan);
307470db83c4SJohan Hedberg 
3075fc75cc86SJohan Hedberg 	if (chan->data)
30765d88cc73SJohan Hedberg 		smp_chan_destroy(conn);
30775d88cc73SJohan Hedberg 
307870db83c4SJohan Hedberg 	conn->smp = NULL;
307970db83c4SJohan Hedberg 	l2cap_chan_put(chan);
308070db83c4SJohan Hedberg }
308170db83c4SJohan Hedberg 
bredr_pairing(struct l2cap_chan * chan)3082b5ae344dSJohan Hedberg static void bredr_pairing(struct l2cap_chan *chan)
3083b5ae344dSJohan Hedberg {
3084b5ae344dSJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
3085b5ae344dSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
3086b5ae344dSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
3087b5ae344dSJohan Hedberg 	struct smp_cmd_pairing req;
3088b5ae344dSJohan Hedberg 	struct smp_chan *smp;
3089b5ae344dSJohan Hedberg 
30902e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "chan %p", chan);
3091b5ae344dSJohan Hedberg 
3092b5ae344dSJohan Hedberg 	/* Only new pairings are interesting */
3093b5ae344dSJohan Hedberg 	if (!test_bit(HCI_CONN_NEW_LINK_KEY, &hcon->flags))
3094b5ae344dSJohan Hedberg 		return;
3095b5ae344dSJohan Hedberg 
3096b5ae344dSJohan Hedberg 	/* Don't bother if we're not encrypted */
3097b5ae344dSJohan Hedberg 	if (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags))
3098b5ae344dSJohan Hedberg 		return;
3099b5ae344dSJohan Hedberg 
310074be523cSArchie Pusaka 	/* Only initiator may initiate SMP over BR/EDR */
3101b5ae344dSJohan Hedberg 	if (hcon->role != HCI_ROLE_MASTER)
3102b5ae344dSJohan Hedberg 		return;
3103b5ae344dSJohan Hedberg 
3104b5ae344dSJohan Hedberg 	/* Secure Connections support must be enabled */
3105d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_SC_ENABLED))
3106b5ae344dSJohan Hedberg 		return;
3107b5ae344dSJohan Hedberg 
3108b5ae344dSJohan Hedberg 	/* BR/EDR must use Secure Connections for SMP */
3109b5ae344dSJohan Hedberg 	if (!test_bit(HCI_CONN_AES_CCM, &hcon->flags) &&
3110b7cb93e5SMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP))
3111b5ae344dSJohan Hedberg 		return;
3112b5ae344dSJohan Hedberg 
3113b5ae344dSJohan Hedberg 	/* If our LE support is not enabled don't do anything */
3114d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED))
3115b5ae344dSJohan Hedberg 		return;
3116b5ae344dSJohan Hedberg 
3117b5ae344dSJohan Hedberg 	/* Don't bother if remote LE support is not enabled */
3118b5ae344dSJohan Hedberg 	if (!lmp_host_le_capable(hcon))
3119b5ae344dSJohan Hedberg 		return;
3120b5ae344dSJohan Hedberg 
3121b5ae344dSJohan Hedberg 	/* Remote must support SMP fixed chan for BR/EDR */
3122b5ae344dSJohan Hedberg 	if (!(conn->remote_fixed_chan & L2CAP_FC_SMP_BREDR))
3123b5ae344dSJohan Hedberg 		return;
3124b5ae344dSJohan Hedberg 
3125b5ae344dSJohan Hedberg 	/* Don't bother if SMP is already ongoing */
3126b5ae344dSJohan Hedberg 	if (chan->data)
3127b5ae344dSJohan Hedberg 		return;
3128b5ae344dSJohan Hedberg 
3129b5ae344dSJohan Hedberg 	smp = smp_chan_create(conn);
3130b5ae344dSJohan Hedberg 	if (!smp) {
31312064ee33SMarcel Holtmann 		bt_dev_err(hdev, "unable to create SMP context for BR/EDR");
3132b5ae344dSJohan Hedberg 		return;
3133b5ae344dSJohan Hedberg 	}
3134b5ae344dSJohan Hedberg 
3135b5ae344dSJohan Hedberg 	set_bit(SMP_FLAG_SC, &smp->flags);
3136b5ae344dSJohan Hedberg 
31372e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "starting SMP over BR/EDR");
3138b5ae344dSJohan Hedberg 
3139b5ae344dSJohan Hedberg 	/* Prepare and send the BR/EDR SMP Pairing Request */
3140b5ae344dSJohan Hedberg 	build_bredr_pairing_cmd(smp, &req, NULL);
3141b5ae344dSJohan Hedberg 
3142b5ae344dSJohan Hedberg 	smp->preq[0] = SMP_CMD_PAIRING_REQ;
3143b5ae344dSJohan Hedberg 	memcpy(&smp->preq[1], &req, sizeof(req));
3144b5ae344dSJohan Hedberg 
3145b5ae344dSJohan Hedberg 	smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(req), &req);
3146b5ae344dSJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP);
3147b5ae344dSJohan Hedberg }
3148b5ae344dSJohan Hedberg 
smp_resume_cb(struct l2cap_chan * chan)314944f1a7abSJohan Hedberg static void smp_resume_cb(struct l2cap_chan *chan)
315044f1a7abSJohan Hedberg {
3151b68fda68SJohan Hedberg 	struct smp_chan *smp = chan->data;
315244f1a7abSJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
315344f1a7abSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
315444f1a7abSJohan Hedberg 
31552e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hcon->hdev, "chan %p", chan);
315644f1a7abSJohan Hedberg 
3157b5ae344dSJohan Hedberg 	if (hcon->type == ACL_LINK) {
3158b5ae344dSJohan Hedberg 		bredr_pairing(chan);
3159ef8efe4bSJohan Hedberg 		return;
3160b5ae344dSJohan Hedberg 	}
3161ef8efe4bSJohan Hedberg 
316286d1407cSJohan Hedberg 	if (!smp)
316386d1407cSJohan Hedberg 		return;
3164b68fda68SJohan Hedberg 
316584bc0db5SJohan Hedberg 	if (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags))
316684bc0db5SJohan Hedberg 		return;
316784bc0db5SJohan Hedberg 
3168b68fda68SJohan Hedberg 	cancel_delayed_work(&smp->security_timer);
316986d1407cSJohan Hedberg 
3170d6268e86SJohan Hedberg 	smp_distribute_keys(smp);
317144f1a7abSJohan Hedberg }
317244f1a7abSJohan Hedberg 
smp_ready_cb(struct l2cap_chan * chan)317370db83c4SJohan Hedberg static void smp_ready_cb(struct l2cap_chan *chan)
317470db83c4SJohan Hedberg {
317570db83c4SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
3176b5ae344dSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
317770db83c4SJohan Hedberg 
31782e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hcon->hdev, "chan %p", chan);
317970db83c4SJohan Hedberg 
31807883746bSJohan Hedberg 	/* No need to call l2cap_chan_hold() here since we already own
31817883746bSJohan Hedberg 	 * the reference taken in smp_new_conn_cb(). This is just the
31827883746bSJohan Hedberg 	 * first time that we tie it to a specific pointer. The code in
31837883746bSJohan Hedberg 	 * l2cap_core.c ensures that there's no risk this function wont
31847883746bSJohan Hedberg 	 * get called if smp_new_conn_cb was previously called.
31857883746bSJohan Hedberg 	 */
318670db83c4SJohan Hedberg 	conn->smp = chan;
3187b5ae344dSJohan Hedberg 
3188b5ae344dSJohan Hedberg 	if (hcon->type == ACL_LINK && test_bit(HCI_CONN_ENCRYPT, &hcon->flags))
3189b5ae344dSJohan Hedberg 		bredr_pairing(chan);
319070db83c4SJohan Hedberg }
319170db83c4SJohan Hedberg 
smp_recv_cb(struct l2cap_chan * chan,struct sk_buff * skb)31924befb867SJohan Hedberg static int smp_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
31934befb867SJohan Hedberg {
31944befb867SJohan Hedberg 	int err;
31954befb867SJohan Hedberg 
31962e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(chan->conn->hcon->hdev, "chan %p", chan);
31974befb867SJohan Hedberg 
31984befb867SJohan Hedberg 	err = smp_sig_channel(chan, skb);
31994befb867SJohan Hedberg 	if (err) {
3200b68fda68SJohan Hedberg 		struct smp_chan *smp = chan->data;
32014befb867SJohan Hedberg 
3202b68fda68SJohan Hedberg 		if (smp)
3203b68fda68SJohan Hedberg 			cancel_delayed_work_sync(&smp->security_timer);
32044befb867SJohan Hedberg 
32051e91c29eSJohan Hedberg 		hci_disconnect(chan->conn->hcon, HCI_ERROR_AUTH_FAILURE);
32064befb867SJohan Hedberg 	}
32074befb867SJohan Hedberg 
32084befb867SJohan Hedberg 	return err;
32094befb867SJohan Hedberg }
32104befb867SJohan Hedberg 
smp_alloc_skb_cb(struct l2cap_chan * chan,unsigned long hdr_len,unsigned long len,int nb)321170db83c4SJohan Hedberg static struct sk_buff *smp_alloc_skb_cb(struct l2cap_chan *chan,
321270db83c4SJohan Hedberg 					unsigned long hdr_len,
321370db83c4SJohan Hedberg 					unsigned long len, int nb)
321470db83c4SJohan Hedberg {
321570db83c4SJohan Hedberg 	struct sk_buff *skb;
321670db83c4SJohan Hedberg 
321770db83c4SJohan Hedberg 	skb = bt_skb_alloc(hdr_len + len, GFP_KERNEL);
321870db83c4SJohan Hedberg 	if (!skb)
321970db83c4SJohan Hedberg 		return ERR_PTR(-ENOMEM);
322070db83c4SJohan Hedberg 
322170db83c4SJohan Hedberg 	skb->priority = HCI_PRIO_MAX;
3222a4368ff3SJohan Hedberg 	bt_cb(skb)->l2cap.chan = chan;
322370db83c4SJohan Hedberg 
322470db83c4SJohan Hedberg 	return skb;
322570db83c4SJohan Hedberg }
322670db83c4SJohan Hedberg 
322770db83c4SJohan Hedberg static const struct l2cap_ops smp_chan_ops = {
322870db83c4SJohan Hedberg 	.name			= "Security Manager",
322970db83c4SJohan Hedberg 	.ready			= smp_ready_cb,
32305d88cc73SJohan Hedberg 	.recv			= smp_recv_cb,
323170db83c4SJohan Hedberg 	.alloc_skb		= smp_alloc_skb_cb,
323270db83c4SJohan Hedberg 	.teardown		= smp_teardown_cb,
323344f1a7abSJohan Hedberg 	.resume			= smp_resume_cb,
323470db83c4SJohan Hedberg 
323570db83c4SJohan Hedberg 	.new_connection		= l2cap_chan_no_new_connection,
323670db83c4SJohan Hedberg 	.state_change		= l2cap_chan_no_state_change,
323770db83c4SJohan Hedberg 	.close			= l2cap_chan_no_close,
323870db83c4SJohan Hedberg 	.defer			= l2cap_chan_no_defer,
323970db83c4SJohan Hedberg 	.suspend		= l2cap_chan_no_suspend,
324070db83c4SJohan Hedberg 	.set_shutdown		= l2cap_chan_no_set_shutdown,
324170db83c4SJohan Hedberg 	.get_sndtimeo		= l2cap_chan_no_get_sndtimeo,
324270db83c4SJohan Hedberg };
324370db83c4SJohan Hedberg 
smp_new_conn_cb(struct l2cap_chan * pchan)324470db83c4SJohan Hedberg static inline struct l2cap_chan *smp_new_conn_cb(struct l2cap_chan *pchan)
324570db83c4SJohan Hedberg {
324670db83c4SJohan Hedberg 	struct l2cap_chan *chan;
324770db83c4SJohan Hedberg 
3248995fca15SLuiz Augusto von Dentz 	BT_DBG("pchan %p", pchan);
324970db83c4SJohan Hedberg 
325070db83c4SJohan Hedberg 	chan = l2cap_chan_create();
325170db83c4SJohan Hedberg 	if (!chan)
325270db83c4SJohan Hedberg 		return NULL;
325370db83c4SJohan Hedberg 
325470db83c4SJohan Hedberg 	chan->chan_type	= pchan->chan_type;
325570db83c4SJohan Hedberg 	chan->ops	= &smp_chan_ops;
325670db83c4SJohan Hedberg 	chan->scid	= pchan->scid;
325770db83c4SJohan Hedberg 	chan->dcid	= chan->scid;
325870db83c4SJohan Hedberg 	chan->imtu	= pchan->imtu;
325970db83c4SJohan Hedberg 	chan->omtu	= pchan->omtu;
326070db83c4SJohan Hedberg 	chan->mode	= pchan->mode;
326170db83c4SJohan Hedberg 
3262abe84903SJohan Hedberg 	/* Other L2CAP channels may request SMP routines in order to
3263abe84903SJohan Hedberg 	 * change the security level. This means that the SMP channel
3264abe84903SJohan Hedberg 	 * lock must be considered in its own category to avoid lockdep
3265abe84903SJohan Hedberg 	 * warnings.
3266abe84903SJohan Hedberg 	 */
3267abe84903SJohan Hedberg 	atomic_set(&chan->nesting, L2CAP_NESTING_SMP);
3268abe84903SJohan Hedberg 
3269995fca15SLuiz Augusto von Dentz 	BT_DBG("created chan %p", chan);
327070db83c4SJohan Hedberg 
327170db83c4SJohan Hedberg 	return chan;
327270db83c4SJohan Hedberg }
327370db83c4SJohan Hedberg 
327470db83c4SJohan Hedberg static const struct l2cap_ops smp_root_chan_ops = {
327570db83c4SJohan Hedberg 	.name			= "Security Manager Root",
327670db83c4SJohan Hedberg 	.new_connection		= smp_new_conn_cb,
327770db83c4SJohan Hedberg 
327870db83c4SJohan Hedberg 	/* None of these are implemented for the root channel */
327970db83c4SJohan Hedberg 	.close			= l2cap_chan_no_close,
328070db83c4SJohan Hedberg 	.alloc_skb		= l2cap_chan_no_alloc_skb,
328170db83c4SJohan Hedberg 	.recv			= l2cap_chan_no_recv,
328270db83c4SJohan Hedberg 	.state_change		= l2cap_chan_no_state_change,
328370db83c4SJohan Hedberg 	.teardown		= l2cap_chan_no_teardown,
328470db83c4SJohan Hedberg 	.ready			= l2cap_chan_no_ready,
328570db83c4SJohan Hedberg 	.defer			= l2cap_chan_no_defer,
328670db83c4SJohan Hedberg 	.suspend		= l2cap_chan_no_suspend,
328770db83c4SJohan Hedberg 	.resume			= l2cap_chan_no_resume,
328870db83c4SJohan Hedberg 	.set_shutdown		= l2cap_chan_no_set_shutdown,
328970db83c4SJohan Hedberg 	.get_sndtimeo		= l2cap_chan_no_get_sndtimeo,
329070db83c4SJohan Hedberg };
329170db83c4SJohan Hedberg 
smp_add_cid(struct hci_dev * hdev,u16 cid)3292ef8efe4bSJohan Hedberg static struct l2cap_chan *smp_add_cid(struct hci_dev *hdev, u16 cid)
3293711eafe3SJohan Hedberg {
329470db83c4SJohan Hedberg 	struct l2cap_chan *chan;
329588a479d9SMarcel Holtmann 	struct smp_dev *smp;
329671af2f6bSHerbert Xu 	struct crypto_shash *tfm_cmac;
329747eb2ac8STudor Ambarus 	struct crypto_kpp *tfm_ecdh;
329870db83c4SJohan Hedberg 
3299ef8efe4bSJohan Hedberg 	if (cid == L2CAP_CID_SMP_BREDR) {
330088a479d9SMarcel Holtmann 		smp = NULL;
3301ef8efe4bSJohan Hedberg 		goto create_chan;
3302ef8efe4bSJohan Hedberg 	}
3303711eafe3SJohan Hedberg 
330488a479d9SMarcel Holtmann 	smp = kzalloc(sizeof(*smp), GFP_KERNEL);
330588a479d9SMarcel Holtmann 	if (!smp)
330688a479d9SMarcel Holtmann 		return ERR_PTR(-ENOMEM);
330788a479d9SMarcel Holtmann 
330871af2f6bSHerbert Xu 	tfm_cmac = crypto_alloc_shash("cmac(aes)", 0, 0);
33096e2dc6d1SMarcel Holtmann 	if (IS_ERR(tfm_cmac)) {
33102e1614f7SLuiz Augusto von Dentz 		bt_dev_err(hdev, "Unable to create CMAC crypto context");
3311453431a5SWaiman Long 		kfree_sensitive(smp);
33126e2dc6d1SMarcel Holtmann 		return ERR_CAST(tfm_cmac);
33136e2dc6d1SMarcel Holtmann 	}
33146e2dc6d1SMarcel Holtmann 
33156763f5eaSMeng Yu 	tfm_ecdh = crypto_alloc_kpp("ecdh-nist-p256", 0, 0);
331647eb2ac8STudor Ambarus 	if (IS_ERR(tfm_ecdh)) {
33172e1614f7SLuiz Augusto von Dentz 		bt_dev_err(hdev, "Unable to create ECDH crypto context");
331847eb2ac8STudor Ambarus 		crypto_free_shash(tfm_cmac);
3319453431a5SWaiman Long 		kfree_sensitive(smp);
332047eb2ac8STudor Ambarus 		return ERR_CAST(tfm_ecdh);
332147eb2ac8STudor Ambarus 	}
332247eb2ac8STudor Ambarus 
332394f14e47SJohan Hedberg 	smp->local_oob = false;
33246e2dc6d1SMarcel Holtmann 	smp->tfm_cmac = tfm_cmac;
332547eb2ac8STudor Ambarus 	smp->tfm_ecdh = tfm_ecdh;
332688a479d9SMarcel Holtmann 
3327ef8efe4bSJohan Hedberg create_chan:
332870db83c4SJohan Hedberg 	chan = l2cap_chan_create();
332970db83c4SJohan Hedberg 	if (!chan) {
333063511f6dSMarcel Holtmann 		if (smp) {
333171af2f6bSHerbert Xu 			crypto_free_shash(smp->tfm_cmac);
333247eb2ac8STudor Ambarus 			crypto_free_kpp(smp->tfm_ecdh);
3333453431a5SWaiman Long 			kfree_sensitive(smp);
333463511f6dSMarcel Holtmann 		}
3335ef8efe4bSJohan Hedberg 		return ERR_PTR(-ENOMEM);
333670db83c4SJohan Hedberg 	}
333770db83c4SJohan Hedberg 
333888a479d9SMarcel Holtmann 	chan->data = smp;
3339defce9e8SJohan Hedberg 
3340ef8efe4bSJohan Hedberg 	l2cap_add_scid(chan, cid);
334170db83c4SJohan Hedberg 
334270db83c4SJohan Hedberg 	l2cap_chan_set_defaults(chan);
334370db83c4SJohan Hedberg 
3344157029baSMarcel Holtmann 	if (cid == L2CAP_CID_SMP) {
334539e3e744SJohan Hedberg 		u8 bdaddr_type;
334639e3e744SJohan Hedberg 
334739e3e744SJohan Hedberg 		hci_copy_identity_address(hdev, &chan->src, &bdaddr_type);
334839e3e744SJohan Hedberg 
334939e3e744SJohan Hedberg 		if (bdaddr_type == ADDR_LE_DEV_PUBLIC)
335070db83c4SJohan Hedberg 			chan->src_type = BDADDR_LE_PUBLIC;
335139e3e744SJohan Hedberg 		else
335239e3e744SJohan Hedberg 			chan->src_type = BDADDR_LE_RANDOM;
3353157029baSMarcel Holtmann 	} else {
3354157029baSMarcel Holtmann 		bacpy(&chan->src, &hdev->bdaddr);
3355ef8efe4bSJohan Hedberg 		chan->src_type = BDADDR_BREDR;
3356157029baSMarcel Holtmann 	}
3357157029baSMarcel Holtmann 
335870db83c4SJohan Hedberg 	chan->state = BT_LISTEN;
335970db83c4SJohan Hedberg 	chan->mode = L2CAP_MODE_BASIC;
336070db83c4SJohan Hedberg 	chan->imtu = L2CAP_DEFAULT_MTU;
336170db83c4SJohan Hedberg 	chan->ops = &smp_root_chan_ops;
336270db83c4SJohan Hedberg 
3363abe84903SJohan Hedberg 	/* Set correct nesting level for a parent/listening channel */
3364abe84903SJohan Hedberg 	atomic_set(&chan->nesting, L2CAP_NESTING_PARENT);
3365abe84903SJohan Hedberg 
3366ef8efe4bSJohan Hedberg 	return chan;
3367711eafe3SJohan Hedberg }
3368711eafe3SJohan Hedberg 
smp_del_chan(struct l2cap_chan * chan)3369ef8efe4bSJohan Hedberg static void smp_del_chan(struct l2cap_chan *chan)
3370711eafe3SJohan Hedberg {
337188a479d9SMarcel Holtmann 	struct smp_dev *smp;
337270db83c4SJohan Hedberg 
3373995fca15SLuiz Augusto von Dentz 	BT_DBG("chan %p", chan);
3374711eafe3SJohan Hedberg 
337588a479d9SMarcel Holtmann 	smp = chan->data;
337688a479d9SMarcel Holtmann 	if (smp) {
3377defce9e8SJohan Hedberg 		chan->data = NULL;
337871af2f6bSHerbert Xu 		crypto_free_shash(smp->tfm_cmac);
337947eb2ac8STudor Ambarus 		crypto_free_kpp(smp->tfm_ecdh);
3380453431a5SWaiman Long 		kfree_sensitive(smp);
3381711eafe3SJohan Hedberg 	}
338270db83c4SJohan Hedberg 
338370db83c4SJohan Hedberg 	l2cap_chan_put(chan);
3384711eafe3SJohan Hedberg }
3385ef8efe4bSJohan Hedberg 
smp_force_bredr(struct hci_dev * hdev,bool enable)338682493316SClaire Chang int smp_force_bredr(struct hci_dev *hdev, bool enable)
3387300acfdeSMarcel Holtmann {
3388b7cb93e5SMarcel Holtmann 	if (enable == hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP))
3389300acfdeSMarcel Holtmann 		return -EALREADY;
3390300acfdeSMarcel Holtmann 
3391300acfdeSMarcel Holtmann 	if (enable) {
3392300acfdeSMarcel Holtmann 		struct l2cap_chan *chan;
3393300acfdeSMarcel Holtmann 
3394300acfdeSMarcel Holtmann 		chan = smp_add_cid(hdev, L2CAP_CID_SMP_BREDR);
3395300acfdeSMarcel Holtmann 		if (IS_ERR(chan))
3396300acfdeSMarcel Holtmann 			return PTR_ERR(chan);
3397300acfdeSMarcel Holtmann 
3398300acfdeSMarcel Holtmann 		hdev->smp_bredr_data = chan;
3399300acfdeSMarcel Holtmann 	} else {
3400300acfdeSMarcel Holtmann 		struct l2cap_chan *chan;
3401300acfdeSMarcel Holtmann 
3402300acfdeSMarcel Holtmann 		chan = hdev->smp_bredr_data;
3403300acfdeSMarcel Holtmann 		hdev->smp_bredr_data = NULL;
3404300acfdeSMarcel Holtmann 		smp_del_chan(chan);
3405300acfdeSMarcel Holtmann 	}
3406300acfdeSMarcel Holtmann 
3407b7cb93e5SMarcel Holtmann 	hci_dev_change_flag(hdev, HCI_FORCE_BREDR_SMP);
3408300acfdeSMarcel Holtmann 
340982493316SClaire Chang 	return 0;
3410300acfdeSMarcel Holtmann }
3411300acfdeSMarcel Holtmann 
smp_register(struct hci_dev * hdev)3412ef8efe4bSJohan Hedberg int smp_register(struct hci_dev *hdev)
3413ef8efe4bSJohan Hedberg {
3414ef8efe4bSJohan Hedberg 	struct l2cap_chan *chan;
3415ef8efe4bSJohan Hedberg 
34162e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
3417ef8efe4bSJohan Hedberg 
34187e7ec445SMarcel Holtmann 	/* If the controller does not support Low Energy operation, then
34197e7ec445SMarcel Holtmann 	 * there is also no need to register any SMP channel.
34207e7ec445SMarcel Holtmann 	 */
34217e7ec445SMarcel Holtmann 	if (!lmp_le_capable(hdev))
34227e7ec445SMarcel Holtmann 		return 0;
34237e7ec445SMarcel Holtmann 
34242b8df323SMarcel Holtmann 	if (WARN_ON(hdev->smp_data)) {
34252b8df323SMarcel Holtmann 		chan = hdev->smp_data;
34262b8df323SMarcel Holtmann 		hdev->smp_data = NULL;
34272b8df323SMarcel Holtmann 		smp_del_chan(chan);
34282b8df323SMarcel Holtmann 	}
34292b8df323SMarcel Holtmann 
3430ef8efe4bSJohan Hedberg 	chan = smp_add_cid(hdev, L2CAP_CID_SMP);
3431ef8efe4bSJohan Hedberg 	if (IS_ERR(chan))
3432ef8efe4bSJohan Hedberg 		return PTR_ERR(chan);
3433ef8efe4bSJohan Hedberg 
3434ef8efe4bSJohan Hedberg 	hdev->smp_data = chan;
3435ef8efe4bSJohan Hedberg 
3436300acfdeSMarcel Holtmann 	if (!lmp_sc_capable(hdev)) {
343783ebb9ecSSzymon Janc 		/* Flag can be already set here (due to power toggle) */
343883ebb9ecSSzymon Janc 		if (!hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP))
3439ef8efe4bSJohan Hedberg 			return 0;
3440300acfdeSMarcel Holtmann 	}
3441ef8efe4bSJohan Hedberg 
34422b8df323SMarcel Holtmann 	if (WARN_ON(hdev->smp_bredr_data)) {
34432b8df323SMarcel Holtmann 		chan = hdev->smp_bredr_data;
34442b8df323SMarcel Holtmann 		hdev->smp_bredr_data = NULL;
34452b8df323SMarcel Holtmann 		smp_del_chan(chan);
34462b8df323SMarcel Holtmann 	}
34472b8df323SMarcel Holtmann 
3448ef8efe4bSJohan Hedberg 	chan = smp_add_cid(hdev, L2CAP_CID_SMP_BREDR);
3449ef8efe4bSJohan Hedberg 	if (IS_ERR(chan)) {
3450ef8efe4bSJohan Hedberg 		int err = PTR_ERR(chan);
3451ef8efe4bSJohan Hedberg 		chan = hdev->smp_data;
3452ef8efe4bSJohan Hedberg 		hdev->smp_data = NULL;
3453ef8efe4bSJohan Hedberg 		smp_del_chan(chan);
3454ef8efe4bSJohan Hedberg 		return err;
3455ef8efe4bSJohan Hedberg 	}
3456ef8efe4bSJohan Hedberg 
3457ef8efe4bSJohan Hedberg 	hdev->smp_bredr_data = chan;
3458ef8efe4bSJohan Hedberg 
3459ef8efe4bSJohan Hedberg 	return 0;
3460ef8efe4bSJohan Hedberg }
3461ef8efe4bSJohan Hedberg 
smp_unregister(struct hci_dev * hdev)3462ef8efe4bSJohan Hedberg void smp_unregister(struct hci_dev *hdev)
3463ef8efe4bSJohan Hedberg {
3464ef8efe4bSJohan Hedberg 	struct l2cap_chan *chan;
3465ef8efe4bSJohan Hedberg 
3466ef8efe4bSJohan Hedberg 	if (hdev->smp_bredr_data) {
3467ef8efe4bSJohan Hedberg 		chan = hdev->smp_bredr_data;
3468ef8efe4bSJohan Hedberg 		hdev->smp_bredr_data = NULL;
3469ef8efe4bSJohan Hedberg 		smp_del_chan(chan);
3470ef8efe4bSJohan Hedberg 	}
3471ef8efe4bSJohan Hedberg 
3472ef8efe4bSJohan Hedberg 	if (hdev->smp_data) {
3473ef8efe4bSJohan Hedberg 		chan = hdev->smp_data;
3474ef8efe4bSJohan Hedberg 		hdev->smp_data = NULL;
3475ef8efe4bSJohan Hedberg 		smp_del_chan(chan);
3476ef8efe4bSJohan Hedberg 	}
3477ef8efe4bSJohan Hedberg }
34780a2b0f04SJohan Hedberg 
34790a2b0f04SJohan Hedberg #if IS_ENABLED(CONFIG_BT_SELFTEST_SMP)
34800a2b0f04SJohan Hedberg 
test_debug_key(struct crypto_kpp * tfm_ecdh)348147eb2ac8STudor Ambarus static int __init test_debug_key(struct crypto_kpp *tfm_ecdh)
348271653eb6SMarcel Holtmann {
3483c0153b0bSTudor Ambarus 	u8 pk[64];
3484a2976416STudor Ambarus 	int err;
348571653eb6SMarcel Holtmann 
3486c0153b0bSTudor Ambarus 	err = set_ecdh_privkey(tfm_ecdh, debug_sk);
3487a2976416STudor Ambarus 	if (err)
3488a2976416STudor Ambarus 		return err;
348971653eb6SMarcel Holtmann 
3490c0153b0bSTudor Ambarus 	err = generate_ecdh_public_key(tfm_ecdh, pk);
3491c0153b0bSTudor Ambarus 	if (err)
3492c0153b0bSTudor Ambarus 		return err;
349371653eb6SMarcel Holtmann 
3494329d8230SJason A. Donenfeld 	if (crypto_memneq(pk, debug_pk, 64))
349571653eb6SMarcel Holtmann 		return -EINVAL;
349671653eb6SMarcel Holtmann 
349771653eb6SMarcel Holtmann 	return 0;
349871653eb6SMarcel Holtmann }
349971653eb6SMarcel Holtmann 
test_ah(void)350028a220aaSArd Biesheuvel static int __init test_ah(void)
3501cfc4198eSJohan Hedberg {
3502cfc4198eSJohan Hedberg 	const u8 irk[16] = {
3503cfc4198eSJohan Hedberg 			0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34,
3504cfc4198eSJohan Hedberg 			0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec };
3505cfc4198eSJohan Hedberg 	const u8 r[3] = { 0x94, 0x81, 0x70 };
3506cfc4198eSJohan Hedberg 	const u8 exp[3] = { 0xaa, 0xfb, 0x0d };
3507cfc4198eSJohan Hedberg 	u8 res[3];
3508cfc4198eSJohan Hedberg 	int err;
3509cfc4198eSJohan Hedberg 
351028a220aaSArd Biesheuvel 	err = smp_ah(irk, r, res);
3511cfc4198eSJohan Hedberg 	if (err)
3512cfc4198eSJohan Hedberg 		return err;
3513cfc4198eSJohan Hedberg 
3514329d8230SJason A. Donenfeld 	if (crypto_memneq(res, exp, 3))
3515cfc4198eSJohan Hedberg 		return -EINVAL;
3516cfc4198eSJohan Hedberg 
3517cfc4198eSJohan Hedberg 	return 0;
3518cfc4198eSJohan Hedberg }
3519cfc4198eSJohan Hedberg 
test_c1(void)352028a220aaSArd Biesheuvel static int __init test_c1(void)
3521cfc4198eSJohan Hedberg {
3522cfc4198eSJohan Hedberg 	const u8 k[16] = {
3523cfc4198eSJohan Hedberg 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3524cfc4198eSJohan Hedberg 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
3525cfc4198eSJohan Hedberg 	const u8 r[16] = {
3526cfc4198eSJohan Hedberg 			0xe0, 0x2e, 0x70, 0xc6, 0x4e, 0x27, 0x88, 0x63,
3527cfc4198eSJohan Hedberg 			0x0e, 0x6f, 0xad, 0x56, 0x21, 0xd5, 0x83, 0x57 };
3528cfc4198eSJohan Hedberg 	const u8 preq[7] = { 0x01, 0x01, 0x00, 0x00, 0x10, 0x07, 0x07 };
3529cfc4198eSJohan Hedberg 	const u8 pres[7] = { 0x02, 0x03, 0x00, 0x00, 0x08, 0x00, 0x05 };
3530cfc4198eSJohan Hedberg 	const u8 _iat = 0x01;
3531cfc4198eSJohan Hedberg 	const u8 _rat = 0x00;
3532cfc4198eSJohan Hedberg 	const bdaddr_t ra = { { 0xb6, 0xb5, 0xb4, 0xb3, 0xb2, 0xb1 } };
3533cfc4198eSJohan Hedberg 	const bdaddr_t ia = { { 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1 } };
3534cfc4198eSJohan Hedberg 	const u8 exp[16] = {
3535cfc4198eSJohan Hedberg 			0x86, 0x3b, 0xf1, 0xbe, 0xc5, 0x4d, 0xa7, 0xd2,
3536cfc4198eSJohan Hedberg 			0xea, 0x88, 0x89, 0x87, 0xef, 0x3f, 0x1e, 0x1e };
3537cfc4198eSJohan Hedberg 	u8 res[16];
3538cfc4198eSJohan Hedberg 	int err;
3539cfc4198eSJohan Hedberg 
354028a220aaSArd Biesheuvel 	err = smp_c1(k, r, preq, pres, _iat, &ia, _rat, &ra, res);
3541cfc4198eSJohan Hedberg 	if (err)
3542cfc4198eSJohan Hedberg 		return err;
3543cfc4198eSJohan Hedberg 
3544329d8230SJason A. Donenfeld 	if (crypto_memneq(res, exp, 16))
3545cfc4198eSJohan Hedberg 		return -EINVAL;
3546cfc4198eSJohan Hedberg 
3547cfc4198eSJohan Hedberg 	return 0;
3548cfc4198eSJohan Hedberg }
3549cfc4198eSJohan Hedberg 
test_s1(void)355028a220aaSArd Biesheuvel static int __init test_s1(void)
3551cfc4198eSJohan Hedberg {
3552cfc4198eSJohan Hedberg 	const u8 k[16] = {
3553cfc4198eSJohan Hedberg 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3554cfc4198eSJohan Hedberg 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
3555cfc4198eSJohan Hedberg 	const u8 r1[16] = {
3556cfc4198eSJohan Hedberg 			0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 };
3557cfc4198eSJohan Hedberg 	const u8 r2[16] = {
3558cfc4198eSJohan Hedberg 			0x00, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99 };
3559cfc4198eSJohan Hedberg 	const u8 exp[16] = {
3560cfc4198eSJohan Hedberg 			0x62, 0xa0, 0x6d, 0x79, 0xae, 0x16, 0x42, 0x5b,
3561cfc4198eSJohan Hedberg 			0x9b, 0xf4, 0xb0, 0xe8, 0xf0, 0xe1, 0x1f, 0x9a };
3562cfc4198eSJohan Hedberg 	u8 res[16];
3563cfc4198eSJohan Hedberg 	int err;
3564cfc4198eSJohan Hedberg 
356528a220aaSArd Biesheuvel 	err = smp_s1(k, r1, r2, res);
3566cfc4198eSJohan Hedberg 	if (err)
3567cfc4198eSJohan Hedberg 		return err;
3568cfc4198eSJohan Hedberg 
3569329d8230SJason A. Donenfeld 	if (crypto_memneq(res, exp, 16))
3570cfc4198eSJohan Hedberg 		return -EINVAL;
3571cfc4198eSJohan Hedberg 
3572cfc4198eSJohan Hedberg 	return 0;
3573cfc4198eSJohan Hedberg }
3574cfc4198eSJohan Hedberg 
test_f4(struct crypto_shash * tfm_cmac)357571af2f6bSHerbert Xu static int __init test_f4(struct crypto_shash *tfm_cmac)
3576fb2969a3SJohan Hedberg {
3577fb2969a3SJohan Hedberg 	const u8 u[32] = {
3578fb2969a3SJohan Hedberg 			0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc,
3579fb2969a3SJohan Hedberg 			0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef,
3580fb2969a3SJohan Hedberg 			0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e,
3581fb2969a3SJohan Hedberg 			0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20 };
3582fb2969a3SJohan Hedberg 	const u8 v[32] = {
3583fb2969a3SJohan Hedberg 			0xfd, 0xc5, 0x7f, 0xf4, 0x49, 0xdd, 0x4f, 0x6b,
3584fb2969a3SJohan Hedberg 			0xfb, 0x7c, 0x9d, 0xf1, 0xc2, 0x9a, 0xcb, 0x59,
3585fb2969a3SJohan Hedberg 			0x2a, 0xe7, 0xd4, 0xee, 0xfb, 0xfc, 0x0a, 0x90,
3586fb2969a3SJohan Hedberg 			0x9a, 0xbb, 0xf6, 0x32, 0x3d, 0x8b, 0x18, 0x55 };
3587fb2969a3SJohan Hedberg 	const u8 x[16] = {
3588fb2969a3SJohan Hedberg 			0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff,
3589fb2969a3SJohan Hedberg 			0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 };
3590fb2969a3SJohan Hedberg 	const u8 z = 0x00;
3591fb2969a3SJohan Hedberg 	const u8 exp[16] = {
3592fb2969a3SJohan Hedberg 			0x2d, 0x87, 0x74, 0xa9, 0xbe, 0xa1, 0xed, 0xf1,
3593fb2969a3SJohan Hedberg 			0x1c, 0xbd, 0xa9, 0x07, 0xf1, 0x16, 0xc9, 0xf2 };
3594fb2969a3SJohan Hedberg 	u8 res[16];
3595fb2969a3SJohan Hedberg 	int err;
3596fb2969a3SJohan Hedberg 
3597fb2969a3SJohan Hedberg 	err = smp_f4(tfm_cmac, u, v, x, z, res);
3598fb2969a3SJohan Hedberg 	if (err)
3599fb2969a3SJohan Hedberg 		return err;
3600fb2969a3SJohan Hedberg 
3601329d8230SJason A. Donenfeld 	if (crypto_memneq(res, exp, 16))
3602fb2969a3SJohan Hedberg 		return -EINVAL;
3603fb2969a3SJohan Hedberg 
3604fb2969a3SJohan Hedberg 	return 0;
3605fb2969a3SJohan Hedberg }
3606fb2969a3SJohan Hedberg 
test_f5(struct crypto_shash * tfm_cmac)360771af2f6bSHerbert Xu static int __init test_f5(struct crypto_shash *tfm_cmac)
3608fb2969a3SJohan Hedberg {
3609fb2969a3SJohan Hedberg 	const u8 w[32] = {
3610fb2969a3SJohan Hedberg 			0x98, 0xa6, 0xbf, 0x73, 0xf3, 0x34, 0x8d, 0x86,
3611fb2969a3SJohan Hedberg 			0xf1, 0x66, 0xf8, 0xb4, 0x13, 0x6b, 0x79, 0x99,
3612fb2969a3SJohan Hedberg 			0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34,
3613fb2969a3SJohan Hedberg 			0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec };
3614fb2969a3SJohan Hedberg 	const u8 n1[16] = {
3615fb2969a3SJohan Hedberg 			0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff,
3616fb2969a3SJohan Hedberg 			0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 };
3617fb2969a3SJohan Hedberg 	const u8 n2[16] = {
3618fb2969a3SJohan Hedberg 			0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21,
3619fb2969a3SJohan Hedberg 			0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6 };
3620fb2969a3SJohan Hedberg 	const u8 a1[7] = { 0xce, 0xbf, 0x37, 0x37, 0x12, 0x56, 0x00 };
3621fb2969a3SJohan Hedberg 	const u8 a2[7] = { 0xc1, 0xcf, 0x2d, 0x70, 0x13, 0xa7, 0x00 };
3622fb2969a3SJohan Hedberg 	const u8 exp_ltk[16] = {
3623fb2969a3SJohan Hedberg 			0x38, 0x0a, 0x75, 0x94, 0xb5, 0x22, 0x05, 0x98,
3624fb2969a3SJohan Hedberg 			0x23, 0xcd, 0xd7, 0x69, 0x11, 0x79, 0x86, 0x69 };
3625fb2969a3SJohan Hedberg 	const u8 exp_mackey[16] = {
3626fb2969a3SJohan Hedberg 			0x20, 0x6e, 0x63, 0xce, 0x20, 0x6a, 0x3f, 0xfd,
3627fb2969a3SJohan Hedberg 			0x02, 0x4a, 0x08, 0xa1, 0x76, 0xf1, 0x65, 0x29 };
3628fb2969a3SJohan Hedberg 	u8 mackey[16], ltk[16];
3629fb2969a3SJohan Hedberg 	int err;
3630fb2969a3SJohan Hedberg 
3631fb2969a3SJohan Hedberg 	err = smp_f5(tfm_cmac, w, n1, n2, a1, a2, mackey, ltk);
3632fb2969a3SJohan Hedberg 	if (err)
3633fb2969a3SJohan Hedberg 		return err;
3634fb2969a3SJohan Hedberg 
3635329d8230SJason A. Donenfeld 	if (crypto_memneq(mackey, exp_mackey, 16))
3636fb2969a3SJohan Hedberg 		return -EINVAL;
3637fb2969a3SJohan Hedberg 
3638329d8230SJason A. Donenfeld 	if (crypto_memneq(ltk, exp_ltk, 16))
3639fb2969a3SJohan Hedberg 		return -EINVAL;
3640fb2969a3SJohan Hedberg 
3641fb2969a3SJohan Hedberg 	return 0;
3642fb2969a3SJohan Hedberg }
3643fb2969a3SJohan Hedberg 
test_f6(struct crypto_shash * tfm_cmac)364471af2f6bSHerbert Xu static int __init test_f6(struct crypto_shash *tfm_cmac)
3645fb2969a3SJohan Hedberg {
3646fb2969a3SJohan Hedberg 	const u8 w[16] = {
3647fb2969a3SJohan Hedberg 			0x20, 0x6e, 0x63, 0xce, 0x20, 0x6a, 0x3f, 0xfd,
3648fb2969a3SJohan Hedberg 			0x02, 0x4a, 0x08, 0xa1, 0x76, 0xf1, 0x65, 0x29 };
3649fb2969a3SJohan Hedberg 	const u8 n1[16] = {
3650fb2969a3SJohan Hedberg 			0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff,
3651fb2969a3SJohan Hedberg 			0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 };
3652fb2969a3SJohan Hedberg 	const u8 n2[16] = {
3653fb2969a3SJohan Hedberg 			0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21,
3654fb2969a3SJohan Hedberg 			0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6 };
3655fb2969a3SJohan Hedberg 	const u8 r[16] = {
3656fb2969a3SJohan Hedberg 			0xc8, 0x0f, 0x2d, 0x0c, 0xd2, 0x42, 0xda, 0x08,
3657fb2969a3SJohan Hedberg 			0x54, 0xbb, 0x53, 0xb4, 0x3b, 0x34, 0xa3, 0x12 };
3658fb2969a3SJohan Hedberg 	const u8 io_cap[3] = { 0x02, 0x01, 0x01 };
3659fb2969a3SJohan Hedberg 	const u8 a1[7] = { 0xce, 0xbf, 0x37, 0x37, 0x12, 0x56, 0x00 };
3660fb2969a3SJohan Hedberg 	const u8 a2[7] = { 0xc1, 0xcf, 0x2d, 0x70, 0x13, 0xa7, 0x00 };
3661fb2969a3SJohan Hedberg 	const u8 exp[16] = {
3662fb2969a3SJohan Hedberg 			0x61, 0x8f, 0x95, 0xda, 0x09, 0x0b, 0x6c, 0xd2,
3663fb2969a3SJohan Hedberg 			0xc5, 0xe8, 0xd0, 0x9c, 0x98, 0x73, 0xc4, 0xe3 };
3664fb2969a3SJohan Hedberg 	u8 res[16];
3665fb2969a3SJohan Hedberg 	int err;
3666fb2969a3SJohan Hedberg 
3667fb2969a3SJohan Hedberg 	err = smp_f6(tfm_cmac, w, n1, n2, r, io_cap, a1, a2, res);
3668fb2969a3SJohan Hedberg 	if (err)
3669fb2969a3SJohan Hedberg 		return err;
3670fb2969a3SJohan Hedberg 
3671329d8230SJason A. Donenfeld 	if (crypto_memneq(res, exp, 16))
3672fb2969a3SJohan Hedberg 		return -EINVAL;
3673fb2969a3SJohan Hedberg 
3674fb2969a3SJohan Hedberg 	return 0;
3675fb2969a3SJohan Hedberg }
3676fb2969a3SJohan Hedberg 
test_g2(struct crypto_shash * tfm_cmac)367771af2f6bSHerbert Xu static int __init test_g2(struct crypto_shash *tfm_cmac)
3678fb2969a3SJohan Hedberg {
3679fb2969a3SJohan Hedberg 	const u8 u[32] = {
3680fb2969a3SJohan Hedberg 			0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc,
3681fb2969a3SJohan Hedberg 			0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef,
3682fb2969a3SJohan Hedberg 			0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e,
3683fb2969a3SJohan Hedberg 			0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20 };
3684fb2969a3SJohan Hedberg 	const u8 v[32] = {
3685fb2969a3SJohan Hedberg 			0xfd, 0xc5, 0x7f, 0xf4, 0x49, 0xdd, 0x4f, 0x6b,
3686fb2969a3SJohan Hedberg 			0xfb, 0x7c, 0x9d, 0xf1, 0xc2, 0x9a, 0xcb, 0x59,
3687fb2969a3SJohan Hedberg 			0x2a, 0xe7, 0xd4, 0xee, 0xfb, 0xfc, 0x0a, 0x90,
3688fb2969a3SJohan Hedberg 			0x9a, 0xbb, 0xf6, 0x32, 0x3d, 0x8b, 0x18, 0x55 };
3689fb2969a3SJohan Hedberg 	const u8 x[16] = {
3690fb2969a3SJohan Hedberg 			0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff,
3691fb2969a3SJohan Hedberg 			0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 };
3692fb2969a3SJohan Hedberg 	const u8 y[16] = {
3693fb2969a3SJohan Hedberg 			0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21,
3694fb2969a3SJohan Hedberg 			0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6 };
3695fb2969a3SJohan Hedberg 	const u32 exp_val = 0x2f9ed5ba % 1000000;
3696fb2969a3SJohan Hedberg 	u32 val;
3697fb2969a3SJohan Hedberg 	int err;
3698fb2969a3SJohan Hedberg 
3699fb2969a3SJohan Hedberg 	err = smp_g2(tfm_cmac, u, v, x, y, &val);
3700fb2969a3SJohan Hedberg 	if (err)
3701fb2969a3SJohan Hedberg 		return err;
3702fb2969a3SJohan Hedberg 
3703fb2969a3SJohan Hedberg 	if (val != exp_val)
3704fb2969a3SJohan Hedberg 		return -EINVAL;
3705fb2969a3SJohan Hedberg 
3706fb2969a3SJohan Hedberg 	return 0;
3707fb2969a3SJohan Hedberg }
3708fb2969a3SJohan Hedberg 
test_h6(struct crypto_shash * tfm_cmac)370971af2f6bSHerbert Xu static int __init test_h6(struct crypto_shash *tfm_cmac)
3710fb2969a3SJohan Hedberg {
3711fb2969a3SJohan Hedberg 	const u8 w[16] = {
3712fb2969a3SJohan Hedberg 			0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34,
3713fb2969a3SJohan Hedberg 			0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec };
3714fb2969a3SJohan Hedberg 	const u8 key_id[4] = { 0x72, 0x62, 0x65, 0x6c };
3715fb2969a3SJohan Hedberg 	const u8 exp[16] = {
3716fb2969a3SJohan Hedberg 			0x99, 0x63, 0xb1, 0x80, 0xe2, 0xa9, 0xd3, 0xe8,
3717fb2969a3SJohan Hedberg 			0x1c, 0xc9, 0x6d, 0xe7, 0x02, 0xe1, 0x9a, 0x2d };
3718fb2969a3SJohan Hedberg 	u8 res[16];
3719fb2969a3SJohan Hedberg 	int err;
3720fb2969a3SJohan Hedberg 
3721fb2969a3SJohan Hedberg 	err = smp_h6(tfm_cmac, w, key_id, res);
3722fb2969a3SJohan Hedberg 	if (err)
3723fb2969a3SJohan Hedberg 		return err;
3724fb2969a3SJohan Hedberg 
3725329d8230SJason A. Donenfeld 	if (crypto_memneq(res, exp, 16))
3726fb2969a3SJohan Hedberg 		return -EINVAL;
3727fb2969a3SJohan Hedberg 
3728fb2969a3SJohan Hedberg 	return 0;
3729fb2969a3SJohan Hedberg }
3730fb2969a3SJohan Hedberg 
373164dd374eSMarcel Holtmann static char test_smp_buffer[32];
373264dd374eSMarcel Holtmann 
test_smp_read(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)373364dd374eSMarcel Holtmann static ssize_t test_smp_read(struct file *file, char __user *user_buf,
373464dd374eSMarcel Holtmann 			     size_t count, loff_t *ppos)
373564dd374eSMarcel Holtmann {
373664dd374eSMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, test_smp_buffer,
373764dd374eSMarcel Holtmann 				       strlen(test_smp_buffer));
373864dd374eSMarcel Holtmann }
373964dd374eSMarcel Holtmann 
374064dd374eSMarcel Holtmann static const struct file_operations test_smp_fops = {
374164dd374eSMarcel Holtmann 	.open		= simple_open,
374264dd374eSMarcel Holtmann 	.read		= test_smp_read,
374364dd374eSMarcel Holtmann 	.llseek		= default_llseek,
374464dd374eSMarcel Holtmann };
374564dd374eSMarcel Holtmann 
run_selftests(struct crypto_shash * tfm_cmac,struct crypto_kpp * tfm_ecdh)374628a220aaSArd Biesheuvel static int __init run_selftests(struct crypto_shash *tfm_cmac,
374747eb2ac8STudor Ambarus 				struct crypto_kpp *tfm_ecdh)
37480a2b0f04SJohan Hedberg {
3749255047b0SMarcel Holtmann 	ktime_t calltime, delta, rettime;
3750255047b0SMarcel Holtmann 	unsigned long long duration;
3751cfc4198eSJohan Hedberg 	int err;
3752cfc4198eSJohan Hedberg 
3753255047b0SMarcel Holtmann 	calltime = ktime_get();
3754255047b0SMarcel Holtmann 
375547eb2ac8STudor Ambarus 	err = test_debug_key(tfm_ecdh);
375671653eb6SMarcel Holtmann 	if (err) {
375771653eb6SMarcel Holtmann 		BT_ERR("debug_key test failed");
375871653eb6SMarcel Holtmann 		goto done;
375971653eb6SMarcel Holtmann 	}
376071653eb6SMarcel Holtmann 
376128a220aaSArd Biesheuvel 	err = test_ah();
3762cfc4198eSJohan Hedberg 	if (err) {
3763cfc4198eSJohan Hedberg 		BT_ERR("smp_ah test failed");
376464dd374eSMarcel Holtmann 		goto done;
3765cfc4198eSJohan Hedberg 	}
3766cfc4198eSJohan Hedberg 
376728a220aaSArd Biesheuvel 	err = test_c1();
3768cfc4198eSJohan Hedberg 	if (err) {
3769cfc4198eSJohan Hedberg 		BT_ERR("smp_c1 test failed");
377064dd374eSMarcel Holtmann 		goto done;
3771cfc4198eSJohan Hedberg 	}
3772cfc4198eSJohan Hedberg 
377328a220aaSArd Biesheuvel 	err = test_s1();
3774cfc4198eSJohan Hedberg 	if (err) {
3775cfc4198eSJohan Hedberg 		BT_ERR("smp_s1 test failed");
377664dd374eSMarcel Holtmann 		goto done;
3777cfc4198eSJohan Hedberg 	}
3778cfc4198eSJohan Hedberg 
3779fb2969a3SJohan Hedberg 	err = test_f4(tfm_cmac);
3780fb2969a3SJohan Hedberg 	if (err) {
3781fb2969a3SJohan Hedberg 		BT_ERR("smp_f4 test failed");
378264dd374eSMarcel Holtmann 		goto done;
3783fb2969a3SJohan Hedberg 	}
3784fb2969a3SJohan Hedberg 
3785fb2969a3SJohan Hedberg 	err = test_f5(tfm_cmac);
3786fb2969a3SJohan Hedberg 	if (err) {
3787fb2969a3SJohan Hedberg 		BT_ERR("smp_f5 test failed");
378864dd374eSMarcel Holtmann 		goto done;
3789fb2969a3SJohan Hedberg 	}
3790fb2969a3SJohan Hedberg 
3791fb2969a3SJohan Hedberg 	err = test_f6(tfm_cmac);
3792fb2969a3SJohan Hedberg 	if (err) {
3793fb2969a3SJohan Hedberg 		BT_ERR("smp_f6 test failed");
379464dd374eSMarcel Holtmann 		goto done;
3795fb2969a3SJohan Hedberg 	}
3796fb2969a3SJohan Hedberg 
3797fb2969a3SJohan Hedberg 	err = test_g2(tfm_cmac);
3798fb2969a3SJohan Hedberg 	if (err) {
3799fb2969a3SJohan Hedberg 		BT_ERR("smp_g2 test failed");
380064dd374eSMarcel Holtmann 		goto done;
3801fb2969a3SJohan Hedberg 	}
3802fb2969a3SJohan Hedberg 
3803fb2969a3SJohan Hedberg 	err = test_h6(tfm_cmac);
3804fb2969a3SJohan Hedberg 	if (err) {
3805fb2969a3SJohan Hedberg 		BT_ERR("smp_h6 test failed");
380664dd374eSMarcel Holtmann 		goto done;
3807fb2969a3SJohan Hedberg 	}
3808fb2969a3SJohan Hedberg 
3809255047b0SMarcel Holtmann 	rettime = ktime_get();
3810255047b0SMarcel Holtmann 	delta = ktime_sub(rettime, calltime);
3811255047b0SMarcel Holtmann 	duration = (unsigned long long) ktime_to_ns(delta) >> 10;
3812255047b0SMarcel Holtmann 
38135ced2464SMarcel Holtmann 	BT_INFO("SMP test passed in %llu usecs", duration);
38140a2b0f04SJohan Hedberg 
381564dd374eSMarcel Holtmann done:
381664dd374eSMarcel Holtmann 	if (!err)
381764dd374eSMarcel Holtmann 		snprintf(test_smp_buffer, sizeof(test_smp_buffer),
381864dd374eSMarcel Holtmann 			 "PASS (%llu usecs)\n", duration);
381964dd374eSMarcel Holtmann 	else
382064dd374eSMarcel Holtmann 		snprintf(test_smp_buffer, sizeof(test_smp_buffer), "FAIL\n");
382164dd374eSMarcel Holtmann 
382264dd374eSMarcel Holtmann 	debugfs_create_file("selftest_smp", 0444, bt_debugfs, NULL,
382364dd374eSMarcel Holtmann 			    &test_smp_fops);
382464dd374eSMarcel Holtmann 
382564dd374eSMarcel Holtmann 	return err;
38260a2b0f04SJohan Hedberg }
38270a2b0f04SJohan Hedberg 
bt_selftest_smp(void)38280a2b0f04SJohan Hedberg int __init bt_selftest_smp(void)
38290a2b0f04SJohan Hedberg {
383071af2f6bSHerbert Xu 	struct crypto_shash *tfm_cmac;
383147eb2ac8STudor Ambarus 	struct crypto_kpp *tfm_ecdh;
38320a2b0f04SJohan Hedberg 	int err;
38330a2b0f04SJohan Hedberg 
38343d234b33SEric Biggers 	tfm_cmac = crypto_alloc_shash("cmac(aes)", 0, 0);
38350a2b0f04SJohan Hedberg 	if (IS_ERR(tfm_cmac)) {
38360a2b0f04SJohan Hedberg 		BT_ERR("Unable to create CMAC crypto context");
38370a2b0f04SJohan Hedberg 		return PTR_ERR(tfm_cmac);
38380a2b0f04SJohan Hedberg 	}
38390a2b0f04SJohan Hedberg 
38406763f5eaSMeng Yu 	tfm_ecdh = crypto_alloc_kpp("ecdh-nist-p256", 0, 0);
384147eb2ac8STudor Ambarus 	if (IS_ERR(tfm_ecdh)) {
384247eb2ac8STudor Ambarus 		BT_ERR("Unable to create ECDH crypto context");
384347eb2ac8STudor Ambarus 		crypto_free_shash(tfm_cmac);
384447eb2ac8STudor Ambarus 		return PTR_ERR(tfm_ecdh);
384547eb2ac8STudor Ambarus 	}
384647eb2ac8STudor Ambarus 
384728a220aaSArd Biesheuvel 	err = run_selftests(tfm_cmac, tfm_ecdh);
38480a2b0f04SJohan Hedberg 
384971af2f6bSHerbert Xu 	crypto_free_shash(tfm_cmac);
385047eb2ac8STudor Ambarus 	crypto_free_kpp(tfm_ecdh);
38510a2b0f04SJohan Hedberg 
38520a2b0f04SJohan Hedberg 	return err;
38530a2b0f04SJohan Hedberg }
38540a2b0f04SJohan Hedberg 
38550a2b0f04SJohan Hedberg #endif
3856