address types added, secure connectins oob added

pull/6188/head
paul-szczepanek-arm 2018-02-06 10:17:31 +00:00
parent 32e91ac168
commit 9bc8c56df3
6 changed files with 117 additions and 32 deletions

View File

@ -340,11 +340,17 @@ typedef octet_type_t<8> rand_t;
typedef octet_type_t<8> random_data_t; typedef octet_type_t<8> random_data_t;
/** Out of band data exchanged during pairing */ /** 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 */ /** data to be encrypted */
typedef octet_type_t<16> encryption_block_t; 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 } // namespace ble
/** /**

View File

@ -612,8 +612,8 @@ public:
* Set the requirements for encryption key size. If the peer cannot comply with the requirements * Set the requirements for encryption key size. If the peer cannot comply with the requirements
* paring will fail. * paring will fail.
* *
* @param[in] minimumByteSize Smallest 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. * @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. * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason.
*/ */
virtual ble_error_t setEncryptionKeyRequirements(uint8_t minimumByteSize, uint8_t maximumByteSize) { virtual ble_error_t setEncryptionKeyRequirements(uint8_t minimumByteSize, uint8_t maximumByteSize) {

View File

@ -31,6 +31,7 @@ using ble::csrk_t;
using ble::ltk_t; using ble::ltk_t;
using ble::ediv_t; using ble::ediv_t;
using ble::rand_t; using ble::rand_t;
using ble::pal::connection_peer_address_type_t;
/* separate structs for keys to allow db implementation /* separate structs for keys to allow db implementation
* to minimise memory usage, only holding live connection * to minimise memory usage, only holding live connection
@ -39,8 +40,9 @@ using ble::rand_t;
struct SecurityEntry_t { struct SecurityEntry_t {
SecurityEntry_t() SecurityEntry_t()
: handle(0), : handle(0),
encryption_key_size (0), encryption_key_size(0),
peer_address_public(false), peer_address_public(false),
local_address_public(false),
csrk_stored(false), csrk_stored(false),
mitm_csrk(false), mitm_csrk(false),
ltk_stored(false), ltk_stored(false),
@ -77,6 +79,7 @@ struct SecurityEntry_t {
connection_handle_t handle; connection_handle_t handle;
uint8_t encryption_key_size; uint8_t encryption_key_size;
uint8_t peer_address_public:1; uint8_t peer_address_public:1;
uint8_t local_address_public:1;
uint8_t csrk_stored:1; uint8_t csrk_stored:1;
uint8_t mitm_csrk:1; uint8_t mitm_csrk:1;
@ -110,7 +113,9 @@ struct SecurityEntryKeys_t {
struct SecurityEntryIdentity_t { struct SecurityEntryIdentity_t {
address_t peer_identity_address; 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 */ /* callbacks for asynchronous data retrieval from the security db */
@ -319,13 +324,15 @@ public:
* synchronously through connection handle. * synchronously through connection handle.
* *
* @param[in] connection this will be the index for live entries. * @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. * @param[in] peer_address this address will be used to locate existing entry.
* *
* @return pointer to entry newly created or located existing entry. * @return pointer to entry newly created or located existing entry.
*/ */
virtual SecurityEntry_t* connect_entry( virtual SecurityEntry_t* connect_entry(
connection_handle_t connection, connection_handle_t connection,
const address_t peer_address connection_peer_address_type_t::type peer_address_type,
const address_t& peer_address
) = 0; ) = 0;
/** /**
@ -546,7 +553,7 @@ public:
store->key.rand = *rand; store->key.rand = *rand;
store->csrk = *csrk; store->csrk = *csrk;
size_t index = store - _db; size_t index = store - _db;
_identities[index].irk = *irk; _identities[index].peer_irk = *irk;
_identities[index].peer_identity_address = peer_address; _identities[index].peer_identity_address = peer_address;
} }
} }
@ -580,7 +587,7 @@ public:
db_store_t *store = get_store(connection); db_store_t *store = get_store(connection);
if (store) { if (store) {
size_t index = store - _db; size_t index = store - _db;
_identities[index].irk = *irk; _identities[index].peer_irk = *irk;
} }
} }
@ -618,11 +625,19 @@ public:
/* list management */ /* 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++) { for (size_t i = 0; i < MAX_ENTRIES; i++) {
if (_db[i].entry.connected) { if (_db[i].entry.connected) {
continue; 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; return &_db[i].entry;
} }
} }
@ -632,6 +647,8 @@ public:
if (!_db[i].entry.connected) { if (!_db[i].entry.connected) {
_db[i] = db_store_t(); _db[i] = db_store_t();
_identities[i] = SecurityEntryIdentity_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; return &_db[i].entry;
} }
} }

View File

@ -29,6 +29,7 @@ using ble::pal::address_t;
using ble::pal::advertising_peer_address_type_t; using ble::pal::advertising_peer_address_type_t;
using ble::pal::AuthenticationMask; using ble::pal::AuthenticationMask;
using ble::pal::KeyDistribution; using ble::pal::KeyDistribution;
using ble::pal::connection_peer_address_type_t;
using ble::irk_t; using ble::irk_t;
using ble::csrk_t; using ble::csrk_t;
@ -191,6 +192,19 @@ public:
Keypress_t keypress 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: protected:
GenericSecurityManager(ble::pal::SecurityManager& palImpl, GenericSecurityDb& dbImpl) GenericSecurityManager(ble::pal::SecurityManager& palImpl, GenericSecurityDb& dbImpl)
: _pal(palImpl), : _pal(palImpl),
@ -443,11 +457,17 @@ public:
* Called by GAP. * Called by GAP.
* *
* @param[in] connectionHandle Handle to identify the connection. * @param[in] connectionHandle Handle to identify the connection.
* @param peer_address Address of the connected device. * @param[in] is_master True if device is the master.
* @param 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. * @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: private:
/* handler is always a valid pointer */ /* handler is always a valid pointer */

View File

@ -354,24 +354,14 @@ public:
/** /**
* Request OOB data from the user application. * 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( virtual void on_legacy_pairing_oob_request(
connection_handle_t connection connection_handle_t connection
) = 0; ) = 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 // Keys
// //
@ -499,6 +489,35 @@ public:
const ediv_t *ediv, const ediv_t *ediv,
const rand_t *rand const rand_t *rand
) = 0; ) = 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 const csrk_t *csrk
) = 0; ) = 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 // Authentication
// //
@ -866,7 +891,7 @@ public:
* @param[in] passkey Set the passkey that shall be used by the security * @param[in] passkey Set the passkey that shall be used by the security
* manager when SecurityManagerEvent::on_passkey_display is called. If * manager when SecurityManagerEvent::on_passkey_display is called. If
* passkey is a null pointer then the security manager generates a random * 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 * @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 * @param[in] oob_data pointer to out of band data
* @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure * @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, connection_handle_t connection,
const oob_data_t *oob_data const oob_tk_t *oob_data
) = 0; ) = 0;
/** /**
@ -921,6 +946,14 @@ public:
Keypress_t keypress Keypress_t keypress
) = 0; ) = 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. */ /* Entry points for the underlying stack to report events back to the user. */
public: public:
/** /**

View File

@ -933,8 +933,18 @@ void GenericSecurityManager::on_disconnected(connection_handle_t connection) {
_db.sync(); _db.sync();
} }
void GenericSecurityManager::on_connected(connection_handle_t connection, address_t peer_address, bool is_master) { void GenericSecurityManager::on_connected(
SecurityEntry_t *entry = _db.connect_entry(connection, peer_address); 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) { if (!entry) {
return; return;
} }
@ -943,6 +953,5 @@ void GenericSecurityManager::on_connected(connection_handle_t connection, addres
entry->master = is_master; entry->master = is_master;
} }
} /* namespace generic */ } /* namespace generic */
} /* namespace ble */ } /* namespace ble */