set peer csrk on pal

pull/6932/head
paul-szczepanek-arm 2018-03-28 18:30:01 +01:00
parent 27ff79c6e5
commit cf6bf9968f
7 changed files with 108 additions and 10 deletions

View File

@ -116,6 +116,15 @@ public:
* The server does not acknowledge the status of the operation. * The server does not acknowledge the status of the operation.
*/ */
GATT_OP_WRITE_CMD = 0x02, GATT_OP_WRITE_CMD = 0x02,
/**
* Signed Write command.
*
* It is used to request the server to write the value of an attribute
* using a signed packet. The server does not acknowledge the status
* of the operation.
*/
GATT_OP_SIGNED_WRITE_CMD = 0x03
}; };
/** /**

View File

@ -313,13 +313,24 @@ private:
* Returns the CSRK for the connection. Called by the security db. * Returns the CSRK for the connection. Called by the security db.
* *
* @param[in] connectionHandle Handle to identify the connection. * @param[in] connectionHandle Handle to identify the connection.
* @param[in] entryKeys security entry containing keys. * @param[in] csrk connection signature resolving key.
*/ */
void return_csrk_cb( void return_csrk_cb(
pal::SecurityDb::entry_handle_t connection, pal::SecurityDb::entry_handle_t connection,
const csrk_t *csrk const csrk_t *csrk
); );
/**
* Set the peer CSRK for the connection. Called by the security db.
*
* @param[in] connectionHandle Handle to identify the connection.
* @param[in] csrk connection signature resolving key.
*/
void set_peer_csrk_cb(
pal::SecurityDb::entry_handle_t connection,
const csrk_t *csrk
);
/** /**
* Updates the entry for the connection with OOB data presence. * Updates the entry for the connection with OOB data presence.
* *

View File

@ -866,6 +866,18 @@ public:
const csrk_t &csrk const csrk_t &csrk
) = 0; ) = 0;
/**
* Set the peer CSRK for particular connection.
*
* @param[in] connection connection handle
* @param[in] csrk signing key
* @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure
*/
virtual ble_error_t set_peer_csrk(
connection_handle_t connection,
const csrk_t &csrk
) = 0;
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// Authentication // Authentication
// //

View File

