/* BlueZ - Bluetooth protocol stack for Linux Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation;
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED.
*/
/* Low-level debug macros to be used for stuff that we don't want * accidentally in dmesg, i.e. the values of the various crypto keys * and the inputs & outputs of crypto functions.
*/ #ifdef DEBUG #define SMP_DBG(fmt, ...) printk(KERN_DEBUG "%s: " fmt, __func__, \ ##__VA_ARGS__) #else #define SMP_DBG(fmt, ...) no_printk(KERN_DEBUG "%s: " fmt, __func__, \ ##__VA_ARGS__) #endif
err = aes_cmac(tfm_cmac, x, m, sizeof(m), res); if (err) return err;
SMP_DBG("res %16phN", res);
return err;
}
staticint smp_f5(struct crypto_shash *tfm_cmac, const u8 w[32], const u8 n1[16], const u8 n2[16], const u8 a1[7], const u8 a2[7], u8 mackey[16], u8 ltk[16])
{ /* The btle, salt and length "magic" values are as defined in * the SMP section of the Bluetooth core specification. In ASCII * the btle value ends up being 'btle'. The salt is just a * random number whereas length is the value 256 in little * endian format.
*/ const u8 btle[4] = { 0x65, 0x6c, 0x74, 0x62 }; const u8 salt[16] = { 0xbe, 0x83, 0x60, 0x5a, 0xdb, 0x0b, 0x37, 0x60,
0x38, 0xa5, 0xf5, 0xaa, 0x91, 0x83, 0x88, 0x6c }; const u8 length[2] = { 0x00, 0x01 };
u8 m[53], t[16]; int err;
/* The output of the random address function ah is: * ah(k, r) = e(k, r') mod 2^24 * The output of the security function e is then truncated to 24 bits * by taking the least significant 24 bits of the output of e as the * result of ah.
*/
memcpy(res, _res, 3);
int smp_generate_oob(struct hci_dev *hdev, u8 hash[16], u8 rand[16])
{ struct l2cap_chan *chan = hdev->smp_data; struct smp_dev *smp; int err;
if (!chan || !chan->data) return -EOPNOTSUPP;
smp = chan->data;
if (hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS)) {
bt_dev_dbg(hdev, "Using debug keys");
err = set_ecdh_privkey(smp->tfm_ecdh, debug_sk); if (err) return err;
memcpy(smp->local_pk, debug_pk, 64);
smp->debug_key = true;
} else { while (true) { /* Generate key pair for Secure Connections */
err = generate_ecdh_keys(smp->tfm_ecdh, smp->local_pk); if (err) return err;
/* This is unlikely, but we need to check that * we didn't accidentally generate a debug key.
*/ if (crypto_memneq(smp->local_pk, debug_pk, 64)) break;
}
smp->debug_key = false;
}
SMP_DBG("OOB Public Key X: %32phN", smp->local_pk);
SMP_DBG("OOB Public Key Y: %32phN", smp->local_pk + 32);
/* Ensure that we don't leave any debug key around if debug key * support hasn't been explicitly enabled.
*/ if (smp->ltk && smp->ltk->type == SMP_LTK_P256_DEBUG &&
!hci_dev_test_flag(hcon->hdev, HCI_KEEP_DEBUG_KEYS)) {
list_del_rcu(&smp->ltk->list);
kfree_rcu(smp->ltk, rcu);
smp->ltk = NULL;
}
/* If pairing failed clean up any keys we might have */ if (!complete) { if (smp->ltk) {
list_del_rcu(&smp->ltk->list);
kfree_rcu(smp->ltk, rcu);
}
if (smp->responder_ltk) {
list_del_rcu(&smp->responder_ltk->list);
kfree_rcu(smp->responder_ltk, rcu);
}
if (smp->remote_irk) {
list_del_rcu(&smp->remote_irk->list);
kfree_rcu(smp->remote_irk, rcu);
}
}
static u8 get_auth_method(struct smp_chan *smp, u8 local_io, u8 remote_io)
{ /* If either side has unknown io_caps, use JUST_CFM (which gets * converted later to JUST_WORKS if we're initiators.
*/ if (local_io > SMP_IO_KEYBOARD_DISPLAY ||
remote_io > SMP_IO_KEYBOARD_DISPLAY) return JUST_CFM;
if (test_bit(SMP_FLAG_SC, &smp->flags)) return sc_method[remote_io][local_io];
/* If neither side wants MITM, either "just" confirm an incoming * request or use just-works for outgoing ones. The JUST_CFM * will be converted to JUST_WORKS if necessary later in this * function. If either side has MITM look up the method from the * table.
*/ if (!(auth & SMP_AUTH_MITM))
smp->method = JUST_CFM; else
smp->method = get_auth_method(smp, local_io, remote_io);
/* Don't bother user space with no IO capabilities */ if (smp->method == JUST_CFM &&
hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
smp->method = JUST_WORKS;
/* If Just Works, Continue with Zero TK and ask user-space for
* confirmation */ if (smp->method == JUST_WORKS) {
ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
hcon->type,
hcon->dst_type,
passkey, 1); if (ret) return ret;
set_bit(SMP_FLAG_WAIT_USER, &smp->flags); return 0;
}
/* If this function is used for SC -> legacy fallback we * can only recover the just-works case.
*/ if (test_bit(SMP_FLAG_SC, &smp->flags)) return -EINVAL;
/* Not Just Works/Confirm results in MITM Authentication */ if (smp->method != JUST_CFM) {
set_bit(SMP_FLAG_MITM_AUTH, &smp->flags); if (hcon->pending_sec_level < BT_SECURITY_HIGH)
hcon->pending_sec_level = BT_SECURITY_HIGH;
}
/* If both devices have Keyboard-Display I/O, the initiator * Confirms and the responder Enters the passkey.
*/ if (smp->method == OVERLAP) { if (test_bit(SMP_FLAG_INITIATOR, &smp->flags))
smp->method = CFM_PASSKEY; else
smp->method = REQ_PASSKEY;
}
/* Even though there's no _RESPONDER suffix this is the * responder STK we're adding for later lookup (the initiator * STK never needs to be stored).
*/
hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
SMP_STK, auth, stk, smp->enc_key_size, ediv, rand);
}
if (hcon->type == ACL_LINK) { if (hcon->key_type == HCI_LK_DEBUG_COMBINATION)
persistent = false; else
persistent = !test_bit(HCI_CONN_FLUSH_KEY,
&hcon->flags);
} else { /* The LTKs, IRKs and CSRKs should be persistent only if * both sides had the bonding bit set in their * authentication requests.
*/
persistent = !!((req->auth_req & rsp->auth_req) &
SMP_AUTH_BONDING);
}
if (smp->remote_irk) {
mgmt_new_irk(hdev, smp->remote_irk, persistent);
/* Now that user space can be considered to know the * identity address track the connection based on it * from now on (assuming this is an LE link).
*/ if (hcon->type == LE_LINK) {
bacpy(&hcon->dst, &smp->remote_irk->bdaddr);
hcon->dst_type = smp->remote_irk->addr_type; /* Use a short delay to make sure the new address is * propagated _before_ the channels.
*/
queue_delayed_work(hdev->workqueue,
&conn->id_addr_timer,
ID_ADDR_TIMEOUT);
}
}
if (smp->link_key) { struct link_key *key;
u8 type;
if (test_bit(SMP_FLAG_DEBUG_KEY, &smp->flags))
type = HCI_LK_DEBUG_COMBINATION; elseif (hcon->sec_level == BT_SECURITY_FIPS)
type = HCI_LK_AUTH_COMBINATION_P256; else
type = HCI_LK_UNAUTH_COMBINATION_P256;
/* Don't keep debug keys around if the relevant * flag is not set.
*/ if (!hci_dev_test_flag(hdev, HCI_KEEP_DEBUG_KEYS) &&
key->type == HCI_LK_DEBUG_COMBINATION) {
list_del_rcu(&key->list);
kfree_rcu(key, rcu);
}
}
}
}
staticvoid smp_allow_key_dist(struct smp_chan *smp)
{ /* Allow the first expected phase 3 PDU. The rest of the PDUs * will be allowed in each PDU handler to ensure we receive * them in the correct order.
*/ if (smp->remote_key_dist & SMP_DIST_ENC_KEY)
SMP_ALLOW_CMD(smp, SMP_CMD_ENCRYPT_INFO); elseif (smp->remote_key_dist & SMP_DIST_ID_KEY)
SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO); elseif (smp->remote_key_dist & SMP_DIST_SIGN)
SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO);
}
staticvoid sc_generate_ltk(struct smp_chan *smp)
{ /* From core spec. Spells out in ASCII as 'brle'. */ const u8 brle[4] = { 0x65, 0x6c, 0x72, 0x62 }; struct hci_conn *hcon = smp->conn->hcon; struct hci_dev *hdev = hcon->hdev; struct link_key *key;
key = hci_find_link_key(hdev, &hcon->dst); if (!key) {
bt_dev_err(hdev, "no Link Key found to generate LTK"); return;
}
if (key->type == HCI_LK_DEBUG_COMBINATION)
set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags);
if (test_bit(SMP_FLAG_CT2, &smp->flags)) { /* SALT = 0x000000000000000000000000746D7032 */ const u8 salt[16] = { 0x32, 0x70, 0x6d, 0x74 };
if (smp_h7(smp->tfm_cmac, key->val, salt, smp->tk)) return;
} else { /* From core spec. Spells out in ASCII as 'tmp2'. */ const u8 tmp2[4] = { 0x32, 0x70, 0x6d, 0x74 };
if (smp_h6(smp->tfm_cmac, key->val, tmp2, smp->tk)) return;
}
if (smp_h6(smp->tfm_cmac, smp->tk, brle, smp->tk)) return;
/* The responder sends its keys first */ if (test_bit(SMP_FLAG_INITIATOR, &smp->flags) &&
(smp->remote_key_dist & KEY_DIST_MASK)) {
smp_allow_key_dist(smp); return;
}
/* Make sure we generate only the significant amount of * bytes based on the encryption key size, and set the rest * of the value to zeroes.
*/
get_random_bytes(enc.ltk, smp->enc_key_size);
memset(enc.ltk + smp->enc_key_size, 0, sizeof(enc.ltk) - smp->enc_key_size);
/* The hci_conn contains the local identity address * after the connection has been established. * * This is true even when the connection has been * established using a resolvable random address.
*/
bacpy(&addrinfo.bdaddr, &hcon->src);
addrinfo.addr_type = hcon->src_type;
/* Ignore the PDU if we've already done 20 rounds (0 - 19) */ if (smp->passkey_round >= 20) return 0;
switch (smp_op) { case SMP_CMD_PAIRING_RANDOM:
r = ((hcon->passkey_notify >> smp->passkey_round) & 0x01);
r |= 0x80;
if (smp_f4(smp->tfm_cmac, smp->remote_pk, smp->local_pk,
smp->rrnd, r, cfm)) return SMP_UNSPECIFIED;
if (crypto_memneq(smp->pcnf, cfm, 16)) return SMP_CONFIRM_FAILED;
smp->passkey_round++;
if (smp->passkey_round == 20) { /* Generate MacKey and LTK */ if (sc_mackey_and_ltk(smp, smp->mackey, smp->tk)) return SMP_UNSPECIFIED;
}
/* The round is only complete when the initiator * receives pairing random.
*/ if (!test_bit(SMP_FLAG_INITIATOR, &smp->flags)) {
smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd), smp->prnd); if (smp->passkey_round == 20)
SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK); else
SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); return 0;
}
/* Start the next round */ if (smp->passkey_round != 20) return sc_passkey_round(smp, 0);
switch (mgmt_op) { case MGMT_OP_USER_PASSKEY_REPLY:
value = le32_to_cpu(passkey);
memset(smp->tk, 0, sizeof(smp->tk));
bt_dev_dbg(conn->hcon->hdev, "PassKey: %u", value);
put_unaligned_le32(value, smp->tk);
fallthrough; case MGMT_OP_USER_CONFIRM_REPLY:
set_bit(SMP_FLAG_TK_VALID, &smp->flags); break; case MGMT_OP_USER_PASSKEY_NEG_REPLY: case MGMT_OP_USER_CONFIRM_NEG_REPLY:
smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
err = 0; goto unlock; default:
smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
err = -EOPNOTSUPP; goto unlock;
}
err = 0;
/* If it is our turn to send Pairing Confirm, do so now */ if (test_bit(SMP_FLAG_CFM_PENDING, &smp->flags)) {
u8 rsp = smp_confirm(smp); if (rsp)
smp_failure(conn, rsp);
}
/* If the remote side's OOB flag is set it means it has * successfully received our local OOB data - therefore set the * flag to indicate that local OOB is in use.
*/ if (req->oob_flag == SMP_OOB_PRESENT && SMP_DEV(hdev)->local_oob)
set_bit(SMP_FLAG_LOCAL_OOB, &smp->flags);
/* SMP over BR/EDR requires special treatment */ if (conn->hcon->type == ACL_LINK) { /* We must have a BR/EDR SC link */ if (!test_bit(HCI_CONN_AES_CCM, &conn->hcon->flags) &&
!hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP)) return SMP_CROSS_TRANSP_NOT_ALLOWED;
set_bit(SMP_FLAG_SC, &smp->flags);
build_bredr_pairing_cmd(smp, req, &rsp);
if (req->auth_req & SMP_AUTH_CT2)
set_bit(SMP_FLAG_CT2, &smp->flags);
key_size = min(req->max_key_size, rsp.max_key_size); if (check_enc_key_size(conn, key_size)) return SMP_ENC_KEY_SIZE;
/* Clear bits which are generated but not distributed */
smp->remote_key_dist &= ~SMP_SC_NO_DIST;
/* Strictly speaking we shouldn't allow Pairing Confirm for the * SC case, however some implementations incorrectly copy RFU auth * req bits from our security request, which may create a false * positive SC enablement.
*/
SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
if (test_bit(SMP_FLAG_SC, &smp->flags)) {
SMP_ALLOW_CMD(smp, SMP_CMD_PUBLIC_KEY); /* Clear bits which are generated but not distributed */
smp->remote_key_dist &= ~SMP_SC_NO_DIST; /* Wait for Public Key from Initiating Device */ return 0;
}
/* Request setup of TK */
ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability); if (ret) return SMP_UNSPECIFIED;
if (smp_dev->debug_key)
set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags);
goto done;
}
if (hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS)) {
bt_dev_dbg(hdev, "Using debug keys"); if (set_ecdh_privkey(smp->tfm_ecdh, debug_sk)) return SMP_UNSPECIFIED;
memcpy(smp->local_pk, debug_pk, 64);
set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags);
} else { while (true) { /* Generate key pair for Secure Connections */ if (generate_ecdh_keys(smp->tfm_ecdh, smp->local_pk)) return SMP_UNSPECIFIED;
/* This is unlikely, but we need to check that * we didn't accidentally generate a debug key.
*/ if (crypto_memneq(smp->local_pk, debug_pk, 64)) break;
}
}
done:
SMP_DBG("Local Public Key X: %32phN", smp->local_pk);
SMP_DBG("Local Public Key Y: %32phN", smp->local_pk + 32);
if (skb->len < sizeof(*rsp)) return SMP_INVALID_PARAMS;
if (!test_bit(SMP_FLAG_INITIATOR, &smp->flags)) return SMP_CMD_NOTSUPP;
skb_pull(skb, sizeof(*rsp));
req = (void *) &smp->preq[1];
key_size = min(req->max_key_size, rsp->max_key_size); if (check_enc_key_size(conn, key_size)) return SMP_ENC_KEY_SIZE;
auth = rsp->auth_req & AUTH_REQ_MASK(hdev);
if (hci_dev_test_flag(hdev, HCI_SC_ONLY) && !(auth & SMP_AUTH_SC)) return SMP_AUTH_REQUIREMENTS;
/* If the remote side's OOB flag is set it means it has * successfully received our local OOB data - therefore set the * flag to indicate that local OOB is in use.
*/ if (rsp->oob_flag == SMP_OOB_PRESENT && SMP_DEV(hdev)->local_oob)
set_bit(SMP_FLAG_LOCAL_OOB, &smp->flags);
/* Update remote key distribution in case the remote cleared * some bits that we had enabled in our request.
*/
smp->remote_key_dist &= rsp->resp_key_dist;
if ((req->auth_req & SMP_AUTH_CT2) && (auth & SMP_AUTH_CT2))
set_bit(SMP_FLAG_CT2, &smp->flags);
/* For BR/EDR this means we're done and can start phase 3 */ if (conn->hcon->type == ACL_LINK) { /* Clear bits which are generated but not distributed */
smp->remote_key_dist &= ~SMP_SC_NO_DIST;
smp_distribute_keys(smp); return 0;
}
/* Update remote key distribution in case the remote cleared * some bits that we had enabled in our request.
*/
smp->remote_key_dist &= rsp->resp_key_dist;
if (test_bit(SMP_FLAG_SC, &smp->flags)) { /* Clear bits which are generated but not distributed */
smp->remote_key_dist &= ~SMP_SC_NO_DIST;
SMP_ALLOW_CMD(smp, SMP_CMD_PUBLIC_KEY); return sc_send_public_key(smp);
}
auth |= req->auth_req;
ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability); if (ret) return SMP_UNSPECIFIED;
set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
/* Can't compose response until we have been confirmed */ if (test_bit(SMP_FLAG_TK_VALID, &smp->flags)) return smp_confirm(smp);
/* Work-around for some implementations that incorrectly copy RFU bits * from our security request and thereby create the impression that * we're doing SC when in fact the remote doesn't support it.
*/ staticint fixup_sc_false_positive(struct smp_chan *smp)
{ struct l2cap_conn *conn = smp->conn; struct hci_conn *hcon = conn->hcon; struct hci_dev *hdev = hcon->hdev; struct smp_cmd_pairing *req, *rsp;
u8 auth;
/* The issue is only observed when we're in responder role */ if (test_bit(SMP_FLAG_INITIATOR, &smp->flags)) return SMP_UNSPECIFIED;
if (hci_dev_test_flag(hdev, HCI_SC_ONLY)) {
bt_dev_err(hdev, "refusing legacy fallback in SC-only mode"); return SMP_UNSPECIFIED;
}
bt_dev_err(hdev, "trying to fall back to legacy SMP");
/* Rebuild key dist flags which may have been cleared for SC */
smp->remote_key_dist = (req->init_key_dist & rsp->resp_key_dist);
auth = req->auth_req & AUTH_REQ_MASK(hdev);
if (tk_request(conn, 0, auth, rsp->io_capability, req->io_capability)) {
bt_dev_err(hdev, "failed to fall back to legacy SMP"); return SMP_UNSPECIFIED;
}
/* Only Just-Works pairing requires extra checks */ if (smp->method != JUST_WORKS) goto mackey_and_ltk;
/* If there already exists long term key in local host, leave * the decision to user space since the remote device could * be legitimate or malicious.
*/ if (hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
hcon->role)) { /* Set passkey to 0. The value can be any number since * it'll be ignored anyway.
*/
passkey = 0;
confirm_hint = 1; goto confirm;
}
}
mackey_and_ltk: /* Generate MacKey and LTK */
err = sc_mackey_and_ltk(smp, smp->mackey, smp->tk); if (err) return SMP_UNSPECIFIED;
if (smp->method == REQ_OOB) { if (test_bit(SMP_FLAG_INITIATOR, &smp->flags)) {
sc_dhkey_check(smp);
SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
} return 0;
}
/* If we're encrypted with an STK but the caller prefers using * LTK claim insufficient security. This way we allow the * connection to be re-encrypted with an LTK, even if the LTK * provides the same level of security. Only exception is if we * don't have an LTK (e.g. because of key distribution bits).
*/ if (key_pref == SMP_USE_LTK &&
test_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags) &&
hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, hcon->role)) returnfalse;
if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK)) { /* If link is already encrypted with sufficient security we * still need refresh encryption as per Core Spec 5.0 Vol 3, * Part H 2.4.6
*/
smp_ltk_encrypt(conn, hcon->sec_level); return 0;
}
if (sec_level > hcon->pending_sec_level)
hcon->pending_sec_level = sec_level;
if (smp_ltk_encrypt(conn, hcon->pending_sec_level)) return 0;
smp = smp_chan_create(conn); if (!smp) return SMP_UNSPECIFIED;
if (!hci_dev_test_flag(hdev, HCI_BONDABLE) &&
(auth & SMP_AUTH_BONDING)) return SMP_PAIRING_NOTSUPP;
/* This may be NULL if there's an unexpected disconnection */ if (!conn) return 1;
if (!hci_dev_test_flag(hcon->hdev, HCI_LE_ENABLED)) return 1;
if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK)) return 1;
if (sec_level > hcon->pending_sec_level)
hcon->pending_sec_level = sec_level;
if (hcon->role == HCI_ROLE_MASTER) if (smp_ltk_encrypt(conn, hcon->pending_sec_level)) return 0;
chan = conn->smp; if (!chan) {
bt_dev_err(hcon->hdev, "security requested but not available"); return 1;
}
l2cap_chan_lock(chan);
/* If SMP is already in progress ignore this request */ if (chan->data) {
ret = 0; goto unlock;
}
smp = smp_chan_create(conn); if (!smp) {
ret = 1; goto unlock;
}
authreq = seclevel_to_authreq(sec_level);
if (hci_dev_test_flag(hcon->hdev, HCI_SC_ENABLED)) {
authreq |= SMP_AUTH_SC; if (hci_dev_test_flag(hcon->hdev, HCI_SSP_ENABLED))
authreq |= SMP_AUTH_CT2;
}
/* Don't attempt to set MITM if setting is overridden by debugfs * Needed to pass certification test SM/MAS/PKE/BV-01-C
*/ if (!hci_dev_test_flag(hcon->hdev, HCI_FORCE_NO_MITM)) { /* Require MITM if IO Capability allows or the security level * requires it.
*/ if (hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT ||
hcon->pending_sec_level > BT_SECURITY_MEDIUM)
authreq |= SMP_AUTH_MITM;
}
if (hcon->role == HCI_ROLE_MASTER)
smp_send_pairing_req(smp, authreq); else
smp_send_security_req(smp, authreq);
hcon = hci_conn_hash_lookup_le(hdev, bdaddr, addr_type); if (!hcon) goto done;
conn = hcon->l2cap_data; if (!conn) goto done;
chan = conn->smp; if (!chan) goto done;
l2cap_chan_lock(chan);
smp = chan->data; if (smp) { /* Set keys to NULL to make sure smp_failure() does not try to
* remove and free already invalidated rcu list entries. */
smp->ltk = NULL;
smp->responder_ltk = NULL;
smp->remote_irk = NULL;
if (skb->len < sizeof(*rp)) return SMP_INVALID_PARAMS;
/* Pairing is aborted if any blocked keys are distributed */ if (hci_is_blocked_key(conn->hcon->hdev, HCI_BLOCKED_KEY_TYPE_LTK,
rp->ltk)) {
bt_dev_warn_ratelimited(conn->hcon->hdev, "LTK blocked for %pMR",
&conn->hcon->dst); return SMP_INVALID_PARAMS;
}
if (skb->len < sizeof(*info)) return SMP_INVALID_PARAMS;
/* Pairing is aborted if any blocked keys are distributed */ if (hci_is_blocked_key(conn->hcon->hdev, HCI_BLOCKED_KEY_TYPE_IRK,
info->irk)) {
bt_dev_warn_ratelimited(conn->hcon->hdev, "Identity key blocked for %pMR",
&conn->hcon->dst); return SMP_INVALID_PARAMS;
}
if (skb->len < sizeof(*info)) return SMP_INVALID_PARAMS;
/* Mark the information as received */
smp->remote_key_dist &= ~SMP_DIST_ID_KEY;
if (smp->remote_key_dist & SMP_DIST_SIGN)
SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO);
skb_pull(skb, sizeof(*info));
/* Strictly speaking the Core Specification (4.1) allows sending * an empty address which would force us to rely on just the IRK * as "identity information". However, since such * implementations are not known of and in order to not over * complicate our implementation, simply pretend that we never * received an IRK for such a device. * * The Identity Address must also be a Static Random or Public * Address, which hci_is_identity_address() checks for.
*/ if (!bacmp(&info->bdaddr, BDADDR_ANY) ||
!hci_is_identity_address(&info->bdaddr, info->addr_type)) {
bt_dev_err(hcon->hdev, "ignoring IRK with no identity address"); goto distribute;
}
/* Drop IRK if peer is using identity address during pairing but is * providing different address as identity information. * * Microsoft Surface Precision Mouse is known to have this bug.
*/ if (hci_is_identity_address(&hcon->dst, hcon->dst_type) &&
(bacmp(&info->bdaddr, &hcon->dst) ||
info->addr_type != hcon->dst_type)) {
bt_dev_err(hcon->hdev, "ignoring IRK with invalid identity address"); goto distribute;
}
if (test_bit(SMP_FLAG_REMOTE_OOB, &smp->flags) ||
test_bit(SMP_FLAG_LOCAL_OOB, &smp->flags)) return REQ_OOB;
/* The preq/prsp contain the raw Pairing Request/Response PDUs * which are needed as inputs to some crypto functions. To get * the "struct smp_cmd_pairing" from them we need to skip the * first byte which contains the opcode.
*/ if (test_bit(SMP_FLAG_INITIATOR, &smp->flags)) {
local = (void *) &smp->preq[1];
remote = (void *) &smp->prsp[1];
} else {
local = (void *) &smp->prsp[1];
remote = (void *) &smp->preq[1];
}
/* If either side wants MITM, look up the method from the table, * otherwise use JUST WORKS.
*/ if (local_mitm || remote_mitm)
method = get_auth_method(smp, local_io, remote_io); else
method = JUST_WORKS;
if (skb->len < sizeof(*key)) return SMP_INVALID_PARAMS;
/* Check if remote and local public keys are the same and debug key is * not in use.
*/ if (!test_bit(SMP_FLAG_DEBUG_KEY, &smp->flags) &&
!crypto_memneq(key, smp->local_pk, 64)) {
bt_dev_err(hdev, "Remote and local public keys are identical"); return SMP_UNSPECIFIED;
}
memcpy(smp->remote_pk, key, 64);
if (test_bit(SMP_FLAG_REMOTE_OOB, &smp->flags)) {
err = smp_f4(smp->tfm_cmac, smp->remote_pk, smp->remote_pk,
smp->rr, 0, cfm.confirm_val); if (err) return SMP_UNSPECIFIED;
if (crypto_memneq(cfm.confirm_val, smp->pcnf, 16)) return SMP_CONFIRM_FAILED;
}
/* Non-initiating device sends its public key after receiving * the key from the initiating device.
*/ if (!test_bit(SMP_FLAG_INITIATOR, &smp->flags)) {
err = sc_send_public_key(smp); if (err) return err;
}
SMP_DBG("Remote Public Key X: %32phN", smp->remote_pk);
SMP_DBG("Remote Public Key Y: %32phN", smp->remote_pk + 32);
/* Compute the shared secret on the same crypto tfm on which the private * key was set/generated.
*/ if (test_bit(SMP_FLAG_LOCAL_OOB, &smp->flags)) { struct l2cap_chan *hchan = hdev->smp_data; struct smp_dev *smp_dev;
if (!hchan || !hchan->data) return SMP_UNSPECIFIED;
/* JUST_WORKS and JUST_CFM result in an unauthenticated key */ if (smp->method == JUST_WORKS || smp->method == JUST_CFM)
hcon->pending_sec_level = BT_SECURITY_MEDIUM; else
hcon->pending_sec_level = BT_SECURITY_FIPS;
if (!crypto_memneq(debug_pk, smp->remote_pk, 64))
set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags);
if (!hci_dev_test_flag(hcon->hdev, HCI_LE_ENABLED)) {
reason = SMP_PAIRING_NOTSUPP; goto done;
}
code = skb->data[0];
skb_pull(skb, sizeof(code));
smp = chan->data;
if (code > SMP_CMD_MAX) goto drop;
if (smp && !test_and_clear_bit(code, &smp->allow_cmd)) { /* If there is a context and the command is not allowed consider * it a failure so the session is cleanup properly.
*/ switch (code) { case SMP_CMD_IDENT_INFO: case SMP_CMD_IDENT_ADDR_INFO: case SMP_CMD_SIGN_INFO: /* 3.6.1. Key distribution and generation * * A device may reject a distributed key by sending the * Pairing Failed command with the reason set to * "Key Rejected".
*/
smp_failure(conn, SMP_KEY_REJECTED); break;
} goto drop;
}
/* If we don't have a context the only allowed commands are * pairing request and security request.
*/ if (!smp && code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ) goto drop;
switch (code) { case SMP_CMD_PAIRING_REQ:
reason = smp_cmd_pairing_req(conn, skb); break;
case SMP_CMD_PAIRING_FAIL:
smp_failure(conn, 0);
err = -EPERM; break;
case SMP_CMD_PAIRING_RSP:
reason = smp_cmd_pairing_rsp(conn, skb); break;
case SMP_CMD_SECURITY_REQ:
reason = smp_cmd_security_req(conn, skb); break;
case SMP_CMD_PAIRING_CONFIRM:
reason = smp_cmd_pairing_confirm(conn, skb); break;
case SMP_CMD_PAIRING_RANDOM:
reason = smp_cmd_pairing_random(conn, skb); break;
case SMP_CMD_ENCRYPT_INFO:
reason = smp_cmd_encrypt_info(conn, skb); break;
case SMP_CMD_INITIATOR_IDENT:
reason = smp_cmd_initiator_ident(conn, skb); break;
case SMP_CMD_IDENT_INFO:
reason = smp_cmd_ident_info(conn, skb); break;
case SMP_CMD_IDENT_ADDR_INFO:
reason = smp_cmd_ident_addr_info(conn, skb); break;
case SMP_CMD_SIGN_INFO:
reason = smp_cmd_sign_info(conn, skb); break;
case SMP_CMD_PUBLIC_KEY:
reason = smp_cmd_public_key(conn, skb); break;
case SMP_CMD_DHKEY_CHECK:
reason = smp_cmd_dhkey_check(conn, skb); break;
case SMP_CMD_KEYPRESS_NOTIFY:
reason = smp_cmd_keypress_notify(conn, skb); break;
/* Only new pairings are interesting */ if (!test_bit(HCI_CONN_NEW_LINK_KEY, &hcon->flags)) return;
/* Don't bother if we're not encrypted */ if (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags)) return;
/* Only initiator may initiate SMP over BR/EDR */ if (hcon->role != HCI_ROLE_MASTER) return;
/* Secure Connections support must be enabled */ if (!hci_dev_test_flag(hdev, HCI_SC_ENABLED)) return;
/* BR/EDR must use Secure Connections for SMP */ if (!test_bit(HCI_CONN_AES_CCM, &hcon->flags) &&
!hci_dev_test_flag(hdev, HCI_FORCE_BREDR_SMP)) return;
/* If our LE support is not enabled don't do anything */ if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED)) return;
/* Don't bother if remote LE support is not enabled */ if (!lmp_host_le_capable(hcon)) return;
/* Remote must support SMP fixed chan for BR/EDR */ if (!(conn->remote_fixed_chan & L2CAP_FC_SMP_BREDR)) return;
/* Don't bother if SMP is already ongoing */ if (chan->data) return;
smp = smp_chan_create(conn); if (!smp) {
bt_dev_err(hdev, "unable to create SMP context for BR/EDR"); return;
}
/* No need to call l2cap_chan_hold() here since we already own * the reference taken in smp_new_conn_cb(). This is just the * first time that we tie it to a specific pointer. The code in * l2cap_core.c ensures that there's no risk this function won't * get called if smp_new_conn_cb was previously called.
*/
conn->smp = chan;
if (hcon->type == ACL_LINK && test_bit(HCI_CONN_ENCRYPT, &hcon->flags))
bredr_pairing(chan);
}
staticint smp_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
{ int err;
/* Other L2CAP channels may request SMP routines in order to * change the security level. This means that the SMP channel * lock must be considered in its own category to avoid lockdep * warnings.
*/
atomic_set(&chan->nesting, L2CAP_NESTING_SMP);
int smp_register(struct hci_dev *hdev)
{ struct l2cap_chan *chan;
bt_dev_dbg(hdev, "");
/* If the controller does not support Low Energy operation, then * there is also no need to register any SMP channel.
*/ if (!lmp_le_capable(hdev)) return 0;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.