key dist flags only in db now and not in control block of sec manager

pull/6932/head
paul-szczepanek-arm 2018-05-13 23:26:34 +01:00
parent ab117737fa
commit 23c6a69d66
2 changed files with 147 additions and 52 deletions

View File

@ -426,7 +426,7 @@ private:
); );
private: private:
struct ControlBlock_t : public SecurityDistributionFlags_t { struct ControlBlock_t {
ControlBlock_t(); ControlBlock_t();
pal::KeyDistribution get_initiator_key_distribution() { pal::KeyDistribution get_initiator_key_distribution() {

View File

@ -345,11 +345,16 @@ ble_error_t GenericSecurityManager::enableSigning(
return BLE_ERROR_INVALID_PARAM; return BLE_ERROR_INVALID_PARAM;
} }
SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry);
if (!flags) {
return BLE_ERROR_INVALID_PARAM;
}
cb->signing_override_default = true; cb->signing_override_default = true;
if (enabled && !cb->signing_requested && !_default_key_distribution.get_signing()) { if (enabled && !cb->signing_requested && !_default_key_distribution.get_signing()) {
cb->signing_requested = true; cb->signing_requested = true;
if (cb->csrk_stored) { if (flags->csrk_stored) {
/* used the stored ones when available */ /* used the stored ones when available */
_db->get_entry_peer_csrk( _db->get_entry_peer_csrk(
mbed::callback(this, &GenericSecurityManager::set_peer_csrk_cb), mbed::callback(this, &GenericSecurityManager::set_peer_csrk_cb),
@ -390,8 +395,13 @@ ble_error_t GenericSecurityManager::getLinkEncryption(
return BLE_ERROR_INVALID_PARAM; return BLE_ERROR_INVALID_PARAM;
} }
SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry);
if (!flags) {
return BLE_ERROR_INVALID_PARAM;
}
if (cb->encrypted) { if (cb->encrypted) {
if (cb->ltk_mitm_protected || cb->mitm_performed) { if (flags->ltk_mitm_protected || cb->mitm_performed) {
*encryption = link_encryption_t::ENCRYPTED_WITH_MITM; *encryption = link_encryption_t::ENCRYPTED_WITH_MITM;
} else { } else {
*encryption = link_encryption_t::ENCRYPTED; *encryption = link_encryption_t::ENCRYPTED;
@ -414,6 +424,11 @@ ble_error_t GenericSecurityManager::setLinkEncryption(
return BLE_ERROR_INVALID_PARAM; return BLE_ERROR_INVALID_PARAM;
} }
SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry);
if (!flags) {
return BLE_ERROR_INVALID_PARAM;
}
link_encryption_t current_encryption(link_encryption_t::NOT_ENCRYPTED); link_encryption_t current_encryption(link_encryption_t::NOT_ENCRYPTED);
getLinkEncryption(connection, &current_encryption); getLinkEncryption(connection, &current_encryption);
@ -439,7 +454,7 @@ ble_error_t GenericSecurityManager::setLinkEncryption(
} else if (encryption == link_encryption_t::ENCRYPTED_WITH_MITM) { } else if (encryption == link_encryption_t::ENCRYPTED_WITH_MITM) {
if (cb->ltk_mitm_protected && !cb->encrypted) { if (flags->ltk_mitm_protected && !cb->encrypted) {
cb->encryption_requested = true; cb->encryption_requested = true;
return enable_encryption(connection); return enable_encryption(connection);
} else { } else {
@ -461,12 +476,17 @@ ble_error_t GenericSecurityManager::getEncryptionKeySize(
uint8_t *size uint8_t *size
) { ) {
ControlBlock_t *cb = get_control_block(connection); ControlBlock_t *cb = get_control_block(connection);
if (cb) { if (!cb) {
*size = cb->encryption_key_size;
return BLE_ERROR_NONE;
} else {
return BLE_ERROR_INVALID_PARAM; return BLE_ERROR_INVALID_PARAM;
} }
SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry);
if (!flags) {
return BLE_ERROR_INVALID_PARAM;
}
*size = flags->encryption_key_size;
return BLE_ERROR_NONE;
} }
ble_error_t GenericSecurityManager::setEncryptionKeyRequirements( ble_error_t GenericSecurityManager::setEncryptionKeyRequirements(
@ -487,7 +507,12 @@ ble_error_t GenericSecurityManager::getSigningKey(connection_handle_t connection
return BLE_ERROR_INVALID_PARAM; return BLE_ERROR_INVALID_PARAM;
} }
if (cb->csrk_stored && (cb->csrk_mitm_protected || !authenticated)) { SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry);
if (!flags) {
return BLE_ERROR_INVALID_PARAM;
}
if (flags->csrk_stored && (flags->csrk_mitm_protected || !authenticated)) {
/* we have a key that is either authenticated or we don't care if it is /* we have a key that is either authenticated or we don't care if it is
* so retrieve it from the db now */ * so retrieve it from the db now */
_db->get_entry_peer_csrk( _db->get_entry_peer_csrk(
@ -527,7 +552,12 @@ ble_error_t GenericSecurityManager::requestAuthentication(connection_handle_t co
return BLE_ERROR_INVALID_PARAM; return BLE_ERROR_INVALID_PARAM;
} }
if (cb->ltk_mitm_protected) { SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry);
if (!flags) {
return BLE_ERROR_INVALID_PARAM;
}
if (flags->ltk_mitm_protected) {
if (cb->authenticated) { if (cb->authenticated) {
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} else { } else {
@ -639,10 +669,15 @@ ble_error_t GenericSecurityManager::legacyPairingOobReceived(
return BLE_ERROR_INVALID_PARAM; return BLE_ERROR_INVALID_PARAM;
} }
SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry);
if (!flags) {
return BLE_ERROR_INVALID_PARAM;
}
_oob_temporary_key = *tk; _oob_temporary_key = *tk;
_oob_temporary_key_creator_address = *address; _oob_temporary_key_creator_address = *address;
if (cb->peer_address == _oob_temporary_key_creator_address) { if (flags->peer_address == _oob_temporary_key_creator_address) {
cb->attempt_oob = true; cb->attempt_oob = true;
} }
@ -732,8 +767,14 @@ ble_error_t GenericSecurityManager::enable_encryption(connection_handle_t connec
if (!cb) { if (!cb) {
return BLE_ERROR_INVALID_PARAM; return BLE_ERROR_INVALID_PARAM;
} }
SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry);
if (!flags) {
return BLE_ERROR_INVALID_PARAM;
}
if (cb->is_master) { if (cb->is_master) {
if (cb->ltk_stored) { if (flags->ltk_stored) {
_db->get_entry_peer_keys( _db->get_entry_peer_keys(
mbed::callback(this, &GenericSecurityManager::enable_encryption_cb), mbed::callback(this, &GenericSecurityManager::enable_encryption_cb),
cb->db_entry cb->db_entry
@ -752,12 +793,20 @@ void GenericSecurityManager::enable_encryption_cb(
const SecurityEntryKeys_t* entryKeys const SecurityEntryKeys_t* entryKeys
) { ) {
ControlBlock_t *cb = get_control_block(db_entry); ControlBlock_t *cb = get_control_block(db_entry);
if (!cb) {
return;
}
if (cb && entryKeys) { SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry);
if (cb->secure_connections_paired) { if (!flags) {
_pal.enable_encryption(cb->connection, entryKeys->ltk, cb->ltk_mitm_protected); return;
}
if (entryKeys) {
if (flags->secure_connections_paired) {
_pal.enable_encryption(cb->connection, entryKeys->ltk, flags->ltk_mitm_protected);
} else { } else {
_pal.enable_encryption(cb->connection, entryKeys->ltk, entryKeys->rand, entryKeys->ediv, cb->ltk_mitm_protected); _pal.enable_encryption(cb->connection, entryKeys->ltk, entryKeys->rand, entryKeys->ediv, flags->ltk_mitm_protected);
} }
} }
} }
@ -767,13 +816,19 @@ void GenericSecurityManager::set_ltk_cb(
const SecurityEntryKeys_t* entryKeys const SecurityEntryKeys_t* entryKeys
) { ) {
ControlBlock_t *cb = get_control_block(db_entry); ControlBlock_t *cb = get_control_block(db_entry);
if (!cb) {
return;
}
if (cb) { SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry);
if (entryKeys) { if (!flags) {
_pal.set_ltk(cb->connection, entryKeys->ltk, cb->ltk_mitm_protected, cb->secure_connections_paired); return;
} else { }
_pal.set_ltk_not_found(cb->connection);
} if (entryKeys) {
_pal.set_ltk(cb->connection, entryKeys->ltk, flags->ltk_mitm_protected, flags->secure_connections_paired);
} else {
_pal.set_ltk_not_found(cb->connection);
} }
} }
@ -786,10 +841,15 @@ void GenericSecurityManager::set_peer_csrk_cb(
return; return;
} }
SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry);
if (!flags) {
return;
}
_pal.set_peer_csrk( _pal.set_peer_csrk(
cb->connection, cb->connection,
signing->csrk, signing->csrk,
cb->csrk_mitm_protected, flags->csrk_mitm_protected,
signing->counter signing->counter
); );
} }
@ -803,10 +863,15 @@ void GenericSecurityManager::return_csrk_cb(
return; return;
} }
SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry);
if (!flags) {
return;
}
eventHandler->signingKey( eventHandler->signingKey(
cb->connection, cb->connection,
&signing->csrk, &signing->csrk,
cb->csrk_mitm_protected flags->csrk_mitm_protected
); );
} }
@ -816,15 +881,20 @@ void GenericSecurityManager::update_oob_presence(connection_handle_t connection)
return; return;
} }
SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry);
if (!flags) {
return;
}
/* if we support secure connection we only care about secure connections oob data */ /* if we support secure connection we only care about secure connections oob data */
if (_default_authentication.get_secure_connections()) { if (_default_authentication.get_secure_connections()) {
cb->oob_present = (cb->peer_address == _oob_peer_address); cb->oob_present = (flags->peer_address == _oob_peer_address);
} else { } else {
/* otherwise for legacy pairing we first set the oob based on set preference */ /* otherwise for legacy pairing we first set the oob based on set preference */
cb->oob_present = cb->attempt_oob; cb->oob_present = cb->attempt_oob;
/* and also turn it on if we have oob data for legacy pairing */ /* and also turn it on if we have oob data for legacy pairing */
if (cb->peer_address == _oob_temporary_key_creator_address if (flags->peer_address == _oob_temporary_key_creator_address
|| cb->local_address == _oob_temporary_key_creator_address) { || cb->local_address == _oob_temporary_key_creator_address) {
cb->oob_present = true; cb->oob_present = true;
} }
@ -859,27 +929,22 @@ void GenericSecurityManager::on_connected(
} }
// setup the control block // setup the control block
cb->peer_address = peer_address;
cb->local_address = local_address; cb->local_address = local_address;
cb->peer_address_is_public =
(peer_address_type == BLEProtocol::AddressType::PUBLIC);
cb->is_master = (role == Gap::CENTRAL); cb->is_master = (role == Gap::CENTRAL);
// get the associated db handle and the distribution flags if any // get the associated db handle and the distribution flags if any
cb->db_entry = _db->open_entry(peer_address_type, peer_address); cb->db_entry = _db->open_entry(peer_address_type, peer_address);
const SecurityDistributionFlags_t* dist_flags = SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry);
_db->get_distribution_flags(cb->db_entry);
if (dist_flags) { flags->peer_address = peer_address;
*static_cast<SecurityDistributionFlags_t*>(cb) = *dist_flags; flags->peer_address_is_public = (peer_address_type == BLEProtocol::AddressType::PUBLIC);
}
const bool signing = cb->signing_override_default ? const bool signing = cb->signing_override_default ?
cb->signing_requested : cb->signing_requested :
_default_key_distribution.get_signing(); _default_key_distribution.get_signing();
if (signing && cb->csrk_stored) { if (signing && flags->csrk_stored) {
_db->get_entry_peer_csrk( _db->get_entry_peer_csrk(
mbed::callback(this, &GenericSecurityManager::set_peer_csrk_cb), mbed::callback(this, &GenericSecurityManager::set_peer_csrk_cb),
cb->db_entry cb->db_entry
@ -1011,8 +1076,6 @@ void GenericSecurityManager::on_pairing_completed(connection_handle_t connection
MBED_ASSERT(_db); MBED_ASSERT(_db);
ControlBlock_t *cb = get_control_block(connection); ControlBlock_t *cb = get_control_block(connection);
if (cb) { if (cb) {
// set the distribution flags in the db
_db->set_distribution_flags(cb->db_entry, *cb);
_db->get_entry_identity( _db->get_entry_identity(
mbed::callback(this, &GenericSecurityManager::on_security_entry_retrieved), mbed::callback(this, &GenericSecurityManager::on_security_entry_retrieved),
cb->db_entry cb->db_entry
@ -1084,14 +1147,19 @@ void GenericSecurityManager::on_slave_security_request(
return; return;
} }
SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry);
if (!flags) {
return;
}
bool pairing_required = false; bool pairing_required = false;
if (authentication.get_secure_connections() && !cb->secure_connections_paired if (authentication.get_secure_connections() && !flags->secure_connections_paired
&& _default_authentication.get_secure_connections()) { && _default_authentication.get_secure_connections()) {
pairing_required = true; pairing_required = true;
} }
if (authentication.get_mitm() && !cb->ltk_mitm_protected) { if (authentication.get_mitm() && !flags->ltk_mitm_protected) {
pairing_required = true; pairing_required = true;
cb->mitm_requested = true; cb->mitm_requested = true;
} }
@ -1193,7 +1261,12 @@ void GenericSecurityManager::on_secure_connections_oob_request(connection_handle
return; return;
} }
if (cb->peer_address == _oob_peer_address) { SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry);
if (!flags) {
return;
}
if (flags->peer_address == _oob_peer_address) {
_pal.secure_connections_oob_request_reply(connection, _oob_local_random, _oob_peer_random, _oob_peer_confirm); _pal.secure_connections_oob_request_reply(connection, _oob_local_random, _oob_peer_random, _oob_peer_confirm);
/* do not re-use peer OOB */ /* do not re-use peer OOB */
set_all_zeros(_oob_peer_address); set_all_zeros(_oob_peer_address);
@ -1208,14 +1281,19 @@ void GenericSecurityManager::on_legacy_pairing_oob_request(connection_handle_t c
return; return;
} }
if (cb->peer_address == _oob_temporary_key_creator_address SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry);
if (!flags) {
return;
}
if (flags->peer_address == _oob_temporary_key_creator_address
|| cb->local_address == _oob_temporary_key_creator_address) { || cb->local_address == _oob_temporary_key_creator_address) {
set_mitm_performed(connection); set_mitm_performed(connection);
_pal.legacy_pairing_oob_request_reply(connection, _oob_temporary_key); _pal.legacy_pairing_oob_request_reply(connection, _oob_temporary_key);
/* do not re-use peer OOB */ /* do not re-use peer OOB */
if (cb->peer_address == _oob_temporary_key_creator_address) { if (flags->peer_address == _oob_temporary_key_creator_address) {
set_all_zeros(_oob_temporary_key_creator_address); set_all_zeros(_oob_temporary_key_creator_address);
} }
@ -1249,8 +1327,13 @@ void GenericSecurityManager::on_secure_connections_ltk_generated(
return; return;
} }
cb->ltk_mitm_protected = cb->mitm_performed; SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry);
cb->secure_connections_paired = true; if (!flags) {
return;
}
flags->ltk_mitm_protected = cb->mitm_performed;
flags->secure_connections_paired = true;
_db->set_entry_peer_ltk(cb->db_entry, ltk); _db->set_entry_peer_ltk(cb->db_entry, ltk);
} }
@ -1264,7 +1347,13 @@ void GenericSecurityManager::on_keys_distributed_ltk(
if (!cb) { if (!cb) {
return; return;
} }
cb->ltk_mitm_protected = cb->mitm_performed;
SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry);
if (!flags) {
return;
}
flags->ltk_mitm_protected = cb->mitm_performed;
_db->set_entry_peer_ltk(cb->db_entry, ltk); _db->set_entry_peer_ltk(cb->db_entry, ltk);
} }
@ -1350,14 +1439,19 @@ void GenericSecurityManager::on_keys_distributed_csrk(
return; return;
} }
cb->csrk_mitm_protected = cb->mitm_performed; SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry);
if (!flags) {
return;
}
flags->csrk_mitm_protected = cb->mitm_performed;
_db->set_entry_peer_csrk(cb->db_entry, csrk); _db->set_entry_peer_csrk(cb->db_entry, csrk);
eventHandler->signingKey( eventHandler->signingKey(
connection, connection,
&csrk, &csrk,
cb->csrk_mitm_protected flags->csrk_mitm_protected
); );
} }
@ -1383,7 +1477,6 @@ void GenericSecurityManager::on_ltk_request(
/* control blocks list management */ /* control blocks list management */
GenericSecurityManager::ControlBlock_t::ControlBlock_t() : GenericSecurityManager::ControlBlock_t::ControlBlock_t() :
SecurityDistributionFlags_t(),
connection(0), connection(0),
db_entry(0), db_entry(0),
local_address(), local_address(),
@ -1450,10 +1543,12 @@ GenericSecurityManager::ControlBlock_t* GenericSecurityManager::get_control_bloc
const address_t &peer_address const address_t &peer_address
) { ) {
for (size_t i = 0; i < MAX_CONTROL_BLOCKS; i++) { for (size_t i = 0; i < MAX_CONTROL_BLOCKS; i++) {
if (!_control_blocks[i].connected) { ControlBlock_t *cb = &_control_blocks[i];
continue; if (cb->connected) {
} else if (peer_address == _control_blocks[i].peer_address) { SecurityDistributionFlags_t* flags = _db->get_distribution_flags(cb->db_entry);
return &_control_blocks[i]; if (flags && (flags->peer_address == peer_address)) {
return cb;
}
} }
} }
return NULL; return NULL;