This is the second post in a new series – Embedded Security!
In the last post, we saw that there a few basic features which when added to a system can help make that system resilient to attacks. In this post, we discuss one of them – Hardware Root of Trust.
What is Root Of Trust?
Let us understand “root of trust” in two parts – root and trust.
Literally, root means the the basic cause, source or origin of something. Similarly, trust means the firm belief in the reliability, truth, or ability of someone or something.
In the embedded security context, the root of trust is any quantity that serves as the origin of trust of that particular embedded system. As long as that embedded system can use and present that root of trust directly or indirectly to any other interested party. If during the process of authentication, the usage or presentation of this root of trust results in a success, it is a genuine embedded system.
More often than not, possession of the root of trust results in successful authentication unless an exceptional event occurs like blacklisting of that node.
Implementation of Root Of Trust
Let us consider that you are designing a simple system like an access system. The purpose of such a system is to authenticate people carrying that tag and allow them access into a facility. Being the thorough designer that you are, you want to make this system scalable such that it works today for 50 tags, 500 tags tomorrow, 5000 later on, etc. But since you are a smart designer, you realize that having a database of these tag identifiers is not the best way to do this. You want to make the system scalable without scaling the resources used.
What would you do? Let us check out a couple of approaches that guys I know would take.
The Shared Secret Guy
This guy likes to keep things simple.
He hard codes a global system secret (say 32 bytes) that will be present inside all the system components (the access system reader, the access system tags and all other entities if any).
An OK System
This is the simplest implementation.
Whenever someone wants to authenticate themselves, they present the tag to the reader. The reader tries to read the contents of the card. Once the content is read, the reader compares it with the secret that is hard-coded into it. If both of them match, the tag is authentic and the user is genuine.
A Better System
This is a better implementation.
Other than the hard-coded secret, the guy also comes up with a few unique identifiers that the reader programs into the tag upon the first usage of the card – unlike the hard-coded secret that gets programmed during the mass production of the tags. When someone wants to authenticate themselves, they present the tag to the reader. The reader tries to read the contents of the card. Once the content is read, the reader tries to find the global secret in the data it has read. If the global secret is present, it also tries to look for one of the unique identifiers. If it succeeds, the tag is authentic and the user is genuine.
An Even Better System
This is an even better implementation given the direction the guy has chosen.
Other than having a memory, the tag also has some limited computing capability. This capability allows it to perform a cryptographic function – say a strong hash function. When someone wants to authenticate themselves, they present the tag to the reader. The reader does not try to read anything. Rather, it sends a random challenge (say 32 random bytes) to the tag and waits for the tag to respond. Internally, the tag appends the hard-coded global secret with the challenge that was just sent to it and performs the hash function on this big chunk of data. The output of this hash function is sent back to the reader which does the same computation inside it. If both the outputs match, the tag is authentic and the user is genuine.
Why OK, Better and Even Better?
What makes the above approaches OK, better and even better? Let us analyze them a bit.
The matrix below ranks the above approaches on the basis of their resilience to cloning attack. For this purpose, it is assumed that cloning attack is an attack whose end result is that an exact replica of the memory area of the target is possible.
Irrespective of the score, in all the above systems, the root of trust is the global shared secret. Possession and presentation of the shared secret or a quantity derived from it is proof that the system is genuine.
The Root Certificate Guy
This guy has the larger picture in mind. He knows that this access system is not the only thing that he wants to build although this is the thing at hand right now.
He decides to do what the internet folks do. He purchases a certificate from a well-known certificate authority like GlobalSign, Digicert, etc. Using this, he generates a trusted certificate for this series of products. And using this trusted certificate, he is going to generate unique certificates for each of his genuine tags. This way, all his genuine tags have a unique identity that can be authenticated only by the genuine reader.
The below summarizes the approach.
Now in order to authenticate the tags, all that is needed is to prove that you possess the right certificates and are able to prove ownership of the private key. More on this implementation in a later post.
In this kind of an implementation, the root of trust is the guy’s certificate. Possession of this certificate along with the intermediate ones plays a huge role in establishing trust on the node.
Fine…but what is a Hardware Root of Trust?
Now that we know what a root of trust is, let us understand what a hardware root of trust is.
Since it is clear that the shared secret and the certificate+private key play a defining role in authenticating the tags and the readers in the above systems, it is easy to appreciate why it is extremely important to store the shared secret and the certificate+private key in a special enclave that protects data much better than a simple flash memory or an EEPROM or even flash internal to a microcontroller.
For instance, it is a bad idea to store the shared secret as a uint array inside your firmware. Similarly, storing your private key as a uint array inside your firmware would leave your system vulnerable to cloning attacks as possession of the certs and the key is sufficient to get authenticated.
The ideal solution to store your root of trust is a secure element or a trusted platform module (TPM).
These are ICs that have a lot of protections built in to prevent commonly known tamper attacks, microprobing attacks, timing attacks and lots more. Most of the times, these would also incorporate strong cryptography primitives and random number generators in order to sandbox the authentication part of the system. For example, I have been using the Microchip ATECC508A for some of my projects and it does the job perfectly – more on this in later post(s)!
A hardware root of trust is a key element of any secure embedded system. Depending on the type of implementation, a shared secret approach or a certificate-based approach may be used to serve as the root of trust. Secure elements and TPMs are commonly used to serve as the hardware root of trust.