Safeguard
Supply Chain Security•

TCG DICE Explained: Layered Device Identity for Microcontrollers

TCG DICE gives small chips a hardware identity without a TPM: a secret mixed with a hash of the next code. How layers, certificates and attestation work.

Safeguard Security Team
46 min read

TCG DICE (Device Identifier Composition Engine) is a Trusted Computing Group design that gives a chip a cryptographic identity without a TPM. At reset, a tiny piece of immutable hardware mixes a per device secret with a hash of the first code it is about to run, locks the secret away and hands the result to that code. Because the identity depends on the code, changing the firmware changes the identity, and each boot stage can repeat the trick for the next one, building a certificate chain a remote verifier can check.

This guide goes one level deeper than our posts on SPDM device attestation and CPU microcode updates. Every title, date, field name and object identifier below comes from the TCG specifications, the Open Profile for DICE, IETF RFCs 9334 and 9711, NIST SP 800-193, Android's documentation and the Caliptra specification listed under Sources. Where two of them disagree, we say so.

Key takeaways

  • DICE is a minimal hardware root of trust. TCG's hardware requirements say the engine must have exclusive read access to a Unique Device Secret (UDS), must combine it with a measurement of the First Measured Code using a one way function, and must block access to the UDS before handing over control.
  • The output is the Compound Device Identifier (CDI). The TCG spec gives two example constructions, a hash of the UDS concatenated with the code hash, or an HMAC keyed with the UDS. Any change to the UDS or the measured code produces a different CDI.
  • Layering repeats the same step at each boot stage. Layer n mixes its own CDI with a measurement of layer n+1, then hides its CDI before jumping. Malware that replaces a stage never sees the CDI the genuine stage would have received.
  • Keys come from CDIs. The layer 0 key is called the DeviceID; the key derived from the last CDI is the Alias Key, which signs attestation evidence. Each layer can act as an Embedded Certificate Authority (ECA) and certify the next layer's key, producing an X.509 chain from a manufacturer root to the running firmware.
  • DICE maps cleanly onto the IETF RATS architecture (RFC 9334): the device is a layered Attester, certificates carry Evidence in TCG extensions such as DiceTcbInfo, and a Verifier compares that Evidence with Endorsements and Reference Values before a Relying Party trusts the device.
  • DICE gives identity and attestation, not protection or recovery. Rollback, UDS provisioning, CDI leakage, measurement gaps and lax verifier policy are the places real deployments go wrong.

What is DICE, and why was it designed for devices too small for a TPM?

The TCG DICE Architectures work group page describes DICE as technology that "establishes a unique cryptographic identity for resource-constrained devices", for systems "with or without a TPM". Its stated goal is new approaches to security and privacy "with minimal silicon requirements". The page's reasoning is simple: many components, from IoT sensors to the small controllers inside larger systems, have no TPM or similar security chip, and the cost, power and area constraints of those markets make one hard to add.

A TPM 2.0 is a complete security subsystem with protected key storage, Platform Configuration Registers and a command interface. DICE asks for far less: a secret only the engine can read, a one way function, a latch that hides the secret and a defined jump into measured code. That fits in mask ROM plus a few fuses and a register lock, which is why DICE reaches microcontrollers, FPGAs, peripherals and security subsystems inside larger chips.

Which TCG documents define DICE?

There are four core specifications and one runtime interface. The table lists what each one covers, with dates taken from the TCG resource pages and the PDFs themselves.

DocumentLatest version we foundDateWhat it defines
Hardware Requirements for a Device Identifier Composition EngineVersion 1.0, Revision 0.91TCG page: 22 March 2018; PDF footer: 8 August 2024UDS properties, the CDI computation, the reset and lock flow, debug rules, immutable versus updatable engines
DICE Layering ArchitectureVersion 1.0, Revision 0.1923 July 2020How CDIs chain through layers 0 to n, DeviceID and Alias Keys, embedded CAs, trust requirements per layer
DICE Attestation ArchitectureVersion 1.2 (PDF footer: Revision 3), plus Errata v1.0 r124 April 2025; errata 29 January 2026Attestation roles, Evidence and Endorsement extensions for X.509 such as DiceTcbInfo, MultiTcbInfo, Ueid and the conceptual message wrapper
DICE Certificate ProfilesVersion 1.124 April 2025X.509 conventions for IDevID, LDevID, ECA and attestation certificates, and the TCG DICE key purpose OIDs
DICE Protection EnvironmentVersion 1.025 October 2024A service interface that keeps CDIs inside a protected environment and derives keys on behalf of callers

One date conflict: the TCG resource page lists the hardware requirements v1.0 r0.91 as published on 22 March 2018, but the footer of the PDF it serves reads 8/8/2024, and the text uses the newer term "First Measured Code" in place of "First Mutable Code". We cite both dates.

A timeline of DICE and the standards around it

DateEventSource
22 March 2018TCG lists Hardware Requirements for a DICE v1.0 r0.91 (PDF footer dated 8 August 2024)TCG resource page and PDF
May 2018NIST publishes SP 800-193, Platform Firmware Resiliency GuidelinesNIST CSRC
23 July 2020DICE Layering Architecture v1.0 r0.19 and DICE Certificate Profiles v1.0 r0.01 publishedTCG resource pages
1 March 2021DICE Attestation Architecture v1.00 r0.23TCG resource page
7 June 2021Errata for DICE Certificate ProfilesTCG resource page
January 2023RFC 9334, Remote ATtestation procedureS (RATS) ArchitectureRFC Editor
6 January 2024DICE Attestation Architecture v1.1 r18TCG resource page
25 October 2024DICE Protection Environment v1.0TCG resource page
April 2025RFC 9711, The Entity Attestation Token (EAT), Standards TrackRFC Editor
24 April 2025DICE Attestation Architecture v1.2 and DICE Certificate Profiles v1.1TCG resource pages
29 January 2026Errata v1.0 r1 for DICE Attestation Architecture v1.2TCG resource page
30 September 2026Android's DICE documentation page last updatedsource.android.com

