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> 2871af2f6bSHerbert Xu #include <crypto/hash.h> 2947eb2ac8STudor Ambarus #include <crypto/kpp.h> 308c520a59SGustavo Padovan 31eb492e01SAnderson Briglia #include <net/bluetooth/bluetooth.h> 32eb492e01SAnderson Briglia #include <net/bluetooth/hci_core.h> 33eb492e01SAnderson Briglia #include <net/bluetooth/l2cap.h> 342b64d153SBrian Gix #include <net/bluetooth/mgmt.h> 35ac4b7236SMarcel Holtmann 3658771c1cSSalvatore Benedetto #include "ecdh_helper.h" 37ac4b7236SMarcel Holtmann #include "smp.h" 38d22ef0bcSAnderson Briglia 392fd36558SJohan Hedberg #define SMP_DEV(hdev) \ 402fd36558SJohan Hedberg ((struct smp_dev *)((struct l2cap_chan *)((hdev)->smp_data))->data) 412fd36558SJohan Hedberg 42c7a3d57dSJohan Hedberg /* Low-level debug macros to be used for stuff that we don't want 4391641b79SZheng Yongjun * accidentally in dmesg, i.e. the values of the various crypto keys 44c7a3d57dSJohan Hedberg * and the inputs & outputs of crypto functions. 45c7a3d57dSJohan Hedberg */ 46c7a3d57dSJohan Hedberg #ifdef DEBUG 47c7a3d57dSJohan Hedberg #define SMP_DBG(fmt, ...) printk(KERN_DEBUG "%s: " fmt, __func__, \ 48c7a3d57dSJohan Hedberg ##__VA_ARGS__) 49c7a3d57dSJohan Hedberg #else 50c7a3d57dSJohan Hedberg #define SMP_DBG(fmt, ...) no_printk(KERN_DEBUG "%s: " fmt, __func__, \ 51c7a3d57dSJohan Hedberg ##__VA_ARGS__) 52c7a3d57dSJohan Hedberg #endif 53c7a3d57dSJohan Hedberg 54b28b4943SJohan Hedberg #define SMP_ALLOW_CMD(smp, code) set_bit(code, &smp->allow_cmd) 55b28b4943SJohan Hedberg 563b19146dSJohan Hedberg /* Keys which are not distributed with Secure Connections */ 57c29fb5f6SMeng Yu #define SMP_SC_NO_DIST (SMP_DIST_ENC_KEY | SMP_DIST_LINK_KEY) 583b19146dSJohan Hedberg 5917b02e62SMarcel Holtmann #define SMP_TIMEOUT msecs_to_jiffies(30000) 605d3de7dfSVinicius Costa Gomes 61*b8b23001SLuiz Augusto von Dentz #define ID_ADDR_TIMEOUT msecs_to_jiffies(200) 62*b8b23001SLuiz Augusto von Dentz 63d7a5a11dSMarcel Holtmann #define AUTH_REQ_MASK(dev) (hci_dev_test_flag(dev, HCI_SC_ENABLED) ? \ 64a62da6f1SJohan Hedberg 0x3f : 0x07) 6588d3a8acSJohan Hedberg #define KEY_DIST_MASK 0x07 66065a13e2SJohan Hedberg 67cbbbe3e2SJohan Hedberg /* Maximum message length that can be passed to aes_cmac */ 68cbbbe3e2SJohan Hedberg #define CMAC_MSG_MAX 80 69cbbbe3e2SJohan Hedberg 70533e35d4SJohan Hedberg enum { 71533e35d4SJohan Hedberg SMP_FLAG_TK_VALID, 72533e35d4SJohan Hedberg SMP_FLAG_CFM_PENDING, 73533e35d4SJohan Hedberg SMP_FLAG_MITM_AUTH, 74533e35d4SJohan Hedberg SMP_FLAG_COMPLETE, 75533e35d4SJohan Hedberg SMP_FLAG_INITIATOR, 7665668776SJohan Hedberg SMP_FLAG_SC, 77d8f8edbeSJohan Hedberg SMP_FLAG_REMOTE_PK, 78aeb7d461SJohan Hedberg SMP_FLAG_DEBUG_KEY, 7938606f14SJohan Hedberg SMP_FLAG_WAIT_USER, 80d3e54a87SJohan Hedberg SMP_FLAG_DHKEY_PENDING, 811a8bab4fSJohan Hedberg SMP_FLAG_REMOTE_OOB, 821a8bab4fSJohan Hedberg SMP_FLAG_LOCAL_OOB, 83a62da6f1SJohan Hedberg SMP_FLAG_CT2, 84533e35d4SJohan Hedberg }; 854bc58f51SJohan Hedberg 8688a479d9SMarcel Holtmann struct smp_dev { 8760a27d65SMarcel Holtmann /* Secure Connections OOB data */ 8894f14e47SJohan Hedberg bool local_oob; 8960a27d65SMarcel Holtmann u8 local_pk[64]; 90fb334feeSMarcel Holtmann u8 local_rand[16]; 9160a27d65SMarcel Holtmann bool debug_key; 9260a27d65SMarcel Holtmann 9371af2f6bSHerbert Xu struct crypto_shash *tfm_cmac; 9447eb2ac8STudor Ambarus struct crypto_kpp *tfm_ecdh; 9588a479d9SMarcel Holtmann }; 9688a479d9SMarcel Holtmann 974bc58f51SJohan Hedberg struct smp_chan { 984bc58f51SJohan Hedberg struct l2cap_conn *conn; 99b68fda68SJohan Hedberg struct delayed_work security_timer; 100b28b4943SJohan Hedberg unsigned long allow_cmd; /* Bitmask of allowed commands */ 101b68fda68SJohan Hedberg 1024bc58f51SJohan Hedberg u8 preq[7]; /* SMP Pairing Request */ 1034bc58f51SJohan Hedberg u8 prsp[7]; /* SMP Pairing Response */ 1044bc58f51SJohan Hedberg u8 prnd[16]; /* SMP Pairing Random (local) */ 1054bc58f51SJohan Hedberg u8 rrnd[16]; /* SMP Pairing Random (remote) */ 1064bc58f51SJohan Hedberg u8 pcnf[16]; /* SMP Pairing Confirm */ 1074bc58f51SJohan Hedberg u8 tk[16]; /* SMP Temporary Key */ 108882fafadSJohan Hedberg u8 rr[16]; /* Remote OOB ra/rb value */ 109882fafadSJohan Hedberg u8 lr[16]; /* Local OOB ra/rb value */ 1104bc58f51SJohan Hedberg u8 enc_key_size; 1114bc58f51SJohan Hedberg u8 remote_key_dist; 1124bc58f51SJohan Hedberg bdaddr_t id_addr; 1134bc58f51SJohan Hedberg u8 id_addr_type; 1144bc58f51SJohan Hedberg u8 irk[16]; 1154bc58f51SJohan Hedberg struct smp_csrk *csrk; 116fad646e1SArchie Pusaka struct smp_csrk *responder_csrk; 1174bc58f51SJohan Hedberg struct smp_ltk *ltk; 118fad646e1SArchie Pusaka struct smp_ltk *responder_ltk; 1194bc58f51SJohan Hedberg struct smp_irk *remote_irk; 1206a77083aSJohan Hedberg u8 *link_key; 1214a74d658SJohan Hedberg unsigned long flags; 122783e0574SJohan Hedberg u8 method; 12338606f14SJohan Hedberg u8 passkey_round; 1246a7bd103SJohan Hedberg 1253b19146dSJohan Hedberg /* Secure Connections variables */ 1263b19146dSJohan Hedberg u8 local_pk[64]; 127d8f8edbeSJohan Hedberg u8 remote_pk[64]; 128d8f8edbeSJohan Hedberg u8 dhkey[32]; 129760b018bSJohan Hedberg u8 mackey[16]; 1303b19146dSJohan Hedberg 13171af2f6bSHerbert Xu struct crypto_shash *tfm_cmac; 13247eb2ac8STudor Ambarus struct crypto_kpp *tfm_ecdh; 1334bc58f51SJohan Hedberg }; 1344bc58f51SJohan Hedberg 135aeb7d461SJohan Hedberg /* These debug key values are defined in the SMP section of the core 136aeb7d461SJohan Hedberg * specification. debug_pk is the public debug key and debug_sk the 137aeb7d461SJohan Hedberg * private debug key. 138aeb7d461SJohan Hedberg */ 139aeb7d461SJohan Hedberg static const u8 debug_pk[64] = { 140aeb7d461SJohan Hedberg 0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc, 141aeb7d461SJohan Hedberg 0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef, 142aeb7d461SJohan Hedberg 0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e, 143aeb7d461SJohan Hedberg 0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20, 144aeb7d461SJohan Hedberg 145aeb7d461SJohan Hedberg 0x8b, 0xd2, 0x89, 0x15, 0xd0, 0x8e, 0x1c, 0x74, 146aeb7d461SJohan Hedberg 0x24, 0x30, 0xed, 0x8f, 0xc2, 0x45, 0x63, 0x76, 147aeb7d461SJohan Hedberg 0x5c, 0x15, 0x52, 0x5a, 0xbf, 0x9a, 0x32, 0x63, 148aeb7d461SJohan Hedberg 0x6d, 0xeb, 0x2a, 0x65, 0x49, 0x9c, 0x80, 0xdc, 149aeb7d461SJohan Hedberg }; 150aeb7d461SJohan Hedberg 151aeb7d461SJohan Hedberg static const u8 debug_sk[32] = { 152aeb7d461SJohan Hedberg 0xbd, 0x1a, 0x3c, 0xcd, 0xa6, 0xb8, 0x99, 0x58, 153aeb7d461SJohan Hedberg 0x99, 0xb7, 0x40, 0xeb, 0x7b, 0x60, 0xff, 0x4a, 154aeb7d461SJohan Hedberg 0x50, 0x3f, 0x10, 0xd2, 0xe3, 0xb3, 0xc9, 0x74, 155aeb7d461SJohan Hedberg 0x38, 0x5f, 0xc5, 0xa3, 0xd4, 0xf6, 0x49, 0x3f, 156aeb7d461SJohan Hedberg }; 157aeb7d461SJohan Hedberg 1588a2936f4SJohan Hedberg static inline void swap_buf(const u8 *src, u8 *dst, size_t len) 159d22ef0bcSAnderson Briglia { 1608a2936f4SJohan Hedberg size_t i; 161d22ef0bcSAnderson Briglia 1628a2936f4SJohan Hedberg for (i = 0; i < len; i++) 1638a2936f4SJohan Hedberg dst[len - 1 - i] = src[i]; 164d22ef0bcSAnderson Briglia } 165d22ef0bcSAnderson Briglia 16606edf8deSJohan Hedberg /* The following functions map to the LE SC SMP crypto functions 16706edf8deSJohan Hedberg * AES-CMAC, f4, f5, f6, g2 and h6. 16806edf8deSJohan Hedberg */ 16906edf8deSJohan Hedberg 17071af2f6bSHerbert Xu static int aes_cmac(struct crypto_shash *tfm, const u8 k[16], const u8 *m, 171cbbbe3e2SJohan Hedberg size_t len, u8 mac[16]) 172cbbbe3e2SJohan Hedberg { 173cbbbe3e2SJohan Hedberg uint8_t tmp[16], mac_msb[16], msg_msb[CMAC_MSG_MAX]; 174cbbbe3e2SJohan Hedberg int err; 175cbbbe3e2SJohan Hedberg 176cbbbe3e2SJohan Hedberg if (len > CMAC_MSG_MAX) 177cbbbe3e2SJohan Hedberg return -EFBIG; 178cbbbe3e2SJohan Hedberg 179cbbbe3e2SJohan Hedberg if (!tfm) { 180cbbbe3e2SJohan Hedberg BT_ERR("tfm %p", tfm); 181cbbbe3e2SJohan Hedberg return -EINVAL; 182cbbbe3e2SJohan Hedberg } 183cbbbe3e2SJohan Hedberg 184cbbbe3e2SJohan Hedberg /* Swap key and message from LSB to MSB */ 185cbbbe3e2SJohan Hedberg swap_buf(k, tmp, 16); 186cbbbe3e2SJohan Hedberg swap_buf(m, msg_msb, len); 187cbbbe3e2SJohan Hedberg 188c7a3d57dSJohan Hedberg SMP_DBG("msg (len %zu) %*phN", len, (int) len, m); 189c7a3d57dSJohan Hedberg SMP_DBG("key %16phN", k); 190cbbbe3e2SJohan Hedberg 19171af2f6bSHerbert Xu err = crypto_shash_setkey(tfm, tmp, 16); 192cbbbe3e2SJohan Hedberg if (err) { 193cbbbe3e2SJohan Hedberg BT_ERR("cipher setkey failed: %d", err); 194cbbbe3e2SJohan Hedberg return err; 195cbbbe3e2SJohan Hedberg } 196cbbbe3e2SJohan Hedberg 197ec0bf6edSEric Biggers err = crypto_shash_tfm_digest(tfm, msg_msb, len, mac_msb); 198cbbbe3e2SJohan Hedberg if (err) { 19971af2f6bSHerbert Xu BT_ERR("Hash computation error %d", err); 200cbbbe3e2SJohan Hedberg return err; 201cbbbe3e2SJohan Hedberg } 202cbbbe3e2SJohan Hedberg 203cbbbe3e2SJohan Hedberg swap_buf(mac_msb, mac, 16); 204cbbbe3e2SJohan Hedberg 205c7a3d57dSJohan Hedberg SMP_DBG("mac %16phN", mac); 206cbbbe3e2SJohan Hedberg 207cbbbe3e2SJohan Hedberg return 0; 208cbbbe3e2SJohan Hedberg } 209cbbbe3e2SJohan Hedberg 21071af2f6bSHerbert Xu static int smp_f4(struct crypto_shash *tfm_cmac, const u8 u[32], 21171af2f6bSHerbert Xu const u8 v[32], const u8 x[16], u8 z, u8 res[16]) 212cbbbe3e2SJohan Hedberg { 213cbbbe3e2SJohan Hedberg u8 m[65]; 214cbbbe3e2SJohan Hedberg int err; 215cbbbe3e2SJohan Hedberg 216c7a3d57dSJohan Hedberg SMP_DBG("u %32phN", u); 217c7a3d57dSJohan Hedberg SMP_DBG("v %32phN", v); 218c7a3d57dSJohan Hedberg SMP_DBG("x %16phN z %02x", x, z); 219cbbbe3e2SJohan Hedberg 220cbbbe3e2SJohan Hedberg m[0] = z; 221cbbbe3e2SJohan Hedberg memcpy(m + 1, v, 32); 222cbbbe3e2SJohan Hedberg memcpy(m + 33, u, 32); 223cbbbe3e2SJohan Hedberg 224cbbbe3e2SJohan Hedberg err = aes_cmac(tfm_cmac, x, m, sizeof(m), res); 225cbbbe3e2SJohan Hedberg if (err) 226cbbbe3e2SJohan Hedberg return err; 227cbbbe3e2SJohan Hedberg 228c7a3d57dSJohan Hedberg SMP_DBG("res %16phN", res); 229cbbbe3e2SJohan Hedberg 230cbbbe3e2SJohan Hedberg return err; 231cbbbe3e2SJohan Hedberg } 232cbbbe3e2SJohan Hedberg 23371af2f6bSHerbert Xu static int smp_f5(struct crypto_shash *tfm_cmac, const u8 w[32], 2344da50de8SJohan Hedberg const u8 n1[16], const u8 n2[16], const u8 a1[7], 2354da50de8SJohan Hedberg const u8 a2[7], u8 mackey[16], u8 ltk[16]) 236760b018bSJohan Hedberg { 237760b018bSJohan Hedberg /* The btle, salt and length "magic" values are as defined in 238760b018bSJohan Hedberg * the SMP section of the Bluetooth core specification. In ASCII 239760b018bSJohan Hedberg * the btle value ends up being 'btle'. The salt is just a 240760b018bSJohan Hedberg * random number whereas length is the value 256 in little 241760b018bSJohan Hedberg * endian format. 242760b018bSJohan Hedberg */ 243760b018bSJohan Hedberg const u8 btle[4] = { 0x65, 0x6c, 0x74, 0x62 }; 244760b018bSJohan Hedberg const u8 salt[16] = { 0xbe, 0x83, 0x60, 0x5a, 0xdb, 0x0b, 0x37, 0x60, 245760b018bSJohan Hedberg 0x38, 0xa5, 0xf5, 0xaa, 0x91, 0x83, 0x88, 0x6c }; 246760b018bSJohan Hedberg const u8 length[2] = { 0x00, 0x01 }; 247760b018bSJohan Hedberg u8 m[53], t[16]; 248760b018bSJohan Hedberg int err; 249760b018bSJohan Hedberg 250c7a3d57dSJohan Hedberg SMP_DBG("w %32phN", w); 251c7a3d57dSJohan Hedberg SMP_DBG("n1 %16phN n2 %16phN", n1, n2); 252c7a3d57dSJohan Hedberg SMP_DBG("a1 %7phN a2 %7phN", a1, a2); 253760b018bSJohan Hedberg 254760b018bSJohan Hedberg err = aes_cmac(tfm_cmac, salt, w, 32, t); 255760b018bSJohan Hedberg if (err) 256760b018bSJohan Hedberg return err; 257760b018bSJohan Hedberg 258c7a3d57dSJohan Hedberg SMP_DBG("t %16phN", t); 259760b018bSJohan Hedberg 260760b018bSJohan Hedberg memcpy(m, length, 2); 261760b018bSJohan Hedberg memcpy(m + 2, a2, 7); 262760b018bSJohan Hedberg memcpy(m + 9, a1, 7); 263760b018bSJohan Hedberg memcpy(m + 16, n2, 16); 264760b018bSJohan Hedberg memcpy(m + 32, n1, 16); 265760b018bSJohan Hedberg memcpy(m + 48, btle, 4); 266760b018bSJohan Hedberg 267760b018bSJohan Hedberg m[52] = 0; /* Counter */ 268760b018bSJohan Hedberg 269760b018bSJohan Hedberg err = aes_cmac(tfm_cmac, t, m, sizeof(m), mackey); 270760b018bSJohan Hedberg if (err) 271760b018bSJohan Hedberg return err; 272760b018bSJohan Hedberg 273c7a3d57dSJohan Hedberg SMP_DBG("mackey %16phN", mackey); 274760b018bSJohan Hedberg 275760b018bSJohan Hedberg m[52] = 1; /* Counter */ 276760b018bSJohan Hedberg 277760b018bSJohan Hedberg err = aes_cmac(tfm_cmac, t, m, sizeof(m), ltk); 278760b018bSJohan Hedberg if (err) 279760b018bSJohan Hedberg return err; 280760b018bSJohan Hedberg 281c7a3d57dSJohan Hedberg SMP_DBG("ltk %16phN", ltk); 282760b018bSJohan Hedberg 283760b018bSJohan Hedberg return 0; 284760b018bSJohan Hedberg } 285760b018bSJohan Hedberg 28671af2f6bSHerbert Xu static int smp_f6(struct crypto_shash *tfm_cmac, const u8 w[16], 2874da50de8SJohan Hedberg const u8 n1[16], const u8 n2[16], const u8 r[16], 288760b018bSJohan Hedberg const u8 io_cap[3], const u8 a1[7], const u8 a2[7], 289760b018bSJohan Hedberg u8 res[16]) 290760b018bSJohan Hedberg { 291760b018bSJohan Hedberg u8 m[65]; 292760b018bSJohan Hedberg int err; 293760b018bSJohan Hedberg 294c7a3d57dSJohan Hedberg SMP_DBG("w %16phN", w); 295c7a3d57dSJohan Hedberg SMP_DBG("n1 %16phN n2 %16phN", n1, n2); 296c7a3d57dSJohan Hedberg SMP_DBG("r %16phN io_cap %3phN a1 %7phN a2 %7phN", r, io_cap, a1, a2); 297760b018bSJohan Hedberg 298760b018bSJohan Hedberg memcpy(m, a2, 7); 299760b018bSJohan Hedberg memcpy(m + 7, a1, 7); 300760b018bSJohan Hedberg memcpy(m + 14, io_cap, 3); 301760b018bSJohan Hedberg memcpy(m + 17, r, 16); 302760b018bSJohan Hedberg memcpy(m + 33, n2, 16); 303760b018bSJohan Hedberg memcpy(m + 49, n1, 16); 304760b018bSJohan Hedberg 305760b018bSJohan Hedberg err = aes_cmac(tfm_cmac, w, m, sizeof(m), res); 306760b018bSJohan Hedberg if (err) 307760b018bSJohan Hedberg return err; 308760b018bSJohan Hedberg 309203de21bSMarcel Holtmann SMP_DBG("res %16phN", res); 310760b018bSJohan Hedberg 311760b018bSJohan Hedberg return err; 312760b018bSJohan Hedberg } 313760b018bSJohan Hedberg 31471af2f6bSHerbert Xu static int smp_g2(struct crypto_shash *tfm_cmac, const u8 u[32], const u8 v[32], 315191dc7feSJohan Hedberg const u8 x[16], const u8 y[16], u32 *val) 316191dc7feSJohan Hedberg { 317191dc7feSJohan Hedberg u8 m[80], tmp[16]; 318191dc7feSJohan Hedberg int err; 319191dc7feSJohan Hedberg 320c7a3d57dSJohan Hedberg SMP_DBG("u %32phN", u); 321c7a3d57dSJohan Hedberg SMP_DBG("v %32phN", v); 322c7a3d57dSJohan Hedberg SMP_DBG("x %16phN y %16phN", x, y); 323191dc7feSJohan Hedberg 324191dc7feSJohan Hedberg memcpy(m, y, 16); 325191dc7feSJohan Hedberg memcpy(m + 16, v, 32); 326191dc7feSJohan Hedberg memcpy(m + 48, u, 32); 327191dc7feSJohan Hedberg 328191dc7feSJohan Hedberg err = aes_cmac(tfm_cmac, x, m, sizeof(m), tmp); 329191dc7feSJohan Hedberg if (err) 330191dc7feSJohan Hedberg return err; 331191dc7feSJohan Hedberg 332191dc7feSJohan Hedberg *val = get_unaligned_le32(tmp); 333191dc7feSJohan Hedberg *val %= 1000000; 334191dc7feSJohan Hedberg 335c7a3d57dSJohan Hedberg SMP_DBG("val %06u", *val); 336191dc7feSJohan Hedberg 337191dc7feSJohan Hedberg return 0; 338191dc7feSJohan Hedberg } 339191dc7feSJohan Hedberg 34071af2f6bSHerbert Xu static int smp_h6(struct crypto_shash *tfm_cmac, const u8 w[16], 34106edf8deSJohan Hedberg const u8 key_id[4], u8 res[16]) 34206edf8deSJohan Hedberg { 34306edf8deSJohan Hedberg int err; 34406edf8deSJohan Hedberg 34506edf8deSJohan Hedberg SMP_DBG("w %16phN key_id %4phN", w, key_id); 34606edf8deSJohan Hedberg 34706edf8deSJohan Hedberg err = aes_cmac(tfm_cmac, w, key_id, 4, res); 34806edf8deSJohan Hedberg if (err) 34906edf8deSJohan Hedberg return err; 35006edf8deSJohan Hedberg 35106edf8deSJohan Hedberg SMP_DBG("res %16phN", res); 35206edf8deSJohan Hedberg 35306edf8deSJohan Hedberg return err; 35406edf8deSJohan Hedberg } 35506edf8deSJohan Hedberg 356a62da6f1SJohan Hedberg static int smp_h7(struct crypto_shash *tfm_cmac, const u8 w[16], 357a62da6f1SJohan Hedberg const u8 salt[16], u8 res[16]) 358a62da6f1SJohan Hedberg { 359a62da6f1SJohan Hedberg int err; 360a62da6f1SJohan Hedberg 361a62da6f1SJohan Hedberg SMP_DBG("w %16phN salt %16phN", w, salt); 362a62da6f1SJohan Hedberg 363a62da6f1SJohan Hedberg err = aes_cmac(tfm_cmac, salt, w, 16, res); 364a62da6f1SJohan Hedberg if (err) 365a62da6f1SJohan Hedberg return err; 366a62da6f1SJohan Hedberg 367a62da6f1SJohan Hedberg SMP_DBG("res %16phN", res); 368a62da6f1SJohan Hedberg 369a62da6f1SJohan Hedberg return err; 370a62da6f1SJohan Hedberg } 371a62da6f1SJohan Hedberg 37206edf8deSJohan Hedberg /* The following functions map to the legacy SMP crypto functions e, c1, 37306edf8deSJohan Hedberg * s1 and ah. 37406edf8deSJohan Hedberg */ 37506edf8deSJohan Hedberg 37628a220aaSArd Biesheuvel static int smp_e(const u8 *k, u8 *r) 377d22ef0bcSAnderson Briglia { 37828a220aaSArd Biesheuvel struct crypto_aes_ctx ctx; 379943a732aSJohan Hedberg uint8_t tmp[16], data[16]; 380201a5929SJohan Hedberg int err; 381d22ef0bcSAnderson Briglia 382011c391aSJohan Hedberg SMP_DBG("k %16phN r %16phN", k, r); 383011c391aSJohan Hedberg 384943a732aSJohan Hedberg /* The most significant octet of key corresponds to k[0] */ 3858a2936f4SJohan Hedberg swap_buf(k, tmp, 16); 386943a732aSJohan Hedberg 38728a220aaSArd Biesheuvel err = aes_expandkey(&ctx, tmp, 16); 388d22ef0bcSAnderson Briglia if (err) { 389d22ef0bcSAnderson Briglia BT_ERR("cipher setkey failed: %d", err); 390d22ef0bcSAnderson Briglia return err; 391d22ef0bcSAnderson Briglia } 392d22ef0bcSAnderson Briglia 393943a732aSJohan Hedberg /* Most significant octet of plaintextData corresponds to data[0] */ 3948a2936f4SJohan Hedberg swap_buf(r, data, 16); 395943a732aSJohan Hedberg 39628a220aaSArd Biesheuvel aes_encrypt(&ctx, data, data); 397d22ef0bcSAnderson Briglia 398943a732aSJohan Hedberg /* Most significant octet of encryptedData corresponds to data[0] */ 3998a2936f4SJohan Hedberg swap_buf(data, r, 16); 400943a732aSJohan Hedberg 401011c391aSJohan Hedberg SMP_DBG("r %16phN", r); 402011c391aSJohan Hedberg 40328a220aaSArd Biesheuvel memzero_explicit(&ctx, sizeof(ctx)); 404d22ef0bcSAnderson Briglia return err; 405d22ef0bcSAnderson Briglia } 406d22ef0bcSAnderson Briglia 40728a220aaSArd Biesheuvel static int smp_c1(const u8 k[16], 40806edf8deSJohan Hedberg const u8 r[16], const u8 preq[7], const u8 pres[7], u8 _iat, 40906edf8deSJohan Hedberg const bdaddr_t *ia, u8 _rat, const bdaddr_t *ra, u8 res[16]) 41006edf8deSJohan Hedberg { 41106edf8deSJohan Hedberg u8 p1[16], p2[16]; 41206edf8deSJohan Hedberg int err; 41306edf8deSJohan Hedberg 414011c391aSJohan Hedberg SMP_DBG("k %16phN r %16phN", k, r); 415011c391aSJohan Hedberg SMP_DBG("iat %u ia %6phN rat %u ra %6phN", _iat, ia, _rat, ra); 416011c391aSJohan Hedberg SMP_DBG("preq %7phN pres %7phN", preq, pres); 417011c391aSJohan Hedberg 41806edf8deSJohan Hedberg memset(p1, 0, 16); 41906edf8deSJohan Hedberg 42006edf8deSJohan Hedberg /* p1 = pres || preq || _rat || _iat */ 42106edf8deSJohan Hedberg p1[0] = _iat; 42206edf8deSJohan Hedberg p1[1] = _rat; 42306edf8deSJohan Hedberg memcpy(p1 + 2, preq, 7); 42406edf8deSJohan Hedberg memcpy(p1 + 9, pres, 7); 42506edf8deSJohan Hedberg 426011c391aSJohan Hedberg SMP_DBG("p1 %16phN", p1); 42706edf8deSJohan Hedberg 42806edf8deSJohan Hedberg /* res = r XOR p1 */ 429ef0bb5adSArd Biesheuvel crypto_xor_cpy(res, r, p1, sizeof(p1)); 43006edf8deSJohan Hedberg 43106edf8deSJohan Hedberg /* res = e(k, res) */ 43228a220aaSArd Biesheuvel err = smp_e(k, res); 43306edf8deSJohan Hedberg if (err) { 43406edf8deSJohan Hedberg BT_ERR("Encrypt data error"); 43506edf8deSJohan Hedberg return err; 43606edf8deSJohan Hedberg } 43706edf8deSJohan Hedberg 438011c391aSJohan Hedberg /* p2 = padding || ia || ra */ 439011c391aSJohan Hedberg memcpy(p2, ra, 6); 440011c391aSJohan Hedberg memcpy(p2 + 6, ia, 6); 441011c391aSJohan Hedberg memset(p2 + 12, 0, 4); 442011c391aSJohan Hedberg 443011c391aSJohan Hedberg SMP_DBG("p2 %16phN", p2); 444011c391aSJohan Hedberg 44506edf8deSJohan Hedberg /* res = res XOR p2 */ 446ef0bb5adSArd Biesheuvel crypto_xor(res, p2, sizeof(p2)); 44706edf8deSJohan Hedberg 44806edf8deSJohan Hedberg /* res = e(k, res) */ 44928a220aaSArd Biesheuvel err = smp_e(k, res); 45006edf8deSJohan Hedberg if (err) 45106edf8deSJohan Hedberg BT_ERR("Encrypt data error"); 45206edf8deSJohan Hedberg 45306edf8deSJohan Hedberg return err; 45406edf8deSJohan Hedberg } 45506edf8deSJohan Hedberg 45628a220aaSArd Biesheuvel static int smp_s1(const u8 k[16], 45706edf8deSJohan Hedberg const u8 r1[16], const u8 r2[16], u8 _r[16]) 4586a77083aSJohan Hedberg { 4596a77083aSJohan Hedberg int err; 4606a77083aSJohan Hedberg 46106edf8deSJohan Hedberg /* Just least significant octets from r1 and r2 are considered */ 46206edf8deSJohan Hedberg memcpy(_r, r2, 8); 46306edf8deSJohan Hedberg memcpy(_r + 8, r1, 8); 4646a77083aSJohan Hedberg 46528a220aaSArd Biesheuvel err = smp_e(k, _r); 4666a77083aSJohan Hedberg if (err) 46706edf8deSJohan Hedberg BT_ERR("Encrypt data error"); 4686a77083aSJohan Hedberg 4696a77083aSJohan Hedberg return err; 4706a77083aSJohan Hedberg } 4716a77083aSJohan Hedberg 47228a220aaSArd Biesheuvel static int smp_ah(const u8 irk[16], const u8 r[3], u8 res[3]) 47360478054SJohan Hedberg { 474943a732aSJohan Hedberg u8 _res[16]; 47560478054SJohan Hedberg int err; 47660478054SJohan Hedberg 47760478054SJohan Hedberg /* r' = padding || r */ 478943a732aSJohan Hedberg memcpy(_res, r, 3); 479943a732aSJohan Hedberg memset(_res + 3, 0, 13); 48060478054SJohan Hedberg 48128a220aaSArd Biesheuvel err = smp_e(irk, _res); 48260478054SJohan Hedberg if (err) { 48360478054SJohan Hedberg BT_ERR("Encrypt error"); 48460478054SJohan Hedberg return err; 48560478054SJohan Hedberg } 48660478054SJohan Hedberg 48760478054SJohan Hedberg /* The output of the random address function ah is: 488c5080d42SMarcel Holtmann * ah(k, r) = e(k, r') mod 2^24 48960478054SJohan Hedberg * The output of the security function e is then truncated to 24 bits 49060478054SJohan Hedberg * by taking the least significant 24 bits of the output of e as the 49160478054SJohan Hedberg * result of ah. 49260478054SJohan Hedberg */ 493943a732aSJohan Hedberg memcpy(res, _res, 3); 49460478054SJohan Hedberg 49560478054SJohan Hedberg return 0; 49660478054SJohan Hedberg } 49760478054SJohan Hedberg 498cd082797SJohan Hedberg bool smp_irk_matches(struct hci_dev *hdev, const u8 irk[16], 499cd082797SJohan Hedberg const bdaddr_t *bdaddr) 50060478054SJohan Hedberg { 501defce9e8SJohan Hedberg struct l2cap_chan *chan = hdev->smp_data; 50260478054SJohan Hedberg u8 hash[3]; 50360478054SJohan Hedberg int err; 50460478054SJohan Hedberg 505defce9e8SJohan Hedberg if (!chan || !chan->data) 506defce9e8SJohan Hedberg return false; 507defce9e8SJohan Hedberg 50856860245SMarcel Holtmann bt_dev_dbg(hdev, "RPA %pMR IRK %*phN", bdaddr, 16, irk); 50960478054SJohan Hedberg 51028a220aaSArd Biesheuvel err = smp_ah(irk, &bdaddr->b[3], hash); 51160478054SJohan Hedberg if (err) 51260478054SJohan Hedberg return false; 51360478054SJohan Hedberg 514329d8230SJason A. Donenfeld return !crypto_memneq(bdaddr->b, hash, 3); 51560478054SJohan Hedberg } 51660478054SJohan Hedberg 517cd082797SJohan Hedberg int smp_generate_rpa(struct hci_dev *hdev, const u8 irk[16], bdaddr_t *rpa) 518b1e2b3aeSJohan Hedberg { 519defce9e8SJohan Hedberg struct l2cap_chan *chan = hdev->smp_data; 520b1e2b3aeSJohan Hedberg int err; 521b1e2b3aeSJohan Hedberg 522defce9e8SJohan Hedberg if (!chan || !chan->data) 523defce9e8SJohan Hedberg return -EOPNOTSUPP; 524defce9e8SJohan Hedberg 525b1e2b3aeSJohan Hedberg get_random_bytes(&rpa->b[3], 3); 526b1e2b3aeSJohan Hedberg 527b1e2b3aeSJohan Hedberg rpa->b[5] &= 0x3f; /* Clear two most significant bits */ 528b1e2b3aeSJohan Hedberg rpa->b[5] |= 0x40; /* Set second most significant bit */ 529b1e2b3aeSJohan Hedberg 53028a220aaSArd Biesheuvel err = smp_ah(irk, &rpa->b[3], rpa->b); 531b1e2b3aeSJohan Hedberg if (err < 0) 532b1e2b3aeSJohan Hedberg return err; 533b1e2b3aeSJohan Hedberg 53456860245SMarcel Holtmann bt_dev_dbg(hdev, "RPA %pMR", rpa); 535b1e2b3aeSJohan Hedberg 536b1e2b3aeSJohan Hedberg return 0; 537b1e2b3aeSJohan Hedberg } 538b1e2b3aeSJohan Hedberg 53960a27d65SMarcel Holtmann int smp_generate_oob(struct hci_dev *hdev, u8 hash[16], u8 rand[16]) 54060a27d65SMarcel Holtmann { 54160a27d65SMarcel Holtmann struct l2cap_chan *chan = hdev->smp_data; 54260a27d65SMarcel Holtmann struct smp_dev *smp; 54360a27d65SMarcel Holtmann int err; 54460a27d65SMarcel Holtmann 54560a27d65SMarcel Holtmann if (!chan || !chan->data) 54660a27d65SMarcel Holtmann return -EOPNOTSUPP; 54760a27d65SMarcel Holtmann 54860a27d65SMarcel Holtmann smp = chan->data; 54960a27d65SMarcel Holtmann 55060a27d65SMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS)) { 55156860245SMarcel Holtmann bt_dev_dbg(hdev, "Using debug keys"); 552c0153b0bSTudor Ambarus err = set_ecdh_privkey(smp->tfm_ecdh, debug_sk); 553c0153b0bSTudor Ambarus if (err) 554c0153b0bSTudor Ambarus return err; 55560a27d65SMarcel Holtmann memcpy(smp->local_pk, debug_pk, 64); 55660a27d65SMarcel Holtmann smp->debug_key = true; 55760a27d65SMarcel Holtmann } else { 55860a27d65SMarcel Holtmann while (true) { 559c0153b0bSTudor Ambarus /* Generate key pair for Secure Connections */ 560c0153b0bSTudor Ambarus err = generate_ecdh_keys(smp->tfm_ecdh, smp->local_pk); 561a2976416STudor Ambarus if (err) 562a2976416STudor Ambarus return err; 56360a27d65SMarcel Holtmann 56460a27d65SMarcel Holtmann /* This is unlikely, but we need to check that 56591641b79SZheng Yongjun * we didn't accidentally generate a debug key. 56660a27d65SMarcel Holtmann */ 567c0153b0bSTudor Ambarus if (crypto_memneq(smp->local_pk, debug_pk, 64)) 56860a27d65SMarcel Holtmann break; 56960a27d65SMarcel Holtmann } 57060a27d65SMarcel Holtmann smp->debug_key = false; 57160a27d65SMarcel Holtmann } 57260a27d65SMarcel Holtmann 57360a27d65SMarcel Holtmann SMP_DBG("OOB Public Key X: %32phN", smp->local_pk); 57460a27d65SMarcel Holtmann SMP_DBG("OOB Public Key Y: %32phN", smp->local_pk + 32); 57560a27d65SMarcel Holtmann 576fb334feeSMarcel Holtmann get_random_bytes(smp->local_rand, 16); 57760a27d65SMarcel Holtmann 57860a27d65SMarcel Holtmann err = smp_f4(smp->tfm_cmac, smp->local_pk, smp->local_pk, 579fb334feeSMarcel Holtmann smp->local_rand, 0, hash); 58060a27d65SMarcel Holtmann if (err < 0) 58160a27d65SMarcel Holtmann return err; 58260a27d65SMarcel Holtmann 583fb334feeSMarcel Holtmann memcpy(rand, smp->local_rand, 16); 58460a27d65SMarcel Holtmann 58594f14e47SJohan Hedberg smp->local_oob = true; 58694f14e47SJohan Hedberg 58760a27d65SMarcel Holtmann return 0; 58860a27d65SMarcel Holtmann } 58960a27d65SMarcel Holtmann 590eb492e01SAnderson Briglia static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data) 591eb492e01SAnderson Briglia { 5925d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 593b68fda68SJohan Hedberg struct smp_chan *smp; 5945d88cc73SJohan Hedberg struct kvec iv[2]; 5955d88cc73SJohan Hedberg struct msghdr msg; 5965d88cc73SJohan Hedberg 5975d88cc73SJohan Hedberg if (!chan) 5985d88cc73SJohan Hedberg return; 599eb492e01SAnderson Briglia 6002e1614f7SLuiz Augusto von Dentz bt_dev_dbg(conn->hcon->hdev, "code 0x%2.2x", code); 601eb492e01SAnderson Briglia 6025d88cc73SJohan Hedberg iv[0].iov_base = &code; 6035d88cc73SJohan Hedberg iv[0].iov_len = 1; 604eb492e01SAnderson Briglia 6055d88cc73SJohan Hedberg iv[1].iov_base = data; 6065d88cc73SJohan Hedberg iv[1].iov_len = len; 6075d88cc73SJohan Hedberg 6085d88cc73SJohan Hedberg memset(&msg, 0, sizeof(msg)); 6095d88cc73SJohan Hedberg 610de4eda9dSAl Viro iov_iter_kvec(&msg.msg_iter, ITER_SOURCE, iv, 2, 1 + len); 6115d88cc73SJohan Hedberg 6125d88cc73SJohan Hedberg l2cap_chan_send(chan, &msg, 1 + len); 613e2dcd113SVinicius Costa Gomes 614b68fda68SJohan Hedberg if (!chan->data) 615b68fda68SJohan Hedberg return; 616b68fda68SJohan Hedberg 617b68fda68SJohan Hedberg smp = chan->data; 618b68fda68SJohan Hedberg 619b68fda68SJohan Hedberg cancel_delayed_work_sync(&smp->security_timer); 620b68fda68SJohan Hedberg schedule_delayed_work(&smp->security_timer, SMP_TIMEOUT); 621eb492e01SAnderson Briglia } 622eb492e01SAnderson Briglia 623d2eb9e10SJohan Hedberg static u8 authreq_to_seclevel(u8 authreq) 6242b64d153SBrian Gix { 625d2eb9e10SJohan Hedberg if (authreq & SMP_AUTH_MITM) { 626d2eb9e10SJohan Hedberg if (authreq & SMP_AUTH_SC) 627d2eb9e10SJohan Hedberg return BT_SECURITY_FIPS; 6282b64d153SBrian Gix else 629d2eb9e10SJohan Hedberg return BT_SECURITY_HIGH; 630d2eb9e10SJohan Hedberg } else { 6312b64d153SBrian Gix return BT_SECURITY_MEDIUM; 6322b64d153SBrian Gix } 633d2eb9e10SJohan Hedberg } 6342b64d153SBrian Gix 6352b64d153SBrian Gix static __u8 seclevel_to_authreq(__u8 sec_level) 6362b64d153SBrian Gix { 6372b64d153SBrian Gix switch (sec_level) { 638d2eb9e10SJohan Hedberg case BT_SECURITY_FIPS: 6392b64d153SBrian Gix case BT_SECURITY_HIGH: 6402b64d153SBrian Gix return SMP_AUTH_MITM | SMP_AUTH_BONDING; 6412b64d153SBrian Gix case BT_SECURITY_MEDIUM: 6422b64d153SBrian Gix return SMP_AUTH_BONDING; 6432b64d153SBrian Gix default: 6442b64d153SBrian Gix return SMP_AUTH_NONE; 6452b64d153SBrian Gix } 6462b64d153SBrian Gix } 6472b64d153SBrian Gix 648b8e66eacSVinicius Costa Gomes static void build_pairing_cmd(struct l2cap_conn *conn, 64954790f73SVinicius Costa Gomes struct smp_cmd_pairing *req, 650f1560463SMarcel Holtmann struct smp_cmd_pairing *rsp, __u8 authreq) 651b8e66eacSVinicius Costa Gomes { 6525d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 6535d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 654fd349c02SJohan Hedberg struct hci_conn *hcon = conn->hcon; 655fd349c02SJohan Hedberg struct hci_dev *hdev = hcon->hdev; 65602b05bd8SJohan Hedberg u8 local_dist = 0, remote_dist = 0, oob_flag = SMP_OOB_NOT_PRESENT; 65754790f73SVinicius Costa Gomes 658d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_BONDABLE)) { 6597ee4ea36SMarcel Holtmann local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN; 6607ee4ea36SMarcel Holtmann remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN; 66154790f73SVinicius Costa Gomes authreq |= SMP_AUTH_BONDING; 6622b64d153SBrian Gix } else { 6632b64d153SBrian Gix authreq &= ~SMP_AUTH_BONDING; 66454790f73SVinicius Costa Gomes } 66554790f73SVinicius Costa Gomes 666d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_RPA_RESOLVING)) 667fd349c02SJohan Hedberg remote_dist |= SMP_DIST_ID_KEY; 668fd349c02SJohan Hedberg 669d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_PRIVACY)) 670863efaf2SJohan Hedberg local_dist |= SMP_DIST_ID_KEY; 671863efaf2SJohan Hedberg 672d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SC_ENABLED) && 67302b05bd8SJohan Hedberg (authreq & SMP_AUTH_SC)) { 67402b05bd8SJohan Hedberg struct oob_data *oob_data; 67502b05bd8SJohan Hedberg u8 bdaddr_type; 67602b05bd8SJohan Hedberg 677d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SSP_ENABLED)) { 678df8e1a4cSJohan Hedberg local_dist |= SMP_DIST_LINK_KEY; 679df8e1a4cSJohan Hedberg remote_dist |= SMP_DIST_LINK_KEY; 680df8e1a4cSJohan Hedberg } 68102b05bd8SJohan Hedberg 68202b05bd8SJohan Hedberg if (hcon->dst_type == ADDR_LE_DEV_PUBLIC) 68302b05bd8SJohan Hedberg bdaddr_type = BDADDR_LE_PUBLIC; 68402b05bd8SJohan Hedberg else 68502b05bd8SJohan Hedberg bdaddr_type = BDADDR_LE_RANDOM; 68602b05bd8SJohan Hedberg 68702b05bd8SJohan Hedberg oob_data = hci_find_remote_oob_data(hdev, &hcon->dst, 68802b05bd8SJohan Hedberg bdaddr_type); 6894775a4eaSMarcel Holtmann if (oob_data && oob_data->present) { 6901a8bab4fSJohan Hedberg set_bit(SMP_FLAG_REMOTE_OOB, &smp->flags); 69102b05bd8SJohan Hedberg oob_flag = SMP_OOB_PRESENT; 692a29b0733SJohan Hedberg memcpy(smp->rr, oob_data->rand256, 16); 69302b05bd8SJohan Hedberg memcpy(smp->pcnf, oob_data->hash256, 16); 694bc07cd69SMarcel Holtmann SMP_DBG("OOB Remote Confirmation: %16phN", smp->pcnf); 695bc07cd69SMarcel Holtmann SMP_DBG("OOB Remote Random: %16phN", smp->rr); 69602b05bd8SJohan Hedberg } 69702b05bd8SJohan Hedberg 698df8e1a4cSJohan Hedberg } else { 699df8e1a4cSJohan Hedberg authreq &= ~SMP_AUTH_SC; 700df8e1a4cSJohan Hedberg } 701df8e1a4cSJohan Hedberg 70254790f73SVinicius Costa Gomes if (rsp == NULL) { 70354790f73SVinicius Costa Gomes req->io_capability = conn->hcon->io_capability; 70402b05bd8SJohan Hedberg req->oob_flag = oob_flag; 70530d65e08SMatias Karhumaa req->max_key_size = hdev->le_max_key_size; 706fd349c02SJohan Hedberg req->init_key_dist = local_dist; 707fd349c02SJohan Hedberg req->resp_key_dist = remote_dist; 7080edb14deSJohan Hedberg req->auth_req = (authreq & AUTH_REQ_MASK(hdev)); 709fd349c02SJohan Hedberg 710fd349c02SJohan Hedberg smp->remote_key_dist = remote_dist; 71154790f73SVinicius Costa Gomes return; 71254790f73SVinicius Costa Gomes } 71354790f73SVinicius Costa Gomes 71454790f73SVinicius Costa Gomes rsp->io_capability = conn->hcon->io_capability; 71502b05bd8SJohan Hedberg rsp->oob_flag = oob_flag; 71630d65e08SMatias Karhumaa rsp->max_key_size = hdev->le_max_key_size; 717fd349c02SJohan Hedberg rsp->init_key_dist = req->init_key_dist & remote_dist; 718fd349c02SJohan Hedberg rsp->resp_key_dist = req->resp_key_dist & local_dist; 7190edb14deSJohan Hedberg rsp->auth_req = (authreq & AUTH_REQ_MASK(hdev)); 720fd349c02SJohan Hedberg 721fd349c02SJohan Hedberg smp->remote_key_dist = rsp->init_key_dist; 722b8e66eacSVinicius Costa Gomes } 723b8e66eacSVinicius Costa Gomes 7243158c50cSVinicius Costa Gomes static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size) 7253158c50cSVinicius Costa Gomes { 7265d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 7272fd36558SJohan Hedberg struct hci_dev *hdev = conn->hcon->hdev; 7285d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 7291c1def09SVinicius Costa Gomes 73049c06c9eSŁukasz Rymanowski if (conn->hcon->pending_sec_level == BT_SECURITY_FIPS && 73149c06c9eSŁukasz Rymanowski max_key_size != SMP_MAX_ENC_KEY_SIZE) 73249c06c9eSŁukasz Rymanowski return SMP_ENC_KEY_SIZE; 73349c06c9eSŁukasz Rymanowski 73430d65e08SMatias Karhumaa if (max_key_size > hdev->le_max_key_size || 7352fd36558SJohan Hedberg max_key_size < SMP_MIN_ENC_KEY_SIZE) 7363158c50cSVinicius Costa Gomes return SMP_ENC_KEY_SIZE; 7373158c50cSVinicius Costa Gomes 738f7aa611aSVinicius Costa Gomes smp->enc_key_size = max_key_size; 7393158c50cSVinicius Costa Gomes 7403158c50cSVinicius Costa Gomes return 0; 7413158c50cSVinicius Costa Gomes } 7423158c50cSVinicius Costa Gomes 7436f48e260SJohan Hedberg static void smp_chan_destroy(struct l2cap_conn *conn) 7446f48e260SJohan Hedberg { 7456f48e260SJohan Hedberg struct l2cap_chan *chan = conn->smp; 7466f48e260SJohan Hedberg struct smp_chan *smp = chan->data; 747923e2414SJohan Hedberg struct hci_conn *hcon = conn->hcon; 7486f48e260SJohan Hedberg bool complete; 7496f48e260SJohan Hedberg 7506f48e260SJohan Hedberg BUG_ON(!smp); 7516f48e260SJohan Hedberg 7526f48e260SJohan Hedberg cancel_delayed_work_sync(&smp->security_timer); 7536f48e260SJohan Hedberg 7546f48e260SJohan Hedberg complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags); 755923e2414SJohan Hedberg mgmt_smp_complete(hcon, complete); 7566f48e260SJohan Hedberg 757453431a5SWaiman Long kfree_sensitive(smp->csrk); 758fad646e1SArchie Pusaka kfree_sensitive(smp->responder_csrk); 759453431a5SWaiman Long kfree_sensitive(smp->link_key); 7606f48e260SJohan Hedberg 76171af2f6bSHerbert Xu crypto_free_shash(smp->tfm_cmac); 76247eb2ac8STudor Ambarus crypto_free_kpp(smp->tfm_ecdh); 7636f48e260SJohan Hedberg 764923e2414SJohan Hedberg /* Ensure that we don't leave any debug key around if debug key 765923e2414SJohan Hedberg * support hasn't been explicitly enabled. 766923e2414SJohan Hedberg */ 767923e2414SJohan Hedberg if (smp->ltk && smp->ltk->type == SMP_LTK_P256_DEBUG && 768d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hcon->hdev, HCI_KEEP_DEBUG_KEYS)) { 769923e2414SJohan Hedberg list_del_rcu(&smp->ltk->list); 770923e2414SJohan Hedberg kfree_rcu(smp->ltk, rcu); 771923e2414SJohan Hedberg smp->ltk = NULL; 772923e2414SJohan Hedberg } 773923e2414SJohan Hedberg 7746f48e260SJohan Hedberg /* If pairing failed clean up any keys we might have */ 7756f48e260SJohan Hedberg if (!complete) { 7766f48e260SJohan Hedberg if (smp->ltk) { 777970d0f1bSJohan Hedberg list_del_rcu(&smp->ltk->list); 778970d0f1bSJohan Hedberg kfree_rcu(smp->ltk, rcu); 7796f48e260SJohan Hedberg } 7806f48e260SJohan Hedberg 781fad646e1SArchie Pusaka if (smp->responder_ltk) { 782fad646e1SArchie Pusaka list_del_rcu(&smp->responder_ltk->list); 783fad646e1SArchie Pusaka kfree_rcu(smp->responder_ltk, rcu); 7846f48e260SJohan Hedberg } 7856f48e260SJohan Hedberg 7866f48e260SJohan Hedberg if (smp->remote_irk) { 787adae20cbSJohan Hedberg list_del_rcu(&smp->remote_irk->list); 788adae20cbSJohan Hedberg kfree_rcu(smp->remote_irk, rcu); 7896f48e260SJohan Hedberg } 7906f48e260SJohan Hedberg } 7916f48e260SJohan Hedberg 7926f48e260SJohan Hedberg chan->data = NULL; 793453431a5SWaiman Long kfree_sensitive(smp); 794923e2414SJohan Hedberg hci_conn_drop(hcon); 7956f48e260SJohan Hedberg } 7966f48e260SJohan Hedberg 79784794e11SJohan Hedberg static void smp_failure(struct l2cap_conn *conn, u8 reason) 7984f957a76SBrian Gix { 799bab73cb6SJohan Hedberg struct hci_conn *hcon = conn->hcon; 800b68fda68SJohan Hedberg struct l2cap_chan *chan = conn->smp; 801bab73cb6SJohan Hedberg 80284794e11SJohan Hedberg if (reason) 8034f957a76SBrian Gix smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason), 8044f957a76SBrian Gix &reason); 8054f957a76SBrian Gix 806e1e930f5SJohan Hedberg mgmt_auth_failed(hcon, HCI_ERROR_AUTH_FAILURE); 807f1c09c07SVinicius Costa Gomes 808fc75cc86SJohan Hedberg if (chan->data) 8094f957a76SBrian Gix smp_chan_destroy(conn); 8104f957a76SBrian Gix } 8114f957a76SBrian Gix 8122b64d153SBrian Gix #define JUST_WORKS 0x00 8132b64d153SBrian Gix #define JUST_CFM 0x01 8142b64d153SBrian Gix #define REQ_PASSKEY 0x02 8152b64d153SBrian Gix #define CFM_PASSKEY 0x03 8162b64d153SBrian Gix #define REQ_OOB 0x04 8175e3d3d9bSJohan Hedberg #define DSP_PASSKEY 0x05 8182b64d153SBrian Gix #define OVERLAP 0xFF 8192b64d153SBrian Gix 8202b64d153SBrian Gix static const u8 gen_method[5][5] = { 8212b64d153SBrian Gix { JUST_WORKS, JUST_CFM, REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY }, 8222b64d153SBrian Gix { JUST_WORKS, JUST_CFM, REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY }, 8232b64d153SBrian Gix { CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY }, 8242b64d153SBrian Gix { JUST_WORKS, JUST_CFM, JUST_WORKS, JUST_WORKS, JUST_CFM }, 8252b64d153SBrian Gix { CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, OVERLAP }, 8262b64d153SBrian Gix }; 8272b64d153SBrian Gix 8285e3d3d9bSJohan Hedberg static const u8 sc_method[5][5] = { 8295e3d3d9bSJohan Hedberg { JUST_WORKS, JUST_CFM, REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY }, 8305e3d3d9bSJohan Hedberg { JUST_WORKS, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY }, 8315e3d3d9bSJohan Hedberg { DSP_PASSKEY, DSP_PASSKEY, REQ_PASSKEY, JUST_WORKS, DSP_PASSKEY }, 8325e3d3d9bSJohan Hedberg { JUST_WORKS, JUST_CFM, JUST_WORKS, JUST_WORKS, JUST_CFM }, 8335e3d3d9bSJohan Hedberg { DSP_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY }, 8345e3d3d9bSJohan Hedberg }; 8355e3d3d9bSJohan Hedberg 836581370ccSJohan Hedberg static u8 get_auth_method(struct smp_chan *smp, u8 local_io, u8 remote_io) 837581370ccSJohan Hedberg { 8382bcd4003SJohan Hedberg /* If either side has unknown io_caps, use JUST_CFM (which gets 8392bcd4003SJohan Hedberg * converted later to JUST_WORKS if we're initiators. 8402bcd4003SJohan Hedberg */ 841581370ccSJohan Hedberg if (local_io > SMP_IO_KEYBOARD_DISPLAY || 842581370ccSJohan Hedberg remote_io > SMP_IO_KEYBOARD_DISPLAY) 8432bcd4003SJohan Hedberg return JUST_CFM; 844581370ccSJohan Hedberg 8455e3d3d9bSJohan Hedberg if (test_bit(SMP_FLAG_SC, &smp->flags)) 8465e3d3d9bSJohan Hedberg return sc_method[remote_io][local_io]; 8475e3d3d9bSJohan Hedberg 848581370ccSJohan Hedberg return gen_method[remote_io][local_io]; 849581370ccSJohan Hedberg } 850581370ccSJohan Hedberg 8512b64d153SBrian Gix static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth, 8522b64d153SBrian Gix u8 local_io, u8 remote_io) 8532b64d153SBrian Gix { 8542b64d153SBrian Gix struct hci_conn *hcon = conn->hcon; 8555d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 8565d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 8572b64d153SBrian Gix u32 passkey = 0; 858d1d900f8SGuenter Roeck int ret; 8592b64d153SBrian Gix 8602b64d153SBrian Gix /* Initialize key for JUST WORKS */ 8612b64d153SBrian Gix memset(smp->tk, 0, sizeof(smp->tk)); 8624a74d658SJohan Hedberg clear_bit(SMP_FLAG_TK_VALID, &smp->flags); 8632b64d153SBrian Gix 86483b4b195SKai Ye bt_dev_dbg(hcon->hdev, "auth:%u lcl:%u rem:%u", auth, local_io, 8652e1614f7SLuiz Augusto von Dentz remote_io); 8662b64d153SBrian Gix 8672bcd4003SJohan Hedberg /* If neither side wants MITM, either "just" confirm an incoming 8682bcd4003SJohan Hedberg * request or use just-works for outgoing ones. The JUST_CFM 8692bcd4003SJohan Hedberg * will be converted to JUST_WORKS if necessary later in this 8702bcd4003SJohan Hedberg * function. If either side has MITM look up the method from the 8712bcd4003SJohan Hedberg * table. 8722bcd4003SJohan Hedberg */ 873581370ccSJohan Hedberg if (!(auth & SMP_AUTH_MITM)) 874783e0574SJohan Hedberg smp->method = JUST_CFM; 8752b64d153SBrian Gix else 876783e0574SJohan Hedberg smp->method = get_auth_method(smp, local_io, remote_io); 8772b64d153SBrian Gix 878a82505c7SJohan Hedberg /* Don't confirm locally initiated pairing attempts */ 879783e0574SJohan Hedberg if (smp->method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR, 880783e0574SJohan Hedberg &smp->flags)) 881783e0574SJohan Hedberg smp->method = JUST_WORKS; 882a82505c7SJohan Hedberg 88302f3e254SJohan Hedberg /* Don't bother user space with no IO capabilities */ 884783e0574SJohan Hedberg if (smp->method == JUST_CFM && 885783e0574SJohan Hedberg hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT) 886783e0574SJohan Hedberg smp->method = JUST_WORKS; 88702f3e254SJohan Hedberg 88892516cd9SSonny Sasaka /* If Just Works, Continue with Zero TK and ask user-space for 88992516cd9SSonny Sasaka * confirmation */ 890783e0574SJohan Hedberg if (smp->method == JUST_WORKS) { 891d1d900f8SGuenter Roeck ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst, 89292516cd9SSonny Sasaka hcon->type, 89392516cd9SSonny Sasaka hcon->dst_type, 89492516cd9SSonny Sasaka passkey, 1); 895d1d900f8SGuenter Roeck if (ret) 896d1d900f8SGuenter Roeck return ret; 89792516cd9SSonny Sasaka set_bit(SMP_FLAG_WAIT_USER, &smp->flags); 8982b64d153SBrian Gix return 0; 8992b64d153SBrian Gix } 9002b64d153SBrian Gix 90119c5ce9cSJohan Hedberg /* If this function is used for SC -> legacy fallback we 90219c5ce9cSJohan Hedberg * can only recover the just-works case. 90319c5ce9cSJohan Hedberg */ 90419c5ce9cSJohan Hedberg if (test_bit(SMP_FLAG_SC, &smp->flags)) 90519c5ce9cSJohan Hedberg return -EINVAL; 90619c5ce9cSJohan Hedberg 9072b64d153SBrian Gix /* Not Just Works/Confirm results in MITM Authentication */ 908783e0574SJohan Hedberg if (smp->method != JUST_CFM) { 9094a74d658SJohan Hedberg set_bit(SMP_FLAG_MITM_AUTH, &smp->flags); 9105eb596f5SJohan Hedberg if (hcon->pending_sec_level < BT_SECURITY_HIGH) 9115eb596f5SJohan Hedberg hcon->pending_sec_level = BT_SECURITY_HIGH; 9125eb596f5SJohan Hedberg } 9132b64d153SBrian Gix 91474be523cSArchie Pusaka /* If both devices have Keyboard-Display I/O, the initiator 91574be523cSArchie Pusaka * Confirms and the responder Enters the passkey. 9162b64d153SBrian Gix */ 917783e0574SJohan Hedberg if (smp->method == OVERLAP) { 91840bef302SJohan Hedberg if (hcon->role == HCI_ROLE_MASTER) 919783e0574SJohan Hedberg smp->method = CFM_PASSKEY; 9202b64d153SBrian Gix else 921783e0574SJohan Hedberg smp->method = REQ_PASSKEY; 9222b64d153SBrian Gix } 9232b64d153SBrian Gix 92401ad34d2SJohan Hedberg /* Generate random passkey. */ 925783e0574SJohan Hedberg if (smp->method == CFM_PASSKEY) { 926943a732aSJohan Hedberg memset(smp->tk, 0, sizeof(smp->tk)); 9272b64d153SBrian Gix get_random_bytes(&passkey, sizeof(passkey)); 9282b64d153SBrian Gix passkey %= 1000000; 929943a732aSJohan Hedberg put_unaligned_le32(passkey, smp->tk); 93083b4b195SKai Ye bt_dev_dbg(hcon->hdev, "PassKey: %u", passkey); 9314a74d658SJohan Hedberg set_bit(SMP_FLAG_TK_VALID, &smp->flags); 9322b64d153SBrian Gix } 9332b64d153SBrian Gix 934783e0574SJohan Hedberg if (smp->method == REQ_PASSKEY) 935ce39fb4eSMarcel Holtmann ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst, 936272d90dfSJohan Hedberg hcon->type, hcon->dst_type); 937783e0574SJohan Hedberg else if (smp->method == JUST_CFM) 9384eb65e66SJohan Hedberg ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst, 9394eb65e66SJohan Hedberg hcon->type, hcon->dst_type, 9404eb65e66SJohan Hedberg passkey, 1); 9412b64d153SBrian Gix else 94201ad34d2SJohan Hedberg ret = mgmt_user_passkey_notify(hcon->hdev, &hcon->dst, 943272d90dfSJohan Hedberg hcon->type, hcon->dst_type, 94439adbffeSJohan Hedberg passkey, 0); 9452b64d153SBrian Gix 9462b64d153SBrian Gix return ret; 9472b64d153SBrian Gix } 9482b64d153SBrian Gix 9491cc61144SJohan Hedberg static u8 smp_confirm(struct smp_chan *smp) 9508aab4757SVinicius Costa Gomes { 9518aab4757SVinicius Costa Gomes struct l2cap_conn *conn = smp->conn; 9528aab4757SVinicius Costa Gomes struct smp_cmd_pairing_confirm cp; 9538aab4757SVinicius Costa Gomes int ret; 9548aab4757SVinicius Costa Gomes 9552e1614f7SLuiz Augusto von Dentz bt_dev_dbg(conn->hcon->hdev, "conn %p", conn); 9568aab4757SVinicius Costa Gomes 95728a220aaSArd Biesheuvel ret = smp_c1(smp->tk, smp->prnd, smp->preq, smp->prsp, 958b1cd5fd9SJohan Hedberg conn->hcon->init_addr_type, &conn->hcon->init_addr, 959943a732aSJohan Hedberg conn->hcon->resp_addr_type, &conn->hcon->resp_addr, 960943a732aSJohan Hedberg cp.confirm_val); 9611cc61144SJohan Hedberg if (ret) 9621cc61144SJohan Hedberg return SMP_UNSPECIFIED; 9638aab4757SVinicius Costa Gomes 9644a74d658SJohan Hedberg clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags); 9652b64d153SBrian Gix 9668aab4757SVinicius Costa Gomes smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp); 9678aab4757SVinicius Costa Gomes 968b28b4943SJohan Hedberg if (conn->hcon->out) 969b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); 970b28b4943SJohan Hedberg else 971b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM); 972b28b4943SJohan Hedberg 9731cc61144SJohan Hedberg return 0; 9748aab4757SVinicius Costa Gomes } 9758aab4757SVinicius Costa Gomes 976861580a9SJohan Hedberg static u8 smp_random(struct smp_chan *smp) 9778aab4757SVinicius Costa Gomes { 9788aab4757SVinicius Costa Gomes struct l2cap_conn *conn = smp->conn; 9798aab4757SVinicius Costa Gomes struct hci_conn *hcon = conn->hcon; 980861580a9SJohan Hedberg u8 confirm[16]; 9818aab4757SVinicius Costa Gomes int ret; 9828aab4757SVinicius Costa Gomes 9832e1614f7SLuiz Augusto von Dentz bt_dev_dbg(conn->hcon->hdev, "conn %p %s", conn, 984fad646e1SArchie Pusaka conn->hcon->out ? "initiator" : "responder"); 9858aab4757SVinicius Costa Gomes 98628a220aaSArd Biesheuvel ret = smp_c1(smp->tk, smp->rrnd, smp->preq, smp->prsp, 987b1cd5fd9SJohan Hedberg hcon->init_addr_type, &hcon->init_addr, 988943a732aSJohan Hedberg hcon->resp_addr_type, &hcon->resp_addr, confirm); 989861580a9SJohan Hedberg if (ret) 990861580a9SJohan Hedberg return SMP_UNSPECIFIED; 9918aab4757SVinicius Costa Gomes 992329d8230SJason A. Donenfeld if (crypto_memneq(smp->pcnf, confirm, sizeof(smp->pcnf))) { 9932064ee33SMarcel Holtmann bt_dev_err(hcon->hdev, "pairing failed " 9942064ee33SMarcel Holtmann "(confirmation values mismatch)"); 995861580a9SJohan Hedberg return SMP_CONFIRM_FAILED; 9968aab4757SVinicius Costa Gomes } 9978aab4757SVinicius Costa Gomes 9988aab4757SVinicius Costa Gomes if (hcon->out) { 999fe39c7b2SMarcel Holtmann u8 stk[16]; 1000fe39c7b2SMarcel Holtmann __le64 rand = 0; 1001fe39c7b2SMarcel Holtmann __le16 ediv = 0; 10028aab4757SVinicius Costa Gomes 100328a220aaSArd Biesheuvel smp_s1(smp->tk, smp->rrnd, smp->prnd, stk); 10048aab4757SVinicius Costa Gomes 1005861580a9SJohan Hedberg if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags)) 1006861580a9SJohan Hedberg return SMP_UNSPECIFIED; 10078aab4757SVinicius Costa Gomes 10088b76ce34SJohan Hedberg hci_le_start_enc(hcon, ediv, rand, stk, smp->enc_key_size); 1009f7aa611aSVinicius Costa Gomes hcon->enc_key_size = smp->enc_key_size; 1010fe59a05fSJohan Hedberg set_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags); 10118aab4757SVinicius Costa Gomes } else { 1012fff3490fSJohan Hedberg u8 stk[16], auth; 1013fe39c7b2SMarcel Holtmann __le64 rand = 0; 1014fe39c7b2SMarcel Holtmann __le16 ediv = 0; 10158aab4757SVinicius Costa Gomes 1016943a732aSJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd), 1017943a732aSJohan Hedberg smp->prnd); 10188aab4757SVinicius Costa Gomes 101928a220aaSArd Biesheuvel smp_s1(smp->tk, smp->prnd, smp->rrnd, stk); 10208aab4757SVinicius Costa Gomes 1021fff3490fSJohan Hedberg if (hcon->pending_sec_level == BT_SECURITY_HIGH) 1022fff3490fSJohan Hedberg auth = 1; 1023fff3490fSJohan Hedberg else 1024fff3490fSJohan Hedberg auth = 0; 1025fff3490fSJohan Hedberg 1026fad646e1SArchie Pusaka /* Even though there's no _RESPONDER suffix this is the 1027fad646e1SArchie Pusaka * responder STK we're adding for later lookup (the initiator 10287d5843b7SJohan Hedberg * STK never needs to be stored). 10297d5843b7SJohan Hedberg */ 1030ce39fb4eSMarcel Holtmann hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, 10312ceba539SJohan Hedberg SMP_STK, auth, stk, smp->enc_key_size, ediv, rand); 10328aab4757SVinicius Costa Gomes } 10338aab4757SVinicius Costa Gomes 1034861580a9SJohan Hedberg return 0; 10358aab4757SVinicius Costa Gomes } 10368aab4757SVinicius Costa Gomes 103744f1a7abSJohan Hedberg static void smp_notify_keys(struct l2cap_conn *conn) 103844f1a7abSJohan Hedberg { 103944f1a7abSJohan Hedberg struct l2cap_chan *chan = conn->smp; 104044f1a7abSJohan Hedberg struct smp_chan *smp = chan->data; 104144f1a7abSJohan Hedberg struct hci_conn *hcon = conn->hcon; 104244f1a7abSJohan Hedberg struct hci_dev *hdev = hcon->hdev; 104344f1a7abSJohan Hedberg struct smp_cmd_pairing *req = (void *) &smp->preq[1]; 104444f1a7abSJohan Hedberg struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1]; 104544f1a7abSJohan Hedberg bool persistent; 104644f1a7abSJohan Hedberg 1047cad20c27SJohan Hedberg if (hcon->type == ACL_LINK) { 1048cad20c27SJohan Hedberg if (hcon->key_type == HCI_LK_DEBUG_COMBINATION) 1049cad20c27SJohan Hedberg persistent = false; 1050cad20c27SJohan Hedberg else 1051cad20c27SJohan Hedberg persistent = !test_bit(HCI_CONN_FLUSH_KEY, 1052cad20c27SJohan Hedberg &hcon->flags); 1053cad20c27SJohan Hedberg } else { 1054cad20c27SJohan Hedberg /* The LTKs, IRKs and CSRKs should be persistent only if 1055cad20c27SJohan Hedberg * both sides had the bonding bit set in their 1056cad20c27SJohan Hedberg * authentication requests. 1057cad20c27SJohan Hedberg */ 1058cad20c27SJohan Hedberg persistent = !!((req->auth_req & rsp->auth_req) & 1059cad20c27SJohan Hedberg SMP_AUTH_BONDING); 1060cad20c27SJohan Hedberg } 1061cad20c27SJohan Hedberg 106244f1a7abSJohan Hedberg if (smp->remote_irk) { 1063cad20c27SJohan Hedberg mgmt_new_irk(hdev, smp->remote_irk, persistent); 1064cad20c27SJohan Hedberg 106544f1a7abSJohan Hedberg /* Now that user space can be considered to know the 106644f1a7abSJohan Hedberg * identity address track the connection based on it 1067b5ae344dSJohan Hedberg * from now on (assuming this is an LE link). 106844f1a7abSJohan Hedberg */ 1069b5ae344dSJohan Hedberg if (hcon->type == LE_LINK) { 107044f1a7abSJohan Hedberg bacpy(&hcon->dst, &smp->remote_irk->bdaddr); 107144f1a7abSJohan Hedberg hcon->dst_type = smp->remote_irk->addr_type; 1072*b8b23001SLuiz Augusto von Dentz /* Use a short delay to make sure the new address is 1073*b8b23001SLuiz Augusto von Dentz * propagated _before_ the channels. 1074*b8b23001SLuiz Augusto von Dentz */ 1075*b8b23001SLuiz Augusto von Dentz queue_delayed_work(hdev->workqueue, 1076*b8b23001SLuiz Augusto von Dentz &conn->id_addr_timer, 1077*b8b23001SLuiz Augusto von Dentz ID_ADDR_TIMEOUT); 1078b5ae344dSJohan Hedberg } 107944f1a7abSJohan Hedberg } 108044f1a7abSJohan Hedberg 108144f1a7abSJohan Hedberg if (smp->csrk) { 108244f1a7abSJohan Hedberg smp->csrk->bdaddr_type = hcon->dst_type; 108344f1a7abSJohan Hedberg bacpy(&smp->csrk->bdaddr, &hcon->dst); 108444f1a7abSJohan Hedberg mgmt_new_csrk(hdev, smp->csrk, persistent); 108544f1a7abSJohan Hedberg } 108644f1a7abSJohan Hedberg 1087fad646e1SArchie Pusaka if (smp->responder_csrk) { 1088fad646e1SArchie Pusaka smp->responder_csrk->bdaddr_type = hcon->dst_type; 1089fad646e1SArchie Pusaka bacpy(&smp->responder_csrk->bdaddr, &hcon->dst); 1090fad646e1SArchie Pusaka mgmt_new_csrk(hdev, smp->responder_csrk, persistent); 109144f1a7abSJohan Hedberg } 109244f1a7abSJohan Hedberg 109344f1a7abSJohan Hedberg if (smp->ltk) { 109444f1a7abSJohan Hedberg smp->ltk->bdaddr_type = hcon->dst_type; 109544f1a7abSJohan Hedberg bacpy(&smp->ltk->bdaddr, &hcon->dst); 109644f1a7abSJohan Hedberg mgmt_new_ltk(hdev, smp->ltk, persistent); 109744f1a7abSJohan Hedberg } 109844f1a7abSJohan Hedberg 1099fad646e1SArchie Pusaka if (smp->responder_ltk) { 1100fad646e1SArchie Pusaka smp->responder_ltk->bdaddr_type = hcon->dst_type; 1101fad646e1SArchie Pusaka bacpy(&smp->responder_ltk->bdaddr, &hcon->dst); 1102fad646e1SArchie Pusaka mgmt_new_ltk(hdev, smp->responder_ltk, persistent); 110344f1a7abSJohan Hedberg } 11046a77083aSJohan Hedberg 11056a77083aSJohan Hedberg if (smp->link_key) { 1106e3befab9SJohan Hedberg struct link_key *key; 1107e3befab9SJohan Hedberg u8 type; 1108e3befab9SJohan Hedberg 1109e3befab9SJohan Hedberg if (test_bit(SMP_FLAG_DEBUG_KEY, &smp->flags)) 1110e3befab9SJohan Hedberg type = HCI_LK_DEBUG_COMBINATION; 1111e3befab9SJohan Hedberg else if (hcon->sec_level == BT_SECURITY_FIPS) 1112e3befab9SJohan Hedberg type = HCI_LK_AUTH_COMBINATION_P256; 1113e3befab9SJohan Hedberg else 1114e3befab9SJohan Hedberg type = HCI_LK_UNAUTH_COMBINATION_P256; 1115e3befab9SJohan Hedberg 1116e3befab9SJohan Hedberg key = hci_add_link_key(hdev, smp->conn->hcon, &hcon->dst, 1117e3befab9SJohan Hedberg smp->link_key, type, 0, &persistent); 1118e3befab9SJohan Hedberg if (key) { 1119e3befab9SJohan Hedberg mgmt_new_link_key(hdev, key, persistent); 1120e3befab9SJohan Hedberg 1121e3befab9SJohan Hedberg /* Don't keep debug keys around if the relevant 1122e3befab9SJohan Hedberg * flag is not set. 1123e3befab9SJohan Hedberg */ 1124d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_KEEP_DEBUG_KEYS) && 1125e3befab9SJohan Hedberg key->type == HCI_LK_DEBUG_COMBINATION) { 1126e3befab9SJohan Hedberg list_del_rcu(&key->list); 1127e3befab9SJohan Hedberg kfree_rcu(key, rcu); 1128e3befab9SJohan Hedberg } 1129e3befab9SJohan Hedberg } 11306a77083aSJohan Hedberg } 11316a77083aSJohan Hedberg } 11326a77083aSJohan Hedberg 1133d3e54a87SJohan Hedberg static void sc_add_ltk(struct smp_chan *smp) 1134d3e54a87SJohan Hedberg { 1135d3e54a87SJohan Hedberg struct hci_conn *hcon = smp->conn->hcon; 1136d3e54a87SJohan Hedberg u8 key_type, auth; 1137d3e54a87SJohan Hedberg 1138d3e54a87SJohan Hedberg if (test_bit(SMP_FLAG_DEBUG_KEY, &smp->flags)) 1139d3e54a87SJohan Hedberg key_type = SMP_LTK_P256_DEBUG; 1140d3e54a87SJohan Hedberg else 1141d3e54a87SJohan Hedberg key_type = SMP_LTK_P256; 1142d3e54a87SJohan Hedberg 1143d3e54a87SJohan Hedberg if (hcon->pending_sec_level == BT_SECURITY_FIPS) 1144d3e54a87SJohan Hedberg auth = 1; 1145d3e54a87SJohan Hedberg else 1146d3e54a87SJohan Hedberg auth = 0; 1147d3e54a87SJohan Hedberg 1148d3e54a87SJohan Hedberg smp->ltk = hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, 1149d3e54a87SJohan Hedberg key_type, auth, smp->tk, smp->enc_key_size, 1150d3e54a87SJohan Hedberg 0, 0); 1151d3e54a87SJohan Hedberg } 1152d3e54a87SJohan Hedberg 11536a77083aSJohan Hedberg static void sc_generate_link_key(struct smp_chan *smp) 11546a77083aSJohan Hedberg { 1155a62da6f1SJohan Hedberg /* From core spec. Spells out in ASCII as 'lebr'. */ 11566a77083aSJohan Hedberg const u8 lebr[4] = { 0x72, 0x62, 0x65, 0x6c }; 11576a77083aSJohan Hedberg 11586a77083aSJohan Hedberg smp->link_key = kzalloc(16, GFP_KERNEL); 11596a77083aSJohan Hedberg if (!smp->link_key) 11606a77083aSJohan Hedberg return; 11616a77083aSJohan Hedberg 1162a62da6f1SJohan Hedberg if (test_bit(SMP_FLAG_CT2, &smp->flags)) { 1163151129dfSChristophe JAILLET /* SALT = 0x000000000000000000000000746D7031 */ 1164a62da6f1SJohan Hedberg const u8 salt[16] = { 0x31, 0x70, 0x6d, 0x74 }; 1165a62da6f1SJohan Hedberg 1166a62da6f1SJohan Hedberg if (smp_h7(smp->tfm_cmac, smp->tk, salt, smp->link_key)) { 1167453431a5SWaiman Long kfree_sensitive(smp->link_key); 1168a62da6f1SJohan Hedberg smp->link_key = NULL; 1169a62da6f1SJohan Hedberg return; 1170a62da6f1SJohan Hedberg } 1171a62da6f1SJohan Hedberg } else { 1172a62da6f1SJohan Hedberg /* From core spec. Spells out in ASCII as 'tmp1'. */ 1173a62da6f1SJohan Hedberg const u8 tmp1[4] = { 0x31, 0x70, 0x6d, 0x74 }; 1174a62da6f1SJohan Hedberg 11756a77083aSJohan Hedberg if (smp_h6(smp->tfm_cmac, smp->tk, tmp1, smp->link_key)) { 1176453431a5SWaiman Long kfree_sensitive(smp->link_key); 11776a77083aSJohan Hedberg smp->link_key = NULL; 11786a77083aSJohan Hedberg return; 11796a77083aSJohan Hedberg } 1180a62da6f1SJohan Hedberg } 11816a77083aSJohan Hedberg 11826a77083aSJohan Hedberg if (smp_h6(smp->tfm_cmac, smp->link_key, lebr, smp->link_key)) { 1183453431a5SWaiman Long kfree_sensitive(smp->link_key); 11846a77083aSJohan Hedberg smp->link_key = NULL; 11856a77083aSJohan Hedberg return; 11866a77083aSJohan Hedberg } 118744f1a7abSJohan Hedberg } 118844f1a7abSJohan Hedberg 1189b28b4943SJohan Hedberg static void smp_allow_key_dist(struct smp_chan *smp) 1190b28b4943SJohan Hedberg { 1191b28b4943SJohan Hedberg /* Allow the first expected phase 3 PDU. The rest of the PDUs 1192b28b4943SJohan Hedberg * will be allowed in each PDU handler to ensure we receive 1193b28b4943SJohan Hedberg * them in the correct order. 1194b28b4943SJohan Hedberg */ 1195b28b4943SJohan Hedberg if (smp->remote_key_dist & SMP_DIST_ENC_KEY) 1196b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_ENCRYPT_INFO); 1197b28b4943SJohan Hedberg else if (smp->remote_key_dist & SMP_DIST_ID_KEY) 1198b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO); 1199b28b4943SJohan Hedberg else if (smp->remote_key_dist & SMP_DIST_SIGN) 1200b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO); 1201b28b4943SJohan Hedberg } 1202b28b4943SJohan Hedberg 1203b5ae344dSJohan Hedberg static void sc_generate_ltk(struct smp_chan *smp) 1204b5ae344dSJohan Hedberg { 1205a62da6f1SJohan Hedberg /* From core spec. Spells out in ASCII as 'brle'. */ 1206b5ae344dSJohan Hedberg const u8 brle[4] = { 0x65, 0x6c, 0x72, 0x62 }; 1207b5ae344dSJohan Hedberg struct hci_conn *hcon = smp->conn->hcon; 1208b5ae344dSJohan Hedberg struct hci_dev *hdev = hcon->hdev; 1209b5ae344dSJohan Hedberg struct link_key *key; 1210b5ae344dSJohan Hedberg 1211b5ae344dSJohan Hedberg key = hci_find_link_key(hdev, &hcon->dst); 1212b5ae344dSJohan Hedberg if (!key) { 12132064ee33SMarcel Holtmann bt_dev_err(hdev, "no Link Key found to generate LTK"); 1214b5ae344dSJohan Hedberg return; 1215b5ae344dSJohan Hedberg } 1216b5ae344dSJohan Hedberg 1217b5ae344dSJohan Hedberg if (key->type == HCI_LK_DEBUG_COMBINATION) 1218b5ae344dSJohan Hedberg set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags); 1219b5ae344dSJohan Hedberg 1220a62da6f1SJohan Hedberg if (test_bit(SMP_FLAG_CT2, &smp->flags)) { 1221151129dfSChristophe JAILLET /* SALT = 0x000000000000000000000000746D7032 */ 1222a62da6f1SJohan Hedberg const u8 salt[16] = { 0x32, 0x70, 0x6d, 0x74 }; 1223a62da6f1SJohan Hedberg 1224a62da6f1SJohan Hedberg if (smp_h7(smp->tfm_cmac, key->val, salt, smp->tk)) 1225a62da6f1SJohan Hedberg return; 1226a62da6f1SJohan Hedberg } else { 1227a62da6f1SJohan Hedberg /* From core spec. Spells out in ASCII as 'tmp2'. */ 1228a62da6f1SJohan Hedberg const u8 tmp2[4] = { 0x32, 0x70, 0x6d, 0x74 }; 1229a62da6f1SJohan Hedberg 1230b5ae344dSJohan Hedberg if (smp_h6(smp->tfm_cmac, key->val, tmp2, smp->tk)) 1231b5ae344dSJohan Hedberg return; 1232a62da6f1SJohan Hedberg } 1233b5ae344dSJohan Hedberg 1234b5ae344dSJohan Hedberg if (smp_h6(smp->tfm_cmac, smp->tk, brle, smp->tk)) 1235b5ae344dSJohan Hedberg return; 1236b5ae344dSJohan Hedberg 1237b5ae344dSJohan Hedberg sc_add_ltk(smp); 1238b5ae344dSJohan Hedberg } 1239b5ae344dSJohan Hedberg 1240d6268e86SJohan Hedberg static void smp_distribute_keys(struct smp_chan *smp) 124144f1a7abSJohan Hedberg { 124244f1a7abSJohan Hedberg struct smp_cmd_pairing *req, *rsp; 124386d1407cSJohan Hedberg struct l2cap_conn *conn = smp->conn; 124444f1a7abSJohan Hedberg struct hci_conn *hcon = conn->hcon; 124544f1a7abSJohan Hedberg struct hci_dev *hdev = hcon->hdev; 124644f1a7abSJohan Hedberg __u8 *keydist; 124744f1a7abSJohan Hedberg 12482e1614f7SLuiz Augusto von Dentz bt_dev_dbg(hdev, "conn %p", conn); 124944f1a7abSJohan Hedberg 125044f1a7abSJohan Hedberg rsp = (void *) &smp->prsp[1]; 125144f1a7abSJohan Hedberg 125244f1a7abSJohan Hedberg /* The responder sends its keys first */ 1253b28b4943SJohan Hedberg if (hcon->out && (smp->remote_key_dist & KEY_DIST_MASK)) { 1254b28b4943SJohan Hedberg smp_allow_key_dist(smp); 125586d1407cSJohan Hedberg return; 1256b28b4943SJohan Hedberg } 125744f1a7abSJohan Hedberg 125844f1a7abSJohan Hedberg req = (void *) &smp->preq[1]; 125944f1a7abSJohan Hedberg 126044f1a7abSJohan Hedberg if (hcon->out) { 126144f1a7abSJohan Hedberg keydist = &rsp->init_key_dist; 126244f1a7abSJohan Hedberg *keydist &= req->init_key_dist; 126344f1a7abSJohan Hedberg } else { 126444f1a7abSJohan Hedberg keydist = &rsp->resp_key_dist; 126544f1a7abSJohan Hedberg *keydist &= req->resp_key_dist; 126644f1a7abSJohan Hedberg } 126744f1a7abSJohan Hedberg 12686a77083aSJohan Hedberg if (test_bit(SMP_FLAG_SC, &smp->flags)) { 1269b5ae344dSJohan Hedberg if (hcon->type == LE_LINK && (*keydist & SMP_DIST_LINK_KEY)) 12706a77083aSJohan Hedberg sc_generate_link_key(smp); 1271b5ae344dSJohan Hedberg if (hcon->type == ACL_LINK && (*keydist & SMP_DIST_ENC_KEY)) 1272b5ae344dSJohan Hedberg sc_generate_ltk(smp); 12736a77083aSJohan Hedberg 12746a77083aSJohan Hedberg /* Clear the keys which are generated but not distributed */ 12756a77083aSJohan Hedberg *keydist &= ~SMP_SC_NO_DIST; 12766a77083aSJohan Hedberg } 12776a77083aSJohan Hedberg 12782e1614f7SLuiz Augusto von Dentz bt_dev_dbg(hdev, "keydist 0x%x", *keydist); 127944f1a7abSJohan Hedberg 128044f1a7abSJohan Hedberg if (*keydist & SMP_DIST_ENC_KEY) { 128144f1a7abSJohan Hedberg struct smp_cmd_encrypt_info enc; 1282fad646e1SArchie Pusaka struct smp_cmd_initiator_ident ident; 128344f1a7abSJohan Hedberg struct smp_ltk *ltk; 128444f1a7abSJohan Hedberg u8 authenticated; 128544f1a7abSJohan Hedberg __le16 ediv; 128644f1a7abSJohan Hedberg __le64 rand; 128744f1a7abSJohan Hedberg 12881fc62c52SJohan Hedberg /* Make sure we generate only the significant amount of 12891fc62c52SJohan Hedberg * bytes based on the encryption key size, and set the rest 12901fc62c52SJohan Hedberg * of the value to zeroes. 12911fc62c52SJohan Hedberg */ 12921fc62c52SJohan Hedberg get_random_bytes(enc.ltk, smp->enc_key_size); 12931fc62c52SJohan Hedberg memset(enc.ltk + smp->enc_key_size, 0, 12941fc62c52SJohan Hedberg sizeof(enc.ltk) - smp->enc_key_size); 12951fc62c52SJohan Hedberg 129644f1a7abSJohan Hedberg get_random_bytes(&ediv, sizeof(ediv)); 129744f1a7abSJohan Hedberg get_random_bytes(&rand, sizeof(rand)); 129844f1a7abSJohan Hedberg 129944f1a7abSJohan Hedberg smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc); 130044f1a7abSJohan Hedberg 130144f1a7abSJohan Hedberg authenticated = hcon->sec_level == BT_SECURITY_HIGH; 130244f1a7abSJohan Hedberg ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, 1303fad646e1SArchie Pusaka SMP_LTK_RESPONDER, authenticated, enc.ltk, 130444f1a7abSJohan Hedberg smp->enc_key_size, ediv, rand); 1305fad646e1SArchie Pusaka smp->responder_ltk = ltk; 130644f1a7abSJohan Hedberg 130744f1a7abSJohan Hedberg ident.ediv = ediv; 130844f1a7abSJohan Hedberg ident.rand = rand; 130944f1a7abSJohan Hedberg 1310fad646e1SArchie Pusaka smp_send_cmd(conn, SMP_CMD_INITIATOR_IDENT, sizeof(ident), 1311fad646e1SArchie Pusaka &ident); 131244f1a7abSJohan Hedberg 131344f1a7abSJohan Hedberg *keydist &= ~SMP_DIST_ENC_KEY; 131444f1a7abSJohan Hedberg } 131544f1a7abSJohan Hedberg 131644f1a7abSJohan Hedberg if (*keydist & SMP_DIST_ID_KEY) { 131744f1a7abSJohan Hedberg struct smp_cmd_ident_addr_info addrinfo; 131844f1a7abSJohan Hedberg struct smp_cmd_ident_info idinfo; 131944f1a7abSJohan Hedberg 132044f1a7abSJohan Hedberg memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk)); 132144f1a7abSJohan Hedberg 132244f1a7abSJohan Hedberg smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo); 132344f1a7abSJohan Hedberg 132444f1a7abSJohan Hedberg /* The hci_conn contains the local identity address 132544f1a7abSJohan Hedberg * after the connection has been established. 132644f1a7abSJohan Hedberg * 132744f1a7abSJohan Hedberg * This is true even when the connection has been 132844f1a7abSJohan Hedberg * established using a resolvable random address. 132944f1a7abSJohan Hedberg */ 133044f1a7abSJohan Hedberg bacpy(&addrinfo.bdaddr, &hcon->src); 133144f1a7abSJohan Hedberg addrinfo.addr_type = hcon->src_type; 133244f1a7abSJohan Hedberg 133344f1a7abSJohan Hedberg smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo), 133444f1a7abSJohan Hedberg &addrinfo); 133544f1a7abSJohan Hedberg 133644f1a7abSJohan Hedberg *keydist &= ~SMP_DIST_ID_KEY; 133744f1a7abSJohan Hedberg } 133844f1a7abSJohan Hedberg 133944f1a7abSJohan Hedberg if (*keydist & SMP_DIST_SIGN) { 134044f1a7abSJohan Hedberg struct smp_cmd_sign_info sign; 134144f1a7abSJohan Hedberg struct smp_csrk *csrk; 134244f1a7abSJohan Hedberg 134344f1a7abSJohan Hedberg /* Generate a new random key */ 134444f1a7abSJohan Hedberg get_random_bytes(sign.csrk, sizeof(sign.csrk)); 134544f1a7abSJohan Hedberg 134644f1a7abSJohan Hedberg csrk = kzalloc(sizeof(*csrk), GFP_KERNEL); 134744f1a7abSJohan Hedberg if (csrk) { 13484cd3928aSJohan Hedberg if (hcon->sec_level > BT_SECURITY_MEDIUM) 13494cd3928aSJohan Hedberg csrk->type = MGMT_CSRK_LOCAL_AUTHENTICATED; 13504cd3928aSJohan Hedberg else 13514cd3928aSJohan Hedberg csrk->type = MGMT_CSRK_LOCAL_UNAUTHENTICATED; 135244f1a7abSJohan Hedberg memcpy(csrk->val, sign.csrk, sizeof(csrk->val)); 135344f1a7abSJohan Hedberg } 1354fad646e1SArchie Pusaka smp->responder_csrk = csrk; 135544f1a7abSJohan Hedberg 135644f1a7abSJohan Hedberg smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign); 135744f1a7abSJohan Hedberg 135844f1a7abSJohan Hedberg *keydist &= ~SMP_DIST_SIGN; 135944f1a7abSJohan Hedberg } 136044f1a7abSJohan Hedberg 136144f1a7abSJohan Hedberg /* If there are still keys to be received wait for them */ 1362b28b4943SJohan Hedberg if (smp->remote_key_dist & KEY_DIST_MASK) { 1363b28b4943SJohan Hedberg smp_allow_key_dist(smp); 136486d1407cSJohan Hedberg return; 1365b28b4943SJohan Hedberg } 136644f1a7abSJohan Hedberg 136744f1a7abSJohan Hedberg set_bit(SMP_FLAG_COMPLETE, &smp->flags); 136844f1a7abSJohan Hedberg smp_notify_keys(conn); 136944f1a7abSJohan Hedberg 137044f1a7abSJohan Hedberg smp_chan_destroy(conn); 137144f1a7abSJohan Hedberg } 137244f1a7abSJohan Hedberg 1373b68fda68SJohan Hedberg static void smp_timeout(struct work_struct *work) 1374b68fda68SJohan Hedberg { 1375b68fda68SJohan Hedberg struct smp_chan *smp = container_of(work, struct smp_chan, 1376b68fda68SJohan Hedberg security_timer.work); 1377b68fda68SJohan Hedberg struct l2cap_conn *conn = smp->conn; 1378b68fda68SJohan Hedberg 13792e1614f7SLuiz Augusto von Dentz bt_dev_dbg(conn->hcon->hdev, "conn %p", conn); 1380b68fda68SJohan Hedberg 13811e91c29eSJohan Hedberg hci_disconnect(conn->hcon, HCI_ERROR_REMOTE_USER_TERM); 1382b68fda68SJohan Hedberg } 1383b68fda68SJohan Hedberg 13848aab4757SVinicius Costa Gomes static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) 13858aab4757SVinicius Costa Gomes { 13862e1614f7SLuiz Augusto von Dentz struct hci_conn *hcon = conn->hcon; 13875d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 13888aab4757SVinicius Costa Gomes struct smp_chan *smp; 13898aab4757SVinicius Costa Gomes 1390f1560463SMarcel Holtmann smp = kzalloc(sizeof(*smp), GFP_ATOMIC); 1391fc75cc86SJohan Hedberg if (!smp) 13928aab4757SVinicius Costa Gomes return NULL; 13938aab4757SVinicius Costa Gomes 139471af2f6bSHerbert Xu smp->tfm_cmac = crypto_alloc_shash("cmac(aes)", 0, 0); 1395407cecf6SJohan Hedberg if (IS_ERR(smp->tfm_cmac)) { 13962e1614f7SLuiz Augusto von Dentz bt_dev_err(hcon->hdev, "Unable to create CMAC crypto context"); 139728a220aaSArd Biesheuvel goto zfree_smp; 139847eb2ac8STudor Ambarus } 139947eb2ac8STudor Ambarus 14006763f5eaSMeng Yu smp->tfm_ecdh = crypto_alloc_kpp("ecdh-nist-p256", 0, 0); 140147eb2ac8STudor Ambarus if (IS_ERR(smp->tfm_ecdh)) { 14022e1614f7SLuiz Augusto von Dentz bt_dev_err(hcon->hdev, "Unable to create ECDH crypto context"); 140347eb2ac8STudor Ambarus goto free_shash; 1404407cecf6SJohan Hedberg } 1405407cecf6SJohan Hedberg 14068aab4757SVinicius Costa Gomes smp->conn = conn; 14075d88cc73SJohan Hedberg chan->data = smp; 14088aab4757SVinicius Costa Gomes 1409b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_FAIL); 1410b28b4943SJohan Hedberg 1411b68fda68SJohan Hedberg INIT_DELAYED_WORK(&smp->security_timer, smp_timeout); 1412b68fda68SJohan Hedberg 14132e1614f7SLuiz Augusto von Dentz hci_conn_hold(hcon); 14148aab4757SVinicius Costa Gomes 14158aab4757SVinicius Costa Gomes return smp; 141647eb2ac8STudor Ambarus 141747eb2ac8STudor Ambarus free_shash: 141847eb2ac8STudor Ambarus crypto_free_shash(smp->tfm_cmac); 141947eb2ac8STudor Ambarus zfree_smp: 1420453431a5SWaiman Long kfree_sensitive(smp); 142147eb2ac8STudor Ambarus return NULL; 14228aab4757SVinicius Costa Gomes } 14238aab4757SVinicius Costa Gomes 1424760b018bSJohan Hedberg static int sc_mackey_and_ltk(struct smp_chan *smp, u8 mackey[16], u8 ltk[16]) 1425760b018bSJohan Hedberg { 1426760b018bSJohan Hedberg struct hci_conn *hcon = smp->conn->hcon; 1427760b018bSJohan Hedberg u8 *na, *nb, a[7], b[7]; 1428760b018bSJohan Hedberg 1429760b018bSJohan Hedberg if (hcon->out) { 1430760b018bSJohan Hedberg na = smp->prnd; 1431760b018bSJohan Hedberg nb = smp->rrnd; 1432760b018bSJohan Hedberg } else { 1433760b018bSJohan Hedberg na = smp->rrnd; 1434760b018bSJohan Hedberg nb = smp->prnd; 1435760b018bSJohan Hedberg } 1436760b018bSJohan Hedberg 1437760b018bSJohan Hedberg memcpy(a, &hcon->init_addr, 6); 1438760b018bSJohan Hedberg memcpy(b, &hcon->resp_addr, 6); 1439760b018bSJohan Hedberg a[6] = hcon->init_addr_type; 1440760b018bSJohan Hedberg b[6] = hcon->resp_addr_type; 1441760b018bSJohan Hedberg 1442760b018bSJohan Hedberg return smp_f5(smp->tfm_cmac, smp->dhkey, na, nb, a, b, mackey, ltk); 1443760b018bSJohan Hedberg } 1444760b018bSJohan Hedberg 144538606f14SJohan Hedberg static void sc_dhkey_check(struct smp_chan *smp) 1446760b018bSJohan Hedberg { 1447760b018bSJohan Hedberg struct hci_conn *hcon = smp->conn->hcon; 1448760b018bSJohan Hedberg struct smp_cmd_dhkey_check check; 1449760b018bSJohan Hedberg u8 a[7], b[7], *local_addr, *remote_addr; 1450760b018bSJohan Hedberg u8 io_cap[3], r[16]; 1451760b018bSJohan Hedberg 1452760b018bSJohan Hedberg memcpy(a, &hcon->init_addr, 6); 1453760b018bSJohan Hedberg memcpy(b, &hcon->resp_addr, 6); 1454760b018bSJohan Hedberg a[6] = hcon->init_addr_type; 1455760b018bSJohan Hedberg b[6] = hcon->resp_addr_type; 1456760b018bSJohan Hedberg 1457760b018bSJohan Hedberg if (hcon->out) { 1458760b018bSJohan Hedberg local_addr = a; 1459760b018bSJohan Hedberg remote_addr = b; 1460760b018bSJohan Hedberg memcpy(io_cap, &smp->preq[1], 3); 1461760b018bSJohan Hedberg } else { 1462760b018bSJohan Hedberg local_addr = b; 1463760b018bSJohan Hedberg remote_addr = a; 1464760b018bSJohan Hedberg memcpy(io_cap, &smp->prsp[1], 3); 1465760b018bSJohan Hedberg } 1466760b018bSJohan Hedberg 1467dddd3059SJohan Hedberg memset(r, 0, sizeof(r)); 1468dddd3059SJohan Hedberg 1469dddd3059SJohan Hedberg if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY) 147038606f14SJohan Hedberg put_unaligned_le32(hcon->passkey_notify, r); 1471760b018bSJohan Hedberg 1472a29b0733SJohan Hedberg if (smp->method == REQ_OOB) 1473a29b0733SJohan Hedberg memcpy(r, smp->rr, 16); 1474a29b0733SJohan Hedberg 1475760b018bSJohan Hedberg smp_f6(smp->tfm_cmac, smp->mackey, smp->prnd, smp->rrnd, r, io_cap, 1476760b018bSJohan Hedberg local_addr, remote_addr, check.e); 1477760b018bSJohan Hedberg 1478760b018bSJohan Hedberg smp_send_cmd(smp->conn, SMP_CMD_DHKEY_CHECK, sizeof(check), &check); 1479dddd3059SJohan Hedberg } 1480dddd3059SJohan Hedberg 148138606f14SJohan Hedberg static u8 sc_passkey_send_confirm(struct smp_chan *smp) 148238606f14SJohan Hedberg { 148338606f14SJohan Hedberg struct l2cap_conn *conn = smp->conn; 148438606f14SJohan Hedberg struct hci_conn *hcon = conn->hcon; 148538606f14SJohan Hedberg struct smp_cmd_pairing_confirm cfm; 148638606f14SJohan Hedberg u8 r; 148738606f14SJohan Hedberg 148838606f14SJohan Hedberg r = ((hcon->passkey_notify >> smp->passkey_round) & 0x01); 148938606f14SJohan Hedberg r |= 0x80; 149038606f14SJohan Hedberg 149138606f14SJohan Hedberg get_random_bytes(smp->prnd, sizeof(smp->prnd)); 149238606f14SJohan Hedberg 149338606f14SJohan Hedberg if (smp_f4(smp->tfm_cmac, smp->local_pk, smp->remote_pk, smp->prnd, r, 149438606f14SJohan Hedberg cfm.confirm_val)) 149538606f14SJohan Hedberg return SMP_UNSPECIFIED; 149638606f14SJohan Hedberg 149738606f14SJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cfm), &cfm); 149838606f14SJohan Hedberg 149938606f14SJohan Hedberg return 0; 150038606f14SJohan Hedberg } 150138606f14SJohan Hedberg 150238606f14SJohan Hedberg static u8 sc_passkey_round(struct smp_chan *smp, u8 smp_op) 150338606f14SJohan Hedberg { 150438606f14SJohan Hedberg struct l2cap_conn *conn = smp->conn; 150538606f14SJohan Hedberg struct hci_conn *hcon = conn->hcon; 150638606f14SJohan Hedberg struct hci_dev *hdev = hcon->hdev; 150738606f14SJohan Hedberg u8 cfm[16], r; 150838606f14SJohan Hedberg 150938606f14SJohan Hedberg /* Ignore the PDU if we've already done 20 rounds (0 - 19) */ 151038606f14SJohan Hedberg if (smp->passkey_round >= 20) 151138606f14SJohan Hedberg return 0; 151238606f14SJohan Hedberg 151338606f14SJohan Hedberg switch (smp_op) { 151438606f14SJohan Hedberg case SMP_CMD_PAIRING_RANDOM: 151538606f14SJohan Hedberg r = ((hcon->passkey_notify >> smp->passkey_round) & 0x01); 151638606f14SJohan Hedberg r |= 0x80; 151738606f14SJohan Hedberg 151838606f14SJohan Hedberg if (smp_f4(smp->tfm_cmac, smp->remote_pk, smp->local_pk, 151938606f14SJohan Hedberg smp->rrnd, r, cfm)) 152038606f14SJohan Hedberg return SMP_UNSPECIFIED; 152138606f14SJohan Hedberg 1522329d8230SJason A. Donenfeld if (crypto_memneq(smp->pcnf, cfm, 16)) 152338606f14SJohan Hedberg return SMP_CONFIRM_FAILED; 152438606f14SJohan Hedberg 152538606f14SJohan Hedberg smp->passkey_round++; 152638606f14SJohan Hedberg 152738606f14SJohan Hedberg if (smp->passkey_round == 20) { 152838606f14SJohan Hedberg /* Generate MacKey and LTK */ 152938606f14SJohan Hedberg if (sc_mackey_and_ltk(smp, smp->mackey, smp->tk)) 153038606f14SJohan Hedberg return SMP_UNSPECIFIED; 153138606f14SJohan Hedberg } 153238606f14SJohan Hedberg 153338606f14SJohan Hedberg /* The round is only complete when the initiator 153438606f14SJohan Hedberg * receives pairing random. 153538606f14SJohan Hedberg */ 153638606f14SJohan Hedberg if (!hcon->out) { 153738606f14SJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, 153838606f14SJohan Hedberg sizeof(smp->prnd), smp->prnd); 1539d3e54a87SJohan Hedberg if (smp->passkey_round == 20) 154038606f14SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK); 1541d3e54a87SJohan Hedberg else 154238606f14SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); 154338606f14SJohan Hedberg return 0; 154438606f14SJohan Hedberg } 154538606f14SJohan Hedberg 154638606f14SJohan Hedberg /* Start the next round */ 154738606f14SJohan Hedberg if (smp->passkey_round != 20) 154838606f14SJohan Hedberg return sc_passkey_round(smp, 0); 154938606f14SJohan Hedberg 155038606f14SJohan Hedberg /* Passkey rounds are complete - start DHKey Check */ 155138606f14SJohan Hedberg sc_dhkey_check(smp); 155238606f14SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK); 155338606f14SJohan Hedberg 155438606f14SJohan Hedberg break; 155538606f14SJohan Hedberg 155638606f14SJohan Hedberg case SMP_CMD_PAIRING_CONFIRM: 155738606f14SJohan Hedberg if (test_bit(SMP_FLAG_WAIT_USER, &smp->flags)) { 155838606f14SJohan Hedberg set_bit(SMP_FLAG_CFM_PENDING, &smp->flags); 155938606f14SJohan Hedberg return 0; 156038606f14SJohan Hedberg } 156138606f14SJohan Hedberg 156238606f14SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM); 156338606f14SJohan Hedberg 156438606f14SJohan Hedberg if (hcon->out) { 156538606f14SJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, 156638606f14SJohan Hedberg sizeof(smp->prnd), smp->prnd); 156738606f14SJohan Hedberg return 0; 156838606f14SJohan Hedberg } 156938606f14SJohan Hedberg 157038606f14SJohan Hedberg return sc_passkey_send_confirm(smp); 157138606f14SJohan Hedberg 157238606f14SJohan Hedberg case SMP_CMD_PUBLIC_KEY: 157338606f14SJohan Hedberg default: 157438606f14SJohan Hedberg /* Initiating device starts the round */ 157538606f14SJohan Hedberg if (!hcon->out) 157638606f14SJohan Hedberg return 0; 157738606f14SJohan Hedberg 15782e1614f7SLuiz Augusto von Dentz bt_dev_dbg(hdev, "Starting passkey round %u", 157938606f14SJohan Hedberg smp->passkey_round + 1); 158038606f14SJohan Hedberg 158138606f14SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); 158238606f14SJohan Hedberg 158338606f14SJohan Hedberg return sc_passkey_send_confirm(smp); 158438606f14SJohan Hedberg } 158538606f14SJohan Hedberg 158638606f14SJohan Hedberg return 0; 158738606f14SJohan Hedberg } 158838606f14SJohan Hedberg 1589dddd3059SJohan Hedberg static int sc_user_reply(struct smp_chan *smp, u16 mgmt_op, __le32 passkey) 1590dddd3059SJohan Hedberg { 159138606f14SJohan Hedberg struct l2cap_conn *conn = smp->conn; 159238606f14SJohan Hedberg struct hci_conn *hcon = conn->hcon; 159338606f14SJohan Hedberg u8 smp_op; 159438606f14SJohan Hedberg 159538606f14SJohan Hedberg clear_bit(SMP_FLAG_WAIT_USER, &smp->flags); 159638606f14SJohan Hedberg 1597dddd3059SJohan Hedberg switch (mgmt_op) { 1598dddd3059SJohan Hedberg case MGMT_OP_USER_PASSKEY_NEG_REPLY: 1599dddd3059SJohan Hedberg smp_failure(smp->conn, SMP_PASSKEY_ENTRY_FAILED); 1600dddd3059SJohan Hedberg return 0; 1601dddd3059SJohan Hedberg case MGMT_OP_USER_CONFIRM_NEG_REPLY: 1602dddd3059SJohan Hedberg smp_failure(smp->conn, SMP_NUMERIC_COMP_FAILED); 1603dddd3059SJohan Hedberg return 0; 160438606f14SJohan Hedberg case MGMT_OP_USER_PASSKEY_REPLY: 160538606f14SJohan Hedberg hcon->passkey_notify = le32_to_cpu(passkey); 160638606f14SJohan Hedberg smp->passkey_round = 0; 160738606f14SJohan Hedberg 160838606f14SJohan Hedberg if (test_and_clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags)) 160938606f14SJohan Hedberg smp_op = SMP_CMD_PAIRING_CONFIRM; 161038606f14SJohan Hedberg else 161138606f14SJohan Hedberg smp_op = 0; 161238606f14SJohan Hedberg 161338606f14SJohan Hedberg if (sc_passkey_round(smp, smp_op)) 161438606f14SJohan Hedberg return -EIO; 161538606f14SJohan Hedberg 161638606f14SJohan Hedberg return 0; 1617dddd3059SJohan Hedberg } 1618dddd3059SJohan Hedberg 1619d3e54a87SJohan Hedberg /* Initiator sends DHKey check first */ 1620d3e54a87SJohan Hedberg if (hcon->out) { 162138606f14SJohan Hedberg sc_dhkey_check(smp); 1622d3e54a87SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK); 1623d3e54a87SJohan Hedberg } else if (test_and_clear_bit(SMP_FLAG_DHKEY_PENDING, &smp->flags)) { 1624d3e54a87SJohan Hedberg sc_dhkey_check(smp); 1625d3e54a87SJohan Hedberg sc_add_ltk(smp); 1626d3e54a87SJohan Hedberg } 1627760b018bSJohan Hedberg 1628760b018bSJohan Hedberg return 0; 1629760b018bSJohan Hedberg } 1630760b018bSJohan Hedberg 16312b64d153SBrian Gix int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey) 16322b64d153SBrian Gix { 1633b10e8017SJohan Hedberg struct l2cap_conn *conn = hcon->l2cap_data; 16345d88cc73SJohan Hedberg struct l2cap_chan *chan; 16352b64d153SBrian Gix struct smp_chan *smp; 16362b64d153SBrian Gix u32 value; 1637fc75cc86SJohan Hedberg int err; 16382b64d153SBrian Gix 1639fc75cc86SJohan Hedberg if (!conn) 16402b64d153SBrian Gix return -ENOTCONN; 16412b64d153SBrian Gix 16420ae8ef67SLuiz Augusto von Dentz bt_dev_dbg(conn->hcon->hdev, ""); 16430ae8ef67SLuiz Augusto von Dentz 16445d88cc73SJohan Hedberg chan = conn->smp; 16455d88cc73SJohan Hedberg if (!chan) 16465d88cc73SJohan Hedberg return -ENOTCONN; 16475d88cc73SJohan Hedberg 1648fc75cc86SJohan Hedberg l2cap_chan_lock(chan); 1649fc75cc86SJohan Hedberg if (!chan->data) { 1650fc75cc86SJohan Hedberg err = -ENOTCONN; 1651fc75cc86SJohan Hedberg goto unlock; 1652fc75cc86SJohan Hedberg } 1653fc75cc86SJohan Hedberg 16545d88cc73SJohan Hedberg smp = chan->data; 16552b64d153SBrian Gix 1656760b018bSJohan Hedberg if (test_bit(SMP_FLAG_SC, &smp->flags)) { 1657760b018bSJohan Hedberg err = sc_user_reply(smp, mgmt_op, passkey); 1658760b018bSJohan Hedberg goto unlock; 1659760b018bSJohan Hedberg } 1660760b018bSJohan Hedberg 16612b64d153SBrian Gix switch (mgmt_op) { 16622b64d153SBrian Gix case MGMT_OP_USER_PASSKEY_REPLY: 16632b64d153SBrian Gix value = le32_to_cpu(passkey); 1664943a732aSJohan Hedberg memset(smp->tk, 0, sizeof(smp->tk)); 166583b4b195SKai Ye bt_dev_dbg(conn->hcon->hdev, "PassKey: %u", value); 1666943a732aSJohan Hedberg put_unaligned_le32(value, smp->tk); 166719186c7bSGustavo A. R. Silva fallthrough; 16682b64d153SBrian Gix case MGMT_OP_USER_CONFIRM_REPLY: 16694a74d658SJohan Hedberg set_bit(SMP_FLAG_TK_VALID, &smp->flags); 16702b64d153SBrian Gix break; 16712b64d153SBrian Gix case MGMT_OP_USER_PASSKEY_NEG_REPLY: 16722b64d153SBrian Gix case MGMT_OP_USER_CONFIRM_NEG_REPLY: 167384794e11SJohan Hedberg smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED); 1674fc75cc86SJohan Hedberg err = 0; 1675fc75cc86SJohan Hedberg goto unlock; 16762b64d153SBrian Gix default: 167784794e11SJohan Hedberg smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED); 1678fc75cc86SJohan Hedberg err = -EOPNOTSUPP; 1679fc75cc86SJohan Hedberg goto unlock; 16802b64d153SBrian Gix } 16812b64d153SBrian Gix 1682fc75cc86SJohan Hedberg err = 0; 1683fc75cc86SJohan Hedberg 16842b64d153SBrian Gix /* If it is our turn to send Pairing Confirm, do so now */ 16851cc61144SJohan Hedberg if (test_bit(SMP_FLAG_CFM_PENDING, &smp->flags)) { 16861cc61144SJohan Hedberg u8 rsp = smp_confirm(smp); 16871cc61144SJohan Hedberg if (rsp) 16881cc61144SJohan Hedberg smp_failure(conn, rsp); 16891cc61144SJohan Hedberg } 16902b64d153SBrian Gix 1691fc75cc86SJohan Hedberg unlock: 1692fc75cc86SJohan Hedberg l2cap_chan_unlock(chan); 1693fc75cc86SJohan Hedberg return err; 16942b64d153SBrian Gix } 16952b64d153SBrian Gix 1696b5ae344dSJohan Hedberg static void build_bredr_pairing_cmd(struct smp_chan *smp, 1697b5ae344dSJohan Hedberg struct smp_cmd_pairing *req, 1698b5ae344dSJohan Hedberg struct smp_cmd_pairing *rsp) 1699b5ae344dSJohan Hedberg { 1700b5ae344dSJohan Hedberg struct l2cap_conn *conn = smp->conn; 1701b5ae344dSJohan Hedberg struct hci_dev *hdev = conn->hcon->hdev; 1702b5ae344dSJohan Hedberg u8 local_dist = 0, remote_dist = 0; 1703b5ae344dSJohan Hedberg 1704d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_BONDABLE)) { 1705b5ae344dSJohan Hedberg local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN; 1706b5ae344dSJohan Hedberg remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN; 1707b5ae344dSJohan Hedberg } 1708b5ae344dSJohan Hedberg 1709d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_RPA_RESOLVING)) 1710b5ae344dSJohan Hedberg remote_dist |= SMP_DIST_ID_KEY; 1711b5ae344dSJohan Hedberg 1712d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_PRIVACY)) 1713b5ae344dSJohan Hedberg local_dist |= SMP_DIST_ID_KEY; 1714b5ae344dSJohan Hedberg 1715b5ae344dSJohan Hedberg if (!rsp) { 1716b5ae344dSJohan Hedberg memset(req, 0, sizeof(*req)); 1717b5ae344dSJohan Hedberg 1718a62da6f1SJohan Hedberg req->auth_req = SMP_AUTH_CT2; 1719b5ae344dSJohan Hedberg req->init_key_dist = local_dist; 1720b5ae344dSJohan Hedberg req->resp_key_dist = remote_dist; 1721e3f6a257SJohan Hedberg req->max_key_size = conn->hcon->enc_key_size; 1722b5ae344dSJohan Hedberg 1723b5ae344dSJohan Hedberg smp->remote_key_dist = remote_dist; 1724b5ae344dSJohan Hedberg 1725b5ae344dSJohan Hedberg return; 1726b5ae344dSJohan Hedberg } 1727b5ae344dSJohan Hedberg 1728b5ae344dSJohan Hedberg memset(rsp, 0, sizeof(*rsp)); 1729b5ae344dSJohan Hedberg 1730a62da6f1SJohan Hedberg rsp->auth_req = SMP_AUTH_CT2; 1731e3f6a257SJohan Hedberg rsp->max_key_size = conn->hcon->enc_key_size; 1732b5ae344dSJohan Hedberg rsp->init_key_dist = req->init_key_dist & remote_dist; 1733b5ae344dSJohan Hedberg rsp->resp_key_dist = req->resp_key_dist & local_dist; 1734b5ae344dSJohan Hedberg 1735b5ae344dSJohan Hedberg smp->remote_key_dist = rsp->init_key_dist; 1736b5ae344dSJohan Hedberg } 1737b5ae344dSJohan Hedberg 1738da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) 173988ba43b6SAnderson Briglia { 17403158c50cSVinicius Costa Gomes struct smp_cmd_pairing rsp, *req = (void *) skb->data; 1741fc75cc86SJohan Hedberg struct l2cap_chan *chan = conn->smp; 1742b3c6410bSJohan Hedberg struct hci_dev *hdev = conn->hcon->hdev; 17438aab4757SVinicius Costa Gomes struct smp_chan *smp; 1744c7262e71SJohan Hedberg u8 key_size, auth, sec_level; 17458aab4757SVinicius Costa Gomes int ret; 174688ba43b6SAnderson Briglia 17472e1614f7SLuiz Augusto von Dentz bt_dev_dbg(hdev, "conn %p", conn); 174888ba43b6SAnderson Briglia 1749c46b98beSJohan Hedberg if (skb->len < sizeof(*req)) 175038e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 1751c46b98beSJohan Hedberg 175240bef302SJohan Hedberg if (conn->hcon->role != HCI_ROLE_SLAVE) 17532b64d153SBrian Gix return SMP_CMD_NOTSUPP; 17542b64d153SBrian Gix 1755fc75cc86SJohan Hedberg if (!chan->data) 17568aab4757SVinicius Costa Gomes smp = smp_chan_create(conn); 1757fc75cc86SJohan Hedberg else 17585d88cc73SJohan Hedberg smp = chan->data; 1759d26a2345SVinicius Costa Gomes 1760d08fd0e7SAndrei Emeltchenko if (!smp) 1761d08fd0e7SAndrei Emeltchenko return SMP_UNSPECIFIED; 1762d08fd0e7SAndrei Emeltchenko 1763c05b9339SJohan Hedberg /* We didn't start the pairing, so match remote */ 17640edb14deSJohan Hedberg auth = req->auth_req & AUTH_REQ_MASK(hdev); 1765c05b9339SJohan Hedberg 1766d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_BONDABLE) && 1767c05b9339SJohan Hedberg (auth & SMP_AUTH_BONDING)) 1768b3c6410bSJohan Hedberg return SMP_PAIRING_NOTSUPP; 1769b3c6410bSJohan Hedberg 1770d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SC_ONLY) && !(auth & SMP_AUTH_SC)) 1771903b71c7SJohan Hedberg return SMP_AUTH_REQUIREMENTS; 1772903b71c7SJohan Hedberg 17731c1def09SVinicius Costa Gomes smp->preq[0] = SMP_CMD_PAIRING_REQ; 17741c1def09SVinicius Costa Gomes memcpy(&smp->preq[1], req, sizeof(*req)); 17753158c50cSVinicius Costa Gomes skb_pull(skb, sizeof(*req)); 177688ba43b6SAnderson Briglia 1777cb06d366SJohan Hedberg /* If the remote side's OOB flag is set it means it has 1778cb06d366SJohan Hedberg * successfully received our local OOB data - therefore set the 1779cb06d366SJohan Hedberg * flag to indicate that local OOB is in use. 1780cb06d366SJohan Hedberg */ 178194f14e47SJohan Hedberg if (req->oob_flag == SMP_OOB_PRESENT && SMP_DEV(hdev)->local_oob) 178258428563SJohan Hedberg set_bit(SMP_FLAG_LOCAL_OOB, &smp->flags); 178358428563SJohan Hedberg 1784b5ae344dSJohan Hedberg /* SMP over BR/EDR requires special treatment */ 1785b5ae344dSJohan Hedberg if (conn->hcon->type == ACL_LINK) { 1786b5ae344dSJohan Hedberg /* We must have a BR/EDR SC link */ 178708f63cc5SMarcel Holtmann if (!test_bit(HCI_CONN_AES_CCM, &conn->hcon->flags) && 1788b7cb93e5SMarcel Holtmann !hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP)) 1789b5ae344dSJohan Hedberg return SMP_CROSS_TRANSP_NOT_ALLOWED; 1790b5ae344dSJohan Hedberg 1791b5ae344dSJohan Hedberg set_bit(SMP_FLAG_SC, &smp->flags); 1792b5ae344dSJohan Hedberg 1793b5ae344dSJohan Hedberg build_bredr_pairing_cmd(smp, req, &rsp); 1794b5ae344dSJohan Hedberg 1795a62da6f1SJohan Hedberg if (req->auth_req & SMP_AUTH_CT2) 1796a62da6f1SJohan Hedberg set_bit(SMP_FLAG_CT2, &smp->flags); 1797a62da6f1SJohan Hedberg 1798b5ae344dSJohan Hedberg key_size = min(req->max_key_size, rsp.max_key_size); 1799b5ae344dSJohan Hedberg if (check_enc_key_size(conn, key_size)) 1800b5ae344dSJohan Hedberg return SMP_ENC_KEY_SIZE; 1801b5ae344dSJohan Hedberg 1802b5ae344dSJohan Hedberg /* Clear bits which are generated but not distributed */ 1803b5ae344dSJohan Hedberg smp->remote_key_dist &= ~SMP_SC_NO_DIST; 1804b5ae344dSJohan Hedberg 1805b5ae344dSJohan Hedberg smp->prsp[0] = SMP_CMD_PAIRING_RSP; 1806b5ae344dSJohan Hedberg memcpy(&smp->prsp[1], &rsp, sizeof(rsp)); 1807b5ae344dSJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp); 1808b5ae344dSJohan Hedberg 1809b5ae344dSJohan Hedberg smp_distribute_keys(smp); 1810b5ae344dSJohan Hedberg return 0; 1811b5ae344dSJohan Hedberg } 1812b5ae344dSJohan Hedberg 18135e3d3d9bSJohan Hedberg build_pairing_cmd(conn, req, &rsp, auth); 18145e3d3d9bSJohan Hedberg 1815a62da6f1SJohan Hedberg if (rsp.auth_req & SMP_AUTH_SC) { 18165e3d3d9bSJohan Hedberg set_bit(SMP_FLAG_SC, &smp->flags); 18175e3d3d9bSJohan Hedberg 1818a62da6f1SJohan Hedberg if (rsp.auth_req & SMP_AUTH_CT2) 1819a62da6f1SJohan Hedberg set_bit(SMP_FLAG_CT2, &smp->flags); 1820a62da6f1SJohan Hedberg } 1821a62da6f1SJohan Hedberg 18225be5e275SJohan Hedberg if (conn->hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT) 18231afc2a1aSJohan Hedberg sec_level = BT_SECURITY_MEDIUM; 18241afc2a1aSJohan Hedberg else 1825c7262e71SJohan Hedberg sec_level = authreq_to_seclevel(auth); 18261afc2a1aSJohan Hedberg 1827c7262e71SJohan Hedberg if (sec_level > conn->hcon->pending_sec_level) 1828c7262e71SJohan Hedberg conn->hcon->pending_sec_level = sec_level; 1829fdde0a26SIdo Yariv 183049c922bbSStephen Hemminger /* If we need MITM check that it can be achieved */ 18312ed8f65cSJohan Hedberg if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) { 18322ed8f65cSJohan Hedberg u8 method; 18332ed8f65cSJohan Hedberg 18342ed8f65cSJohan Hedberg method = get_auth_method(smp, conn->hcon->io_capability, 18352ed8f65cSJohan Hedberg req->io_capability); 18362ed8f65cSJohan Hedberg if (method == JUST_WORKS || method == JUST_CFM) 18372ed8f65cSJohan Hedberg return SMP_AUTH_REQUIREMENTS; 18382ed8f65cSJohan Hedberg } 18392ed8f65cSJohan Hedberg 18403158c50cSVinicius Costa Gomes key_size = min(req->max_key_size, rsp.max_key_size); 18413158c50cSVinicius Costa Gomes if (check_enc_key_size(conn, key_size)) 18423158c50cSVinicius Costa Gomes return SMP_ENC_KEY_SIZE; 184388ba43b6SAnderson Briglia 1844e84a6b13SJohan Hedberg get_random_bytes(smp->prnd, sizeof(smp->prnd)); 18458aab4757SVinicius Costa Gomes 18461c1def09SVinicius Costa Gomes smp->prsp[0] = SMP_CMD_PAIRING_RSP; 18471c1def09SVinicius Costa Gomes memcpy(&smp->prsp[1], &rsp, sizeof(rsp)); 1848f01ead31SAnderson Briglia 18493158c50cSVinicius Costa Gomes smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp); 18503b19146dSJohan Hedberg 18513b19146dSJohan Hedberg clear_bit(SMP_FLAG_INITIATOR, &smp->flags); 18523b19146dSJohan Hedberg 185319c5ce9cSJohan Hedberg /* Strictly speaking we shouldn't allow Pairing Confirm for the 185419c5ce9cSJohan Hedberg * SC case, however some implementations incorrectly copy RFU auth 185519c5ce9cSJohan Hedberg * req bits from our security request, which may create a false 185619c5ce9cSJohan Hedberg * positive SC enablement. 185719c5ce9cSJohan Hedberg */ 185819c5ce9cSJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); 185919c5ce9cSJohan Hedberg 18603b19146dSJohan Hedberg if (test_bit(SMP_FLAG_SC, &smp->flags)) { 18613b19146dSJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PUBLIC_KEY); 18623b19146dSJohan Hedberg /* Clear bits which are generated but not distributed */ 18633b19146dSJohan Hedberg smp->remote_key_dist &= ~SMP_SC_NO_DIST; 18643b19146dSJohan Hedberg /* Wait for Public Key from Initiating Device */ 18653b19146dSJohan Hedberg return 0; 18663b19146dSJohan Hedberg } 1867da85e5e5SVinicius Costa Gomes 18682b64d153SBrian Gix /* Request setup of TK */ 18692b64d153SBrian Gix ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability); 18702b64d153SBrian Gix if (ret) 18712b64d153SBrian Gix return SMP_UNSPECIFIED; 18722b64d153SBrian Gix 1873da85e5e5SVinicius Costa Gomes return 0; 187488ba43b6SAnderson Briglia } 187588ba43b6SAnderson Briglia 18763b19146dSJohan Hedberg static u8 sc_send_public_key(struct smp_chan *smp) 18773b19146dSJohan Hedberg { 187870157ef5SJohan Hedberg struct hci_dev *hdev = smp->conn->hcon->hdev; 187970157ef5SJohan Hedberg 188056860245SMarcel Holtmann bt_dev_dbg(hdev, ""); 18813b19146dSJohan Hedberg 18821a8bab4fSJohan Hedberg if (test_bit(SMP_FLAG_LOCAL_OOB, &smp->flags)) { 188333d0c030SMarcel Holtmann struct l2cap_chan *chan = hdev->smp_data; 188433d0c030SMarcel Holtmann struct smp_dev *smp_dev; 188533d0c030SMarcel Holtmann 188633d0c030SMarcel Holtmann if (!chan || !chan->data) 188733d0c030SMarcel Holtmann return SMP_UNSPECIFIED; 188833d0c030SMarcel Holtmann 188933d0c030SMarcel Holtmann smp_dev = chan->data; 189033d0c030SMarcel Holtmann 189133d0c030SMarcel Holtmann memcpy(smp->local_pk, smp_dev->local_pk, 64); 1892fb334feeSMarcel Holtmann memcpy(smp->lr, smp_dev->local_rand, 16); 189333d0c030SMarcel Holtmann 189433d0c030SMarcel Holtmann if (smp_dev->debug_key) 189533d0c030SMarcel Holtmann set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags); 189633d0c030SMarcel Holtmann 189733d0c030SMarcel Holtmann goto done; 189833d0c030SMarcel Holtmann } 189933d0c030SMarcel Holtmann 1900d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS)) { 19012e1614f7SLuiz Augusto von Dentz bt_dev_dbg(hdev, "Using debug keys"); 1902c0153b0bSTudor Ambarus if (set_ecdh_privkey(smp->tfm_ecdh, debug_sk)) 1903c0153b0bSTudor Ambarus return SMP_UNSPECIFIED; 190470157ef5SJohan Hedberg memcpy(smp->local_pk, debug_pk, 64); 190570157ef5SJohan Hedberg set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags); 190670157ef5SJohan Hedberg } else { 19076c0dcc50SJohan Hedberg while (true) { 1908c0153b0bSTudor Ambarus /* Generate key pair for Secure Connections */ 1909c0153b0bSTudor Ambarus if (generate_ecdh_keys(smp->tfm_ecdh, smp->local_pk)) 19103b19146dSJohan Hedberg return SMP_UNSPECIFIED; 19113b19146dSJohan Hedberg 191270157ef5SJohan Hedberg /* This is unlikely, but we need to check that 191391641b79SZheng Yongjun * we didn't accidentally generate a debug key. 19146c0dcc50SJohan Hedberg */ 1915c0153b0bSTudor Ambarus if (crypto_memneq(smp->local_pk, debug_pk, 64)) 19166c0dcc50SJohan Hedberg break; 19176c0dcc50SJohan Hedberg } 191870157ef5SJohan Hedberg } 19196c0dcc50SJohan Hedberg 192033d0c030SMarcel Holtmann done: 1921c7a3d57dSJohan Hedberg SMP_DBG("Local Public Key X: %32phN", smp->local_pk); 19228e4e2ee5SMarcel Holtmann SMP_DBG("Local Public Key Y: %32phN", smp->local_pk + 32); 19233b19146dSJohan Hedberg 19243b19146dSJohan Hedberg smp_send_cmd(smp->conn, SMP_CMD_PUBLIC_KEY, 64, smp->local_pk); 19253b19146dSJohan Hedberg 19263b19146dSJohan Hedberg return 0; 19273b19146dSJohan Hedberg } 19283b19146dSJohan Hedberg 1929da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) 193088ba43b6SAnderson Briglia { 19313158c50cSVinicius Costa Gomes struct smp_cmd_pairing *req, *rsp = (void *) skb->data; 19325d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 19335d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 19340edb14deSJohan Hedberg struct hci_dev *hdev = conn->hcon->hdev; 19353a7dbfb8SJohan Hedberg u8 key_size, auth; 19367d24ddccSAnderson Briglia int ret; 193788ba43b6SAnderson Briglia 19382e1614f7SLuiz Augusto von Dentz bt_dev_dbg(hdev, "conn %p", conn); 193988ba43b6SAnderson Briglia 1940c46b98beSJohan Hedberg if (skb->len < sizeof(*rsp)) 194138e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 1942c46b98beSJohan Hedberg 194340bef302SJohan Hedberg if (conn->hcon->role != HCI_ROLE_MASTER) 19442b64d153SBrian Gix return SMP_CMD_NOTSUPP; 19452b64d153SBrian Gix 19463158c50cSVinicius Costa Gomes skb_pull(skb, sizeof(*rsp)); 1947da85e5e5SVinicius Costa Gomes 19481c1def09SVinicius Costa Gomes req = (void *) &smp->preq[1]; 19493158c50cSVinicius Costa Gomes 19503158c50cSVinicius Costa Gomes key_size = min(req->max_key_size, rsp->max_key_size); 19513158c50cSVinicius Costa Gomes if (check_enc_key_size(conn, key_size)) 19523158c50cSVinicius Costa Gomes return SMP_ENC_KEY_SIZE; 19533158c50cSVinicius Costa Gomes 19540edb14deSJohan Hedberg auth = rsp->auth_req & AUTH_REQ_MASK(hdev); 1955c05b9339SJohan Hedberg 1956d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SC_ONLY) && !(auth & SMP_AUTH_SC)) 1957903b71c7SJohan Hedberg return SMP_AUTH_REQUIREMENTS; 1958903b71c7SJohan Hedberg 1959cb06d366SJohan Hedberg /* If the remote side's OOB flag is set it means it has 1960cb06d366SJohan Hedberg * successfully received our local OOB data - therefore set the 1961cb06d366SJohan Hedberg * flag to indicate that local OOB is in use. 1962cb06d366SJohan Hedberg */ 196394f14e47SJohan Hedberg if (rsp->oob_flag == SMP_OOB_PRESENT && SMP_DEV(hdev)->local_oob) 196458428563SJohan Hedberg set_bit(SMP_FLAG_LOCAL_OOB, &smp->flags); 196558428563SJohan Hedberg 1966b5ae344dSJohan Hedberg smp->prsp[0] = SMP_CMD_PAIRING_RSP; 1967b5ae344dSJohan Hedberg memcpy(&smp->prsp[1], rsp, sizeof(*rsp)); 1968b5ae344dSJohan Hedberg 1969b5ae344dSJohan Hedberg /* Update remote key distribution in case the remote cleared 1970b5ae344dSJohan Hedberg * some bits that we had enabled in our request. 1971b5ae344dSJohan Hedberg */ 1972b5ae344dSJohan Hedberg smp->remote_key_dist &= rsp->resp_key_dist; 1973b5ae344dSJohan Hedberg 1974a62da6f1SJohan Hedberg if ((req->auth_req & SMP_AUTH_CT2) && (auth & SMP_AUTH_CT2)) 1975a62da6f1SJohan Hedberg set_bit(SMP_FLAG_CT2, &smp->flags); 1976a62da6f1SJohan Hedberg 1977b5ae344dSJohan Hedberg /* For BR/EDR this means we're done and can start phase 3 */ 1978b5ae344dSJohan Hedberg if (conn->hcon->type == ACL_LINK) { 1979b5ae344dSJohan Hedberg /* Clear bits which are generated but not distributed */ 1980b5ae344dSJohan Hedberg smp->remote_key_dist &= ~SMP_SC_NO_DIST; 1981b5ae344dSJohan Hedberg smp_distribute_keys(smp); 1982b5ae344dSJohan Hedberg return 0; 1983b5ae344dSJohan Hedberg } 1984b5ae344dSJohan Hedberg 198565668776SJohan Hedberg if ((req->auth_req & SMP_AUTH_SC) && (auth & SMP_AUTH_SC)) 198665668776SJohan Hedberg set_bit(SMP_FLAG_SC, &smp->flags); 1987d2eb9e10SJohan Hedberg else if (conn->hcon->pending_sec_level > BT_SECURITY_HIGH) 1988d2eb9e10SJohan Hedberg conn->hcon->pending_sec_level = BT_SECURITY_HIGH; 198965668776SJohan Hedberg 199049c922bbSStephen Hemminger /* If we need MITM check that it can be achieved */ 19912ed8f65cSJohan Hedberg if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) { 19922ed8f65cSJohan Hedberg u8 method; 19932ed8f65cSJohan Hedberg 19942ed8f65cSJohan Hedberg method = get_auth_method(smp, req->io_capability, 19952ed8f65cSJohan Hedberg rsp->io_capability); 19962ed8f65cSJohan Hedberg if (method == JUST_WORKS || method == JUST_CFM) 19972ed8f65cSJohan Hedberg return SMP_AUTH_REQUIREMENTS; 19982ed8f65cSJohan Hedberg } 19992ed8f65cSJohan Hedberg 2000e84a6b13SJohan Hedberg get_random_bytes(smp->prnd, sizeof(smp->prnd)); 20017d24ddccSAnderson Briglia 2002fdcc4becSJohan Hedberg /* Update remote key distribution in case the remote cleared 2003fdcc4becSJohan Hedberg * some bits that we had enabled in our request. 2004fdcc4becSJohan Hedberg */ 2005fdcc4becSJohan Hedberg smp->remote_key_dist &= rsp->resp_key_dist; 2006fdcc4becSJohan Hedberg 20073b19146dSJohan Hedberg if (test_bit(SMP_FLAG_SC, &smp->flags)) { 20083b19146dSJohan Hedberg /* Clear bits which are generated but not distributed */ 20093b19146dSJohan Hedberg smp->remote_key_dist &= ~SMP_SC_NO_DIST; 20103b19146dSJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PUBLIC_KEY); 20113b19146dSJohan Hedberg return sc_send_public_key(smp); 20123b19146dSJohan Hedberg } 20133b19146dSJohan Hedberg 2014c05b9339SJohan Hedberg auth |= req->auth_req; 20152b64d153SBrian Gix 2016476585ecSJohan Hedberg ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability); 20172b64d153SBrian Gix if (ret) 20182b64d153SBrian Gix return SMP_UNSPECIFIED; 20192b64d153SBrian Gix 20204a74d658SJohan Hedberg set_bit(SMP_FLAG_CFM_PENDING, &smp->flags); 20212b64d153SBrian Gix 20222b64d153SBrian Gix /* Can't compose response until we have been confirmed */ 20234a74d658SJohan Hedberg if (test_bit(SMP_FLAG_TK_VALID, &smp->flags)) 20241cc61144SJohan Hedberg return smp_confirm(smp); 2025da85e5e5SVinicius Costa Gomes 2026da85e5e5SVinicius Costa Gomes return 0; 202788ba43b6SAnderson Briglia } 202888ba43b6SAnderson Briglia 2029dcee2b32SJohan Hedberg static u8 sc_check_confirm(struct smp_chan *smp) 2030dcee2b32SJohan Hedberg { 2031dcee2b32SJohan Hedberg struct l2cap_conn *conn = smp->conn; 2032dcee2b32SJohan Hedberg 20332e1614f7SLuiz Augusto von Dentz bt_dev_dbg(conn->hcon->hdev, ""); 2034dcee2b32SJohan Hedberg 203538606f14SJohan Hedberg if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY) 203638606f14SJohan Hedberg return sc_passkey_round(smp, SMP_CMD_PAIRING_CONFIRM); 203738606f14SJohan Hedberg 2038dcee2b32SJohan Hedberg if (conn->hcon->out) { 2039dcee2b32SJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd), 2040dcee2b32SJohan Hedberg smp->prnd); 2041dcee2b32SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM); 2042dcee2b32SJohan Hedberg } 2043dcee2b32SJohan Hedberg 2044dcee2b32SJohan Hedberg return 0; 2045dcee2b32SJohan Hedberg } 2046dcee2b32SJohan Hedberg 204719c5ce9cSJohan Hedberg /* Work-around for some implementations that incorrectly copy RFU bits 204819c5ce9cSJohan Hedberg * from our security request and thereby create the impression that 204919c5ce9cSJohan Hedberg * we're doing SC when in fact the remote doesn't support it. 205019c5ce9cSJohan Hedberg */ 205119c5ce9cSJohan Hedberg static int fixup_sc_false_positive(struct smp_chan *smp) 205219c5ce9cSJohan Hedberg { 205319c5ce9cSJohan Hedberg struct l2cap_conn *conn = smp->conn; 205419c5ce9cSJohan Hedberg struct hci_conn *hcon = conn->hcon; 205519c5ce9cSJohan Hedberg struct hci_dev *hdev = hcon->hdev; 205619c5ce9cSJohan Hedberg struct smp_cmd_pairing *req, *rsp; 205719c5ce9cSJohan Hedberg u8 auth; 205819c5ce9cSJohan Hedberg 2059fad646e1SArchie Pusaka /* The issue is only observed when we're in responder role */ 206019c5ce9cSJohan Hedberg if (hcon->out) 206119c5ce9cSJohan Hedberg return SMP_UNSPECIFIED; 206219c5ce9cSJohan Hedberg 206319c5ce9cSJohan Hedberg if (hci_dev_test_flag(hdev, HCI_SC_ONLY)) { 20642064ee33SMarcel Holtmann bt_dev_err(hdev, "refusing legacy fallback in SC-only mode"); 206519c5ce9cSJohan Hedberg return SMP_UNSPECIFIED; 206619c5ce9cSJohan Hedberg } 206719c5ce9cSJohan Hedberg 20682064ee33SMarcel Holtmann bt_dev_err(hdev, "trying to fall back to legacy SMP"); 206919c5ce9cSJohan Hedberg 207019c5ce9cSJohan Hedberg req = (void *) &smp->preq[1]; 207119c5ce9cSJohan Hedberg rsp = (void *) &smp->prsp[1]; 207219c5ce9cSJohan Hedberg 207319c5ce9cSJohan Hedberg /* Rebuild key dist flags which may have been cleared for SC */ 207419c5ce9cSJohan Hedberg smp->remote_key_dist = (req->init_key_dist & rsp->resp_key_dist); 207519c5ce9cSJohan Hedberg 207619c5ce9cSJohan Hedberg auth = req->auth_req & AUTH_REQ_MASK(hdev); 207719c5ce9cSJohan Hedberg 207819c5ce9cSJohan Hedberg if (tk_request(conn, 0, auth, rsp->io_capability, req->io_capability)) { 20792064ee33SMarcel Holtmann bt_dev_err(hdev, "failed to fall back to legacy SMP"); 208019c5ce9cSJohan Hedberg return SMP_UNSPECIFIED; 208119c5ce9cSJohan Hedberg } 208219c5ce9cSJohan Hedberg 208319c5ce9cSJohan Hedberg clear_bit(SMP_FLAG_SC, &smp->flags); 208419c5ce9cSJohan Hedberg 208519c5ce9cSJohan Hedberg return 0; 208619c5ce9cSJohan Hedberg } 208719c5ce9cSJohan Hedberg 2088da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb) 208988ba43b6SAnderson Briglia { 20905d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 20915d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 20922e1614f7SLuiz Augusto von Dentz struct hci_conn *hcon = conn->hcon; 20932e1614f7SLuiz Augusto von Dentz struct hci_dev *hdev = hcon->hdev; 20947d24ddccSAnderson Briglia 2095fad646e1SArchie Pusaka bt_dev_dbg(hdev, "conn %p %s", conn, 2096fad646e1SArchie Pusaka hcon->out ? "initiator" : "responder"); 209788ba43b6SAnderson Briglia 2098c46b98beSJohan Hedberg if (skb->len < sizeof(smp->pcnf)) 209938e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 2100c46b98beSJohan Hedberg 21011c1def09SVinicius Costa Gomes memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf)); 21021c1def09SVinicius Costa Gomes skb_pull(skb, sizeof(smp->pcnf)); 21037d24ddccSAnderson Briglia 210419c5ce9cSJohan Hedberg if (test_bit(SMP_FLAG_SC, &smp->flags)) { 210519c5ce9cSJohan Hedberg int ret; 210619c5ce9cSJohan Hedberg 210719c5ce9cSJohan Hedberg /* Public Key exchange must happen before any other steps */ 210819c5ce9cSJohan Hedberg if (test_bit(SMP_FLAG_REMOTE_PK, &smp->flags)) 2109dcee2b32SJohan Hedberg return sc_check_confirm(smp); 2110dcee2b32SJohan Hedberg 21112e1614f7SLuiz Augusto von Dentz bt_dev_err(hdev, "Unexpected SMP Pairing Confirm"); 211219c5ce9cSJohan Hedberg 211319c5ce9cSJohan Hedberg ret = fixup_sc_false_positive(smp); 211419c5ce9cSJohan Hedberg if (ret) 211519c5ce9cSJohan Hedberg return ret; 211619c5ce9cSJohan Hedberg } 211719c5ce9cSJohan Hedberg 2118b28b4943SJohan Hedberg if (conn->hcon->out) { 2119943a732aSJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd), 2120943a732aSJohan Hedberg smp->prnd); 2121b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM); 2122b28b4943SJohan Hedberg return 0; 2123b28b4943SJohan Hedberg } 2124b28b4943SJohan Hedberg 2125b28b4943SJohan Hedberg if (test_bit(SMP_FLAG_TK_VALID, &smp->flags)) 21261cc61144SJohan Hedberg return smp_confirm(smp); 2127983f9814SMarcel Holtmann 21284a74d658SJohan Hedberg set_bit(SMP_FLAG_CFM_PENDING, &smp->flags); 2129da85e5e5SVinicius Costa Gomes 2130da85e5e5SVinicius Costa Gomes return 0; 213188ba43b6SAnderson Briglia } 213288ba43b6SAnderson Briglia 2133da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) 213488ba43b6SAnderson Briglia { 21355d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 21365d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 2137191dc7feSJohan Hedberg struct hci_conn *hcon = conn->hcon; 2138eed467b5SHoward Chung u8 *pkax, *pkbx, *na, *nb, confirm_hint; 2139191dc7feSJohan Hedberg u32 passkey; 2140191dc7feSJohan Hedberg int err; 21417d24ddccSAnderson Briglia 21422e1614f7SLuiz Augusto von Dentz bt_dev_dbg(hcon->hdev, "conn %p", conn); 21437d24ddccSAnderson Briglia 2144c46b98beSJohan Hedberg if (skb->len < sizeof(smp->rrnd)) 214538e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 2146c46b98beSJohan Hedberg 2147943a732aSJohan Hedberg memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd)); 21488aab4757SVinicius Costa Gomes skb_pull(skb, sizeof(smp->rrnd)); 214988ba43b6SAnderson Briglia 2150191dc7feSJohan Hedberg if (!test_bit(SMP_FLAG_SC, &smp->flags)) 2151861580a9SJohan Hedberg return smp_random(smp); 2152191dc7feSJohan Hedberg 2153580039e8SJohan Hedberg if (hcon->out) { 2154580039e8SJohan Hedberg pkax = smp->local_pk; 2155580039e8SJohan Hedberg pkbx = smp->remote_pk; 2156580039e8SJohan Hedberg na = smp->prnd; 2157580039e8SJohan Hedberg nb = smp->rrnd; 2158580039e8SJohan Hedberg } else { 2159580039e8SJohan Hedberg pkax = smp->remote_pk; 2160580039e8SJohan Hedberg pkbx = smp->local_pk; 2161580039e8SJohan Hedberg na = smp->rrnd; 2162580039e8SJohan Hedberg nb = smp->prnd; 2163580039e8SJohan Hedberg } 2164580039e8SJohan Hedberg 2165a29b0733SJohan Hedberg if (smp->method == REQ_OOB) { 2166a29b0733SJohan Hedberg if (!hcon->out) 2167a29b0733SJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, 2168a29b0733SJohan Hedberg sizeof(smp->prnd), smp->prnd); 2169a29b0733SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK); 2170a29b0733SJohan Hedberg goto mackey_and_ltk; 2171a29b0733SJohan Hedberg } 2172a29b0733SJohan Hedberg 217338606f14SJohan Hedberg /* Passkey entry has special treatment */ 217438606f14SJohan Hedberg if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY) 217538606f14SJohan Hedberg return sc_passkey_round(smp, SMP_CMD_PAIRING_RANDOM); 217638606f14SJohan Hedberg 2177191dc7feSJohan Hedberg if (hcon->out) { 2178191dc7feSJohan Hedberg u8 cfm[16]; 2179191dc7feSJohan Hedberg 2180191dc7feSJohan Hedberg err = smp_f4(smp->tfm_cmac, smp->remote_pk, smp->local_pk, 2181191dc7feSJohan Hedberg smp->rrnd, 0, cfm); 2182191dc7feSJohan Hedberg if (err) 2183191dc7feSJohan Hedberg return SMP_UNSPECIFIED; 2184191dc7feSJohan Hedberg 2185329d8230SJason A. Donenfeld if (crypto_memneq(smp->pcnf, cfm, 16)) 2186191dc7feSJohan Hedberg return SMP_CONFIRM_FAILED; 2187191dc7feSJohan Hedberg } else { 2188191dc7feSJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd), 2189191dc7feSJohan Hedberg smp->prnd); 2190191dc7feSJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK); 2191cee5f20fSHoward Chung 2192cee5f20fSHoward Chung /* Only Just-Works pairing requires extra checks */ 2193cee5f20fSHoward Chung if (smp->method != JUST_WORKS) 2194cee5f20fSHoward Chung goto mackey_and_ltk; 2195cee5f20fSHoward Chung 2196cee5f20fSHoward Chung /* If there already exists long term key in local host, leave 2197cee5f20fSHoward Chung * the decision to user space since the remote device could 2198cee5f20fSHoward Chung * be legitimate or malicious. 2199cee5f20fSHoward Chung */ 2200cee5f20fSHoward Chung if (hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, 2201cee5f20fSHoward Chung hcon->role)) { 2202eed467b5SHoward Chung /* Set passkey to 0. The value can be any number since 2203eed467b5SHoward Chung * it'll be ignored anyway. 2204eed467b5SHoward Chung */ 2205eed467b5SHoward Chung passkey = 0; 2206eed467b5SHoward Chung confirm_hint = 1; 2207eed467b5SHoward Chung goto confirm; 2208cee5f20fSHoward Chung } 2209191dc7feSJohan Hedberg } 2210191dc7feSJohan Hedberg 2211a29b0733SJohan Hedberg mackey_and_ltk: 2212760b018bSJohan Hedberg /* Generate MacKey and LTK */ 2213760b018bSJohan Hedberg err = sc_mackey_and_ltk(smp, smp->mackey, smp->tk); 2214760b018bSJohan Hedberg if (err) 2215760b018bSJohan Hedberg return SMP_UNSPECIFIED; 2216760b018bSJohan Hedberg 2217ffee202aSSonny Sasaka if (smp->method == REQ_OOB) { 2218dddd3059SJohan Hedberg if (hcon->out) { 221938606f14SJohan Hedberg sc_dhkey_check(smp); 2220dddd3059SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK); 2221dddd3059SJohan Hedberg } 2222dddd3059SJohan Hedberg return 0; 2223dddd3059SJohan Hedberg } 2224dddd3059SJohan Hedberg 222538606f14SJohan Hedberg err = smp_g2(smp->tfm_cmac, pkax, pkbx, na, nb, &passkey); 2226191dc7feSJohan Hedberg if (err) 2227191dc7feSJohan Hedberg return SMP_UNSPECIFIED; 2228191dc7feSJohan Hedberg 2229eed467b5SHoward Chung confirm_hint = 0; 2230eed467b5SHoward Chung 2231eed467b5SHoward Chung confirm: 2232ffee202aSSonny Sasaka if (smp->method == JUST_WORKS) 2233ffee202aSSonny Sasaka confirm_hint = 1; 2234ffee202aSSonny Sasaka 223538606f14SJohan Hedberg err = mgmt_user_confirm_request(hcon->hdev, &hcon->dst, hcon->type, 2236eed467b5SHoward Chung hcon->dst_type, passkey, confirm_hint); 223738606f14SJohan Hedberg if (err) 223838606f14SJohan Hedberg return SMP_UNSPECIFIED; 223938606f14SJohan Hedberg 224038606f14SJohan Hedberg set_bit(SMP_FLAG_WAIT_USER, &smp->flags); 224138606f14SJohan Hedberg 2242191dc7feSJohan Hedberg return 0; 224388ba43b6SAnderson Briglia } 224488ba43b6SAnderson Briglia 2245f81cd823SMarcel Holtmann static bool smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level) 2246988c5997SVinicius Costa Gomes { 2247c9839a11SVinicius Costa Gomes struct smp_ltk *key; 2248988c5997SVinicius Costa Gomes struct hci_conn *hcon = conn->hcon; 2249988c5997SVinicius Costa Gomes 2250f3a73d97SJohan Hedberg key = hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, hcon->role); 2251988c5997SVinicius Costa Gomes if (!key) 2252f81cd823SMarcel Holtmann return false; 2253988c5997SVinicius Costa Gomes 2254a6f7833cSJohan Hedberg if (smp_ltk_sec_level(key) < sec_level) 2255f81cd823SMarcel Holtmann return false; 22564dab7864SJohan Hedberg 225751a8efd7SJohan Hedberg if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags)) 2258f81cd823SMarcel Holtmann return true; 2259988c5997SVinicius Costa Gomes 22608b76ce34SJohan Hedberg hci_le_start_enc(hcon, key->ediv, key->rand, key->val, key->enc_size); 2261c9839a11SVinicius Costa Gomes hcon->enc_key_size = key->enc_size; 2262988c5997SVinicius Costa Gomes 2263fad646e1SArchie Pusaka /* We never store STKs for initiator role, so clear this flag */ 2264fe59a05fSJohan Hedberg clear_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags); 2265fe59a05fSJohan Hedberg 2266f81cd823SMarcel Holtmann return true; 2267988c5997SVinicius Costa Gomes } 2268f1560463SMarcel Holtmann 226935dc6f83SJohan Hedberg bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level, 227035dc6f83SJohan Hedberg enum smp_key_pref key_pref) 2271854f4727SJohan Hedberg { 2272854f4727SJohan Hedberg if (sec_level == BT_SECURITY_LOW) 2273854f4727SJohan Hedberg return true; 2274854f4727SJohan Hedberg 227535dc6f83SJohan Hedberg /* If we're encrypted with an STK but the caller prefers using 227635dc6f83SJohan Hedberg * LTK claim insufficient security. This way we allow the 227735dc6f83SJohan Hedberg * connection to be re-encrypted with an LTK, even if the LTK 227835dc6f83SJohan Hedberg * provides the same level of security. Only exception is if we 227935dc6f83SJohan Hedberg * don't have an LTK (e.g. because of key distribution bits). 22809ab65d60SJohan Hedberg */ 228135dc6f83SJohan Hedberg if (key_pref == SMP_USE_LTK && 228235dc6f83SJohan Hedberg test_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags) && 2283f3a73d97SJohan Hedberg hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, hcon->role)) 22849ab65d60SJohan Hedberg return false; 22859ab65d60SJohan Hedberg 2286854f4727SJohan Hedberg if (hcon->sec_level >= sec_level) 2287854f4727SJohan Hedberg return true; 2288854f4727SJohan Hedberg 2289854f4727SJohan Hedberg return false; 2290854f4727SJohan Hedberg } 2291854f4727SJohan Hedberg 2292da85e5e5SVinicius Costa Gomes static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) 229388ba43b6SAnderson Briglia { 229488ba43b6SAnderson Briglia struct smp_cmd_security_req *rp = (void *) skb->data; 229588ba43b6SAnderson Briglia struct smp_cmd_pairing cp; 2296f1cb9af5SVinicius Costa Gomes struct hci_conn *hcon = conn->hcon; 22970edb14deSJohan Hedberg struct hci_dev *hdev = hcon->hdev; 22988aab4757SVinicius Costa Gomes struct smp_chan *smp; 2299c05b9339SJohan Hedberg u8 sec_level, auth; 230088ba43b6SAnderson Briglia 23012e1614f7SLuiz Augusto von Dentz bt_dev_dbg(hdev, "conn %p", conn); 230288ba43b6SAnderson Briglia 2303c46b98beSJohan Hedberg if (skb->len < sizeof(*rp)) 230438e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 2305c46b98beSJohan Hedberg 230640bef302SJohan Hedberg if (hcon->role != HCI_ROLE_MASTER) 230786ca9eacSJohan Hedberg return SMP_CMD_NOTSUPP; 230886ca9eacSJohan Hedberg 23090edb14deSJohan Hedberg auth = rp->auth_req & AUTH_REQ_MASK(hdev); 2310c05b9339SJohan Hedberg 2311d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SC_ONLY) && !(auth & SMP_AUTH_SC)) 2312903b71c7SJohan Hedberg return SMP_AUTH_REQUIREMENTS; 2313903b71c7SJohan Hedberg 23145be5e275SJohan Hedberg if (hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT) 23151afc2a1aSJohan Hedberg sec_level = BT_SECURITY_MEDIUM; 23161afc2a1aSJohan Hedberg else 2317c05b9339SJohan Hedberg sec_level = authreq_to_seclevel(auth); 23181afc2a1aSJohan Hedberg 231964e759f5SSzymon Janc if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK)) { 232064e759f5SSzymon Janc /* If link is already encrypted with sufficient security we 232164e759f5SSzymon Janc * still need refresh encryption as per Core Spec 5.0 Vol 3, 232264e759f5SSzymon Janc * Part H 2.4.6 232364e759f5SSzymon Janc */ 232464e759f5SSzymon Janc smp_ltk_encrypt(conn, hcon->sec_level); 2325854f4727SJohan Hedberg return 0; 232664e759f5SSzymon Janc } 2327854f4727SJohan Hedberg 2328c7262e71SJohan Hedberg if (sec_level > hcon->pending_sec_level) 2329c7262e71SJohan Hedberg hcon->pending_sec_level = sec_level; 2330feb45eb5SVinicius Costa Gomes 23314dab7864SJohan Hedberg if (smp_ltk_encrypt(conn, hcon->pending_sec_level)) 2332988c5997SVinicius Costa Gomes return 0; 2333988c5997SVinicius Costa Gomes 23348aab4757SVinicius Costa Gomes smp = smp_chan_create(conn); 2335c29d2444SJohan Hedberg if (!smp) 2336c29d2444SJohan Hedberg return SMP_UNSPECIFIED; 2337d26a2345SVinicius Costa Gomes 2338d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_BONDABLE) && 2339c05b9339SJohan Hedberg (auth & SMP_AUTH_BONDING)) 2340616d55beSJohan Hedberg return SMP_PAIRING_NOTSUPP; 2341616d55beSJohan Hedberg 234288ba43b6SAnderson Briglia skb_pull(skb, sizeof(*rp)); 234388ba43b6SAnderson Briglia 2344da85e5e5SVinicius Costa Gomes memset(&cp, 0, sizeof(cp)); 2345c05b9339SJohan Hedberg build_pairing_cmd(conn, &cp, NULL, auth); 234688ba43b6SAnderson Briglia 23471c1def09SVinicius Costa Gomes smp->preq[0] = SMP_CMD_PAIRING_REQ; 23481c1def09SVinicius Costa Gomes memcpy(&smp->preq[1], &cp, sizeof(cp)); 2349f01ead31SAnderson Briglia 235088ba43b6SAnderson Briglia smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp); 2351b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP); 2352f1cb9af5SVinicius Costa Gomes 2353da85e5e5SVinicius Costa Gomes return 0; 235488ba43b6SAnderson Briglia } 235588ba43b6SAnderson Briglia 2356cc110922SVinicius Costa Gomes int smp_conn_security(struct hci_conn *hcon, __u8 sec_level) 2357eb492e01SAnderson Briglia { 2358cc110922SVinicius Costa Gomes struct l2cap_conn *conn = hcon->l2cap_data; 2359c68b7f12SJohan Hedberg struct l2cap_chan *chan; 23600a66cf20SJohan Hedberg struct smp_chan *smp; 23612b64d153SBrian Gix __u8 authreq; 2362fc75cc86SJohan Hedberg int ret; 2363eb492e01SAnderson Briglia 23642e1614f7SLuiz Augusto von Dentz bt_dev_dbg(hcon->hdev, "conn %p hcon %p level 0x%2.2x", conn, hcon, 23652e1614f7SLuiz Augusto von Dentz sec_level); 23663a0259bbSVinicius Costa Gomes 23670a66cf20SJohan Hedberg /* This may be NULL if there's an unexpected disconnection */ 23680a66cf20SJohan Hedberg if (!conn) 23690a66cf20SJohan Hedberg return 1; 23700a66cf20SJohan Hedberg 2371d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hcon->hdev, HCI_LE_ENABLED)) 23722e65c9d2SAndre Guedes return 1; 23732e65c9d2SAndre Guedes 237435dc6f83SJohan Hedberg if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK)) 2375f1cb9af5SVinicius Costa Gomes return 1; 2376f1cb9af5SVinicius Costa Gomes 2377c7262e71SJohan Hedberg if (sec_level > hcon->pending_sec_level) 2378c7262e71SJohan Hedberg hcon->pending_sec_level = sec_level; 2379c7262e71SJohan Hedberg 238040bef302SJohan Hedberg if (hcon->role == HCI_ROLE_MASTER) 2381c7262e71SJohan Hedberg if (smp_ltk_encrypt(conn, hcon->pending_sec_level)) 2382c7262e71SJohan Hedberg return 0; 2383d26a2345SVinicius Costa Gomes 2384d8949aadSJohan Hedberg chan = conn->smp; 2385d8949aadSJohan Hedberg if (!chan) { 23862064ee33SMarcel Holtmann bt_dev_err(hcon->hdev, "security requested but not available"); 2387d8949aadSJohan Hedberg return 1; 2388d8949aadSJohan Hedberg } 2389d8949aadSJohan Hedberg 2390fc75cc86SJohan Hedberg l2cap_chan_lock(chan); 2391fc75cc86SJohan Hedberg 2392fc75cc86SJohan Hedberg /* If SMP is already in progress ignore this request */ 2393fc75cc86SJohan Hedberg if (chan->data) { 2394fc75cc86SJohan Hedberg ret = 0; 2395fc75cc86SJohan Hedberg goto unlock; 2396fc75cc86SJohan Hedberg } 2397d26a2345SVinicius Costa Gomes 23988aab4757SVinicius Costa Gomes smp = smp_chan_create(conn); 2399fc75cc86SJohan Hedberg if (!smp) { 2400fc75cc86SJohan Hedberg ret = 1; 2401fc75cc86SJohan Hedberg goto unlock; 2402fc75cc86SJohan Hedberg } 24032b64d153SBrian Gix 24042b64d153SBrian Gix authreq = seclevel_to_authreq(sec_level); 2405d26a2345SVinicius Costa Gomes 2406a62da6f1SJohan Hedberg if (hci_dev_test_flag(hcon->hdev, HCI_SC_ENABLED)) { 2407d2eb9e10SJohan Hedberg authreq |= SMP_AUTH_SC; 2408a62da6f1SJohan Hedberg if (hci_dev_test_flag(hcon->hdev, HCI_SSP_ENABLED)) 2409a62da6f1SJohan Hedberg authreq |= SMP_AUTH_CT2; 2410a62da6f1SJohan Hedberg } 2411d2eb9e10SJohan Hedberg 2412c2aa30dbSArchie Pusaka /* Don't attempt to set MITM if setting is overridden by debugfs 2413c2aa30dbSArchie Pusaka * Needed to pass certification test SM/MAS/PKE/BV-01-C 2414c2aa30dbSArchie Pusaka */ 2415c2aa30dbSArchie Pusaka if (!hci_dev_test_flag(hcon->hdev, HCI_FORCE_NO_MITM)) { 241679897d20SJohan Hedberg /* Require MITM if IO Capability allows or the security level 241779897d20SJohan Hedberg * requires it. 24182e233644SJohan Hedberg */ 241979897d20SJohan Hedberg if (hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT || 2420c7262e71SJohan Hedberg hcon->pending_sec_level > BT_SECURITY_MEDIUM) 24212e233644SJohan Hedberg authreq |= SMP_AUTH_MITM; 2422c2aa30dbSArchie Pusaka } 24232e233644SJohan Hedberg 242440bef302SJohan Hedberg if (hcon->role == HCI_ROLE_MASTER) { 2425d26a2345SVinicius Costa Gomes struct smp_cmd_pairing cp; 2426f01ead31SAnderson Briglia 24272b64d153SBrian Gix build_pairing_cmd(conn, &cp, NULL, authreq); 24281c1def09SVinicius Costa Gomes smp->preq[0] = SMP_CMD_PAIRING_REQ; 24291c1def09SVinicius Costa Gomes memcpy(&smp->preq[1], &cp, sizeof(cp)); 2430f01ead31SAnderson Briglia 2431eb492e01SAnderson Briglia smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp); 2432b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP); 2433eb492e01SAnderson Briglia } else { 2434eb492e01SAnderson Briglia struct smp_cmd_security_req cp; 24352b64d153SBrian Gix cp.auth_req = authreq; 2436eb492e01SAnderson Briglia smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp); 2437b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_REQ); 2438eb492e01SAnderson Briglia } 2439eb492e01SAnderson Briglia 24404a74d658SJohan Hedberg set_bit(SMP_FLAG_INITIATOR, &smp->flags); 2441fc75cc86SJohan Hedberg ret = 0; 2442edca792cSJohan Hedberg 2443fc75cc86SJohan Hedberg unlock: 2444fc75cc86SJohan Hedberg l2cap_chan_unlock(chan); 2445fc75cc86SJohan Hedberg return ret; 2446eb492e01SAnderson Briglia } 2447eb492e01SAnderson Briglia 2448cb28c306SMatias Karhumaa int smp_cancel_and_remove_pairing(struct hci_dev *hdev, bdaddr_t *bdaddr, 2449cb28c306SMatias Karhumaa u8 addr_type) 2450c81d555aSJohan Hedberg { 2451cb28c306SMatias Karhumaa struct hci_conn *hcon; 2452cb28c306SMatias Karhumaa struct l2cap_conn *conn; 2453c81d555aSJohan Hedberg struct l2cap_chan *chan; 2454c81d555aSJohan Hedberg struct smp_chan *smp; 2455cb28c306SMatias Karhumaa int err; 2456c81d555aSJohan Hedberg 2457cb28c306SMatias Karhumaa err = hci_remove_ltk(hdev, bdaddr, addr_type); 2458cb28c306SMatias Karhumaa hci_remove_irk(hdev, bdaddr, addr_type); 2459cb28c306SMatias Karhumaa 2460cb28c306SMatias Karhumaa hcon = hci_conn_hash_lookup_le(hdev, bdaddr, addr_type); 2461cb28c306SMatias Karhumaa if (!hcon) 2462cb28c306SMatias Karhumaa goto done; 2463cb28c306SMatias Karhumaa 2464cb28c306SMatias Karhumaa conn = hcon->l2cap_data; 2465c81d555aSJohan Hedberg if (!conn) 2466cb28c306SMatias Karhumaa goto done; 2467c81d555aSJohan Hedberg 2468c81d555aSJohan Hedberg chan = conn->smp; 2469c81d555aSJohan Hedberg if (!chan) 2470cb28c306SMatias Karhumaa goto done; 2471c81d555aSJohan Hedberg 2472c81d555aSJohan Hedberg l2cap_chan_lock(chan); 2473c81d555aSJohan Hedberg 2474c81d555aSJohan Hedberg smp = chan->data; 2475c81d555aSJohan Hedberg if (smp) { 2476cb28c306SMatias Karhumaa /* Set keys to NULL to make sure smp_failure() does not try to 2477cb28c306SMatias Karhumaa * remove and free already invalidated rcu list entries. */ 2478cb28c306SMatias Karhumaa smp->ltk = NULL; 2479fad646e1SArchie Pusaka smp->responder_ltk = NULL; 2480cb28c306SMatias Karhumaa smp->remote_irk = NULL; 2481cb28c306SMatias Karhumaa 2482c81d555aSJohan Hedberg if (test_bit(SMP_FLAG_COMPLETE, &smp->flags)) 2483c81d555aSJohan Hedberg smp_failure(conn, 0); 2484c81d555aSJohan Hedberg else 2485c81d555aSJohan Hedberg smp_failure(conn, SMP_UNSPECIFIED); 2486cb28c306SMatias Karhumaa err = 0; 2487c81d555aSJohan Hedberg } 2488c81d555aSJohan Hedberg 2489c81d555aSJohan Hedberg l2cap_chan_unlock(chan); 2490cb28c306SMatias Karhumaa 2491cb28c306SMatias Karhumaa done: 2492cb28c306SMatias Karhumaa return err; 2493c81d555aSJohan Hedberg } 2494c81d555aSJohan Hedberg 24957034b911SVinicius Costa Gomes static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb) 24967034b911SVinicius Costa Gomes { 249716b90839SVinicius Costa Gomes struct smp_cmd_encrypt_info *rp = (void *) skb->data; 24985d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 24995d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 250016b90839SVinicius Costa Gomes 25012e1614f7SLuiz Augusto von Dentz bt_dev_dbg(conn->hcon->hdev, "conn %p", conn); 2502c46b98beSJohan Hedberg 2503c46b98beSJohan Hedberg if (skb->len < sizeof(*rp)) 250438e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 2505c46b98beSJohan Hedberg 2506600a8749SAlain Michaud /* Pairing is aborted if any blocked keys are distributed */ 2507600a8749SAlain Michaud if (hci_is_blocked_key(conn->hcon->hdev, HCI_BLOCKED_KEY_TYPE_LTK, 2508600a8749SAlain Michaud rp->ltk)) { 2509600a8749SAlain Michaud bt_dev_warn_ratelimited(conn->hcon->hdev, 2510600a8749SAlain Michaud "LTK blocked for %pMR", 2511600a8749SAlain Michaud &conn->hcon->dst); 2512600a8749SAlain Michaud return SMP_INVALID_PARAMS; 2513600a8749SAlain Michaud } 2514600a8749SAlain Michaud 2515fad646e1SArchie Pusaka SMP_ALLOW_CMD(smp, SMP_CMD_INITIATOR_IDENT); 25166131ddc8SJohan Hedberg 251716b90839SVinicius Costa Gomes skb_pull(skb, sizeof(*rp)); 251816b90839SVinicius Costa Gomes 25191c1def09SVinicius Costa Gomes memcpy(smp->tk, rp->ltk, sizeof(smp->tk)); 252016b90839SVinicius Costa Gomes 25217034b911SVinicius Costa Gomes return 0; 25227034b911SVinicius Costa Gomes } 25237034b911SVinicius Costa Gomes 2524fad646e1SArchie Pusaka static int smp_cmd_initiator_ident(struct l2cap_conn *conn, struct sk_buff *skb) 25257034b911SVinicius Costa Gomes { 2526fad646e1SArchie Pusaka struct smp_cmd_initiator_ident *rp = (void *)skb->data; 25275d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 25285d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 2529c9839a11SVinicius Costa Gomes struct hci_dev *hdev = conn->hcon->hdev; 2530c9839a11SVinicius Costa Gomes struct hci_conn *hcon = conn->hcon; 253123d0e128SJohan Hedberg struct smp_ltk *ltk; 2532c9839a11SVinicius Costa Gomes u8 authenticated; 25337034b911SVinicius Costa Gomes 25342e1614f7SLuiz Augusto von Dentz bt_dev_dbg(hdev, "conn %p", conn); 2535c46b98beSJohan Hedberg 2536c46b98beSJohan Hedberg if (skb->len < sizeof(*rp)) 253738e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 2538c46b98beSJohan Hedberg 25399747a9f3SJohan Hedberg /* Mark the information as received */ 25409747a9f3SJohan Hedberg smp->remote_key_dist &= ~SMP_DIST_ENC_KEY; 25419747a9f3SJohan Hedberg 2542b28b4943SJohan Hedberg if (smp->remote_key_dist & SMP_DIST_ID_KEY) 2543b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO); 2544196332f5SJohan Hedberg else if (smp->remote_key_dist & SMP_DIST_SIGN) 2545196332f5SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO); 2546b28b4943SJohan Hedberg 254716b90839SVinicius Costa Gomes skb_pull(skb, sizeof(*rp)); 254816b90839SVinicius Costa Gomes 2549ce39fb4eSMarcel Holtmann authenticated = (hcon->sec_level == BT_SECURITY_HIGH); 25502ceba539SJohan Hedberg ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, SMP_LTK, 2551ce39fb4eSMarcel Holtmann authenticated, smp->tk, smp->enc_key_size, 255204124681SGustavo F. Padovan rp->ediv, rp->rand); 255323d0e128SJohan Hedberg smp->ltk = ltk; 2554c6e81e9aSJohan Hedberg if (!(smp->remote_key_dist & KEY_DIST_MASK)) 2555d6268e86SJohan Hedberg smp_distribute_keys(smp); 25567034b911SVinicius Costa Gomes 25577034b911SVinicius Costa Gomes return 0; 25587034b911SVinicius Costa Gomes } 25597034b911SVinicius Costa Gomes 2560fd349c02SJohan Hedberg static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb) 2561fd349c02SJohan Hedberg { 2562fd349c02SJohan Hedberg struct smp_cmd_ident_info *info = (void *) skb->data; 25635d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 25645d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 2565fd349c02SJohan Hedberg 25662e1614f7SLuiz Augusto von Dentz bt_dev_dbg(conn->hcon->hdev, ""); 2567fd349c02SJohan Hedberg 2568fd349c02SJohan Hedberg if (skb->len < sizeof(*info)) 256938e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 2570fd349c02SJohan Hedberg 2571600a8749SAlain Michaud /* Pairing is aborted if any blocked keys are distributed */ 2572600a8749SAlain Michaud if (hci_is_blocked_key(conn->hcon->hdev, HCI_BLOCKED_KEY_TYPE_IRK, 2573600a8749SAlain Michaud info->irk)) { 2574600a8749SAlain Michaud bt_dev_warn_ratelimited(conn->hcon->hdev, 2575600a8749SAlain Michaud "Identity key blocked for %pMR", 2576600a8749SAlain Michaud &conn->hcon->dst); 2577600a8749SAlain Michaud return SMP_INVALID_PARAMS; 2578600a8749SAlain Michaud } 2579600a8749SAlain Michaud 2580b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_ADDR_INFO); 25816131ddc8SJohan Hedberg 2582fd349c02SJohan Hedberg skb_pull(skb, sizeof(*info)); 2583fd349c02SJohan Hedberg 2584fd349c02SJohan Hedberg memcpy(smp->irk, info->irk, 16); 2585fd349c02SJohan Hedberg 2586fd349c02SJohan Hedberg return 0; 2587fd349c02SJohan Hedberg } 2588fd349c02SJohan Hedberg 2589fd349c02SJohan Hedberg static int smp_cmd_ident_addr_info(struct l2cap_conn *conn, 2590fd349c02SJohan Hedberg struct sk_buff *skb) 2591fd349c02SJohan Hedberg { 2592fd349c02SJohan Hedberg struct smp_cmd_ident_addr_info *info = (void *) skb->data; 25935d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 25945d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 2595fd349c02SJohan Hedberg struct hci_conn *hcon = conn->hcon; 2596fd349c02SJohan Hedberg bdaddr_t rpa; 2597fd349c02SJohan Hedberg 25982e1614f7SLuiz Augusto von Dentz bt_dev_dbg(hcon->hdev, ""); 2599fd349c02SJohan Hedberg 2600fd349c02SJohan Hedberg if (skb->len < sizeof(*info)) 260138e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 2602fd349c02SJohan Hedberg 26039747a9f3SJohan Hedberg /* Mark the information as received */ 26049747a9f3SJohan Hedberg smp->remote_key_dist &= ~SMP_DIST_ID_KEY; 26059747a9f3SJohan Hedberg 2606b28b4943SJohan Hedberg if (smp->remote_key_dist & SMP_DIST_SIGN) 2607b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO); 2608b28b4943SJohan Hedberg 2609fd349c02SJohan Hedberg skb_pull(skb, sizeof(*info)); 2610fd349c02SJohan Hedberg 2611a9a58f86SJohan Hedberg /* Strictly speaking the Core Specification (4.1) allows sending 2612a9a58f86SJohan Hedberg * an empty address which would force us to rely on just the IRK 2613a9a58f86SJohan Hedberg * as "identity information". However, since such 2614a9a58f86SJohan Hedberg * implementations are not known of and in order to not over 2615a9a58f86SJohan Hedberg * complicate our implementation, simply pretend that we never 2616a9a58f86SJohan Hedberg * received an IRK for such a device. 2617e12af489SJohan Hedberg * 2618e12af489SJohan Hedberg * The Identity Address must also be a Static Random or Public 2619e12af489SJohan Hedberg * Address, which hci_is_identity_address() checks for. 2620a9a58f86SJohan Hedberg */ 2621e12af489SJohan Hedberg if (!bacmp(&info->bdaddr, BDADDR_ANY) || 2622e12af489SJohan Hedberg !hci_is_identity_address(&info->bdaddr, info->addr_type)) { 26232064ee33SMarcel Holtmann bt_dev_err(hcon->hdev, "ignoring IRK with no identity address"); 262431dd624eSJohan Hedberg goto distribute; 2625a9a58f86SJohan Hedberg } 2626a9a58f86SJohan Hedberg 26271d87b88bSSzymon Janc /* Drop IRK if peer is using identity address during pairing but is 26281d87b88bSSzymon Janc * providing different address as identity information. 26291d87b88bSSzymon Janc * 26301d87b88bSSzymon Janc * Microsoft Surface Precision Mouse is known to have this bug. 26311d87b88bSSzymon Janc */ 26321d87b88bSSzymon Janc if (hci_is_identity_address(&hcon->dst, hcon->dst_type) && 26331d87b88bSSzymon Janc (bacmp(&info->bdaddr, &hcon->dst) || 26341d87b88bSSzymon Janc info->addr_type != hcon->dst_type)) { 26351d87b88bSSzymon Janc bt_dev_err(hcon->hdev, 26361d87b88bSSzymon Janc "ignoring IRK with invalid identity address"); 26371d87b88bSSzymon Janc goto distribute; 26381d87b88bSSzymon Janc } 26391d87b88bSSzymon Janc 2640fd349c02SJohan Hedberg bacpy(&smp->id_addr, &info->bdaddr); 2641fd349c02SJohan Hedberg smp->id_addr_type = info->addr_type; 2642fd349c02SJohan Hedberg 2643fd349c02SJohan Hedberg if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type)) 2644fd349c02SJohan Hedberg bacpy(&rpa, &hcon->dst); 2645fd349c02SJohan Hedberg else 2646fd349c02SJohan Hedberg bacpy(&rpa, BDADDR_ANY); 2647fd349c02SJohan Hedberg 264823d0e128SJohan Hedberg smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr, 264923d0e128SJohan Hedberg smp->id_addr_type, smp->irk, &rpa); 2650fd349c02SJohan Hedberg 265131dd624eSJohan Hedberg distribute: 2652c6e81e9aSJohan Hedberg if (!(smp->remote_key_dist & KEY_DIST_MASK)) 2653d6268e86SJohan Hedberg smp_distribute_keys(smp); 2654fd349c02SJohan Hedberg 2655fd349c02SJohan Hedberg return 0; 2656fd349c02SJohan Hedberg } 2657fd349c02SJohan Hedberg 26587ee4ea36SMarcel Holtmann static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb) 26597ee4ea36SMarcel Holtmann { 26607ee4ea36SMarcel Holtmann struct smp_cmd_sign_info *rp = (void *) skb->data; 26615d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 26625d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 26637ee4ea36SMarcel Holtmann struct smp_csrk *csrk; 26647ee4ea36SMarcel Holtmann 26652e1614f7SLuiz Augusto von Dentz bt_dev_dbg(conn->hcon->hdev, "conn %p", conn); 26667ee4ea36SMarcel Holtmann 26677ee4ea36SMarcel Holtmann if (skb->len < sizeof(*rp)) 266838e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 26697ee4ea36SMarcel Holtmann 26707ee4ea36SMarcel Holtmann /* Mark the information as received */ 26717ee4ea36SMarcel Holtmann smp->remote_key_dist &= ~SMP_DIST_SIGN; 26727ee4ea36SMarcel Holtmann 26737ee4ea36SMarcel Holtmann skb_pull(skb, sizeof(*rp)); 26747ee4ea36SMarcel Holtmann 26757ee4ea36SMarcel Holtmann csrk = kzalloc(sizeof(*csrk), GFP_KERNEL); 26767ee4ea36SMarcel Holtmann if (csrk) { 26774cd3928aSJohan Hedberg if (conn->hcon->sec_level > BT_SECURITY_MEDIUM) 26784cd3928aSJohan Hedberg csrk->type = MGMT_CSRK_REMOTE_AUTHENTICATED; 26794cd3928aSJohan Hedberg else 26804cd3928aSJohan Hedberg csrk->type = MGMT_CSRK_REMOTE_UNAUTHENTICATED; 26817ee4ea36SMarcel Holtmann memcpy(csrk->val, rp->csrk, sizeof(csrk->val)); 26827ee4ea36SMarcel Holtmann } 26837ee4ea36SMarcel Holtmann smp->csrk = csrk; 2684d6268e86SJohan Hedberg smp_distribute_keys(smp); 26857ee4ea36SMarcel Holtmann 26867ee4ea36SMarcel Holtmann return 0; 26877ee4ea36SMarcel Holtmann } 26887ee4ea36SMarcel Holtmann 26895e3d3d9bSJohan Hedberg static u8 sc_select_method(struct smp_chan *smp) 26905e3d3d9bSJohan Hedberg { 26915e3d3d9bSJohan Hedberg struct l2cap_conn *conn = smp->conn; 26925e3d3d9bSJohan Hedberg struct hci_conn *hcon = conn->hcon; 26935e3d3d9bSJohan Hedberg struct smp_cmd_pairing *local, *remote; 26945e3d3d9bSJohan Hedberg u8 local_mitm, remote_mitm, local_io, remote_io, method; 26955e3d3d9bSJohan Hedberg 26961a8bab4fSJohan Hedberg if (test_bit(SMP_FLAG_REMOTE_OOB, &smp->flags) || 26971a8bab4fSJohan Hedberg test_bit(SMP_FLAG_LOCAL_OOB, &smp->flags)) 2698a29b0733SJohan Hedberg return REQ_OOB; 2699a29b0733SJohan Hedberg 27005e3d3d9bSJohan Hedberg /* The preq/prsp contain the raw Pairing Request/Response PDUs 27015e3d3d9bSJohan Hedberg * which are needed as inputs to some crypto functions. To get 27025e3d3d9bSJohan Hedberg * the "struct smp_cmd_pairing" from them we need to skip the 27035e3d3d9bSJohan Hedberg * first byte which contains the opcode. 27045e3d3d9bSJohan Hedberg */ 27055e3d3d9bSJohan Hedberg if (hcon->out) { 27065e3d3d9bSJohan Hedberg local = (void *) &smp->preq[1]; 27075e3d3d9bSJohan Hedberg remote = (void *) &smp->prsp[1]; 27085e3d3d9bSJohan Hedberg } else { 27095e3d3d9bSJohan Hedberg local = (void *) &smp->prsp[1]; 27105e3d3d9bSJohan Hedberg remote = (void *) &smp->preq[1]; 27115e3d3d9bSJohan Hedberg } 27125e3d3d9bSJohan Hedberg 27135e3d3d9bSJohan Hedberg local_io = local->io_capability; 27145e3d3d9bSJohan Hedberg remote_io = remote->io_capability; 27155e3d3d9bSJohan Hedberg 27165e3d3d9bSJohan Hedberg local_mitm = (local->auth_req & SMP_AUTH_MITM); 27175e3d3d9bSJohan Hedberg remote_mitm = (remote->auth_req & SMP_AUTH_MITM); 27185e3d3d9bSJohan Hedberg 27195e3d3d9bSJohan Hedberg /* If either side wants MITM, look up the method from the table, 27205e3d3d9bSJohan Hedberg * otherwise use JUST WORKS. 27215e3d3d9bSJohan Hedberg */ 27225e3d3d9bSJohan Hedberg if (local_mitm || remote_mitm) 27235e3d3d9bSJohan Hedberg method = get_auth_method(smp, local_io, remote_io); 27245e3d3d9bSJohan Hedberg else 27255e3d3d9bSJohan Hedberg method = JUST_WORKS; 27265e3d3d9bSJohan Hedberg 27275e3d3d9bSJohan Hedberg /* Don't confirm locally initiated pairing attempts */ 27285e3d3d9bSJohan Hedberg if (method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR, &smp->flags)) 27295e3d3d9bSJohan Hedberg method = JUST_WORKS; 27305e3d3d9bSJohan Hedberg 27315e3d3d9bSJohan Hedberg return method; 27325e3d3d9bSJohan Hedberg } 27335e3d3d9bSJohan Hedberg 2734d8f8edbeSJohan Hedberg static int smp_cmd_public_key(struct l2cap_conn *conn, struct sk_buff *skb) 2735d8f8edbeSJohan Hedberg { 2736d8f8edbeSJohan Hedberg struct smp_cmd_public_key *key = (void *) skb->data; 2737d8f8edbeSJohan Hedberg struct hci_conn *hcon = conn->hcon; 2738d8f8edbeSJohan Hedberg struct l2cap_chan *chan = conn->smp; 2739d8f8edbeSJohan Hedberg struct smp_chan *smp = chan->data; 27405e3d3d9bSJohan Hedberg struct hci_dev *hdev = hcon->hdev; 2741c0153b0bSTudor Ambarus struct crypto_kpp *tfm_ecdh; 2742cbbbe3e2SJohan Hedberg struct smp_cmd_pairing_confirm cfm; 2743d8f8edbeSJohan Hedberg int err; 2744d8f8edbeSJohan Hedberg 27452e1614f7SLuiz Augusto von Dentz bt_dev_dbg(hdev, "conn %p", conn); 2746d8f8edbeSJohan Hedberg 2747d8f8edbeSJohan Hedberg if (skb->len < sizeof(*key)) 2748d8f8edbeSJohan Hedberg return SMP_INVALID_PARAMS; 2749d8f8edbeSJohan Hedberg 27506d19628fSLuiz Augusto von Dentz /* Check if remote and local public keys are the same and debug key is 27516d19628fSLuiz Augusto von Dentz * not in use. 27526d19628fSLuiz Augusto von Dentz */ 27536d19628fSLuiz Augusto von Dentz if (!test_bit(SMP_FLAG_DEBUG_KEY, &smp->flags) && 27546d19628fSLuiz Augusto von Dentz !crypto_memneq(key, smp->local_pk, 64)) { 27556d19628fSLuiz Augusto von Dentz bt_dev_err(hdev, "Remote and local public keys are identical"); 27566d19628fSLuiz Augusto von Dentz return SMP_UNSPECIFIED; 27576d19628fSLuiz Augusto von Dentz } 27586d19628fSLuiz Augusto von Dentz 2759d8f8edbeSJohan Hedberg memcpy(smp->remote_pk, key, 64); 2760d8f8edbeSJohan Hedberg 2761a8ca617cSJohan Hedberg if (test_bit(SMP_FLAG_REMOTE_OOB, &smp->flags)) { 2762a8ca617cSJohan Hedberg err = smp_f4(smp->tfm_cmac, smp->remote_pk, smp->remote_pk, 2763a8ca617cSJohan Hedberg smp->rr, 0, cfm.confirm_val); 2764a8ca617cSJohan Hedberg if (err) 2765a8ca617cSJohan Hedberg return SMP_UNSPECIFIED; 2766a8ca617cSJohan Hedberg 2767329d8230SJason A. Donenfeld if (crypto_memneq(cfm.confirm_val, smp->pcnf, 16)) 2768a8ca617cSJohan Hedberg return SMP_CONFIRM_FAILED; 2769a8ca617cSJohan Hedberg } 2770a8ca617cSJohan Hedberg 2771d8f8edbeSJohan Hedberg /* Non-initiating device sends its public key after receiving 2772d8f8edbeSJohan Hedberg * the key from the initiating device. 2773d8f8edbeSJohan Hedberg */ 2774d8f8edbeSJohan Hedberg if (!hcon->out) { 2775d8f8edbeSJohan Hedberg err = sc_send_public_key(smp); 2776d8f8edbeSJohan Hedberg if (err) 2777d8f8edbeSJohan Hedberg return err; 2778d8f8edbeSJohan Hedberg } 2779d8f8edbeSJohan Hedberg 2780c7a3d57dSJohan Hedberg SMP_DBG("Remote Public Key X: %32phN", smp->remote_pk); 2781e091526dSMarcel Holtmann SMP_DBG("Remote Public Key Y: %32phN", smp->remote_pk + 32); 2782d8f8edbeSJohan Hedberg 2783c0153b0bSTudor Ambarus /* Compute the shared secret on the same crypto tfm on which the private 2784c0153b0bSTudor Ambarus * key was set/generated. 2785c0153b0bSTudor Ambarus */ 2786c0153b0bSTudor Ambarus if (test_bit(SMP_FLAG_LOCAL_OOB, &smp->flags)) { 27874ba5175fSMatias Karhumaa struct l2cap_chan *hchan = hdev->smp_data; 27884ba5175fSMatias Karhumaa struct smp_dev *smp_dev; 27894ba5175fSMatias Karhumaa 27904ba5175fSMatias Karhumaa if (!hchan || !hchan->data) 27914ba5175fSMatias Karhumaa return SMP_UNSPECIFIED; 27924ba5175fSMatias Karhumaa 27934ba5175fSMatias Karhumaa smp_dev = hchan->data; 2794c0153b0bSTudor Ambarus 2795c0153b0bSTudor Ambarus tfm_ecdh = smp_dev->tfm_ecdh; 2796c0153b0bSTudor Ambarus } else { 2797c0153b0bSTudor Ambarus tfm_ecdh = smp->tfm_ecdh; 2798c0153b0bSTudor Ambarus } 2799c0153b0bSTudor Ambarus 2800c0153b0bSTudor Ambarus if (compute_ecdh_secret(tfm_ecdh, smp->remote_pk, smp->dhkey)) 2801d8f8edbeSJohan Hedberg return SMP_UNSPECIFIED; 2802d8f8edbeSJohan Hedberg 2803c7a3d57dSJohan Hedberg SMP_DBG("DHKey %32phN", smp->dhkey); 2804d8f8edbeSJohan Hedberg 2805d8f8edbeSJohan Hedberg set_bit(SMP_FLAG_REMOTE_PK, &smp->flags); 2806d8f8edbeSJohan Hedberg 28075e3d3d9bSJohan Hedberg smp->method = sc_select_method(smp); 28085e3d3d9bSJohan Hedberg 28092e1614f7SLuiz Augusto von Dentz bt_dev_dbg(hdev, "selected method 0x%02x", smp->method); 28105e3d3d9bSJohan Hedberg 28115e3d3d9bSJohan Hedberg /* JUST_WORKS and JUST_CFM result in an unauthenticated key */ 28125e3d3d9bSJohan Hedberg if (smp->method == JUST_WORKS || smp->method == JUST_CFM) 28135e3d3d9bSJohan Hedberg hcon->pending_sec_level = BT_SECURITY_MEDIUM; 28145e3d3d9bSJohan Hedberg else 28155e3d3d9bSJohan Hedberg hcon->pending_sec_level = BT_SECURITY_FIPS; 28165e3d3d9bSJohan Hedberg 2817329d8230SJason A. Donenfeld if (!crypto_memneq(debug_pk, smp->remote_pk, 64)) 2818aeb7d461SJohan Hedberg set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags); 2819aeb7d461SJohan Hedberg 282038606f14SJohan Hedberg if (smp->method == DSP_PASSKEY) { 282138606f14SJohan Hedberg get_random_bytes(&hcon->passkey_notify, 282238606f14SJohan Hedberg sizeof(hcon->passkey_notify)); 282338606f14SJohan Hedberg hcon->passkey_notify %= 1000000; 282438606f14SJohan Hedberg hcon->passkey_entered = 0; 282538606f14SJohan Hedberg smp->passkey_round = 0; 282638606f14SJohan Hedberg if (mgmt_user_passkey_notify(hdev, &hcon->dst, hcon->type, 282738606f14SJohan Hedberg hcon->dst_type, 282838606f14SJohan Hedberg hcon->passkey_notify, 282938606f14SJohan Hedberg hcon->passkey_entered)) 283038606f14SJohan Hedberg return SMP_UNSPECIFIED; 283138606f14SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); 283238606f14SJohan Hedberg return sc_passkey_round(smp, SMP_CMD_PUBLIC_KEY); 283338606f14SJohan Hedberg } 283438606f14SJohan Hedberg 283594ea7257SJohan Hedberg if (smp->method == REQ_OOB) { 2836a29b0733SJohan Hedberg if (hcon->out) 2837a29b0733SJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, 2838a29b0733SJohan Hedberg sizeof(smp->prnd), smp->prnd); 2839a29b0733SJohan Hedberg 2840a29b0733SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM); 2841a29b0733SJohan Hedberg 2842a29b0733SJohan Hedberg return 0; 2843a29b0733SJohan Hedberg } 2844a29b0733SJohan Hedberg 284538606f14SJohan Hedberg if (hcon->out) 284638606f14SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); 284738606f14SJohan Hedberg 284838606f14SJohan Hedberg if (smp->method == REQ_PASSKEY) { 284938606f14SJohan Hedberg if (mgmt_user_passkey_request(hdev, &hcon->dst, hcon->type, 285038606f14SJohan Hedberg hcon->dst_type)) 285138606f14SJohan Hedberg return SMP_UNSPECIFIED; 285238606f14SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); 285338606f14SJohan Hedberg set_bit(SMP_FLAG_WAIT_USER, &smp->flags); 285438606f14SJohan Hedberg return 0; 285538606f14SJohan Hedberg } 285638606f14SJohan Hedberg 2857cbbbe3e2SJohan Hedberg /* The Initiating device waits for the non-initiating device to 2858cbbbe3e2SJohan Hedberg * send the confirm value. 2859cbbbe3e2SJohan Hedberg */ 2860cbbbe3e2SJohan Hedberg if (conn->hcon->out) 2861cbbbe3e2SJohan Hedberg return 0; 2862cbbbe3e2SJohan Hedberg 2863cbbbe3e2SJohan Hedberg err = smp_f4(smp->tfm_cmac, smp->local_pk, smp->remote_pk, smp->prnd, 2864cbbbe3e2SJohan Hedberg 0, cfm.confirm_val); 2865cbbbe3e2SJohan Hedberg if (err) 2866cbbbe3e2SJohan Hedberg return SMP_UNSPECIFIED; 2867cbbbe3e2SJohan Hedberg 2868cbbbe3e2SJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cfm), &cfm); 2869cbbbe3e2SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM); 2870cbbbe3e2SJohan Hedberg 2871d8f8edbeSJohan Hedberg return 0; 2872d8f8edbeSJohan Hedberg } 2873d8f8edbeSJohan Hedberg 28746433a9a2SJohan Hedberg static int smp_cmd_dhkey_check(struct l2cap_conn *conn, struct sk_buff *skb) 28756433a9a2SJohan Hedberg { 28766433a9a2SJohan Hedberg struct smp_cmd_dhkey_check *check = (void *) skb->data; 28776433a9a2SJohan Hedberg struct l2cap_chan *chan = conn->smp; 28786433a9a2SJohan Hedberg struct hci_conn *hcon = conn->hcon; 28796433a9a2SJohan Hedberg struct smp_chan *smp = chan->data; 28806433a9a2SJohan Hedberg u8 a[7], b[7], *local_addr, *remote_addr; 28816433a9a2SJohan Hedberg u8 io_cap[3], r[16], e[16]; 28826433a9a2SJohan Hedberg int err; 28836433a9a2SJohan Hedberg 28842e1614f7SLuiz Augusto von Dentz bt_dev_dbg(hcon->hdev, "conn %p", conn); 28856433a9a2SJohan Hedberg 28866433a9a2SJohan Hedberg if (skb->len < sizeof(*check)) 28876433a9a2SJohan Hedberg return SMP_INVALID_PARAMS; 28886433a9a2SJohan Hedberg 28896433a9a2SJohan Hedberg memcpy(a, &hcon->init_addr, 6); 28906433a9a2SJohan Hedberg memcpy(b, &hcon->resp_addr, 6); 28916433a9a2SJohan Hedberg a[6] = hcon->init_addr_type; 28926433a9a2SJohan Hedberg b[6] = hcon->resp_addr_type; 28936433a9a2SJohan Hedberg 28946433a9a2SJohan Hedberg if (hcon->out) { 28956433a9a2SJohan Hedberg local_addr = a; 28966433a9a2SJohan Hedberg remote_addr = b; 28976433a9a2SJohan Hedberg memcpy(io_cap, &smp->prsp[1], 3); 28986433a9a2SJohan Hedberg } else { 28996433a9a2SJohan Hedberg local_addr = b; 29006433a9a2SJohan Hedberg remote_addr = a; 29016433a9a2SJohan Hedberg memcpy(io_cap, &smp->preq[1], 3); 29026433a9a2SJohan Hedberg } 29036433a9a2SJohan Hedberg 29046433a9a2SJohan Hedberg memset(r, 0, sizeof(r)); 29056433a9a2SJohan Hedberg 290638606f14SJohan Hedberg if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY) 290738606f14SJohan Hedberg put_unaligned_le32(hcon->passkey_notify, r); 2908882fafadSJohan Hedberg else if (smp->method == REQ_OOB) 2909882fafadSJohan Hedberg memcpy(r, smp->lr, 16); 291038606f14SJohan Hedberg 29116433a9a2SJohan Hedberg err = smp_f6(smp->tfm_cmac, smp->mackey, smp->rrnd, smp->prnd, r, 29126433a9a2SJohan Hedberg io_cap, remote_addr, local_addr, e); 29136433a9a2SJohan Hedberg if (err) 29146433a9a2SJohan Hedberg return SMP_UNSPECIFIED; 29156433a9a2SJohan Hedberg 2916329d8230SJason A. Donenfeld if (crypto_memneq(check->e, e, 16)) 29176433a9a2SJohan Hedberg return SMP_DHKEY_CHECK_FAILED; 29186433a9a2SJohan Hedberg 2919d3e54a87SJohan Hedberg if (!hcon->out) { 2920d3e54a87SJohan Hedberg if (test_bit(SMP_FLAG_WAIT_USER, &smp->flags)) { 2921d3e54a87SJohan Hedberg set_bit(SMP_FLAG_DHKEY_PENDING, &smp->flags); 2922d3e54a87SJohan Hedberg return 0; 2923d3e54a87SJohan Hedberg } 2924d378a2d7SJohan Hedberg 2925fad646e1SArchie Pusaka /* Responder sends DHKey check as response to initiator */ 2926d3e54a87SJohan Hedberg sc_dhkey_check(smp); 2927d3e54a87SJohan Hedberg } 2928d378a2d7SJohan Hedberg 2929d3e54a87SJohan Hedberg sc_add_ltk(smp); 29306433a9a2SJohan Hedberg 29316433a9a2SJohan Hedberg if (hcon->out) { 29328b76ce34SJohan Hedberg hci_le_start_enc(hcon, 0, 0, smp->tk, smp->enc_key_size); 29336433a9a2SJohan Hedberg hcon->enc_key_size = smp->enc_key_size; 29346433a9a2SJohan Hedberg } 29356433a9a2SJohan Hedberg 29366433a9a2SJohan Hedberg return 0; 29376433a9a2SJohan Hedberg } 29386433a9a2SJohan Hedberg 29391408bb6eSJohan Hedberg static int smp_cmd_keypress_notify(struct l2cap_conn *conn, 29401408bb6eSJohan Hedberg struct sk_buff *skb) 29411408bb6eSJohan Hedberg { 29421408bb6eSJohan Hedberg struct smp_cmd_keypress_notify *kp = (void *) skb->data; 29431408bb6eSJohan Hedberg 29442e1614f7SLuiz Augusto von Dentz bt_dev_dbg(conn->hcon->hdev, "value 0x%02x", kp->value); 29451408bb6eSJohan Hedberg 29461408bb6eSJohan Hedberg return 0; 29471408bb6eSJohan Hedberg } 29481408bb6eSJohan Hedberg 29494befb867SJohan Hedberg static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb) 2950eb492e01SAnderson Briglia { 29515d88cc73SJohan Hedberg struct l2cap_conn *conn = chan->conn; 29527b9899dbSMarcel Holtmann struct hci_conn *hcon = conn->hcon; 2953b28b4943SJohan Hedberg struct smp_chan *smp; 295492381f5cSMarcel Holtmann __u8 code, reason; 2955eb492e01SAnderson Briglia int err = 0; 2956eb492e01SAnderson Briglia 29578ae9b984SJohan Hedberg if (skb->len < 1) 295892381f5cSMarcel Holtmann return -EILSEQ; 295992381f5cSMarcel Holtmann 2960d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hcon->hdev, HCI_LE_ENABLED)) { 29612e65c9d2SAndre Guedes reason = SMP_PAIRING_NOTSUPP; 29622e65c9d2SAndre Guedes goto done; 29632e65c9d2SAndre Guedes } 29642e65c9d2SAndre Guedes 296592381f5cSMarcel Holtmann code = skb->data[0]; 2966eb492e01SAnderson Briglia skb_pull(skb, sizeof(code)); 2967eb492e01SAnderson Briglia 2968b28b4943SJohan Hedberg smp = chan->data; 2969b28b4943SJohan Hedberg 2970b28b4943SJohan Hedberg if (code > SMP_CMD_MAX) 2971b28b4943SJohan Hedberg goto drop; 2972b28b4943SJohan Hedberg 297324bd0bd9SJohan Hedberg if (smp && !test_and_clear_bit(code, &smp->allow_cmd)) 2974b28b4943SJohan Hedberg goto drop; 2975b28b4943SJohan Hedberg 2976b28b4943SJohan Hedberg /* If we don't have a context the only allowed commands are 2977b28b4943SJohan Hedberg * pairing request and security request. 29788cf9fa12SJohan Hedberg */ 2979b28b4943SJohan Hedberg if (!smp && code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ) 2980b28b4943SJohan Hedberg goto drop; 29818cf9fa12SJohan Hedberg 2982eb492e01SAnderson Briglia switch (code) { 2983eb492e01SAnderson Briglia case SMP_CMD_PAIRING_REQ: 2984da85e5e5SVinicius Costa Gomes reason = smp_cmd_pairing_req(conn, skb); 2985eb492e01SAnderson Briglia break; 2986eb492e01SAnderson Briglia 2987eb492e01SAnderson Briglia case SMP_CMD_PAIRING_FAIL: 298884794e11SJohan Hedberg smp_failure(conn, 0); 2989da85e5e5SVinicius Costa Gomes err = -EPERM; 2990eb492e01SAnderson Briglia break; 2991eb492e01SAnderson Briglia 2992eb492e01SAnderson Briglia case SMP_CMD_PAIRING_RSP: 2993da85e5e5SVinicius Costa Gomes reason = smp_cmd_pairing_rsp(conn, skb); 299488ba43b6SAnderson Briglia break; 299588ba43b6SAnderson Briglia 299688ba43b6SAnderson Briglia case SMP_CMD_SECURITY_REQ: 2997da85e5e5SVinicius Costa Gomes reason = smp_cmd_security_req(conn, skb); 299888ba43b6SAnderson Briglia break; 299988ba43b6SAnderson Briglia 3000eb492e01SAnderson Briglia case SMP_CMD_PAIRING_CONFIRM: 3001da85e5e5SVinicius Costa Gomes reason = smp_cmd_pairing_confirm(conn, skb); 300288ba43b6SAnderson Briglia break; 300388ba43b6SAnderson Briglia 3004eb492e01SAnderson Briglia case SMP_CMD_PAIRING_RANDOM: 3005da85e5e5SVinicius Costa Gomes reason = smp_cmd_pairing_random(conn, skb); 300688ba43b6SAnderson Briglia break; 300788ba43b6SAnderson Briglia 3008eb492e01SAnderson Briglia case SMP_CMD_ENCRYPT_INFO: 30097034b911SVinicius Costa Gomes reason = smp_cmd_encrypt_info(conn, skb); 30107034b911SVinicius Costa Gomes break; 30117034b911SVinicius Costa Gomes 3012fad646e1SArchie Pusaka case SMP_CMD_INITIATOR_IDENT: 3013fad646e1SArchie Pusaka reason = smp_cmd_initiator_ident(conn, skb); 30147034b911SVinicius Costa Gomes break; 30157034b911SVinicius Costa Gomes 3016eb492e01SAnderson Briglia case SMP_CMD_IDENT_INFO: 3017fd349c02SJohan Hedberg reason = smp_cmd_ident_info(conn, skb); 3018fd349c02SJohan Hedberg break; 3019fd349c02SJohan Hedberg 3020eb492e01SAnderson Briglia case SMP_CMD_IDENT_ADDR_INFO: 3021fd349c02SJohan Hedberg reason = smp_cmd_ident_addr_info(conn, skb); 3022fd349c02SJohan Hedberg break; 3023fd349c02SJohan Hedberg 3024eb492e01SAnderson Briglia case SMP_CMD_SIGN_INFO: 30257ee4ea36SMarcel Holtmann reason = smp_cmd_sign_info(conn, skb); 30267034b911SVinicius Costa Gomes break; 30277034b911SVinicius Costa Gomes 3028d8f8edbeSJohan Hedberg case SMP_CMD_PUBLIC_KEY: 3029d8f8edbeSJohan Hedberg reason = smp_cmd_public_key(conn, skb); 3030d8f8edbeSJohan Hedberg break; 3031d8f8edbeSJohan Hedberg 30326433a9a2SJohan Hedberg case SMP_CMD_DHKEY_CHECK: 30336433a9a2SJohan Hedberg reason = smp_cmd_dhkey_check(conn, skb); 30346433a9a2SJohan Hedberg break; 30356433a9a2SJohan Hedberg 30361408bb6eSJohan Hedberg case SMP_CMD_KEYPRESS_NOTIFY: 30371408bb6eSJohan Hedberg reason = smp_cmd_keypress_notify(conn, skb); 30381408bb6eSJohan Hedberg break; 30391408bb6eSJohan Hedberg 3040eb492e01SAnderson Briglia default: 30412e1614f7SLuiz Augusto von Dentz bt_dev_dbg(hcon->hdev, "Unknown command code 0x%2.2x", code); 3042eb492e01SAnderson Briglia reason = SMP_CMD_NOTSUPP; 30433a0259bbSVinicius Costa Gomes goto done; 30443a0259bbSVinicius Costa Gomes } 30453a0259bbSVinicius Costa Gomes 30463a0259bbSVinicius Costa Gomes done: 30479b7b18efSJohan Hedberg if (!err) { 30483a0259bbSVinicius Costa Gomes if (reason) 304984794e11SJohan Hedberg smp_failure(conn, reason); 3050eb492e01SAnderson Briglia kfree_skb(skb); 30519b7b18efSJohan Hedberg } 30529b7b18efSJohan Hedberg 3053eb492e01SAnderson Briglia return err; 3054b28b4943SJohan Hedberg 3055b28b4943SJohan Hedberg drop: 30562064ee33SMarcel Holtmann bt_dev_err(hcon->hdev, "unexpected SMP command 0x%02x from %pMR", 3057b28b4943SJohan Hedberg code, &hcon->dst); 3058b28b4943SJohan Hedberg kfree_skb(skb); 3059b28b4943SJohan Hedberg return 0; 3060eb492e01SAnderson Briglia } 30617034b911SVinicius Costa Gomes 306270db83c4SJohan Hedberg static void smp_teardown_cb(struct l2cap_chan *chan, int err) 306370db83c4SJohan Hedberg { 306470db83c4SJohan Hedberg struct l2cap_conn *conn = chan->conn; 306570db83c4SJohan Hedberg 30662e1614f7SLuiz Augusto von Dentz bt_dev_dbg(conn->hcon->hdev, "chan %p", chan); 306770db83c4SJohan Hedberg 3068fc75cc86SJohan Hedberg if (chan->data) 30695d88cc73SJohan Hedberg smp_chan_destroy(conn); 30705d88cc73SJohan Hedberg 307170db83c4SJohan Hedberg conn->smp = NULL; 307270db83c4SJohan Hedberg l2cap_chan_put(chan); 307370db83c4SJohan Hedberg } 307470db83c4SJohan Hedberg 3075b5ae344dSJohan Hedberg static void bredr_pairing(struct l2cap_chan *chan) 3076b5ae344dSJohan Hedberg { 3077b5ae344dSJohan Hedberg struct l2cap_conn *conn = chan->conn; 3078b5ae344dSJohan Hedberg struct hci_conn *hcon = conn->hcon; 3079b5ae344dSJohan Hedberg struct hci_dev *hdev = hcon->hdev; 3080b5ae344dSJohan Hedberg struct smp_cmd_pairing req; 3081b5ae344dSJohan Hedberg struct smp_chan *smp; 3082b5ae344dSJohan Hedberg 30832e1614f7SLuiz Augusto von Dentz bt_dev_dbg(hdev, "chan %p", chan); 3084b5ae344dSJohan Hedberg 3085b5ae344dSJohan Hedberg /* Only new pairings are interesting */ 3086b5ae344dSJohan Hedberg if (!test_bit(HCI_CONN_NEW_LINK_KEY, &hcon->flags)) 3087b5ae344dSJohan Hedberg return; 3088b5ae344dSJohan Hedberg 3089b5ae344dSJohan Hedberg /* Don't bother if we're not encrypted */ 3090b5ae344dSJohan Hedberg if (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags)) 3091b5ae344dSJohan Hedberg return; 3092b5ae344dSJohan Hedberg 309374be523cSArchie Pusaka /* Only initiator may initiate SMP over BR/EDR */ 3094b5ae344dSJohan Hedberg if (hcon->role != HCI_ROLE_MASTER) 3095b5ae344dSJohan Hedberg return; 3096b5ae344dSJohan Hedberg 3097b5ae344dSJohan Hedberg /* Secure Connections support must be enabled */ 3098d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_SC_ENABLED)) 3099b5ae344dSJohan Hedberg return; 3100b5ae344dSJohan Hedberg 3101b5ae344dSJohan Hedberg /* BR/EDR must use Secure Connections for SMP */ 3102b5ae344dSJohan Hedberg if (!test_bit(HCI_CONN_AES_CCM, &hcon->flags) && 3103b7cb93e5SMarcel Holtmann !hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP)) 3104b5ae344dSJohan Hedberg return; 3105b5ae344dSJohan Hedberg 3106b5ae344dSJohan Hedberg /* If our LE support is not enabled don't do anything */ 3107d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED)) 3108b5ae344dSJohan Hedberg return; 3109b5ae344dSJohan Hedberg 3110b5ae344dSJohan Hedberg /* Don't bother if remote LE support is not enabled */ 3111b5ae344dSJohan Hedberg if (!lmp_host_le_capable(hcon)) 3112b5ae344dSJohan Hedberg return; 3113b5ae344dSJohan Hedberg 3114b5ae344dSJohan Hedberg /* Remote must support SMP fixed chan for BR/EDR */ 3115b5ae344dSJohan Hedberg if (!(conn->remote_fixed_chan & L2CAP_FC_SMP_BREDR)) 3116b5ae344dSJohan Hedberg return; 3117b5ae344dSJohan Hedberg 3118b5ae344dSJohan Hedberg /* Don't bother if SMP is already ongoing */ 3119b5ae344dSJohan Hedberg if (chan->data) 3120b5ae344dSJohan Hedberg return; 3121b5ae344dSJohan Hedberg 3122b5ae344dSJohan Hedberg smp = smp_chan_create(conn); 3123b5ae344dSJohan Hedberg if (!smp) { 31242064ee33SMarcel Holtmann bt_dev_err(hdev, "unable to create SMP context for BR/EDR"); 3125b5ae344dSJohan Hedberg return; 3126b5ae344dSJohan Hedberg } 3127b5ae344dSJohan Hedberg 3128b5ae344dSJohan Hedberg set_bit(SMP_FLAG_SC, &smp->flags); 3129b5ae344dSJohan Hedberg 31302e1614f7SLuiz Augusto von Dentz bt_dev_dbg(hdev, "starting SMP over BR/EDR"); 3131b5ae344dSJohan Hedberg 3132b5ae344dSJohan Hedberg /* Prepare and send the BR/EDR SMP Pairing Request */ 3133b5ae344dSJohan Hedberg build_bredr_pairing_cmd(smp, &req, NULL); 3134b5ae344dSJohan Hedberg 3135b5ae344dSJohan Hedberg smp->preq[0] = SMP_CMD_PAIRING_REQ; 3136b5ae344dSJohan Hedberg memcpy(&smp->preq[1], &req, sizeof(req)); 3137b5ae344dSJohan Hedberg 3138b5ae344dSJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(req), &req); 3139b5ae344dSJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP); 3140b5ae344dSJohan Hedberg } 3141b5ae344dSJohan Hedberg 314244f1a7abSJohan Hedberg static void smp_resume_cb(struct l2cap_chan *chan) 314344f1a7abSJohan Hedberg { 3144b68fda68SJohan Hedberg struct smp_chan *smp = chan->data; 314544f1a7abSJohan Hedberg struct l2cap_conn *conn = chan->conn; 314644f1a7abSJohan Hedberg struct hci_conn *hcon = conn->hcon; 314744f1a7abSJohan Hedberg 31482e1614f7SLuiz Augusto von Dentz bt_dev_dbg(hcon->hdev, "chan %p", chan); 314944f1a7abSJohan Hedberg 3150b5ae344dSJohan Hedberg if (hcon->type == ACL_LINK) { 3151b5ae344dSJohan Hedberg bredr_pairing(chan); 3152ef8efe4bSJohan Hedberg return; 3153b5ae344dSJohan Hedberg } 3154ef8efe4bSJohan Hedberg 315586d1407cSJohan Hedberg if (!smp) 315686d1407cSJohan Hedberg return; 3157b68fda68SJohan Hedberg 315884bc0db5SJohan Hedberg if (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags)) 315984bc0db5SJohan Hedberg return; 316084bc0db5SJohan Hedberg 3161b68fda68SJohan Hedberg cancel_delayed_work(&smp->security_timer); 316286d1407cSJohan Hedberg 3163d6268e86SJohan Hedberg smp_distribute_keys(smp); 316444f1a7abSJohan Hedberg } 316544f1a7abSJohan Hedberg 316670db83c4SJohan Hedberg static void smp_ready_cb(struct l2cap_chan *chan) 316770db83c4SJohan Hedberg { 316870db83c4SJohan Hedberg struct l2cap_conn *conn = chan->conn; 3169b5ae344dSJohan Hedberg struct hci_conn *hcon = conn->hcon; 317070db83c4SJohan Hedberg 31712e1614f7SLuiz Augusto von Dentz bt_dev_dbg(hcon->hdev, "chan %p", chan); 317270db83c4SJohan Hedberg 31737883746bSJohan Hedberg /* No need to call l2cap_chan_hold() here since we already own 31747883746bSJohan Hedberg * the reference taken in smp_new_conn_cb(). This is just the 31757883746bSJohan Hedberg * first time that we tie it to a specific pointer. The code in 31767883746bSJohan Hedberg * l2cap_core.c ensures that there's no risk this function wont 31777883746bSJohan Hedberg * get called if smp_new_conn_cb was previously called. 31787883746bSJohan Hedberg */ 317970db83c4SJohan Hedberg conn->smp = chan; 3180b5ae344dSJohan Hedberg 3181b5ae344dSJohan Hedberg if (hcon->type == ACL_LINK && test_bit(HCI_CONN_ENCRYPT, &hcon->flags)) 3182b5ae344dSJohan Hedberg bredr_pairing(chan); 318370db83c4SJohan Hedberg } 318470db83c4SJohan Hedberg 31854befb867SJohan Hedberg static int smp_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) 31864befb867SJohan Hedberg { 31874befb867SJohan Hedberg int err; 31884befb867SJohan Hedberg 31892e1614f7SLuiz Augusto von Dentz bt_dev_dbg(chan->conn->hcon->hdev, "chan %p", chan); 31904befb867SJohan Hedberg 31914befb867SJohan Hedberg err = smp_sig_channel(chan, skb); 31924befb867SJohan Hedberg if (err) { 3193b68fda68SJohan Hedberg struct smp_chan *smp = chan->data; 31944befb867SJohan Hedberg 3195b68fda68SJohan Hedberg if (smp) 3196b68fda68SJohan Hedberg cancel_delayed_work_sync(&smp->security_timer); 31974befb867SJohan Hedberg 31981e91c29eSJohan Hedberg hci_disconnect(chan->conn->hcon, HCI_ERROR_AUTH_FAILURE); 31994befb867SJohan Hedberg } 32004befb867SJohan Hedberg 32014befb867SJohan Hedberg return err; 32024befb867SJohan Hedberg } 32034befb867SJohan Hedberg 320470db83c4SJohan Hedberg static struct sk_buff *smp_alloc_skb_cb(struct l2cap_chan *chan, 320570db83c4SJohan Hedberg unsigned long hdr_len, 320670db83c4SJohan Hedberg unsigned long len, int nb) 320770db83c4SJohan Hedberg { 320870db83c4SJohan Hedberg struct sk_buff *skb; 320970db83c4SJohan Hedberg 321070db83c4SJohan Hedberg skb = bt_skb_alloc(hdr_len + len, GFP_KERNEL); 321170db83c4SJohan Hedberg if (!skb) 321270db83c4SJohan Hedberg return ERR_PTR(-ENOMEM); 321370db83c4SJohan Hedberg 321470db83c4SJohan Hedberg skb->priority = HCI_PRIO_MAX; 3215a4368ff3SJohan Hedberg bt_cb(skb)->l2cap.chan = chan; 321670db83c4SJohan Hedberg 321770db83c4SJohan Hedberg return skb; 321870db83c4SJohan Hedberg } 321970db83c4SJohan Hedberg 322070db83c4SJohan Hedberg static const struct l2cap_ops smp_chan_ops = { 322170db83c4SJohan Hedberg .name = "Security Manager", 322270db83c4SJohan Hedberg .ready = smp_ready_cb, 32235d88cc73SJohan Hedberg .recv = smp_recv_cb, 322470db83c4SJohan Hedberg .alloc_skb = smp_alloc_skb_cb, 322570db83c4SJohan Hedberg .teardown = smp_teardown_cb, 322644f1a7abSJohan Hedberg .resume = smp_resume_cb, 322770db83c4SJohan Hedberg 322870db83c4SJohan Hedberg .new_connection = l2cap_chan_no_new_connection, 322970db83c4SJohan Hedberg .state_change = l2cap_chan_no_state_change, 323070db83c4SJohan Hedberg .close = l2cap_chan_no_close, 323170db83c4SJohan Hedberg .defer = l2cap_chan_no_defer, 323270db83c4SJohan Hedberg .suspend = l2cap_chan_no_suspend, 323370db83c4SJohan Hedberg .set_shutdown = l2cap_chan_no_set_shutdown, 323470db83c4SJohan Hedberg .get_sndtimeo = l2cap_chan_no_get_sndtimeo, 323570db83c4SJohan Hedberg }; 323670db83c4SJohan Hedberg 323770db83c4SJohan Hedberg static inline struct l2cap_chan *smp_new_conn_cb(struct l2cap_chan *pchan) 323870db83c4SJohan Hedberg { 323970db83c4SJohan Hedberg struct l2cap_chan *chan; 324070db83c4SJohan Hedberg 3241995fca15SLuiz Augusto von Dentz BT_DBG("pchan %p", pchan); 324270db83c4SJohan Hedberg 324370db83c4SJohan Hedberg chan = l2cap_chan_create(); 324470db83c4SJohan Hedberg if (!chan) 324570db83c4SJohan Hedberg return NULL; 324670db83c4SJohan Hedberg 324770db83c4SJohan Hedberg chan->chan_type = pchan->chan_type; 324870db83c4SJohan Hedberg chan->ops = &smp_chan_ops; 324970db83c4SJohan Hedberg chan->scid = pchan->scid; 325070db83c4SJohan Hedberg chan->dcid = chan->scid; 325170db83c4SJohan Hedberg chan->imtu = pchan->imtu; 325270db83c4SJohan Hedberg chan->omtu = pchan->omtu; 325370db83c4SJohan Hedberg chan->mode = pchan->mode; 325470db83c4SJohan Hedberg 3255abe84903SJohan Hedberg /* Other L2CAP channels may request SMP routines in order to 3256abe84903SJohan Hedberg * change the security level. This means that the SMP channel 3257abe84903SJohan Hedberg * lock must be considered in its own category to avoid lockdep 3258abe84903SJohan Hedberg * warnings. 3259abe84903SJohan Hedberg */ 3260abe84903SJohan Hedberg atomic_set(&chan->nesting, L2CAP_NESTING_SMP); 3261abe84903SJohan Hedberg 3262995fca15SLuiz Augusto von Dentz BT_DBG("created chan %p", chan); 326370db83c4SJohan Hedberg 326470db83c4SJohan Hedberg return chan; 326570db83c4SJohan Hedberg } 326670db83c4SJohan Hedberg 326770db83c4SJohan Hedberg static const struct l2cap_ops smp_root_chan_ops = { 326870db83c4SJohan Hedberg .name = "Security Manager Root", 326970db83c4SJohan Hedberg .new_connection = smp_new_conn_cb, 327070db83c4SJohan Hedberg 327170db83c4SJohan Hedberg /* None of these are implemented for the root channel */ 327270db83c4SJohan Hedberg .close = l2cap_chan_no_close, 327370db83c4SJohan Hedberg .alloc_skb = l2cap_chan_no_alloc_skb, 327470db83c4SJohan Hedberg .recv = l2cap_chan_no_recv, 327570db83c4SJohan Hedberg .state_change = l2cap_chan_no_state_change, 327670db83c4SJohan Hedberg .teardown = l2cap_chan_no_teardown, 327770db83c4SJohan Hedberg .ready = l2cap_chan_no_ready, 327870db83c4SJohan Hedberg .defer = l2cap_chan_no_defer, 327970db83c4SJohan Hedberg .suspend = l2cap_chan_no_suspend, 328070db83c4SJohan Hedberg .resume = l2cap_chan_no_resume, 328170db83c4SJohan Hedberg .set_shutdown = l2cap_chan_no_set_shutdown, 328270db83c4SJohan Hedberg .get_sndtimeo = l2cap_chan_no_get_sndtimeo, 328370db83c4SJohan Hedberg }; 328470db83c4SJohan Hedberg 3285ef8efe4bSJohan Hedberg static struct l2cap_chan *smp_add_cid(struct hci_dev *hdev, u16 cid) 3286711eafe3SJohan Hedberg { 328770db83c4SJohan Hedberg struct l2cap_chan *chan; 328888a479d9SMarcel Holtmann struct smp_dev *smp; 328971af2f6bSHerbert Xu struct crypto_shash *tfm_cmac; 329047eb2ac8STudor Ambarus struct crypto_kpp *tfm_ecdh; 329170db83c4SJohan Hedberg 3292ef8efe4bSJohan Hedberg if (cid == L2CAP_CID_SMP_BREDR) { 329388a479d9SMarcel Holtmann smp = NULL; 3294ef8efe4bSJohan Hedberg goto create_chan; 3295ef8efe4bSJohan Hedberg } 3296711eafe3SJohan Hedberg 329788a479d9SMarcel Holtmann smp = kzalloc(sizeof(*smp), GFP_KERNEL); 329888a479d9SMarcel Holtmann if (!smp) 329988a479d9SMarcel Holtmann return ERR_PTR(-ENOMEM); 330088a479d9SMarcel Holtmann 330171af2f6bSHerbert Xu tfm_cmac = crypto_alloc_shash("cmac(aes)", 0, 0); 33026e2dc6d1SMarcel Holtmann if (IS_ERR(tfm_cmac)) { 33032e1614f7SLuiz Augusto von Dentz bt_dev_err(hdev, "Unable to create CMAC crypto context"); 3304453431a5SWaiman Long kfree_sensitive(smp); 33056e2dc6d1SMarcel Holtmann return ERR_CAST(tfm_cmac); 33066e2dc6d1SMarcel Holtmann } 33076e2dc6d1SMarcel Holtmann 33086763f5eaSMeng Yu tfm_ecdh = crypto_alloc_kpp("ecdh-nist-p256", 0, 0); 330947eb2ac8STudor Ambarus if (IS_ERR(tfm_ecdh)) { 33102e1614f7SLuiz Augusto von Dentz bt_dev_err(hdev, "Unable to create ECDH crypto context"); 331147eb2ac8STudor Ambarus crypto_free_shash(tfm_cmac); 3312453431a5SWaiman Long kfree_sensitive(smp); 331347eb2ac8STudor Ambarus return ERR_CAST(tfm_ecdh); 331447eb2ac8STudor Ambarus } 331547eb2ac8STudor Ambarus 331694f14e47SJohan Hedberg smp->local_oob = false; 33176e2dc6d1SMarcel Holtmann smp->tfm_cmac = tfm_cmac; 331847eb2ac8STudor Ambarus smp->tfm_ecdh = tfm_ecdh; 331988a479d9SMarcel Holtmann 3320ef8efe4bSJohan Hedberg create_chan: 332170db83c4SJohan Hedberg chan = l2cap_chan_create(); 332270db83c4SJohan Hedberg if (!chan) { 332363511f6dSMarcel Holtmann if (smp) { 332471af2f6bSHerbert Xu crypto_free_shash(smp->tfm_cmac); 332547eb2ac8STudor Ambarus crypto_free_kpp(smp->tfm_ecdh); 3326453431a5SWaiman Long kfree_sensitive(smp); 332763511f6dSMarcel Holtmann } 3328ef8efe4bSJohan Hedberg return ERR_PTR(-ENOMEM); 332970db83c4SJohan Hedberg } 333070db83c4SJohan Hedberg 333188a479d9SMarcel Holtmann chan->data = smp; 3332defce9e8SJohan Hedberg 3333ef8efe4bSJohan Hedberg l2cap_add_scid(chan, cid); 333470db83c4SJohan Hedberg 333570db83c4SJohan Hedberg l2cap_chan_set_defaults(chan); 333670db83c4SJohan Hedberg 3337157029baSMarcel Holtmann if (cid == L2CAP_CID_SMP) { 333839e3e744SJohan Hedberg u8 bdaddr_type; 333939e3e744SJohan Hedberg 334039e3e744SJohan Hedberg hci_copy_identity_address(hdev, &chan->src, &bdaddr_type); 334139e3e744SJohan Hedberg 334239e3e744SJohan Hedberg if (bdaddr_type == ADDR_LE_DEV_PUBLIC) 334370db83c4SJohan Hedberg chan->src_type = BDADDR_LE_PUBLIC; 334439e3e744SJohan Hedberg else 334539e3e744SJohan Hedberg chan->src_type = BDADDR_LE_RANDOM; 3346157029baSMarcel Holtmann } else { 3347157029baSMarcel Holtmann bacpy(&chan->src, &hdev->bdaddr); 3348ef8efe4bSJohan Hedberg chan->src_type = BDADDR_BREDR; 3349157029baSMarcel Holtmann } 3350157029baSMarcel Holtmann 335170db83c4SJohan Hedberg chan->state = BT_LISTEN; 335270db83c4SJohan Hedberg chan->mode = L2CAP_MODE_BASIC; 335370db83c4SJohan Hedberg chan->imtu = L2CAP_DEFAULT_MTU; 335470db83c4SJohan Hedberg chan->ops = &smp_root_chan_ops; 335570db83c4SJohan Hedberg 3356abe84903SJohan Hedberg /* Set correct nesting level for a parent/listening channel */ 3357abe84903SJohan Hedberg atomic_set(&chan->nesting, L2CAP_NESTING_PARENT); 3358abe84903SJohan Hedberg 3359ef8efe4bSJohan Hedberg return chan; 3360711eafe3SJohan Hedberg } 3361711eafe3SJohan Hedberg 3362ef8efe4bSJohan Hedberg static void smp_del_chan(struct l2cap_chan *chan) 3363711eafe3SJohan Hedberg { 336488a479d9SMarcel Holtmann struct smp_dev *smp; 336570db83c4SJohan Hedberg 3366995fca15SLuiz Augusto von Dentz BT_DBG("chan %p", chan); 3367711eafe3SJohan Hedberg 336888a479d9SMarcel Holtmann smp = chan->data; 336988a479d9SMarcel Holtmann if (smp) { 3370defce9e8SJohan Hedberg chan->data = NULL; 337171af2f6bSHerbert Xu crypto_free_shash(smp->tfm_cmac); 337247eb2ac8STudor Ambarus crypto_free_kpp(smp->tfm_ecdh); 3373453431a5SWaiman Long kfree_sensitive(smp); 3374711eafe3SJohan Hedberg } 337570db83c4SJohan Hedberg 337670db83c4SJohan Hedberg l2cap_chan_put(chan); 3377711eafe3SJohan Hedberg } 3378ef8efe4bSJohan Hedberg 337982493316SClaire Chang int smp_force_bredr(struct hci_dev *hdev, bool enable) 3380300acfdeSMarcel Holtmann { 3381b7cb93e5SMarcel Holtmann if (enable == hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP)) 3382300acfdeSMarcel Holtmann return -EALREADY; 3383300acfdeSMarcel Holtmann 3384300acfdeSMarcel Holtmann if (enable) { 3385300acfdeSMarcel Holtmann struct l2cap_chan *chan; 3386300acfdeSMarcel Holtmann 3387300acfdeSMarcel Holtmann chan = smp_add_cid(hdev, L2CAP_CID_SMP_BREDR); 3388300acfdeSMarcel Holtmann if (IS_ERR(chan)) 3389300acfdeSMarcel Holtmann return PTR_ERR(chan); 3390300acfdeSMarcel Holtmann 3391300acfdeSMarcel Holtmann hdev->smp_bredr_data = chan; 3392300acfdeSMarcel Holtmann } else { 3393300acfdeSMarcel Holtmann struct l2cap_chan *chan; 3394300acfdeSMarcel Holtmann 3395300acfdeSMarcel Holtmann chan = hdev->smp_bredr_data; 3396300acfdeSMarcel Holtmann hdev->smp_bredr_data = NULL; 3397300acfdeSMarcel Holtmann smp_del_chan(chan); 3398300acfdeSMarcel Holtmann } 3399300acfdeSMarcel Holtmann 3400b7cb93e5SMarcel Holtmann hci_dev_change_flag(hdev, HCI_FORCE_BREDR_SMP); 3401300acfdeSMarcel Holtmann 340282493316SClaire Chang return 0; 3403300acfdeSMarcel Holtmann } 3404300acfdeSMarcel Holtmann 3405ef8efe4bSJohan Hedberg int smp_register(struct hci_dev *hdev) 3406ef8efe4bSJohan Hedberg { 3407ef8efe4bSJohan Hedberg struct l2cap_chan *chan; 3408ef8efe4bSJohan Hedberg 34092e1614f7SLuiz Augusto von Dentz bt_dev_dbg(hdev, ""); 3410ef8efe4bSJohan Hedberg 34117e7ec445SMarcel Holtmann /* If the controller does not support Low Energy operation, then 34127e7ec445SMarcel Holtmann * there is also no need to register any SMP channel. 34137e7ec445SMarcel Holtmann */ 34147e7ec445SMarcel Holtmann if (!lmp_le_capable(hdev)) 34157e7ec445SMarcel Holtmann return 0; 34167e7ec445SMarcel Holtmann 34172b8df323SMarcel Holtmann if (WARN_ON(hdev->smp_data)) { 34182b8df323SMarcel Holtmann chan = hdev->smp_data; 34192b8df323SMarcel Holtmann hdev->smp_data = NULL; 34202b8df323SMarcel Holtmann smp_del_chan(chan); 34212b8df323SMarcel Holtmann } 34222b8df323SMarcel Holtmann 3423ef8efe4bSJohan Hedberg chan = smp_add_cid(hdev, L2CAP_CID_SMP); 3424ef8efe4bSJohan Hedberg if (IS_ERR(chan)) 3425ef8efe4bSJohan Hedberg return PTR_ERR(chan); 3426ef8efe4bSJohan Hedberg 3427ef8efe4bSJohan Hedberg hdev->smp_data = chan; 3428ef8efe4bSJohan Hedberg 3429300acfdeSMarcel Holtmann if (!lmp_sc_capable(hdev)) { 343083ebb9ecSSzymon Janc /* Flag can be already set here (due to power toggle) */ 343183ebb9ecSSzymon Janc if (!hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP)) 3432ef8efe4bSJohan Hedberg return 0; 3433300acfdeSMarcel Holtmann } 3434ef8efe4bSJohan Hedberg 34352b8df323SMarcel Holtmann if (WARN_ON(hdev->smp_bredr_data)) { 34362b8df323SMarcel Holtmann chan = hdev->smp_bredr_data; 34372b8df323SMarcel Holtmann hdev->smp_bredr_data = NULL; 34382b8df323SMarcel Holtmann smp_del_chan(chan); 34392b8df323SMarcel Holtmann } 34402b8df323SMarcel Holtmann 3441ef8efe4bSJohan Hedberg chan = smp_add_cid(hdev, L2CAP_CID_SMP_BREDR); 3442ef8efe4bSJohan Hedberg if (IS_ERR(chan)) { 3443ef8efe4bSJohan Hedberg int err = PTR_ERR(chan); 3444ef8efe4bSJohan Hedberg chan = hdev->smp_data; 3445ef8efe4bSJohan Hedberg hdev->smp_data = NULL; 3446ef8efe4bSJohan Hedberg smp_del_chan(chan); 3447ef8efe4bSJohan Hedberg return err; 3448ef8efe4bSJohan Hedberg } 3449ef8efe4bSJohan Hedberg 3450ef8efe4bSJohan Hedberg hdev->smp_bredr_data = chan; 3451ef8efe4bSJohan Hedberg 3452ef8efe4bSJohan Hedberg return 0; 3453ef8efe4bSJohan Hedberg } 3454ef8efe4bSJohan Hedberg 3455ef8efe4bSJohan Hedberg void smp_unregister(struct hci_dev *hdev) 3456ef8efe4bSJohan Hedberg { 3457ef8efe4bSJohan Hedberg struct l2cap_chan *chan; 3458ef8efe4bSJohan Hedberg 3459ef8efe4bSJohan Hedberg if (hdev->smp_bredr_data) { 3460ef8efe4bSJohan Hedberg chan = hdev->smp_bredr_data; 3461ef8efe4bSJohan Hedberg hdev->smp_bredr_data = NULL; 3462ef8efe4bSJohan Hedberg smp_del_chan(chan); 3463ef8efe4bSJohan Hedberg } 3464ef8efe4bSJohan Hedberg 3465ef8efe4bSJohan Hedberg if (hdev->smp_data) { 3466ef8efe4bSJohan Hedberg chan = hdev->smp_data; 3467ef8efe4bSJohan Hedberg hdev->smp_data = NULL; 3468ef8efe4bSJohan Hedberg smp_del_chan(chan); 3469ef8efe4bSJohan Hedberg } 3470ef8efe4bSJohan Hedberg } 34710a2b0f04SJohan Hedberg 34720a2b0f04SJohan Hedberg #if IS_ENABLED(CONFIG_BT_SELFTEST_SMP) 34730a2b0f04SJohan Hedberg 347447eb2ac8STudor Ambarus static int __init test_debug_key(struct crypto_kpp *tfm_ecdh) 347571653eb6SMarcel Holtmann { 3476c0153b0bSTudor Ambarus u8 pk[64]; 3477a2976416STudor Ambarus int err; 347871653eb6SMarcel Holtmann 3479c0153b0bSTudor Ambarus err = set_ecdh_privkey(tfm_ecdh, debug_sk); 3480a2976416STudor Ambarus if (err) 3481a2976416STudor Ambarus return err; 348271653eb6SMarcel Holtmann 3483c0153b0bSTudor Ambarus err = generate_ecdh_public_key(tfm_ecdh, pk); 3484c0153b0bSTudor Ambarus if (err) 3485c0153b0bSTudor Ambarus return err; 348671653eb6SMarcel Holtmann 3487329d8230SJason A. Donenfeld if (crypto_memneq(pk, debug_pk, 64)) 348871653eb6SMarcel Holtmann return -EINVAL; 348971653eb6SMarcel Holtmann 349071653eb6SMarcel Holtmann return 0; 349171653eb6SMarcel Holtmann } 349271653eb6SMarcel Holtmann 349328a220aaSArd Biesheuvel static int __init test_ah(void) 3494cfc4198eSJohan Hedberg { 3495cfc4198eSJohan Hedberg const u8 irk[16] = { 3496cfc4198eSJohan Hedberg 0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34, 3497cfc4198eSJohan Hedberg 0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec }; 3498cfc4198eSJohan Hedberg const u8 r[3] = { 0x94, 0x81, 0x70 }; 3499cfc4198eSJohan Hedberg const u8 exp[3] = { 0xaa, 0xfb, 0x0d }; 3500cfc4198eSJohan Hedberg u8 res[3]; 3501cfc4198eSJohan Hedberg int err; 3502cfc4198eSJohan Hedberg 350328a220aaSArd Biesheuvel err = smp_ah(irk, r, res); 3504cfc4198eSJohan Hedberg if (err) 3505cfc4198eSJohan Hedberg return err; 3506cfc4198eSJohan Hedberg 3507329d8230SJason A. Donenfeld if (crypto_memneq(res, exp, 3)) 3508cfc4198eSJohan Hedberg return -EINVAL; 3509cfc4198eSJohan Hedberg 3510cfc4198eSJohan Hedberg return 0; 3511cfc4198eSJohan Hedberg } 3512cfc4198eSJohan Hedberg 351328a220aaSArd Biesheuvel static int __init test_c1(void) 3514cfc4198eSJohan Hedberg { 3515cfc4198eSJohan Hedberg const u8 k[16] = { 3516cfc4198eSJohan Hedberg 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3517cfc4198eSJohan Hedberg 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 3518cfc4198eSJohan Hedberg const u8 r[16] = { 3519cfc4198eSJohan Hedberg 0xe0, 0x2e, 0x70, 0xc6, 0x4e, 0x27, 0x88, 0x63, 3520cfc4198eSJohan Hedberg 0x0e, 0x6f, 0xad, 0x56, 0x21, 0xd5, 0x83, 0x57 }; 3521cfc4198eSJohan Hedberg const u8 preq[7] = { 0x01, 0x01, 0x00, 0x00, 0x10, 0x07, 0x07 }; 3522cfc4198eSJohan Hedberg const u8 pres[7] = { 0x02, 0x03, 0x00, 0x00, 0x08, 0x00, 0x05 }; 3523cfc4198eSJohan Hedberg const u8 _iat = 0x01; 3524cfc4198eSJohan Hedberg const u8 _rat = 0x00; 3525cfc4198eSJohan Hedberg const bdaddr_t ra = { { 0xb6, 0xb5, 0xb4, 0xb3, 0xb2, 0xb1 } }; 3526cfc4198eSJohan Hedberg const bdaddr_t ia = { { 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1 } }; 3527cfc4198eSJohan Hedberg const u8 exp[16] = { 3528cfc4198eSJohan Hedberg 0x86, 0x3b, 0xf1, 0xbe, 0xc5, 0x4d, 0xa7, 0xd2, 3529cfc4198eSJohan Hedberg 0xea, 0x88, 0x89, 0x87, 0xef, 0x3f, 0x1e, 0x1e }; 3530cfc4198eSJohan Hedberg u8 res[16]; 3531cfc4198eSJohan Hedberg int err; 3532cfc4198eSJohan Hedberg 353328a220aaSArd Biesheuvel err = smp_c1(k, r, preq, pres, _iat, &ia, _rat, &ra, res); 3534cfc4198eSJohan Hedberg if (err) 3535cfc4198eSJohan Hedberg return err; 3536cfc4198eSJohan Hedberg 3537329d8230SJason A. Donenfeld if (crypto_memneq(res, exp, 16)) 3538cfc4198eSJohan Hedberg return -EINVAL; 3539cfc4198eSJohan Hedberg 3540cfc4198eSJohan Hedberg return 0; 3541cfc4198eSJohan Hedberg } 3542cfc4198eSJohan Hedberg 354328a220aaSArd Biesheuvel static int __init test_s1(void) 3544cfc4198eSJohan Hedberg { 3545cfc4198eSJohan Hedberg const u8 k[16] = { 3546cfc4198eSJohan Hedberg 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3547cfc4198eSJohan Hedberg 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 3548cfc4198eSJohan Hedberg const u8 r1[16] = { 3549cfc4198eSJohan Hedberg 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 }; 3550cfc4198eSJohan Hedberg const u8 r2[16] = { 3551cfc4198eSJohan Hedberg 0x00, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99 }; 3552cfc4198eSJohan Hedberg const u8 exp[16] = { 3553cfc4198eSJohan Hedberg 0x62, 0xa0, 0x6d, 0x79, 0xae, 0x16, 0x42, 0x5b, 3554cfc4198eSJohan Hedberg 0x9b, 0xf4, 0xb0, 0xe8, 0xf0, 0xe1, 0x1f, 0x9a }; 3555cfc4198eSJohan Hedberg u8 res[16]; 3556cfc4198eSJohan Hedberg int err; 3557cfc4198eSJohan Hedberg 355828a220aaSArd Biesheuvel err = smp_s1(k, r1, r2, res); 3559cfc4198eSJohan Hedberg if (err) 3560cfc4198eSJohan Hedberg return err; 3561cfc4198eSJohan Hedberg 3562329d8230SJason A. Donenfeld if (crypto_memneq(res, exp, 16)) 3563cfc4198eSJohan Hedberg return -EINVAL; 3564cfc4198eSJohan Hedberg 3565cfc4198eSJohan Hedberg return 0; 3566cfc4198eSJohan Hedberg } 3567cfc4198eSJohan Hedberg 356871af2f6bSHerbert Xu static int __init test_f4(struct crypto_shash *tfm_cmac) 3569fb2969a3SJohan Hedberg { 3570fb2969a3SJohan Hedberg const u8 u[32] = { 3571fb2969a3SJohan Hedberg 0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc, 3572fb2969a3SJohan Hedberg 0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef, 3573fb2969a3SJohan Hedberg 0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e, 3574fb2969a3SJohan Hedberg 0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20 }; 3575fb2969a3SJohan Hedberg const u8 v[32] = { 3576fb2969a3SJohan Hedberg 0xfd, 0xc5, 0x7f, 0xf4, 0x49, 0xdd, 0x4f, 0x6b, 3577fb2969a3SJohan Hedberg 0xfb, 0x7c, 0x9d, 0xf1, 0xc2, 0x9a, 0xcb, 0x59, 3578fb2969a3SJohan Hedberg 0x2a, 0xe7, 0xd4, 0xee, 0xfb, 0xfc, 0x0a, 0x90, 3579fb2969a3SJohan Hedberg 0x9a, 0xbb, 0xf6, 0x32, 0x3d, 0x8b, 0x18, 0x55 }; 3580fb2969a3SJohan Hedberg const u8 x[16] = { 3581fb2969a3SJohan Hedberg 0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff, 3582fb2969a3SJohan Hedberg 0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 }; 3583fb2969a3SJohan Hedberg const u8 z = 0x00; 3584fb2969a3SJohan Hedberg const u8 exp[16] = { 3585fb2969a3SJohan Hedberg 0x2d, 0x87, 0x74, 0xa9, 0xbe, 0xa1, 0xed, 0xf1, 3586fb2969a3SJohan Hedberg 0x1c, 0xbd, 0xa9, 0x07, 0xf1, 0x16, 0xc9, 0xf2 }; 3587fb2969a3SJohan Hedberg u8 res[16]; 3588fb2969a3SJohan Hedberg int err; 3589fb2969a3SJohan Hedberg 3590fb2969a3SJohan Hedberg err = smp_f4(tfm_cmac, u, v, x, z, res); 3591fb2969a3SJohan Hedberg if (err) 3592fb2969a3SJohan Hedberg return err; 3593fb2969a3SJohan Hedberg 3594329d8230SJason A. Donenfeld if (crypto_memneq(res, exp, 16)) 3595fb2969a3SJohan Hedberg return -EINVAL; 3596fb2969a3SJohan Hedberg 3597fb2969a3SJohan Hedberg return 0; 3598fb2969a3SJohan Hedberg } 3599fb2969a3SJohan Hedberg 360071af2f6bSHerbert Xu static int __init test_f5(struct crypto_shash *tfm_cmac) 3601fb2969a3SJohan Hedberg { 3602fb2969a3SJohan Hedberg const u8 w[32] = { 3603fb2969a3SJohan Hedberg 0x98, 0xa6, 0xbf, 0x73, 0xf3, 0x34, 0x8d, 0x86, 3604fb2969a3SJohan Hedberg 0xf1, 0x66, 0xf8, 0xb4, 0x13, 0x6b, 0x79, 0x99, 3605fb2969a3SJohan Hedberg 0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34, 3606fb2969a3SJohan Hedberg 0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec }; 3607fb2969a3SJohan Hedberg const u8 n1[16] = { 3608fb2969a3SJohan Hedberg 0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff, 3609fb2969a3SJohan Hedberg 0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 }; 3610fb2969a3SJohan Hedberg const u8 n2[16] = { 3611fb2969a3SJohan Hedberg 0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21, 3612fb2969a3SJohan Hedberg 0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6 }; 3613fb2969a3SJohan Hedberg const u8 a1[7] = { 0xce, 0xbf, 0x37, 0x37, 0x12, 0x56, 0x00 }; 3614fb2969a3SJohan Hedberg const u8 a2[7] = { 0xc1, 0xcf, 0x2d, 0x70, 0x13, 0xa7, 0x00 }; 3615fb2969a3SJohan Hedberg const u8 exp_ltk[16] = { 3616fb2969a3SJohan Hedberg 0x38, 0x0a, 0x75, 0x94, 0xb5, 0x22, 0x05, 0x98, 3617fb2969a3SJohan Hedberg 0x23, 0xcd, 0xd7, 0x69, 0x11, 0x79, 0x86, 0x69 }; 3618fb2969a3SJohan Hedberg const u8 exp_mackey[16] = { 3619fb2969a3SJohan Hedberg 0x20, 0x6e, 0x63, 0xce, 0x20, 0x6a, 0x3f, 0xfd, 3620fb2969a3SJohan Hedberg 0x02, 0x4a, 0x08, 0xa1, 0x76, 0xf1, 0x65, 0x29 }; 3621fb2969a3SJohan Hedberg u8 mackey[16], ltk[16]; 3622fb2969a3SJohan Hedberg int err; 3623fb2969a3SJohan Hedberg 3624fb2969a3SJohan Hedberg err = smp_f5(tfm_cmac, w, n1, n2, a1, a2, mackey, ltk); 3625fb2969a3SJohan Hedberg if (err) 3626fb2969a3SJohan Hedberg return err; 3627fb2969a3SJohan Hedberg 3628329d8230SJason A. Donenfeld if (crypto_memneq(mackey, exp_mackey, 16)) 3629fb2969a3SJohan Hedberg return -EINVAL; 3630fb2969a3SJohan Hedberg 3631329d8230SJason A. Donenfeld if (crypto_memneq(ltk, exp_ltk, 16)) 3632fb2969a3SJohan Hedberg return -EINVAL; 3633fb2969a3SJohan Hedberg 3634fb2969a3SJohan Hedberg return 0; 3635fb2969a3SJohan Hedberg } 3636fb2969a3SJohan Hedberg 363771af2f6bSHerbert Xu static int __init test_f6(struct crypto_shash *tfm_cmac) 3638fb2969a3SJohan Hedberg { 3639fb2969a3SJohan Hedberg const u8 w[16] = { 3640fb2969a3SJohan Hedberg 0x20, 0x6e, 0x63, 0xce, 0x20, 0x6a, 0x3f, 0xfd, 3641fb2969a3SJohan Hedberg 0x02, 0x4a, 0x08, 0xa1, 0x76, 0xf1, 0x65, 0x29 }; 3642fb2969a3SJohan Hedberg const u8 n1[16] = { 3643fb2969a3SJohan Hedberg 0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff, 3644fb2969a3SJohan Hedberg 0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 }; 3645fb2969a3SJohan Hedberg const u8 n2[16] = { 3646fb2969a3SJohan Hedberg 0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21, 3647fb2969a3SJohan Hedberg 0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6 }; 3648fb2969a3SJohan Hedberg const u8 r[16] = { 3649fb2969a3SJohan Hedberg 0xc8, 0x0f, 0x2d, 0x0c, 0xd2, 0x42, 0xda, 0x08, 3650fb2969a3SJohan Hedberg 0x54, 0xbb, 0x53, 0xb4, 0x3b, 0x34, 0xa3, 0x12 }; 3651fb2969a3SJohan Hedberg const u8 io_cap[3] = { 0x02, 0x01, 0x01 }; 3652fb2969a3SJohan Hedberg const u8 a1[7] = { 0xce, 0xbf, 0x37, 0x37, 0x12, 0x56, 0x00 }; 3653fb2969a3SJohan Hedberg const u8 a2[7] = { 0xc1, 0xcf, 0x2d, 0x70, 0x13, 0xa7, 0x00 }; 3654fb2969a3SJohan Hedberg const u8 exp[16] = { 3655fb2969a3SJohan Hedberg 0x61, 0x8f, 0x95, 0xda, 0x09, 0x0b, 0x6c, 0xd2, 3656fb2969a3SJohan Hedberg 0xc5, 0xe8, 0xd0, 0x9c, 0x98, 0x73, 0xc4, 0xe3 }; 3657fb2969a3SJohan Hedberg u8 res[16]; 3658fb2969a3SJohan Hedberg int err; 3659fb2969a3SJohan Hedberg 3660fb2969a3SJohan Hedberg err = smp_f6(tfm_cmac, w, n1, n2, r, io_cap, a1, a2, res); 3661fb2969a3SJohan Hedberg if (err) 3662fb2969a3SJohan Hedberg return err; 3663fb2969a3SJohan Hedberg 3664329d8230SJason A. Donenfeld if (crypto_memneq(res, exp, 16)) 3665fb2969a3SJohan Hedberg return -EINVAL; 3666fb2969a3SJohan Hedberg 3667fb2969a3SJohan Hedberg return 0; 3668fb2969a3SJohan Hedberg } 3669fb2969a3SJohan Hedberg 367071af2f6bSHerbert Xu static int __init test_g2(struct crypto_shash *tfm_cmac) 3671fb2969a3SJohan Hedberg { 3672fb2969a3SJohan Hedberg const u8 u[32] = { 3673fb2969a3SJohan Hedberg 0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc, 3674fb2969a3SJohan Hedberg 0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef, 3675fb2969a3SJohan Hedberg 0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e, 3676fb2969a3SJohan Hedberg 0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20 }; 3677fb2969a3SJohan Hedberg const u8 v[32] = { 3678fb2969a3SJohan Hedberg 0xfd, 0xc5, 0x7f, 0xf4, 0x49, 0xdd, 0x4f, 0x6b, 3679fb2969a3SJohan Hedberg 0xfb, 0x7c, 0x9d, 0xf1, 0xc2, 0x9a, 0xcb, 0x59, 3680fb2969a3SJohan Hedberg 0x2a, 0xe7, 0xd4, 0xee, 0xfb, 0xfc, 0x0a, 0x90, 3681fb2969a3SJohan Hedberg 0x9a, 0xbb, 0xf6, 0x32, 0x3d, 0x8b, 0x18, 0x55 }; 3682fb2969a3SJohan Hedberg const u8 x[16] = { 3683fb2969a3SJohan Hedberg 0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff, 3684fb2969a3SJohan Hedberg 0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 }; 3685fb2969a3SJohan Hedberg const u8 y[16] = { 3686fb2969a3SJohan Hedberg 0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21, 3687fb2969a3SJohan Hedberg 0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6 }; 3688fb2969a3SJohan Hedberg const u32 exp_val = 0x2f9ed5ba % 1000000; 3689fb2969a3SJohan Hedberg u32 val; 3690fb2969a3SJohan Hedberg int err; 3691fb2969a3SJohan Hedberg 3692fb2969a3SJohan Hedberg err = smp_g2(tfm_cmac, u, v, x, y, &val); 3693fb2969a3SJohan Hedberg if (err) 3694fb2969a3SJohan Hedberg return err; 3695fb2969a3SJohan Hedberg 3696fb2969a3SJohan Hedberg if (val != exp_val) 3697fb2969a3SJohan Hedberg return -EINVAL; 3698fb2969a3SJohan Hedberg 3699fb2969a3SJohan Hedberg return 0; 3700fb2969a3SJohan Hedberg } 3701fb2969a3SJohan Hedberg 370271af2f6bSHerbert Xu static int __init test_h6(struct crypto_shash *tfm_cmac) 3703fb2969a3SJohan Hedberg { 3704fb2969a3SJohan Hedberg const u8 w[16] = { 3705fb2969a3SJohan Hedberg 0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34, 3706fb2969a3SJohan Hedberg 0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec }; 3707fb2969a3SJohan Hedberg const u8 key_id[4] = { 0x72, 0x62, 0x65, 0x6c }; 3708fb2969a3SJohan Hedberg const u8 exp[16] = { 3709fb2969a3SJohan Hedberg 0x99, 0x63, 0xb1, 0x80, 0xe2, 0xa9, 0xd3, 0xe8, 3710fb2969a3SJohan Hedberg 0x1c, 0xc9, 0x6d, 0xe7, 0x02, 0xe1, 0x9a, 0x2d }; 3711fb2969a3SJohan Hedberg u8 res[16]; 3712fb2969a3SJohan Hedberg int err; 3713fb2969a3SJohan Hedberg 3714fb2969a3SJohan Hedberg err = smp_h6(tfm_cmac, w, key_id, res); 3715fb2969a3SJohan Hedberg if (err) 3716fb2969a3SJohan Hedberg return err; 3717fb2969a3SJohan Hedberg 3718329d8230SJason A. Donenfeld if (crypto_memneq(res, exp, 16)) 3719fb2969a3SJohan Hedberg return -EINVAL; 3720fb2969a3SJohan Hedberg 3721fb2969a3SJohan Hedberg return 0; 3722fb2969a3SJohan Hedberg } 3723fb2969a3SJohan Hedberg 372464dd374eSMarcel Holtmann static char test_smp_buffer[32]; 372564dd374eSMarcel Holtmann 372664dd374eSMarcel Holtmann static ssize_t test_smp_read(struct file *file, char __user *user_buf, 372764dd374eSMarcel Holtmann size_t count, loff_t *ppos) 372864dd374eSMarcel Holtmann { 372964dd374eSMarcel Holtmann return simple_read_from_buffer(user_buf, count, ppos, test_smp_buffer, 373064dd374eSMarcel Holtmann strlen(test_smp_buffer)); 373164dd374eSMarcel Holtmann } 373264dd374eSMarcel Holtmann 373364dd374eSMarcel Holtmann static const struct file_operations test_smp_fops = { 373464dd374eSMarcel Holtmann .open = simple_open, 373564dd374eSMarcel Holtmann .read = test_smp_read, 373664dd374eSMarcel Holtmann .llseek = default_llseek, 373764dd374eSMarcel Holtmann }; 373864dd374eSMarcel Holtmann 373928a220aaSArd Biesheuvel static int __init run_selftests(struct crypto_shash *tfm_cmac, 374047eb2ac8STudor Ambarus struct crypto_kpp *tfm_ecdh) 37410a2b0f04SJohan Hedberg { 3742255047b0SMarcel Holtmann ktime_t calltime, delta, rettime; 3743255047b0SMarcel Holtmann unsigned long long duration; 3744cfc4198eSJohan Hedberg int err; 3745cfc4198eSJohan Hedberg 3746255047b0SMarcel Holtmann calltime = ktime_get(); 3747255047b0SMarcel Holtmann 374847eb2ac8STudor Ambarus err = test_debug_key(tfm_ecdh); 374971653eb6SMarcel Holtmann if (err) { 375071653eb6SMarcel Holtmann BT_ERR("debug_key test failed"); 375171653eb6SMarcel Holtmann goto done; 375271653eb6SMarcel Holtmann } 375371653eb6SMarcel Holtmann 375428a220aaSArd Biesheuvel err = test_ah(); 3755cfc4198eSJohan Hedberg if (err) { 3756cfc4198eSJohan Hedberg BT_ERR("smp_ah test failed"); 375764dd374eSMarcel Holtmann goto done; 3758cfc4198eSJohan Hedberg } 3759cfc4198eSJohan Hedberg 376028a220aaSArd Biesheuvel err = test_c1(); 3761cfc4198eSJohan Hedberg if (err) { 3762cfc4198eSJohan Hedberg BT_ERR("smp_c1 test failed"); 376364dd374eSMarcel Holtmann goto done; 3764cfc4198eSJohan Hedberg } 3765cfc4198eSJohan Hedberg 376628a220aaSArd Biesheuvel err = test_s1(); 3767cfc4198eSJohan Hedberg if (err) { 3768cfc4198eSJohan Hedberg BT_ERR("smp_s1 test failed"); 376964dd374eSMarcel Holtmann goto done; 3770cfc4198eSJohan Hedberg } 3771cfc4198eSJohan Hedberg 3772fb2969a3SJohan Hedberg err = test_f4(tfm_cmac); 3773fb2969a3SJohan Hedberg if (err) { 3774fb2969a3SJohan Hedberg BT_ERR("smp_f4 test failed"); 377564dd374eSMarcel Holtmann goto done; 3776fb2969a3SJohan Hedberg } 3777fb2969a3SJohan Hedberg 3778fb2969a3SJohan Hedberg err = test_f5(tfm_cmac); 3779fb2969a3SJohan Hedberg if (err) { 3780fb2969a3SJohan Hedberg BT_ERR("smp_f5 test failed"); 378164dd374eSMarcel Holtmann goto done; 3782fb2969a3SJohan Hedberg } 3783fb2969a3SJohan Hedberg 3784fb2969a3SJohan Hedberg err = test_f6(tfm_cmac); 3785fb2969a3SJohan Hedberg if (err) { 3786fb2969a3SJohan Hedberg BT_ERR("smp_f6 test failed"); 378764dd374eSMarcel Holtmann goto done; 3788fb2969a3SJohan Hedberg } 3789fb2969a3SJohan Hedberg 3790fb2969a3SJohan Hedberg err = test_g2(tfm_cmac); 3791fb2969a3SJohan Hedberg if (err) { 3792fb2969a3SJohan Hedberg BT_ERR("smp_g2 test failed"); 379364dd374eSMarcel Holtmann goto done; 3794fb2969a3SJohan Hedberg } 3795fb2969a3SJohan Hedberg 3796fb2969a3SJohan Hedberg err = test_h6(tfm_cmac); 3797fb2969a3SJohan Hedberg if (err) { 3798fb2969a3SJohan Hedberg BT_ERR("smp_h6 test failed"); 379964dd374eSMarcel Holtmann goto done; 3800fb2969a3SJohan Hedberg } 3801fb2969a3SJohan Hedberg 3802255047b0SMarcel Holtmann rettime = ktime_get(); 3803255047b0SMarcel Holtmann delta = ktime_sub(rettime, calltime); 3804255047b0SMarcel Holtmann duration = (unsigned long long) ktime_to_ns(delta) >> 10; 3805255047b0SMarcel Holtmann 38065ced2464SMarcel Holtmann BT_INFO("SMP test passed in %llu usecs", duration); 38070a2b0f04SJohan Hedberg 380864dd374eSMarcel Holtmann done: 380964dd374eSMarcel Holtmann if (!err) 381064dd374eSMarcel Holtmann snprintf(test_smp_buffer, sizeof(test_smp_buffer), 381164dd374eSMarcel Holtmann "PASS (%llu usecs)\n", duration); 381264dd374eSMarcel Holtmann else 381364dd374eSMarcel Holtmann snprintf(test_smp_buffer, sizeof(test_smp_buffer), "FAIL\n"); 381464dd374eSMarcel Holtmann 381564dd374eSMarcel Holtmann debugfs_create_file("selftest_smp", 0444, bt_debugfs, NULL, 381664dd374eSMarcel Holtmann &test_smp_fops); 381764dd374eSMarcel Holtmann 381864dd374eSMarcel Holtmann return err; 38190a2b0f04SJohan Hedberg } 38200a2b0f04SJohan Hedberg 38210a2b0f04SJohan Hedberg int __init bt_selftest_smp(void) 38220a2b0f04SJohan Hedberg { 382371af2f6bSHerbert Xu struct crypto_shash *tfm_cmac; 382447eb2ac8STudor Ambarus struct crypto_kpp *tfm_ecdh; 38250a2b0f04SJohan Hedberg int err; 38260a2b0f04SJohan Hedberg 38273d234b33SEric Biggers tfm_cmac = crypto_alloc_shash("cmac(aes)", 0, 0); 38280a2b0f04SJohan Hedberg if (IS_ERR(tfm_cmac)) { 38290a2b0f04SJohan Hedberg BT_ERR("Unable to create CMAC crypto context"); 38300a2b0f04SJohan Hedberg return PTR_ERR(tfm_cmac); 38310a2b0f04SJohan Hedberg } 38320a2b0f04SJohan Hedberg 38336763f5eaSMeng Yu tfm_ecdh = crypto_alloc_kpp("ecdh-nist-p256", 0, 0); 383447eb2ac8STudor Ambarus if (IS_ERR(tfm_ecdh)) { 383547eb2ac8STudor Ambarus BT_ERR("Unable to create ECDH crypto context"); 383647eb2ac8STudor Ambarus crypto_free_shash(tfm_cmac); 383747eb2ac8STudor Ambarus return PTR_ERR(tfm_ecdh); 383847eb2ac8STudor Ambarus } 383947eb2ac8STudor Ambarus 384028a220aaSArd Biesheuvel err = run_selftests(tfm_cmac, tfm_ecdh); 38410a2b0f04SJohan Hedberg 384271af2f6bSHerbert Xu crypto_free_shash(tfm_cmac); 384347eb2ac8STudor Ambarus crypto_free_kpp(tfm_ecdh); 38440a2b0f04SJohan Hedberg 38450a2b0f04SJohan Hedberg return err; 38460a2b0f04SJohan Hedberg } 38470a2b0f04SJohan Hedberg 38480a2b0f04SJohan Hedberg #endif 3849