1eb492e01SAnderson Briglia /* 2eb492e01SAnderson Briglia BlueZ - Bluetooth protocol stack for Linux 3eb492e01SAnderson Briglia Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4eb492e01SAnderson Briglia 5eb492e01SAnderson Briglia This program is free software; you can redistribute it and/or modify 6eb492e01SAnderson Briglia it under the terms of the GNU General Public License version 2 as 7eb492e01SAnderson Briglia published by the Free Software Foundation; 8eb492e01SAnderson Briglia 9eb492e01SAnderson Briglia THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 10eb492e01SAnderson Briglia OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 11eb492e01SAnderson Briglia FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. 12eb492e01SAnderson Briglia IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY 13eb492e01SAnderson Briglia CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 14eb492e01SAnderson Briglia WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15eb492e01SAnderson Briglia ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16eb492e01SAnderson Briglia OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17eb492e01SAnderson Briglia 18eb492e01SAnderson Briglia ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 19eb492e01SAnderson Briglia COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 20eb492e01SAnderson Briglia SOFTWARE IS DISCLAIMED. 21eb492e01SAnderson Briglia */ 22eb492e01SAnderson Briglia 23300acfdeSMarcel Holtmann #include <linux/debugfs.h> 248c520a59SGustavo Padovan #include <linux/scatterlist.h> 25a4770e11SAndy Lutomirski #include <linux/crypto.h> 2628a220aaSArd Biesheuvel #include <crypto/aes.h> 27329d8230SJason A. Donenfeld #include <crypto/algapi.h> 288c520a59SGustavo Padovan #include <crypto/b128ops.h> 2971af2f6bSHerbert Xu #include <crypto/hash.h> 3047eb2ac8STudor Ambarus #include <crypto/kpp.h> 318c520a59SGustavo Padovan 32eb492e01SAnderson Briglia #include <net/bluetooth/bluetooth.h> 33eb492e01SAnderson Briglia #include <net/bluetooth/hci_core.h> 34eb492e01SAnderson Briglia #include <net/bluetooth/l2cap.h> 352b64d153SBrian Gix #include <net/bluetooth/mgmt.h> 36ac4b7236SMarcel Holtmann 3758771c1cSSalvatore Benedetto #include "ecdh_helper.h" 38ac4b7236SMarcel Holtmann #include "smp.h" 39d22ef0bcSAnderson Briglia 402fd36558SJohan Hedberg #define SMP_DEV(hdev) \ 412fd36558SJohan Hedberg ((struct smp_dev *)((struct l2cap_chan *)((hdev)->smp_data))->data) 422fd36558SJohan Hedberg 43c7a3d57dSJohan Hedberg /* Low-level debug macros to be used for stuff that we don't want 44c7a3d57dSJohan Hedberg * accidentially in dmesg, i.e. the values of the various crypto keys 45c7a3d57dSJohan Hedberg * and the inputs & outputs of crypto functions. 46c7a3d57dSJohan Hedberg */ 47c7a3d57dSJohan Hedberg #ifdef DEBUG 48c7a3d57dSJohan Hedberg #define SMP_DBG(fmt, ...) printk(KERN_DEBUG "%s: " fmt, __func__, \ 49c7a3d57dSJohan Hedberg ##__VA_ARGS__) 50c7a3d57dSJohan Hedberg #else 51c7a3d57dSJohan Hedberg #define SMP_DBG(fmt, ...) no_printk(KERN_DEBUG "%s: " fmt, __func__, \ 52c7a3d57dSJohan Hedberg ##__VA_ARGS__) 53c7a3d57dSJohan Hedberg #endif 54c7a3d57dSJohan Hedberg 55b28b4943SJohan Hedberg #define SMP_ALLOW_CMD(smp, code) set_bit(code, &smp->allow_cmd) 56b28b4943SJohan Hedberg 573b19146dSJohan Hedberg /* Keys which are not distributed with Secure Connections */ 583b19146dSJohan Hedberg #define SMP_SC_NO_DIST (SMP_DIST_ENC_KEY | SMP_DIST_LINK_KEY); 593b19146dSJohan Hedberg 6017b02e62SMarcel Holtmann #define SMP_TIMEOUT msecs_to_jiffies(30000) 615d3de7dfSVinicius Costa Gomes 62d7a5a11dSMarcel Holtmann #define AUTH_REQ_MASK(dev) (hci_dev_test_flag(dev, HCI_SC_ENABLED) ? \ 63a62da6f1SJohan Hedberg 0x3f : 0x07) 6488d3a8acSJohan Hedberg #define KEY_DIST_MASK 0x07 65065a13e2SJohan Hedberg 66cbbbe3e2SJohan Hedberg /* Maximum message length that can be passed to aes_cmac */ 67cbbbe3e2SJohan Hedberg #define CMAC_MSG_MAX 80 68cbbbe3e2SJohan Hedberg 69533e35d4SJohan Hedberg enum { 70533e35d4SJohan Hedberg SMP_FLAG_TK_VALID, 71533e35d4SJohan Hedberg SMP_FLAG_CFM_PENDING, 72533e35d4SJohan Hedberg SMP_FLAG_MITM_AUTH, 73533e35d4SJohan Hedberg SMP_FLAG_COMPLETE, 74533e35d4SJohan Hedberg SMP_FLAG_INITIATOR, 7565668776SJohan Hedberg SMP_FLAG_SC, 76d8f8edbeSJohan Hedberg SMP_FLAG_REMOTE_PK, 77aeb7d461SJohan Hedberg SMP_FLAG_DEBUG_KEY, 7838606f14SJohan Hedberg SMP_FLAG_WAIT_USER, 79d3e54a87SJohan Hedberg SMP_FLAG_DHKEY_PENDING, 801a8bab4fSJohan Hedberg SMP_FLAG_REMOTE_OOB, 811a8bab4fSJohan Hedberg SMP_FLAG_LOCAL_OOB, 82a62da6f1SJohan Hedberg SMP_FLAG_CT2, 83533e35d4SJohan Hedberg }; 844bc58f51SJohan Hedberg 8588a479d9SMarcel Holtmann struct smp_dev { 8660a27d65SMarcel Holtmann /* Secure Connections OOB data */ 8794f14e47SJohan Hedberg bool local_oob; 8860a27d65SMarcel Holtmann u8 local_pk[64]; 89fb334feeSMarcel Holtmann u8 local_rand[16]; 9060a27d65SMarcel Holtmann bool debug_key; 9160a27d65SMarcel Holtmann 9271af2f6bSHerbert Xu struct crypto_shash *tfm_cmac; 9347eb2ac8STudor Ambarus struct crypto_kpp *tfm_ecdh; 9488a479d9SMarcel Holtmann }; 9588a479d9SMarcel Holtmann 964bc58f51SJohan Hedberg struct smp_chan { 974bc58f51SJohan Hedberg struct l2cap_conn *conn; 98b68fda68SJohan Hedberg struct delayed_work security_timer; 99b28b4943SJohan Hedberg unsigned long allow_cmd; /* Bitmask of allowed commands */ 100b68fda68SJohan Hedberg 1014bc58f51SJohan Hedberg u8 preq[7]; /* SMP Pairing Request */ 1024bc58f51SJohan Hedberg u8 prsp[7]; /* SMP Pairing Response */ 1034bc58f51SJohan Hedberg u8 prnd[16]; /* SMP Pairing Random (local) */ 1044bc58f51SJohan Hedberg u8 rrnd[16]; /* SMP Pairing Random (remote) */ 1054bc58f51SJohan Hedberg u8 pcnf[16]; /* SMP Pairing Confirm */ 1064bc58f51SJohan Hedberg u8 tk[16]; /* SMP Temporary Key */ 107882fafadSJohan Hedberg u8 rr[16]; /* Remote OOB ra/rb value */ 108882fafadSJohan Hedberg u8 lr[16]; /* Local OOB ra/rb value */ 1094bc58f51SJohan Hedberg u8 enc_key_size; 1104bc58f51SJohan Hedberg u8 remote_key_dist; 1114bc58f51SJohan Hedberg bdaddr_t id_addr; 1124bc58f51SJohan Hedberg u8 id_addr_type; 1134bc58f51SJohan Hedberg u8 irk[16]; 1144bc58f51SJohan Hedberg struct smp_csrk *csrk; 1154bc58f51SJohan Hedberg struct smp_csrk *slave_csrk; 1164bc58f51SJohan Hedberg struct smp_ltk *ltk; 1174bc58f51SJohan Hedberg struct smp_ltk *slave_ltk; 1184bc58f51SJohan Hedberg struct smp_irk *remote_irk; 1196a77083aSJohan Hedberg u8 *link_key; 1204a74d658SJohan Hedberg unsigned long flags; 121783e0574SJohan Hedberg u8 method; 12238606f14SJohan Hedberg u8 passkey_round; 1236a7bd103SJohan Hedberg 1243b19146dSJohan Hedberg /* Secure Connections variables */ 1253b19146dSJohan Hedberg u8 local_pk[64]; 126d8f8edbeSJohan Hedberg u8 remote_pk[64]; 127d8f8edbeSJohan Hedberg u8 dhkey[32]; 128760b018bSJohan Hedberg u8 mackey[16]; 1293b19146dSJohan Hedberg 13071af2f6bSHerbert Xu struct crypto_shash *tfm_cmac; 13147eb2ac8STudor Ambarus struct crypto_kpp *tfm_ecdh; 1324bc58f51SJohan Hedberg }; 1334bc58f51SJohan Hedberg 134aeb7d461SJohan Hedberg /* These debug key values are defined in the SMP section of the core 135aeb7d461SJohan Hedberg * specification. debug_pk is the public debug key and debug_sk the 136aeb7d461SJohan Hedberg * private debug key. 137aeb7d461SJohan Hedberg */ 138aeb7d461SJohan Hedberg static const u8 debug_pk[64] = { 139aeb7d461SJohan Hedberg 0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc, 140aeb7d461SJohan Hedberg 0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef, 141aeb7d461SJohan Hedberg 0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e, 142aeb7d461SJohan Hedberg 0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20, 143aeb7d461SJohan Hedberg 144aeb7d461SJohan Hedberg 0x8b, 0xd2, 0x89, 0x15, 0xd0, 0x8e, 0x1c, 0x74, 145aeb7d461SJohan Hedberg 0x24, 0x30, 0xed, 0x8f, 0xc2, 0x45, 0x63, 0x76, 146aeb7d461SJohan Hedberg 0x5c, 0x15, 0x52, 0x5a, 0xbf, 0x9a, 0x32, 0x63, 147aeb7d461SJohan Hedberg 0x6d, 0xeb, 0x2a, 0x65, 0x49, 0x9c, 0x80, 0xdc, 148aeb7d461SJohan Hedberg }; 149aeb7d461SJohan Hedberg 150aeb7d461SJohan Hedberg static const u8 debug_sk[32] = { 151aeb7d461SJohan Hedberg 0xbd, 0x1a, 0x3c, 0xcd, 0xa6, 0xb8, 0x99, 0x58, 152aeb7d461SJohan Hedberg 0x99, 0xb7, 0x40, 0xeb, 0x7b, 0x60, 0xff, 0x4a, 153aeb7d461SJohan Hedberg 0x50, 0x3f, 0x10, 0xd2, 0xe3, 0xb3, 0xc9, 0x74, 154aeb7d461SJohan Hedberg 0x38, 0x5f, 0xc5, 0xa3, 0xd4, 0xf6, 0x49, 0x3f, 155aeb7d461SJohan Hedberg }; 156aeb7d461SJohan Hedberg 1578a2936f4SJohan Hedberg static inline void swap_buf(const u8 *src, u8 *dst, size_t len) 158d22ef0bcSAnderson Briglia { 1598a2936f4SJohan Hedberg size_t i; 160d22ef0bcSAnderson Briglia 1618a2936f4SJohan Hedberg for (i = 0; i < len; i++) 1628a2936f4SJohan Hedberg dst[len - 1 - i] = src[i]; 163d22ef0bcSAnderson Briglia } 164d22ef0bcSAnderson Briglia 16506edf8deSJohan Hedberg /* The following functions map to the LE SC SMP crypto functions 16606edf8deSJohan Hedberg * AES-CMAC, f4, f5, f6, g2 and h6. 16706edf8deSJohan Hedberg */ 16806edf8deSJohan Hedberg 16971af2f6bSHerbert Xu static int aes_cmac(struct crypto_shash *tfm, const u8 k[16], const u8 *m, 170cbbbe3e2SJohan Hedberg size_t len, u8 mac[16]) 171cbbbe3e2SJohan Hedberg { 172cbbbe3e2SJohan Hedberg uint8_t tmp[16], mac_msb[16], msg_msb[CMAC_MSG_MAX]; 17371af2f6bSHerbert Xu SHASH_DESC_ON_STACK(desc, tfm); 174cbbbe3e2SJohan Hedberg int err; 175cbbbe3e2SJohan Hedberg 176cbbbe3e2SJohan Hedberg if (len > CMAC_MSG_MAX) 177cbbbe3e2SJohan Hedberg return -EFBIG; 178cbbbe3e2SJohan Hedberg 179cbbbe3e2SJohan Hedberg if (!tfm) { 180cbbbe3e2SJohan Hedberg BT_ERR("tfm %p", tfm); 181cbbbe3e2SJohan Hedberg return -EINVAL; 182cbbbe3e2SJohan Hedberg } 183cbbbe3e2SJohan Hedberg 18471af2f6bSHerbert Xu desc->tfm = tfm; 185cbbbe3e2SJohan Hedberg 186cbbbe3e2SJohan Hedberg /* Swap key and message from LSB to MSB */ 187cbbbe3e2SJohan Hedberg swap_buf(k, tmp, 16); 188cbbbe3e2SJohan Hedberg swap_buf(m, msg_msb, len); 189cbbbe3e2SJohan Hedberg 190c7a3d57dSJohan Hedberg SMP_DBG("msg (len %zu) %*phN", len, (int) len, m); 191c7a3d57dSJohan Hedberg SMP_DBG("key %16phN", k); 192cbbbe3e2SJohan Hedberg 19371af2f6bSHerbert Xu err = crypto_shash_setkey(tfm, tmp, 16); 194cbbbe3e2SJohan Hedberg if (err) { 195cbbbe3e2SJohan Hedberg BT_ERR("cipher setkey failed: %d", err); 196cbbbe3e2SJohan Hedberg return err; 197cbbbe3e2SJohan Hedberg } 198cbbbe3e2SJohan Hedberg 19971af2f6bSHerbert Xu err = crypto_shash_digest(desc, msg_msb, len, mac_msb); 20071af2f6bSHerbert Xu shash_desc_zero(desc); 201cbbbe3e2SJohan Hedberg if (err) { 20271af2f6bSHerbert Xu BT_ERR("Hash computation error %d", err); 203cbbbe3e2SJohan Hedberg return err; 204cbbbe3e2SJohan Hedberg } 205cbbbe3e2SJohan Hedberg 206cbbbe3e2SJohan Hedberg swap_buf(mac_msb, mac, 16); 207cbbbe3e2SJohan Hedberg 208c7a3d57dSJohan Hedberg SMP_DBG("mac %16phN", mac); 209cbbbe3e2SJohan Hedberg 210cbbbe3e2SJohan Hedberg return 0; 211cbbbe3e2SJohan Hedberg } 212cbbbe3e2SJohan Hedberg 21371af2f6bSHerbert Xu static int smp_f4(struct crypto_shash *tfm_cmac, const u8 u[32], 21471af2f6bSHerbert Xu const u8 v[32], const u8 x[16], u8 z, u8 res[16]) 215cbbbe3e2SJohan Hedberg { 216cbbbe3e2SJohan Hedberg u8 m[65]; 217cbbbe3e2SJohan Hedberg int err; 218cbbbe3e2SJohan Hedberg 219c7a3d57dSJohan Hedberg SMP_DBG("u %32phN", u); 220c7a3d57dSJohan Hedberg SMP_DBG("v %32phN", v); 221c7a3d57dSJohan Hedberg SMP_DBG("x %16phN z %02x", x, z); 222cbbbe3e2SJohan Hedberg 223cbbbe3e2SJohan Hedberg m[0] = z; 224cbbbe3e2SJohan Hedberg memcpy(m + 1, v, 32); 225cbbbe3e2SJohan Hedberg memcpy(m + 33, u, 32); 226cbbbe3e2SJohan Hedberg 227cbbbe3e2SJohan Hedberg err = aes_cmac(tfm_cmac, x, m, sizeof(m), res); 228cbbbe3e2SJohan Hedberg if (err) 229cbbbe3e2SJohan Hedberg return err; 230cbbbe3e2SJohan Hedberg 231c7a3d57dSJohan Hedberg SMP_DBG("res %16phN", res); 232cbbbe3e2SJohan Hedberg 233cbbbe3e2SJohan Hedberg return err; 234cbbbe3e2SJohan Hedberg } 235cbbbe3e2SJohan Hedberg 23671af2f6bSHerbert Xu static int smp_f5(struct crypto_shash *tfm_cmac, const u8 w[32], 2374da50de8SJohan Hedberg const u8 n1[16], const u8 n2[16], const u8 a1[7], 2384da50de8SJohan Hedberg const u8 a2[7], u8 mackey[16], u8 ltk[16]) 239760b018bSJohan Hedberg { 240760b018bSJohan Hedberg /* The btle, salt and length "magic" values are as defined in 241760b018bSJohan Hedberg * the SMP section of the Bluetooth core specification. In ASCII 242760b018bSJohan Hedberg * the btle value ends up being 'btle'. The salt is just a 243760b018bSJohan Hedberg * random number whereas length is the value 256 in little 244760b018bSJohan Hedberg * endian format. 245760b018bSJohan Hedberg */ 246760b018bSJohan Hedberg const u8 btle[4] = { 0x65, 0x6c, 0x74, 0x62 }; 247760b018bSJohan Hedberg const u8 salt[16] = { 0xbe, 0x83, 0x60, 0x5a, 0xdb, 0x0b, 0x37, 0x60, 248760b018bSJohan Hedberg 0x38, 0xa5, 0xf5, 0xaa, 0x91, 0x83, 0x88, 0x6c }; 249760b018bSJohan Hedberg const u8 length[2] = { 0x00, 0x01 }; 250760b018bSJohan Hedberg u8 m[53], t[16]; 251760b018bSJohan Hedberg int err; 252760b018bSJohan Hedberg 253c7a3d57dSJohan Hedberg SMP_DBG("w %32phN", w); 254c7a3d57dSJohan Hedberg SMP_DBG("n1 %16phN n2 %16phN", n1, n2); 255c7a3d57dSJohan Hedberg SMP_DBG("a1 %7phN a2 %7phN", a1, a2); 256760b018bSJohan Hedberg 257760b018bSJohan Hedberg err = aes_cmac(tfm_cmac, salt, w, 32, t); 258760b018bSJohan Hedberg if (err) 259760b018bSJohan Hedberg return err; 260760b018bSJohan Hedberg 261c7a3d57dSJohan Hedberg SMP_DBG("t %16phN", t); 262760b018bSJohan Hedberg 263760b018bSJohan Hedberg memcpy(m, length, 2); 264760b018bSJohan Hedberg memcpy(m + 2, a2, 7); 265760b018bSJohan Hedberg memcpy(m + 9, a1, 7); 266760b018bSJohan Hedberg memcpy(m + 16, n2, 16); 267760b018bSJohan Hedberg memcpy(m + 32, n1, 16); 268760b018bSJohan Hedberg memcpy(m + 48, btle, 4); 269760b018bSJohan Hedberg 270760b018bSJohan Hedberg m[52] = 0; /* Counter */ 271760b018bSJohan Hedberg 272760b018bSJohan Hedberg err = aes_cmac(tfm_cmac, t, m, sizeof(m), mackey); 273760b018bSJohan Hedberg if (err) 274760b018bSJohan Hedberg return err; 275760b018bSJohan Hedberg 276c7a3d57dSJohan Hedberg SMP_DBG("mackey %16phN", mackey); 277760b018bSJohan Hedberg 278760b018bSJohan Hedberg m[52] = 1; /* Counter */ 279760b018bSJohan Hedberg 280760b018bSJohan Hedberg err = aes_cmac(tfm_cmac, t, m, sizeof(m), ltk); 281760b018bSJohan Hedberg if (err) 282760b018bSJohan Hedberg return err; 283760b018bSJohan Hedberg 284c7a3d57dSJohan Hedberg SMP_DBG("ltk %16phN", ltk); 285760b018bSJohan Hedberg 286760b018bSJohan Hedberg return 0; 287760b018bSJohan Hedberg } 288760b018bSJohan Hedberg 28971af2f6bSHerbert Xu static int smp_f6(struct crypto_shash *tfm_cmac, const u8 w[16], 2904da50de8SJohan Hedberg const u8 n1[16], const u8 n2[16], const u8 r[16], 291760b018bSJohan Hedberg const u8 io_cap[3], const u8 a1[7], const u8 a2[7], 292760b018bSJohan Hedberg u8 res[16]) 293760b018bSJohan Hedberg { 294760b018bSJohan Hedberg u8 m[65]; 295760b018bSJohan Hedberg int err; 296760b018bSJohan Hedberg 297c7a3d57dSJohan Hedberg SMP_DBG("w %16phN", w); 298c7a3d57dSJohan Hedberg SMP_DBG("n1 %16phN n2 %16phN", n1, n2); 299c7a3d57dSJohan Hedberg SMP_DBG("r %16phN io_cap %3phN a1 %7phN a2 %7phN", r, io_cap, a1, a2); 300760b018bSJohan Hedberg 301760b018bSJohan Hedberg memcpy(m, a2, 7); 302760b018bSJohan Hedberg memcpy(m + 7, a1, 7); 303760b018bSJohan Hedberg memcpy(m + 14, io_cap, 3); 304760b018bSJohan Hedberg memcpy(m + 17, r, 16); 305760b018bSJohan Hedberg memcpy(m + 33, n2, 16); 306760b018bSJohan Hedberg memcpy(m + 49, n1, 16); 307760b018bSJohan Hedberg 308760b018bSJohan Hedberg err = aes_cmac(tfm_cmac, w, m, sizeof(m), res); 309760b018bSJohan Hedberg if (err) 310760b018bSJohan Hedberg return err; 311760b018bSJohan Hedberg 312203de21bSMarcel Holtmann SMP_DBG("res %16phN", res); 313760b018bSJohan Hedberg 314760b018bSJohan Hedberg return err; 315760b018bSJohan Hedberg } 316760b018bSJohan Hedberg 31771af2f6bSHerbert Xu static int smp_g2(struct crypto_shash *tfm_cmac, const u8 u[32], const u8 v[32], 318191dc7feSJohan Hedberg const u8 x[16], const u8 y[16], u32 *val) 319191dc7feSJohan Hedberg { 320191dc7feSJohan Hedberg u8 m[80], tmp[16]; 321191dc7feSJohan Hedberg int err; 322191dc7feSJohan Hedberg 323c7a3d57dSJohan Hedberg SMP_DBG("u %32phN", u); 324c7a3d57dSJohan Hedberg SMP_DBG("v %32phN", v); 325c7a3d57dSJohan Hedberg SMP_DBG("x %16phN y %16phN", x, y); 326191dc7feSJohan Hedberg 327191dc7feSJohan Hedberg memcpy(m, y, 16); 328191dc7feSJohan Hedberg memcpy(m + 16, v, 32); 329191dc7feSJohan Hedberg memcpy(m + 48, u, 32); 330191dc7feSJohan Hedberg 331191dc7feSJohan Hedberg err = aes_cmac(tfm_cmac, x, m, sizeof(m), tmp); 332191dc7feSJohan Hedberg if (err) 333191dc7feSJohan Hedberg return err; 334191dc7feSJohan Hedberg 335191dc7feSJohan Hedberg *val = get_unaligned_le32(tmp); 336191dc7feSJohan Hedberg *val %= 1000000; 337191dc7feSJohan Hedberg 338c7a3d57dSJohan Hedberg SMP_DBG("val %06u", *val); 339191dc7feSJohan Hedberg 340191dc7feSJohan Hedberg return 0; 341191dc7feSJohan Hedberg } 342191dc7feSJohan Hedberg 34371af2f6bSHerbert Xu static int smp_h6(struct crypto_shash *tfm_cmac, const u8 w[16], 34406edf8deSJohan Hedberg const u8 key_id[4], u8 res[16]) 34506edf8deSJohan Hedberg { 34606edf8deSJohan Hedberg int err; 34706edf8deSJohan Hedberg 34806edf8deSJohan Hedberg SMP_DBG("w %16phN key_id %4phN", w, key_id); 34906edf8deSJohan Hedberg 35006edf8deSJohan Hedberg err = aes_cmac(tfm_cmac, w, key_id, 4, res); 35106edf8deSJohan Hedberg if (err) 35206edf8deSJohan Hedberg return err; 35306edf8deSJohan Hedberg 35406edf8deSJohan Hedberg SMP_DBG("res %16phN", res); 35506edf8deSJohan Hedberg 35606edf8deSJohan Hedberg return err; 35706edf8deSJohan Hedberg } 35806edf8deSJohan Hedberg 359a62da6f1SJohan Hedberg static int smp_h7(struct crypto_shash *tfm_cmac, const u8 w[16], 360a62da6f1SJohan Hedberg const u8 salt[16], u8 res[16]) 361a62da6f1SJohan Hedberg { 362a62da6f1SJohan Hedberg int err; 363a62da6f1SJohan Hedberg 364a62da6f1SJohan Hedberg SMP_DBG("w %16phN salt %16phN", w, salt); 365a62da6f1SJohan Hedberg 366a62da6f1SJohan Hedberg err = aes_cmac(tfm_cmac, salt, w, 16, res); 367a62da6f1SJohan Hedberg if (err) 368a62da6f1SJohan Hedberg return err; 369a62da6f1SJohan Hedberg 370a62da6f1SJohan Hedberg SMP_DBG("res %16phN", res); 371a62da6f1SJohan Hedberg 372a62da6f1SJohan Hedberg return err; 373a62da6f1SJohan Hedberg } 374a62da6f1SJohan Hedberg 37506edf8deSJohan Hedberg /* The following functions map to the legacy SMP crypto functions e, c1, 37606edf8deSJohan Hedberg * s1 and ah. 37706edf8deSJohan Hedberg */ 37806edf8deSJohan Hedberg 37928a220aaSArd Biesheuvel static int smp_e(const u8 *k, u8 *r) 380d22ef0bcSAnderson Briglia { 38128a220aaSArd Biesheuvel struct crypto_aes_ctx ctx; 382943a732aSJohan Hedberg uint8_t tmp[16], data[16]; 383201a5929SJohan Hedberg int err; 384d22ef0bcSAnderson Briglia 385011c391aSJohan Hedberg SMP_DBG("k %16phN r %16phN", k, r); 386011c391aSJohan Hedberg 387943a732aSJohan Hedberg /* The most significant octet of key corresponds to k[0] */ 3888a2936f4SJohan Hedberg swap_buf(k, tmp, 16); 389943a732aSJohan Hedberg 39028a220aaSArd Biesheuvel err = aes_expandkey(&ctx, tmp, 16); 391d22ef0bcSAnderson Briglia if (err) { 392d22ef0bcSAnderson Briglia BT_ERR("cipher setkey failed: %d", err); 393d22ef0bcSAnderson Briglia return err; 394d22ef0bcSAnderson Briglia } 395d22ef0bcSAnderson Briglia 396943a732aSJohan Hedberg /* Most significant octet of plaintextData corresponds to data[0] */ 3978a2936f4SJohan Hedberg swap_buf(r, data, 16); 398943a732aSJohan Hedberg 39928a220aaSArd Biesheuvel aes_encrypt(&ctx, data, data); 400d22ef0bcSAnderson Briglia 401943a732aSJohan Hedberg /* Most significant octet of encryptedData corresponds to data[0] */ 4028a2936f4SJohan Hedberg swap_buf(data, r, 16); 403943a732aSJohan Hedberg 404011c391aSJohan Hedberg SMP_DBG("r %16phN", r); 405011c391aSJohan Hedberg 40628a220aaSArd Biesheuvel memzero_explicit(&ctx, sizeof (ctx)); 407d22ef0bcSAnderson Briglia return err; 408d22ef0bcSAnderson Briglia } 409d22ef0bcSAnderson Briglia 41028a220aaSArd Biesheuvel static int smp_c1(const u8 k[16], 41106edf8deSJohan Hedberg const u8 r[16], const u8 preq[7], const u8 pres[7], u8 _iat, 41206edf8deSJohan Hedberg const bdaddr_t *ia, u8 _rat, const bdaddr_t *ra, u8 res[16]) 41306edf8deSJohan Hedberg { 41406edf8deSJohan Hedberg u8 p1[16], p2[16]; 41506edf8deSJohan Hedberg int err; 41606edf8deSJohan Hedberg 417011c391aSJohan Hedberg SMP_DBG("k %16phN r %16phN", k, r); 418011c391aSJohan Hedberg SMP_DBG("iat %u ia %6phN rat %u ra %6phN", _iat, ia, _rat, ra); 419011c391aSJohan Hedberg SMP_DBG("preq %7phN pres %7phN", preq, pres); 420011c391aSJohan Hedberg 42106edf8deSJohan Hedberg memset(p1, 0, 16); 42206edf8deSJohan Hedberg 42306edf8deSJohan Hedberg /* p1 = pres || preq || _rat || _iat */ 42406edf8deSJohan Hedberg p1[0] = _iat; 42506edf8deSJohan Hedberg p1[1] = _rat; 42606edf8deSJohan Hedberg memcpy(p1 + 2, preq, 7); 42706edf8deSJohan Hedberg memcpy(p1 + 9, pres, 7); 42806edf8deSJohan Hedberg 429011c391aSJohan Hedberg SMP_DBG("p1 %16phN", p1); 43006edf8deSJohan Hedberg 43106edf8deSJohan Hedberg /* res = r XOR p1 */ 43206edf8deSJohan Hedberg u128_xor((u128 *) res, (u128 *) r, (u128 *) p1); 43306edf8deSJohan Hedberg 43406edf8deSJohan Hedberg /* res = e(k, res) */ 43528a220aaSArd Biesheuvel err = smp_e(k, res); 43606edf8deSJohan Hedberg if (err) { 43706edf8deSJohan Hedberg BT_ERR("Encrypt data error"); 43806edf8deSJohan Hedberg return err; 43906edf8deSJohan Hedberg } 44006edf8deSJohan Hedberg 441011c391aSJohan Hedberg /* p2 = padding || ia || ra */ 442011c391aSJohan Hedberg memcpy(p2, ra, 6); 443011c391aSJohan Hedberg memcpy(p2 + 6, ia, 6); 444011c391aSJohan Hedberg memset(p2 + 12, 0, 4); 445011c391aSJohan Hedberg 446011c391aSJohan Hedberg SMP_DBG("p2 %16phN", p2); 447011c391aSJohan Hedberg 44806edf8deSJohan Hedberg /* res = res XOR p2 */ 44906edf8deSJohan Hedberg u128_xor((u128 *) res, (u128 *) res, (u128 *) p2); 45006edf8deSJohan Hedberg 45106edf8deSJohan Hedberg /* res = e(k, res) */ 45228a220aaSArd Biesheuvel err = smp_e(k, res); 45306edf8deSJohan Hedberg if (err) 45406edf8deSJohan Hedberg BT_ERR("Encrypt data error"); 45506edf8deSJohan Hedberg 45606edf8deSJohan Hedberg return err; 45706edf8deSJohan Hedberg } 45806edf8deSJohan Hedberg 45928a220aaSArd Biesheuvel static int smp_s1(const u8 k[16], 46006edf8deSJohan Hedberg const u8 r1[16], const u8 r2[16], u8 _r[16]) 4616a77083aSJohan Hedberg { 4626a77083aSJohan Hedberg int err; 4636a77083aSJohan Hedberg 46406edf8deSJohan Hedberg /* Just least significant octets from r1 and r2 are considered */ 46506edf8deSJohan Hedberg memcpy(_r, r2, 8); 46606edf8deSJohan Hedberg memcpy(_r + 8, r1, 8); 4676a77083aSJohan Hedberg 46828a220aaSArd Biesheuvel err = smp_e(k, _r); 4696a77083aSJohan Hedberg if (err) 47006edf8deSJohan Hedberg BT_ERR("Encrypt data error"); 4716a77083aSJohan Hedberg 4726a77083aSJohan Hedberg return err; 4736a77083aSJohan Hedberg } 4746a77083aSJohan Hedberg 47528a220aaSArd Biesheuvel static int smp_ah(const u8 irk[16], const u8 r[3], u8 res[3]) 47660478054SJohan Hedberg { 477943a732aSJohan Hedberg u8 _res[16]; 47860478054SJohan Hedberg int err; 47960478054SJohan Hedberg 48060478054SJohan Hedberg /* r' = padding || r */ 481943a732aSJohan Hedberg memcpy(_res, r, 3); 482943a732aSJohan Hedberg memset(_res + 3, 0, 13); 48360478054SJohan Hedberg 48428a220aaSArd Biesheuvel err = smp_e(irk, _res); 48560478054SJohan Hedberg if (err) { 48660478054SJohan Hedberg BT_ERR("Encrypt error"); 48760478054SJohan Hedberg return err; 48860478054SJohan Hedberg } 48960478054SJohan Hedberg 49060478054SJohan Hedberg /* The output of the random address function ah is: 491c5080d42SMarcel Holtmann * ah(k, r) = e(k, r') mod 2^24 49260478054SJohan Hedberg * The output of the security function e is then truncated to 24 bits 49360478054SJohan Hedberg * by taking the least significant 24 bits of the output of e as the 49460478054SJohan Hedberg * result of ah. 49560478054SJohan Hedberg */ 496943a732aSJohan Hedberg memcpy(res, _res, 3); 49760478054SJohan Hedberg 49860478054SJohan Hedberg return 0; 49960478054SJohan Hedberg } 50060478054SJohan Hedberg 501cd082797SJohan Hedberg bool smp_irk_matches(struct hci_dev *hdev, const u8 irk[16], 502cd082797SJohan Hedberg const bdaddr_t *bdaddr) 50360478054SJohan Hedberg { 504defce9e8SJohan Hedberg struct l2cap_chan *chan = hdev->smp_data; 50560478054SJohan Hedberg u8 hash[3]; 50660478054SJohan Hedberg int err; 50760478054SJohan Hedberg 508defce9e8SJohan Hedberg if (!chan || !chan->data) 509defce9e8SJohan Hedberg return false; 510defce9e8SJohan Hedberg 51156860245SMarcel Holtmann bt_dev_dbg(hdev, "RPA %pMR IRK %*phN", bdaddr, 16, irk); 51260478054SJohan Hedberg 51328a220aaSArd Biesheuvel err = smp_ah(irk, &bdaddr->b[3], hash); 51460478054SJohan Hedberg if (err) 51560478054SJohan Hedberg return false; 51660478054SJohan Hedberg 517329d8230SJason A. Donenfeld return !crypto_memneq(bdaddr->b, hash, 3); 51860478054SJohan Hedberg } 51960478054SJohan Hedberg 520cd082797SJohan Hedberg int smp_generate_rpa(struct hci_dev *hdev, const u8 irk[16], bdaddr_t *rpa) 521b1e2b3aeSJohan Hedberg { 522defce9e8SJohan Hedberg struct l2cap_chan *chan = hdev->smp_data; 523b1e2b3aeSJohan Hedberg int err; 524b1e2b3aeSJohan Hedberg 525defce9e8SJohan Hedberg if (!chan || !chan->data) 526defce9e8SJohan Hedberg return -EOPNOTSUPP; 527defce9e8SJohan Hedberg 528b1e2b3aeSJohan Hedberg get_random_bytes(&rpa->b[3], 3); 529b1e2b3aeSJohan Hedberg 530b1e2b3aeSJohan Hedberg rpa->b[5] &= 0x3f; /* Clear two most significant bits */ 531b1e2b3aeSJohan Hedberg rpa->b[5] |= 0x40; /* Set second most significant bit */ 532b1e2b3aeSJohan Hedberg 53328a220aaSArd Biesheuvel err = smp_ah(irk, &rpa->b[3], rpa->b); 534b1e2b3aeSJohan Hedberg if (err < 0) 535b1e2b3aeSJohan Hedberg return err; 536b1e2b3aeSJohan Hedberg 53756860245SMarcel Holtmann bt_dev_dbg(hdev, "RPA %pMR", rpa); 538b1e2b3aeSJohan Hedberg 539b1e2b3aeSJohan Hedberg return 0; 540b1e2b3aeSJohan Hedberg } 541b1e2b3aeSJohan Hedberg 54260a27d65SMarcel Holtmann int smp_generate_oob(struct hci_dev *hdev, u8 hash[16], u8 rand[16]) 54360a27d65SMarcel Holtmann { 54460a27d65SMarcel Holtmann struct l2cap_chan *chan = hdev->smp_data; 54560a27d65SMarcel Holtmann struct smp_dev *smp; 54660a27d65SMarcel Holtmann int err; 54760a27d65SMarcel Holtmann 54860a27d65SMarcel Holtmann if (!chan || !chan->data) 54960a27d65SMarcel Holtmann return -EOPNOTSUPP; 55060a27d65SMarcel Holtmann 55160a27d65SMarcel Holtmann smp = chan->data; 55260a27d65SMarcel Holtmann 55360a27d65SMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS)) { 55456860245SMarcel Holtmann bt_dev_dbg(hdev, "Using debug keys"); 555c0153b0bSTudor Ambarus err = set_ecdh_privkey(smp->tfm_ecdh, debug_sk); 556c0153b0bSTudor Ambarus if (err) 557c0153b0bSTudor Ambarus return err; 55860a27d65SMarcel Holtmann memcpy(smp->local_pk, debug_pk, 64); 55960a27d65SMarcel Holtmann smp->debug_key = true; 56060a27d65SMarcel Holtmann } else { 56160a27d65SMarcel Holtmann while (true) { 562c0153b0bSTudor Ambarus /* Generate key pair for Secure Connections */ 563c0153b0bSTudor Ambarus err = generate_ecdh_keys(smp->tfm_ecdh, smp->local_pk); 564a2976416STudor Ambarus if (err) 565a2976416STudor Ambarus return err; 56660a27d65SMarcel Holtmann 56760a27d65SMarcel Holtmann /* This is unlikely, but we need to check that 56860a27d65SMarcel Holtmann * we didn't accidentially generate a debug key. 56960a27d65SMarcel Holtmann */ 570c0153b0bSTudor Ambarus if (crypto_memneq(smp->local_pk, debug_pk, 64)) 57160a27d65SMarcel Holtmann break; 57260a27d65SMarcel Holtmann } 57360a27d65SMarcel Holtmann smp->debug_key = false; 57460a27d65SMarcel Holtmann } 57560a27d65SMarcel Holtmann 57660a27d65SMarcel Holtmann SMP_DBG("OOB Public Key X: %32phN", smp->local_pk); 57760a27d65SMarcel Holtmann SMP_DBG("OOB Public Key Y: %32phN", smp->local_pk + 32); 57860a27d65SMarcel Holtmann 579fb334feeSMarcel Holtmann get_random_bytes(smp->local_rand, 16); 58060a27d65SMarcel Holtmann 58160a27d65SMarcel Holtmann err = smp_f4(smp->tfm_cmac, smp->local_pk, smp->local_pk, 582fb334feeSMarcel Holtmann smp->local_rand, 0, hash); 58360a27d65SMarcel Holtmann if (err < 0) 58460a27d65SMarcel Holtmann return err; 58560a27d65SMarcel Holtmann 586fb334feeSMarcel Holtmann memcpy(rand, smp->local_rand, 16); 58760a27d65SMarcel Holtmann 58894f14e47SJohan Hedberg smp->local_oob = true; 58994f14e47SJohan Hedberg 59060a27d65SMarcel Holtmann return 0; 59160a27d65SMarcel Holtmann } 59260a27d65SMarcel Holtmann 593eb492e01SAnderson Briglia static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data) 594eb492e01SAnderson Briglia { 5955d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 596b68fda68SJohan Hedberg struct smp_chan *smp; 5975d88cc73SJohan Hedberg struct kvec iv[2]; 5985d88cc73SJohan Hedberg struct msghdr msg; 5995d88cc73SJohan Hedberg 6005d88cc73SJohan Hedberg if (!chan) 6015d88cc73SJohan Hedberg return; 602eb492e01SAnderson Briglia 603eb492e01SAnderson Briglia BT_DBG("code 0x%2.2x", code); 604eb492e01SAnderson Briglia 6055d88cc73SJohan Hedberg iv[0].iov_base = &code; 6065d88cc73SJohan Hedberg iv[0].iov_len = 1; 607eb492e01SAnderson Briglia 6085d88cc73SJohan Hedberg iv[1].iov_base = data; 6095d88cc73SJohan Hedberg iv[1].iov_len = len; 6105d88cc73SJohan Hedberg 6115d88cc73SJohan Hedberg memset(&msg, 0, sizeof(msg)); 6125d88cc73SJohan Hedberg 613aa563d7bSDavid Howells iov_iter_kvec(&msg.msg_iter, WRITE, iv, 2, 1 + len); 6145d88cc73SJohan Hedberg 6155d88cc73SJohan Hedberg l2cap_chan_send(chan, &msg, 1 + len); 616e2dcd113SVinicius Costa Gomes 617b68fda68SJohan Hedberg if (!chan->data) 618b68fda68SJohan Hedberg return; 619b68fda68SJohan Hedberg 620b68fda68SJohan Hedberg smp = chan->data; 621b68fda68SJohan Hedberg 622b68fda68SJohan Hedberg cancel_delayed_work_sync(&smp->security_timer); 623b68fda68SJohan Hedberg schedule_delayed_work(&smp->security_timer, SMP_TIMEOUT); 624eb492e01SAnderson Briglia } 625eb492e01SAnderson Briglia 626d2eb9e10SJohan Hedberg static u8 authreq_to_seclevel(u8 authreq) 6272b64d153SBrian Gix { 628d2eb9e10SJohan Hedberg if (authreq & SMP_AUTH_MITM) { 629d2eb9e10SJohan Hedberg if (authreq & SMP_AUTH_SC) 630d2eb9e10SJohan Hedberg return BT_SECURITY_FIPS; 6312b64d153SBrian Gix else 632d2eb9e10SJohan Hedberg return BT_SECURITY_HIGH; 633d2eb9e10SJohan Hedberg } else { 6342b64d153SBrian Gix return BT_SECURITY_MEDIUM; 6352b64d153SBrian Gix } 636d2eb9e10SJohan Hedberg } 6372b64d153SBrian Gix 6382b64d153SBrian Gix static __u8 seclevel_to_authreq(__u8 sec_level) 6392b64d153SBrian Gix { 6402b64d153SBrian Gix switch (sec_level) { 641d2eb9e10SJohan Hedberg case BT_SECURITY_FIPS: 6422b64d153SBrian Gix case BT_SECURITY_HIGH: 6432b64d153SBrian Gix return SMP_AUTH_MITM | SMP_AUTH_BONDING; 6442b64d153SBrian Gix case BT_SECURITY_MEDIUM: 6452b64d153SBrian Gix return SMP_AUTH_BONDING; 6462b64d153SBrian Gix default: 6472b64d153SBrian Gix return SMP_AUTH_NONE; 6482b64d153SBrian Gix } 6492b64d153SBrian Gix } 6502b64d153SBrian Gix 651b8e66eacSVinicius Costa Gomes static void build_pairing_cmd(struct l2cap_conn *conn, 65254790f73SVinicius Costa Gomes struct smp_cmd_pairing *req, 653f1560463SMarcel Holtmann struct smp_cmd_pairing *rsp, __u8 authreq) 654b8e66eacSVinicius Costa Gomes { 6555d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 6565d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 657fd349c02SJohan Hedberg struct hci_conn *hcon = conn->hcon; 658fd349c02SJohan Hedberg struct hci_dev *hdev = hcon->hdev; 65902b05bd8SJohan Hedberg u8 local_dist = 0, remote_dist = 0, oob_flag = SMP_OOB_NOT_PRESENT; 66054790f73SVinicius Costa Gomes 661d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_BONDABLE)) { 6627ee4ea36SMarcel Holtmann local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN; 6637ee4ea36SMarcel Holtmann remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN; 66454790f73SVinicius Costa Gomes authreq |= SMP_AUTH_BONDING; 6652b64d153SBrian Gix } else { 6662b64d153SBrian Gix authreq &= ~SMP_AUTH_BONDING; 66754790f73SVinicius Costa Gomes } 66854790f73SVinicius Costa Gomes 669d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_RPA_RESOLVING)) 670fd349c02SJohan Hedberg remote_dist |= SMP_DIST_ID_KEY; 671fd349c02SJohan Hedberg 672d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_PRIVACY)) 673863efaf2SJohan Hedberg local_dist |= SMP_DIST_ID_KEY; 674863efaf2SJohan Hedberg 675d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SC_ENABLED) && 67602b05bd8SJohan Hedberg (authreq & SMP_AUTH_SC)) { 67702b05bd8SJohan Hedberg struct oob_data *oob_data; 67802b05bd8SJohan Hedberg u8 bdaddr_type; 67902b05bd8SJohan Hedberg 680d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SSP_ENABLED)) { 681df8e1a4cSJohan Hedberg local_dist |= SMP_DIST_LINK_KEY; 682df8e1a4cSJohan Hedberg remote_dist |= SMP_DIST_LINK_KEY; 683df8e1a4cSJohan Hedberg } 68402b05bd8SJohan Hedberg 68502b05bd8SJohan Hedberg if (hcon->dst_type == ADDR_LE_DEV_PUBLIC) 68602b05bd8SJohan Hedberg bdaddr_type = BDADDR_LE_PUBLIC; 68702b05bd8SJohan Hedberg else 68802b05bd8SJohan Hedberg bdaddr_type = BDADDR_LE_RANDOM; 68902b05bd8SJohan Hedberg 69002b05bd8SJohan Hedberg oob_data = hci_find_remote_oob_data(hdev, &hcon->dst, 69102b05bd8SJohan Hedberg bdaddr_type); 6924775a4eaSMarcel Holtmann if (oob_data && oob_data->present) { 6931a8bab4fSJohan Hedberg set_bit(SMP_FLAG_REMOTE_OOB, &smp->flags); 69402b05bd8SJohan Hedberg oob_flag = SMP_OOB_PRESENT; 695a29b0733SJohan Hedberg memcpy(smp->rr, oob_data->rand256, 16); 69602b05bd8SJohan Hedberg memcpy(smp->pcnf, oob_data->hash256, 16); 697bc07cd69SMarcel Holtmann SMP_DBG("OOB Remote Confirmation: %16phN", smp->pcnf); 698bc07cd69SMarcel Holtmann SMP_DBG("OOB Remote Random: %16phN", smp->rr); 69902b05bd8SJohan Hedberg } 70002b05bd8SJohan Hedberg 701df8e1a4cSJohan Hedberg } else { 702df8e1a4cSJohan Hedberg authreq &= ~SMP_AUTH_SC; 703df8e1a4cSJohan Hedberg } 704df8e1a4cSJohan Hedberg 70554790f73SVinicius Costa Gomes if (rsp == NULL) { 70654790f73SVinicius Costa Gomes req->io_capability = conn->hcon->io_capability; 70702b05bd8SJohan Hedberg req->oob_flag = oob_flag; 70830d65e08SMatias Karhumaa req->max_key_size = hdev->le_max_key_size; 709fd349c02SJohan Hedberg req->init_key_dist = local_dist; 710fd349c02SJohan Hedberg req->resp_key_dist = remote_dist; 7110edb14deSJohan Hedberg req->auth_req = (authreq & AUTH_REQ_MASK(hdev)); 712fd349c02SJohan Hedberg 713fd349c02SJohan Hedberg smp->remote_key_dist = remote_dist; 71454790f73SVinicius Costa Gomes return; 71554790f73SVinicius Costa Gomes } 71654790f73SVinicius Costa Gomes 71754790f73SVinicius Costa Gomes rsp->io_capability = conn->hcon->io_capability; 71802b05bd8SJohan Hedberg rsp->oob_flag = oob_flag; 71930d65e08SMatias Karhumaa rsp->max_key_size = hdev->le_max_key_size; 720fd349c02SJohan Hedberg rsp->init_key_dist = req->init_key_dist & remote_dist; 721fd349c02SJohan Hedberg rsp->resp_key_dist = req->resp_key_dist & local_dist; 7220edb14deSJohan Hedberg rsp->auth_req = (authreq & AUTH_REQ_MASK(hdev)); 723fd349c02SJohan Hedberg 724fd349c02SJohan Hedberg smp->remote_key_dist = rsp->init_key_dist; 725b8e66eacSVinicius Costa Gomes } 726b8e66eacSVinicius Costa Gomes 7273158c50cSVinicius Costa Gomes static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size) 7283158c50cSVinicius Costa Gomes { 7295d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 7302fd36558SJohan Hedberg struct hci_dev *hdev = conn->hcon->hdev; 7315d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 7321c1def09SVinicius Costa Gomes 73349c06c9eSŁukasz Rymanowski if (conn->hcon->pending_sec_level == BT_SECURITY_FIPS && 73449c06c9eSŁukasz Rymanowski max_key_size != SMP_MAX_ENC_KEY_SIZE) 73549c06c9eSŁukasz Rymanowski return SMP_ENC_KEY_SIZE; 73649c06c9eSŁukasz Rymanowski 73730d65e08SMatias Karhumaa if (max_key_size > hdev->le_max_key_size || 7382fd36558SJohan Hedberg max_key_size < SMP_MIN_ENC_KEY_SIZE) 7393158c50cSVinicius Costa Gomes return SMP_ENC_KEY_SIZE; 7403158c50cSVinicius Costa Gomes 741f7aa611aSVinicius Costa Gomes smp->enc_key_size = max_key_size; 7423158c50cSVinicius Costa Gomes 7433158c50cSVinicius Costa Gomes return 0; 7443158c50cSVinicius Costa Gomes } 7453158c50cSVinicius Costa Gomes 7466f48e260SJohan Hedberg static void smp_chan_destroy(struct l2cap_conn *conn) 7476f48e260SJohan Hedberg { 7486f48e260SJohan Hedberg struct l2cap_chan *chan = conn->smp; 7496f48e260SJohan Hedberg struct smp_chan *smp = chan->data; 750923e2414SJohan Hedberg struct hci_conn *hcon = conn->hcon; 7516f48e260SJohan Hedberg bool complete; 7526f48e260SJohan Hedberg 7536f48e260SJohan Hedberg BUG_ON(!smp); 7546f48e260SJohan Hedberg 7556f48e260SJohan Hedberg cancel_delayed_work_sync(&smp->security_timer); 7566f48e260SJohan Hedberg 7576f48e260SJohan Hedberg complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags); 758923e2414SJohan Hedberg mgmt_smp_complete(hcon, complete); 7596f48e260SJohan Hedberg 760276812ecSMarcel Holtmann kzfree(smp->csrk); 761276812ecSMarcel Holtmann kzfree(smp->slave_csrk); 762276812ecSMarcel Holtmann kzfree(smp->link_key); 7636f48e260SJohan Hedberg 76471af2f6bSHerbert Xu crypto_free_shash(smp->tfm_cmac); 76547eb2ac8STudor Ambarus crypto_free_kpp(smp->tfm_ecdh); 7666f48e260SJohan Hedberg 767923e2414SJohan Hedberg /* Ensure that we don't leave any debug key around if debug key 768923e2414SJohan Hedberg * support hasn't been explicitly enabled. 769923e2414SJohan Hedberg */ 770923e2414SJohan Hedberg if (smp->ltk && smp->ltk->type == SMP_LTK_P256_DEBUG && 771d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hcon->hdev, HCI_KEEP_DEBUG_KEYS)) { 772923e2414SJohan Hedberg list_del_rcu(&smp->ltk->list); 773923e2414SJohan Hedberg kfree_rcu(smp->ltk, rcu); 774923e2414SJohan Hedberg smp->ltk = NULL; 775923e2414SJohan Hedberg } 776923e2414SJohan Hedberg 7776f48e260SJohan Hedberg /* If pairing failed clean up any keys we might have */ 7786f48e260SJohan Hedberg if (!complete) { 7796f48e260SJohan Hedberg if (smp->ltk) { 780970d0f1bSJohan Hedberg list_del_rcu(&smp->ltk->list); 781970d0f1bSJohan Hedberg kfree_rcu(smp->ltk, rcu); 7826f48e260SJohan Hedberg } 7836f48e260SJohan Hedberg 7846f48e260SJohan Hedberg if (smp->slave_ltk) { 785970d0f1bSJohan Hedberg list_del_rcu(&smp->slave_ltk->list); 786970d0f1bSJohan Hedberg kfree_rcu(smp->slave_ltk, rcu); 7876f48e260SJohan Hedberg } 7886f48e260SJohan Hedberg 7896f48e260SJohan Hedberg if (smp->remote_irk) { 790adae20cbSJohan Hedberg list_del_rcu(&smp->remote_irk->list); 791adae20cbSJohan Hedberg kfree_rcu(smp->remote_irk, rcu); 7926f48e260SJohan Hedberg } 7936f48e260SJohan Hedberg } 7946f48e260SJohan Hedberg 7956f48e260SJohan Hedberg chan->data = NULL; 796276812ecSMarcel Holtmann kzfree(smp); 797923e2414SJohan Hedberg hci_conn_drop(hcon); 7986f48e260SJohan Hedberg } 7996f48e260SJohan Hedberg 80084794e11SJohan Hedberg static void smp_failure(struct l2cap_conn *conn, u8 reason) 8014f957a76SBrian Gix { 802bab73cb6SJohan Hedberg struct hci_conn *hcon = conn->hcon; 803b68fda68SJohan Hedberg struct l2cap_chan *chan = conn->smp; 804bab73cb6SJohan Hedberg 80584794e11SJohan Hedberg if (reason) 8064f957a76SBrian Gix smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason), 8074f957a76SBrian Gix &reason); 8084f957a76SBrian Gix 809e1e930f5SJohan Hedberg mgmt_auth_failed(hcon, HCI_ERROR_AUTH_FAILURE); 810f1c09c07SVinicius Costa Gomes 811fc75cc86SJohan Hedberg if (chan->data) 8124f957a76SBrian Gix smp_chan_destroy(conn); 8134f957a76SBrian Gix } 8144f957a76SBrian Gix 8152b64d153SBrian Gix #define JUST_WORKS 0x00 8162b64d153SBrian Gix #define JUST_CFM 0x01 8172b64d153SBrian Gix #define REQ_PASSKEY 0x02 8182b64d153SBrian Gix #define CFM_PASSKEY 0x03 8192b64d153SBrian Gix #define REQ_OOB 0x04 8205e3d3d9bSJohan Hedberg #define DSP_PASSKEY 0x05 8212b64d153SBrian Gix #define OVERLAP 0xFF 8222b64d153SBrian Gix 8232b64d153SBrian Gix static const u8 gen_method[5][5] = { 8242b64d153SBrian Gix { JUST_WORKS, JUST_CFM, REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY }, 8252b64d153SBrian Gix { JUST_WORKS, JUST_CFM, REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY }, 8262b64d153SBrian Gix { CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY }, 8272b64d153SBrian Gix { JUST_WORKS, JUST_CFM, JUST_WORKS, JUST_WORKS, JUST_CFM }, 8282b64d153SBrian Gix { CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, OVERLAP }, 8292b64d153SBrian Gix }; 8302b64d153SBrian Gix 8315e3d3d9bSJohan Hedberg static const u8 sc_method[5][5] = { 8325e3d3d9bSJohan Hedberg { JUST_WORKS, JUST_CFM, REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY }, 8335e3d3d9bSJohan Hedberg { JUST_WORKS, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY }, 8345e3d3d9bSJohan Hedberg { DSP_PASSKEY, DSP_PASSKEY, REQ_PASSKEY, JUST_WORKS, DSP_PASSKEY }, 8355e3d3d9bSJohan Hedberg { JUST_WORKS, JUST_CFM, JUST_WORKS, JUST_WORKS, JUST_CFM }, 8365e3d3d9bSJohan Hedberg { DSP_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY }, 8375e3d3d9bSJohan Hedberg }; 8385e3d3d9bSJohan Hedberg 839581370ccSJohan Hedberg static u8 get_auth_method(struct smp_chan *smp, u8 local_io, u8 remote_io) 840581370ccSJohan Hedberg { 8412bcd4003SJohan Hedberg /* If either side has unknown io_caps, use JUST_CFM (which gets 8422bcd4003SJohan Hedberg * converted later to JUST_WORKS if we're initiators. 8432bcd4003SJohan Hedberg */ 844581370ccSJohan Hedberg if (local_io > SMP_IO_KEYBOARD_DISPLAY || 845581370ccSJohan Hedberg remote_io > SMP_IO_KEYBOARD_DISPLAY) 8462bcd4003SJohan Hedberg return JUST_CFM; 847581370ccSJohan Hedberg 8485e3d3d9bSJohan Hedberg if (test_bit(SMP_FLAG_SC, &smp->flags)) 8495e3d3d9bSJohan Hedberg return sc_method[remote_io][local_io]; 8505e3d3d9bSJohan Hedberg 851581370ccSJohan Hedberg return gen_method[remote_io][local_io]; 852581370ccSJohan Hedberg } 853581370ccSJohan Hedberg 8542b64d153SBrian Gix static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth, 8552b64d153SBrian Gix u8 local_io, u8 remote_io) 8562b64d153SBrian Gix { 8572b64d153SBrian Gix struct hci_conn *hcon = conn->hcon; 8585d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 8595d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 8602b64d153SBrian Gix u32 passkey = 0; 861d1d900f8SGuenter Roeck int ret; 8622b64d153SBrian Gix 8632b64d153SBrian Gix /* Initialize key for JUST WORKS */ 8642b64d153SBrian Gix memset(smp->tk, 0, sizeof(smp->tk)); 8654a74d658SJohan Hedberg clear_bit(SMP_FLAG_TK_VALID, &smp->flags); 8662b64d153SBrian Gix 8672b64d153SBrian Gix BT_DBG("tk_request: auth:%d lcl:%d rem:%d", auth, local_io, remote_io); 8682b64d153SBrian Gix 8692bcd4003SJohan Hedberg /* If neither side wants MITM, either "just" confirm an incoming 8702bcd4003SJohan Hedberg * request or use just-works for outgoing ones. The JUST_CFM 8712bcd4003SJohan Hedberg * will be converted to JUST_WORKS if necessary later in this 8722bcd4003SJohan Hedberg * function. If either side has MITM look up the method from the 8732bcd4003SJohan Hedberg * table. 8742bcd4003SJohan Hedberg */ 875581370ccSJohan Hedberg if (!(auth & SMP_AUTH_MITM)) 876783e0574SJohan Hedberg smp->method = JUST_CFM; 8772b64d153SBrian Gix else 878783e0574SJohan Hedberg smp->method = get_auth_method(smp, local_io, remote_io); 8792b64d153SBrian Gix 880a82505c7SJohan Hedberg /* Don't confirm locally initiated pairing attempts */ 881783e0574SJohan Hedberg if (smp->method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR, 882783e0574SJohan Hedberg &smp->flags)) 883783e0574SJohan Hedberg smp->method = JUST_WORKS; 884a82505c7SJohan Hedberg 88502f3e254SJohan Hedberg /* Don't bother user space with no IO capabilities */ 886783e0574SJohan Hedberg if (smp->method == JUST_CFM && 887783e0574SJohan Hedberg hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT) 888783e0574SJohan Hedberg smp->method = JUST_WORKS; 88902f3e254SJohan Hedberg 89092516cd9SSonny Sasaka /* If Just Works, Continue with Zero TK and ask user-space for 89192516cd9SSonny Sasaka * confirmation */ 892783e0574SJohan Hedberg if (smp->method == JUST_WORKS) { 893d1d900f8SGuenter Roeck ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst, 89492516cd9SSonny Sasaka hcon->type, 89592516cd9SSonny Sasaka hcon->dst_type, 89692516cd9SSonny Sasaka passkey, 1); 897d1d900f8SGuenter Roeck if (ret) 898d1d900f8SGuenter Roeck return ret; 89992516cd9SSonny Sasaka set_bit(SMP_FLAG_WAIT_USER, &smp->flags); 9002b64d153SBrian Gix return 0; 9012b64d153SBrian Gix } 9022b64d153SBrian Gix 90319c5ce9cSJohan Hedberg /* If this function is used for SC -> legacy fallback we 90419c5ce9cSJohan Hedberg * can only recover the just-works case. 90519c5ce9cSJohan Hedberg */ 90619c5ce9cSJohan Hedberg if (test_bit(SMP_FLAG_SC, &smp->flags)) 90719c5ce9cSJohan Hedberg return -EINVAL; 90819c5ce9cSJohan Hedberg 9092b64d153SBrian Gix /* Not Just Works/Confirm results in MITM Authentication */ 910783e0574SJohan Hedberg if (smp->method != JUST_CFM) { 9114a74d658SJohan Hedberg set_bit(SMP_FLAG_MITM_AUTH, &smp->flags); 9125eb596f5SJohan Hedberg if (hcon->pending_sec_level < BT_SECURITY_HIGH) 9135eb596f5SJohan Hedberg hcon->pending_sec_level = BT_SECURITY_HIGH; 9145eb596f5SJohan Hedberg } 9152b64d153SBrian Gix 9162b64d153SBrian Gix /* If both devices have Keyoard-Display I/O, the master 9172b64d153SBrian Gix * Confirms and the slave Enters the passkey. 9182b64d153SBrian Gix */ 919783e0574SJohan Hedberg if (smp->method == OVERLAP) { 92040bef302SJohan Hedberg if (hcon->role == HCI_ROLE_MASTER) 921783e0574SJohan Hedberg smp->method = CFM_PASSKEY; 9222b64d153SBrian Gix else 923783e0574SJohan Hedberg smp->method = REQ_PASSKEY; 9242b64d153SBrian Gix } 9252b64d153SBrian Gix 92601ad34d2SJohan Hedberg /* Generate random passkey. */ 927783e0574SJohan Hedberg if (smp->method == CFM_PASSKEY) { 928943a732aSJohan Hedberg memset(smp->tk, 0, sizeof(smp->tk)); 9292b64d153SBrian Gix get_random_bytes(&passkey, sizeof(passkey)); 9302b64d153SBrian Gix passkey %= 1000000; 931943a732aSJohan Hedberg put_unaligned_le32(passkey, smp->tk); 9322b64d153SBrian Gix BT_DBG("PassKey: %d", passkey); 9334a74d658SJohan Hedberg set_bit(SMP_FLAG_TK_VALID, &smp->flags); 9342b64d153SBrian Gix } 9352b64d153SBrian Gix 936783e0574SJohan Hedberg if (smp->method == REQ_PASSKEY) 937ce39fb4eSMarcel Holtmann ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst, 938272d90dfSJohan Hedberg hcon->type, hcon->dst_type); 939783e0574SJohan Hedberg else if (smp->method == JUST_CFM) 9404eb65e66SJohan Hedberg ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst, 9414eb65e66SJohan Hedberg hcon->type, hcon->dst_type, 9424eb65e66SJohan Hedberg passkey, 1); 9432b64d153SBrian Gix else 94401ad34d2SJohan Hedberg ret = mgmt_user_passkey_notify(hcon->hdev, &hcon->dst, 945272d90dfSJohan Hedberg hcon->type, hcon->dst_type, 94639adbffeSJohan Hedberg passkey, 0); 9472b64d153SBrian Gix 9482b64d153SBrian Gix return ret; 9492b64d153SBrian Gix } 9502b64d153SBrian Gix 9511cc61144SJohan Hedberg static u8 smp_confirm(struct smp_chan *smp) 9528aab4757SVinicius Costa Gomes { 9538aab4757SVinicius Costa Gomes struct l2cap_conn *conn = smp->conn; 9548aab4757SVinicius Costa Gomes struct smp_cmd_pairing_confirm cp; 9558aab4757SVinicius Costa Gomes int ret; 9568aab4757SVinicius Costa Gomes 9578aab4757SVinicius Costa Gomes BT_DBG("conn %p", conn); 9588aab4757SVinicius Costa Gomes 95928a220aaSArd Biesheuvel ret = smp_c1(smp->tk, smp->prnd, smp->preq, smp->prsp, 960b1cd5fd9SJohan Hedberg conn->hcon->init_addr_type, &conn->hcon->init_addr, 961943a732aSJohan Hedberg conn->hcon->resp_addr_type, &conn->hcon->resp_addr, 962943a732aSJohan Hedberg cp.confirm_val); 9631cc61144SJohan Hedberg if (ret) 9641cc61144SJohan Hedberg return SMP_UNSPECIFIED; 9658aab4757SVinicius Costa Gomes 9664a74d658SJohan Hedberg clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags); 9672b64d153SBrian Gix 9688aab4757SVinicius Costa Gomes smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp); 9698aab4757SVinicius Costa Gomes 970b28b4943SJohan Hedberg if (conn->hcon->out) 971b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); 972b28b4943SJohan Hedberg else 973b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM); 974b28b4943SJohan Hedberg 9751cc61144SJohan Hedberg return 0; 9768aab4757SVinicius Costa Gomes } 9778aab4757SVinicius Costa Gomes 978861580a9SJohan Hedberg static u8 smp_random(struct smp_chan *smp) 9798aab4757SVinicius Costa Gomes { 9808aab4757SVinicius Costa Gomes struct l2cap_conn *conn = smp->conn; 9818aab4757SVinicius Costa Gomes struct hci_conn *hcon = conn->hcon; 982861580a9SJohan Hedberg u8 confirm[16]; 9838aab4757SVinicius Costa Gomes int ret; 9848aab4757SVinicius Costa Gomes 9858aab4757SVinicius Costa Gomes BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave"); 9868aab4757SVinicius Costa Gomes 98728a220aaSArd Biesheuvel ret = smp_c1(smp->tk, smp->rrnd, smp->preq, smp->prsp, 988b1cd5fd9SJohan Hedberg hcon->init_addr_type, &hcon->init_addr, 989943a732aSJohan Hedberg hcon->resp_addr_type, &hcon->resp_addr, confirm); 990861580a9SJohan Hedberg if (ret) 991861580a9SJohan Hedberg return SMP_UNSPECIFIED; 9928aab4757SVinicius Costa Gomes 993329d8230SJason A. Donenfeld if (crypto_memneq(smp->pcnf, confirm, sizeof(smp->pcnf))) { 9942064ee33SMarcel Holtmann bt_dev_err(hcon->hdev, "pairing failed " 9952064ee33SMarcel Holtmann "(confirmation values mismatch)"); 996861580a9SJohan Hedberg return SMP_CONFIRM_FAILED; 9978aab4757SVinicius Costa Gomes } 9988aab4757SVinicius Costa Gomes 9998aab4757SVinicius Costa Gomes if (hcon->out) { 1000fe39c7b2SMarcel Holtmann u8 stk[16]; 1001fe39c7b2SMarcel Holtmann __le64 rand = 0; 1002fe39c7b2SMarcel Holtmann __le16 ediv = 0; 10038aab4757SVinicius Costa Gomes 100428a220aaSArd Biesheuvel smp_s1(smp->tk, smp->rrnd, smp->prnd, stk); 10058aab4757SVinicius Costa Gomes 1006861580a9SJohan Hedberg if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags)) 1007861580a9SJohan Hedberg return SMP_UNSPECIFIED; 10088aab4757SVinicius Costa Gomes 10098b76ce34SJohan Hedberg hci_le_start_enc(hcon, ediv, rand, stk, smp->enc_key_size); 1010f7aa611aSVinicius Costa Gomes hcon->enc_key_size = smp->enc_key_size; 1011fe59a05fSJohan Hedberg set_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags); 10128aab4757SVinicius Costa Gomes } else { 1013fff3490fSJohan Hedberg u8 stk[16], auth; 1014fe39c7b2SMarcel Holtmann __le64 rand = 0; 1015fe39c7b2SMarcel Holtmann __le16 ediv = 0; 10168aab4757SVinicius Costa Gomes 1017943a732aSJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd), 1018943a732aSJohan Hedberg smp->prnd); 10198aab4757SVinicius Costa Gomes 102028a220aaSArd Biesheuvel smp_s1(smp->tk, smp->prnd, smp->rrnd, stk); 10218aab4757SVinicius Costa Gomes 1022fff3490fSJohan Hedberg if (hcon->pending_sec_level == BT_SECURITY_HIGH) 1023fff3490fSJohan Hedberg auth = 1; 1024fff3490fSJohan Hedberg else 1025fff3490fSJohan Hedberg auth = 0; 1026fff3490fSJohan Hedberg 10277d5843b7SJohan Hedberg /* Even though there's no _SLAVE suffix this is the 10287d5843b7SJohan Hedberg * slave STK we're adding for later lookup (the master 10297d5843b7SJohan Hedberg * STK never needs to be stored). 10307d5843b7SJohan Hedberg */ 1031ce39fb4eSMarcel Holtmann hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, 10322ceba539SJohan Hedberg SMP_STK, auth, stk, smp->enc_key_size, ediv, rand); 10338aab4757SVinicius Costa Gomes } 10348aab4757SVinicius Costa Gomes 1035861580a9SJohan Hedberg return 0; 10368aab4757SVinicius Costa Gomes } 10378aab4757SVinicius Costa Gomes 103844f1a7abSJohan Hedberg static void smp_notify_keys(struct l2cap_conn *conn) 103944f1a7abSJohan Hedberg { 104044f1a7abSJohan Hedberg struct l2cap_chan *chan = conn->smp; 104144f1a7abSJohan Hedberg struct smp_chan *smp = chan->data; 104244f1a7abSJohan Hedberg struct hci_conn *hcon = conn->hcon; 104344f1a7abSJohan Hedberg struct hci_dev *hdev = hcon->hdev; 104444f1a7abSJohan Hedberg struct smp_cmd_pairing *req = (void *) &smp->preq[1]; 104544f1a7abSJohan Hedberg struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1]; 104644f1a7abSJohan Hedberg bool persistent; 104744f1a7abSJohan Hedberg 1048cad20c27SJohan Hedberg if (hcon->type == ACL_LINK) { 1049cad20c27SJohan Hedberg if (hcon->key_type == HCI_LK_DEBUG_COMBINATION) 1050cad20c27SJohan Hedberg persistent = false; 1051cad20c27SJohan Hedberg else 1052cad20c27SJohan Hedberg persistent = !test_bit(HCI_CONN_FLUSH_KEY, 1053cad20c27SJohan Hedberg &hcon->flags); 1054cad20c27SJohan Hedberg } else { 1055cad20c27SJohan Hedberg /* The LTKs, IRKs and CSRKs should be persistent only if 1056cad20c27SJohan Hedberg * both sides had the bonding bit set in their 1057cad20c27SJohan Hedberg * authentication requests. 1058cad20c27SJohan Hedberg */ 1059cad20c27SJohan Hedberg persistent = !!((req->auth_req & rsp->auth_req) & 1060cad20c27SJohan Hedberg SMP_AUTH_BONDING); 1061cad20c27SJohan Hedberg } 1062cad20c27SJohan Hedberg 106344f1a7abSJohan Hedberg if (smp->remote_irk) { 1064cad20c27SJohan Hedberg mgmt_new_irk(hdev, smp->remote_irk, persistent); 1065cad20c27SJohan Hedberg 106644f1a7abSJohan Hedberg /* Now that user space can be considered to know the 106744f1a7abSJohan Hedberg * identity address track the connection based on it 1068b5ae344dSJohan Hedberg * from now on (assuming this is an LE link). 106944f1a7abSJohan Hedberg */ 1070b5ae344dSJohan Hedberg if (hcon->type == LE_LINK) { 107144f1a7abSJohan Hedberg bacpy(&hcon->dst, &smp->remote_irk->bdaddr); 107244f1a7abSJohan Hedberg hcon->dst_type = smp->remote_irk->addr_type; 1073f3d82d0cSJohan Hedberg queue_work(hdev->workqueue, &conn->id_addr_update_work); 1074b5ae344dSJohan Hedberg } 107544f1a7abSJohan Hedberg } 107644f1a7abSJohan Hedberg 107744f1a7abSJohan Hedberg if (smp->csrk) { 107844f1a7abSJohan Hedberg smp->csrk->bdaddr_type = hcon->dst_type; 107944f1a7abSJohan Hedberg bacpy(&smp->csrk->bdaddr, &hcon->dst); 108044f1a7abSJohan Hedberg mgmt_new_csrk(hdev, smp->csrk, persistent); 108144f1a7abSJohan Hedberg } 108244f1a7abSJohan Hedberg 108344f1a7abSJohan Hedberg if (smp->slave_csrk) { 108444f1a7abSJohan Hedberg smp->slave_csrk->bdaddr_type = hcon->dst_type; 108544f1a7abSJohan Hedberg bacpy(&smp->slave_csrk->bdaddr, &hcon->dst); 108644f1a7abSJohan Hedberg mgmt_new_csrk(hdev, smp->slave_csrk, persistent); 108744f1a7abSJohan Hedberg } 108844f1a7abSJohan Hedberg 108944f1a7abSJohan Hedberg if (smp->ltk) { 109044f1a7abSJohan Hedberg smp->ltk->bdaddr_type = hcon->dst_type; 109144f1a7abSJohan Hedberg bacpy(&smp->ltk->bdaddr, &hcon->dst); 109244f1a7abSJohan Hedberg mgmt_new_ltk(hdev, smp->ltk, persistent); 109344f1a7abSJohan Hedberg } 109444f1a7abSJohan Hedberg 109544f1a7abSJohan Hedberg if (smp->slave_ltk) { 109644f1a7abSJohan Hedberg smp->slave_ltk->bdaddr_type = hcon->dst_type; 109744f1a7abSJohan Hedberg bacpy(&smp->slave_ltk->bdaddr, &hcon->dst); 109844f1a7abSJohan Hedberg mgmt_new_ltk(hdev, smp->slave_ltk, persistent); 109944f1a7abSJohan Hedberg } 11006a77083aSJohan Hedberg 11016a77083aSJohan Hedberg if (smp->link_key) { 1102e3befab9SJohan Hedberg struct link_key *key; 1103e3befab9SJohan Hedberg u8 type; 1104e3befab9SJohan Hedberg 1105e3befab9SJohan Hedberg if (test_bit(SMP_FLAG_DEBUG_KEY, &smp->flags)) 1106e3befab9SJohan Hedberg type = HCI_LK_DEBUG_COMBINATION; 1107e3befab9SJohan Hedberg else if (hcon->sec_level == BT_SECURITY_FIPS) 1108e3befab9SJohan Hedberg type = HCI_LK_AUTH_COMBINATION_P256; 1109e3befab9SJohan Hedberg else 1110e3befab9SJohan Hedberg type = HCI_LK_UNAUTH_COMBINATION_P256; 1111e3befab9SJohan Hedberg 1112e3befab9SJohan Hedberg key = hci_add_link_key(hdev, smp->conn->hcon, &hcon->dst, 1113e3befab9SJohan Hedberg smp->link_key, type, 0, &persistent); 1114e3befab9SJohan Hedberg if (key) { 1115e3befab9SJohan Hedberg mgmt_new_link_key(hdev, key, persistent); 1116e3befab9SJohan Hedberg 1117e3befab9SJohan Hedberg /* Don't keep debug keys around if the relevant 1118e3befab9SJohan Hedberg * flag is not set. 1119e3befab9SJohan Hedberg */ 1120d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_KEEP_DEBUG_KEYS) && 1121e3befab9SJohan Hedberg key->type == HCI_LK_DEBUG_COMBINATION) { 1122e3befab9SJohan Hedberg list_del_rcu(&key->list); 1123e3befab9SJohan Hedberg kfree_rcu(key, rcu); 1124e3befab9SJohan Hedberg } 1125e3befab9SJohan Hedberg } 11266a77083aSJohan Hedberg } 11276a77083aSJohan Hedberg } 11286a77083aSJohan Hedberg 1129d3e54a87SJohan Hedberg static void sc_add_ltk(struct smp_chan *smp) 1130d3e54a87SJohan Hedberg { 1131d3e54a87SJohan Hedberg struct hci_conn *hcon = smp->conn->hcon; 1132d3e54a87SJohan Hedberg u8 key_type, auth; 1133d3e54a87SJohan Hedberg 1134d3e54a87SJohan Hedberg if (test_bit(SMP_FLAG_DEBUG_KEY, &smp->flags)) 1135d3e54a87SJohan Hedberg key_type = SMP_LTK_P256_DEBUG; 1136d3e54a87SJohan Hedberg else 1137d3e54a87SJohan Hedberg key_type = SMP_LTK_P256; 1138d3e54a87SJohan Hedberg 1139d3e54a87SJohan Hedberg if (hcon->pending_sec_level == BT_SECURITY_FIPS) 1140d3e54a87SJohan Hedberg auth = 1; 1141d3e54a87SJohan Hedberg else 1142d3e54a87SJohan Hedberg auth = 0; 1143d3e54a87SJohan Hedberg 1144d3e54a87SJohan Hedberg smp->ltk = hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, 1145d3e54a87SJohan Hedberg key_type, auth, smp->tk, smp->enc_key_size, 1146d3e54a87SJohan Hedberg 0, 0); 1147d3e54a87SJohan Hedberg } 1148d3e54a87SJohan Hedberg 11496a77083aSJohan Hedberg static void sc_generate_link_key(struct smp_chan *smp) 11506a77083aSJohan Hedberg { 1151a62da6f1SJohan Hedberg /* From core spec. Spells out in ASCII as 'lebr'. */ 11526a77083aSJohan Hedberg const u8 lebr[4] = { 0x72, 0x62, 0x65, 0x6c }; 11536a77083aSJohan Hedberg 11546a77083aSJohan Hedberg smp->link_key = kzalloc(16, GFP_KERNEL); 11556a77083aSJohan Hedberg if (!smp->link_key) 11566a77083aSJohan Hedberg return; 11576a77083aSJohan Hedberg 1158a62da6f1SJohan Hedberg if (test_bit(SMP_FLAG_CT2, &smp->flags)) { 1159151129dfSChristophe JAILLET /* SALT = 0x000000000000000000000000746D7031 */ 1160a62da6f1SJohan Hedberg const u8 salt[16] = { 0x31, 0x70, 0x6d, 0x74 }; 1161a62da6f1SJohan Hedberg 1162a62da6f1SJohan Hedberg if (smp_h7(smp->tfm_cmac, smp->tk, salt, smp->link_key)) { 1163a62da6f1SJohan Hedberg kzfree(smp->link_key); 1164a62da6f1SJohan Hedberg smp->link_key = NULL; 1165a62da6f1SJohan Hedberg return; 1166a62da6f1SJohan Hedberg } 1167a62da6f1SJohan Hedberg } else { 1168a62da6f1SJohan Hedberg /* From core spec. Spells out in ASCII as 'tmp1'. */ 1169a62da6f1SJohan Hedberg const u8 tmp1[4] = { 0x31, 0x70, 0x6d, 0x74 }; 1170a62da6f1SJohan Hedberg 11716a77083aSJohan Hedberg if (smp_h6(smp->tfm_cmac, smp->tk, tmp1, smp->link_key)) { 1172276812ecSMarcel Holtmann kzfree(smp->link_key); 11736a77083aSJohan Hedberg smp->link_key = NULL; 11746a77083aSJohan Hedberg return; 11756a77083aSJohan Hedberg } 1176a62da6f1SJohan Hedberg } 11776a77083aSJohan Hedberg 11786a77083aSJohan Hedberg if (smp_h6(smp->tfm_cmac, smp->link_key, lebr, smp->link_key)) { 1179276812ecSMarcel Holtmann kzfree(smp->link_key); 11806a77083aSJohan Hedberg smp->link_key = NULL; 11816a77083aSJohan Hedberg return; 11826a77083aSJohan Hedberg } 118344f1a7abSJohan Hedberg } 118444f1a7abSJohan Hedberg 1185b28b4943SJohan Hedberg static void smp_allow_key_dist(struct smp_chan *smp) 1186b28b4943SJohan Hedberg { 1187b28b4943SJohan Hedberg /* Allow the first expected phase 3 PDU. The rest of the PDUs 1188b28b4943SJohan Hedberg * will be allowed in each PDU handler to ensure we receive 1189b28b4943SJohan Hedberg * them in the correct order. 1190b28b4943SJohan Hedberg */ 1191b28b4943SJohan Hedberg if (smp->remote_key_dist & SMP_DIST_ENC_KEY) 1192b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_ENCRYPT_INFO); 1193b28b4943SJohan Hedberg else if (smp->remote_key_dist & SMP_DIST_ID_KEY) 1194b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO); 1195b28b4943SJohan Hedberg else if (smp->remote_key_dist & SMP_DIST_SIGN) 1196b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO); 1197b28b4943SJohan Hedberg } 1198b28b4943SJohan Hedberg 1199b5ae344dSJohan Hedberg static void sc_generate_ltk(struct smp_chan *smp) 1200b5ae344dSJohan Hedberg { 1201a62da6f1SJohan Hedberg /* From core spec. Spells out in ASCII as 'brle'. */ 1202b5ae344dSJohan Hedberg const u8 brle[4] = { 0x65, 0x6c, 0x72, 0x62 }; 1203b5ae344dSJohan Hedberg struct hci_conn *hcon = smp->conn->hcon; 1204b5ae344dSJohan Hedberg struct hci_dev *hdev = hcon->hdev; 1205b5ae344dSJohan Hedberg struct link_key *key; 1206b5ae344dSJohan Hedberg 1207b5ae344dSJohan Hedberg key = hci_find_link_key(hdev, &hcon->dst); 1208b5ae344dSJohan Hedberg if (!key) { 12092064ee33SMarcel Holtmann bt_dev_err(hdev, "no Link Key found to generate LTK"); 1210b5ae344dSJohan Hedberg return; 1211b5ae344dSJohan Hedberg } 1212b5ae344dSJohan Hedberg 1213b5ae344dSJohan Hedberg if (key->type == HCI_LK_DEBUG_COMBINATION) 1214b5ae344dSJohan Hedberg set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags); 1215b5ae344dSJohan Hedberg 1216a62da6f1SJohan Hedberg if (test_bit(SMP_FLAG_CT2, &smp->flags)) { 1217151129dfSChristophe JAILLET /* SALT = 0x000000000000000000000000746D7032 */ 1218a62da6f1SJohan Hedberg const u8 salt[16] = { 0x32, 0x70, 0x6d, 0x74 }; 1219a62da6f1SJohan Hedberg 1220a62da6f1SJohan Hedberg if (smp_h7(smp->tfm_cmac, key->val, salt, smp->tk)) 1221a62da6f1SJohan Hedberg return; 1222a62da6f1SJohan Hedberg } else { 1223a62da6f1SJohan Hedberg /* From core spec. Spells out in ASCII as 'tmp2'. */ 1224a62da6f1SJohan Hedberg const u8 tmp2[4] = { 0x32, 0x70, 0x6d, 0x74 }; 1225a62da6f1SJohan Hedberg 1226b5ae344dSJohan Hedberg if (smp_h6(smp->tfm_cmac, key->val, tmp2, smp->tk)) 1227b5ae344dSJohan Hedberg return; 1228a62da6f1SJohan Hedberg } 1229b5ae344dSJohan Hedberg 1230b5ae344dSJohan Hedberg if (smp_h6(smp->tfm_cmac, smp->tk, brle, smp->tk)) 1231b5ae344dSJohan Hedberg return; 1232b5ae344dSJohan Hedberg 1233b5ae344dSJohan Hedberg sc_add_ltk(smp); 1234b5ae344dSJohan Hedberg } 1235b5ae344dSJohan Hedberg 1236d6268e86SJohan Hedberg static void smp_distribute_keys(struct smp_chan *smp) 123744f1a7abSJohan Hedberg { 123844f1a7abSJohan Hedberg struct smp_cmd_pairing *req, *rsp; 123986d1407cSJohan Hedberg struct l2cap_conn *conn = smp->conn; 124044f1a7abSJohan Hedberg struct hci_conn *hcon = conn->hcon; 124144f1a7abSJohan Hedberg struct hci_dev *hdev = hcon->hdev; 124244f1a7abSJohan Hedberg __u8 *keydist; 124344f1a7abSJohan Hedberg 124444f1a7abSJohan Hedberg BT_DBG("conn %p", conn); 124544f1a7abSJohan Hedberg 124644f1a7abSJohan Hedberg rsp = (void *) &smp->prsp[1]; 124744f1a7abSJohan Hedberg 124844f1a7abSJohan Hedberg /* The responder sends its keys first */ 1249b28b4943SJohan Hedberg if (hcon->out && (smp->remote_key_dist & KEY_DIST_MASK)) { 1250b28b4943SJohan Hedberg smp_allow_key_dist(smp); 125186d1407cSJohan Hedberg return; 1252b28b4943SJohan Hedberg } 125344f1a7abSJohan Hedberg 125444f1a7abSJohan Hedberg req = (void *) &smp->preq[1]; 125544f1a7abSJohan Hedberg 125644f1a7abSJohan Hedberg if (hcon->out) { 125744f1a7abSJohan Hedberg keydist = &rsp->init_key_dist; 125844f1a7abSJohan Hedberg *keydist &= req->init_key_dist; 125944f1a7abSJohan Hedberg } else { 126044f1a7abSJohan Hedberg keydist = &rsp->resp_key_dist; 126144f1a7abSJohan Hedberg *keydist &= req->resp_key_dist; 126244f1a7abSJohan Hedberg } 126344f1a7abSJohan Hedberg 12646a77083aSJohan Hedberg if (test_bit(SMP_FLAG_SC, &smp->flags)) { 1265b5ae344dSJohan Hedberg if (hcon->type == LE_LINK && (*keydist & SMP_DIST_LINK_KEY)) 12666a77083aSJohan Hedberg sc_generate_link_key(smp); 1267b5ae344dSJohan Hedberg if (hcon->type == ACL_LINK && (*keydist & SMP_DIST_ENC_KEY)) 1268b5ae344dSJohan Hedberg sc_generate_ltk(smp); 12696a77083aSJohan Hedberg 12706a77083aSJohan Hedberg /* Clear the keys which are generated but not distributed */ 12716a77083aSJohan Hedberg *keydist &= ~SMP_SC_NO_DIST; 12726a77083aSJohan Hedberg } 12736a77083aSJohan Hedberg 127444f1a7abSJohan Hedberg BT_DBG("keydist 0x%x", *keydist); 127544f1a7abSJohan Hedberg 127644f1a7abSJohan Hedberg if (*keydist & SMP_DIST_ENC_KEY) { 127744f1a7abSJohan Hedberg struct smp_cmd_encrypt_info enc; 127844f1a7abSJohan Hedberg struct smp_cmd_master_ident ident; 127944f1a7abSJohan Hedberg struct smp_ltk *ltk; 128044f1a7abSJohan Hedberg u8 authenticated; 128144f1a7abSJohan Hedberg __le16 ediv; 128244f1a7abSJohan Hedberg __le64 rand; 128344f1a7abSJohan Hedberg 12841fc62c52SJohan Hedberg /* Make sure we generate only the significant amount of 12851fc62c52SJohan Hedberg * bytes based on the encryption key size, and set the rest 12861fc62c52SJohan Hedberg * of the value to zeroes. 12871fc62c52SJohan Hedberg */ 12881fc62c52SJohan Hedberg get_random_bytes(enc.ltk, smp->enc_key_size); 12891fc62c52SJohan Hedberg memset(enc.ltk + smp->enc_key_size, 0, 12901fc62c52SJohan Hedberg sizeof(enc.ltk) - smp->enc_key_size); 12911fc62c52SJohan Hedberg 129244f1a7abSJohan Hedberg get_random_bytes(&ediv, sizeof(ediv)); 129344f1a7abSJohan Hedberg get_random_bytes(&rand, sizeof(rand)); 129444f1a7abSJohan Hedberg 129544f1a7abSJohan Hedberg smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc); 129644f1a7abSJohan Hedberg 129744f1a7abSJohan Hedberg authenticated = hcon->sec_level == BT_SECURITY_HIGH; 129844f1a7abSJohan Hedberg ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, 129944f1a7abSJohan Hedberg SMP_LTK_SLAVE, authenticated, enc.ltk, 130044f1a7abSJohan Hedberg smp->enc_key_size, ediv, rand); 130144f1a7abSJohan Hedberg smp->slave_ltk = ltk; 130244f1a7abSJohan Hedberg 130344f1a7abSJohan Hedberg ident.ediv = ediv; 130444f1a7abSJohan Hedberg ident.rand = rand; 130544f1a7abSJohan Hedberg 130644f1a7abSJohan Hedberg smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident); 130744f1a7abSJohan Hedberg 130844f1a7abSJohan Hedberg *keydist &= ~SMP_DIST_ENC_KEY; 130944f1a7abSJohan Hedberg } 131044f1a7abSJohan Hedberg 131144f1a7abSJohan Hedberg if (*keydist & SMP_DIST_ID_KEY) { 131244f1a7abSJohan Hedberg struct smp_cmd_ident_addr_info addrinfo; 131344f1a7abSJohan Hedberg struct smp_cmd_ident_info idinfo; 131444f1a7abSJohan Hedberg 131544f1a7abSJohan Hedberg memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk)); 131644f1a7abSJohan Hedberg 131744f1a7abSJohan Hedberg smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo); 131844f1a7abSJohan Hedberg 131944f1a7abSJohan Hedberg /* The hci_conn contains the local identity address 132044f1a7abSJohan Hedberg * after the connection has been established. 132144f1a7abSJohan Hedberg * 132244f1a7abSJohan Hedberg * This is true even when the connection has been 132344f1a7abSJohan Hedberg * established using a resolvable random address. 132444f1a7abSJohan Hedberg */ 132544f1a7abSJohan Hedberg bacpy(&addrinfo.bdaddr, &hcon->src); 132644f1a7abSJohan Hedberg addrinfo.addr_type = hcon->src_type; 132744f1a7abSJohan Hedberg 132844f1a7abSJohan Hedberg smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo), 132944f1a7abSJohan Hedberg &addrinfo); 133044f1a7abSJohan Hedberg 133144f1a7abSJohan Hedberg *keydist &= ~SMP_DIST_ID_KEY; 133244f1a7abSJohan Hedberg } 133344f1a7abSJohan Hedberg 133444f1a7abSJohan Hedberg if (*keydist & SMP_DIST_SIGN) { 133544f1a7abSJohan Hedberg struct smp_cmd_sign_info sign; 133644f1a7abSJohan Hedberg struct smp_csrk *csrk; 133744f1a7abSJohan Hedberg 133844f1a7abSJohan Hedberg /* Generate a new random key */ 133944f1a7abSJohan Hedberg get_random_bytes(sign.csrk, sizeof(sign.csrk)); 134044f1a7abSJohan Hedberg 134144f1a7abSJohan Hedberg csrk = kzalloc(sizeof(*csrk), GFP_KERNEL); 134244f1a7abSJohan Hedberg if (csrk) { 13434cd3928aSJohan Hedberg if (hcon->sec_level > BT_SECURITY_MEDIUM) 13444cd3928aSJohan Hedberg csrk->type = MGMT_CSRK_LOCAL_AUTHENTICATED; 13454cd3928aSJohan Hedberg else 13464cd3928aSJohan Hedberg csrk->type = MGMT_CSRK_LOCAL_UNAUTHENTICATED; 134744f1a7abSJohan Hedberg memcpy(csrk->val, sign.csrk, sizeof(csrk->val)); 134844f1a7abSJohan Hedberg } 134944f1a7abSJohan Hedberg smp->slave_csrk = csrk; 135044f1a7abSJohan Hedberg 135144f1a7abSJohan Hedberg smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign); 135244f1a7abSJohan Hedberg 135344f1a7abSJohan Hedberg *keydist &= ~SMP_DIST_SIGN; 135444f1a7abSJohan Hedberg } 135544f1a7abSJohan Hedberg 135644f1a7abSJohan Hedberg /* If there are still keys to be received wait for them */ 1357b28b4943SJohan Hedberg if (smp->remote_key_dist & KEY_DIST_MASK) { 1358b28b4943SJohan Hedberg smp_allow_key_dist(smp); 135986d1407cSJohan Hedberg return; 1360b28b4943SJohan Hedberg } 136144f1a7abSJohan Hedberg 136244f1a7abSJohan Hedberg set_bit(SMP_FLAG_COMPLETE, &smp->flags); 136344f1a7abSJohan Hedberg smp_notify_keys(conn); 136444f1a7abSJohan Hedberg 136544f1a7abSJohan Hedberg smp_chan_destroy(conn); 136644f1a7abSJohan Hedberg } 136744f1a7abSJohan Hedberg 1368b68fda68SJohan Hedberg static void smp_timeout(struct work_struct *work) 1369b68fda68SJohan Hedberg { 1370b68fda68SJohan Hedberg struct smp_chan *smp = container_of(work, struct smp_chan, 1371b68fda68SJohan Hedberg security_timer.work); 1372b68fda68SJohan Hedberg struct l2cap_conn *conn = smp->conn; 1373b68fda68SJohan Hedberg 1374b68fda68SJohan Hedberg BT_DBG("conn %p", conn); 1375b68fda68SJohan Hedberg 13761e91c29eSJohan Hedberg hci_disconnect(conn->hcon, HCI_ERROR_REMOTE_USER_TERM); 1377b68fda68SJohan Hedberg } 1378b68fda68SJohan Hedberg 13798aab4757SVinicius Costa Gomes static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) 13808aab4757SVinicius Costa Gomes { 13815d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 13828aab4757SVinicius Costa Gomes struct smp_chan *smp; 13838aab4757SVinicius Costa Gomes 1384f1560463SMarcel Holtmann smp = kzalloc(sizeof(*smp), GFP_ATOMIC); 1385fc75cc86SJohan Hedberg if (!smp) 13868aab4757SVinicius Costa Gomes return NULL; 13878aab4757SVinicius Costa Gomes 138871af2f6bSHerbert Xu smp->tfm_cmac = crypto_alloc_shash("cmac(aes)", 0, 0); 1389407cecf6SJohan Hedberg if (IS_ERR(smp->tfm_cmac)) { 1390407cecf6SJohan Hedberg BT_ERR("Unable to create CMAC crypto context"); 139128a220aaSArd Biesheuvel goto zfree_smp; 139247eb2ac8STudor Ambarus } 139347eb2ac8STudor Ambarus 1394*075f7732SHerbert Xu smp->tfm_ecdh = crypto_alloc_kpp("ecdh", 0, 0); 139547eb2ac8STudor Ambarus if (IS_ERR(smp->tfm_ecdh)) { 139647eb2ac8STudor Ambarus BT_ERR("Unable to create ECDH crypto context"); 139747eb2ac8STudor Ambarus goto free_shash; 1398407cecf6SJohan Hedberg } 1399407cecf6SJohan Hedberg 14008aab4757SVinicius Costa Gomes smp->conn = conn; 14015d88cc73SJohan Hedberg chan->data = smp; 14028aab4757SVinicius Costa Gomes 1403b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_FAIL); 1404b28b4943SJohan Hedberg 1405b68fda68SJohan Hedberg INIT_DELAYED_WORK(&smp->security_timer, smp_timeout); 1406b68fda68SJohan Hedberg 14078aab4757SVinicius Costa Gomes hci_conn_hold(conn->hcon); 14088aab4757SVinicius Costa Gomes 14098aab4757SVinicius Costa Gomes return smp; 141047eb2ac8STudor Ambarus 141147eb2ac8STudor Ambarus free_shash: 141247eb2ac8STudor Ambarus crypto_free_shash(smp->tfm_cmac); 141347eb2ac8STudor Ambarus zfree_smp: 141447eb2ac8STudor Ambarus kzfree(smp); 141547eb2ac8STudor Ambarus return NULL; 14168aab4757SVinicius Costa Gomes } 14178aab4757SVinicius Costa Gomes 1418760b018bSJohan Hedberg static int sc_mackey_and_ltk(struct smp_chan *smp, u8 mackey[16], u8 ltk[16]) 1419760b018bSJohan Hedberg { 1420760b018bSJohan Hedberg struct hci_conn *hcon = smp->conn->hcon; 1421760b018bSJohan Hedberg u8 *na, *nb, a[7], b[7]; 1422760b018bSJohan Hedberg 1423760b018bSJohan Hedberg if (hcon->out) { 1424760b018bSJohan Hedberg na = smp->prnd; 1425760b018bSJohan Hedberg nb = smp->rrnd; 1426760b018bSJohan Hedberg } else { 1427760b018bSJohan Hedberg na = smp->rrnd; 1428760b018bSJohan Hedberg nb = smp->prnd; 1429760b018bSJohan Hedberg } 1430760b018bSJohan Hedberg 1431760b018bSJohan Hedberg memcpy(a, &hcon->init_addr, 6); 1432760b018bSJohan Hedberg memcpy(b, &hcon->resp_addr, 6); 1433760b018bSJohan Hedberg a[6] = hcon->init_addr_type; 1434760b018bSJohan Hedberg b[6] = hcon->resp_addr_type; 1435760b018bSJohan Hedberg 1436760b018bSJohan Hedberg return smp_f5(smp->tfm_cmac, smp->dhkey, na, nb, a, b, mackey, ltk); 1437760b018bSJohan Hedberg } 1438760b018bSJohan Hedberg 143938606f14SJohan Hedberg static void sc_dhkey_check(struct smp_chan *smp) 1440760b018bSJohan Hedberg { 1441760b018bSJohan Hedberg struct hci_conn *hcon = smp->conn->hcon; 1442760b018bSJohan Hedberg struct smp_cmd_dhkey_check check; 1443760b018bSJohan Hedberg u8 a[7], b[7], *local_addr, *remote_addr; 1444760b018bSJohan Hedberg u8 io_cap[3], r[16]; 1445760b018bSJohan Hedberg 1446760b018bSJohan Hedberg memcpy(a, &hcon->init_addr, 6); 1447760b018bSJohan Hedberg memcpy(b, &hcon->resp_addr, 6); 1448760b018bSJohan Hedberg a[6] = hcon->init_addr_type; 1449760b018bSJohan Hedberg b[6] = hcon->resp_addr_type; 1450760b018bSJohan Hedberg 1451760b018bSJohan Hedberg if (hcon->out) { 1452760b018bSJohan Hedberg local_addr = a; 1453760b018bSJohan Hedberg remote_addr = b; 1454760b018bSJohan Hedberg memcpy(io_cap, &smp->preq[1], 3); 1455760b018bSJohan Hedberg } else { 1456760b018bSJohan Hedberg local_addr = b; 1457760b018bSJohan Hedberg remote_addr = a; 1458760b018bSJohan Hedberg memcpy(io_cap, &smp->prsp[1], 3); 1459760b018bSJohan Hedberg } 1460760b018bSJohan Hedberg 1461dddd3059SJohan Hedberg memset(r, 0, sizeof(r)); 1462dddd3059SJohan Hedberg 1463dddd3059SJohan Hedberg if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY) 146438606f14SJohan Hedberg put_unaligned_le32(hcon->passkey_notify, r); 1465760b018bSJohan Hedberg 1466a29b0733SJohan Hedberg if (smp->method == REQ_OOB) 1467a29b0733SJohan Hedberg memcpy(r, smp->rr, 16); 1468a29b0733SJohan Hedberg 1469760b018bSJohan Hedberg smp_f6(smp->tfm_cmac, smp->mackey, smp->prnd, smp->rrnd, r, io_cap, 1470760b018bSJohan Hedberg local_addr, remote_addr, check.e); 1471760b018bSJohan Hedberg 1472760b018bSJohan Hedberg smp_send_cmd(smp->conn, SMP_CMD_DHKEY_CHECK, sizeof(check), &check); 1473dddd3059SJohan Hedberg } 1474dddd3059SJohan Hedberg 147538606f14SJohan Hedberg static u8 sc_passkey_send_confirm(struct smp_chan *smp) 147638606f14SJohan Hedberg { 147738606f14SJohan Hedberg struct l2cap_conn *conn = smp->conn; 147838606f14SJohan Hedberg struct hci_conn *hcon = conn->hcon; 147938606f14SJohan Hedberg struct smp_cmd_pairing_confirm cfm; 148038606f14SJohan Hedberg u8 r; 148138606f14SJohan Hedberg 148238606f14SJohan Hedberg r = ((hcon->passkey_notify >> smp->passkey_round) & 0x01); 148338606f14SJohan Hedberg r |= 0x80; 148438606f14SJohan Hedberg 148538606f14SJohan Hedberg get_random_bytes(smp->prnd, sizeof(smp->prnd)); 148638606f14SJohan Hedberg 148738606f14SJohan Hedberg if (smp_f4(smp->tfm_cmac, smp->local_pk, smp->remote_pk, smp->prnd, r, 148838606f14SJohan Hedberg cfm.confirm_val)) 148938606f14SJohan Hedberg return SMP_UNSPECIFIED; 149038606f14SJohan Hedberg 149138606f14SJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cfm), &cfm); 149238606f14SJohan Hedberg 149338606f14SJohan Hedberg return 0; 149438606f14SJohan Hedberg } 149538606f14SJohan Hedberg 149638606f14SJohan Hedberg static u8 sc_passkey_round(struct smp_chan *smp, u8 smp_op) 149738606f14SJohan Hedberg { 149838606f14SJohan Hedberg struct l2cap_conn *conn = smp->conn; 149938606f14SJohan Hedberg struct hci_conn *hcon = conn->hcon; 150038606f14SJohan Hedberg struct hci_dev *hdev = hcon->hdev; 150138606f14SJohan Hedberg u8 cfm[16], r; 150238606f14SJohan Hedberg 150338606f14SJohan Hedberg /* Ignore the PDU if we've already done 20 rounds (0 - 19) */ 150438606f14SJohan Hedberg if (smp->passkey_round >= 20) 150538606f14SJohan Hedberg return 0; 150638606f14SJohan Hedberg 150738606f14SJohan Hedberg switch (smp_op) { 150838606f14SJohan Hedberg case SMP_CMD_PAIRING_RANDOM: 150938606f14SJohan Hedberg r = ((hcon->passkey_notify >> smp->passkey_round) & 0x01); 151038606f14SJohan Hedberg r |= 0x80; 151138606f14SJohan Hedberg 151238606f14SJohan Hedberg if (smp_f4(smp->tfm_cmac, smp->remote_pk, smp->local_pk, 151338606f14SJohan Hedberg smp->rrnd, r, cfm)) 151438606f14SJohan Hedberg return SMP_UNSPECIFIED; 151538606f14SJohan Hedberg 1516329d8230SJason A. Donenfeld if (crypto_memneq(smp->pcnf, cfm, 16)) 151738606f14SJohan Hedberg return SMP_CONFIRM_FAILED; 151838606f14SJohan Hedberg 151938606f14SJohan Hedberg smp->passkey_round++; 152038606f14SJohan Hedberg 152138606f14SJohan Hedberg if (smp->passkey_round == 20) { 152238606f14SJohan Hedberg /* Generate MacKey and LTK */ 152338606f14SJohan Hedberg if (sc_mackey_and_ltk(smp, smp->mackey, smp->tk)) 152438606f14SJohan Hedberg return SMP_UNSPECIFIED; 152538606f14SJohan Hedberg } 152638606f14SJohan Hedberg 152738606f14SJohan Hedberg /* The round is only complete when the initiator 152838606f14SJohan Hedberg * receives pairing random. 152938606f14SJohan Hedberg */ 153038606f14SJohan Hedberg if (!hcon->out) { 153138606f14SJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, 153238606f14SJohan Hedberg sizeof(smp->prnd), smp->prnd); 1533d3e54a87SJohan Hedberg if (smp->passkey_round == 20) 153438606f14SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK); 1535d3e54a87SJohan Hedberg else 153638606f14SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); 153738606f14SJohan Hedberg return 0; 153838606f14SJohan Hedberg } 153938606f14SJohan Hedberg 154038606f14SJohan Hedberg /* Start the next round */ 154138606f14SJohan Hedberg if (smp->passkey_round != 20) 154238606f14SJohan Hedberg return sc_passkey_round(smp, 0); 154338606f14SJohan Hedberg 154438606f14SJohan Hedberg /* Passkey rounds are complete - start DHKey Check */ 154538606f14SJohan Hedberg sc_dhkey_check(smp); 154638606f14SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK); 154738606f14SJohan Hedberg 154838606f14SJohan Hedberg break; 154938606f14SJohan Hedberg 155038606f14SJohan Hedberg case SMP_CMD_PAIRING_CONFIRM: 155138606f14SJohan Hedberg if (test_bit(SMP_FLAG_WAIT_USER, &smp->flags)) { 155238606f14SJohan Hedberg set_bit(SMP_FLAG_CFM_PENDING, &smp->flags); 155338606f14SJohan Hedberg return 0; 155438606f14SJohan Hedberg } 155538606f14SJohan Hedberg 155638606f14SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM); 155738606f14SJohan Hedberg 155838606f14SJohan Hedberg if (hcon->out) { 155938606f14SJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, 156038606f14SJohan Hedberg sizeof(smp->prnd), smp->prnd); 156138606f14SJohan Hedberg return 0; 156238606f14SJohan Hedberg } 156338606f14SJohan Hedberg 156438606f14SJohan Hedberg return sc_passkey_send_confirm(smp); 156538606f14SJohan Hedberg 156638606f14SJohan Hedberg case SMP_CMD_PUBLIC_KEY: 156738606f14SJohan Hedberg default: 156838606f14SJohan Hedberg /* Initiating device starts the round */ 156938606f14SJohan Hedberg if (!hcon->out) 157038606f14SJohan Hedberg return 0; 157138606f14SJohan Hedberg 157238606f14SJohan Hedberg BT_DBG("%s Starting passkey round %u", hdev->name, 157338606f14SJohan Hedberg smp->passkey_round + 1); 157438606f14SJohan Hedberg 157538606f14SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); 157638606f14SJohan Hedberg 157738606f14SJohan Hedberg return sc_passkey_send_confirm(smp); 157838606f14SJohan Hedberg } 157938606f14SJohan Hedberg 158038606f14SJohan Hedberg return 0; 158138606f14SJohan Hedberg } 158238606f14SJohan Hedberg 1583dddd3059SJohan Hedberg static int sc_user_reply(struct smp_chan *smp, u16 mgmt_op, __le32 passkey) 1584dddd3059SJohan Hedberg { 158538606f14SJohan Hedberg struct l2cap_conn *conn = smp->conn; 158638606f14SJohan Hedberg struct hci_conn *hcon = conn->hcon; 158738606f14SJohan Hedberg u8 smp_op; 158838606f14SJohan Hedberg 158938606f14SJohan Hedberg clear_bit(SMP_FLAG_WAIT_USER, &smp->flags); 159038606f14SJohan Hedberg 1591dddd3059SJohan Hedberg switch (mgmt_op) { 1592dddd3059SJohan Hedberg case MGMT_OP_USER_PASSKEY_NEG_REPLY: 1593dddd3059SJohan Hedberg smp_failure(smp->conn, SMP_PASSKEY_ENTRY_FAILED); 1594dddd3059SJohan Hedberg return 0; 1595dddd3059SJohan Hedberg case MGMT_OP_USER_CONFIRM_NEG_REPLY: 1596dddd3059SJohan Hedberg smp_failure(smp->conn, SMP_NUMERIC_COMP_FAILED); 1597dddd3059SJohan Hedberg return 0; 159838606f14SJohan Hedberg case MGMT_OP_USER_PASSKEY_REPLY: 159938606f14SJohan Hedberg hcon->passkey_notify = le32_to_cpu(passkey); 160038606f14SJohan Hedberg smp->passkey_round = 0; 160138606f14SJohan Hedberg 160238606f14SJohan Hedberg if (test_and_clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags)) 160338606f14SJohan Hedberg smp_op = SMP_CMD_PAIRING_CONFIRM; 160438606f14SJohan Hedberg else 160538606f14SJohan Hedberg smp_op = 0; 160638606f14SJohan Hedberg 160738606f14SJohan Hedberg if (sc_passkey_round(smp, smp_op)) 160838606f14SJohan Hedberg return -EIO; 160938606f14SJohan Hedberg 161038606f14SJohan Hedberg return 0; 1611dddd3059SJohan Hedberg } 1612dddd3059SJohan Hedberg 1613d3e54a87SJohan Hedberg /* Initiator sends DHKey check first */ 1614d3e54a87SJohan Hedberg if (hcon->out) { 161538606f14SJohan Hedberg sc_dhkey_check(smp); 1616d3e54a87SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK); 1617d3e54a87SJohan Hedberg } else if (test_and_clear_bit(SMP_FLAG_DHKEY_PENDING, &smp->flags)) { 1618d3e54a87SJohan Hedberg sc_dhkey_check(smp); 1619d3e54a87SJohan Hedberg sc_add_ltk(smp); 1620d3e54a87SJohan Hedberg } 1621760b018bSJohan Hedberg 1622760b018bSJohan Hedberg return 0; 1623760b018bSJohan Hedberg } 1624760b018bSJohan Hedberg 16252b64d153SBrian Gix int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey) 16262b64d153SBrian Gix { 1627b10e8017SJohan Hedberg struct l2cap_conn *conn = hcon->l2cap_data; 16285d88cc73SJohan Hedberg struct l2cap_chan *chan; 16292b64d153SBrian Gix struct smp_chan *smp; 16302b64d153SBrian Gix u32 value; 1631fc75cc86SJohan Hedberg int err; 16322b64d153SBrian Gix 16332b64d153SBrian Gix BT_DBG(""); 16342b64d153SBrian Gix 1635fc75cc86SJohan Hedberg if (!conn) 16362b64d153SBrian Gix return -ENOTCONN; 16372b64d153SBrian Gix 16385d88cc73SJohan Hedberg chan = conn->smp; 16395d88cc73SJohan Hedberg if (!chan) 16405d88cc73SJohan Hedberg return -ENOTCONN; 16415d88cc73SJohan Hedberg 1642fc75cc86SJohan Hedberg l2cap_chan_lock(chan); 1643fc75cc86SJohan Hedberg if (!chan->data) { 1644fc75cc86SJohan Hedberg err = -ENOTCONN; 1645fc75cc86SJohan Hedberg goto unlock; 1646fc75cc86SJohan Hedberg } 1647fc75cc86SJohan Hedberg 16485d88cc73SJohan Hedberg smp = chan->data; 16492b64d153SBrian Gix 1650760b018bSJohan Hedberg if (test_bit(SMP_FLAG_SC, &smp->flags)) { 1651760b018bSJohan Hedberg err = sc_user_reply(smp, mgmt_op, passkey); 1652760b018bSJohan Hedberg goto unlock; 1653760b018bSJohan Hedberg } 1654760b018bSJohan Hedberg 16552b64d153SBrian Gix switch (mgmt_op) { 16562b64d153SBrian Gix case MGMT_OP_USER_PASSKEY_REPLY: 16572b64d153SBrian Gix value = le32_to_cpu(passkey); 1658943a732aSJohan Hedberg memset(smp->tk, 0, sizeof(smp->tk)); 16592b64d153SBrian Gix BT_DBG("PassKey: %d", value); 1660943a732aSJohan Hedberg put_unaligned_le32(value, smp->tk); 166119186c7bSGustavo A. R. Silva fallthrough; 16622b64d153SBrian Gix case MGMT_OP_USER_CONFIRM_REPLY: 16634a74d658SJohan Hedberg set_bit(SMP_FLAG_TK_VALID, &smp->flags); 16642b64d153SBrian Gix break; 16652b64d153SBrian Gix case MGMT_OP_USER_PASSKEY_NEG_REPLY: 16662b64d153SBrian Gix case MGMT_OP_USER_CONFIRM_NEG_REPLY: 166784794e11SJohan Hedberg smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED); 1668fc75cc86SJohan Hedberg err = 0; 1669fc75cc86SJohan Hedberg goto unlock; 16702b64d153SBrian Gix default: 167184794e11SJohan Hedberg smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED); 1672fc75cc86SJohan Hedberg err = -EOPNOTSUPP; 1673fc75cc86SJohan Hedberg goto unlock; 16742b64d153SBrian Gix } 16752b64d153SBrian Gix 1676fc75cc86SJohan Hedberg err = 0; 1677fc75cc86SJohan Hedberg 16782b64d153SBrian Gix /* If it is our turn to send Pairing Confirm, do so now */ 16791cc61144SJohan Hedberg if (test_bit(SMP_FLAG_CFM_PENDING, &smp->flags)) { 16801cc61144SJohan Hedberg u8 rsp = smp_confirm(smp); 16811cc61144SJohan Hedberg if (rsp) 16821cc61144SJohan Hedberg smp_failure(conn, rsp); 16831cc61144SJohan Hedberg } 16842b64d153SBrian Gix 1685fc75cc86SJohan Hedberg unlock: 1686fc75cc86SJohan Hedberg l2cap_chan_unlock(chan); 1687fc75cc86SJohan Hedberg return err; 16882b64d153SBrian Gix } 16892b64d153SBrian Gix 1690b5ae344dSJohan Hedberg static void build_bredr_pairing_cmd(struct smp_chan *smp, 1691b5ae344dSJohan Hedberg struct smp_cmd_pairing *req, 1692b5ae344dSJohan Hedberg struct smp_cmd_pairing *rsp) 1693b5ae344dSJohan Hedberg { 1694b5ae344dSJohan Hedberg struct l2cap_conn *conn = smp->conn; 1695b5ae344dSJohan Hedberg struct hci_dev *hdev = conn->hcon->hdev; 1696b5ae344dSJohan Hedberg u8 local_dist = 0, remote_dist = 0; 1697b5ae344dSJohan Hedberg 1698d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_BONDABLE)) { 1699b5ae344dSJohan Hedberg local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN; 1700b5ae344dSJohan Hedberg remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN; 1701b5ae344dSJohan Hedberg } 1702b5ae344dSJohan Hedberg 1703d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_RPA_RESOLVING)) 1704b5ae344dSJohan Hedberg remote_dist |= SMP_DIST_ID_KEY; 1705b5ae344dSJohan Hedberg 1706d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_PRIVACY)) 1707b5ae344dSJohan Hedberg local_dist |= SMP_DIST_ID_KEY; 1708b5ae344dSJohan Hedberg 1709b5ae344dSJohan Hedberg if (!rsp) { 1710b5ae344dSJohan Hedberg memset(req, 0, sizeof(*req)); 1711b5ae344dSJohan Hedberg 1712a62da6f1SJohan Hedberg req->auth_req = SMP_AUTH_CT2; 1713b5ae344dSJohan Hedberg req->init_key_dist = local_dist; 1714b5ae344dSJohan Hedberg req->resp_key_dist = remote_dist; 1715e3f6a257SJohan Hedberg req->max_key_size = conn->hcon->enc_key_size; 1716b5ae344dSJohan Hedberg 1717b5ae344dSJohan Hedberg smp->remote_key_dist = remote_dist; 1718b5ae344dSJohan Hedberg 1719b5ae344dSJohan Hedberg return; 1720b5ae344dSJohan Hedberg } 1721b5ae344dSJohan Hedberg 1722b5ae344dSJohan Hedberg memset(rsp, 0, sizeof(*rsp)); 1723b5ae344dSJohan Hedberg 1724a62da6f1SJohan Hedberg rsp->auth_req = SMP_AUTH_CT2; 1725e3f6a257SJohan Hedberg rsp->max_key_size = conn->hcon->enc_key_size; 1726b5ae344dSJohan Hedberg rsp->init_key_dist = req->init_key_dist & remote_dist; 1727b5ae344dSJohan Hedberg rsp->resp_key_dist = req->resp_key_dist & local_dist; 1728b5ae344dSJohan Hedberg 1729b5ae344dSJohan Hedberg smp->remote_key_dist = rsp->init_key_dist; 1730b5ae344dSJohan Hedberg } 1731b5ae344dSJohan Hedberg 1732da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) 173388ba43b6SAnderson Briglia { 17343158c50cSVinicius Costa Gomes struct smp_cmd_pairing rsp, *req = (void *) skb->data; 1735fc75cc86SJohan Hedberg struct l2cap_chan *chan = conn->smp; 1736b3c6410bSJohan Hedberg struct hci_dev *hdev = conn->hcon->hdev; 17378aab4757SVinicius Costa Gomes struct smp_chan *smp; 1738c7262e71SJohan Hedberg u8 key_size, auth, sec_level; 17398aab4757SVinicius Costa Gomes int ret; 174088ba43b6SAnderson Briglia 174188ba43b6SAnderson Briglia BT_DBG("conn %p", conn); 174288ba43b6SAnderson Briglia 1743c46b98beSJohan Hedberg if (skb->len < sizeof(*req)) 174438e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 1745c46b98beSJohan Hedberg 174640bef302SJohan Hedberg if (conn->hcon->role != HCI_ROLE_SLAVE) 17472b64d153SBrian Gix return SMP_CMD_NOTSUPP; 17482b64d153SBrian Gix 1749fc75cc86SJohan Hedberg if (!chan->data) 17508aab4757SVinicius Costa Gomes smp = smp_chan_create(conn); 1751fc75cc86SJohan Hedberg else 17525d88cc73SJohan Hedberg smp = chan->data; 1753d26a2345SVinicius Costa Gomes 1754d08fd0e7SAndrei Emeltchenko if (!smp) 1755d08fd0e7SAndrei Emeltchenko return SMP_UNSPECIFIED; 1756d08fd0e7SAndrei Emeltchenko 1757c05b9339SJohan Hedberg /* We didn't start the pairing, so match remote */ 17580edb14deSJohan Hedberg auth = req->auth_req & AUTH_REQ_MASK(hdev); 1759c05b9339SJohan Hedberg 1760d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_BONDABLE) && 1761c05b9339SJohan Hedberg (auth & SMP_AUTH_BONDING)) 1762b3c6410bSJohan Hedberg return SMP_PAIRING_NOTSUPP; 1763b3c6410bSJohan Hedberg 1764d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SC_ONLY) && !(auth & SMP_AUTH_SC)) 1765903b71c7SJohan Hedberg return SMP_AUTH_REQUIREMENTS; 1766903b71c7SJohan Hedberg 17671c1def09SVinicius Costa Gomes smp->preq[0] = SMP_CMD_PAIRING_REQ; 17681c1def09SVinicius Costa Gomes memcpy(&smp->preq[1], req, sizeof(*req)); 17693158c50cSVinicius Costa Gomes skb_pull(skb, sizeof(*req)); 177088ba43b6SAnderson Briglia 1771cb06d366SJohan Hedberg /* If the remote side's OOB flag is set it means it has 1772cb06d366SJohan Hedberg * successfully received our local OOB data - therefore set the 1773cb06d366SJohan Hedberg * flag to indicate that local OOB is in use. 1774cb06d366SJohan Hedberg */ 177594f14e47SJohan Hedberg if (req->oob_flag == SMP_OOB_PRESENT && SMP_DEV(hdev)->local_oob) 177658428563SJohan Hedberg set_bit(SMP_FLAG_LOCAL_OOB, &smp->flags); 177758428563SJohan Hedberg 1778b5ae344dSJohan Hedberg /* SMP over BR/EDR requires special treatment */ 1779b5ae344dSJohan Hedberg if (conn->hcon->type == ACL_LINK) { 1780b5ae344dSJohan Hedberg /* We must have a BR/EDR SC link */ 178108f63cc5SMarcel Holtmann if (!test_bit(HCI_CONN_AES_CCM, &conn->hcon->flags) && 1782b7cb93e5SMarcel Holtmann !hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP)) 1783b5ae344dSJohan Hedberg return SMP_CROSS_TRANSP_NOT_ALLOWED; 1784b5ae344dSJohan Hedberg 1785b5ae344dSJohan Hedberg set_bit(SMP_FLAG_SC, &smp->flags); 1786b5ae344dSJohan Hedberg 1787b5ae344dSJohan Hedberg build_bredr_pairing_cmd(smp, req, &rsp); 1788b5ae344dSJohan Hedberg 1789a62da6f1SJohan Hedberg if (req->auth_req & SMP_AUTH_CT2) 1790a62da6f1SJohan Hedberg set_bit(SMP_FLAG_CT2, &smp->flags); 1791a62da6f1SJohan Hedberg 1792b5ae344dSJohan Hedberg key_size = min(req->max_key_size, rsp.max_key_size); 1793b5ae344dSJohan Hedberg if (check_enc_key_size(conn, key_size)) 1794b5ae344dSJohan Hedberg return SMP_ENC_KEY_SIZE; 1795b5ae344dSJohan Hedberg 1796b5ae344dSJohan Hedberg /* Clear bits which are generated but not distributed */ 1797b5ae344dSJohan Hedberg smp->remote_key_dist &= ~SMP_SC_NO_DIST; 1798b5ae344dSJohan Hedberg 1799b5ae344dSJohan Hedberg smp->prsp[0] = SMP_CMD_PAIRING_RSP; 1800b5ae344dSJohan Hedberg memcpy(&smp->prsp[1], &rsp, sizeof(rsp)); 1801b5ae344dSJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp); 1802b5ae344dSJohan Hedberg 1803b5ae344dSJohan Hedberg smp_distribute_keys(smp); 1804b5ae344dSJohan Hedberg return 0; 1805b5ae344dSJohan Hedberg } 1806b5ae344dSJohan Hedberg 18075e3d3d9bSJohan Hedberg build_pairing_cmd(conn, req, &rsp, auth); 18085e3d3d9bSJohan Hedberg 1809a62da6f1SJohan Hedberg if (rsp.auth_req & SMP_AUTH_SC) { 18105e3d3d9bSJohan Hedberg set_bit(SMP_FLAG_SC, &smp->flags); 18115e3d3d9bSJohan Hedberg 1812a62da6f1SJohan Hedberg if (rsp.auth_req & SMP_AUTH_CT2) 1813a62da6f1SJohan Hedberg set_bit(SMP_FLAG_CT2, &smp->flags); 1814a62da6f1SJohan Hedberg } 1815a62da6f1SJohan Hedberg 18165be5e275SJohan Hedberg if (conn->hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT) 18171afc2a1aSJohan Hedberg sec_level = BT_SECURITY_MEDIUM; 18181afc2a1aSJohan Hedberg else 1819c7262e71SJohan Hedberg sec_level = authreq_to_seclevel(auth); 18201afc2a1aSJohan Hedberg 1821c7262e71SJohan Hedberg if (sec_level > conn->hcon->pending_sec_level) 1822c7262e71SJohan Hedberg conn->hcon->pending_sec_level = sec_level; 1823fdde0a26SIdo Yariv 182449c922bbSStephen Hemminger /* If we need MITM check that it can be achieved */ 18252ed8f65cSJohan Hedberg if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) { 18262ed8f65cSJohan Hedberg u8 method; 18272ed8f65cSJohan Hedberg 18282ed8f65cSJohan Hedberg method = get_auth_method(smp, conn->hcon->io_capability, 18292ed8f65cSJohan Hedberg req->io_capability); 18302ed8f65cSJohan Hedberg if (method == JUST_WORKS || method == JUST_CFM) 18312ed8f65cSJohan Hedberg return SMP_AUTH_REQUIREMENTS; 18322ed8f65cSJohan Hedberg } 18332ed8f65cSJohan Hedberg 18343158c50cSVinicius Costa Gomes key_size = min(req->max_key_size, rsp.max_key_size); 18353158c50cSVinicius Costa Gomes if (check_enc_key_size(conn, key_size)) 18363158c50cSVinicius Costa Gomes return SMP_ENC_KEY_SIZE; 183788ba43b6SAnderson Briglia 1838e84a6b13SJohan Hedberg get_random_bytes(smp->prnd, sizeof(smp->prnd)); 18398aab4757SVinicius Costa Gomes 18401c1def09SVinicius Costa Gomes smp->prsp[0] = SMP_CMD_PAIRING_RSP; 18411c1def09SVinicius Costa Gomes memcpy(&smp->prsp[1], &rsp, sizeof(rsp)); 1842f01ead31SAnderson Briglia 18433158c50cSVinicius Costa Gomes smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp); 18443b19146dSJohan Hedberg 18453b19146dSJohan Hedberg clear_bit(SMP_FLAG_INITIATOR, &smp->flags); 18463b19146dSJohan Hedberg 184719c5ce9cSJohan Hedberg /* Strictly speaking we shouldn't allow Pairing Confirm for the 184819c5ce9cSJohan Hedberg * SC case, however some implementations incorrectly copy RFU auth 184919c5ce9cSJohan Hedberg * req bits from our security request, which may create a false 185019c5ce9cSJohan Hedberg * positive SC enablement. 185119c5ce9cSJohan Hedberg */ 185219c5ce9cSJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); 185319c5ce9cSJohan Hedberg 18543b19146dSJohan Hedberg if (test_bit(SMP_FLAG_SC, &smp->flags)) { 18553b19146dSJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PUBLIC_KEY); 18563b19146dSJohan Hedberg /* Clear bits which are generated but not distributed */ 18573b19146dSJohan Hedberg smp->remote_key_dist &= ~SMP_SC_NO_DIST; 18583b19146dSJohan Hedberg /* Wait for Public Key from Initiating Device */ 18593b19146dSJohan Hedberg return 0; 18603b19146dSJohan Hedberg } 1861da85e5e5SVinicius Costa Gomes 18622b64d153SBrian Gix /* Request setup of TK */ 18632b64d153SBrian Gix ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability); 18642b64d153SBrian Gix if (ret) 18652b64d153SBrian Gix return SMP_UNSPECIFIED; 18662b64d153SBrian Gix 1867da85e5e5SVinicius Costa Gomes return 0; 186888ba43b6SAnderson Briglia } 186988ba43b6SAnderson Briglia 18703b19146dSJohan Hedberg static u8 sc_send_public_key(struct smp_chan *smp) 18713b19146dSJohan Hedberg { 187270157ef5SJohan Hedberg struct hci_dev *hdev = smp->conn->hcon->hdev; 187370157ef5SJohan Hedberg 187456860245SMarcel Holtmann bt_dev_dbg(hdev, ""); 18753b19146dSJohan Hedberg 18761a8bab4fSJohan Hedberg if (test_bit(SMP_FLAG_LOCAL_OOB, &smp->flags)) { 187733d0c030SMarcel Holtmann struct l2cap_chan *chan = hdev->smp_data; 187833d0c030SMarcel Holtmann struct smp_dev *smp_dev; 187933d0c030SMarcel Holtmann 188033d0c030SMarcel Holtmann if (!chan || !chan->data) 188133d0c030SMarcel Holtmann return SMP_UNSPECIFIED; 188233d0c030SMarcel Holtmann 188333d0c030SMarcel Holtmann smp_dev = chan->data; 188433d0c030SMarcel Holtmann 188533d0c030SMarcel Holtmann memcpy(smp->local_pk, smp_dev->local_pk, 64); 1886fb334feeSMarcel Holtmann memcpy(smp->lr, smp_dev->local_rand, 16); 188733d0c030SMarcel Holtmann 188833d0c030SMarcel Holtmann if (smp_dev->debug_key) 188933d0c030SMarcel Holtmann set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags); 189033d0c030SMarcel Holtmann 189133d0c030SMarcel Holtmann goto done; 189233d0c030SMarcel Holtmann } 189333d0c030SMarcel Holtmann 1894d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS)) { 189570157ef5SJohan Hedberg BT_DBG("Using debug keys"); 1896c0153b0bSTudor Ambarus if (set_ecdh_privkey(smp->tfm_ecdh, debug_sk)) 1897c0153b0bSTudor Ambarus return SMP_UNSPECIFIED; 189870157ef5SJohan Hedberg memcpy(smp->local_pk, debug_pk, 64); 189970157ef5SJohan Hedberg set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags); 190070157ef5SJohan Hedberg } else { 19016c0dcc50SJohan Hedberg while (true) { 1902c0153b0bSTudor Ambarus /* Generate key pair for Secure Connections */ 1903c0153b0bSTudor Ambarus if (generate_ecdh_keys(smp->tfm_ecdh, smp->local_pk)) 19043b19146dSJohan Hedberg return SMP_UNSPECIFIED; 19053b19146dSJohan Hedberg 190670157ef5SJohan Hedberg /* This is unlikely, but we need to check that 190770157ef5SJohan Hedberg * we didn't accidentially generate a debug key. 19086c0dcc50SJohan Hedberg */ 1909c0153b0bSTudor Ambarus if (crypto_memneq(smp->local_pk, debug_pk, 64)) 19106c0dcc50SJohan Hedberg break; 19116c0dcc50SJohan Hedberg } 191270157ef5SJohan Hedberg } 19136c0dcc50SJohan Hedberg 191433d0c030SMarcel Holtmann done: 1915c7a3d57dSJohan Hedberg SMP_DBG("Local Public Key X: %32phN", smp->local_pk); 19168e4e2ee5SMarcel Holtmann SMP_DBG("Local Public Key Y: %32phN", smp->local_pk + 32); 19173b19146dSJohan Hedberg 19183b19146dSJohan Hedberg smp_send_cmd(smp->conn, SMP_CMD_PUBLIC_KEY, 64, smp->local_pk); 19193b19146dSJohan Hedberg 19203b19146dSJohan Hedberg return 0; 19213b19146dSJohan Hedberg } 19223b19146dSJohan Hedberg 1923da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) 192488ba43b6SAnderson Briglia { 19253158c50cSVinicius Costa Gomes struct smp_cmd_pairing *req, *rsp = (void *) skb->data; 19265d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 19275d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 19280edb14deSJohan Hedberg struct hci_dev *hdev = conn->hcon->hdev; 19293a7dbfb8SJohan Hedberg u8 key_size, auth; 19307d24ddccSAnderson Briglia int ret; 193188ba43b6SAnderson Briglia 193288ba43b6SAnderson Briglia BT_DBG("conn %p", conn); 193388ba43b6SAnderson Briglia 1934c46b98beSJohan Hedberg if (skb->len < sizeof(*rsp)) 193538e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 1936c46b98beSJohan Hedberg 193740bef302SJohan Hedberg if (conn->hcon->role != HCI_ROLE_MASTER) 19382b64d153SBrian Gix return SMP_CMD_NOTSUPP; 19392b64d153SBrian Gix 19403158c50cSVinicius Costa Gomes skb_pull(skb, sizeof(*rsp)); 1941da85e5e5SVinicius Costa Gomes 19421c1def09SVinicius Costa Gomes req = (void *) &smp->preq[1]; 19433158c50cSVinicius Costa Gomes 19443158c50cSVinicius Costa Gomes key_size = min(req->max_key_size, rsp->max_key_size); 19453158c50cSVinicius Costa Gomes if (check_enc_key_size(conn, key_size)) 19463158c50cSVinicius Costa Gomes return SMP_ENC_KEY_SIZE; 19473158c50cSVinicius Costa Gomes 19480edb14deSJohan Hedberg auth = rsp->auth_req & AUTH_REQ_MASK(hdev); 1949c05b9339SJohan Hedberg 1950d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SC_ONLY) && !(auth & SMP_AUTH_SC)) 1951903b71c7SJohan Hedberg return SMP_AUTH_REQUIREMENTS; 1952903b71c7SJohan Hedberg 1953cb06d366SJohan Hedberg /* If the remote side's OOB flag is set it means it has 1954cb06d366SJohan Hedberg * successfully received our local OOB data - therefore set the 1955cb06d366SJohan Hedberg * flag to indicate that local OOB is in use. 1956cb06d366SJohan Hedberg */ 195794f14e47SJohan Hedberg if (rsp->oob_flag == SMP_OOB_PRESENT && SMP_DEV(hdev)->local_oob) 195858428563SJohan Hedberg set_bit(SMP_FLAG_LOCAL_OOB, &smp->flags); 195958428563SJohan Hedberg 1960b5ae344dSJohan Hedberg smp->prsp[0] = SMP_CMD_PAIRING_RSP; 1961b5ae344dSJohan Hedberg memcpy(&smp->prsp[1], rsp, sizeof(*rsp)); 1962b5ae344dSJohan Hedberg 1963b5ae344dSJohan Hedberg /* Update remote key distribution in case the remote cleared 1964b5ae344dSJohan Hedberg * some bits that we had enabled in our request. 1965b5ae344dSJohan Hedberg */ 1966b5ae344dSJohan Hedberg smp->remote_key_dist &= rsp->resp_key_dist; 1967b5ae344dSJohan Hedberg 1968a62da6f1SJohan Hedberg if ((req->auth_req & SMP_AUTH_CT2) && (auth & SMP_AUTH_CT2)) 1969a62da6f1SJohan Hedberg set_bit(SMP_FLAG_CT2, &smp->flags); 1970a62da6f1SJohan Hedberg 1971b5ae344dSJohan Hedberg /* For BR/EDR this means we're done and can start phase 3 */ 1972b5ae344dSJohan Hedberg if (conn->hcon->type == ACL_LINK) { 1973b5ae344dSJohan Hedberg /* Clear bits which are generated but not distributed */ 1974b5ae344dSJohan Hedberg smp->remote_key_dist &= ~SMP_SC_NO_DIST; 1975b5ae344dSJohan Hedberg smp_distribute_keys(smp); 1976b5ae344dSJohan Hedberg return 0; 1977b5ae344dSJohan Hedberg } 1978b5ae344dSJohan Hedberg 197965668776SJohan Hedberg if ((req->auth_req & SMP_AUTH_SC) && (auth & SMP_AUTH_SC)) 198065668776SJohan Hedberg set_bit(SMP_FLAG_SC, &smp->flags); 1981d2eb9e10SJohan Hedberg else if (conn->hcon->pending_sec_level > BT_SECURITY_HIGH) 1982d2eb9e10SJohan Hedberg conn->hcon->pending_sec_level = BT_SECURITY_HIGH; 198365668776SJohan Hedberg 198449c922bbSStephen Hemminger /* If we need MITM check that it can be achieved */ 19852ed8f65cSJohan Hedberg if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) { 19862ed8f65cSJohan Hedberg u8 method; 19872ed8f65cSJohan Hedberg 19882ed8f65cSJohan Hedberg method = get_auth_method(smp, req->io_capability, 19892ed8f65cSJohan Hedberg rsp->io_capability); 19902ed8f65cSJohan Hedberg if (method == JUST_WORKS || method == JUST_CFM) 19912ed8f65cSJohan Hedberg return SMP_AUTH_REQUIREMENTS; 19922ed8f65cSJohan Hedberg } 19932ed8f65cSJohan Hedberg 1994e84a6b13SJohan Hedberg get_random_bytes(smp->prnd, sizeof(smp->prnd)); 19957d24ddccSAnderson Briglia 1996fdcc4becSJohan Hedberg /* Update remote key distribution in case the remote cleared 1997fdcc4becSJohan Hedberg * some bits that we had enabled in our request. 1998fdcc4becSJohan Hedberg */ 1999fdcc4becSJohan Hedberg smp->remote_key_dist &= rsp->resp_key_dist; 2000fdcc4becSJohan Hedberg 20013b19146dSJohan Hedberg if (test_bit(SMP_FLAG_SC, &smp->flags)) { 20023b19146dSJohan Hedberg /* Clear bits which are generated but not distributed */ 20033b19146dSJohan Hedberg smp->remote_key_dist &= ~SMP_SC_NO_DIST; 20043b19146dSJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PUBLIC_KEY); 20053b19146dSJohan Hedberg return sc_send_public_key(smp); 20063b19146dSJohan Hedberg } 20073b19146dSJohan Hedberg 2008c05b9339SJohan Hedberg auth |= req->auth_req; 20092b64d153SBrian Gix 2010476585ecSJohan Hedberg ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability); 20112b64d153SBrian Gix if (ret) 20122b64d153SBrian Gix return SMP_UNSPECIFIED; 20132b64d153SBrian Gix 20144a74d658SJohan Hedberg set_bit(SMP_FLAG_CFM_PENDING, &smp->flags); 20152b64d153SBrian Gix 20162b64d153SBrian Gix /* Can't compose response until we have been confirmed */ 20174a74d658SJohan Hedberg if (test_bit(SMP_FLAG_TK_VALID, &smp->flags)) 20181cc61144SJohan Hedberg return smp_confirm(smp); 2019da85e5e5SVinicius Costa Gomes 2020da85e5e5SVinicius Costa Gomes return 0; 202188ba43b6SAnderson Briglia } 202288ba43b6SAnderson Briglia 2023dcee2b32SJohan Hedberg static u8 sc_check_confirm(struct smp_chan *smp) 2024dcee2b32SJohan Hedberg { 2025dcee2b32SJohan Hedberg struct l2cap_conn *conn = smp->conn; 2026dcee2b32SJohan Hedberg 2027dcee2b32SJohan Hedberg BT_DBG(""); 2028dcee2b32SJohan Hedberg 202938606f14SJohan Hedberg if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY) 203038606f14SJohan Hedberg return sc_passkey_round(smp, SMP_CMD_PAIRING_CONFIRM); 203138606f14SJohan Hedberg 2032dcee2b32SJohan Hedberg if (conn->hcon->out) { 2033dcee2b32SJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd), 2034dcee2b32SJohan Hedberg smp->prnd); 2035dcee2b32SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM); 2036dcee2b32SJohan Hedberg } 2037dcee2b32SJohan Hedberg 2038dcee2b32SJohan Hedberg return 0; 2039dcee2b32SJohan Hedberg } 2040dcee2b32SJohan Hedberg 204119c5ce9cSJohan Hedberg /* Work-around for some implementations that incorrectly copy RFU bits 204219c5ce9cSJohan Hedberg * from our security request and thereby create the impression that 204319c5ce9cSJohan Hedberg * we're doing SC when in fact the remote doesn't support it. 204419c5ce9cSJohan Hedberg */ 204519c5ce9cSJohan Hedberg static int fixup_sc_false_positive(struct smp_chan *smp) 204619c5ce9cSJohan Hedberg { 204719c5ce9cSJohan Hedberg struct l2cap_conn *conn = smp->conn; 204819c5ce9cSJohan Hedberg struct hci_conn *hcon = conn->hcon; 204919c5ce9cSJohan Hedberg struct hci_dev *hdev = hcon->hdev; 205019c5ce9cSJohan Hedberg struct smp_cmd_pairing *req, *rsp; 205119c5ce9cSJohan Hedberg u8 auth; 205219c5ce9cSJohan Hedberg 205319c5ce9cSJohan Hedberg /* The issue is only observed when we're in slave role */ 205419c5ce9cSJohan Hedberg if (hcon->out) 205519c5ce9cSJohan Hedberg return SMP_UNSPECIFIED; 205619c5ce9cSJohan Hedberg 205719c5ce9cSJohan Hedberg if (hci_dev_test_flag(hdev, HCI_SC_ONLY)) { 20582064ee33SMarcel Holtmann bt_dev_err(hdev, "refusing legacy fallback in SC-only mode"); 205919c5ce9cSJohan Hedberg return SMP_UNSPECIFIED; 206019c5ce9cSJohan Hedberg } 206119c5ce9cSJohan Hedberg 20622064ee33SMarcel Holtmann bt_dev_err(hdev, "trying to fall back to legacy SMP"); 206319c5ce9cSJohan Hedberg 206419c5ce9cSJohan Hedberg req = (void *) &smp->preq[1]; 206519c5ce9cSJohan Hedberg rsp = (void *) &smp->prsp[1]; 206619c5ce9cSJohan Hedberg 206719c5ce9cSJohan Hedberg /* Rebuild key dist flags which may have been cleared for SC */ 206819c5ce9cSJohan Hedberg smp->remote_key_dist = (req->init_key_dist & rsp->resp_key_dist); 206919c5ce9cSJohan Hedberg 207019c5ce9cSJohan Hedberg auth = req->auth_req & AUTH_REQ_MASK(hdev); 207119c5ce9cSJohan Hedberg 207219c5ce9cSJohan Hedberg if (tk_request(conn, 0, auth, rsp->io_capability, req->io_capability)) { 20732064ee33SMarcel Holtmann bt_dev_err(hdev, "failed to fall back to legacy SMP"); 207419c5ce9cSJohan Hedberg return SMP_UNSPECIFIED; 207519c5ce9cSJohan Hedberg } 207619c5ce9cSJohan Hedberg 207719c5ce9cSJohan Hedberg clear_bit(SMP_FLAG_SC, &smp->flags); 207819c5ce9cSJohan Hedberg 207919c5ce9cSJohan Hedberg return 0; 208019c5ce9cSJohan Hedberg } 208119c5ce9cSJohan Hedberg 2082da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb) 208388ba43b6SAnderson Briglia { 20845d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 20855d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 20867d24ddccSAnderson Briglia 208788ba43b6SAnderson Briglia BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave"); 208888ba43b6SAnderson Briglia 2089c46b98beSJohan Hedberg if (skb->len < sizeof(smp->pcnf)) 209038e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 2091c46b98beSJohan Hedberg 20921c1def09SVinicius Costa Gomes memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf)); 20931c1def09SVinicius Costa Gomes skb_pull(skb, sizeof(smp->pcnf)); 20947d24ddccSAnderson Briglia 209519c5ce9cSJohan Hedberg if (test_bit(SMP_FLAG_SC, &smp->flags)) { 209619c5ce9cSJohan Hedberg int ret; 209719c5ce9cSJohan Hedberg 209819c5ce9cSJohan Hedberg /* Public Key exchange must happen before any other steps */ 209919c5ce9cSJohan Hedberg if (test_bit(SMP_FLAG_REMOTE_PK, &smp->flags)) 2100dcee2b32SJohan Hedberg return sc_check_confirm(smp); 2101dcee2b32SJohan Hedberg 210219c5ce9cSJohan Hedberg BT_ERR("Unexpected SMP Pairing Confirm"); 210319c5ce9cSJohan Hedberg 210419c5ce9cSJohan Hedberg ret = fixup_sc_false_positive(smp); 210519c5ce9cSJohan Hedberg if (ret) 210619c5ce9cSJohan Hedberg return ret; 210719c5ce9cSJohan Hedberg } 210819c5ce9cSJohan Hedberg 2109b28b4943SJohan Hedberg if (conn->hcon->out) { 2110943a732aSJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd), 2111943a732aSJohan Hedberg smp->prnd); 2112b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM); 2113b28b4943SJohan Hedberg return 0; 2114b28b4943SJohan Hedberg } 2115b28b4943SJohan Hedberg 2116b28b4943SJohan Hedberg if (test_bit(SMP_FLAG_TK_VALID, &smp->flags)) 21171cc61144SJohan Hedberg return smp_confirm(smp); 2118983f9814SMarcel Holtmann 21194a74d658SJohan Hedberg set_bit(SMP_FLAG_CFM_PENDING, &smp->flags); 2120da85e5e5SVinicius Costa Gomes 2121da85e5e5SVinicius Costa Gomes return 0; 212288ba43b6SAnderson Briglia } 212388ba43b6SAnderson Briglia 2124da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) 212588ba43b6SAnderson Briglia { 21265d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 21275d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 2128191dc7feSJohan Hedberg struct hci_conn *hcon = conn->hcon; 2129eed467b5SHoward Chung u8 *pkax, *pkbx, *na, *nb, confirm_hint; 2130191dc7feSJohan Hedberg u32 passkey; 2131191dc7feSJohan Hedberg int err; 21327d24ddccSAnderson Briglia 21338aab4757SVinicius Costa Gomes BT_DBG("conn %p", conn); 21347d24ddccSAnderson Briglia 2135c46b98beSJohan Hedberg if (skb->len < sizeof(smp->rrnd)) 213638e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 2137c46b98beSJohan Hedberg 2138943a732aSJohan Hedberg memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd)); 21398aab4757SVinicius Costa Gomes skb_pull(skb, sizeof(smp->rrnd)); 214088ba43b6SAnderson Briglia 2141191dc7feSJohan Hedberg if (!test_bit(SMP_FLAG_SC, &smp->flags)) 2142861580a9SJohan Hedberg return smp_random(smp); 2143191dc7feSJohan Hedberg 2144580039e8SJohan Hedberg if (hcon->out) { 2145580039e8SJohan Hedberg pkax = smp->local_pk; 2146580039e8SJohan Hedberg pkbx = smp->remote_pk; 2147580039e8SJohan Hedberg na = smp->prnd; 2148580039e8SJohan Hedberg nb = smp->rrnd; 2149580039e8SJohan Hedberg } else { 2150580039e8SJohan Hedberg pkax = smp->remote_pk; 2151580039e8SJohan Hedberg pkbx = smp->local_pk; 2152580039e8SJohan Hedberg na = smp->rrnd; 2153580039e8SJohan Hedberg nb = smp->prnd; 2154580039e8SJohan Hedberg } 2155580039e8SJohan Hedberg 2156a29b0733SJohan Hedberg if (smp->method == REQ_OOB) { 2157a29b0733SJohan Hedberg if (!hcon->out) 2158a29b0733SJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, 2159a29b0733SJohan Hedberg sizeof(smp->prnd), smp->prnd); 2160a29b0733SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK); 2161a29b0733SJohan Hedberg goto mackey_and_ltk; 2162a29b0733SJohan Hedberg } 2163a29b0733SJohan Hedberg 216438606f14SJohan Hedberg /* Passkey entry has special treatment */ 216538606f14SJohan Hedberg if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY) 216638606f14SJohan Hedberg return sc_passkey_round(smp, SMP_CMD_PAIRING_RANDOM); 216738606f14SJohan Hedberg 2168191dc7feSJohan Hedberg if (hcon->out) { 2169191dc7feSJohan Hedberg u8 cfm[16]; 2170191dc7feSJohan Hedberg 2171191dc7feSJohan Hedberg err = smp_f4(smp->tfm_cmac, smp->remote_pk, smp->local_pk, 2172191dc7feSJohan Hedberg smp->rrnd, 0, cfm); 2173191dc7feSJohan Hedberg if (err) 2174191dc7feSJohan Hedberg return SMP_UNSPECIFIED; 2175191dc7feSJohan Hedberg 2176329d8230SJason A. Donenfeld if (crypto_memneq(smp->pcnf, cfm, 16)) 2177191dc7feSJohan Hedberg return SMP_CONFIRM_FAILED; 2178191dc7feSJohan Hedberg } else { 2179191dc7feSJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd), 2180191dc7feSJohan Hedberg smp->prnd); 2181191dc7feSJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK); 2182cee5f20fSHoward Chung 2183cee5f20fSHoward Chung /* Only Just-Works pairing requires extra checks */ 2184cee5f20fSHoward Chung if (smp->method != JUST_WORKS) 2185cee5f20fSHoward Chung goto mackey_and_ltk; 2186cee5f20fSHoward Chung 2187cee5f20fSHoward Chung /* If there already exists long term key in local host, leave 2188cee5f20fSHoward Chung * the decision to user space since the remote device could 2189cee5f20fSHoward Chung * be legitimate or malicious. 2190cee5f20fSHoward Chung */ 2191cee5f20fSHoward Chung if (hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, 2192cee5f20fSHoward Chung hcon->role)) { 2193eed467b5SHoward Chung /* Set passkey to 0. The value can be any number since 2194eed467b5SHoward Chung * it'll be ignored anyway. 2195eed467b5SHoward Chung */ 2196eed467b5SHoward Chung passkey = 0; 2197eed467b5SHoward Chung confirm_hint = 1; 2198eed467b5SHoward Chung goto confirm; 2199cee5f20fSHoward Chung } 2200191dc7feSJohan Hedberg } 2201191dc7feSJohan Hedberg 2202a29b0733SJohan Hedberg mackey_and_ltk: 2203760b018bSJohan Hedberg /* Generate MacKey and LTK */ 2204760b018bSJohan Hedberg err = sc_mackey_and_ltk(smp, smp->mackey, smp->tk); 2205760b018bSJohan Hedberg if (err) 2206760b018bSJohan Hedberg return SMP_UNSPECIFIED; 2207760b018bSJohan Hedberg 2208ffee202aSSonny Sasaka if (smp->method == REQ_OOB) { 2209dddd3059SJohan Hedberg if (hcon->out) { 221038606f14SJohan Hedberg sc_dhkey_check(smp); 2211dddd3059SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK); 2212dddd3059SJohan Hedberg } 2213dddd3059SJohan Hedberg return 0; 2214dddd3059SJohan Hedberg } 2215dddd3059SJohan Hedberg 221638606f14SJohan Hedberg err = smp_g2(smp->tfm_cmac, pkax, pkbx, na, nb, &passkey); 2217191dc7feSJohan Hedberg if (err) 2218191dc7feSJohan Hedberg return SMP_UNSPECIFIED; 2219191dc7feSJohan Hedberg 2220eed467b5SHoward Chung confirm_hint = 0; 2221eed467b5SHoward Chung 2222eed467b5SHoward Chung confirm: 2223ffee202aSSonny Sasaka if (smp->method == JUST_WORKS) 2224ffee202aSSonny Sasaka confirm_hint = 1; 2225ffee202aSSonny Sasaka 222638606f14SJohan Hedberg err = mgmt_user_confirm_request(hcon->hdev, &hcon->dst, hcon->type, 2227eed467b5SHoward Chung hcon->dst_type, passkey, confirm_hint); 222838606f14SJohan Hedberg if (err) 222938606f14SJohan Hedberg return SMP_UNSPECIFIED; 223038606f14SJohan Hedberg 223138606f14SJohan Hedberg set_bit(SMP_FLAG_WAIT_USER, &smp->flags); 223238606f14SJohan Hedberg 2233191dc7feSJohan Hedberg return 0; 223488ba43b6SAnderson Briglia } 223588ba43b6SAnderson Briglia 2236f81cd823SMarcel Holtmann static bool smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level) 2237988c5997SVinicius Costa Gomes { 2238c9839a11SVinicius Costa Gomes struct smp_ltk *key; 2239988c5997SVinicius Costa Gomes struct hci_conn *hcon = conn->hcon; 2240988c5997SVinicius Costa Gomes 2241f3a73d97SJohan Hedberg key = hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, hcon->role); 2242988c5997SVinicius Costa Gomes if (!key) 2243f81cd823SMarcel Holtmann return false; 2244988c5997SVinicius Costa Gomes 2245a6f7833cSJohan Hedberg if (smp_ltk_sec_level(key) < sec_level) 2246f81cd823SMarcel Holtmann return false; 22474dab7864SJohan Hedberg 224851a8efd7SJohan Hedberg if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags)) 2249f81cd823SMarcel Holtmann return true; 2250988c5997SVinicius Costa Gomes 22518b76ce34SJohan Hedberg hci_le_start_enc(hcon, key->ediv, key->rand, key->val, key->enc_size); 2252c9839a11SVinicius Costa Gomes hcon->enc_key_size = key->enc_size; 2253988c5997SVinicius Costa Gomes 2254fe59a05fSJohan Hedberg /* We never store STKs for master role, so clear this flag */ 2255fe59a05fSJohan Hedberg clear_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags); 2256fe59a05fSJohan Hedberg 2257f81cd823SMarcel Holtmann return true; 2258988c5997SVinicius Costa Gomes } 2259f1560463SMarcel Holtmann 226035dc6f83SJohan Hedberg bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level, 226135dc6f83SJohan Hedberg enum smp_key_pref key_pref) 2262854f4727SJohan Hedberg { 2263854f4727SJohan Hedberg if (sec_level == BT_SECURITY_LOW) 2264854f4727SJohan Hedberg return true; 2265854f4727SJohan Hedberg 226635dc6f83SJohan Hedberg /* If we're encrypted with an STK but the caller prefers using 226735dc6f83SJohan Hedberg * LTK claim insufficient security. This way we allow the 226835dc6f83SJohan Hedberg * connection to be re-encrypted with an LTK, even if the LTK 226935dc6f83SJohan Hedberg * provides the same level of security. Only exception is if we 227035dc6f83SJohan Hedberg * don't have an LTK (e.g. because of key distribution bits). 22719ab65d60SJohan Hedberg */ 227235dc6f83SJohan Hedberg if (key_pref == SMP_USE_LTK && 227335dc6f83SJohan Hedberg test_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags) && 2274f3a73d97SJohan Hedberg hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, hcon->role)) 22759ab65d60SJohan Hedberg return false; 22769ab65d60SJohan Hedberg 2277854f4727SJohan Hedberg if (hcon->sec_level >= sec_level) 2278854f4727SJohan Hedberg return true; 2279854f4727SJohan Hedberg 2280854f4727SJohan Hedberg return false; 2281854f4727SJohan Hedberg } 2282854f4727SJohan Hedberg 2283da85e5e5SVinicius Costa Gomes static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) 228488ba43b6SAnderson Briglia { 228588ba43b6SAnderson Briglia struct smp_cmd_security_req *rp = (void *) skb->data; 228688ba43b6SAnderson Briglia struct smp_cmd_pairing cp; 2287f1cb9af5SVinicius Costa Gomes struct hci_conn *hcon = conn->hcon; 22880edb14deSJohan Hedberg struct hci_dev *hdev = hcon->hdev; 22898aab4757SVinicius Costa Gomes struct smp_chan *smp; 2290c05b9339SJohan Hedberg u8 sec_level, auth; 229188ba43b6SAnderson Briglia 229288ba43b6SAnderson Briglia BT_DBG("conn %p", conn); 229388ba43b6SAnderson Briglia 2294c46b98beSJohan Hedberg if (skb->len < sizeof(*rp)) 229538e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 2296c46b98beSJohan Hedberg 229740bef302SJohan Hedberg if (hcon->role != HCI_ROLE_MASTER) 229886ca9eacSJohan Hedberg return SMP_CMD_NOTSUPP; 229986ca9eacSJohan Hedberg 23000edb14deSJohan Hedberg auth = rp->auth_req & AUTH_REQ_MASK(hdev); 2301c05b9339SJohan Hedberg 2302d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SC_ONLY) && !(auth & SMP_AUTH_SC)) 2303903b71c7SJohan Hedberg return SMP_AUTH_REQUIREMENTS; 2304903b71c7SJohan Hedberg 23055be5e275SJohan Hedberg if (hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT) 23061afc2a1aSJohan Hedberg sec_level = BT_SECURITY_MEDIUM; 23071afc2a1aSJohan Hedberg else 2308c05b9339SJohan Hedberg sec_level = authreq_to_seclevel(auth); 23091afc2a1aSJohan Hedberg 231064e759f5SSzymon Janc if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK)) { 231164e759f5SSzymon Janc /* If link is already encrypted with sufficient security we 231264e759f5SSzymon Janc * still need refresh encryption as per Core Spec 5.0 Vol 3, 231364e759f5SSzymon Janc * Part H 2.4.6 231464e759f5SSzymon Janc */ 231564e759f5SSzymon Janc smp_ltk_encrypt(conn, hcon->sec_level); 2316854f4727SJohan Hedberg return 0; 231764e759f5SSzymon Janc } 2318854f4727SJohan Hedberg 2319c7262e71SJohan Hedberg if (sec_level > hcon->pending_sec_level) 2320c7262e71SJohan Hedberg hcon->pending_sec_level = sec_level; 2321feb45eb5SVinicius Costa Gomes 23224dab7864SJohan Hedberg if (smp_ltk_encrypt(conn, hcon->pending_sec_level)) 2323988c5997SVinicius Costa Gomes return 0; 2324988c5997SVinicius Costa Gomes 23258aab4757SVinicius Costa Gomes smp = smp_chan_create(conn); 2326c29d2444SJohan Hedberg if (!smp) 2327c29d2444SJohan Hedberg return SMP_UNSPECIFIED; 2328d26a2345SVinicius Costa Gomes 2329d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_BONDABLE) && 2330c05b9339SJohan Hedberg (auth & SMP_AUTH_BONDING)) 2331616d55beSJohan Hedberg return SMP_PAIRING_NOTSUPP; 2332616d55beSJohan Hedberg 233388ba43b6SAnderson Briglia skb_pull(skb, sizeof(*rp)); 233488ba43b6SAnderson Briglia 2335da85e5e5SVinicius Costa Gomes memset(&cp, 0, sizeof(cp)); 2336c05b9339SJohan Hedberg build_pairing_cmd(conn, &cp, NULL, auth); 233788ba43b6SAnderson Briglia 23381c1def09SVinicius Costa Gomes smp->preq[0] = SMP_CMD_PAIRING_REQ; 23391c1def09SVinicius Costa Gomes memcpy(&smp->preq[1], &cp, sizeof(cp)); 2340f01ead31SAnderson Briglia 234188ba43b6SAnderson Briglia smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp); 2342b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP); 2343f1cb9af5SVinicius Costa Gomes 2344da85e5e5SVinicius Costa Gomes return 0; 234588ba43b6SAnderson Briglia } 234688ba43b6SAnderson Briglia 2347cc110922SVinicius Costa Gomes int smp_conn_security(struct hci_conn *hcon, __u8 sec_level) 2348eb492e01SAnderson Briglia { 2349cc110922SVinicius Costa Gomes struct l2cap_conn *conn = hcon->l2cap_data; 2350c68b7f12SJohan Hedberg struct l2cap_chan *chan; 23510a66cf20SJohan Hedberg struct smp_chan *smp; 23522b64d153SBrian Gix __u8 authreq; 2353fc75cc86SJohan Hedberg int ret; 2354eb492e01SAnderson Briglia 23553a0259bbSVinicius Costa Gomes BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level); 23563a0259bbSVinicius Costa Gomes 23570a66cf20SJohan Hedberg /* This may be NULL if there's an unexpected disconnection */ 23580a66cf20SJohan Hedberg if (!conn) 23590a66cf20SJohan Hedberg return 1; 23600a66cf20SJohan Hedberg 2361d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hcon->hdev, HCI_LE_ENABLED)) 23622e65c9d2SAndre Guedes return 1; 23632e65c9d2SAndre Guedes 236435dc6f83SJohan Hedberg if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK)) 2365f1cb9af5SVinicius Costa Gomes return 1; 2366f1cb9af5SVinicius Costa Gomes 2367c7262e71SJohan Hedberg if (sec_level > hcon->pending_sec_level) 2368c7262e71SJohan Hedberg hcon->pending_sec_level = sec_level; 2369c7262e71SJohan Hedberg 237040bef302SJohan Hedberg if (hcon->role == HCI_ROLE_MASTER) 2371c7262e71SJohan Hedberg if (smp_ltk_encrypt(conn, hcon->pending_sec_level)) 2372c7262e71SJohan Hedberg return 0; 2373d26a2345SVinicius Costa Gomes 2374d8949aadSJohan Hedberg chan = conn->smp; 2375d8949aadSJohan Hedberg if (!chan) { 23762064ee33SMarcel Holtmann bt_dev_err(hcon->hdev, "security requested but not available"); 2377d8949aadSJohan Hedberg return 1; 2378d8949aadSJohan Hedberg } 2379d8949aadSJohan Hedberg 2380fc75cc86SJohan Hedberg l2cap_chan_lock(chan); 2381fc75cc86SJohan Hedberg 2382fc75cc86SJohan Hedberg /* If SMP is already in progress ignore this request */ 2383fc75cc86SJohan Hedberg if (chan->data) { 2384fc75cc86SJohan Hedberg ret = 0; 2385fc75cc86SJohan Hedberg goto unlock; 2386fc75cc86SJohan Hedberg } 2387d26a2345SVinicius Costa Gomes 23888aab4757SVinicius Costa Gomes smp = smp_chan_create(conn); 2389fc75cc86SJohan Hedberg if (!smp) { 2390fc75cc86SJohan Hedberg ret = 1; 2391fc75cc86SJohan Hedberg goto unlock; 2392fc75cc86SJohan Hedberg } 23932b64d153SBrian Gix 23942b64d153SBrian Gix authreq = seclevel_to_authreq(sec_level); 2395d26a2345SVinicius Costa Gomes 2396a62da6f1SJohan Hedberg if (hci_dev_test_flag(hcon->hdev, HCI_SC_ENABLED)) { 2397d2eb9e10SJohan Hedberg authreq |= SMP_AUTH_SC; 2398a62da6f1SJohan Hedberg if (hci_dev_test_flag(hcon->hdev, HCI_SSP_ENABLED)) 2399a62da6f1SJohan Hedberg authreq |= SMP_AUTH_CT2; 2400a62da6f1SJohan Hedberg } 2401d2eb9e10SJohan Hedberg 2402c2aa30dbSArchie Pusaka /* Don't attempt to set MITM if setting is overridden by debugfs 2403c2aa30dbSArchie Pusaka * Needed to pass certification test SM/MAS/PKE/BV-01-C 2404c2aa30dbSArchie Pusaka */ 2405c2aa30dbSArchie Pusaka if (!hci_dev_test_flag(hcon->hdev, HCI_FORCE_NO_MITM)) { 240679897d20SJohan Hedberg /* Require MITM if IO Capability allows or the security level 240779897d20SJohan Hedberg * requires it. 24082e233644SJohan Hedberg */ 240979897d20SJohan Hedberg if (hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT || 2410c7262e71SJohan Hedberg hcon->pending_sec_level > BT_SECURITY_MEDIUM) 24112e233644SJohan Hedberg authreq |= SMP_AUTH_MITM; 2412c2aa30dbSArchie Pusaka } 24132e233644SJohan Hedberg 241440bef302SJohan Hedberg if (hcon->role == HCI_ROLE_MASTER) { 2415d26a2345SVinicius Costa Gomes struct smp_cmd_pairing cp; 2416f01ead31SAnderson Briglia 24172b64d153SBrian Gix build_pairing_cmd(conn, &cp, NULL, authreq); 24181c1def09SVinicius Costa Gomes smp->preq[0] = SMP_CMD_PAIRING_REQ; 24191c1def09SVinicius Costa Gomes memcpy(&smp->preq[1], &cp, sizeof(cp)); 2420f01ead31SAnderson Briglia 2421eb492e01SAnderson Briglia smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp); 2422b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP); 2423eb492e01SAnderson Briglia } else { 2424eb492e01SAnderson Briglia struct smp_cmd_security_req cp; 24252b64d153SBrian Gix cp.auth_req = authreq; 2426eb492e01SAnderson Briglia smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp); 2427b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_REQ); 2428eb492e01SAnderson Briglia } 2429eb492e01SAnderson Briglia 24304a74d658SJohan Hedberg set_bit(SMP_FLAG_INITIATOR, &smp->flags); 2431fc75cc86SJohan Hedberg ret = 0; 2432edca792cSJohan Hedberg 2433fc75cc86SJohan Hedberg unlock: 2434fc75cc86SJohan Hedberg l2cap_chan_unlock(chan); 2435fc75cc86SJohan Hedberg return ret; 2436eb492e01SAnderson Briglia } 2437eb492e01SAnderson Briglia 2438cb28c306SMatias Karhumaa int smp_cancel_and_remove_pairing(struct hci_dev *hdev, bdaddr_t *bdaddr, 2439cb28c306SMatias Karhumaa u8 addr_type) 2440c81d555aSJohan Hedberg { 2441cb28c306SMatias Karhumaa struct hci_conn *hcon; 2442cb28c306SMatias Karhumaa struct l2cap_conn *conn; 2443c81d555aSJohan Hedberg struct l2cap_chan *chan; 2444c81d555aSJohan Hedberg struct smp_chan *smp; 2445cb28c306SMatias Karhumaa int err; 2446c81d555aSJohan Hedberg 2447cb28c306SMatias Karhumaa err = hci_remove_ltk(hdev, bdaddr, addr_type); 2448cb28c306SMatias Karhumaa hci_remove_irk(hdev, bdaddr, addr_type); 2449cb28c306SMatias Karhumaa 2450cb28c306SMatias Karhumaa hcon = hci_conn_hash_lookup_le(hdev, bdaddr, addr_type); 2451cb28c306SMatias Karhumaa if (!hcon) 2452cb28c306SMatias Karhumaa goto done; 2453cb28c306SMatias Karhumaa 2454cb28c306SMatias Karhumaa conn = hcon->l2cap_data; 2455c81d555aSJohan Hedberg if (!conn) 2456cb28c306SMatias Karhumaa goto done; 2457c81d555aSJohan Hedberg 2458c81d555aSJohan Hedberg chan = conn->smp; 2459c81d555aSJohan Hedberg if (!chan) 2460cb28c306SMatias Karhumaa goto done; 2461c81d555aSJohan Hedberg 2462c81d555aSJohan Hedberg l2cap_chan_lock(chan); 2463c81d555aSJohan Hedberg 2464c81d555aSJohan Hedberg smp = chan->data; 2465c81d555aSJohan Hedberg if (smp) { 2466cb28c306SMatias Karhumaa /* Set keys to NULL to make sure smp_failure() does not try to 2467cb28c306SMatias Karhumaa * remove and free already invalidated rcu list entries. */ 2468cb28c306SMatias Karhumaa smp->ltk = NULL; 2469cb28c306SMatias Karhumaa smp->slave_ltk = NULL; 2470cb28c306SMatias Karhumaa smp->remote_irk = NULL; 2471cb28c306SMatias Karhumaa 2472c81d555aSJohan Hedberg if (test_bit(SMP_FLAG_COMPLETE, &smp->flags)) 2473c81d555aSJohan Hedberg smp_failure(conn, 0); 2474c81d555aSJohan Hedberg else 2475c81d555aSJohan Hedberg smp_failure(conn, SMP_UNSPECIFIED); 2476cb28c306SMatias Karhumaa err = 0; 2477c81d555aSJohan Hedberg } 2478c81d555aSJohan Hedberg 2479c81d555aSJohan Hedberg l2cap_chan_unlock(chan); 2480cb28c306SMatias Karhumaa 2481cb28c306SMatias Karhumaa done: 2482cb28c306SMatias Karhumaa return err; 2483c81d555aSJohan Hedberg } 2484c81d555aSJohan Hedberg 24857034b911SVinicius Costa Gomes static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb) 24867034b911SVinicius Costa Gomes { 248716b90839SVinicius Costa Gomes struct smp_cmd_encrypt_info *rp = (void *) skb->data; 24885d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 24895d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 249016b90839SVinicius Costa Gomes 2491c46b98beSJohan Hedberg BT_DBG("conn %p", conn); 2492c46b98beSJohan Hedberg 2493c46b98beSJohan Hedberg if (skb->len < sizeof(*rp)) 249438e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 2495c46b98beSJohan Hedberg 2496600a8749SAlain Michaud /* Pairing is aborted if any blocked keys are distributed */ 2497600a8749SAlain Michaud if (hci_is_blocked_key(conn->hcon->hdev, HCI_BLOCKED_KEY_TYPE_LTK, 2498600a8749SAlain Michaud rp->ltk)) { 2499600a8749SAlain Michaud bt_dev_warn_ratelimited(conn->hcon->hdev, 2500600a8749SAlain Michaud "LTK blocked for %pMR", 2501600a8749SAlain Michaud &conn->hcon->dst); 2502600a8749SAlain Michaud return SMP_INVALID_PARAMS; 2503600a8749SAlain Michaud } 2504600a8749SAlain Michaud 2505b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_MASTER_IDENT); 25066131ddc8SJohan Hedberg 250716b90839SVinicius Costa Gomes skb_pull(skb, sizeof(*rp)); 250816b90839SVinicius Costa Gomes 25091c1def09SVinicius Costa Gomes memcpy(smp->tk, rp->ltk, sizeof(smp->tk)); 251016b90839SVinicius Costa Gomes 25117034b911SVinicius Costa Gomes return 0; 25127034b911SVinicius Costa Gomes } 25137034b911SVinicius Costa Gomes 25147034b911SVinicius Costa Gomes static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb) 25157034b911SVinicius Costa Gomes { 251616b90839SVinicius Costa Gomes struct smp_cmd_master_ident *rp = (void *) skb->data; 25175d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 25185d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 2519c9839a11SVinicius Costa Gomes struct hci_dev *hdev = conn->hcon->hdev; 2520c9839a11SVinicius Costa Gomes struct hci_conn *hcon = conn->hcon; 252123d0e128SJohan Hedberg struct smp_ltk *ltk; 2522c9839a11SVinicius Costa Gomes u8 authenticated; 25237034b911SVinicius Costa Gomes 2524c46b98beSJohan Hedberg BT_DBG("conn %p", conn); 2525c46b98beSJohan Hedberg 2526c46b98beSJohan Hedberg if (skb->len < sizeof(*rp)) 252738e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 2528c46b98beSJohan Hedberg 25299747a9f3SJohan Hedberg /* Mark the information as received */ 25309747a9f3SJohan Hedberg smp->remote_key_dist &= ~SMP_DIST_ENC_KEY; 25319747a9f3SJohan Hedberg 2532b28b4943SJohan Hedberg if (smp->remote_key_dist & SMP_DIST_ID_KEY) 2533b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO); 2534196332f5SJohan Hedberg else if (smp->remote_key_dist & SMP_DIST_SIGN) 2535196332f5SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO); 2536b28b4943SJohan Hedberg 253716b90839SVinicius Costa Gomes skb_pull(skb, sizeof(*rp)); 253816b90839SVinicius Costa Gomes 2539ce39fb4eSMarcel Holtmann authenticated = (hcon->sec_level == BT_SECURITY_HIGH); 25402ceba539SJohan Hedberg ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, SMP_LTK, 2541ce39fb4eSMarcel Holtmann authenticated, smp->tk, smp->enc_key_size, 254204124681SGustavo F. Padovan rp->ediv, rp->rand); 254323d0e128SJohan Hedberg smp->ltk = ltk; 2544c6e81e9aSJohan Hedberg if (!(smp->remote_key_dist & KEY_DIST_MASK)) 2545d6268e86SJohan Hedberg smp_distribute_keys(smp); 25467034b911SVinicius Costa Gomes 25477034b911SVinicius Costa Gomes return 0; 25487034b911SVinicius Costa Gomes } 25497034b911SVinicius Costa Gomes 2550fd349c02SJohan Hedberg static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb) 2551fd349c02SJohan Hedberg { 2552fd349c02SJohan Hedberg struct smp_cmd_ident_info *info = (void *) skb->data; 25535d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 25545d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 2555fd349c02SJohan Hedberg 2556fd349c02SJohan Hedberg BT_DBG(""); 2557fd349c02SJohan Hedberg 2558fd349c02SJohan Hedberg if (skb->len < sizeof(*info)) 255938e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 2560fd349c02SJohan Hedberg 2561600a8749SAlain Michaud /* Pairing is aborted if any blocked keys are distributed */ 2562600a8749SAlain Michaud if (hci_is_blocked_key(conn->hcon->hdev, HCI_BLOCKED_KEY_TYPE_IRK, 2563600a8749SAlain Michaud info->irk)) { 2564600a8749SAlain Michaud bt_dev_warn_ratelimited(conn->hcon->hdev, 2565600a8749SAlain Michaud "Identity key blocked for %pMR", 2566600a8749SAlain Michaud &conn->hcon->dst); 2567600a8749SAlain Michaud return SMP_INVALID_PARAMS; 2568600a8749SAlain Michaud } 2569600a8749SAlain Michaud 2570b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_ADDR_INFO); 25716131ddc8SJohan Hedberg 2572fd349c02SJohan Hedberg skb_pull(skb, sizeof(*info)); 2573fd349c02SJohan Hedberg 2574fd349c02SJohan Hedberg memcpy(smp->irk, info->irk, 16); 2575fd349c02SJohan Hedberg 2576fd349c02SJohan Hedberg return 0; 2577fd349c02SJohan Hedberg } 2578fd349c02SJohan Hedberg 2579fd349c02SJohan Hedberg static int smp_cmd_ident_addr_info(struct l2cap_conn *conn, 2580fd349c02SJohan Hedberg struct sk_buff *skb) 2581fd349c02SJohan Hedberg { 2582fd349c02SJohan Hedberg struct smp_cmd_ident_addr_info *info = (void *) skb->data; 25835d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 25845d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 2585fd349c02SJohan Hedberg struct hci_conn *hcon = conn->hcon; 2586fd349c02SJohan Hedberg bdaddr_t rpa; 2587fd349c02SJohan Hedberg 2588fd349c02SJohan Hedberg BT_DBG(""); 2589fd349c02SJohan Hedberg 2590fd349c02SJohan Hedberg if (skb->len < sizeof(*info)) 259138e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 2592fd349c02SJohan Hedberg 25939747a9f3SJohan Hedberg /* Mark the information as received */ 25949747a9f3SJohan Hedberg smp->remote_key_dist &= ~SMP_DIST_ID_KEY; 25959747a9f3SJohan Hedberg 2596b28b4943SJohan Hedberg if (smp->remote_key_dist & SMP_DIST_SIGN) 2597b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO); 2598b28b4943SJohan Hedberg 2599fd349c02SJohan Hedberg skb_pull(skb, sizeof(*info)); 2600fd349c02SJohan Hedberg 2601a9a58f86SJohan Hedberg /* Strictly speaking the Core Specification (4.1) allows sending 2602a9a58f86SJohan Hedberg * an empty address which would force us to rely on just the IRK 2603a9a58f86SJohan Hedberg * as "identity information". However, since such 2604a9a58f86SJohan Hedberg * implementations are not known of and in order to not over 2605a9a58f86SJohan Hedberg * complicate our implementation, simply pretend that we never 2606a9a58f86SJohan Hedberg * received an IRK for such a device. 2607e12af489SJohan Hedberg * 2608e12af489SJohan Hedberg * The Identity Address must also be a Static Random or Public 2609e12af489SJohan Hedberg * Address, which hci_is_identity_address() checks for. 2610a9a58f86SJohan Hedberg */ 2611e12af489SJohan Hedberg if (!bacmp(&info->bdaddr, BDADDR_ANY) || 2612e12af489SJohan Hedberg !hci_is_identity_address(&info->bdaddr, info->addr_type)) { 26132064ee33SMarcel Holtmann bt_dev_err(hcon->hdev, "ignoring IRK with no identity address"); 261431dd624eSJohan Hedberg goto distribute; 2615a9a58f86SJohan Hedberg } 2616a9a58f86SJohan Hedberg 26171d87b88bSSzymon Janc /* Drop IRK if peer is using identity address during pairing but is 26181d87b88bSSzymon Janc * providing different address as identity information. 26191d87b88bSSzymon Janc * 26201d87b88bSSzymon Janc * Microsoft Surface Precision Mouse is known to have this bug. 26211d87b88bSSzymon Janc */ 26221d87b88bSSzymon Janc if (hci_is_identity_address(&hcon->dst, hcon->dst_type) && 26231d87b88bSSzymon Janc (bacmp(&info->bdaddr, &hcon->dst) || 26241d87b88bSSzymon Janc info->addr_type != hcon->dst_type)) { 26251d87b88bSSzymon Janc bt_dev_err(hcon->hdev, 26261d87b88bSSzymon Janc "ignoring IRK with invalid identity address"); 26271d87b88bSSzymon Janc goto distribute; 26281d87b88bSSzymon Janc } 26291d87b88bSSzymon Janc 2630fd349c02SJohan Hedberg bacpy(&smp->id_addr, &info->bdaddr); 2631fd349c02SJohan Hedberg smp->id_addr_type = info->addr_type; 2632fd349c02SJohan Hedberg 2633fd349c02SJohan Hedberg if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type)) 2634fd349c02SJohan Hedberg bacpy(&rpa, &hcon->dst); 2635fd349c02SJohan Hedberg else 2636fd349c02SJohan Hedberg bacpy(&rpa, BDADDR_ANY); 2637fd349c02SJohan Hedberg 263823d0e128SJohan Hedberg smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr, 263923d0e128SJohan Hedberg smp->id_addr_type, smp->irk, &rpa); 2640fd349c02SJohan Hedberg 264131dd624eSJohan Hedberg distribute: 2642c6e81e9aSJohan Hedberg if (!(smp->remote_key_dist & KEY_DIST_MASK)) 2643d6268e86SJohan Hedberg smp_distribute_keys(smp); 2644fd349c02SJohan Hedberg 2645fd349c02SJohan Hedberg return 0; 2646fd349c02SJohan Hedberg } 2647fd349c02SJohan Hedberg 26487ee4ea36SMarcel Holtmann static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb) 26497ee4ea36SMarcel Holtmann { 26507ee4ea36SMarcel Holtmann struct smp_cmd_sign_info *rp = (void *) skb->data; 26515d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 26525d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 26537ee4ea36SMarcel Holtmann struct smp_csrk *csrk; 26547ee4ea36SMarcel Holtmann 26557ee4ea36SMarcel Holtmann BT_DBG("conn %p", conn); 26567ee4ea36SMarcel Holtmann 26577ee4ea36SMarcel Holtmann if (skb->len < sizeof(*rp)) 265838e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 26597ee4ea36SMarcel Holtmann 26607ee4ea36SMarcel Holtmann /* Mark the information as received */ 26617ee4ea36SMarcel Holtmann smp->remote_key_dist &= ~SMP_DIST_SIGN; 26627ee4ea36SMarcel Holtmann 26637ee4ea36SMarcel Holtmann skb_pull(skb, sizeof(*rp)); 26647ee4ea36SMarcel Holtmann 26657ee4ea36SMarcel Holtmann csrk = kzalloc(sizeof(*csrk), GFP_KERNEL); 26667ee4ea36SMarcel Holtmann if (csrk) { 26674cd3928aSJohan Hedberg if (conn->hcon->sec_level > BT_SECURITY_MEDIUM) 26684cd3928aSJohan Hedberg csrk->type = MGMT_CSRK_REMOTE_AUTHENTICATED; 26694cd3928aSJohan Hedberg else 26704cd3928aSJohan Hedberg csrk->type = MGMT_CSRK_REMOTE_UNAUTHENTICATED; 26717ee4ea36SMarcel Holtmann memcpy(csrk->val, rp->csrk, sizeof(csrk->val)); 26727ee4ea36SMarcel Holtmann } 26737ee4ea36SMarcel Holtmann smp->csrk = csrk; 2674d6268e86SJohan Hedberg smp_distribute_keys(smp); 26757ee4ea36SMarcel Holtmann 26767ee4ea36SMarcel Holtmann return 0; 26777ee4ea36SMarcel Holtmann } 26787ee4ea36SMarcel Holtmann 26795e3d3d9bSJohan Hedberg static u8 sc_select_method(struct smp_chan *smp) 26805e3d3d9bSJohan Hedberg { 26815e3d3d9bSJohan Hedberg struct l2cap_conn *conn = smp->conn; 26825e3d3d9bSJohan Hedberg struct hci_conn *hcon = conn->hcon; 26835e3d3d9bSJohan Hedberg struct smp_cmd_pairing *local, *remote; 26845e3d3d9bSJohan Hedberg u8 local_mitm, remote_mitm, local_io, remote_io, method; 26855e3d3d9bSJohan Hedberg 26861a8bab4fSJohan Hedberg if (test_bit(SMP_FLAG_REMOTE_OOB, &smp->flags) || 26871a8bab4fSJohan Hedberg test_bit(SMP_FLAG_LOCAL_OOB, &smp->flags)) 2688a29b0733SJohan Hedberg return REQ_OOB; 2689a29b0733SJohan Hedberg 26905e3d3d9bSJohan Hedberg /* The preq/prsp contain the raw Pairing Request/Response PDUs 26915e3d3d9bSJohan Hedberg * which are needed as inputs to some crypto functions. To get 26925e3d3d9bSJohan Hedberg * the "struct smp_cmd_pairing" from them we need to skip the 26935e3d3d9bSJohan Hedberg * first byte which contains the opcode. 26945e3d3d9bSJohan Hedberg */ 26955e3d3d9bSJohan Hedberg if (hcon->out) { 26965e3d3d9bSJohan Hedberg local = (void *) &smp->preq[1]; 26975e3d3d9bSJohan Hedberg remote = (void *) &smp->prsp[1]; 26985e3d3d9bSJohan Hedberg } else { 26995e3d3d9bSJohan Hedberg local = (void *) &smp->prsp[1]; 27005e3d3d9bSJohan Hedberg remote = (void *) &smp->preq[1]; 27015e3d3d9bSJohan Hedberg } 27025e3d3d9bSJohan Hedberg 27035e3d3d9bSJohan Hedberg local_io = local->io_capability; 27045e3d3d9bSJohan Hedberg remote_io = remote->io_capability; 27055e3d3d9bSJohan Hedberg 27065e3d3d9bSJohan Hedberg local_mitm = (local->auth_req & SMP_AUTH_MITM); 27075e3d3d9bSJohan Hedberg remote_mitm = (remote->auth_req & SMP_AUTH_MITM); 27085e3d3d9bSJohan Hedberg 27095e3d3d9bSJohan Hedberg /* If either side wants MITM, look up the method from the table, 27105e3d3d9bSJohan Hedberg * otherwise use JUST WORKS. 27115e3d3d9bSJohan Hedberg */ 27125e3d3d9bSJohan Hedberg if (local_mitm || remote_mitm) 27135e3d3d9bSJohan Hedberg method = get_auth_method(smp, local_io, remote_io); 27145e3d3d9bSJohan Hedberg else 27155e3d3d9bSJohan Hedberg method = JUST_WORKS; 27165e3d3d9bSJohan Hedberg 27175e3d3d9bSJohan Hedberg /* Don't confirm locally initiated pairing attempts */ 27185e3d3d9bSJohan Hedberg if (method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR, &smp->flags)) 27195e3d3d9bSJohan Hedberg method = JUST_WORKS; 27205e3d3d9bSJohan Hedberg 27215e3d3d9bSJohan Hedberg return method; 27225e3d3d9bSJohan Hedberg } 27235e3d3d9bSJohan Hedberg 2724d8f8edbeSJohan Hedberg static int smp_cmd_public_key(struct l2cap_conn *conn, struct sk_buff *skb) 2725d8f8edbeSJohan Hedberg { 2726d8f8edbeSJohan Hedberg struct smp_cmd_public_key *key = (void *) skb->data; 2727d8f8edbeSJohan Hedberg struct hci_conn *hcon = conn->hcon; 2728d8f8edbeSJohan Hedberg struct l2cap_chan *chan = conn->smp; 2729d8f8edbeSJohan Hedberg struct smp_chan *smp = chan->data; 27305e3d3d9bSJohan Hedberg struct hci_dev *hdev = hcon->hdev; 2731c0153b0bSTudor Ambarus struct crypto_kpp *tfm_ecdh; 2732cbbbe3e2SJohan Hedberg struct smp_cmd_pairing_confirm cfm; 2733d8f8edbeSJohan Hedberg int err; 2734d8f8edbeSJohan Hedberg 2735d8f8edbeSJohan Hedberg BT_DBG("conn %p", conn); 2736d8f8edbeSJohan Hedberg 2737d8f8edbeSJohan Hedberg if (skb->len < sizeof(*key)) 2738d8f8edbeSJohan Hedberg return SMP_INVALID_PARAMS; 2739d8f8edbeSJohan Hedberg 2740d8f8edbeSJohan Hedberg memcpy(smp->remote_pk, key, 64); 2741d8f8edbeSJohan Hedberg 2742a8ca617cSJohan Hedberg if (test_bit(SMP_FLAG_REMOTE_OOB, &smp->flags)) { 2743a8ca617cSJohan Hedberg err = smp_f4(smp->tfm_cmac, smp->remote_pk, smp->remote_pk, 2744a8ca617cSJohan Hedberg smp->rr, 0, cfm.confirm_val); 2745a8ca617cSJohan Hedberg if (err) 2746a8ca617cSJohan Hedberg return SMP_UNSPECIFIED; 2747a8ca617cSJohan Hedberg 2748329d8230SJason A. Donenfeld if (crypto_memneq(cfm.confirm_val, smp->pcnf, 16)) 2749a8ca617cSJohan Hedberg return SMP_CONFIRM_FAILED; 2750a8ca617cSJohan Hedberg } 2751a8ca617cSJohan Hedberg 2752d8f8edbeSJohan Hedberg /* Non-initiating device sends its public key after receiving 2753d8f8edbeSJohan Hedberg * the key from the initiating device. 2754d8f8edbeSJohan Hedberg */ 2755d8f8edbeSJohan Hedberg if (!hcon->out) { 2756d8f8edbeSJohan Hedberg err = sc_send_public_key(smp); 2757d8f8edbeSJohan Hedberg if (err) 2758d8f8edbeSJohan Hedberg return err; 2759d8f8edbeSJohan Hedberg } 2760d8f8edbeSJohan Hedberg 2761c7a3d57dSJohan Hedberg SMP_DBG("Remote Public Key X: %32phN", smp->remote_pk); 2762e091526dSMarcel Holtmann SMP_DBG("Remote Public Key Y: %32phN", smp->remote_pk + 32); 2763d8f8edbeSJohan Hedberg 2764c0153b0bSTudor Ambarus /* Compute the shared secret on the same crypto tfm on which the private 2765c0153b0bSTudor Ambarus * key was set/generated. 2766c0153b0bSTudor Ambarus */ 2767c0153b0bSTudor Ambarus if (test_bit(SMP_FLAG_LOCAL_OOB, &smp->flags)) { 27684ba5175fSMatias Karhumaa struct l2cap_chan *hchan = hdev->smp_data; 27694ba5175fSMatias Karhumaa struct smp_dev *smp_dev; 27704ba5175fSMatias Karhumaa 27714ba5175fSMatias Karhumaa if (!hchan || !hchan->data) 27724ba5175fSMatias Karhumaa return SMP_UNSPECIFIED; 27734ba5175fSMatias Karhumaa 27744ba5175fSMatias Karhumaa smp_dev = hchan->data; 2775c0153b0bSTudor Ambarus 2776c0153b0bSTudor Ambarus tfm_ecdh = smp_dev->tfm_ecdh; 2777c0153b0bSTudor Ambarus } else { 2778c0153b0bSTudor Ambarus tfm_ecdh = smp->tfm_ecdh; 2779c0153b0bSTudor Ambarus } 2780c0153b0bSTudor Ambarus 2781c0153b0bSTudor Ambarus if (compute_ecdh_secret(tfm_ecdh, smp->remote_pk, smp->dhkey)) 2782d8f8edbeSJohan Hedberg return SMP_UNSPECIFIED; 2783d8f8edbeSJohan Hedberg 2784c7a3d57dSJohan Hedberg SMP_DBG("DHKey %32phN", smp->dhkey); 2785d8f8edbeSJohan Hedberg 2786d8f8edbeSJohan Hedberg set_bit(SMP_FLAG_REMOTE_PK, &smp->flags); 2787d8f8edbeSJohan Hedberg 27885e3d3d9bSJohan Hedberg smp->method = sc_select_method(smp); 27895e3d3d9bSJohan Hedberg 27905e3d3d9bSJohan Hedberg BT_DBG("%s selected method 0x%02x", hdev->name, smp->method); 27915e3d3d9bSJohan Hedberg 27925e3d3d9bSJohan Hedberg /* JUST_WORKS and JUST_CFM result in an unauthenticated key */ 27935e3d3d9bSJohan Hedberg if (smp->method == JUST_WORKS || smp->method == JUST_CFM) 27945e3d3d9bSJohan Hedberg hcon->pending_sec_level = BT_SECURITY_MEDIUM; 27955e3d3d9bSJohan Hedberg else 27965e3d3d9bSJohan Hedberg hcon->pending_sec_level = BT_SECURITY_FIPS; 27975e3d3d9bSJohan Hedberg 2798329d8230SJason A. Donenfeld if (!crypto_memneq(debug_pk, smp->remote_pk, 64)) 2799aeb7d461SJohan Hedberg set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags); 2800aeb7d461SJohan Hedberg 280138606f14SJohan Hedberg if (smp->method == DSP_PASSKEY) { 280238606f14SJohan Hedberg get_random_bytes(&hcon->passkey_notify, 280338606f14SJohan Hedberg sizeof(hcon->passkey_notify)); 280438606f14SJohan Hedberg hcon->passkey_notify %= 1000000; 280538606f14SJohan Hedberg hcon->passkey_entered = 0; 280638606f14SJohan Hedberg smp->passkey_round = 0; 280738606f14SJohan Hedberg if (mgmt_user_passkey_notify(hdev, &hcon->dst, hcon->type, 280838606f14SJohan Hedberg hcon->dst_type, 280938606f14SJohan Hedberg hcon->passkey_notify, 281038606f14SJohan Hedberg hcon->passkey_entered)) 281138606f14SJohan Hedberg return SMP_UNSPECIFIED; 281238606f14SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); 281338606f14SJohan Hedberg return sc_passkey_round(smp, SMP_CMD_PUBLIC_KEY); 281438606f14SJohan Hedberg } 281538606f14SJohan Hedberg 281694ea7257SJohan Hedberg if (smp->method == REQ_OOB) { 2817a29b0733SJohan Hedberg if (hcon->out) 2818a29b0733SJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, 2819a29b0733SJohan Hedberg sizeof(smp->prnd), smp->prnd); 2820a29b0733SJohan Hedberg 2821a29b0733SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM); 2822a29b0733SJohan Hedberg 2823a29b0733SJohan Hedberg return 0; 2824a29b0733SJohan Hedberg } 2825a29b0733SJohan Hedberg 282638606f14SJohan Hedberg if (hcon->out) 282738606f14SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); 282838606f14SJohan Hedberg 282938606f14SJohan Hedberg if (smp->method == REQ_PASSKEY) { 283038606f14SJohan Hedberg if (mgmt_user_passkey_request(hdev, &hcon->dst, hcon->type, 283138606f14SJohan Hedberg hcon->dst_type)) 283238606f14SJohan Hedberg return SMP_UNSPECIFIED; 283338606f14SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); 283438606f14SJohan Hedberg set_bit(SMP_FLAG_WAIT_USER, &smp->flags); 283538606f14SJohan Hedberg return 0; 283638606f14SJohan Hedberg } 283738606f14SJohan Hedberg 2838cbbbe3e2SJohan Hedberg /* The Initiating device waits for the non-initiating device to 2839cbbbe3e2SJohan Hedberg * send the confirm value. 2840cbbbe3e2SJohan Hedberg */ 2841cbbbe3e2SJohan Hedberg if (conn->hcon->out) 2842cbbbe3e2SJohan Hedberg return 0; 2843cbbbe3e2SJohan Hedberg 2844cbbbe3e2SJohan Hedberg err = smp_f4(smp->tfm_cmac, smp->local_pk, smp->remote_pk, smp->prnd, 2845cbbbe3e2SJohan Hedberg 0, cfm.confirm_val); 2846cbbbe3e2SJohan Hedberg if (err) 2847cbbbe3e2SJohan Hedberg return SMP_UNSPECIFIED; 2848cbbbe3e2SJohan Hedberg 2849cbbbe3e2SJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cfm), &cfm); 2850cbbbe3e2SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM); 2851cbbbe3e2SJohan Hedberg 2852d8f8edbeSJohan Hedberg return 0; 2853d8f8edbeSJohan Hedberg } 2854d8f8edbeSJohan Hedberg 28556433a9a2SJohan Hedberg static int smp_cmd_dhkey_check(struct l2cap_conn *conn, struct sk_buff *skb) 28566433a9a2SJohan Hedberg { 28576433a9a2SJohan Hedberg struct smp_cmd_dhkey_check *check = (void *) skb->data; 28586433a9a2SJohan Hedberg struct l2cap_chan *chan = conn->smp; 28596433a9a2SJohan Hedberg struct hci_conn *hcon = conn->hcon; 28606433a9a2SJohan Hedberg struct smp_chan *smp = chan->data; 28616433a9a2SJohan Hedberg u8 a[7], b[7], *local_addr, *remote_addr; 28626433a9a2SJohan Hedberg u8 io_cap[3], r[16], e[16]; 28636433a9a2SJohan Hedberg int err; 28646433a9a2SJohan Hedberg 28656433a9a2SJohan Hedberg BT_DBG("conn %p", conn); 28666433a9a2SJohan Hedberg 28676433a9a2SJohan Hedberg if (skb->len < sizeof(*check)) 28686433a9a2SJohan Hedberg return SMP_INVALID_PARAMS; 28696433a9a2SJohan Hedberg 28706433a9a2SJohan Hedberg memcpy(a, &hcon->init_addr, 6); 28716433a9a2SJohan Hedberg memcpy(b, &hcon->resp_addr, 6); 28726433a9a2SJohan Hedberg a[6] = hcon->init_addr_type; 28736433a9a2SJohan Hedberg b[6] = hcon->resp_addr_type; 28746433a9a2SJohan Hedberg 28756433a9a2SJohan Hedberg if (hcon->out) { 28766433a9a2SJohan Hedberg local_addr = a; 28776433a9a2SJohan Hedberg remote_addr = b; 28786433a9a2SJohan Hedberg memcpy(io_cap, &smp->prsp[1], 3); 28796433a9a2SJohan Hedberg } else { 28806433a9a2SJohan Hedberg local_addr = b; 28816433a9a2SJohan Hedberg remote_addr = a; 28826433a9a2SJohan Hedberg memcpy(io_cap, &smp->preq[1], 3); 28836433a9a2SJohan Hedberg } 28846433a9a2SJohan Hedberg 28856433a9a2SJohan Hedberg memset(r, 0, sizeof(r)); 28866433a9a2SJohan Hedberg 288738606f14SJohan Hedberg if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY) 288838606f14SJohan Hedberg put_unaligned_le32(hcon->passkey_notify, r); 2889882fafadSJohan Hedberg else if (smp->method == REQ_OOB) 2890882fafadSJohan Hedberg memcpy(r, smp->lr, 16); 289138606f14SJohan Hedberg 28926433a9a2SJohan Hedberg err = smp_f6(smp->tfm_cmac, smp->mackey, smp->rrnd, smp->prnd, r, 28936433a9a2SJohan Hedberg io_cap, remote_addr, local_addr, e); 28946433a9a2SJohan Hedberg if (err) 28956433a9a2SJohan Hedberg return SMP_UNSPECIFIED; 28966433a9a2SJohan Hedberg 2897329d8230SJason A. Donenfeld if (crypto_memneq(check->e, e, 16)) 28986433a9a2SJohan Hedberg return SMP_DHKEY_CHECK_FAILED; 28996433a9a2SJohan Hedberg 2900d3e54a87SJohan Hedberg if (!hcon->out) { 2901d3e54a87SJohan Hedberg if (test_bit(SMP_FLAG_WAIT_USER, &smp->flags)) { 2902d3e54a87SJohan Hedberg set_bit(SMP_FLAG_DHKEY_PENDING, &smp->flags); 2903d3e54a87SJohan Hedberg return 0; 2904d3e54a87SJohan Hedberg } 2905d378a2d7SJohan Hedberg 2906d3e54a87SJohan Hedberg /* Slave sends DHKey check as response to master */ 2907d3e54a87SJohan Hedberg sc_dhkey_check(smp); 2908d3e54a87SJohan Hedberg } 2909d378a2d7SJohan Hedberg 2910d3e54a87SJohan Hedberg sc_add_ltk(smp); 29116433a9a2SJohan Hedberg 29126433a9a2SJohan Hedberg if (hcon->out) { 29138b76ce34SJohan Hedberg hci_le_start_enc(hcon, 0, 0, smp->tk, smp->enc_key_size); 29146433a9a2SJohan Hedberg hcon->enc_key_size = smp->enc_key_size; 29156433a9a2SJohan Hedberg } 29166433a9a2SJohan Hedberg 29176433a9a2SJohan Hedberg return 0; 29186433a9a2SJohan Hedberg } 29196433a9a2SJohan Hedberg 29201408bb6eSJohan Hedberg static int smp_cmd_keypress_notify(struct l2cap_conn *conn, 29211408bb6eSJohan Hedberg struct sk_buff *skb) 29221408bb6eSJohan Hedberg { 29231408bb6eSJohan Hedberg struct smp_cmd_keypress_notify *kp = (void *) skb->data; 29241408bb6eSJohan Hedberg 29251408bb6eSJohan Hedberg BT_DBG("value 0x%02x", kp->value); 29261408bb6eSJohan Hedberg 29271408bb6eSJohan Hedberg return 0; 29281408bb6eSJohan Hedberg } 29291408bb6eSJohan Hedberg 29304befb867SJohan Hedberg static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb) 2931eb492e01SAnderson Briglia { 29325d88cc73SJohan Hedberg struct l2cap_conn *conn = chan->conn; 29337b9899dbSMarcel Holtmann struct hci_conn *hcon = conn->hcon; 2934b28b4943SJohan Hedberg struct smp_chan *smp; 293592381f5cSMarcel Holtmann __u8 code, reason; 2936eb492e01SAnderson Briglia int err = 0; 2937eb492e01SAnderson Briglia 29388ae9b984SJohan Hedberg if (skb->len < 1) 293992381f5cSMarcel Holtmann return -EILSEQ; 294092381f5cSMarcel Holtmann 2941d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hcon->hdev, HCI_LE_ENABLED)) { 29422e65c9d2SAndre Guedes reason = SMP_PAIRING_NOTSUPP; 29432e65c9d2SAndre Guedes goto done; 29442e65c9d2SAndre Guedes } 29452e65c9d2SAndre Guedes 294692381f5cSMarcel Holtmann code = skb->data[0]; 2947eb492e01SAnderson Briglia skb_pull(skb, sizeof(code)); 2948eb492e01SAnderson Briglia 2949b28b4943SJohan Hedberg smp = chan->data; 2950b28b4943SJohan Hedberg 2951b28b4943SJohan Hedberg if (code > SMP_CMD_MAX) 2952b28b4943SJohan Hedberg goto drop; 2953b28b4943SJohan Hedberg 295424bd0bd9SJohan Hedberg if (smp && !test_and_clear_bit(code, &smp->allow_cmd)) 2955b28b4943SJohan Hedberg goto drop; 2956b28b4943SJohan Hedberg 2957b28b4943SJohan Hedberg /* If we don't have a context the only allowed commands are 2958b28b4943SJohan Hedberg * pairing request and security request. 29598cf9fa12SJohan Hedberg */ 2960b28b4943SJohan Hedberg if (!smp && code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ) 2961b28b4943SJohan Hedberg goto drop; 29628cf9fa12SJohan Hedberg 2963eb492e01SAnderson Briglia switch (code) { 2964eb492e01SAnderson Briglia case SMP_CMD_PAIRING_REQ: 2965da85e5e5SVinicius Costa Gomes reason = smp_cmd_pairing_req(conn, skb); 2966eb492e01SAnderson Briglia break; 2967eb492e01SAnderson Briglia 2968eb492e01SAnderson Briglia case SMP_CMD_PAIRING_FAIL: 296984794e11SJohan Hedberg smp_failure(conn, 0); 2970da85e5e5SVinicius Costa Gomes err = -EPERM; 2971eb492e01SAnderson Briglia break; 2972eb492e01SAnderson Briglia 2973eb492e01SAnderson Briglia case SMP_CMD_PAIRING_RSP: 2974da85e5e5SVinicius Costa Gomes reason = smp_cmd_pairing_rsp(conn, skb); 297588ba43b6SAnderson Briglia break; 297688ba43b6SAnderson Briglia 297788ba43b6SAnderson Briglia case SMP_CMD_SECURITY_REQ: 2978da85e5e5SVinicius Costa Gomes reason = smp_cmd_security_req(conn, skb); 297988ba43b6SAnderson Briglia break; 298088ba43b6SAnderson Briglia 2981eb492e01SAnderson Briglia case SMP_CMD_PAIRING_CONFIRM: 2982da85e5e5SVinicius Costa Gomes reason = smp_cmd_pairing_confirm(conn, skb); 298388ba43b6SAnderson Briglia break; 298488ba43b6SAnderson Briglia 2985eb492e01SAnderson Briglia case SMP_CMD_PAIRING_RANDOM: 2986da85e5e5SVinicius Costa Gomes reason = smp_cmd_pairing_random(conn, skb); 298788ba43b6SAnderson Briglia break; 298888ba43b6SAnderson Briglia 2989eb492e01SAnderson Briglia case SMP_CMD_ENCRYPT_INFO: 29907034b911SVinicius Costa Gomes reason = smp_cmd_encrypt_info(conn, skb); 29917034b911SVinicius Costa Gomes break; 29927034b911SVinicius Costa Gomes 2993eb492e01SAnderson Briglia case SMP_CMD_MASTER_IDENT: 29947034b911SVinicius Costa Gomes reason = smp_cmd_master_ident(conn, skb); 29957034b911SVinicius Costa Gomes break; 29967034b911SVinicius Costa Gomes 2997eb492e01SAnderson Briglia case SMP_CMD_IDENT_INFO: 2998fd349c02SJohan Hedberg reason = smp_cmd_ident_info(conn, skb); 2999fd349c02SJohan Hedberg break; 3000fd349c02SJohan Hedberg 3001eb492e01SAnderson Briglia case SMP_CMD_IDENT_ADDR_INFO: 3002fd349c02SJohan Hedberg reason = smp_cmd_ident_addr_info(conn, skb); 3003fd349c02SJohan Hedberg break; 3004fd349c02SJohan Hedberg 3005eb492e01SAnderson Briglia case SMP_CMD_SIGN_INFO: 30067ee4ea36SMarcel Holtmann reason = smp_cmd_sign_info(conn, skb); 30077034b911SVinicius Costa Gomes break; 30087034b911SVinicius Costa Gomes 3009d8f8edbeSJohan Hedberg case SMP_CMD_PUBLIC_KEY: 3010d8f8edbeSJohan Hedberg reason = smp_cmd_public_key(conn, skb); 3011d8f8edbeSJohan Hedberg break; 3012d8f8edbeSJohan Hedberg 30136433a9a2SJohan Hedberg case SMP_CMD_DHKEY_CHECK: 30146433a9a2SJohan Hedberg reason = smp_cmd_dhkey_check(conn, skb); 30156433a9a2SJohan Hedberg break; 30166433a9a2SJohan Hedberg 30171408bb6eSJohan Hedberg case SMP_CMD_KEYPRESS_NOTIFY: 30181408bb6eSJohan Hedberg reason = smp_cmd_keypress_notify(conn, skb); 30191408bb6eSJohan Hedberg break; 30201408bb6eSJohan Hedberg 3021eb492e01SAnderson Briglia default: 3022eb492e01SAnderson Briglia BT_DBG("Unknown command code 0x%2.2x", code); 3023eb492e01SAnderson Briglia reason = SMP_CMD_NOTSUPP; 30243a0259bbSVinicius Costa Gomes goto done; 30253a0259bbSVinicius Costa Gomes } 30263a0259bbSVinicius Costa Gomes 30273a0259bbSVinicius Costa Gomes done: 30289b7b18efSJohan Hedberg if (!err) { 30293a0259bbSVinicius Costa Gomes if (reason) 303084794e11SJohan Hedberg smp_failure(conn, reason); 3031eb492e01SAnderson Briglia kfree_skb(skb); 30329b7b18efSJohan Hedberg } 30339b7b18efSJohan Hedberg 3034eb492e01SAnderson Briglia return err; 3035b28b4943SJohan Hedberg 3036b28b4943SJohan Hedberg drop: 30372064ee33SMarcel Holtmann bt_dev_err(hcon->hdev, "unexpected SMP command 0x%02x from %pMR", 3038b28b4943SJohan Hedberg code, &hcon->dst); 3039b28b4943SJohan Hedberg kfree_skb(skb); 3040b28b4943SJohan Hedberg return 0; 3041eb492e01SAnderson Briglia } 30427034b911SVinicius Costa Gomes 304370db83c4SJohan Hedberg static void smp_teardown_cb(struct l2cap_chan *chan, int err) 304470db83c4SJohan Hedberg { 304570db83c4SJohan Hedberg struct l2cap_conn *conn = chan->conn; 304670db83c4SJohan Hedberg 304770db83c4SJohan Hedberg BT_DBG("chan %p", chan); 304870db83c4SJohan Hedberg 3049fc75cc86SJohan Hedberg if (chan->data) 30505d88cc73SJohan Hedberg smp_chan_destroy(conn); 30515d88cc73SJohan Hedberg 305270db83c4SJohan Hedberg conn->smp = NULL; 305370db83c4SJohan Hedberg l2cap_chan_put(chan); 305470db83c4SJohan Hedberg } 305570db83c4SJohan Hedberg 3056b5ae344dSJohan Hedberg static void bredr_pairing(struct l2cap_chan *chan) 3057b5ae344dSJohan Hedberg { 3058b5ae344dSJohan Hedberg struct l2cap_conn *conn = chan->conn; 3059b5ae344dSJohan Hedberg struct hci_conn *hcon = conn->hcon; 3060b5ae344dSJohan Hedberg struct hci_dev *hdev = hcon->hdev; 3061b5ae344dSJohan Hedberg struct smp_cmd_pairing req; 3062b5ae344dSJohan Hedberg struct smp_chan *smp; 3063b5ae344dSJohan Hedberg 3064b5ae344dSJohan Hedberg BT_DBG("chan %p", chan); 3065b5ae344dSJohan Hedberg 3066b5ae344dSJohan Hedberg /* Only new pairings are interesting */ 3067b5ae344dSJohan Hedberg if (!test_bit(HCI_CONN_NEW_LINK_KEY, &hcon->flags)) 3068b5ae344dSJohan Hedberg return; 3069b5ae344dSJohan Hedberg 3070b5ae344dSJohan Hedberg /* Don't bother if we're not encrypted */ 3071b5ae344dSJohan Hedberg if (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags)) 3072b5ae344dSJohan Hedberg return; 3073b5ae344dSJohan Hedberg 3074b5ae344dSJohan Hedberg /* Only master may initiate SMP over BR/EDR */ 3075b5ae344dSJohan Hedberg if (hcon->role != HCI_ROLE_MASTER) 3076b5ae344dSJohan Hedberg return; 3077b5ae344dSJohan Hedberg 3078b5ae344dSJohan Hedberg /* Secure Connections support must be enabled */ 3079d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_SC_ENABLED)) 3080b5ae344dSJohan Hedberg return; 3081b5ae344dSJohan Hedberg 3082b5ae344dSJohan Hedberg /* BR/EDR must use Secure Connections for SMP */ 3083b5ae344dSJohan Hedberg if (!test_bit(HCI_CONN_AES_CCM, &hcon->flags) && 3084b7cb93e5SMarcel Holtmann !hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP)) 3085b5ae344dSJohan Hedberg return; 3086b5ae344dSJohan Hedberg 3087b5ae344dSJohan Hedberg /* If our LE support is not enabled don't do anything */ 3088d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED)) 3089b5ae344dSJohan Hedberg return; 3090b5ae344dSJohan Hedberg 3091b5ae344dSJohan Hedberg /* Don't bother if remote LE support is not enabled */ 3092b5ae344dSJohan Hedberg if (!lmp_host_le_capable(hcon)) 3093b5ae344dSJohan Hedberg return; 3094b5ae344dSJohan Hedberg 3095b5ae344dSJohan Hedberg /* Remote must support SMP fixed chan for BR/EDR */ 3096b5ae344dSJohan Hedberg if (!(conn->remote_fixed_chan & L2CAP_FC_SMP_BREDR)) 3097b5ae344dSJohan Hedberg return; 3098b5ae344dSJohan Hedberg 3099b5ae344dSJohan Hedberg /* Don't bother if SMP is already ongoing */ 3100b5ae344dSJohan Hedberg if (chan->data) 3101b5ae344dSJohan Hedberg return; 3102b5ae344dSJohan Hedberg 3103b5ae344dSJohan Hedberg smp = smp_chan_create(conn); 3104b5ae344dSJohan Hedberg if (!smp) { 31052064ee33SMarcel Holtmann bt_dev_err(hdev, "unable to create SMP context for BR/EDR"); 3106b5ae344dSJohan Hedberg return; 3107b5ae344dSJohan Hedberg } 3108b5ae344dSJohan Hedberg 3109b5ae344dSJohan Hedberg set_bit(SMP_FLAG_SC, &smp->flags); 3110b5ae344dSJohan Hedberg 3111b5ae344dSJohan Hedberg BT_DBG("%s starting SMP over BR/EDR", hdev->name); 3112b5ae344dSJohan Hedberg 3113b5ae344dSJohan Hedberg /* Prepare and send the BR/EDR SMP Pairing Request */ 3114b5ae344dSJohan Hedberg build_bredr_pairing_cmd(smp, &req, NULL); 3115b5ae344dSJohan Hedberg 3116b5ae344dSJohan Hedberg smp->preq[0] = SMP_CMD_PAIRING_REQ; 3117b5ae344dSJohan Hedberg memcpy(&smp->preq[1], &req, sizeof(req)); 3118b5ae344dSJohan Hedberg 3119b5ae344dSJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(req), &req); 3120b5ae344dSJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP); 3121b5ae344dSJohan Hedberg } 3122b5ae344dSJohan Hedberg 312344f1a7abSJohan Hedberg static void smp_resume_cb(struct l2cap_chan *chan) 312444f1a7abSJohan Hedberg { 3125b68fda68SJohan Hedberg struct smp_chan *smp = chan->data; 312644f1a7abSJohan Hedberg struct l2cap_conn *conn = chan->conn; 312744f1a7abSJohan Hedberg struct hci_conn *hcon = conn->hcon; 312844f1a7abSJohan Hedberg 312944f1a7abSJohan Hedberg BT_DBG("chan %p", chan); 313044f1a7abSJohan Hedberg 3131b5ae344dSJohan Hedberg if (hcon->type == ACL_LINK) { 3132b5ae344dSJohan Hedberg bredr_pairing(chan); 3133ef8efe4bSJohan Hedberg return; 3134b5ae344dSJohan Hedberg } 3135ef8efe4bSJohan Hedberg 313686d1407cSJohan Hedberg if (!smp) 313786d1407cSJohan Hedberg return; 3138b68fda68SJohan Hedberg 313984bc0db5SJohan Hedberg if (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags)) 314084bc0db5SJohan Hedberg return; 314184bc0db5SJohan Hedberg 3142b68fda68SJohan Hedberg cancel_delayed_work(&smp->security_timer); 314386d1407cSJohan Hedberg 3144d6268e86SJohan Hedberg smp_distribute_keys(smp); 314544f1a7abSJohan Hedberg } 314644f1a7abSJohan Hedberg 314770db83c4SJohan Hedberg static void smp_ready_cb(struct l2cap_chan *chan) 314870db83c4SJohan Hedberg { 314970db83c4SJohan Hedberg struct l2cap_conn *conn = chan->conn; 3150b5ae344dSJohan Hedberg struct hci_conn *hcon = conn->hcon; 315170db83c4SJohan Hedberg 315270db83c4SJohan Hedberg BT_DBG("chan %p", chan); 315370db83c4SJohan Hedberg 31547883746bSJohan Hedberg /* No need to call l2cap_chan_hold() here since we already own 31557883746bSJohan Hedberg * the reference taken in smp_new_conn_cb(). This is just the 31567883746bSJohan Hedberg * first time that we tie it to a specific pointer. The code in 31577883746bSJohan Hedberg * l2cap_core.c ensures that there's no risk this function wont 31587883746bSJohan Hedberg * get called if smp_new_conn_cb was previously called. 31597883746bSJohan Hedberg */ 316070db83c4SJohan Hedberg conn->smp = chan; 3161b5ae344dSJohan Hedberg 3162b5ae344dSJohan Hedberg if (hcon->type == ACL_LINK && test_bit(HCI_CONN_ENCRYPT, &hcon->flags)) 3163b5ae344dSJohan Hedberg bredr_pairing(chan); 316470db83c4SJohan Hedberg } 316570db83c4SJohan Hedberg 31664befb867SJohan Hedberg static int smp_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) 31674befb867SJohan Hedberg { 31684befb867SJohan Hedberg int err; 31694befb867SJohan Hedberg 31704befb867SJohan Hedberg BT_DBG("chan %p", chan); 31714befb867SJohan Hedberg 31724befb867SJohan Hedberg err = smp_sig_channel(chan, skb); 31734befb867SJohan Hedberg if (err) { 3174b68fda68SJohan Hedberg struct smp_chan *smp = chan->data; 31754befb867SJohan Hedberg 3176b68fda68SJohan Hedberg if (smp) 3177b68fda68SJohan Hedberg cancel_delayed_work_sync(&smp->security_timer); 31784befb867SJohan Hedberg 31791e91c29eSJohan Hedberg hci_disconnect(chan->conn->hcon, HCI_ERROR_AUTH_FAILURE); 31804befb867SJohan Hedberg } 31814befb867SJohan Hedberg 31824befb867SJohan Hedberg return err; 31834befb867SJohan Hedberg } 31844befb867SJohan Hedberg 318570db83c4SJohan Hedberg static struct sk_buff *smp_alloc_skb_cb(struct l2cap_chan *chan, 318670db83c4SJohan Hedberg unsigned long hdr_len, 318770db83c4SJohan Hedberg unsigned long len, int nb) 318870db83c4SJohan Hedberg { 318970db83c4SJohan Hedberg struct sk_buff *skb; 319070db83c4SJohan Hedberg 319170db83c4SJohan Hedberg skb = bt_skb_alloc(hdr_len + len, GFP_KERNEL); 319270db83c4SJohan Hedberg if (!skb) 319370db83c4SJohan Hedberg return ERR_PTR(-ENOMEM); 319470db83c4SJohan Hedberg 319570db83c4SJohan Hedberg skb->priority = HCI_PRIO_MAX; 3196a4368ff3SJohan Hedberg bt_cb(skb)->l2cap.chan = chan; 319770db83c4SJohan Hedberg 319870db83c4SJohan Hedberg return skb; 319970db83c4SJohan Hedberg } 320070db83c4SJohan Hedberg 320170db83c4SJohan Hedberg static const struct l2cap_ops smp_chan_ops = { 320270db83c4SJohan Hedberg .name = "Security Manager", 320370db83c4SJohan Hedberg .ready = smp_ready_cb, 32045d88cc73SJohan Hedberg .recv = smp_recv_cb, 320570db83c4SJohan Hedberg .alloc_skb = smp_alloc_skb_cb, 320670db83c4SJohan Hedberg .teardown = smp_teardown_cb, 320744f1a7abSJohan Hedberg .resume = smp_resume_cb, 320870db83c4SJohan Hedberg 320970db83c4SJohan Hedberg .new_connection = l2cap_chan_no_new_connection, 321070db83c4SJohan Hedberg .state_change = l2cap_chan_no_state_change, 321170db83c4SJohan Hedberg .close = l2cap_chan_no_close, 321270db83c4SJohan Hedberg .defer = l2cap_chan_no_defer, 321370db83c4SJohan Hedberg .suspend = l2cap_chan_no_suspend, 321470db83c4SJohan Hedberg .set_shutdown = l2cap_chan_no_set_shutdown, 321570db83c4SJohan Hedberg .get_sndtimeo = l2cap_chan_no_get_sndtimeo, 321670db83c4SJohan Hedberg }; 321770db83c4SJohan Hedberg 321870db83c4SJohan Hedberg static inline struct l2cap_chan *smp_new_conn_cb(struct l2cap_chan *pchan) 321970db83c4SJohan Hedberg { 322070db83c4SJohan Hedberg struct l2cap_chan *chan; 322170db83c4SJohan Hedberg 322270db83c4SJohan Hedberg BT_DBG("pchan %p", pchan); 322370db83c4SJohan Hedberg 322470db83c4SJohan Hedberg chan = l2cap_chan_create(); 322570db83c4SJohan Hedberg if (!chan) 322670db83c4SJohan Hedberg return NULL; 322770db83c4SJohan Hedberg 322870db83c4SJohan Hedberg chan->chan_type = pchan->chan_type; 322970db83c4SJohan Hedberg chan->ops = &smp_chan_ops; 323070db83c4SJohan Hedberg chan->scid = pchan->scid; 323170db83c4SJohan Hedberg chan->dcid = chan->scid; 323270db83c4SJohan Hedberg chan->imtu = pchan->imtu; 323370db83c4SJohan Hedberg chan->omtu = pchan->omtu; 323470db83c4SJohan Hedberg chan->mode = pchan->mode; 323570db83c4SJohan Hedberg 3236abe84903SJohan Hedberg /* Other L2CAP channels may request SMP routines in order to 3237abe84903SJohan Hedberg * change the security level. This means that the SMP channel 3238abe84903SJohan Hedberg * lock must be considered in its own category to avoid lockdep 3239abe84903SJohan Hedberg * warnings. 3240abe84903SJohan Hedberg */ 3241abe84903SJohan Hedberg atomic_set(&chan->nesting, L2CAP_NESTING_SMP); 3242abe84903SJohan Hedberg 324370db83c4SJohan Hedberg BT_DBG("created chan %p", chan); 324470db83c4SJohan Hedberg 324570db83c4SJohan Hedberg return chan; 324670db83c4SJohan Hedberg } 324770db83c4SJohan Hedberg 324870db83c4SJohan Hedberg static const struct l2cap_ops smp_root_chan_ops = { 324970db83c4SJohan Hedberg .name = "Security Manager Root", 325070db83c4SJohan Hedberg .new_connection = smp_new_conn_cb, 325170db83c4SJohan Hedberg 325270db83c4SJohan Hedberg /* None of these are implemented for the root channel */ 325370db83c4SJohan Hedberg .close = l2cap_chan_no_close, 325470db83c4SJohan Hedberg .alloc_skb = l2cap_chan_no_alloc_skb, 325570db83c4SJohan Hedberg .recv = l2cap_chan_no_recv, 325670db83c4SJohan Hedberg .state_change = l2cap_chan_no_state_change, 325770db83c4SJohan Hedberg .teardown = l2cap_chan_no_teardown, 325870db83c4SJohan Hedberg .ready = l2cap_chan_no_ready, 325970db83c4SJohan Hedberg .defer = l2cap_chan_no_defer, 326070db83c4SJohan Hedberg .suspend = l2cap_chan_no_suspend, 326170db83c4SJohan Hedberg .resume = l2cap_chan_no_resume, 326270db83c4SJohan Hedberg .set_shutdown = l2cap_chan_no_set_shutdown, 326370db83c4SJohan Hedberg .get_sndtimeo = l2cap_chan_no_get_sndtimeo, 326470db83c4SJohan Hedberg }; 326570db83c4SJohan Hedberg 3266ef8efe4bSJohan Hedberg static struct l2cap_chan *smp_add_cid(struct hci_dev *hdev, u16 cid) 3267711eafe3SJohan Hedberg { 326870db83c4SJohan Hedberg struct l2cap_chan *chan; 326988a479d9SMarcel Holtmann struct smp_dev *smp; 327071af2f6bSHerbert Xu struct crypto_shash *tfm_cmac; 327147eb2ac8STudor Ambarus struct crypto_kpp *tfm_ecdh; 327270db83c4SJohan Hedberg 3273ef8efe4bSJohan Hedberg if (cid == L2CAP_CID_SMP_BREDR) { 327488a479d9SMarcel Holtmann smp = NULL; 3275ef8efe4bSJohan Hedberg goto create_chan; 3276ef8efe4bSJohan Hedberg } 3277711eafe3SJohan Hedberg 327888a479d9SMarcel Holtmann smp = kzalloc(sizeof(*smp), GFP_KERNEL); 327988a479d9SMarcel Holtmann if (!smp) 328088a479d9SMarcel Holtmann return ERR_PTR(-ENOMEM); 328188a479d9SMarcel Holtmann 328271af2f6bSHerbert Xu tfm_cmac = crypto_alloc_shash("cmac(aes)", 0, 0); 32836e2dc6d1SMarcel Holtmann if (IS_ERR(tfm_cmac)) { 32846e2dc6d1SMarcel Holtmann BT_ERR("Unable to create CMAC crypto context"); 32856e2dc6d1SMarcel Holtmann kzfree(smp); 32866e2dc6d1SMarcel Holtmann return ERR_CAST(tfm_cmac); 32876e2dc6d1SMarcel Holtmann } 32886e2dc6d1SMarcel Holtmann 3289*075f7732SHerbert Xu tfm_ecdh = crypto_alloc_kpp("ecdh", 0, 0); 329047eb2ac8STudor Ambarus if (IS_ERR(tfm_ecdh)) { 329147eb2ac8STudor Ambarus BT_ERR("Unable to create ECDH crypto context"); 329247eb2ac8STudor Ambarus crypto_free_shash(tfm_cmac); 329347eb2ac8STudor Ambarus kzfree(smp); 329447eb2ac8STudor Ambarus return ERR_CAST(tfm_ecdh); 329547eb2ac8STudor Ambarus } 329647eb2ac8STudor Ambarus 329794f14e47SJohan Hedberg smp->local_oob = false; 32986e2dc6d1SMarcel Holtmann smp->tfm_cmac = tfm_cmac; 329947eb2ac8STudor Ambarus smp->tfm_ecdh = tfm_ecdh; 330088a479d9SMarcel Holtmann 3301ef8efe4bSJohan Hedberg create_chan: 330270db83c4SJohan Hedberg chan = l2cap_chan_create(); 330370db83c4SJohan Hedberg if (!chan) { 330463511f6dSMarcel Holtmann if (smp) { 330571af2f6bSHerbert Xu crypto_free_shash(smp->tfm_cmac); 330647eb2ac8STudor Ambarus crypto_free_kpp(smp->tfm_ecdh); 330788a479d9SMarcel Holtmann kzfree(smp); 330863511f6dSMarcel Holtmann } 3309ef8efe4bSJohan Hedberg return ERR_PTR(-ENOMEM); 331070db83c4SJohan Hedberg } 331170db83c4SJohan Hedberg 331288a479d9SMarcel Holtmann chan->data = smp; 3313defce9e8SJohan Hedberg 3314ef8efe4bSJohan Hedberg l2cap_add_scid(chan, cid); 331570db83c4SJohan Hedberg 331670db83c4SJohan Hedberg l2cap_chan_set_defaults(chan); 331770db83c4SJohan Hedberg 3318157029baSMarcel Holtmann if (cid == L2CAP_CID_SMP) { 331939e3e744SJohan Hedberg u8 bdaddr_type; 332039e3e744SJohan Hedberg 332139e3e744SJohan Hedberg hci_copy_identity_address(hdev, &chan->src, &bdaddr_type); 332239e3e744SJohan Hedberg 332339e3e744SJohan Hedberg if (bdaddr_type == ADDR_LE_DEV_PUBLIC) 332470db83c4SJohan Hedberg chan->src_type = BDADDR_LE_PUBLIC; 332539e3e744SJohan Hedberg else 332639e3e744SJohan Hedberg chan->src_type = BDADDR_LE_RANDOM; 3327157029baSMarcel Holtmann } else { 3328157029baSMarcel Holtmann bacpy(&chan->src, &hdev->bdaddr); 3329ef8efe4bSJohan Hedberg chan->src_type = BDADDR_BREDR; 3330157029baSMarcel Holtmann } 3331157029baSMarcel Holtmann 333270db83c4SJohan Hedberg chan->state = BT_LISTEN; 333370db83c4SJohan Hedberg chan->mode = L2CAP_MODE_BASIC; 333470db83c4SJohan Hedberg chan->imtu = L2CAP_DEFAULT_MTU; 333570db83c4SJohan Hedberg chan->ops = &smp_root_chan_ops; 333670db83c4SJohan Hedberg 3337abe84903SJohan Hedberg /* Set correct nesting level for a parent/listening channel */ 3338abe84903SJohan Hedberg atomic_set(&chan->nesting, L2CAP_NESTING_PARENT); 3339abe84903SJohan Hedberg 3340ef8efe4bSJohan Hedberg return chan; 3341711eafe3SJohan Hedberg } 3342711eafe3SJohan Hedberg 3343ef8efe4bSJohan Hedberg static void smp_del_chan(struct l2cap_chan *chan) 3344711eafe3SJohan Hedberg { 334588a479d9SMarcel Holtmann struct smp_dev *smp; 334670db83c4SJohan Hedberg 3347ef8efe4bSJohan Hedberg BT_DBG("chan %p", chan); 3348711eafe3SJohan Hedberg 334988a479d9SMarcel Holtmann smp = chan->data; 335088a479d9SMarcel Holtmann if (smp) { 3351defce9e8SJohan Hedberg chan->data = NULL; 335271af2f6bSHerbert Xu crypto_free_shash(smp->tfm_cmac); 335347eb2ac8STudor Ambarus crypto_free_kpp(smp->tfm_ecdh); 335488a479d9SMarcel Holtmann kzfree(smp); 3355711eafe3SJohan Hedberg } 335670db83c4SJohan Hedberg 335770db83c4SJohan Hedberg l2cap_chan_put(chan); 3358711eafe3SJohan Hedberg } 3359ef8efe4bSJohan Hedberg 3360300acfdeSMarcel Holtmann static ssize_t force_bredr_smp_read(struct file *file, 3361300acfdeSMarcel Holtmann char __user *user_buf, 3362300acfdeSMarcel Holtmann size_t count, loff_t *ppos) 3363300acfdeSMarcel Holtmann { 3364300acfdeSMarcel Holtmann struct hci_dev *hdev = file->private_data; 3365300acfdeSMarcel Holtmann char buf[3]; 3366300acfdeSMarcel Holtmann 3367b7cb93e5SMarcel Holtmann buf[0] = hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP) ? 'Y': 'N'; 3368300acfdeSMarcel Holtmann buf[1] = '\n'; 3369300acfdeSMarcel Holtmann buf[2] = '\0'; 3370300acfdeSMarcel Holtmann return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 3371300acfdeSMarcel Holtmann } 3372300acfdeSMarcel Holtmann 3373300acfdeSMarcel Holtmann static ssize_t force_bredr_smp_write(struct file *file, 3374300acfdeSMarcel Holtmann const char __user *user_buf, 3375300acfdeSMarcel Holtmann size_t count, loff_t *ppos) 3376300acfdeSMarcel Holtmann { 3377300acfdeSMarcel Holtmann struct hci_dev *hdev = file->private_data; 3378300acfdeSMarcel Holtmann bool enable; 33793bf5e97dSAndy Shevchenko int err; 3380300acfdeSMarcel Holtmann 33813bf5e97dSAndy Shevchenko err = kstrtobool_from_user(user_buf, count, &enable); 33823bf5e97dSAndy Shevchenko if (err) 33833bf5e97dSAndy Shevchenko return err; 3384300acfdeSMarcel Holtmann 3385b7cb93e5SMarcel Holtmann if (enable == hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP)) 3386300acfdeSMarcel Holtmann return -EALREADY; 3387300acfdeSMarcel Holtmann 3388300acfdeSMarcel Holtmann if (enable) { 3389300acfdeSMarcel Holtmann struct l2cap_chan *chan; 3390300acfdeSMarcel Holtmann 3391300acfdeSMarcel Holtmann chan = smp_add_cid(hdev, L2CAP_CID_SMP_BREDR); 3392300acfdeSMarcel Holtmann if (IS_ERR(chan)) 3393300acfdeSMarcel Holtmann return PTR_ERR(chan); 3394300acfdeSMarcel Holtmann 3395300acfdeSMarcel Holtmann hdev->smp_bredr_data = chan; 3396300acfdeSMarcel Holtmann } else { 3397300acfdeSMarcel Holtmann struct l2cap_chan *chan; 3398300acfdeSMarcel Holtmann 3399300acfdeSMarcel Holtmann chan = hdev->smp_bredr_data; 3400300acfdeSMarcel Holtmann hdev->smp_bredr_data = NULL; 3401300acfdeSMarcel Holtmann smp_del_chan(chan); 3402300acfdeSMarcel Holtmann } 3403300acfdeSMarcel Holtmann 3404b7cb93e5SMarcel Holtmann hci_dev_change_flag(hdev, HCI_FORCE_BREDR_SMP); 3405300acfdeSMarcel Holtmann 3406300acfdeSMarcel Holtmann return count; 3407300acfdeSMarcel Holtmann } 3408300acfdeSMarcel Holtmann 3409300acfdeSMarcel Holtmann static const struct file_operations force_bredr_smp_fops = { 3410300acfdeSMarcel Holtmann .open = simple_open, 3411300acfdeSMarcel Holtmann .read = force_bredr_smp_read, 3412300acfdeSMarcel Holtmann .write = force_bredr_smp_write, 3413300acfdeSMarcel Holtmann .llseek = default_llseek, 3414300acfdeSMarcel Holtmann }; 3415300acfdeSMarcel Holtmann 3416ef8efe4bSJohan Hedberg int smp_register(struct hci_dev *hdev) 3417ef8efe4bSJohan Hedberg { 3418ef8efe4bSJohan Hedberg struct l2cap_chan *chan; 3419ef8efe4bSJohan Hedberg 3420ef8efe4bSJohan Hedberg BT_DBG("%s", hdev->name); 3421ef8efe4bSJohan Hedberg 34227e7ec445SMarcel Holtmann /* If the controller does not support Low Energy operation, then 34237e7ec445SMarcel Holtmann * there is also no need to register any SMP channel. 34247e7ec445SMarcel Holtmann */ 34257e7ec445SMarcel Holtmann if (!lmp_le_capable(hdev)) 34267e7ec445SMarcel Holtmann return 0; 34277e7ec445SMarcel Holtmann 34282b8df323SMarcel Holtmann if (WARN_ON(hdev->smp_data)) { 34292b8df323SMarcel Holtmann chan = hdev->smp_data; 34302b8df323SMarcel Holtmann hdev->smp_data = NULL; 34312b8df323SMarcel Holtmann smp_del_chan(chan); 34322b8df323SMarcel Holtmann } 34332b8df323SMarcel Holtmann 3434ef8efe4bSJohan Hedberg chan = smp_add_cid(hdev, L2CAP_CID_SMP); 3435ef8efe4bSJohan Hedberg if (IS_ERR(chan)) 3436ef8efe4bSJohan Hedberg return PTR_ERR(chan); 3437ef8efe4bSJohan Hedberg 3438ef8efe4bSJohan Hedberg hdev->smp_data = chan; 3439ef8efe4bSJohan Hedberg 3440300acfdeSMarcel Holtmann /* If the controller does not support BR/EDR Secure Connections 3441300acfdeSMarcel Holtmann * feature, then the BR/EDR SMP channel shall not be present. 3442300acfdeSMarcel Holtmann * 3443300acfdeSMarcel Holtmann * To test this with Bluetooth 4.0 controllers, create a debugfs 3444300acfdeSMarcel Holtmann * switch that allows forcing BR/EDR SMP support and accepting 3445300acfdeSMarcel Holtmann * cross-transport pairing on non-AES encrypted connections. 3446300acfdeSMarcel Holtmann */ 3447300acfdeSMarcel Holtmann if (!lmp_sc_capable(hdev)) { 3448300acfdeSMarcel Holtmann debugfs_create_file("force_bredr_smp", 0644, hdev->debugfs, 3449300acfdeSMarcel Holtmann hdev, &force_bredr_smp_fops); 345083ebb9ecSSzymon Janc 345183ebb9ecSSzymon Janc /* Flag can be already set here (due to power toggle) */ 345283ebb9ecSSzymon Janc if (!hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP)) 3453ef8efe4bSJohan Hedberg return 0; 3454300acfdeSMarcel Holtmann } 3455ef8efe4bSJohan Hedberg 34562b8df323SMarcel Holtmann if (WARN_ON(hdev->smp_bredr_data)) { 34572b8df323SMarcel Holtmann chan = hdev->smp_bredr_data; 34582b8df323SMarcel Holtmann hdev->smp_bredr_data = NULL; 34592b8df323SMarcel Holtmann smp_del_chan(chan); 34602b8df323SMarcel Holtmann } 34612b8df323SMarcel Holtmann 3462ef8efe4bSJohan Hedberg chan = smp_add_cid(hdev, L2CAP_CID_SMP_BREDR); 3463ef8efe4bSJohan Hedberg if (IS_ERR(chan)) { 3464ef8efe4bSJohan Hedberg int err = PTR_ERR(chan); 3465ef8efe4bSJohan Hedberg chan = hdev->smp_data; 3466ef8efe4bSJohan Hedberg hdev->smp_data = NULL; 3467ef8efe4bSJohan Hedberg smp_del_chan(chan); 3468ef8efe4bSJohan Hedberg return err; 3469ef8efe4bSJohan Hedberg } 3470ef8efe4bSJohan Hedberg 3471ef8efe4bSJohan Hedberg hdev->smp_bredr_data = chan; 3472ef8efe4bSJohan Hedberg 3473ef8efe4bSJohan Hedberg return 0; 3474ef8efe4bSJohan Hedberg } 3475ef8efe4bSJohan Hedberg 3476ef8efe4bSJohan Hedberg void smp_unregister(struct hci_dev *hdev) 3477ef8efe4bSJohan Hedberg { 3478ef8efe4bSJohan Hedberg struct l2cap_chan *chan; 3479ef8efe4bSJohan Hedberg 3480ef8efe4bSJohan Hedberg if (hdev->smp_bredr_data) { 3481ef8efe4bSJohan Hedberg chan = hdev->smp_bredr_data; 3482ef8efe4bSJohan Hedberg hdev->smp_bredr_data = NULL; 3483ef8efe4bSJohan Hedberg smp_del_chan(chan); 3484ef8efe4bSJohan Hedberg } 3485ef8efe4bSJohan Hedberg 3486ef8efe4bSJohan Hedberg if (hdev->smp_data) { 3487ef8efe4bSJohan Hedberg chan = hdev->smp_data; 3488ef8efe4bSJohan Hedberg hdev->smp_data = NULL; 3489ef8efe4bSJohan Hedberg smp_del_chan(chan); 3490ef8efe4bSJohan Hedberg } 3491ef8efe4bSJohan Hedberg } 34920a2b0f04SJohan Hedberg 34930a2b0f04SJohan Hedberg #if IS_ENABLED(CONFIG_BT_SELFTEST_SMP) 34940a2b0f04SJohan Hedberg 349547eb2ac8STudor Ambarus static int __init test_debug_key(struct crypto_kpp *tfm_ecdh) 349671653eb6SMarcel Holtmann { 3497c0153b0bSTudor Ambarus u8 pk[64]; 3498a2976416STudor Ambarus int err; 349971653eb6SMarcel Holtmann 3500c0153b0bSTudor Ambarus err = set_ecdh_privkey(tfm_ecdh, debug_sk); 3501a2976416STudor Ambarus if (err) 3502a2976416STudor Ambarus return err; 350371653eb6SMarcel Holtmann 3504c0153b0bSTudor Ambarus err = generate_ecdh_public_key(tfm_ecdh, pk); 3505c0153b0bSTudor Ambarus if (err) 3506c0153b0bSTudor Ambarus return err; 350771653eb6SMarcel Holtmann 3508329d8230SJason A. Donenfeld if (crypto_memneq(pk, debug_pk, 64)) 350971653eb6SMarcel Holtmann return -EINVAL; 351071653eb6SMarcel Holtmann 351171653eb6SMarcel Holtmann return 0; 351271653eb6SMarcel Holtmann } 351371653eb6SMarcel Holtmann 351428a220aaSArd Biesheuvel static int __init test_ah(void) 3515cfc4198eSJohan Hedberg { 3516cfc4198eSJohan Hedberg const u8 irk[16] = { 3517cfc4198eSJohan Hedberg 0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34, 3518cfc4198eSJohan Hedberg 0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec }; 3519cfc4198eSJohan Hedberg const u8 r[3] = { 0x94, 0x81, 0x70 }; 3520cfc4198eSJohan Hedberg const u8 exp[3] = { 0xaa, 0xfb, 0x0d }; 3521cfc4198eSJohan Hedberg u8 res[3]; 3522cfc4198eSJohan Hedberg int err; 3523cfc4198eSJohan Hedberg 352428a220aaSArd Biesheuvel err = smp_ah(irk, r, res); 3525cfc4198eSJohan Hedberg if (err) 3526cfc4198eSJohan Hedberg return err; 3527cfc4198eSJohan Hedberg 3528329d8230SJason A. Donenfeld if (crypto_memneq(res, exp, 3)) 3529cfc4198eSJohan Hedberg return -EINVAL; 3530cfc4198eSJohan Hedberg 3531cfc4198eSJohan Hedberg return 0; 3532cfc4198eSJohan Hedberg } 3533cfc4198eSJohan Hedberg 353428a220aaSArd Biesheuvel static int __init test_c1(void) 3535cfc4198eSJohan Hedberg { 3536cfc4198eSJohan Hedberg const u8 k[16] = { 3537cfc4198eSJohan Hedberg 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3538cfc4198eSJohan Hedberg 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 3539cfc4198eSJohan Hedberg const u8 r[16] = { 3540cfc4198eSJohan Hedberg 0xe0, 0x2e, 0x70, 0xc6, 0x4e, 0x27, 0x88, 0x63, 3541cfc4198eSJohan Hedberg 0x0e, 0x6f, 0xad, 0x56, 0x21, 0xd5, 0x83, 0x57 }; 3542cfc4198eSJohan Hedberg const u8 preq[7] = { 0x01, 0x01, 0x00, 0x00, 0x10, 0x07, 0x07 }; 3543cfc4198eSJohan Hedberg const u8 pres[7] = { 0x02, 0x03, 0x00, 0x00, 0x08, 0x00, 0x05 }; 3544cfc4198eSJohan Hedberg const u8 _iat = 0x01; 3545cfc4198eSJohan Hedberg const u8 _rat = 0x00; 3546cfc4198eSJohan Hedberg const bdaddr_t ra = { { 0xb6, 0xb5, 0xb4, 0xb3, 0xb2, 0xb1 } }; 3547cfc4198eSJohan Hedberg const bdaddr_t ia = { { 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1 } }; 3548cfc4198eSJohan Hedberg const u8 exp[16] = { 3549cfc4198eSJohan Hedberg 0x86, 0x3b, 0xf1, 0xbe, 0xc5, 0x4d, 0xa7, 0xd2, 3550cfc4198eSJohan Hedberg 0xea, 0x88, 0x89, 0x87, 0xef, 0x3f, 0x1e, 0x1e }; 3551cfc4198eSJohan Hedberg u8 res[16]; 3552cfc4198eSJohan Hedberg int err; 3553cfc4198eSJohan Hedberg 355428a220aaSArd Biesheuvel err = smp_c1(k, r, preq, pres, _iat, &ia, _rat, &ra, res); 3555cfc4198eSJohan Hedberg if (err) 3556cfc4198eSJohan Hedberg return err; 3557cfc4198eSJohan Hedberg 3558329d8230SJason A. Donenfeld if (crypto_memneq(res, exp, 16)) 3559cfc4198eSJohan Hedberg return -EINVAL; 3560cfc4198eSJohan Hedberg 3561cfc4198eSJohan Hedberg return 0; 3562cfc4198eSJohan Hedberg } 3563cfc4198eSJohan Hedberg 356428a220aaSArd Biesheuvel static int __init test_s1(void) 3565cfc4198eSJohan Hedberg { 3566cfc4198eSJohan Hedberg const u8 k[16] = { 3567cfc4198eSJohan Hedberg 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3568cfc4198eSJohan Hedberg 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 3569cfc4198eSJohan Hedberg const u8 r1[16] = { 3570cfc4198eSJohan Hedberg 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 }; 3571cfc4198eSJohan Hedberg const u8 r2[16] = { 3572cfc4198eSJohan Hedberg 0x00, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99 }; 3573cfc4198eSJohan Hedberg const u8 exp[16] = { 3574cfc4198eSJohan Hedberg 0x62, 0xa0, 0x6d, 0x79, 0xae, 0x16, 0x42, 0x5b, 3575cfc4198eSJohan Hedberg 0x9b, 0xf4, 0xb0, 0xe8, 0xf0, 0xe1, 0x1f, 0x9a }; 3576cfc4198eSJohan Hedberg u8 res[16]; 3577cfc4198eSJohan Hedberg int err; 3578cfc4198eSJohan Hedberg 357928a220aaSArd Biesheuvel err = smp_s1(k, r1, r2, res); 3580cfc4198eSJohan Hedberg if (err) 3581cfc4198eSJohan Hedberg return err; 3582cfc4198eSJohan Hedberg 3583329d8230SJason A. Donenfeld if (crypto_memneq(res, exp, 16)) 3584cfc4198eSJohan Hedberg return -EINVAL; 3585cfc4198eSJohan Hedberg 3586cfc4198eSJohan Hedberg return 0; 3587cfc4198eSJohan Hedberg } 3588cfc4198eSJohan Hedberg 358971af2f6bSHerbert Xu static int __init test_f4(struct crypto_shash *tfm_cmac) 3590fb2969a3SJohan Hedberg { 3591fb2969a3SJohan Hedberg const u8 u[32] = { 3592fb2969a3SJohan Hedberg 0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc, 3593fb2969a3SJohan Hedberg 0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef, 3594fb2969a3SJohan Hedberg 0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e, 3595fb2969a3SJohan Hedberg 0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20 }; 3596fb2969a3SJohan Hedberg const u8 v[32] = { 3597fb2969a3SJohan Hedberg 0xfd, 0xc5, 0x7f, 0xf4, 0x49, 0xdd, 0x4f, 0x6b, 3598fb2969a3SJohan Hedberg 0xfb, 0x7c, 0x9d, 0xf1, 0xc2, 0x9a, 0xcb, 0x59, 3599fb2969a3SJohan Hedberg 0x2a, 0xe7, 0xd4, 0xee, 0xfb, 0xfc, 0x0a, 0x90, 3600fb2969a3SJohan Hedberg 0x9a, 0xbb, 0xf6, 0x32, 0x3d, 0x8b, 0x18, 0x55 }; 3601fb2969a3SJohan Hedberg const u8 x[16] = { 3602fb2969a3SJohan Hedberg 0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff, 3603fb2969a3SJohan Hedberg 0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 }; 3604fb2969a3SJohan Hedberg const u8 z = 0x00; 3605fb2969a3SJohan Hedberg const u8 exp[16] = { 3606fb2969a3SJohan Hedberg 0x2d, 0x87, 0x74, 0xa9, 0xbe, 0xa1, 0xed, 0xf1, 3607fb2969a3SJohan Hedberg 0x1c, 0xbd, 0xa9, 0x07, 0xf1, 0x16, 0xc9, 0xf2 }; 3608fb2969a3SJohan Hedberg u8 res[16]; 3609fb2969a3SJohan Hedberg int err; 3610fb2969a3SJohan Hedberg 3611fb2969a3SJohan Hedberg err = smp_f4(tfm_cmac, u, v, x, z, res); 3612fb2969a3SJohan Hedberg if (err) 3613fb2969a3SJohan Hedberg return err; 3614fb2969a3SJohan Hedberg 3615329d8230SJason A. Donenfeld if (crypto_memneq(res, exp, 16)) 3616fb2969a3SJohan Hedberg return -EINVAL; 3617fb2969a3SJohan Hedberg 3618fb2969a3SJohan Hedberg return 0; 3619fb2969a3SJohan Hedberg } 3620fb2969a3SJohan Hedberg 362171af2f6bSHerbert Xu static int __init test_f5(struct crypto_shash *tfm_cmac) 3622fb2969a3SJohan Hedberg { 3623fb2969a3SJohan Hedberg const u8 w[32] = { 3624fb2969a3SJohan Hedberg 0x98, 0xa6, 0xbf, 0x73, 0xf3, 0x34, 0x8d, 0x86, 3625fb2969a3SJohan Hedberg 0xf1, 0x66, 0xf8, 0xb4, 0x13, 0x6b, 0x79, 0x99, 3626fb2969a3SJohan Hedberg 0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34, 3627fb2969a3SJohan Hedberg 0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec }; 3628fb2969a3SJohan Hedberg const u8 n1[16] = { 3629fb2969a3SJohan Hedberg 0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff, 3630fb2969a3SJohan Hedberg 0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 }; 3631fb2969a3SJohan Hedberg const u8 n2[16] = { 3632fb2969a3SJohan Hedberg 0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21, 3633fb2969a3SJohan Hedberg 0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6 }; 3634fb2969a3SJohan Hedberg const u8 a1[7] = { 0xce, 0xbf, 0x37, 0x37, 0x12, 0x56, 0x00 }; 3635fb2969a3SJohan Hedberg const u8 a2[7] = { 0xc1, 0xcf, 0x2d, 0x70, 0x13, 0xa7, 0x00 }; 3636fb2969a3SJohan Hedberg const u8 exp_ltk[16] = { 3637fb2969a3SJohan Hedberg 0x38, 0x0a, 0x75, 0x94, 0xb5, 0x22, 0x05, 0x98, 3638fb2969a3SJohan Hedberg 0x23, 0xcd, 0xd7, 0x69, 0x11, 0x79, 0x86, 0x69 }; 3639fb2969a3SJohan Hedberg const u8 exp_mackey[16] = { 3640fb2969a3SJohan Hedberg 0x20, 0x6e, 0x63, 0xce, 0x20, 0x6a, 0x3f, 0xfd, 3641fb2969a3SJohan Hedberg 0x02, 0x4a, 0x08, 0xa1, 0x76, 0xf1, 0x65, 0x29 }; 3642fb2969a3SJohan Hedberg u8 mackey[16], ltk[16]; 3643fb2969a3SJohan Hedberg int err; 3644fb2969a3SJohan Hedberg 3645fb2969a3SJohan Hedberg err = smp_f5(tfm_cmac, w, n1, n2, a1, a2, mackey, ltk); 3646fb2969a3SJohan Hedberg if (err) 3647fb2969a3SJohan Hedberg return err; 3648fb2969a3SJohan Hedberg 3649329d8230SJason A. Donenfeld if (crypto_memneq(mackey, exp_mackey, 16)) 3650fb2969a3SJohan Hedberg return -EINVAL; 3651fb2969a3SJohan Hedberg 3652329d8230SJason A. Donenfeld if (crypto_memneq(ltk, exp_ltk, 16)) 3653fb2969a3SJohan Hedberg return -EINVAL; 3654fb2969a3SJohan Hedberg 3655fb2969a3SJohan Hedberg return 0; 3656fb2969a3SJohan Hedberg } 3657fb2969a3SJohan Hedberg 365871af2f6bSHerbert Xu static int __init test_f6(struct crypto_shash *tfm_cmac) 3659fb2969a3SJohan Hedberg { 3660fb2969a3SJohan Hedberg const u8 w[16] = { 3661fb2969a3SJohan Hedberg 0x20, 0x6e, 0x63, 0xce, 0x20, 0x6a, 0x3f, 0xfd, 3662fb2969a3SJohan Hedberg 0x02, 0x4a, 0x08, 0xa1, 0x76, 0xf1, 0x65, 0x29 }; 3663fb2969a3SJohan Hedberg const u8 n1[16] = { 3664fb2969a3SJohan Hedberg 0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff, 3665fb2969a3SJohan Hedberg 0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 }; 3666fb2969a3SJohan Hedberg const u8 n2[16] = { 3667fb2969a3SJohan Hedberg 0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21, 3668fb2969a3SJohan Hedberg 0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6 }; 3669fb2969a3SJohan Hedberg const u8 r[16] = { 3670fb2969a3SJohan Hedberg 0xc8, 0x0f, 0x2d, 0x0c, 0xd2, 0x42, 0xda, 0x08, 3671fb2969a3SJohan Hedberg 0x54, 0xbb, 0x53, 0xb4, 0x3b, 0x34, 0xa3, 0x12 }; 3672fb2969a3SJohan Hedberg const u8 io_cap[3] = { 0x02, 0x01, 0x01 }; 3673fb2969a3SJohan Hedberg const u8 a1[7] = { 0xce, 0xbf, 0x37, 0x37, 0x12, 0x56, 0x00 }; 3674fb2969a3SJohan Hedberg const u8 a2[7] = { 0xc1, 0xcf, 0x2d, 0x70, 0x13, 0xa7, 0x00 }; 3675fb2969a3SJohan Hedberg const u8 exp[16] = { 3676fb2969a3SJohan Hedberg 0x61, 0x8f, 0x95, 0xda, 0x09, 0x0b, 0x6c, 0xd2, 3677fb2969a3SJohan Hedberg 0xc5, 0xe8, 0xd0, 0x9c, 0x98, 0x73, 0xc4, 0xe3 }; 3678fb2969a3SJohan Hedberg u8 res[16]; 3679fb2969a3SJohan Hedberg int err; 3680fb2969a3SJohan Hedberg 3681fb2969a3SJohan Hedberg err = smp_f6(tfm_cmac, w, n1, n2, r, io_cap, a1, a2, res); 3682fb2969a3SJohan Hedberg if (err) 3683fb2969a3SJohan Hedberg return err; 3684fb2969a3SJohan Hedberg 3685329d8230SJason A. Donenfeld if (crypto_memneq(res, exp, 16)) 3686fb2969a3SJohan Hedberg return -EINVAL; 3687fb2969a3SJohan Hedberg 3688fb2969a3SJohan Hedberg return 0; 3689fb2969a3SJohan Hedberg } 3690fb2969a3SJohan Hedberg 369171af2f6bSHerbert Xu static int __init test_g2(struct crypto_shash *tfm_cmac) 3692fb2969a3SJohan Hedberg { 3693fb2969a3SJohan Hedberg const u8 u[32] = { 3694fb2969a3SJohan Hedberg 0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc, 3695fb2969a3SJohan Hedberg 0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef, 3696fb2969a3SJohan Hedberg 0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e, 3697fb2969a3SJohan Hedberg 0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20 }; 3698fb2969a3SJohan Hedberg const u8 v[32] = { 3699fb2969a3SJohan Hedberg 0xfd, 0xc5, 0x7f, 0xf4, 0x49, 0xdd, 0x4f, 0x6b, 3700fb2969a3SJohan Hedberg 0xfb, 0x7c, 0x9d, 0xf1, 0xc2, 0x9a, 0xcb, 0x59, 3701fb2969a3SJohan Hedberg 0x2a, 0xe7, 0xd4, 0xee, 0xfb, 0xfc, 0x0a, 0x90, 3702fb2969a3SJohan Hedberg 0x9a, 0xbb, 0xf6, 0x32, 0x3d, 0x8b, 0x18, 0x55 }; 3703fb2969a3SJohan Hedberg const u8 x[16] = { 3704fb2969a3SJohan Hedberg 0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff, 3705fb2969a3SJohan Hedberg 0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 }; 3706fb2969a3SJohan Hedberg const u8 y[16] = { 3707fb2969a3SJohan Hedberg 0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21, 3708fb2969a3SJohan Hedberg 0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6 }; 3709fb2969a3SJohan Hedberg const u32 exp_val = 0x2f9ed5ba % 1000000; 3710fb2969a3SJohan Hedberg u32 val; 3711fb2969a3SJohan Hedberg int err; 3712fb2969a3SJohan Hedberg 3713fb2969a3SJohan Hedberg err = smp_g2(tfm_cmac, u, v, x, y, &val); 3714fb2969a3SJohan Hedberg if (err) 3715fb2969a3SJohan Hedberg return err; 3716fb2969a3SJohan Hedberg 3717fb2969a3SJohan Hedberg if (val != exp_val) 3718fb2969a3SJohan Hedberg return -EINVAL; 3719fb2969a3SJohan Hedberg 3720fb2969a3SJohan Hedberg return 0; 3721fb2969a3SJohan Hedberg } 3722fb2969a3SJohan Hedberg 372371af2f6bSHerbert Xu static int __init test_h6(struct crypto_shash *tfm_cmac) 3724fb2969a3SJohan Hedberg { 3725fb2969a3SJohan Hedberg const u8 w[16] = { 3726fb2969a3SJohan Hedberg 0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34, 3727fb2969a3SJohan Hedberg 0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec }; 3728fb2969a3SJohan Hedberg const u8 key_id[4] = { 0x72, 0x62, 0x65, 0x6c }; 3729fb2969a3SJohan Hedberg const u8 exp[16] = { 3730fb2969a3SJohan Hedberg 0x99, 0x63, 0xb1, 0x80, 0xe2, 0xa9, 0xd3, 0xe8, 3731fb2969a3SJohan Hedberg 0x1c, 0xc9, 0x6d, 0xe7, 0x02, 0xe1, 0x9a, 0x2d }; 3732fb2969a3SJohan Hedberg u8 res[16]; 3733fb2969a3SJohan Hedberg int err; 3734fb2969a3SJohan Hedberg 3735fb2969a3SJohan Hedberg err = smp_h6(tfm_cmac, w, key_id, res); 3736fb2969a3SJohan Hedberg if (err) 3737fb2969a3SJohan Hedberg return err; 3738fb2969a3SJohan Hedberg 3739329d8230SJason A. Donenfeld if (crypto_memneq(res, exp, 16)) 3740fb2969a3SJohan Hedberg return -EINVAL; 3741fb2969a3SJohan Hedberg 3742fb2969a3SJohan Hedberg return 0; 3743fb2969a3SJohan Hedberg } 3744fb2969a3SJohan Hedberg 374564dd374eSMarcel Holtmann static char test_smp_buffer[32]; 374664dd374eSMarcel Holtmann 374764dd374eSMarcel Holtmann static ssize_t test_smp_read(struct file *file, char __user *user_buf, 374864dd374eSMarcel Holtmann size_t count, loff_t *ppos) 374964dd374eSMarcel Holtmann { 375064dd374eSMarcel Holtmann return simple_read_from_buffer(user_buf, count, ppos, test_smp_buffer, 375164dd374eSMarcel Holtmann strlen(test_smp_buffer)); 375264dd374eSMarcel Holtmann } 375364dd374eSMarcel Holtmann 375464dd374eSMarcel Holtmann static const struct file_operations test_smp_fops = { 375564dd374eSMarcel Holtmann .open = simple_open, 375664dd374eSMarcel Holtmann .read = test_smp_read, 375764dd374eSMarcel Holtmann .llseek = default_llseek, 375864dd374eSMarcel Holtmann }; 375964dd374eSMarcel Holtmann 376028a220aaSArd Biesheuvel static int __init run_selftests(struct crypto_shash *tfm_cmac, 376147eb2ac8STudor Ambarus struct crypto_kpp *tfm_ecdh) 37620a2b0f04SJohan Hedberg { 3763255047b0SMarcel Holtmann ktime_t calltime, delta, rettime; 3764255047b0SMarcel Holtmann unsigned long long duration; 3765cfc4198eSJohan Hedberg int err; 3766cfc4198eSJohan Hedberg 3767255047b0SMarcel Holtmann calltime = ktime_get(); 3768255047b0SMarcel Holtmann 376947eb2ac8STudor Ambarus err = test_debug_key(tfm_ecdh); 377071653eb6SMarcel Holtmann if (err) { 377171653eb6SMarcel Holtmann BT_ERR("debug_key test failed"); 377271653eb6SMarcel Holtmann goto done; 377371653eb6SMarcel Holtmann } 377471653eb6SMarcel Holtmann 377528a220aaSArd Biesheuvel err = test_ah(); 3776cfc4198eSJohan Hedberg if (err) { 3777cfc4198eSJohan Hedberg BT_ERR("smp_ah test failed"); 377864dd374eSMarcel Holtmann goto done; 3779cfc4198eSJohan Hedberg } 3780cfc4198eSJohan Hedberg 378128a220aaSArd Biesheuvel err = test_c1(); 3782cfc4198eSJohan Hedberg if (err) { 3783cfc4198eSJohan Hedberg BT_ERR("smp_c1 test failed"); 378464dd374eSMarcel Holtmann goto done; 3785cfc4198eSJohan Hedberg } 3786cfc4198eSJohan Hedberg 378728a220aaSArd Biesheuvel err = test_s1(); 3788cfc4198eSJohan Hedberg if (err) { 3789cfc4198eSJohan Hedberg BT_ERR("smp_s1 test failed"); 379064dd374eSMarcel Holtmann goto done; 3791cfc4198eSJohan Hedberg } 3792cfc4198eSJohan Hedberg 3793fb2969a3SJohan Hedberg err = test_f4(tfm_cmac); 3794fb2969a3SJohan Hedberg if (err) { 3795fb2969a3SJohan Hedberg BT_ERR("smp_f4 test failed"); 379664dd374eSMarcel Holtmann goto done; 3797fb2969a3SJohan Hedberg } 3798fb2969a3SJohan Hedberg 3799fb2969a3SJohan Hedberg err = test_f5(tfm_cmac); 3800fb2969a3SJohan Hedberg if (err) { 3801fb2969a3SJohan Hedberg BT_ERR("smp_f5 test failed"); 380264dd374eSMarcel Holtmann goto done; 3803fb2969a3SJohan Hedberg } 3804fb2969a3SJohan Hedberg 3805fb2969a3SJohan Hedberg err = test_f6(tfm_cmac); 3806fb2969a3SJohan Hedberg if (err) { 3807fb2969a3SJohan Hedberg BT_ERR("smp_f6 test failed"); 380864dd374eSMarcel Holtmann goto done; 3809fb2969a3SJohan Hedberg } 3810fb2969a3SJohan Hedberg 3811fb2969a3SJohan Hedberg err = test_g2(tfm_cmac); 3812fb2969a3SJohan Hedberg if (err) { 3813fb2969a3SJohan Hedberg BT_ERR("smp_g2 test failed"); 381464dd374eSMarcel Holtmann goto done; 3815fb2969a3SJohan Hedberg } 3816fb2969a3SJohan Hedberg 3817fb2969a3SJohan Hedberg err = test_h6(tfm_cmac); 3818fb2969a3SJohan Hedberg if (err) { 3819fb2969a3SJohan Hedberg BT_ERR("smp_h6 test failed"); 382064dd374eSMarcel Holtmann goto done; 3821fb2969a3SJohan Hedberg } 3822fb2969a3SJohan Hedberg 3823255047b0SMarcel Holtmann rettime = ktime_get(); 3824255047b0SMarcel Holtmann delta = ktime_sub(rettime, calltime); 3825255047b0SMarcel Holtmann duration = (unsigned long long) ktime_to_ns(delta) >> 10; 3826255047b0SMarcel Holtmann 38275ced2464SMarcel Holtmann BT_INFO("SMP test passed in %llu usecs", duration); 38280a2b0f04SJohan Hedberg 382964dd374eSMarcel Holtmann done: 383064dd374eSMarcel Holtmann if (!err) 383164dd374eSMarcel Holtmann snprintf(test_smp_buffer, sizeof(test_smp_buffer), 383264dd374eSMarcel Holtmann "PASS (%llu usecs)\n", duration); 383364dd374eSMarcel Holtmann else 383464dd374eSMarcel Holtmann snprintf(test_smp_buffer, sizeof(test_smp_buffer), "FAIL\n"); 383564dd374eSMarcel Holtmann 383664dd374eSMarcel Holtmann debugfs_create_file("selftest_smp", 0444, bt_debugfs, NULL, 383764dd374eSMarcel Holtmann &test_smp_fops); 383864dd374eSMarcel Holtmann 383964dd374eSMarcel Holtmann return err; 38400a2b0f04SJohan Hedberg } 38410a2b0f04SJohan Hedberg 38420a2b0f04SJohan Hedberg int __init bt_selftest_smp(void) 38430a2b0f04SJohan Hedberg { 384471af2f6bSHerbert Xu struct crypto_shash *tfm_cmac; 384547eb2ac8STudor Ambarus struct crypto_kpp *tfm_ecdh; 38460a2b0f04SJohan Hedberg int err; 38470a2b0f04SJohan Hedberg 38483d234b33SEric Biggers tfm_cmac = crypto_alloc_shash("cmac(aes)", 0, 0); 38490a2b0f04SJohan Hedberg if (IS_ERR(tfm_cmac)) { 38500a2b0f04SJohan Hedberg BT_ERR("Unable to create CMAC crypto context"); 38510a2b0f04SJohan Hedberg return PTR_ERR(tfm_cmac); 38520a2b0f04SJohan Hedberg } 38530a2b0f04SJohan Hedberg 3854*075f7732SHerbert Xu tfm_ecdh = crypto_alloc_kpp("ecdh", 0, 0); 385547eb2ac8STudor Ambarus if (IS_ERR(tfm_ecdh)) { 385647eb2ac8STudor Ambarus BT_ERR("Unable to create ECDH crypto context"); 385747eb2ac8STudor Ambarus crypto_free_shash(tfm_cmac); 385847eb2ac8STudor Ambarus return PTR_ERR(tfm_ecdh); 385947eb2ac8STudor Ambarus } 386047eb2ac8STudor Ambarus 386128a220aaSArd Biesheuvel err = run_selftests(tfm_cmac, tfm_ecdh); 38620a2b0f04SJohan Hedberg 386371af2f6bSHerbert Xu crypto_free_shash(tfm_cmac); 386447eb2ac8STudor Ambarus crypto_free_kpp(tfm_ecdh); 38650a2b0f04SJohan Hedberg 38660a2b0f04SJohan Hedberg return err; 38670a2b0f04SJohan Hedberg } 38680a2b0f04SJohan Hedberg 38690a2b0f04SJohan Hedberg #endif 3870