Loading system/gd/security/pairing_handler_le.cc +27 −10 Original line number Diff line number Diff line Loading @@ -56,7 +56,8 @@ void PairingHandlerLe::PairingMain(InitialInformations i) { auto [pairing_request, pairing_response] = std::get<Phase1Result>(phase_1_result); /************************************************ PHASE 2 *********************************************************/ if (pairing_request.GetAuthReq() & pairing_response.GetAuthReq() & AuthReqMaskSc) { bool isSecureConnections = pairing_request.GetAuthReq() & pairing_response.GetAuthReq() & AuthReqMaskSc; if (isSecureConnections) { // 2.3.5.6 LE Secure Connections pairing phase 2 LOG_INFO("Pairing Phase 2 LE Secure connections Started"); Loading Loading @@ -97,6 +98,7 @@ void PairingHandlerLe::PairingMain(InitialInformations i) { Octet16 ltk = std::get<Octet16>(stage_2_result); if (IAmMaster(i)) { LOG_INFO("Sending start encryption request"); SendHciLeStartEncryption(i, i.connection_handle, {0}, {0}, ltk); } Loading Loading @@ -126,9 +128,9 @@ void PairingHandlerLe::PairingMain(InitialInformations i) { } /************************************************ PHASE 3 *********************************************************/ LOG_INFO("Waiting for encryption changed"); auto encryption_change_result = WaitEncryptionChanged(); if (std::holds_alternative<PairingFailure>(encryption_change_result)) { LOG_ERROR("encryption change failed"); i.OnPairingFinished(std::get<PairingFailure>(encryption_change_result)); return; } else if (std::holds_alternative<EncryptionChangeView>(encryption_change_result)) { Loading @@ -136,24 +138,29 @@ void PairingHandlerLe::PairingMain(InitialInformations i) { if (encryption_changed.GetStatus() != hci::ErrorCode::SUCCESS || encryption_changed.GetEncryptionEnabled() != hci::EncryptionEnabled::ON) { i.OnPairingFinished(PairingFailure("Encryption change failed")); return; } } else if (std::holds_alternative<EncryptionKeyRefreshCompleteView>(encryption_change_result)) { EncryptionKeyRefreshCompleteView encryption_changed = std::get<EncryptionKeyRefreshCompleteView>(encryption_change_result); if (encryption_changed.GetStatus() != hci::ErrorCode::SUCCESS) { i.OnPairingFinished(PairingFailure("Encryption key refresh failed")); return; } } else { i.OnPairingFinished(PairingFailure("Unknown case of encryption change result")); return; } LOG_INFO("Encryption change finished successfully"); DistributedKeysOrFailure keyExchangeStatus = DistributeKeys(i, pairing_response); DistributedKeysOrFailure keyExchangeStatus = DistributeKeys(i, pairing_response, isSecureConnections); if (std::holds_alternative<PairingFailure>(keyExchangeStatus)) { i.OnPairingFinished(std::get<PairingFailure>(keyExchangeStatus)); LOG_ERROR("Key exchange failed"); return; } LOG_INFO("Pairing finished successfully."); i.OnPairingFinished(PairingResult{ .connection_address = i.remote_connection_address, .distributed_keys = std::get<DistributedKeys>(keyExchangeStatus), Loading Loading @@ -259,16 +266,22 @@ Phase1ResultOrFailure PairingHandlerLe::ExchangePairingFeature(const InitialInfo } DistributedKeysOrFailure PairingHandlerLe::DistributeKeys(const InitialInformations& i, const PairingResponseView& pairing_response) { LOG_INFO("Key distribution start"); const uint8_t& keys_i_receive = const PairingResponseView& pairing_response, bool isSecureConnections) { uint8_t keys_i_receive = IAmMaster(i) ? pairing_response.GetResponderKeyDistribution() : pairing_response.GetInitiatorKeyDistribution(); const uint8_t& keys_i_send = uint8_t keys_i_send = IAmMaster(i) ? pairing_response.GetInitiatorKeyDistribution() : pairing_response.GetResponderKeyDistribution(); // TODO: obtain actual values! // In Secure Connections on the LE Transport, the EncKey field shall be ignored if (isSecureConnections) { keys_i_send = (~KeyMaskEnc) & keys_i_send; keys_i_receive = (~KeyMaskEnc) & keys_i_receive; } LOG_INFO("Key distribution start, keys_i_send=%02x, keys_i_receive=%02x", keys_i_send, keys_i_receive); // TODO: obtain actual values! Octet16 my_ltk = {0}; uint16_t my_ediv{0}; std::array<uint8_t, 8> my_rand = {0}; Loading Loading @@ -372,17 +385,21 @@ void PairingHandlerLe::SendKeys(const InitialInformations& i, const uint8_t& key std::array<uint8_t, 8> rand, Octet16 irk, Address identity_address, AddrType identity_addres_type, Octet16 signature_key) { if (keys_i_send & KeyMaskEnc) { LOG_INFO("Sending Encryption Information"); SendL2capPacket(i, EncryptionInformationBuilder::Create(ltk)); LOG_INFO("Sending Master Identification"); SendL2capPacket(i, MasterIdentificationBuilder::Create(ediv, rand)); } if (keys_i_send & KeyMaskId) { LOG_INFO("Sending Identity Information"); SendL2capPacket(i, IdentityInformationBuilder::Create(irk)); LOG_INFO("Sending Identity Address Information"); SendL2capPacket(i, IdentityAddressInformationBuilder::Create(identity_addres_type, identity_address)); } if (keys_i_send & KeyMaskSign) { LOG_INFO("Sending Signing Information"); SendL2capPacket(i, SigningInformationBuilder::Create(signature_key)); } } Loading system/gd/security/pairing_handler_le.h +12 −8 Original line number Diff line number Diff line Loading @@ -41,10 +41,10 @@ // Code generated by PDL does not allow us ot do || and && operations on bits // efficiently. Use those masks on fields requiring them until this is solved constexpr uint8_t AuthReqMaskBondingFlag = 0x01; constexpr uint8_t AuthReqMaskMitm = 0x02; constexpr uint8_t AuthReqMaskSc = 0x04; constexpr uint8_t AuthReqMaskKeypress = 0x08; constexpr uint8_t AuthReqMaskCt2 = 0x10; constexpr uint8_t AuthReqMaskMitm = 0x04; constexpr uint8_t AuthReqMaskSc = 0x08; constexpr uint8_t AuthReqMaskKeypress = 0x10; constexpr uint8_t AuthReqMaskCt2 = 0x20; constexpr uint8_t KeyMaskEnc = 0x01; constexpr uint8_t KeyMaskId = 0x02; Loading Loading @@ -139,8 +139,11 @@ class PairingHandlerLe { common::BindOnce([](hci::CommandStatusView) { // TODO: handle command status. It's important - can show we are not // connected any more. // TODO: if anything useful must be done there, use some sort of proper // handler, wait/notify, and execute on the handler thread }), nullptr); i.l2cap_handler); } std::variant<PairingFailure, EncryptionChangeView, EncryptionKeyRefreshCompleteView> WaitEncryptionChanged() { Loading @@ -160,7 +163,7 @@ class PairingHandlerLe { if (e.hci_event->GetEventCode() == hci::EventCode::ENCRYPTION_KEY_REFRESH_COMPLETE) { hci::EncryptionKeyRefreshCompleteView enc_packet = EncryptionKeyRefreshCompleteView::Create(*e.hci_event); if (!enc_packet.IsValid()) { return PairingFailure("Invalid EncryptionChange packet received"); return PairingFailure("Invalid Key Refresh packet received"); } return enc_packet; } Loading Loading @@ -210,7 +213,8 @@ class PairingHandlerLe { const Stage1Result stage1result, const std::array<uint8_t, 32>& dhkey); DistributedKeysOrFailure DistributeKeys(const InitialInformations& i, const PairingResponseView& pairing_response); DistributedKeysOrFailure DistributeKeys(const InitialInformations& i, const PairingResponseView& pairing_response, bool isSecureConnections); DistributedKeysOrFailure ReceiveKeys(const uint8_t& keys_i_receive); Loading Loading
system/gd/security/pairing_handler_le.cc +27 −10 Original line number Diff line number Diff line Loading @@ -56,7 +56,8 @@ void PairingHandlerLe::PairingMain(InitialInformations i) { auto [pairing_request, pairing_response] = std::get<Phase1Result>(phase_1_result); /************************************************ PHASE 2 *********************************************************/ if (pairing_request.GetAuthReq() & pairing_response.GetAuthReq() & AuthReqMaskSc) { bool isSecureConnections = pairing_request.GetAuthReq() & pairing_response.GetAuthReq() & AuthReqMaskSc; if (isSecureConnections) { // 2.3.5.6 LE Secure Connections pairing phase 2 LOG_INFO("Pairing Phase 2 LE Secure connections Started"); Loading Loading @@ -97,6 +98,7 @@ void PairingHandlerLe::PairingMain(InitialInformations i) { Octet16 ltk = std::get<Octet16>(stage_2_result); if (IAmMaster(i)) { LOG_INFO("Sending start encryption request"); SendHciLeStartEncryption(i, i.connection_handle, {0}, {0}, ltk); } Loading Loading @@ -126,9 +128,9 @@ void PairingHandlerLe::PairingMain(InitialInformations i) { } /************************************************ PHASE 3 *********************************************************/ LOG_INFO("Waiting for encryption changed"); auto encryption_change_result = WaitEncryptionChanged(); if (std::holds_alternative<PairingFailure>(encryption_change_result)) { LOG_ERROR("encryption change failed"); i.OnPairingFinished(std::get<PairingFailure>(encryption_change_result)); return; } else if (std::holds_alternative<EncryptionChangeView>(encryption_change_result)) { Loading @@ -136,24 +138,29 @@ void PairingHandlerLe::PairingMain(InitialInformations i) { if (encryption_changed.GetStatus() != hci::ErrorCode::SUCCESS || encryption_changed.GetEncryptionEnabled() != hci::EncryptionEnabled::ON) { i.OnPairingFinished(PairingFailure("Encryption change failed")); return; } } else if (std::holds_alternative<EncryptionKeyRefreshCompleteView>(encryption_change_result)) { EncryptionKeyRefreshCompleteView encryption_changed = std::get<EncryptionKeyRefreshCompleteView>(encryption_change_result); if (encryption_changed.GetStatus() != hci::ErrorCode::SUCCESS) { i.OnPairingFinished(PairingFailure("Encryption key refresh failed")); return; } } else { i.OnPairingFinished(PairingFailure("Unknown case of encryption change result")); return; } LOG_INFO("Encryption change finished successfully"); DistributedKeysOrFailure keyExchangeStatus = DistributeKeys(i, pairing_response); DistributedKeysOrFailure keyExchangeStatus = DistributeKeys(i, pairing_response, isSecureConnections); if (std::holds_alternative<PairingFailure>(keyExchangeStatus)) { i.OnPairingFinished(std::get<PairingFailure>(keyExchangeStatus)); LOG_ERROR("Key exchange failed"); return; } LOG_INFO("Pairing finished successfully."); i.OnPairingFinished(PairingResult{ .connection_address = i.remote_connection_address, .distributed_keys = std::get<DistributedKeys>(keyExchangeStatus), Loading Loading @@ -259,16 +266,22 @@ Phase1ResultOrFailure PairingHandlerLe::ExchangePairingFeature(const InitialInfo } DistributedKeysOrFailure PairingHandlerLe::DistributeKeys(const InitialInformations& i, const PairingResponseView& pairing_response) { LOG_INFO("Key distribution start"); const uint8_t& keys_i_receive = const PairingResponseView& pairing_response, bool isSecureConnections) { uint8_t keys_i_receive = IAmMaster(i) ? pairing_response.GetResponderKeyDistribution() : pairing_response.GetInitiatorKeyDistribution(); const uint8_t& keys_i_send = uint8_t keys_i_send = IAmMaster(i) ? pairing_response.GetInitiatorKeyDistribution() : pairing_response.GetResponderKeyDistribution(); // TODO: obtain actual values! // In Secure Connections on the LE Transport, the EncKey field shall be ignored if (isSecureConnections) { keys_i_send = (~KeyMaskEnc) & keys_i_send; keys_i_receive = (~KeyMaskEnc) & keys_i_receive; } LOG_INFO("Key distribution start, keys_i_send=%02x, keys_i_receive=%02x", keys_i_send, keys_i_receive); // TODO: obtain actual values! Octet16 my_ltk = {0}; uint16_t my_ediv{0}; std::array<uint8_t, 8> my_rand = {0}; Loading Loading @@ -372,17 +385,21 @@ void PairingHandlerLe::SendKeys(const InitialInformations& i, const uint8_t& key std::array<uint8_t, 8> rand, Octet16 irk, Address identity_address, AddrType identity_addres_type, Octet16 signature_key) { if (keys_i_send & KeyMaskEnc) { LOG_INFO("Sending Encryption Information"); SendL2capPacket(i, EncryptionInformationBuilder::Create(ltk)); LOG_INFO("Sending Master Identification"); SendL2capPacket(i, MasterIdentificationBuilder::Create(ediv, rand)); } if (keys_i_send & KeyMaskId) { LOG_INFO("Sending Identity Information"); SendL2capPacket(i, IdentityInformationBuilder::Create(irk)); LOG_INFO("Sending Identity Address Information"); SendL2capPacket(i, IdentityAddressInformationBuilder::Create(identity_addres_type, identity_address)); } if (keys_i_send & KeyMaskSign) { LOG_INFO("Sending Signing Information"); SendL2capPacket(i, SigningInformationBuilder::Create(signature_key)); } } Loading
system/gd/security/pairing_handler_le.h +12 −8 Original line number Diff line number Diff line Loading @@ -41,10 +41,10 @@ // Code generated by PDL does not allow us ot do || and && operations on bits // efficiently. Use those masks on fields requiring them until this is solved constexpr uint8_t AuthReqMaskBondingFlag = 0x01; constexpr uint8_t AuthReqMaskMitm = 0x02; constexpr uint8_t AuthReqMaskSc = 0x04; constexpr uint8_t AuthReqMaskKeypress = 0x08; constexpr uint8_t AuthReqMaskCt2 = 0x10; constexpr uint8_t AuthReqMaskMitm = 0x04; constexpr uint8_t AuthReqMaskSc = 0x08; constexpr uint8_t AuthReqMaskKeypress = 0x10; constexpr uint8_t AuthReqMaskCt2 = 0x20; constexpr uint8_t KeyMaskEnc = 0x01; constexpr uint8_t KeyMaskId = 0x02; Loading Loading @@ -139,8 +139,11 @@ class PairingHandlerLe { common::BindOnce([](hci::CommandStatusView) { // TODO: handle command status. It's important - can show we are not // connected any more. // TODO: if anything useful must be done there, use some sort of proper // handler, wait/notify, and execute on the handler thread }), nullptr); i.l2cap_handler); } std::variant<PairingFailure, EncryptionChangeView, EncryptionKeyRefreshCompleteView> WaitEncryptionChanged() { Loading @@ -160,7 +163,7 @@ class PairingHandlerLe { if (e.hci_event->GetEventCode() == hci::EventCode::ENCRYPTION_KEY_REFRESH_COMPLETE) { hci::EncryptionKeyRefreshCompleteView enc_packet = EncryptionKeyRefreshCompleteView::Create(*e.hci_event); if (!enc_packet.IsValid()) { return PairingFailure("Invalid EncryptionChange packet received"); return PairingFailure("Invalid Key Refresh packet received"); } return enc_packet; } Loading Loading @@ -210,7 +213,8 @@ class PairingHandlerLe { const Stage1Result stage1result, const std::array<uint8_t, 32>& dhkey); DistributedKeysOrFailure DistributeKeys(const InitialInformations& i, const PairingResponseView& pairing_response); DistributedKeysOrFailure DistributeKeys(const InitialInformations& i, const PairingResponseView& pairing_response, bool isSecureConnections); DistributedKeysOrFailure ReceiveKeys(const uint8_t& keys_i_receive); Loading