xref: /openbmc/linux/net/bluetooth/smp.c (revision 6c0dcc50)
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 
238c520a59SGustavo Padovan #include <linux/crypto.h>
248c520a59SGustavo Padovan #include <linux/scatterlist.h>
258c520a59SGustavo Padovan #include <crypto/b128ops.h>
268c520a59SGustavo Padovan 
27eb492e01SAnderson Briglia #include <net/bluetooth/bluetooth.h>
28eb492e01SAnderson Briglia #include <net/bluetooth/hci_core.h>
29eb492e01SAnderson Briglia #include <net/bluetooth/l2cap.h>
302b64d153SBrian Gix #include <net/bluetooth/mgmt.h>
31ac4b7236SMarcel Holtmann 
323b19146dSJohan Hedberg #include "ecc.h"
33ac4b7236SMarcel Holtmann #include "smp.h"
34d22ef0bcSAnderson Briglia 
35b28b4943SJohan Hedberg #define SMP_ALLOW_CMD(smp, code)	set_bit(code, &smp->allow_cmd)
36b28b4943SJohan Hedberg 
373b19146dSJohan Hedberg /* Keys which are not distributed with Secure Connections */
383b19146dSJohan Hedberg #define SMP_SC_NO_DIST (SMP_DIST_ENC_KEY | SMP_DIST_LINK_KEY);
393b19146dSJohan Hedberg 
4017b02e62SMarcel Holtmann #define SMP_TIMEOUT	msecs_to_jiffies(30000)
415d3de7dfSVinicius Costa Gomes 
420edb14deSJohan Hedberg #define AUTH_REQ_MASK(dev)	(test_bit(HCI_SC_ENABLED, &(dev)->dev_flags) ? \
430edb14deSJohan Hedberg 				 0x1f : 0x07)
4488d3a8acSJohan Hedberg #define KEY_DIST_MASK		0x07
45065a13e2SJohan Hedberg 
46cbbbe3e2SJohan Hedberg /* Maximum message length that can be passed to aes_cmac */
47cbbbe3e2SJohan Hedberg #define CMAC_MSG_MAX	80
48cbbbe3e2SJohan Hedberg 
49533e35d4SJohan Hedberg enum {
50533e35d4SJohan Hedberg 	SMP_FLAG_TK_VALID,
51533e35d4SJohan Hedberg 	SMP_FLAG_CFM_PENDING,
52533e35d4SJohan Hedberg 	SMP_FLAG_MITM_AUTH,
53533e35d4SJohan Hedberg 	SMP_FLAG_COMPLETE,
54533e35d4SJohan Hedberg 	SMP_FLAG_INITIATOR,
5565668776SJohan Hedberg 	SMP_FLAG_SC,
56d8f8edbeSJohan Hedberg 	SMP_FLAG_REMOTE_PK,
57aeb7d461SJohan Hedberg 	SMP_FLAG_DEBUG_KEY,
58533e35d4SJohan Hedberg };
594bc58f51SJohan Hedberg 
604bc58f51SJohan Hedberg struct smp_chan {
614bc58f51SJohan Hedberg 	struct l2cap_conn	*conn;
62b68fda68SJohan Hedberg 	struct delayed_work	security_timer;
63b28b4943SJohan Hedberg 	unsigned long           allow_cmd; /* Bitmask of allowed commands */
64b68fda68SJohan Hedberg 
654bc58f51SJohan Hedberg 	u8		preq[7]; /* SMP Pairing Request */
664bc58f51SJohan Hedberg 	u8		prsp[7]; /* SMP Pairing Response */
674bc58f51SJohan Hedberg 	u8		prnd[16]; /* SMP Pairing Random (local) */
684bc58f51SJohan Hedberg 	u8		rrnd[16]; /* SMP Pairing Random (remote) */
694bc58f51SJohan Hedberg 	u8		pcnf[16]; /* SMP Pairing Confirm */
704bc58f51SJohan Hedberg 	u8		tk[16]; /* SMP Temporary Key */
714bc58f51SJohan Hedberg 	u8		enc_key_size;
724bc58f51SJohan Hedberg 	u8		remote_key_dist;
734bc58f51SJohan Hedberg 	bdaddr_t	id_addr;
744bc58f51SJohan Hedberg 	u8		id_addr_type;
754bc58f51SJohan Hedberg 	u8		irk[16];
764bc58f51SJohan Hedberg 	struct smp_csrk	*csrk;
774bc58f51SJohan Hedberg 	struct smp_csrk	*slave_csrk;
784bc58f51SJohan Hedberg 	struct smp_ltk	*ltk;
794bc58f51SJohan Hedberg 	struct smp_ltk	*slave_ltk;
804bc58f51SJohan Hedberg 	struct smp_irk	*remote_irk;
816a77083aSJohan Hedberg 	u8		*link_key;
824a74d658SJohan Hedberg 	unsigned long	flags;
83783e0574SJohan Hedberg 	u8		method;
846a7bd103SJohan Hedberg 
853b19146dSJohan Hedberg 	/* Secure Connections variables */
863b19146dSJohan Hedberg 	u8			local_pk[64];
873b19146dSJohan Hedberg 	u8			local_sk[32];
88d8f8edbeSJohan Hedberg 	u8			remote_pk[64];
89d8f8edbeSJohan Hedberg 	u8			dhkey[32];
90760b018bSJohan Hedberg 	u8			mackey[16];
913b19146dSJohan Hedberg 
926a7bd103SJohan Hedberg 	struct crypto_blkcipher	*tfm_aes;
93407cecf6SJohan Hedberg 	struct crypto_hash	*tfm_cmac;
944bc58f51SJohan Hedberg };
954bc58f51SJohan Hedberg 
96aeb7d461SJohan Hedberg /* These debug key values are defined in the SMP section of the core
97aeb7d461SJohan Hedberg  * specification. debug_pk is the public debug key and debug_sk the
98aeb7d461SJohan Hedberg  * private debug key.
99aeb7d461SJohan Hedberg  */
100aeb7d461SJohan Hedberg static const u8 debug_pk[64] = {
101aeb7d461SJohan Hedberg 		0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc,
102aeb7d461SJohan Hedberg 		0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef,
103aeb7d461SJohan Hedberg 		0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e,
104aeb7d461SJohan Hedberg 		0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20,
105aeb7d461SJohan Hedberg 
106aeb7d461SJohan Hedberg 		0x8b, 0xd2, 0x89, 0x15, 0xd0, 0x8e, 0x1c, 0x74,
107aeb7d461SJohan Hedberg 		0x24, 0x30, 0xed, 0x8f, 0xc2, 0x45, 0x63, 0x76,
108aeb7d461SJohan Hedberg 		0x5c, 0x15, 0x52, 0x5a, 0xbf, 0x9a, 0x32, 0x63,
109aeb7d461SJohan Hedberg 		0x6d, 0xeb, 0x2a, 0x65, 0x49, 0x9c, 0x80, 0xdc,
110aeb7d461SJohan Hedberg };
111aeb7d461SJohan Hedberg 
112aeb7d461SJohan Hedberg static const u8 debug_sk[32] = {
113aeb7d461SJohan Hedberg 		0xbd, 0x1a, 0x3c, 0xcd, 0xa6, 0xb8, 0x99, 0x58,
114aeb7d461SJohan Hedberg 		0x99, 0xb7, 0x40, 0xeb, 0x7b, 0x60, 0xff, 0x4a,
115aeb7d461SJohan Hedberg 		0x50, 0x3f, 0x10, 0xd2, 0xe3, 0xb3, 0xc9, 0x74,
116aeb7d461SJohan Hedberg 		0x38, 0x5f, 0xc5, 0xa3, 0xd4, 0xf6, 0x49, 0x3f,
117aeb7d461SJohan Hedberg };
118aeb7d461SJohan Hedberg 
1198a2936f4SJohan Hedberg static inline void swap_buf(const u8 *src, u8 *dst, size_t len)
120d22ef0bcSAnderson Briglia {
1218a2936f4SJohan Hedberg 	size_t i;
122d22ef0bcSAnderson Briglia 
1238a2936f4SJohan Hedberg 	for (i = 0; i < len; i++)
1248a2936f4SJohan Hedberg 		dst[len - 1 - i] = src[i];
125d22ef0bcSAnderson Briglia }
126d22ef0bcSAnderson Briglia 
127cbbbe3e2SJohan Hedberg static int aes_cmac(struct crypto_hash *tfm, const u8 k[16], const u8 *m,
128cbbbe3e2SJohan Hedberg 		    size_t len, u8 mac[16])
129cbbbe3e2SJohan Hedberg {
130cbbbe3e2SJohan Hedberg 	uint8_t tmp[16], mac_msb[16], msg_msb[CMAC_MSG_MAX];
131cbbbe3e2SJohan Hedberg 	struct hash_desc desc;
132cbbbe3e2SJohan Hedberg 	struct scatterlist sg;
133cbbbe3e2SJohan Hedberg 	int err;
134cbbbe3e2SJohan Hedberg 
135cbbbe3e2SJohan Hedberg 	if (len > CMAC_MSG_MAX)
136cbbbe3e2SJohan Hedberg 		return -EFBIG;
137cbbbe3e2SJohan Hedberg 
138cbbbe3e2SJohan Hedberg 	if (!tfm) {
139cbbbe3e2SJohan Hedberg 		BT_ERR("tfm %p", tfm);
140cbbbe3e2SJohan Hedberg 		return -EINVAL;
141cbbbe3e2SJohan Hedberg 	}
142cbbbe3e2SJohan Hedberg 
143cbbbe3e2SJohan Hedberg 	desc.tfm = tfm;
144cbbbe3e2SJohan Hedberg 	desc.flags = 0;
145cbbbe3e2SJohan Hedberg 
146cbbbe3e2SJohan Hedberg 	crypto_hash_init(&desc);
147cbbbe3e2SJohan Hedberg 
148cbbbe3e2SJohan Hedberg 	/* Swap key and message from LSB to MSB */
149cbbbe3e2SJohan Hedberg 	swap_buf(k, tmp, 16);
150cbbbe3e2SJohan Hedberg 	swap_buf(m, msg_msb, len);
151cbbbe3e2SJohan Hedberg 
152cbbbe3e2SJohan Hedberg 	BT_DBG("msg (len %zu) %*phN", len, (int) len, m);
153cbbbe3e2SJohan Hedberg 	BT_DBG("key %16phN", k);
154cbbbe3e2SJohan Hedberg 
155cbbbe3e2SJohan Hedberg 	err = crypto_hash_setkey(tfm, tmp, 16);
156cbbbe3e2SJohan Hedberg 	if (err) {
157cbbbe3e2SJohan Hedberg 		BT_ERR("cipher setkey failed: %d", err);
158cbbbe3e2SJohan Hedberg 		return err;
159cbbbe3e2SJohan Hedberg 	}
160cbbbe3e2SJohan Hedberg 
161cbbbe3e2SJohan Hedberg 	sg_init_one(&sg, msg_msb, len);
162cbbbe3e2SJohan Hedberg 
163cbbbe3e2SJohan Hedberg 	err = crypto_hash_update(&desc, &sg, len);
164cbbbe3e2SJohan Hedberg 	if (err) {
165cbbbe3e2SJohan Hedberg 		BT_ERR("Hash update error %d", err);
166cbbbe3e2SJohan Hedberg 		return err;
167cbbbe3e2SJohan Hedberg 	}
168cbbbe3e2SJohan Hedberg 
169cbbbe3e2SJohan Hedberg 	err = crypto_hash_final(&desc, mac_msb);
170cbbbe3e2SJohan Hedberg 	if (err) {
171cbbbe3e2SJohan Hedberg 		BT_ERR("Hash final error %d", err);
172cbbbe3e2SJohan Hedberg 		return err;
173cbbbe3e2SJohan Hedberg 	}
174cbbbe3e2SJohan Hedberg 
175cbbbe3e2SJohan Hedberg 	swap_buf(mac_msb, mac, 16);
176cbbbe3e2SJohan Hedberg 
177cbbbe3e2SJohan Hedberg 	BT_DBG("mac %16phN", mac);
178cbbbe3e2SJohan Hedberg 
179cbbbe3e2SJohan Hedberg 	return 0;
180cbbbe3e2SJohan Hedberg }
181cbbbe3e2SJohan Hedberg 
182cbbbe3e2SJohan Hedberg static int smp_f4(struct crypto_hash *tfm_cmac, const u8 u[32], const u8 v[32],
183cbbbe3e2SJohan Hedberg 		  const u8 x[16], u8 z, u8 res[16])
184cbbbe3e2SJohan Hedberg {
185cbbbe3e2SJohan Hedberg 	u8 m[65];
186cbbbe3e2SJohan Hedberg 	int err;
187cbbbe3e2SJohan Hedberg 
188cbbbe3e2SJohan Hedberg 	BT_DBG("u %32phN", u);
189cbbbe3e2SJohan Hedberg 	BT_DBG("v %32phN", v);
190cbbbe3e2SJohan Hedberg 	BT_DBG("x %16phN z %02x", x, z);
191cbbbe3e2SJohan Hedberg 
192cbbbe3e2SJohan Hedberg 	m[0] = z;
193cbbbe3e2SJohan Hedberg 	memcpy(m + 1, v, 32);
194cbbbe3e2SJohan Hedberg 	memcpy(m + 33, u, 32);
195cbbbe3e2SJohan Hedberg 
196cbbbe3e2SJohan Hedberg 	err = aes_cmac(tfm_cmac, x, m, sizeof(m), res);
197cbbbe3e2SJohan Hedberg 	if (err)
198cbbbe3e2SJohan Hedberg 		return err;
199cbbbe3e2SJohan Hedberg 
200cbbbe3e2SJohan Hedberg 	BT_DBG("res %16phN", res);
201cbbbe3e2SJohan Hedberg 
202cbbbe3e2SJohan Hedberg 	return err;
203cbbbe3e2SJohan Hedberg }
204cbbbe3e2SJohan Hedberg 
205760b018bSJohan Hedberg static int smp_f5(struct crypto_hash *tfm_cmac, u8 w[32], u8 n1[16], u8 n2[16],
206760b018bSJohan Hedberg 		  u8 a1[7], u8 a2[7], u8 mackey[16], u8 ltk[16])
207760b018bSJohan Hedberg {
208760b018bSJohan Hedberg 	/* The btle, salt and length "magic" values are as defined in
209760b018bSJohan Hedberg 	 * the SMP section of the Bluetooth core specification. In ASCII
210760b018bSJohan Hedberg 	 * the btle value ends up being 'btle'. The salt is just a
211760b018bSJohan Hedberg 	 * random number whereas length is the value 256 in little
212760b018bSJohan Hedberg 	 * endian format.
213760b018bSJohan Hedberg 	 */
214760b018bSJohan Hedberg 	const u8 btle[4] = { 0x65, 0x6c, 0x74, 0x62 };
215760b018bSJohan Hedberg 	const u8 salt[16] = { 0xbe, 0x83, 0x60, 0x5a, 0xdb, 0x0b, 0x37, 0x60,
216760b018bSJohan Hedberg 			      0x38, 0xa5, 0xf5, 0xaa, 0x91, 0x83, 0x88, 0x6c };
217760b018bSJohan Hedberg 	const u8 length[2] = { 0x00, 0x01 };
218760b018bSJohan Hedberg 	u8 m[53], t[16];
219760b018bSJohan Hedberg 	int err;
220760b018bSJohan Hedberg 
221760b018bSJohan Hedberg 	BT_DBG("w %32phN", w);
222760b018bSJohan Hedberg 	BT_DBG("n1 %16phN n2 %16phN", n1, n2);
223760b018bSJohan Hedberg 	BT_DBG("a1 %7phN a2 %7phN", a1, a2);
224760b018bSJohan Hedberg 
225760b018bSJohan Hedberg 	err = aes_cmac(tfm_cmac, salt, w, 32, t);
226760b018bSJohan Hedberg 	if (err)
227760b018bSJohan Hedberg 		return err;
228760b018bSJohan Hedberg 
229760b018bSJohan Hedberg 	BT_DBG("t %16phN", t);
230760b018bSJohan Hedberg 
231760b018bSJohan Hedberg 	memcpy(m, length, 2);
232760b018bSJohan Hedberg 	memcpy(m + 2, a2, 7);
233760b018bSJohan Hedberg 	memcpy(m + 9, a1, 7);
234760b018bSJohan Hedberg 	memcpy(m + 16, n2, 16);
235760b018bSJohan Hedberg 	memcpy(m + 32, n1, 16);
236760b018bSJohan Hedberg 	memcpy(m + 48, btle, 4);
237760b018bSJohan Hedberg 
238760b018bSJohan Hedberg 	m[52] = 0; /* Counter */
239760b018bSJohan Hedberg 
240760b018bSJohan Hedberg 	err = aes_cmac(tfm_cmac, t, m, sizeof(m), mackey);
241760b018bSJohan Hedberg 	if (err)
242760b018bSJohan Hedberg 		return err;
243760b018bSJohan Hedberg 
244760b018bSJohan Hedberg 	BT_DBG("mackey %16phN", mackey);
245760b018bSJohan Hedberg 
246760b018bSJohan Hedberg 	m[52] = 1; /* Counter */
247760b018bSJohan Hedberg 
248760b018bSJohan Hedberg 	err = aes_cmac(tfm_cmac, t, m, sizeof(m), ltk);
249760b018bSJohan Hedberg 	if (err)
250760b018bSJohan Hedberg 		return err;
251760b018bSJohan Hedberg 
252760b018bSJohan Hedberg 	BT_DBG("ltk %16phN", ltk);
253760b018bSJohan Hedberg 
254760b018bSJohan Hedberg 	return 0;
255760b018bSJohan Hedberg }
256760b018bSJohan Hedberg 
257760b018bSJohan Hedberg static int smp_f6(struct crypto_hash *tfm_cmac, const u8 w[16],
258760b018bSJohan Hedberg 		  const u8 n1[16], u8 n2[16], const u8 r[16],
259760b018bSJohan Hedberg 		  const u8 io_cap[3], const u8 a1[7], const u8 a2[7],
260760b018bSJohan Hedberg 		  u8 res[16])
261760b018bSJohan Hedberg {
262760b018bSJohan Hedberg 	u8 m[65];
263760b018bSJohan Hedberg 	int err;
264760b018bSJohan Hedberg 
265760b018bSJohan Hedberg 	BT_DBG("w %16phN", w);
266760b018bSJohan Hedberg 	BT_DBG("n1 %16phN n2 %16phN", n1, n2);
267760b018bSJohan Hedberg 	BT_DBG("r %16phN io_cap %3phN a1 %7phN a2 %7phN", r, io_cap, a1, a2);
268760b018bSJohan Hedberg 
269760b018bSJohan Hedberg 	memcpy(m, a2, 7);
270760b018bSJohan Hedberg 	memcpy(m + 7, a1, 7);
271760b018bSJohan Hedberg 	memcpy(m + 14, io_cap, 3);
272760b018bSJohan Hedberg 	memcpy(m + 17, r, 16);
273760b018bSJohan Hedberg 	memcpy(m + 33, n2, 16);
274760b018bSJohan Hedberg 	memcpy(m + 49, n1, 16);
275760b018bSJohan Hedberg 
276760b018bSJohan Hedberg 	err = aes_cmac(tfm_cmac, w, m, sizeof(m), res);
277760b018bSJohan Hedberg 	if (err)
278760b018bSJohan Hedberg 		return err;
279760b018bSJohan Hedberg 
280760b018bSJohan Hedberg 	BT_DBG("res %16phN", res);
281760b018bSJohan Hedberg 
282760b018bSJohan Hedberg 	return err;
283760b018bSJohan Hedberg }
284760b018bSJohan Hedberg 
285191dc7feSJohan Hedberg static int smp_g2(struct crypto_hash *tfm_cmac, const u8 u[32], const u8 v[32],
286191dc7feSJohan Hedberg 		  const u8 x[16], const u8 y[16], u32 *val)
287191dc7feSJohan Hedberg {
288191dc7feSJohan Hedberg 	u8 m[80], tmp[16];
289191dc7feSJohan Hedberg 	int err;
290191dc7feSJohan Hedberg 
291191dc7feSJohan Hedberg 	BT_DBG("u %32phN", u);
292191dc7feSJohan Hedberg 	BT_DBG("v %32phN", v);
293191dc7feSJohan Hedberg 	BT_DBG("x %16phN y %16phN", x, y);
294191dc7feSJohan Hedberg 
295191dc7feSJohan Hedberg 	memcpy(m, y, 16);
296191dc7feSJohan Hedberg 	memcpy(m + 16, v, 32);
297191dc7feSJohan Hedberg 	memcpy(m + 48, u, 32);
298191dc7feSJohan Hedberg 
299191dc7feSJohan Hedberg 	err = aes_cmac(tfm_cmac, x, m, sizeof(m), tmp);
300191dc7feSJohan Hedberg 	if (err)
301191dc7feSJohan Hedberg 		return err;
302191dc7feSJohan Hedberg 
303191dc7feSJohan Hedberg 	*val = get_unaligned_le32(tmp);
304191dc7feSJohan Hedberg 	*val %= 1000000;
305191dc7feSJohan Hedberg 
306191dc7feSJohan Hedberg 	BT_DBG("val %06u", *val);
307191dc7feSJohan Hedberg 
308191dc7feSJohan Hedberg 	return 0;
309191dc7feSJohan Hedberg }
310191dc7feSJohan Hedberg 
311d22ef0bcSAnderson Briglia static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
312d22ef0bcSAnderson Briglia {
313d22ef0bcSAnderson Briglia 	struct blkcipher_desc desc;
314d22ef0bcSAnderson Briglia 	struct scatterlist sg;
315943a732aSJohan Hedberg 	uint8_t tmp[16], data[16];
316201a5929SJohan Hedberg 	int err;
317d22ef0bcSAnderson Briglia 
318d22ef0bcSAnderson Briglia 	if (tfm == NULL) {
319d22ef0bcSAnderson Briglia 		BT_ERR("tfm %p", tfm);
320d22ef0bcSAnderson Briglia 		return -EINVAL;
321d22ef0bcSAnderson Briglia 	}
322d22ef0bcSAnderson Briglia 
323d22ef0bcSAnderson Briglia 	desc.tfm = tfm;
324d22ef0bcSAnderson Briglia 	desc.flags = 0;
325d22ef0bcSAnderson Briglia 
326943a732aSJohan Hedberg 	/* The most significant octet of key corresponds to k[0] */
3278a2936f4SJohan Hedberg 	swap_buf(k, tmp, 16);
328943a732aSJohan Hedberg 
329943a732aSJohan Hedberg 	err = crypto_blkcipher_setkey(tfm, tmp, 16);
330d22ef0bcSAnderson Briglia 	if (err) {
331d22ef0bcSAnderson Briglia 		BT_ERR("cipher setkey failed: %d", err);
332d22ef0bcSAnderson Briglia 		return err;
333d22ef0bcSAnderson Briglia 	}
334d22ef0bcSAnderson Briglia 
335943a732aSJohan Hedberg 	/* Most significant octet of plaintextData corresponds to data[0] */
3368a2936f4SJohan Hedberg 	swap_buf(r, data, 16);
337943a732aSJohan Hedberg 
338943a732aSJohan Hedberg 	sg_init_one(&sg, data, 16);
339d22ef0bcSAnderson Briglia 
340d22ef0bcSAnderson Briglia 	err = crypto_blkcipher_encrypt(&desc, &sg, &sg, 16);
341d22ef0bcSAnderson Briglia 	if (err)
342d22ef0bcSAnderson Briglia 		BT_ERR("Encrypt data error %d", err);
343d22ef0bcSAnderson Briglia 
344943a732aSJohan Hedberg 	/* Most significant octet of encryptedData corresponds to data[0] */
3458a2936f4SJohan Hedberg 	swap_buf(data, r, 16);
346943a732aSJohan Hedberg 
347d22ef0bcSAnderson Briglia 	return err;
348d22ef0bcSAnderson Briglia }
349d22ef0bcSAnderson Briglia 
3506a77083aSJohan Hedberg static int smp_h6(struct crypto_hash *tfm_cmac, const u8 w[16],
3516a77083aSJohan Hedberg 		  const u8 key_id[4], u8 res[16])
3526a77083aSJohan Hedberg {
3536a77083aSJohan Hedberg 	int err;
3546a77083aSJohan Hedberg 
3556a77083aSJohan Hedberg 	BT_DBG("w %16phN key_id %4phN", w, key_id);
3566a77083aSJohan Hedberg 
3576a77083aSJohan Hedberg 	err = aes_cmac(tfm_cmac, w, key_id, 4, res);
3586a77083aSJohan Hedberg 	if (err)
3596a77083aSJohan Hedberg 		return err;
3606a77083aSJohan Hedberg 
3616a77083aSJohan Hedberg 	BT_DBG("res %16phN", res);
3626a77083aSJohan Hedberg 
3636a77083aSJohan Hedberg 	return err;
3646a77083aSJohan Hedberg }
3656a77083aSJohan Hedberg 
36660478054SJohan Hedberg static int smp_ah(struct crypto_blkcipher *tfm, u8 irk[16], u8 r[3], u8 res[3])
36760478054SJohan Hedberg {
368943a732aSJohan Hedberg 	u8 _res[16];
36960478054SJohan Hedberg 	int err;
37060478054SJohan Hedberg 
37160478054SJohan Hedberg 	/* r' = padding || r */
372943a732aSJohan Hedberg 	memcpy(_res, r, 3);
373943a732aSJohan Hedberg 	memset(_res + 3, 0, 13);
37460478054SJohan Hedberg 
375943a732aSJohan Hedberg 	err = smp_e(tfm, irk, _res);
37660478054SJohan Hedberg 	if (err) {
37760478054SJohan Hedberg 		BT_ERR("Encrypt error");
37860478054SJohan Hedberg 		return err;
37960478054SJohan Hedberg 	}
38060478054SJohan Hedberg 
38160478054SJohan Hedberg 	/* The output of the random address function ah is:
38260478054SJohan Hedberg 	 *	ah(h, r) = e(k, r') mod 2^24
38360478054SJohan Hedberg 	 * The output of the security function e is then truncated to 24 bits
38460478054SJohan Hedberg 	 * by taking the least significant 24 bits of the output of e as the
38560478054SJohan Hedberg 	 * result of ah.
38660478054SJohan Hedberg 	 */
387943a732aSJohan Hedberg 	memcpy(res, _res, 3);
38860478054SJohan Hedberg 
38960478054SJohan Hedberg 	return 0;
39060478054SJohan Hedberg }
39160478054SJohan Hedberg 
392defce9e8SJohan Hedberg bool smp_irk_matches(struct hci_dev *hdev, u8 irk[16], bdaddr_t *bdaddr)
39360478054SJohan Hedberg {
394defce9e8SJohan Hedberg 	struct l2cap_chan *chan = hdev->smp_data;
395defce9e8SJohan Hedberg 	struct crypto_blkcipher *tfm;
39660478054SJohan Hedberg 	u8 hash[3];
39760478054SJohan Hedberg 	int err;
39860478054SJohan Hedberg 
399defce9e8SJohan Hedberg 	if (!chan || !chan->data)
400defce9e8SJohan Hedberg 		return false;
401defce9e8SJohan Hedberg 
402defce9e8SJohan Hedberg 	tfm = chan->data;
403defce9e8SJohan Hedberg 
40460478054SJohan Hedberg 	BT_DBG("RPA %pMR IRK %*phN", bdaddr, 16, irk);
40560478054SJohan Hedberg 
40660478054SJohan Hedberg 	err = smp_ah(tfm, irk, &bdaddr->b[3], hash);
40760478054SJohan Hedberg 	if (err)
40860478054SJohan Hedberg 		return false;
40960478054SJohan Hedberg 
41060478054SJohan Hedberg 	return !memcmp(bdaddr->b, hash, 3);
41160478054SJohan Hedberg }
41260478054SJohan Hedberg 
413defce9e8SJohan Hedberg int smp_generate_rpa(struct hci_dev *hdev, u8 irk[16], bdaddr_t *rpa)
414b1e2b3aeSJohan Hedberg {
415defce9e8SJohan Hedberg 	struct l2cap_chan *chan = hdev->smp_data;
416defce9e8SJohan Hedberg 	struct crypto_blkcipher *tfm;
417b1e2b3aeSJohan Hedberg 	int err;
418b1e2b3aeSJohan Hedberg 
419defce9e8SJohan Hedberg 	if (!chan || !chan->data)
420defce9e8SJohan Hedberg 		return -EOPNOTSUPP;
421defce9e8SJohan Hedberg 
422defce9e8SJohan Hedberg 	tfm = chan->data;
423defce9e8SJohan Hedberg 
424b1e2b3aeSJohan Hedberg 	get_random_bytes(&rpa->b[3], 3);
425b1e2b3aeSJohan Hedberg 
426b1e2b3aeSJohan Hedberg 	rpa->b[5] &= 0x3f;	/* Clear two most significant bits */
427b1e2b3aeSJohan Hedberg 	rpa->b[5] |= 0x40;	/* Set second most significant bit */
428b1e2b3aeSJohan Hedberg 
429b1e2b3aeSJohan Hedberg 	err = smp_ah(tfm, irk, &rpa->b[3], rpa->b);
430b1e2b3aeSJohan Hedberg 	if (err < 0)
431b1e2b3aeSJohan Hedberg 		return err;
432b1e2b3aeSJohan Hedberg 
433b1e2b3aeSJohan Hedberg 	BT_DBG("RPA %pMR", rpa);
434b1e2b3aeSJohan Hedberg 
435b1e2b3aeSJohan Hedberg 	return 0;
436b1e2b3aeSJohan Hedberg }
437b1e2b3aeSJohan Hedberg 
438e491eaf3SJohan Hedberg static int smp_c1(struct crypto_blkcipher *tfm_aes, u8 k[16], u8 r[16],
439e491eaf3SJohan Hedberg 		  u8 preq[7], u8 pres[7], u8 _iat, bdaddr_t *ia, u8 _rat,
440e491eaf3SJohan Hedberg 		  bdaddr_t *ra, u8 res[16])
441d22ef0bcSAnderson Briglia {
442d22ef0bcSAnderson Briglia 	u8 p1[16], p2[16];
443d22ef0bcSAnderson Briglia 	int err;
444d22ef0bcSAnderson Briglia 
445d22ef0bcSAnderson Briglia 	memset(p1, 0, 16);
446d22ef0bcSAnderson Briglia 
447d22ef0bcSAnderson Briglia 	/* p1 = pres || preq || _rat || _iat */
448943a732aSJohan Hedberg 	p1[0] = _iat;
449943a732aSJohan Hedberg 	p1[1] = _rat;
450943a732aSJohan Hedberg 	memcpy(p1 + 2, preq, 7);
451943a732aSJohan Hedberg 	memcpy(p1 + 9, pres, 7);
452d22ef0bcSAnderson Briglia 
453d22ef0bcSAnderson Briglia 	/* p2 = padding || ia || ra */
454943a732aSJohan Hedberg 	memcpy(p2, ra, 6);
455943a732aSJohan Hedberg 	memcpy(p2 + 6, ia, 6);
456943a732aSJohan Hedberg 	memset(p2 + 12, 0, 4);
457d22ef0bcSAnderson Briglia 
458d22ef0bcSAnderson Briglia 	/* res = r XOR p1 */
459d22ef0bcSAnderson Briglia 	u128_xor((u128 *) res, (u128 *) r, (u128 *) p1);
460d22ef0bcSAnderson Briglia 
461d22ef0bcSAnderson Briglia 	/* res = e(k, res) */
462e491eaf3SJohan Hedberg 	err = smp_e(tfm_aes, k, res);
463d22ef0bcSAnderson Briglia 	if (err) {
464d22ef0bcSAnderson Briglia 		BT_ERR("Encrypt data error");
465d22ef0bcSAnderson Briglia 		return err;
466d22ef0bcSAnderson Briglia 	}
467d22ef0bcSAnderson Briglia 
468d22ef0bcSAnderson Briglia 	/* res = res XOR p2 */
469d22ef0bcSAnderson Briglia 	u128_xor((u128 *) res, (u128 *) res, (u128 *) p2);
470d22ef0bcSAnderson Briglia 
471d22ef0bcSAnderson Briglia 	/* res = e(k, res) */
472e491eaf3SJohan Hedberg 	err = smp_e(tfm_aes, k, res);
473d22ef0bcSAnderson Briglia 	if (err)
474d22ef0bcSAnderson Briglia 		BT_ERR("Encrypt data error");
475d22ef0bcSAnderson Briglia 
476d22ef0bcSAnderson Briglia 	return err;
477d22ef0bcSAnderson Briglia }
478d22ef0bcSAnderson Briglia 
479e491eaf3SJohan Hedberg static int smp_s1(struct crypto_blkcipher *tfm_aes, u8 k[16], u8 r1[16],
480e491eaf3SJohan Hedberg 		  u8 r2[16], u8 _r[16])
481d22ef0bcSAnderson Briglia {
482d22ef0bcSAnderson Briglia 	int err;
483d22ef0bcSAnderson Briglia 
484d22ef0bcSAnderson Briglia 	/* Just least significant octets from r1 and r2 are considered */
485943a732aSJohan Hedberg 	memcpy(_r, r2, 8);
486943a732aSJohan Hedberg 	memcpy(_r + 8, r1, 8);
487d22ef0bcSAnderson Briglia 
488e491eaf3SJohan Hedberg 	err = smp_e(tfm_aes, k, _r);
489d22ef0bcSAnderson Briglia 	if (err)
490d22ef0bcSAnderson Briglia 		BT_ERR("Encrypt data error");
491d22ef0bcSAnderson Briglia 
492d22ef0bcSAnderson Briglia 	return err;
493d22ef0bcSAnderson Briglia }
494d22ef0bcSAnderson Briglia 
495eb492e01SAnderson Briglia static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
496eb492e01SAnderson Briglia {
4975d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
498b68fda68SJohan Hedberg 	struct smp_chan *smp;
4995d88cc73SJohan Hedberg 	struct kvec iv[2];
5005d88cc73SJohan Hedberg 	struct msghdr msg;
5015d88cc73SJohan Hedberg 
5025d88cc73SJohan Hedberg 	if (!chan)
5035d88cc73SJohan Hedberg 		return;
504eb492e01SAnderson Briglia 
505eb492e01SAnderson Briglia 	BT_DBG("code 0x%2.2x", code);
506eb492e01SAnderson Briglia 
5075d88cc73SJohan Hedberg 	iv[0].iov_base = &code;
5085d88cc73SJohan Hedberg 	iv[0].iov_len = 1;
509eb492e01SAnderson Briglia 
5105d88cc73SJohan Hedberg 	iv[1].iov_base = data;
5115d88cc73SJohan Hedberg 	iv[1].iov_len = len;
5125d88cc73SJohan Hedberg 
5135d88cc73SJohan Hedberg 	memset(&msg, 0, sizeof(msg));
5145d88cc73SJohan Hedberg 
5155d88cc73SJohan Hedberg 	msg.msg_iov = (struct iovec *) &iv;
5165d88cc73SJohan Hedberg 	msg.msg_iovlen = 2;
5175d88cc73SJohan Hedberg 
5185d88cc73SJohan Hedberg 	l2cap_chan_send(chan, &msg, 1 + len);
519e2dcd113SVinicius Costa Gomes 
520b68fda68SJohan Hedberg 	if (!chan->data)
521b68fda68SJohan Hedberg 		return;
522b68fda68SJohan Hedberg 
523b68fda68SJohan Hedberg 	smp = chan->data;
524b68fda68SJohan Hedberg 
525b68fda68SJohan Hedberg 	cancel_delayed_work_sync(&smp->security_timer);
526b68fda68SJohan Hedberg 	schedule_delayed_work(&smp->security_timer, SMP_TIMEOUT);
527eb492e01SAnderson Briglia }
528eb492e01SAnderson Briglia 
529d2eb9e10SJohan Hedberg static u8 authreq_to_seclevel(u8 authreq)
5302b64d153SBrian Gix {
531d2eb9e10SJohan Hedberg 	if (authreq & SMP_AUTH_MITM) {
532d2eb9e10SJohan Hedberg 		if (authreq & SMP_AUTH_SC)
533d2eb9e10SJohan Hedberg 			return BT_SECURITY_FIPS;
5342b64d153SBrian Gix 		else
535d2eb9e10SJohan Hedberg 			return BT_SECURITY_HIGH;
536d2eb9e10SJohan Hedberg 	} else {
5372b64d153SBrian Gix 		return BT_SECURITY_MEDIUM;
5382b64d153SBrian Gix 	}
539d2eb9e10SJohan Hedberg }
5402b64d153SBrian Gix 
5412b64d153SBrian Gix static __u8 seclevel_to_authreq(__u8 sec_level)
5422b64d153SBrian Gix {
5432b64d153SBrian Gix 	switch (sec_level) {
544d2eb9e10SJohan Hedberg 	case BT_SECURITY_FIPS:
5452b64d153SBrian Gix 	case BT_SECURITY_HIGH:
5462b64d153SBrian Gix 		return SMP_AUTH_MITM | SMP_AUTH_BONDING;
5472b64d153SBrian Gix 	case BT_SECURITY_MEDIUM:
5482b64d153SBrian Gix 		return SMP_AUTH_BONDING;
5492b64d153SBrian Gix 	default:
5502b64d153SBrian Gix 		return SMP_AUTH_NONE;
5512b64d153SBrian Gix 	}
5522b64d153SBrian Gix }
5532b64d153SBrian Gix 
554b8e66eacSVinicius Costa Gomes static void build_pairing_cmd(struct l2cap_conn *conn,
55554790f73SVinicius Costa Gomes 			      struct smp_cmd_pairing *req,
556f1560463SMarcel Holtmann 			      struct smp_cmd_pairing *rsp, __u8 authreq)
557b8e66eacSVinicius Costa Gomes {
5585d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
5595d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
560fd349c02SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
561fd349c02SJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
562fd349c02SJohan Hedberg 	u8 local_dist = 0, remote_dist = 0;
56354790f73SVinicius Costa Gomes 
564b6ae8457SJohan Hedberg 	if (test_bit(HCI_BONDABLE, &conn->hcon->hdev->dev_flags)) {
5657ee4ea36SMarcel Holtmann 		local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
5667ee4ea36SMarcel Holtmann 		remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
56754790f73SVinicius Costa Gomes 		authreq |= SMP_AUTH_BONDING;
5682b64d153SBrian Gix 	} else {
5692b64d153SBrian Gix 		authreq &= ~SMP_AUTH_BONDING;
57054790f73SVinicius Costa Gomes 	}
57154790f73SVinicius Costa Gomes 
572fd349c02SJohan Hedberg 	if (test_bit(HCI_RPA_RESOLVING, &hdev->dev_flags))
573fd349c02SJohan Hedberg 		remote_dist |= SMP_DIST_ID_KEY;
574fd349c02SJohan Hedberg 
575863efaf2SJohan Hedberg 	if (test_bit(HCI_PRIVACY, &hdev->dev_flags))
576863efaf2SJohan Hedberg 		local_dist |= SMP_DIST_ID_KEY;
577863efaf2SJohan Hedberg 
578df8e1a4cSJohan Hedberg 	if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) {
579df8e1a4cSJohan Hedberg 		if ((authreq & SMP_AUTH_SC) &&
580df8e1a4cSJohan Hedberg 		    test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
581df8e1a4cSJohan Hedberg 			local_dist |= SMP_DIST_LINK_KEY;
582df8e1a4cSJohan Hedberg 			remote_dist |= SMP_DIST_LINK_KEY;
583df8e1a4cSJohan Hedberg 		}
584df8e1a4cSJohan Hedberg 	} else {
585df8e1a4cSJohan Hedberg 		authreq &= ~SMP_AUTH_SC;
586df8e1a4cSJohan Hedberg 	}
587df8e1a4cSJohan Hedberg 
58854790f73SVinicius Costa Gomes 	if (rsp == NULL) {
58954790f73SVinicius Costa Gomes 		req->io_capability = conn->hcon->io_capability;
59054790f73SVinicius Costa Gomes 		req->oob_flag = SMP_OOB_NOT_PRESENT;
59154790f73SVinicius Costa Gomes 		req->max_key_size = SMP_MAX_ENC_KEY_SIZE;
592fd349c02SJohan Hedberg 		req->init_key_dist = local_dist;
593fd349c02SJohan Hedberg 		req->resp_key_dist = remote_dist;
5940edb14deSJohan Hedberg 		req->auth_req = (authreq & AUTH_REQ_MASK(hdev));
595fd349c02SJohan Hedberg 
596fd349c02SJohan Hedberg 		smp->remote_key_dist = remote_dist;
59754790f73SVinicius Costa Gomes 		return;
59854790f73SVinicius Costa Gomes 	}
59954790f73SVinicius Costa Gomes 
60054790f73SVinicius Costa Gomes 	rsp->io_capability = conn->hcon->io_capability;
60154790f73SVinicius Costa Gomes 	rsp->oob_flag = SMP_OOB_NOT_PRESENT;
60254790f73SVinicius Costa Gomes 	rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE;
603fd349c02SJohan Hedberg 	rsp->init_key_dist = req->init_key_dist & remote_dist;
604fd349c02SJohan Hedberg 	rsp->resp_key_dist = req->resp_key_dist & local_dist;
6050edb14deSJohan Hedberg 	rsp->auth_req = (authreq & AUTH_REQ_MASK(hdev));
606fd349c02SJohan Hedberg 
607fd349c02SJohan Hedberg 	smp->remote_key_dist = rsp->init_key_dist;
608b8e66eacSVinicius Costa Gomes }
609b8e66eacSVinicius Costa Gomes 
6103158c50cSVinicius Costa Gomes static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
6113158c50cSVinicius Costa Gomes {
6125d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
6135d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
6141c1def09SVinicius Costa Gomes 
6153158c50cSVinicius Costa Gomes 	if ((max_key_size > SMP_MAX_ENC_KEY_SIZE) ||
6163158c50cSVinicius Costa Gomes 	    (max_key_size < SMP_MIN_ENC_KEY_SIZE))
6173158c50cSVinicius Costa Gomes 		return SMP_ENC_KEY_SIZE;
6183158c50cSVinicius Costa Gomes 
619f7aa611aSVinicius Costa Gomes 	smp->enc_key_size = max_key_size;
6203158c50cSVinicius Costa Gomes 
6213158c50cSVinicius Costa Gomes 	return 0;
6223158c50cSVinicius Costa Gomes }
6233158c50cSVinicius Costa Gomes 
6246f48e260SJohan Hedberg static void smp_chan_destroy(struct l2cap_conn *conn)
6256f48e260SJohan Hedberg {
6266f48e260SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
6276f48e260SJohan Hedberg 	struct smp_chan *smp = chan->data;
6286f48e260SJohan Hedberg 	bool complete;
6296f48e260SJohan Hedberg 
6306f48e260SJohan Hedberg 	BUG_ON(!smp);
6316f48e260SJohan Hedberg 
6326f48e260SJohan Hedberg 	cancel_delayed_work_sync(&smp->security_timer);
6336f48e260SJohan Hedberg 
6346f48e260SJohan Hedberg 	complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags);
6356f48e260SJohan Hedberg 	mgmt_smp_complete(conn->hcon, complete);
6366f48e260SJohan Hedberg 
6376f48e260SJohan Hedberg 	kfree(smp->csrk);
6386f48e260SJohan Hedberg 	kfree(smp->slave_csrk);
6396a77083aSJohan Hedberg 	kfree(smp->link_key);
6406f48e260SJohan Hedberg 
6416f48e260SJohan Hedberg 	crypto_free_blkcipher(smp->tfm_aes);
642407cecf6SJohan Hedberg 	crypto_free_hash(smp->tfm_cmac);
6436f48e260SJohan Hedberg 
6446f48e260SJohan Hedberg 	/* If pairing failed clean up any keys we might have */
6456f48e260SJohan Hedberg 	if (!complete) {
6466f48e260SJohan Hedberg 		if (smp->ltk) {
647970d0f1bSJohan Hedberg 			list_del_rcu(&smp->ltk->list);
648970d0f1bSJohan Hedberg 			kfree_rcu(smp->ltk, rcu);
6496f48e260SJohan Hedberg 		}
6506f48e260SJohan Hedberg 
6516f48e260SJohan Hedberg 		if (smp->slave_ltk) {
652970d0f1bSJohan Hedberg 			list_del_rcu(&smp->slave_ltk->list);
653970d0f1bSJohan Hedberg 			kfree_rcu(smp->slave_ltk, rcu);
6546f48e260SJohan Hedberg 		}
6556f48e260SJohan Hedberg 
6566f48e260SJohan Hedberg 		if (smp->remote_irk) {
657adae20cbSJohan Hedberg 			list_del_rcu(&smp->remote_irk->list);
658adae20cbSJohan Hedberg 			kfree_rcu(smp->remote_irk, rcu);
6596f48e260SJohan Hedberg 		}
6606f48e260SJohan Hedberg 	}
6616f48e260SJohan Hedberg 
6626f48e260SJohan Hedberg 	chan->data = NULL;
6636f48e260SJohan Hedberg 	kfree(smp);
6646f48e260SJohan Hedberg 	hci_conn_drop(conn->hcon);
6656f48e260SJohan Hedberg }
6666f48e260SJohan Hedberg 
66784794e11SJohan Hedberg static void smp_failure(struct l2cap_conn *conn, u8 reason)
6684f957a76SBrian Gix {
669bab73cb6SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
670b68fda68SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
671bab73cb6SJohan Hedberg 
67284794e11SJohan Hedberg 	if (reason)
6734f957a76SBrian Gix 		smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
6744f957a76SBrian Gix 			     &reason);
6754f957a76SBrian Gix 
676ce39fb4eSMarcel Holtmann 	clear_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags);
677e1e930f5SJohan Hedberg 	mgmt_auth_failed(hcon, HCI_ERROR_AUTH_FAILURE);
678f1c09c07SVinicius Costa Gomes 
679fc75cc86SJohan Hedberg 	if (chan->data)
6804f957a76SBrian Gix 		smp_chan_destroy(conn);
6814f957a76SBrian Gix }
6824f957a76SBrian Gix 
6832b64d153SBrian Gix #define JUST_WORKS	0x00
6842b64d153SBrian Gix #define JUST_CFM	0x01
6852b64d153SBrian Gix #define REQ_PASSKEY	0x02
6862b64d153SBrian Gix #define CFM_PASSKEY	0x03
6872b64d153SBrian Gix #define REQ_OOB		0x04
6885e3d3d9bSJohan Hedberg #define DSP_PASSKEY	0x05
6892b64d153SBrian Gix #define OVERLAP		0xFF
6902b64d153SBrian Gix 
6912b64d153SBrian Gix static const u8 gen_method[5][5] = {
6922b64d153SBrian Gix 	{ JUST_WORKS,  JUST_CFM,    REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
6932b64d153SBrian Gix 	{ JUST_WORKS,  JUST_CFM,    REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
6942b64d153SBrian Gix 	{ CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
6952b64d153SBrian Gix 	{ JUST_WORKS,  JUST_CFM,    JUST_WORKS,  JUST_WORKS, JUST_CFM    },
6962b64d153SBrian Gix 	{ CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, OVERLAP     },
6972b64d153SBrian Gix };
6982b64d153SBrian Gix 
6995e3d3d9bSJohan Hedberg static const u8 sc_method[5][5] = {
7005e3d3d9bSJohan Hedberg 	{ JUST_WORKS,  JUST_CFM,    REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
7015e3d3d9bSJohan Hedberg 	{ JUST_WORKS,  CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
7025e3d3d9bSJohan Hedberg 	{ DSP_PASSKEY, DSP_PASSKEY, REQ_PASSKEY, JUST_WORKS, DSP_PASSKEY },
7035e3d3d9bSJohan Hedberg 	{ JUST_WORKS,  JUST_CFM,    JUST_WORKS,  JUST_WORKS, JUST_CFM    },
7045e3d3d9bSJohan Hedberg 	{ DSP_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
7055e3d3d9bSJohan Hedberg };
7065e3d3d9bSJohan Hedberg 
707581370ccSJohan Hedberg static u8 get_auth_method(struct smp_chan *smp, u8 local_io, u8 remote_io)
708581370ccSJohan Hedberg {
7092bcd4003SJohan Hedberg 	/* If either side has unknown io_caps, use JUST_CFM (which gets
7102bcd4003SJohan Hedberg 	 * converted later to JUST_WORKS if we're initiators.
7112bcd4003SJohan Hedberg 	 */
712581370ccSJohan Hedberg 	if (local_io > SMP_IO_KEYBOARD_DISPLAY ||
713581370ccSJohan Hedberg 	    remote_io > SMP_IO_KEYBOARD_DISPLAY)
7142bcd4003SJohan Hedberg 		return JUST_CFM;
715581370ccSJohan Hedberg 
7165e3d3d9bSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags))
7175e3d3d9bSJohan Hedberg 		return sc_method[remote_io][local_io];
7185e3d3d9bSJohan Hedberg 
719581370ccSJohan Hedberg 	return gen_method[remote_io][local_io];
720581370ccSJohan Hedberg }
721581370ccSJohan Hedberg 
7222b64d153SBrian Gix static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
7232b64d153SBrian Gix 						u8 local_io, u8 remote_io)
7242b64d153SBrian Gix {
7252b64d153SBrian Gix 	struct hci_conn *hcon = conn->hcon;
7265d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
7275d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
7282b64d153SBrian Gix 	u32 passkey = 0;
7292b64d153SBrian Gix 	int ret = 0;
7302b64d153SBrian Gix 
7312b64d153SBrian Gix 	/* Initialize key for JUST WORKS */
7322b64d153SBrian Gix 	memset(smp->tk, 0, sizeof(smp->tk));
7334a74d658SJohan Hedberg 	clear_bit(SMP_FLAG_TK_VALID, &smp->flags);
7342b64d153SBrian Gix 
7352b64d153SBrian Gix 	BT_DBG("tk_request: auth:%d lcl:%d rem:%d", auth, local_io, remote_io);
7362b64d153SBrian Gix 
7372bcd4003SJohan Hedberg 	/* If neither side wants MITM, either "just" confirm an incoming
7382bcd4003SJohan Hedberg 	 * request or use just-works for outgoing ones. The JUST_CFM
7392bcd4003SJohan Hedberg 	 * will be converted to JUST_WORKS if necessary later in this
7402bcd4003SJohan Hedberg 	 * function. If either side has MITM look up the method from the
7412bcd4003SJohan Hedberg 	 * table.
7422bcd4003SJohan Hedberg 	 */
743581370ccSJohan Hedberg 	if (!(auth & SMP_AUTH_MITM))
744783e0574SJohan Hedberg 		smp->method = JUST_CFM;
7452b64d153SBrian Gix 	else
746783e0574SJohan Hedberg 		smp->method = get_auth_method(smp, local_io, remote_io);
7472b64d153SBrian Gix 
748a82505c7SJohan Hedberg 	/* Don't confirm locally initiated pairing attempts */
749783e0574SJohan Hedberg 	if (smp->method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR,
750783e0574SJohan Hedberg 						&smp->flags))
751783e0574SJohan Hedberg 		smp->method = JUST_WORKS;
752a82505c7SJohan Hedberg 
75302f3e254SJohan Hedberg 	/* Don't bother user space with no IO capabilities */
754783e0574SJohan Hedberg 	if (smp->method == JUST_CFM &&
755783e0574SJohan Hedberg 	    hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
756783e0574SJohan Hedberg 		smp->method = JUST_WORKS;
75702f3e254SJohan Hedberg 
7582b64d153SBrian Gix 	/* If Just Works, Continue with Zero TK */
759783e0574SJohan Hedberg 	if (smp->method == JUST_WORKS) {
7604a74d658SJohan Hedberg 		set_bit(SMP_FLAG_TK_VALID, &smp->flags);
7612b64d153SBrian Gix 		return 0;
7622b64d153SBrian Gix 	}
7632b64d153SBrian Gix 
7642b64d153SBrian Gix 	/* Not Just Works/Confirm results in MITM Authentication */
765783e0574SJohan Hedberg 	if (smp->method != JUST_CFM) {
7664a74d658SJohan Hedberg 		set_bit(SMP_FLAG_MITM_AUTH, &smp->flags);
7675eb596f5SJohan Hedberg 		if (hcon->pending_sec_level < BT_SECURITY_HIGH)
7685eb596f5SJohan Hedberg 			hcon->pending_sec_level = BT_SECURITY_HIGH;
7695eb596f5SJohan Hedberg 	}
7702b64d153SBrian Gix 
7712b64d153SBrian Gix 	/* If both devices have Keyoard-Display I/O, the master
7722b64d153SBrian Gix 	 * Confirms and the slave Enters the passkey.
7732b64d153SBrian Gix 	 */
774783e0574SJohan Hedberg 	if (smp->method == OVERLAP) {
77540bef302SJohan Hedberg 		if (hcon->role == HCI_ROLE_MASTER)
776783e0574SJohan Hedberg 			smp->method = CFM_PASSKEY;
7772b64d153SBrian Gix 		else
778783e0574SJohan Hedberg 			smp->method = REQ_PASSKEY;
7792b64d153SBrian Gix 	}
7802b64d153SBrian Gix 
78101ad34d2SJohan Hedberg 	/* Generate random passkey. */
782783e0574SJohan Hedberg 	if (smp->method == CFM_PASSKEY) {
783943a732aSJohan Hedberg 		memset(smp->tk, 0, sizeof(smp->tk));
7842b64d153SBrian Gix 		get_random_bytes(&passkey, sizeof(passkey));
7852b64d153SBrian Gix 		passkey %= 1000000;
786943a732aSJohan Hedberg 		put_unaligned_le32(passkey, smp->tk);
7872b64d153SBrian Gix 		BT_DBG("PassKey: %d", passkey);
7884a74d658SJohan Hedberg 		set_bit(SMP_FLAG_TK_VALID, &smp->flags);
7892b64d153SBrian Gix 	}
7902b64d153SBrian Gix 
791783e0574SJohan Hedberg 	if (smp->method == REQ_PASSKEY)
792ce39fb4eSMarcel Holtmann 		ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst,
793272d90dfSJohan Hedberg 						hcon->type, hcon->dst_type);
794783e0574SJohan Hedberg 	else if (smp->method == JUST_CFM)
7954eb65e66SJohan Hedberg 		ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
7964eb65e66SJohan Hedberg 						hcon->type, hcon->dst_type,
7974eb65e66SJohan Hedberg 						passkey, 1);
7982b64d153SBrian Gix 	else
79901ad34d2SJohan Hedberg 		ret = mgmt_user_passkey_notify(hcon->hdev, &hcon->dst,
800272d90dfSJohan Hedberg 						hcon->type, hcon->dst_type,
80139adbffeSJohan Hedberg 						passkey, 0);
8022b64d153SBrian Gix 
8032b64d153SBrian Gix 	return ret;
8042b64d153SBrian Gix }
8052b64d153SBrian Gix 
8061cc61144SJohan Hedberg static u8 smp_confirm(struct smp_chan *smp)
8078aab4757SVinicius Costa Gomes {
8088aab4757SVinicius Costa Gomes 	struct l2cap_conn *conn = smp->conn;
8098aab4757SVinicius Costa Gomes 	struct smp_cmd_pairing_confirm cp;
8108aab4757SVinicius Costa Gomes 	int ret;
8118aab4757SVinicius Costa Gomes 
8128aab4757SVinicius Costa Gomes 	BT_DBG("conn %p", conn);
8138aab4757SVinicius Costa Gomes 
814e491eaf3SJohan Hedberg 	ret = smp_c1(smp->tfm_aes, smp->tk, smp->prnd, smp->preq, smp->prsp,
815b1cd5fd9SJohan Hedberg 		     conn->hcon->init_addr_type, &conn->hcon->init_addr,
816943a732aSJohan Hedberg 		     conn->hcon->resp_addr_type, &conn->hcon->resp_addr,
817943a732aSJohan Hedberg 		     cp.confirm_val);
8181cc61144SJohan Hedberg 	if (ret)
8191cc61144SJohan Hedberg 		return SMP_UNSPECIFIED;
8208aab4757SVinicius Costa Gomes 
8214a74d658SJohan Hedberg 	clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
8222b64d153SBrian Gix 
8238aab4757SVinicius Costa Gomes 	smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
8248aab4757SVinicius Costa Gomes 
825b28b4943SJohan Hedberg 	if (conn->hcon->out)
826b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
827b28b4943SJohan Hedberg 	else
828b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
829b28b4943SJohan Hedberg 
8301cc61144SJohan Hedberg 	return 0;
8318aab4757SVinicius Costa Gomes }
8328aab4757SVinicius Costa Gomes 
833861580a9SJohan Hedberg static u8 smp_random(struct smp_chan *smp)
8348aab4757SVinicius Costa Gomes {
8358aab4757SVinicius Costa Gomes 	struct l2cap_conn *conn = smp->conn;
8368aab4757SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
837861580a9SJohan Hedberg 	u8 confirm[16];
8388aab4757SVinicius Costa Gomes 	int ret;
8398aab4757SVinicius Costa Gomes 
840ec70f36fSJohan Hedberg 	if (IS_ERR_OR_NULL(smp->tfm_aes))
841861580a9SJohan Hedberg 		return SMP_UNSPECIFIED;
8428aab4757SVinicius Costa Gomes 
8438aab4757SVinicius Costa Gomes 	BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
8448aab4757SVinicius Costa Gomes 
845e491eaf3SJohan Hedberg 	ret = smp_c1(smp->tfm_aes, smp->tk, smp->rrnd, smp->preq, smp->prsp,
846b1cd5fd9SJohan Hedberg 		     hcon->init_addr_type, &hcon->init_addr,
847943a732aSJohan Hedberg 		     hcon->resp_addr_type, &hcon->resp_addr, confirm);
848861580a9SJohan Hedberg 	if (ret)
849861580a9SJohan Hedberg 		return SMP_UNSPECIFIED;
8508aab4757SVinicius Costa Gomes 
8518aab4757SVinicius Costa Gomes 	if (memcmp(smp->pcnf, confirm, sizeof(smp->pcnf)) != 0) {
8528aab4757SVinicius Costa Gomes 		BT_ERR("Pairing failed (confirmation values mismatch)");
853861580a9SJohan Hedberg 		return SMP_CONFIRM_FAILED;
8548aab4757SVinicius Costa Gomes 	}
8558aab4757SVinicius Costa Gomes 
8568aab4757SVinicius Costa Gomes 	if (hcon->out) {
857fe39c7b2SMarcel Holtmann 		u8 stk[16];
858fe39c7b2SMarcel Holtmann 		__le64 rand = 0;
859fe39c7b2SMarcel Holtmann 		__le16 ediv = 0;
8608aab4757SVinicius Costa Gomes 
861e491eaf3SJohan Hedberg 		smp_s1(smp->tfm_aes, smp->tk, smp->rrnd, smp->prnd, stk);
8628aab4757SVinicius Costa Gomes 
863f7aa611aSVinicius Costa Gomes 		memset(stk + smp->enc_key_size, 0,
864f7aa611aSVinicius Costa Gomes 		       SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
8658aab4757SVinicius Costa Gomes 
866861580a9SJohan Hedberg 		if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
867861580a9SJohan Hedberg 			return SMP_UNSPECIFIED;
8688aab4757SVinicius Costa Gomes 
8698aab4757SVinicius Costa Gomes 		hci_le_start_enc(hcon, ediv, rand, stk);
870f7aa611aSVinicius Costa Gomes 		hcon->enc_key_size = smp->enc_key_size;
871fe59a05fSJohan Hedberg 		set_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags);
8728aab4757SVinicius Costa Gomes 	} else {
873fff3490fSJohan Hedberg 		u8 stk[16], auth;
874fe39c7b2SMarcel Holtmann 		__le64 rand = 0;
875fe39c7b2SMarcel Holtmann 		__le16 ediv = 0;
8768aab4757SVinicius Costa Gomes 
877943a732aSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
878943a732aSJohan Hedberg 			     smp->prnd);
8798aab4757SVinicius Costa Gomes 
880e491eaf3SJohan Hedberg 		smp_s1(smp->tfm_aes, smp->tk, smp->prnd, smp->rrnd, stk);
8818aab4757SVinicius Costa Gomes 
882f7aa611aSVinicius Costa Gomes 		memset(stk + smp->enc_key_size, 0,
883f7aa611aSVinicius Costa Gomes 		       SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
8848aab4757SVinicius Costa Gomes 
885fff3490fSJohan Hedberg 		if (hcon->pending_sec_level == BT_SECURITY_HIGH)
886fff3490fSJohan Hedberg 			auth = 1;
887fff3490fSJohan Hedberg 		else
888fff3490fSJohan Hedberg 			auth = 0;
889fff3490fSJohan Hedberg 
8907d5843b7SJohan Hedberg 		/* Even though there's no _SLAVE suffix this is the
8917d5843b7SJohan Hedberg 		 * slave STK we're adding for later lookup (the master
8927d5843b7SJohan Hedberg 		 * STK never needs to be stored).
8937d5843b7SJohan Hedberg 		 */
894ce39fb4eSMarcel Holtmann 		hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
8952ceba539SJohan Hedberg 			    SMP_STK, auth, stk, smp->enc_key_size, ediv, rand);
8968aab4757SVinicius Costa Gomes 	}
8978aab4757SVinicius Costa Gomes 
898861580a9SJohan Hedberg 	return 0;
8998aab4757SVinicius Costa Gomes }
9008aab4757SVinicius Costa Gomes 
90144f1a7abSJohan Hedberg static void smp_notify_keys(struct l2cap_conn *conn)
90244f1a7abSJohan Hedberg {
90344f1a7abSJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
90444f1a7abSJohan Hedberg 	struct smp_chan *smp = chan->data;
90544f1a7abSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
90644f1a7abSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
90744f1a7abSJohan Hedberg 	struct smp_cmd_pairing *req = (void *) &smp->preq[1];
90844f1a7abSJohan Hedberg 	struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1];
90944f1a7abSJohan Hedberg 	bool persistent;
91044f1a7abSJohan Hedberg 
91144f1a7abSJohan Hedberg 	if (smp->remote_irk) {
91244f1a7abSJohan Hedberg 		mgmt_new_irk(hdev, smp->remote_irk);
91344f1a7abSJohan Hedberg 		/* Now that user space can be considered to know the
91444f1a7abSJohan Hedberg 		 * identity address track the connection based on it
91544f1a7abSJohan Hedberg 		 * from now on.
91644f1a7abSJohan Hedberg 		 */
91744f1a7abSJohan Hedberg 		bacpy(&hcon->dst, &smp->remote_irk->bdaddr);
91844f1a7abSJohan Hedberg 		hcon->dst_type = smp->remote_irk->addr_type;
919f3d82d0cSJohan Hedberg 		queue_work(hdev->workqueue, &conn->id_addr_update_work);
92044f1a7abSJohan Hedberg 
92144f1a7abSJohan Hedberg 		/* When receiving an indentity resolving key for
92244f1a7abSJohan Hedberg 		 * a remote device that does not use a resolvable
92344f1a7abSJohan Hedberg 		 * private address, just remove the key so that
92444f1a7abSJohan Hedberg 		 * it is possible to use the controller white
92544f1a7abSJohan Hedberg 		 * list for scanning.
92644f1a7abSJohan Hedberg 		 *
92744f1a7abSJohan Hedberg 		 * Userspace will have been told to not store
92844f1a7abSJohan Hedberg 		 * this key at this point. So it is safe to
92944f1a7abSJohan Hedberg 		 * just remove it.
93044f1a7abSJohan Hedberg 		 */
93144f1a7abSJohan Hedberg 		if (!bacmp(&smp->remote_irk->rpa, BDADDR_ANY)) {
932adae20cbSJohan Hedberg 			list_del_rcu(&smp->remote_irk->list);
933adae20cbSJohan Hedberg 			kfree_rcu(smp->remote_irk, rcu);
93444f1a7abSJohan Hedberg 			smp->remote_irk = NULL;
93544f1a7abSJohan Hedberg 		}
93644f1a7abSJohan Hedberg 	}
93744f1a7abSJohan Hedberg 
93844f1a7abSJohan Hedberg 	/* The LTKs and CSRKs should be persistent only if both sides
93944f1a7abSJohan Hedberg 	 * had the bonding bit set in their authentication requests.
94044f1a7abSJohan Hedberg 	 */
94144f1a7abSJohan Hedberg 	persistent = !!((req->auth_req & rsp->auth_req) & SMP_AUTH_BONDING);
94244f1a7abSJohan Hedberg 
94344f1a7abSJohan Hedberg 	if (smp->csrk) {
94444f1a7abSJohan Hedberg 		smp->csrk->bdaddr_type = hcon->dst_type;
94544f1a7abSJohan Hedberg 		bacpy(&smp->csrk->bdaddr, &hcon->dst);
94644f1a7abSJohan Hedberg 		mgmt_new_csrk(hdev, smp->csrk, persistent);
94744f1a7abSJohan Hedberg 	}
94844f1a7abSJohan Hedberg 
94944f1a7abSJohan Hedberg 	if (smp->slave_csrk) {
95044f1a7abSJohan Hedberg 		smp->slave_csrk->bdaddr_type = hcon->dst_type;
95144f1a7abSJohan Hedberg 		bacpy(&smp->slave_csrk->bdaddr, &hcon->dst);
95244f1a7abSJohan Hedberg 		mgmt_new_csrk(hdev, smp->slave_csrk, persistent);
95344f1a7abSJohan Hedberg 	}
95444f1a7abSJohan Hedberg 
95544f1a7abSJohan Hedberg 	if (smp->ltk) {
95644f1a7abSJohan Hedberg 		smp->ltk->bdaddr_type = hcon->dst_type;
95744f1a7abSJohan Hedberg 		bacpy(&smp->ltk->bdaddr, &hcon->dst);
95844f1a7abSJohan Hedberg 		mgmt_new_ltk(hdev, smp->ltk, persistent);
95944f1a7abSJohan Hedberg 	}
96044f1a7abSJohan Hedberg 
96144f1a7abSJohan Hedberg 	if (smp->slave_ltk) {
96244f1a7abSJohan Hedberg 		smp->slave_ltk->bdaddr_type = hcon->dst_type;
96344f1a7abSJohan Hedberg 		bacpy(&smp->slave_ltk->bdaddr, &hcon->dst);
96444f1a7abSJohan Hedberg 		mgmt_new_ltk(hdev, smp->slave_ltk, persistent);
96544f1a7abSJohan Hedberg 	}
9666a77083aSJohan Hedberg 
9676a77083aSJohan Hedberg 	if (smp->link_key) {
9686a77083aSJohan Hedberg 		hci_add_link_key(hdev, smp->conn->hcon, &hcon->dst,
9696a77083aSJohan Hedberg 				 smp->link_key, HCI_LK_AUTH_COMBINATION_P256,
9706a77083aSJohan Hedberg 				 0, NULL);
9716a77083aSJohan Hedberg 	}
9726a77083aSJohan Hedberg }
9736a77083aSJohan Hedberg 
9746a77083aSJohan Hedberg static void sc_generate_link_key(struct smp_chan *smp)
9756a77083aSJohan Hedberg {
9766a77083aSJohan Hedberg 	/* These constants are as specified in the core specification.
9776a77083aSJohan Hedberg 	 * In ASCII they spell out to 'tmp1' and 'lebr'.
9786a77083aSJohan Hedberg 	 */
9796a77083aSJohan Hedberg 	const u8 tmp1[4] = { 0x31, 0x70, 0x6d, 0x74 };
9806a77083aSJohan Hedberg 	const u8 lebr[4] = { 0x72, 0x62, 0x65, 0x6c };
9816a77083aSJohan Hedberg 
9826a77083aSJohan Hedberg 	smp->link_key = kzalloc(16, GFP_KERNEL);
9836a77083aSJohan Hedberg 	if (!smp->link_key)
9846a77083aSJohan Hedberg 		return;
9856a77083aSJohan Hedberg 
9866a77083aSJohan Hedberg 	if (smp_h6(smp->tfm_cmac, smp->tk, tmp1, smp->link_key)) {
9876a77083aSJohan Hedberg 		kfree(smp->link_key);
9886a77083aSJohan Hedberg 		smp->link_key = NULL;
9896a77083aSJohan Hedberg 		return;
9906a77083aSJohan Hedberg 	}
9916a77083aSJohan Hedberg 
9926a77083aSJohan Hedberg 	if (smp_h6(smp->tfm_cmac, smp->link_key, lebr, smp->link_key)) {
9936a77083aSJohan Hedberg 		kfree(smp->link_key);
9946a77083aSJohan Hedberg 		smp->link_key = NULL;
9956a77083aSJohan Hedberg 		return;
9966a77083aSJohan Hedberg 	}
99744f1a7abSJohan Hedberg }
99844f1a7abSJohan Hedberg 
999b28b4943SJohan Hedberg static void smp_allow_key_dist(struct smp_chan *smp)
1000b28b4943SJohan Hedberg {
1001b28b4943SJohan Hedberg 	/* Allow the first expected phase 3 PDU. The rest of the PDUs
1002b28b4943SJohan Hedberg 	 * will be allowed in each PDU handler to ensure we receive
1003b28b4943SJohan Hedberg 	 * them in the correct order.
1004b28b4943SJohan Hedberg 	 */
1005b28b4943SJohan Hedberg 	if (smp->remote_key_dist & SMP_DIST_ENC_KEY)
1006b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_ENCRYPT_INFO);
1007b28b4943SJohan Hedberg 	else if (smp->remote_key_dist & SMP_DIST_ID_KEY)
1008b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO);
1009b28b4943SJohan Hedberg 	else if (smp->remote_key_dist & SMP_DIST_SIGN)
1010b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO);
1011b28b4943SJohan Hedberg }
1012b28b4943SJohan Hedberg 
1013d6268e86SJohan Hedberg static void smp_distribute_keys(struct smp_chan *smp)
101444f1a7abSJohan Hedberg {
101544f1a7abSJohan Hedberg 	struct smp_cmd_pairing *req, *rsp;
101686d1407cSJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
101744f1a7abSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
101844f1a7abSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
101944f1a7abSJohan Hedberg 	__u8 *keydist;
102044f1a7abSJohan Hedberg 
102144f1a7abSJohan Hedberg 	BT_DBG("conn %p", conn);
102244f1a7abSJohan Hedberg 
102344f1a7abSJohan Hedberg 	rsp = (void *) &smp->prsp[1];
102444f1a7abSJohan Hedberg 
102544f1a7abSJohan Hedberg 	/* The responder sends its keys first */
1026b28b4943SJohan Hedberg 	if (hcon->out && (smp->remote_key_dist & KEY_DIST_MASK)) {
1027b28b4943SJohan Hedberg 		smp_allow_key_dist(smp);
102886d1407cSJohan Hedberg 		return;
1029b28b4943SJohan Hedberg 	}
103044f1a7abSJohan Hedberg 
103144f1a7abSJohan Hedberg 	req = (void *) &smp->preq[1];
103244f1a7abSJohan Hedberg 
103344f1a7abSJohan Hedberg 	if (hcon->out) {
103444f1a7abSJohan Hedberg 		keydist = &rsp->init_key_dist;
103544f1a7abSJohan Hedberg 		*keydist &= req->init_key_dist;
103644f1a7abSJohan Hedberg 	} else {
103744f1a7abSJohan Hedberg 		keydist = &rsp->resp_key_dist;
103844f1a7abSJohan Hedberg 		*keydist &= req->resp_key_dist;
103944f1a7abSJohan Hedberg 	}
104044f1a7abSJohan Hedberg 
10416a77083aSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
10426a77083aSJohan Hedberg 		if (*keydist & SMP_DIST_LINK_KEY)
10436a77083aSJohan Hedberg 			sc_generate_link_key(smp);
10446a77083aSJohan Hedberg 
10456a77083aSJohan Hedberg 		/* Clear the keys which are generated but not distributed */
10466a77083aSJohan Hedberg 		*keydist &= ~SMP_SC_NO_DIST;
10476a77083aSJohan Hedberg 	}
10486a77083aSJohan Hedberg 
104944f1a7abSJohan Hedberg 	BT_DBG("keydist 0x%x", *keydist);
105044f1a7abSJohan Hedberg 
105144f1a7abSJohan Hedberg 	if (*keydist & SMP_DIST_ENC_KEY) {
105244f1a7abSJohan Hedberg 		struct smp_cmd_encrypt_info enc;
105344f1a7abSJohan Hedberg 		struct smp_cmd_master_ident ident;
105444f1a7abSJohan Hedberg 		struct smp_ltk *ltk;
105544f1a7abSJohan Hedberg 		u8 authenticated;
105644f1a7abSJohan Hedberg 		__le16 ediv;
105744f1a7abSJohan Hedberg 		__le64 rand;
105844f1a7abSJohan Hedberg 
105944f1a7abSJohan Hedberg 		get_random_bytes(enc.ltk, sizeof(enc.ltk));
106044f1a7abSJohan Hedberg 		get_random_bytes(&ediv, sizeof(ediv));
106144f1a7abSJohan Hedberg 		get_random_bytes(&rand, sizeof(rand));
106244f1a7abSJohan Hedberg 
106344f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
106444f1a7abSJohan Hedberg 
106544f1a7abSJohan Hedberg 		authenticated = hcon->sec_level == BT_SECURITY_HIGH;
106644f1a7abSJohan Hedberg 		ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type,
106744f1a7abSJohan Hedberg 				  SMP_LTK_SLAVE, authenticated, enc.ltk,
106844f1a7abSJohan Hedberg 				  smp->enc_key_size, ediv, rand);
106944f1a7abSJohan Hedberg 		smp->slave_ltk = ltk;
107044f1a7abSJohan Hedberg 
107144f1a7abSJohan Hedberg 		ident.ediv = ediv;
107244f1a7abSJohan Hedberg 		ident.rand = rand;
107344f1a7abSJohan Hedberg 
107444f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident);
107544f1a7abSJohan Hedberg 
107644f1a7abSJohan Hedberg 		*keydist &= ~SMP_DIST_ENC_KEY;
107744f1a7abSJohan Hedberg 	}
107844f1a7abSJohan Hedberg 
107944f1a7abSJohan Hedberg 	if (*keydist & SMP_DIST_ID_KEY) {
108044f1a7abSJohan Hedberg 		struct smp_cmd_ident_addr_info addrinfo;
108144f1a7abSJohan Hedberg 		struct smp_cmd_ident_info idinfo;
108244f1a7abSJohan Hedberg 
108344f1a7abSJohan Hedberg 		memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk));
108444f1a7abSJohan Hedberg 
108544f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo);
108644f1a7abSJohan Hedberg 
108744f1a7abSJohan Hedberg 		/* The hci_conn contains the local identity address
108844f1a7abSJohan Hedberg 		 * after the connection has been established.
108944f1a7abSJohan Hedberg 		 *
109044f1a7abSJohan Hedberg 		 * This is true even when the connection has been
109144f1a7abSJohan Hedberg 		 * established using a resolvable random address.
109244f1a7abSJohan Hedberg 		 */
109344f1a7abSJohan Hedberg 		bacpy(&addrinfo.bdaddr, &hcon->src);
109444f1a7abSJohan Hedberg 		addrinfo.addr_type = hcon->src_type;
109544f1a7abSJohan Hedberg 
109644f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo),
109744f1a7abSJohan Hedberg 			     &addrinfo);
109844f1a7abSJohan Hedberg 
109944f1a7abSJohan Hedberg 		*keydist &= ~SMP_DIST_ID_KEY;
110044f1a7abSJohan Hedberg 	}
110144f1a7abSJohan Hedberg 
110244f1a7abSJohan Hedberg 	if (*keydist & SMP_DIST_SIGN) {
110344f1a7abSJohan Hedberg 		struct smp_cmd_sign_info sign;
110444f1a7abSJohan Hedberg 		struct smp_csrk *csrk;
110544f1a7abSJohan Hedberg 
110644f1a7abSJohan Hedberg 		/* Generate a new random key */
110744f1a7abSJohan Hedberg 		get_random_bytes(sign.csrk, sizeof(sign.csrk));
110844f1a7abSJohan Hedberg 
110944f1a7abSJohan Hedberg 		csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
111044f1a7abSJohan Hedberg 		if (csrk) {
111144f1a7abSJohan Hedberg 			csrk->master = 0x00;
111244f1a7abSJohan Hedberg 			memcpy(csrk->val, sign.csrk, sizeof(csrk->val));
111344f1a7abSJohan Hedberg 		}
111444f1a7abSJohan Hedberg 		smp->slave_csrk = csrk;
111544f1a7abSJohan Hedberg 
111644f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign);
111744f1a7abSJohan Hedberg 
111844f1a7abSJohan Hedberg 		*keydist &= ~SMP_DIST_SIGN;
111944f1a7abSJohan Hedberg 	}
112044f1a7abSJohan Hedberg 
112144f1a7abSJohan Hedberg 	/* If there are still keys to be received wait for them */
1122b28b4943SJohan Hedberg 	if (smp->remote_key_dist & KEY_DIST_MASK) {
1123b28b4943SJohan Hedberg 		smp_allow_key_dist(smp);
112486d1407cSJohan Hedberg 		return;
1125b28b4943SJohan Hedberg 	}
112644f1a7abSJohan Hedberg 
112744f1a7abSJohan Hedberg 	set_bit(SMP_FLAG_COMPLETE, &smp->flags);
112844f1a7abSJohan Hedberg 	smp_notify_keys(conn);
112944f1a7abSJohan Hedberg 
113044f1a7abSJohan Hedberg 	smp_chan_destroy(conn);
113144f1a7abSJohan Hedberg }
113244f1a7abSJohan Hedberg 
1133b68fda68SJohan Hedberg static void smp_timeout(struct work_struct *work)
1134b68fda68SJohan Hedberg {
1135b68fda68SJohan Hedberg 	struct smp_chan *smp = container_of(work, struct smp_chan,
1136b68fda68SJohan Hedberg 					    security_timer.work);
1137b68fda68SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
1138b68fda68SJohan Hedberg 
1139b68fda68SJohan Hedberg 	BT_DBG("conn %p", conn);
1140b68fda68SJohan Hedberg 
11411e91c29eSJohan Hedberg 	hci_disconnect(conn->hcon, HCI_ERROR_REMOTE_USER_TERM);
1142b68fda68SJohan Hedberg }
1143b68fda68SJohan Hedberg 
11448aab4757SVinicius Costa Gomes static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
11458aab4757SVinicius Costa Gomes {
11465d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
11478aab4757SVinicius Costa Gomes 	struct smp_chan *smp;
11488aab4757SVinicius Costa Gomes 
1149f1560463SMarcel Holtmann 	smp = kzalloc(sizeof(*smp), GFP_ATOMIC);
1150fc75cc86SJohan Hedberg 	if (!smp)
11518aab4757SVinicius Costa Gomes 		return NULL;
11528aab4757SVinicius Costa Gomes 
11536a7bd103SJohan Hedberg 	smp->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
11546a7bd103SJohan Hedberg 	if (IS_ERR(smp->tfm_aes)) {
11556a7bd103SJohan Hedberg 		BT_ERR("Unable to create ECB crypto context");
11566a7bd103SJohan Hedberg 		kfree(smp);
11576a7bd103SJohan Hedberg 		return NULL;
11586a7bd103SJohan Hedberg 	}
11596a7bd103SJohan Hedberg 
1160407cecf6SJohan Hedberg 	smp->tfm_cmac = crypto_alloc_hash("cmac(aes)", 0, CRYPTO_ALG_ASYNC);
1161407cecf6SJohan Hedberg 	if (IS_ERR(smp->tfm_cmac)) {
1162407cecf6SJohan Hedberg 		BT_ERR("Unable to create CMAC crypto context");
1163407cecf6SJohan Hedberg 		crypto_free_blkcipher(smp->tfm_aes);
1164407cecf6SJohan Hedberg 		kfree(smp);
1165407cecf6SJohan Hedberg 		return NULL;
1166407cecf6SJohan Hedberg 	}
1167407cecf6SJohan Hedberg 
11688aab4757SVinicius Costa Gomes 	smp->conn = conn;
11695d88cc73SJohan Hedberg 	chan->data = smp;
11708aab4757SVinicius Costa Gomes 
1171b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_FAIL);
1172b28b4943SJohan Hedberg 
1173b68fda68SJohan Hedberg 	INIT_DELAYED_WORK(&smp->security_timer, smp_timeout);
1174b68fda68SJohan Hedberg 
11758aab4757SVinicius Costa Gomes 	hci_conn_hold(conn->hcon);
11768aab4757SVinicius Costa Gomes 
11778aab4757SVinicius Costa Gomes 	return smp;
11788aab4757SVinicius Costa Gomes }
11798aab4757SVinicius Costa Gomes 
1180760b018bSJohan Hedberg static int sc_mackey_and_ltk(struct smp_chan *smp, u8 mackey[16], u8 ltk[16])
1181760b018bSJohan Hedberg {
1182760b018bSJohan Hedberg 	struct hci_conn *hcon = smp->conn->hcon;
1183760b018bSJohan Hedberg 	u8 *na, *nb, a[7], b[7];
1184760b018bSJohan Hedberg 
1185760b018bSJohan Hedberg 	if (hcon->out) {
1186760b018bSJohan Hedberg 		na   = smp->prnd;
1187760b018bSJohan Hedberg 		nb   = smp->rrnd;
1188760b018bSJohan Hedberg 	} else {
1189760b018bSJohan Hedberg 		na   = smp->rrnd;
1190760b018bSJohan Hedberg 		nb   = smp->prnd;
1191760b018bSJohan Hedberg 	}
1192760b018bSJohan Hedberg 
1193760b018bSJohan Hedberg 	memcpy(a, &hcon->init_addr, 6);
1194760b018bSJohan Hedberg 	memcpy(b, &hcon->resp_addr, 6);
1195760b018bSJohan Hedberg 	a[6] = hcon->init_addr_type;
1196760b018bSJohan Hedberg 	b[6] = hcon->resp_addr_type;
1197760b018bSJohan Hedberg 
1198760b018bSJohan Hedberg 	return smp_f5(smp->tfm_cmac, smp->dhkey, na, nb, a, b, mackey, ltk);
1199760b018bSJohan Hedberg }
1200760b018bSJohan Hedberg 
1201760b018bSJohan Hedberg static int sc_user_reply(struct smp_chan *smp, u16 mgmt_op, __le32 passkey)
1202760b018bSJohan Hedberg {
1203760b018bSJohan Hedberg 	struct hci_conn *hcon = smp->conn->hcon;
1204760b018bSJohan Hedberg 	struct smp_cmd_dhkey_check check;
1205760b018bSJohan Hedberg 	u8 a[7], b[7], *local_addr, *remote_addr;
1206760b018bSJohan Hedberg 	u8 io_cap[3], r[16];
1207760b018bSJohan Hedberg 
1208760b018bSJohan Hedberg 	switch (mgmt_op) {
1209760b018bSJohan Hedberg 	case MGMT_OP_USER_PASSKEY_NEG_REPLY:
1210760b018bSJohan Hedberg 		smp_failure(smp->conn, SMP_PASSKEY_ENTRY_FAILED);
1211760b018bSJohan Hedberg 		return 0;
1212760b018bSJohan Hedberg 	case MGMT_OP_USER_CONFIRM_NEG_REPLY:
1213760b018bSJohan Hedberg 		smp_failure(smp->conn, SMP_NUMERIC_COMP_FAILED);
1214760b018bSJohan Hedberg 		return 0;
1215760b018bSJohan Hedberg 	}
1216760b018bSJohan Hedberg 
1217760b018bSJohan Hedberg 	memcpy(a, &hcon->init_addr, 6);
1218760b018bSJohan Hedberg 	memcpy(b, &hcon->resp_addr, 6);
1219760b018bSJohan Hedberg 	a[6] = hcon->init_addr_type;
1220760b018bSJohan Hedberg 	b[6] = hcon->resp_addr_type;
1221760b018bSJohan Hedberg 
1222760b018bSJohan Hedberg 	if (hcon->out) {
1223760b018bSJohan Hedberg 		local_addr = a;
1224760b018bSJohan Hedberg 		remote_addr = b;
1225760b018bSJohan Hedberg 		memcpy(io_cap, &smp->preq[1], 3);
1226760b018bSJohan Hedberg 	} else {
1227760b018bSJohan Hedberg 		local_addr = b;
1228760b018bSJohan Hedberg 		remote_addr = a;
1229760b018bSJohan Hedberg 		memcpy(io_cap, &smp->prsp[1], 3);
1230760b018bSJohan Hedberg 	}
1231760b018bSJohan Hedberg 
1232760b018bSJohan Hedberg 	memcpy(r, &passkey, sizeof(passkey));
1233760b018bSJohan Hedberg 	memset(r + sizeof(passkey), 0, sizeof(r) - sizeof(passkey));
1234760b018bSJohan Hedberg 
1235760b018bSJohan Hedberg 	smp_f6(smp->tfm_cmac, smp->mackey, smp->prnd, smp->rrnd, r, io_cap,
1236760b018bSJohan Hedberg 	       local_addr, remote_addr, check.e);
1237760b018bSJohan Hedberg 
1238760b018bSJohan Hedberg 	smp_send_cmd(smp->conn, SMP_CMD_DHKEY_CHECK, sizeof(check), &check);
1239760b018bSJohan Hedberg 
1240760b018bSJohan Hedberg 	return 0;
1241760b018bSJohan Hedberg }
1242760b018bSJohan Hedberg 
12432b64d153SBrian Gix int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
12442b64d153SBrian Gix {
1245b10e8017SJohan Hedberg 	struct l2cap_conn *conn = hcon->l2cap_data;
12465d88cc73SJohan Hedberg 	struct l2cap_chan *chan;
12472b64d153SBrian Gix 	struct smp_chan *smp;
12482b64d153SBrian Gix 	u32 value;
1249fc75cc86SJohan Hedberg 	int err;
12502b64d153SBrian Gix 
12512b64d153SBrian Gix 	BT_DBG("");
12522b64d153SBrian Gix 
1253fc75cc86SJohan Hedberg 	if (!conn)
12542b64d153SBrian Gix 		return -ENOTCONN;
12552b64d153SBrian Gix 
12565d88cc73SJohan Hedberg 	chan = conn->smp;
12575d88cc73SJohan Hedberg 	if (!chan)
12585d88cc73SJohan Hedberg 		return -ENOTCONN;
12595d88cc73SJohan Hedberg 
1260fc75cc86SJohan Hedberg 	l2cap_chan_lock(chan);
1261fc75cc86SJohan Hedberg 	if (!chan->data) {
1262fc75cc86SJohan Hedberg 		err = -ENOTCONN;
1263fc75cc86SJohan Hedberg 		goto unlock;
1264fc75cc86SJohan Hedberg 	}
1265fc75cc86SJohan Hedberg 
12665d88cc73SJohan Hedberg 	smp = chan->data;
12672b64d153SBrian Gix 
1268760b018bSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
1269760b018bSJohan Hedberg 		err = sc_user_reply(smp, mgmt_op, passkey);
1270760b018bSJohan Hedberg 		goto unlock;
1271760b018bSJohan Hedberg 	}
1272760b018bSJohan Hedberg 
12732b64d153SBrian Gix 	switch (mgmt_op) {
12742b64d153SBrian Gix 	case MGMT_OP_USER_PASSKEY_REPLY:
12752b64d153SBrian Gix 		value = le32_to_cpu(passkey);
1276943a732aSJohan Hedberg 		memset(smp->tk, 0, sizeof(smp->tk));
12772b64d153SBrian Gix 		BT_DBG("PassKey: %d", value);
1278943a732aSJohan Hedberg 		put_unaligned_le32(value, smp->tk);
12792b64d153SBrian Gix 		/* Fall Through */
12802b64d153SBrian Gix 	case MGMT_OP_USER_CONFIRM_REPLY:
12814a74d658SJohan Hedberg 		set_bit(SMP_FLAG_TK_VALID, &smp->flags);
12822b64d153SBrian Gix 		break;
12832b64d153SBrian Gix 	case MGMT_OP_USER_PASSKEY_NEG_REPLY:
12842b64d153SBrian Gix 	case MGMT_OP_USER_CONFIRM_NEG_REPLY:
128584794e11SJohan Hedberg 		smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
1286fc75cc86SJohan Hedberg 		err = 0;
1287fc75cc86SJohan Hedberg 		goto unlock;
12882b64d153SBrian Gix 	default:
128984794e11SJohan Hedberg 		smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
1290fc75cc86SJohan Hedberg 		err = -EOPNOTSUPP;
1291fc75cc86SJohan Hedberg 		goto unlock;
12922b64d153SBrian Gix 	}
12932b64d153SBrian Gix 
1294fc75cc86SJohan Hedberg 	err = 0;
1295fc75cc86SJohan Hedberg 
12962b64d153SBrian Gix 	/* If it is our turn to send Pairing Confirm, do so now */
12971cc61144SJohan Hedberg 	if (test_bit(SMP_FLAG_CFM_PENDING, &smp->flags)) {
12981cc61144SJohan Hedberg 		u8 rsp = smp_confirm(smp);
12991cc61144SJohan Hedberg 		if (rsp)
13001cc61144SJohan Hedberg 			smp_failure(conn, rsp);
13011cc61144SJohan Hedberg 	}
13022b64d153SBrian Gix 
1303fc75cc86SJohan Hedberg unlock:
1304fc75cc86SJohan Hedberg 	l2cap_chan_unlock(chan);
1305fc75cc86SJohan Hedberg 	return err;
13062b64d153SBrian Gix }
13072b64d153SBrian Gix 
1308da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
130988ba43b6SAnderson Briglia {
13103158c50cSVinicius Costa Gomes 	struct smp_cmd_pairing rsp, *req = (void *) skb->data;
1311fc75cc86SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
1312b3c6410bSJohan Hedberg 	struct hci_dev *hdev = conn->hcon->hdev;
13138aab4757SVinicius Costa Gomes 	struct smp_chan *smp;
1314c7262e71SJohan Hedberg 	u8 key_size, auth, sec_level;
13158aab4757SVinicius Costa Gomes 	int ret;
131688ba43b6SAnderson Briglia 
131788ba43b6SAnderson Briglia 	BT_DBG("conn %p", conn);
131888ba43b6SAnderson Briglia 
1319c46b98beSJohan Hedberg 	if (skb->len < sizeof(*req))
132038e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1321c46b98beSJohan Hedberg 
132240bef302SJohan Hedberg 	if (conn->hcon->role != HCI_ROLE_SLAVE)
13232b64d153SBrian Gix 		return SMP_CMD_NOTSUPP;
13242b64d153SBrian Gix 
1325fc75cc86SJohan Hedberg 	if (!chan->data)
13268aab4757SVinicius Costa Gomes 		smp = smp_chan_create(conn);
1327fc75cc86SJohan Hedberg 	else
13285d88cc73SJohan Hedberg 		smp = chan->data;
1329d26a2345SVinicius Costa Gomes 
1330d08fd0e7SAndrei Emeltchenko 	if (!smp)
1331d08fd0e7SAndrei Emeltchenko 		return SMP_UNSPECIFIED;
1332d08fd0e7SAndrei Emeltchenko 
1333c05b9339SJohan Hedberg 	/* We didn't start the pairing, so match remote */
13340edb14deSJohan Hedberg 	auth = req->auth_req & AUTH_REQ_MASK(hdev);
1335c05b9339SJohan Hedberg 
1336b6ae8457SJohan Hedberg 	if (!test_bit(HCI_BONDABLE, &hdev->dev_flags) &&
1337c05b9339SJohan Hedberg 	    (auth & SMP_AUTH_BONDING))
1338b3c6410bSJohan Hedberg 		return SMP_PAIRING_NOTSUPP;
1339b3c6410bSJohan Hedberg 
13401c1def09SVinicius Costa Gomes 	smp->preq[0] = SMP_CMD_PAIRING_REQ;
13411c1def09SVinicius Costa Gomes 	memcpy(&smp->preq[1], req, sizeof(*req));
13423158c50cSVinicius Costa Gomes 	skb_pull(skb, sizeof(*req));
134388ba43b6SAnderson Briglia 
13445e3d3d9bSJohan Hedberg 	build_pairing_cmd(conn, req, &rsp, auth);
13455e3d3d9bSJohan Hedberg 
13465e3d3d9bSJohan Hedberg 	if (rsp.auth_req & SMP_AUTH_SC)
13475e3d3d9bSJohan Hedberg 		set_bit(SMP_FLAG_SC, &smp->flags);
13485e3d3d9bSJohan Hedberg 
13495be5e275SJohan Hedberg 	if (conn->hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
13501afc2a1aSJohan Hedberg 		sec_level = BT_SECURITY_MEDIUM;
13511afc2a1aSJohan Hedberg 	else
1352c7262e71SJohan Hedberg 		sec_level = authreq_to_seclevel(auth);
13531afc2a1aSJohan Hedberg 
1354c7262e71SJohan Hedberg 	if (sec_level > conn->hcon->pending_sec_level)
1355c7262e71SJohan Hedberg 		conn->hcon->pending_sec_level = sec_level;
1356fdde0a26SIdo Yariv 
135749c922bbSStephen Hemminger 	/* If we need MITM check that it can be achieved */
13582ed8f65cSJohan Hedberg 	if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
13592ed8f65cSJohan Hedberg 		u8 method;
13602ed8f65cSJohan Hedberg 
13612ed8f65cSJohan Hedberg 		method = get_auth_method(smp, conn->hcon->io_capability,
13622ed8f65cSJohan Hedberg 					 req->io_capability);
13632ed8f65cSJohan Hedberg 		if (method == JUST_WORKS || method == JUST_CFM)
13642ed8f65cSJohan Hedberg 			return SMP_AUTH_REQUIREMENTS;
13652ed8f65cSJohan Hedberg 	}
13662ed8f65cSJohan Hedberg 
13673158c50cSVinicius Costa Gomes 	key_size = min(req->max_key_size, rsp.max_key_size);
13683158c50cSVinicius Costa Gomes 	if (check_enc_key_size(conn, key_size))
13693158c50cSVinicius Costa Gomes 		return SMP_ENC_KEY_SIZE;
137088ba43b6SAnderson Briglia 
1371e84a6b13SJohan Hedberg 	get_random_bytes(smp->prnd, sizeof(smp->prnd));
13728aab4757SVinicius Costa Gomes 
13731c1def09SVinicius Costa Gomes 	smp->prsp[0] = SMP_CMD_PAIRING_RSP;
13741c1def09SVinicius Costa Gomes 	memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
1375f01ead31SAnderson Briglia 
13763158c50cSVinicius Costa Gomes 	smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
13773b19146dSJohan Hedberg 
13783b19146dSJohan Hedberg 	clear_bit(SMP_FLAG_INITIATOR, &smp->flags);
13793b19146dSJohan Hedberg 
13803b19146dSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
13813b19146dSJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PUBLIC_KEY);
13823b19146dSJohan Hedberg 		/* Clear bits which are generated but not distributed */
13833b19146dSJohan Hedberg 		smp->remote_key_dist &= ~SMP_SC_NO_DIST;
13843b19146dSJohan Hedberg 		/* Wait for Public Key from Initiating Device */
13853b19146dSJohan Hedberg 		return 0;
13863b19146dSJohan Hedberg 	} else {
1387b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
13883b19146dSJohan Hedberg 	}
1389da85e5e5SVinicius Costa Gomes 
13902b64d153SBrian Gix 	/* Request setup of TK */
13912b64d153SBrian Gix 	ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability);
13922b64d153SBrian Gix 	if (ret)
13932b64d153SBrian Gix 		return SMP_UNSPECIFIED;
13942b64d153SBrian Gix 
1395da85e5e5SVinicius Costa Gomes 	return 0;
139688ba43b6SAnderson Briglia }
139788ba43b6SAnderson Briglia 
13983b19146dSJohan Hedberg static u8 sc_send_public_key(struct smp_chan *smp)
13993b19146dSJohan Hedberg {
14003b19146dSJohan Hedberg 	BT_DBG("");
14013b19146dSJohan Hedberg 
1402*6c0dcc50SJohan Hedberg 	while (true) {
14033b19146dSJohan Hedberg 		/* Generate local key pair for Secure Connections */
14043b19146dSJohan Hedberg 		if (!ecc_make_key(smp->local_pk, smp->local_sk))
14053b19146dSJohan Hedberg 			return SMP_UNSPECIFIED;
14063b19146dSJohan Hedberg 
1407*6c0dcc50SJohan Hedberg 		/* This is unlikely, but we need to check that we didn't
1408*6c0dcc50SJohan Hedberg 		 * accidentially generate a debug key.
1409*6c0dcc50SJohan Hedberg 		 */
1410*6c0dcc50SJohan Hedberg 		if (memcmp(smp->local_sk, debug_sk, 32))
1411*6c0dcc50SJohan Hedberg 			break;
1412*6c0dcc50SJohan Hedberg 	}
1413*6c0dcc50SJohan Hedberg 
14143b19146dSJohan Hedberg 	BT_DBG("Local Public Key X: %32phN", smp->local_pk);
14153b19146dSJohan Hedberg 	BT_DBG("Local Public Key Y: %32phN", &smp->local_pk[32]);
14163b19146dSJohan Hedberg 	BT_DBG("Local Private Key:  %32phN", smp->local_sk);
14173b19146dSJohan Hedberg 
14183b19146dSJohan Hedberg 	smp_send_cmd(smp->conn, SMP_CMD_PUBLIC_KEY, 64, smp->local_pk);
14193b19146dSJohan Hedberg 
14203b19146dSJohan Hedberg 	return 0;
14213b19146dSJohan Hedberg }
14223b19146dSJohan Hedberg 
1423da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
142488ba43b6SAnderson Briglia {
14253158c50cSVinicius Costa Gomes 	struct smp_cmd_pairing *req, *rsp = (void *) skb->data;
14265d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
14275d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
14280edb14deSJohan Hedberg 	struct hci_dev *hdev = conn->hcon->hdev;
14293a7dbfb8SJohan Hedberg 	u8 key_size, auth;
14307d24ddccSAnderson Briglia 	int ret;
143188ba43b6SAnderson Briglia 
143288ba43b6SAnderson Briglia 	BT_DBG("conn %p", conn);
143388ba43b6SAnderson Briglia 
1434c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rsp))
143538e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1436c46b98beSJohan Hedberg 
143740bef302SJohan Hedberg 	if (conn->hcon->role != HCI_ROLE_MASTER)
14382b64d153SBrian Gix 		return SMP_CMD_NOTSUPP;
14392b64d153SBrian Gix 
14403158c50cSVinicius Costa Gomes 	skb_pull(skb, sizeof(*rsp));
1441da85e5e5SVinicius Costa Gomes 
14421c1def09SVinicius Costa Gomes 	req = (void *) &smp->preq[1];
14433158c50cSVinicius Costa Gomes 
14443158c50cSVinicius Costa Gomes 	key_size = min(req->max_key_size, rsp->max_key_size);
14453158c50cSVinicius Costa Gomes 	if (check_enc_key_size(conn, key_size))
14463158c50cSVinicius Costa Gomes 		return SMP_ENC_KEY_SIZE;
14473158c50cSVinicius Costa Gomes 
14480edb14deSJohan Hedberg 	auth = rsp->auth_req & AUTH_REQ_MASK(hdev);
1449c05b9339SJohan Hedberg 
145065668776SJohan Hedberg 	if ((req->auth_req & SMP_AUTH_SC) && (auth & SMP_AUTH_SC))
145165668776SJohan Hedberg 		set_bit(SMP_FLAG_SC, &smp->flags);
1452d2eb9e10SJohan Hedberg 	else if (conn->hcon->pending_sec_level > BT_SECURITY_HIGH)
1453d2eb9e10SJohan Hedberg 		conn->hcon->pending_sec_level = BT_SECURITY_HIGH;
145465668776SJohan Hedberg 
145549c922bbSStephen Hemminger 	/* If we need MITM check that it can be achieved */
14562ed8f65cSJohan Hedberg 	if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
14572ed8f65cSJohan Hedberg 		u8 method;
14582ed8f65cSJohan Hedberg 
14592ed8f65cSJohan Hedberg 		method = get_auth_method(smp, req->io_capability,
14602ed8f65cSJohan Hedberg 					 rsp->io_capability);
14612ed8f65cSJohan Hedberg 		if (method == JUST_WORKS || method == JUST_CFM)
14622ed8f65cSJohan Hedberg 			return SMP_AUTH_REQUIREMENTS;
14632ed8f65cSJohan Hedberg 	}
14642ed8f65cSJohan Hedberg 
1465e84a6b13SJohan Hedberg 	get_random_bytes(smp->prnd, sizeof(smp->prnd));
14667d24ddccSAnderson Briglia 
14678aab4757SVinicius Costa Gomes 	smp->prsp[0] = SMP_CMD_PAIRING_RSP;
14688aab4757SVinicius Costa Gomes 	memcpy(&smp->prsp[1], rsp, sizeof(*rsp));
14697d24ddccSAnderson Briglia 
1470fdcc4becSJohan Hedberg 	/* Update remote key distribution in case the remote cleared
1471fdcc4becSJohan Hedberg 	 * some bits that we had enabled in our request.
1472fdcc4becSJohan Hedberg 	 */
1473fdcc4becSJohan Hedberg 	smp->remote_key_dist &= rsp->resp_key_dist;
1474fdcc4becSJohan Hedberg 
14753b19146dSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
14763b19146dSJohan Hedberg 		/* Clear bits which are generated but not distributed */
14773b19146dSJohan Hedberg 		smp->remote_key_dist &= ~SMP_SC_NO_DIST;
14783b19146dSJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PUBLIC_KEY);
14793b19146dSJohan Hedberg 		return sc_send_public_key(smp);
14803b19146dSJohan Hedberg 	}
14813b19146dSJohan Hedberg 
1482c05b9339SJohan Hedberg 	auth |= req->auth_req;
14832b64d153SBrian Gix 
1484476585ecSJohan Hedberg 	ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability);
14852b64d153SBrian Gix 	if (ret)
14862b64d153SBrian Gix 		return SMP_UNSPECIFIED;
14872b64d153SBrian Gix 
14884a74d658SJohan Hedberg 	set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
14892b64d153SBrian Gix 
14902b64d153SBrian Gix 	/* Can't compose response until we have been confirmed */
14914a74d658SJohan Hedberg 	if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
14921cc61144SJohan Hedberg 		return smp_confirm(smp);
1493da85e5e5SVinicius Costa Gomes 
1494da85e5e5SVinicius Costa Gomes 	return 0;
149588ba43b6SAnderson Briglia }
149688ba43b6SAnderson Briglia 
1497dcee2b32SJohan Hedberg static u8 sc_check_confirm(struct smp_chan *smp)
1498dcee2b32SJohan Hedberg {
1499dcee2b32SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
1500dcee2b32SJohan Hedberg 
1501dcee2b32SJohan Hedberg 	BT_DBG("");
1502dcee2b32SJohan Hedberg 
1503dcee2b32SJohan Hedberg 	/* Public Key exchange must happen before any other steps */
1504dcee2b32SJohan Hedberg 	if (!test_bit(SMP_FLAG_REMOTE_PK, &smp->flags))
1505dcee2b32SJohan Hedberg 		return SMP_UNSPECIFIED;
1506dcee2b32SJohan Hedberg 
1507dcee2b32SJohan Hedberg 	if (conn->hcon->out) {
1508dcee2b32SJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
1509dcee2b32SJohan Hedberg 			     smp->prnd);
1510dcee2b32SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
1511dcee2b32SJohan Hedberg 	}
1512dcee2b32SJohan Hedberg 
1513dcee2b32SJohan Hedberg 	return 0;
1514dcee2b32SJohan Hedberg }
1515dcee2b32SJohan Hedberg 
1516da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
151788ba43b6SAnderson Briglia {
15185d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
15195d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
15207d24ddccSAnderson Briglia 
152188ba43b6SAnderson Briglia 	BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
152288ba43b6SAnderson Briglia 
1523c46b98beSJohan Hedberg 	if (skb->len < sizeof(smp->pcnf))
152438e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1525c46b98beSJohan Hedberg 
15261c1def09SVinicius Costa Gomes 	memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf));
15271c1def09SVinicius Costa Gomes 	skb_pull(skb, sizeof(smp->pcnf));
15287d24ddccSAnderson Briglia 
1529dcee2b32SJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags))
1530dcee2b32SJohan Hedberg 		return sc_check_confirm(smp);
1531dcee2b32SJohan Hedberg 
1532b28b4943SJohan Hedberg 	if (conn->hcon->out) {
1533943a732aSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
1534943a732aSJohan Hedberg 			     smp->prnd);
1535b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
1536b28b4943SJohan Hedberg 		return 0;
1537b28b4943SJohan Hedberg 	}
1538b28b4943SJohan Hedberg 
1539b28b4943SJohan Hedberg 	if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
15401cc61144SJohan Hedberg 		return smp_confirm(smp);
1541943a732aSJohan Hedberg 	else
15424a74d658SJohan Hedberg 		set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
1543da85e5e5SVinicius Costa Gomes 
1544da85e5e5SVinicius Costa Gomes 	return 0;
154588ba43b6SAnderson Briglia }
154688ba43b6SAnderson Briglia 
1547da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
154888ba43b6SAnderson Briglia {
15495d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
15505d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
1551191dc7feSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
1552191dc7feSJohan Hedberg 	u8 *pkax, *pkbx, *na, *nb;
1553191dc7feSJohan Hedberg 	u32 passkey;
1554191dc7feSJohan Hedberg 	int err;
15557d24ddccSAnderson Briglia 
15568aab4757SVinicius Costa Gomes 	BT_DBG("conn %p", conn);
15577d24ddccSAnderson Briglia 
1558c46b98beSJohan Hedberg 	if (skb->len < sizeof(smp->rrnd))
155938e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1560c46b98beSJohan Hedberg 
1561943a732aSJohan Hedberg 	memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd));
15628aab4757SVinicius Costa Gomes 	skb_pull(skb, sizeof(smp->rrnd));
156388ba43b6SAnderson Briglia 
1564191dc7feSJohan Hedberg 	if (!test_bit(SMP_FLAG_SC, &smp->flags))
1565861580a9SJohan Hedberg 		return smp_random(smp);
1566191dc7feSJohan Hedberg 
1567191dc7feSJohan Hedberg 	if (hcon->out) {
1568191dc7feSJohan Hedberg 		u8 cfm[16];
1569191dc7feSJohan Hedberg 
1570191dc7feSJohan Hedberg 		err = smp_f4(smp->tfm_cmac, smp->remote_pk, smp->local_pk,
1571191dc7feSJohan Hedberg 			     smp->rrnd, 0, cfm);
1572191dc7feSJohan Hedberg 		if (err)
1573191dc7feSJohan Hedberg 			return SMP_UNSPECIFIED;
1574191dc7feSJohan Hedberg 
1575191dc7feSJohan Hedberg 		if (memcmp(smp->pcnf, cfm, 16))
1576191dc7feSJohan Hedberg 			return SMP_CONFIRM_FAILED;
1577191dc7feSJohan Hedberg 
1578191dc7feSJohan Hedberg 		pkax = smp->local_pk;
1579191dc7feSJohan Hedberg 		pkbx = smp->remote_pk;
1580191dc7feSJohan Hedberg 		na   = smp->prnd;
1581191dc7feSJohan Hedberg 		nb   = smp->rrnd;
1582191dc7feSJohan Hedberg 	} else {
1583191dc7feSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
1584191dc7feSJohan Hedberg 			     smp->prnd);
1585191dc7feSJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
1586191dc7feSJohan Hedberg 
1587191dc7feSJohan Hedberg 		pkax = smp->remote_pk;
1588191dc7feSJohan Hedberg 		pkbx = smp->local_pk;
1589191dc7feSJohan Hedberg 		na   = smp->rrnd;
1590191dc7feSJohan Hedberg 		nb   = smp->prnd;
1591191dc7feSJohan Hedberg 	}
1592191dc7feSJohan Hedberg 
1593760b018bSJohan Hedberg 	/* Generate MacKey and LTK */
1594760b018bSJohan Hedberg 	err = sc_mackey_and_ltk(smp, smp->mackey, smp->tk);
1595760b018bSJohan Hedberg 	if (err)
1596760b018bSJohan Hedberg 		return SMP_UNSPECIFIED;
1597760b018bSJohan Hedberg 
1598191dc7feSJohan Hedberg 	err = smp_g2(smp->tfm_cmac, pkax, pkbx, na, nb, &passkey);
1599191dc7feSJohan Hedberg 	if (err)
1600191dc7feSJohan Hedberg 		return SMP_UNSPECIFIED;
1601191dc7feSJohan Hedberg 
1602191dc7feSJohan Hedberg 	err = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
1603191dc7feSJohan Hedberg 					hcon->type, hcon->dst_type,
1604191dc7feSJohan Hedberg 					passkey, 0);
1605191dc7feSJohan Hedberg 	if (err)
1606191dc7feSJohan Hedberg 		return SMP_UNSPECIFIED;
1607191dc7feSJohan Hedberg 
1608191dc7feSJohan Hedberg 	return 0;
160988ba43b6SAnderson Briglia }
161088ba43b6SAnderson Briglia 
1611f81cd823SMarcel Holtmann static bool smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
1612988c5997SVinicius Costa Gomes {
1613c9839a11SVinicius Costa Gomes 	struct smp_ltk *key;
1614988c5997SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
1615988c5997SVinicius Costa Gomes 
1616f3a73d97SJohan Hedberg 	key = hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, hcon->role);
1617988c5997SVinicius Costa Gomes 	if (!key)
1618f81cd823SMarcel Holtmann 		return false;
1619988c5997SVinicius Costa Gomes 
1620a6f7833cSJohan Hedberg 	if (smp_ltk_sec_level(key) < sec_level)
1621f81cd823SMarcel Holtmann 		return false;
16224dab7864SJohan Hedberg 
162351a8efd7SJohan Hedberg 	if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
1624f81cd823SMarcel Holtmann 		return true;
1625988c5997SVinicius Costa Gomes 
1626c9839a11SVinicius Costa Gomes 	hci_le_start_enc(hcon, key->ediv, key->rand, key->val);
1627c9839a11SVinicius Costa Gomes 	hcon->enc_key_size = key->enc_size;
1628988c5997SVinicius Costa Gomes 
1629fe59a05fSJohan Hedberg 	/* We never store STKs for master role, so clear this flag */
1630fe59a05fSJohan Hedberg 	clear_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags);
1631fe59a05fSJohan Hedberg 
1632f81cd823SMarcel Holtmann 	return true;
1633988c5997SVinicius Costa Gomes }
1634f1560463SMarcel Holtmann 
163535dc6f83SJohan Hedberg bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level,
163635dc6f83SJohan Hedberg 			     enum smp_key_pref key_pref)
1637854f4727SJohan Hedberg {
1638854f4727SJohan Hedberg 	if (sec_level == BT_SECURITY_LOW)
1639854f4727SJohan Hedberg 		return true;
1640854f4727SJohan Hedberg 
164135dc6f83SJohan Hedberg 	/* If we're encrypted with an STK but the caller prefers using
164235dc6f83SJohan Hedberg 	 * LTK claim insufficient security. This way we allow the
164335dc6f83SJohan Hedberg 	 * connection to be re-encrypted with an LTK, even if the LTK
164435dc6f83SJohan Hedberg 	 * provides the same level of security. Only exception is if we
164535dc6f83SJohan Hedberg 	 * don't have an LTK (e.g. because of key distribution bits).
16469ab65d60SJohan Hedberg 	 */
164735dc6f83SJohan Hedberg 	if (key_pref == SMP_USE_LTK &&
164835dc6f83SJohan Hedberg 	    test_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags) &&
1649f3a73d97SJohan Hedberg 	    hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, hcon->role))
16509ab65d60SJohan Hedberg 		return false;
16519ab65d60SJohan Hedberg 
1652854f4727SJohan Hedberg 	if (hcon->sec_level >= sec_level)
1653854f4727SJohan Hedberg 		return true;
1654854f4727SJohan Hedberg 
1655854f4727SJohan Hedberg 	return false;
1656854f4727SJohan Hedberg }
1657854f4727SJohan Hedberg 
1658da85e5e5SVinicius Costa Gomes static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
165988ba43b6SAnderson Briglia {
166088ba43b6SAnderson Briglia 	struct smp_cmd_security_req *rp = (void *) skb->data;
166188ba43b6SAnderson Briglia 	struct smp_cmd_pairing cp;
1662f1cb9af5SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
16630edb14deSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
16648aab4757SVinicius Costa Gomes 	struct smp_chan *smp;
1665c05b9339SJohan Hedberg 	u8 sec_level, auth;
166688ba43b6SAnderson Briglia 
166788ba43b6SAnderson Briglia 	BT_DBG("conn %p", conn);
166888ba43b6SAnderson Briglia 
1669c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rp))
167038e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1671c46b98beSJohan Hedberg 
167240bef302SJohan Hedberg 	if (hcon->role != HCI_ROLE_MASTER)
167386ca9eacSJohan Hedberg 		return SMP_CMD_NOTSUPP;
167486ca9eacSJohan Hedberg 
16750edb14deSJohan Hedberg 	auth = rp->auth_req & AUTH_REQ_MASK(hdev);
1676c05b9339SJohan Hedberg 
16775be5e275SJohan Hedberg 	if (hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
16781afc2a1aSJohan Hedberg 		sec_level = BT_SECURITY_MEDIUM;
16791afc2a1aSJohan Hedberg 	else
1680c05b9339SJohan Hedberg 		sec_level = authreq_to_seclevel(auth);
16811afc2a1aSJohan Hedberg 
168235dc6f83SJohan Hedberg 	if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK))
1683854f4727SJohan Hedberg 		return 0;
1684854f4727SJohan Hedberg 
1685c7262e71SJohan Hedberg 	if (sec_level > hcon->pending_sec_level)
1686c7262e71SJohan Hedberg 		hcon->pending_sec_level = sec_level;
1687feb45eb5SVinicius Costa Gomes 
16884dab7864SJohan Hedberg 	if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
1689988c5997SVinicius Costa Gomes 		return 0;
1690988c5997SVinicius Costa Gomes 
16918aab4757SVinicius Costa Gomes 	smp = smp_chan_create(conn);
1692c29d2444SJohan Hedberg 	if (!smp)
1693c29d2444SJohan Hedberg 		return SMP_UNSPECIFIED;
1694d26a2345SVinicius Costa Gomes 
1695b6ae8457SJohan Hedberg 	if (!test_bit(HCI_BONDABLE, &hcon->hdev->dev_flags) &&
1696c05b9339SJohan Hedberg 	    (auth & SMP_AUTH_BONDING))
1697616d55beSJohan Hedberg 		return SMP_PAIRING_NOTSUPP;
1698616d55beSJohan Hedberg 
169988ba43b6SAnderson Briglia 	skb_pull(skb, sizeof(*rp));
170088ba43b6SAnderson Briglia 
1701da85e5e5SVinicius Costa Gomes 	memset(&cp, 0, sizeof(cp));
1702c05b9339SJohan Hedberg 	build_pairing_cmd(conn, &cp, NULL, auth);
170388ba43b6SAnderson Briglia 
17041c1def09SVinicius Costa Gomes 	smp->preq[0] = SMP_CMD_PAIRING_REQ;
17051c1def09SVinicius Costa Gomes 	memcpy(&smp->preq[1], &cp, sizeof(cp));
1706f01ead31SAnderson Briglia 
170788ba43b6SAnderson Briglia 	smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
1708b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP);
1709f1cb9af5SVinicius Costa Gomes 
1710da85e5e5SVinicius Costa Gomes 	return 0;
171188ba43b6SAnderson Briglia }
171288ba43b6SAnderson Briglia 
1713cc110922SVinicius Costa Gomes int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
1714eb492e01SAnderson Briglia {
1715cc110922SVinicius Costa Gomes 	struct l2cap_conn *conn = hcon->l2cap_data;
1716c68b7f12SJohan Hedberg 	struct l2cap_chan *chan;
17170a66cf20SJohan Hedberg 	struct smp_chan *smp;
17182b64d153SBrian Gix 	__u8 authreq;
1719fc75cc86SJohan Hedberg 	int ret;
1720eb492e01SAnderson Briglia 
17213a0259bbSVinicius Costa Gomes 	BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
17223a0259bbSVinicius Costa Gomes 
17230a66cf20SJohan Hedberg 	/* This may be NULL if there's an unexpected disconnection */
17240a66cf20SJohan Hedberg 	if (!conn)
17250a66cf20SJohan Hedberg 		return 1;
17260a66cf20SJohan Hedberg 
1727c68b7f12SJohan Hedberg 	chan = conn->smp;
1728c68b7f12SJohan Hedberg 
1729757aee0fSJohan Hedberg 	if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags))
17302e65c9d2SAndre Guedes 		return 1;
17312e65c9d2SAndre Guedes 
173235dc6f83SJohan Hedberg 	if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK))
1733f1cb9af5SVinicius Costa Gomes 		return 1;
1734f1cb9af5SVinicius Costa Gomes 
1735c7262e71SJohan Hedberg 	if (sec_level > hcon->pending_sec_level)
1736c7262e71SJohan Hedberg 		hcon->pending_sec_level = sec_level;
1737c7262e71SJohan Hedberg 
173840bef302SJohan Hedberg 	if (hcon->role == HCI_ROLE_MASTER)
1739c7262e71SJohan Hedberg 		if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
1740c7262e71SJohan Hedberg 			return 0;
1741d26a2345SVinicius Costa Gomes 
1742fc75cc86SJohan Hedberg 	l2cap_chan_lock(chan);
1743fc75cc86SJohan Hedberg 
1744fc75cc86SJohan Hedberg 	/* If SMP is already in progress ignore this request */
1745fc75cc86SJohan Hedberg 	if (chan->data) {
1746fc75cc86SJohan Hedberg 		ret = 0;
1747fc75cc86SJohan Hedberg 		goto unlock;
1748fc75cc86SJohan Hedberg 	}
1749d26a2345SVinicius Costa Gomes 
17508aab4757SVinicius Costa Gomes 	smp = smp_chan_create(conn);
1751fc75cc86SJohan Hedberg 	if (!smp) {
1752fc75cc86SJohan Hedberg 		ret = 1;
1753fc75cc86SJohan Hedberg 		goto unlock;
1754fc75cc86SJohan Hedberg 	}
17552b64d153SBrian Gix 
17562b64d153SBrian Gix 	authreq = seclevel_to_authreq(sec_level);
1757d26a2345SVinicius Costa Gomes 
1758d2eb9e10SJohan Hedberg 	if (test_bit(HCI_SC_ENABLED, &hcon->hdev->dev_flags))
1759d2eb9e10SJohan Hedberg 		authreq |= SMP_AUTH_SC;
1760d2eb9e10SJohan Hedberg 
176179897d20SJohan Hedberg 	/* Require MITM if IO Capability allows or the security level
176279897d20SJohan Hedberg 	 * requires it.
17632e233644SJohan Hedberg 	 */
176479897d20SJohan Hedberg 	if (hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT ||
1765c7262e71SJohan Hedberg 	    hcon->pending_sec_level > BT_SECURITY_MEDIUM)
17662e233644SJohan Hedberg 		authreq |= SMP_AUTH_MITM;
17672e233644SJohan Hedberg 
176840bef302SJohan Hedberg 	if (hcon->role == HCI_ROLE_MASTER) {
1769d26a2345SVinicius Costa Gomes 		struct smp_cmd_pairing cp;
1770f01ead31SAnderson Briglia 
17712b64d153SBrian Gix 		build_pairing_cmd(conn, &cp, NULL, authreq);
17721c1def09SVinicius Costa Gomes 		smp->preq[0] = SMP_CMD_PAIRING_REQ;
17731c1def09SVinicius Costa Gomes 		memcpy(&smp->preq[1], &cp, sizeof(cp));
1774f01ead31SAnderson Briglia 
1775eb492e01SAnderson Briglia 		smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
1776b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP);
1777eb492e01SAnderson Briglia 	} else {
1778eb492e01SAnderson Briglia 		struct smp_cmd_security_req cp;
17792b64d153SBrian Gix 		cp.auth_req = authreq;
1780eb492e01SAnderson Briglia 		smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
1781b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_REQ);
1782eb492e01SAnderson Briglia 	}
1783eb492e01SAnderson Briglia 
17844a74d658SJohan Hedberg 	set_bit(SMP_FLAG_INITIATOR, &smp->flags);
1785fc75cc86SJohan Hedberg 	ret = 0;
1786edca792cSJohan Hedberg 
1787fc75cc86SJohan Hedberg unlock:
1788fc75cc86SJohan Hedberg 	l2cap_chan_unlock(chan);
1789fc75cc86SJohan Hedberg 	return ret;
1790eb492e01SAnderson Briglia }
1791eb492e01SAnderson Briglia 
17927034b911SVinicius Costa Gomes static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
17937034b911SVinicius Costa Gomes {
179416b90839SVinicius Costa Gomes 	struct smp_cmd_encrypt_info *rp = (void *) skb->data;
17955d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
17965d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
179716b90839SVinicius Costa Gomes 
1798c46b98beSJohan Hedberg 	BT_DBG("conn %p", conn);
1799c46b98beSJohan Hedberg 
1800c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rp))
180138e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1802c46b98beSJohan Hedberg 
1803b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_MASTER_IDENT);
18046131ddc8SJohan Hedberg 
180516b90839SVinicius Costa Gomes 	skb_pull(skb, sizeof(*rp));
180616b90839SVinicius Costa Gomes 
18071c1def09SVinicius Costa Gomes 	memcpy(smp->tk, rp->ltk, sizeof(smp->tk));
180816b90839SVinicius Costa Gomes 
18097034b911SVinicius Costa Gomes 	return 0;
18107034b911SVinicius Costa Gomes }
18117034b911SVinicius Costa Gomes 
18127034b911SVinicius Costa Gomes static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
18137034b911SVinicius Costa Gomes {
181416b90839SVinicius Costa Gomes 	struct smp_cmd_master_ident *rp = (void *) skb->data;
18155d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
18165d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
1817c9839a11SVinicius Costa Gomes 	struct hci_dev *hdev = conn->hcon->hdev;
1818c9839a11SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
181923d0e128SJohan Hedberg 	struct smp_ltk *ltk;
1820c9839a11SVinicius Costa Gomes 	u8 authenticated;
18217034b911SVinicius Costa Gomes 
1822c46b98beSJohan Hedberg 	BT_DBG("conn %p", conn);
1823c46b98beSJohan Hedberg 
1824c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rp))
182538e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1826c46b98beSJohan Hedberg 
18279747a9f3SJohan Hedberg 	/* Mark the information as received */
18289747a9f3SJohan Hedberg 	smp->remote_key_dist &= ~SMP_DIST_ENC_KEY;
18299747a9f3SJohan Hedberg 
1830b28b4943SJohan Hedberg 	if (smp->remote_key_dist & SMP_DIST_ID_KEY)
1831b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO);
1832196332f5SJohan Hedberg 	else if (smp->remote_key_dist & SMP_DIST_SIGN)
1833196332f5SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO);
1834b28b4943SJohan Hedberg 
183516b90839SVinicius Costa Gomes 	skb_pull(skb, sizeof(*rp));
183616b90839SVinicius Costa Gomes 
1837ce39fb4eSMarcel Holtmann 	authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
18382ceba539SJohan Hedberg 	ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, SMP_LTK,
1839ce39fb4eSMarcel Holtmann 			  authenticated, smp->tk, smp->enc_key_size,
184004124681SGustavo F. Padovan 			  rp->ediv, rp->rand);
184123d0e128SJohan Hedberg 	smp->ltk = ltk;
1842c6e81e9aSJohan Hedberg 	if (!(smp->remote_key_dist & KEY_DIST_MASK))
1843d6268e86SJohan Hedberg 		smp_distribute_keys(smp);
18447034b911SVinicius Costa Gomes 
18457034b911SVinicius Costa Gomes 	return 0;
18467034b911SVinicius Costa Gomes }
18477034b911SVinicius Costa Gomes 
1848fd349c02SJohan Hedberg static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
1849fd349c02SJohan Hedberg {
1850fd349c02SJohan Hedberg 	struct smp_cmd_ident_info *info = (void *) skb->data;
18515d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
18525d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
1853fd349c02SJohan Hedberg 
1854fd349c02SJohan Hedberg 	BT_DBG("");
1855fd349c02SJohan Hedberg 
1856fd349c02SJohan Hedberg 	if (skb->len < sizeof(*info))
185738e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1858fd349c02SJohan Hedberg 
1859b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_ADDR_INFO);
18606131ddc8SJohan Hedberg 
1861fd349c02SJohan Hedberg 	skb_pull(skb, sizeof(*info));
1862fd349c02SJohan Hedberg 
1863fd349c02SJohan Hedberg 	memcpy(smp->irk, info->irk, 16);
1864fd349c02SJohan Hedberg 
1865fd349c02SJohan Hedberg 	return 0;
1866fd349c02SJohan Hedberg }
1867fd349c02SJohan Hedberg 
1868fd349c02SJohan Hedberg static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
1869fd349c02SJohan Hedberg 				   struct sk_buff *skb)
1870fd349c02SJohan Hedberg {
1871fd349c02SJohan Hedberg 	struct smp_cmd_ident_addr_info *info = (void *) skb->data;
18725d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
18735d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
1874fd349c02SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
1875fd349c02SJohan Hedberg 	bdaddr_t rpa;
1876fd349c02SJohan Hedberg 
1877fd349c02SJohan Hedberg 	BT_DBG("");
1878fd349c02SJohan Hedberg 
1879fd349c02SJohan Hedberg 	if (skb->len < sizeof(*info))
188038e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1881fd349c02SJohan Hedberg 
18829747a9f3SJohan Hedberg 	/* Mark the information as received */
18839747a9f3SJohan Hedberg 	smp->remote_key_dist &= ~SMP_DIST_ID_KEY;
18849747a9f3SJohan Hedberg 
1885b28b4943SJohan Hedberg 	if (smp->remote_key_dist & SMP_DIST_SIGN)
1886b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO);
1887b28b4943SJohan Hedberg 
1888fd349c02SJohan Hedberg 	skb_pull(skb, sizeof(*info));
1889fd349c02SJohan Hedberg 
1890a9a58f86SJohan Hedberg 	/* Strictly speaking the Core Specification (4.1) allows sending
1891a9a58f86SJohan Hedberg 	 * an empty address which would force us to rely on just the IRK
1892a9a58f86SJohan Hedberg 	 * as "identity information". However, since such
1893a9a58f86SJohan Hedberg 	 * implementations are not known of and in order to not over
1894a9a58f86SJohan Hedberg 	 * complicate our implementation, simply pretend that we never
1895a9a58f86SJohan Hedberg 	 * received an IRK for such a device.
1896a9a58f86SJohan Hedberg 	 */
1897a9a58f86SJohan Hedberg 	if (!bacmp(&info->bdaddr, BDADDR_ANY)) {
1898a9a58f86SJohan Hedberg 		BT_ERR("Ignoring IRK with no identity address");
189931dd624eSJohan Hedberg 		goto distribute;
1900a9a58f86SJohan Hedberg 	}
1901a9a58f86SJohan Hedberg 
1902fd349c02SJohan Hedberg 	bacpy(&smp->id_addr, &info->bdaddr);
1903fd349c02SJohan Hedberg 	smp->id_addr_type = info->addr_type;
1904fd349c02SJohan Hedberg 
1905fd349c02SJohan Hedberg 	if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type))
1906fd349c02SJohan Hedberg 		bacpy(&rpa, &hcon->dst);
1907fd349c02SJohan Hedberg 	else
1908fd349c02SJohan Hedberg 		bacpy(&rpa, BDADDR_ANY);
1909fd349c02SJohan Hedberg 
191023d0e128SJohan Hedberg 	smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
191123d0e128SJohan Hedberg 				      smp->id_addr_type, smp->irk, &rpa);
1912fd349c02SJohan Hedberg 
191331dd624eSJohan Hedberg distribute:
1914c6e81e9aSJohan Hedberg 	if (!(smp->remote_key_dist & KEY_DIST_MASK))
1915d6268e86SJohan Hedberg 		smp_distribute_keys(smp);
1916fd349c02SJohan Hedberg 
1917fd349c02SJohan Hedberg 	return 0;
1918fd349c02SJohan Hedberg }
1919fd349c02SJohan Hedberg 
19207ee4ea36SMarcel Holtmann static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)
19217ee4ea36SMarcel Holtmann {
19227ee4ea36SMarcel Holtmann 	struct smp_cmd_sign_info *rp = (void *) skb->data;
19235d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
19245d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
19257ee4ea36SMarcel Holtmann 	struct smp_csrk *csrk;
19267ee4ea36SMarcel Holtmann 
19277ee4ea36SMarcel Holtmann 	BT_DBG("conn %p", conn);
19287ee4ea36SMarcel Holtmann 
19297ee4ea36SMarcel Holtmann 	if (skb->len < sizeof(*rp))
193038e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
19317ee4ea36SMarcel Holtmann 
19327ee4ea36SMarcel Holtmann 	/* Mark the information as received */
19337ee4ea36SMarcel Holtmann 	smp->remote_key_dist &= ~SMP_DIST_SIGN;
19347ee4ea36SMarcel Holtmann 
19357ee4ea36SMarcel Holtmann 	skb_pull(skb, sizeof(*rp));
19367ee4ea36SMarcel Holtmann 
19377ee4ea36SMarcel Holtmann 	csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
19387ee4ea36SMarcel Holtmann 	if (csrk) {
19397ee4ea36SMarcel Holtmann 		csrk->master = 0x01;
19407ee4ea36SMarcel Holtmann 		memcpy(csrk->val, rp->csrk, sizeof(csrk->val));
19417ee4ea36SMarcel Holtmann 	}
19427ee4ea36SMarcel Holtmann 	smp->csrk = csrk;
1943d6268e86SJohan Hedberg 	smp_distribute_keys(smp);
19447ee4ea36SMarcel Holtmann 
19457ee4ea36SMarcel Holtmann 	return 0;
19467ee4ea36SMarcel Holtmann }
19477ee4ea36SMarcel Holtmann 
19485e3d3d9bSJohan Hedberg static u8 sc_select_method(struct smp_chan *smp)
19495e3d3d9bSJohan Hedberg {
19505e3d3d9bSJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
19515e3d3d9bSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
19525e3d3d9bSJohan Hedberg 	struct smp_cmd_pairing *local, *remote;
19535e3d3d9bSJohan Hedberg 	u8 local_mitm, remote_mitm, local_io, remote_io, method;
19545e3d3d9bSJohan Hedberg 
19555e3d3d9bSJohan Hedberg 	/* The preq/prsp contain the raw Pairing Request/Response PDUs
19565e3d3d9bSJohan Hedberg 	 * which are needed as inputs to some crypto functions. To get
19575e3d3d9bSJohan Hedberg 	 * the "struct smp_cmd_pairing" from them we need to skip the
19585e3d3d9bSJohan Hedberg 	 * first byte which contains the opcode.
19595e3d3d9bSJohan Hedberg 	 */
19605e3d3d9bSJohan Hedberg 	if (hcon->out) {
19615e3d3d9bSJohan Hedberg 		local = (void *) &smp->preq[1];
19625e3d3d9bSJohan Hedberg 		remote = (void *) &smp->prsp[1];
19635e3d3d9bSJohan Hedberg 	} else {
19645e3d3d9bSJohan Hedberg 		local = (void *) &smp->prsp[1];
19655e3d3d9bSJohan Hedberg 		remote = (void *) &smp->preq[1];
19665e3d3d9bSJohan Hedberg 	}
19675e3d3d9bSJohan Hedberg 
19685e3d3d9bSJohan Hedberg 	local_io = local->io_capability;
19695e3d3d9bSJohan Hedberg 	remote_io = remote->io_capability;
19705e3d3d9bSJohan Hedberg 
19715e3d3d9bSJohan Hedberg 	local_mitm = (local->auth_req & SMP_AUTH_MITM);
19725e3d3d9bSJohan Hedberg 	remote_mitm = (remote->auth_req & SMP_AUTH_MITM);
19735e3d3d9bSJohan Hedberg 
19745e3d3d9bSJohan Hedberg 	/* If either side wants MITM, look up the method from the table,
19755e3d3d9bSJohan Hedberg 	 * otherwise use JUST WORKS.
19765e3d3d9bSJohan Hedberg 	 */
19775e3d3d9bSJohan Hedberg 	if (local_mitm || remote_mitm)
19785e3d3d9bSJohan Hedberg 		method = get_auth_method(smp, local_io, remote_io);
19795e3d3d9bSJohan Hedberg 	else
19805e3d3d9bSJohan Hedberg 		method = JUST_WORKS;
19815e3d3d9bSJohan Hedberg 
19825e3d3d9bSJohan Hedberg 	/* Don't confirm locally initiated pairing attempts */
19835e3d3d9bSJohan Hedberg 	if (method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR, &smp->flags))
19845e3d3d9bSJohan Hedberg 		method = JUST_WORKS;
19855e3d3d9bSJohan Hedberg 
19865e3d3d9bSJohan Hedberg 	return method;
19875e3d3d9bSJohan Hedberg }
19885e3d3d9bSJohan Hedberg 
1989d8f8edbeSJohan Hedberg static int smp_cmd_public_key(struct l2cap_conn *conn, struct sk_buff *skb)
1990d8f8edbeSJohan Hedberg {
1991d8f8edbeSJohan Hedberg 	struct smp_cmd_public_key *key = (void *) skb->data;
1992d8f8edbeSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
1993d8f8edbeSJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
1994d8f8edbeSJohan Hedberg 	struct smp_chan *smp = chan->data;
19955e3d3d9bSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
1996cbbbe3e2SJohan Hedberg 	struct smp_cmd_pairing_confirm cfm;
1997d8f8edbeSJohan Hedberg 	int err;
1998d8f8edbeSJohan Hedberg 
1999d8f8edbeSJohan Hedberg 	BT_DBG("conn %p", conn);
2000d8f8edbeSJohan Hedberg 
2001d8f8edbeSJohan Hedberg 	if (skb->len < sizeof(*key))
2002d8f8edbeSJohan Hedberg 		return SMP_INVALID_PARAMS;
2003d8f8edbeSJohan Hedberg 
2004d8f8edbeSJohan Hedberg 	memcpy(smp->remote_pk, key, 64);
2005d8f8edbeSJohan Hedberg 
2006d8f8edbeSJohan Hedberg 	/* Non-initiating device sends its public key after receiving
2007d8f8edbeSJohan Hedberg 	 * the key from the initiating device.
2008d8f8edbeSJohan Hedberg 	 */
2009d8f8edbeSJohan Hedberg 	if (!hcon->out) {
2010d8f8edbeSJohan Hedberg 		err = sc_send_public_key(smp);
2011d8f8edbeSJohan Hedberg 		if (err)
2012d8f8edbeSJohan Hedberg 			return err;
2013d8f8edbeSJohan Hedberg 	}
2014d8f8edbeSJohan Hedberg 
2015d8f8edbeSJohan Hedberg 	BT_DBG("Remote Public Key X: %32phN", smp->remote_pk);
2016d8f8edbeSJohan Hedberg 	BT_DBG("Remote Public Key Y: %32phN", &smp->remote_pk[32]);
2017d8f8edbeSJohan Hedberg 
2018d8f8edbeSJohan Hedberg 	if (!ecdh_shared_secret(smp->remote_pk, smp->local_sk, smp->dhkey))
2019d8f8edbeSJohan Hedberg 		return SMP_UNSPECIFIED;
2020d8f8edbeSJohan Hedberg 
2021d8f8edbeSJohan Hedberg 	BT_DBG("DHKey %32phN", smp->dhkey);
2022d8f8edbeSJohan Hedberg 
2023d8f8edbeSJohan Hedberg 	set_bit(SMP_FLAG_REMOTE_PK, &smp->flags);
2024d8f8edbeSJohan Hedberg 
20255e3d3d9bSJohan Hedberg 	smp->method = sc_select_method(smp);
20265e3d3d9bSJohan Hedberg 
20275e3d3d9bSJohan Hedberg 	BT_DBG("%s selected method 0x%02x", hdev->name, smp->method);
20285e3d3d9bSJohan Hedberg 
20295e3d3d9bSJohan Hedberg 	/* JUST_WORKS and JUST_CFM result in an unauthenticated key */
20305e3d3d9bSJohan Hedberg 	if (smp->method == JUST_WORKS || smp->method == JUST_CFM)
20315e3d3d9bSJohan Hedberg 		hcon->pending_sec_level = BT_SECURITY_MEDIUM;
20325e3d3d9bSJohan Hedberg 	else
20335e3d3d9bSJohan Hedberg 		hcon->pending_sec_level = BT_SECURITY_FIPS;
20345e3d3d9bSJohan Hedberg 
2035aeb7d461SJohan Hedberg 	if (!memcmp(debug_pk, smp->remote_pk, 64))
2036aeb7d461SJohan Hedberg 		set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags);
2037aeb7d461SJohan Hedberg 
2038cbbbe3e2SJohan Hedberg 	/* The Initiating device waits for the non-initiating device to
2039cbbbe3e2SJohan Hedberg 	 * send the confirm value.
2040cbbbe3e2SJohan Hedberg 	 */
2041cbbbe3e2SJohan Hedberg 	if (conn->hcon->out)
2042cbbbe3e2SJohan Hedberg 		return 0;
2043cbbbe3e2SJohan Hedberg 
2044cbbbe3e2SJohan Hedberg 	err = smp_f4(smp->tfm_cmac, smp->local_pk, smp->remote_pk, smp->prnd,
2045cbbbe3e2SJohan Hedberg 		     0, cfm.confirm_val);
2046cbbbe3e2SJohan Hedberg 	if (err)
2047cbbbe3e2SJohan Hedberg 		return SMP_UNSPECIFIED;
2048cbbbe3e2SJohan Hedberg 
2049cbbbe3e2SJohan Hedberg 	smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cfm), &cfm);
2050cbbbe3e2SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
2051cbbbe3e2SJohan Hedberg 
2052d8f8edbeSJohan Hedberg 	return 0;
2053d8f8edbeSJohan Hedberg }
2054d8f8edbeSJohan Hedberg 
20556433a9a2SJohan Hedberg static int smp_cmd_dhkey_check(struct l2cap_conn *conn, struct sk_buff *skb)
20566433a9a2SJohan Hedberg {
20576433a9a2SJohan Hedberg 	struct smp_cmd_dhkey_check *check = (void *) skb->data;
20586433a9a2SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
20596433a9a2SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
20606433a9a2SJohan Hedberg 	struct smp_chan *smp = chan->data;
20616433a9a2SJohan Hedberg 	u8 a[7], b[7], *local_addr, *remote_addr;
20626433a9a2SJohan Hedberg 	u8 io_cap[3], r[16], e[16];
20636433a9a2SJohan Hedberg 	int err;
20646433a9a2SJohan Hedberg 
20656433a9a2SJohan Hedberg 	BT_DBG("conn %p", conn);
20666433a9a2SJohan Hedberg 
20676433a9a2SJohan Hedberg 	if (skb->len < sizeof(*check))
20686433a9a2SJohan Hedberg 		return SMP_INVALID_PARAMS;
20696433a9a2SJohan Hedberg 
20706433a9a2SJohan Hedberg 	memcpy(a, &hcon->init_addr, 6);
20716433a9a2SJohan Hedberg 	memcpy(b, &hcon->resp_addr, 6);
20726433a9a2SJohan Hedberg 	a[6] = hcon->init_addr_type;
20736433a9a2SJohan Hedberg 	b[6] = hcon->resp_addr_type;
20746433a9a2SJohan Hedberg 
20756433a9a2SJohan Hedberg 	if (hcon->out) {
20766433a9a2SJohan Hedberg 		local_addr = a;
20776433a9a2SJohan Hedberg 		remote_addr = b;
20786433a9a2SJohan Hedberg 		memcpy(io_cap, &smp->prsp[1], 3);
20796433a9a2SJohan Hedberg 	} else {
20806433a9a2SJohan Hedberg 		local_addr = b;
20816433a9a2SJohan Hedberg 		remote_addr = a;
20826433a9a2SJohan Hedberg 		memcpy(io_cap, &smp->preq[1], 3);
20836433a9a2SJohan Hedberg 	}
20846433a9a2SJohan Hedberg 
20856433a9a2SJohan Hedberg 	memset(r, 0, sizeof(r));
20866433a9a2SJohan Hedberg 
20876433a9a2SJohan Hedberg 	err = smp_f6(smp->tfm_cmac, smp->mackey, smp->rrnd, smp->prnd, r,
20886433a9a2SJohan Hedberg 		     io_cap, remote_addr, local_addr, e);
20896433a9a2SJohan Hedberg 	if (err)
20906433a9a2SJohan Hedberg 		return SMP_UNSPECIFIED;
20916433a9a2SJohan Hedberg 
20926433a9a2SJohan Hedberg 	if (memcmp(check->e, e, 16))
20936433a9a2SJohan Hedberg 		return SMP_DHKEY_CHECK_FAILED;
20946433a9a2SJohan Hedberg 
20956433a9a2SJohan Hedberg 	smp->ltk = hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
20966433a9a2SJohan Hedberg 			       SMP_LTK_P256, 0, smp->tk, smp->enc_key_size,
20976433a9a2SJohan Hedberg 			       0, 0);
20986433a9a2SJohan Hedberg 
20996433a9a2SJohan Hedberg 	if (hcon->out) {
21006433a9a2SJohan Hedberg 		hci_le_start_enc(hcon, 0, 0, smp->tk);
21016433a9a2SJohan Hedberg 		hcon->enc_key_size = smp->enc_key_size;
21026433a9a2SJohan Hedberg 	}
21036433a9a2SJohan Hedberg 
21046433a9a2SJohan Hedberg 	return 0;
21056433a9a2SJohan Hedberg }
21066433a9a2SJohan Hedberg 
21074befb867SJohan Hedberg static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb)
2108eb492e01SAnderson Briglia {
21095d88cc73SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
21107b9899dbSMarcel Holtmann 	struct hci_conn *hcon = conn->hcon;
2111b28b4943SJohan Hedberg 	struct smp_chan *smp;
211292381f5cSMarcel Holtmann 	__u8 code, reason;
2113eb492e01SAnderson Briglia 	int err = 0;
2114eb492e01SAnderson Briglia 
21157b9899dbSMarcel Holtmann 	if (hcon->type != LE_LINK) {
21167b9899dbSMarcel Holtmann 		kfree_skb(skb);
21173432711fSJohan Hedberg 		return 0;
21187b9899dbSMarcel Holtmann 	}
21197b9899dbSMarcel Holtmann 
21208ae9b984SJohan Hedberg 	if (skb->len < 1)
212192381f5cSMarcel Holtmann 		return -EILSEQ;
212292381f5cSMarcel Holtmann 
212306ae3314SMarcel Holtmann 	if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) {
21242e65c9d2SAndre Guedes 		reason = SMP_PAIRING_NOTSUPP;
21252e65c9d2SAndre Guedes 		goto done;
21262e65c9d2SAndre Guedes 	}
21272e65c9d2SAndre Guedes 
212892381f5cSMarcel Holtmann 	code = skb->data[0];
2129eb492e01SAnderson Briglia 	skb_pull(skb, sizeof(code));
2130eb492e01SAnderson Briglia 
2131b28b4943SJohan Hedberg 	smp = chan->data;
2132b28b4943SJohan Hedberg 
2133b28b4943SJohan Hedberg 	if (code > SMP_CMD_MAX)
2134b28b4943SJohan Hedberg 		goto drop;
2135b28b4943SJohan Hedberg 
213624bd0bd9SJohan Hedberg 	if (smp && !test_and_clear_bit(code, &smp->allow_cmd))
2137b28b4943SJohan Hedberg 		goto drop;
2138b28b4943SJohan Hedberg 
2139b28b4943SJohan Hedberg 	/* If we don't have a context the only allowed commands are
2140b28b4943SJohan Hedberg 	 * pairing request and security request.
21418cf9fa12SJohan Hedberg 	 */
2142b28b4943SJohan Hedberg 	if (!smp && code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ)
2143b28b4943SJohan Hedberg 		goto drop;
21448cf9fa12SJohan Hedberg 
2145eb492e01SAnderson Briglia 	switch (code) {
2146eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_REQ:
2147da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_req(conn, skb);
2148eb492e01SAnderson Briglia 		break;
2149eb492e01SAnderson Briglia 
2150eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_FAIL:
215184794e11SJohan Hedberg 		smp_failure(conn, 0);
2152da85e5e5SVinicius Costa Gomes 		err = -EPERM;
2153eb492e01SAnderson Briglia 		break;
2154eb492e01SAnderson Briglia 
2155eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_RSP:
2156da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_rsp(conn, skb);
215788ba43b6SAnderson Briglia 		break;
215888ba43b6SAnderson Briglia 
215988ba43b6SAnderson Briglia 	case SMP_CMD_SECURITY_REQ:
2160da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_security_req(conn, skb);
216188ba43b6SAnderson Briglia 		break;
216288ba43b6SAnderson Briglia 
2163eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_CONFIRM:
2164da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_confirm(conn, skb);
216588ba43b6SAnderson Briglia 		break;
216688ba43b6SAnderson Briglia 
2167eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_RANDOM:
2168da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_random(conn, skb);
216988ba43b6SAnderson Briglia 		break;
217088ba43b6SAnderson Briglia 
2171eb492e01SAnderson Briglia 	case SMP_CMD_ENCRYPT_INFO:
21727034b911SVinicius Costa Gomes 		reason = smp_cmd_encrypt_info(conn, skb);
21737034b911SVinicius Costa Gomes 		break;
21747034b911SVinicius Costa Gomes 
2175eb492e01SAnderson Briglia 	case SMP_CMD_MASTER_IDENT:
21767034b911SVinicius Costa Gomes 		reason = smp_cmd_master_ident(conn, skb);
21777034b911SVinicius Costa Gomes 		break;
21787034b911SVinicius Costa Gomes 
2179eb492e01SAnderson Briglia 	case SMP_CMD_IDENT_INFO:
2180fd349c02SJohan Hedberg 		reason = smp_cmd_ident_info(conn, skb);
2181fd349c02SJohan Hedberg 		break;
2182fd349c02SJohan Hedberg 
2183eb492e01SAnderson Briglia 	case SMP_CMD_IDENT_ADDR_INFO:
2184fd349c02SJohan Hedberg 		reason = smp_cmd_ident_addr_info(conn, skb);
2185fd349c02SJohan Hedberg 		break;
2186fd349c02SJohan Hedberg 
2187eb492e01SAnderson Briglia 	case SMP_CMD_SIGN_INFO:
21887ee4ea36SMarcel Holtmann 		reason = smp_cmd_sign_info(conn, skb);
21897034b911SVinicius Costa Gomes 		break;
21907034b911SVinicius Costa Gomes 
2191d8f8edbeSJohan Hedberg 	case SMP_CMD_PUBLIC_KEY:
2192d8f8edbeSJohan Hedberg 		reason = smp_cmd_public_key(conn, skb);
2193d8f8edbeSJohan Hedberg 		break;
2194d8f8edbeSJohan Hedberg 
21956433a9a2SJohan Hedberg 	case SMP_CMD_DHKEY_CHECK:
21966433a9a2SJohan Hedberg 		reason = smp_cmd_dhkey_check(conn, skb);
21976433a9a2SJohan Hedberg 		break;
21986433a9a2SJohan Hedberg 
2199eb492e01SAnderson Briglia 	default:
2200eb492e01SAnderson Briglia 		BT_DBG("Unknown command code 0x%2.2x", code);
2201eb492e01SAnderson Briglia 		reason = SMP_CMD_NOTSUPP;
22023a0259bbSVinicius Costa Gomes 		goto done;
22033a0259bbSVinicius Costa Gomes 	}
22043a0259bbSVinicius Costa Gomes 
22053a0259bbSVinicius Costa Gomes done:
22069b7b18efSJohan Hedberg 	if (!err) {
22073a0259bbSVinicius Costa Gomes 		if (reason)
220884794e11SJohan Hedberg 			smp_failure(conn, reason);
2209eb492e01SAnderson Briglia 		kfree_skb(skb);
22109b7b18efSJohan Hedberg 	}
22119b7b18efSJohan Hedberg 
2212eb492e01SAnderson Briglia 	return err;
2213b28b4943SJohan Hedberg 
2214b28b4943SJohan Hedberg drop:
2215b28b4943SJohan Hedberg 	BT_ERR("%s unexpected SMP command 0x%02x from %pMR", hcon->hdev->name,
2216b28b4943SJohan Hedberg 	       code, &hcon->dst);
2217b28b4943SJohan Hedberg 	kfree_skb(skb);
2218b28b4943SJohan Hedberg 	return 0;
2219eb492e01SAnderson Briglia }
22207034b911SVinicius Costa Gomes 
222170db83c4SJohan Hedberg static void smp_teardown_cb(struct l2cap_chan *chan, int err)
222270db83c4SJohan Hedberg {
222370db83c4SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
222470db83c4SJohan Hedberg 
222570db83c4SJohan Hedberg 	BT_DBG("chan %p", chan);
222670db83c4SJohan Hedberg 
2227fc75cc86SJohan Hedberg 	if (chan->data)
22285d88cc73SJohan Hedberg 		smp_chan_destroy(conn);
22295d88cc73SJohan Hedberg 
223070db83c4SJohan Hedberg 	conn->smp = NULL;
223170db83c4SJohan Hedberg 	l2cap_chan_put(chan);
223270db83c4SJohan Hedberg }
223370db83c4SJohan Hedberg 
223444f1a7abSJohan Hedberg static void smp_resume_cb(struct l2cap_chan *chan)
223544f1a7abSJohan Hedberg {
2236b68fda68SJohan Hedberg 	struct smp_chan *smp = chan->data;
223744f1a7abSJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
223844f1a7abSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
223944f1a7abSJohan Hedberg 
224044f1a7abSJohan Hedberg 	BT_DBG("chan %p", chan);
224144f1a7abSJohan Hedberg 
224286d1407cSJohan Hedberg 	if (!smp)
224386d1407cSJohan Hedberg 		return;
2244b68fda68SJohan Hedberg 
224584bc0db5SJohan Hedberg 	if (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags))
224684bc0db5SJohan Hedberg 		return;
224784bc0db5SJohan Hedberg 
2248b68fda68SJohan Hedberg 	cancel_delayed_work(&smp->security_timer);
224986d1407cSJohan Hedberg 
2250d6268e86SJohan Hedberg 	smp_distribute_keys(smp);
225144f1a7abSJohan Hedberg }
225244f1a7abSJohan Hedberg 
225370db83c4SJohan Hedberg static void smp_ready_cb(struct l2cap_chan *chan)
225470db83c4SJohan Hedberg {
225570db83c4SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
225670db83c4SJohan Hedberg 
225770db83c4SJohan Hedberg 	BT_DBG("chan %p", chan);
225870db83c4SJohan Hedberg 
225970db83c4SJohan Hedberg 	conn->smp = chan;
226070db83c4SJohan Hedberg 	l2cap_chan_hold(chan);
226170db83c4SJohan Hedberg }
226270db83c4SJohan Hedberg 
22634befb867SJohan Hedberg static int smp_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
22644befb867SJohan Hedberg {
22654befb867SJohan Hedberg 	int err;
22664befb867SJohan Hedberg 
22674befb867SJohan Hedberg 	BT_DBG("chan %p", chan);
22684befb867SJohan Hedberg 
22694befb867SJohan Hedberg 	err = smp_sig_channel(chan, skb);
22704befb867SJohan Hedberg 	if (err) {
2271b68fda68SJohan Hedberg 		struct smp_chan *smp = chan->data;
22724befb867SJohan Hedberg 
2273b68fda68SJohan Hedberg 		if (smp)
2274b68fda68SJohan Hedberg 			cancel_delayed_work_sync(&smp->security_timer);
22754befb867SJohan Hedberg 
22761e91c29eSJohan Hedberg 		hci_disconnect(chan->conn->hcon, HCI_ERROR_AUTH_FAILURE);
22774befb867SJohan Hedberg 	}
22784befb867SJohan Hedberg 
22794befb867SJohan Hedberg 	return err;
22804befb867SJohan Hedberg }
22814befb867SJohan Hedberg 
228270db83c4SJohan Hedberg static struct sk_buff *smp_alloc_skb_cb(struct l2cap_chan *chan,
228370db83c4SJohan Hedberg 					unsigned long hdr_len,
228470db83c4SJohan Hedberg 					unsigned long len, int nb)
228570db83c4SJohan Hedberg {
228670db83c4SJohan Hedberg 	struct sk_buff *skb;
228770db83c4SJohan Hedberg 
228870db83c4SJohan Hedberg 	skb = bt_skb_alloc(hdr_len + len, GFP_KERNEL);
228970db83c4SJohan Hedberg 	if (!skb)
229070db83c4SJohan Hedberg 		return ERR_PTR(-ENOMEM);
229170db83c4SJohan Hedberg 
229270db83c4SJohan Hedberg 	skb->priority = HCI_PRIO_MAX;
229370db83c4SJohan Hedberg 	bt_cb(skb)->chan = chan;
229470db83c4SJohan Hedberg 
229570db83c4SJohan Hedberg 	return skb;
229670db83c4SJohan Hedberg }
229770db83c4SJohan Hedberg 
229870db83c4SJohan Hedberg static const struct l2cap_ops smp_chan_ops = {
229970db83c4SJohan Hedberg 	.name			= "Security Manager",
230070db83c4SJohan Hedberg 	.ready			= smp_ready_cb,
23015d88cc73SJohan Hedberg 	.recv			= smp_recv_cb,
230270db83c4SJohan Hedberg 	.alloc_skb		= smp_alloc_skb_cb,
230370db83c4SJohan Hedberg 	.teardown		= smp_teardown_cb,
230444f1a7abSJohan Hedberg 	.resume			= smp_resume_cb,
230570db83c4SJohan Hedberg 
230670db83c4SJohan Hedberg 	.new_connection		= l2cap_chan_no_new_connection,
230770db83c4SJohan Hedberg 	.state_change		= l2cap_chan_no_state_change,
230870db83c4SJohan Hedberg 	.close			= l2cap_chan_no_close,
230970db83c4SJohan Hedberg 	.defer			= l2cap_chan_no_defer,
231070db83c4SJohan Hedberg 	.suspend		= l2cap_chan_no_suspend,
231170db83c4SJohan Hedberg 	.set_shutdown		= l2cap_chan_no_set_shutdown,
231270db83c4SJohan Hedberg 	.get_sndtimeo		= l2cap_chan_no_get_sndtimeo,
231370db83c4SJohan Hedberg 	.memcpy_fromiovec	= l2cap_chan_no_memcpy_fromiovec,
231470db83c4SJohan Hedberg };
231570db83c4SJohan Hedberg 
231670db83c4SJohan Hedberg static inline struct l2cap_chan *smp_new_conn_cb(struct l2cap_chan *pchan)
231770db83c4SJohan Hedberg {
231870db83c4SJohan Hedberg 	struct l2cap_chan *chan;
231970db83c4SJohan Hedberg 
232070db83c4SJohan Hedberg 	BT_DBG("pchan %p", pchan);
232170db83c4SJohan Hedberg 
232270db83c4SJohan Hedberg 	chan = l2cap_chan_create();
232370db83c4SJohan Hedberg 	if (!chan)
232470db83c4SJohan Hedberg 		return NULL;
232570db83c4SJohan Hedberg 
232670db83c4SJohan Hedberg 	chan->chan_type	= pchan->chan_type;
232770db83c4SJohan Hedberg 	chan->ops	= &smp_chan_ops;
232870db83c4SJohan Hedberg 	chan->scid	= pchan->scid;
232970db83c4SJohan Hedberg 	chan->dcid	= chan->scid;
233070db83c4SJohan Hedberg 	chan->imtu	= pchan->imtu;
233170db83c4SJohan Hedberg 	chan->omtu	= pchan->omtu;
233270db83c4SJohan Hedberg 	chan->mode	= pchan->mode;
233370db83c4SJohan Hedberg 
2334abe84903SJohan Hedberg 	/* Other L2CAP channels may request SMP routines in order to
2335abe84903SJohan Hedberg 	 * change the security level. This means that the SMP channel
2336abe84903SJohan Hedberg 	 * lock must be considered in its own category to avoid lockdep
2337abe84903SJohan Hedberg 	 * warnings.
2338abe84903SJohan Hedberg 	 */
2339abe84903SJohan Hedberg 	atomic_set(&chan->nesting, L2CAP_NESTING_SMP);
2340abe84903SJohan Hedberg 
234170db83c4SJohan Hedberg 	BT_DBG("created chan %p", chan);
234270db83c4SJohan Hedberg 
234370db83c4SJohan Hedberg 	return chan;
234470db83c4SJohan Hedberg }
234570db83c4SJohan Hedberg 
234670db83c4SJohan Hedberg static const struct l2cap_ops smp_root_chan_ops = {
234770db83c4SJohan Hedberg 	.name			= "Security Manager Root",
234870db83c4SJohan Hedberg 	.new_connection		= smp_new_conn_cb,
234970db83c4SJohan Hedberg 
235070db83c4SJohan Hedberg 	/* None of these are implemented for the root channel */
235170db83c4SJohan Hedberg 	.close			= l2cap_chan_no_close,
235270db83c4SJohan Hedberg 	.alloc_skb		= l2cap_chan_no_alloc_skb,
235370db83c4SJohan Hedberg 	.recv			= l2cap_chan_no_recv,
235470db83c4SJohan Hedberg 	.state_change		= l2cap_chan_no_state_change,
235570db83c4SJohan Hedberg 	.teardown		= l2cap_chan_no_teardown,
235670db83c4SJohan Hedberg 	.ready			= l2cap_chan_no_ready,
235770db83c4SJohan Hedberg 	.defer			= l2cap_chan_no_defer,
235870db83c4SJohan Hedberg 	.suspend		= l2cap_chan_no_suspend,
235970db83c4SJohan Hedberg 	.resume			= l2cap_chan_no_resume,
236070db83c4SJohan Hedberg 	.set_shutdown		= l2cap_chan_no_set_shutdown,
236170db83c4SJohan Hedberg 	.get_sndtimeo		= l2cap_chan_no_get_sndtimeo,
236270db83c4SJohan Hedberg 	.memcpy_fromiovec	= l2cap_chan_no_memcpy_fromiovec,
236370db83c4SJohan Hedberg };
236470db83c4SJohan Hedberg 
2365711eafe3SJohan Hedberg int smp_register(struct hci_dev *hdev)
2366711eafe3SJohan Hedberg {
236770db83c4SJohan Hedberg 	struct l2cap_chan *chan;
2368defce9e8SJohan Hedberg 	struct crypto_blkcipher	*tfm_aes;
236970db83c4SJohan Hedberg 
2370711eafe3SJohan Hedberg 	BT_DBG("%s", hdev->name);
2371711eafe3SJohan Hedberg 
2372adae20cbSJohan Hedberg 	tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, 0);
2373defce9e8SJohan Hedberg 	if (IS_ERR(tfm_aes)) {
2374defce9e8SJohan Hedberg 		int err = PTR_ERR(tfm_aes);
2375711eafe3SJohan Hedberg 		BT_ERR("Unable to create crypto context");
2376711eafe3SJohan Hedberg 		return err;
2377711eafe3SJohan Hedberg 	}
2378711eafe3SJohan Hedberg 
237970db83c4SJohan Hedberg 	chan = l2cap_chan_create();
238070db83c4SJohan Hedberg 	if (!chan) {
2381defce9e8SJohan Hedberg 		crypto_free_blkcipher(tfm_aes);
238270db83c4SJohan Hedberg 		return -ENOMEM;
238370db83c4SJohan Hedberg 	}
238470db83c4SJohan Hedberg 
2385defce9e8SJohan Hedberg 	chan->data = tfm_aes;
2386defce9e8SJohan Hedberg 
23875d88cc73SJohan Hedberg 	l2cap_add_scid(chan, L2CAP_CID_SMP);
238870db83c4SJohan Hedberg 
238970db83c4SJohan Hedberg 	l2cap_chan_set_defaults(chan);
239070db83c4SJohan Hedberg 
239170db83c4SJohan Hedberg 	bacpy(&chan->src, &hdev->bdaddr);
239270db83c4SJohan Hedberg 	chan->src_type = BDADDR_LE_PUBLIC;
239370db83c4SJohan Hedberg 	chan->state = BT_LISTEN;
239470db83c4SJohan Hedberg 	chan->mode = L2CAP_MODE_BASIC;
239570db83c4SJohan Hedberg 	chan->imtu = L2CAP_DEFAULT_MTU;
239670db83c4SJohan Hedberg 	chan->ops = &smp_root_chan_ops;
239770db83c4SJohan Hedberg 
2398abe84903SJohan Hedberg 	/* Set correct nesting level for a parent/listening channel */
2399abe84903SJohan Hedberg 	atomic_set(&chan->nesting, L2CAP_NESTING_PARENT);
2400abe84903SJohan Hedberg 
240170db83c4SJohan Hedberg 	hdev->smp_data = chan;
240270db83c4SJohan Hedberg 
2403711eafe3SJohan Hedberg 	return 0;
2404711eafe3SJohan Hedberg }
2405711eafe3SJohan Hedberg 
2406711eafe3SJohan Hedberg void smp_unregister(struct hci_dev *hdev)
2407711eafe3SJohan Hedberg {
240870db83c4SJohan Hedberg 	struct l2cap_chan *chan = hdev->smp_data;
2409defce9e8SJohan Hedberg 	struct crypto_blkcipher *tfm_aes;
241070db83c4SJohan Hedberg 
241170db83c4SJohan Hedberg 	if (!chan)
241270db83c4SJohan Hedberg 		return;
241370db83c4SJohan Hedberg 
241470db83c4SJohan Hedberg 	BT_DBG("%s chan %p", hdev->name, chan);
2415711eafe3SJohan Hedberg 
2416defce9e8SJohan Hedberg 	tfm_aes = chan->data;
2417defce9e8SJohan Hedberg 	if (tfm_aes) {
2418defce9e8SJohan Hedberg 		chan->data = NULL;
2419defce9e8SJohan Hedberg 		crypto_free_blkcipher(tfm_aes);
2420711eafe3SJohan Hedberg 	}
242170db83c4SJohan Hedberg 
242270db83c4SJohan Hedberg 	hdev->smp_data = NULL;
242370db83c4SJohan Hedberg 	l2cap_chan_put(chan);
2424711eafe3SJohan Hedberg }
2425