xref: /openbmc/linux/net/bluetooth/smp.c (revision aa563d7b)
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>
26329d8230SJason A. Donenfeld #include <crypto/algapi.h>
278c520a59SGustavo Padovan #include <crypto/b128ops.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
43c7a3d57dSJohan Hedberg  * accidentially 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 */
573b19146dSJohan Hedberg #define SMP_SC_NO_DIST (SMP_DIST_ENC_KEY | SMP_DIST_LINK_KEY);
583b19146dSJohan Hedberg 
5917b02e62SMarcel Holtmann #define SMP_TIMEOUT	msecs_to_jiffies(30000)
605d3de7dfSVinicius Costa Gomes 
61d7a5a11dSMarcel Holtmann #define AUTH_REQ_MASK(dev)	(hci_dev_test_flag(dev, HCI_SC_ENABLED) ? \
62a62da6f1SJohan Hedberg 				 0x3f : 0x07)
6388d3a8acSJohan Hedberg #define KEY_DIST_MASK		0x07
64065a13e2SJohan Hedberg 
65cbbbe3e2SJohan Hedberg /* Maximum message length that can be passed to aes_cmac */
66cbbbe3e2SJohan Hedberg #define CMAC_MSG_MAX	80
67cbbbe3e2SJohan Hedberg 
68533e35d4SJohan Hedberg enum {
69533e35d4SJohan Hedberg 	SMP_FLAG_TK_VALID,
70533e35d4SJohan Hedberg 	SMP_FLAG_CFM_PENDING,
71533e35d4SJohan Hedberg 	SMP_FLAG_MITM_AUTH,
72533e35d4SJohan Hedberg 	SMP_FLAG_COMPLETE,
73533e35d4SJohan Hedberg 	SMP_FLAG_INITIATOR,
7465668776SJohan Hedberg 	SMP_FLAG_SC,
75d8f8edbeSJohan Hedberg 	SMP_FLAG_REMOTE_PK,
76aeb7d461SJohan Hedberg 	SMP_FLAG_DEBUG_KEY,
7738606f14SJohan Hedberg 	SMP_FLAG_WAIT_USER,
78d3e54a87SJohan Hedberg 	SMP_FLAG_DHKEY_PENDING,
791a8bab4fSJohan Hedberg 	SMP_FLAG_REMOTE_OOB,
801a8bab4fSJohan Hedberg 	SMP_FLAG_LOCAL_OOB,
81a62da6f1SJohan Hedberg 	SMP_FLAG_CT2,
82533e35d4SJohan Hedberg };
834bc58f51SJohan Hedberg 
8488a479d9SMarcel Holtmann struct smp_dev {
8560a27d65SMarcel Holtmann 	/* Secure Connections OOB data */
8694f14e47SJohan Hedberg 	bool			local_oob;
8760a27d65SMarcel Holtmann 	u8			local_pk[64];
88fb334feeSMarcel Holtmann 	u8			local_rand[16];
8960a27d65SMarcel Holtmann 	bool			debug_key;
9060a27d65SMarcel Holtmann 
91a4770e11SAndy Lutomirski 	struct crypto_cipher	*tfm_aes;
9271af2f6bSHerbert Xu 	struct crypto_shash	*tfm_cmac;
9347eb2ac8STudor Ambarus 	struct crypto_kpp	*tfm_ecdh;
9488a479d9SMarcel Holtmann };
9588a479d9SMarcel Holtmann 
964bc58f51SJohan Hedberg struct smp_chan {
974bc58f51SJohan Hedberg 	struct l2cap_conn	*conn;
98b68fda68SJohan Hedberg 	struct delayed_work	security_timer;
99b28b4943SJohan Hedberg 	unsigned long           allow_cmd; /* Bitmask of allowed commands */
100b68fda68SJohan Hedberg 
1014bc58f51SJohan Hedberg 	u8		preq[7]; /* SMP Pairing Request */
1024bc58f51SJohan Hedberg 	u8		prsp[7]; /* SMP Pairing Response */
1034bc58f51SJohan Hedberg 	u8		prnd[16]; /* SMP Pairing Random (local) */
1044bc58f51SJohan Hedberg 	u8		rrnd[16]; /* SMP Pairing Random (remote) */
1054bc58f51SJohan Hedberg 	u8		pcnf[16]; /* SMP Pairing Confirm */
1064bc58f51SJohan Hedberg 	u8		tk[16]; /* SMP Temporary Key */
107882fafadSJohan Hedberg 	u8		rr[16]; /* Remote OOB ra/rb value */
108882fafadSJohan Hedberg 	u8		lr[16]; /* Local OOB ra/rb value */
1094bc58f51SJohan Hedberg 	u8		enc_key_size;
1104bc58f51SJohan Hedberg 	u8		remote_key_dist;
1114bc58f51SJohan Hedberg 	bdaddr_t	id_addr;
1124bc58f51SJohan Hedberg 	u8		id_addr_type;
1134bc58f51SJohan Hedberg 	u8		irk[16];
1144bc58f51SJohan Hedberg 	struct smp_csrk	*csrk;
1154bc58f51SJohan Hedberg 	struct smp_csrk	*slave_csrk;
1164bc58f51SJohan Hedberg 	struct smp_ltk	*ltk;
1174bc58f51SJohan Hedberg 	struct smp_ltk	*slave_ltk;
1184bc58f51SJohan Hedberg 	struct smp_irk	*remote_irk;
1196a77083aSJohan Hedberg 	u8		*link_key;
1204a74d658SJohan Hedberg 	unsigned long	flags;
121783e0574SJohan Hedberg 	u8		method;
12238606f14SJohan Hedberg 	u8		passkey_round;
1236a7bd103SJohan Hedberg 
1243b19146dSJohan Hedberg 	/* Secure Connections variables */
1253b19146dSJohan Hedberg 	u8			local_pk[64];
126d8f8edbeSJohan Hedberg 	u8			remote_pk[64];
127d8f8edbeSJohan Hedberg 	u8			dhkey[32];
128760b018bSJohan Hedberg 	u8			mackey[16];
1293b19146dSJohan Hedberg 
130a4770e11SAndy Lutomirski 	struct crypto_cipher	*tfm_aes;
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];
17471af2f6bSHerbert Xu 	SHASH_DESC_ON_STACK(desc, tfm);
175cbbbe3e2SJohan Hedberg 	int err;
176cbbbe3e2SJohan Hedberg 
177cbbbe3e2SJohan Hedberg 	if (len > CMAC_MSG_MAX)
178cbbbe3e2SJohan Hedberg 		return -EFBIG;
179cbbbe3e2SJohan Hedberg 
180cbbbe3e2SJohan Hedberg 	if (!tfm) {
181cbbbe3e2SJohan Hedberg 		BT_ERR("tfm %p", tfm);
182cbbbe3e2SJohan Hedberg 		return -EINVAL;
183cbbbe3e2SJohan Hedberg 	}
184cbbbe3e2SJohan Hedberg 
18571af2f6bSHerbert Xu 	desc->tfm = tfm;
18671af2f6bSHerbert Xu 	desc->flags = 0;
187cbbbe3e2SJohan Hedberg 
188cbbbe3e2SJohan Hedberg 	/* Swap key and message from LSB to MSB */
189cbbbe3e2SJohan Hedberg 	swap_buf(k, tmp, 16);
190cbbbe3e2SJohan Hedberg 	swap_buf(m, msg_msb, len);
191cbbbe3e2SJohan Hedberg 
192c7a3d57dSJohan Hedberg 	SMP_DBG("msg (len %zu) %*phN", len, (int) len, m);
193c7a3d57dSJohan Hedberg 	SMP_DBG("key %16phN", k);
194cbbbe3e2SJohan Hedberg 
19571af2f6bSHerbert Xu 	err = crypto_shash_setkey(tfm, tmp, 16);
196cbbbe3e2SJohan Hedberg 	if (err) {
197cbbbe3e2SJohan Hedberg 		BT_ERR("cipher setkey failed: %d", err);
198cbbbe3e2SJohan Hedberg 		return err;
199cbbbe3e2SJohan Hedberg 	}
200cbbbe3e2SJohan Hedberg 
20171af2f6bSHerbert Xu 	err = crypto_shash_digest(desc, msg_msb, len, mac_msb);
20271af2f6bSHerbert Xu 	shash_desc_zero(desc);
203cbbbe3e2SJohan Hedberg 	if (err) {
20471af2f6bSHerbert Xu 		BT_ERR("Hash computation error %d", err);
205cbbbe3e2SJohan Hedberg 		return err;
206cbbbe3e2SJohan Hedberg 	}
207cbbbe3e2SJohan Hedberg 
208cbbbe3e2SJohan Hedberg 	swap_buf(mac_msb, mac, 16);
209cbbbe3e2SJohan Hedberg 
210c7a3d57dSJohan Hedberg 	SMP_DBG("mac %16phN", mac);
211cbbbe3e2SJohan Hedberg 
212cbbbe3e2SJohan Hedberg 	return 0;
213cbbbe3e2SJohan Hedberg }
214cbbbe3e2SJohan Hedberg 
21571af2f6bSHerbert Xu static int smp_f4(struct crypto_shash *tfm_cmac, const u8 u[32],
21671af2f6bSHerbert Xu 		  const u8 v[32], const u8 x[16], u8 z, u8 res[16])
217cbbbe3e2SJohan Hedberg {
218cbbbe3e2SJohan Hedberg 	u8 m[65];
219cbbbe3e2SJohan Hedberg 	int err;
220cbbbe3e2SJohan Hedberg 
221c7a3d57dSJohan Hedberg 	SMP_DBG("u %32phN", u);
222c7a3d57dSJohan Hedberg 	SMP_DBG("v %32phN", v);
223c7a3d57dSJohan Hedberg 	SMP_DBG("x %16phN z %02x", x, z);
224cbbbe3e2SJohan Hedberg 
225cbbbe3e2SJohan Hedberg 	m[0] = z;
226cbbbe3e2SJohan Hedberg 	memcpy(m + 1, v, 32);
227cbbbe3e2SJohan Hedberg 	memcpy(m + 33, u, 32);
228cbbbe3e2SJohan Hedberg 
229cbbbe3e2SJohan Hedberg 	err = aes_cmac(tfm_cmac, x, m, sizeof(m), res);
230cbbbe3e2SJohan Hedberg 	if (err)
231cbbbe3e2SJohan Hedberg 		return err;
232cbbbe3e2SJohan Hedberg 
233c7a3d57dSJohan Hedberg 	SMP_DBG("res %16phN", res);
234cbbbe3e2SJohan Hedberg 
235cbbbe3e2SJohan Hedberg 	return err;
236cbbbe3e2SJohan Hedberg }
237cbbbe3e2SJohan Hedberg 
23871af2f6bSHerbert Xu static int smp_f5(struct crypto_shash *tfm_cmac, const u8 w[32],
2394da50de8SJohan Hedberg 		  const u8 n1[16], const u8 n2[16], const u8 a1[7],
2404da50de8SJohan Hedberg 		  const u8 a2[7], u8 mackey[16], u8 ltk[16])
241760b018bSJohan Hedberg {
242760b018bSJohan Hedberg 	/* The btle, salt and length "magic" values are as defined in
243760b018bSJohan Hedberg 	 * the SMP section of the Bluetooth core specification. In ASCII
244760b018bSJohan Hedberg 	 * the btle value ends up being 'btle'. The salt is just a
245760b018bSJohan Hedberg 	 * random number whereas length is the value 256 in little
246760b018bSJohan Hedberg 	 * endian format.
247760b018bSJohan Hedberg 	 */
248760b018bSJohan Hedberg 	const u8 btle[4] = { 0x65, 0x6c, 0x74, 0x62 };
249760b018bSJohan Hedberg 	const u8 salt[16] = { 0xbe, 0x83, 0x60, 0x5a, 0xdb, 0x0b, 0x37, 0x60,
250760b018bSJohan Hedberg 			      0x38, 0xa5, 0xf5, 0xaa, 0x91, 0x83, 0x88, 0x6c };
251760b018bSJohan Hedberg 	const u8 length[2] = { 0x00, 0x01 };
252760b018bSJohan Hedberg 	u8 m[53], t[16];
253760b018bSJohan Hedberg 	int err;
254760b018bSJohan Hedberg 
255c7a3d57dSJohan Hedberg 	SMP_DBG("w %32phN", w);
256c7a3d57dSJohan Hedberg 	SMP_DBG("n1 %16phN n2 %16phN", n1, n2);
257c7a3d57dSJohan Hedberg 	SMP_DBG("a1 %7phN a2 %7phN", a1, a2);
258760b018bSJohan Hedberg 
259760b018bSJohan Hedberg 	err = aes_cmac(tfm_cmac, salt, w, 32, t);
260760b018bSJohan Hedberg 	if (err)
261760b018bSJohan Hedberg 		return err;
262760b018bSJohan Hedberg 
263c7a3d57dSJohan Hedberg 	SMP_DBG("t %16phN", t);
264760b018bSJohan Hedberg 
265760b018bSJohan Hedberg 	memcpy(m, length, 2);
266760b018bSJohan Hedberg 	memcpy(m + 2, a2, 7);
267760b018bSJohan Hedberg 	memcpy(m + 9, a1, 7);
268760b018bSJohan Hedberg 	memcpy(m + 16, n2, 16);
269760b018bSJohan Hedberg 	memcpy(m + 32, n1, 16);
270760b018bSJohan Hedberg 	memcpy(m + 48, btle, 4);
271760b018bSJohan Hedberg 
272760b018bSJohan Hedberg 	m[52] = 0; /* Counter */
273760b018bSJohan Hedberg 
274760b018bSJohan Hedberg 	err = aes_cmac(tfm_cmac, t, m, sizeof(m), mackey);
275760b018bSJohan Hedberg 	if (err)
276760b018bSJohan Hedberg 		return err;
277760b018bSJohan Hedberg 
278c7a3d57dSJohan Hedberg 	SMP_DBG("mackey %16phN", mackey);
279760b018bSJohan Hedberg 
280760b018bSJohan Hedberg 	m[52] = 1; /* Counter */
281760b018bSJohan Hedberg 
282760b018bSJohan Hedberg 	err = aes_cmac(tfm_cmac, t, m, sizeof(m), ltk);
283760b018bSJohan Hedberg 	if (err)
284760b018bSJohan Hedberg 		return err;
285760b018bSJohan Hedberg 
286c7a3d57dSJohan Hedberg 	SMP_DBG("ltk %16phN", ltk);
287760b018bSJohan Hedberg 
288760b018bSJohan Hedberg 	return 0;
289760b018bSJohan Hedberg }
290760b018bSJohan Hedberg 
29171af2f6bSHerbert Xu static int smp_f6(struct crypto_shash *tfm_cmac, const u8 w[16],
2924da50de8SJohan Hedberg 		  const u8 n1[16], const u8 n2[16], const u8 r[16],
293760b018bSJohan Hedberg 		  const u8 io_cap[3], const u8 a1[7], const u8 a2[7],
294760b018bSJohan Hedberg 		  u8 res[16])
295760b018bSJohan Hedberg {
296760b018bSJohan Hedberg 	u8 m[65];
297760b018bSJohan Hedberg 	int err;
298760b018bSJohan Hedberg 
299c7a3d57dSJohan Hedberg 	SMP_DBG("w %16phN", w);
300c7a3d57dSJohan Hedberg 	SMP_DBG("n1 %16phN n2 %16phN", n1, n2);
301c7a3d57dSJohan Hedberg 	SMP_DBG("r %16phN io_cap %3phN a1 %7phN a2 %7phN", r, io_cap, a1, a2);
302760b018bSJohan Hedberg 
303760b018bSJohan Hedberg 	memcpy(m, a2, 7);
304760b018bSJohan Hedberg 	memcpy(m + 7, a1, 7);
305760b018bSJohan Hedberg 	memcpy(m + 14, io_cap, 3);
306760b018bSJohan Hedberg 	memcpy(m + 17, r, 16);
307760b018bSJohan Hedberg 	memcpy(m + 33, n2, 16);
308760b018bSJohan Hedberg 	memcpy(m + 49, n1, 16);
309760b018bSJohan Hedberg 
310760b018bSJohan Hedberg 	err = aes_cmac(tfm_cmac, w, m, sizeof(m), res);
311760b018bSJohan Hedberg 	if (err)
312760b018bSJohan Hedberg 		return err;
313760b018bSJohan Hedberg 
314203de21bSMarcel Holtmann 	SMP_DBG("res %16phN", res);
315760b018bSJohan Hedberg 
316760b018bSJohan Hedberg 	return err;
317760b018bSJohan Hedberg }
318760b018bSJohan Hedberg 
31971af2f6bSHerbert Xu static int smp_g2(struct crypto_shash *tfm_cmac, const u8 u[32], const u8 v[32],
320191dc7feSJohan Hedberg 		  const u8 x[16], const u8 y[16], u32 *val)
321191dc7feSJohan Hedberg {
322191dc7feSJohan Hedberg 	u8 m[80], tmp[16];
323191dc7feSJohan Hedberg 	int err;
324191dc7feSJohan Hedberg 
325c7a3d57dSJohan Hedberg 	SMP_DBG("u %32phN", u);
326c7a3d57dSJohan Hedberg 	SMP_DBG("v %32phN", v);
327c7a3d57dSJohan Hedberg 	SMP_DBG("x %16phN y %16phN", x, y);
328191dc7feSJohan Hedberg 
329191dc7feSJohan Hedberg 	memcpy(m, y, 16);
330191dc7feSJohan Hedberg 	memcpy(m + 16, v, 32);
331191dc7feSJohan Hedberg 	memcpy(m + 48, u, 32);
332191dc7feSJohan Hedberg 
333191dc7feSJohan Hedberg 	err = aes_cmac(tfm_cmac, x, m, sizeof(m), tmp);
334191dc7feSJohan Hedberg 	if (err)
335191dc7feSJohan Hedberg 		return err;
336191dc7feSJohan Hedberg 
337191dc7feSJohan Hedberg 	*val = get_unaligned_le32(tmp);
338191dc7feSJohan Hedberg 	*val %= 1000000;
339191dc7feSJohan Hedberg 
340c7a3d57dSJohan Hedberg 	SMP_DBG("val %06u", *val);
341191dc7feSJohan Hedberg 
342191dc7feSJohan Hedberg 	return 0;
343191dc7feSJohan Hedberg }
344191dc7feSJohan Hedberg 
34571af2f6bSHerbert Xu static int smp_h6(struct crypto_shash *tfm_cmac, const u8 w[16],
34606edf8deSJohan Hedberg 		  const u8 key_id[4], u8 res[16])
34706edf8deSJohan Hedberg {
34806edf8deSJohan Hedberg 	int err;
34906edf8deSJohan Hedberg 
35006edf8deSJohan Hedberg 	SMP_DBG("w %16phN key_id %4phN", w, key_id);
35106edf8deSJohan Hedberg 
35206edf8deSJohan Hedberg 	err = aes_cmac(tfm_cmac, w, key_id, 4, res);
35306edf8deSJohan Hedberg 	if (err)
35406edf8deSJohan Hedberg 		return err;
35506edf8deSJohan Hedberg 
35606edf8deSJohan Hedberg 	SMP_DBG("res %16phN", res);
35706edf8deSJohan Hedberg 
35806edf8deSJohan Hedberg 	return err;
35906edf8deSJohan Hedberg }
36006edf8deSJohan Hedberg 
361a62da6f1SJohan Hedberg static int smp_h7(struct crypto_shash *tfm_cmac, const u8 w[16],
362a62da6f1SJohan Hedberg 		  const u8 salt[16], u8 res[16])
363a62da6f1SJohan Hedberg {
364a62da6f1SJohan Hedberg 	int err;
365a62da6f1SJohan Hedberg 
366a62da6f1SJohan Hedberg 	SMP_DBG("w %16phN salt %16phN", w, salt);
367a62da6f1SJohan Hedberg 
368a62da6f1SJohan Hedberg 	err = aes_cmac(tfm_cmac, salt, w, 16, res);
369a62da6f1SJohan Hedberg 	if (err)
370a62da6f1SJohan Hedberg 		return err;
371a62da6f1SJohan Hedberg 
372a62da6f1SJohan Hedberg 	SMP_DBG("res %16phN", res);
373a62da6f1SJohan Hedberg 
374a62da6f1SJohan Hedberg 	return err;
375a62da6f1SJohan Hedberg }
376a62da6f1SJohan Hedberg 
37706edf8deSJohan Hedberg /* The following functions map to the legacy SMP crypto functions e, c1,
37806edf8deSJohan Hedberg  * s1 and ah.
37906edf8deSJohan Hedberg  */
38006edf8deSJohan Hedberg 
381a4770e11SAndy Lutomirski static int smp_e(struct crypto_cipher *tfm, const u8 *k, u8 *r)
382d22ef0bcSAnderson Briglia {
383943a732aSJohan Hedberg 	uint8_t tmp[16], data[16];
384201a5929SJohan Hedberg 	int err;
385d22ef0bcSAnderson Briglia 
386011c391aSJohan Hedberg 	SMP_DBG("k %16phN r %16phN", k, r);
387011c391aSJohan Hedberg 
3887f376cd6SJohan Hedberg 	if (!tfm) {
389d22ef0bcSAnderson Briglia 		BT_ERR("tfm %p", tfm);
390d22ef0bcSAnderson Briglia 		return -EINVAL;
391d22ef0bcSAnderson Briglia 	}
392d22ef0bcSAnderson Briglia 
393943a732aSJohan Hedberg 	/* The most significant octet of key corresponds to k[0] */
3948a2936f4SJohan Hedberg 	swap_buf(k, tmp, 16);
395943a732aSJohan Hedberg 
396a4770e11SAndy Lutomirski 	err = crypto_cipher_setkey(tfm, tmp, 16);
397d22ef0bcSAnderson Briglia 	if (err) {
398d22ef0bcSAnderson Briglia 		BT_ERR("cipher setkey failed: %d", err);
399d22ef0bcSAnderson Briglia 		return err;
400d22ef0bcSAnderson Briglia 	}
401d22ef0bcSAnderson Briglia 
402943a732aSJohan Hedberg 	/* Most significant octet of plaintextData corresponds to data[0] */
4038a2936f4SJohan Hedberg 	swap_buf(r, data, 16);
404943a732aSJohan Hedberg 
405a4770e11SAndy Lutomirski 	crypto_cipher_encrypt_one(tfm, data, data);
406d22ef0bcSAnderson Briglia 
407943a732aSJohan Hedberg 	/* Most significant octet of encryptedData corresponds to data[0] */
4088a2936f4SJohan Hedberg 	swap_buf(data, r, 16);
409943a732aSJohan Hedberg 
410011c391aSJohan Hedberg 	SMP_DBG("r %16phN", r);
411011c391aSJohan Hedberg 
412d22ef0bcSAnderson Briglia 	return err;
413d22ef0bcSAnderson Briglia }
414d22ef0bcSAnderson Briglia 
415a4770e11SAndy Lutomirski static int smp_c1(struct crypto_cipher *tfm_aes, const u8 k[16],
41606edf8deSJohan Hedberg 		  const u8 r[16], const u8 preq[7], const u8 pres[7], u8 _iat,
41706edf8deSJohan Hedberg 		  const bdaddr_t *ia, u8 _rat, const bdaddr_t *ra, u8 res[16])
41806edf8deSJohan Hedberg {
41906edf8deSJohan Hedberg 	u8 p1[16], p2[16];
42006edf8deSJohan Hedberg 	int err;
42106edf8deSJohan Hedberg 
422011c391aSJohan Hedberg 	SMP_DBG("k %16phN r %16phN", k, r);
423011c391aSJohan Hedberg 	SMP_DBG("iat %u ia %6phN rat %u ra %6phN", _iat, ia, _rat, ra);
424011c391aSJohan Hedberg 	SMP_DBG("preq %7phN pres %7phN", preq, pres);
425011c391aSJohan Hedberg 
42606edf8deSJohan Hedberg 	memset(p1, 0, 16);
42706edf8deSJohan Hedberg 
42806edf8deSJohan Hedberg 	/* p1 = pres || preq || _rat || _iat */
42906edf8deSJohan Hedberg 	p1[0] = _iat;
43006edf8deSJohan Hedberg 	p1[1] = _rat;
43106edf8deSJohan Hedberg 	memcpy(p1 + 2, preq, 7);
43206edf8deSJohan Hedberg 	memcpy(p1 + 9, pres, 7);
43306edf8deSJohan Hedberg 
434011c391aSJohan Hedberg 	SMP_DBG("p1 %16phN", p1);
43506edf8deSJohan Hedberg 
43606edf8deSJohan Hedberg 	/* res = r XOR p1 */
43706edf8deSJohan Hedberg 	u128_xor((u128 *) res, (u128 *) r, (u128 *) p1);
43806edf8deSJohan Hedberg 
43906edf8deSJohan Hedberg 	/* res = e(k, res) */
44006edf8deSJohan Hedberg 	err = smp_e(tfm_aes, k, res);
44106edf8deSJohan Hedberg 	if (err) {
44206edf8deSJohan Hedberg 		BT_ERR("Encrypt data error");
44306edf8deSJohan Hedberg 		return err;
44406edf8deSJohan Hedberg 	}
44506edf8deSJohan Hedberg 
446011c391aSJohan Hedberg 	/* p2 = padding || ia || ra */
447011c391aSJohan Hedberg 	memcpy(p2, ra, 6);
448011c391aSJohan Hedberg 	memcpy(p2 + 6, ia, 6);
449011c391aSJohan Hedberg 	memset(p2 + 12, 0, 4);
450011c391aSJohan Hedberg 
451011c391aSJohan Hedberg 	SMP_DBG("p2 %16phN", p2);
452011c391aSJohan Hedberg 
45306edf8deSJohan Hedberg 	/* res = res XOR p2 */
45406edf8deSJohan Hedberg 	u128_xor((u128 *) res, (u128 *) res, (u128 *) p2);
45506edf8deSJohan Hedberg 
45606edf8deSJohan Hedberg 	/* res = e(k, res) */
45706edf8deSJohan Hedberg 	err = smp_e(tfm_aes, k, res);
45806edf8deSJohan Hedberg 	if (err)
45906edf8deSJohan Hedberg 		BT_ERR("Encrypt data error");
46006edf8deSJohan Hedberg 
46106edf8deSJohan Hedberg 	return err;
46206edf8deSJohan Hedberg }
46306edf8deSJohan Hedberg 
464a4770e11SAndy Lutomirski static int smp_s1(struct crypto_cipher *tfm_aes, const u8 k[16],
46506edf8deSJohan Hedberg 		  const u8 r1[16], const u8 r2[16], u8 _r[16])
4666a77083aSJohan Hedberg {
4676a77083aSJohan Hedberg 	int err;
4686a77083aSJohan Hedberg 
46906edf8deSJohan Hedberg 	/* Just least significant octets from r1 and r2 are considered */
47006edf8deSJohan Hedberg 	memcpy(_r, r2, 8);
47106edf8deSJohan Hedberg 	memcpy(_r + 8, r1, 8);
4726a77083aSJohan Hedberg 
47306edf8deSJohan Hedberg 	err = smp_e(tfm_aes, k, _r);
4746a77083aSJohan Hedberg 	if (err)
47506edf8deSJohan Hedberg 		BT_ERR("Encrypt data error");
4766a77083aSJohan Hedberg 
4776a77083aSJohan Hedberg 	return err;
4786a77083aSJohan Hedberg }
4796a77083aSJohan Hedberg 
480a4770e11SAndy Lutomirski static int smp_ah(struct crypto_cipher *tfm, const u8 irk[16],
481cd082797SJohan Hedberg 		  const u8 r[3], u8 res[3])
48260478054SJohan Hedberg {
483943a732aSJohan Hedberg 	u8 _res[16];
48460478054SJohan Hedberg 	int err;
48560478054SJohan Hedberg 
48660478054SJohan Hedberg 	/* r' = padding || r */
487943a732aSJohan Hedberg 	memcpy(_res, r, 3);
488943a732aSJohan Hedberg 	memset(_res + 3, 0, 13);
48960478054SJohan Hedberg 
490943a732aSJohan Hedberg 	err = smp_e(tfm, irk, _res);
49160478054SJohan Hedberg 	if (err) {
49260478054SJohan Hedberg 		BT_ERR("Encrypt error");
49360478054SJohan Hedberg 		return err;
49460478054SJohan Hedberg 	}
49560478054SJohan Hedberg 
49660478054SJohan Hedberg 	/* The output of the random address function ah is:
497c5080d42SMarcel Holtmann 	 *	ah(k, r) = e(k, r') mod 2^24
49860478054SJohan Hedberg 	 * The output of the security function e is then truncated to 24 bits
49960478054SJohan Hedberg 	 * by taking the least significant 24 bits of the output of e as the
50060478054SJohan Hedberg 	 * result of ah.
50160478054SJohan Hedberg 	 */
502943a732aSJohan Hedberg 	memcpy(res, _res, 3);
50360478054SJohan Hedberg 
50460478054SJohan Hedberg 	return 0;
50560478054SJohan Hedberg }
50660478054SJohan Hedberg 
507cd082797SJohan Hedberg bool smp_irk_matches(struct hci_dev *hdev, const u8 irk[16],
508cd082797SJohan Hedberg 		     const bdaddr_t *bdaddr)
50960478054SJohan Hedberg {
510defce9e8SJohan Hedberg 	struct l2cap_chan *chan = hdev->smp_data;
51188a479d9SMarcel Holtmann 	struct smp_dev *smp;
51260478054SJohan Hedberg 	u8 hash[3];
51360478054SJohan Hedberg 	int err;
51460478054SJohan Hedberg 
515defce9e8SJohan Hedberg 	if (!chan || !chan->data)
516defce9e8SJohan Hedberg 		return false;
517defce9e8SJohan Hedberg 
51888a479d9SMarcel Holtmann 	smp = chan->data;
519defce9e8SJohan Hedberg 
52060478054SJohan Hedberg 	BT_DBG("RPA %pMR IRK %*phN", bdaddr, 16, irk);
52160478054SJohan Hedberg 
52288a479d9SMarcel Holtmann 	err = smp_ah(smp->tfm_aes, irk, &bdaddr->b[3], hash);
52360478054SJohan Hedberg 	if (err)
52460478054SJohan Hedberg 		return false;
52560478054SJohan Hedberg 
526329d8230SJason A. Donenfeld 	return !crypto_memneq(bdaddr->b, hash, 3);
52760478054SJohan Hedberg }
52860478054SJohan Hedberg 
529cd082797SJohan Hedberg int smp_generate_rpa(struct hci_dev *hdev, const u8 irk[16], bdaddr_t *rpa)
530b1e2b3aeSJohan Hedberg {
531defce9e8SJohan Hedberg 	struct l2cap_chan *chan = hdev->smp_data;
53288a479d9SMarcel Holtmann 	struct smp_dev *smp;
533b1e2b3aeSJohan Hedberg 	int err;
534b1e2b3aeSJohan Hedberg 
535defce9e8SJohan Hedberg 	if (!chan || !chan->data)
536defce9e8SJohan Hedberg 		return -EOPNOTSUPP;
537defce9e8SJohan Hedberg 
53888a479d9SMarcel Holtmann 	smp = chan->data;
539defce9e8SJohan Hedberg 
540b1e2b3aeSJohan Hedberg 	get_random_bytes(&rpa->b[3], 3);
541b1e2b3aeSJohan Hedberg 
542b1e2b3aeSJohan Hedberg 	rpa->b[5] &= 0x3f;	/* Clear two most significant bits */
543b1e2b3aeSJohan Hedberg 	rpa->b[5] |= 0x40;	/* Set second most significant bit */
544b1e2b3aeSJohan Hedberg 
54588a479d9SMarcel Holtmann 	err = smp_ah(smp->tfm_aes, irk, &rpa->b[3], rpa->b);
546b1e2b3aeSJohan Hedberg 	if (err < 0)
547b1e2b3aeSJohan Hedberg 		return err;
548b1e2b3aeSJohan Hedberg 
549b1e2b3aeSJohan Hedberg 	BT_DBG("RPA %pMR", rpa);
550b1e2b3aeSJohan Hedberg 
551b1e2b3aeSJohan Hedberg 	return 0;
552b1e2b3aeSJohan Hedberg }
553b1e2b3aeSJohan Hedberg 
55460a27d65SMarcel Holtmann int smp_generate_oob(struct hci_dev *hdev, u8 hash[16], u8 rand[16])
55560a27d65SMarcel Holtmann {
55660a27d65SMarcel Holtmann 	struct l2cap_chan *chan = hdev->smp_data;
55760a27d65SMarcel Holtmann 	struct smp_dev *smp;
55860a27d65SMarcel Holtmann 	int err;
55960a27d65SMarcel Holtmann 
56060a27d65SMarcel Holtmann 	if (!chan || !chan->data)
56160a27d65SMarcel Holtmann 		return -EOPNOTSUPP;
56260a27d65SMarcel Holtmann 
56360a27d65SMarcel Holtmann 	smp = chan->data;
56460a27d65SMarcel Holtmann 
56560a27d65SMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS)) {
56660a27d65SMarcel Holtmann 		BT_DBG("Using debug keys");
567c0153b0bSTudor Ambarus 		err = set_ecdh_privkey(smp->tfm_ecdh, debug_sk);
568c0153b0bSTudor Ambarus 		if (err)
569c0153b0bSTudor Ambarus 			return err;
57060a27d65SMarcel Holtmann 		memcpy(smp->local_pk, debug_pk, 64);
57160a27d65SMarcel Holtmann 		smp->debug_key = true;
57260a27d65SMarcel Holtmann 	} else {
57360a27d65SMarcel Holtmann 		while (true) {
574c0153b0bSTudor Ambarus 			/* Generate key pair for Secure Connections */
575c0153b0bSTudor Ambarus 			err = generate_ecdh_keys(smp->tfm_ecdh, smp->local_pk);
576a2976416STudor Ambarus 			if (err)
577a2976416STudor Ambarus 				return err;
57860a27d65SMarcel Holtmann 
57960a27d65SMarcel Holtmann 			/* This is unlikely, but we need to check that
58060a27d65SMarcel Holtmann 			 * we didn't accidentially generate a debug key.
58160a27d65SMarcel Holtmann 			 */
582c0153b0bSTudor Ambarus 			if (crypto_memneq(smp->local_pk, debug_pk, 64))
58360a27d65SMarcel Holtmann 				break;
58460a27d65SMarcel Holtmann 		}
58560a27d65SMarcel Holtmann 		smp->debug_key = false;
58660a27d65SMarcel Holtmann 	}
58760a27d65SMarcel Holtmann 
58860a27d65SMarcel Holtmann 	SMP_DBG("OOB Public Key X: %32phN", smp->local_pk);
58960a27d65SMarcel Holtmann 	SMP_DBG("OOB Public Key Y: %32phN", smp->local_pk + 32);
59060a27d65SMarcel Holtmann 
591fb334feeSMarcel Holtmann 	get_random_bytes(smp->local_rand, 16);
59260a27d65SMarcel Holtmann 
59360a27d65SMarcel Holtmann 	err = smp_f4(smp->tfm_cmac, smp->local_pk, smp->local_pk,
594fb334feeSMarcel Holtmann 		     smp->local_rand, 0, hash);
59560a27d65SMarcel Holtmann 	if (err < 0)
59660a27d65SMarcel Holtmann 		return err;
59760a27d65SMarcel Holtmann 
598fb334feeSMarcel Holtmann 	memcpy(rand, smp->local_rand, 16);
59960a27d65SMarcel Holtmann 
60094f14e47SJohan Hedberg 	smp->local_oob = true;
60194f14e47SJohan Hedberg 
60260a27d65SMarcel Holtmann 	return 0;
60360a27d65SMarcel Holtmann }
60460a27d65SMarcel Holtmann 
605eb492e01SAnderson Briglia static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
606eb492e01SAnderson Briglia {
6075d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
608b68fda68SJohan Hedberg 	struct smp_chan *smp;
6095d88cc73SJohan Hedberg 	struct kvec iv[2];
6105d88cc73SJohan Hedberg 	struct msghdr msg;
6115d88cc73SJohan Hedberg 
6125d88cc73SJohan Hedberg 	if (!chan)
6135d88cc73SJohan Hedberg 		return;
614eb492e01SAnderson Briglia 
615eb492e01SAnderson Briglia 	BT_DBG("code 0x%2.2x", code);
616eb492e01SAnderson Briglia 
6175d88cc73SJohan Hedberg 	iv[0].iov_base = &code;
6185d88cc73SJohan Hedberg 	iv[0].iov_len = 1;
619eb492e01SAnderson Briglia 
6205d88cc73SJohan Hedberg 	iv[1].iov_base = data;
6215d88cc73SJohan Hedberg 	iv[1].iov_len = len;
6225d88cc73SJohan Hedberg 
6235d88cc73SJohan Hedberg 	memset(&msg, 0, sizeof(msg));
6245d88cc73SJohan Hedberg 
625aa563d7bSDavid Howells 	iov_iter_kvec(&msg.msg_iter, WRITE, iv, 2, 1 + len);
6265d88cc73SJohan Hedberg 
6275d88cc73SJohan Hedberg 	l2cap_chan_send(chan, &msg, 1 + len);
628e2dcd113SVinicius Costa Gomes 
629b68fda68SJohan Hedberg 	if (!chan->data)
630b68fda68SJohan Hedberg 		return;
631b68fda68SJohan Hedberg 
632b68fda68SJohan Hedberg 	smp = chan->data;
633b68fda68SJohan Hedberg 
634b68fda68SJohan Hedberg 	cancel_delayed_work_sync(&smp->security_timer);
635b68fda68SJohan Hedberg 	schedule_delayed_work(&smp->security_timer, SMP_TIMEOUT);
636eb492e01SAnderson Briglia }
637eb492e01SAnderson Briglia 
638d2eb9e10SJohan Hedberg static u8 authreq_to_seclevel(u8 authreq)
6392b64d153SBrian Gix {
640d2eb9e10SJohan Hedberg 	if (authreq & SMP_AUTH_MITM) {
641d2eb9e10SJohan Hedberg 		if (authreq & SMP_AUTH_SC)
642d2eb9e10SJohan Hedberg 			return BT_SECURITY_FIPS;
6432b64d153SBrian Gix 		else
644d2eb9e10SJohan Hedberg 			return BT_SECURITY_HIGH;
645d2eb9e10SJohan Hedberg 	} else {
6462b64d153SBrian Gix 		return BT_SECURITY_MEDIUM;
6472b64d153SBrian Gix 	}
648d2eb9e10SJohan Hedberg }
6492b64d153SBrian Gix 
6502b64d153SBrian Gix static __u8 seclevel_to_authreq(__u8 sec_level)
6512b64d153SBrian Gix {
6522b64d153SBrian Gix 	switch (sec_level) {
653d2eb9e10SJohan Hedberg 	case BT_SECURITY_FIPS:
6542b64d153SBrian Gix 	case BT_SECURITY_HIGH:
6552b64d153SBrian Gix 		return SMP_AUTH_MITM | SMP_AUTH_BONDING;
6562b64d153SBrian Gix 	case BT_SECURITY_MEDIUM:
6572b64d153SBrian Gix 		return SMP_AUTH_BONDING;
6582b64d153SBrian Gix 	default:
6592b64d153SBrian Gix 		return SMP_AUTH_NONE;
6602b64d153SBrian Gix 	}
6612b64d153SBrian Gix }
6622b64d153SBrian Gix 
663b8e66eacSVinicius Costa Gomes static void build_pairing_cmd(struct l2cap_conn *conn,
66454790f73SVinicius Costa Gomes 			      struct smp_cmd_pairing *req,
665f1560463SMarcel Holtmann 			      struct smp_cmd_pairing *rsp, __u8 authreq)
666b8e66eacSVinicius Costa Gomes {
6675d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
6685d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
669fd349c02SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
670fd349c02SJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
67102b05bd8SJohan Hedberg 	u8 local_dist = 0, remote_dist = 0, oob_flag = SMP_OOB_NOT_PRESENT;
67254790f73SVinicius Costa Gomes 
673d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_BONDABLE)) {
6747ee4ea36SMarcel Holtmann 		local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
6757ee4ea36SMarcel Holtmann 		remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
67654790f73SVinicius Costa Gomes 		authreq |= SMP_AUTH_BONDING;
6772b64d153SBrian Gix 	} else {
6782b64d153SBrian Gix 		authreq &= ~SMP_AUTH_BONDING;
67954790f73SVinicius Costa Gomes 	}
68054790f73SVinicius Costa Gomes 
681d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_RPA_RESOLVING))
682fd349c02SJohan Hedberg 		remote_dist |= SMP_DIST_ID_KEY;
683fd349c02SJohan Hedberg 
684d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_PRIVACY))
685863efaf2SJohan Hedberg 		local_dist |= SMP_DIST_ID_KEY;
686863efaf2SJohan Hedberg 
687d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SC_ENABLED) &&
68802b05bd8SJohan Hedberg 	    (authreq & SMP_AUTH_SC)) {
68902b05bd8SJohan Hedberg 		struct oob_data *oob_data;
69002b05bd8SJohan Hedberg 		u8 bdaddr_type;
69102b05bd8SJohan Hedberg 
692d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_SSP_ENABLED)) {
693df8e1a4cSJohan Hedberg 			local_dist |= SMP_DIST_LINK_KEY;
694df8e1a4cSJohan Hedberg 			remote_dist |= SMP_DIST_LINK_KEY;
695df8e1a4cSJohan Hedberg 		}
69602b05bd8SJohan Hedberg 
69702b05bd8SJohan Hedberg 		if (hcon->dst_type == ADDR_LE_DEV_PUBLIC)
69802b05bd8SJohan Hedberg 			bdaddr_type = BDADDR_LE_PUBLIC;
69902b05bd8SJohan Hedberg 		else
70002b05bd8SJohan Hedberg 			bdaddr_type = BDADDR_LE_RANDOM;
70102b05bd8SJohan Hedberg 
70202b05bd8SJohan Hedberg 		oob_data = hci_find_remote_oob_data(hdev, &hcon->dst,
70302b05bd8SJohan Hedberg 						    bdaddr_type);
7044775a4eaSMarcel Holtmann 		if (oob_data && oob_data->present) {
7051a8bab4fSJohan Hedberg 			set_bit(SMP_FLAG_REMOTE_OOB, &smp->flags);
70602b05bd8SJohan Hedberg 			oob_flag = SMP_OOB_PRESENT;
707a29b0733SJohan Hedberg 			memcpy(smp->rr, oob_data->rand256, 16);
70802b05bd8SJohan Hedberg 			memcpy(smp->pcnf, oob_data->hash256, 16);
709bc07cd69SMarcel Holtmann 			SMP_DBG("OOB Remote Confirmation: %16phN", smp->pcnf);
710bc07cd69SMarcel Holtmann 			SMP_DBG("OOB Remote Random: %16phN", smp->rr);
71102b05bd8SJohan Hedberg 		}
71202b05bd8SJohan Hedberg 
713df8e1a4cSJohan Hedberg 	} else {
714df8e1a4cSJohan Hedberg 		authreq &= ~SMP_AUTH_SC;
715df8e1a4cSJohan Hedberg 	}
716df8e1a4cSJohan Hedberg 
71754790f73SVinicius Costa Gomes 	if (rsp == NULL) {
71854790f73SVinicius Costa Gomes 		req->io_capability = conn->hcon->io_capability;
71902b05bd8SJohan Hedberg 		req->oob_flag = oob_flag;
72030d65e08SMatias Karhumaa 		req->max_key_size = hdev->le_max_key_size;
721fd349c02SJohan Hedberg 		req->init_key_dist = local_dist;
722fd349c02SJohan Hedberg 		req->resp_key_dist = remote_dist;
7230edb14deSJohan Hedberg 		req->auth_req = (authreq & AUTH_REQ_MASK(hdev));
724fd349c02SJohan Hedberg 
725fd349c02SJohan Hedberg 		smp->remote_key_dist = remote_dist;
72654790f73SVinicius Costa Gomes 		return;
72754790f73SVinicius Costa Gomes 	}
72854790f73SVinicius Costa Gomes 
72954790f73SVinicius Costa Gomes 	rsp->io_capability = conn->hcon->io_capability;
73002b05bd8SJohan Hedberg 	rsp->oob_flag = oob_flag;
73130d65e08SMatias Karhumaa 	rsp->max_key_size = hdev->le_max_key_size;
732fd349c02SJohan Hedberg 	rsp->init_key_dist = req->init_key_dist & remote_dist;
733fd349c02SJohan Hedberg 	rsp->resp_key_dist = req->resp_key_dist & local_dist;
7340edb14deSJohan Hedberg 	rsp->auth_req = (authreq & AUTH_REQ_MASK(hdev));
735fd349c02SJohan Hedberg 
736fd349c02SJohan Hedberg 	smp->remote_key_dist = rsp->init_key_dist;
737b8e66eacSVinicius Costa Gomes }
738b8e66eacSVinicius Costa Gomes 
7393158c50cSVinicius Costa Gomes static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
7403158c50cSVinicius Costa Gomes {
7415d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
7422fd36558SJohan Hedberg 	struct hci_dev *hdev = conn->hcon->hdev;
7435d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
7441c1def09SVinicius Costa Gomes 
74530d65e08SMatias Karhumaa 	if (max_key_size > hdev->le_max_key_size ||
7462fd36558SJohan Hedberg 	    max_key_size < SMP_MIN_ENC_KEY_SIZE)
7473158c50cSVinicius Costa Gomes 		return SMP_ENC_KEY_SIZE;
7483158c50cSVinicius Costa Gomes 
749f7aa611aSVinicius Costa Gomes 	smp->enc_key_size = max_key_size;
7503158c50cSVinicius Costa Gomes 
7513158c50cSVinicius Costa Gomes 	return 0;
7523158c50cSVinicius Costa Gomes }
7533158c50cSVinicius Costa Gomes 
7546f48e260SJohan Hedberg static void smp_chan_destroy(struct l2cap_conn *conn)
7556f48e260SJohan Hedberg {
7566f48e260SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
7576f48e260SJohan Hedberg 	struct smp_chan *smp = chan->data;
758923e2414SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
7596f48e260SJohan Hedberg 	bool complete;
7606f48e260SJohan Hedberg 
7616f48e260SJohan Hedberg 	BUG_ON(!smp);
7626f48e260SJohan Hedberg 
7636f48e260SJohan Hedberg 	cancel_delayed_work_sync(&smp->security_timer);
7646f48e260SJohan Hedberg 
7656f48e260SJohan Hedberg 	complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags);
766923e2414SJohan Hedberg 	mgmt_smp_complete(hcon, complete);
7676f48e260SJohan Hedberg 
768276812ecSMarcel Holtmann 	kzfree(smp->csrk);
769276812ecSMarcel Holtmann 	kzfree(smp->slave_csrk);
770276812ecSMarcel Holtmann 	kzfree(smp->link_key);
7716f48e260SJohan Hedberg 
772a4770e11SAndy Lutomirski 	crypto_free_cipher(smp->tfm_aes);
77371af2f6bSHerbert Xu 	crypto_free_shash(smp->tfm_cmac);
77447eb2ac8STudor Ambarus 	crypto_free_kpp(smp->tfm_ecdh);
7756f48e260SJohan Hedberg 
776923e2414SJohan Hedberg 	/* Ensure that we don't leave any debug key around if debug key
777923e2414SJohan Hedberg 	 * support hasn't been explicitly enabled.
778923e2414SJohan Hedberg 	 */
779923e2414SJohan Hedberg 	if (smp->ltk && smp->ltk->type == SMP_LTK_P256_DEBUG &&
780d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hcon->hdev, HCI_KEEP_DEBUG_KEYS)) {
781923e2414SJohan Hedberg 		list_del_rcu(&smp->ltk->list);
782923e2414SJohan Hedberg 		kfree_rcu(smp->ltk, rcu);
783923e2414SJohan Hedberg 		smp->ltk = NULL;
784923e2414SJohan Hedberg 	}
785923e2414SJohan Hedberg 
7866f48e260SJohan Hedberg 	/* If pairing failed clean up any keys we might have */
7876f48e260SJohan Hedberg 	if (!complete) {
7886f48e260SJohan Hedberg 		if (smp->ltk) {
789970d0f1bSJohan Hedberg 			list_del_rcu(&smp->ltk->list);
790970d0f1bSJohan Hedberg 			kfree_rcu(smp->ltk, rcu);
7916f48e260SJohan Hedberg 		}
7926f48e260SJohan Hedberg 
7936f48e260SJohan Hedberg 		if (smp->slave_ltk) {
794970d0f1bSJohan Hedberg 			list_del_rcu(&smp->slave_ltk->list);
795970d0f1bSJohan Hedberg 			kfree_rcu(smp->slave_ltk, rcu);
7966f48e260SJohan Hedberg 		}
7976f48e260SJohan Hedberg 
7986f48e260SJohan Hedberg 		if (smp->remote_irk) {
799adae20cbSJohan Hedberg 			list_del_rcu(&smp->remote_irk->list);
800adae20cbSJohan Hedberg 			kfree_rcu(smp->remote_irk, rcu);
8016f48e260SJohan Hedberg 		}
8026f48e260SJohan Hedberg 	}
8036f48e260SJohan Hedberg 
8046f48e260SJohan Hedberg 	chan->data = NULL;
805276812ecSMarcel Holtmann 	kzfree(smp);
806923e2414SJohan Hedberg 	hci_conn_drop(hcon);
8076f48e260SJohan Hedberg }
8086f48e260SJohan Hedberg 
80984794e11SJohan Hedberg static void smp_failure(struct l2cap_conn *conn, u8 reason)
8104f957a76SBrian Gix {
811bab73cb6SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
812b68fda68SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
813bab73cb6SJohan Hedberg 
81484794e11SJohan Hedberg 	if (reason)
8154f957a76SBrian Gix 		smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
8164f957a76SBrian Gix 			     &reason);
8174f957a76SBrian Gix 
818e1e930f5SJohan Hedberg 	mgmt_auth_failed(hcon, HCI_ERROR_AUTH_FAILURE);
819f1c09c07SVinicius Costa Gomes 
820fc75cc86SJohan Hedberg 	if (chan->data)
8214f957a76SBrian Gix 		smp_chan_destroy(conn);
8224f957a76SBrian Gix }
8234f957a76SBrian Gix 
8242b64d153SBrian Gix #define JUST_WORKS	0x00
8252b64d153SBrian Gix #define JUST_CFM	0x01
8262b64d153SBrian Gix #define REQ_PASSKEY	0x02
8272b64d153SBrian Gix #define CFM_PASSKEY	0x03
8282b64d153SBrian Gix #define REQ_OOB		0x04
8295e3d3d9bSJohan Hedberg #define DSP_PASSKEY	0x05
8302b64d153SBrian Gix #define OVERLAP		0xFF
8312b64d153SBrian Gix 
8322b64d153SBrian Gix static const u8 gen_method[5][5] = {
8332b64d153SBrian Gix 	{ JUST_WORKS,  JUST_CFM,    REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
8342b64d153SBrian Gix 	{ JUST_WORKS,  JUST_CFM,    REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
8352b64d153SBrian Gix 	{ CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
8362b64d153SBrian Gix 	{ JUST_WORKS,  JUST_CFM,    JUST_WORKS,  JUST_WORKS, JUST_CFM    },
8372b64d153SBrian Gix 	{ CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, OVERLAP     },
8382b64d153SBrian Gix };
8392b64d153SBrian Gix 
8405e3d3d9bSJohan Hedberg static const u8 sc_method[5][5] = {
8415e3d3d9bSJohan Hedberg 	{ JUST_WORKS,  JUST_CFM,    REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
8425e3d3d9bSJohan Hedberg 	{ JUST_WORKS,  CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
8435e3d3d9bSJohan Hedberg 	{ DSP_PASSKEY, DSP_PASSKEY, REQ_PASSKEY, JUST_WORKS, DSP_PASSKEY },
8445e3d3d9bSJohan Hedberg 	{ JUST_WORKS,  JUST_CFM,    JUST_WORKS,  JUST_WORKS, JUST_CFM    },
8455e3d3d9bSJohan Hedberg 	{ DSP_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
8465e3d3d9bSJohan Hedberg };
8475e3d3d9bSJohan Hedberg 
848581370ccSJohan Hedberg static u8 get_auth_method(struct smp_chan *smp, u8 local_io, u8 remote_io)
849581370ccSJohan Hedberg {
8502bcd4003SJohan Hedberg 	/* If either side has unknown io_caps, use JUST_CFM (which gets
8512bcd4003SJohan Hedberg 	 * converted later to JUST_WORKS if we're initiators.
8522bcd4003SJohan Hedberg 	 */
853581370ccSJohan Hedberg 	if (local_io > SMP_IO_KEYBOARD_DISPLAY ||
854581370ccSJohan Hedberg 	    remote_io > SMP_IO_KEYBOARD_DISPLAY)
8552bcd4003SJohan Hedberg 		return JUST_CFM;
856581370ccSJohan Hedberg 
8575e3d3d9bSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags))
8585e3d3d9bSJohan Hedberg 		return sc_method[remote_io][local_io];
8595e3d3d9bSJohan Hedberg 
860581370ccSJohan Hedberg 	return gen_method[remote_io][local_io];
861581370ccSJohan Hedberg }
862581370ccSJohan Hedberg 
8632b64d153SBrian Gix static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
8642b64d153SBrian Gix 						u8 local_io, u8 remote_io)
8652b64d153SBrian Gix {
8662b64d153SBrian Gix 	struct hci_conn *hcon = conn->hcon;
8675d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
8685d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
8692b64d153SBrian Gix 	u32 passkey = 0;
8702b64d153SBrian Gix 	int ret = 0;
8712b64d153SBrian Gix 
8722b64d153SBrian Gix 	/* Initialize key for JUST WORKS */
8732b64d153SBrian Gix 	memset(smp->tk, 0, sizeof(smp->tk));
8744a74d658SJohan Hedberg 	clear_bit(SMP_FLAG_TK_VALID, &smp->flags);
8752b64d153SBrian Gix 
8762b64d153SBrian Gix 	BT_DBG("tk_request: auth:%d lcl:%d rem:%d", auth, local_io, remote_io);
8772b64d153SBrian Gix 
8782bcd4003SJohan Hedberg 	/* If neither side wants MITM, either "just" confirm an incoming
8792bcd4003SJohan Hedberg 	 * request or use just-works for outgoing ones. The JUST_CFM
8802bcd4003SJohan Hedberg 	 * will be converted to JUST_WORKS if necessary later in this
8812bcd4003SJohan Hedberg 	 * function. If either side has MITM look up the method from the
8822bcd4003SJohan Hedberg 	 * table.
8832bcd4003SJohan Hedberg 	 */
884581370ccSJohan Hedberg 	if (!(auth & SMP_AUTH_MITM))
885783e0574SJohan Hedberg 		smp->method = JUST_CFM;
8862b64d153SBrian Gix 	else
887783e0574SJohan Hedberg 		smp->method = get_auth_method(smp, local_io, remote_io);
8882b64d153SBrian Gix 
889a82505c7SJohan Hedberg 	/* Don't confirm locally initiated pairing attempts */
890783e0574SJohan Hedberg 	if (smp->method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR,
891783e0574SJohan Hedberg 						&smp->flags))
892783e0574SJohan Hedberg 		smp->method = JUST_WORKS;
893a82505c7SJohan Hedberg 
89402f3e254SJohan Hedberg 	/* Don't bother user space with no IO capabilities */
895783e0574SJohan Hedberg 	if (smp->method == JUST_CFM &&
896783e0574SJohan Hedberg 	    hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
897783e0574SJohan Hedberg 		smp->method = JUST_WORKS;
89802f3e254SJohan Hedberg 
8992b64d153SBrian Gix 	/* If Just Works, Continue with Zero TK */
900783e0574SJohan Hedberg 	if (smp->method == JUST_WORKS) {
9014a74d658SJohan Hedberg 		set_bit(SMP_FLAG_TK_VALID, &smp->flags);
9022b64d153SBrian Gix 		return 0;
9032b64d153SBrian Gix 	}
9042b64d153SBrian Gix 
90519c5ce9cSJohan Hedberg 	/* If this function is used for SC -> legacy fallback we
90619c5ce9cSJohan Hedberg 	 * can only recover the just-works case.
90719c5ce9cSJohan Hedberg 	 */
90819c5ce9cSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags))
90919c5ce9cSJohan Hedberg 		return -EINVAL;
91019c5ce9cSJohan Hedberg 
9112b64d153SBrian Gix 	/* Not Just Works/Confirm results in MITM Authentication */
912783e0574SJohan Hedberg 	if (smp->method != JUST_CFM) {
9134a74d658SJohan Hedberg 		set_bit(SMP_FLAG_MITM_AUTH, &smp->flags);
9145eb596f5SJohan Hedberg 		if (hcon->pending_sec_level < BT_SECURITY_HIGH)
9155eb596f5SJohan Hedberg 			hcon->pending_sec_level = BT_SECURITY_HIGH;
9165eb596f5SJohan Hedberg 	}
9172b64d153SBrian Gix 
9182b64d153SBrian Gix 	/* If both devices have Keyoard-Display I/O, the master
9192b64d153SBrian Gix 	 * Confirms and the slave Enters the passkey.
9202b64d153SBrian Gix 	 */
921783e0574SJohan Hedberg 	if (smp->method == OVERLAP) {
92240bef302SJohan Hedberg 		if (hcon->role == HCI_ROLE_MASTER)
923783e0574SJohan Hedberg 			smp->method = CFM_PASSKEY;
9242b64d153SBrian Gix 		else
925783e0574SJohan Hedberg 			smp->method = REQ_PASSKEY;
9262b64d153SBrian Gix 	}
9272b64d153SBrian Gix 
92801ad34d2SJohan Hedberg 	/* Generate random passkey. */
929783e0574SJohan Hedberg 	if (smp->method == CFM_PASSKEY) {
930943a732aSJohan Hedberg 		memset(smp->tk, 0, sizeof(smp->tk));
9312b64d153SBrian Gix 		get_random_bytes(&passkey, sizeof(passkey));
9322b64d153SBrian Gix 		passkey %= 1000000;
933943a732aSJohan Hedberg 		put_unaligned_le32(passkey, smp->tk);
9342b64d153SBrian Gix 		BT_DBG("PassKey: %d", passkey);
9354a74d658SJohan Hedberg 		set_bit(SMP_FLAG_TK_VALID, &smp->flags);
9362b64d153SBrian Gix 	}
9372b64d153SBrian Gix 
938783e0574SJohan Hedberg 	if (smp->method == REQ_PASSKEY)
939ce39fb4eSMarcel Holtmann 		ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst,
940272d90dfSJohan Hedberg 						hcon->type, hcon->dst_type);
941783e0574SJohan Hedberg 	else if (smp->method == JUST_CFM)
9424eb65e66SJohan Hedberg 		ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
9434eb65e66SJohan Hedberg 						hcon->type, hcon->dst_type,
9444eb65e66SJohan Hedberg 						passkey, 1);
9452b64d153SBrian Gix 	else
94601ad34d2SJohan Hedberg 		ret = mgmt_user_passkey_notify(hcon->hdev, &hcon->dst,
947272d90dfSJohan Hedberg 						hcon->type, hcon->dst_type,
94839adbffeSJohan Hedberg 						passkey, 0);
9492b64d153SBrian Gix 
9502b64d153SBrian Gix 	return ret;
9512b64d153SBrian Gix }
9522b64d153SBrian Gix 
9531cc61144SJohan Hedberg static u8 smp_confirm(struct smp_chan *smp)
9548aab4757SVinicius Costa Gomes {
9558aab4757SVinicius Costa Gomes 	struct l2cap_conn *conn = smp->conn;
9568aab4757SVinicius Costa Gomes 	struct smp_cmd_pairing_confirm cp;
9578aab4757SVinicius Costa Gomes 	int ret;
9588aab4757SVinicius Costa Gomes 
9598aab4757SVinicius Costa Gomes 	BT_DBG("conn %p", conn);
9608aab4757SVinicius Costa Gomes 
961e491eaf3SJohan Hedberg 	ret = smp_c1(smp->tfm_aes, smp->tk, smp->prnd, smp->preq, smp->prsp,
962b1cd5fd9SJohan Hedberg 		     conn->hcon->init_addr_type, &conn->hcon->init_addr,
963943a732aSJohan Hedberg 		     conn->hcon->resp_addr_type, &conn->hcon->resp_addr,
964943a732aSJohan Hedberg 		     cp.confirm_val);
9651cc61144SJohan Hedberg 	if (ret)
9661cc61144SJohan Hedberg 		return SMP_UNSPECIFIED;
9678aab4757SVinicius Costa Gomes 
9684a74d658SJohan Hedberg 	clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
9692b64d153SBrian Gix 
9708aab4757SVinicius Costa Gomes 	smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
9718aab4757SVinicius Costa Gomes 
972b28b4943SJohan Hedberg 	if (conn->hcon->out)
973b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
974b28b4943SJohan Hedberg 	else
975b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
976b28b4943SJohan Hedberg 
9771cc61144SJohan Hedberg 	return 0;
9788aab4757SVinicius Costa Gomes }
9798aab4757SVinicius Costa Gomes 
980861580a9SJohan Hedberg static u8 smp_random(struct smp_chan *smp)
9818aab4757SVinicius Costa Gomes {
9828aab4757SVinicius Costa Gomes 	struct l2cap_conn *conn = smp->conn;
9838aab4757SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
984861580a9SJohan Hedberg 	u8 confirm[16];
9858aab4757SVinicius Costa Gomes 	int ret;
9868aab4757SVinicius Costa Gomes 
987ec70f36fSJohan Hedberg 	if (IS_ERR_OR_NULL(smp->tfm_aes))
988861580a9SJohan Hedberg 		return SMP_UNSPECIFIED;
9898aab4757SVinicius Costa Gomes 
9908aab4757SVinicius Costa Gomes 	BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
9918aab4757SVinicius Costa Gomes 
992e491eaf3SJohan Hedberg 	ret = smp_c1(smp->tfm_aes, smp->tk, smp->rrnd, smp->preq, smp->prsp,
993b1cd5fd9SJohan Hedberg 		     hcon->init_addr_type, &hcon->init_addr,
994943a732aSJohan Hedberg 		     hcon->resp_addr_type, &hcon->resp_addr, confirm);
995861580a9SJohan Hedberg 	if (ret)
996861580a9SJohan Hedberg 		return SMP_UNSPECIFIED;
9978aab4757SVinicius Costa Gomes 
998329d8230SJason A. Donenfeld 	if (crypto_memneq(smp->pcnf, confirm, sizeof(smp->pcnf))) {
9992064ee33SMarcel Holtmann 		bt_dev_err(hcon->hdev, "pairing failed "
10002064ee33SMarcel Holtmann 			   "(confirmation values mismatch)");
1001861580a9SJohan Hedberg 		return SMP_CONFIRM_FAILED;
10028aab4757SVinicius Costa Gomes 	}
10038aab4757SVinicius Costa Gomes 
10048aab4757SVinicius Costa Gomes 	if (hcon->out) {
1005fe39c7b2SMarcel Holtmann 		u8 stk[16];
1006fe39c7b2SMarcel Holtmann 		__le64 rand = 0;
1007fe39c7b2SMarcel Holtmann 		__le16 ediv = 0;
10088aab4757SVinicius Costa Gomes 
1009e491eaf3SJohan Hedberg 		smp_s1(smp->tfm_aes, smp->tk, smp->rrnd, smp->prnd, stk);
10108aab4757SVinicius Costa Gomes 
1011861580a9SJohan Hedberg 		if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
1012861580a9SJohan Hedberg 			return SMP_UNSPECIFIED;
10138aab4757SVinicius Costa Gomes 
10148b76ce34SJohan Hedberg 		hci_le_start_enc(hcon, ediv, rand, stk, smp->enc_key_size);
1015f7aa611aSVinicius Costa Gomes 		hcon->enc_key_size = smp->enc_key_size;
1016fe59a05fSJohan Hedberg 		set_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags);
10178aab4757SVinicius Costa Gomes 	} else {
1018fff3490fSJohan Hedberg 		u8 stk[16], auth;
1019fe39c7b2SMarcel Holtmann 		__le64 rand = 0;
1020fe39c7b2SMarcel Holtmann 		__le16 ediv = 0;
10218aab4757SVinicius Costa Gomes 
1022943a732aSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
1023943a732aSJohan Hedberg 			     smp->prnd);
10248aab4757SVinicius Costa Gomes 
1025e491eaf3SJohan Hedberg 		smp_s1(smp->tfm_aes, smp->tk, smp->prnd, smp->rrnd, stk);
10268aab4757SVinicius Costa Gomes 
1027fff3490fSJohan Hedberg 		if (hcon->pending_sec_level == BT_SECURITY_HIGH)
1028fff3490fSJohan Hedberg 			auth = 1;
1029fff3490fSJohan Hedberg 		else
1030fff3490fSJohan Hedberg 			auth = 0;
1031fff3490fSJohan Hedberg 
10327d5843b7SJohan Hedberg 		/* Even though there's no _SLAVE suffix this is the
10337d5843b7SJohan Hedberg 		 * slave STK we're adding for later lookup (the master
10347d5843b7SJohan Hedberg 		 * STK never needs to be stored).
10357d5843b7SJohan Hedberg 		 */
1036ce39fb4eSMarcel Holtmann 		hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
10372ceba539SJohan Hedberg 			    SMP_STK, auth, stk, smp->enc_key_size, ediv, rand);
10388aab4757SVinicius Costa Gomes 	}
10398aab4757SVinicius Costa Gomes 
1040861580a9SJohan Hedberg 	return 0;
10418aab4757SVinicius Costa Gomes }
10428aab4757SVinicius Costa Gomes 
104344f1a7abSJohan Hedberg static void smp_notify_keys(struct l2cap_conn *conn)
104444f1a7abSJohan Hedberg {
104544f1a7abSJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
104644f1a7abSJohan Hedberg 	struct smp_chan *smp = chan->data;
104744f1a7abSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
104844f1a7abSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
104944f1a7abSJohan Hedberg 	struct smp_cmd_pairing *req = (void *) &smp->preq[1];
105044f1a7abSJohan Hedberg 	struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1];
105144f1a7abSJohan Hedberg 	bool persistent;
105244f1a7abSJohan Hedberg 
1053cad20c27SJohan Hedberg 	if (hcon->type == ACL_LINK) {
1054cad20c27SJohan Hedberg 		if (hcon->key_type == HCI_LK_DEBUG_COMBINATION)
1055cad20c27SJohan Hedberg 			persistent = false;
1056cad20c27SJohan Hedberg 		else
1057cad20c27SJohan Hedberg 			persistent = !test_bit(HCI_CONN_FLUSH_KEY,
1058cad20c27SJohan Hedberg 					       &hcon->flags);
1059cad20c27SJohan Hedberg 	} else {
1060cad20c27SJohan Hedberg 		/* The LTKs, IRKs and CSRKs should be persistent only if
1061cad20c27SJohan Hedberg 		 * both sides had the bonding bit set in their
1062cad20c27SJohan Hedberg 		 * authentication requests.
1063cad20c27SJohan Hedberg 		 */
1064cad20c27SJohan Hedberg 		persistent = !!((req->auth_req & rsp->auth_req) &
1065cad20c27SJohan Hedberg 				SMP_AUTH_BONDING);
1066cad20c27SJohan Hedberg 	}
1067cad20c27SJohan Hedberg 
106844f1a7abSJohan Hedberg 	if (smp->remote_irk) {
1069cad20c27SJohan Hedberg 		mgmt_new_irk(hdev, smp->remote_irk, persistent);
1070cad20c27SJohan Hedberg 
107144f1a7abSJohan Hedberg 		/* Now that user space can be considered to know the
107244f1a7abSJohan Hedberg 		 * identity address track the connection based on it
1073b5ae344dSJohan Hedberg 		 * from now on (assuming this is an LE link).
107444f1a7abSJohan Hedberg 		 */
1075b5ae344dSJohan Hedberg 		if (hcon->type == LE_LINK) {
107644f1a7abSJohan Hedberg 			bacpy(&hcon->dst, &smp->remote_irk->bdaddr);
107744f1a7abSJohan Hedberg 			hcon->dst_type = smp->remote_irk->addr_type;
1078f3d82d0cSJohan Hedberg 			queue_work(hdev->workqueue, &conn->id_addr_update_work);
1079b5ae344dSJohan Hedberg 		}
108044f1a7abSJohan Hedberg 	}
108144f1a7abSJohan Hedberg 
108244f1a7abSJohan Hedberg 	if (smp->csrk) {
108344f1a7abSJohan Hedberg 		smp->csrk->bdaddr_type = hcon->dst_type;
108444f1a7abSJohan Hedberg 		bacpy(&smp->csrk->bdaddr, &hcon->dst);
108544f1a7abSJohan Hedberg 		mgmt_new_csrk(hdev, smp->csrk, persistent);
108644f1a7abSJohan Hedberg 	}
108744f1a7abSJohan Hedberg 
108844f1a7abSJohan Hedberg 	if (smp->slave_csrk) {
108944f1a7abSJohan Hedberg 		smp->slave_csrk->bdaddr_type = hcon->dst_type;
109044f1a7abSJohan Hedberg 		bacpy(&smp->slave_csrk->bdaddr, &hcon->dst);
109144f1a7abSJohan Hedberg 		mgmt_new_csrk(hdev, smp->slave_csrk, persistent);
109244f1a7abSJohan Hedberg 	}
109344f1a7abSJohan Hedberg 
109444f1a7abSJohan Hedberg 	if (smp->ltk) {
109544f1a7abSJohan Hedberg 		smp->ltk->bdaddr_type = hcon->dst_type;
109644f1a7abSJohan Hedberg 		bacpy(&smp->ltk->bdaddr, &hcon->dst);
109744f1a7abSJohan Hedberg 		mgmt_new_ltk(hdev, smp->ltk, persistent);
109844f1a7abSJohan Hedberg 	}
109944f1a7abSJohan Hedberg 
110044f1a7abSJohan Hedberg 	if (smp->slave_ltk) {
110144f1a7abSJohan Hedberg 		smp->slave_ltk->bdaddr_type = hcon->dst_type;
110244f1a7abSJohan Hedberg 		bacpy(&smp->slave_ltk->bdaddr, &hcon->dst);
110344f1a7abSJohan Hedberg 		mgmt_new_ltk(hdev, smp->slave_ltk, persistent);
110444f1a7abSJohan Hedberg 	}
11056a77083aSJohan Hedberg 
11066a77083aSJohan Hedberg 	if (smp->link_key) {
1107e3befab9SJohan Hedberg 		struct link_key *key;
1108e3befab9SJohan Hedberg 		u8 type;
1109e3befab9SJohan Hedberg 
1110e3befab9SJohan Hedberg 		if (test_bit(SMP_FLAG_DEBUG_KEY, &smp->flags))
1111e3befab9SJohan Hedberg 			type = HCI_LK_DEBUG_COMBINATION;
1112e3befab9SJohan Hedberg 		else if (hcon->sec_level == BT_SECURITY_FIPS)
1113e3befab9SJohan Hedberg 			type = HCI_LK_AUTH_COMBINATION_P256;
1114e3befab9SJohan Hedberg 		else
1115e3befab9SJohan Hedberg 			type = HCI_LK_UNAUTH_COMBINATION_P256;
1116e3befab9SJohan Hedberg 
1117e3befab9SJohan Hedberg 		key = hci_add_link_key(hdev, smp->conn->hcon, &hcon->dst,
1118e3befab9SJohan Hedberg 				       smp->link_key, type, 0, &persistent);
1119e3befab9SJohan Hedberg 		if (key) {
1120e3befab9SJohan Hedberg 			mgmt_new_link_key(hdev, key, persistent);
1121e3befab9SJohan Hedberg 
1122e3befab9SJohan Hedberg 			/* Don't keep debug keys around if the relevant
1123e3befab9SJohan Hedberg 			 * flag is not set.
1124e3befab9SJohan Hedberg 			 */
1125d7a5a11dSMarcel Holtmann 			if (!hci_dev_test_flag(hdev, HCI_KEEP_DEBUG_KEYS) &&
1126e3befab9SJohan Hedberg 			    key->type == HCI_LK_DEBUG_COMBINATION) {
1127e3befab9SJohan Hedberg 				list_del_rcu(&key->list);
1128e3befab9SJohan Hedberg 				kfree_rcu(key, rcu);
1129e3befab9SJohan Hedberg 			}
1130e3befab9SJohan Hedberg 		}
11316a77083aSJohan Hedberg 	}
11326a77083aSJohan Hedberg }
11336a77083aSJohan Hedberg 
1134d3e54a87SJohan Hedberg static void sc_add_ltk(struct smp_chan *smp)
1135d3e54a87SJohan Hedberg {
1136d3e54a87SJohan Hedberg 	struct hci_conn *hcon = smp->conn->hcon;
1137d3e54a87SJohan Hedberg 	u8 key_type, auth;
1138d3e54a87SJohan Hedberg 
1139d3e54a87SJohan Hedberg 	if (test_bit(SMP_FLAG_DEBUG_KEY, &smp->flags))
1140d3e54a87SJohan Hedberg 		key_type = SMP_LTK_P256_DEBUG;
1141d3e54a87SJohan Hedberg 	else
1142d3e54a87SJohan Hedberg 		key_type = SMP_LTK_P256;
1143d3e54a87SJohan Hedberg 
1144d3e54a87SJohan Hedberg 	if (hcon->pending_sec_level == BT_SECURITY_FIPS)
1145d3e54a87SJohan Hedberg 		auth = 1;
1146d3e54a87SJohan Hedberg 	else
1147d3e54a87SJohan Hedberg 		auth = 0;
1148d3e54a87SJohan Hedberg 
1149d3e54a87SJohan Hedberg 	smp->ltk = hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
1150d3e54a87SJohan Hedberg 			       key_type, auth, smp->tk, smp->enc_key_size,
1151d3e54a87SJohan Hedberg 			       0, 0);
1152d3e54a87SJohan Hedberg }
1153d3e54a87SJohan Hedberg 
11546a77083aSJohan Hedberg static void sc_generate_link_key(struct smp_chan *smp)
11556a77083aSJohan Hedberg {
1156a62da6f1SJohan Hedberg 	/* From core spec. Spells out in ASCII as 'lebr'. */
11576a77083aSJohan Hedberg 	const u8 lebr[4] = { 0x72, 0x62, 0x65, 0x6c };
11586a77083aSJohan Hedberg 
11596a77083aSJohan Hedberg 	smp->link_key = kzalloc(16, GFP_KERNEL);
11606a77083aSJohan Hedberg 	if (!smp->link_key)
11616a77083aSJohan Hedberg 		return;
11626a77083aSJohan Hedberg 
1163a62da6f1SJohan Hedberg 	if (test_bit(SMP_FLAG_CT2, &smp->flags)) {
1164a62da6f1SJohan Hedberg 		/* SALT = 0x00000000000000000000000000000000746D7031 */
1165a62da6f1SJohan Hedberg 		const u8 salt[16] = { 0x31, 0x70, 0x6d, 0x74 };
1166a62da6f1SJohan Hedberg 
1167a62da6f1SJohan Hedberg 		if (smp_h7(smp->tfm_cmac, smp->tk, salt, smp->link_key)) {
1168a62da6f1SJohan Hedberg 			kzfree(smp->link_key);
1169a62da6f1SJohan Hedberg 			smp->link_key = NULL;
1170a62da6f1SJohan Hedberg 			return;
1171a62da6f1SJohan Hedberg 		}
1172a62da6f1SJohan Hedberg 	} else {
1173a62da6f1SJohan Hedberg 		/* From core spec. Spells out in ASCII as 'tmp1'. */
1174a62da6f1SJohan Hedberg 		const u8 tmp1[4] = { 0x31, 0x70, 0x6d, 0x74 };
1175a62da6f1SJohan Hedberg 
11766a77083aSJohan Hedberg 		if (smp_h6(smp->tfm_cmac, smp->tk, tmp1, smp->link_key)) {
1177276812ecSMarcel Holtmann 			kzfree(smp->link_key);
11786a77083aSJohan Hedberg 			smp->link_key = NULL;
11796a77083aSJohan Hedberg 			return;
11806a77083aSJohan Hedberg 		}
1181a62da6f1SJohan Hedberg 	}
11826a77083aSJohan Hedberg 
11836a77083aSJohan Hedberg 	if (smp_h6(smp->tfm_cmac, smp->link_key, lebr, smp->link_key)) {
1184276812ecSMarcel Holtmann 		kzfree(smp->link_key);
11856a77083aSJohan Hedberg 		smp->link_key = NULL;
11866a77083aSJohan Hedberg 		return;
11876a77083aSJohan Hedberg 	}
118844f1a7abSJohan Hedberg }
118944f1a7abSJohan Hedberg 
1190b28b4943SJohan Hedberg static void smp_allow_key_dist(struct smp_chan *smp)
1191b28b4943SJohan Hedberg {
1192b28b4943SJohan Hedberg 	/* Allow the first expected phase 3 PDU. The rest of the PDUs
1193b28b4943SJohan Hedberg 	 * will be allowed in each PDU handler to ensure we receive
1194b28b4943SJohan Hedberg 	 * them in the correct order.
1195b28b4943SJohan Hedberg 	 */
1196b28b4943SJohan Hedberg 	if (smp->remote_key_dist & SMP_DIST_ENC_KEY)
1197b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_ENCRYPT_INFO);
1198b28b4943SJohan Hedberg 	else if (smp->remote_key_dist & SMP_DIST_ID_KEY)
1199b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO);
1200b28b4943SJohan Hedberg 	else if (smp->remote_key_dist & SMP_DIST_SIGN)
1201b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO);
1202b28b4943SJohan Hedberg }
1203b28b4943SJohan Hedberg 
1204b5ae344dSJohan Hedberg static void sc_generate_ltk(struct smp_chan *smp)
1205b5ae344dSJohan Hedberg {
1206a62da6f1SJohan Hedberg 	/* From core spec. Spells out in ASCII as 'brle'. */
1207b5ae344dSJohan Hedberg 	const u8 brle[4] = { 0x65, 0x6c, 0x72, 0x62 };
1208b5ae344dSJohan Hedberg 	struct hci_conn *hcon = smp->conn->hcon;
1209b5ae344dSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
1210b5ae344dSJohan Hedberg 	struct link_key *key;
1211b5ae344dSJohan Hedberg 
1212b5ae344dSJohan Hedberg 	key = hci_find_link_key(hdev, &hcon->dst);
1213b5ae344dSJohan Hedberg 	if (!key) {
12142064ee33SMarcel Holtmann 		bt_dev_err(hdev, "no Link Key found to generate LTK");
1215b5ae344dSJohan Hedberg 		return;
1216b5ae344dSJohan Hedberg 	}
1217b5ae344dSJohan Hedberg 
1218b5ae344dSJohan Hedberg 	if (key->type == HCI_LK_DEBUG_COMBINATION)
1219b5ae344dSJohan Hedberg 		set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags);
1220b5ae344dSJohan Hedberg 
1221a62da6f1SJohan Hedberg 	if (test_bit(SMP_FLAG_CT2, &smp->flags)) {
1222a62da6f1SJohan Hedberg 		/* SALT = 0x00000000000000000000000000000000746D7032 */
1223a62da6f1SJohan Hedberg 		const u8 salt[16] = { 0x32, 0x70, 0x6d, 0x74 };
1224a62da6f1SJohan Hedberg 
1225a62da6f1SJohan Hedberg 		if (smp_h7(smp->tfm_cmac, key->val, salt, smp->tk))
1226a62da6f1SJohan Hedberg 			return;
1227a62da6f1SJohan Hedberg 	} else {
1228a62da6f1SJohan Hedberg 		/* From core spec. Spells out in ASCII as 'tmp2'. */
1229a62da6f1SJohan Hedberg 		const u8 tmp2[4] = { 0x32, 0x70, 0x6d, 0x74 };
1230a62da6f1SJohan Hedberg 
1231b5ae344dSJohan Hedberg 		if (smp_h6(smp->tfm_cmac, key->val, tmp2, smp->tk))
1232b5ae344dSJohan Hedberg 			return;
1233a62da6f1SJohan Hedberg 	}
1234b5ae344dSJohan Hedberg 
1235b5ae344dSJohan Hedberg 	if (smp_h6(smp->tfm_cmac, smp->tk, brle, smp->tk))
1236b5ae344dSJohan Hedberg 		return;
1237b5ae344dSJohan Hedberg 
1238b5ae344dSJohan Hedberg 	sc_add_ltk(smp);
1239b5ae344dSJohan Hedberg }
1240b5ae344dSJohan Hedberg 
1241d6268e86SJohan Hedberg static void smp_distribute_keys(struct smp_chan *smp)
124244f1a7abSJohan Hedberg {
124344f1a7abSJohan Hedberg 	struct smp_cmd_pairing *req, *rsp;
124486d1407cSJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
124544f1a7abSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
124644f1a7abSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
124744f1a7abSJohan Hedberg 	__u8 *keydist;
124844f1a7abSJohan Hedberg 
124944f1a7abSJohan Hedberg 	BT_DBG("conn %p", conn);
125044f1a7abSJohan Hedberg 
125144f1a7abSJohan Hedberg 	rsp = (void *) &smp->prsp[1];
125244f1a7abSJohan Hedberg 
125344f1a7abSJohan Hedberg 	/* The responder sends its keys first */
1254b28b4943SJohan Hedberg 	if (hcon->out && (smp->remote_key_dist & KEY_DIST_MASK)) {
1255b28b4943SJohan Hedberg 		smp_allow_key_dist(smp);
125686d1407cSJohan Hedberg 		return;
1257b28b4943SJohan Hedberg 	}
125844f1a7abSJohan Hedberg 
125944f1a7abSJohan Hedberg 	req = (void *) &smp->preq[1];
126044f1a7abSJohan Hedberg 
126144f1a7abSJohan Hedberg 	if (hcon->out) {
126244f1a7abSJohan Hedberg 		keydist = &rsp->init_key_dist;
126344f1a7abSJohan Hedberg 		*keydist &= req->init_key_dist;
126444f1a7abSJohan Hedberg 	} else {
126544f1a7abSJohan Hedberg 		keydist = &rsp->resp_key_dist;
126644f1a7abSJohan Hedberg 		*keydist &= req->resp_key_dist;
126744f1a7abSJohan Hedberg 	}
126844f1a7abSJohan Hedberg 
12696a77083aSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
1270b5ae344dSJohan Hedberg 		if (hcon->type == LE_LINK && (*keydist & SMP_DIST_LINK_KEY))
12716a77083aSJohan Hedberg 			sc_generate_link_key(smp);
1272b5ae344dSJohan Hedberg 		if (hcon->type == ACL_LINK && (*keydist & SMP_DIST_ENC_KEY))
1273b5ae344dSJohan Hedberg 			sc_generate_ltk(smp);
12746a77083aSJohan Hedberg 
12756a77083aSJohan Hedberg 		/* Clear the keys which are generated but not distributed */
12766a77083aSJohan Hedberg 		*keydist &= ~SMP_SC_NO_DIST;
12776a77083aSJohan Hedberg 	}
12786a77083aSJohan Hedberg 
127944f1a7abSJohan Hedberg 	BT_DBG("keydist 0x%x", *keydist);
128044f1a7abSJohan Hedberg 
128144f1a7abSJohan Hedberg 	if (*keydist & SMP_DIST_ENC_KEY) {
128244f1a7abSJohan Hedberg 		struct smp_cmd_encrypt_info enc;
128344f1a7abSJohan Hedberg 		struct smp_cmd_master_ident ident;
128444f1a7abSJohan Hedberg 		struct smp_ltk *ltk;
128544f1a7abSJohan Hedberg 		u8 authenticated;
128644f1a7abSJohan Hedberg 		__le16 ediv;
128744f1a7abSJohan Hedberg 		__le64 rand;
128844f1a7abSJohan Hedberg 
12891fc62c52SJohan Hedberg 		/* Make sure we generate only the significant amount of
12901fc62c52SJohan Hedberg 		 * bytes based on the encryption key size, and set the rest
12911fc62c52SJohan Hedberg 		 * of the value to zeroes.
12921fc62c52SJohan Hedberg 		 */
12931fc62c52SJohan Hedberg 		get_random_bytes(enc.ltk, smp->enc_key_size);
12941fc62c52SJohan Hedberg 		memset(enc.ltk + smp->enc_key_size, 0,
12951fc62c52SJohan Hedberg 		       sizeof(enc.ltk) - smp->enc_key_size);
12961fc62c52SJohan Hedberg 
129744f1a7abSJohan Hedberg 		get_random_bytes(&ediv, sizeof(ediv));
129844f1a7abSJohan Hedberg 		get_random_bytes(&rand, sizeof(rand));
129944f1a7abSJohan Hedberg 
130044f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
130144f1a7abSJohan Hedberg 
130244f1a7abSJohan Hedberg 		authenticated = hcon->sec_level == BT_SECURITY_HIGH;
130344f1a7abSJohan Hedberg 		ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type,
130444f1a7abSJohan Hedberg 				  SMP_LTK_SLAVE, authenticated, enc.ltk,
130544f1a7abSJohan Hedberg 				  smp->enc_key_size, ediv, rand);
130644f1a7abSJohan Hedberg 		smp->slave_ltk = ltk;
130744f1a7abSJohan Hedberg 
130844f1a7abSJohan Hedberg 		ident.ediv = ediv;
130944f1a7abSJohan Hedberg 		ident.rand = rand;
131044f1a7abSJohan Hedberg 
131144f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &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 		}
135444f1a7abSJohan Hedberg 		smp->slave_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 
1379b68fda68SJohan Hedberg 	BT_DBG("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 {
13865d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
13878aab4757SVinicius Costa Gomes 	struct smp_chan *smp;
13888aab4757SVinicius Costa Gomes 
1389f1560463SMarcel Holtmann 	smp = kzalloc(sizeof(*smp), GFP_ATOMIC);
1390fc75cc86SJohan Hedberg 	if (!smp)
13918aab4757SVinicius Costa Gomes 		return NULL;
13928aab4757SVinicius Costa Gomes 
1393a4770e11SAndy Lutomirski 	smp->tfm_aes = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
13946a7bd103SJohan Hedberg 	if (IS_ERR(smp->tfm_aes)) {
1395a4770e11SAndy Lutomirski 		BT_ERR("Unable to create AES crypto context");
139647eb2ac8STudor Ambarus 		goto zfree_smp;
13976a7bd103SJohan Hedberg 	}
13986a7bd103SJohan Hedberg 
139971af2f6bSHerbert Xu 	smp->tfm_cmac = crypto_alloc_shash("cmac(aes)", 0, 0);
1400407cecf6SJohan Hedberg 	if (IS_ERR(smp->tfm_cmac)) {
1401407cecf6SJohan Hedberg 		BT_ERR("Unable to create CMAC crypto context");
140247eb2ac8STudor Ambarus 		goto free_cipher;
140347eb2ac8STudor Ambarus 	}
140447eb2ac8STudor Ambarus 
140547eb2ac8STudor Ambarus 	smp->tfm_ecdh = crypto_alloc_kpp("ecdh", CRYPTO_ALG_INTERNAL, 0);
140647eb2ac8STudor Ambarus 	if (IS_ERR(smp->tfm_ecdh)) {
140747eb2ac8STudor Ambarus 		BT_ERR("Unable to create ECDH crypto context");
140847eb2ac8STudor Ambarus 		goto free_shash;
1409407cecf6SJohan Hedberg 	}
1410407cecf6SJohan Hedberg 
14118aab4757SVinicius Costa Gomes 	smp->conn = conn;
14125d88cc73SJohan Hedberg 	chan->data = smp;
14138aab4757SVinicius Costa Gomes 
1414b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_FAIL);
1415b28b4943SJohan Hedberg 
1416b68fda68SJohan Hedberg 	INIT_DELAYED_WORK(&smp->security_timer, smp_timeout);
1417b68fda68SJohan Hedberg 
14188aab4757SVinicius Costa Gomes 	hci_conn_hold(conn->hcon);
14198aab4757SVinicius Costa Gomes 
14208aab4757SVinicius Costa Gomes 	return smp;
142147eb2ac8STudor Ambarus 
142247eb2ac8STudor Ambarus free_shash:
142347eb2ac8STudor Ambarus 	crypto_free_shash(smp->tfm_cmac);
142447eb2ac8STudor Ambarus free_cipher:
142547eb2ac8STudor Ambarus 	crypto_free_cipher(smp->tfm_aes);
142647eb2ac8STudor Ambarus zfree_smp:
142747eb2ac8STudor Ambarus 	kzfree(smp);
142847eb2ac8STudor Ambarus 	return NULL;
14298aab4757SVinicius Costa Gomes }
14308aab4757SVinicius Costa Gomes 
1431760b018bSJohan Hedberg static int sc_mackey_and_ltk(struct smp_chan *smp, u8 mackey[16], u8 ltk[16])
1432760b018bSJohan Hedberg {
1433760b018bSJohan Hedberg 	struct hci_conn *hcon = smp->conn->hcon;
1434760b018bSJohan Hedberg 	u8 *na, *nb, a[7], b[7];
1435760b018bSJohan Hedberg 
1436760b018bSJohan Hedberg 	if (hcon->out) {
1437760b018bSJohan Hedberg 		na   = smp->prnd;
1438760b018bSJohan Hedberg 		nb   = smp->rrnd;
1439760b018bSJohan Hedberg 	} else {
1440760b018bSJohan Hedberg 		na   = smp->rrnd;
1441760b018bSJohan Hedberg 		nb   = smp->prnd;
1442760b018bSJohan Hedberg 	}
1443760b018bSJohan Hedberg 
1444760b018bSJohan Hedberg 	memcpy(a, &hcon->init_addr, 6);
1445760b018bSJohan Hedberg 	memcpy(b, &hcon->resp_addr, 6);
1446760b018bSJohan Hedberg 	a[6] = hcon->init_addr_type;
1447760b018bSJohan Hedberg 	b[6] = hcon->resp_addr_type;
1448760b018bSJohan Hedberg 
1449760b018bSJohan Hedberg 	return smp_f5(smp->tfm_cmac, smp->dhkey, na, nb, a, b, mackey, ltk);
1450760b018bSJohan Hedberg }
1451760b018bSJohan Hedberg 
145238606f14SJohan Hedberg static void sc_dhkey_check(struct smp_chan *smp)
1453760b018bSJohan Hedberg {
1454760b018bSJohan Hedberg 	struct hci_conn *hcon = smp->conn->hcon;
1455760b018bSJohan Hedberg 	struct smp_cmd_dhkey_check check;
1456760b018bSJohan Hedberg 	u8 a[7], b[7], *local_addr, *remote_addr;
1457760b018bSJohan Hedberg 	u8 io_cap[3], r[16];
1458760b018bSJohan Hedberg 
1459760b018bSJohan Hedberg 	memcpy(a, &hcon->init_addr, 6);
1460760b018bSJohan Hedberg 	memcpy(b, &hcon->resp_addr, 6);
1461760b018bSJohan Hedberg 	a[6] = hcon->init_addr_type;
1462760b018bSJohan Hedberg 	b[6] = hcon->resp_addr_type;
1463760b018bSJohan Hedberg 
1464760b018bSJohan Hedberg 	if (hcon->out) {
1465760b018bSJohan Hedberg 		local_addr = a;
1466760b018bSJohan Hedberg 		remote_addr = b;
1467760b018bSJohan Hedberg 		memcpy(io_cap, &smp->preq[1], 3);
1468760b018bSJohan Hedberg 	} else {
1469760b018bSJohan Hedberg 		local_addr = b;
1470760b018bSJohan Hedberg 		remote_addr = a;
1471760b018bSJohan Hedberg 		memcpy(io_cap, &smp->prsp[1], 3);
1472760b018bSJohan Hedberg 	}
1473760b018bSJohan Hedberg 
1474dddd3059SJohan Hedberg 	memset(r, 0, sizeof(r));
1475dddd3059SJohan Hedberg 
1476dddd3059SJohan Hedberg 	if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY)
147738606f14SJohan Hedberg 		put_unaligned_le32(hcon->passkey_notify, r);
1478760b018bSJohan Hedberg 
1479a29b0733SJohan Hedberg 	if (smp->method == REQ_OOB)
1480a29b0733SJohan Hedberg 		memcpy(r, smp->rr, 16);
1481a29b0733SJohan Hedberg 
1482760b018bSJohan Hedberg 	smp_f6(smp->tfm_cmac, smp->mackey, smp->prnd, smp->rrnd, r, io_cap,
1483760b018bSJohan Hedberg 	       local_addr, remote_addr, check.e);
1484760b018bSJohan Hedberg 
1485760b018bSJohan Hedberg 	smp_send_cmd(smp->conn, SMP_CMD_DHKEY_CHECK, sizeof(check), &check);
1486dddd3059SJohan Hedberg }
1487dddd3059SJohan Hedberg 
148838606f14SJohan Hedberg static u8 sc_passkey_send_confirm(struct smp_chan *smp)
148938606f14SJohan Hedberg {
149038606f14SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
149138606f14SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
149238606f14SJohan Hedberg 	struct smp_cmd_pairing_confirm cfm;
149338606f14SJohan Hedberg 	u8 r;
149438606f14SJohan Hedberg 
149538606f14SJohan Hedberg 	r = ((hcon->passkey_notify >> smp->passkey_round) & 0x01);
149638606f14SJohan Hedberg 	r |= 0x80;
149738606f14SJohan Hedberg 
149838606f14SJohan Hedberg 	get_random_bytes(smp->prnd, sizeof(smp->prnd));
149938606f14SJohan Hedberg 
150038606f14SJohan Hedberg 	if (smp_f4(smp->tfm_cmac, smp->local_pk, smp->remote_pk, smp->prnd, r,
150138606f14SJohan Hedberg 		   cfm.confirm_val))
150238606f14SJohan Hedberg 		return SMP_UNSPECIFIED;
150338606f14SJohan Hedberg 
150438606f14SJohan Hedberg 	smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cfm), &cfm);
150538606f14SJohan Hedberg 
150638606f14SJohan Hedberg 	return 0;
150738606f14SJohan Hedberg }
150838606f14SJohan Hedberg 
150938606f14SJohan Hedberg static u8 sc_passkey_round(struct smp_chan *smp, u8 smp_op)
151038606f14SJohan Hedberg {
151138606f14SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
151238606f14SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
151338606f14SJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
151438606f14SJohan Hedberg 	u8 cfm[16], r;
151538606f14SJohan Hedberg 
151638606f14SJohan Hedberg 	/* Ignore the PDU if we've already done 20 rounds (0 - 19) */
151738606f14SJohan Hedberg 	if (smp->passkey_round >= 20)
151838606f14SJohan Hedberg 		return 0;
151938606f14SJohan Hedberg 
152038606f14SJohan Hedberg 	switch (smp_op) {
152138606f14SJohan Hedberg 	case SMP_CMD_PAIRING_RANDOM:
152238606f14SJohan Hedberg 		r = ((hcon->passkey_notify >> smp->passkey_round) & 0x01);
152338606f14SJohan Hedberg 		r |= 0x80;
152438606f14SJohan Hedberg 
152538606f14SJohan Hedberg 		if (smp_f4(smp->tfm_cmac, smp->remote_pk, smp->local_pk,
152638606f14SJohan Hedberg 			   smp->rrnd, r, cfm))
152738606f14SJohan Hedberg 			return SMP_UNSPECIFIED;
152838606f14SJohan Hedberg 
1529329d8230SJason A. Donenfeld 		if (crypto_memneq(smp->pcnf, cfm, 16))
153038606f14SJohan Hedberg 			return SMP_CONFIRM_FAILED;
153138606f14SJohan Hedberg 
153238606f14SJohan Hedberg 		smp->passkey_round++;
153338606f14SJohan Hedberg 
153438606f14SJohan Hedberg 		if (smp->passkey_round == 20) {
153538606f14SJohan Hedberg 			/* Generate MacKey and LTK */
153638606f14SJohan Hedberg 			if (sc_mackey_and_ltk(smp, smp->mackey, smp->tk))
153738606f14SJohan Hedberg 				return SMP_UNSPECIFIED;
153838606f14SJohan Hedberg 		}
153938606f14SJohan Hedberg 
154038606f14SJohan Hedberg 		/* The round is only complete when the initiator
154138606f14SJohan Hedberg 		 * receives pairing random.
154238606f14SJohan Hedberg 		 */
154338606f14SJohan Hedberg 		if (!hcon->out) {
154438606f14SJohan Hedberg 			smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM,
154538606f14SJohan Hedberg 				     sizeof(smp->prnd), smp->prnd);
1546d3e54a87SJohan Hedberg 			if (smp->passkey_round == 20)
154738606f14SJohan Hedberg 				SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
1548d3e54a87SJohan Hedberg 			else
154938606f14SJohan Hedberg 				SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
155038606f14SJohan Hedberg 			return 0;
155138606f14SJohan Hedberg 		}
155238606f14SJohan Hedberg 
155338606f14SJohan Hedberg 		/* Start the next round */
155438606f14SJohan Hedberg 		if (smp->passkey_round != 20)
155538606f14SJohan Hedberg 			return sc_passkey_round(smp, 0);
155638606f14SJohan Hedberg 
155738606f14SJohan Hedberg 		/* Passkey rounds are complete - start DHKey Check */
155838606f14SJohan Hedberg 		sc_dhkey_check(smp);
155938606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
156038606f14SJohan Hedberg 
156138606f14SJohan Hedberg 		break;
156238606f14SJohan Hedberg 
156338606f14SJohan Hedberg 	case SMP_CMD_PAIRING_CONFIRM:
156438606f14SJohan Hedberg 		if (test_bit(SMP_FLAG_WAIT_USER, &smp->flags)) {
156538606f14SJohan Hedberg 			set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
156638606f14SJohan Hedberg 			return 0;
156738606f14SJohan Hedberg 		}
156838606f14SJohan Hedberg 
156938606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
157038606f14SJohan Hedberg 
157138606f14SJohan Hedberg 		if (hcon->out) {
157238606f14SJohan Hedberg 			smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM,
157338606f14SJohan Hedberg 				     sizeof(smp->prnd), smp->prnd);
157438606f14SJohan Hedberg 			return 0;
157538606f14SJohan Hedberg 		}
157638606f14SJohan Hedberg 
157738606f14SJohan Hedberg 		return sc_passkey_send_confirm(smp);
157838606f14SJohan Hedberg 
157938606f14SJohan Hedberg 	case SMP_CMD_PUBLIC_KEY:
158038606f14SJohan Hedberg 	default:
158138606f14SJohan Hedberg 		/* Initiating device starts the round */
158238606f14SJohan Hedberg 		if (!hcon->out)
158338606f14SJohan Hedberg 			return 0;
158438606f14SJohan Hedberg 
158538606f14SJohan Hedberg 		BT_DBG("%s Starting passkey round %u", hdev->name,
158638606f14SJohan Hedberg 		       smp->passkey_round + 1);
158738606f14SJohan Hedberg 
158838606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
158938606f14SJohan Hedberg 
159038606f14SJohan Hedberg 		return sc_passkey_send_confirm(smp);
159138606f14SJohan Hedberg 	}
159238606f14SJohan Hedberg 
159338606f14SJohan Hedberg 	return 0;
159438606f14SJohan Hedberg }
159538606f14SJohan Hedberg 
1596dddd3059SJohan Hedberg static int sc_user_reply(struct smp_chan *smp, u16 mgmt_op, __le32 passkey)
1597dddd3059SJohan Hedberg {
159838606f14SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
159938606f14SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
160038606f14SJohan Hedberg 	u8 smp_op;
160138606f14SJohan Hedberg 
160238606f14SJohan Hedberg 	clear_bit(SMP_FLAG_WAIT_USER, &smp->flags);
160338606f14SJohan Hedberg 
1604dddd3059SJohan Hedberg 	switch (mgmt_op) {
1605dddd3059SJohan Hedberg 	case MGMT_OP_USER_PASSKEY_NEG_REPLY:
1606dddd3059SJohan Hedberg 		smp_failure(smp->conn, SMP_PASSKEY_ENTRY_FAILED);
1607dddd3059SJohan Hedberg 		return 0;
1608dddd3059SJohan Hedberg 	case MGMT_OP_USER_CONFIRM_NEG_REPLY:
1609dddd3059SJohan Hedberg 		smp_failure(smp->conn, SMP_NUMERIC_COMP_FAILED);
1610dddd3059SJohan Hedberg 		return 0;
161138606f14SJohan Hedberg 	case MGMT_OP_USER_PASSKEY_REPLY:
161238606f14SJohan Hedberg 		hcon->passkey_notify = le32_to_cpu(passkey);
161338606f14SJohan Hedberg 		smp->passkey_round = 0;
161438606f14SJohan Hedberg 
161538606f14SJohan Hedberg 		if (test_and_clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags))
161638606f14SJohan Hedberg 			smp_op = SMP_CMD_PAIRING_CONFIRM;
161738606f14SJohan Hedberg 		else
161838606f14SJohan Hedberg 			smp_op = 0;
161938606f14SJohan Hedberg 
162038606f14SJohan Hedberg 		if (sc_passkey_round(smp, smp_op))
162138606f14SJohan Hedberg 			return -EIO;
162238606f14SJohan Hedberg 
162338606f14SJohan Hedberg 		return 0;
1624dddd3059SJohan Hedberg 	}
1625dddd3059SJohan Hedberg 
1626d3e54a87SJohan Hedberg 	/* Initiator sends DHKey check first */
1627d3e54a87SJohan Hedberg 	if (hcon->out) {
162838606f14SJohan Hedberg 		sc_dhkey_check(smp);
1629d3e54a87SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
1630d3e54a87SJohan Hedberg 	} else if (test_and_clear_bit(SMP_FLAG_DHKEY_PENDING, &smp->flags)) {
1631d3e54a87SJohan Hedberg 		sc_dhkey_check(smp);
1632d3e54a87SJohan Hedberg 		sc_add_ltk(smp);
1633d3e54a87SJohan Hedberg 	}
1634760b018bSJohan Hedberg 
1635760b018bSJohan Hedberg 	return 0;
1636760b018bSJohan Hedberg }
1637760b018bSJohan Hedberg 
16382b64d153SBrian Gix int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
16392b64d153SBrian Gix {
1640b10e8017SJohan Hedberg 	struct l2cap_conn *conn = hcon->l2cap_data;
16415d88cc73SJohan Hedberg 	struct l2cap_chan *chan;
16422b64d153SBrian Gix 	struct smp_chan *smp;
16432b64d153SBrian Gix 	u32 value;
1644fc75cc86SJohan Hedberg 	int err;
16452b64d153SBrian Gix 
16462b64d153SBrian Gix 	BT_DBG("");
16472b64d153SBrian Gix 
1648fc75cc86SJohan Hedberg 	if (!conn)
16492b64d153SBrian Gix 		return -ENOTCONN;
16502b64d153SBrian Gix 
16515d88cc73SJohan Hedberg 	chan = conn->smp;
16525d88cc73SJohan Hedberg 	if (!chan)
16535d88cc73SJohan Hedberg 		return -ENOTCONN;
16545d88cc73SJohan Hedberg 
1655fc75cc86SJohan Hedberg 	l2cap_chan_lock(chan);
1656fc75cc86SJohan Hedberg 	if (!chan->data) {
1657fc75cc86SJohan Hedberg 		err = -ENOTCONN;
1658fc75cc86SJohan Hedberg 		goto unlock;
1659fc75cc86SJohan Hedberg 	}
1660fc75cc86SJohan Hedberg 
16615d88cc73SJohan Hedberg 	smp = chan->data;
16622b64d153SBrian Gix 
1663760b018bSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
1664760b018bSJohan Hedberg 		err = sc_user_reply(smp, mgmt_op, passkey);
1665760b018bSJohan Hedberg 		goto unlock;
1666760b018bSJohan Hedberg 	}
1667760b018bSJohan Hedberg 
16682b64d153SBrian Gix 	switch (mgmt_op) {
16692b64d153SBrian Gix 	case MGMT_OP_USER_PASSKEY_REPLY:
16702b64d153SBrian Gix 		value = le32_to_cpu(passkey);
1671943a732aSJohan Hedberg 		memset(smp->tk, 0, sizeof(smp->tk));
16722b64d153SBrian Gix 		BT_DBG("PassKey: %d", value);
1673943a732aSJohan Hedberg 		put_unaligned_le32(value, smp->tk);
16742b64d153SBrian Gix 		/* Fall Through */
16752b64d153SBrian Gix 	case MGMT_OP_USER_CONFIRM_REPLY:
16764a74d658SJohan Hedberg 		set_bit(SMP_FLAG_TK_VALID, &smp->flags);
16772b64d153SBrian Gix 		break;
16782b64d153SBrian Gix 	case MGMT_OP_USER_PASSKEY_NEG_REPLY:
16792b64d153SBrian Gix 	case MGMT_OP_USER_CONFIRM_NEG_REPLY:
168084794e11SJohan Hedberg 		smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
1681fc75cc86SJohan Hedberg 		err = 0;
1682fc75cc86SJohan Hedberg 		goto unlock;
16832b64d153SBrian Gix 	default:
168484794e11SJohan Hedberg 		smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
1685fc75cc86SJohan Hedberg 		err = -EOPNOTSUPP;
1686fc75cc86SJohan Hedberg 		goto unlock;
16872b64d153SBrian Gix 	}
16882b64d153SBrian Gix 
1689fc75cc86SJohan Hedberg 	err = 0;
1690fc75cc86SJohan Hedberg 
16912b64d153SBrian Gix 	/* If it is our turn to send Pairing Confirm, do so now */
16921cc61144SJohan Hedberg 	if (test_bit(SMP_FLAG_CFM_PENDING, &smp->flags)) {
16931cc61144SJohan Hedberg 		u8 rsp = smp_confirm(smp);
16941cc61144SJohan Hedberg 		if (rsp)
16951cc61144SJohan Hedberg 			smp_failure(conn, rsp);
16961cc61144SJohan Hedberg 	}
16972b64d153SBrian Gix 
1698fc75cc86SJohan Hedberg unlock:
1699fc75cc86SJohan Hedberg 	l2cap_chan_unlock(chan);
1700fc75cc86SJohan Hedberg 	return err;
17012b64d153SBrian Gix }
17022b64d153SBrian Gix 
1703b5ae344dSJohan Hedberg static void build_bredr_pairing_cmd(struct smp_chan *smp,
1704b5ae344dSJohan Hedberg 				    struct smp_cmd_pairing *req,
1705b5ae344dSJohan Hedberg 				    struct smp_cmd_pairing *rsp)
1706b5ae344dSJohan Hedberg {
1707b5ae344dSJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
1708b5ae344dSJohan Hedberg 	struct hci_dev *hdev = conn->hcon->hdev;
1709b5ae344dSJohan Hedberg 	u8 local_dist = 0, remote_dist = 0;
1710b5ae344dSJohan Hedberg 
1711d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_BONDABLE)) {
1712b5ae344dSJohan Hedberg 		local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
1713b5ae344dSJohan Hedberg 		remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
1714b5ae344dSJohan Hedberg 	}
1715b5ae344dSJohan Hedberg 
1716d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_RPA_RESOLVING))
1717b5ae344dSJohan Hedberg 		remote_dist |= SMP_DIST_ID_KEY;
1718b5ae344dSJohan Hedberg 
1719d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_PRIVACY))
1720b5ae344dSJohan Hedberg 		local_dist |= SMP_DIST_ID_KEY;
1721b5ae344dSJohan Hedberg 
1722b5ae344dSJohan Hedberg 	if (!rsp) {
1723b5ae344dSJohan Hedberg 		memset(req, 0, sizeof(*req));
1724b5ae344dSJohan Hedberg 
1725a62da6f1SJohan Hedberg 		req->auth_req        = SMP_AUTH_CT2;
1726b5ae344dSJohan Hedberg 		req->init_key_dist   = local_dist;
1727b5ae344dSJohan Hedberg 		req->resp_key_dist   = remote_dist;
1728e3f6a257SJohan Hedberg 		req->max_key_size    = conn->hcon->enc_key_size;
1729b5ae344dSJohan Hedberg 
1730b5ae344dSJohan Hedberg 		smp->remote_key_dist = remote_dist;
1731b5ae344dSJohan Hedberg 
1732b5ae344dSJohan Hedberg 		return;
1733b5ae344dSJohan Hedberg 	}
1734b5ae344dSJohan Hedberg 
1735b5ae344dSJohan Hedberg 	memset(rsp, 0, sizeof(*rsp));
1736b5ae344dSJohan Hedberg 
1737a62da6f1SJohan Hedberg 	rsp->auth_req        = SMP_AUTH_CT2;
1738e3f6a257SJohan Hedberg 	rsp->max_key_size    = conn->hcon->enc_key_size;
1739b5ae344dSJohan Hedberg 	rsp->init_key_dist   = req->init_key_dist & remote_dist;
1740b5ae344dSJohan Hedberg 	rsp->resp_key_dist   = req->resp_key_dist & local_dist;
1741b5ae344dSJohan Hedberg 
1742b5ae344dSJohan Hedberg 	smp->remote_key_dist = rsp->init_key_dist;
1743b5ae344dSJohan Hedberg }
1744b5ae344dSJohan Hedberg 
1745da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
174688ba43b6SAnderson Briglia {
17473158c50cSVinicius Costa Gomes 	struct smp_cmd_pairing rsp, *req = (void *) skb->data;
1748fc75cc86SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
1749b3c6410bSJohan Hedberg 	struct hci_dev *hdev = conn->hcon->hdev;
17508aab4757SVinicius Costa Gomes 	struct smp_chan *smp;
1751c7262e71SJohan Hedberg 	u8 key_size, auth, sec_level;
17528aab4757SVinicius Costa Gomes 	int ret;
175388ba43b6SAnderson Briglia 
175488ba43b6SAnderson Briglia 	BT_DBG("conn %p", conn);
175588ba43b6SAnderson Briglia 
1756c46b98beSJohan Hedberg 	if (skb->len < sizeof(*req))
175738e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1758c46b98beSJohan Hedberg 
175940bef302SJohan Hedberg 	if (conn->hcon->role != HCI_ROLE_SLAVE)
17602b64d153SBrian Gix 		return SMP_CMD_NOTSUPP;
17612b64d153SBrian Gix 
1762fc75cc86SJohan Hedberg 	if (!chan->data)
17638aab4757SVinicius Costa Gomes 		smp = smp_chan_create(conn);
1764fc75cc86SJohan Hedberg 	else
17655d88cc73SJohan Hedberg 		smp = chan->data;
1766d26a2345SVinicius Costa Gomes 
1767d08fd0e7SAndrei Emeltchenko 	if (!smp)
1768d08fd0e7SAndrei Emeltchenko 		return SMP_UNSPECIFIED;
1769d08fd0e7SAndrei Emeltchenko 
1770c05b9339SJohan Hedberg 	/* We didn't start the pairing, so match remote */
17710edb14deSJohan Hedberg 	auth = req->auth_req & AUTH_REQ_MASK(hdev);
1772c05b9339SJohan Hedberg 
1773d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BONDABLE) &&
1774c05b9339SJohan Hedberg 	    (auth & SMP_AUTH_BONDING))
1775b3c6410bSJohan Hedberg 		return SMP_PAIRING_NOTSUPP;
1776b3c6410bSJohan Hedberg 
1777d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SC_ONLY) && !(auth & SMP_AUTH_SC))
1778903b71c7SJohan Hedberg 		return SMP_AUTH_REQUIREMENTS;
1779903b71c7SJohan Hedberg 
17801c1def09SVinicius Costa Gomes 	smp->preq[0] = SMP_CMD_PAIRING_REQ;
17811c1def09SVinicius Costa Gomes 	memcpy(&smp->preq[1], req, sizeof(*req));
17823158c50cSVinicius Costa Gomes 	skb_pull(skb, sizeof(*req));
178388ba43b6SAnderson Briglia 
1784cb06d366SJohan Hedberg 	/* If the remote side's OOB flag is set it means it has
1785cb06d366SJohan Hedberg 	 * successfully received our local OOB data - therefore set the
1786cb06d366SJohan Hedberg 	 * flag to indicate that local OOB is in use.
1787cb06d366SJohan Hedberg 	 */
178894f14e47SJohan Hedberg 	if (req->oob_flag == SMP_OOB_PRESENT && SMP_DEV(hdev)->local_oob)
178958428563SJohan Hedberg 		set_bit(SMP_FLAG_LOCAL_OOB, &smp->flags);
179058428563SJohan Hedberg 
1791b5ae344dSJohan Hedberg 	/* SMP over BR/EDR requires special treatment */
1792b5ae344dSJohan Hedberg 	if (conn->hcon->type == ACL_LINK) {
1793b5ae344dSJohan Hedberg 		/* We must have a BR/EDR SC link */
179408f63cc5SMarcel Holtmann 		if (!test_bit(HCI_CONN_AES_CCM, &conn->hcon->flags) &&
1795b7cb93e5SMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP))
1796b5ae344dSJohan Hedberg 			return SMP_CROSS_TRANSP_NOT_ALLOWED;
1797b5ae344dSJohan Hedberg 
1798b5ae344dSJohan Hedberg 		set_bit(SMP_FLAG_SC, &smp->flags);
1799b5ae344dSJohan Hedberg 
1800b5ae344dSJohan Hedberg 		build_bredr_pairing_cmd(smp, req, &rsp);
1801b5ae344dSJohan Hedberg 
1802a62da6f1SJohan Hedberg 		if (req->auth_req & SMP_AUTH_CT2)
1803a62da6f1SJohan Hedberg 			set_bit(SMP_FLAG_CT2, &smp->flags);
1804a62da6f1SJohan Hedberg 
1805b5ae344dSJohan Hedberg 		key_size = min(req->max_key_size, rsp.max_key_size);
1806b5ae344dSJohan Hedberg 		if (check_enc_key_size(conn, key_size))
1807b5ae344dSJohan Hedberg 			return SMP_ENC_KEY_SIZE;
1808b5ae344dSJohan Hedberg 
1809b5ae344dSJohan Hedberg 		/* Clear bits which are generated but not distributed */
1810b5ae344dSJohan Hedberg 		smp->remote_key_dist &= ~SMP_SC_NO_DIST;
1811b5ae344dSJohan Hedberg 
1812b5ae344dSJohan Hedberg 		smp->prsp[0] = SMP_CMD_PAIRING_RSP;
1813b5ae344dSJohan Hedberg 		memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
1814b5ae344dSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
1815b5ae344dSJohan Hedberg 
1816b5ae344dSJohan Hedberg 		smp_distribute_keys(smp);
1817b5ae344dSJohan Hedberg 		return 0;
1818b5ae344dSJohan Hedberg 	}
1819b5ae344dSJohan Hedberg 
18205e3d3d9bSJohan Hedberg 	build_pairing_cmd(conn, req, &rsp, auth);
18215e3d3d9bSJohan Hedberg 
1822a62da6f1SJohan Hedberg 	if (rsp.auth_req & SMP_AUTH_SC) {
18235e3d3d9bSJohan Hedberg 		set_bit(SMP_FLAG_SC, &smp->flags);
18245e3d3d9bSJohan Hedberg 
1825a62da6f1SJohan Hedberg 		if (rsp.auth_req & SMP_AUTH_CT2)
1826a62da6f1SJohan Hedberg 			set_bit(SMP_FLAG_CT2, &smp->flags);
1827a62da6f1SJohan Hedberg 	}
1828a62da6f1SJohan Hedberg 
18295be5e275SJohan Hedberg 	if (conn->hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
18301afc2a1aSJohan Hedberg 		sec_level = BT_SECURITY_MEDIUM;
18311afc2a1aSJohan Hedberg 	else
1832c7262e71SJohan Hedberg 		sec_level = authreq_to_seclevel(auth);
18331afc2a1aSJohan Hedberg 
1834c7262e71SJohan Hedberg 	if (sec_level > conn->hcon->pending_sec_level)
1835c7262e71SJohan Hedberg 		conn->hcon->pending_sec_level = sec_level;
1836fdde0a26SIdo Yariv 
183749c922bbSStephen Hemminger 	/* If we need MITM check that it can be achieved */
18382ed8f65cSJohan Hedberg 	if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
18392ed8f65cSJohan Hedberg 		u8 method;
18402ed8f65cSJohan Hedberg 
18412ed8f65cSJohan Hedberg 		method = get_auth_method(smp, conn->hcon->io_capability,
18422ed8f65cSJohan Hedberg 					 req->io_capability);
18432ed8f65cSJohan Hedberg 		if (method == JUST_WORKS || method == JUST_CFM)
18442ed8f65cSJohan Hedberg 			return SMP_AUTH_REQUIREMENTS;
18452ed8f65cSJohan Hedberg 	}
18462ed8f65cSJohan Hedberg 
18473158c50cSVinicius Costa Gomes 	key_size = min(req->max_key_size, rsp.max_key_size);
18483158c50cSVinicius Costa Gomes 	if (check_enc_key_size(conn, key_size))
18493158c50cSVinicius Costa Gomes 		return SMP_ENC_KEY_SIZE;
185088ba43b6SAnderson Briglia 
1851e84a6b13SJohan Hedberg 	get_random_bytes(smp->prnd, sizeof(smp->prnd));
18528aab4757SVinicius Costa Gomes 
18531c1def09SVinicius Costa Gomes 	smp->prsp[0] = SMP_CMD_PAIRING_RSP;
18541c1def09SVinicius Costa Gomes 	memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
1855f01ead31SAnderson Briglia 
18563158c50cSVinicius Costa Gomes 	smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
18573b19146dSJohan Hedberg 
18583b19146dSJohan Hedberg 	clear_bit(SMP_FLAG_INITIATOR, &smp->flags);
18593b19146dSJohan Hedberg 
186019c5ce9cSJohan Hedberg 	/* Strictly speaking we shouldn't allow Pairing Confirm for the
186119c5ce9cSJohan Hedberg 	 * SC case, however some implementations incorrectly copy RFU auth
186219c5ce9cSJohan Hedberg 	 * req bits from our security request, which may create a false
186319c5ce9cSJohan Hedberg 	 * positive SC enablement.
186419c5ce9cSJohan Hedberg 	 */
186519c5ce9cSJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
186619c5ce9cSJohan Hedberg 
18673b19146dSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
18683b19146dSJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PUBLIC_KEY);
18693b19146dSJohan Hedberg 		/* Clear bits which are generated but not distributed */
18703b19146dSJohan Hedberg 		smp->remote_key_dist &= ~SMP_SC_NO_DIST;
18713b19146dSJohan Hedberg 		/* Wait for Public Key from Initiating Device */
18723b19146dSJohan Hedberg 		return 0;
18733b19146dSJohan Hedberg 	}
1874da85e5e5SVinicius Costa Gomes 
18752b64d153SBrian Gix 	/* Request setup of TK */
18762b64d153SBrian Gix 	ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability);
18772b64d153SBrian Gix 	if (ret)
18782b64d153SBrian Gix 		return SMP_UNSPECIFIED;
18792b64d153SBrian Gix 
1880da85e5e5SVinicius Costa Gomes 	return 0;
188188ba43b6SAnderson Briglia }
188288ba43b6SAnderson Briglia 
18833b19146dSJohan Hedberg static u8 sc_send_public_key(struct smp_chan *smp)
18843b19146dSJohan Hedberg {
188570157ef5SJohan Hedberg 	struct hci_dev *hdev = smp->conn->hcon->hdev;
188670157ef5SJohan Hedberg 
18873b19146dSJohan Hedberg 	BT_DBG("");
18883b19146dSJohan Hedberg 
18891a8bab4fSJohan Hedberg 	if (test_bit(SMP_FLAG_LOCAL_OOB, &smp->flags)) {
189033d0c030SMarcel Holtmann 		struct l2cap_chan *chan = hdev->smp_data;
189133d0c030SMarcel Holtmann 		struct smp_dev *smp_dev;
189233d0c030SMarcel Holtmann 
189333d0c030SMarcel Holtmann 		if (!chan || !chan->data)
189433d0c030SMarcel Holtmann 			return SMP_UNSPECIFIED;
189533d0c030SMarcel Holtmann 
189633d0c030SMarcel Holtmann 		smp_dev = chan->data;
189733d0c030SMarcel Holtmann 
189833d0c030SMarcel Holtmann 		memcpy(smp->local_pk, smp_dev->local_pk, 64);
1899fb334feeSMarcel Holtmann 		memcpy(smp->lr, smp_dev->local_rand, 16);
190033d0c030SMarcel Holtmann 
190133d0c030SMarcel Holtmann 		if (smp_dev->debug_key)
190233d0c030SMarcel Holtmann 			set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags);
190333d0c030SMarcel Holtmann 
190433d0c030SMarcel Holtmann 		goto done;
190533d0c030SMarcel Holtmann 	}
190633d0c030SMarcel Holtmann 
1907d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS)) {
190870157ef5SJohan Hedberg 		BT_DBG("Using debug keys");
1909c0153b0bSTudor Ambarus 		if (set_ecdh_privkey(smp->tfm_ecdh, debug_sk))
1910c0153b0bSTudor Ambarus 			return SMP_UNSPECIFIED;
191170157ef5SJohan Hedberg 		memcpy(smp->local_pk, debug_pk, 64);
191270157ef5SJohan Hedberg 		set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags);
191370157ef5SJohan Hedberg 	} else {
19146c0dcc50SJohan Hedberg 		while (true) {
1915c0153b0bSTudor Ambarus 			/* Generate key pair for Secure Connections */
1916c0153b0bSTudor Ambarus 			if (generate_ecdh_keys(smp->tfm_ecdh, smp->local_pk))
19173b19146dSJohan Hedberg 				return SMP_UNSPECIFIED;
19183b19146dSJohan Hedberg 
191970157ef5SJohan Hedberg 			/* This is unlikely, but we need to check that
192070157ef5SJohan Hedberg 			 * we didn't accidentially generate a debug key.
19216c0dcc50SJohan Hedberg 			 */
1922c0153b0bSTudor Ambarus 			if (crypto_memneq(smp->local_pk, debug_pk, 64))
19236c0dcc50SJohan Hedberg 				break;
19246c0dcc50SJohan Hedberg 		}
192570157ef5SJohan Hedberg 	}
19266c0dcc50SJohan Hedberg 
192733d0c030SMarcel Holtmann done:
1928c7a3d57dSJohan Hedberg 	SMP_DBG("Local Public Key X: %32phN", smp->local_pk);
19298e4e2ee5SMarcel Holtmann 	SMP_DBG("Local Public Key Y: %32phN", smp->local_pk + 32);
19303b19146dSJohan Hedberg 
19313b19146dSJohan Hedberg 	smp_send_cmd(smp->conn, SMP_CMD_PUBLIC_KEY, 64, smp->local_pk);
19323b19146dSJohan Hedberg 
19333b19146dSJohan Hedberg 	return 0;
19343b19146dSJohan Hedberg }
19353b19146dSJohan Hedberg 
1936da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
193788ba43b6SAnderson Briglia {
19383158c50cSVinicius Costa Gomes 	struct smp_cmd_pairing *req, *rsp = (void *) skb->data;
19395d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
19405d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
19410edb14deSJohan Hedberg 	struct hci_dev *hdev = conn->hcon->hdev;
19423a7dbfb8SJohan Hedberg 	u8 key_size, auth;
19437d24ddccSAnderson Briglia 	int ret;
194488ba43b6SAnderson Briglia 
194588ba43b6SAnderson Briglia 	BT_DBG("conn %p", conn);
194688ba43b6SAnderson Briglia 
1947c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rsp))
194838e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1949c46b98beSJohan Hedberg 
195040bef302SJohan Hedberg 	if (conn->hcon->role != HCI_ROLE_MASTER)
19512b64d153SBrian Gix 		return SMP_CMD_NOTSUPP;
19522b64d153SBrian Gix 
19533158c50cSVinicius Costa Gomes 	skb_pull(skb, sizeof(*rsp));
1954da85e5e5SVinicius Costa Gomes 
19551c1def09SVinicius Costa Gomes 	req = (void *) &smp->preq[1];
19563158c50cSVinicius Costa Gomes 
19573158c50cSVinicius Costa Gomes 	key_size = min(req->max_key_size, rsp->max_key_size);
19583158c50cSVinicius Costa Gomes 	if (check_enc_key_size(conn, key_size))
19593158c50cSVinicius Costa Gomes 		return SMP_ENC_KEY_SIZE;
19603158c50cSVinicius Costa Gomes 
19610edb14deSJohan Hedberg 	auth = rsp->auth_req & AUTH_REQ_MASK(hdev);
1962c05b9339SJohan Hedberg 
1963d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SC_ONLY) && !(auth & SMP_AUTH_SC))
1964903b71c7SJohan Hedberg 		return SMP_AUTH_REQUIREMENTS;
1965903b71c7SJohan Hedberg 
1966cb06d366SJohan Hedberg 	/* If the remote side's OOB flag is set it means it has
1967cb06d366SJohan Hedberg 	 * successfully received our local OOB data - therefore set the
1968cb06d366SJohan Hedberg 	 * flag to indicate that local OOB is in use.
1969cb06d366SJohan Hedberg 	 */
197094f14e47SJohan Hedberg 	if (rsp->oob_flag == SMP_OOB_PRESENT && SMP_DEV(hdev)->local_oob)
197158428563SJohan Hedberg 		set_bit(SMP_FLAG_LOCAL_OOB, &smp->flags);
197258428563SJohan Hedberg 
1973b5ae344dSJohan Hedberg 	smp->prsp[0] = SMP_CMD_PAIRING_RSP;
1974b5ae344dSJohan Hedberg 	memcpy(&smp->prsp[1], rsp, sizeof(*rsp));
1975b5ae344dSJohan Hedberg 
1976b5ae344dSJohan Hedberg 	/* Update remote key distribution in case the remote cleared
1977b5ae344dSJohan Hedberg 	 * some bits that we had enabled in our request.
1978b5ae344dSJohan Hedberg 	 */
1979b5ae344dSJohan Hedberg 	smp->remote_key_dist &= rsp->resp_key_dist;
1980b5ae344dSJohan Hedberg 
1981a62da6f1SJohan Hedberg 	if ((req->auth_req & SMP_AUTH_CT2) && (auth & SMP_AUTH_CT2))
1982a62da6f1SJohan Hedberg 		set_bit(SMP_FLAG_CT2, &smp->flags);
1983a62da6f1SJohan Hedberg 
1984b5ae344dSJohan Hedberg 	/* For BR/EDR this means we're done and can start phase 3 */
1985b5ae344dSJohan Hedberg 	if (conn->hcon->type == ACL_LINK) {
1986b5ae344dSJohan Hedberg 		/* Clear bits which are generated but not distributed */
1987b5ae344dSJohan Hedberg 		smp->remote_key_dist &= ~SMP_SC_NO_DIST;
1988b5ae344dSJohan Hedberg 		smp_distribute_keys(smp);
1989b5ae344dSJohan Hedberg 		return 0;
1990b5ae344dSJohan Hedberg 	}
1991b5ae344dSJohan Hedberg 
199265668776SJohan Hedberg 	if ((req->auth_req & SMP_AUTH_SC) && (auth & SMP_AUTH_SC))
199365668776SJohan Hedberg 		set_bit(SMP_FLAG_SC, &smp->flags);
1994d2eb9e10SJohan Hedberg 	else if (conn->hcon->pending_sec_level > BT_SECURITY_HIGH)
1995d2eb9e10SJohan Hedberg 		conn->hcon->pending_sec_level = BT_SECURITY_HIGH;
199665668776SJohan Hedberg 
199749c922bbSStephen Hemminger 	/* If we need MITM check that it can be achieved */
19982ed8f65cSJohan Hedberg 	if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
19992ed8f65cSJohan Hedberg 		u8 method;
20002ed8f65cSJohan Hedberg 
20012ed8f65cSJohan Hedberg 		method = get_auth_method(smp, req->io_capability,
20022ed8f65cSJohan Hedberg 					 rsp->io_capability);
20032ed8f65cSJohan Hedberg 		if (method == JUST_WORKS || method == JUST_CFM)
20042ed8f65cSJohan Hedberg 			return SMP_AUTH_REQUIREMENTS;
20052ed8f65cSJohan Hedberg 	}
20062ed8f65cSJohan Hedberg 
2007e84a6b13SJohan Hedberg 	get_random_bytes(smp->prnd, sizeof(smp->prnd));
20087d24ddccSAnderson Briglia 
2009fdcc4becSJohan Hedberg 	/* Update remote key distribution in case the remote cleared
2010fdcc4becSJohan Hedberg 	 * some bits that we had enabled in our request.
2011fdcc4becSJohan Hedberg 	 */
2012fdcc4becSJohan Hedberg 	smp->remote_key_dist &= rsp->resp_key_dist;
2013fdcc4becSJohan Hedberg 
20143b19146dSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
20153b19146dSJohan Hedberg 		/* Clear bits which are generated but not distributed */
20163b19146dSJohan Hedberg 		smp->remote_key_dist &= ~SMP_SC_NO_DIST;
20173b19146dSJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PUBLIC_KEY);
20183b19146dSJohan Hedberg 		return sc_send_public_key(smp);
20193b19146dSJohan Hedberg 	}
20203b19146dSJohan Hedberg 
2021c05b9339SJohan Hedberg 	auth |= req->auth_req;
20222b64d153SBrian Gix 
2023476585ecSJohan Hedberg 	ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability);
20242b64d153SBrian Gix 	if (ret)
20252b64d153SBrian Gix 		return SMP_UNSPECIFIED;
20262b64d153SBrian Gix 
20274a74d658SJohan Hedberg 	set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
20282b64d153SBrian Gix 
20292b64d153SBrian Gix 	/* Can't compose response until we have been confirmed */
20304a74d658SJohan Hedberg 	if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
20311cc61144SJohan Hedberg 		return smp_confirm(smp);
2032da85e5e5SVinicius Costa Gomes 
2033da85e5e5SVinicius Costa Gomes 	return 0;
203488ba43b6SAnderson Briglia }
203588ba43b6SAnderson Briglia 
2036dcee2b32SJohan Hedberg static u8 sc_check_confirm(struct smp_chan *smp)
2037dcee2b32SJohan Hedberg {
2038dcee2b32SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
2039dcee2b32SJohan Hedberg 
2040dcee2b32SJohan Hedberg 	BT_DBG("");
2041dcee2b32SJohan Hedberg 
204238606f14SJohan Hedberg 	if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY)
204338606f14SJohan Hedberg 		return sc_passkey_round(smp, SMP_CMD_PAIRING_CONFIRM);
204438606f14SJohan Hedberg 
2045dcee2b32SJohan Hedberg 	if (conn->hcon->out) {
2046dcee2b32SJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
2047dcee2b32SJohan Hedberg 			     smp->prnd);
2048dcee2b32SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
2049dcee2b32SJohan Hedberg 	}
2050dcee2b32SJohan Hedberg 
2051dcee2b32SJohan Hedberg 	return 0;
2052dcee2b32SJohan Hedberg }
2053dcee2b32SJohan Hedberg 
205419c5ce9cSJohan Hedberg /* Work-around for some implementations that incorrectly copy RFU bits
205519c5ce9cSJohan Hedberg  * from our security request and thereby create the impression that
205619c5ce9cSJohan Hedberg  * we're doing SC when in fact the remote doesn't support it.
205719c5ce9cSJohan Hedberg  */
205819c5ce9cSJohan Hedberg static int fixup_sc_false_positive(struct smp_chan *smp)
205919c5ce9cSJohan Hedberg {
206019c5ce9cSJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
206119c5ce9cSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
206219c5ce9cSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
206319c5ce9cSJohan Hedberg 	struct smp_cmd_pairing *req, *rsp;
206419c5ce9cSJohan Hedberg 	u8 auth;
206519c5ce9cSJohan Hedberg 
206619c5ce9cSJohan Hedberg 	/* The issue is only observed when we're in slave role */
206719c5ce9cSJohan Hedberg 	if (hcon->out)
206819c5ce9cSJohan Hedberg 		return SMP_UNSPECIFIED;
206919c5ce9cSJohan Hedberg 
207019c5ce9cSJohan Hedberg 	if (hci_dev_test_flag(hdev, HCI_SC_ONLY)) {
20712064ee33SMarcel Holtmann 		bt_dev_err(hdev, "refusing legacy fallback in SC-only mode");
207219c5ce9cSJohan Hedberg 		return SMP_UNSPECIFIED;
207319c5ce9cSJohan Hedberg 	}
207419c5ce9cSJohan Hedberg 
20752064ee33SMarcel Holtmann 	bt_dev_err(hdev, "trying to fall back to legacy SMP");
207619c5ce9cSJohan Hedberg 
207719c5ce9cSJohan Hedberg 	req = (void *) &smp->preq[1];
207819c5ce9cSJohan Hedberg 	rsp = (void *) &smp->prsp[1];
207919c5ce9cSJohan Hedberg 
208019c5ce9cSJohan Hedberg 	/* Rebuild key dist flags which may have been cleared for SC */
208119c5ce9cSJohan Hedberg 	smp->remote_key_dist = (req->init_key_dist & rsp->resp_key_dist);
208219c5ce9cSJohan Hedberg 
208319c5ce9cSJohan Hedberg 	auth = req->auth_req & AUTH_REQ_MASK(hdev);
208419c5ce9cSJohan Hedberg 
208519c5ce9cSJohan Hedberg 	if (tk_request(conn, 0, auth, rsp->io_capability, req->io_capability)) {
20862064ee33SMarcel Holtmann 		bt_dev_err(hdev, "failed to fall back to legacy SMP");
208719c5ce9cSJohan Hedberg 		return SMP_UNSPECIFIED;
208819c5ce9cSJohan Hedberg 	}
208919c5ce9cSJohan Hedberg 
209019c5ce9cSJohan Hedberg 	clear_bit(SMP_FLAG_SC, &smp->flags);
209119c5ce9cSJohan Hedberg 
209219c5ce9cSJohan Hedberg 	return 0;
209319c5ce9cSJohan Hedberg }
209419c5ce9cSJohan Hedberg 
2095da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
209688ba43b6SAnderson Briglia {
20975d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
20985d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
20997d24ddccSAnderson Briglia 
210088ba43b6SAnderson Briglia 	BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
210188ba43b6SAnderson Briglia 
2102c46b98beSJohan Hedberg 	if (skb->len < sizeof(smp->pcnf))
210338e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2104c46b98beSJohan Hedberg 
21051c1def09SVinicius Costa Gomes 	memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf));
21061c1def09SVinicius Costa Gomes 	skb_pull(skb, sizeof(smp->pcnf));
21077d24ddccSAnderson Briglia 
210819c5ce9cSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
210919c5ce9cSJohan Hedberg 		int ret;
211019c5ce9cSJohan Hedberg 
211119c5ce9cSJohan Hedberg 		/* Public Key exchange must happen before any other steps */
211219c5ce9cSJohan Hedberg 		if (test_bit(SMP_FLAG_REMOTE_PK, &smp->flags))
2113dcee2b32SJohan Hedberg 			return sc_check_confirm(smp);
2114dcee2b32SJohan Hedberg 
211519c5ce9cSJohan Hedberg 		BT_ERR("Unexpected SMP Pairing Confirm");
211619c5ce9cSJohan Hedberg 
211719c5ce9cSJohan Hedberg 		ret = fixup_sc_false_positive(smp);
211819c5ce9cSJohan Hedberg 		if (ret)
211919c5ce9cSJohan Hedberg 			return ret;
212019c5ce9cSJohan Hedberg 	}
212119c5ce9cSJohan Hedberg 
2122b28b4943SJohan Hedberg 	if (conn->hcon->out) {
2123943a732aSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
2124943a732aSJohan Hedberg 			     smp->prnd);
2125b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
2126b28b4943SJohan Hedberg 		return 0;
2127b28b4943SJohan Hedberg 	}
2128b28b4943SJohan Hedberg 
2129b28b4943SJohan Hedberg 	if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
21301cc61144SJohan Hedberg 		return smp_confirm(smp);
2131983f9814SMarcel Holtmann 
21324a74d658SJohan Hedberg 	set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
2133da85e5e5SVinicius Costa Gomes 
2134da85e5e5SVinicius Costa Gomes 	return 0;
213588ba43b6SAnderson Briglia }
213688ba43b6SAnderson Briglia 
2137da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
213888ba43b6SAnderson Briglia {
21395d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
21405d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
2141191dc7feSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
2142191dc7feSJohan Hedberg 	u8 *pkax, *pkbx, *na, *nb;
2143191dc7feSJohan Hedberg 	u32 passkey;
2144191dc7feSJohan Hedberg 	int err;
21457d24ddccSAnderson Briglia 
21468aab4757SVinicius Costa Gomes 	BT_DBG("conn %p", conn);
21477d24ddccSAnderson Briglia 
2148c46b98beSJohan Hedberg 	if (skb->len < sizeof(smp->rrnd))
214938e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2150c46b98beSJohan Hedberg 
2151943a732aSJohan Hedberg 	memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd));
21528aab4757SVinicius Costa Gomes 	skb_pull(skb, sizeof(smp->rrnd));
215388ba43b6SAnderson Briglia 
2154191dc7feSJohan Hedberg 	if (!test_bit(SMP_FLAG_SC, &smp->flags))
2155861580a9SJohan Hedberg 		return smp_random(smp);
2156191dc7feSJohan Hedberg 
2157580039e8SJohan Hedberg 	if (hcon->out) {
2158580039e8SJohan Hedberg 		pkax = smp->local_pk;
2159580039e8SJohan Hedberg 		pkbx = smp->remote_pk;
2160580039e8SJohan Hedberg 		na   = smp->prnd;
2161580039e8SJohan Hedberg 		nb   = smp->rrnd;
2162580039e8SJohan Hedberg 	} else {
2163580039e8SJohan Hedberg 		pkax = smp->remote_pk;
2164580039e8SJohan Hedberg 		pkbx = smp->local_pk;
2165580039e8SJohan Hedberg 		na   = smp->rrnd;
2166580039e8SJohan Hedberg 		nb   = smp->prnd;
2167580039e8SJohan Hedberg 	}
2168580039e8SJohan Hedberg 
2169a29b0733SJohan Hedberg 	if (smp->method == REQ_OOB) {
2170a29b0733SJohan Hedberg 		if (!hcon->out)
2171a29b0733SJohan Hedberg 			smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM,
2172a29b0733SJohan Hedberg 				     sizeof(smp->prnd), smp->prnd);
2173a29b0733SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
2174a29b0733SJohan Hedberg 		goto mackey_and_ltk;
2175a29b0733SJohan Hedberg 	}
2176a29b0733SJohan Hedberg 
217738606f14SJohan Hedberg 	/* Passkey entry has special treatment */
217838606f14SJohan Hedberg 	if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY)
217938606f14SJohan Hedberg 		return sc_passkey_round(smp, SMP_CMD_PAIRING_RANDOM);
218038606f14SJohan Hedberg 
2181191dc7feSJohan Hedberg 	if (hcon->out) {
2182191dc7feSJohan Hedberg 		u8 cfm[16];
2183191dc7feSJohan Hedberg 
2184191dc7feSJohan Hedberg 		err = smp_f4(smp->tfm_cmac, smp->remote_pk, smp->local_pk,
2185191dc7feSJohan Hedberg 			     smp->rrnd, 0, cfm);
2186191dc7feSJohan Hedberg 		if (err)
2187191dc7feSJohan Hedberg 			return SMP_UNSPECIFIED;
2188191dc7feSJohan Hedberg 
2189329d8230SJason A. Donenfeld 		if (crypto_memneq(smp->pcnf, cfm, 16))
2190191dc7feSJohan Hedberg 			return SMP_CONFIRM_FAILED;
2191191dc7feSJohan Hedberg 	} else {
2192191dc7feSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
2193191dc7feSJohan Hedberg 			     smp->prnd);
2194191dc7feSJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
2195191dc7feSJohan Hedberg 	}
2196191dc7feSJohan Hedberg 
2197a29b0733SJohan Hedberg mackey_and_ltk:
2198760b018bSJohan Hedberg 	/* Generate MacKey and LTK */
2199760b018bSJohan Hedberg 	err = sc_mackey_and_ltk(smp, smp->mackey, smp->tk);
2200760b018bSJohan Hedberg 	if (err)
2201760b018bSJohan Hedberg 		return SMP_UNSPECIFIED;
2202760b018bSJohan Hedberg 
2203a29b0733SJohan Hedberg 	if (smp->method == JUST_WORKS || smp->method == REQ_OOB) {
2204dddd3059SJohan Hedberg 		if (hcon->out) {
220538606f14SJohan Hedberg 			sc_dhkey_check(smp);
2206dddd3059SJohan Hedberg 			SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
2207dddd3059SJohan Hedberg 		}
2208dddd3059SJohan Hedberg 		return 0;
2209dddd3059SJohan Hedberg 	}
2210dddd3059SJohan Hedberg 
221138606f14SJohan Hedberg 	err = smp_g2(smp->tfm_cmac, pkax, pkbx, na, nb, &passkey);
2212191dc7feSJohan Hedberg 	if (err)
2213191dc7feSJohan Hedberg 		return SMP_UNSPECIFIED;
2214191dc7feSJohan Hedberg 
221538606f14SJohan Hedberg 	err = mgmt_user_confirm_request(hcon->hdev, &hcon->dst, hcon->type,
221638606f14SJohan Hedberg 					hcon->dst_type, passkey, 0);
221738606f14SJohan Hedberg 	if (err)
221838606f14SJohan Hedberg 		return SMP_UNSPECIFIED;
221938606f14SJohan Hedberg 
222038606f14SJohan Hedberg 	set_bit(SMP_FLAG_WAIT_USER, &smp->flags);
222138606f14SJohan Hedberg 
2222191dc7feSJohan Hedberg 	return 0;
222388ba43b6SAnderson Briglia }
222488ba43b6SAnderson Briglia 
2225f81cd823SMarcel Holtmann static bool smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
2226988c5997SVinicius Costa Gomes {
2227c9839a11SVinicius Costa Gomes 	struct smp_ltk *key;
2228988c5997SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
2229988c5997SVinicius Costa Gomes 
2230f3a73d97SJohan Hedberg 	key = hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, hcon->role);
2231988c5997SVinicius Costa Gomes 	if (!key)
2232f81cd823SMarcel Holtmann 		return false;
2233988c5997SVinicius Costa Gomes 
2234a6f7833cSJohan Hedberg 	if (smp_ltk_sec_level(key) < sec_level)
2235f81cd823SMarcel Holtmann 		return false;
22364dab7864SJohan Hedberg 
223751a8efd7SJohan Hedberg 	if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
2238f81cd823SMarcel Holtmann 		return true;
2239988c5997SVinicius Costa Gomes 
22408b76ce34SJohan Hedberg 	hci_le_start_enc(hcon, key->ediv, key->rand, key->val, key->enc_size);
2241c9839a11SVinicius Costa Gomes 	hcon->enc_key_size = key->enc_size;
2242988c5997SVinicius Costa Gomes 
2243fe59a05fSJohan Hedberg 	/* We never store STKs for master role, so clear this flag */
2244fe59a05fSJohan Hedberg 	clear_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags);
2245fe59a05fSJohan Hedberg 
2246f81cd823SMarcel Holtmann 	return true;
2247988c5997SVinicius Costa Gomes }
2248f1560463SMarcel Holtmann 
224935dc6f83SJohan Hedberg bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level,
225035dc6f83SJohan Hedberg 			     enum smp_key_pref key_pref)
2251854f4727SJohan Hedberg {
2252854f4727SJohan Hedberg 	if (sec_level == BT_SECURITY_LOW)
2253854f4727SJohan Hedberg 		return true;
2254854f4727SJohan Hedberg 
225535dc6f83SJohan Hedberg 	/* If we're encrypted with an STK but the caller prefers using
225635dc6f83SJohan Hedberg 	 * LTK claim insufficient security. This way we allow the
225735dc6f83SJohan Hedberg 	 * connection to be re-encrypted with an LTK, even if the LTK
225835dc6f83SJohan Hedberg 	 * provides the same level of security. Only exception is if we
225935dc6f83SJohan Hedberg 	 * don't have an LTK (e.g. because of key distribution bits).
22609ab65d60SJohan Hedberg 	 */
226135dc6f83SJohan Hedberg 	if (key_pref == SMP_USE_LTK &&
226235dc6f83SJohan Hedberg 	    test_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags) &&
2263f3a73d97SJohan Hedberg 	    hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, hcon->role))
22649ab65d60SJohan Hedberg 		return false;
22659ab65d60SJohan Hedberg 
2266854f4727SJohan Hedberg 	if (hcon->sec_level >= sec_level)
2267854f4727SJohan Hedberg 		return true;
2268854f4727SJohan Hedberg 
2269854f4727SJohan Hedberg 	return false;
2270854f4727SJohan Hedberg }
2271854f4727SJohan Hedberg 
2272da85e5e5SVinicius Costa Gomes static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
227388ba43b6SAnderson Briglia {
227488ba43b6SAnderson Briglia 	struct smp_cmd_security_req *rp = (void *) skb->data;
227588ba43b6SAnderson Briglia 	struct smp_cmd_pairing cp;
2276f1cb9af5SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
22770edb14deSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
22788aab4757SVinicius Costa Gomes 	struct smp_chan *smp;
2279c05b9339SJohan Hedberg 	u8 sec_level, auth;
228088ba43b6SAnderson Briglia 
228188ba43b6SAnderson Briglia 	BT_DBG("conn %p", conn);
228288ba43b6SAnderson Briglia 
2283c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rp))
228438e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2285c46b98beSJohan Hedberg 
228640bef302SJohan Hedberg 	if (hcon->role != HCI_ROLE_MASTER)
228786ca9eacSJohan Hedberg 		return SMP_CMD_NOTSUPP;
228886ca9eacSJohan Hedberg 
22890edb14deSJohan Hedberg 	auth = rp->auth_req & AUTH_REQ_MASK(hdev);
2290c05b9339SJohan Hedberg 
2291d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SC_ONLY) && !(auth & SMP_AUTH_SC))
2292903b71c7SJohan Hedberg 		return SMP_AUTH_REQUIREMENTS;
2293903b71c7SJohan Hedberg 
22945be5e275SJohan Hedberg 	if (hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
22951afc2a1aSJohan Hedberg 		sec_level = BT_SECURITY_MEDIUM;
22961afc2a1aSJohan Hedberg 	else
2297c05b9339SJohan Hedberg 		sec_level = authreq_to_seclevel(auth);
22981afc2a1aSJohan Hedberg 
229964e759f5SSzymon Janc 	if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK)) {
230064e759f5SSzymon Janc 		/* If link is already encrypted with sufficient security we
230164e759f5SSzymon Janc 		 * still need refresh encryption as per Core Spec 5.0 Vol 3,
230264e759f5SSzymon Janc 		 * Part H 2.4.6
230364e759f5SSzymon Janc 		 */
230464e759f5SSzymon Janc 		smp_ltk_encrypt(conn, hcon->sec_level);
2305854f4727SJohan Hedberg 		return 0;
230664e759f5SSzymon Janc 	}
2307854f4727SJohan Hedberg 
2308c7262e71SJohan Hedberg 	if (sec_level > hcon->pending_sec_level)
2309c7262e71SJohan Hedberg 		hcon->pending_sec_level = sec_level;
2310feb45eb5SVinicius Costa Gomes 
23114dab7864SJohan Hedberg 	if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
2312988c5997SVinicius Costa Gomes 		return 0;
2313988c5997SVinicius Costa Gomes 
23148aab4757SVinicius Costa Gomes 	smp = smp_chan_create(conn);
2315c29d2444SJohan Hedberg 	if (!smp)
2316c29d2444SJohan Hedberg 		return SMP_UNSPECIFIED;
2317d26a2345SVinicius Costa Gomes 
2318d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BONDABLE) &&
2319c05b9339SJohan Hedberg 	    (auth & SMP_AUTH_BONDING))
2320616d55beSJohan Hedberg 		return SMP_PAIRING_NOTSUPP;
2321616d55beSJohan Hedberg 
232288ba43b6SAnderson Briglia 	skb_pull(skb, sizeof(*rp));
232388ba43b6SAnderson Briglia 
2324da85e5e5SVinicius Costa Gomes 	memset(&cp, 0, sizeof(cp));
2325c05b9339SJohan Hedberg 	build_pairing_cmd(conn, &cp, NULL, auth);
232688ba43b6SAnderson Briglia 
23271c1def09SVinicius Costa Gomes 	smp->preq[0] = SMP_CMD_PAIRING_REQ;
23281c1def09SVinicius Costa Gomes 	memcpy(&smp->preq[1], &cp, sizeof(cp));
2329f01ead31SAnderson Briglia 
233088ba43b6SAnderson Briglia 	smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
2331b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP);
2332f1cb9af5SVinicius Costa Gomes 
2333da85e5e5SVinicius Costa Gomes 	return 0;
233488ba43b6SAnderson Briglia }
233588ba43b6SAnderson Briglia 
2336cc110922SVinicius Costa Gomes int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
2337eb492e01SAnderson Briglia {
2338cc110922SVinicius Costa Gomes 	struct l2cap_conn *conn = hcon->l2cap_data;
2339c68b7f12SJohan Hedberg 	struct l2cap_chan *chan;
23400a66cf20SJohan Hedberg 	struct smp_chan *smp;
23412b64d153SBrian Gix 	__u8 authreq;
2342fc75cc86SJohan Hedberg 	int ret;
2343eb492e01SAnderson Briglia 
23443a0259bbSVinicius Costa Gomes 	BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
23453a0259bbSVinicius Costa Gomes 
23460a66cf20SJohan Hedberg 	/* This may be NULL if there's an unexpected disconnection */
23470a66cf20SJohan Hedberg 	if (!conn)
23480a66cf20SJohan Hedberg 		return 1;
23490a66cf20SJohan Hedberg 
2350d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hcon->hdev, HCI_LE_ENABLED))
23512e65c9d2SAndre Guedes 		return 1;
23522e65c9d2SAndre Guedes 
235335dc6f83SJohan Hedberg 	if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK))
2354f1cb9af5SVinicius Costa Gomes 		return 1;
2355f1cb9af5SVinicius Costa Gomes 
2356c7262e71SJohan Hedberg 	if (sec_level > hcon->pending_sec_level)
2357c7262e71SJohan Hedberg 		hcon->pending_sec_level = sec_level;
2358c7262e71SJohan Hedberg 
235940bef302SJohan Hedberg 	if (hcon->role == HCI_ROLE_MASTER)
2360c7262e71SJohan Hedberg 		if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
2361c7262e71SJohan Hedberg 			return 0;
2362d26a2345SVinicius Costa Gomes 
2363d8949aadSJohan Hedberg 	chan = conn->smp;
2364d8949aadSJohan Hedberg 	if (!chan) {
23652064ee33SMarcel Holtmann 		bt_dev_err(hcon->hdev, "security requested but not available");
2366d8949aadSJohan Hedberg 		return 1;
2367d8949aadSJohan Hedberg 	}
2368d8949aadSJohan Hedberg 
2369fc75cc86SJohan Hedberg 	l2cap_chan_lock(chan);
2370fc75cc86SJohan Hedberg 
2371fc75cc86SJohan Hedberg 	/* If SMP is already in progress ignore this request */
2372fc75cc86SJohan Hedberg 	if (chan->data) {
2373fc75cc86SJohan Hedberg 		ret = 0;
2374fc75cc86SJohan Hedberg 		goto unlock;
2375fc75cc86SJohan Hedberg 	}
2376d26a2345SVinicius Costa Gomes 
23778aab4757SVinicius Costa Gomes 	smp = smp_chan_create(conn);
2378fc75cc86SJohan Hedberg 	if (!smp) {
2379fc75cc86SJohan Hedberg 		ret = 1;
2380fc75cc86SJohan Hedberg 		goto unlock;
2381fc75cc86SJohan Hedberg 	}
23822b64d153SBrian Gix 
23832b64d153SBrian Gix 	authreq = seclevel_to_authreq(sec_level);
2384d26a2345SVinicius Costa Gomes 
2385a62da6f1SJohan Hedberg 	if (hci_dev_test_flag(hcon->hdev, HCI_SC_ENABLED)) {
2386d2eb9e10SJohan Hedberg 		authreq |= SMP_AUTH_SC;
2387a62da6f1SJohan Hedberg 		if (hci_dev_test_flag(hcon->hdev, HCI_SSP_ENABLED))
2388a62da6f1SJohan Hedberg 			authreq |= SMP_AUTH_CT2;
2389a62da6f1SJohan Hedberg 	}
2390d2eb9e10SJohan Hedberg 
239179897d20SJohan Hedberg 	/* Require MITM if IO Capability allows or the security level
239279897d20SJohan Hedberg 	 * requires it.
23932e233644SJohan Hedberg 	 */
239479897d20SJohan Hedberg 	if (hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT ||
2395c7262e71SJohan Hedberg 	    hcon->pending_sec_level > BT_SECURITY_MEDIUM)
23962e233644SJohan Hedberg 		authreq |= SMP_AUTH_MITM;
23972e233644SJohan Hedberg 
239840bef302SJohan Hedberg 	if (hcon->role == HCI_ROLE_MASTER) {
2399d26a2345SVinicius Costa Gomes 		struct smp_cmd_pairing cp;
2400f01ead31SAnderson Briglia 
24012b64d153SBrian Gix 		build_pairing_cmd(conn, &cp, NULL, authreq);
24021c1def09SVinicius Costa Gomes 		smp->preq[0] = SMP_CMD_PAIRING_REQ;
24031c1def09SVinicius Costa Gomes 		memcpy(&smp->preq[1], &cp, sizeof(cp));
2404f01ead31SAnderson Briglia 
2405eb492e01SAnderson Briglia 		smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
2406b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP);
2407eb492e01SAnderson Briglia 	} else {
2408eb492e01SAnderson Briglia 		struct smp_cmd_security_req cp;
24092b64d153SBrian Gix 		cp.auth_req = authreq;
2410eb492e01SAnderson Briglia 		smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
2411b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_REQ);
2412eb492e01SAnderson Briglia 	}
2413eb492e01SAnderson Briglia 
24144a74d658SJohan Hedberg 	set_bit(SMP_FLAG_INITIATOR, &smp->flags);
2415fc75cc86SJohan Hedberg 	ret = 0;
2416edca792cSJohan Hedberg 
2417fc75cc86SJohan Hedberg unlock:
2418fc75cc86SJohan Hedberg 	l2cap_chan_unlock(chan);
2419fc75cc86SJohan Hedberg 	return ret;
2420eb492e01SAnderson Briglia }
2421eb492e01SAnderson Briglia 
2422cb28c306SMatias Karhumaa int smp_cancel_and_remove_pairing(struct hci_dev *hdev, bdaddr_t *bdaddr,
2423cb28c306SMatias Karhumaa 				  u8 addr_type)
2424c81d555aSJohan Hedberg {
2425cb28c306SMatias Karhumaa 	struct hci_conn *hcon;
2426cb28c306SMatias Karhumaa 	struct l2cap_conn *conn;
2427c81d555aSJohan Hedberg 	struct l2cap_chan *chan;
2428c81d555aSJohan Hedberg 	struct smp_chan *smp;
2429cb28c306SMatias Karhumaa 	int err;
2430c81d555aSJohan Hedberg 
2431cb28c306SMatias Karhumaa 	err = hci_remove_ltk(hdev, bdaddr, addr_type);
2432cb28c306SMatias Karhumaa 	hci_remove_irk(hdev, bdaddr, addr_type);
2433cb28c306SMatias Karhumaa 
2434cb28c306SMatias Karhumaa 	hcon = hci_conn_hash_lookup_le(hdev, bdaddr, addr_type);
2435cb28c306SMatias Karhumaa 	if (!hcon)
2436cb28c306SMatias Karhumaa 		goto done;
2437cb28c306SMatias Karhumaa 
2438cb28c306SMatias Karhumaa 	conn = hcon->l2cap_data;
2439c81d555aSJohan Hedberg 	if (!conn)
2440cb28c306SMatias Karhumaa 		goto done;
2441c81d555aSJohan Hedberg 
2442c81d555aSJohan Hedberg 	chan = conn->smp;
2443c81d555aSJohan Hedberg 	if (!chan)
2444cb28c306SMatias Karhumaa 		goto done;
2445c81d555aSJohan Hedberg 
2446c81d555aSJohan Hedberg 	l2cap_chan_lock(chan);
2447c81d555aSJohan Hedberg 
2448c81d555aSJohan Hedberg 	smp = chan->data;
2449c81d555aSJohan Hedberg 	if (smp) {
2450cb28c306SMatias Karhumaa 		/* Set keys to NULL to make sure smp_failure() does not try to
2451cb28c306SMatias Karhumaa 		 * remove and free already invalidated rcu list entries. */
2452cb28c306SMatias Karhumaa 		smp->ltk = NULL;
2453cb28c306SMatias Karhumaa 		smp->slave_ltk = NULL;
2454cb28c306SMatias Karhumaa 		smp->remote_irk = NULL;
2455cb28c306SMatias Karhumaa 
2456c81d555aSJohan Hedberg 		if (test_bit(SMP_FLAG_COMPLETE, &smp->flags))
2457c81d555aSJohan Hedberg 			smp_failure(conn, 0);
2458c81d555aSJohan Hedberg 		else
2459c81d555aSJohan Hedberg 			smp_failure(conn, SMP_UNSPECIFIED);
2460cb28c306SMatias Karhumaa 		err = 0;
2461c81d555aSJohan Hedberg 	}
2462c81d555aSJohan Hedberg 
2463c81d555aSJohan Hedberg 	l2cap_chan_unlock(chan);
2464cb28c306SMatias Karhumaa 
2465cb28c306SMatias Karhumaa done:
2466cb28c306SMatias Karhumaa 	return err;
2467c81d555aSJohan Hedberg }
2468c81d555aSJohan Hedberg 
24697034b911SVinicius Costa Gomes static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
24707034b911SVinicius Costa Gomes {
247116b90839SVinicius Costa Gomes 	struct smp_cmd_encrypt_info *rp = (void *) skb->data;
24725d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
24735d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
247416b90839SVinicius Costa Gomes 
2475c46b98beSJohan Hedberg 	BT_DBG("conn %p", conn);
2476c46b98beSJohan Hedberg 
2477c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rp))
247838e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2479c46b98beSJohan Hedberg 
2480b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_MASTER_IDENT);
24816131ddc8SJohan Hedberg 
248216b90839SVinicius Costa Gomes 	skb_pull(skb, sizeof(*rp));
248316b90839SVinicius Costa Gomes 
24841c1def09SVinicius Costa Gomes 	memcpy(smp->tk, rp->ltk, sizeof(smp->tk));
248516b90839SVinicius Costa Gomes 
24867034b911SVinicius Costa Gomes 	return 0;
24877034b911SVinicius Costa Gomes }
24887034b911SVinicius Costa Gomes 
24897034b911SVinicius Costa Gomes static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
24907034b911SVinicius Costa Gomes {
249116b90839SVinicius Costa Gomes 	struct smp_cmd_master_ident *rp = (void *) skb->data;
24925d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
24935d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
2494c9839a11SVinicius Costa Gomes 	struct hci_dev *hdev = conn->hcon->hdev;
2495c9839a11SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
249623d0e128SJohan Hedberg 	struct smp_ltk *ltk;
2497c9839a11SVinicius Costa Gomes 	u8 authenticated;
24987034b911SVinicius Costa Gomes 
2499c46b98beSJohan Hedberg 	BT_DBG("conn %p", conn);
2500c46b98beSJohan Hedberg 
2501c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rp))
250238e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2503c46b98beSJohan Hedberg 
25049747a9f3SJohan Hedberg 	/* Mark the information as received */
25059747a9f3SJohan Hedberg 	smp->remote_key_dist &= ~SMP_DIST_ENC_KEY;
25069747a9f3SJohan Hedberg 
2507b28b4943SJohan Hedberg 	if (smp->remote_key_dist & SMP_DIST_ID_KEY)
2508b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO);
2509196332f5SJohan Hedberg 	else if (smp->remote_key_dist & SMP_DIST_SIGN)
2510196332f5SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO);
2511b28b4943SJohan Hedberg 
251216b90839SVinicius Costa Gomes 	skb_pull(skb, sizeof(*rp));
251316b90839SVinicius Costa Gomes 
2514ce39fb4eSMarcel Holtmann 	authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
25152ceba539SJohan Hedberg 	ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, SMP_LTK,
2516ce39fb4eSMarcel Holtmann 			  authenticated, smp->tk, smp->enc_key_size,
251704124681SGustavo F. Padovan 			  rp->ediv, rp->rand);
251823d0e128SJohan Hedberg 	smp->ltk = ltk;
2519c6e81e9aSJohan Hedberg 	if (!(smp->remote_key_dist & KEY_DIST_MASK))
2520d6268e86SJohan Hedberg 		smp_distribute_keys(smp);
25217034b911SVinicius Costa Gomes 
25227034b911SVinicius Costa Gomes 	return 0;
25237034b911SVinicius Costa Gomes }
25247034b911SVinicius Costa Gomes 
2525fd349c02SJohan Hedberg static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
2526fd349c02SJohan Hedberg {
2527fd349c02SJohan Hedberg 	struct smp_cmd_ident_info *info = (void *) skb->data;
25285d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
25295d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
2530fd349c02SJohan Hedberg 
2531fd349c02SJohan Hedberg 	BT_DBG("");
2532fd349c02SJohan Hedberg 
2533fd349c02SJohan Hedberg 	if (skb->len < sizeof(*info))
253438e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2535fd349c02SJohan Hedberg 
2536b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_ADDR_INFO);
25376131ddc8SJohan Hedberg 
2538fd349c02SJohan Hedberg 	skb_pull(skb, sizeof(*info));
2539fd349c02SJohan Hedberg 
2540fd349c02SJohan Hedberg 	memcpy(smp->irk, info->irk, 16);
2541fd349c02SJohan Hedberg 
2542fd349c02SJohan Hedberg 	return 0;
2543fd349c02SJohan Hedberg }
2544fd349c02SJohan Hedberg 
2545fd349c02SJohan Hedberg static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
2546fd349c02SJohan Hedberg 				   struct sk_buff *skb)
2547fd349c02SJohan Hedberg {
2548fd349c02SJohan Hedberg 	struct smp_cmd_ident_addr_info *info = (void *) skb->data;
25495d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
25505d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
2551fd349c02SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
2552fd349c02SJohan Hedberg 	bdaddr_t rpa;
2553fd349c02SJohan Hedberg 
2554fd349c02SJohan Hedberg 	BT_DBG("");
2555fd349c02SJohan Hedberg 
2556fd349c02SJohan Hedberg 	if (skb->len < sizeof(*info))
255738e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2558fd349c02SJohan Hedberg 
25599747a9f3SJohan Hedberg 	/* Mark the information as received */
25609747a9f3SJohan Hedberg 	smp->remote_key_dist &= ~SMP_DIST_ID_KEY;
25619747a9f3SJohan Hedberg 
2562b28b4943SJohan Hedberg 	if (smp->remote_key_dist & SMP_DIST_SIGN)
2563b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO);
2564b28b4943SJohan Hedberg 
2565fd349c02SJohan Hedberg 	skb_pull(skb, sizeof(*info));
2566fd349c02SJohan Hedberg 
2567a9a58f86SJohan Hedberg 	/* Strictly speaking the Core Specification (4.1) allows sending
2568a9a58f86SJohan Hedberg 	 * an empty address which would force us to rely on just the IRK
2569a9a58f86SJohan Hedberg 	 * as "identity information". However, since such
2570a9a58f86SJohan Hedberg 	 * implementations are not known of and in order to not over
2571a9a58f86SJohan Hedberg 	 * complicate our implementation, simply pretend that we never
2572a9a58f86SJohan Hedberg 	 * received an IRK for such a device.
2573e12af489SJohan Hedberg 	 *
2574e12af489SJohan Hedberg 	 * The Identity Address must also be a Static Random or Public
2575e12af489SJohan Hedberg 	 * Address, which hci_is_identity_address() checks for.
2576a9a58f86SJohan Hedberg 	 */
2577e12af489SJohan Hedberg 	if (!bacmp(&info->bdaddr, BDADDR_ANY) ||
2578e12af489SJohan Hedberg 	    !hci_is_identity_address(&info->bdaddr, info->addr_type)) {
25792064ee33SMarcel Holtmann 		bt_dev_err(hcon->hdev, "ignoring IRK with no identity address");
258031dd624eSJohan Hedberg 		goto distribute;
2581a9a58f86SJohan Hedberg 	}
2582a9a58f86SJohan Hedberg 
2583fd349c02SJohan Hedberg 	bacpy(&smp->id_addr, &info->bdaddr);
2584fd349c02SJohan Hedberg 	smp->id_addr_type = info->addr_type;
2585fd349c02SJohan Hedberg 
2586fd349c02SJohan Hedberg 	if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type))
2587fd349c02SJohan Hedberg 		bacpy(&rpa, &hcon->dst);
2588fd349c02SJohan Hedberg 	else
2589fd349c02SJohan Hedberg 		bacpy(&rpa, BDADDR_ANY);
2590fd349c02SJohan Hedberg 
259123d0e128SJohan Hedberg 	smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
259223d0e128SJohan Hedberg 				      smp->id_addr_type, smp->irk, &rpa);
2593fd349c02SJohan Hedberg 
259431dd624eSJohan Hedberg distribute:
2595c6e81e9aSJohan Hedberg 	if (!(smp->remote_key_dist & KEY_DIST_MASK))
2596d6268e86SJohan Hedberg 		smp_distribute_keys(smp);
2597fd349c02SJohan Hedberg 
2598fd349c02SJohan Hedberg 	return 0;
2599fd349c02SJohan Hedberg }
2600fd349c02SJohan Hedberg 
26017ee4ea36SMarcel Holtmann static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)
26027ee4ea36SMarcel Holtmann {
26037ee4ea36SMarcel Holtmann 	struct smp_cmd_sign_info *rp = (void *) skb->data;
26045d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
26055d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
26067ee4ea36SMarcel Holtmann 	struct smp_csrk *csrk;
26077ee4ea36SMarcel Holtmann 
26087ee4ea36SMarcel Holtmann 	BT_DBG("conn %p", conn);
26097ee4ea36SMarcel Holtmann 
26107ee4ea36SMarcel Holtmann 	if (skb->len < sizeof(*rp))
261138e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
26127ee4ea36SMarcel Holtmann 
26137ee4ea36SMarcel Holtmann 	/* Mark the information as received */
26147ee4ea36SMarcel Holtmann 	smp->remote_key_dist &= ~SMP_DIST_SIGN;
26157ee4ea36SMarcel Holtmann 
26167ee4ea36SMarcel Holtmann 	skb_pull(skb, sizeof(*rp));
26177ee4ea36SMarcel Holtmann 
26187ee4ea36SMarcel Holtmann 	csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
26197ee4ea36SMarcel Holtmann 	if (csrk) {
26204cd3928aSJohan Hedberg 		if (conn->hcon->sec_level > BT_SECURITY_MEDIUM)
26214cd3928aSJohan Hedberg 			csrk->type = MGMT_CSRK_REMOTE_AUTHENTICATED;
26224cd3928aSJohan Hedberg 		else
26234cd3928aSJohan Hedberg 			csrk->type = MGMT_CSRK_REMOTE_UNAUTHENTICATED;
26247ee4ea36SMarcel Holtmann 		memcpy(csrk->val, rp->csrk, sizeof(csrk->val));
26257ee4ea36SMarcel Holtmann 	}
26267ee4ea36SMarcel Holtmann 	smp->csrk = csrk;
2627d6268e86SJohan Hedberg 	smp_distribute_keys(smp);
26287ee4ea36SMarcel Holtmann 
26297ee4ea36SMarcel Holtmann 	return 0;
26307ee4ea36SMarcel Holtmann }
26317ee4ea36SMarcel Holtmann 
26325e3d3d9bSJohan Hedberg static u8 sc_select_method(struct smp_chan *smp)
26335e3d3d9bSJohan Hedberg {
26345e3d3d9bSJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
26355e3d3d9bSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
26365e3d3d9bSJohan Hedberg 	struct smp_cmd_pairing *local, *remote;
26375e3d3d9bSJohan Hedberg 	u8 local_mitm, remote_mitm, local_io, remote_io, method;
26385e3d3d9bSJohan Hedberg 
26391a8bab4fSJohan Hedberg 	if (test_bit(SMP_FLAG_REMOTE_OOB, &smp->flags) ||
26401a8bab4fSJohan Hedberg 	    test_bit(SMP_FLAG_LOCAL_OOB, &smp->flags))
2641a29b0733SJohan Hedberg 		return REQ_OOB;
2642a29b0733SJohan Hedberg 
26435e3d3d9bSJohan Hedberg 	/* The preq/prsp contain the raw Pairing Request/Response PDUs
26445e3d3d9bSJohan Hedberg 	 * which are needed as inputs to some crypto functions. To get
26455e3d3d9bSJohan Hedberg 	 * the "struct smp_cmd_pairing" from them we need to skip the
26465e3d3d9bSJohan Hedberg 	 * first byte which contains the opcode.
26475e3d3d9bSJohan Hedberg 	 */
26485e3d3d9bSJohan Hedberg 	if (hcon->out) {
26495e3d3d9bSJohan Hedberg 		local = (void *) &smp->preq[1];
26505e3d3d9bSJohan Hedberg 		remote = (void *) &smp->prsp[1];
26515e3d3d9bSJohan Hedberg 	} else {
26525e3d3d9bSJohan Hedberg 		local = (void *) &smp->prsp[1];
26535e3d3d9bSJohan Hedberg 		remote = (void *) &smp->preq[1];
26545e3d3d9bSJohan Hedberg 	}
26555e3d3d9bSJohan Hedberg 
26565e3d3d9bSJohan Hedberg 	local_io = local->io_capability;
26575e3d3d9bSJohan Hedberg 	remote_io = remote->io_capability;
26585e3d3d9bSJohan Hedberg 
26595e3d3d9bSJohan Hedberg 	local_mitm = (local->auth_req & SMP_AUTH_MITM);
26605e3d3d9bSJohan Hedberg 	remote_mitm = (remote->auth_req & SMP_AUTH_MITM);
26615e3d3d9bSJohan Hedberg 
26625e3d3d9bSJohan Hedberg 	/* If either side wants MITM, look up the method from the table,
26635e3d3d9bSJohan Hedberg 	 * otherwise use JUST WORKS.
26645e3d3d9bSJohan Hedberg 	 */
26655e3d3d9bSJohan Hedberg 	if (local_mitm || remote_mitm)
26665e3d3d9bSJohan Hedberg 		method = get_auth_method(smp, local_io, remote_io);
26675e3d3d9bSJohan Hedberg 	else
26685e3d3d9bSJohan Hedberg 		method = JUST_WORKS;
26695e3d3d9bSJohan Hedberg 
26705e3d3d9bSJohan Hedberg 	/* Don't confirm locally initiated pairing attempts */
26715e3d3d9bSJohan Hedberg 	if (method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR, &smp->flags))
26725e3d3d9bSJohan Hedberg 		method = JUST_WORKS;
26735e3d3d9bSJohan Hedberg 
26745e3d3d9bSJohan Hedberg 	return method;
26755e3d3d9bSJohan Hedberg }
26765e3d3d9bSJohan Hedberg 
2677d8f8edbeSJohan Hedberg static int smp_cmd_public_key(struct l2cap_conn *conn, struct sk_buff *skb)
2678d8f8edbeSJohan Hedberg {
2679d8f8edbeSJohan Hedberg 	struct smp_cmd_public_key *key = (void *) skb->data;
2680d8f8edbeSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
2681d8f8edbeSJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
2682d8f8edbeSJohan Hedberg 	struct smp_chan *smp = chan->data;
26835e3d3d9bSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
2684c0153b0bSTudor Ambarus 	struct crypto_kpp *tfm_ecdh;
2685cbbbe3e2SJohan Hedberg 	struct smp_cmd_pairing_confirm cfm;
2686d8f8edbeSJohan Hedberg 	int err;
2687d8f8edbeSJohan Hedberg 
2688d8f8edbeSJohan Hedberg 	BT_DBG("conn %p", conn);
2689d8f8edbeSJohan Hedberg 
2690d8f8edbeSJohan Hedberg 	if (skb->len < sizeof(*key))
2691d8f8edbeSJohan Hedberg 		return SMP_INVALID_PARAMS;
2692d8f8edbeSJohan Hedberg 
2693d8f8edbeSJohan Hedberg 	memcpy(smp->remote_pk, key, 64);
2694d8f8edbeSJohan Hedberg 
2695a8ca617cSJohan Hedberg 	if (test_bit(SMP_FLAG_REMOTE_OOB, &smp->flags)) {
2696a8ca617cSJohan Hedberg 		err = smp_f4(smp->tfm_cmac, smp->remote_pk, smp->remote_pk,
2697a8ca617cSJohan Hedberg 			     smp->rr, 0, cfm.confirm_val);
2698a8ca617cSJohan Hedberg 		if (err)
2699a8ca617cSJohan Hedberg 			return SMP_UNSPECIFIED;
2700a8ca617cSJohan Hedberg 
2701329d8230SJason A. Donenfeld 		if (crypto_memneq(cfm.confirm_val, smp->pcnf, 16))
2702a8ca617cSJohan Hedberg 			return SMP_CONFIRM_FAILED;
2703a8ca617cSJohan Hedberg 	}
2704a8ca617cSJohan Hedberg 
2705d8f8edbeSJohan Hedberg 	/* Non-initiating device sends its public key after receiving
2706d8f8edbeSJohan Hedberg 	 * the key from the initiating device.
2707d8f8edbeSJohan Hedberg 	 */
2708d8f8edbeSJohan Hedberg 	if (!hcon->out) {
2709d8f8edbeSJohan Hedberg 		err = sc_send_public_key(smp);
2710d8f8edbeSJohan Hedberg 		if (err)
2711d8f8edbeSJohan Hedberg 			return err;
2712d8f8edbeSJohan Hedberg 	}
2713d8f8edbeSJohan Hedberg 
2714c7a3d57dSJohan Hedberg 	SMP_DBG("Remote Public Key X: %32phN", smp->remote_pk);
2715e091526dSMarcel Holtmann 	SMP_DBG("Remote Public Key Y: %32phN", smp->remote_pk + 32);
2716d8f8edbeSJohan Hedberg 
2717c0153b0bSTudor Ambarus 	/* Compute the shared secret on the same crypto tfm on which the private
2718c0153b0bSTudor Ambarus 	 * key was set/generated.
2719c0153b0bSTudor Ambarus 	 */
2720c0153b0bSTudor Ambarus 	if (test_bit(SMP_FLAG_LOCAL_OOB, &smp->flags)) {
27214ba5175fSMatias Karhumaa 		struct l2cap_chan *hchan = hdev->smp_data;
27224ba5175fSMatias Karhumaa 		struct smp_dev *smp_dev;
27234ba5175fSMatias Karhumaa 
27244ba5175fSMatias Karhumaa 		if (!hchan || !hchan->data)
27254ba5175fSMatias Karhumaa 			return SMP_UNSPECIFIED;
27264ba5175fSMatias Karhumaa 
27274ba5175fSMatias Karhumaa 		smp_dev = hchan->data;
2728c0153b0bSTudor Ambarus 
2729c0153b0bSTudor Ambarus 		tfm_ecdh = smp_dev->tfm_ecdh;
2730c0153b0bSTudor Ambarus 	} else {
2731c0153b0bSTudor Ambarus 		tfm_ecdh = smp->tfm_ecdh;
2732c0153b0bSTudor Ambarus 	}
2733c0153b0bSTudor Ambarus 
2734c0153b0bSTudor Ambarus 	if (compute_ecdh_secret(tfm_ecdh, smp->remote_pk, smp->dhkey))
2735d8f8edbeSJohan Hedberg 		return SMP_UNSPECIFIED;
2736d8f8edbeSJohan Hedberg 
2737c7a3d57dSJohan Hedberg 	SMP_DBG("DHKey %32phN", smp->dhkey);
2738d8f8edbeSJohan Hedberg 
2739d8f8edbeSJohan Hedberg 	set_bit(SMP_FLAG_REMOTE_PK, &smp->flags);
2740d8f8edbeSJohan Hedberg 
27415e3d3d9bSJohan Hedberg 	smp->method = sc_select_method(smp);
27425e3d3d9bSJohan Hedberg 
27435e3d3d9bSJohan Hedberg 	BT_DBG("%s selected method 0x%02x", hdev->name, smp->method);
27445e3d3d9bSJohan Hedberg 
27455e3d3d9bSJohan Hedberg 	/* JUST_WORKS and JUST_CFM result in an unauthenticated key */
27465e3d3d9bSJohan Hedberg 	if (smp->method == JUST_WORKS || smp->method == JUST_CFM)
27475e3d3d9bSJohan Hedberg 		hcon->pending_sec_level = BT_SECURITY_MEDIUM;
27485e3d3d9bSJohan Hedberg 	else
27495e3d3d9bSJohan Hedberg 		hcon->pending_sec_level = BT_SECURITY_FIPS;
27505e3d3d9bSJohan Hedberg 
2751329d8230SJason A. Donenfeld 	if (!crypto_memneq(debug_pk, smp->remote_pk, 64))
2752aeb7d461SJohan Hedberg 		set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags);
2753aeb7d461SJohan Hedberg 
275438606f14SJohan Hedberg 	if (smp->method == DSP_PASSKEY) {
275538606f14SJohan Hedberg 		get_random_bytes(&hcon->passkey_notify,
275638606f14SJohan Hedberg 				 sizeof(hcon->passkey_notify));
275738606f14SJohan Hedberg 		hcon->passkey_notify %= 1000000;
275838606f14SJohan Hedberg 		hcon->passkey_entered = 0;
275938606f14SJohan Hedberg 		smp->passkey_round = 0;
276038606f14SJohan Hedberg 		if (mgmt_user_passkey_notify(hdev, &hcon->dst, hcon->type,
276138606f14SJohan Hedberg 					     hcon->dst_type,
276238606f14SJohan Hedberg 					     hcon->passkey_notify,
276338606f14SJohan Hedberg 					     hcon->passkey_entered))
276438606f14SJohan Hedberg 			return SMP_UNSPECIFIED;
276538606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
276638606f14SJohan Hedberg 		return sc_passkey_round(smp, SMP_CMD_PUBLIC_KEY);
276738606f14SJohan Hedberg 	}
276838606f14SJohan Hedberg 
276994ea7257SJohan Hedberg 	if (smp->method == REQ_OOB) {
2770a29b0733SJohan Hedberg 		if (hcon->out)
2771a29b0733SJohan Hedberg 			smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM,
2772a29b0733SJohan Hedberg 				     sizeof(smp->prnd), smp->prnd);
2773a29b0733SJohan Hedberg 
2774a29b0733SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
2775a29b0733SJohan Hedberg 
2776a29b0733SJohan Hedberg 		return 0;
2777a29b0733SJohan Hedberg 	}
2778a29b0733SJohan Hedberg 
277938606f14SJohan Hedberg 	if (hcon->out)
278038606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
278138606f14SJohan Hedberg 
278238606f14SJohan Hedberg 	if (smp->method == REQ_PASSKEY) {
278338606f14SJohan Hedberg 		if (mgmt_user_passkey_request(hdev, &hcon->dst, hcon->type,
278438606f14SJohan Hedberg 					      hcon->dst_type))
278538606f14SJohan Hedberg 			return SMP_UNSPECIFIED;
278638606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
278738606f14SJohan Hedberg 		set_bit(SMP_FLAG_WAIT_USER, &smp->flags);
278838606f14SJohan Hedberg 		return 0;
278938606f14SJohan Hedberg 	}
279038606f14SJohan Hedberg 
2791cbbbe3e2SJohan Hedberg 	/* The Initiating device waits for the non-initiating device to
2792cbbbe3e2SJohan Hedberg 	 * send the confirm value.
2793cbbbe3e2SJohan Hedberg 	 */
2794cbbbe3e2SJohan Hedberg 	if (conn->hcon->out)
2795cbbbe3e2SJohan Hedberg 		return 0;
2796cbbbe3e2SJohan Hedberg 
2797cbbbe3e2SJohan Hedberg 	err = smp_f4(smp->tfm_cmac, smp->local_pk, smp->remote_pk, smp->prnd,
2798cbbbe3e2SJohan Hedberg 		     0, cfm.confirm_val);
2799cbbbe3e2SJohan Hedberg 	if (err)
2800cbbbe3e2SJohan Hedberg 		return SMP_UNSPECIFIED;
2801cbbbe3e2SJohan Hedberg 
2802cbbbe3e2SJohan Hedberg 	smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cfm), &cfm);
2803cbbbe3e2SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
2804cbbbe3e2SJohan Hedberg 
2805d8f8edbeSJohan Hedberg 	return 0;
2806d8f8edbeSJohan Hedberg }
2807d8f8edbeSJohan Hedberg 
28086433a9a2SJohan Hedberg static int smp_cmd_dhkey_check(struct l2cap_conn *conn, struct sk_buff *skb)
28096433a9a2SJohan Hedberg {
28106433a9a2SJohan Hedberg 	struct smp_cmd_dhkey_check *check = (void *) skb->data;
28116433a9a2SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
28126433a9a2SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
28136433a9a2SJohan Hedberg 	struct smp_chan *smp = chan->data;
28146433a9a2SJohan Hedberg 	u8 a[7], b[7], *local_addr, *remote_addr;
28156433a9a2SJohan Hedberg 	u8 io_cap[3], r[16], e[16];
28166433a9a2SJohan Hedberg 	int err;
28176433a9a2SJohan Hedberg 
28186433a9a2SJohan Hedberg 	BT_DBG("conn %p", conn);
28196433a9a2SJohan Hedberg 
28206433a9a2SJohan Hedberg 	if (skb->len < sizeof(*check))
28216433a9a2SJohan Hedberg 		return SMP_INVALID_PARAMS;
28226433a9a2SJohan Hedberg 
28236433a9a2SJohan Hedberg 	memcpy(a, &hcon->init_addr, 6);
28246433a9a2SJohan Hedberg 	memcpy(b, &hcon->resp_addr, 6);
28256433a9a2SJohan Hedberg 	a[6] = hcon->init_addr_type;
28266433a9a2SJohan Hedberg 	b[6] = hcon->resp_addr_type;
28276433a9a2SJohan Hedberg 
28286433a9a2SJohan Hedberg 	if (hcon->out) {
28296433a9a2SJohan Hedberg 		local_addr = a;
28306433a9a2SJohan Hedberg 		remote_addr = b;
28316433a9a2SJohan Hedberg 		memcpy(io_cap, &smp->prsp[1], 3);
28326433a9a2SJohan Hedberg 	} else {
28336433a9a2SJohan Hedberg 		local_addr = b;
28346433a9a2SJohan Hedberg 		remote_addr = a;
28356433a9a2SJohan Hedberg 		memcpy(io_cap, &smp->preq[1], 3);
28366433a9a2SJohan Hedberg 	}
28376433a9a2SJohan Hedberg 
28386433a9a2SJohan Hedberg 	memset(r, 0, sizeof(r));
28396433a9a2SJohan Hedberg 
284038606f14SJohan Hedberg 	if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY)
284138606f14SJohan Hedberg 		put_unaligned_le32(hcon->passkey_notify, r);
2842882fafadSJohan Hedberg 	else if (smp->method == REQ_OOB)
2843882fafadSJohan Hedberg 		memcpy(r, smp->lr, 16);
284438606f14SJohan Hedberg 
28456433a9a2SJohan Hedberg 	err = smp_f6(smp->tfm_cmac, smp->mackey, smp->rrnd, smp->prnd, r,
28466433a9a2SJohan Hedberg 		     io_cap, remote_addr, local_addr, e);
28476433a9a2SJohan Hedberg 	if (err)
28486433a9a2SJohan Hedberg 		return SMP_UNSPECIFIED;
28496433a9a2SJohan Hedberg 
2850329d8230SJason A. Donenfeld 	if (crypto_memneq(check->e, e, 16))
28516433a9a2SJohan Hedberg 		return SMP_DHKEY_CHECK_FAILED;
28526433a9a2SJohan Hedberg 
2853d3e54a87SJohan Hedberg 	if (!hcon->out) {
2854d3e54a87SJohan Hedberg 		if (test_bit(SMP_FLAG_WAIT_USER, &smp->flags)) {
2855d3e54a87SJohan Hedberg 			set_bit(SMP_FLAG_DHKEY_PENDING, &smp->flags);
2856d3e54a87SJohan Hedberg 			return 0;
2857d3e54a87SJohan Hedberg 		}
2858d378a2d7SJohan Hedberg 
2859d3e54a87SJohan Hedberg 		/* Slave sends DHKey check as response to master */
2860d3e54a87SJohan Hedberg 		sc_dhkey_check(smp);
2861d3e54a87SJohan Hedberg 	}
2862d378a2d7SJohan Hedberg 
2863d3e54a87SJohan Hedberg 	sc_add_ltk(smp);
28646433a9a2SJohan Hedberg 
28656433a9a2SJohan Hedberg 	if (hcon->out) {
28668b76ce34SJohan Hedberg 		hci_le_start_enc(hcon, 0, 0, smp->tk, smp->enc_key_size);
28676433a9a2SJohan Hedberg 		hcon->enc_key_size = smp->enc_key_size;
28686433a9a2SJohan Hedberg 	}
28696433a9a2SJohan Hedberg 
28706433a9a2SJohan Hedberg 	return 0;
28716433a9a2SJohan Hedberg }
28726433a9a2SJohan Hedberg 
28731408bb6eSJohan Hedberg static int smp_cmd_keypress_notify(struct l2cap_conn *conn,
28741408bb6eSJohan Hedberg 				   struct sk_buff *skb)
28751408bb6eSJohan Hedberg {
28761408bb6eSJohan Hedberg 	struct smp_cmd_keypress_notify *kp = (void *) skb->data;
28771408bb6eSJohan Hedberg 
28781408bb6eSJohan Hedberg 	BT_DBG("value 0x%02x", kp->value);
28791408bb6eSJohan Hedberg 
28801408bb6eSJohan Hedberg 	return 0;
28811408bb6eSJohan Hedberg }
28821408bb6eSJohan Hedberg 
28834befb867SJohan Hedberg static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb)
2884eb492e01SAnderson Briglia {
28855d88cc73SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
28867b9899dbSMarcel Holtmann 	struct hci_conn *hcon = conn->hcon;
2887b28b4943SJohan Hedberg 	struct smp_chan *smp;
288892381f5cSMarcel Holtmann 	__u8 code, reason;
2889eb492e01SAnderson Briglia 	int err = 0;
2890eb492e01SAnderson Briglia 
28918ae9b984SJohan Hedberg 	if (skb->len < 1)
289292381f5cSMarcel Holtmann 		return -EILSEQ;
289392381f5cSMarcel Holtmann 
2894d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hcon->hdev, HCI_LE_ENABLED)) {
28952e65c9d2SAndre Guedes 		reason = SMP_PAIRING_NOTSUPP;
28962e65c9d2SAndre Guedes 		goto done;
28972e65c9d2SAndre Guedes 	}
28982e65c9d2SAndre Guedes 
289992381f5cSMarcel Holtmann 	code = skb->data[0];
2900eb492e01SAnderson Briglia 	skb_pull(skb, sizeof(code));
2901eb492e01SAnderson Briglia 
2902b28b4943SJohan Hedberg 	smp = chan->data;
2903b28b4943SJohan Hedberg 
2904b28b4943SJohan Hedberg 	if (code > SMP_CMD_MAX)
2905b28b4943SJohan Hedberg 		goto drop;
2906b28b4943SJohan Hedberg 
290724bd0bd9SJohan Hedberg 	if (smp && !test_and_clear_bit(code, &smp->allow_cmd))
2908b28b4943SJohan Hedberg 		goto drop;
2909b28b4943SJohan Hedberg 
2910b28b4943SJohan Hedberg 	/* If we don't have a context the only allowed commands are
2911b28b4943SJohan Hedberg 	 * pairing request and security request.
29128cf9fa12SJohan Hedberg 	 */
2913b28b4943SJohan Hedberg 	if (!smp && code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ)
2914b28b4943SJohan Hedberg 		goto drop;
29158cf9fa12SJohan Hedberg 
2916eb492e01SAnderson Briglia 	switch (code) {
2917eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_REQ:
2918da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_req(conn, skb);
2919eb492e01SAnderson Briglia 		break;
2920eb492e01SAnderson Briglia 
2921eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_FAIL:
292284794e11SJohan Hedberg 		smp_failure(conn, 0);
2923da85e5e5SVinicius Costa Gomes 		err = -EPERM;
2924eb492e01SAnderson Briglia 		break;
2925eb492e01SAnderson Briglia 
2926eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_RSP:
2927da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_rsp(conn, skb);
292888ba43b6SAnderson Briglia 		break;
292988ba43b6SAnderson Briglia 
293088ba43b6SAnderson Briglia 	case SMP_CMD_SECURITY_REQ:
2931da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_security_req(conn, skb);
293288ba43b6SAnderson Briglia 		break;
293388ba43b6SAnderson Briglia 
2934eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_CONFIRM:
2935da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_confirm(conn, skb);
293688ba43b6SAnderson Briglia 		break;
293788ba43b6SAnderson Briglia 
2938eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_RANDOM:
2939da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_random(conn, skb);
294088ba43b6SAnderson Briglia 		break;
294188ba43b6SAnderson Briglia 
2942eb492e01SAnderson Briglia 	case SMP_CMD_ENCRYPT_INFO:
29437034b911SVinicius Costa Gomes 		reason = smp_cmd_encrypt_info(conn, skb);
29447034b911SVinicius Costa Gomes 		break;
29457034b911SVinicius Costa Gomes 
2946eb492e01SAnderson Briglia 	case SMP_CMD_MASTER_IDENT:
29477034b911SVinicius Costa Gomes 		reason = smp_cmd_master_ident(conn, skb);
29487034b911SVinicius Costa Gomes 		break;
29497034b911SVinicius Costa Gomes 
2950eb492e01SAnderson Briglia 	case SMP_CMD_IDENT_INFO:
2951fd349c02SJohan Hedberg 		reason = smp_cmd_ident_info(conn, skb);
2952fd349c02SJohan Hedberg 		break;
2953fd349c02SJohan Hedberg 
2954eb492e01SAnderson Briglia 	case SMP_CMD_IDENT_ADDR_INFO:
2955fd349c02SJohan Hedberg 		reason = smp_cmd_ident_addr_info(conn, skb);
2956fd349c02SJohan Hedberg 		break;
2957fd349c02SJohan Hedberg 
2958eb492e01SAnderson Briglia 	case SMP_CMD_SIGN_INFO:
29597ee4ea36SMarcel Holtmann 		reason = smp_cmd_sign_info(conn, skb);
29607034b911SVinicius Costa Gomes 		break;
29617034b911SVinicius Costa Gomes 
2962d8f8edbeSJohan Hedberg 	case SMP_CMD_PUBLIC_KEY:
2963d8f8edbeSJohan Hedberg 		reason = smp_cmd_public_key(conn, skb);
2964d8f8edbeSJohan Hedberg 		break;
2965d8f8edbeSJohan Hedberg 
29666433a9a2SJohan Hedberg 	case SMP_CMD_DHKEY_CHECK:
29676433a9a2SJohan Hedberg 		reason = smp_cmd_dhkey_check(conn, skb);
29686433a9a2SJohan Hedberg 		break;
29696433a9a2SJohan Hedberg 
29701408bb6eSJohan Hedberg 	case SMP_CMD_KEYPRESS_NOTIFY:
29711408bb6eSJohan Hedberg 		reason = smp_cmd_keypress_notify(conn, skb);
29721408bb6eSJohan Hedberg 		break;
29731408bb6eSJohan Hedberg 
2974eb492e01SAnderson Briglia 	default:
2975eb492e01SAnderson Briglia 		BT_DBG("Unknown command code 0x%2.2x", code);
2976eb492e01SAnderson Briglia 		reason = SMP_CMD_NOTSUPP;
29773a0259bbSVinicius Costa Gomes 		goto done;
29783a0259bbSVinicius Costa Gomes 	}
29793a0259bbSVinicius Costa Gomes 
29803a0259bbSVinicius Costa Gomes done:
29819b7b18efSJohan Hedberg 	if (!err) {
29823a0259bbSVinicius Costa Gomes 		if (reason)
298384794e11SJohan Hedberg 			smp_failure(conn, reason);
2984eb492e01SAnderson Briglia 		kfree_skb(skb);
29859b7b18efSJohan Hedberg 	}
29869b7b18efSJohan Hedberg 
2987eb492e01SAnderson Briglia 	return err;
2988b28b4943SJohan Hedberg 
2989b28b4943SJohan Hedberg drop:
29902064ee33SMarcel Holtmann 	bt_dev_err(hcon->hdev, "unexpected SMP command 0x%02x from %pMR",
2991b28b4943SJohan Hedberg 		   code, &hcon->dst);
2992b28b4943SJohan Hedberg 	kfree_skb(skb);
2993b28b4943SJohan Hedberg 	return 0;
2994eb492e01SAnderson Briglia }
29957034b911SVinicius Costa Gomes 
299670db83c4SJohan Hedberg static void smp_teardown_cb(struct l2cap_chan *chan, int err)
299770db83c4SJohan Hedberg {
299870db83c4SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
299970db83c4SJohan Hedberg 
300070db83c4SJohan Hedberg 	BT_DBG("chan %p", chan);
300170db83c4SJohan Hedberg 
3002fc75cc86SJohan Hedberg 	if (chan->data)
30035d88cc73SJohan Hedberg 		smp_chan_destroy(conn);
30045d88cc73SJohan Hedberg 
300570db83c4SJohan Hedberg 	conn->smp = NULL;
300670db83c4SJohan Hedberg 	l2cap_chan_put(chan);
300770db83c4SJohan Hedberg }
300870db83c4SJohan Hedberg 
3009b5ae344dSJohan Hedberg static void bredr_pairing(struct l2cap_chan *chan)
3010b5ae344dSJohan Hedberg {
3011b5ae344dSJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
3012b5ae344dSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
3013b5ae344dSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
3014b5ae344dSJohan Hedberg 	struct smp_cmd_pairing req;
3015b5ae344dSJohan Hedberg 	struct smp_chan *smp;
3016b5ae344dSJohan Hedberg 
3017b5ae344dSJohan Hedberg 	BT_DBG("chan %p", chan);
3018b5ae344dSJohan Hedberg 
3019b5ae344dSJohan Hedberg 	/* Only new pairings are interesting */
3020b5ae344dSJohan Hedberg 	if (!test_bit(HCI_CONN_NEW_LINK_KEY, &hcon->flags))
3021b5ae344dSJohan Hedberg 		return;
3022b5ae344dSJohan Hedberg 
3023b5ae344dSJohan Hedberg 	/* Don't bother if we're not encrypted */
3024b5ae344dSJohan Hedberg 	if (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags))
3025b5ae344dSJohan Hedberg 		return;
3026b5ae344dSJohan Hedberg 
3027b5ae344dSJohan Hedberg 	/* Only master may initiate SMP over BR/EDR */
3028b5ae344dSJohan Hedberg 	if (hcon->role != HCI_ROLE_MASTER)
3029b5ae344dSJohan Hedberg 		return;
3030b5ae344dSJohan Hedberg 
3031b5ae344dSJohan Hedberg 	/* Secure Connections support must be enabled */
3032d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_SC_ENABLED))
3033b5ae344dSJohan Hedberg 		return;
3034b5ae344dSJohan Hedberg 
3035b5ae344dSJohan Hedberg 	/* BR/EDR must use Secure Connections for SMP */
3036b5ae344dSJohan Hedberg 	if (!test_bit(HCI_CONN_AES_CCM, &hcon->flags) &&
3037b7cb93e5SMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP))
3038b5ae344dSJohan Hedberg 		return;
3039b5ae344dSJohan Hedberg 
3040b5ae344dSJohan Hedberg 	/* If our LE support is not enabled don't do anything */
3041d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED))
3042b5ae344dSJohan Hedberg 		return;
3043b5ae344dSJohan Hedberg 
3044b5ae344dSJohan Hedberg 	/* Don't bother if remote LE support is not enabled */
3045b5ae344dSJohan Hedberg 	if (!lmp_host_le_capable(hcon))
3046b5ae344dSJohan Hedberg 		return;
3047b5ae344dSJohan Hedberg 
3048b5ae344dSJohan Hedberg 	/* Remote must support SMP fixed chan for BR/EDR */
3049b5ae344dSJohan Hedberg 	if (!(conn->remote_fixed_chan & L2CAP_FC_SMP_BREDR))
3050b5ae344dSJohan Hedberg 		return;
3051b5ae344dSJohan Hedberg 
3052b5ae344dSJohan Hedberg 	/* Don't bother if SMP is already ongoing */
3053b5ae344dSJohan Hedberg 	if (chan->data)
3054b5ae344dSJohan Hedberg 		return;
3055b5ae344dSJohan Hedberg 
3056b5ae344dSJohan Hedberg 	smp = smp_chan_create(conn);
3057b5ae344dSJohan Hedberg 	if (!smp) {
30582064ee33SMarcel Holtmann 		bt_dev_err(hdev, "unable to create SMP context for BR/EDR");
3059b5ae344dSJohan Hedberg 		return;
3060b5ae344dSJohan Hedberg 	}
3061b5ae344dSJohan Hedberg 
3062b5ae344dSJohan Hedberg 	set_bit(SMP_FLAG_SC, &smp->flags);
3063b5ae344dSJohan Hedberg 
3064b5ae344dSJohan Hedberg 	BT_DBG("%s starting SMP over BR/EDR", hdev->name);
3065b5ae344dSJohan Hedberg 
3066b5ae344dSJohan Hedberg 	/* Prepare and send the BR/EDR SMP Pairing Request */
3067b5ae344dSJohan Hedberg 	build_bredr_pairing_cmd(smp, &req, NULL);
3068b5ae344dSJohan Hedberg 
3069b5ae344dSJohan Hedberg 	smp->preq[0] = SMP_CMD_PAIRING_REQ;
3070b5ae344dSJohan Hedberg 	memcpy(&smp->preq[1], &req, sizeof(req));
3071b5ae344dSJohan Hedberg 
3072b5ae344dSJohan Hedberg 	smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(req), &req);
3073b5ae344dSJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP);
3074b5ae344dSJohan Hedberg }
3075b5ae344dSJohan Hedberg 
307644f1a7abSJohan Hedberg static void smp_resume_cb(struct l2cap_chan *chan)
307744f1a7abSJohan Hedberg {
3078b68fda68SJohan Hedberg 	struct smp_chan *smp = chan->data;
307944f1a7abSJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
308044f1a7abSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
308144f1a7abSJohan Hedberg 
308244f1a7abSJohan Hedberg 	BT_DBG("chan %p", chan);
308344f1a7abSJohan Hedberg 
3084b5ae344dSJohan Hedberg 	if (hcon->type == ACL_LINK) {
3085b5ae344dSJohan Hedberg 		bredr_pairing(chan);
3086ef8efe4bSJohan Hedberg 		return;
3087b5ae344dSJohan Hedberg 	}
3088ef8efe4bSJohan Hedberg 
308986d1407cSJohan Hedberg 	if (!smp)
309086d1407cSJohan Hedberg 		return;
3091b68fda68SJohan Hedberg 
309284bc0db5SJohan Hedberg 	if (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags))
309384bc0db5SJohan Hedberg 		return;
309484bc0db5SJohan Hedberg 
3095b68fda68SJohan Hedberg 	cancel_delayed_work(&smp->security_timer);
309686d1407cSJohan Hedberg 
3097d6268e86SJohan Hedberg 	smp_distribute_keys(smp);
309844f1a7abSJohan Hedberg }
309944f1a7abSJohan Hedberg 
310070db83c4SJohan Hedberg static void smp_ready_cb(struct l2cap_chan *chan)
310170db83c4SJohan Hedberg {
310270db83c4SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
3103b5ae344dSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
310470db83c4SJohan Hedberg 
310570db83c4SJohan Hedberg 	BT_DBG("chan %p", chan);
310670db83c4SJohan Hedberg 
31077883746bSJohan Hedberg 	/* No need to call l2cap_chan_hold() here since we already own
31087883746bSJohan Hedberg 	 * the reference taken in smp_new_conn_cb(). This is just the
31097883746bSJohan Hedberg 	 * first time that we tie it to a specific pointer. The code in
31107883746bSJohan Hedberg 	 * l2cap_core.c ensures that there's no risk this function wont
31117883746bSJohan Hedberg 	 * get called if smp_new_conn_cb was previously called.
31127883746bSJohan Hedberg 	 */
311370db83c4SJohan Hedberg 	conn->smp = chan;
3114b5ae344dSJohan Hedberg 
3115b5ae344dSJohan Hedberg 	if (hcon->type == ACL_LINK && test_bit(HCI_CONN_ENCRYPT, &hcon->flags))
3116b5ae344dSJohan Hedberg 		bredr_pairing(chan);
311770db83c4SJohan Hedberg }
311870db83c4SJohan Hedberg 
31194befb867SJohan Hedberg static int smp_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
31204befb867SJohan Hedberg {
31214befb867SJohan Hedberg 	int err;
31224befb867SJohan Hedberg 
31234befb867SJohan Hedberg 	BT_DBG("chan %p", chan);
31244befb867SJohan Hedberg 
31254befb867SJohan Hedberg 	err = smp_sig_channel(chan, skb);
31264befb867SJohan Hedberg 	if (err) {
3127b68fda68SJohan Hedberg 		struct smp_chan *smp = chan->data;
31284befb867SJohan Hedberg 
3129b68fda68SJohan Hedberg 		if (smp)
3130b68fda68SJohan Hedberg 			cancel_delayed_work_sync(&smp->security_timer);
31314befb867SJohan Hedberg 
31321e91c29eSJohan Hedberg 		hci_disconnect(chan->conn->hcon, HCI_ERROR_AUTH_FAILURE);
31334befb867SJohan Hedberg 	}
31344befb867SJohan Hedberg 
31354befb867SJohan Hedberg 	return err;
31364befb867SJohan Hedberg }
31374befb867SJohan Hedberg 
313870db83c4SJohan Hedberg static struct sk_buff *smp_alloc_skb_cb(struct l2cap_chan *chan,
313970db83c4SJohan Hedberg 					unsigned long hdr_len,
314070db83c4SJohan Hedberg 					unsigned long len, int nb)
314170db83c4SJohan Hedberg {
314270db83c4SJohan Hedberg 	struct sk_buff *skb;
314370db83c4SJohan Hedberg 
314470db83c4SJohan Hedberg 	skb = bt_skb_alloc(hdr_len + len, GFP_KERNEL);
314570db83c4SJohan Hedberg 	if (!skb)
314670db83c4SJohan Hedberg 		return ERR_PTR(-ENOMEM);
314770db83c4SJohan Hedberg 
314870db83c4SJohan Hedberg 	skb->priority = HCI_PRIO_MAX;
3149a4368ff3SJohan Hedberg 	bt_cb(skb)->l2cap.chan = chan;
315070db83c4SJohan Hedberg 
315170db83c4SJohan Hedberg 	return skb;
315270db83c4SJohan Hedberg }
315370db83c4SJohan Hedberg 
315470db83c4SJohan Hedberg static const struct l2cap_ops smp_chan_ops = {
315570db83c4SJohan Hedberg 	.name			= "Security Manager",
315670db83c4SJohan Hedberg 	.ready			= smp_ready_cb,
31575d88cc73SJohan Hedberg 	.recv			= smp_recv_cb,
315870db83c4SJohan Hedberg 	.alloc_skb		= smp_alloc_skb_cb,
315970db83c4SJohan Hedberg 	.teardown		= smp_teardown_cb,
316044f1a7abSJohan Hedberg 	.resume			= smp_resume_cb,
316170db83c4SJohan Hedberg 
316270db83c4SJohan Hedberg 	.new_connection		= l2cap_chan_no_new_connection,
316370db83c4SJohan Hedberg 	.state_change		= l2cap_chan_no_state_change,
316470db83c4SJohan Hedberg 	.close			= l2cap_chan_no_close,
316570db83c4SJohan Hedberg 	.defer			= l2cap_chan_no_defer,
316670db83c4SJohan Hedberg 	.suspend		= l2cap_chan_no_suspend,
316770db83c4SJohan Hedberg 	.set_shutdown		= l2cap_chan_no_set_shutdown,
316870db83c4SJohan Hedberg 	.get_sndtimeo		= l2cap_chan_no_get_sndtimeo,
316970db83c4SJohan Hedberg };
317070db83c4SJohan Hedberg 
317170db83c4SJohan Hedberg static inline struct l2cap_chan *smp_new_conn_cb(struct l2cap_chan *pchan)
317270db83c4SJohan Hedberg {
317370db83c4SJohan Hedberg 	struct l2cap_chan *chan;
317470db83c4SJohan Hedberg 
317570db83c4SJohan Hedberg 	BT_DBG("pchan %p", pchan);
317670db83c4SJohan Hedberg 
317770db83c4SJohan Hedberg 	chan = l2cap_chan_create();
317870db83c4SJohan Hedberg 	if (!chan)
317970db83c4SJohan Hedberg 		return NULL;
318070db83c4SJohan Hedberg 
318170db83c4SJohan Hedberg 	chan->chan_type	= pchan->chan_type;
318270db83c4SJohan Hedberg 	chan->ops	= &smp_chan_ops;
318370db83c4SJohan Hedberg 	chan->scid	= pchan->scid;
318470db83c4SJohan Hedberg 	chan->dcid	= chan->scid;
318570db83c4SJohan Hedberg 	chan->imtu	= pchan->imtu;
318670db83c4SJohan Hedberg 	chan->omtu	= pchan->omtu;
318770db83c4SJohan Hedberg 	chan->mode	= pchan->mode;
318870db83c4SJohan Hedberg 
3189abe84903SJohan Hedberg 	/* Other L2CAP channels may request SMP routines in order to
3190abe84903SJohan Hedberg 	 * change the security level. This means that the SMP channel
3191abe84903SJohan Hedberg 	 * lock must be considered in its own category to avoid lockdep
3192abe84903SJohan Hedberg 	 * warnings.
3193abe84903SJohan Hedberg 	 */
3194abe84903SJohan Hedberg 	atomic_set(&chan->nesting, L2CAP_NESTING_SMP);
3195abe84903SJohan Hedberg 
319670db83c4SJohan Hedberg 	BT_DBG("created chan %p", chan);
319770db83c4SJohan Hedberg 
319870db83c4SJohan Hedberg 	return chan;
319970db83c4SJohan Hedberg }
320070db83c4SJohan Hedberg 
320170db83c4SJohan Hedberg static const struct l2cap_ops smp_root_chan_ops = {
320270db83c4SJohan Hedberg 	.name			= "Security Manager Root",
320370db83c4SJohan Hedberg 	.new_connection		= smp_new_conn_cb,
320470db83c4SJohan Hedberg 
320570db83c4SJohan Hedberg 	/* None of these are implemented for the root channel */
320670db83c4SJohan Hedberg 	.close			= l2cap_chan_no_close,
320770db83c4SJohan Hedberg 	.alloc_skb		= l2cap_chan_no_alloc_skb,
320870db83c4SJohan Hedberg 	.recv			= l2cap_chan_no_recv,
320970db83c4SJohan Hedberg 	.state_change		= l2cap_chan_no_state_change,
321070db83c4SJohan Hedberg 	.teardown		= l2cap_chan_no_teardown,
321170db83c4SJohan Hedberg 	.ready			= l2cap_chan_no_ready,
321270db83c4SJohan Hedberg 	.defer			= l2cap_chan_no_defer,
321370db83c4SJohan Hedberg 	.suspend		= l2cap_chan_no_suspend,
321470db83c4SJohan Hedberg 	.resume			= l2cap_chan_no_resume,
321570db83c4SJohan Hedberg 	.set_shutdown		= l2cap_chan_no_set_shutdown,
321670db83c4SJohan Hedberg 	.get_sndtimeo		= l2cap_chan_no_get_sndtimeo,
321770db83c4SJohan Hedberg };
321870db83c4SJohan Hedberg 
3219ef8efe4bSJohan Hedberg static struct l2cap_chan *smp_add_cid(struct hci_dev *hdev, u16 cid)
3220711eafe3SJohan Hedberg {
322170db83c4SJohan Hedberg 	struct l2cap_chan *chan;
322288a479d9SMarcel Holtmann 	struct smp_dev *smp;
3223a4770e11SAndy Lutomirski 	struct crypto_cipher *tfm_aes;
322471af2f6bSHerbert Xu 	struct crypto_shash *tfm_cmac;
322547eb2ac8STudor Ambarus 	struct crypto_kpp *tfm_ecdh;
322670db83c4SJohan Hedberg 
3227ef8efe4bSJohan Hedberg 	if (cid == L2CAP_CID_SMP_BREDR) {
322888a479d9SMarcel Holtmann 		smp = NULL;
3229ef8efe4bSJohan Hedberg 		goto create_chan;
3230ef8efe4bSJohan Hedberg 	}
3231711eafe3SJohan Hedberg 
323288a479d9SMarcel Holtmann 	smp = kzalloc(sizeof(*smp), GFP_KERNEL);
323388a479d9SMarcel Holtmann 	if (!smp)
323488a479d9SMarcel Holtmann 		return ERR_PTR(-ENOMEM);
323588a479d9SMarcel Holtmann 
3236a4770e11SAndy Lutomirski 	tfm_aes = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
3237defce9e8SJohan Hedberg 	if (IS_ERR(tfm_aes)) {
3238a4770e11SAndy Lutomirski 		BT_ERR("Unable to create AES crypto context");
323988a479d9SMarcel Holtmann 		kzfree(smp);
3240fe700771SFengguang Wu 		return ERR_CAST(tfm_aes);
3241711eafe3SJohan Hedberg 	}
3242711eafe3SJohan Hedberg 
324371af2f6bSHerbert Xu 	tfm_cmac = crypto_alloc_shash("cmac(aes)", 0, 0);
32446e2dc6d1SMarcel Holtmann 	if (IS_ERR(tfm_cmac)) {
32456e2dc6d1SMarcel Holtmann 		BT_ERR("Unable to create CMAC crypto context");
3246a4770e11SAndy Lutomirski 		crypto_free_cipher(tfm_aes);
32476e2dc6d1SMarcel Holtmann 		kzfree(smp);
32486e2dc6d1SMarcel Holtmann 		return ERR_CAST(tfm_cmac);
32496e2dc6d1SMarcel Holtmann 	}
32506e2dc6d1SMarcel Holtmann 
325147eb2ac8STudor Ambarus 	tfm_ecdh = crypto_alloc_kpp("ecdh", CRYPTO_ALG_INTERNAL, 0);
325247eb2ac8STudor Ambarus 	if (IS_ERR(tfm_ecdh)) {
325347eb2ac8STudor Ambarus 		BT_ERR("Unable to create ECDH crypto context");
325447eb2ac8STudor Ambarus 		crypto_free_shash(tfm_cmac);
325547eb2ac8STudor Ambarus 		crypto_free_cipher(tfm_aes);
325647eb2ac8STudor Ambarus 		kzfree(smp);
325747eb2ac8STudor Ambarus 		return ERR_CAST(tfm_ecdh);
325847eb2ac8STudor Ambarus 	}
325947eb2ac8STudor Ambarus 
326094f14e47SJohan Hedberg 	smp->local_oob = false;
326188a479d9SMarcel Holtmann 	smp->tfm_aes = tfm_aes;
32626e2dc6d1SMarcel Holtmann 	smp->tfm_cmac = tfm_cmac;
326347eb2ac8STudor Ambarus 	smp->tfm_ecdh = tfm_ecdh;
326488a479d9SMarcel Holtmann 
3265ef8efe4bSJohan Hedberg create_chan:
326670db83c4SJohan Hedberg 	chan = l2cap_chan_create();
326770db83c4SJohan Hedberg 	if (!chan) {
326863511f6dSMarcel Holtmann 		if (smp) {
3269a4770e11SAndy Lutomirski 			crypto_free_cipher(smp->tfm_aes);
327071af2f6bSHerbert Xu 			crypto_free_shash(smp->tfm_cmac);
327147eb2ac8STudor Ambarus 			crypto_free_kpp(smp->tfm_ecdh);
327288a479d9SMarcel Holtmann 			kzfree(smp);
327363511f6dSMarcel Holtmann 		}
3274ef8efe4bSJohan Hedberg 		return ERR_PTR(-ENOMEM);
327570db83c4SJohan Hedberg 	}
327670db83c4SJohan Hedberg 
327788a479d9SMarcel Holtmann 	chan->data = smp;
3278defce9e8SJohan Hedberg 
3279ef8efe4bSJohan Hedberg 	l2cap_add_scid(chan, cid);
328070db83c4SJohan Hedberg 
328170db83c4SJohan Hedberg 	l2cap_chan_set_defaults(chan);
328270db83c4SJohan Hedberg 
3283157029baSMarcel Holtmann 	if (cid == L2CAP_CID_SMP) {
328439e3e744SJohan Hedberg 		u8 bdaddr_type;
328539e3e744SJohan Hedberg 
328639e3e744SJohan Hedberg 		hci_copy_identity_address(hdev, &chan->src, &bdaddr_type);
328739e3e744SJohan Hedberg 
328839e3e744SJohan Hedberg 		if (bdaddr_type == ADDR_LE_DEV_PUBLIC)
328970db83c4SJohan Hedberg 			chan->src_type = BDADDR_LE_PUBLIC;
329039e3e744SJohan Hedberg 		else
329139e3e744SJohan Hedberg 			chan->src_type = BDADDR_LE_RANDOM;
3292157029baSMarcel Holtmann 	} else {
3293157029baSMarcel Holtmann 		bacpy(&chan->src, &hdev->bdaddr);
3294ef8efe4bSJohan Hedberg 		chan->src_type = BDADDR_BREDR;
3295157029baSMarcel Holtmann 	}
3296157029baSMarcel Holtmann 
329770db83c4SJohan Hedberg 	chan->state = BT_LISTEN;
329870db83c4SJohan Hedberg 	chan->mode = L2CAP_MODE_BASIC;
329970db83c4SJohan Hedberg 	chan->imtu = L2CAP_DEFAULT_MTU;
330070db83c4SJohan Hedberg 	chan->ops = &smp_root_chan_ops;
330170db83c4SJohan Hedberg 
3302abe84903SJohan Hedberg 	/* Set correct nesting level for a parent/listening channel */
3303abe84903SJohan Hedberg 	atomic_set(&chan->nesting, L2CAP_NESTING_PARENT);
3304abe84903SJohan Hedberg 
3305ef8efe4bSJohan Hedberg 	return chan;
3306711eafe3SJohan Hedberg }
3307711eafe3SJohan Hedberg 
3308ef8efe4bSJohan Hedberg static void smp_del_chan(struct l2cap_chan *chan)
3309711eafe3SJohan Hedberg {
331088a479d9SMarcel Holtmann 	struct smp_dev *smp;
331170db83c4SJohan Hedberg 
3312ef8efe4bSJohan Hedberg 	BT_DBG("chan %p", chan);
3313711eafe3SJohan Hedberg 
331488a479d9SMarcel Holtmann 	smp = chan->data;
331588a479d9SMarcel Holtmann 	if (smp) {
3316defce9e8SJohan Hedberg 		chan->data = NULL;
3317a4770e11SAndy Lutomirski 		crypto_free_cipher(smp->tfm_aes);
331871af2f6bSHerbert Xu 		crypto_free_shash(smp->tfm_cmac);
331947eb2ac8STudor Ambarus 		crypto_free_kpp(smp->tfm_ecdh);
332088a479d9SMarcel Holtmann 		kzfree(smp);
3321711eafe3SJohan Hedberg 	}
332270db83c4SJohan Hedberg 
332370db83c4SJohan Hedberg 	l2cap_chan_put(chan);
3324711eafe3SJohan Hedberg }
3325ef8efe4bSJohan Hedberg 
3326300acfdeSMarcel Holtmann static ssize_t force_bredr_smp_read(struct file *file,
3327300acfdeSMarcel Holtmann 				    char __user *user_buf,
3328300acfdeSMarcel Holtmann 				    size_t count, loff_t *ppos)
3329300acfdeSMarcel Holtmann {
3330300acfdeSMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
3331300acfdeSMarcel Holtmann 	char buf[3];
3332300acfdeSMarcel Holtmann 
3333b7cb93e5SMarcel Holtmann 	buf[0] = hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP) ? 'Y': 'N';
3334300acfdeSMarcel Holtmann 	buf[1] = '\n';
3335300acfdeSMarcel Holtmann 	buf[2] = '\0';
3336300acfdeSMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
3337300acfdeSMarcel Holtmann }
3338300acfdeSMarcel Holtmann 
3339300acfdeSMarcel Holtmann static ssize_t force_bredr_smp_write(struct file *file,
3340300acfdeSMarcel Holtmann 				     const char __user *user_buf,
3341300acfdeSMarcel Holtmann 				     size_t count, loff_t *ppos)
3342300acfdeSMarcel Holtmann {
3343300acfdeSMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
3344300acfdeSMarcel Holtmann 	bool enable;
33453bf5e97dSAndy Shevchenko 	int err;
3346300acfdeSMarcel Holtmann 
33473bf5e97dSAndy Shevchenko 	err = kstrtobool_from_user(user_buf, count, &enable);
33483bf5e97dSAndy Shevchenko 	if (err)
33493bf5e97dSAndy Shevchenko 		return err;
3350300acfdeSMarcel Holtmann 
3351b7cb93e5SMarcel Holtmann 	if (enable == hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP))
3352300acfdeSMarcel Holtmann 		return -EALREADY;
3353300acfdeSMarcel Holtmann 
3354300acfdeSMarcel Holtmann 	if (enable) {
3355300acfdeSMarcel Holtmann 		struct l2cap_chan *chan;
3356300acfdeSMarcel Holtmann 
3357300acfdeSMarcel Holtmann 		chan = smp_add_cid(hdev, L2CAP_CID_SMP_BREDR);
3358300acfdeSMarcel Holtmann 		if (IS_ERR(chan))
3359300acfdeSMarcel Holtmann 			return PTR_ERR(chan);
3360300acfdeSMarcel Holtmann 
3361300acfdeSMarcel Holtmann 		hdev->smp_bredr_data = chan;
3362300acfdeSMarcel Holtmann 	} else {
3363300acfdeSMarcel Holtmann 		struct l2cap_chan *chan;
3364300acfdeSMarcel Holtmann 
3365300acfdeSMarcel Holtmann 		chan = hdev->smp_bredr_data;
3366300acfdeSMarcel Holtmann 		hdev->smp_bredr_data = NULL;
3367300acfdeSMarcel Holtmann 		smp_del_chan(chan);
3368300acfdeSMarcel Holtmann 	}
3369300acfdeSMarcel Holtmann 
3370b7cb93e5SMarcel Holtmann 	hci_dev_change_flag(hdev, HCI_FORCE_BREDR_SMP);
3371300acfdeSMarcel Holtmann 
3372300acfdeSMarcel Holtmann 	return count;
3373300acfdeSMarcel Holtmann }
3374300acfdeSMarcel Holtmann 
3375300acfdeSMarcel Holtmann static const struct file_operations force_bredr_smp_fops = {
3376300acfdeSMarcel Holtmann 	.open		= simple_open,
3377300acfdeSMarcel Holtmann 	.read		= force_bredr_smp_read,
3378300acfdeSMarcel Holtmann 	.write		= force_bredr_smp_write,
3379300acfdeSMarcel Holtmann 	.llseek		= default_llseek,
3380300acfdeSMarcel Holtmann };
3381300acfdeSMarcel Holtmann 
3382b1f663c9SJohan Hedberg static ssize_t le_min_key_size_read(struct file *file,
3383b1f663c9SJohan Hedberg 				     char __user *user_buf,
3384b1f663c9SJohan Hedberg 				     size_t count, loff_t *ppos)
3385b1f663c9SJohan Hedberg {
3386b1f663c9SJohan Hedberg 	struct hci_dev *hdev = file->private_data;
3387b1f663c9SJohan Hedberg 	char buf[4];
3388b1f663c9SJohan Hedberg 
338930d65e08SMatias Karhumaa 	snprintf(buf, sizeof(buf), "%2u\n", hdev->le_min_key_size);
3390b1f663c9SJohan Hedberg 
3391b1f663c9SJohan Hedberg 	return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
3392b1f663c9SJohan Hedberg }
3393b1f663c9SJohan Hedberg 
3394b1f663c9SJohan Hedberg static ssize_t le_min_key_size_write(struct file *file,
3395b1f663c9SJohan Hedberg 				      const char __user *user_buf,
3396b1f663c9SJohan Hedberg 				      size_t count, loff_t *ppos)
3397b1f663c9SJohan Hedberg {
3398b1f663c9SJohan Hedberg 	struct hci_dev *hdev = file->private_data;
3399b1f663c9SJohan Hedberg 	char buf[32];
3400b1f663c9SJohan Hedberg 	size_t buf_size = min(count, (sizeof(buf) - 1));
3401b1f663c9SJohan Hedberg 	u8 key_size;
3402b1f663c9SJohan Hedberg 
3403b1f663c9SJohan Hedberg 	if (copy_from_user(buf, user_buf, buf_size))
3404b1f663c9SJohan Hedberg 		return -EFAULT;
3405b1f663c9SJohan Hedberg 
3406b1f663c9SJohan Hedberg 	buf[buf_size] = '\0';
3407b1f663c9SJohan Hedberg 
3408b1f663c9SJohan Hedberg 	sscanf(buf, "%hhu", &key_size);
3409b1f663c9SJohan Hedberg 
341030d65e08SMatias Karhumaa 	if (key_size > hdev->le_max_key_size ||
3411b1f663c9SJohan Hedberg 	    key_size < SMP_MIN_ENC_KEY_SIZE)
3412b1f663c9SJohan Hedberg 		return -EINVAL;
3413b1f663c9SJohan Hedberg 
341430d65e08SMatias Karhumaa 	hdev->le_min_key_size = key_size;
3415b1f663c9SJohan Hedberg 
3416b1f663c9SJohan Hedberg 	return count;
3417b1f663c9SJohan Hedberg }
3418b1f663c9SJohan Hedberg 
3419b1f663c9SJohan Hedberg static const struct file_operations le_min_key_size_fops = {
3420b1f663c9SJohan Hedberg 	.open		= simple_open,
3421b1f663c9SJohan Hedberg 	.read		= le_min_key_size_read,
3422b1f663c9SJohan Hedberg 	.write		= le_min_key_size_write,
3423b1f663c9SJohan Hedberg 	.llseek		= default_llseek,
3424b1f663c9SJohan Hedberg };
3425b1f663c9SJohan Hedberg 
34262fd36558SJohan Hedberg static ssize_t le_max_key_size_read(struct file *file,
34272fd36558SJohan Hedberg 				     char __user *user_buf,
34282fd36558SJohan Hedberg 				     size_t count, loff_t *ppos)
34292fd36558SJohan Hedberg {
34302fd36558SJohan Hedberg 	struct hci_dev *hdev = file->private_data;
34312fd36558SJohan Hedberg 	char buf[4];
34322fd36558SJohan Hedberg 
343330d65e08SMatias Karhumaa 	snprintf(buf, sizeof(buf), "%2u\n", hdev->le_max_key_size);
34342fd36558SJohan Hedberg 
34352fd36558SJohan Hedberg 	return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
34362fd36558SJohan Hedberg }
34372fd36558SJohan Hedberg 
34382fd36558SJohan Hedberg static ssize_t le_max_key_size_write(struct file *file,
34392fd36558SJohan Hedberg 				      const char __user *user_buf,
34402fd36558SJohan Hedberg 				      size_t count, loff_t *ppos)
34412fd36558SJohan Hedberg {
34422fd36558SJohan Hedberg 	struct hci_dev *hdev = file->private_data;
34432fd36558SJohan Hedberg 	char buf[32];
34442fd36558SJohan Hedberg 	size_t buf_size = min(count, (sizeof(buf) - 1));
34452fd36558SJohan Hedberg 	u8 key_size;
34462fd36558SJohan Hedberg 
34472fd36558SJohan Hedberg 	if (copy_from_user(buf, user_buf, buf_size))
34482fd36558SJohan Hedberg 		return -EFAULT;
34492fd36558SJohan Hedberg 
34502fd36558SJohan Hedberg 	buf[buf_size] = '\0';
34512fd36558SJohan Hedberg 
34522fd36558SJohan Hedberg 	sscanf(buf, "%hhu", &key_size);
34532fd36558SJohan Hedberg 
3454b1f663c9SJohan Hedberg 	if (key_size > SMP_MAX_ENC_KEY_SIZE ||
345530d65e08SMatias Karhumaa 	    key_size < hdev->le_min_key_size)
34562fd36558SJohan Hedberg 		return -EINVAL;
34572fd36558SJohan Hedberg 
345830d65e08SMatias Karhumaa 	hdev->le_max_key_size = key_size;
34592fd36558SJohan Hedberg 
34602fd36558SJohan Hedberg 	return count;
34612fd36558SJohan Hedberg }
34622fd36558SJohan Hedberg 
34632fd36558SJohan Hedberg static const struct file_operations le_max_key_size_fops = {
34642fd36558SJohan Hedberg 	.open		= simple_open,
34652fd36558SJohan Hedberg 	.read		= le_max_key_size_read,
34662fd36558SJohan Hedberg 	.write		= le_max_key_size_write,
34672fd36558SJohan Hedberg 	.llseek		= default_llseek,
34682fd36558SJohan Hedberg };
34692fd36558SJohan Hedberg 
3470ef8efe4bSJohan Hedberg int smp_register(struct hci_dev *hdev)
3471ef8efe4bSJohan Hedberg {
3472ef8efe4bSJohan Hedberg 	struct l2cap_chan *chan;
3473ef8efe4bSJohan Hedberg 
3474ef8efe4bSJohan Hedberg 	BT_DBG("%s", hdev->name);
3475ef8efe4bSJohan Hedberg 
34767e7ec445SMarcel Holtmann 	/* If the controller does not support Low Energy operation, then
34777e7ec445SMarcel Holtmann 	 * there is also no need to register any SMP channel.
34787e7ec445SMarcel Holtmann 	 */
34797e7ec445SMarcel Holtmann 	if (!lmp_le_capable(hdev))
34807e7ec445SMarcel Holtmann 		return 0;
34817e7ec445SMarcel Holtmann 
34822b8df323SMarcel Holtmann 	if (WARN_ON(hdev->smp_data)) {
34832b8df323SMarcel Holtmann 		chan = hdev->smp_data;
34842b8df323SMarcel Holtmann 		hdev->smp_data = NULL;
34852b8df323SMarcel Holtmann 		smp_del_chan(chan);
34862b8df323SMarcel Holtmann 	}
34872b8df323SMarcel Holtmann 
3488ef8efe4bSJohan Hedberg 	chan = smp_add_cid(hdev, L2CAP_CID_SMP);
3489ef8efe4bSJohan Hedberg 	if (IS_ERR(chan))
3490ef8efe4bSJohan Hedberg 		return PTR_ERR(chan);
3491ef8efe4bSJohan Hedberg 
3492ef8efe4bSJohan Hedberg 	hdev->smp_data = chan;
3493ef8efe4bSJohan Hedberg 
3494b1f663c9SJohan Hedberg 	debugfs_create_file("le_min_key_size", 0644, hdev->debugfs, hdev,
3495b1f663c9SJohan Hedberg 			    &le_min_key_size_fops);
34962fd36558SJohan Hedberg 	debugfs_create_file("le_max_key_size", 0644, hdev->debugfs, hdev,
34972fd36558SJohan Hedberg 			    &le_max_key_size_fops);
34982fd36558SJohan Hedberg 
3499300acfdeSMarcel Holtmann 	/* If the controller does not support BR/EDR Secure Connections
3500300acfdeSMarcel Holtmann 	 * feature, then the BR/EDR SMP channel shall not be present.
3501300acfdeSMarcel Holtmann 	 *
3502300acfdeSMarcel Holtmann 	 * To test this with Bluetooth 4.0 controllers, create a debugfs
3503300acfdeSMarcel Holtmann 	 * switch that allows forcing BR/EDR SMP support and accepting
3504300acfdeSMarcel Holtmann 	 * cross-transport pairing on non-AES encrypted connections.
3505300acfdeSMarcel Holtmann 	 */
3506300acfdeSMarcel Holtmann 	if (!lmp_sc_capable(hdev)) {
3507300acfdeSMarcel Holtmann 		debugfs_create_file("force_bredr_smp", 0644, hdev->debugfs,
3508300acfdeSMarcel Holtmann 				    hdev, &force_bredr_smp_fops);
350983ebb9ecSSzymon Janc 
351083ebb9ecSSzymon Janc 		/* Flag can be already set here (due to power toggle) */
351183ebb9ecSSzymon Janc 		if (!hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP))
3512ef8efe4bSJohan Hedberg 			return 0;
3513300acfdeSMarcel Holtmann 	}
3514ef8efe4bSJohan Hedberg 
35152b8df323SMarcel Holtmann 	if (WARN_ON(hdev->smp_bredr_data)) {
35162b8df323SMarcel Holtmann 		chan = hdev->smp_bredr_data;
35172b8df323SMarcel Holtmann 		hdev->smp_bredr_data = NULL;
35182b8df323SMarcel Holtmann 		smp_del_chan(chan);
35192b8df323SMarcel Holtmann 	}
35202b8df323SMarcel Holtmann 
3521ef8efe4bSJohan Hedberg 	chan = smp_add_cid(hdev, L2CAP_CID_SMP_BREDR);
3522ef8efe4bSJohan Hedberg 	if (IS_ERR(chan)) {
3523ef8efe4bSJohan Hedberg 		int err = PTR_ERR(chan);
3524ef8efe4bSJohan Hedberg 		chan = hdev->smp_data;
3525ef8efe4bSJohan Hedberg 		hdev->smp_data = NULL;
3526ef8efe4bSJohan Hedberg 		smp_del_chan(chan);
3527ef8efe4bSJohan Hedberg 		return err;
3528ef8efe4bSJohan Hedberg 	}
3529ef8efe4bSJohan Hedberg 
3530ef8efe4bSJohan Hedberg 	hdev->smp_bredr_data = chan;
3531ef8efe4bSJohan Hedberg 
3532ef8efe4bSJohan Hedberg 	return 0;
3533ef8efe4bSJohan Hedberg }
3534ef8efe4bSJohan Hedberg 
3535ef8efe4bSJohan Hedberg void smp_unregister(struct hci_dev *hdev)
3536ef8efe4bSJohan Hedberg {
3537ef8efe4bSJohan Hedberg 	struct l2cap_chan *chan;
3538ef8efe4bSJohan Hedberg 
3539ef8efe4bSJohan Hedberg 	if (hdev->smp_bredr_data) {
3540ef8efe4bSJohan Hedberg 		chan = hdev->smp_bredr_data;
3541ef8efe4bSJohan Hedberg 		hdev->smp_bredr_data = NULL;
3542ef8efe4bSJohan Hedberg 		smp_del_chan(chan);
3543ef8efe4bSJohan Hedberg 	}
3544ef8efe4bSJohan Hedberg 
3545ef8efe4bSJohan Hedberg 	if (hdev->smp_data) {
3546ef8efe4bSJohan Hedberg 		chan = hdev->smp_data;
3547ef8efe4bSJohan Hedberg 		hdev->smp_data = NULL;
3548ef8efe4bSJohan Hedberg 		smp_del_chan(chan);
3549ef8efe4bSJohan Hedberg 	}
3550ef8efe4bSJohan Hedberg }
35510a2b0f04SJohan Hedberg 
35520a2b0f04SJohan Hedberg #if IS_ENABLED(CONFIG_BT_SELFTEST_SMP)
35530a2b0f04SJohan Hedberg 
355447eb2ac8STudor Ambarus static int __init test_debug_key(struct crypto_kpp *tfm_ecdh)
355571653eb6SMarcel Holtmann {
3556c0153b0bSTudor Ambarus 	u8 pk[64];
3557a2976416STudor Ambarus 	int err;
355871653eb6SMarcel Holtmann 
3559c0153b0bSTudor Ambarus 	err = set_ecdh_privkey(tfm_ecdh, debug_sk);
3560a2976416STudor Ambarus 	if (err)
3561a2976416STudor Ambarus 		return err;
356271653eb6SMarcel Holtmann 
3563c0153b0bSTudor Ambarus 	err = generate_ecdh_public_key(tfm_ecdh, pk);
3564c0153b0bSTudor Ambarus 	if (err)
3565c0153b0bSTudor Ambarus 		return err;
356671653eb6SMarcel Holtmann 
3567329d8230SJason A. Donenfeld 	if (crypto_memneq(pk, debug_pk, 64))
356871653eb6SMarcel Holtmann 		return -EINVAL;
356971653eb6SMarcel Holtmann 
357071653eb6SMarcel Holtmann 	return 0;
357171653eb6SMarcel Holtmann }
357271653eb6SMarcel Holtmann 
3573a4770e11SAndy Lutomirski static int __init test_ah(struct crypto_cipher *tfm_aes)
3574cfc4198eSJohan Hedberg {
3575cfc4198eSJohan Hedberg 	const u8 irk[16] = {
3576cfc4198eSJohan Hedberg 			0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34,
3577cfc4198eSJohan Hedberg 			0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec };
3578cfc4198eSJohan Hedberg 	const u8 r[3] = { 0x94, 0x81, 0x70 };
3579cfc4198eSJohan Hedberg 	const u8 exp[3] = { 0xaa, 0xfb, 0x0d };
3580cfc4198eSJohan Hedberg 	u8 res[3];
3581cfc4198eSJohan Hedberg 	int err;
3582cfc4198eSJohan Hedberg 
3583cfc4198eSJohan Hedberg 	err = smp_ah(tfm_aes, irk, r, res);
3584cfc4198eSJohan Hedberg 	if (err)
3585cfc4198eSJohan Hedberg 		return err;
3586cfc4198eSJohan Hedberg 
3587329d8230SJason A. Donenfeld 	if (crypto_memneq(res, exp, 3))
3588cfc4198eSJohan Hedberg 		return -EINVAL;
3589cfc4198eSJohan Hedberg 
3590cfc4198eSJohan Hedberg 	return 0;
3591cfc4198eSJohan Hedberg }
3592cfc4198eSJohan Hedberg 
3593a4770e11SAndy Lutomirski static int __init test_c1(struct crypto_cipher *tfm_aes)
3594cfc4198eSJohan Hedberg {
3595cfc4198eSJohan Hedberg 	const u8 k[16] = {
3596cfc4198eSJohan Hedberg 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3597cfc4198eSJohan Hedberg 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
3598cfc4198eSJohan Hedberg 	const u8 r[16] = {
3599cfc4198eSJohan Hedberg 			0xe0, 0x2e, 0x70, 0xc6, 0x4e, 0x27, 0x88, 0x63,
3600cfc4198eSJohan Hedberg 			0x0e, 0x6f, 0xad, 0x56, 0x21, 0xd5, 0x83, 0x57 };
3601cfc4198eSJohan Hedberg 	const u8 preq[7] = { 0x01, 0x01, 0x00, 0x00, 0x10, 0x07, 0x07 };
3602cfc4198eSJohan Hedberg 	const u8 pres[7] = { 0x02, 0x03, 0x00, 0x00, 0x08, 0x00, 0x05 };
3603cfc4198eSJohan Hedberg 	const u8 _iat = 0x01;
3604cfc4198eSJohan Hedberg 	const u8 _rat = 0x00;
3605cfc4198eSJohan Hedberg 	const bdaddr_t ra = { { 0xb6, 0xb5, 0xb4, 0xb3, 0xb2, 0xb1 } };
3606cfc4198eSJohan Hedberg 	const bdaddr_t ia = { { 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1 } };
3607cfc4198eSJohan Hedberg 	const u8 exp[16] = {
3608cfc4198eSJohan Hedberg 			0x86, 0x3b, 0xf1, 0xbe, 0xc5, 0x4d, 0xa7, 0xd2,
3609cfc4198eSJohan Hedberg 			0xea, 0x88, 0x89, 0x87, 0xef, 0x3f, 0x1e, 0x1e };
3610cfc4198eSJohan Hedberg 	u8 res[16];
3611cfc4198eSJohan Hedberg 	int err;
3612cfc4198eSJohan Hedberg 
3613cfc4198eSJohan Hedberg 	err = smp_c1(tfm_aes, k, r, preq, pres, _iat, &ia, _rat, &ra, res);
3614cfc4198eSJohan Hedberg 	if (err)
3615cfc4198eSJohan Hedberg 		return err;
3616cfc4198eSJohan Hedberg 
3617329d8230SJason A. Donenfeld 	if (crypto_memneq(res, exp, 16))
3618cfc4198eSJohan Hedberg 		return -EINVAL;
3619cfc4198eSJohan Hedberg 
3620cfc4198eSJohan Hedberg 	return 0;
3621cfc4198eSJohan Hedberg }
3622cfc4198eSJohan Hedberg 
3623a4770e11SAndy Lutomirski static int __init test_s1(struct crypto_cipher *tfm_aes)
3624cfc4198eSJohan Hedberg {
3625cfc4198eSJohan Hedberg 	const u8 k[16] = {
3626cfc4198eSJohan Hedberg 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3627cfc4198eSJohan Hedberg 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
3628cfc4198eSJohan Hedberg 	const u8 r1[16] = {
3629cfc4198eSJohan Hedberg 			0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 };
3630cfc4198eSJohan Hedberg 	const u8 r2[16] = {
3631cfc4198eSJohan Hedberg 			0x00, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99 };
3632cfc4198eSJohan Hedberg 	const u8 exp[16] = {
3633cfc4198eSJohan Hedberg 			0x62, 0xa0, 0x6d, 0x79, 0xae, 0x16, 0x42, 0x5b,
3634cfc4198eSJohan Hedberg 			0x9b, 0xf4, 0xb0, 0xe8, 0xf0, 0xe1, 0x1f, 0x9a };
3635cfc4198eSJohan Hedberg 	u8 res[16];
3636cfc4198eSJohan Hedberg 	int err;
3637cfc4198eSJohan Hedberg 
3638cfc4198eSJohan Hedberg 	err = smp_s1(tfm_aes, k, r1, r2, res);
3639cfc4198eSJohan Hedberg 	if (err)
3640cfc4198eSJohan Hedberg 		return err;
3641cfc4198eSJohan Hedberg 
3642329d8230SJason A. Donenfeld 	if (crypto_memneq(res, exp, 16))
3643cfc4198eSJohan Hedberg 		return -EINVAL;
3644cfc4198eSJohan Hedberg 
3645cfc4198eSJohan Hedberg 	return 0;
3646cfc4198eSJohan Hedberg }
3647cfc4198eSJohan Hedberg 
364871af2f6bSHerbert Xu static int __init test_f4(struct crypto_shash *tfm_cmac)
3649fb2969a3SJohan Hedberg {
3650fb2969a3SJohan Hedberg 	const u8 u[32] = {
3651fb2969a3SJohan Hedberg 			0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc,
3652fb2969a3SJohan Hedberg 			0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef,
3653fb2969a3SJohan Hedberg 			0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e,
3654fb2969a3SJohan Hedberg 			0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20 };
3655fb2969a3SJohan Hedberg 	const u8 v[32] = {
3656fb2969a3SJohan Hedberg 			0xfd, 0xc5, 0x7f, 0xf4, 0x49, 0xdd, 0x4f, 0x6b,
3657fb2969a3SJohan Hedberg 			0xfb, 0x7c, 0x9d, 0xf1, 0xc2, 0x9a, 0xcb, 0x59,
3658fb2969a3SJohan Hedberg 			0x2a, 0xe7, 0xd4, 0xee, 0xfb, 0xfc, 0x0a, 0x90,
3659fb2969a3SJohan Hedberg 			0x9a, 0xbb, 0xf6, 0x32, 0x3d, 0x8b, 0x18, 0x55 };
3660fb2969a3SJohan Hedberg 	const u8 x[16] = {
3661fb2969a3SJohan Hedberg 			0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff,
3662fb2969a3SJohan Hedberg 			0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 };
3663fb2969a3SJohan Hedberg 	const u8 z = 0x00;
3664fb2969a3SJohan Hedberg 	const u8 exp[16] = {
3665fb2969a3SJohan Hedberg 			0x2d, 0x87, 0x74, 0xa9, 0xbe, 0xa1, 0xed, 0xf1,
3666fb2969a3SJohan Hedberg 			0x1c, 0xbd, 0xa9, 0x07, 0xf1, 0x16, 0xc9, 0xf2 };
3667fb2969a3SJohan Hedberg 	u8 res[16];
3668fb2969a3SJohan Hedberg 	int err;
3669fb2969a3SJohan Hedberg 
3670fb2969a3SJohan Hedberg 	err = smp_f4(tfm_cmac, u, v, x, z, res);
3671fb2969a3SJohan Hedberg 	if (err)
3672fb2969a3SJohan Hedberg 		return err;
3673fb2969a3SJohan Hedberg 
3674329d8230SJason A. Donenfeld 	if (crypto_memneq(res, exp, 16))
3675fb2969a3SJohan Hedberg 		return -EINVAL;
3676fb2969a3SJohan Hedberg 
3677fb2969a3SJohan Hedberg 	return 0;
3678fb2969a3SJohan Hedberg }
3679fb2969a3SJohan Hedberg 
368071af2f6bSHerbert Xu static int __init test_f5(struct crypto_shash *tfm_cmac)
3681fb2969a3SJohan Hedberg {
3682fb2969a3SJohan Hedberg 	const u8 w[32] = {
3683fb2969a3SJohan Hedberg 			0x98, 0xa6, 0xbf, 0x73, 0xf3, 0x34, 0x8d, 0x86,
3684fb2969a3SJohan Hedberg 			0xf1, 0x66, 0xf8, 0xb4, 0x13, 0x6b, 0x79, 0x99,
3685fb2969a3SJohan Hedberg 			0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34,
3686fb2969a3SJohan Hedberg 			0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec };
3687fb2969a3SJohan Hedberg 	const u8 n1[16] = {
3688fb2969a3SJohan Hedberg 			0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff,
3689fb2969a3SJohan Hedberg 			0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 };
3690fb2969a3SJohan Hedberg 	const u8 n2[16] = {
3691fb2969a3SJohan Hedberg 			0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21,
3692fb2969a3SJohan Hedberg 			0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6 };
3693fb2969a3SJohan Hedberg 	const u8 a1[7] = { 0xce, 0xbf, 0x37, 0x37, 0x12, 0x56, 0x00 };
3694fb2969a3SJohan Hedberg 	const u8 a2[7] = { 0xc1, 0xcf, 0x2d, 0x70, 0x13, 0xa7, 0x00 };
3695fb2969a3SJohan Hedberg 	const u8 exp_ltk[16] = {
3696fb2969a3SJohan Hedberg 			0x38, 0x0a, 0x75, 0x94, 0xb5, 0x22, 0x05, 0x98,
3697fb2969a3SJohan Hedberg 			0x23, 0xcd, 0xd7, 0x69, 0x11, 0x79, 0x86, 0x69 };
3698fb2969a3SJohan Hedberg 	const u8 exp_mackey[16] = {
3699fb2969a3SJohan Hedberg 			0x20, 0x6e, 0x63, 0xce, 0x20, 0x6a, 0x3f, 0xfd,
3700fb2969a3SJohan Hedberg 			0x02, 0x4a, 0x08, 0xa1, 0x76, 0xf1, 0x65, 0x29 };
3701fb2969a3SJohan Hedberg 	u8 mackey[16], ltk[16];
3702fb2969a3SJohan Hedberg 	int err;
3703fb2969a3SJohan Hedberg 
3704fb2969a3SJohan Hedberg 	err = smp_f5(tfm_cmac, w, n1, n2, a1, a2, mackey, ltk);
3705fb2969a3SJohan Hedberg 	if (err)
3706fb2969a3SJohan Hedberg 		return err;
3707fb2969a3SJohan Hedberg 
3708329d8230SJason A. Donenfeld 	if (crypto_memneq(mackey, exp_mackey, 16))
3709fb2969a3SJohan Hedberg 		return -EINVAL;
3710fb2969a3SJohan Hedberg 
3711329d8230SJason A. Donenfeld 	if (crypto_memneq(ltk, exp_ltk, 16))
3712fb2969a3SJohan Hedberg 		return -EINVAL;
3713fb2969a3SJohan Hedberg 
3714fb2969a3SJohan Hedberg 	return 0;
3715fb2969a3SJohan Hedberg }
3716fb2969a3SJohan Hedberg 
371771af2f6bSHerbert Xu static int __init test_f6(struct crypto_shash *tfm_cmac)
3718fb2969a3SJohan Hedberg {
3719fb2969a3SJohan Hedberg 	const u8 w[16] = {
3720fb2969a3SJohan Hedberg 			0x20, 0x6e, 0x63, 0xce, 0x20, 0x6a, 0x3f, 0xfd,
3721fb2969a3SJohan Hedberg 			0x02, 0x4a, 0x08, 0xa1, 0x76, 0xf1, 0x65, 0x29 };
3722fb2969a3SJohan Hedberg 	const u8 n1[16] = {
3723fb2969a3SJohan Hedberg 			0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff,
3724fb2969a3SJohan Hedberg 			0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 };
3725fb2969a3SJohan Hedberg 	const u8 n2[16] = {
3726fb2969a3SJohan Hedberg 			0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21,
3727fb2969a3SJohan Hedberg 			0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6 };
3728fb2969a3SJohan Hedberg 	const u8 r[16] = {
3729fb2969a3SJohan Hedberg 			0xc8, 0x0f, 0x2d, 0x0c, 0xd2, 0x42, 0xda, 0x08,
3730fb2969a3SJohan Hedberg 			0x54, 0xbb, 0x53, 0xb4, 0x3b, 0x34, 0xa3, 0x12 };
3731fb2969a3SJohan Hedberg 	const u8 io_cap[3] = { 0x02, 0x01, 0x01 };
3732fb2969a3SJohan Hedberg 	const u8 a1[7] = { 0xce, 0xbf, 0x37, 0x37, 0x12, 0x56, 0x00 };
3733fb2969a3SJohan Hedberg 	const u8 a2[7] = { 0xc1, 0xcf, 0x2d, 0x70, 0x13, 0xa7, 0x00 };
3734fb2969a3SJohan Hedberg 	const u8 exp[16] = {
3735fb2969a3SJohan Hedberg 			0x61, 0x8f, 0x95, 0xda, 0x09, 0x0b, 0x6c, 0xd2,
3736fb2969a3SJohan Hedberg 			0xc5, 0xe8, 0xd0, 0x9c, 0x98, 0x73, 0xc4, 0xe3 };
3737fb2969a3SJohan Hedberg 	u8 res[16];
3738fb2969a3SJohan Hedberg 	int err;
3739fb2969a3SJohan Hedberg 
3740fb2969a3SJohan Hedberg 	err = smp_f6(tfm_cmac, w, n1, n2, r, io_cap, a1, a2, res);
3741fb2969a3SJohan Hedberg 	if (err)
3742fb2969a3SJohan Hedberg 		return err;
3743fb2969a3SJohan Hedberg 
3744329d8230SJason A. Donenfeld 	if (crypto_memneq(res, exp, 16))
3745fb2969a3SJohan Hedberg 		return -EINVAL;
3746fb2969a3SJohan Hedberg 
3747fb2969a3SJohan Hedberg 	return 0;
3748fb2969a3SJohan Hedberg }
3749fb2969a3SJohan Hedberg 
375071af2f6bSHerbert Xu static int __init test_g2(struct crypto_shash *tfm_cmac)
3751fb2969a3SJohan Hedberg {
3752fb2969a3SJohan Hedberg 	const u8 u[32] = {
3753fb2969a3SJohan Hedberg 			0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc,
3754fb2969a3SJohan Hedberg 			0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef,
3755fb2969a3SJohan Hedberg 			0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e,
3756fb2969a3SJohan Hedberg 			0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20 };
3757fb2969a3SJohan Hedberg 	const u8 v[32] = {
3758fb2969a3SJohan Hedberg 			0xfd, 0xc5, 0x7f, 0xf4, 0x49, 0xdd, 0x4f, 0x6b,
3759fb2969a3SJohan Hedberg 			0xfb, 0x7c, 0x9d, 0xf1, 0xc2, 0x9a, 0xcb, 0x59,
3760fb2969a3SJohan Hedberg 			0x2a, 0xe7, 0xd4, 0xee, 0xfb, 0xfc, 0x0a, 0x90,
3761fb2969a3SJohan Hedberg 			0x9a, 0xbb, 0xf6, 0x32, 0x3d, 0x8b, 0x18, 0x55 };
3762fb2969a3SJohan Hedberg 	const u8 x[16] = {
3763fb2969a3SJohan Hedberg 			0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff,
3764fb2969a3SJohan Hedberg 			0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 };
3765fb2969a3SJohan Hedberg 	const u8 y[16] = {
3766fb2969a3SJohan Hedberg 			0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21,
3767fb2969a3SJohan Hedberg 			0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6 };
3768fb2969a3SJohan Hedberg 	const u32 exp_val = 0x2f9ed5ba % 1000000;
3769fb2969a3SJohan Hedberg 	u32 val;
3770fb2969a3SJohan Hedberg 	int err;
3771fb2969a3SJohan Hedberg 
3772fb2969a3SJohan Hedberg 	err = smp_g2(tfm_cmac, u, v, x, y, &val);
3773fb2969a3SJohan Hedberg 	if (err)
3774fb2969a3SJohan Hedberg 		return err;
3775fb2969a3SJohan Hedberg 
3776fb2969a3SJohan Hedberg 	if (val != exp_val)
3777fb2969a3SJohan Hedberg 		return -EINVAL;
3778fb2969a3SJohan Hedberg 
3779fb2969a3SJohan Hedberg 	return 0;
3780fb2969a3SJohan Hedberg }
3781fb2969a3SJohan Hedberg 
378271af2f6bSHerbert Xu static int __init test_h6(struct crypto_shash *tfm_cmac)
3783fb2969a3SJohan Hedberg {
3784fb2969a3SJohan Hedberg 	const u8 w[16] = {
3785fb2969a3SJohan Hedberg 			0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34,
3786fb2969a3SJohan Hedberg 			0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec };
3787fb2969a3SJohan Hedberg 	const u8 key_id[4] = { 0x72, 0x62, 0x65, 0x6c };
3788fb2969a3SJohan Hedberg 	const u8 exp[16] = {
3789fb2969a3SJohan Hedberg 			0x99, 0x63, 0xb1, 0x80, 0xe2, 0xa9, 0xd3, 0xe8,
3790fb2969a3SJohan Hedberg 			0x1c, 0xc9, 0x6d, 0xe7, 0x02, 0xe1, 0x9a, 0x2d };
3791fb2969a3SJohan Hedberg 	u8 res[16];
3792fb2969a3SJohan Hedberg 	int err;
3793fb2969a3SJohan Hedberg 
3794fb2969a3SJohan Hedberg 	err = smp_h6(tfm_cmac, w, key_id, res);
3795fb2969a3SJohan Hedberg 	if (err)
3796fb2969a3SJohan Hedberg 		return err;
3797fb2969a3SJohan Hedberg 
3798329d8230SJason A. Donenfeld 	if (crypto_memneq(res, exp, 16))
3799fb2969a3SJohan Hedberg 		return -EINVAL;
3800fb2969a3SJohan Hedberg 
3801fb2969a3SJohan Hedberg 	return 0;
3802fb2969a3SJohan Hedberg }
3803fb2969a3SJohan Hedberg 
380464dd374eSMarcel Holtmann static char test_smp_buffer[32];
380564dd374eSMarcel Holtmann 
380664dd374eSMarcel Holtmann static ssize_t test_smp_read(struct file *file, char __user *user_buf,
380764dd374eSMarcel Holtmann 			     size_t count, loff_t *ppos)
380864dd374eSMarcel Holtmann {
380964dd374eSMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, test_smp_buffer,
381064dd374eSMarcel Holtmann 				       strlen(test_smp_buffer));
381164dd374eSMarcel Holtmann }
381264dd374eSMarcel Holtmann 
381364dd374eSMarcel Holtmann static const struct file_operations test_smp_fops = {
381464dd374eSMarcel Holtmann 	.open		= simple_open,
381564dd374eSMarcel Holtmann 	.read		= test_smp_read,
381664dd374eSMarcel Holtmann 	.llseek		= default_llseek,
381764dd374eSMarcel Holtmann };
381864dd374eSMarcel Holtmann 
3819a4770e11SAndy Lutomirski static int __init run_selftests(struct crypto_cipher *tfm_aes,
382047eb2ac8STudor Ambarus 				struct crypto_shash *tfm_cmac,
382147eb2ac8STudor Ambarus 				struct crypto_kpp *tfm_ecdh)
38220a2b0f04SJohan Hedberg {
3823255047b0SMarcel Holtmann 	ktime_t calltime, delta, rettime;
3824255047b0SMarcel Holtmann 	unsigned long long duration;
3825cfc4198eSJohan Hedberg 	int err;
3826cfc4198eSJohan Hedberg 
3827255047b0SMarcel Holtmann 	calltime = ktime_get();
3828255047b0SMarcel Holtmann 
382947eb2ac8STudor Ambarus 	err = test_debug_key(tfm_ecdh);
383071653eb6SMarcel Holtmann 	if (err) {
383171653eb6SMarcel Holtmann 		BT_ERR("debug_key test failed");
383271653eb6SMarcel Holtmann 		goto done;
383371653eb6SMarcel Holtmann 	}
383471653eb6SMarcel Holtmann 
3835cfc4198eSJohan Hedberg 	err = test_ah(tfm_aes);
3836cfc4198eSJohan Hedberg 	if (err) {
3837cfc4198eSJohan Hedberg 		BT_ERR("smp_ah test failed");
383864dd374eSMarcel Holtmann 		goto done;
3839cfc4198eSJohan Hedberg 	}
3840cfc4198eSJohan Hedberg 
3841cfc4198eSJohan Hedberg 	err = test_c1(tfm_aes);
3842cfc4198eSJohan Hedberg 	if (err) {
3843cfc4198eSJohan Hedberg 		BT_ERR("smp_c1 test failed");
384464dd374eSMarcel Holtmann 		goto done;
3845cfc4198eSJohan Hedberg 	}
3846cfc4198eSJohan Hedberg 
3847cfc4198eSJohan Hedberg 	err = test_s1(tfm_aes);
3848cfc4198eSJohan Hedberg 	if (err) {
3849cfc4198eSJohan Hedberg 		BT_ERR("smp_s1 test failed");
385064dd374eSMarcel Holtmann 		goto done;
3851cfc4198eSJohan Hedberg 	}
3852cfc4198eSJohan Hedberg 
3853fb2969a3SJohan Hedberg 	err = test_f4(tfm_cmac);
3854fb2969a3SJohan Hedberg 	if (err) {
3855fb2969a3SJohan Hedberg 		BT_ERR("smp_f4 test failed");
385664dd374eSMarcel Holtmann 		goto done;
3857fb2969a3SJohan Hedberg 	}
3858fb2969a3SJohan Hedberg 
3859fb2969a3SJohan Hedberg 	err = test_f5(tfm_cmac);
3860fb2969a3SJohan Hedberg 	if (err) {
3861fb2969a3SJohan Hedberg 		BT_ERR("smp_f5 test failed");
386264dd374eSMarcel Holtmann 		goto done;
3863fb2969a3SJohan Hedberg 	}
3864fb2969a3SJohan Hedberg 
3865fb2969a3SJohan Hedberg 	err = test_f6(tfm_cmac);
3866fb2969a3SJohan Hedberg 	if (err) {
3867fb2969a3SJohan Hedberg 		BT_ERR("smp_f6 test failed");
386864dd374eSMarcel Holtmann 		goto done;
3869fb2969a3SJohan Hedberg 	}
3870fb2969a3SJohan Hedberg 
3871fb2969a3SJohan Hedberg 	err = test_g2(tfm_cmac);
3872fb2969a3SJohan Hedberg 	if (err) {
3873fb2969a3SJohan Hedberg 		BT_ERR("smp_g2 test failed");
387464dd374eSMarcel Holtmann 		goto done;
3875fb2969a3SJohan Hedberg 	}
3876fb2969a3SJohan Hedberg 
3877fb2969a3SJohan Hedberg 	err = test_h6(tfm_cmac);
3878fb2969a3SJohan Hedberg 	if (err) {
3879fb2969a3SJohan Hedberg 		BT_ERR("smp_h6 test failed");
388064dd374eSMarcel Holtmann 		goto done;
3881fb2969a3SJohan Hedberg 	}
3882fb2969a3SJohan Hedberg 
3883255047b0SMarcel Holtmann 	rettime = ktime_get();
3884255047b0SMarcel Holtmann 	delta = ktime_sub(rettime, calltime);
3885255047b0SMarcel Holtmann 	duration = (unsigned long long) ktime_to_ns(delta) >> 10;
3886255047b0SMarcel Holtmann 
38875ced2464SMarcel Holtmann 	BT_INFO("SMP test passed in %llu usecs", duration);
38880a2b0f04SJohan Hedberg 
388964dd374eSMarcel Holtmann done:
389064dd374eSMarcel Holtmann 	if (!err)
389164dd374eSMarcel Holtmann 		snprintf(test_smp_buffer, sizeof(test_smp_buffer),
389264dd374eSMarcel Holtmann 			 "PASS (%llu usecs)\n", duration);
389364dd374eSMarcel Holtmann 	else
389464dd374eSMarcel Holtmann 		snprintf(test_smp_buffer, sizeof(test_smp_buffer), "FAIL\n");
389564dd374eSMarcel Holtmann 
389664dd374eSMarcel Holtmann 	debugfs_create_file("selftest_smp", 0444, bt_debugfs, NULL,
389764dd374eSMarcel Holtmann 			    &test_smp_fops);
389864dd374eSMarcel Holtmann 
389964dd374eSMarcel Holtmann 	return err;
39000a2b0f04SJohan Hedberg }
39010a2b0f04SJohan Hedberg 
39020a2b0f04SJohan Hedberg int __init bt_selftest_smp(void)
39030a2b0f04SJohan Hedberg {
3904a4770e11SAndy Lutomirski 	struct crypto_cipher *tfm_aes;
390571af2f6bSHerbert Xu 	struct crypto_shash *tfm_cmac;
390647eb2ac8STudor Ambarus 	struct crypto_kpp *tfm_ecdh;
39070a2b0f04SJohan Hedberg 	int err;
39080a2b0f04SJohan Hedberg 
3909a4770e11SAndy Lutomirski 	tfm_aes = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
39100a2b0f04SJohan Hedberg 	if (IS_ERR(tfm_aes)) {
3911a4770e11SAndy Lutomirski 		BT_ERR("Unable to create AES crypto context");
39120a2b0f04SJohan Hedberg 		return PTR_ERR(tfm_aes);
39130a2b0f04SJohan Hedberg 	}
39140a2b0f04SJohan Hedberg 
391571af2f6bSHerbert Xu 	tfm_cmac = crypto_alloc_shash("cmac(aes)", 0, CRYPTO_ALG_ASYNC);
39160a2b0f04SJohan Hedberg 	if (IS_ERR(tfm_cmac)) {
39170a2b0f04SJohan Hedberg 		BT_ERR("Unable to create CMAC crypto context");
3918a4770e11SAndy Lutomirski 		crypto_free_cipher(tfm_aes);
39190a2b0f04SJohan Hedberg 		return PTR_ERR(tfm_cmac);
39200a2b0f04SJohan Hedberg 	}
39210a2b0f04SJohan Hedberg 
392247eb2ac8STudor Ambarus 	tfm_ecdh = crypto_alloc_kpp("ecdh", CRYPTO_ALG_INTERNAL, 0);
392347eb2ac8STudor Ambarus 	if (IS_ERR(tfm_ecdh)) {
392447eb2ac8STudor Ambarus 		BT_ERR("Unable to create ECDH crypto context");
392547eb2ac8STudor Ambarus 		crypto_free_shash(tfm_cmac);
392647eb2ac8STudor Ambarus 		crypto_free_cipher(tfm_aes);
392747eb2ac8STudor Ambarus 		return PTR_ERR(tfm_ecdh);
392847eb2ac8STudor Ambarus 	}
392947eb2ac8STudor Ambarus 
393047eb2ac8STudor Ambarus 	err = run_selftests(tfm_aes, tfm_cmac, tfm_ecdh);
39310a2b0f04SJohan Hedberg 
393271af2f6bSHerbert Xu 	crypto_free_shash(tfm_cmac);
3933a4770e11SAndy Lutomirski 	crypto_free_cipher(tfm_aes);
393447eb2ac8STudor Ambarus 	crypto_free_kpp(tfm_ecdh);
39350a2b0f04SJohan Hedberg 
39360a2b0f04SJohan Hedberg 	return err;
39370a2b0f04SJohan Hedberg }
39380a2b0f04SJohan Hedberg 
39390a2b0f04SJohan Hedberg #endif
3940