How does DICE work?

The hardware requirements specification breaks the engine into four steps that run from reset: measure, compute, lock and transfer. The Open Profile for DICE expands the same flow into seven steps once certificates are added. Here is the core flow first.

  1. Reset. The chip comes out of reset and starts executing the DICE engine, usually mask ROM. TCG's informative text describes the common pattern: read access to the UDS storage is enabled by a hardware event such as reset, then disabled by a software command.
  2. Measure. The engine hashes the First Measured Code (FMC), which the spec says may be a bootloader, a boot ROM or an FPGA bitstream. It can optionally include hardware state and configuration that could influence how that code runs.
  3. Compute the CDI. The engine mixes the UDS with the measurement through a one way function, so the UDS cannot be recovered from the CDI and the measurement.
  4. Lock. The engine blocks further access to the UDS by a hardware mechanism and erases any remnants from memory.
  5. Transfer. Control jumps to an architecturally defined location in the measured code, which receives the CDI.

The Unique Device Secret

The UDS is the only long term secret in a DICE device. The TCG requirements are short. UDS values must be uncorrelated and statistically unique. The UDS must not be used as an identity value by any other entity. It must be long enough to support the security strength of the algorithms the device uses. The spec adds a practical point that is easy to miss: no key derived from the UDS can be stronger than the UDS itself, so the UDS length is an upper bound on the strength of every attestation key the device will ever have.

The engine must have exclusive read access to the UDS. If the device has a debug port or debug mode, it may only be enabled at reset or explicitly by software that runs after the engine, and while debug is on, any attempt to read the UDS, including by the engine itself, must be denied or must return a value uncorrelated with the UDS. TCG notes that a constant such as all zeros counts as uncorrelated. That rule is what stops a debugger attached at boot from extracting the root secret.

The Open Profile for DICE tightens these requirements. It asks for a UDS of at least 256 bits that is full entropy, conditioned from at least 512 bits of entropy. If a UDS has not been provisioned, the device uses all zero bytes, which keeps factory testing predictable. Its provisioning tests include a check that the CDI values cannot be reproduced with a zero UDS, which catches a device that shipped without its secret.

The Compound Device Identifier

The TCG spec gives two example constructions and lets the manufacturer choose, because the choice does not affect interoperability:

CDI = H( UDS || H(FMC) )          (1)  secure hash construction
CDI = HMAC( UDS, H(FMC) )         (2)  HMAC construction, UDS as the key

TCG notes that the HMAC form gives the UDS more protection than a plain hash, citing NIST SP 800-57.

The point of the design is in one sentence of the spec: "A benefit of the CDI is that the CDI has a different value when the FMC changes." If an attacker replaces the bootloader with malware, the malware is measured, the CDI it receives is different, and the CDI that belonged to the genuine bootloader is never produced. If the bootloader is patched, the patched version gets a new CDI too. The secret the genuine firmware holds cannot be obtained by any other firmware on that device, and the same firmware on another device gets a different CDI because the UDS differs.

Worked example: why a one byte code change changes the identity

The snippet below uses the HMAC construction with SHA-256 and an all zero test UDS, which is exactly the "unprovisioned" value the Open Profile uses for testing. It is illustrative only: real devices compute this in ROM with a secret no software can read.

import hashlib, hmac

uds = bytes(32)  # all-zero test UDS; a real UDS is secret and never leaves the chip
for fw in [b"bootloader v1.4.0", b"bootloader v1.4.1"]:
    measurement = hashlib.sha256(fw).digest()
    cdi = hmac.new(uds, measurement, hashlib.sha256).hexdigest()
    print(fw.decode(), "H(FMC)=", measurement.hex()[:16], "CDI=", cdi[:16])

Running it prints:

bootloader v1.4.0 H(FMC)= 4804ceddd3b0da98 CDI= 5d7ee98aba120e54
bootloader v1.4.1 H(FMC)= c6599fcec11b763a CDI= 3ea0296a4d261150

One changed character in the "image" gives an unrelated measurement and an unrelated CDI. On a real device, every key and certificate derived from that CDI changes with it.

The Open Profile's richer inputs

The TCG spec mentions code and optional configuration. The Open Profile for DICE (specification v2.6 at the time we read it) defines five fixed size inputs per layer:

InputSizeWhat it captures
Code64 bytesA hash of the target code, or a descriptor such as the root hash of a hash tree for images too big to hash at once
Configuration Data64 bytesSecurity relevant configuration: verified boot authority selection, device mode, boot location, chip status, instance identifiers. May change between boots
Authority Data64 bytesA hash of the verified boot trusted authority, for example the public key in one time programmable memory. All zeros if code authorization is off
Mode Decision1 byte0 Not Configured, 1 Normal, 2 Debug, 3 Recovery
Hidden Inputs64 bytesOptional, never appears in a certificate. For example an ownership secret or a rotation counter

It then derives two different CDIs from those inputs, which solves a real problem with the single TCG CDI. A CDI that changes with every firmware update is perfect for attestation and terrible for sealing data, because an update would make previously encrypted data unreadable.

