xref: /openbmc/linux/net/bluetooth/smp.c (revision fad646e1)
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 
61d7a5a11dSMarcel Holtmann #define AUTH_REQ_MASK(dev)	(hci_dev_test_flag(dev, HCI_SC_ENABLED) ? \
62a62da6f1SJohan Hedberg 				 0x3f : 0x07)
6388d3a8acSJohan Hedberg #define KEY_DIST_MASK		0x07
64065a13e2SJohan Hedberg 
65cbbbe3e2SJohan Hedberg /* Maximum message length that can be passed to aes_cmac */
66cbbbe3e2SJohan Hedberg #define CMAC_MSG_MAX	80
67cbbbe3e2SJohan Hedberg 
68533e35d4SJohan Hedberg enum {
69533e35d4SJohan Hedberg 	SMP_FLAG_TK_VALID,
70533e35d4SJohan Hedberg 	SMP_FLAG_CFM_PENDING,
71533e35d4SJohan Hedberg 	SMP_FLAG_MITM_AUTH,
72533e35d4SJohan Hedberg 	SMP_FLAG_COMPLETE,
73533e35d4SJohan Hedberg 	SMP_FLAG_INITIATOR,
7465668776SJohan Hedberg 	SMP_FLAG_SC,
75d8f8edbeSJohan Hedberg 	SMP_FLAG_REMOTE_PK,
76aeb7d461SJohan Hedberg 	SMP_FLAG_DEBUG_KEY,
7738606f14SJohan Hedberg 	SMP_FLAG_WAIT_USER,
78d3e54a87SJohan Hedberg 	SMP_FLAG_DHKEY_PENDING,
791a8bab4fSJohan Hedberg 	SMP_FLAG_REMOTE_OOB,
801a8bab4fSJohan Hedberg 	SMP_FLAG_LOCAL_OOB,
81a62da6f1SJohan Hedberg 	SMP_FLAG_CT2,
82533e35d4SJohan Hedberg };
834bc58f51SJohan Hedberg 
8488a479d9SMarcel Holtmann struct smp_dev {
8560a27d65SMarcel Holtmann 	/* Secure Connections OOB data */
8694f14e47SJohan Hedberg 	bool			local_oob;
8760a27d65SMarcel Holtmann 	u8			local_pk[64];
88fb334feeSMarcel Holtmann 	u8			local_rand[16];
8960a27d65SMarcel Holtmann 	bool			debug_key;
9060a27d65SMarcel Holtmann 
9171af2f6bSHerbert Xu 	struct crypto_shash	*tfm_cmac;
9247eb2ac8STudor Ambarus 	struct crypto_kpp	*tfm_ecdh;
9388a479d9SMarcel Holtmann };
9488a479d9SMarcel Holtmann 
954bc58f51SJohan Hedberg struct smp_chan {
964bc58f51SJohan Hedberg 	struct l2cap_conn	*conn;
97b68fda68SJohan Hedberg 	struct delayed_work	security_timer;
98b28b4943SJohan Hedberg 	unsigned long           allow_cmd; /* Bitmask of allowed commands */
99b68fda68SJohan Hedberg 
1004bc58f51SJohan Hedberg 	u8		preq[7]; /* SMP Pairing Request */
1014bc58f51SJohan Hedberg 	u8		prsp[7]; /* SMP Pairing Response */
1024bc58f51SJohan Hedberg 	u8		prnd[16]; /* SMP Pairing Random (local) */
1034bc58f51SJohan Hedberg 	u8		rrnd[16]; /* SMP Pairing Random (remote) */
1044bc58f51SJohan Hedberg 	u8		pcnf[16]; /* SMP Pairing Confirm */
1054bc58f51SJohan Hedberg 	u8		tk[16]; /* SMP Temporary Key */
106882fafadSJohan Hedberg 	u8		rr[16]; /* Remote OOB ra/rb value */
107882fafadSJohan Hedberg 	u8		lr[16]; /* Local OOB ra/rb value */
1084bc58f51SJohan Hedberg 	u8		enc_key_size;
1094bc58f51SJohan Hedberg 	u8		remote_key_dist;
1104bc58f51SJohan Hedberg 	bdaddr_t	id_addr;
1114bc58f51SJohan Hedberg 	u8		id_addr_type;
1124bc58f51SJohan Hedberg 	u8		irk[16];
1134bc58f51SJohan Hedberg 	struct smp_csrk	*csrk;
114*fad646e1SArchie Pusaka 	struct smp_csrk	*responder_csrk;
1154bc58f51SJohan Hedberg 	struct smp_ltk	*ltk;
116*fad646e1SArchie Pusaka 	struct smp_ltk	*responder_ltk;
1174bc58f51SJohan Hedberg 	struct smp_irk	*remote_irk;
1186a77083aSJohan Hedberg 	u8		*link_key;
1194a74d658SJohan Hedberg 	unsigned long	flags;
120783e0574SJohan Hedberg 	u8		method;
12138606f14SJohan Hedberg 	u8		passkey_round;
1226a7bd103SJohan Hedberg 
1233b19146dSJohan Hedberg 	/* Secure Connections variables */
1243b19146dSJohan Hedberg 	u8			local_pk[64];
125d8f8edbeSJohan Hedberg 	u8			remote_pk[64];
126d8f8edbeSJohan Hedberg 	u8			dhkey[32];
127760b018bSJohan Hedberg 	u8			mackey[16];
1283b19146dSJohan Hedberg 
12971af2f6bSHerbert Xu 	struct crypto_shash	*tfm_cmac;
13047eb2ac8STudor Ambarus 	struct crypto_kpp	*tfm_ecdh;
1314bc58f51SJohan Hedberg };
1324bc58f51SJohan Hedberg 
133aeb7d461SJohan Hedberg /* These debug key values are defined in the SMP section of the core
134aeb7d461SJohan Hedberg  * specification. debug_pk is the public debug key and debug_sk the
135aeb7d461SJohan Hedberg  * private debug key.
136aeb7d461SJohan Hedberg  */
137aeb7d461SJohan Hedberg static const u8 debug_pk[64] = {
138aeb7d461SJohan Hedberg 		0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc,
139aeb7d461SJohan Hedberg 		0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef,
140aeb7d461SJohan Hedberg 		0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e,
141aeb7d461SJohan Hedberg 		0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20,
142aeb7d461SJohan Hedberg 
143aeb7d461SJohan Hedberg 		0x8b, 0xd2, 0x89, 0x15, 0xd0, 0x8e, 0x1c, 0x74,
144aeb7d461SJohan Hedberg 		0x24, 0x30, 0xed, 0x8f, 0xc2, 0x45, 0x63, 0x76,
145aeb7d461SJohan Hedberg 		0x5c, 0x15, 0x52, 0x5a, 0xbf, 0x9a, 0x32, 0x63,
146aeb7d461SJohan Hedberg 		0x6d, 0xeb, 0x2a, 0x65, 0x49, 0x9c, 0x80, 0xdc,
147aeb7d461SJohan Hedberg };
148aeb7d461SJohan Hedberg 
149aeb7d461SJohan Hedberg static const u8 debug_sk[32] = {
150aeb7d461SJohan Hedberg 		0xbd, 0x1a, 0x3c, 0xcd, 0xa6, 0xb8, 0x99, 0x58,
151aeb7d461SJohan Hedberg 		0x99, 0xb7, 0x40, 0xeb, 0x7b, 0x60, 0xff, 0x4a,
152aeb7d461SJohan Hedberg 		0x50, 0x3f, 0x10, 0xd2, 0xe3, 0xb3, 0xc9, 0x74,
153aeb7d461SJohan Hedberg 		0x38, 0x5f, 0xc5, 0xa3, 0xd4, 0xf6, 0x49, 0x3f,
154aeb7d461SJohan Hedberg };
155aeb7d461SJohan Hedberg 
1568a2936f4SJohan Hedberg static inline void swap_buf(const u8 *src, u8 *dst, size_t len)
157d22ef0bcSAnderson Briglia {
1588a2936f4SJohan Hedberg 	size_t i;
159d22ef0bcSAnderson Briglia 
1608a2936f4SJohan Hedberg 	for (i = 0; i < len; i++)
1618a2936f4SJohan Hedberg 		dst[len - 1 - i] = src[i];
162d22ef0bcSAnderson Briglia }
163d22ef0bcSAnderson Briglia 
16406edf8deSJohan Hedberg /* The following functions map to the LE SC SMP crypto functions
16506edf8deSJohan Hedberg  * AES-CMAC, f4, f5, f6, g2 and h6.
16606edf8deSJohan Hedberg  */
16706edf8deSJohan Hedberg 
16871af2f6bSHerbert Xu static int aes_cmac(struct crypto_shash *tfm, const u8 k[16], const u8 *m,
169cbbbe3e2SJohan Hedberg 		    size_t len, u8 mac[16])
170cbbbe3e2SJohan Hedberg {
171cbbbe3e2SJohan Hedberg 	uint8_t tmp[16], mac_msb[16], msg_msb[CMAC_MSG_MAX];
172cbbbe3e2SJohan Hedberg 	int err;
173cbbbe3e2SJohan Hedberg 
174cbbbe3e2SJohan Hedberg 	if (len > CMAC_MSG_MAX)
175cbbbe3e2SJohan Hedberg 		return -EFBIG;
176cbbbe3e2SJohan Hedberg 
177cbbbe3e2SJohan Hedberg 	if (!tfm) {
178cbbbe3e2SJohan Hedberg 		BT_ERR("tfm %p", tfm);
179cbbbe3e2SJohan Hedberg 		return -EINVAL;
180cbbbe3e2SJohan Hedberg 	}
181cbbbe3e2SJohan Hedberg 
182cbbbe3e2SJohan Hedberg 	/* Swap key and message from LSB to MSB */
183cbbbe3e2SJohan Hedberg 	swap_buf(k, tmp, 16);
184cbbbe3e2SJohan Hedberg 	swap_buf(m, msg_msb, len);
185cbbbe3e2SJohan Hedberg 
186c7a3d57dSJohan Hedberg 	SMP_DBG("msg (len %zu) %*phN", len, (int) len, m);
187c7a3d57dSJohan Hedberg 	SMP_DBG("key %16phN", k);
188cbbbe3e2SJohan Hedberg 
18971af2f6bSHerbert Xu 	err = crypto_shash_setkey(tfm, tmp, 16);
190cbbbe3e2SJohan Hedberg 	if (err) {
191cbbbe3e2SJohan Hedberg 		BT_ERR("cipher setkey failed: %d", err);
192cbbbe3e2SJohan Hedberg 		return err;
193cbbbe3e2SJohan Hedberg 	}
194cbbbe3e2SJohan Hedberg 
195ec0bf6edSEric Biggers 	err = crypto_shash_tfm_digest(tfm, msg_msb, len, mac_msb);
196cbbbe3e2SJohan Hedberg 	if (err) {
19771af2f6bSHerbert Xu 		BT_ERR("Hash computation error %d", err);
198cbbbe3e2SJohan Hedberg 		return err;
199cbbbe3e2SJohan Hedberg 	}
200cbbbe3e2SJohan Hedberg 
201cbbbe3e2SJohan Hedberg 	swap_buf(mac_msb, mac, 16);
202cbbbe3e2SJohan Hedberg 
203c7a3d57dSJohan Hedberg 	SMP_DBG("mac %16phN", mac);
204cbbbe3e2SJohan Hedberg 
205cbbbe3e2SJohan Hedberg 	return 0;
206cbbbe3e2SJohan Hedberg }
207cbbbe3e2SJohan Hedberg 
20871af2f6bSHerbert Xu static int smp_f4(struct crypto_shash *tfm_cmac, const u8 u[32],
20971af2f6bSHerbert Xu 		  const u8 v[32], const u8 x[16], u8 z, u8 res[16])
210cbbbe3e2SJohan Hedberg {
211cbbbe3e2SJohan Hedberg 	u8 m[65];
212cbbbe3e2SJohan Hedberg 	int err;
213cbbbe3e2SJohan Hedberg 
214c7a3d57dSJohan Hedberg 	SMP_DBG("u %32phN", u);
215c7a3d57dSJohan Hedberg 	SMP_DBG("v %32phN", v);
216c7a3d57dSJohan Hedberg 	SMP_DBG("x %16phN z %02x", x, z);
217cbbbe3e2SJohan Hedberg 
218cbbbe3e2SJohan Hedberg 	m[0] = z;
219cbbbe3e2SJohan Hedberg 	memcpy(m + 1, v, 32);
220cbbbe3e2SJohan Hedberg 	memcpy(m + 33, u, 32);
221cbbbe3e2SJohan Hedberg 
222cbbbe3e2SJohan Hedberg 	err = aes_cmac(tfm_cmac, x, m, sizeof(m), res);
223cbbbe3e2SJohan Hedberg 	if (err)
224cbbbe3e2SJohan Hedberg 		return err;
225cbbbe3e2SJohan Hedberg 
226c7a3d57dSJohan Hedberg 	SMP_DBG("res %16phN", res);
227cbbbe3e2SJohan Hedberg 
228cbbbe3e2SJohan Hedberg 	return err;
229cbbbe3e2SJohan Hedberg }
230cbbbe3e2SJohan Hedberg 
23171af2f6bSHerbert Xu static int smp_f5(struct crypto_shash *tfm_cmac, const u8 w[32],
2324da50de8SJohan Hedberg 		  const u8 n1[16], const u8 n2[16], const u8 a1[7],
2334da50de8SJohan Hedberg 		  const u8 a2[7], u8 mackey[16], u8 ltk[16])
234760b018bSJohan Hedberg {
235760b018bSJohan Hedberg 	/* The btle, salt and length "magic" values are as defined in
236760b018bSJohan Hedberg 	 * the SMP section of the Bluetooth core specification. In ASCII
237760b018bSJohan Hedberg 	 * the btle value ends up being 'btle'. The salt is just a
238760b018bSJohan Hedberg 	 * random number whereas length is the value 256 in little
239760b018bSJohan Hedberg 	 * endian format.
240760b018bSJohan Hedberg 	 */
241760b018bSJohan Hedberg 	const u8 btle[4] = { 0x65, 0x6c, 0x74, 0x62 };
242760b018bSJohan Hedberg 	const u8 salt[16] = { 0xbe, 0x83, 0x60, 0x5a, 0xdb, 0x0b, 0x37, 0x60,
243760b018bSJohan Hedberg 			      0x38, 0xa5, 0xf5, 0xaa, 0x91, 0x83, 0x88, 0x6c };
244760b018bSJohan Hedberg 	const u8 length[2] = { 0x00, 0x01 };
245760b018bSJohan Hedberg 	u8 m[53], t[16];
246760b018bSJohan Hedberg 	int err;
247760b018bSJohan Hedberg 
248c7a3d57dSJohan Hedberg 	SMP_DBG("w %32phN", w);
249c7a3d57dSJohan Hedberg 	SMP_DBG("n1 %16phN n2 %16phN", n1, n2);
250c7a3d57dSJohan Hedberg 	SMP_DBG("a1 %7phN a2 %7phN", a1, a2);
251760b018bSJohan Hedberg 
252760b018bSJohan Hedberg 	err = aes_cmac(tfm_cmac, salt, w, 32, t);
253760b018bSJohan Hedberg 	if (err)
254760b018bSJohan Hedberg 		return err;
255760b018bSJohan Hedberg 
256c7a3d57dSJohan Hedberg 	SMP_DBG("t %16phN", t);
257760b018bSJohan Hedberg 
258760b018bSJohan Hedberg 	memcpy(m, length, 2);
259760b018bSJohan Hedberg 	memcpy(m + 2, a2, 7);
260760b018bSJohan Hedberg 	memcpy(m + 9, a1, 7);
261760b018bSJohan Hedberg 	memcpy(m + 16, n2, 16);
262760b018bSJohan Hedberg 	memcpy(m + 32, n1, 16);
263760b018bSJohan Hedberg 	memcpy(m + 48, btle, 4);
264760b018bSJohan Hedberg 
265760b018bSJohan Hedberg 	m[52] = 0; /* Counter */
266760b018bSJohan Hedberg 
267760b018bSJohan Hedberg 	err = aes_cmac(tfm_cmac, t, m, sizeof(m), mackey);
268760b018bSJohan Hedberg 	if (err)
269760b018bSJohan Hedberg 		return err;
270760b018bSJohan Hedberg 
271c7a3d57dSJohan Hedberg 	SMP_DBG("mackey %16phN", mackey);
272760b018bSJohan Hedberg 
273760b018bSJohan Hedberg 	m[52] = 1; /* Counter */
274760b018bSJohan Hedberg 
275760b018bSJohan Hedberg 	err = aes_cmac(tfm_cmac, t, m, sizeof(m), ltk);
276760b018bSJohan Hedberg 	if (err)
277760b018bSJohan Hedberg 		return err;
278760b018bSJohan Hedberg 
279c7a3d57dSJohan Hedberg 	SMP_DBG("ltk %16phN", ltk);
280760b018bSJohan Hedberg 
281760b018bSJohan Hedberg 	return 0;
282760b018bSJohan Hedberg }
283760b018bSJohan Hedberg 
28471af2f6bSHerbert Xu static int smp_f6(struct crypto_shash *tfm_cmac, const u8 w[16],
2854da50de8SJohan Hedberg 		  const u8 n1[16], const u8 n2[16], const u8 r[16],
286760b018bSJohan Hedberg 		  const u8 io_cap[3], const u8 a1[7], const u8 a2[7],
287760b018bSJohan Hedberg 		  u8 res[16])
288760b018bSJohan Hedberg {
289760b018bSJohan Hedberg 	u8 m[65];
290760b018bSJohan Hedberg 	int err;
291760b018bSJohan Hedberg 
292c7a3d57dSJohan Hedberg 	SMP_DBG("w %16phN", w);
293c7a3d57dSJohan Hedberg 	SMP_DBG("n1 %16phN n2 %16phN", n1, n2);
294c7a3d57dSJohan Hedberg 	SMP_DBG("r %16phN io_cap %3phN a1 %7phN a2 %7phN", r, io_cap, a1, a2);
295760b018bSJohan Hedberg 
296760b018bSJohan Hedberg 	memcpy(m, a2, 7);
297760b018bSJohan Hedberg 	memcpy(m + 7, a1, 7);
298760b018bSJohan Hedberg 	memcpy(m + 14, io_cap, 3);
299760b018bSJohan Hedberg 	memcpy(m + 17, r, 16);
300760b018bSJohan Hedberg 	memcpy(m + 33, n2, 16);
301760b018bSJohan Hedberg 	memcpy(m + 49, n1, 16);
302760b018bSJohan Hedberg 
303760b018bSJohan Hedberg 	err = aes_cmac(tfm_cmac, w, m, sizeof(m), res);
304760b018bSJohan Hedberg 	if (err)
305760b018bSJohan Hedberg 		return err;
306760b018bSJohan Hedberg 
307203de21bSMarcel Holtmann 	SMP_DBG("res %16phN", res);
308760b018bSJohan Hedberg 
309760b018bSJohan Hedberg 	return err;
310760b018bSJohan Hedberg }
311760b018bSJohan Hedberg 
31271af2f6bSHerbert Xu static int smp_g2(struct crypto_shash *tfm_cmac, const u8 u[32], const u8 v[32],
313191dc7feSJohan Hedberg 		  const u8 x[16], const u8 y[16], u32 *val)
314191dc7feSJohan Hedberg {
315191dc7feSJohan Hedberg 	u8 m[80], tmp[16];
316191dc7feSJohan Hedberg 	int err;
317191dc7feSJohan Hedberg 
318c7a3d57dSJohan Hedberg 	SMP_DBG("u %32phN", u);
319c7a3d57dSJohan Hedberg 	SMP_DBG("v %32phN", v);
320c7a3d57dSJohan Hedberg 	SMP_DBG("x %16phN y %16phN", x, y);
321191dc7feSJohan Hedberg 
322191dc7feSJohan Hedberg 	memcpy(m, y, 16);
323191dc7feSJohan Hedberg 	memcpy(m + 16, v, 32);
324191dc7feSJohan Hedberg 	memcpy(m + 48, u, 32);
325191dc7feSJohan Hedberg 
326191dc7feSJohan Hedberg 	err = aes_cmac(tfm_cmac, x, m, sizeof(m), tmp);
327191dc7feSJohan Hedberg 	if (err)
328191dc7feSJohan Hedberg 		return err;
329191dc7feSJohan Hedberg 
330191dc7feSJohan Hedberg 	*val = get_unaligned_le32(tmp);
331191dc7feSJohan Hedberg 	*val %= 1000000;
332191dc7feSJohan Hedberg 
333c7a3d57dSJohan Hedberg 	SMP_DBG("val %06u", *val);
334191dc7feSJohan Hedberg 
335191dc7feSJohan Hedberg 	return 0;
336191dc7feSJohan Hedberg }
337191dc7feSJohan Hedberg 
33871af2f6bSHerbert Xu static int smp_h6(struct crypto_shash *tfm_cmac, const u8 w[16],
33906edf8deSJohan Hedberg 		  const u8 key_id[4], u8 res[16])
34006edf8deSJohan Hedberg {
34106edf8deSJohan Hedberg 	int err;
34206edf8deSJohan Hedberg 
34306edf8deSJohan Hedberg 	SMP_DBG("w %16phN key_id %4phN", w, key_id);
34406edf8deSJohan Hedberg 
34506edf8deSJohan Hedberg 	err = aes_cmac(tfm_cmac, w, key_id, 4, res);
34606edf8deSJohan Hedberg 	if (err)
34706edf8deSJohan Hedberg 		return err;
34806edf8deSJohan Hedberg 
34906edf8deSJohan Hedberg 	SMP_DBG("res %16phN", res);
35006edf8deSJohan Hedberg 
35106edf8deSJohan Hedberg 	return err;
35206edf8deSJohan Hedberg }
35306edf8deSJohan Hedberg 
354a62da6f1SJohan Hedberg static int smp_h7(struct crypto_shash *tfm_cmac, const u8 w[16],
355a62da6f1SJohan Hedberg 		  const u8 salt[16], u8 res[16])
356a62da6f1SJohan Hedberg {
357a62da6f1SJohan Hedberg 	int err;
358a62da6f1SJohan Hedberg 
359a62da6f1SJohan Hedberg 	SMP_DBG("w %16phN salt %16phN", w, salt);
360a62da6f1SJohan Hedberg 
361a62da6f1SJohan Hedberg 	err = aes_cmac(tfm_cmac, salt, w, 16, res);
362a62da6f1SJohan Hedberg 	if (err)
363a62da6f1SJohan Hedberg 		return err;
364a62da6f1SJohan Hedberg 
365a62da6f1SJohan Hedberg 	SMP_DBG("res %16phN", res);
366a62da6f1SJohan Hedberg 
367a62da6f1SJohan Hedberg 	return err;
368a62da6f1SJohan Hedberg }
369a62da6f1SJohan Hedberg 
37006edf8deSJohan Hedberg /* The following functions map to the legacy SMP crypto functions e, c1,
37106edf8deSJohan Hedberg  * s1 and ah.
37206edf8deSJohan Hedberg  */
37306edf8deSJohan Hedberg 
37428a220aaSArd Biesheuvel static int smp_e(const u8 *k, u8 *r)
375d22ef0bcSAnderson Briglia {
37628a220aaSArd Biesheuvel 	struct crypto_aes_ctx ctx;
377943a732aSJohan Hedberg 	uint8_t tmp[16], data[16];
378201a5929SJohan Hedberg 	int err;
379d22ef0bcSAnderson Briglia 
380011c391aSJohan Hedberg 	SMP_DBG("k %16phN r %16phN", k, r);
381011c391aSJohan Hedberg 
382943a732aSJohan Hedberg 	/* The most significant octet of key corresponds to k[0] */
3838a2936f4SJohan Hedberg 	swap_buf(k, tmp, 16);
384943a732aSJohan Hedberg 
38528a220aaSArd Biesheuvel 	err = aes_expandkey(&ctx, tmp, 16);
386d22ef0bcSAnderson Briglia 	if (err) {
387d22ef0bcSAnderson Briglia 		BT_ERR("cipher setkey failed: %d", err);
388d22ef0bcSAnderson Briglia 		return err;
389d22ef0bcSAnderson Briglia 	}
390d22ef0bcSAnderson Briglia 
391943a732aSJohan Hedberg 	/* Most significant octet of plaintextData corresponds to data[0] */
3928a2936f4SJohan Hedberg 	swap_buf(r, data, 16);
393943a732aSJohan Hedberg 
39428a220aaSArd Biesheuvel 	aes_encrypt(&ctx, data, data);
395d22ef0bcSAnderson Briglia 
396943a732aSJohan Hedberg 	/* Most significant octet of encryptedData corresponds to data[0] */
3978a2936f4SJohan Hedberg 	swap_buf(data, r, 16);
398943a732aSJohan Hedberg 
399011c391aSJohan Hedberg 	SMP_DBG("r %16phN", r);
400011c391aSJohan Hedberg 
40128a220aaSArd Biesheuvel 	memzero_explicit(&ctx, sizeof(ctx));
402d22ef0bcSAnderson Briglia 	return err;
403d22ef0bcSAnderson Briglia }
404d22ef0bcSAnderson Briglia 
40528a220aaSArd Biesheuvel static int smp_c1(const u8 k[16],
40606edf8deSJohan Hedberg 		  const u8 r[16], const u8 preq[7], const u8 pres[7], u8 _iat,
40706edf8deSJohan Hedberg 		  const bdaddr_t *ia, u8 _rat, const bdaddr_t *ra, u8 res[16])
40806edf8deSJohan Hedberg {
40906edf8deSJohan Hedberg 	u8 p1[16], p2[16];
41006edf8deSJohan Hedberg 	int err;
41106edf8deSJohan Hedberg 
412011c391aSJohan Hedberg 	SMP_DBG("k %16phN r %16phN", k, r);
413011c391aSJohan Hedberg 	SMP_DBG("iat %u ia %6phN rat %u ra %6phN", _iat, ia, _rat, ra);
414011c391aSJohan Hedberg 	SMP_DBG("preq %7phN pres %7phN", preq, pres);
415011c391aSJohan Hedberg 
41606edf8deSJohan Hedberg 	memset(p1, 0, 16);
41706edf8deSJohan Hedberg 
41806edf8deSJohan Hedberg 	/* p1 = pres || preq || _rat || _iat */
41906edf8deSJohan Hedberg 	p1[0] = _iat;
42006edf8deSJohan Hedberg 	p1[1] = _rat;
42106edf8deSJohan Hedberg 	memcpy(p1 + 2, preq, 7);
42206edf8deSJohan Hedberg 	memcpy(p1 + 9, pres, 7);
42306edf8deSJohan Hedberg 
424011c391aSJohan Hedberg 	SMP_DBG("p1 %16phN", p1);
42506edf8deSJohan Hedberg 
42606edf8deSJohan Hedberg 	/* res = r XOR p1 */
427ef0bb5adSArd Biesheuvel 	crypto_xor_cpy(res, r, p1, sizeof(p1));
42806edf8deSJohan Hedberg 
42906edf8deSJohan Hedberg 	/* res = e(k, res) */
43028a220aaSArd Biesheuvel 	err = smp_e(k, res);
43106edf8deSJohan Hedberg 	if (err) {
43206edf8deSJohan Hedberg 		BT_ERR("Encrypt data error");
43306edf8deSJohan Hedberg 		return err;
43406edf8deSJohan Hedberg 	}
43506edf8deSJohan Hedberg 
436011c391aSJohan Hedberg 	/* p2 = padding || ia || ra */
437011c391aSJohan Hedberg 	memcpy(p2, ra, 6);
438011c391aSJohan Hedberg 	memcpy(p2 + 6, ia, 6);
439011c391aSJohan Hedberg 	memset(p2 + 12, 0, 4);
440011c391aSJohan Hedberg 
441011c391aSJohan Hedberg 	SMP_DBG("p2 %16phN", p2);
442011c391aSJohan Hedberg 
44306edf8deSJohan Hedberg 	/* res = res XOR p2 */
444ef0bb5adSArd Biesheuvel 	crypto_xor(res, p2, sizeof(p2));
44506edf8deSJohan Hedberg 
44606edf8deSJohan Hedberg 	/* res = e(k, res) */
44728a220aaSArd Biesheuvel 	err = smp_e(k, res);
44806edf8deSJohan Hedberg 	if (err)
44906edf8deSJohan Hedberg 		BT_ERR("Encrypt data error");
45006edf8deSJohan Hedberg 
45106edf8deSJohan Hedberg 	return err;
45206edf8deSJohan Hedberg }
45306edf8deSJohan Hedberg 
45428a220aaSArd Biesheuvel static int smp_s1(const u8 k[16],
45506edf8deSJohan Hedberg 		  const u8 r1[16], const u8 r2[16], u8 _r[16])
4566a77083aSJohan Hedberg {
4576a77083aSJohan Hedberg 	int err;
4586a77083aSJohan Hedberg 
45906edf8deSJohan Hedberg 	/* Just least significant octets from r1 and r2 are considered */
46006edf8deSJohan Hedberg 	memcpy(_r, r2, 8);
46106edf8deSJohan Hedberg 	memcpy(_r + 8, r1, 8);
4626a77083aSJohan Hedberg 
46328a220aaSArd Biesheuvel 	err = smp_e(k, _r);
4646a77083aSJohan Hedberg 	if (err)
46506edf8deSJohan Hedberg 		BT_ERR("Encrypt data error");
4666a77083aSJohan Hedberg 
4676a77083aSJohan Hedberg 	return err;
4686a77083aSJohan Hedberg }
4696a77083aSJohan Hedberg 
47028a220aaSArd Biesheuvel static int smp_ah(const u8 irk[16], const u8 r[3], u8 res[3])
47160478054SJohan Hedberg {
472943a732aSJohan Hedberg 	u8 _res[16];
47360478054SJohan Hedberg 	int err;
47460478054SJohan Hedberg 
47560478054SJohan Hedberg 	/* r' = padding || r */
476943a732aSJohan Hedberg 	memcpy(_res, r, 3);
477943a732aSJohan Hedberg 	memset(_res + 3, 0, 13);
47860478054SJohan Hedberg 
47928a220aaSArd Biesheuvel 	err = smp_e(irk, _res);
48060478054SJohan Hedberg 	if (err) {
48160478054SJohan Hedberg 		BT_ERR("Encrypt error");
48260478054SJohan Hedberg 		return err;
48360478054SJohan Hedberg 	}
48460478054SJohan Hedberg 
48560478054SJohan Hedberg 	/* The output of the random address function ah is:
486c5080d42SMarcel Holtmann 	 *	ah(k, r) = e(k, r') mod 2^24
48760478054SJohan Hedberg 	 * The output of the security function e is then truncated to 24 bits
48860478054SJohan Hedberg 	 * by taking the least significant 24 bits of the output of e as the
48960478054SJohan Hedberg 	 * result of ah.
49060478054SJohan Hedberg 	 */
491943a732aSJohan Hedberg 	memcpy(res, _res, 3);
49260478054SJohan Hedberg 
49360478054SJohan Hedberg 	return 0;
49460478054SJohan Hedberg }
49560478054SJohan Hedberg 
496cd082797SJohan Hedberg bool smp_irk_matches(struct hci_dev *hdev, const u8 irk[16],
497cd082797SJohan Hedberg 		     const bdaddr_t *bdaddr)
49860478054SJohan Hedberg {
499defce9e8SJohan Hedberg 	struct l2cap_chan *chan = hdev->smp_data;
50060478054SJohan Hedberg 	u8 hash[3];
50160478054SJohan Hedberg 	int err;
50260478054SJohan Hedberg 
503defce9e8SJohan Hedberg 	if (!chan || !chan->data)
504defce9e8SJohan Hedberg 		return false;
505defce9e8SJohan Hedberg 
50656860245SMarcel Holtmann 	bt_dev_dbg(hdev, "RPA %pMR IRK %*phN", bdaddr, 16, irk);
50760478054SJohan Hedberg 
50828a220aaSArd Biesheuvel 	err = smp_ah(irk, &bdaddr->b[3], hash);
50960478054SJohan Hedberg 	if (err)
51060478054SJohan Hedberg 		return false;
51160478054SJohan Hedberg 
512329d8230SJason A. Donenfeld 	return !crypto_memneq(bdaddr->b, hash, 3);
51360478054SJohan Hedberg }
51460478054SJohan Hedberg 
515cd082797SJohan Hedberg int smp_generate_rpa(struct hci_dev *hdev, const u8 irk[16], bdaddr_t *rpa)
516b1e2b3aeSJohan Hedberg {
517defce9e8SJohan Hedberg 	struct l2cap_chan *chan = hdev->smp_data;
518b1e2b3aeSJohan Hedberg 	int err;
519b1e2b3aeSJohan Hedberg 
520defce9e8SJohan Hedberg 	if (!chan || !chan->data)
521defce9e8SJohan Hedberg 		return -EOPNOTSUPP;
522defce9e8SJohan Hedberg 
523b1e2b3aeSJohan Hedberg 	get_random_bytes(&rpa->b[3], 3);
524b1e2b3aeSJohan Hedberg 
525b1e2b3aeSJohan Hedberg 	rpa->b[5] &= 0x3f;	/* Clear two most significant bits */
526b1e2b3aeSJohan Hedberg 	rpa->b[5] |= 0x40;	/* Set second most significant bit */
527b1e2b3aeSJohan Hedberg 
52828a220aaSArd Biesheuvel 	err = smp_ah(irk, &rpa->b[3], rpa->b);
529b1e2b3aeSJohan Hedberg 	if (err < 0)
530b1e2b3aeSJohan Hedberg 		return err;
531b1e2b3aeSJohan Hedberg 
53256860245SMarcel Holtmann 	bt_dev_dbg(hdev, "RPA %pMR", rpa);
533b1e2b3aeSJohan Hedberg 
534b1e2b3aeSJohan Hedberg 	return 0;
535b1e2b3aeSJohan Hedberg }
536b1e2b3aeSJohan Hedberg 
53760a27d65SMarcel Holtmann int smp_generate_oob(struct hci_dev *hdev, u8 hash[16], u8 rand[16])
53860a27d65SMarcel Holtmann {
53960a27d65SMarcel Holtmann 	struct l2cap_chan *chan = hdev->smp_data;
54060a27d65SMarcel Holtmann 	struct smp_dev *smp;
54160a27d65SMarcel Holtmann 	int err;
54260a27d65SMarcel Holtmann 
54360a27d65SMarcel Holtmann 	if (!chan || !chan->data)
54460a27d65SMarcel Holtmann 		return -EOPNOTSUPP;
54560a27d65SMarcel Holtmann 
54660a27d65SMarcel Holtmann 	smp = chan->data;
54760a27d65SMarcel Holtmann 
54860a27d65SMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS)) {
54956860245SMarcel Holtmann 		bt_dev_dbg(hdev, "Using debug keys");
550c0153b0bSTudor Ambarus 		err = set_ecdh_privkey(smp->tfm_ecdh, debug_sk);
551c0153b0bSTudor Ambarus 		if (err)
552c0153b0bSTudor Ambarus 			return err;
55360a27d65SMarcel Holtmann 		memcpy(smp->local_pk, debug_pk, 64);
55460a27d65SMarcel Holtmann 		smp->debug_key = true;
55560a27d65SMarcel Holtmann 	} else {
55660a27d65SMarcel Holtmann 		while (true) {
557c0153b0bSTudor Ambarus 			/* Generate key pair for Secure Connections */
558c0153b0bSTudor Ambarus 			err = generate_ecdh_keys(smp->tfm_ecdh, smp->local_pk);
559a2976416STudor Ambarus 			if (err)
560a2976416STudor Ambarus 				return err;
56160a27d65SMarcel Holtmann 
56260a27d65SMarcel Holtmann 			/* This is unlikely, but we need to check that
56391641b79SZheng Yongjun 			 * we didn't accidentally generate a debug key.
56460a27d65SMarcel Holtmann 			 */
565c0153b0bSTudor Ambarus 			if (crypto_memneq(smp->local_pk, debug_pk, 64))
56660a27d65SMarcel Holtmann 				break;
56760a27d65SMarcel Holtmann 		}
56860a27d65SMarcel Holtmann 		smp->debug_key = false;
56960a27d65SMarcel Holtmann 	}
57060a27d65SMarcel Holtmann 
57160a27d65SMarcel Holtmann 	SMP_DBG("OOB Public Key X: %32phN", smp->local_pk);
57260a27d65SMarcel Holtmann 	SMP_DBG("OOB Public Key Y: %32phN", smp->local_pk + 32);
57360a27d65SMarcel Holtmann 
574fb334feeSMarcel Holtmann 	get_random_bytes(smp->local_rand, 16);
57560a27d65SMarcel Holtmann 
57660a27d65SMarcel Holtmann 	err = smp_f4(smp->tfm_cmac, smp->local_pk, smp->local_pk,
577fb334feeSMarcel Holtmann 		     smp->local_rand, 0, hash);
57860a27d65SMarcel Holtmann 	if (err < 0)
57960a27d65SMarcel Holtmann 		return err;
58060a27d65SMarcel Holtmann 
581fb334feeSMarcel Holtmann 	memcpy(rand, smp->local_rand, 16);
58260a27d65SMarcel Holtmann 
58394f14e47SJohan Hedberg 	smp->local_oob = true;
58494f14e47SJohan Hedberg 
58560a27d65SMarcel Holtmann 	return 0;
58660a27d65SMarcel Holtmann }
58760a27d65SMarcel Holtmann 
588eb492e01SAnderson Briglia static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
589eb492e01SAnderson Briglia {
5905d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
591b68fda68SJohan Hedberg 	struct smp_chan *smp;
5925d88cc73SJohan Hedberg 	struct kvec iv[2];
5935d88cc73SJohan Hedberg 	struct msghdr msg;
5945d88cc73SJohan Hedberg 
5955d88cc73SJohan Hedberg 	if (!chan)
5965d88cc73SJohan Hedberg 		return;
597eb492e01SAnderson Briglia 
5982e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(conn->hcon->hdev, "code 0x%2.2x", code);
599eb492e01SAnderson Briglia 
6005d88cc73SJohan Hedberg 	iv[0].iov_base = &code;
6015d88cc73SJohan Hedberg 	iv[0].iov_len = 1;
602eb492e01SAnderson Briglia 
6035d88cc73SJohan Hedberg 	iv[1].iov_base = data;
6045d88cc73SJohan Hedberg 	iv[1].iov_len = len;
6055d88cc73SJohan Hedberg 
6065d88cc73SJohan Hedberg 	memset(&msg, 0, sizeof(msg));
6075d88cc73SJohan Hedberg 
608aa563d7bSDavid Howells 	iov_iter_kvec(&msg.msg_iter, WRITE, iv, 2, 1 + len);
6095d88cc73SJohan Hedberg 
6105d88cc73SJohan Hedberg 	l2cap_chan_send(chan, &msg, 1 + len);
611e2dcd113SVinicius Costa Gomes 
612b68fda68SJohan Hedberg 	if (!chan->data)
613b68fda68SJohan Hedberg 		return;
614b68fda68SJohan Hedberg 
615b68fda68SJohan Hedberg 	smp = chan->data;
616b68fda68SJohan Hedberg 
617b68fda68SJohan Hedberg 	cancel_delayed_work_sync(&smp->security_timer);
618b68fda68SJohan Hedberg 	schedule_delayed_work(&smp->security_timer, SMP_TIMEOUT);
619eb492e01SAnderson Briglia }
620eb492e01SAnderson Briglia 
621d2eb9e10SJohan Hedberg static u8 authreq_to_seclevel(u8 authreq)
6222b64d153SBrian Gix {
623d2eb9e10SJohan Hedberg 	if (authreq & SMP_AUTH_MITM) {
624d2eb9e10SJohan Hedberg 		if (authreq & SMP_AUTH_SC)
625d2eb9e10SJohan Hedberg 			return BT_SECURITY_FIPS;
6262b64d153SBrian Gix 		else
627d2eb9e10SJohan Hedberg 			return BT_SECURITY_HIGH;
628d2eb9e10SJohan Hedberg 	} else {
6292b64d153SBrian Gix 		return BT_SECURITY_MEDIUM;
6302b64d153SBrian Gix 	}
631d2eb9e10SJohan Hedberg }
6322b64d153SBrian Gix 
6332b64d153SBrian Gix static __u8 seclevel_to_authreq(__u8 sec_level)
6342b64d153SBrian Gix {
6352b64d153SBrian Gix 	switch (sec_level) {
636d2eb9e10SJohan Hedberg 	case BT_SECURITY_FIPS:
6372b64d153SBrian Gix 	case BT_SECURITY_HIGH:
6382b64d153SBrian Gix 		return SMP_AUTH_MITM | SMP_AUTH_BONDING;
6392b64d153SBrian Gix 	case BT_SECURITY_MEDIUM:
6402b64d153SBrian Gix 		return SMP_AUTH_BONDING;
6412b64d153SBrian Gix 	default:
6422b64d153SBrian Gix 		return SMP_AUTH_NONE;
6432b64d153SBrian Gix 	}
6442b64d153SBrian Gix }
6452b64d153SBrian Gix 
646b8e66eacSVinicius Costa Gomes static void build_pairing_cmd(struct l2cap_conn *conn,
64754790f73SVinicius Costa Gomes 			      struct smp_cmd_pairing *req,
648f1560463SMarcel Holtmann 			      struct smp_cmd_pairing *rsp, __u8 authreq)
649b8e66eacSVinicius Costa Gomes {
6505d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
6515d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
652fd349c02SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
653fd349c02SJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
65402b05bd8SJohan Hedberg 	u8 local_dist = 0, remote_dist = 0, oob_flag = SMP_OOB_NOT_PRESENT;
65554790f73SVinicius Costa Gomes 
656d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_BONDABLE)) {
6577ee4ea36SMarcel Holtmann 		local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
6587ee4ea36SMarcel Holtmann 		remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
65954790f73SVinicius Costa Gomes 		authreq |= SMP_AUTH_BONDING;
6602b64d153SBrian Gix 	} else {
6612b64d153SBrian Gix 		authreq &= ~SMP_AUTH_BONDING;
66254790f73SVinicius Costa Gomes 	}
66354790f73SVinicius Costa Gomes 
664d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_RPA_RESOLVING))
665fd349c02SJohan Hedberg 		remote_dist |= SMP_DIST_ID_KEY;
666fd349c02SJohan Hedberg 
667d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_PRIVACY))
668863efaf2SJohan Hedberg 		local_dist |= SMP_DIST_ID_KEY;
669863efaf2SJohan Hedberg 
670d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SC_ENABLED) &&
67102b05bd8SJohan Hedberg 	    (authreq & SMP_AUTH_SC)) {
67202b05bd8SJohan Hedberg 		struct oob_data *oob_data;
67302b05bd8SJohan Hedberg 		u8 bdaddr_type;
67402b05bd8SJohan Hedberg 
675d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_SSP_ENABLED)) {
676df8e1a4cSJohan Hedberg 			local_dist |= SMP_DIST_LINK_KEY;
677df8e1a4cSJohan Hedberg 			remote_dist |= SMP_DIST_LINK_KEY;
678df8e1a4cSJohan Hedberg 		}
67902b05bd8SJohan Hedberg 
68002b05bd8SJohan Hedberg 		if (hcon->dst_type == ADDR_LE_DEV_PUBLIC)
68102b05bd8SJohan Hedberg 			bdaddr_type = BDADDR_LE_PUBLIC;
68202b05bd8SJohan Hedberg 		else
68302b05bd8SJohan Hedberg 			bdaddr_type = BDADDR_LE_RANDOM;
68402b05bd8SJohan Hedberg 
68502b05bd8SJohan Hedberg 		oob_data = hci_find_remote_oob_data(hdev, &hcon->dst,
68602b05bd8SJohan Hedberg 						    bdaddr_type);
6874775a4eaSMarcel Holtmann 		if (oob_data && oob_data->present) {
6881a8bab4fSJohan Hedberg 			set_bit(SMP_FLAG_REMOTE_OOB, &smp->flags);
68902b05bd8SJohan Hedberg 			oob_flag = SMP_OOB_PRESENT;
690a29b0733SJohan Hedberg 			memcpy(smp->rr, oob_data->rand256, 16);
69102b05bd8SJohan Hedberg 			memcpy(smp->pcnf, oob_data->hash256, 16);
692bc07cd69SMarcel Holtmann 			SMP_DBG("OOB Remote Confirmation: %16phN", smp->pcnf);
693bc07cd69SMarcel Holtmann 			SMP_DBG("OOB Remote Random: %16phN", smp->rr);
69402b05bd8SJohan Hedberg 		}
69502b05bd8SJohan Hedberg 
696df8e1a4cSJohan Hedberg 	} else {
697df8e1a4cSJohan Hedberg 		authreq &= ~SMP_AUTH_SC;
698df8e1a4cSJohan Hedberg 	}
699df8e1a4cSJohan Hedberg 
70054790f73SVinicius Costa Gomes 	if (rsp == NULL) {
70154790f73SVinicius Costa Gomes 		req->io_capability = conn->hcon->io_capability;
70202b05bd8SJohan Hedberg 		req->oob_flag = oob_flag;
70330d65e08SMatias Karhumaa 		req->max_key_size = hdev->le_max_key_size;
704fd349c02SJohan Hedberg 		req->init_key_dist = local_dist;
705fd349c02SJohan Hedberg 		req->resp_key_dist = remote_dist;
7060edb14deSJohan Hedberg 		req->auth_req = (authreq & AUTH_REQ_MASK(hdev));
707fd349c02SJohan Hedberg 
708fd349c02SJohan Hedberg 		smp->remote_key_dist = remote_dist;
70954790f73SVinicius Costa Gomes 		return;
71054790f73SVinicius Costa Gomes 	}
71154790f73SVinicius Costa Gomes 
71254790f73SVinicius Costa Gomes 	rsp->io_capability = conn->hcon->io_capability;
71302b05bd8SJohan Hedberg 	rsp->oob_flag = oob_flag;
71430d65e08SMatias Karhumaa 	rsp->max_key_size = hdev->le_max_key_size;
715fd349c02SJohan Hedberg 	rsp->init_key_dist = req->init_key_dist & remote_dist;
716fd349c02SJohan Hedberg 	rsp->resp_key_dist = req->resp_key_dist & local_dist;
7170edb14deSJohan Hedberg 	rsp->auth_req = (authreq & AUTH_REQ_MASK(hdev));
718fd349c02SJohan Hedberg 
719fd349c02SJohan Hedberg 	smp->remote_key_dist = rsp->init_key_dist;
720b8e66eacSVinicius Costa Gomes }
721b8e66eacSVinicius Costa Gomes 
7223158c50cSVinicius Costa Gomes static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
7233158c50cSVinicius Costa Gomes {
7245d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
7252fd36558SJohan Hedberg 	struct hci_dev *hdev = conn->hcon->hdev;
7265d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
7271c1def09SVinicius Costa Gomes 
72849c06c9eSŁukasz Rymanowski 	if (conn->hcon->pending_sec_level == BT_SECURITY_FIPS &&
72949c06c9eSŁukasz Rymanowski 	    max_key_size != SMP_MAX_ENC_KEY_SIZE)
73049c06c9eSŁukasz Rymanowski 		return SMP_ENC_KEY_SIZE;
73149c06c9eSŁukasz Rymanowski 
73230d65e08SMatias Karhumaa 	if (max_key_size > hdev->le_max_key_size ||
7332fd36558SJohan Hedberg 	    max_key_size < SMP_MIN_ENC_KEY_SIZE)
7343158c50cSVinicius Costa Gomes 		return SMP_ENC_KEY_SIZE;
7353158c50cSVinicius Costa Gomes 
736f7aa611aSVinicius Costa Gomes 	smp->enc_key_size = max_key_size;
7373158c50cSVinicius Costa Gomes 
7383158c50cSVinicius Costa Gomes 	return 0;
7393158c50cSVinicius Costa Gomes }
7403158c50cSVinicius Costa Gomes 
7416f48e260SJohan Hedberg static void smp_chan_destroy(struct l2cap_conn *conn)
7426f48e260SJohan Hedberg {
7436f48e260SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
7446f48e260SJohan Hedberg 	struct smp_chan *smp = chan->data;
745923e2414SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
7466f48e260SJohan Hedberg 	bool complete;
7476f48e260SJohan Hedberg 
7486f48e260SJohan Hedberg 	BUG_ON(!smp);
7496f48e260SJohan Hedberg 
7506f48e260SJohan Hedberg 	cancel_delayed_work_sync(&smp->security_timer);
7516f48e260SJohan Hedberg 
7526f48e260SJohan Hedberg 	complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags);
753923e2414SJohan Hedberg 	mgmt_smp_complete(hcon, complete);
7546f48e260SJohan Hedberg 
755453431a5SWaiman Long 	kfree_sensitive(smp->csrk);
756*fad646e1SArchie Pusaka 	kfree_sensitive(smp->responder_csrk);
757453431a5SWaiman Long 	kfree_sensitive(smp->link_key);
7586f48e260SJohan Hedberg 
75971af2f6bSHerbert Xu 	crypto_free_shash(smp->tfm_cmac);
76047eb2ac8STudor Ambarus 	crypto_free_kpp(smp->tfm_ecdh);
7616f48e260SJohan Hedberg 
762923e2414SJohan Hedberg 	/* Ensure that we don't leave any debug key around if debug key
763923e2414SJohan Hedberg 	 * support hasn't been explicitly enabled.
764923e2414SJohan Hedberg 	 */
765923e2414SJohan Hedberg 	if (smp->ltk && smp->ltk->type == SMP_LTK_P256_DEBUG &&
766d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hcon->hdev, HCI_KEEP_DEBUG_KEYS)) {
767923e2414SJohan Hedberg 		list_del_rcu(&smp->ltk->list);
768923e2414SJohan Hedberg 		kfree_rcu(smp->ltk, rcu);
769923e2414SJohan Hedberg 		smp->ltk = NULL;
770923e2414SJohan Hedberg 	}
771923e2414SJohan Hedberg 
7726f48e260SJohan Hedberg 	/* If pairing failed clean up any keys we might have */
7736f48e260SJohan Hedberg 	if (!complete) {
7746f48e260SJohan Hedberg 		if (smp->ltk) {
775970d0f1bSJohan Hedberg 			list_del_rcu(&smp->ltk->list);
776970d0f1bSJohan Hedberg 			kfree_rcu(smp->ltk, rcu);
7776f48e260SJohan Hedberg 		}
7786f48e260SJohan Hedberg 
779*fad646e1SArchie Pusaka 		if (smp->responder_ltk) {
780*fad646e1SArchie Pusaka 			list_del_rcu(&smp->responder_ltk->list);
781*fad646e1SArchie Pusaka 			kfree_rcu(smp->responder_ltk, rcu);
7826f48e260SJohan Hedberg 		}
7836f48e260SJohan Hedberg 
7846f48e260SJohan Hedberg 		if (smp->remote_irk) {
785adae20cbSJohan Hedberg 			list_del_rcu(&smp->remote_irk->list);
786adae20cbSJohan Hedberg 			kfree_rcu(smp->remote_irk, rcu);
7876f48e260SJohan Hedberg 		}
7886f48e260SJohan Hedberg 	}
7896f48e260SJohan Hedberg 
7906f48e260SJohan Hedberg 	chan->data = NULL;
791453431a5SWaiman Long 	kfree_sensitive(smp);
792923e2414SJohan Hedberg 	hci_conn_drop(hcon);
7936f48e260SJohan Hedberg }
7946f48e260SJohan Hedberg 
79584794e11SJohan Hedberg static void smp_failure(struct l2cap_conn *conn, u8 reason)
7964f957a76SBrian Gix {
797bab73cb6SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
798b68fda68SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
799bab73cb6SJohan Hedberg 
80084794e11SJohan Hedberg 	if (reason)
8014f957a76SBrian Gix 		smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
8024f957a76SBrian Gix 			     &reason);
8034f957a76SBrian Gix 
804e1e930f5SJohan Hedberg 	mgmt_auth_failed(hcon, HCI_ERROR_AUTH_FAILURE);
805f1c09c07SVinicius Costa Gomes 
806fc75cc86SJohan Hedberg 	if (chan->data)
8074f957a76SBrian Gix 		smp_chan_destroy(conn);
8084f957a76SBrian Gix }
8094f957a76SBrian Gix 
8102b64d153SBrian Gix #define JUST_WORKS	0x00
8112b64d153SBrian Gix #define JUST_CFM	0x01
8122b64d153SBrian Gix #define REQ_PASSKEY	0x02
8132b64d153SBrian Gix #define CFM_PASSKEY	0x03
8142b64d153SBrian Gix #define REQ_OOB		0x04
8155e3d3d9bSJohan Hedberg #define DSP_PASSKEY	0x05
8162b64d153SBrian Gix #define OVERLAP		0xFF
8172b64d153SBrian Gix 
8182b64d153SBrian Gix static const u8 gen_method[5][5] = {
8192b64d153SBrian Gix 	{ JUST_WORKS,  JUST_CFM,    REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
8202b64d153SBrian Gix 	{ JUST_WORKS,  JUST_CFM,    REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
8212b64d153SBrian Gix 	{ CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
8222b64d153SBrian Gix 	{ JUST_WORKS,  JUST_CFM,    JUST_WORKS,  JUST_WORKS, JUST_CFM    },
8232b64d153SBrian Gix 	{ CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, OVERLAP     },
8242b64d153SBrian Gix };
8252b64d153SBrian Gix 
8265e3d3d9bSJohan Hedberg static const u8 sc_method[5][5] = {
8275e3d3d9bSJohan Hedberg 	{ JUST_WORKS,  JUST_CFM,    REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
8285e3d3d9bSJohan Hedberg 	{ JUST_WORKS,  CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
8295e3d3d9bSJohan Hedberg 	{ DSP_PASSKEY, DSP_PASSKEY, REQ_PASSKEY, JUST_WORKS, DSP_PASSKEY },
8305e3d3d9bSJohan Hedberg 	{ JUST_WORKS,  JUST_CFM,    JUST_WORKS,  JUST_WORKS, JUST_CFM    },
8315e3d3d9bSJohan Hedberg 	{ DSP_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
8325e3d3d9bSJohan Hedberg };
8335e3d3d9bSJohan Hedberg 
834581370ccSJohan Hedberg static u8 get_auth_method(struct smp_chan *smp, u8 local_io, u8 remote_io)
835581370ccSJohan Hedberg {
8362bcd4003SJohan Hedberg 	/* If either side has unknown io_caps, use JUST_CFM (which gets
8372bcd4003SJohan Hedberg 	 * converted later to JUST_WORKS if we're initiators.
8382bcd4003SJohan Hedberg 	 */
839581370ccSJohan Hedberg 	if (local_io > SMP_IO_KEYBOARD_DISPLAY ||
840581370ccSJohan Hedberg 	    remote_io > SMP_IO_KEYBOARD_DISPLAY)
8412bcd4003SJohan Hedberg 		return JUST_CFM;
842581370ccSJohan Hedberg 
8435e3d3d9bSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags))
8445e3d3d9bSJohan Hedberg 		return sc_method[remote_io][local_io];
8455e3d3d9bSJohan Hedberg 
846581370ccSJohan Hedberg 	return gen_method[remote_io][local_io];
847581370ccSJohan Hedberg }
848581370ccSJohan Hedberg 
8492b64d153SBrian Gix static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
8502b64d153SBrian Gix 						u8 local_io, u8 remote_io)
8512b64d153SBrian Gix {
8522b64d153SBrian Gix 	struct hci_conn *hcon = conn->hcon;
8535d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
8545d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
8552b64d153SBrian Gix 	u32 passkey = 0;
856d1d900f8SGuenter Roeck 	int ret;
8572b64d153SBrian Gix 
8582b64d153SBrian Gix 	/* Initialize key for JUST WORKS */
8592b64d153SBrian Gix 	memset(smp->tk, 0, sizeof(smp->tk));
8604a74d658SJohan Hedberg 	clear_bit(SMP_FLAG_TK_VALID, &smp->flags);
8612b64d153SBrian Gix 
8622e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hcon->hdev, "auth:%d lcl:%d rem:%d", auth, local_io,
8632e1614f7SLuiz Augusto von Dentz 		   remote_io);
8642b64d153SBrian Gix 
8652bcd4003SJohan Hedberg 	/* If neither side wants MITM, either "just" confirm an incoming
8662bcd4003SJohan Hedberg 	 * request or use just-works for outgoing ones. The JUST_CFM
8672bcd4003SJohan Hedberg 	 * will be converted to JUST_WORKS if necessary later in this
8682bcd4003SJohan Hedberg 	 * function. If either side has MITM look up the method from the
8692bcd4003SJohan Hedberg 	 * table.
8702bcd4003SJohan Hedberg 	 */
871581370ccSJohan Hedberg 	if (!(auth & SMP_AUTH_MITM))
872783e0574SJohan Hedberg 		smp->method = JUST_CFM;
8732b64d153SBrian Gix 	else
874783e0574SJohan Hedberg 		smp->method = get_auth_method(smp, local_io, remote_io);
8752b64d153SBrian Gix 
876a82505c7SJohan Hedberg 	/* Don't confirm locally initiated pairing attempts */
877783e0574SJohan Hedberg 	if (smp->method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR,
878783e0574SJohan Hedberg 						&smp->flags))
879783e0574SJohan Hedberg 		smp->method = JUST_WORKS;
880a82505c7SJohan Hedberg 
88102f3e254SJohan Hedberg 	/* Don't bother user space with no IO capabilities */
882783e0574SJohan Hedberg 	if (smp->method == JUST_CFM &&
883783e0574SJohan Hedberg 	    hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
884783e0574SJohan Hedberg 		smp->method = JUST_WORKS;
88502f3e254SJohan Hedberg 
88692516cd9SSonny Sasaka 	/* If Just Works, Continue with Zero TK and ask user-space for
88792516cd9SSonny Sasaka 	 * confirmation */
888783e0574SJohan Hedberg 	if (smp->method == JUST_WORKS) {
889d1d900f8SGuenter Roeck 		ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
89092516cd9SSonny Sasaka 						hcon->type,
89192516cd9SSonny Sasaka 						hcon->dst_type,
89292516cd9SSonny Sasaka 						passkey, 1);
893d1d900f8SGuenter Roeck 		if (ret)
894d1d900f8SGuenter Roeck 			return ret;
89592516cd9SSonny Sasaka 		set_bit(SMP_FLAG_WAIT_USER, &smp->flags);
8962b64d153SBrian Gix 		return 0;
8972b64d153SBrian Gix 	}
8982b64d153SBrian Gix 
89919c5ce9cSJohan Hedberg 	/* If this function is used for SC -> legacy fallback we
90019c5ce9cSJohan Hedberg 	 * can only recover the just-works case.
90119c5ce9cSJohan Hedberg 	 */
90219c5ce9cSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags))
90319c5ce9cSJohan Hedberg 		return -EINVAL;
90419c5ce9cSJohan Hedberg 
9052b64d153SBrian Gix 	/* Not Just Works/Confirm results in MITM Authentication */
906783e0574SJohan Hedberg 	if (smp->method != JUST_CFM) {
9074a74d658SJohan Hedberg 		set_bit(SMP_FLAG_MITM_AUTH, &smp->flags);
9085eb596f5SJohan Hedberg 		if (hcon->pending_sec_level < BT_SECURITY_HIGH)
9095eb596f5SJohan Hedberg 			hcon->pending_sec_level = BT_SECURITY_HIGH;
9105eb596f5SJohan Hedberg 	}
9112b64d153SBrian Gix 
9122b64d153SBrian Gix 	/* If both devices have Keyoard-Display I/O, the master
9132b64d153SBrian Gix 	 * Confirms and the slave Enters the passkey.
9142b64d153SBrian Gix 	 */
915783e0574SJohan Hedberg 	if (smp->method == OVERLAP) {
91640bef302SJohan Hedberg 		if (hcon->role == HCI_ROLE_MASTER)
917783e0574SJohan Hedberg 			smp->method = CFM_PASSKEY;
9182b64d153SBrian Gix 		else
919783e0574SJohan Hedberg 			smp->method = REQ_PASSKEY;
9202b64d153SBrian Gix 	}
9212b64d153SBrian Gix 
92201ad34d2SJohan Hedberg 	/* Generate random passkey. */
923783e0574SJohan Hedberg 	if (smp->method == CFM_PASSKEY) {
924943a732aSJohan Hedberg 		memset(smp->tk, 0, sizeof(smp->tk));
9252b64d153SBrian Gix 		get_random_bytes(&passkey, sizeof(passkey));
9262b64d153SBrian Gix 		passkey %= 1000000;
927943a732aSJohan Hedberg 		put_unaligned_le32(passkey, smp->tk);
9282e1614f7SLuiz Augusto von Dentz 		bt_dev_dbg(hcon->hdev, "PassKey: %d", passkey);
9294a74d658SJohan Hedberg 		set_bit(SMP_FLAG_TK_VALID, &smp->flags);
9302b64d153SBrian Gix 	}
9312b64d153SBrian Gix 
932783e0574SJohan Hedberg 	if (smp->method == REQ_PASSKEY)
933ce39fb4eSMarcel Holtmann 		ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst,
934272d90dfSJohan Hedberg 						hcon->type, hcon->dst_type);
935783e0574SJohan Hedberg 	else if (smp->method == JUST_CFM)
9364eb65e66SJohan Hedberg 		ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
9374eb65e66SJohan Hedberg 						hcon->type, hcon->dst_type,
9384eb65e66SJohan Hedberg 						passkey, 1);
9392b64d153SBrian Gix 	else
94001ad34d2SJohan Hedberg 		ret = mgmt_user_passkey_notify(hcon->hdev, &hcon->dst,
941272d90dfSJohan Hedberg 						hcon->type, hcon->dst_type,
94239adbffeSJohan Hedberg 						passkey, 0);
9432b64d153SBrian Gix 
9442b64d153SBrian Gix 	return ret;
9452b64d153SBrian Gix }
9462b64d153SBrian Gix 
9471cc61144SJohan Hedberg static u8 smp_confirm(struct smp_chan *smp)
9488aab4757SVinicius Costa Gomes {
9498aab4757SVinicius Costa Gomes 	struct l2cap_conn *conn = smp->conn;
9508aab4757SVinicius Costa Gomes 	struct smp_cmd_pairing_confirm cp;
9518aab4757SVinicius Costa Gomes 	int ret;
9528aab4757SVinicius Costa Gomes 
9532e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(conn->hcon->hdev, "conn %p", conn);
9548aab4757SVinicius Costa Gomes 
95528a220aaSArd Biesheuvel 	ret = smp_c1(smp->tk, smp->prnd, smp->preq, smp->prsp,
956b1cd5fd9SJohan Hedberg 		     conn->hcon->init_addr_type, &conn->hcon->init_addr,
957943a732aSJohan Hedberg 		     conn->hcon->resp_addr_type, &conn->hcon->resp_addr,
958943a732aSJohan Hedberg 		     cp.confirm_val);
9591cc61144SJohan Hedberg 	if (ret)
9601cc61144SJohan Hedberg 		return SMP_UNSPECIFIED;
9618aab4757SVinicius Costa Gomes 
9624a74d658SJohan Hedberg 	clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
9632b64d153SBrian Gix 
9648aab4757SVinicius Costa Gomes 	smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
9658aab4757SVinicius Costa Gomes 
966b28b4943SJohan Hedberg 	if (conn->hcon->out)
967b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
968b28b4943SJohan Hedberg 	else
969b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
970b28b4943SJohan Hedberg 
9711cc61144SJohan Hedberg 	return 0;
9728aab4757SVinicius Costa Gomes }
9738aab4757SVinicius Costa Gomes 
974861580a9SJohan Hedberg static u8 smp_random(struct smp_chan *smp)
9758aab4757SVinicius Costa Gomes {
9768aab4757SVinicius Costa Gomes 	struct l2cap_conn *conn = smp->conn;
9778aab4757SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
978861580a9SJohan Hedberg 	u8 confirm[16];
9798aab4757SVinicius Costa Gomes 	int ret;
9808aab4757SVinicius Costa Gomes 
9812e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(conn->hcon->hdev, "conn %p %s", conn,
982*fad646e1SArchie Pusaka 		   conn->hcon->out ? "initiator" : "responder");
9838aab4757SVinicius Costa Gomes 
98428a220aaSArd Biesheuvel 	ret = smp_c1(smp->tk, smp->rrnd, smp->preq, smp->prsp,
985b1cd5fd9SJohan Hedberg 		     hcon->init_addr_type, &hcon->init_addr,
986943a732aSJohan Hedberg 		     hcon->resp_addr_type, &hcon->resp_addr, confirm);
987861580a9SJohan Hedberg 	if (ret)
988861580a9SJohan Hedberg 		return SMP_UNSPECIFIED;
9898aab4757SVinicius Costa Gomes 
990329d8230SJason A. Donenfeld 	if (crypto_memneq(smp->pcnf, confirm, sizeof(smp->pcnf))) {
9912064ee33SMarcel Holtmann 		bt_dev_err(hcon->hdev, "pairing failed "
9922064ee33SMarcel Holtmann 			   "(confirmation values mismatch)");
993861580a9SJohan Hedberg 		return SMP_CONFIRM_FAILED;
9948aab4757SVinicius Costa Gomes 	}
9958aab4757SVinicius Costa Gomes 
9968aab4757SVinicius Costa Gomes 	if (hcon->out) {
997fe39c7b2SMarcel Holtmann 		u8 stk[16];
998fe39c7b2SMarcel Holtmann 		__le64 rand = 0;
999fe39c7b2SMarcel Holtmann 		__le16 ediv = 0;
10008aab4757SVinicius Costa Gomes 
100128a220aaSArd Biesheuvel 		smp_s1(smp->tk, smp->rrnd, smp->prnd, stk);
10028aab4757SVinicius Costa Gomes 
1003861580a9SJohan Hedberg 		if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
1004861580a9SJohan Hedberg 			return SMP_UNSPECIFIED;
10058aab4757SVinicius Costa Gomes 
10068b76ce34SJohan Hedberg 		hci_le_start_enc(hcon, ediv, rand, stk, smp->enc_key_size);
1007f7aa611aSVinicius Costa Gomes 		hcon->enc_key_size = smp->enc_key_size;
1008fe59a05fSJohan Hedberg 		set_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags);
10098aab4757SVinicius Costa Gomes 	} else {
1010fff3490fSJohan Hedberg 		u8 stk[16], auth;
1011fe39c7b2SMarcel Holtmann 		__le64 rand = 0;
1012fe39c7b2SMarcel Holtmann 		__le16 ediv = 0;
10138aab4757SVinicius Costa Gomes 
1014943a732aSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
1015943a732aSJohan Hedberg 			     smp->prnd);
10168aab4757SVinicius Costa Gomes 
101728a220aaSArd Biesheuvel 		smp_s1(smp->tk, smp->prnd, smp->rrnd, stk);
10188aab4757SVinicius Costa Gomes 
1019fff3490fSJohan Hedberg 		if (hcon->pending_sec_level == BT_SECURITY_HIGH)
1020fff3490fSJohan Hedberg 			auth = 1;
1021fff3490fSJohan Hedberg 		else
1022fff3490fSJohan Hedberg 			auth = 0;
1023fff3490fSJohan Hedberg 
1024*fad646e1SArchie Pusaka 		/* Even though there's no _RESPONDER suffix this is the
1025*fad646e1SArchie Pusaka 		 * responder STK we're adding for later lookup (the initiator
10267d5843b7SJohan Hedberg 		 * STK never needs to be stored).
10277d5843b7SJohan Hedberg 		 */
1028ce39fb4eSMarcel Holtmann 		hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
10292ceba539SJohan Hedberg 			    SMP_STK, auth, stk, smp->enc_key_size, ediv, rand);
10308aab4757SVinicius Costa Gomes 	}
10318aab4757SVinicius Costa Gomes 
1032861580a9SJohan Hedberg 	return 0;
10338aab4757SVinicius Costa Gomes }
10348aab4757SVinicius Costa Gomes 
103544f1a7abSJohan Hedberg static void smp_notify_keys(struct l2cap_conn *conn)
103644f1a7abSJohan Hedberg {
103744f1a7abSJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
103844f1a7abSJohan Hedberg 	struct smp_chan *smp = chan->data;
103944f1a7abSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
104044f1a7abSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
104144f1a7abSJohan Hedberg 	struct smp_cmd_pairing *req = (void *) &smp->preq[1];
104244f1a7abSJohan Hedberg 	struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1];
104344f1a7abSJohan Hedberg 	bool persistent;
104444f1a7abSJohan Hedberg 
1045cad20c27SJohan Hedberg 	if (hcon->type == ACL_LINK) {
1046cad20c27SJohan Hedberg 		if (hcon->key_type == HCI_LK_DEBUG_COMBINATION)
1047cad20c27SJohan Hedberg 			persistent = false;
1048cad20c27SJohan Hedberg 		else
1049cad20c27SJohan Hedberg 			persistent = !test_bit(HCI_CONN_FLUSH_KEY,
1050cad20c27SJohan Hedberg 					       &hcon->flags);
1051cad20c27SJohan Hedberg 	} else {
1052cad20c27SJohan Hedberg 		/* The LTKs, IRKs and CSRKs should be persistent only if
1053cad20c27SJohan Hedberg 		 * both sides had the bonding bit set in their
1054cad20c27SJohan Hedberg 		 * authentication requests.
1055cad20c27SJohan Hedberg 		 */
1056cad20c27SJohan Hedberg 		persistent = !!((req->auth_req & rsp->auth_req) &
1057cad20c27SJohan Hedberg 				SMP_AUTH_BONDING);
1058cad20c27SJohan Hedberg 	}
1059cad20c27SJohan Hedberg 
106044f1a7abSJohan Hedberg 	if (smp->remote_irk) {
1061cad20c27SJohan Hedberg 		mgmt_new_irk(hdev, smp->remote_irk, persistent);
1062cad20c27SJohan Hedberg 
106344f1a7abSJohan Hedberg 		/* Now that user space can be considered to know the
106444f1a7abSJohan Hedberg 		 * identity address track the connection based on it
1065b5ae344dSJohan Hedberg 		 * from now on (assuming this is an LE link).
106644f1a7abSJohan Hedberg 		 */
1067b5ae344dSJohan Hedberg 		if (hcon->type == LE_LINK) {
106844f1a7abSJohan Hedberg 			bacpy(&hcon->dst, &smp->remote_irk->bdaddr);
106944f1a7abSJohan Hedberg 			hcon->dst_type = smp->remote_irk->addr_type;
1070f3d82d0cSJohan Hedberg 			queue_work(hdev->workqueue, &conn->id_addr_update_work);
1071b5ae344dSJohan Hedberg 		}
107244f1a7abSJohan Hedberg 	}
107344f1a7abSJohan Hedberg 
107444f1a7abSJohan Hedberg 	if (smp->csrk) {
107544f1a7abSJohan Hedberg 		smp->csrk->bdaddr_type = hcon->dst_type;
107644f1a7abSJohan Hedberg 		bacpy(&smp->csrk->bdaddr, &hcon->dst);
107744f1a7abSJohan Hedberg 		mgmt_new_csrk(hdev, smp->csrk, persistent);
107844f1a7abSJohan Hedberg 	}
107944f1a7abSJohan Hedberg 
1080*fad646e1SArchie Pusaka 	if (smp->responder_csrk) {
1081*fad646e1SArchie Pusaka 		smp->responder_csrk->bdaddr_type = hcon->dst_type;
1082*fad646e1SArchie Pusaka 		bacpy(&smp->responder_csrk->bdaddr, &hcon->dst);
1083*fad646e1SArchie Pusaka 		mgmt_new_csrk(hdev, smp->responder_csrk, persistent);
108444f1a7abSJohan Hedberg 	}
108544f1a7abSJohan Hedberg 
108644f1a7abSJohan Hedberg 	if (smp->ltk) {
108744f1a7abSJohan Hedberg 		smp->ltk->bdaddr_type = hcon->dst_type;
108844f1a7abSJohan Hedberg 		bacpy(&smp->ltk->bdaddr, &hcon->dst);
108944f1a7abSJohan Hedberg 		mgmt_new_ltk(hdev, smp->ltk, persistent);
109044f1a7abSJohan Hedberg 	}
109144f1a7abSJohan Hedberg 
1092*fad646e1SArchie Pusaka 	if (smp->responder_ltk) {
1093*fad646e1SArchie Pusaka 		smp->responder_ltk->bdaddr_type = hcon->dst_type;
1094*fad646e1SArchie Pusaka 		bacpy(&smp->responder_ltk->bdaddr, &hcon->dst);
1095*fad646e1SArchie Pusaka 		mgmt_new_ltk(hdev, smp->responder_ltk, persistent);
109644f1a7abSJohan Hedberg 	}
10976a77083aSJohan Hedberg 
10986a77083aSJohan Hedberg 	if (smp->link_key) {
1099e3befab9SJohan Hedberg 		struct link_key *key;
1100e3befab9SJohan Hedberg 		u8 type;
1101e3befab9SJohan Hedberg 
1102e3befab9SJohan Hedberg 		if (test_bit(SMP_FLAG_DEBUG_KEY, &smp->flags))
1103e3befab9SJohan Hedberg 			type = HCI_LK_DEBUG_COMBINATION;
1104e3befab9SJohan Hedberg 		else if (hcon->sec_level == BT_SECURITY_FIPS)
1105e3befab9SJohan Hedberg 			type = HCI_LK_AUTH_COMBINATION_P256;
1106e3befab9SJohan Hedberg 		else
1107e3befab9SJohan Hedberg 			type = HCI_LK_UNAUTH_COMBINATION_P256;
1108e3befab9SJohan Hedberg 
1109e3befab9SJohan Hedberg 		key = hci_add_link_key(hdev, smp->conn->hcon, &hcon->dst,
1110e3befab9SJohan Hedberg 				       smp->link_key, type, 0, &persistent);
1111e3befab9SJohan Hedberg 		if (key) {
1112e3befab9SJohan Hedberg 			mgmt_new_link_key(hdev, key, persistent);
1113e3befab9SJohan Hedberg 
1114e3befab9SJohan Hedberg 			/* Don't keep debug keys around if the relevant
1115e3befab9SJohan Hedberg 			 * flag is not set.
1116e3befab9SJohan Hedberg 			 */
1117d7a5a11dSMarcel Holtmann 			if (!hci_dev_test_flag(hdev, HCI_KEEP_DEBUG_KEYS) &&
1118e3befab9SJohan Hedberg 			    key->type == HCI_LK_DEBUG_COMBINATION) {
1119e3befab9SJohan Hedberg 				list_del_rcu(&key->list);
1120e3befab9SJohan Hedberg 				kfree_rcu(key, rcu);
1121e3befab9SJohan Hedberg 			}
1122e3befab9SJohan Hedberg 		}
11236a77083aSJohan Hedberg 	}
11246a77083aSJohan Hedberg }
11256a77083aSJohan Hedberg 
1126d3e54a87SJohan Hedberg static void sc_add_ltk(struct smp_chan *smp)
1127d3e54a87SJohan Hedberg {
1128d3e54a87SJohan Hedberg 	struct hci_conn *hcon = smp->conn->hcon;
1129d3e54a87SJohan Hedberg 	u8 key_type, auth;
1130d3e54a87SJohan Hedberg 
1131d3e54a87SJohan Hedberg 	if (test_bit(SMP_FLAG_DEBUG_KEY, &smp->flags))
1132d3e54a87SJohan Hedberg 		key_type = SMP_LTK_P256_DEBUG;
1133d3e54a87SJohan Hedberg 	else
1134d3e54a87SJohan Hedberg 		key_type = SMP_LTK_P256;
1135d3e54a87SJohan Hedberg 
1136d3e54a87SJohan Hedberg 	if (hcon->pending_sec_level == BT_SECURITY_FIPS)
1137d3e54a87SJohan Hedberg 		auth = 1;
1138d3e54a87SJohan Hedberg 	else
1139d3e54a87SJohan Hedberg 		auth = 0;
1140d3e54a87SJohan Hedberg 
1141d3e54a87SJohan Hedberg 	smp->ltk = hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
1142d3e54a87SJohan Hedberg 			       key_type, auth, smp->tk, smp->enc_key_size,
1143d3e54a87SJohan Hedberg 			       0, 0);
1144d3e54a87SJohan Hedberg }
1145d3e54a87SJohan Hedberg 
11466a77083aSJohan Hedberg static void sc_generate_link_key(struct smp_chan *smp)
11476a77083aSJohan Hedberg {
1148a62da6f1SJohan Hedberg 	/* From core spec. Spells out in ASCII as 'lebr'. */
11496a77083aSJohan Hedberg 	const u8 lebr[4] = { 0x72, 0x62, 0x65, 0x6c };
11506a77083aSJohan Hedberg 
11516a77083aSJohan Hedberg 	smp->link_key = kzalloc(16, GFP_KERNEL);
11526a77083aSJohan Hedberg 	if (!smp->link_key)
11536a77083aSJohan Hedberg 		return;
11546a77083aSJohan Hedberg 
1155a62da6f1SJohan Hedberg 	if (test_bit(SMP_FLAG_CT2, &smp->flags)) {
1156151129dfSChristophe JAILLET 		/* SALT = 0x000000000000000000000000746D7031 */
1157a62da6f1SJohan Hedberg 		const u8 salt[16] = { 0x31, 0x70, 0x6d, 0x74 };
1158a62da6f1SJohan Hedberg 
1159a62da6f1SJohan Hedberg 		if (smp_h7(smp->tfm_cmac, smp->tk, salt, smp->link_key)) {
1160453431a5SWaiman Long 			kfree_sensitive(smp->link_key);
1161a62da6f1SJohan Hedberg 			smp->link_key = NULL;
1162a62da6f1SJohan Hedberg 			return;
1163a62da6f1SJohan Hedberg 		}
1164a62da6f1SJohan Hedberg 	} else {
1165a62da6f1SJohan Hedberg 		/* From core spec. Spells out in ASCII as 'tmp1'. */
1166a62da6f1SJohan Hedberg 		const u8 tmp1[4] = { 0x31, 0x70, 0x6d, 0x74 };
1167a62da6f1SJohan Hedberg 
11686a77083aSJohan Hedberg 		if (smp_h6(smp->tfm_cmac, smp->tk, tmp1, smp->link_key)) {
1169453431a5SWaiman Long 			kfree_sensitive(smp->link_key);
11706a77083aSJohan Hedberg 			smp->link_key = NULL;
11716a77083aSJohan Hedberg 			return;
11726a77083aSJohan Hedberg 		}
1173a62da6f1SJohan Hedberg 	}
11746a77083aSJohan Hedberg 
11756a77083aSJohan Hedberg 	if (smp_h6(smp->tfm_cmac, smp->link_key, lebr, smp->link_key)) {
1176453431a5SWaiman Long 		kfree_sensitive(smp->link_key);
11776a77083aSJohan Hedberg 		smp->link_key = NULL;
11786a77083aSJohan Hedberg 		return;
11796a77083aSJohan Hedberg 	}
118044f1a7abSJohan Hedberg }
118144f1a7abSJohan Hedberg 
1182b28b4943SJohan Hedberg static void smp_allow_key_dist(struct smp_chan *smp)
1183b28b4943SJohan Hedberg {
1184b28b4943SJohan Hedberg 	/* Allow the first expected phase 3 PDU. The rest of the PDUs
1185b28b4943SJohan Hedberg 	 * will be allowed in each PDU handler to ensure we receive
1186b28b4943SJohan Hedberg 	 * them in the correct order.
1187b28b4943SJohan Hedberg 	 */
1188b28b4943SJohan Hedberg 	if (smp->remote_key_dist & SMP_DIST_ENC_KEY)
1189b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_ENCRYPT_INFO);
1190b28b4943SJohan Hedberg 	else if (smp->remote_key_dist & SMP_DIST_ID_KEY)
1191b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO);
1192b28b4943SJohan Hedberg 	else if (smp->remote_key_dist & SMP_DIST_SIGN)
1193b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO);
1194b28b4943SJohan Hedberg }
1195b28b4943SJohan Hedberg 
1196b5ae344dSJohan Hedberg static void sc_generate_ltk(struct smp_chan *smp)
1197b5ae344dSJohan Hedberg {
1198a62da6f1SJohan Hedberg 	/* From core spec. Spells out in ASCII as 'brle'. */
1199b5ae344dSJohan Hedberg 	const u8 brle[4] = { 0x65, 0x6c, 0x72, 0x62 };
1200b5ae344dSJohan Hedberg 	struct hci_conn *hcon = smp->conn->hcon;
1201b5ae344dSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
1202b5ae344dSJohan Hedberg 	struct link_key *key;
1203b5ae344dSJohan Hedberg 
1204b5ae344dSJohan Hedberg 	key = hci_find_link_key(hdev, &hcon->dst);
1205b5ae344dSJohan Hedberg 	if (!key) {
12062064ee33SMarcel Holtmann 		bt_dev_err(hdev, "no Link Key found to generate LTK");
1207b5ae344dSJohan Hedberg 		return;
1208b5ae344dSJohan Hedberg 	}
1209b5ae344dSJohan Hedberg 
1210b5ae344dSJohan Hedberg 	if (key->type == HCI_LK_DEBUG_COMBINATION)
1211b5ae344dSJohan Hedberg 		set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags);
1212b5ae344dSJohan Hedberg 
1213a62da6f1SJohan Hedberg 	if (test_bit(SMP_FLAG_CT2, &smp->flags)) {
1214151129dfSChristophe JAILLET 		/* SALT = 0x000000000000000000000000746D7032 */
1215a62da6f1SJohan Hedberg 		const u8 salt[16] = { 0x32, 0x70, 0x6d, 0x74 };
1216a62da6f1SJohan Hedberg 
1217a62da6f1SJohan Hedberg 		if (smp_h7(smp->tfm_cmac, key->val, salt, smp->tk))
1218a62da6f1SJohan Hedberg 			return;
1219a62da6f1SJohan Hedberg 	} else {
1220a62da6f1SJohan Hedberg 		/* From core spec. Spells out in ASCII as 'tmp2'. */
1221a62da6f1SJohan Hedberg 		const u8 tmp2[4] = { 0x32, 0x70, 0x6d, 0x74 };
1222a62da6f1SJohan Hedberg 
1223b5ae344dSJohan Hedberg 		if (smp_h6(smp->tfm_cmac, key->val, tmp2, smp->tk))
1224b5ae344dSJohan Hedberg 			return;
1225a62da6f1SJohan Hedberg 	}
1226b5ae344dSJohan Hedberg 
1227b5ae344dSJohan Hedberg 	if (smp_h6(smp->tfm_cmac, smp->tk, brle, smp->tk))
1228b5ae344dSJohan Hedberg 		return;
1229b5ae344dSJohan Hedberg 
1230b5ae344dSJohan Hedberg 	sc_add_ltk(smp);
1231b5ae344dSJohan Hedberg }
1232b5ae344dSJohan Hedberg 
1233d6268e86SJohan Hedberg static void smp_distribute_keys(struct smp_chan *smp)
123444f1a7abSJohan Hedberg {
123544f1a7abSJohan Hedberg 	struct smp_cmd_pairing *req, *rsp;
123686d1407cSJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
123744f1a7abSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
123844f1a7abSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
123944f1a7abSJohan Hedberg 	__u8 *keydist;
124044f1a7abSJohan Hedberg 
12412e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "conn %p", conn);
124244f1a7abSJohan Hedberg 
124344f1a7abSJohan Hedberg 	rsp = (void *) &smp->prsp[1];
124444f1a7abSJohan Hedberg 
124544f1a7abSJohan Hedberg 	/* The responder sends its keys first */
1246b28b4943SJohan Hedberg 	if (hcon->out && (smp->remote_key_dist & KEY_DIST_MASK)) {
1247b28b4943SJohan Hedberg 		smp_allow_key_dist(smp);
124886d1407cSJohan Hedberg 		return;
1249b28b4943SJohan Hedberg 	}
125044f1a7abSJohan Hedberg 
125144f1a7abSJohan Hedberg 	req = (void *) &smp->preq[1];
125244f1a7abSJohan Hedberg 
125344f1a7abSJohan Hedberg 	if (hcon->out) {
125444f1a7abSJohan Hedberg 		keydist = &rsp->init_key_dist;
125544f1a7abSJohan Hedberg 		*keydist &= req->init_key_dist;
125644f1a7abSJohan Hedberg 	} else {
125744f1a7abSJohan Hedberg 		keydist = &rsp->resp_key_dist;
125844f1a7abSJohan Hedberg 		*keydist &= req->resp_key_dist;
125944f1a7abSJohan Hedberg 	}
126044f1a7abSJohan Hedberg 
12616a77083aSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
1262b5ae344dSJohan Hedberg 		if (hcon->type == LE_LINK && (*keydist & SMP_DIST_LINK_KEY))
12636a77083aSJohan Hedberg 			sc_generate_link_key(smp);
1264b5ae344dSJohan Hedberg 		if (hcon->type == ACL_LINK && (*keydist & SMP_DIST_ENC_KEY))
1265b5ae344dSJohan Hedberg 			sc_generate_ltk(smp);
12666a77083aSJohan Hedberg 
12676a77083aSJohan Hedberg 		/* Clear the keys which are generated but not distributed */
12686a77083aSJohan Hedberg 		*keydist &= ~SMP_SC_NO_DIST;
12696a77083aSJohan Hedberg 	}
12706a77083aSJohan Hedberg 
12712e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "keydist 0x%x", *keydist);
127244f1a7abSJohan Hedberg 
127344f1a7abSJohan Hedberg 	if (*keydist & SMP_DIST_ENC_KEY) {
127444f1a7abSJohan Hedberg 		struct smp_cmd_encrypt_info enc;
1275*fad646e1SArchie Pusaka 		struct smp_cmd_initiator_ident ident;
127644f1a7abSJohan Hedberg 		struct smp_ltk *ltk;
127744f1a7abSJohan Hedberg 		u8 authenticated;
127844f1a7abSJohan Hedberg 		__le16 ediv;
127944f1a7abSJohan Hedberg 		__le64 rand;
128044f1a7abSJohan Hedberg 
12811fc62c52SJohan Hedberg 		/* Make sure we generate only the significant amount of
12821fc62c52SJohan Hedberg 		 * bytes based on the encryption key size, and set the rest
12831fc62c52SJohan Hedberg 		 * of the value to zeroes.
12841fc62c52SJohan Hedberg 		 */
12851fc62c52SJohan Hedberg 		get_random_bytes(enc.ltk, smp->enc_key_size);
12861fc62c52SJohan Hedberg 		memset(enc.ltk + smp->enc_key_size, 0,
12871fc62c52SJohan Hedberg 		       sizeof(enc.ltk) - smp->enc_key_size);
12881fc62c52SJohan Hedberg 
128944f1a7abSJohan Hedberg 		get_random_bytes(&ediv, sizeof(ediv));
129044f1a7abSJohan Hedberg 		get_random_bytes(&rand, sizeof(rand));
129144f1a7abSJohan Hedberg 
129244f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
129344f1a7abSJohan Hedberg 
129444f1a7abSJohan Hedberg 		authenticated = hcon->sec_level == BT_SECURITY_HIGH;
129544f1a7abSJohan Hedberg 		ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type,
1296*fad646e1SArchie Pusaka 				  SMP_LTK_RESPONDER, authenticated, enc.ltk,
129744f1a7abSJohan Hedberg 				  smp->enc_key_size, ediv, rand);
1298*fad646e1SArchie Pusaka 		smp->responder_ltk = ltk;
129944f1a7abSJohan Hedberg 
130044f1a7abSJohan Hedberg 		ident.ediv = ediv;
130144f1a7abSJohan Hedberg 		ident.rand = rand;
130244f1a7abSJohan Hedberg 
1303*fad646e1SArchie Pusaka 		smp_send_cmd(conn, SMP_CMD_INITIATOR_IDENT, sizeof(ident),
1304*fad646e1SArchie Pusaka 			     &ident);
130544f1a7abSJohan Hedberg 
130644f1a7abSJohan Hedberg 		*keydist &= ~SMP_DIST_ENC_KEY;
130744f1a7abSJohan Hedberg 	}
130844f1a7abSJohan Hedberg 
130944f1a7abSJohan Hedberg 	if (*keydist & SMP_DIST_ID_KEY) {
131044f1a7abSJohan Hedberg 		struct smp_cmd_ident_addr_info addrinfo;
131144f1a7abSJohan Hedberg 		struct smp_cmd_ident_info idinfo;
131244f1a7abSJohan Hedberg 
131344f1a7abSJohan Hedberg 		memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk));
131444f1a7abSJohan Hedberg 
131544f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo);
131644f1a7abSJohan Hedberg 
131744f1a7abSJohan Hedberg 		/* The hci_conn contains the local identity address
131844f1a7abSJohan Hedberg 		 * after the connection has been established.
131944f1a7abSJohan Hedberg 		 *
132044f1a7abSJohan Hedberg 		 * This is true even when the connection has been
132144f1a7abSJohan Hedberg 		 * established using a resolvable random address.
132244f1a7abSJohan Hedberg 		 */
132344f1a7abSJohan Hedberg 		bacpy(&addrinfo.bdaddr, &hcon->src);
132444f1a7abSJohan Hedberg 		addrinfo.addr_type = hcon->src_type;
132544f1a7abSJohan Hedberg 
132644f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo),
132744f1a7abSJohan Hedberg 			     &addrinfo);
132844f1a7abSJohan Hedberg 
132944f1a7abSJohan Hedberg 		*keydist &= ~SMP_DIST_ID_KEY;
133044f1a7abSJohan Hedberg 	}
133144f1a7abSJohan Hedberg 
133244f1a7abSJohan Hedberg 	if (*keydist & SMP_DIST_SIGN) {
133344f1a7abSJohan Hedberg 		struct smp_cmd_sign_info sign;
133444f1a7abSJohan Hedberg 		struct smp_csrk *csrk;
133544f1a7abSJohan Hedberg 
133644f1a7abSJohan Hedberg 		/* Generate a new random key */
133744f1a7abSJohan Hedberg 		get_random_bytes(sign.csrk, sizeof(sign.csrk));
133844f1a7abSJohan Hedberg 
133944f1a7abSJohan Hedberg 		csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
134044f1a7abSJohan Hedberg 		if (csrk) {
13414cd3928aSJohan Hedberg 			if (hcon->sec_level > BT_SECURITY_MEDIUM)
13424cd3928aSJohan Hedberg 				csrk->type = MGMT_CSRK_LOCAL_AUTHENTICATED;
13434cd3928aSJohan Hedberg 			else
13444cd3928aSJohan Hedberg 				csrk->type = MGMT_CSRK_LOCAL_UNAUTHENTICATED;
134544f1a7abSJohan Hedberg 			memcpy(csrk->val, sign.csrk, sizeof(csrk->val));
134644f1a7abSJohan Hedberg 		}
1347*fad646e1SArchie Pusaka 		smp->responder_csrk = csrk;
134844f1a7abSJohan Hedberg 
134944f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign);
135044f1a7abSJohan Hedberg 
135144f1a7abSJohan Hedberg 		*keydist &= ~SMP_DIST_SIGN;
135244f1a7abSJohan Hedberg 	}
135344f1a7abSJohan Hedberg 
135444f1a7abSJohan Hedberg 	/* If there are still keys to be received wait for them */
1355b28b4943SJohan Hedberg 	if (smp->remote_key_dist & KEY_DIST_MASK) {
1356b28b4943SJohan Hedberg 		smp_allow_key_dist(smp);
135786d1407cSJohan Hedberg 		return;
1358b28b4943SJohan Hedberg 	}
135944f1a7abSJohan Hedberg 
136044f1a7abSJohan Hedberg 	set_bit(SMP_FLAG_COMPLETE, &smp->flags);
136144f1a7abSJohan Hedberg 	smp_notify_keys(conn);
136244f1a7abSJohan Hedberg 
136344f1a7abSJohan Hedberg 	smp_chan_destroy(conn);
136444f1a7abSJohan Hedberg }
136544f1a7abSJohan Hedberg 
1366b68fda68SJohan Hedberg static void smp_timeout(struct work_struct *work)
1367b68fda68SJohan Hedberg {
1368b68fda68SJohan Hedberg 	struct smp_chan *smp = container_of(work, struct smp_chan,
1369b68fda68SJohan Hedberg 					    security_timer.work);
1370b68fda68SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
1371b68fda68SJohan Hedberg 
13722e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(conn->hcon->hdev, "conn %p", conn);
1373b68fda68SJohan Hedberg 
13741e91c29eSJohan Hedberg 	hci_disconnect(conn->hcon, HCI_ERROR_REMOTE_USER_TERM);
1375b68fda68SJohan Hedberg }
1376b68fda68SJohan Hedberg 
13778aab4757SVinicius Costa Gomes static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
13788aab4757SVinicius Costa Gomes {
13792e1614f7SLuiz Augusto von Dentz 	struct hci_conn *hcon = conn->hcon;
13805d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
13818aab4757SVinicius Costa Gomes 	struct smp_chan *smp;
13828aab4757SVinicius Costa Gomes 
1383f1560463SMarcel Holtmann 	smp = kzalloc(sizeof(*smp), GFP_ATOMIC);
1384fc75cc86SJohan Hedberg 	if (!smp)
13858aab4757SVinicius Costa Gomes 		return NULL;
13868aab4757SVinicius Costa Gomes 
138771af2f6bSHerbert Xu 	smp->tfm_cmac = crypto_alloc_shash("cmac(aes)", 0, 0);
1388407cecf6SJohan Hedberg 	if (IS_ERR(smp->tfm_cmac)) {
13892e1614f7SLuiz Augusto von Dentz 		bt_dev_err(hcon->hdev, "Unable to create CMAC crypto context");
139028a220aaSArd Biesheuvel 		goto zfree_smp;
139147eb2ac8STudor Ambarus 	}
139247eb2ac8STudor Ambarus 
13936763f5eaSMeng Yu 	smp->tfm_ecdh = crypto_alloc_kpp("ecdh-nist-p256", 0, 0);
139447eb2ac8STudor Ambarus 	if (IS_ERR(smp->tfm_ecdh)) {
13952e1614f7SLuiz Augusto von Dentz 		bt_dev_err(hcon->hdev, "Unable to create ECDH crypto context");
139647eb2ac8STudor Ambarus 		goto free_shash;
1397407cecf6SJohan Hedberg 	}
1398407cecf6SJohan Hedberg 
13998aab4757SVinicius Costa Gomes 	smp->conn = conn;
14005d88cc73SJohan Hedberg 	chan->data = smp;
14018aab4757SVinicius Costa Gomes 
1402b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_FAIL);
1403b28b4943SJohan Hedberg 
1404b68fda68SJohan Hedberg 	INIT_DELAYED_WORK(&smp->security_timer, smp_timeout);
1405b68fda68SJohan Hedberg 
14062e1614f7SLuiz Augusto von Dentz 	hci_conn_hold(hcon);
14078aab4757SVinicius Costa Gomes 
14088aab4757SVinicius Costa Gomes 	return smp;
140947eb2ac8STudor Ambarus 
141047eb2ac8STudor Ambarus free_shash:
141147eb2ac8STudor Ambarus 	crypto_free_shash(smp->tfm_cmac);
141247eb2ac8STudor Ambarus zfree_smp:
1413453431a5SWaiman Long 	kfree_sensitive(smp);
141447eb2ac8STudor Ambarus 	return NULL;
14158aab4757SVinicius Costa Gomes }
14168aab4757SVinicius Costa Gomes 
1417760b018bSJohan Hedberg static int sc_mackey_and_ltk(struct smp_chan *smp, u8 mackey[16], u8 ltk[16])
1418760b018bSJohan Hedberg {
1419760b018bSJohan Hedberg 	struct hci_conn *hcon = smp->conn->hcon;
1420760b018bSJohan Hedberg 	u8 *na, *nb, a[7], b[7];
1421760b018bSJohan Hedberg 
1422760b018bSJohan Hedberg 	if (hcon->out) {
1423760b018bSJohan Hedberg 		na   = smp->prnd;
1424760b018bSJohan Hedberg 		nb   = smp->rrnd;
1425760b018bSJohan Hedberg 	} else {
1426760b018bSJohan Hedberg 		na   = smp->rrnd;
1427760b018bSJohan Hedberg 		nb   = smp->prnd;
1428760b018bSJohan Hedberg 	}
1429760b018bSJohan Hedberg 
1430760b018bSJohan Hedberg 	memcpy(a, &hcon->init_addr, 6);
1431760b018bSJohan Hedberg 	memcpy(b, &hcon->resp_addr, 6);
1432760b018bSJohan Hedberg 	a[6] = hcon->init_addr_type;
1433760b018bSJohan Hedberg 	b[6] = hcon->resp_addr_type;
1434760b018bSJohan Hedberg 
1435760b018bSJohan Hedberg 	return smp_f5(smp->tfm_cmac, smp->dhkey, na, nb, a, b, mackey, ltk);
1436760b018bSJohan Hedberg }
1437760b018bSJohan Hedberg 
143838606f14SJohan Hedberg static void sc_dhkey_check(struct smp_chan *smp)
1439760b018bSJohan Hedberg {
1440760b018bSJohan Hedberg 	struct hci_conn *hcon = smp->conn->hcon;
1441760b018bSJohan Hedberg 	struct smp_cmd_dhkey_check check;
1442760b018bSJohan Hedberg 	u8 a[7], b[7], *local_addr, *remote_addr;
1443760b018bSJohan Hedberg 	u8 io_cap[3], r[16];
1444760b018bSJohan Hedberg 
1445760b018bSJohan Hedberg 	memcpy(a, &hcon->init_addr, 6);
1446760b018bSJohan Hedberg 	memcpy(b, &hcon->resp_addr, 6);
1447760b018bSJohan Hedberg 	a[6] = hcon->init_addr_type;
1448760b018bSJohan Hedberg 	b[6] = hcon->resp_addr_type;
1449760b018bSJohan Hedberg 
1450760b018bSJohan Hedberg 	if (hcon->out) {
1451760b018bSJohan Hedberg 		local_addr = a;
1452760b018bSJohan Hedberg 		remote_addr = b;
1453760b018bSJohan Hedberg 		memcpy(io_cap, &smp->preq[1], 3);
1454760b018bSJohan Hedberg 	} else {
1455760b018bSJohan Hedberg 		local_addr = b;
1456760b018bSJohan Hedberg 		remote_addr = a;
1457760b018bSJohan Hedberg 		memcpy(io_cap, &smp->prsp[1], 3);
1458760b018bSJohan Hedberg 	}
1459760b018bSJohan Hedberg 
1460dddd3059SJohan Hedberg 	memset(r, 0, sizeof(r));
1461dddd3059SJohan Hedberg 
1462dddd3059SJohan Hedberg 	if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY)
146338606f14SJohan Hedberg 		put_unaligned_le32(hcon->passkey_notify, r);
1464760b018bSJohan Hedberg 
1465a29b0733SJohan Hedberg 	if (smp->method == REQ_OOB)
1466a29b0733SJohan Hedberg 		memcpy(r, smp->rr, 16);
1467a29b0733SJohan Hedberg 
1468760b018bSJohan Hedberg 	smp_f6(smp->tfm_cmac, smp->mackey, smp->prnd, smp->rrnd, r, io_cap,
1469760b018bSJohan Hedberg 	       local_addr, remote_addr, check.e);
1470760b018bSJohan Hedberg 
1471760b018bSJohan Hedberg 	smp_send_cmd(smp->conn, SMP_CMD_DHKEY_CHECK, sizeof(check), &check);
1472dddd3059SJohan Hedberg }
1473dddd3059SJohan Hedberg 
147438606f14SJohan Hedberg static u8 sc_passkey_send_confirm(struct smp_chan *smp)
147538606f14SJohan Hedberg {
147638606f14SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
147738606f14SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
147838606f14SJohan Hedberg 	struct smp_cmd_pairing_confirm cfm;
147938606f14SJohan Hedberg 	u8 r;
148038606f14SJohan Hedberg 
148138606f14SJohan Hedberg 	r = ((hcon->passkey_notify >> smp->passkey_round) & 0x01);
148238606f14SJohan Hedberg 	r |= 0x80;
148338606f14SJohan Hedberg 
148438606f14SJohan Hedberg 	get_random_bytes(smp->prnd, sizeof(smp->prnd));
148538606f14SJohan Hedberg 
148638606f14SJohan Hedberg 	if (smp_f4(smp->tfm_cmac, smp->local_pk, smp->remote_pk, smp->prnd, r,
148738606f14SJohan Hedberg 		   cfm.confirm_val))
148838606f14SJohan Hedberg 		return SMP_UNSPECIFIED;
148938606f14SJohan Hedberg 
149038606f14SJohan Hedberg 	smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cfm), &cfm);
149138606f14SJohan Hedberg 
149238606f14SJohan Hedberg 	return 0;
149338606f14SJohan Hedberg }
149438606f14SJohan Hedberg 
149538606f14SJohan Hedberg static u8 sc_passkey_round(struct smp_chan *smp, u8 smp_op)
149638606f14SJohan Hedberg {
149738606f14SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
149838606f14SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
149938606f14SJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
150038606f14SJohan Hedberg 	u8 cfm[16], r;
150138606f14SJohan Hedberg 
150238606f14SJohan Hedberg 	/* Ignore the PDU if we've already done 20 rounds (0 - 19) */
150338606f14SJohan Hedberg 	if (smp->passkey_round >= 20)
150438606f14SJohan Hedberg 		return 0;
150538606f14SJohan Hedberg 
150638606f14SJohan Hedberg 	switch (smp_op) {
150738606f14SJohan Hedberg 	case SMP_CMD_PAIRING_RANDOM:
150838606f14SJohan Hedberg 		r = ((hcon->passkey_notify >> smp->passkey_round) & 0x01);
150938606f14SJohan Hedberg 		r |= 0x80;
151038606f14SJohan Hedberg 
151138606f14SJohan Hedberg 		if (smp_f4(smp->tfm_cmac, smp->remote_pk, smp->local_pk,
151238606f14SJohan Hedberg 			   smp->rrnd, r, cfm))
151338606f14SJohan Hedberg 			return SMP_UNSPECIFIED;
151438606f14SJohan Hedberg 
1515329d8230SJason A. Donenfeld 		if (crypto_memneq(smp->pcnf, cfm, 16))
151638606f14SJohan Hedberg 			return SMP_CONFIRM_FAILED;
151738606f14SJohan Hedberg 
151838606f14SJohan Hedberg 		smp->passkey_round++;
151938606f14SJohan Hedberg 
152038606f14SJohan Hedberg 		if (smp->passkey_round == 20) {
152138606f14SJohan Hedberg 			/* Generate MacKey and LTK */
152238606f14SJohan Hedberg 			if (sc_mackey_and_ltk(smp, smp->mackey, smp->tk))
152338606f14SJohan Hedberg 				return SMP_UNSPECIFIED;
152438606f14SJohan Hedberg 		}
152538606f14SJohan Hedberg 
152638606f14SJohan Hedberg 		/* The round is only complete when the initiator
152738606f14SJohan Hedberg 		 * receives pairing random.
152838606f14SJohan Hedberg 		 */
152938606f14SJohan Hedberg 		if (!hcon->out) {
153038606f14SJohan Hedberg 			smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM,
153138606f14SJohan Hedberg 				     sizeof(smp->prnd), smp->prnd);
1532d3e54a87SJohan Hedberg 			if (smp->passkey_round == 20)
153338606f14SJohan Hedberg 				SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
1534d3e54a87SJohan Hedberg 			else
153538606f14SJohan Hedberg 				SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
153638606f14SJohan Hedberg 			return 0;
153738606f14SJohan Hedberg 		}
153838606f14SJohan Hedberg 
153938606f14SJohan Hedberg 		/* Start the next round */
154038606f14SJohan Hedberg 		if (smp->passkey_round != 20)
154138606f14SJohan Hedberg 			return sc_passkey_round(smp, 0);
154238606f14SJohan Hedberg 
154338606f14SJohan Hedberg 		/* Passkey rounds are complete - start DHKey Check */
154438606f14SJohan Hedberg 		sc_dhkey_check(smp);
154538606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
154638606f14SJohan Hedberg 
154738606f14SJohan Hedberg 		break;
154838606f14SJohan Hedberg 
154938606f14SJohan Hedberg 	case SMP_CMD_PAIRING_CONFIRM:
155038606f14SJohan Hedberg 		if (test_bit(SMP_FLAG_WAIT_USER, &smp->flags)) {
155138606f14SJohan Hedberg 			set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
155238606f14SJohan Hedberg 			return 0;
155338606f14SJohan Hedberg 		}
155438606f14SJohan Hedberg 
155538606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
155638606f14SJohan Hedberg 
155738606f14SJohan Hedberg 		if (hcon->out) {
155838606f14SJohan Hedberg 			smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM,
155938606f14SJohan Hedberg 				     sizeof(smp->prnd), smp->prnd);
156038606f14SJohan Hedberg 			return 0;
156138606f14SJohan Hedberg 		}
156238606f14SJohan Hedberg 
156338606f14SJohan Hedberg 		return sc_passkey_send_confirm(smp);
156438606f14SJohan Hedberg 
156538606f14SJohan Hedberg 	case SMP_CMD_PUBLIC_KEY:
156638606f14SJohan Hedberg 	default:
156738606f14SJohan Hedberg 		/* Initiating device starts the round */
156838606f14SJohan Hedberg 		if (!hcon->out)
156938606f14SJohan Hedberg 			return 0;
157038606f14SJohan Hedberg 
15712e1614f7SLuiz Augusto von Dentz 		bt_dev_dbg(hdev, "Starting passkey round %u",
157238606f14SJohan Hedberg 			   smp->passkey_round + 1);
157338606f14SJohan Hedberg 
157438606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
157538606f14SJohan Hedberg 
157638606f14SJohan Hedberg 		return sc_passkey_send_confirm(smp);
157738606f14SJohan Hedberg 	}
157838606f14SJohan Hedberg 
157938606f14SJohan Hedberg 	return 0;
158038606f14SJohan Hedberg }
158138606f14SJohan Hedberg 
1582dddd3059SJohan Hedberg static int sc_user_reply(struct smp_chan *smp, u16 mgmt_op, __le32 passkey)
1583dddd3059SJohan Hedberg {
158438606f14SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
158538606f14SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
158638606f14SJohan Hedberg 	u8 smp_op;
158738606f14SJohan Hedberg 
158838606f14SJohan Hedberg 	clear_bit(SMP_FLAG_WAIT_USER, &smp->flags);
158938606f14SJohan Hedberg 
1590dddd3059SJohan Hedberg 	switch (mgmt_op) {
1591dddd3059SJohan Hedberg 	case MGMT_OP_USER_PASSKEY_NEG_REPLY:
1592dddd3059SJohan Hedberg 		smp_failure(smp->conn, SMP_PASSKEY_ENTRY_FAILED);
1593dddd3059SJohan Hedberg 		return 0;
1594dddd3059SJohan Hedberg 	case MGMT_OP_USER_CONFIRM_NEG_REPLY:
1595dddd3059SJohan Hedberg 		smp_failure(smp->conn, SMP_NUMERIC_COMP_FAILED);
1596dddd3059SJohan Hedberg 		return 0;
159738606f14SJohan Hedberg 	case MGMT_OP_USER_PASSKEY_REPLY:
159838606f14SJohan Hedberg 		hcon->passkey_notify = le32_to_cpu(passkey);
159938606f14SJohan Hedberg 		smp->passkey_round = 0;
160038606f14SJohan Hedberg 
160138606f14SJohan Hedberg 		if (test_and_clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags))
160238606f14SJohan Hedberg 			smp_op = SMP_CMD_PAIRING_CONFIRM;
160338606f14SJohan Hedberg 		else
160438606f14SJohan Hedberg 			smp_op = 0;
160538606f14SJohan Hedberg 
160638606f14SJohan Hedberg 		if (sc_passkey_round(smp, smp_op))
160738606f14SJohan Hedberg 			return -EIO;
160838606f14SJohan Hedberg 
160938606f14SJohan Hedberg 		return 0;
1610dddd3059SJohan Hedberg 	}
1611dddd3059SJohan Hedberg 
1612d3e54a87SJohan Hedberg 	/* Initiator sends DHKey check first */
1613d3e54a87SJohan Hedberg 	if (hcon->out) {
161438606f14SJohan Hedberg 		sc_dhkey_check(smp);
1615d3e54a87SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
1616d3e54a87SJohan Hedberg 	} else if (test_and_clear_bit(SMP_FLAG_DHKEY_PENDING, &smp->flags)) {
1617d3e54a87SJohan Hedberg 		sc_dhkey_check(smp);
1618d3e54a87SJohan Hedberg 		sc_add_ltk(smp);
1619d3e54a87SJohan Hedberg 	}
1620760b018bSJohan Hedberg 
1621760b018bSJohan Hedberg 	return 0;
1622760b018bSJohan Hedberg }
1623760b018bSJohan Hedberg 
16242b64d153SBrian Gix int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
16252b64d153SBrian Gix {
1626b10e8017SJohan Hedberg 	struct l2cap_conn *conn = hcon->l2cap_data;
16275d88cc73SJohan Hedberg 	struct l2cap_chan *chan;
16282b64d153SBrian Gix 	struct smp_chan *smp;
16292b64d153SBrian Gix 	u32 value;
1630fc75cc86SJohan Hedberg 	int err;
16312b64d153SBrian Gix 
1632fc75cc86SJohan Hedberg 	if (!conn)
16332b64d153SBrian Gix 		return -ENOTCONN;
16342b64d153SBrian Gix 
16350ae8ef67SLuiz Augusto von Dentz 	bt_dev_dbg(conn->hcon->hdev, "");
16360ae8ef67SLuiz Augusto von Dentz 
16375d88cc73SJohan Hedberg 	chan = conn->smp;
16385d88cc73SJohan Hedberg 	if (!chan)
16395d88cc73SJohan Hedberg 		return -ENOTCONN;
16405d88cc73SJohan Hedberg 
1641fc75cc86SJohan Hedberg 	l2cap_chan_lock(chan);
1642fc75cc86SJohan Hedberg 	if (!chan->data) {
1643fc75cc86SJohan Hedberg 		err = -ENOTCONN;
1644fc75cc86SJohan Hedberg 		goto unlock;
1645fc75cc86SJohan Hedberg 	}
1646fc75cc86SJohan Hedberg 
16475d88cc73SJohan Hedberg 	smp = chan->data;
16482b64d153SBrian Gix 
1649760b018bSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
1650760b018bSJohan Hedberg 		err = sc_user_reply(smp, mgmt_op, passkey);
1651760b018bSJohan Hedberg 		goto unlock;
1652760b018bSJohan Hedberg 	}
1653760b018bSJohan Hedberg 
16542b64d153SBrian Gix 	switch (mgmt_op) {
16552b64d153SBrian Gix 	case MGMT_OP_USER_PASSKEY_REPLY:
16562b64d153SBrian Gix 		value = le32_to_cpu(passkey);
1657943a732aSJohan Hedberg 		memset(smp->tk, 0, sizeof(smp->tk));
16582e1614f7SLuiz Augusto von Dentz 		bt_dev_dbg(conn->hcon->hdev, "PassKey: %d", value);
1659943a732aSJohan Hedberg 		put_unaligned_le32(value, smp->tk);
166019186c7bSGustavo A. R. Silva 		fallthrough;
16612b64d153SBrian Gix 	case MGMT_OP_USER_CONFIRM_REPLY:
16624a74d658SJohan Hedberg 		set_bit(SMP_FLAG_TK_VALID, &smp->flags);
16632b64d153SBrian Gix 		break;
16642b64d153SBrian Gix 	case MGMT_OP_USER_PASSKEY_NEG_REPLY:
16652b64d153SBrian Gix 	case MGMT_OP_USER_CONFIRM_NEG_REPLY:
166684794e11SJohan Hedberg 		smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
1667fc75cc86SJohan Hedberg 		err = 0;
1668fc75cc86SJohan Hedberg 		goto unlock;
16692b64d153SBrian Gix 	default:
167084794e11SJohan Hedberg 		smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
1671fc75cc86SJohan Hedberg 		err = -EOPNOTSUPP;
1672fc75cc86SJohan Hedberg 		goto unlock;
16732b64d153SBrian Gix 	}
16742b64d153SBrian Gix 
1675fc75cc86SJohan Hedberg 	err = 0;
1676fc75cc86SJohan Hedberg 
16772b64d153SBrian Gix 	/* If it is our turn to send Pairing Confirm, do so now */
16781cc61144SJohan Hedberg 	if (test_bit(SMP_FLAG_CFM_PENDING, &smp->flags)) {
16791cc61144SJohan Hedberg 		u8 rsp = smp_confirm(smp);
16801cc61144SJohan Hedberg 		if (rsp)
16811cc61144SJohan Hedberg 			smp_failure(conn, rsp);
16821cc61144SJohan Hedberg 	}
16832b64d153SBrian Gix 
1684fc75cc86SJohan Hedberg unlock:
1685fc75cc86SJohan Hedberg 	l2cap_chan_unlock(chan);
1686fc75cc86SJohan Hedberg 	return err;
16872b64d153SBrian Gix }
16882b64d153SBrian Gix 
1689b5ae344dSJohan Hedberg static void build_bredr_pairing_cmd(struct smp_chan *smp,
1690b5ae344dSJohan Hedberg 				    struct smp_cmd_pairing *req,
1691b5ae344dSJohan Hedberg 				    struct smp_cmd_pairing *rsp)
1692b5ae344dSJohan Hedberg {
1693b5ae344dSJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
1694b5ae344dSJohan Hedberg 	struct hci_dev *hdev = conn->hcon->hdev;
1695b5ae344dSJohan Hedberg 	u8 local_dist = 0, remote_dist = 0;
1696b5ae344dSJohan Hedberg 
1697d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_BONDABLE)) {
1698b5ae344dSJohan Hedberg 		local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
1699b5ae344dSJohan Hedberg 		remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
1700b5ae344dSJohan Hedberg 	}
1701b5ae344dSJohan Hedberg 
1702d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_RPA_RESOLVING))
1703b5ae344dSJohan Hedberg 		remote_dist |= SMP_DIST_ID_KEY;
1704b5ae344dSJohan Hedberg 
1705d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_PRIVACY))
1706b5ae344dSJohan Hedberg 		local_dist |= SMP_DIST_ID_KEY;
1707b5ae344dSJohan Hedberg 
1708b5ae344dSJohan Hedberg 	if (!rsp) {
1709b5ae344dSJohan Hedberg 		memset(req, 0, sizeof(*req));
1710b5ae344dSJohan Hedberg 
1711a62da6f1SJohan Hedberg 		req->auth_req        = SMP_AUTH_CT2;
1712b5ae344dSJohan Hedberg 		req->init_key_dist   = local_dist;
1713b5ae344dSJohan Hedberg 		req->resp_key_dist   = remote_dist;
1714e3f6a257SJohan Hedberg 		req->max_key_size    = conn->hcon->enc_key_size;
1715b5ae344dSJohan Hedberg 
1716b5ae344dSJohan Hedberg 		smp->remote_key_dist = remote_dist;
1717b5ae344dSJohan Hedberg 
1718b5ae344dSJohan Hedberg 		return;
1719b5ae344dSJohan Hedberg 	}
1720b5ae344dSJohan Hedberg 
1721b5ae344dSJohan Hedberg 	memset(rsp, 0, sizeof(*rsp));
1722b5ae344dSJohan Hedberg 
1723a62da6f1SJohan Hedberg 	rsp->auth_req        = SMP_AUTH_CT2;
1724e3f6a257SJohan Hedberg 	rsp->max_key_size    = conn->hcon->enc_key_size;
1725b5ae344dSJohan Hedberg 	rsp->init_key_dist   = req->init_key_dist & remote_dist;
1726b5ae344dSJohan Hedberg 	rsp->resp_key_dist   = req->resp_key_dist & local_dist;
1727b5ae344dSJohan Hedberg 
1728b5ae344dSJohan Hedberg 	smp->remote_key_dist = rsp->init_key_dist;
1729b5ae344dSJohan Hedberg }
1730b5ae344dSJohan Hedberg 
1731da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
173288ba43b6SAnderson Briglia {
17333158c50cSVinicius Costa Gomes 	struct smp_cmd_pairing rsp, *req = (void *) skb->data;
1734fc75cc86SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
1735b3c6410bSJohan Hedberg 	struct hci_dev *hdev = conn->hcon->hdev;
17368aab4757SVinicius Costa Gomes 	struct smp_chan *smp;
1737c7262e71SJohan Hedberg 	u8 key_size, auth, sec_level;
17388aab4757SVinicius Costa Gomes 	int ret;
173988ba43b6SAnderson Briglia 
17402e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "conn %p", conn);
174188ba43b6SAnderson Briglia 
1742c46b98beSJohan Hedberg 	if (skb->len < sizeof(*req))
174338e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1744c46b98beSJohan Hedberg 
174540bef302SJohan Hedberg 	if (conn->hcon->role != HCI_ROLE_SLAVE)
17462b64d153SBrian Gix 		return SMP_CMD_NOTSUPP;
17472b64d153SBrian Gix 
1748fc75cc86SJohan Hedberg 	if (!chan->data)
17498aab4757SVinicius Costa Gomes 		smp = smp_chan_create(conn);
1750fc75cc86SJohan Hedberg 	else
17515d88cc73SJohan Hedberg 		smp = chan->data;
1752d26a2345SVinicius Costa Gomes 
1753d08fd0e7SAndrei Emeltchenko 	if (!smp)
1754d08fd0e7SAndrei Emeltchenko 		return SMP_UNSPECIFIED;
1755d08fd0e7SAndrei Emeltchenko 
1756c05b9339SJohan Hedberg 	/* We didn't start the pairing, so match remote */
17570edb14deSJohan Hedberg 	auth = req->auth_req & AUTH_REQ_MASK(hdev);
1758c05b9339SJohan Hedberg 
1759d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BONDABLE) &&
1760c05b9339SJohan Hedberg 	    (auth & SMP_AUTH_BONDING))
1761b3c6410bSJohan Hedberg 		return SMP_PAIRING_NOTSUPP;
1762b3c6410bSJohan Hedberg 
1763d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SC_ONLY) && !(auth & SMP_AUTH_SC))
1764903b71c7SJohan Hedberg 		return SMP_AUTH_REQUIREMENTS;
1765903b71c7SJohan Hedberg 
17661c1def09SVinicius Costa Gomes 	smp->preq[0] = SMP_CMD_PAIRING_REQ;
17671c1def09SVinicius Costa Gomes 	memcpy(&smp->preq[1], req, sizeof(*req));
17683158c50cSVinicius Costa Gomes 	skb_pull(skb, sizeof(*req));
176988ba43b6SAnderson Briglia 
1770cb06d366SJohan Hedberg 	/* If the remote side's OOB flag is set it means it has
1771cb06d366SJohan Hedberg 	 * successfully received our local OOB data - therefore set the
1772cb06d366SJohan Hedberg 	 * flag to indicate that local OOB is in use.
1773cb06d366SJohan Hedberg 	 */
177494f14e47SJohan Hedberg 	if (req->oob_flag == SMP_OOB_PRESENT && SMP_DEV(hdev)->local_oob)
177558428563SJohan Hedberg 		set_bit(SMP_FLAG_LOCAL_OOB, &smp->flags);
177658428563SJohan Hedberg 
1777b5ae344dSJohan Hedberg 	/* SMP over BR/EDR requires special treatment */
1778b5ae344dSJohan Hedberg 	if (conn->hcon->type == ACL_LINK) {
1779b5ae344dSJohan Hedberg 		/* We must have a BR/EDR SC link */
178008f63cc5SMarcel Holtmann 		if (!test_bit(HCI_CONN_AES_CCM, &conn->hcon->flags) &&
1781b7cb93e5SMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP))
1782b5ae344dSJohan Hedberg 			return SMP_CROSS_TRANSP_NOT_ALLOWED;
1783b5ae344dSJohan Hedberg 
1784b5ae344dSJohan Hedberg 		set_bit(SMP_FLAG_SC, &smp->flags);
1785b5ae344dSJohan Hedberg 
1786b5ae344dSJohan Hedberg 		build_bredr_pairing_cmd(smp, req, &rsp);
1787b5ae344dSJohan Hedberg 
1788a62da6f1SJohan Hedberg 		if (req->auth_req & SMP_AUTH_CT2)
1789a62da6f1SJohan Hedberg 			set_bit(SMP_FLAG_CT2, &smp->flags);
1790a62da6f1SJohan Hedberg 
1791b5ae344dSJohan Hedberg 		key_size = min(req->max_key_size, rsp.max_key_size);
1792b5ae344dSJohan Hedberg 		if (check_enc_key_size(conn, key_size))
1793b5ae344dSJohan Hedberg 			return SMP_ENC_KEY_SIZE;
1794b5ae344dSJohan Hedberg 
1795b5ae344dSJohan Hedberg 		/* Clear bits which are generated but not distributed */
1796b5ae344dSJohan Hedberg 		smp->remote_key_dist &= ~SMP_SC_NO_DIST;
1797b5ae344dSJohan Hedberg 
1798b5ae344dSJohan Hedberg 		smp->prsp[0] = SMP_CMD_PAIRING_RSP;
1799b5ae344dSJohan Hedberg 		memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
1800b5ae344dSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
1801b5ae344dSJohan Hedberg 
1802b5ae344dSJohan Hedberg 		smp_distribute_keys(smp);
1803b5ae344dSJohan Hedberg 		return 0;
1804b5ae344dSJohan Hedberg 	}
1805b5ae344dSJohan Hedberg 
18065e3d3d9bSJohan Hedberg 	build_pairing_cmd(conn, req, &rsp, auth);
18075e3d3d9bSJohan Hedberg 
1808a62da6f1SJohan Hedberg 	if (rsp.auth_req & SMP_AUTH_SC) {
18095e3d3d9bSJohan Hedberg 		set_bit(SMP_FLAG_SC, &smp->flags);
18105e3d3d9bSJohan Hedberg 
1811a62da6f1SJohan Hedberg 		if (rsp.auth_req & SMP_AUTH_CT2)
1812a62da6f1SJohan Hedberg 			set_bit(SMP_FLAG_CT2, &smp->flags);
1813a62da6f1SJohan Hedberg 	}
1814a62da6f1SJohan Hedberg 
18155be5e275SJohan Hedberg 	if (conn->hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
18161afc2a1aSJohan Hedberg 		sec_level = BT_SECURITY_MEDIUM;
18171afc2a1aSJohan Hedberg 	else
1818c7262e71SJohan Hedberg 		sec_level = authreq_to_seclevel(auth);
18191afc2a1aSJohan Hedberg 
1820c7262e71SJohan Hedberg 	if (sec_level > conn->hcon->pending_sec_level)
1821c7262e71SJohan Hedberg 		conn->hcon->pending_sec_level = sec_level;
1822fdde0a26SIdo Yariv 
182349c922bbSStephen Hemminger 	/* If we need MITM check that it can be achieved */
18242ed8f65cSJohan Hedberg 	if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
18252ed8f65cSJohan Hedberg 		u8 method;
18262ed8f65cSJohan Hedberg 
18272ed8f65cSJohan Hedberg 		method = get_auth_method(smp, conn->hcon->io_capability,
18282ed8f65cSJohan Hedberg 					 req->io_capability);
18292ed8f65cSJohan Hedberg 		if (method == JUST_WORKS || method == JUST_CFM)
18302ed8f65cSJohan Hedberg 			return SMP_AUTH_REQUIREMENTS;
18312ed8f65cSJohan Hedberg 	}
18322ed8f65cSJohan Hedberg 
18333158c50cSVinicius Costa Gomes 	key_size = min(req->max_key_size, rsp.max_key_size);
18343158c50cSVinicius Costa Gomes 	if (check_enc_key_size(conn, key_size))
18353158c50cSVinicius Costa Gomes 		return SMP_ENC_KEY_SIZE;
183688ba43b6SAnderson Briglia 
1837e84a6b13SJohan Hedberg 	get_random_bytes(smp->prnd, sizeof(smp->prnd));
18388aab4757SVinicius Costa Gomes 
18391c1def09SVinicius Costa Gomes 	smp->prsp[0] = SMP_CMD_PAIRING_RSP;
18401c1def09SVinicius Costa Gomes 	memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
1841f01ead31SAnderson Briglia 
18423158c50cSVinicius Costa Gomes 	smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
18433b19146dSJohan Hedberg 
18443b19146dSJohan Hedberg 	clear_bit(SMP_FLAG_INITIATOR, &smp->flags);
18453b19146dSJohan Hedberg 
184619c5ce9cSJohan Hedberg 	/* Strictly speaking we shouldn't allow Pairing Confirm for the
184719c5ce9cSJohan Hedberg 	 * SC case, however some implementations incorrectly copy RFU auth
184819c5ce9cSJohan Hedberg 	 * req bits from our security request, which may create a false
184919c5ce9cSJohan Hedberg 	 * positive SC enablement.
185019c5ce9cSJohan Hedberg 	 */
185119c5ce9cSJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
185219c5ce9cSJohan Hedberg 
18533b19146dSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
18543b19146dSJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PUBLIC_KEY);
18553b19146dSJohan Hedberg 		/* Clear bits which are generated but not distributed */
18563b19146dSJohan Hedberg 		smp->remote_key_dist &= ~SMP_SC_NO_DIST;
18573b19146dSJohan Hedberg 		/* Wait for Public Key from Initiating Device */
18583b19146dSJohan Hedberg 		return 0;
18593b19146dSJohan Hedberg 	}
1860da85e5e5SVinicius Costa Gomes 
18612b64d153SBrian Gix 	/* Request setup of TK */
18622b64d153SBrian Gix 	ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability);
18632b64d153SBrian Gix 	if (ret)
18642b64d153SBrian Gix 		return SMP_UNSPECIFIED;
18652b64d153SBrian Gix 
1866da85e5e5SVinicius Costa Gomes 	return 0;
186788ba43b6SAnderson Briglia }
186888ba43b6SAnderson Briglia 
18693b19146dSJohan Hedberg static u8 sc_send_public_key(struct smp_chan *smp)
18703b19146dSJohan Hedberg {
187170157ef5SJohan Hedberg 	struct hci_dev *hdev = smp->conn->hcon->hdev;
187270157ef5SJohan Hedberg 
187356860245SMarcel Holtmann 	bt_dev_dbg(hdev, "");
18743b19146dSJohan Hedberg 
18751a8bab4fSJohan Hedberg 	if (test_bit(SMP_FLAG_LOCAL_OOB, &smp->flags)) {
187633d0c030SMarcel Holtmann 		struct l2cap_chan *chan = hdev->smp_data;
187733d0c030SMarcel Holtmann 		struct smp_dev *smp_dev;
187833d0c030SMarcel Holtmann 
187933d0c030SMarcel Holtmann 		if (!chan || !chan->data)
188033d0c030SMarcel Holtmann 			return SMP_UNSPECIFIED;
188133d0c030SMarcel Holtmann 
188233d0c030SMarcel Holtmann 		smp_dev = chan->data;
188333d0c030SMarcel Holtmann 
188433d0c030SMarcel Holtmann 		memcpy(smp->local_pk, smp_dev->local_pk, 64);
1885fb334feeSMarcel Holtmann 		memcpy(smp->lr, smp_dev->local_rand, 16);
188633d0c030SMarcel Holtmann 
188733d0c030SMarcel Holtmann 		if (smp_dev->debug_key)
188833d0c030SMarcel Holtmann 			set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags);
188933d0c030SMarcel Holtmann 
189033d0c030SMarcel Holtmann 		goto done;
189133d0c030SMarcel Holtmann 	}
189233d0c030SMarcel Holtmann 
1893d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS)) {
18942e1614f7SLuiz Augusto von Dentz 		bt_dev_dbg(hdev, "Using debug keys");
1895c0153b0bSTudor Ambarus 		if (set_ecdh_privkey(smp->tfm_ecdh, debug_sk))
1896c0153b0bSTudor Ambarus 			return SMP_UNSPECIFIED;
189770157ef5SJohan Hedberg 		memcpy(smp->local_pk, debug_pk, 64);
189870157ef5SJohan Hedberg 		set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags);
189970157ef5SJohan Hedberg 	} else {
19006c0dcc50SJohan Hedberg 		while (true) {
1901c0153b0bSTudor Ambarus 			/* Generate key pair for Secure Connections */
1902c0153b0bSTudor Ambarus 			if (generate_ecdh_keys(smp->tfm_ecdh, smp->local_pk))
19033b19146dSJohan Hedberg 				return SMP_UNSPECIFIED;
19043b19146dSJohan Hedberg 
190570157ef5SJohan Hedberg 			/* This is unlikely, but we need to check that
190691641b79SZheng Yongjun 			 * we didn't accidentally generate a debug key.
19076c0dcc50SJohan Hedberg 			 */
1908c0153b0bSTudor Ambarus 			if (crypto_memneq(smp->local_pk, debug_pk, 64))
19096c0dcc50SJohan Hedberg 				break;
19106c0dcc50SJohan Hedberg 		}
191170157ef5SJohan Hedberg 	}
19126c0dcc50SJohan Hedberg 
191333d0c030SMarcel Holtmann done:
1914c7a3d57dSJohan Hedberg 	SMP_DBG("Local Public Key X: %32phN", smp->local_pk);
19158e4e2ee5SMarcel Holtmann 	SMP_DBG("Local Public Key Y: %32phN", smp->local_pk + 32);
19163b19146dSJohan Hedberg 
19173b19146dSJohan Hedberg 	smp_send_cmd(smp->conn, SMP_CMD_PUBLIC_KEY, 64, smp->local_pk);
19183b19146dSJohan Hedberg 
19193b19146dSJohan Hedberg 	return 0;
19203b19146dSJohan Hedberg }
19213b19146dSJohan Hedberg 
1922da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
192388ba43b6SAnderson Briglia {
19243158c50cSVinicius Costa Gomes 	struct smp_cmd_pairing *req, *rsp = (void *) skb->data;
19255d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
19265d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
19270edb14deSJohan Hedberg 	struct hci_dev *hdev = conn->hcon->hdev;
19283a7dbfb8SJohan Hedberg 	u8 key_size, auth;
19297d24ddccSAnderson Briglia 	int ret;
193088ba43b6SAnderson Briglia 
19312e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "conn %p", conn);
193288ba43b6SAnderson Briglia 
1933c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rsp))
193438e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1935c46b98beSJohan Hedberg 
193640bef302SJohan Hedberg 	if (conn->hcon->role != HCI_ROLE_MASTER)
19372b64d153SBrian Gix 		return SMP_CMD_NOTSUPP;
19382b64d153SBrian Gix 
19393158c50cSVinicius Costa Gomes 	skb_pull(skb, sizeof(*rsp));
1940da85e5e5SVinicius Costa Gomes 
19411c1def09SVinicius Costa Gomes 	req = (void *) &smp->preq[1];
19423158c50cSVinicius Costa Gomes 
19433158c50cSVinicius Costa Gomes 	key_size = min(req->max_key_size, rsp->max_key_size);
19443158c50cSVinicius Costa Gomes 	if (check_enc_key_size(conn, key_size))
19453158c50cSVinicius Costa Gomes 		return SMP_ENC_KEY_SIZE;
19463158c50cSVinicius Costa Gomes 
19470edb14deSJohan Hedberg 	auth = rsp->auth_req & AUTH_REQ_MASK(hdev);
1948c05b9339SJohan Hedberg 
1949d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SC_ONLY) && !(auth & SMP_AUTH_SC))
1950903b71c7SJohan Hedberg 		return SMP_AUTH_REQUIREMENTS;
1951903b71c7SJohan Hedberg 
1952cb06d366SJohan Hedberg 	/* If the remote side's OOB flag is set it means it has
1953cb06d366SJohan Hedberg 	 * successfully received our local OOB data - therefore set the
1954cb06d366SJohan Hedberg 	 * flag to indicate that local OOB is in use.
1955cb06d366SJohan Hedberg 	 */
195694f14e47SJohan Hedberg 	if (rsp->oob_flag == SMP_OOB_PRESENT && SMP_DEV(hdev)->local_oob)
195758428563SJohan Hedberg 		set_bit(SMP_FLAG_LOCAL_OOB, &smp->flags);
195858428563SJohan Hedberg 
1959b5ae344dSJohan Hedberg 	smp->prsp[0] = SMP_CMD_PAIRING_RSP;
1960b5ae344dSJohan Hedberg 	memcpy(&smp->prsp[1], rsp, sizeof(*rsp));
1961b5ae344dSJohan Hedberg 
1962b5ae344dSJohan Hedberg 	/* Update remote key distribution in case the remote cleared
1963b5ae344dSJohan Hedberg 	 * some bits that we had enabled in our request.
1964b5ae344dSJohan Hedberg 	 */
1965b5ae344dSJohan Hedberg 	smp->remote_key_dist &= rsp->resp_key_dist;
1966b5ae344dSJohan Hedberg 
1967a62da6f1SJohan Hedberg 	if ((req->auth_req & SMP_AUTH_CT2) && (auth & SMP_AUTH_CT2))
1968a62da6f1SJohan Hedberg 		set_bit(SMP_FLAG_CT2, &smp->flags);
1969a62da6f1SJohan Hedberg 
1970b5ae344dSJohan Hedberg 	/* For BR/EDR this means we're done and can start phase 3 */
1971b5ae344dSJohan Hedberg 	if (conn->hcon->type == ACL_LINK) {
1972b5ae344dSJohan Hedberg 		/* Clear bits which are generated but not distributed */
1973b5ae344dSJohan Hedberg 		smp->remote_key_dist &= ~SMP_SC_NO_DIST;
1974b5ae344dSJohan Hedberg 		smp_distribute_keys(smp);
1975b5ae344dSJohan Hedberg 		return 0;
1976b5ae344dSJohan Hedberg 	}
1977b5ae344dSJohan Hedberg 
197865668776SJohan Hedberg 	if ((req->auth_req & SMP_AUTH_SC) && (auth & SMP_AUTH_SC))
197965668776SJohan Hedberg 		set_bit(SMP_FLAG_SC, &smp->flags);
1980d2eb9e10SJohan Hedberg 	else if (conn->hcon->pending_sec_level > BT_SECURITY_HIGH)
1981d2eb9e10SJohan Hedberg 		conn->hcon->pending_sec_level = BT_SECURITY_HIGH;
198265668776SJohan Hedberg 
198349c922bbSStephen Hemminger 	/* If we need MITM check that it can be achieved */
19842ed8f65cSJohan Hedberg 	if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
19852ed8f65cSJohan Hedberg 		u8 method;
19862ed8f65cSJohan Hedberg 
19872ed8f65cSJohan Hedberg 		method = get_auth_method(smp, req->io_capability,
19882ed8f65cSJohan Hedberg 					 rsp->io_capability);
19892ed8f65cSJohan Hedberg 		if (method == JUST_WORKS || method == JUST_CFM)
19902ed8f65cSJohan Hedberg 			return SMP_AUTH_REQUIREMENTS;
19912ed8f65cSJohan Hedberg 	}
19922ed8f65cSJohan Hedberg 
1993e84a6b13SJohan Hedberg 	get_random_bytes(smp->prnd, sizeof(smp->prnd));
19947d24ddccSAnderson Briglia 
1995fdcc4becSJohan Hedberg 	/* Update remote key distribution in case the remote cleared
1996fdcc4becSJohan Hedberg 	 * some bits that we had enabled in our request.
1997fdcc4becSJohan Hedberg 	 */
1998fdcc4becSJohan Hedberg 	smp->remote_key_dist &= rsp->resp_key_dist;
1999fdcc4becSJohan Hedberg 
20003b19146dSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
20013b19146dSJohan Hedberg 		/* Clear bits which are generated but not distributed */
20023b19146dSJohan Hedberg 		smp->remote_key_dist &= ~SMP_SC_NO_DIST;
20033b19146dSJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PUBLIC_KEY);
20043b19146dSJohan Hedberg 		return sc_send_public_key(smp);
20053b19146dSJohan Hedberg 	}
20063b19146dSJohan Hedberg 
2007c05b9339SJohan Hedberg 	auth |= req->auth_req;
20082b64d153SBrian Gix 
2009476585ecSJohan Hedberg 	ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability);
20102b64d153SBrian Gix 	if (ret)
20112b64d153SBrian Gix 		return SMP_UNSPECIFIED;
20122b64d153SBrian Gix 
20134a74d658SJohan Hedberg 	set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
20142b64d153SBrian Gix 
20152b64d153SBrian Gix 	/* Can't compose response until we have been confirmed */
20164a74d658SJohan Hedberg 	if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
20171cc61144SJohan Hedberg 		return smp_confirm(smp);
2018da85e5e5SVinicius Costa Gomes 
2019da85e5e5SVinicius Costa Gomes 	return 0;
202088ba43b6SAnderson Briglia }
202188ba43b6SAnderson Briglia 
2022dcee2b32SJohan Hedberg static u8 sc_check_confirm(struct smp_chan *smp)
2023dcee2b32SJohan Hedberg {
2024dcee2b32SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
2025dcee2b32SJohan Hedberg 
20262e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(conn->hcon->hdev, "");
2027dcee2b32SJohan Hedberg 
202838606f14SJohan Hedberg 	if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY)
202938606f14SJohan Hedberg 		return sc_passkey_round(smp, SMP_CMD_PAIRING_CONFIRM);
203038606f14SJohan Hedberg 
2031dcee2b32SJohan Hedberg 	if (conn->hcon->out) {
2032dcee2b32SJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
2033dcee2b32SJohan Hedberg 			     smp->prnd);
2034dcee2b32SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
2035dcee2b32SJohan Hedberg 	}
2036dcee2b32SJohan Hedberg 
2037dcee2b32SJohan Hedberg 	return 0;
2038dcee2b32SJohan Hedberg }
2039dcee2b32SJohan Hedberg 
204019c5ce9cSJohan Hedberg /* Work-around for some implementations that incorrectly copy RFU bits
204119c5ce9cSJohan Hedberg  * from our security request and thereby create the impression that
204219c5ce9cSJohan Hedberg  * we're doing SC when in fact the remote doesn't support it.
204319c5ce9cSJohan Hedberg  */
204419c5ce9cSJohan Hedberg static int fixup_sc_false_positive(struct smp_chan *smp)
204519c5ce9cSJohan Hedberg {
204619c5ce9cSJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
204719c5ce9cSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
204819c5ce9cSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
204919c5ce9cSJohan Hedberg 	struct smp_cmd_pairing *req, *rsp;
205019c5ce9cSJohan Hedberg 	u8 auth;
205119c5ce9cSJohan Hedberg 
2052*fad646e1SArchie Pusaka 	/* The issue is only observed when we're in responder role */
205319c5ce9cSJohan Hedberg 	if (hcon->out)
205419c5ce9cSJohan Hedberg 		return SMP_UNSPECIFIED;
205519c5ce9cSJohan Hedberg 
205619c5ce9cSJohan Hedberg 	if (hci_dev_test_flag(hdev, HCI_SC_ONLY)) {
20572064ee33SMarcel Holtmann 		bt_dev_err(hdev, "refusing legacy fallback in SC-only mode");
205819c5ce9cSJohan Hedberg 		return SMP_UNSPECIFIED;
205919c5ce9cSJohan Hedberg 	}
206019c5ce9cSJohan Hedberg 
20612064ee33SMarcel Holtmann 	bt_dev_err(hdev, "trying to fall back to legacy SMP");
206219c5ce9cSJohan Hedberg 
206319c5ce9cSJohan Hedberg 	req = (void *) &smp->preq[1];
206419c5ce9cSJohan Hedberg 	rsp = (void *) &smp->prsp[1];
206519c5ce9cSJohan Hedberg 
206619c5ce9cSJohan Hedberg 	/* Rebuild key dist flags which may have been cleared for SC */
206719c5ce9cSJohan Hedberg 	smp->remote_key_dist = (req->init_key_dist & rsp->resp_key_dist);
206819c5ce9cSJohan Hedberg 
206919c5ce9cSJohan Hedberg 	auth = req->auth_req & AUTH_REQ_MASK(hdev);
207019c5ce9cSJohan Hedberg 
207119c5ce9cSJohan Hedberg 	if (tk_request(conn, 0, auth, rsp->io_capability, req->io_capability)) {
20722064ee33SMarcel Holtmann 		bt_dev_err(hdev, "failed to fall back to legacy SMP");
207319c5ce9cSJohan Hedberg 		return SMP_UNSPECIFIED;
207419c5ce9cSJohan Hedberg 	}
207519c5ce9cSJohan Hedberg 
207619c5ce9cSJohan Hedberg 	clear_bit(SMP_FLAG_SC, &smp->flags);
207719c5ce9cSJohan Hedberg 
207819c5ce9cSJohan Hedberg 	return 0;
207919c5ce9cSJohan Hedberg }
208019c5ce9cSJohan Hedberg 
2081da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
208288ba43b6SAnderson Briglia {
20835d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
20845d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
20852e1614f7SLuiz Augusto von Dentz 	struct hci_conn *hcon = conn->hcon;
20862e1614f7SLuiz Augusto von Dentz 	struct hci_dev *hdev = hcon->hdev;
20877d24ddccSAnderson Briglia 
2088*fad646e1SArchie Pusaka 	bt_dev_dbg(hdev, "conn %p %s", conn,
2089*fad646e1SArchie Pusaka 		   hcon->out ? "initiator" : "responder");
209088ba43b6SAnderson Briglia 
2091c46b98beSJohan Hedberg 	if (skb->len < sizeof(smp->pcnf))
209238e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2093c46b98beSJohan Hedberg 
20941c1def09SVinicius Costa Gomes 	memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf));
20951c1def09SVinicius Costa Gomes 	skb_pull(skb, sizeof(smp->pcnf));
20967d24ddccSAnderson Briglia 
209719c5ce9cSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
209819c5ce9cSJohan Hedberg 		int ret;
209919c5ce9cSJohan Hedberg 
210019c5ce9cSJohan Hedberg 		/* Public Key exchange must happen before any other steps */
210119c5ce9cSJohan Hedberg 		if (test_bit(SMP_FLAG_REMOTE_PK, &smp->flags))
2102dcee2b32SJohan Hedberg 			return sc_check_confirm(smp);
2103dcee2b32SJohan Hedberg 
21042e1614f7SLuiz Augusto von Dentz 		bt_dev_err(hdev, "Unexpected SMP Pairing Confirm");
210519c5ce9cSJohan Hedberg 
210619c5ce9cSJohan Hedberg 		ret = fixup_sc_false_positive(smp);
210719c5ce9cSJohan Hedberg 		if (ret)
210819c5ce9cSJohan Hedberg 			return ret;
210919c5ce9cSJohan Hedberg 	}
211019c5ce9cSJohan Hedberg 
2111b28b4943SJohan Hedberg 	if (conn->hcon->out) {
2112943a732aSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
2113943a732aSJohan Hedberg 			     smp->prnd);
2114b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
2115b28b4943SJohan Hedberg 		return 0;
2116b28b4943SJohan Hedberg 	}
2117b28b4943SJohan Hedberg 
2118b28b4943SJohan Hedberg 	if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
21191cc61144SJohan Hedberg 		return smp_confirm(smp);
2120983f9814SMarcel Holtmann 
21214a74d658SJohan Hedberg 	set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
2122da85e5e5SVinicius Costa Gomes 
2123da85e5e5SVinicius Costa Gomes 	return 0;
212488ba43b6SAnderson Briglia }
212588ba43b6SAnderson Briglia 
2126da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
212788ba43b6SAnderson Briglia {
21285d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
21295d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
2130191dc7feSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
2131eed467b5SHoward Chung 	u8 *pkax, *pkbx, *na, *nb, confirm_hint;
2132191dc7feSJohan Hedberg 	u32 passkey;
2133191dc7feSJohan Hedberg 	int err;
21347d24ddccSAnderson Briglia 
21352e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hcon->hdev, "conn %p", conn);
21367d24ddccSAnderson Briglia 
2137c46b98beSJohan Hedberg 	if (skb->len < sizeof(smp->rrnd))
213838e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2139c46b98beSJohan Hedberg 
2140943a732aSJohan Hedberg 	memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd));
21418aab4757SVinicius Costa Gomes 	skb_pull(skb, sizeof(smp->rrnd));
214288ba43b6SAnderson Briglia 
2143191dc7feSJohan Hedberg 	if (!test_bit(SMP_FLAG_SC, &smp->flags))
2144861580a9SJohan Hedberg 		return smp_random(smp);
2145191dc7feSJohan Hedberg 
2146580039e8SJohan Hedberg 	if (hcon->out) {
2147580039e8SJohan Hedberg 		pkax = smp->local_pk;
2148580039e8SJohan Hedberg 		pkbx = smp->remote_pk;
2149580039e8SJohan Hedberg 		na   = smp->prnd;
2150580039e8SJohan Hedberg 		nb   = smp->rrnd;
2151580039e8SJohan Hedberg 	} else {
2152580039e8SJohan Hedberg 		pkax = smp->remote_pk;
2153580039e8SJohan Hedberg 		pkbx = smp->local_pk;
2154580039e8SJohan Hedberg 		na   = smp->rrnd;
2155580039e8SJohan Hedberg 		nb   = smp->prnd;
2156580039e8SJohan Hedberg 	}
2157580039e8SJohan Hedberg 
2158a29b0733SJohan Hedberg 	if (smp->method == REQ_OOB) {
2159a29b0733SJohan Hedberg 		if (!hcon->out)
2160a29b0733SJohan Hedberg 			smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM,
2161a29b0733SJohan Hedberg 				     sizeof(smp->prnd), smp->prnd);
2162a29b0733SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
2163a29b0733SJohan Hedberg 		goto mackey_and_ltk;
2164a29b0733SJohan Hedberg 	}
2165a29b0733SJohan Hedberg 
216638606f14SJohan Hedberg 	/* Passkey entry has special treatment */
216738606f14SJohan Hedberg 	if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY)
216838606f14SJohan Hedberg 		return sc_passkey_round(smp, SMP_CMD_PAIRING_RANDOM);
216938606f14SJohan Hedberg 
2170191dc7feSJohan Hedberg 	if (hcon->out) {
2171191dc7feSJohan Hedberg 		u8 cfm[16];
2172191dc7feSJohan Hedberg 
2173191dc7feSJohan Hedberg 		err = smp_f4(smp->tfm_cmac, smp->remote_pk, smp->local_pk,
2174191dc7feSJohan Hedberg 			     smp->rrnd, 0, cfm);
2175191dc7feSJohan Hedberg 		if (err)
2176191dc7feSJohan Hedberg 			return SMP_UNSPECIFIED;
2177191dc7feSJohan Hedberg 
2178329d8230SJason A. Donenfeld 		if (crypto_memneq(smp->pcnf, cfm, 16))
2179191dc7feSJohan Hedberg 			return SMP_CONFIRM_FAILED;
2180191dc7feSJohan Hedberg 	} else {
2181191dc7feSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
2182191dc7feSJohan Hedberg 			     smp->prnd);
2183191dc7feSJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
2184cee5f20fSHoward Chung 
2185cee5f20fSHoward Chung 		/* Only Just-Works pairing requires extra checks */
2186cee5f20fSHoward Chung 		if (smp->method != JUST_WORKS)
2187cee5f20fSHoward Chung 			goto mackey_and_ltk;
2188cee5f20fSHoward Chung 
2189cee5f20fSHoward Chung 		/* If there already exists long term key in local host, leave
2190cee5f20fSHoward Chung 		 * the decision to user space since the remote device could
2191cee5f20fSHoward Chung 		 * be legitimate or malicious.
2192cee5f20fSHoward Chung 		 */
2193cee5f20fSHoward Chung 		if (hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
2194cee5f20fSHoward Chung 				 hcon->role)) {
2195eed467b5SHoward Chung 			/* Set passkey to 0. The value can be any number since
2196eed467b5SHoward Chung 			 * it'll be ignored anyway.
2197eed467b5SHoward Chung 			 */
2198eed467b5SHoward Chung 			passkey = 0;
2199eed467b5SHoward Chung 			confirm_hint = 1;
2200eed467b5SHoward Chung 			goto confirm;
2201cee5f20fSHoward Chung 		}
2202191dc7feSJohan Hedberg 	}
2203191dc7feSJohan Hedberg 
2204a29b0733SJohan Hedberg mackey_and_ltk:
2205760b018bSJohan Hedberg 	/* Generate MacKey and LTK */
2206760b018bSJohan Hedberg 	err = sc_mackey_and_ltk(smp, smp->mackey, smp->tk);
2207760b018bSJohan Hedberg 	if (err)
2208760b018bSJohan Hedberg 		return SMP_UNSPECIFIED;
2209760b018bSJohan Hedberg 
2210ffee202aSSonny Sasaka 	if (smp->method == REQ_OOB) {
2211dddd3059SJohan Hedberg 		if (hcon->out) {
221238606f14SJohan Hedberg 			sc_dhkey_check(smp);
2213dddd3059SJohan Hedberg 			SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
2214dddd3059SJohan Hedberg 		}
2215dddd3059SJohan Hedberg 		return 0;
2216dddd3059SJohan Hedberg 	}
2217dddd3059SJohan Hedberg 
221838606f14SJohan Hedberg 	err = smp_g2(smp->tfm_cmac, pkax, pkbx, na, nb, &passkey);
2219191dc7feSJohan Hedberg 	if (err)
2220191dc7feSJohan Hedberg 		return SMP_UNSPECIFIED;
2221191dc7feSJohan Hedberg 
2222eed467b5SHoward Chung 	confirm_hint = 0;
2223eed467b5SHoward Chung 
2224eed467b5SHoward Chung confirm:
2225ffee202aSSonny Sasaka 	if (smp->method == JUST_WORKS)
2226ffee202aSSonny Sasaka 		confirm_hint = 1;
2227ffee202aSSonny Sasaka 
222838606f14SJohan Hedberg 	err = mgmt_user_confirm_request(hcon->hdev, &hcon->dst, hcon->type,
2229eed467b5SHoward Chung 					hcon->dst_type, passkey, confirm_hint);
223038606f14SJohan Hedberg 	if (err)
223138606f14SJohan Hedberg 		return SMP_UNSPECIFIED;
223238606f14SJohan Hedberg 
223338606f14SJohan Hedberg 	set_bit(SMP_FLAG_WAIT_USER, &smp->flags);
223438606f14SJohan Hedberg 
2235191dc7feSJohan Hedberg 	return 0;
223688ba43b6SAnderson Briglia }
223788ba43b6SAnderson Briglia 
2238f81cd823SMarcel Holtmann static bool smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
2239988c5997SVinicius Costa Gomes {
2240c9839a11SVinicius Costa Gomes 	struct smp_ltk *key;
2241988c5997SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
2242988c5997SVinicius Costa Gomes 
2243f3a73d97SJohan Hedberg 	key = hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, hcon->role);
2244988c5997SVinicius Costa Gomes 	if (!key)
2245f81cd823SMarcel Holtmann 		return false;
2246988c5997SVinicius Costa Gomes 
2247a6f7833cSJohan Hedberg 	if (smp_ltk_sec_level(key) < sec_level)
2248f81cd823SMarcel Holtmann 		return false;
22494dab7864SJohan Hedberg 
225051a8efd7SJohan Hedberg 	if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
2251f81cd823SMarcel Holtmann 		return true;
2252988c5997SVinicius Costa Gomes 
22538b76ce34SJohan Hedberg 	hci_le_start_enc(hcon, key->ediv, key->rand, key->val, key->enc_size);
2254c9839a11SVinicius Costa Gomes 	hcon->enc_key_size = key->enc_size;
2255988c5997SVinicius Costa Gomes 
2256*fad646e1SArchie Pusaka 	/* We never store STKs for initiator role, so clear this flag */
2257fe59a05fSJohan Hedberg 	clear_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags);
2258fe59a05fSJohan Hedberg 
2259f81cd823SMarcel Holtmann 	return true;
2260988c5997SVinicius Costa Gomes }
2261f1560463SMarcel Holtmann 
226235dc6f83SJohan Hedberg bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level,
226335dc6f83SJohan Hedberg 			     enum smp_key_pref key_pref)
2264854f4727SJohan Hedberg {
2265854f4727SJohan Hedberg 	if (sec_level == BT_SECURITY_LOW)
2266854f4727SJohan Hedberg 		return true;
2267854f4727SJohan Hedberg 
226835dc6f83SJohan Hedberg 	/* If we're encrypted with an STK but the caller prefers using
226935dc6f83SJohan Hedberg 	 * LTK claim insufficient security. This way we allow the
227035dc6f83SJohan Hedberg 	 * connection to be re-encrypted with an LTK, even if the LTK
227135dc6f83SJohan Hedberg 	 * provides the same level of security. Only exception is if we
227235dc6f83SJohan Hedberg 	 * don't have an LTK (e.g. because of key distribution bits).
22739ab65d60SJohan Hedberg 	 */
227435dc6f83SJohan Hedberg 	if (key_pref == SMP_USE_LTK &&
227535dc6f83SJohan Hedberg 	    test_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags) &&
2276f3a73d97SJohan Hedberg 	    hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, hcon->role))
22779ab65d60SJohan Hedberg 		return false;
22789ab65d60SJohan Hedberg 
2279854f4727SJohan Hedberg 	if (hcon->sec_level >= sec_level)
2280854f4727SJohan Hedberg 		return true;
2281854f4727SJohan Hedberg 
2282854f4727SJohan Hedberg 	return false;
2283854f4727SJohan Hedberg }
2284854f4727SJohan Hedberg 
2285da85e5e5SVinicius Costa Gomes static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
228688ba43b6SAnderson Briglia {
228788ba43b6SAnderson Briglia 	struct smp_cmd_security_req *rp = (void *) skb->data;
228888ba43b6SAnderson Briglia 	struct smp_cmd_pairing cp;
2289f1cb9af5SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
22900edb14deSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
22918aab4757SVinicius Costa Gomes 	struct smp_chan *smp;
2292c05b9339SJohan Hedberg 	u8 sec_level, auth;
229388ba43b6SAnderson Briglia 
22942e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "conn %p", conn);
229588ba43b6SAnderson Briglia 
2296c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rp))
229738e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2298c46b98beSJohan Hedberg 
229940bef302SJohan Hedberg 	if (hcon->role != HCI_ROLE_MASTER)
230086ca9eacSJohan Hedberg 		return SMP_CMD_NOTSUPP;
230186ca9eacSJohan Hedberg 
23020edb14deSJohan Hedberg 	auth = rp->auth_req & AUTH_REQ_MASK(hdev);
2303c05b9339SJohan Hedberg 
2304d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SC_ONLY) && !(auth & SMP_AUTH_SC))
2305903b71c7SJohan Hedberg 		return SMP_AUTH_REQUIREMENTS;
2306903b71c7SJohan Hedberg 
23075be5e275SJohan Hedberg 	if (hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
23081afc2a1aSJohan Hedberg 		sec_level = BT_SECURITY_MEDIUM;
23091afc2a1aSJohan Hedberg 	else
2310c05b9339SJohan Hedberg 		sec_level = authreq_to_seclevel(auth);
23111afc2a1aSJohan Hedberg 
231264e759f5SSzymon Janc 	if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK)) {
231364e759f5SSzymon Janc 		/* If link is already encrypted with sufficient security we
231464e759f5SSzymon Janc 		 * still need refresh encryption as per Core Spec 5.0 Vol 3,
231564e759f5SSzymon Janc 		 * Part H 2.4.6
231664e759f5SSzymon Janc 		 */
231764e759f5SSzymon Janc 		smp_ltk_encrypt(conn, hcon->sec_level);
2318854f4727SJohan Hedberg 		return 0;
231964e759f5SSzymon Janc 	}
2320854f4727SJohan Hedberg 
2321c7262e71SJohan Hedberg 	if (sec_level > hcon->pending_sec_level)
2322c7262e71SJohan Hedberg 		hcon->pending_sec_level = sec_level;
2323feb45eb5SVinicius Costa Gomes 
23244dab7864SJohan Hedberg 	if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
2325988c5997SVinicius Costa Gomes 		return 0;
2326988c5997SVinicius Costa Gomes 
23278aab4757SVinicius Costa Gomes 	smp = smp_chan_create(conn);
2328c29d2444SJohan Hedberg 	if (!smp)
2329c29d2444SJohan Hedberg 		return SMP_UNSPECIFIED;
2330d26a2345SVinicius Costa Gomes 
2331d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BONDABLE) &&
2332c05b9339SJohan Hedberg 	    (auth & SMP_AUTH_BONDING))
2333616d55beSJohan Hedberg 		return SMP_PAIRING_NOTSUPP;
2334616d55beSJohan Hedberg 
233588ba43b6SAnderson Briglia 	skb_pull(skb, sizeof(*rp));
233688ba43b6SAnderson Briglia 
2337da85e5e5SVinicius Costa Gomes 	memset(&cp, 0, sizeof(cp));
2338c05b9339SJohan Hedberg 	build_pairing_cmd(conn, &cp, NULL, auth);
233988ba43b6SAnderson Briglia 
23401c1def09SVinicius Costa Gomes 	smp->preq[0] = SMP_CMD_PAIRING_REQ;
23411c1def09SVinicius Costa Gomes 	memcpy(&smp->preq[1], &cp, sizeof(cp));
2342f01ead31SAnderson Briglia 
234388ba43b6SAnderson Briglia 	smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
2344b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP);
2345f1cb9af5SVinicius Costa Gomes 
2346da85e5e5SVinicius Costa Gomes 	return 0;
234788ba43b6SAnderson Briglia }
234888ba43b6SAnderson Briglia 
2349cc110922SVinicius Costa Gomes int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
2350eb492e01SAnderson Briglia {
2351cc110922SVinicius Costa Gomes 	struct l2cap_conn *conn = hcon->l2cap_data;
2352c68b7f12SJohan Hedberg 	struct l2cap_chan *chan;
23530a66cf20SJohan Hedberg 	struct smp_chan *smp;
23542b64d153SBrian Gix 	__u8 authreq;
2355fc75cc86SJohan Hedberg 	int ret;
2356eb492e01SAnderson Briglia 
23572e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hcon->hdev, "conn %p hcon %p level 0x%2.2x", conn, hcon,
23582e1614f7SLuiz Augusto von Dentz 		   sec_level);
23593a0259bbSVinicius Costa Gomes 
23600a66cf20SJohan Hedberg 	/* This may be NULL if there's an unexpected disconnection */
23610a66cf20SJohan Hedberg 	if (!conn)
23620a66cf20SJohan Hedberg 		return 1;
23630a66cf20SJohan Hedberg 
2364d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hcon->hdev, HCI_LE_ENABLED))
23652e65c9d2SAndre Guedes 		return 1;
23662e65c9d2SAndre Guedes 
236735dc6f83SJohan Hedberg 	if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK))
2368f1cb9af5SVinicius Costa Gomes 		return 1;
2369f1cb9af5SVinicius Costa Gomes 
2370c7262e71SJohan Hedberg 	if (sec_level > hcon->pending_sec_level)
2371c7262e71SJohan Hedberg 		hcon->pending_sec_level = sec_level;
2372c7262e71SJohan Hedberg 
237340bef302SJohan Hedberg 	if (hcon->role == HCI_ROLE_MASTER)
2374c7262e71SJohan Hedberg 		if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
2375c7262e71SJohan Hedberg 			return 0;
2376d26a2345SVinicius Costa Gomes 
2377d8949aadSJohan Hedberg 	chan = conn->smp;
2378d8949aadSJohan Hedberg 	if (!chan) {
23792064ee33SMarcel Holtmann 		bt_dev_err(hcon->hdev, "security requested but not available");
2380d8949aadSJohan Hedberg 		return 1;
2381d8949aadSJohan Hedberg 	}
2382d8949aadSJohan Hedberg 
2383fc75cc86SJohan Hedberg 	l2cap_chan_lock(chan);
2384fc75cc86SJohan Hedberg 
2385fc75cc86SJohan Hedberg 	/* If SMP is already in progress ignore this request */
2386fc75cc86SJohan Hedberg 	if (chan->data) {
2387fc75cc86SJohan Hedberg 		ret = 0;
2388fc75cc86SJohan Hedberg 		goto unlock;
2389fc75cc86SJohan Hedberg 	}
2390d26a2345SVinicius Costa Gomes 
23918aab4757SVinicius Costa Gomes 	smp = smp_chan_create(conn);
2392fc75cc86SJohan Hedberg 	if (!smp) {
2393fc75cc86SJohan Hedberg 		ret = 1;
2394fc75cc86SJohan Hedberg 		goto unlock;
2395fc75cc86SJohan Hedberg 	}
23962b64d153SBrian Gix 
23972b64d153SBrian Gix 	authreq = seclevel_to_authreq(sec_level);
2398d26a2345SVinicius Costa Gomes 
2399a62da6f1SJohan Hedberg 	if (hci_dev_test_flag(hcon->hdev, HCI_SC_ENABLED)) {
2400d2eb9e10SJohan Hedberg 		authreq |= SMP_AUTH_SC;
2401a62da6f1SJohan Hedberg 		if (hci_dev_test_flag(hcon->hdev, HCI_SSP_ENABLED))
2402a62da6f1SJohan Hedberg 			authreq |= SMP_AUTH_CT2;
2403a62da6f1SJohan Hedberg 	}
2404d2eb9e10SJohan Hedberg 
2405c2aa30dbSArchie Pusaka 	/* Don't attempt to set MITM if setting is overridden by debugfs
2406c2aa30dbSArchie Pusaka 	 * Needed to pass certification test SM/MAS/PKE/BV-01-C
2407c2aa30dbSArchie Pusaka 	 */
2408c2aa30dbSArchie Pusaka 	if (!hci_dev_test_flag(hcon->hdev, HCI_FORCE_NO_MITM)) {
240979897d20SJohan Hedberg 		/* Require MITM if IO Capability allows or the security level
241079897d20SJohan Hedberg 		 * requires it.
24112e233644SJohan Hedberg 		 */
241279897d20SJohan Hedberg 		if (hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT ||
2413c7262e71SJohan Hedberg 		    hcon->pending_sec_level > BT_SECURITY_MEDIUM)
24142e233644SJohan Hedberg 			authreq |= SMP_AUTH_MITM;
2415c2aa30dbSArchie Pusaka 	}
24162e233644SJohan Hedberg 
241740bef302SJohan Hedberg 	if (hcon->role == HCI_ROLE_MASTER) {
2418d26a2345SVinicius Costa Gomes 		struct smp_cmd_pairing cp;
2419f01ead31SAnderson Briglia 
24202b64d153SBrian Gix 		build_pairing_cmd(conn, &cp, NULL, authreq);
24211c1def09SVinicius Costa Gomes 		smp->preq[0] = SMP_CMD_PAIRING_REQ;
24221c1def09SVinicius Costa Gomes 		memcpy(&smp->preq[1], &cp, sizeof(cp));
2423f01ead31SAnderson Briglia 
2424eb492e01SAnderson Briglia 		smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
2425b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP);
2426eb492e01SAnderson Briglia 	} else {
2427eb492e01SAnderson Briglia 		struct smp_cmd_security_req cp;
24282b64d153SBrian Gix 		cp.auth_req = authreq;
2429eb492e01SAnderson Briglia 		smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
2430b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_REQ);
2431eb492e01SAnderson Briglia 	}
2432eb492e01SAnderson Briglia 
24334a74d658SJohan Hedberg 	set_bit(SMP_FLAG_INITIATOR, &smp->flags);
2434fc75cc86SJohan Hedberg 	ret = 0;
2435edca792cSJohan Hedberg 
2436fc75cc86SJohan Hedberg unlock:
2437fc75cc86SJohan Hedberg 	l2cap_chan_unlock(chan);
2438fc75cc86SJohan Hedberg 	return ret;
2439eb492e01SAnderson Briglia }
2440eb492e01SAnderson Briglia 
2441cb28c306SMatias Karhumaa int smp_cancel_and_remove_pairing(struct hci_dev *hdev, bdaddr_t *bdaddr,
2442cb28c306SMatias Karhumaa 				  u8 addr_type)
2443c81d555aSJohan Hedberg {
2444cb28c306SMatias Karhumaa 	struct hci_conn *hcon;
2445cb28c306SMatias Karhumaa 	struct l2cap_conn *conn;
2446c81d555aSJohan Hedberg 	struct l2cap_chan *chan;
2447c81d555aSJohan Hedberg 	struct smp_chan *smp;
2448cb28c306SMatias Karhumaa 	int err;
2449c81d555aSJohan Hedberg 
2450cb28c306SMatias Karhumaa 	err = hci_remove_ltk(hdev, bdaddr, addr_type);
2451cb28c306SMatias Karhumaa 	hci_remove_irk(hdev, bdaddr, addr_type);
2452cb28c306SMatias Karhumaa 
2453cb28c306SMatias Karhumaa 	hcon = hci_conn_hash_lookup_le(hdev, bdaddr, addr_type);
2454cb28c306SMatias Karhumaa 	if (!hcon)
2455cb28c306SMatias Karhumaa 		goto done;
2456cb28c306SMatias Karhumaa 
2457cb28c306SMatias Karhumaa 	conn = hcon->l2cap_data;
2458c81d555aSJohan Hedberg 	if (!conn)
2459cb28c306SMatias Karhumaa 		goto done;
2460c81d555aSJohan Hedberg 
2461c81d555aSJohan Hedberg 	chan = conn->smp;
2462c81d555aSJohan Hedberg 	if (!chan)
2463cb28c306SMatias Karhumaa 		goto done;
2464c81d555aSJohan Hedberg 
2465c81d555aSJohan Hedberg 	l2cap_chan_lock(chan);
2466c81d555aSJohan Hedberg 
2467c81d555aSJohan Hedberg 	smp = chan->data;
2468c81d555aSJohan Hedberg 	if (smp) {
2469cb28c306SMatias Karhumaa 		/* Set keys to NULL to make sure smp_failure() does not try to
2470cb28c306SMatias Karhumaa 		 * remove and free already invalidated rcu list entries. */
2471cb28c306SMatias Karhumaa 		smp->ltk = NULL;
2472*fad646e1SArchie Pusaka 		smp->responder_ltk = NULL;
2473cb28c306SMatias Karhumaa 		smp->remote_irk = NULL;
2474cb28c306SMatias Karhumaa 
2475c81d555aSJohan Hedberg 		if (test_bit(SMP_FLAG_COMPLETE, &smp->flags))
2476c81d555aSJohan Hedberg 			smp_failure(conn, 0);
2477c81d555aSJohan Hedberg 		else
2478c81d555aSJohan Hedberg 			smp_failure(conn, SMP_UNSPECIFIED);
2479cb28c306SMatias Karhumaa 		err = 0;
2480c81d555aSJohan Hedberg 	}
2481c81d555aSJohan Hedberg 
2482c81d555aSJohan Hedberg 	l2cap_chan_unlock(chan);
2483cb28c306SMatias Karhumaa 
2484cb28c306SMatias Karhumaa done:
2485cb28c306SMatias Karhumaa 	return err;
2486c81d555aSJohan Hedberg }
2487c81d555aSJohan Hedberg 
24887034b911SVinicius Costa Gomes static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
24897034b911SVinicius Costa Gomes {
249016b90839SVinicius Costa Gomes 	struct smp_cmd_encrypt_info *rp = (void *) skb->data;
24915d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
24925d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
249316b90839SVinicius Costa Gomes 
24942e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(conn->hcon->hdev, "conn %p", conn);
2495c46b98beSJohan Hedberg 
2496c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rp))
249738e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2498c46b98beSJohan Hedberg 
2499600a8749SAlain Michaud 	/* Pairing is aborted if any blocked keys are distributed */
2500600a8749SAlain Michaud 	if (hci_is_blocked_key(conn->hcon->hdev, HCI_BLOCKED_KEY_TYPE_LTK,
2501600a8749SAlain Michaud 			       rp->ltk)) {
2502600a8749SAlain Michaud 		bt_dev_warn_ratelimited(conn->hcon->hdev,
2503600a8749SAlain Michaud 					"LTK blocked for %pMR",
2504600a8749SAlain Michaud 					&conn->hcon->dst);
2505600a8749SAlain Michaud 		return SMP_INVALID_PARAMS;
2506600a8749SAlain Michaud 	}
2507600a8749SAlain Michaud 
2508*fad646e1SArchie Pusaka 	SMP_ALLOW_CMD(smp, SMP_CMD_INITIATOR_IDENT);
25096131ddc8SJohan Hedberg 
251016b90839SVinicius Costa Gomes 	skb_pull(skb, sizeof(*rp));
251116b90839SVinicius Costa Gomes 
25121c1def09SVinicius Costa Gomes 	memcpy(smp->tk, rp->ltk, sizeof(smp->tk));
251316b90839SVinicius Costa Gomes 
25147034b911SVinicius Costa Gomes 	return 0;
25157034b911SVinicius Costa Gomes }
25167034b911SVinicius Costa Gomes 
2517*fad646e1SArchie Pusaka static int smp_cmd_initiator_ident(struct l2cap_conn *conn, struct sk_buff *skb)
25187034b911SVinicius Costa Gomes {
2519*fad646e1SArchie Pusaka 	struct smp_cmd_initiator_ident *rp = (void *)skb->data;
25205d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
25215d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
2522c9839a11SVinicius Costa Gomes 	struct hci_dev *hdev = conn->hcon->hdev;
2523c9839a11SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
252423d0e128SJohan Hedberg 	struct smp_ltk *ltk;
2525c9839a11SVinicius Costa Gomes 	u8 authenticated;
25267034b911SVinicius Costa Gomes 
25272e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "conn %p", conn);
2528c46b98beSJohan Hedberg 
2529c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rp))
253038e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2531c46b98beSJohan Hedberg 
25329747a9f3SJohan Hedberg 	/* Mark the information as received */
25339747a9f3SJohan Hedberg 	smp->remote_key_dist &= ~SMP_DIST_ENC_KEY;
25349747a9f3SJohan Hedberg 
2535b28b4943SJohan Hedberg 	if (smp->remote_key_dist & SMP_DIST_ID_KEY)
2536b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO);
2537196332f5SJohan Hedberg 	else if (smp->remote_key_dist & SMP_DIST_SIGN)
2538196332f5SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO);
2539b28b4943SJohan Hedberg 
254016b90839SVinicius Costa Gomes 	skb_pull(skb, sizeof(*rp));
254116b90839SVinicius Costa Gomes 
2542ce39fb4eSMarcel Holtmann 	authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
25432ceba539SJohan Hedberg 	ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, SMP_LTK,
2544ce39fb4eSMarcel Holtmann 			  authenticated, smp->tk, smp->enc_key_size,
254504124681SGustavo F. Padovan 			  rp->ediv, rp->rand);
254623d0e128SJohan Hedberg 	smp->ltk = ltk;
2547c6e81e9aSJohan Hedberg 	if (!(smp->remote_key_dist & KEY_DIST_MASK))
2548d6268e86SJohan Hedberg 		smp_distribute_keys(smp);
25497034b911SVinicius Costa Gomes 
25507034b911SVinicius Costa Gomes 	return 0;
25517034b911SVinicius Costa Gomes }
25527034b911SVinicius Costa Gomes 
2553fd349c02SJohan Hedberg static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
2554fd349c02SJohan Hedberg {
2555fd349c02SJohan Hedberg 	struct smp_cmd_ident_info *info = (void *) skb->data;
25565d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
25575d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
2558fd349c02SJohan Hedberg 
25592e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(conn->hcon->hdev, "");
2560fd349c02SJohan Hedberg 
2561fd349c02SJohan Hedberg 	if (skb->len < sizeof(*info))
256238e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2563fd349c02SJohan Hedberg 
2564600a8749SAlain Michaud 	/* Pairing is aborted if any blocked keys are distributed */
2565600a8749SAlain Michaud 	if (hci_is_blocked_key(conn->hcon->hdev, HCI_BLOCKED_KEY_TYPE_IRK,
2566600a8749SAlain Michaud 			       info->irk)) {
2567600a8749SAlain Michaud 		bt_dev_warn_ratelimited(conn->hcon->hdev,
2568600a8749SAlain Michaud 					"Identity key blocked for %pMR",
2569600a8749SAlain Michaud 					&conn->hcon->dst);
2570600a8749SAlain Michaud 		return SMP_INVALID_PARAMS;
2571600a8749SAlain Michaud 	}
2572600a8749SAlain Michaud 
2573b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_ADDR_INFO);
25746131ddc8SJohan Hedberg 
2575fd349c02SJohan Hedberg 	skb_pull(skb, sizeof(*info));
2576fd349c02SJohan Hedberg 
2577fd349c02SJohan Hedberg 	memcpy(smp->irk, info->irk, 16);
2578fd349c02SJohan Hedberg 
2579fd349c02SJohan Hedberg 	return 0;
2580fd349c02SJohan Hedberg }
2581fd349c02SJohan Hedberg 
2582fd349c02SJohan Hedberg static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
2583fd349c02SJohan Hedberg 				   struct sk_buff *skb)
2584fd349c02SJohan Hedberg {
2585fd349c02SJohan Hedberg 	struct smp_cmd_ident_addr_info *info = (void *) skb->data;
25865d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
25875d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
2588fd349c02SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
2589fd349c02SJohan Hedberg 	bdaddr_t rpa;
2590fd349c02SJohan Hedberg 
25912e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hcon->hdev, "");
2592fd349c02SJohan Hedberg 
2593fd349c02SJohan Hedberg 	if (skb->len < sizeof(*info))
259438e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2595fd349c02SJohan Hedberg 
25969747a9f3SJohan Hedberg 	/* Mark the information as received */
25979747a9f3SJohan Hedberg 	smp->remote_key_dist &= ~SMP_DIST_ID_KEY;
25989747a9f3SJohan Hedberg 
2599b28b4943SJohan Hedberg 	if (smp->remote_key_dist & SMP_DIST_SIGN)
2600b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO);
2601b28b4943SJohan Hedberg 
2602fd349c02SJohan Hedberg 	skb_pull(skb, sizeof(*info));
2603fd349c02SJohan Hedberg 
2604a9a58f86SJohan Hedberg 	/* Strictly speaking the Core Specification (4.1) allows sending
2605a9a58f86SJohan Hedberg 	 * an empty address which would force us to rely on just the IRK
2606a9a58f86SJohan Hedberg 	 * as "identity information". However, since such
2607a9a58f86SJohan Hedberg 	 * implementations are not known of and in order to not over
2608a9a58f86SJohan Hedberg 	 * complicate our implementation, simply pretend that we never
2609a9a58f86SJohan Hedberg 	 * received an IRK for such a device.
2610e12af489SJohan Hedberg 	 *
2611e12af489SJohan Hedberg 	 * The Identity Address must also be a Static Random or Public
2612e12af489SJohan Hedberg 	 * Address, which hci_is_identity_address() checks for.
2613a9a58f86SJohan Hedberg 	 */
2614e12af489SJohan Hedberg 	if (!bacmp(&info->bdaddr, BDADDR_ANY) ||
2615e12af489SJohan Hedberg 	    !hci_is_identity_address(&info->bdaddr, info->addr_type)) {
26162064ee33SMarcel Holtmann 		bt_dev_err(hcon->hdev, "ignoring IRK with no identity address");
261731dd624eSJohan Hedberg 		goto distribute;
2618a9a58f86SJohan Hedberg 	}
2619a9a58f86SJohan Hedberg 
26201d87b88bSSzymon Janc 	/* Drop IRK if peer is using identity address during pairing but is
26211d87b88bSSzymon Janc 	 * providing different address as identity information.
26221d87b88bSSzymon Janc 	 *
26231d87b88bSSzymon Janc 	 * Microsoft Surface Precision Mouse is known to have this bug.
26241d87b88bSSzymon Janc 	 */
26251d87b88bSSzymon Janc 	if (hci_is_identity_address(&hcon->dst, hcon->dst_type) &&
26261d87b88bSSzymon Janc 	    (bacmp(&info->bdaddr, &hcon->dst) ||
26271d87b88bSSzymon Janc 	     info->addr_type != hcon->dst_type)) {
26281d87b88bSSzymon Janc 		bt_dev_err(hcon->hdev,
26291d87b88bSSzymon Janc 			   "ignoring IRK with invalid identity address");
26301d87b88bSSzymon Janc 		goto distribute;
26311d87b88bSSzymon Janc 	}
26321d87b88bSSzymon Janc 
2633fd349c02SJohan Hedberg 	bacpy(&smp->id_addr, &info->bdaddr);
2634fd349c02SJohan Hedberg 	smp->id_addr_type = info->addr_type;
2635fd349c02SJohan Hedberg 
2636fd349c02SJohan Hedberg 	if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type))
2637fd349c02SJohan Hedberg 		bacpy(&rpa, &hcon->dst);
2638fd349c02SJohan Hedberg 	else
2639fd349c02SJohan Hedberg 		bacpy(&rpa, BDADDR_ANY);
2640fd349c02SJohan Hedberg 
264123d0e128SJohan Hedberg 	smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
264223d0e128SJohan Hedberg 				      smp->id_addr_type, smp->irk, &rpa);
2643fd349c02SJohan Hedberg 
264431dd624eSJohan Hedberg distribute:
2645c6e81e9aSJohan Hedberg 	if (!(smp->remote_key_dist & KEY_DIST_MASK))
2646d6268e86SJohan Hedberg 		smp_distribute_keys(smp);
2647fd349c02SJohan Hedberg 
2648fd349c02SJohan Hedberg 	return 0;
2649fd349c02SJohan Hedberg }
2650fd349c02SJohan Hedberg 
26517ee4ea36SMarcel Holtmann static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)
26527ee4ea36SMarcel Holtmann {
26537ee4ea36SMarcel Holtmann 	struct smp_cmd_sign_info *rp = (void *) skb->data;
26545d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
26555d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
26567ee4ea36SMarcel Holtmann 	struct smp_csrk *csrk;
26577ee4ea36SMarcel Holtmann 
26582e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(conn->hcon->hdev, "conn %p", conn);
26597ee4ea36SMarcel Holtmann 
26607ee4ea36SMarcel Holtmann 	if (skb->len < sizeof(*rp))
266138e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
26627ee4ea36SMarcel Holtmann 
26637ee4ea36SMarcel Holtmann 	/* Mark the information as received */
26647ee4ea36SMarcel Holtmann 	smp->remote_key_dist &= ~SMP_DIST_SIGN;
26657ee4ea36SMarcel Holtmann 
26667ee4ea36SMarcel Holtmann 	skb_pull(skb, sizeof(*rp));
26677ee4ea36SMarcel Holtmann 
26687ee4ea36SMarcel Holtmann 	csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
26697ee4ea36SMarcel Holtmann 	if (csrk) {
26704cd3928aSJohan Hedberg 		if (conn->hcon->sec_level > BT_SECURITY_MEDIUM)
26714cd3928aSJohan Hedberg 			csrk->type = MGMT_CSRK_REMOTE_AUTHENTICATED;
26724cd3928aSJohan Hedberg 		else
26734cd3928aSJohan Hedberg 			csrk->type = MGMT_CSRK_REMOTE_UNAUTHENTICATED;
26747ee4ea36SMarcel Holtmann 		memcpy(csrk->val, rp->csrk, sizeof(csrk->val));
26757ee4ea36SMarcel Holtmann 	}
26767ee4ea36SMarcel Holtmann 	smp->csrk = csrk;
2677d6268e86SJohan Hedberg 	smp_distribute_keys(smp);
26787ee4ea36SMarcel Holtmann 
26797ee4ea36SMarcel Holtmann 	return 0;
26807ee4ea36SMarcel Holtmann }
26817ee4ea36SMarcel Holtmann 
26825e3d3d9bSJohan Hedberg static u8 sc_select_method(struct smp_chan *smp)
26835e3d3d9bSJohan Hedberg {
26845e3d3d9bSJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
26855e3d3d9bSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
26865e3d3d9bSJohan Hedberg 	struct smp_cmd_pairing *local, *remote;
26875e3d3d9bSJohan Hedberg 	u8 local_mitm, remote_mitm, local_io, remote_io, method;
26885e3d3d9bSJohan Hedberg 
26891a8bab4fSJohan Hedberg 	if (test_bit(SMP_FLAG_REMOTE_OOB, &smp->flags) ||
26901a8bab4fSJohan Hedberg 	    test_bit(SMP_FLAG_LOCAL_OOB, &smp->flags))
2691a29b0733SJohan Hedberg 		return REQ_OOB;
2692a29b0733SJohan Hedberg 
26935e3d3d9bSJohan Hedberg 	/* The preq/prsp contain the raw Pairing Request/Response PDUs
26945e3d3d9bSJohan Hedberg 	 * which are needed as inputs to some crypto functions. To get
26955e3d3d9bSJohan Hedberg 	 * the "struct smp_cmd_pairing" from them we need to skip the
26965e3d3d9bSJohan Hedberg 	 * first byte which contains the opcode.
26975e3d3d9bSJohan Hedberg 	 */
26985e3d3d9bSJohan Hedberg 	if (hcon->out) {
26995e3d3d9bSJohan Hedberg 		local = (void *) &smp->preq[1];
27005e3d3d9bSJohan Hedberg 		remote = (void *) &smp->prsp[1];
27015e3d3d9bSJohan Hedberg 	} else {
27025e3d3d9bSJohan Hedberg 		local = (void *) &smp->prsp[1];
27035e3d3d9bSJohan Hedberg 		remote = (void *) &smp->preq[1];
27045e3d3d9bSJohan Hedberg 	}
27055e3d3d9bSJohan Hedberg 
27065e3d3d9bSJohan Hedberg 	local_io = local->io_capability;
27075e3d3d9bSJohan Hedberg 	remote_io = remote->io_capability;
27085e3d3d9bSJohan Hedberg 
27095e3d3d9bSJohan Hedberg 	local_mitm = (local->auth_req & SMP_AUTH_MITM);
27105e3d3d9bSJohan Hedberg 	remote_mitm = (remote->auth_req & SMP_AUTH_MITM);
27115e3d3d9bSJohan Hedberg 
27125e3d3d9bSJohan Hedberg 	/* If either side wants MITM, look up the method from the table,
27135e3d3d9bSJohan Hedberg 	 * otherwise use JUST WORKS.
27145e3d3d9bSJohan Hedberg 	 */
27155e3d3d9bSJohan Hedberg 	if (local_mitm || remote_mitm)
27165e3d3d9bSJohan Hedberg 		method = get_auth_method(smp, local_io, remote_io);
27175e3d3d9bSJohan Hedberg 	else
27185e3d3d9bSJohan Hedberg 		method = JUST_WORKS;
27195e3d3d9bSJohan Hedberg 
27205e3d3d9bSJohan Hedberg 	/* Don't confirm locally initiated pairing attempts */
27215e3d3d9bSJohan Hedberg 	if (method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR, &smp->flags))
27225e3d3d9bSJohan Hedberg 		method = JUST_WORKS;
27235e3d3d9bSJohan Hedberg 
27245e3d3d9bSJohan Hedberg 	return method;
27255e3d3d9bSJohan Hedberg }
27265e3d3d9bSJohan Hedberg 
2727d8f8edbeSJohan Hedberg static int smp_cmd_public_key(struct l2cap_conn *conn, struct sk_buff *skb)
2728d8f8edbeSJohan Hedberg {
2729d8f8edbeSJohan Hedberg 	struct smp_cmd_public_key *key = (void *) skb->data;
2730d8f8edbeSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
2731d8f8edbeSJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
2732d8f8edbeSJohan Hedberg 	struct smp_chan *smp = chan->data;
27335e3d3d9bSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
2734c0153b0bSTudor Ambarus 	struct crypto_kpp *tfm_ecdh;
2735cbbbe3e2SJohan Hedberg 	struct smp_cmd_pairing_confirm cfm;
2736d8f8edbeSJohan Hedberg 	int err;
2737d8f8edbeSJohan Hedberg 
27382e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "conn %p", conn);
2739d8f8edbeSJohan Hedberg 
2740d8f8edbeSJohan Hedberg 	if (skb->len < sizeof(*key))
2741d8f8edbeSJohan Hedberg 		return SMP_INVALID_PARAMS;
2742d8f8edbeSJohan Hedberg 
27436d19628fSLuiz Augusto von Dentz 	/* Check if remote and local public keys are the same and debug key is
27446d19628fSLuiz Augusto von Dentz 	 * not in use.
27456d19628fSLuiz Augusto von Dentz 	 */
27466d19628fSLuiz Augusto von Dentz 	if (!test_bit(SMP_FLAG_DEBUG_KEY, &smp->flags) &&
27476d19628fSLuiz Augusto von Dentz 	    !crypto_memneq(key, smp->local_pk, 64)) {
27486d19628fSLuiz Augusto von Dentz 		bt_dev_err(hdev, "Remote and local public keys are identical");
27496d19628fSLuiz Augusto von Dentz 		return SMP_UNSPECIFIED;
27506d19628fSLuiz Augusto von Dentz 	}
27516d19628fSLuiz Augusto von Dentz 
2752d8f8edbeSJohan Hedberg 	memcpy(smp->remote_pk, key, 64);
2753d8f8edbeSJohan Hedberg 
2754a8ca617cSJohan Hedberg 	if (test_bit(SMP_FLAG_REMOTE_OOB, &smp->flags)) {
2755a8ca617cSJohan Hedberg 		err = smp_f4(smp->tfm_cmac, smp->remote_pk, smp->remote_pk,
2756a8ca617cSJohan Hedberg 			     smp->rr, 0, cfm.confirm_val);
2757a8ca617cSJohan Hedberg 		if (err)
2758a8ca617cSJohan Hedberg 			return SMP_UNSPECIFIED;
2759a8ca617cSJohan Hedberg 
2760329d8230SJason A. Donenfeld 		if (crypto_memneq(cfm.confirm_val, smp->pcnf, 16))
2761a8ca617cSJohan Hedberg 			return SMP_CONFIRM_FAILED;
2762a8ca617cSJohan Hedberg 	}
2763a8ca617cSJohan Hedberg 
2764d8f8edbeSJohan Hedberg 	/* Non-initiating device sends its public key after receiving
2765d8f8edbeSJohan Hedberg 	 * the key from the initiating device.
2766d8f8edbeSJohan Hedberg 	 */
2767d8f8edbeSJohan Hedberg 	if (!hcon->out) {
2768d8f8edbeSJohan Hedberg 		err = sc_send_public_key(smp);
2769d8f8edbeSJohan Hedberg 		if (err)
2770d8f8edbeSJohan Hedberg 			return err;
2771d8f8edbeSJohan Hedberg 	}
2772d8f8edbeSJohan Hedberg 
2773c7a3d57dSJohan Hedberg 	SMP_DBG("Remote Public Key X: %32phN", smp->remote_pk);
2774e091526dSMarcel Holtmann 	SMP_DBG("Remote Public Key Y: %32phN", smp->remote_pk + 32);
2775d8f8edbeSJohan Hedberg 
2776c0153b0bSTudor Ambarus 	/* Compute the shared secret on the same crypto tfm on which the private
2777c0153b0bSTudor Ambarus 	 * key was set/generated.
2778c0153b0bSTudor Ambarus 	 */
2779c0153b0bSTudor Ambarus 	if (test_bit(SMP_FLAG_LOCAL_OOB, &smp->flags)) {
27804ba5175fSMatias Karhumaa 		struct l2cap_chan *hchan = hdev->smp_data;
27814ba5175fSMatias Karhumaa 		struct smp_dev *smp_dev;
27824ba5175fSMatias Karhumaa 
27834ba5175fSMatias Karhumaa 		if (!hchan || !hchan->data)
27844ba5175fSMatias Karhumaa 			return SMP_UNSPECIFIED;
27854ba5175fSMatias Karhumaa 
27864ba5175fSMatias Karhumaa 		smp_dev = hchan->data;
2787c0153b0bSTudor Ambarus 
2788c0153b0bSTudor Ambarus 		tfm_ecdh = smp_dev->tfm_ecdh;
2789c0153b0bSTudor Ambarus 	} else {
2790c0153b0bSTudor Ambarus 		tfm_ecdh = smp->tfm_ecdh;
2791c0153b0bSTudor Ambarus 	}
2792c0153b0bSTudor Ambarus 
2793c0153b0bSTudor Ambarus 	if (compute_ecdh_secret(tfm_ecdh, smp->remote_pk, smp->dhkey))
2794d8f8edbeSJohan Hedberg 		return SMP_UNSPECIFIED;
2795d8f8edbeSJohan Hedberg 
2796c7a3d57dSJohan Hedberg 	SMP_DBG("DHKey %32phN", smp->dhkey);
2797d8f8edbeSJohan Hedberg 
2798d8f8edbeSJohan Hedberg 	set_bit(SMP_FLAG_REMOTE_PK, &smp->flags);
2799d8f8edbeSJohan Hedberg 
28005e3d3d9bSJohan Hedberg 	smp->method = sc_select_method(smp);
28015e3d3d9bSJohan Hedberg 
28022e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "selected method 0x%02x", smp->method);
28035e3d3d9bSJohan Hedberg 
28045e3d3d9bSJohan Hedberg 	/* JUST_WORKS and JUST_CFM result in an unauthenticated key */
28055e3d3d9bSJohan Hedberg 	if (smp->method == JUST_WORKS || smp->method == JUST_CFM)
28065e3d3d9bSJohan Hedberg 		hcon->pending_sec_level = BT_SECURITY_MEDIUM;
28075e3d3d9bSJohan Hedberg 	else
28085e3d3d9bSJohan Hedberg 		hcon->pending_sec_level = BT_SECURITY_FIPS;
28095e3d3d9bSJohan Hedberg 
2810329d8230SJason A. Donenfeld 	if (!crypto_memneq(debug_pk, smp->remote_pk, 64))
2811aeb7d461SJohan Hedberg 		set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags);
2812aeb7d461SJohan Hedberg 
281338606f14SJohan Hedberg 	if (smp->method == DSP_PASSKEY) {
281438606f14SJohan Hedberg 		get_random_bytes(&hcon->passkey_notify,
281538606f14SJohan Hedberg 				 sizeof(hcon->passkey_notify));
281638606f14SJohan Hedberg 		hcon->passkey_notify %= 1000000;
281738606f14SJohan Hedberg 		hcon->passkey_entered = 0;
281838606f14SJohan Hedberg 		smp->passkey_round = 0;
281938606f14SJohan Hedberg 		if (mgmt_user_passkey_notify(hdev, &hcon->dst, hcon->type,
282038606f14SJohan Hedberg 					     hcon->dst_type,
282138606f14SJohan Hedberg 					     hcon->passkey_notify,
282238606f14SJohan Hedberg 					     hcon->passkey_entered))
282338606f14SJohan Hedberg 			return SMP_UNSPECIFIED;
282438606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
282538606f14SJohan Hedberg 		return sc_passkey_round(smp, SMP_CMD_PUBLIC_KEY);
282638606f14SJohan Hedberg 	}
282738606f14SJohan Hedberg 
282894ea7257SJohan Hedberg 	if (smp->method == REQ_OOB) {
2829a29b0733SJohan Hedberg 		if (hcon->out)
2830a29b0733SJohan Hedberg 			smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM,
2831a29b0733SJohan Hedberg 				     sizeof(smp->prnd), smp->prnd);
2832a29b0733SJohan Hedberg 
2833a29b0733SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
2834a29b0733SJohan Hedberg 
2835a29b0733SJohan Hedberg 		return 0;
2836a29b0733SJohan Hedberg 	}
2837a29b0733SJohan Hedberg 
283838606f14SJohan Hedberg 	if (hcon->out)
283938606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
284038606f14SJohan Hedberg 
284138606f14SJohan Hedberg 	if (smp->method == REQ_PASSKEY) {
284238606f14SJohan Hedberg 		if (mgmt_user_passkey_request(hdev, &hcon->dst, hcon->type,
284338606f14SJohan Hedberg 					      hcon->dst_type))
284438606f14SJohan Hedberg 			return SMP_UNSPECIFIED;
284538606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
284638606f14SJohan Hedberg 		set_bit(SMP_FLAG_WAIT_USER, &smp->flags);
284738606f14SJohan Hedberg 		return 0;
284838606f14SJohan Hedberg 	}
284938606f14SJohan Hedberg 
2850cbbbe3e2SJohan Hedberg 	/* The Initiating device waits for the non-initiating device to
2851cbbbe3e2SJohan Hedberg 	 * send the confirm value.
2852cbbbe3e2SJohan Hedberg 	 */
2853cbbbe3e2SJohan Hedberg 	if (conn->hcon->out)
2854cbbbe3e2SJohan Hedberg 		return 0;
2855cbbbe3e2SJohan Hedberg 
2856cbbbe3e2SJohan Hedberg 	err = smp_f4(smp->tfm_cmac, smp->local_pk, smp->remote_pk, smp->prnd,
2857cbbbe3e2SJohan Hedberg 		     0, cfm.confirm_val);
2858cbbbe3e2SJohan Hedberg 	if (err)
2859cbbbe3e2SJohan Hedberg 		return SMP_UNSPECIFIED;
2860cbbbe3e2SJohan Hedberg 
2861cbbbe3e2SJohan Hedberg 	smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cfm), &cfm);
2862cbbbe3e2SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
2863cbbbe3e2SJohan Hedberg 
2864d8f8edbeSJohan Hedberg 	return 0;
2865d8f8edbeSJohan Hedberg }
2866d8f8edbeSJohan Hedberg 
28676433a9a2SJohan Hedberg static int smp_cmd_dhkey_check(struct l2cap_conn *conn, struct sk_buff *skb)
28686433a9a2SJohan Hedberg {
28696433a9a2SJohan Hedberg 	struct smp_cmd_dhkey_check *check = (void *) skb->data;
28706433a9a2SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
28716433a9a2SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
28726433a9a2SJohan Hedberg 	struct smp_chan *smp = chan->data;
28736433a9a2SJohan Hedberg 	u8 a[7], b[7], *local_addr, *remote_addr;
28746433a9a2SJohan Hedberg 	u8 io_cap[3], r[16], e[16];
28756433a9a2SJohan Hedberg 	int err;
28766433a9a2SJohan Hedberg 
28772e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hcon->hdev, "conn %p", conn);
28786433a9a2SJohan Hedberg 
28796433a9a2SJohan Hedberg 	if (skb->len < sizeof(*check))
28806433a9a2SJohan Hedberg 		return SMP_INVALID_PARAMS;
28816433a9a2SJohan Hedberg 
28826433a9a2SJohan Hedberg 	memcpy(a, &hcon->init_addr, 6);
28836433a9a2SJohan Hedberg 	memcpy(b, &hcon->resp_addr, 6);
28846433a9a2SJohan Hedberg 	a[6] = hcon->init_addr_type;
28856433a9a2SJohan Hedberg 	b[6] = hcon->resp_addr_type;
28866433a9a2SJohan Hedberg 
28876433a9a2SJohan Hedberg 	if (hcon->out) {
28886433a9a2SJohan Hedberg 		local_addr = a;
28896433a9a2SJohan Hedberg 		remote_addr = b;
28906433a9a2SJohan Hedberg 		memcpy(io_cap, &smp->prsp[1], 3);
28916433a9a2SJohan Hedberg 	} else {
28926433a9a2SJohan Hedberg 		local_addr = b;
28936433a9a2SJohan Hedberg 		remote_addr = a;
28946433a9a2SJohan Hedberg 		memcpy(io_cap, &smp->preq[1], 3);
28956433a9a2SJohan Hedberg 	}
28966433a9a2SJohan Hedberg 
28976433a9a2SJohan Hedberg 	memset(r, 0, sizeof(r));
28986433a9a2SJohan Hedberg 
289938606f14SJohan Hedberg 	if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY)
290038606f14SJohan Hedberg 		put_unaligned_le32(hcon->passkey_notify, r);
2901882fafadSJohan Hedberg 	else if (smp->method == REQ_OOB)
2902882fafadSJohan Hedberg 		memcpy(r, smp->lr, 16);
290338606f14SJohan Hedberg 
29046433a9a2SJohan Hedberg 	err = smp_f6(smp->tfm_cmac, smp->mackey, smp->rrnd, smp->prnd, r,
29056433a9a2SJohan Hedberg 		     io_cap, remote_addr, local_addr, e);
29066433a9a2SJohan Hedberg 	if (err)
29076433a9a2SJohan Hedberg 		return SMP_UNSPECIFIED;
29086433a9a2SJohan Hedberg 
2909329d8230SJason A. Donenfeld 	if (crypto_memneq(check->e, e, 16))
29106433a9a2SJohan Hedberg 		return SMP_DHKEY_CHECK_FAILED;
29116433a9a2SJohan Hedberg 
2912d3e54a87SJohan Hedberg 	if (!hcon->out) {
2913d3e54a87SJohan Hedberg 		if (test_bit(SMP_FLAG_WAIT_USER, &smp->flags)) {
2914d3e54a87SJohan Hedberg 			set_bit(SMP_FLAG_DHKEY_PENDING, &smp->flags);
2915d3e54a87SJohan Hedberg 			return 0;
2916d3e54a87SJohan Hedberg 		}
2917d378a2d7SJohan Hedberg 
2918*fad646e1SArchie Pusaka 		/* Responder sends DHKey check as response to initiator */
2919d3e54a87SJohan Hedberg 		sc_dhkey_check(smp);
2920d3e54a87SJohan Hedberg 	}
2921d378a2d7SJohan Hedberg 
2922d3e54a87SJohan Hedberg 	sc_add_ltk(smp);
29236433a9a2SJohan Hedberg 
29246433a9a2SJohan Hedberg 	if (hcon->out) {
29258b76ce34SJohan Hedberg 		hci_le_start_enc(hcon, 0, 0, smp->tk, smp->enc_key_size);
29266433a9a2SJohan Hedberg 		hcon->enc_key_size = smp->enc_key_size;
29276433a9a2SJohan Hedberg 	}
29286433a9a2SJohan Hedberg 
29296433a9a2SJohan Hedberg 	return 0;
29306433a9a2SJohan Hedberg }
29316433a9a2SJohan Hedberg 
29321408bb6eSJohan Hedberg static int smp_cmd_keypress_notify(struct l2cap_conn *conn,
29331408bb6eSJohan Hedberg 				   struct sk_buff *skb)
29341408bb6eSJohan Hedberg {
29351408bb6eSJohan Hedberg 	struct smp_cmd_keypress_notify *kp = (void *) skb->data;
29361408bb6eSJohan Hedberg 
29372e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(conn->hcon->hdev, "value 0x%02x", kp->value);
29381408bb6eSJohan Hedberg 
29391408bb6eSJohan Hedberg 	return 0;
29401408bb6eSJohan Hedberg }
29411408bb6eSJohan Hedberg 
29424befb867SJohan Hedberg static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb)
2943eb492e01SAnderson Briglia {
29445d88cc73SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
29457b9899dbSMarcel Holtmann 	struct hci_conn *hcon = conn->hcon;
2946b28b4943SJohan Hedberg 	struct smp_chan *smp;
294792381f5cSMarcel Holtmann 	__u8 code, reason;
2948eb492e01SAnderson Briglia 	int err = 0;
2949eb492e01SAnderson Briglia 
29508ae9b984SJohan Hedberg 	if (skb->len < 1)
295192381f5cSMarcel Holtmann 		return -EILSEQ;
295292381f5cSMarcel Holtmann 
2953d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hcon->hdev, HCI_LE_ENABLED)) {
29542e65c9d2SAndre Guedes 		reason = SMP_PAIRING_NOTSUPP;
29552e65c9d2SAndre Guedes 		goto done;
29562e65c9d2SAndre Guedes 	}
29572e65c9d2SAndre Guedes 
295892381f5cSMarcel Holtmann 	code = skb->data[0];
2959eb492e01SAnderson Briglia 	skb_pull(skb, sizeof(code));
2960eb492e01SAnderson Briglia 
2961b28b4943SJohan Hedberg 	smp = chan->data;
2962b28b4943SJohan Hedberg 
2963b28b4943SJohan Hedberg 	if (code > SMP_CMD_MAX)
2964b28b4943SJohan Hedberg 		goto drop;
2965b28b4943SJohan Hedberg 
296624bd0bd9SJohan Hedberg 	if (smp && !test_and_clear_bit(code, &smp->allow_cmd))
2967b28b4943SJohan Hedberg 		goto drop;
2968b28b4943SJohan Hedberg 
2969b28b4943SJohan Hedberg 	/* If we don't have a context the only allowed commands are
2970b28b4943SJohan Hedberg 	 * pairing request and security request.
29718cf9fa12SJohan Hedberg 	 */
2972b28b4943SJohan Hedberg 	if (!smp && code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ)
2973b28b4943SJohan Hedberg 		goto drop;
29748cf9fa12SJohan Hedberg 
2975eb492e01SAnderson Briglia 	switch (code) {
2976eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_REQ:
2977da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_req(conn, skb);
2978eb492e01SAnderson Briglia 		break;
2979eb492e01SAnderson Briglia 
2980eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_FAIL:
298184794e11SJohan Hedberg 		smp_failure(conn, 0);
2982da85e5e5SVinicius Costa Gomes 		err = -EPERM;
2983eb492e01SAnderson Briglia 		break;
2984eb492e01SAnderson Briglia 
2985eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_RSP:
2986da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_rsp(conn, skb);
298788ba43b6SAnderson Briglia 		break;
298888ba43b6SAnderson Briglia 
298988ba43b6SAnderson Briglia 	case SMP_CMD_SECURITY_REQ:
2990da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_security_req(conn, skb);
299188ba43b6SAnderson Briglia 		break;
299288ba43b6SAnderson Briglia 
2993eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_CONFIRM:
2994da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_confirm(conn, skb);
299588ba43b6SAnderson Briglia 		break;
299688ba43b6SAnderson Briglia 
2997eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_RANDOM:
2998da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_random(conn, skb);
299988ba43b6SAnderson Briglia 		break;
300088ba43b6SAnderson Briglia 
3001eb492e01SAnderson Briglia 	case SMP_CMD_ENCRYPT_INFO:
30027034b911SVinicius Costa Gomes 		reason = smp_cmd_encrypt_info(conn, skb);
30037034b911SVinicius Costa Gomes 		break;
30047034b911SVinicius Costa Gomes 
3005*fad646e1SArchie Pusaka 	case SMP_CMD_INITIATOR_IDENT:
3006*fad646e1SArchie Pusaka 		reason = smp_cmd_initiator_ident(conn, skb);
30077034b911SVinicius Costa Gomes 		break;
30087034b911SVinicius Costa Gomes 
3009eb492e01SAnderson Briglia 	case SMP_CMD_IDENT_INFO:
3010fd349c02SJohan Hedberg 		reason = smp_cmd_ident_info(conn, skb);
3011fd349c02SJohan Hedberg 		break;
3012fd349c02SJohan Hedberg 
3013eb492e01SAnderson Briglia 	case SMP_CMD_IDENT_ADDR_INFO:
3014fd349c02SJohan Hedberg 		reason = smp_cmd_ident_addr_info(conn, skb);
3015fd349c02SJohan Hedberg 		break;
3016fd349c02SJohan Hedberg 
3017eb492e01SAnderson Briglia 	case SMP_CMD_SIGN_INFO:
30187ee4ea36SMarcel Holtmann 		reason = smp_cmd_sign_info(conn, skb);
30197034b911SVinicius Costa Gomes 		break;
30207034b911SVinicius Costa Gomes 
3021d8f8edbeSJohan Hedberg 	case SMP_CMD_PUBLIC_KEY:
3022d8f8edbeSJohan Hedberg 		reason = smp_cmd_public_key(conn, skb);
3023d8f8edbeSJohan Hedberg 		break;
3024d8f8edbeSJohan Hedberg 
30256433a9a2SJohan Hedberg 	case SMP_CMD_DHKEY_CHECK:
30266433a9a2SJohan Hedberg 		reason = smp_cmd_dhkey_check(conn, skb);
30276433a9a2SJohan Hedberg 		break;
30286433a9a2SJohan Hedberg 
30291408bb6eSJohan Hedberg 	case SMP_CMD_KEYPRESS_NOTIFY:
30301408bb6eSJohan Hedberg 		reason = smp_cmd_keypress_notify(conn, skb);
30311408bb6eSJohan Hedberg 		break;
30321408bb6eSJohan Hedberg 
3033eb492e01SAnderson Briglia 	default:
30342e1614f7SLuiz Augusto von Dentz 		bt_dev_dbg(hcon->hdev, "Unknown command code 0x%2.2x", code);
3035eb492e01SAnderson Briglia 		reason = SMP_CMD_NOTSUPP;
30363a0259bbSVinicius Costa Gomes 		goto done;
30373a0259bbSVinicius Costa Gomes 	}
30383a0259bbSVinicius Costa Gomes 
30393a0259bbSVinicius Costa Gomes done:
30409b7b18efSJohan Hedberg 	if (!err) {
30413a0259bbSVinicius Costa Gomes 		if (reason)
304284794e11SJohan Hedberg 			smp_failure(conn, reason);
3043eb492e01SAnderson Briglia 		kfree_skb(skb);
30449b7b18efSJohan Hedberg 	}
30459b7b18efSJohan Hedberg 
3046eb492e01SAnderson Briglia 	return err;
3047b28b4943SJohan Hedberg 
3048b28b4943SJohan Hedberg drop:
30492064ee33SMarcel Holtmann 	bt_dev_err(hcon->hdev, "unexpected SMP command 0x%02x from %pMR",
3050b28b4943SJohan Hedberg 		   code, &hcon->dst);
3051b28b4943SJohan Hedberg 	kfree_skb(skb);
3052b28b4943SJohan Hedberg 	return 0;
3053eb492e01SAnderson Briglia }
30547034b911SVinicius Costa Gomes 
305570db83c4SJohan Hedberg static void smp_teardown_cb(struct l2cap_chan *chan, int err)
305670db83c4SJohan Hedberg {
305770db83c4SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
305870db83c4SJohan Hedberg 
30592e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(conn->hcon->hdev, "chan %p", chan);
306070db83c4SJohan Hedberg 
3061fc75cc86SJohan Hedberg 	if (chan->data)
30625d88cc73SJohan Hedberg 		smp_chan_destroy(conn);
30635d88cc73SJohan Hedberg 
306470db83c4SJohan Hedberg 	conn->smp = NULL;
306570db83c4SJohan Hedberg 	l2cap_chan_put(chan);
306670db83c4SJohan Hedberg }
306770db83c4SJohan Hedberg 
3068b5ae344dSJohan Hedberg static void bredr_pairing(struct l2cap_chan *chan)
3069b5ae344dSJohan Hedberg {
3070b5ae344dSJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
3071b5ae344dSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
3072b5ae344dSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
3073b5ae344dSJohan Hedberg 	struct smp_cmd_pairing req;
3074b5ae344dSJohan Hedberg 	struct smp_chan *smp;
3075b5ae344dSJohan Hedberg 
30762e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "chan %p", chan);
3077b5ae344dSJohan Hedberg 
3078b5ae344dSJohan Hedberg 	/* Only new pairings are interesting */
3079b5ae344dSJohan Hedberg 	if (!test_bit(HCI_CONN_NEW_LINK_KEY, &hcon->flags))
3080b5ae344dSJohan Hedberg 		return;
3081b5ae344dSJohan Hedberg 
3082b5ae344dSJohan Hedberg 	/* Don't bother if we're not encrypted */
3083b5ae344dSJohan Hedberg 	if (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags))
3084b5ae344dSJohan Hedberg 		return;
3085b5ae344dSJohan Hedberg 
3086b5ae344dSJohan Hedberg 	/* Only master may initiate SMP over BR/EDR */
3087b5ae344dSJohan Hedberg 	if (hcon->role != HCI_ROLE_MASTER)
3088b5ae344dSJohan Hedberg 		return;
3089b5ae344dSJohan Hedberg 
3090b5ae344dSJohan Hedberg 	/* Secure Connections support must be enabled */
3091d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_SC_ENABLED))
3092b5ae344dSJohan Hedberg 		return;
3093b5ae344dSJohan Hedberg 
3094b5ae344dSJohan Hedberg 	/* BR/EDR must use Secure Connections for SMP */
3095b5ae344dSJohan Hedberg 	if (!test_bit(HCI_CONN_AES_CCM, &hcon->flags) &&
3096b7cb93e5SMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP))
3097b5ae344dSJohan Hedberg 		return;
3098b5ae344dSJohan Hedberg 
3099b5ae344dSJohan Hedberg 	/* If our LE support is not enabled don't do anything */
3100d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED))
3101b5ae344dSJohan Hedberg 		return;
3102b5ae344dSJohan Hedberg 
3103b5ae344dSJohan Hedberg 	/* Don't bother if remote LE support is not enabled */
3104b5ae344dSJohan Hedberg 	if (!lmp_host_le_capable(hcon))
3105b5ae344dSJohan Hedberg 		return;
3106b5ae344dSJohan Hedberg 
3107b5ae344dSJohan Hedberg 	/* Remote must support SMP fixed chan for BR/EDR */
3108b5ae344dSJohan Hedberg 	if (!(conn->remote_fixed_chan & L2CAP_FC_SMP_BREDR))
3109b5ae344dSJohan Hedberg 		return;
3110b5ae344dSJohan Hedberg 
3111b5ae344dSJohan Hedberg 	/* Don't bother if SMP is already ongoing */
3112b5ae344dSJohan Hedberg 	if (chan->data)
3113b5ae344dSJohan Hedberg 		return;
3114b5ae344dSJohan Hedberg 
3115b5ae344dSJohan Hedberg 	smp = smp_chan_create(conn);
3116b5ae344dSJohan Hedberg 	if (!smp) {
31172064ee33SMarcel Holtmann 		bt_dev_err(hdev, "unable to create SMP context for BR/EDR");
3118b5ae344dSJohan Hedberg 		return;
3119b5ae344dSJohan Hedberg 	}
3120b5ae344dSJohan Hedberg 
3121b5ae344dSJohan Hedberg 	set_bit(SMP_FLAG_SC, &smp->flags);
3122b5ae344dSJohan Hedberg 
31232e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "starting SMP over BR/EDR");
3124b5ae344dSJohan Hedberg 
3125b5ae344dSJohan Hedberg 	/* Prepare and send the BR/EDR SMP Pairing Request */
3126b5ae344dSJohan Hedberg 	build_bredr_pairing_cmd(smp, &req, NULL);
3127b5ae344dSJohan Hedberg 
3128b5ae344dSJohan Hedberg 	smp->preq[0] = SMP_CMD_PAIRING_REQ;
3129b5ae344dSJohan Hedberg 	memcpy(&smp->preq[1], &req, sizeof(req));
3130b5ae344dSJohan Hedberg 
3131b5ae344dSJohan Hedberg 	smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(req), &req);
3132b5ae344dSJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP);
3133b5ae344dSJohan Hedberg }
3134b5ae344dSJohan Hedberg 
313544f1a7abSJohan Hedberg static void smp_resume_cb(struct l2cap_chan *chan)
313644f1a7abSJohan Hedberg {
3137b68fda68SJohan Hedberg 	struct smp_chan *smp = chan->data;
313844f1a7abSJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
313944f1a7abSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
314044f1a7abSJohan Hedberg 
31412e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hcon->hdev, "chan %p", chan);
314244f1a7abSJohan Hedberg 
3143b5ae344dSJohan Hedberg 	if (hcon->type == ACL_LINK) {
3144b5ae344dSJohan Hedberg 		bredr_pairing(chan);
3145ef8efe4bSJohan Hedberg 		return;
3146b5ae344dSJohan Hedberg 	}
3147ef8efe4bSJohan Hedberg 
314886d1407cSJohan Hedberg 	if (!smp)
314986d1407cSJohan Hedberg 		return;
3150b68fda68SJohan Hedberg 
315184bc0db5SJohan Hedberg 	if (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags))
315284bc0db5SJohan Hedberg 		return;
315384bc0db5SJohan Hedberg 
3154b68fda68SJohan Hedberg 	cancel_delayed_work(&smp->security_timer);
315586d1407cSJohan Hedberg 
3156d6268e86SJohan Hedberg 	smp_distribute_keys(smp);
315744f1a7abSJohan Hedberg }
315844f1a7abSJohan Hedberg 
315970db83c4SJohan Hedberg static void smp_ready_cb(struct l2cap_chan *chan)
316070db83c4SJohan Hedberg {
316170db83c4SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
3162b5ae344dSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
316370db83c4SJohan Hedberg 
31642e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hcon->hdev, "chan %p", chan);
316570db83c4SJohan Hedberg 
31667883746bSJohan Hedberg 	/* No need to call l2cap_chan_hold() here since we already own
31677883746bSJohan Hedberg 	 * the reference taken in smp_new_conn_cb(). This is just the
31687883746bSJohan Hedberg 	 * first time that we tie it to a specific pointer. The code in
31697883746bSJohan Hedberg 	 * l2cap_core.c ensures that there's no risk this function wont
31707883746bSJohan Hedberg 	 * get called if smp_new_conn_cb was previously called.
31717883746bSJohan Hedberg 	 */
317270db83c4SJohan Hedberg 	conn->smp = chan;
3173b5ae344dSJohan Hedberg 
3174b5ae344dSJohan Hedberg 	if (hcon->type == ACL_LINK && test_bit(HCI_CONN_ENCRYPT, &hcon->flags))
3175b5ae344dSJohan Hedberg 		bredr_pairing(chan);
317670db83c4SJohan Hedberg }
317770db83c4SJohan Hedberg 
31784befb867SJohan Hedberg static int smp_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
31794befb867SJohan Hedberg {
31804befb867SJohan Hedberg 	int err;
31814befb867SJohan Hedberg 
31822e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(chan->conn->hcon->hdev, "chan %p", chan);
31834befb867SJohan Hedberg 
31844befb867SJohan Hedberg 	err = smp_sig_channel(chan, skb);
31854befb867SJohan Hedberg 	if (err) {
3186b68fda68SJohan Hedberg 		struct smp_chan *smp = chan->data;
31874befb867SJohan Hedberg 
3188b68fda68SJohan Hedberg 		if (smp)
3189b68fda68SJohan Hedberg 			cancel_delayed_work_sync(&smp->security_timer);
31904befb867SJohan Hedberg 
31911e91c29eSJohan Hedberg 		hci_disconnect(chan->conn->hcon, HCI_ERROR_AUTH_FAILURE);
31924befb867SJohan Hedberg 	}
31934befb867SJohan Hedberg 
31944befb867SJohan Hedberg 	return err;
31954befb867SJohan Hedberg }
31964befb867SJohan Hedberg 
319770db83c4SJohan Hedberg static struct sk_buff *smp_alloc_skb_cb(struct l2cap_chan *chan,
319870db83c4SJohan Hedberg 					unsigned long hdr_len,
319970db83c4SJohan Hedberg 					unsigned long len, int nb)
320070db83c4SJohan Hedberg {
320170db83c4SJohan Hedberg 	struct sk_buff *skb;
320270db83c4SJohan Hedberg 
320370db83c4SJohan Hedberg 	skb = bt_skb_alloc(hdr_len + len, GFP_KERNEL);
320470db83c4SJohan Hedberg 	if (!skb)
320570db83c4SJohan Hedberg 		return ERR_PTR(-ENOMEM);
320670db83c4SJohan Hedberg 
320770db83c4SJohan Hedberg 	skb->priority = HCI_PRIO_MAX;
3208a4368ff3SJohan Hedberg 	bt_cb(skb)->l2cap.chan = chan;
320970db83c4SJohan Hedberg 
321070db83c4SJohan Hedberg 	return skb;
321170db83c4SJohan Hedberg }
321270db83c4SJohan Hedberg 
321370db83c4SJohan Hedberg static const struct l2cap_ops smp_chan_ops = {
321470db83c4SJohan Hedberg 	.name			= "Security Manager",
321570db83c4SJohan Hedberg 	.ready			= smp_ready_cb,
32165d88cc73SJohan Hedberg 	.recv			= smp_recv_cb,
321770db83c4SJohan Hedberg 	.alloc_skb		= smp_alloc_skb_cb,
321870db83c4SJohan Hedberg 	.teardown		= smp_teardown_cb,
321944f1a7abSJohan Hedberg 	.resume			= smp_resume_cb,
322070db83c4SJohan Hedberg 
322170db83c4SJohan Hedberg 	.new_connection		= l2cap_chan_no_new_connection,
322270db83c4SJohan Hedberg 	.state_change		= l2cap_chan_no_state_change,
322370db83c4SJohan Hedberg 	.close			= l2cap_chan_no_close,
322470db83c4SJohan Hedberg 	.defer			= l2cap_chan_no_defer,
322570db83c4SJohan Hedberg 	.suspend		= l2cap_chan_no_suspend,
322670db83c4SJohan Hedberg 	.set_shutdown		= l2cap_chan_no_set_shutdown,
322770db83c4SJohan Hedberg 	.get_sndtimeo		= l2cap_chan_no_get_sndtimeo,
322870db83c4SJohan Hedberg };
322970db83c4SJohan Hedberg 
323070db83c4SJohan Hedberg static inline struct l2cap_chan *smp_new_conn_cb(struct l2cap_chan *pchan)
323170db83c4SJohan Hedberg {
323270db83c4SJohan Hedberg 	struct l2cap_chan *chan;
323370db83c4SJohan Hedberg 
3234995fca15SLuiz Augusto von Dentz 	BT_DBG("pchan %p", pchan);
323570db83c4SJohan Hedberg 
323670db83c4SJohan Hedberg 	chan = l2cap_chan_create();
323770db83c4SJohan Hedberg 	if (!chan)
323870db83c4SJohan Hedberg 		return NULL;
323970db83c4SJohan Hedberg 
324070db83c4SJohan Hedberg 	chan->chan_type	= pchan->chan_type;
324170db83c4SJohan Hedberg 	chan->ops	= &smp_chan_ops;
324270db83c4SJohan Hedberg 	chan->scid	= pchan->scid;
324370db83c4SJohan Hedberg 	chan->dcid	= chan->scid;
324470db83c4SJohan Hedberg 	chan->imtu	= pchan->imtu;
324570db83c4SJohan Hedberg 	chan->omtu	= pchan->omtu;
324670db83c4SJohan Hedberg 	chan->mode	= pchan->mode;
324770db83c4SJohan Hedberg 
3248abe84903SJohan Hedberg 	/* Other L2CAP channels may request SMP routines in order to
3249abe84903SJohan Hedberg 	 * change the security level. This means that the SMP channel
3250abe84903SJohan Hedberg 	 * lock must be considered in its own category to avoid lockdep
3251abe84903SJohan Hedberg 	 * warnings.
3252abe84903SJohan Hedberg 	 */
3253abe84903SJohan Hedberg 	atomic_set(&chan->nesting, L2CAP_NESTING_SMP);
3254abe84903SJohan Hedberg 
3255995fca15SLuiz Augusto von Dentz 	BT_DBG("created chan %p", chan);
325670db83c4SJohan Hedberg 
325770db83c4SJohan Hedberg 	return chan;
325870db83c4SJohan Hedberg }
325970db83c4SJohan Hedberg 
326070db83c4SJohan Hedberg static const struct l2cap_ops smp_root_chan_ops = {
326170db83c4SJohan Hedberg 	.name			= "Security Manager Root",
326270db83c4SJohan Hedberg 	.new_connection		= smp_new_conn_cb,
326370db83c4SJohan Hedberg 
326470db83c4SJohan Hedberg 	/* None of these are implemented for the root channel */
326570db83c4SJohan Hedberg 	.close			= l2cap_chan_no_close,
326670db83c4SJohan Hedberg 	.alloc_skb		= l2cap_chan_no_alloc_skb,
326770db83c4SJohan Hedberg 	.recv			= l2cap_chan_no_recv,
326870db83c4SJohan Hedberg 	.state_change		= l2cap_chan_no_state_change,
326970db83c4SJohan Hedberg 	.teardown		= l2cap_chan_no_teardown,
327070db83c4SJohan Hedberg 	.ready			= l2cap_chan_no_ready,
327170db83c4SJohan Hedberg 	.defer			= l2cap_chan_no_defer,
327270db83c4SJohan Hedberg 	.suspend		= l2cap_chan_no_suspend,
327370db83c4SJohan Hedberg 	.resume			= l2cap_chan_no_resume,
327470db83c4SJohan Hedberg 	.set_shutdown		= l2cap_chan_no_set_shutdown,
327570db83c4SJohan Hedberg 	.get_sndtimeo		= l2cap_chan_no_get_sndtimeo,
327670db83c4SJohan Hedberg };
327770db83c4SJohan Hedberg 
3278ef8efe4bSJohan Hedberg static struct l2cap_chan *smp_add_cid(struct hci_dev *hdev, u16 cid)
3279711eafe3SJohan Hedberg {
328070db83c4SJohan Hedberg 	struct l2cap_chan *chan;
328188a479d9SMarcel Holtmann 	struct smp_dev *smp;
328271af2f6bSHerbert Xu 	struct crypto_shash *tfm_cmac;
328347eb2ac8STudor Ambarus 	struct crypto_kpp *tfm_ecdh;
328470db83c4SJohan Hedberg 
3285ef8efe4bSJohan Hedberg 	if (cid == L2CAP_CID_SMP_BREDR) {
328688a479d9SMarcel Holtmann 		smp = NULL;
3287ef8efe4bSJohan Hedberg 		goto create_chan;
3288ef8efe4bSJohan Hedberg 	}
3289711eafe3SJohan Hedberg 
329088a479d9SMarcel Holtmann 	smp = kzalloc(sizeof(*smp), GFP_KERNEL);
329188a479d9SMarcel Holtmann 	if (!smp)
329288a479d9SMarcel Holtmann 		return ERR_PTR(-ENOMEM);
329388a479d9SMarcel Holtmann 
329471af2f6bSHerbert Xu 	tfm_cmac = crypto_alloc_shash("cmac(aes)", 0, 0);
32956e2dc6d1SMarcel Holtmann 	if (IS_ERR(tfm_cmac)) {
32962e1614f7SLuiz Augusto von Dentz 		bt_dev_err(hdev, "Unable to create CMAC crypto context");
3297453431a5SWaiman Long 		kfree_sensitive(smp);
32986e2dc6d1SMarcel Holtmann 		return ERR_CAST(tfm_cmac);
32996e2dc6d1SMarcel Holtmann 	}
33006e2dc6d1SMarcel Holtmann 
33016763f5eaSMeng Yu 	tfm_ecdh = crypto_alloc_kpp("ecdh-nist-p256", 0, 0);
330247eb2ac8STudor Ambarus 	if (IS_ERR(tfm_ecdh)) {
33032e1614f7SLuiz Augusto von Dentz 		bt_dev_err(hdev, "Unable to create ECDH crypto context");
330447eb2ac8STudor Ambarus 		crypto_free_shash(tfm_cmac);
3305453431a5SWaiman Long 		kfree_sensitive(smp);
330647eb2ac8STudor Ambarus 		return ERR_CAST(tfm_ecdh);
330747eb2ac8STudor Ambarus 	}
330847eb2ac8STudor Ambarus 
330994f14e47SJohan Hedberg 	smp->local_oob = false;
33106e2dc6d1SMarcel Holtmann 	smp->tfm_cmac = tfm_cmac;
331147eb2ac8STudor Ambarus 	smp->tfm_ecdh = tfm_ecdh;
331288a479d9SMarcel Holtmann 
3313ef8efe4bSJohan Hedberg create_chan:
331470db83c4SJohan Hedberg 	chan = l2cap_chan_create();
331570db83c4SJohan Hedberg 	if (!chan) {
331663511f6dSMarcel Holtmann 		if (smp) {
331771af2f6bSHerbert Xu 			crypto_free_shash(smp->tfm_cmac);
331847eb2ac8STudor Ambarus 			crypto_free_kpp(smp->tfm_ecdh);
3319453431a5SWaiman Long 			kfree_sensitive(smp);
332063511f6dSMarcel Holtmann 		}
3321ef8efe4bSJohan Hedberg 		return ERR_PTR(-ENOMEM);
332270db83c4SJohan Hedberg 	}
332370db83c4SJohan Hedberg 
332488a479d9SMarcel Holtmann 	chan->data = smp;
3325defce9e8SJohan Hedberg 
3326ef8efe4bSJohan Hedberg 	l2cap_add_scid(chan, cid);
332770db83c4SJohan Hedberg 
332870db83c4SJohan Hedberg 	l2cap_chan_set_defaults(chan);
332970db83c4SJohan Hedberg 
3330157029baSMarcel Holtmann 	if (cid == L2CAP_CID_SMP) {
333139e3e744SJohan Hedberg 		u8 bdaddr_type;
333239e3e744SJohan Hedberg 
333339e3e744SJohan Hedberg 		hci_copy_identity_address(hdev, &chan->src, &bdaddr_type);
333439e3e744SJohan Hedberg 
333539e3e744SJohan Hedberg 		if (bdaddr_type == ADDR_LE_DEV_PUBLIC)
333670db83c4SJohan Hedberg 			chan->src_type = BDADDR_LE_PUBLIC;
333739e3e744SJohan Hedberg 		else
333839e3e744SJohan Hedberg 			chan->src_type = BDADDR_LE_RANDOM;
3339157029baSMarcel Holtmann 	} else {
3340157029baSMarcel Holtmann 		bacpy(&chan->src, &hdev->bdaddr);
3341ef8efe4bSJohan Hedberg 		chan->src_type = BDADDR_BREDR;
3342157029baSMarcel Holtmann 	}
3343157029baSMarcel Holtmann 
334470db83c4SJohan Hedberg 	chan->state = BT_LISTEN;
334570db83c4SJohan Hedberg 	chan->mode = L2CAP_MODE_BASIC;
334670db83c4SJohan Hedberg 	chan->imtu = L2CAP_DEFAULT_MTU;
334770db83c4SJohan Hedberg 	chan->ops = &smp_root_chan_ops;
334870db83c4SJohan Hedberg 
3349abe84903SJohan Hedberg 	/* Set correct nesting level for a parent/listening channel */
3350abe84903SJohan Hedberg 	atomic_set(&chan->nesting, L2CAP_NESTING_PARENT);
3351abe84903SJohan Hedberg 
3352ef8efe4bSJohan Hedberg 	return chan;
3353711eafe3SJohan Hedberg }
3354711eafe3SJohan Hedberg 
3355ef8efe4bSJohan Hedberg static void smp_del_chan(struct l2cap_chan *chan)
3356711eafe3SJohan Hedberg {
335788a479d9SMarcel Holtmann 	struct smp_dev *smp;
335870db83c4SJohan Hedberg 
3359995fca15SLuiz Augusto von Dentz 	BT_DBG("chan %p", chan);
3360711eafe3SJohan Hedberg 
336188a479d9SMarcel Holtmann 	smp = chan->data;
336288a479d9SMarcel Holtmann 	if (smp) {
3363defce9e8SJohan Hedberg 		chan->data = NULL;
336471af2f6bSHerbert Xu 		crypto_free_shash(smp->tfm_cmac);
336547eb2ac8STudor Ambarus 		crypto_free_kpp(smp->tfm_ecdh);
3366453431a5SWaiman Long 		kfree_sensitive(smp);
3367711eafe3SJohan Hedberg 	}
336870db83c4SJohan Hedberg 
336970db83c4SJohan Hedberg 	l2cap_chan_put(chan);
3370711eafe3SJohan Hedberg }
3371ef8efe4bSJohan Hedberg 
337282493316SClaire Chang int smp_force_bredr(struct hci_dev *hdev, bool enable)
3373300acfdeSMarcel Holtmann {
3374b7cb93e5SMarcel Holtmann 	if (enable == hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP))
3375300acfdeSMarcel Holtmann 		return -EALREADY;
3376300acfdeSMarcel Holtmann 
3377300acfdeSMarcel Holtmann 	if (enable) {
3378300acfdeSMarcel Holtmann 		struct l2cap_chan *chan;
3379300acfdeSMarcel Holtmann 
3380300acfdeSMarcel Holtmann 		chan = smp_add_cid(hdev, L2CAP_CID_SMP_BREDR);
3381300acfdeSMarcel Holtmann 		if (IS_ERR(chan))
3382300acfdeSMarcel Holtmann 			return PTR_ERR(chan);
3383300acfdeSMarcel Holtmann 
3384300acfdeSMarcel Holtmann 		hdev->smp_bredr_data = chan;
3385300acfdeSMarcel Holtmann 	} else {
3386300acfdeSMarcel Holtmann 		struct l2cap_chan *chan;
3387300acfdeSMarcel Holtmann 
3388300acfdeSMarcel Holtmann 		chan = hdev->smp_bredr_data;
3389300acfdeSMarcel Holtmann 		hdev->smp_bredr_data = NULL;
3390300acfdeSMarcel Holtmann 		smp_del_chan(chan);
3391300acfdeSMarcel Holtmann 	}
3392300acfdeSMarcel Holtmann 
3393b7cb93e5SMarcel Holtmann 	hci_dev_change_flag(hdev, HCI_FORCE_BREDR_SMP);
3394300acfdeSMarcel Holtmann 
339582493316SClaire Chang 	return 0;
3396300acfdeSMarcel Holtmann }
3397300acfdeSMarcel Holtmann 
3398ef8efe4bSJohan Hedberg int smp_register(struct hci_dev *hdev)
3399ef8efe4bSJohan Hedberg {
3400ef8efe4bSJohan Hedberg 	struct l2cap_chan *chan;
3401ef8efe4bSJohan Hedberg 
34022e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
3403ef8efe4bSJohan Hedberg 
34047e7ec445SMarcel Holtmann 	/* If the controller does not support Low Energy operation, then
34057e7ec445SMarcel Holtmann 	 * there is also no need to register any SMP channel.
34067e7ec445SMarcel Holtmann 	 */
34077e7ec445SMarcel Holtmann 	if (!lmp_le_capable(hdev))
34087e7ec445SMarcel Holtmann 		return 0;
34097e7ec445SMarcel Holtmann 
34102b8df323SMarcel Holtmann 	if (WARN_ON(hdev->smp_data)) {
34112b8df323SMarcel Holtmann 		chan = hdev->smp_data;
34122b8df323SMarcel Holtmann 		hdev->smp_data = NULL;
34132b8df323SMarcel Holtmann 		smp_del_chan(chan);
34142b8df323SMarcel Holtmann 	}
34152b8df323SMarcel Holtmann 
3416ef8efe4bSJohan Hedberg 	chan = smp_add_cid(hdev, L2CAP_CID_SMP);
3417ef8efe4bSJohan Hedberg 	if (IS_ERR(chan))
3418ef8efe4bSJohan Hedberg 		return PTR_ERR(chan);
3419ef8efe4bSJohan Hedberg 
3420ef8efe4bSJohan Hedberg 	hdev->smp_data = chan;
3421ef8efe4bSJohan Hedberg 
3422300acfdeSMarcel Holtmann 	if (!lmp_sc_capable(hdev)) {
342383ebb9ecSSzymon Janc 		/* Flag can be already set here (due to power toggle) */
342483ebb9ecSSzymon Janc 		if (!hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP))
3425ef8efe4bSJohan Hedberg 			return 0;
3426300acfdeSMarcel Holtmann 	}
3427ef8efe4bSJohan Hedberg 
34282b8df323SMarcel Holtmann 	if (WARN_ON(hdev->smp_bredr_data)) {
34292b8df323SMarcel Holtmann 		chan = hdev->smp_bredr_data;
34302b8df323SMarcel Holtmann 		hdev->smp_bredr_data = NULL;
34312b8df323SMarcel Holtmann 		smp_del_chan(chan);
34322b8df323SMarcel Holtmann 	}
34332b8df323SMarcel Holtmann 
3434ef8efe4bSJohan Hedberg 	chan = smp_add_cid(hdev, L2CAP_CID_SMP_BREDR);
3435ef8efe4bSJohan Hedberg 	if (IS_ERR(chan)) {
3436ef8efe4bSJohan Hedberg 		int err = PTR_ERR(chan);
3437ef8efe4bSJohan Hedberg 		chan = hdev->smp_data;
3438ef8efe4bSJohan Hedberg 		hdev->smp_data = NULL;
3439ef8efe4bSJohan Hedberg 		smp_del_chan(chan);
3440ef8efe4bSJohan Hedberg 		return err;
3441ef8efe4bSJohan Hedberg 	}
3442ef8efe4bSJohan Hedberg 
3443ef8efe4bSJohan Hedberg 	hdev->smp_bredr_data = chan;
3444ef8efe4bSJohan Hedberg 
3445ef8efe4bSJohan Hedberg 	return 0;
3446ef8efe4bSJohan Hedberg }
3447ef8efe4bSJohan Hedberg 
3448ef8efe4bSJohan Hedberg void smp_unregister(struct hci_dev *hdev)
3449ef8efe4bSJohan Hedberg {
3450ef8efe4bSJohan Hedberg 	struct l2cap_chan *chan;
3451ef8efe4bSJohan Hedberg 
3452ef8efe4bSJohan Hedberg 	if (hdev->smp_bredr_data) {
3453ef8efe4bSJohan Hedberg 		chan = hdev->smp_bredr_data;
3454ef8efe4bSJohan Hedberg 		hdev->smp_bredr_data = NULL;
3455ef8efe4bSJohan Hedberg 		smp_del_chan(chan);
3456ef8efe4bSJohan Hedberg 	}
3457ef8efe4bSJohan Hedberg 
3458ef8efe4bSJohan Hedberg 	if (hdev->smp_data) {
3459ef8efe4bSJohan Hedberg 		chan = hdev->smp_data;
3460ef8efe4bSJohan Hedberg 		hdev->smp_data = NULL;
3461ef8efe4bSJohan Hedberg 		smp_del_chan(chan);
3462ef8efe4bSJohan Hedberg 	}
3463ef8efe4bSJohan Hedberg }
34640a2b0f04SJohan Hedberg 
34650a2b0f04SJohan Hedberg #if IS_ENABLED(CONFIG_BT_SELFTEST_SMP)
34660a2b0f04SJohan Hedberg 
346747eb2ac8STudor Ambarus static int __init test_debug_key(struct crypto_kpp *tfm_ecdh)
346871653eb6SMarcel Holtmann {
3469c0153b0bSTudor Ambarus 	u8 pk[64];
3470a2976416STudor Ambarus 	int err;
347171653eb6SMarcel Holtmann 
3472c0153b0bSTudor Ambarus 	err = set_ecdh_privkey(tfm_ecdh, debug_sk);
3473a2976416STudor Ambarus 	if (err)
3474a2976416STudor Ambarus 		return err;
347571653eb6SMarcel Holtmann 
3476c0153b0bSTudor Ambarus 	err = generate_ecdh_public_key(tfm_ecdh, pk);
3477c0153b0bSTudor Ambarus 	if (err)
3478c0153b0bSTudor Ambarus 		return err;
347971653eb6SMarcel Holtmann 
3480329d8230SJason A. Donenfeld 	if (crypto_memneq(pk, debug_pk, 64))
348171653eb6SMarcel Holtmann 		return -EINVAL;
348271653eb6SMarcel Holtmann 
348371653eb6SMarcel Holtmann 	return 0;
348471653eb6SMarcel Holtmann }
348571653eb6SMarcel Holtmann 
348628a220aaSArd Biesheuvel static int __init test_ah(void)
3487cfc4198eSJohan Hedberg {
3488cfc4198eSJohan Hedberg 	const u8 irk[16] = {
3489cfc4198eSJohan Hedberg 			0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34,
3490cfc4198eSJohan Hedberg 			0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec };
3491cfc4198eSJohan Hedberg 	const u8 r[3] = { 0x94, 0x81, 0x70 };
3492cfc4198eSJohan Hedberg 	const u8 exp[3] = { 0xaa, 0xfb, 0x0d };
3493cfc4198eSJohan Hedberg 	u8 res[3];
3494cfc4198eSJohan Hedberg 	int err;
3495cfc4198eSJohan Hedberg 
349628a220aaSArd Biesheuvel 	err = smp_ah(irk, r, res);
3497cfc4198eSJohan Hedberg 	if (err)
3498cfc4198eSJohan Hedberg 		return err;
3499cfc4198eSJohan Hedberg 
3500329d8230SJason A. Donenfeld 	if (crypto_memneq(res, exp, 3))
3501cfc4198eSJohan Hedberg 		return -EINVAL;
3502cfc4198eSJohan Hedberg 
3503cfc4198eSJohan Hedberg 	return 0;
3504cfc4198eSJohan Hedberg }
3505cfc4198eSJohan Hedberg 
350628a220aaSArd Biesheuvel static int __init test_c1(void)
3507cfc4198eSJohan Hedberg {
3508cfc4198eSJohan Hedberg 	const u8 k[16] = {
3509cfc4198eSJohan Hedberg 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3510cfc4198eSJohan Hedberg 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
3511cfc4198eSJohan Hedberg 	const u8 r[16] = {
3512cfc4198eSJohan Hedberg 			0xe0, 0x2e, 0x70, 0xc6, 0x4e, 0x27, 0x88, 0x63,
3513cfc4198eSJohan Hedberg 			0x0e, 0x6f, 0xad, 0x56, 0x21, 0xd5, 0x83, 0x57 };
3514cfc4198eSJohan Hedberg 	const u8 preq[7] = { 0x01, 0x01, 0x00, 0x00, 0x10, 0x07, 0x07 };
3515cfc4198eSJohan Hedberg 	const u8 pres[7] = { 0x02, 0x03, 0x00, 0x00, 0x08, 0x00, 0x05 };
3516cfc4198eSJohan Hedberg 	const u8 _iat = 0x01;
3517cfc4198eSJohan Hedberg 	const u8 _rat = 0x00;
3518cfc4198eSJohan Hedberg 	const bdaddr_t ra = { { 0xb6, 0xb5, 0xb4, 0xb3, 0xb2, 0xb1 } };
3519cfc4198eSJohan Hedberg 	const bdaddr_t ia = { { 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1 } };
3520cfc4198eSJohan Hedberg 	const u8 exp[16] = {
3521cfc4198eSJohan Hedberg 			0x86, 0x3b, 0xf1, 0xbe, 0xc5, 0x4d, 0xa7, 0xd2,
3522cfc4198eSJohan Hedberg 			0xea, 0x88, 0x89, 0x87, 0xef, 0x3f, 0x1e, 0x1e };
3523cfc4198eSJohan Hedberg 	u8 res[16];
3524cfc4198eSJohan Hedberg 	int err;
3525cfc4198eSJohan Hedberg 
352628a220aaSArd Biesheuvel 	err = smp_c1(k, r, preq, pres, _iat, &ia, _rat, &ra, res);
3527cfc4198eSJohan Hedberg 	if (err)
3528cfc4198eSJohan Hedberg 		return err;
3529cfc4198eSJohan Hedberg 
3530329d8230SJason A. Donenfeld 	if (crypto_memneq(res, exp, 16))
3531cfc4198eSJohan Hedberg 		return -EINVAL;
3532cfc4198eSJohan Hedberg 
3533cfc4198eSJohan Hedberg 	return 0;
3534cfc4198eSJohan Hedberg }
3535cfc4198eSJohan Hedberg 
353628a220aaSArd Biesheuvel static int __init test_s1(void)
3537cfc4198eSJohan Hedberg {
3538cfc4198eSJohan Hedberg 	const u8 k[16] = {
3539cfc4198eSJohan Hedberg 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3540cfc4198eSJohan Hedberg 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
3541cfc4198eSJohan Hedberg 	const u8 r1[16] = {
3542cfc4198eSJohan Hedberg 			0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 };
3543cfc4198eSJohan Hedberg 	const u8 r2[16] = {
3544cfc4198eSJohan Hedberg 			0x00, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99 };
3545cfc4198eSJohan Hedberg 	const u8 exp[16] = {
3546cfc4198eSJohan Hedberg 			0x62, 0xa0, 0x6d, 0x79, 0xae, 0x16, 0x42, 0x5b,
3547cfc4198eSJohan Hedberg 			0x9b, 0xf4, 0xb0, 0xe8, 0xf0, 0xe1, 0x1f, 0x9a };
3548cfc4198eSJohan Hedberg 	u8 res[16];
3549cfc4198eSJohan Hedberg 	int err;
3550cfc4198eSJohan Hedberg 
355128a220aaSArd Biesheuvel 	err = smp_s1(k, r1, r2, res);
3552cfc4198eSJohan Hedberg 	if (err)
3553cfc4198eSJohan Hedberg 		return err;
3554cfc4198eSJohan Hedberg 
3555329d8230SJason A. Donenfeld 	if (crypto_memneq(res, exp, 16))
3556cfc4198eSJohan Hedberg 		return -EINVAL;
3557cfc4198eSJohan Hedberg 
3558cfc4198eSJohan Hedberg 	return 0;
3559cfc4198eSJohan Hedberg }
3560cfc4198eSJohan Hedberg 
356171af2f6bSHerbert Xu static int __init test_f4(struct crypto_shash *tfm_cmac)
3562fb2969a3SJohan Hedberg {
3563fb2969a3SJohan Hedberg 	const u8 u[32] = {
3564fb2969a3SJohan Hedberg 			0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc,
3565fb2969a3SJohan Hedberg 			0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef,
3566fb2969a3SJohan Hedberg 			0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e,
3567fb2969a3SJohan Hedberg 			0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20 };
3568fb2969a3SJohan Hedberg 	const u8 v[32] = {
3569fb2969a3SJohan Hedberg 			0xfd, 0xc5, 0x7f, 0xf4, 0x49, 0xdd, 0x4f, 0x6b,
3570fb2969a3SJohan Hedberg 			0xfb, 0x7c, 0x9d, 0xf1, 0xc2, 0x9a, 0xcb, 0x59,
3571fb2969a3SJohan Hedberg 			0x2a, 0xe7, 0xd4, 0xee, 0xfb, 0xfc, 0x0a, 0x90,
3572fb2969a3SJohan Hedberg 			0x9a, 0xbb, 0xf6, 0x32, 0x3d, 0x8b, 0x18, 0x55 };
3573fb2969a3SJohan Hedberg 	const u8 x[16] = {
3574fb2969a3SJohan Hedberg 			0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff,
3575fb2969a3SJohan Hedberg 			0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 };
3576fb2969a3SJohan Hedberg 	const u8 z = 0x00;
3577fb2969a3SJohan Hedberg 	const u8 exp[16] = {
3578fb2969a3SJohan Hedberg 			0x2d, 0x87, 0x74, 0xa9, 0xbe, 0xa1, 0xed, 0xf1,
3579fb2969a3SJohan Hedberg 			0x1c, 0xbd, 0xa9, 0x07, 0xf1, 0x16, 0xc9, 0xf2 };
3580fb2969a3SJohan Hedberg 	u8 res[16];
3581fb2969a3SJohan Hedberg 	int err;
3582fb2969a3SJohan Hedberg 
3583fb2969a3SJohan Hedberg 	err = smp_f4(tfm_cmac, u, v, x, z, res);
3584fb2969a3SJohan Hedberg 	if (err)
3585fb2969a3SJohan Hedberg 		return err;
3586fb2969a3SJohan Hedberg 
3587329d8230SJason A. Donenfeld 	if (crypto_memneq(res, exp, 16))
3588fb2969a3SJohan Hedberg 		return -EINVAL;
3589fb2969a3SJohan Hedberg 
3590fb2969a3SJohan Hedberg 	return 0;
3591fb2969a3SJohan Hedberg }
3592fb2969a3SJohan Hedberg 
359371af2f6bSHerbert Xu static int __init test_f5(struct crypto_shash *tfm_cmac)
3594fb2969a3SJohan Hedberg {
3595fb2969a3SJohan Hedberg 	const u8 w[32] = {
3596fb2969a3SJohan Hedberg 			0x98, 0xa6, 0xbf, 0x73, 0xf3, 0x34, 0x8d, 0x86,
3597fb2969a3SJohan Hedberg 			0xf1, 0x66, 0xf8, 0xb4, 0x13, 0x6b, 0x79, 0x99,
3598fb2969a3SJohan Hedberg 			0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34,
3599fb2969a3SJohan Hedberg 			0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec };
3600fb2969a3SJohan Hedberg 	const u8 n1[16] = {
3601fb2969a3SJohan Hedberg 			0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff,
3602fb2969a3SJohan Hedberg 			0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 };
3603fb2969a3SJohan Hedberg 	const u8 n2[16] = {
3604fb2969a3SJohan Hedberg 			0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21,
3605fb2969a3SJohan Hedberg 			0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6 };
3606fb2969a3SJohan Hedberg 	const u8 a1[7] = { 0xce, 0xbf, 0x37, 0x37, 0x12, 0x56, 0x00 };
3607fb2969a3SJohan Hedberg 	const u8 a2[7] = { 0xc1, 0xcf, 0x2d, 0x70, 0x13, 0xa7, 0x00 };
3608fb2969a3SJohan Hedberg 	const u8 exp_ltk[16] = {
3609fb2969a3SJohan Hedberg 			0x38, 0x0a, 0x75, 0x94, 0xb5, 0x22, 0x05, 0x98,
3610fb2969a3SJohan Hedberg 			0x23, 0xcd, 0xd7, 0x69, 0x11, 0x79, 0x86, 0x69 };
3611fb2969a3SJohan Hedberg 	const u8 exp_mackey[16] = {
3612fb2969a3SJohan Hedberg 			0x20, 0x6e, 0x63, 0xce, 0x20, 0x6a, 0x3f, 0xfd,
3613fb2969a3SJohan Hedberg 			0x02, 0x4a, 0x08, 0xa1, 0x76, 0xf1, 0x65, 0x29 };
3614fb2969a3SJohan Hedberg 	u8 mackey[16], ltk[16];
3615fb2969a3SJohan Hedberg 	int err;
3616fb2969a3SJohan Hedberg 
3617fb2969a3SJohan Hedberg 	err = smp_f5(tfm_cmac, w, n1, n2, a1, a2, mackey, ltk);
3618fb2969a3SJohan Hedberg 	if (err)
3619fb2969a3SJohan Hedberg 		return err;
3620fb2969a3SJohan Hedberg 
3621329d8230SJason A. Donenfeld 	if (crypto_memneq(mackey, exp_mackey, 16))
3622fb2969a3SJohan Hedberg 		return -EINVAL;
3623fb2969a3SJohan Hedberg 
3624329d8230SJason A. Donenfeld 	if (crypto_memneq(ltk, exp_ltk, 16))
3625fb2969a3SJohan Hedberg 		return -EINVAL;
3626fb2969a3SJohan Hedberg 
3627fb2969a3SJohan Hedberg 	return 0;
3628fb2969a3SJohan Hedberg }
3629fb2969a3SJohan Hedberg 
363071af2f6bSHerbert Xu static int __init test_f6(struct crypto_shash *tfm_cmac)
3631fb2969a3SJohan Hedberg {
3632fb2969a3SJohan Hedberg 	const u8 w[16] = {
3633fb2969a3SJohan Hedberg 			0x20, 0x6e, 0x63, 0xce, 0x20, 0x6a, 0x3f, 0xfd,
3634fb2969a3SJohan Hedberg 			0x02, 0x4a, 0x08, 0xa1, 0x76, 0xf1, 0x65, 0x29 };
3635fb2969a3SJohan Hedberg 	const u8 n1[16] = {
3636fb2969a3SJohan Hedberg 			0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff,
3637fb2969a3SJohan Hedberg 			0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 };
3638fb2969a3SJohan Hedberg 	const u8 n2[16] = {
3639fb2969a3SJohan Hedberg 			0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21,
3640fb2969a3SJohan Hedberg 			0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6 };
3641fb2969a3SJohan Hedberg 	const u8 r[16] = {
3642fb2969a3SJohan Hedberg 			0xc8, 0x0f, 0x2d, 0x0c, 0xd2, 0x42, 0xda, 0x08,
3643fb2969a3SJohan Hedberg 			0x54, 0xbb, 0x53, 0xb4, 0x3b, 0x34, 0xa3, 0x12 };
3644fb2969a3SJohan Hedberg 	const u8 io_cap[3] = { 0x02, 0x01, 0x01 };
3645fb2969a3SJohan Hedberg 	const u8 a1[7] = { 0xce, 0xbf, 0x37, 0x37, 0x12, 0x56, 0x00 };
3646fb2969a3SJohan Hedberg 	const u8 a2[7] = { 0xc1, 0xcf, 0x2d, 0x70, 0x13, 0xa7, 0x00 };
3647fb2969a3SJohan Hedberg 	const u8 exp[16] = {
3648fb2969a3SJohan Hedberg 			0x61, 0x8f, 0x95, 0xda, 0x09, 0x0b, 0x6c, 0xd2,
3649fb2969a3SJohan Hedberg 			0xc5, 0xe8, 0xd0, 0x9c, 0x98, 0x73, 0xc4, 0xe3 };
3650fb2969a3SJohan Hedberg 	u8 res[16];
3651fb2969a3SJohan Hedberg 	int err;
3652fb2969a3SJohan Hedberg 
3653fb2969a3SJohan Hedberg 	err = smp_f6(tfm_cmac, w, n1, n2, r, io_cap, a1, a2, res);
3654fb2969a3SJohan Hedberg 	if (err)
3655fb2969a3SJohan Hedberg 		return err;
3656fb2969a3SJohan Hedberg 
3657329d8230SJason A. Donenfeld 	if (crypto_memneq(res, exp, 16))
3658fb2969a3SJohan Hedberg 		return -EINVAL;
3659fb2969a3SJohan Hedberg 
3660fb2969a3SJohan Hedberg 	return 0;
3661fb2969a3SJohan Hedberg }
3662fb2969a3SJohan Hedberg 
366371af2f6bSHerbert Xu static int __init test_g2(struct crypto_shash *tfm_cmac)
3664fb2969a3SJohan Hedberg {
3665fb2969a3SJohan Hedberg 	const u8 u[32] = {
3666fb2969a3SJohan Hedberg 			0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc,
3667fb2969a3SJohan Hedberg 			0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef,
3668fb2969a3SJohan Hedberg 			0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e,
3669fb2969a3SJohan Hedberg 			0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20 };
3670fb2969a3SJohan Hedberg 	const u8 v[32] = {
3671fb2969a3SJohan Hedberg 			0xfd, 0xc5, 0x7f, 0xf4, 0x49, 0xdd, 0x4f, 0x6b,
3672fb2969a3SJohan Hedberg 			0xfb, 0x7c, 0x9d, 0xf1, 0xc2, 0x9a, 0xcb, 0x59,
3673fb2969a3SJohan Hedberg 			0x2a, 0xe7, 0xd4, 0xee, 0xfb, 0xfc, 0x0a, 0x90,
3674fb2969a3SJohan Hedberg 			0x9a, 0xbb, 0xf6, 0x32, 0x3d, 0x8b, 0x18, 0x55 };
3675fb2969a3SJohan Hedberg 	const u8 x[16] = {
3676fb2969a3SJohan Hedberg 			0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff,
3677fb2969a3SJohan Hedberg 			0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 };
3678fb2969a3SJohan Hedberg 	const u8 y[16] = {
3679fb2969a3SJohan Hedberg 			0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21,
3680fb2969a3SJohan Hedberg 			0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6 };
3681fb2969a3SJohan Hedberg 	const u32 exp_val = 0x2f9ed5ba % 1000000;
3682fb2969a3SJohan Hedberg 	u32 val;
3683fb2969a3SJohan Hedberg 	int err;
3684fb2969a3SJohan Hedberg 
3685fb2969a3SJohan Hedberg 	err = smp_g2(tfm_cmac, u, v, x, y, &val);
3686fb2969a3SJohan Hedberg 	if (err)
3687fb2969a3SJohan Hedberg 		return err;
3688fb2969a3SJohan Hedberg 
3689fb2969a3SJohan Hedberg 	if (val != exp_val)
3690fb2969a3SJohan Hedberg 		return -EINVAL;
3691fb2969a3SJohan Hedberg 
3692fb2969a3SJohan Hedberg 	return 0;
3693fb2969a3SJohan Hedberg }
3694fb2969a3SJohan Hedberg 
369571af2f6bSHerbert Xu static int __init test_h6(struct crypto_shash *tfm_cmac)
3696fb2969a3SJohan Hedberg {
3697fb2969a3SJohan Hedberg 	const u8 w[16] = {
3698fb2969a3SJohan Hedberg 			0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34,
3699fb2969a3SJohan Hedberg 			0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec };
3700fb2969a3SJohan Hedberg 	const u8 key_id[4] = { 0x72, 0x62, 0x65, 0x6c };
3701fb2969a3SJohan Hedberg 	const u8 exp[16] = {
3702fb2969a3SJohan Hedberg 			0x99, 0x63, 0xb1, 0x80, 0xe2, 0xa9, 0xd3, 0xe8,
3703fb2969a3SJohan Hedberg 			0x1c, 0xc9, 0x6d, 0xe7, 0x02, 0xe1, 0x9a, 0x2d };
3704fb2969a3SJohan Hedberg 	u8 res[16];
3705fb2969a3SJohan Hedberg 	int err;
3706fb2969a3SJohan Hedberg 
3707fb2969a3SJohan Hedberg 	err = smp_h6(tfm_cmac, w, key_id, res);
3708fb2969a3SJohan Hedberg 	if (err)
3709fb2969a3SJohan Hedberg 		return err;
3710fb2969a3SJohan Hedberg 
3711329d8230SJason A. Donenfeld 	if (crypto_memneq(res, exp, 16))
3712fb2969a3SJohan Hedberg 		return -EINVAL;
3713fb2969a3SJohan Hedberg 
3714fb2969a3SJohan Hedberg 	return 0;
3715fb2969a3SJohan Hedberg }
3716fb2969a3SJohan Hedberg 
371764dd374eSMarcel Holtmann static char test_smp_buffer[32];
371864dd374eSMarcel Holtmann 
371964dd374eSMarcel Holtmann static ssize_t test_smp_read(struct file *file, char __user *user_buf,
372064dd374eSMarcel Holtmann 			     size_t count, loff_t *ppos)
372164dd374eSMarcel Holtmann {
372264dd374eSMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, test_smp_buffer,
372364dd374eSMarcel Holtmann 				       strlen(test_smp_buffer));
372464dd374eSMarcel Holtmann }
372564dd374eSMarcel Holtmann 
372664dd374eSMarcel Holtmann static const struct file_operations test_smp_fops = {
372764dd374eSMarcel Holtmann 	.open		= simple_open,
372864dd374eSMarcel Holtmann 	.read		= test_smp_read,
372964dd374eSMarcel Holtmann 	.llseek		= default_llseek,
373064dd374eSMarcel Holtmann };
373164dd374eSMarcel Holtmann 
373228a220aaSArd Biesheuvel static int __init run_selftests(struct crypto_shash *tfm_cmac,
373347eb2ac8STudor Ambarus 				struct crypto_kpp *tfm_ecdh)
37340a2b0f04SJohan Hedberg {
3735255047b0SMarcel Holtmann 	ktime_t calltime, delta, rettime;
3736255047b0SMarcel Holtmann 	unsigned long long duration;
3737cfc4198eSJohan Hedberg 	int err;
3738cfc4198eSJohan Hedberg 
3739255047b0SMarcel Holtmann 	calltime = ktime_get();
3740255047b0SMarcel Holtmann 
374147eb2ac8STudor Ambarus 	err = test_debug_key(tfm_ecdh);
374271653eb6SMarcel Holtmann 	if (err) {
374371653eb6SMarcel Holtmann 		BT_ERR("debug_key test failed");
374471653eb6SMarcel Holtmann 		goto done;
374571653eb6SMarcel Holtmann 	}
374671653eb6SMarcel Holtmann 
374728a220aaSArd Biesheuvel 	err = test_ah();
3748cfc4198eSJohan Hedberg 	if (err) {
3749cfc4198eSJohan Hedberg 		BT_ERR("smp_ah test failed");
375064dd374eSMarcel Holtmann 		goto done;
3751cfc4198eSJohan Hedberg 	}
3752cfc4198eSJohan Hedberg 
375328a220aaSArd Biesheuvel 	err = test_c1();
3754cfc4198eSJohan Hedberg 	if (err) {
3755cfc4198eSJohan Hedberg 		BT_ERR("smp_c1 test failed");
375664dd374eSMarcel Holtmann 		goto done;
3757cfc4198eSJohan Hedberg 	}
3758cfc4198eSJohan Hedberg 
375928a220aaSArd Biesheuvel 	err = test_s1();
3760cfc4198eSJohan Hedberg 	if (err) {
3761cfc4198eSJohan Hedberg 		BT_ERR("smp_s1 test failed");
376264dd374eSMarcel Holtmann 		goto done;
3763cfc4198eSJohan Hedberg 	}
3764cfc4198eSJohan Hedberg 
3765fb2969a3SJohan Hedberg 	err = test_f4(tfm_cmac);
3766fb2969a3SJohan Hedberg 	if (err) {
3767fb2969a3SJohan Hedberg 		BT_ERR("smp_f4 test failed");
376864dd374eSMarcel Holtmann 		goto done;
3769fb2969a3SJohan Hedberg 	}
3770fb2969a3SJohan Hedberg 
3771fb2969a3SJohan Hedberg 	err = test_f5(tfm_cmac);
3772fb2969a3SJohan Hedberg 	if (err) {
3773fb2969a3SJohan Hedberg 		BT_ERR("smp_f5 test failed");
377464dd374eSMarcel Holtmann 		goto done;
3775fb2969a3SJohan Hedberg 	}
3776fb2969a3SJohan Hedberg 
3777fb2969a3SJohan Hedberg 	err = test_f6(tfm_cmac);
3778fb2969a3SJohan Hedberg 	if (err) {
3779fb2969a3SJohan Hedberg 		BT_ERR("smp_f6 test failed");
378064dd374eSMarcel Holtmann 		goto done;
3781fb2969a3SJohan Hedberg 	}
3782fb2969a3SJohan Hedberg 
3783fb2969a3SJohan Hedberg 	err = test_g2(tfm_cmac);
3784fb2969a3SJohan Hedberg 	if (err) {
3785fb2969a3SJohan Hedberg 		BT_ERR("smp_g2 test failed");
378664dd374eSMarcel Holtmann 		goto done;
3787fb2969a3SJohan Hedberg 	}
3788fb2969a3SJohan Hedberg 
3789fb2969a3SJohan Hedberg 	err = test_h6(tfm_cmac);
3790fb2969a3SJohan Hedberg 	if (err) {
3791fb2969a3SJohan Hedberg 		BT_ERR("smp_h6 test failed");
379264dd374eSMarcel Holtmann 		goto done;
3793fb2969a3SJohan Hedberg 	}
3794fb2969a3SJohan Hedberg 
3795255047b0SMarcel Holtmann 	rettime = ktime_get();
3796255047b0SMarcel Holtmann 	delta = ktime_sub(rettime, calltime);
3797255047b0SMarcel Holtmann 	duration = (unsigned long long) ktime_to_ns(delta) >> 10;
3798255047b0SMarcel Holtmann 
37995ced2464SMarcel Holtmann 	BT_INFO("SMP test passed in %llu usecs", duration);
38000a2b0f04SJohan Hedberg 
380164dd374eSMarcel Holtmann done:
380264dd374eSMarcel Holtmann 	if (!err)
380364dd374eSMarcel Holtmann 		snprintf(test_smp_buffer, sizeof(test_smp_buffer),
380464dd374eSMarcel Holtmann 			 "PASS (%llu usecs)\n", duration);
380564dd374eSMarcel Holtmann 	else
380664dd374eSMarcel Holtmann 		snprintf(test_smp_buffer, sizeof(test_smp_buffer), "FAIL\n");
380764dd374eSMarcel Holtmann 
380864dd374eSMarcel Holtmann 	debugfs_create_file("selftest_smp", 0444, bt_debugfs, NULL,
380964dd374eSMarcel Holtmann 			    &test_smp_fops);
381064dd374eSMarcel Holtmann 
381164dd374eSMarcel Holtmann 	return err;
38120a2b0f04SJohan Hedberg }
38130a2b0f04SJohan Hedberg 
38140a2b0f04SJohan Hedberg int __init bt_selftest_smp(void)
38150a2b0f04SJohan Hedberg {
381671af2f6bSHerbert Xu 	struct crypto_shash *tfm_cmac;
381747eb2ac8STudor Ambarus 	struct crypto_kpp *tfm_ecdh;
38180a2b0f04SJohan Hedberg 	int err;
38190a2b0f04SJohan Hedberg 
38203d234b33SEric Biggers 	tfm_cmac = crypto_alloc_shash("cmac(aes)", 0, 0);
38210a2b0f04SJohan Hedberg 	if (IS_ERR(tfm_cmac)) {
38220a2b0f04SJohan Hedberg 		BT_ERR("Unable to create CMAC crypto context");
38230a2b0f04SJohan Hedberg 		return PTR_ERR(tfm_cmac);
38240a2b0f04SJohan Hedberg 	}
38250a2b0f04SJohan Hedberg 
38266763f5eaSMeng Yu 	tfm_ecdh = crypto_alloc_kpp("ecdh-nist-p256", 0, 0);
382747eb2ac8STudor Ambarus 	if (IS_ERR(tfm_ecdh)) {
382847eb2ac8STudor Ambarus 		BT_ERR("Unable to create ECDH crypto context");
382947eb2ac8STudor Ambarus 		crypto_free_shash(tfm_cmac);
383047eb2ac8STudor Ambarus 		return PTR_ERR(tfm_ecdh);
383147eb2ac8STudor Ambarus 	}
383247eb2ac8STudor Ambarus 
383328a220aaSArd Biesheuvel 	err = run_selftests(tfm_cmac, tfm_ecdh);
38340a2b0f04SJohan Hedberg 
383571af2f6bSHerbert Xu 	crypto_free_shash(tfm_cmac);
383647eb2ac8STudor Ambarus 	crypto_free_kpp(tfm_ecdh);
38370a2b0f04SJohan Hedberg 
38380a2b0f04SJohan Hedberg 	return err;
38390a2b0f04SJohan Hedberg }
38400a2b0f04SJohan Hedberg 
38410a2b0f04SJohan Hedberg #endif
3842