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/crypto.h> 258c520a59SGustavo Padovan #include <linux/scatterlist.h> 268c520a59SGustavo Padovan #include <crypto/b128ops.h> 278c520a59SGustavo Padovan 28eb492e01SAnderson Briglia #include <net/bluetooth/bluetooth.h> 29eb492e01SAnderson Briglia #include <net/bluetooth/hci_core.h> 30eb492e01SAnderson Briglia #include <net/bluetooth/l2cap.h> 312b64d153SBrian Gix #include <net/bluetooth/mgmt.h> 32ac4b7236SMarcel Holtmann 333b19146dSJohan Hedberg #include "ecc.h" 34ac4b7236SMarcel Holtmann #include "smp.h" 35d22ef0bcSAnderson Briglia 36c7a3d57dSJohan Hedberg /* Low-level debug macros to be used for stuff that we don't want 37c7a3d57dSJohan Hedberg * accidentially in dmesg, i.e. the values of the various crypto keys 38c7a3d57dSJohan Hedberg * and the inputs & outputs of crypto functions. 39c7a3d57dSJohan Hedberg */ 40c7a3d57dSJohan Hedberg #ifdef DEBUG 41c7a3d57dSJohan Hedberg #define SMP_DBG(fmt, ...) printk(KERN_DEBUG "%s: " fmt, __func__, \ 42c7a3d57dSJohan Hedberg ##__VA_ARGS__) 43c7a3d57dSJohan Hedberg #else 44c7a3d57dSJohan Hedberg #define SMP_DBG(fmt, ...) no_printk(KERN_DEBUG "%s: " fmt, __func__, \ 45c7a3d57dSJohan Hedberg ##__VA_ARGS__) 46c7a3d57dSJohan Hedberg #endif 47c7a3d57dSJohan Hedberg 48b28b4943SJohan Hedberg #define SMP_ALLOW_CMD(smp, code) set_bit(code, &smp->allow_cmd) 49b28b4943SJohan Hedberg 503b19146dSJohan Hedberg /* Keys which are not distributed with Secure Connections */ 513b19146dSJohan Hedberg #define SMP_SC_NO_DIST (SMP_DIST_ENC_KEY | SMP_DIST_LINK_KEY); 523b19146dSJohan Hedberg 5317b02e62SMarcel Holtmann #define SMP_TIMEOUT msecs_to_jiffies(30000) 545d3de7dfSVinicius Costa Gomes 55d7a5a11dSMarcel Holtmann #define AUTH_REQ_MASK(dev) (hci_dev_test_flag(dev, HCI_SC_ENABLED) ? \ 560edb14deSJohan Hedberg 0x1f : 0x07) 5788d3a8acSJohan Hedberg #define KEY_DIST_MASK 0x07 58065a13e2SJohan Hedberg 59cbbbe3e2SJohan Hedberg /* Maximum message length that can be passed to aes_cmac */ 60cbbbe3e2SJohan Hedberg #define CMAC_MSG_MAX 80 61cbbbe3e2SJohan Hedberg 62533e35d4SJohan Hedberg enum { 63533e35d4SJohan Hedberg SMP_FLAG_TK_VALID, 64533e35d4SJohan Hedberg SMP_FLAG_CFM_PENDING, 65533e35d4SJohan Hedberg SMP_FLAG_MITM_AUTH, 66533e35d4SJohan Hedberg SMP_FLAG_COMPLETE, 67533e35d4SJohan Hedberg SMP_FLAG_INITIATOR, 6865668776SJohan Hedberg SMP_FLAG_SC, 69d8f8edbeSJohan Hedberg SMP_FLAG_REMOTE_PK, 70aeb7d461SJohan Hedberg SMP_FLAG_DEBUG_KEY, 7138606f14SJohan Hedberg SMP_FLAG_WAIT_USER, 72d3e54a87SJohan Hedberg SMP_FLAG_DHKEY_PENDING, 731a8bab4fSJohan Hedberg SMP_FLAG_REMOTE_OOB, 741a8bab4fSJohan Hedberg SMP_FLAG_LOCAL_OOB, 75533e35d4SJohan Hedberg }; 764bc58f51SJohan Hedberg 7788a479d9SMarcel Holtmann struct smp_dev { 7860a27d65SMarcel Holtmann /* Secure Connections OOB data */ 7960a27d65SMarcel Holtmann u8 local_pk[64]; 8060a27d65SMarcel Holtmann u8 local_sk[32]; 8160a27d65SMarcel Holtmann u8 local_rr[16]; 8260a27d65SMarcel Holtmann bool debug_key; 8360a27d65SMarcel Holtmann 8488a479d9SMarcel Holtmann struct crypto_blkcipher *tfm_aes; 856e2dc6d1SMarcel Holtmann struct crypto_hash *tfm_cmac; 8688a479d9SMarcel Holtmann }; 8788a479d9SMarcel Holtmann 884bc58f51SJohan Hedberg struct smp_chan { 894bc58f51SJohan Hedberg struct l2cap_conn *conn; 90b68fda68SJohan Hedberg struct delayed_work security_timer; 91b28b4943SJohan Hedberg unsigned long allow_cmd; /* Bitmask of allowed commands */ 92b68fda68SJohan Hedberg 934bc58f51SJohan Hedberg u8 preq[7]; /* SMP Pairing Request */ 944bc58f51SJohan Hedberg u8 prsp[7]; /* SMP Pairing Response */ 954bc58f51SJohan Hedberg u8 prnd[16]; /* SMP Pairing Random (local) */ 964bc58f51SJohan Hedberg u8 rrnd[16]; /* SMP Pairing Random (remote) */ 974bc58f51SJohan Hedberg u8 pcnf[16]; /* SMP Pairing Confirm */ 984bc58f51SJohan Hedberg u8 tk[16]; /* SMP Temporary Key */ 99882fafadSJohan Hedberg u8 rr[16]; /* Remote OOB ra/rb value */ 100882fafadSJohan Hedberg u8 lr[16]; /* Local OOB ra/rb value */ 1014bc58f51SJohan Hedberg u8 enc_key_size; 1024bc58f51SJohan Hedberg u8 remote_key_dist; 1034bc58f51SJohan Hedberg bdaddr_t id_addr; 1044bc58f51SJohan Hedberg u8 id_addr_type; 1054bc58f51SJohan Hedberg u8 irk[16]; 1064bc58f51SJohan Hedberg struct smp_csrk *csrk; 1074bc58f51SJohan Hedberg struct smp_csrk *slave_csrk; 1084bc58f51SJohan Hedberg struct smp_ltk *ltk; 1094bc58f51SJohan Hedberg struct smp_ltk *slave_ltk; 1104bc58f51SJohan Hedberg struct smp_irk *remote_irk; 1116a77083aSJohan Hedberg u8 *link_key; 1124a74d658SJohan Hedberg unsigned long flags; 113783e0574SJohan Hedberg u8 method; 11438606f14SJohan Hedberg u8 passkey_round; 1156a7bd103SJohan Hedberg 1163b19146dSJohan Hedberg /* Secure Connections variables */ 1173b19146dSJohan Hedberg u8 local_pk[64]; 1183b19146dSJohan Hedberg u8 local_sk[32]; 119d8f8edbeSJohan Hedberg u8 remote_pk[64]; 120d8f8edbeSJohan Hedberg u8 dhkey[32]; 121760b018bSJohan Hedberg u8 mackey[16]; 1223b19146dSJohan Hedberg 1236a7bd103SJohan Hedberg struct crypto_blkcipher *tfm_aes; 124407cecf6SJohan Hedberg struct crypto_hash *tfm_cmac; 1254bc58f51SJohan Hedberg }; 1264bc58f51SJohan Hedberg 127aeb7d461SJohan Hedberg /* These debug key values are defined in the SMP section of the core 128aeb7d461SJohan Hedberg * specification. debug_pk is the public debug key and debug_sk the 129aeb7d461SJohan Hedberg * private debug key. 130aeb7d461SJohan Hedberg */ 131aeb7d461SJohan Hedberg static const u8 debug_pk[64] = { 132aeb7d461SJohan Hedberg 0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc, 133aeb7d461SJohan Hedberg 0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef, 134aeb7d461SJohan Hedberg 0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e, 135aeb7d461SJohan Hedberg 0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20, 136aeb7d461SJohan Hedberg 137aeb7d461SJohan Hedberg 0x8b, 0xd2, 0x89, 0x15, 0xd0, 0x8e, 0x1c, 0x74, 138aeb7d461SJohan Hedberg 0x24, 0x30, 0xed, 0x8f, 0xc2, 0x45, 0x63, 0x76, 139aeb7d461SJohan Hedberg 0x5c, 0x15, 0x52, 0x5a, 0xbf, 0x9a, 0x32, 0x63, 140aeb7d461SJohan Hedberg 0x6d, 0xeb, 0x2a, 0x65, 0x49, 0x9c, 0x80, 0xdc, 141aeb7d461SJohan Hedberg }; 142aeb7d461SJohan Hedberg 143aeb7d461SJohan Hedberg static const u8 debug_sk[32] = { 144aeb7d461SJohan Hedberg 0xbd, 0x1a, 0x3c, 0xcd, 0xa6, 0xb8, 0x99, 0x58, 145aeb7d461SJohan Hedberg 0x99, 0xb7, 0x40, 0xeb, 0x7b, 0x60, 0xff, 0x4a, 146aeb7d461SJohan Hedberg 0x50, 0x3f, 0x10, 0xd2, 0xe3, 0xb3, 0xc9, 0x74, 147aeb7d461SJohan Hedberg 0x38, 0x5f, 0xc5, 0xa3, 0xd4, 0xf6, 0x49, 0x3f, 148aeb7d461SJohan Hedberg }; 149aeb7d461SJohan Hedberg 1508a2936f4SJohan Hedberg static inline void swap_buf(const u8 *src, u8 *dst, size_t len) 151d22ef0bcSAnderson Briglia { 1528a2936f4SJohan Hedberg size_t i; 153d22ef0bcSAnderson Briglia 1548a2936f4SJohan Hedberg for (i = 0; i < len; i++) 1558a2936f4SJohan Hedberg dst[len - 1 - i] = src[i]; 156d22ef0bcSAnderson Briglia } 157d22ef0bcSAnderson Briglia 15806edf8deSJohan Hedberg /* The following functions map to the LE SC SMP crypto functions 15906edf8deSJohan Hedberg * AES-CMAC, f4, f5, f6, g2 and h6. 16006edf8deSJohan Hedberg */ 16106edf8deSJohan Hedberg 162cbbbe3e2SJohan Hedberg static int aes_cmac(struct crypto_hash *tfm, const u8 k[16], const u8 *m, 163cbbbe3e2SJohan Hedberg size_t len, u8 mac[16]) 164cbbbe3e2SJohan Hedberg { 165cbbbe3e2SJohan Hedberg uint8_t tmp[16], mac_msb[16], msg_msb[CMAC_MSG_MAX]; 166cbbbe3e2SJohan Hedberg struct hash_desc desc; 167cbbbe3e2SJohan Hedberg struct scatterlist sg; 168cbbbe3e2SJohan Hedberg int err; 169cbbbe3e2SJohan Hedberg 170cbbbe3e2SJohan Hedberg if (len > CMAC_MSG_MAX) 171cbbbe3e2SJohan Hedberg return -EFBIG; 172cbbbe3e2SJohan Hedberg 173cbbbe3e2SJohan Hedberg if (!tfm) { 174cbbbe3e2SJohan Hedberg BT_ERR("tfm %p", tfm); 175cbbbe3e2SJohan Hedberg return -EINVAL; 176cbbbe3e2SJohan Hedberg } 177cbbbe3e2SJohan Hedberg 178cbbbe3e2SJohan Hedberg desc.tfm = tfm; 179cbbbe3e2SJohan Hedberg desc.flags = 0; 180cbbbe3e2SJohan Hedberg 181cbbbe3e2SJohan Hedberg crypto_hash_init(&desc); 182cbbbe3e2SJohan Hedberg 183cbbbe3e2SJohan Hedberg /* Swap key and message from LSB to MSB */ 184cbbbe3e2SJohan Hedberg swap_buf(k, tmp, 16); 185cbbbe3e2SJohan Hedberg swap_buf(m, msg_msb, len); 186cbbbe3e2SJohan Hedberg 187c7a3d57dSJohan Hedberg SMP_DBG("msg (len %zu) %*phN", len, (int) len, m); 188c7a3d57dSJohan Hedberg SMP_DBG("key %16phN", k); 189cbbbe3e2SJohan Hedberg 190cbbbe3e2SJohan Hedberg err = crypto_hash_setkey(tfm, tmp, 16); 191cbbbe3e2SJohan Hedberg if (err) { 192cbbbe3e2SJohan Hedberg BT_ERR("cipher setkey failed: %d", err); 193cbbbe3e2SJohan Hedberg return err; 194cbbbe3e2SJohan Hedberg } 195cbbbe3e2SJohan Hedberg 196cbbbe3e2SJohan Hedberg sg_init_one(&sg, msg_msb, len); 197cbbbe3e2SJohan Hedberg 198cbbbe3e2SJohan Hedberg err = crypto_hash_update(&desc, &sg, len); 199cbbbe3e2SJohan Hedberg if (err) { 200cbbbe3e2SJohan Hedberg BT_ERR("Hash update error %d", err); 201cbbbe3e2SJohan Hedberg return err; 202cbbbe3e2SJohan Hedberg } 203cbbbe3e2SJohan Hedberg 204cbbbe3e2SJohan Hedberg err = crypto_hash_final(&desc, mac_msb); 205cbbbe3e2SJohan Hedberg if (err) { 206cbbbe3e2SJohan Hedberg BT_ERR("Hash final error %d", err); 207cbbbe3e2SJohan Hedberg return err; 208cbbbe3e2SJohan Hedberg } 209cbbbe3e2SJohan Hedberg 210cbbbe3e2SJohan Hedberg swap_buf(mac_msb, mac, 16); 211cbbbe3e2SJohan Hedberg 212c7a3d57dSJohan Hedberg SMP_DBG("mac %16phN", mac); 213cbbbe3e2SJohan Hedberg 214cbbbe3e2SJohan Hedberg return 0; 215cbbbe3e2SJohan Hedberg } 216cbbbe3e2SJohan Hedberg 217cbbbe3e2SJohan Hedberg static int smp_f4(struct crypto_hash *tfm_cmac, const u8 u[32], const u8 v[32], 218cbbbe3e2SJohan Hedberg const u8 x[16], u8 z, u8 res[16]) 219cbbbe3e2SJohan Hedberg { 220cbbbe3e2SJohan Hedberg u8 m[65]; 221cbbbe3e2SJohan Hedberg int err; 222cbbbe3e2SJohan Hedberg 223c7a3d57dSJohan Hedberg SMP_DBG("u %32phN", u); 224c7a3d57dSJohan Hedberg SMP_DBG("v %32phN", v); 225c7a3d57dSJohan Hedberg SMP_DBG("x %16phN z %02x", x, z); 226cbbbe3e2SJohan Hedberg 227cbbbe3e2SJohan Hedberg m[0] = z; 228cbbbe3e2SJohan Hedberg memcpy(m + 1, v, 32); 229cbbbe3e2SJohan Hedberg memcpy(m + 33, u, 32); 230cbbbe3e2SJohan Hedberg 231cbbbe3e2SJohan Hedberg err = aes_cmac(tfm_cmac, x, m, sizeof(m), res); 232cbbbe3e2SJohan Hedberg if (err) 233cbbbe3e2SJohan Hedberg return err; 234cbbbe3e2SJohan Hedberg 235c7a3d57dSJohan Hedberg SMP_DBG("res %16phN", res); 236cbbbe3e2SJohan Hedberg 237cbbbe3e2SJohan Hedberg return err; 238cbbbe3e2SJohan Hedberg } 239cbbbe3e2SJohan Hedberg 2404da50de8SJohan Hedberg static int smp_f5(struct crypto_hash *tfm_cmac, const u8 w[32], 2414da50de8SJohan Hedberg const u8 n1[16], const u8 n2[16], const u8 a1[7], 2424da50de8SJohan Hedberg const u8 a2[7], u8 mackey[16], u8 ltk[16]) 243760b018bSJohan Hedberg { 244760b018bSJohan Hedberg /* The btle, salt and length "magic" values are as defined in 245760b018bSJohan Hedberg * the SMP section of the Bluetooth core specification. In ASCII 246760b018bSJohan Hedberg * the btle value ends up being 'btle'. The salt is just a 247760b018bSJohan Hedberg * random number whereas length is the value 256 in little 248760b018bSJohan Hedberg * endian format. 249760b018bSJohan Hedberg */ 250760b018bSJohan Hedberg const u8 btle[4] = { 0x65, 0x6c, 0x74, 0x62 }; 251760b018bSJohan Hedberg const u8 salt[16] = { 0xbe, 0x83, 0x60, 0x5a, 0xdb, 0x0b, 0x37, 0x60, 252760b018bSJohan Hedberg 0x38, 0xa5, 0xf5, 0xaa, 0x91, 0x83, 0x88, 0x6c }; 253760b018bSJohan Hedberg const u8 length[2] = { 0x00, 0x01 }; 254760b018bSJohan Hedberg u8 m[53], t[16]; 255760b018bSJohan Hedberg int err; 256760b018bSJohan Hedberg 257c7a3d57dSJohan Hedberg SMP_DBG("w %32phN", w); 258c7a3d57dSJohan Hedberg SMP_DBG("n1 %16phN n2 %16phN", n1, n2); 259c7a3d57dSJohan Hedberg SMP_DBG("a1 %7phN a2 %7phN", a1, a2); 260760b018bSJohan Hedberg 261760b018bSJohan Hedberg err = aes_cmac(tfm_cmac, salt, w, 32, t); 262760b018bSJohan Hedberg if (err) 263760b018bSJohan Hedberg return err; 264760b018bSJohan Hedberg 265c7a3d57dSJohan Hedberg SMP_DBG("t %16phN", t); 266760b018bSJohan Hedberg 267760b018bSJohan Hedberg memcpy(m, length, 2); 268760b018bSJohan Hedberg memcpy(m + 2, a2, 7); 269760b018bSJohan Hedberg memcpy(m + 9, a1, 7); 270760b018bSJohan Hedberg memcpy(m + 16, n2, 16); 271760b018bSJohan Hedberg memcpy(m + 32, n1, 16); 272760b018bSJohan Hedberg memcpy(m + 48, btle, 4); 273760b018bSJohan Hedberg 274760b018bSJohan Hedberg m[52] = 0; /* Counter */ 275760b018bSJohan Hedberg 276760b018bSJohan Hedberg err = aes_cmac(tfm_cmac, t, m, sizeof(m), mackey); 277760b018bSJohan Hedberg if (err) 278760b018bSJohan Hedberg return err; 279760b018bSJohan Hedberg 280c7a3d57dSJohan Hedberg SMP_DBG("mackey %16phN", mackey); 281760b018bSJohan Hedberg 282760b018bSJohan Hedberg m[52] = 1; /* Counter */ 283760b018bSJohan Hedberg 284760b018bSJohan Hedberg err = aes_cmac(tfm_cmac, t, m, sizeof(m), ltk); 285760b018bSJohan Hedberg if (err) 286760b018bSJohan Hedberg return err; 287760b018bSJohan Hedberg 288c7a3d57dSJohan Hedberg SMP_DBG("ltk %16phN", ltk); 289760b018bSJohan Hedberg 290760b018bSJohan Hedberg return 0; 291760b018bSJohan Hedberg } 292760b018bSJohan Hedberg 293760b018bSJohan Hedberg static int smp_f6(struct crypto_hash *tfm_cmac, const u8 w[16], 2944da50de8SJohan Hedberg const u8 n1[16], const u8 n2[16], const u8 r[16], 295760b018bSJohan Hedberg const u8 io_cap[3], const u8 a1[7], const u8 a2[7], 296760b018bSJohan Hedberg u8 res[16]) 297760b018bSJohan Hedberg { 298760b018bSJohan Hedberg u8 m[65]; 299760b018bSJohan Hedberg int err; 300760b018bSJohan Hedberg 301c7a3d57dSJohan Hedberg SMP_DBG("w %16phN", w); 302c7a3d57dSJohan Hedberg SMP_DBG("n1 %16phN n2 %16phN", n1, n2); 303c7a3d57dSJohan Hedberg SMP_DBG("r %16phN io_cap %3phN a1 %7phN a2 %7phN", r, io_cap, a1, a2); 304760b018bSJohan Hedberg 305760b018bSJohan Hedberg memcpy(m, a2, 7); 306760b018bSJohan Hedberg memcpy(m + 7, a1, 7); 307760b018bSJohan Hedberg memcpy(m + 14, io_cap, 3); 308760b018bSJohan Hedberg memcpy(m + 17, r, 16); 309760b018bSJohan Hedberg memcpy(m + 33, n2, 16); 310760b018bSJohan Hedberg memcpy(m + 49, n1, 16); 311760b018bSJohan Hedberg 312760b018bSJohan Hedberg err = aes_cmac(tfm_cmac, w, m, sizeof(m), res); 313760b018bSJohan Hedberg if (err) 314760b018bSJohan Hedberg return err; 315760b018bSJohan Hedberg 316203de21bSMarcel Holtmann SMP_DBG("res %16phN", res); 317760b018bSJohan Hedberg 318760b018bSJohan Hedberg return err; 319760b018bSJohan Hedberg } 320760b018bSJohan Hedberg 321191dc7feSJohan Hedberg static int smp_g2(struct crypto_hash *tfm_cmac, const u8 u[32], const u8 v[32], 322191dc7feSJohan Hedberg const u8 x[16], const u8 y[16], u32 *val) 323191dc7feSJohan Hedberg { 324191dc7feSJohan Hedberg u8 m[80], tmp[16]; 325191dc7feSJohan Hedberg int err; 326191dc7feSJohan Hedberg 327c7a3d57dSJohan Hedberg SMP_DBG("u %32phN", u); 328c7a3d57dSJohan Hedberg SMP_DBG("v %32phN", v); 329c7a3d57dSJohan Hedberg SMP_DBG("x %16phN y %16phN", x, y); 330191dc7feSJohan Hedberg 331191dc7feSJohan Hedberg memcpy(m, y, 16); 332191dc7feSJohan Hedberg memcpy(m + 16, v, 32); 333191dc7feSJohan Hedberg memcpy(m + 48, u, 32); 334191dc7feSJohan Hedberg 335191dc7feSJohan Hedberg err = aes_cmac(tfm_cmac, x, m, sizeof(m), tmp); 336191dc7feSJohan Hedberg if (err) 337191dc7feSJohan Hedberg return err; 338191dc7feSJohan Hedberg 339191dc7feSJohan Hedberg *val = get_unaligned_le32(tmp); 340191dc7feSJohan Hedberg *val %= 1000000; 341191dc7feSJohan Hedberg 342c7a3d57dSJohan Hedberg SMP_DBG("val %06u", *val); 343191dc7feSJohan Hedberg 344191dc7feSJohan Hedberg return 0; 345191dc7feSJohan Hedberg } 346191dc7feSJohan Hedberg 34706edf8deSJohan Hedberg static int smp_h6(struct crypto_hash *tfm_cmac, const u8 w[16], 34806edf8deSJohan Hedberg const u8 key_id[4], u8 res[16]) 34906edf8deSJohan Hedberg { 35006edf8deSJohan Hedberg int err; 35106edf8deSJohan Hedberg 35206edf8deSJohan Hedberg SMP_DBG("w %16phN key_id %4phN", w, key_id); 35306edf8deSJohan Hedberg 35406edf8deSJohan Hedberg err = aes_cmac(tfm_cmac, w, key_id, 4, res); 35506edf8deSJohan Hedberg if (err) 35606edf8deSJohan Hedberg return err; 35706edf8deSJohan Hedberg 35806edf8deSJohan Hedberg SMP_DBG("res %16phN", res); 35906edf8deSJohan Hedberg 36006edf8deSJohan Hedberg return err; 36106edf8deSJohan Hedberg } 36206edf8deSJohan Hedberg 36306edf8deSJohan Hedberg /* The following functions map to the legacy SMP crypto functions e, c1, 36406edf8deSJohan Hedberg * s1 and ah. 36506edf8deSJohan Hedberg */ 36606edf8deSJohan Hedberg 367d22ef0bcSAnderson Briglia static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r) 368d22ef0bcSAnderson Briglia { 369d22ef0bcSAnderson Briglia struct blkcipher_desc desc; 370d22ef0bcSAnderson Briglia struct scatterlist sg; 371943a732aSJohan Hedberg uint8_t tmp[16], data[16]; 372201a5929SJohan Hedberg int err; 373d22ef0bcSAnderson Briglia 3747f376cd6SJohan Hedberg if (!tfm) { 375d22ef0bcSAnderson Briglia BT_ERR("tfm %p", tfm); 376d22ef0bcSAnderson Briglia return -EINVAL; 377d22ef0bcSAnderson Briglia } 378d22ef0bcSAnderson Briglia 379d22ef0bcSAnderson Briglia desc.tfm = tfm; 380d22ef0bcSAnderson Briglia desc.flags = 0; 381d22ef0bcSAnderson Briglia 382943a732aSJohan Hedberg /* The most significant octet of key corresponds to k[0] */ 3838a2936f4SJohan Hedberg swap_buf(k, tmp, 16); 384943a732aSJohan Hedberg 385943a732aSJohan Hedberg err = crypto_blkcipher_setkey(tfm, tmp, 16); 386d22ef0bcSAnderson Briglia if (err) { 387d22ef0bcSAnderson Briglia BT_ERR("cipher setkey failed: %d", err); 388d22ef0bcSAnderson Briglia return err; 389d22ef0bcSAnderson Briglia } 390d22ef0bcSAnderson Briglia 391943a732aSJohan Hedberg /* Most significant octet of plaintextData corresponds to data[0] */ 3928a2936f4SJohan Hedberg swap_buf(r, data, 16); 393943a732aSJohan Hedberg 394943a732aSJohan Hedberg sg_init_one(&sg, data, 16); 395d22ef0bcSAnderson Briglia 396d22ef0bcSAnderson Briglia err = crypto_blkcipher_encrypt(&desc, &sg, &sg, 16); 397d22ef0bcSAnderson Briglia if (err) 398d22ef0bcSAnderson Briglia BT_ERR("Encrypt data error %d", err); 399d22ef0bcSAnderson Briglia 400943a732aSJohan Hedberg /* Most significant octet of encryptedData corresponds to data[0] */ 4018a2936f4SJohan Hedberg swap_buf(data, r, 16); 402943a732aSJohan Hedberg 403d22ef0bcSAnderson Briglia return err; 404d22ef0bcSAnderson Briglia } 405d22ef0bcSAnderson Briglia 40606edf8deSJohan Hedberg static int smp_c1(struct crypto_blkcipher *tfm_aes, const u8 k[16], 40706edf8deSJohan Hedberg const u8 r[16], const u8 preq[7], const u8 pres[7], u8 _iat, 40806edf8deSJohan Hedberg const bdaddr_t *ia, u8 _rat, const bdaddr_t *ra, u8 res[16]) 40906edf8deSJohan Hedberg { 41006edf8deSJohan Hedberg u8 p1[16], p2[16]; 41106edf8deSJohan Hedberg int err; 41206edf8deSJohan Hedberg 41306edf8deSJohan Hedberg memset(p1, 0, 16); 41406edf8deSJohan Hedberg 41506edf8deSJohan Hedberg /* p1 = pres || preq || _rat || _iat */ 41606edf8deSJohan Hedberg p1[0] = _iat; 41706edf8deSJohan Hedberg p1[1] = _rat; 41806edf8deSJohan Hedberg memcpy(p1 + 2, preq, 7); 41906edf8deSJohan Hedberg memcpy(p1 + 9, pres, 7); 42006edf8deSJohan Hedberg 42106edf8deSJohan Hedberg /* p2 = padding || ia || ra */ 42206edf8deSJohan Hedberg memcpy(p2, ra, 6); 42306edf8deSJohan Hedberg memcpy(p2 + 6, ia, 6); 42406edf8deSJohan Hedberg memset(p2 + 12, 0, 4); 42506edf8deSJohan Hedberg 42606edf8deSJohan Hedberg /* res = r XOR p1 */ 42706edf8deSJohan Hedberg u128_xor((u128 *) res, (u128 *) r, (u128 *) p1); 42806edf8deSJohan Hedberg 42906edf8deSJohan Hedberg /* res = e(k, res) */ 43006edf8deSJohan Hedberg err = smp_e(tfm_aes, k, res); 43106edf8deSJohan Hedberg if (err) { 43206edf8deSJohan Hedberg BT_ERR("Encrypt data error"); 43306edf8deSJohan Hedberg return err; 43406edf8deSJohan Hedberg } 43506edf8deSJohan Hedberg 43606edf8deSJohan Hedberg /* res = res XOR p2 */ 43706edf8deSJohan Hedberg u128_xor((u128 *) res, (u128 *) res, (u128 *) p2); 43806edf8deSJohan Hedberg 43906edf8deSJohan Hedberg /* res = e(k, res) */ 44006edf8deSJohan Hedberg err = smp_e(tfm_aes, k, res); 44106edf8deSJohan Hedberg if (err) 44206edf8deSJohan Hedberg BT_ERR("Encrypt data error"); 44306edf8deSJohan Hedberg 44406edf8deSJohan Hedberg return err; 44506edf8deSJohan Hedberg } 44606edf8deSJohan Hedberg 44706edf8deSJohan Hedberg static int smp_s1(struct crypto_blkcipher *tfm_aes, const u8 k[16], 44806edf8deSJohan Hedberg const u8 r1[16], const u8 r2[16], u8 _r[16]) 4496a77083aSJohan Hedberg { 4506a77083aSJohan Hedberg int err; 4516a77083aSJohan Hedberg 45206edf8deSJohan Hedberg /* Just least significant octets from r1 and r2 are considered */ 45306edf8deSJohan Hedberg memcpy(_r, r2, 8); 45406edf8deSJohan Hedberg memcpy(_r + 8, r1, 8); 4556a77083aSJohan Hedberg 45606edf8deSJohan Hedberg err = smp_e(tfm_aes, k, _r); 4576a77083aSJohan Hedberg if (err) 45806edf8deSJohan Hedberg BT_ERR("Encrypt data error"); 4596a77083aSJohan Hedberg 4606a77083aSJohan Hedberg return err; 4616a77083aSJohan Hedberg } 4626a77083aSJohan Hedberg 463cd082797SJohan Hedberg static int smp_ah(struct crypto_blkcipher *tfm, const u8 irk[16], 464cd082797SJohan Hedberg const u8 r[3], u8 res[3]) 46560478054SJohan Hedberg { 466943a732aSJohan Hedberg u8 _res[16]; 46760478054SJohan Hedberg int err; 46860478054SJohan Hedberg 46960478054SJohan Hedberg /* r' = padding || r */ 470943a732aSJohan Hedberg memcpy(_res, r, 3); 471943a732aSJohan Hedberg memset(_res + 3, 0, 13); 47260478054SJohan Hedberg 473943a732aSJohan Hedberg err = smp_e(tfm, irk, _res); 47460478054SJohan Hedberg if (err) { 47560478054SJohan Hedberg BT_ERR("Encrypt error"); 47660478054SJohan Hedberg return err; 47760478054SJohan Hedberg } 47860478054SJohan Hedberg 47960478054SJohan Hedberg /* The output of the random address function ah is: 48060478054SJohan Hedberg * ah(h, r) = e(k, r') mod 2^24 48160478054SJohan Hedberg * The output of the security function e is then truncated to 24 bits 48260478054SJohan Hedberg * by taking the least significant 24 bits of the output of e as the 48360478054SJohan Hedberg * result of ah. 48460478054SJohan Hedberg */ 485943a732aSJohan Hedberg memcpy(res, _res, 3); 48660478054SJohan Hedberg 48760478054SJohan Hedberg return 0; 48860478054SJohan Hedberg } 48960478054SJohan Hedberg 490cd082797SJohan Hedberg bool smp_irk_matches(struct hci_dev *hdev, const u8 irk[16], 491cd082797SJohan Hedberg const bdaddr_t *bdaddr) 49260478054SJohan Hedberg { 493defce9e8SJohan Hedberg struct l2cap_chan *chan = hdev->smp_data; 49488a479d9SMarcel Holtmann struct smp_dev *smp; 49560478054SJohan Hedberg u8 hash[3]; 49660478054SJohan Hedberg int err; 49760478054SJohan Hedberg 498defce9e8SJohan Hedberg if (!chan || !chan->data) 499defce9e8SJohan Hedberg return false; 500defce9e8SJohan Hedberg 50188a479d9SMarcel Holtmann smp = chan->data; 502defce9e8SJohan Hedberg 50360478054SJohan Hedberg BT_DBG("RPA %pMR IRK %*phN", bdaddr, 16, irk); 50460478054SJohan Hedberg 50588a479d9SMarcel Holtmann err = smp_ah(smp->tfm_aes, irk, &bdaddr->b[3], hash); 50660478054SJohan Hedberg if (err) 50760478054SJohan Hedberg return false; 50860478054SJohan Hedberg 50960478054SJohan Hedberg return !memcmp(bdaddr->b, hash, 3); 51060478054SJohan Hedberg } 51160478054SJohan Hedberg 512cd082797SJohan Hedberg int smp_generate_rpa(struct hci_dev *hdev, const u8 irk[16], bdaddr_t *rpa) 513b1e2b3aeSJohan Hedberg { 514defce9e8SJohan Hedberg struct l2cap_chan *chan = hdev->smp_data; 51588a479d9SMarcel Holtmann struct smp_dev *smp; 516b1e2b3aeSJohan Hedberg int err; 517b1e2b3aeSJohan Hedberg 518defce9e8SJohan Hedberg if (!chan || !chan->data) 519defce9e8SJohan Hedberg return -EOPNOTSUPP; 520defce9e8SJohan Hedberg 52188a479d9SMarcel Holtmann smp = chan->data; 522defce9e8SJohan Hedberg 523b1e2b3aeSJohan Hedberg get_random_bytes(&rpa->b[3], 3); 524b1e2b3aeSJohan Hedberg 525b1e2b3aeSJohan Hedberg rpa->b[5] &= 0x3f; /* Clear two most significant bits */ 526b1e2b3aeSJohan Hedberg rpa->b[5] |= 0x40; /* Set second most significant bit */ 527b1e2b3aeSJohan Hedberg 52888a479d9SMarcel Holtmann err = smp_ah(smp->tfm_aes, irk, &rpa->b[3], rpa->b); 529b1e2b3aeSJohan Hedberg if (err < 0) 530b1e2b3aeSJohan Hedberg return err; 531b1e2b3aeSJohan Hedberg 532b1e2b3aeSJohan Hedberg BT_DBG("RPA %pMR", rpa); 533b1e2b3aeSJohan Hedberg 534b1e2b3aeSJohan Hedberg return 0; 535b1e2b3aeSJohan Hedberg } 536b1e2b3aeSJohan Hedberg 53760a27d65SMarcel Holtmann int smp_generate_oob(struct hci_dev *hdev, u8 hash[16], u8 rand[16]) 53860a27d65SMarcel Holtmann { 53960a27d65SMarcel Holtmann struct l2cap_chan *chan = hdev->smp_data; 54060a27d65SMarcel Holtmann struct smp_dev *smp; 54160a27d65SMarcel Holtmann int err; 54260a27d65SMarcel Holtmann 54360a27d65SMarcel Holtmann if (!chan || !chan->data) 54460a27d65SMarcel Holtmann return -EOPNOTSUPP; 54560a27d65SMarcel Holtmann 54660a27d65SMarcel Holtmann smp = chan->data; 54760a27d65SMarcel Holtmann 54860a27d65SMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS)) { 54960a27d65SMarcel Holtmann BT_DBG("Using debug keys"); 55060a27d65SMarcel Holtmann memcpy(smp->local_pk, debug_pk, 64); 55160a27d65SMarcel Holtmann memcpy(smp->local_sk, debug_sk, 32); 55260a27d65SMarcel Holtmann smp->debug_key = true; 55360a27d65SMarcel Holtmann } else { 55460a27d65SMarcel Holtmann while (true) { 55560a27d65SMarcel Holtmann /* Generate local key pair for Secure Connections */ 55660a27d65SMarcel Holtmann if (!ecc_make_key(smp->local_pk, smp->local_sk)) 55760a27d65SMarcel Holtmann return -EIO; 55860a27d65SMarcel Holtmann 55960a27d65SMarcel Holtmann /* This is unlikely, but we need to check that 56060a27d65SMarcel Holtmann * we didn't accidentially generate a debug key. 56160a27d65SMarcel Holtmann */ 56260a27d65SMarcel Holtmann if (memcmp(smp->local_sk, debug_sk, 32)) 56360a27d65SMarcel Holtmann break; 56460a27d65SMarcel Holtmann } 56560a27d65SMarcel Holtmann smp->debug_key = false; 56660a27d65SMarcel Holtmann } 56760a27d65SMarcel Holtmann 56860a27d65SMarcel Holtmann SMP_DBG("OOB Public Key X: %32phN", smp->local_pk); 56960a27d65SMarcel Holtmann SMP_DBG("OOB Public Key Y: %32phN", smp->local_pk + 32); 57060a27d65SMarcel Holtmann SMP_DBG("OOB Private Key: %32phN", smp->local_sk); 57160a27d65SMarcel Holtmann 57260a27d65SMarcel Holtmann get_random_bytes(smp->local_rr, 16); 57360a27d65SMarcel Holtmann 57460a27d65SMarcel Holtmann err = smp_f4(smp->tfm_cmac, smp->local_pk, smp->local_pk, 57560a27d65SMarcel Holtmann smp->local_rr, 0, hash); 57660a27d65SMarcel Holtmann if (err < 0) 57760a27d65SMarcel Holtmann return err; 57860a27d65SMarcel Holtmann 57960a27d65SMarcel Holtmann memcpy(rand, smp->local_rr, 16); 58060a27d65SMarcel Holtmann 58160a27d65SMarcel Holtmann return 0; 58260a27d65SMarcel Holtmann } 58360a27d65SMarcel Holtmann 584eb492e01SAnderson Briglia static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data) 585eb492e01SAnderson Briglia { 5865d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 587b68fda68SJohan Hedberg struct smp_chan *smp; 5885d88cc73SJohan Hedberg struct kvec iv[2]; 5895d88cc73SJohan Hedberg struct msghdr msg; 5905d88cc73SJohan Hedberg 5915d88cc73SJohan Hedberg if (!chan) 5925d88cc73SJohan Hedberg return; 593eb492e01SAnderson Briglia 594eb492e01SAnderson Briglia BT_DBG("code 0x%2.2x", code); 595eb492e01SAnderson Briglia 5965d88cc73SJohan Hedberg iv[0].iov_base = &code; 5975d88cc73SJohan Hedberg iv[0].iov_len = 1; 598eb492e01SAnderson Briglia 5995d88cc73SJohan Hedberg iv[1].iov_base = data; 6005d88cc73SJohan Hedberg iv[1].iov_len = len; 6015d88cc73SJohan Hedberg 6025d88cc73SJohan Hedberg memset(&msg, 0, sizeof(msg)); 6035d88cc73SJohan Hedberg 60417836394SAl Viro iov_iter_kvec(&msg.msg_iter, WRITE | ITER_KVEC, iv, 2, 1 + len); 6055d88cc73SJohan Hedberg 6065d88cc73SJohan Hedberg l2cap_chan_send(chan, &msg, 1 + len); 607e2dcd113SVinicius Costa Gomes 608b68fda68SJohan Hedberg if (!chan->data) 609b68fda68SJohan Hedberg return; 610b68fda68SJohan Hedberg 611b68fda68SJohan Hedberg smp = chan->data; 612b68fda68SJohan Hedberg 613b68fda68SJohan Hedberg cancel_delayed_work_sync(&smp->security_timer); 614b68fda68SJohan Hedberg schedule_delayed_work(&smp->security_timer, SMP_TIMEOUT); 615eb492e01SAnderson Briglia } 616eb492e01SAnderson Briglia 617d2eb9e10SJohan Hedberg static u8 authreq_to_seclevel(u8 authreq) 6182b64d153SBrian Gix { 619d2eb9e10SJohan Hedberg if (authreq & SMP_AUTH_MITM) { 620d2eb9e10SJohan Hedberg if (authreq & SMP_AUTH_SC) 621d2eb9e10SJohan Hedberg return BT_SECURITY_FIPS; 6222b64d153SBrian Gix else 623d2eb9e10SJohan Hedberg return BT_SECURITY_HIGH; 624d2eb9e10SJohan Hedberg } else { 6252b64d153SBrian Gix return BT_SECURITY_MEDIUM; 6262b64d153SBrian Gix } 627d2eb9e10SJohan Hedberg } 6282b64d153SBrian Gix 6292b64d153SBrian Gix static __u8 seclevel_to_authreq(__u8 sec_level) 6302b64d153SBrian Gix { 6312b64d153SBrian Gix switch (sec_level) { 632d2eb9e10SJohan Hedberg case BT_SECURITY_FIPS: 6332b64d153SBrian Gix case BT_SECURITY_HIGH: 6342b64d153SBrian Gix return SMP_AUTH_MITM | SMP_AUTH_BONDING; 6352b64d153SBrian Gix case BT_SECURITY_MEDIUM: 6362b64d153SBrian Gix return SMP_AUTH_BONDING; 6372b64d153SBrian Gix default: 6382b64d153SBrian Gix return SMP_AUTH_NONE; 6392b64d153SBrian Gix } 6402b64d153SBrian Gix } 6412b64d153SBrian Gix 642b8e66eacSVinicius Costa Gomes static void build_pairing_cmd(struct l2cap_conn *conn, 64354790f73SVinicius Costa Gomes struct smp_cmd_pairing *req, 644f1560463SMarcel Holtmann struct smp_cmd_pairing *rsp, __u8 authreq) 645b8e66eacSVinicius Costa Gomes { 6465d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 6475d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 648fd349c02SJohan Hedberg struct hci_conn *hcon = conn->hcon; 649fd349c02SJohan Hedberg struct hci_dev *hdev = hcon->hdev; 65002b05bd8SJohan Hedberg u8 local_dist = 0, remote_dist = 0, oob_flag = SMP_OOB_NOT_PRESENT; 65154790f73SVinicius Costa Gomes 652d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_BONDABLE)) { 6537ee4ea36SMarcel Holtmann local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN; 6547ee4ea36SMarcel Holtmann remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN; 65554790f73SVinicius Costa Gomes authreq |= SMP_AUTH_BONDING; 6562b64d153SBrian Gix } else { 6572b64d153SBrian Gix authreq &= ~SMP_AUTH_BONDING; 65854790f73SVinicius Costa Gomes } 65954790f73SVinicius Costa Gomes 660d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_RPA_RESOLVING)) 661fd349c02SJohan Hedberg remote_dist |= SMP_DIST_ID_KEY; 662fd349c02SJohan Hedberg 663d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_PRIVACY)) 664863efaf2SJohan Hedberg local_dist |= SMP_DIST_ID_KEY; 665863efaf2SJohan Hedberg 666d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SC_ENABLED) && 66702b05bd8SJohan Hedberg (authreq & SMP_AUTH_SC)) { 66802b05bd8SJohan Hedberg struct oob_data *oob_data; 66902b05bd8SJohan Hedberg u8 bdaddr_type; 67002b05bd8SJohan Hedberg 671d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SSP_ENABLED)) { 672df8e1a4cSJohan Hedberg local_dist |= SMP_DIST_LINK_KEY; 673df8e1a4cSJohan Hedberg remote_dist |= SMP_DIST_LINK_KEY; 674df8e1a4cSJohan Hedberg } 67502b05bd8SJohan Hedberg 67602b05bd8SJohan Hedberg if (hcon->dst_type == ADDR_LE_DEV_PUBLIC) 67702b05bd8SJohan Hedberg bdaddr_type = BDADDR_LE_PUBLIC; 67802b05bd8SJohan Hedberg else 67902b05bd8SJohan Hedberg bdaddr_type = BDADDR_LE_RANDOM; 68002b05bd8SJohan Hedberg 68102b05bd8SJohan Hedberg oob_data = hci_find_remote_oob_data(hdev, &hcon->dst, 68202b05bd8SJohan Hedberg bdaddr_type); 6834775a4eaSMarcel Holtmann if (oob_data && oob_data->present) { 6841a8bab4fSJohan Hedberg set_bit(SMP_FLAG_REMOTE_OOB, &smp->flags); 68502b05bd8SJohan Hedberg oob_flag = SMP_OOB_PRESENT; 686a29b0733SJohan Hedberg memcpy(smp->rr, oob_data->rand256, 16); 68702b05bd8SJohan Hedberg memcpy(smp->pcnf, oob_data->hash256, 16); 68802b05bd8SJohan Hedberg } 68902b05bd8SJohan Hedberg 690df8e1a4cSJohan Hedberg } else { 691df8e1a4cSJohan Hedberg authreq &= ~SMP_AUTH_SC; 692df8e1a4cSJohan Hedberg } 693df8e1a4cSJohan Hedberg 69454790f73SVinicius Costa Gomes if (rsp == NULL) { 69554790f73SVinicius Costa Gomes req->io_capability = conn->hcon->io_capability; 69602b05bd8SJohan Hedberg req->oob_flag = oob_flag; 69754790f73SVinicius Costa Gomes req->max_key_size = SMP_MAX_ENC_KEY_SIZE; 698fd349c02SJohan Hedberg req->init_key_dist = local_dist; 699fd349c02SJohan Hedberg req->resp_key_dist = remote_dist; 7000edb14deSJohan Hedberg req->auth_req = (authreq & AUTH_REQ_MASK(hdev)); 701fd349c02SJohan Hedberg 702fd349c02SJohan Hedberg smp->remote_key_dist = remote_dist; 70354790f73SVinicius Costa Gomes return; 70454790f73SVinicius Costa Gomes } 70554790f73SVinicius Costa Gomes 70654790f73SVinicius Costa Gomes rsp->io_capability = conn->hcon->io_capability; 70702b05bd8SJohan Hedberg rsp->oob_flag = oob_flag; 70854790f73SVinicius Costa Gomes rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE; 709fd349c02SJohan Hedberg rsp->init_key_dist = req->init_key_dist & remote_dist; 710fd349c02SJohan Hedberg rsp->resp_key_dist = req->resp_key_dist & local_dist; 7110edb14deSJohan Hedberg rsp->auth_req = (authreq & AUTH_REQ_MASK(hdev)); 712fd349c02SJohan Hedberg 713fd349c02SJohan Hedberg smp->remote_key_dist = rsp->init_key_dist; 714b8e66eacSVinicius Costa Gomes } 715b8e66eacSVinicius Costa Gomes 7163158c50cSVinicius Costa Gomes static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size) 7173158c50cSVinicius Costa Gomes { 7185d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 7195d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 7201c1def09SVinicius Costa Gomes 7213158c50cSVinicius Costa Gomes if ((max_key_size > SMP_MAX_ENC_KEY_SIZE) || 7223158c50cSVinicius Costa Gomes (max_key_size < SMP_MIN_ENC_KEY_SIZE)) 7233158c50cSVinicius Costa Gomes return SMP_ENC_KEY_SIZE; 7243158c50cSVinicius Costa Gomes 725f7aa611aSVinicius Costa Gomes smp->enc_key_size = max_key_size; 7263158c50cSVinicius Costa Gomes 7273158c50cSVinicius Costa Gomes return 0; 7283158c50cSVinicius Costa Gomes } 7293158c50cSVinicius Costa Gomes 7306f48e260SJohan Hedberg static void smp_chan_destroy(struct l2cap_conn *conn) 7316f48e260SJohan Hedberg { 7326f48e260SJohan Hedberg struct l2cap_chan *chan = conn->smp; 7336f48e260SJohan Hedberg struct smp_chan *smp = chan->data; 734923e2414SJohan Hedberg struct hci_conn *hcon = conn->hcon; 7356f48e260SJohan Hedberg bool complete; 7366f48e260SJohan Hedberg 7376f48e260SJohan Hedberg BUG_ON(!smp); 7386f48e260SJohan Hedberg 7396f48e260SJohan Hedberg cancel_delayed_work_sync(&smp->security_timer); 7406f48e260SJohan Hedberg 7416f48e260SJohan Hedberg complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags); 742923e2414SJohan Hedberg mgmt_smp_complete(hcon, complete); 7436f48e260SJohan Hedberg 744276812ecSMarcel Holtmann kzfree(smp->csrk); 745276812ecSMarcel Holtmann kzfree(smp->slave_csrk); 746276812ecSMarcel Holtmann kzfree(smp->link_key); 7476f48e260SJohan Hedberg 7486f48e260SJohan Hedberg crypto_free_blkcipher(smp->tfm_aes); 749407cecf6SJohan Hedberg crypto_free_hash(smp->tfm_cmac); 7506f48e260SJohan Hedberg 751923e2414SJohan Hedberg /* Ensure that we don't leave any debug key around if debug key 752923e2414SJohan Hedberg * support hasn't been explicitly enabled. 753923e2414SJohan Hedberg */ 754923e2414SJohan Hedberg if (smp->ltk && smp->ltk->type == SMP_LTK_P256_DEBUG && 755d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hcon->hdev, HCI_KEEP_DEBUG_KEYS)) { 756923e2414SJohan Hedberg list_del_rcu(&smp->ltk->list); 757923e2414SJohan Hedberg kfree_rcu(smp->ltk, rcu); 758923e2414SJohan Hedberg smp->ltk = NULL; 759923e2414SJohan Hedberg } 760923e2414SJohan Hedberg 7616f48e260SJohan Hedberg /* If pairing failed clean up any keys we might have */ 7626f48e260SJohan Hedberg if (!complete) { 7636f48e260SJohan Hedberg if (smp->ltk) { 764970d0f1bSJohan Hedberg list_del_rcu(&smp->ltk->list); 765970d0f1bSJohan Hedberg kfree_rcu(smp->ltk, rcu); 7666f48e260SJohan Hedberg } 7676f48e260SJohan Hedberg 7686f48e260SJohan Hedberg if (smp->slave_ltk) { 769970d0f1bSJohan Hedberg list_del_rcu(&smp->slave_ltk->list); 770970d0f1bSJohan Hedberg kfree_rcu(smp->slave_ltk, rcu); 7716f48e260SJohan Hedberg } 7726f48e260SJohan Hedberg 7736f48e260SJohan Hedberg if (smp->remote_irk) { 774adae20cbSJohan Hedberg list_del_rcu(&smp->remote_irk->list); 775adae20cbSJohan Hedberg kfree_rcu(smp->remote_irk, rcu); 7766f48e260SJohan Hedberg } 7776f48e260SJohan Hedberg } 7786f48e260SJohan Hedberg 7796f48e260SJohan Hedberg chan->data = NULL; 780276812ecSMarcel Holtmann kzfree(smp); 781923e2414SJohan Hedberg hci_conn_drop(hcon); 7826f48e260SJohan Hedberg } 7836f48e260SJohan Hedberg 78484794e11SJohan Hedberg static void smp_failure(struct l2cap_conn *conn, u8 reason) 7854f957a76SBrian Gix { 786bab73cb6SJohan Hedberg struct hci_conn *hcon = conn->hcon; 787b68fda68SJohan Hedberg struct l2cap_chan *chan = conn->smp; 788bab73cb6SJohan Hedberg 78984794e11SJohan Hedberg if (reason) 7904f957a76SBrian Gix smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason), 7914f957a76SBrian Gix &reason); 7924f957a76SBrian Gix 793ce39fb4eSMarcel Holtmann clear_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags); 794e1e930f5SJohan Hedberg mgmt_auth_failed(hcon, HCI_ERROR_AUTH_FAILURE); 795f1c09c07SVinicius Costa Gomes 796fc75cc86SJohan Hedberg if (chan->data) 7974f957a76SBrian Gix smp_chan_destroy(conn); 7984f957a76SBrian Gix } 7994f957a76SBrian Gix 8002b64d153SBrian Gix #define JUST_WORKS 0x00 8012b64d153SBrian Gix #define JUST_CFM 0x01 8022b64d153SBrian Gix #define REQ_PASSKEY 0x02 8032b64d153SBrian Gix #define CFM_PASSKEY 0x03 8042b64d153SBrian Gix #define REQ_OOB 0x04 8055e3d3d9bSJohan Hedberg #define DSP_PASSKEY 0x05 8062b64d153SBrian Gix #define OVERLAP 0xFF 8072b64d153SBrian Gix 8082b64d153SBrian Gix static const u8 gen_method[5][5] = { 8092b64d153SBrian Gix { JUST_WORKS, JUST_CFM, REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY }, 8102b64d153SBrian Gix { JUST_WORKS, JUST_CFM, REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY }, 8112b64d153SBrian Gix { CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY }, 8122b64d153SBrian Gix { JUST_WORKS, JUST_CFM, JUST_WORKS, JUST_WORKS, JUST_CFM }, 8132b64d153SBrian Gix { CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, OVERLAP }, 8142b64d153SBrian Gix }; 8152b64d153SBrian Gix 8165e3d3d9bSJohan Hedberg static const u8 sc_method[5][5] = { 8175e3d3d9bSJohan Hedberg { JUST_WORKS, JUST_CFM, REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY }, 8185e3d3d9bSJohan Hedberg { JUST_WORKS, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY }, 8195e3d3d9bSJohan Hedberg { DSP_PASSKEY, DSP_PASSKEY, REQ_PASSKEY, JUST_WORKS, DSP_PASSKEY }, 8205e3d3d9bSJohan Hedberg { JUST_WORKS, JUST_CFM, JUST_WORKS, JUST_WORKS, JUST_CFM }, 8215e3d3d9bSJohan Hedberg { DSP_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY }, 8225e3d3d9bSJohan Hedberg }; 8235e3d3d9bSJohan Hedberg 824581370ccSJohan Hedberg static u8 get_auth_method(struct smp_chan *smp, u8 local_io, u8 remote_io) 825581370ccSJohan Hedberg { 8262bcd4003SJohan Hedberg /* If either side has unknown io_caps, use JUST_CFM (which gets 8272bcd4003SJohan Hedberg * converted later to JUST_WORKS if we're initiators. 8282bcd4003SJohan Hedberg */ 829581370ccSJohan Hedberg if (local_io > SMP_IO_KEYBOARD_DISPLAY || 830581370ccSJohan Hedberg remote_io > SMP_IO_KEYBOARD_DISPLAY) 8312bcd4003SJohan Hedberg return JUST_CFM; 832581370ccSJohan Hedberg 8335e3d3d9bSJohan Hedberg if (test_bit(SMP_FLAG_SC, &smp->flags)) 8345e3d3d9bSJohan Hedberg return sc_method[remote_io][local_io]; 8355e3d3d9bSJohan Hedberg 836581370ccSJohan Hedberg return gen_method[remote_io][local_io]; 837581370ccSJohan Hedberg } 838581370ccSJohan Hedberg 8392b64d153SBrian Gix static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth, 8402b64d153SBrian Gix u8 local_io, u8 remote_io) 8412b64d153SBrian Gix { 8422b64d153SBrian Gix struct hci_conn *hcon = conn->hcon; 8435d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 8445d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 8452b64d153SBrian Gix u32 passkey = 0; 8462b64d153SBrian Gix int ret = 0; 8472b64d153SBrian Gix 8482b64d153SBrian Gix /* Initialize key for JUST WORKS */ 8492b64d153SBrian Gix memset(smp->tk, 0, sizeof(smp->tk)); 8504a74d658SJohan Hedberg clear_bit(SMP_FLAG_TK_VALID, &smp->flags); 8512b64d153SBrian Gix 8522b64d153SBrian Gix BT_DBG("tk_request: auth:%d lcl:%d rem:%d", auth, local_io, remote_io); 8532b64d153SBrian Gix 8542bcd4003SJohan Hedberg /* If neither side wants MITM, either "just" confirm an incoming 8552bcd4003SJohan Hedberg * request or use just-works for outgoing ones. The JUST_CFM 8562bcd4003SJohan Hedberg * will be converted to JUST_WORKS if necessary later in this 8572bcd4003SJohan Hedberg * function. If either side has MITM look up the method from the 8582bcd4003SJohan Hedberg * table. 8592bcd4003SJohan Hedberg */ 860581370ccSJohan Hedberg if (!(auth & SMP_AUTH_MITM)) 861783e0574SJohan Hedberg smp->method = JUST_CFM; 8622b64d153SBrian Gix else 863783e0574SJohan Hedberg smp->method = get_auth_method(smp, local_io, remote_io); 8642b64d153SBrian Gix 865a82505c7SJohan Hedberg /* Don't confirm locally initiated pairing attempts */ 866783e0574SJohan Hedberg if (smp->method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR, 867783e0574SJohan Hedberg &smp->flags)) 868783e0574SJohan Hedberg smp->method = JUST_WORKS; 869a82505c7SJohan Hedberg 87002f3e254SJohan Hedberg /* Don't bother user space with no IO capabilities */ 871783e0574SJohan Hedberg if (smp->method == JUST_CFM && 872783e0574SJohan Hedberg hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT) 873783e0574SJohan Hedberg smp->method = JUST_WORKS; 87402f3e254SJohan Hedberg 8752b64d153SBrian Gix /* If Just Works, Continue with Zero TK */ 876783e0574SJohan Hedberg if (smp->method == JUST_WORKS) { 8774a74d658SJohan Hedberg set_bit(SMP_FLAG_TK_VALID, &smp->flags); 8782b64d153SBrian Gix return 0; 8792b64d153SBrian Gix } 8802b64d153SBrian Gix 8812b64d153SBrian Gix /* Not Just Works/Confirm results in MITM Authentication */ 882783e0574SJohan Hedberg if (smp->method != JUST_CFM) { 8834a74d658SJohan Hedberg set_bit(SMP_FLAG_MITM_AUTH, &smp->flags); 8845eb596f5SJohan Hedberg if (hcon->pending_sec_level < BT_SECURITY_HIGH) 8855eb596f5SJohan Hedberg hcon->pending_sec_level = BT_SECURITY_HIGH; 8865eb596f5SJohan Hedberg } 8872b64d153SBrian Gix 8882b64d153SBrian Gix /* If both devices have Keyoard-Display I/O, the master 8892b64d153SBrian Gix * Confirms and the slave Enters the passkey. 8902b64d153SBrian Gix */ 891783e0574SJohan Hedberg if (smp->method == OVERLAP) { 89240bef302SJohan Hedberg if (hcon->role == HCI_ROLE_MASTER) 893783e0574SJohan Hedberg smp->method = CFM_PASSKEY; 8942b64d153SBrian Gix else 895783e0574SJohan Hedberg smp->method = REQ_PASSKEY; 8962b64d153SBrian Gix } 8972b64d153SBrian Gix 89801ad34d2SJohan Hedberg /* Generate random passkey. */ 899783e0574SJohan Hedberg if (smp->method == CFM_PASSKEY) { 900943a732aSJohan Hedberg memset(smp->tk, 0, sizeof(smp->tk)); 9012b64d153SBrian Gix get_random_bytes(&passkey, sizeof(passkey)); 9022b64d153SBrian Gix passkey %= 1000000; 903943a732aSJohan Hedberg put_unaligned_le32(passkey, smp->tk); 9042b64d153SBrian Gix BT_DBG("PassKey: %d", passkey); 9054a74d658SJohan Hedberg set_bit(SMP_FLAG_TK_VALID, &smp->flags); 9062b64d153SBrian Gix } 9072b64d153SBrian Gix 908783e0574SJohan Hedberg if (smp->method == REQ_PASSKEY) 909ce39fb4eSMarcel Holtmann ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst, 910272d90dfSJohan Hedberg hcon->type, hcon->dst_type); 911783e0574SJohan Hedberg else if (smp->method == JUST_CFM) 9124eb65e66SJohan Hedberg ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst, 9134eb65e66SJohan Hedberg hcon->type, hcon->dst_type, 9144eb65e66SJohan Hedberg passkey, 1); 9152b64d153SBrian Gix else 91601ad34d2SJohan Hedberg ret = mgmt_user_passkey_notify(hcon->hdev, &hcon->dst, 917272d90dfSJohan Hedberg hcon->type, hcon->dst_type, 91839adbffeSJohan Hedberg passkey, 0); 9192b64d153SBrian Gix 9202b64d153SBrian Gix return ret; 9212b64d153SBrian Gix } 9222b64d153SBrian Gix 9231cc61144SJohan Hedberg static u8 smp_confirm(struct smp_chan *smp) 9248aab4757SVinicius Costa Gomes { 9258aab4757SVinicius Costa Gomes struct l2cap_conn *conn = smp->conn; 9268aab4757SVinicius Costa Gomes struct smp_cmd_pairing_confirm cp; 9278aab4757SVinicius Costa Gomes int ret; 9288aab4757SVinicius Costa Gomes 9298aab4757SVinicius Costa Gomes BT_DBG("conn %p", conn); 9308aab4757SVinicius Costa Gomes 931e491eaf3SJohan Hedberg ret = smp_c1(smp->tfm_aes, smp->tk, smp->prnd, smp->preq, smp->prsp, 932b1cd5fd9SJohan Hedberg conn->hcon->init_addr_type, &conn->hcon->init_addr, 933943a732aSJohan Hedberg conn->hcon->resp_addr_type, &conn->hcon->resp_addr, 934943a732aSJohan Hedberg cp.confirm_val); 9351cc61144SJohan Hedberg if (ret) 9361cc61144SJohan Hedberg return SMP_UNSPECIFIED; 9378aab4757SVinicius Costa Gomes 9384a74d658SJohan Hedberg clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags); 9392b64d153SBrian Gix 9408aab4757SVinicius Costa Gomes smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp); 9418aab4757SVinicius Costa Gomes 942b28b4943SJohan Hedberg if (conn->hcon->out) 943b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); 944b28b4943SJohan Hedberg else 945b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM); 946b28b4943SJohan Hedberg 9471cc61144SJohan Hedberg return 0; 9488aab4757SVinicius Costa Gomes } 9498aab4757SVinicius Costa Gomes 950861580a9SJohan Hedberg static u8 smp_random(struct smp_chan *smp) 9518aab4757SVinicius Costa Gomes { 9528aab4757SVinicius Costa Gomes struct l2cap_conn *conn = smp->conn; 9538aab4757SVinicius Costa Gomes struct hci_conn *hcon = conn->hcon; 954861580a9SJohan Hedberg u8 confirm[16]; 9558aab4757SVinicius Costa Gomes int ret; 9568aab4757SVinicius Costa Gomes 957ec70f36fSJohan Hedberg if (IS_ERR_OR_NULL(smp->tfm_aes)) 958861580a9SJohan Hedberg return SMP_UNSPECIFIED; 9598aab4757SVinicius Costa Gomes 9608aab4757SVinicius Costa Gomes BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave"); 9618aab4757SVinicius Costa Gomes 962e491eaf3SJohan Hedberg ret = smp_c1(smp->tfm_aes, smp->tk, smp->rrnd, smp->preq, smp->prsp, 963b1cd5fd9SJohan Hedberg hcon->init_addr_type, &hcon->init_addr, 964943a732aSJohan Hedberg hcon->resp_addr_type, &hcon->resp_addr, confirm); 965861580a9SJohan Hedberg if (ret) 966861580a9SJohan Hedberg return SMP_UNSPECIFIED; 9678aab4757SVinicius Costa Gomes 9688aab4757SVinicius Costa Gomes if (memcmp(smp->pcnf, confirm, sizeof(smp->pcnf)) != 0) { 9698aab4757SVinicius Costa Gomes BT_ERR("Pairing failed (confirmation values mismatch)"); 970861580a9SJohan Hedberg return SMP_CONFIRM_FAILED; 9718aab4757SVinicius Costa Gomes } 9728aab4757SVinicius Costa Gomes 9738aab4757SVinicius Costa Gomes if (hcon->out) { 974fe39c7b2SMarcel Holtmann u8 stk[16]; 975fe39c7b2SMarcel Holtmann __le64 rand = 0; 976fe39c7b2SMarcel Holtmann __le16 ediv = 0; 9778aab4757SVinicius Costa Gomes 978e491eaf3SJohan Hedberg smp_s1(smp->tfm_aes, smp->tk, smp->rrnd, smp->prnd, stk); 9798aab4757SVinicius Costa Gomes 980f7aa611aSVinicius Costa Gomes memset(stk + smp->enc_key_size, 0, 981f7aa611aSVinicius Costa Gomes SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size); 9828aab4757SVinicius Costa Gomes 983861580a9SJohan Hedberg if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags)) 984861580a9SJohan Hedberg return SMP_UNSPECIFIED; 9858aab4757SVinicius Costa Gomes 9868aab4757SVinicius Costa Gomes hci_le_start_enc(hcon, ediv, rand, stk); 987f7aa611aSVinicius Costa Gomes hcon->enc_key_size = smp->enc_key_size; 988fe59a05fSJohan Hedberg set_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags); 9898aab4757SVinicius Costa Gomes } else { 990fff3490fSJohan Hedberg u8 stk[16], auth; 991fe39c7b2SMarcel Holtmann __le64 rand = 0; 992fe39c7b2SMarcel Holtmann __le16 ediv = 0; 9938aab4757SVinicius Costa Gomes 994943a732aSJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd), 995943a732aSJohan Hedberg smp->prnd); 9968aab4757SVinicius Costa Gomes 997e491eaf3SJohan Hedberg smp_s1(smp->tfm_aes, smp->tk, smp->prnd, smp->rrnd, stk); 9988aab4757SVinicius Costa Gomes 999f7aa611aSVinicius Costa Gomes memset(stk + smp->enc_key_size, 0, 1000f7aa611aSVinicius Costa Gomes SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size); 10018aab4757SVinicius Costa Gomes 1002fff3490fSJohan Hedberg if (hcon->pending_sec_level == BT_SECURITY_HIGH) 1003fff3490fSJohan Hedberg auth = 1; 1004fff3490fSJohan Hedberg else 1005fff3490fSJohan Hedberg auth = 0; 1006fff3490fSJohan Hedberg 10077d5843b7SJohan Hedberg /* Even though there's no _SLAVE suffix this is the 10087d5843b7SJohan Hedberg * slave STK we're adding for later lookup (the master 10097d5843b7SJohan Hedberg * STK never needs to be stored). 10107d5843b7SJohan Hedberg */ 1011ce39fb4eSMarcel Holtmann hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, 10122ceba539SJohan Hedberg SMP_STK, auth, stk, smp->enc_key_size, ediv, rand); 10138aab4757SVinicius Costa Gomes } 10148aab4757SVinicius Costa Gomes 1015861580a9SJohan Hedberg return 0; 10168aab4757SVinicius Costa Gomes } 10178aab4757SVinicius Costa Gomes 101844f1a7abSJohan Hedberg static void smp_notify_keys(struct l2cap_conn *conn) 101944f1a7abSJohan Hedberg { 102044f1a7abSJohan Hedberg struct l2cap_chan *chan = conn->smp; 102144f1a7abSJohan Hedberg struct smp_chan *smp = chan->data; 102244f1a7abSJohan Hedberg struct hci_conn *hcon = conn->hcon; 102344f1a7abSJohan Hedberg struct hci_dev *hdev = hcon->hdev; 102444f1a7abSJohan Hedberg struct smp_cmd_pairing *req = (void *) &smp->preq[1]; 102544f1a7abSJohan Hedberg struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1]; 102644f1a7abSJohan Hedberg bool persistent; 102744f1a7abSJohan Hedberg 102844f1a7abSJohan Hedberg if (smp->remote_irk) { 102944f1a7abSJohan Hedberg mgmt_new_irk(hdev, smp->remote_irk); 103044f1a7abSJohan Hedberg /* Now that user space can be considered to know the 103144f1a7abSJohan Hedberg * identity address track the connection based on it 1032b5ae344dSJohan Hedberg * from now on (assuming this is an LE link). 103344f1a7abSJohan Hedberg */ 1034b5ae344dSJohan Hedberg if (hcon->type == LE_LINK) { 103544f1a7abSJohan Hedberg bacpy(&hcon->dst, &smp->remote_irk->bdaddr); 103644f1a7abSJohan Hedberg hcon->dst_type = smp->remote_irk->addr_type; 1037f3d82d0cSJohan Hedberg queue_work(hdev->workqueue, &conn->id_addr_update_work); 1038b5ae344dSJohan Hedberg } 103944f1a7abSJohan Hedberg 104044f1a7abSJohan Hedberg /* When receiving an indentity resolving key for 104144f1a7abSJohan Hedberg * a remote device that does not use a resolvable 104244f1a7abSJohan Hedberg * private address, just remove the key so that 104344f1a7abSJohan Hedberg * it is possible to use the controller white 104444f1a7abSJohan Hedberg * list for scanning. 104544f1a7abSJohan Hedberg * 104644f1a7abSJohan Hedberg * Userspace will have been told to not store 104744f1a7abSJohan Hedberg * this key at this point. So it is safe to 104844f1a7abSJohan Hedberg * just remove it. 104944f1a7abSJohan Hedberg */ 105044f1a7abSJohan Hedberg if (!bacmp(&smp->remote_irk->rpa, BDADDR_ANY)) { 1051adae20cbSJohan Hedberg list_del_rcu(&smp->remote_irk->list); 1052adae20cbSJohan Hedberg kfree_rcu(smp->remote_irk, rcu); 105344f1a7abSJohan Hedberg smp->remote_irk = NULL; 105444f1a7abSJohan Hedberg } 105544f1a7abSJohan Hedberg } 105644f1a7abSJohan Hedberg 1057b5ae344dSJohan Hedberg if (hcon->type == ACL_LINK) { 1058b5ae344dSJohan Hedberg if (hcon->key_type == HCI_LK_DEBUG_COMBINATION) 1059b5ae344dSJohan Hedberg persistent = false; 1060b5ae344dSJohan Hedberg else 1061b5ae344dSJohan Hedberg persistent = !test_bit(HCI_CONN_FLUSH_KEY, 1062b5ae344dSJohan Hedberg &hcon->flags); 1063b5ae344dSJohan Hedberg } else { 106444f1a7abSJohan Hedberg /* The LTKs and CSRKs should be persistent only if both sides 106544f1a7abSJohan Hedberg * had the bonding bit set in their authentication requests. 106644f1a7abSJohan Hedberg */ 1067b5ae344dSJohan Hedberg persistent = !!((req->auth_req & rsp->auth_req) & 1068b5ae344dSJohan Hedberg SMP_AUTH_BONDING); 1069b5ae344dSJohan Hedberg } 1070b5ae344dSJohan Hedberg 107144f1a7abSJohan Hedberg 107244f1a7abSJohan Hedberg if (smp->csrk) { 107344f1a7abSJohan Hedberg smp->csrk->bdaddr_type = hcon->dst_type; 107444f1a7abSJohan Hedberg bacpy(&smp->csrk->bdaddr, &hcon->dst); 107544f1a7abSJohan Hedberg mgmt_new_csrk(hdev, smp->csrk, persistent); 107644f1a7abSJohan Hedberg } 107744f1a7abSJohan Hedberg 107844f1a7abSJohan Hedberg if (smp->slave_csrk) { 107944f1a7abSJohan Hedberg smp->slave_csrk->bdaddr_type = hcon->dst_type; 108044f1a7abSJohan Hedberg bacpy(&smp->slave_csrk->bdaddr, &hcon->dst); 108144f1a7abSJohan Hedberg mgmt_new_csrk(hdev, smp->slave_csrk, persistent); 108244f1a7abSJohan Hedberg } 108344f1a7abSJohan Hedberg 108444f1a7abSJohan Hedberg if (smp->ltk) { 108544f1a7abSJohan Hedberg smp->ltk->bdaddr_type = hcon->dst_type; 108644f1a7abSJohan Hedberg bacpy(&smp->ltk->bdaddr, &hcon->dst); 108744f1a7abSJohan Hedberg mgmt_new_ltk(hdev, smp->ltk, persistent); 108844f1a7abSJohan Hedberg } 108944f1a7abSJohan Hedberg 109044f1a7abSJohan Hedberg if (smp->slave_ltk) { 109144f1a7abSJohan Hedberg smp->slave_ltk->bdaddr_type = hcon->dst_type; 109244f1a7abSJohan Hedberg bacpy(&smp->slave_ltk->bdaddr, &hcon->dst); 109344f1a7abSJohan Hedberg mgmt_new_ltk(hdev, smp->slave_ltk, persistent); 109444f1a7abSJohan Hedberg } 10956a77083aSJohan Hedberg 10966a77083aSJohan Hedberg if (smp->link_key) { 1097e3befab9SJohan Hedberg struct link_key *key; 1098e3befab9SJohan Hedberg u8 type; 1099e3befab9SJohan Hedberg 1100e3befab9SJohan Hedberg if (test_bit(SMP_FLAG_DEBUG_KEY, &smp->flags)) 1101e3befab9SJohan Hedberg type = HCI_LK_DEBUG_COMBINATION; 1102e3befab9SJohan Hedberg else if (hcon->sec_level == BT_SECURITY_FIPS) 1103e3befab9SJohan Hedberg type = HCI_LK_AUTH_COMBINATION_P256; 1104e3befab9SJohan Hedberg else 1105e3befab9SJohan Hedberg type = HCI_LK_UNAUTH_COMBINATION_P256; 1106e3befab9SJohan Hedberg 1107e3befab9SJohan Hedberg key = hci_add_link_key(hdev, smp->conn->hcon, &hcon->dst, 1108e3befab9SJohan Hedberg smp->link_key, type, 0, &persistent); 1109e3befab9SJohan Hedberg if (key) { 1110e3befab9SJohan Hedberg mgmt_new_link_key(hdev, key, persistent); 1111e3befab9SJohan Hedberg 1112e3befab9SJohan Hedberg /* Don't keep debug keys around if the relevant 1113e3befab9SJohan Hedberg * flag is not set. 1114e3befab9SJohan Hedberg */ 1115d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_KEEP_DEBUG_KEYS) && 1116e3befab9SJohan Hedberg key->type == HCI_LK_DEBUG_COMBINATION) { 1117e3befab9SJohan Hedberg list_del_rcu(&key->list); 1118e3befab9SJohan Hedberg kfree_rcu(key, rcu); 1119e3befab9SJohan Hedberg } 1120e3befab9SJohan Hedberg } 11216a77083aSJohan Hedberg } 11226a77083aSJohan Hedberg } 11236a77083aSJohan Hedberg 1124d3e54a87SJohan Hedberg static void sc_add_ltk(struct smp_chan *smp) 1125d3e54a87SJohan Hedberg { 1126d3e54a87SJohan Hedberg struct hci_conn *hcon = smp->conn->hcon; 1127d3e54a87SJohan Hedberg u8 key_type, auth; 1128d3e54a87SJohan Hedberg 1129d3e54a87SJohan Hedberg if (test_bit(SMP_FLAG_DEBUG_KEY, &smp->flags)) 1130d3e54a87SJohan Hedberg key_type = SMP_LTK_P256_DEBUG; 1131d3e54a87SJohan Hedberg else 1132d3e54a87SJohan Hedberg key_type = SMP_LTK_P256; 1133d3e54a87SJohan Hedberg 1134d3e54a87SJohan Hedberg if (hcon->pending_sec_level == BT_SECURITY_FIPS) 1135d3e54a87SJohan Hedberg auth = 1; 1136d3e54a87SJohan Hedberg else 1137d3e54a87SJohan Hedberg auth = 0; 1138d3e54a87SJohan Hedberg 1139d3e54a87SJohan Hedberg memset(smp->tk + smp->enc_key_size, 0, 1140d3e54a87SJohan Hedberg SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size); 1141d3e54a87SJohan Hedberg 1142d3e54a87SJohan Hedberg smp->ltk = hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, 1143d3e54a87SJohan Hedberg key_type, auth, smp->tk, smp->enc_key_size, 1144d3e54a87SJohan Hedberg 0, 0); 1145d3e54a87SJohan Hedberg } 1146d3e54a87SJohan Hedberg 11476a77083aSJohan Hedberg static void sc_generate_link_key(struct smp_chan *smp) 11486a77083aSJohan Hedberg { 11496a77083aSJohan Hedberg /* These constants are as specified in the core specification. 11506a77083aSJohan Hedberg * In ASCII they spell out to 'tmp1' and 'lebr'. 11516a77083aSJohan Hedberg */ 11526a77083aSJohan Hedberg const u8 tmp1[4] = { 0x31, 0x70, 0x6d, 0x74 }; 11536a77083aSJohan Hedberg const u8 lebr[4] = { 0x72, 0x62, 0x65, 0x6c }; 11546a77083aSJohan Hedberg 11556a77083aSJohan Hedberg smp->link_key = kzalloc(16, GFP_KERNEL); 11566a77083aSJohan Hedberg if (!smp->link_key) 11576a77083aSJohan Hedberg return; 11586a77083aSJohan Hedberg 11596a77083aSJohan Hedberg if (smp_h6(smp->tfm_cmac, smp->tk, tmp1, smp->link_key)) { 1160276812ecSMarcel Holtmann kzfree(smp->link_key); 11616a77083aSJohan Hedberg smp->link_key = NULL; 11626a77083aSJohan Hedberg return; 11636a77083aSJohan Hedberg } 11646a77083aSJohan Hedberg 11656a77083aSJohan Hedberg if (smp_h6(smp->tfm_cmac, smp->link_key, lebr, smp->link_key)) { 1166276812ecSMarcel Holtmann kzfree(smp->link_key); 11676a77083aSJohan Hedberg smp->link_key = NULL; 11686a77083aSJohan Hedberg return; 11696a77083aSJohan Hedberg } 117044f1a7abSJohan Hedberg } 117144f1a7abSJohan Hedberg 1172b28b4943SJohan Hedberg static void smp_allow_key_dist(struct smp_chan *smp) 1173b28b4943SJohan Hedberg { 1174b28b4943SJohan Hedberg /* Allow the first expected phase 3 PDU. The rest of the PDUs 1175b28b4943SJohan Hedberg * will be allowed in each PDU handler to ensure we receive 1176b28b4943SJohan Hedberg * them in the correct order. 1177b28b4943SJohan Hedberg */ 1178b28b4943SJohan Hedberg if (smp->remote_key_dist & SMP_DIST_ENC_KEY) 1179b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_ENCRYPT_INFO); 1180b28b4943SJohan Hedberg else if (smp->remote_key_dist & SMP_DIST_ID_KEY) 1181b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO); 1182b28b4943SJohan Hedberg else if (smp->remote_key_dist & SMP_DIST_SIGN) 1183b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO); 1184b28b4943SJohan Hedberg } 1185b28b4943SJohan Hedberg 1186b5ae344dSJohan Hedberg static void sc_generate_ltk(struct smp_chan *smp) 1187b5ae344dSJohan Hedberg { 1188b5ae344dSJohan Hedberg /* These constants are as specified in the core specification. 1189b5ae344dSJohan Hedberg * In ASCII they spell out to 'tmp2' and 'brle'. 1190b5ae344dSJohan Hedberg */ 1191b5ae344dSJohan Hedberg const u8 tmp2[4] = { 0x32, 0x70, 0x6d, 0x74 }; 1192b5ae344dSJohan Hedberg const u8 brle[4] = { 0x65, 0x6c, 0x72, 0x62 }; 1193b5ae344dSJohan Hedberg struct hci_conn *hcon = smp->conn->hcon; 1194b5ae344dSJohan Hedberg struct hci_dev *hdev = hcon->hdev; 1195b5ae344dSJohan Hedberg struct link_key *key; 1196b5ae344dSJohan Hedberg 1197b5ae344dSJohan Hedberg key = hci_find_link_key(hdev, &hcon->dst); 1198b5ae344dSJohan Hedberg if (!key) { 1199b5ae344dSJohan Hedberg BT_ERR("%s No Link Key found to generate LTK", hdev->name); 1200b5ae344dSJohan Hedberg return; 1201b5ae344dSJohan Hedberg } 1202b5ae344dSJohan Hedberg 1203b5ae344dSJohan Hedberg if (key->type == HCI_LK_DEBUG_COMBINATION) 1204b5ae344dSJohan Hedberg set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags); 1205b5ae344dSJohan Hedberg 1206b5ae344dSJohan Hedberg if (smp_h6(smp->tfm_cmac, key->val, tmp2, smp->tk)) 1207b5ae344dSJohan Hedberg return; 1208b5ae344dSJohan Hedberg 1209b5ae344dSJohan Hedberg if (smp_h6(smp->tfm_cmac, smp->tk, brle, smp->tk)) 1210b5ae344dSJohan Hedberg return; 1211b5ae344dSJohan Hedberg 1212b5ae344dSJohan Hedberg sc_add_ltk(smp); 1213b5ae344dSJohan Hedberg } 1214b5ae344dSJohan Hedberg 1215d6268e86SJohan Hedberg static void smp_distribute_keys(struct smp_chan *smp) 121644f1a7abSJohan Hedberg { 121744f1a7abSJohan Hedberg struct smp_cmd_pairing *req, *rsp; 121886d1407cSJohan Hedberg struct l2cap_conn *conn = smp->conn; 121944f1a7abSJohan Hedberg struct hci_conn *hcon = conn->hcon; 122044f1a7abSJohan Hedberg struct hci_dev *hdev = hcon->hdev; 122144f1a7abSJohan Hedberg __u8 *keydist; 122244f1a7abSJohan Hedberg 122344f1a7abSJohan Hedberg BT_DBG("conn %p", conn); 122444f1a7abSJohan Hedberg 122544f1a7abSJohan Hedberg rsp = (void *) &smp->prsp[1]; 122644f1a7abSJohan Hedberg 122744f1a7abSJohan Hedberg /* The responder sends its keys first */ 1228b28b4943SJohan Hedberg if (hcon->out && (smp->remote_key_dist & KEY_DIST_MASK)) { 1229b28b4943SJohan Hedberg smp_allow_key_dist(smp); 123086d1407cSJohan Hedberg return; 1231b28b4943SJohan Hedberg } 123244f1a7abSJohan Hedberg 123344f1a7abSJohan Hedberg req = (void *) &smp->preq[1]; 123444f1a7abSJohan Hedberg 123544f1a7abSJohan Hedberg if (hcon->out) { 123644f1a7abSJohan Hedberg keydist = &rsp->init_key_dist; 123744f1a7abSJohan Hedberg *keydist &= req->init_key_dist; 123844f1a7abSJohan Hedberg } else { 123944f1a7abSJohan Hedberg keydist = &rsp->resp_key_dist; 124044f1a7abSJohan Hedberg *keydist &= req->resp_key_dist; 124144f1a7abSJohan Hedberg } 124244f1a7abSJohan Hedberg 12436a77083aSJohan Hedberg if (test_bit(SMP_FLAG_SC, &smp->flags)) { 1244b5ae344dSJohan Hedberg if (hcon->type == LE_LINK && (*keydist & SMP_DIST_LINK_KEY)) 12456a77083aSJohan Hedberg sc_generate_link_key(smp); 1246b5ae344dSJohan Hedberg if (hcon->type == ACL_LINK && (*keydist & SMP_DIST_ENC_KEY)) 1247b5ae344dSJohan Hedberg sc_generate_ltk(smp); 12486a77083aSJohan Hedberg 12496a77083aSJohan Hedberg /* Clear the keys which are generated but not distributed */ 12506a77083aSJohan Hedberg *keydist &= ~SMP_SC_NO_DIST; 12516a77083aSJohan Hedberg } 12526a77083aSJohan Hedberg 125344f1a7abSJohan Hedberg BT_DBG("keydist 0x%x", *keydist); 125444f1a7abSJohan Hedberg 125544f1a7abSJohan Hedberg if (*keydist & SMP_DIST_ENC_KEY) { 125644f1a7abSJohan Hedberg struct smp_cmd_encrypt_info enc; 125744f1a7abSJohan Hedberg struct smp_cmd_master_ident ident; 125844f1a7abSJohan Hedberg struct smp_ltk *ltk; 125944f1a7abSJohan Hedberg u8 authenticated; 126044f1a7abSJohan Hedberg __le16 ediv; 126144f1a7abSJohan Hedberg __le64 rand; 126244f1a7abSJohan Hedberg 126344f1a7abSJohan Hedberg get_random_bytes(enc.ltk, sizeof(enc.ltk)); 126444f1a7abSJohan Hedberg get_random_bytes(&ediv, sizeof(ediv)); 126544f1a7abSJohan Hedberg get_random_bytes(&rand, sizeof(rand)); 126644f1a7abSJohan Hedberg 126744f1a7abSJohan Hedberg smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc); 126844f1a7abSJohan Hedberg 126944f1a7abSJohan Hedberg authenticated = hcon->sec_level == BT_SECURITY_HIGH; 127044f1a7abSJohan Hedberg ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, 127144f1a7abSJohan Hedberg SMP_LTK_SLAVE, authenticated, enc.ltk, 127244f1a7abSJohan Hedberg smp->enc_key_size, ediv, rand); 127344f1a7abSJohan Hedberg smp->slave_ltk = ltk; 127444f1a7abSJohan Hedberg 127544f1a7abSJohan Hedberg ident.ediv = ediv; 127644f1a7abSJohan Hedberg ident.rand = rand; 127744f1a7abSJohan Hedberg 127844f1a7abSJohan Hedberg smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident); 127944f1a7abSJohan Hedberg 128044f1a7abSJohan Hedberg *keydist &= ~SMP_DIST_ENC_KEY; 128144f1a7abSJohan Hedberg } 128244f1a7abSJohan Hedberg 128344f1a7abSJohan Hedberg if (*keydist & SMP_DIST_ID_KEY) { 128444f1a7abSJohan Hedberg struct smp_cmd_ident_addr_info addrinfo; 128544f1a7abSJohan Hedberg struct smp_cmd_ident_info idinfo; 128644f1a7abSJohan Hedberg 128744f1a7abSJohan Hedberg memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk)); 128844f1a7abSJohan Hedberg 128944f1a7abSJohan Hedberg smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo); 129044f1a7abSJohan Hedberg 129144f1a7abSJohan Hedberg /* The hci_conn contains the local identity address 129244f1a7abSJohan Hedberg * after the connection has been established. 129344f1a7abSJohan Hedberg * 129444f1a7abSJohan Hedberg * This is true even when the connection has been 129544f1a7abSJohan Hedberg * established using a resolvable random address. 129644f1a7abSJohan Hedberg */ 129744f1a7abSJohan Hedberg bacpy(&addrinfo.bdaddr, &hcon->src); 129844f1a7abSJohan Hedberg addrinfo.addr_type = hcon->src_type; 129944f1a7abSJohan Hedberg 130044f1a7abSJohan Hedberg smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo), 130144f1a7abSJohan Hedberg &addrinfo); 130244f1a7abSJohan Hedberg 130344f1a7abSJohan Hedberg *keydist &= ~SMP_DIST_ID_KEY; 130444f1a7abSJohan Hedberg } 130544f1a7abSJohan Hedberg 130644f1a7abSJohan Hedberg if (*keydist & SMP_DIST_SIGN) { 130744f1a7abSJohan Hedberg struct smp_cmd_sign_info sign; 130844f1a7abSJohan Hedberg struct smp_csrk *csrk; 130944f1a7abSJohan Hedberg 131044f1a7abSJohan Hedberg /* Generate a new random key */ 131144f1a7abSJohan Hedberg get_random_bytes(sign.csrk, sizeof(sign.csrk)); 131244f1a7abSJohan Hedberg 131344f1a7abSJohan Hedberg csrk = kzalloc(sizeof(*csrk), GFP_KERNEL); 131444f1a7abSJohan Hedberg if (csrk) { 13154cd3928aSJohan Hedberg if (hcon->sec_level > BT_SECURITY_MEDIUM) 13164cd3928aSJohan Hedberg csrk->type = MGMT_CSRK_LOCAL_AUTHENTICATED; 13174cd3928aSJohan Hedberg else 13184cd3928aSJohan Hedberg csrk->type = MGMT_CSRK_LOCAL_UNAUTHENTICATED; 131944f1a7abSJohan Hedberg memcpy(csrk->val, sign.csrk, sizeof(csrk->val)); 132044f1a7abSJohan Hedberg } 132144f1a7abSJohan Hedberg smp->slave_csrk = csrk; 132244f1a7abSJohan Hedberg 132344f1a7abSJohan Hedberg smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign); 132444f1a7abSJohan Hedberg 132544f1a7abSJohan Hedberg *keydist &= ~SMP_DIST_SIGN; 132644f1a7abSJohan Hedberg } 132744f1a7abSJohan Hedberg 132844f1a7abSJohan Hedberg /* If there are still keys to be received wait for them */ 1329b28b4943SJohan Hedberg if (smp->remote_key_dist & KEY_DIST_MASK) { 1330b28b4943SJohan Hedberg smp_allow_key_dist(smp); 133186d1407cSJohan Hedberg return; 1332b28b4943SJohan Hedberg } 133344f1a7abSJohan Hedberg 133444f1a7abSJohan Hedberg set_bit(SMP_FLAG_COMPLETE, &smp->flags); 133544f1a7abSJohan Hedberg smp_notify_keys(conn); 133644f1a7abSJohan Hedberg 133744f1a7abSJohan Hedberg smp_chan_destroy(conn); 133844f1a7abSJohan Hedberg } 133944f1a7abSJohan Hedberg 1340b68fda68SJohan Hedberg static void smp_timeout(struct work_struct *work) 1341b68fda68SJohan Hedberg { 1342b68fda68SJohan Hedberg struct smp_chan *smp = container_of(work, struct smp_chan, 1343b68fda68SJohan Hedberg security_timer.work); 1344b68fda68SJohan Hedberg struct l2cap_conn *conn = smp->conn; 1345b68fda68SJohan Hedberg 1346b68fda68SJohan Hedberg BT_DBG("conn %p", conn); 1347b68fda68SJohan Hedberg 13481e91c29eSJohan Hedberg hci_disconnect(conn->hcon, HCI_ERROR_REMOTE_USER_TERM); 1349b68fda68SJohan Hedberg } 1350b68fda68SJohan Hedberg 13518aab4757SVinicius Costa Gomes static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) 13528aab4757SVinicius Costa Gomes { 13535d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 13548aab4757SVinicius Costa Gomes struct smp_chan *smp; 13558aab4757SVinicius Costa Gomes 1356f1560463SMarcel Holtmann smp = kzalloc(sizeof(*smp), GFP_ATOMIC); 1357fc75cc86SJohan Hedberg if (!smp) 13588aab4757SVinicius Costa Gomes return NULL; 13598aab4757SVinicius Costa Gomes 13606a7bd103SJohan Hedberg smp->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC); 13616a7bd103SJohan Hedberg if (IS_ERR(smp->tfm_aes)) { 13626a7bd103SJohan Hedberg BT_ERR("Unable to create ECB crypto context"); 1363276812ecSMarcel Holtmann kzfree(smp); 13646a7bd103SJohan Hedberg return NULL; 13656a7bd103SJohan Hedberg } 13666a7bd103SJohan Hedberg 1367407cecf6SJohan Hedberg smp->tfm_cmac = crypto_alloc_hash("cmac(aes)", 0, CRYPTO_ALG_ASYNC); 1368407cecf6SJohan Hedberg if (IS_ERR(smp->tfm_cmac)) { 1369407cecf6SJohan Hedberg BT_ERR("Unable to create CMAC crypto context"); 1370407cecf6SJohan Hedberg crypto_free_blkcipher(smp->tfm_aes); 1371276812ecSMarcel Holtmann kzfree(smp); 1372407cecf6SJohan Hedberg return NULL; 1373407cecf6SJohan Hedberg } 1374407cecf6SJohan Hedberg 13758aab4757SVinicius Costa Gomes smp->conn = conn; 13765d88cc73SJohan Hedberg chan->data = smp; 13778aab4757SVinicius Costa Gomes 1378b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_FAIL); 1379b28b4943SJohan Hedberg 1380b68fda68SJohan Hedberg INIT_DELAYED_WORK(&smp->security_timer, smp_timeout); 1381b68fda68SJohan Hedberg 13828aab4757SVinicius Costa Gomes hci_conn_hold(conn->hcon); 13838aab4757SVinicius Costa Gomes 13848aab4757SVinicius Costa Gomes return smp; 13858aab4757SVinicius Costa Gomes } 13868aab4757SVinicius Costa Gomes 1387760b018bSJohan Hedberg static int sc_mackey_and_ltk(struct smp_chan *smp, u8 mackey[16], u8 ltk[16]) 1388760b018bSJohan Hedberg { 1389760b018bSJohan Hedberg struct hci_conn *hcon = smp->conn->hcon; 1390760b018bSJohan Hedberg u8 *na, *nb, a[7], b[7]; 1391760b018bSJohan Hedberg 1392760b018bSJohan Hedberg if (hcon->out) { 1393760b018bSJohan Hedberg na = smp->prnd; 1394760b018bSJohan Hedberg nb = smp->rrnd; 1395760b018bSJohan Hedberg } else { 1396760b018bSJohan Hedberg na = smp->rrnd; 1397760b018bSJohan Hedberg nb = smp->prnd; 1398760b018bSJohan Hedberg } 1399760b018bSJohan Hedberg 1400760b018bSJohan Hedberg memcpy(a, &hcon->init_addr, 6); 1401760b018bSJohan Hedberg memcpy(b, &hcon->resp_addr, 6); 1402760b018bSJohan Hedberg a[6] = hcon->init_addr_type; 1403760b018bSJohan Hedberg b[6] = hcon->resp_addr_type; 1404760b018bSJohan Hedberg 1405760b018bSJohan Hedberg return smp_f5(smp->tfm_cmac, smp->dhkey, na, nb, a, b, mackey, ltk); 1406760b018bSJohan Hedberg } 1407760b018bSJohan Hedberg 140838606f14SJohan Hedberg static void sc_dhkey_check(struct smp_chan *smp) 1409760b018bSJohan Hedberg { 1410760b018bSJohan Hedberg struct hci_conn *hcon = smp->conn->hcon; 1411760b018bSJohan Hedberg struct smp_cmd_dhkey_check check; 1412760b018bSJohan Hedberg u8 a[7], b[7], *local_addr, *remote_addr; 1413760b018bSJohan Hedberg u8 io_cap[3], r[16]; 1414760b018bSJohan Hedberg 1415760b018bSJohan Hedberg memcpy(a, &hcon->init_addr, 6); 1416760b018bSJohan Hedberg memcpy(b, &hcon->resp_addr, 6); 1417760b018bSJohan Hedberg a[6] = hcon->init_addr_type; 1418760b018bSJohan Hedberg b[6] = hcon->resp_addr_type; 1419760b018bSJohan Hedberg 1420760b018bSJohan Hedberg if (hcon->out) { 1421760b018bSJohan Hedberg local_addr = a; 1422760b018bSJohan Hedberg remote_addr = b; 1423760b018bSJohan Hedberg memcpy(io_cap, &smp->preq[1], 3); 1424760b018bSJohan Hedberg } else { 1425760b018bSJohan Hedberg local_addr = b; 1426760b018bSJohan Hedberg remote_addr = a; 1427760b018bSJohan Hedberg memcpy(io_cap, &smp->prsp[1], 3); 1428760b018bSJohan Hedberg } 1429760b018bSJohan Hedberg 1430dddd3059SJohan Hedberg memset(r, 0, sizeof(r)); 1431dddd3059SJohan Hedberg 1432dddd3059SJohan Hedberg if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY) 143338606f14SJohan Hedberg put_unaligned_le32(hcon->passkey_notify, r); 1434760b018bSJohan Hedberg 1435a29b0733SJohan Hedberg if (smp->method == REQ_OOB) 1436a29b0733SJohan Hedberg memcpy(r, smp->rr, 16); 1437a29b0733SJohan Hedberg 1438760b018bSJohan Hedberg smp_f6(smp->tfm_cmac, smp->mackey, smp->prnd, smp->rrnd, r, io_cap, 1439760b018bSJohan Hedberg local_addr, remote_addr, check.e); 1440760b018bSJohan Hedberg 1441760b018bSJohan Hedberg smp_send_cmd(smp->conn, SMP_CMD_DHKEY_CHECK, sizeof(check), &check); 1442dddd3059SJohan Hedberg } 1443dddd3059SJohan Hedberg 144438606f14SJohan Hedberg static u8 sc_passkey_send_confirm(struct smp_chan *smp) 144538606f14SJohan Hedberg { 144638606f14SJohan Hedberg struct l2cap_conn *conn = smp->conn; 144738606f14SJohan Hedberg struct hci_conn *hcon = conn->hcon; 144838606f14SJohan Hedberg struct smp_cmd_pairing_confirm cfm; 144938606f14SJohan Hedberg u8 r; 145038606f14SJohan Hedberg 145138606f14SJohan Hedberg r = ((hcon->passkey_notify >> smp->passkey_round) & 0x01); 145238606f14SJohan Hedberg r |= 0x80; 145338606f14SJohan Hedberg 145438606f14SJohan Hedberg get_random_bytes(smp->prnd, sizeof(smp->prnd)); 145538606f14SJohan Hedberg 145638606f14SJohan Hedberg if (smp_f4(smp->tfm_cmac, smp->local_pk, smp->remote_pk, smp->prnd, r, 145738606f14SJohan Hedberg cfm.confirm_val)) 145838606f14SJohan Hedberg return SMP_UNSPECIFIED; 145938606f14SJohan Hedberg 146038606f14SJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cfm), &cfm); 146138606f14SJohan Hedberg 146238606f14SJohan Hedberg return 0; 146338606f14SJohan Hedberg } 146438606f14SJohan Hedberg 146538606f14SJohan Hedberg static u8 sc_passkey_round(struct smp_chan *smp, u8 smp_op) 146638606f14SJohan Hedberg { 146738606f14SJohan Hedberg struct l2cap_conn *conn = smp->conn; 146838606f14SJohan Hedberg struct hci_conn *hcon = conn->hcon; 146938606f14SJohan Hedberg struct hci_dev *hdev = hcon->hdev; 147038606f14SJohan Hedberg u8 cfm[16], r; 147138606f14SJohan Hedberg 147238606f14SJohan Hedberg /* Ignore the PDU if we've already done 20 rounds (0 - 19) */ 147338606f14SJohan Hedberg if (smp->passkey_round >= 20) 147438606f14SJohan Hedberg return 0; 147538606f14SJohan Hedberg 147638606f14SJohan Hedberg switch (smp_op) { 147738606f14SJohan Hedberg case SMP_CMD_PAIRING_RANDOM: 147838606f14SJohan Hedberg r = ((hcon->passkey_notify >> smp->passkey_round) & 0x01); 147938606f14SJohan Hedberg r |= 0x80; 148038606f14SJohan Hedberg 148138606f14SJohan Hedberg if (smp_f4(smp->tfm_cmac, smp->remote_pk, smp->local_pk, 148238606f14SJohan Hedberg smp->rrnd, r, cfm)) 148338606f14SJohan Hedberg return SMP_UNSPECIFIED; 148438606f14SJohan Hedberg 148538606f14SJohan Hedberg if (memcmp(smp->pcnf, cfm, 16)) 148638606f14SJohan Hedberg return SMP_CONFIRM_FAILED; 148738606f14SJohan Hedberg 148838606f14SJohan Hedberg smp->passkey_round++; 148938606f14SJohan Hedberg 149038606f14SJohan Hedberg if (smp->passkey_round == 20) { 149138606f14SJohan Hedberg /* Generate MacKey and LTK */ 149238606f14SJohan Hedberg if (sc_mackey_and_ltk(smp, smp->mackey, smp->tk)) 149338606f14SJohan Hedberg return SMP_UNSPECIFIED; 149438606f14SJohan Hedberg } 149538606f14SJohan Hedberg 149638606f14SJohan Hedberg /* The round is only complete when the initiator 149738606f14SJohan Hedberg * receives pairing random. 149838606f14SJohan Hedberg */ 149938606f14SJohan Hedberg if (!hcon->out) { 150038606f14SJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, 150138606f14SJohan Hedberg sizeof(smp->prnd), smp->prnd); 1502d3e54a87SJohan Hedberg if (smp->passkey_round == 20) 150338606f14SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK); 1504d3e54a87SJohan Hedberg else 150538606f14SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); 150638606f14SJohan Hedberg return 0; 150738606f14SJohan Hedberg } 150838606f14SJohan Hedberg 150938606f14SJohan Hedberg /* Start the next round */ 151038606f14SJohan Hedberg if (smp->passkey_round != 20) 151138606f14SJohan Hedberg return sc_passkey_round(smp, 0); 151238606f14SJohan Hedberg 151338606f14SJohan Hedberg /* Passkey rounds are complete - start DHKey Check */ 151438606f14SJohan Hedberg sc_dhkey_check(smp); 151538606f14SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK); 151638606f14SJohan Hedberg 151738606f14SJohan Hedberg break; 151838606f14SJohan Hedberg 151938606f14SJohan Hedberg case SMP_CMD_PAIRING_CONFIRM: 152038606f14SJohan Hedberg if (test_bit(SMP_FLAG_WAIT_USER, &smp->flags)) { 152138606f14SJohan Hedberg set_bit(SMP_FLAG_CFM_PENDING, &smp->flags); 152238606f14SJohan Hedberg return 0; 152338606f14SJohan Hedberg } 152438606f14SJohan Hedberg 152538606f14SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM); 152638606f14SJohan Hedberg 152738606f14SJohan Hedberg if (hcon->out) { 152838606f14SJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, 152938606f14SJohan Hedberg sizeof(smp->prnd), smp->prnd); 153038606f14SJohan Hedberg return 0; 153138606f14SJohan Hedberg } 153238606f14SJohan Hedberg 153338606f14SJohan Hedberg return sc_passkey_send_confirm(smp); 153438606f14SJohan Hedberg 153538606f14SJohan Hedberg case SMP_CMD_PUBLIC_KEY: 153638606f14SJohan Hedberg default: 153738606f14SJohan Hedberg /* Initiating device starts the round */ 153838606f14SJohan Hedberg if (!hcon->out) 153938606f14SJohan Hedberg return 0; 154038606f14SJohan Hedberg 154138606f14SJohan Hedberg BT_DBG("%s Starting passkey round %u", hdev->name, 154238606f14SJohan Hedberg smp->passkey_round + 1); 154338606f14SJohan Hedberg 154438606f14SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); 154538606f14SJohan Hedberg 154638606f14SJohan Hedberg return sc_passkey_send_confirm(smp); 154738606f14SJohan Hedberg } 154838606f14SJohan Hedberg 154938606f14SJohan Hedberg return 0; 155038606f14SJohan Hedberg } 155138606f14SJohan Hedberg 1552dddd3059SJohan Hedberg static int sc_user_reply(struct smp_chan *smp, u16 mgmt_op, __le32 passkey) 1553dddd3059SJohan Hedberg { 155438606f14SJohan Hedberg struct l2cap_conn *conn = smp->conn; 155538606f14SJohan Hedberg struct hci_conn *hcon = conn->hcon; 155638606f14SJohan Hedberg u8 smp_op; 155738606f14SJohan Hedberg 155838606f14SJohan Hedberg clear_bit(SMP_FLAG_WAIT_USER, &smp->flags); 155938606f14SJohan Hedberg 1560dddd3059SJohan Hedberg switch (mgmt_op) { 1561dddd3059SJohan Hedberg case MGMT_OP_USER_PASSKEY_NEG_REPLY: 1562dddd3059SJohan Hedberg smp_failure(smp->conn, SMP_PASSKEY_ENTRY_FAILED); 1563dddd3059SJohan Hedberg return 0; 1564dddd3059SJohan Hedberg case MGMT_OP_USER_CONFIRM_NEG_REPLY: 1565dddd3059SJohan Hedberg smp_failure(smp->conn, SMP_NUMERIC_COMP_FAILED); 1566dddd3059SJohan Hedberg return 0; 156738606f14SJohan Hedberg case MGMT_OP_USER_PASSKEY_REPLY: 156838606f14SJohan Hedberg hcon->passkey_notify = le32_to_cpu(passkey); 156938606f14SJohan Hedberg smp->passkey_round = 0; 157038606f14SJohan Hedberg 157138606f14SJohan Hedberg if (test_and_clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags)) 157238606f14SJohan Hedberg smp_op = SMP_CMD_PAIRING_CONFIRM; 157338606f14SJohan Hedberg else 157438606f14SJohan Hedberg smp_op = 0; 157538606f14SJohan Hedberg 157638606f14SJohan Hedberg if (sc_passkey_round(smp, smp_op)) 157738606f14SJohan Hedberg return -EIO; 157838606f14SJohan Hedberg 157938606f14SJohan Hedberg return 0; 1580dddd3059SJohan Hedberg } 1581dddd3059SJohan Hedberg 1582d3e54a87SJohan Hedberg /* Initiator sends DHKey check first */ 1583d3e54a87SJohan Hedberg if (hcon->out) { 158438606f14SJohan Hedberg sc_dhkey_check(smp); 1585d3e54a87SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK); 1586d3e54a87SJohan Hedberg } else if (test_and_clear_bit(SMP_FLAG_DHKEY_PENDING, &smp->flags)) { 1587d3e54a87SJohan Hedberg sc_dhkey_check(smp); 1588d3e54a87SJohan Hedberg sc_add_ltk(smp); 1589d3e54a87SJohan Hedberg } 1590760b018bSJohan Hedberg 1591760b018bSJohan Hedberg return 0; 1592760b018bSJohan Hedberg } 1593760b018bSJohan Hedberg 15942b64d153SBrian Gix int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey) 15952b64d153SBrian Gix { 1596b10e8017SJohan Hedberg struct l2cap_conn *conn = hcon->l2cap_data; 15975d88cc73SJohan Hedberg struct l2cap_chan *chan; 15982b64d153SBrian Gix struct smp_chan *smp; 15992b64d153SBrian Gix u32 value; 1600fc75cc86SJohan Hedberg int err; 16012b64d153SBrian Gix 16022b64d153SBrian Gix BT_DBG(""); 16032b64d153SBrian Gix 1604fc75cc86SJohan Hedberg if (!conn) 16052b64d153SBrian Gix return -ENOTCONN; 16062b64d153SBrian Gix 16075d88cc73SJohan Hedberg chan = conn->smp; 16085d88cc73SJohan Hedberg if (!chan) 16095d88cc73SJohan Hedberg return -ENOTCONN; 16105d88cc73SJohan Hedberg 1611fc75cc86SJohan Hedberg l2cap_chan_lock(chan); 1612fc75cc86SJohan Hedberg if (!chan->data) { 1613fc75cc86SJohan Hedberg err = -ENOTCONN; 1614fc75cc86SJohan Hedberg goto unlock; 1615fc75cc86SJohan Hedberg } 1616fc75cc86SJohan Hedberg 16175d88cc73SJohan Hedberg smp = chan->data; 16182b64d153SBrian Gix 1619760b018bSJohan Hedberg if (test_bit(SMP_FLAG_SC, &smp->flags)) { 1620760b018bSJohan Hedberg err = sc_user_reply(smp, mgmt_op, passkey); 1621760b018bSJohan Hedberg goto unlock; 1622760b018bSJohan Hedberg } 1623760b018bSJohan Hedberg 16242b64d153SBrian Gix switch (mgmt_op) { 16252b64d153SBrian Gix case MGMT_OP_USER_PASSKEY_REPLY: 16262b64d153SBrian Gix value = le32_to_cpu(passkey); 1627943a732aSJohan Hedberg memset(smp->tk, 0, sizeof(smp->tk)); 16282b64d153SBrian Gix BT_DBG("PassKey: %d", value); 1629943a732aSJohan Hedberg put_unaligned_le32(value, smp->tk); 16302b64d153SBrian Gix /* Fall Through */ 16312b64d153SBrian Gix case MGMT_OP_USER_CONFIRM_REPLY: 16324a74d658SJohan Hedberg set_bit(SMP_FLAG_TK_VALID, &smp->flags); 16332b64d153SBrian Gix break; 16342b64d153SBrian Gix case MGMT_OP_USER_PASSKEY_NEG_REPLY: 16352b64d153SBrian Gix case MGMT_OP_USER_CONFIRM_NEG_REPLY: 163684794e11SJohan Hedberg smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED); 1637fc75cc86SJohan Hedberg err = 0; 1638fc75cc86SJohan Hedberg goto unlock; 16392b64d153SBrian Gix default: 164084794e11SJohan Hedberg smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED); 1641fc75cc86SJohan Hedberg err = -EOPNOTSUPP; 1642fc75cc86SJohan Hedberg goto unlock; 16432b64d153SBrian Gix } 16442b64d153SBrian Gix 1645fc75cc86SJohan Hedberg err = 0; 1646fc75cc86SJohan Hedberg 16472b64d153SBrian Gix /* If it is our turn to send Pairing Confirm, do so now */ 16481cc61144SJohan Hedberg if (test_bit(SMP_FLAG_CFM_PENDING, &smp->flags)) { 16491cc61144SJohan Hedberg u8 rsp = smp_confirm(smp); 16501cc61144SJohan Hedberg if (rsp) 16511cc61144SJohan Hedberg smp_failure(conn, rsp); 16521cc61144SJohan Hedberg } 16532b64d153SBrian Gix 1654fc75cc86SJohan Hedberg unlock: 1655fc75cc86SJohan Hedberg l2cap_chan_unlock(chan); 1656fc75cc86SJohan Hedberg return err; 16572b64d153SBrian Gix } 16582b64d153SBrian Gix 1659b5ae344dSJohan Hedberg static void build_bredr_pairing_cmd(struct smp_chan *smp, 1660b5ae344dSJohan Hedberg struct smp_cmd_pairing *req, 1661b5ae344dSJohan Hedberg struct smp_cmd_pairing *rsp) 1662b5ae344dSJohan Hedberg { 1663b5ae344dSJohan Hedberg struct l2cap_conn *conn = smp->conn; 1664b5ae344dSJohan Hedberg struct hci_dev *hdev = conn->hcon->hdev; 1665b5ae344dSJohan Hedberg u8 local_dist = 0, remote_dist = 0; 1666b5ae344dSJohan Hedberg 1667d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_BONDABLE)) { 1668b5ae344dSJohan Hedberg local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN; 1669b5ae344dSJohan Hedberg remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN; 1670b5ae344dSJohan Hedberg } 1671b5ae344dSJohan Hedberg 1672d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_RPA_RESOLVING)) 1673b5ae344dSJohan Hedberg remote_dist |= SMP_DIST_ID_KEY; 1674b5ae344dSJohan Hedberg 1675d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_PRIVACY)) 1676b5ae344dSJohan Hedberg local_dist |= SMP_DIST_ID_KEY; 1677b5ae344dSJohan Hedberg 1678b5ae344dSJohan Hedberg if (!rsp) { 1679b5ae344dSJohan Hedberg memset(req, 0, sizeof(*req)); 1680b5ae344dSJohan Hedberg 1681b5ae344dSJohan Hedberg req->init_key_dist = local_dist; 1682b5ae344dSJohan Hedberg req->resp_key_dist = remote_dist; 1683b5ae344dSJohan Hedberg req->max_key_size = SMP_MAX_ENC_KEY_SIZE; 1684b5ae344dSJohan Hedberg 1685b5ae344dSJohan Hedberg smp->remote_key_dist = remote_dist; 1686b5ae344dSJohan Hedberg 1687b5ae344dSJohan Hedberg return; 1688b5ae344dSJohan Hedberg } 1689b5ae344dSJohan Hedberg 1690b5ae344dSJohan Hedberg memset(rsp, 0, sizeof(*rsp)); 1691b5ae344dSJohan Hedberg 1692b5ae344dSJohan Hedberg rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE; 1693b5ae344dSJohan Hedberg rsp->init_key_dist = req->init_key_dist & remote_dist; 1694b5ae344dSJohan Hedberg rsp->resp_key_dist = req->resp_key_dist & local_dist; 1695b5ae344dSJohan Hedberg 1696b5ae344dSJohan Hedberg smp->remote_key_dist = rsp->init_key_dist; 1697b5ae344dSJohan Hedberg } 1698b5ae344dSJohan Hedberg 1699da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) 170088ba43b6SAnderson Briglia { 17013158c50cSVinicius Costa Gomes struct smp_cmd_pairing rsp, *req = (void *) skb->data; 1702fc75cc86SJohan Hedberg struct l2cap_chan *chan = conn->smp; 1703b3c6410bSJohan Hedberg struct hci_dev *hdev = conn->hcon->hdev; 17048aab4757SVinicius Costa Gomes struct smp_chan *smp; 1705c7262e71SJohan Hedberg u8 key_size, auth, sec_level; 17068aab4757SVinicius Costa Gomes int ret; 170788ba43b6SAnderson Briglia 170888ba43b6SAnderson Briglia BT_DBG("conn %p", conn); 170988ba43b6SAnderson Briglia 1710c46b98beSJohan Hedberg if (skb->len < sizeof(*req)) 171138e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 1712c46b98beSJohan Hedberg 171340bef302SJohan Hedberg if (conn->hcon->role != HCI_ROLE_SLAVE) 17142b64d153SBrian Gix return SMP_CMD_NOTSUPP; 17152b64d153SBrian Gix 1716fc75cc86SJohan Hedberg if (!chan->data) 17178aab4757SVinicius Costa Gomes smp = smp_chan_create(conn); 1718fc75cc86SJohan Hedberg else 17195d88cc73SJohan Hedberg smp = chan->data; 1720d26a2345SVinicius Costa Gomes 1721d08fd0e7SAndrei Emeltchenko if (!smp) 1722d08fd0e7SAndrei Emeltchenko return SMP_UNSPECIFIED; 1723d08fd0e7SAndrei Emeltchenko 1724c05b9339SJohan Hedberg /* We didn't start the pairing, so match remote */ 17250edb14deSJohan Hedberg auth = req->auth_req & AUTH_REQ_MASK(hdev); 1726c05b9339SJohan Hedberg 1727d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_BONDABLE) && 1728c05b9339SJohan Hedberg (auth & SMP_AUTH_BONDING)) 1729b3c6410bSJohan Hedberg return SMP_PAIRING_NOTSUPP; 1730b3c6410bSJohan Hedberg 1731d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SC_ONLY) && !(auth & SMP_AUTH_SC)) 1732903b71c7SJohan Hedberg return SMP_AUTH_REQUIREMENTS; 1733903b71c7SJohan Hedberg 17341c1def09SVinicius Costa Gomes smp->preq[0] = SMP_CMD_PAIRING_REQ; 17351c1def09SVinicius Costa Gomes memcpy(&smp->preq[1], req, sizeof(*req)); 17363158c50cSVinicius Costa Gomes skb_pull(skb, sizeof(*req)); 173788ba43b6SAnderson Briglia 1738b5ae344dSJohan Hedberg /* SMP over BR/EDR requires special treatment */ 1739b5ae344dSJohan Hedberg if (conn->hcon->type == ACL_LINK) { 1740b5ae344dSJohan Hedberg /* We must have a BR/EDR SC link */ 174108f63cc5SMarcel Holtmann if (!test_bit(HCI_CONN_AES_CCM, &conn->hcon->flags) && 1742b7cb93e5SMarcel Holtmann !hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP)) 1743b5ae344dSJohan Hedberg return SMP_CROSS_TRANSP_NOT_ALLOWED; 1744b5ae344dSJohan Hedberg 1745b5ae344dSJohan Hedberg set_bit(SMP_FLAG_SC, &smp->flags); 1746b5ae344dSJohan Hedberg 1747b5ae344dSJohan Hedberg build_bredr_pairing_cmd(smp, req, &rsp); 1748b5ae344dSJohan Hedberg 1749b5ae344dSJohan Hedberg key_size = min(req->max_key_size, rsp.max_key_size); 1750b5ae344dSJohan Hedberg if (check_enc_key_size(conn, key_size)) 1751b5ae344dSJohan Hedberg return SMP_ENC_KEY_SIZE; 1752b5ae344dSJohan Hedberg 1753b5ae344dSJohan Hedberg /* Clear bits which are generated but not distributed */ 1754b5ae344dSJohan Hedberg smp->remote_key_dist &= ~SMP_SC_NO_DIST; 1755b5ae344dSJohan Hedberg 1756b5ae344dSJohan Hedberg smp->prsp[0] = SMP_CMD_PAIRING_RSP; 1757b5ae344dSJohan Hedberg memcpy(&smp->prsp[1], &rsp, sizeof(rsp)); 1758b5ae344dSJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp); 1759b5ae344dSJohan Hedberg 1760b5ae344dSJohan Hedberg smp_distribute_keys(smp); 1761b5ae344dSJohan Hedberg return 0; 1762b5ae344dSJohan Hedberg } 1763b5ae344dSJohan Hedberg 17645e3d3d9bSJohan Hedberg build_pairing_cmd(conn, req, &rsp, auth); 17655e3d3d9bSJohan Hedberg 17665e3d3d9bSJohan Hedberg if (rsp.auth_req & SMP_AUTH_SC) 17675e3d3d9bSJohan Hedberg set_bit(SMP_FLAG_SC, &smp->flags); 17685e3d3d9bSJohan Hedberg 17695be5e275SJohan Hedberg if (conn->hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT) 17701afc2a1aSJohan Hedberg sec_level = BT_SECURITY_MEDIUM; 17711afc2a1aSJohan Hedberg else 1772c7262e71SJohan Hedberg sec_level = authreq_to_seclevel(auth); 17731afc2a1aSJohan Hedberg 1774c7262e71SJohan Hedberg if (sec_level > conn->hcon->pending_sec_level) 1775c7262e71SJohan Hedberg conn->hcon->pending_sec_level = sec_level; 1776fdde0a26SIdo Yariv 177749c922bbSStephen Hemminger /* If we need MITM check that it can be achieved */ 17782ed8f65cSJohan Hedberg if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) { 17792ed8f65cSJohan Hedberg u8 method; 17802ed8f65cSJohan Hedberg 17812ed8f65cSJohan Hedberg method = get_auth_method(smp, conn->hcon->io_capability, 17822ed8f65cSJohan Hedberg req->io_capability); 17832ed8f65cSJohan Hedberg if (method == JUST_WORKS || method == JUST_CFM) 17842ed8f65cSJohan Hedberg return SMP_AUTH_REQUIREMENTS; 17852ed8f65cSJohan Hedberg } 17862ed8f65cSJohan Hedberg 17873158c50cSVinicius Costa Gomes key_size = min(req->max_key_size, rsp.max_key_size); 17883158c50cSVinicius Costa Gomes if (check_enc_key_size(conn, key_size)) 17893158c50cSVinicius Costa Gomes return SMP_ENC_KEY_SIZE; 179088ba43b6SAnderson Briglia 1791e84a6b13SJohan Hedberg get_random_bytes(smp->prnd, sizeof(smp->prnd)); 17928aab4757SVinicius Costa Gomes 17931c1def09SVinicius Costa Gomes smp->prsp[0] = SMP_CMD_PAIRING_RSP; 17941c1def09SVinicius Costa Gomes memcpy(&smp->prsp[1], &rsp, sizeof(rsp)); 1795f01ead31SAnderson Briglia 17963158c50cSVinicius Costa Gomes smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp); 17973b19146dSJohan Hedberg 17983b19146dSJohan Hedberg clear_bit(SMP_FLAG_INITIATOR, &smp->flags); 17993b19146dSJohan Hedberg 18003b19146dSJohan Hedberg if (test_bit(SMP_FLAG_SC, &smp->flags)) { 18013b19146dSJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PUBLIC_KEY); 18023b19146dSJohan Hedberg /* Clear bits which are generated but not distributed */ 18033b19146dSJohan Hedberg smp->remote_key_dist &= ~SMP_SC_NO_DIST; 18043b19146dSJohan Hedberg /* Wait for Public Key from Initiating Device */ 18053b19146dSJohan Hedberg return 0; 18063b19146dSJohan Hedberg } 1807da85e5e5SVinicius Costa Gomes 1808983f9814SMarcel Holtmann SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); 1809983f9814SMarcel Holtmann 18102b64d153SBrian Gix /* Request setup of TK */ 18112b64d153SBrian Gix ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability); 18122b64d153SBrian Gix if (ret) 18132b64d153SBrian Gix return SMP_UNSPECIFIED; 18142b64d153SBrian Gix 1815da85e5e5SVinicius Costa Gomes return 0; 181688ba43b6SAnderson Briglia } 181788ba43b6SAnderson Briglia 18183b19146dSJohan Hedberg static u8 sc_send_public_key(struct smp_chan *smp) 18193b19146dSJohan Hedberg { 182070157ef5SJohan Hedberg struct hci_dev *hdev = smp->conn->hcon->hdev; 182170157ef5SJohan Hedberg 18223b19146dSJohan Hedberg BT_DBG(""); 18233b19146dSJohan Hedberg 18241a8bab4fSJohan Hedberg if (test_bit(SMP_FLAG_LOCAL_OOB, &smp->flags)) { 182533d0c030SMarcel Holtmann struct l2cap_chan *chan = hdev->smp_data; 182633d0c030SMarcel Holtmann struct smp_dev *smp_dev; 182733d0c030SMarcel Holtmann 182833d0c030SMarcel Holtmann if (!chan || !chan->data) 182933d0c030SMarcel Holtmann return SMP_UNSPECIFIED; 183033d0c030SMarcel Holtmann 183133d0c030SMarcel Holtmann smp_dev = chan->data; 183233d0c030SMarcel Holtmann 183333d0c030SMarcel Holtmann memcpy(smp->local_pk, smp_dev->local_pk, 64); 183433d0c030SMarcel Holtmann memcpy(smp->local_sk, smp_dev->local_sk, 32); 1835882fafadSJohan Hedberg memcpy(smp->lr, smp_dev->local_rr, 16); 183633d0c030SMarcel Holtmann 183733d0c030SMarcel Holtmann if (smp_dev->debug_key) 183833d0c030SMarcel Holtmann set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags); 183933d0c030SMarcel Holtmann 184033d0c030SMarcel Holtmann goto done; 184133d0c030SMarcel Holtmann } 184233d0c030SMarcel Holtmann 1843d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS)) { 184470157ef5SJohan Hedberg BT_DBG("Using debug keys"); 184570157ef5SJohan Hedberg memcpy(smp->local_pk, debug_pk, 64); 184670157ef5SJohan Hedberg memcpy(smp->local_sk, debug_sk, 32); 184770157ef5SJohan Hedberg set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags); 184870157ef5SJohan Hedberg } else { 18496c0dcc50SJohan Hedberg while (true) { 18503b19146dSJohan Hedberg /* Generate local key pair for Secure Connections */ 18513b19146dSJohan Hedberg if (!ecc_make_key(smp->local_pk, smp->local_sk)) 18523b19146dSJohan Hedberg return SMP_UNSPECIFIED; 18533b19146dSJohan Hedberg 185470157ef5SJohan Hedberg /* This is unlikely, but we need to check that 185570157ef5SJohan Hedberg * we didn't accidentially generate a debug key. 18566c0dcc50SJohan Hedberg */ 18576c0dcc50SJohan Hedberg if (memcmp(smp->local_sk, debug_sk, 32)) 18586c0dcc50SJohan Hedberg break; 18596c0dcc50SJohan Hedberg } 186070157ef5SJohan Hedberg } 18616c0dcc50SJohan Hedberg 186233d0c030SMarcel Holtmann done: 1863c7a3d57dSJohan Hedberg SMP_DBG("Local Public Key X: %32phN", smp->local_pk); 18648e4e2ee5SMarcel Holtmann SMP_DBG("Local Public Key Y: %32phN", smp->local_pk + 32); 1865c7a3d57dSJohan Hedberg SMP_DBG("Local Private Key: %32phN", smp->local_sk); 18663b19146dSJohan Hedberg 18673b19146dSJohan Hedberg smp_send_cmd(smp->conn, SMP_CMD_PUBLIC_KEY, 64, smp->local_pk); 18683b19146dSJohan Hedberg 18693b19146dSJohan Hedberg return 0; 18703b19146dSJohan Hedberg } 18713b19146dSJohan Hedberg 1872da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) 187388ba43b6SAnderson Briglia { 18743158c50cSVinicius Costa Gomes struct smp_cmd_pairing *req, *rsp = (void *) skb->data; 18755d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 18765d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 18770edb14deSJohan Hedberg struct hci_dev *hdev = conn->hcon->hdev; 18783a7dbfb8SJohan Hedberg u8 key_size, auth; 18797d24ddccSAnderson Briglia int ret; 188088ba43b6SAnderson Briglia 188188ba43b6SAnderson Briglia BT_DBG("conn %p", conn); 188288ba43b6SAnderson Briglia 1883c46b98beSJohan Hedberg if (skb->len < sizeof(*rsp)) 188438e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 1885c46b98beSJohan Hedberg 188640bef302SJohan Hedberg if (conn->hcon->role != HCI_ROLE_MASTER) 18872b64d153SBrian Gix return SMP_CMD_NOTSUPP; 18882b64d153SBrian Gix 18893158c50cSVinicius Costa Gomes skb_pull(skb, sizeof(*rsp)); 1890da85e5e5SVinicius Costa Gomes 18911c1def09SVinicius Costa Gomes req = (void *) &smp->preq[1]; 18923158c50cSVinicius Costa Gomes 18933158c50cSVinicius Costa Gomes key_size = min(req->max_key_size, rsp->max_key_size); 18943158c50cSVinicius Costa Gomes if (check_enc_key_size(conn, key_size)) 18953158c50cSVinicius Costa Gomes return SMP_ENC_KEY_SIZE; 18963158c50cSVinicius Costa Gomes 18970edb14deSJohan Hedberg auth = rsp->auth_req & AUTH_REQ_MASK(hdev); 1898c05b9339SJohan Hedberg 1899d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SC_ONLY) && !(auth & SMP_AUTH_SC)) 1900903b71c7SJohan Hedberg return SMP_AUTH_REQUIREMENTS; 1901903b71c7SJohan Hedberg 1902b5ae344dSJohan Hedberg smp->prsp[0] = SMP_CMD_PAIRING_RSP; 1903b5ae344dSJohan Hedberg memcpy(&smp->prsp[1], rsp, sizeof(*rsp)); 1904b5ae344dSJohan Hedberg 1905b5ae344dSJohan Hedberg /* Update remote key distribution in case the remote cleared 1906b5ae344dSJohan Hedberg * some bits that we had enabled in our request. 1907b5ae344dSJohan Hedberg */ 1908b5ae344dSJohan Hedberg smp->remote_key_dist &= rsp->resp_key_dist; 1909b5ae344dSJohan Hedberg 1910b5ae344dSJohan Hedberg /* For BR/EDR this means we're done and can start phase 3 */ 1911b5ae344dSJohan Hedberg if (conn->hcon->type == ACL_LINK) { 1912b5ae344dSJohan Hedberg /* Clear bits which are generated but not distributed */ 1913b5ae344dSJohan Hedberg smp->remote_key_dist &= ~SMP_SC_NO_DIST; 1914b5ae344dSJohan Hedberg smp_distribute_keys(smp); 1915b5ae344dSJohan Hedberg return 0; 1916b5ae344dSJohan Hedberg } 1917b5ae344dSJohan Hedberg 191865668776SJohan Hedberg if ((req->auth_req & SMP_AUTH_SC) && (auth & SMP_AUTH_SC)) 191965668776SJohan Hedberg set_bit(SMP_FLAG_SC, &smp->flags); 1920d2eb9e10SJohan Hedberg else if (conn->hcon->pending_sec_level > BT_SECURITY_HIGH) 1921d2eb9e10SJohan Hedberg conn->hcon->pending_sec_level = BT_SECURITY_HIGH; 192265668776SJohan Hedberg 192349c922bbSStephen Hemminger /* If we need MITM check that it can be achieved */ 19242ed8f65cSJohan Hedberg if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) { 19252ed8f65cSJohan Hedberg u8 method; 19262ed8f65cSJohan Hedberg 19272ed8f65cSJohan Hedberg method = get_auth_method(smp, req->io_capability, 19282ed8f65cSJohan Hedberg rsp->io_capability); 19292ed8f65cSJohan Hedberg if (method == JUST_WORKS || method == JUST_CFM) 19302ed8f65cSJohan Hedberg return SMP_AUTH_REQUIREMENTS; 19312ed8f65cSJohan Hedberg } 19322ed8f65cSJohan Hedberg 1933e84a6b13SJohan Hedberg get_random_bytes(smp->prnd, sizeof(smp->prnd)); 19347d24ddccSAnderson Briglia 1935fdcc4becSJohan Hedberg /* Update remote key distribution in case the remote cleared 1936fdcc4becSJohan Hedberg * some bits that we had enabled in our request. 1937fdcc4becSJohan Hedberg */ 1938fdcc4becSJohan Hedberg smp->remote_key_dist &= rsp->resp_key_dist; 1939fdcc4becSJohan Hedberg 19403b19146dSJohan Hedberg if (test_bit(SMP_FLAG_SC, &smp->flags)) { 19413b19146dSJohan Hedberg /* Clear bits which are generated but not distributed */ 19423b19146dSJohan Hedberg smp->remote_key_dist &= ~SMP_SC_NO_DIST; 19433b19146dSJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PUBLIC_KEY); 19443b19146dSJohan Hedberg return sc_send_public_key(smp); 19453b19146dSJohan Hedberg } 19463b19146dSJohan Hedberg 1947c05b9339SJohan Hedberg auth |= req->auth_req; 19482b64d153SBrian Gix 1949476585ecSJohan Hedberg ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability); 19502b64d153SBrian Gix if (ret) 19512b64d153SBrian Gix return SMP_UNSPECIFIED; 19522b64d153SBrian Gix 19534a74d658SJohan Hedberg set_bit(SMP_FLAG_CFM_PENDING, &smp->flags); 19542b64d153SBrian Gix 19552b64d153SBrian Gix /* Can't compose response until we have been confirmed */ 19564a74d658SJohan Hedberg if (test_bit(SMP_FLAG_TK_VALID, &smp->flags)) 19571cc61144SJohan Hedberg return smp_confirm(smp); 1958da85e5e5SVinicius Costa Gomes 1959da85e5e5SVinicius Costa Gomes return 0; 196088ba43b6SAnderson Briglia } 196188ba43b6SAnderson Briglia 1962dcee2b32SJohan Hedberg static u8 sc_check_confirm(struct smp_chan *smp) 1963dcee2b32SJohan Hedberg { 1964dcee2b32SJohan Hedberg struct l2cap_conn *conn = smp->conn; 1965dcee2b32SJohan Hedberg 1966dcee2b32SJohan Hedberg BT_DBG(""); 1967dcee2b32SJohan Hedberg 1968dcee2b32SJohan Hedberg /* Public Key exchange must happen before any other steps */ 1969dcee2b32SJohan Hedberg if (!test_bit(SMP_FLAG_REMOTE_PK, &smp->flags)) 1970dcee2b32SJohan Hedberg return SMP_UNSPECIFIED; 1971dcee2b32SJohan Hedberg 197238606f14SJohan Hedberg if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY) 197338606f14SJohan Hedberg return sc_passkey_round(smp, SMP_CMD_PAIRING_CONFIRM); 197438606f14SJohan Hedberg 1975dcee2b32SJohan Hedberg if (conn->hcon->out) { 1976dcee2b32SJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd), 1977dcee2b32SJohan Hedberg smp->prnd); 1978dcee2b32SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM); 1979dcee2b32SJohan Hedberg } 1980dcee2b32SJohan Hedberg 1981dcee2b32SJohan Hedberg return 0; 1982dcee2b32SJohan Hedberg } 1983dcee2b32SJohan Hedberg 1984da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb) 198588ba43b6SAnderson Briglia { 19865d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 19875d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 19887d24ddccSAnderson Briglia 198988ba43b6SAnderson Briglia BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave"); 199088ba43b6SAnderson Briglia 1991c46b98beSJohan Hedberg if (skb->len < sizeof(smp->pcnf)) 199238e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 1993c46b98beSJohan Hedberg 19941c1def09SVinicius Costa Gomes memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf)); 19951c1def09SVinicius Costa Gomes skb_pull(skb, sizeof(smp->pcnf)); 19967d24ddccSAnderson Briglia 1997dcee2b32SJohan Hedberg if (test_bit(SMP_FLAG_SC, &smp->flags)) 1998dcee2b32SJohan Hedberg return sc_check_confirm(smp); 1999dcee2b32SJohan Hedberg 2000b28b4943SJohan Hedberg if (conn->hcon->out) { 2001943a732aSJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd), 2002943a732aSJohan Hedberg smp->prnd); 2003b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM); 2004b28b4943SJohan Hedberg return 0; 2005b28b4943SJohan Hedberg } 2006b28b4943SJohan Hedberg 2007b28b4943SJohan Hedberg if (test_bit(SMP_FLAG_TK_VALID, &smp->flags)) 20081cc61144SJohan Hedberg return smp_confirm(smp); 2009983f9814SMarcel Holtmann 20104a74d658SJohan Hedberg set_bit(SMP_FLAG_CFM_PENDING, &smp->flags); 2011da85e5e5SVinicius Costa Gomes 2012da85e5e5SVinicius Costa Gomes return 0; 201388ba43b6SAnderson Briglia } 201488ba43b6SAnderson Briglia 2015da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) 201688ba43b6SAnderson Briglia { 20175d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 20185d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 2019191dc7feSJohan Hedberg struct hci_conn *hcon = conn->hcon; 2020191dc7feSJohan Hedberg u8 *pkax, *pkbx, *na, *nb; 2021191dc7feSJohan Hedberg u32 passkey; 2022191dc7feSJohan Hedberg int err; 20237d24ddccSAnderson Briglia 20248aab4757SVinicius Costa Gomes BT_DBG("conn %p", conn); 20257d24ddccSAnderson Briglia 2026c46b98beSJohan Hedberg if (skb->len < sizeof(smp->rrnd)) 202738e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 2028c46b98beSJohan Hedberg 2029943a732aSJohan Hedberg memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd)); 20308aab4757SVinicius Costa Gomes skb_pull(skb, sizeof(smp->rrnd)); 203188ba43b6SAnderson Briglia 2032191dc7feSJohan Hedberg if (!test_bit(SMP_FLAG_SC, &smp->flags)) 2033861580a9SJohan Hedberg return smp_random(smp); 2034191dc7feSJohan Hedberg 2035580039e8SJohan Hedberg if (hcon->out) { 2036580039e8SJohan Hedberg pkax = smp->local_pk; 2037580039e8SJohan Hedberg pkbx = smp->remote_pk; 2038580039e8SJohan Hedberg na = smp->prnd; 2039580039e8SJohan Hedberg nb = smp->rrnd; 2040580039e8SJohan Hedberg } else { 2041580039e8SJohan Hedberg pkax = smp->remote_pk; 2042580039e8SJohan Hedberg pkbx = smp->local_pk; 2043580039e8SJohan Hedberg na = smp->rrnd; 2044580039e8SJohan Hedberg nb = smp->prnd; 2045580039e8SJohan Hedberg } 2046580039e8SJohan Hedberg 2047a29b0733SJohan Hedberg if (smp->method == REQ_OOB) { 2048a29b0733SJohan Hedberg if (!hcon->out) 2049a29b0733SJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, 2050a29b0733SJohan Hedberg sizeof(smp->prnd), smp->prnd); 2051a29b0733SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK); 2052a29b0733SJohan Hedberg goto mackey_and_ltk; 2053a29b0733SJohan Hedberg } 2054a29b0733SJohan Hedberg 205538606f14SJohan Hedberg /* Passkey entry has special treatment */ 205638606f14SJohan Hedberg if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY) 205738606f14SJohan Hedberg return sc_passkey_round(smp, SMP_CMD_PAIRING_RANDOM); 205838606f14SJohan Hedberg 2059191dc7feSJohan Hedberg if (hcon->out) { 2060191dc7feSJohan Hedberg u8 cfm[16]; 2061191dc7feSJohan Hedberg 2062191dc7feSJohan Hedberg err = smp_f4(smp->tfm_cmac, smp->remote_pk, smp->local_pk, 2063191dc7feSJohan Hedberg smp->rrnd, 0, cfm); 2064191dc7feSJohan Hedberg if (err) 2065191dc7feSJohan Hedberg return SMP_UNSPECIFIED; 2066191dc7feSJohan Hedberg 2067191dc7feSJohan Hedberg if (memcmp(smp->pcnf, cfm, 16)) 2068191dc7feSJohan Hedberg return SMP_CONFIRM_FAILED; 2069191dc7feSJohan Hedberg } else { 2070191dc7feSJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd), 2071191dc7feSJohan Hedberg smp->prnd); 2072191dc7feSJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK); 2073191dc7feSJohan Hedberg } 2074191dc7feSJohan Hedberg 2075a29b0733SJohan Hedberg mackey_and_ltk: 2076760b018bSJohan Hedberg /* Generate MacKey and LTK */ 2077760b018bSJohan Hedberg err = sc_mackey_and_ltk(smp, smp->mackey, smp->tk); 2078760b018bSJohan Hedberg if (err) 2079760b018bSJohan Hedberg return SMP_UNSPECIFIED; 2080760b018bSJohan Hedberg 2081a29b0733SJohan Hedberg if (smp->method == JUST_WORKS || smp->method == REQ_OOB) { 2082dddd3059SJohan Hedberg if (hcon->out) { 208338606f14SJohan Hedberg sc_dhkey_check(smp); 2084dddd3059SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK); 2085dddd3059SJohan Hedberg } 2086dddd3059SJohan Hedberg return 0; 2087dddd3059SJohan Hedberg } 2088dddd3059SJohan Hedberg 208938606f14SJohan Hedberg err = smp_g2(smp->tfm_cmac, pkax, pkbx, na, nb, &passkey); 2090191dc7feSJohan Hedberg if (err) 2091191dc7feSJohan Hedberg return SMP_UNSPECIFIED; 2092191dc7feSJohan Hedberg 209338606f14SJohan Hedberg err = mgmt_user_confirm_request(hcon->hdev, &hcon->dst, hcon->type, 209438606f14SJohan Hedberg hcon->dst_type, passkey, 0); 209538606f14SJohan Hedberg if (err) 209638606f14SJohan Hedberg return SMP_UNSPECIFIED; 209738606f14SJohan Hedberg 209838606f14SJohan Hedberg set_bit(SMP_FLAG_WAIT_USER, &smp->flags); 209938606f14SJohan Hedberg 2100191dc7feSJohan Hedberg return 0; 210188ba43b6SAnderson Briglia } 210288ba43b6SAnderson Briglia 2103f81cd823SMarcel Holtmann static bool smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level) 2104988c5997SVinicius Costa Gomes { 2105c9839a11SVinicius Costa Gomes struct smp_ltk *key; 2106988c5997SVinicius Costa Gomes struct hci_conn *hcon = conn->hcon; 2107988c5997SVinicius Costa Gomes 2108f3a73d97SJohan Hedberg key = hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, hcon->role); 2109988c5997SVinicius Costa Gomes if (!key) 2110f81cd823SMarcel Holtmann return false; 2111988c5997SVinicius Costa Gomes 2112a6f7833cSJohan Hedberg if (smp_ltk_sec_level(key) < sec_level) 2113f81cd823SMarcel Holtmann return false; 21144dab7864SJohan Hedberg 211551a8efd7SJohan Hedberg if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags)) 2116f81cd823SMarcel Holtmann return true; 2117988c5997SVinicius Costa Gomes 2118c9839a11SVinicius Costa Gomes hci_le_start_enc(hcon, key->ediv, key->rand, key->val); 2119c9839a11SVinicius Costa Gomes hcon->enc_key_size = key->enc_size; 2120988c5997SVinicius Costa Gomes 2121fe59a05fSJohan Hedberg /* We never store STKs for master role, so clear this flag */ 2122fe59a05fSJohan Hedberg clear_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags); 2123fe59a05fSJohan Hedberg 2124f81cd823SMarcel Holtmann return true; 2125988c5997SVinicius Costa Gomes } 2126f1560463SMarcel Holtmann 212735dc6f83SJohan Hedberg bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level, 212835dc6f83SJohan Hedberg enum smp_key_pref key_pref) 2129854f4727SJohan Hedberg { 2130854f4727SJohan Hedberg if (sec_level == BT_SECURITY_LOW) 2131854f4727SJohan Hedberg return true; 2132854f4727SJohan Hedberg 213335dc6f83SJohan Hedberg /* If we're encrypted with an STK but the caller prefers using 213435dc6f83SJohan Hedberg * LTK claim insufficient security. This way we allow the 213535dc6f83SJohan Hedberg * connection to be re-encrypted with an LTK, even if the LTK 213635dc6f83SJohan Hedberg * provides the same level of security. Only exception is if we 213735dc6f83SJohan Hedberg * don't have an LTK (e.g. because of key distribution bits). 21389ab65d60SJohan Hedberg */ 213935dc6f83SJohan Hedberg if (key_pref == SMP_USE_LTK && 214035dc6f83SJohan Hedberg test_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags) && 2141f3a73d97SJohan Hedberg hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, hcon->role)) 21429ab65d60SJohan Hedberg return false; 21439ab65d60SJohan Hedberg 2144854f4727SJohan Hedberg if (hcon->sec_level >= sec_level) 2145854f4727SJohan Hedberg return true; 2146854f4727SJohan Hedberg 2147854f4727SJohan Hedberg return false; 2148854f4727SJohan Hedberg } 2149854f4727SJohan Hedberg 2150da85e5e5SVinicius Costa Gomes static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) 215188ba43b6SAnderson Briglia { 215288ba43b6SAnderson Briglia struct smp_cmd_security_req *rp = (void *) skb->data; 215388ba43b6SAnderson Briglia struct smp_cmd_pairing cp; 2154f1cb9af5SVinicius Costa Gomes struct hci_conn *hcon = conn->hcon; 21550edb14deSJohan Hedberg struct hci_dev *hdev = hcon->hdev; 21568aab4757SVinicius Costa Gomes struct smp_chan *smp; 2157c05b9339SJohan Hedberg u8 sec_level, auth; 215888ba43b6SAnderson Briglia 215988ba43b6SAnderson Briglia BT_DBG("conn %p", conn); 216088ba43b6SAnderson Briglia 2161c46b98beSJohan Hedberg if (skb->len < sizeof(*rp)) 216238e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 2163c46b98beSJohan Hedberg 216440bef302SJohan Hedberg if (hcon->role != HCI_ROLE_MASTER) 216586ca9eacSJohan Hedberg return SMP_CMD_NOTSUPP; 216686ca9eacSJohan Hedberg 21670edb14deSJohan Hedberg auth = rp->auth_req & AUTH_REQ_MASK(hdev); 2168c05b9339SJohan Hedberg 2169d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SC_ONLY) && !(auth & SMP_AUTH_SC)) 2170903b71c7SJohan Hedberg return SMP_AUTH_REQUIREMENTS; 2171903b71c7SJohan Hedberg 21725be5e275SJohan Hedberg if (hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT) 21731afc2a1aSJohan Hedberg sec_level = BT_SECURITY_MEDIUM; 21741afc2a1aSJohan Hedberg else 2175c05b9339SJohan Hedberg sec_level = authreq_to_seclevel(auth); 21761afc2a1aSJohan Hedberg 217735dc6f83SJohan Hedberg if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK)) 2178854f4727SJohan Hedberg return 0; 2179854f4727SJohan Hedberg 2180c7262e71SJohan Hedberg if (sec_level > hcon->pending_sec_level) 2181c7262e71SJohan Hedberg hcon->pending_sec_level = sec_level; 2182feb45eb5SVinicius Costa Gomes 21834dab7864SJohan Hedberg if (smp_ltk_encrypt(conn, hcon->pending_sec_level)) 2184988c5997SVinicius Costa Gomes return 0; 2185988c5997SVinicius Costa Gomes 21868aab4757SVinicius Costa Gomes smp = smp_chan_create(conn); 2187c29d2444SJohan Hedberg if (!smp) 2188c29d2444SJohan Hedberg return SMP_UNSPECIFIED; 2189d26a2345SVinicius Costa Gomes 2190d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_BONDABLE) && 2191c05b9339SJohan Hedberg (auth & SMP_AUTH_BONDING)) 2192616d55beSJohan Hedberg return SMP_PAIRING_NOTSUPP; 2193616d55beSJohan Hedberg 219488ba43b6SAnderson Briglia skb_pull(skb, sizeof(*rp)); 219588ba43b6SAnderson Briglia 2196da85e5e5SVinicius Costa Gomes memset(&cp, 0, sizeof(cp)); 2197c05b9339SJohan Hedberg build_pairing_cmd(conn, &cp, NULL, auth); 219888ba43b6SAnderson Briglia 21991c1def09SVinicius Costa Gomes smp->preq[0] = SMP_CMD_PAIRING_REQ; 22001c1def09SVinicius Costa Gomes memcpy(&smp->preq[1], &cp, sizeof(cp)); 2201f01ead31SAnderson Briglia 220288ba43b6SAnderson Briglia smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp); 2203b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP); 2204f1cb9af5SVinicius Costa Gomes 2205da85e5e5SVinicius Costa Gomes return 0; 220688ba43b6SAnderson Briglia } 220788ba43b6SAnderson Briglia 2208cc110922SVinicius Costa Gomes int smp_conn_security(struct hci_conn *hcon, __u8 sec_level) 2209eb492e01SAnderson Briglia { 2210cc110922SVinicius Costa Gomes struct l2cap_conn *conn = hcon->l2cap_data; 2211c68b7f12SJohan Hedberg struct l2cap_chan *chan; 22120a66cf20SJohan Hedberg struct smp_chan *smp; 22132b64d153SBrian Gix __u8 authreq; 2214fc75cc86SJohan Hedberg int ret; 2215eb492e01SAnderson Briglia 22163a0259bbSVinicius Costa Gomes BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level); 22173a0259bbSVinicius Costa Gomes 22180a66cf20SJohan Hedberg /* This may be NULL if there's an unexpected disconnection */ 22190a66cf20SJohan Hedberg if (!conn) 22200a66cf20SJohan Hedberg return 1; 22210a66cf20SJohan Hedberg 2222c68b7f12SJohan Hedberg chan = conn->smp; 2223c68b7f12SJohan Hedberg 2224d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hcon->hdev, HCI_LE_ENABLED)) 22252e65c9d2SAndre Guedes return 1; 22262e65c9d2SAndre Guedes 222735dc6f83SJohan Hedberg if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK)) 2228f1cb9af5SVinicius Costa Gomes return 1; 2229f1cb9af5SVinicius Costa Gomes 2230c7262e71SJohan Hedberg if (sec_level > hcon->pending_sec_level) 2231c7262e71SJohan Hedberg hcon->pending_sec_level = sec_level; 2232c7262e71SJohan Hedberg 223340bef302SJohan Hedberg if (hcon->role == HCI_ROLE_MASTER) 2234c7262e71SJohan Hedberg if (smp_ltk_encrypt(conn, hcon->pending_sec_level)) 2235c7262e71SJohan Hedberg return 0; 2236d26a2345SVinicius Costa Gomes 2237fc75cc86SJohan Hedberg l2cap_chan_lock(chan); 2238fc75cc86SJohan Hedberg 2239fc75cc86SJohan Hedberg /* If SMP is already in progress ignore this request */ 2240fc75cc86SJohan Hedberg if (chan->data) { 2241fc75cc86SJohan Hedberg ret = 0; 2242fc75cc86SJohan Hedberg goto unlock; 2243fc75cc86SJohan Hedberg } 2244d26a2345SVinicius Costa Gomes 22458aab4757SVinicius Costa Gomes smp = smp_chan_create(conn); 2246fc75cc86SJohan Hedberg if (!smp) { 2247fc75cc86SJohan Hedberg ret = 1; 2248fc75cc86SJohan Hedberg goto unlock; 2249fc75cc86SJohan Hedberg } 22502b64d153SBrian Gix 22512b64d153SBrian Gix authreq = seclevel_to_authreq(sec_level); 2252d26a2345SVinicius Costa Gomes 2253d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hcon->hdev, HCI_SC_ENABLED)) 2254d2eb9e10SJohan Hedberg authreq |= SMP_AUTH_SC; 2255d2eb9e10SJohan Hedberg 225679897d20SJohan Hedberg /* Require MITM if IO Capability allows or the security level 225779897d20SJohan Hedberg * requires it. 22582e233644SJohan Hedberg */ 225979897d20SJohan Hedberg if (hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT || 2260c7262e71SJohan Hedberg hcon->pending_sec_level > BT_SECURITY_MEDIUM) 22612e233644SJohan Hedberg authreq |= SMP_AUTH_MITM; 22622e233644SJohan Hedberg 226340bef302SJohan Hedberg if (hcon->role == HCI_ROLE_MASTER) { 2264d26a2345SVinicius Costa Gomes struct smp_cmd_pairing cp; 2265f01ead31SAnderson Briglia 22662b64d153SBrian Gix build_pairing_cmd(conn, &cp, NULL, authreq); 22671c1def09SVinicius Costa Gomes smp->preq[0] = SMP_CMD_PAIRING_REQ; 22681c1def09SVinicius Costa Gomes memcpy(&smp->preq[1], &cp, sizeof(cp)); 2269f01ead31SAnderson Briglia 2270eb492e01SAnderson Briglia smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp); 2271b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP); 2272eb492e01SAnderson Briglia } else { 2273eb492e01SAnderson Briglia struct smp_cmd_security_req cp; 22742b64d153SBrian Gix cp.auth_req = authreq; 2275eb492e01SAnderson Briglia smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp); 2276b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_REQ); 2277eb492e01SAnderson Briglia } 2278eb492e01SAnderson Briglia 22794a74d658SJohan Hedberg set_bit(SMP_FLAG_INITIATOR, &smp->flags); 2280fc75cc86SJohan Hedberg ret = 0; 2281edca792cSJohan Hedberg 2282fc75cc86SJohan Hedberg unlock: 2283fc75cc86SJohan Hedberg l2cap_chan_unlock(chan); 2284fc75cc86SJohan Hedberg return ret; 2285eb492e01SAnderson Briglia } 2286eb492e01SAnderson Briglia 22877034b911SVinicius Costa Gomes static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb) 22887034b911SVinicius Costa Gomes { 228916b90839SVinicius Costa Gomes struct smp_cmd_encrypt_info *rp = (void *) skb->data; 22905d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 22915d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 229216b90839SVinicius Costa Gomes 2293c46b98beSJohan Hedberg BT_DBG("conn %p", conn); 2294c46b98beSJohan Hedberg 2295c46b98beSJohan Hedberg if (skb->len < sizeof(*rp)) 229638e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 2297c46b98beSJohan Hedberg 2298b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_MASTER_IDENT); 22996131ddc8SJohan Hedberg 230016b90839SVinicius Costa Gomes skb_pull(skb, sizeof(*rp)); 230116b90839SVinicius Costa Gomes 23021c1def09SVinicius Costa Gomes memcpy(smp->tk, rp->ltk, sizeof(smp->tk)); 230316b90839SVinicius Costa Gomes 23047034b911SVinicius Costa Gomes return 0; 23057034b911SVinicius Costa Gomes } 23067034b911SVinicius Costa Gomes 23077034b911SVinicius Costa Gomes static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb) 23087034b911SVinicius Costa Gomes { 230916b90839SVinicius Costa Gomes struct smp_cmd_master_ident *rp = (void *) skb->data; 23105d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 23115d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 2312c9839a11SVinicius Costa Gomes struct hci_dev *hdev = conn->hcon->hdev; 2313c9839a11SVinicius Costa Gomes struct hci_conn *hcon = conn->hcon; 231423d0e128SJohan Hedberg struct smp_ltk *ltk; 2315c9839a11SVinicius Costa Gomes u8 authenticated; 23167034b911SVinicius Costa Gomes 2317c46b98beSJohan Hedberg BT_DBG("conn %p", conn); 2318c46b98beSJohan Hedberg 2319c46b98beSJohan Hedberg if (skb->len < sizeof(*rp)) 232038e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 2321c46b98beSJohan Hedberg 23229747a9f3SJohan Hedberg /* Mark the information as received */ 23239747a9f3SJohan Hedberg smp->remote_key_dist &= ~SMP_DIST_ENC_KEY; 23249747a9f3SJohan Hedberg 2325b28b4943SJohan Hedberg if (smp->remote_key_dist & SMP_DIST_ID_KEY) 2326b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO); 2327196332f5SJohan Hedberg else if (smp->remote_key_dist & SMP_DIST_SIGN) 2328196332f5SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO); 2329b28b4943SJohan Hedberg 233016b90839SVinicius Costa Gomes skb_pull(skb, sizeof(*rp)); 233116b90839SVinicius Costa Gomes 2332ce39fb4eSMarcel Holtmann authenticated = (hcon->sec_level == BT_SECURITY_HIGH); 23332ceba539SJohan Hedberg ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, SMP_LTK, 2334ce39fb4eSMarcel Holtmann authenticated, smp->tk, smp->enc_key_size, 233504124681SGustavo F. Padovan rp->ediv, rp->rand); 233623d0e128SJohan Hedberg smp->ltk = ltk; 2337c6e81e9aSJohan Hedberg if (!(smp->remote_key_dist & KEY_DIST_MASK)) 2338d6268e86SJohan Hedberg smp_distribute_keys(smp); 23397034b911SVinicius Costa Gomes 23407034b911SVinicius Costa Gomes return 0; 23417034b911SVinicius Costa Gomes } 23427034b911SVinicius Costa Gomes 2343fd349c02SJohan Hedberg static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb) 2344fd349c02SJohan Hedberg { 2345fd349c02SJohan Hedberg struct smp_cmd_ident_info *info = (void *) skb->data; 23465d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 23475d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 2348fd349c02SJohan Hedberg 2349fd349c02SJohan Hedberg BT_DBG(""); 2350fd349c02SJohan Hedberg 2351fd349c02SJohan Hedberg if (skb->len < sizeof(*info)) 235238e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 2353fd349c02SJohan Hedberg 2354b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_ADDR_INFO); 23556131ddc8SJohan Hedberg 2356fd349c02SJohan Hedberg skb_pull(skb, sizeof(*info)); 2357fd349c02SJohan Hedberg 2358fd349c02SJohan Hedberg memcpy(smp->irk, info->irk, 16); 2359fd349c02SJohan Hedberg 2360fd349c02SJohan Hedberg return 0; 2361fd349c02SJohan Hedberg } 2362fd349c02SJohan Hedberg 2363fd349c02SJohan Hedberg static int smp_cmd_ident_addr_info(struct l2cap_conn *conn, 2364fd349c02SJohan Hedberg struct sk_buff *skb) 2365fd349c02SJohan Hedberg { 2366fd349c02SJohan Hedberg struct smp_cmd_ident_addr_info *info = (void *) skb->data; 23675d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 23685d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 2369fd349c02SJohan Hedberg struct hci_conn *hcon = conn->hcon; 2370fd349c02SJohan Hedberg bdaddr_t rpa; 2371fd349c02SJohan Hedberg 2372fd349c02SJohan Hedberg BT_DBG(""); 2373fd349c02SJohan Hedberg 2374fd349c02SJohan Hedberg if (skb->len < sizeof(*info)) 237538e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 2376fd349c02SJohan Hedberg 23779747a9f3SJohan Hedberg /* Mark the information as received */ 23789747a9f3SJohan Hedberg smp->remote_key_dist &= ~SMP_DIST_ID_KEY; 23799747a9f3SJohan Hedberg 2380b28b4943SJohan Hedberg if (smp->remote_key_dist & SMP_DIST_SIGN) 2381b28b4943SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO); 2382b28b4943SJohan Hedberg 2383fd349c02SJohan Hedberg skb_pull(skb, sizeof(*info)); 2384fd349c02SJohan Hedberg 2385a9a58f86SJohan Hedberg /* Strictly speaking the Core Specification (4.1) allows sending 2386a9a58f86SJohan Hedberg * an empty address which would force us to rely on just the IRK 2387a9a58f86SJohan Hedberg * as "identity information". However, since such 2388a9a58f86SJohan Hedberg * implementations are not known of and in order to not over 2389a9a58f86SJohan Hedberg * complicate our implementation, simply pretend that we never 2390a9a58f86SJohan Hedberg * received an IRK for such a device. 2391e12af489SJohan Hedberg * 2392e12af489SJohan Hedberg * The Identity Address must also be a Static Random or Public 2393e12af489SJohan Hedberg * Address, which hci_is_identity_address() checks for. 2394a9a58f86SJohan Hedberg */ 2395e12af489SJohan Hedberg if (!bacmp(&info->bdaddr, BDADDR_ANY) || 2396e12af489SJohan Hedberg !hci_is_identity_address(&info->bdaddr, info->addr_type)) { 2397a9a58f86SJohan Hedberg BT_ERR("Ignoring IRK with no identity address"); 239831dd624eSJohan Hedberg goto distribute; 2399a9a58f86SJohan Hedberg } 2400a9a58f86SJohan Hedberg 2401fd349c02SJohan Hedberg bacpy(&smp->id_addr, &info->bdaddr); 2402fd349c02SJohan Hedberg smp->id_addr_type = info->addr_type; 2403fd349c02SJohan Hedberg 2404fd349c02SJohan Hedberg if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type)) 2405fd349c02SJohan Hedberg bacpy(&rpa, &hcon->dst); 2406fd349c02SJohan Hedberg else 2407fd349c02SJohan Hedberg bacpy(&rpa, BDADDR_ANY); 2408fd349c02SJohan Hedberg 240923d0e128SJohan Hedberg smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr, 241023d0e128SJohan Hedberg smp->id_addr_type, smp->irk, &rpa); 2411fd349c02SJohan Hedberg 241231dd624eSJohan Hedberg distribute: 2413c6e81e9aSJohan Hedberg if (!(smp->remote_key_dist & KEY_DIST_MASK)) 2414d6268e86SJohan Hedberg smp_distribute_keys(smp); 2415fd349c02SJohan Hedberg 2416fd349c02SJohan Hedberg return 0; 2417fd349c02SJohan Hedberg } 2418fd349c02SJohan Hedberg 24197ee4ea36SMarcel Holtmann static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb) 24207ee4ea36SMarcel Holtmann { 24217ee4ea36SMarcel Holtmann struct smp_cmd_sign_info *rp = (void *) skb->data; 24225d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 24235d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 24247ee4ea36SMarcel Holtmann struct smp_csrk *csrk; 24257ee4ea36SMarcel Holtmann 24267ee4ea36SMarcel Holtmann BT_DBG("conn %p", conn); 24277ee4ea36SMarcel Holtmann 24287ee4ea36SMarcel Holtmann if (skb->len < sizeof(*rp)) 242938e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 24307ee4ea36SMarcel Holtmann 24317ee4ea36SMarcel Holtmann /* Mark the information as received */ 24327ee4ea36SMarcel Holtmann smp->remote_key_dist &= ~SMP_DIST_SIGN; 24337ee4ea36SMarcel Holtmann 24347ee4ea36SMarcel Holtmann skb_pull(skb, sizeof(*rp)); 24357ee4ea36SMarcel Holtmann 24367ee4ea36SMarcel Holtmann csrk = kzalloc(sizeof(*csrk), GFP_KERNEL); 24377ee4ea36SMarcel Holtmann if (csrk) { 24384cd3928aSJohan Hedberg if (conn->hcon->sec_level > BT_SECURITY_MEDIUM) 24394cd3928aSJohan Hedberg csrk->type = MGMT_CSRK_REMOTE_AUTHENTICATED; 24404cd3928aSJohan Hedberg else 24414cd3928aSJohan Hedberg csrk->type = MGMT_CSRK_REMOTE_UNAUTHENTICATED; 24427ee4ea36SMarcel Holtmann memcpy(csrk->val, rp->csrk, sizeof(csrk->val)); 24437ee4ea36SMarcel Holtmann } 24447ee4ea36SMarcel Holtmann smp->csrk = csrk; 2445d6268e86SJohan Hedberg smp_distribute_keys(smp); 24467ee4ea36SMarcel Holtmann 24477ee4ea36SMarcel Holtmann return 0; 24487ee4ea36SMarcel Holtmann } 24497ee4ea36SMarcel Holtmann 24505e3d3d9bSJohan Hedberg static u8 sc_select_method(struct smp_chan *smp) 24515e3d3d9bSJohan Hedberg { 24525e3d3d9bSJohan Hedberg struct l2cap_conn *conn = smp->conn; 24535e3d3d9bSJohan Hedberg struct hci_conn *hcon = conn->hcon; 24545e3d3d9bSJohan Hedberg struct smp_cmd_pairing *local, *remote; 24555e3d3d9bSJohan Hedberg u8 local_mitm, remote_mitm, local_io, remote_io, method; 24565e3d3d9bSJohan Hedberg 24571a8bab4fSJohan Hedberg if (test_bit(SMP_FLAG_REMOTE_OOB, &smp->flags) || 24581a8bab4fSJohan Hedberg test_bit(SMP_FLAG_LOCAL_OOB, &smp->flags)) 2459a29b0733SJohan Hedberg return REQ_OOB; 2460a29b0733SJohan Hedberg 24615e3d3d9bSJohan Hedberg /* The preq/prsp contain the raw Pairing Request/Response PDUs 24625e3d3d9bSJohan Hedberg * which are needed as inputs to some crypto functions. To get 24635e3d3d9bSJohan Hedberg * the "struct smp_cmd_pairing" from them we need to skip the 24645e3d3d9bSJohan Hedberg * first byte which contains the opcode. 24655e3d3d9bSJohan Hedberg */ 24665e3d3d9bSJohan Hedberg if (hcon->out) { 24675e3d3d9bSJohan Hedberg local = (void *) &smp->preq[1]; 24685e3d3d9bSJohan Hedberg remote = (void *) &smp->prsp[1]; 24695e3d3d9bSJohan Hedberg } else { 24705e3d3d9bSJohan Hedberg local = (void *) &smp->prsp[1]; 24715e3d3d9bSJohan Hedberg remote = (void *) &smp->preq[1]; 24725e3d3d9bSJohan Hedberg } 24735e3d3d9bSJohan Hedberg 24745e3d3d9bSJohan Hedberg local_io = local->io_capability; 24755e3d3d9bSJohan Hedberg remote_io = remote->io_capability; 24765e3d3d9bSJohan Hedberg 24775e3d3d9bSJohan Hedberg local_mitm = (local->auth_req & SMP_AUTH_MITM); 24785e3d3d9bSJohan Hedberg remote_mitm = (remote->auth_req & SMP_AUTH_MITM); 24795e3d3d9bSJohan Hedberg 24805e3d3d9bSJohan Hedberg /* If either side wants MITM, look up the method from the table, 24815e3d3d9bSJohan Hedberg * otherwise use JUST WORKS. 24825e3d3d9bSJohan Hedberg */ 24835e3d3d9bSJohan Hedberg if (local_mitm || remote_mitm) 24845e3d3d9bSJohan Hedberg method = get_auth_method(smp, local_io, remote_io); 24855e3d3d9bSJohan Hedberg else 24865e3d3d9bSJohan Hedberg method = JUST_WORKS; 24875e3d3d9bSJohan Hedberg 24885e3d3d9bSJohan Hedberg /* Don't confirm locally initiated pairing attempts */ 24895e3d3d9bSJohan Hedberg if (method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR, &smp->flags)) 24905e3d3d9bSJohan Hedberg method = JUST_WORKS; 24915e3d3d9bSJohan Hedberg 24925e3d3d9bSJohan Hedberg return method; 24935e3d3d9bSJohan Hedberg } 24945e3d3d9bSJohan Hedberg 2495d8f8edbeSJohan Hedberg static int smp_cmd_public_key(struct l2cap_conn *conn, struct sk_buff *skb) 2496d8f8edbeSJohan Hedberg { 2497d8f8edbeSJohan Hedberg struct smp_cmd_public_key *key = (void *) skb->data; 2498d8f8edbeSJohan Hedberg struct hci_conn *hcon = conn->hcon; 2499d8f8edbeSJohan Hedberg struct l2cap_chan *chan = conn->smp; 2500d8f8edbeSJohan Hedberg struct smp_chan *smp = chan->data; 25015e3d3d9bSJohan Hedberg struct hci_dev *hdev = hcon->hdev; 2502cbbbe3e2SJohan Hedberg struct smp_cmd_pairing_confirm cfm; 2503d8f8edbeSJohan Hedberg int err; 2504d8f8edbeSJohan Hedberg 2505d8f8edbeSJohan Hedberg BT_DBG("conn %p", conn); 2506d8f8edbeSJohan Hedberg 2507d8f8edbeSJohan Hedberg if (skb->len < sizeof(*key)) 2508d8f8edbeSJohan Hedberg return SMP_INVALID_PARAMS; 2509d8f8edbeSJohan Hedberg 2510d8f8edbeSJohan Hedberg memcpy(smp->remote_pk, key, 64); 2511d8f8edbeSJohan Hedberg 2512d8f8edbeSJohan Hedberg /* Non-initiating device sends its public key after receiving 2513d8f8edbeSJohan Hedberg * the key from the initiating device. 2514d8f8edbeSJohan Hedberg */ 2515d8f8edbeSJohan Hedberg if (!hcon->out) { 2516d8f8edbeSJohan Hedberg err = sc_send_public_key(smp); 2517d8f8edbeSJohan Hedberg if (err) 2518d8f8edbeSJohan Hedberg return err; 2519d8f8edbeSJohan Hedberg } 2520d8f8edbeSJohan Hedberg 2521c7a3d57dSJohan Hedberg SMP_DBG("Remote Public Key X: %32phN", smp->remote_pk); 2522c7a3d57dSJohan Hedberg SMP_DBG("Remote Public Key Y: %32phN", &smp->remote_pk[32]); 2523d8f8edbeSJohan Hedberg 2524d8f8edbeSJohan Hedberg if (!ecdh_shared_secret(smp->remote_pk, smp->local_sk, smp->dhkey)) 2525d8f8edbeSJohan Hedberg return SMP_UNSPECIFIED; 2526d8f8edbeSJohan Hedberg 2527c7a3d57dSJohan Hedberg SMP_DBG("DHKey %32phN", smp->dhkey); 2528d8f8edbeSJohan Hedberg 2529d8f8edbeSJohan Hedberg set_bit(SMP_FLAG_REMOTE_PK, &smp->flags); 2530d8f8edbeSJohan Hedberg 25315e3d3d9bSJohan Hedberg smp->method = sc_select_method(smp); 25325e3d3d9bSJohan Hedberg 25335e3d3d9bSJohan Hedberg BT_DBG("%s selected method 0x%02x", hdev->name, smp->method); 25345e3d3d9bSJohan Hedberg 25355e3d3d9bSJohan Hedberg /* JUST_WORKS and JUST_CFM result in an unauthenticated key */ 25365e3d3d9bSJohan Hedberg if (smp->method == JUST_WORKS || smp->method == JUST_CFM) 25375e3d3d9bSJohan Hedberg hcon->pending_sec_level = BT_SECURITY_MEDIUM; 25385e3d3d9bSJohan Hedberg else 25395e3d3d9bSJohan Hedberg hcon->pending_sec_level = BT_SECURITY_FIPS; 25405e3d3d9bSJohan Hedberg 2541aeb7d461SJohan Hedberg if (!memcmp(debug_pk, smp->remote_pk, 64)) 2542aeb7d461SJohan Hedberg set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags); 2543aeb7d461SJohan Hedberg 254438606f14SJohan Hedberg if (smp->method == DSP_PASSKEY) { 254538606f14SJohan Hedberg get_random_bytes(&hcon->passkey_notify, 254638606f14SJohan Hedberg sizeof(hcon->passkey_notify)); 254738606f14SJohan Hedberg hcon->passkey_notify %= 1000000; 254838606f14SJohan Hedberg hcon->passkey_entered = 0; 254938606f14SJohan Hedberg smp->passkey_round = 0; 255038606f14SJohan Hedberg if (mgmt_user_passkey_notify(hdev, &hcon->dst, hcon->type, 255138606f14SJohan Hedberg hcon->dst_type, 255238606f14SJohan Hedberg hcon->passkey_notify, 255338606f14SJohan Hedberg hcon->passkey_entered)) 255438606f14SJohan Hedberg return SMP_UNSPECIFIED; 255538606f14SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); 255638606f14SJohan Hedberg return sc_passkey_round(smp, SMP_CMD_PUBLIC_KEY); 255738606f14SJohan Hedberg } 255838606f14SJohan Hedberg 2559a29b0733SJohan Hedberg if (smp->method == REQ_OOB) { 2560a29b0733SJohan Hedberg err = smp_f4(smp->tfm_cmac, smp->remote_pk, smp->remote_pk, 2561a29b0733SJohan Hedberg smp->rr, 0, cfm.confirm_val); 2562a29b0733SJohan Hedberg if (err) 2563a29b0733SJohan Hedberg return SMP_UNSPECIFIED; 2564a29b0733SJohan Hedberg 2565a29b0733SJohan Hedberg if (memcmp(cfm.confirm_val, smp->pcnf, 16)) 2566a29b0733SJohan Hedberg return SMP_CONFIRM_FAILED; 2567a29b0733SJohan Hedberg 2568a29b0733SJohan Hedberg if (hcon->out) 2569a29b0733SJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, 2570a29b0733SJohan Hedberg sizeof(smp->prnd), smp->prnd); 2571a29b0733SJohan Hedberg 2572a29b0733SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM); 2573a29b0733SJohan Hedberg 2574a29b0733SJohan Hedberg return 0; 2575a29b0733SJohan Hedberg } 2576a29b0733SJohan Hedberg 257738606f14SJohan Hedberg if (hcon->out) 257838606f14SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); 257938606f14SJohan Hedberg 258038606f14SJohan Hedberg if (smp->method == REQ_PASSKEY) { 258138606f14SJohan Hedberg if (mgmt_user_passkey_request(hdev, &hcon->dst, hcon->type, 258238606f14SJohan Hedberg hcon->dst_type)) 258338606f14SJohan Hedberg return SMP_UNSPECIFIED; 258438606f14SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); 258538606f14SJohan Hedberg set_bit(SMP_FLAG_WAIT_USER, &smp->flags); 258638606f14SJohan Hedberg return 0; 258738606f14SJohan Hedberg } 258838606f14SJohan Hedberg 2589cbbbe3e2SJohan Hedberg /* The Initiating device waits for the non-initiating device to 2590cbbbe3e2SJohan Hedberg * send the confirm value. 2591cbbbe3e2SJohan Hedberg */ 2592cbbbe3e2SJohan Hedberg if (conn->hcon->out) 2593cbbbe3e2SJohan Hedberg return 0; 2594cbbbe3e2SJohan Hedberg 2595cbbbe3e2SJohan Hedberg err = smp_f4(smp->tfm_cmac, smp->local_pk, smp->remote_pk, smp->prnd, 2596cbbbe3e2SJohan Hedberg 0, cfm.confirm_val); 2597cbbbe3e2SJohan Hedberg if (err) 2598cbbbe3e2SJohan Hedberg return SMP_UNSPECIFIED; 2599cbbbe3e2SJohan Hedberg 2600cbbbe3e2SJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cfm), &cfm); 2601cbbbe3e2SJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM); 2602cbbbe3e2SJohan Hedberg 2603d8f8edbeSJohan Hedberg return 0; 2604d8f8edbeSJohan Hedberg } 2605d8f8edbeSJohan Hedberg 26066433a9a2SJohan Hedberg static int smp_cmd_dhkey_check(struct l2cap_conn *conn, struct sk_buff *skb) 26076433a9a2SJohan Hedberg { 26086433a9a2SJohan Hedberg struct smp_cmd_dhkey_check *check = (void *) skb->data; 26096433a9a2SJohan Hedberg struct l2cap_chan *chan = conn->smp; 26106433a9a2SJohan Hedberg struct hci_conn *hcon = conn->hcon; 26116433a9a2SJohan Hedberg struct smp_chan *smp = chan->data; 26126433a9a2SJohan Hedberg u8 a[7], b[7], *local_addr, *remote_addr; 26136433a9a2SJohan Hedberg u8 io_cap[3], r[16], e[16]; 26146433a9a2SJohan Hedberg int err; 26156433a9a2SJohan Hedberg 26166433a9a2SJohan Hedberg BT_DBG("conn %p", conn); 26176433a9a2SJohan Hedberg 26186433a9a2SJohan Hedberg if (skb->len < sizeof(*check)) 26196433a9a2SJohan Hedberg return SMP_INVALID_PARAMS; 26206433a9a2SJohan Hedberg 26216433a9a2SJohan Hedberg memcpy(a, &hcon->init_addr, 6); 26226433a9a2SJohan Hedberg memcpy(b, &hcon->resp_addr, 6); 26236433a9a2SJohan Hedberg a[6] = hcon->init_addr_type; 26246433a9a2SJohan Hedberg b[6] = hcon->resp_addr_type; 26256433a9a2SJohan Hedberg 26266433a9a2SJohan Hedberg if (hcon->out) { 26276433a9a2SJohan Hedberg local_addr = a; 26286433a9a2SJohan Hedberg remote_addr = b; 26296433a9a2SJohan Hedberg memcpy(io_cap, &smp->prsp[1], 3); 26306433a9a2SJohan Hedberg } else { 26316433a9a2SJohan Hedberg local_addr = b; 26326433a9a2SJohan Hedberg remote_addr = a; 26336433a9a2SJohan Hedberg memcpy(io_cap, &smp->preq[1], 3); 26346433a9a2SJohan Hedberg } 26356433a9a2SJohan Hedberg 26366433a9a2SJohan Hedberg memset(r, 0, sizeof(r)); 26376433a9a2SJohan Hedberg 263838606f14SJohan Hedberg if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY) 263938606f14SJohan Hedberg put_unaligned_le32(hcon->passkey_notify, r); 2640882fafadSJohan Hedberg else if (smp->method == REQ_OOB) 2641882fafadSJohan Hedberg memcpy(r, smp->lr, 16); 264238606f14SJohan Hedberg 26436433a9a2SJohan Hedberg err = smp_f6(smp->tfm_cmac, smp->mackey, smp->rrnd, smp->prnd, r, 26446433a9a2SJohan Hedberg io_cap, remote_addr, local_addr, e); 26456433a9a2SJohan Hedberg if (err) 26466433a9a2SJohan Hedberg return SMP_UNSPECIFIED; 26476433a9a2SJohan Hedberg 26486433a9a2SJohan Hedberg if (memcmp(check->e, e, 16)) 26496433a9a2SJohan Hedberg return SMP_DHKEY_CHECK_FAILED; 26506433a9a2SJohan Hedberg 2651d3e54a87SJohan Hedberg if (!hcon->out) { 2652d3e54a87SJohan Hedberg if (test_bit(SMP_FLAG_WAIT_USER, &smp->flags)) { 2653d3e54a87SJohan Hedberg set_bit(SMP_FLAG_DHKEY_PENDING, &smp->flags); 2654d3e54a87SJohan Hedberg return 0; 2655d3e54a87SJohan Hedberg } 2656d378a2d7SJohan Hedberg 2657d3e54a87SJohan Hedberg /* Slave sends DHKey check as response to master */ 2658d3e54a87SJohan Hedberg sc_dhkey_check(smp); 2659d3e54a87SJohan Hedberg } 2660d378a2d7SJohan Hedberg 2661d3e54a87SJohan Hedberg sc_add_ltk(smp); 26626433a9a2SJohan Hedberg 26636433a9a2SJohan Hedberg if (hcon->out) { 26646433a9a2SJohan Hedberg hci_le_start_enc(hcon, 0, 0, smp->tk); 26656433a9a2SJohan Hedberg hcon->enc_key_size = smp->enc_key_size; 26666433a9a2SJohan Hedberg } 26676433a9a2SJohan Hedberg 26686433a9a2SJohan Hedberg return 0; 26696433a9a2SJohan Hedberg } 26706433a9a2SJohan Hedberg 26711408bb6eSJohan Hedberg static int smp_cmd_keypress_notify(struct l2cap_conn *conn, 26721408bb6eSJohan Hedberg struct sk_buff *skb) 26731408bb6eSJohan Hedberg { 26741408bb6eSJohan Hedberg struct smp_cmd_keypress_notify *kp = (void *) skb->data; 26751408bb6eSJohan Hedberg 26761408bb6eSJohan Hedberg BT_DBG("value 0x%02x", kp->value); 26771408bb6eSJohan Hedberg 26781408bb6eSJohan Hedberg return 0; 26791408bb6eSJohan Hedberg } 26801408bb6eSJohan Hedberg 26814befb867SJohan Hedberg static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb) 2682eb492e01SAnderson Briglia { 26835d88cc73SJohan Hedberg struct l2cap_conn *conn = chan->conn; 26847b9899dbSMarcel Holtmann struct hci_conn *hcon = conn->hcon; 2685b28b4943SJohan Hedberg struct smp_chan *smp; 268692381f5cSMarcel Holtmann __u8 code, reason; 2687eb492e01SAnderson Briglia int err = 0; 2688eb492e01SAnderson Briglia 26898ae9b984SJohan Hedberg if (skb->len < 1) 269092381f5cSMarcel Holtmann return -EILSEQ; 269192381f5cSMarcel Holtmann 2692d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hcon->hdev, HCI_LE_ENABLED)) { 26932e65c9d2SAndre Guedes reason = SMP_PAIRING_NOTSUPP; 26942e65c9d2SAndre Guedes goto done; 26952e65c9d2SAndre Guedes } 26962e65c9d2SAndre Guedes 269792381f5cSMarcel Holtmann code = skb->data[0]; 2698eb492e01SAnderson Briglia skb_pull(skb, sizeof(code)); 2699eb492e01SAnderson Briglia 2700b28b4943SJohan Hedberg smp = chan->data; 2701b28b4943SJohan Hedberg 2702b28b4943SJohan Hedberg if (code > SMP_CMD_MAX) 2703b28b4943SJohan Hedberg goto drop; 2704b28b4943SJohan Hedberg 270524bd0bd9SJohan Hedberg if (smp && !test_and_clear_bit(code, &smp->allow_cmd)) 2706b28b4943SJohan Hedberg goto drop; 2707b28b4943SJohan Hedberg 2708b28b4943SJohan Hedberg /* If we don't have a context the only allowed commands are 2709b28b4943SJohan Hedberg * pairing request and security request. 27108cf9fa12SJohan Hedberg */ 2711b28b4943SJohan Hedberg if (!smp && code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ) 2712b28b4943SJohan Hedberg goto drop; 27138cf9fa12SJohan Hedberg 2714eb492e01SAnderson Briglia switch (code) { 2715eb492e01SAnderson Briglia case SMP_CMD_PAIRING_REQ: 2716da85e5e5SVinicius Costa Gomes reason = smp_cmd_pairing_req(conn, skb); 2717eb492e01SAnderson Briglia break; 2718eb492e01SAnderson Briglia 2719eb492e01SAnderson Briglia case SMP_CMD_PAIRING_FAIL: 272084794e11SJohan Hedberg smp_failure(conn, 0); 2721da85e5e5SVinicius Costa Gomes err = -EPERM; 2722eb492e01SAnderson Briglia break; 2723eb492e01SAnderson Briglia 2724eb492e01SAnderson Briglia case SMP_CMD_PAIRING_RSP: 2725da85e5e5SVinicius Costa Gomes reason = smp_cmd_pairing_rsp(conn, skb); 272688ba43b6SAnderson Briglia break; 272788ba43b6SAnderson Briglia 272888ba43b6SAnderson Briglia case SMP_CMD_SECURITY_REQ: 2729da85e5e5SVinicius Costa Gomes reason = smp_cmd_security_req(conn, skb); 273088ba43b6SAnderson Briglia break; 273188ba43b6SAnderson Briglia 2732eb492e01SAnderson Briglia case SMP_CMD_PAIRING_CONFIRM: 2733da85e5e5SVinicius Costa Gomes reason = smp_cmd_pairing_confirm(conn, skb); 273488ba43b6SAnderson Briglia break; 273588ba43b6SAnderson Briglia 2736eb492e01SAnderson Briglia case SMP_CMD_PAIRING_RANDOM: 2737da85e5e5SVinicius Costa Gomes reason = smp_cmd_pairing_random(conn, skb); 273888ba43b6SAnderson Briglia break; 273988ba43b6SAnderson Briglia 2740eb492e01SAnderson Briglia case SMP_CMD_ENCRYPT_INFO: 27417034b911SVinicius Costa Gomes reason = smp_cmd_encrypt_info(conn, skb); 27427034b911SVinicius Costa Gomes break; 27437034b911SVinicius Costa Gomes 2744eb492e01SAnderson Briglia case SMP_CMD_MASTER_IDENT: 27457034b911SVinicius Costa Gomes reason = smp_cmd_master_ident(conn, skb); 27467034b911SVinicius Costa Gomes break; 27477034b911SVinicius Costa Gomes 2748eb492e01SAnderson Briglia case SMP_CMD_IDENT_INFO: 2749fd349c02SJohan Hedberg reason = smp_cmd_ident_info(conn, skb); 2750fd349c02SJohan Hedberg break; 2751fd349c02SJohan Hedberg 2752eb492e01SAnderson Briglia case SMP_CMD_IDENT_ADDR_INFO: 2753fd349c02SJohan Hedberg reason = smp_cmd_ident_addr_info(conn, skb); 2754fd349c02SJohan Hedberg break; 2755fd349c02SJohan Hedberg 2756eb492e01SAnderson Briglia case SMP_CMD_SIGN_INFO: 27577ee4ea36SMarcel Holtmann reason = smp_cmd_sign_info(conn, skb); 27587034b911SVinicius Costa Gomes break; 27597034b911SVinicius Costa Gomes 2760d8f8edbeSJohan Hedberg case SMP_CMD_PUBLIC_KEY: 2761d8f8edbeSJohan Hedberg reason = smp_cmd_public_key(conn, skb); 2762d8f8edbeSJohan Hedberg break; 2763d8f8edbeSJohan Hedberg 27646433a9a2SJohan Hedberg case SMP_CMD_DHKEY_CHECK: 27656433a9a2SJohan Hedberg reason = smp_cmd_dhkey_check(conn, skb); 27666433a9a2SJohan Hedberg break; 27676433a9a2SJohan Hedberg 27681408bb6eSJohan Hedberg case SMP_CMD_KEYPRESS_NOTIFY: 27691408bb6eSJohan Hedberg reason = smp_cmd_keypress_notify(conn, skb); 27701408bb6eSJohan Hedberg break; 27711408bb6eSJohan Hedberg 2772eb492e01SAnderson Briglia default: 2773eb492e01SAnderson Briglia BT_DBG("Unknown command code 0x%2.2x", code); 2774eb492e01SAnderson Briglia reason = SMP_CMD_NOTSUPP; 27753a0259bbSVinicius Costa Gomes goto done; 27763a0259bbSVinicius Costa Gomes } 27773a0259bbSVinicius Costa Gomes 27783a0259bbSVinicius Costa Gomes done: 27799b7b18efSJohan Hedberg if (!err) { 27803a0259bbSVinicius Costa Gomes if (reason) 278184794e11SJohan Hedberg smp_failure(conn, reason); 2782eb492e01SAnderson Briglia kfree_skb(skb); 27839b7b18efSJohan Hedberg } 27849b7b18efSJohan Hedberg 2785eb492e01SAnderson Briglia return err; 2786b28b4943SJohan Hedberg 2787b28b4943SJohan Hedberg drop: 2788b28b4943SJohan Hedberg BT_ERR("%s unexpected SMP command 0x%02x from %pMR", hcon->hdev->name, 2789b28b4943SJohan Hedberg code, &hcon->dst); 2790b28b4943SJohan Hedberg kfree_skb(skb); 2791b28b4943SJohan Hedberg return 0; 2792eb492e01SAnderson Briglia } 27937034b911SVinicius Costa Gomes 279470db83c4SJohan Hedberg static void smp_teardown_cb(struct l2cap_chan *chan, int err) 279570db83c4SJohan Hedberg { 279670db83c4SJohan Hedberg struct l2cap_conn *conn = chan->conn; 279770db83c4SJohan Hedberg 279870db83c4SJohan Hedberg BT_DBG("chan %p", chan); 279970db83c4SJohan Hedberg 2800fc75cc86SJohan Hedberg if (chan->data) 28015d88cc73SJohan Hedberg smp_chan_destroy(conn); 28025d88cc73SJohan Hedberg 280370db83c4SJohan Hedberg conn->smp = NULL; 280470db83c4SJohan Hedberg l2cap_chan_put(chan); 280570db83c4SJohan Hedberg } 280670db83c4SJohan Hedberg 2807b5ae344dSJohan Hedberg static void bredr_pairing(struct l2cap_chan *chan) 2808b5ae344dSJohan Hedberg { 2809b5ae344dSJohan Hedberg struct l2cap_conn *conn = chan->conn; 2810b5ae344dSJohan Hedberg struct hci_conn *hcon = conn->hcon; 2811b5ae344dSJohan Hedberg struct hci_dev *hdev = hcon->hdev; 2812b5ae344dSJohan Hedberg struct smp_cmd_pairing req; 2813b5ae344dSJohan Hedberg struct smp_chan *smp; 2814b5ae344dSJohan Hedberg 2815b5ae344dSJohan Hedberg BT_DBG("chan %p", chan); 2816b5ae344dSJohan Hedberg 2817b5ae344dSJohan Hedberg /* Only new pairings are interesting */ 2818b5ae344dSJohan Hedberg if (!test_bit(HCI_CONN_NEW_LINK_KEY, &hcon->flags)) 2819b5ae344dSJohan Hedberg return; 2820b5ae344dSJohan Hedberg 2821b5ae344dSJohan Hedberg /* Don't bother if we're not encrypted */ 2822b5ae344dSJohan Hedberg if (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags)) 2823b5ae344dSJohan Hedberg return; 2824b5ae344dSJohan Hedberg 2825b5ae344dSJohan Hedberg /* Only master may initiate SMP over BR/EDR */ 2826b5ae344dSJohan Hedberg if (hcon->role != HCI_ROLE_MASTER) 2827b5ae344dSJohan Hedberg return; 2828b5ae344dSJohan Hedberg 2829b5ae344dSJohan Hedberg /* Secure Connections support must be enabled */ 2830d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_SC_ENABLED)) 2831b5ae344dSJohan Hedberg return; 2832b5ae344dSJohan Hedberg 2833b5ae344dSJohan Hedberg /* BR/EDR must use Secure Connections for SMP */ 2834b5ae344dSJohan Hedberg if (!test_bit(HCI_CONN_AES_CCM, &hcon->flags) && 2835b7cb93e5SMarcel Holtmann !hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP)) 2836b5ae344dSJohan Hedberg return; 2837b5ae344dSJohan Hedberg 2838b5ae344dSJohan Hedberg /* If our LE support is not enabled don't do anything */ 2839d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED)) 2840b5ae344dSJohan Hedberg return; 2841b5ae344dSJohan Hedberg 2842b5ae344dSJohan Hedberg /* Don't bother if remote LE support is not enabled */ 2843b5ae344dSJohan Hedberg if (!lmp_host_le_capable(hcon)) 2844b5ae344dSJohan Hedberg return; 2845b5ae344dSJohan Hedberg 2846b5ae344dSJohan Hedberg /* Remote must support SMP fixed chan for BR/EDR */ 2847b5ae344dSJohan Hedberg if (!(conn->remote_fixed_chan & L2CAP_FC_SMP_BREDR)) 2848b5ae344dSJohan Hedberg return; 2849b5ae344dSJohan Hedberg 2850b5ae344dSJohan Hedberg /* Don't bother if SMP is already ongoing */ 2851b5ae344dSJohan Hedberg if (chan->data) 2852b5ae344dSJohan Hedberg return; 2853b5ae344dSJohan Hedberg 2854b5ae344dSJohan Hedberg smp = smp_chan_create(conn); 2855b5ae344dSJohan Hedberg if (!smp) { 2856b5ae344dSJohan Hedberg BT_ERR("%s unable to create SMP context for BR/EDR", 2857b5ae344dSJohan Hedberg hdev->name); 2858b5ae344dSJohan Hedberg return; 2859b5ae344dSJohan Hedberg } 2860b5ae344dSJohan Hedberg 2861b5ae344dSJohan Hedberg set_bit(SMP_FLAG_SC, &smp->flags); 2862b5ae344dSJohan Hedberg 2863b5ae344dSJohan Hedberg BT_DBG("%s starting SMP over BR/EDR", hdev->name); 2864b5ae344dSJohan Hedberg 2865b5ae344dSJohan Hedberg /* Prepare and send the BR/EDR SMP Pairing Request */ 2866b5ae344dSJohan Hedberg build_bredr_pairing_cmd(smp, &req, NULL); 2867b5ae344dSJohan Hedberg 2868b5ae344dSJohan Hedberg smp->preq[0] = SMP_CMD_PAIRING_REQ; 2869b5ae344dSJohan Hedberg memcpy(&smp->preq[1], &req, sizeof(req)); 2870b5ae344dSJohan Hedberg 2871b5ae344dSJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(req), &req); 2872b5ae344dSJohan Hedberg SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP); 2873b5ae344dSJohan Hedberg } 2874b5ae344dSJohan Hedberg 287544f1a7abSJohan Hedberg static void smp_resume_cb(struct l2cap_chan *chan) 287644f1a7abSJohan Hedberg { 2877b68fda68SJohan Hedberg struct smp_chan *smp = chan->data; 287844f1a7abSJohan Hedberg struct l2cap_conn *conn = chan->conn; 287944f1a7abSJohan Hedberg struct hci_conn *hcon = conn->hcon; 288044f1a7abSJohan Hedberg 288144f1a7abSJohan Hedberg BT_DBG("chan %p", chan); 288244f1a7abSJohan Hedberg 2883b5ae344dSJohan Hedberg if (hcon->type == ACL_LINK) { 2884b5ae344dSJohan Hedberg bredr_pairing(chan); 2885ef8efe4bSJohan Hedberg return; 2886b5ae344dSJohan Hedberg } 2887ef8efe4bSJohan Hedberg 288886d1407cSJohan Hedberg if (!smp) 288986d1407cSJohan Hedberg return; 2890b68fda68SJohan Hedberg 289184bc0db5SJohan Hedberg if (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags)) 289284bc0db5SJohan Hedberg return; 289384bc0db5SJohan Hedberg 2894b68fda68SJohan Hedberg cancel_delayed_work(&smp->security_timer); 289586d1407cSJohan Hedberg 2896d6268e86SJohan Hedberg smp_distribute_keys(smp); 289744f1a7abSJohan Hedberg } 289844f1a7abSJohan Hedberg 289970db83c4SJohan Hedberg static void smp_ready_cb(struct l2cap_chan *chan) 290070db83c4SJohan Hedberg { 290170db83c4SJohan Hedberg struct l2cap_conn *conn = chan->conn; 2902b5ae344dSJohan Hedberg struct hci_conn *hcon = conn->hcon; 290370db83c4SJohan Hedberg 290470db83c4SJohan Hedberg BT_DBG("chan %p", chan); 290570db83c4SJohan Hedberg 290670db83c4SJohan Hedberg conn->smp = chan; 290770db83c4SJohan Hedberg l2cap_chan_hold(chan); 2908b5ae344dSJohan Hedberg 2909b5ae344dSJohan Hedberg if (hcon->type == ACL_LINK && test_bit(HCI_CONN_ENCRYPT, &hcon->flags)) 2910b5ae344dSJohan Hedberg bredr_pairing(chan); 291170db83c4SJohan Hedberg } 291270db83c4SJohan Hedberg 29134befb867SJohan Hedberg static int smp_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) 29144befb867SJohan Hedberg { 29154befb867SJohan Hedberg int err; 29164befb867SJohan Hedberg 29174befb867SJohan Hedberg BT_DBG("chan %p", chan); 29184befb867SJohan Hedberg 29194befb867SJohan Hedberg err = smp_sig_channel(chan, skb); 29204befb867SJohan Hedberg if (err) { 2921b68fda68SJohan Hedberg struct smp_chan *smp = chan->data; 29224befb867SJohan Hedberg 2923b68fda68SJohan Hedberg if (smp) 2924b68fda68SJohan Hedberg cancel_delayed_work_sync(&smp->security_timer); 29254befb867SJohan Hedberg 29261e91c29eSJohan Hedberg hci_disconnect(chan->conn->hcon, HCI_ERROR_AUTH_FAILURE); 29274befb867SJohan Hedberg } 29284befb867SJohan Hedberg 29294befb867SJohan Hedberg return err; 29304befb867SJohan Hedberg } 29314befb867SJohan Hedberg 293270db83c4SJohan Hedberg static struct sk_buff *smp_alloc_skb_cb(struct l2cap_chan *chan, 293370db83c4SJohan Hedberg unsigned long hdr_len, 293470db83c4SJohan Hedberg unsigned long len, int nb) 293570db83c4SJohan Hedberg { 293670db83c4SJohan Hedberg struct sk_buff *skb; 293770db83c4SJohan Hedberg 293870db83c4SJohan Hedberg skb = bt_skb_alloc(hdr_len + len, GFP_KERNEL); 293970db83c4SJohan Hedberg if (!skb) 294070db83c4SJohan Hedberg return ERR_PTR(-ENOMEM); 294170db83c4SJohan Hedberg 294270db83c4SJohan Hedberg skb->priority = HCI_PRIO_MAX; 294370db83c4SJohan Hedberg bt_cb(skb)->chan = chan; 294470db83c4SJohan Hedberg 294570db83c4SJohan Hedberg return skb; 294670db83c4SJohan Hedberg } 294770db83c4SJohan Hedberg 294870db83c4SJohan Hedberg static const struct l2cap_ops smp_chan_ops = { 294970db83c4SJohan Hedberg .name = "Security Manager", 295070db83c4SJohan Hedberg .ready = smp_ready_cb, 29515d88cc73SJohan Hedberg .recv = smp_recv_cb, 295270db83c4SJohan Hedberg .alloc_skb = smp_alloc_skb_cb, 295370db83c4SJohan Hedberg .teardown = smp_teardown_cb, 295444f1a7abSJohan Hedberg .resume = smp_resume_cb, 295570db83c4SJohan Hedberg 295670db83c4SJohan Hedberg .new_connection = l2cap_chan_no_new_connection, 295770db83c4SJohan Hedberg .state_change = l2cap_chan_no_state_change, 295870db83c4SJohan Hedberg .close = l2cap_chan_no_close, 295970db83c4SJohan Hedberg .defer = l2cap_chan_no_defer, 296070db83c4SJohan Hedberg .suspend = l2cap_chan_no_suspend, 296170db83c4SJohan Hedberg .set_shutdown = l2cap_chan_no_set_shutdown, 296270db83c4SJohan Hedberg .get_sndtimeo = l2cap_chan_no_get_sndtimeo, 296370db83c4SJohan Hedberg }; 296470db83c4SJohan Hedberg 296570db83c4SJohan Hedberg static inline struct l2cap_chan *smp_new_conn_cb(struct l2cap_chan *pchan) 296670db83c4SJohan Hedberg { 296770db83c4SJohan Hedberg struct l2cap_chan *chan; 296870db83c4SJohan Hedberg 296970db83c4SJohan Hedberg BT_DBG("pchan %p", pchan); 297070db83c4SJohan Hedberg 297170db83c4SJohan Hedberg chan = l2cap_chan_create(); 297270db83c4SJohan Hedberg if (!chan) 297370db83c4SJohan Hedberg return NULL; 297470db83c4SJohan Hedberg 297570db83c4SJohan Hedberg chan->chan_type = pchan->chan_type; 297670db83c4SJohan Hedberg chan->ops = &smp_chan_ops; 297770db83c4SJohan Hedberg chan->scid = pchan->scid; 297870db83c4SJohan Hedberg chan->dcid = chan->scid; 297970db83c4SJohan Hedberg chan->imtu = pchan->imtu; 298070db83c4SJohan Hedberg chan->omtu = pchan->omtu; 298170db83c4SJohan Hedberg chan->mode = pchan->mode; 298270db83c4SJohan Hedberg 2983abe84903SJohan Hedberg /* Other L2CAP channels may request SMP routines in order to 2984abe84903SJohan Hedberg * change the security level. This means that the SMP channel 2985abe84903SJohan Hedberg * lock must be considered in its own category to avoid lockdep 2986abe84903SJohan Hedberg * warnings. 2987abe84903SJohan Hedberg */ 2988abe84903SJohan Hedberg atomic_set(&chan->nesting, L2CAP_NESTING_SMP); 2989abe84903SJohan Hedberg 299070db83c4SJohan Hedberg BT_DBG("created chan %p", chan); 299170db83c4SJohan Hedberg 299270db83c4SJohan Hedberg return chan; 299370db83c4SJohan Hedberg } 299470db83c4SJohan Hedberg 299570db83c4SJohan Hedberg static const struct l2cap_ops smp_root_chan_ops = { 299670db83c4SJohan Hedberg .name = "Security Manager Root", 299770db83c4SJohan Hedberg .new_connection = smp_new_conn_cb, 299870db83c4SJohan Hedberg 299970db83c4SJohan Hedberg /* None of these are implemented for the root channel */ 300070db83c4SJohan Hedberg .close = l2cap_chan_no_close, 300170db83c4SJohan Hedberg .alloc_skb = l2cap_chan_no_alloc_skb, 300270db83c4SJohan Hedberg .recv = l2cap_chan_no_recv, 300370db83c4SJohan Hedberg .state_change = l2cap_chan_no_state_change, 300470db83c4SJohan Hedberg .teardown = l2cap_chan_no_teardown, 300570db83c4SJohan Hedberg .ready = l2cap_chan_no_ready, 300670db83c4SJohan Hedberg .defer = l2cap_chan_no_defer, 300770db83c4SJohan Hedberg .suspend = l2cap_chan_no_suspend, 300870db83c4SJohan Hedberg .resume = l2cap_chan_no_resume, 300970db83c4SJohan Hedberg .set_shutdown = l2cap_chan_no_set_shutdown, 301070db83c4SJohan Hedberg .get_sndtimeo = l2cap_chan_no_get_sndtimeo, 301170db83c4SJohan Hedberg }; 301270db83c4SJohan Hedberg 3013ef8efe4bSJohan Hedberg static struct l2cap_chan *smp_add_cid(struct hci_dev *hdev, u16 cid) 3014711eafe3SJohan Hedberg { 301570db83c4SJohan Hedberg struct l2cap_chan *chan; 301688a479d9SMarcel Holtmann struct smp_dev *smp; 3017defce9e8SJohan Hedberg struct crypto_blkcipher *tfm_aes; 30186e2dc6d1SMarcel Holtmann struct crypto_hash *tfm_cmac; 301970db83c4SJohan Hedberg 3020ef8efe4bSJohan Hedberg if (cid == L2CAP_CID_SMP_BREDR) { 302188a479d9SMarcel Holtmann smp = NULL; 3022ef8efe4bSJohan Hedberg goto create_chan; 3023ef8efe4bSJohan Hedberg } 3024711eafe3SJohan Hedberg 302588a479d9SMarcel Holtmann smp = kzalloc(sizeof(*smp), GFP_KERNEL); 302688a479d9SMarcel Holtmann if (!smp) 302788a479d9SMarcel Holtmann return ERR_PTR(-ENOMEM); 302888a479d9SMarcel Holtmann 302988a479d9SMarcel Holtmann tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC); 3030defce9e8SJohan Hedberg if (IS_ERR(tfm_aes)) { 303188a479d9SMarcel Holtmann BT_ERR("Unable to create ECB crypto context"); 303288a479d9SMarcel Holtmann kzfree(smp); 3033fe700771SFengguang Wu return ERR_CAST(tfm_aes); 3034711eafe3SJohan Hedberg } 3035711eafe3SJohan Hedberg 30366e2dc6d1SMarcel Holtmann tfm_cmac = crypto_alloc_hash("cmac(aes)", 0, CRYPTO_ALG_ASYNC); 30376e2dc6d1SMarcel Holtmann if (IS_ERR(tfm_cmac)) { 30386e2dc6d1SMarcel Holtmann BT_ERR("Unable to create CMAC crypto context"); 30396e2dc6d1SMarcel Holtmann crypto_free_blkcipher(tfm_aes); 30406e2dc6d1SMarcel Holtmann kzfree(smp); 30416e2dc6d1SMarcel Holtmann return ERR_CAST(tfm_cmac); 30426e2dc6d1SMarcel Holtmann } 30436e2dc6d1SMarcel Holtmann 304488a479d9SMarcel Holtmann smp->tfm_aes = tfm_aes; 30456e2dc6d1SMarcel Holtmann smp->tfm_cmac = tfm_cmac; 304688a479d9SMarcel Holtmann 3047ef8efe4bSJohan Hedberg create_chan: 304870db83c4SJohan Hedberg chan = l2cap_chan_create(); 304970db83c4SJohan Hedberg if (!chan) { 305088a479d9SMarcel Holtmann crypto_free_blkcipher(smp->tfm_aes); 30516e2dc6d1SMarcel Holtmann crypto_free_hash(smp->tfm_cmac); 305288a479d9SMarcel Holtmann kzfree(smp); 3053ef8efe4bSJohan Hedberg return ERR_PTR(-ENOMEM); 305470db83c4SJohan Hedberg } 305570db83c4SJohan Hedberg 305688a479d9SMarcel Holtmann chan->data = smp; 3057defce9e8SJohan Hedberg 3058ef8efe4bSJohan Hedberg l2cap_add_scid(chan, cid); 305970db83c4SJohan Hedberg 306070db83c4SJohan Hedberg l2cap_chan_set_defaults(chan); 306170db83c4SJohan Hedberg 3062157029baSMarcel Holtmann if (cid == L2CAP_CID_SMP) { 306339e3e744SJohan Hedberg u8 bdaddr_type; 306439e3e744SJohan Hedberg 306539e3e744SJohan Hedberg hci_copy_identity_address(hdev, &chan->src, &bdaddr_type); 306639e3e744SJohan Hedberg 306739e3e744SJohan Hedberg if (bdaddr_type == ADDR_LE_DEV_PUBLIC) 306870db83c4SJohan Hedberg chan->src_type = BDADDR_LE_PUBLIC; 306939e3e744SJohan Hedberg else 307039e3e744SJohan Hedberg chan->src_type = BDADDR_LE_RANDOM; 3071157029baSMarcel Holtmann } else { 3072157029baSMarcel Holtmann bacpy(&chan->src, &hdev->bdaddr); 3073ef8efe4bSJohan Hedberg chan->src_type = BDADDR_BREDR; 3074157029baSMarcel Holtmann } 3075157029baSMarcel Holtmann 307670db83c4SJohan Hedberg chan->state = BT_LISTEN; 307770db83c4SJohan Hedberg chan->mode = L2CAP_MODE_BASIC; 307870db83c4SJohan Hedberg chan->imtu = L2CAP_DEFAULT_MTU; 307970db83c4SJohan Hedberg chan->ops = &smp_root_chan_ops; 308070db83c4SJohan Hedberg 3081abe84903SJohan Hedberg /* Set correct nesting level for a parent/listening channel */ 3082abe84903SJohan Hedberg atomic_set(&chan->nesting, L2CAP_NESTING_PARENT); 3083abe84903SJohan Hedberg 3084ef8efe4bSJohan Hedberg return chan; 3085711eafe3SJohan Hedberg } 3086711eafe3SJohan Hedberg 3087ef8efe4bSJohan Hedberg static void smp_del_chan(struct l2cap_chan *chan) 3088711eafe3SJohan Hedberg { 308988a479d9SMarcel Holtmann struct smp_dev *smp; 309070db83c4SJohan Hedberg 3091ef8efe4bSJohan Hedberg BT_DBG("chan %p", chan); 3092711eafe3SJohan Hedberg 309388a479d9SMarcel Holtmann smp = chan->data; 309488a479d9SMarcel Holtmann if (smp) { 3095defce9e8SJohan Hedberg chan->data = NULL; 309688a479d9SMarcel Holtmann if (smp->tfm_aes) 309788a479d9SMarcel Holtmann crypto_free_blkcipher(smp->tfm_aes); 30986e2dc6d1SMarcel Holtmann if (smp->tfm_cmac) 30996e2dc6d1SMarcel Holtmann crypto_free_hash(smp->tfm_cmac); 310088a479d9SMarcel Holtmann kzfree(smp); 3101711eafe3SJohan Hedberg } 310270db83c4SJohan Hedberg 310370db83c4SJohan Hedberg l2cap_chan_put(chan); 3104711eafe3SJohan Hedberg } 3105ef8efe4bSJohan Hedberg 3106300acfdeSMarcel Holtmann static ssize_t force_bredr_smp_read(struct file *file, 3107300acfdeSMarcel Holtmann char __user *user_buf, 3108300acfdeSMarcel Holtmann size_t count, loff_t *ppos) 3109300acfdeSMarcel Holtmann { 3110300acfdeSMarcel Holtmann struct hci_dev *hdev = file->private_data; 3111300acfdeSMarcel Holtmann char buf[3]; 3112300acfdeSMarcel Holtmann 3113b7cb93e5SMarcel Holtmann buf[0] = hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP) ? 'Y': 'N'; 3114300acfdeSMarcel Holtmann buf[1] = '\n'; 3115300acfdeSMarcel Holtmann buf[2] = '\0'; 3116300acfdeSMarcel Holtmann return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 3117300acfdeSMarcel Holtmann } 3118300acfdeSMarcel Holtmann 3119300acfdeSMarcel Holtmann static ssize_t force_bredr_smp_write(struct file *file, 3120300acfdeSMarcel Holtmann const char __user *user_buf, 3121300acfdeSMarcel Holtmann size_t count, loff_t *ppos) 3122300acfdeSMarcel Holtmann { 3123300acfdeSMarcel Holtmann struct hci_dev *hdev = file->private_data; 3124300acfdeSMarcel Holtmann char buf[32]; 3125300acfdeSMarcel Holtmann size_t buf_size = min(count, (sizeof(buf)-1)); 3126300acfdeSMarcel Holtmann bool enable; 3127300acfdeSMarcel Holtmann 3128300acfdeSMarcel Holtmann if (copy_from_user(buf, user_buf, buf_size)) 3129300acfdeSMarcel Holtmann return -EFAULT; 3130300acfdeSMarcel Holtmann 3131300acfdeSMarcel Holtmann buf[buf_size] = '\0'; 3132300acfdeSMarcel Holtmann if (strtobool(buf, &enable)) 3133300acfdeSMarcel Holtmann return -EINVAL; 3134300acfdeSMarcel Holtmann 3135b7cb93e5SMarcel Holtmann if (enable == hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP)) 3136300acfdeSMarcel Holtmann return -EALREADY; 3137300acfdeSMarcel Holtmann 3138300acfdeSMarcel Holtmann if (enable) { 3139300acfdeSMarcel Holtmann struct l2cap_chan *chan; 3140300acfdeSMarcel Holtmann 3141300acfdeSMarcel Holtmann chan = smp_add_cid(hdev, L2CAP_CID_SMP_BREDR); 3142300acfdeSMarcel Holtmann if (IS_ERR(chan)) 3143300acfdeSMarcel Holtmann return PTR_ERR(chan); 3144300acfdeSMarcel Holtmann 3145300acfdeSMarcel Holtmann hdev->smp_bredr_data = chan; 3146300acfdeSMarcel Holtmann } else { 3147300acfdeSMarcel Holtmann struct l2cap_chan *chan; 3148300acfdeSMarcel Holtmann 3149300acfdeSMarcel Holtmann chan = hdev->smp_bredr_data; 3150300acfdeSMarcel Holtmann hdev->smp_bredr_data = NULL; 3151300acfdeSMarcel Holtmann smp_del_chan(chan); 3152300acfdeSMarcel Holtmann } 3153300acfdeSMarcel Holtmann 3154b7cb93e5SMarcel Holtmann hci_dev_change_flag(hdev, HCI_FORCE_BREDR_SMP); 3155300acfdeSMarcel Holtmann 3156300acfdeSMarcel Holtmann return count; 3157300acfdeSMarcel Holtmann } 3158300acfdeSMarcel Holtmann 3159300acfdeSMarcel Holtmann static const struct file_operations force_bredr_smp_fops = { 3160300acfdeSMarcel Holtmann .open = simple_open, 3161300acfdeSMarcel Holtmann .read = force_bredr_smp_read, 3162300acfdeSMarcel Holtmann .write = force_bredr_smp_write, 3163300acfdeSMarcel Holtmann .llseek = default_llseek, 3164300acfdeSMarcel Holtmann }; 3165300acfdeSMarcel Holtmann 3166ef8efe4bSJohan Hedberg int smp_register(struct hci_dev *hdev) 3167ef8efe4bSJohan Hedberg { 3168ef8efe4bSJohan Hedberg struct l2cap_chan *chan; 3169ef8efe4bSJohan Hedberg 3170ef8efe4bSJohan Hedberg BT_DBG("%s", hdev->name); 3171ef8efe4bSJohan Hedberg 31727e7ec445SMarcel Holtmann /* If the controller does not support Low Energy operation, then 31737e7ec445SMarcel Holtmann * there is also no need to register any SMP channel. 31747e7ec445SMarcel Holtmann */ 31757e7ec445SMarcel Holtmann if (!lmp_le_capable(hdev)) 31767e7ec445SMarcel Holtmann return 0; 31777e7ec445SMarcel Holtmann 31782b8df323SMarcel Holtmann if (WARN_ON(hdev->smp_data)) { 31792b8df323SMarcel Holtmann chan = hdev->smp_data; 31802b8df323SMarcel Holtmann hdev->smp_data = NULL; 31812b8df323SMarcel Holtmann smp_del_chan(chan); 31822b8df323SMarcel Holtmann } 31832b8df323SMarcel Holtmann 3184ef8efe4bSJohan Hedberg chan = smp_add_cid(hdev, L2CAP_CID_SMP); 3185ef8efe4bSJohan Hedberg if (IS_ERR(chan)) 3186ef8efe4bSJohan Hedberg return PTR_ERR(chan); 3187ef8efe4bSJohan Hedberg 3188ef8efe4bSJohan Hedberg hdev->smp_data = chan; 3189ef8efe4bSJohan Hedberg 3190300acfdeSMarcel Holtmann /* If the controller does not support BR/EDR Secure Connections 3191300acfdeSMarcel Holtmann * feature, then the BR/EDR SMP channel shall not be present. 3192300acfdeSMarcel Holtmann * 3193300acfdeSMarcel Holtmann * To test this with Bluetooth 4.0 controllers, create a debugfs 3194300acfdeSMarcel Holtmann * switch that allows forcing BR/EDR SMP support and accepting 3195300acfdeSMarcel Holtmann * cross-transport pairing on non-AES encrypted connections. 3196300acfdeSMarcel Holtmann */ 3197300acfdeSMarcel Holtmann if (!lmp_sc_capable(hdev)) { 3198300acfdeSMarcel Holtmann debugfs_create_file("force_bredr_smp", 0644, hdev->debugfs, 3199300acfdeSMarcel Holtmann hdev, &force_bredr_smp_fops); 3200ef8efe4bSJohan Hedberg return 0; 3201300acfdeSMarcel Holtmann } 3202ef8efe4bSJohan Hedberg 32032b8df323SMarcel Holtmann if (WARN_ON(hdev->smp_bredr_data)) { 32042b8df323SMarcel Holtmann chan = hdev->smp_bredr_data; 32052b8df323SMarcel Holtmann hdev->smp_bredr_data = NULL; 32062b8df323SMarcel Holtmann smp_del_chan(chan); 32072b8df323SMarcel Holtmann } 32082b8df323SMarcel Holtmann 3209ef8efe4bSJohan Hedberg chan = smp_add_cid(hdev, L2CAP_CID_SMP_BREDR); 3210ef8efe4bSJohan Hedberg if (IS_ERR(chan)) { 3211ef8efe4bSJohan Hedberg int err = PTR_ERR(chan); 3212ef8efe4bSJohan Hedberg chan = hdev->smp_data; 3213ef8efe4bSJohan Hedberg hdev->smp_data = NULL; 3214ef8efe4bSJohan Hedberg smp_del_chan(chan); 3215ef8efe4bSJohan Hedberg return err; 3216ef8efe4bSJohan Hedberg } 3217ef8efe4bSJohan Hedberg 3218ef8efe4bSJohan Hedberg hdev->smp_bredr_data = chan; 3219ef8efe4bSJohan Hedberg 3220ef8efe4bSJohan Hedberg return 0; 3221ef8efe4bSJohan Hedberg } 3222ef8efe4bSJohan Hedberg 3223ef8efe4bSJohan Hedberg void smp_unregister(struct hci_dev *hdev) 3224ef8efe4bSJohan Hedberg { 3225ef8efe4bSJohan Hedberg struct l2cap_chan *chan; 3226ef8efe4bSJohan Hedberg 3227ef8efe4bSJohan Hedberg if (hdev->smp_bredr_data) { 3228ef8efe4bSJohan Hedberg chan = hdev->smp_bredr_data; 3229ef8efe4bSJohan Hedberg hdev->smp_bredr_data = NULL; 3230ef8efe4bSJohan Hedberg smp_del_chan(chan); 3231ef8efe4bSJohan Hedberg } 3232ef8efe4bSJohan Hedberg 3233ef8efe4bSJohan Hedberg if (hdev->smp_data) { 3234ef8efe4bSJohan Hedberg chan = hdev->smp_data; 3235ef8efe4bSJohan Hedberg hdev->smp_data = NULL; 3236ef8efe4bSJohan Hedberg smp_del_chan(chan); 3237ef8efe4bSJohan Hedberg } 3238ef8efe4bSJohan Hedberg } 32390a2b0f04SJohan Hedberg 32400a2b0f04SJohan Hedberg #if IS_ENABLED(CONFIG_BT_SELFTEST_SMP) 32410a2b0f04SJohan Hedberg 3242cfc4198eSJohan Hedberg static int __init test_ah(struct crypto_blkcipher *tfm_aes) 3243cfc4198eSJohan Hedberg { 3244cfc4198eSJohan Hedberg const u8 irk[16] = { 3245cfc4198eSJohan Hedberg 0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34, 3246cfc4198eSJohan Hedberg 0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec }; 3247cfc4198eSJohan Hedberg const u8 r[3] = { 0x94, 0x81, 0x70 }; 3248cfc4198eSJohan Hedberg const u8 exp[3] = { 0xaa, 0xfb, 0x0d }; 3249cfc4198eSJohan Hedberg u8 res[3]; 3250cfc4198eSJohan Hedberg int err; 3251cfc4198eSJohan Hedberg 3252cfc4198eSJohan Hedberg err = smp_ah(tfm_aes, irk, r, res); 3253cfc4198eSJohan Hedberg if (err) 3254cfc4198eSJohan Hedberg return err; 3255cfc4198eSJohan Hedberg 3256cfc4198eSJohan Hedberg if (memcmp(res, exp, 3)) 3257cfc4198eSJohan Hedberg return -EINVAL; 3258cfc4198eSJohan Hedberg 3259cfc4198eSJohan Hedberg return 0; 3260cfc4198eSJohan Hedberg } 3261cfc4198eSJohan Hedberg 3262cfc4198eSJohan Hedberg static int __init test_c1(struct crypto_blkcipher *tfm_aes) 3263cfc4198eSJohan Hedberg { 3264cfc4198eSJohan Hedberg const u8 k[16] = { 3265cfc4198eSJohan Hedberg 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3266cfc4198eSJohan Hedberg 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 3267cfc4198eSJohan Hedberg const u8 r[16] = { 3268cfc4198eSJohan Hedberg 0xe0, 0x2e, 0x70, 0xc6, 0x4e, 0x27, 0x88, 0x63, 3269cfc4198eSJohan Hedberg 0x0e, 0x6f, 0xad, 0x56, 0x21, 0xd5, 0x83, 0x57 }; 3270cfc4198eSJohan Hedberg const u8 preq[7] = { 0x01, 0x01, 0x00, 0x00, 0x10, 0x07, 0x07 }; 3271cfc4198eSJohan Hedberg const u8 pres[7] = { 0x02, 0x03, 0x00, 0x00, 0x08, 0x00, 0x05 }; 3272cfc4198eSJohan Hedberg const u8 _iat = 0x01; 3273cfc4198eSJohan Hedberg const u8 _rat = 0x00; 3274cfc4198eSJohan Hedberg const bdaddr_t ra = { { 0xb6, 0xb5, 0xb4, 0xb3, 0xb2, 0xb1 } }; 3275cfc4198eSJohan Hedberg const bdaddr_t ia = { { 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1 } }; 3276cfc4198eSJohan Hedberg const u8 exp[16] = { 3277cfc4198eSJohan Hedberg 0x86, 0x3b, 0xf1, 0xbe, 0xc5, 0x4d, 0xa7, 0xd2, 3278cfc4198eSJohan Hedberg 0xea, 0x88, 0x89, 0x87, 0xef, 0x3f, 0x1e, 0x1e }; 3279cfc4198eSJohan Hedberg u8 res[16]; 3280cfc4198eSJohan Hedberg int err; 3281cfc4198eSJohan Hedberg 3282cfc4198eSJohan Hedberg err = smp_c1(tfm_aes, k, r, preq, pres, _iat, &ia, _rat, &ra, res); 3283cfc4198eSJohan Hedberg if (err) 3284cfc4198eSJohan Hedberg return err; 3285cfc4198eSJohan Hedberg 3286cfc4198eSJohan Hedberg if (memcmp(res, exp, 16)) 3287cfc4198eSJohan Hedberg return -EINVAL; 3288cfc4198eSJohan Hedberg 3289cfc4198eSJohan Hedberg return 0; 3290cfc4198eSJohan Hedberg } 3291cfc4198eSJohan Hedberg 3292cfc4198eSJohan Hedberg static int __init test_s1(struct crypto_blkcipher *tfm_aes) 3293cfc4198eSJohan Hedberg { 3294cfc4198eSJohan Hedberg const u8 k[16] = { 3295cfc4198eSJohan Hedberg 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3296cfc4198eSJohan Hedberg 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 3297cfc4198eSJohan Hedberg const u8 r1[16] = { 3298cfc4198eSJohan Hedberg 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 }; 3299cfc4198eSJohan Hedberg const u8 r2[16] = { 3300cfc4198eSJohan Hedberg 0x00, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99 }; 3301cfc4198eSJohan Hedberg const u8 exp[16] = { 3302cfc4198eSJohan Hedberg 0x62, 0xa0, 0x6d, 0x79, 0xae, 0x16, 0x42, 0x5b, 3303cfc4198eSJohan Hedberg 0x9b, 0xf4, 0xb0, 0xe8, 0xf0, 0xe1, 0x1f, 0x9a }; 3304cfc4198eSJohan Hedberg u8 res[16]; 3305cfc4198eSJohan Hedberg int err; 3306cfc4198eSJohan Hedberg 3307cfc4198eSJohan Hedberg err = smp_s1(tfm_aes, k, r1, r2, res); 3308cfc4198eSJohan Hedberg if (err) 3309cfc4198eSJohan Hedberg return err; 3310cfc4198eSJohan Hedberg 3311cfc4198eSJohan Hedberg if (memcmp(res, exp, 16)) 3312cfc4198eSJohan Hedberg return -EINVAL; 3313cfc4198eSJohan Hedberg 3314cfc4198eSJohan Hedberg return 0; 3315cfc4198eSJohan Hedberg } 3316cfc4198eSJohan Hedberg 3317fb2969a3SJohan Hedberg static int __init test_f4(struct crypto_hash *tfm_cmac) 3318fb2969a3SJohan Hedberg { 3319fb2969a3SJohan Hedberg const u8 u[32] = { 3320fb2969a3SJohan Hedberg 0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc, 3321fb2969a3SJohan Hedberg 0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef, 3322fb2969a3SJohan Hedberg 0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e, 3323fb2969a3SJohan Hedberg 0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20 }; 3324fb2969a3SJohan Hedberg const u8 v[32] = { 3325fb2969a3SJohan Hedberg 0xfd, 0xc5, 0x7f, 0xf4, 0x49, 0xdd, 0x4f, 0x6b, 3326fb2969a3SJohan Hedberg 0xfb, 0x7c, 0x9d, 0xf1, 0xc2, 0x9a, 0xcb, 0x59, 3327fb2969a3SJohan Hedberg 0x2a, 0xe7, 0xd4, 0xee, 0xfb, 0xfc, 0x0a, 0x90, 3328fb2969a3SJohan Hedberg 0x9a, 0xbb, 0xf6, 0x32, 0x3d, 0x8b, 0x18, 0x55 }; 3329fb2969a3SJohan Hedberg const u8 x[16] = { 3330fb2969a3SJohan Hedberg 0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff, 3331fb2969a3SJohan Hedberg 0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 }; 3332fb2969a3SJohan Hedberg const u8 z = 0x00; 3333fb2969a3SJohan Hedberg const u8 exp[16] = { 3334fb2969a3SJohan Hedberg 0x2d, 0x87, 0x74, 0xa9, 0xbe, 0xa1, 0xed, 0xf1, 3335fb2969a3SJohan Hedberg 0x1c, 0xbd, 0xa9, 0x07, 0xf1, 0x16, 0xc9, 0xf2 }; 3336fb2969a3SJohan Hedberg u8 res[16]; 3337fb2969a3SJohan Hedberg int err; 3338fb2969a3SJohan Hedberg 3339fb2969a3SJohan Hedberg err = smp_f4(tfm_cmac, u, v, x, z, res); 3340fb2969a3SJohan Hedberg if (err) 3341fb2969a3SJohan Hedberg return err; 3342fb2969a3SJohan Hedberg 3343fb2969a3SJohan Hedberg if (memcmp(res, exp, 16)) 3344fb2969a3SJohan Hedberg return -EINVAL; 3345fb2969a3SJohan Hedberg 3346fb2969a3SJohan Hedberg return 0; 3347fb2969a3SJohan Hedberg } 3348fb2969a3SJohan Hedberg 3349fb2969a3SJohan Hedberg static int __init test_f5(struct crypto_hash *tfm_cmac) 3350fb2969a3SJohan Hedberg { 3351fb2969a3SJohan Hedberg const u8 w[32] = { 3352fb2969a3SJohan Hedberg 0x98, 0xa6, 0xbf, 0x73, 0xf3, 0x34, 0x8d, 0x86, 3353fb2969a3SJohan Hedberg 0xf1, 0x66, 0xf8, 0xb4, 0x13, 0x6b, 0x79, 0x99, 3354fb2969a3SJohan Hedberg 0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34, 3355fb2969a3SJohan Hedberg 0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec }; 3356fb2969a3SJohan Hedberg const u8 n1[16] = { 3357fb2969a3SJohan Hedberg 0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff, 3358fb2969a3SJohan Hedberg 0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 }; 3359fb2969a3SJohan Hedberg const u8 n2[16] = { 3360fb2969a3SJohan Hedberg 0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21, 3361fb2969a3SJohan Hedberg 0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6 }; 3362fb2969a3SJohan Hedberg const u8 a1[7] = { 0xce, 0xbf, 0x37, 0x37, 0x12, 0x56, 0x00 }; 3363fb2969a3SJohan Hedberg const u8 a2[7] = { 0xc1, 0xcf, 0x2d, 0x70, 0x13, 0xa7, 0x00 }; 3364fb2969a3SJohan Hedberg const u8 exp_ltk[16] = { 3365fb2969a3SJohan Hedberg 0x38, 0x0a, 0x75, 0x94, 0xb5, 0x22, 0x05, 0x98, 3366fb2969a3SJohan Hedberg 0x23, 0xcd, 0xd7, 0x69, 0x11, 0x79, 0x86, 0x69 }; 3367fb2969a3SJohan Hedberg const u8 exp_mackey[16] = { 3368fb2969a3SJohan Hedberg 0x20, 0x6e, 0x63, 0xce, 0x20, 0x6a, 0x3f, 0xfd, 3369fb2969a3SJohan Hedberg 0x02, 0x4a, 0x08, 0xa1, 0x76, 0xf1, 0x65, 0x29 }; 3370fb2969a3SJohan Hedberg u8 mackey[16], ltk[16]; 3371fb2969a3SJohan Hedberg int err; 3372fb2969a3SJohan Hedberg 3373fb2969a3SJohan Hedberg err = smp_f5(tfm_cmac, w, n1, n2, a1, a2, mackey, ltk); 3374fb2969a3SJohan Hedberg if (err) 3375fb2969a3SJohan Hedberg return err; 3376fb2969a3SJohan Hedberg 3377fb2969a3SJohan Hedberg if (memcmp(mackey, exp_mackey, 16)) 3378fb2969a3SJohan Hedberg return -EINVAL; 3379fb2969a3SJohan Hedberg 3380fb2969a3SJohan Hedberg if (memcmp(ltk, exp_ltk, 16)) 3381fb2969a3SJohan Hedberg return -EINVAL; 3382fb2969a3SJohan Hedberg 3383fb2969a3SJohan Hedberg return 0; 3384fb2969a3SJohan Hedberg } 3385fb2969a3SJohan Hedberg 3386fb2969a3SJohan Hedberg static int __init test_f6(struct crypto_hash *tfm_cmac) 3387fb2969a3SJohan Hedberg { 3388fb2969a3SJohan Hedberg const u8 w[16] = { 3389fb2969a3SJohan Hedberg 0x20, 0x6e, 0x63, 0xce, 0x20, 0x6a, 0x3f, 0xfd, 3390fb2969a3SJohan Hedberg 0x02, 0x4a, 0x08, 0xa1, 0x76, 0xf1, 0x65, 0x29 }; 3391fb2969a3SJohan Hedberg const u8 n1[16] = { 3392fb2969a3SJohan Hedberg 0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff, 3393fb2969a3SJohan Hedberg 0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 }; 3394fb2969a3SJohan Hedberg const u8 n2[16] = { 3395fb2969a3SJohan Hedberg 0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21, 3396fb2969a3SJohan Hedberg 0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6 }; 3397fb2969a3SJohan Hedberg const u8 r[16] = { 3398fb2969a3SJohan Hedberg 0xc8, 0x0f, 0x2d, 0x0c, 0xd2, 0x42, 0xda, 0x08, 3399fb2969a3SJohan Hedberg 0x54, 0xbb, 0x53, 0xb4, 0x3b, 0x34, 0xa3, 0x12 }; 3400fb2969a3SJohan Hedberg const u8 io_cap[3] = { 0x02, 0x01, 0x01 }; 3401fb2969a3SJohan Hedberg const u8 a1[7] = { 0xce, 0xbf, 0x37, 0x37, 0x12, 0x56, 0x00 }; 3402fb2969a3SJohan Hedberg const u8 a2[7] = { 0xc1, 0xcf, 0x2d, 0x70, 0x13, 0xa7, 0x00 }; 3403fb2969a3SJohan Hedberg const u8 exp[16] = { 3404fb2969a3SJohan Hedberg 0x61, 0x8f, 0x95, 0xda, 0x09, 0x0b, 0x6c, 0xd2, 3405fb2969a3SJohan Hedberg 0xc5, 0xe8, 0xd0, 0x9c, 0x98, 0x73, 0xc4, 0xe3 }; 3406fb2969a3SJohan Hedberg u8 res[16]; 3407fb2969a3SJohan Hedberg int err; 3408fb2969a3SJohan Hedberg 3409fb2969a3SJohan Hedberg err = smp_f6(tfm_cmac, w, n1, n2, r, io_cap, a1, a2, res); 3410fb2969a3SJohan Hedberg if (err) 3411fb2969a3SJohan Hedberg return err; 3412fb2969a3SJohan Hedberg 3413fb2969a3SJohan Hedberg if (memcmp(res, exp, 16)) 3414fb2969a3SJohan Hedberg return -EINVAL; 3415fb2969a3SJohan Hedberg 3416fb2969a3SJohan Hedberg return 0; 3417fb2969a3SJohan Hedberg } 3418fb2969a3SJohan Hedberg 3419fb2969a3SJohan Hedberg static int __init test_g2(struct crypto_hash *tfm_cmac) 3420fb2969a3SJohan Hedberg { 3421fb2969a3SJohan Hedberg const u8 u[32] = { 3422fb2969a3SJohan Hedberg 0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc, 3423fb2969a3SJohan Hedberg 0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef, 3424fb2969a3SJohan Hedberg 0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e, 3425fb2969a3SJohan Hedberg 0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20 }; 3426fb2969a3SJohan Hedberg const u8 v[32] = { 3427fb2969a3SJohan Hedberg 0xfd, 0xc5, 0x7f, 0xf4, 0x49, 0xdd, 0x4f, 0x6b, 3428fb2969a3SJohan Hedberg 0xfb, 0x7c, 0x9d, 0xf1, 0xc2, 0x9a, 0xcb, 0x59, 3429fb2969a3SJohan Hedberg 0x2a, 0xe7, 0xd4, 0xee, 0xfb, 0xfc, 0x0a, 0x90, 3430fb2969a3SJohan Hedberg 0x9a, 0xbb, 0xf6, 0x32, 0x3d, 0x8b, 0x18, 0x55 }; 3431fb2969a3SJohan Hedberg const u8 x[16] = { 3432fb2969a3SJohan Hedberg 0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff, 3433fb2969a3SJohan Hedberg 0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 }; 3434fb2969a3SJohan Hedberg const u8 y[16] = { 3435fb2969a3SJohan Hedberg 0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21, 3436fb2969a3SJohan Hedberg 0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6 }; 3437fb2969a3SJohan Hedberg const u32 exp_val = 0x2f9ed5ba % 1000000; 3438fb2969a3SJohan Hedberg u32 val; 3439fb2969a3SJohan Hedberg int err; 3440fb2969a3SJohan Hedberg 3441fb2969a3SJohan Hedberg err = smp_g2(tfm_cmac, u, v, x, y, &val); 3442fb2969a3SJohan Hedberg if (err) 3443fb2969a3SJohan Hedberg return err; 3444fb2969a3SJohan Hedberg 3445fb2969a3SJohan Hedberg if (val != exp_val) 3446fb2969a3SJohan Hedberg return -EINVAL; 3447fb2969a3SJohan Hedberg 3448fb2969a3SJohan Hedberg return 0; 3449fb2969a3SJohan Hedberg } 3450fb2969a3SJohan Hedberg 3451fb2969a3SJohan Hedberg static int __init test_h6(struct crypto_hash *tfm_cmac) 3452fb2969a3SJohan Hedberg { 3453fb2969a3SJohan Hedberg const u8 w[16] = { 3454fb2969a3SJohan Hedberg 0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34, 3455fb2969a3SJohan Hedberg 0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec }; 3456fb2969a3SJohan Hedberg const u8 key_id[4] = { 0x72, 0x62, 0x65, 0x6c }; 3457fb2969a3SJohan Hedberg const u8 exp[16] = { 3458fb2969a3SJohan Hedberg 0x99, 0x63, 0xb1, 0x80, 0xe2, 0xa9, 0xd3, 0xe8, 3459fb2969a3SJohan Hedberg 0x1c, 0xc9, 0x6d, 0xe7, 0x02, 0xe1, 0x9a, 0x2d }; 3460fb2969a3SJohan Hedberg u8 res[16]; 3461fb2969a3SJohan Hedberg int err; 3462fb2969a3SJohan Hedberg 3463fb2969a3SJohan Hedberg err = smp_h6(tfm_cmac, w, key_id, res); 3464fb2969a3SJohan Hedberg if (err) 3465fb2969a3SJohan Hedberg return err; 3466fb2969a3SJohan Hedberg 3467fb2969a3SJohan Hedberg if (memcmp(res, exp, 16)) 3468fb2969a3SJohan Hedberg return -EINVAL; 3469fb2969a3SJohan Hedberg 3470fb2969a3SJohan Hedberg return 0; 3471fb2969a3SJohan Hedberg } 3472fb2969a3SJohan Hedberg 34730a2b0f04SJohan Hedberg static int __init run_selftests(struct crypto_blkcipher *tfm_aes, 34740a2b0f04SJohan Hedberg struct crypto_hash *tfm_cmac) 34750a2b0f04SJohan Hedberg { 3476255047b0SMarcel Holtmann ktime_t calltime, delta, rettime; 3477255047b0SMarcel Holtmann unsigned long long duration; 3478cfc4198eSJohan Hedberg int err; 3479cfc4198eSJohan Hedberg 3480255047b0SMarcel Holtmann calltime = ktime_get(); 3481255047b0SMarcel Holtmann 3482cfc4198eSJohan Hedberg err = test_ah(tfm_aes); 3483cfc4198eSJohan Hedberg if (err) { 3484cfc4198eSJohan Hedberg BT_ERR("smp_ah test failed"); 3485cfc4198eSJohan Hedberg return err; 3486cfc4198eSJohan Hedberg } 3487cfc4198eSJohan Hedberg 3488cfc4198eSJohan Hedberg err = test_c1(tfm_aes); 3489cfc4198eSJohan Hedberg if (err) { 3490cfc4198eSJohan Hedberg BT_ERR("smp_c1 test failed"); 3491cfc4198eSJohan Hedberg return err; 3492cfc4198eSJohan Hedberg } 3493cfc4198eSJohan Hedberg 3494cfc4198eSJohan Hedberg err = test_s1(tfm_aes); 3495cfc4198eSJohan Hedberg if (err) { 3496cfc4198eSJohan Hedberg BT_ERR("smp_s1 test failed"); 3497cfc4198eSJohan Hedberg return err; 3498cfc4198eSJohan Hedberg } 3499cfc4198eSJohan Hedberg 3500fb2969a3SJohan Hedberg err = test_f4(tfm_cmac); 3501fb2969a3SJohan Hedberg if (err) { 3502fb2969a3SJohan Hedberg BT_ERR("smp_f4 test failed"); 3503fb2969a3SJohan Hedberg return err; 3504fb2969a3SJohan Hedberg } 3505fb2969a3SJohan Hedberg 3506fb2969a3SJohan Hedberg err = test_f5(tfm_cmac); 3507fb2969a3SJohan Hedberg if (err) { 3508fb2969a3SJohan Hedberg BT_ERR("smp_f5 test failed"); 3509fb2969a3SJohan Hedberg return err; 3510fb2969a3SJohan Hedberg } 3511fb2969a3SJohan Hedberg 3512fb2969a3SJohan Hedberg err = test_f6(tfm_cmac); 3513fb2969a3SJohan Hedberg if (err) { 3514fb2969a3SJohan Hedberg BT_ERR("smp_f6 test failed"); 3515fb2969a3SJohan Hedberg return err; 3516fb2969a3SJohan Hedberg } 3517fb2969a3SJohan Hedberg 3518fb2969a3SJohan Hedberg err = test_g2(tfm_cmac); 3519fb2969a3SJohan Hedberg if (err) { 3520fb2969a3SJohan Hedberg BT_ERR("smp_g2 test failed"); 3521fb2969a3SJohan Hedberg return err; 3522fb2969a3SJohan Hedberg } 3523fb2969a3SJohan Hedberg 3524fb2969a3SJohan Hedberg err = test_h6(tfm_cmac); 3525fb2969a3SJohan Hedberg if (err) { 3526fb2969a3SJohan Hedberg BT_ERR("smp_h6 test failed"); 3527fb2969a3SJohan Hedberg return err; 3528fb2969a3SJohan Hedberg } 3529fb2969a3SJohan Hedberg 3530255047b0SMarcel Holtmann rettime = ktime_get(); 3531255047b0SMarcel Holtmann delta = ktime_sub(rettime, calltime); 3532255047b0SMarcel Holtmann duration = (unsigned long long) ktime_to_ns(delta) >> 10; 3533255047b0SMarcel Holtmann 35345ced2464SMarcel Holtmann BT_INFO("SMP test passed in %llu usecs", duration); 35350a2b0f04SJohan Hedberg 35360a2b0f04SJohan Hedberg return 0; 35370a2b0f04SJohan Hedberg } 35380a2b0f04SJohan Hedberg 35390a2b0f04SJohan Hedberg int __init bt_selftest_smp(void) 35400a2b0f04SJohan Hedberg { 35410a2b0f04SJohan Hedberg struct crypto_blkcipher *tfm_aes; 35420a2b0f04SJohan Hedberg struct crypto_hash *tfm_cmac; 35430a2b0f04SJohan Hedberg int err; 35440a2b0f04SJohan Hedberg 35450a2b0f04SJohan Hedberg tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC); 35460a2b0f04SJohan Hedberg if (IS_ERR(tfm_aes)) { 35470a2b0f04SJohan Hedberg BT_ERR("Unable to create ECB crypto context"); 35480a2b0f04SJohan Hedberg return PTR_ERR(tfm_aes); 35490a2b0f04SJohan Hedberg } 35500a2b0f04SJohan Hedberg 35510a2b0f04SJohan Hedberg tfm_cmac = crypto_alloc_hash("cmac(aes)", 0, CRYPTO_ALG_ASYNC); 35520a2b0f04SJohan Hedberg if (IS_ERR(tfm_cmac)) { 35530a2b0f04SJohan Hedberg BT_ERR("Unable to create CMAC crypto context"); 35540a2b0f04SJohan Hedberg crypto_free_blkcipher(tfm_aes); 35550a2b0f04SJohan Hedberg return PTR_ERR(tfm_cmac); 35560a2b0f04SJohan Hedberg } 35570a2b0f04SJohan Hedberg 35580a2b0f04SJohan Hedberg err = run_selftests(tfm_aes, tfm_cmac); 35590a2b0f04SJohan Hedberg 35600a2b0f04SJohan Hedberg crypto_free_hash(tfm_cmac); 35610a2b0f04SJohan Hedberg crypto_free_blkcipher(tfm_aes); 35620a2b0f04SJohan Hedberg 35630a2b0f04SJohan Hedberg return err; 35640a2b0f04SJohan Hedberg } 35650a2b0f04SJohan Hedberg 35660a2b0f04SJohan Hedberg #endif 3567