CDI_Attest = KDF(32, UDS, H(code + config + authority + mode + hidden), "CDI_Attest")
CDI_Seal   = KDF(32, UDS, H(authority + mode + hidden), "CDI_Seal")

The attestation CDI changes with any code or configuration change. The sealing CDI depends only on the signing authority, the mode and the hidden inputs, so it stays stable across signed updates but still changes if someone boots in debug mode or with a different verified boot key. The Open Profile notes that sealing therefore only works well together with a verified boot system. Its default cryptography is SHA-512, HKDF with SHA-512 and Ed25519, chosen so a device needs only one hash function. It also allows SHA-256 and SHA-384, ECDSA on P-256 and P-384, and ML-DSA.

Worked example: how the Open Profile turns a CDI into a key and an ID

The Open Profile derives keys deterministically, so a device can recreate them on every boot without storing a private key:

seed = KDF(32, CDI_Attest, ASYM_SALT, "Key Pair")   -> 32 byte seed
CDI_Private, CDI_Public = Ed25519 key pair from seed
CDI_ID = KDF(20, CDI_Public, ID_SALT, "ID")          -> 20 byte identifier

The same pattern applies to the UDS (UDS_ID from UDS_Public). In the X.509 certificates, the 20 byte IDs become the serial number and the key identifiers that link each certificate to its issuer, and each certificate carries a 64 byte Ed25519 signature. Because everything is derived, the device can recreate its keys and even its CDI certificate on every boot.

How do DICE layers chain?

Layers, measurements and CDIs

The DICE Layering Architecture generalises the reset step into a pattern any stage can follow. By convention, the code that receives the CDI from the hardware engine is layer 0. Layer 0 measures layer 1 to produce a TCB Component Identifier (TCI), mixes it with its own CDI to make the layer 1 CDI, protects its own CDI, and transfers control. Layer 1 does the same for layer 2, and so on. The spec gives example stacks: boot loader then operating system, hypervisor loader then hypervisor, enclave runtime then enclave applet, runtime boot loader then co-processor runtime.

The Open Profile writes the layered computation explicitly:

CDI_Attest[n+1] = KDF(32, CDI_Attest[n], H(code + config + authority + mode + hidden), "CDI_Attest")
CDI_Seal[n+1]   = KDF(32, CDI_Seal[n],   H(authority + mode + hidden),               "CDI_Seal")

The protection rule is strict. Layer n+1 must never obtain CDI[n] and must not be able to use it in any computation, which means a layer cannot offer a service that uses its CDI on behalf of the next layer. Where a layer stays resident and launches several children, as a kernel, a trusted execution environment or a hypervisor does, its CDI must be protected from all of them while they run and destroyed when no longer needed. The TCG layering spec adds the matching trust rule: a DICE layer must protect its CDI and derived private keys and must not implicitly trust any layer that executes after it.

DeviceID and Alias Keys

The layering spec names two key types. The DeviceID is the asymmetric key derived from the CDI of layer 0. Its requirements are specific: it must be created by a manufacturer controlled process, its derivation must depend on the layer 0 CDI, the manufacturer should issue a certificate for it (for example an IEEE 802.1AR IDevID), and any change to the layer 0 TCB must produce a different DeviceID key. TCG observes that if a DeviceID certificate is expected to be irrevocable and never expire, layer 0 should not be modifiable outside a manufacturer controlled process. Put simply, if you plan to update layer 0 in the field, plan to re-certify the DeviceID.

The Alias Key is the asymmetric key derived from the last CDI in the chain. It and its certificate are usually the leaf of the chain and carry attestation information about the top level firmware. The Alias Key signs attestation evidence. Both keys are "DICE Layered Identities": in the certificate profiles' wording, identities that "cannot exist without a precise chain of TCB components".

Certificates per layer and embedded CAs

There are two ways for a layer to extend trust to the next. Under the first, the layer is an Embedded Certificate Authority: following a policy in its own firmware, it generates or derives the next layer's key and issues the certificate itself. Under the second, the higher layer creates a Certificate Signing Request and the ECA signs it. The layering spec walks through the first model: layer n measures layer n+1, computes the layer n+1 CDI, derives the next layer's key, and signs a certificate for it with its own key before transferring control.

A typical chain looks like this:

Manufacturer root CA
  └─ DeviceID certificate (layer 0 key, issued in the factory; an IDevID)
       └─ Layer 1 certificate (issued on device by layer 0 acting as an ECA)
            └─ ...
                 └─ Alias Key certificate (leaf; signs attestation evidence)

The Open Profile builds the same chain with its own names. The UDS certificate is issued externally during manufacturing, and each CDI certificate is signed by the previous layer's key. Every UDS and CDI certificate is semantically a CA certificate, and the Open Profile is explicit that CDI private keys should only sign certificates: they should certify an attestation key rather than take part in attestation protocols directly. If a component launches nothing further, pathLenConstraint can be set to zero so no deeper layer can be certified.

What the TCG DICE Certificate Profiles specify

