Bluetooth: Compress bt_keys struct
There's a bit of unnecessary space in the bt_keys struct. Re-design some fields for a more compact format, which is particularly helpful now that the struct gets stored as-is to flash through the settings API. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
parent
f36ea83628
commit
6af5d1cd1f
5 changed files with 50 additions and 62 deletions
|
@ -785,8 +785,8 @@ void bt_conn_identity_resolved(struct bt_conn *conn)
|
|||
}
|
||||
}
|
||||
|
||||
int bt_conn_le_start_encryption(struct bt_conn *conn, u64_t rand,
|
||||
u16_t ediv, const u8_t *ltk, size_t len)
|
||||
int bt_conn_le_start_encryption(struct bt_conn *conn, u8_t rand[8], u16_t ediv,
|
||||
const u8_t *ltk, size_t len)
|
||||
{
|
||||
struct bt_hci_cp_le_start_encryption *cp;
|
||||
struct net_buf *buf;
|
||||
|
@ -798,7 +798,7 @@ int bt_conn_le_start_encryption(struct bt_conn *conn, u64_t rand,
|
|||
|
||||
cp = net_buf_add(buf, sizeof(*cp));
|
||||
cp->handle = sys_cpu_to_le16(conn->handle);
|
||||
cp->rand = rand;
|
||||
memcpy(&cp->rand, rand, sizeof(cp->rand));
|
||||
cp->ediv = ediv;
|
||||
|
||||
memcpy(cp->ltk, ltk, len);
|
||||
|
@ -906,14 +906,12 @@ static int start_security(struct bt_conn *conn)
|
|||
}
|
||||
|
||||
if (conn->required_sec_level > BT_SECURITY_MEDIUM &&
|
||||
!atomic_test_bit(conn->le.keys->flags,
|
||||
BT_KEYS_AUTHENTICATED)) {
|
||||
!(conn->le.keys->flags & BT_KEYS_AUTHENTICATED)) {
|
||||
return bt_smp_send_pairing_req(conn);
|
||||
}
|
||||
|
||||
if (conn->required_sec_level > BT_SECURITY_HIGH &&
|
||||
!atomic_test_bit(conn->le.keys->flags,
|
||||
BT_KEYS_AUTHENTICATED) &&
|
||||
!(conn->le.keys->flags & BT_KEYS_AUTHENTICATED) &&
|
||||
!(conn->le.keys->keys & BT_KEYS_LTK_P256)) {
|
||||
return bt_smp_send_pairing_req(conn);
|
||||
}
|
||||
|
|
|
@ -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, u64_t rand,
|
||||
u16_t ediv, const u8_t *ltk, size_t len);
|
||||
int bt_conn_le_start_encryption(struct bt_conn *conn, u8_t rand[8], u16_t ediv,
|
||||
const u8_t *ltk, size_t len);
|
||||
|
||||
/* Notify higher layers that RPA was resolved */
|
||||
void bt_conn_identity_resolved(struct bt_conn *conn);
|
||||
|
|
|
@ -732,12 +732,14 @@ static void update_conn_param(struct bt_conn *conn)
|
|||
#if defined(CONFIG_BT_SMP)
|
||||
static void update_pending_id(struct bt_keys *keys)
|
||||
{
|
||||
if (atomic_test_and_clear_bit(keys->flags, BT_KEYS_ID_PENDING_ADD)) {
|
||||
if (keys->flags & BT_KEYS_ID_PENDING_ADD) {
|
||||
keys->flags &= ~BT_KEYS_ID_PENDING_ADD;
|
||||
bt_id_add(keys);
|
||||
return;
|
||||
}
|
||||
|
||||
if (atomic_test_and_clear_bit(keys->flags, BT_KEYS_ID_PENDING_DEL)) {
|
||||
if (keys->flags & BT_KEYS_ID_PENDING_DEL) {
|
||||
keys->flags &= ~BT_KEYS_ID_PENDING_DEL;
|
||||
bt_id_del(keys);
|
||||
return;
|
||||
}
|
||||
|
@ -1459,8 +1461,7 @@ static void update_sec_level_br(struct bt_conn *conn)
|
|||
}
|
||||
|
||||
if (conn->br.link_key) {
|
||||
if (atomic_test_bit(conn->br.link_key->flags,
|
||||
BT_LINK_KEY_AUTHENTICATED)) {
|
||||
if (conn->br.link_key->flags & BT_LINK_KEY_AUTHENTICATED) {
|
||||
if (conn->encrypt == 0x02) {
|
||||
conn->sec_level = BT_SECURITY_FIPS;
|
||||
} else {
|
||||
|
@ -1587,7 +1588,7 @@ static void link_key_notify(struct net_buf *buf)
|
|||
}
|
||||
|
||||
/* clear any old Link Key flags */
|
||||
atomic_set(conn->br.link_key->flags, 0);
|
||||
conn->br.link_key->flags = 0;
|
||||
|
||||
switch (evt->key_type) {
|
||||
case BT_LK_COMBINATION:
|
||||
|
@ -1597,14 +1598,12 @@ static void link_key_notify(struct net_buf *buf)
|
|||
*/
|
||||
if (atomic_test_and_clear_bit(conn->flags,
|
||||
BT_CONN_BR_LEGACY_SECURE)) {
|
||||
atomic_set_bit(conn->br.link_key->flags,
|
||||
BT_LINK_KEY_AUTHENTICATED);
|
||||
conn->br.link_key->flags |= BT_LINK_KEY_AUTHENTICATED;
|
||||
}
|
||||
memcpy(conn->br.link_key->val, evt->link_key, 16);
|
||||
break;
|
||||
case BT_LK_AUTH_COMBINATION_P192:
|
||||
atomic_set_bit(conn->br.link_key->flags,
|
||||
BT_LINK_KEY_AUTHENTICATED);
|
||||
conn->br.link_key->flags |= BT_LINK_KEY_AUTHENTICATED;
|
||||
/* fall through */
|
||||
case BT_LK_UNAUTH_COMBINATION_P192:
|
||||
/* Mark no-bond so that link-key is removed on disconnection */
|
||||
|
@ -1615,11 +1614,10 @@ static void link_key_notify(struct net_buf *buf)
|
|||
memcpy(conn->br.link_key->val, evt->link_key, 16);
|
||||
break;
|
||||
case BT_LK_AUTH_COMBINATION_P256:
|
||||
atomic_set_bit(conn->br.link_key->flags,
|
||||
BT_LINK_KEY_AUTHENTICATED);
|
||||
conn->br.link_key->flags |= BT_LINK_KEY_AUTHENTICATED;
|
||||
/* fall through */
|
||||
case BT_LK_UNAUTH_COMBINATION_P256:
|
||||
atomic_set_bit(conn->br.link_key->flags, BT_LINK_KEY_SC);
|
||||
conn->br.link_key->flags |= BT_LINK_KEY_SC;
|
||||
|
||||
/* Mark no-bond so that link-key is removed on disconnection */
|
||||
if (bt_conn_ssp_get_auth(conn) < BT_HCI_DEDICATED_BONDING) {
|
||||
|
@ -1703,8 +1701,7 @@ static void link_key_req(struct net_buf *buf)
|
|||
* Enforce regenerate by controller stronger link key since found one
|
||||
* in database not covers requested security level.
|
||||
*/
|
||||
if (!atomic_test_bit(conn->br.link_key->flags,
|
||||
BT_LINK_KEY_AUTHENTICATED) &&
|
||||
if (!(conn->br.link_key->flags & BT_LINK_KEY_AUTHENTICATED) &&
|
||||
conn->required_sec_level > BT_SECURITY_MEDIUM) {
|
||||
link_key_neg_reply(&evt->bdaddr);
|
||||
bt_conn_unref(conn);
|
||||
|
@ -2431,7 +2428,7 @@ int bt_id_add(struct bt_keys *keys)
|
|||
conn = bt_conn_lookup_state_le(NULL, BT_CONN_CONNECT);
|
||||
if (conn) {
|
||||
atomic_set_bit(bt_dev.flags, BT_DEV_ID_PENDING);
|
||||
atomic_set_bit(keys->flags, BT_KEYS_ID_PENDING_ADD);
|
||||
keys->flags |= BT_KEYS_ID_PENDING_ADD;
|
||||
bt_conn_unref(conn);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
@ -2533,7 +2530,7 @@ int bt_id_del(struct bt_keys *keys)
|
|||
conn = bt_conn_lookup_state_le(NULL, BT_CONN_CONNECT);
|
||||
if (conn) {
|
||||
atomic_set_bit(bt_dev.flags, BT_DEV_ID_PENDING);
|
||||
atomic_set_bit(keys->flags, BT_KEYS_ID_PENDING_DEL);
|
||||
keys->flags |= BT_KEYS_ID_PENDING_DEL;
|
||||
bt_conn_unref(conn);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
@ -2603,8 +2600,7 @@ static void update_sec_level(struct bt_conn *conn)
|
|||
return;
|
||||
}
|
||||
|
||||
if (conn->le.keys && atomic_test_bit(conn->le.keys->flags,
|
||||
BT_KEYS_AUTHENTICATED)) {
|
||||
if (conn->le.keys && (conn->le.keys->flags & BT_KEYS_AUTHENTICATED)) {
|
||||
if (conn->le.keys->keys & BT_KEYS_LTK_P256) {
|
||||
conn->sec_level = BT_SECURITY_FIPS;
|
||||
} else {
|
||||
|
@ -2833,7 +2829,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) &&
|
||||
conn->le.keys->slave_ltk.rand == evt->rand &&
|
||||
!memcmp(conn->le.keys->slave_ltk.rand, &evt->rand, 8) &&
|
||||
conn->le.keys->slave_ltk.ediv == evt->ediv) {
|
||||
buf = bt_hci_cmd_create(BT_HCI_OP_LE_LTK_REQ_REPLY,
|
||||
sizeof(*cp));
|
||||
|
|
|
@ -20,17 +20,14 @@ enum {
|
|||
};
|
||||
|
||||
enum {
|
||||
BT_KEYS_AUTHENTICATED,
|
||||
BT_KEYS_DEBUG,
|
||||
BT_KEYS_ID_PENDING_ADD,
|
||||
BT_KEYS_ID_PENDING_DEL,
|
||||
|
||||
/* Total number of flags - must be at the end of the enum */
|
||||
BT_KEYS_NUM_FLAGS,
|
||||
BT_KEYS_AUTHENTICATED = BIT(0),
|
||||
BT_KEYS_DEBUG = BIT(1),
|
||||
BT_KEYS_ID_PENDING_ADD = BIT(2),
|
||||
BT_KEYS_ID_PENDING_DEL = BIT(3),
|
||||
};
|
||||
|
||||
struct bt_ltk {
|
||||
u64_t rand;
|
||||
u8_t rand[8];
|
||||
u16_t ediv;
|
||||
u8_t val[16];
|
||||
};
|
||||
|
@ -49,7 +46,7 @@ struct bt_keys {
|
|||
bt_addr_le_t addr;
|
||||
u8_t storage_start[0];
|
||||
u8_t enc_size;
|
||||
ATOMIC_DEFINE(flags, BT_KEYS_NUM_FLAGS);
|
||||
u8_t flags;
|
||||
u16_t keys;
|
||||
struct bt_ltk ltk;
|
||||
struct bt_irk irk;
|
||||
|
@ -88,17 +85,14 @@ static inline int bt_keys_store(struct bt_keys *keys)
|
|||
#endif
|
||||
|
||||
enum {
|
||||
BT_LINK_KEY_AUTHENTICATED,
|
||||
BT_LINK_KEY_DEBUG,
|
||||
BT_LINK_KEY_SC,
|
||||
|
||||
/* Total number of flags - must be at the end of the enum */
|
||||
BT_LINK_KEY_NUM_FLAGS,
|
||||
BT_LINK_KEY_AUTHENTICATED = BIT(0),
|
||||
BT_LINK_KEY_DEBUG = BIT(1),
|
||||
BT_LINK_KEY_SC = BIT(2),
|
||||
};
|
||||
|
||||
struct bt_keys_link_key {
|
||||
bt_addr_t addr;
|
||||
ATOMIC_DEFINE(flags, BT_LINK_KEY_NUM_FLAGS);
|
||||
u8_t flags;
|
||||
u8_t val[16];
|
||||
};
|
||||
|
||||
|
|
|
@ -673,12 +673,12 @@ static void sc_derive_link_key(struct bt_smp *smp)
|
|||
bt_keys_link_key_clear(link_key);
|
||||
}
|
||||
|
||||
atomic_set_bit(link_key->flags, BT_LINK_KEY_SC);
|
||||
link_key->flags |= BT_LINK_KEY_SC;
|
||||
|
||||
if (atomic_test_bit(conn->le.keys->flags, BT_KEYS_AUTHENTICATED)) {
|
||||
atomic_set_bit(link_key->flags, BT_LINK_KEY_AUTHENTICATED);
|
||||
if (conn->le.keys->flags & BT_KEYS_AUTHENTICATED) {
|
||||
link_key->flags |= BT_LINK_KEY_AUTHENTICATED;
|
||||
} else {
|
||||
atomic_clear_bit(link_key->flags, BT_LINK_KEY_AUTHENTICATED);
|
||||
link_key->flags &= ~BT_LINK_KEY_AUTHENTICATED;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -836,13 +836,13 @@ static void smp_br_derive_ltk(struct bt_smp_br *smp)
|
|||
}
|
||||
|
||||
keys->ltk.ediv = 0;
|
||||
keys->ltk.rand = 0;
|
||||
memset(keys->ltk.rand, 0, sizeof(keys->ltk.rand));
|
||||
keys->enc_size = smp->enc_key_size;
|
||||
|
||||
if (atomic_test_bit(link_key->flags, BT_LINK_KEY_AUTHENTICATED)) {
|
||||
atomic_set_bit(keys->flags, BT_KEYS_AUTHENTICATED);
|
||||
if (link_key->flags & BT_LINK_KEY_AUTHENTICATED) {
|
||||
keys->flags |= BT_KEYS_AUTHENTICATED;
|
||||
} else {
|
||||
atomic_clear_bit(keys->flags, BT_KEYS_AUTHENTICATED);
|
||||
keys->flags &= ~BT_KEYS_AUTHENTICATED;
|
||||
}
|
||||
|
||||
BT_DBG("LTK derived from LinkKey");
|
||||
|
@ -1719,7 +1719,7 @@ static void legacy_distribute_keys(struct bt_smp *smp)
|
|||
|
||||
memcpy(keys->slave_ltk.val, key,
|
||||
sizeof(keys->slave_ltk.val));
|
||||
keys->slave_ltk.rand = rand;
|
||||
memcpy(keys->slave_ltk.rand, &rand, sizeof(rand));
|
||||
keys->slave_ltk.ediv = ediv;
|
||||
}
|
||||
}
|
||||
|
@ -1886,7 +1886,7 @@ static u8_t legacy_request_tk(struct bt_smp *smp)
|
|||
* keys with unauthenticated ones.
|
||||
*/
|
||||
keys = bt_keys_find_addr(&conn->le.dst);
|
||||
if (keys && atomic_test_bit(keys->flags, BT_KEYS_AUTHENTICATED) &&
|
||||
if (keys && (keys->flags & BT_KEYS_AUTHENTICATED) &&
|
||||
smp->method == JUST_WORKS) {
|
||||
BT_ERR("JustWorks failed, authenticated keys present");
|
||||
return BT_SMP_ERR_UNSPECIFIED;
|
||||
|
@ -2124,7 +2124,7 @@ static u8_t smp_master_ident(struct bt_smp *smp, struct net_buf *buf)
|
|||
}
|
||||
|
||||
keys->ltk.ediv = req->ediv;
|
||||
keys->ltk.rand = req->rand;
|
||||
memcpy(keys->ltk.rand, &req->rand, sizeof(req->rand));
|
||||
|
||||
smp->remote_dist &= ~BT_SMP_DIST_ENC_KEY;
|
||||
}
|
||||
|
@ -3141,7 +3141,7 @@ static u8_t smp_security_request(struct bt_smp *smp, struct net_buf *buf)
|
|||
|
||||
/* if MITM required key must be authenticated */
|
||||
if ((auth & BT_SMP_AUTH_MITM) &&
|
||||
!atomic_test_bit(conn->le.keys->flags, BT_KEYS_AUTHENTICATED)) {
|
||||
!(conn->le.keys->flags & BT_KEYS_AUTHENTICATED)) {
|
||||
if (get_io_capa() != BT_SMP_IO_NO_INPUT_OUTPUT) {
|
||||
BT_INFO("New auth requirements: 0x%x, repairing",
|
||||
auth);
|
||||
|
@ -3529,8 +3529,7 @@ static void bt_smp_disconnected(struct bt_l2cap_chan *chan)
|
|||
* If debug keys were used for pairing remove them.
|
||||
* No keys indicate no bonding so free keys storage.
|
||||
*/
|
||||
if (!keys->keys ||
|
||||
atomic_test_bit(keys->flags, BT_KEYS_DEBUG)) {
|
||||
if (!keys->keys || (keys->flags & BT_KEYS_DEBUG)) {
|
||||
bt_keys_clear(keys);
|
||||
}
|
||||
}
|
||||
|
@ -4350,7 +4349,7 @@ void bt_smp_update_keys(struct bt_conn *conn)
|
|||
|
||||
/* mark keys as debug */
|
||||
if (atomic_test_bit(smp->flags, SMP_FLAG_SC_DEBUG_KEY)) {
|
||||
atomic_set_bit(conn->le.keys->flags, BT_KEYS_DEBUG);
|
||||
conn->le.keys->flags |= BT_KEYS_DEBUG;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -4362,12 +4361,12 @@ void bt_smp_update_keys(struct bt_conn *conn)
|
|||
case PASSKEY_DISPLAY:
|
||||
case PASSKEY_INPUT:
|
||||
case PASSKEY_CONFIRM:
|
||||
atomic_set_bit(conn->le.keys->flags, BT_KEYS_AUTHENTICATED);
|
||||
conn->le.keys->flags |= BT_KEYS_AUTHENTICATED;
|
||||
break;
|
||||
case JUST_WORKS:
|
||||
default:
|
||||
/* unauthenticated key, clear it */
|
||||
atomic_clear_bit(conn->le.keys->flags, BT_KEYS_AUTHENTICATED);
|
||||
conn->le.keys->flags &= ~BT_KEYS_AUTHENTICATED;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -4383,7 +4382,8 @@ void bt_smp_update_keys(struct bt_conn *conn)
|
|||
bt_keys_add_type(conn->le.keys, BT_KEYS_LTK_P256);
|
||||
memcpy(conn->le.keys->ltk.val, smp->tk,
|
||||
sizeof(conn->le.keys->ltk.val));
|
||||
conn->le.keys->ltk.rand = 0;
|
||||
memset(conn->le.keys->ltk.rand, 0,
|
||||
sizeof(conn->le.keys->ltk.rand));
|
||||
conn->le.keys->ltk.ediv = 0;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue