Loading system/gd/cert/matchers.py +2 −2 Original line number Diff line number Diff line Loading @@ -652,8 +652,8 @@ class SecurityMatchers(object): return lambda event: True if event.message_type == type and (address == None or address == event.peer) else False @staticmethod def BondMsg(type, address=None): return lambda event: True if event.message_type == type and (address == None or address == event.peer) else False def BondMsg(type, address=None, reason=None): return lambda event: True if event.message_type == type and (address == None or address == event.peer) and (reason == None or reason == event.reason) else False @staticmethod def HelperMsg(type, address=None): Loading system/gd/hci/acl_manager/classic_impl.h +1 −1 Original line number Diff line number Diff line Loading @@ -499,7 +499,7 @@ struct classic_impl : public DisconnectorForLe, public security::ISecurityManage void OnDeviceBonded(bluetooth::hci::AddressWithType device) override {} void OnDeviceUnbonded(bluetooth::hci::AddressWithType device) override {} void OnDeviceBondFailed(bluetooth::hci::AddressWithType device) override {} void OnDeviceBondFailed(bluetooth::hci::AddressWithType device, security::PairingFailure status) override {} void OnEncryptionStateChanged(EncryptionChangeView encryption_change_view) override { if (!encryption_change_view.IsValid()) { Loading system/gd/security/cert/le_security_test.py +112 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ import time from bluetooth_packets_python3 import hci_packets from bluetooth_packets_python3 import security_packets from cert.event_stream import EventStream from cert.gd_base_test import GdBaseTestClass from cert.matchers import HciMatchers Loading Loading @@ -45,6 +46,7 @@ from security.facade_pb2 import LeMaximumEncryptionKeySizeMessage import time from bluetooth_packets_python3.hci_packets import OpCode from bluetooth_packets_python3.security_packets import PairingFailedReason LeIoCapabilities = LeIoCapabilityMessage.LeIoCapabilities LeOobDataFlag = LeOobDataPresentMessage.LeOobDataFlag Loading Loading @@ -474,7 +476,7 @@ class LeSecurityTest(GdBaseTestClass): @metadata( pts_test_id="SM/MAS/EKS/BV-01-C", pts_test_name="IUT initiator, Lower Tester Maximum Encryption Key Size = Min_Encryption_Key_Length") def test_min_encryption_key_size_equal_to_max(self): def test_min_encryption_key_size_equal_to_max_iut_initiator(self): """ Verify that the IUT uses correct key size during encryption as initiator. """ Loading Loading @@ -507,6 +509,115 @@ class LeSecurityTest(GdBaseTestClass): assertThat(self.dut_security.get_bond_stream()).emits( SecurityMatchers.BondMsg(BondMsgType.DEVICE_BONDED, self.cert_address)) @metadata( pts_test_id="SM/SLA/EKS/BV-02-C", pts_test_name="IUT Responder, Lower Tester Maximum Encryption Key Size = Min_Encryption_Key_Length") def test_min_encryption_key_size_equal_to_max_iut_responder(self): """ Verify that the IUT uses correct key size during encryption as responder. """ self._prepare_dut_for_connection() self.dut.security.SetLeIoCapability(KEYBOARD_ONLY) self.dut.security.SetLeOobDataPresent(OOB_NOT_PRESENT) self.dut_security.SetLeAuthRequirements() self.dut.security.SetLeMaximumEncryptionKeySize( LeMaximumEncryptionKeySizeMessage(maximum_encryption_key_size=0x07)) self.cert.security.SetLeIoCapability(NO_INPUT_NO_OUTPUT) self.cert.security.SetLeOobDataPresent(OOB_NOT_PRESENT) self.cert_security.SetLeAuthRequirements() self.cert.security.SetLeMaximumEncryptionKeySize( LeMaximumEncryptionKeySizeMessage(maximum_encryption_key_size=0x10)) # 1. Lower Tester initiates Pairing Request command with Maximum Encryption Key Size field set to Min_Encryption_Key_Length’. self.cert.security.CreateBondLe(self.dut_address) assertThat(self.dut_security.get_ui_stream()).emits( SecurityMatchers.UiMsg(UiMsgType.DISPLAY_PAIRING_PROMPT, self.cert_address)) # 2. IUT responds with Pairing Response command. self.dut.security.SendUiCallback( UiCallbackMsg( message_type=UiCallbackType.PAIRING_PROMPT, boolean=True, unique_id=1, address=self.cert_address)) #3. IUT and Lower Tester perform phase 2 of the LE pairing and establish an encrypted link with the key generated in phase 2. assertThat(self.dut_security.get_bond_stream()).emits( SecurityMatchers.BondMsg(BondMsgType.DEVICE_BONDED, self.cert_address)) @metadata( pts_test_id="SM/MAS/EKS/BI-01-C", pts_test_name="IUT initiator, Lower Tester Maximum Encryption Key Size < Min_Encryption_Key_Length") def test_min_encryption_key_size_less_than_min_iut_initiator(self): """ Verify that the IUT checks that the resultant encryption key size is not smaller than the minimum key size. """ self._prepare_cert_for_connection() self.dut.security.SetLeIoCapability(KEYBOARD_DISPLAY) self.dut.security.SetLeOobDataPresent(OOB_NOT_PRESENT) self.dut_security.SetLeAuthRequirements(secure_connections=1) self.dut.security.SetLeMaximumEncryptionKeySize( LeMaximumEncryptionKeySizeMessage(maximum_encryption_key_size=0x10)) self.cert.security.SetLeIoCapability(NO_INPUT_NO_OUTPUT) self.cert.security.SetLeOobDataPresent(OOB_NOT_PRESENT) self.cert_security.SetLeAuthRequirements(mitm=1, secure_connections=1) self.cert.security.SetLeMaximumEncryptionKeySize( LeMaximumEncryptionKeySizeMessage(maximum_encryption_key_size=0x06)) # 1. IUT transmits a Pairing Request self.dut.security.CreateBondLe(self.cert_address) assertThat(self.cert_security.get_ui_stream()).emits( SecurityMatchers.UiMsg(UiMsgType.DISPLAY_PAIRING_PROMPT, self.dut_address)) # 2. Lower Tester responds with Pairing Response command with Maximum Encryption Key Size field set to Min_Encryption_Key_Length-1’. self.cert.security.SendUiCallback( UiCallbackMsg( message_type=UiCallbackType.PAIRING_PROMPT, boolean=True, unique_id=1, address=self.dut_address)) # 3. IUT transmits the Pairing Failed command. assertThat(self.dut_security.get_bond_stream()).emits( SecurityMatchers.BondMsg(BondMsgType.DEVICE_BOND_FAILED, self.cert_address, int(PairingFailedReason.ENCRYPTION_KEY_SIZE))) @metadata( pts_test_id="SM/SLA/EKS/BI-02-C", pts_test_name="IUT Responder, Lower Tester Maximum Encryption Key Size < Min_Encryption_Key_Length") def test_min_encryption_key_size_less_than_min_iut_responder(self): """ Verify that the IUT uses correct key size during encryption as responder. """ self._prepare_dut_for_connection() self.dut.security.SetLeIoCapability(KEYBOARD_ONLY) self.dut.security.SetLeOobDataPresent(OOB_NOT_PRESENT) self.dut_security.SetLeAuthRequirements() self.dut.security.SetLeMaximumEncryptionKeySize( LeMaximumEncryptionKeySizeMessage(maximum_encryption_key_size=0x06)) self.cert.security.SetLeIoCapability(NO_INPUT_NO_OUTPUT) self.cert.security.SetLeOobDataPresent(OOB_NOT_PRESENT) self.cert_security.SetLeAuthRequirements() self.cert.security.SetLeMaximumEncryptionKeySize( LeMaximumEncryptionKeySizeMessage(maximum_encryption_key_size=0x10)) # 1. Lower Tester initiates Pairing Request command with Maximum Encryption Key Size field set to Min_Encryption_Key_Length-1. self.cert.security.CreateBondLe(self.dut_address) assertThat(self.dut_security.get_ui_stream()).emits( SecurityMatchers.UiMsg(UiMsgType.DISPLAY_PAIRING_PROMPT, self.cert_address)) self.dut.security.SendUiCallback( UiCallbackMsg( message_type=UiCallbackType.PAIRING_PROMPT, boolean=True, unique_id=1, address=self.cert_address)) #3. IUT transmits the Pairing Failed command. assertThat(self.cert_security.get_bond_stream()).emits( SecurityMatchers.BondMsg(BondMsgType.DEVICE_BOND_FAILED, self.dut_address, int(PairingFailedReason.ENCRYPTION_KEY_SIZE))) @metadata( pts_test_id="SM/MAS/SCPK/BV-01-C", pts_test_name="Passkey Entry, IUT Initiator, Secure Connections – Success") def test_passkey_entry_iut_initiator_secure_connections(self): Loading system/gd/security/facade.cc +2 −1 Original line number Diff line number Diff line Loading @@ -423,11 +423,12 @@ class SecurityModuleFacadeService : public SecurityModuleFacade::Service, public bond_events_.OnIncomingEvent(unbonded); } void OnDeviceBondFailed(hci::AddressWithType peer) override { void OnDeviceBondFailed(hci::AddressWithType peer, PairingFailure status) override { LOG_INFO("%s", peer.ToString().c_str()); BondMsg bond_failed; *bond_failed.mutable_peer() = ToFacadeAddressWithType(peer); bond_failed.set_message_type(BondMsgType::DEVICE_BOND_FAILED); bond_failed.set_reason(static_cast<uint8_t>(status.reason)); bond_events_.OnIncomingEvent(bond_failed); } Loading system/gd/security/facade.proto +1 −0 Original line number Diff line number Diff line Loading @@ -76,6 +76,7 @@ enum BondMsgType { message BondMsg { BondMsgType message_type = 1; facade.BluetoothAddressWithType peer = 2; uint32 reason = 3; } enum HelperMsgType { DEVICE_DISCONNECTED = 0; } Loading Loading
system/gd/cert/matchers.py +2 −2 Original line number Diff line number Diff line Loading @@ -652,8 +652,8 @@ class SecurityMatchers(object): return lambda event: True if event.message_type == type and (address == None or address == event.peer) else False @staticmethod def BondMsg(type, address=None): return lambda event: True if event.message_type == type and (address == None or address == event.peer) else False def BondMsg(type, address=None, reason=None): return lambda event: True if event.message_type == type and (address == None or address == event.peer) and (reason == None or reason == event.reason) else False @staticmethod def HelperMsg(type, address=None): Loading
system/gd/hci/acl_manager/classic_impl.h +1 −1 Original line number Diff line number Diff line Loading @@ -499,7 +499,7 @@ struct classic_impl : public DisconnectorForLe, public security::ISecurityManage void OnDeviceBonded(bluetooth::hci::AddressWithType device) override {} void OnDeviceUnbonded(bluetooth::hci::AddressWithType device) override {} void OnDeviceBondFailed(bluetooth::hci::AddressWithType device) override {} void OnDeviceBondFailed(bluetooth::hci::AddressWithType device, security::PairingFailure status) override {} void OnEncryptionStateChanged(EncryptionChangeView encryption_change_view) override { if (!encryption_change_view.IsValid()) { Loading
system/gd/security/cert/le_security_test.py +112 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ import time from bluetooth_packets_python3 import hci_packets from bluetooth_packets_python3 import security_packets from cert.event_stream import EventStream from cert.gd_base_test import GdBaseTestClass from cert.matchers import HciMatchers Loading Loading @@ -45,6 +46,7 @@ from security.facade_pb2 import LeMaximumEncryptionKeySizeMessage import time from bluetooth_packets_python3.hci_packets import OpCode from bluetooth_packets_python3.security_packets import PairingFailedReason LeIoCapabilities = LeIoCapabilityMessage.LeIoCapabilities LeOobDataFlag = LeOobDataPresentMessage.LeOobDataFlag Loading Loading @@ -474,7 +476,7 @@ class LeSecurityTest(GdBaseTestClass): @metadata( pts_test_id="SM/MAS/EKS/BV-01-C", pts_test_name="IUT initiator, Lower Tester Maximum Encryption Key Size = Min_Encryption_Key_Length") def test_min_encryption_key_size_equal_to_max(self): def test_min_encryption_key_size_equal_to_max_iut_initiator(self): """ Verify that the IUT uses correct key size during encryption as initiator. """ Loading Loading @@ -507,6 +509,115 @@ class LeSecurityTest(GdBaseTestClass): assertThat(self.dut_security.get_bond_stream()).emits( SecurityMatchers.BondMsg(BondMsgType.DEVICE_BONDED, self.cert_address)) @metadata( pts_test_id="SM/SLA/EKS/BV-02-C", pts_test_name="IUT Responder, Lower Tester Maximum Encryption Key Size = Min_Encryption_Key_Length") def test_min_encryption_key_size_equal_to_max_iut_responder(self): """ Verify that the IUT uses correct key size during encryption as responder. """ self._prepare_dut_for_connection() self.dut.security.SetLeIoCapability(KEYBOARD_ONLY) self.dut.security.SetLeOobDataPresent(OOB_NOT_PRESENT) self.dut_security.SetLeAuthRequirements() self.dut.security.SetLeMaximumEncryptionKeySize( LeMaximumEncryptionKeySizeMessage(maximum_encryption_key_size=0x07)) self.cert.security.SetLeIoCapability(NO_INPUT_NO_OUTPUT) self.cert.security.SetLeOobDataPresent(OOB_NOT_PRESENT) self.cert_security.SetLeAuthRequirements() self.cert.security.SetLeMaximumEncryptionKeySize( LeMaximumEncryptionKeySizeMessage(maximum_encryption_key_size=0x10)) # 1. Lower Tester initiates Pairing Request command with Maximum Encryption Key Size field set to Min_Encryption_Key_Length’. self.cert.security.CreateBondLe(self.dut_address) assertThat(self.dut_security.get_ui_stream()).emits( SecurityMatchers.UiMsg(UiMsgType.DISPLAY_PAIRING_PROMPT, self.cert_address)) # 2. IUT responds with Pairing Response command. self.dut.security.SendUiCallback( UiCallbackMsg( message_type=UiCallbackType.PAIRING_PROMPT, boolean=True, unique_id=1, address=self.cert_address)) #3. IUT and Lower Tester perform phase 2 of the LE pairing and establish an encrypted link with the key generated in phase 2. assertThat(self.dut_security.get_bond_stream()).emits( SecurityMatchers.BondMsg(BondMsgType.DEVICE_BONDED, self.cert_address)) @metadata( pts_test_id="SM/MAS/EKS/BI-01-C", pts_test_name="IUT initiator, Lower Tester Maximum Encryption Key Size < Min_Encryption_Key_Length") def test_min_encryption_key_size_less_than_min_iut_initiator(self): """ Verify that the IUT checks that the resultant encryption key size is not smaller than the minimum key size. """ self._prepare_cert_for_connection() self.dut.security.SetLeIoCapability(KEYBOARD_DISPLAY) self.dut.security.SetLeOobDataPresent(OOB_NOT_PRESENT) self.dut_security.SetLeAuthRequirements(secure_connections=1) self.dut.security.SetLeMaximumEncryptionKeySize( LeMaximumEncryptionKeySizeMessage(maximum_encryption_key_size=0x10)) self.cert.security.SetLeIoCapability(NO_INPUT_NO_OUTPUT) self.cert.security.SetLeOobDataPresent(OOB_NOT_PRESENT) self.cert_security.SetLeAuthRequirements(mitm=1, secure_connections=1) self.cert.security.SetLeMaximumEncryptionKeySize( LeMaximumEncryptionKeySizeMessage(maximum_encryption_key_size=0x06)) # 1. IUT transmits a Pairing Request self.dut.security.CreateBondLe(self.cert_address) assertThat(self.cert_security.get_ui_stream()).emits( SecurityMatchers.UiMsg(UiMsgType.DISPLAY_PAIRING_PROMPT, self.dut_address)) # 2. Lower Tester responds with Pairing Response command with Maximum Encryption Key Size field set to Min_Encryption_Key_Length-1’. self.cert.security.SendUiCallback( UiCallbackMsg( message_type=UiCallbackType.PAIRING_PROMPT, boolean=True, unique_id=1, address=self.dut_address)) # 3. IUT transmits the Pairing Failed command. assertThat(self.dut_security.get_bond_stream()).emits( SecurityMatchers.BondMsg(BondMsgType.DEVICE_BOND_FAILED, self.cert_address, int(PairingFailedReason.ENCRYPTION_KEY_SIZE))) @metadata( pts_test_id="SM/SLA/EKS/BI-02-C", pts_test_name="IUT Responder, Lower Tester Maximum Encryption Key Size < Min_Encryption_Key_Length") def test_min_encryption_key_size_less_than_min_iut_responder(self): """ Verify that the IUT uses correct key size during encryption as responder. """ self._prepare_dut_for_connection() self.dut.security.SetLeIoCapability(KEYBOARD_ONLY) self.dut.security.SetLeOobDataPresent(OOB_NOT_PRESENT) self.dut_security.SetLeAuthRequirements() self.dut.security.SetLeMaximumEncryptionKeySize( LeMaximumEncryptionKeySizeMessage(maximum_encryption_key_size=0x06)) self.cert.security.SetLeIoCapability(NO_INPUT_NO_OUTPUT) self.cert.security.SetLeOobDataPresent(OOB_NOT_PRESENT) self.cert_security.SetLeAuthRequirements() self.cert.security.SetLeMaximumEncryptionKeySize( LeMaximumEncryptionKeySizeMessage(maximum_encryption_key_size=0x10)) # 1. Lower Tester initiates Pairing Request command with Maximum Encryption Key Size field set to Min_Encryption_Key_Length-1. self.cert.security.CreateBondLe(self.dut_address) assertThat(self.dut_security.get_ui_stream()).emits( SecurityMatchers.UiMsg(UiMsgType.DISPLAY_PAIRING_PROMPT, self.cert_address)) self.dut.security.SendUiCallback( UiCallbackMsg( message_type=UiCallbackType.PAIRING_PROMPT, boolean=True, unique_id=1, address=self.cert_address)) #3. IUT transmits the Pairing Failed command. assertThat(self.cert_security.get_bond_stream()).emits( SecurityMatchers.BondMsg(BondMsgType.DEVICE_BOND_FAILED, self.dut_address, int(PairingFailedReason.ENCRYPTION_KEY_SIZE))) @metadata( pts_test_id="SM/MAS/SCPK/BV-01-C", pts_test_name="Passkey Entry, IUT Initiator, Secure Connections – Success") def test_passkey_entry_iut_initiator_secure_connections(self): Loading
system/gd/security/facade.cc +2 −1 Original line number Diff line number Diff line Loading @@ -423,11 +423,12 @@ class SecurityModuleFacadeService : public SecurityModuleFacade::Service, public bond_events_.OnIncomingEvent(unbonded); } void OnDeviceBondFailed(hci::AddressWithType peer) override { void OnDeviceBondFailed(hci::AddressWithType peer, PairingFailure status) override { LOG_INFO("%s", peer.ToString().c_str()); BondMsg bond_failed; *bond_failed.mutable_peer() = ToFacadeAddressWithType(peer); bond_failed.set_message_type(BondMsgType::DEVICE_BOND_FAILED); bond_failed.set_reason(static_cast<uint8_t>(status.reason)); bond_events_.OnIncomingEvent(bond_failed); } Loading
system/gd/security/facade.proto +1 −0 Original line number Diff line number Diff line Loading @@ -76,6 +76,7 @@ enum BondMsgType { message BondMsg { BondMsgType message_type = 1; facade.BluetoothAddressWithType peer = 2; uint32 reason = 3; } enum HelperMsgType { DEVICE_DISCONNECTED = 0; } Loading