Secure storage is a broad term that can refer to any storage, networking, or security discipline, technology, or methodology for the purpose of protecting and securing digital assets.
This topic describes how to provide integrity and confidentiality guarantees on data stored in persistent memory.
The most common way to provide these guarantees is by using authenticated encryption algorithms to protect the data. But because these algorithms require an encryption key, this method still does not solve the problem of how to store the key in a protected way.
In cases where user interaction is guaranteed, you can use a user-provided key (such as a fingerprint, password, or pattern). In embedded platforms, the most common case is that there is no user to provide the key. This problem is typically solved with specific hardware that provides mechanisms to protect the key, such as cryptochips or Trusted Platform Modules (TPMs).
This topic describes a solution using the CAAM module on the i.MX8M Mini CPU.
This page describes the low-level secure storage mechanism provided by the CAAM hardware. However, most secure storage use cases can be solved by using an encrypted partition. For information on using an encrypted root file system see Set up your device with root file system encryption. |
CAAM blobs
The CAAM module provides a method to protect data in a cryptographic data structure called CAAM blob. The data to be protected is encrypted so that it can be safely placed into non-volatile storage. Each time you create a CAAM blob, the CAAM module generates a new random key to encrypt the data. The data is then encrypted using AES-CCM, resulting in a Message Authentication Code (MAC) and the encrypted data (ciphertext). This random key is itself encrypted using the OTPMK and then stored along with the encrypted data. The combination of encrypted key, the encrypted data, and the MAC constitute the CAAM blob.
Because an authenticated encryption algorithm (AES-CCM) is used, CAAM blobs provide both confidentiality and integrity protection for the encapsulated data.
When using CAAM blobs, having access to the device effectively acts as a key for accessing the encrypted information. For this reason, when using CAAM blobs the device should be secured so that it can only be used by authorized users. You can use TrustFence framework features such as Secure boot or Secure console modes to secure access to the device.
As a unique key is used in each device, data encrypted on one device cannot be copied and decrypted on a different device, ensuring the secrecy of the data. This also provides anti-counterfeit guarantee (i.e. if an attacker clones the contents of the flash to another device, the counterfeit device cannot run the software since it can not decrypt the CAAM blob).
You must close the device, to generate CAAM blobs protected by the unique key. Any CAAM blobs that you generate with an open device (not secure enabled) use the same public test key and can be decrypted by any other device. |
Key modifier
Many different blobs may exist at the same time, be used for different purposes, and be subject to different security policies. Key modifiers ensure that blobs are not inadvertently or maliciously swapped. They can also differentiate specific data or prevent replay attacks (the replacement of the current blob with a previous version of the blob).
To decrypt a CAAM blob you have to use the same key modifier that you used to create it. Otherwise, the decryption operation will fail.
The key modifier can be thought of as an optional parameter, and a zeroed key modifier can be used as default. Using different key modifiers is not required for the generated CAAM blob to be safe. |
CAAM blob encapsulation
When the CAAM encapsulates data into a CAAM blob, the following operations take place:
-
The CAAM True Random Number Generator generates a 256-bit key. This is called Blob Key (BK).
-
The input data (plaintext) is encrypted using AES-CCM with BK as the encryption key. This process produces two outputs:
-
the encrypted data (referred to as either BK-encrypted data or ciphertext).
-
a Message Authentication Code (MAC).
-
The CAAM uses constant values as nonce and initial counter for the AES-CCM operation. This is secure because any given BK (which is the AES-CCM key) is never used more than once. |
-
A new 256-bit key, the Blob Key Encryption Key (BKEK), is derived from the following inputs:
-
OTPMK (closed devices) or NVTK (open devices)
-
Key modifier
-
-
The BK is encrypted using AES-ECB with the BKEK as key. We refer to the output of this process as the BKEK-encrypted BK.
The CAAM blob is then formed by concatenating the following outputs:
-
BKEK-encrypted BK.
-
Ciphertext.
-
Message Authentication Code.
CAAM blob decapsulation
Decapsulating a CAAM blob uses the reverse process:
-
A 256-bit key BKEK is regenerated from the same inputs (OTPMK/NVTK, key modifier and blob type). Note that for this BKEK to be equal to the one used when the CAAM blob was created you must:
-
make sure the device is in the same security state (closed or open) that it was in when you created the blob.
-
if closed, use the same device (since the OTPMK is unique per device).
-
use the same key modifier.
-
-
The regenerated BKEK is used to AES-ECB decrypt the BKEK-encrypted BK present on the blob. This produces 256 bits of data, which will be used as BK.
-
This BK is used as key to perform AES-CCM decryption on the BK-encrypted data (ciphertext). This process produces two outputs:
-
computed MAC.
-
unencrypted input data (plaintext).
-
-
The computed MAC is checked against the MAC present in the CAAM blob. If they do not match, the process signals a decryption error (in this case, the regenerated BKEK was incorrect).
-
If the computed MAC matches that of the blob, the output of that last decryption is returned as the original input data.
Limitations
When using CAAM blobs:
-
The maximum input data size for a CAAM blob is 65487 bytes (almost 64 KiB).
-
This operation is quite specific so, unlike other cryptographic algorithms, external APIs rarely support it.
-
A CAAM blob is 48 bytes larger than the input data.
Use cases
Depending on whether these limitations apply, there are two main use cases:
-
You can use a CAAM blob directly.
-
You can use a standard encryption algorithm and protect its encryption key in a CAAM blob.
Direct CAAM blob usage
When working with relatively small pieces of sensitive data, you can generate CAAM blobs encapsulating the data itself. You can do this to protect things such as:
-
Encryption keys
-
Certificates
-
Other small sensitive data
In these cases, the input size is small enough to fit in a CAAM blob, and the CAAM encapsulation/decapsulation can be done before/after the protected data is used.
As an example, the TrustFence framework uses this method to secure the U-Boot environment.
Using an intermediate encryption key
When dealing with big amounts of data, or with APIs that expect standard encryption algorithms, you can follow this approach:
-
Generate a key for the encryption algorithm. Use an encryption algorithm of your choice to encrypt the data, but keep in mind that the encryption key cannot exceed the maximum size for a CAAM blob (see Limitations).
-
Protect the key as a CAAM blob.
Then when the encryption key is required by the external API, or when protected data is required, the following happens:
-
The CAAM blob is decapsulated to access the encryption key. The encryption key is now unprotected so you must not write it to storage. You should also delete it from RAM when the decryption process is complete.
-
The unprotected encryption key is provided to the external API (or used to decrypt/encrypt the data read/written).
As an example, the TrustFence framework uses this method to implement encrypted root file system. A LUKS encrypted partition is set up using dm-crypt, and the encryption key is protected as a CAAM blob. During boot, the encryption key is decapsulated from its blob to RAM and the encrypted volume is mounted.
Example application
As an example for other use cases, Digi Embedded Yocto includes an application that demostrates how to interact with CAAM blobs.
Go to GitHub to see the application instructions and source code.