UDS Security Access Testing (in HydraVision)#
Background#
Effective automotive diagnostics and ECU (Electronic Control Unit) security management necessitate a deep understanding of System States. Each System State influences the ECU’s behavior, communication protocols, and security measures. This chapter provides an overview of these System States and their implications for Security Access.
System States#
System States define the operational modes of an ECU and determine the available services and communication protocols. The key states are:
Default Session: This is the ECU’s standard operating mode with limited functionality. Authentication is typically required to transition from the Default Session to a higher privileged state.
Extended Diagnostic Session: This mode allows for advanced diagnostic operations and generally demands enhanced security measures.
Programming Session: Used for firmware updates and ECU reprogramming, this state involves stringent security protocols to prevent unauthorized modifications.
Proprietary Sessions: These are specialized modes defined by specific suppliers or OEMs. They may include unique functions or security requirements and can vary significantly between manufacturers. Proprietary sessions often include custom diagnostic or maintenance modes tailored to specific needs.
Security Access and System States#
Security Access mechanisms regulate the authentication necessary to use various ECU services, with requirements differing by System State:
Default Session: Requires basic authentication for standard operations.
Extended Diagnostic Session: Demands higher security levels for advanced diagnostic features.
Programming Session: Involves rigorous security controls to prevent unauthorized firmware changes or reprogramming.
Proprietary Sessions: May have distinct security requirements set by the supplier or OEM, often including additional measures not covered by standard sessions.
According to the UDS Standard, the Security Access level is denoted by a field in the protocol, with values ranging from 1 to 255. Odd values are used for seed requests, while even values are used to provide a key. While the Security Access Level is not uniformly associated with authentication levels across manufacturers, Security Access Levels 0x11 (17) and 0x12 (18) are frequently employed in the bootloader for firmware update authentication. The following figure illustrates the basic Security Access procedure:
Example#
The diagram below depicts a complex system state graph, highlighting that different sessions require different security access levels:
Typically, different development teams or companies are responsible for the firmware of the bootloader and the application software, leading to varied security levels between these components and even entirely different implementations. To effectively test an ECU’s Security Access, it is crucial to analyze every security access level across all System States. This comprehensive approach ensures thorough evaluation of the ECU’s security measures.
Penetration Testing#
Penetration testing is essential to validate the effectiveness of an ECU’s security access services. A common approach involves Seed-Key-based implementations, which may use either shared secrets or public-private key cryptography. In most cases, offline testers are utilized, necessitating the inclusion of key material within these testers. This scenario introduces a potential risk for key material leakage, especially if the OEM does not employ a secure backend service.
HydraVision#
In HydraVision, we focus on automating security tests to enhance efficiency. To support this, we have developed specialized helper objects for creating Security Access test cases. One such tool is the UdsSecurityAccessSystemStates object, which provides utilities to streamline and perform security tests effectively. Below is an example:
class UdsSecurityAccessTest(TestCase):
def test_case(self, uds_sa_system_states: UdsSecurityAccessSystemStates) -> None:
"""
Test case for scanning the UDS SecurityAccess service.
:param uds_sa_system_states: Object representing the system states relevant to UDS SecurityAccess.
:type uds_sa_system_states: UdsSecurityAccessSystemStates
:return: None
:rtype: None
.. tags::
- PowerSupply
- UDS
- StateScan
"""
self.logger.info("Start execution")
self.initialize_variables(uds_sa_system_states.uds_system_states)
# The UdsSecurityAccessSystemStates object holds all necessary interface objects to our Device under Test
# The full system state graph of our ECU, as shown in the previous figure
self.uds_system_states = uds_sa_system_states
# A PowerSupply object to control our ECUs power supply
self.ps = self.uds_system_states._power_supply
# A UDS Socket to communicate with our ECU. We don't care if we are talking over DoIP or ISOTP
self.uds_socket = self.uds_system_states._uds_socket
# A dictionary of all states and available security access levels
self.states_and_levels = uds_sa_system_states.security_access_states_and_levels
# The biggest advantage of the SystemStateGraph is, that it knows all the transition functions to enter a specific state of the ECU.
# Suppose we want to enter ProgrammingSession with Security Access Level 17, we just need to call the following function:
self.uds_system_states.enter_state(EcuState(session=2, security_level=17))
The greatest advantage of this system state object is its ability to understand the ECU-specific transition functions required to enter a defined state from any previous UDS SystemState scan. This means we can directly work with known states and programmatically test each of these states and their associated security levels for proper implementation. This streamlined approach ensures thorough and efficient testing of the ECU’s security mechanisms.
For more information about security test automation with HydraVision, please contact us.
General Test Cases#
This section outlines some fundamental tests that should always be conducted on security access implementations. However, we recommend complementing these with semi-automated testing and custom test cases tailored to the specific target ECU.
Penalty Time Check#
As an initial step, this test assesses whether the ECU is in a penalty time mode. During this mode, the ECU should not respond with a Seed but rather return a Negative Response Code indicating “RequiredTimeDelayNotExpired.”
To verify this, the test sends a seed request packet to the ECU and evaluates the response. If the ECU does not respond or indicates that the required time delay has not expired, the test retries. Failure to establish communication with the ECU after several attempts results in a failed test.
Immediate Key Try#
This test examines the ECU’s response when a security key is sent immediately, bypassing the seed request. The test iterates through various key sizes and assesses the ECU’s handling of different scenarios, including incorrect message lengths, request sequence errors, invalid keys, and exceeding allowed attempts. If communication issues arise with the ECU, an error is logged.
Invalid Key Try#
The Invalid Key Try test evaluates how the ECU’s Security Access service manages invalid keys and penalty time modes. It checks the ECU’s responses to invalid keys and ensures that the ECU correctly enters penalty time mode after a few failed attempts (e.g., 3) in accordance with protocol specifications. Unexpected behavior or deviations from protocol compliance are flagged.
Random Key Try#
Similar to the Invalid Key Try test, this case involves sending random data instead of predefined keys. This adds an element of unpredictability to the testing process and can reveal additional insights into the ECU’s handling of unexpected input.
Seed Analysis#
This test collects seeds from the ECU and assesses their uniqueness, length, and entropy. It identifies any anomalies or potential issues with the seed generation process. By analyzing various conditions, this test ensures the ECU’s seed handling mechanism functions correctly and raises warnings if any irregularities are detected.
Request Seed without Key Try#
This test evaluates whether penalty time is enforced when only seed requests are made without providing the corresponding key packets. A common issue in ECUs is that they respond to each new seed request, and penalty time is never triggered if no key is provided. This flaw allows an attacker to repeatedly query the ECU until a favorable seed is obtained. (credit: Stephan DB)
Key Try after first Seed request#
This test evaluates whether penalty time is enforced when a tester requests a seed once and then sends incrementing key packets. Vulnerable implementations will allow infinite key packets, enabling multiple attempts until the correct key is found. (credit: Stephan DB)
Conclusion#
Effective security testing is crucial for ensuring compliance with standards such as ISO 21434 and UNECE R155, which mandate robust measures to protect automotive systems against cyber threats. By implementing a comprehensive suite of test cases—ranging from penalty time checks to seed analysis—you can verify the integrity and resilience of your ECU’s security access mechanisms.
HydraVision enhances this process with advanced automation capabilities, streamlining security testing and making it more efficient. Through automated testing, HydraVision ensures thorough evaluation of ECU security, helping to identify vulnerabilities and maintain compliance with industry regulations.