From 9bc8c56df3107d89192576de70b546db87dd60f6 Mon Sep 17 00:00:00 2001 From: paul-szczepanek-arm <33840200+paul-szczepanek-arm@users.noreply.github.com> Date: Tue, 6 Feb 2018 10:17:31 +0000 Subject: [PATCH] address types added, secure connectins oob added --- features/FEATURE_BLE/ble/BLETypes.h | 8 ++- features/FEATURE_BLE/ble/SecurityManager.h | 4 +- .../ble/generic/GenericSecurityDb.h | 31 +++++++-- .../ble/generic/GenericSecurityManager.h | 26 +++++++- .../FEATURE_BLE/ble/pal/PalSecurityManager.h | 65 ++++++++++++++----- .../source/generic/GenericSecurityManager.cpp | 15 ++++- 6 files changed, 117 insertions(+), 32 deletions(-) diff --git a/features/FEATURE_BLE/ble/BLETypes.h b/features/FEATURE_BLE/ble/BLETypes.h index 5245eb9acc..ebae0f544a 100644 --- a/features/FEATURE_BLE/ble/BLETypes.h +++ b/features/FEATURE_BLE/ble/BLETypes.h @@ -340,11 +340,17 @@ typedef octet_type_t<8> rand_t; typedef octet_type_t<8> random_data_t; /** Out of band data exchanged during pairing */ -typedef octet_type_t<16> oob_data_t; +typedef octet_type_t<16> oob_tk_t; /**< legacy pairing TK */ +typedef octet_type_t<16> oob_rand_t; /**< secure connections oob random 128 value */ +typedef octet_type_t<16> oob_confirm_t; /**< secure connections oob confirmation value */ /** data to be encrypted */ typedef octet_type_t<16> encryption_block_t; +typedef octet_type_t<32> public_key_t; +typedef octet_type_t<32> private_key_t; +typedef octet_type_t<32> dhkey_t; + } // namespace ble /** diff --git a/features/FEATURE_BLE/ble/SecurityManager.h b/features/FEATURE_BLE/ble/SecurityManager.h index 4bc8c6e22e..ace846f77f 100644 --- a/features/FEATURE_BLE/ble/SecurityManager.h +++ b/features/FEATURE_BLE/ble/SecurityManager.h @@ -612,8 +612,8 @@ public: * Set the requirements for encryption key size. If the peer cannot comply with the requirements * paring will fail. * - * @param[in] minimumByteSize Smallest allowed encryption key size in bytes. - * @param[in] maximumByteSize Largest allowed encryption key size in bytes. + * @param[in] minimumByteSize Smallest allowed encryption key size in bytes. (no smaller than 7) + * @param[in] maximumByteSize Largest allowed encryption key size in bytes. (no larger than 16) * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. */ virtual ble_error_t setEncryptionKeyRequirements(uint8_t minimumByteSize, uint8_t maximumByteSize) { diff --git a/features/FEATURE_BLE/ble/generic/GenericSecurityDb.h b/features/FEATURE_BLE/ble/generic/GenericSecurityDb.h index e06f62fe56..f7b3171dff 100644 --- a/features/FEATURE_BLE/ble/generic/GenericSecurityDb.h +++ b/features/FEATURE_BLE/ble/generic/GenericSecurityDb.h @@ -31,6 +31,7 @@ using ble::csrk_t; using ble::ltk_t; using ble::ediv_t; using ble::rand_t; +using ble::pal::connection_peer_address_type_t; /* separate structs for keys to allow db implementation * to minimise memory usage, only holding live connection @@ -39,8 +40,9 @@ using ble::rand_t; struct SecurityEntry_t { SecurityEntry_t() : handle(0), - encryption_key_size (0), + encryption_key_size(0), peer_address_public(false), + local_address_public(false), csrk_stored(false), mitm_csrk(false), ltk_stored(false), @@ -77,6 +79,7 @@ struct SecurityEntry_t { connection_handle_t handle; uint8_t encryption_key_size; uint8_t peer_address_public:1; + uint8_t local_address_public:1; uint8_t csrk_stored:1; uint8_t mitm_csrk:1; @@ -110,7 +113,9 @@ struct SecurityEntryKeys_t { struct SecurityEntryIdentity_t { address_t peer_identity_address; - irk_t irk; + irk_t peer_irk; + address_t local_identity_address; + irk_t local_irk; }; /* callbacks for asynchronous data retrieval from the security db */ @@ -319,13 +324,15 @@ public: * synchronously through connection handle. * * @param[in] connection this will be the index for live entries. + * @param[in] peer_address_type type of address * @param[in] peer_address this address will be used to locate existing entry. * * @return pointer to entry newly created or located existing entry. */ virtual SecurityEntry_t* connect_entry( connection_handle_t connection, - const address_t peer_address + connection_peer_address_type_t::type peer_address_type, + const address_t& peer_address ) = 0; /** @@ -546,7 +553,7 @@ public: store->key.rand = *rand; store->csrk = *csrk; size_t index = store - _db; - _identities[index].irk = *irk; + _identities[index].peer_irk = *irk; _identities[index].peer_identity_address = peer_address; } } @@ -580,7 +587,7 @@ public: db_store_t *store = get_store(connection); if (store) { size_t index = store - _db; - _identities[index].irk = *irk; + _identities[index].peer_irk = *irk; } } @@ -618,11 +625,19 @@ public: /* list management */ - virtual SecurityEntry_t* connect_entry(connection_handle_t connection, address_t peer_address) { + virtual SecurityEntry_t* connect_entry( + connection_handle_t connection, + connection_peer_address_type_t::type peer_address_type, + const address_t& peer_address + ) { + const bool peer_address_public = + (peer_address_type == connection_peer_address_type_t::PUBLIC_ADDRESS); + for (size_t i = 0; i < MAX_ENTRIES; i++) { if (_db[i].entry.connected) { continue; - } else if (peer_address == _identities[i].peer_identity_address) { + } else if (peer_address == _identities[i].peer_identity_address + && _db[i].entry.peer_address_public == peer_address_public) { return &_db[i].entry; } } @@ -632,6 +647,8 @@ public: if (!_db[i].entry.connected) { _db[i] = db_store_t(); _identities[i] = SecurityEntryIdentity_t(); + _identities[i].peer_identity_address = peer_address; + _db[i].entry.peer_address_public = peer_address_public; return &_db[i].entry; } } diff --git a/features/FEATURE_BLE/ble/generic/GenericSecurityManager.h b/features/FEATURE_BLE/ble/generic/GenericSecurityManager.h index 6614527f71..daece01e2d 100644 --- a/features/FEATURE_BLE/ble/generic/GenericSecurityManager.h +++ b/features/FEATURE_BLE/ble/generic/GenericSecurityManager.h @@ -29,6 +29,7 @@ using ble::pal::address_t; using ble::pal::advertising_peer_address_type_t; using ble::pal::AuthenticationMask; using ble::pal::KeyDistribution; +using ble::pal::connection_peer_address_type_t; using ble::irk_t; using ble::csrk_t; @@ -191,6 +192,19 @@ public: Keypress_t keypress ); + virtual ble_error_t set_peer_oob( + const address_t& peer_address, + const oob_rand_t& random, + const oob_confirm_t& confirm + ); + + virtual ble_error_t get_local_oob( + connection_handle_t connection, + address_t& peer_address, + oob_rand_t& random, + oob_confirm_t& confirm + ) const; + protected: GenericSecurityManager(ble::pal::SecurityManager& palImpl, GenericSecurityDb& dbImpl) : _pal(palImpl), @@ -443,11 +457,17 @@ public: * Called by GAP. * * @param[in] connectionHandle Handle to identify the connection. - * @param peer_address Address of the connected device. - * @param is_master True if device is the master. + * @param[in] is_master True if device is the master. + * @param[in] peer_address_type type of address + * @param[in] peer_address Address of the connected device. * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. */ - virtual void on_connected(connection_handle_t connection, address_t peer_address, bool is_master); + virtual void on_connected( + connection_handle_t connection, + bool is_master, + connection_peer_address_type_t::type peer_address_type, + const address_t &peer_address + ); private: /* handler is always a valid pointer */ diff --git a/features/FEATURE_BLE/ble/pal/PalSecurityManager.h b/features/FEATURE_BLE/ble/pal/PalSecurityManager.h index 1702faf077..2313a24281 100644 --- a/features/FEATURE_BLE/ble/pal/PalSecurityManager.h +++ b/features/FEATURE_BLE/ble/pal/PalSecurityManager.h @@ -354,24 +354,14 @@ public: /** * Request OOB data from the user application. * - * @param[in] connection connection handle + * @param[in] connection connection handlendle + * @note shall be followed by: pal::SecurityManager::legacy_pairing_oob_data_request_reply + * or a cancellation of the procedure. */ virtual void on_legacy_pairing_oob_request( connection_handle_t connection ) = 0; - /** - * Request oob data entered during pairing. - * - * @param[in] connection connection handle - * @note shall be followed by: pal::SecurityManager::oob_data_request_reply - * or a cancellation of the procedure. - */ - virtual void on_oob_request( - connection_handle_t connection - ) = 0; - - //////////////////////////////////////////////////////////////////////////// // Keys // @@ -499,6 +489,35 @@ public: const ediv_t *ediv, const rand_t *rand ) = 0; + + /** + * Store the peer's public keys. + * + * @param[in] connection connection handle + * @param[in] public_key_x peer public key (x coordinate) received during pairing + * @param[in] public_key_y peer public key (y coordinate) received during pairing + */ + virtual void on_keys_distributed_public_key( + connection_handle_t connection, + const public_key_t &public_key_x, + const public_key_t &public_key_y + ) = 0; + + /** + * Provide the local public key. + * + * @param[in] public_key_x newly generated public key (x coordinate) + * @param[in] public_key_y newly generated public key (y coordinate) + */ + virtual void on_public_key_generated( + const public_key_t &public_key_x, + const public_key_t &public_key_y + ) = 0; + + virtual void on_local_secure_connections_oob_data_generated( + const oob_confirm_t &confirm, + const oob_rand_t &random + ) = 0; }; /** @@ -769,6 +788,12 @@ public: const csrk_t *csrk ) = 0; + /** + * Generate the Public key. This will also generate the private key. + * Public key will be returned as an event handler callback when it's ready. + */ + virtual void generate_public_key() = 0; + //////////////////////////////////////////////////////////////////////////// // Authentication // @@ -866,7 +891,7 @@ public: * @param[in] passkey Set the passkey that shall be used by the security * manager when SecurityManagerEvent::on_passkey_display is called. If * passkey is a null pointer then the security manager generates a random - * passkey everytime it calls SecurityManagerEvent::on_passkey_display. + * passkey every time it calls SecurityManagerEvent::on_passkey_display. * * @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure */ @@ -891,9 +916,9 @@ public: * @param[in] oob_data pointer to out of band data * @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure */ - virtual ble_error_t oob_data_request_reply( + virtual ble_error_t legacy_pairing_oob_data_request_reply( connection_handle_t connection, - const oob_data_t *oob_data + const oob_tk_t *oob_data ) = 0; /** @@ -921,6 +946,14 @@ public: Keypress_t keypress ) = 0; + virtual ble_error_t get_local_secure_connections_oob_data() = 0; + + virtual ble_error_t set_peer_secure_connections_oob_data( + const address_t &peer_address, + const oob_rand_t &random, + const oob_confirm_t &confirm + ) = 0; + /* Entry points for the underlying stack to report events back to the user. */ public: /** diff --git a/features/FEATURE_BLE/source/generic/GenericSecurityManager.cpp b/features/FEATURE_BLE/source/generic/GenericSecurityManager.cpp index b649b4e987..83676914db 100644 --- a/features/FEATURE_BLE/source/generic/GenericSecurityManager.cpp +++ b/features/FEATURE_BLE/source/generic/GenericSecurityManager.cpp @@ -933,8 +933,18 @@ void GenericSecurityManager::on_disconnected(connection_handle_t connection) { _db.sync(); } -void GenericSecurityManager::on_connected(connection_handle_t connection, address_t peer_address, bool is_master) { - SecurityEntry_t *entry = _db.connect_entry(connection, peer_address); +void GenericSecurityManager::on_connected( + connection_handle_t connection, + bool is_master, + connection_peer_address_type_t::type peer_address_type, + const address_t &peer_address +) { + SecurityEntry_t *entry = _db.connect_entry( + connection, + peer_address_type, + peer_address + ); + if (!entry) { return; } @@ -943,6 +953,5 @@ void GenericSecurityManager::on_connected(connection_handle_t connection, addres entry->master = is_master; } - } /* namespace generic */ } /* namespace ble */