monitor for signing events and set local counter

pull/6932/head
paul-szczepanek-arm 2018-04-04 19:24:00 +01:00
parent 1d74dfa1f9
commit 57149b69e4
15 changed files with 148 additions and 55 deletions

View File

@ -20,6 +20,7 @@
#include <algorithm> #include <algorithm>
#include "ble/GattClient.h" #include "ble/GattClient.h"
#include "ble/pal/PalGattClient.h" #include "ble/pal/PalGattClient.h"
#include "ble/pal/SigningEventMonitor.h"
// IMPORTANT: private header. Not part of the public interface. // IMPORTANT: private header. Not part of the public interface.
@ -31,7 +32,8 @@ namespace generic {
* It requires a pal::GattClient injected at construction site. * It requires a pal::GattClient injected at construction site.
* @attention: Not part of the public interface of BLE API. * @attention: Not part of the public interface of BLE API.
*/ */
class GenericGattClient : public GattClient { class GenericGattClient : public GattClient,
public pal::SigningEventMonitor {
public: public:
/** /**
* Create a GenericGattClient from a pal::GattClient * Create a GenericGattClient from a pal::GattClient
@ -114,6 +116,11 @@ public:
*/ */
virtual ble_error_t reset(void); virtual ble_error_t reset(void);
/**
* @see ble::pal::SigningEventMonitor::set_signing_event_handler
*/
virtual void set_signing_event_handler(pal::SigningEventMonitor::EventHandler *signing_event_handler);
private: private:
struct ProcedureControlBlock; struct ProcedureControlBlock;
struct DiscoveryControlBlock; struct DiscoveryControlBlock;
@ -136,6 +143,7 @@ private:
pal::GattClient* const _pal_client; pal::GattClient* const _pal_client;
ServiceDiscovery::TerminationCallback_t _termination_callback; ServiceDiscovery::TerminationCallback_t _termination_callback;
pal::SigningEventMonitor::EventHandler* _signing_event_handler;
mutable ProcedureControlBlock* control_blocks; mutable ProcedureControlBlock* control_blocks;
bool _is_reseting; bool _is_reseting;
}; };

View File

@ -22,6 +22,7 @@
#include "ble/pal/SecurityDb.h" #include "ble/pal/SecurityDb.h"
#include "platform/Callback.h" #include "platform/Callback.h"
#include "ble/pal/ConnectionEventMonitor.h" #include "ble/pal/ConnectionEventMonitor.h"
#include "ble/pal/SigningEventMonitor.h"
#include "ble/generic/GenericGap.h" #include "ble/generic/GenericGap.h"
#include "ble/pal/PalSecurityManager.h" #include "ble/pal/PalSecurityManager.h"
@ -32,7 +33,8 @@ typedef SecurityManager::SecurityIOCapabilities_t SecurityIOCapabilities_t;
class GenericSecurityManager : public SecurityManager, class GenericSecurityManager : public SecurityManager,
public pal::SecurityManager::EventHandler, public pal::SecurityManager::EventHandler,
public pal::ConnectionEventMonitor::EventHandler { public pal::ConnectionEventMonitor::EventHandler,
public pal::SigningEventMonitor::EventHandler {
public: public:
typedef ble::pal::SecurityDistributionFlags_t SecurityDistributionFlags_t; typedef ble::pal::SecurityDistributionFlags_t SecurityDistributionFlags_t;
typedef ble::pal::SecurityEntryKeys_t SecurityEntryKeys_t; typedef ble::pal::SecurityEntryKeys_t SecurityEntryKeys_t;
@ -234,10 +236,12 @@ public:
GenericSecurityManager( GenericSecurityManager(
pal::SecurityManager &palImpl, pal::SecurityManager &palImpl,
pal::SecurityDb &dbImpl, pal::SecurityDb &dbImpl,
pal::ConnectionEventMonitor &connMonitorImpl pal::ConnectionEventMonitor &connMonitorImpl,
pal::SigningEventMonitor &signingMonitorImpl
) : _pal(palImpl), ) : _pal(palImpl),
_db(dbImpl), _db(dbImpl),
_connection_monitor(connMonitorImpl), _connection_monitor(connMonitorImpl),
_signing_monitor(signingMonitorImpl),
_default_authentication(0), _default_authentication(0),
_default_key_distribution(pal::KeyDistribution::KEY_DISTRIBUTION_ALL), _default_key_distribution(pal::KeyDistribution::KEY_DISTRIBUTION_ALL),
_pairing_authorisation_required(false), _pairing_authorisation_required(false),
@ -467,6 +471,7 @@ private:
pal::SecurityManager &_pal; pal::SecurityManager &_pal;
pal::SecurityDb &_db; pal::SecurityDb &_db;
pal::ConnectionEventMonitor &_connection_monitor; pal::ConnectionEventMonitor &_connection_monitor;
pal::SigningEventMonitor &_signing_monitor;
/* OOB data */ /* OOB data */
address_t _oob_local_address; address_t _oob_local_address;
@ -547,6 +552,10 @@ public:
connection_handle_t connection connection_handle_t connection
); );
/** @copydoc ble::pal::SecurityManager::on_signed_write
*/
virtual void on_signed_write();
/** @copydoc ble::pal::SecurityManager::on_slave_security_request /** @copydoc ble::pal::SecurityManager::on_slave_security_request
*/ */
virtual void on_slave_security_request( virtual void on_slave_security_request(

View File

@ -485,7 +485,6 @@ struct AttClient {
* request to. * request to.
* @param attribute_handle Handle of the attribute to write. * @param attribute_handle Handle of the attribute to write.
* @param value Value to write. It can't be longer than (mtu - 15). * @param value Value to write. It can't be longer than (mtu - 15).
* @param sign_counter Signed write counter to use for this command.
* *
* @note the authentication signature to send with this request is * @note the authentication signature to send with this request is
* computed by the implementation following the rules defined in BLUETOOTH * computed by the implementation following the rules defined in BLUETOOTH
@ -499,8 +498,7 @@ struct AttClient {
virtual ble_error_t signed_write_command( virtual ble_error_t signed_write_command(
connection_handle_t connection_handle, connection_handle_t connection_handle,
attribute_handle_t attribute_handle, attribute_handle_t attribute_handle,
const ArrayView<const uint8_t>& value, const ArrayView<const uint8_t>& value
uint32_t sign_counter
) = 0; ) = 0;
/** /**

View File

@ -221,14 +221,12 @@ public:
virtual ble_error_t signed_write_without_response( virtual ble_error_t signed_write_without_response(
connection_handle_t connection_handle, connection_handle_t connection_handle,
attribute_handle_t characteristic_value_handle, attribute_handle_t characteristic_value_handle,
const ArrayView<const uint8_t>& value, const ArrayView<const uint8_t>& value
uint32_t sign_counter
) { ) {
return _client.signed_write_command( return _client.signed_write_command(
connection_handle, connection_handle,
characteristic_value_handle, characteristic_value_handle,
value, value
sign_counter
); );
} }

View File

@ -455,15 +455,13 @@ public:
* @param connection_handle The handle of the connection to send this request to. * @param connection_handle The handle of the connection to send this request to.
* @param attribute_handle Handle of the attribute to write. * @param attribute_handle Handle of the attribute to write.
* @param value The value to write. * @param value The value to write.
* @param sign_counter Signed write counter to use for this command.
* *
* @return BLE_ERROR_NONE or an appropriate error. * @return BLE_ERROR_NONE or an appropriate error.
*/ */
virtual ble_error_t signed_write_without_response( virtual ble_error_t signed_write_without_response(
connection_handle_t connection_handle, connection_handle_t connection_handle,
attribute_handle_t characteristic_value_handle, attribute_handle_t characteristic_value_handle,
const ArrayView<const uint8_t>& value, const ArrayView<const uint8_t>& value
uint32_t sign_counter
) = 0; ) = 0;
/** /**

View File

@ -280,27 +280,6 @@ public:
connection_handle_t connection connection_handle_t connection
) = 0; ) = 0;
/**
* Set new signed write peer counter.
*
* @param[in] connection connection handle
* @param[in] sign_coutner counter received from peer
*/
virtual void on_signed_write_received(
connection_handle_t connection,
uint32_t sign_coutner
) = 0;
/**
* Indicate that signed data was rejected due to verification failure. This could
* be due to an invalid CSRK key.
*
* @param[in] connection connection handle
*/
virtual void on_signed_write_verification_failure(
connection_handle_t connection
) = 0;
/** /**
* Ask the stack to evaluate the security request received from the slave. * Ask the stack to evaluate the security request received from the slave.
* This might result in the stack enabling encryption, or pairing/re-pairing. * This might result in the stack enabling encryption, or pairing/re-pairing.
@ -879,11 +858,13 @@ public:
/** /**
* Set the local CSRK. * Set the local CSRK.
* *
* @param[in] csrk signing key * @param[in] csrk local signing key
* @param[in] sign_counter local signing counter
* @return BLE_ERROR_NONE On success, else an error code indicating reason for failure * @return BLE_ERROR_NONE On success, else an error code indicating reason for failure
*/ */
virtual ble_error_t set_csrk( virtual ble_error_t set_csrk(
const csrk_t &csrk const csrk_t &csrk,
uint32_t sign_counter
) = 0; ) = 0;
/** /**
@ -891,6 +872,8 @@ public:
* *
* @param[in] connection connection handle * @param[in] connection connection handle
* @param[in] csrk signing key * @param[in] csrk signing key
* @param[in] authenticated is the CSRK authenticated
* @param[in] sign_counter signing counter
* @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 set_peer_csrk( virtual ble_error_t set_peer_csrk(

View File

@ -0,0 +1,74 @@
/* mbed Microcontroller Library
* Copyright (c) 2017-2017 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.
*/
#ifndef MBED_BLE_SIGNING_EVENT_MONITOR
#define MBED_BLE_SIGNING_EVENT_MONITOR
#include "ble/BLETypes.h"
namespace ble {
namespace pal {
/**
* Implemented by classes that need to be notified of signing events.
* Notification is done by calling functions in the passed in event handler
*/
class SigningEventMonitor {
public:
/**
* Implemented by classes that are reacting to signing events.
*/
class EventHandler {
public:
/**
* Set new signed write peer counter.
*
* @param[in] connection connection handle
* @param[in] sign_coutner counter received from peer
*/
virtual void on_signed_write_received(
connection_handle_t connection,
uint32_t sign_coutner
) = 0;
/**
* Indicate that signed data was rejected due to verification failure. This could
* be due to an invalid CSRK key.
*
* @param[in] connection connection handle
*/
virtual void on_signed_write_verification_failure(
connection_handle_t connection
) = 0;
/**
* Notify a new signed write cmd was executed.
*/
virtual void on_signed_write() = 0;
};
/**
* Register a handler for singing events to be used internally and serviced first.
*
* @param[in] signing_event_handler Event handler being registered.
*/
virtual void set_signing_event_handler(EventHandler *signing_event_handler) = 0;
};
} // namespace pal
} // namespace ble
#endif /* MBED_BLE_SIGNING_EVENT_MONITOR */

View File

@ -936,6 +936,7 @@ struct GenericGattClient::DescriptorDiscoveryControlBlock : public ProcedureCont
GenericGattClient::GenericGattClient(pal::GattClient* pal_client) : GenericGattClient::GenericGattClient(pal::GattClient* pal_client) :
_pal_client(pal_client), _pal_client(pal_client),
_termination_callback(), _termination_callback(),
_signing_event_handler(NULL),
control_blocks(NULL), control_blocks(NULL),
_is_reseting(false) { _is_reseting(false) {
_pal_client->when_server_message_received( _pal_client->when_server_message_received(
@ -1097,14 +1098,15 @@ ble_error_t GenericGattClient::write(
if (length > (uint16_t) (mtu - WRITE_HEADER_LENGTH - CMAC_LENGTH - MAC_COUNTER_LENGTH)) { if (length > (uint16_t) (mtu - WRITE_HEADER_LENGTH - CMAC_LENGTH - MAC_COUNTER_LENGTH)) {
return BLE_ERROR_PARAM_OUT_OF_RANGE; return BLE_ERROR_PARAM_OUT_OF_RANGE;
} }
GenericSecurityManager* sm = (GenericSecurityManager*)(&createBLEInstance()->getSecurityManager()); ble_error_t status = _pal_client->signed_write_without_response(
const uint32_t sign_counter = sm->get_next_sign_counter();
return _pal_client->signed_write_without_response(
connection_handle, connection_handle,
attribute_handle, attribute_handle,
make_const_ArrayView(value, length), make_const_ArrayView(value, length)
sign_counter
); );
if (_signing_event_handler && (status == BLE_ERROR_NONE)) {
_signing_event_handler->on_signed_write();
}
return status;
} else { } else {
uint8_t* data = NULL; uint8_t* data = NULL;
@ -1257,6 +1259,12 @@ ble_error_t GenericGattClient::reset(void) {
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
void GenericGattClient::set_signing_event_handler(
EventHandler *signing_event_handler
) {
_signing_event_handler = signing_event_handler;
}
void GenericGattClient::on_termination(Gap::Handle_t connection_handle) { void GenericGattClient::on_termination(Gap::Handle_t connection_handle) {
if (_termination_callback) { if (_termination_callback) {
_termination_callback(connection_handle); _termination_callback(connection_handle);

View File

@ -71,6 +71,7 @@ ble_error_t GenericSecurityManager::init(
} }
_connection_monitor.set_connection_event_handler(this); _connection_monitor.set_connection_event_handler(this);
_signing_monitor.set_signing_event_handler(this);
_pal.set_event_handler(this); _pal.set_event_handler(this);
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
@ -640,7 +641,8 @@ ble_error_t GenericSecurityManager::oobReceived(
ble_error_t GenericSecurityManager::init_signing() { ble_error_t GenericSecurityManager::init_signing() {
const csrk_t *pcsrk = _db.get_local_csrk(); const csrk_t *pcsrk = _db.get_local_csrk();
_local_sign_counter = _db.get_local_sign_counter(); uint32_t local_sign_counter = _db.get_local_sign_counter();
if (!pcsrk) { if (!pcsrk) {
csrk_t csrk; csrk_t csrk;
@ -651,9 +653,10 @@ ble_error_t GenericSecurityManager::init_signing() {
pcsrk = &csrk; pcsrk = &csrk;
_db.set_local_csrk(csrk); _db.set_local_csrk(csrk);
_db.set_local_sign_counter(_local_sign_counter); _db.set_local_sign_counter(local_sign_counter);
} }
return _pal.set_csrk(*pcsrk);
return _pal.set_csrk(*pcsrk, local_sign_counter);
} }
ble_error_t GenericSecurityManager::get_random_data(uint8_t *buffer, size_t size) { ble_error_t GenericSecurityManager::get_random_data(uint8_t *buffer, size_t size) {
@ -947,6 +950,7 @@ void GenericSecurityManager::on_pairing_completed(connection_handle_t connection
void GenericSecurityManager::on_valid_mic_timeout(connection_handle_t connection) { void GenericSecurityManager::on_valid_mic_timeout(connection_handle_t connection) {
(void)connection; (void)connection;
} }
void GenericSecurityManager::on_signed_write_received( void GenericSecurityManager::on_signed_write_received(
connection_handle_t connection, connection_handle_t connection,
uint32_t sign_counter uint32_t sign_counter
@ -983,6 +987,10 @@ void GenericSecurityManager::on_signed_write_verification_failure(
} }
} }
void GenericSecurityManager::on_signed_write() {
_db.set_local_sign_counter(_db.get_local_sign_counter() + 1);
}
void GenericSecurityManager::on_slave_security_request( void GenericSecurityManager::on_slave_security_request(
connection_handle_t connection, connection_handle_t connection,
AuthenticationMask authentication AuthenticationMask authentication

View File

@ -211,13 +211,12 @@ public:
virtual ble_error_t signed_write_command( virtual ble_error_t signed_write_command(
connection_handle_t connection_handle, connection_handle_t connection_handle,
attribute_handle_t attribute_handle, attribute_handle_t attribute_handle,
const ArrayView<const uint8_t>& value, const ArrayView<const uint8_t>& value
uint32_t sign_counter
) { ) {
AttcSignedWriteCmd( AttcSignedWriteCmd(
connection_handle, connection_handle,
attribute_handle, attribute_handle,
sign_counter, /*TODO: get sign counter from cordio sm */0,
value.size(), value.size(),
const_cast<uint8_t*>(value.data()) const_cast<uint8_t*>(value.data())
); );

View File

@ -237,7 +237,10 @@ public:
/** /**
* @see ::ble::pal::SecurityManager::set_csrk * @see ::ble::pal::SecurityManager::set_csrk
*/ */
virtual ble_error_t set_csrk(const csrk_t &csrk); virtual ble_error_t set_csrk(
const csrk_t &csrk,
uint32_t sign_counter
);
/** /**
* @see ::ble::pal::SecurityManager::set_peer_csrk * @see ::ble::pal::SecurityManager::set_peer_csrk
@ -321,6 +324,7 @@ public:
private: private:
bool _use_default_passkey; bool _use_default_passkey;
passkey_num_t _default_passkey; passkey_num_t _default_passkey;
uint32_t _local_sign_counter;
bool _lesc_keys_generated; bool _lesc_keys_generated;
uint8_t _public_key_x[SEC_ECC_KEY_LEN]; uint8_t _public_key_x[SEC_ECC_KEY_LEN];
}; };

View File

@ -219,10 +219,14 @@ const SecurityManager& BLE::getSecurityManager() const
{ {
static pal::MemorySecurityDb m_db; static pal::MemorySecurityDb m_db;
pal::vendor::cordio::CordioSecurityManager &m_pal = pal::vendor::cordio::CordioSecurityManager::get_security_manager(); pal::vendor::cordio::CordioSecurityManager &m_pal = pal::vendor::cordio::CordioSecurityManager::get_security_manager();
BLE *self = const_cast<BLE*>(this);
static generic::GenericSecurityManager m_instance( static generic::GenericSecurityManager m_instance(
m_pal, m_pal,
m_db, m_db,
const_cast<generic::GenericGap&>(getGenericGap()) const_cast<generic::GenericGap&>(getGenericGap()),
static_cast<generic::GenericGattClient&>(self->getGattClient())
); );
return m_instance; return m_instance;

View File

@ -31,6 +31,7 @@ CordioSecurityManager::CordioSecurityManager() :
::ble::pal::SecurityManager(), ::ble::pal::SecurityManager(),
_use_default_passkey(false), _use_default_passkey(false),
_default_passkey(0), _default_passkey(0),
_local_sign_counter(0),
_lesc_keys_generated(false), _lesc_keys_generated(false),
_public_key_x() _public_key_x()
{ {
@ -267,8 +268,11 @@ ble_error_t CordioSecurityManager::set_irk(const irk_t& irk)
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
ble_error_t CordioSecurityManager::set_csrk(const csrk_t& csrk) ble_error_t CordioSecurityManager::set_csrk(
{ const csrk_t& csrk,
uint32_t sign_counter
) {
_local_sign_counter = sign_counter;
DmSecSetLocalCsrk(const_cast<uint8_t*>(csrk.data())); DmSecSetLocalCsrk(const_cast<uint8_t*>(csrk.data()));
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }

View File

@ -300,8 +300,7 @@ ble_error_t nRF5XGattClient::write_without_response(
ble_error_t nRF5XGattClient::signed_write_without_response( ble_error_t nRF5XGattClient::signed_write_without_response(
connection_handle_t connection_handle, connection_handle_t connection_handle,
attribute_handle_t characteristic_value_handle, attribute_handle_t characteristic_value_handle,
const ArrayView<const uint8_t>& value, const ArrayView<const uint8_t>& value
uint32_t sign_counter
) { ) {
ble_gattc_write_params_t write_params = { ble_gattc_write_params_t write_params = {
BLE_GATT_OP_SIGN_WRITE_CMD, BLE_GATT_OP_SIGN_WRITE_CMD,

View File

@ -153,8 +153,7 @@ public:
virtual ble_error_t signed_write_without_response( virtual ble_error_t signed_write_without_response(
connection_handle_t connection_handle, connection_handle_t connection_handle,
attribute_handle_t characteristic_value_handle, attribute_handle_t characteristic_value_handle,
const ArrayView<const uint8_t>& value, const ArrayView<const uint8_t>& value
uint32_t sign_counter
); );
/** /**