DICE Certificate Profiles v1.1 sets conventions so that verifiers can parse certificates produced by different devices. The rules that matter most in practice:

  • Serial numbers. Must be unique per CA for each Alias Key certificate. Different embedded CAs may reuse serial numbers, so a verifier must never treat a serial number alone as a device identifier.
  • Lifetime. A device with a secure clock can set real validity periods. A device without one may set notAfter to the X.509 value 99991231235959Z, meaning no defined expiry, and notBefore to a recent known time such as the TCB build time. The profile expects certificates to rotate with firmware updates.
  • Names. Subject names should identify the environment that holds the private key, may carry serial numbers, firmware identifiers or layer coordinates, and must work in plain byte comparisons. The issuer name at layer n+1 must match the subject name of the issuing certificate at layer n. When a layer acts as an ECA, the root ECA subject must be device unique.
  • No claims from names. The profile recommends that verifiers do not read attestation claims from Subject, SubjectAltName, Issuer or IssuerAltName.
  • Key purposes. The profile defines Extended Key Usage OIDs under the TCG arc 2.23.133.5.4.100: identityInit (6) and identityLoc (7) for initial and local device identities such as IDevID and LDevID, attestInit (8) and attestLoc (9) for attestation keys, assertInit (10) and assertLoc (11), and eca (12) for an embedded CA.
  • Profiles. Tables for IDevID, LDevID, ECA and attestation certificates. An ECA certificate must contain the ECA key purpose and cA:TRUE; an IDevID certified by an embedded CA requires that the embedded CA key itself is certified by the manufacturer and bound to the device during manufacturing.

The Attestation Architecture adds the extensions that carry measurements. The most important is DiceTcbInfo, OID 2.23.133.5.4.1, a sequence of optional fields: vendor, model, version, svn (security version number), layer, index, fwids (a list of hash algorithm and digest pairs), flags, vendorInfo, type and integrityRegisters. The operational flags include notConfigured, notSecure, recovery, debug, notReplayProtected, notIntegrityProtected, notRuntimeMeasured, notImmutable and notTcb. Other extensions in the same arc include MultiTcbInfo (2.23.133.5.4.5) for several components in one certificate, Ueid (2.23.133.5.4.4) for a unique entity identifier, endorsement manifest (.2) and manifest URI (.3), and the conceptual message wrapper (.9) for carrying other evidence formats.

One rule in the DiceTcbInfo section is the bridge between identity and attestation: the issuer must include in DiceTcbInfo any field that contributes to the CDI that generates the subject key. If a value changed the key, the verifier must be able to see it.

The Open Profile uses a different extension of its own, OID 1.3.6.1.4.1.11129.2.1.24 (an arc under a private enterprise number, named diceAttestationData), whose OpenDiceInput sequence carries the code hash, code descriptor, configuration hash, configuration descriptor, authority hash, authority descriptor and mode. It also allows CBOR certificates built on CBOR Web Tokens and COSE instead of X.509, and lets the two formats mix within one chain.

How does DICE fit the IETF RATS architecture?

RFC 9334 (January 2023) defines the vocabulary most attestation systems now share. Its roles are the Attester, which produces Evidence; the Verifier, which appraises Evidence using Endorsements, Reference Values and an Appraisal Policy for Evidence; the Relying Party, which uses the Verifier's Attestation Results to make a decision; and the Endorser, Reference Value Provider and the owners of each policy. DICE Attestation Architecture v1.2 adopts these roles explicitly and cites RFC 9334.

The mapping onto a DICE device is direct:

RATS concept (RFC 9334)DICE equivalent
AttesterThe device, as a stack of DICE layers
Attesting EnvironmentThe DICE engine for layer 0; layer n for layer n+1
Target EnvironmentThe next layer being measured
EvidenceAlias Key and layer certificates with DiceTcbInfo or similar extensions, plus anything the Alias Key signs
EndorsementThe manufacturer's DeviceID or UDS certificate, and statements about what the hardware is
Reference ValuesExpected FWID digests, versions and SVNs, often from a signed manifest
VerifierA service that validates the chain and compares measurements with Reference Values
Relying PartyThe service deciding whether to accept the device: a fleet manager, a key service, a peer

Section 3.2 of RFC 9334, "Layered Attestation Environments", reads almost like a description of DICE. An Attester may consist of nested layers; the bottom layer's Attesting Environment is designed to be immutable or hard to modify; Claims are normally not self asserted, because a previous layer acts as the Attesting Environment for the next; and Claims about the initial layer are typically asserted by an Endorser. The RFC's example is a ROM, a bootloader and a kernel, with the ROM endorsed by its maker and Reference Values supplied for all three.

RFC 9334 also describes two conveyance patterns. In the Passport Model, the Attester sends Evidence to the Verifier, gets an Attestation Result back and presents that result to Relying Parties. In the Background-Check Model, the Attester sends Evidence straight to the Relying Party, which forwards it to a Verifier. A DICE certificate chain works in both: it can be checked once and exchanged for a short lived token, or forwarded on each connection.

Freshness is the piece certificates alone do not give you. An Alias Key certificate shows what booted, not that the device is the one talking to you now. The attestation architecture expects Evidence to carry freshness claims, for example a Verifier supplied nonce signed by the Alias Key. RFC 9711, the Entity Attestation Token (Standards Track, April 2025), defines a signed claims format that many systems use for that signed, fresh Evidence. In data center hardware, the SPDM protocol plays the same role (the TCG work group also lists a DICE Concise Evidence Binding for SPDM document), carrying the DICE chain and signing a verifier's challenge, which our SPDM post covers in depth.

Where is DICE used?

Microcontrollers and small devices

The original audience. A microcontroller with mask ROM, a few fuses for the UDS, a hash engine and a register lock can implement the TCG hardware requirements. The value for a fleet of small devices is that each unit can prove both which chip it is and which firmware it is running, without a separate security chip on the board.

Android

