List of Figures
List of Tables
Acknowledgements
The Contributors of this Specification would like to acknowledge the following:
- Fabrizio D Amato (AMD)
- Steven Bellock (NVIDIA)
- Jeff Andersen (Google)
- Brett Henning (Broadcom)
Terminology
- PKI: Public-key infrastructure. Consists of a root key that is trusted by relying parties and infrastructure that manages the issuing of certificates.
- PKI owner: An entity that owns a PKI and issues device identity certificates that chain back to that PKI’s root key.
- PKI anchor point: In the context of this specification, this is the key in a device’s internal identity key hierarchy for which a PKI owner issues an identity certificate.
- Certificate deactivation: In the context of this specification, this occurs when a device identity certificate subject key’s derivation input changes, which causes the identity keypair to change.
Introduction
In a data center environment, hardware roots of trust leverage device identity keys to attest to their current configuration. Verifiers ensure that the device emitting the attestation is authentic, before going on to evaluate the attested claims against a policy.
In a simple case, such as the one illustrated in Figure 1, a device ships with an identity keypair that is endorsed by the device vendor. Verifiers ensure that the key which signed a given attestation chains back to a known vendor PKI root key.
Note: see Appendix 2.1 for clarification on DICE terminology in this and later diagrams.
A separate PKI owner may elect to issue their own certificate for the device’s identity upon receipt of the device. This identity certificate chains back to the PKI owner’s root key, rather than the vendor’s. Verifiers can verify attestations against the PKI owner’s root key, rather than the vendor’s.
Figure 2 illustrates the case of a data center operator acting as a PKI owner and issuing a certificate for the device’s identity.
There are several reasons an operator may wish to issue their own identity certificate for devices in their possession:
Consistent attestation verification
An operator’s fleet may be heterogeneous, with devices from a number of different vendors, each with their own distinct PKI. By issuing an identity certificate for devices based on the operator’s PKI, attestation verification within the operator’s fleet can be rendered more consistent and simple, as attestation can rely on a single PKI root key.
Insulation from potential vendor PKI compromise
A verifier that relies on a vendor PKI root key is relying on the ongoing security of the vendor’s PKI. Figure 4 illustrates the risk of a vendor PKI compromise, and how that risk is mitigated by way of the operator’s PKI.
Note that the act of issuing an identity certificate via an operator PKI necessarily involves relying on the trustworthiness of the vendor’s PKI. This necessary trust in the vendor’s PKI is point-in-time and does not extend past the time at which the certificate was issued. In the event that a vendor PKI becomes compromised, verifiers that trust the operator’s PKI can continue to rely on attestations emitted from existing devices that have already been deployed to the operator’s fleet. Furthermore, during identity certificate issuance, an operator may be able to rely on other signals in addition to the vendor’s PKI to establish the authenticity of devices. See Section 1.4 for more details.
Insulation from potential supply-chain compromise
Devices often support a hierarchy of identity keys, derived from a number of inputs. Figure 5 illustrates how identity keys are derived in Caliptra [1]. Other devices may have different identity layering schemes.
In Caliptra, the LDevID keypair is derived not only from UDS, but also field entropy, which is typically held in fuses and may be programmed into the device upon initial ingestion. By choosing the LDevID keypair as the PKI anchor point for the operator’s device identity certificate, the operator insulates themselves from supply-chain attackers that may have invasively exfiltrated the device’s UDS. See the Caliptra specification for additional commentary on the utility of LDevID and field entropy.
Implicit attestation
The PKI owner may select various keys in the identity hierarchy for which to issue a certificate. Each key will have different measurements contribute to that key’s derivation. By issuing a device identity certificate for a given key, the PKI owner is implicitly blessing the measurements which contribute to that key’s derivation. Any attestations endorsed via that identity certificate carry implicit assurance that the measurements which contribute to that identity key are the same as when the identity certificate was issued.
Consider the case of a data center operator that deploys a device, and a tenant that leases the device. This arrangement is illustrated in Figure 6.
In this example, a device wielding an identity key endorsed by the tenant-issued identity certificate implicitly attests that its owner configuration and FMC hash are the same as was present on the device when the tenant issued the identity certificate. The certificate will be implicitly deactivated if the owner configuration or FMC hash change.
Note: “certificate deactivation” is not the same as certificate revocation or expiration. A certificate that was deactivated by virtue of an identity key derivation input changing will become re-activated if that input reverts to its prior value. PKI owners wishing to permanently revoke an identity certificate must therefore use a separate mechansim, such as a CRL.
Each PKI owner may have their own desired implicit attestation properties, and can select their PKI anchor point accordingly.
Support for multiple PKI owners
A device may have multiple simultaneous PKI owners, and serve attestations to multiple verifiers, each with their own configured PKI root key.
While each identity certificate issued by a given PKI owner could be distributed to the relevant attestation verifiers through a number of means, the most tractable method in many cases is for the device to cache each of its PKI owner’s identity certificates locally, and serve a selected identity certificate along with each attestation statement. Each attestation requester must be able to request a PKI anchor point on a per-attestation-request basis.
Note: there may be intermediate certificates between a given PKI owner’s root key and the identity certificate issued for a device. This specification does not impose an upper-limit on the number of intermediate certificates that may exist for a given PKI owner. Devices typically have limited internal storage capacity. As a result, this specification does not require that the device’s attestation responses include any intermediate certificates beyond the identity certificate issued by a PKI owner. These intermediate certificates should be communicated to the verifier out-of-band. Such communication is outside the scope of this specification.
Specification scope
This specification describes the following aspects of device identity endorsement and provisioning:
- Discovering the set of identity keypairs supported by a device, along with each keypair’s respective derivation inputs.
- Establishing trust in a selected identity keypair from the device.
- Issuing and provisioning an identity certificate to the device.
- Requesting a given identity certificate when obtaining an attestation statement from the device.
The following items are out of scope:
- Certificate revocation
- General attestation verification
Discovering device identity keypairs
A device may expose multiple identity keypairs (e.g., IDevID, LDevID, and other vendor- or owner-defined keys), each with its own derivation inputs. Before a PKI owner can select a suitable PKI anchor point, it must discover which keypairs the device supports and which derivation attributes are associated with each.
This specification reuses the GET_ATTESTED_CSR command
defined in Section 1.4
for keypair discovery, by reserving KeyPairID = 0 as a
discovery sentinel. SPDM reserves the value 0 for the
KeyPairID field; value 0 is not a valid KeyPairID, so it is
safe to repurpose here without colliding with any valid keypair
identifier.
Discovery request
To discover the set of supported identity keypairs, the Requester
sends a GET_ATTESTED_CSR request with the following field
values:
Param1(KeyPairID) SHALL be0, indicating a discovery request rather than a CSR request.Param2(Request Attributes),RequesterInfoLength,OpaqueDataLength,RequesterInfo, andOpaqueDataSHALL be0/ empty. The Responder SHALL ignore any non-zero values in these fields whenKeyPairIDis0.SignerSlotIDParamSHALL be interpreted identically to the CSR case. Bits [3:0] select the SPDM slot whose Attestation Key signs the CWT. The discovery response SHALL be attested so that the inventory is attestable.NonceSHOULD be a fresh random value chosen by the Requester, and is used to bind the discovery response to this request.
Discovery response
When KeyPairID = 0 is specified in the request, the
Responder SHALL return an ATTESTED_CSR response whose
AttestedCSRdata is an EAT encoded as a CWT, with the
following requirements:
- The EAT SHALL include a nonce claim whose value matches the
Nonceprovided in the discovery request. - The EAT SHALL NOT include the CSR claim or the derivation-attribute claim defined in Section 1.4. Instead, it SHALL include a single private claim, the KeyPair Inventory claim, containing the device’s keypair inventory.
- The CWT SHALL be signed by the Attestation Key corresponding to the
specified slot, following the same
kidand signing rules as in Section 1.4.
The KeyPair Inventory claim SHALL be a CBOR array. Each element SHALL be a CBOR array of two elements:
- The
KeyPairIDas a CBOR unsigned integer in the range1..255. KeyPairID values are the same as those defined in SPDM. - A map describing the derivation attributes of that keypair, keyed by OID, as defined in Section 1.4.1.
The inventory SHALL include every KeyPairID. The CDDL
definition of the KeyPair Inventory claim
(cwt-attested-csr-eat-inventory) is provided in Section 2.2.
After consuming the inventory, the Requester can issue a follow-up
GET_ATTESTED_CSR request with a specific
KeyPairID to retrieve a CSR for the selected keypair, as
described in Section 1.4.
Establishing trust in a selected identity keypair
To allow a remote party to establish trust in a selected keypair, the device can emit a Certification Signing Request (CSR) [2]. This is supported in SPDM 1.3 [3] via the GET_CSR command. However, there is a drawback to GET_CSR as it is currently defined: the CSR is signed only by the subject key, and does not include a way to attest that the CSR was emitted from a given device.
To allow a device to attest that a given key is trustworthy, the device should issue its own signature over the public key, which can include a freshness nonce and additional metadata, such as the key’s derivation attribute OIDs.
The CSR is included as a claim in an Entity Attestation Token (EAT) [4].
Metadata such as the key’s derivation attribute OIDs can also be embedded in a CoRIM. The mechanism for this is out of scope of this specification.
Some devices may not support the generation of self-signed CSRs for certain keys in their identity key hierarchy, such as LDevID. To support such devices, this specification defines a “non-self-signed CSR”, which includes the subject public key but an all-zeroes signature field. The non-self-signed CSR is still itself signed, by way of the EAT.
This specification provides a definition for a vendor-defined SPDM command, utilizing VENDOR_DEFINED_REQUEST of SPDM 1.3 and later, which can be used to surface these attested CSRs.
Note: the GET_ATTESTED_CSR request format described in
this section (including the VENDOR_DEFINED_REQUEST framing
and Tables 1 / 2) is provided as a reference only and is
non-normative. This specification is normative on the
contents and encoding of the response payload (the attested CSR EAT/CWT
defined in this section), but does not mandate a particular transport or
command format for the request. Implementations are free to surface the
attested CSR via any suitable mechanism. Open-source implementations
such as Caliptra [1] may define and
carry their own implementation of the GET_ATTESTED_CSR
command for interoperability convenience.
GET_ATTESTED_CSR request and ATTESTED_CSR response messages are transported as follows:
- The Requester must use the SPDM VENDOR_DEFINED_REQUEST format
- The Responder must use the SPDM VENDOR_DEFINED_RESPONSE format
- The StandardID field of VENDOR_DEFINED_REQUEST and VENDOR_DEFINED_RESPONSE message must contain 4 (the value assigned in SPDM to identify IANA).
- The VendorID field of VENDOR_DEFINED_REQUEST and VENDOR_DEFINED_RESPONSE message must contain 42623 (the value assigned in IANA to identify Open Compute Project).
- The first byte of the VendorDefinedReqPayload/VendorDefinedRespPayload is the Command Code, and must contain the value 01h to indicate GET_ATTESTED_CSR / ATTESTED_CSR.
- The GET_ATTESTED_CSR request and ATTESTED_CSR response forms the payload in the VendorDefinedReqPayload and VendorDefinedRespPayload respectively, defined in Tables 1 and 2.
| Byte offset | Field | Size (bytes) | Description |
|---|---|---|---|
| 0 | CommandVersion | 1 | The version of this request structure. Shall be zero. |
| 1 | CommandCode | 1 | Shall be 01h to indicate GET_ATTESTED_CSR. |
| 2 | Reserved | 4 | Reserved. |
| 6 | Param1 | 1 | KeyPairID. The value of this field shall be the keypair ID identifying the desired asymmetric key pair for which the CSR should be issued. |
| 7 | Param2 | 1 | Request Attributes. Shall adhere to Table 91 of SPDM 1.3. |
| 8 | RequesterInfoLength | 2 | Shall be the length of the RequesterInfo field in bytes provided by the Requester. This field can be 0. |
| 10 | OpaqueDataLength | 2 | Shall be the length of the OpaqueData field in bytes provided by the Requester. The value should not be greater than 1024 bytes. Shall be 0 if no OpaqueData is provided. |
| 12 | SignerSlotIDParam | 1 |
|
| 13 | Nonce | 32 | The Requester should choose a random value. |
| 45 | RequesterInfo | RequesterInfoLength | Shall be the optional information provided by the Requester. This field shall be DER-encoded. |
| 45 + RequesterInfoLength | OpaqueData | OpaqueDataLength | The Requester can include vendor-specific information for the Responder to generate the CSR. This field is optional. If present, this field shall conform to the selected opaque data format in OtherParamsSelection from Table 21 of SPDM 1.3. |
The following fields should be treated identically as in GET_CSR from SPDM 1.3:
- Param1
- Param2
- RequesterInfoLength
- OpaqueDataLength
- RequesterInfo
- OpaqueData
The following fields present in this command are not present in GET_CSR:
- SignerSlotIDParam - defines which Attestation Key signs the attested CSR.
- Nonce - provides freshness.
| Byte offset | Field | Size (bytes) | Description |
|---|---|---|---|
| 0 | CommandVersion | 1 | The version of this request structure. Shall be zero. |
| 1 | CommandCode | 1 | Shall be 01h to indicate ATTESTED_CSR. |
| 2 | Reserved | 4 | Reserved. |
| 6 | AttestedCSRLength | 2 | Shall be the length of the AttestedCSRdata in bytes. |
| 8 | AttestedCSRdata | AttestedCSRLength | Shall be the requested contents of the attested CSR. This field shall be CBOR-encoded. |
The AttestedCSRdata shall adhere to the following requirements:
- The payload SHALL be an EAT encoded as a CBOR Web Token (CWT) [5].
- The EAT SHALL include a nonce claim for freshness verification.
- The EAT SHALL include private claims1
containing:
- The CSR as a byte string
- A map describing the key’s derivation attributes, keyed by OID (see Section 1.4.1)
- The CSR included in the EAT SHALL be DER-encoded and may be either self-signed or non-self-signed depending on device capabilities. For non-self-signed CSRs, the signature field SHALL contain all zeroes and be the same size as would be required for a valid signature using the subject key’s algorithm.
- The nonce claim SHALL match the nonce value provided in the GET_ATTESTED_CSR request to ensure freshness.
- The CWT SHALL be signed by an Attestation Key endorsed by the
certificate chain corresponding to the specified SlotID. The Requester
obtains the Attestation Key’s certificate chain out-of-band via the SPDM
GET_CERTIFICATEcommand for that slot. - The
kidparameter (COSE header label4) in the CWT’s protected header SHALL be the SHA-384 digest of the Attestation Key’s certificate chain, computed in the same manner as the SPDM DIGEST response for the selected slot. The Requester uses this digest to confirm that the signing key matches the Attestation Key whose certificate chain it retrieved from the selected SPDM slot.
Defined OIDs
OCP Security Branch:
ocp-security OBJECT IDENTIFIER ::= {1 3 6 1 4 1 42623 1}
OCP Key Derivation Attributes OID:
ocp-security-dip-kda OBJECT IDENTIFIER ::= {ocp-security 2}
(1.3.6.1.4.1.42623.1.2)
A keypair’s derivation attributes are expressed as a CBOR map from an OID to a bitfield. This keeps the encoding compact while preserving a mandatory, interoperable baseline and allowing vendor-specific extension:
- The OCP derivation-attributes OID
(
ocp-security-dip-kda) SHALL be present and maps to the OCP derivation-component bitfield defined below. This single OID and bitfield provide a common, high-level set of derivation components that all PKI owners can interpret. - A device MAY include additional vendor-defined OIDs, each mapping to a vendor-specific bitfield, to describe derivation components not covered by the OCP bitfield. PKI owners that do not recognize a vendor OID SHALL ignore its bitfield.
The OCP bitfield is a CBOR unsigned integer. A set bit indicates that the corresponding component contributed to the derivation of the identity key:
- Bit 0 — UDS: The device’s Unique Device Secret.
- Bit 1 — FIELD_ENTROPY: Field-programmable entropy (e.g., field entropy fuses).
- Bit 2 — OWNER_PROVISIONED_NON_CONFIDENTIAL_FUSE: Owner-provisioned, non-confidential fuse values.
- Bit 3 — VENDOR_PROVISIONED_NON_CONFIDENTIAL_FUSE: Vendor-provisioned, non-confidential fuse values.
- Bit 4 — FIRST_MUTABLE_CODE: The first mutable code layer (FMC).
- Bit 5 — RUNTIME_FIRMWARE: The runtime firmware layer.
The bitfield for a given key is a complete enumeration of all derivation components that contributed to that keypair. In typical DICE implementations, a given key’s bitfield will be the union (bitwise OR) of the components introduced at its own derivation step and the bitfields of all of its ancestors. For such implementations, a descendant key’s bitfield can never clear a bit that is set in an ancestor key’s bitfield.
For example, consider an identity hierarchy in which the IDevID key is derived from the UDS, and the LDevID key is derived from the IDevID key plus field entropy. The cumulative bitfields are then:
| Key | Derivation components introduced at this step | Bits set (inclusive of ancestors) | Bitfield value |
|---|---|---|---|
| IDevID | UDS | UDS (bit 0) | 0b000001 (0x01) |
| LDevID | FIELD_ENTROPY | UDS (bit 0), FIELD_ENTROPY (bit 1) | 0b000011 (0x03) |
The LDevID bitfield explicitly sets both the UDS bit inherited from the IDevID key and the FIELD_ENTROPY bit introduced at its own derivation step.
The CDDL definition of the derivation-attribute map
(key-attributes-map) is provided in Section 2.2.
Subsequent versions of this specification may define additional bits in the OCP bitfield, or additional OIDs.
Issuing and provisioning an identity certificate
This will be accomplished via the SET_CERTIFICATE SPDM
command.
TODO: fill in additional details.
Requesting an identity certificate during attestation
This will be accomplished by selecting the correct
SlotIDParam when invoking SPDM commands.
TODO: fill in additional details.
Confidential compute considerations
TODO: fill in
Appendix
Clarification of DICE Terminology
In this specification, several example device identity key hierarchies use the term “FMC”. In this context, FMC stands for “First Mutable Code”.
In TCG’s DICE Hardware Requirements [6], FMC is defined as “First Measured Code”, and is “the code and/or configuration information that is executed and/or takes effect immediately following the Device Identifier Composition Engine”. First Measured Code is synonymous with Layer 0 in the DICE Layering Architecture [7].
The difference between First Measured Code and First Mutable Code is subtle but important. In Caliptra, the First Measured Code corresponds with the Caliptra ROM layer. As such, Caliptra’s Device ID or IDevID keypair is wielded by ROM, rather than Caliptra’s FMC.
Attested CSR EAT CDDL
; An Attested CSR EAT is one of two variants:
; - A CSR response, returned for a specific KeyPairID > 0.
; - A keypair-inventory (discovery) response, returned when the
; Requester specifies KeyPairID = 0.
cwt-attested-csr-eat =
cwt-attested-csr-eat-csr /
cwt-attested-csr-eat-inventory
cwt-attested-csr-eat-csr = {
; Nonce claim is nonce-type = bstr .size (8..64)
&(nonce : 10) => bstr
; Private Claims (they have to be < -65536 for rfc8392)
; CSR bytestring
&(csr: -70001) => bstr
; Derivation attributes, expressed as an OID -> bitfield map
&(attrib: -70002) => key-attributes-map
}
; Discovery response payload returned when KeyPairID = 0 in the request.
cwt-attested-csr-eat-inventory = {
; Nonce claim is nonce-type = bstr .size (8..64)
&(nonce : 10) => bstr
; KeyPair Inventory private claim. Each entry pairs a KeyPairID
; with the derivation-attribute bitfield map that applies to it.
&(keypair-inventory: -70003) => [+ keypair-inventory-entry]
}
keypair-inventory-entry = [
keypair-id: 1..255,
attributes: key-attributes-map
]
; Derivation attributes are expressed as a map from an OID to a
; bitfield. The OCP OID (ocp-security-dip-kda) is REQUIRED and maps to
; the OCP derivation-component bitfield. Vendors MAY add additional
; OIDs mapping to vendor-specific bitfields for derivation components
; not covered by the OCP bitfield.
key-attributes-map = {
ocp-security-dip-kda => ocp-derivation-bitfield
* tagged-oid-type => uint
}
; Tagged OID per RFC 9090.
tagged-oid-type = #6.111(bstr)
; OID 1.3.6.1.4.1.42623.1.2 (ocp-security-dip-kda).
ocp-security-dip-kda = #6.111(h'2B0601040182CC7F0102')
; OCP derivation-component bitfield. A set bit indicates that the
; corresponding component contributed to the keypair's derivation.
ocp-derivation-bitfield = uint .bits ocp-derivation-components
ocp-derivation-components = &(
UDS: 0,
FIELD_ENTROPY: 1,
OWNER_PROVISIONED_NON_CONFIDENTIAL_FUSE: 2,
VENDOR_PROVISIONED_NON_CONFIDENTIAL_FUSE: 3,
FIRST_MUTABLE_CODE: 4,
RUNTIME_FIRMWARE: 5,
)
signed-cwt = #6.18(COSE-Sign1-attested-csr)
COSE-Sign1-attested-csr = [
protected: bstr .cbor protected-header-map
unprotected: {}
payload: bstr .cbor cwt-attested-csr-eat
signature: bstr
]
protected-header-map = {
&(alg-id: 1) => int
&(content-type: 3) => tstr / int
&(issuer-key-id: 4) => bstr
}
Attested CSR EAT example CDDL diag
; ----------------------------------------------------------------------
; Example: CSR response (returned when the Requester sent
; GET_ATTESTED_CSR with a specific KeyPairID > 0). The payload
; carries the CSR for the selected keypair along with the derivation-
; attribute bitfield map that applies to it.
; ----------------------------------------------------------------------
signed-cwt / 18([
/ protected / <<{
/ alg-id / 1 : 7,
/ content-type / 3 : "application/eat+cbor",
; SHA-384 hash of the Attestation Key's certificate chain (same as
; the SPDM DIGEST response) for the slot that produced this signature.
/ kid / 4 : h'1a2b3c4d5e6f70819203a4b5c6d7e8f900112233445566778899aabbccddeeff00112233445566778899aabbccddeeff'
}>>,
/ unprotected / {},
/ payload / <<{
/ nonce / 10: h'AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999',
/ csr / -70001 : h'59025630820252308201d9a003020102021431a4e0',
; Derivation attributes as an OID -> bitfield map. The single OCP
; OID (1.3.6.1.4.1.42623.1.2) maps to the OCP bitfield. This CSR is
; for the LDevID keypair (KeyPairID 2 in the discovery example):
; UDS(bit 0) | FIELD_ENTROPY(bit 1) = 3
/ attrib / -70002: {
111(h'2B0601040182CC7F0102') : 3
}
}>>,
/ signature / h'FA45AAB345AB4988'
])
; ----------------------------------------------------------------------
; Example: discovery response (returned when the Requester sent
; GET_ATTESTED_CSR with KeyPairID = 0). The payload omits the
; CSR/attrib claims and instead carries the KeyPair Inventory claim,
; which enumerates every supported KeyPairID and its derivation-
; attribute bitfield map.
; ----------------------------------------------------------------------
signed-cwt / 18([
/ protected / <<{
/ alg-id / 1 : 7,
/ content-type / 3 : "application/eat+cbor",
; SHA-384 hash of the Attestation Key's certificate chain (same as
; the SPDM DIGEST response) for the slot that produced this signature.
/ kid / 4 : h'1a2b3c4d5e6f70819203a4b5c6d7e8f900112233445566778899aabbccddeeff00112233445566778899aabbccddeeff'
}>>,
/ unprotected / {},
/ payload / <<{
/ nonce / 10 : h'AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999',
/ keypair-inventory / -70003 : [
; Each entry: [ KeyPairID, { OCP OID : bitfield } ].
; The single OCP OID is 1.3.6.1.4.1.42623.1.2.
; In a typical DICE implementation, bitfields are cumulative: each key's
; bitfield includes the derivation components inherited from its ancestor keys.
; KeyPairID 1: IDevID, derived from UDS.
; UDS(bit 0) = 1
[ 1, {
111(h'2B0601040182CC7F0102') : 1
} ],
; KeyPairID 2: LDevID, derived from IDevID + Field Entropy.
; UDS(bit 0) | FIELD_ENTROPY(bit 1) = 3
[ 2, {
111(h'2B0601040182CC7F0102') : 3
} ],
; KeyPairID 3: derived from Owner-provisioned alias key + Field Entropy + UDS.
; UDS(bit 0) | FIELD_ENTROPY(bit 1) |
; OWNER_PROVISIONED_NON_CONFIDENTIAL_FUSE(bit 2) = 7
[ 3, {
111(h'2B0601040182CC7F0102') : 7
} ]
]
}>>,
/ signature / h'FA45AAB345AB4988'
])