@ -21,6 +21,8 @@
#include <ble/DiscoveredCharacteristic.h> #include <ble/DiscoveredCharacteristic.h>
#include "ble/generic/GenericGattClient.h" #include "ble/generic/GenericGattClient.h"
#include "ble/blecommon.h" #include "ble/blecommon.h"
#include "ble/BLEInstanceBase.h"
#include "ble/generic/GenericSecurityManager.h"
#include <algorithm> #include <algorithm>
using ble::pal::AttServerMessage; using ble::pal::AttServerMessage;
@ -1062,6 +1064,11 @@ ble_error_t GenericGattClient::read(
return err; return err;
} }
#define PREPARE_WRITE_HEADER_LENGTH 5
#define WRITE_HEADER_LENGTH 3
#define CMAC_LENGTH 8
#define MAC_COUNTER_LENGTH 4
ble_error_t GenericGattClient::write( ble_error_t GenericGattClient::write(
GattClient::WriteOp_t cmd, GattClient::WriteOp_t cmd,
Gap::Handle_t connection_handle, Gap::Handle_t connection_handle,
@ -1077,7 +1084,7 @@ ble_error_t GenericGattClient::write(
uint16_t mtu = get_mtu(connection_handle); uint16_t mtu = get_mtu(connection_handle);
if (cmd == GattClient::GATT_OP_WRITE_CMD) { if (cmd == GattClient::GATT_OP_WRITE_CMD) {
if (length > (uint16_t)(mtu - 3)) { if (length > (uint16_t)(mtu - WRITE_HEADER_LENGTH)) {
return BLE_ERROR_PARAM_OUT_OF_RANGE; return BLE_ERROR_PARAM_OUT_OF_RANGE;
} }
return _pal_client->write_without_response( return _pal_client->write_without_response(
@ -1085,10 +1092,20 @@ ble_error_t GenericGattClient::write(
attribute_handle, attribute_handle,
make_const_ArrayView(value, length) make_const_ArrayView(value, length)
); );
} else if (cmd == GattClient::GATT_OP_SIGNED_WRITE_CMD) {
if (length > (uint16_t)(mtu - WRITE_HEADER_LENGTH - CMAC_LENGTH - MAC_COUNTER_LENGTH)) {
return BLE_ERROR_PARAM_OUT_OF_RANGE;
}
return _pal_client->signed_write_without_response(
connection_handle,
attribute_handle,
make_const_ArrayView(value, length)
);
} else { } else {
uint8_t* data = NULL; uint8_t* data = NULL;
if (length > (uint16_t)(mtu - 3)) { if (length > (uint16_t)(mtu - WRITE_HEADER_LENGTH)) {
data = (uint8_t*) malloc(length); data = (uint8_t*) malloc(length);
if (data == NULL) { if (data == NULL) {
return BLE_ERROR_NO_MEM; return BLE_ERROR_NO_MEM;
@ -1115,7 +1132,7 @@ ble_error_t GenericGattClient::write(
err = _pal_client->queue_prepare_write( err = _pal_client->queue_prepare_write(
connection_handle, connection_handle,
attribute_handle, attribute_handle,
make_const_ArrayView(value, mtu - 5), make_const_ArrayView(value, mtu - PREPARE_WRITE_HEADER_LENGTH),
/* offset */ 0 /* offset */ 0
); );
} else { } else {

View File

@ -313,17 +313,27 @@ ble_error_t GenericSecurityManager::enableSigning(
} }
cb->signing_requested = enabled; cb->signing_requested = enabled;
cb->signing_override_default = false; cb->signing_override_default = true;
if (cb->encrypted) { if (cb->encrypted) {
return BLE_ERROR_INVALID_STATE; return BLE_ERROR_INVALID_STATE;
} }
if (!cb->csrk_stored && cb->signing_requested) {
init_signing(); if (cb->signing_requested) {
if (cb->is_master) { if (cb->csrk_stored) {
return requestPairing(connection); /* used the stored ones when available */
_db.get_entry_peer_csrk(
mbed::callback(this, &GenericSecurityManager::set_peer_csrk_cb),
cb->db_entry
);
} else { } else {
return slave_security_request(connection); /* crate keys if needed and exchange them */
init_signing();
if (cb->is_master) {
return requestPairing(connection);
} else {
return slave_security_request(connection);
}
} }
} }
@ -698,6 +708,18 @@ void GenericSecurityManager::set_ltk_cb(
} }
} }
void GenericSecurityManager::set_peer_csrk_cb(
pal::SecurityDb::entry_handle_t db_entry,
const csrk_t *csrk
) {
ControlBlock_t *cb = get_control_block(db_entry);
if (!cb) {
return;
}
_pal.set_peer_csrk(cb->connection, *csrk);
}
void GenericSecurityManager::return_csrk_cb( void GenericSecurityManager::return_csrk_cb(
pal::SecurityDb::entry_handle_t db_entry, pal::SecurityDb::entry_handle_t db_entry,
const csrk_t *csrk const csrk_t *csrk
@ -772,6 +794,17 @@ void GenericSecurityManager::on_connected(
if (dist_flags) { if (dist_flags) {
*static_cast<pal::SecurityDistributionFlags_t*>(cb) = *dist_flags; *static_cast<pal::SecurityDistributionFlags_t*>(cb) = *dist_flags;
} }
const bool signing = cb->signing_override_default ?
cb->signing_requested
: _default_key_distribution.get_signing();
if (signing && cb->csrk_stored) {
_db.get_entry_peer_csrk(
mbed::callback(this, &GenericSecurityManager::set_peer_csrk_cb),
cb->db_entry
);
}
} }
void GenericSecurityManager::on_disconnected( void GenericSecurityManager::on_disconnected(

View File

@ -239,6 +239,14 @@ public:
*/ */
virtual ble_error_t set_csrk(const csrk_t &csrk); virtual ble_error_t set_csrk(const csrk_t &csrk);
/**
* @see ::ble::pal::SecurityManager::set_peer_csrk
*/
virtual ble_error_t set_peer_csrk(
connection_handle_t connection,
const csrk_t &csrk
);
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// Authentication // Authentication
// //

View File

@ -272,6 +272,14 @@ ble_error_t CordioSecurityManager::set_csrk(const csrk_t& csrk)
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
ble_error_t CordioSecurityManager::set_peer_csrk(
connection_handle_t connection,
const csrk_t &csrk
) {
/* TODO implement */
return BLE_ERROR_NOT_IMPLEMENTED;
}
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// Global parameters // Global parameters
// //