mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #13942 from paul-szczepanek-arm/securitydb-fix
ble: Fix persistence in SecurityDBpull/13969/head
commit
dd432a387e
|
@ -26,8 +26,6 @@ namespace ble {
|
||||||
#error "BLE_SECURITY_DATABASE_MAX_ENTRIES must be only one digit long"
|
#error "BLE_SECURITY_DATABASE_MAX_ENTRIES must be only one digit long"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ENTRY_INVALID (0xFF)
|
|
||||||
|
|
||||||
constexpr uint8_t KVStoreSecurityDb::KVSTORESECURITYDB_VERSION;
|
constexpr uint8_t KVStoreSecurityDb::KVSTORESECURITYDB_VERSION;
|
||||||
constexpr size_t KVStoreSecurityDb::DB_PREFIX_SIZE;
|
constexpr size_t KVStoreSecurityDb::DB_PREFIX_SIZE;
|
||||||
constexpr size_t KVStoreSecurityDb::DB_KEY_SIZE;
|
constexpr size_t KVStoreSecurityDb::DB_KEY_SIZE;
|
||||||
|
@ -54,9 +52,6 @@ typedef SecurityDb::entry_handle_t entry_handle_t;
|
||||||
KVStoreSecurityDb::KVStoreSecurityDb()
|
KVStoreSecurityDb::KVStoreSecurityDb()
|
||||||
: SecurityDb() {
|
: SecurityDb() {
|
||||||
memset(_entries, 0, sizeof(_entries));
|
memset(_entries, 0, sizeof(_entries));
|
||||||
for (size_t i = 0; i < get_entry_count(); i++) {
|
|
||||||
_entries[i].index = ENTRY_INVALID;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
KVStoreSecurityDb::~KVStoreSecurityDb()
|
KVStoreSecurityDb::~KVStoreSecurityDb()
|
||||||
|
@ -95,7 +90,7 @@ bool KVStoreSecurityDb::erase_db()
|
||||||
|
|
||||||
/* we zero the database and make sure we can fit all our keys */
|
/* we zero the database and make sure we can fit all our keys */
|
||||||
|
|
||||||
db_write(zero.entries, DB_ENTRIES);
|
db_write(&zero.entries, DB_ENTRIES);
|
||||||
db_write((SecurityEntryIdentity_t*)zero.buffer, DB_LOCAL_IDENTITY);
|
db_write((SecurityEntryIdentity_t*)zero.buffer, DB_LOCAL_IDENTITY);
|
||||||
db_write((csrk_t*)zero.buffer, DB_LOCAL_CSRK);
|
db_write((csrk_t*)zero.buffer, DB_LOCAL_CSRK);
|
||||||
db_write((sign_count_t*)zero.buffer, DB_LOCAL_SIGN_COUNT);
|
db_write((sign_count_t*)zero.buffer, DB_LOCAL_SIGN_COUNT);
|
||||||
|
@ -144,7 +139,7 @@ void KVStoreSecurityDb::set_entry_local_ltk(
|
||||||
SecurityEntryKeys_t* current_entry = read_in_entry_local_keys(db_handle);
|
SecurityEntryKeys_t* current_entry = read_in_entry_local_keys(db_handle);
|
||||||
current_entry->ltk = ltk;
|
current_entry->ltk = ltk;
|
||||||
|
|
||||||
db_write_entry(current_entry, DB_ENTRY_LOCAL_KEYS, entry->index);
|
db_write_entry(current_entry, DB_ENTRY_LOCAL_KEYS, get_index(entry));
|
||||||
}
|
}
|
||||||
|
|
||||||
void KVStoreSecurityDb::set_entry_local_ediv_rand(
|
void KVStoreSecurityDb::set_entry_local_ediv_rand(
|
||||||
|
@ -162,7 +157,7 @@ void KVStoreSecurityDb::set_entry_local_ediv_rand(
|
||||||
current_entry->ediv = ediv;
|
current_entry->ediv = ediv;
|
||||||
current_entry->rand = rand;
|
current_entry->rand = rand;
|
||||||
|
|
||||||
db_write_entry(current_entry, DB_ENTRY_LOCAL_KEYS, entry->index);
|
db_write_entry(current_entry, DB_ENTRY_LOCAL_KEYS, get_index(entry));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* peer's keys */
|
/* peer's keys */
|
||||||
|
@ -184,7 +179,7 @@ void KVStoreSecurityDb::set_entry_peer_ltk(
|
||||||
SecurityEntryKeys_t* current_entry = read_in_entry_peer_keys(db_handle);
|
SecurityEntryKeys_t* current_entry = read_in_entry_peer_keys(db_handle);
|
||||||
current_entry->ltk = ltk;
|
current_entry->ltk = ltk;
|
||||||
|
|
||||||
db_write_entry(current_entry, DB_ENTRY_PEER_KEYS, entry->index);
|
db_write_entry(current_entry, DB_ENTRY_PEER_KEYS, get_index(entry));
|
||||||
}
|
}
|
||||||
|
|
||||||
void KVStoreSecurityDb::set_entry_peer_ediv_rand(
|
void KVStoreSecurityDb::set_entry_peer_ediv_rand(
|
||||||
|
@ -202,7 +197,7 @@ void KVStoreSecurityDb::set_entry_peer_ediv_rand(
|
||||||
current_entry->ediv = ediv;
|
current_entry->ediv = ediv;
|
||||||
current_entry->rand = rand;
|
current_entry->rand = rand;
|
||||||
|
|
||||||
db_write_entry(current_entry, DB_ENTRY_PEER_KEYS, entry->index);
|
db_write_entry(current_entry, DB_ENTRY_PEER_KEYS, get_index(entry));
|
||||||
}
|
}
|
||||||
|
|
||||||
void KVStoreSecurityDb::set_entry_peer_irk(
|
void KVStoreSecurityDb::set_entry_peer_irk(
|
||||||
|
@ -220,7 +215,7 @@ void KVStoreSecurityDb::set_entry_peer_irk(
|
||||||
SecurityEntryIdentity_t* current_entry = read_in_entry_peer_identity(db_handle);
|
SecurityEntryIdentity_t* current_entry = read_in_entry_peer_identity(db_handle);
|
||||||
current_entry->irk = irk;
|
current_entry->irk = irk;
|
||||||
|
|
||||||
db_write_entry(current_entry, DB_ENTRY_PEER_IDENTITY, entry->index);
|
db_write_entry(current_entry, DB_ENTRY_PEER_IDENTITY, get_index(entry));
|
||||||
}
|
}
|
||||||
|
|
||||||
void KVStoreSecurityDb::set_entry_peer_bdaddr(
|
void KVStoreSecurityDb::set_entry_peer_bdaddr(
|
||||||
|
@ -238,7 +233,7 @@ void KVStoreSecurityDb::set_entry_peer_bdaddr(
|
||||||
current_entry->identity_address = peer_address;
|
current_entry->identity_address = peer_address;
|
||||||
current_entry->identity_address_is_public = address_is_public;
|
current_entry->identity_address_is_public = address_is_public;
|
||||||
|
|
||||||
db_write_entry(current_entry, DB_ENTRY_PEER_IDENTITY, entry->index);
|
db_write_entry(current_entry, DB_ENTRY_PEER_IDENTITY, get_index(entry));
|
||||||
}
|
}
|
||||||
|
|
||||||
void KVStoreSecurityDb::set_entry_peer_csrk(
|
void KVStoreSecurityDb::set_entry_peer_csrk(
|
||||||
|
@ -256,7 +251,7 @@ void KVStoreSecurityDb::set_entry_peer_csrk(
|
||||||
SecurityEntrySigning_t* current_entry = read_in_entry_peer_signing(db_handle);
|
SecurityEntrySigning_t* current_entry = read_in_entry_peer_signing(db_handle);
|
||||||
current_entry->csrk = csrk;
|
current_entry->csrk = csrk;
|
||||||
|
|
||||||
db_write_entry(current_entry, DB_ENTRY_PEER_SIGNING, entry->index);
|
db_write_entry(current_entry, DB_ENTRY_PEER_SIGNING, get_index(entry));
|
||||||
}
|
}
|
||||||
|
|
||||||
void KVStoreSecurityDb::set_entry_peer_sign_counter(
|
void KVStoreSecurityDb::set_entry_peer_sign_counter(
|
||||||
|
@ -349,16 +344,12 @@ void KVStoreSecurityDb::reset_entry(entry_handle_t db_handle)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry->index != ENTRY_INVALID) {
|
uint8_t zero_buffer[sizeof(SecurityEntryKeys_t)] = {0};
|
||||||
uint8_t zero_buffer[sizeof(SecurityEntryKeys_t)] = {0};
|
|
||||||
|
|
||||||
db_write_entry((SecurityEntryKeys_t*)zero_buffer, DB_ENTRY_LOCAL_KEYS, entry->index);
|
db_write_entry((SecurityEntryKeys_t*)zero_buffer, DB_ENTRY_LOCAL_KEYS, get_index(entry));
|
||||||
db_write_entry((SecurityEntryIdentity_t*)zero_buffer, DB_ENTRY_PEER_IDENTITY, entry->index);
|
db_write_entry((SecurityEntryIdentity_t*)zero_buffer, DB_ENTRY_PEER_IDENTITY, get_index(entry));
|
||||||
db_write_entry((SecurityEntryKeys_t*)zero_buffer, DB_ENTRY_PEER_KEYS, entry->index);
|
db_write_entry((SecurityEntryKeys_t*)zero_buffer, DB_ENTRY_PEER_KEYS, get_index(entry));
|
||||||
db_write_entry((SecurityEntrySigning_t*)zero_buffer, DB_ENTRY_PEER_SIGNING, entry->index);
|
db_write_entry((SecurityEntrySigning_t*)zero_buffer, DB_ENTRY_PEER_SIGNING, get_index(entry));
|
||||||
|
|
||||||
entry->index = ENTRY_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
entry->flags = SecurityDistributionFlags_t();
|
entry->flags = SecurityDistributionFlags_t();
|
||||||
entry->peer_sign_counter = 0;
|
entry->peer_sign_counter = 0;
|
||||||
|
@ -372,7 +363,7 @@ SecurityEntryIdentity_t* KVStoreSecurityDb::read_in_entry_peer_identity(entry_ha
|
||||||
}
|
}
|
||||||
|
|
||||||
SecurityEntryIdentity_t* identity = reinterpret_cast<SecurityEntryIdentity_t*>(_buffer);
|
SecurityEntryIdentity_t* identity = reinterpret_cast<SecurityEntryIdentity_t*>(_buffer);
|
||||||
db_read_entry(identity, DB_ENTRY_PEER_IDENTITY, entry->index);
|
db_read_entry(identity, DB_ENTRY_PEER_IDENTITY, get_index(entry));
|
||||||
|
|
||||||
return identity;
|
return identity;
|
||||||
};
|
};
|
||||||
|
@ -385,7 +376,7 @@ SecurityEntryKeys_t* KVStoreSecurityDb::read_in_entry_peer_keys(entry_handle_t d
|
||||||
}
|
}
|
||||||
|
|
||||||
SecurityEntryKeys_t* keys = reinterpret_cast<SecurityEntryKeys_t*>(_buffer);
|
SecurityEntryKeys_t* keys = reinterpret_cast<SecurityEntryKeys_t*>(_buffer);
|
||||||
db_read_entry(keys, DB_ENTRY_PEER_KEYS, entry->index);
|
db_read_entry(keys, DB_ENTRY_PEER_KEYS, get_index(entry));
|
||||||
|
|
||||||
return keys;
|
return keys;
|
||||||
};
|
};
|
||||||
|
@ -398,7 +389,7 @@ SecurityEntryKeys_t* KVStoreSecurityDb::read_in_entry_local_keys(entry_handle_t
|
||||||
}
|
}
|
||||||
|
|
||||||
SecurityEntryKeys_t* keys = reinterpret_cast<SecurityEntryKeys_t*>(_buffer);
|
SecurityEntryKeys_t* keys = reinterpret_cast<SecurityEntryKeys_t*>(_buffer);
|
||||||
db_read_entry(keys, DB_ENTRY_LOCAL_KEYS, entry->index);
|
db_read_entry(keys, DB_ENTRY_LOCAL_KEYS, get_index(entry));
|
||||||
|
|
||||||
return keys;
|
return keys;
|
||||||
};
|
};
|
||||||
|
@ -412,7 +403,7 @@ SecurityEntrySigning_t* KVStoreSecurityDb::read_in_entry_peer_signing(entry_hand
|
||||||
|
|
||||||
/* only read in the csrk */
|
/* only read in the csrk */
|
||||||
csrk_t* csrk = reinterpret_cast<csrk_t*>(_buffer);
|
csrk_t* csrk = reinterpret_cast<csrk_t*>(_buffer);
|
||||||
db_read_entry(csrk, DB_ENTRY_PEER_SIGNING, entry->index);
|
db_read_entry(csrk, DB_ENTRY_PEER_SIGNING,get_index(entry));
|
||||||
|
|
||||||
|
|
||||||
/* use the counter held in memory */
|
/* use the counter held in memory */
|
||||||
|
|
|
@ -38,7 +38,6 @@ private:
|
||||||
struct entry_t {
|
struct entry_t {
|
||||||
SecurityDistributionFlags_t flags;
|
SecurityDistributionFlags_t flags;
|
||||||
sign_count_t peer_sign_counter;
|
sign_count_t peer_sign_counter;
|
||||||
uint8_t index;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static constexpr uint8_t KVSTORESECURITYDB_VERSION = 1;
|
static constexpr uint8_t KVSTORESECURITYDB_VERSION = 1;
|
||||||
|
@ -228,6 +227,11 @@ private:
|
||||||
private:
|
private:
|
||||||
entry_t _entries[BLE_SECURITY_DATABASE_MAX_ENTRIES];
|
entry_t _entries[BLE_SECURITY_DATABASE_MAX_ENTRIES];
|
||||||
uint8_t _buffer[sizeof(SecurityEntryKeys_t)];
|
uint8_t _buffer[sizeof(SecurityEntryKeys_t)];
|
||||||
|
|
||||||
|
uint8_t get_index(entry_t *entry)
|
||||||
|
{
|
||||||
|
return entry - _entries;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ble */
|
} /* namespace ble */
|
||||||
|
|
|
@ -181,10 +181,21 @@ public:
|
||||||
entry_handle_t correct_handle = find_entry_by_peer_ediv_rand(ediv, rand);
|
entry_handle_t correct_handle = find_entry_by_peer_ediv_rand(ediv, rand);
|
||||||
if (!correct_handle) {
|
if (!correct_handle) {
|
||||||
cb(*db_handle, NULL);
|
cb(*db_handle, NULL);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
// Note: keys should never be null as a matching entry has been retrieved
|
// Note: keys should never be null as a matching entry has been retrieved
|
||||||
SecurityEntryKeys_t* keys = read_in_entry_local_keys(correct_handle);
|
SecurityEntryKeys_t* keys = read_in_entry_local_keys(correct_handle);
|
||||||
MBED_ASSERT(keys);
|
MBED_ASSERT(keys);
|
||||||
|
|
||||||
|
/* set flags connected */
|
||||||
|
SecurityDistributionFlags_t* flags = get_distribution_flags(correct_handle);
|
||||||
|
flags->connected = true;
|
||||||
|
|
||||||
|
/* update peer address */
|
||||||
|
SecurityDistributionFlags_t* old_flags = get_distribution_flags(*db_handle);
|
||||||
|
flags->peer_address = old_flags->peer_address;
|
||||||
|
flags->peer_address_is_public = old_flags->peer_address_is_public;
|
||||||
|
|
||||||
close_entry(*db_handle, false);
|
close_entry(*db_handle, false);
|
||||||
*db_handle = correct_handle;
|
*db_handle = correct_handle;
|
||||||
cb(*db_handle, keys);
|
cb(*db_handle, keys);
|
||||||
|
@ -494,6 +505,7 @@ public:
|
||||||
) {
|
) {
|
||||||
entry_handle_t db_handle = find_entry_by_peer_address(peer_address_type, peer_address);
|
entry_handle_t db_handle = find_entry_by_peer_address(peer_address_type, peer_address);
|
||||||
if (db_handle) {
|
if (db_handle) {
|
||||||
|
((SecurityDistributionFlags_t*)db_handle)->connected = true;
|
||||||
return db_handle;
|
return db_handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -507,6 +519,7 @@ public:
|
||||||
* by identity address */
|
* by identity address */
|
||||||
flags->peer_address = peer_address;
|
flags->peer_address = peer_address;
|
||||||
flags->peer_address_is_public = peer_address_public;
|
flags->peer_address_is_public = peer_address_public;
|
||||||
|
flags->connected = true;
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue