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]; 173cbbbe3e2SJohan Hedberg int err; 174cbbbe3e2SJohan Hedberg 175cbbbe3e2SJohan Hedberg if (len > CMAC_MSG_MAX) 176cbbbe3e2SJohan Hedberg return -EFBIG; 177cbbbe3e2SJohan Hedberg 178cbbbe3e2SJohan Hedberg if (!tfm) { 179cbbbe3e2SJohan Hedberg BT_ERR("tfm %p", tfm); 180cbbbe3e2SJohan Hedberg return -EINVAL; 181cbbbe3e2SJohan Hedberg } 182cbbbe3e2SJohan Hedberg 183cbbbe3e2SJohan Hedberg /* Swap key and message from LSB to MSB */ 184cbbbe3e2SJohan Hedberg swap_buf(k, tmp, 16); 185cbbbe3e2SJohan Hedberg swap_buf(m, msg_msb, len); 186cbbbe3e2SJohan Hedberg 187c7a3d57dSJohan Hedberg SMP_DBG("msg (len %zu) %*phN", len, (int) len, m); 188c7a3d57dSJohan Hedberg SMP_DBG("key %16phN", k); 189cbbbe3e2SJohan Hedberg 19071af2f6bSHerbert Xu err = crypto_shash_setkey(tfm, tmp, 16); 191cbbbe3e2SJohan Hedberg if (err) { 192cbbbe3e2SJohan Hedberg BT_ERR("cipher setkey failed: %d", err); 193cbbbe3e2SJohan Hedberg return err; 194cbbbe3e2SJohan Hedberg } 195cbbbe3e2SJohan Hedberg 196ec0bf6edSEric Biggers err = crypto_shash_tfm_digest(tfm, msg_msb, len, mac_msb); 197cbbbe3e2SJohan Hedberg if (err) { 19871af2f6bSHerbert Xu BT_ERR("Hash computation error %d", err); 199cbbbe3e2SJohan Hedberg return err; 200cbbbe3e2SJohan Hedberg } 201cbbbe3e2SJohan Hedberg 202cbbbe3e2SJohan Hedberg swap_buf(mac_msb, mac, 16); 203cbbbe3e2SJohan Hedberg 204c7a3d57dSJohan Hedberg SMP_DBG("mac %16phN", mac); 205cbbbe3e2SJohan Hedberg 206cbbbe3e2SJohan Hedberg return 0; 207cbbbe3e2SJohan Hedberg } 208cbbbe3e2SJohan Hedberg 20971af2f6bSHerbert Xu static int smp_f4(struct crypto_shash *tfm_cmac, const u8 u[32], 21071af2f6bSHerbert Xu const u8 v[32], const u8 x[16], u8 z, u8 res[16]) 211cbbbe3e2SJohan Hedberg { 212cbbbe3e2SJohan Hedberg u8 m[65]; 213cbbbe3e2SJohan Hedberg int err; 214cbbbe3e2SJohan Hedberg 215c7a3d57dSJohan Hedberg SMP_DBG("u %32phN", u); 216c7a3d57dSJohan Hedberg SMP_DBG("v %32phN", v); 217c7a3d57dSJohan Hedberg SMP_DBG("x %16phN z %02x", x, z); 218cbbbe3e2SJohan Hedberg 219cbbbe3e2SJohan Hedberg m[0] = z; 220cbbbe3e2SJohan Hedberg memcpy(m + 1, v, 32); 221cbbbe3e2SJohan Hedberg memcpy(m + 33, u, 32); 222cbbbe3e2SJohan Hedberg 223cbbbe3e2SJohan Hedberg err = aes_cmac(tfm_cmac, x, m, sizeof(m), res); 224cbbbe3e2SJohan Hedberg if (err) 225cbbbe3e2SJohan Hedberg return err; 226cbbbe3e2SJohan Hedberg 227c7a3d57dSJohan Hedberg SMP_DBG("res %16phN", res); 228cbbbe3e2SJohan Hedberg 229cbbbe3e2SJohan Hedberg return err; 230cbbbe3e2SJohan Hedberg } 231cbbbe3e2SJohan Hedberg 23271af2f6bSHerbert Xu static int smp_f5(struct crypto_shash *tfm_cmac, const u8 w[32], 2334da50de8SJohan Hedberg const u8 n1[16], const u8 n2[16], const u8 a1[7], 2344da50de8SJohan Hedberg const u8 a2[7], u8 mackey[16], u8 ltk[16]) 235760b018bSJohan Hedberg { 236760b018bSJohan Hedberg /* The btle, salt and length "magic" values are as defined in 237760b018bSJohan Hedberg * the SMP section of the Bluetooth core specification. In ASCII 238760b018bSJohan Hedberg * the btle value ends up being 'btle'. The salt is just a 239760b018bSJohan Hedberg * random number whereas length is the value 256 in little 240760b018bSJohan Hedberg * endian format. 241760b018bSJohan Hedberg */ 242760b018bSJohan Hedberg const u8 btle[4] = { 0x65, 0x6c, 0x74, 0x62 }; 243760b018bSJohan Hedberg const u8 salt[16] = { 0xbe, 0x83, 0x60, 0x5a, 0xdb, 0x0b, 0x37, 0x60, 244760b018bSJohan Hedberg 0x38, 0xa5, 0xf5, 0xaa, 0x91, 0x83, 0x88, 0x6c }; 245760b018bSJohan Hedberg const u8 length[2] = { 0x00, 0x01 }; 246760b018bSJohan Hedberg u8 m[53], t[16]; 247760b018bSJohan Hedberg int err; 248760b018bSJohan Hedberg 249c7a3d57dSJohan Hedberg SMP_DBG("w %32phN", w); 250c7a3d57dSJohan Hedberg SMP_DBG("n1 %16phN n2 %16phN", n1, n2); 251c7a3d57dSJohan Hedberg SMP_DBG("a1 %7phN a2 %7phN", a1, a2); 252760b018bSJohan Hedberg 253760b018bSJohan Hedberg err = aes_cmac(tfm_cmac, salt, w, 32, t); 254760b018bSJohan Hedberg if (err) 255760b018bSJohan Hedberg return err; 256760b018bSJohan Hedberg 257c7a3d57dSJohan Hedberg SMP_DBG("t %16phN", t); 258760b018bSJohan Hedberg 259760b018bSJohan Hedberg memcpy(m, length, 2); 260760b018bSJohan Hedberg memcpy(m + 2, a2, 7); 261760b018bSJohan Hedberg memcpy(m + 9, a1, 7); 262760b018bSJohan Hedberg memcpy(m + 16, n2, 16); 263760b018bSJohan Hedberg memcpy(m + 32, n1, 16); 264760b018bSJohan Hedberg memcpy(m + 48, btle, 4); 265760b018bSJohan Hedberg 266760b018bSJohan Hedberg m[52] = 0; /* Counter */ 267760b018bSJohan Hedberg 268760b018bSJohan Hedberg err = aes_cmac(tfm_cmac, t, m, sizeof(m), mackey); 269760b018bSJohan Hedberg if (err) 270760b018bSJohan Hedberg return err; 271760b018bSJohan Hedberg 272c7a3d57dSJohan Hedberg SMP_DBG("mackey %16phN", mackey); 273760b018bSJohan Hedberg 274760b018bSJohan Hedberg m[52] = 1; /* Counter */ 275760b018bSJohan Hedberg 276760b018bSJohan Hedberg err = aes_cmac(tfm_cmac, t, m, sizeof(m), ltk); 277760b018bSJohan Hedberg if (err) 278760b018bSJohan Hedberg return err; 279760b018bSJohan Hedberg 280c7a3d57dSJohan Hedberg SMP_DBG("ltk %16phN", ltk); 281760b018bSJohan Hedberg 282760b018bSJohan Hedberg return 0; 283760b018bSJohan Hedberg } 284760b018bSJohan Hedberg 28571af2f6bSHerbert Xu static int smp_f6(struct crypto_shash *tfm_cmac, const u8 w[16], 2864da50de8SJohan Hedberg const u8 n1[16], const u8 n2[16], const u8 r[16], 287760b018bSJohan Hedberg const u8 io_cap[3], const u8 a1[7], const u8 a2[7], 288760b018bSJohan Hedberg u8 res[16]) 289760b018bSJohan Hedberg { 290760b018bSJohan Hedberg u8 m[65]; 291760b018bSJohan Hedberg int err; 292760b018bSJohan Hedberg 293c7a3d57dSJohan Hedberg SMP_DBG("w %16phN", w); 294c7a3d57dSJohan Hedberg SMP_DBG("n1 %16phN n2 %16phN", n1, n2); 295c7a3d57dSJohan Hedberg SMP_DBG("r %16phN io_cap %3phN a1 %7phN a2 %7phN", r, io_cap, a1, a2); 296760b018bSJohan Hedberg 297760b018bSJohan Hedberg memcpy(m, a2, 7); 298760b018bSJohan Hedberg memcpy(m + 7, a1, 7); 299760b018bSJohan Hedberg memcpy(m + 14, io_cap, 3); 300760b018bSJohan Hedberg memcpy(m + 17, r, 16); 301760b018bSJohan Hedberg memcpy(m + 33, n2, 16); 302760b018bSJohan Hedberg memcpy(m + 49, n1, 16); 303760b018bSJohan Hedberg 304760b018bSJohan Hedberg err = aes_cmac(tfm_cmac, w, m, sizeof(m), res); 305760b018bSJohan Hedberg if (err) 306760b018bSJohan Hedberg return err; 307760b018bSJohan Hedberg 308203de21bSMarcel Holtmann SMP_DBG("res %16phN", res); 309760b018bSJohan Hedberg 310760b018bSJohan Hedberg return err; 311760b018bSJohan Hedberg } 312760b018bSJohan Hedberg 31371af2f6bSHerbert Xu static int smp_g2(struct crypto_shash *tfm_cmac, const u8 u[32], const u8 v[32], 314191dc7feSJohan Hedberg const u8 x[16], const u8 y[16], u32 *val) 315191dc7feSJohan Hedberg { 316191dc7feSJohan Hedberg u8 m[80], tmp[16]; 317191dc7feSJohan Hedberg int err; 318191dc7feSJohan Hedberg 319c7a3d57dSJohan Hedberg SMP_DBG("u %32phN", u); 320c7a3d57dSJohan Hedberg SMP_DBG("v %32phN", v); 321c7a3d57dSJohan Hedberg SMP_DBG("x %16phN y %16phN", x, y); 322191dc7feSJohan Hedberg 323191dc7feSJohan Hedberg memcpy(m, y, 16); 324191dc7feSJohan Hedberg memcpy(m + 16, v, 32); 325191dc7feSJohan Hedberg memcpy(m + 48, u, 32); 326191dc7feSJohan Hedberg 327191dc7feSJohan Hedberg err = aes_cmac(tfm_cmac, x, m, sizeof(m), tmp); 328191dc7feSJohan Hedberg if (err) 329191dc7feSJohan Hedberg return err; 330191dc7feSJohan Hedberg 331191dc7feSJohan Hedberg *val = get_unaligned_le32(tmp); 332191dc7feSJohan Hedberg *val %= 1000000; 333191dc7feSJohan Hedberg 334c7a3d57dSJohan Hedberg SMP_DBG("val %06u", *val); 335191dc7feSJohan Hedberg 336191dc7feSJohan Hedberg return 0; 337191dc7feSJohan Hedberg } 338191dc7feSJohan Hedberg 33971af2f6bSHerbert Xu static int smp_h6(struct crypto_shash *tfm_cmac, const u8 w[16], 34006edf8deSJohan Hedberg const u8 key_id[4], u8 res[16]) 34106edf8deSJohan Hedberg { 34206edf8deSJohan Hedberg int err; 34306edf8deSJohan Hedberg 34406edf8deSJohan Hedberg SMP_DBG("w %16phN key_id %4phN", w, key_id); 34506edf8deSJohan Hedberg 34606edf8deSJohan Hedberg err = aes_cmac(tfm_cmac, w, key_id, 4, res); 34706edf8deSJohan Hedberg if (err) 34806edf8deSJohan Hedberg return err; 34906edf8deSJohan Hedberg 35006edf8deSJohan Hedberg SMP_DBG("res %16phN", res); 35106edf8deSJohan Hedberg 35206edf8deSJohan Hedberg return err; 35306edf8deSJohan Hedberg } 35406edf8deSJohan Hedberg 355a62da6f1SJohan Hedberg static int smp_h7(struct crypto_shash *tfm_cmac, const u8 w[16], 356a62da6f1SJohan Hedberg const u8 salt[16], u8 res[16]) 357a62da6f1SJohan Hedberg { 358a62da6f1SJohan Hedberg int err; 359a62da6f1SJohan Hedberg 360a62da6f1SJohan Hedberg SMP_DBG("w %16phN salt %16phN", w, salt); 361a62da6f1SJohan Hedberg 362a62da6f1SJohan Hedberg err = aes_cmac(tfm_cmac, salt, w, 16, res); 363a62da6f1SJohan Hedberg if (err) 364a62da6f1SJohan Hedberg return err; 365a62da6f1SJohan Hedberg 366a62da6f1SJohan Hedberg SMP_DBG("res %16phN", res); 367a62da6f1SJohan Hedberg 368a62da6f1SJohan Hedberg return err; 369a62da6f1SJohan Hedberg } 370a62da6f1SJohan Hedberg 37106edf8deSJohan Hedberg /* The following functions map to the legacy SMP crypto functions e, c1, 37206edf8deSJohan Hedberg * s1 and ah. 37306edf8deSJohan Hedberg */ 37406edf8deSJohan Hedberg 37528a220aaSArd Biesheuvel static int smp_e(const u8 *k, u8 *r) 376d22ef0bcSAnderson Briglia { 37728a220aaSArd Biesheuvel struct crypto_aes_ctx ctx; 378943a732aSJohan Hedberg uint8_t tmp[16], data[16]; 379201a5929SJohan Hedberg int err; 380d22ef0bcSAnderson Briglia 381011c391aSJohan Hedberg SMP_DBG("k %16phN r %16phN", k, r); 382011c391aSJohan Hedberg 383943a732aSJohan Hedberg /* The most significant octet of key corresponds to k[0] */ 3848a2936f4SJohan Hedberg swap_buf(k, tmp, 16); 385943a732aSJohan Hedberg 38628a220aaSArd Biesheuvel err = aes_expandkey(&ctx, tmp, 16); 387d22ef0bcSAnderson Briglia if (err) { 388d22ef0bcSAnderson Briglia BT_ERR("cipher setkey failed: %d", err); 389d22ef0bcSAnderson Briglia return err; 390d22ef0bcSAnderson Briglia } 391d22ef0bcSAnderson Briglia 392943a732aSJohan Hedberg /* Most significant octet of plaintextData corresponds to data[0] */ 3938a2936f4SJohan Hedberg swap_buf(r, data, 16); 394943a732aSJohan Hedberg 39528a220aaSArd Biesheuvel aes_encrypt(&ctx, data, data); 396d22ef0bcSAnderson Briglia 397943a732aSJohan Hedberg /* Most significant octet of encryptedData corresponds to data[0] */ 3988a2936f4SJohan Hedberg swap_buf(data, r, 16); 399943a732aSJohan Hedberg 400011c391aSJohan Hedberg SMP_DBG("r %16phN", r); 401011c391aSJohan Hedberg 40228a220aaSArd Biesheuvel memzero_explicit(&ctx, sizeof (ctx)); 403d22ef0bcSAnderson Briglia return err; 404d22ef0bcSAnderson Briglia } 405d22ef0bcSAnderson Briglia 40628a220aaSArd Biesheuvel static int smp_c1(const u8 k[16], 40706edf8deSJohan Hedberg const u8 r[16], const u8 preq[7], const u8 pres[7], u8 _iat, 40806edf8deSJohan Hedberg const bdaddr_t *ia, u8 _rat, const bdaddr_t *ra, u8 res[16]) 40906edf8deSJohan Hedberg { 41006edf8deSJohan Hedberg u8 p1[16], p2[16]; 41106edf8deSJohan Hedberg int err; 41206edf8deSJohan Hedberg 413011c391aSJohan Hedberg SMP_DBG("k %16phN r %16phN", k, r); 414011c391aSJohan Hedberg SMP_DBG("iat %u ia %6phN rat %u ra %6phN", _iat, ia, _rat, ra); 415011c391aSJohan Hedberg SMP_DBG("preq %7phN pres %7phN", preq, pres); 416011c391aSJohan Hedberg 41706edf8deSJohan Hedberg memset(p1, 0, 16); 41806edf8deSJohan Hedberg 41906edf8deSJohan Hedberg /* p1 = pres || preq || _rat || _iat */ 42006edf8deSJohan Hedberg p1[0] = _iat; 42106edf8deSJohan Hedberg p1[1] = _rat; 42206edf8deSJohan Hedberg memcpy(p1 + 2, preq, 7); 42306edf8deSJohan Hedberg memcpy(p1 + 9, pres, 7); 42406edf8deSJohan Hedberg 425011c391aSJohan Hedberg SMP_DBG("p1 %16phN", p1); 42606edf8deSJohan Hedberg 42706edf8deSJohan Hedberg /* res = r XOR p1 */ 42806edf8deSJohan Hedberg u128_xor((u128 *) res, (u128 *) r, (u128 *) p1); 42906edf8deSJohan Hedberg 43006edf8deSJohan Hedberg /* res = e(k, res) */ 43128a220aaSArd Biesheuvel err = smp_e(k, res); 43206edf8deSJohan Hedberg if (err) { 43306edf8deSJohan Hedberg BT_ERR("Encrypt data error"); 43406edf8deSJohan Hedberg return err; 43506edf8deSJohan Hedberg } 43606edf8deSJohan Hedberg 437011c391aSJohan Hedberg /* p2 = padding || ia || ra */ 438011c391aSJohan Hedberg memcpy(p2, ra, 6); 439011c391aSJohan Hedberg memcpy(p2 + 6, ia, 6); 440011c391aSJohan Hedberg memset(p2 + 12, 0, 4); 441011c391aSJohan Hedberg 442011c391aSJohan Hedberg SMP_DBG("p2 %16phN", p2); 443011c391aSJohan Hedberg 44406edf8deSJohan Hedberg /* res = res XOR p2 */ 44506edf8deSJohan Hedberg u128_xor((u128 *) res, (u128 *) res, (u128 *) p2); 44606edf8deSJohan Hedberg 44706edf8deSJohan Hedberg /* res = e(k, res) */ 44828a220aaSArd Biesheuvel err = smp_e(k, res); 44906edf8deSJohan Hedberg if (err) 45006edf8deSJohan Hedberg BT_ERR("Encrypt data error"); 45106edf8deSJohan Hedberg 45206edf8deSJohan Hedberg return err; 45306edf8deSJohan Hedberg } 45406edf8deSJohan Hedberg 45528a220aaSArd Biesheuvel static int smp_s1(const u8 k[16], 45606edf8deSJohan Hedberg const u8 r1[16], const u8 r2[16], u8 _r[16]) 4576a77083aSJohan Hedberg { 4586a77083aSJohan Hedberg int err; 4596a77083aSJohan Hedberg 46006edf8deSJohan Hedberg /* Just least significant octets from r1 and r2 are considered */ 46106edf8deSJohan Hedberg memcpy(_r, r2, 8); 46206edf8deSJohan Hedberg memcpy(_r + 8, r1, 8); 4636a77083aSJohan Hedberg 46428a220aaSArd Biesheuvel err = smp_e(k, _r); 4656a77083aSJohan Hedberg if (err) 46606edf8deSJohan Hedberg BT_ERR("Encrypt data error"); 4676a77083aSJohan Hedberg 4686a77083aSJohan Hedberg return err; 4696a77083aSJohan Hedberg } 4706a77083aSJohan Hedberg 47128a220aaSArd Biesheuvel static int smp_ah(const u8 irk[16], const u8 r[3], u8 res[3]) 47260478054SJohan Hedberg { 473943a732aSJohan Hedberg u8 _res[16]; 47460478054SJohan Hedberg int err; 47560478054SJohan Hedberg 47660478054SJohan Hedberg /* r' = padding || r */ 477943a732aSJohan Hedberg memcpy(_res, r, 3); 478943a732aSJohan Hedberg memset(_res + 3, 0, 13); 47960478054SJohan Hedberg 48028a220aaSArd Biesheuvel err = smp_e(irk, _res); 48160478054SJohan Hedberg if (err) { 48260478054SJohan Hedberg BT_ERR("Encrypt error"); 48360478054SJohan Hedberg return err; 48460478054SJohan Hedberg } 48560478054SJohan Hedberg 48660478054SJohan Hedberg /* The output of the random address function ah is: 487c5080d42SMarcel Holtmann * ah(k, r) = e(k, r') mod 2^24 48860478054SJohan Hedberg * The output of the security function e is then truncated to 24 bits 48960478054SJohan Hedberg * by taking the least significant 24 bits of the output of e as the 49060478054SJohan Hedberg * result of ah. 49160478054SJohan Hedberg */ 492943a732aSJohan Hedberg memcpy(res, _res, 3); 49360478054SJohan Hedberg 49460478054SJohan Hedberg return 0; 49560478054SJohan Hedberg } 49660478054SJohan Hedberg 497cd082797SJohan Hedberg bool smp_irk_matches(struct hci_dev *hdev, const u8 irk[16], 498cd082797SJohan Hedberg const bdaddr_t *bdaddr) 49960478054SJohan Hedberg { 500defce9e8SJohan Hedberg struct l2cap_chan *chan = hdev->smp_data; 50160478054SJohan Hedberg u8 hash[3]; 50260478054SJohan Hedberg int err; 50360478054SJohan Hedberg 504defce9e8SJohan Hedberg if (!chan || !chan->data) 505defce9e8SJohan Hedberg return false; 506defce9e8SJohan Hedberg 50756860245SMarcel Holtmann bt_dev_dbg(hdev, "RPA %pMR IRK %*phN", bdaddr, 16, irk); 50860478054SJohan Hedberg 50928a220aaSArd Biesheuvel err = smp_ah(irk, &bdaddr->b[3], hash); 51060478054SJohan Hedberg if (err) 51160478054SJohan Hedberg return false; 51260478054SJohan Hedberg 513329d8230SJason A. Donenfeld return !crypto_memneq(bdaddr->b, hash, 3); 51460478054SJohan Hedberg } 51560478054SJohan Hedberg 516cd082797SJohan Hedberg int smp_generate_rpa(struct hci_dev *hdev, const u8 irk[16], bdaddr_t *rpa) 517b1e2b3aeSJohan Hedberg { 518defce9e8SJohan Hedberg struct l2cap_chan *chan = hdev->smp_data; 519b1e2b3aeSJohan Hedberg int err; 520b1e2b3aeSJohan Hedberg 521defce9e8SJohan Hedberg if (!chan || !chan->data) 522defce9e8SJohan Hedberg return -EOPNOTSUPP; 523defce9e8SJohan Hedberg 524b1e2b3aeSJohan Hedberg get_random_bytes(&rpa->b[3], 3); 525b1e2b3aeSJohan Hedberg 526b1e2b3aeSJohan Hedberg rpa->b[5] &= 0x3f; /* Clear two most significant bits */ 527b1e2b3aeSJohan Hedberg rpa->b[5] |= 0x40; /* Set second most significant bit */ 528b1e2b3aeSJohan Hedberg 52928a220aaSArd Biesheuvel err = smp_ah(irk, &rpa->b[3], rpa->b); 530b1e2b3aeSJohan Hedberg if (err < 0) 531b1e2b3aeSJohan Hedberg return err; 532b1e2b3aeSJohan Hedberg 53356860245SMarcel Holtmann bt_dev_dbg(hdev, "RPA %pMR", rpa); 534b1e2b3aeSJohan Hedberg 535b1e2b3aeSJohan Hedberg return 0; 536b1e2b3aeSJohan Hedberg } 537b1e2b3aeSJohan Hedberg 53860a27d65SMarcel Holtmann int smp_generate_oob(struct hci_dev *hdev, u8 hash[16], u8 rand[16]) 53960a27d65SMarcel Holtmann { 54060a27d65SMarcel Holtmann struct l2cap_chan *chan = hdev->smp_data; 54160a27d65SMarcel Holtmann struct smp_dev *smp; 54260a27d65SMarcel Holtmann int err; 54360a27d65SMarcel Holtmann 54460a27d65SMarcel Holtmann if (!chan || !chan->data) 54560a27d65SMarcel Holtmann return -EOPNOTSUPP; 54660a27d65SMarcel Holtmann 54760a27d65SMarcel Holtmann smp = chan->data; 54860a27d65SMarcel Holtmann 54960a27d65SMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS)) { 55056860245SMarcel Holtmann bt_dev_dbg(hdev, "Using debug keys"); 551c0153b0bSTudor Ambarus err = set_ecdh_privkey(smp->tfm_ecdh, debug_sk); 552c0153b0bSTudor Ambarus if (err) 553c0153b0bSTudor Ambarus return err; 55460a27d65SMarcel Holtmann memcpy(smp->local_pk, debug_pk, 64); 55560a27d65SMarcel Holtmann smp->debug_key = true; 55660a27d65SMarcel Holtmann } else { 55760a27d65SMarcel Holtmann while (true) { 558c0153b0bSTudor Ambarus /* Generate key pair for Secure Connections */ 559c0153b0bSTudor Ambarus err = generate_ecdh_keys(smp->tfm_ecdh, smp->local_pk); 560a2976416STudor Ambarus if (err) 561a2976416STudor Ambarus return err; 56260a27d65SMarcel Holtmann 56360a27d65SMarcel Holtmann /* This is unlikely, but we need to check that 56460a27d65SMarcel Holtmann * we didn't accidentially generate a debug key. 56560a27d65SMarcel Holtmann */ 566c0153b0bSTudor Ambarus if (crypto_memneq(smp->local_pk, debug_pk, 64)) 56760a27d65SMarcel Holtmann break; 56860a27d65SMarcel Holtmann } 56960a27d65SMarcel Holtmann smp->debug_key = false; 57060a27d65SMarcel Holtmann } 57160a27d65SMarcel Holtmann 57260a27d65SMarcel Holtmann SMP_DBG("OOB Public Key X: %32phN", smp->local_pk); 57360a27d65SMarcel Holtmann SMP_DBG("OOB Public Key Y: %32phN", smp->local_pk + 32); 57460a27d65SMarcel Holtmann 575fb334feeSMarcel Holtmann get_random_bytes(smp->local_rand, 16); 57660a27d65SMarcel Holtmann 57760a27d65SMarcel Holtmann err = smp_f4(smp->tfm_cmac, smp->local_pk, smp->local_pk, 578fb334feeSMarcel Holtmann smp->local_rand, 0, hash); 57960a27d65SMarcel Holtmann if (err < 0) 58060a27d65SMarcel Holtmann return err; 58160a27d65SMarcel Holtmann 582fb334feeSMarcel Holtmann memcpy(rand, smp->local_rand, 16); 58360a27d65SMarcel Holtmann 58494f14e47SJohan Hedberg smp->local_oob = true; 58594f14e47SJohan Hedberg 58660a27d65SMarcel Holtmann return 0; 58760a27d65SMarcel Holtmann } 58860a27d65SMarcel Holtmann 589eb492e01SAnderson Briglia static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data) 590eb492e01SAnderson Briglia { 5915d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 592b68fda68SJohan Hedberg struct smp_chan *smp; 5935d88cc73SJohan Hedberg struct kvec iv[2]; 5945d88cc73SJohan Hedberg struct msghdr msg; 5955d88cc73SJohan Hedberg 5965d88cc73SJohan Hedberg if (!chan) 5975d88cc73SJohan Hedberg return; 598eb492e01SAnderson Briglia 599eb492e01SAnderson Briglia BT_DBG("code 0x%2.2x", code); 600eb492e01SAnderson Briglia 6015d88cc73SJohan Hedberg iv[0].iov_base = &code; 6025d88cc73SJohan Hedberg iv[0].iov_len = 1; 603eb492e01SAnderson Briglia 6045d88cc73SJohan Hedberg iv[1].iov_base = data; 6055d88cc73SJohan Hedberg iv[1].iov_len = len; 6065d88cc73SJohan Hedberg 6075d88cc73SJohan Hedberg memset(&msg, 0, sizeof(msg)); 6085d88cc73SJohan Hedberg 609aa563d7bSDavid Howells iov_iter_kvec(&msg.msg_iter, WRITE, iv, 2, 1 + len); 6105d88cc73SJohan Hedberg 6115d88cc73SJohan Hedberg l2cap_chan_send(chan, &msg, 1 + len); 612e2dcd113SVinicius Costa Gomes 613b68fda68SJohan Hedberg if (!chan->data) 614b68fda68SJohan Hedberg return; 615b68fda68SJohan Hedberg 616b68fda68SJohan Hedberg smp = chan->data; 617b68fda68SJohan Hedberg 618b68fda68SJohan Hedberg cancel_delayed_work_sync(&smp->security_timer); 619b68fda68SJohan Hedberg schedule_delayed_work(&smp->security_timer, SMP_TIMEOUT); 620eb492e01SAnderson Briglia } 621eb492e01SAnderson Briglia 622d2eb9e10SJohan Hedberg static u8 authreq_to_seclevel(u8 authreq) 6232b64d153SBrian Gix { 624d2eb9e10SJohan Hedberg if (authreq & SMP_AUTH_MITM) { 625d2eb9e10SJohan Hedberg if (authreq & SMP_AUTH_SC) 626d2eb9e10SJohan Hedberg return BT_SECURITY_FIPS; 6272b64d153SBrian Gix else 628d2eb9e10SJohan Hedberg return BT_SECURITY_HIGH; 629d2eb9e10SJohan Hedberg } else { 6302b64d153SBrian Gix return BT_SECURITY_MEDIUM; 6312b64d153SBrian Gix } 632d2eb9e10SJohan Hedberg } 6332b64d153SBrian Gix 6342b64d153SBrian Gix static __u8 seclevel_to_authreq(__u8 sec_level) 6352b64d153SBrian Gix { 6362b64d153SBrian Gix switch (sec_level) { 637d2eb9e10SJohan Hedberg case BT_SECURITY_FIPS: 6382b64d153SBrian Gix case BT_SECURITY_HIGH: 6392b64d153SBrian Gix return SMP_AUTH_MITM | SMP_AUTH_BONDING; 6402b64d153SBrian Gix case BT_SECURITY_MEDIUM: 6412b64d153SBrian Gix return SMP_AUTH_BONDING; 6422b64d153SBrian Gix default: 6432b64d153SBrian Gix return SMP_AUTH_NONE; 6442b64d153SBrian Gix } 6452b64d153SBrian Gix } 6462b64d153SBrian Gix 647b8e66eacSVinicius Costa Gomes static void build_pairing_cmd(struct l2cap_conn *conn, 64854790f73SVinicius Costa Gomes struct smp_cmd_pairing *req, 649f1560463SMarcel Holtmann struct smp_cmd_pairing *rsp, __u8 authreq) 650b8e66eacSVinicius Costa Gomes { 6515d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 6525d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 653fd349c02SJohan Hedberg struct hci_conn *hcon = conn->hcon; 654fd349c02SJohan Hedberg struct hci_dev *hdev = hcon->hdev; 65502b05bd8SJohan Hedberg u8 local_dist = 0, remote_dist = 0, oob_flag = SMP_OOB_NOT_PRESENT; 65654790f73SVinicius Costa Gomes 657d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_BONDABLE)) { 6587ee4ea36SMarcel Holtmann local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN; 6597ee4ea36SMarcel Holtmann remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN; 66054790f73SVinicius Costa Gomes authreq |= SMP_AUTH_BONDING; 6612b64d153SBrian Gix } else { 6622b64d153SBrian Gix authreq &= ~SMP_AUTH_BONDING; 66354790f73SVinicius Costa Gomes } 66454790f73SVinicius Costa Gomes 665d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_RPA_RESOLVING)) 666fd349c02SJohan Hedberg remote_dist |= SMP_DIST_ID_KEY; 667fd349c02SJohan Hedberg 668d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_PRIVACY)) 669863efaf2SJohan Hedberg local_dist |= SMP_DIST_ID_KEY; 670863efaf2SJohan Hedberg 671d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SC_ENABLED) && 67202b05bd8SJohan Hedberg (authreq & SMP_AUTH_SC)) { 67302b05bd8SJohan Hedberg struct oob_data *oob_data; 67402b05bd8SJohan Hedberg u8 bdaddr_type; 67502b05bd8SJohan Hedberg 676d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SSP_ENABLED)) { 677df8e1a4cSJohan Hedberg local_dist |= SMP_DIST_LINK_KEY; 678df8e1a4cSJohan Hedberg remote_dist |= SMP_DIST_LINK_KEY; 679df8e1a4cSJohan Hedberg } 68002b05bd8SJohan Hedberg 68102b05bd8SJohan Hedberg if (hcon->dst_type == ADDR_LE_DEV_PUBLIC) 68202b05bd8SJohan Hedberg bdaddr_type = BDADDR_LE_PUBLIC; 68302b05bd8SJohan Hedberg else 68402b05bd8SJohan Hedberg bdaddr_type = BDADDR_LE_RANDOM; 68502b05bd8SJohan Hedberg 68602b05bd8SJohan Hedberg oob_data = hci_find_remote_oob_data(hdev, &hcon->dst, 68702b05bd8SJohan Hedberg bdaddr_type); 6884775a4eaSMarcel Holtmann if (oob_data && oob_data->present) { 6891a8bab4fSJohan Hedberg set_bit(SMP_FLAG_REMOTE_OOB, &smp->flags); 69002b05bd8SJohan Hedberg oob_flag = SMP_OOB_PRESENT; 691a29b0733SJohan Hedberg memcpy(smp->rr, oob_data->rand256, 16); 69202b05bd8SJohan Hedberg memcpy(smp->pcnf, oob_data->hash256, 16); 693bc07cd69SMarcel Holtmann SMP_DBG("OOB Remote Confirmation: %16phN", smp->pcnf); 694bc07cd69SMarcel Holtmann SMP_DBG("OOB Remote Random: %16phN", smp->rr); 69502b05bd8SJohan Hedberg } 69602b05bd8SJohan Hedberg 697df8e1a4cSJohan Hedberg } else { 698df8e1a4cSJohan Hedberg authreq &= ~SMP_AUTH_SC; 699df8e1a4cSJohan Hedberg } 700df8e1a4cSJohan Hedberg 70154790f73SVinicius Costa Gomes if (rsp == NULL) { 70254790f73SVinicius Costa Gomes req->io_capability = conn->hcon->io_capability; 70302b05bd8SJohan Hedberg req->oob_flag = oob_flag; 70430d65e08SMatias Karhumaa req->max_key_size = hdev->le_max_key_size; 705fd349c02SJohan Hedberg req->init_key_dist = local_dist; 706fd349c02SJohan Hedberg req->resp_key_dist = remote_dist; 7070edb14deSJohan Hedberg req->auth_req = (authreq & AUTH_REQ_MASK(hdev)); 708fd349c02SJohan Hedberg 709fd349c02SJohan Hedberg smp->remote_key_dist = remote_dist; 71054790f73SVinicius Costa Gomes return; 71154790f73SVinicius Costa Gomes } 71254790f73SVinicius Costa Gomes 71354790f73SVinicius Costa Gomes rsp->io_capability = conn->hcon->io_capability; 71402b05bd8SJohan Hedberg rsp->oob_flag = oob_flag; 71530d65e08SMatias Karhumaa rsp->max_key_size = hdev->le_max_key_size; 716fd349c02SJohan Hedberg rsp->init_key_dist = req->init_key_dist & remote_dist; 717fd349c02SJohan Hedberg rsp->resp_key_dist = req->resp_key_dist & local_dist; 7180edb14deSJohan Hedberg rsp->auth_req = (authreq & AUTH_REQ_MASK(hdev)); 719fd349c02SJohan Hedberg 720fd349c02SJohan Hedberg smp->remote_key_dist = rsp->init_key_dist; 721b8e66eacSVinicius Costa Gomes } 722b8e66eacSVinicius Costa Gomes 7233158c50cSVinicius Costa Gomes static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size) 7243158c50cSVinicius Costa Gomes { 7255d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 7262fd36558SJohan Hedberg struct hci_dev *hdev = conn->hcon->hdev; 7275d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 7281c1def09SVinicius Costa Gomes 72949c06c9eSŁukasz Rymanowski if (conn->hcon->pending_sec_level == BT_SECURITY_FIPS && 73049c06c9eSŁukasz Rymanowski max_key_size != SMP_MAX_ENC_KEY_SIZE) 73149c06c9eSŁukasz Rymanowski return SMP_ENC_KEY_SIZE; 73249c06c9eSŁukasz Rymanowski 73330d65e08SMatias Karhumaa if (max_key_size > hdev->le_max_key_size || 7342fd36558SJohan Hedberg max_key_size < SMP_MIN_ENC_KEY_SIZE) 7353158c50cSVinicius Costa Gomes return SMP_ENC_KEY_SIZE; 7363158c50cSVinicius Costa Gomes 737f7aa611aSVinicius Costa Gomes smp->enc_key_size = max_key_size; 7383158c50cSVinicius Costa Gomes 7393158c50cSVinicius Costa Gomes return 0; 7403158c50cSVinicius Costa Gomes } 7413158c50cSVinicius Costa Gomes 7426f48e260SJohan Hedberg static void smp_chan_destroy(struct l2cap_conn *conn) 7436f48e260SJohan Hedberg { 7446f48e260SJohan Hedberg struct l2cap_chan *chan = conn->smp; 7456f48e260SJohan Hedberg struct smp_chan *smp = chan->data; 746923e2414SJohan Hedberg struct hci_conn *hcon = conn->hcon; 7476f48e260SJohan Hedberg bool complete; 7486f48e260SJohan Hedberg 7496f48e260SJohan Hedberg BUG_ON(!smp); 7506f48e260SJohan Hedberg 7516f48e260SJohan Hedberg cancel_delayed_work_sync(&smp->security_timer); 7526f48e260SJohan Hedberg 7536f48e260SJohan Hedberg complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags); 754923e2414SJohan Hedberg mgmt_smp_complete(hcon, complete); 7556f48e260SJohan Hedberg 756453431a5SWaiman Long kfree_sensitive(smp->csrk); 757453431a5SWaiman Long kfree_sensitive(smp->slave_csrk); 758453431a5SWaiman Long kfree_sensitive(smp->link_key); 7596f48e260SJohan Hedberg 76071af2f6bSHerbert Xu crypto_free_shash(smp->tfm_cmac); 76147eb2ac8STudor Ambarus crypto_free_kpp(smp->tfm_ecdh); 7626f48e260SJohan Hedberg 763923e2414SJohan Hedberg /* Ensure that we don't leave any debug key around if debug key 764923e2414SJohan Hedberg * support hasn't been explicitly enabled. 765923e2414SJohan Hedberg */ 766923e2414SJohan Hedberg if (smp->ltk && smp->ltk->type == SMP_LTK_P256_DEBUG && 767d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hcon->hdev, HCI_KEEP_DEBUG_KEYS)) { 768923e2414SJohan Hedberg list_del_rcu(&smp->ltk->list); 769923e2414SJohan Hedberg kfree_rcu(smp->ltk, rcu); 770923e2414SJohan Hedberg smp->ltk = NULL; 771923e2414SJohan Hedberg } 772923e2414SJohan Hedberg 7736f48e260SJohan Hedberg /* If pairing failed clean up any keys we might have */ 7746f48e260SJohan Hedberg if (!complete) { 7756f48e260SJohan Hedberg if (smp->ltk) { 776970d0f1bSJohan Hedberg list_del_rcu(&smp->ltk->list); 777970d0f1bSJohan Hedberg kfree_rcu(smp->ltk, rcu); 7786f48e260SJohan Hedberg } 7796f48e260SJohan Hedberg 7806f48e260SJohan Hedberg if (smp->slave_ltk) { 781970d0f1bSJohan Hedberg list_del_rcu(&smp->slave_ltk->list); 782970d0f1bSJohan Hedberg kfree_rcu(smp->slave_ltk, rcu); 7836f48e260SJohan Hedberg } 7846f48e260SJohan Hedberg 7856f48e260SJohan Hedberg if (smp->remote_irk) { 786adae20cbSJohan Hedberg list_del_rcu(&smp->remote_irk->list); 787adae20cbSJohan Hedberg kfree_rcu(smp->remote_irk, rcu); 7886f48e260SJohan Hedberg } 7896f48e260SJohan Hedberg } 7906f48e260SJohan Hedberg 7916f48e260SJohan Hedberg chan->data = NULL; 792453431a5SWaiman Long kfree_sensitive(smp); 793923e2414SJohan Hedberg hci_conn_drop(hcon); 7946f48e260SJohan Hedberg } 7956f48e260SJohan Hedberg 79684794e11SJohan Hedberg static void smp_failure(struct l2cap_conn *conn, u8 reason) 7974f957a76SBrian Gix { 798bab73cb6SJohan Hedberg struct hci_conn *hcon = conn->hcon; 799b68fda68SJohan Hedberg struct l2cap_chan *chan = conn->smp; 800bab73cb6SJohan Hedberg 80184794e11SJohan Hedberg if (reason) 8024f957a76SBrian Gix smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason), 8034f957a76SBrian Gix &reason); 8044f957a76SBrian Gix 805e1e930f5SJohan Hedberg mgmt_auth_failed(hcon, HCI_ERROR_AUTH_FAILURE); 806f1c09c07SVinicius Costa Gomes 807fc75cc86SJohan Hedberg if (chan->data) 8084f957a76SBrian Gix smp_chan_destroy(conn); 8094f957a76SBrian Gix } 8104f957a76SBrian Gix 8112b64d153SBrian Gix #define JUST_WORKS 0x00 8122b64d153SBrian Gix #define JUST_CFM 0x01 8132b64d153SBrian Gix #define REQ_PASSKEY 0x02 8142b64d153SBrian Gix #define CFM_PASSKEY 0x03 8152b64d153SBrian Gix #define REQ_OOB 0x04 8165e3d3d9bSJohan Hedberg #define DSP_PASSKEY 0x05 8172b64d153SBrian Gix #define OVERLAP 0xFF 8182b64d153SBrian Gix 8192b64d153SBrian Gix static const u8 gen_method[5][5] = { 8202b64d153SBrian Gix { JUST_WORKS, JUST_CFM, REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY }, 8212b64d153SBrian Gix { JUST_WORKS, JUST_CFM, REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY }, 8222b64d153SBrian Gix { CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY }, 8232b64d153SBrian Gix { JUST_WORKS, JUST_CFM, JUST_WORKS, JUST_WORKS, JUST_CFM }, 8242b64d153SBrian Gix { CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, OVERLAP }, 8252b64d153SBrian Gix }; 8262b64d153SBrian Gix 8275e3d3d9bSJohan Hedberg static const u8 sc_method[5][5] = { 8285e3d3d9bSJohan Hedberg { JUST_WORKS, JUST_CFM, REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY }, 8295e3d3d9bSJohan Hedberg { JUST_WORKS, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY }, 8305e3d3d9bSJohan Hedberg { DSP_PASSKEY, DSP_PASSKEY, REQ_PASSKEY, JUST_WORKS, DSP_PASSKEY }, 8315e3d3d9bSJohan Hedberg { JUST_WORKS, JUST_CFM, JUST_WORKS, JUST_WORKS, JUST_CFM }, 8325e3d3d9bSJohan Hedberg { DSP_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY }, 8335e3d3d9bSJohan Hedberg }; 8345e3d3d9bSJohan Hedberg 835581370ccSJohan Hedberg static u8 get_auth_method(struct smp_chan *smp, u8 local_io, u8 remote_io) 836581370ccSJohan Hedberg { 8372bcd4003SJohan Hedberg /* If either side has unknown io_caps, use JUST_CFM (which gets 8382bcd4003SJohan Hedberg * converted later to JUST_WORKS if we're initiators. 8392bcd4003SJohan Hedberg */ 840581370ccSJohan Hedberg if (local_io > SMP_IO_KEYBOARD_DISPLAY || 841581370ccSJohan Hedberg remote_io > SMP_IO_KEYBOARD_DISPLAY) 8422bcd4003SJohan Hedberg return JUST_CFM; 843581370ccSJohan Hedberg 8445e3d3d9bSJohan Hedberg if (test_bit(SMP_FLAG_SC, &smp->flags)) 8455e3d3d9bSJohan Hedberg return sc_method[remote_io][local_io]; 8465e3d3d9bSJohan Hedberg 847581370ccSJohan Hedberg return gen_method[remote_io][local_io]; 848581370ccSJohan Hedberg } 849581370ccSJohan Hedberg 8502b64d153SBrian Gix static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth, 8512b64d153SBrian Gix u8 local_io, u8 remote_io) 8522b64d153SBrian Gix { 8532b64d153SBrian Gix struct hci_conn *hcon = conn->hcon; 8545d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 8555d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 8562b64d153SBrian Gix u32 passkey = 0; 857d1d900f8SGuenter Roeck int ret; 8582b64d153SBrian Gix 8592b64d153SBrian Gix /* Initialize key for JUST WORKS */ 8602b64d153SBrian Gix memset(smp->tk, 0, sizeof(smp->tk)); 8614a74d658SJohan Hedberg clear_bit(SMP_FLAG_TK_VALID, &smp->flags); 8622b64d153SBrian Gix 8632b64d153SBrian Gix BT_DBG("tk_request: auth:%d lcl:%d rem:%d", auth, local_io, remote_io); 8642b64d153SBrian Gix 8652bcd4003SJohan Hedberg /* If neither side wants MITM, either "just" confirm an incoming 8662bcd4003SJohan Hedberg * request or use just-works for outgoing ones. The JUST_CFM 8672bcd4003SJohan Hedberg * will be converted to JUST_WORKS if necessary later in this 8682bcd4003SJohan Hedberg * function. If either side has MITM look up the method from the 8692bcd4003SJohan Hedberg * table. 8702bcd4003SJohan Hedberg */ 871581370ccSJohan Hedberg if (!(auth & SMP_AUTH_MITM)) 872783e0574SJohan Hedberg smp->method = JUST_CFM; 8732b64d153SBrian Gix else 874783e0574SJohan Hedberg smp->method = get_auth_method(smp, local_io, remote_io); 8752b64d153SBrian Gix 876a82505c7SJohan Hedberg /* Don't confirm locally initiated pairing attempts */ 877783e0574SJohan Hedberg if (smp->method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR, 878783e0574SJohan Hedberg &smp->flags)) 879783e0574SJohan Hedberg smp->method = JUST_WORKS; 880a82505c7SJohan Hedberg 88102f3e254SJohan Hedberg /* Don't bother user space with no IO capabilities */ 882783e0574SJohan Hedberg if (smp->method == JUST_CFM && 883783e0574SJohan Hedberg hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT) 884783e0574SJohan Hedberg smp->method = JUST_WORKS; 88502f3e254SJohan Hedberg 88692516cd9SSonny Sasaka /* If Just Works, Continue with Zero TK and ask user-space for 88792516cd9SSonny Sasaka * confirmation */ 888783e0574SJohan Hedberg if (smp->method == JUST_WORKS) { 889d1d900f8SGuenter Roeck ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst, 89092516cd9SSonny Sasaka hcon->type, 89192516cd9SSonny Sasaka hcon->dst_type, 89292516cd9SSonny Sasaka passkey, 1); 893d1d900f8SGuenter Roeck if (ret) 894d1d900f8SGuenter Roeck return ret; 89592516cd9SSonny Sasaka set_bit(SMP_FLAG_WAIT_USER, &smp->flags); 8962b64d153SBrian Gix return 0; 8972b64d153SBrian Gix } 8982b64d153SBrian Gix 89919c5ce9cSJohan Hedberg /* If this function is used for SC -> legacy fallback we 90019c5ce9cSJohan Hedberg * can only recover the just-works case. 90119c5ce9cSJohan Hedberg */ 90219c5ce9cSJohan Hedberg if (test_bit(SMP_FLAG_SC, &smp->flags)) 90319c5ce9cSJohan Hedberg return -EINVAL; 90419c5ce9cSJohan Hedberg 9052b64d153SBrian Gix /* Not Just Works/Confirm results in MITM Authentication */ 906783e0574SJohan Hedberg if (smp->method != JUST_CFM) { 9074a74d658SJohan Hedberg set_bit(SMP_FLAG_MITM_AUTH, &smp->flags); 9085eb596f5SJohan Hedberg if (hcon->pending_sec_level < BT_SECURITY_HIGH) 9095eb596f5SJohan Hedberg hcon->pending_sec_level = BT_SECURITY_HIGH; 9105eb596f5SJohan Hedberg } 9112b64d153SBrian Gix 9122b64d153SBrian Gix /* If both devices have Keyoard-Display I/O, the master 9132b64d153SBrian Gix * Confirms and the slave Enters the passkey. 9142b64d153SBrian Gix */ 915783e0574SJohan Hedberg if (smp->method == OVERLAP) { 91640bef302SJohan Hedberg if (hcon->role == HCI_ROLE_MASTER) 917783e0574SJohan Hedberg smp->method = CFM_PASSKEY; 9182b64d153SBrian Gix else 919783e0574SJohan Hedberg smp->method = REQ_PASSKEY; 9202b64d153SBrian Gix } 9212b64d153SBrian Gix 92201ad34d2SJohan Hedberg /* Generate random passkey. */ 923783e0574SJohan Hedberg if (smp->method == CFM_PASSKEY) { 924943a732aSJohan Hedberg memset(smp->tk, 0, sizeof(smp->tk)); 9252b64d153SBrian Gix get_random_bytes(&passkey, sizeof(passkey)); 9262b64d153SBrian Gix passkey %= 1000000; 927943a732aSJohan Hedberg put_unaligned_le32(passkey, smp->tk); 9282b64d153SBrian Gix BT_DBG("PassKey: %d", passkey); 9294a74d658SJohan Hedberg set_bit(SMP_FLAG_TK_VALID, &smp->flags); 9302b64d153SBrian Gix } 9312b64d153SBrian Gix 932783e0574SJohan Hedberg if (smp->method == REQ_PASSKEY) 933ce39fb4eSMarcel Holtmann ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst, 934272d90dfSJohan Hedberg hcon->type, hcon->dst_type); 935783e0574SJohan Hedberg else if (smp->method == JUST_CFM) 9364eb65e66SJohan Hedberg ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst, 9374eb65e66SJohan Hedberg hcon->type, hcon->dst_type, 9384eb65e66SJohan Hedberg passkey, 1); 9392b64d153SBrian Gix else 94001ad34d2SJohan Hedberg ret = mgmt_user_passkey_notify(hcon->hdev, &hcon->dst, 941272d90dfSJohan Hedberg hcon->type, hcon->dst_type, 94239adbffeSJohan Hedberg passkey, 0); 9432b64d153SBrian Gix 9442b64d153SBrian Gix return ret; 9452b64d153SBrian Gix } 9462b64d153SBrian Gix 9471cc61144SJohan Hedberg static u8 smp_confirm(struct smp_chan *smp) 9488aab4757SVinicius Costa Gomes { 9498aab4757SVinicius Costa Gomes struct l2cap_conn *conn = smp->conn; 9508aab4757SVinicius Costa Gomes struct smp_cmd_pairing_confirm cp; 9518aab4757SVinicius Costa Gomes int ret; 9528aab4757SVinicius Costa Gomes 9538aab4757SVinicius Costa Gomes BT_DBG("conn %p", conn); 9548aab4757SVinicius Costa Gomes 95528a220aaSArd Biesheuvel ret = smp_c1(smp->tk, smp->prnd, smp->preq, smp->prsp, 956b1cd5fd9SJohan Hedberg conn->hcon->init_addr_type, &conn->hcon->init_addr, 957943a732aSJohan Hedberg conn->hcon->resp_addr_type, &conn->hcon->resp_addr, 958943a732aSJohan Hedberg cp.confirm_val); 9591cc61144SJohan Hedberg if (ret) 9601cc61144SJohan Hedberg return SMP_UNSPECIFIED; 9618aab4757SVinicius Costa Gomes 9624a74d658SJohan Hedberg clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags); 9632b64d153SBrian Gix 9648aab4757SVinicius Costa Gomes smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp); 9658aab4757SVinicius Costa Gomes 966b28b4943SJohan Hedberg if (conn->hcon->out) 967b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); 968b28b4943SJohan Hedberg else 969b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM); 970b28b4943SJohan Hedberg 9711cc61144SJohan Hedberg return 0; 9728aab4757SVinicius Costa Gomes } 9738aab4757SVinicius Costa Gomes 974861580a9SJohan Hedberg static u8 smp_random(struct smp_chan *smp) 9758aab4757SVinicius Costa Gomes { 9768aab4757SVinicius Costa Gomes struct l2cap_conn *conn = smp->conn; 9778aab4757SVinicius Costa Gomes struct hci_conn *hcon = conn->hcon; 978861580a9SJohan Hedberg u8 confirm[16]; 9798aab4757SVinicius Costa Gomes int ret; 9808aab4757SVinicius Costa Gomes 9818aab4757SVinicius Costa Gomes BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave"); 9828aab4757SVinicius Costa Gomes 98328a220aaSArd Biesheuvel ret = smp_c1(smp->tk, smp->rrnd, smp->preq, smp->prsp, 984b1cd5fd9SJohan Hedberg hcon->init_addr_type, &hcon->init_addr, 985943a732aSJohan Hedberg hcon->resp_addr_type, &hcon->resp_addr, confirm); 986861580a9SJohan Hedberg if (ret) 987861580a9SJohan Hedberg return SMP_UNSPECIFIED; 9888aab4757SVinicius Costa Gomes 989329d8230SJason A. Donenfeld if (crypto_memneq(smp->pcnf, confirm, sizeof(smp->pcnf))) { 9902064ee33SMarcel Holtmann bt_dev_err(hcon->hdev, "pairing failed " 9912064ee33SMarcel Holtmann "(confirmation values mismatch)"); 992861580a9SJohan Hedberg return SMP_CONFIRM_FAILED; 9938aab4757SVinicius Costa Gomes } 9948aab4757SVinicius Costa Gomes 9958aab4757SVinicius Costa Gomes if (hcon->out) { 996fe39c7b2SMarcel Holtmann u8 stk[16]; 997fe39c7b2SMarcel Holtmann __le64 rand = 0; 998fe39c7b2SMarcel Holtmann __le16 ediv = 0; 9998aab4757SVinicius Costa Gomes 100028a220aaSArd Biesheuvel smp_s1(smp->tk, smp->rrnd, smp->prnd, stk); 10018aab4757SVinicius Costa Gomes 1002861580a9SJohan Hedberg if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags)) 1003861580a9SJohan Hedberg return SMP_UNSPECIFIED; 10048aab4757SVinicius Costa Gomes 10058b76ce34SJohan Hedberg hci_le_start_enc(hcon, ediv, rand, stk, smp->enc_key_size); 1006f7aa611aSVinicius Costa Gomes hcon->enc_key_size = smp->enc_key_size; 1007fe59a05fSJohan Hedberg set_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags); 10088aab4757SVinicius Costa Gomes } else { 1009fff3490fSJohan Hedberg u8 stk[16], auth; 1010fe39c7b2SMarcel Holtmann __le64 rand = 0; 1011fe39c7b2SMarcel Holtmann __le16 ediv = 0; 10128aab4757SVinicius Costa Gomes 1013943a732aSJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd), 1014943a732aSJohan Hedberg smp->prnd); 10158aab4757SVinicius Costa Gomes 101628a220aaSArd Biesheuvel smp_s1(smp->tk, smp->prnd, smp->rrnd, stk); 10178aab4757SVinicius Costa Gomes 1018fff3490fSJohan Hedberg if (hcon->pending_sec_level == BT_SECURITY_HIGH) 1019fff3490fSJohan Hedberg auth = 1; 1020fff3490fSJohan Hedberg else 1021fff3490fSJohan Hedberg auth = 0; 1022fff3490fSJohan Hedberg 10237d5843b7SJohan Hedberg /* Even though there's no _SLAVE suffix this is the 10247d5843b7SJohan Hedberg * slave STK we're adding for later lookup (the master 10257d5843b7SJohan Hedberg * STK never needs to be stored). 10267d5843b7SJohan Hedberg */ 1027ce39fb4eSMarcel Holtmann hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, 10282ceba539SJohan Hedberg SMP_STK, auth, stk, smp->enc_key_size, ediv, rand); 10298aab4757SVinicius Costa Gomes } 10308aab4757SVinicius Costa Gomes 1031861580a9SJohan Hedberg return 0; 10328aab4757SVinicius Costa Gomes } 10338aab4757SVinicius Costa Gomes 103444f1a7abSJohan Hedberg static void smp_notify_keys(struct l2cap_conn *conn) 103544f1a7abSJohan Hedberg { 103644f1a7abSJohan Hedberg struct l2cap_chan *chan = conn->smp; 103744f1a7abSJohan Hedberg struct smp_chan *smp = chan->data; 103844f1a7abSJohan Hedberg struct hci_conn *hcon = conn->hcon; 103944f1a7abSJohan Hedberg struct hci_dev *hdev = hcon->hdev; 104044f1a7abSJohan Hedberg struct smp_cmd_pairing *req = (void *) &smp->preq[1]; 104144f1a7abSJohan Hedberg struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1]; 104244f1a7abSJohan Hedberg bool persistent; 104344f1a7abSJohan Hedberg 1044cad20c27SJohan Hedberg if (hcon->type == ACL_LINK) { 1045cad20c27SJohan Hedberg if (hcon->key_type == HCI_LK_DEBUG_COMBINATION) 1046cad20c27SJohan Hedberg persistent = false; 1047cad20c27SJohan Hedberg else 1048cad20c27SJohan Hedberg persistent = !test_bit(HCI_CONN_FLUSH_KEY, 1049cad20c27SJohan Hedberg &hcon->flags); 1050cad20c27SJohan Hedberg } else { 1051cad20c27SJohan Hedberg /* The LTKs, IRKs and CSRKs should be persistent only if 1052cad20c27SJohan Hedberg * both sides had the bonding bit set in their 1053cad20c27SJohan Hedberg * authentication requests. 1054cad20c27SJohan Hedberg */ 1055cad20c27SJohan Hedberg persistent = !!((req->auth_req & rsp->auth_req) & 1056cad20c27SJohan Hedberg SMP_AUTH_BONDING); 1057cad20c27SJohan Hedberg } 1058cad20c27SJohan Hedberg 105944f1a7abSJohan Hedberg if (smp->remote_irk) { 1060cad20c27SJohan Hedberg mgmt_new_irk(hdev, smp->remote_irk, persistent); 1061cad20c27SJohan Hedberg 106244f1a7abSJohan Hedberg /* Now that user space can be considered to know the 106344f1a7abSJohan Hedberg * identity address track the connection based on it 1064b5ae344dSJohan Hedberg * from now on (assuming this is an LE link). 106544f1a7abSJohan Hedberg */ 1066b5ae344dSJohan Hedberg if (hcon->type == LE_LINK) { 106744f1a7abSJohan Hedberg bacpy(&hcon->dst, &smp->remote_irk->bdaddr); 106844f1a7abSJohan Hedberg hcon->dst_type = smp->remote_irk->addr_type; 1069f3d82d0cSJohan Hedberg queue_work(hdev->workqueue, &conn->id_addr_update_work); 1070b5ae344dSJohan Hedberg } 107144f1a7abSJohan Hedberg } 107244f1a7abSJohan Hedberg 107344f1a7abSJohan Hedberg if (smp->csrk) { 107444f1a7abSJohan Hedberg smp->csrk->bdaddr_type = hcon->dst_type; 107544f1a7abSJohan Hedberg bacpy(&smp->csrk->bdaddr, &hcon->dst); 107644f1a7abSJohan Hedberg mgmt_new_csrk(hdev, smp->csrk, persistent); 107744f1a7abSJohan Hedberg } 107844f1a7abSJohan Hedberg 107944f1a7abSJohan Hedberg if (smp->slave_csrk) { 108044f1a7abSJohan Hedberg smp->slave_csrk->bdaddr_type = hcon->dst_type; 108144f1a7abSJohan Hedberg bacpy(&smp->slave_csrk->bdaddr, &hcon->dst); 108244f1a7abSJohan Hedberg mgmt_new_csrk(hdev, smp->slave_csrk, persistent); 108344f1a7abSJohan Hedberg } 108444f1a7abSJohan Hedberg 108544f1a7abSJohan Hedberg if (smp->ltk) { 108644f1a7abSJohan Hedberg smp->ltk->bdaddr_type = hcon->dst_type; 108744f1a7abSJohan Hedberg bacpy(&smp->ltk->bdaddr, &hcon->dst); 108844f1a7abSJohan Hedberg mgmt_new_ltk(hdev, smp->ltk, persistent); 108944f1a7abSJohan Hedberg } 109044f1a7abSJohan Hedberg 109144f1a7abSJohan Hedberg if (smp->slave_ltk) { 109244f1a7abSJohan Hedberg smp->slave_ltk->bdaddr_type = hcon->dst_type; 109344f1a7abSJohan Hedberg bacpy(&smp->slave_ltk->bdaddr, &hcon->dst); 109444f1a7abSJohan Hedberg mgmt_new_ltk(hdev, smp->slave_ltk, persistent); 109544f1a7abSJohan Hedberg } 10966a77083aSJohan Hedberg 10976a77083aSJohan Hedberg if (smp->link_key) { 1098e3befab9SJohan Hedberg struct link_key *key; 1099e3befab9SJohan Hedberg u8 type; 1100e3befab9SJohan Hedberg 1101e3befab9SJohan Hedberg if (test_bit(SMP_FLAG_DEBUG_KEY, &smp->flags)) 1102e3befab9SJohan Hedberg type = HCI_LK_DEBUG_COMBINATION; 1103e3befab9SJohan Hedberg else if (hcon->sec_level == BT_SECURITY_FIPS) 1104e3befab9SJohan Hedberg type = HCI_LK_AUTH_COMBINATION_P256; 1105e3befab9SJohan Hedberg else 1106e3befab9SJohan Hedberg type = HCI_LK_UNAUTH_COMBINATION_P256; 1107e3befab9SJohan Hedberg 1108e3befab9SJohan Hedberg key = hci_add_link_key(hdev, smp->conn->hcon, &hcon->dst, 1109e3befab9SJohan Hedberg smp->link_key, type, 0, &persistent); 1110e3befab9SJohan Hedberg if (key) { 1111e3befab9SJohan Hedberg mgmt_new_link_key(hdev, key, persistent); 1112e3befab9SJohan Hedberg 1113e3befab9SJohan Hedberg /* Don't keep debug keys around if the relevant 1114e3befab9SJohan Hedberg * flag is not set. 1115e3befab9SJohan Hedberg */ 1116d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_KEEP_DEBUG_KEYS) && 1117e3befab9SJohan Hedberg key->type == HCI_LK_DEBUG_COMBINATION) { 1118e3befab9SJohan Hedberg list_del_rcu(&key->list); 1119e3befab9SJohan Hedberg kfree_rcu(key, rcu); 1120e3befab9SJohan Hedberg } 1121e3befab9SJohan Hedberg } 11226a77083aSJohan Hedberg } 11236a77083aSJohan Hedberg } 11246a77083aSJohan Hedberg 1125d3e54a87SJohan Hedberg static void sc_add_ltk(struct smp_chan *smp) 1126d3e54a87SJohan Hedberg { 1127d3e54a87SJohan Hedberg struct hci_conn *hcon = smp->conn->hcon; 1128d3e54a87SJohan Hedberg u8 key_type, auth; 1129d3e54a87SJohan Hedberg 1130d3e54a87SJohan Hedberg if (test_bit(SMP_FLAG_DEBUG_KEY, &smp->flags)) 1131d3e54a87SJohan Hedberg key_type = SMP_LTK_P256_DEBUG; 1132d3e54a87SJohan Hedberg else 1133d3e54a87SJohan Hedberg key_type = SMP_LTK_P256; 1134d3e54a87SJohan Hedberg 1135d3e54a87SJohan Hedberg if (hcon->pending_sec_level == BT_SECURITY_FIPS) 1136d3e54a87SJohan Hedberg auth = 1; 1137d3e54a87SJohan Hedberg else 1138d3e54a87SJohan Hedberg auth = 0; 1139d3e54a87SJohan Hedberg 1140d3e54a87SJohan Hedberg smp->ltk = hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, 1141d3e54a87SJohan Hedberg key_type, auth, smp->tk, smp->enc_key_size, 1142d3e54a87SJohan Hedberg 0, 0); 1143d3e54a87SJohan Hedberg } 1144d3e54a87SJohan Hedberg 11456a77083aSJohan Hedberg static void sc_generate_link_key(struct smp_chan *smp) 11466a77083aSJohan Hedberg { 1147a62da6f1SJohan Hedberg /* From core spec. Spells out in ASCII as 'lebr'. */ 11486a77083aSJohan Hedberg const u8 lebr[4] = { 0x72, 0x62, 0x65, 0x6c }; 11496a77083aSJohan Hedberg 11506a77083aSJohan Hedberg smp->link_key = kzalloc(16, GFP_KERNEL); 11516a77083aSJohan Hedberg if (!smp->link_key) 11526a77083aSJohan Hedberg return; 11536a77083aSJohan Hedberg 1154a62da6f1SJohan Hedberg if (test_bit(SMP_FLAG_CT2, &smp->flags)) { 1155151129dfSChristophe JAILLET /* SALT = 0x000000000000000000000000746D7031 */ 1156a62da6f1SJohan Hedberg const u8 salt[16] = { 0x31, 0x70, 0x6d, 0x74 }; 1157a62da6f1SJohan Hedberg 1158a62da6f1SJohan Hedberg if (smp_h7(smp->tfm_cmac, smp->tk, salt, smp->link_key)) { 1159453431a5SWaiman Long kfree_sensitive(smp->link_key); 1160a62da6f1SJohan Hedberg smp->link_key = NULL; 1161a62da6f1SJohan Hedberg return; 1162a62da6f1SJohan Hedberg } 1163a62da6f1SJohan Hedberg } else { 1164a62da6f1SJohan Hedberg /* From core spec. Spells out in ASCII as 'tmp1'. */ 1165a62da6f1SJohan Hedberg const u8 tmp1[4] = { 0x31, 0x70, 0x6d, 0x74 }; 1166a62da6f1SJohan Hedberg 11676a77083aSJohan Hedberg if (smp_h6(smp->tfm_cmac, smp->tk, tmp1, smp->link_key)) { 1168453431a5SWaiman Long kfree_sensitive(smp->link_key); 11696a77083aSJohan Hedberg smp->link_key = NULL; 11706a77083aSJohan Hedberg return; 11716a77083aSJohan Hedberg } 1172a62da6f1SJohan Hedberg } 11736a77083aSJohan Hedberg 11746a77083aSJohan Hedberg if (smp_h6(smp->tfm_cmac, smp->link_key, lebr, smp->link_key)) { 1175453431a5SWaiman Long kfree_sensitive(smp->link_key); 11766a77083aSJohan Hedberg smp->link_key = NULL; 11776a77083aSJohan Hedberg return; 11786a77083aSJohan Hedberg } 117944f1a7abSJohan Hedberg } 118044f1a7abSJohan Hedberg 1181b28b4943SJohan Hedberg static void smp_allow_key_dist(struct smp_chan *smp) 1182b28b4943SJohan Hedberg { 1183b28b4943SJohan Hedberg /* Allow the first expected phase 3 PDU. The rest of the PDUs 1184b28b4943SJohan Hedberg * will be allowed in each PDU handler to ensure we receive 1185b28b4943SJohan Hedberg * them in the correct order. 1186b28b4943SJohan Hedberg */ 1187b28b4943SJohan Hedberg if (smp->remote_key_dist & SMP_DIST_ENC_KEY) 1188b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_ENCRYPT_INFO); 1189b28b4943SJohan Hedberg else if (smp->remote_key_dist & SMP_DIST_ID_KEY) 1190b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO); 1191b28b4943SJohan Hedberg else if (smp->remote_key_dist & SMP_DIST_SIGN) 1192b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO); 1193b28b4943SJohan Hedberg } 1194b28b4943SJohan Hedberg 1195b5ae344dSJohan Hedberg static void sc_generate_ltk(struct smp_chan *smp) 1196b5ae344dSJohan Hedberg { 1197a62da6f1SJohan Hedberg /* From core spec. Spells out in ASCII as 'brle'. */ 1198b5ae344dSJohan Hedberg const u8 brle[4] = { 0x65, 0x6c, 0x72, 0x62 }; 1199b5ae344dSJohan Hedberg struct hci_conn *hcon = smp->conn->hcon; 1200b5ae344dSJohan Hedberg struct hci_dev *hdev = hcon->hdev; 1201b5ae344dSJohan Hedberg struct link_key *key; 1202b5ae344dSJohan Hedberg 1203b5ae344dSJohan Hedberg key = hci_find_link_key(hdev, &hcon->dst); 1204b5ae344dSJohan Hedberg if (!key) { 12052064ee33SMarcel Holtmann bt_dev_err(hdev, "no Link Key found to generate LTK"); 1206b5ae344dSJohan Hedberg return; 1207b5ae344dSJohan Hedberg } 1208b5ae344dSJohan Hedberg 1209b5ae344dSJohan Hedberg if (key->type == HCI_LK_DEBUG_COMBINATION) 1210b5ae344dSJohan Hedberg set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags); 1211b5ae344dSJohan Hedberg 1212a62da6f1SJohan Hedberg if (test_bit(SMP_FLAG_CT2, &smp->flags)) { 1213151129dfSChristophe JAILLET /* SALT = 0x000000000000000000000000746D7032 */ 1214a62da6f1SJohan Hedberg const u8 salt[16] = { 0x32, 0x70, 0x6d, 0x74 }; 1215a62da6f1SJohan Hedberg 1216a62da6f1SJohan Hedberg if (smp_h7(smp->tfm_cmac, key->val, salt, smp->tk)) 1217a62da6f1SJohan Hedberg return; 1218a62da6f1SJohan Hedberg } else { 1219a62da6f1SJohan Hedberg /* From core spec. Spells out in ASCII as 'tmp2'. */ 1220a62da6f1SJohan Hedberg const u8 tmp2[4] = { 0x32, 0x70, 0x6d, 0x74 }; 1221a62da6f1SJohan Hedberg 1222b5ae344dSJohan Hedberg if (smp_h6(smp->tfm_cmac, key->val, tmp2, smp->tk)) 1223b5ae344dSJohan Hedberg return; 1224a62da6f1SJohan Hedberg } 1225b5ae344dSJohan Hedberg 1226b5ae344dSJohan Hedberg if (smp_h6(smp->tfm_cmac, smp->tk, brle, smp->tk)) 1227b5ae344dSJohan Hedberg return; 1228b5ae344dSJohan Hedberg 1229b5ae344dSJohan Hedberg sc_add_ltk(smp); 1230b5ae344dSJohan Hedberg } 1231b5ae344dSJohan Hedberg 1232d6268e86SJohan Hedberg static void smp_distribute_keys(struct smp_chan *smp) 123344f1a7abSJohan Hedberg { 123444f1a7abSJohan Hedberg struct smp_cmd_pairing *req, *rsp; 123586d1407cSJohan Hedberg struct l2cap_conn *conn = smp->conn; 123644f1a7abSJohan Hedberg struct hci_conn *hcon = conn->hcon; 123744f1a7abSJohan Hedberg struct hci_dev *hdev = hcon->hdev; 123844f1a7abSJohan Hedberg __u8 *keydist; 123944f1a7abSJohan Hedberg 124044f1a7abSJohan Hedberg BT_DBG("conn %p", conn); 124144f1a7abSJohan Hedberg 124244f1a7abSJohan Hedberg rsp = (void *) &smp->prsp[1]; 124344f1a7abSJohan Hedberg 124444f1a7abSJohan Hedberg /* The responder sends its keys first */ 1245b28b4943SJohan Hedberg if (hcon->out && (smp->remote_key_dist & KEY_DIST_MASK)) { 1246b28b4943SJohan Hedberg smp_allow_key_dist(smp); 124786d1407cSJohan Hedberg return; 1248b28b4943SJohan Hedberg } 124944f1a7abSJohan Hedberg 125044f1a7abSJohan Hedberg req = (void *) &smp->preq[1]; 125144f1a7abSJohan Hedberg 125244f1a7abSJohan Hedberg if (hcon->out) { 125344f1a7abSJohan Hedberg keydist = &rsp->init_key_dist; 125444f1a7abSJohan Hedberg *keydist &= req->init_key_dist; 125544f1a7abSJohan Hedberg } else { 125644f1a7abSJohan Hedberg keydist = &rsp->resp_key_dist; 125744f1a7abSJohan Hedberg *keydist &= req->resp_key_dist; 125844f1a7abSJohan Hedberg } 125944f1a7abSJohan Hedberg 12606a77083aSJohan Hedberg if (test_bit(SMP_FLAG_SC, &smp->flags)) { 1261b5ae344dSJohan Hedberg if (hcon->type == LE_LINK && (*keydist & SMP_DIST_LINK_KEY)) 12626a77083aSJohan Hedberg sc_generate_link_key(smp); 1263b5ae344dSJohan Hedberg if (hcon->type == ACL_LINK && (*keydist & SMP_DIST_ENC_KEY)) 1264b5ae344dSJohan Hedberg sc_generate_ltk(smp); 12656a77083aSJohan Hedberg 12666a77083aSJohan Hedberg /* Clear the keys which are generated but not distributed */ 12676a77083aSJohan Hedberg *keydist &= ~SMP_SC_NO_DIST; 12686a77083aSJohan Hedberg } 12696a77083aSJohan Hedberg 127044f1a7abSJohan Hedberg BT_DBG("keydist 0x%x", *keydist); 127144f1a7abSJohan Hedberg 127244f1a7abSJohan Hedberg if (*keydist & SMP_DIST_ENC_KEY) { 127344f1a7abSJohan Hedberg struct smp_cmd_encrypt_info enc; 127444f1a7abSJohan Hedberg struct smp_cmd_master_ident ident; 127544f1a7abSJohan Hedberg struct smp_ltk *ltk; 127644f1a7abSJohan Hedberg u8 authenticated; 127744f1a7abSJohan Hedberg __le16 ediv; 127844f1a7abSJohan Hedberg __le64 rand; 127944f1a7abSJohan Hedberg 12801fc62c52SJohan Hedberg /* Make sure we generate only the significant amount of 12811fc62c52SJohan Hedberg * bytes based on the encryption key size, and set the rest 12821fc62c52SJohan Hedberg * of the value to zeroes. 12831fc62c52SJohan Hedberg */ 12841fc62c52SJohan Hedberg get_random_bytes(enc.ltk, smp->enc_key_size); 12851fc62c52SJohan Hedberg memset(enc.ltk + smp->enc_key_size, 0, 12861fc62c52SJohan Hedberg sizeof(enc.ltk) - smp->enc_key_size); 12871fc62c52SJohan Hedberg 128844f1a7abSJohan Hedberg get_random_bytes(&ediv, sizeof(ediv)); 128944f1a7abSJohan Hedberg get_random_bytes(&rand, sizeof(rand)); 129044f1a7abSJohan Hedberg 129144f1a7abSJohan Hedberg smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc); 129244f1a7abSJohan Hedberg 129344f1a7abSJohan Hedberg authenticated = hcon->sec_level == BT_SECURITY_HIGH; 129444f1a7abSJohan Hedberg ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, 129544f1a7abSJohan Hedberg SMP_LTK_SLAVE, authenticated, enc.ltk, 129644f1a7abSJohan Hedberg smp->enc_key_size, ediv, rand); 129744f1a7abSJohan Hedberg smp->slave_ltk = ltk; 129844f1a7abSJohan Hedberg 129944f1a7abSJohan Hedberg ident.ediv = ediv; 130044f1a7abSJohan Hedberg ident.rand = rand; 130144f1a7abSJohan Hedberg 130244f1a7abSJohan Hedberg smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident); 130344f1a7abSJohan Hedberg 130444f1a7abSJohan Hedberg *keydist &= ~SMP_DIST_ENC_KEY; 130544f1a7abSJohan Hedberg } 130644f1a7abSJohan Hedberg 130744f1a7abSJohan Hedberg if (*keydist & SMP_DIST_ID_KEY) { 130844f1a7abSJohan Hedberg struct smp_cmd_ident_addr_info addrinfo; 130944f1a7abSJohan Hedberg struct smp_cmd_ident_info idinfo; 131044f1a7abSJohan Hedberg 131144f1a7abSJohan Hedberg memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk)); 131244f1a7abSJohan Hedberg 131344f1a7abSJohan Hedberg smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo); 131444f1a7abSJohan Hedberg 131544f1a7abSJohan Hedberg /* The hci_conn contains the local identity address 131644f1a7abSJohan Hedberg * after the connection has been established. 131744f1a7abSJohan Hedberg * 131844f1a7abSJohan Hedberg * This is true even when the connection has been 131944f1a7abSJohan Hedberg * established using a resolvable random address. 132044f1a7abSJohan Hedberg */ 132144f1a7abSJohan Hedberg bacpy(&addrinfo.bdaddr, &hcon->src); 132244f1a7abSJohan Hedberg addrinfo.addr_type = hcon->src_type; 132344f1a7abSJohan Hedberg 132444f1a7abSJohan Hedberg smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo), 132544f1a7abSJohan Hedberg &addrinfo); 132644f1a7abSJohan Hedberg 132744f1a7abSJohan Hedberg *keydist &= ~SMP_DIST_ID_KEY; 132844f1a7abSJohan Hedberg } 132944f1a7abSJohan Hedberg 133044f1a7abSJohan Hedberg if (*keydist & SMP_DIST_SIGN) { 133144f1a7abSJohan Hedberg struct smp_cmd_sign_info sign; 133244f1a7abSJohan Hedberg struct smp_csrk *csrk; 133344f1a7abSJohan Hedberg 133444f1a7abSJohan Hedberg /* Generate a new random key */ 133544f1a7abSJohan Hedberg get_random_bytes(sign.csrk, sizeof(sign.csrk)); 133644f1a7abSJohan Hedberg 133744f1a7abSJohan Hedberg csrk = kzalloc(sizeof(*csrk), GFP_KERNEL); 133844f1a7abSJohan Hedberg if (csrk) { 13394cd3928aSJohan Hedberg if (hcon->sec_level > BT_SECURITY_MEDIUM) 13404cd3928aSJohan Hedberg csrk->type = MGMT_CSRK_LOCAL_AUTHENTICATED; 13414cd3928aSJohan Hedberg else 13424cd3928aSJohan Hedberg csrk->type = MGMT_CSRK_LOCAL_UNAUTHENTICATED; 134344f1a7abSJohan Hedberg memcpy(csrk->val, sign.csrk, sizeof(csrk->val)); 134444f1a7abSJohan Hedberg } 134544f1a7abSJohan Hedberg smp->slave_csrk = csrk; 134644f1a7abSJohan Hedberg 134744f1a7abSJohan Hedberg smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign); 134844f1a7abSJohan Hedberg 134944f1a7abSJohan Hedberg *keydist &= ~SMP_DIST_SIGN; 135044f1a7abSJohan Hedberg } 135144f1a7abSJohan Hedberg 135244f1a7abSJohan Hedberg /* If there are still keys to be received wait for them */ 1353b28b4943SJohan Hedberg if (smp->remote_key_dist & KEY_DIST_MASK) { 1354b28b4943SJohan Hedberg smp_allow_key_dist(smp); 135586d1407cSJohan Hedberg return; 1356b28b4943SJohan Hedberg } 135744f1a7abSJohan Hedberg 135844f1a7abSJohan Hedberg set_bit(SMP_FLAG_COMPLETE, &smp->flags); 135944f1a7abSJohan Hedberg smp_notify_keys(conn); 136044f1a7abSJohan Hedberg 136144f1a7abSJohan Hedberg smp_chan_destroy(conn); 136244f1a7abSJohan Hedberg } 136344f1a7abSJohan Hedberg 1364b68fda68SJohan Hedberg static void smp_timeout(struct work_struct *work) 1365b68fda68SJohan Hedberg { 1366b68fda68SJohan Hedberg struct smp_chan *smp = container_of(work, struct smp_chan, 1367b68fda68SJohan Hedberg security_timer.work); 1368b68fda68SJohan Hedberg struct l2cap_conn *conn = smp->conn; 1369b68fda68SJohan Hedberg 1370b68fda68SJohan Hedberg BT_DBG("conn %p", conn); 1371b68fda68SJohan Hedberg 13721e91c29eSJohan Hedberg hci_disconnect(conn->hcon, HCI_ERROR_REMOTE_USER_TERM); 1373b68fda68SJohan Hedberg } 1374b68fda68SJohan Hedberg 13758aab4757SVinicius Costa Gomes static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) 13768aab4757SVinicius Costa Gomes { 13775d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 13788aab4757SVinicius Costa Gomes struct smp_chan *smp; 13798aab4757SVinicius Costa Gomes 1380f1560463SMarcel Holtmann smp = kzalloc(sizeof(*smp), GFP_ATOMIC); 1381fc75cc86SJohan Hedberg if (!smp) 13828aab4757SVinicius Costa Gomes return NULL; 13838aab4757SVinicius Costa Gomes 138471af2f6bSHerbert Xu smp->tfm_cmac = crypto_alloc_shash("cmac(aes)", 0, 0); 1385407cecf6SJohan Hedberg if (IS_ERR(smp->tfm_cmac)) { 1386407cecf6SJohan Hedberg BT_ERR("Unable to create CMAC crypto context"); 138728a220aaSArd Biesheuvel goto zfree_smp; 138847eb2ac8STudor Ambarus } 138947eb2ac8STudor Ambarus 1390075f7732SHerbert Xu smp->tfm_ecdh = crypto_alloc_kpp("ecdh", 0, 0); 139147eb2ac8STudor Ambarus if (IS_ERR(smp->tfm_ecdh)) { 139247eb2ac8STudor Ambarus BT_ERR("Unable to create ECDH crypto context"); 139347eb2ac8STudor Ambarus goto free_shash; 1394407cecf6SJohan Hedberg } 1395407cecf6SJohan Hedberg 13968aab4757SVinicius Costa Gomes smp->conn = conn; 13975d88cc73SJohan Hedberg chan->data = smp; 13988aab4757SVinicius Costa Gomes 1399b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_FAIL); 1400b28b4943SJohan Hedberg 1401b68fda68SJohan Hedberg INIT_DELAYED_WORK(&smp->security_timer, smp_timeout); 1402b68fda68SJohan Hedberg 14038aab4757SVinicius Costa Gomes hci_conn_hold(conn->hcon); 14048aab4757SVinicius Costa Gomes 14058aab4757SVinicius Costa Gomes return smp; 140647eb2ac8STudor Ambarus 140747eb2ac8STudor Ambarus free_shash: 140847eb2ac8STudor Ambarus crypto_free_shash(smp->tfm_cmac); 140947eb2ac8STudor Ambarus zfree_smp: 1410453431a5SWaiman Long kfree_sensitive(smp); 141147eb2ac8STudor Ambarus return NULL; 14128aab4757SVinicius Costa Gomes } 14138aab4757SVinicius Costa Gomes 1414760b018bSJohan Hedberg static int sc_mackey_and_ltk(struct smp_chan *smp, u8 mackey[16], u8 ltk[16]) 1415760b018bSJohan Hedberg { 1416760b018bSJohan Hedberg struct hci_conn *hcon = smp->conn->hcon; 1417760b018bSJohan Hedberg u8 *na, *nb, a[7], b[7]; 1418760b018bSJohan Hedberg 1419760b018bSJohan Hedberg if (hcon->out) { 1420760b018bSJohan Hedberg na = smp->prnd; 1421760b018bSJohan Hedberg nb = smp->rrnd; 1422760b018bSJohan Hedberg } else { 1423760b018bSJohan Hedberg na = smp->rrnd; 1424760b018bSJohan Hedberg nb = smp->prnd; 1425760b018bSJohan Hedberg } 1426760b018bSJohan Hedberg 1427760b018bSJohan Hedberg memcpy(a, &hcon->init_addr, 6); 1428760b018bSJohan Hedberg memcpy(b, &hcon->resp_addr, 6); 1429760b018bSJohan Hedberg a[6] = hcon->init_addr_type; 1430760b018bSJohan Hedberg b[6] = hcon->resp_addr_type; 1431760b018bSJohan Hedberg 1432760b018bSJohan Hedberg return smp_f5(smp->tfm_cmac, smp->dhkey, na, nb, a, b, mackey, ltk); 1433760b018bSJohan Hedberg } 1434760b018bSJohan Hedberg 143538606f14SJohan Hedberg static void sc_dhkey_check(struct smp_chan *smp) 1436760b018bSJohan Hedberg { 1437760b018bSJohan Hedberg struct hci_conn *hcon = smp->conn->hcon; 1438760b018bSJohan Hedberg struct smp_cmd_dhkey_check check; 1439760b018bSJohan Hedberg u8 a[7], b[7], *local_addr, *remote_addr; 1440760b018bSJohan Hedberg u8 io_cap[3], r[16]; 1441760b018bSJohan Hedberg 1442760b018bSJohan Hedberg memcpy(a, &hcon->init_addr, 6); 1443760b018bSJohan Hedberg memcpy(b, &hcon->resp_addr, 6); 1444760b018bSJohan Hedberg a[6] = hcon->init_addr_type; 1445760b018bSJohan Hedberg b[6] = hcon->resp_addr_type; 1446760b018bSJohan Hedberg 1447760b018bSJohan Hedberg if (hcon->out) { 1448760b018bSJohan Hedberg local_addr = a; 1449760b018bSJohan Hedberg remote_addr = b; 1450760b018bSJohan Hedberg memcpy(io_cap, &smp->preq[1], 3); 1451760b018bSJohan Hedberg } else { 1452760b018bSJohan Hedberg local_addr = b; 1453760b018bSJohan Hedberg remote_addr = a; 1454760b018bSJohan Hedberg memcpy(io_cap, &smp->prsp[1], 3); 1455760b018bSJohan Hedberg } 1456760b018bSJohan Hedberg 1457dddd3059SJohan Hedberg memset(r, 0, sizeof(r)); 1458dddd3059SJohan Hedberg 1459dddd3059SJohan Hedberg if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY) 146038606f14SJohan Hedberg put_unaligned_le32(hcon->passkey_notify, r); 1461760b018bSJohan Hedberg 1462a29b0733SJohan Hedberg if (smp->method == REQ_OOB) 1463a29b0733SJohan Hedberg memcpy(r, smp->rr, 16); 1464a29b0733SJohan Hedberg 1465760b018bSJohan Hedberg smp_f6(smp->tfm_cmac, smp->mackey, smp->prnd, smp->rrnd, r, io_cap, 1466760b018bSJohan Hedberg local_addr, remote_addr, check.e); 1467760b018bSJohan Hedberg 1468760b018bSJohan Hedberg smp_send_cmd(smp->conn, SMP_CMD_DHKEY_CHECK, sizeof(check), &check); 1469dddd3059SJohan Hedberg } 1470dddd3059SJohan Hedberg 147138606f14SJohan Hedberg static u8 sc_passkey_send_confirm(struct smp_chan *smp) 147238606f14SJohan Hedberg { 147338606f14SJohan Hedberg struct l2cap_conn *conn = smp->conn; 147438606f14SJohan Hedberg struct hci_conn *hcon = conn->hcon; 147538606f14SJohan Hedberg struct smp_cmd_pairing_confirm cfm; 147638606f14SJohan Hedberg u8 r; 147738606f14SJohan Hedberg 147838606f14SJohan Hedberg r = ((hcon->passkey_notify >> smp->passkey_round) & 0x01); 147938606f14SJohan Hedberg r |= 0x80; 148038606f14SJohan Hedberg 148138606f14SJohan Hedberg get_random_bytes(smp->prnd, sizeof(smp->prnd)); 148238606f14SJohan Hedberg 148338606f14SJohan Hedberg if (smp_f4(smp->tfm_cmac, smp->local_pk, smp->remote_pk, smp->prnd, r, 148438606f14SJohan Hedberg cfm.confirm_val)) 148538606f14SJohan Hedberg return SMP_UNSPECIFIED; 148638606f14SJohan Hedberg 148738606f14SJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cfm), &cfm); 148838606f14SJohan Hedberg 148938606f14SJohan Hedberg return 0; 149038606f14SJohan Hedberg } 149138606f14SJohan Hedberg 149238606f14SJohan Hedberg static u8 sc_passkey_round(struct smp_chan *smp, u8 smp_op) 149338606f14SJohan Hedberg { 149438606f14SJohan Hedberg struct l2cap_conn *conn = smp->conn; 149538606f14SJohan Hedberg struct hci_conn *hcon = conn->hcon; 149638606f14SJohan Hedberg struct hci_dev *hdev = hcon->hdev; 149738606f14SJohan Hedberg u8 cfm[16], r; 149838606f14SJohan Hedberg 149938606f14SJohan Hedberg /* Ignore the PDU if we've already done 20 rounds (0 - 19) */ 150038606f14SJohan Hedberg if (smp->passkey_round >= 20) 150138606f14SJohan Hedberg return 0; 150238606f14SJohan Hedberg 150338606f14SJohan Hedberg switch (smp_op) { 150438606f14SJohan Hedberg case SMP_CMD_PAIRING_RANDOM: 150538606f14SJohan Hedberg r = ((hcon->passkey_notify >> smp->passkey_round) & 0x01); 150638606f14SJohan Hedberg r |= 0x80; 150738606f14SJohan Hedberg 150838606f14SJohan Hedberg if (smp_f4(smp->tfm_cmac, smp->remote_pk, smp->local_pk, 150938606f14SJohan Hedberg smp->rrnd, r, cfm)) 151038606f14SJohan Hedberg return SMP_UNSPECIFIED; 151138606f14SJohan Hedberg 1512329d8230SJason A. Donenfeld if (crypto_memneq(smp->pcnf, cfm, 16)) 151338606f14SJohan Hedberg return SMP_CONFIRM_FAILED; 151438606f14SJohan Hedberg 151538606f14SJohan Hedberg smp->passkey_round++; 151638606f14SJohan Hedberg 151738606f14SJohan Hedberg if (smp->passkey_round == 20) { 151838606f14SJohan Hedberg /* Generate MacKey and LTK */ 151938606f14SJohan Hedberg if (sc_mackey_and_ltk(smp, smp->mackey, smp->tk)) 152038606f14SJohan Hedberg return SMP_UNSPECIFIED; 152138606f14SJohan Hedberg } 152238606f14SJohan Hedberg 152338606f14SJohan Hedberg /* The round is only complete when the initiator 152438606f14SJohan Hedberg * receives pairing random. 152538606f14SJohan Hedberg */ 152638606f14SJohan Hedberg if (!hcon->out) { 152738606f14SJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, 152838606f14SJohan Hedberg sizeof(smp->prnd), smp->prnd); 1529d3e54a87SJohan Hedberg if (smp->passkey_round == 20) 153038606f14SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK); 1531d3e54a87SJohan Hedberg else 153238606f14SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); 153338606f14SJohan Hedberg return 0; 153438606f14SJohan Hedberg } 153538606f14SJohan Hedberg 153638606f14SJohan Hedberg /* Start the next round */ 153738606f14SJohan Hedberg if (smp->passkey_round != 20) 153838606f14SJohan Hedberg return sc_passkey_round(smp, 0); 153938606f14SJohan Hedberg 154038606f14SJohan Hedberg /* Passkey rounds are complete - start DHKey Check */ 154138606f14SJohan Hedberg sc_dhkey_check(smp); 154238606f14SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK); 154338606f14SJohan Hedberg 154438606f14SJohan Hedberg break; 154538606f14SJohan Hedberg 154638606f14SJohan Hedberg case SMP_CMD_PAIRING_CONFIRM: 154738606f14SJohan Hedberg if (test_bit(SMP_FLAG_WAIT_USER, &smp->flags)) { 154838606f14SJohan Hedberg set_bit(SMP_FLAG_CFM_PENDING, &smp->flags); 154938606f14SJohan Hedberg return 0; 155038606f14SJohan Hedberg } 155138606f14SJohan Hedberg 155238606f14SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM); 155338606f14SJohan Hedberg 155438606f14SJohan Hedberg if (hcon->out) { 155538606f14SJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, 155638606f14SJohan Hedberg sizeof(smp->prnd), smp->prnd); 155738606f14SJohan Hedberg return 0; 155838606f14SJohan Hedberg } 155938606f14SJohan Hedberg 156038606f14SJohan Hedberg return sc_passkey_send_confirm(smp); 156138606f14SJohan Hedberg 156238606f14SJohan Hedberg case SMP_CMD_PUBLIC_KEY: 156338606f14SJohan Hedberg default: 156438606f14SJohan Hedberg /* Initiating device starts the round */ 156538606f14SJohan Hedberg if (!hcon->out) 156638606f14SJohan Hedberg return 0; 156738606f14SJohan Hedberg 156838606f14SJohan Hedberg BT_DBG("%s Starting passkey round %u", hdev->name, 156938606f14SJohan Hedberg smp->passkey_round + 1); 157038606f14SJohan Hedberg 157138606f14SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); 157238606f14SJohan Hedberg 157338606f14SJohan Hedberg return sc_passkey_send_confirm(smp); 157438606f14SJohan Hedberg } 157538606f14SJohan Hedberg 157638606f14SJohan Hedberg return 0; 157738606f14SJohan Hedberg } 157838606f14SJohan Hedberg 1579dddd3059SJohan Hedberg static int sc_user_reply(struct smp_chan *smp, u16 mgmt_op, __le32 passkey) 1580dddd3059SJohan Hedberg { 158138606f14SJohan Hedberg struct l2cap_conn *conn = smp->conn; 158238606f14SJohan Hedberg struct hci_conn *hcon = conn->hcon; 158338606f14SJohan Hedberg u8 smp_op; 158438606f14SJohan Hedberg 158538606f14SJohan Hedberg clear_bit(SMP_FLAG_WAIT_USER, &smp->flags); 158638606f14SJohan Hedberg 1587dddd3059SJohan Hedberg switch (mgmt_op) { 1588dddd3059SJohan Hedberg case MGMT_OP_USER_PASSKEY_NEG_REPLY: 1589dddd3059SJohan Hedberg smp_failure(smp->conn, SMP_PASSKEY_ENTRY_FAILED); 1590dddd3059SJohan Hedberg return 0; 1591dddd3059SJohan Hedberg case MGMT_OP_USER_CONFIRM_NEG_REPLY: 1592dddd3059SJohan Hedberg smp_failure(smp->conn, SMP_NUMERIC_COMP_FAILED); 1593dddd3059SJohan Hedberg return 0; 159438606f14SJohan Hedberg case MGMT_OP_USER_PASSKEY_REPLY: 159538606f14SJohan Hedberg hcon->passkey_notify = le32_to_cpu(passkey); 159638606f14SJohan Hedberg smp->passkey_round = 0; 159738606f14SJohan Hedberg 159838606f14SJohan Hedberg if (test_and_clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags)) 159938606f14SJohan Hedberg smp_op = SMP_CMD_PAIRING_CONFIRM; 160038606f14SJohan Hedberg else 160138606f14SJohan Hedberg smp_op = 0; 160238606f14SJohan Hedberg 160338606f14SJohan Hedberg if (sc_passkey_round(smp, smp_op)) 160438606f14SJohan Hedberg return -EIO; 160538606f14SJohan Hedberg 160638606f14SJohan Hedberg return 0; 1607dddd3059SJohan Hedberg } 1608dddd3059SJohan Hedberg 1609d3e54a87SJohan Hedberg /* Initiator sends DHKey check first */ 1610d3e54a87SJohan Hedberg if (hcon->out) { 161138606f14SJohan Hedberg sc_dhkey_check(smp); 1612d3e54a87SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK); 1613d3e54a87SJohan Hedberg } else if (test_and_clear_bit(SMP_FLAG_DHKEY_PENDING, &smp->flags)) { 1614d3e54a87SJohan Hedberg sc_dhkey_check(smp); 1615d3e54a87SJohan Hedberg sc_add_ltk(smp); 1616d3e54a87SJohan Hedberg } 1617760b018bSJohan Hedberg 1618760b018bSJohan Hedberg return 0; 1619760b018bSJohan Hedberg } 1620760b018bSJohan Hedberg 16212b64d153SBrian Gix int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey) 16222b64d153SBrian Gix { 1623b10e8017SJohan Hedberg struct l2cap_conn *conn = hcon->l2cap_data; 16245d88cc73SJohan Hedberg struct l2cap_chan *chan; 16252b64d153SBrian Gix struct smp_chan *smp; 16262b64d153SBrian Gix u32 value; 1627fc75cc86SJohan Hedberg int err; 16282b64d153SBrian Gix 16292b64d153SBrian Gix BT_DBG(""); 16302b64d153SBrian Gix 1631fc75cc86SJohan Hedberg if (!conn) 16322b64d153SBrian Gix return -ENOTCONN; 16332b64d153SBrian Gix 16345d88cc73SJohan Hedberg chan = conn->smp; 16355d88cc73SJohan Hedberg if (!chan) 16365d88cc73SJohan Hedberg return -ENOTCONN; 16375d88cc73SJohan Hedberg 1638fc75cc86SJohan Hedberg l2cap_chan_lock(chan); 1639fc75cc86SJohan Hedberg if (!chan->data) { 1640fc75cc86SJohan Hedberg err = -ENOTCONN; 1641fc75cc86SJohan Hedberg goto unlock; 1642fc75cc86SJohan Hedberg } 1643fc75cc86SJohan Hedberg 16445d88cc73SJohan Hedberg smp = chan->data; 16452b64d153SBrian Gix 1646760b018bSJohan Hedberg if (test_bit(SMP_FLAG_SC, &smp->flags)) { 1647760b018bSJohan Hedberg err = sc_user_reply(smp, mgmt_op, passkey); 1648760b018bSJohan Hedberg goto unlock; 1649760b018bSJohan Hedberg } 1650760b018bSJohan Hedberg 16512b64d153SBrian Gix switch (mgmt_op) { 16522b64d153SBrian Gix case MGMT_OP_USER_PASSKEY_REPLY: 16532b64d153SBrian Gix value = le32_to_cpu(passkey); 1654943a732aSJohan Hedberg memset(smp->tk, 0, sizeof(smp->tk)); 16552b64d153SBrian Gix BT_DBG("PassKey: %d", value); 1656943a732aSJohan Hedberg put_unaligned_le32(value, smp->tk); 165719186c7bSGustavo A. R. Silva fallthrough; 16582b64d153SBrian Gix case MGMT_OP_USER_CONFIRM_REPLY: 16594a74d658SJohan Hedberg set_bit(SMP_FLAG_TK_VALID, &smp->flags); 16602b64d153SBrian Gix break; 16612b64d153SBrian Gix case MGMT_OP_USER_PASSKEY_NEG_REPLY: 16622b64d153SBrian Gix case MGMT_OP_USER_CONFIRM_NEG_REPLY: 166384794e11SJohan Hedberg smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED); 1664fc75cc86SJohan Hedberg err = 0; 1665fc75cc86SJohan Hedberg goto unlock; 16662b64d153SBrian Gix default: 166784794e11SJohan Hedberg smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED); 1668fc75cc86SJohan Hedberg err = -EOPNOTSUPP; 1669fc75cc86SJohan Hedberg goto unlock; 16702b64d153SBrian Gix } 16712b64d153SBrian Gix 1672fc75cc86SJohan Hedberg err = 0; 1673fc75cc86SJohan Hedberg 16742b64d153SBrian Gix /* If it is our turn to send Pairing Confirm, do so now */ 16751cc61144SJohan Hedberg if (test_bit(SMP_FLAG_CFM_PENDING, &smp->flags)) { 16761cc61144SJohan Hedberg u8 rsp = smp_confirm(smp); 16771cc61144SJohan Hedberg if (rsp) 16781cc61144SJohan Hedberg smp_failure(conn, rsp); 16791cc61144SJohan Hedberg } 16802b64d153SBrian Gix 1681fc75cc86SJohan Hedberg unlock: 1682fc75cc86SJohan Hedberg l2cap_chan_unlock(chan); 1683fc75cc86SJohan Hedberg return err; 16842b64d153SBrian Gix } 16852b64d153SBrian Gix 1686b5ae344dSJohan Hedberg static void build_bredr_pairing_cmd(struct smp_chan *smp, 1687b5ae344dSJohan Hedberg struct smp_cmd_pairing *req, 1688b5ae344dSJohan Hedberg struct smp_cmd_pairing *rsp) 1689b5ae344dSJohan Hedberg { 1690b5ae344dSJohan Hedberg struct l2cap_conn *conn = smp->conn; 1691b5ae344dSJohan Hedberg struct hci_dev *hdev = conn->hcon->hdev; 1692b5ae344dSJohan Hedberg u8 local_dist = 0, remote_dist = 0; 1693b5ae344dSJohan Hedberg 1694d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_BONDABLE)) { 1695b5ae344dSJohan Hedberg local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN; 1696b5ae344dSJohan Hedberg remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN; 1697b5ae344dSJohan Hedberg } 1698b5ae344dSJohan Hedberg 1699d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_RPA_RESOLVING)) 1700b5ae344dSJohan Hedberg remote_dist |= SMP_DIST_ID_KEY; 1701b5ae344dSJohan Hedberg 1702d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_PRIVACY)) 1703b5ae344dSJohan Hedberg local_dist |= SMP_DIST_ID_KEY; 1704b5ae344dSJohan Hedberg 1705b5ae344dSJohan Hedberg if (!rsp) { 1706b5ae344dSJohan Hedberg memset(req, 0, sizeof(*req)); 1707b5ae344dSJohan Hedberg 1708a62da6f1SJohan Hedberg req->auth_req = SMP_AUTH_CT2; 1709b5ae344dSJohan Hedberg req->init_key_dist = local_dist; 1710b5ae344dSJohan Hedberg req->resp_key_dist = remote_dist; 1711e3f6a257SJohan Hedberg req->max_key_size = conn->hcon->enc_key_size; 1712b5ae344dSJohan Hedberg 1713b5ae344dSJohan Hedberg smp->remote_key_dist = remote_dist; 1714b5ae344dSJohan Hedberg 1715b5ae344dSJohan Hedberg return; 1716b5ae344dSJohan Hedberg } 1717b5ae344dSJohan Hedberg 1718b5ae344dSJohan Hedberg memset(rsp, 0, sizeof(*rsp)); 1719b5ae344dSJohan Hedberg 1720a62da6f1SJohan Hedberg rsp->auth_req = SMP_AUTH_CT2; 1721e3f6a257SJohan Hedberg rsp->max_key_size = conn->hcon->enc_key_size; 1722b5ae344dSJohan Hedberg rsp->init_key_dist = req->init_key_dist & remote_dist; 1723b5ae344dSJohan Hedberg rsp->resp_key_dist = req->resp_key_dist & local_dist; 1724b5ae344dSJohan Hedberg 1725b5ae344dSJohan Hedberg smp->remote_key_dist = rsp->init_key_dist; 1726b5ae344dSJohan Hedberg } 1727b5ae344dSJohan Hedberg 1728da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) 172988ba43b6SAnderson Briglia { 17303158c50cSVinicius Costa Gomes struct smp_cmd_pairing rsp, *req = (void *) skb->data; 1731fc75cc86SJohan Hedberg struct l2cap_chan *chan = conn->smp; 1732b3c6410bSJohan Hedberg struct hci_dev *hdev = conn->hcon->hdev; 17338aab4757SVinicius Costa Gomes struct smp_chan *smp; 1734c7262e71SJohan Hedberg u8 key_size, auth, sec_level; 17358aab4757SVinicius Costa Gomes int ret; 173688ba43b6SAnderson Briglia 173788ba43b6SAnderson Briglia BT_DBG("conn %p", conn); 173888ba43b6SAnderson Briglia 1739c46b98beSJohan Hedberg if (skb->len < sizeof(*req)) 174038e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 1741c46b98beSJohan Hedberg 174240bef302SJohan Hedberg if (conn->hcon->role != HCI_ROLE_SLAVE) 17432b64d153SBrian Gix return SMP_CMD_NOTSUPP; 17442b64d153SBrian Gix 1745fc75cc86SJohan Hedberg if (!chan->data) 17468aab4757SVinicius Costa Gomes smp = smp_chan_create(conn); 1747fc75cc86SJohan Hedberg else 17485d88cc73SJohan Hedberg smp = chan->data; 1749d26a2345SVinicius Costa Gomes 1750d08fd0e7SAndrei Emeltchenko if (!smp) 1751d08fd0e7SAndrei Emeltchenko return SMP_UNSPECIFIED; 1752d08fd0e7SAndrei Emeltchenko 1753c05b9339SJohan Hedberg /* We didn't start the pairing, so match remote */ 17540edb14deSJohan Hedberg auth = req->auth_req & AUTH_REQ_MASK(hdev); 1755c05b9339SJohan Hedberg 1756d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_BONDABLE) && 1757c05b9339SJohan Hedberg (auth & SMP_AUTH_BONDING)) 1758b3c6410bSJohan Hedberg return SMP_PAIRING_NOTSUPP; 1759b3c6410bSJohan Hedberg 1760d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SC_ONLY) && !(auth & SMP_AUTH_SC)) 1761903b71c7SJohan Hedberg return SMP_AUTH_REQUIREMENTS; 1762903b71c7SJohan Hedberg 17631c1def09SVinicius Costa Gomes smp->preq[0] = SMP_CMD_PAIRING_REQ; 17641c1def09SVinicius Costa Gomes memcpy(&smp->preq[1], req, sizeof(*req)); 17653158c50cSVinicius Costa Gomes skb_pull(skb, sizeof(*req)); 176688ba43b6SAnderson Briglia 1767cb06d366SJohan Hedberg /* If the remote side's OOB flag is set it means it has 1768cb06d366SJohan Hedberg * successfully received our local OOB data - therefore set the 1769cb06d366SJohan Hedberg * flag to indicate that local OOB is in use. 1770cb06d366SJohan Hedberg */ 177194f14e47SJohan Hedberg if (req->oob_flag == SMP_OOB_PRESENT && SMP_DEV(hdev)->local_oob) 177258428563SJohan Hedberg set_bit(SMP_FLAG_LOCAL_OOB, &smp->flags); 177358428563SJohan Hedberg 1774b5ae344dSJohan Hedberg /* SMP over BR/EDR requires special treatment */ 1775b5ae344dSJohan Hedberg if (conn->hcon->type == ACL_LINK) { 1776b5ae344dSJohan Hedberg /* We must have a BR/EDR SC link */ 177708f63cc5SMarcel Holtmann if (!test_bit(HCI_CONN_AES_CCM, &conn->hcon->flags) && 1778b7cb93e5SMarcel Holtmann !hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP)) 1779b5ae344dSJohan Hedberg return SMP_CROSS_TRANSP_NOT_ALLOWED; 1780b5ae344dSJohan Hedberg 1781b5ae344dSJohan Hedberg set_bit(SMP_FLAG_SC, &smp->flags); 1782b5ae344dSJohan Hedberg 1783b5ae344dSJohan Hedberg build_bredr_pairing_cmd(smp, req, &rsp); 1784b5ae344dSJohan Hedberg 1785a62da6f1SJohan Hedberg if (req->auth_req & SMP_AUTH_CT2) 1786a62da6f1SJohan Hedberg set_bit(SMP_FLAG_CT2, &smp->flags); 1787a62da6f1SJohan Hedberg 1788b5ae344dSJohan Hedberg key_size = min(req->max_key_size, rsp.max_key_size); 1789b5ae344dSJohan Hedberg if (check_enc_key_size(conn, key_size)) 1790b5ae344dSJohan Hedberg return SMP_ENC_KEY_SIZE; 1791b5ae344dSJohan Hedberg 1792b5ae344dSJohan Hedberg /* Clear bits which are generated but not distributed */ 1793b5ae344dSJohan Hedberg smp->remote_key_dist &= ~SMP_SC_NO_DIST; 1794b5ae344dSJohan Hedberg 1795b5ae344dSJohan Hedberg smp->prsp[0] = SMP_CMD_PAIRING_RSP; 1796b5ae344dSJohan Hedberg memcpy(&smp->prsp[1], &rsp, sizeof(rsp)); 1797b5ae344dSJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp); 1798b5ae344dSJohan Hedberg 1799b5ae344dSJohan Hedberg smp_distribute_keys(smp); 1800b5ae344dSJohan Hedberg return 0; 1801b5ae344dSJohan Hedberg } 1802b5ae344dSJohan Hedberg 18035e3d3d9bSJohan Hedberg build_pairing_cmd(conn, req, &rsp, auth); 18045e3d3d9bSJohan Hedberg 1805a62da6f1SJohan Hedberg if (rsp.auth_req & SMP_AUTH_SC) { 18065e3d3d9bSJohan Hedberg set_bit(SMP_FLAG_SC, &smp->flags); 18075e3d3d9bSJohan Hedberg 1808a62da6f1SJohan Hedberg if (rsp.auth_req & SMP_AUTH_CT2) 1809a62da6f1SJohan Hedberg set_bit(SMP_FLAG_CT2, &smp->flags); 1810a62da6f1SJohan Hedberg } 1811a62da6f1SJohan Hedberg 18125be5e275SJohan Hedberg if (conn->hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT) 18131afc2a1aSJohan Hedberg sec_level = BT_SECURITY_MEDIUM; 18141afc2a1aSJohan Hedberg else 1815c7262e71SJohan Hedberg sec_level = authreq_to_seclevel(auth); 18161afc2a1aSJohan Hedberg 1817c7262e71SJohan Hedberg if (sec_level > conn->hcon->pending_sec_level) 1818c7262e71SJohan Hedberg conn->hcon->pending_sec_level = sec_level; 1819fdde0a26SIdo Yariv 182049c922bbSStephen Hemminger /* If we need MITM check that it can be achieved */ 18212ed8f65cSJohan Hedberg if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) { 18222ed8f65cSJohan Hedberg u8 method; 18232ed8f65cSJohan Hedberg 18242ed8f65cSJohan Hedberg method = get_auth_method(smp, conn->hcon->io_capability, 18252ed8f65cSJohan Hedberg req->io_capability); 18262ed8f65cSJohan Hedberg if (method == JUST_WORKS || method == JUST_CFM) 18272ed8f65cSJohan Hedberg return SMP_AUTH_REQUIREMENTS; 18282ed8f65cSJohan Hedberg } 18292ed8f65cSJohan Hedberg 18303158c50cSVinicius Costa Gomes key_size = min(req->max_key_size, rsp.max_key_size); 18313158c50cSVinicius Costa Gomes if (check_enc_key_size(conn, key_size)) 18323158c50cSVinicius Costa Gomes return SMP_ENC_KEY_SIZE; 183388ba43b6SAnderson Briglia 1834e84a6b13SJohan Hedberg get_random_bytes(smp->prnd, sizeof(smp->prnd)); 18358aab4757SVinicius Costa Gomes 18361c1def09SVinicius Costa Gomes smp->prsp[0] = SMP_CMD_PAIRING_RSP; 18371c1def09SVinicius Costa Gomes memcpy(&smp->prsp[1], &rsp, sizeof(rsp)); 1838f01ead31SAnderson Briglia 18393158c50cSVinicius Costa Gomes smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp); 18403b19146dSJohan Hedberg 18413b19146dSJohan Hedberg clear_bit(SMP_FLAG_INITIATOR, &smp->flags); 18423b19146dSJohan Hedberg 184319c5ce9cSJohan Hedberg /* Strictly speaking we shouldn't allow Pairing Confirm for the 184419c5ce9cSJohan Hedberg * SC case, however some implementations incorrectly copy RFU auth 184519c5ce9cSJohan Hedberg * req bits from our security request, which may create a false 184619c5ce9cSJohan Hedberg * positive SC enablement. 184719c5ce9cSJohan Hedberg */ 184819c5ce9cSJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); 184919c5ce9cSJohan Hedberg 18503b19146dSJohan Hedberg if (test_bit(SMP_FLAG_SC, &smp->flags)) { 18513b19146dSJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PUBLIC_KEY); 18523b19146dSJohan Hedberg /* Clear bits which are generated but not distributed */ 18533b19146dSJohan Hedberg smp->remote_key_dist &= ~SMP_SC_NO_DIST; 18543b19146dSJohan Hedberg /* Wait for Public Key from Initiating Device */ 18553b19146dSJohan Hedberg return 0; 18563b19146dSJohan Hedberg } 1857da85e5e5SVinicius Costa Gomes 18582b64d153SBrian Gix /* Request setup of TK */ 18592b64d153SBrian Gix ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability); 18602b64d153SBrian Gix if (ret) 18612b64d153SBrian Gix return SMP_UNSPECIFIED; 18622b64d153SBrian Gix 1863da85e5e5SVinicius Costa Gomes return 0; 186488ba43b6SAnderson Briglia } 186588ba43b6SAnderson Briglia 18663b19146dSJohan Hedberg static u8 sc_send_public_key(struct smp_chan *smp) 18673b19146dSJohan Hedberg { 186870157ef5SJohan Hedberg struct hci_dev *hdev = smp->conn->hcon->hdev; 186970157ef5SJohan Hedberg 187056860245SMarcel Holtmann bt_dev_dbg(hdev, ""); 18713b19146dSJohan Hedberg 18721a8bab4fSJohan Hedberg if (test_bit(SMP_FLAG_LOCAL_OOB, &smp->flags)) { 187333d0c030SMarcel Holtmann struct l2cap_chan *chan = hdev->smp_data; 187433d0c030SMarcel Holtmann struct smp_dev *smp_dev; 187533d0c030SMarcel Holtmann 187633d0c030SMarcel Holtmann if (!chan || !chan->data) 187733d0c030SMarcel Holtmann return SMP_UNSPECIFIED; 187833d0c030SMarcel Holtmann 187933d0c030SMarcel Holtmann smp_dev = chan->data; 188033d0c030SMarcel Holtmann 188133d0c030SMarcel Holtmann memcpy(smp->local_pk, smp_dev->local_pk, 64); 1882fb334feeSMarcel Holtmann memcpy(smp->lr, smp_dev->local_rand, 16); 188333d0c030SMarcel Holtmann 188433d0c030SMarcel Holtmann if (smp_dev->debug_key) 188533d0c030SMarcel Holtmann set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags); 188633d0c030SMarcel Holtmann 188733d0c030SMarcel Holtmann goto done; 188833d0c030SMarcel Holtmann } 188933d0c030SMarcel Holtmann 1890d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS)) { 189170157ef5SJohan Hedberg BT_DBG("Using debug keys"); 1892c0153b0bSTudor Ambarus if (set_ecdh_privkey(smp->tfm_ecdh, debug_sk)) 1893c0153b0bSTudor Ambarus return SMP_UNSPECIFIED; 189470157ef5SJohan Hedberg memcpy(smp->local_pk, debug_pk, 64); 189570157ef5SJohan Hedberg set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags); 189670157ef5SJohan Hedberg } else { 18976c0dcc50SJohan Hedberg while (true) { 1898c0153b0bSTudor Ambarus /* Generate key pair for Secure Connections */ 1899c0153b0bSTudor Ambarus if (generate_ecdh_keys(smp->tfm_ecdh, smp->local_pk)) 19003b19146dSJohan Hedberg return SMP_UNSPECIFIED; 19013b19146dSJohan Hedberg 190270157ef5SJohan Hedberg /* This is unlikely, but we need to check that 190370157ef5SJohan Hedberg * we didn't accidentially generate a debug key. 19046c0dcc50SJohan Hedberg */ 1905c0153b0bSTudor Ambarus if (crypto_memneq(smp->local_pk, debug_pk, 64)) 19066c0dcc50SJohan Hedberg break; 19076c0dcc50SJohan Hedberg } 190870157ef5SJohan Hedberg } 19096c0dcc50SJohan Hedberg 191033d0c030SMarcel Holtmann done: 1911c7a3d57dSJohan Hedberg SMP_DBG("Local Public Key X: %32phN", smp->local_pk); 19128e4e2ee5SMarcel Holtmann SMP_DBG("Local Public Key Y: %32phN", smp->local_pk + 32); 19133b19146dSJohan Hedberg 19143b19146dSJohan Hedberg smp_send_cmd(smp->conn, SMP_CMD_PUBLIC_KEY, 64, smp->local_pk); 19153b19146dSJohan Hedberg 19163b19146dSJohan Hedberg return 0; 19173b19146dSJohan Hedberg } 19183b19146dSJohan Hedberg 1919da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) 192088ba43b6SAnderson Briglia { 19213158c50cSVinicius Costa Gomes struct smp_cmd_pairing *req, *rsp = (void *) skb->data; 19225d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 19235d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 19240edb14deSJohan Hedberg struct hci_dev *hdev = conn->hcon->hdev; 19253a7dbfb8SJohan Hedberg u8 key_size, auth; 19267d24ddccSAnderson Briglia int ret; 192788ba43b6SAnderson Briglia 192888ba43b6SAnderson Briglia BT_DBG("conn %p", conn); 192988ba43b6SAnderson Briglia 1930c46b98beSJohan Hedberg if (skb->len < sizeof(*rsp)) 193138e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 1932c46b98beSJohan Hedberg 193340bef302SJohan Hedberg if (conn->hcon->role != HCI_ROLE_MASTER) 19342b64d153SBrian Gix return SMP_CMD_NOTSUPP; 19352b64d153SBrian Gix 19363158c50cSVinicius Costa Gomes skb_pull(skb, sizeof(*rsp)); 1937da85e5e5SVinicius Costa Gomes 19381c1def09SVinicius Costa Gomes req = (void *) &smp->preq[1]; 19393158c50cSVinicius Costa Gomes 19403158c50cSVinicius Costa Gomes key_size = min(req->max_key_size, rsp->max_key_size); 19413158c50cSVinicius Costa Gomes if (check_enc_key_size(conn, key_size)) 19423158c50cSVinicius Costa Gomes return SMP_ENC_KEY_SIZE; 19433158c50cSVinicius Costa Gomes 19440edb14deSJohan Hedberg auth = rsp->auth_req & AUTH_REQ_MASK(hdev); 1945c05b9339SJohan Hedberg 1946d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SC_ONLY) && !(auth & SMP_AUTH_SC)) 1947903b71c7SJohan Hedberg return SMP_AUTH_REQUIREMENTS; 1948903b71c7SJohan Hedberg 1949cb06d366SJohan Hedberg /* If the remote side's OOB flag is set it means it has 1950cb06d366SJohan Hedberg * successfully received our local OOB data - therefore set the 1951cb06d366SJohan Hedberg * flag to indicate that local OOB is in use. 1952cb06d366SJohan Hedberg */ 195394f14e47SJohan Hedberg if (rsp->oob_flag == SMP_OOB_PRESENT && SMP_DEV(hdev)->local_oob) 195458428563SJohan Hedberg set_bit(SMP_FLAG_LOCAL_OOB, &smp->flags); 195558428563SJohan Hedberg 1956b5ae344dSJohan Hedberg smp->prsp[0] = SMP_CMD_PAIRING_RSP; 1957b5ae344dSJohan Hedberg memcpy(&smp->prsp[1], rsp, sizeof(*rsp)); 1958b5ae344dSJohan Hedberg 1959b5ae344dSJohan Hedberg /* Update remote key distribution in case the remote cleared 1960b5ae344dSJohan Hedberg * some bits that we had enabled in our request. 1961b5ae344dSJohan Hedberg */ 1962b5ae344dSJohan Hedberg smp->remote_key_dist &= rsp->resp_key_dist; 1963b5ae344dSJohan Hedberg 1964a62da6f1SJohan Hedberg if ((req->auth_req & SMP_AUTH_CT2) && (auth & SMP_AUTH_CT2)) 1965a62da6f1SJohan Hedberg set_bit(SMP_FLAG_CT2, &smp->flags); 1966a62da6f1SJohan Hedberg 1967b5ae344dSJohan Hedberg /* For BR/EDR this means we're done and can start phase 3 */ 1968b5ae344dSJohan Hedberg if (conn->hcon->type == ACL_LINK) { 1969b5ae344dSJohan Hedberg /* Clear bits which are generated but not distributed */ 1970b5ae344dSJohan Hedberg smp->remote_key_dist &= ~SMP_SC_NO_DIST; 1971b5ae344dSJohan Hedberg smp_distribute_keys(smp); 1972b5ae344dSJohan Hedberg return 0; 1973b5ae344dSJohan Hedberg } 1974b5ae344dSJohan Hedberg 197565668776SJohan Hedberg if ((req->auth_req & SMP_AUTH_SC) && (auth & SMP_AUTH_SC)) 197665668776SJohan Hedberg set_bit(SMP_FLAG_SC, &smp->flags); 1977d2eb9e10SJohan Hedberg else if (conn->hcon->pending_sec_level > BT_SECURITY_HIGH) 1978d2eb9e10SJohan Hedberg conn->hcon->pending_sec_level = BT_SECURITY_HIGH; 197965668776SJohan Hedberg 198049c922bbSStephen Hemminger /* If we need MITM check that it can be achieved */ 19812ed8f65cSJohan Hedberg if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) { 19822ed8f65cSJohan Hedberg u8 method; 19832ed8f65cSJohan Hedberg 19842ed8f65cSJohan Hedberg method = get_auth_method(smp, req->io_capability, 19852ed8f65cSJohan Hedberg rsp->io_capability); 19862ed8f65cSJohan Hedberg if (method == JUST_WORKS || method == JUST_CFM) 19872ed8f65cSJohan Hedberg return SMP_AUTH_REQUIREMENTS; 19882ed8f65cSJohan Hedberg } 19892ed8f65cSJohan Hedberg 1990e84a6b13SJohan Hedberg get_random_bytes(smp->prnd, sizeof(smp->prnd)); 19917d24ddccSAnderson Briglia 1992fdcc4becSJohan Hedberg /* Update remote key distribution in case the remote cleared 1993fdcc4becSJohan Hedberg * some bits that we had enabled in our request. 1994fdcc4becSJohan Hedberg */ 1995fdcc4becSJohan Hedberg smp->remote_key_dist &= rsp->resp_key_dist; 1996fdcc4becSJohan Hedberg 19973b19146dSJohan Hedberg if (test_bit(SMP_FLAG_SC, &smp->flags)) { 19983b19146dSJohan Hedberg /* Clear bits which are generated but not distributed */ 19993b19146dSJohan Hedberg smp->remote_key_dist &= ~SMP_SC_NO_DIST; 20003b19146dSJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PUBLIC_KEY); 20013b19146dSJohan Hedberg return sc_send_public_key(smp); 20023b19146dSJohan Hedberg } 20033b19146dSJohan Hedberg 2004c05b9339SJohan Hedberg auth |= req->auth_req; 20052b64d153SBrian Gix 2006476585ecSJohan Hedberg ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability); 20072b64d153SBrian Gix if (ret) 20082b64d153SBrian Gix return SMP_UNSPECIFIED; 20092b64d153SBrian Gix 20104a74d658SJohan Hedberg set_bit(SMP_FLAG_CFM_PENDING, &smp->flags); 20112b64d153SBrian Gix 20122b64d153SBrian Gix /* Can't compose response until we have been confirmed */ 20134a74d658SJohan Hedberg if (test_bit(SMP_FLAG_TK_VALID, &smp->flags)) 20141cc61144SJohan Hedberg return smp_confirm(smp); 2015da85e5e5SVinicius Costa Gomes 2016da85e5e5SVinicius Costa Gomes return 0; 201788ba43b6SAnderson Briglia } 201888ba43b6SAnderson Briglia 2019dcee2b32SJohan Hedberg static u8 sc_check_confirm(struct smp_chan *smp) 2020dcee2b32SJohan Hedberg { 2021dcee2b32SJohan Hedberg struct l2cap_conn *conn = smp->conn; 2022dcee2b32SJohan Hedberg 2023dcee2b32SJohan Hedberg BT_DBG(""); 2024dcee2b32SJohan Hedberg 202538606f14SJohan Hedberg if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY) 202638606f14SJohan Hedberg return sc_passkey_round(smp, SMP_CMD_PAIRING_CONFIRM); 202738606f14SJohan Hedberg 2028dcee2b32SJohan Hedberg if (conn->hcon->out) { 2029dcee2b32SJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd), 2030dcee2b32SJohan Hedberg smp->prnd); 2031dcee2b32SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM); 2032dcee2b32SJohan Hedberg } 2033dcee2b32SJohan Hedberg 2034dcee2b32SJohan Hedberg return 0; 2035dcee2b32SJohan Hedberg } 2036dcee2b32SJohan Hedberg 203719c5ce9cSJohan Hedberg /* Work-around for some implementations that incorrectly copy RFU bits 203819c5ce9cSJohan Hedberg * from our security request and thereby create the impression that 203919c5ce9cSJohan Hedberg * we're doing SC when in fact the remote doesn't support it. 204019c5ce9cSJohan Hedberg */ 204119c5ce9cSJohan Hedberg static int fixup_sc_false_positive(struct smp_chan *smp) 204219c5ce9cSJohan Hedberg { 204319c5ce9cSJohan Hedberg struct l2cap_conn *conn = smp->conn; 204419c5ce9cSJohan Hedberg struct hci_conn *hcon = conn->hcon; 204519c5ce9cSJohan Hedberg struct hci_dev *hdev = hcon->hdev; 204619c5ce9cSJohan Hedberg struct smp_cmd_pairing *req, *rsp; 204719c5ce9cSJohan Hedberg u8 auth; 204819c5ce9cSJohan Hedberg 204919c5ce9cSJohan Hedberg /* The issue is only observed when we're in slave role */ 205019c5ce9cSJohan Hedberg if (hcon->out) 205119c5ce9cSJohan Hedberg return SMP_UNSPECIFIED; 205219c5ce9cSJohan Hedberg 205319c5ce9cSJohan Hedberg if (hci_dev_test_flag(hdev, HCI_SC_ONLY)) { 20542064ee33SMarcel Holtmann bt_dev_err(hdev, "refusing legacy fallback in SC-only mode"); 205519c5ce9cSJohan Hedberg return SMP_UNSPECIFIED; 205619c5ce9cSJohan Hedberg } 205719c5ce9cSJohan Hedberg 20582064ee33SMarcel Holtmann bt_dev_err(hdev, "trying to fall back to legacy SMP"); 205919c5ce9cSJohan Hedberg 206019c5ce9cSJohan Hedberg req = (void *) &smp->preq[1]; 206119c5ce9cSJohan Hedberg rsp = (void *) &smp->prsp[1]; 206219c5ce9cSJohan Hedberg 206319c5ce9cSJohan Hedberg /* Rebuild key dist flags which may have been cleared for SC */ 206419c5ce9cSJohan Hedberg smp->remote_key_dist = (req->init_key_dist & rsp->resp_key_dist); 206519c5ce9cSJohan Hedberg 206619c5ce9cSJohan Hedberg auth = req->auth_req & AUTH_REQ_MASK(hdev); 206719c5ce9cSJohan Hedberg 206819c5ce9cSJohan Hedberg if (tk_request(conn, 0, auth, rsp->io_capability, req->io_capability)) { 20692064ee33SMarcel Holtmann bt_dev_err(hdev, "failed to fall back to legacy SMP"); 207019c5ce9cSJohan Hedberg return SMP_UNSPECIFIED; 207119c5ce9cSJohan Hedberg } 207219c5ce9cSJohan Hedberg 207319c5ce9cSJohan Hedberg clear_bit(SMP_FLAG_SC, &smp->flags); 207419c5ce9cSJohan Hedberg 207519c5ce9cSJohan Hedberg return 0; 207619c5ce9cSJohan Hedberg } 207719c5ce9cSJohan Hedberg 2078da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb) 207988ba43b6SAnderson Briglia { 20805d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 20815d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 20827d24ddccSAnderson Briglia 208388ba43b6SAnderson Briglia BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave"); 208488ba43b6SAnderson Briglia 2085c46b98beSJohan Hedberg if (skb->len < sizeof(smp->pcnf)) 208638e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 2087c46b98beSJohan Hedberg 20881c1def09SVinicius Costa Gomes memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf)); 20891c1def09SVinicius Costa Gomes skb_pull(skb, sizeof(smp->pcnf)); 20907d24ddccSAnderson Briglia 209119c5ce9cSJohan Hedberg if (test_bit(SMP_FLAG_SC, &smp->flags)) { 209219c5ce9cSJohan Hedberg int ret; 209319c5ce9cSJohan Hedberg 209419c5ce9cSJohan Hedberg /* Public Key exchange must happen before any other steps */ 209519c5ce9cSJohan Hedberg if (test_bit(SMP_FLAG_REMOTE_PK, &smp->flags)) 2096dcee2b32SJohan Hedberg return sc_check_confirm(smp); 2097dcee2b32SJohan Hedberg 209819c5ce9cSJohan Hedberg BT_ERR("Unexpected SMP Pairing Confirm"); 209919c5ce9cSJohan Hedberg 210019c5ce9cSJohan Hedberg ret = fixup_sc_false_positive(smp); 210119c5ce9cSJohan Hedberg if (ret) 210219c5ce9cSJohan Hedberg return ret; 210319c5ce9cSJohan Hedberg } 210419c5ce9cSJohan Hedberg 2105b28b4943SJohan Hedberg if (conn->hcon->out) { 2106943a732aSJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd), 2107943a732aSJohan Hedberg smp->prnd); 2108b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM); 2109b28b4943SJohan Hedberg return 0; 2110b28b4943SJohan Hedberg } 2111b28b4943SJohan Hedberg 2112b28b4943SJohan Hedberg if (test_bit(SMP_FLAG_TK_VALID, &smp->flags)) 21131cc61144SJohan Hedberg return smp_confirm(smp); 2114983f9814SMarcel Holtmann 21154a74d658SJohan Hedberg set_bit(SMP_FLAG_CFM_PENDING, &smp->flags); 2116da85e5e5SVinicius Costa Gomes 2117da85e5e5SVinicius Costa Gomes return 0; 211888ba43b6SAnderson Briglia } 211988ba43b6SAnderson Briglia 2120da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) 212188ba43b6SAnderson Briglia { 21225d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 21235d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 2124191dc7feSJohan Hedberg struct hci_conn *hcon = conn->hcon; 2125eed467b5SHoward Chung u8 *pkax, *pkbx, *na, *nb, confirm_hint; 2126191dc7feSJohan Hedberg u32 passkey; 2127191dc7feSJohan Hedberg int err; 21287d24ddccSAnderson Briglia 21298aab4757SVinicius Costa Gomes BT_DBG("conn %p", conn); 21307d24ddccSAnderson Briglia 2131c46b98beSJohan Hedberg if (skb->len < sizeof(smp->rrnd)) 213238e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 2133c46b98beSJohan Hedberg 2134943a732aSJohan Hedberg memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd)); 21358aab4757SVinicius Costa Gomes skb_pull(skb, sizeof(smp->rrnd)); 213688ba43b6SAnderson Briglia 2137191dc7feSJohan Hedberg if (!test_bit(SMP_FLAG_SC, &smp->flags)) 2138861580a9SJohan Hedberg return smp_random(smp); 2139191dc7feSJohan Hedberg 2140580039e8SJohan Hedberg if (hcon->out) { 2141580039e8SJohan Hedberg pkax = smp->local_pk; 2142580039e8SJohan Hedberg pkbx = smp->remote_pk; 2143580039e8SJohan Hedberg na = smp->prnd; 2144580039e8SJohan Hedberg nb = smp->rrnd; 2145580039e8SJohan Hedberg } else { 2146580039e8SJohan Hedberg pkax = smp->remote_pk; 2147580039e8SJohan Hedberg pkbx = smp->local_pk; 2148580039e8SJohan Hedberg na = smp->rrnd; 2149580039e8SJohan Hedberg nb = smp->prnd; 2150580039e8SJohan Hedberg } 2151580039e8SJohan Hedberg 2152a29b0733SJohan Hedberg if (smp->method == REQ_OOB) { 2153a29b0733SJohan Hedberg if (!hcon->out) 2154a29b0733SJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, 2155a29b0733SJohan Hedberg sizeof(smp->prnd), smp->prnd); 2156a29b0733SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK); 2157a29b0733SJohan Hedberg goto mackey_and_ltk; 2158a29b0733SJohan Hedberg } 2159a29b0733SJohan Hedberg 216038606f14SJohan Hedberg /* Passkey entry has special treatment */ 216138606f14SJohan Hedberg if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY) 216238606f14SJohan Hedberg return sc_passkey_round(smp, SMP_CMD_PAIRING_RANDOM); 216338606f14SJohan Hedberg 2164191dc7feSJohan Hedberg if (hcon->out) { 2165191dc7feSJohan Hedberg u8 cfm[16]; 2166191dc7feSJohan Hedberg 2167191dc7feSJohan Hedberg err = smp_f4(smp->tfm_cmac, smp->remote_pk, smp->local_pk, 2168191dc7feSJohan Hedberg smp->rrnd, 0, cfm); 2169191dc7feSJohan Hedberg if (err) 2170191dc7feSJohan Hedberg return SMP_UNSPECIFIED; 2171191dc7feSJohan Hedberg 2172329d8230SJason A. Donenfeld if (crypto_memneq(smp->pcnf, cfm, 16)) 2173191dc7feSJohan Hedberg return SMP_CONFIRM_FAILED; 2174191dc7feSJohan Hedberg } else { 2175191dc7feSJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd), 2176191dc7feSJohan Hedberg smp->prnd); 2177191dc7feSJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK); 2178cee5f20fSHoward Chung 2179cee5f20fSHoward Chung /* Only Just-Works pairing requires extra checks */ 2180cee5f20fSHoward Chung if (smp->method != JUST_WORKS) 2181cee5f20fSHoward Chung goto mackey_and_ltk; 2182cee5f20fSHoward Chung 2183cee5f20fSHoward Chung /* If there already exists long term key in local host, leave 2184cee5f20fSHoward Chung * the decision to user space since the remote device could 2185cee5f20fSHoward Chung * be legitimate or malicious. 2186cee5f20fSHoward Chung */ 2187cee5f20fSHoward Chung if (hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, 2188cee5f20fSHoward Chung hcon->role)) { 2189eed467b5SHoward Chung /* Set passkey to 0. The value can be any number since 2190eed467b5SHoward Chung * it'll be ignored anyway. 2191eed467b5SHoward Chung */ 2192eed467b5SHoward Chung passkey = 0; 2193eed467b5SHoward Chung confirm_hint = 1; 2194eed467b5SHoward Chung goto confirm; 2195cee5f20fSHoward Chung } 2196191dc7feSJohan Hedberg } 2197191dc7feSJohan Hedberg 2198a29b0733SJohan Hedberg mackey_and_ltk: 2199760b018bSJohan Hedberg /* Generate MacKey and LTK */ 2200760b018bSJohan Hedberg err = sc_mackey_and_ltk(smp, smp->mackey, smp->tk); 2201760b018bSJohan Hedberg if (err) 2202760b018bSJohan Hedberg return SMP_UNSPECIFIED; 2203760b018bSJohan Hedberg 2204ffee202aSSonny Sasaka if (smp->method == REQ_OOB) { 2205dddd3059SJohan Hedberg if (hcon->out) { 220638606f14SJohan Hedberg sc_dhkey_check(smp); 2207dddd3059SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK); 2208dddd3059SJohan Hedberg } 2209dddd3059SJohan Hedberg return 0; 2210dddd3059SJohan Hedberg } 2211dddd3059SJohan Hedberg 221238606f14SJohan Hedberg err = smp_g2(smp->tfm_cmac, pkax, pkbx, na, nb, &passkey); 2213191dc7feSJohan Hedberg if (err) 2214191dc7feSJohan Hedberg return SMP_UNSPECIFIED; 2215191dc7feSJohan Hedberg 2216eed467b5SHoward Chung confirm_hint = 0; 2217eed467b5SHoward Chung 2218eed467b5SHoward Chung confirm: 2219ffee202aSSonny Sasaka if (smp->method == JUST_WORKS) 2220ffee202aSSonny Sasaka confirm_hint = 1; 2221ffee202aSSonny Sasaka 222238606f14SJohan Hedberg err = mgmt_user_confirm_request(hcon->hdev, &hcon->dst, hcon->type, 2223eed467b5SHoward Chung hcon->dst_type, passkey, confirm_hint); 222438606f14SJohan Hedberg if (err) 222538606f14SJohan Hedberg return SMP_UNSPECIFIED; 222638606f14SJohan Hedberg 222738606f14SJohan Hedberg set_bit(SMP_FLAG_WAIT_USER, &smp->flags); 222838606f14SJohan Hedberg 2229191dc7feSJohan Hedberg return 0; 223088ba43b6SAnderson Briglia } 223188ba43b6SAnderson Briglia 2232f81cd823SMarcel Holtmann static bool smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level) 2233988c5997SVinicius Costa Gomes { 2234c9839a11SVinicius Costa Gomes struct smp_ltk *key; 2235988c5997SVinicius Costa Gomes struct hci_conn *hcon = conn->hcon; 2236988c5997SVinicius Costa Gomes 2237f3a73d97SJohan Hedberg key = hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, hcon->role); 2238988c5997SVinicius Costa Gomes if (!key) 2239f81cd823SMarcel Holtmann return false; 2240988c5997SVinicius Costa Gomes 2241a6f7833cSJohan Hedberg if (smp_ltk_sec_level(key) < sec_level) 2242f81cd823SMarcel Holtmann return false; 22434dab7864SJohan Hedberg 224451a8efd7SJohan Hedberg if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags)) 2245f81cd823SMarcel Holtmann return true; 2246988c5997SVinicius Costa Gomes 22478b76ce34SJohan Hedberg hci_le_start_enc(hcon, key->ediv, key->rand, key->val, key->enc_size); 2248c9839a11SVinicius Costa Gomes hcon->enc_key_size = key->enc_size; 2249988c5997SVinicius Costa Gomes 2250fe59a05fSJohan Hedberg /* We never store STKs for master role, so clear this flag */ 2251fe59a05fSJohan Hedberg clear_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags); 2252fe59a05fSJohan Hedberg 2253f81cd823SMarcel Holtmann return true; 2254988c5997SVinicius Costa Gomes } 2255f1560463SMarcel Holtmann 225635dc6f83SJohan Hedberg bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level, 225735dc6f83SJohan Hedberg enum smp_key_pref key_pref) 2258854f4727SJohan Hedberg { 2259854f4727SJohan Hedberg if (sec_level == BT_SECURITY_LOW) 2260854f4727SJohan Hedberg return true; 2261854f4727SJohan Hedberg 226235dc6f83SJohan Hedberg /* If we're encrypted with an STK but the caller prefers using 226335dc6f83SJohan Hedberg * LTK claim insufficient security. This way we allow the 226435dc6f83SJohan Hedberg * connection to be re-encrypted with an LTK, even if the LTK 226535dc6f83SJohan Hedberg * provides the same level of security. Only exception is if we 226635dc6f83SJohan Hedberg * don't have an LTK (e.g. because of key distribution bits). 22679ab65d60SJohan Hedberg */ 226835dc6f83SJohan Hedberg if (key_pref == SMP_USE_LTK && 226935dc6f83SJohan Hedberg test_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags) && 2270f3a73d97SJohan Hedberg hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, hcon->role)) 22719ab65d60SJohan Hedberg return false; 22729ab65d60SJohan Hedberg 2273854f4727SJohan Hedberg if (hcon->sec_level >= sec_level) 2274854f4727SJohan Hedberg return true; 2275854f4727SJohan Hedberg 2276854f4727SJohan Hedberg return false; 2277854f4727SJohan Hedberg } 2278854f4727SJohan Hedberg 2279da85e5e5SVinicius Costa Gomes static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) 228088ba43b6SAnderson Briglia { 228188ba43b6SAnderson Briglia struct smp_cmd_security_req *rp = (void *) skb->data; 228288ba43b6SAnderson Briglia struct smp_cmd_pairing cp; 2283f1cb9af5SVinicius Costa Gomes struct hci_conn *hcon = conn->hcon; 22840edb14deSJohan Hedberg struct hci_dev *hdev = hcon->hdev; 22858aab4757SVinicius Costa Gomes struct smp_chan *smp; 2286c05b9339SJohan Hedberg u8 sec_level, auth; 228788ba43b6SAnderson Briglia 228888ba43b6SAnderson Briglia BT_DBG("conn %p", conn); 228988ba43b6SAnderson Briglia 2290c46b98beSJohan Hedberg if (skb->len < sizeof(*rp)) 229138e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 2292c46b98beSJohan Hedberg 229340bef302SJohan Hedberg if (hcon->role != HCI_ROLE_MASTER) 229486ca9eacSJohan Hedberg return SMP_CMD_NOTSUPP; 229586ca9eacSJohan Hedberg 22960edb14deSJohan Hedberg auth = rp->auth_req & AUTH_REQ_MASK(hdev); 2297c05b9339SJohan Hedberg 2298d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SC_ONLY) && !(auth & SMP_AUTH_SC)) 2299903b71c7SJohan Hedberg return SMP_AUTH_REQUIREMENTS; 2300903b71c7SJohan Hedberg 23015be5e275SJohan Hedberg if (hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT) 23021afc2a1aSJohan Hedberg sec_level = BT_SECURITY_MEDIUM; 23031afc2a1aSJohan Hedberg else 2304c05b9339SJohan Hedberg sec_level = authreq_to_seclevel(auth); 23051afc2a1aSJohan Hedberg 230664e759f5SSzymon Janc if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK)) { 230764e759f5SSzymon Janc /* If link is already encrypted with sufficient security we 230864e759f5SSzymon Janc * still need refresh encryption as per Core Spec 5.0 Vol 3, 230964e759f5SSzymon Janc * Part H 2.4.6 231064e759f5SSzymon Janc */ 231164e759f5SSzymon Janc smp_ltk_encrypt(conn, hcon->sec_level); 2312854f4727SJohan Hedberg return 0; 231364e759f5SSzymon Janc } 2314854f4727SJohan Hedberg 2315c7262e71SJohan Hedberg if (sec_level > hcon->pending_sec_level) 2316c7262e71SJohan Hedberg hcon->pending_sec_level = sec_level; 2317feb45eb5SVinicius Costa Gomes 23184dab7864SJohan Hedberg if (smp_ltk_encrypt(conn, hcon->pending_sec_level)) 2319988c5997SVinicius Costa Gomes return 0; 2320988c5997SVinicius Costa Gomes 23218aab4757SVinicius Costa Gomes smp = smp_chan_create(conn); 2322c29d2444SJohan Hedberg if (!smp) 2323c29d2444SJohan Hedberg return SMP_UNSPECIFIED; 2324d26a2345SVinicius Costa Gomes 2325d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_BONDABLE) && 2326c05b9339SJohan Hedberg (auth & SMP_AUTH_BONDING)) 2327616d55beSJohan Hedberg return SMP_PAIRING_NOTSUPP; 2328616d55beSJohan Hedberg 232988ba43b6SAnderson Briglia skb_pull(skb, sizeof(*rp)); 233088ba43b6SAnderson Briglia 2331da85e5e5SVinicius Costa Gomes memset(&cp, 0, sizeof(cp)); 2332c05b9339SJohan Hedberg build_pairing_cmd(conn, &cp, NULL, auth); 233388ba43b6SAnderson Briglia 23341c1def09SVinicius Costa Gomes smp->preq[0] = SMP_CMD_PAIRING_REQ; 23351c1def09SVinicius Costa Gomes memcpy(&smp->preq[1], &cp, sizeof(cp)); 2336f01ead31SAnderson Briglia 233788ba43b6SAnderson Briglia smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp); 2338b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP); 2339f1cb9af5SVinicius Costa Gomes 2340da85e5e5SVinicius Costa Gomes return 0; 234188ba43b6SAnderson Briglia } 234288ba43b6SAnderson Briglia 2343cc110922SVinicius Costa Gomes int smp_conn_security(struct hci_conn *hcon, __u8 sec_level) 2344eb492e01SAnderson Briglia { 2345cc110922SVinicius Costa Gomes struct l2cap_conn *conn = hcon->l2cap_data; 2346c68b7f12SJohan Hedberg struct l2cap_chan *chan; 23470a66cf20SJohan Hedberg struct smp_chan *smp; 23482b64d153SBrian Gix __u8 authreq; 2349fc75cc86SJohan Hedberg int ret; 2350eb492e01SAnderson Briglia 23513a0259bbSVinicius Costa Gomes BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level); 23523a0259bbSVinicius Costa Gomes 23530a66cf20SJohan Hedberg /* This may be NULL if there's an unexpected disconnection */ 23540a66cf20SJohan Hedberg if (!conn) 23550a66cf20SJohan Hedberg return 1; 23560a66cf20SJohan Hedberg 2357d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hcon->hdev, HCI_LE_ENABLED)) 23582e65c9d2SAndre Guedes return 1; 23592e65c9d2SAndre Guedes 236035dc6f83SJohan Hedberg if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK)) 2361f1cb9af5SVinicius Costa Gomes return 1; 2362f1cb9af5SVinicius Costa Gomes 2363c7262e71SJohan Hedberg if (sec_level > hcon->pending_sec_level) 2364c7262e71SJohan Hedberg hcon->pending_sec_level = sec_level; 2365c7262e71SJohan Hedberg 236640bef302SJohan Hedberg if (hcon->role == HCI_ROLE_MASTER) 2367c7262e71SJohan Hedberg if (smp_ltk_encrypt(conn, hcon->pending_sec_level)) 2368c7262e71SJohan Hedberg return 0; 2369d26a2345SVinicius Costa Gomes 2370d8949aadSJohan Hedberg chan = conn->smp; 2371d8949aadSJohan Hedberg if (!chan) { 23722064ee33SMarcel Holtmann bt_dev_err(hcon->hdev, "security requested but not available"); 2373d8949aadSJohan Hedberg return 1; 2374d8949aadSJohan Hedberg } 2375d8949aadSJohan Hedberg 2376fc75cc86SJohan Hedberg l2cap_chan_lock(chan); 2377fc75cc86SJohan Hedberg 2378fc75cc86SJohan Hedberg /* If SMP is already in progress ignore this request */ 2379fc75cc86SJohan Hedberg if (chan->data) { 2380fc75cc86SJohan Hedberg ret = 0; 2381fc75cc86SJohan Hedberg goto unlock; 2382fc75cc86SJohan Hedberg } 2383d26a2345SVinicius Costa Gomes 23848aab4757SVinicius Costa Gomes smp = smp_chan_create(conn); 2385fc75cc86SJohan Hedberg if (!smp) { 2386fc75cc86SJohan Hedberg ret = 1; 2387fc75cc86SJohan Hedberg goto unlock; 2388fc75cc86SJohan Hedberg } 23892b64d153SBrian Gix 23902b64d153SBrian Gix authreq = seclevel_to_authreq(sec_level); 2391d26a2345SVinicius Costa Gomes 2392a62da6f1SJohan Hedberg if (hci_dev_test_flag(hcon->hdev, HCI_SC_ENABLED)) { 2393d2eb9e10SJohan Hedberg authreq |= SMP_AUTH_SC; 2394a62da6f1SJohan Hedberg if (hci_dev_test_flag(hcon->hdev, HCI_SSP_ENABLED)) 2395a62da6f1SJohan Hedberg authreq |= SMP_AUTH_CT2; 2396a62da6f1SJohan Hedberg } 2397d2eb9e10SJohan Hedberg 2398c2aa30dbSArchie Pusaka /* Don't attempt to set MITM if setting is overridden by debugfs 2399c2aa30dbSArchie Pusaka * Needed to pass certification test SM/MAS/PKE/BV-01-C 2400c2aa30dbSArchie Pusaka */ 2401c2aa30dbSArchie Pusaka if (!hci_dev_test_flag(hcon->hdev, HCI_FORCE_NO_MITM)) { 240279897d20SJohan Hedberg /* Require MITM if IO Capability allows or the security level 240379897d20SJohan Hedberg * requires it. 24042e233644SJohan Hedberg */ 240579897d20SJohan Hedberg if (hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT || 2406c7262e71SJohan Hedberg hcon->pending_sec_level > BT_SECURITY_MEDIUM) 24072e233644SJohan Hedberg authreq |= SMP_AUTH_MITM; 2408c2aa30dbSArchie Pusaka } 24092e233644SJohan Hedberg 241040bef302SJohan Hedberg if (hcon->role == HCI_ROLE_MASTER) { 2411d26a2345SVinicius Costa Gomes struct smp_cmd_pairing cp; 2412f01ead31SAnderson Briglia 24132b64d153SBrian Gix build_pairing_cmd(conn, &cp, NULL, authreq); 24141c1def09SVinicius Costa Gomes smp->preq[0] = SMP_CMD_PAIRING_REQ; 24151c1def09SVinicius Costa Gomes memcpy(&smp->preq[1], &cp, sizeof(cp)); 2416f01ead31SAnderson Briglia 2417eb492e01SAnderson Briglia smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp); 2418b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP); 2419eb492e01SAnderson Briglia } else { 2420eb492e01SAnderson Briglia struct smp_cmd_security_req cp; 24212b64d153SBrian Gix cp.auth_req = authreq; 2422eb492e01SAnderson Briglia smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp); 2423b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_REQ); 2424eb492e01SAnderson Briglia } 2425eb492e01SAnderson Briglia 24264a74d658SJohan Hedberg set_bit(SMP_FLAG_INITIATOR, &smp->flags); 2427fc75cc86SJohan Hedberg ret = 0; 2428edca792cSJohan Hedberg 2429fc75cc86SJohan Hedberg unlock: 2430fc75cc86SJohan Hedberg l2cap_chan_unlock(chan); 2431fc75cc86SJohan Hedberg return ret; 2432eb492e01SAnderson Briglia } 2433eb492e01SAnderson Briglia 2434cb28c306SMatias Karhumaa int smp_cancel_and_remove_pairing(struct hci_dev *hdev, bdaddr_t *bdaddr, 2435cb28c306SMatias Karhumaa u8 addr_type) 2436c81d555aSJohan Hedberg { 2437cb28c306SMatias Karhumaa struct hci_conn *hcon; 2438cb28c306SMatias Karhumaa struct l2cap_conn *conn; 2439c81d555aSJohan Hedberg struct l2cap_chan *chan; 2440c81d555aSJohan Hedberg struct smp_chan *smp; 2441cb28c306SMatias Karhumaa int err; 2442c81d555aSJohan Hedberg 2443cb28c306SMatias Karhumaa err = hci_remove_ltk(hdev, bdaddr, addr_type); 2444cb28c306SMatias Karhumaa hci_remove_irk(hdev, bdaddr, addr_type); 2445cb28c306SMatias Karhumaa 2446cb28c306SMatias Karhumaa hcon = hci_conn_hash_lookup_le(hdev, bdaddr, addr_type); 2447cb28c306SMatias Karhumaa if (!hcon) 2448cb28c306SMatias Karhumaa goto done; 2449cb28c306SMatias Karhumaa 2450cb28c306SMatias Karhumaa conn = hcon->l2cap_data; 2451c81d555aSJohan Hedberg if (!conn) 2452cb28c306SMatias Karhumaa goto done; 2453c81d555aSJohan Hedberg 2454c81d555aSJohan Hedberg chan = conn->smp; 2455c81d555aSJohan Hedberg if (!chan) 2456cb28c306SMatias Karhumaa goto done; 2457c81d555aSJohan Hedberg 2458c81d555aSJohan Hedberg l2cap_chan_lock(chan); 2459c81d555aSJohan Hedberg 2460c81d555aSJohan Hedberg smp = chan->data; 2461c81d555aSJohan Hedberg if (smp) { 2462cb28c306SMatias Karhumaa /* Set keys to NULL to make sure smp_failure() does not try to 2463cb28c306SMatias Karhumaa * remove and free already invalidated rcu list entries. */ 2464cb28c306SMatias Karhumaa smp->ltk = NULL; 2465cb28c306SMatias Karhumaa smp->slave_ltk = NULL; 2466cb28c306SMatias Karhumaa smp->remote_irk = NULL; 2467cb28c306SMatias Karhumaa 2468c81d555aSJohan Hedberg if (test_bit(SMP_FLAG_COMPLETE, &smp->flags)) 2469c81d555aSJohan Hedberg smp_failure(conn, 0); 2470c81d555aSJohan Hedberg else 2471c81d555aSJohan Hedberg smp_failure(conn, SMP_UNSPECIFIED); 2472cb28c306SMatias Karhumaa err = 0; 2473c81d555aSJohan Hedberg } 2474c81d555aSJohan Hedberg 2475c81d555aSJohan Hedberg l2cap_chan_unlock(chan); 2476cb28c306SMatias Karhumaa 2477cb28c306SMatias Karhumaa done: 2478cb28c306SMatias Karhumaa return err; 2479c81d555aSJohan Hedberg } 2480c81d555aSJohan Hedberg 24817034b911SVinicius Costa Gomes static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb) 24827034b911SVinicius Costa Gomes { 248316b90839SVinicius Costa Gomes struct smp_cmd_encrypt_info *rp = (void *) skb->data; 24845d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 24855d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 248616b90839SVinicius Costa Gomes 2487c46b98beSJohan Hedberg BT_DBG("conn %p", conn); 2488c46b98beSJohan Hedberg 2489c46b98beSJohan Hedberg if (skb->len < sizeof(*rp)) 249038e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 2491c46b98beSJohan Hedberg 2492600a8749SAlain Michaud /* Pairing is aborted if any blocked keys are distributed */ 2493600a8749SAlain Michaud if (hci_is_blocked_key(conn->hcon->hdev, HCI_BLOCKED_KEY_TYPE_LTK, 2494600a8749SAlain Michaud rp->ltk)) { 2495600a8749SAlain Michaud bt_dev_warn_ratelimited(conn->hcon->hdev, 2496600a8749SAlain Michaud "LTK blocked for %pMR", 2497600a8749SAlain Michaud &conn->hcon->dst); 2498600a8749SAlain Michaud return SMP_INVALID_PARAMS; 2499600a8749SAlain Michaud } 2500600a8749SAlain Michaud 2501b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_MASTER_IDENT); 25026131ddc8SJohan Hedberg 250316b90839SVinicius Costa Gomes skb_pull(skb, sizeof(*rp)); 250416b90839SVinicius Costa Gomes 25051c1def09SVinicius Costa Gomes memcpy(smp->tk, rp->ltk, sizeof(smp->tk)); 250616b90839SVinicius Costa Gomes 25077034b911SVinicius Costa Gomes return 0; 25087034b911SVinicius Costa Gomes } 25097034b911SVinicius Costa Gomes 25107034b911SVinicius Costa Gomes static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb) 25117034b911SVinicius Costa Gomes { 251216b90839SVinicius Costa Gomes struct smp_cmd_master_ident *rp = (void *) skb->data; 25135d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 25145d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 2515c9839a11SVinicius Costa Gomes struct hci_dev *hdev = conn->hcon->hdev; 2516c9839a11SVinicius Costa Gomes struct hci_conn *hcon = conn->hcon; 251723d0e128SJohan Hedberg struct smp_ltk *ltk; 2518c9839a11SVinicius Costa Gomes u8 authenticated; 25197034b911SVinicius Costa Gomes 2520c46b98beSJohan Hedberg BT_DBG("conn %p", conn); 2521c46b98beSJohan Hedberg 2522c46b98beSJohan Hedberg if (skb->len < sizeof(*rp)) 252338e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 2524c46b98beSJohan Hedberg 25259747a9f3SJohan Hedberg /* Mark the information as received */ 25269747a9f3SJohan Hedberg smp->remote_key_dist &= ~SMP_DIST_ENC_KEY; 25279747a9f3SJohan Hedberg 2528b28b4943SJohan Hedberg if (smp->remote_key_dist & SMP_DIST_ID_KEY) 2529b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO); 2530196332f5SJohan Hedberg else if (smp->remote_key_dist & SMP_DIST_SIGN) 2531196332f5SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO); 2532b28b4943SJohan Hedberg 253316b90839SVinicius Costa Gomes skb_pull(skb, sizeof(*rp)); 253416b90839SVinicius Costa Gomes 2535ce39fb4eSMarcel Holtmann authenticated = (hcon->sec_level == BT_SECURITY_HIGH); 25362ceba539SJohan Hedberg ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, SMP_LTK, 2537ce39fb4eSMarcel Holtmann authenticated, smp->tk, smp->enc_key_size, 253804124681SGustavo F. Padovan rp->ediv, rp->rand); 253923d0e128SJohan Hedberg smp->ltk = ltk; 2540c6e81e9aSJohan Hedberg if (!(smp->remote_key_dist & KEY_DIST_MASK)) 2541d6268e86SJohan Hedberg smp_distribute_keys(smp); 25427034b911SVinicius Costa Gomes 25437034b911SVinicius Costa Gomes return 0; 25447034b911SVinicius Costa Gomes } 25457034b911SVinicius Costa Gomes 2546fd349c02SJohan Hedberg static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb) 2547fd349c02SJohan Hedberg { 2548fd349c02SJohan Hedberg struct smp_cmd_ident_info *info = (void *) skb->data; 25495d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 25505d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 2551fd349c02SJohan Hedberg 2552fd349c02SJohan Hedberg BT_DBG(""); 2553fd349c02SJohan Hedberg 2554fd349c02SJohan Hedberg if (skb->len < sizeof(*info)) 255538e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 2556fd349c02SJohan Hedberg 2557600a8749SAlain Michaud /* Pairing is aborted if any blocked keys are distributed */ 2558600a8749SAlain Michaud if (hci_is_blocked_key(conn->hcon->hdev, HCI_BLOCKED_KEY_TYPE_IRK, 2559600a8749SAlain Michaud info->irk)) { 2560600a8749SAlain Michaud bt_dev_warn_ratelimited(conn->hcon->hdev, 2561600a8749SAlain Michaud "Identity key blocked for %pMR", 2562600a8749SAlain Michaud &conn->hcon->dst); 2563600a8749SAlain Michaud return SMP_INVALID_PARAMS; 2564600a8749SAlain Michaud } 2565600a8749SAlain Michaud 2566b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_ADDR_INFO); 25676131ddc8SJohan Hedberg 2568fd349c02SJohan Hedberg skb_pull(skb, sizeof(*info)); 2569fd349c02SJohan Hedberg 2570fd349c02SJohan Hedberg memcpy(smp->irk, info->irk, 16); 2571fd349c02SJohan Hedberg 2572fd349c02SJohan Hedberg return 0; 2573fd349c02SJohan Hedberg } 2574fd349c02SJohan Hedberg 2575fd349c02SJohan Hedberg static int smp_cmd_ident_addr_info(struct l2cap_conn *conn, 2576fd349c02SJohan Hedberg struct sk_buff *skb) 2577fd349c02SJohan Hedberg { 2578fd349c02SJohan Hedberg struct smp_cmd_ident_addr_info *info = (void *) skb->data; 25795d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 25805d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 2581fd349c02SJohan Hedberg struct hci_conn *hcon = conn->hcon; 2582fd349c02SJohan Hedberg bdaddr_t rpa; 2583fd349c02SJohan Hedberg 2584fd349c02SJohan Hedberg BT_DBG(""); 2585fd349c02SJohan Hedberg 2586fd349c02SJohan Hedberg if (skb->len < sizeof(*info)) 258738e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 2588fd349c02SJohan Hedberg 25899747a9f3SJohan Hedberg /* Mark the information as received */ 25909747a9f3SJohan Hedberg smp->remote_key_dist &= ~SMP_DIST_ID_KEY; 25919747a9f3SJohan Hedberg 2592b28b4943SJohan Hedberg if (smp->remote_key_dist & SMP_DIST_SIGN) 2593b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO); 2594b28b4943SJohan Hedberg 2595fd349c02SJohan Hedberg skb_pull(skb, sizeof(*info)); 2596fd349c02SJohan Hedberg 2597a9a58f86SJohan Hedberg /* Strictly speaking the Core Specification (4.1) allows sending 2598a9a58f86SJohan Hedberg * an empty address which would force us to rely on just the IRK 2599a9a58f86SJohan Hedberg * as "identity information". However, since such 2600a9a58f86SJohan Hedberg * implementations are not known of and in order to not over 2601a9a58f86SJohan Hedberg * complicate our implementation, simply pretend that we never 2602a9a58f86SJohan Hedberg * received an IRK for such a device. 2603e12af489SJohan Hedberg * 2604e12af489SJohan Hedberg * The Identity Address must also be a Static Random or Public 2605e12af489SJohan Hedberg * Address, which hci_is_identity_address() checks for. 2606a9a58f86SJohan Hedberg */ 2607e12af489SJohan Hedberg if (!bacmp(&info->bdaddr, BDADDR_ANY) || 2608e12af489SJohan Hedberg !hci_is_identity_address(&info->bdaddr, info->addr_type)) { 26092064ee33SMarcel Holtmann bt_dev_err(hcon->hdev, "ignoring IRK with no identity address"); 261031dd624eSJohan Hedberg goto distribute; 2611a9a58f86SJohan Hedberg } 2612a9a58f86SJohan Hedberg 26131d87b88bSSzymon Janc /* Drop IRK if peer is using identity address during pairing but is 26141d87b88bSSzymon Janc * providing different address as identity information. 26151d87b88bSSzymon Janc * 26161d87b88bSSzymon Janc * Microsoft Surface Precision Mouse is known to have this bug. 26171d87b88bSSzymon Janc */ 26181d87b88bSSzymon Janc if (hci_is_identity_address(&hcon->dst, hcon->dst_type) && 26191d87b88bSSzymon Janc (bacmp(&info->bdaddr, &hcon->dst) || 26201d87b88bSSzymon Janc info->addr_type != hcon->dst_type)) { 26211d87b88bSSzymon Janc bt_dev_err(hcon->hdev, 26221d87b88bSSzymon Janc "ignoring IRK with invalid identity address"); 26231d87b88bSSzymon Janc goto distribute; 26241d87b88bSSzymon Janc } 26251d87b88bSSzymon Janc 2626fd349c02SJohan Hedberg bacpy(&smp->id_addr, &info->bdaddr); 2627fd349c02SJohan Hedberg smp->id_addr_type = info->addr_type; 2628fd349c02SJohan Hedberg 2629fd349c02SJohan Hedberg if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type)) 2630fd349c02SJohan Hedberg bacpy(&rpa, &hcon->dst); 2631fd349c02SJohan Hedberg else 2632fd349c02SJohan Hedberg bacpy(&rpa, BDADDR_ANY); 2633fd349c02SJohan Hedberg 263423d0e128SJohan Hedberg smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr, 263523d0e128SJohan Hedberg smp->id_addr_type, smp->irk, &rpa); 2636fd349c02SJohan Hedberg 263731dd624eSJohan Hedberg distribute: 2638c6e81e9aSJohan Hedberg if (!(smp->remote_key_dist & KEY_DIST_MASK)) 2639d6268e86SJohan Hedberg smp_distribute_keys(smp); 2640fd349c02SJohan Hedberg 2641fd349c02SJohan Hedberg return 0; 2642fd349c02SJohan Hedberg } 2643fd349c02SJohan Hedberg 26447ee4ea36SMarcel Holtmann static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb) 26457ee4ea36SMarcel Holtmann { 26467ee4ea36SMarcel Holtmann struct smp_cmd_sign_info *rp = (void *) skb->data; 26475d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 26485d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 26497ee4ea36SMarcel Holtmann struct smp_csrk *csrk; 26507ee4ea36SMarcel Holtmann 26517ee4ea36SMarcel Holtmann BT_DBG("conn %p", conn); 26527ee4ea36SMarcel Holtmann 26537ee4ea36SMarcel Holtmann if (skb->len < sizeof(*rp)) 265438e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 26557ee4ea36SMarcel Holtmann 26567ee4ea36SMarcel Holtmann /* Mark the information as received */ 26577ee4ea36SMarcel Holtmann smp->remote_key_dist &= ~SMP_DIST_SIGN; 26587ee4ea36SMarcel Holtmann 26597ee4ea36SMarcel Holtmann skb_pull(skb, sizeof(*rp)); 26607ee4ea36SMarcel Holtmann 26617ee4ea36SMarcel Holtmann csrk = kzalloc(sizeof(*csrk), GFP_KERNEL); 26627ee4ea36SMarcel Holtmann if (csrk) { 26634cd3928aSJohan Hedberg if (conn->hcon->sec_level > BT_SECURITY_MEDIUM) 26644cd3928aSJohan Hedberg csrk->type = MGMT_CSRK_REMOTE_AUTHENTICATED; 26654cd3928aSJohan Hedberg else 26664cd3928aSJohan Hedberg csrk->type = MGMT_CSRK_REMOTE_UNAUTHENTICATED; 26677ee4ea36SMarcel Holtmann memcpy(csrk->val, rp->csrk, sizeof(csrk->val)); 26687ee4ea36SMarcel Holtmann } 26697ee4ea36SMarcel Holtmann smp->csrk = csrk; 2670d6268e86SJohan Hedberg smp_distribute_keys(smp); 26717ee4ea36SMarcel Holtmann 26727ee4ea36SMarcel Holtmann return 0; 26737ee4ea36SMarcel Holtmann } 26747ee4ea36SMarcel Holtmann 26755e3d3d9bSJohan Hedberg static u8 sc_select_method(struct smp_chan *smp) 26765e3d3d9bSJohan Hedberg { 26775e3d3d9bSJohan Hedberg struct l2cap_conn *conn = smp->conn; 26785e3d3d9bSJohan Hedberg struct hci_conn *hcon = conn->hcon; 26795e3d3d9bSJohan Hedberg struct smp_cmd_pairing *local, *remote; 26805e3d3d9bSJohan Hedberg u8 local_mitm, remote_mitm, local_io, remote_io, method; 26815e3d3d9bSJohan Hedberg 26821a8bab4fSJohan Hedberg if (test_bit(SMP_FLAG_REMOTE_OOB, &smp->flags) || 26831a8bab4fSJohan Hedberg test_bit(SMP_FLAG_LOCAL_OOB, &smp->flags)) 2684a29b0733SJohan Hedberg return REQ_OOB; 2685a29b0733SJohan Hedberg 26865e3d3d9bSJohan Hedberg /* The preq/prsp contain the raw Pairing Request/Response PDUs 26875e3d3d9bSJohan Hedberg * which are needed as inputs to some crypto functions. To get 26885e3d3d9bSJohan Hedberg * the "struct smp_cmd_pairing" from them we need to skip the 26895e3d3d9bSJohan Hedberg * first byte which contains the opcode. 26905e3d3d9bSJohan Hedberg */ 26915e3d3d9bSJohan Hedberg if (hcon->out) { 26925e3d3d9bSJohan Hedberg local = (void *) &smp->preq[1]; 26935e3d3d9bSJohan Hedberg remote = (void *) &smp->prsp[1]; 26945e3d3d9bSJohan Hedberg } else { 26955e3d3d9bSJohan Hedberg local = (void *) &smp->prsp[1]; 26965e3d3d9bSJohan Hedberg remote = (void *) &smp->preq[1]; 26975e3d3d9bSJohan Hedberg } 26985e3d3d9bSJohan Hedberg 26995e3d3d9bSJohan Hedberg local_io = local->io_capability; 27005e3d3d9bSJohan Hedberg remote_io = remote->io_capability; 27015e3d3d9bSJohan Hedberg 27025e3d3d9bSJohan Hedberg local_mitm = (local->auth_req & SMP_AUTH_MITM); 27035e3d3d9bSJohan Hedberg remote_mitm = (remote->auth_req & SMP_AUTH_MITM); 27045e3d3d9bSJohan Hedberg 27055e3d3d9bSJohan Hedberg /* If either side wants MITM, look up the method from the table, 27065e3d3d9bSJohan Hedberg * otherwise use JUST WORKS. 27075e3d3d9bSJohan Hedberg */ 27085e3d3d9bSJohan Hedberg if (local_mitm || remote_mitm) 27095e3d3d9bSJohan Hedberg method = get_auth_method(smp, local_io, remote_io); 27105e3d3d9bSJohan Hedberg else 27115e3d3d9bSJohan Hedberg method = JUST_WORKS; 27125e3d3d9bSJohan Hedberg 27135e3d3d9bSJohan Hedberg /* Don't confirm locally initiated pairing attempts */ 27145e3d3d9bSJohan Hedberg if (method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR, &smp->flags)) 27155e3d3d9bSJohan Hedberg method = JUST_WORKS; 27165e3d3d9bSJohan Hedberg 27175e3d3d9bSJohan Hedberg return method; 27185e3d3d9bSJohan Hedberg } 27195e3d3d9bSJohan Hedberg 2720d8f8edbeSJohan Hedberg static int smp_cmd_public_key(struct l2cap_conn *conn, struct sk_buff *skb) 2721d8f8edbeSJohan Hedberg { 2722d8f8edbeSJohan Hedberg struct smp_cmd_public_key *key = (void *) skb->data; 2723d8f8edbeSJohan Hedberg struct hci_conn *hcon = conn->hcon; 2724d8f8edbeSJohan Hedberg struct l2cap_chan *chan = conn->smp; 2725d8f8edbeSJohan Hedberg struct smp_chan *smp = chan->data; 27265e3d3d9bSJohan Hedberg struct hci_dev *hdev = hcon->hdev; 2727c0153b0bSTudor Ambarus struct crypto_kpp *tfm_ecdh; 2728cbbbe3e2SJohan Hedberg struct smp_cmd_pairing_confirm cfm; 2729d8f8edbeSJohan Hedberg int err; 2730d8f8edbeSJohan Hedberg 2731d8f8edbeSJohan Hedberg BT_DBG("conn %p", conn); 2732d8f8edbeSJohan Hedberg 2733d8f8edbeSJohan Hedberg if (skb->len < sizeof(*key)) 2734d8f8edbeSJohan Hedberg return SMP_INVALID_PARAMS; 2735d8f8edbeSJohan Hedberg 2736d8f8edbeSJohan Hedberg memcpy(smp->remote_pk, key, 64); 2737d8f8edbeSJohan Hedberg 2738a8ca617cSJohan Hedberg if (test_bit(SMP_FLAG_REMOTE_OOB, &smp->flags)) { 2739a8ca617cSJohan Hedberg err = smp_f4(smp->tfm_cmac, smp->remote_pk, smp->remote_pk, 2740a8ca617cSJohan Hedberg smp->rr, 0, cfm.confirm_val); 2741a8ca617cSJohan Hedberg if (err) 2742a8ca617cSJohan Hedberg return SMP_UNSPECIFIED; 2743a8ca617cSJohan Hedberg 2744329d8230SJason A. Donenfeld if (crypto_memneq(cfm.confirm_val, smp->pcnf, 16)) 2745a8ca617cSJohan Hedberg return SMP_CONFIRM_FAILED; 2746a8ca617cSJohan Hedberg } 2747a8ca617cSJohan Hedberg 2748d8f8edbeSJohan Hedberg /* Non-initiating device sends its public key after receiving 2749d8f8edbeSJohan Hedberg * the key from the initiating device. 2750d8f8edbeSJohan Hedberg */ 2751d8f8edbeSJohan Hedberg if (!hcon->out) { 2752d8f8edbeSJohan Hedberg err = sc_send_public_key(smp); 2753d8f8edbeSJohan Hedberg if (err) 2754d8f8edbeSJohan Hedberg return err; 2755d8f8edbeSJohan Hedberg } 2756d8f8edbeSJohan Hedberg 2757c7a3d57dSJohan Hedberg SMP_DBG("Remote Public Key X: %32phN", smp->remote_pk); 2758e091526dSMarcel Holtmann SMP_DBG("Remote Public Key Y: %32phN", smp->remote_pk + 32); 2759d8f8edbeSJohan Hedberg 2760c0153b0bSTudor Ambarus /* Compute the shared secret on the same crypto tfm on which the private 2761c0153b0bSTudor Ambarus * key was set/generated. 2762c0153b0bSTudor Ambarus */ 2763c0153b0bSTudor Ambarus if (test_bit(SMP_FLAG_LOCAL_OOB, &smp->flags)) { 27644ba5175fSMatias Karhumaa struct l2cap_chan *hchan = hdev->smp_data; 27654ba5175fSMatias Karhumaa struct smp_dev *smp_dev; 27664ba5175fSMatias Karhumaa 27674ba5175fSMatias Karhumaa if (!hchan || !hchan->data) 27684ba5175fSMatias Karhumaa return SMP_UNSPECIFIED; 27694ba5175fSMatias Karhumaa 27704ba5175fSMatias Karhumaa smp_dev = hchan->data; 2771c0153b0bSTudor Ambarus 2772c0153b0bSTudor Ambarus tfm_ecdh = smp_dev->tfm_ecdh; 2773c0153b0bSTudor Ambarus } else { 2774c0153b0bSTudor Ambarus tfm_ecdh = smp->tfm_ecdh; 2775c0153b0bSTudor Ambarus } 2776c0153b0bSTudor Ambarus 2777c0153b0bSTudor Ambarus if (compute_ecdh_secret(tfm_ecdh, smp->remote_pk, smp->dhkey)) 2778d8f8edbeSJohan Hedberg return SMP_UNSPECIFIED; 2779d8f8edbeSJohan Hedberg 2780c7a3d57dSJohan Hedberg SMP_DBG("DHKey %32phN", smp->dhkey); 2781d8f8edbeSJohan Hedberg 2782d8f8edbeSJohan Hedberg set_bit(SMP_FLAG_REMOTE_PK, &smp->flags); 2783d8f8edbeSJohan Hedberg 27845e3d3d9bSJohan Hedberg smp->method = sc_select_method(smp); 27855e3d3d9bSJohan Hedberg 27865e3d3d9bSJohan Hedberg BT_DBG("%s selected method 0x%02x", hdev->name, smp->method); 27875e3d3d9bSJohan Hedberg 27885e3d3d9bSJohan Hedberg /* JUST_WORKS and JUST_CFM result in an unauthenticated key */ 27895e3d3d9bSJohan Hedberg if (smp->method == JUST_WORKS || smp->method == JUST_CFM) 27905e3d3d9bSJohan Hedberg hcon->pending_sec_level = BT_SECURITY_MEDIUM; 27915e3d3d9bSJohan Hedberg else 27925e3d3d9bSJohan Hedberg hcon->pending_sec_level = BT_SECURITY_FIPS; 27935e3d3d9bSJohan Hedberg 2794329d8230SJason A. Donenfeld if (!crypto_memneq(debug_pk, smp->remote_pk, 64)) 2795aeb7d461SJohan Hedberg set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags); 2796aeb7d461SJohan Hedberg 279738606f14SJohan Hedberg if (smp->method == DSP_PASSKEY) { 279838606f14SJohan Hedberg get_random_bytes(&hcon->passkey_notify, 279938606f14SJohan Hedberg sizeof(hcon->passkey_notify)); 280038606f14SJohan Hedberg hcon->passkey_notify %= 1000000; 280138606f14SJohan Hedberg hcon->passkey_entered = 0; 280238606f14SJohan Hedberg smp->passkey_round = 0; 280338606f14SJohan Hedberg if (mgmt_user_passkey_notify(hdev, &hcon->dst, hcon->type, 280438606f14SJohan Hedberg hcon->dst_type, 280538606f14SJohan Hedberg hcon->passkey_notify, 280638606f14SJohan Hedberg hcon->passkey_entered)) 280738606f14SJohan Hedberg return SMP_UNSPECIFIED; 280838606f14SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); 280938606f14SJohan Hedberg return sc_passkey_round(smp, SMP_CMD_PUBLIC_KEY); 281038606f14SJohan Hedberg } 281138606f14SJohan Hedberg 281294ea7257SJohan Hedberg if (smp->method == REQ_OOB) { 2813a29b0733SJohan Hedberg if (hcon->out) 2814a29b0733SJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, 2815a29b0733SJohan Hedberg sizeof(smp->prnd), smp->prnd); 2816a29b0733SJohan Hedberg 2817a29b0733SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM); 2818a29b0733SJohan Hedberg 2819a29b0733SJohan Hedberg return 0; 2820a29b0733SJohan Hedberg } 2821a29b0733SJohan Hedberg 282238606f14SJohan Hedberg if (hcon->out) 282338606f14SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); 282438606f14SJohan Hedberg 282538606f14SJohan Hedberg if (smp->method == REQ_PASSKEY) { 282638606f14SJohan Hedberg if (mgmt_user_passkey_request(hdev, &hcon->dst, hcon->type, 282738606f14SJohan Hedberg hcon->dst_type)) 282838606f14SJohan Hedberg return SMP_UNSPECIFIED; 282938606f14SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); 283038606f14SJohan Hedberg set_bit(SMP_FLAG_WAIT_USER, &smp->flags); 283138606f14SJohan Hedberg return 0; 283238606f14SJohan Hedberg } 283338606f14SJohan Hedberg 2834cbbbe3e2SJohan Hedberg /* The Initiating device waits for the non-initiating device to 2835cbbbe3e2SJohan Hedberg * send the confirm value. 2836cbbbe3e2SJohan Hedberg */ 2837cbbbe3e2SJohan Hedberg if (conn->hcon->out) 2838cbbbe3e2SJohan Hedberg return 0; 2839cbbbe3e2SJohan Hedberg 2840cbbbe3e2SJohan Hedberg err = smp_f4(smp->tfm_cmac, smp->local_pk, smp->remote_pk, smp->prnd, 2841cbbbe3e2SJohan Hedberg 0, cfm.confirm_val); 2842cbbbe3e2SJohan Hedberg if (err) 2843cbbbe3e2SJohan Hedberg return SMP_UNSPECIFIED; 2844cbbbe3e2SJohan Hedberg 2845cbbbe3e2SJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cfm), &cfm); 2846cbbbe3e2SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM); 2847cbbbe3e2SJohan Hedberg 2848d8f8edbeSJohan Hedberg return 0; 2849d8f8edbeSJohan Hedberg } 2850d8f8edbeSJohan Hedberg 28516433a9a2SJohan Hedberg static int smp_cmd_dhkey_check(struct l2cap_conn *conn, struct sk_buff *skb) 28526433a9a2SJohan Hedberg { 28536433a9a2SJohan Hedberg struct smp_cmd_dhkey_check *check = (void *) skb->data; 28546433a9a2SJohan Hedberg struct l2cap_chan *chan = conn->smp; 28556433a9a2SJohan Hedberg struct hci_conn *hcon = conn->hcon; 28566433a9a2SJohan Hedberg struct smp_chan *smp = chan->data; 28576433a9a2SJohan Hedberg u8 a[7], b[7], *local_addr, *remote_addr; 28586433a9a2SJohan Hedberg u8 io_cap[3], r[16], e[16]; 28596433a9a2SJohan Hedberg int err; 28606433a9a2SJohan Hedberg 28616433a9a2SJohan Hedberg BT_DBG("conn %p", conn); 28626433a9a2SJohan Hedberg 28636433a9a2SJohan Hedberg if (skb->len < sizeof(*check)) 28646433a9a2SJohan Hedberg return SMP_INVALID_PARAMS; 28656433a9a2SJohan Hedberg 28666433a9a2SJohan Hedberg memcpy(a, &hcon->init_addr, 6); 28676433a9a2SJohan Hedberg memcpy(b, &hcon->resp_addr, 6); 28686433a9a2SJohan Hedberg a[6] = hcon->init_addr_type; 28696433a9a2SJohan Hedberg b[6] = hcon->resp_addr_type; 28706433a9a2SJohan Hedberg 28716433a9a2SJohan Hedberg if (hcon->out) { 28726433a9a2SJohan Hedberg local_addr = a; 28736433a9a2SJohan Hedberg remote_addr = b; 28746433a9a2SJohan Hedberg memcpy(io_cap, &smp->prsp[1], 3); 28756433a9a2SJohan Hedberg } else { 28766433a9a2SJohan Hedberg local_addr = b; 28776433a9a2SJohan Hedberg remote_addr = a; 28786433a9a2SJohan Hedberg memcpy(io_cap, &smp->preq[1], 3); 28796433a9a2SJohan Hedberg } 28806433a9a2SJohan Hedberg 28816433a9a2SJohan Hedberg memset(r, 0, sizeof(r)); 28826433a9a2SJohan Hedberg 288338606f14SJohan Hedberg if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY) 288438606f14SJohan Hedberg put_unaligned_le32(hcon->passkey_notify, r); 2885882fafadSJohan Hedberg else if (smp->method == REQ_OOB) 2886882fafadSJohan Hedberg memcpy(r, smp->lr, 16); 288738606f14SJohan Hedberg 28886433a9a2SJohan Hedberg err = smp_f6(smp->tfm_cmac, smp->mackey, smp->rrnd, smp->prnd, r, 28896433a9a2SJohan Hedberg io_cap, remote_addr, local_addr, e); 28906433a9a2SJohan Hedberg if (err) 28916433a9a2SJohan Hedberg return SMP_UNSPECIFIED; 28926433a9a2SJohan Hedberg 2893329d8230SJason A. Donenfeld if (crypto_memneq(check->e, e, 16)) 28946433a9a2SJohan Hedberg return SMP_DHKEY_CHECK_FAILED; 28956433a9a2SJohan Hedberg 2896d3e54a87SJohan Hedberg if (!hcon->out) { 2897d3e54a87SJohan Hedberg if (test_bit(SMP_FLAG_WAIT_USER, &smp->flags)) { 2898d3e54a87SJohan Hedberg set_bit(SMP_FLAG_DHKEY_PENDING, &smp->flags); 2899d3e54a87SJohan Hedberg return 0; 2900d3e54a87SJohan Hedberg } 2901d378a2d7SJohan Hedberg 2902d3e54a87SJohan Hedberg /* Slave sends DHKey check as response to master */ 2903d3e54a87SJohan Hedberg sc_dhkey_check(smp); 2904d3e54a87SJohan Hedberg } 2905d378a2d7SJohan Hedberg 2906d3e54a87SJohan Hedberg sc_add_ltk(smp); 29076433a9a2SJohan Hedberg 29086433a9a2SJohan Hedberg if (hcon->out) { 29098b76ce34SJohan Hedberg hci_le_start_enc(hcon, 0, 0, smp->tk, smp->enc_key_size); 29106433a9a2SJohan Hedberg hcon->enc_key_size = smp->enc_key_size; 29116433a9a2SJohan Hedberg } 29126433a9a2SJohan Hedberg 29136433a9a2SJohan Hedberg return 0; 29146433a9a2SJohan Hedberg } 29156433a9a2SJohan Hedberg 29161408bb6eSJohan Hedberg static int smp_cmd_keypress_notify(struct l2cap_conn *conn, 29171408bb6eSJohan Hedberg struct sk_buff *skb) 29181408bb6eSJohan Hedberg { 29191408bb6eSJohan Hedberg struct smp_cmd_keypress_notify *kp = (void *) skb->data; 29201408bb6eSJohan Hedberg 29211408bb6eSJohan Hedberg BT_DBG("value 0x%02x", kp->value); 29221408bb6eSJohan Hedberg 29231408bb6eSJohan Hedberg return 0; 29241408bb6eSJohan Hedberg } 29251408bb6eSJohan Hedberg 29264befb867SJohan Hedberg static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb) 2927eb492e01SAnderson Briglia { 29285d88cc73SJohan Hedberg struct l2cap_conn *conn = chan->conn; 29297b9899dbSMarcel Holtmann struct hci_conn *hcon = conn->hcon; 2930b28b4943SJohan Hedberg struct smp_chan *smp; 293192381f5cSMarcel Holtmann __u8 code, reason; 2932eb492e01SAnderson Briglia int err = 0; 2933eb492e01SAnderson Briglia 29348ae9b984SJohan Hedberg if (skb->len < 1) 293592381f5cSMarcel Holtmann return -EILSEQ; 293692381f5cSMarcel Holtmann 2937d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hcon->hdev, HCI_LE_ENABLED)) { 29382e65c9d2SAndre Guedes reason = SMP_PAIRING_NOTSUPP; 29392e65c9d2SAndre Guedes goto done; 29402e65c9d2SAndre Guedes } 29412e65c9d2SAndre Guedes 294292381f5cSMarcel Holtmann code = skb->data[0]; 2943eb492e01SAnderson Briglia skb_pull(skb, sizeof(code)); 2944eb492e01SAnderson Briglia 2945b28b4943SJohan Hedberg smp = chan->data; 2946b28b4943SJohan Hedberg 2947b28b4943SJohan Hedberg if (code > SMP_CMD_MAX) 2948b28b4943SJohan Hedberg goto drop; 2949b28b4943SJohan Hedberg 295024bd0bd9SJohan Hedberg if (smp && !test_and_clear_bit(code, &smp->allow_cmd)) 2951b28b4943SJohan Hedberg goto drop; 2952b28b4943SJohan Hedberg 2953b28b4943SJohan Hedberg /* If we don't have a context the only allowed commands are 2954b28b4943SJohan Hedberg * pairing request and security request. 29558cf9fa12SJohan Hedberg */ 2956b28b4943SJohan Hedberg if (!smp && code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ) 2957b28b4943SJohan Hedberg goto drop; 29588cf9fa12SJohan Hedberg 2959eb492e01SAnderson Briglia switch (code) { 2960eb492e01SAnderson Briglia case SMP_CMD_PAIRING_REQ: 2961da85e5e5SVinicius Costa Gomes reason = smp_cmd_pairing_req(conn, skb); 2962eb492e01SAnderson Briglia break; 2963eb492e01SAnderson Briglia 2964eb492e01SAnderson Briglia case SMP_CMD_PAIRING_FAIL: 296584794e11SJohan Hedberg smp_failure(conn, 0); 2966da85e5e5SVinicius Costa Gomes err = -EPERM; 2967eb492e01SAnderson Briglia break; 2968eb492e01SAnderson Briglia 2969eb492e01SAnderson Briglia case SMP_CMD_PAIRING_RSP: 2970da85e5e5SVinicius Costa Gomes reason = smp_cmd_pairing_rsp(conn, skb); 297188ba43b6SAnderson Briglia break; 297288ba43b6SAnderson Briglia 297388ba43b6SAnderson Briglia case SMP_CMD_SECURITY_REQ: 2974da85e5e5SVinicius Costa Gomes reason = smp_cmd_security_req(conn, skb); 297588ba43b6SAnderson Briglia break; 297688ba43b6SAnderson Briglia 2977eb492e01SAnderson Briglia case SMP_CMD_PAIRING_CONFIRM: 2978da85e5e5SVinicius Costa Gomes reason = smp_cmd_pairing_confirm(conn, skb); 297988ba43b6SAnderson Briglia break; 298088ba43b6SAnderson Briglia 2981eb492e01SAnderson Briglia case SMP_CMD_PAIRING_RANDOM: 2982da85e5e5SVinicius Costa Gomes reason = smp_cmd_pairing_random(conn, skb); 298388ba43b6SAnderson Briglia break; 298488ba43b6SAnderson Briglia 2985eb492e01SAnderson Briglia case SMP_CMD_ENCRYPT_INFO: 29867034b911SVinicius Costa Gomes reason = smp_cmd_encrypt_info(conn, skb); 29877034b911SVinicius Costa Gomes break; 29887034b911SVinicius Costa Gomes 2989eb492e01SAnderson Briglia case SMP_CMD_MASTER_IDENT: 29907034b911SVinicius Costa Gomes reason = smp_cmd_master_ident(conn, skb); 29917034b911SVinicius Costa Gomes break; 29927034b911SVinicius Costa Gomes 2993eb492e01SAnderson Briglia case SMP_CMD_IDENT_INFO: 2994fd349c02SJohan Hedberg reason = smp_cmd_ident_info(conn, skb); 2995fd349c02SJohan Hedberg break; 2996fd349c02SJohan Hedberg 2997eb492e01SAnderson Briglia case SMP_CMD_IDENT_ADDR_INFO: 2998fd349c02SJohan Hedberg reason = smp_cmd_ident_addr_info(conn, skb); 2999fd349c02SJohan Hedberg break; 3000fd349c02SJohan Hedberg 3001eb492e01SAnderson Briglia case SMP_CMD_SIGN_INFO: 30027ee4ea36SMarcel Holtmann reason = smp_cmd_sign_info(conn, skb); 30037034b911SVinicius Costa Gomes break; 30047034b911SVinicius Costa Gomes 3005d8f8edbeSJohan Hedberg case SMP_CMD_PUBLIC_KEY: 3006d8f8edbeSJohan Hedberg reason = smp_cmd_public_key(conn, skb); 3007d8f8edbeSJohan Hedberg break; 3008d8f8edbeSJohan Hedberg 30096433a9a2SJohan Hedberg case SMP_CMD_DHKEY_CHECK: 30106433a9a2SJohan Hedberg reason = smp_cmd_dhkey_check(conn, skb); 30116433a9a2SJohan Hedberg break; 30126433a9a2SJohan Hedberg 30131408bb6eSJohan Hedberg case SMP_CMD_KEYPRESS_NOTIFY: 30141408bb6eSJohan Hedberg reason = smp_cmd_keypress_notify(conn, skb); 30151408bb6eSJohan Hedberg break; 30161408bb6eSJohan Hedberg 3017eb492e01SAnderson Briglia default: 3018eb492e01SAnderson Briglia BT_DBG("Unknown command code 0x%2.2x", code); 3019eb492e01SAnderson Briglia reason = SMP_CMD_NOTSUPP; 30203a0259bbSVinicius Costa Gomes goto done; 30213a0259bbSVinicius Costa Gomes } 30223a0259bbSVinicius Costa Gomes 30233a0259bbSVinicius Costa Gomes done: 30249b7b18efSJohan Hedberg if (!err) { 30253a0259bbSVinicius Costa Gomes if (reason) 302684794e11SJohan Hedberg smp_failure(conn, reason); 3027eb492e01SAnderson Briglia kfree_skb(skb); 30289b7b18efSJohan Hedberg } 30299b7b18efSJohan Hedberg 3030eb492e01SAnderson Briglia return err; 3031b28b4943SJohan Hedberg 3032b28b4943SJohan Hedberg drop: 30332064ee33SMarcel Holtmann bt_dev_err(hcon->hdev, "unexpected SMP command 0x%02x from %pMR", 3034b28b4943SJohan Hedberg code, &hcon->dst); 3035b28b4943SJohan Hedberg kfree_skb(skb); 3036b28b4943SJohan Hedberg return 0; 3037eb492e01SAnderson Briglia } 30387034b911SVinicius Costa Gomes 303970db83c4SJohan Hedberg static void smp_teardown_cb(struct l2cap_chan *chan, int err) 304070db83c4SJohan Hedberg { 304170db83c4SJohan Hedberg struct l2cap_conn *conn = chan->conn; 304270db83c4SJohan Hedberg 304370db83c4SJohan Hedberg BT_DBG("chan %p", chan); 304470db83c4SJohan Hedberg 3045fc75cc86SJohan Hedberg if (chan->data) 30465d88cc73SJohan Hedberg smp_chan_destroy(conn); 30475d88cc73SJohan Hedberg 304870db83c4SJohan Hedberg conn->smp = NULL; 304970db83c4SJohan Hedberg l2cap_chan_put(chan); 305070db83c4SJohan Hedberg } 305170db83c4SJohan Hedberg 3052b5ae344dSJohan Hedberg static void bredr_pairing(struct l2cap_chan *chan) 3053b5ae344dSJohan Hedberg { 3054b5ae344dSJohan Hedberg struct l2cap_conn *conn = chan->conn; 3055b5ae344dSJohan Hedberg struct hci_conn *hcon = conn->hcon; 3056b5ae344dSJohan Hedberg struct hci_dev *hdev = hcon->hdev; 3057b5ae344dSJohan Hedberg struct smp_cmd_pairing req; 3058b5ae344dSJohan Hedberg struct smp_chan *smp; 3059b5ae344dSJohan Hedberg 3060b5ae344dSJohan Hedberg BT_DBG("chan %p", chan); 3061b5ae344dSJohan Hedberg 3062b5ae344dSJohan Hedberg /* Only new pairings are interesting */ 3063b5ae344dSJohan Hedberg if (!test_bit(HCI_CONN_NEW_LINK_KEY, &hcon->flags)) 3064b5ae344dSJohan Hedberg return; 3065b5ae344dSJohan Hedberg 3066b5ae344dSJohan Hedberg /* Don't bother if we're not encrypted */ 3067b5ae344dSJohan Hedberg if (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags)) 3068b5ae344dSJohan Hedberg return; 3069b5ae344dSJohan Hedberg 3070b5ae344dSJohan Hedberg /* Only master may initiate SMP over BR/EDR */ 3071b5ae344dSJohan Hedberg if (hcon->role != HCI_ROLE_MASTER) 3072b5ae344dSJohan Hedberg return; 3073b5ae344dSJohan Hedberg 3074b5ae344dSJohan Hedberg /* Secure Connections support must be enabled */ 3075d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_SC_ENABLED)) 3076b5ae344dSJohan Hedberg return; 3077b5ae344dSJohan Hedberg 3078b5ae344dSJohan Hedberg /* BR/EDR must use Secure Connections for SMP */ 3079b5ae344dSJohan Hedberg if (!test_bit(HCI_CONN_AES_CCM, &hcon->flags) && 3080b7cb93e5SMarcel Holtmann !hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP)) 3081b5ae344dSJohan Hedberg return; 3082b5ae344dSJohan Hedberg 3083b5ae344dSJohan Hedberg /* If our LE support is not enabled don't do anything */ 3084d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED)) 3085b5ae344dSJohan Hedberg return; 3086b5ae344dSJohan Hedberg 3087b5ae344dSJohan Hedberg /* Don't bother if remote LE support is not enabled */ 3088b5ae344dSJohan Hedberg if (!lmp_host_le_capable(hcon)) 3089b5ae344dSJohan Hedberg return; 3090b5ae344dSJohan Hedberg 3091b5ae344dSJohan Hedberg /* Remote must support SMP fixed chan for BR/EDR */ 3092b5ae344dSJohan Hedberg if (!(conn->remote_fixed_chan & L2CAP_FC_SMP_BREDR)) 3093b5ae344dSJohan Hedberg return; 3094b5ae344dSJohan Hedberg 3095b5ae344dSJohan Hedberg /* Don't bother if SMP is already ongoing */ 3096b5ae344dSJohan Hedberg if (chan->data) 3097b5ae344dSJohan Hedberg return; 3098b5ae344dSJohan Hedberg 3099b5ae344dSJohan Hedberg smp = smp_chan_create(conn); 3100b5ae344dSJohan Hedberg if (!smp) { 31012064ee33SMarcel Holtmann bt_dev_err(hdev, "unable to create SMP context for BR/EDR"); 3102b5ae344dSJohan Hedberg return; 3103b5ae344dSJohan Hedberg } 3104b5ae344dSJohan Hedberg 3105b5ae344dSJohan Hedberg set_bit(SMP_FLAG_SC, &smp->flags); 3106b5ae344dSJohan Hedberg 3107b5ae344dSJohan Hedberg BT_DBG("%s starting SMP over BR/EDR", hdev->name); 3108b5ae344dSJohan Hedberg 3109b5ae344dSJohan Hedberg /* Prepare and send the BR/EDR SMP Pairing Request */ 3110b5ae344dSJohan Hedberg build_bredr_pairing_cmd(smp, &req, NULL); 3111b5ae344dSJohan Hedberg 3112b5ae344dSJohan Hedberg smp->preq[0] = SMP_CMD_PAIRING_REQ; 3113b5ae344dSJohan Hedberg memcpy(&smp->preq[1], &req, sizeof(req)); 3114b5ae344dSJohan Hedberg 3115b5ae344dSJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(req), &req); 3116b5ae344dSJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP); 3117b5ae344dSJohan Hedberg } 3118b5ae344dSJohan Hedberg 311944f1a7abSJohan Hedberg static void smp_resume_cb(struct l2cap_chan *chan) 312044f1a7abSJohan Hedberg { 3121b68fda68SJohan Hedberg struct smp_chan *smp = chan->data; 312244f1a7abSJohan Hedberg struct l2cap_conn *conn = chan->conn; 312344f1a7abSJohan Hedberg struct hci_conn *hcon = conn->hcon; 312444f1a7abSJohan Hedberg 312544f1a7abSJohan Hedberg BT_DBG("chan %p", chan); 312644f1a7abSJohan Hedberg 3127b5ae344dSJohan Hedberg if (hcon->type == ACL_LINK) { 3128b5ae344dSJohan Hedberg bredr_pairing(chan); 3129ef8efe4bSJohan Hedberg return; 3130b5ae344dSJohan Hedberg } 3131ef8efe4bSJohan Hedberg 313286d1407cSJohan Hedberg if (!smp) 313386d1407cSJohan Hedberg return; 3134b68fda68SJohan Hedberg 313584bc0db5SJohan Hedberg if (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags)) 313684bc0db5SJohan Hedberg return; 313784bc0db5SJohan Hedberg 3138b68fda68SJohan Hedberg cancel_delayed_work(&smp->security_timer); 313986d1407cSJohan Hedberg 3140d6268e86SJohan Hedberg smp_distribute_keys(smp); 314144f1a7abSJohan Hedberg } 314244f1a7abSJohan Hedberg 314370db83c4SJohan Hedberg static void smp_ready_cb(struct l2cap_chan *chan) 314470db83c4SJohan Hedberg { 314570db83c4SJohan Hedberg struct l2cap_conn *conn = chan->conn; 3146b5ae344dSJohan Hedberg struct hci_conn *hcon = conn->hcon; 314770db83c4SJohan Hedberg 314870db83c4SJohan Hedberg BT_DBG("chan %p", chan); 314970db83c4SJohan Hedberg 31507883746bSJohan Hedberg /* No need to call l2cap_chan_hold() here since we already own 31517883746bSJohan Hedberg * the reference taken in smp_new_conn_cb(). This is just the 31527883746bSJohan Hedberg * first time that we tie it to a specific pointer. The code in 31537883746bSJohan Hedberg * l2cap_core.c ensures that there's no risk this function wont 31547883746bSJohan Hedberg * get called if smp_new_conn_cb was previously called. 31557883746bSJohan Hedberg */ 315670db83c4SJohan Hedberg conn->smp = chan; 3157b5ae344dSJohan Hedberg 3158b5ae344dSJohan Hedberg if (hcon->type == ACL_LINK && test_bit(HCI_CONN_ENCRYPT, &hcon->flags)) 3159b5ae344dSJohan Hedberg bredr_pairing(chan); 316070db83c4SJohan Hedberg } 316170db83c4SJohan Hedberg 31624befb867SJohan Hedberg static int smp_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) 31634befb867SJohan Hedberg { 31644befb867SJohan Hedberg int err; 31654befb867SJohan Hedberg 31664befb867SJohan Hedberg BT_DBG("chan %p", chan); 31674befb867SJohan Hedberg 31684befb867SJohan Hedberg err = smp_sig_channel(chan, skb); 31694befb867SJohan Hedberg if (err) { 3170b68fda68SJohan Hedberg struct smp_chan *smp = chan->data; 31714befb867SJohan Hedberg 3172b68fda68SJohan Hedberg if (smp) 3173b68fda68SJohan Hedberg cancel_delayed_work_sync(&smp->security_timer); 31744befb867SJohan Hedberg 31751e91c29eSJohan Hedberg hci_disconnect(chan->conn->hcon, HCI_ERROR_AUTH_FAILURE); 31764befb867SJohan Hedberg } 31774befb867SJohan Hedberg 31784befb867SJohan Hedberg return err; 31794befb867SJohan Hedberg } 31804befb867SJohan Hedberg 318170db83c4SJohan Hedberg static struct sk_buff *smp_alloc_skb_cb(struct l2cap_chan *chan, 318270db83c4SJohan Hedberg unsigned long hdr_len, 318370db83c4SJohan Hedberg unsigned long len, int nb) 318470db83c4SJohan Hedberg { 318570db83c4SJohan Hedberg struct sk_buff *skb; 318670db83c4SJohan Hedberg 318770db83c4SJohan Hedberg skb = bt_skb_alloc(hdr_len + len, GFP_KERNEL); 318870db83c4SJohan Hedberg if (!skb) 318970db83c4SJohan Hedberg return ERR_PTR(-ENOMEM); 319070db83c4SJohan Hedberg 319170db83c4SJohan Hedberg skb->priority = HCI_PRIO_MAX; 3192a4368ff3SJohan Hedberg bt_cb(skb)->l2cap.chan = chan; 319370db83c4SJohan Hedberg 319470db83c4SJohan Hedberg return skb; 319570db83c4SJohan Hedberg } 319670db83c4SJohan Hedberg 319770db83c4SJohan Hedberg static const struct l2cap_ops smp_chan_ops = { 319870db83c4SJohan Hedberg .name = "Security Manager", 319970db83c4SJohan Hedberg .ready = smp_ready_cb, 32005d88cc73SJohan Hedberg .recv = smp_recv_cb, 320170db83c4SJohan Hedberg .alloc_skb = smp_alloc_skb_cb, 320270db83c4SJohan Hedberg .teardown = smp_teardown_cb, 320344f1a7abSJohan Hedberg .resume = smp_resume_cb, 320470db83c4SJohan Hedberg 320570db83c4SJohan Hedberg .new_connection = l2cap_chan_no_new_connection, 320670db83c4SJohan Hedberg .state_change = l2cap_chan_no_state_change, 320770db83c4SJohan Hedberg .close = l2cap_chan_no_close, 320870db83c4SJohan Hedberg .defer = l2cap_chan_no_defer, 320970db83c4SJohan Hedberg .suspend = l2cap_chan_no_suspend, 321070db83c4SJohan Hedberg .set_shutdown = l2cap_chan_no_set_shutdown, 321170db83c4SJohan Hedberg .get_sndtimeo = l2cap_chan_no_get_sndtimeo, 321270db83c4SJohan Hedberg }; 321370db83c4SJohan Hedberg 321470db83c4SJohan Hedberg static inline struct l2cap_chan *smp_new_conn_cb(struct l2cap_chan *pchan) 321570db83c4SJohan Hedberg { 321670db83c4SJohan Hedberg struct l2cap_chan *chan; 321770db83c4SJohan Hedberg 321870db83c4SJohan Hedberg BT_DBG("pchan %p", pchan); 321970db83c4SJohan Hedberg 322070db83c4SJohan Hedberg chan = l2cap_chan_create(); 322170db83c4SJohan Hedberg if (!chan) 322270db83c4SJohan Hedberg return NULL; 322370db83c4SJohan Hedberg 322470db83c4SJohan Hedberg chan->chan_type = pchan->chan_type; 322570db83c4SJohan Hedberg chan->ops = &smp_chan_ops; 322670db83c4SJohan Hedberg chan->scid = pchan->scid; 322770db83c4SJohan Hedberg chan->dcid = chan->scid; 322870db83c4SJohan Hedberg chan->imtu = pchan->imtu; 322970db83c4SJohan Hedberg chan->omtu = pchan->omtu; 323070db83c4SJohan Hedberg chan->mode = pchan->mode; 323170db83c4SJohan Hedberg 3232abe84903SJohan Hedberg /* Other L2CAP channels may request SMP routines in order to 3233abe84903SJohan Hedberg * change the security level. This means that the SMP channel 3234abe84903SJohan Hedberg * lock must be considered in its own category to avoid lockdep 3235abe84903SJohan Hedberg * warnings. 3236abe84903SJohan Hedberg */ 3237abe84903SJohan Hedberg atomic_set(&chan->nesting, L2CAP_NESTING_SMP); 3238abe84903SJohan Hedberg 323970db83c4SJohan Hedberg BT_DBG("created chan %p", chan); 324070db83c4SJohan Hedberg 324170db83c4SJohan Hedberg return chan; 324270db83c4SJohan Hedberg } 324370db83c4SJohan Hedberg 324470db83c4SJohan Hedberg static const struct l2cap_ops smp_root_chan_ops = { 324570db83c4SJohan Hedberg .name = "Security Manager Root", 324670db83c4SJohan Hedberg .new_connection = smp_new_conn_cb, 324770db83c4SJohan Hedberg 324870db83c4SJohan Hedberg /* None of these are implemented for the root channel */ 324970db83c4SJohan Hedberg .close = l2cap_chan_no_close, 325070db83c4SJohan Hedberg .alloc_skb = l2cap_chan_no_alloc_skb, 325170db83c4SJohan Hedberg .recv = l2cap_chan_no_recv, 325270db83c4SJohan Hedberg .state_change = l2cap_chan_no_state_change, 325370db83c4SJohan Hedberg .teardown = l2cap_chan_no_teardown, 325470db83c4SJohan Hedberg .ready = l2cap_chan_no_ready, 325570db83c4SJohan Hedberg .defer = l2cap_chan_no_defer, 325670db83c4SJohan Hedberg .suspend = l2cap_chan_no_suspend, 325770db83c4SJohan Hedberg .resume = l2cap_chan_no_resume, 325870db83c4SJohan Hedberg .set_shutdown = l2cap_chan_no_set_shutdown, 325970db83c4SJohan Hedberg .get_sndtimeo = l2cap_chan_no_get_sndtimeo, 326070db83c4SJohan Hedberg }; 326170db83c4SJohan Hedberg 3262ef8efe4bSJohan Hedberg static struct l2cap_chan *smp_add_cid(struct hci_dev *hdev, u16 cid) 3263711eafe3SJohan Hedberg { 326470db83c4SJohan Hedberg struct l2cap_chan *chan; 326588a479d9SMarcel Holtmann struct smp_dev *smp; 326671af2f6bSHerbert Xu struct crypto_shash *tfm_cmac; 326747eb2ac8STudor Ambarus struct crypto_kpp *tfm_ecdh; 326870db83c4SJohan Hedberg 3269ef8efe4bSJohan Hedberg if (cid == L2CAP_CID_SMP_BREDR) { 327088a479d9SMarcel Holtmann smp = NULL; 3271ef8efe4bSJohan Hedberg goto create_chan; 3272ef8efe4bSJohan Hedberg } 3273711eafe3SJohan Hedberg 327488a479d9SMarcel Holtmann smp = kzalloc(sizeof(*smp), GFP_KERNEL); 327588a479d9SMarcel Holtmann if (!smp) 327688a479d9SMarcel Holtmann return ERR_PTR(-ENOMEM); 327788a479d9SMarcel Holtmann 327871af2f6bSHerbert Xu tfm_cmac = crypto_alloc_shash("cmac(aes)", 0, 0); 32796e2dc6d1SMarcel Holtmann if (IS_ERR(tfm_cmac)) { 32806e2dc6d1SMarcel Holtmann BT_ERR("Unable to create CMAC crypto context"); 3281453431a5SWaiman Long kfree_sensitive(smp); 32826e2dc6d1SMarcel Holtmann return ERR_CAST(tfm_cmac); 32836e2dc6d1SMarcel Holtmann } 32846e2dc6d1SMarcel Holtmann 3285075f7732SHerbert Xu tfm_ecdh = crypto_alloc_kpp("ecdh", 0, 0); 328647eb2ac8STudor Ambarus if (IS_ERR(tfm_ecdh)) { 328747eb2ac8STudor Ambarus BT_ERR("Unable to create ECDH crypto context"); 328847eb2ac8STudor Ambarus crypto_free_shash(tfm_cmac); 3289453431a5SWaiman Long kfree_sensitive(smp); 329047eb2ac8STudor Ambarus return ERR_CAST(tfm_ecdh); 329147eb2ac8STudor Ambarus } 329247eb2ac8STudor Ambarus 329394f14e47SJohan Hedberg smp->local_oob = false; 32946e2dc6d1SMarcel Holtmann smp->tfm_cmac = tfm_cmac; 329547eb2ac8STudor Ambarus smp->tfm_ecdh = tfm_ecdh; 329688a479d9SMarcel Holtmann 3297ef8efe4bSJohan Hedberg create_chan: 329870db83c4SJohan Hedberg chan = l2cap_chan_create(); 329970db83c4SJohan Hedberg if (!chan) { 330063511f6dSMarcel Holtmann if (smp) { 330171af2f6bSHerbert Xu crypto_free_shash(smp->tfm_cmac); 330247eb2ac8STudor Ambarus crypto_free_kpp(smp->tfm_ecdh); 3303453431a5SWaiman Long kfree_sensitive(smp); 330463511f6dSMarcel Holtmann } 3305ef8efe4bSJohan Hedberg return ERR_PTR(-ENOMEM); 330670db83c4SJohan Hedberg } 330770db83c4SJohan Hedberg 330888a479d9SMarcel Holtmann chan->data = smp; 3309defce9e8SJohan Hedberg 3310ef8efe4bSJohan Hedberg l2cap_add_scid(chan, cid); 331170db83c4SJohan Hedberg 331270db83c4SJohan Hedberg l2cap_chan_set_defaults(chan); 331370db83c4SJohan Hedberg 3314157029baSMarcel Holtmann if (cid == L2CAP_CID_SMP) { 331539e3e744SJohan Hedberg u8 bdaddr_type; 331639e3e744SJohan Hedberg 331739e3e744SJohan Hedberg hci_copy_identity_address(hdev, &chan->src, &bdaddr_type); 331839e3e744SJohan Hedberg 331939e3e744SJohan Hedberg if (bdaddr_type == ADDR_LE_DEV_PUBLIC) 332070db83c4SJohan Hedberg chan->src_type = BDADDR_LE_PUBLIC; 332139e3e744SJohan Hedberg else 332239e3e744SJohan Hedberg chan->src_type = BDADDR_LE_RANDOM; 3323157029baSMarcel Holtmann } else { 3324157029baSMarcel Holtmann bacpy(&chan->src, &hdev->bdaddr); 3325ef8efe4bSJohan Hedberg chan->src_type = BDADDR_BREDR; 3326157029baSMarcel Holtmann } 3327157029baSMarcel Holtmann 332870db83c4SJohan Hedberg chan->state = BT_LISTEN; 332970db83c4SJohan Hedberg chan->mode = L2CAP_MODE_BASIC; 333070db83c4SJohan Hedberg chan->imtu = L2CAP_DEFAULT_MTU; 333170db83c4SJohan Hedberg chan->ops = &smp_root_chan_ops; 333270db83c4SJohan Hedberg 3333abe84903SJohan Hedberg /* Set correct nesting level for a parent/listening channel */ 3334abe84903SJohan Hedberg atomic_set(&chan->nesting, L2CAP_NESTING_PARENT); 3335abe84903SJohan Hedberg 3336ef8efe4bSJohan Hedberg return chan; 3337711eafe3SJohan Hedberg } 3338711eafe3SJohan Hedberg 3339ef8efe4bSJohan Hedberg static void smp_del_chan(struct l2cap_chan *chan) 3340711eafe3SJohan Hedberg { 334188a479d9SMarcel Holtmann struct smp_dev *smp; 334270db83c4SJohan Hedberg 3343ef8efe4bSJohan Hedberg BT_DBG("chan %p", chan); 3344711eafe3SJohan Hedberg 334588a479d9SMarcel Holtmann smp = chan->data; 334688a479d9SMarcel Holtmann if (smp) { 3347defce9e8SJohan Hedberg chan->data = NULL; 334871af2f6bSHerbert Xu crypto_free_shash(smp->tfm_cmac); 334947eb2ac8STudor Ambarus crypto_free_kpp(smp->tfm_ecdh); 3350453431a5SWaiman Long kfree_sensitive(smp); 3351711eafe3SJohan Hedberg } 335270db83c4SJohan Hedberg 335370db83c4SJohan Hedberg l2cap_chan_put(chan); 3354711eafe3SJohan Hedberg } 3355ef8efe4bSJohan Hedberg 3356*82493316SClaire Chang int smp_force_bredr(struct hci_dev *hdev, bool enable) 3357300acfdeSMarcel Holtmann { 3358b7cb93e5SMarcel Holtmann if (enable == hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP)) 3359300acfdeSMarcel Holtmann return -EALREADY; 3360300acfdeSMarcel Holtmann 3361300acfdeSMarcel Holtmann if (enable) { 3362300acfdeSMarcel Holtmann struct l2cap_chan *chan; 3363300acfdeSMarcel Holtmann 3364300acfdeSMarcel Holtmann chan = smp_add_cid(hdev, L2CAP_CID_SMP_BREDR); 3365300acfdeSMarcel Holtmann if (IS_ERR(chan)) 3366300acfdeSMarcel Holtmann return PTR_ERR(chan); 3367300acfdeSMarcel Holtmann 3368300acfdeSMarcel Holtmann hdev->smp_bredr_data = chan; 3369300acfdeSMarcel Holtmann } else { 3370300acfdeSMarcel Holtmann struct l2cap_chan *chan; 3371300acfdeSMarcel Holtmann 3372300acfdeSMarcel Holtmann chan = hdev->smp_bredr_data; 3373300acfdeSMarcel Holtmann hdev->smp_bredr_data = NULL; 3374300acfdeSMarcel Holtmann smp_del_chan(chan); 3375300acfdeSMarcel Holtmann } 3376300acfdeSMarcel Holtmann 3377b7cb93e5SMarcel Holtmann hci_dev_change_flag(hdev, HCI_FORCE_BREDR_SMP); 3378300acfdeSMarcel Holtmann 3379*82493316SClaire Chang return 0; 3380300acfdeSMarcel Holtmann } 3381300acfdeSMarcel Holtmann 3382ef8efe4bSJohan Hedberg int smp_register(struct hci_dev *hdev) 3383ef8efe4bSJohan Hedberg { 3384ef8efe4bSJohan Hedberg struct l2cap_chan *chan; 3385ef8efe4bSJohan Hedberg 3386ef8efe4bSJohan Hedberg BT_DBG("%s", hdev->name); 3387ef8efe4bSJohan Hedberg 33887e7ec445SMarcel Holtmann /* If the controller does not support Low Energy operation, then 33897e7ec445SMarcel Holtmann * there is also no need to register any SMP channel. 33907e7ec445SMarcel Holtmann */ 33917e7ec445SMarcel Holtmann if (!lmp_le_capable(hdev)) 33927e7ec445SMarcel Holtmann return 0; 33937e7ec445SMarcel Holtmann 33942b8df323SMarcel Holtmann if (WARN_ON(hdev->smp_data)) { 33952b8df323SMarcel Holtmann chan = hdev->smp_data; 33962b8df323SMarcel Holtmann hdev->smp_data = NULL; 33972b8df323SMarcel Holtmann smp_del_chan(chan); 33982b8df323SMarcel Holtmann } 33992b8df323SMarcel Holtmann 3400ef8efe4bSJohan Hedberg chan = smp_add_cid(hdev, L2CAP_CID_SMP); 3401ef8efe4bSJohan Hedberg if (IS_ERR(chan)) 3402ef8efe4bSJohan Hedberg return PTR_ERR(chan); 3403ef8efe4bSJohan Hedberg 3404ef8efe4bSJohan Hedberg hdev->smp_data = chan; 3405ef8efe4bSJohan Hedberg 3406300acfdeSMarcel Holtmann if (!lmp_sc_capable(hdev)) { 340783ebb9ecSSzymon Janc /* Flag can be already set here (due to power toggle) */ 340883ebb9ecSSzymon Janc if (!hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP)) 3409ef8efe4bSJohan Hedberg return 0; 3410300acfdeSMarcel Holtmann } 3411ef8efe4bSJohan Hedberg 34122b8df323SMarcel Holtmann if (WARN_ON(hdev->smp_bredr_data)) { 34132b8df323SMarcel Holtmann chan = hdev->smp_bredr_data; 34142b8df323SMarcel Holtmann hdev->smp_bredr_data = NULL; 34152b8df323SMarcel Holtmann smp_del_chan(chan); 34162b8df323SMarcel Holtmann } 34172b8df323SMarcel Holtmann 3418ef8efe4bSJohan Hedberg chan = smp_add_cid(hdev, L2CAP_CID_SMP_BREDR); 3419ef8efe4bSJohan Hedberg if (IS_ERR(chan)) { 3420ef8efe4bSJohan Hedberg int err = PTR_ERR(chan); 3421ef8efe4bSJohan Hedberg chan = hdev->smp_data; 3422ef8efe4bSJohan Hedberg hdev->smp_data = NULL; 3423ef8efe4bSJohan Hedberg smp_del_chan(chan); 3424ef8efe4bSJohan Hedberg return err; 3425ef8efe4bSJohan Hedberg } 3426ef8efe4bSJohan Hedberg 3427ef8efe4bSJohan Hedberg hdev->smp_bredr_data = chan; 3428ef8efe4bSJohan Hedberg 3429ef8efe4bSJohan Hedberg return 0; 3430ef8efe4bSJohan Hedberg } 3431ef8efe4bSJohan Hedberg 3432ef8efe4bSJohan Hedberg void smp_unregister(struct hci_dev *hdev) 3433ef8efe4bSJohan Hedberg { 3434ef8efe4bSJohan Hedberg struct l2cap_chan *chan; 3435ef8efe4bSJohan Hedberg 3436ef8efe4bSJohan Hedberg if (hdev->smp_bredr_data) { 3437ef8efe4bSJohan Hedberg chan = hdev->smp_bredr_data; 3438ef8efe4bSJohan Hedberg hdev->smp_bredr_data = NULL; 3439ef8efe4bSJohan Hedberg smp_del_chan(chan); 3440ef8efe4bSJohan Hedberg } 3441ef8efe4bSJohan Hedberg 3442ef8efe4bSJohan Hedberg if (hdev->smp_data) { 3443ef8efe4bSJohan Hedberg chan = hdev->smp_data; 3444ef8efe4bSJohan Hedberg hdev->smp_data = NULL; 3445ef8efe4bSJohan Hedberg smp_del_chan(chan); 3446ef8efe4bSJohan Hedberg } 3447ef8efe4bSJohan Hedberg } 34480a2b0f04SJohan Hedberg 34490a2b0f04SJohan Hedberg #if IS_ENABLED(CONFIG_BT_SELFTEST_SMP) 34500a2b0f04SJohan Hedberg 345147eb2ac8STudor Ambarus static int __init test_debug_key(struct crypto_kpp *tfm_ecdh) 345271653eb6SMarcel Holtmann { 3453c0153b0bSTudor Ambarus u8 pk[64]; 3454a2976416STudor Ambarus int err; 345571653eb6SMarcel Holtmann 3456c0153b0bSTudor Ambarus err = set_ecdh_privkey(tfm_ecdh, debug_sk); 3457a2976416STudor Ambarus if (err) 3458a2976416STudor Ambarus return err; 345971653eb6SMarcel Holtmann 3460c0153b0bSTudor Ambarus err = generate_ecdh_public_key(tfm_ecdh, pk); 3461c0153b0bSTudor Ambarus if (err) 3462c0153b0bSTudor Ambarus return err; 346371653eb6SMarcel Holtmann 3464329d8230SJason A. Donenfeld if (crypto_memneq(pk, debug_pk, 64)) 346571653eb6SMarcel Holtmann return -EINVAL; 346671653eb6SMarcel Holtmann 346771653eb6SMarcel Holtmann return 0; 346871653eb6SMarcel Holtmann } 346971653eb6SMarcel Holtmann 347028a220aaSArd Biesheuvel static int __init test_ah(void) 3471cfc4198eSJohan Hedberg { 3472cfc4198eSJohan Hedberg const u8 irk[16] = { 3473cfc4198eSJohan Hedberg 0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34, 3474cfc4198eSJohan Hedberg 0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec }; 3475cfc4198eSJohan Hedberg const u8 r[3] = { 0x94, 0x81, 0x70 }; 3476cfc4198eSJohan Hedberg const u8 exp[3] = { 0xaa, 0xfb, 0x0d }; 3477cfc4198eSJohan Hedberg u8 res[3]; 3478cfc4198eSJohan Hedberg int err; 3479cfc4198eSJohan Hedberg 348028a220aaSArd Biesheuvel err = smp_ah(irk, r, res); 3481cfc4198eSJohan Hedberg if (err) 3482cfc4198eSJohan Hedberg return err; 3483cfc4198eSJohan Hedberg 3484329d8230SJason A. Donenfeld if (crypto_memneq(res, exp, 3)) 3485cfc4198eSJohan Hedberg return -EINVAL; 3486cfc4198eSJohan Hedberg 3487cfc4198eSJohan Hedberg return 0; 3488cfc4198eSJohan Hedberg } 3489cfc4198eSJohan Hedberg 349028a220aaSArd Biesheuvel static int __init test_c1(void) 3491cfc4198eSJohan Hedberg { 3492cfc4198eSJohan Hedberg const u8 k[16] = { 3493cfc4198eSJohan Hedberg 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3494cfc4198eSJohan Hedberg 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 3495cfc4198eSJohan Hedberg const u8 r[16] = { 3496cfc4198eSJohan Hedberg 0xe0, 0x2e, 0x70, 0xc6, 0x4e, 0x27, 0x88, 0x63, 3497cfc4198eSJohan Hedberg 0x0e, 0x6f, 0xad, 0x56, 0x21, 0xd5, 0x83, 0x57 }; 3498cfc4198eSJohan Hedberg const u8 preq[7] = { 0x01, 0x01, 0x00, 0x00, 0x10, 0x07, 0x07 }; 3499cfc4198eSJohan Hedberg const u8 pres[7] = { 0x02, 0x03, 0x00, 0x00, 0x08, 0x00, 0x05 }; 3500cfc4198eSJohan Hedberg const u8 _iat = 0x01; 3501cfc4198eSJohan Hedberg const u8 _rat = 0x00; 3502cfc4198eSJohan Hedberg const bdaddr_t ra = { { 0xb6, 0xb5, 0xb4, 0xb3, 0xb2, 0xb1 } }; 3503cfc4198eSJohan Hedberg const bdaddr_t ia = { { 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1 } }; 3504cfc4198eSJohan Hedberg const u8 exp[16] = { 3505cfc4198eSJohan Hedberg 0x86, 0x3b, 0xf1, 0xbe, 0xc5, 0x4d, 0xa7, 0xd2, 3506cfc4198eSJohan Hedberg 0xea, 0x88, 0x89, 0x87, 0xef, 0x3f, 0x1e, 0x1e }; 3507cfc4198eSJohan Hedberg u8 res[16]; 3508cfc4198eSJohan Hedberg int err; 3509cfc4198eSJohan Hedberg 351028a220aaSArd Biesheuvel err = smp_c1(k, r, preq, pres, _iat, &ia, _rat, &ra, res); 3511cfc4198eSJohan Hedberg if (err) 3512cfc4198eSJohan Hedberg return err; 3513cfc4198eSJohan Hedberg 3514329d8230SJason A. Donenfeld if (crypto_memneq(res, exp, 16)) 3515cfc4198eSJohan Hedberg return -EINVAL; 3516cfc4198eSJohan Hedberg 3517cfc4198eSJohan Hedberg return 0; 3518cfc4198eSJohan Hedberg } 3519cfc4198eSJohan Hedberg 352028a220aaSArd Biesheuvel static int __init test_s1(void) 3521cfc4198eSJohan Hedberg { 3522cfc4198eSJohan Hedberg const u8 k[16] = { 3523cfc4198eSJohan Hedberg 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3524cfc4198eSJohan Hedberg 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 3525cfc4198eSJohan Hedberg const u8 r1[16] = { 3526cfc4198eSJohan Hedberg 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 }; 3527cfc4198eSJohan Hedberg const u8 r2[16] = { 3528cfc4198eSJohan Hedberg 0x00, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99 }; 3529cfc4198eSJohan Hedberg const u8 exp[16] = { 3530cfc4198eSJohan Hedberg 0x62, 0xa0, 0x6d, 0x79, 0xae, 0x16, 0x42, 0x5b, 3531cfc4198eSJohan Hedberg 0x9b, 0xf4, 0xb0, 0xe8, 0xf0, 0xe1, 0x1f, 0x9a }; 3532cfc4198eSJohan Hedberg u8 res[16]; 3533cfc4198eSJohan Hedberg int err; 3534cfc4198eSJohan Hedberg 353528a220aaSArd Biesheuvel err = smp_s1(k, r1, r2, res); 3536cfc4198eSJohan Hedberg if (err) 3537cfc4198eSJohan Hedberg return err; 3538cfc4198eSJohan Hedberg 3539329d8230SJason A. Donenfeld if (crypto_memneq(res, exp, 16)) 3540cfc4198eSJohan Hedberg return -EINVAL; 3541cfc4198eSJohan Hedberg 3542cfc4198eSJohan Hedberg return 0; 3543cfc4198eSJohan Hedberg } 3544cfc4198eSJohan Hedberg 354571af2f6bSHerbert Xu static int __init test_f4(struct crypto_shash *tfm_cmac) 3546fb2969a3SJohan Hedberg { 3547fb2969a3SJohan Hedberg const u8 u[32] = { 3548fb2969a3SJohan Hedberg 0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc, 3549fb2969a3SJohan Hedberg 0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef, 3550fb2969a3SJohan Hedberg 0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e, 3551fb2969a3SJohan Hedberg 0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20 }; 3552fb2969a3SJohan Hedberg const u8 v[32] = { 3553fb2969a3SJohan Hedberg 0xfd, 0xc5, 0x7f, 0xf4, 0x49, 0xdd, 0x4f, 0x6b, 3554fb2969a3SJohan Hedberg 0xfb, 0x7c, 0x9d, 0xf1, 0xc2, 0x9a, 0xcb, 0x59, 3555fb2969a3SJohan Hedberg 0x2a, 0xe7, 0xd4, 0xee, 0xfb, 0xfc, 0x0a, 0x90, 3556fb2969a3SJohan Hedberg 0x9a, 0xbb, 0xf6, 0x32, 0x3d, 0x8b, 0x18, 0x55 }; 3557fb2969a3SJohan Hedberg const u8 x[16] = { 3558fb2969a3SJohan Hedberg 0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff, 3559fb2969a3SJohan Hedberg 0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 }; 3560fb2969a3SJohan Hedberg const u8 z = 0x00; 3561fb2969a3SJohan Hedberg const u8 exp[16] = { 3562fb2969a3SJohan Hedberg 0x2d, 0x87, 0x74, 0xa9, 0xbe, 0xa1, 0xed, 0xf1, 3563fb2969a3SJohan Hedberg 0x1c, 0xbd, 0xa9, 0x07, 0xf1, 0x16, 0xc9, 0xf2 }; 3564fb2969a3SJohan Hedberg u8 res[16]; 3565fb2969a3SJohan Hedberg int err; 3566fb2969a3SJohan Hedberg 3567fb2969a3SJohan Hedberg err = smp_f4(tfm_cmac, u, v, x, z, res); 3568fb2969a3SJohan Hedberg if (err) 3569fb2969a3SJohan Hedberg return err; 3570fb2969a3SJohan Hedberg 3571329d8230SJason A. Donenfeld if (crypto_memneq(res, exp, 16)) 3572fb2969a3SJohan Hedberg return -EINVAL; 3573fb2969a3SJohan Hedberg 3574fb2969a3SJohan Hedberg return 0; 3575fb2969a3SJohan Hedberg } 3576fb2969a3SJohan Hedberg 357771af2f6bSHerbert Xu static int __init test_f5(struct crypto_shash *tfm_cmac) 3578fb2969a3SJohan Hedberg { 3579fb2969a3SJohan Hedberg const u8 w[32] = { 3580fb2969a3SJohan Hedberg 0x98, 0xa6, 0xbf, 0x73, 0xf3, 0x34, 0x8d, 0x86, 3581fb2969a3SJohan Hedberg 0xf1, 0x66, 0xf8, 0xb4, 0x13, 0x6b, 0x79, 0x99, 3582fb2969a3SJohan Hedberg 0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34, 3583fb2969a3SJohan Hedberg 0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec }; 3584fb2969a3SJohan Hedberg const u8 n1[16] = { 3585fb2969a3SJohan Hedberg 0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff, 3586fb2969a3SJohan Hedberg 0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 }; 3587fb2969a3SJohan Hedberg const u8 n2[16] = { 3588fb2969a3SJohan Hedberg 0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21, 3589fb2969a3SJohan Hedberg 0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6 }; 3590fb2969a3SJohan Hedberg const u8 a1[7] = { 0xce, 0xbf, 0x37, 0x37, 0x12, 0x56, 0x00 }; 3591fb2969a3SJohan Hedberg const u8 a2[7] = { 0xc1, 0xcf, 0x2d, 0x70, 0x13, 0xa7, 0x00 }; 3592fb2969a3SJohan Hedberg const u8 exp_ltk[16] = { 3593fb2969a3SJohan Hedberg 0x38, 0x0a, 0x75, 0x94, 0xb5, 0x22, 0x05, 0x98, 3594fb2969a3SJohan Hedberg 0x23, 0xcd, 0xd7, 0x69, 0x11, 0x79, 0x86, 0x69 }; 3595fb2969a3SJohan Hedberg const u8 exp_mackey[16] = { 3596fb2969a3SJohan Hedberg 0x20, 0x6e, 0x63, 0xce, 0x20, 0x6a, 0x3f, 0xfd, 3597fb2969a3SJohan Hedberg 0x02, 0x4a, 0x08, 0xa1, 0x76, 0xf1, 0x65, 0x29 }; 3598fb2969a3SJohan Hedberg u8 mackey[16], ltk[16]; 3599fb2969a3SJohan Hedberg int err; 3600fb2969a3SJohan Hedberg 3601fb2969a3SJohan Hedberg err = smp_f5(tfm_cmac, w, n1, n2, a1, a2, mackey, ltk); 3602fb2969a3SJohan Hedberg if (err) 3603fb2969a3SJohan Hedberg return err; 3604fb2969a3SJohan Hedberg 3605329d8230SJason A. Donenfeld if (crypto_memneq(mackey, exp_mackey, 16)) 3606fb2969a3SJohan Hedberg return -EINVAL; 3607fb2969a3SJohan Hedberg 3608329d8230SJason A. Donenfeld if (crypto_memneq(ltk, exp_ltk, 16)) 3609fb2969a3SJohan Hedberg return -EINVAL; 3610fb2969a3SJohan Hedberg 3611fb2969a3SJohan Hedberg return 0; 3612fb2969a3SJohan Hedberg } 3613fb2969a3SJohan Hedberg 361471af2f6bSHerbert Xu static int __init test_f6(struct crypto_shash *tfm_cmac) 3615fb2969a3SJohan Hedberg { 3616fb2969a3SJohan Hedberg const u8 w[16] = { 3617fb2969a3SJohan Hedberg 0x20, 0x6e, 0x63, 0xce, 0x20, 0x6a, 0x3f, 0xfd, 3618fb2969a3SJohan Hedberg 0x02, 0x4a, 0x08, 0xa1, 0x76, 0xf1, 0x65, 0x29 }; 3619fb2969a3SJohan Hedberg const u8 n1[16] = { 3620fb2969a3SJohan Hedberg 0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff, 3621fb2969a3SJohan Hedberg 0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 }; 3622fb2969a3SJohan Hedberg const u8 n2[16] = { 3623fb2969a3SJohan Hedberg 0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21, 3624fb2969a3SJohan Hedberg 0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6 }; 3625fb2969a3SJohan Hedberg const u8 r[16] = { 3626fb2969a3SJohan Hedberg 0xc8, 0x0f, 0x2d, 0x0c, 0xd2, 0x42, 0xda, 0x08, 3627fb2969a3SJohan Hedberg 0x54, 0xbb, 0x53, 0xb4, 0x3b, 0x34, 0xa3, 0x12 }; 3628fb2969a3SJohan Hedberg const u8 io_cap[3] = { 0x02, 0x01, 0x01 }; 3629fb2969a3SJohan Hedberg const u8 a1[7] = { 0xce, 0xbf, 0x37, 0x37, 0x12, 0x56, 0x00 }; 3630fb2969a3SJohan Hedberg const u8 a2[7] = { 0xc1, 0xcf, 0x2d, 0x70, 0x13, 0xa7, 0x00 }; 3631fb2969a3SJohan Hedberg const u8 exp[16] = { 3632fb2969a3SJohan Hedberg 0x61, 0x8f, 0x95, 0xda, 0x09, 0x0b, 0x6c, 0xd2, 3633fb2969a3SJohan Hedberg 0xc5, 0xe8, 0xd0, 0x9c, 0x98, 0x73, 0xc4, 0xe3 }; 3634fb2969a3SJohan Hedberg u8 res[16]; 3635fb2969a3SJohan Hedberg int err; 3636fb2969a3SJohan Hedberg 3637fb2969a3SJohan Hedberg err = smp_f6(tfm_cmac, w, n1, n2, r, io_cap, a1, a2, res); 3638fb2969a3SJohan Hedberg if (err) 3639fb2969a3SJohan Hedberg return err; 3640fb2969a3SJohan Hedberg 3641329d8230SJason A. Donenfeld if (crypto_memneq(res, exp, 16)) 3642fb2969a3SJohan Hedberg return -EINVAL; 3643fb2969a3SJohan Hedberg 3644fb2969a3SJohan Hedberg return 0; 3645fb2969a3SJohan Hedberg } 3646fb2969a3SJohan Hedberg 364771af2f6bSHerbert Xu static int __init test_g2(struct crypto_shash *tfm_cmac) 3648fb2969a3SJohan Hedberg { 3649fb2969a3SJohan Hedberg const u8 u[32] = { 3650fb2969a3SJohan Hedberg 0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc, 3651fb2969a3SJohan Hedberg 0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef, 3652fb2969a3SJohan Hedberg 0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e, 3653fb2969a3SJohan Hedberg 0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20 }; 3654fb2969a3SJohan Hedberg const u8 v[32] = { 3655fb2969a3SJohan Hedberg 0xfd, 0xc5, 0x7f, 0xf4, 0x49, 0xdd, 0x4f, 0x6b, 3656fb2969a3SJohan Hedberg 0xfb, 0x7c, 0x9d, 0xf1, 0xc2, 0x9a, 0xcb, 0x59, 3657fb2969a3SJohan Hedberg 0x2a, 0xe7, 0xd4, 0xee, 0xfb, 0xfc, 0x0a, 0x90, 3658fb2969a3SJohan Hedberg 0x9a, 0xbb, 0xf6, 0x32, 0x3d, 0x8b, 0x18, 0x55 }; 3659fb2969a3SJohan Hedberg const u8 x[16] = { 3660fb2969a3SJohan Hedberg 0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff, 3661fb2969a3SJohan Hedberg 0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 }; 3662fb2969a3SJohan Hedberg const u8 y[16] = { 3663fb2969a3SJohan Hedberg 0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21, 3664fb2969a3SJohan Hedberg 0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6 }; 3665fb2969a3SJohan Hedberg const u32 exp_val = 0x2f9ed5ba % 1000000; 3666fb2969a3SJohan Hedberg u32 val; 3667fb2969a3SJohan Hedberg int err; 3668fb2969a3SJohan Hedberg 3669fb2969a3SJohan Hedberg err = smp_g2(tfm_cmac, u, v, x, y, &val); 3670fb2969a3SJohan Hedberg if (err) 3671fb2969a3SJohan Hedberg return err; 3672fb2969a3SJohan Hedberg 3673fb2969a3SJohan Hedberg if (val != exp_val) 3674fb2969a3SJohan Hedberg return -EINVAL; 3675fb2969a3SJohan Hedberg 3676fb2969a3SJohan Hedberg return 0; 3677fb2969a3SJohan Hedberg } 3678fb2969a3SJohan Hedberg 367971af2f6bSHerbert Xu static int __init test_h6(struct crypto_shash *tfm_cmac) 3680fb2969a3SJohan Hedberg { 3681fb2969a3SJohan Hedberg const u8 w[16] = { 3682fb2969a3SJohan Hedberg 0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34, 3683fb2969a3SJohan Hedberg 0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec }; 3684fb2969a3SJohan Hedberg const u8 key_id[4] = { 0x72, 0x62, 0x65, 0x6c }; 3685fb2969a3SJohan Hedberg const u8 exp[16] = { 3686fb2969a3SJohan Hedberg 0x99, 0x63, 0xb1, 0x80, 0xe2, 0xa9, 0xd3, 0xe8, 3687fb2969a3SJohan Hedberg 0x1c, 0xc9, 0x6d, 0xe7, 0x02, 0xe1, 0x9a, 0x2d }; 3688fb2969a3SJohan Hedberg u8 res[16]; 3689fb2969a3SJohan Hedberg int err; 3690fb2969a3SJohan Hedberg 3691fb2969a3SJohan Hedberg err = smp_h6(tfm_cmac, w, key_id, res); 3692fb2969a3SJohan Hedberg if (err) 3693fb2969a3SJohan Hedberg return err; 3694fb2969a3SJohan Hedberg 3695329d8230SJason A. Donenfeld if (crypto_memneq(res, exp, 16)) 3696fb2969a3SJohan Hedberg return -EINVAL; 3697fb2969a3SJohan Hedberg 3698fb2969a3SJohan Hedberg return 0; 3699fb2969a3SJohan Hedberg } 3700fb2969a3SJohan Hedberg 370164dd374eSMarcel Holtmann static char test_smp_buffer[32]; 370264dd374eSMarcel Holtmann 370364dd374eSMarcel Holtmann static ssize_t test_smp_read(struct file *file, char __user *user_buf, 370464dd374eSMarcel Holtmann size_t count, loff_t *ppos) 370564dd374eSMarcel Holtmann { 370664dd374eSMarcel Holtmann return simple_read_from_buffer(user_buf, count, ppos, test_smp_buffer, 370764dd374eSMarcel Holtmann strlen(test_smp_buffer)); 370864dd374eSMarcel Holtmann } 370964dd374eSMarcel Holtmann 371064dd374eSMarcel Holtmann static const struct file_operations test_smp_fops = { 371164dd374eSMarcel Holtmann .open = simple_open, 371264dd374eSMarcel Holtmann .read = test_smp_read, 371364dd374eSMarcel Holtmann .llseek = default_llseek, 371464dd374eSMarcel Holtmann }; 371564dd374eSMarcel Holtmann 371628a220aaSArd Biesheuvel static int __init run_selftests(struct crypto_shash *tfm_cmac, 371747eb2ac8STudor Ambarus struct crypto_kpp *tfm_ecdh) 37180a2b0f04SJohan Hedberg { 3719255047b0SMarcel Holtmann ktime_t calltime, delta, rettime; 3720255047b0SMarcel Holtmann unsigned long long duration; 3721cfc4198eSJohan Hedberg int err; 3722cfc4198eSJohan Hedberg 3723255047b0SMarcel Holtmann calltime = ktime_get(); 3724255047b0SMarcel Holtmann 372547eb2ac8STudor Ambarus err = test_debug_key(tfm_ecdh); 372671653eb6SMarcel Holtmann if (err) { 372771653eb6SMarcel Holtmann BT_ERR("debug_key test failed"); 372871653eb6SMarcel Holtmann goto done; 372971653eb6SMarcel Holtmann } 373071653eb6SMarcel Holtmann 373128a220aaSArd Biesheuvel err = test_ah(); 3732cfc4198eSJohan Hedberg if (err) { 3733cfc4198eSJohan Hedberg BT_ERR("smp_ah test failed"); 373464dd374eSMarcel Holtmann goto done; 3735cfc4198eSJohan Hedberg } 3736cfc4198eSJohan Hedberg 373728a220aaSArd Biesheuvel err = test_c1(); 3738cfc4198eSJohan Hedberg if (err) { 3739cfc4198eSJohan Hedberg BT_ERR("smp_c1 test failed"); 374064dd374eSMarcel Holtmann goto done; 3741cfc4198eSJohan Hedberg } 3742cfc4198eSJohan Hedberg 374328a220aaSArd Biesheuvel err = test_s1(); 3744cfc4198eSJohan Hedberg if (err) { 3745cfc4198eSJohan Hedberg BT_ERR("smp_s1 test failed"); 374664dd374eSMarcel Holtmann goto done; 3747cfc4198eSJohan Hedberg } 3748cfc4198eSJohan Hedberg 3749fb2969a3SJohan Hedberg err = test_f4(tfm_cmac); 3750fb2969a3SJohan Hedberg if (err) { 3751fb2969a3SJohan Hedberg BT_ERR("smp_f4 test failed"); 375264dd374eSMarcel Holtmann goto done; 3753fb2969a3SJohan Hedberg } 3754fb2969a3SJohan Hedberg 3755fb2969a3SJohan Hedberg err = test_f5(tfm_cmac); 3756fb2969a3SJohan Hedberg if (err) { 3757fb2969a3SJohan Hedberg BT_ERR("smp_f5 test failed"); 375864dd374eSMarcel Holtmann goto done; 3759fb2969a3SJohan Hedberg } 3760fb2969a3SJohan Hedberg 3761fb2969a3SJohan Hedberg err = test_f6(tfm_cmac); 3762fb2969a3SJohan Hedberg if (err) { 3763fb2969a3SJohan Hedberg BT_ERR("smp_f6 test failed"); 376464dd374eSMarcel Holtmann goto done; 3765fb2969a3SJohan Hedberg } 3766fb2969a3SJohan Hedberg 3767fb2969a3SJohan Hedberg err = test_g2(tfm_cmac); 3768fb2969a3SJohan Hedberg if (err) { 3769fb2969a3SJohan Hedberg BT_ERR("smp_g2 test failed"); 377064dd374eSMarcel Holtmann goto done; 3771fb2969a3SJohan Hedberg } 3772fb2969a3SJohan Hedberg 3773fb2969a3SJohan Hedberg err = test_h6(tfm_cmac); 3774fb2969a3SJohan Hedberg if (err) { 3775fb2969a3SJohan Hedberg BT_ERR("smp_h6 test failed"); 377664dd374eSMarcel Holtmann goto done; 3777fb2969a3SJohan Hedberg } 3778fb2969a3SJohan Hedberg 3779255047b0SMarcel Holtmann rettime = ktime_get(); 3780255047b0SMarcel Holtmann delta = ktime_sub(rettime, calltime); 3781255047b0SMarcel Holtmann duration = (unsigned long long) ktime_to_ns(delta) >> 10; 3782255047b0SMarcel Holtmann 37835ced2464SMarcel Holtmann BT_INFO("SMP test passed in %llu usecs", duration); 37840a2b0f04SJohan Hedberg 378564dd374eSMarcel Holtmann done: 378664dd374eSMarcel Holtmann if (!err) 378764dd374eSMarcel Holtmann snprintf(test_smp_buffer, sizeof(test_smp_buffer), 378864dd374eSMarcel Holtmann "PASS (%llu usecs)\n", duration); 378964dd374eSMarcel Holtmann else 379064dd374eSMarcel Holtmann snprintf(test_smp_buffer, sizeof(test_smp_buffer), "FAIL\n"); 379164dd374eSMarcel Holtmann 379264dd374eSMarcel Holtmann debugfs_create_file("selftest_smp", 0444, bt_debugfs, NULL, 379364dd374eSMarcel Holtmann &test_smp_fops); 379464dd374eSMarcel Holtmann 379564dd374eSMarcel Holtmann return err; 37960a2b0f04SJohan Hedberg } 37970a2b0f04SJohan Hedberg 37980a2b0f04SJohan Hedberg int __init bt_selftest_smp(void) 37990a2b0f04SJohan Hedberg { 380071af2f6bSHerbert Xu struct crypto_shash *tfm_cmac; 380147eb2ac8STudor Ambarus struct crypto_kpp *tfm_ecdh; 38020a2b0f04SJohan Hedberg int err; 38030a2b0f04SJohan Hedberg 38043d234b33SEric Biggers tfm_cmac = crypto_alloc_shash("cmac(aes)", 0, 0); 38050a2b0f04SJohan Hedberg if (IS_ERR(tfm_cmac)) { 38060a2b0f04SJohan Hedberg BT_ERR("Unable to create CMAC crypto context"); 38070a2b0f04SJohan Hedberg return PTR_ERR(tfm_cmac); 38080a2b0f04SJohan Hedberg } 38090a2b0f04SJohan Hedberg 3810075f7732SHerbert Xu tfm_ecdh = crypto_alloc_kpp("ecdh", 0, 0); 381147eb2ac8STudor Ambarus if (IS_ERR(tfm_ecdh)) { 381247eb2ac8STudor Ambarus BT_ERR("Unable to create ECDH crypto context"); 381347eb2ac8STudor Ambarus crypto_free_shash(tfm_cmac); 381447eb2ac8STudor Ambarus return PTR_ERR(tfm_ecdh); 381547eb2ac8STudor Ambarus } 381647eb2ac8STudor Ambarus 381728a220aaSArd Biesheuvel err = run_selftests(tfm_cmac, tfm_ecdh); 38180a2b0f04SJohan Hedberg 381971af2f6bSHerbert Xu crypto_free_shash(tfm_cmac); 382047eb2ac8STudor Ambarus crypto_free_kpp(tfm_ecdh); 38210a2b0f04SJohan Hedberg 38220a2b0f04SJohan Hedberg return err; 38230a2b0f04SJohan Hedberg } 38240a2b0f04SJohan Hedberg 38250a2b0f04SJohan Hedberg #endif 3826