xref: /openbmc/linux/net/bluetooth/smp.c (revision 7f376cd6)
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 
35c7a3d57dSJohan Hedberg /* Low-level debug macros to be used for stuff that we don't want
36c7a3d57dSJohan Hedberg  * accidentially in dmesg, i.e. the values of the various crypto keys
37c7a3d57dSJohan Hedberg  * and the inputs & outputs of crypto functions.
38c7a3d57dSJohan Hedberg  */
39c7a3d57dSJohan Hedberg #ifdef DEBUG
40c7a3d57dSJohan Hedberg #define SMP_DBG(fmt, ...) printk(KERN_DEBUG "%s: " fmt, __func__, \
41c7a3d57dSJohan Hedberg 				 ##__VA_ARGS__)
42c7a3d57dSJohan Hedberg #else
43c7a3d57dSJohan Hedberg #define SMP_DBG(fmt, ...) no_printk(KERN_DEBUG "%s: " fmt, __func__, \
44c7a3d57dSJohan Hedberg 				    ##__VA_ARGS__)
45c7a3d57dSJohan Hedberg #endif
46c7a3d57dSJohan Hedberg 
47b28b4943SJohan Hedberg #define SMP_ALLOW_CMD(smp, code)	set_bit(code, &smp->allow_cmd)
48b28b4943SJohan Hedberg 
493b19146dSJohan Hedberg /* Keys which are not distributed with Secure Connections */
503b19146dSJohan Hedberg #define SMP_SC_NO_DIST (SMP_DIST_ENC_KEY | SMP_DIST_LINK_KEY);
513b19146dSJohan Hedberg 
5217b02e62SMarcel Holtmann #define SMP_TIMEOUT	msecs_to_jiffies(30000)
535d3de7dfSVinicius Costa Gomes 
540edb14deSJohan Hedberg #define AUTH_REQ_MASK(dev)	(test_bit(HCI_SC_ENABLED, &(dev)->dev_flags) ? \
550edb14deSJohan Hedberg 				 0x1f : 0x07)
5688d3a8acSJohan Hedberg #define KEY_DIST_MASK		0x07
57065a13e2SJohan Hedberg 
58cbbbe3e2SJohan Hedberg /* Maximum message length that can be passed to aes_cmac */
59cbbbe3e2SJohan Hedberg #define CMAC_MSG_MAX	80
60cbbbe3e2SJohan Hedberg 
61533e35d4SJohan Hedberg enum {
62533e35d4SJohan Hedberg 	SMP_FLAG_TK_VALID,
63533e35d4SJohan Hedberg 	SMP_FLAG_CFM_PENDING,
64533e35d4SJohan Hedberg 	SMP_FLAG_MITM_AUTH,
65533e35d4SJohan Hedberg 	SMP_FLAG_COMPLETE,
66533e35d4SJohan Hedberg 	SMP_FLAG_INITIATOR,
6765668776SJohan Hedberg 	SMP_FLAG_SC,
68d8f8edbeSJohan Hedberg 	SMP_FLAG_REMOTE_PK,
69aeb7d461SJohan Hedberg 	SMP_FLAG_DEBUG_KEY,
7038606f14SJohan Hedberg 	SMP_FLAG_WAIT_USER,
71d3e54a87SJohan Hedberg 	SMP_FLAG_DHKEY_PENDING,
7202b05bd8SJohan Hedberg 	SMP_FLAG_OOB,
73533e35d4SJohan Hedberg };
744bc58f51SJohan Hedberg 
754bc58f51SJohan Hedberg struct smp_chan {
764bc58f51SJohan Hedberg 	struct l2cap_conn	*conn;
77b68fda68SJohan Hedberg 	struct delayed_work	security_timer;
78b28b4943SJohan Hedberg 	unsigned long           allow_cmd; /* Bitmask of allowed commands */
79b68fda68SJohan Hedberg 
804bc58f51SJohan Hedberg 	u8		preq[7]; /* SMP Pairing Request */
814bc58f51SJohan Hedberg 	u8		prsp[7]; /* SMP Pairing Response */
824bc58f51SJohan Hedberg 	u8		prnd[16]; /* SMP Pairing Random (local) */
834bc58f51SJohan Hedberg 	u8		rrnd[16]; /* SMP Pairing Random (remote) */
844bc58f51SJohan Hedberg 	u8		pcnf[16]; /* SMP Pairing Confirm */
854bc58f51SJohan Hedberg 	u8		tk[16]; /* SMP Temporary Key */
86a29b0733SJohan Hedberg 	u8		rr[16];
874bc58f51SJohan Hedberg 	u8		enc_key_size;
884bc58f51SJohan Hedberg 	u8		remote_key_dist;
894bc58f51SJohan Hedberg 	bdaddr_t	id_addr;
904bc58f51SJohan Hedberg 	u8		id_addr_type;
914bc58f51SJohan Hedberg 	u8		irk[16];
924bc58f51SJohan Hedberg 	struct smp_csrk	*csrk;
934bc58f51SJohan Hedberg 	struct smp_csrk	*slave_csrk;
944bc58f51SJohan Hedberg 	struct smp_ltk	*ltk;
954bc58f51SJohan Hedberg 	struct smp_ltk	*slave_ltk;
964bc58f51SJohan Hedberg 	struct smp_irk	*remote_irk;
976a77083aSJohan Hedberg 	u8		*link_key;
984a74d658SJohan Hedberg 	unsigned long	flags;
99783e0574SJohan Hedberg 	u8		method;
10038606f14SJohan Hedberg 	u8		passkey_round;
1016a7bd103SJohan Hedberg 
1023b19146dSJohan Hedberg 	/* Secure Connections variables */
1033b19146dSJohan Hedberg 	u8			local_pk[64];
1043b19146dSJohan Hedberg 	u8			local_sk[32];
105d8f8edbeSJohan Hedberg 	u8			remote_pk[64];
106d8f8edbeSJohan Hedberg 	u8			dhkey[32];
107760b018bSJohan Hedberg 	u8			mackey[16];
1083b19146dSJohan Hedberg 
1096a7bd103SJohan Hedberg 	struct crypto_blkcipher	*tfm_aes;
110407cecf6SJohan Hedberg 	struct crypto_hash	*tfm_cmac;
1114bc58f51SJohan Hedberg };
1124bc58f51SJohan Hedberg 
113aeb7d461SJohan Hedberg /* These debug key values are defined in the SMP section of the core
114aeb7d461SJohan Hedberg  * specification. debug_pk is the public debug key and debug_sk the
115aeb7d461SJohan Hedberg  * private debug key.
116aeb7d461SJohan Hedberg  */
117aeb7d461SJohan Hedberg static const u8 debug_pk[64] = {
118aeb7d461SJohan Hedberg 		0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc,
119aeb7d461SJohan Hedberg 		0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef,
120aeb7d461SJohan Hedberg 		0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e,
121aeb7d461SJohan Hedberg 		0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20,
122aeb7d461SJohan Hedberg 
123aeb7d461SJohan Hedberg 		0x8b, 0xd2, 0x89, 0x15, 0xd0, 0x8e, 0x1c, 0x74,
124aeb7d461SJohan Hedberg 		0x24, 0x30, 0xed, 0x8f, 0xc2, 0x45, 0x63, 0x76,
125aeb7d461SJohan Hedberg 		0x5c, 0x15, 0x52, 0x5a, 0xbf, 0x9a, 0x32, 0x63,
126aeb7d461SJohan Hedberg 		0x6d, 0xeb, 0x2a, 0x65, 0x49, 0x9c, 0x80, 0xdc,
127aeb7d461SJohan Hedberg };
128aeb7d461SJohan Hedberg 
129aeb7d461SJohan Hedberg static const u8 debug_sk[32] = {
130aeb7d461SJohan Hedberg 		0xbd, 0x1a, 0x3c, 0xcd, 0xa6, 0xb8, 0x99, 0x58,
131aeb7d461SJohan Hedberg 		0x99, 0xb7, 0x40, 0xeb, 0x7b, 0x60, 0xff, 0x4a,
132aeb7d461SJohan Hedberg 		0x50, 0x3f, 0x10, 0xd2, 0xe3, 0xb3, 0xc9, 0x74,
133aeb7d461SJohan Hedberg 		0x38, 0x5f, 0xc5, 0xa3, 0xd4, 0xf6, 0x49, 0x3f,
134aeb7d461SJohan Hedberg };
135aeb7d461SJohan Hedberg 
1368a2936f4SJohan Hedberg static inline void swap_buf(const u8 *src, u8 *dst, size_t len)
137d22ef0bcSAnderson Briglia {
1388a2936f4SJohan Hedberg 	size_t i;
139d22ef0bcSAnderson Briglia 
1408a2936f4SJohan Hedberg 	for (i = 0; i < len; i++)
1418a2936f4SJohan Hedberg 		dst[len - 1 - i] = src[i];
142d22ef0bcSAnderson Briglia }
143d22ef0bcSAnderson Briglia 
14406edf8deSJohan Hedberg /* The following functions map to the LE SC SMP crypto functions
14506edf8deSJohan Hedberg  * AES-CMAC, f4, f5, f6, g2 and h6.
14606edf8deSJohan Hedberg  */
14706edf8deSJohan Hedberg 
148cbbbe3e2SJohan Hedberg static int aes_cmac(struct crypto_hash *tfm, const u8 k[16], const u8 *m,
149cbbbe3e2SJohan Hedberg 		    size_t len, u8 mac[16])
150cbbbe3e2SJohan Hedberg {
151cbbbe3e2SJohan Hedberg 	uint8_t tmp[16], mac_msb[16], msg_msb[CMAC_MSG_MAX];
152cbbbe3e2SJohan Hedberg 	struct hash_desc desc;
153cbbbe3e2SJohan Hedberg 	struct scatterlist sg;
154cbbbe3e2SJohan Hedberg 	int err;
155cbbbe3e2SJohan Hedberg 
156cbbbe3e2SJohan Hedberg 	if (len > CMAC_MSG_MAX)
157cbbbe3e2SJohan Hedberg 		return -EFBIG;
158cbbbe3e2SJohan Hedberg 
159cbbbe3e2SJohan Hedberg 	if (!tfm) {
160cbbbe3e2SJohan Hedberg 		BT_ERR("tfm %p", tfm);
161cbbbe3e2SJohan Hedberg 		return -EINVAL;
162cbbbe3e2SJohan Hedberg 	}
163cbbbe3e2SJohan Hedberg 
164cbbbe3e2SJohan Hedberg 	desc.tfm = tfm;
165cbbbe3e2SJohan Hedberg 	desc.flags = 0;
166cbbbe3e2SJohan Hedberg 
167cbbbe3e2SJohan Hedberg 	crypto_hash_init(&desc);
168cbbbe3e2SJohan Hedberg 
169cbbbe3e2SJohan Hedberg 	/* Swap key and message from LSB to MSB */
170cbbbe3e2SJohan Hedberg 	swap_buf(k, tmp, 16);
171cbbbe3e2SJohan Hedberg 	swap_buf(m, msg_msb, len);
172cbbbe3e2SJohan Hedberg 
173c7a3d57dSJohan Hedberg 	SMP_DBG("msg (len %zu) %*phN", len, (int) len, m);
174c7a3d57dSJohan Hedberg 	SMP_DBG("key %16phN", k);
175cbbbe3e2SJohan Hedberg 
176cbbbe3e2SJohan Hedberg 	err = crypto_hash_setkey(tfm, tmp, 16);
177cbbbe3e2SJohan Hedberg 	if (err) {
178cbbbe3e2SJohan Hedberg 		BT_ERR("cipher setkey failed: %d", err);
179cbbbe3e2SJohan Hedberg 		return err;
180cbbbe3e2SJohan Hedberg 	}
181cbbbe3e2SJohan Hedberg 
182cbbbe3e2SJohan Hedberg 	sg_init_one(&sg, msg_msb, len);
183cbbbe3e2SJohan Hedberg 
184cbbbe3e2SJohan Hedberg 	err = crypto_hash_update(&desc, &sg, len);
185cbbbe3e2SJohan Hedberg 	if (err) {
186cbbbe3e2SJohan Hedberg 		BT_ERR("Hash update error %d", err);
187cbbbe3e2SJohan Hedberg 		return err;
188cbbbe3e2SJohan Hedberg 	}
189cbbbe3e2SJohan Hedberg 
190cbbbe3e2SJohan Hedberg 	err = crypto_hash_final(&desc, mac_msb);
191cbbbe3e2SJohan Hedberg 	if (err) {
192cbbbe3e2SJohan Hedberg 		BT_ERR("Hash final error %d", err);
193cbbbe3e2SJohan Hedberg 		return err;
194cbbbe3e2SJohan Hedberg 	}
195cbbbe3e2SJohan Hedberg 
196cbbbe3e2SJohan Hedberg 	swap_buf(mac_msb, mac, 16);
197cbbbe3e2SJohan Hedberg 
198c7a3d57dSJohan Hedberg 	SMP_DBG("mac %16phN", mac);
199cbbbe3e2SJohan Hedberg 
200cbbbe3e2SJohan Hedberg 	return 0;
201cbbbe3e2SJohan Hedberg }
202cbbbe3e2SJohan Hedberg 
203cbbbe3e2SJohan Hedberg static int smp_f4(struct crypto_hash *tfm_cmac, const u8 u[32], const u8 v[32],
204cbbbe3e2SJohan Hedberg 		  const u8 x[16], u8 z, u8 res[16])
205cbbbe3e2SJohan Hedberg {
206cbbbe3e2SJohan Hedberg 	u8 m[65];
207cbbbe3e2SJohan Hedberg 	int err;
208cbbbe3e2SJohan Hedberg 
209c7a3d57dSJohan Hedberg 	SMP_DBG("u %32phN", u);
210c7a3d57dSJohan Hedberg 	SMP_DBG("v %32phN", v);
211c7a3d57dSJohan Hedberg 	SMP_DBG("x %16phN z %02x", x, z);
212cbbbe3e2SJohan Hedberg 
213cbbbe3e2SJohan Hedberg 	m[0] = z;
214cbbbe3e2SJohan Hedberg 	memcpy(m + 1, v, 32);
215cbbbe3e2SJohan Hedberg 	memcpy(m + 33, u, 32);
216cbbbe3e2SJohan Hedberg 
217cbbbe3e2SJohan Hedberg 	err = aes_cmac(tfm_cmac, x, m, sizeof(m), res);
218cbbbe3e2SJohan Hedberg 	if (err)
219cbbbe3e2SJohan Hedberg 		return err;
220cbbbe3e2SJohan Hedberg 
221c7a3d57dSJohan Hedberg 	SMP_DBG("res %16phN", res);
222cbbbe3e2SJohan Hedberg 
223cbbbe3e2SJohan Hedberg 	return err;
224cbbbe3e2SJohan Hedberg }
225cbbbe3e2SJohan Hedberg 
226760b018bSJohan Hedberg static int smp_f5(struct crypto_hash *tfm_cmac, u8 w[32], u8 n1[16], u8 n2[16],
227760b018bSJohan Hedberg 		  u8 a1[7], u8 a2[7], u8 mackey[16], u8 ltk[16])
228760b018bSJohan Hedberg {
229760b018bSJohan Hedberg 	/* The btle, salt and length "magic" values are as defined in
230760b018bSJohan Hedberg 	 * the SMP section of the Bluetooth core specification. In ASCII
231760b018bSJohan Hedberg 	 * the btle value ends up being 'btle'. The salt is just a
232760b018bSJohan Hedberg 	 * random number whereas length is the value 256 in little
233760b018bSJohan Hedberg 	 * endian format.
234760b018bSJohan Hedberg 	 */
235760b018bSJohan Hedberg 	const u8 btle[4] = { 0x65, 0x6c, 0x74, 0x62 };
236760b018bSJohan Hedberg 	const u8 salt[16] = { 0xbe, 0x83, 0x60, 0x5a, 0xdb, 0x0b, 0x37, 0x60,
237760b018bSJohan Hedberg 			      0x38, 0xa5, 0xf5, 0xaa, 0x91, 0x83, 0x88, 0x6c };
238760b018bSJohan Hedberg 	const u8 length[2] = { 0x00, 0x01 };
239760b018bSJohan Hedberg 	u8 m[53], t[16];
240760b018bSJohan Hedberg 	int err;
241760b018bSJohan Hedberg 
242c7a3d57dSJohan Hedberg 	SMP_DBG("w %32phN", w);
243c7a3d57dSJohan Hedberg 	SMP_DBG("n1 %16phN n2 %16phN", n1, n2);
244c7a3d57dSJohan Hedberg 	SMP_DBG("a1 %7phN a2 %7phN", a1, a2);
245760b018bSJohan Hedberg 
246760b018bSJohan Hedberg 	err = aes_cmac(tfm_cmac, salt, w, 32, t);
247760b018bSJohan Hedberg 	if (err)
248760b018bSJohan Hedberg 		return err;
249760b018bSJohan Hedberg 
250c7a3d57dSJohan Hedberg 	SMP_DBG("t %16phN", t);
251760b018bSJohan Hedberg 
252760b018bSJohan Hedberg 	memcpy(m, length, 2);
253760b018bSJohan Hedberg 	memcpy(m + 2, a2, 7);
254760b018bSJohan Hedberg 	memcpy(m + 9, a1, 7);
255760b018bSJohan Hedberg 	memcpy(m + 16, n2, 16);
256760b018bSJohan Hedberg 	memcpy(m + 32, n1, 16);
257760b018bSJohan Hedberg 	memcpy(m + 48, btle, 4);
258760b018bSJohan Hedberg 
259760b018bSJohan Hedberg 	m[52] = 0; /* Counter */
260760b018bSJohan Hedberg 
261760b018bSJohan Hedberg 	err = aes_cmac(tfm_cmac, t, m, sizeof(m), mackey);
262760b018bSJohan Hedberg 	if (err)
263760b018bSJohan Hedberg 		return err;
264760b018bSJohan Hedberg 
265c7a3d57dSJohan Hedberg 	SMP_DBG("mackey %16phN", mackey);
266760b018bSJohan Hedberg 
267760b018bSJohan Hedberg 	m[52] = 1; /* Counter */
268760b018bSJohan Hedberg 
269760b018bSJohan Hedberg 	err = aes_cmac(tfm_cmac, t, m, sizeof(m), ltk);
270760b018bSJohan Hedberg 	if (err)
271760b018bSJohan Hedberg 		return err;
272760b018bSJohan Hedberg 
273c7a3d57dSJohan Hedberg 	SMP_DBG("ltk %16phN", ltk);
274760b018bSJohan Hedberg 
275760b018bSJohan Hedberg 	return 0;
276760b018bSJohan Hedberg }
277760b018bSJohan Hedberg 
278760b018bSJohan Hedberg static int smp_f6(struct crypto_hash *tfm_cmac, const u8 w[16],
279760b018bSJohan Hedberg 		  const u8 n1[16], u8 n2[16], const u8 r[16],
280760b018bSJohan Hedberg 		  const u8 io_cap[3], const u8 a1[7], const u8 a2[7],
281760b018bSJohan Hedberg 		  u8 res[16])
282760b018bSJohan Hedberg {
283760b018bSJohan Hedberg 	u8 m[65];
284760b018bSJohan Hedberg 	int err;
285760b018bSJohan Hedberg 
286c7a3d57dSJohan Hedberg 	SMP_DBG("w %16phN", w);
287c7a3d57dSJohan Hedberg 	SMP_DBG("n1 %16phN n2 %16phN", n1, n2);
288c7a3d57dSJohan Hedberg 	SMP_DBG("r %16phN io_cap %3phN a1 %7phN a2 %7phN", r, io_cap, a1, a2);
289760b018bSJohan Hedberg 
290760b018bSJohan Hedberg 	memcpy(m, a2, 7);
291760b018bSJohan Hedberg 	memcpy(m + 7, a1, 7);
292760b018bSJohan Hedberg 	memcpy(m + 14, io_cap, 3);
293760b018bSJohan Hedberg 	memcpy(m + 17, r, 16);
294760b018bSJohan Hedberg 	memcpy(m + 33, n2, 16);
295760b018bSJohan Hedberg 	memcpy(m + 49, n1, 16);
296760b018bSJohan Hedberg 
297760b018bSJohan Hedberg 	err = aes_cmac(tfm_cmac, w, m, sizeof(m), res);
298760b018bSJohan Hedberg 	if (err)
299760b018bSJohan Hedberg 		return err;
300760b018bSJohan Hedberg 
301760b018bSJohan Hedberg 	BT_DBG("res %16phN", res);
302760b018bSJohan Hedberg 
303760b018bSJohan Hedberg 	return err;
304760b018bSJohan Hedberg }
305760b018bSJohan Hedberg 
306191dc7feSJohan Hedberg static int smp_g2(struct crypto_hash *tfm_cmac, const u8 u[32], const u8 v[32],
307191dc7feSJohan Hedberg 		  const u8 x[16], const u8 y[16], u32 *val)
308191dc7feSJohan Hedberg {
309191dc7feSJohan Hedberg 	u8 m[80], tmp[16];
310191dc7feSJohan Hedberg 	int err;
311191dc7feSJohan Hedberg 
312c7a3d57dSJohan Hedberg 	SMP_DBG("u %32phN", u);
313c7a3d57dSJohan Hedberg 	SMP_DBG("v %32phN", v);
314c7a3d57dSJohan Hedberg 	SMP_DBG("x %16phN y %16phN", x, y);
315191dc7feSJohan Hedberg 
316191dc7feSJohan Hedberg 	memcpy(m, y, 16);
317191dc7feSJohan Hedberg 	memcpy(m + 16, v, 32);
318191dc7feSJohan Hedberg 	memcpy(m + 48, u, 32);
319191dc7feSJohan Hedberg 
320191dc7feSJohan Hedberg 	err = aes_cmac(tfm_cmac, x, m, sizeof(m), tmp);
321191dc7feSJohan Hedberg 	if (err)
322191dc7feSJohan Hedberg 		return err;
323191dc7feSJohan Hedberg 
324191dc7feSJohan Hedberg 	*val = get_unaligned_le32(tmp);
325191dc7feSJohan Hedberg 	*val %= 1000000;
326191dc7feSJohan Hedberg 
327c7a3d57dSJohan Hedberg 	SMP_DBG("val %06u", *val);
328191dc7feSJohan Hedberg 
329191dc7feSJohan Hedberg 	return 0;
330191dc7feSJohan Hedberg }
331191dc7feSJohan Hedberg 
33206edf8deSJohan Hedberg static int smp_h6(struct crypto_hash *tfm_cmac, const u8 w[16],
33306edf8deSJohan Hedberg 		  const u8 key_id[4], u8 res[16])
33406edf8deSJohan Hedberg {
33506edf8deSJohan Hedberg 	int err;
33606edf8deSJohan Hedberg 
33706edf8deSJohan Hedberg 	SMP_DBG("w %16phN key_id %4phN", w, key_id);
33806edf8deSJohan Hedberg 
33906edf8deSJohan Hedberg 	err = aes_cmac(tfm_cmac, w, key_id, 4, res);
34006edf8deSJohan Hedberg 	if (err)
34106edf8deSJohan Hedberg 		return err;
34206edf8deSJohan Hedberg 
34306edf8deSJohan Hedberg 	SMP_DBG("res %16phN", res);
34406edf8deSJohan Hedberg 
34506edf8deSJohan Hedberg 	return err;
34606edf8deSJohan Hedberg }
34706edf8deSJohan Hedberg 
34806edf8deSJohan Hedberg /* The following functions map to the legacy SMP crypto functions e, c1,
34906edf8deSJohan Hedberg  * s1 and ah.
35006edf8deSJohan Hedberg  */
35106edf8deSJohan Hedberg 
352d22ef0bcSAnderson Briglia static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
353d22ef0bcSAnderson Briglia {
354d22ef0bcSAnderson Briglia 	struct blkcipher_desc desc;
355d22ef0bcSAnderson Briglia 	struct scatterlist sg;
356943a732aSJohan Hedberg 	uint8_t tmp[16], data[16];
357201a5929SJohan Hedberg 	int err;
358d22ef0bcSAnderson Briglia 
359*7f376cd6SJohan Hedberg 	if (!tfm) {
360d22ef0bcSAnderson Briglia 		BT_ERR("tfm %p", tfm);
361d22ef0bcSAnderson Briglia 		return -EINVAL;
362d22ef0bcSAnderson Briglia 	}
363d22ef0bcSAnderson Briglia 
364d22ef0bcSAnderson Briglia 	desc.tfm = tfm;
365d22ef0bcSAnderson Briglia 	desc.flags = 0;
366d22ef0bcSAnderson Briglia 
367943a732aSJohan Hedberg 	/* The most significant octet of key corresponds to k[0] */
3688a2936f4SJohan Hedberg 	swap_buf(k, tmp, 16);
369943a732aSJohan Hedberg 
370943a732aSJohan Hedberg 	err = crypto_blkcipher_setkey(tfm, tmp, 16);
371d22ef0bcSAnderson Briglia 	if (err) {
372d22ef0bcSAnderson Briglia 		BT_ERR("cipher setkey failed: %d", err);
373d22ef0bcSAnderson Briglia 		return err;
374d22ef0bcSAnderson Briglia 	}
375d22ef0bcSAnderson Briglia 
376943a732aSJohan Hedberg 	/* Most significant octet of plaintextData corresponds to data[0] */
3778a2936f4SJohan Hedberg 	swap_buf(r, data, 16);
378943a732aSJohan Hedberg 
379943a732aSJohan Hedberg 	sg_init_one(&sg, data, 16);
380d22ef0bcSAnderson Briglia 
381d22ef0bcSAnderson Briglia 	err = crypto_blkcipher_encrypt(&desc, &sg, &sg, 16);
382d22ef0bcSAnderson Briglia 	if (err)
383d22ef0bcSAnderson Briglia 		BT_ERR("Encrypt data error %d", err);
384d22ef0bcSAnderson Briglia 
385943a732aSJohan Hedberg 	/* Most significant octet of encryptedData corresponds to data[0] */
3868a2936f4SJohan Hedberg 	swap_buf(data, r, 16);
387943a732aSJohan Hedberg 
388d22ef0bcSAnderson Briglia 	return err;
389d22ef0bcSAnderson Briglia }
390d22ef0bcSAnderson Briglia 
39106edf8deSJohan Hedberg static int smp_c1(struct crypto_blkcipher *tfm_aes, const u8 k[16],
39206edf8deSJohan Hedberg 		  const u8 r[16], const u8 preq[7], const u8 pres[7], u8 _iat,
39306edf8deSJohan Hedberg 		  const bdaddr_t *ia, u8 _rat, const bdaddr_t *ra, u8 res[16])
39406edf8deSJohan Hedberg {
39506edf8deSJohan Hedberg 	u8 p1[16], p2[16];
39606edf8deSJohan Hedberg 	int err;
39706edf8deSJohan Hedberg 
39806edf8deSJohan Hedberg 	memset(p1, 0, 16);
39906edf8deSJohan Hedberg 
40006edf8deSJohan Hedberg 	/* p1 = pres || preq || _rat || _iat */
40106edf8deSJohan Hedberg 	p1[0] = _iat;
40206edf8deSJohan Hedberg 	p1[1] = _rat;
40306edf8deSJohan Hedberg 	memcpy(p1 + 2, preq, 7);
40406edf8deSJohan Hedberg 	memcpy(p1 + 9, pres, 7);
40506edf8deSJohan Hedberg 
40606edf8deSJohan Hedberg 	/* p2 = padding || ia || ra */
40706edf8deSJohan Hedberg 	memcpy(p2, ra, 6);
40806edf8deSJohan Hedberg 	memcpy(p2 + 6, ia, 6);
40906edf8deSJohan Hedberg 	memset(p2 + 12, 0, 4);
41006edf8deSJohan Hedberg 
41106edf8deSJohan Hedberg 	/* res = r XOR p1 */
41206edf8deSJohan Hedberg 	u128_xor((u128 *) res, (u128 *) r, (u128 *) p1);
41306edf8deSJohan Hedberg 
41406edf8deSJohan Hedberg 	/* res = e(k, res) */
41506edf8deSJohan Hedberg 	err = smp_e(tfm_aes, k, res);
41606edf8deSJohan Hedberg 	if (err) {
41706edf8deSJohan Hedberg 		BT_ERR("Encrypt data error");
41806edf8deSJohan Hedberg 		return err;
41906edf8deSJohan Hedberg 	}
42006edf8deSJohan Hedberg 
42106edf8deSJohan Hedberg 	/* res = res XOR p2 */
42206edf8deSJohan Hedberg 	u128_xor((u128 *) res, (u128 *) res, (u128 *) p2);
42306edf8deSJohan Hedberg 
42406edf8deSJohan Hedberg 	/* res = e(k, res) */
42506edf8deSJohan Hedberg 	err = smp_e(tfm_aes, k, res);
42606edf8deSJohan Hedberg 	if (err)
42706edf8deSJohan Hedberg 		BT_ERR("Encrypt data error");
42806edf8deSJohan Hedberg 
42906edf8deSJohan Hedberg 	return err;
43006edf8deSJohan Hedberg }
43106edf8deSJohan Hedberg 
43206edf8deSJohan Hedberg static int smp_s1(struct crypto_blkcipher *tfm_aes, const u8 k[16],
43306edf8deSJohan Hedberg 		  const u8 r1[16], const u8 r2[16], u8 _r[16])
4346a77083aSJohan Hedberg {
4356a77083aSJohan Hedberg 	int err;
4366a77083aSJohan Hedberg 
43706edf8deSJohan Hedberg 	/* Just least significant octets from r1 and r2 are considered */
43806edf8deSJohan Hedberg 	memcpy(_r, r2, 8);
43906edf8deSJohan Hedberg 	memcpy(_r + 8, r1, 8);
4406a77083aSJohan Hedberg 
44106edf8deSJohan Hedberg 	err = smp_e(tfm_aes, k, _r);
4426a77083aSJohan Hedberg 	if (err)
44306edf8deSJohan Hedberg 		BT_ERR("Encrypt data error");
4446a77083aSJohan Hedberg 
4456a77083aSJohan Hedberg 	return err;
4466a77083aSJohan Hedberg }
4476a77083aSJohan Hedberg 
448cd082797SJohan Hedberg static int smp_ah(struct crypto_blkcipher *tfm, const u8 irk[16],
449cd082797SJohan Hedberg 		  const u8 r[3], u8 res[3])
45060478054SJohan Hedberg {
451943a732aSJohan Hedberg 	u8 _res[16];
45260478054SJohan Hedberg 	int err;
45360478054SJohan Hedberg 
45460478054SJohan Hedberg 	/* r' = padding || r */
455943a732aSJohan Hedberg 	memcpy(_res, r, 3);
456943a732aSJohan Hedberg 	memset(_res + 3, 0, 13);
45760478054SJohan Hedberg 
458943a732aSJohan Hedberg 	err = smp_e(tfm, irk, _res);
45960478054SJohan Hedberg 	if (err) {
46060478054SJohan Hedberg 		BT_ERR("Encrypt error");
46160478054SJohan Hedberg 		return err;
46260478054SJohan Hedberg 	}
46360478054SJohan Hedberg 
46460478054SJohan Hedberg 	/* The output of the random address function ah is:
46560478054SJohan Hedberg 	 *	ah(h, r) = e(k, r') mod 2^24
46660478054SJohan Hedberg 	 * The output of the security function e is then truncated to 24 bits
46760478054SJohan Hedberg 	 * by taking the least significant 24 bits of the output of e as the
46860478054SJohan Hedberg 	 * result of ah.
46960478054SJohan Hedberg 	 */
470943a732aSJohan Hedberg 	memcpy(res, _res, 3);
47160478054SJohan Hedberg 
47260478054SJohan Hedberg 	return 0;
47360478054SJohan Hedberg }
47460478054SJohan Hedberg 
475cd082797SJohan Hedberg bool smp_irk_matches(struct hci_dev *hdev, const u8 irk[16],
476cd082797SJohan Hedberg 		     const bdaddr_t *bdaddr)
47760478054SJohan Hedberg {
478defce9e8SJohan Hedberg 	struct l2cap_chan *chan = hdev->smp_data;
479defce9e8SJohan Hedberg 	struct crypto_blkcipher *tfm;
48060478054SJohan Hedberg 	u8 hash[3];
48160478054SJohan Hedberg 	int err;
48260478054SJohan Hedberg 
483defce9e8SJohan Hedberg 	if (!chan || !chan->data)
484defce9e8SJohan Hedberg 		return false;
485defce9e8SJohan Hedberg 
486defce9e8SJohan Hedberg 	tfm = chan->data;
487defce9e8SJohan Hedberg 
48860478054SJohan Hedberg 	BT_DBG("RPA %pMR IRK %*phN", bdaddr, 16, irk);
48960478054SJohan Hedberg 
49060478054SJohan Hedberg 	err = smp_ah(tfm, irk, &bdaddr->b[3], hash);
49160478054SJohan Hedberg 	if (err)
49260478054SJohan Hedberg 		return false;
49360478054SJohan Hedberg 
49460478054SJohan Hedberg 	return !memcmp(bdaddr->b, hash, 3);
49560478054SJohan Hedberg }
49660478054SJohan Hedberg 
497cd082797SJohan Hedberg int smp_generate_rpa(struct hci_dev *hdev, const u8 irk[16], bdaddr_t *rpa)
498b1e2b3aeSJohan Hedberg {
499defce9e8SJohan Hedberg 	struct l2cap_chan *chan = hdev->smp_data;
500defce9e8SJohan Hedberg 	struct crypto_blkcipher *tfm;
501b1e2b3aeSJohan Hedberg 	int err;
502b1e2b3aeSJohan Hedberg 
503defce9e8SJohan Hedberg 	if (!chan || !chan->data)
504defce9e8SJohan Hedberg 		return -EOPNOTSUPP;
505defce9e8SJohan Hedberg 
506defce9e8SJohan Hedberg 	tfm = chan->data;
507defce9e8SJohan Hedberg 
508b1e2b3aeSJohan Hedberg 	get_random_bytes(&rpa->b[3], 3);
509b1e2b3aeSJohan Hedberg 
510b1e2b3aeSJohan Hedberg 	rpa->b[5] &= 0x3f;	/* Clear two most significant bits */
511b1e2b3aeSJohan Hedberg 	rpa->b[5] |= 0x40;	/* Set second most significant bit */
512b1e2b3aeSJohan Hedberg 
513b1e2b3aeSJohan Hedberg 	err = smp_ah(tfm, irk, &rpa->b[3], rpa->b);
514b1e2b3aeSJohan Hedberg 	if (err < 0)
515b1e2b3aeSJohan Hedberg 		return err;
516b1e2b3aeSJohan Hedberg 
517b1e2b3aeSJohan Hedberg 	BT_DBG("RPA %pMR", rpa);
518b1e2b3aeSJohan Hedberg 
519b1e2b3aeSJohan Hedberg 	return 0;
520b1e2b3aeSJohan Hedberg }
521b1e2b3aeSJohan Hedberg 
522eb492e01SAnderson Briglia static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
523eb492e01SAnderson Briglia {
5245d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
525b68fda68SJohan Hedberg 	struct smp_chan *smp;
5265d88cc73SJohan Hedberg 	struct kvec iv[2];
5275d88cc73SJohan Hedberg 	struct msghdr msg;
5285d88cc73SJohan Hedberg 
5295d88cc73SJohan Hedberg 	if (!chan)
5305d88cc73SJohan Hedberg 		return;
531eb492e01SAnderson Briglia 
532eb492e01SAnderson Briglia 	BT_DBG("code 0x%2.2x", code);
533eb492e01SAnderson Briglia 
5345d88cc73SJohan Hedberg 	iv[0].iov_base = &code;
5355d88cc73SJohan Hedberg 	iv[0].iov_len = 1;
536eb492e01SAnderson Briglia 
5375d88cc73SJohan Hedberg 	iv[1].iov_base = data;
5385d88cc73SJohan Hedberg 	iv[1].iov_len = len;
5395d88cc73SJohan Hedberg 
5405d88cc73SJohan Hedberg 	memset(&msg, 0, sizeof(msg));
5415d88cc73SJohan Hedberg 
5425d88cc73SJohan Hedberg 	msg.msg_iov = (struct iovec *) &iv;
5435d88cc73SJohan Hedberg 	msg.msg_iovlen = 2;
5445d88cc73SJohan Hedberg 
5455d88cc73SJohan Hedberg 	l2cap_chan_send(chan, &msg, 1 + len);
546e2dcd113SVinicius Costa Gomes 
547b68fda68SJohan Hedberg 	if (!chan->data)
548b68fda68SJohan Hedberg 		return;
549b68fda68SJohan Hedberg 
550b68fda68SJohan Hedberg 	smp = chan->data;
551b68fda68SJohan Hedberg 
552b68fda68SJohan Hedberg 	cancel_delayed_work_sync(&smp->security_timer);
553b68fda68SJohan Hedberg 	schedule_delayed_work(&smp->security_timer, SMP_TIMEOUT);
554eb492e01SAnderson Briglia }
555eb492e01SAnderson Briglia 
556d2eb9e10SJohan Hedberg static u8 authreq_to_seclevel(u8 authreq)
5572b64d153SBrian Gix {
558d2eb9e10SJohan Hedberg 	if (authreq & SMP_AUTH_MITM) {
559d2eb9e10SJohan Hedberg 		if (authreq & SMP_AUTH_SC)
560d2eb9e10SJohan Hedberg 			return BT_SECURITY_FIPS;
5612b64d153SBrian Gix 		else
562d2eb9e10SJohan Hedberg 			return BT_SECURITY_HIGH;
563d2eb9e10SJohan Hedberg 	} else {
5642b64d153SBrian Gix 		return BT_SECURITY_MEDIUM;
5652b64d153SBrian Gix 	}
566d2eb9e10SJohan Hedberg }
5672b64d153SBrian Gix 
5682b64d153SBrian Gix static __u8 seclevel_to_authreq(__u8 sec_level)
5692b64d153SBrian Gix {
5702b64d153SBrian Gix 	switch (sec_level) {
571d2eb9e10SJohan Hedberg 	case BT_SECURITY_FIPS:
5722b64d153SBrian Gix 	case BT_SECURITY_HIGH:
5732b64d153SBrian Gix 		return SMP_AUTH_MITM | SMP_AUTH_BONDING;
5742b64d153SBrian Gix 	case BT_SECURITY_MEDIUM:
5752b64d153SBrian Gix 		return SMP_AUTH_BONDING;
5762b64d153SBrian Gix 	default:
5772b64d153SBrian Gix 		return SMP_AUTH_NONE;
5782b64d153SBrian Gix 	}
5792b64d153SBrian Gix }
5802b64d153SBrian Gix 
581b8e66eacSVinicius Costa Gomes static void build_pairing_cmd(struct l2cap_conn *conn,
58254790f73SVinicius Costa Gomes 			      struct smp_cmd_pairing *req,
583f1560463SMarcel Holtmann 			      struct smp_cmd_pairing *rsp, __u8 authreq)
584b8e66eacSVinicius Costa Gomes {
5855d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
5865d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
587fd349c02SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
588fd349c02SJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
58902b05bd8SJohan Hedberg 	u8 local_dist = 0, remote_dist = 0, oob_flag = SMP_OOB_NOT_PRESENT;
59054790f73SVinicius Costa Gomes 
591b6ae8457SJohan Hedberg 	if (test_bit(HCI_BONDABLE, &conn->hcon->hdev->dev_flags)) {
5927ee4ea36SMarcel Holtmann 		local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
5937ee4ea36SMarcel Holtmann 		remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
59454790f73SVinicius Costa Gomes 		authreq |= SMP_AUTH_BONDING;
5952b64d153SBrian Gix 	} else {
5962b64d153SBrian Gix 		authreq &= ~SMP_AUTH_BONDING;
59754790f73SVinicius Costa Gomes 	}
59854790f73SVinicius Costa Gomes 
599fd349c02SJohan Hedberg 	if (test_bit(HCI_RPA_RESOLVING, &hdev->dev_flags))
600fd349c02SJohan Hedberg 		remote_dist |= SMP_DIST_ID_KEY;
601fd349c02SJohan Hedberg 
602863efaf2SJohan Hedberg 	if (test_bit(HCI_PRIVACY, &hdev->dev_flags))
603863efaf2SJohan Hedberg 		local_dist |= SMP_DIST_ID_KEY;
604863efaf2SJohan Hedberg 
60502b05bd8SJohan Hedberg 	if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags) &&
60602b05bd8SJohan Hedberg 	    (authreq & SMP_AUTH_SC)) {
60702b05bd8SJohan Hedberg 		struct oob_data *oob_data;
60802b05bd8SJohan Hedberg 		u8 bdaddr_type;
60902b05bd8SJohan Hedberg 
61002b05bd8SJohan Hedberg 		if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
611df8e1a4cSJohan Hedberg 			local_dist |= SMP_DIST_LINK_KEY;
612df8e1a4cSJohan Hedberg 			remote_dist |= SMP_DIST_LINK_KEY;
613df8e1a4cSJohan Hedberg 		}
61402b05bd8SJohan Hedberg 
61502b05bd8SJohan Hedberg 		if (hcon->dst_type == ADDR_LE_DEV_PUBLIC)
61602b05bd8SJohan Hedberg 			bdaddr_type = BDADDR_LE_PUBLIC;
61702b05bd8SJohan Hedberg 		else
61802b05bd8SJohan Hedberg 			bdaddr_type = BDADDR_LE_RANDOM;
61902b05bd8SJohan Hedberg 
62002b05bd8SJohan Hedberg 		oob_data = hci_find_remote_oob_data(hdev, &hcon->dst,
62102b05bd8SJohan Hedberg 						    bdaddr_type);
62202b05bd8SJohan Hedberg 		if (oob_data) {
62302b05bd8SJohan Hedberg 			set_bit(SMP_FLAG_OOB, &smp->flags);
62402b05bd8SJohan Hedberg 			oob_flag = SMP_OOB_PRESENT;
625a29b0733SJohan Hedberg 			memcpy(smp->rr, oob_data->rand256, 16);
62602b05bd8SJohan Hedberg 			memcpy(smp->pcnf, oob_data->hash256, 16);
62702b05bd8SJohan Hedberg 		}
62802b05bd8SJohan Hedberg 
629df8e1a4cSJohan Hedberg 	} else {
630df8e1a4cSJohan Hedberg 		authreq &= ~SMP_AUTH_SC;
631df8e1a4cSJohan Hedberg 	}
632df8e1a4cSJohan Hedberg 
63354790f73SVinicius Costa Gomes 	if (rsp == NULL) {
63454790f73SVinicius Costa Gomes 		req->io_capability = conn->hcon->io_capability;
63502b05bd8SJohan Hedberg 		req->oob_flag = oob_flag;
63654790f73SVinicius Costa Gomes 		req->max_key_size = SMP_MAX_ENC_KEY_SIZE;
637fd349c02SJohan Hedberg 		req->init_key_dist = local_dist;
638fd349c02SJohan Hedberg 		req->resp_key_dist = remote_dist;
6390edb14deSJohan Hedberg 		req->auth_req = (authreq & AUTH_REQ_MASK(hdev));
640fd349c02SJohan Hedberg 
641fd349c02SJohan Hedberg 		smp->remote_key_dist = remote_dist;
64254790f73SVinicius Costa Gomes 		return;
64354790f73SVinicius Costa Gomes 	}
64454790f73SVinicius Costa Gomes 
64554790f73SVinicius Costa Gomes 	rsp->io_capability = conn->hcon->io_capability;
64602b05bd8SJohan Hedberg 	rsp->oob_flag = oob_flag;
64754790f73SVinicius Costa Gomes 	rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE;
648fd349c02SJohan Hedberg 	rsp->init_key_dist = req->init_key_dist & remote_dist;
649fd349c02SJohan Hedberg 	rsp->resp_key_dist = req->resp_key_dist & local_dist;
6500edb14deSJohan Hedberg 	rsp->auth_req = (authreq & AUTH_REQ_MASK(hdev));
651fd349c02SJohan Hedberg 
652fd349c02SJohan Hedberg 	smp->remote_key_dist = rsp->init_key_dist;
653b8e66eacSVinicius Costa Gomes }
654b8e66eacSVinicius Costa Gomes 
6553158c50cSVinicius Costa Gomes static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
6563158c50cSVinicius Costa Gomes {
6575d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
6585d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
6591c1def09SVinicius Costa Gomes 
6603158c50cSVinicius Costa Gomes 	if ((max_key_size > SMP_MAX_ENC_KEY_SIZE) ||
6613158c50cSVinicius Costa Gomes 	    (max_key_size < SMP_MIN_ENC_KEY_SIZE))
6623158c50cSVinicius Costa Gomes 		return SMP_ENC_KEY_SIZE;
6633158c50cSVinicius Costa Gomes 
664f7aa611aSVinicius Costa Gomes 	smp->enc_key_size = max_key_size;
6653158c50cSVinicius Costa Gomes 
6663158c50cSVinicius Costa Gomes 	return 0;
6673158c50cSVinicius Costa Gomes }
6683158c50cSVinicius Costa Gomes 
6696f48e260SJohan Hedberg static void smp_chan_destroy(struct l2cap_conn *conn)
6706f48e260SJohan Hedberg {
6716f48e260SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
6726f48e260SJohan Hedberg 	struct smp_chan *smp = chan->data;
673923e2414SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
6746f48e260SJohan Hedberg 	bool complete;
6756f48e260SJohan Hedberg 
6766f48e260SJohan Hedberg 	BUG_ON(!smp);
6776f48e260SJohan Hedberg 
6786f48e260SJohan Hedberg 	cancel_delayed_work_sync(&smp->security_timer);
6796f48e260SJohan Hedberg 
6806f48e260SJohan Hedberg 	complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags);
681923e2414SJohan Hedberg 	mgmt_smp_complete(hcon, complete);
6826f48e260SJohan Hedberg 
6836f48e260SJohan Hedberg 	kfree(smp->csrk);
6846f48e260SJohan Hedberg 	kfree(smp->slave_csrk);
6856a77083aSJohan Hedberg 	kfree(smp->link_key);
6866f48e260SJohan Hedberg 
6876f48e260SJohan Hedberg 	crypto_free_blkcipher(smp->tfm_aes);
688407cecf6SJohan Hedberg 	crypto_free_hash(smp->tfm_cmac);
6896f48e260SJohan Hedberg 
690923e2414SJohan Hedberg 	/* Ensure that we don't leave any debug key around if debug key
691923e2414SJohan Hedberg 	 * support hasn't been explicitly enabled.
692923e2414SJohan Hedberg 	 */
693923e2414SJohan Hedberg 	if (smp->ltk && smp->ltk->type == SMP_LTK_P256_DEBUG &&
694923e2414SJohan Hedberg 	    !test_bit(HCI_KEEP_DEBUG_KEYS, &hcon->hdev->dev_flags)) {
695923e2414SJohan Hedberg 		list_del_rcu(&smp->ltk->list);
696923e2414SJohan Hedberg 		kfree_rcu(smp->ltk, rcu);
697923e2414SJohan Hedberg 		smp->ltk = NULL;
698923e2414SJohan Hedberg 	}
699923e2414SJohan Hedberg 
7006f48e260SJohan Hedberg 	/* If pairing failed clean up any keys we might have */
7016f48e260SJohan Hedberg 	if (!complete) {
7026f48e260SJohan Hedberg 		if (smp->ltk) {
703970d0f1bSJohan Hedberg 			list_del_rcu(&smp->ltk->list);
704970d0f1bSJohan Hedberg 			kfree_rcu(smp->ltk, rcu);
7056f48e260SJohan Hedberg 		}
7066f48e260SJohan Hedberg 
7076f48e260SJohan Hedberg 		if (smp->slave_ltk) {
708970d0f1bSJohan Hedberg 			list_del_rcu(&smp->slave_ltk->list);
709970d0f1bSJohan Hedberg 			kfree_rcu(smp->slave_ltk, rcu);
7106f48e260SJohan Hedberg 		}
7116f48e260SJohan Hedberg 
7126f48e260SJohan Hedberg 		if (smp->remote_irk) {
713adae20cbSJohan Hedberg 			list_del_rcu(&smp->remote_irk->list);
714adae20cbSJohan Hedberg 			kfree_rcu(smp->remote_irk, rcu);
7156f48e260SJohan Hedberg 		}
7166f48e260SJohan Hedberg 	}
7176f48e260SJohan Hedberg 
7186f48e260SJohan Hedberg 	chan->data = NULL;
7196f48e260SJohan Hedberg 	kfree(smp);
720923e2414SJohan Hedberg 	hci_conn_drop(hcon);
7216f48e260SJohan Hedberg }
7226f48e260SJohan Hedberg 
72384794e11SJohan Hedberg static void smp_failure(struct l2cap_conn *conn, u8 reason)
7244f957a76SBrian Gix {
725bab73cb6SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
726b68fda68SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
727bab73cb6SJohan Hedberg 
72884794e11SJohan Hedberg 	if (reason)
7294f957a76SBrian Gix 		smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
7304f957a76SBrian Gix 			     &reason);
7314f957a76SBrian Gix 
732ce39fb4eSMarcel Holtmann 	clear_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags);
733e1e930f5SJohan Hedberg 	mgmt_auth_failed(hcon, HCI_ERROR_AUTH_FAILURE);
734f1c09c07SVinicius Costa Gomes 
735fc75cc86SJohan Hedberg 	if (chan->data)
7364f957a76SBrian Gix 		smp_chan_destroy(conn);
7374f957a76SBrian Gix }
7384f957a76SBrian Gix 
7392b64d153SBrian Gix #define JUST_WORKS	0x00
7402b64d153SBrian Gix #define JUST_CFM	0x01
7412b64d153SBrian Gix #define REQ_PASSKEY	0x02
7422b64d153SBrian Gix #define CFM_PASSKEY	0x03
7432b64d153SBrian Gix #define REQ_OOB		0x04
7445e3d3d9bSJohan Hedberg #define DSP_PASSKEY	0x05
7452b64d153SBrian Gix #define OVERLAP		0xFF
7462b64d153SBrian Gix 
7472b64d153SBrian Gix static const u8 gen_method[5][5] = {
7482b64d153SBrian Gix 	{ JUST_WORKS,  JUST_CFM,    REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
7492b64d153SBrian Gix 	{ JUST_WORKS,  JUST_CFM,    REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
7502b64d153SBrian Gix 	{ CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
7512b64d153SBrian Gix 	{ JUST_WORKS,  JUST_CFM,    JUST_WORKS,  JUST_WORKS, JUST_CFM    },
7522b64d153SBrian Gix 	{ CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, OVERLAP     },
7532b64d153SBrian Gix };
7542b64d153SBrian Gix 
7555e3d3d9bSJohan Hedberg static const u8 sc_method[5][5] = {
7565e3d3d9bSJohan Hedberg 	{ JUST_WORKS,  JUST_CFM,    REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY },
7575e3d3d9bSJohan Hedberg 	{ JUST_WORKS,  CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
7585e3d3d9bSJohan Hedberg 	{ DSP_PASSKEY, DSP_PASSKEY, REQ_PASSKEY, JUST_WORKS, DSP_PASSKEY },
7595e3d3d9bSJohan Hedberg 	{ JUST_WORKS,  JUST_CFM,    JUST_WORKS,  JUST_WORKS, JUST_CFM    },
7605e3d3d9bSJohan Hedberg 	{ DSP_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY },
7615e3d3d9bSJohan Hedberg };
7625e3d3d9bSJohan Hedberg 
763581370ccSJohan Hedberg static u8 get_auth_method(struct smp_chan *smp, u8 local_io, u8 remote_io)
764581370ccSJohan Hedberg {
7652bcd4003SJohan Hedberg 	/* If either side has unknown io_caps, use JUST_CFM (which gets
7662bcd4003SJohan Hedberg 	 * converted later to JUST_WORKS if we're initiators.
7672bcd4003SJohan Hedberg 	 */
768581370ccSJohan Hedberg 	if (local_io > SMP_IO_KEYBOARD_DISPLAY ||
769581370ccSJohan Hedberg 	    remote_io > SMP_IO_KEYBOARD_DISPLAY)
7702bcd4003SJohan Hedberg 		return JUST_CFM;
771581370ccSJohan Hedberg 
7725e3d3d9bSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags))
7735e3d3d9bSJohan Hedberg 		return sc_method[remote_io][local_io];
7745e3d3d9bSJohan Hedberg 
775581370ccSJohan Hedberg 	return gen_method[remote_io][local_io];
776581370ccSJohan Hedberg }
777581370ccSJohan Hedberg 
7782b64d153SBrian Gix static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
7792b64d153SBrian Gix 						u8 local_io, u8 remote_io)
7802b64d153SBrian Gix {
7812b64d153SBrian Gix 	struct hci_conn *hcon = conn->hcon;
7825d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
7835d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
7842b64d153SBrian Gix 	u32 passkey = 0;
7852b64d153SBrian Gix 	int ret = 0;
7862b64d153SBrian Gix 
7872b64d153SBrian Gix 	/* Initialize key for JUST WORKS */
7882b64d153SBrian Gix 	memset(smp->tk, 0, sizeof(smp->tk));
7894a74d658SJohan Hedberg 	clear_bit(SMP_FLAG_TK_VALID, &smp->flags);
7902b64d153SBrian Gix 
7912b64d153SBrian Gix 	BT_DBG("tk_request: auth:%d lcl:%d rem:%d", auth, local_io, remote_io);
7922b64d153SBrian Gix 
7932bcd4003SJohan Hedberg 	/* If neither side wants MITM, either "just" confirm an incoming
7942bcd4003SJohan Hedberg 	 * request or use just-works for outgoing ones. The JUST_CFM
7952bcd4003SJohan Hedberg 	 * will be converted to JUST_WORKS if necessary later in this
7962bcd4003SJohan Hedberg 	 * function. If either side has MITM look up the method from the
7972bcd4003SJohan Hedberg 	 * table.
7982bcd4003SJohan Hedberg 	 */
799581370ccSJohan Hedberg 	if (!(auth & SMP_AUTH_MITM))
800783e0574SJohan Hedberg 		smp->method = JUST_CFM;
8012b64d153SBrian Gix 	else
802783e0574SJohan Hedberg 		smp->method = get_auth_method(smp, local_io, remote_io);
8032b64d153SBrian Gix 
804a82505c7SJohan Hedberg 	/* Don't confirm locally initiated pairing attempts */
805783e0574SJohan Hedberg 	if (smp->method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR,
806783e0574SJohan Hedberg 						&smp->flags))
807783e0574SJohan Hedberg 		smp->method = JUST_WORKS;
808a82505c7SJohan Hedberg 
80902f3e254SJohan Hedberg 	/* Don't bother user space with no IO capabilities */
810783e0574SJohan Hedberg 	if (smp->method == JUST_CFM &&
811783e0574SJohan Hedberg 	    hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
812783e0574SJohan Hedberg 		smp->method = JUST_WORKS;
81302f3e254SJohan Hedberg 
8142b64d153SBrian Gix 	/* If Just Works, Continue with Zero TK */
815783e0574SJohan Hedberg 	if (smp->method == JUST_WORKS) {
8164a74d658SJohan Hedberg 		set_bit(SMP_FLAG_TK_VALID, &smp->flags);
8172b64d153SBrian Gix 		return 0;
8182b64d153SBrian Gix 	}
8192b64d153SBrian Gix 
8202b64d153SBrian Gix 	/* Not Just Works/Confirm results in MITM Authentication */
821783e0574SJohan Hedberg 	if (smp->method != JUST_CFM) {
8224a74d658SJohan Hedberg 		set_bit(SMP_FLAG_MITM_AUTH, &smp->flags);
8235eb596f5SJohan Hedberg 		if (hcon->pending_sec_level < BT_SECURITY_HIGH)
8245eb596f5SJohan Hedberg 			hcon->pending_sec_level = BT_SECURITY_HIGH;
8255eb596f5SJohan Hedberg 	}
8262b64d153SBrian Gix 
8272b64d153SBrian Gix 	/* If both devices have Keyoard-Display I/O, the master
8282b64d153SBrian Gix 	 * Confirms and the slave Enters the passkey.
8292b64d153SBrian Gix 	 */
830783e0574SJohan Hedberg 	if (smp->method == OVERLAP) {
83140bef302SJohan Hedberg 		if (hcon->role == HCI_ROLE_MASTER)
832783e0574SJohan Hedberg 			smp->method = CFM_PASSKEY;
8332b64d153SBrian Gix 		else
834783e0574SJohan Hedberg 			smp->method = REQ_PASSKEY;
8352b64d153SBrian Gix 	}
8362b64d153SBrian Gix 
83701ad34d2SJohan Hedberg 	/* Generate random passkey. */
838783e0574SJohan Hedberg 	if (smp->method == CFM_PASSKEY) {
839943a732aSJohan Hedberg 		memset(smp->tk, 0, sizeof(smp->tk));
8402b64d153SBrian Gix 		get_random_bytes(&passkey, sizeof(passkey));
8412b64d153SBrian Gix 		passkey %= 1000000;
842943a732aSJohan Hedberg 		put_unaligned_le32(passkey, smp->tk);
8432b64d153SBrian Gix 		BT_DBG("PassKey: %d", passkey);
8444a74d658SJohan Hedberg 		set_bit(SMP_FLAG_TK_VALID, &smp->flags);
8452b64d153SBrian Gix 	}
8462b64d153SBrian Gix 
847783e0574SJohan Hedberg 	if (smp->method == REQ_PASSKEY)
848ce39fb4eSMarcel Holtmann 		ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst,
849272d90dfSJohan Hedberg 						hcon->type, hcon->dst_type);
850783e0574SJohan Hedberg 	else if (smp->method == JUST_CFM)
8514eb65e66SJohan Hedberg 		ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
8524eb65e66SJohan Hedberg 						hcon->type, hcon->dst_type,
8534eb65e66SJohan Hedberg 						passkey, 1);
8542b64d153SBrian Gix 	else
85501ad34d2SJohan Hedberg 		ret = mgmt_user_passkey_notify(hcon->hdev, &hcon->dst,
856272d90dfSJohan Hedberg 						hcon->type, hcon->dst_type,
85739adbffeSJohan Hedberg 						passkey, 0);
8582b64d153SBrian Gix 
8592b64d153SBrian Gix 	return ret;
8602b64d153SBrian Gix }
8612b64d153SBrian Gix 
8621cc61144SJohan Hedberg static u8 smp_confirm(struct smp_chan *smp)
8638aab4757SVinicius Costa Gomes {
8648aab4757SVinicius Costa Gomes 	struct l2cap_conn *conn = smp->conn;
8658aab4757SVinicius Costa Gomes 	struct smp_cmd_pairing_confirm cp;
8668aab4757SVinicius Costa Gomes 	int ret;
8678aab4757SVinicius Costa Gomes 
8688aab4757SVinicius Costa Gomes 	BT_DBG("conn %p", conn);
8698aab4757SVinicius Costa Gomes 
870e491eaf3SJohan Hedberg 	ret = smp_c1(smp->tfm_aes, smp->tk, smp->prnd, smp->preq, smp->prsp,
871b1cd5fd9SJohan Hedberg 		     conn->hcon->init_addr_type, &conn->hcon->init_addr,
872943a732aSJohan Hedberg 		     conn->hcon->resp_addr_type, &conn->hcon->resp_addr,
873943a732aSJohan Hedberg 		     cp.confirm_val);
8741cc61144SJohan Hedberg 	if (ret)
8751cc61144SJohan Hedberg 		return SMP_UNSPECIFIED;
8768aab4757SVinicius Costa Gomes 
8774a74d658SJohan Hedberg 	clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
8782b64d153SBrian Gix 
8798aab4757SVinicius Costa Gomes 	smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
8808aab4757SVinicius Costa Gomes 
881b28b4943SJohan Hedberg 	if (conn->hcon->out)
882b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
883b28b4943SJohan Hedberg 	else
884b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
885b28b4943SJohan Hedberg 
8861cc61144SJohan Hedberg 	return 0;
8878aab4757SVinicius Costa Gomes }
8888aab4757SVinicius Costa Gomes 
889861580a9SJohan Hedberg static u8 smp_random(struct smp_chan *smp)
8908aab4757SVinicius Costa Gomes {
8918aab4757SVinicius Costa Gomes 	struct l2cap_conn *conn = smp->conn;
8928aab4757SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
893861580a9SJohan Hedberg 	u8 confirm[16];
8948aab4757SVinicius Costa Gomes 	int ret;
8958aab4757SVinicius Costa Gomes 
896ec70f36fSJohan Hedberg 	if (IS_ERR_OR_NULL(smp->tfm_aes))
897861580a9SJohan Hedberg 		return SMP_UNSPECIFIED;
8988aab4757SVinicius Costa Gomes 
8998aab4757SVinicius Costa Gomes 	BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
9008aab4757SVinicius Costa Gomes 
901e491eaf3SJohan Hedberg 	ret = smp_c1(smp->tfm_aes, smp->tk, smp->rrnd, smp->preq, smp->prsp,
902b1cd5fd9SJohan Hedberg 		     hcon->init_addr_type, &hcon->init_addr,
903943a732aSJohan Hedberg 		     hcon->resp_addr_type, &hcon->resp_addr, confirm);
904861580a9SJohan Hedberg 	if (ret)
905861580a9SJohan Hedberg 		return SMP_UNSPECIFIED;
9068aab4757SVinicius Costa Gomes 
9078aab4757SVinicius Costa Gomes 	if (memcmp(smp->pcnf, confirm, sizeof(smp->pcnf)) != 0) {
9088aab4757SVinicius Costa Gomes 		BT_ERR("Pairing failed (confirmation values mismatch)");
909861580a9SJohan Hedberg 		return SMP_CONFIRM_FAILED;
9108aab4757SVinicius Costa Gomes 	}
9118aab4757SVinicius Costa Gomes 
9128aab4757SVinicius Costa Gomes 	if (hcon->out) {
913fe39c7b2SMarcel Holtmann 		u8 stk[16];
914fe39c7b2SMarcel Holtmann 		__le64 rand = 0;
915fe39c7b2SMarcel Holtmann 		__le16 ediv = 0;
9168aab4757SVinicius Costa Gomes 
917e491eaf3SJohan Hedberg 		smp_s1(smp->tfm_aes, smp->tk, smp->rrnd, smp->prnd, stk);
9188aab4757SVinicius Costa Gomes 
919f7aa611aSVinicius Costa Gomes 		memset(stk + smp->enc_key_size, 0,
920f7aa611aSVinicius Costa Gomes 		       SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
9218aab4757SVinicius Costa Gomes 
922861580a9SJohan Hedberg 		if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
923861580a9SJohan Hedberg 			return SMP_UNSPECIFIED;
9248aab4757SVinicius Costa Gomes 
9258aab4757SVinicius Costa Gomes 		hci_le_start_enc(hcon, ediv, rand, stk);
926f7aa611aSVinicius Costa Gomes 		hcon->enc_key_size = smp->enc_key_size;
927fe59a05fSJohan Hedberg 		set_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags);
9288aab4757SVinicius Costa Gomes 	} else {
929fff3490fSJohan Hedberg 		u8 stk[16], auth;
930fe39c7b2SMarcel Holtmann 		__le64 rand = 0;
931fe39c7b2SMarcel Holtmann 		__le16 ediv = 0;
9328aab4757SVinicius Costa Gomes 
933943a732aSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
934943a732aSJohan Hedberg 			     smp->prnd);
9358aab4757SVinicius Costa Gomes 
936e491eaf3SJohan Hedberg 		smp_s1(smp->tfm_aes, smp->tk, smp->prnd, smp->rrnd, stk);
9378aab4757SVinicius Costa Gomes 
938f7aa611aSVinicius Costa Gomes 		memset(stk + smp->enc_key_size, 0,
939f7aa611aSVinicius Costa Gomes 		       SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
9408aab4757SVinicius Costa Gomes 
941fff3490fSJohan Hedberg 		if (hcon->pending_sec_level == BT_SECURITY_HIGH)
942fff3490fSJohan Hedberg 			auth = 1;
943fff3490fSJohan Hedberg 		else
944fff3490fSJohan Hedberg 			auth = 0;
945fff3490fSJohan Hedberg 
9467d5843b7SJohan Hedberg 		/* Even though there's no _SLAVE suffix this is the
9477d5843b7SJohan Hedberg 		 * slave STK we're adding for later lookup (the master
9487d5843b7SJohan Hedberg 		 * STK never needs to be stored).
9497d5843b7SJohan Hedberg 		 */
950ce39fb4eSMarcel Holtmann 		hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
9512ceba539SJohan Hedberg 			    SMP_STK, auth, stk, smp->enc_key_size, ediv, rand);
9528aab4757SVinicius Costa Gomes 	}
9538aab4757SVinicius Costa Gomes 
954861580a9SJohan Hedberg 	return 0;
9558aab4757SVinicius Costa Gomes }
9568aab4757SVinicius Costa Gomes 
95744f1a7abSJohan Hedberg static void smp_notify_keys(struct l2cap_conn *conn)
95844f1a7abSJohan Hedberg {
95944f1a7abSJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
96044f1a7abSJohan Hedberg 	struct smp_chan *smp = chan->data;
96144f1a7abSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
96244f1a7abSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
96344f1a7abSJohan Hedberg 	struct smp_cmd_pairing *req = (void *) &smp->preq[1];
96444f1a7abSJohan Hedberg 	struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1];
96544f1a7abSJohan Hedberg 	bool persistent;
96644f1a7abSJohan Hedberg 
96744f1a7abSJohan Hedberg 	if (smp->remote_irk) {
96844f1a7abSJohan Hedberg 		mgmt_new_irk(hdev, smp->remote_irk);
96944f1a7abSJohan Hedberg 		/* Now that user space can be considered to know the
97044f1a7abSJohan Hedberg 		 * identity address track the connection based on it
971b5ae344dSJohan Hedberg 		 * from now on (assuming this is an LE link).
97244f1a7abSJohan Hedberg 		 */
973b5ae344dSJohan Hedberg 		if (hcon->type == LE_LINK) {
97444f1a7abSJohan Hedberg 			bacpy(&hcon->dst, &smp->remote_irk->bdaddr);
97544f1a7abSJohan Hedberg 			hcon->dst_type = smp->remote_irk->addr_type;
976f3d82d0cSJohan Hedberg 			queue_work(hdev->workqueue, &conn->id_addr_update_work);
977b5ae344dSJohan Hedberg 		}
97844f1a7abSJohan Hedberg 
97944f1a7abSJohan Hedberg 		/* When receiving an indentity resolving key for
98044f1a7abSJohan Hedberg 		 * a remote device that does not use a resolvable
98144f1a7abSJohan Hedberg 		 * private address, just remove the key so that
98244f1a7abSJohan Hedberg 		 * it is possible to use the controller white
98344f1a7abSJohan Hedberg 		 * list for scanning.
98444f1a7abSJohan Hedberg 		 *
98544f1a7abSJohan Hedberg 		 * Userspace will have been told to not store
98644f1a7abSJohan Hedberg 		 * this key at this point. So it is safe to
98744f1a7abSJohan Hedberg 		 * just remove it.
98844f1a7abSJohan Hedberg 		 */
98944f1a7abSJohan Hedberg 		if (!bacmp(&smp->remote_irk->rpa, BDADDR_ANY)) {
990adae20cbSJohan Hedberg 			list_del_rcu(&smp->remote_irk->list);
991adae20cbSJohan Hedberg 			kfree_rcu(smp->remote_irk, rcu);
99244f1a7abSJohan Hedberg 			smp->remote_irk = NULL;
99344f1a7abSJohan Hedberg 		}
99444f1a7abSJohan Hedberg 	}
99544f1a7abSJohan Hedberg 
996b5ae344dSJohan Hedberg 	if (hcon->type == ACL_LINK) {
997b5ae344dSJohan Hedberg 		if (hcon->key_type == HCI_LK_DEBUG_COMBINATION)
998b5ae344dSJohan Hedberg 			persistent = false;
999b5ae344dSJohan Hedberg 		else
1000b5ae344dSJohan Hedberg 			persistent = !test_bit(HCI_CONN_FLUSH_KEY,
1001b5ae344dSJohan Hedberg 					       &hcon->flags);
1002b5ae344dSJohan Hedberg 	} else {
100344f1a7abSJohan Hedberg 		/* The LTKs and CSRKs should be persistent only if both sides
100444f1a7abSJohan Hedberg 		 * had the bonding bit set in their authentication requests.
100544f1a7abSJohan Hedberg 		 */
1006b5ae344dSJohan Hedberg 		persistent = !!((req->auth_req & rsp->auth_req) &
1007b5ae344dSJohan Hedberg 				SMP_AUTH_BONDING);
1008b5ae344dSJohan Hedberg 	}
1009b5ae344dSJohan Hedberg 
101044f1a7abSJohan Hedberg 
101144f1a7abSJohan Hedberg 	if (smp->csrk) {
101244f1a7abSJohan Hedberg 		smp->csrk->bdaddr_type = hcon->dst_type;
101344f1a7abSJohan Hedberg 		bacpy(&smp->csrk->bdaddr, &hcon->dst);
101444f1a7abSJohan Hedberg 		mgmt_new_csrk(hdev, smp->csrk, persistent);
101544f1a7abSJohan Hedberg 	}
101644f1a7abSJohan Hedberg 
101744f1a7abSJohan Hedberg 	if (smp->slave_csrk) {
101844f1a7abSJohan Hedberg 		smp->slave_csrk->bdaddr_type = hcon->dst_type;
101944f1a7abSJohan Hedberg 		bacpy(&smp->slave_csrk->bdaddr, &hcon->dst);
102044f1a7abSJohan Hedberg 		mgmt_new_csrk(hdev, smp->slave_csrk, persistent);
102144f1a7abSJohan Hedberg 	}
102244f1a7abSJohan Hedberg 
102344f1a7abSJohan Hedberg 	if (smp->ltk) {
102444f1a7abSJohan Hedberg 		smp->ltk->bdaddr_type = hcon->dst_type;
102544f1a7abSJohan Hedberg 		bacpy(&smp->ltk->bdaddr, &hcon->dst);
102644f1a7abSJohan Hedberg 		mgmt_new_ltk(hdev, smp->ltk, persistent);
102744f1a7abSJohan Hedberg 	}
102844f1a7abSJohan Hedberg 
102944f1a7abSJohan Hedberg 	if (smp->slave_ltk) {
103044f1a7abSJohan Hedberg 		smp->slave_ltk->bdaddr_type = hcon->dst_type;
103144f1a7abSJohan Hedberg 		bacpy(&smp->slave_ltk->bdaddr, &hcon->dst);
103244f1a7abSJohan Hedberg 		mgmt_new_ltk(hdev, smp->slave_ltk, persistent);
103344f1a7abSJohan Hedberg 	}
10346a77083aSJohan Hedberg 
10356a77083aSJohan Hedberg 	if (smp->link_key) {
1036e3befab9SJohan Hedberg 		struct link_key *key;
1037e3befab9SJohan Hedberg 		u8 type;
1038e3befab9SJohan Hedberg 
1039e3befab9SJohan Hedberg 		if (test_bit(SMP_FLAG_DEBUG_KEY, &smp->flags))
1040e3befab9SJohan Hedberg 			type = HCI_LK_DEBUG_COMBINATION;
1041e3befab9SJohan Hedberg 		else if (hcon->sec_level == BT_SECURITY_FIPS)
1042e3befab9SJohan Hedberg 			type = HCI_LK_AUTH_COMBINATION_P256;
1043e3befab9SJohan Hedberg 		else
1044e3befab9SJohan Hedberg 			type = HCI_LK_UNAUTH_COMBINATION_P256;
1045e3befab9SJohan Hedberg 
1046e3befab9SJohan Hedberg 		key = hci_add_link_key(hdev, smp->conn->hcon, &hcon->dst,
1047e3befab9SJohan Hedberg 				       smp->link_key, type, 0, &persistent);
1048e3befab9SJohan Hedberg 		if (key) {
1049e3befab9SJohan Hedberg 			mgmt_new_link_key(hdev, key, persistent);
1050e3befab9SJohan Hedberg 
1051e3befab9SJohan Hedberg 			/* Don't keep debug keys around if the relevant
1052e3befab9SJohan Hedberg 			 * flag is not set.
1053e3befab9SJohan Hedberg 			 */
1054e3befab9SJohan Hedberg 			if (!test_bit(HCI_KEEP_DEBUG_KEYS, &hdev->dev_flags) &&
1055e3befab9SJohan Hedberg 			    key->type == HCI_LK_DEBUG_COMBINATION) {
1056e3befab9SJohan Hedberg 				list_del_rcu(&key->list);
1057e3befab9SJohan Hedberg 				kfree_rcu(key, rcu);
1058e3befab9SJohan Hedberg 			}
1059e3befab9SJohan Hedberg 		}
10606a77083aSJohan Hedberg 	}
10616a77083aSJohan Hedberg }
10626a77083aSJohan Hedberg 
1063d3e54a87SJohan Hedberg static void sc_add_ltk(struct smp_chan *smp)
1064d3e54a87SJohan Hedberg {
1065d3e54a87SJohan Hedberg 	struct hci_conn *hcon = smp->conn->hcon;
1066d3e54a87SJohan Hedberg 	u8 key_type, auth;
1067d3e54a87SJohan Hedberg 
1068d3e54a87SJohan Hedberg 	if (test_bit(SMP_FLAG_DEBUG_KEY, &smp->flags))
1069d3e54a87SJohan Hedberg 		key_type = SMP_LTK_P256_DEBUG;
1070d3e54a87SJohan Hedberg 	else
1071d3e54a87SJohan Hedberg 		key_type = SMP_LTK_P256;
1072d3e54a87SJohan Hedberg 
1073d3e54a87SJohan Hedberg 	if (hcon->pending_sec_level == BT_SECURITY_FIPS)
1074d3e54a87SJohan Hedberg 		auth = 1;
1075d3e54a87SJohan Hedberg 	else
1076d3e54a87SJohan Hedberg 		auth = 0;
1077d3e54a87SJohan Hedberg 
1078d3e54a87SJohan Hedberg 	memset(smp->tk + smp->enc_key_size, 0,
1079d3e54a87SJohan Hedberg 	       SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
1080d3e54a87SJohan Hedberg 
1081d3e54a87SJohan Hedberg 	smp->ltk = hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
1082d3e54a87SJohan Hedberg 			       key_type, auth, smp->tk, smp->enc_key_size,
1083d3e54a87SJohan Hedberg 			       0, 0);
1084d3e54a87SJohan Hedberg }
1085d3e54a87SJohan Hedberg 
10866a77083aSJohan Hedberg static void sc_generate_link_key(struct smp_chan *smp)
10876a77083aSJohan Hedberg {
10886a77083aSJohan Hedberg 	/* These constants are as specified in the core specification.
10896a77083aSJohan Hedberg 	 * In ASCII they spell out to 'tmp1' and 'lebr'.
10906a77083aSJohan Hedberg 	 */
10916a77083aSJohan Hedberg 	const u8 tmp1[4] = { 0x31, 0x70, 0x6d, 0x74 };
10926a77083aSJohan Hedberg 	const u8 lebr[4] = { 0x72, 0x62, 0x65, 0x6c };
10936a77083aSJohan Hedberg 
10946a77083aSJohan Hedberg 	smp->link_key = kzalloc(16, GFP_KERNEL);
10956a77083aSJohan Hedberg 	if (!smp->link_key)
10966a77083aSJohan Hedberg 		return;
10976a77083aSJohan Hedberg 
10986a77083aSJohan Hedberg 	if (smp_h6(smp->tfm_cmac, smp->tk, tmp1, smp->link_key)) {
10996a77083aSJohan Hedberg 		kfree(smp->link_key);
11006a77083aSJohan Hedberg 		smp->link_key = NULL;
11016a77083aSJohan Hedberg 		return;
11026a77083aSJohan Hedberg 	}
11036a77083aSJohan Hedberg 
11046a77083aSJohan Hedberg 	if (smp_h6(smp->tfm_cmac, smp->link_key, lebr, smp->link_key)) {
11056a77083aSJohan Hedberg 		kfree(smp->link_key);
11066a77083aSJohan Hedberg 		smp->link_key = NULL;
11076a77083aSJohan Hedberg 		return;
11086a77083aSJohan Hedberg 	}
110944f1a7abSJohan Hedberg }
111044f1a7abSJohan Hedberg 
1111b28b4943SJohan Hedberg static void smp_allow_key_dist(struct smp_chan *smp)
1112b28b4943SJohan Hedberg {
1113b28b4943SJohan Hedberg 	/* Allow the first expected phase 3 PDU. The rest of the PDUs
1114b28b4943SJohan Hedberg 	 * will be allowed in each PDU handler to ensure we receive
1115b28b4943SJohan Hedberg 	 * them in the correct order.
1116b28b4943SJohan Hedberg 	 */
1117b28b4943SJohan Hedberg 	if (smp->remote_key_dist & SMP_DIST_ENC_KEY)
1118b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_ENCRYPT_INFO);
1119b28b4943SJohan Hedberg 	else if (smp->remote_key_dist & SMP_DIST_ID_KEY)
1120b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO);
1121b28b4943SJohan Hedberg 	else if (smp->remote_key_dist & SMP_DIST_SIGN)
1122b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO);
1123b28b4943SJohan Hedberg }
1124b28b4943SJohan Hedberg 
1125b5ae344dSJohan Hedberg static void sc_generate_ltk(struct smp_chan *smp)
1126b5ae344dSJohan Hedberg {
1127b5ae344dSJohan Hedberg 	/* These constants are as specified in the core specification.
1128b5ae344dSJohan Hedberg 	 * In ASCII they spell out to 'tmp2' and 'brle'.
1129b5ae344dSJohan Hedberg 	 */
1130b5ae344dSJohan Hedberg 	const u8 tmp2[4] = { 0x32, 0x70, 0x6d, 0x74 };
1131b5ae344dSJohan Hedberg 	const u8 brle[4] = { 0x65, 0x6c, 0x72, 0x62 };
1132b5ae344dSJohan Hedberg 	struct hci_conn *hcon = smp->conn->hcon;
1133b5ae344dSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
1134b5ae344dSJohan Hedberg 	struct link_key *key;
1135b5ae344dSJohan Hedberg 
1136b5ae344dSJohan Hedberg 	key = hci_find_link_key(hdev, &hcon->dst);
1137b5ae344dSJohan Hedberg 	if (!key) {
1138b5ae344dSJohan Hedberg 		BT_ERR("%s No Link Key found to generate LTK", hdev->name);
1139b5ae344dSJohan Hedberg 		return;
1140b5ae344dSJohan Hedberg 	}
1141b5ae344dSJohan Hedberg 
1142b5ae344dSJohan Hedberg 	if (key->type == HCI_LK_DEBUG_COMBINATION)
1143b5ae344dSJohan Hedberg 		set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags);
1144b5ae344dSJohan Hedberg 
1145b5ae344dSJohan Hedberg 	if (smp_h6(smp->tfm_cmac, key->val, tmp2, smp->tk))
1146b5ae344dSJohan Hedberg 		return;
1147b5ae344dSJohan Hedberg 
1148b5ae344dSJohan Hedberg 	if (smp_h6(smp->tfm_cmac, smp->tk, brle, smp->tk))
1149b5ae344dSJohan Hedberg 		return;
1150b5ae344dSJohan Hedberg 
1151b5ae344dSJohan Hedberg 	sc_add_ltk(smp);
1152b5ae344dSJohan Hedberg }
1153b5ae344dSJohan Hedberg 
1154d6268e86SJohan Hedberg static void smp_distribute_keys(struct smp_chan *smp)
115544f1a7abSJohan Hedberg {
115644f1a7abSJohan Hedberg 	struct smp_cmd_pairing *req, *rsp;
115786d1407cSJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
115844f1a7abSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
115944f1a7abSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
116044f1a7abSJohan Hedberg 	__u8 *keydist;
116144f1a7abSJohan Hedberg 
116244f1a7abSJohan Hedberg 	BT_DBG("conn %p", conn);
116344f1a7abSJohan Hedberg 
116444f1a7abSJohan Hedberg 	rsp = (void *) &smp->prsp[1];
116544f1a7abSJohan Hedberg 
116644f1a7abSJohan Hedberg 	/* The responder sends its keys first */
1167b28b4943SJohan Hedberg 	if (hcon->out && (smp->remote_key_dist & KEY_DIST_MASK)) {
1168b28b4943SJohan Hedberg 		smp_allow_key_dist(smp);
116986d1407cSJohan Hedberg 		return;
1170b28b4943SJohan Hedberg 	}
117144f1a7abSJohan Hedberg 
117244f1a7abSJohan Hedberg 	req = (void *) &smp->preq[1];
117344f1a7abSJohan Hedberg 
117444f1a7abSJohan Hedberg 	if (hcon->out) {
117544f1a7abSJohan Hedberg 		keydist = &rsp->init_key_dist;
117644f1a7abSJohan Hedberg 		*keydist &= req->init_key_dist;
117744f1a7abSJohan Hedberg 	} else {
117844f1a7abSJohan Hedberg 		keydist = &rsp->resp_key_dist;
117944f1a7abSJohan Hedberg 		*keydist &= req->resp_key_dist;
118044f1a7abSJohan Hedberg 	}
118144f1a7abSJohan Hedberg 
11826a77083aSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
1183b5ae344dSJohan Hedberg 		if (hcon->type == LE_LINK && (*keydist & SMP_DIST_LINK_KEY))
11846a77083aSJohan Hedberg 			sc_generate_link_key(smp);
1185b5ae344dSJohan Hedberg 		if (hcon->type == ACL_LINK && (*keydist & SMP_DIST_ENC_KEY))
1186b5ae344dSJohan Hedberg 			sc_generate_ltk(smp);
11876a77083aSJohan Hedberg 
11886a77083aSJohan Hedberg 		/* Clear the keys which are generated but not distributed */
11896a77083aSJohan Hedberg 		*keydist &= ~SMP_SC_NO_DIST;
11906a77083aSJohan Hedberg 	}
11916a77083aSJohan Hedberg 
119244f1a7abSJohan Hedberg 	BT_DBG("keydist 0x%x", *keydist);
119344f1a7abSJohan Hedberg 
119444f1a7abSJohan Hedberg 	if (*keydist & SMP_DIST_ENC_KEY) {
119544f1a7abSJohan Hedberg 		struct smp_cmd_encrypt_info enc;
119644f1a7abSJohan Hedberg 		struct smp_cmd_master_ident ident;
119744f1a7abSJohan Hedberg 		struct smp_ltk *ltk;
119844f1a7abSJohan Hedberg 		u8 authenticated;
119944f1a7abSJohan Hedberg 		__le16 ediv;
120044f1a7abSJohan Hedberg 		__le64 rand;
120144f1a7abSJohan Hedberg 
120244f1a7abSJohan Hedberg 		get_random_bytes(enc.ltk, sizeof(enc.ltk));
120344f1a7abSJohan Hedberg 		get_random_bytes(&ediv, sizeof(ediv));
120444f1a7abSJohan Hedberg 		get_random_bytes(&rand, sizeof(rand));
120544f1a7abSJohan Hedberg 
120644f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
120744f1a7abSJohan Hedberg 
120844f1a7abSJohan Hedberg 		authenticated = hcon->sec_level == BT_SECURITY_HIGH;
120944f1a7abSJohan Hedberg 		ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type,
121044f1a7abSJohan Hedberg 				  SMP_LTK_SLAVE, authenticated, enc.ltk,
121144f1a7abSJohan Hedberg 				  smp->enc_key_size, ediv, rand);
121244f1a7abSJohan Hedberg 		smp->slave_ltk = ltk;
121344f1a7abSJohan Hedberg 
121444f1a7abSJohan Hedberg 		ident.ediv = ediv;
121544f1a7abSJohan Hedberg 		ident.rand = rand;
121644f1a7abSJohan Hedberg 
121744f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident);
121844f1a7abSJohan Hedberg 
121944f1a7abSJohan Hedberg 		*keydist &= ~SMP_DIST_ENC_KEY;
122044f1a7abSJohan Hedberg 	}
122144f1a7abSJohan Hedberg 
122244f1a7abSJohan Hedberg 	if (*keydist & SMP_DIST_ID_KEY) {
122344f1a7abSJohan Hedberg 		struct smp_cmd_ident_addr_info addrinfo;
122444f1a7abSJohan Hedberg 		struct smp_cmd_ident_info idinfo;
122544f1a7abSJohan Hedberg 
122644f1a7abSJohan Hedberg 		memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk));
122744f1a7abSJohan Hedberg 
122844f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo);
122944f1a7abSJohan Hedberg 
123044f1a7abSJohan Hedberg 		/* The hci_conn contains the local identity address
123144f1a7abSJohan Hedberg 		 * after the connection has been established.
123244f1a7abSJohan Hedberg 		 *
123344f1a7abSJohan Hedberg 		 * This is true even when the connection has been
123444f1a7abSJohan Hedberg 		 * established using a resolvable random address.
123544f1a7abSJohan Hedberg 		 */
123644f1a7abSJohan Hedberg 		bacpy(&addrinfo.bdaddr, &hcon->src);
123744f1a7abSJohan Hedberg 		addrinfo.addr_type = hcon->src_type;
123844f1a7abSJohan Hedberg 
123944f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo),
124044f1a7abSJohan Hedberg 			     &addrinfo);
124144f1a7abSJohan Hedberg 
124244f1a7abSJohan Hedberg 		*keydist &= ~SMP_DIST_ID_KEY;
124344f1a7abSJohan Hedberg 	}
124444f1a7abSJohan Hedberg 
124544f1a7abSJohan Hedberg 	if (*keydist & SMP_DIST_SIGN) {
124644f1a7abSJohan Hedberg 		struct smp_cmd_sign_info sign;
124744f1a7abSJohan Hedberg 		struct smp_csrk *csrk;
124844f1a7abSJohan Hedberg 
124944f1a7abSJohan Hedberg 		/* Generate a new random key */
125044f1a7abSJohan Hedberg 		get_random_bytes(sign.csrk, sizeof(sign.csrk));
125144f1a7abSJohan Hedberg 
125244f1a7abSJohan Hedberg 		csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
125344f1a7abSJohan Hedberg 		if (csrk) {
125444f1a7abSJohan Hedberg 			csrk->master = 0x00;
125544f1a7abSJohan Hedberg 			memcpy(csrk->val, sign.csrk, sizeof(csrk->val));
125644f1a7abSJohan Hedberg 		}
125744f1a7abSJohan Hedberg 		smp->slave_csrk = csrk;
125844f1a7abSJohan Hedberg 
125944f1a7abSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign);
126044f1a7abSJohan Hedberg 
126144f1a7abSJohan Hedberg 		*keydist &= ~SMP_DIST_SIGN;
126244f1a7abSJohan Hedberg 	}
126344f1a7abSJohan Hedberg 
126444f1a7abSJohan Hedberg 	/* If there are still keys to be received wait for them */
1265b28b4943SJohan Hedberg 	if (smp->remote_key_dist & KEY_DIST_MASK) {
1266b28b4943SJohan Hedberg 		smp_allow_key_dist(smp);
126786d1407cSJohan Hedberg 		return;
1268b28b4943SJohan Hedberg 	}
126944f1a7abSJohan Hedberg 
127044f1a7abSJohan Hedberg 	set_bit(SMP_FLAG_COMPLETE, &smp->flags);
127144f1a7abSJohan Hedberg 	smp_notify_keys(conn);
127244f1a7abSJohan Hedberg 
127344f1a7abSJohan Hedberg 	smp_chan_destroy(conn);
127444f1a7abSJohan Hedberg }
127544f1a7abSJohan Hedberg 
1276b68fda68SJohan Hedberg static void smp_timeout(struct work_struct *work)
1277b68fda68SJohan Hedberg {
1278b68fda68SJohan Hedberg 	struct smp_chan *smp = container_of(work, struct smp_chan,
1279b68fda68SJohan Hedberg 					    security_timer.work);
1280b68fda68SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
1281b68fda68SJohan Hedberg 
1282b68fda68SJohan Hedberg 	BT_DBG("conn %p", conn);
1283b68fda68SJohan Hedberg 
12841e91c29eSJohan Hedberg 	hci_disconnect(conn->hcon, HCI_ERROR_REMOTE_USER_TERM);
1285b68fda68SJohan Hedberg }
1286b68fda68SJohan Hedberg 
12878aab4757SVinicius Costa Gomes static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
12888aab4757SVinicius Costa Gomes {
12895d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
12908aab4757SVinicius Costa Gomes 	struct smp_chan *smp;
12918aab4757SVinicius Costa Gomes 
1292f1560463SMarcel Holtmann 	smp = kzalloc(sizeof(*smp), GFP_ATOMIC);
1293fc75cc86SJohan Hedberg 	if (!smp)
12948aab4757SVinicius Costa Gomes 		return NULL;
12958aab4757SVinicius Costa Gomes 
12966a7bd103SJohan Hedberg 	smp->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
12976a7bd103SJohan Hedberg 	if (IS_ERR(smp->tfm_aes)) {
12986a7bd103SJohan Hedberg 		BT_ERR("Unable to create ECB crypto context");
12996a7bd103SJohan Hedberg 		kfree(smp);
13006a7bd103SJohan Hedberg 		return NULL;
13016a7bd103SJohan Hedberg 	}
13026a7bd103SJohan Hedberg 
1303407cecf6SJohan Hedberg 	smp->tfm_cmac = crypto_alloc_hash("cmac(aes)", 0, CRYPTO_ALG_ASYNC);
1304407cecf6SJohan Hedberg 	if (IS_ERR(smp->tfm_cmac)) {
1305407cecf6SJohan Hedberg 		BT_ERR("Unable to create CMAC crypto context");
1306407cecf6SJohan Hedberg 		crypto_free_blkcipher(smp->tfm_aes);
1307407cecf6SJohan Hedberg 		kfree(smp);
1308407cecf6SJohan Hedberg 		return NULL;
1309407cecf6SJohan Hedberg 	}
1310407cecf6SJohan Hedberg 
13118aab4757SVinicius Costa Gomes 	smp->conn = conn;
13125d88cc73SJohan Hedberg 	chan->data = smp;
13138aab4757SVinicius Costa Gomes 
1314b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_FAIL);
1315b28b4943SJohan Hedberg 
1316b68fda68SJohan Hedberg 	INIT_DELAYED_WORK(&smp->security_timer, smp_timeout);
1317b68fda68SJohan Hedberg 
13188aab4757SVinicius Costa Gomes 	hci_conn_hold(conn->hcon);
13198aab4757SVinicius Costa Gomes 
13208aab4757SVinicius Costa Gomes 	return smp;
13218aab4757SVinicius Costa Gomes }
13228aab4757SVinicius Costa Gomes 
1323760b018bSJohan Hedberg static int sc_mackey_and_ltk(struct smp_chan *smp, u8 mackey[16], u8 ltk[16])
1324760b018bSJohan Hedberg {
1325760b018bSJohan Hedberg 	struct hci_conn *hcon = smp->conn->hcon;
1326760b018bSJohan Hedberg 	u8 *na, *nb, a[7], b[7];
1327760b018bSJohan Hedberg 
1328760b018bSJohan Hedberg 	if (hcon->out) {
1329760b018bSJohan Hedberg 		na   = smp->prnd;
1330760b018bSJohan Hedberg 		nb   = smp->rrnd;
1331760b018bSJohan Hedberg 	} else {
1332760b018bSJohan Hedberg 		na   = smp->rrnd;
1333760b018bSJohan Hedberg 		nb   = smp->prnd;
1334760b018bSJohan Hedberg 	}
1335760b018bSJohan Hedberg 
1336760b018bSJohan Hedberg 	memcpy(a, &hcon->init_addr, 6);
1337760b018bSJohan Hedberg 	memcpy(b, &hcon->resp_addr, 6);
1338760b018bSJohan Hedberg 	a[6] = hcon->init_addr_type;
1339760b018bSJohan Hedberg 	b[6] = hcon->resp_addr_type;
1340760b018bSJohan Hedberg 
1341760b018bSJohan Hedberg 	return smp_f5(smp->tfm_cmac, smp->dhkey, na, nb, a, b, mackey, ltk);
1342760b018bSJohan Hedberg }
1343760b018bSJohan Hedberg 
134438606f14SJohan Hedberg static void sc_dhkey_check(struct smp_chan *smp)
1345760b018bSJohan Hedberg {
1346760b018bSJohan Hedberg 	struct hci_conn *hcon = smp->conn->hcon;
1347760b018bSJohan Hedberg 	struct smp_cmd_dhkey_check check;
1348760b018bSJohan Hedberg 	u8 a[7], b[7], *local_addr, *remote_addr;
1349760b018bSJohan Hedberg 	u8 io_cap[3], r[16];
1350760b018bSJohan Hedberg 
1351760b018bSJohan Hedberg 	memcpy(a, &hcon->init_addr, 6);
1352760b018bSJohan Hedberg 	memcpy(b, &hcon->resp_addr, 6);
1353760b018bSJohan Hedberg 	a[6] = hcon->init_addr_type;
1354760b018bSJohan Hedberg 	b[6] = hcon->resp_addr_type;
1355760b018bSJohan Hedberg 
1356760b018bSJohan Hedberg 	if (hcon->out) {
1357760b018bSJohan Hedberg 		local_addr = a;
1358760b018bSJohan Hedberg 		remote_addr = b;
1359760b018bSJohan Hedberg 		memcpy(io_cap, &smp->preq[1], 3);
1360760b018bSJohan Hedberg 	} else {
1361760b018bSJohan Hedberg 		local_addr = b;
1362760b018bSJohan Hedberg 		remote_addr = a;
1363760b018bSJohan Hedberg 		memcpy(io_cap, &smp->prsp[1], 3);
1364760b018bSJohan Hedberg 	}
1365760b018bSJohan Hedberg 
1366dddd3059SJohan Hedberg 	memset(r, 0, sizeof(r));
1367dddd3059SJohan Hedberg 
1368dddd3059SJohan Hedberg 	if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY)
136938606f14SJohan Hedberg 		put_unaligned_le32(hcon->passkey_notify, r);
1370760b018bSJohan Hedberg 
1371a29b0733SJohan Hedberg 	if (smp->method == REQ_OOB)
1372a29b0733SJohan Hedberg 		memcpy(r, smp->rr, 16);
1373a29b0733SJohan Hedberg 
1374760b018bSJohan Hedberg 	smp_f6(smp->tfm_cmac, smp->mackey, smp->prnd, smp->rrnd, r, io_cap,
1375760b018bSJohan Hedberg 	       local_addr, remote_addr, check.e);
1376760b018bSJohan Hedberg 
1377760b018bSJohan Hedberg 	smp_send_cmd(smp->conn, SMP_CMD_DHKEY_CHECK, sizeof(check), &check);
1378dddd3059SJohan Hedberg }
1379dddd3059SJohan Hedberg 
138038606f14SJohan Hedberg static u8 sc_passkey_send_confirm(struct smp_chan *smp)
138138606f14SJohan Hedberg {
138238606f14SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
138338606f14SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
138438606f14SJohan Hedberg 	struct smp_cmd_pairing_confirm cfm;
138538606f14SJohan Hedberg 	u8 r;
138638606f14SJohan Hedberg 
138738606f14SJohan Hedberg 	r = ((hcon->passkey_notify >> smp->passkey_round) & 0x01);
138838606f14SJohan Hedberg 	r |= 0x80;
138938606f14SJohan Hedberg 
139038606f14SJohan Hedberg 	get_random_bytes(smp->prnd, sizeof(smp->prnd));
139138606f14SJohan Hedberg 
139238606f14SJohan Hedberg 	if (smp_f4(smp->tfm_cmac, smp->local_pk, smp->remote_pk, smp->prnd, r,
139338606f14SJohan Hedberg 		   cfm.confirm_val))
139438606f14SJohan Hedberg 		return SMP_UNSPECIFIED;
139538606f14SJohan Hedberg 
139638606f14SJohan Hedberg 	smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cfm), &cfm);
139738606f14SJohan Hedberg 
139838606f14SJohan Hedberg 	return 0;
139938606f14SJohan Hedberg }
140038606f14SJohan Hedberg 
140138606f14SJohan Hedberg static u8 sc_passkey_round(struct smp_chan *smp, u8 smp_op)
140238606f14SJohan Hedberg {
140338606f14SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
140438606f14SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
140538606f14SJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
140638606f14SJohan Hedberg 	u8 cfm[16], r;
140738606f14SJohan Hedberg 
140838606f14SJohan Hedberg 	/* Ignore the PDU if we've already done 20 rounds (0 - 19) */
140938606f14SJohan Hedberg 	if (smp->passkey_round >= 20)
141038606f14SJohan Hedberg 		return 0;
141138606f14SJohan Hedberg 
141238606f14SJohan Hedberg 	switch (smp_op) {
141338606f14SJohan Hedberg 	case SMP_CMD_PAIRING_RANDOM:
141438606f14SJohan Hedberg 		r = ((hcon->passkey_notify >> smp->passkey_round) & 0x01);
141538606f14SJohan Hedberg 		r |= 0x80;
141638606f14SJohan Hedberg 
141738606f14SJohan Hedberg 		if (smp_f4(smp->tfm_cmac, smp->remote_pk, smp->local_pk,
141838606f14SJohan Hedberg 			   smp->rrnd, r, cfm))
141938606f14SJohan Hedberg 			return SMP_UNSPECIFIED;
142038606f14SJohan Hedberg 
142138606f14SJohan Hedberg 		if (memcmp(smp->pcnf, cfm, 16))
142238606f14SJohan Hedberg 			return SMP_CONFIRM_FAILED;
142338606f14SJohan Hedberg 
142438606f14SJohan Hedberg 		smp->passkey_round++;
142538606f14SJohan Hedberg 
142638606f14SJohan Hedberg 		if (smp->passkey_round == 20) {
142738606f14SJohan Hedberg 			/* Generate MacKey and LTK */
142838606f14SJohan Hedberg 			if (sc_mackey_and_ltk(smp, smp->mackey, smp->tk))
142938606f14SJohan Hedberg 				return SMP_UNSPECIFIED;
143038606f14SJohan Hedberg 		}
143138606f14SJohan Hedberg 
143238606f14SJohan Hedberg 		/* The round is only complete when the initiator
143338606f14SJohan Hedberg 		 * receives pairing random.
143438606f14SJohan Hedberg 		 */
143538606f14SJohan Hedberg 		if (!hcon->out) {
143638606f14SJohan Hedberg 			smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM,
143738606f14SJohan Hedberg 				     sizeof(smp->prnd), smp->prnd);
1438d3e54a87SJohan Hedberg 			if (smp->passkey_round == 20)
143938606f14SJohan Hedberg 				SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
1440d3e54a87SJohan Hedberg 			else
144138606f14SJohan Hedberg 				SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
144238606f14SJohan Hedberg 			return 0;
144338606f14SJohan Hedberg 		}
144438606f14SJohan Hedberg 
144538606f14SJohan Hedberg 		/* Start the next round */
144638606f14SJohan Hedberg 		if (smp->passkey_round != 20)
144738606f14SJohan Hedberg 			return sc_passkey_round(smp, 0);
144838606f14SJohan Hedberg 
144938606f14SJohan Hedberg 		/* Passkey rounds are complete - start DHKey Check */
145038606f14SJohan Hedberg 		sc_dhkey_check(smp);
145138606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
145238606f14SJohan Hedberg 
145338606f14SJohan Hedberg 		break;
145438606f14SJohan Hedberg 
145538606f14SJohan Hedberg 	case SMP_CMD_PAIRING_CONFIRM:
145638606f14SJohan Hedberg 		if (test_bit(SMP_FLAG_WAIT_USER, &smp->flags)) {
145738606f14SJohan Hedberg 			set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
145838606f14SJohan Hedberg 			return 0;
145938606f14SJohan Hedberg 		}
146038606f14SJohan Hedberg 
146138606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
146238606f14SJohan Hedberg 
146338606f14SJohan Hedberg 		if (hcon->out) {
146438606f14SJohan Hedberg 			smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM,
146538606f14SJohan Hedberg 				     sizeof(smp->prnd), smp->prnd);
146638606f14SJohan Hedberg 			return 0;
146738606f14SJohan Hedberg 		}
146838606f14SJohan Hedberg 
146938606f14SJohan Hedberg 		return sc_passkey_send_confirm(smp);
147038606f14SJohan Hedberg 
147138606f14SJohan Hedberg 	case SMP_CMD_PUBLIC_KEY:
147238606f14SJohan Hedberg 	default:
147338606f14SJohan Hedberg 		/* Initiating device starts the round */
147438606f14SJohan Hedberg 		if (!hcon->out)
147538606f14SJohan Hedberg 			return 0;
147638606f14SJohan Hedberg 
147738606f14SJohan Hedberg 		BT_DBG("%s Starting passkey round %u", hdev->name,
147838606f14SJohan Hedberg 		       smp->passkey_round + 1);
147938606f14SJohan Hedberg 
148038606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
148138606f14SJohan Hedberg 
148238606f14SJohan Hedberg 		return sc_passkey_send_confirm(smp);
148338606f14SJohan Hedberg 	}
148438606f14SJohan Hedberg 
148538606f14SJohan Hedberg 	return 0;
148638606f14SJohan Hedberg }
148738606f14SJohan Hedberg 
1488dddd3059SJohan Hedberg static int sc_user_reply(struct smp_chan *smp, u16 mgmt_op, __le32 passkey)
1489dddd3059SJohan Hedberg {
149038606f14SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
149138606f14SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
149238606f14SJohan Hedberg 	u8 smp_op;
149338606f14SJohan Hedberg 
149438606f14SJohan Hedberg 	clear_bit(SMP_FLAG_WAIT_USER, &smp->flags);
149538606f14SJohan Hedberg 
1496dddd3059SJohan Hedberg 	switch (mgmt_op) {
1497dddd3059SJohan Hedberg 	case MGMT_OP_USER_PASSKEY_NEG_REPLY:
1498dddd3059SJohan Hedberg 		smp_failure(smp->conn, SMP_PASSKEY_ENTRY_FAILED);
1499dddd3059SJohan Hedberg 		return 0;
1500dddd3059SJohan Hedberg 	case MGMT_OP_USER_CONFIRM_NEG_REPLY:
1501dddd3059SJohan Hedberg 		smp_failure(smp->conn, SMP_NUMERIC_COMP_FAILED);
1502dddd3059SJohan Hedberg 		return 0;
150338606f14SJohan Hedberg 	case MGMT_OP_USER_PASSKEY_REPLY:
150438606f14SJohan Hedberg 		hcon->passkey_notify = le32_to_cpu(passkey);
150538606f14SJohan Hedberg 		smp->passkey_round = 0;
150638606f14SJohan Hedberg 
150738606f14SJohan Hedberg 		if (test_and_clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags))
150838606f14SJohan Hedberg 			smp_op = SMP_CMD_PAIRING_CONFIRM;
150938606f14SJohan Hedberg 		else
151038606f14SJohan Hedberg 			smp_op = 0;
151138606f14SJohan Hedberg 
151238606f14SJohan Hedberg 		if (sc_passkey_round(smp, smp_op))
151338606f14SJohan Hedberg 			return -EIO;
151438606f14SJohan Hedberg 
151538606f14SJohan Hedberg 		return 0;
1516dddd3059SJohan Hedberg 	}
1517dddd3059SJohan Hedberg 
1518d3e54a87SJohan Hedberg 	/* Initiator sends DHKey check first */
1519d3e54a87SJohan Hedberg 	if (hcon->out) {
152038606f14SJohan Hedberg 		sc_dhkey_check(smp);
1521d3e54a87SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
1522d3e54a87SJohan Hedberg 	} else if (test_and_clear_bit(SMP_FLAG_DHKEY_PENDING, &smp->flags)) {
1523d3e54a87SJohan Hedberg 		sc_dhkey_check(smp);
1524d3e54a87SJohan Hedberg 		sc_add_ltk(smp);
1525d3e54a87SJohan Hedberg 	}
1526760b018bSJohan Hedberg 
1527760b018bSJohan Hedberg 	return 0;
1528760b018bSJohan Hedberg }
1529760b018bSJohan Hedberg 
15302b64d153SBrian Gix int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
15312b64d153SBrian Gix {
1532b10e8017SJohan Hedberg 	struct l2cap_conn *conn = hcon->l2cap_data;
15335d88cc73SJohan Hedberg 	struct l2cap_chan *chan;
15342b64d153SBrian Gix 	struct smp_chan *smp;
15352b64d153SBrian Gix 	u32 value;
1536fc75cc86SJohan Hedberg 	int err;
15372b64d153SBrian Gix 
15382b64d153SBrian Gix 	BT_DBG("");
15392b64d153SBrian Gix 
1540fc75cc86SJohan Hedberg 	if (!conn)
15412b64d153SBrian Gix 		return -ENOTCONN;
15422b64d153SBrian Gix 
15435d88cc73SJohan Hedberg 	chan = conn->smp;
15445d88cc73SJohan Hedberg 	if (!chan)
15455d88cc73SJohan Hedberg 		return -ENOTCONN;
15465d88cc73SJohan Hedberg 
1547fc75cc86SJohan Hedberg 	l2cap_chan_lock(chan);
1548fc75cc86SJohan Hedberg 	if (!chan->data) {
1549fc75cc86SJohan Hedberg 		err = -ENOTCONN;
1550fc75cc86SJohan Hedberg 		goto unlock;
1551fc75cc86SJohan Hedberg 	}
1552fc75cc86SJohan Hedberg 
15535d88cc73SJohan Hedberg 	smp = chan->data;
15542b64d153SBrian Gix 
1555760b018bSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
1556760b018bSJohan Hedberg 		err = sc_user_reply(smp, mgmt_op, passkey);
1557760b018bSJohan Hedberg 		goto unlock;
1558760b018bSJohan Hedberg 	}
1559760b018bSJohan Hedberg 
15602b64d153SBrian Gix 	switch (mgmt_op) {
15612b64d153SBrian Gix 	case MGMT_OP_USER_PASSKEY_REPLY:
15622b64d153SBrian Gix 		value = le32_to_cpu(passkey);
1563943a732aSJohan Hedberg 		memset(smp->tk, 0, sizeof(smp->tk));
15642b64d153SBrian Gix 		BT_DBG("PassKey: %d", value);
1565943a732aSJohan Hedberg 		put_unaligned_le32(value, smp->tk);
15662b64d153SBrian Gix 		/* Fall Through */
15672b64d153SBrian Gix 	case MGMT_OP_USER_CONFIRM_REPLY:
15684a74d658SJohan Hedberg 		set_bit(SMP_FLAG_TK_VALID, &smp->flags);
15692b64d153SBrian Gix 		break;
15702b64d153SBrian Gix 	case MGMT_OP_USER_PASSKEY_NEG_REPLY:
15712b64d153SBrian Gix 	case MGMT_OP_USER_CONFIRM_NEG_REPLY:
157284794e11SJohan Hedberg 		smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
1573fc75cc86SJohan Hedberg 		err = 0;
1574fc75cc86SJohan Hedberg 		goto unlock;
15752b64d153SBrian Gix 	default:
157684794e11SJohan Hedberg 		smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
1577fc75cc86SJohan Hedberg 		err = -EOPNOTSUPP;
1578fc75cc86SJohan Hedberg 		goto unlock;
15792b64d153SBrian Gix 	}
15802b64d153SBrian Gix 
1581fc75cc86SJohan Hedberg 	err = 0;
1582fc75cc86SJohan Hedberg 
15832b64d153SBrian Gix 	/* If it is our turn to send Pairing Confirm, do so now */
15841cc61144SJohan Hedberg 	if (test_bit(SMP_FLAG_CFM_PENDING, &smp->flags)) {
15851cc61144SJohan Hedberg 		u8 rsp = smp_confirm(smp);
15861cc61144SJohan Hedberg 		if (rsp)
15871cc61144SJohan Hedberg 			smp_failure(conn, rsp);
15881cc61144SJohan Hedberg 	}
15892b64d153SBrian Gix 
1590fc75cc86SJohan Hedberg unlock:
1591fc75cc86SJohan Hedberg 	l2cap_chan_unlock(chan);
1592fc75cc86SJohan Hedberg 	return err;
15932b64d153SBrian Gix }
15942b64d153SBrian Gix 
1595b5ae344dSJohan Hedberg static void build_bredr_pairing_cmd(struct smp_chan *smp,
1596b5ae344dSJohan Hedberg 				    struct smp_cmd_pairing *req,
1597b5ae344dSJohan Hedberg 				    struct smp_cmd_pairing *rsp)
1598b5ae344dSJohan Hedberg {
1599b5ae344dSJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
1600b5ae344dSJohan Hedberg 	struct hci_dev *hdev = conn->hcon->hdev;
1601b5ae344dSJohan Hedberg 	u8 local_dist = 0, remote_dist = 0;
1602b5ae344dSJohan Hedberg 
1603b5ae344dSJohan Hedberg 	if (test_bit(HCI_BONDABLE, &hdev->dev_flags)) {
1604b5ae344dSJohan Hedberg 		local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
1605b5ae344dSJohan Hedberg 		remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;
1606b5ae344dSJohan Hedberg 	}
1607b5ae344dSJohan Hedberg 
1608b5ae344dSJohan Hedberg 	if (test_bit(HCI_RPA_RESOLVING, &hdev->dev_flags))
1609b5ae344dSJohan Hedberg 		remote_dist |= SMP_DIST_ID_KEY;
1610b5ae344dSJohan Hedberg 
1611b5ae344dSJohan Hedberg 	if (test_bit(HCI_PRIVACY, &hdev->dev_flags))
1612b5ae344dSJohan Hedberg 		local_dist |= SMP_DIST_ID_KEY;
1613b5ae344dSJohan Hedberg 
1614b5ae344dSJohan Hedberg 	if (!rsp) {
1615b5ae344dSJohan Hedberg 		memset(req, 0, sizeof(*req));
1616b5ae344dSJohan Hedberg 
1617b5ae344dSJohan Hedberg 		req->init_key_dist   = local_dist;
1618b5ae344dSJohan Hedberg 		req->resp_key_dist   = remote_dist;
1619b5ae344dSJohan Hedberg 		req->max_key_size    = SMP_MAX_ENC_KEY_SIZE;
1620b5ae344dSJohan Hedberg 
1621b5ae344dSJohan Hedberg 		smp->remote_key_dist = remote_dist;
1622b5ae344dSJohan Hedberg 
1623b5ae344dSJohan Hedberg 		return;
1624b5ae344dSJohan Hedberg 	}
1625b5ae344dSJohan Hedberg 
1626b5ae344dSJohan Hedberg 	memset(rsp, 0, sizeof(*rsp));
1627b5ae344dSJohan Hedberg 
1628b5ae344dSJohan Hedberg 	rsp->max_key_size    = SMP_MAX_ENC_KEY_SIZE;
1629b5ae344dSJohan Hedberg 	rsp->init_key_dist   = req->init_key_dist & remote_dist;
1630b5ae344dSJohan Hedberg 	rsp->resp_key_dist   = req->resp_key_dist & local_dist;
1631b5ae344dSJohan Hedberg 
1632b5ae344dSJohan Hedberg 	smp->remote_key_dist = rsp->init_key_dist;
1633b5ae344dSJohan Hedberg }
1634b5ae344dSJohan Hedberg 
1635da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
163688ba43b6SAnderson Briglia {
16373158c50cSVinicius Costa Gomes 	struct smp_cmd_pairing rsp, *req = (void *) skb->data;
1638fc75cc86SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
1639b3c6410bSJohan Hedberg 	struct hci_dev *hdev = conn->hcon->hdev;
16408aab4757SVinicius Costa Gomes 	struct smp_chan *smp;
1641c7262e71SJohan Hedberg 	u8 key_size, auth, sec_level;
16428aab4757SVinicius Costa Gomes 	int ret;
164388ba43b6SAnderson Briglia 
164488ba43b6SAnderson Briglia 	BT_DBG("conn %p", conn);
164588ba43b6SAnderson Briglia 
1646c46b98beSJohan Hedberg 	if (skb->len < sizeof(*req))
164738e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1648c46b98beSJohan Hedberg 
164940bef302SJohan Hedberg 	if (conn->hcon->role != HCI_ROLE_SLAVE)
16502b64d153SBrian Gix 		return SMP_CMD_NOTSUPP;
16512b64d153SBrian Gix 
1652fc75cc86SJohan Hedberg 	if (!chan->data)
16538aab4757SVinicius Costa Gomes 		smp = smp_chan_create(conn);
1654fc75cc86SJohan Hedberg 	else
16555d88cc73SJohan Hedberg 		smp = chan->data;
1656d26a2345SVinicius Costa Gomes 
1657d08fd0e7SAndrei Emeltchenko 	if (!smp)
1658d08fd0e7SAndrei Emeltchenko 		return SMP_UNSPECIFIED;
1659d08fd0e7SAndrei Emeltchenko 
1660c05b9339SJohan Hedberg 	/* We didn't start the pairing, so match remote */
16610edb14deSJohan Hedberg 	auth = req->auth_req & AUTH_REQ_MASK(hdev);
1662c05b9339SJohan Hedberg 
1663b6ae8457SJohan Hedberg 	if (!test_bit(HCI_BONDABLE, &hdev->dev_flags) &&
1664c05b9339SJohan Hedberg 	    (auth & SMP_AUTH_BONDING))
1665b3c6410bSJohan Hedberg 		return SMP_PAIRING_NOTSUPP;
1666b3c6410bSJohan Hedberg 
1667903b71c7SJohan Hedberg 	if (test_bit(HCI_SC_ONLY, &hdev->dev_flags) && !(auth & SMP_AUTH_SC))
1668903b71c7SJohan Hedberg 		return SMP_AUTH_REQUIREMENTS;
1669903b71c7SJohan Hedberg 
16701c1def09SVinicius Costa Gomes 	smp->preq[0] = SMP_CMD_PAIRING_REQ;
16711c1def09SVinicius Costa Gomes 	memcpy(&smp->preq[1], req, sizeof(*req));
16723158c50cSVinicius Costa Gomes 	skb_pull(skb, sizeof(*req));
167388ba43b6SAnderson Briglia 
1674b5ae344dSJohan Hedberg 	/* SMP over BR/EDR requires special treatment */
1675b5ae344dSJohan Hedberg 	if (conn->hcon->type == ACL_LINK) {
1676b5ae344dSJohan Hedberg 		/* We must have a BR/EDR SC link */
1677b5ae344dSJohan Hedberg 		if (!test_bit(HCI_CONN_AES_CCM, &conn->hcon->flags))
1678b5ae344dSJohan Hedberg 			return SMP_CROSS_TRANSP_NOT_ALLOWED;
1679b5ae344dSJohan Hedberg 
1680b5ae344dSJohan Hedberg 		set_bit(SMP_FLAG_SC, &smp->flags);
1681b5ae344dSJohan Hedberg 
1682b5ae344dSJohan Hedberg 		build_bredr_pairing_cmd(smp, req, &rsp);
1683b5ae344dSJohan Hedberg 
1684b5ae344dSJohan Hedberg 		key_size = min(req->max_key_size, rsp.max_key_size);
1685b5ae344dSJohan Hedberg 		if (check_enc_key_size(conn, key_size))
1686b5ae344dSJohan Hedberg 			return SMP_ENC_KEY_SIZE;
1687b5ae344dSJohan Hedberg 
1688b5ae344dSJohan Hedberg 		/* Clear bits which are generated but not distributed */
1689b5ae344dSJohan Hedberg 		smp->remote_key_dist &= ~SMP_SC_NO_DIST;
1690b5ae344dSJohan Hedberg 
1691b5ae344dSJohan Hedberg 		smp->prsp[0] = SMP_CMD_PAIRING_RSP;
1692b5ae344dSJohan Hedberg 		memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
1693b5ae344dSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
1694b5ae344dSJohan Hedberg 
1695b5ae344dSJohan Hedberg 		smp_distribute_keys(smp);
1696b5ae344dSJohan Hedberg 		return 0;
1697b5ae344dSJohan Hedberg 	}
1698b5ae344dSJohan Hedberg 
16995e3d3d9bSJohan Hedberg 	build_pairing_cmd(conn, req, &rsp, auth);
17005e3d3d9bSJohan Hedberg 
17015e3d3d9bSJohan Hedberg 	if (rsp.auth_req & SMP_AUTH_SC)
17025e3d3d9bSJohan Hedberg 		set_bit(SMP_FLAG_SC, &smp->flags);
17035e3d3d9bSJohan Hedberg 
17045be5e275SJohan Hedberg 	if (conn->hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
17051afc2a1aSJohan Hedberg 		sec_level = BT_SECURITY_MEDIUM;
17061afc2a1aSJohan Hedberg 	else
1707c7262e71SJohan Hedberg 		sec_level = authreq_to_seclevel(auth);
17081afc2a1aSJohan Hedberg 
1709c7262e71SJohan Hedberg 	if (sec_level > conn->hcon->pending_sec_level)
1710c7262e71SJohan Hedberg 		conn->hcon->pending_sec_level = sec_level;
1711fdde0a26SIdo Yariv 
171249c922bbSStephen Hemminger 	/* If we need MITM check that it can be achieved */
17132ed8f65cSJohan Hedberg 	if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
17142ed8f65cSJohan Hedberg 		u8 method;
17152ed8f65cSJohan Hedberg 
17162ed8f65cSJohan Hedberg 		method = get_auth_method(smp, conn->hcon->io_capability,
17172ed8f65cSJohan Hedberg 					 req->io_capability);
17182ed8f65cSJohan Hedberg 		if (method == JUST_WORKS || method == JUST_CFM)
17192ed8f65cSJohan Hedberg 			return SMP_AUTH_REQUIREMENTS;
17202ed8f65cSJohan Hedberg 	}
17212ed8f65cSJohan Hedberg 
17223158c50cSVinicius Costa Gomes 	key_size = min(req->max_key_size, rsp.max_key_size);
17233158c50cSVinicius Costa Gomes 	if (check_enc_key_size(conn, key_size))
17243158c50cSVinicius Costa Gomes 		return SMP_ENC_KEY_SIZE;
172588ba43b6SAnderson Briglia 
1726e84a6b13SJohan Hedberg 	get_random_bytes(smp->prnd, sizeof(smp->prnd));
17278aab4757SVinicius Costa Gomes 
17281c1def09SVinicius Costa Gomes 	smp->prsp[0] = SMP_CMD_PAIRING_RSP;
17291c1def09SVinicius Costa Gomes 	memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
1730f01ead31SAnderson Briglia 
17313158c50cSVinicius Costa Gomes 	smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
17323b19146dSJohan Hedberg 
17333b19146dSJohan Hedberg 	clear_bit(SMP_FLAG_INITIATOR, &smp->flags);
17343b19146dSJohan Hedberg 
17353b19146dSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
17363b19146dSJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PUBLIC_KEY);
17373b19146dSJohan Hedberg 		/* Clear bits which are generated but not distributed */
17383b19146dSJohan Hedberg 		smp->remote_key_dist &= ~SMP_SC_NO_DIST;
17393b19146dSJohan Hedberg 		/* Wait for Public Key from Initiating Device */
17403b19146dSJohan Hedberg 		return 0;
17413b19146dSJohan Hedberg 	} else {
1742b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
17433b19146dSJohan Hedberg 	}
1744da85e5e5SVinicius Costa Gomes 
17452b64d153SBrian Gix 	/* Request setup of TK */
17462b64d153SBrian Gix 	ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability);
17472b64d153SBrian Gix 	if (ret)
17482b64d153SBrian Gix 		return SMP_UNSPECIFIED;
17492b64d153SBrian Gix 
1750da85e5e5SVinicius Costa Gomes 	return 0;
175188ba43b6SAnderson Briglia }
175288ba43b6SAnderson Briglia 
17533b19146dSJohan Hedberg static u8 sc_send_public_key(struct smp_chan *smp)
17543b19146dSJohan Hedberg {
175570157ef5SJohan Hedberg 	struct hci_dev *hdev = smp->conn->hcon->hdev;
175670157ef5SJohan Hedberg 
17573b19146dSJohan Hedberg 	BT_DBG("");
17583b19146dSJohan Hedberg 
175970157ef5SJohan Hedberg 	if (test_bit(HCI_USE_DEBUG_KEYS, &hdev->dev_flags)) {
176070157ef5SJohan Hedberg 		BT_DBG("Using debug keys");
176170157ef5SJohan Hedberg 		memcpy(smp->local_pk, debug_pk, 64);
176270157ef5SJohan Hedberg 		memcpy(smp->local_sk, debug_sk, 32);
176370157ef5SJohan Hedberg 		set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags);
176470157ef5SJohan Hedberg 	} else {
17656c0dcc50SJohan Hedberg 		while (true) {
17663b19146dSJohan Hedberg 			/* Generate local key pair for Secure Connections */
17673b19146dSJohan Hedberg 			if (!ecc_make_key(smp->local_pk, smp->local_sk))
17683b19146dSJohan Hedberg 				return SMP_UNSPECIFIED;
17693b19146dSJohan Hedberg 
177070157ef5SJohan Hedberg 			/* This is unlikely, but we need to check that
177170157ef5SJohan Hedberg 			 * we didn't accidentially generate a debug key.
17726c0dcc50SJohan Hedberg 			 */
17736c0dcc50SJohan Hedberg 			if (memcmp(smp->local_sk, debug_sk, 32))
17746c0dcc50SJohan Hedberg 				break;
17756c0dcc50SJohan Hedberg 		}
177670157ef5SJohan Hedberg 	}
17776c0dcc50SJohan Hedberg 
1778c7a3d57dSJohan Hedberg 	SMP_DBG("Local Public Key X: %32phN", smp->local_pk);
1779c7a3d57dSJohan Hedberg 	SMP_DBG("Local Public Key Y: %32phN", &smp->local_pk[32]);
1780c7a3d57dSJohan Hedberg 	SMP_DBG("Local Private Key:  %32phN", smp->local_sk);
17813b19146dSJohan Hedberg 
17823b19146dSJohan Hedberg 	smp_send_cmd(smp->conn, SMP_CMD_PUBLIC_KEY, 64, smp->local_pk);
17833b19146dSJohan Hedberg 
17843b19146dSJohan Hedberg 	return 0;
17853b19146dSJohan Hedberg }
17863b19146dSJohan Hedberg 
1787da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
178888ba43b6SAnderson Briglia {
17893158c50cSVinicius Costa Gomes 	struct smp_cmd_pairing *req, *rsp = (void *) skb->data;
17905d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
17915d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
17920edb14deSJohan Hedberg 	struct hci_dev *hdev = conn->hcon->hdev;
17933a7dbfb8SJohan Hedberg 	u8 key_size, auth;
17947d24ddccSAnderson Briglia 	int ret;
179588ba43b6SAnderson Briglia 
179688ba43b6SAnderson Briglia 	BT_DBG("conn %p", conn);
179788ba43b6SAnderson Briglia 
1798c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rsp))
179938e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1800c46b98beSJohan Hedberg 
180140bef302SJohan Hedberg 	if (conn->hcon->role != HCI_ROLE_MASTER)
18022b64d153SBrian Gix 		return SMP_CMD_NOTSUPP;
18032b64d153SBrian Gix 
18043158c50cSVinicius Costa Gomes 	skb_pull(skb, sizeof(*rsp));
1805da85e5e5SVinicius Costa Gomes 
18061c1def09SVinicius Costa Gomes 	req = (void *) &smp->preq[1];
18073158c50cSVinicius Costa Gomes 
18083158c50cSVinicius Costa Gomes 	key_size = min(req->max_key_size, rsp->max_key_size);
18093158c50cSVinicius Costa Gomes 	if (check_enc_key_size(conn, key_size))
18103158c50cSVinicius Costa Gomes 		return SMP_ENC_KEY_SIZE;
18113158c50cSVinicius Costa Gomes 
18120edb14deSJohan Hedberg 	auth = rsp->auth_req & AUTH_REQ_MASK(hdev);
1813c05b9339SJohan Hedberg 
1814903b71c7SJohan Hedberg 	if (test_bit(HCI_SC_ONLY, &hdev->dev_flags) && !(auth & SMP_AUTH_SC))
1815903b71c7SJohan Hedberg 		return SMP_AUTH_REQUIREMENTS;
1816903b71c7SJohan Hedberg 
1817b5ae344dSJohan Hedberg 	smp->prsp[0] = SMP_CMD_PAIRING_RSP;
1818b5ae344dSJohan Hedberg 	memcpy(&smp->prsp[1], rsp, sizeof(*rsp));
1819b5ae344dSJohan Hedberg 
1820b5ae344dSJohan Hedberg 	/* Update remote key distribution in case the remote cleared
1821b5ae344dSJohan Hedberg 	 * some bits that we had enabled in our request.
1822b5ae344dSJohan Hedberg 	 */
1823b5ae344dSJohan Hedberg 	smp->remote_key_dist &= rsp->resp_key_dist;
1824b5ae344dSJohan Hedberg 
1825b5ae344dSJohan Hedberg 	/* For BR/EDR this means we're done and can start phase 3 */
1826b5ae344dSJohan Hedberg 	if (conn->hcon->type == ACL_LINK) {
1827b5ae344dSJohan Hedberg 		/* Clear bits which are generated but not distributed */
1828b5ae344dSJohan Hedberg 		smp->remote_key_dist &= ~SMP_SC_NO_DIST;
1829b5ae344dSJohan Hedberg 		smp_distribute_keys(smp);
1830b5ae344dSJohan Hedberg 		return 0;
1831b5ae344dSJohan Hedberg 	}
1832b5ae344dSJohan Hedberg 
183365668776SJohan Hedberg 	if ((req->auth_req & SMP_AUTH_SC) && (auth & SMP_AUTH_SC))
183465668776SJohan Hedberg 		set_bit(SMP_FLAG_SC, &smp->flags);
1835d2eb9e10SJohan Hedberg 	else if (conn->hcon->pending_sec_level > BT_SECURITY_HIGH)
1836d2eb9e10SJohan Hedberg 		conn->hcon->pending_sec_level = BT_SECURITY_HIGH;
183765668776SJohan Hedberg 
183849c922bbSStephen Hemminger 	/* If we need MITM check that it can be achieved */
18392ed8f65cSJohan Hedberg 	if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
18402ed8f65cSJohan Hedberg 		u8 method;
18412ed8f65cSJohan Hedberg 
18422ed8f65cSJohan Hedberg 		method = get_auth_method(smp, req->io_capability,
18432ed8f65cSJohan Hedberg 					 rsp->io_capability);
18442ed8f65cSJohan Hedberg 		if (method == JUST_WORKS || method == JUST_CFM)
18452ed8f65cSJohan Hedberg 			return SMP_AUTH_REQUIREMENTS;
18462ed8f65cSJohan Hedberg 	}
18472ed8f65cSJohan Hedberg 
1848e84a6b13SJohan Hedberg 	get_random_bytes(smp->prnd, sizeof(smp->prnd));
18497d24ddccSAnderson Briglia 
1850fdcc4becSJohan Hedberg 	/* Update remote key distribution in case the remote cleared
1851fdcc4becSJohan Hedberg 	 * some bits that we had enabled in our request.
1852fdcc4becSJohan Hedberg 	 */
1853fdcc4becSJohan Hedberg 	smp->remote_key_dist &= rsp->resp_key_dist;
1854fdcc4becSJohan Hedberg 
18553b19146dSJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags)) {
18563b19146dSJohan Hedberg 		/* Clear bits which are generated but not distributed */
18573b19146dSJohan Hedberg 		smp->remote_key_dist &= ~SMP_SC_NO_DIST;
18583b19146dSJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PUBLIC_KEY);
18593b19146dSJohan Hedberg 		return sc_send_public_key(smp);
18603b19146dSJohan Hedberg 	}
18613b19146dSJohan Hedberg 
1862c05b9339SJohan Hedberg 	auth |= req->auth_req;
18632b64d153SBrian Gix 
1864476585ecSJohan Hedberg 	ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability);
18652b64d153SBrian Gix 	if (ret)
18662b64d153SBrian Gix 		return SMP_UNSPECIFIED;
18672b64d153SBrian Gix 
18684a74d658SJohan Hedberg 	set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
18692b64d153SBrian Gix 
18702b64d153SBrian Gix 	/* Can't compose response until we have been confirmed */
18714a74d658SJohan Hedberg 	if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
18721cc61144SJohan Hedberg 		return smp_confirm(smp);
1873da85e5e5SVinicius Costa Gomes 
1874da85e5e5SVinicius Costa Gomes 	return 0;
187588ba43b6SAnderson Briglia }
187688ba43b6SAnderson Briglia 
1877dcee2b32SJohan Hedberg static u8 sc_check_confirm(struct smp_chan *smp)
1878dcee2b32SJohan Hedberg {
1879dcee2b32SJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
1880dcee2b32SJohan Hedberg 
1881dcee2b32SJohan Hedberg 	BT_DBG("");
1882dcee2b32SJohan Hedberg 
1883dcee2b32SJohan Hedberg 	/* Public Key exchange must happen before any other steps */
1884dcee2b32SJohan Hedberg 	if (!test_bit(SMP_FLAG_REMOTE_PK, &smp->flags))
1885dcee2b32SJohan Hedberg 		return SMP_UNSPECIFIED;
1886dcee2b32SJohan Hedberg 
188738606f14SJohan Hedberg 	if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY)
188838606f14SJohan Hedberg 		return sc_passkey_round(smp, SMP_CMD_PAIRING_CONFIRM);
188938606f14SJohan Hedberg 
1890dcee2b32SJohan Hedberg 	if (conn->hcon->out) {
1891dcee2b32SJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
1892dcee2b32SJohan Hedberg 			     smp->prnd);
1893dcee2b32SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
1894dcee2b32SJohan Hedberg 	}
1895dcee2b32SJohan Hedberg 
1896dcee2b32SJohan Hedberg 	return 0;
1897dcee2b32SJohan Hedberg }
1898dcee2b32SJohan Hedberg 
1899da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
190088ba43b6SAnderson Briglia {
19015d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
19025d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
19037d24ddccSAnderson Briglia 
190488ba43b6SAnderson Briglia 	BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
190588ba43b6SAnderson Briglia 
1906c46b98beSJohan Hedberg 	if (skb->len < sizeof(smp->pcnf))
190738e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1908c46b98beSJohan Hedberg 
19091c1def09SVinicius Costa Gomes 	memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf));
19101c1def09SVinicius Costa Gomes 	skb_pull(skb, sizeof(smp->pcnf));
19117d24ddccSAnderson Briglia 
1912dcee2b32SJohan Hedberg 	if (test_bit(SMP_FLAG_SC, &smp->flags))
1913dcee2b32SJohan Hedberg 		return sc_check_confirm(smp);
1914dcee2b32SJohan Hedberg 
1915b28b4943SJohan Hedberg 	if (conn->hcon->out) {
1916943a732aSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
1917943a732aSJohan Hedberg 			     smp->prnd);
1918b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
1919b28b4943SJohan Hedberg 		return 0;
1920b28b4943SJohan Hedberg 	}
1921b28b4943SJohan Hedberg 
1922b28b4943SJohan Hedberg 	if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
19231cc61144SJohan Hedberg 		return smp_confirm(smp);
1924943a732aSJohan Hedberg 	else
19254a74d658SJohan Hedberg 		set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
1926da85e5e5SVinicius Costa Gomes 
1927da85e5e5SVinicius Costa Gomes 	return 0;
192888ba43b6SAnderson Briglia }
192988ba43b6SAnderson Briglia 
1930da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
193188ba43b6SAnderson Briglia {
19325d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
19335d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
1934191dc7feSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
1935191dc7feSJohan Hedberg 	u8 *pkax, *pkbx, *na, *nb;
1936191dc7feSJohan Hedberg 	u32 passkey;
1937191dc7feSJohan Hedberg 	int err;
19387d24ddccSAnderson Briglia 
19398aab4757SVinicius Costa Gomes 	BT_DBG("conn %p", conn);
19407d24ddccSAnderson Briglia 
1941c46b98beSJohan Hedberg 	if (skb->len < sizeof(smp->rrnd))
194238e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
1943c46b98beSJohan Hedberg 
1944943a732aSJohan Hedberg 	memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd));
19458aab4757SVinicius Costa Gomes 	skb_pull(skb, sizeof(smp->rrnd));
194688ba43b6SAnderson Briglia 
1947191dc7feSJohan Hedberg 	if (!test_bit(SMP_FLAG_SC, &smp->flags))
1948861580a9SJohan Hedberg 		return smp_random(smp);
1949191dc7feSJohan Hedberg 
1950a29b0733SJohan Hedberg 	if (smp->method == REQ_OOB) {
1951a29b0733SJohan Hedberg 		if (!hcon->out)
1952a29b0733SJohan Hedberg 			smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM,
1953a29b0733SJohan Hedberg 				     sizeof(smp->prnd), smp->prnd);
1954a29b0733SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
1955a29b0733SJohan Hedberg 		goto mackey_and_ltk;
1956a29b0733SJohan Hedberg 	}
1957a29b0733SJohan Hedberg 
195838606f14SJohan Hedberg 	/* Passkey entry has special treatment */
195938606f14SJohan Hedberg 	if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY)
196038606f14SJohan Hedberg 		return sc_passkey_round(smp, SMP_CMD_PAIRING_RANDOM);
196138606f14SJohan Hedberg 
1962191dc7feSJohan Hedberg 	if (hcon->out) {
1963191dc7feSJohan Hedberg 		u8 cfm[16];
1964191dc7feSJohan Hedberg 
1965191dc7feSJohan Hedberg 		err = smp_f4(smp->tfm_cmac, smp->remote_pk, smp->local_pk,
1966191dc7feSJohan Hedberg 			     smp->rrnd, 0, cfm);
1967191dc7feSJohan Hedberg 		if (err)
1968191dc7feSJohan Hedberg 			return SMP_UNSPECIFIED;
1969191dc7feSJohan Hedberg 
1970191dc7feSJohan Hedberg 		if (memcmp(smp->pcnf, cfm, 16))
1971191dc7feSJohan Hedberg 			return SMP_CONFIRM_FAILED;
1972191dc7feSJohan Hedberg 
1973191dc7feSJohan Hedberg 		pkax = smp->local_pk;
1974191dc7feSJohan Hedberg 		pkbx = smp->remote_pk;
1975191dc7feSJohan Hedberg 		na   = smp->prnd;
1976191dc7feSJohan Hedberg 		nb   = smp->rrnd;
1977191dc7feSJohan Hedberg 	} else {
1978191dc7feSJohan Hedberg 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
1979191dc7feSJohan Hedberg 			     smp->prnd);
1980191dc7feSJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
1981191dc7feSJohan Hedberg 
1982191dc7feSJohan Hedberg 		pkax = smp->remote_pk;
1983191dc7feSJohan Hedberg 		pkbx = smp->local_pk;
1984191dc7feSJohan Hedberg 		na   = smp->rrnd;
1985191dc7feSJohan Hedberg 		nb   = smp->prnd;
1986191dc7feSJohan Hedberg 	}
1987191dc7feSJohan Hedberg 
1988a29b0733SJohan Hedberg mackey_and_ltk:
1989760b018bSJohan Hedberg 	/* Generate MacKey and LTK */
1990760b018bSJohan Hedberg 	err = sc_mackey_and_ltk(smp, smp->mackey, smp->tk);
1991760b018bSJohan Hedberg 	if (err)
1992760b018bSJohan Hedberg 		return SMP_UNSPECIFIED;
1993760b018bSJohan Hedberg 
1994a29b0733SJohan Hedberg 	if (smp->method == JUST_WORKS || smp->method == REQ_OOB) {
1995dddd3059SJohan Hedberg 		if (hcon->out) {
199638606f14SJohan Hedberg 			sc_dhkey_check(smp);
1997dddd3059SJohan Hedberg 			SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
1998dddd3059SJohan Hedberg 		}
1999dddd3059SJohan Hedberg 		return 0;
2000dddd3059SJohan Hedberg 	}
2001dddd3059SJohan Hedberg 
200238606f14SJohan Hedberg 	err = smp_g2(smp->tfm_cmac, pkax, pkbx, na, nb, &passkey);
2003191dc7feSJohan Hedberg 	if (err)
2004191dc7feSJohan Hedberg 		return SMP_UNSPECIFIED;
2005191dc7feSJohan Hedberg 
200638606f14SJohan Hedberg 	err = mgmt_user_confirm_request(hcon->hdev, &hcon->dst, hcon->type,
200738606f14SJohan Hedberg 					hcon->dst_type, passkey, 0);
200838606f14SJohan Hedberg 	if (err)
200938606f14SJohan Hedberg 		return SMP_UNSPECIFIED;
201038606f14SJohan Hedberg 
201138606f14SJohan Hedberg 	set_bit(SMP_FLAG_WAIT_USER, &smp->flags);
201238606f14SJohan Hedberg 
2013191dc7feSJohan Hedberg 	return 0;
201488ba43b6SAnderson Briglia }
201588ba43b6SAnderson Briglia 
2016f81cd823SMarcel Holtmann static bool smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
2017988c5997SVinicius Costa Gomes {
2018c9839a11SVinicius Costa Gomes 	struct smp_ltk *key;
2019988c5997SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
2020988c5997SVinicius Costa Gomes 
2021f3a73d97SJohan Hedberg 	key = hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, hcon->role);
2022988c5997SVinicius Costa Gomes 	if (!key)
2023f81cd823SMarcel Holtmann 		return false;
2024988c5997SVinicius Costa Gomes 
2025a6f7833cSJohan Hedberg 	if (smp_ltk_sec_level(key) < sec_level)
2026f81cd823SMarcel Holtmann 		return false;
20274dab7864SJohan Hedberg 
202851a8efd7SJohan Hedberg 	if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
2029f81cd823SMarcel Holtmann 		return true;
2030988c5997SVinicius Costa Gomes 
2031c9839a11SVinicius Costa Gomes 	hci_le_start_enc(hcon, key->ediv, key->rand, key->val);
2032c9839a11SVinicius Costa Gomes 	hcon->enc_key_size = key->enc_size;
2033988c5997SVinicius Costa Gomes 
2034fe59a05fSJohan Hedberg 	/* We never store STKs for master role, so clear this flag */
2035fe59a05fSJohan Hedberg 	clear_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags);
2036fe59a05fSJohan Hedberg 
2037f81cd823SMarcel Holtmann 	return true;
2038988c5997SVinicius Costa Gomes }
2039f1560463SMarcel Holtmann 
204035dc6f83SJohan Hedberg bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level,
204135dc6f83SJohan Hedberg 			     enum smp_key_pref key_pref)
2042854f4727SJohan Hedberg {
2043854f4727SJohan Hedberg 	if (sec_level == BT_SECURITY_LOW)
2044854f4727SJohan Hedberg 		return true;
2045854f4727SJohan Hedberg 
204635dc6f83SJohan Hedberg 	/* If we're encrypted with an STK but the caller prefers using
204735dc6f83SJohan Hedberg 	 * LTK claim insufficient security. This way we allow the
204835dc6f83SJohan Hedberg 	 * connection to be re-encrypted with an LTK, even if the LTK
204935dc6f83SJohan Hedberg 	 * provides the same level of security. Only exception is if we
205035dc6f83SJohan Hedberg 	 * don't have an LTK (e.g. because of key distribution bits).
20519ab65d60SJohan Hedberg 	 */
205235dc6f83SJohan Hedberg 	if (key_pref == SMP_USE_LTK &&
205335dc6f83SJohan Hedberg 	    test_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags) &&
2054f3a73d97SJohan Hedberg 	    hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, hcon->role))
20559ab65d60SJohan Hedberg 		return false;
20569ab65d60SJohan Hedberg 
2057854f4727SJohan Hedberg 	if (hcon->sec_level >= sec_level)
2058854f4727SJohan Hedberg 		return true;
2059854f4727SJohan Hedberg 
2060854f4727SJohan Hedberg 	return false;
2061854f4727SJohan Hedberg }
2062854f4727SJohan Hedberg 
2063da85e5e5SVinicius Costa Gomes static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
206488ba43b6SAnderson Briglia {
206588ba43b6SAnderson Briglia 	struct smp_cmd_security_req *rp = (void *) skb->data;
206688ba43b6SAnderson Briglia 	struct smp_cmd_pairing cp;
2067f1cb9af5SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
20680edb14deSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
20698aab4757SVinicius Costa Gomes 	struct smp_chan *smp;
2070c05b9339SJohan Hedberg 	u8 sec_level, auth;
207188ba43b6SAnderson Briglia 
207288ba43b6SAnderson Briglia 	BT_DBG("conn %p", conn);
207388ba43b6SAnderson Briglia 
2074c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rp))
207538e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2076c46b98beSJohan Hedberg 
207740bef302SJohan Hedberg 	if (hcon->role != HCI_ROLE_MASTER)
207886ca9eacSJohan Hedberg 		return SMP_CMD_NOTSUPP;
207986ca9eacSJohan Hedberg 
20800edb14deSJohan Hedberg 	auth = rp->auth_req & AUTH_REQ_MASK(hdev);
2081c05b9339SJohan Hedberg 
2082903b71c7SJohan Hedberg 	if (test_bit(HCI_SC_ONLY, &hdev->dev_flags) && !(auth & SMP_AUTH_SC))
2083903b71c7SJohan Hedberg 		return SMP_AUTH_REQUIREMENTS;
2084903b71c7SJohan Hedberg 
20855be5e275SJohan Hedberg 	if (hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
20861afc2a1aSJohan Hedberg 		sec_level = BT_SECURITY_MEDIUM;
20871afc2a1aSJohan Hedberg 	else
2088c05b9339SJohan Hedberg 		sec_level = authreq_to_seclevel(auth);
20891afc2a1aSJohan Hedberg 
209035dc6f83SJohan Hedberg 	if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK))
2091854f4727SJohan Hedberg 		return 0;
2092854f4727SJohan Hedberg 
2093c7262e71SJohan Hedberg 	if (sec_level > hcon->pending_sec_level)
2094c7262e71SJohan Hedberg 		hcon->pending_sec_level = sec_level;
2095feb45eb5SVinicius Costa Gomes 
20964dab7864SJohan Hedberg 	if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
2097988c5997SVinicius Costa Gomes 		return 0;
2098988c5997SVinicius Costa Gomes 
20998aab4757SVinicius Costa Gomes 	smp = smp_chan_create(conn);
2100c29d2444SJohan Hedberg 	if (!smp)
2101c29d2444SJohan Hedberg 		return SMP_UNSPECIFIED;
2102d26a2345SVinicius Costa Gomes 
2103b6ae8457SJohan Hedberg 	if (!test_bit(HCI_BONDABLE, &hcon->hdev->dev_flags) &&
2104c05b9339SJohan Hedberg 	    (auth & SMP_AUTH_BONDING))
2105616d55beSJohan Hedberg 		return SMP_PAIRING_NOTSUPP;
2106616d55beSJohan Hedberg 
210788ba43b6SAnderson Briglia 	skb_pull(skb, sizeof(*rp));
210888ba43b6SAnderson Briglia 
2109da85e5e5SVinicius Costa Gomes 	memset(&cp, 0, sizeof(cp));
2110c05b9339SJohan Hedberg 	build_pairing_cmd(conn, &cp, NULL, auth);
211188ba43b6SAnderson Briglia 
21121c1def09SVinicius Costa Gomes 	smp->preq[0] = SMP_CMD_PAIRING_REQ;
21131c1def09SVinicius Costa Gomes 	memcpy(&smp->preq[1], &cp, sizeof(cp));
2114f01ead31SAnderson Briglia 
211588ba43b6SAnderson Briglia 	smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
2116b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP);
2117f1cb9af5SVinicius Costa Gomes 
2118da85e5e5SVinicius Costa Gomes 	return 0;
211988ba43b6SAnderson Briglia }
212088ba43b6SAnderson Briglia 
2121cc110922SVinicius Costa Gomes int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
2122eb492e01SAnderson Briglia {
2123cc110922SVinicius Costa Gomes 	struct l2cap_conn *conn = hcon->l2cap_data;
2124c68b7f12SJohan Hedberg 	struct l2cap_chan *chan;
21250a66cf20SJohan Hedberg 	struct smp_chan *smp;
21262b64d153SBrian Gix 	__u8 authreq;
2127fc75cc86SJohan Hedberg 	int ret;
2128eb492e01SAnderson Briglia 
21293a0259bbSVinicius Costa Gomes 	BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
21303a0259bbSVinicius Costa Gomes 
21310a66cf20SJohan Hedberg 	/* This may be NULL if there's an unexpected disconnection */
21320a66cf20SJohan Hedberg 	if (!conn)
21330a66cf20SJohan Hedberg 		return 1;
21340a66cf20SJohan Hedberg 
2135c68b7f12SJohan Hedberg 	chan = conn->smp;
2136c68b7f12SJohan Hedberg 
2137757aee0fSJohan Hedberg 	if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags))
21382e65c9d2SAndre Guedes 		return 1;
21392e65c9d2SAndre Guedes 
214035dc6f83SJohan Hedberg 	if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK))
2141f1cb9af5SVinicius Costa Gomes 		return 1;
2142f1cb9af5SVinicius Costa Gomes 
2143c7262e71SJohan Hedberg 	if (sec_level > hcon->pending_sec_level)
2144c7262e71SJohan Hedberg 		hcon->pending_sec_level = sec_level;
2145c7262e71SJohan Hedberg 
214640bef302SJohan Hedberg 	if (hcon->role == HCI_ROLE_MASTER)
2147c7262e71SJohan Hedberg 		if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
2148c7262e71SJohan Hedberg 			return 0;
2149d26a2345SVinicius Costa Gomes 
2150fc75cc86SJohan Hedberg 	l2cap_chan_lock(chan);
2151fc75cc86SJohan Hedberg 
2152fc75cc86SJohan Hedberg 	/* If SMP is already in progress ignore this request */
2153fc75cc86SJohan Hedberg 	if (chan->data) {
2154fc75cc86SJohan Hedberg 		ret = 0;
2155fc75cc86SJohan Hedberg 		goto unlock;
2156fc75cc86SJohan Hedberg 	}
2157d26a2345SVinicius Costa Gomes 
21588aab4757SVinicius Costa Gomes 	smp = smp_chan_create(conn);
2159fc75cc86SJohan Hedberg 	if (!smp) {
2160fc75cc86SJohan Hedberg 		ret = 1;
2161fc75cc86SJohan Hedberg 		goto unlock;
2162fc75cc86SJohan Hedberg 	}
21632b64d153SBrian Gix 
21642b64d153SBrian Gix 	authreq = seclevel_to_authreq(sec_level);
2165d26a2345SVinicius Costa Gomes 
2166d2eb9e10SJohan Hedberg 	if (test_bit(HCI_SC_ENABLED, &hcon->hdev->dev_flags))
2167d2eb9e10SJohan Hedberg 		authreq |= SMP_AUTH_SC;
2168d2eb9e10SJohan Hedberg 
216979897d20SJohan Hedberg 	/* Require MITM if IO Capability allows or the security level
217079897d20SJohan Hedberg 	 * requires it.
21712e233644SJohan Hedberg 	 */
217279897d20SJohan Hedberg 	if (hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT ||
2173c7262e71SJohan Hedberg 	    hcon->pending_sec_level > BT_SECURITY_MEDIUM)
21742e233644SJohan Hedberg 		authreq |= SMP_AUTH_MITM;
21752e233644SJohan Hedberg 
217640bef302SJohan Hedberg 	if (hcon->role == HCI_ROLE_MASTER) {
2177d26a2345SVinicius Costa Gomes 		struct smp_cmd_pairing cp;
2178f01ead31SAnderson Briglia 
21792b64d153SBrian Gix 		build_pairing_cmd(conn, &cp, NULL, authreq);
21801c1def09SVinicius Costa Gomes 		smp->preq[0] = SMP_CMD_PAIRING_REQ;
21811c1def09SVinicius Costa Gomes 		memcpy(&smp->preq[1], &cp, sizeof(cp));
2182f01ead31SAnderson Briglia 
2183eb492e01SAnderson Briglia 		smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
2184b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP);
2185eb492e01SAnderson Briglia 	} else {
2186eb492e01SAnderson Briglia 		struct smp_cmd_security_req cp;
21872b64d153SBrian Gix 		cp.auth_req = authreq;
2188eb492e01SAnderson Briglia 		smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
2189b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_REQ);
2190eb492e01SAnderson Briglia 	}
2191eb492e01SAnderson Briglia 
21924a74d658SJohan Hedberg 	set_bit(SMP_FLAG_INITIATOR, &smp->flags);
2193fc75cc86SJohan Hedberg 	ret = 0;
2194edca792cSJohan Hedberg 
2195fc75cc86SJohan Hedberg unlock:
2196fc75cc86SJohan Hedberg 	l2cap_chan_unlock(chan);
2197fc75cc86SJohan Hedberg 	return ret;
2198eb492e01SAnderson Briglia }
2199eb492e01SAnderson Briglia 
22007034b911SVinicius Costa Gomes static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
22017034b911SVinicius Costa Gomes {
220216b90839SVinicius Costa Gomes 	struct smp_cmd_encrypt_info *rp = (void *) skb->data;
22035d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
22045d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
220516b90839SVinicius Costa Gomes 
2206c46b98beSJohan Hedberg 	BT_DBG("conn %p", conn);
2207c46b98beSJohan Hedberg 
2208c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rp))
220938e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2210c46b98beSJohan Hedberg 
2211b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_MASTER_IDENT);
22126131ddc8SJohan Hedberg 
221316b90839SVinicius Costa Gomes 	skb_pull(skb, sizeof(*rp));
221416b90839SVinicius Costa Gomes 
22151c1def09SVinicius Costa Gomes 	memcpy(smp->tk, rp->ltk, sizeof(smp->tk));
221616b90839SVinicius Costa Gomes 
22177034b911SVinicius Costa Gomes 	return 0;
22187034b911SVinicius Costa Gomes }
22197034b911SVinicius Costa Gomes 
22207034b911SVinicius Costa Gomes static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
22217034b911SVinicius Costa Gomes {
222216b90839SVinicius Costa Gomes 	struct smp_cmd_master_ident *rp = (void *) skb->data;
22235d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
22245d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
2225c9839a11SVinicius Costa Gomes 	struct hci_dev *hdev = conn->hcon->hdev;
2226c9839a11SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
222723d0e128SJohan Hedberg 	struct smp_ltk *ltk;
2228c9839a11SVinicius Costa Gomes 	u8 authenticated;
22297034b911SVinicius Costa Gomes 
2230c46b98beSJohan Hedberg 	BT_DBG("conn %p", conn);
2231c46b98beSJohan Hedberg 
2232c46b98beSJohan Hedberg 	if (skb->len < sizeof(*rp))
223338e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2234c46b98beSJohan Hedberg 
22359747a9f3SJohan Hedberg 	/* Mark the information as received */
22369747a9f3SJohan Hedberg 	smp->remote_key_dist &= ~SMP_DIST_ENC_KEY;
22379747a9f3SJohan Hedberg 
2238b28b4943SJohan Hedberg 	if (smp->remote_key_dist & SMP_DIST_ID_KEY)
2239b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO);
2240196332f5SJohan Hedberg 	else if (smp->remote_key_dist & SMP_DIST_SIGN)
2241196332f5SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO);
2242b28b4943SJohan Hedberg 
224316b90839SVinicius Costa Gomes 	skb_pull(skb, sizeof(*rp));
224416b90839SVinicius Costa Gomes 
2245ce39fb4eSMarcel Holtmann 	authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
22462ceba539SJohan Hedberg 	ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, SMP_LTK,
2247ce39fb4eSMarcel Holtmann 			  authenticated, smp->tk, smp->enc_key_size,
224804124681SGustavo F. Padovan 			  rp->ediv, rp->rand);
224923d0e128SJohan Hedberg 	smp->ltk = ltk;
2250c6e81e9aSJohan Hedberg 	if (!(smp->remote_key_dist & KEY_DIST_MASK))
2251d6268e86SJohan Hedberg 		smp_distribute_keys(smp);
22527034b911SVinicius Costa Gomes 
22537034b911SVinicius Costa Gomes 	return 0;
22547034b911SVinicius Costa Gomes }
22557034b911SVinicius Costa Gomes 
2256fd349c02SJohan Hedberg static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
2257fd349c02SJohan Hedberg {
2258fd349c02SJohan Hedberg 	struct smp_cmd_ident_info *info = (void *) skb->data;
22595d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
22605d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
2261fd349c02SJohan Hedberg 
2262fd349c02SJohan Hedberg 	BT_DBG("");
2263fd349c02SJohan Hedberg 
2264fd349c02SJohan Hedberg 	if (skb->len < sizeof(*info))
226538e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2266fd349c02SJohan Hedberg 
2267b28b4943SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_ADDR_INFO);
22686131ddc8SJohan Hedberg 
2269fd349c02SJohan Hedberg 	skb_pull(skb, sizeof(*info));
2270fd349c02SJohan Hedberg 
2271fd349c02SJohan Hedberg 	memcpy(smp->irk, info->irk, 16);
2272fd349c02SJohan Hedberg 
2273fd349c02SJohan Hedberg 	return 0;
2274fd349c02SJohan Hedberg }
2275fd349c02SJohan Hedberg 
2276fd349c02SJohan Hedberg static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
2277fd349c02SJohan Hedberg 				   struct sk_buff *skb)
2278fd349c02SJohan Hedberg {
2279fd349c02SJohan Hedberg 	struct smp_cmd_ident_addr_info *info = (void *) skb->data;
22805d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
22815d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
2282fd349c02SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
2283fd349c02SJohan Hedberg 	bdaddr_t rpa;
2284fd349c02SJohan Hedberg 
2285fd349c02SJohan Hedberg 	BT_DBG("");
2286fd349c02SJohan Hedberg 
2287fd349c02SJohan Hedberg 	if (skb->len < sizeof(*info))
228838e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
2289fd349c02SJohan Hedberg 
22909747a9f3SJohan Hedberg 	/* Mark the information as received */
22919747a9f3SJohan Hedberg 	smp->remote_key_dist &= ~SMP_DIST_ID_KEY;
22929747a9f3SJohan Hedberg 
2293b28b4943SJohan Hedberg 	if (smp->remote_key_dist & SMP_DIST_SIGN)
2294b28b4943SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO);
2295b28b4943SJohan Hedberg 
2296fd349c02SJohan Hedberg 	skb_pull(skb, sizeof(*info));
2297fd349c02SJohan Hedberg 
2298a9a58f86SJohan Hedberg 	/* Strictly speaking the Core Specification (4.1) allows sending
2299a9a58f86SJohan Hedberg 	 * an empty address which would force us to rely on just the IRK
2300a9a58f86SJohan Hedberg 	 * as "identity information". However, since such
2301a9a58f86SJohan Hedberg 	 * implementations are not known of and in order to not over
2302a9a58f86SJohan Hedberg 	 * complicate our implementation, simply pretend that we never
2303a9a58f86SJohan Hedberg 	 * received an IRK for such a device.
2304a9a58f86SJohan Hedberg 	 */
2305a9a58f86SJohan Hedberg 	if (!bacmp(&info->bdaddr, BDADDR_ANY)) {
2306a9a58f86SJohan Hedberg 		BT_ERR("Ignoring IRK with no identity address");
230731dd624eSJohan Hedberg 		goto distribute;
2308a9a58f86SJohan Hedberg 	}
2309a9a58f86SJohan Hedberg 
2310fd349c02SJohan Hedberg 	bacpy(&smp->id_addr, &info->bdaddr);
2311fd349c02SJohan Hedberg 	smp->id_addr_type = info->addr_type;
2312fd349c02SJohan Hedberg 
2313fd349c02SJohan Hedberg 	if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type))
2314fd349c02SJohan Hedberg 		bacpy(&rpa, &hcon->dst);
2315fd349c02SJohan Hedberg 	else
2316fd349c02SJohan Hedberg 		bacpy(&rpa, BDADDR_ANY);
2317fd349c02SJohan Hedberg 
231823d0e128SJohan Hedberg 	smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
231923d0e128SJohan Hedberg 				      smp->id_addr_type, smp->irk, &rpa);
2320fd349c02SJohan Hedberg 
232131dd624eSJohan Hedberg distribute:
2322c6e81e9aSJohan Hedberg 	if (!(smp->remote_key_dist & KEY_DIST_MASK))
2323d6268e86SJohan Hedberg 		smp_distribute_keys(smp);
2324fd349c02SJohan Hedberg 
2325fd349c02SJohan Hedberg 	return 0;
2326fd349c02SJohan Hedberg }
2327fd349c02SJohan Hedberg 
23287ee4ea36SMarcel Holtmann static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)
23297ee4ea36SMarcel Holtmann {
23307ee4ea36SMarcel Holtmann 	struct smp_cmd_sign_info *rp = (void *) skb->data;
23315d88cc73SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
23325d88cc73SJohan Hedberg 	struct smp_chan *smp = chan->data;
23337ee4ea36SMarcel Holtmann 	struct smp_csrk *csrk;
23347ee4ea36SMarcel Holtmann 
23357ee4ea36SMarcel Holtmann 	BT_DBG("conn %p", conn);
23367ee4ea36SMarcel Holtmann 
23377ee4ea36SMarcel Holtmann 	if (skb->len < sizeof(*rp))
233838e4a915SJohan Hedberg 		return SMP_INVALID_PARAMS;
23397ee4ea36SMarcel Holtmann 
23407ee4ea36SMarcel Holtmann 	/* Mark the information as received */
23417ee4ea36SMarcel Holtmann 	smp->remote_key_dist &= ~SMP_DIST_SIGN;
23427ee4ea36SMarcel Holtmann 
23437ee4ea36SMarcel Holtmann 	skb_pull(skb, sizeof(*rp));
23447ee4ea36SMarcel Holtmann 
23457ee4ea36SMarcel Holtmann 	csrk = kzalloc(sizeof(*csrk), GFP_KERNEL);
23467ee4ea36SMarcel Holtmann 	if (csrk) {
23477ee4ea36SMarcel Holtmann 		csrk->master = 0x01;
23487ee4ea36SMarcel Holtmann 		memcpy(csrk->val, rp->csrk, sizeof(csrk->val));
23497ee4ea36SMarcel Holtmann 	}
23507ee4ea36SMarcel Holtmann 	smp->csrk = csrk;
2351d6268e86SJohan Hedberg 	smp_distribute_keys(smp);
23527ee4ea36SMarcel Holtmann 
23537ee4ea36SMarcel Holtmann 	return 0;
23547ee4ea36SMarcel Holtmann }
23557ee4ea36SMarcel Holtmann 
23565e3d3d9bSJohan Hedberg static u8 sc_select_method(struct smp_chan *smp)
23575e3d3d9bSJohan Hedberg {
23585e3d3d9bSJohan Hedberg 	struct l2cap_conn *conn = smp->conn;
23595e3d3d9bSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
23605e3d3d9bSJohan Hedberg 	struct smp_cmd_pairing *local, *remote;
23615e3d3d9bSJohan Hedberg 	u8 local_mitm, remote_mitm, local_io, remote_io, method;
23625e3d3d9bSJohan Hedberg 
2363a29b0733SJohan Hedberg 	if (test_bit(SMP_FLAG_OOB, &smp->flags))
2364a29b0733SJohan Hedberg 		return REQ_OOB;
2365a29b0733SJohan Hedberg 
23665e3d3d9bSJohan Hedberg 	/* The preq/prsp contain the raw Pairing Request/Response PDUs
23675e3d3d9bSJohan Hedberg 	 * which are needed as inputs to some crypto functions. To get
23685e3d3d9bSJohan Hedberg 	 * the "struct smp_cmd_pairing" from them we need to skip the
23695e3d3d9bSJohan Hedberg 	 * first byte which contains the opcode.
23705e3d3d9bSJohan Hedberg 	 */
23715e3d3d9bSJohan Hedberg 	if (hcon->out) {
23725e3d3d9bSJohan Hedberg 		local = (void *) &smp->preq[1];
23735e3d3d9bSJohan Hedberg 		remote = (void *) &smp->prsp[1];
23745e3d3d9bSJohan Hedberg 	} else {
23755e3d3d9bSJohan Hedberg 		local = (void *) &smp->prsp[1];
23765e3d3d9bSJohan Hedberg 		remote = (void *) &smp->preq[1];
23775e3d3d9bSJohan Hedberg 	}
23785e3d3d9bSJohan Hedberg 
23795e3d3d9bSJohan Hedberg 	local_io = local->io_capability;
23805e3d3d9bSJohan Hedberg 	remote_io = remote->io_capability;
23815e3d3d9bSJohan Hedberg 
23825e3d3d9bSJohan Hedberg 	local_mitm = (local->auth_req & SMP_AUTH_MITM);
23835e3d3d9bSJohan Hedberg 	remote_mitm = (remote->auth_req & SMP_AUTH_MITM);
23845e3d3d9bSJohan Hedberg 
23855e3d3d9bSJohan Hedberg 	/* If either side wants MITM, look up the method from the table,
23865e3d3d9bSJohan Hedberg 	 * otherwise use JUST WORKS.
23875e3d3d9bSJohan Hedberg 	 */
23885e3d3d9bSJohan Hedberg 	if (local_mitm || remote_mitm)
23895e3d3d9bSJohan Hedberg 		method = get_auth_method(smp, local_io, remote_io);
23905e3d3d9bSJohan Hedberg 	else
23915e3d3d9bSJohan Hedberg 		method = JUST_WORKS;
23925e3d3d9bSJohan Hedberg 
23935e3d3d9bSJohan Hedberg 	/* Don't confirm locally initiated pairing attempts */
23945e3d3d9bSJohan Hedberg 	if (method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR, &smp->flags))
23955e3d3d9bSJohan Hedberg 		method = JUST_WORKS;
23965e3d3d9bSJohan Hedberg 
23975e3d3d9bSJohan Hedberg 	return method;
23985e3d3d9bSJohan Hedberg }
23995e3d3d9bSJohan Hedberg 
2400d8f8edbeSJohan Hedberg static int smp_cmd_public_key(struct l2cap_conn *conn, struct sk_buff *skb)
2401d8f8edbeSJohan Hedberg {
2402d8f8edbeSJohan Hedberg 	struct smp_cmd_public_key *key = (void *) skb->data;
2403d8f8edbeSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
2404d8f8edbeSJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
2405d8f8edbeSJohan Hedberg 	struct smp_chan *smp = chan->data;
24065e3d3d9bSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
2407cbbbe3e2SJohan Hedberg 	struct smp_cmd_pairing_confirm cfm;
2408d8f8edbeSJohan Hedberg 	int err;
2409d8f8edbeSJohan Hedberg 
2410d8f8edbeSJohan Hedberg 	BT_DBG("conn %p", conn);
2411d8f8edbeSJohan Hedberg 
2412d8f8edbeSJohan Hedberg 	if (skb->len < sizeof(*key))
2413d8f8edbeSJohan Hedberg 		return SMP_INVALID_PARAMS;
2414d8f8edbeSJohan Hedberg 
2415d8f8edbeSJohan Hedberg 	memcpy(smp->remote_pk, key, 64);
2416d8f8edbeSJohan Hedberg 
2417d8f8edbeSJohan Hedberg 	/* Non-initiating device sends its public key after receiving
2418d8f8edbeSJohan Hedberg 	 * the key from the initiating device.
2419d8f8edbeSJohan Hedberg 	 */
2420d8f8edbeSJohan Hedberg 	if (!hcon->out) {
2421d8f8edbeSJohan Hedberg 		err = sc_send_public_key(smp);
2422d8f8edbeSJohan Hedberg 		if (err)
2423d8f8edbeSJohan Hedberg 			return err;
2424d8f8edbeSJohan Hedberg 	}
2425d8f8edbeSJohan Hedberg 
2426c7a3d57dSJohan Hedberg 	SMP_DBG("Remote Public Key X: %32phN", smp->remote_pk);
2427c7a3d57dSJohan Hedberg 	SMP_DBG("Remote Public Key Y: %32phN", &smp->remote_pk[32]);
2428d8f8edbeSJohan Hedberg 
2429d8f8edbeSJohan Hedberg 	if (!ecdh_shared_secret(smp->remote_pk, smp->local_sk, smp->dhkey))
2430d8f8edbeSJohan Hedberg 		return SMP_UNSPECIFIED;
2431d8f8edbeSJohan Hedberg 
2432c7a3d57dSJohan Hedberg 	SMP_DBG("DHKey %32phN", smp->dhkey);
2433d8f8edbeSJohan Hedberg 
2434d8f8edbeSJohan Hedberg 	set_bit(SMP_FLAG_REMOTE_PK, &smp->flags);
2435d8f8edbeSJohan Hedberg 
24365e3d3d9bSJohan Hedberg 	smp->method = sc_select_method(smp);
24375e3d3d9bSJohan Hedberg 
24385e3d3d9bSJohan Hedberg 	BT_DBG("%s selected method 0x%02x", hdev->name, smp->method);
24395e3d3d9bSJohan Hedberg 
24405e3d3d9bSJohan Hedberg 	/* JUST_WORKS and JUST_CFM result in an unauthenticated key */
24415e3d3d9bSJohan Hedberg 	if (smp->method == JUST_WORKS || smp->method == JUST_CFM)
24425e3d3d9bSJohan Hedberg 		hcon->pending_sec_level = BT_SECURITY_MEDIUM;
24435e3d3d9bSJohan Hedberg 	else
24445e3d3d9bSJohan Hedberg 		hcon->pending_sec_level = BT_SECURITY_FIPS;
24455e3d3d9bSJohan Hedberg 
2446aeb7d461SJohan Hedberg 	if (!memcmp(debug_pk, smp->remote_pk, 64))
2447aeb7d461SJohan Hedberg 		set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags);
2448aeb7d461SJohan Hedberg 
244938606f14SJohan Hedberg 	if (smp->method == DSP_PASSKEY) {
245038606f14SJohan Hedberg 		get_random_bytes(&hcon->passkey_notify,
245138606f14SJohan Hedberg 				 sizeof(hcon->passkey_notify));
245238606f14SJohan Hedberg 		hcon->passkey_notify %= 1000000;
245338606f14SJohan Hedberg 		hcon->passkey_entered = 0;
245438606f14SJohan Hedberg 		smp->passkey_round = 0;
245538606f14SJohan Hedberg 		if (mgmt_user_passkey_notify(hdev, &hcon->dst, hcon->type,
245638606f14SJohan Hedberg 					     hcon->dst_type,
245738606f14SJohan Hedberg 					     hcon->passkey_notify,
245838606f14SJohan Hedberg 					     hcon->passkey_entered))
245938606f14SJohan Hedberg 			return SMP_UNSPECIFIED;
246038606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
246138606f14SJohan Hedberg 		return sc_passkey_round(smp, SMP_CMD_PUBLIC_KEY);
246238606f14SJohan Hedberg 	}
246338606f14SJohan Hedberg 
2464a29b0733SJohan Hedberg 	if (smp->method == REQ_OOB) {
2465a29b0733SJohan Hedberg 		err = smp_f4(smp->tfm_cmac, smp->remote_pk, smp->remote_pk,
2466a29b0733SJohan Hedberg 			     smp->rr, 0, cfm.confirm_val);
2467a29b0733SJohan Hedberg 		if (err)
2468a29b0733SJohan Hedberg 			return SMP_UNSPECIFIED;
2469a29b0733SJohan Hedberg 
2470a29b0733SJohan Hedberg 		if (memcmp(cfm.confirm_val, smp->pcnf, 16))
2471a29b0733SJohan Hedberg 			return SMP_CONFIRM_FAILED;
2472a29b0733SJohan Hedberg 
2473a29b0733SJohan Hedberg 		if (hcon->out)
2474a29b0733SJohan Hedberg 			smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM,
2475a29b0733SJohan Hedberg 				     sizeof(smp->prnd), smp->prnd);
2476a29b0733SJohan Hedberg 
2477a29b0733SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
2478a29b0733SJohan Hedberg 
2479a29b0733SJohan Hedberg 		return 0;
2480a29b0733SJohan Hedberg 	}
2481a29b0733SJohan Hedberg 
248238606f14SJohan Hedberg 	if (hcon->out)
248338606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
248438606f14SJohan Hedberg 
248538606f14SJohan Hedberg 	if (smp->method == REQ_PASSKEY) {
248638606f14SJohan Hedberg 		if (mgmt_user_passkey_request(hdev, &hcon->dst, hcon->type,
248738606f14SJohan Hedberg 					      hcon->dst_type))
248838606f14SJohan Hedberg 			return SMP_UNSPECIFIED;
248938606f14SJohan Hedberg 		SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
249038606f14SJohan Hedberg 		set_bit(SMP_FLAG_WAIT_USER, &smp->flags);
249138606f14SJohan Hedberg 		return 0;
249238606f14SJohan Hedberg 	}
249338606f14SJohan Hedberg 
2494cbbbe3e2SJohan Hedberg 	/* The Initiating device waits for the non-initiating device to
2495cbbbe3e2SJohan Hedberg 	 * send the confirm value.
2496cbbbe3e2SJohan Hedberg 	 */
2497cbbbe3e2SJohan Hedberg 	if (conn->hcon->out)
2498cbbbe3e2SJohan Hedberg 		return 0;
2499cbbbe3e2SJohan Hedberg 
2500cbbbe3e2SJohan Hedberg 	err = smp_f4(smp->tfm_cmac, smp->local_pk, smp->remote_pk, smp->prnd,
2501cbbbe3e2SJohan Hedberg 		     0, cfm.confirm_val);
2502cbbbe3e2SJohan Hedberg 	if (err)
2503cbbbe3e2SJohan Hedberg 		return SMP_UNSPECIFIED;
2504cbbbe3e2SJohan Hedberg 
2505cbbbe3e2SJohan Hedberg 	smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cfm), &cfm);
2506cbbbe3e2SJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
2507cbbbe3e2SJohan Hedberg 
2508d8f8edbeSJohan Hedberg 	return 0;
2509d8f8edbeSJohan Hedberg }
2510d8f8edbeSJohan Hedberg 
25116433a9a2SJohan Hedberg static int smp_cmd_dhkey_check(struct l2cap_conn *conn, struct sk_buff *skb)
25126433a9a2SJohan Hedberg {
25136433a9a2SJohan Hedberg 	struct smp_cmd_dhkey_check *check = (void *) skb->data;
25146433a9a2SJohan Hedberg 	struct l2cap_chan *chan = conn->smp;
25156433a9a2SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
25166433a9a2SJohan Hedberg 	struct smp_chan *smp = chan->data;
25176433a9a2SJohan Hedberg 	u8 a[7], b[7], *local_addr, *remote_addr;
25186433a9a2SJohan Hedberg 	u8 io_cap[3], r[16], e[16];
25196433a9a2SJohan Hedberg 	int err;
25206433a9a2SJohan Hedberg 
25216433a9a2SJohan Hedberg 	BT_DBG("conn %p", conn);
25226433a9a2SJohan Hedberg 
25236433a9a2SJohan Hedberg 	if (skb->len < sizeof(*check))
25246433a9a2SJohan Hedberg 		return SMP_INVALID_PARAMS;
25256433a9a2SJohan Hedberg 
25266433a9a2SJohan Hedberg 	memcpy(a, &hcon->init_addr, 6);
25276433a9a2SJohan Hedberg 	memcpy(b, &hcon->resp_addr, 6);
25286433a9a2SJohan Hedberg 	a[6] = hcon->init_addr_type;
25296433a9a2SJohan Hedberg 	b[6] = hcon->resp_addr_type;
25306433a9a2SJohan Hedberg 
25316433a9a2SJohan Hedberg 	if (hcon->out) {
25326433a9a2SJohan Hedberg 		local_addr = a;
25336433a9a2SJohan Hedberg 		remote_addr = b;
25346433a9a2SJohan Hedberg 		memcpy(io_cap, &smp->prsp[1], 3);
25356433a9a2SJohan Hedberg 	} else {
25366433a9a2SJohan Hedberg 		local_addr = b;
25376433a9a2SJohan Hedberg 		remote_addr = a;
25386433a9a2SJohan Hedberg 		memcpy(io_cap, &smp->preq[1], 3);
25396433a9a2SJohan Hedberg 	}
25406433a9a2SJohan Hedberg 
25416433a9a2SJohan Hedberg 	memset(r, 0, sizeof(r));
25426433a9a2SJohan Hedberg 
254338606f14SJohan Hedberg 	if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY)
254438606f14SJohan Hedberg 		put_unaligned_le32(hcon->passkey_notify, r);
254538606f14SJohan Hedberg 
25466433a9a2SJohan Hedberg 	err = smp_f6(smp->tfm_cmac, smp->mackey, smp->rrnd, smp->prnd, r,
25476433a9a2SJohan Hedberg 		     io_cap, remote_addr, local_addr, e);
25486433a9a2SJohan Hedberg 	if (err)
25496433a9a2SJohan Hedberg 		return SMP_UNSPECIFIED;
25506433a9a2SJohan Hedberg 
25516433a9a2SJohan Hedberg 	if (memcmp(check->e, e, 16))
25526433a9a2SJohan Hedberg 		return SMP_DHKEY_CHECK_FAILED;
25536433a9a2SJohan Hedberg 
2554d3e54a87SJohan Hedberg 	if (!hcon->out) {
2555d3e54a87SJohan Hedberg 		if (test_bit(SMP_FLAG_WAIT_USER, &smp->flags)) {
2556d3e54a87SJohan Hedberg 			set_bit(SMP_FLAG_DHKEY_PENDING, &smp->flags);
2557d3e54a87SJohan Hedberg 			return 0;
2558d3e54a87SJohan Hedberg 		}
2559d378a2d7SJohan Hedberg 
2560d3e54a87SJohan Hedberg 		/* Slave sends DHKey check as response to master */
2561d3e54a87SJohan Hedberg 		sc_dhkey_check(smp);
2562d3e54a87SJohan Hedberg 	}
2563d378a2d7SJohan Hedberg 
2564d3e54a87SJohan Hedberg 	sc_add_ltk(smp);
25656433a9a2SJohan Hedberg 
25666433a9a2SJohan Hedberg 	if (hcon->out) {
25676433a9a2SJohan Hedberg 		hci_le_start_enc(hcon, 0, 0, smp->tk);
25686433a9a2SJohan Hedberg 		hcon->enc_key_size = smp->enc_key_size;
25696433a9a2SJohan Hedberg 	}
25706433a9a2SJohan Hedberg 
25716433a9a2SJohan Hedberg 	return 0;
25726433a9a2SJohan Hedberg }
25736433a9a2SJohan Hedberg 
25741408bb6eSJohan Hedberg static int smp_cmd_keypress_notify(struct l2cap_conn *conn,
25751408bb6eSJohan Hedberg 				   struct sk_buff *skb)
25761408bb6eSJohan Hedberg {
25771408bb6eSJohan Hedberg 	struct smp_cmd_keypress_notify *kp = (void *) skb->data;
25781408bb6eSJohan Hedberg 
25791408bb6eSJohan Hedberg 	BT_DBG("value 0x%02x", kp->value);
25801408bb6eSJohan Hedberg 
25811408bb6eSJohan Hedberg 	return 0;
25821408bb6eSJohan Hedberg }
25831408bb6eSJohan Hedberg 
25844befb867SJohan Hedberg static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb)
2585eb492e01SAnderson Briglia {
25865d88cc73SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
25877b9899dbSMarcel Holtmann 	struct hci_conn *hcon = conn->hcon;
2588b28b4943SJohan Hedberg 	struct smp_chan *smp;
258992381f5cSMarcel Holtmann 	__u8 code, reason;
2590eb492e01SAnderson Briglia 	int err = 0;
2591eb492e01SAnderson Briglia 
25928ae9b984SJohan Hedberg 	if (skb->len < 1)
259392381f5cSMarcel Holtmann 		return -EILSEQ;
259492381f5cSMarcel Holtmann 
259506ae3314SMarcel Holtmann 	if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) {
25962e65c9d2SAndre Guedes 		reason = SMP_PAIRING_NOTSUPP;
25972e65c9d2SAndre Guedes 		goto done;
25982e65c9d2SAndre Guedes 	}
25992e65c9d2SAndre Guedes 
260092381f5cSMarcel Holtmann 	code = skb->data[0];
2601eb492e01SAnderson Briglia 	skb_pull(skb, sizeof(code));
2602eb492e01SAnderson Briglia 
2603b28b4943SJohan Hedberg 	smp = chan->data;
2604b28b4943SJohan Hedberg 
2605b28b4943SJohan Hedberg 	if (code > SMP_CMD_MAX)
2606b28b4943SJohan Hedberg 		goto drop;
2607b28b4943SJohan Hedberg 
260824bd0bd9SJohan Hedberg 	if (smp && !test_and_clear_bit(code, &smp->allow_cmd))
2609b28b4943SJohan Hedberg 		goto drop;
2610b28b4943SJohan Hedberg 
2611b28b4943SJohan Hedberg 	/* If we don't have a context the only allowed commands are
2612b28b4943SJohan Hedberg 	 * pairing request and security request.
26138cf9fa12SJohan Hedberg 	 */
2614b28b4943SJohan Hedberg 	if (!smp && code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ)
2615b28b4943SJohan Hedberg 		goto drop;
26168cf9fa12SJohan Hedberg 
2617eb492e01SAnderson Briglia 	switch (code) {
2618eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_REQ:
2619da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_req(conn, skb);
2620eb492e01SAnderson Briglia 		break;
2621eb492e01SAnderson Briglia 
2622eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_FAIL:
262384794e11SJohan Hedberg 		smp_failure(conn, 0);
2624da85e5e5SVinicius Costa Gomes 		err = -EPERM;
2625eb492e01SAnderson Briglia 		break;
2626eb492e01SAnderson Briglia 
2627eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_RSP:
2628da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_rsp(conn, skb);
262988ba43b6SAnderson Briglia 		break;
263088ba43b6SAnderson Briglia 
263188ba43b6SAnderson Briglia 	case SMP_CMD_SECURITY_REQ:
2632da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_security_req(conn, skb);
263388ba43b6SAnderson Briglia 		break;
263488ba43b6SAnderson Briglia 
2635eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_CONFIRM:
2636da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_confirm(conn, skb);
263788ba43b6SAnderson Briglia 		break;
263888ba43b6SAnderson Briglia 
2639eb492e01SAnderson Briglia 	case SMP_CMD_PAIRING_RANDOM:
2640da85e5e5SVinicius Costa Gomes 		reason = smp_cmd_pairing_random(conn, skb);
264188ba43b6SAnderson Briglia 		break;
264288ba43b6SAnderson Briglia 
2643eb492e01SAnderson Briglia 	case SMP_CMD_ENCRYPT_INFO:
26447034b911SVinicius Costa Gomes 		reason = smp_cmd_encrypt_info(conn, skb);
26457034b911SVinicius Costa Gomes 		break;
26467034b911SVinicius Costa Gomes 
2647eb492e01SAnderson Briglia 	case SMP_CMD_MASTER_IDENT:
26487034b911SVinicius Costa Gomes 		reason = smp_cmd_master_ident(conn, skb);
26497034b911SVinicius Costa Gomes 		break;
26507034b911SVinicius Costa Gomes 
2651eb492e01SAnderson Briglia 	case SMP_CMD_IDENT_INFO:
2652fd349c02SJohan Hedberg 		reason = smp_cmd_ident_info(conn, skb);
2653fd349c02SJohan Hedberg 		break;
2654fd349c02SJohan Hedberg 
2655eb492e01SAnderson Briglia 	case SMP_CMD_IDENT_ADDR_INFO:
2656fd349c02SJohan Hedberg 		reason = smp_cmd_ident_addr_info(conn, skb);
2657fd349c02SJohan Hedberg 		break;
2658fd349c02SJohan Hedberg 
2659eb492e01SAnderson Briglia 	case SMP_CMD_SIGN_INFO:
26607ee4ea36SMarcel Holtmann 		reason = smp_cmd_sign_info(conn, skb);
26617034b911SVinicius Costa Gomes 		break;
26627034b911SVinicius Costa Gomes 
2663d8f8edbeSJohan Hedberg 	case SMP_CMD_PUBLIC_KEY:
2664d8f8edbeSJohan Hedberg 		reason = smp_cmd_public_key(conn, skb);
2665d8f8edbeSJohan Hedberg 		break;
2666d8f8edbeSJohan Hedberg 
26676433a9a2SJohan Hedberg 	case SMP_CMD_DHKEY_CHECK:
26686433a9a2SJohan Hedberg 		reason = smp_cmd_dhkey_check(conn, skb);
26696433a9a2SJohan Hedberg 		break;
26706433a9a2SJohan Hedberg 
26711408bb6eSJohan Hedberg 	case SMP_CMD_KEYPRESS_NOTIFY:
26721408bb6eSJohan Hedberg 		reason = smp_cmd_keypress_notify(conn, skb);
26731408bb6eSJohan Hedberg 		break;
26741408bb6eSJohan Hedberg 
2675eb492e01SAnderson Briglia 	default:
2676eb492e01SAnderson Briglia 		BT_DBG("Unknown command code 0x%2.2x", code);
2677eb492e01SAnderson Briglia 		reason = SMP_CMD_NOTSUPP;
26783a0259bbSVinicius Costa Gomes 		goto done;
26793a0259bbSVinicius Costa Gomes 	}
26803a0259bbSVinicius Costa Gomes 
26813a0259bbSVinicius Costa Gomes done:
26829b7b18efSJohan Hedberg 	if (!err) {
26833a0259bbSVinicius Costa Gomes 		if (reason)
268484794e11SJohan Hedberg 			smp_failure(conn, reason);
2685eb492e01SAnderson Briglia 		kfree_skb(skb);
26869b7b18efSJohan Hedberg 	}
26879b7b18efSJohan Hedberg 
2688eb492e01SAnderson Briglia 	return err;
2689b28b4943SJohan Hedberg 
2690b28b4943SJohan Hedberg drop:
2691b28b4943SJohan Hedberg 	BT_ERR("%s unexpected SMP command 0x%02x from %pMR", hcon->hdev->name,
2692b28b4943SJohan Hedberg 	       code, &hcon->dst);
2693b28b4943SJohan Hedberg 	kfree_skb(skb);
2694b28b4943SJohan Hedberg 	return 0;
2695eb492e01SAnderson Briglia }
26967034b911SVinicius Costa Gomes 
269770db83c4SJohan Hedberg static void smp_teardown_cb(struct l2cap_chan *chan, int err)
269870db83c4SJohan Hedberg {
269970db83c4SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
270070db83c4SJohan Hedberg 
270170db83c4SJohan Hedberg 	BT_DBG("chan %p", chan);
270270db83c4SJohan Hedberg 
2703fc75cc86SJohan Hedberg 	if (chan->data)
27045d88cc73SJohan Hedberg 		smp_chan_destroy(conn);
27055d88cc73SJohan Hedberg 
270670db83c4SJohan Hedberg 	conn->smp = NULL;
270770db83c4SJohan Hedberg 	l2cap_chan_put(chan);
270870db83c4SJohan Hedberg }
270970db83c4SJohan Hedberg 
2710b5ae344dSJohan Hedberg static void bredr_pairing(struct l2cap_chan *chan)
2711b5ae344dSJohan Hedberg {
2712b5ae344dSJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
2713b5ae344dSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
2714b5ae344dSJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
2715b5ae344dSJohan Hedberg 	struct smp_cmd_pairing req;
2716b5ae344dSJohan Hedberg 	struct smp_chan *smp;
2717b5ae344dSJohan Hedberg 
2718b5ae344dSJohan Hedberg 	BT_DBG("chan %p", chan);
2719b5ae344dSJohan Hedberg 
2720b5ae344dSJohan Hedberg 	/* Only new pairings are interesting */
2721b5ae344dSJohan Hedberg 	if (!test_bit(HCI_CONN_NEW_LINK_KEY, &hcon->flags))
2722b5ae344dSJohan Hedberg 		return;
2723b5ae344dSJohan Hedberg 
2724b5ae344dSJohan Hedberg 	/* Don't bother if we're not encrypted */
2725b5ae344dSJohan Hedberg 	if (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags))
2726b5ae344dSJohan Hedberg 		return;
2727b5ae344dSJohan Hedberg 
2728b5ae344dSJohan Hedberg 	/* Only master may initiate SMP over BR/EDR */
2729b5ae344dSJohan Hedberg 	if (hcon->role != HCI_ROLE_MASTER)
2730b5ae344dSJohan Hedberg 		return;
2731b5ae344dSJohan Hedberg 
2732b5ae344dSJohan Hedberg 	/* Secure Connections support must be enabled */
2733b5ae344dSJohan Hedberg 	if (!test_bit(HCI_SC_ENABLED, &hdev->dev_flags))
2734b5ae344dSJohan Hedberg 		return;
2735b5ae344dSJohan Hedberg 
2736b5ae344dSJohan Hedberg 	/* BR/EDR must use Secure Connections for SMP */
2737b5ae344dSJohan Hedberg 	if (!test_bit(HCI_CONN_AES_CCM, &hcon->flags) &&
2738b5ae344dSJohan Hedberg 	    !test_bit(HCI_FORCE_LESC, &hdev->dbg_flags))
2739b5ae344dSJohan Hedberg 		return;
2740b5ae344dSJohan Hedberg 
2741b5ae344dSJohan Hedberg 	/* If our LE support is not enabled don't do anything */
2742b5ae344dSJohan Hedberg 	if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags))
2743b5ae344dSJohan Hedberg 		return;
2744b5ae344dSJohan Hedberg 
2745b5ae344dSJohan Hedberg 	/* Don't bother if remote LE support is not enabled */
2746b5ae344dSJohan Hedberg 	if (!lmp_host_le_capable(hcon))
2747b5ae344dSJohan Hedberg 		return;
2748b5ae344dSJohan Hedberg 
2749b5ae344dSJohan Hedberg 	/* Remote must support SMP fixed chan for BR/EDR */
2750b5ae344dSJohan Hedberg 	if (!(conn->remote_fixed_chan & L2CAP_FC_SMP_BREDR))
2751b5ae344dSJohan Hedberg 		return;
2752b5ae344dSJohan Hedberg 
2753b5ae344dSJohan Hedberg 	/* Don't bother if SMP is already ongoing */
2754b5ae344dSJohan Hedberg 	if (chan->data)
2755b5ae344dSJohan Hedberg 		return;
2756b5ae344dSJohan Hedberg 
2757b5ae344dSJohan Hedberg 	smp = smp_chan_create(conn);
2758b5ae344dSJohan Hedberg 	if (!smp) {
2759b5ae344dSJohan Hedberg 		BT_ERR("%s unable to create SMP context for BR/EDR",
2760b5ae344dSJohan Hedberg 		       hdev->name);
2761b5ae344dSJohan Hedberg 		return;
2762b5ae344dSJohan Hedberg 	}
2763b5ae344dSJohan Hedberg 
2764b5ae344dSJohan Hedberg 	set_bit(SMP_FLAG_SC, &smp->flags);
2765b5ae344dSJohan Hedberg 
2766b5ae344dSJohan Hedberg 	BT_DBG("%s starting SMP over BR/EDR", hdev->name);
2767b5ae344dSJohan Hedberg 
2768b5ae344dSJohan Hedberg 	/* Prepare and send the BR/EDR SMP Pairing Request */
2769b5ae344dSJohan Hedberg 	build_bredr_pairing_cmd(smp, &req, NULL);
2770b5ae344dSJohan Hedberg 
2771b5ae344dSJohan Hedberg 	smp->preq[0] = SMP_CMD_PAIRING_REQ;
2772b5ae344dSJohan Hedberg 	memcpy(&smp->preq[1], &req, sizeof(req));
2773b5ae344dSJohan Hedberg 
2774b5ae344dSJohan Hedberg 	smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(req), &req);
2775b5ae344dSJohan Hedberg 	SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP);
2776b5ae344dSJohan Hedberg }
2777b5ae344dSJohan Hedberg 
277844f1a7abSJohan Hedberg static void smp_resume_cb(struct l2cap_chan *chan)
277944f1a7abSJohan Hedberg {
2780b68fda68SJohan Hedberg 	struct smp_chan *smp = chan->data;
278144f1a7abSJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
278244f1a7abSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
278344f1a7abSJohan Hedberg 
278444f1a7abSJohan Hedberg 	BT_DBG("chan %p", chan);
278544f1a7abSJohan Hedberg 
2786b5ae344dSJohan Hedberg 	if (hcon->type == ACL_LINK) {
2787b5ae344dSJohan Hedberg 		bredr_pairing(chan);
2788ef8efe4bSJohan Hedberg 		return;
2789b5ae344dSJohan Hedberg 	}
2790ef8efe4bSJohan Hedberg 
279186d1407cSJohan Hedberg 	if (!smp)
279286d1407cSJohan Hedberg 		return;
2793b68fda68SJohan Hedberg 
279484bc0db5SJohan Hedberg 	if (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags))
279584bc0db5SJohan Hedberg 		return;
279684bc0db5SJohan Hedberg 
2797b68fda68SJohan Hedberg 	cancel_delayed_work(&smp->security_timer);
279886d1407cSJohan Hedberg 
2799d6268e86SJohan Hedberg 	smp_distribute_keys(smp);
280044f1a7abSJohan Hedberg }
280144f1a7abSJohan Hedberg 
280270db83c4SJohan Hedberg static void smp_ready_cb(struct l2cap_chan *chan)
280370db83c4SJohan Hedberg {
280470db83c4SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
2805b5ae344dSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
280670db83c4SJohan Hedberg 
280770db83c4SJohan Hedberg 	BT_DBG("chan %p", chan);
280870db83c4SJohan Hedberg 
280970db83c4SJohan Hedberg 	conn->smp = chan;
281070db83c4SJohan Hedberg 	l2cap_chan_hold(chan);
2811b5ae344dSJohan Hedberg 
2812b5ae344dSJohan Hedberg 	if (hcon->type == ACL_LINK && test_bit(HCI_CONN_ENCRYPT, &hcon->flags))
2813b5ae344dSJohan Hedberg 		bredr_pairing(chan);
281470db83c4SJohan Hedberg }
281570db83c4SJohan Hedberg 
28164befb867SJohan Hedberg static int smp_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
28174befb867SJohan Hedberg {
28184befb867SJohan Hedberg 	int err;
28194befb867SJohan Hedberg 
28204befb867SJohan Hedberg 	BT_DBG("chan %p", chan);
28214befb867SJohan Hedberg 
28224befb867SJohan Hedberg 	err = smp_sig_channel(chan, skb);
28234befb867SJohan Hedberg 	if (err) {
2824b68fda68SJohan Hedberg 		struct smp_chan *smp = chan->data;
28254befb867SJohan Hedberg 
2826b68fda68SJohan Hedberg 		if (smp)
2827b68fda68SJohan Hedberg 			cancel_delayed_work_sync(&smp->security_timer);
28284befb867SJohan Hedberg 
28291e91c29eSJohan Hedberg 		hci_disconnect(chan->conn->hcon, HCI_ERROR_AUTH_FAILURE);
28304befb867SJohan Hedberg 	}
28314befb867SJohan Hedberg 
28324befb867SJohan Hedberg 	return err;
28334befb867SJohan Hedberg }
28344befb867SJohan Hedberg 
283570db83c4SJohan Hedberg static struct sk_buff *smp_alloc_skb_cb(struct l2cap_chan *chan,
283670db83c4SJohan Hedberg 					unsigned long hdr_len,
283770db83c4SJohan Hedberg 					unsigned long len, int nb)
283870db83c4SJohan Hedberg {
283970db83c4SJohan Hedberg 	struct sk_buff *skb;
284070db83c4SJohan Hedberg 
284170db83c4SJohan Hedberg 	skb = bt_skb_alloc(hdr_len + len, GFP_KERNEL);
284270db83c4SJohan Hedberg 	if (!skb)
284370db83c4SJohan Hedberg 		return ERR_PTR(-ENOMEM);
284470db83c4SJohan Hedberg 
284570db83c4SJohan Hedberg 	skb->priority = HCI_PRIO_MAX;
284670db83c4SJohan Hedberg 	bt_cb(skb)->chan = chan;
284770db83c4SJohan Hedberg 
284870db83c4SJohan Hedberg 	return skb;
284970db83c4SJohan Hedberg }
285070db83c4SJohan Hedberg 
285170db83c4SJohan Hedberg static const struct l2cap_ops smp_chan_ops = {
285270db83c4SJohan Hedberg 	.name			= "Security Manager",
285370db83c4SJohan Hedberg 	.ready			= smp_ready_cb,
28545d88cc73SJohan Hedberg 	.recv			= smp_recv_cb,
285570db83c4SJohan Hedberg 	.alloc_skb		= smp_alloc_skb_cb,
285670db83c4SJohan Hedberg 	.teardown		= smp_teardown_cb,
285744f1a7abSJohan Hedberg 	.resume			= smp_resume_cb,
285870db83c4SJohan Hedberg 
285970db83c4SJohan Hedberg 	.new_connection		= l2cap_chan_no_new_connection,
286070db83c4SJohan Hedberg 	.state_change		= l2cap_chan_no_state_change,
286170db83c4SJohan Hedberg 	.close			= l2cap_chan_no_close,
286270db83c4SJohan Hedberg 	.defer			= l2cap_chan_no_defer,
286370db83c4SJohan Hedberg 	.suspend		= l2cap_chan_no_suspend,
286470db83c4SJohan Hedberg 	.set_shutdown		= l2cap_chan_no_set_shutdown,
286570db83c4SJohan Hedberg 	.get_sndtimeo		= l2cap_chan_no_get_sndtimeo,
286670db83c4SJohan Hedberg 	.memcpy_fromiovec	= l2cap_chan_no_memcpy_fromiovec,
286770db83c4SJohan Hedberg };
286870db83c4SJohan Hedberg 
286970db83c4SJohan Hedberg static inline struct l2cap_chan *smp_new_conn_cb(struct l2cap_chan *pchan)
287070db83c4SJohan Hedberg {
287170db83c4SJohan Hedberg 	struct l2cap_chan *chan;
287270db83c4SJohan Hedberg 
287370db83c4SJohan Hedberg 	BT_DBG("pchan %p", pchan);
287470db83c4SJohan Hedberg 
287570db83c4SJohan Hedberg 	chan = l2cap_chan_create();
287670db83c4SJohan Hedberg 	if (!chan)
287770db83c4SJohan Hedberg 		return NULL;
287870db83c4SJohan Hedberg 
287970db83c4SJohan Hedberg 	chan->chan_type	= pchan->chan_type;
288070db83c4SJohan Hedberg 	chan->ops	= &smp_chan_ops;
288170db83c4SJohan Hedberg 	chan->scid	= pchan->scid;
288270db83c4SJohan Hedberg 	chan->dcid	= chan->scid;
288370db83c4SJohan Hedberg 	chan->imtu	= pchan->imtu;
288470db83c4SJohan Hedberg 	chan->omtu	= pchan->omtu;
288570db83c4SJohan Hedberg 	chan->mode	= pchan->mode;
288670db83c4SJohan Hedberg 
2887abe84903SJohan Hedberg 	/* Other L2CAP channels may request SMP routines in order to
2888abe84903SJohan Hedberg 	 * change the security level. This means that the SMP channel
2889abe84903SJohan Hedberg 	 * lock must be considered in its own category to avoid lockdep
2890abe84903SJohan Hedberg 	 * warnings.
2891abe84903SJohan Hedberg 	 */
2892abe84903SJohan Hedberg 	atomic_set(&chan->nesting, L2CAP_NESTING_SMP);
2893abe84903SJohan Hedberg 
289470db83c4SJohan Hedberg 	BT_DBG("created chan %p", chan);
289570db83c4SJohan Hedberg 
289670db83c4SJohan Hedberg 	return chan;
289770db83c4SJohan Hedberg }
289870db83c4SJohan Hedberg 
289970db83c4SJohan Hedberg static const struct l2cap_ops smp_root_chan_ops = {
290070db83c4SJohan Hedberg 	.name			= "Security Manager Root",
290170db83c4SJohan Hedberg 	.new_connection		= smp_new_conn_cb,
290270db83c4SJohan Hedberg 
290370db83c4SJohan Hedberg 	/* None of these are implemented for the root channel */
290470db83c4SJohan Hedberg 	.close			= l2cap_chan_no_close,
290570db83c4SJohan Hedberg 	.alloc_skb		= l2cap_chan_no_alloc_skb,
290670db83c4SJohan Hedberg 	.recv			= l2cap_chan_no_recv,
290770db83c4SJohan Hedberg 	.state_change		= l2cap_chan_no_state_change,
290870db83c4SJohan Hedberg 	.teardown		= l2cap_chan_no_teardown,
290970db83c4SJohan Hedberg 	.ready			= l2cap_chan_no_ready,
291070db83c4SJohan Hedberg 	.defer			= l2cap_chan_no_defer,
291170db83c4SJohan Hedberg 	.suspend		= l2cap_chan_no_suspend,
291270db83c4SJohan Hedberg 	.resume			= l2cap_chan_no_resume,
291370db83c4SJohan Hedberg 	.set_shutdown		= l2cap_chan_no_set_shutdown,
291470db83c4SJohan Hedberg 	.get_sndtimeo		= l2cap_chan_no_get_sndtimeo,
291570db83c4SJohan Hedberg 	.memcpy_fromiovec	= l2cap_chan_no_memcpy_fromiovec,
291670db83c4SJohan Hedberg };
291770db83c4SJohan Hedberg 
2918ef8efe4bSJohan Hedberg static struct l2cap_chan *smp_add_cid(struct hci_dev *hdev, u16 cid)
2919711eafe3SJohan Hedberg {
292070db83c4SJohan Hedberg 	struct l2cap_chan *chan;
2921defce9e8SJohan Hedberg 	struct crypto_blkcipher	*tfm_aes;
292270db83c4SJohan Hedberg 
2923ef8efe4bSJohan Hedberg 	if (cid == L2CAP_CID_SMP_BREDR) {
2924ef8efe4bSJohan Hedberg 		tfm_aes = NULL;
2925ef8efe4bSJohan Hedberg 		goto create_chan;
2926ef8efe4bSJohan Hedberg 	}
2927711eafe3SJohan Hedberg 
2928adae20cbSJohan Hedberg 	tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, 0);
2929defce9e8SJohan Hedberg 	if (IS_ERR(tfm_aes)) {
2930711eafe3SJohan Hedberg 		BT_ERR("Unable to create crypto context");
2931ef8efe4bSJohan Hedberg 		return ERR_PTR(PTR_ERR(tfm_aes));
2932711eafe3SJohan Hedberg 	}
2933711eafe3SJohan Hedberg 
2934ef8efe4bSJohan Hedberg create_chan:
293570db83c4SJohan Hedberg 	chan = l2cap_chan_create();
293670db83c4SJohan Hedberg 	if (!chan) {
2937defce9e8SJohan Hedberg 		crypto_free_blkcipher(tfm_aes);
2938ef8efe4bSJohan Hedberg 		return ERR_PTR(-ENOMEM);
293970db83c4SJohan Hedberg 	}
294070db83c4SJohan Hedberg 
2941defce9e8SJohan Hedberg 	chan->data = tfm_aes;
2942defce9e8SJohan Hedberg 
2943ef8efe4bSJohan Hedberg 	l2cap_add_scid(chan, cid);
294470db83c4SJohan Hedberg 
294570db83c4SJohan Hedberg 	l2cap_chan_set_defaults(chan);
294670db83c4SJohan Hedberg 
294770db83c4SJohan Hedberg 	bacpy(&chan->src, &hdev->bdaddr);
2948ef8efe4bSJohan Hedberg 	if (cid == L2CAP_CID_SMP)
294970db83c4SJohan Hedberg 		chan->src_type = BDADDR_LE_PUBLIC;
2950ef8efe4bSJohan Hedberg 	else
2951ef8efe4bSJohan Hedberg 		chan->src_type = BDADDR_BREDR;
295270db83c4SJohan Hedberg 	chan->state = BT_LISTEN;
295370db83c4SJohan Hedberg 	chan->mode = L2CAP_MODE_BASIC;
295470db83c4SJohan Hedberg 	chan->imtu = L2CAP_DEFAULT_MTU;
295570db83c4SJohan Hedberg 	chan->ops = &smp_root_chan_ops;
295670db83c4SJohan Hedberg 
2957abe84903SJohan Hedberg 	/* Set correct nesting level for a parent/listening channel */
2958abe84903SJohan Hedberg 	atomic_set(&chan->nesting, L2CAP_NESTING_PARENT);
2959abe84903SJohan Hedberg 
2960ef8efe4bSJohan Hedberg 	return chan;
2961711eafe3SJohan Hedberg }
2962711eafe3SJohan Hedberg 
2963ef8efe4bSJohan Hedberg static void smp_del_chan(struct l2cap_chan *chan)
2964711eafe3SJohan Hedberg {
2965defce9e8SJohan Hedberg 	struct crypto_blkcipher	*tfm_aes;
296670db83c4SJohan Hedberg 
2967ef8efe4bSJohan Hedberg 	BT_DBG("chan %p", chan);
2968711eafe3SJohan Hedberg 
2969defce9e8SJohan Hedberg 	tfm_aes = chan->data;
2970defce9e8SJohan Hedberg 	if (tfm_aes) {
2971defce9e8SJohan Hedberg 		chan->data = NULL;
2972defce9e8SJohan Hedberg 		crypto_free_blkcipher(tfm_aes);
2973711eafe3SJohan Hedberg 	}
297470db83c4SJohan Hedberg 
297570db83c4SJohan Hedberg 	l2cap_chan_put(chan);
2976711eafe3SJohan Hedberg }
2977ef8efe4bSJohan Hedberg 
2978ef8efe4bSJohan Hedberg int smp_register(struct hci_dev *hdev)
2979ef8efe4bSJohan Hedberg {
2980ef8efe4bSJohan Hedberg 	struct l2cap_chan *chan;
2981ef8efe4bSJohan Hedberg 
2982ef8efe4bSJohan Hedberg 	BT_DBG("%s", hdev->name);
2983ef8efe4bSJohan Hedberg 
2984ef8efe4bSJohan Hedberg 	chan = smp_add_cid(hdev, L2CAP_CID_SMP);
2985ef8efe4bSJohan Hedberg 	if (IS_ERR(chan))
2986ef8efe4bSJohan Hedberg 		return PTR_ERR(chan);
2987ef8efe4bSJohan Hedberg 
2988ef8efe4bSJohan Hedberg 	hdev->smp_data = chan;
2989ef8efe4bSJohan Hedberg 
2990ef8efe4bSJohan Hedberg 	if (!lmp_sc_capable(hdev) &&
2991ef8efe4bSJohan Hedberg 	    !test_bit(HCI_FORCE_LESC, &hdev->dbg_flags))
2992ef8efe4bSJohan Hedberg 		return 0;
2993ef8efe4bSJohan Hedberg 
2994ef8efe4bSJohan Hedberg 	chan = smp_add_cid(hdev, L2CAP_CID_SMP_BREDR);
2995ef8efe4bSJohan Hedberg 	if (IS_ERR(chan)) {
2996ef8efe4bSJohan Hedberg 		int err = PTR_ERR(chan);
2997ef8efe4bSJohan Hedberg 		chan = hdev->smp_data;
2998ef8efe4bSJohan Hedberg 		hdev->smp_data = NULL;
2999ef8efe4bSJohan Hedberg 		smp_del_chan(chan);
3000ef8efe4bSJohan Hedberg 		return err;
3001ef8efe4bSJohan Hedberg 	}
3002ef8efe4bSJohan Hedberg 
3003ef8efe4bSJohan Hedberg 	hdev->smp_bredr_data = chan;
3004ef8efe4bSJohan Hedberg 
3005ef8efe4bSJohan Hedberg 	return 0;
3006ef8efe4bSJohan Hedberg }
3007ef8efe4bSJohan Hedberg 
3008ef8efe4bSJohan Hedberg void smp_unregister(struct hci_dev *hdev)
3009ef8efe4bSJohan Hedberg {
3010ef8efe4bSJohan Hedberg 	struct l2cap_chan *chan;
3011ef8efe4bSJohan Hedberg 
3012ef8efe4bSJohan Hedberg 	if (hdev->smp_bredr_data) {
3013ef8efe4bSJohan Hedberg 		chan = hdev->smp_bredr_data;
3014ef8efe4bSJohan Hedberg 		hdev->smp_bredr_data = NULL;
3015ef8efe4bSJohan Hedberg 		smp_del_chan(chan);
3016ef8efe4bSJohan Hedberg 	}
3017ef8efe4bSJohan Hedberg 
3018ef8efe4bSJohan Hedberg 	if (hdev->smp_data) {
3019ef8efe4bSJohan Hedberg 		chan = hdev->smp_data;
3020ef8efe4bSJohan Hedberg 		hdev->smp_data = NULL;
3021ef8efe4bSJohan Hedberg 		smp_del_chan(chan);
3022ef8efe4bSJohan Hedberg 	}
3023ef8efe4bSJohan Hedberg }
3024