Android's documentation states that DICE has been adopted into Android and describes the flow in Android's terms. At stage 0 the chipset ROM reads the UDS from immutable storage, typically fuses, and a hardware latch locks UDS access until the next boot. At stage 1 the ROM uses the UDS in a key derivation function to create a permanent device key pair, measures the next firmware stage including whether secure boot is enabled, and derives the first CDI. From stage 2 onward each stage derives a new CDI from the previous one and the hash of the next image, generates its own key pair and signs a certificate with its measurements. The page notes that the resulting posture can only be evaded by compromising the ROM. The Open Profile for DICE lists an Android Profile for DICE as a known specialization.

Open Profile for DICE

The Open Profile for DICE is an open specification with portable C99 code, hosted in the Pigweed project's source repository. Its README describes it as a specialization of the TCG hardware requirements and layering specifications, distinguished by separate attestation and sealing CDIs, categorized inputs including verified boot values, certified UDS values, and X.509 or CBOR certificates. Crypto and certificate generation are injected through callbacks, with implementations backed by BoringSSL, mbedTLS and a CBOR template writer. The source tree includes operations for Ed25519, P-256, P-384, ML-DSA-65 and ML-DSA-87. The spec defines three UDS provisioning schemes:

SchemeHow the UDS is createdHow it is certifiedTrade off
1. Pre-generationGenerated off device, injected in a controlled factory, source copy destroyedCertificate pre-generated and written to the deviceNo factory CA; works offline; relies on the generation facility not retaining UDS values
2. Factory CADerived on chip from internal entropy (PUF or TRNG stored in OTP) and external entropy injected onceA CA in the factory reads UDS_Public and issues a certificateUDS never exists off chip; needs a CA on the production line
3. On-demand certificationAs scheme 2Manufacturer keeps a SHA-512 hash of UDS_Public; an online CA certifies on requestNo certificate storage needed on device; the approach of sharing a list of hashes reveals device counts

Caliptra

Caliptra is open source IP and firmware for a root of trust block integrated inside data center class chips such as CPUs, GPUs and DPUs. Its README says the project began at the Open Compute Project and its source now lives in the CHIPS Alliance; the integration gives the chip identity, measured boot and attestation. Its specification says its root of trust for measurement "follows TCG DICE" and that the runtime code must have a DICE identity rooted in ROM. The Caliptra design shows how DICE scales up:

  • The UDS seed is stored as ciphertext in fuses and deobfuscated only on cold boot with a key known to Caliptra hardware. The unobfuscated UDS is used to derive the IDevID identity and is then cleared by hardware.
  • The IDevID is generated by Caliptra ROM during manufacturing, never exposed, and endorsed by the vendor's provisioning CA running on a hardware security module in the manufacturing flow.
  • An LDevID is derived using field programmable entropy (two 16 byte one time programmable slots) so an owner can create a fresh identity that an attacker who stole the UDS earlier cannot derive. The LDevID certifies the FMC alias key, which in turn certifies the runtime alias key.
  • Caliptra implements the DICE Protection Environment API so it can derive and use DICE identities on behalf of other parts of the chip, for example acting as the signing service for an SPDM responder running on the application processor.

The Caliptra specification is unusually candid about limits. It says Caliptra 1.0 alone does not fully address IDevID provisioning, gives the example of a person in the middle in the supply chain submitting its own IDevID certificate signing request to the provisioning CA, and says IDevID "is not renewable".

What NIST SP 800-193 adds

DICE answers "what is this device and what did it boot?". NIST SP 800-193, Platform Firmware Resiliency Guidelines (May 2018, author Andrew Regenscheid), answers a different question: what happens when firmware is attacked? Its abstract frames the goal as resiliency against destructive attacks that could leave a system inoperable, and organises the guidance into three principles: protecting platform firmware and critical data from unauthorized changes, detecting unauthorized changes when they happen, and recovering to a known good state.

SP 800-193 builds on three roots of trust: the Root of Trust for Update (RTU), the Root of Trust for Detection (RTD) and the Root of Trust for Recovery (RTRec). DICE helps with detection, because a tampered stage produces a different CDI and certificate that a verifier can spot. It does nothing for protection, which needs verified boot and authenticated updates, or for recovery, which needs a protected recovery image. A complete design pairs DICE with signed updates, anti-rollback and a recovery path.

What are DICE's weak points?

DICE removes many problems, but deployments go wrong in predictable places. None of these are flaws in the cryptography; they are gaps between what DICE guarantees and what people assume it guarantees.

UDS provisioning and leakage

Everything rests on the UDS. If it is copied during manufacturing, an attacker can compute every CDI and key the genuine device would, for any firmware, and impersonate the device indefinitely. The Open Profile's pre-generation scheme depends on the generation facility not retaining UDS values; its factory CA schemes avoid that by deriving the UDS on chip but add a CA to the production line. Caliptra's specification describes a supply chain attacker swapping in its own certificate request and treats a stolen UDS as a real threat, which is why it adds owner programmed field entropy and an LDevID.

What to do: prefer on chip derivation where the hardware supports it, keep the factory CA in a hardware security module, test that CDIs cannot be reproduced from a zero UDS, and for high value devices create an owner identity at onboarding that a stolen UDS cannot derive.

CDI leakage and replay

The TCG hardware requirements warn that a device which leaks a CDI produced from authorized firmware "may be vulnerable to a replay attack and impersonation". The CDI is a secret held by mutable code, and that code may have bugs. TCG's remedy is to update the first measured code: the new code has a new measurement and a new CDI, so the leaked value becomes obsolete, though the device identity may need re-certifying. TCG also lists erasing the CDI from RAM, registers and cache right after use, and using a DICE Protection Environment. The Open Profile's README adds that sensitive data may remain in cache, be swapped out or appear in a crash dump.

