xref: /openbmc/linux/net/bluetooth/smp.c (revision b8b23001)
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 
61*b8b23001SLuiz Augusto von Dentz #define ID_ADDR_TIMEOUT	msecs_to_jiffies(200)
62*b8b23001SLuiz Augusto von Dentz 
63d7a5a11dSMarcel Holtmann #define AUTH_REQ_MASK(dev)	(hci_dev_test_flag(dev, HCI_SC_ENABLED) ? \
64a62da6f1SJohan Hedberg 				 0x3f : 0x07)
6588d3a8acSJohan Hedberg #define KEY_DIST_MASK		0x07
66065a13e2SJohan Hedberg 
67cbbbe3e2SJohan Hedberg /* Maximum message length that can be passed to aes_cmac */
68cbbbe3e2SJohan Hedberg #define CMAC_MSG_MAX	80
69cbbbe3e2SJohan Hedberg 
70533e35d4SJohan Hedberg enum {
71533e35d4SJohan Hedberg 	SMP_FLAG_TK_VALID,
72533e35d4SJohan Hedberg 	SMP_FLAG_CFM_PENDING,
73533e35d4SJohan Hedberg 	SMP_FLAG_MITM_AUTH,
74533e35d4SJohan Hedberg 	SMP_FLAG_COMPLETE,
75533e35d4SJohan Hedberg 	SMP_FLAG_INITIATOR,
7665668776SJohan Hedberg 	SMP_FLAG_SC,
77d8f8edbeSJohan Hedberg 	SMP_FLAG_REMOTE_PK,
78aeb7d461SJohan Hedberg 	SMP_FLAG_DEBUG_KEY,
7938606f14SJohan Hedberg 	SMP_FLAG_WAIT_USER,
80d3e54a87SJohan Hedberg 	SMP_FLAG_DHKEY_PENDING,
811a8bab4fSJohan Hedberg 	SMP_FLAG_REMOTE_OOB,
821a8bab4fSJohan Hedberg 	SMP_FLAG_LOCAL_OOB,
83a62da6f1SJohan Hedberg 	SMP_FLAG_CT2,
84533e35d4SJohan Hedberg };
854bc58f51SJohan Hedberg 
8688a479d9SMarcel Holtmann struct smp_dev {
8760a27d65SMarcel Holtmann 	/* Secure Connections OOB data */
8894f14e47SJohan Hedberg 	bool			local_oob;
8960a27d65SMarcel Holtmann 	u8			local_pk[64];
90fb334feeSMarcel Holtmann 	u8			local_rand[16];
9160a27d65SMarcel Holtmann 	bool			debug_key;
9260a27d65SMarcel Holtmann 
9371af2f6bSHerbert Xu 	struct crypto_shash	*tfm_cmac;
9447eb2ac8STudor Ambarus 	struct crypto_kpp	*tfm_ecdh;
9588a479d9SMarcel Holtmann };
9688a479d9SMarcel Holtmann 
974bc58f51SJohan Hedberg struct smp_chan {
984bc58f51SJohan Hedberg 	struct l2cap_conn	*conn;
99b68fda68SJohan Hedberg 	struct delayed_work	security_timer;
100b28b4943SJohan Hedberg 	unsigned long           allow_cmd; /* Bitmask of allowed commands */
101b68fda68SJohan Hedberg 
1024bc58f51SJohan Hedberg 	u8		preq[7]; /* SMP Pairing Request */
1034bc58f51SJohan Hedberg 	u8		prsp[7]; /* SMP Pairing Response */
1044bc58f51SJohan Hedberg 	u8		prnd[16]; /* SMP Pairing Random (local) */
1054bc58f51SJohan Hedberg 	u8		rrnd[16]; /* SMP Pairing Random (remote) */
1064bc58f51SJohan Hedberg 	u8		pcnf[16]; /* SMP Pairing Confirm */
1074bc58f51SJohan Hedberg 	u8		tk[16]; /* SMP Temporary Key */
108882fafadSJohan Hedberg 	u8		rr[16]; /* Remote OOB ra/rb value */
109882fafadSJohan Hedberg 	u8		lr[16]; /* Local OOB ra/rb value */
1104bc58f51SJohan Hedberg 	u8		enc_key_size;
1114bc58f51SJohan Hedberg 	u8		remote_key_dist;
1124bc58f51SJohan Hedberg 	bdaddr_t	id_addr;
1134bc58f51SJohan Hedberg 	u8		id_addr_type;
1144bc58f51SJohan Hedberg 	u8		irk[16];
1154bc58f51SJohan Hedberg 	struct smp_csrk	*csrk;
116fad646e1SArchie Pusaka 	struct smp_csrk	*responder_csrk;
1174bc58f51SJohan Hedberg 	struct smp_ltk	*ltk;
118fad646e1SArchie Pusaka 	struct smp_ltk	*responder_ltk;
1194bc58f51SJohan Hedberg 	struct smp_irk	*remote_irk;
1206a77083aSJohan Hedberg 	u8		*link_key;
1214a74d658SJohan Hedberg 	unsigned long	flags;
122783e0574SJohan Hedberg 	u8		method;
12338606f14SJohan Hedberg 	u8		passkey_round;
1246a7bd103SJohan Hedberg 
1253b19146dSJohan Hedberg 	/* Secure Connections variables */
1263b19146dSJohan Hedberg 	u8			local_pk[64];
127d8f8edbeSJohan Hedberg 	u8			remote_pk[64];
128d8f8edbeSJohan Hedberg 	u8			dhkey[32];
129760b018bSJohan Hedberg 	u8			mackey[16];
1303b19146dSJohan Hedberg 
13171af2f6bSHerbert Xu 	struct crypto_shash	*tfm_cmac;
13247eb2ac8STudor Ambarus 	struct crypto_kpp	*tfm_ecdh;
1334bc58f51SJohan Hedberg };
1344bc58f51SJohan Hedberg 
135aeb7d461SJohan Hedberg /* These debug key values are defined in the SMP section of the core
136aeb7d461SJohan Hedberg  * specification. debug_pk is the public debug key and debug_sk the
137aeb7d461SJohan Hedberg  * private debug key.
138aeb7d461SJohan Hedberg  */
139aeb7d461SJohan Hedberg static const u8 debug_pk[64] = {
140aeb7d461SJohan Hedberg 		0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc,
141aeb7d461SJohan Hedberg 		0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef,
142aeb7d461SJohan Hedberg 		0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e,
143aeb7d461SJohan Hedberg 		0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20,
144aeb7d461SJohan Hedberg 
145aeb7d461SJohan Hedberg 		0x8b, 0xd2, 0x89, 0x15, 0xd0, 0x8e, 0x1c, 0x74,
146aeb7d461SJohan Hedberg 		0x24, 0x30, 0xed, 0x8f, 0xc2, 0x45, 0x63, 0x76,
147aeb7d461SJohan Hedberg 		0x5c, 0x15, 0x52, 0x5a, 0xbf, 0x9a, 0x32, 0x63,
148aeb7d461SJohan Hedberg 		0x6d, 0xeb, 0x2a, 0x65, 0x49, 0x9c, 0x80, 0xdc,
149aeb7d461SJohan Hedberg };
150aeb7d461SJohan Hedberg 
151aeb7d461SJohan Hedberg static const u8 debug_sk[32] = {
152aeb7d461SJohan Hedberg 		0xbd, 0x1a, 0x3c, 0xcd, 0xa6, 0xb8, 0x99, 0x58,
153aeb7d461SJohan Hedberg 		0x99, 0xb7, 0x40, 0xeb, 0x7b, 0x60, 0xff, 0x4a,
154aeb7d461SJohan Hedberg 		0x50, 0x3f, 0x10, 0xd2, 0xe3, 0xb3, 0xc9, 0x74,
155aeb7d461SJohan Hedberg 		0x38, 0x5f, 0xc5, 0xa3, 0xd4, 0xf6, 0x49, 0x3f,
156aeb7d461SJohan Hedberg };
157aeb7d461SJohan Hedberg 
1588a2936f4SJohan Hedberg static inline void swap_buf(const u8 *src, u8 *dst, size_t len)
159d22ef0bcSAnderson Briglia {
1608a2936f4SJohan Hedberg 	size_t i;
161d22ef0bcSAnderson Briglia 
1628a2936f4SJohan Hedberg 	for (i = 0; i < len; i++)
1638a2936f4SJohan Hedberg 		dst[len - 1 - i] = src[i];
164d22ef0bcSAnderson Briglia }
165d22ef0bcSAnderson Briglia 
16606edf8deSJohan Hedberg /* The following functions map to the LE SC SMP crypto functions
16706edf8deSJohan Hedberg  * AES-CMAC, f4, f5, f6, g2 and h6.
16806edf8deSJohan Hedberg  */
16906edf8deSJohan Hedberg 
17071af2f6bSHerbert Xu static int aes_cmac(struct crypto_shash *tfm, const u8 k[16], const u8 *m,
171cbbbe3e2SJohan Hedberg 		    size_t len, u8 mac[16])
172cbbbe3e2SJohan Hedberg {
173cbbbe3e2SJohan Hedberg 	uint8_t tmp[16], mac_msb[16], msg_msb[CMAC_MSG_MAX];
174cbbbe3e2SJohan Hedberg 	int err;
175cbbbe3e2SJohan Hedberg 
176cbbbe3e2SJohan Hedberg 	if (len > CMAC_MSG_MAX)
177cbbbe3e2SJohan Hedberg 		return -EFBIG;
178cbbbe3e2SJohan Hedberg 
179cbbbe3e2SJohan Hedberg 	if (!tfm) {
180cbbbe3e2SJohan Hedberg 		BT_ERR("tfm %p", tfm);
181cbbbe3e2SJohan Hedberg 		return -EINVAL;
182cbbbe3e2SJohan Hedberg 	}
183cbbbe3e2SJohan Hedberg 
184cbbbe3e2SJohan Hedberg 	/* Swap key and message from LSB to MSB */
185cbbbe3e2SJohan Hedberg 	swap_buf(k, tmp, 16);
186cbbbe3e2SJohan Hedberg 	swap_buf(m, msg_msb, len);
187cbbbe3e2SJohan Hedberg 
188c7a3d57dSJohan Hedberg 	SMP_DBG("msg (len %zu) %*phN", len, (int) len, m);
189c7a3d57dSJohan Hedberg 	SMP_DBG("key %16phN", k);
190cbbbe3e2SJohan Hedberg 
19171af2f6bSHerbert Xu 	err = crypto_shash_setkey(tfm, tmp, 16);
192cbbbe3e2SJohan Hedberg 	if (err) {
193cbbbe3e2SJohan Hedberg 		BT_ERR("cipher setkey failed: %d", err);
194cbbbe3e2SJohan Hedberg 		return err;
195cbbbe3e2SJohan Hedberg 	}
196cbbbe3e2SJohan Hedberg 
197ec0bf6edSEric Biggers 	err = crypto_shash_tfm_digest(tfm, msg_msb, len, mac_msb);
198cbbbe3e2SJohan Hedberg 	if (err) {
19971af2f6bSHerbert Xu 		BT_ERR("Hash computation error %d", err);
200cbbbe3e2SJohan Hedberg 		return err;
201cbbbe3e2SJohan Hedberg 	}
202cbbbe3e2SJohan Hedberg 
203cbbbe3e2SJohan Hedberg 	swap_buf(mac_msb, mac, 16);
204cbbbe3e2SJohan Hedberg 
205c7a3d57dSJohan Hedberg 	SMP_DBG("mac %16phN", mac);
206cbbbe3e2SJohan Hedberg 
207cbbbe3e2SJohan Hedberg 	return 0;
208cbbbe3e2SJohan Hedberg }
209cbbbe3e2SJohan Hedberg 
21071af2f6bSHerbert Xu static int smp_f4(struct crypto_shash *tfm_cmac, const u8 u[32],
21171af2f6bSHerbert Xu 		  const u8 v[32], const u8 x[16], u8 z, u8 res[16])
212cbbbe3e2SJohan Hedberg {
213cbbbe3e2SJohan Hedberg 	u8 m[65];
214cbbbe3e2SJohan Hedberg 	int err;
215cbbbe3e2SJohan Hedberg 
216c7a3d57dSJohan Hedberg 	SMP_DBG("u %32phN", u);
217c7a3d57dSJohan Hedberg 	SMP_DBG("v %32phN", v);
218c7a3d57dSJohan Hedberg 	SMP_DBG("x %16phN z %02x", x, z);
219cbbbe3e2SJohan Hedberg 
220cbbbe3e2SJohan Hedberg 	m[0] = z;
221cbbbe3e2SJohan Hedberg 	memcpy(m + 1, v, 32);
222cbbbe3e2SJohan Hedberg 	memcpy(m + 33, u, 32);
223cbbbe3e2SJohan Hedberg 
224cbbbe3e2SJohan Hedberg 	err = aes_cmac(tfm_cmac, x, m, sizeof(m), res);
225cbbbe3e2SJohan Hedberg 	if (err)
226cbbbe3e2SJohan Hedberg 		return err;
227cbbbe3e2SJohan Hedberg 
228c7a3d57dSJohan Hedberg 	SMP_DBG("res %16phN", res);
229cbbbe3e2SJohan Hedberg 
230cbbbe3e2SJohan Hedberg 	return err;
231cbbbe3e2SJohan Hedberg }
232cbbbe3e2SJohan Hedberg 
23371af2f6bSHerbert Xu static int smp_f5(struct crypto_shash *tfm_cmac, const u8 w[32],
2344da50de8SJohan Hedberg 		  const u8 n1[16], const u8 n2[16], const u8 a1[7],
2354da50de8SJohan Hedberg 		  const u8 a2[7], u8 mackey[16], u8 ltk[16])
236760b018bSJohan Hedberg {
237760b018bSJohan Hedberg 	/* The btle, salt and length "magic" values are as defined in
238760b018bSJohan Hedberg 	 * the SMP section of the Bluetooth core specification. In ASCII
239760b018bSJohan Hedberg 	 * the btle value ends up being 'btle'. The salt is just a
240760b018bSJohan Hedberg 	 * random number whereas length is the value 256 in little
241760b018bSJohan Hedberg 	 * endian format.
242760b018bSJohan Hedberg 	 */
243760b018bSJohan Hedberg 	const u8 btle[4] = { 0x65, 0x6c, 0x74, 0x62 };
244760b018bSJohan Hedberg 	const u8 salt[16] = { 0xbe, 0x83, 0x60, 0x5a, 0xdb, 0x0b, 0x37, 0x60,
245760b018bSJohan Hedberg 			      0x38, 0xa5, 0xf5, 0xaa, 0x91, 0x83, 0x88, 0x6c };
246760b018bSJohan Hedberg 	const u8 length[2] = { 0x00, 0x01 };
247760b018bSJohan Hedberg 	u8 m[53], t[16];
248760b018bSJohan Hedberg 	int err;
249760b018bSJohan Hedberg 
250c7a3d57dSJohan Hedberg 	SMP_DBG("w %32phN", w);
251c7a3d57dSJohan Hedberg 	SMP_DBG("n1 %16phN n2 %16phN", n1, n2);
252c7a3d57dSJohan Hedberg 	SMP_DBG("a1 %7phN a2 %7phN", a1, a2);
253760b018bSJohan Hedberg 
254760b018bSJohan Hedberg 	err = aes_cmac(tfm_cmac, salt, w, 32, t);
255760b018bSJohan Hedberg 	if (err)
256760b018bSJohan Hedberg 		return err;
257760b018bSJohan Hedberg 
258c7a3d57dSJohan Hedberg 	SMP_DBG("t %16phN", t);
259760b018bSJohan Hedberg 
260760b018bSJohan Hedberg 	memcpy(m, length, 2);
261760b018bSJohan Hedberg 	memcpy(m + 2, a2, 7);
262760b018bSJohan Hedberg 	memcpy(m + 9, a1, 7);
263760b018bSJohan Hedberg 	memcpy(m + 16, n2, 16);
264760b018bSJohan Hedberg 	memcpy(m + 32, n1, 16);
265760b018bSJohan Hedberg 	memcpy(m + 48, btle, 4);
266760b018bSJohan Hedberg 
267760b018bSJohan Hedberg 	m[52] = 0; /* Counter */
268760b018bSJohan Hedberg 
269760b018bSJohan Hedberg 	err = aes_cmac(tfm_cmac, t, m, sizeof(m), mackey);
270760b018bSJohan Hedberg 	if (err)
271760b018bSJohan Hedberg 		return err;
272760b018bSJohan Hedberg 
273c7a3d57dSJohan Hedberg 	SMP_DBG("mackey %16phN", mackey);
274760b018bSJohan Hedberg 
275760b018bSJohan Hedberg 	m[52] = 1; /* Counter */
276760b018bSJohan Hedberg 
277760b018bSJohan Hedberg 	err = aes_cmac(tfm_cmac, t, m, sizeof(m), ltk);
278760b018bSJohan Hedberg 	if (err)
279760b018bSJohan Hedberg 		return err;
280760b018bSJohan Hedberg 
281c7a3d57dSJohan Hedberg 	SMP_DBG("ltk %16phN", ltk);
282760b018bSJohan Hedberg 
283760b018bSJohan Hedberg 	return 0;
284760b018bSJohan Hedberg }
285760b018bSJohan Hedberg 
28671af2f6bSHerbert Xu static int smp_f6(struct crypto_shash *tfm_cmac, const u8 w[16],
2874da50de8SJohan Hedberg 		  const u8 n1[16], const u8 n2[16], const u8 r[16],
288760b018bSJohan Hedberg 		  const u8 io_cap[3], const u8 a1[7], const u8 a2[7],
289760b018bSJohan Hedberg 		  u8 res[16])
290760b018bSJohan Hedberg {
291760b018bSJohan Hedberg 	u8 m[65];
292760b018bSJohan Hedberg 	int err;
293760b018bSJohan Hedberg 
294c7a3d57dSJohan Hedberg 	SMP_DBG("w %16phN", w);
295c7a3d57dSJohan Hedberg 	SMP_DBG("n1 %16phN n2 %16phN", n1, n2);
296c7a3d57dSJohan Hedberg 	SMP_DBG("r %16phN io_cap %3phN a1 %7phN a2 %7phN", r, io_cap, a1, a2);
297760b018bSJohan Hedberg 
298760b018bSJohan Hedberg 	memcpy(m, a2, 7);
299760b018bSJohan Hedberg 	memcpy(m + 7, a1, 7);
300760b018bSJohan Hedberg 	memcpy(m + 14, io_cap, 3);
301760b018bSJohan Hedberg 	memcpy(m + 17, r, 16);
302760b018bSJohan Hedberg 	memcpy(m + 33, n2, 16);
303760b018bSJohan Hedberg 	memcpy(m + 49, n1, 16);
304760b018bSJohan Hedberg 
305760b018bSJohan Hedberg 	err = aes_cmac(tfm_cmac, w, m, sizeof(m), res);
306760b018bSJohan Hedberg 	if (err)
307760b018bSJohan Hedberg 		return err;
308760b018bSJohan Hedberg 
309203de21bSMarcel Holtmann 	SMP_DBG("res %16phN", res);
310760b018bSJohan Hedberg 
311760b018bSJohan Hedberg 	return err;
312760b018bSJohan Hedberg }
313760b018bSJohan Hedberg 
31471af2f6bSHerbert Xu static int smp_g2(struct crypto_shash *tfm_cmac, const u8 u[32], const u8 v[32],
315191dc7feSJohan Hedberg 		  const u8 x[16], const u8 y[16], u32 *val)
316191dc7feSJohan Hedberg {
317191dc7feSJohan Hedberg 	u8 m[80], tmp[16];
318191dc7feSJohan Hedberg 	int err;
319191dc7feSJohan Hedberg 
320c7a3d57dSJohan Hedberg 	SMP_DBG("u %32phN", u);
321c7a3d57dSJohan Hedberg 	SMP_DBG("v %32phN", v);
322c7a3d57dSJohan Hedberg 	SMP_DBG("x %16phN y %16phN", x, y);
323191dc7feSJohan Hedberg 
324191dc7feSJohan Hedberg 	memcpy(m, y, 16);
325191dc7feSJohan Hedberg 	memcpy(m + 16, v, 32);
326191dc7feSJohan Hedberg 	memcpy(m + 48, u, 32);
327191dc7feSJohan Hedberg 
328191dc7feSJohan Hedberg 	err = aes_cmac(tfm_cmac, x, m, sizeof(m), tmp);
329191dc7feSJohan Hedberg 	if (err)
330191dc7feSJohan Hedberg 		return err;
331191dc7feSJohan Hedberg 
332191dc7feSJohan Hedberg 	*val = get_unaligned_le32(tmp);
333191dc7feSJohan Hedberg 	*val %= 1000000;
334191dc7feSJohan Hedberg 
335c7a3d57dSJohan Hedberg 	SMP_DBG("val %06u", *val);
336191dc7feSJohan Hedberg 
337191dc7feSJohan Hedberg 	return 0;
338191dc7feSJohan Hedberg }
339191dc7feSJohan Hedberg 
34071af2f6bSHerbert Xu static int smp_h6(struct crypto_shash *tfm_cmac, const u8 w[16],
34106edf8deSJohan Hedberg 		  const u8 key_id[4], u8 res[16])
34206edf8deSJohan Hedberg {
34306edf8deSJohan Hedberg 	int err;
34406edf8deSJohan Hedberg 
34506edf8deSJohan Hedberg 	SMP_DBG("w %16phN key_id %4phN", w, key_id);
34606edf8deSJohan Hedberg 
34706edf8deSJohan Hedberg 	err = aes_cmac(tfm_cmac, w, key_id, 4, res);
34806edf8deSJohan Hedberg 	if (err)
34906edf8deSJohan Hedberg 		return err;
35006edf8deSJohan Hedberg 
35106edf8deSJohan Hedberg 	SMP_DBG("res %16phN", res);
35206edf8deSJohan Hedberg 
35306edf8deSJohan Hedberg 	return err;
35406edf8deSJohan Hedberg }
35506edf8deSJohan Hedberg 
356a62da6f1SJohan Hedberg static int smp_h7(struct crypto_shash *tfm_cmac, const u8 w[16],
357a62da6f1SJohan Hedberg 		  const u8 salt[16], u8 res[16])
358a62da6f1SJohan Hedberg {
359a62da6f1SJohan Hedberg 	int err;
360a62da6f1SJohan Hedberg 
361a62da6f1SJohan Hedberg 	SMP_DBG("w %16phN salt %16phN", w, salt);
362a62da6f1SJohan Hedberg 
363a62da6f1SJohan Hedberg 	err = aes_cmac(tfm_cmac, salt, w, 16, res);
364a62da6f1SJohan Hedberg 	if (err)
365a62da6f1SJohan Hedberg 		return err;
366a62da6f1SJohan Hedberg 
367a62da6f1SJohan Hedberg 	SMP_DBG("res %16phN", res);
368a62da6f1SJohan Hedberg 
369a62da6f1SJohan Hedberg 	return err;
370a62da6f1SJohan Hedberg }
371a62da6f1SJohan Hedberg 
37206edf8deSJohan Hedberg /* The following functions map to the legacy SMP crypto functions e, c1,
37306edf8deSJohan Hedberg  * s1 and ah.
37406edf8deSJohan Hedberg  */
37506edf8deSJohan Hedberg 
37628a220aaSArd Biesheuvel static int smp_e(const u8 *k, u8 *r)
377d22ef0bcSAnderson Briglia {
37828a220aaSArd Biesheuvel 	struct crypto_aes_ctx ctx;
379943a732aSJohan Hedberg 	uint8_t tmp[16], data[16];
380201a5929SJohan Hedberg 	int err;
381d22ef0bcSAnderson Briglia 
382011c391aSJohan Hedberg 	SMP_DBG("k %16phN r %16phN", k, r);
383011c391aSJohan Hedberg 
384943a732aSJohan Hedberg 	/* The most significant octet of key corresponds to k[0] */
3858a2936f4SJohan Hedberg 	swap_buf(k, tmp, 16);
386943a732aSJohan Hedberg 
38728a220aaSArd Biesheuvel 	err = aes_expandkey(&ctx, tmp, 16);
388d22ef0bcSAnderson Briglia 	if (err) {
389d22ef0bcSAnderson Briglia 		BT_ERR("cipher setkey failed: %d", err);
390d22ef0bcSAnderson Briglia 		return err;
391d22ef0bcSAnderson Briglia 	}
392d22ef0bcSAnderson Briglia 
393943a732aSJohan Hedberg 	/* Most significant octet of plaintextData corresponds to data[0] */
3948a2936f4SJohan Hedberg 	swap_buf(r, data, 16);
395943a732aSJohan Hedberg 
39628a220aaSArd Biesheuvel 	aes_encrypt(&ctx, data, data);
397d22ef0bcSAnderson Briglia 
398943a732aSJohan Hedberg 	/* Most significant octet of encryptedData corresponds to data[0] */
3998a2936f4SJohan Hedberg 	swap_buf(data, r, 16);
400943a732aSJohan Hedberg 
401011c391aSJohan Hedberg 	SMP_DBG("r %16phN", r);
402011c391aSJohan Hedberg 
40328a220aaSArd Biesheuvel 	memzero_explicit(&ctx, sizeof(ctx));
404d22ef0bcSAnderson Briglia 	return err;
405d22ef0bcSAnderson Briglia }
406d22ef0bcSAnderson Briglia 
40728a220aaSArd Biesheuvel static int smp_c1(const u8 k[16],
40806edf8deSJohan Hedberg 		  const u8 r[16], const u8 preq[7], const u8 pres[7], u8 _iat,
40906edf8deSJohan Hedberg 		  const bdaddr_t *ia, u8 _rat, const bdaddr_t *ra, u8 res[16])
41006edf8deSJohan Hedberg {
41106edf8deSJohan Hedberg 	u8 p1[16], p2[16];
41206edf8deSJohan Hedberg 	int err;
41306edf8deSJohan Hedberg 
414011c391aSJohan Hedberg 	SMP_DBG("k %16phN r %16phN", k, r);
415011c391aSJohan Hedberg 	SMP_DBG("iat %u ia %6phN rat %u ra %6phN", _iat, ia, _rat, ra);
416011c391aSJohan Hedberg 	SMP_DBG("preq %7phN pres %7phN", preq, pres);
417011c391aSJohan Hedberg 
41806edf8deSJohan Hedberg 	memset(p1, 0, 16);
41906edf8deSJohan Hedberg 
42006edf8deSJohan Hedberg 	/* p1 = pres || preq || _rat || _iat */
42106edf8deSJohan Hedberg 	p1[0] = _iat;
42206edf8deSJohan Hedberg 	p1[1] = _rat;
42306edf8deSJohan Hedberg 	memcpy(p1 + 2, preq, 7);
42406edf8deSJohan Hedberg 	memcpy(p1 + 9, pres, 7);
42506edf8deSJohan Hedberg 
426011c391aSJohan Hedberg 	SMP_DBG("p1 %16phN", p1);
42706edf8deSJohan Hedberg 
42806edf8deSJohan Hedberg 	/* res = r XOR p1 */
429ef0bb5adSArd Biesheuvel 	crypto_xor_cpy(res, r, p1, sizeof(p1));
43006edf8deSJohan Hedberg 
43106edf8deSJohan Hedberg 	/* res = e(k, res) */
43228a220aaSArd Biesheuvel 	err = smp_e(k, res);
43306edf8deSJohan Hedberg 	if (err) {
43406edf8deSJohan Hedberg 		BT_ERR("Encrypt data error");
43506edf8deSJohan Hedberg 		return err;
43606edf8deSJohan Hedberg 	}
43706edf8deSJohan Hedberg 
438011c391aSJohan Hedberg 	/* p2 = padding || ia || ra */
439011c391aSJohan Hedberg 	memcpy(p2, ra, 6);
440011c391aSJohan Hedberg 	memcpy(p2 + 6, ia, 6);
441011c391aSJohan Hedberg 	memset(p2 + 12, 0, 4);
442011c391aSJohan Hedberg 
443011c391aSJohan Hedberg 	SMP_DBG("p2 %16phN", p2);
444011c391aSJohan Hedberg 
44506edf8deSJohan Hedberg 	/* res = res XOR p2 */
446ef0bb5adSArd Biesheuvel 	crypto_xor(res, p2, sizeof(p2));
44706edf8deSJohan Hedberg 
44806edf8deSJohan Hedberg 	/* res = e(k, res) */
44928a220aaSArd Biesheuvel 	err = smp_e(k, res);
45006edf8deSJohan Hedberg 	if (err)
45106edf8deSJohan Hedberg 		BT_ERR("Encrypt data error");
45206edf8deSJohan Hedberg 
45306edf8deSJohan Hedberg 	return err;
45406edf8deSJohan Hedberg }
45506edf8deSJohan Hedberg 
45628a220aaSArd Biesheuvel static int smp_s1(const u8 k[16],
45706edf8deSJohan Hedberg 		  const u8 r1[16], const u8 r2[16], u8 _r[16])
4586a77083aSJohan Hedberg {
4596a77083aSJohan Hedberg 	int err;
4606a77083aSJohan Hedberg 
46106edf8deSJohan Hedberg 	/* Just least significant octets from r1 and r2 are considered */
46206edf8deSJohan Hedberg 	memcpy(_r, r2, 8);
46306edf8deSJohan Hedberg 	memcpy(_r + 8, r1, 8);
4646a77083aSJohan Hedberg 
46528a220aaSArd Biesheuvel 	err = smp_e(k, _r);
4666a77083aSJohan Hedberg 	if (err)
46706edf8deSJohan Hedberg 		BT_ERR("Encrypt data error");
4686a77083aSJohan Hedberg 
4696a77083aSJohan Hedberg 	return err;
4706a77083aSJohan Hedberg }
4716a77083aSJohan Hedberg 
47228a220aaSArd Biesheuvel static int smp_ah(const u8 irk[16], const u8 r[3], u8 res[3])
47360478054SJohan Hedberg {
474943a732aSJohan Hedberg 	u8 _res[16];
47560478054SJohan Hedberg 	int err;
47660478054SJohan Hedberg 
47760478054SJohan Hedberg 	/* r' = padding || r */
478943a732aSJohan Hedberg 	memcpy(_res, r, 3);
479943a732aSJohan Hedberg 	memset(_res + 3, 0, 13);
48060478054SJohan Hedberg 
48128a220aaSArd Biesheuvel 	err = smp_e(irk, _res);
48260478054SJohan Hedberg 	if (err) {
48360478054SJohan Hedberg 		BT_ERR("Encrypt error");
48460478054SJohan Hedberg 		return err;
48560478054SJohan Hedberg 	}
48660478054SJohan Hedberg 
48760478054SJohan Hedberg 	/* The output of the random address function ah is:
488c5080d42SMarcel Holtmann 	 *	ah(k, r) = e(k, r') mod 2^24
48960478054SJohan Hedberg 	 * The output of the security function e is then truncated to 24 bits
49060478054SJohan Hedberg 	 * by taking the least significant 24 bits of the output of e as the
49160478054SJohan Hedberg 	 * result of ah.
49260478054SJohan Hedberg 	 */
493943a732aSJohan Hedberg 	memcpy(res, _res, 3);
49460478054SJohan Hedberg 
49560478054SJohan Hedberg 	return 0;
49660478054SJohan Hedberg }
49760478054SJohan Hedberg 
498cd082797SJohan Hedberg bool smp_irk_matches(struct hci_dev *hdev, const u8 irk[16],
499cd082797SJohan Hedberg 		     const bdaddr_t *bdaddr)
50060478054SJohan Hedberg {
501defce9e8SJohan Hedberg 	struct l2cap_chan *chan = hdev->smp_data;
50260478054SJohan Hedberg 	u8 hash[3];
50360478054SJohan Hedberg 	int err;
50460478054SJohan Hedberg 
505defce9e8SJohan Hedberg 	if (!chan || !chan->data)
506defce9e8SJohan Hedberg 		return false;
507defce9e8SJohan Hedberg 
50856860245SMarcel Holtmann 	bt_dev_dbg(hdev, "RPA %pMR IRK %*phN", bdaddr, 16, irk);
50960478054SJohan Hedberg 
51028a220aaSArd Biesheuvel 	err = smp_ah(irk, &bdaddr->b[3], hash);
51160478054SJohan Hedberg 	if (err)
51260478054SJohan Hedberg 		return false;
51360478054SJohan Hedberg 
514329d8230SJason A. Donenfeld 	return !crypto_memneq(bdaddr->b, hash, 3);
51560478054SJohan Hedberg }
51660478054SJohan Hedberg 
517cd082797SJohan Hedberg int smp_generate_rpa(struct hci_dev *hdev, const u8 irk[16], bdaddr_t *rpa)
518b1e2b3aeSJohan Hedberg {
519defce9e8SJohan Hedberg 	struct l2cap_chan *chan = hdev->smp_data;
520b1e2b3aeSJohan Hedberg 	int err;
521b1e2b3aeSJohan Hedberg 
522defce9e8SJohan Hedberg 	if (!chan || !chan->data)
523defce9e8SJohan Hedberg 		return -EOPNOTSUPP;
524defce9e8SJohan Hedberg 
525b1e2b3aeSJohan Hedberg 	get_random_bytes(&rpa->b[3], 3);
526b1e2b3aeSJohan Hedberg 
527b1e2b3aeSJohan Hedberg 	rpa->b[5] &= 0x3f;	/* Clear two most significant bits */
528b1e2b3aeSJohan Hedberg 	rpa->b[5] |= 0x40;	/* Set second most significant bit */
529b1e2b3aeSJohan Hedberg 
53028a220aaSArd Biesheuvel 	err = smp_ah(irk, &rpa->b[3], rpa->b);
531b1e2b3aeSJohan Hedberg 	if (err < 0)
532b1e2b3aeSJohan Hedberg 		return err;
533b1e2b3aeSJohan Hedberg 
53456860245SMarcel Holtmann 	bt_dev_dbg(hdev, "RPA %pMR", rpa);
535b1e2b3aeSJohan Hedberg 
536b1e2b3aeSJohan Hedberg 	return 0;
537b1e2b3aeSJohan Hedberg }
538b1e2b3aeSJohan Hedberg 
53960a27d65SMarcel Holtmann int smp_generate_oob(struct hci_dev *hdev, u8 hash[16], u8 rand[16])
54060a27d65SMarcel Holtmann {
54160a27d65SMarcel Holtmann 	struct l2cap_chan *chan = hdev->smp_data;
54260a27d65SMarcel Holtmann 	struct smp_dev *smp;
54360a27d65SMarcel Holtmann 	int err;
54460a27d65SMarcel Holtmann 
54560a27d65SMarcel Holtmann 	if (!chan || !chan->data)
54660a27d65SMarcel Holtmann 		return -EOPNOTSUPP;
54760a27d65SMarcel Holtmann 
54860a27d65SMarcel Holtmann 	smp = chan->data;
54960a27d65SMarcel Holtmann 
55060a27d65SMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS)) {
55156860245SMarcel Holtmann 		bt_dev_dbg(hdev, "Using debug keys");
552c0153b0bSTudor Ambarus 		err = set_ecdh_privkey(smp->tfm_ecdh, debug_sk);
553c0153b0bSTudor Ambarus 		if (err)
554c0153b0bSTudor Ambarus 			return err;
55560a27d65SMarcel Holtmann 		memcpy(smp->local_pk, debug_pk, 64);
55660a27d65SMarcel Holtmann 		smp->debug_key = true;
55760a27d65SMarcel Holtmann 	} else {
55860a27d65SMarcel Holtmann 		while (true) {
559c0153b0bSTudor Ambarus 			/* Generate key pair for Secure Connections */
560c0153b0bSTudor Ambarus 			err = generate_ecdh_keys(smp->tfm_ecdh, smp->local_pk);
561a2976416STudor Ambarus 			if (err)
562a2976416STudor Ambarus 				return err;
56360a27d65SMarcel Holtmann 
56460a27d65SMarcel Holtmann 			/* This is unlikely, but we need to check that
56591641b79SZheng Yongjun 			 * we didn't accidentally generate a debug key.
56660a27d65SMarcel Holtmann 			 */
567c0153b0bSTudor Ambarus 			if (crypto_memneq(smp->local_pk, debug_pk, 64))
56860a27d65SMarcel Holtmann 				break;
56960a27d65SMarcel Holtmann 		}
57060a27d65SMarcel Holtmann 		smp->debug_key = false;
57160a27d65SMarcel Holtmann 	}
57260a27d65SMarcel Holtmann 
57360a27d65SMarcel Holtmann 	SMP_DBG("OOB Public Key X: %32phN", smp->local_pk);
57460a27d65SMarcel Holtmann 	SMP_DBG("OOB Public Key Y: %32phN", smp->local_pk + 32);
57560a27d65SMarcel Holtmann 
576fb334feeSMarcel Holtmann 	get_random_bytes(smp->local_rand, 16);
57760a27d65SMarcel Holtmann 
57860a27d65SMarcel Holtmann 	err = smp_f4(smp->tfm_cmac, smp->local_pk, smp->local_pk,
579fb334feeSMarcel Holtmann 		     smp->local_rand, 0, hash);
58060a27d65SMarcel Holtmann 	if (err < 0)
58160a27d65SMarcel Holtmann 		return err;
58260a27d65SMarcel Holtmann 
583fb334feeSMarcel Holtmann 	memcpy(rand, smp->local_rand, 16);
58460a27d65SMarcel Holtmann 
58594f14e47SJohan Hedberg 	smp->local_oob = true;
58694f14e47SJohan Hedberg 
58760a27d65SMarcel Holtmann 	return 0;
58860a27d65SMarcel Holtmann }
58960a27d65SMarcel Holtmann 
590eb492e01SAnderson Briglia static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
591eb492e01SAnderson Briglia {
5925d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
593b68fda68SJohan Hedberg 	struct smp_chan *smp;
5945d88cc73SJohan Hedberg 	struct kvec iv[2];
5955d88cc73SJohan Hedberg 	struct msghdr msg;
5965d88cc73SJohan Hedberg 
5975d88cc73SJohan Hedberg 	if (!chan)
5985d88cc73SJohan Hedberg 		return;
599eb492e01SAnderson Briglia 
6002e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(conn->hcon->hdev, "code 0x%2.2x", code);
601eb492e01SAnderson Briglia 
6025d88cc73SJohan Hedberg 	iv[0].iov_base = &code;
6035d88cc73SJohan Hedberg 	iv[0].iov_len = 1;
604eb492e01SAnderson Briglia 
6055d88cc73SJohan Hedberg 	iv[1].iov_base = data;
6065d88cc73SJohan Hedberg 	iv[1].iov_len = len;
6075d88cc73SJohan Hedberg 
6085d88cc73SJohan Hedberg 	memset(&msg, 0, sizeof(msg));
6095d88cc73SJohan Hedberg 
610de4eda9dSAl Viro 	iov_iter_kvec(&msg.msg_iter, ITER_SOURCE, iv, 2, 1 + len);
6115d88cc73SJohan Hedberg 
6125d88cc73SJohan Hedberg 	l2cap_chan_send(chan, &msg, 1 + len);
613e2dcd113SVinicius Costa Gomes 
614b68fda68SJohan Hedberg 	if (!chan->data)
615b68fda68SJohan Hedberg 		return;
616b68fda68SJohan Hedberg 
617b68fda68SJohan Hedberg 	smp = chan->data;
618b68fda68SJohan Hedberg 
619b68fda68SJohan Hedberg 	cancel_delayed_work_sync(&smp->security_timer);
620b68fda68SJohan Hedberg 	schedule_delayed_work(&smp->security_timer, SMP_TIMEOUT);
621eb492e01SAnderson Briglia }
622eb492e01SAnderson Briglia 
623d2eb9e10SJohan Hedberg static u8 authreq_to_seclevel(u8 authreq)
6242b64d153SBrian Gix {
625d2eb9e10SJohan Hedberg 	if (authreq & SMP_AUTH_MITM) {
626d2eb9e10SJohan Hedberg 		if (authreq & SMP_AUTH_SC)
627d2eb9e10SJohan Hedberg 			return BT_SECURITY_FIPS;
6282b64d153SBrian Gix 		else
629d2eb9e10SJohan Hedberg 			return BT_SECURITY_HIGH;
630d2eb9e10SJohan Hedberg 	} else {
6312b64d153SBrian Gix 		return BT_SECURITY_MEDIUM;
6322b64d153SBrian Gix 	}
633d2eb9e10SJohan Hedberg }
6342b64d153SBrian Gix 
6352b64d153SBrian Gix static __u8 seclevel_to_authreq(__u8 sec_level)
6362b64d153SBrian Gix {
6372b64d153SBrian Gix 	switch (sec_level) {
638d2eb9e10SJohan Hedberg 	case BT_SECURITY_FIPS:
6392b64d153SBrian Gix 	case BT_SECURITY_HIGH:
6402b64d153SBrian Gix 		return SMP_AUTH_MITM | SMP_AUTH_BONDING;
6412b64d153SBrian Gix 	case BT_SECURITY_MEDIUM:
6422b64d153SBrian Gix 		return SMP_AUTH_BONDING;
6432b64d153SBrian Gix 	default:
6442b64d153SBrian Gix 		return SMP_AUTH_NONE;
6452b64d153SBrian Gix 	}
6462b64d153SBrian Gix }
6472b64d153SBrian Gix 
648b8e66eacSVinicius Costa Gomes static void build_pairing_cmd(struct l2cap_conn *conn,
64954790f73SVinicius Costa Gomes 			      struct smp_cmd_pairing *req,
650f1560463SMarcel Holtmann 			      struct smp_cmd_pairing *rsp, __u8 authreq)
651b8e66eacSVinicius Costa Gomes {
6525d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
6535d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
654fd349c02SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
655fd349c02SJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
65602b05bd8SJohan Hedberg 	u8 local_dist = 0, remote_dist = 0, oob_flag = SMP_OOB_NOT_PRESENT;
65754790f73SVinicius Costa Gomes 
658d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_BONDABLE)) {
6597ee4ea36SMarcel Holtmann 		local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
6607ee4ea36SMarcel Holtmann 		remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
66154790f73SVinicius Costa Gomes 		authreq |= SMP_AUTH_BONDING;
6622b64d153SBrian Gix 	} else {
6632b64d153SBrian Gix 		authreq &= ~SMP_AUTH_BONDING;
66454790f73SVinicius Costa Gomes 	}
66554790f73SVinicius Costa Gomes 
666d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_RPA_RESOLVING))
667fd349c02SJohan Hedberg 		remote_dist |= SMP_DIST_ID_KEY;
668fd349c02SJohan Hedberg 
669d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_PRIVACY))
670863efaf2SJohan Hedberg 		local_dist |= SMP_DIST_ID_KEY;
671863efaf2SJohan Hedberg 
672d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SC_ENABLED) &&
67302b05bd8SJohan Hedberg 	    (authreq & SMP_AUTH_SC)) {
67402b05bd8SJohan Hedberg 		struct oob_data *oob_data;
67502b05bd8SJohan Hedberg 		u8 bdaddr_type;
67602b05bd8SJohan Hedberg 
677d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_SSP_ENABLED)) {
678df8e1a4cSJohan Hedberg 			local_dist |= SMP_DIST_LINK_KEY;
679df8e1a4cSJohan Hedberg 			remote_dist |= SMP_DIST_LINK_KEY;
680df8e1a4cSJohan Hedberg 		}
68102b05bd8SJohan Hedberg 
68202b05bd8SJohan Hedberg 		if (hcon->dst_type == ADDR_LE_DEV_PUBLIC)
68302b05bd8SJohan Hedberg 			bdaddr_type = BDADDR_LE_PUBLIC;
68402b05bd8SJohan Hedberg 		else
68502b05bd8SJohan Hedberg 			bdaddr_type = BDADDR_LE_RANDOM;
68602b05bd8SJohan Hedberg 
68702b05bd8SJohan Hedberg 		oob_data = hci_find_remote_oob_data(hdev, &hcon->dst,
68802b05bd8SJohan Hedberg 						    bdaddr_type);
6894775a4eaSMarcel Holtmann 		if (oob_data && oob_data->present) {
6901a8bab4fSJohan Hedberg 			set_bit(SMP_FLAG_REMOTE_OOB, &smp->flags);
69102b05bd8SJohan Hedberg 			oob_flag = SMP_OOB_PRESENT;
692a29b0733SJohan Hedberg 			memcpy(smp->rr, oob_data->rand256, 16);
69302b05bd8SJohan Hedberg 			memcpy(smp->pcnf, oob_data->hash256, 16);
694bc07cd69SMarcel Holtmann 			SMP_DBG("OOB Remote Confirmation: %16phN", smp->pcnf);
695bc07cd69SMarcel Holtmann 			SMP_DBG("OOB Remote Random: %16phN", smp->rr);
69602b05bd8SJohan Hedberg 		}
69702b05bd8SJohan Hedberg 
698df8e1a4cSJohan Hedberg 	} else {
699df8e1a4cSJohan Hedberg 		authreq &= ~SMP_AUTH_SC;
700df8e1a4cSJohan Hedberg 	}
701df8e1a4cSJohan Hedberg 
70254790f73SVinicius Costa Gomes 	if (rsp == NULL) {
70354790f73SVinicius Costa Gomes 		req->io_capability = conn->hcon->io_capability;
70402b05bd8SJohan Hedberg 		req->oob_flag = oob_flag;
70530d65e08SMatias Karhumaa 		req->max_key_size = hdev->le_max_key_size;
706fd349c02SJohan Hedberg 		req->init_key_dist = local_dist;
707fd349c02SJohan Hedberg 		req->resp_key_dist = remote_dist;
7080edb14deSJohan Hedberg 		req->auth_req = (authreq & AUTH_REQ_MASK(hdev));
709fd349c02SJohan Hedberg 
710fd349c02SJohan Hedberg 		smp->remote_key_dist = remote_dist;
71154790f73SVinicius Costa Gomes 		return;
71254790f73SVinicius Costa Gomes 	}
71354790f73SVinicius Costa Gomes 
71454790f73SVinicius Costa Gomes 	rsp->io_capability = conn->hcon->io_capability;
71502b05bd8SJohan Hedberg 	rsp->oob_flag = oob_flag;
71630d65e08SMatias Karhumaa 	rsp->max_key_size = hdev->le_max_key_size;
717fd349c02SJohan Hedberg 	rsp->init_key_dist = req->init_key_dist & remote_dist;
718fd349c02SJohan Hedberg 	rsp->resp_key_dist = req->resp_key_dist & local_dist;
7190edb14deSJohan Hedberg 	rsp->auth_req = (authreq & AUTH_REQ_MASK(hdev));
720fd349c02SJohan Hedberg 
721fd349c02SJohan Hedberg 	smp->remote_key_dist = rsp->init_key_dist;
722b8e66eacSVinicius Costa Gomes }
723b8e66eacSVinicius Costa Gomes 
7243158c50cSVinicius Costa Gomes static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
7253158c50cSVinicius Costa Gomes {
7265d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
7272fd36558SJohan Hedberg 	struct hci_dev *hdev = conn->hcon->hdev;
7285d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
7291c1def09SVinicius Costa Gomes 
73049c06c9eSŁukasz Rymanowski 	if (conn->hcon->pending_sec_level == BT_SECURITY_FIPS &&
73149c06c9eSŁukasz Rymanowski 	    max_key_size != SMP_MAX_ENC_KEY_SIZE)
73249c06c9eSŁukasz Rymanowski 		return SMP_ENC_KEY_SIZE;
73349c06c9eSŁukasz Rymanowski 
73430d65e08SMatias Karhumaa 	if (max_key_size > hdev->le_max_key_size ||
7352fd36558SJohan Hedberg 	    max_key_size < SMP_MIN_ENC_KEY_SIZE)
7363158c50cSVinicius Costa Gomes 		return SMP_ENC_KEY_SIZE;
7373158c50cSVinicius Costa Gomes 
738f7aa611aSVinicius Costa Gomes 	smp->enc_key_size = max_key_size;
7393158c50cSVinicius Costa Gomes 
7403158c50cSVinicius Costa Gomes 	return 0;
7413158c50cSVinicius Costa Gomes }
7423158c50cSVinicius Costa Gomes 
7436f48e260SJohan Hedberg static void smp_chan_destroy(struct l2cap_conn *conn)
7446f48e260SJohan Hedberg {
7456f48e260SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
7466f48e260SJohan Hedberg 	struct smp_chan *smp = chan->data;
747923e2414SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
7486f48e260SJohan Hedberg 	bool complete;
7496f48e260SJohan Hedberg 
7506f48e260SJohan Hedberg 	BUG_ON(!smp);
7516f48e260SJohan Hedberg 
7526f48e260SJohan Hedberg 	cancel_delayed_work_sync(&smp->security_timer);
7536f48e260SJohan Hedberg 
7546f48e260SJohan Hedberg 	complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags);
755923e2414SJohan Hedberg 	mgmt_smp_complete(hcon, complete);
7566f48e260SJohan Hedberg 
757453431a5SWaiman Long 	kfree_sensitive(smp->csrk);
758fad646e1SArchie Pusaka 	kfree_sensitive(smp->responder_csrk);
759453431a5SWaiman Long 	kfree_sensitive(smp->link_key);
7606f48e260SJohan Hedberg 
76171af2f6bSHerbert Xu 	crypto_free_shash(smp->tfm_cmac);
76247eb2ac8STudor Ambarus 	crypto_free_kpp(smp->tfm_ecdh);
7636f48e260SJohan Hedberg 
764923e2414SJohan Hedberg 	/* Ensure that we don't leave any debug key around if debug key
765923e2414SJohan Hedberg 	 * support hasn't been explicitly enabled.
766923e2414SJohan Hedberg 	 */
767923e2414SJohan Hedberg 	if (smp->ltk && smp->ltk->type == SMP_LTK_P256_DEBUG &&
768d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hcon->hdev, HCI_KEEP_DEBUG_KEYS)) {
769923e2414SJohan Hedberg 		list_del_rcu(&smp->ltk->list);
770923e2414SJohan Hedberg 		kfree_rcu(smp->ltk, rcu);
771923e2414SJohan Hedberg 		smp->ltk = NULL;
772923e2414SJohan Hedberg 	}
773923e2414SJohan Hedberg 
7746f48e260SJohan Hedberg 	/* If pairing failed clean up any keys we might have */
7756f48e260SJohan Hedberg 	if (!complete) {
7766f48e260SJohan Hedberg 		if (smp->ltk) {
777970d0f1bSJohan Hedberg 			list_del_rcu(&smp->ltk->list);
778970d0f1bSJohan Hedberg 			kfree_rcu(smp->ltk, rcu);
7796f48e260SJohan Hedberg 		}
7806f48e260SJohan Hedberg 
781fad646e1SArchie Pusaka 		if (smp->responder_ltk) {
782fad646e1SArchie Pusaka 			list_del_rcu(&smp->responder_ltk->list);
783fad646e1SArchie Pusaka 			kfree_rcu(smp->responder_ltk, rcu);
7846f48e260SJohan Hedberg 		}
7856f48e260SJohan Hedberg 
7866f48e260SJohan Hedberg 		if (smp->remote_irk) {
787adae20cbSJohan Hedberg 			list_del_rcu(&smp->remote_irk->list);
788adae20cbSJohan Hedberg 			kfree_rcu(smp->remote_irk, rcu);
7896f48e260SJohan Hedberg 		}
7906f48e260SJohan Hedberg 	}
7916f48e260SJohan Hedberg 
7926f48e260SJohan Hedberg 	chan->data = NULL;
793453431a5SWaiman Long 	kfree_sensitive(smp);
794923e2414SJohan Hedberg 	hci_conn_drop(hcon);
7956f48e260SJohan Hedberg }
7966f48e260SJohan Hedberg 
79784794e11SJohan Hedberg static void smp_failure(struct l2cap_conn *conn, u8 reason)
7984f957a76SBrian Gix {
799bab73cb6SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
800b68fda68SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
801bab73cb6SJohan Hedberg 
80284794e11SJohan Hedberg 	if (reason)
8034f957a76SBrian Gix 		smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
8044f957a76SBrian Gix 			     &reason);
8054f957a76SBrian Gix 
806e1e930f5SJohan Hedberg 	mgmt_auth_failed(hcon, HCI_ERROR_AUTH_FAILURE);
807f1c09c07SVinicius Costa Gomes 
808fc75cc86SJohan Hedberg 	if (chan->data)
8094f957a76SBrian Gix 		smp_chan_destroy(conn);
8104f957a76SBrian Gix }
8114f957a76SBrian Gix 
8122b64d153SBrian Gix #define JUST_WORKS	0x00
8132b64d153SBrian Gix #define JUST_CFM	0x01
8142b64d153SBrian Gix #define REQ_PASSKEY	0x02
8152b64d153SBrian Gix #define CFM_PASSKEY	0x03
8162b64d153SBrian Gix #define REQ_OOB		0x04
8175e3d3d9bSJohan Hedberg #define DSP_PASSKEY	0x05
8182b64d153SBrian Gix #define OVERLAP		0xFF
8192b64d153SBrian Gix 
8202b64d153SBrian Gix static const u8 gen_method[5][5] = {
8212b64d153SBrian Gix 	{ JUST_WORKS,  JUST_CFM,    REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
8222b64d153SBrian Gix 	{ JUST_WORKS,  JUST_CFM,    REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
8232b64d153SBrian Gix 	{ CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
8242b64d153SBrian Gix 	{ JUST_WORKS,  JUST_CFM,    JUST_WORKS,  JUST_WORKS, JUST_CFM    },
8252b64d153SBrian Gix 	{ CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, OVERLAP     },
8262b64d153SBrian Gix };
8272b64d153SBrian Gix 
8285e3d3d9bSJohan Hedberg static const u8 sc_method[5][5] = {
8295e3d3d9bSJohan Hedberg 	{ JUST_WORKS,  JUST_CFM,    REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
8305e3d3d9bSJohan Hedberg 	{ JUST_WORKS,  CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
8315e3d3d9bSJohan Hedberg 	{ DSP_PASSKEY, DSP_PASSKEY, REQ_PASSKEY, JUST_WORKS, DSP_PASSKEY },
8325e3d3d9bSJohan Hedberg 	{ JUST_WORKS,  JUST_CFM,    JUST_WORKS,  JUST_WORKS, JUST_CFM    },
8335e3d3d9bSJohan Hedberg 	{ DSP_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
8345e3d3d9bSJohan Hedberg };
8355e3d3d9bSJohan Hedberg 
836581370ccSJohan Hedberg static u8 get_auth_method(struct smp_chan *smp, u8 local_io, u8 remote_io)
837581370ccSJohan Hedberg {
8382bcd4003SJohan Hedberg 	/* If either side has unknown io_caps, use JUST_CFM (which gets
8392bcd4003SJohan Hedberg 	 * converted later to JUST_WORKS if we're initiators.
8402bcd4003SJohan Hedberg 	 */
841581370ccSJohan Hedberg 	if (local_io > SMP_IO_KEYBOARD_DISPLAY ||
842581370ccSJohan Hedberg 	    remote_io > SMP_IO_KEYBOARD_DISPLAY)
8432bcd4003SJohan Hedberg 		return JUST_CFM;
844581370ccSJohan Hedberg 
8455e3d3d9bSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags))
8465e3d3d9bSJohan Hedberg 		return sc_method[remote_io][local_io];
8475e3d3d9bSJohan Hedberg 
848581370ccSJohan Hedberg 	return gen_method[remote_io][local_io];
849581370ccSJohan Hedberg }
850581370ccSJohan Hedberg 
8512b64d153SBrian Gix static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
8522b64d153SBrian Gix 						u8 local_io, u8 remote_io)
8532b64d153SBrian Gix {
8542b64d153SBrian Gix 	struct hci_conn *hcon = conn->hcon;
8555d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
8565d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
8572b64d153SBrian Gix 	u32 passkey = 0;
858d1d900f8SGuenter Roeck 	int ret;
8592b64d153SBrian Gix 
8602b64d153SBrian Gix 	/* Initialize key for JUST WORKS */
8612b64d153SBrian Gix 	memset(smp->tk, 0, sizeof(smp->tk));
8624a74d658SJohan Hedberg 	clear_bit(SMP_FLAG_TK_VALID, &smp->flags);
8632b64d153SBrian Gix 
86483b4b195SKai Ye 	bt_dev_dbg(hcon->hdev, "auth:%u lcl:%u rem:%u", auth, local_io,
8652e1614f7SLuiz Augusto von Dentz 		   remote_io);
8662b64d153SBrian Gix 
8672bcd4003SJohan Hedberg 	/* If neither side wants MITM, either "just" confirm an incoming
8682bcd4003SJohan Hedberg 	 * request or use just-works for outgoing ones. The JUST_CFM
8692bcd4003SJohan Hedberg 	 * will be converted to JUST_WORKS if necessary later in this
8702bcd4003SJohan Hedberg 	 * function. If either side has MITM look up the method from the
8712bcd4003SJohan Hedberg 	 * table.
8722bcd4003SJohan Hedberg 	 */
873581370ccSJohan Hedberg 	if (!(auth & SMP_AUTH_MITM))
874783e0574SJohan Hedberg 		smp->method = JUST_CFM;
8752b64d153SBrian Gix 	else
876783e0574SJohan Hedberg 		smp->method = get_auth_method(smp, local_io, remote_io);
8772b64d153SBrian Gix 
878a82505c7SJohan Hedberg 	/* Don't confirm locally initiated pairing attempts */
879783e0574SJohan Hedberg 	if (smp->method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR,
880783e0574SJohan Hedberg 						&smp->flags))
881783e0574SJohan Hedberg 		smp->method = JUST_WORKS;
882a82505c7SJohan Hedberg 
88302f3e254SJohan Hedberg 	/* Don't bother user space with no IO capabilities */
884783e0574SJohan Hedberg 	if (smp->method == JUST_CFM &&
885783e0574SJohan Hedberg 	    hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
886783e0574SJohan Hedberg 		smp->method = JUST_WORKS;
88702f3e254SJohan Hedberg 
88892516cd9SSonny Sasaka 	/* If Just Works, Continue with Zero TK and ask user-space for
88992516cd9SSonny Sasaka 	 * confirmation */
890783e0574SJohan Hedberg 	if (smp->method == JUST_WORKS) {
891d1d900f8SGuenter Roeck 		ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
89292516cd9SSonny Sasaka 						hcon->type,
89392516cd9SSonny Sasaka 						hcon->dst_type,
89492516cd9SSonny Sasaka 						passkey, 1);
895d1d900f8SGuenter Roeck 		if (ret)
896d1d900f8SGuenter Roeck 			return ret;
89792516cd9SSonny Sasaka 		set_bit(SMP_FLAG_WAIT_USER, &smp->flags);
8982b64d153SBrian Gix 		return 0;
8992b64d153SBrian Gix 	}
9002b64d153SBrian Gix 
90119c5ce9cSJohan Hedberg 	/* If this function is used for SC -> legacy fallback we
90219c5ce9cSJohan Hedberg 	 * can only recover the just-works case.
90319c5ce9cSJohan Hedberg 	 */
90419c5ce9cSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags))
90519c5ce9cSJohan Hedberg 		return -EINVAL;
90619c5ce9cSJohan Hedberg 
9072b64d153SBrian Gix 	/* Not Just Works/Confirm results in MITM Authentication */
908783e0574SJohan Hedberg 	if (smp->method != JUST_CFM) {
9094a74d658SJohan Hedberg 		set_bit(SMP_FLAG_MITM_AUTH, &smp->flags);
9105eb596f5SJohan Hedberg 		if (hcon->pending_sec_level < BT_SECURITY_HIGH)
9115eb596f5SJohan Hedberg 			hcon->pending_sec_level = BT_SECURITY_HIGH;
9125eb596f5SJohan Hedberg 	}
9132b64d153SBrian Gix 
91474be523cSArchie Pusaka 	/* If both devices have Keyboard-Display I/O, the initiator
91574be523cSArchie Pusaka 	 * Confirms and the responder Enters the passkey.
9162b64d153SBrian Gix 	 */
917783e0574SJohan Hedberg 	if (smp->method == OVERLAP) {
91840bef302SJohan Hedberg 		if (hcon->role == HCI_ROLE_MASTER)
919783e0574SJohan Hedberg 			smp->method = CFM_PASSKEY;
9202b64d153SBrian Gix 		else
921783e0574SJohan Hedberg 			smp->method = REQ_PASSKEY;
9222b64d153SBrian Gix 	}
9232b64d153SBrian Gix 
92401ad34d2SJohan Hedberg 	/* Generate random passkey. */
925783e0574SJohan Hedberg 	if (smp->method == CFM_PASSKEY) {
926943a732aSJohan Hedberg 		memset(smp->tk, 0, sizeof(smp->tk));
9272b64d153SBrian Gix 		get_random_bytes(&passkey, sizeof(passkey));
9282b64d153SBrian Gix 		passkey %= 1000000;
929943a732aSJohan Hedberg 		put_unaligned_le32(passkey, smp->tk);
93083b4b195SKai Ye 		bt_dev_dbg(hcon->hdev, "PassKey: %u", passkey);
9314a74d658SJohan Hedberg 		set_bit(SMP_FLAG_TK_VALID, &smp->flags);
9322b64d153SBrian Gix 	}
9332b64d153SBrian Gix 
934783e0574SJohan Hedberg 	if (smp->method == REQ_PASSKEY)
935ce39fb4eSMarcel Holtmann 		ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst,
936272d90dfSJohan Hedberg 						hcon->type, hcon->dst_type);
937783e0574SJohan Hedberg 	else if (smp->method == JUST_CFM)
9384eb65e66SJohan Hedberg 		ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
9394eb65e66SJohan Hedberg 						hcon->type, hcon->dst_type,
9404eb65e66SJohan Hedberg 						passkey, 1);
9412b64d153SBrian Gix 	else
94201ad34d2SJohan Hedberg 		ret = mgmt_user_passkey_notify(hcon->hdev, &hcon->dst,
943272d90dfSJohan Hedberg 						hcon->type, hcon->dst_type,
94439adbffeSJohan Hedberg 						passkey, 0);
9452b64d153SBrian Gix 
9462b64d153SBrian Gix 	return ret;
9472b64d153SBrian Gix }
9482b64d153SBrian Gix 
9491cc61144SJohan Hedberg static u8 smp_confirm(struct smp_chan *smp)
9508aab4757SVinicius Costa Gomes {
9518aab4757SVinicius Costa Gomes 	struct l2cap_conn *conn = smp->conn;
9528aab4757SVinicius Costa Gomes 	struct smp_cmd_pairing_confirm cp;
9538aab4757SVinicius Costa Gomes 	int ret;
9548aab4757SVinicius Costa Gomes 
9552e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(conn->hcon->hdev, "conn %p", conn);
9568aab4757SVinicius Costa Gomes 
95728a220aaSArd Biesheuvel 	ret = smp_c1(smp->tk, smp->prnd, smp->preq, smp->prsp,
958b1cd5fd9SJohan Hedberg 		     conn->hcon->init_addr_type, &conn->hcon->init_addr,
959943a732aSJohan Hedberg 		     conn->hcon->resp_addr_type, &conn->hcon->resp_addr,
960943a732aSJohan Hedberg 		     cp.confirm_val);
9611cc61144SJohan Hedberg 	if (ret)
9621cc61144SJohan Hedberg 		return SMP_UNSPECIFIED;
9638aab4757SVinicius Costa Gomes 
9644a74d658SJohan Hedberg 	clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
9652b64d153SBrian Gix 
9668aab4757SVinicius Costa Gomes 	smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
9678aab4757SVinicius Costa Gomes 
968b28b4943SJohan Hedberg 	if (conn->hcon->out)
969b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
970b28b4943SJohan Hedberg 	else
971b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
972b28b4943SJohan Hedberg 
9731cc61144SJohan Hedberg 	return 0;
9748aab4757SVinicius Costa Gomes }
9758aab4757SVinicius Costa Gomes 
976861580a9SJohan Hedberg static u8 smp_random(struct smp_chan *smp)
9778aab4757SVinicius Costa Gomes {
9788aab4757SVinicius Costa Gomes 	struct l2cap_conn *conn = smp->conn;
9798aab4757SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
980861580a9SJohan Hedberg 	u8 confirm[16];
9818aab4757SVinicius Costa Gomes 	int ret;
9828aab4757SVinicius Costa Gomes 
9832e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(conn->hcon->hdev, "conn %p %s", conn,
984fad646e1SArchie Pusaka 		   conn->hcon->out ? "initiator" : "responder");
9858aab4757SVinicius Costa Gomes 
98628a220aaSArd Biesheuvel 	ret = smp_c1(smp->tk, smp->rrnd, smp->preq, smp->prsp,
987b1cd5fd9SJohan Hedberg 		     hcon->init_addr_type, &hcon->init_addr,
988943a732aSJohan Hedberg 		     hcon->resp_addr_type, &hcon->resp_addr, confirm);
989861580a9SJohan Hedberg 	if (ret)
990861580a9SJohan Hedberg 		return SMP_UNSPECIFIED;
9918aab4757SVinicius Costa Gomes 
992329d8230SJason A. Donenfeld 	if (crypto_memneq(smp->pcnf, confirm, sizeof(smp->pcnf))) {
9932064ee33SMarcel Holtmann 		bt_dev_err(hcon->hdev, "pairing failed "
9942064ee33SMarcel Holtmann 			   "(confirmation values mismatch)");
995861580a9SJohan Hedberg 		return SMP_CONFIRM_FAILED;
9968aab4757SVinicius Costa Gomes 	}
9978aab4757SVinicius Costa Gomes 
9988aab4757SVinicius Costa Gomes 	if (hcon->out) {
999fe39c7b2SMarcel Holtmann 		u8 stk[16];
1000fe39c7b2SMarcel Holtmann 		__le64 rand = 0;
1001fe39c7b2SMarcel Holtmann 		__le16 ediv = 0;
10028aab4757SVinicius Costa Gomes 
100328a220aaSArd Biesheuvel 		smp_s1(smp->tk, smp->rrnd, smp->prnd, stk);
10048aab4757SVinicius Costa Gomes 
1005861580a9SJohan Hedberg 		if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
1006861580a9SJohan Hedberg 			return SMP_UNSPECIFIED;
10078aab4757SVinicius Costa Gomes 
10088b76ce34SJohan Hedberg 		hci_le_start_enc(hcon, ediv, rand, stk, smp->enc_key_size);
1009f7aa611aSVinicius Costa Gomes 		hcon->enc_key_size = smp->enc_key_size;
1010fe59a05fSJohan Hedberg 		set_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags);
10118aab4757SVinicius Costa Gomes 	} else {
1012fff3490fSJohan Hedberg 		u8 stk[16], auth;
1013fe39c7b2SMarcel Holtmann 		__le64 rand = 0;
1014fe39c7b2SMarcel Holtmann 		__le16 ediv = 0;
10158aab4757SVinicius Costa Gomes 
1016943a732aSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
1017943a732aSJohan Hedberg 			     smp->prnd);
10188aab4757SVinicius Costa Gomes 
101928a220aaSArd Biesheuvel 		smp_s1(smp->tk, smp->prnd, smp->rrnd, stk);
10208aab4757SVinicius Costa Gomes 
1021fff3490fSJohan Hedberg 		if (hcon->pending_sec_level == BT_SECURITY_HIGH)
1022fff3490fSJohan Hedberg 			auth = 1;
1023fff3490fSJohan Hedberg 		else
1024fff3490fSJohan Hedberg 			auth = 0;
1025fff3490fSJohan Hedberg 
1026fad646e1SArchie Pusaka 		/* Even though there's no _RESPONDER suffix this is the
1027fad646e1SArchie Pusaka 		 * responder STK we're adding for later lookup (the initiator
10287d5843b7SJohan Hedberg 		 * STK never needs to be stored).
10297d5843b7SJohan Hedberg 		 */
1030ce39fb4eSMarcel Holtmann 		hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
10312ceba539SJohan Hedberg 			    SMP_STK, auth, stk, smp->enc_key_size, ediv, rand);
10328aab4757SVinicius Costa Gomes 	}
10338aab4757SVinicius Costa Gomes 
1034861580a9SJohan Hedberg 	return 0;
10358aab4757SVinicius Costa Gomes }
10368aab4757SVinicius Costa Gomes 
103744f1a7abSJohan Hedberg static void smp_notify_keys(struct l2cap_conn *conn)
103844f1a7abSJohan Hedberg {
103944f1a7abSJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
104044f1a7abSJohan Hedberg 	struct smp_chan *smp = chan->data;
104144f1a7abSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
104244f1a7abSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
104344f1a7abSJohan Hedberg 	struct smp_cmd_pairing *req = (void *) &smp->preq[1];
104444f1a7abSJohan Hedberg 	struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1];
104544f1a7abSJohan Hedberg 	bool persistent;
104644f1a7abSJohan Hedberg 
1047cad20c27SJohan Hedberg 	if (hcon->type == ACL_LINK) {
1048cad20c27SJohan Hedberg 		if (hcon->key_type == HCI_LK_DEBUG_COMBINATION)
1049cad20c27SJohan Hedberg 			persistent = false;
1050cad20c27SJohan Hedberg 		else
1051cad20c27SJohan Hedberg 			persistent = !test_bit(HCI_CONN_FLUSH_KEY,
1052cad20c27SJohan Hedberg 					       &hcon->flags);
1053cad20c27SJohan Hedberg 	} else {
1054cad20c27SJohan Hedberg 		/* The LTKs, IRKs and CSRKs should be persistent only if
1055cad20c27SJohan Hedberg 		 * both sides had the bonding bit set in their
1056cad20c27SJohan Hedberg 		 * authentication requests.
1057cad20c27SJohan Hedberg 		 */
1058cad20c27SJohan Hedberg 		persistent = !!((req->auth_req & rsp->auth_req) &
1059cad20c27SJohan Hedberg 				SMP_AUTH_BONDING);
1060cad20c27SJohan Hedberg 	}
1061cad20c27SJohan Hedberg 
106244f1a7abSJohan Hedberg 	if (smp->remote_irk) {
1063cad20c27SJohan Hedberg 		mgmt_new_irk(hdev, smp->remote_irk, persistent);
1064cad20c27SJohan Hedberg 
106544f1a7abSJohan Hedberg 		/* Now that user space can be considered to know the
106644f1a7abSJohan Hedberg 		 * identity address track the connection based on it
1067b5ae344dSJohan Hedberg 		 * from now on (assuming this is an LE link).
106844f1a7abSJohan Hedberg 		 */
1069b5ae344dSJohan Hedberg 		if (hcon->type == LE_LINK) {
107044f1a7abSJohan Hedberg 			bacpy(&hcon->dst, &smp->remote_irk->bdaddr);
107144f1a7abSJohan Hedberg 			hcon->dst_type = smp->remote_irk->addr_type;
1072*b8b23001SLuiz Augusto von Dentz 			/* Use a short delay to make sure the new address is
1073*b8b23001SLuiz Augusto von Dentz 			 * propagated _before_ the channels.
1074*b8b23001SLuiz Augusto von Dentz 			 */
1075*b8b23001SLuiz Augusto von Dentz 			queue_delayed_work(hdev->workqueue,
1076*b8b23001SLuiz Augusto von Dentz 					   &conn->id_addr_timer,
1077*b8b23001SLuiz Augusto von Dentz 					   ID_ADDR_TIMEOUT);
1078b5ae344dSJohan Hedberg 		}
107944f1a7abSJohan Hedberg 	}
108044f1a7abSJohan Hedberg 
108144f1a7abSJohan Hedberg 	if (smp->csrk) {
108244f1a7abSJohan Hedberg 		smp->csrk->bdaddr_type = hcon->dst_type;
108344f1a7abSJohan Hedberg 		bacpy(&smp->csrk->bdaddr, &hcon->dst);
108444f1a7abSJohan Hedberg 		mgmt_new_csrk(hdev, smp->csrk, persistent);
108544f1a7abSJohan Hedberg 	}
108644f1a7abSJohan Hedberg 
1087fad646e1SArchie Pusaka 	if (smp->responder_csrk) {
1088fad646e1SArchie Pusaka 		smp->responder_csrk->bdaddr_type = hcon->dst_type;
1089fad646e1SArchie Pusaka 		bacpy(&smp->responder_csrk->bdaddr, &hcon->dst);
1090fad646e1SArchie Pusaka 		mgmt_new_csrk(hdev, smp->responder_csrk, persistent);
109144f1a7abSJohan Hedberg 	}
109244f1a7abSJohan Hedberg 
109344f1a7abSJohan Hedberg 	if (smp->ltk) {
109444f1a7abSJohan Hedberg 		smp->ltk->bdaddr_type = hcon->dst_type;
109544f1a7abSJohan Hedberg 		bacpy(&smp->ltk->bdaddr, &hcon->dst);
109644f1a7abSJohan Hedberg 		mgmt_new_ltk(hdev, smp->ltk, persistent);
109744f1a7abSJohan Hedberg 	}
109844f1a7abSJohan Hedberg 
1099fad646e1SArchie Pusaka 	if (smp->responder_ltk) {
1100fad646e1SArchie Pusaka 		smp->responder_ltk->bdaddr_type = hcon->dst_type;
1101fad646e1SArchie Pusaka 		bacpy(&smp->responder_ltk->bdaddr, &hcon->dst);
1102fad646e1SArchie Pusaka 		mgmt_new_ltk(hdev, smp->responder_ltk, persistent);
110344f1a7abSJohan Hedberg 	}
11046a77083aSJohan Hedberg 
11056a77083aSJohan Hedberg 	if (smp->link_key) {
1106e3befab9SJohan Hedberg 		struct link_key *key;
1107e3befab9SJohan Hedberg 		u8 type;
1108e3befab9SJohan Hedberg 
1109e3befab9SJohan Hedberg 		if (test_bit(SMP_FLAG_DEBUG_KEY, &smp->flags))
1110e3befab9SJohan Hedberg 			type = HCI_LK_DEBUG_COMBINATION;
1111e3befab9SJohan Hedberg 		else if (hcon->sec_level == BT_SECURITY_FIPS)
1112e3befab9SJohan Hedberg 			type = HCI_LK_AUTH_COMBINATION_P256;
1113e3befab9SJohan Hedberg 		else
1114e3befab9SJohan Hedberg 			type = HCI_LK_UNAUTH_COMBINATION_P256;
1115e3befab9SJohan Hedberg 
1116e3befab9SJohan Hedberg 		key = hci_add_link_key(hdev, smp->conn->hcon, &hcon->dst,
1117e3befab9SJohan Hedberg 				       smp->link_key, type, 0, &persistent);
1118e3befab9SJohan Hedberg 		if (key) {
1119e3befab9SJohan Hedberg 			mgmt_new_link_key(hdev, key, persistent);
1120e3befab9SJohan Hedberg 
1121e3befab9SJohan Hedberg 			/* Don't keep debug keys around if the relevant
1122e3befab9SJohan Hedberg 			 * flag is not set.
1123e3befab9SJohan Hedberg 			 */
1124d7a5a11dSMarcel Holtmann 			if (!hci_dev_test_flag(hdev, HCI_KEEP_DEBUG_KEYS) &&
1125e3befab9SJohan Hedberg 			    key->type == HCI_LK_DEBUG_COMBINATION) {
1126e3befab9SJohan Hedberg 				list_del_rcu(&key->list);
1127e3befab9SJohan Hedberg 				kfree_rcu(key, rcu);
1128e3befab9SJohan Hedberg 			}
1129e3befab9SJohan Hedberg 		}
11306a77083aSJohan Hedberg 	}
11316a77083aSJohan Hedberg }
11326a77083aSJohan Hedberg 
1133d3e54a87SJohan Hedberg static void sc_add_ltk(struct smp_chan *smp)
1134d3e54a87SJohan Hedberg {
1135d3e54a87SJohan Hedberg 	struct hci_conn *hcon = smp->conn->hcon;
1136d3e54a87SJohan Hedberg 	u8 key_type, auth;
1137d3e54a87SJohan Hedberg 
1138d3e54a87SJohan Hedberg 	if (test_bit(SMP_FLAG_DEBUG_KEY, &smp->flags))
1139d3e54a87SJohan Hedberg 		key_type = SMP_LTK_P256_DEBUG;
1140d3e54a87SJohan Hedberg 	else
1141d3e54a87SJohan Hedberg 		key_type = SMP_LTK_P256;
1142d3e54a87SJohan Hedberg 
1143d3e54a87SJohan Hedberg 	if (hcon->pending_sec_level == BT_SECURITY_FIPS)
1144d3e54a87SJohan Hedberg 		auth = 1;
1145d3e54a87SJohan Hedberg 	else
1146d3e54a87SJohan Hedberg 		auth = 0;
1147d3e54a87SJohan Hedberg 
1148d3e54a87SJohan Hedberg 	smp->ltk = hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
1149d3e54a87SJohan Hedberg 			       key_type, auth, smp->tk, smp->enc_key_size,
1150d3e54a87SJohan Hedberg 			       0, 0);
1151d3e54a87SJohan Hedberg }
1152d3e54a87SJohan Hedberg 
11536a77083aSJohan Hedberg static void sc_generate_link_key(struct smp_chan *smp)
11546a77083aSJohan Hedberg {
1155a62da6f1SJohan Hedberg 	/* From core spec. Spells out in ASCII as 'lebr'. */
11566a77083aSJohan Hedberg 	const u8 lebr[4] = { 0x72, 0x62, 0x65, 0x6c };
11576a77083aSJohan Hedberg 
11586a77083aSJohan Hedberg 	smp->link_key = kzalloc(16, GFP_KERNEL);
11596a77083aSJohan Hedberg 	if (!smp->link_key)
11606a77083aSJohan Hedberg 		return;
11616a77083aSJohan Hedberg 
1162a62da6f1SJohan Hedberg 	if (test_bit(SMP_FLAG_CT2, &smp->flags)) {
1163151129dfSChristophe JAILLET 		/* SALT = 0x000000000000000000000000746D7031 */
1164a62da6f1SJohan Hedberg 		const u8 salt[16] = { 0x31, 0x70, 0x6d, 0x74 };
1165a62da6f1SJohan Hedberg 
1166a62da6f1SJohan Hedberg 		if (smp_h7(smp->tfm_cmac, smp->tk, salt, smp->link_key)) {
1167453431a5SWaiman Long 			kfree_sensitive(smp->link_key);
1168a62da6f1SJohan Hedberg 			smp->link_key = NULL;
1169a62da6f1SJohan Hedberg 			return;
1170a62da6f1SJohan Hedberg 		}
1171a62da6f1SJohan Hedberg 	} else {
1172a62da6f1SJohan Hedberg 		/* From core spec. Spells out in ASCII as 'tmp1'. */
1173a62da6f1SJohan Hedberg 		const u8 tmp1[4] = { 0x31, 0x70, 0x6d, 0x74 };
1174a62da6f1SJohan Hedberg 
11756a77083aSJohan Hedberg 		if (smp_h6(smp->tfm_cmac, smp->tk, tmp1, smp->link_key)) {
1176453431a5SWaiman Long 			kfree_sensitive(smp->link_key);
11776a77083aSJohan Hedberg 			smp->link_key = NULL;
11786a77083aSJohan Hedberg 			return;
11796a77083aSJohan Hedberg 		}
1180a62da6f1SJohan Hedberg 	}
11816a77083aSJohan Hedberg 
11826a77083aSJohan Hedberg 	if (smp_h6(smp->tfm_cmac, smp->link_key, lebr, smp->link_key)) {
1183453431a5SWaiman Long 		kfree_sensitive(smp->link_key);
11846a77083aSJohan Hedberg 		smp->link_key = NULL;
11856a77083aSJohan Hedberg 		return;
11866a77083aSJohan Hedberg 	}
118744f1a7abSJohan Hedberg }
118844f1a7abSJohan Hedberg 
1189b28b4943SJohan Hedberg static void smp_allow_key_dist(struct smp_chan *smp)
1190b28b4943SJohan Hedberg {
1191b28b4943SJohan Hedberg 	/* Allow the first expected phase 3 PDU. The rest of the PDUs
1192b28b4943SJohan Hedberg 	 * will be allowed in each PDU handler to ensure we receive
1193b28b4943SJohan Hedberg 	 * them in the correct order.
1194b28b4943SJohan Hedberg 	 */
1195b28b4943SJohan Hedberg 	if (smp->remote_key_dist & SMP_DIST_ENC_KEY)
1196b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_ENCRYPT_INFO);
1197b28b4943SJohan Hedberg 	else if (smp->remote_key_dist & SMP_DIST_ID_KEY)
1198b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO);
1199b28b4943SJohan Hedberg 	else if (smp->remote_key_dist & SMP_DIST_SIGN)
1200b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO);
1201b28b4943SJohan Hedberg }
1202b28b4943SJohan Hedberg 
1203b5ae344dSJohan Hedberg static void sc_generate_ltk(struct smp_chan *smp)
1204b5ae344dSJohan Hedberg {
1205a62da6f1SJohan Hedberg 	/* From core spec. Spells out in ASCII as 'brle'. */
1206b5ae344dSJohan Hedberg 	const u8 brle[4] = { 0x65, 0x6c, 0x72, 0x62 };
1207b5ae344dSJohan Hedberg 	struct hci_conn *hcon = smp->conn->hcon;
1208b5ae344dSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
1209b5ae344dSJohan Hedberg 	struct link_key *key;
1210b5ae344dSJohan Hedberg 
1211b5ae344dSJohan Hedberg 	key = hci_find_link_key(hdev, &hcon->dst);
1212b5ae344dSJohan Hedberg 	if (!key) {
12132064ee33SMarcel Holtmann 		bt_dev_err(hdev, "no Link Key found to generate LTK");
1214b5ae344dSJohan Hedberg 		return;
1215b5ae344dSJohan Hedberg 	}
1216b5ae344dSJohan Hedberg 
1217b5ae344dSJohan Hedberg 	if (key->type == HCI_LK_DEBUG_COMBINATION)
1218b5ae344dSJohan Hedberg 		set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags);
1219b5ae344dSJohan Hedberg 
1220a62da6f1SJohan Hedberg 	if (test_bit(SMP_FLAG_CT2, &smp->flags)) {
1221151129dfSChristophe JAILLET 		/* SALT = 0x000000000000000000000000746D7032 */
1222a62da6f1SJohan Hedberg 		const u8 salt[16] = { 0x32, 0x70, 0x6d, 0x74 };
1223a62da6f1SJohan Hedberg 
1224a62da6f1SJohan Hedberg 		if (smp_h7(smp->tfm_cmac, key->val, salt, smp->tk))
1225a62da6f1SJohan Hedberg 			return;
1226a62da6f1SJohan Hedberg 	} else {
1227a62da6f1SJohan Hedberg 		/* From core spec. Spells out in ASCII as 'tmp2'. */
1228a62da6f1SJohan Hedberg 		const u8 tmp2[4] = { 0x32, 0x70, 0x6d, 0x74 };
1229a62da6f1SJohan Hedberg 
1230b5ae344dSJohan Hedberg 		if (smp_h6(smp->tfm_cmac, key->val, tmp2, smp->tk))
1231b5ae344dSJohan Hedberg 			return;
1232a62da6f1SJohan Hedberg 	}
1233b5ae344dSJohan Hedberg 
1234b5ae344dSJohan Hedberg 	if (smp_h6(smp->tfm_cmac, smp->tk, brle, smp->tk))
1235b5ae344dSJohan Hedberg 		return;
1236b5ae344dSJohan Hedberg 
1237b5ae344dSJohan Hedberg 	sc_add_ltk(smp);
1238b5ae344dSJohan Hedberg }
1239b5ae344dSJohan Hedberg 
1240d6268e86SJohan Hedberg static void smp_distribute_keys(struct smp_chan *smp)
124144f1a7abSJohan Hedberg {
124244f1a7abSJohan Hedberg 	struct smp_cmd_pairing *req, *rsp;
124386d1407cSJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
124444f1a7abSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
124544f1a7abSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
124644f1a7abSJohan Hedberg 	__u8 *keydist;
124744f1a7abSJohan Hedberg 
12482e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "conn %p", conn);
124944f1a7abSJohan Hedberg 
125044f1a7abSJohan Hedberg 	rsp = (void *) &smp->prsp[1];
125144f1a7abSJohan Hedberg 
125244f1a7abSJohan Hedberg 	/* The responder sends its keys first */
1253b28b4943SJohan Hedberg 	if (hcon->out && (smp->remote_key_dist & KEY_DIST_MASK)) {
1254b28b4943SJohan Hedberg 		smp_allow_key_dist(smp);
125586d1407cSJohan Hedberg 		return;
1256b28b4943SJohan Hedberg 	}
125744f1a7abSJohan Hedberg 
125844f1a7abSJohan Hedberg 	req = (void *) &smp->preq[1];
125944f1a7abSJohan Hedberg 
126044f1a7abSJohan Hedberg 	if (hcon->out) {
126144f1a7abSJohan Hedberg 		keydist = &rsp->init_key_dist;
126244f1a7abSJohan Hedberg 		*keydist &= req->init_key_dist;
126344f1a7abSJohan Hedberg 	} else {
126444f1a7abSJohan Hedberg 		keydist = &rsp->resp_key_dist;
126544f1a7abSJohan Hedberg 		*keydist &= req->resp_key_dist;
126644f1a7abSJohan Hedberg 	}
126744f1a7abSJohan Hedberg 
12686a77083aSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
1269b5ae344dSJohan Hedberg 		if (hcon->type == LE_LINK && (*keydist & SMP_DIST_LINK_KEY))
12706a77083aSJohan Hedberg 			sc_generate_link_key(smp);
1271b5ae344dSJohan Hedberg 		if (hcon->type == ACL_LINK && (*keydist & SMP_DIST_ENC_KEY))
1272b5ae344dSJohan Hedberg 			sc_generate_ltk(smp);
12736a77083aSJohan Hedberg 
12746a77083aSJohan Hedberg 		/* Clear the keys which are generated but not distributed */
12756a77083aSJohan Hedberg 		*keydist &= ~SMP_SC_NO_DIST;
12766a77083aSJohan Hedberg 	}
12776a77083aSJohan Hedberg 
12782e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "keydist 0x%x", *keydist);
127944f1a7abSJohan Hedberg 
128044f1a7abSJohan Hedberg 	if (*keydist & SMP_DIST_ENC_KEY) {
128144f1a7abSJohan Hedberg 		struct smp_cmd_encrypt_info enc;
1282fad646e1SArchie Pusaka 		struct smp_cmd_initiator_ident ident;
128344f1a7abSJohan Hedberg 		struct smp_ltk *ltk;
128444f1a7abSJohan Hedberg 		u8 authenticated;
128544f1a7abSJohan Hedberg 		__le16 ediv;
128644f1a7abSJohan Hedberg 		__le64 rand;
128744f1a7abSJohan Hedberg 
12881fc62c52SJohan Hedberg 		/* Make sure we generate only the significant amount of
12891fc62c52SJohan Hedberg 		 * bytes based on the encryption key size, and set the rest
12901fc62c52SJohan Hedberg 		 * of the value to zeroes.
12911fc62c52SJohan Hedberg 		 */
12921fc62c52SJohan Hedberg 		get_random_bytes(enc.ltk, smp->enc_key_size);
12931fc62c52SJohan Hedberg 		memset(enc.ltk + smp->enc_key_size, 0,
12941fc62c52SJohan Hedberg 		       sizeof(enc.ltk) - smp->enc_key_size);
12951fc62c52SJohan Hedberg 
129644f1a7abSJohan Hedberg 		get_random_bytes(&ediv, sizeof(ediv));
129744f1a7abSJohan Hedberg 		get_random_bytes(&rand, sizeof(rand));
129844f1a7abSJohan Hedberg 
129944f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
130044f1a7abSJohan Hedberg 
130144f1a7abSJohan Hedberg 		authenticated = hcon->sec_level == BT_SECURITY_HIGH;
130244f1a7abSJohan Hedberg 		ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type,
1303fad646e1SArchie Pusaka 				  SMP_LTK_RESPONDER, authenticated, enc.ltk,
130444f1a7abSJohan Hedberg 				  smp->enc_key_size, ediv, rand);
1305fad646e1SArchie Pusaka 		smp->responder_ltk = ltk;
130644f1a7abSJohan Hedberg 
130744f1a7abSJohan Hedberg 		ident.ediv = ediv;
130844f1a7abSJohan Hedberg 		ident.rand = rand;
130944f1a7abSJohan Hedberg 
1310fad646e1SArchie Pusaka 		smp_send_cmd(conn, SMP_CMD_INITIATOR_IDENT, sizeof(ident),
1311fad646e1SArchie Pusaka 			     &ident);
131244f1a7abSJohan Hedberg 
131344f1a7abSJohan Hedberg 		*keydist &= ~SMP_DIST_ENC_KEY;
131444f1a7abSJohan Hedberg 	}
131544f1a7abSJohan Hedberg 
131644f1a7abSJohan Hedberg 	if (*keydist & SMP_DIST_ID_KEY) {
131744f1a7abSJohan Hedberg 		struct smp_cmd_ident_addr_info addrinfo;
131844f1a7abSJohan Hedberg 		struct smp_cmd_ident_info idinfo;
131944f1a7abSJohan Hedberg 
132044f1a7abSJohan Hedberg 		memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk));
132144f1a7abSJohan Hedberg 
132244f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo);
132344f1a7abSJohan Hedberg 
132444f1a7abSJohan Hedberg 		/* The hci_conn contains the local identity address
132544f1a7abSJohan Hedberg 		 * after the connection has been established.
132644f1a7abSJohan Hedberg 		 *
132744f1a7abSJohan Hedberg 		 * This is true even when the connection has been
132844f1a7abSJohan Hedberg 		 * established using a resolvable random address.
132944f1a7abSJohan Hedberg 		 */
133044f1a7abSJohan Hedberg 		bacpy(&addrinfo.bdaddr, &hcon->src);
133144f1a7abSJohan Hedberg 		addrinfo.addr_type = hcon->src_type;
133244f1a7abSJohan Hedberg 
133344f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo),
133444f1a7abSJohan Hedberg 			     &addrinfo);
133544f1a7abSJohan Hedberg 
133644f1a7abSJohan Hedberg 		*keydist &= ~SMP_DIST_ID_KEY;
133744f1a7abSJohan Hedberg 	}
133844f1a7abSJohan Hedberg 
133944f1a7abSJohan Hedberg 	if (*keydist & SMP_DIST_SIGN) {
134044f1a7abSJohan Hedberg 		struct smp_cmd_sign_info sign;
134144f1a7abSJohan Hedberg 		struct smp_csrk *csrk;
134244f1a7abSJohan Hedberg 
134344f1a7abSJohan Hedberg 		/* Generate a new random key */
134444f1a7abSJohan Hedberg 		get_random_bytes(sign.csrk, sizeof(sign.csrk));
134544f1a7abSJohan Hedberg 
134644f1a7abSJohan Hedberg 		csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
134744f1a7abSJohan Hedberg 		if (csrk) {
13484cd3928aSJohan Hedberg 			if (hcon->sec_level > BT_SECURITY_MEDIUM)
13494cd3928aSJohan Hedberg 				csrk->type = MGMT_CSRK_LOCAL_AUTHENTICATED;
13504cd3928aSJohan Hedberg 			else
13514cd3928aSJohan Hedberg 				csrk->type = MGMT_CSRK_LOCAL_UNAUTHENTICATED;
135244f1a7abSJohan Hedberg 			memcpy(csrk->val, sign.csrk, sizeof(csrk->val));
135344f1a7abSJohan Hedberg 		}
1354fad646e1SArchie Pusaka 		smp->responder_csrk = csrk;
135544f1a7abSJohan Hedberg 
135644f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign);
135744f1a7abSJohan Hedberg 
135844f1a7abSJohan Hedberg 		*keydist &= ~SMP_DIST_SIGN;
135944f1a7abSJohan Hedberg 	}
136044f1a7abSJohan Hedberg 
136144f1a7abSJohan Hedberg 	/* If there are still keys to be received wait for them */
1362b28b4943SJohan Hedberg 	if (smp->remote_key_dist & KEY_DIST_MASK) {
1363b28b4943SJohan Hedberg 		smp_allow_key_dist(smp);
136486d1407cSJohan Hedberg 		return;
1365b28b4943SJohan Hedberg 	}
136644f1a7abSJohan Hedberg 
136744f1a7abSJohan Hedberg 	set_bit(SMP_FLAG_COMPLETE, &smp->flags);
136844f1a7abSJohan Hedberg 	smp_notify_keys(conn);
136944f1a7abSJohan Hedberg 
137044f1a7abSJohan Hedberg 	smp_chan_destroy(conn);
137144f1a7abSJohan Hedberg }
137244f1a7abSJohan Hedberg 
1373b68fda68SJohan Hedberg static void smp_timeout(struct work_struct *work)
1374b68fda68SJohan Hedberg {
1375b68fda68SJohan Hedberg 	struct smp_chan *smp = container_of(work, struct smp_chan,
1376b68fda68SJohan Hedberg 					    security_timer.work);
1377b68fda68SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
1378b68fda68SJohan Hedberg 
13792e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(conn->hcon->hdev, "conn %p", conn);
1380b68fda68SJohan Hedberg 
13811e91c29eSJohan Hedberg 	hci_disconnect(conn->hcon, HCI_ERROR_REMOTE_USER_TERM);
1382b68fda68SJohan Hedberg }
1383b68fda68SJohan Hedberg 
13848aab4757SVinicius Costa Gomes static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
13858aab4757SVinicius Costa Gomes {
13862e1614f7SLuiz Augusto von Dentz 	struct hci_conn *hcon = conn->hcon;
13875d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
13888aab4757SVinicius Costa Gomes 	struct smp_chan *smp;
13898aab4757SVinicius Costa Gomes 
1390f1560463SMarcel Holtmann 	smp = kzalloc(sizeof(*smp), GFP_ATOMIC);
1391fc75cc86SJohan Hedberg 	if (!smp)
13928aab4757SVinicius Costa Gomes 		return NULL;
13938aab4757SVinicius Costa Gomes 
139471af2f6bSHerbert Xu 	smp->tfm_cmac = crypto_alloc_shash("cmac(aes)", 0, 0);
1395407cecf6SJohan Hedberg 	if (IS_ERR(smp->tfm_cmac)) {
13962e1614f7SLuiz Augusto von Dentz 		bt_dev_err(hcon->hdev, "Unable to create CMAC crypto context");
139728a220aaSArd Biesheuvel 		goto zfree_smp;
139847eb2ac8STudor Ambarus 	}
139947eb2ac8STudor Ambarus 
14006763f5eaSMeng Yu 	smp->tfm_ecdh = crypto_alloc_kpp("ecdh-nist-p256", 0, 0);
140147eb2ac8STudor Ambarus 	if (IS_ERR(smp->tfm_ecdh)) {
14022e1614f7SLuiz Augusto von Dentz 		bt_dev_err(hcon->hdev, "Unable to create ECDH crypto context");
140347eb2ac8STudor Ambarus 		goto free_shash;
1404407cecf6SJohan Hedberg 	}
1405407cecf6SJohan Hedberg 
14068aab4757SVinicius Costa Gomes 	smp->conn = conn;
14075d88cc73SJohan Hedberg 	chan->data = smp;
14088aab4757SVinicius Costa Gomes 
1409b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_FAIL);
1410b28b4943SJohan Hedberg 
1411b68fda68SJohan Hedberg 	INIT_DELAYED_WORK(&smp->security_timer, smp_timeout);
1412b68fda68SJohan Hedberg 
14132e1614f7SLuiz Augusto von Dentz 	hci_conn_hold(hcon);
14148aab4757SVinicius Costa Gomes 
14158aab4757SVinicius Costa Gomes 	return smp;
141647eb2ac8STudor Ambarus 
141747eb2ac8STudor Ambarus free_shash:
141847eb2ac8STudor Ambarus 	crypto_free_shash(smp->tfm_cmac);
141947eb2ac8STudor Ambarus zfree_smp:
1420453431a5SWaiman Long 	kfree_sensitive(smp);
142147eb2ac8STudor Ambarus 	return NULL;
14228aab4757SVinicius Costa Gomes }
14238aab4757SVinicius Costa Gomes 
1424760b018bSJohan Hedberg static int sc_mackey_and_ltk(struct smp_chan *smp, u8 mackey[16], u8 ltk[16])
1425760b018bSJohan Hedberg {
1426760b018bSJohan Hedberg 	struct hci_conn *hcon = smp->conn->hcon;
1427760b018bSJohan Hedberg 	u8 *na, *nb, a[7], b[7];
1428760b018bSJohan Hedberg 
1429760b018bSJohan Hedberg 	if (hcon->out) {
1430760b018bSJohan Hedberg 		na   = smp->prnd;
1431760b018bSJohan Hedberg 		nb   = smp->rrnd;
1432760b018bSJohan Hedberg 	} else {
1433760b018bSJohan Hedberg 		na   = smp->rrnd;
1434760b018bSJohan Hedberg 		nb   = smp->prnd;
1435760b018bSJohan Hedberg 	}
1436760b018bSJohan Hedberg 
1437760b018bSJohan Hedberg 	memcpy(a, &hcon->init_addr, 6);
1438760b018bSJohan Hedberg 	memcpy(b, &hcon->resp_addr, 6);
1439760b018bSJohan Hedberg 	a[6] = hcon->init_addr_type;
1440760b018bSJohan Hedberg 	b[6] = hcon->resp_addr_type;
1441760b018bSJohan Hedberg 
1442760b018bSJohan Hedberg 	return smp_f5(smp->tfm_cmac, smp->dhkey, na, nb, a, b, mackey, ltk);
1443760b018bSJohan Hedberg }
1444760b018bSJohan Hedberg 
144538606f14SJohan Hedberg static void sc_dhkey_check(struct smp_chan *smp)
1446760b018bSJohan Hedberg {
1447760b018bSJohan Hedberg 	struct hci_conn *hcon = smp->conn->hcon;
1448760b018bSJohan Hedberg 	struct smp_cmd_dhkey_check check;
1449760b018bSJohan Hedberg 	u8 a[7], b[7], *local_addr, *remote_addr;
1450760b018bSJohan Hedberg 	u8 io_cap[3], r[16];
1451760b018bSJohan Hedberg 
1452760b018bSJohan Hedberg 	memcpy(a, &hcon->init_addr, 6);
1453760b018bSJohan Hedberg 	memcpy(b, &hcon->resp_addr, 6);
1454760b018bSJohan Hedberg 	a[6] = hcon->init_addr_type;
1455760b018bSJohan Hedberg 	b[6] = hcon->resp_addr_type;
1456760b018bSJohan Hedberg 
1457760b018bSJohan Hedberg 	if (hcon->out) {
1458760b018bSJohan Hedberg 		local_addr = a;
1459760b018bSJohan Hedberg 		remote_addr = b;
1460760b018bSJohan Hedberg 		memcpy(io_cap, &smp->preq[1], 3);
1461760b018bSJohan Hedberg 	} else {
1462760b018bSJohan Hedberg 		local_addr = b;
1463760b018bSJohan Hedberg 		remote_addr = a;
1464760b018bSJohan Hedberg 		memcpy(io_cap, &smp->prsp[1], 3);
1465760b018bSJohan Hedberg 	}
1466760b018bSJohan Hedberg 
1467dddd3059SJohan Hedberg 	memset(r, 0, sizeof(r));
1468dddd3059SJohan Hedberg 
1469dddd3059SJohan Hedberg 	if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY)
147038606f14SJohan Hedberg 		put_unaligned_le32(hcon->passkey_notify, r);
1471760b018bSJohan Hedberg 
1472a29b0733SJohan Hedberg 	if (smp->method == REQ_OOB)
1473a29b0733SJohan Hedberg 		memcpy(r, smp->rr, 16);
1474a29b0733SJohan Hedberg 
1475760b018bSJohan Hedberg 	smp_f6(smp->tfm_cmac, smp->mackey, smp->prnd, smp->rrnd, r, io_cap,
1476760b018bSJohan Hedberg 	       local_addr, remote_addr, check.e);
1477760b018bSJohan Hedberg 
1478760b018bSJohan Hedberg 	smp_send_cmd(smp->conn, SMP_CMD_DHKEY_CHECK, sizeof(check), &check);
1479dddd3059SJohan Hedberg }
1480dddd3059SJohan Hedberg 
148138606f14SJohan Hedberg static u8 sc_passkey_send_confirm(struct smp_chan *smp)
148238606f14SJohan Hedberg {
148338606f14SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
148438606f14SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
148538606f14SJohan Hedberg 	struct smp_cmd_pairing_confirm cfm;
148638606f14SJohan Hedberg 	u8 r;
148738606f14SJohan Hedberg 
148838606f14SJohan Hedberg 	r = ((hcon->passkey_notify >> smp->passkey_round) & 0x01);
148938606f14SJohan Hedberg 	r |= 0x80;
149038606f14SJohan Hedberg 
149138606f14SJohan Hedberg 	get_random_bytes(smp->prnd, sizeof(smp->prnd));
149238606f14SJohan Hedberg 
149338606f14SJohan Hedberg 	if (smp_f4(smp->tfm_cmac, smp->local_pk, smp->remote_pk, smp->prnd, r,
149438606f14SJohan Hedberg 		   cfm.confirm_val))
149538606f14SJohan Hedberg 		return SMP_UNSPECIFIED;
149638606f14SJohan Hedberg 
149738606f14SJohan Hedberg 	smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cfm), &cfm);
149838606f14SJohan Hedberg 
149938606f14SJohan Hedberg 	return 0;
150038606f14SJohan Hedberg }
150138606f14SJohan Hedberg 
150238606f14SJohan Hedberg static u8 sc_passkey_round(struct smp_chan *smp, u8 smp_op)
150338606f14SJohan Hedberg {
150438606f14SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
150538606f14SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
150638606f14SJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
150738606f14SJohan Hedberg 	u8 cfm[16], r;
150838606f14SJohan Hedberg 
150938606f14SJohan Hedberg 	/* Ignore the PDU if we've already done 20 rounds (0 - 19) */
151038606f14SJohan Hedberg 	if (smp->passkey_round >= 20)
151138606f14SJohan Hedberg 		return 0;
151238606f14SJohan Hedberg 
151338606f14SJohan Hedberg 	switch (smp_op) {
151438606f14SJohan Hedberg 	case SMP_CMD_PAIRING_RANDOM:
151538606f14SJohan Hedberg 		r = ((hcon->passkey_notify >> smp->passkey_round) & 0x01);
151638606f14SJohan Hedberg 		r |= 0x80;
151738606f14SJohan Hedberg 
151838606f14SJohan Hedberg 		if (smp_f4(smp->tfm_cmac, smp->remote_pk, smp->local_pk,
151938606f14SJohan Hedberg 			   smp->rrnd, r, cfm))
152038606f14SJohan Hedberg 			return SMP_UNSPECIFIED;
152138606f14SJohan Hedberg 
1522329d8230SJason A. Donenfeld 		if (crypto_memneq(smp->pcnf, cfm, 16))
152338606f14SJohan Hedberg 			return SMP_CONFIRM_FAILED;
152438606f14SJohan Hedberg 
152538606f14SJohan Hedberg 		smp->passkey_round++;
152638606f14SJohan Hedberg 
152738606f14SJohan Hedberg 		if (smp->passkey_round == 20) {
152838606f14SJohan Hedberg 			/* Generate MacKey and LTK */
152938606f14SJohan Hedberg 			if (sc_mackey_and_ltk(smp, smp->mackey, smp->tk))
153038606f14SJohan Hedberg 				return SMP_UNSPECIFIED;
153138606f14SJohan Hedberg 		}
153238606f14SJohan Hedberg 
153338606f14SJohan Hedberg 		/* The round is only complete when the initiator
153438606f14SJohan Hedberg 		 * receives pairing random.
153538606f14SJohan Hedberg 		 */
153638606f14SJohan Hedberg 		if (!hcon->out) {
153738606f14SJohan Hedberg 			smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM,
153838606f14SJohan Hedberg 				     sizeof(smp->prnd), smp->prnd);
1539d3e54a87SJohan Hedberg 			if (smp->passkey_round == 20)
154038606f14SJohan Hedberg 				SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
1541d3e54a87SJohan Hedberg 			else
154238606f14SJohan Hedberg 				SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
154338606f14SJohan Hedberg 			return 0;
154438606f14SJohan Hedberg 		}
154538606f14SJohan Hedberg 
154638606f14SJohan Hedberg 		/* Start the next round */
154738606f14SJohan Hedberg 		if (smp->passkey_round != 20)
154838606f14SJohan Hedberg 			return sc_passkey_round(smp, 0);
154938606f14SJohan Hedberg 
155038606f14SJohan Hedberg 		/* Passkey rounds are complete - start DHKey Check */
155138606f14SJohan Hedberg 		sc_dhkey_check(smp);
155238606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
155338606f14SJohan Hedberg 
155438606f14SJohan Hedberg 		break;
155538606f14SJohan Hedberg 
155638606f14SJohan Hedberg 	case SMP_CMD_PAIRING_CONFIRM:
155738606f14SJohan Hedberg 		if (test_bit(SMP_FLAG_WAIT_USER, &smp->flags)) {
155838606f14SJohan Hedberg 			set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
155938606f14SJohan Hedberg 			return 0;
156038606f14SJohan Hedberg 		}
156138606f14SJohan Hedberg 
156238606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
156338606f14SJohan Hedberg 
156438606f14SJohan Hedberg 		if (hcon->out) {
156538606f14SJohan Hedberg 			smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM,
156638606f14SJohan Hedberg 				     sizeof(smp->prnd), smp->prnd);
156738606f14SJohan Hedberg 			return 0;
156838606f14SJohan Hedberg 		}
156938606f14SJohan Hedberg 
157038606f14SJohan Hedberg 		return sc_passkey_send_confirm(smp);
157138606f14SJohan Hedberg 
157238606f14SJohan Hedberg 	case SMP_CMD_PUBLIC_KEY:
157338606f14SJohan Hedberg 	default:
157438606f14SJohan Hedberg 		/* Initiating device starts the round */
157538606f14SJohan Hedberg 		if (!hcon->out)
157638606f14SJohan Hedberg 			return 0;
157738606f14SJohan Hedberg 
15782e1614f7SLuiz Augusto von Dentz 		bt_dev_dbg(hdev, "Starting passkey round %u",
157938606f14SJohan Hedberg 			   smp->passkey_round + 1);
158038606f14SJohan Hedberg 
158138606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
158238606f14SJohan Hedberg 
158338606f14SJohan Hedberg 		return sc_passkey_send_confirm(smp);
158438606f14SJohan Hedberg 	}
158538606f14SJohan Hedberg 
158638606f14SJohan Hedberg 	return 0;
158738606f14SJohan Hedberg }
158838606f14SJohan Hedberg 
1589dddd3059SJohan Hedberg static int sc_user_reply(struct smp_chan *smp, u16 mgmt_op, __le32 passkey)
1590dddd3059SJohan Hedberg {
159138606f14SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
159238606f14SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
159338606f14SJohan Hedberg 	u8 smp_op;
159438606f14SJohan Hedberg 
159538606f14SJohan Hedberg 	clear_bit(SMP_FLAG_WAIT_USER, &smp->flags);
159638606f14SJohan Hedberg 
1597dddd3059SJohan Hedberg 	switch (mgmt_op) {
1598dddd3059SJohan Hedberg 	case MGMT_OP_USER_PASSKEY_NEG_REPLY:
1599dddd3059SJohan Hedberg 		smp_failure(smp->conn, SMP_PASSKEY_ENTRY_FAILED);
1600dddd3059SJohan Hedberg 		return 0;
1601dddd3059SJohan Hedberg 	case MGMT_OP_USER_CONFIRM_NEG_REPLY:
1602dddd3059SJohan Hedberg 		smp_failure(smp->conn, SMP_NUMERIC_COMP_FAILED);
1603dddd3059SJohan Hedberg 		return 0;
160438606f14SJohan Hedberg 	case MGMT_OP_USER_PASSKEY_REPLY:
160538606f14SJohan Hedberg 		hcon->passkey_notify = le32_to_cpu(passkey);
160638606f14SJohan Hedberg 		smp->passkey_round = 0;
160738606f14SJohan Hedberg 
160838606f14SJohan Hedberg 		if (test_and_clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags))
160938606f14SJohan Hedberg 			smp_op = SMP_CMD_PAIRING_CONFIRM;
161038606f14SJohan Hedberg 		else
161138606f14SJohan Hedberg 			smp_op = 0;
161238606f14SJohan Hedberg 
161338606f14SJohan Hedberg 		if (sc_passkey_round(smp, smp_op))
161438606f14SJohan Hedberg 			return -EIO;
161538606f14SJohan Hedberg 
161638606f14SJohan Hedberg 		return 0;
1617dddd3059SJohan Hedberg 	}
1618dddd3059SJohan Hedberg 
1619d3e54a87SJohan Hedberg 	/* Initiator sends DHKey check first */
1620d3e54a87SJohan Hedberg 	if (hcon->out) {
162138606f14SJohan Hedberg 		sc_dhkey_check(smp);
1622d3e54a87SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
1623d3e54a87SJohan Hedberg 	} else if (test_and_clear_bit(SMP_FLAG_DHKEY_PENDING, &smp->flags)) {
1624d3e54a87SJohan Hedberg 		sc_dhkey_check(smp);
1625d3e54a87SJohan Hedberg 		sc_add_ltk(smp);
1626d3e54a87SJohan Hedberg 	}
1627760b018bSJohan Hedberg 
1628760b018bSJohan Hedberg 	return 0;
1629760b018bSJohan Hedberg }
1630760b018bSJohan Hedberg 
16312b64d153SBrian Gix int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
16322b64d153SBrian Gix {
1633b10e8017SJohan Hedberg 	struct l2cap_conn *conn = hcon->l2cap_data;
16345d88cc73SJohan Hedberg 	struct l2cap_chan *chan;
16352b64d153SBrian Gix 	struct smp_chan *smp;
16362b64d153SBrian Gix 	u32 value;
1637fc75cc86SJohan Hedberg 	int err;
16382b64d153SBrian Gix 
1639fc75cc86SJohan Hedberg 	if (!conn)
16402b64d153SBrian Gix 		return -ENOTCONN;
16412b64d153SBrian Gix 
16420ae8ef67SLuiz Augusto von Dentz 	bt_dev_dbg(conn->hcon->hdev, "");
16430ae8ef67SLuiz Augusto von Dentz 
16445d88cc73SJohan Hedberg 	chan = conn->smp;
16455d88cc73SJohan Hedberg 	if (!chan)
16465d88cc73SJohan Hedberg 		return -ENOTCONN;
16475d88cc73SJohan Hedberg 
1648fc75cc86SJohan Hedberg 	l2cap_chan_lock(chan);
1649fc75cc86SJohan Hedberg 	if (!chan->data) {
1650fc75cc86SJohan Hedberg 		err = -ENOTCONN;
1651fc75cc86SJohan Hedberg 		goto unlock;
1652fc75cc86SJohan Hedberg 	}
1653fc75cc86SJohan Hedberg 
16545d88cc73SJohan Hedberg 	smp = chan->data;
16552b64d153SBrian Gix 
1656760b018bSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
1657760b018bSJohan Hedberg 		err = sc_user_reply(smp, mgmt_op, passkey);
1658760b018bSJohan Hedberg 		goto unlock;
1659760b018bSJohan Hedberg 	}
1660760b018bSJohan Hedberg 
16612b64d153SBrian Gix 	switch (mgmt_op) {
16622b64d153SBrian Gix 	case MGMT_OP_USER_PASSKEY_REPLY:
16632b64d153SBrian Gix 		value = le32_to_cpu(passkey);
1664943a732aSJohan Hedberg 		memset(smp->tk, 0, sizeof(smp->tk));
166583b4b195SKai Ye 		bt_dev_dbg(conn->hcon->hdev, "PassKey: %u", value);
1666943a732aSJohan Hedberg 		put_unaligned_le32(value, smp->tk);
166719186c7bSGustavo A. R. Silva 		fallthrough;
16682b64d153SBrian Gix 	case MGMT_OP_USER_CONFIRM_REPLY:
16694a74d658SJohan Hedberg 		set_bit(SMP_FLAG_TK_VALID, &smp->flags);
16702b64d153SBrian Gix 		break;
16712b64d153SBrian Gix 	case MGMT_OP_USER_PASSKEY_NEG_REPLY:
16722b64d153SBrian Gix 	case MGMT_OP_USER_CONFIRM_NEG_REPLY:
167384794e11SJohan Hedberg 		smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
1674fc75cc86SJohan Hedberg 		err = 0;
1675fc75cc86SJohan Hedberg 		goto unlock;
16762b64d153SBrian Gix 	default:
167784794e11SJohan Hedberg 		smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
1678fc75cc86SJohan Hedberg 		err = -EOPNOTSUPP;
1679fc75cc86SJohan Hedberg 		goto unlock;
16802b64d153SBrian Gix 	}
16812b64d153SBrian Gix 
1682fc75cc86SJohan Hedberg 	err = 0;
1683fc75cc86SJohan Hedberg 
16842b64d153SBrian Gix 	/* If it is our turn to send Pairing Confirm, do so now */
16851cc61144SJohan Hedberg 	if (test_bit(SMP_FLAG_CFM_PENDING, &smp->flags)) {
16861cc61144SJohan Hedberg 		u8 rsp = smp_confirm(smp);
16871cc61144SJohan Hedberg 		if (rsp)
16881cc61144SJohan Hedberg 			smp_failure(conn, rsp);
16891cc61144SJohan Hedberg 	}
16902b64d153SBrian Gix 
1691fc75cc86SJohan Hedberg unlock:
1692fc75cc86SJohan Hedberg 	l2cap_chan_unlock(chan);
1693fc75cc86SJohan Hedberg 	return err;
16942b64d153SBrian Gix }
16952b64d153SBrian Gix 
1696b5ae344dSJohan Hedberg static void build_bredr_pairing_cmd(struct smp_chan *smp,
1697b5ae344dSJohan Hedberg 				    struct smp_cmd_pairing *req,
1698b5ae344dSJohan Hedberg 				    struct smp_cmd_pairing *rsp)
1699b5ae344dSJohan Hedberg {
1700b5ae344dSJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
1701b5ae344dSJohan Hedberg 	struct hci_dev *hdev = conn->hcon->hdev;
1702b5ae344dSJohan Hedberg 	u8 local_dist = 0, remote_dist = 0;
1703b5ae344dSJohan Hedberg 
1704d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_BONDABLE)) {
1705b5ae344dSJohan Hedberg 		local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
1706b5ae344dSJohan Hedberg 		remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
1707b5ae344dSJohan Hedberg 	}
1708b5ae344dSJohan Hedberg 
1709d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_RPA_RESOLVING))
1710b5ae344dSJohan Hedberg 		remote_dist |= SMP_DIST_ID_KEY;
1711b5ae344dSJohan Hedberg 
1712d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_PRIVACY))
1713b5ae344dSJohan Hedberg 		local_dist |= SMP_DIST_ID_KEY;
1714b5ae344dSJohan Hedberg 
1715b5ae344dSJohan Hedberg 	if (!rsp) {
1716b5ae344dSJohan Hedberg 		memset(req, 0, sizeof(*req));
1717b5ae344dSJohan Hedberg 
1718a62da6f1SJohan Hedberg 		req->auth_req        = SMP_AUTH_CT2;
1719b5ae344dSJohan Hedberg 		req->init_key_dist   = local_dist;
1720b5ae344dSJohan Hedberg 		req->resp_key_dist   = remote_dist;
1721e3f6a257SJohan Hedberg 		req->max_key_size    = conn->hcon->enc_key_size;
1722b5ae344dSJohan Hedberg 
1723b5ae344dSJohan Hedberg 		smp->remote_key_dist = remote_dist;
1724b5ae344dSJohan Hedberg 
1725b5ae344dSJohan Hedberg 		return;
1726b5ae344dSJohan Hedberg 	}
1727b5ae344dSJohan Hedberg 
1728b5ae344dSJohan Hedberg 	memset(rsp, 0, sizeof(*rsp));
1729b5ae344dSJohan Hedberg 
1730a62da6f1SJohan Hedberg 	rsp->auth_req        = SMP_AUTH_CT2;
1731e3f6a257SJohan Hedberg 	rsp->max_key_size    = conn->hcon->enc_key_size;
1732b5ae344dSJohan Hedberg 	rsp->init_key_dist   = req->init_key_dist & remote_dist;
1733b5ae344dSJohan Hedberg 	rsp->resp_key_dist   = req->resp_key_dist & local_dist;
1734b5ae344dSJohan Hedberg 
1735b5ae344dSJohan Hedberg 	smp->remote_key_dist = rsp->init_key_dist;
1736b5ae344dSJohan Hedberg }
1737b5ae344dSJohan Hedberg 
1738da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
173988ba43b6SAnderson Briglia {
17403158c50cSVinicius Costa Gomes 	struct smp_cmd_pairing rsp, *req = (void *) skb->data;
1741fc75cc86SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
1742b3c6410bSJohan Hedberg 	struct hci_dev *hdev = conn->hcon->hdev;
17438aab4757SVinicius Costa Gomes 	struct smp_chan *smp;
1744c7262e71SJohan Hedberg 	u8 key_size, auth, sec_level;
17458aab4757SVinicius Costa Gomes 	int ret;
174688ba43b6SAnderson Briglia 
17472e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "conn %p", conn);
174888ba43b6SAnderson Briglia 
1749c46b98beSJohan Hedberg 	if (skb->len < sizeof(*req))
175038e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1751c46b98beSJohan Hedberg 
175240bef302SJohan Hedberg 	if (conn->hcon->role != HCI_ROLE_SLAVE)
17532b64d153SBrian Gix 		return SMP_CMD_NOTSUPP;
17542b64d153SBrian Gix 
1755fc75cc86SJohan Hedberg 	if (!chan->data)
17568aab4757SVinicius Costa Gomes 		smp = smp_chan_create(conn);
1757fc75cc86SJohan Hedberg 	else
17585d88cc73SJohan Hedberg 		smp = chan->data;
1759d26a2345SVinicius Costa Gomes 
1760d08fd0e7SAndrei Emeltchenko 	if (!smp)
1761d08fd0e7SAndrei Emeltchenko 		return SMP_UNSPECIFIED;
1762d08fd0e7SAndrei Emeltchenko 
1763c05b9339SJohan Hedberg 	/* We didn't start the pairing, so match remote */
17640edb14deSJohan Hedberg 	auth = req->auth_req & AUTH_REQ_MASK(hdev);
1765c05b9339SJohan Hedberg 
1766d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BONDABLE) &&
1767c05b9339SJohan Hedberg 	    (auth & SMP_AUTH_BONDING))
1768b3c6410bSJohan Hedberg 		return SMP_PAIRING_NOTSUPP;
1769b3c6410bSJohan Hedberg 
1770d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SC_ONLY) && !(auth & SMP_AUTH_SC))
1771903b71c7SJohan Hedberg 		return SMP_AUTH_REQUIREMENTS;
1772903b71c7SJohan Hedberg 
17731c1def09SVinicius Costa Gomes 	smp->preq[0] = SMP_CMD_PAIRING_REQ;
17741c1def09SVinicius Costa Gomes 	memcpy(&smp->preq[1], req, sizeof(*req));
17753158c50cSVinicius Costa Gomes 	skb_pull(skb, sizeof(*req));
177688ba43b6SAnderson Briglia 
1777cb06d366SJohan Hedberg 	/* If the remote side's OOB flag is set it means it has
1778cb06d366SJohan Hedberg 	 * successfully received our local OOB data - therefore set the
1779cb06d366SJohan Hedberg 	 * flag to indicate that local OOB is in use.
1780cb06d366SJohan Hedberg 	 */
178194f14e47SJohan Hedberg 	if (req->oob_flag == SMP_OOB_PRESENT && SMP_DEV(hdev)->local_oob)
178258428563SJohan Hedberg 		set_bit(SMP_FLAG_LOCAL_OOB, &smp->flags);
178358428563SJohan Hedberg 
1784b5ae344dSJohan Hedberg 	/* SMP over BR/EDR requires special treatment */
1785b5ae344dSJohan Hedberg 	if (conn->hcon->type == ACL_LINK) {
1786b5ae344dSJohan Hedberg 		/* We must have a BR/EDR SC link */
178708f63cc5SMarcel Holtmann 		if (!test_bit(HCI_CONN_AES_CCM, &conn->hcon->flags) &&
1788b7cb93e5SMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP))
1789b5ae344dSJohan Hedberg 			return SMP_CROSS_TRANSP_NOT_ALLOWED;
1790b5ae344dSJohan Hedberg 
1791b5ae344dSJohan Hedberg 		set_bit(SMP_FLAG_SC, &smp->flags);
1792b5ae344dSJohan Hedberg 
1793b5ae344dSJohan Hedberg 		build_bredr_pairing_cmd(smp, req, &rsp);
1794b5ae344dSJohan Hedberg 
1795a62da6f1SJohan Hedberg 		if (req->auth_req & SMP_AUTH_CT2)
1796a62da6f1SJohan Hedberg 			set_bit(SMP_FLAG_CT2, &smp->flags);
1797a62da6f1SJohan Hedberg 
1798b5ae344dSJohan Hedberg 		key_size = min(req->max_key_size, rsp.max_key_size);
1799b5ae344dSJohan Hedberg 		if (check_enc_key_size(conn, key_size))
1800b5ae344dSJohan Hedberg 			return SMP_ENC_KEY_SIZE;
1801b5ae344dSJohan Hedberg 
1802b5ae344dSJohan Hedberg 		/* Clear bits which are generated but not distributed */
1803b5ae344dSJohan Hedberg 		smp->remote_key_dist &= ~SMP_SC_NO_DIST;
1804b5ae344dSJohan Hedberg 
1805b5ae344dSJohan Hedberg 		smp->prsp[0] = SMP_CMD_PAIRING_RSP;
1806b5ae344dSJohan Hedberg 		memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
1807b5ae344dSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
1808b5ae344dSJohan Hedberg 
1809b5ae344dSJohan Hedberg 		smp_distribute_keys(smp);
1810b5ae344dSJohan Hedberg 		return 0;
1811b5ae344dSJohan Hedberg 	}
1812b5ae344dSJohan Hedberg 
18135e3d3d9bSJohan Hedberg 	build_pairing_cmd(conn, req, &rsp, auth);
18145e3d3d9bSJohan Hedberg 
1815a62da6f1SJohan Hedberg 	if (rsp.auth_req & SMP_AUTH_SC) {
18165e3d3d9bSJohan Hedberg 		set_bit(SMP_FLAG_SC, &smp->flags);
18175e3d3d9bSJohan Hedberg 
1818a62da6f1SJohan Hedberg 		if (rsp.auth_req & SMP_AUTH_CT2)
1819a62da6f1SJohan Hedberg 			set_bit(SMP_FLAG_CT2, &smp->flags);
1820a62da6f1SJohan Hedberg 	}
1821a62da6f1SJohan Hedberg 
18225be5e275SJohan Hedberg 	if (conn->hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
18231afc2a1aSJohan Hedberg 		sec_level = BT_SECURITY_MEDIUM;
18241afc2a1aSJohan Hedberg 	else
1825c7262e71SJohan Hedberg 		sec_level = authreq_to_seclevel(auth);
18261afc2a1aSJohan Hedberg 
1827c7262e71SJohan Hedberg 	if (sec_level > conn->hcon->pending_sec_level)
1828c7262e71SJohan Hedberg 		conn->hcon->pending_sec_level = sec_level;
1829fdde0a26SIdo Yariv 
183049c922bbSStephen Hemminger 	/* If we need MITM check that it can be achieved */
18312ed8f65cSJohan Hedberg 	if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
18322ed8f65cSJohan Hedberg 		u8 method;
18332ed8f65cSJohan Hedberg 
18342ed8f65cSJohan Hedberg 		method = get_auth_method(smp, conn->hcon->io_capability,
18352ed8f65cSJohan Hedberg 					 req->io_capability);
18362ed8f65cSJohan Hedberg 		if (method == JUST_WORKS || method == JUST_CFM)
18372ed8f65cSJohan Hedberg 			return SMP_AUTH_REQUIREMENTS;
18382ed8f65cSJohan Hedberg 	}
18392ed8f65cSJohan Hedberg 
18403158c50cSVinicius Costa Gomes 	key_size = min(req->max_key_size, rsp.max_key_size);
18413158c50cSVinicius Costa Gomes 	if (check_enc_key_size(conn, key_size))
18423158c50cSVinicius Costa Gomes 		return SMP_ENC_KEY_SIZE;
184388ba43b6SAnderson Briglia 
1844e84a6b13SJohan Hedberg 	get_random_bytes(smp->prnd, sizeof(smp->prnd));
18458aab4757SVinicius Costa Gomes 
18461c1def09SVinicius Costa Gomes 	smp->prsp[0] = SMP_CMD_PAIRING_RSP;
18471c1def09SVinicius Costa Gomes 	memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
1848f01ead31SAnderson Briglia 
18493158c50cSVinicius Costa Gomes 	smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
18503b19146dSJohan Hedberg 
18513b19146dSJohan Hedberg 	clear_bit(SMP_FLAG_INITIATOR, &smp->flags);
18523b19146dSJohan Hedberg 
185319c5ce9cSJohan Hedberg 	/* Strictly speaking we shouldn't allow Pairing Confirm for the
185419c5ce9cSJohan Hedberg 	 * SC case, however some implementations incorrectly copy RFU auth
185519c5ce9cSJohan Hedberg 	 * req bits from our security request, which may create a false
185619c5ce9cSJohan Hedberg 	 * positive SC enablement.
185719c5ce9cSJohan Hedberg 	 */
185819c5ce9cSJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
185919c5ce9cSJohan Hedberg 
18603b19146dSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
18613b19146dSJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PUBLIC_KEY);
18623b19146dSJohan Hedberg 		/* Clear bits which are generated but not distributed */
18633b19146dSJohan Hedberg 		smp->remote_key_dist &= ~SMP_SC_NO_DIST;
18643b19146dSJohan Hedberg 		/* Wait for Public Key from Initiating Device */
18653b19146dSJohan Hedberg 		return 0;
18663b19146dSJohan Hedberg 	}
1867da85e5e5SVinicius Costa Gomes 
18682b64d153SBrian Gix 	/* Request setup of TK */
18692b64d153SBrian Gix 	ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability);
18702b64d153SBrian Gix 	if (ret)
18712b64d153SBrian Gix 		return SMP_UNSPECIFIED;
18722b64d153SBrian Gix 
1873da85e5e5SVinicius Costa Gomes 	return 0;
187488ba43b6SAnderson Briglia }
187588ba43b6SAnderson Briglia 
18763b19146dSJohan Hedberg static u8 sc_send_public_key(struct smp_chan *smp)
18773b19146dSJohan Hedberg {
187870157ef5SJohan Hedberg 	struct hci_dev *hdev = smp->conn->hcon->hdev;
187970157ef5SJohan Hedberg 
188056860245SMarcel Holtmann 	bt_dev_dbg(hdev, "");
18813b19146dSJohan Hedberg 
18821a8bab4fSJohan Hedberg 	if (test_bit(SMP_FLAG_LOCAL_OOB, &smp->flags)) {
188333d0c030SMarcel Holtmann 		struct l2cap_chan *chan = hdev->smp_data;
188433d0c030SMarcel Holtmann 		struct smp_dev *smp_dev;
188533d0c030SMarcel Holtmann 
188633d0c030SMarcel Holtmann 		if (!chan || !chan->data)
188733d0c030SMarcel Holtmann 			return SMP_UNSPECIFIED;
188833d0c030SMarcel Holtmann 
188933d0c030SMarcel Holtmann 		smp_dev = chan->data;
189033d0c030SMarcel Holtmann 
189133d0c030SMarcel Holtmann 		memcpy(smp->local_pk, smp_dev->local_pk, 64);
1892fb334feeSMarcel Holtmann 		memcpy(smp->lr, smp_dev->local_rand, 16);
189333d0c030SMarcel Holtmann 
189433d0c030SMarcel Holtmann 		if (smp_dev->debug_key)
189533d0c030SMarcel Holtmann 			set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags);
189633d0c030SMarcel Holtmann 
189733d0c030SMarcel Holtmann 		goto done;
189833d0c030SMarcel Holtmann 	}
189933d0c030SMarcel Holtmann 
1900d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS)) {
19012e1614f7SLuiz Augusto von Dentz 		bt_dev_dbg(hdev, "Using debug keys");
1902c0153b0bSTudor Ambarus 		if (set_ecdh_privkey(smp->tfm_ecdh, debug_sk))
1903c0153b0bSTudor Ambarus 			return SMP_UNSPECIFIED;
190470157ef5SJohan Hedberg 		memcpy(smp->local_pk, debug_pk, 64);
190570157ef5SJohan Hedberg 		set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags);
190670157ef5SJohan Hedberg 	} else {
19076c0dcc50SJohan Hedberg 		while (true) {
1908c0153b0bSTudor Ambarus 			/* Generate key pair for Secure Connections */
1909c0153b0bSTudor Ambarus 			if (generate_ecdh_keys(smp->tfm_ecdh, smp->local_pk))
19103b19146dSJohan Hedberg 				return SMP_UNSPECIFIED;
19113b19146dSJohan Hedberg 
191270157ef5SJohan Hedberg 			/* This is unlikely, but we need to check that
191391641b79SZheng Yongjun 			 * we didn't accidentally generate a debug key.
19146c0dcc50SJohan Hedberg 			 */
1915c0153b0bSTudor Ambarus 			if (crypto_memneq(smp->local_pk, debug_pk, 64))
19166c0dcc50SJohan Hedberg 				break;
19176c0dcc50SJohan Hedberg 		}
191870157ef5SJohan Hedberg 	}
19196c0dcc50SJohan Hedberg 
192033d0c030SMarcel Holtmann done:
1921c7a3d57dSJohan Hedberg 	SMP_DBG("Local Public Key X: %32phN", smp->local_pk);
19228e4e2ee5SMarcel Holtmann 	SMP_DBG("Local Public Key Y: %32phN", smp->local_pk + 32);
19233b19146dSJohan Hedberg 
19243b19146dSJohan Hedberg 	smp_send_cmd(smp->conn, SMP_CMD_PUBLIC_KEY, 64, smp->local_pk);
19253b19146dSJohan Hedberg 
19263b19146dSJohan Hedberg 	return 0;
19273b19146dSJohan Hedberg }
19283b19146dSJohan Hedberg 
1929da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
193088ba43b6SAnderson Briglia {
19313158c50cSVinicius Costa Gomes 	struct smp_cmd_pairing *req, *rsp = (void *) skb->data;
19325d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
19335d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
19340edb14deSJohan Hedberg 	struct hci_dev *hdev = conn->hcon->hdev;
19353a7dbfb8SJohan Hedberg 	u8 key_size, auth;
19367d24ddccSAnderson Briglia 	int ret;
193788ba43b6SAnderson Briglia 
19382e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "conn %p", conn);
193988ba43b6SAnderson Briglia 
1940c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rsp))
194138e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1942c46b98beSJohan Hedberg 
194340bef302SJohan Hedberg 	if (conn->hcon->role != HCI_ROLE_MASTER)
19442b64d153SBrian Gix 		return SMP_CMD_NOTSUPP;
19452b64d153SBrian Gix 
19463158c50cSVinicius Costa Gomes 	skb_pull(skb, sizeof(*rsp));
1947da85e5e5SVinicius Costa Gomes 
19481c1def09SVinicius Costa Gomes 	req = (void *) &smp->preq[1];
19493158c50cSVinicius Costa Gomes 
19503158c50cSVinicius Costa Gomes 	key_size = min(req->max_key_size, rsp->max_key_size);
19513158c50cSVinicius Costa Gomes 	if (check_enc_key_size(conn, key_size))
19523158c50cSVinicius Costa Gomes 		return SMP_ENC_KEY_SIZE;
19533158c50cSVinicius Costa Gomes 
19540edb14deSJohan Hedberg 	auth = rsp->auth_req & AUTH_REQ_MASK(hdev);
1955c05b9339SJohan Hedberg 
1956d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SC_ONLY) && !(auth & SMP_AUTH_SC))
1957903b71c7SJohan Hedberg 		return SMP_AUTH_REQUIREMENTS;
1958903b71c7SJohan Hedberg 
1959cb06d366SJohan Hedberg 	/* If the remote side's OOB flag is set it means it has
1960cb06d366SJohan Hedberg 	 * successfully received our local OOB data - therefore set the
1961cb06d366SJohan Hedberg 	 * flag to indicate that local OOB is in use.
1962cb06d366SJohan Hedberg 	 */
196394f14e47SJohan Hedberg 	if (rsp->oob_flag == SMP_OOB_PRESENT && SMP_DEV(hdev)->local_oob)
196458428563SJohan Hedberg 		set_bit(SMP_FLAG_LOCAL_OOB, &smp->flags);
196558428563SJohan Hedberg 
1966b5ae344dSJohan Hedberg 	smp->prsp[0] = SMP_CMD_PAIRING_RSP;
1967b5ae344dSJohan Hedberg 	memcpy(&smp->prsp[1], rsp, sizeof(*rsp));
1968b5ae344dSJohan Hedberg 
1969b5ae344dSJohan Hedberg 	/* Update remote key distribution in case the remote cleared
1970b5ae344dSJohan Hedberg 	 * some bits that we had enabled in our request.
1971b5ae344dSJohan Hedberg 	 */
1972b5ae344dSJohan Hedberg 	smp->remote_key_dist &= rsp->resp_key_dist;
1973b5ae344dSJohan Hedberg 
1974a62da6f1SJohan Hedberg 	if ((req->auth_req & SMP_AUTH_CT2) && (auth & SMP_AUTH_CT2))
1975a62da6f1SJohan Hedberg 		set_bit(SMP_FLAG_CT2, &smp->flags);
1976a62da6f1SJohan Hedberg 
1977b5ae344dSJohan Hedberg 	/* For BR/EDR this means we're done and can start phase 3 */
1978b5ae344dSJohan Hedberg 	if (conn->hcon->type == ACL_LINK) {
1979b5ae344dSJohan Hedberg 		/* Clear bits which are generated but not distributed */
1980b5ae344dSJohan Hedberg 		smp->remote_key_dist &= ~SMP_SC_NO_DIST;
1981b5ae344dSJohan Hedberg 		smp_distribute_keys(smp);
1982b5ae344dSJohan Hedberg 		return 0;
1983b5ae344dSJohan Hedberg 	}
1984b5ae344dSJohan Hedberg 
198565668776SJohan Hedberg 	if ((req->auth_req & SMP_AUTH_SC) && (auth & SMP_AUTH_SC))
198665668776SJohan Hedberg 		set_bit(SMP_FLAG_SC, &smp->flags);
1987d2eb9e10SJohan Hedberg 	else if (conn->hcon->pending_sec_level > BT_SECURITY_HIGH)
1988d2eb9e10SJohan Hedberg 		conn->hcon->pending_sec_level = BT_SECURITY_HIGH;
198965668776SJohan Hedberg 
199049c922bbSStephen Hemminger 	/* If we need MITM check that it can be achieved */
19912ed8f65cSJohan Hedberg 	if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
19922ed8f65cSJohan Hedberg 		u8 method;
19932ed8f65cSJohan Hedberg 
19942ed8f65cSJohan Hedberg 		method = get_auth_method(smp, req->io_capability,
19952ed8f65cSJohan Hedberg 					 rsp->io_capability);
19962ed8f65cSJohan Hedberg 		if (method == JUST_WORKS || method == JUST_CFM)
19972ed8f65cSJohan Hedberg 			return SMP_AUTH_REQUIREMENTS;
19982ed8f65cSJohan Hedberg 	}
19992ed8f65cSJohan Hedberg 
2000e84a6b13SJohan Hedberg 	get_random_bytes(smp->prnd, sizeof(smp->prnd));
20017d24ddccSAnderson Briglia 
2002fdcc4becSJohan Hedberg 	/* Update remote key distribution in case the remote cleared
2003fdcc4becSJohan Hedberg 	 * some bits that we had enabled in our request.
2004fdcc4becSJohan Hedberg 	 */
2005fdcc4becSJohan Hedberg 	smp->remote_key_dist &= rsp->resp_key_dist;
2006fdcc4becSJohan Hedberg 
20073b19146dSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
20083b19146dSJohan Hedberg 		/* Clear bits which are generated but not distributed */
20093b19146dSJohan Hedberg 		smp->remote_key_dist &= ~SMP_SC_NO_DIST;
20103b19146dSJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PUBLIC_KEY);
20113b19146dSJohan Hedberg 		return sc_send_public_key(smp);
20123b19146dSJohan Hedberg 	}
20133b19146dSJohan Hedberg 
2014c05b9339SJohan Hedberg 	auth |= req->auth_req;
20152b64d153SBrian Gix 
2016476585ecSJohan Hedberg 	ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability);
20172b64d153SBrian Gix 	if (ret)
20182b64d153SBrian Gix 		return SMP_UNSPECIFIED;
20192b64d153SBrian Gix 
20204a74d658SJohan Hedberg 	set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
20212b64d153SBrian Gix 
20222b64d153SBrian Gix 	/* Can't compose response until we have been confirmed */
20234a74d658SJohan Hedberg 	if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
20241cc61144SJohan Hedberg 		return smp_confirm(smp);
2025da85e5e5SVinicius Costa Gomes 
2026da85e5e5SVinicius Costa Gomes 	return 0;
202788ba43b6SAnderson Briglia }
202888ba43b6SAnderson Briglia 
2029dcee2b32SJohan Hedberg static u8 sc_check_confirm(struct smp_chan *smp)
2030dcee2b32SJohan Hedberg {
2031dcee2b32SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
2032dcee2b32SJohan Hedberg 
20332e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(conn->hcon->hdev, "");
2034dcee2b32SJohan Hedberg 
203538606f14SJohan Hedberg 	if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY)
203638606f14SJohan Hedberg 		return sc_passkey_round(smp, SMP_CMD_PAIRING_CONFIRM);
203738606f14SJohan Hedberg 
2038dcee2b32SJohan Hedberg 	if (conn->hcon->out) {
2039dcee2b32SJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
2040dcee2b32SJohan Hedberg 			     smp->prnd);
2041dcee2b32SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
2042dcee2b32SJohan Hedberg 	}
2043dcee2b32SJohan Hedberg 
2044dcee2b32SJohan Hedberg 	return 0;
2045dcee2b32SJohan Hedberg }
2046dcee2b32SJohan Hedberg 
204719c5ce9cSJohan Hedberg /* Work-around for some implementations that incorrectly copy RFU bits
204819c5ce9cSJohan Hedberg  * from our security request and thereby create the impression that
204919c5ce9cSJohan Hedberg  * we're doing SC when in fact the remote doesn't support it.
205019c5ce9cSJohan Hedberg  */
205119c5ce9cSJohan Hedberg static int fixup_sc_false_positive(struct smp_chan *smp)
205219c5ce9cSJohan Hedberg {
205319c5ce9cSJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
205419c5ce9cSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
205519c5ce9cSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
205619c5ce9cSJohan Hedberg 	struct smp_cmd_pairing *req, *rsp;
205719c5ce9cSJohan Hedberg 	u8 auth;
205819c5ce9cSJohan Hedberg 
2059fad646e1SArchie Pusaka 	/* The issue is only observed when we're in responder role */
206019c5ce9cSJohan Hedberg 	if (hcon->out)
206119c5ce9cSJohan Hedberg 		return SMP_UNSPECIFIED;
206219c5ce9cSJohan Hedberg 
206319c5ce9cSJohan Hedberg 	if (hci_dev_test_flag(hdev, HCI_SC_ONLY)) {
20642064ee33SMarcel Holtmann 		bt_dev_err(hdev, "refusing legacy fallback in SC-only mode");
206519c5ce9cSJohan Hedberg 		return SMP_UNSPECIFIED;
206619c5ce9cSJohan Hedberg 	}
206719c5ce9cSJohan Hedberg 
20682064ee33SMarcel Holtmann 	bt_dev_err(hdev, "trying to fall back to legacy SMP");
206919c5ce9cSJohan Hedberg 
207019c5ce9cSJohan Hedberg 	req = (void *) &smp->preq[1];
207119c5ce9cSJohan Hedberg 	rsp = (void *) &smp->prsp[1];
207219c5ce9cSJohan Hedberg 
207319c5ce9cSJohan Hedberg 	/* Rebuild key dist flags which may have been cleared for SC */
207419c5ce9cSJohan Hedberg 	smp->remote_key_dist = (req->init_key_dist & rsp->resp_key_dist);
207519c5ce9cSJohan Hedberg 
207619c5ce9cSJohan Hedberg 	auth = req->auth_req & AUTH_REQ_MASK(hdev);
207719c5ce9cSJohan Hedberg 
207819c5ce9cSJohan Hedberg 	if (tk_request(conn, 0, auth, rsp->io_capability, req->io_capability)) {
20792064ee33SMarcel Holtmann 		bt_dev_err(hdev, "failed to fall back to legacy SMP");
208019c5ce9cSJohan Hedberg 		return SMP_UNSPECIFIED;
208119c5ce9cSJohan Hedberg 	}
208219c5ce9cSJohan Hedberg 
208319c5ce9cSJohan Hedberg 	clear_bit(SMP_FLAG_SC, &smp->flags);
208419c5ce9cSJohan Hedberg 
208519c5ce9cSJohan Hedberg 	return 0;
208619c5ce9cSJohan Hedberg }
208719c5ce9cSJohan Hedberg 
2088da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
208988ba43b6SAnderson Briglia {
20905d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
20915d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
20922e1614f7SLuiz Augusto von Dentz 	struct hci_conn *hcon = conn->hcon;
20932e1614f7SLuiz Augusto von Dentz 	struct hci_dev *hdev = hcon->hdev;
20947d24ddccSAnderson Briglia 
2095fad646e1SArchie Pusaka 	bt_dev_dbg(hdev, "conn %p %s", conn,
2096fad646e1SArchie Pusaka 		   hcon->out ? "initiator" : "responder");
209788ba43b6SAnderson Briglia 
2098c46b98beSJohan Hedberg 	if (skb->len < sizeof(smp->pcnf))
209938e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2100c46b98beSJohan Hedberg 
21011c1def09SVinicius Costa Gomes 	memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf));
21021c1def09SVinicius Costa Gomes 	skb_pull(skb, sizeof(smp->pcnf));
21037d24ddccSAnderson Briglia 
210419c5ce9cSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
210519c5ce9cSJohan Hedberg 		int ret;
210619c5ce9cSJohan Hedberg 
210719c5ce9cSJohan Hedberg 		/* Public Key exchange must happen before any other steps */
210819c5ce9cSJohan Hedberg 		if (test_bit(SMP_FLAG_REMOTE_PK, &smp->flags))
2109dcee2b32SJohan Hedberg 			return sc_check_confirm(smp);
2110dcee2b32SJohan Hedberg 
21112e1614f7SLuiz Augusto von Dentz 		bt_dev_err(hdev, "Unexpected SMP Pairing Confirm");
211219c5ce9cSJohan Hedberg 
211319c5ce9cSJohan Hedberg 		ret = fixup_sc_false_positive(smp);
211419c5ce9cSJohan Hedberg 		if (ret)
211519c5ce9cSJohan Hedberg 			return ret;
211619c5ce9cSJohan Hedberg 	}
211719c5ce9cSJohan Hedberg 
2118b28b4943SJohan Hedberg 	if (conn->hcon->out) {
2119943a732aSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
2120943a732aSJohan Hedberg 			     smp->prnd);
2121b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
2122b28b4943SJohan Hedberg 		return 0;
2123b28b4943SJohan Hedberg 	}
2124b28b4943SJohan Hedberg 
2125b28b4943SJohan Hedberg 	if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
21261cc61144SJohan Hedberg 		return smp_confirm(smp);
2127983f9814SMarcel Holtmann 
21284a74d658SJohan Hedberg 	set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
2129da85e5e5SVinicius Costa Gomes 
2130da85e5e5SVinicius Costa Gomes 	return 0;
213188ba43b6SAnderson Briglia }
213288ba43b6SAnderson Briglia 
2133da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
213488ba43b6SAnderson Briglia {
21355d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
21365d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
2137191dc7feSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
2138eed467b5SHoward Chung 	u8 *pkax, *pkbx, *na, *nb, confirm_hint;
2139191dc7feSJohan Hedberg 	u32 passkey;
2140191dc7feSJohan Hedberg 	int err;
21417d24ddccSAnderson Briglia 
21422e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hcon->hdev, "conn %p", conn);
21437d24ddccSAnderson Briglia 
2144c46b98beSJohan Hedberg 	if (skb->len < sizeof(smp->rrnd))
214538e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2146c46b98beSJohan Hedberg 
2147943a732aSJohan Hedberg 	memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd));
21488aab4757SVinicius Costa Gomes 	skb_pull(skb, sizeof(smp->rrnd));
214988ba43b6SAnderson Briglia 
2150191dc7feSJohan Hedberg 	if (!test_bit(SMP_FLAG_SC, &smp->flags))
2151861580a9SJohan Hedberg 		return smp_random(smp);
2152191dc7feSJohan Hedberg 
2153580039e8SJohan Hedberg 	if (hcon->out) {
2154580039e8SJohan Hedberg 		pkax = smp->local_pk;
2155580039e8SJohan Hedberg 		pkbx = smp->remote_pk;
2156580039e8SJohan Hedberg 		na   = smp->prnd;
2157580039e8SJohan Hedberg 		nb   = smp->rrnd;
2158580039e8SJohan Hedberg 	} else {
2159580039e8SJohan Hedberg 		pkax = smp->remote_pk;
2160580039e8SJohan Hedberg 		pkbx = smp->local_pk;
2161580039e8SJohan Hedberg 		na   = smp->rrnd;
2162580039e8SJohan Hedberg 		nb   = smp->prnd;
2163580039e8SJohan Hedberg 	}
2164580039e8SJohan Hedberg 
2165a29b0733SJohan Hedberg 	if (smp->method == REQ_OOB) {
2166a29b0733SJohan Hedberg 		if (!hcon->out)
2167a29b0733SJohan Hedberg 			smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM,
2168a29b0733SJohan Hedberg 				     sizeof(smp->prnd), smp->prnd);
2169a29b0733SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
2170a29b0733SJohan Hedberg 		goto mackey_and_ltk;
2171a29b0733SJohan Hedberg 	}
2172a29b0733SJohan Hedberg 
217338606f14SJohan Hedberg 	/* Passkey entry has special treatment */
217438606f14SJohan Hedberg 	if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY)
217538606f14SJohan Hedberg 		return sc_passkey_round(smp, SMP_CMD_PAIRING_RANDOM);
217638606f14SJohan Hedberg 
2177191dc7feSJohan Hedberg 	if (hcon->out) {
2178191dc7feSJohan Hedberg 		u8 cfm[16];
2179191dc7feSJohan Hedberg 
2180191dc7feSJohan Hedberg 		err = smp_f4(smp->tfm_cmac, smp->remote_pk, smp->local_pk,
2181191dc7feSJohan Hedberg 			     smp->rrnd, 0, cfm);
2182191dc7feSJohan Hedberg 		if (err)
2183191dc7feSJohan Hedberg 			return SMP_UNSPECIFIED;
2184191dc7feSJohan Hedberg 
2185329d8230SJason A. Donenfeld 		if (crypto_memneq(smp->pcnf, cfm, 16))
2186191dc7feSJohan Hedberg 			return SMP_CONFIRM_FAILED;
2187191dc7feSJohan Hedberg 	} else {
2188191dc7feSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
2189191dc7feSJohan Hedberg 			     smp->prnd);
2190191dc7feSJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
2191cee5f20fSHoward Chung 
2192cee5f20fSHoward Chung 		/* Only Just-Works pairing requires extra checks */
2193cee5f20fSHoward Chung 		if (smp->method != JUST_WORKS)
2194cee5f20fSHoward Chung 			goto mackey_and_ltk;
2195cee5f20fSHoward Chung 
2196cee5f20fSHoward Chung 		/* If there already exists long term key in local host, leave
2197cee5f20fSHoward Chung 		 * the decision to user space since the remote device could
2198cee5f20fSHoward Chung 		 * be legitimate or malicious.
2199cee5f20fSHoward Chung 		 */
2200cee5f20fSHoward Chung 		if (hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
2201cee5f20fSHoward Chung 				 hcon->role)) {
2202eed467b5SHoward Chung 			/* Set passkey to 0. The value can be any number since
2203eed467b5SHoward Chung 			 * it'll be ignored anyway.
2204eed467b5SHoward Chung 			 */
2205eed467b5SHoward Chung 			passkey = 0;
2206eed467b5SHoward Chung 			confirm_hint = 1;
2207eed467b5SHoward Chung 			goto confirm;
2208cee5f20fSHoward Chung 		}
2209191dc7feSJohan Hedberg 	}
2210191dc7feSJohan Hedberg 
2211a29b0733SJohan Hedberg mackey_and_ltk:
2212760b018bSJohan Hedberg 	/* Generate MacKey and LTK */
2213760b018bSJohan Hedberg 	err = sc_mackey_and_ltk(smp, smp->mackey, smp->tk);
2214760b018bSJohan Hedberg 	if (err)
2215760b018bSJohan Hedberg 		return SMP_UNSPECIFIED;
2216760b018bSJohan Hedberg 
2217ffee202aSSonny Sasaka 	if (smp->method == REQ_OOB) {
2218dddd3059SJohan Hedberg 		if (hcon->out) {
221938606f14SJohan Hedberg 			sc_dhkey_check(smp);
2220dddd3059SJohan Hedberg 			SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
2221dddd3059SJohan Hedberg 		}
2222dddd3059SJohan Hedberg 		return 0;
2223dddd3059SJohan Hedberg 	}
2224dddd3059SJohan Hedberg 
222538606f14SJohan Hedberg 	err = smp_g2(smp->tfm_cmac, pkax, pkbx, na, nb, &passkey);
2226191dc7feSJohan Hedberg 	if (err)
2227191dc7feSJohan Hedberg 		return SMP_UNSPECIFIED;
2228191dc7feSJohan Hedberg 
2229eed467b5SHoward Chung 	confirm_hint = 0;
2230eed467b5SHoward Chung 
2231eed467b5SHoward Chung confirm:
2232ffee202aSSonny Sasaka 	if (smp->method == JUST_WORKS)
2233ffee202aSSonny Sasaka 		confirm_hint = 1;
2234ffee202aSSonny Sasaka 
223538606f14SJohan Hedberg 	err = mgmt_user_confirm_request(hcon->hdev, &hcon->dst, hcon->type,
2236eed467b5SHoward Chung 					hcon->dst_type, passkey, confirm_hint);
223738606f14SJohan Hedberg 	if (err)
223838606f14SJohan Hedberg 		return SMP_UNSPECIFIED;
223938606f14SJohan Hedberg 
224038606f14SJohan Hedberg 	set_bit(SMP_FLAG_WAIT_USER, &smp->flags);
224138606f14SJohan Hedberg 
2242191dc7feSJohan Hedberg 	return 0;
224388ba43b6SAnderson Briglia }
224488ba43b6SAnderson Briglia 
2245f81cd823SMarcel Holtmann static bool smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
2246988c5997SVinicius Costa Gomes {
2247c9839a11SVinicius Costa Gomes 	struct smp_ltk *key;
2248988c5997SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
2249988c5997SVinicius Costa Gomes 
2250f3a73d97SJohan Hedberg 	key = hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, hcon->role);
2251988c5997SVinicius Costa Gomes 	if (!key)
2252f81cd823SMarcel Holtmann 		return false;
2253988c5997SVinicius Costa Gomes 
2254a6f7833cSJohan Hedberg 	if (smp_ltk_sec_level(key) < sec_level)
2255f81cd823SMarcel Holtmann 		return false;
22564dab7864SJohan Hedberg 
225751a8efd7SJohan Hedberg 	if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
2258f81cd823SMarcel Holtmann 		return true;
2259988c5997SVinicius Costa Gomes 
22608b76ce34SJohan Hedberg 	hci_le_start_enc(hcon, key->ediv, key->rand, key->val, key->enc_size);
2261c9839a11SVinicius Costa Gomes 	hcon->enc_key_size = key->enc_size;
2262988c5997SVinicius Costa Gomes 
2263fad646e1SArchie Pusaka 	/* We never store STKs for initiator role, so clear this flag */
2264fe59a05fSJohan Hedberg 	clear_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags);
2265fe59a05fSJohan Hedberg 
2266f81cd823SMarcel Holtmann 	return true;
2267988c5997SVinicius Costa Gomes }
2268f1560463SMarcel Holtmann 
226935dc6f83SJohan Hedberg bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level,
227035dc6f83SJohan Hedberg 			     enum smp_key_pref key_pref)
2271854f4727SJohan Hedberg {
2272854f4727SJohan Hedberg 	if (sec_level == BT_SECURITY_LOW)
2273854f4727SJohan Hedberg 		return true;
2274854f4727SJohan Hedberg 
227535dc6f83SJohan Hedberg 	/* If we're encrypted with an STK but the caller prefers using
227635dc6f83SJohan Hedberg 	 * LTK claim insufficient security. This way we allow the
227735dc6f83SJohan Hedberg 	 * connection to be re-encrypted with an LTK, even if the LTK
227835dc6f83SJohan Hedberg 	 * provides the same level of security. Only exception is if we
227935dc6f83SJohan Hedberg 	 * don't have an LTK (e.g. because of key distribution bits).
22809ab65d60SJohan Hedberg 	 */
228135dc6f83SJohan Hedberg 	if (key_pref == SMP_USE_LTK &&
228235dc6f83SJohan Hedberg 	    test_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags) &&
2283f3a73d97SJohan Hedberg 	    hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, hcon->role))
22849ab65d60SJohan Hedberg 		return false;
22859ab65d60SJohan Hedberg 
2286854f4727SJohan Hedberg 	if (hcon->sec_level >= sec_level)
2287854f4727SJohan Hedberg 		return true;
2288854f4727SJohan Hedberg 
2289854f4727SJohan Hedberg 	return false;
2290854f4727SJohan Hedberg }
2291854f4727SJohan Hedberg 
2292da85e5e5SVinicius Costa Gomes static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
229388ba43b6SAnderson Briglia {
229488ba43b6SAnderson Briglia 	struct smp_cmd_security_req *rp = (void *) skb->data;
229588ba43b6SAnderson Briglia 	struct smp_cmd_pairing cp;
2296f1cb9af5SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
22970edb14deSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
22988aab4757SVinicius Costa Gomes 	struct smp_chan *smp;
2299c05b9339SJohan Hedberg 	u8 sec_level, auth;
230088ba43b6SAnderson Briglia 
23012e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "conn %p", conn);
230288ba43b6SAnderson Briglia 
2303c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rp))
230438e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2305c46b98beSJohan Hedberg 
230640bef302SJohan Hedberg 	if (hcon->role != HCI_ROLE_MASTER)
230786ca9eacSJohan Hedberg 		return SMP_CMD_NOTSUPP;
230886ca9eacSJohan Hedberg 
23090edb14deSJohan Hedberg 	auth = rp->auth_req & AUTH_REQ_MASK(hdev);
2310c05b9339SJohan Hedberg 
2311d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SC_ONLY) && !(auth & SMP_AUTH_SC))
2312903b71c7SJohan Hedberg 		return SMP_AUTH_REQUIREMENTS;
2313903b71c7SJohan Hedberg 
23145be5e275SJohan Hedberg 	if (hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
23151afc2a1aSJohan Hedberg 		sec_level = BT_SECURITY_MEDIUM;
23161afc2a1aSJohan Hedberg 	else
2317c05b9339SJohan Hedberg 		sec_level = authreq_to_seclevel(auth);
23181afc2a1aSJohan Hedberg 
231964e759f5SSzymon Janc 	if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK)) {
232064e759f5SSzymon Janc 		/* If link is already encrypted with sufficient security we
232164e759f5SSzymon Janc 		 * still need refresh encryption as per Core Spec 5.0 Vol 3,
232264e759f5SSzymon Janc 		 * Part H 2.4.6
232364e759f5SSzymon Janc 		 */
232464e759f5SSzymon Janc 		smp_ltk_encrypt(conn, hcon->sec_level);
2325854f4727SJohan Hedberg 		return 0;
232664e759f5SSzymon Janc 	}
2327854f4727SJohan Hedberg 
2328c7262e71SJohan Hedberg 	if (sec_level > hcon->pending_sec_level)
2329c7262e71SJohan Hedberg 		hcon->pending_sec_level = sec_level;
2330feb45eb5SVinicius Costa Gomes 
23314dab7864SJohan Hedberg 	if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
2332988c5997SVinicius Costa Gomes 		return 0;
2333988c5997SVinicius Costa Gomes 
23348aab4757SVinicius Costa Gomes 	smp = smp_chan_create(conn);
2335c29d2444SJohan Hedberg 	if (!smp)
2336c29d2444SJohan Hedberg 		return SMP_UNSPECIFIED;
2337d26a2345SVinicius Costa Gomes 
2338d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BONDABLE) &&
2339c05b9339SJohan Hedberg 	    (auth & SMP_AUTH_BONDING))
2340616d55beSJohan Hedberg 		return SMP_PAIRING_NOTSUPP;
2341616d55beSJohan Hedberg 
234288ba43b6SAnderson Briglia 	skb_pull(skb, sizeof(*rp));
234388ba43b6SAnderson Briglia 
2344da85e5e5SVinicius Costa Gomes 	memset(&cp, 0, sizeof(cp));
2345c05b9339SJohan Hedberg 	build_pairing_cmd(conn, &cp, NULL, auth);
234688ba43b6SAnderson Briglia 
23471c1def09SVinicius Costa Gomes 	smp->preq[0] = SMP_CMD_PAIRING_REQ;
23481c1def09SVinicius Costa Gomes 	memcpy(&smp->preq[1], &cp, sizeof(cp));
2349f01ead31SAnderson Briglia 
235088ba43b6SAnderson Briglia 	smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
2351b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP);
2352f1cb9af5SVinicius Costa Gomes 
2353da85e5e5SVinicius Costa Gomes 	return 0;
235488ba43b6SAnderson Briglia }
235588ba43b6SAnderson Briglia 
2356cc110922SVinicius Costa Gomes int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
2357eb492e01SAnderson Briglia {
2358cc110922SVinicius Costa Gomes 	struct l2cap_conn *conn = hcon->l2cap_data;
2359c68b7f12SJohan Hedberg 	struct l2cap_chan *chan;
23600a66cf20SJohan Hedberg 	struct smp_chan *smp;
23612b64d153SBrian Gix 	__u8 authreq;
2362fc75cc86SJohan Hedberg 	int ret;
2363eb492e01SAnderson Briglia 
23642e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hcon->hdev, "conn %p hcon %p level 0x%2.2x", conn, hcon,
23652e1614f7SLuiz Augusto von Dentz 		   sec_level);
23663a0259bbSVinicius Costa Gomes 
23670a66cf20SJohan Hedberg 	/* This may be NULL if there's an unexpected disconnection */
23680a66cf20SJohan Hedberg 	if (!conn)
23690a66cf20SJohan Hedberg 		return 1;
23700a66cf20SJohan Hedberg 
2371d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hcon->hdev, HCI_LE_ENABLED))
23722e65c9d2SAndre Guedes 		return 1;
23732e65c9d2SAndre Guedes 
237435dc6f83SJohan Hedberg 	if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK))
2375f1cb9af5SVinicius Costa Gomes 		return 1;
2376f1cb9af5SVinicius Costa Gomes 
2377c7262e71SJohan Hedberg 	if (sec_level > hcon->pending_sec_level)
2378c7262e71SJohan Hedberg 		hcon->pending_sec_level = sec_level;
2379c7262e71SJohan Hedberg 
238040bef302SJohan Hedberg 	if (hcon->role == HCI_ROLE_MASTER)
2381c7262e71SJohan Hedberg 		if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
2382c7262e71SJohan Hedberg 			return 0;
2383d26a2345SVinicius Costa Gomes 
2384d8949aadSJohan Hedberg 	chan = conn->smp;
2385d8949aadSJohan Hedberg 	if (!chan) {
23862064ee33SMarcel Holtmann 		bt_dev_err(hcon->hdev, "security requested but not available");
2387d8949aadSJohan Hedberg 		return 1;
2388d8949aadSJohan Hedberg 	}
2389d8949aadSJohan Hedberg 
2390fc75cc86SJohan Hedberg 	l2cap_chan_lock(chan);
2391fc75cc86SJohan Hedberg 
2392fc75cc86SJohan Hedberg 	/* If SMP is already in progress ignore this request */
2393fc75cc86SJohan Hedberg 	if (chan->data) {
2394fc75cc86SJohan Hedberg 		ret = 0;
2395fc75cc86SJohan Hedberg 		goto unlock;
2396fc75cc86SJohan Hedberg 	}
2397d26a2345SVinicius Costa Gomes 
23988aab4757SVinicius Costa Gomes 	smp = smp_chan_create(conn);
2399fc75cc86SJohan Hedberg 	if (!smp) {
2400fc75cc86SJohan Hedberg 		ret = 1;
2401fc75cc86SJohan Hedberg 		goto unlock;
2402fc75cc86SJohan Hedberg 	}
24032b64d153SBrian Gix 
24042b64d153SBrian Gix 	authreq = seclevel_to_authreq(sec_level);
2405d26a2345SVinicius Costa Gomes 
2406a62da6f1SJohan Hedberg 	if (hci_dev_test_flag(hcon->hdev, HCI_SC_ENABLED)) {
2407d2eb9e10SJohan Hedberg 		authreq |= SMP_AUTH_SC;
2408a62da6f1SJohan Hedberg 		if (hci_dev_test_flag(hcon->hdev, HCI_SSP_ENABLED))
2409a62da6f1SJohan Hedberg 			authreq |= SMP_AUTH_CT2;
2410a62da6f1SJohan Hedberg 	}
2411d2eb9e10SJohan Hedberg 
2412c2aa30dbSArchie Pusaka 	/* Don't attempt to set MITM if setting is overridden by debugfs
2413c2aa30dbSArchie Pusaka 	 * Needed to pass certification test SM/MAS/PKE/BV-01-C
2414c2aa30dbSArchie Pusaka 	 */
2415c2aa30dbSArchie Pusaka 	if (!hci_dev_test_flag(hcon->hdev, HCI_FORCE_NO_MITM)) {
241679897d20SJohan Hedberg 		/* Require MITM if IO Capability allows or the security level
241779897d20SJohan Hedberg 		 * requires it.
24182e233644SJohan Hedberg 		 */
241979897d20SJohan Hedberg 		if (hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT ||
2420c7262e71SJohan Hedberg 		    hcon->pending_sec_level > BT_SECURITY_MEDIUM)
24212e233644SJohan Hedberg 			authreq |= SMP_AUTH_MITM;
2422c2aa30dbSArchie Pusaka 	}
24232e233644SJohan Hedberg 
242440bef302SJohan Hedberg 	if (hcon->role == HCI_ROLE_MASTER) {
2425d26a2345SVinicius Costa Gomes 		struct smp_cmd_pairing cp;
2426f01ead31SAnderson Briglia 
24272b64d153SBrian Gix 		build_pairing_cmd(conn, &cp, NULL, authreq);
24281c1def09SVinicius Costa Gomes 		smp->preq[0] = SMP_CMD_PAIRING_REQ;
24291c1def09SVinicius Costa Gomes 		memcpy(&smp->preq[1], &cp, sizeof(cp));
2430f01ead31SAnderson Briglia 
2431eb492e01SAnderson Briglia 		smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
2432b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP);
2433eb492e01SAnderson Briglia 	} else {
2434eb492e01SAnderson Briglia 		struct smp_cmd_security_req cp;
24352b64d153SBrian Gix 		cp.auth_req = authreq;
2436eb492e01SAnderson Briglia 		smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
2437b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_REQ);
2438eb492e01SAnderson Briglia 	}
2439eb492e01SAnderson Briglia 
24404a74d658SJohan Hedberg 	set_bit(SMP_FLAG_INITIATOR, &smp->flags);
2441fc75cc86SJohan Hedberg 	ret = 0;
2442edca792cSJohan Hedberg 
2443fc75cc86SJohan Hedberg unlock:
2444fc75cc86SJohan Hedberg 	l2cap_chan_unlock(chan);
2445fc75cc86SJohan Hedberg 	return ret;
2446eb492e01SAnderson Briglia }
2447eb492e01SAnderson Briglia 
2448cb28c306SMatias Karhumaa int smp_cancel_and_remove_pairing(struct hci_dev *hdev, bdaddr_t *bdaddr,
2449cb28c306SMatias Karhumaa 				  u8 addr_type)
2450c81d555aSJohan Hedberg {
2451cb28c306SMatias Karhumaa 	struct hci_conn *hcon;
2452cb28c306SMatias Karhumaa 	struct l2cap_conn *conn;
2453c81d555aSJohan Hedberg 	struct l2cap_chan *chan;
2454c81d555aSJohan Hedberg 	struct smp_chan *smp;
2455cb28c306SMatias Karhumaa 	int err;
2456c81d555aSJohan Hedberg 
2457cb28c306SMatias Karhumaa 	err = hci_remove_ltk(hdev, bdaddr, addr_type);
2458cb28c306SMatias Karhumaa 	hci_remove_irk(hdev, bdaddr, addr_type);
2459cb28c306SMatias Karhumaa 
2460cb28c306SMatias Karhumaa 	hcon = hci_conn_hash_lookup_le(hdev, bdaddr, addr_type);
2461cb28c306SMatias Karhumaa 	if (!hcon)
2462cb28c306SMatias Karhumaa 		goto done;
2463cb28c306SMatias Karhumaa 
2464cb28c306SMatias Karhumaa 	conn = hcon->l2cap_data;
2465c81d555aSJohan Hedberg 	if (!conn)
2466cb28c306SMatias Karhumaa 		goto done;
2467c81d555aSJohan Hedberg 
2468c81d555aSJohan Hedberg 	chan = conn->smp;
2469c81d555aSJohan Hedberg 	if (!chan)
2470cb28c306SMatias Karhumaa 		goto done;
2471c81d555aSJohan Hedberg 
2472c81d555aSJohan Hedberg 	l2cap_chan_lock(chan);
2473c81d555aSJohan Hedberg 
2474c81d555aSJohan Hedberg 	smp = chan->data;
2475c81d555aSJohan Hedberg 	if (smp) {
2476cb28c306SMatias Karhumaa 		/* Set keys to NULL to make sure smp_failure() does not try to
2477cb28c306SMatias Karhumaa 		 * remove and free already invalidated rcu list entries. */
2478cb28c306SMatias Karhumaa 		smp->ltk = NULL;
2479fad646e1SArchie Pusaka 		smp->responder_ltk = NULL;
2480cb28c306SMatias Karhumaa 		smp->remote_irk = NULL;
2481cb28c306SMatias Karhumaa 
2482c81d555aSJohan Hedberg 		if (test_bit(SMP_FLAG_COMPLETE, &smp->flags))
2483c81d555aSJohan Hedberg 			smp_failure(conn, 0);
2484c81d555aSJohan Hedberg 		else
2485c81d555aSJohan Hedberg 			smp_failure(conn, SMP_UNSPECIFIED);
2486cb28c306SMatias Karhumaa 		err = 0;
2487c81d555aSJohan Hedberg 	}
2488c81d555aSJohan Hedberg 
2489c81d555aSJohan Hedberg 	l2cap_chan_unlock(chan);
2490cb28c306SMatias Karhumaa 
2491cb28c306SMatias Karhumaa done:
2492cb28c306SMatias Karhumaa 	return err;
2493c81d555aSJohan Hedberg }
2494c81d555aSJohan Hedberg 
24957034b911SVinicius Costa Gomes static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
24967034b911SVinicius Costa Gomes {
249716b90839SVinicius Costa Gomes 	struct smp_cmd_encrypt_info *rp = (void *) skb->data;
24985d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
24995d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
250016b90839SVinicius Costa Gomes 
25012e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(conn->hcon->hdev, "conn %p", conn);
2502c46b98beSJohan Hedberg 
2503c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rp))
250438e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2505c46b98beSJohan Hedberg 
2506600a8749SAlain Michaud 	/* Pairing is aborted if any blocked keys are distributed */
2507600a8749SAlain Michaud 	if (hci_is_blocked_key(conn->hcon->hdev, HCI_BLOCKED_KEY_TYPE_LTK,
2508600a8749SAlain Michaud 			       rp->ltk)) {
2509600a8749SAlain Michaud 		bt_dev_warn_ratelimited(conn->hcon->hdev,
2510600a8749SAlain Michaud 					"LTK blocked for %pMR",
2511600a8749SAlain Michaud 					&conn->hcon->dst);
2512600a8749SAlain Michaud 		return SMP_INVALID_PARAMS;
2513600a8749SAlain Michaud 	}
2514600a8749SAlain Michaud 
2515fad646e1SArchie Pusaka 	SMP_ALLOW_CMD(smp, SMP_CMD_INITIATOR_IDENT);
25166131ddc8SJohan Hedberg 
251716b90839SVinicius Costa Gomes 	skb_pull(skb, sizeof(*rp));
251816b90839SVinicius Costa Gomes 
25191c1def09SVinicius Costa Gomes 	memcpy(smp->tk, rp->ltk, sizeof(smp->tk));
252016b90839SVinicius Costa Gomes 
25217034b911SVinicius Costa Gomes 	return 0;
25227034b911SVinicius Costa Gomes }
25237034b911SVinicius Costa Gomes 
2524fad646e1SArchie Pusaka static int smp_cmd_initiator_ident(struct l2cap_conn *conn, struct sk_buff *skb)
25257034b911SVinicius Costa Gomes {
2526fad646e1SArchie Pusaka 	struct smp_cmd_initiator_ident *rp = (void *)skb->data;
25275d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
25285d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
2529c9839a11SVinicius Costa Gomes 	struct hci_dev *hdev = conn->hcon->hdev;
2530c9839a11SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
253123d0e128SJohan Hedberg 	struct smp_ltk *ltk;
2532c9839a11SVinicius Costa Gomes 	u8 authenticated;
25337034b911SVinicius Costa Gomes 
25342e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "conn %p", conn);
2535c46b98beSJohan Hedberg 
2536c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rp))
253738e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2538c46b98beSJohan Hedberg 
25399747a9f3SJohan Hedberg 	/* Mark the information as received */
25409747a9f3SJohan Hedberg 	smp->remote_key_dist &= ~SMP_DIST_ENC_KEY;
25419747a9f3SJohan Hedberg 
2542b28b4943SJohan Hedberg 	if (smp->remote_key_dist & SMP_DIST_ID_KEY)
2543b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO);
2544196332f5SJohan Hedberg 	else if (smp->remote_key_dist & SMP_DIST_SIGN)
2545196332f5SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO);
2546b28b4943SJohan Hedberg 
254716b90839SVinicius Costa Gomes 	skb_pull(skb, sizeof(*rp));
254816b90839SVinicius Costa Gomes 
2549ce39fb4eSMarcel Holtmann 	authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
25502ceba539SJohan Hedberg 	ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, SMP_LTK,
2551ce39fb4eSMarcel Holtmann 			  authenticated, smp->tk, smp->enc_key_size,
255204124681SGustavo F. Padovan 			  rp->ediv, rp->rand);
255323d0e128SJohan Hedberg 	smp->ltk = ltk;
2554c6e81e9aSJohan Hedberg 	if (!(smp->remote_key_dist & KEY_DIST_MASK))
2555d6268e86SJohan Hedberg 		smp_distribute_keys(smp);
25567034b911SVinicius Costa Gomes 
25577034b911SVinicius Costa Gomes 	return 0;
25587034b911SVinicius Costa Gomes }
25597034b911SVinicius Costa Gomes 
2560fd349c02SJohan Hedberg static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
2561fd349c02SJohan Hedberg {
2562fd349c02SJohan Hedberg 	struct smp_cmd_ident_info *info = (void *) skb->data;
25635d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
25645d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
2565fd349c02SJohan Hedberg 
25662e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(conn->hcon->hdev, "");
2567fd349c02SJohan Hedberg 
2568fd349c02SJohan Hedberg 	if (skb->len < sizeof(*info))
256938e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2570fd349c02SJohan Hedberg 
2571600a8749SAlain Michaud 	/* Pairing is aborted if any blocked keys are distributed */
2572600a8749SAlain Michaud 	if (hci_is_blocked_key(conn->hcon->hdev, HCI_BLOCKED_KEY_TYPE_IRK,
2573600a8749SAlain Michaud 			       info->irk)) {
2574600a8749SAlain Michaud 		bt_dev_warn_ratelimited(conn->hcon->hdev,
2575600a8749SAlain Michaud 					"Identity key blocked for %pMR",
2576600a8749SAlain Michaud 					&conn->hcon->dst);
2577600a8749SAlain Michaud 		return SMP_INVALID_PARAMS;
2578600a8749SAlain Michaud 	}
2579600a8749SAlain Michaud 
2580b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_ADDR_INFO);
25816131ddc8SJohan Hedberg 
2582fd349c02SJohan Hedberg 	skb_pull(skb, sizeof(*info));
2583fd349c02SJohan Hedberg 
2584fd349c02SJohan Hedberg 	memcpy(smp->irk, info->irk, 16);
2585fd349c02SJohan Hedberg 
2586fd349c02SJohan Hedberg 	return 0;
2587fd349c02SJohan Hedberg }
2588fd349c02SJohan Hedberg 
2589fd349c02SJohan Hedberg static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
2590fd349c02SJohan Hedberg 				   struct sk_buff *skb)
2591fd349c02SJohan Hedberg {
2592fd349c02SJohan Hedberg 	struct smp_cmd_ident_addr_info *info = (void *) skb->data;
25935d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
25945d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
2595fd349c02SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
2596fd349c02SJohan Hedberg 	bdaddr_t rpa;
2597fd349c02SJohan Hedberg 
25982e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hcon->hdev, "");
2599fd349c02SJohan Hedberg 
2600fd349c02SJohan Hedberg 	if (skb->len < sizeof(*info))
260138e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2602fd349c02SJohan Hedberg 
26039747a9f3SJohan Hedberg 	/* Mark the information as received */
26049747a9f3SJohan Hedberg 	smp->remote_key_dist &= ~SMP_DIST_ID_KEY;
26059747a9f3SJohan Hedberg 
2606b28b4943SJohan Hedberg 	if (smp->remote_key_dist & SMP_DIST_SIGN)
2607b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO);
2608b28b4943SJohan Hedberg 
2609fd349c02SJohan Hedberg 	skb_pull(skb, sizeof(*info));
2610fd349c02SJohan Hedberg 
2611a9a58f86SJohan Hedberg 	/* Strictly speaking the Core Specification (4.1) allows sending
2612a9a58f86SJohan Hedberg 	 * an empty address which would force us to rely on just the IRK
2613a9a58f86SJohan Hedberg 	 * as "identity information". However, since such
2614a9a58f86SJohan Hedberg 	 * implementations are not known of and in order to not over
2615a9a58f86SJohan Hedberg 	 * complicate our implementation, simply pretend that we never
2616a9a58f86SJohan Hedberg 	 * received an IRK for such a device.
2617e12af489SJohan Hedberg 	 *
2618e12af489SJohan Hedberg 	 * The Identity Address must also be a Static Random or Public
2619e12af489SJohan Hedberg 	 * Address, which hci_is_identity_address() checks for.
2620a9a58f86SJohan Hedberg 	 */
2621e12af489SJohan Hedberg 	if (!bacmp(&info->bdaddr, BDADDR_ANY) ||
2622e12af489SJohan Hedberg 	    !hci_is_identity_address(&info->bdaddr, info->addr_type)) {
26232064ee33SMarcel Holtmann 		bt_dev_err(hcon->hdev, "ignoring IRK with no identity address");
262431dd624eSJohan Hedberg 		goto distribute;
2625a9a58f86SJohan Hedberg 	}
2626a9a58f86SJohan Hedberg 
26271d87b88bSSzymon Janc 	/* Drop IRK if peer is using identity address during pairing but is
26281d87b88bSSzymon Janc 	 * providing different address as identity information.
26291d87b88bSSzymon Janc 	 *
26301d87b88bSSzymon Janc 	 * Microsoft Surface Precision Mouse is known to have this bug.
26311d87b88bSSzymon Janc 	 */
26321d87b88bSSzymon Janc 	if (hci_is_identity_address(&hcon->dst, hcon->dst_type) &&
26331d87b88bSSzymon Janc 	    (bacmp(&info->bdaddr, &hcon->dst) ||
26341d87b88bSSzymon Janc 	     info->addr_type != hcon->dst_type)) {
26351d87b88bSSzymon Janc 		bt_dev_err(hcon->hdev,
26361d87b88bSSzymon Janc 			   "ignoring IRK with invalid identity address");
26371d87b88bSSzymon Janc 		goto distribute;
26381d87b88bSSzymon Janc 	}
26391d87b88bSSzymon Janc 
2640fd349c02SJohan Hedberg 	bacpy(&smp->id_addr, &info->bdaddr);
2641fd349c02SJohan Hedberg 	smp->id_addr_type = info->addr_type;
2642fd349c02SJohan Hedberg 
2643fd349c02SJohan Hedberg 	if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type))
2644fd349c02SJohan Hedberg 		bacpy(&rpa, &hcon->dst);
2645fd349c02SJohan Hedberg 	else
2646fd349c02SJohan Hedberg 		bacpy(&rpa, BDADDR_ANY);
2647fd349c02SJohan Hedberg 
264823d0e128SJohan Hedberg 	smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
264923d0e128SJohan Hedberg 				      smp->id_addr_type, smp->irk, &rpa);
2650fd349c02SJohan Hedberg 
265131dd624eSJohan Hedberg distribute:
2652c6e81e9aSJohan Hedberg 	if (!(smp->remote_key_dist & KEY_DIST_MASK))
2653d6268e86SJohan Hedberg 		smp_distribute_keys(smp);
2654fd349c02SJohan Hedberg 
2655fd349c02SJohan Hedberg 	return 0;
2656fd349c02SJohan Hedberg }
2657fd349c02SJohan Hedberg 
26587ee4ea36SMarcel Holtmann static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)
26597ee4ea36SMarcel Holtmann {
26607ee4ea36SMarcel Holtmann 	struct smp_cmd_sign_info *rp = (void *) skb->data;
26615d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
26625d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
26637ee4ea36SMarcel Holtmann 	struct smp_csrk *csrk;
26647ee4ea36SMarcel Holtmann 
26652e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(conn->hcon->hdev, "conn %p", conn);
26667ee4ea36SMarcel Holtmann 
26677ee4ea36SMarcel Holtmann 	if (skb->len < sizeof(*rp))
266838e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
26697ee4ea36SMarcel Holtmann 
26707ee4ea36SMarcel Holtmann 	/* Mark the information as received */
26717ee4ea36SMarcel Holtmann 	smp->remote_key_dist &= ~SMP_DIST_SIGN;
26727ee4ea36SMarcel Holtmann 
26737ee4ea36SMarcel Holtmann 	skb_pull(skb, sizeof(*rp));
26747ee4ea36SMarcel Holtmann 
26757ee4ea36SMarcel Holtmann 	csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
26767ee4ea36SMarcel Holtmann 	if (csrk) {
26774cd3928aSJohan Hedberg 		if (conn->hcon->sec_level > BT_SECURITY_MEDIUM)
26784cd3928aSJohan Hedberg 			csrk->type = MGMT_CSRK_REMOTE_AUTHENTICATED;
26794cd3928aSJohan Hedberg 		else
26804cd3928aSJohan Hedberg 			csrk->type = MGMT_CSRK_REMOTE_UNAUTHENTICATED;
26817ee4ea36SMarcel Holtmann 		memcpy(csrk->val, rp->csrk, sizeof(csrk->val));
26827ee4ea36SMarcel Holtmann 	}
26837ee4ea36SMarcel Holtmann 	smp->csrk = csrk;
2684d6268e86SJohan Hedberg 	smp_distribute_keys(smp);
26857ee4ea36SMarcel Holtmann 
26867ee4ea36SMarcel Holtmann 	return 0;
26877ee4ea36SMarcel Holtmann }
26887ee4ea36SMarcel Holtmann 
26895e3d3d9bSJohan Hedberg static u8 sc_select_method(struct smp_chan *smp)
26905e3d3d9bSJohan Hedberg {
26915e3d3d9bSJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
26925e3d3d9bSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
26935e3d3d9bSJohan Hedberg 	struct smp_cmd_pairing *local, *remote;
26945e3d3d9bSJohan Hedberg 	u8 local_mitm, remote_mitm, local_io, remote_io, method;
26955e3d3d9bSJohan Hedberg 
26961a8bab4fSJohan Hedberg 	if (test_bit(SMP_FLAG_REMOTE_OOB, &smp->flags) ||
26971a8bab4fSJohan Hedberg 	    test_bit(SMP_FLAG_LOCAL_OOB, &smp->flags))
2698a29b0733SJohan Hedberg 		return REQ_OOB;
2699a29b0733SJohan Hedberg 
27005e3d3d9bSJohan Hedberg 	/* The preq/prsp contain the raw Pairing Request/Response PDUs
27015e3d3d9bSJohan Hedberg 	 * which are needed as inputs to some crypto functions. To get
27025e3d3d9bSJohan Hedberg 	 * the "struct smp_cmd_pairing" from them we need to skip the
27035e3d3d9bSJohan Hedberg 	 * first byte which contains the opcode.
27045e3d3d9bSJohan Hedberg 	 */
27055e3d3d9bSJohan Hedberg 	if (hcon->out) {
27065e3d3d9bSJohan Hedberg 		local = (void *) &smp->preq[1];
27075e3d3d9bSJohan Hedberg 		remote = (void *) &smp->prsp[1];
27085e3d3d9bSJohan Hedberg 	} else {
27095e3d3d9bSJohan Hedberg 		local = (void *) &smp->prsp[1];
27105e3d3d9bSJohan Hedberg 		remote = (void *) &smp->preq[1];
27115e3d3d9bSJohan Hedberg 	}
27125e3d3d9bSJohan Hedberg 
27135e3d3d9bSJohan Hedberg 	local_io = local->io_capability;
27145e3d3d9bSJohan Hedberg 	remote_io = remote->io_capability;
27155e3d3d9bSJohan Hedberg 
27165e3d3d9bSJohan Hedberg 	local_mitm = (local->auth_req & SMP_AUTH_MITM);
27175e3d3d9bSJohan Hedberg 	remote_mitm = (remote->auth_req & SMP_AUTH_MITM);
27185e3d3d9bSJohan Hedberg 
27195e3d3d9bSJohan Hedberg 	/* If either side wants MITM, look up the method from the table,
27205e3d3d9bSJohan Hedberg 	 * otherwise use JUST WORKS.
27215e3d3d9bSJohan Hedberg 	 */
27225e3d3d9bSJohan Hedberg 	if (local_mitm || remote_mitm)
27235e3d3d9bSJohan Hedberg 		method = get_auth_method(smp, local_io, remote_io);
27245e3d3d9bSJohan Hedberg 	else
27255e3d3d9bSJohan Hedberg 		method = JUST_WORKS;
27265e3d3d9bSJohan Hedberg 
27275e3d3d9bSJohan Hedberg 	/* Don't confirm locally initiated pairing attempts */
27285e3d3d9bSJohan Hedberg 	if (method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR, &smp->flags))
27295e3d3d9bSJohan Hedberg 		method = JUST_WORKS;
27305e3d3d9bSJohan Hedberg 
27315e3d3d9bSJohan Hedberg 	return method;
27325e3d3d9bSJohan Hedberg }
27335e3d3d9bSJohan Hedberg 
2734d8f8edbeSJohan Hedberg static int smp_cmd_public_key(struct l2cap_conn *conn, struct sk_buff *skb)
2735d8f8edbeSJohan Hedberg {
2736d8f8edbeSJohan Hedberg 	struct smp_cmd_public_key *key = (void *) skb->data;
2737d8f8edbeSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
2738d8f8edbeSJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
2739d8f8edbeSJohan Hedberg 	struct smp_chan *smp = chan->data;
27405e3d3d9bSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
2741c0153b0bSTudor Ambarus 	struct crypto_kpp *tfm_ecdh;
2742cbbbe3e2SJohan Hedberg 	struct smp_cmd_pairing_confirm cfm;
2743d8f8edbeSJohan Hedberg 	int err;
2744d8f8edbeSJohan Hedberg 
27452e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "conn %p", conn);
2746d8f8edbeSJohan Hedberg 
2747d8f8edbeSJohan Hedberg 	if (skb->len < sizeof(*key))
2748d8f8edbeSJohan Hedberg 		return SMP_INVALID_PARAMS;
2749d8f8edbeSJohan Hedberg 
27506d19628fSLuiz Augusto von Dentz 	/* Check if remote and local public keys are the same and debug key is
27516d19628fSLuiz Augusto von Dentz 	 * not in use.
27526d19628fSLuiz Augusto von Dentz 	 */
27536d19628fSLuiz Augusto von Dentz 	if (!test_bit(SMP_FLAG_DEBUG_KEY, &smp->flags) &&
27546d19628fSLuiz Augusto von Dentz 	    !crypto_memneq(key, smp->local_pk, 64)) {
27556d19628fSLuiz Augusto von Dentz 		bt_dev_err(hdev, "Remote and local public keys are identical");
27566d19628fSLuiz Augusto von Dentz 		return SMP_UNSPECIFIED;
27576d19628fSLuiz Augusto von Dentz 	}
27586d19628fSLuiz Augusto von Dentz 
2759d8f8edbeSJohan Hedberg 	memcpy(smp->remote_pk, key, 64);
2760d8f8edbeSJohan Hedberg 
2761a8ca617cSJohan Hedberg 	if (test_bit(SMP_FLAG_REMOTE_OOB, &smp->flags)) {
2762a8ca617cSJohan Hedberg 		err = smp_f4(smp->tfm_cmac, smp->remote_pk, smp->remote_pk,
2763a8ca617cSJohan Hedberg 			     smp->rr, 0, cfm.confirm_val);
2764a8ca617cSJohan Hedberg 		if (err)
2765a8ca617cSJohan Hedberg 			return SMP_UNSPECIFIED;
2766a8ca617cSJohan Hedberg 
2767329d8230SJason A. Donenfeld 		if (crypto_memneq(cfm.confirm_val, smp->pcnf, 16))
2768a8ca617cSJohan Hedberg 			return SMP_CONFIRM_FAILED;
2769a8ca617cSJohan Hedberg 	}
2770a8ca617cSJohan Hedberg 
2771d8f8edbeSJohan Hedberg 	/* Non-initiating device sends its public key after receiving
2772d8f8edbeSJohan Hedberg 	 * the key from the initiating device.
2773d8f8edbeSJohan Hedberg 	 */
2774d8f8edbeSJohan Hedberg 	if (!hcon->out) {
2775d8f8edbeSJohan Hedberg 		err = sc_send_public_key(smp);
2776d8f8edbeSJohan Hedberg 		if (err)
2777d8f8edbeSJohan Hedberg 			return err;
2778d8f8edbeSJohan Hedberg 	}
2779d8f8edbeSJohan Hedberg 
2780c7a3d57dSJohan Hedberg 	SMP_DBG("Remote Public Key X: %32phN", smp->remote_pk);
2781e091526dSMarcel Holtmann 	SMP_DBG("Remote Public Key Y: %32phN", smp->remote_pk + 32);
2782d8f8edbeSJohan Hedberg 
2783c0153b0bSTudor Ambarus 	/* Compute the shared secret on the same crypto tfm on which the private
2784c0153b0bSTudor Ambarus 	 * key was set/generated.
2785c0153b0bSTudor Ambarus 	 */
2786c0153b0bSTudor Ambarus 	if (test_bit(SMP_FLAG_LOCAL_OOB, &smp->flags)) {
27874ba5175fSMatias Karhumaa 		struct l2cap_chan *hchan = hdev->smp_data;
27884ba5175fSMatias Karhumaa 		struct smp_dev *smp_dev;
27894ba5175fSMatias Karhumaa 
27904ba5175fSMatias Karhumaa 		if (!hchan || !hchan->data)
27914ba5175fSMatias Karhumaa 			return SMP_UNSPECIFIED;
27924ba5175fSMatias Karhumaa 
27934ba5175fSMatias Karhumaa 		smp_dev = hchan->data;
2794c0153b0bSTudor Ambarus 
2795c0153b0bSTudor Ambarus 		tfm_ecdh = smp_dev->tfm_ecdh;
2796c0153b0bSTudor Ambarus 	} else {
2797c0153b0bSTudor Ambarus 		tfm_ecdh = smp->tfm_ecdh;
2798c0153b0bSTudor Ambarus 	}
2799c0153b0bSTudor Ambarus 
2800c0153b0bSTudor Ambarus 	if (compute_ecdh_secret(tfm_ecdh, smp->remote_pk, smp->dhkey))
2801d8f8edbeSJohan Hedberg 		return SMP_UNSPECIFIED;
2802d8f8edbeSJohan Hedberg 
2803c7a3d57dSJohan Hedberg 	SMP_DBG("DHKey %32phN", smp->dhkey);
2804d8f8edbeSJohan Hedberg 
2805d8f8edbeSJohan Hedberg 	set_bit(SMP_FLAG_REMOTE_PK, &smp->flags);
2806d8f8edbeSJohan Hedberg 
28075e3d3d9bSJohan Hedberg 	smp->method = sc_select_method(smp);
28085e3d3d9bSJohan Hedberg 
28092e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "selected method 0x%02x", smp->method);
28105e3d3d9bSJohan Hedberg 
28115e3d3d9bSJohan Hedberg 	/* JUST_WORKS and JUST_CFM result in an unauthenticated key */
28125e3d3d9bSJohan Hedberg 	if (smp->method == JUST_WORKS || smp->method == JUST_CFM)
28135e3d3d9bSJohan Hedberg 		hcon->pending_sec_level = BT_SECURITY_MEDIUM;
28145e3d3d9bSJohan Hedberg 	else
28155e3d3d9bSJohan Hedberg 		hcon->pending_sec_level = BT_SECURITY_FIPS;
28165e3d3d9bSJohan Hedberg 
2817329d8230SJason A. Donenfeld 	if (!crypto_memneq(debug_pk, smp->remote_pk, 64))
2818aeb7d461SJohan Hedberg 		set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags);
2819aeb7d461SJohan Hedberg 
282038606f14SJohan Hedberg 	if (smp->method == DSP_PASSKEY) {
282138606f14SJohan Hedberg 		get_random_bytes(&hcon->passkey_notify,
282238606f14SJohan Hedberg 				 sizeof(hcon->passkey_notify));
282338606f14SJohan Hedberg 		hcon->passkey_notify %= 1000000;
282438606f14SJohan Hedberg 		hcon->passkey_entered = 0;
282538606f14SJohan Hedberg 		smp->passkey_round = 0;
282638606f14SJohan Hedberg 		if (mgmt_user_passkey_notify(hdev, &hcon->dst, hcon->type,
282738606f14SJohan Hedberg 					     hcon->dst_type,
282838606f14SJohan Hedberg 					     hcon->passkey_notify,
282938606f14SJohan Hedberg 					     hcon->passkey_entered))
283038606f14SJohan Hedberg 			return SMP_UNSPECIFIED;
283138606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
283238606f14SJohan Hedberg 		return sc_passkey_round(smp, SMP_CMD_PUBLIC_KEY);
283338606f14SJohan Hedberg 	}
283438606f14SJohan Hedberg 
283594ea7257SJohan Hedberg 	if (smp->method == REQ_OOB) {
2836a29b0733SJohan Hedberg 		if (hcon->out)
2837a29b0733SJohan Hedberg 			smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM,
2838a29b0733SJohan Hedberg 				     sizeof(smp->prnd), smp->prnd);
2839a29b0733SJohan Hedberg 
2840a29b0733SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
2841a29b0733SJohan Hedberg 
2842a29b0733SJohan Hedberg 		return 0;
2843a29b0733SJohan Hedberg 	}
2844a29b0733SJohan Hedberg 
284538606f14SJohan Hedberg 	if (hcon->out)
284638606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
284738606f14SJohan Hedberg 
284838606f14SJohan Hedberg 	if (smp->method == REQ_PASSKEY) {
284938606f14SJohan Hedberg 		if (mgmt_user_passkey_request(hdev, &hcon->dst, hcon->type,
285038606f14SJohan Hedberg 					      hcon->dst_type))
285138606f14SJohan Hedberg 			return SMP_UNSPECIFIED;
285238606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
285338606f14SJohan Hedberg 		set_bit(SMP_FLAG_WAIT_USER, &smp->flags);
285438606f14SJohan Hedberg 		return 0;
285538606f14SJohan Hedberg 	}
285638606f14SJohan Hedberg 
2857cbbbe3e2SJohan Hedberg 	/* The Initiating device waits for the non-initiating device to
2858cbbbe3e2SJohan Hedberg 	 * send the confirm value.
2859cbbbe3e2SJohan Hedberg 	 */
2860cbbbe3e2SJohan Hedberg 	if (conn->hcon->out)
2861cbbbe3e2SJohan Hedberg 		return 0;
2862cbbbe3e2SJohan Hedberg 
2863cbbbe3e2SJohan Hedberg 	err = smp_f4(smp->tfm_cmac, smp->local_pk, smp->remote_pk, smp->prnd,
2864cbbbe3e2SJohan Hedberg 		     0, cfm.confirm_val);
2865cbbbe3e2SJohan Hedberg 	if (err)
2866cbbbe3e2SJohan Hedberg 		return SMP_UNSPECIFIED;
2867cbbbe3e2SJohan Hedberg 
2868cbbbe3e2SJohan Hedberg 	smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cfm), &cfm);
2869cbbbe3e2SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
2870cbbbe3e2SJohan Hedberg 
2871d8f8edbeSJohan Hedberg 	return 0;
2872d8f8edbeSJohan Hedberg }
2873d8f8edbeSJohan Hedberg 
28746433a9a2SJohan Hedberg static int smp_cmd_dhkey_check(struct l2cap_conn *conn, struct sk_buff *skb)
28756433a9a2SJohan Hedberg {
28766433a9a2SJohan Hedberg 	struct smp_cmd_dhkey_check *check = (void *) skb->data;
28776433a9a2SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
28786433a9a2SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
28796433a9a2SJohan Hedberg 	struct smp_chan *smp = chan->data;
28806433a9a2SJohan Hedberg 	u8 a[7], b[7], *local_addr, *remote_addr;
28816433a9a2SJohan Hedberg 	u8 io_cap[3], r[16], e[16];
28826433a9a2SJohan Hedberg 	int err;
28836433a9a2SJohan Hedberg 
28842e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hcon->hdev, "conn %p", conn);
28856433a9a2SJohan Hedberg 
28866433a9a2SJohan Hedberg 	if (skb->len < sizeof(*check))
28876433a9a2SJohan Hedberg 		return SMP_INVALID_PARAMS;
28886433a9a2SJohan Hedberg 
28896433a9a2SJohan Hedberg 	memcpy(a, &hcon->init_addr, 6);
28906433a9a2SJohan Hedberg 	memcpy(b, &hcon->resp_addr, 6);
28916433a9a2SJohan Hedberg 	a[6] = hcon->init_addr_type;
28926433a9a2SJohan Hedberg 	b[6] = hcon->resp_addr_type;
28936433a9a2SJohan Hedberg 
28946433a9a2SJohan Hedberg 	if (hcon->out) {
28956433a9a2SJohan Hedberg 		local_addr = a;
28966433a9a2SJohan Hedberg 		remote_addr = b;
28976433a9a2SJohan Hedberg 		memcpy(io_cap, &smp->prsp[1], 3);
28986433a9a2SJohan Hedberg 	} else {
28996433a9a2SJohan Hedberg 		local_addr = b;
29006433a9a2SJohan Hedberg 		remote_addr = a;
29016433a9a2SJohan Hedberg 		memcpy(io_cap, &smp->preq[1], 3);
29026433a9a2SJohan Hedberg 	}
29036433a9a2SJohan Hedberg 
29046433a9a2SJohan Hedberg 	memset(r, 0, sizeof(r));
29056433a9a2SJohan Hedberg 
290638606f14SJohan Hedberg 	if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY)
290738606f14SJohan Hedberg 		put_unaligned_le32(hcon->passkey_notify, r);
2908882fafadSJohan Hedberg 	else if (smp->method == REQ_OOB)
2909882fafadSJohan Hedberg 		memcpy(r, smp->lr, 16);
291038606f14SJohan Hedberg 
29116433a9a2SJohan Hedberg 	err = smp_f6(smp->tfm_cmac, smp->mackey, smp->rrnd, smp->prnd, r,
29126433a9a2SJohan Hedberg 		     io_cap, remote_addr, local_addr, e);
29136433a9a2SJohan Hedberg 	if (err)
29146433a9a2SJohan Hedberg 		return SMP_UNSPECIFIED;
29156433a9a2SJohan Hedberg 
2916329d8230SJason A. Donenfeld 	if (crypto_memneq(check->e, e, 16))
29176433a9a2SJohan Hedberg 		return SMP_DHKEY_CHECK_FAILED;
29186433a9a2SJohan Hedberg 
2919d3e54a87SJohan Hedberg 	if (!hcon->out) {
2920d3e54a87SJohan Hedberg 		if (test_bit(SMP_FLAG_WAIT_USER, &smp->flags)) {
2921d3e54a87SJohan Hedberg 			set_bit(SMP_FLAG_DHKEY_PENDING, &smp->flags);
2922d3e54a87SJohan Hedberg 			return 0;
2923d3e54a87SJohan Hedberg 		}
2924d378a2d7SJohan Hedberg 
2925fad646e1SArchie Pusaka 		/* Responder sends DHKey check as response to initiator */
2926d3e54a87SJohan Hedberg 		sc_dhkey_check(smp);
2927d3e54a87SJohan Hedberg 	}
2928d378a2d7SJohan Hedberg 
2929d3e54a87SJohan Hedberg 	sc_add_ltk(smp);
29306433a9a2SJohan Hedberg 
29316433a9a2SJohan Hedberg 	if (hcon->out) {
29328b76ce34SJohan Hedberg 		hci_le_start_enc(hcon, 0, 0, smp->tk, smp->enc_key_size);
29336433a9a2SJohan Hedberg 		hcon->enc_key_size = smp->enc_key_size;
29346433a9a2SJohan Hedberg 	}
29356433a9a2SJohan Hedberg 
29366433a9a2SJohan Hedberg 	return 0;
29376433a9a2SJohan Hedberg }
29386433a9a2SJohan Hedberg 
29391408bb6eSJohan Hedberg static int smp_cmd_keypress_notify(struct l2cap_conn *conn,
29401408bb6eSJohan Hedberg 				   struct sk_buff *skb)
29411408bb6eSJohan Hedberg {
29421408bb6eSJohan Hedberg 	struct smp_cmd_keypress_notify *kp = (void *) skb->data;
29431408bb6eSJohan Hedberg 
29442e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(conn->hcon->hdev, "value 0x%02x", kp->value);
29451408bb6eSJohan Hedberg 
29461408bb6eSJohan Hedberg 	return 0;
29471408bb6eSJohan Hedberg }
29481408bb6eSJohan Hedberg 
29494befb867SJohan Hedberg static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb)
2950eb492e01SAnderson Briglia {
29515d88cc73SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
29527b9899dbSMarcel Holtmann 	struct hci_conn *hcon = conn->hcon;
2953b28b4943SJohan Hedberg 	struct smp_chan *smp;
295492381f5cSMarcel Holtmann 	__u8 code, reason;
2955eb492e01SAnderson Briglia 	int err = 0;
2956eb492e01SAnderson Briglia 
29578ae9b984SJohan Hedberg 	if (skb->len < 1)
295892381f5cSMarcel Holtmann 		return -EILSEQ;
295992381f5cSMarcel Holtmann 
2960d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hcon->hdev, HCI_LE_ENABLED)) {
29612e65c9d2SAndre Guedes 		reason = SMP_PAIRING_NOTSUPP;
29622e65c9d2SAndre Guedes 		goto done;
29632e65c9d2SAndre Guedes 	}
29642e65c9d2SAndre Guedes 
296592381f5cSMarcel Holtmann 	code = skb->data[0];
2966eb492e01SAnderson Briglia 	skb_pull(skb, sizeof(code));
2967eb492e01SAnderson Briglia 
2968b28b4943SJohan Hedberg 	smp = chan->data;
2969b28b4943SJohan Hedberg 
2970b28b4943SJohan Hedberg 	if (code > SMP_CMD_MAX)
2971b28b4943SJohan Hedberg 		goto drop;
2972b28b4943SJohan Hedberg 
297324bd0bd9SJohan Hedberg 	if (smp && !test_and_clear_bit(code, &smp->allow_cmd))
2974b28b4943SJohan Hedberg 		goto drop;
2975b28b4943SJohan Hedberg 
2976b28b4943SJohan Hedberg 	/* If we don't have a context the only allowed commands are
2977b28b4943SJohan Hedberg 	 * pairing request and security request.
29788cf9fa12SJohan Hedberg 	 */
2979b28b4943SJohan Hedberg 	if (!smp && code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ)
2980b28b4943SJohan Hedberg 		goto drop;
29818cf9fa12SJohan Hedberg 
2982eb492e01SAnderson Briglia 	switch (code) {
2983eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_REQ:
2984da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_req(conn, skb);
2985eb492e01SAnderson Briglia 		break;
2986eb492e01SAnderson Briglia 
2987eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_FAIL:
298884794e11SJohan Hedberg 		smp_failure(conn, 0);
2989da85e5e5SVinicius Costa Gomes 		err = -EPERM;
2990eb492e01SAnderson Briglia 		break;
2991eb492e01SAnderson Briglia 
2992eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_RSP:
2993da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_rsp(conn, skb);
299488ba43b6SAnderson Briglia 		break;
299588ba43b6SAnderson Briglia 
299688ba43b6SAnderson Briglia 	case SMP_CMD_SECURITY_REQ:
2997da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_security_req(conn, skb);
299888ba43b6SAnderson Briglia 		break;
299988ba43b6SAnderson Briglia 
3000eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_CONFIRM:
3001da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_confirm(conn, skb);
300288ba43b6SAnderson Briglia 		break;
300388ba43b6SAnderson Briglia 
3004eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_RANDOM:
3005da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_random(conn, skb);
300688ba43b6SAnderson Briglia 		break;
300788ba43b6SAnderson Briglia 
3008eb492e01SAnderson Briglia 	case SMP_CMD_ENCRYPT_INFO:
30097034b911SVinicius Costa Gomes 		reason = smp_cmd_encrypt_info(conn, skb);
30107034b911SVinicius Costa Gomes 		break;
30117034b911SVinicius Costa Gomes 
3012fad646e1SArchie Pusaka 	case SMP_CMD_INITIATOR_IDENT:
3013fad646e1SArchie Pusaka 		reason = smp_cmd_initiator_ident(conn, skb);
30147034b911SVinicius Costa Gomes 		break;
30157034b911SVinicius Costa Gomes 
3016eb492e01SAnderson Briglia 	case SMP_CMD_IDENT_INFO:
3017fd349c02SJohan Hedberg 		reason = smp_cmd_ident_info(conn, skb);
3018fd349c02SJohan Hedberg 		break;
3019fd349c02SJohan Hedberg 
3020eb492e01SAnderson Briglia 	case SMP_CMD_IDENT_ADDR_INFO:
3021fd349c02SJohan Hedberg 		reason = smp_cmd_ident_addr_info(conn, skb);
3022fd349c02SJohan Hedberg 		break;
3023fd349c02SJohan Hedberg 
3024eb492e01SAnderson Briglia 	case SMP_CMD_SIGN_INFO:
30257ee4ea36SMarcel Holtmann 		reason = smp_cmd_sign_info(conn, skb);
30267034b911SVinicius Costa Gomes 		break;
30277034b911SVinicius Costa Gomes 
3028d8f8edbeSJohan Hedberg 	case SMP_CMD_PUBLIC_KEY:
3029d8f8edbeSJohan Hedberg 		reason = smp_cmd_public_key(conn, skb);
3030d8f8edbeSJohan Hedberg 		break;
3031d8f8edbeSJohan Hedberg 
30326433a9a2SJohan Hedberg 	case SMP_CMD_DHKEY_CHECK:
30336433a9a2SJohan Hedberg 		reason = smp_cmd_dhkey_check(conn, skb);
30346433a9a2SJohan Hedberg 		break;
30356433a9a2SJohan Hedberg 
30361408bb6eSJohan Hedberg 	case SMP_CMD_KEYPRESS_NOTIFY:
30371408bb6eSJohan Hedberg 		reason = smp_cmd_keypress_notify(conn, skb);
30381408bb6eSJohan Hedberg 		break;
30391408bb6eSJohan Hedberg 
3040eb492e01SAnderson Briglia 	default:
30412e1614f7SLuiz Augusto von Dentz 		bt_dev_dbg(hcon->hdev, "Unknown command code 0x%2.2x", code);
3042eb492e01SAnderson Briglia 		reason = SMP_CMD_NOTSUPP;
30433a0259bbSVinicius Costa Gomes 		goto done;
30443a0259bbSVinicius Costa Gomes 	}
30453a0259bbSVinicius Costa Gomes 
30463a0259bbSVinicius Costa Gomes done:
30479b7b18efSJohan Hedberg 	if (!err) {
30483a0259bbSVinicius Costa Gomes 		if (reason)
304984794e11SJohan Hedberg 			smp_failure(conn, reason);
3050eb492e01SAnderson Briglia 		kfree_skb(skb);
30519b7b18efSJohan Hedberg 	}
30529b7b18efSJohan Hedberg 
3053eb492e01SAnderson Briglia 	return err;
3054b28b4943SJohan Hedberg 
3055b28b4943SJohan Hedberg drop:
30562064ee33SMarcel Holtmann 	bt_dev_err(hcon->hdev, "unexpected SMP command 0x%02x from %pMR",
3057b28b4943SJohan Hedberg 		   code, &hcon->dst);
3058b28b4943SJohan Hedberg 	kfree_skb(skb);
3059b28b4943SJohan Hedberg 	return 0;
3060eb492e01SAnderson Briglia }
30617034b911SVinicius Costa Gomes 
306270db83c4SJohan Hedberg static void smp_teardown_cb(struct l2cap_chan *chan, int err)
306370db83c4SJohan Hedberg {
306470db83c4SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
306570db83c4SJohan Hedberg 
30662e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(conn->hcon->hdev, "chan %p", chan);
306770db83c4SJohan Hedberg 
3068fc75cc86SJohan Hedberg 	if (chan->data)
30695d88cc73SJohan Hedberg 		smp_chan_destroy(conn);
30705d88cc73SJohan Hedberg 
307170db83c4SJohan Hedberg 	conn->smp = NULL;
307270db83c4SJohan Hedberg 	l2cap_chan_put(chan);
307370db83c4SJohan Hedberg }
307470db83c4SJohan Hedberg 
3075b5ae344dSJohan Hedberg static void bredr_pairing(struct l2cap_chan *chan)
3076b5ae344dSJohan Hedberg {
3077b5ae344dSJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
3078b5ae344dSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
3079b5ae344dSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
3080b5ae344dSJohan Hedberg 	struct smp_cmd_pairing req;
3081b5ae344dSJohan Hedberg 	struct smp_chan *smp;
3082b5ae344dSJohan Hedberg 
30832e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "chan %p", chan);
3084b5ae344dSJohan Hedberg 
3085b5ae344dSJohan Hedberg 	/* Only new pairings are interesting */
3086b5ae344dSJohan Hedberg 	if (!test_bit(HCI_CONN_NEW_LINK_KEY, &hcon->flags))
3087b5ae344dSJohan Hedberg 		return;
3088b5ae344dSJohan Hedberg 
3089b5ae344dSJohan Hedberg 	/* Don't bother if we're not encrypted */
3090b5ae344dSJohan Hedberg 	if (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags))
3091b5ae344dSJohan Hedberg 		return;
3092b5ae344dSJohan Hedberg 
309374be523cSArchie Pusaka 	/* Only initiator may initiate SMP over BR/EDR */
3094b5ae344dSJohan Hedberg 	if (hcon->role != HCI_ROLE_MASTER)
3095b5ae344dSJohan Hedberg 		return;
3096b5ae344dSJohan Hedberg 
3097b5ae344dSJohan Hedberg 	/* Secure Connections support must be enabled */
3098d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_SC_ENABLED))
3099b5ae344dSJohan Hedberg 		return;
3100b5ae344dSJohan Hedberg 
3101b5ae344dSJohan Hedberg 	/* BR/EDR must use Secure Connections for SMP */
3102b5ae344dSJohan Hedberg 	if (!test_bit(HCI_CONN_AES_CCM, &hcon->flags) &&
3103b7cb93e5SMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP))
3104b5ae344dSJohan Hedberg 		return;
3105b5ae344dSJohan Hedberg 
3106b5ae344dSJohan Hedberg 	/* If our LE support is not enabled don't do anything */
3107d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED))
3108b5ae344dSJohan Hedberg 		return;
3109b5ae344dSJohan Hedberg 
3110b5ae344dSJohan Hedberg 	/* Don't bother if remote LE support is not enabled */
3111b5ae344dSJohan Hedberg 	if (!lmp_host_le_capable(hcon))
3112b5ae344dSJohan Hedberg 		return;
3113b5ae344dSJohan Hedberg 
3114b5ae344dSJohan Hedberg 	/* Remote must support SMP fixed chan for BR/EDR */
3115b5ae344dSJohan Hedberg 	if (!(conn->remote_fixed_chan & L2CAP_FC_SMP_BREDR))
3116b5ae344dSJohan Hedberg 		return;
3117b5ae344dSJohan Hedberg 
3118b5ae344dSJohan Hedberg 	/* Don't bother if SMP is already ongoing */
3119b5ae344dSJohan Hedberg 	if (chan->data)
3120b5ae344dSJohan Hedberg 		return;
3121b5ae344dSJohan Hedberg 
3122b5ae344dSJohan Hedberg 	smp = smp_chan_create(conn);
3123b5ae344dSJohan Hedberg 	if (!smp) {
31242064ee33SMarcel Holtmann 		bt_dev_err(hdev, "unable to create SMP context for BR/EDR");
3125b5ae344dSJohan Hedberg 		return;
3126b5ae344dSJohan Hedberg 	}
3127b5ae344dSJohan Hedberg 
3128b5ae344dSJohan Hedberg 	set_bit(SMP_FLAG_SC, &smp->flags);
3129b5ae344dSJohan Hedberg 
31302e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "starting SMP over BR/EDR");
3131b5ae344dSJohan Hedberg 
3132b5ae344dSJohan Hedberg 	/* Prepare and send the BR/EDR SMP Pairing Request */
3133b5ae344dSJohan Hedberg 	build_bredr_pairing_cmd(smp, &req, NULL);
3134b5ae344dSJohan Hedberg 
3135b5ae344dSJohan Hedberg 	smp->preq[0] = SMP_CMD_PAIRING_REQ;
3136b5ae344dSJohan Hedberg 	memcpy(&smp->preq[1], &req, sizeof(req));
3137b5ae344dSJohan Hedberg 
3138b5ae344dSJohan Hedberg 	smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(req), &req);
3139b5ae344dSJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP);
3140b5ae344dSJohan Hedberg }
3141b5ae344dSJohan Hedberg 
314244f1a7abSJohan Hedberg static void smp_resume_cb(struct l2cap_chan *chan)
314344f1a7abSJohan Hedberg {
3144b68fda68SJohan Hedberg 	struct smp_chan *smp = chan->data;
314544f1a7abSJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
314644f1a7abSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
314744f1a7abSJohan Hedberg 
31482e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hcon->hdev, "chan %p", chan);
314944f1a7abSJohan Hedberg 
3150b5ae344dSJohan Hedberg 	if (hcon->type == ACL_LINK) {
3151b5ae344dSJohan Hedberg 		bredr_pairing(chan);
3152ef8efe4bSJohan Hedberg 		return;
3153b5ae344dSJohan Hedberg 	}
3154ef8efe4bSJohan Hedberg 
315586d1407cSJohan Hedberg 	if (!smp)
315686d1407cSJohan Hedberg 		return;
3157b68fda68SJohan Hedberg 
315884bc0db5SJohan Hedberg 	if (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags))
315984bc0db5SJohan Hedberg 		return;
316084bc0db5SJohan Hedberg 
3161b68fda68SJohan Hedberg 	cancel_delayed_work(&smp->security_timer);
316286d1407cSJohan Hedberg 
3163d6268e86SJohan Hedberg 	smp_distribute_keys(smp);
316444f1a7abSJohan Hedberg }
316544f1a7abSJohan Hedberg 
316670db83c4SJohan Hedberg static void smp_ready_cb(struct l2cap_chan *chan)
316770db83c4SJohan Hedberg {
316870db83c4SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
3169b5ae344dSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
317070db83c4SJohan Hedberg 
31712e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hcon->hdev, "chan %p", chan);
317270db83c4SJohan Hedberg 
31737883746bSJohan Hedberg 	/* No need to call l2cap_chan_hold() here since we already own
31747883746bSJohan Hedberg 	 * the reference taken in smp_new_conn_cb(). This is just the
31757883746bSJohan Hedberg 	 * first time that we tie it to a specific pointer. The code in
31767883746bSJohan Hedberg 	 * l2cap_core.c ensures that there's no risk this function wont
31777883746bSJohan Hedberg 	 * get called if smp_new_conn_cb was previously called.
31787883746bSJohan Hedberg 	 */
317970db83c4SJohan Hedberg 	conn->smp = chan;
3180b5ae344dSJohan Hedberg 
3181b5ae344dSJohan Hedberg 	if (hcon->type == ACL_LINK && test_bit(HCI_CONN_ENCRYPT, &hcon->flags))
3182b5ae344dSJohan Hedberg 		bredr_pairing(chan);
318370db83c4SJohan Hedberg }
318470db83c4SJohan Hedberg 
31854befb867SJohan Hedberg static int smp_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
31864befb867SJohan Hedberg {
31874befb867SJohan Hedberg 	int err;
31884befb867SJohan Hedberg 
31892e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(chan->conn->hcon->hdev, "chan %p", chan);
31904befb867SJohan Hedberg 
31914befb867SJohan Hedberg 	err = smp_sig_channel(chan, skb);
31924befb867SJohan Hedberg 	if (err) {
3193b68fda68SJohan Hedberg 		struct smp_chan *smp = chan->data;
31944befb867SJohan Hedberg 
3195b68fda68SJohan Hedberg 		if (smp)
3196b68fda68SJohan Hedberg 			cancel_delayed_work_sync(&smp->security_timer);
31974befb867SJohan Hedberg 
31981e91c29eSJohan Hedberg 		hci_disconnect(chan->conn->hcon, HCI_ERROR_AUTH_FAILURE);
31994befb867SJohan Hedberg 	}
32004befb867SJohan Hedberg 
32014befb867SJohan Hedberg 	return err;
32024befb867SJohan Hedberg }
32034befb867SJohan Hedberg 
320470db83c4SJohan Hedberg static struct sk_buff *smp_alloc_skb_cb(struct l2cap_chan *chan,
320570db83c4SJohan Hedberg 					unsigned long hdr_len,
320670db83c4SJohan Hedberg 					unsigned long len, int nb)
320770db83c4SJohan Hedberg {
320870db83c4SJohan Hedberg 	struct sk_buff *skb;
320970db83c4SJohan Hedberg 
321070db83c4SJohan Hedberg 	skb = bt_skb_alloc(hdr_len + len, GFP_KERNEL);
321170db83c4SJohan Hedberg 	if (!skb)
321270db83c4SJohan Hedberg 		return ERR_PTR(-ENOMEM);
321370db83c4SJohan Hedberg 
321470db83c4SJohan Hedberg 	skb->priority = HCI_PRIO_MAX;
3215a4368ff3SJohan Hedberg 	bt_cb(skb)->l2cap.chan = chan;
321670db83c4SJohan Hedberg 
321770db83c4SJohan Hedberg 	return skb;
321870db83c4SJohan Hedberg }
321970db83c4SJohan Hedberg 
322070db83c4SJohan Hedberg static const struct l2cap_ops smp_chan_ops = {
322170db83c4SJohan Hedberg 	.name			= "Security Manager",
322270db83c4SJohan Hedberg 	.ready			= smp_ready_cb,
32235d88cc73SJohan Hedberg 	.recv			= smp_recv_cb,
322470db83c4SJohan Hedberg 	.alloc_skb		= smp_alloc_skb_cb,
322570db83c4SJohan Hedberg 	.teardown		= smp_teardown_cb,
322644f1a7abSJohan Hedberg 	.resume			= smp_resume_cb,
322770db83c4SJohan Hedberg 
322870db83c4SJohan Hedberg 	.new_connection		= l2cap_chan_no_new_connection,
322970db83c4SJohan Hedberg 	.state_change		= l2cap_chan_no_state_change,
323070db83c4SJohan Hedberg 	.close			= l2cap_chan_no_close,
323170db83c4SJohan Hedberg 	.defer			= l2cap_chan_no_defer,
323270db83c4SJohan Hedberg 	.suspend		= l2cap_chan_no_suspend,
323370db83c4SJohan Hedberg 	.set_shutdown		= l2cap_chan_no_set_shutdown,
323470db83c4SJohan Hedberg 	.get_sndtimeo		= l2cap_chan_no_get_sndtimeo,
323570db83c4SJohan Hedberg };
323670db83c4SJohan Hedberg 
323770db83c4SJohan Hedberg static inline struct l2cap_chan *smp_new_conn_cb(struct l2cap_chan *pchan)
323870db83c4SJohan Hedberg {
323970db83c4SJohan Hedberg 	struct l2cap_chan *chan;
324070db83c4SJohan Hedberg 
3241995fca15SLuiz Augusto von Dentz 	BT_DBG("pchan %p", pchan);
324270db83c4SJohan Hedberg 
324370db83c4SJohan Hedberg 	chan = l2cap_chan_create();
324470db83c4SJohan Hedberg 	if (!chan)
324570db83c4SJohan Hedberg 		return NULL;
324670db83c4SJohan Hedberg 
324770db83c4SJohan Hedberg 	chan->chan_type	= pchan->chan_type;
324870db83c4SJohan Hedberg 	chan->ops	= &smp_chan_ops;
324970db83c4SJohan Hedberg 	chan->scid	= pchan->scid;
325070db83c4SJohan Hedberg 	chan->dcid	= chan->scid;
325170db83c4SJohan Hedberg 	chan->imtu	= pchan->imtu;
325270db83c4SJohan Hedberg 	chan->omtu	= pchan->omtu;
325370db83c4SJohan Hedberg 	chan->mode	= pchan->mode;
325470db83c4SJohan Hedberg 
3255abe84903SJohan Hedberg 	/* Other L2CAP channels may request SMP routines in order to
3256abe84903SJohan Hedberg 	 * change the security level. This means that the SMP channel
3257abe84903SJohan Hedberg 	 * lock must be considered in its own category to avoid lockdep
3258abe84903SJohan Hedberg 	 * warnings.
3259abe84903SJohan Hedberg 	 */
3260abe84903SJohan Hedberg 	atomic_set(&chan->nesting, L2CAP_NESTING_SMP);
3261abe84903SJohan Hedberg 
3262995fca15SLuiz Augusto von Dentz 	BT_DBG("created chan %p", chan);
326370db83c4SJohan Hedberg 
326470db83c4SJohan Hedberg 	return chan;
326570db83c4SJohan Hedberg }
326670db83c4SJohan Hedberg 
326770db83c4SJohan Hedberg static const struct l2cap_ops smp_root_chan_ops = {
326870db83c4SJohan Hedberg 	.name			= "Security Manager Root",
326970db83c4SJohan Hedberg 	.new_connection		= smp_new_conn_cb,
327070db83c4SJohan Hedberg 
327170db83c4SJohan Hedberg 	/* None of these are implemented for the root channel */
327270db83c4SJohan Hedberg 	.close			= l2cap_chan_no_close,
327370db83c4SJohan Hedberg 	.alloc_skb		= l2cap_chan_no_alloc_skb,
327470db83c4SJohan Hedberg 	.recv			= l2cap_chan_no_recv,
327570db83c4SJohan Hedberg 	.state_change		= l2cap_chan_no_state_change,
327670db83c4SJohan Hedberg 	.teardown		= l2cap_chan_no_teardown,
327770db83c4SJohan Hedberg 	.ready			= l2cap_chan_no_ready,
327870db83c4SJohan Hedberg 	.defer			= l2cap_chan_no_defer,
327970db83c4SJohan Hedberg 	.suspend		= l2cap_chan_no_suspend,
328070db83c4SJohan Hedberg 	.resume			= l2cap_chan_no_resume,
328170db83c4SJohan Hedberg 	.set_shutdown		= l2cap_chan_no_set_shutdown,
328270db83c4SJohan Hedberg 	.get_sndtimeo		= l2cap_chan_no_get_sndtimeo,
328370db83c4SJohan Hedberg };
328470db83c4SJohan Hedberg 
3285ef8efe4bSJohan Hedberg static struct l2cap_chan *smp_add_cid(struct hci_dev *hdev, u16 cid)
3286711eafe3SJohan Hedberg {
328770db83c4SJohan Hedberg 	struct l2cap_chan *chan;
328888a479d9SMarcel Holtmann 	struct smp_dev *smp;
328971af2f6bSHerbert Xu 	struct crypto_shash *tfm_cmac;
329047eb2ac8STudor Ambarus 	struct crypto_kpp *tfm_ecdh;
329170db83c4SJohan Hedberg 
3292ef8efe4bSJohan Hedberg 	if (cid == L2CAP_CID_SMP_BREDR) {
329388a479d9SMarcel Holtmann 		smp = NULL;
3294ef8efe4bSJohan Hedberg 		goto create_chan;
3295ef8efe4bSJohan Hedberg 	}
3296711eafe3SJohan Hedberg 
329788a479d9SMarcel Holtmann 	smp = kzalloc(sizeof(*smp), GFP_KERNEL);
329888a479d9SMarcel Holtmann 	if (!smp)
329988a479d9SMarcel Holtmann 		return ERR_PTR(-ENOMEM);
330088a479d9SMarcel Holtmann 
330171af2f6bSHerbert Xu 	tfm_cmac = crypto_alloc_shash("cmac(aes)", 0, 0);
33026e2dc6d1SMarcel Holtmann 	if (IS_ERR(tfm_cmac)) {
33032e1614f7SLuiz Augusto von Dentz 		bt_dev_err(hdev, "Unable to create CMAC crypto context");
3304453431a5SWaiman Long 		kfree_sensitive(smp);
33056e2dc6d1SMarcel Holtmann 		return ERR_CAST(tfm_cmac);
33066e2dc6d1SMarcel Holtmann 	}
33076e2dc6d1SMarcel Holtmann 
33086763f5eaSMeng Yu 	tfm_ecdh = crypto_alloc_kpp("ecdh-nist-p256", 0, 0);
330947eb2ac8STudor Ambarus 	if (IS_ERR(tfm_ecdh)) {
33102e1614f7SLuiz Augusto von Dentz 		bt_dev_err(hdev, "Unable to create ECDH crypto context");
331147eb2ac8STudor Ambarus 		crypto_free_shash(tfm_cmac);
3312453431a5SWaiman Long 		kfree_sensitive(smp);
331347eb2ac8STudor Ambarus 		return ERR_CAST(tfm_ecdh);
331447eb2ac8STudor Ambarus 	}
331547eb2ac8STudor Ambarus 
331694f14e47SJohan Hedberg 	smp->local_oob = false;
33176e2dc6d1SMarcel Holtmann 	smp->tfm_cmac = tfm_cmac;
331847eb2ac8STudor Ambarus 	smp->tfm_ecdh = tfm_ecdh;
331988a479d9SMarcel Holtmann 
3320ef8efe4bSJohan Hedberg create_chan:
332170db83c4SJohan Hedberg 	chan = l2cap_chan_create();
332270db83c4SJohan Hedberg 	if (!chan) {
332363511f6dSMarcel Holtmann 		if (smp) {
332471af2f6bSHerbert Xu 			crypto_free_shash(smp->tfm_cmac);
332547eb2ac8STudor Ambarus 			crypto_free_kpp(smp->tfm_ecdh);
3326453431a5SWaiman Long 			kfree_sensitive(smp);
332763511f6dSMarcel Holtmann 		}
3328ef8efe4bSJohan Hedberg 		return ERR_PTR(-ENOMEM);
332970db83c4SJohan Hedberg 	}
333070db83c4SJohan Hedberg 
333188a479d9SMarcel Holtmann 	chan->data = smp;
3332defce9e8SJohan Hedberg 
3333ef8efe4bSJohan Hedberg 	l2cap_add_scid(chan, cid);
333470db83c4SJohan Hedberg 
333570db83c4SJohan Hedberg 	l2cap_chan_set_defaults(chan);
333670db83c4SJohan Hedberg 
3337157029baSMarcel Holtmann 	if (cid == L2CAP_CID_SMP) {
333839e3e744SJohan Hedberg 		u8 bdaddr_type;
333939e3e744SJohan Hedberg 
334039e3e744SJohan Hedberg 		hci_copy_identity_address(hdev, &chan->src, &bdaddr_type);
334139e3e744SJohan Hedberg 
334239e3e744SJohan Hedberg 		if (bdaddr_type == ADDR_LE_DEV_PUBLIC)
334370db83c4SJohan Hedberg 			chan->src_type = BDADDR_LE_PUBLIC;
334439e3e744SJohan Hedberg 		else
334539e3e744SJohan Hedberg 			chan->src_type = BDADDR_LE_RANDOM;
3346157029baSMarcel Holtmann 	} else {
3347157029baSMarcel Holtmann 		bacpy(&chan->src, &hdev->bdaddr);
3348ef8efe4bSJohan Hedberg 		chan->src_type = BDADDR_BREDR;
3349157029baSMarcel Holtmann 	}
3350157029baSMarcel Holtmann 
335170db83c4SJohan Hedberg 	chan->state = BT_LISTEN;
335270db83c4SJohan Hedberg 	chan->mode = L2CAP_MODE_BASIC;
335370db83c4SJohan Hedberg 	chan->imtu = L2CAP_DEFAULT_MTU;
335470db83c4SJohan Hedberg 	chan->ops = &smp_root_chan_ops;
335570db83c4SJohan Hedberg 
3356abe84903SJohan Hedberg 	/* Set correct nesting level for a parent/listening channel */
3357abe84903SJohan Hedberg 	atomic_set(&chan->nesting, L2CAP_NESTING_PARENT);
3358abe84903SJohan Hedberg 
3359ef8efe4bSJohan Hedberg 	return chan;
3360711eafe3SJohan Hedberg }
3361711eafe3SJohan Hedberg 
3362ef8efe4bSJohan Hedberg static void smp_del_chan(struct l2cap_chan *chan)
3363711eafe3SJohan Hedberg {
336488a479d9SMarcel Holtmann 	struct smp_dev *smp;
336570db83c4SJohan Hedberg 
3366995fca15SLuiz Augusto von Dentz 	BT_DBG("chan %p", chan);
3367711eafe3SJohan Hedberg 
336888a479d9SMarcel Holtmann 	smp = chan->data;
336988a479d9SMarcel Holtmann 	if (smp) {
3370defce9e8SJohan Hedberg 		chan->data = NULL;
337171af2f6bSHerbert Xu 		crypto_free_shash(smp->tfm_cmac);
337247eb2ac8STudor Ambarus 		crypto_free_kpp(smp->tfm_ecdh);
3373453431a5SWaiman Long 		kfree_sensitive(smp);
3374711eafe3SJohan Hedberg 	}
337570db83c4SJohan Hedberg 
337670db83c4SJohan Hedberg 	l2cap_chan_put(chan);
3377711eafe3SJohan Hedberg }
3378ef8efe4bSJohan Hedberg 
337982493316SClaire Chang int smp_force_bredr(struct hci_dev *hdev, bool enable)
3380300acfdeSMarcel Holtmann {
3381b7cb93e5SMarcel Holtmann 	if (enable == hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP))
3382300acfdeSMarcel Holtmann 		return -EALREADY;
3383300acfdeSMarcel Holtmann 
3384300acfdeSMarcel Holtmann 	if (enable) {
3385300acfdeSMarcel Holtmann 		struct l2cap_chan *chan;
3386300acfdeSMarcel Holtmann 
3387300acfdeSMarcel Holtmann 		chan = smp_add_cid(hdev, L2CAP_CID_SMP_BREDR);
3388300acfdeSMarcel Holtmann 		if (IS_ERR(chan))
3389300acfdeSMarcel Holtmann 			return PTR_ERR(chan);
3390300acfdeSMarcel Holtmann 
3391300acfdeSMarcel Holtmann 		hdev->smp_bredr_data = chan;
3392300acfdeSMarcel Holtmann 	} else {
3393300acfdeSMarcel Holtmann 		struct l2cap_chan *chan;
3394300acfdeSMarcel Holtmann 
3395300acfdeSMarcel Holtmann 		chan = hdev->smp_bredr_data;
3396300acfdeSMarcel Holtmann 		hdev->smp_bredr_data = NULL;
3397300acfdeSMarcel Holtmann 		smp_del_chan(chan);
3398300acfdeSMarcel Holtmann 	}
3399300acfdeSMarcel Holtmann 
3400b7cb93e5SMarcel Holtmann 	hci_dev_change_flag(hdev, HCI_FORCE_BREDR_SMP);
3401300acfdeSMarcel Holtmann 
340282493316SClaire Chang 	return 0;
3403300acfdeSMarcel Holtmann }
3404300acfdeSMarcel Holtmann 
3405ef8efe4bSJohan Hedberg int smp_register(struct hci_dev *hdev)
3406ef8efe4bSJohan Hedberg {
3407ef8efe4bSJohan Hedberg 	struct l2cap_chan *chan;
3408ef8efe4bSJohan Hedberg 
34092e1614f7SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
3410ef8efe4bSJohan Hedberg 
34117e7ec445SMarcel Holtmann 	/* If the controller does not support Low Energy operation, then
34127e7ec445SMarcel Holtmann 	 * there is also no need to register any SMP channel.
34137e7ec445SMarcel Holtmann 	 */
34147e7ec445SMarcel Holtmann 	if (!lmp_le_capable(hdev))
34157e7ec445SMarcel Holtmann 		return 0;
34167e7ec445SMarcel Holtmann 
34172b8df323SMarcel Holtmann 	if (WARN_ON(hdev->smp_data)) {
34182b8df323SMarcel Holtmann 		chan = hdev->smp_data;
34192b8df323SMarcel Holtmann 		hdev->smp_data = NULL;
34202b8df323SMarcel Holtmann 		smp_del_chan(chan);
34212b8df323SMarcel Holtmann 	}
34222b8df323SMarcel Holtmann 
3423ef8efe4bSJohan Hedberg 	chan = smp_add_cid(hdev, L2CAP_CID_SMP);
3424ef8efe4bSJohan Hedberg 	if (IS_ERR(chan))
3425ef8efe4bSJohan Hedberg 		return PTR_ERR(chan);
3426ef8efe4bSJohan Hedberg 
3427ef8efe4bSJohan Hedberg 	hdev->smp_data = chan;
3428ef8efe4bSJohan Hedberg 
3429300acfdeSMarcel Holtmann 	if (!lmp_sc_capable(hdev)) {
343083ebb9ecSSzymon Janc 		/* Flag can be already set here (due to power toggle) */
343183ebb9ecSSzymon Janc 		if (!hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP))
3432ef8efe4bSJohan Hedberg 			return 0;
3433300acfdeSMarcel Holtmann 	}
3434ef8efe4bSJohan Hedberg 
34352b8df323SMarcel Holtmann 	if (WARN_ON(hdev->smp_bredr_data)) {
34362b8df323SMarcel Holtmann 		chan = hdev->smp_bredr_data;
34372b8df323SMarcel Holtmann 		hdev->smp_bredr_data = NULL;
34382b8df323SMarcel Holtmann 		smp_del_chan(chan);
34392b8df323SMarcel Holtmann 	}
34402b8df323SMarcel Holtmann 
3441ef8efe4bSJohan Hedberg 	chan = smp_add_cid(hdev, L2CAP_CID_SMP_BREDR);
3442ef8efe4bSJohan Hedberg 	if (IS_ERR(chan)) {
3443ef8efe4bSJohan Hedberg 		int err = PTR_ERR(chan);
3444ef8efe4bSJohan Hedberg 		chan = hdev->smp_data;
3445ef8efe4bSJohan Hedberg 		hdev->smp_data = NULL;
3446ef8efe4bSJohan Hedberg 		smp_del_chan(chan);
3447ef8efe4bSJohan Hedberg 		return err;
3448ef8efe4bSJohan Hedberg 	}
3449ef8efe4bSJohan Hedberg 
3450ef8efe4bSJohan Hedberg 	hdev->smp_bredr_data = chan;
3451ef8efe4bSJohan Hedberg 
3452ef8efe4bSJohan Hedberg 	return 0;
3453ef8efe4bSJohan Hedberg }
3454ef8efe4bSJohan Hedberg 
3455ef8efe4bSJohan Hedberg void smp_unregister(struct hci_dev *hdev)
3456ef8efe4bSJohan Hedberg {
3457ef8efe4bSJohan Hedberg 	struct l2cap_chan *chan;
3458ef8efe4bSJohan Hedberg 
3459ef8efe4bSJohan Hedberg 	if (hdev->smp_bredr_data) {
3460ef8efe4bSJohan Hedberg 		chan = hdev->smp_bredr_data;
3461ef8efe4bSJohan Hedberg 		hdev->smp_bredr_data = NULL;
3462ef8efe4bSJohan Hedberg 		smp_del_chan(chan);
3463ef8efe4bSJohan Hedberg 	}
3464ef8efe4bSJohan Hedberg 
3465ef8efe4bSJohan Hedberg 	if (hdev->smp_data) {
3466ef8efe4bSJohan Hedberg 		chan = hdev->smp_data;
3467ef8efe4bSJohan Hedberg 		hdev->smp_data = NULL;
3468ef8efe4bSJohan Hedberg 		smp_del_chan(chan);
3469ef8efe4bSJohan Hedberg 	}
3470ef8efe4bSJohan Hedberg }
34710a2b0f04SJohan Hedberg 
34720a2b0f04SJohan Hedberg #if IS_ENABLED(CONFIG_BT_SELFTEST_SMP)
34730a2b0f04SJohan Hedberg 
347447eb2ac8STudor Ambarus static int __init test_debug_key(struct crypto_kpp *tfm_ecdh)
347571653eb6SMarcel Holtmann {
3476c0153b0bSTudor Ambarus 	u8 pk[64];
3477a2976416STudor Ambarus 	int err;
347871653eb6SMarcel Holtmann 
3479c0153b0bSTudor Ambarus 	err = set_ecdh_privkey(tfm_ecdh, debug_sk);
3480a2976416STudor Ambarus 	if (err)
3481a2976416STudor Ambarus 		return err;
348271653eb6SMarcel Holtmann 
3483c0153b0bSTudor Ambarus 	err = generate_ecdh_public_key(tfm_ecdh, pk);
3484c0153b0bSTudor Ambarus 	if (err)
3485c0153b0bSTudor Ambarus 		return err;
348671653eb6SMarcel Holtmann 
3487329d8230SJason A. Donenfeld 	if (crypto_memneq(pk, debug_pk, 64))
348871653eb6SMarcel Holtmann 		return -EINVAL;
348971653eb6SMarcel Holtmann 
349071653eb6SMarcel Holtmann 	return 0;
349171653eb6SMarcel Holtmann }
349271653eb6SMarcel Holtmann 
349328a220aaSArd Biesheuvel static int __init test_ah(void)
3494cfc4198eSJohan Hedberg {
3495cfc4198eSJohan Hedberg 	const u8 irk[16] = {
3496cfc4198eSJohan Hedberg 			0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34,
3497cfc4198eSJohan Hedberg 			0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec };
3498cfc4198eSJohan Hedberg 	const u8 r[3] = { 0x94, 0x81, 0x70 };
3499cfc4198eSJohan Hedberg 	const u8 exp[3] = { 0xaa, 0xfb, 0x0d };
3500cfc4198eSJohan Hedberg 	u8 res[3];
3501cfc4198eSJohan Hedberg 	int err;
3502cfc4198eSJohan Hedberg 
350328a220aaSArd Biesheuvel 	err = smp_ah(irk, r, res);
3504cfc4198eSJohan Hedberg 	if (err)
3505cfc4198eSJohan Hedberg 		return err;
3506cfc4198eSJohan Hedberg 
3507329d8230SJason A. Donenfeld 	if (crypto_memneq(res, exp, 3))
3508cfc4198eSJohan Hedberg 		return -EINVAL;
3509cfc4198eSJohan Hedberg 
3510cfc4198eSJohan Hedberg 	return 0;
3511cfc4198eSJohan Hedberg }
3512cfc4198eSJohan Hedberg 
351328a220aaSArd Biesheuvel static int __init test_c1(void)
3514cfc4198eSJohan Hedberg {
3515cfc4198eSJohan Hedberg 	const u8 k[16] = {
3516cfc4198eSJohan Hedberg 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3517cfc4198eSJohan Hedberg 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
3518cfc4198eSJohan Hedberg 	const u8 r[16] = {
3519cfc4198eSJohan Hedberg 			0xe0, 0x2e, 0x70, 0xc6, 0x4e, 0x27, 0x88, 0x63,
3520cfc4198eSJohan Hedberg 			0x0e, 0x6f, 0xad, 0x56, 0x21, 0xd5, 0x83, 0x57 };
3521cfc4198eSJohan Hedberg 	const u8 preq[7] = { 0x01, 0x01, 0x00, 0x00, 0x10, 0x07, 0x07 };
3522cfc4198eSJohan Hedberg 	const u8 pres[7] = { 0x02, 0x03, 0x00, 0x00, 0x08, 0x00, 0x05 };
3523cfc4198eSJohan Hedberg 	const u8 _iat = 0x01;
3524cfc4198eSJohan Hedberg 	const u8 _rat = 0x00;
3525cfc4198eSJohan Hedberg 	const bdaddr_t ra = { { 0xb6, 0xb5, 0xb4, 0xb3, 0xb2, 0xb1 } };
3526cfc4198eSJohan Hedberg 	const bdaddr_t ia = { { 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1 } };
3527cfc4198eSJohan Hedberg 	const u8 exp[16] = {
3528cfc4198eSJohan Hedberg 			0x86, 0x3b, 0xf1, 0xbe, 0xc5, 0x4d, 0xa7, 0xd2,
3529cfc4198eSJohan Hedberg 			0xea, 0x88, 0x89, 0x87, 0xef, 0x3f, 0x1e, 0x1e };
3530cfc4198eSJohan Hedberg 	u8 res[16];
3531cfc4198eSJohan Hedberg 	int err;
3532cfc4198eSJohan Hedberg 
353328a220aaSArd Biesheuvel 	err = smp_c1(k, r, preq, pres, _iat, &ia, _rat, &ra, res);
3534cfc4198eSJohan Hedberg 	if (err)
3535cfc4198eSJohan Hedberg 		return err;
3536cfc4198eSJohan Hedberg 
3537329d8230SJason A. Donenfeld 	if (crypto_memneq(res, exp, 16))
3538cfc4198eSJohan Hedberg 		return -EINVAL;
3539cfc4198eSJohan Hedberg 
3540cfc4198eSJohan Hedberg 	return 0;
3541cfc4198eSJohan Hedberg }
3542cfc4198eSJohan Hedberg 
354328a220aaSArd Biesheuvel static int __init test_s1(void)
3544cfc4198eSJohan Hedberg {
3545cfc4198eSJohan Hedberg 	const u8 k[16] = {
3546cfc4198eSJohan Hedberg 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3547cfc4198eSJohan Hedberg 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
3548cfc4198eSJohan Hedberg 	const u8 r1[16] = {
3549cfc4198eSJohan Hedberg 			0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 };
3550cfc4198eSJohan Hedberg 	const u8 r2[16] = {
3551cfc4198eSJohan Hedberg 			0x00, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99 };
3552cfc4198eSJohan Hedberg 	const u8 exp[16] = {
3553cfc4198eSJohan Hedberg 			0x62, 0xa0, 0x6d, 0x79, 0xae, 0x16, 0x42, 0x5b,
3554cfc4198eSJohan Hedberg 			0x9b, 0xf4, 0xb0, 0xe8, 0xf0, 0xe1, 0x1f, 0x9a };
3555cfc4198eSJohan Hedberg 	u8 res[16];
3556cfc4198eSJohan Hedberg 	int err;
3557cfc4198eSJohan Hedberg 
355828a220aaSArd Biesheuvel 	err = smp_s1(k, r1, r2, res);
3559cfc4198eSJohan Hedberg 	if (err)
3560cfc4198eSJohan Hedberg 		return err;
3561cfc4198eSJohan Hedberg 
3562329d8230SJason A. Donenfeld 	if (crypto_memneq(res, exp, 16))
3563cfc4198eSJohan Hedberg 		return -EINVAL;
3564cfc4198eSJohan Hedberg 
3565cfc4198eSJohan Hedberg 	return 0;
3566cfc4198eSJohan Hedberg }
3567cfc4198eSJohan Hedberg 
356871af2f6bSHerbert Xu static int __init test_f4(struct crypto_shash *tfm_cmac)
3569fb2969a3SJohan Hedberg {
3570fb2969a3SJohan Hedberg 	const u8 u[32] = {
3571fb2969a3SJohan Hedberg 			0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc,
3572fb2969a3SJohan Hedberg 			0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef,
3573fb2969a3SJohan Hedberg 			0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e,
3574fb2969a3SJohan Hedberg 			0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20 };
3575fb2969a3SJohan Hedberg 	const u8 v[32] = {
3576fb2969a3SJohan Hedberg 			0xfd, 0xc5, 0x7f, 0xf4, 0x49, 0xdd, 0x4f, 0x6b,
3577fb2969a3SJohan Hedberg 			0xfb, 0x7c, 0x9d, 0xf1, 0xc2, 0x9a, 0xcb, 0x59,
3578fb2969a3SJohan Hedberg 			0x2a, 0xe7, 0xd4, 0xee, 0xfb, 0xfc, 0x0a, 0x90,
3579fb2969a3SJohan Hedberg 			0x9a, 0xbb, 0xf6, 0x32, 0x3d, 0x8b, 0x18, 0x55 };
3580fb2969a3SJohan Hedberg 	const u8 x[16] = {
3581fb2969a3SJohan Hedberg 			0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff,
3582fb2969a3SJohan Hedberg 			0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 };
3583fb2969a3SJohan Hedberg 	const u8 z = 0x00;
3584fb2969a3SJohan Hedberg 	const u8 exp[16] = {
3585fb2969a3SJohan Hedberg 			0x2d, 0x87, 0x74, 0xa9, 0xbe, 0xa1, 0xed, 0xf1,
3586fb2969a3SJohan Hedberg 			0x1c, 0xbd, 0xa9, 0x07, 0xf1, 0x16, 0xc9, 0xf2 };
3587fb2969a3SJohan Hedberg 	u8 res[16];
3588fb2969a3SJohan Hedberg 	int err;
3589fb2969a3SJohan Hedberg 
3590fb2969a3SJohan Hedberg 	err = smp_f4(tfm_cmac, u, v, x, z, res);
3591fb2969a3SJohan Hedberg 	if (err)
3592fb2969a3SJohan Hedberg 		return err;
3593fb2969a3SJohan Hedberg 
3594329d8230SJason A. Donenfeld 	if (crypto_memneq(res, exp, 16))
3595fb2969a3SJohan Hedberg 		return -EINVAL;
3596fb2969a3SJohan Hedberg 
3597fb2969a3SJohan Hedberg 	return 0;
3598fb2969a3SJohan Hedberg }
3599fb2969a3SJohan Hedberg 
360071af2f6bSHerbert Xu static int __init test_f5(struct crypto_shash *tfm_cmac)
3601fb2969a3SJohan Hedberg {
3602fb2969a3SJohan Hedberg 	const u8 w[32] = {
3603fb2969a3SJohan Hedberg 			0x98, 0xa6, 0xbf, 0x73, 0xf3, 0x34, 0x8d, 0x86,
3604fb2969a3SJohan Hedberg 			0xf1, 0x66, 0xf8, 0xb4, 0x13, 0x6b, 0x79, 0x99,
3605fb2969a3SJohan Hedberg 			0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34,
3606fb2969a3SJohan Hedberg 			0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec };
3607fb2969a3SJohan Hedberg 	const u8 n1[16] = {
3608fb2969a3SJohan Hedberg 			0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff,
3609fb2969a3SJohan Hedberg 			0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 };
3610fb2969a3SJohan Hedberg 	const u8 n2[16] = {
3611fb2969a3SJohan Hedberg 			0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21,
3612fb2969a3SJohan Hedberg 			0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6 };
3613fb2969a3SJohan Hedberg 	const u8 a1[7] = { 0xce, 0xbf, 0x37, 0x37, 0x12, 0x56, 0x00 };
3614fb2969a3SJohan Hedberg 	const u8 a2[7] = { 0xc1, 0xcf, 0x2d, 0x70, 0x13, 0xa7, 0x00 };
3615fb2969a3SJohan Hedberg 	const u8 exp_ltk[16] = {
3616fb2969a3SJohan Hedberg 			0x38, 0x0a, 0x75, 0x94, 0xb5, 0x22, 0x05, 0x98,
3617fb2969a3SJohan Hedberg 			0x23, 0xcd, 0xd7, 0x69, 0x11, 0x79, 0x86, 0x69 };
3618fb2969a3SJohan Hedberg 	const u8 exp_mackey[16] = {
3619fb2969a3SJohan Hedberg 			0x20, 0x6e, 0x63, 0xce, 0x20, 0x6a, 0x3f, 0xfd,
3620fb2969a3SJohan Hedberg 			0x02, 0x4a, 0x08, 0xa1, 0x76, 0xf1, 0x65, 0x29 };
3621fb2969a3SJohan Hedberg 	u8 mackey[16], ltk[16];
3622fb2969a3SJohan Hedberg 	int err;
3623fb2969a3SJohan Hedberg 
3624fb2969a3SJohan Hedberg 	err = smp_f5(tfm_cmac, w, n1, n2, a1, a2, mackey, ltk);
3625fb2969a3SJohan Hedberg 	if (err)
3626fb2969a3SJohan Hedberg 		return err;
3627fb2969a3SJohan Hedberg 
3628329d8230SJason A. Donenfeld 	if (crypto_memneq(mackey, exp_mackey, 16))
3629fb2969a3SJohan Hedberg 		return -EINVAL;
3630fb2969a3SJohan Hedberg 
3631329d8230SJason A. Donenfeld 	if (crypto_memneq(ltk, exp_ltk, 16))
3632fb2969a3SJohan Hedberg 		return -EINVAL;
3633fb2969a3SJohan Hedberg 
3634fb2969a3SJohan Hedberg 	return 0;
3635fb2969a3SJohan Hedberg }
3636fb2969a3SJohan Hedberg 
363771af2f6bSHerbert Xu static int __init test_f6(struct crypto_shash *tfm_cmac)
3638fb2969a3SJohan Hedberg {
3639fb2969a3SJohan Hedberg 	const u8 w[16] = {
3640fb2969a3SJohan Hedberg 			0x20, 0x6e, 0x63, 0xce, 0x20, 0x6a, 0x3f, 0xfd,
3641fb2969a3SJohan Hedberg 			0x02, 0x4a, 0x08, 0xa1, 0x76, 0xf1, 0x65, 0x29 };
3642fb2969a3SJohan Hedberg 	const u8 n1[16] = {
3643fb2969a3SJohan Hedberg 			0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff,
3644fb2969a3SJohan Hedberg 			0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 };
3645fb2969a3SJohan Hedberg 	const u8 n2[16] = {
3646fb2969a3SJohan Hedberg 			0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21,
3647fb2969a3SJohan Hedberg 			0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6 };
3648fb2969a3SJohan Hedberg 	const u8 r[16] = {
3649fb2969a3SJohan Hedberg 			0xc8, 0x0f, 0x2d, 0x0c, 0xd2, 0x42, 0xda, 0x08,
3650fb2969a3SJohan Hedberg 			0x54, 0xbb, 0x53, 0xb4, 0x3b, 0x34, 0xa3, 0x12 };
3651fb2969a3SJohan Hedberg 	const u8 io_cap[3] = { 0x02, 0x01, 0x01 };
3652fb2969a3SJohan Hedberg 	const u8 a1[7] = { 0xce, 0xbf, 0x37, 0x37, 0x12, 0x56, 0x00 };
3653fb2969a3SJohan Hedberg 	const u8 a2[7] = { 0xc1, 0xcf, 0x2d, 0x70, 0x13, 0xa7, 0x00 };
3654fb2969a3SJohan Hedberg 	const u8 exp[16] = {
3655fb2969a3SJohan Hedberg 			0x61, 0x8f, 0x95, 0xda, 0x09, 0x0b, 0x6c, 0xd2,
3656fb2969a3SJohan Hedberg 			0xc5, 0xe8, 0xd0, 0x9c, 0x98, 0x73, 0xc4, 0xe3 };
3657fb2969a3SJohan Hedberg 	u8 res[16];
3658fb2969a3SJohan Hedberg 	int err;
3659fb2969a3SJohan Hedberg 
3660fb2969a3SJohan Hedberg 	err = smp_f6(tfm_cmac, w, n1, n2, r, io_cap, a1, a2, res);
3661fb2969a3SJohan Hedberg 	if (err)
3662fb2969a3SJohan Hedberg 		return err;
3663fb2969a3SJohan Hedberg 
3664329d8230SJason A. Donenfeld 	if (crypto_memneq(res, exp, 16))
3665fb2969a3SJohan Hedberg 		return -EINVAL;
3666fb2969a3SJohan Hedberg 
3667fb2969a3SJohan Hedberg 	return 0;
3668fb2969a3SJohan Hedberg }
3669fb2969a3SJohan Hedberg 
367071af2f6bSHerbert Xu static int __init test_g2(struct crypto_shash *tfm_cmac)
3671fb2969a3SJohan Hedberg {
3672fb2969a3SJohan Hedberg 	const u8 u[32] = {
3673fb2969a3SJohan Hedberg 			0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc,
3674fb2969a3SJohan Hedberg 			0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef,
3675fb2969a3SJohan Hedberg 			0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e,
3676fb2969a3SJohan Hedberg 			0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20 };
3677fb2969a3SJohan Hedberg 	const u8 v[32] = {
3678fb2969a3SJohan Hedberg 			0xfd, 0xc5, 0x7f, 0xf4, 0x49, 0xdd, 0x4f, 0x6b,
3679fb2969a3SJohan Hedberg 			0xfb, 0x7c, 0x9d, 0xf1, 0xc2, 0x9a, 0xcb, 0x59,
3680fb2969a3SJohan Hedberg 			0x2a, 0xe7, 0xd4, 0xee, 0xfb, 0xfc, 0x0a, 0x90,
3681fb2969a3SJohan Hedberg 			0x9a, 0xbb, 0xf6, 0x32, 0x3d, 0x8b, 0x18, 0x55 };
3682fb2969a3SJohan Hedberg 	const u8 x[16] = {
3683fb2969a3SJohan Hedberg 			0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff,
3684fb2969a3SJohan Hedberg 			0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 };
3685fb2969a3SJohan Hedberg 	const u8 y[16] = {
3686fb2969a3SJohan Hedberg 			0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21,
3687fb2969a3SJohan Hedberg 			0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6 };
3688fb2969a3SJohan Hedberg 	const u32 exp_val = 0x2f9ed5ba % 1000000;
3689fb2969a3SJohan Hedberg 	u32 val;
3690fb2969a3SJohan Hedberg 	int err;
3691fb2969a3SJohan Hedberg 
3692fb2969a3SJohan Hedberg 	err = smp_g2(tfm_cmac, u, v, x, y, &val);
3693fb2969a3SJohan Hedberg 	if (err)
3694fb2969a3SJohan Hedberg 		return err;
3695fb2969a3SJohan Hedberg 
3696fb2969a3SJohan Hedberg 	if (val != exp_val)
3697fb2969a3SJohan Hedberg 		return -EINVAL;
3698fb2969a3SJohan Hedberg 
3699fb2969a3SJohan Hedberg 	return 0;
3700fb2969a3SJohan Hedberg }
3701fb2969a3SJohan Hedberg 
370271af2f6bSHerbert Xu static int __init test_h6(struct crypto_shash *tfm_cmac)
3703fb2969a3SJohan Hedberg {
3704fb2969a3SJohan Hedberg 	const u8 w[16] = {
3705fb2969a3SJohan Hedberg 			0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34,
3706fb2969a3SJohan Hedberg 			0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec };
3707fb2969a3SJohan Hedberg 	const u8 key_id[4] = { 0x72, 0x62, 0x65, 0x6c };
3708fb2969a3SJohan Hedberg 	const u8 exp[16] = {
3709fb2969a3SJohan Hedberg 			0x99, 0x63, 0xb1, 0x80, 0xe2, 0xa9, 0xd3, 0xe8,
3710fb2969a3SJohan Hedberg 			0x1c, 0xc9, 0x6d, 0xe7, 0x02, 0xe1, 0x9a, 0x2d };
3711fb2969a3SJohan Hedberg 	u8 res[16];
3712fb2969a3SJohan Hedberg 	int err;
3713fb2969a3SJohan Hedberg 
3714fb2969a3SJohan Hedberg 	err = smp_h6(tfm_cmac, w, key_id, res);
3715fb2969a3SJohan Hedberg 	if (err)
3716fb2969a3SJohan Hedberg 		return err;
3717fb2969a3SJohan Hedberg 
3718329d8230SJason A. Donenfeld 	if (crypto_memneq(res, exp, 16))
3719fb2969a3SJohan Hedberg 		return -EINVAL;
3720fb2969a3SJohan Hedberg 
3721fb2969a3SJohan Hedberg 	return 0;
3722fb2969a3SJohan Hedberg }
3723fb2969a3SJohan Hedberg 
372464dd374eSMarcel Holtmann static char test_smp_buffer[32];
372564dd374eSMarcel Holtmann 
372664dd374eSMarcel Holtmann static ssize_t test_smp_read(struct file *file, char __user *user_buf,
372764dd374eSMarcel Holtmann 			     size_t count, loff_t *ppos)
372864dd374eSMarcel Holtmann {
372964dd374eSMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, test_smp_buffer,
373064dd374eSMarcel Holtmann 				       strlen(test_smp_buffer));
373164dd374eSMarcel Holtmann }
373264dd374eSMarcel Holtmann 
373364dd374eSMarcel Holtmann static const struct file_operations test_smp_fops = {
373464dd374eSMarcel Holtmann 	.open		= simple_open,
373564dd374eSMarcel Holtmann 	.read		= test_smp_read,
373664dd374eSMarcel Holtmann 	.llseek		= default_llseek,
373764dd374eSMarcel Holtmann };
373864dd374eSMarcel Holtmann 
373928a220aaSArd Biesheuvel static int __init run_selftests(struct crypto_shash *tfm_cmac,
374047eb2ac8STudor Ambarus 				struct crypto_kpp *tfm_ecdh)
37410a2b0f04SJohan Hedberg {
3742255047b0SMarcel Holtmann 	ktime_t calltime, delta, rettime;
3743255047b0SMarcel Holtmann 	unsigned long long duration;
3744cfc4198eSJohan Hedberg 	int err;
3745cfc4198eSJohan Hedberg 
3746255047b0SMarcel Holtmann 	calltime = ktime_get();
3747255047b0SMarcel Holtmann 
374847eb2ac8STudor Ambarus 	err = test_debug_key(tfm_ecdh);
374971653eb6SMarcel Holtmann 	if (err) {
375071653eb6SMarcel Holtmann 		BT_ERR("debug_key test failed");
375171653eb6SMarcel Holtmann 		goto done;
375271653eb6SMarcel Holtmann 	}
375371653eb6SMarcel Holtmann 
375428a220aaSArd Biesheuvel 	err = test_ah();
3755cfc4198eSJohan Hedberg 	if (err) {
3756cfc4198eSJohan Hedberg 		BT_ERR("smp_ah test failed");
375764dd374eSMarcel Holtmann 		goto done;
3758cfc4198eSJohan Hedberg 	}
3759cfc4198eSJohan Hedberg 
376028a220aaSArd Biesheuvel 	err = test_c1();
3761cfc4198eSJohan Hedberg 	if (err) {
3762cfc4198eSJohan Hedberg 		BT_ERR("smp_c1 test failed");
376364dd374eSMarcel Holtmann 		goto done;
3764cfc4198eSJohan Hedberg 	}
3765cfc4198eSJohan Hedberg 
376628a220aaSArd Biesheuvel 	err = test_s1();
3767cfc4198eSJohan Hedberg 	if (err) {
3768cfc4198eSJohan Hedberg 		BT_ERR("smp_s1 test failed");
376964dd374eSMarcel Holtmann 		goto done;
3770cfc4198eSJohan Hedberg 	}
3771cfc4198eSJohan Hedberg 
3772fb2969a3SJohan Hedberg 	err = test_f4(tfm_cmac);
3773fb2969a3SJohan Hedberg 	if (err) {
3774fb2969a3SJohan Hedberg 		BT_ERR("smp_f4 test failed");
377564dd374eSMarcel Holtmann 		goto done;
3776fb2969a3SJohan Hedberg 	}
3777fb2969a3SJohan Hedberg 
3778fb2969a3SJohan Hedberg 	err = test_f5(tfm_cmac);
3779fb2969a3SJohan Hedberg 	if (err) {
3780fb2969a3SJohan Hedberg 		BT_ERR("smp_f5 test failed");
378164dd374eSMarcel Holtmann 		goto done;
3782fb2969a3SJohan Hedberg 	}
3783fb2969a3SJohan Hedberg 
3784fb2969a3SJohan Hedberg 	err = test_f6(tfm_cmac);
3785fb2969a3SJohan Hedberg 	if (err) {
3786fb2969a3SJohan Hedberg 		BT_ERR("smp_f6 test failed");
378764dd374eSMarcel Holtmann 		goto done;
3788fb2969a3SJohan Hedberg 	}
3789fb2969a3SJohan Hedberg 
3790fb2969a3SJohan Hedberg 	err = test_g2(tfm_cmac);
3791fb2969a3SJohan Hedberg 	if (err) {
3792fb2969a3SJohan Hedberg 		BT_ERR("smp_g2 test failed");
379364dd374eSMarcel Holtmann 		goto done;
3794fb2969a3SJohan Hedberg 	}
3795fb2969a3SJohan Hedberg 
3796fb2969a3SJohan Hedberg 	err = test_h6(tfm_cmac);
3797fb2969a3SJohan Hedberg 	if (err) {
3798fb2969a3SJohan Hedberg 		BT_ERR("smp_h6 test failed");
379964dd374eSMarcel Holtmann 		goto done;
3800fb2969a3SJohan Hedberg 	}
3801fb2969a3SJohan Hedberg 
3802255047b0SMarcel Holtmann 	rettime = ktime_get();
3803255047b0SMarcel Holtmann 	delta = ktime_sub(rettime, calltime);
3804255047b0SMarcel Holtmann 	duration = (unsigned long long) ktime_to_ns(delta) >> 10;
3805255047b0SMarcel Holtmann 
38065ced2464SMarcel Holtmann 	BT_INFO("SMP test passed in %llu usecs", duration);
38070a2b0f04SJohan Hedberg 
380864dd374eSMarcel Holtmann done:
380964dd374eSMarcel Holtmann 	if (!err)
381064dd374eSMarcel Holtmann 		snprintf(test_smp_buffer, sizeof(test_smp_buffer),
381164dd374eSMarcel Holtmann 			 "PASS (%llu usecs)\n", duration);
381264dd374eSMarcel Holtmann 	else
381364dd374eSMarcel Holtmann 		snprintf(test_smp_buffer, sizeof(test_smp_buffer), "FAIL\n");
381464dd374eSMarcel Holtmann 
381564dd374eSMarcel Holtmann 	debugfs_create_file("selftest_smp", 0444, bt_debugfs, NULL,
381664dd374eSMarcel Holtmann 			    &test_smp_fops);
381764dd374eSMarcel Holtmann 
381864dd374eSMarcel Holtmann 	return err;
38190a2b0f04SJohan Hedberg }
38200a2b0f04SJohan Hedberg 
38210a2b0f04SJohan Hedberg int __init bt_selftest_smp(void)
38220a2b0f04SJohan Hedberg {
382371af2f6bSHerbert Xu 	struct crypto_shash *tfm_cmac;
382447eb2ac8STudor Ambarus 	struct crypto_kpp *tfm_ecdh;
38250a2b0f04SJohan Hedberg 	int err;
38260a2b0f04SJohan Hedberg 
38273d234b33SEric Biggers 	tfm_cmac = crypto_alloc_shash("cmac(aes)", 0, 0);
38280a2b0f04SJohan Hedberg 	if (IS_ERR(tfm_cmac)) {
38290a2b0f04SJohan Hedberg 		BT_ERR("Unable to create CMAC crypto context");
38300a2b0f04SJohan Hedberg 		return PTR_ERR(tfm_cmac);
38310a2b0f04SJohan Hedberg 	}
38320a2b0f04SJohan Hedberg 
38336763f5eaSMeng Yu 	tfm_ecdh = crypto_alloc_kpp("ecdh-nist-p256", 0, 0);
383447eb2ac8STudor Ambarus 	if (IS_ERR(tfm_ecdh)) {
383547eb2ac8STudor Ambarus 		BT_ERR("Unable to create ECDH crypto context");
383647eb2ac8STudor Ambarus 		crypto_free_shash(tfm_cmac);
383747eb2ac8STudor Ambarus 		return PTR_ERR(tfm_ecdh);
383847eb2ac8STudor Ambarus 	}
383947eb2ac8STudor Ambarus 
384028a220aaSArd Biesheuvel 	err = run_selftests(tfm_cmac, tfm_ecdh);
38410a2b0f04SJohan Hedberg 
384271af2f6bSHerbert Xu 	crypto_free_shash(tfm_cmac);
384347eb2ac8STudor Ambarus 	crypto_free_kpp(tfm_ecdh);
38440a2b0f04SJohan Hedberg 
38450a2b0f04SJohan Hedberg 	return err;
38460a2b0f04SJohan Hedberg }
38470a2b0f04SJohan Hedberg 
38480a2b0f04SJohan Hedberg #endif
3849