1eb492e01SAnderson Briglia /* 2eb492e01SAnderson Briglia BlueZ - Bluetooth protocol stack for Linux 3eb492e01SAnderson Briglia Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4eb492e01SAnderson Briglia 5eb492e01SAnderson Briglia This program is free software; you can redistribute it and/or modify 6eb492e01SAnderson Briglia it under the terms of the GNU General Public License version 2 as 7eb492e01SAnderson Briglia published by the Free Software Foundation; 8eb492e01SAnderson Briglia 9eb492e01SAnderson Briglia THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 10eb492e01SAnderson Briglia OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 11eb492e01SAnderson Briglia FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. 12eb492e01SAnderson Briglia IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY 13eb492e01SAnderson Briglia CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 14eb492e01SAnderson Briglia WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15eb492e01SAnderson Briglia ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16eb492e01SAnderson Briglia OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17eb492e01SAnderson Briglia 18eb492e01SAnderson Briglia ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 19eb492e01SAnderson Briglia COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 20eb492e01SAnderson Briglia SOFTWARE IS DISCLAIMED. 21eb492e01SAnderson Briglia */ 22eb492e01SAnderson Briglia 238c520a59SGustavo Padovan #include <linux/crypto.h> 248c520a59SGustavo Padovan #include <linux/scatterlist.h> 258c520a59SGustavo Padovan #include <crypto/b128ops.h> 268c520a59SGustavo Padovan 27eb492e01SAnderson Briglia #include <net/bluetooth/bluetooth.h> 28eb492e01SAnderson Briglia #include <net/bluetooth/hci_core.h> 29eb492e01SAnderson Briglia #include <net/bluetooth/l2cap.h> 302b64d153SBrian Gix #include <net/bluetooth/mgmt.h> 31ac4b7236SMarcel Holtmann 32ac4b7236SMarcel Holtmann #include "smp.h" 33d22ef0bcSAnderson Briglia 3417b02e62SMarcel Holtmann #define SMP_TIMEOUT msecs_to_jiffies(30000) 355d3de7dfSVinicius Costa Gomes 36065a13e2SJohan Hedberg #define AUTH_REQ_MASK 0x07 37065a13e2SJohan Hedberg 38533e35d4SJohan Hedberg enum { 39533e35d4SJohan Hedberg SMP_FLAG_TK_VALID, 40533e35d4SJohan Hedberg SMP_FLAG_CFM_PENDING, 41533e35d4SJohan Hedberg SMP_FLAG_MITM_AUTH, 42533e35d4SJohan Hedberg SMP_FLAG_COMPLETE, 43533e35d4SJohan Hedberg SMP_FLAG_INITIATOR, 44533e35d4SJohan Hedberg }; 454bc58f51SJohan Hedberg 464bc58f51SJohan Hedberg struct smp_chan { 474bc58f51SJohan Hedberg struct l2cap_conn *conn; 48b68fda68SJohan Hedberg struct delayed_work security_timer; 49b68fda68SJohan Hedberg 504bc58f51SJohan Hedberg u8 preq[7]; /* SMP Pairing Request */ 514bc58f51SJohan Hedberg u8 prsp[7]; /* SMP Pairing Response */ 524bc58f51SJohan Hedberg u8 prnd[16]; /* SMP Pairing Random (local) */ 534bc58f51SJohan Hedberg u8 rrnd[16]; /* SMP Pairing Random (remote) */ 544bc58f51SJohan Hedberg u8 pcnf[16]; /* SMP Pairing Confirm */ 554bc58f51SJohan Hedberg u8 tk[16]; /* SMP Temporary Key */ 564bc58f51SJohan Hedberg u8 enc_key_size; 574bc58f51SJohan Hedberg u8 remote_key_dist; 584bc58f51SJohan Hedberg bdaddr_t id_addr; 594bc58f51SJohan Hedberg u8 id_addr_type; 604bc58f51SJohan Hedberg u8 irk[16]; 614bc58f51SJohan Hedberg struct smp_csrk *csrk; 624bc58f51SJohan Hedberg struct smp_csrk *slave_csrk; 634bc58f51SJohan Hedberg struct smp_ltk *ltk; 644bc58f51SJohan Hedberg struct smp_ltk *slave_ltk; 654bc58f51SJohan Hedberg struct smp_irk *remote_irk; 664a74d658SJohan Hedberg unsigned long flags; 676a7bd103SJohan Hedberg 686a7bd103SJohan Hedberg struct crypto_blkcipher *tfm_aes; 694bc58f51SJohan Hedberg }; 704bc58f51SJohan Hedberg 718a2936f4SJohan Hedberg static inline void swap_buf(const u8 *src, u8 *dst, size_t len) 72d22ef0bcSAnderson Briglia { 738a2936f4SJohan Hedberg size_t i; 74d22ef0bcSAnderson Briglia 758a2936f4SJohan Hedberg for (i = 0; i < len; i++) 768a2936f4SJohan Hedberg dst[len - 1 - i] = src[i]; 77d22ef0bcSAnderson Briglia } 78d22ef0bcSAnderson Briglia 79d22ef0bcSAnderson Briglia static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r) 80d22ef0bcSAnderson Briglia { 81d22ef0bcSAnderson Briglia struct blkcipher_desc desc; 82d22ef0bcSAnderson Briglia struct scatterlist sg; 83943a732aSJohan Hedberg uint8_t tmp[16], data[16]; 84201a5929SJohan Hedberg int err; 85d22ef0bcSAnderson Briglia 86d22ef0bcSAnderson Briglia if (tfm == NULL) { 87d22ef0bcSAnderson Briglia BT_ERR("tfm %p", tfm); 88d22ef0bcSAnderson Briglia return -EINVAL; 89d22ef0bcSAnderson Briglia } 90d22ef0bcSAnderson Briglia 91d22ef0bcSAnderson Briglia desc.tfm = tfm; 92d22ef0bcSAnderson Briglia desc.flags = 0; 93d22ef0bcSAnderson Briglia 94943a732aSJohan Hedberg /* The most significant octet of key corresponds to k[0] */ 958a2936f4SJohan Hedberg swap_buf(k, tmp, 16); 96943a732aSJohan Hedberg 97943a732aSJohan Hedberg err = crypto_blkcipher_setkey(tfm, tmp, 16); 98d22ef0bcSAnderson Briglia if (err) { 99d22ef0bcSAnderson Briglia BT_ERR("cipher setkey failed: %d", err); 100d22ef0bcSAnderson Briglia return err; 101d22ef0bcSAnderson Briglia } 102d22ef0bcSAnderson Briglia 103943a732aSJohan Hedberg /* Most significant octet of plaintextData corresponds to data[0] */ 1048a2936f4SJohan Hedberg swap_buf(r, data, 16); 105943a732aSJohan Hedberg 106943a732aSJohan Hedberg sg_init_one(&sg, data, 16); 107d22ef0bcSAnderson Briglia 108d22ef0bcSAnderson Briglia err = crypto_blkcipher_encrypt(&desc, &sg, &sg, 16); 109d22ef0bcSAnderson Briglia if (err) 110d22ef0bcSAnderson Briglia BT_ERR("Encrypt data error %d", err); 111d22ef0bcSAnderson Briglia 112943a732aSJohan Hedberg /* Most significant octet of encryptedData corresponds to data[0] */ 1138a2936f4SJohan Hedberg swap_buf(data, r, 16); 114943a732aSJohan Hedberg 115d22ef0bcSAnderson Briglia return err; 116d22ef0bcSAnderson Briglia } 117d22ef0bcSAnderson Briglia 11860478054SJohan Hedberg static int smp_ah(struct crypto_blkcipher *tfm, u8 irk[16], u8 r[3], u8 res[3]) 11960478054SJohan Hedberg { 120943a732aSJohan Hedberg u8 _res[16]; 12160478054SJohan Hedberg int err; 12260478054SJohan Hedberg 12360478054SJohan Hedberg /* r' = padding || r */ 124943a732aSJohan Hedberg memcpy(_res, r, 3); 125943a732aSJohan Hedberg memset(_res + 3, 0, 13); 12660478054SJohan Hedberg 127943a732aSJohan Hedberg err = smp_e(tfm, irk, _res); 12860478054SJohan Hedberg if (err) { 12960478054SJohan Hedberg BT_ERR("Encrypt error"); 13060478054SJohan Hedberg return err; 13160478054SJohan Hedberg } 13260478054SJohan Hedberg 13360478054SJohan Hedberg /* The output of the random address function ah is: 13460478054SJohan Hedberg * ah(h, r) = e(k, r') mod 2^24 13560478054SJohan Hedberg * The output of the security function e is then truncated to 24 bits 13660478054SJohan Hedberg * by taking the least significant 24 bits of the output of e as the 13760478054SJohan Hedberg * result of ah. 13860478054SJohan Hedberg */ 139943a732aSJohan Hedberg memcpy(res, _res, 3); 14060478054SJohan Hedberg 14160478054SJohan Hedberg return 0; 14260478054SJohan Hedberg } 14360478054SJohan Hedberg 144defce9e8SJohan Hedberg bool smp_irk_matches(struct hci_dev *hdev, u8 irk[16], bdaddr_t *bdaddr) 14560478054SJohan Hedberg { 146defce9e8SJohan Hedberg struct l2cap_chan *chan = hdev->smp_data; 147defce9e8SJohan Hedberg struct crypto_blkcipher *tfm; 14860478054SJohan Hedberg u8 hash[3]; 14960478054SJohan Hedberg int err; 15060478054SJohan Hedberg 151defce9e8SJohan Hedberg if (!chan || !chan->data) 152defce9e8SJohan Hedberg return false; 153defce9e8SJohan Hedberg 154defce9e8SJohan Hedberg tfm = chan->data; 155defce9e8SJohan Hedberg 15660478054SJohan Hedberg BT_DBG("RPA %pMR IRK %*phN", bdaddr, 16, irk); 15760478054SJohan Hedberg 15860478054SJohan Hedberg err = smp_ah(tfm, irk, &bdaddr->b[3], hash); 15960478054SJohan Hedberg if (err) 16060478054SJohan Hedberg return false; 16160478054SJohan Hedberg 16260478054SJohan Hedberg return !memcmp(bdaddr->b, hash, 3); 16360478054SJohan Hedberg } 16460478054SJohan Hedberg 165defce9e8SJohan Hedberg int smp_generate_rpa(struct hci_dev *hdev, u8 irk[16], bdaddr_t *rpa) 166b1e2b3aeSJohan Hedberg { 167defce9e8SJohan Hedberg struct l2cap_chan *chan = hdev->smp_data; 168defce9e8SJohan Hedberg struct crypto_blkcipher *tfm; 169b1e2b3aeSJohan Hedberg int err; 170b1e2b3aeSJohan Hedberg 171defce9e8SJohan Hedberg if (!chan || !chan->data) 172defce9e8SJohan Hedberg return -EOPNOTSUPP; 173defce9e8SJohan Hedberg 174defce9e8SJohan Hedberg tfm = chan->data; 175defce9e8SJohan Hedberg 176b1e2b3aeSJohan Hedberg get_random_bytes(&rpa->b[3], 3); 177b1e2b3aeSJohan Hedberg 178b1e2b3aeSJohan Hedberg rpa->b[5] &= 0x3f; /* Clear two most significant bits */ 179b1e2b3aeSJohan Hedberg rpa->b[5] |= 0x40; /* Set second most significant bit */ 180b1e2b3aeSJohan Hedberg 181b1e2b3aeSJohan Hedberg err = smp_ah(tfm, irk, &rpa->b[3], rpa->b); 182b1e2b3aeSJohan Hedberg if (err < 0) 183b1e2b3aeSJohan Hedberg return err; 184b1e2b3aeSJohan Hedberg 185b1e2b3aeSJohan Hedberg BT_DBG("RPA %pMR", rpa); 186b1e2b3aeSJohan Hedberg 187b1e2b3aeSJohan Hedberg return 0; 188b1e2b3aeSJohan Hedberg } 189b1e2b3aeSJohan Hedberg 190ec70f36fSJohan Hedberg static int smp_c1(struct smp_chan *smp, u8 k[16], u8 r[16], u8 preq[7], 191ec70f36fSJohan Hedberg u8 pres[7], u8 _iat, bdaddr_t *ia, u8 _rat, bdaddr_t *ra, 192ec70f36fSJohan Hedberg u8 res[16]) 193d22ef0bcSAnderson Briglia { 194ec70f36fSJohan Hedberg struct hci_dev *hdev = smp->conn->hcon->hdev; 195d22ef0bcSAnderson Briglia u8 p1[16], p2[16]; 196d22ef0bcSAnderson Briglia int err; 197d22ef0bcSAnderson Briglia 198ec70f36fSJohan Hedberg BT_DBG("%s", hdev->name); 199ec70f36fSJohan Hedberg 200d22ef0bcSAnderson Briglia memset(p1, 0, 16); 201d22ef0bcSAnderson Briglia 202d22ef0bcSAnderson Briglia /* p1 = pres || preq || _rat || _iat */ 203943a732aSJohan Hedberg p1[0] = _iat; 204943a732aSJohan Hedberg p1[1] = _rat; 205943a732aSJohan Hedberg memcpy(p1 + 2, preq, 7); 206943a732aSJohan Hedberg memcpy(p1 + 9, pres, 7); 207d22ef0bcSAnderson Briglia 208d22ef0bcSAnderson Briglia /* p2 = padding || ia || ra */ 209943a732aSJohan Hedberg memcpy(p2, ra, 6); 210943a732aSJohan Hedberg memcpy(p2 + 6, ia, 6); 211943a732aSJohan Hedberg memset(p2 + 12, 0, 4); 212d22ef0bcSAnderson Briglia 213d22ef0bcSAnderson Briglia /* res = r XOR p1 */ 214d22ef0bcSAnderson Briglia u128_xor((u128 *) res, (u128 *) r, (u128 *) p1); 215d22ef0bcSAnderson Briglia 216d22ef0bcSAnderson Briglia /* res = e(k, res) */ 217ec70f36fSJohan Hedberg err = smp_e(smp->tfm_aes, k, res); 218d22ef0bcSAnderson Briglia if (err) { 219d22ef0bcSAnderson Briglia BT_ERR("Encrypt data error"); 220d22ef0bcSAnderson Briglia return err; 221d22ef0bcSAnderson Briglia } 222d22ef0bcSAnderson Briglia 223d22ef0bcSAnderson Briglia /* res = res XOR p2 */ 224d22ef0bcSAnderson Briglia u128_xor((u128 *) res, (u128 *) res, (u128 *) p2); 225d22ef0bcSAnderson Briglia 226d22ef0bcSAnderson Briglia /* res = e(k, res) */ 227ec70f36fSJohan Hedberg err = smp_e(smp->tfm_aes, k, res); 228d22ef0bcSAnderson Briglia if (err) 229d22ef0bcSAnderson Briglia BT_ERR("Encrypt data error"); 230d22ef0bcSAnderson Briglia 231d22ef0bcSAnderson Briglia return err; 232d22ef0bcSAnderson Briglia } 233d22ef0bcSAnderson Briglia 234ec70f36fSJohan Hedberg static int smp_s1(struct smp_chan *smp, u8 k[16], u8 r1[16], u8 r2[16], 235ec70f36fSJohan Hedberg u8 _r[16]) 236d22ef0bcSAnderson Briglia { 237ec70f36fSJohan Hedberg struct hci_dev *hdev = smp->conn->hcon->hdev; 238d22ef0bcSAnderson Briglia int err; 239d22ef0bcSAnderson Briglia 240ec70f36fSJohan Hedberg BT_DBG("%s", hdev->name); 241ec70f36fSJohan Hedberg 242d22ef0bcSAnderson Briglia /* Just least significant octets from r1 and r2 are considered */ 243943a732aSJohan Hedberg memcpy(_r, r2, 8); 244943a732aSJohan Hedberg memcpy(_r + 8, r1, 8); 245d22ef0bcSAnderson Briglia 246ec70f36fSJohan Hedberg err = smp_e(smp->tfm_aes, k, _r); 247d22ef0bcSAnderson Briglia if (err) 248d22ef0bcSAnderson Briglia BT_ERR("Encrypt data error"); 249d22ef0bcSAnderson Briglia 250d22ef0bcSAnderson Briglia return err; 251d22ef0bcSAnderson Briglia } 252d22ef0bcSAnderson Briglia 253eb492e01SAnderson Briglia static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data) 254eb492e01SAnderson Briglia { 2555d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 256b68fda68SJohan Hedberg struct smp_chan *smp; 2575d88cc73SJohan Hedberg struct kvec iv[2]; 2585d88cc73SJohan Hedberg struct msghdr msg; 2595d88cc73SJohan Hedberg 2605d88cc73SJohan Hedberg if (!chan) 2615d88cc73SJohan Hedberg return; 262eb492e01SAnderson Briglia 263eb492e01SAnderson Briglia BT_DBG("code 0x%2.2x", code); 264eb492e01SAnderson Briglia 2655d88cc73SJohan Hedberg iv[0].iov_base = &code; 2665d88cc73SJohan Hedberg iv[0].iov_len = 1; 267eb492e01SAnderson Briglia 2685d88cc73SJohan Hedberg iv[1].iov_base = data; 2695d88cc73SJohan Hedberg iv[1].iov_len = len; 2705d88cc73SJohan Hedberg 2715d88cc73SJohan Hedberg memset(&msg, 0, sizeof(msg)); 2725d88cc73SJohan Hedberg 2735d88cc73SJohan Hedberg msg.msg_iov = (struct iovec *) &iv; 2745d88cc73SJohan Hedberg msg.msg_iovlen = 2; 2755d88cc73SJohan Hedberg 2765d88cc73SJohan Hedberg l2cap_chan_send(chan, &msg, 1 + len); 277e2dcd113SVinicius Costa Gomes 278b68fda68SJohan Hedberg if (!chan->data) 279b68fda68SJohan Hedberg return; 280b68fda68SJohan Hedberg 281b68fda68SJohan Hedberg smp = chan->data; 282b68fda68SJohan Hedberg 283b68fda68SJohan Hedberg cancel_delayed_work_sync(&smp->security_timer); 284b68fda68SJohan Hedberg if (test_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) 285b68fda68SJohan Hedberg schedule_delayed_work(&smp->security_timer, SMP_TIMEOUT); 286eb492e01SAnderson Briglia } 287eb492e01SAnderson Briglia 2882b64d153SBrian Gix static __u8 authreq_to_seclevel(__u8 authreq) 2892b64d153SBrian Gix { 2902b64d153SBrian Gix if (authreq & SMP_AUTH_MITM) 2912b64d153SBrian Gix return BT_SECURITY_HIGH; 2922b64d153SBrian Gix else 2932b64d153SBrian Gix return BT_SECURITY_MEDIUM; 2942b64d153SBrian Gix } 2952b64d153SBrian Gix 2962b64d153SBrian Gix static __u8 seclevel_to_authreq(__u8 sec_level) 2972b64d153SBrian Gix { 2982b64d153SBrian Gix switch (sec_level) { 2992b64d153SBrian Gix case BT_SECURITY_HIGH: 3002b64d153SBrian Gix return SMP_AUTH_MITM | SMP_AUTH_BONDING; 3012b64d153SBrian Gix case BT_SECURITY_MEDIUM: 3022b64d153SBrian Gix return SMP_AUTH_BONDING; 3032b64d153SBrian Gix default: 3042b64d153SBrian Gix return SMP_AUTH_NONE; 3052b64d153SBrian Gix } 3062b64d153SBrian Gix } 3072b64d153SBrian Gix 308b8e66eacSVinicius Costa Gomes static void build_pairing_cmd(struct l2cap_conn *conn, 30954790f73SVinicius Costa Gomes struct smp_cmd_pairing *req, 310f1560463SMarcel Holtmann struct smp_cmd_pairing *rsp, __u8 authreq) 311b8e66eacSVinicius Costa Gomes { 3125d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 3135d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 314fd349c02SJohan Hedberg struct hci_conn *hcon = conn->hcon; 315fd349c02SJohan Hedberg struct hci_dev *hdev = hcon->hdev; 316fd349c02SJohan Hedberg u8 local_dist = 0, remote_dist = 0; 31754790f73SVinicius Costa Gomes 318b6ae8457SJohan Hedberg if (test_bit(HCI_BONDABLE, &conn->hcon->hdev->dev_flags)) { 3197ee4ea36SMarcel Holtmann local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN; 3207ee4ea36SMarcel Holtmann remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN; 32154790f73SVinicius Costa Gomes authreq |= SMP_AUTH_BONDING; 3222b64d153SBrian Gix } else { 3232b64d153SBrian Gix authreq &= ~SMP_AUTH_BONDING; 32454790f73SVinicius Costa Gomes } 32554790f73SVinicius Costa Gomes 326fd349c02SJohan Hedberg if (test_bit(HCI_RPA_RESOLVING, &hdev->dev_flags)) 327fd349c02SJohan Hedberg remote_dist |= SMP_DIST_ID_KEY; 328fd349c02SJohan Hedberg 329863efaf2SJohan Hedberg if (test_bit(HCI_PRIVACY, &hdev->dev_flags)) 330863efaf2SJohan Hedberg local_dist |= SMP_DIST_ID_KEY; 331863efaf2SJohan Hedberg 33254790f73SVinicius Costa Gomes if (rsp == NULL) { 33354790f73SVinicius Costa Gomes req->io_capability = conn->hcon->io_capability; 33454790f73SVinicius Costa Gomes req->oob_flag = SMP_OOB_NOT_PRESENT; 33554790f73SVinicius Costa Gomes req->max_key_size = SMP_MAX_ENC_KEY_SIZE; 336fd349c02SJohan Hedberg req->init_key_dist = local_dist; 337fd349c02SJohan Hedberg req->resp_key_dist = remote_dist; 338065a13e2SJohan Hedberg req->auth_req = (authreq & AUTH_REQ_MASK); 339fd349c02SJohan Hedberg 340fd349c02SJohan Hedberg smp->remote_key_dist = remote_dist; 34154790f73SVinicius Costa Gomes return; 34254790f73SVinicius Costa Gomes } 34354790f73SVinicius Costa Gomes 34454790f73SVinicius Costa Gomes rsp->io_capability = conn->hcon->io_capability; 34554790f73SVinicius Costa Gomes rsp->oob_flag = SMP_OOB_NOT_PRESENT; 34654790f73SVinicius Costa Gomes rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE; 347fd349c02SJohan Hedberg rsp->init_key_dist = req->init_key_dist & remote_dist; 348fd349c02SJohan Hedberg rsp->resp_key_dist = req->resp_key_dist & local_dist; 349065a13e2SJohan Hedberg rsp->auth_req = (authreq & AUTH_REQ_MASK); 350fd349c02SJohan Hedberg 351fd349c02SJohan Hedberg smp->remote_key_dist = rsp->init_key_dist; 352b8e66eacSVinicius Costa Gomes } 353b8e66eacSVinicius Costa Gomes 3543158c50cSVinicius Costa Gomes static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size) 3553158c50cSVinicius Costa Gomes { 3565d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 3575d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 3581c1def09SVinicius Costa Gomes 3593158c50cSVinicius Costa Gomes if ((max_key_size > SMP_MAX_ENC_KEY_SIZE) || 3603158c50cSVinicius Costa Gomes (max_key_size < SMP_MIN_ENC_KEY_SIZE)) 3613158c50cSVinicius Costa Gomes return SMP_ENC_KEY_SIZE; 3623158c50cSVinicius Costa Gomes 363f7aa611aSVinicius Costa Gomes smp->enc_key_size = max_key_size; 3643158c50cSVinicius Costa Gomes 3653158c50cSVinicius Costa Gomes return 0; 3663158c50cSVinicius Costa Gomes } 3673158c50cSVinicius Costa Gomes 36884794e11SJohan Hedberg static void smp_failure(struct l2cap_conn *conn, u8 reason) 3694f957a76SBrian Gix { 370bab73cb6SJohan Hedberg struct hci_conn *hcon = conn->hcon; 371b68fda68SJohan Hedberg struct l2cap_chan *chan = conn->smp; 372b68fda68SJohan Hedberg struct smp_chan *smp; 373bab73cb6SJohan Hedberg 37484794e11SJohan Hedberg if (reason) 3754f957a76SBrian Gix smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason), 3764f957a76SBrian Gix &reason); 3774f957a76SBrian Gix 378ce39fb4eSMarcel Holtmann clear_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags); 379ce39fb4eSMarcel Holtmann mgmt_auth_failed(hcon->hdev, &hcon->dst, hcon->type, hcon->dst_type, 380ce39fb4eSMarcel Holtmann HCI_ERROR_AUTH_FAILURE); 381f1c09c07SVinicius Costa Gomes 382b68fda68SJohan Hedberg if (!chan->data) 383b68fda68SJohan Hedberg return; 384b68fda68SJohan Hedberg 385b68fda68SJohan Hedberg smp = chan->data; 386b68fda68SJohan Hedberg 387b68fda68SJohan Hedberg cancel_delayed_work_sync(&smp->security_timer); 38861a0cfb0SAndre Guedes 389ce39fb4eSMarcel Holtmann if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) 3904f957a76SBrian Gix smp_chan_destroy(conn); 3914f957a76SBrian Gix } 3924f957a76SBrian Gix 3932b64d153SBrian Gix #define JUST_WORKS 0x00 3942b64d153SBrian Gix #define JUST_CFM 0x01 3952b64d153SBrian Gix #define REQ_PASSKEY 0x02 3962b64d153SBrian Gix #define CFM_PASSKEY 0x03 3972b64d153SBrian Gix #define REQ_OOB 0x04 3982b64d153SBrian Gix #define OVERLAP 0xFF 3992b64d153SBrian Gix 4002b64d153SBrian Gix static const u8 gen_method[5][5] = { 4012b64d153SBrian Gix { JUST_WORKS, JUST_CFM, REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY }, 4022b64d153SBrian Gix { JUST_WORKS, JUST_CFM, REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY }, 4032b64d153SBrian Gix { CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY }, 4042b64d153SBrian Gix { JUST_WORKS, JUST_CFM, JUST_WORKS, JUST_WORKS, JUST_CFM }, 4052b64d153SBrian Gix { CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, OVERLAP }, 4062b64d153SBrian Gix }; 4072b64d153SBrian Gix 408581370ccSJohan Hedberg static u8 get_auth_method(struct smp_chan *smp, u8 local_io, u8 remote_io) 409581370ccSJohan Hedberg { 4102bcd4003SJohan Hedberg /* If either side has unknown io_caps, use JUST_CFM (which gets 4112bcd4003SJohan Hedberg * converted later to JUST_WORKS if we're initiators. 4122bcd4003SJohan Hedberg */ 413581370ccSJohan Hedberg if (local_io > SMP_IO_KEYBOARD_DISPLAY || 414581370ccSJohan Hedberg remote_io > SMP_IO_KEYBOARD_DISPLAY) 4152bcd4003SJohan Hedberg return JUST_CFM; 416581370ccSJohan Hedberg 417581370ccSJohan Hedberg return gen_method[remote_io][local_io]; 418581370ccSJohan Hedberg } 419581370ccSJohan Hedberg 4202b64d153SBrian Gix static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth, 4212b64d153SBrian Gix u8 local_io, u8 remote_io) 4222b64d153SBrian Gix { 4232b64d153SBrian Gix struct hci_conn *hcon = conn->hcon; 4245d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 4255d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 4262b64d153SBrian Gix u8 method; 4272b64d153SBrian Gix u32 passkey = 0; 4282b64d153SBrian Gix int ret = 0; 4292b64d153SBrian Gix 4302b64d153SBrian Gix /* Initialize key for JUST WORKS */ 4312b64d153SBrian Gix memset(smp->tk, 0, sizeof(smp->tk)); 4324a74d658SJohan Hedberg clear_bit(SMP_FLAG_TK_VALID, &smp->flags); 4332b64d153SBrian Gix 4342b64d153SBrian Gix BT_DBG("tk_request: auth:%d lcl:%d rem:%d", auth, local_io, remote_io); 4352b64d153SBrian Gix 4362bcd4003SJohan Hedberg /* If neither side wants MITM, either "just" confirm an incoming 4372bcd4003SJohan Hedberg * request or use just-works for outgoing ones. The JUST_CFM 4382bcd4003SJohan Hedberg * will be converted to JUST_WORKS if necessary later in this 4392bcd4003SJohan Hedberg * function. If either side has MITM look up the method from the 4402bcd4003SJohan Hedberg * table. 4412bcd4003SJohan Hedberg */ 442581370ccSJohan Hedberg if (!(auth & SMP_AUTH_MITM)) 4432bcd4003SJohan Hedberg method = JUST_CFM; 4442b64d153SBrian Gix else 445581370ccSJohan Hedberg method = get_auth_method(smp, local_io, remote_io); 4462b64d153SBrian Gix 447a82505c7SJohan Hedberg /* Don't confirm locally initiated pairing attempts */ 4484a74d658SJohan Hedberg if (method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR, &smp->flags)) 449a82505c7SJohan Hedberg method = JUST_WORKS; 450a82505c7SJohan Hedberg 45102f3e254SJohan Hedberg /* Don't bother user space with no IO capabilities */ 45202f3e254SJohan Hedberg if (method == JUST_CFM && hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT) 45302f3e254SJohan Hedberg method = JUST_WORKS; 45402f3e254SJohan Hedberg 4552b64d153SBrian Gix /* If Just Works, Continue with Zero TK */ 4562b64d153SBrian Gix if (method == JUST_WORKS) { 4574a74d658SJohan Hedberg set_bit(SMP_FLAG_TK_VALID, &smp->flags); 4582b64d153SBrian Gix return 0; 4592b64d153SBrian Gix } 4602b64d153SBrian Gix 4612b64d153SBrian Gix /* Not Just Works/Confirm results in MITM Authentication */ 4622b64d153SBrian Gix if (method != JUST_CFM) 4634a74d658SJohan Hedberg set_bit(SMP_FLAG_MITM_AUTH, &smp->flags); 4642b64d153SBrian Gix 4652b64d153SBrian Gix /* If both devices have Keyoard-Display I/O, the master 4662b64d153SBrian Gix * Confirms and the slave Enters the passkey. 4672b64d153SBrian Gix */ 4682b64d153SBrian Gix if (method == OVERLAP) { 46940bef302SJohan Hedberg if (hcon->role == HCI_ROLE_MASTER) 4702b64d153SBrian Gix method = CFM_PASSKEY; 4712b64d153SBrian Gix else 4722b64d153SBrian Gix method = REQ_PASSKEY; 4732b64d153SBrian Gix } 4742b64d153SBrian Gix 47501ad34d2SJohan Hedberg /* Generate random passkey. */ 4762b64d153SBrian Gix if (method == CFM_PASSKEY) { 477943a732aSJohan Hedberg memset(smp->tk, 0, sizeof(smp->tk)); 4782b64d153SBrian Gix get_random_bytes(&passkey, sizeof(passkey)); 4792b64d153SBrian Gix passkey %= 1000000; 480943a732aSJohan Hedberg put_unaligned_le32(passkey, smp->tk); 4812b64d153SBrian Gix BT_DBG("PassKey: %d", passkey); 4824a74d658SJohan Hedberg set_bit(SMP_FLAG_TK_VALID, &smp->flags); 4832b64d153SBrian Gix } 4842b64d153SBrian Gix 4852b64d153SBrian Gix hci_dev_lock(hcon->hdev); 4862b64d153SBrian Gix 4872b64d153SBrian Gix if (method == REQ_PASSKEY) 488ce39fb4eSMarcel Holtmann ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst, 489272d90dfSJohan Hedberg hcon->type, hcon->dst_type); 4904eb65e66SJohan Hedberg else if (method == JUST_CFM) 4914eb65e66SJohan Hedberg ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst, 4924eb65e66SJohan Hedberg hcon->type, hcon->dst_type, 4934eb65e66SJohan Hedberg passkey, 1); 4942b64d153SBrian Gix else 49501ad34d2SJohan Hedberg ret = mgmt_user_passkey_notify(hcon->hdev, &hcon->dst, 496272d90dfSJohan Hedberg hcon->type, hcon->dst_type, 49739adbffeSJohan Hedberg passkey, 0); 4982b64d153SBrian Gix 4992b64d153SBrian Gix hci_dev_unlock(hcon->hdev); 5002b64d153SBrian Gix 5012b64d153SBrian Gix return ret; 5022b64d153SBrian Gix } 5032b64d153SBrian Gix 5041cc61144SJohan Hedberg static u8 smp_confirm(struct smp_chan *smp) 5058aab4757SVinicius Costa Gomes { 5068aab4757SVinicius Costa Gomes struct l2cap_conn *conn = smp->conn; 5078aab4757SVinicius Costa Gomes struct smp_cmd_pairing_confirm cp; 5088aab4757SVinicius Costa Gomes int ret; 5098aab4757SVinicius Costa Gomes 5108aab4757SVinicius Costa Gomes BT_DBG("conn %p", conn); 5118aab4757SVinicius Costa Gomes 512ec70f36fSJohan Hedberg ret = smp_c1(smp, smp->tk, smp->prnd, smp->preq, smp->prsp, 513b1cd5fd9SJohan Hedberg conn->hcon->init_addr_type, &conn->hcon->init_addr, 514943a732aSJohan Hedberg conn->hcon->resp_addr_type, &conn->hcon->resp_addr, 515943a732aSJohan Hedberg cp.confirm_val); 5161cc61144SJohan Hedberg if (ret) 5171cc61144SJohan Hedberg return SMP_UNSPECIFIED; 5188aab4757SVinicius Costa Gomes 5194a74d658SJohan Hedberg clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags); 5202b64d153SBrian Gix 5218aab4757SVinicius Costa Gomes smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp); 5228aab4757SVinicius Costa Gomes 5231cc61144SJohan Hedberg return 0; 5248aab4757SVinicius Costa Gomes } 5258aab4757SVinicius Costa Gomes 526861580a9SJohan Hedberg static u8 smp_random(struct smp_chan *smp) 5278aab4757SVinicius Costa Gomes { 5288aab4757SVinicius Costa Gomes struct l2cap_conn *conn = smp->conn; 5298aab4757SVinicius Costa Gomes struct hci_conn *hcon = conn->hcon; 530861580a9SJohan Hedberg u8 confirm[16]; 5318aab4757SVinicius Costa Gomes int ret; 5328aab4757SVinicius Costa Gomes 533ec70f36fSJohan Hedberg if (IS_ERR_OR_NULL(smp->tfm_aes)) 534861580a9SJohan Hedberg return SMP_UNSPECIFIED; 5358aab4757SVinicius Costa Gomes 5368aab4757SVinicius Costa Gomes BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave"); 5378aab4757SVinicius Costa Gomes 538ec70f36fSJohan Hedberg ret = smp_c1(smp, smp->tk, smp->rrnd, smp->preq, smp->prsp, 539b1cd5fd9SJohan Hedberg hcon->init_addr_type, &hcon->init_addr, 540943a732aSJohan Hedberg hcon->resp_addr_type, &hcon->resp_addr, confirm); 541861580a9SJohan Hedberg if (ret) 542861580a9SJohan Hedberg return SMP_UNSPECIFIED; 5438aab4757SVinicius Costa Gomes 5448aab4757SVinicius Costa Gomes if (memcmp(smp->pcnf, confirm, sizeof(smp->pcnf)) != 0) { 5458aab4757SVinicius Costa Gomes BT_ERR("Pairing failed (confirmation values mismatch)"); 546861580a9SJohan Hedberg return SMP_CONFIRM_FAILED; 5478aab4757SVinicius Costa Gomes } 5488aab4757SVinicius Costa Gomes 5498aab4757SVinicius Costa Gomes if (hcon->out) { 550fe39c7b2SMarcel Holtmann u8 stk[16]; 551fe39c7b2SMarcel Holtmann __le64 rand = 0; 552fe39c7b2SMarcel Holtmann __le16 ediv = 0; 5538aab4757SVinicius Costa Gomes 554ec70f36fSJohan Hedberg smp_s1(smp, smp->tk, smp->rrnd, smp->prnd, stk); 5558aab4757SVinicius Costa Gomes 556f7aa611aSVinicius Costa Gomes memset(stk + smp->enc_key_size, 0, 557f7aa611aSVinicius Costa Gomes SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size); 5588aab4757SVinicius Costa Gomes 559861580a9SJohan Hedberg if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags)) 560861580a9SJohan Hedberg return SMP_UNSPECIFIED; 5618aab4757SVinicius Costa Gomes 5628aab4757SVinicius Costa Gomes hci_le_start_enc(hcon, ediv, rand, stk); 563f7aa611aSVinicius Costa Gomes hcon->enc_key_size = smp->enc_key_size; 564fe59a05fSJohan Hedberg set_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags); 5658aab4757SVinicius Costa Gomes } else { 566fff3490fSJohan Hedberg u8 stk[16], auth; 567fe39c7b2SMarcel Holtmann __le64 rand = 0; 568fe39c7b2SMarcel Holtmann __le16 ediv = 0; 5698aab4757SVinicius Costa Gomes 570943a732aSJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd), 571943a732aSJohan Hedberg smp->prnd); 5728aab4757SVinicius Costa Gomes 573ec70f36fSJohan Hedberg smp_s1(smp, smp->tk, smp->prnd, smp->rrnd, stk); 5748aab4757SVinicius Costa Gomes 575f7aa611aSVinicius Costa Gomes memset(stk + smp->enc_key_size, 0, 576f7aa611aSVinicius Costa Gomes SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size); 5778aab4757SVinicius Costa Gomes 578fff3490fSJohan Hedberg if (hcon->pending_sec_level == BT_SECURITY_HIGH) 579fff3490fSJohan Hedberg auth = 1; 580fff3490fSJohan Hedberg else 581fff3490fSJohan Hedberg auth = 0; 582fff3490fSJohan Hedberg 5837d5843b7SJohan Hedberg /* Even though there's no _SLAVE suffix this is the 5847d5843b7SJohan Hedberg * slave STK we're adding for later lookup (the master 5857d5843b7SJohan Hedberg * STK never needs to be stored). 5867d5843b7SJohan Hedberg */ 587ce39fb4eSMarcel Holtmann hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, 5882ceba539SJohan Hedberg SMP_STK, auth, stk, smp->enc_key_size, ediv, rand); 5898aab4757SVinicius Costa Gomes } 5908aab4757SVinicius Costa Gomes 591861580a9SJohan Hedberg return 0; 5928aab4757SVinicius Costa Gomes } 5938aab4757SVinicius Costa Gomes 59444f1a7abSJohan Hedberg static void smp_notify_keys(struct l2cap_conn *conn) 59544f1a7abSJohan Hedberg { 59644f1a7abSJohan Hedberg struct l2cap_chan *chan = conn->smp; 59744f1a7abSJohan Hedberg struct smp_chan *smp = chan->data; 59844f1a7abSJohan Hedberg struct hci_conn *hcon = conn->hcon; 59944f1a7abSJohan Hedberg struct hci_dev *hdev = hcon->hdev; 60044f1a7abSJohan Hedberg struct smp_cmd_pairing *req = (void *) &smp->preq[1]; 60144f1a7abSJohan Hedberg struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1]; 60244f1a7abSJohan Hedberg bool persistent; 60344f1a7abSJohan Hedberg 60444f1a7abSJohan Hedberg if (smp->remote_irk) { 60544f1a7abSJohan Hedberg mgmt_new_irk(hdev, smp->remote_irk); 60644f1a7abSJohan Hedberg /* Now that user space can be considered to know the 60744f1a7abSJohan Hedberg * identity address track the connection based on it 60844f1a7abSJohan Hedberg * from now on. 60944f1a7abSJohan Hedberg */ 61044f1a7abSJohan Hedberg bacpy(&hcon->dst, &smp->remote_irk->bdaddr); 61144f1a7abSJohan Hedberg hcon->dst_type = smp->remote_irk->addr_type; 61244f1a7abSJohan Hedberg l2cap_conn_update_id_addr(hcon); 61344f1a7abSJohan Hedberg 61444f1a7abSJohan Hedberg /* When receiving an indentity resolving key for 61544f1a7abSJohan Hedberg * a remote device that does not use a resolvable 61644f1a7abSJohan Hedberg * private address, just remove the key so that 61744f1a7abSJohan Hedberg * it is possible to use the controller white 61844f1a7abSJohan Hedberg * list for scanning. 61944f1a7abSJohan Hedberg * 62044f1a7abSJohan Hedberg * Userspace will have been told to not store 62144f1a7abSJohan Hedberg * this key at this point. So it is safe to 62244f1a7abSJohan Hedberg * just remove it. 62344f1a7abSJohan Hedberg */ 62444f1a7abSJohan Hedberg if (!bacmp(&smp->remote_irk->rpa, BDADDR_ANY)) { 62544f1a7abSJohan Hedberg list_del(&smp->remote_irk->list); 62644f1a7abSJohan Hedberg kfree(smp->remote_irk); 62744f1a7abSJohan Hedberg smp->remote_irk = NULL; 62844f1a7abSJohan Hedberg } 62944f1a7abSJohan Hedberg } 63044f1a7abSJohan Hedberg 63144f1a7abSJohan Hedberg /* The LTKs and CSRKs should be persistent only if both sides 63244f1a7abSJohan Hedberg * had the bonding bit set in their authentication requests. 63344f1a7abSJohan Hedberg */ 63444f1a7abSJohan Hedberg persistent = !!((req->auth_req & rsp->auth_req) & SMP_AUTH_BONDING); 63544f1a7abSJohan Hedberg 63644f1a7abSJohan Hedberg if (smp->csrk) { 63744f1a7abSJohan Hedberg smp->csrk->bdaddr_type = hcon->dst_type; 63844f1a7abSJohan Hedberg bacpy(&smp->csrk->bdaddr, &hcon->dst); 63944f1a7abSJohan Hedberg mgmt_new_csrk(hdev, smp->csrk, persistent); 64044f1a7abSJohan Hedberg } 64144f1a7abSJohan Hedberg 64244f1a7abSJohan Hedberg if (smp->slave_csrk) { 64344f1a7abSJohan Hedberg smp->slave_csrk->bdaddr_type = hcon->dst_type; 64444f1a7abSJohan Hedberg bacpy(&smp->slave_csrk->bdaddr, &hcon->dst); 64544f1a7abSJohan Hedberg mgmt_new_csrk(hdev, smp->slave_csrk, persistent); 64644f1a7abSJohan Hedberg } 64744f1a7abSJohan Hedberg 64844f1a7abSJohan Hedberg if (smp->ltk) { 64944f1a7abSJohan Hedberg smp->ltk->bdaddr_type = hcon->dst_type; 65044f1a7abSJohan Hedberg bacpy(&smp->ltk->bdaddr, &hcon->dst); 65144f1a7abSJohan Hedberg mgmt_new_ltk(hdev, smp->ltk, persistent); 65244f1a7abSJohan Hedberg } 65344f1a7abSJohan Hedberg 65444f1a7abSJohan Hedberg if (smp->slave_ltk) { 65544f1a7abSJohan Hedberg smp->slave_ltk->bdaddr_type = hcon->dst_type; 65644f1a7abSJohan Hedberg bacpy(&smp->slave_ltk->bdaddr, &hcon->dst); 65744f1a7abSJohan Hedberg mgmt_new_ltk(hdev, smp->slave_ltk, persistent); 65844f1a7abSJohan Hedberg } 65944f1a7abSJohan Hedberg } 66044f1a7abSJohan Hedberg 66144f1a7abSJohan Hedberg static int smp_distribute_keys(struct l2cap_conn *conn) 66244f1a7abSJohan Hedberg { 66344f1a7abSJohan Hedberg struct smp_cmd_pairing *req, *rsp; 66444f1a7abSJohan Hedberg struct l2cap_chan *chan = conn->smp; 66544f1a7abSJohan Hedberg struct smp_chan *smp = chan->data; 66644f1a7abSJohan Hedberg struct hci_conn *hcon = conn->hcon; 66744f1a7abSJohan Hedberg struct hci_dev *hdev = hcon->hdev; 66844f1a7abSJohan Hedberg __u8 *keydist; 66944f1a7abSJohan Hedberg 67044f1a7abSJohan Hedberg BT_DBG("conn %p", conn); 67144f1a7abSJohan Hedberg 67244f1a7abSJohan Hedberg if (!test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) 67344f1a7abSJohan Hedberg return 0; 67444f1a7abSJohan Hedberg 67544f1a7abSJohan Hedberg rsp = (void *) &smp->prsp[1]; 67644f1a7abSJohan Hedberg 67744f1a7abSJohan Hedberg /* The responder sends its keys first */ 67844f1a7abSJohan Hedberg if (hcon->out && (smp->remote_key_dist & 0x07)) 67944f1a7abSJohan Hedberg return 0; 68044f1a7abSJohan Hedberg 68144f1a7abSJohan Hedberg req = (void *) &smp->preq[1]; 68244f1a7abSJohan Hedberg 68344f1a7abSJohan Hedberg if (hcon->out) { 68444f1a7abSJohan Hedberg keydist = &rsp->init_key_dist; 68544f1a7abSJohan Hedberg *keydist &= req->init_key_dist; 68644f1a7abSJohan Hedberg } else { 68744f1a7abSJohan Hedberg keydist = &rsp->resp_key_dist; 68844f1a7abSJohan Hedberg *keydist &= req->resp_key_dist; 68944f1a7abSJohan Hedberg } 69044f1a7abSJohan Hedberg 69144f1a7abSJohan Hedberg BT_DBG("keydist 0x%x", *keydist); 69244f1a7abSJohan Hedberg 69344f1a7abSJohan Hedberg if (*keydist & SMP_DIST_ENC_KEY) { 69444f1a7abSJohan Hedberg struct smp_cmd_encrypt_info enc; 69544f1a7abSJohan Hedberg struct smp_cmd_master_ident ident; 69644f1a7abSJohan Hedberg struct smp_ltk *ltk; 69744f1a7abSJohan Hedberg u8 authenticated; 69844f1a7abSJohan Hedberg __le16 ediv; 69944f1a7abSJohan Hedberg __le64 rand; 70044f1a7abSJohan Hedberg 70144f1a7abSJohan Hedberg get_random_bytes(enc.ltk, sizeof(enc.ltk)); 70244f1a7abSJohan Hedberg get_random_bytes(&ediv, sizeof(ediv)); 70344f1a7abSJohan Hedberg get_random_bytes(&rand, sizeof(rand)); 70444f1a7abSJohan Hedberg 70544f1a7abSJohan Hedberg smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc); 70644f1a7abSJohan Hedberg 70744f1a7abSJohan Hedberg authenticated = hcon->sec_level == BT_SECURITY_HIGH; 70844f1a7abSJohan Hedberg ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, 70944f1a7abSJohan Hedberg SMP_LTK_SLAVE, authenticated, enc.ltk, 71044f1a7abSJohan Hedberg smp->enc_key_size, ediv, rand); 71144f1a7abSJohan Hedberg smp->slave_ltk = ltk; 71244f1a7abSJohan Hedberg 71344f1a7abSJohan Hedberg ident.ediv = ediv; 71444f1a7abSJohan Hedberg ident.rand = rand; 71544f1a7abSJohan Hedberg 71644f1a7abSJohan Hedberg smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident); 71744f1a7abSJohan Hedberg 71844f1a7abSJohan Hedberg *keydist &= ~SMP_DIST_ENC_KEY; 71944f1a7abSJohan Hedberg } 72044f1a7abSJohan Hedberg 72144f1a7abSJohan Hedberg if (*keydist & SMP_DIST_ID_KEY) { 72244f1a7abSJohan Hedberg struct smp_cmd_ident_addr_info addrinfo; 72344f1a7abSJohan Hedberg struct smp_cmd_ident_info idinfo; 72444f1a7abSJohan Hedberg 72544f1a7abSJohan Hedberg memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk)); 72644f1a7abSJohan Hedberg 72744f1a7abSJohan Hedberg smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo); 72844f1a7abSJohan Hedberg 72944f1a7abSJohan Hedberg /* The hci_conn contains the local identity address 73044f1a7abSJohan Hedberg * after the connection has been established. 73144f1a7abSJohan Hedberg * 73244f1a7abSJohan Hedberg * This is true even when the connection has been 73344f1a7abSJohan Hedberg * established using a resolvable random address. 73444f1a7abSJohan Hedberg */ 73544f1a7abSJohan Hedberg bacpy(&addrinfo.bdaddr, &hcon->src); 73644f1a7abSJohan Hedberg addrinfo.addr_type = hcon->src_type; 73744f1a7abSJohan Hedberg 73844f1a7abSJohan Hedberg smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo), 73944f1a7abSJohan Hedberg &addrinfo); 74044f1a7abSJohan Hedberg 74144f1a7abSJohan Hedberg *keydist &= ~SMP_DIST_ID_KEY; 74244f1a7abSJohan Hedberg } 74344f1a7abSJohan Hedberg 74444f1a7abSJohan Hedberg if (*keydist & SMP_DIST_SIGN) { 74544f1a7abSJohan Hedberg struct smp_cmd_sign_info sign; 74644f1a7abSJohan Hedberg struct smp_csrk *csrk; 74744f1a7abSJohan Hedberg 74844f1a7abSJohan Hedberg /* Generate a new random key */ 74944f1a7abSJohan Hedberg get_random_bytes(sign.csrk, sizeof(sign.csrk)); 75044f1a7abSJohan Hedberg 75144f1a7abSJohan Hedberg csrk = kzalloc(sizeof(*csrk), GFP_KERNEL); 75244f1a7abSJohan Hedberg if (csrk) { 75344f1a7abSJohan Hedberg csrk->master = 0x00; 75444f1a7abSJohan Hedberg memcpy(csrk->val, sign.csrk, sizeof(csrk->val)); 75544f1a7abSJohan Hedberg } 75644f1a7abSJohan Hedberg smp->slave_csrk = csrk; 75744f1a7abSJohan Hedberg 75844f1a7abSJohan Hedberg smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign); 75944f1a7abSJohan Hedberg 76044f1a7abSJohan Hedberg *keydist &= ~SMP_DIST_SIGN; 76144f1a7abSJohan Hedberg } 76244f1a7abSJohan Hedberg 76344f1a7abSJohan Hedberg /* If there are still keys to be received wait for them */ 76444f1a7abSJohan Hedberg if ((smp->remote_key_dist & 0x07)) 76544f1a7abSJohan Hedberg return 0; 76644f1a7abSJohan Hedberg 76744f1a7abSJohan Hedberg clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags); 768b68fda68SJohan Hedberg cancel_delayed_work_sync(&smp->security_timer); 76944f1a7abSJohan Hedberg set_bit(SMP_FLAG_COMPLETE, &smp->flags); 77044f1a7abSJohan Hedberg smp_notify_keys(conn); 77144f1a7abSJohan Hedberg 77244f1a7abSJohan Hedberg smp_chan_destroy(conn); 77344f1a7abSJohan Hedberg 77444f1a7abSJohan Hedberg return 0; 77544f1a7abSJohan Hedberg } 77644f1a7abSJohan Hedberg 777b68fda68SJohan Hedberg static void smp_timeout(struct work_struct *work) 778b68fda68SJohan Hedberg { 779b68fda68SJohan Hedberg struct smp_chan *smp = container_of(work, struct smp_chan, 780b68fda68SJohan Hedberg security_timer.work); 781b68fda68SJohan Hedberg struct l2cap_conn *conn = smp->conn; 782b68fda68SJohan Hedberg 783b68fda68SJohan Hedberg BT_DBG("conn %p", conn); 784b68fda68SJohan Hedberg 785b68fda68SJohan Hedberg l2cap_conn_shutdown(conn, ETIMEDOUT); 786b68fda68SJohan Hedberg } 787b68fda68SJohan Hedberg 7888aab4757SVinicius Costa Gomes static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) 7898aab4757SVinicius Costa Gomes { 7905d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 7918aab4757SVinicius Costa Gomes struct smp_chan *smp; 7928aab4757SVinicius Costa Gomes 793f1560463SMarcel Holtmann smp = kzalloc(sizeof(*smp), GFP_ATOMIC); 794616d55beSJohan Hedberg if (!smp) { 795616d55beSJohan Hedberg clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags); 7968aab4757SVinicius Costa Gomes return NULL; 797616d55beSJohan Hedberg } 7988aab4757SVinicius Costa Gomes 7996a7bd103SJohan Hedberg smp->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC); 8006a7bd103SJohan Hedberg if (IS_ERR(smp->tfm_aes)) { 8016a7bd103SJohan Hedberg BT_ERR("Unable to create ECB crypto context"); 8026a7bd103SJohan Hedberg kfree(smp); 803616d55beSJohan Hedberg clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags); 8046a7bd103SJohan Hedberg return NULL; 8056a7bd103SJohan Hedberg } 8066a7bd103SJohan Hedberg 8078aab4757SVinicius Costa Gomes smp->conn = conn; 8085d88cc73SJohan Hedberg chan->data = smp; 8098aab4757SVinicius Costa Gomes 810b68fda68SJohan Hedberg INIT_DELAYED_WORK(&smp->security_timer, smp_timeout); 811b68fda68SJohan Hedberg 8128aab4757SVinicius Costa Gomes hci_conn_hold(conn->hcon); 8138aab4757SVinicius Costa Gomes 8148aab4757SVinicius Costa Gomes return smp; 8158aab4757SVinicius Costa Gomes } 8168aab4757SVinicius Costa Gomes 8178aab4757SVinicius Costa Gomes void smp_chan_destroy(struct l2cap_conn *conn) 8188aab4757SVinicius Costa Gomes { 8195d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 8205d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 821f4a407beSJohan Hedberg bool complete; 822c8eb9690SBrian Gix 823f1c09c07SVinicius Costa Gomes BUG_ON(!smp); 824c8eb9690SBrian Gix 8254a74d658SJohan Hedberg complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags); 826f4a407beSJohan Hedberg mgmt_smp_complete(conn->hcon, complete); 827f4a407beSJohan Hedberg 8287ee4ea36SMarcel Holtmann kfree(smp->csrk); 8297ee4ea36SMarcel Holtmann kfree(smp->slave_csrk); 8307ee4ea36SMarcel Holtmann 8316a7bd103SJohan Hedberg crypto_free_blkcipher(smp->tfm_aes); 8326a7bd103SJohan Hedberg 833759331d7SJohan Hedberg /* If pairing failed clean up any keys we might have */ 834759331d7SJohan Hedberg if (!complete) { 835759331d7SJohan Hedberg if (smp->ltk) { 836759331d7SJohan Hedberg list_del(&smp->ltk->list); 837759331d7SJohan Hedberg kfree(smp->ltk); 838759331d7SJohan Hedberg } 839759331d7SJohan Hedberg 840759331d7SJohan Hedberg if (smp->slave_ltk) { 841759331d7SJohan Hedberg list_del(&smp->slave_ltk->list); 842759331d7SJohan Hedberg kfree(smp->slave_ltk); 843759331d7SJohan Hedberg } 844759331d7SJohan Hedberg 845759331d7SJohan Hedberg if (smp->remote_irk) { 846759331d7SJohan Hedberg list_del(&smp->remote_irk->list); 847759331d7SJohan Hedberg kfree(smp->remote_irk); 848759331d7SJohan Hedberg } 849759331d7SJohan Hedberg } 850759331d7SJohan Hedberg 8515d88cc73SJohan Hedberg chan->data = NULL; 852c8eb9690SBrian Gix kfree(smp); 85376a68ba0SDavid Herrmann hci_conn_drop(conn->hcon); 8548aab4757SVinicius Costa Gomes } 8558aab4757SVinicius Costa Gomes 8562b64d153SBrian Gix int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey) 8572b64d153SBrian Gix { 858b10e8017SJohan Hedberg struct l2cap_conn *conn = hcon->l2cap_data; 8595d88cc73SJohan Hedberg struct l2cap_chan *chan; 8602b64d153SBrian Gix struct smp_chan *smp; 8612b64d153SBrian Gix u32 value; 8622b64d153SBrian Gix 8632b64d153SBrian Gix BT_DBG(""); 8642b64d153SBrian Gix 865642ac774SJohan Hedberg if (!conn || !test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) 8662b64d153SBrian Gix return -ENOTCONN; 8672b64d153SBrian Gix 8685d88cc73SJohan Hedberg chan = conn->smp; 8695d88cc73SJohan Hedberg if (!chan) 8705d88cc73SJohan Hedberg return -ENOTCONN; 8715d88cc73SJohan Hedberg 8725d88cc73SJohan Hedberg smp = chan->data; 8732b64d153SBrian Gix 8742b64d153SBrian Gix switch (mgmt_op) { 8752b64d153SBrian Gix case MGMT_OP_USER_PASSKEY_REPLY: 8762b64d153SBrian Gix value = le32_to_cpu(passkey); 877943a732aSJohan Hedberg memset(smp->tk, 0, sizeof(smp->tk)); 8782b64d153SBrian Gix BT_DBG("PassKey: %d", value); 879943a732aSJohan Hedberg put_unaligned_le32(value, smp->tk); 8802b64d153SBrian Gix /* Fall Through */ 8812b64d153SBrian Gix case MGMT_OP_USER_CONFIRM_REPLY: 8824a74d658SJohan Hedberg set_bit(SMP_FLAG_TK_VALID, &smp->flags); 8832b64d153SBrian Gix break; 8842b64d153SBrian Gix case MGMT_OP_USER_PASSKEY_NEG_REPLY: 8852b64d153SBrian Gix case MGMT_OP_USER_CONFIRM_NEG_REPLY: 88684794e11SJohan Hedberg smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED); 8872b64d153SBrian Gix return 0; 8882b64d153SBrian Gix default: 88984794e11SJohan Hedberg smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED); 8902b64d153SBrian Gix return -EOPNOTSUPP; 8912b64d153SBrian Gix } 8922b64d153SBrian Gix 8932b64d153SBrian Gix /* If it is our turn to send Pairing Confirm, do so now */ 8941cc61144SJohan Hedberg if (test_bit(SMP_FLAG_CFM_PENDING, &smp->flags)) { 8951cc61144SJohan Hedberg u8 rsp = smp_confirm(smp); 8961cc61144SJohan Hedberg if (rsp) 8971cc61144SJohan Hedberg smp_failure(conn, rsp); 8981cc61144SJohan Hedberg } 8992b64d153SBrian Gix 9002b64d153SBrian Gix return 0; 9012b64d153SBrian Gix } 9022b64d153SBrian Gix 903da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) 90488ba43b6SAnderson Briglia { 9053158c50cSVinicius Costa Gomes struct smp_cmd_pairing rsp, *req = (void *) skb->data; 906b3c6410bSJohan Hedberg struct hci_dev *hdev = conn->hcon->hdev; 9078aab4757SVinicius Costa Gomes struct smp_chan *smp; 908c7262e71SJohan Hedberg u8 key_size, auth, sec_level; 9098aab4757SVinicius Costa Gomes int ret; 91088ba43b6SAnderson Briglia 91188ba43b6SAnderson Briglia BT_DBG("conn %p", conn); 91288ba43b6SAnderson Briglia 913c46b98beSJohan Hedberg if (skb->len < sizeof(*req)) 91438e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 915c46b98beSJohan Hedberg 91640bef302SJohan Hedberg if (conn->hcon->role != HCI_ROLE_SLAVE) 9172b64d153SBrian Gix return SMP_CMD_NOTSUPP; 9182b64d153SBrian Gix 9195d88cc73SJohan Hedberg if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) { 9208aab4757SVinicius Costa Gomes smp = smp_chan_create(conn); 9215d88cc73SJohan Hedberg } else { 9225d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 9235d88cc73SJohan Hedberg smp = chan->data; 9245d88cc73SJohan Hedberg } 925d26a2345SVinicius Costa Gomes 926d08fd0e7SAndrei Emeltchenko if (!smp) 927d08fd0e7SAndrei Emeltchenko return SMP_UNSPECIFIED; 928d08fd0e7SAndrei Emeltchenko 929b6ae8457SJohan Hedberg if (!test_bit(HCI_BONDABLE, &hdev->dev_flags) && 930b3c6410bSJohan Hedberg (req->auth_req & SMP_AUTH_BONDING)) 931b3c6410bSJohan Hedberg return SMP_PAIRING_NOTSUPP; 932b3c6410bSJohan Hedberg 9331c1def09SVinicius Costa Gomes smp->preq[0] = SMP_CMD_PAIRING_REQ; 9341c1def09SVinicius Costa Gomes memcpy(&smp->preq[1], req, sizeof(*req)); 9353158c50cSVinicius Costa Gomes skb_pull(skb, sizeof(*req)); 93688ba43b6SAnderson Briglia 9372b64d153SBrian Gix /* We didn't start the pairing, so match remote */ 9382b64d153SBrian Gix auth = req->auth_req; 939da85e5e5SVinicius Costa Gomes 940c7262e71SJohan Hedberg sec_level = authreq_to_seclevel(auth); 941c7262e71SJohan Hedberg if (sec_level > conn->hcon->pending_sec_level) 942c7262e71SJohan Hedberg conn->hcon->pending_sec_level = sec_level; 943fdde0a26SIdo Yariv 9442ed8f65cSJohan Hedberg /* If we need MITM check that it can be acheived */ 9452ed8f65cSJohan Hedberg if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) { 9462ed8f65cSJohan Hedberg u8 method; 9472ed8f65cSJohan Hedberg 9482ed8f65cSJohan Hedberg method = get_auth_method(smp, conn->hcon->io_capability, 9492ed8f65cSJohan Hedberg req->io_capability); 9502ed8f65cSJohan Hedberg if (method == JUST_WORKS || method == JUST_CFM) 9512ed8f65cSJohan Hedberg return SMP_AUTH_REQUIREMENTS; 9522ed8f65cSJohan Hedberg } 9532ed8f65cSJohan Hedberg 9542b64d153SBrian Gix build_pairing_cmd(conn, req, &rsp, auth); 9553158c50cSVinicius Costa Gomes 9563158c50cSVinicius Costa Gomes key_size = min(req->max_key_size, rsp.max_key_size); 9573158c50cSVinicius Costa Gomes if (check_enc_key_size(conn, key_size)) 9583158c50cSVinicius Costa Gomes return SMP_ENC_KEY_SIZE; 95988ba43b6SAnderson Briglia 960e84a6b13SJohan Hedberg get_random_bytes(smp->prnd, sizeof(smp->prnd)); 9618aab4757SVinicius Costa Gomes 9621c1def09SVinicius Costa Gomes smp->prsp[0] = SMP_CMD_PAIRING_RSP; 9631c1def09SVinicius Costa Gomes memcpy(&smp->prsp[1], &rsp, sizeof(rsp)); 964f01ead31SAnderson Briglia 9653158c50cSVinicius Costa Gomes smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp); 966da85e5e5SVinicius Costa Gomes 9672b64d153SBrian Gix /* Request setup of TK */ 9682b64d153SBrian Gix ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability); 9692b64d153SBrian Gix if (ret) 9702b64d153SBrian Gix return SMP_UNSPECIFIED; 9712b64d153SBrian Gix 972da85e5e5SVinicius Costa Gomes return 0; 97388ba43b6SAnderson Briglia } 97488ba43b6SAnderson Briglia 975da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) 97688ba43b6SAnderson Briglia { 9773158c50cSVinicius Costa Gomes struct smp_cmd_pairing *req, *rsp = (void *) skb->data; 9785d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 9795d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 9802b64d153SBrian Gix u8 key_size, auth = SMP_AUTH_NONE; 9817d24ddccSAnderson Briglia int ret; 98288ba43b6SAnderson Briglia 98388ba43b6SAnderson Briglia BT_DBG("conn %p", conn); 98488ba43b6SAnderson Briglia 985c46b98beSJohan Hedberg if (skb->len < sizeof(*rsp)) 98638e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 987c46b98beSJohan Hedberg 98840bef302SJohan Hedberg if (conn->hcon->role != HCI_ROLE_MASTER) 9892b64d153SBrian Gix return SMP_CMD_NOTSUPP; 9902b64d153SBrian Gix 9913158c50cSVinicius Costa Gomes skb_pull(skb, sizeof(*rsp)); 992da85e5e5SVinicius Costa Gomes 9931c1def09SVinicius Costa Gomes req = (void *) &smp->preq[1]; 9943158c50cSVinicius Costa Gomes 9953158c50cSVinicius Costa Gomes key_size = min(req->max_key_size, rsp->max_key_size); 9963158c50cSVinicius Costa Gomes if (check_enc_key_size(conn, key_size)) 9973158c50cSVinicius Costa Gomes return SMP_ENC_KEY_SIZE; 9983158c50cSVinicius Costa Gomes 9992ed8f65cSJohan Hedberg /* If we need MITM check that it can be acheived */ 10002ed8f65cSJohan Hedberg if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) { 10012ed8f65cSJohan Hedberg u8 method; 10022ed8f65cSJohan Hedberg 10032ed8f65cSJohan Hedberg method = get_auth_method(smp, req->io_capability, 10042ed8f65cSJohan Hedberg rsp->io_capability); 10052ed8f65cSJohan Hedberg if (method == JUST_WORKS || method == JUST_CFM) 10062ed8f65cSJohan Hedberg return SMP_AUTH_REQUIREMENTS; 10072ed8f65cSJohan Hedberg } 10082ed8f65cSJohan Hedberg 1009e84a6b13SJohan Hedberg get_random_bytes(smp->prnd, sizeof(smp->prnd)); 10107d24ddccSAnderson Briglia 10118aab4757SVinicius Costa Gomes smp->prsp[0] = SMP_CMD_PAIRING_RSP; 10128aab4757SVinicius Costa Gomes memcpy(&smp->prsp[1], rsp, sizeof(*rsp)); 10137d24ddccSAnderson Briglia 1014fdcc4becSJohan Hedberg /* Update remote key distribution in case the remote cleared 1015fdcc4becSJohan Hedberg * some bits that we had enabled in our request. 1016fdcc4becSJohan Hedberg */ 1017fdcc4becSJohan Hedberg smp->remote_key_dist &= rsp->resp_key_dist; 1018fdcc4becSJohan Hedberg 10192b64d153SBrian Gix if ((req->auth_req & SMP_AUTH_BONDING) && 10202b64d153SBrian Gix (rsp->auth_req & SMP_AUTH_BONDING)) 10212b64d153SBrian Gix auth = SMP_AUTH_BONDING; 10222b64d153SBrian Gix 10232b64d153SBrian Gix auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM; 10242b64d153SBrian Gix 1025476585ecSJohan Hedberg ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability); 10262b64d153SBrian Gix if (ret) 10272b64d153SBrian Gix return SMP_UNSPECIFIED; 10282b64d153SBrian Gix 10294a74d658SJohan Hedberg set_bit(SMP_FLAG_CFM_PENDING, &smp->flags); 10302b64d153SBrian Gix 10312b64d153SBrian Gix /* Can't compose response until we have been confirmed */ 10324a74d658SJohan Hedberg if (test_bit(SMP_FLAG_TK_VALID, &smp->flags)) 10331cc61144SJohan Hedberg return smp_confirm(smp); 1034da85e5e5SVinicius Costa Gomes 1035da85e5e5SVinicius Costa Gomes return 0; 103688ba43b6SAnderson Briglia } 103788ba43b6SAnderson Briglia 1038da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb) 103988ba43b6SAnderson Briglia { 10405d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 10415d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 10427d24ddccSAnderson Briglia 104388ba43b6SAnderson Briglia BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave"); 104488ba43b6SAnderson Briglia 1045c46b98beSJohan Hedberg if (skb->len < sizeof(smp->pcnf)) 104638e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 1047c46b98beSJohan Hedberg 10481c1def09SVinicius Costa Gomes memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf)); 10491c1def09SVinicius Costa Gomes skb_pull(skb, sizeof(smp->pcnf)); 10507d24ddccSAnderson Briglia 1051943a732aSJohan Hedberg if (conn->hcon->out) 1052943a732aSJohan Hedberg smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd), 1053943a732aSJohan Hedberg smp->prnd); 10544a74d658SJohan Hedberg else if (test_bit(SMP_FLAG_TK_VALID, &smp->flags)) 10551cc61144SJohan Hedberg return smp_confirm(smp); 1056943a732aSJohan Hedberg else 10574a74d658SJohan Hedberg set_bit(SMP_FLAG_CFM_PENDING, &smp->flags); 1058da85e5e5SVinicius Costa Gomes 1059da85e5e5SVinicius Costa Gomes return 0; 106088ba43b6SAnderson Briglia } 106188ba43b6SAnderson Briglia 1062da85e5e5SVinicius Costa Gomes static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) 106388ba43b6SAnderson Briglia { 10645d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 10655d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 10667d24ddccSAnderson Briglia 10678aab4757SVinicius Costa Gomes BT_DBG("conn %p", conn); 10687d24ddccSAnderson Briglia 1069c46b98beSJohan Hedberg if (skb->len < sizeof(smp->rrnd)) 107038e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 1071c46b98beSJohan Hedberg 1072943a732aSJohan Hedberg memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd)); 10738aab4757SVinicius Costa Gomes skb_pull(skb, sizeof(smp->rrnd)); 107488ba43b6SAnderson Briglia 1075861580a9SJohan Hedberg return smp_random(smp); 107688ba43b6SAnderson Briglia } 107788ba43b6SAnderson Briglia 1078f81cd823SMarcel Holtmann static bool smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level) 1079988c5997SVinicius Costa Gomes { 1080c9839a11SVinicius Costa Gomes struct smp_ltk *key; 1081988c5997SVinicius Costa Gomes struct hci_conn *hcon = conn->hcon; 1082988c5997SVinicius Costa Gomes 108398a0b845SJohan Hedberg key = hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type, 1084e804d25dSJohan Hedberg hcon->role); 1085988c5997SVinicius Costa Gomes if (!key) 1086f81cd823SMarcel Holtmann return false; 1087988c5997SVinicius Costa Gomes 10884dab7864SJohan Hedberg if (sec_level > BT_SECURITY_MEDIUM && !key->authenticated) 1089f81cd823SMarcel Holtmann return false; 10904dab7864SJohan Hedberg 109151a8efd7SJohan Hedberg if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags)) 1092f81cd823SMarcel Holtmann return true; 1093988c5997SVinicius Costa Gomes 1094c9839a11SVinicius Costa Gomes hci_le_start_enc(hcon, key->ediv, key->rand, key->val); 1095c9839a11SVinicius Costa Gomes hcon->enc_key_size = key->enc_size; 1096988c5997SVinicius Costa Gomes 1097fe59a05fSJohan Hedberg /* We never store STKs for master role, so clear this flag */ 1098fe59a05fSJohan Hedberg clear_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags); 1099fe59a05fSJohan Hedberg 1100f81cd823SMarcel Holtmann return true; 1101988c5997SVinicius Costa Gomes } 1102f1560463SMarcel Holtmann 1103854f4727SJohan Hedberg bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level) 1104854f4727SJohan Hedberg { 1105854f4727SJohan Hedberg if (sec_level == BT_SECURITY_LOW) 1106854f4727SJohan Hedberg return true; 1107854f4727SJohan Hedberg 11089ab65d60SJohan Hedberg /* If we're encrypted with an STK always claim insufficient 11099ab65d60SJohan Hedberg * security. This way we allow the connection to be re-encrypted 11109ab65d60SJohan Hedberg * with an LTK, even if the LTK provides the same level of 1111b2d5e254SJohan Hedberg * security. Only exception is if we don't have an LTK (e.g. 1112b2d5e254SJohan Hedberg * because of key distribution bits). 11139ab65d60SJohan Hedberg */ 1114b2d5e254SJohan Hedberg if (test_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags) && 1115b2d5e254SJohan Hedberg hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type, 1116e804d25dSJohan Hedberg hcon->role)) 11179ab65d60SJohan Hedberg return false; 11189ab65d60SJohan Hedberg 1119854f4727SJohan Hedberg if (hcon->sec_level >= sec_level) 1120854f4727SJohan Hedberg return true; 1121854f4727SJohan Hedberg 1122854f4727SJohan Hedberg return false; 1123854f4727SJohan Hedberg } 1124854f4727SJohan Hedberg 1125da85e5e5SVinicius Costa Gomes static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) 112688ba43b6SAnderson Briglia { 112788ba43b6SAnderson Briglia struct smp_cmd_security_req *rp = (void *) skb->data; 112888ba43b6SAnderson Briglia struct smp_cmd_pairing cp; 1129f1cb9af5SVinicius Costa Gomes struct hci_conn *hcon = conn->hcon; 11308aab4757SVinicius Costa Gomes struct smp_chan *smp; 1131c7262e71SJohan Hedberg u8 sec_level; 113288ba43b6SAnderson Briglia 113388ba43b6SAnderson Briglia BT_DBG("conn %p", conn); 113488ba43b6SAnderson Briglia 1135c46b98beSJohan Hedberg if (skb->len < sizeof(*rp)) 113638e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 1137c46b98beSJohan Hedberg 113840bef302SJohan Hedberg if (hcon->role != HCI_ROLE_MASTER) 113986ca9eacSJohan Hedberg return SMP_CMD_NOTSUPP; 114086ca9eacSJohan Hedberg 1141c7262e71SJohan Hedberg sec_level = authreq_to_seclevel(rp->auth_req); 1142854f4727SJohan Hedberg if (smp_sufficient_security(hcon, sec_level)) 1143854f4727SJohan Hedberg return 0; 1144854f4727SJohan Hedberg 1145c7262e71SJohan Hedberg if (sec_level > hcon->pending_sec_level) 1146c7262e71SJohan Hedberg hcon->pending_sec_level = sec_level; 1147feb45eb5SVinicius Costa Gomes 11484dab7864SJohan Hedberg if (smp_ltk_encrypt(conn, hcon->pending_sec_level)) 1149988c5997SVinicius Costa Gomes return 0; 1150988c5997SVinicius Costa Gomes 115151a8efd7SJohan Hedberg if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) 1152da85e5e5SVinicius Costa Gomes return 0; 1153f1cb9af5SVinicius Costa Gomes 11548aab4757SVinicius Costa Gomes smp = smp_chan_create(conn); 1155c29d2444SJohan Hedberg if (!smp) 1156c29d2444SJohan Hedberg return SMP_UNSPECIFIED; 1157d26a2345SVinicius Costa Gomes 1158b6ae8457SJohan Hedberg if (!test_bit(HCI_BONDABLE, &hcon->hdev->dev_flags) && 1159616d55beSJohan Hedberg (rp->auth_req & SMP_AUTH_BONDING)) 1160616d55beSJohan Hedberg return SMP_PAIRING_NOTSUPP; 1161616d55beSJohan Hedberg 116288ba43b6SAnderson Briglia skb_pull(skb, sizeof(*rp)); 116388ba43b6SAnderson Briglia 1164da85e5e5SVinicius Costa Gomes memset(&cp, 0, sizeof(cp)); 116554790f73SVinicius Costa Gomes build_pairing_cmd(conn, &cp, NULL, rp->auth_req); 116688ba43b6SAnderson Briglia 11671c1def09SVinicius Costa Gomes smp->preq[0] = SMP_CMD_PAIRING_REQ; 11681c1def09SVinicius Costa Gomes memcpy(&smp->preq[1], &cp, sizeof(cp)); 1169f01ead31SAnderson Briglia 117088ba43b6SAnderson Briglia smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp); 1171f1cb9af5SVinicius Costa Gomes 1172da85e5e5SVinicius Costa Gomes return 0; 117388ba43b6SAnderson Briglia } 117488ba43b6SAnderson Briglia 1175cc110922SVinicius Costa Gomes int smp_conn_security(struct hci_conn *hcon, __u8 sec_level) 1176eb492e01SAnderson Briglia { 1177cc110922SVinicius Costa Gomes struct l2cap_conn *conn = hcon->l2cap_data; 11780a66cf20SJohan Hedberg struct smp_chan *smp; 11792b64d153SBrian Gix __u8 authreq; 1180eb492e01SAnderson Briglia 11813a0259bbSVinicius Costa Gomes BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level); 11823a0259bbSVinicius Costa Gomes 11830a66cf20SJohan Hedberg /* This may be NULL if there's an unexpected disconnection */ 11840a66cf20SJohan Hedberg if (!conn) 11850a66cf20SJohan Hedberg return 1; 11860a66cf20SJohan Hedberg 1187757aee0fSJohan Hedberg if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) 11882e65c9d2SAndre Guedes return 1; 11892e65c9d2SAndre Guedes 1190ad32a2f5SJohan Hedberg if (smp_sufficient_security(hcon, sec_level)) 1191f1cb9af5SVinicius Costa Gomes return 1; 1192f1cb9af5SVinicius Costa Gomes 1193c7262e71SJohan Hedberg if (sec_level > hcon->pending_sec_level) 1194c7262e71SJohan Hedberg hcon->pending_sec_level = sec_level; 1195c7262e71SJohan Hedberg 119640bef302SJohan Hedberg if (hcon->role == HCI_ROLE_MASTER) 1197c7262e71SJohan Hedberg if (smp_ltk_encrypt(conn, hcon->pending_sec_level)) 1198c7262e71SJohan Hedberg return 0; 1199d26a2345SVinicius Costa Gomes 120051a8efd7SJohan Hedberg if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) 1201d26a2345SVinicius Costa Gomes return 0; 1202d26a2345SVinicius Costa Gomes 12038aab4757SVinicius Costa Gomes smp = smp_chan_create(conn); 12042b64d153SBrian Gix if (!smp) 12052b64d153SBrian Gix return 1; 12062b64d153SBrian Gix 12072b64d153SBrian Gix authreq = seclevel_to_authreq(sec_level); 1208d26a2345SVinicius Costa Gomes 120979897d20SJohan Hedberg /* Require MITM if IO Capability allows or the security level 121079897d20SJohan Hedberg * requires it. 12112e233644SJohan Hedberg */ 121279897d20SJohan Hedberg if (hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT || 1213c7262e71SJohan Hedberg hcon->pending_sec_level > BT_SECURITY_MEDIUM) 12142e233644SJohan Hedberg authreq |= SMP_AUTH_MITM; 12152e233644SJohan Hedberg 121640bef302SJohan Hedberg if (hcon->role == HCI_ROLE_MASTER) { 1217d26a2345SVinicius Costa Gomes struct smp_cmd_pairing cp; 1218f01ead31SAnderson Briglia 12192b64d153SBrian Gix build_pairing_cmd(conn, &cp, NULL, authreq); 12201c1def09SVinicius Costa Gomes smp->preq[0] = SMP_CMD_PAIRING_REQ; 12211c1def09SVinicius Costa Gomes memcpy(&smp->preq[1], &cp, sizeof(cp)); 1222f01ead31SAnderson Briglia 1223eb492e01SAnderson Briglia smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp); 1224eb492e01SAnderson Briglia } else { 1225eb492e01SAnderson Briglia struct smp_cmd_security_req cp; 12262b64d153SBrian Gix cp.auth_req = authreq; 1227eb492e01SAnderson Briglia smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp); 1228eb492e01SAnderson Briglia } 1229eb492e01SAnderson Briglia 12304a74d658SJohan Hedberg set_bit(SMP_FLAG_INITIATOR, &smp->flags); 1231edca792cSJohan Hedberg 1232eb492e01SAnderson Briglia return 0; 1233eb492e01SAnderson Briglia } 1234eb492e01SAnderson Briglia 12357034b911SVinicius Costa Gomes static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb) 12367034b911SVinicius Costa Gomes { 123716b90839SVinicius Costa Gomes struct smp_cmd_encrypt_info *rp = (void *) skb->data; 12385d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 12395d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 124016b90839SVinicius Costa Gomes 1241c46b98beSJohan Hedberg BT_DBG("conn %p", conn); 1242c46b98beSJohan Hedberg 1243c46b98beSJohan Hedberg if (skb->len < sizeof(*rp)) 124438e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 1245c46b98beSJohan Hedberg 12466131ddc8SJohan Hedberg /* Ignore this PDU if it wasn't requested */ 12476131ddc8SJohan Hedberg if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY)) 12486131ddc8SJohan Hedberg return 0; 12496131ddc8SJohan Hedberg 125016b90839SVinicius Costa Gomes skb_pull(skb, sizeof(*rp)); 125116b90839SVinicius Costa Gomes 12521c1def09SVinicius Costa Gomes memcpy(smp->tk, rp->ltk, sizeof(smp->tk)); 125316b90839SVinicius Costa Gomes 12547034b911SVinicius Costa Gomes return 0; 12557034b911SVinicius Costa Gomes } 12567034b911SVinicius Costa Gomes 12577034b911SVinicius Costa Gomes static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb) 12587034b911SVinicius Costa Gomes { 125916b90839SVinicius Costa Gomes struct smp_cmd_master_ident *rp = (void *) skb->data; 12605d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 12615d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 1262c9839a11SVinicius Costa Gomes struct hci_dev *hdev = conn->hcon->hdev; 1263c9839a11SVinicius Costa Gomes struct hci_conn *hcon = conn->hcon; 126423d0e128SJohan Hedberg struct smp_ltk *ltk; 1265c9839a11SVinicius Costa Gomes u8 authenticated; 12667034b911SVinicius Costa Gomes 1267c46b98beSJohan Hedberg BT_DBG("conn %p", conn); 1268c46b98beSJohan Hedberg 1269c46b98beSJohan Hedberg if (skb->len < sizeof(*rp)) 127038e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 1271c46b98beSJohan Hedberg 12726131ddc8SJohan Hedberg /* Ignore this PDU if it wasn't requested */ 12736131ddc8SJohan Hedberg if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY)) 12746131ddc8SJohan Hedberg return 0; 12756131ddc8SJohan Hedberg 12769747a9f3SJohan Hedberg /* Mark the information as received */ 12779747a9f3SJohan Hedberg smp->remote_key_dist &= ~SMP_DIST_ENC_KEY; 12789747a9f3SJohan Hedberg 127916b90839SVinicius Costa Gomes skb_pull(skb, sizeof(*rp)); 128016b90839SVinicius Costa Gomes 1281c9839a11SVinicius Costa Gomes hci_dev_lock(hdev); 1282ce39fb4eSMarcel Holtmann authenticated = (hcon->sec_level == BT_SECURITY_HIGH); 12832ceba539SJohan Hedberg ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, SMP_LTK, 1284ce39fb4eSMarcel Holtmann authenticated, smp->tk, smp->enc_key_size, 128504124681SGustavo F. Padovan rp->ediv, rp->rand); 128623d0e128SJohan Hedberg smp->ltk = ltk; 1287fd349c02SJohan Hedberg if (!(smp->remote_key_dist & SMP_DIST_ID_KEY)) 12884bd6d38eSJohan Hedberg smp_distribute_keys(conn); 1289c9839a11SVinicius Costa Gomes hci_dev_unlock(hdev); 12907034b911SVinicius Costa Gomes 12917034b911SVinicius Costa Gomes return 0; 12927034b911SVinicius Costa Gomes } 12937034b911SVinicius Costa Gomes 1294fd349c02SJohan Hedberg static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb) 1295fd349c02SJohan Hedberg { 1296fd349c02SJohan Hedberg struct smp_cmd_ident_info *info = (void *) skb->data; 12975d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 12985d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 1299fd349c02SJohan Hedberg 1300fd349c02SJohan Hedberg BT_DBG(""); 1301fd349c02SJohan Hedberg 1302fd349c02SJohan Hedberg if (skb->len < sizeof(*info)) 130338e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 1304fd349c02SJohan Hedberg 13056131ddc8SJohan Hedberg /* Ignore this PDU if it wasn't requested */ 13066131ddc8SJohan Hedberg if (!(smp->remote_key_dist & SMP_DIST_ID_KEY)) 13076131ddc8SJohan Hedberg return 0; 13086131ddc8SJohan Hedberg 1309fd349c02SJohan Hedberg skb_pull(skb, sizeof(*info)); 1310fd349c02SJohan Hedberg 1311fd349c02SJohan Hedberg memcpy(smp->irk, info->irk, 16); 1312fd349c02SJohan Hedberg 1313fd349c02SJohan Hedberg return 0; 1314fd349c02SJohan Hedberg } 1315fd349c02SJohan Hedberg 1316fd349c02SJohan Hedberg static int smp_cmd_ident_addr_info(struct l2cap_conn *conn, 1317fd349c02SJohan Hedberg struct sk_buff *skb) 1318fd349c02SJohan Hedberg { 1319fd349c02SJohan Hedberg struct smp_cmd_ident_addr_info *info = (void *) skb->data; 13205d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 13215d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 1322fd349c02SJohan Hedberg struct hci_conn *hcon = conn->hcon; 1323fd349c02SJohan Hedberg bdaddr_t rpa; 1324fd349c02SJohan Hedberg 1325fd349c02SJohan Hedberg BT_DBG(""); 1326fd349c02SJohan Hedberg 1327fd349c02SJohan Hedberg if (skb->len < sizeof(*info)) 132838e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 1329fd349c02SJohan Hedberg 13306131ddc8SJohan Hedberg /* Ignore this PDU if it wasn't requested */ 13316131ddc8SJohan Hedberg if (!(smp->remote_key_dist & SMP_DIST_ID_KEY)) 13326131ddc8SJohan Hedberg return 0; 13336131ddc8SJohan Hedberg 13349747a9f3SJohan Hedberg /* Mark the information as received */ 13359747a9f3SJohan Hedberg smp->remote_key_dist &= ~SMP_DIST_ID_KEY; 13369747a9f3SJohan Hedberg 1337fd349c02SJohan Hedberg skb_pull(skb, sizeof(*info)); 1338fd349c02SJohan Hedberg 133931dd624eSJohan Hedberg hci_dev_lock(hcon->hdev); 134031dd624eSJohan Hedberg 1341a9a58f86SJohan Hedberg /* Strictly speaking the Core Specification (4.1) allows sending 1342a9a58f86SJohan Hedberg * an empty address which would force us to rely on just the IRK 1343a9a58f86SJohan Hedberg * as "identity information". However, since such 1344a9a58f86SJohan Hedberg * implementations are not known of and in order to not over 1345a9a58f86SJohan Hedberg * complicate our implementation, simply pretend that we never 1346a9a58f86SJohan Hedberg * received an IRK for such a device. 1347a9a58f86SJohan Hedberg */ 1348a9a58f86SJohan Hedberg if (!bacmp(&info->bdaddr, BDADDR_ANY)) { 1349a9a58f86SJohan Hedberg BT_ERR("Ignoring IRK with no identity address"); 135031dd624eSJohan Hedberg goto distribute; 1351a9a58f86SJohan Hedberg } 1352a9a58f86SJohan Hedberg 1353fd349c02SJohan Hedberg bacpy(&smp->id_addr, &info->bdaddr); 1354fd349c02SJohan Hedberg smp->id_addr_type = info->addr_type; 1355fd349c02SJohan Hedberg 1356fd349c02SJohan Hedberg if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type)) 1357fd349c02SJohan Hedberg bacpy(&rpa, &hcon->dst); 1358fd349c02SJohan Hedberg else 1359fd349c02SJohan Hedberg bacpy(&rpa, BDADDR_ANY); 1360fd349c02SJohan Hedberg 136123d0e128SJohan Hedberg smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr, 136223d0e128SJohan Hedberg smp->id_addr_type, smp->irk, &rpa); 1363fd349c02SJohan Hedberg 136431dd624eSJohan Hedberg distribute: 13654bd6d38eSJohan Hedberg smp_distribute_keys(conn); 1366fd349c02SJohan Hedberg 136731dd624eSJohan Hedberg hci_dev_unlock(hcon->hdev); 136831dd624eSJohan Hedberg 1369fd349c02SJohan Hedberg return 0; 1370fd349c02SJohan Hedberg } 1371fd349c02SJohan Hedberg 13727ee4ea36SMarcel Holtmann static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb) 13737ee4ea36SMarcel Holtmann { 13747ee4ea36SMarcel Holtmann struct smp_cmd_sign_info *rp = (void *) skb->data; 13755d88cc73SJohan Hedberg struct l2cap_chan *chan = conn->smp; 13765d88cc73SJohan Hedberg struct smp_chan *smp = chan->data; 13777ee4ea36SMarcel Holtmann struct hci_dev *hdev = conn->hcon->hdev; 13787ee4ea36SMarcel Holtmann struct smp_csrk *csrk; 13797ee4ea36SMarcel Holtmann 13807ee4ea36SMarcel Holtmann BT_DBG("conn %p", conn); 13817ee4ea36SMarcel Holtmann 13827ee4ea36SMarcel Holtmann if (skb->len < sizeof(*rp)) 138338e4a915SJohan Hedberg return SMP_INVALID_PARAMS; 13847ee4ea36SMarcel Holtmann 13857ee4ea36SMarcel Holtmann /* Ignore this PDU if it wasn't requested */ 13867ee4ea36SMarcel Holtmann if (!(smp->remote_key_dist & SMP_DIST_SIGN)) 13877ee4ea36SMarcel Holtmann return 0; 13887ee4ea36SMarcel Holtmann 13897ee4ea36SMarcel Holtmann /* Mark the information as received */ 13907ee4ea36SMarcel Holtmann smp->remote_key_dist &= ~SMP_DIST_SIGN; 13917ee4ea36SMarcel Holtmann 13927ee4ea36SMarcel Holtmann skb_pull(skb, sizeof(*rp)); 13937ee4ea36SMarcel Holtmann 13947ee4ea36SMarcel Holtmann hci_dev_lock(hdev); 13957ee4ea36SMarcel Holtmann csrk = kzalloc(sizeof(*csrk), GFP_KERNEL); 13967ee4ea36SMarcel Holtmann if (csrk) { 13977ee4ea36SMarcel Holtmann csrk->master = 0x01; 13987ee4ea36SMarcel Holtmann memcpy(csrk->val, rp->csrk, sizeof(csrk->val)); 13997ee4ea36SMarcel Holtmann } 14007ee4ea36SMarcel Holtmann smp->csrk = csrk; 14017ee4ea36SMarcel Holtmann smp_distribute_keys(conn); 14027ee4ea36SMarcel Holtmann hci_dev_unlock(hdev); 14037ee4ea36SMarcel Holtmann 14047ee4ea36SMarcel Holtmann return 0; 14057ee4ea36SMarcel Holtmann } 14067ee4ea36SMarcel Holtmann 14074befb867SJohan Hedberg static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb) 1408eb492e01SAnderson Briglia { 14095d88cc73SJohan Hedberg struct l2cap_conn *conn = chan->conn; 14107b9899dbSMarcel Holtmann struct hci_conn *hcon = conn->hcon; 141192381f5cSMarcel Holtmann __u8 code, reason; 1412eb492e01SAnderson Briglia int err = 0; 1413eb492e01SAnderson Briglia 14147b9899dbSMarcel Holtmann if (hcon->type != LE_LINK) { 14157b9899dbSMarcel Holtmann kfree_skb(skb); 14163432711fSJohan Hedberg return 0; 14177b9899dbSMarcel Holtmann } 14187b9899dbSMarcel Holtmann 14198ae9b984SJohan Hedberg if (skb->len < 1) 142092381f5cSMarcel Holtmann return -EILSEQ; 142192381f5cSMarcel Holtmann 142206ae3314SMarcel Holtmann if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) { 1423beb19e4cSJohan Hedberg err = -EOPNOTSUPP; 14242e65c9d2SAndre Guedes reason = SMP_PAIRING_NOTSUPP; 14252e65c9d2SAndre Guedes goto done; 14262e65c9d2SAndre Guedes } 14272e65c9d2SAndre Guedes 142892381f5cSMarcel Holtmann code = skb->data[0]; 1429eb492e01SAnderson Briglia skb_pull(skb, sizeof(code)); 1430eb492e01SAnderson Briglia 14318cf9fa12SJohan Hedberg /* 14328cf9fa12SJohan Hedberg * The SMP context must be initialized for all other PDUs except 14338cf9fa12SJohan Hedberg * pairing and security requests. If we get any other PDU when 14348cf9fa12SJohan Hedberg * not initialized simply disconnect (done if this function 14358cf9fa12SJohan Hedberg * returns an error). 14368cf9fa12SJohan Hedberg */ 14378cf9fa12SJohan Hedberg if (code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ && 1438d3368605SJohan Hedberg !test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) { 14398cf9fa12SJohan Hedberg BT_ERR("Unexpected SMP command 0x%02x. Disconnecting.", code); 14408ae9b984SJohan Hedberg reason = SMP_CMD_NOTSUPP; 14418ae9b984SJohan Hedberg err = -EOPNOTSUPP; 14428ae9b984SJohan Hedberg goto done; 14438cf9fa12SJohan Hedberg } 14448cf9fa12SJohan Hedberg 1445eb492e01SAnderson Briglia switch (code) { 1446eb492e01SAnderson Briglia case SMP_CMD_PAIRING_REQ: 1447da85e5e5SVinicius Costa Gomes reason = smp_cmd_pairing_req(conn, skb); 1448eb492e01SAnderson Briglia break; 1449eb492e01SAnderson Briglia 1450eb492e01SAnderson Briglia case SMP_CMD_PAIRING_FAIL: 145184794e11SJohan Hedberg smp_failure(conn, 0); 1452da85e5e5SVinicius Costa Gomes reason = 0; 1453da85e5e5SVinicius Costa Gomes err = -EPERM; 1454eb492e01SAnderson Briglia break; 1455eb492e01SAnderson Briglia 1456eb492e01SAnderson Briglia case SMP_CMD_PAIRING_RSP: 1457da85e5e5SVinicius Costa Gomes reason = smp_cmd_pairing_rsp(conn, skb); 145888ba43b6SAnderson Briglia break; 145988ba43b6SAnderson Briglia 146088ba43b6SAnderson Briglia case SMP_CMD_SECURITY_REQ: 1461da85e5e5SVinicius Costa Gomes reason = smp_cmd_security_req(conn, skb); 146288ba43b6SAnderson Briglia break; 146388ba43b6SAnderson Briglia 1464eb492e01SAnderson Briglia case SMP_CMD_PAIRING_CONFIRM: 1465da85e5e5SVinicius Costa Gomes reason = smp_cmd_pairing_confirm(conn, skb); 146688ba43b6SAnderson Briglia break; 146788ba43b6SAnderson Briglia 1468eb492e01SAnderson Briglia case SMP_CMD_PAIRING_RANDOM: 1469da85e5e5SVinicius Costa Gomes reason = smp_cmd_pairing_random(conn, skb); 147088ba43b6SAnderson Briglia break; 147188ba43b6SAnderson Briglia 1472eb492e01SAnderson Briglia case SMP_CMD_ENCRYPT_INFO: 14737034b911SVinicius Costa Gomes reason = smp_cmd_encrypt_info(conn, skb); 14747034b911SVinicius Costa Gomes break; 14757034b911SVinicius Costa Gomes 1476eb492e01SAnderson Briglia case SMP_CMD_MASTER_IDENT: 14777034b911SVinicius Costa Gomes reason = smp_cmd_master_ident(conn, skb); 14787034b911SVinicius Costa Gomes break; 14797034b911SVinicius Costa Gomes 1480eb492e01SAnderson Briglia case SMP_CMD_IDENT_INFO: 1481fd349c02SJohan Hedberg reason = smp_cmd_ident_info(conn, skb); 1482fd349c02SJohan Hedberg break; 1483fd349c02SJohan Hedberg 1484eb492e01SAnderson Briglia case SMP_CMD_IDENT_ADDR_INFO: 1485fd349c02SJohan Hedberg reason = smp_cmd_ident_addr_info(conn, skb); 1486fd349c02SJohan Hedberg break; 1487fd349c02SJohan Hedberg 1488eb492e01SAnderson Briglia case SMP_CMD_SIGN_INFO: 14897ee4ea36SMarcel Holtmann reason = smp_cmd_sign_info(conn, skb); 14907034b911SVinicius Costa Gomes break; 14917034b911SVinicius Costa Gomes 1492eb492e01SAnderson Briglia default: 1493eb492e01SAnderson Briglia BT_DBG("Unknown command code 0x%2.2x", code); 1494eb492e01SAnderson Briglia 1495eb492e01SAnderson Briglia reason = SMP_CMD_NOTSUPP; 14963a0259bbSVinicius Costa Gomes err = -EOPNOTSUPP; 14973a0259bbSVinicius Costa Gomes goto done; 14983a0259bbSVinicius Costa Gomes } 14993a0259bbSVinicius Costa Gomes 15003a0259bbSVinicius Costa Gomes done: 15013a0259bbSVinicius Costa Gomes if (reason) 150284794e11SJohan Hedberg smp_failure(conn, reason); 15038ae9b984SJohan Hedberg if (!err) 1504eb492e01SAnderson Briglia kfree_skb(skb); 1505eb492e01SAnderson Briglia return err; 1506eb492e01SAnderson Briglia } 15077034b911SVinicius Costa Gomes 150870db83c4SJohan Hedberg static void smp_teardown_cb(struct l2cap_chan *chan, int err) 150970db83c4SJohan Hedberg { 151070db83c4SJohan Hedberg struct l2cap_conn *conn = chan->conn; 1511b68fda68SJohan Hedberg struct smp_chan *smp = chan->data; 151270db83c4SJohan Hedberg 151370db83c4SJohan Hedberg BT_DBG("chan %p", chan); 151470db83c4SJohan Hedberg 15155d88cc73SJohan Hedberg if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) { 1516b68fda68SJohan Hedberg cancel_delayed_work_sync(&smp->security_timer); 15175d88cc73SJohan Hedberg smp_chan_destroy(conn); 15185d88cc73SJohan Hedberg } 15195d88cc73SJohan Hedberg 152070db83c4SJohan Hedberg conn->smp = NULL; 152170db83c4SJohan Hedberg l2cap_chan_put(chan); 152270db83c4SJohan Hedberg } 152370db83c4SJohan Hedberg 152444f1a7abSJohan Hedberg static void smp_resume_cb(struct l2cap_chan *chan) 152544f1a7abSJohan Hedberg { 1526b68fda68SJohan Hedberg struct smp_chan *smp = chan->data; 152744f1a7abSJohan Hedberg struct l2cap_conn *conn = chan->conn; 152844f1a7abSJohan Hedberg struct hci_conn *hcon = conn->hcon; 152944f1a7abSJohan Hedberg 153044f1a7abSJohan Hedberg BT_DBG("chan %p", chan); 153144f1a7abSJohan Hedberg 153244f1a7abSJohan Hedberg if (test_bit(HCI_CONN_ENCRYPT, &hcon->flags)) 153344f1a7abSJohan Hedberg smp_distribute_keys(conn); 1534b68fda68SJohan Hedberg 1535b68fda68SJohan Hedberg if (smp) 1536b68fda68SJohan Hedberg cancel_delayed_work(&smp->security_timer); 153744f1a7abSJohan Hedberg } 153844f1a7abSJohan Hedberg 153970db83c4SJohan Hedberg static void smp_ready_cb(struct l2cap_chan *chan) 154070db83c4SJohan Hedberg { 154170db83c4SJohan Hedberg struct l2cap_conn *conn = chan->conn; 154270db83c4SJohan Hedberg 154370db83c4SJohan Hedberg BT_DBG("chan %p", chan); 154470db83c4SJohan Hedberg 154570db83c4SJohan Hedberg conn->smp = chan; 154670db83c4SJohan Hedberg l2cap_chan_hold(chan); 154770db83c4SJohan Hedberg } 154870db83c4SJohan Hedberg 15494befb867SJohan Hedberg static int smp_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) 15504befb867SJohan Hedberg { 15514befb867SJohan Hedberg int err; 15524befb867SJohan Hedberg 15534befb867SJohan Hedberg BT_DBG("chan %p", chan); 15544befb867SJohan Hedberg 15554befb867SJohan Hedberg err = smp_sig_channel(chan, skb); 15564befb867SJohan Hedberg if (err) { 1557b68fda68SJohan Hedberg struct smp_chan *smp = chan->data; 15584befb867SJohan Hedberg 1559b68fda68SJohan Hedberg if (smp) 1560b68fda68SJohan Hedberg cancel_delayed_work_sync(&smp->security_timer); 15614befb867SJohan Hedberg 15624befb867SJohan Hedberg l2cap_conn_shutdown(chan->conn, -err); 15634befb867SJohan Hedberg } 15644befb867SJohan Hedberg 15654befb867SJohan Hedberg return err; 15664befb867SJohan Hedberg } 15674befb867SJohan Hedberg 156870db83c4SJohan Hedberg static struct sk_buff *smp_alloc_skb_cb(struct l2cap_chan *chan, 156970db83c4SJohan Hedberg unsigned long hdr_len, 157070db83c4SJohan Hedberg unsigned long len, int nb) 157170db83c4SJohan Hedberg { 157270db83c4SJohan Hedberg struct sk_buff *skb; 157370db83c4SJohan Hedberg 157470db83c4SJohan Hedberg skb = bt_skb_alloc(hdr_len + len, GFP_KERNEL); 157570db83c4SJohan Hedberg if (!skb) 157670db83c4SJohan Hedberg return ERR_PTR(-ENOMEM); 157770db83c4SJohan Hedberg 157870db83c4SJohan Hedberg skb->priority = HCI_PRIO_MAX; 157970db83c4SJohan Hedberg bt_cb(skb)->chan = chan; 158070db83c4SJohan Hedberg 158170db83c4SJohan Hedberg return skb; 158270db83c4SJohan Hedberg } 158370db83c4SJohan Hedberg 158470db83c4SJohan Hedberg static const struct l2cap_ops smp_chan_ops = { 158570db83c4SJohan Hedberg .name = "Security Manager", 158670db83c4SJohan Hedberg .ready = smp_ready_cb, 15875d88cc73SJohan Hedberg .recv = smp_recv_cb, 158870db83c4SJohan Hedberg .alloc_skb = smp_alloc_skb_cb, 158970db83c4SJohan Hedberg .teardown = smp_teardown_cb, 159044f1a7abSJohan Hedberg .resume = smp_resume_cb, 159170db83c4SJohan Hedberg 159270db83c4SJohan Hedberg .new_connection = l2cap_chan_no_new_connection, 159370db83c4SJohan Hedberg .state_change = l2cap_chan_no_state_change, 159470db83c4SJohan Hedberg .close = l2cap_chan_no_close, 159570db83c4SJohan Hedberg .defer = l2cap_chan_no_defer, 159670db83c4SJohan Hedberg .suspend = l2cap_chan_no_suspend, 159770db83c4SJohan Hedberg .set_shutdown = l2cap_chan_no_set_shutdown, 159870db83c4SJohan Hedberg .get_sndtimeo = l2cap_chan_no_get_sndtimeo, 159970db83c4SJohan Hedberg .memcpy_fromiovec = l2cap_chan_no_memcpy_fromiovec, 160070db83c4SJohan Hedberg }; 160170db83c4SJohan Hedberg 160270db83c4SJohan Hedberg static inline struct l2cap_chan *smp_new_conn_cb(struct l2cap_chan *pchan) 160370db83c4SJohan Hedberg { 160470db83c4SJohan Hedberg struct l2cap_chan *chan; 160570db83c4SJohan Hedberg 160670db83c4SJohan Hedberg BT_DBG("pchan %p", pchan); 160770db83c4SJohan Hedberg 160870db83c4SJohan Hedberg chan = l2cap_chan_create(); 160970db83c4SJohan Hedberg if (!chan) 161070db83c4SJohan Hedberg return NULL; 161170db83c4SJohan Hedberg 161270db83c4SJohan Hedberg chan->chan_type = pchan->chan_type; 161370db83c4SJohan Hedberg chan->ops = &smp_chan_ops; 161470db83c4SJohan Hedberg chan->scid = pchan->scid; 161570db83c4SJohan Hedberg chan->dcid = chan->scid; 161670db83c4SJohan Hedberg chan->imtu = pchan->imtu; 161770db83c4SJohan Hedberg chan->omtu = pchan->omtu; 161870db83c4SJohan Hedberg chan->mode = pchan->mode; 161970db83c4SJohan Hedberg 162070db83c4SJohan Hedberg BT_DBG("created chan %p", chan); 162170db83c4SJohan Hedberg 162270db83c4SJohan Hedberg return chan; 162370db83c4SJohan Hedberg } 162470db83c4SJohan Hedberg 162570db83c4SJohan Hedberg static const struct l2cap_ops smp_root_chan_ops = { 162670db83c4SJohan Hedberg .name = "Security Manager Root", 162770db83c4SJohan Hedberg .new_connection = smp_new_conn_cb, 162870db83c4SJohan Hedberg 162970db83c4SJohan Hedberg /* None of these are implemented for the root channel */ 163070db83c4SJohan Hedberg .close = l2cap_chan_no_close, 163170db83c4SJohan Hedberg .alloc_skb = l2cap_chan_no_alloc_skb, 163270db83c4SJohan Hedberg .recv = l2cap_chan_no_recv, 163370db83c4SJohan Hedberg .state_change = l2cap_chan_no_state_change, 163470db83c4SJohan Hedberg .teardown = l2cap_chan_no_teardown, 163570db83c4SJohan Hedberg .ready = l2cap_chan_no_ready, 163670db83c4SJohan Hedberg .defer = l2cap_chan_no_defer, 163770db83c4SJohan Hedberg .suspend = l2cap_chan_no_suspend, 163870db83c4SJohan Hedberg .resume = l2cap_chan_no_resume, 163970db83c4SJohan Hedberg .set_shutdown = l2cap_chan_no_set_shutdown, 164070db83c4SJohan Hedberg .get_sndtimeo = l2cap_chan_no_get_sndtimeo, 164170db83c4SJohan Hedberg .memcpy_fromiovec = l2cap_chan_no_memcpy_fromiovec, 164270db83c4SJohan Hedberg }; 164370db83c4SJohan Hedberg 1644711eafe3SJohan Hedberg int smp_register(struct hci_dev *hdev) 1645711eafe3SJohan Hedberg { 164670db83c4SJohan Hedberg struct l2cap_chan *chan; 1647defce9e8SJohan Hedberg struct crypto_blkcipher *tfm_aes; 164870db83c4SJohan Hedberg 1649711eafe3SJohan Hedberg BT_DBG("%s", hdev->name); 1650711eafe3SJohan Hedberg 1651defce9e8SJohan Hedberg tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC); 1652defce9e8SJohan Hedberg if (IS_ERR(tfm_aes)) { 1653defce9e8SJohan Hedberg int err = PTR_ERR(tfm_aes); 1654711eafe3SJohan Hedberg BT_ERR("Unable to create crypto context"); 1655711eafe3SJohan Hedberg return err; 1656711eafe3SJohan Hedberg } 1657711eafe3SJohan Hedberg 165870db83c4SJohan Hedberg chan = l2cap_chan_create(); 165970db83c4SJohan Hedberg if (!chan) { 1660defce9e8SJohan Hedberg crypto_free_blkcipher(tfm_aes); 166170db83c4SJohan Hedberg return -ENOMEM; 166270db83c4SJohan Hedberg } 166370db83c4SJohan Hedberg 1664defce9e8SJohan Hedberg chan->data = tfm_aes; 1665defce9e8SJohan Hedberg 16665d88cc73SJohan Hedberg l2cap_add_scid(chan, L2CAP_CID_SMP); 166770db83c4SJohan Hedberg 166870db83c4SJohan Hedberg l2cap_chan_set_defaults(chan); 166970db83c4SJohan Hedberg 167070db83c4SJohan Hedberg bacpy(&chan->src, &hdev->bdaddr); 167170db83c4SJohan Hedberg chan->src_type = BDADDR_LE_PUBLIC; 167270db83c4SJohan Hedberg chan->state = BT_LISTEN; 167370db83c4SJohan Hedberg chan->mode = L2CAP_MODE_BASIC; 167470db83c4SJohan Hedberg chan->imtu = L2CAP_DEFAULT_MTU; 167570db83c4SJohan Hedberg chan->ops = &smp_root_chan_ops; 167670db83c4SJohan Hedberg 167770db83c4SJohan Hedberg hdev->smp_data = chan; 167870db83c4SJohan Hedberg 1679711eafe3SJohan Hedberg return 0; 1680711eafe3SJohan Hedberg } 1681711eafe3SJohan Hedberg 1682711eafe3SJohan Hedberg void smp_unregister(struct hci_dev *hdev) 1683711eafe3SJohan Hedberg { 168470db83c4SJohan Hedberg struct l2cap_chan *chan = hdev->smp_data; 1685defce9e8SJohan Hedberg struct crypto_blkcipher *tfm_aes; 168670db83c4SJohan Hedberg 168770db83c4SJohan Hedberg if (!chan) 168870db83c4SJohan Hedberg return; 168970db83c4SJohan Hedberg 169070db83c4SJohan Hedberg BT_DBG("%s chan %p", hdev->name, chan); 1691711eafe3SJohan Hedberg 1692defce9e8SJohan Hedberg tfm_aes = chan->data; 1693defce9e8SJohan Hedberg if (tfm_aes) { 1694defce9e8SJohan Hedberg chan->data = NULL; 1695defce9e8SJohan Hedberg crypto_free_blkcipher(tfm_aes); 1696711eafe3SJohan Hedberg } 169770db83c4SJohan Hedberg 169870db83c4SJohan Hedberg hdev->smp_data = NULL; 169970db83c4SJohan Hedberg l2cap_chan_put(chan); 1700711eafe3SJohan Hedberg } 1701