Rollback

This is the weakness people miss most often. DICE binds identity to code, so an older firmware image produces its own older CDI, deterministically, every time. If an attacker flashes a signed but vulnerable older version, the device boots it, derives the old CDI and can produce a valid looking chain for that old version. DICE does not stop this. The identity is honest: it truthfully says "I am running version 1.3". Whether that is acceptable is a verifier decision.

What to do: enforce anti-rollback in the boot path with a monotonic counter or fuses, and in the verifier, check the svn and version fields in DiceTcbInfo or the equivalent fields in your profile against a minimum. The Open Profile's Configuration Data has a field for the target software version. If your verifier only checks that the chain ends at a manufacturer root, rollback is invisible to it.

Measurement gaps

A CDI is only as complete as its inputs. Three gaps come up repeatedly:

  • The engine itself is not measured. TCG is explicit that updates to an updatable DICE are not measured into the CDI and must be inherently trusted. If your chip vendor can update the DICE engine, the strength of that update process is part of your trust base.
  • Configuration not included. If a fuse that enables a debug feature, or the choice of boot source, influences how the code runs but is not mixed into the CDI, two very different security states share one identity. The Open Profile's Mode and Configuration inputs exist to close this, and the TCG attestation spec requires DiceTcbInfo to include every field that contributed to the CDI.
  • Load after measurement. The Open Profile allows a code descriptor such as a hash tree root for large images, but notes this "requires additional ongoing enforcement to verify pages as they are loaded". A layer that measures a descriptor but then loads unchecked pages has a gap between what it measured and what runs.

Verifier policy

The most common failure is not on the device at all. A verifier that accepts any chain ending at the manufacturer root, without comparing FWIDs with Reference Values, will accept a device running any firmware the manufacturer ever signed, or even firmware it never signed if layer 0 does not enforce verified boot. Other policy mistakes the TCG documents warn against: reading claims from subject or issuer names, assuming serial numbers are globally unique, and relying on expiry to retire certificates whose notAfter is 99991231235959Z. Revocation in DICE comes from Reference Values, CRLs for issuing CAs and the fact that a firmware fix changes the key, not from expiry dates.

How does DICE compare with a TPM and a secure element?

These are different tools, and many products use more than one. Caliptra, for example, implements DICE and can authenticate to a discrete TPM.

DICETPM 2.0Secure element
What it isA small set of hardware requirements inside the main chip: a secret, a one way function, a lock and a measured jumpA dedicated security function, discrete or integrated, with a standard command interfaceA separate tamper resistant chip that stores keys and performs crypto on behalf of the host
Added silicon and costMinimal: ROM code, fuses and a register lock on the existing chipA discrete part or a dedicated block, plus firmwareA discrete part on the board
Identity modelDerived from UDS plus measured code; changes when code changes; no stored private key neededEndorsement and attestation keys held inside the TPM; identity independent of host firmwareKeys generated or injected into the element; identity independent of host firmware
How measurements are heldFolded into each layer's CDI and expressed in certificatesExtended into Platform Configuration RegistersNot inherently; the host must report measurements to it
Attestation formatX.509 or CBOR certificate chain with TCG extensions such as DiceTcbInfo, plus signed evidence from the Alias KeySigned quotes over PCR values with an event logVendor specific; often signatures with a stored key and a certificate
Behaviour on firmware updateKeys and certificates change for the updated layer and every layer after it; needs re-certification or an ECAKeys persist; PCR values change and verifiers update reference valuesKeys persist; the element does not know the host firmware changed unless told
Protects keys from compromised host codeOnly for earlier layers' secrets; the current layer holds its own CDIYes, keys stay inside the TPMYes, keys stay inside the element
Typical fitMCUs, peripherals, FPGAs, security subsystems inside larger chipsPCs, servers, some gatewaysPayment, SIM, IoT devices needing a protected key store

Step by step: build Open DICE, generate a certificate chain and decode it

This walkthrough builds the Open Profile for DICE on a Linux host, runs its test suite, which generates sample certificates with test inputs, and decodes them with OpenSSL. Nothing here touches device firmware or fuses. The build steps come from the project's README; the certificate file names come from the project's test helper source (src/test_utils.cc), and the decode command is the same one the project's generate_test_values.py uses.

Step 1: install prerequisites

The README says the only supported build path is a Pigweed environment on Linux, and bootstrapping can download on the order of 1 GB of dependencies.

sudo apt-get update
sudo apt-get install -y git python3 python3-venv build-essential openssl

Step 2: clone and bootstrap

git clone https://pigweed.googlesource.com/open-dice
cd open-dice
git submodule update --init --recursive
source bootstrap.sh
gn gen out

bootstrap.sh initializes submodules, bootstraps the Pigweed environment and generates build files. In later shells, reactivate with source activate.sh instead of bootstrapping again.

Step 3: build and run the tests

ninja -C out

This builds the library with each crypto backend and runs all tests on the host with the clang toolchain. The build also produces size reports for the library and for small executables, which are useful if you are sizing DICE for a microcontroller:

