Dear TF-M Team,
I'm Takekazu Tabata, a director and architect from the Fujitsu processor team. We are currently developing FUJITSU-MONAKA, which supports the CCA feature.
We have three questions regarding the TF-M documents and TF-M implementations. We would greatly appreciate it if you could provide answers.
Question 1) In the TF-M document “RSE provisioning”, The CM provisioning Key is used to encrypt DM Provisioning Bundle. https://trustedfirmware-m.readthedocs.io/en/latest/platform/arm/rse/rse_prov...
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.
However, the purpose of the data provided in the DM is not described in this document. These data are not used in the source code of TF-M v2.2.0.
DM provisioning is probably assumed to be done during device manufacturing, but could you explain the purpose in more detail? Also, What are the DM provisioning key, the DM code-encryption key and the DM config used for?
Question 2) In the TF-M document “RSE integration guide”, attestation key(CPAK) is derived by GUK. https://trustedfirmware-m.readthedocs.io/en/latest/platform/arm/rse/rse_inte...https://trustedfirmware-m.readthedocs.io/en/latest/platform/arm/rse/rse_integration_guide.html
The GUK is a key unique to a group of chips that have identical security properties, used to derive the attestation key.
However, CPAK is derived from HUK in the source code of TF-M. GUK in the specification is a typo. https://git.trustedfirmware.org/plugins/gitiles/TF-M/trusted-firmware-m.git/...https://git.trustedfirmware.org/plugins/gitiles/TF-M/trusted-firmware-m.git/+/refs/tags/TF-Mv2.2.0/platform/ext/target/arm/rse/common/bl1/rse_kmu_keys.c
/* This derives from HUK, there is a typo in the spec, not from GUK. * FixMe: this should be configurable per platform */ return setup_key_from_derivation(KMU_HW_SLOT_HUK, NULL, iak_seed_label, sizeof(iak_seed_label), NULL, 0, RSE_KMU_SLOT_CPAK_SEED, /* FixMe: The slot needs rename to IAK_SEED */ &aes_key0_export_config, NULL, false, boot_state_config);
Which is right, GUK or HUK? If it‘s HUK (not Virtual HUK), is it no problem that multiple CPAKs are generated in Multi-socket systems?
Question 3) In the CM/DM lifecycle state, is it no problem to create an original provisioning bundle to run chip or device verification programs in PE?
Thank you for your time and assistance.
Best regards, TABATA
Hey Tabata
Firstly, I'd like to apologize for the RSE documentation, as it hasn't been as well-maintained as we'd like due to previous engineering bandwidth, and this is likely the root of your questions.
Crucially, we've done effectively a full overhaul of the provisioning code recently, which is in place in v2.2.0, but the docs refer to the old provisioning methods. We've transitioned from a flow where known-structure data is fed in via a debugger and then provisioned by the ROM to a code + data blob which is input then run, which has significant advantages in flexibility.
The CM provisioning Key is used to encrypt DM Provisioning Bundle.
This is likely a typo I think, and should be the DM provisioning key, though that isn't the whole story. There are two possible flows to generate the blob encryption key, via the KRTL or via ECDH.
Note that if symmetric provisioning is used, the blob is authenticated using AES-CCM via a symmetric key. In asymmetric provisioning the blob is authenticated using ECDSA, and can optionally contain encrypted secrets and/or encrypted code encrypted using CTR mode (instead of CCM).
In the KRTL key flow, the encryption is using `kprov_<c|d>m` which is derived from the RTL key (KRTL). Concretely:
``` kmaster_cm = derive(key=krtl, label="KMASTER_CM") kmaster_dm = derive(key=krtl, label="KMASTER_DM")
kprov_cm = derive(key=kmaster_cm, label="KPROV_CM") kprov_dm = derive(key=kmaster_dm, label="KPROV_DM") ```
The `kprov_` keys are used to do the actual bundle decryption/aead decryption. Note that these keys are unrelated to the `<c|d>m_provisioning_key slots in the LCM` as they are derived and not stored in OTP/LCM, it's just an unfortunate coincidence of naming.
Alternately for DM provisioning it's possible to perform ECDH to agree the key:
The DM ECDH flow uses a "chainload" blob signed by the CM. This blob embeds a trusted DM public key which has been supplied to the CM and can then perform ECDH between the DM (using the corresponding private key) and the device (authenticated by the device attestation key which the DM knows) to get a shared secret for symmetric blob aead encryption. The ECDH flow provides better security, since it's not possible for the CM to know the key the DM is using for provisioning, where in the other flow the CM has access to the KRTL and so could generate kprov_dm and snoop on DM secrets
However, the purpose of the data provided in the DM is not described in this document.
This depends a lot on the DM / device. If the DM owns the AP/SCP firmware we'd expect the DM to provide some public keys to verify the AP and SCP image. It might also contain DM secret keys for image encryption if that is desired by the DM. In certain configurations it might be reasonable to have no DM data at all.
Also, What are the DM provisioning key, the DM code-encryption key and the DM config used for?
These keys are a legacy of the cryptocell-312 lifecycle management hardware, influenced by requirements for the projects for which it was developed. We do not have a clear usecase for provisioning these keys (similar to the CM provisioning and code encryption key slots in the LCM). Currently, we are exploring used them for providing enhanced confidentiality and integrity to the DM by preventing CM altering the DM OTP secrets and/or ROTPKs, but this would involve on-device-generated keys.
Which is right, GUK or HUK?
The CCA security model recommends using the GUK in this usecase, in order to prevent it being possible to work out on which physical server on which a workload is running from the CCA attestation token.
However, this shared-key approach presents a security issue where if one system is compromised, it is possible to forge CCA attestation tokens for all systems which use that key, and is much more difficult to recover from than a compromise of a single system's key. There is an alternate attestation model where the HUK is used to generate the CPAK, and then the CPAK public key (signed by the RTL key) is output during the provisioning process into a database of valid device public keys.
This does not preserve privacy of the underlying system in the CCA token, but has better security properties, so is a trade-off. It is technically acceptable in the CCA security model, but violates the recommendation "[R0025] Arm recommends that as a minimum IAK is derived or provisioned uniquely for a group of implementations with the same security properties, rather than for unique instance.".
is it no problem that multiple CPAKs are generated in Multi-socket systems
There are a few different approaches here as well.
If the system is single-socket, and all chiplets are combined before CM provisioning, then it's valid to use either the vHUK to generate the CPAK, or to select an RSE to be primary and use its HUK to be the CPAK. It is not a problem if the non-primary RSEs generate CPAKs which are then ignored.
If not all chiplets are combined before CM provisioning, then it's not possible to use the vHUK of the whole system, since the CPAK must be known at CM provisioning time. In this case, it is recommended to generate a CPAK public key for each chiplet and store it into the attestation key database (if the chiplet contains multiple RSEs, either selecting a primary or using the chiplet vHUK). Then, when the chiplets are combined, one is selected to be primary and its CPAK is used. Note that in this case a GUK is still required for the chiplets to establish trust in each other.
In a multi-socket system where chips can be swapped between systems, the same approach can be used where each chip generates a CPAK, and then the one in the primary socket is used. Note that this means that chips in the same system would produce a different attestation key, but since all chips have attestation keys in the database, the attestation verification would still succeed. Again, a GUK must be present in order to establish trust, and in this case leaking the GUK would make the system susceptible to an attack where an attacker emulates the RSE on the second socket and allows the system to boot in a state where the second socket doesn't comply with the CCA security guarantees but can still make requests to the RSE in the first socket (with a valid CPAK) for valid attestation tokens.
In the CM/DM lifecycle state, is it no problem to create an original provisioning bundle to run chip or device verification programs in PE?
This is an intended use of the provisioning blobs, particularly when RSE debug is closed (during DM provisioning in some configurations, for example), though we have had feedback from partners that the time required for the ECDSA validation (when using asymmetric provisioning) increases test cost and hence is undesirable. If RSE debug is enabled, it is likely preferable to instead just insert test code via that interface.
Note that currently it might be possible for DM test code to compromise CM security. The following measures must be taken: 1. The entire CM ROTPK array must be provisioned (with zero-counts) prior to running DM test code, in order that the DM cannot insert new ROTPKs and then select them via the ROTPK reprovisioning feature. 2. Blob chainloading must be used where the CM-signed chainloader blob invalidates the hardware keys in the RSE before allowing less trusted test code to run, particularly the CM OTP encryption key.
We are exploring ways to relax the first requirement, since this is currently a major downside.
If you have any further questions about the RSE then feel free to send messages here or to me directly - it will be a good incentive to find time to update our documentation.
I hope this is helpful, Raef
________________________________________ From: Takekazu Tabata (Fujitsu) via TF-M tf-m@lists.trustedfirmware.org Sent: 28 May 2025 06:33 To: 'tf-m@lists.trustedfirmware.org' Cc: Takeuchi, Tsuyoshi/竹内 剛; Toyoda, Yuta/豊田 雄太; Tabata, Takekazu/田端 猛一 Subject: [TF-M] Provisioning related questions about TF-M documents and TF-M implementations
Dear TF-M Team,
I'm Takekazu Tabata, a director and architect from the Fujitsu processor team. We are currently developing FUJITSU-MONAKA, which supports the CCA feature.
We have three questions regarding the TF-M documents and TF-M implementations. We would greatly appreciate it if you could provide answers.
Question 1) In the TF-M document “RSE provisioning”, The CM provisioning Key is used to encrypt DM Provisioning Bundle. https://trustedfirmware-m.readthedocs.io/en/latest/platform/arm/rse/rse_prov...
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.
However, the purpose of the data provided in the DM is not described in this document. These data are not used in the source code of TF-M v2.2.0.
DM provisioning is probably assumed to be done during device manufacturing, but could you explain the purpose in more detail? Also, What are the DM provisioning key, the DM code-encryption key and the DM config used for?
Question 2) In the TF-M document “RSE integration guide”, attestation key(CPAK) is derived by GUK. https://trustedfirmware-m.readthedocs.io/en/latest/platform/arm/rse/rse_inte...https://trustedfirmware-m.readthedocs.io/en/latest/platform/arm/rse/rse_integration_guide.html
The GUK is a key unique to a group of chips that have identical security properties, used to derive the attestation key.
However, CPAK is derived from HUK in the source code of TF-M. GUK in the specification is a typo. https://git.trustedfirmware.org/plugins/gitiles/TF-M/trusted-firmware-m.git/...https://git.trustedfirmware.org/plugins/gitiles/TF-M/trusted-firmware-m.git/+/refs/tags/TF-Mv2.2.0/platform/ext/target/arm/rse/common/bl1/rse_kmu_keys.c
/* This derives from HUK, there is a typo in the spec, not from GUK. * FixMe: this should be configurable per platform */ return setup_key_from_derivation(KMU_HW_SLOT_HUK, NULL, iak_seed_label, sizeof(iak_seed_label), NULL, 0, RSE_KMU_SLOT_CPAK_SEED, /* FixMe: The slot needs rename to IAK_SEED */ &aes_key0_export_config, NULL, false, boot_state_config);
Which is right, GUK or HUK? If it‘s HUK (not Virtual HUK), is it no problem that multiple CPAKs are generated in Multi-socket systems?
Question 3) In the CM/DM lifecycle state, is it no problem to create an original provisioning bundle to run chip or device verification programs in PE?
Thank you for your time and assistance.
Best regards, TABATA
tf-m@lists.trustedfirmware.org