Part of a series on UDS – if you missed it, check out the introduction to the protocol.
What is it?
Many UDS services, which when executed, could create an unsafe state in the vehicle or reveal sensitive information about the ECU or vehicle. We automotive engineers thus want to ensure that only qualified, authorized personnel run some of these services. For example, perhaps we don’t want just anyone to flash software on our ECU, or write in a new serial number. It is these concerns that motivate the use of UDS service 0x27 – security access.
UDS service 0x27 is a means to prove the identity of the UDS tester so that the ECU knows that UDS requests coming from it are from an authorized client. Using this service, the ECU can require certain services, sub-services, or even certain parameters of a service to be used only in conjunction with security access. This makes sure that those select UDS functions can only be executed by an authorized person.
How’s it work?
All security comes down to proving your identity. You can do this by something you have, something you know, or something you are. Something you have would be like a physical token (like your house key). Something you know could be a password or an algorithm. And something you are would be like your fingerprints or iris scan. It should be pretty obvious that UDS security relies on something you know in order to prove your identity.
The “something you know” in this case is almost exclusively a secret algorithm, or better still, a well known algorithm with a secret key. It starts with the tester issuing a request for the server (the ECU) to generate a seed. The seed should be some agreed upon number of random bytes that is unpredictable (a nonce). The tester, using its knowledge of the secret algorithm or key will then take the seed and generate an unlock key. It then sends that back to the ECU, which, if correct, will grant the tester access to the ECU’s secure services.
UDS security also allows you to define levels of security access, denoted by the sub-function with which you use service 0x27. These levels are arbitrary, and can be used to silo different services behind different levels. An example would be for a given level you have one secret key that you share with a supplier. Then any UDS services or sub-services you gate behind that level can be used by that supplier. But other services and sub-services that use a different level won’t be available to that supplier. Let’s take a look at an example unlock sequence:
As always, lets analyze each step that occurred in the above sequence:
- The tester sends a request to unlock the ECU using UDS service 0x27, subservice 0x01. This indicates that the security level for which the tester is applying to unlock the ECU is level 1.
- The UDS server receives this request, and assuming conditions are correct, generates the random seed. It returns this seed as part of the positive response to service 0x27 0x01 (for a reminder on how the UDS protocol works, see UDS Protocol). In this case the random seed was 0D 42 8C 91.
- The UDS client, with its secret knowledge of the algorithm used to unlock the ECU, calculates an unlock key. In this case, the secret algorithm was simply flipping all the bits of the seed to get the key. Notice now the tester sends the secret key using service 0x27, subservice 0x02. The initial request’s subservice is always an odd number. The subsequent unlock key is sent using that number + 1. Then the unlock key is sent as a parameter.
- If the unlock key the UDS client has provided matches what the UDS server expects, it sends a positive response to the unlock service. Otherwise, it would send a negative response code here indicating the reason for failure.
If all went well, the ECU can assume that the UDS Client is now authorized up to security level 1. Any UDS features that are blocked by this security access can now be used, whereas they couldn’t be used before.
UDS security access is linked to UDS sessions. When a UDS session expires, so to does the security access that was obtained while in that session. This means if you come and unlock an ECU, then wait too long without sending any UDS commands, you’ll likely timeout and lose your security access.
Sidebar about Security Levels
The sub-function of UDS Security Service 0x27 is the “security level” that is being unlocked. As mentioned above, the concept of a security level is somewhat arbitrary. Level 9 doesn’t necessarily mean you are granted any more or any less privileges than level 3. It all depends on the system designer, and what services and sub-services they feel should be protected, and who gets to run those services.
For example, you may choose to designate security level 1 for all things related to writing manufacturing information into the ECU (i.e. serial number, date of manufacturing, VIN, etc.). You may then designate security level 3 for all things related to writing ECU runtime data (i.e. tire radius for a vehicle controller, or battery capacity for a battery management ECU). The choice is yours – the spec allows you to have 33 levels.
Last thing – a security level forms the relationship between the “request seed” sub-function and the “send key” sub-function. We generally refer to the level as the sub-function provided in the “request seed” portion of the sequence. For instance, if we want to unlock security level 9, our seed request looks like 0x27 0x09. The subsequent key send must then be 0x27 0x0A. That’s also why security levels are always odd numbers.
The purpose of this UDS service is to authenticate a tester, as unlocking the ECU’s security level gives the tester access to other UDS services that can be dangerous or reveal secret information. Therefore the implementation if this service should be done with security in mind. A few points to consider:
- One should use the NIST Guidelines for Authentication when implementing this service.
- The algorithm should be a well-known cryptographic based authentication mechanism, such as a CMAC or HMAC based on a secret key.
- The implementer should stay away from “security through obscurity” even though it appears tempting.
- Timing is important. The UDS server should implement strict timing for how long the tester has to calculate the unlock key. Exceeding this time should be followed by a negative response code.
- Failed security unlock attempts should force a time-delay between subsequent attempts. This makes brute-force attacks for guessing the unlock key more difficult. Time delays should be stored in some form of persistent memory, so that power cycling the ECU won’t reset the time.
- When generating the seed, make it as random as possible. Many modern microcontrollers come with cryptographic engines as peripherals – these should be used as often as possible when generating random numbers. If this isn’t available, there are software algorithms that can generate pseudo-random numbers, but they need a reliable source of entropy. Usually a free-running timer in conjunction with a few ADCs is sufficient. If an attacker captures your seed + key unlock sequence, and at a later time your ECU produces the same seed when requested, the attacker can simply present the old key and unlock your ECU.
UDS security access is a service that let’s ECUs know that they are talking to an authenticated UDS client. Without it, anyone could access all UDS services, potentially leading to danger or leaked information. The system designer chooses which UDS services can be used with and without security. There are multiple levels of security available as sub-functions of service 0x27, which can be used to group services and sub-services together into security domains.
Leave a Reply