cat out/host_optimized/gen/*.txt | less

Step 4: find the sample certificates

The test helpers dump each test state to files: _attest_cdi_<name>.bin and _seal_cdi_<name>.bin for the CDIs, _<format>_<keytype>_cert_<name>.cert for each layer certificate, and _<format>_<keytype>_uds_cert.cert for the test UDS certificate, where format is X509 or CBOR. The test input sets are named zero_input, hash_only_input and descriptor_input. Locate them under the build tree:

find out -name '_X509_*cert*.cert' | sort
find out -name '_attest_cdi_*.bin' | sort

The exact directory depends on your toolchain configuration, so use find rather than assuming a path. These values come from fixed test inputs and a fake UDS. They are for learning and must never be used as real device secrets or trust anchors.

Step 5: decode a CDI certificate

The certificates are DER encoded X.509. Pick one and print it:

CERT=$(find out -name '_X509_*_cert_hash_only_input.cert' | head -n 1)
openssl x509 -inform DER -in "$CERT" -noout -text -certopt ext_parse

What to look for, mapped to the Open Profile spec:

Field in the outputWhat it should show
Serial NumberThe 20 byte CDI_ID as an integer
Issuer and SubjectNames built from the UDS_ID or previous CDI_ID and the current CDI_ID, hex encoded
ValidityWhatever dates the implementation sets; the TCG profiles allow 99991231235959Z as notAfter for devices without a secure clock
Public Key AlgorithmED25519 for the default profile, or the ECDSA or ML-DSA variant you built
X509v3 Basic ConstraintsCA:TRUE, critical
X509v3 Key UsageCertificate Sign only, critical
Subject and Authority Key IdentifierThe CDI_ID and the issuer's ID
Extension 1.3.6.1.4.1.11129.2.1.24The OpenDiceInput sequence, marked critical

Step 6: look inside the DICE extension

OpenSSL does not know the Open Profile's custom extension by name, so print the raw ASN.1 and find it by OID:

openssl asn1parse -inform DER -in "$CERT" -i | less

Search for 1.3.6.1.4.1.11129.2.1.24. The OCTET STRING that follows contains a SEQUENCE with context tags [0] codeHash, [2] configurationHash, [4] authorityHash and [6] mode, matching the ASN.1 in the spec. To decode just that extension, note the offset of the inner OCTET STRING in the output and pass it with -strparse:

openssl asn1parse -inform DER -in "$CERT" -strparse <offset>

For certificates following the TCG profiles instead, look for 2.23.133.5.4.1 (DiceTcbInfo) and 2.23.133.5.4.5 (MultiTcbInfo), and check the fwids digests and svn against your Reference Values.

Step 7: check that the chain links

Convert the UDS certificate and a CDI certificate to PEM and ask OpenSSL to verify the link, treating the test UDS certificate as the trust anchor:

UDS=$(find out -name '_X509_*_uds_cert.cert' | head -n 1)
openssl x509 -inform DER -in "$UDS"  -out uds.pem
openssl x509 -inform DER -in "$CERT" -out cdi.pem
openssl verify -partial_chain -CAfile uds.pem cdi.pem

If the UDS certificate's key type matches the CDI certificate's, you should see cdi.pem: OK. If verification fails, compare the Issuer of cdi.pem with the Subject of uds.pem and the Authority Key Identifier with the Subject Key Identifier; the TCG certificate profiles require these to match exactly between layers.

Step 8: see identity change with input

Compare the CDIs from two test input sets:

for f in $(find out -name '_attest_cdi_*.bin' | sort); do
  printf '%s  ' "$(basename "$f")"; xxd -p -c 32 "$f"
done

Each input set gives a different 32 byte attestation CDI, which is the same property our worked example showed: different measured inputs, different identity.

Step 9: from test chain to real verifier

A production verifier does more than openssl verify. It validates the chain to a manufacturer root you trust, extracts measurements from every certificate rather than only the leaf, compares them with Reference Values, rejects debug, recovery or not configured states unless policy allows them, enforces a minimum security version, and requires fresh evidence signed by the Alias Key. The weak points section above explains why each check matters.

Common mistakes

  • Treating DICE as secure boot. DICE records what booted; it does not stop anything from booting. Pair it with verified boot and authenticated updates.
  • Verifying only the chain. A chain to the manufacturer root proves the hardware is genuine. Only a comparison against Reference Values proves the firmware is approved.
  • Ignoring rollback. An older signed image produces a valid chain for the older version. Check svn or version in the verifier and enforce anti-rollback on the device.
  • Leaving configuration out of the CDI. If debug state or boot source changes behaviour but not the CDI, a debug device and a production device look identical.
  • Letting a layer use its parent's CDI. The Open Profile forbids a layer offering services that use CDI[n] to layer n+1. Use a DICE Protection Environment if you need that pattern.
  • Shipping an unprovisioned UDS. All zero UDS devices produce predictable keys. Test that the CDI cannot be reproduced with a zero UDS before the device leaves the factory.

FAQ

What does DICE stand for?

Device Identifier Composition Engine. It is the hardware function, specified by the Trusted Computing Group, that combines a Unique Device Secret with a measurement of the first code to run and produces a Compound Device Identifier.

Is DICE a replacement for a TPM?

For identity and attestation on devices that cannot fit a TPM, it can be. It is not a full replacement: a TPM also offers protected key storage independent of host firmware, PCRs and a standard command set. TCG positions DICE for systems with or without a TPM, and some designs use both.

What is the difference between UDS and CDI?

The UDS is the per device hardware secret that only the DICE engine can read, and it is locked after use. The CDI is derived from the UDS and a measurement of the next code; it is passed to that code and changes whenever the code or UDS changes.

Why does my device's attestation key change after a firmware update?

Because the key is derived from a CDI that includes a measurement of the updated firmware. That is the intended behaviour. Your provisioning flow needs an on device embedded CA or a re-certification step so the new key is still trusted.

What are DeviceID and Alias Keys in DICE?

The DeviceID is the asymmetric key derived from the layer 0 CDI, usually certified by the manufacturer as an IDevID. The Alias Key is derived from the last CDI in the chain and signs attestation evidence about the top level firmware.

What is the Open Profile for DICE?

An open specification with portable C code that fills in implementation details the TCG specs leave open: cryptographic algorithms, UDS size and provisioning, the exact input values, separate attestation and sealing CDIs, and X.509 or CBOR certificate formats. Android's DICE profile is a specialization of it.

Does DICE prevent firmware rollback?

No. An older image produces its own valid CDI and chain. Rollback protection needs monotonic counters or fuses in the boot path and a verifier that enforces a minimum security version.

How does DICE relate to SPDM and Caliptra?

Caliptra is an open source silicon root of trust that implements DICE and the DICE Protection Environment API. SPDM is a protocol that can carry a DICE certificate chain and signed measurements from a device to a verifier, so DICE provides the identity and SPDM carries it.

Where Safeguard fits

Safeguard does not implement DICE, provision device secrets, verify device certificate chains or analyse firmware or hardware, and it is not a device management or endpoint tool. The fit is indirect and sits in the software around DICE. Firmware for a DICE device is built from open source components: the crypto backends the Open Profile plugs in, RTOS and bootloader code, CBOR and ASN.1 libraries. The verifier service that appraises evidence, the factory provisioning tools and the certificate authority tooling are ordinary applications with package dependencies and container images. Safeguard can scan those repositories and images with safeguard scan --dir ., --image for a container image, or --sbom for an SBOM file your firmware build produces, writing results as JSON under ./output, and the platform shows which projects contain a given component and version.

A DICE chain tells a verifier exactly which firmware is running, which makes it more important, not less, that the open source libraries inside that firmware and inside the verifier are patched. The steps below apply to the open source dependencies and images in your firmware builds, verifier services and provisioning tools, not to the DICE engine or silicon, which only the chip vendor can change.

Fix it without waiting for upstream

Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.

1. Autonomous remediation: pull requests, not tickets

When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.

2. Gold Open Source: the safe version in seconds, free

gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds. The safeguard-sh/gold-scan-action GitHub Action can fail a build on a known exploited vulnerability, on any known vulnerability, or never, so a version you have just removed cannot quietly come back in next week's merge.

3. Gold Registry: start from components that are already fixed

registry.safeguard.sh provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs, zero malware and a completed license check, with SLSA L3 or higher provenance, a Sigstore signature and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.

When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. This fork and patch flow is in early access today, so ask which packages it covers before you plan around it.

Your situationWhat to use
A fixed version existsAutonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version
You need to know today whether you are affectedGold Open Source lookup and "Am I affected?" checker, free and without login
You want vulnerable versions to stop shippingThe Gold scan GitHub Action in CI, plus Safeguard policies and gates
Upstream has no fix yet, or will not ship oneA custom Gold request; fork and patch (early access)
You want to start clean on new projectsPull hardened components and images from Gold Registry

One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.

See how Safeguard would help

The demos below show Safeguard on ordinary software projects, not on chips, firmware images or certificate chains. They apply to the repositories and images around a DICE deployment: the verifier service, the provisioning and CA tooling, and the build pipeline that produces firmware.

The first demo is a real Safeguard CLI session. After install, safeguard opens the interactive terminal, you ask it to fix the lodash CVE in a repository, and it reads the finding and advisory, asks before each command, edits package.json to lodash 4.17.21, runs npm install and npm test with your approval, prints a summary and pushes nothing. It ends with /permissions, /model and /scan. The same ask, approve and test loop suits a verifier service, where every dependency change should be reviewed and tested before it decides which devices to trust.

Click through it at your own pace, or open it full screen.

Factory provisioning systems and firmware build hosts usually sit on restricted networks. The local runner demo shows how to set up the runner on your own machine, approve it with its device code, and then scan from the terminal. A runner on a build host can scan the provisioning tool repositories and container images stored there without opening that network.

Click through it at your own pace, or open it full screen.

If your team uses Claude, the third demo shows how to connect Claude to the Safeguard MCP server with OAuth and choose which tools Claude can use. An engineer can then ask about known vulnerabilities in the projects that hold your verifier and provisioning code, using only the tools you allowed.

Click through it at your own pace, or open it full screen.

To try it on your own repositories, download Safeguard and follow the CLI documentation.

Quick check

An attacker flashes an older, correctly signed firmware image onto a DICE device. Will the device's certificate chain still validate?

Yes. The older image produces its own deterministic CDI, keys and certificates, so the chain to the manufacturer root still validates. What changes is the measurement: the FWID or code hash and the svn or version describe the older build. Only a verifier that compares those values with Reference Values and a minimum security version will reject it, which is why anti-rollback belongs in both the boot path and the verifier.

Why does the Open Profile for DICE derive a separate sealing CDI?

The attestation CDI changes with every code or configuration change, which is right for attestation but would make sealed data unreadable after each update. The sealing CDI is derived only from the authority data, mode and hidden inputs, so it stays stable across signed updates while still changing if the device boots in debug mode or under a different verified boot authority.

Sources

Last reviewed: 24 October 2026. TCG specifications, the Open Profile for DICE and its build steps change over time; check the linked documents for the latest versions before relying on a field name or command.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.