BLE Nordic: Support LESC.

pull/6932/head
Vincent Coubard 2018-03-29 17:24:46 +01:00
parent f0e18fa007
commit 3272863f83
2 changed files with 157 additions and 58 deletions

View File

@ -76,6 +76,11 @@ struct nRF5xSecurityManager::pairing_control_block_t {
ble_gap_id_key_t peer_id_key; ble_gap_id_key_t peer_id_key;
ble_gap_sign_info_t peer_sign_key; ble_gap_sign_info_t peer_sign_key;
ble_gap_lesc_p256_pk_t peer_pk; ble_gap_lesc_p256_pk_t peer_pk;
// flag required to help DHKey computation/process; should be removed with
// later versions of the softdevice
uint8_t own_oob:1;
uint8_t peer_oob:1;
}; };
nRF5xSecurityManager::nRF5xSecurityManager() nRF5xSecurityManager::nRF5xSecurityManager()
@ -90,7 +95,7 @@ nRF5xSecurityManager::nRF5xSecurityManager()
nRF5xSecurityManager::~nRF5xSecurityManager() nRF5xSecurityManager::~nRF5xSecurityManager()
{ {
terminate();
} }
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
@ -99,19 +104,27 @@ nRF5xSecurityManager::~nRF5xSecurityManager()
ble_error_t nRF5xSecurityManager::initialize() ble_error_t nRF5xSecurityManager::initialize()
{ {
// FIXME: generate and set public and private keys if (_crypto.generate_keys(X, Y, secret)) {
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
}
return BLE_ERROR_INTERNAL_STACK_FAILURE;
} }
ble_error_t nRF5xSecurityManager::terminate() ble_error_t nRF5xSecurityManager::terminate()
{ {
release_all_pairing_cb();
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
ble_error_t nRF5xSecurityManager::reset() ble_error_t nRF5xSecurityManager::reset()
{ {
// FIXME: reset public and private keys ble_error_t err = terminate();
return BLE_ERROR_NONE; if (err) {
return err;
}
return initialize();
} }
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
@ -162,6 +175,7 @@ ble_error_t nRF5xSecurityManager::send_pairing_request(
KeyDistribution initiator_dist, KeyDistribution initiator_dist,
KeyDistribution responder_dist KeyDistribution responder_dist
) { ) {
printf("nRF5xSecurityManager::send_pairing_request\r\n");
// allocate the control block required for the procedure completion // allocate the control block required for the procedure completion
pairing_control_block_t* pairing_cb = allocate_pairing_cb(connection); pairing_control_block_t* pairing_cb = allocate_pairing_cb(connection);
if (!pairing_cb) { if (!pairing_cb) {
@ -173,6 +187,10 @@ ble_error_t nRF5xSecurityManager::send_pairing_request(
initiator_dist.set_signing(false); initiator_dist.set_signing(false);
responder_dist.set_signing(false); responder_dist.set_signing(false);
// override link parameter
initiator_dist.set_link(false);
responder_dist.set_link(false);
ble_gap_sec_params_t security_params = make_security_params( ble_gap_sec_params_t security_params = make_security_params(
oob_data_flag, oob_data_flag,
authentication_requirements, authentication_requirements,
@ -209,6 +227,10 @@ ble_error_t nRF5xSecurityManager::send_pairing_response(
initiator_dist.set_signing(false); initiator_dist.set_signing(false);
responder_dist.set_signing(false); responder_dist.set_signing(false);
// override link parameter
initiator_dist.set_link(false);
responder_dist.set_link(false);
ble_gap_sec_params_t security_params = make_security_params( ble_gap_sec_params_t security_params = make_security_params(
oob_data_flag, oob_data_flag,
authentication_requirements, authentication_requirements,
@ -239,7 +261,7 @@ ble_error_t nRF5xSecurityManager::send_pairing_response(
ble_error_t nRF5xSecurityManager::cancel_pairing( ble_error_t nRF5xSecurityManager::cancel_pairing(
connection_handle_t connection, pairing_failure_t reason connection_handle_t connection, pairing_failure_t reason
) { ) {
// this is the default path except when a key is expected to be enterred by // this is the default path except when a key is expected to be entered by
// the user. // the user.
uint32_t err = sd_ble_gap_sec_params_reply( uint32_t err = sd_ble_gap_sec_params_reply(
connection, connection,
@ -272,9 +294,7 @@ ble_error_t nRF5xSecurityManager::cancel_pairing(
ble_error_t nRF5xSecurityManager::get_secure_connections_support( ble_error_t nRF5xSecurityManager::get_secure_connections_support(
bool &enabled bool &enabled
) { ) {
// NRF5x platforms support secure connections enabled = true;
// FIXME: set to true once the ECC library is included
enabled = false;
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
@ -399,7 +419,7 @@ ble_error_t nRF5xSecurityManager::encrypt_data(
const byte_array_t<16> &key, const byte_array_t<16> &key,
encryption_block_t &data encryption_block_t &data
) { ) {
// FIXME: With signing ? // FIXME: Implement in LescCrypto ?
return BLE_ERROR_NOT_IMPLEMENTED; return BLE_ERROR_NOT_IMPLEMENTED;
} }
@ -446,8 +466,8 @@ ble_error_t nRF5xSecurityManager::set_ltk(
uint32_t err = sd_ble_gap_sec_info_reply( uint32_t err = sd_ble_gap_sec_info_reply(
connection, connection,
&enc_info, &enc_info,
NULL, /* id info */ NULL,
NULL // Not supported /* sign info */ NULL // Not supported
); );
return convert_sd_error(err); return convert_sd_error(err);
@ -520,6 +540,11 @@ ble_error_t nRF5xSecurityManager::set_display_passkey(passkey_num_t passkey)
ble_error_t nRF5xSecurityManager::passkey_request_reply( ble_error_t nRF5xSecurityManager::passkey_request_reply(
connection_handle_t connection, const passkey_num_t passkey connection_handle_t connection, const passkey_num_t passkey
) { ) {
pairing_control_block_t* pairing_cb = get_pairing_cb(connection);
if (!pairing_cb) {
return BLE_ERROR_INVALID_STATE;
}
PasskeyAscii pkasc(passkey); PasskeyAscii pkasc(passkey);
uint32_t err = sd_ble_gap_auth_key_reply( uint32_t err = sd_ble_gap_auth_key_reply(
connection, connection,
@ -530,6 +555,37 @@ ble_error_t nRF5xSecurityManager::passkey_request_reply(
return convert_sd_error(err); return convert_sd_error(err);
} }
ble_error_t nRF5xSecurityManager::secure_connections_oob_request_reply(
connection_handle_t connection,
const oob_lesc_value_t &local_random,
const oob_lesc_value_t &peer_random,
const oob_confirm_t &peer_confirm
) {
pairing_control_block_t* pairing_cb = get_pairing_cb(connection);
if (!pairing_cb) {
return BLE_ERROR_INVALID_STATE;
}
ble_gap_lesc_oob_data_t oob_own;
ble_gap_lesc_oob_data_t oob_peer;
// is own address important ?
memcpy(oob_own.r, local_random.data(), local_random.size());
// FIXME: What to do with local confirm ???
// is peer address important ?
memcpy(oob_peer.r, peer_random.data(), peer_random.size());
memcpy(oob_peer.c, peer_confirm.data(), peer_confirm.size());
uint32_t err = sd_ble_gap_lesc_oob_data_set(
connection,
pairing_cb->own_oob ? &oob_own : NULL,
pairing_cb->peer_oob ? &oob_peer : NULL
);
return convert_sd_error(err);
}
ble_error_t nRF5xSecurityManager::legacy_pairing_oob_request_reply( ble_error_t nRF5xSecurityManager::legacy_pairing_oob_request_reply(
connection_handle_t connection, connection_handle_t connection,
const oob_tk_t& oob_data const oob_tk_t& oob_data
@ -546,11 +602,17 @@ ble_error_t nRF5xSecurityManager::legacy_pairing_oob_request_reply(
ble_error_t nRF5xSecurityManager::confirmation_entered( ble_error_t nRF5xSecurityManager::confirmation_entered(
connection_handle_t connection, bool confirmation connection_handle_t connection, bool confirmation
) { ) {
pairing_control_block_t* pairing_cb = get_pairing_cb(connection);
if (!pairing_cb) {
return BLE_ERROR_INVALID_STATE;
}
uint32_t err = sd_ble_gap_auth_key_reply( uint32_t err = sd_ble_gap_auth_key_reply(
connection, connection,
confirmation ? BLE_GAP_AUTH_KEY_TYPE_PASSKEY : BLE_GAP_AUTH_KEY_TYPE_NONE, confirmation ? BLE_GAP_AUTH_KEY_TYPE_PASSKEY : BLE_GAP_AUTH_KEY_TYPE_NONE,
NULL NULL
); );
return convert_sd_error(err); return convert_sd_error(err);
} }
@ -568,25 +630,26 @@ ble_error_t nRF5xSecurityManager::send_keypress_notification(
ble_error_t nRF5xSecurityManager::generate_secure_connections_oob( ble_error_t nRF5xSecurityManager::generate_secure_connections_oob(
connection_handle_t connection connection_handle_t connection
) { ) {
// FIXME: made with external library; requires SDK v13 ble_gap_lesc_p256_pk_t own_secret;
return BLE_ERROR_NOT_IMPLEMENTED; ble_gap_lesc_oob_data_t oob_data;
}
memcpy(own_secret.pk, secret.buffer(), secret.size());
ble_error_t nRF5xSecurityManager::secure_connections_oob_received( uint32_t err = sd_ble_gap_lesc_oob_data_get(
const address_t &address, connection,
const oob_lesc_value_t &random, &own_secret,
const oob_confirm_t &confirm &oob_data
) { );
// FIXME: store locally
return BLE_ERROR_NOT_IMPLEMENTED;
}
bool nRF5xSecurityManager::is_secure_connections_oob_present( if (!err) {
const address_t &address get_event_handler()->on_secure_connections_oob_generated(
) { connection,
// FIXME: lookup local store oob_data.r,
return false; oob_data.c
);
}
return convert_sd_error(err);
} }
nRF5xSecurityManager& nRF5xSecurityManager::get_security_manager() nRF5xSecurityManager& nRF5xSecurityManager::get_security_manager()
@ -653,18 +716,15 @@ bool nRF5xSecurityManager::sm_handler(const ble_evt_t *evt)
); );
} }
} else { } else {
AuthenticationMask authentication_requirements(
params.bond,
params.mitm,
params.lesc,
params.keypress
);
handler->on_pairing_request( handler->on_pairing_request(
connection, connection,
params.oob, params.oob,
authentication_requirements, AuthenticationMask(
params.bond,
params.mitm,
params.lesc,
params.keypress
),
initiator_dist, initiator_dist,
responder_dist responder_dist
); );
@ -695,7 +755,11 @@ bool nRF5xSecurityManager::sm_handler(const ble_evt_t *evt)
PasskeyAscii::to_num(req.passkey) PasskeyAscii::to_num(req.passkey)
); );
} else { } else {
// FIXME handle this case for secure pairing handler->on_passkey_display(
connection,
PasskeyAscii::to_num(req.passkey)
);
handler->on_confirmation_request(connection);
} }
return true; return true;
@ -708,6 +772,7 @@ bool nRF5xSecurityManager::sm_handler(const ble_evt_t *evt)
); );
return true; return true;
} }
case BLE_GAP_EVT_AUTH_KEY_REQUEST: { case BLE_GAP_EVT_AUTH_KEY_REQUEST: {
uint8_t key_type = gap_evt.params.auth_key_request.key_type; uint8_t key_type = gap_evt.params.auth_key_request.key_type;
@ -727,9 +792,32 @@ bool nRF5xSecurityManager::sm_handler(const ble_evt_t *evt)
return true; return true;
} }
case BLE_GAP_EVT_LESC_DHKEY_REQUEST: case BLE_GAP_EVT_LESC_DHKEY_REQUEST: {
// FIXME: Add with LESC support const ble_gap_evt_lesc_dhkey_request_t& dhkey_request =
gap_evt.params.lesc_dhkey_request;
size_t key_size = public_key_coord_t::size();
public_key_coord_t peer_X(dhkey_request.p_pk_peer->pk, key_size);
public_key_coord_t peer_Y(dhkey_request.p_pk_peer->pk + key_size, key_size);
public_key_coord_t sh_secret;
ble_gap_lesc_dhkey_t shared_secret;
_crypto.generate_shared_secret(
peer_X,
peer_Y,
self.secret,
sh_secret
);
memcpy(shared_secret.key, sh_secret.data(), sh_secret.size());
sd_ble_gap_lesc_dhkey_reply(connection, &shared_secret);
if (dhkey_request.oobd_req) {
handler->on_secure_connections_oob_request(connection);
}
return true; return true;
}
case BLE_GAP_EVT_AUTH_STATUS: { case BLE_GAP_EVT_AUTH_STATUS: {
const ble_gap_evt_auth_status_t& status = gap_evt.params.auth_status; const ble_gap_evt_auth_status_t& status = gap_evt.params.auth_status;
@ -954,13 +1042,13 @@ ble_gap_sec_keyset_t nRF5xSecurityManager::make_keyset(
own_dist->get_encryption() ? &pairing_cb.own_enc_key : NULL, own_dist->get_encryption() ? &pairing_cb.own_enc_key : NULL,
own_dist->get_identity() ? &pairing_cb.own_id_key : NULL, own_dist->get_identity() ? &pairing_cb.own_id_key : NULL,
own_dist->get_signing() ? &pairing_cb.own_sign_key : NULL, own_dist->get_signing() ? &pairing_cb.own_sign_key : NULL,
own_dist->get_link() ? &pairing_cb.own_pk : NULL &pairing_cb.own_pk
}, },
/* keys_peer */ { /* keys_peer */ {
peer_dist->get_encryption() ? &pairing_cb.peer_enc_key : NULL, peer_dist->get_encryption() ? &pairing_cb.peer_enc_key : NULL,
peer_dist->get_identity() ? &pairing_cb.peer_id_key : NULL, peer_dist->get_identity() ? &pairing_cb.peer_id_key : NULL,
peer_dist->get_signing() ? &pairing_cb.peer_sign_key : NULL, peer_dist->get_signing() ? &pairing_cb.peer_sign_key : NULL,
peer_dist->get_link() ? &pairing_cb.peer_pk : NULL &pairing_cb.peer_pk
} }
}; };
@ -969,6 +1057,10 @@ ble_gap_sec_keyset_t nRF5xSecurityManager::make_keyset(
memcpy(keyset.keys_own.p_sign_key->csrk, _csrk.data(), _csrk.size()); memcpy(keyset.keys_own.p_sign_key->csrk, _csrk.data(), _csrk.size());
} }
// copy public keys used
memcpy(pairing_cb.own_pk.pk, X.data(), X.size());
memcpy(pairing_cb.own_pk.pk + X.size(), Y.data(), Y.size());
return keyset; return keyset;
} }
@ -1016,6 +1108,13 @@ nRF5xSecurityManager::get_pairing_cb(connection_handle_t connection)
return NULL; return NULL;
} }
void nRF5xSecurityManager::release_all_pairing_cb()
{
while(_control_blocks) {
release_pairing_cb(_control_blocks);
}
}
} // nordic } // nordic
} // vendor } // vendor
} // pal } // pal

View File

@ -20,6 +20,7 @@
#include "ble/BLETypes.h" #include "ble/BLETypes.h"
#include "ble/pal/PalSecurityManager.h" #include "ble/pal/PalSecurityManager.h"
#include "nrf_ble.h" #include "nrf_ble.h"
#include "nRF5xCrypto.h"
namespace ble { namespace ble {
namespace pal { namespace pal {
@ -264,6 +265,16 @@ public:
passkey_num_t passkey passkey_num_t passkey
); );
/**
* @see ::ble::pal::SecurityManager::secure_connections_oob_request_reply
*/
virtual ble_error_t secure_connections_oob_request_reply(
connection_handle_t connection,
const oob_lesc_value_t &local_random,
const oob_lesc_value_t &peer_random,
const oob_confirm_t &peer_confirm
);
/** /**
* @see ::ble::pal::SecurityManager::legacy_pairing_oob_request_reply * @see ::ble::pal::SecurityManager::legacy_pairing_oob_request_reply
*/ */
@ -293,22 +304,6 @@ public:
connection_handle_t connection connection_handle_t connection
); );
/**
* @see ::ble::pal::SecurityManager::secure_connections_oob_received
*/
virtual ble_error_t secure_connections_oob_received(
const address_t &address,
const oob_lesc_value_t &random,
const oob_confirm_t &confirm
);
/**
* @see ::ble::pal::SecurityManager::is_secure_connections_oob_present
*/
virtual bool is_secure_connections_oob_present(
const address_t &address
);
// singleton of nordic Security Manager // singleton of nordic Security Manager
static nRF5xSecurityManager& get_security_manager(); static nRF5xSecurityManager& get_security_manager();
@ -339,8 +334,13 @@ private:
pairing_control_block_t* allocate_pairing_cb(connection_handle_t connection); pairing_control_block_t* allocate_pairing_cb(connection_handle_t connection);
void release_pairing_cb(pairing_control_block_t* pairing_cb); void release_pairing_cb(pairing_control_block_t* pairing_cb);
pairing_control_block_t* get_pairing_cb(connection_handle_t connection); pairing_control_block_t* get_pairing_cb(connection_handle_t connection);
void release_all_pairing_cb();
pairing_control_block_t* _control_blocks; pairing_control_block_t* _control_blocks;
LescCrypto _crypto;
ble::public_key_coord_t X;
ble::public_key_coord_t Y;
ble::public_key_coord_t secret;
}; };
} // nordic } // nordic