RSE provisioning

Provisioning theory

The LifeCycle Manager (LCM) controls access to the RSE OTP, and includes a state-machine that controls Lifecycle-state (LCS) transitions. The LCM is derived from the OTP management and state machine subsystems of the CryptoCell-3XX series accelerators, and will be familiar to those who have worked with them.

When the chip hasn’t been provisioned, the OTP is blank, which means the LCM is in “Virgin” Test/Production mode “TP mode” state. The first step for provisioning must be to set the LCM to either test-chip mode “TCI” or production-chip mode “PCI”. In TCI mode the RTL key is masked to avoid disclosure, several OTP fields are changed from write-only to read-write, to aid in debugging, and debugging is not limited in secure provisioning mode (though the RTL key reads as zero). If TFM_DUMMY_PROVISIONING is enabled in cmake (which it is by default) then the chip will be set to TCI mode. If this option is not enabled, execution will pause to allow the setting to be set by a debugger.

Once the TP mode has been set, the chip is then is Chip Manufacturer provisioning state “CM”. This mode is intended for the provisioning of the HUK, GUK, CM provisioning key, CM code-encryption key, the root-of-trust public key and the CM config. To provision these fields, The firmware must first receive a provisioning bundle via a debugger. This bundle must be placed at the start of VM0 + an offset the size of the OTP DMA ICS (usually 0x400). This bundle contains the keys and also code to perform the provisioning such as a driver for the LCM, and a function to randomly generate the HUK via the CryptoCell TRNG. The chip must then enter secure provisioning mode by setting the SP_ENABLE register. This causes a reset (but does not clear the RSE SRAMs), and allows access to the RTL key by exporting it to the KMU, though in secure provisioning mode the ability to debug the RSE is disabled, to prevent disclosure of the decrypted provisioning bundle values. The RSE will then decrypt and authenticate the bundle using the RTL key. Under TCI mode the RTL key is zeroed, the bundle generation tool must use a zeroed key to encrypt and sign the bundle. Once the CM provisioning bundle has been unpacked, the RSE will execute the code which will provision the CM provisioning data into OTP. The RSE must be cold-reset, which will disable secure provisioning mode. If TFM_DUMMY_PROVISIONING is enabled the reset will happen automatically, else the external provisioning device should read the provisioning state from the GPIO/PSI (which is set via the rse_sysctrl register) and perform the reset.

After the cold reset, the RSE will automatically transition to Device Manufacturer provisioning state “DM” as the LCM hardware state-machine reads the values of the cm_config_1 and cm_config_2 fields as non-zero. This state is designed to provision the DM provisioning key, the DM code-encryption key and the DM config. The procedure follows the same steps as the CM provisioning flow, with the exception that the bundle will now be encrypted and signed using the CM provisioning key and must be placed at the base of VM1. As before, once the provisioning bundle has been unpacked/run, the RSE must either be cold-reset or will perform this automatically.

After the cold reset, the device will now be in Secure Enable “SE” mode, due to the dm_config_1 field being non-zero. Debug may be limited based on the hardware DCU mask for SE state. Provisioning will not be run on boot.

Practical RSE provisioning

The RSE buildsystem produces two provisioning bundles (containing both code and data), and then encrypts and signs them with the RTL key to produce encrypted_cm_provisioning_bundle.bin and encrypted_dm_provisioning_bundle.bin.

Note

Currently encrypted provisioning bundles are not supported due to a lack of AEAD encryption support in the cc312-rom-lib driver. The encrypted_*_provisioning_bundle.bin files should still be used, but note that their contents are not encrypted.

On first boot, the RSE is in Virgin state. If the RSE firmware was built with TFM_DUMMY_PROVISIONING enabled then it will automatically set the chip to TCI mode and cold-reset. Production ROM implementations must disable TFM_DUMMY_PROVISIONING, which will cause RSE to loop in the ROM until either TCI or PCI mode is set with a debugger. It is possible to set the TP mode in the LCS registers directly, however it may be easier to set the tp_mode variable in the frame where RSE is looping, at which point the loop will exit and the TP mode will be set by the ROM code.

On non-virgin boot in CM lifecycle state, RSE checks the start of VM0 for the magic constant 0xC0DEFEED, which is required to be the first word in the CM provisioning bundle. There is also a second check for a constant at the end of the bundle to ensure the bundle has finished writing. The RSE will perform this check in a loop until a bundle is found.

This procedure is repeated for DM LCS, except that the magic constant is 0xBEEFFEED and the bundle must be loaded to the base of VM1. Note that the size of RSE memory may vary depending on implementation, so the load address of the DM bundle may change.

In production systems it is intended that these bundles are loaded by a debugger, but for development systems it may be too onerous to perform this procedure, particularly if the system is one that has ephemeral OTP such as an FVP. The preferred solution is to preload to the provisioning bundles into VM0 and VM1 as part of the image loading, which is supported on FVPs but may not be on other systems. An alternative solution is to perform provisioning manually once, and then to save the state of the OTP in SE LCS and then preload that on subsequent boots.

RSE provisioning GPIO signalling

The state of the RSE ROM boot/provisioning flow is signalled outside of the RSE subsystem via the GPIOs as part of the Persistent State Interface (PSI). The PSI signals the lifecycle state as a hardware signal, but additionally the software can signal over the PSI by setting the rse_sysctrl register.

The boot state is encoded in the lowest 4 bits of the rse_sysctrl register, and has meaning as follows:

Signal

State

0x0

RSE cold boot default

0x1

Virgin chip idle, ready to set PCI/TCI mode

0x2

CM LCS idle, waiting for CM provisioning bundle

0x3

RMA LCS idle

0x4

CM secure provisioning started, secure provisioning mode enabled

0x5

CM secure provisioning failed due to bundle authentication error

0x6

CM secure provisioning failed due to other error

0x7

CM secure provisioning succeeded

0x8

DM LCS idle, waiting for CM provisioning bundle

0x9

DM secure provisioning started, secure provisioning mode enabled

0xa

DM secure provisioning failed due to bundle authentication error

0xb

DM secure provisioning failed due to other error

0xc

DM secure provisioning succeeded

0xd

SE LCS standard boot


Copyright (c) 2022-2024, Arm Limited. All rights reserved.