From 07bcbeb8f180b86bff79e8cff5b4041c974db3d1 Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Wed, 3 Jun 2020 15:35:03 +0100 Subject: [PATCH 1/5] Make kvstore and fs store configured in the lib json --- features/FEATURE_BLE/mbed_lib.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/features/FEATURE_BLE/mbed_lib.json b/features/FEATURE_BLE/mbed_lib.json index 64601cec010..f44622dda16 100644 --- a/features/FEATURE_BLE/mbed_lib.json +++ b/features/FEATURE_BLE/mbed_lib.json @@ -72,6 +72,16 @@ "value": true, "macro_name": "BLE_FEATURE_PERIODIC_ADVERTISING" }, + "ble-security-database-filesystem": { + "help": "Use filesystem to store security db when path is passed in, depends on security manager.", + "value": true, + "macro_name": "BLE_SECURITY_DATABASE_FILESYSTEM" + }, + "ble-security-database-kvstore": { + "help": "Use KVStore to store security db, depends on security manager.", + "value": false, + "macro_name": "BLE_SECURITY_DATABASE_KVSTORE" + }, "ble-security-database-max-entries": { "help": "How many entries can be stored in the db, depends on security manager.", "value": 5, From f661ce0c81919135a9a63a99a3c11dd9c6c3e517 Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Wed, 3 Jun 2020 15:36:44 +0100 Subject: [PATCH 2/5] Relax the integrity requirement to allow private functions to call themselves --- features/FEATURE_BLE/ble/generic/SecurityDb.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/features/FEATURE_BLE/ble/generic/SecurityDb.h b/features/FEATURE_BLE/ble/generic/SecurityDb.h index 358e5224dca..607e36347f4 100644 --- a/features/FEATURE_BLE/ble/generic/SecurityDb.h +++ b/features/FEATURE_BLE/ble/generic/SecurityDb.h @@ -750,7 +750,7 @@ class SecurityDb { /** * This will read in the requested information into a buffer that will remain valid - * until another read_in call is made. + * until another read_in call is made or an entry is written. * @param db_handle handle of the entry to be read * @return pointer to buffer holding the query result, NULL when not found */ @@ -758,7 +758,7 @@ class SecurityDb { /** * This will read in the requested information into a buffer that will remain valid - * until another read_in call is made. + * until another read_in call is made or an entry is written. * @param db_handle handle of the entry to be read * @return pointer to buffer holding the query result, NULL when not found */ @@ -766,7 +766,7 @@ class SecurityDb { /** * This will read in the requested information into a buffer that will remain valid - * until another read_in call is made. + * until another read_in call is made or an entry is written. * @param db_handle handle of the entry to be read * @return pointer to buffer holding the query result, NULL when not found */ @@ -774,7 +774,7 @@ class SecurityDb { /** * This will read in the requested information into a buffer that will remain valid - * until another read_in call is made. + * until another read_in call is made or an entry is written. * @param db_handle handle of the entry to be read * @return pointer to buffer holding the query result, NULL when not found */ From beb56320ebe608c73cc5ef8d7f2e1bd7de5ce975 Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Wed, 3 Jun 2020 15:39:59 +0100 Subject: [PATCH 3/5] Add a new implementation of security db for KVStore This works similar to filesystem db but uses the KVStore which it assumes is initialised. This is checked by open_db. On initialisation it either reads the present db or writes a new db into all entries thus guaranteeing that after the initialisation we will not run out of space for the keys and no extra error handling is needed. --- .../ble/generic/KVStoreSecurityDb.h | 236 ++++++++++ .../source/generic/KVStoreSecurityDb.cpp | 403 ++++++++++++++++++ 2 files changed, 639 insertions(+) create mode 100644 features/FEATURE_BLE/ble/generic/KVStoreSecurityDb.h create mode 100644 features/FEATURE_BLE/source/generic/KVStoreSecurityDb.cpp diff --git a/features/FEATURE_BLE/ble/generic/KVStoreSecurityDb.h b/features/FEATURE_BLE/ble/generic/KVStoreSecurityDb.h new file mode 100644 index 00000000000..2d55eba9380 --- /dev/null +++ b/features/FEATURE_BLE/ble/generic/KVStoreSecurityDb.h @@ -0,0 +1,236 @@ +/* mbed Microcontroller Library + * Copyright (c) 2018 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if BLE_SECURITY_DATABASE_KVSTORE + +#ifndef GENERIC_KFSTORE_SECURITY_DB_H_ +#define GENERIC_KFSTORE_SECURITY_DB_H_ + +#include "SecurityDb.h" +#include "kvstore_global_api.h" +#include "mbed_error.h" + +#define STR_EXPAND(tok) #tok +#define STR(tok) STR_EXPAND(tok) + +namespace ble { +namespace generic { + +/** Filesystem implementation */ +class KVStoreSecurityDb : public SecurityDb { +private: + + struct entry_t { + SecurityDistributionFlags_t flags; + sign_count_t peer_sign_counter; + uint8_t index; + }; + + static constexpr uint8_t KVSTORESECURITYDB_VERSION = 1; + + static constexpr size_t DB_PREFIX_SIZE = 7 + sizeof (STR(MBED_CONF_STORAGE_DEFAULT_KV)) - 1; + static constexpr size_t DB_KEY_SIZE = 3; + static constexpr size_t DB_ENTRY_KEY_SIZE = 2; + static constexpr size_t DB_FULL_KEY_SIZE = DB_PREFIX_SIZE + DB_KEY_SIZE + 1; + + static constexpr char DB_PREFIX[DB_PREFIX_SIZE + 1] = { "/" STR(MBED_CONF_STORAGE_DEFAULT_KV) "/_ble_" }; + + static constexpr char DB_ENTRIES[DB_KEY_SIZE] = { 'e','n','t' }; + + static constexpr char DB_ENTRY_PEER_IDENTITY[DB_ENTRY_KEY_SIZE] = { 'i','d' }; + static constexpr char DB_ENTRY_LOCAL_KEYS[DB_ENTRY_KEY_SIZE] = { 'l','k' }; + static constexpr char DB_ENTRY_PEER_KEYS[DB_ENTRY_KEY_SIZE] = { 'p','k' }; + static constexpr char DB_ENTRY_PEER_SIGNING[DB_ENTRY_KEY_SIZE] = { 'p','s' }; + + static constexpr char DB_LOCAL_IDENTITY[DB_KEY_SIZE] = { 'l','i','d' }; + static constexpr char DB_LOCAL_CSRK[DB_KEY_SIZE] = { 'l','c','s' }; + static constexpr char DB_LOCAL_SIGN_COUNT[DB_KEY_SIZE] = { 'l','s','c' }; + + static constexpr char DB_VERSION[DB_KEY_SIZE] = { 'v','e','r' }; + static constexpr char DB_RESTORE[DB_KEY_SIZE] = { 'r','e','s' }; + + static entry_t* as_entry(entry_handle_t db_handle) { + return reinterpret_cast(db_handle); + } + + template + static void db_read(T *value, const char* key) { + char db_key[DB_FULL_KEY_SIZE]; + create_key(db_key, key); + size_t size; + const int ret = kv_get(db_key, value, sizeof(T), &size); + (void)ret;//suppress unused var warning + MBED_ASSERT(ret == MBED_SUCCESS && size == sizeof(T)); + } + + template + static void db_write(T *value, const char* key) { + char db_key[DB_FULL_KEY_SIZE]; + create_key(db_key, key); + const int ret = kv_set(db_key, value, sizeof(T), 0); + (void)ret;//suppress unused var warning + MBED_ASSERT(ret == MBED_SUCCESS); + } + + template + static void db_write_entry(T *value, const char* key, uint8_t index) { + char db_key[DB_FULL_KEY_SIZE]; + create_entry_key(db_key, key, index); + const int ret = kv_set(db_key, value, sizeof(T), 0); + (void)ret;//suppress unused var warning + MBED_ASSERT(ret == MBED_SUCCESS); + } + + template + static void db_read_entry(T *value, const char* key, uint8_t index) { + char db_key[DB_FULL_KEY_SIZE]; + create_entry_key(db_key, key, index); + size_t size; + const int ret = kv_get(db_key, value, sizeof(T), &size); + (void)ret;//suppress unused var warning + MBED_ASSERT(ret == MBED_SUCCESS && size == sizeof(T)); + } + + static void create_key(char* full_key, const char* key) { + memcpy(full_key, DB_PREFIX, DB_PREFIX_SIZE); + memcpy(full_key + DB_PREFIX_SIZE, key, DB_KEY_SIZE); + full_key[DB_PREFIX_SIZE + DB_KEY_SIZE] = '\0'; + } + + static void create_entry_key(char* full_key, const char* key, uint8_t index) { + memcpy(full_key, DB_PREFIX, DB_PREFIX_SIZE); + memcpy(full_key + DB_PREFIX_SIZE, key, DB_ENTRY_KEY_SIZE); + full_key[DB_PREFIX_SIZE + DB_ENTRY_KEY_SIZE] = (char)('0' + index); + full_key[DB_PREFIX_SIZE + DB_KEY_SIZE] = '\0'; + } + +public: + KVStoreSecurityDb(); + virtual ~KVStoreSecurityDb(); + + /** + * Validates or creates a kvstore entry for the security database. + * @return true if KVStore works + */ + static bool open_db(); + + virtual SecurityDistributionFlags_t* get_distribution_flags( + entry_handle_t db_handle + ); + + /* local keys */ + + /* set */ + + virtual void set_entry_local_ltk( + entry_handle_t db_handle, + const ltk_t <k + ); + + virtual void set_entry_local_ediv_rand( + entry_handle_t db_handle, + const ediv_t &ediv, + const rand_t &rand + ); + + /* peer's keys */ + + /* set */ + + virtual void set_entry_peer_ltk( + entry_handle_t db_handle, + const ltk_t <k + ); + + virtual void set_entry_peer_ediv_rand( + entry_handle_t db_handle, + const ediv_t &ediv, + const rand_t &rand + ); + + virtual void set_entry_peer_irk( + entry_handle_t db_handle, + const irk_t &irk + ); + + virtual void set_entry_peer_bdaddr( + entry_handle_t db_handle, + bool address_is_public, + const address_t &peer_address + ); + + virtual void set_entry_peer_csrk( + entry_handle_t db_handle, + const csrk_t &csrk + ); + + virtual void set_entry_peer_sign_counter( + entry_handle_t db_handle, + sign_count_t sign_counter + ); + + /* local csrk and identity */ + + virtual void set_local_csrk( + const csrk_t &csrk + ); + + virtual void set_local_identity( + const irk_t &irk, + const address_t &identity_address, + bool public_address + ); + + /* I am not overriding set_local_sign_counter to avoid constant filesystem writes, + * instead this is synced by sync (which is called on disconnection) */ + + /* saving and loading from nvm */ + + virtual void restore(); + + virtual void sync(entry_handle_t db_handle); + + virtual void set_restore(bool reload); + +private: + virtual uint8_t get_entry_count(); + + virtual SecurityDistributionFlags_t* get_entry_handle_by_index(uint8_t index); + + virtual void reset_entry(entry_handle_t db_handle); + + virtual SecurityEntryIdentity_t* read_in_entry_peer_identity(entry_handle_t db_handle); + virtual SecurityEntryKeys_t* read_in_entry_peer_keys(entry_handle_t db_handle); + virtual SecurityEntryKeys_t* read_in_entry_local_keys(entry_handle_t db_handle); + virtual SecurityEntrySigning_t* read_in_entry_peer_signing(entry_handle_t db_handle); + + /** + * Zero the db file. + * @return true if KVStore works + */ + static bool erase_db(); + +private: + entry_t _entries[BLE_SECURITY_DATABASE_MAX_ENTRIES]; + uint8_t _buffer[sizeof(SecurityEntryKeys_t)]; +}; + +} /* namespace pal */ +} /* namespace ble */ + +#endif /*GENERIC_KFSTORE_SECURITY_DB_H_*/ + +#endif /*BLE_SECURITY_DATABASE_KVSTORE*/ diff --git a/features/FEATURE_BLE/source/generic/KVStoreSecurityDb.cpp b/features/FEATURE_BLE/source/generic/KVStoreSecurityDb.cpp new file mode 100644 index 00000000000..f532ab124ce --- /dev/null +++ b/features/FEATURE_BLE/source/generic/KVStoreSecurityDb.cpp @@ -0,0 +1,403 @@ +/* mbed Microcontroller Library + * Copyright (c) 2018 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if BLE_SECURITY_DATABASE_KVSTORE + +#include "KVStoreSecurityDb.h" + +namespace ble { +namespace generic { + +#if BLE_SECURITY_DATABASE_MAX_ENTRIES > 9 +#error "BLE_SECURITY_DATABASE_MAX_ENTRIES must be only one digit long" +#endif + +#define ENTRY_INVALID (0xFF) + +constexpr uint8_t KVStoreSecurityDb::KVSTORESECURITYDB_VERSION; +constexpr size_t KVStoreSecurityDb::DB_PREFIX_SIZE; +constexpr size_t KVStoreSecurityDb::DB_KEY_SIZE; +constexpr size_t KVStoreSecurityDb::DB_ENTRY_KEY_SIZE; +constexpr size_t KVStoreSecurityDb::DB_FULL_KEY_SIZE; +constexpr char KVStoreSecurityDb::DB_PREFIX[DB_PREFIX_SIZE+1]; + +constexpr char KVStoreSecurityDb::DB_ENTRIES[DB_KEY_SIZE]; + +constexpr char KVStoreSecurityDb::DB_ENTRY_PEER_IDENTITY[DB_ENTRY_KEY_SIZE]; +constexpr char KVStoreSecurityDb::DB_ENTRY_LOCAL_KEYS[DB_ENTRY_KEY_SIZE]; +constexpr char KVStoreSecurityDb::DB_ENTRY_PEER_KEYS[DB_ENTRY_KEY_SIZE]; +constexpr char KVStoreSecurityDb::DB_ENTRY_PEER_SIGNING[DB_ENTRY_KEY_SIZE]; + +constexpr char KVStoreSecurityDb::DB_LOCAL_IDENTITY[DB_KEY_SIZE]; +constexpr char KVStoreSecurityDb::DB_LOCAL_CSRK[DB_KEY_SIZE]; +constexpr char KVStoreSecurityDb::DB_LOCAL_SIGN_COUNT[DB_KEY_SIZE]; + +constexpr char KVStoreSecurityDb::DB_VERSION[DB_KEY_SIZE]; +constexpr char KVStoreSecurityDb::DB_RESTORE[DB_KEY_SIZE]; + +typedef SecurityDb::entry_handle_t entry_handle_t; + +KVStoreSecurityDb::KVStoreSecurityDb() + : SecurityDb() { + memset(_entries, 0, sizeof(_entries)); + for (size_t i = 0; i < get_entry_count(); i++) { + _entries[i].index = ENTRY_INVALID; + } +} + +KVStoreSecurityDb::~KVStoreSecurityDb() { +} + +bool KVStoreSecurityDb::open_db() { + uint8_t version = 0; + char db_key[DB_FULL_KEY_SIZE]; + create_key(db_key, DB_VERSION); + size_t size; + int ret = kv_get(db_key, &version, sizeof(uint8_t), &size); + + /* kvstore problem (check if it's been successfully initialised before this call) */ + if (ret != MBED_ERROR_ITEM_NOT_FOUND && (ret != MBED_SUCCESS || size != sizeof(uint8_t))) { + return false; + } + + /* wipe the db if it's the wrong version or it doesn't exist */ + if (version != KVSTORESECURITYDB_VERSION) { + return erase_db(); + } + + return true; +} + +bool KVStoreSecurityDb::erase_db() { + union zero_t { + int dummy; /* we need a dummy for initialisation */ + uint8_t buffer[sizeof(SecurityEntryKeys_t)]; + entry_t entries[BLE_SECURITY_DATABASE_MAX_ENTRIES]; + } zero = { 0 }; + memset(&zero, 0, sizeof(zero)); + + /* we zero the database and make sure we can fit all our keys */ + + db_write(zero.entries, DB_ENTRIES); + db_write((SecurityEntryIdentity_t*)zero.buffer, DB_LOCAL_IDENTITY); + db_write((csrk_t*)zero.buffer, DB_LOCAL_CSRK); + db_write((sign_count_t*)zero.buffer, DB_LOCAL_SIGN_COUNT); + + bool reload = false; + db_write(&reload, DB_RESTORE); + + for (int index = 0; index < BLE_SECURITY_DATABASE_MAX_ENTRIES; ++index) { + db_write_entry((SecurityEntryKeys_t*)zero.buffer, DB_ENTRY_LOCAL_KEYS, index); + db_write_entry((SecurityEntryIdentity_t*)zero.buffer, DB_ENTRY_PEER_IDENTITY, index); + db_write_entry((SecurityEntryKeys_t*)zero.buffer, DB_ENTRY_PEER_KEYS, index); + db_write_entry((SecurityEntrySigning_t*)zero.buffer, DB_ENTRY_PEER_SIGNING, index); + } + + /* now we write the version and read it back to see if was written succesfully */ + uint8_t version = KVSTORESECURITYDB_VERSION; + db_write(&version, DB_VERSION); + version = 0; + db_read(&version, DB_VERSION); + + return (version == KVSTORESECURITYDB_VERSION); +} + +SecurityDistributionFlags_t* KVStoreSecurityDb::get_distribution_flags( + entry_handle_t db_handle +) { + return reinterpret_cast(db_handle); +} + +/* local keys */ + +/* set */ +void KVStoreSecurityDb::set_entry_local_ltk( + entry_handle_t db_handle, + const ltk_t <k +) { + entry_t *entry = as_entry(db_handle); + if (!entry) { + return; + } + + entry->flags.ltk_sent = true; + + SecurityEntryKeys_t* current_entry = read_in_entry_local_keys(db_handle); + current_entry->ltk = ltk; + + db_write_entry(current_entry, DB_ENTRY_LOCAL_KEYS, entry->index); +} + +void KVStoreSecurityDb::set_entry_local_ediv_rand( + entry_handle_t db_handle, + const ediv_t &ediv, + const rand_t &rand +) { + entry_t *entry = as_entry(db_handle); + if (!entry) { + return; + } + + SecurityEntryKeys_t* current_entry = read_in_entry_local_keys(db_handle); + current_entry->ediv = ediv; + current_entry->rand = rand; + + db_write_entry(current_entry, DB_ENTRY_LOCAL_KEYS, entry->index); +} + +/* peer's keys */ + +/* set */ + +void KVStoreSecurityDb::set_entry_peer_ltk( + entry_handle_t db_handle, + const ltk_t <k +) { + entry_t *entry = as_entry(db_handle); + if (!entry) { + return; + } + + entry->flags.ltk_stored = true; + + SecurityEntryKeys_t* current_entry = read_in_entry_peer_keys(db_handle); + current_entry->ltk = ltk; + + db_write_entry(current_entry, DB_ENTRY_PEER_KEYS, entry->index); +} + +void KVStoreSecurityDb::set_entry_peer_ediv_rand( + entry_handle_t db_handle, + const ediv_t &ediv, + const rand_t &rand +) { + entry_t *entry = as_entry(db_handle); + if (!entry) { + return; + } + + SecurityEntryKeys_t* current_entry = read_in_entry_peer_keys(db_handle); + current_entry->ediv = ediv; + current_entry->rand = rand; + + db_write_entry(current_entry, DB_ENTRY_PEER_KEYS, entry->index); +} + +void KVStoreSecurityDb::set_entry_peer_irk( + entry_handle_t db_handle, + const irk_t &irk +) { + entry_t *entry = as_entry(db_handle); + if (!entry) { + return; + } + + entry->flags.irk_stored = true; + + SecurityEntryIdentity_t* current_entry = read_in_entry_peer_identity(db_handle); + current_entry->irk = irk; + + db_write_entry(current_entry, DB_ENTRY_PEER_IDENTITY, entry->index); +} + +void KVStoreSecurityDb::set_entry_peer_bdaddr( + entry_handle_t db_handle, + bool address_is_public, + const address_t &peer_address +) { + entry_t *entry = as_entry(db_handle); + if (!entry) { + return; + } + + SecurityEntryIdentity_t* current_entry = read_in_entry_peer_identity(db_handle); + current_entry->identity_address = peer_address; + current_entry->identity_address_is_public = address_is_public; + + db_write_entry(current_entry, DB_ENTRY_PEER_IDENTITY, entry->index); +} + +void KVStoreSecurityDb::set_entry_peer_csrk( + entry_handle_t db_handle, + const csrk_t &csrk +) { + entry_t *entry = as_entry(db_handle); + if (!entry) { + return; + } + + entry->flags.csrk_stored = true; + + SecurityEntrySigning_t* current_entry = read_in_entry_peer_signing(db_handle); + current_entry->csrk = csrk; + + db_write_entry(current_entry, DB_ENTRY_PEER_SIGNING, entry->index); +} + +void KVStoreSecurityDb::set_entry_peer_sign_counter( + entry_handle_t db_handle, + sign_count_t sign_counter +) { + entry_t *entry = as_entry(db_handle); + if (entry) { + entry->peer_sign_counter = sign_counter; + } +} + +void KVStoreSecurityDb::set_local_csrk( + const csrk_t &csrk +) { + this->SecurityDb::set_local_csrk(csrk); + db_write(&_local_csrk, DB_LOCAL_CSRK); +} + +void KVStoreSecurityDb::set_local_identity( + const irk_t &irk, + const address_t &identity_address, + bool public_address +) { + this->SecurityDb::set_local_identity(irk, identity_address, public_address); + db_write(&_local_identity, DB_LOCAL_IDENTITY); +} + +/* saving and loading from nvm */ + +void KVStoreSecurityDb::restore() { + /* restore if requested */ + bool restore_toggle = false; + db_read(&restore_toggle, DB_RESTORE); + + if (!restore_toggle) { + erase_db(); + return; + } + + db_read(&_entries, DB_ENTRIES); + db_read(&_local_identity, DB_LOCAL_IDENTITY); + db_read(&_local_csrk, DB_LOCAL_CSRK); + db_read(&_local_sign_counter, DB_LOCAL_SIGN_COUNT); +} + +void KVStoreSecurityDb::sync(entry_handle_t db_handle) { + entry_t *entry = as_entry(db_handle); + if (!entry) { + return; + } + + /* all entries are stored in a single key so we store them all*/ + db_write(&_entries, DB_ENTRIES); + db_write(&_local_identity, DB_LOCAL_IDENTITY); + db_write(&_local_csrk, DB_LOCAL_CSRK); + db_write(&_local_sign_counter, DB_LOCAL_SIGN_COUNT); +} + +void KVStoreSecurityDb::set_restore(bool reload) { + db_write(&reload, DB_RESTORE); +} + +/* helper functions */ + +uint8_t KVStoreSecurityDb::get_entry_count() { + return BLE_SECURITY_DATABASE_MAX_ENTRIES; +} + +SecurityDistributionFlags_t* KVStoreSecurityDb::get_entry_handle_by_index(uint8_t index) { + if (index < get_entry_count()) { + return &_entries[index].flags; + } else { + return nullptr; + } +} + +void KVStoreSecurityDb::reset_entry(entry_handle_t db_handle) { + entry_t *entry = as_entry(db_handle); + if (!entry) { + return; + } + + if (entry->index != ENTRY_INVALID) { + uint8_t zero_buffer[sizeof(SecurityEntryKeys_t)] = {0}; + + db_write_entry((SecurityEntryKeys_t*)zero_buffer, DB_ENTRY_LOCAL_KEYS, entry->index); + db_write_entry((SecurityEntryIdentity_t*)zero_buffer, DB_ENTRY_PEER_IDENTITY, entry->index); + db_write_entry((SecurityEntryKeys_t*)zero_buffer, DB_ENTRY_PEER_KEYS, entry->index); + db_write_entry((SecurityEntrySigning_t*)zero_buffer, DB_ENTRY_PEER_SIGNING, entry->index); + + entry->index = ENTRY_INVALID; + } + + entry->flags = SecurityDistributionFlags_t(); + entry->peer_sign_counter = 0; +} + +SecurityEntryIdentity_t* KVStoreSecurityDb::read_in_entry_peer_identity(entry_handle_t db_handle) { + entry_t *entry = as_entry(db_handle); + if (!entry) { + return nullptr; + } + + SecurityEntryIdentity_t* identity = reinterpret_cast(_buffer); + db_read_entry(identity, DB_ENTRY_PEER_IDENTITY, entry->index); + + return identity; +}; + +SecurityEntryKeys_t* KVStoreSecurityDb::read_in_entry_peer_keys(entry_handle_t db_handle) { + entry_t *entry = as_entry(db_handle); + if (!entry) { + return nullptr; + } + + SecurityEntryKeys_t* keys = reinterpret_cast(_buffer); + db_read_entry(keys, DB_ENTRY_PEER_KEYS, entry->index); + + return keys; +}; + +SecurityEntryKeys_t* KVStoreSecurityDb::read_in_entry_local_keys(entry_handle_t db_handle) { + entry_t *entry = as_entry(db_handle); + if (!entry) { + return nullptr; + } + + SecurityEntryKeys_t* keys = reinterpret_cast(_buffer); + db_read_entry(keys, DB_ENTRY_LOCAL_KEYS, entry->index); + + return keys; +}; + +SecurityEntrySigning_t* KVStoreSecurityDb::read_in_entry_peer_signing(entry_handle_t db_handle) { + entry_t *entry = as_entry(db_handle); + if (!entry) { + return nullptr; + } + + /* only read in the csrk */ + csrk_t* csrk = reinterpret_cast(_buffer); + db_read_entry(csrk, DB_ENTRY_PEER_SIGNING, entry->index); + + + /* use the counter held in memory */ + SecurityEntrySigning_t* signing = reinterpret_cast(_buffer); + signing->counter = entry->peer_sign_counter; + + return signing; +}; + +} /* namespace ble */ +} /* namespace generic */ + +#endif // BLE_SECURITY_DATABASE_KVSTORE From 559d6afc436fa3d0b780fb8c10cbf10c6c000f47 Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Wed, 3 Jun 2020 15:42:03 +0100 Subject: [PATCH 4/5] Allow for security db type selection The selection is now based on the lib json (which allows you to disable filesystem db or kvstore db) and the call to SecurityManager::init. It will always fall back on memory db if no other db is available. --- features/FEATURE_BLE/ble/generic/FileSecurityDb.h | 4 ++++ .../FEATURE_BLE/source/generic/FileSecurityDb.cpp | 7 ++++++- .../source/generic/GenericSecurityManager.tpp | 11 ++++++++++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/features/FEATURE_BLE/ble/generic/FileSecurityDb.h b/features/FEATURE_BLE/ble/generic/FileSecurityDb.h index 2dcdb058435..700b8b427cd 100644 --- a/features/FEATURE_BLE/ble/generic/FileSecurityDb.h +++ b/features/FEATURE_BLE/ble/generic/FileSecurityDb.h @@ -17,6 +17,8 @@ #ifndef GENERIC_FILE_SECURITY_DB_H_ #define GENERIC_FILE_SECURITY_DB_H_ +#if BLE_SECURITY_DATABASE_FILESYSTEM + #include "SecurityDb.h" #include @@ -167,4 +169,6 @@ class FileSecurityDb : public SecurityDb { } /* namespace pal */ } /* namespace ble */ +#endif // BLE_SECURITY_DATABASE_FILESYSTEM + #endif /*GENERIC_FILE_SECURITY_DB_H_*/ diff --git a/features/FEATURE_BLE/source/generic/FileSecurityDb.cpp b/features/FEATURE_BLE/source/generic/FileSecurityDb.cpp index abefb7f2098..5d28f94d04a 100644 --- a/features/FEATURE_BLE/source/generic/FileSecurityDb.cpp +++ b/features/FEATURE_BLE/source/generic/FileSecurityDb.cpp @@ -14,6 +14,8 @@ * limitations under the License. */ +#if BLE_SECURITY_DATABASE_FILESYSTEM + #include "FileSecurityDb.h" namespace ble { @@ -408,4 +410,7 @@ SecurityEntrySigning_t* FileSecurityDb::read_in_entry_peer_signing(entry_handle_ }; } /* namespace pal */ -} /* namespace ble */ \ No newline at end of file +} /* namespace ble */ + +#endif // BLE_SECURITY_DATABASE_FILESYSTEM + diff --git a/features/FEATURE_BLE/source/generic/GenericSecurityManager.tpp b/features/FEATURE_BLE/source/generic/GenericSecurityManager.tpp index e08a6f575ca..673651e2612 100644 --- a/features/FEATURE_BLE/source/generic/GenericSecurityManager.tpp +++ b/features/FEATURE_BLE/source/generic/GenericSecurityManager.tpp @@ -21,6 +21,7 @@ #include "ble/generic/GenericSecurityManager.h" #include "ble/generic/MemorySecurityDb.h" #include "ble/generic/FileSecurityDb.h" +#include "ble/generic/KVStoreSecurityDb.h" using ble::pal::advertising_peer_address_type_t; using ble::pal::AuthenticationMask; @@ -884,11 +885,19 @@ ble_error_t GenericSecurityManager::init_da ) { delete _db; +#if BLE_SECURITY_DATABASE_FILESYSTEM FILE* db_file = FileSecurityDb::open_db_file(db_path); if (db_file) { _db = new (std::nothrow) FileSecurityDb(db_file); - } else { + } else +#endif +#if BLE_SECURITY_DATABASE_KVSTORE + if (KVStoreSecurityDb::open_db()) { + _db = new (std::nothrow) KVStoreSecurityDb(); + } else +#endif + { _db = new (std::nothrow) MemorySecurityDb(); } From d080c7e85af7dc3f013be6a7d1f5c38d7094812a Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Mon, 6 Jul 2020 15:06:04 +0100 Subject: [PATCH 5/5] add SPDX identifier --- features/FEATURE_BLE/ble/generic/FileSecurityDb.h | 2 ++ features/FEATURE_BLE/ble/generic/GenericGap.h | 2 ++ features/FEATURE_BLE/ble/generic/GenericGattClient.h | 2 ++ features/FEATURE_BLE/ble/generic/GenericSecurityManager.h | 2 ++ features/FEATURE_BLE/ble/generic/KVStoreSecurityDb.h | 2 ++ features/FEATURE_BLE/ble/generic/MemorySecurityDb.h | 2 ++ features/FEATURE_BLE/ble/generic/SecurityDb.h | 2 ++ features/FEATURE_BLE/source/generic/FileSecurityDb.cpp | 2 ++ features/FEATURE_BLE/source/generic/GenericGap.tpp | 2 ++ features/FEATURE_BLE/source/generic/GenericGattClient.tpp | 2 ++ features/FEATURE_BLE/source/generic/GenericSecurityManager.tpp | 2 ++ features/FEATURE_BLE/source/generic/KVStoreSecurityDb.cpp | 2 ++ 12 files changed, 24 insertions(+) diff --git a/features/FEATURE_BLE/ble/generic/FileSecurityDb.h b/features/FEATURE_BLE/ble/generic/FileSecurityDb.h index 700b8b427cd..4503b497d42 100644 --- a/features/FEATURE_BLE/ble/generic/FileSecurityDb.h +++ b/features/FEATURE_BLE/ble/generic/FileSecurityDb.h @@ -1,6 +1,8 @@ /* mbed Microcontroller Library * Copyright (c) 2018 ARM Limited * + * SPDX-License-Identifier: Apache-2.0 + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/features/FEATURE_BLE/ble/generic/GenericGap.h b/features/FEATURE_BLE/ble/generic/GenericGap.h index 629cf5dac65..bda5dd20200 100644 --- a/features/FEATURE_BLE/ble/generic/GenericGap.h +++ b/features/FEATURE_BLE/ble/generic/GenericGap.h @@ -1,6 +1,8 @@ /* mbed Microcontroller Library * Copyright (c) 2017-2017 ARM Limited * + * SPDX-License-Identifier: Apache-2.0 + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/features/FEATURE_BLE/ble/generic/GenericGattClient.h b/features/FEATURE_BLE/ble/generic/GenericGattClient.h index 0966ffac864..50822aa4d52 100644 --- a/features/FEATURE_BLE/ble/generic/GenericGattClient.h +++ b/features/FEATURE_BLE/ble/generic/GenericGattClient.h @@ -1,6 +1,8 @@ /* mbed Microcontroller Library * Copyright (c) 2017-2017 ARM Limited * + * SPDX-License-Identifier: Apache-2.0 + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/features/FEATURE_BLE/ble/generic/GenericSecurityManager.h b/features/FEATURE_BLE/ble/generic/GenericSecurityManager.h index cc94b97b0b8..3a1651b4d16 100644 --- a/features/FEATURE_BLE/ble/generic/GenericSecurityManager.h +++ b/features/FEATURE_BLE/ble/generic/GenericSecurityManager.h @@ -1,6 +1,8 @@ /* mbed Microcontroller Library * Copyright (c) 2018 ARM Limited * + * SPDX-License-Identifier: Apache-2.0 + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/features/FEATURE_BLE/ble/generic/KVStoreSecurityDb.h b/features/FEATURE_BLE/ble/generic/KVStoreSecurityDb.h index 2d55eba9380..8ee56712b43 100644 --- a/features/FEATURE_BLE/ble/generic/KVStoreSecurityDb.h +++ b/features/FEATURE_BLE/ble/generic/KVStoreSecurityDb.h @@ -1,6 +1,8 @@ /* mbed Microcontroller Library * Copyright (c) 2018 ARM Limited * + * SPDX-License-Identifier: Apache-2.0 + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/features/FEATURE_BLE/ble/generic/MemorySecurityDb.h b/features/FEATURE_BLE/ble/generic/MemorySecurityDb.h index 6ae94ed01c8..6978651784e 100644 --- a/features/FEATURE_BLE/ble/generic/MemorySecurityDb.h +++ b/features/FEATURE_BLE/ble/generic/MemorySecurityDb.h @@ -1,6 +1,8 @@ /* mbed Microcontroller Library * Copyright (c) 2018 ARM Limited * + * SPDX-License-Identifier: Apache-2.0 + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/features/FEATURE_BLE/ble/generic/SecurityDb.h b/features/FEATURE_BLE/ble/generic/SecurityDb.h index 607e36347f4..3cd18e2f72d 100644 --- a/features/FEATURE_BLE/ble/generic/SecurityDb.h +++ b/features/FEATURE_BLE/ble/generic/SecurityDb.h @@ -1,6 +1,8 @@ /* mbed Microcontroller Library * Copyright (c) 2018 ARM Limited * + * SPDX-License-Identifier: Apache-2.0 + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/features/FEATURE_BLE/source/generic/FileSecurityDb.cpp b/features/FEATURE_BLE/source/generic/FileSecurityDb.cpp index 5d28f94d04a..80517dd071c 100644 --- a/features/FEATURE_BLE/source/generic/FileSecurityDb.cpp +++ b/features/FEATURE_BLE/source/generic/FileSecurityDb.cpp @@ -1,6 +1,8 @@ /* mbed Microcontroller Library * Copyright (c) 2018 ARM Limited * + * SPDX-License-Identifier: Apache-2.0 + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/features/FEATURE_BLE/source/generic/GenericGap.tpp b/features/FEATURE_BLE/source/generic/GenericGap.tpp index 2cafaf4a2bf..aabfd843487 100644 --- a/features/FEATURE_BLE/source/generic/GenericGap.tpp +++ b/features/FEATURE_BLE/source/generic/GenericGap.tpp @@ -1,6 +1,8 @@ /* mbed Microcontroller Library * Copyright (c) 2017-2017 ARM Limited * + * SPDX-License-Identifier: Apache-2.0 + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/features/FEATURE_BLE/source/generic/GenericGattClient.tpp b/features/FEATURE_BLE/source/generic/GenericGattClient.tpp index c48b0b4c515..af4ce3cb6b0 100644 --- a/features/FEATURE_BLE/source/generic/GenericGattClient.tpp +++ b/features/FEATURE_BLE/source/generic/GenericGattClient.tpp @@ -1,6 +1,8 @@ /* mbed Microcontroller Library * Copyright (c) 2017-2017 ARM Limited * + * SPDX-License-Identifier: Apache-2.0 + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/features/FEATURE_BLE/source/generic/GenericSecurityManager.tpp b/features/FEATURE_BLE/source/generic/GenericSecurityManager.tpp index 673651e2612..6a62a2faa1b 100644 --- a/features/FEATURE_BLE/source/generic/GenericSecurityManager.tpp +++ b/features/FEATURE_BLE/source/generic/GenericSecurityManager.tpp @@ -1,6 +1,8 @@ /* mbed Microcontroller Library * Copyright (c) 2017-2018 ARM Limited * + * SPDX-License-Identifier: Apache-2.0 + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/features/FEATURE_BLE/source/generic/KVStoreSecurityDb.cpp b/features/FEATURE_BLE/source/generic/KVStoreSecurityDb.cpp index f532ab124ce..bd65446ea05 100644 --- a/features/FEATURE_BLE/source/generic/KVStoreSecurityDb.cpp +++ b/features/FEATURE_BLE/source/generic/KVStoreSecurityDb.cpp @@ -1,6 +1,8 @@ /* mbed Microcontroller Library * Copyright (c) 2018 ARM Limited * + * SPDX-License-Identifier: Apache-2.0 + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at