Skip to content

Commit

Permalink
Bluetooth: Fix encryption key size handling for LTKs
Browse files Browse the repository at this point in the history
The encryption key size for LTKs is supposed to be applied only at the
moment of encryption. When generating a Link Key (using LE SC) from
the LTK the full non-shortened value should be used. This patch
modifies the code to always keep the full value around and only apply
the key size when passing the value to HCI.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
  • Loading branch information
Johan Hedberg authored and Marcel Holtmann committed Jun 9, 2015
1 parent 2eeac87 commit 8b76ce3
Show file tree
Hide file tree
Showing 4 changed files with 8 additions and 16 deletions.
2 changes: 1 addition & 1 deletion include/net/bluetooth/hci_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -1408,7 +1408,7 @@ void mgmt_smp_complete(struct hci_conn *conn, bool complete);
u8 hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, u16 latency,
u16 to_multiplier);
void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __le64 rand,
__u8 ltk[16]);
__u8 ltk[16], __u8 key_size);

void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 *bdaddr_type);
Expand Down
4 changes: 2 additions & 2 deletions net/bluetooth/hci_conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ u8 hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, u16 latency,
}

void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __le64 rand,
__u8 ltk[16])
__u8 ltk[16], __u8 key_size)
{
struct hci_dev *hdev = conn->hdev;
struct hci_cp_le_start_enc cp;
Expand All @@ -288,7 +288,7 @@ void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __le64 rand,
cp.handle = cpu_to_le16(conn->handle);
cp.rand = rand;
cp.ediv = ediv;
memcpy(cp.ltk, ltk, sizeof(cp.ltk));
memcpy(cp.ltk, ltk, key_size);

hci_send_cmd(hdev, HCI_OP_LE_START_ENC, sizeof(cp), &cp);
}
Expand Down
3 changes: 2 additions & 1 deletion net/bluetooth/hci_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -4955,7 +4955,8 @@ static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
goto not_found;
}

memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
memcpy(cp.ltk, ltk->val, ltk->enc_size);
memset(cp.ltk + ltk->enc_size, 0, sizeof(cp.ltk) - ltk->enc_size);
cp.handle = cpu_to_le16(conn->handle);

conn->pending_sec_level = smp_ltk_sec_level(ltk);
Expand Down
15 changes: 3 additions & 12 deletions net/bluetooth/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -997,13 +997,10 @@ static u8 smp_random(struct smp_chan *smp)

smp_s1(smp->tfm_aes, smp->tk, smp->rrnd, smp->prnd, stk);

memset(stk + smp->enc_key_size, 0,
SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);

if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
return SMP_UNSPECIFIED;

hci_le_start_enc(hcon, ediv, rand, stk);
hci_le_start_enc(hcon, ediv, rand, stk, smp->enc_key_size);
hcon->enc_key_size = smp->enc_key_size;
set_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags);
} else {
Expand All @@ -1016,9 +1013,6 @@ static u8 smp_random(struct smp_chan *smp)

smp_s1(smp->tfm_aes, smp->tk, smp->prnd, smp->rrnd, stk);

memset(stk + smp->enc_key_size, 0,
SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);

if (hcon->pending_sec_level == BT_SECURITY_HIGH)
auth = 1;
else
Expand Down Expand Up @@ -1156,9 +1150,6 @@ static void sc_add_ltk(struct smp_chan *smp)
else
auth = 0;

memset(smp->tk + smp->enc_key_size, 0,
SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);

smp->ltk = hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
key_type, auth, smp->tk, smp->enc_key_size,
0, 0);
Expand Down Expand Up @@ -2202,7 +2193,7 @@ static bool smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
return true;

hci_le_start_enc(hcon, key->ediv, key->rand, key->val);
hci_le_start_enc(hcon, key->ediv, key->rand, key->val, key->enc_size);
hcon->enc_key_size = key->enc_size;

/* We never store STKs for master role, so clear this flag */
Expand Down Expand Up @@ -2750,7 +2741,7 @@ static int smp_cmd_dhkey_check(struct l2cap_conn *conn, struct sk_buff *skb)
sc_add_ltk(smp);

if (hcon->out) {
hci_le_start_enc(hcon, 0, 0, smp->tk);
hci_le_start_enc(hcon, 0, 0, smp->tk, smp->enc_key_size);
hcon->enc_key_size = smp->enc_key_size;
}

Expand Down

0 comments on commit 8b76ce3

Please sign in to comment.