Loading system/gd/security/initial_informations.h +12 −9 Original line number Original line Diff line number Diff line Loading @@ -39,15 +39,18 @@ namespace security { struct DistributedKeys { struct DistributedKeys { /* LE Keys*/ /* LE Keys*/ std::optional<crypto_toolbox::Octet16> ltk; std::optional<crypto_toolbox::Octet16> remote_ltk; std::optional<uint16_t> ediv; std::optional<uint16_t> remote_ediv; std::optional<std::array<uint8_t, 8>> rand; std::optional<std::array<uint8_t, 8>> remote_rand; std::optional<hci::AddressWithType> identity_address; std::optional<hci::AddressWithType> remote_identity_address; std::optional<crypto_toolbox::Octet16> irk; std::optional<crypto_toolbox::Octet16> remote_irk; std::optional<crypto_toolbox::Octet16> signature_key; std::optional<crypto_toolbox::Octet16> remote_signature_key; std::optional<crypto_toolbox::Octet16> remote_link_key; /* BR/EDR Keys */ /* BR/EDR Keys */ std::optional<crypto_toolbox::Octet16> link_key; std::optional<crypto_toolbox::Octet16> local_ltk; std::optional<uint16_t> local_ediv; std::optional<std::array<uint8_t, 8>> local_rand; std::optional<crypto_toolbox::Octet16> local_signature_key; }; }; /* This class represents the result of pairing, as returned from Pairing Handler */ /* This class represents the result of pairing, as returned from Pairing Handler */ Loading system/gd/security/internal/security_manager_impl.cc +10 −9 Original line number Original line Diff line number Diff line Loading @@ -662,21 +662,22 @@ void SecurityManagerImpl::OnPairingFinished(security::PairingResultOrFailure pai // TODO: ensure that the security level is not weaker than what we already have. // TODO: ensure that the security level is not weaker than what we already have. auto record = this->security_database_.FindOrCreate(result.connection_address); auto record = this->security_database_.FindOrCreate(result.connection_address); record->identity_address_ = result.distributed_keys.identity_address; record->identity_address_ = result.distributed_keys.remote_identity_address; record->ltk = result.distributed_keys.ltk; record->remote_ltk = result.distributed_keys.remote_ltk; record->key_size = result.key_size; record->key_size = result.key_size; record->security_level = result.security_level; record->security_level = result.security_level; record->ediv = result.distributed_keys.ediv; record->remote_ediv = result.distributed_keys.remote_ediv; record->rand = result.distributed_keys.rand; record->remote_rand = result.distributed_keys.remote_rand; record->irk = result.distributed_keys.irk; record->remote_irk = result.distributed_keys.remote_irk; record->signature_key = result.distributed_keys.signature_key; record->remote_signature_key = result.distributed_keys.remote_signature_key; if (result.distributed_keys.link_key) if (result.distributed_keys.remote_link_key) record->SetLinkKey(*result.distributed_keys.link_key, hci::KeyType::AUTHENTICATED_P256); record->SetLinkKey(*result.distributed_keys.remote_link_key, hci::KeyType::AUTHENTICATED_P256); security_database_.SaveRecordsToStorage(); security_database_.SaveRecordsToStorage(); NotifyDeviceBonded(result.connection_address); NotifyDeviceBonded(result.connection_address); // We also notify bond complete using identity address. That's what old stack used to do. // We also notify bond complete using identity address. That's what old stack used to do. if (result.distributed_keys.identity_address) NotifyDeviceBonded(*result.distributed_keys.identity_address); if (result.distributed_keys.remote_identity_address) NotifyDeviceBonded(*result.distributed_keys.remote_identity_address); security_handler_->CallOn(this, &SecurityManagerImpl::WipeLePairingHandler); security_handler_->CallOn(this, &SecurityManagerImpl::WipeLePairingHandler); } } Loading system/gd/security/pairing_handler_le.cc +20 −12 Original line number Original line Diff line number Diff line Loading @@ -198,10 +198,10 @@ void PairingHandlerLe::PairingMain(InitialInformations i) { // If it's secure connections pairing, do cross-transport key derivation // If it's secure connections pairing, do cross-transport key derivation DistributedKeys distributed_keys = std::get<DistributedKeys>(keyExchangeStatus); DistributedKeys distributed_keys = std::get<DistributedKeys>(keyExchangeStatus); if ((pairing_response.GetAuthReq() & AuthReqMaskSc) && distributed_keys.ltk.has_value()) { if ((pairing_response.GetAuthReq() & AuthReqMaskSc) && distributed_keys.remote_ltk.has_value()) { bool use_h7 = (pairing_response.GetAuthReq() & AuthReqMaskCt2); bool use_h7 = (pairing_response.GetAuthReq() & AuthReqMaskCt2); Octet16 link_key = crypto_toolbox::ltk_to_link_key(*(distributed_keys.ltk), use_h7); Octet16 link_key = crypto_toolbox::ltk_to_link_key(*(distributed_keys.remote_ltk), use_h7); distributed_keys.link_key = link_key; distributed_keys.remote_link_key = link_key; } } // bool bonding = pairing_request.GetAuthReq() & pairing_response.GetAuthReq() & AuthReqMaskBondingFlag; // bool bonding = pairing_request.GetAuthReq() & pairing_response.GetAuthReq() & AuthReqMaskBondingFlag; Loading Loading @@ -336,9 +336,9 @@ DistributedKeysOrFailure PairingHandlerLe::DistributeKeys(const InitialInformati LOG_INFO("Key distribution start, keys_i_send=0x%02x, keys_i_receive=0x%02x", keys_i_send, keys_i_receive); LOG_INFO("Key distribution start, keys_i_send=0x%02x, keys_i_receive=0x%02x", keys_i_send, keys_i_receive); // TODO: obtain actual values, and apply key_size to the LTK // TODO: obtain actual values, and apply key_size to the LTK Octet16 my_ltk = {0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE}; Octet16 my_ltk = bluetooth::os::GenerateRandom<16>(); uint16_t my_ediv{0}; uint16_t my_ediv = bluetooth::os::GenerateRandom(); std::array<uint8_t, 8> my_rand = {0}; std::array<uint8_t, 8> my_rand = bluetooth::os::GenerateRandom<8>(); Octet16 my_irk = {0x01}; Octet16 my_irk = {0x01}; Address my_identity_address; Address my_identity_address; Loading @@ -354,6 +354,10 @@ DistributedKeysOrFailure PairingHandlerLe::DistributeKeys(const InitialInformati SendKeys(i, keys_i_send, my_ltk, my_ediv, my_rand, my_irk, my_identity_address, my_identity_address_type, SendKeys(i, keys_i_send, my_ltk, my_ediv, my_rand, my_irk, my_identity_address, my_identity_address_type, my_signature_key); my_signature_key); std::get<DistributedKeys>(keys).local_ltk = my_ltk; std::get<DistributedKeys>(keys).local_ediv = my_ediv; std::get<DistributedKeys>(keys).local_rand = my_rand; LOG_INFO("Key distribution finish"); LOG_INFO("Key distribution finish"); return keys; return keys; } else { } else { Loading @@ -364,6 +368,10 @@ DistributedKeysOrFailure PairingHandlerLe::DistributeKeys(const InitialInformati if (std::holds_alternative<PairingFailure>(keys)) { if (std::holds_alternative<PairingFailure>(keys)) { return keys; return keys; } } std::get<DistributedKeys>(keys).local_ltk = my_ltk; std::get<DistributedKeys>(keys).local_ediv = my_ediv; std::get<DistributedKeys>(keys).local_rand = my_rand; LOG_INFO("Key distribution finish"); LOG_INFO("Key distribution finish"); return keys; return keys; } } Loading Loading @@ -433,12 +441,12 @@ DistributedKeysOrFailure PairingHandlerLe::ReceiveKeys(const uint8_t& keys_i_rec signature_key = std::get<SigningInformationView>(packet).GetSignatureKey(); signature_key = std::get<SigningInformationView>(packet).GetSignatureKey(); } } return DistributedKeys{.ltk = ltk, return DistributedKeys{.remote_ltk = ltk, .ediv = ediv, .remote_ediv = ediv, .rand = rand, .remote_rand = rand, .identity_address = identity_address, .remote_identity_address = identity_address, .irk = irk, .remote_irk = irk, .signature_key = signature_key}; .remote_signature_key = signature_key}; } } void PairingHandlerLe::SendKeys(const InitialInformations& i, const uint8_t& keys_i_send, Octet16 ltk, uint16_t ediv, void PairingHandlerLe::SendKeys(const InitialInformations& i, const uint8_t& keys_i_send, Octet16 ltk, uint16_t ediv, Loading system/gd/security/record/security_record.h +9 −5 Original line number Original line Diff line number Diff line Loading @@ -126,13 +126,17 @@ class SecurityRecord { /* Identity Address */ /* Identity Address */ std::optional<hci::AddressWithType> identity_address_; std::optional<hci::AddressWithType> identity_address_; std::optional<crypto_toolbox::Octet16> ltk; std::optional<crypto_toolbox::Octet16> remote_ltk; uint8_t key_size; uint8_t key_size; uint8_t security_level; uint8_t security_level; std::optional<uint16_t> ediv; std::optional<uint16_t> remote_ediv; std::optional<std::array<uint8_t, 8>> rand; std::optional<std::array<uint8_t, 8>> remote_rand; std::optional<crypto_toolbox::Octet16> irk; std::optional<crypto_toolbox::Octet16> remote_irk; std::optional<crypto_toolbox::Octet16> signature_key; std::optional<crypto_toolbox::Octet16> remote_signature_key; std::optional<crypto_toolbox::Octet16> local_ltk; std::optional<uint16_t> local_ediv; std::optional<std::array<uint8_t, 8>> local_rand; }; }; } // namespace record } // namespace record Loading system/gd/security/record/security_record_database.h +1 −1 Original line number Original line Diff line number Diff line Loading @@ -59,7 +59,7 @@ class SecurityRecordDatabase { std::shared_ptr<SecurityRecord> record = *it; std::shared_ptr<SecurityRecord> record = *it; if (record->identity_address_.has_value() && record->identity_address_.value() == address) return it; if (record->identity_address_.has_value() && record->identity_address_.value() == address) return it; if (record->GetPseudoAddress() == address) return it; if (record->GetPseudoAddress() == address) return it; if (record->irk.has_value() && address.IsRpaThatMatchesIrk(record->irk.value())) return it; if (record->remote_irk.has_value() && address.IsRpaThatMatchesIrk(record->remote_irk.value())) return it; } } return records_.end(); return records_.end(); } } Loading Loading
system/gd/security/initial_informations.h +12 −9 Original line number Original line Diff line number Diff line Loading @@ -39,15 +39,18 @@ namespace security { struct DistributedKeys { struct DistributedKeys { /* LE Keys*/ /* LE Keys*/ std::optional<crypto_toolbox::Octet16> ltk; std::optional<crypto_toolbox::Octet16> remote_ltk; std::optional<uint16_t> ediv; std::optional<uint16_t> remote_ediv; std::optional<std::array<uint8_t, 8>> rand; std::optional<std::array<uint8_t, 8>> remote_rand; std::optional<hci::AddressWithType> identity_address; std::optional<hci::AddressWithType> remote_identity_address; std::optional<crypto_toolbox::Octet16> irk; std::optional<crypto_toolbox::Octet16> remote_irk; std::optional<crypto_toolbox::Octet16> signature_key; std::optional<crypto_toolbox::Octet16> remote_signature_key; std::optional<crypto_toolbox::Octet16> remote_link_key; /* BR/EDR Keys */ /* BR/EDR Keys */ std::optional<crypto_toolbox::Octet16> link_key; std::optional<crypto_toolbox::Octet16> local_ltk; std::optional<uint16_t> local_ediv; std::optional<std::array<uint8_t, 8>> local_rand; std::optional<crypto_toolbox::Octet16> local_signature_key; }; }; /* This class represents the result of pairing, as returned from Pairing Handler */ /* This class represents the result of pairing, as returned from Pairing Handler */ Loading
system/gd/security/internal/security_manager_impl.cc +10 −9 Original line number Original line Diff line number Diff line Loading @@ -662,21 +662,22 @@ void SecurityManagerImpl::OnPairingFinished(security::PairingResultOrFailure pai // TODO: ensure that the security level is not weaker than what we already have. // TODO: ensure that the security level is not weaker than what we already have. auto record = this->security_database_.FindOrCreate(result.connection_address); auto record = this->security_database_.FindOrCreate(result.connection_address); record->identity_address_ = result.distributed_keys.identity_address; record->identity_address_ = result.distributed_keys.remote_identity_address; record->ltk = result.distributed_keys.ltk; record->remote_ltk = result.distributed_keys.remote_ltk; record->key_size = result.key_size; record->key_size = result.key_size; record->security_level = result.security_level; record->security_level = result.security_level; record->ediv = result.distributed_keys.ediv; record->remote_ediv = result.distributed_keys.remote_ediv; record->rand = result.distributed_keys.rand; record->remote_rand = result.distributed_keys.remote_rand; record->irk = result.distributed_keys.irk; record->remote_irk = result.distributed_keys.remote_irk; record->signature_key = result.distributed_keys.signature_key; record->remote_signature_key = result.distributed_keys.remote_signature_key; if (result.distributed_keys.link_key) if (result.distributed_keys.remote_link_key) record->SetLinkKey(*result.distributed_keys.link_key, hci::KeyType::AUTHENTICATED_P256); record->SetLinkKey(*result.distributed_keys.remote_link_key, hci::KeyType::AUTHENTICATED_P256); security_database_.SaveRecordsToStorage(); security_database_.SaveRecordsToStorage(); NotifyDeviceBonded(result.connection_address); NotifyDeviceBonded(result.connection_address); // We also notify bond complete using identity address. That's what old stack used to do. // We also notify bond complete using identity address. That's what old stack used to do. if (result.distributed_keys.identity_address) NotifyDeviceBonded(*result.distributed_keys.identity_address); if (result.distributed_keys.remote_identity_address) NotifyDeviceBonded(*result.distributed_keys.remote_identity_address); security_handler_->CallOn(this, &SecurityManagerImpl::WipeLePairingHandler); security_handler_->CallOn(this, &SecurityManagerImpl::WipeLePairingHandler); } } Loading
system/gd/security/pairing_handler_le.cc +20 −12 Original line number Original line Diff line number Diff line Loading @@ -198,10 +198,10 @@ void PairingHandlerLe::PairingMain(InitialInformations i) { // If it's secure connections pairing, do cross-transport key derivation // If it's secure connections pairing, do cross-transport key derivation DistributedKeys distributed_keys = std::get<DistributedKeys>(keyExchangeStatus); DistributedKeys distributed_keys = std::get<DistributedKeys>(keyExchangeStatus); if ((pairing_response.GetAuthReq() & AuthReqMaskSc) && distributed_keys.ltk.has_value()) { if ((pairing_response.GetAuthReq() & AuthReqMaskSc) && distributed_keys.remote_ltk.has_value()) { bool use_h7 = (pairing_response.GetAuthReq() & AuthReqMaskCt2); bool use_h7 = (pairing_response.GetAuthReq() & AuthReqMaskCt2); Octet16 link_key = crypto_toolbox::ltk_to_link_key(*(distributed_keys.ltk), use_h7); Octet16 link_key = crypto_toolbox::ltk_to_link_key(*(distributed_keys.remote_ltk), use_h7); distributed_keys.link_key = link_key; distributed_keys.remote_link_key = link_key; } } // bool bonding = pairing_request.GetAuthReq() & pairing_response.GetAuthReq() & AuthReqMaskBondingFlag; // bool bonding = pairing_request.GetAuthReq() & pairing_response.GetAuthReq() & AuthReqMaskBondingFlag; Loading Loading @@ -336,9 +336,9 @@ DistributedKeysOrFailure PairingHandlerLe::DistributeKeys(const InitialInformati LOG_INFO("Key distribution start, keys_i_send=0x%02x, keys_i_receive=0x%02x", keys_i_send, keys_i_receive); LOG_INFO("Key distribution start, keys_i_send=0x%02x, keys_i_receive=0x%02x", keys_i_send, keys_i_receive); // TODO: obtain actual values, and apply key_size to the LTK // TODO: obtain actual values, and apply key_size to the LTK Octet16 my_ltk = {0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE}; Octet16 my_ltk = bluetooth::os::GenerateRandom<16>(); uint16_t my_ediv{0}; uint16_t my_ediv = bluetooth::os::GenerateRandom(); std::array<uint8_t, 8> my_rand = {0}; std::array<uint8_t, 8> my_rand = bluetooth::os::GenerateRandom<8>(); Octet16 my_irk = {0x01}; Octet16 my_irk = {0x01}; Address my_identity_address; Address my_identity_address; Loading @@ -354,6 +354,10 @@ DistributedKeysOrFailure PairingHandlerLe::DistributeKeys(const InitialInformati SendKeys(i, keys_i_send, my_ltk, my_ediv, my_rand, my_irk, my_identity_address, my_identity_address_type, SendKeys(i, keys_i_send, my_ltk, my_ediv, my_rand, my_irk, my_identity_address, my_identity_address_type, my_signature_key); my_signature_key); std::get<DistributedKeys>(keys).local_ltk = my_ltk; std::get<DistributedKeys>(keys).local_ediv = my_ediv; std::get<DistributedKeys>(keys).local_rand = my_rand; LOG_INFO("Key distribution finish"); LOG_INFO("Key distribution finish"); return keys; return keys; } else { } else { Loading @@ -364,6 +368,10 @@ DistributedKeysOrFailure PairingHandlerLe::DistributeKeys(const InitialInformati if (std::holds_alternative<PairingFailure>(keys)) { if (std::holds_alternative<PairingFailure>(keys)) { return keys; return keys; } } std::get<DistributedKeys>(keys).local_ltk = my_ltk; std::get<DistributedKeys>(keys).local_ediv = my_ediv; std::get<DistributedKeys>(keys).local_rand = my_rand; LOG_INFO("Key distribution finish"); LOG_INFO("Key distribution finish"); return keys; return keys; } } Loading Loading @@ -433,12 +441,12 @@ DistributedKeysOrFailure PairingHandlerLe::ReceiveKeys(const uint8_t& keys_i_rec signature_key = std::get<SigningInformationView>(packet).GetSignatureKey(); signature_key = std::get<SigningInformationView>(packet).GetSignatureKey(); } } return DistributedKeys{.ltk = ltk, return DistributedKeys{.remote_ltk = ltk, .ediv = ediv, .remote_ediv = ediv, .rand = rand, .remote_rand = rand, .identity_address = identity_address, .remote_identity_address = identity_address, .irk = irk, .remote_irk = irk, .signature_key = signature_key}; .remote_signature_key = signature_key}; } } void PairingHandlerLe::SendKeys(const InitialInformations& i, const uint8_t& keys_i_send, Octet16 ltk, uint16_t ediv, void PairingHandlerLe::SendKeys(const InitialInformations& i, const uint8_t& keys_i_send, Octet16 ltk, uint16_t ediv, Loading
system/gd/security/record/security_record.h +9 −5 Original line number Original line Diff line number Diff line Loading @@ -126,13 +126,17 @@ class SecurityRecord { /* Identity Address */ /* Identity Address */ std::optional<hci::AddressWithType> identity_address_; std::optional<hci::AddressWithType> identity_address_; std::optional<crypto_toolbox::Octet16> ltk; std::optional<crypto_toolbox::Octet16> remote_ltk; uint8_t key_size; uint8_t key_size; uint8_t security_level; uint8_t security_level; std::optional<uint16_t> ediv; std::optional<uint16_t> remote_ediv; std::optional<std::array<uint8_t, 8>> rand; std::optional<std::array<uint8_t, 8>> remote_rand; std::optional<crypto_toolbox::Octet16> irk; std::optional<crypto_toolbox::Octet16> remote_irk; std::optional<crypto_toolbox::Octet16> signature_key; std::optional<crypto_toolbox::Octet16> remote_signature_key; std::optional<crypto_toolbox::Octet16> local_ltk; std::optional<uint16_t> local_ediv; std::optional<std::array<uint8_t, 8>> local_rand; }; }; } // namespace record } // namespace record Loading
system/gd/security/record/security_record_database.h +1 −1 Original line number Original line Diff line number Diff line Loading @@ -59,7 +59,7 @@ class SecurityRecordDatabase { std::shared_ptr<SecurityRecord> record = *it; std::shared_ptr<SecurityRecord> record = *it; if (record->identity_address_.has_value() && record->identity_address_.value() == address) return it; if (record->identity_address_.has_value() && record->identity_address_.value() == address) return it; if (record->GetPseudoAddress() == address) return it; if (record->GetPseudoAddress() == address) return it; if (record->irk.has_value() && address.IsRpaThatMatchesIrk(record->irk.value())) return it; if (record->remote_irk.has_value() && address.IsRpaThatMatchesIrk(record->remote_irk.value())) return it; } } return records_.end(); return records_.end(); } } Loading