Bluetooth: Fix central from failing to start encryption

This fixes a regression introduced in commit 6af5d1cd1f
("Bluetooth: Compress bt_keys struct").

Instead of passing a value zero as the random number, the
value at the RAM address zero was being used by the start
encryption function call. It is now fixed by consistently
using byte-array to store EDiv and Rand values.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
Vinayak Kariappa Chettimada 2018-06-22 10:34:45 +02:00 committed by Johan Hedberg
commit b35ed7e79c
6 changed files with 31 additions and 21 deletions

View file

@ -785,8 +785,8 @@ void bt_conn_identity_resolved(struct bt_conn *conn)
}
}
int bt_conn_le_start_encryption(struct bt_conn *conn, u8_t rand[8], u16_t ediv,
const u8_t *ltk, size_t len)
int bt_conn_le_start_encryption(struct bt_conn *conn, u8_t rand[8],
u8_t ediv[2], const u8_t *ltk, size_t len)
{
struct bt_hci_cp_le_start_encryption *cp;
struct net_buf *buf;
@ -799,7 +799,7 @@ int bt_conn_le_start_encryption(struct bt_conn *conn, u8_t rand[8], u16_t ediv,
cp = net_buf_add(buf, sizeof(*cp));
cp->handle = sys_cpu_to_le16(conn->handle);
memcpy(&cp->rand, rand, sizeof(cp->rand));
cp->ediv = ediv;
memcpy(&cp->ediv, ediv, sizeof(cp->ediv));
memcpy(cp->ltk, ltk, len);
if (len < sizeof(cp->ltk)) {

View file

@ -194,8 +194,8 @@ bool le_param_req(struct bt_conn *conn, struct bt_le_conn_param *param);
#if defined(CONFIG_BT_SMP)
/* rand and ediv should be in BT order */
int bt_conn_le_start_encryption(struct bt_conn *conn, u8_t rand[8], u16_t ediv,
const u8_t *ltk, size_t len);
int bt_conn_le_start_encryption(struct bt_conn *conn, u8_t rand[8],
u8_t ediv[2], const u8_t *ltk, size_t len);
/* Notify higher layers that RPA was resolved */
void bt_conn_identity_resolved(struct bt_conn *conn);

View file

@ -2843,7 +2843,7 @@ static void le_ltk_request(struct net_buf *buf)
#if !defined(CONFIG_BT_SMP_SC_ONLY)
if (conn->le.keys && (conn->le.keys->keys & BT_KEYS_SLAVE_LTK) &&
!memcmp(conn->le.keys->slave_ltk.rand, &evt->rand, 8) &&
conn->le.keys->slave_ltk.ediv == evt->ediv) {
!memcmp(conn->le.keys->slave_ltk.ediv, &evt->ediv, 2)) {
buf = bt_hci_cmd_create(BT_HCI_OP_LE_LTK_REQ_REPLY,
sizeof(*cp));
if (!buf) {

View file

@ -28,7 +28,7 @@ enum {
struct bt_ltk {
u8_t rand[8];
u16_t ediv;
u8_t ediv[2];
u8_t val[16];
};

View file

@ -835,7 +835,7 @@ static void smp_br_derive_ltk(struct bt_smp_br *smp)
return;
}
keys->ltk.ediv = 0;
memset(keys->ltk.ediv, 0, sizeof(keys->ltk.ediv));
memset(keys->ltk.rand, 0, sizeof(keys->ltk.rand));
keys->enc_size = smp->enc_key_size;
@ -1676,8 +1676,8 @@ static void legacy_distribute_keys(struct bt_smp *smp)
struct bt_smp_master_ident *ident;
struct net_buf *buf;
u8_t key[16];
u64_t rand;
u16_t ediv;
u8_t rand[8];
u8_t ediv[2];
bt_rand(key, sizeof(key));
bt_rand(&rand, sizeof(rand));
@ -1709,8 +1709,8 @@ static void legacy_distribute_keys(struct bt_smp *smp)
}
ident = net_buf_add(buf, sizeof(*ident));
ident->rand = rand;
ident->ediv = ediv;
memcpy(ident->rand, rand, sizeof(ident->rand));
memcpy(ident->ediv, ediv, sizeof(ident->ediv));
smp_send(smp, buf, ident_sent);
@ -1719,8 +1719,9 @@ static void legacy_distribute_keys(struct bt_smp *smp)
memcpy(keys->slave_ltk.val, key,
sizeof(keys->slave_ltk.val));
memcpy(keys->slave_ltk.rand, &rand, sizeof(rand));
keys->slave_ltk.ediv = ediv;
memcpy(keys->slave_ltk.rand, rand, sizeof(rand));
memcpy(keys->slave_ltk.ediv, ediv,
sizeof(keys->slave_ltk.ediv));
}
}
}
@ -1998,6 +1999,8 @@ static u8_t legacy_pairing_random(struct bt_smp *smp)
if (IS_ENABLED(CONFIG_BT_CENTRAL) &&
conn->role == BT_HCI_ROLE_MASTER) {
u8_t ediv[2], rand[8];
/* No need to store master STK */
err = smp_s1(smp->tk, smp->rrnd, smp->prnd, tmp);
if (err) {
@ -2005,7 +2008,9 @@ static u8_t legacy_pairing_random(struct bt_smp *smp)
}
/* Rand and EDiv are 0 for the STK */
if (bt_conn_le_start_encryption(conn, 0, 0, tmp,
memset(ediv, 0, sizeof(ediv));
memset(rand, 0, sizeof(rand));
if (bt_conn_le_start_encryption(conn, rand, ediv, tmp,
get_encryption_key_size(smp))) {
BT_ERR("Failed to start encryption");
return BT_SMP_ERR_UNSPECIFIED;
@ -2123,8 +2128,8 @@ static u8_t smp_master_ident(struct bt_smp *smp, struct net_buf *buf)
return BT_SMP_ERR_UNSPECIFIED;
}
keys->ltk.ediv = req->ediv;
memcpy(keys->ltk.rand, &req->rand, sizeof(req->rand));
memcpy(keys->ltk.ediv, req->ediv, sizeof(keys->ltk.ediv));
memcpy(keys->ltk.rand, req->rand, sizeof(req->rand));
smp->remote_dist &= ~BT_SMP_DIST_ENC_KEY;
}
@ -3325,6 +3330,7 @@ static u8_t smp_dhkey_check(struct bt_smp *smp, struct net_buf *buf)
if (IS_ENABLED(CONFIG_BT_CENTRAL) &&
smp->chan.chan.conn->role == BT_HCI_ROLE_MASTER) {
u8_t e[16], r[16], enc_size;
u8_t ediv[2], rand[8];
memset(r, 0, sizeof(r));
@ -3353,7 +3359,10 @@ static u8_t smp_dhkey_check(struct bt_smp *smp, struct net_buf *buf)
enc_size = get_encryption_key_size(smp);
if (bt_conn_le_start_encryption(smp->chan.chan.conn, 0, 0,
/* Rand and EDiv are 0 */
memset(ediv, 0, sizeof(ediv));
memset(rand, 0, sizeof(rand));
if (bt_conn_le_start_encryption(smp->chan.chan.conn, rand, ediv,
smp->tk, enc_size) < 0) {
return BT_SMP_ERR_UNSPECIFIED;
}
@ -4384,7 +4393,8 @@ void bt_smp_update_keys(struct bt_conn *conn)
sizeof(conn->le.keys->ltk.val));
memset(conn->le.keys->ltk.rand, 0,
sizeof(conn->le.keys->ltk.rand));
conn->le.keys->ltk.ediv = 0;
memset(conn->le.keys->ltk.ediv, 0,
sizeof(conn->le.keys->ltk.ediv));
}
}

View file

@ -87,8 +87,8 @@ struct bt_smp_encrypt_info {
#define BT_SMP_CMD_MASTER_IDENT 0x07
struct bt_smp_master_ident {
u16_t ediv;
u64_t rand;
u8_t ediv[2];
u8_t rand[8];
} __packed;
#define BT_SMP_CMD_IDENT_INFO 0x08