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 {cpu-model} 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 partition see Partition 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, Secure JTAG, 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:

CAAM blob encapsulation
  1. The CAAM True Random Number Generator generates a 256-bit key. This is called Blob Key (BK).

  2. 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.
  1. 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

  2. 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:

  1. 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.

  2. 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.

  3. 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).

  4. 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).

  5. 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:

  1. 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).

  2. 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:

  1. 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.

  2. 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 filesystem. When the system uses an encrypted MTD partition, the encryption key is protected into a CAAM blob. Durign boot, the MTD driver directly uses the CAAM driver to decapsulate the encryption key from the CAAM blob in which it is stored.

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.