From c7fc40c1e84d250a38421e9b84531e05c2cbb223 Mon Sep 17 00:00:00 2001 From: Fabrizio Damato Date: Tue, 30 Sep 2025 17:07:16 -0700 Subject: [PATCH 1/3] Device Identity Provisioning: Expanding the Spec with Provisioning Flow Signed-off-by: Fabrizio Damato --- .../device-identity-provisioning/spec.ocp | 343 +++++++++++++++++- 1 file changed, 341 insertions(+), 2 deletions(-) diff --git a/specifications/device-identity-provisioning/spec.ocp b/specifications/device-identity-provisioning/spec.ocp index d38455d..b00b4d2 100644 --- a/specifications/device-identity-provisioning/spec.ocp +++ b/specifications/device-identity-provisioning/spec.ocp @@ -330,11 +330,350 @@ The following OIDs are defined for key derivation attributes: These OIDs indicate which inputs contribute to the derivation of the identity key for which the CSR is being requested. -Subsequent versions of this specification may be expanded with additional key derivation attribute OIDs. +**Key Provisioning Entity OID Branch**: `ocp-security-dip-kpe OBJECT IDENTIFIER ::= {ocp-security 4}` + +The following OIDs are defined for key provisioning entities: + +- **Vendor Provisioning Entity**: `ocp-security-dip-kpe-vendor ::= {ocp-security-dip-kpe 1}` + - Used to identify vendor-provisioned endorsements (typically pre-installed in slot 0) + +- **Platform Owner Provisioning Entity**: `ocp-security-dip-kpe-owner ::= {ocp-security-dip-kpe 2}` + - Used to identify platform owner-provisioned endorsements + +- **Tenant Provisioning Entity**: `ocp-security-dip-kpe-tenant ::= {ocp-security-dip-kpe 3}` + - Used to identify tenant-provisioned endorsements in bare metal scenarios + +These OIDs are returned by the `OCP_GET_SLOT_ID_MAPPING` command to indicate which entity's endorsement is associated with each slot. + +Subsequent versions of this specification may be expanded with additional key derivation attribute OIDs and provisioning entity OIDs. ## Issuing and provisioning an identity certificate {#sec:issuing-and-provisioning-identity-cert} -This will be accomplished via the `SET_CERTIFICATE` SPDM command. +After establishing trust in a device's identity keypair through the envelope-signed CSR mechanism, a PKI owner can issue and provision an identity certificate to the device. This specification defines a standardized approach using OCP-specific extensions transported via SPDM's VENDOR_DEFINED_REQUEST mechanism. + +### Certificate provisioning overview + +Identity certificates are provisioned to devices using the OCP-specific `OCP_SET_ENDORSEMENT` command. The PKI owner provisions their endorsement chain (excluding the LEAF certificate) to a specific slot on the device. + +**Important**: This specification mandates that LEAF certificates (the identity certificates themselves) are NOT included in the provisioned certificate chains. The separation between endorsement chains and LEAF certificates ensures: + +- Multiple use cases (attestation, secure sessions) can use different LEAF certificates while sharing the same endorsement point +- The endorsement chain remains stable even as LEAF certificates may change based on key derivation inputs + +### Slot allocation and management + +Devices implementing this specification SHALL support certificate slot allocation with the following requirements: + +- **Minimum requirement**: Devices MUST reserve at least 2 slots for OCP provisioning (one for platform owner, one for tenant) +- **Vendor flexibility**: The specific slot numbers are determined by the device vendor and discovered via `OCP_GET_SLOT_ID_MAPPING` +- **Total slots**: SPDM supports up to 8 slots (0-7), with the allocation between vendor and OCP use defined by the vendor + +Example allocation (vendor-specific): +- Slot 0: Vendor endorsement (pre-provisioned) +- Slot 2: Platform owner endorsement +- Slot 4: Tenant endorsement +- Other slots: Available for additional use cases or vendor-specific purposes + +**Important**: The actual slot mapping is vendor-defined and discovered at runtime. The device SHALL return an error if attempts are made to provision more slots than physically supported + +### OCP extensions for certificate management + +To address the needs of heterogeneous environments where devices may support both SPDM and non-SPDM attestation paths, this specification defines OCP-specific commands transported via SPDM's VENDOR_DEFINED_REQUEST mechanism. + +#### OCP_GET_SLOT_ID_MAPPING command + +GET_SLOT_ID_MAPPING request and SLOT_ID_MAPPING 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 03h to indicate GET_SLOT_ID_MAPPING / SLOT_ID_MAPPING. +- The GET_SLOT_ID_MAPPING request and SLOT_ID_MAPPING response forms the payload in the VendorDefinedReqPayload and VendorDefinedRespPayload respectively, defined in Tables [-@tbl:slot-mapping-req] and [-@tbl:slot-mapping-resp]. + +Table: GET_SLOT_ID_MAPPING VendorDefinedReqPayload {#tbl:slot-mapping-req} + ++---------------------+---------------------+---------------------+----------------------------------------------+ +| Byte offset | Field | Size (bytes) | Description | ++=====================+=====================+=====================+==============================================+ +| 0 | CommandVersion | 1 | The version of this request structure. | +| | | | Shall be zero. | ++---------------------+---------------------+---------------------+----------------------------------------------+ +| 1 | CommandCode | 1 | Shall be 03h to indicate | +| | | | GET_SLOT_ID_MAPPING. | ++---------------------+---------------------+---------------------+----------------------------------------------+ +| 2 | Reserved | 4 | Reserved. | ++---------------------+---------------------+---------------------+----------------------------------------------+ + +Table: SLOT_ID_MAPPING VendorDefinedRespPayload {#tbl:slot-mapping-resp} + ++--------+-------------------------+-------------------------+------------------------------------------+ +| Byte | Field | Size (bytes) | Description | +| offset | | | | ++========+=========================+=========================+==========================================+ +| 0 | CommandVersion | 1 | The version of this response structure. | +| | | | Shall be zero. | ++--------+-------------------------+-------------------------+------------------------------------------+ +| 1 | CommandCode | 1 | Shall be 03h to indicate | +| | | | SLOT_ID_MAPPING. | ++--------+-------------------------+-------------------------+------------------------------------------+ +| 2 | Reserved | 4 | Reserved. | ++--------+-------------------------+-------------------------+------------------------------------------+ +| 6 | MappingCount | 1 | Number of slot mappings returned. | +| | | | Shall not exceed 8. | ++--------+-------------------------+-------------------------+------------------------------------------+ +| 7 | Reserved | 1 | Reserved. | ++--------+-------------------------+-------------------------+------------------------------------------+ +| 8 | MappingTable | MappingCount * 16 | Array of slot mappings. Each entry | +| | | | consists of: | +| | | | - SlotID (1 byte) | +| | | | - Reserved (3 bytes) | +| | | | - OID Length (2 bytes) | +| | | | - Reserved (2 bytes) | +| | | | - OID (8 bytes, zero-padded) | ++--------+-------------------------+-------------------------+------------------------------------------+ + +#### OCP_SET_ENDORSEMENT command + +SET_ENDORSEMENT request and SET_ENDORSEMENT 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 04h to indicate SET_ENDORSEMENT. +- The SET_ENDORSEMENT request and SET_ENDORSEMENT response forms the payload in the VendorDefinedReqPayload and VendorDefinedRespPayload respectively, defined in Tables [-@tbl:set-endorsement-req] and [-@tbl:set-endorsement-resp]. + +Table: SET_ENDORSEMENT VendorDefinedReqPayload {#tbl:set-endorsement-req} + ++---------------------+---------------------+---------------------+----------------------------------------------+ +| Byte offset | Field | Size (bytes) | Description | ++=====================+=====================+=====================+==============================================+ +| 0 | CommandVersion | 1 | The version of this request structure. | +| | | | Shall be zero. | ++---------------------+---------------------+---------------------+----------------------------------------------+ +| 1 | CommandCode | 1 | Shall be 04h to indicate | +| | | | SET_ENDORSEMENT. | ++---------------------+---------------------+---------------------+----------------------------------------------+ +| 2 | Reserved | 4 | Reserved. | ++---------------------+---------------------+---------------------+----------------------------------------------+ +| 6 | SlotID | 1 | Target slot for the endorsement chain. | +| | | | Shall be a valid slot as indicated by | +| | | | GET_SLOT_ID_MAPPING. | ++---------------------+---------------------+---------------------+----------------------------------------------+ +| 7 | Flags | 1 | - Bit [7:1]: Reserved. | +| | | | - Bit [0]: FORCE flag. | +| | | | If set to 1, allows overwriting an | +| | | | existing endorsement in the slot. | +| | | | If set to 0, returns error if slot | +| | | | is already occupied. | ++---------------------+---------------------+---------------------+----------------------------------------------+ +| 8 | KeyID | 1 | Key identifier for certificate selection. | +| | | | Usage is vendor-specific. | ++---------------------+---------------------+---------------------+----------------------------------------------+ +| 9 | Reserved | 1 | Reserved. | ++---------------------+---------------------+---------------------+----------------------------------------------+ +| 10 | CertChainLength | 2 | Length of the certificate chain in bytes. | +| | | | Shall not exceed device capabilities. | ++---------------------+---------------------+---------------------+----------------------------------------------+ +| 12 | CertChain | CertChainLength | DER-encoded certificate chain. | +| | | | Shall NOT include LEAF certificate. | ++---------------------+---------------------+---------------------+----------------------------------------------+ + +Table: SET_ENDORSEMENT VendorDefinedRespPayload {#tbl:set-endorsement-resp} + ++--------+-------------------------+-------------------------+------------------------------------------+ +| Byte | Field | Size (bytes) | Description | +| offset | | | | ++========+=========================+=========================+==========================================+ +| 0 | CommandVersion | 1 | The version of this response structure. | +| | | | Shall be zero. | ++--------+-------------------------+-------------------------+------------------------------------------+ +| 1 | CommandCode | 1 | Shall be 04h to indicate | +| | | | SET_ENDORSEMENT. | ++--------+-------------------------+-------------------------+------------------------------------------+ +| 2 | Reserved | 4 | Reserved. | ++--------+-------------------------+-------------------------+------------------------------------------+ +| 6 | Status | 1 | Status code: | +| | | | - 00h: Success | +| | | | - 01h: Slot occupied | +| | | | - 02h: Invalid slot | +| | | | - 03h: Invalid chain | +| | | | - 04h: Chain too long | +| | | | - 05h: Insufficient resources | +| | | | - FFh: General failure | ++--------+-------------------------+-------------------------+------------------------------------------+ +| 7 | Reserved | 1 | Reserved. | ++--------+-------------------------+-------------------------+------------------------------------------+ + + +#### OCP_GET_ENDORSEMENT command + +GET_ENDORSEMENT request and GET_ENDORSEMENT 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 04h to indicate GET_ENDORSEMENT. +- The GET_ENDORSEMENT request and GET_ENDORSEMENT response forms the payload in the VendorDefinedReqPayload and VendorDefinedRespPayload respectively, defined in Tables [-@tbl:get-endorsement-req] and [-@tbl:get-endorsement-resp]. + +Table: GET_ENDORSEMENT VendorDefinedReqPayload {#tbl:get-endorsement-req} + ++---------------------+---------------------+---------------------+----------------------------------------------+ +| Byte offset | Field | Size (bytes) | Description | ++=====================+=====================+=====================+==============================================+ +| 0 | CommandVersion | 1 | The version of this request structure. | +| | | | Shall be zero. | ++---------------------+---------------------+---------------------+----------------------------------------------+ +| 1 | CommandCode | 1 | Shall be 04h to indicate | +| | | | GET_ENDORSEMENT. | ++---------------------+---------------------+---------------------+----------------------------------------------+ +| 2 | Reserved | 4 | Reserved. | ++---------------------+---------------------+---------------------+----------------------------------------------+ +| 6 | SlotID | 1 | Slot from which to retrieve the | +| | | | endorsement chain. | ++---------------------+---------------------+---------------------+----------------------------------------------+ +| 7 | Reserved | 1 | Reserved. | ++---------------------+---------------------+---------------------+----------------------------------------------+ + +Table: GET_ENDORSEMENT VendorDefinedRespPayload {#tbl:get-endorsement-resp} + ++--------+-------------------------+-------------------------+------------------------------------------+ +| Byte | Field | Size (bytes) | Description | +| offset | | | | ++========+=========================+=========================+==========================================+ +| 0 | CommandVersion | 1 | The version of this response structure. | +| | | | Shall be zero. | ++--------+-------------------------+-------------------------+------------------------------------------+ +| 1 | CommandCode | 1 | Shall be 04h to indicate | +| | | | GET_ENDORSEMENT. | ++--------+-------------------------+-------------------------+------------------------------------------+ +| 2 | Reserved | 4 | Reserved. | ++--------+-------------------------+-------------------------+------------------------------------------+ +| 6 | Status | 1 | Status code: | +| | | | - 00h: Success | +| | | | - 02h: Invalid slot | +| | | | - 06h: Slot not provisioned | +| | | | - FFh: General failure | ++--------+-------------------------+-------------------------+------------------------------------------+ +| 7 | Reserved | 1 | Reserved. | ++--------+-------------------------+-------------------------+------------------------------------------+ +| 8 | CertChainLength | 2 | Length of the certificate chain. | +| | | | Zero if status is not success. | ++--------+-------------------------+-------------------------+------------------------------------------+ +| 10 | CertChain | CertChainLength | DER-encoded certificate chain. | +| | | | Does NOT include LEAF certificate. | +| | | | Present only if status is success. | ++--------+-------------------------+-------------------------+------------------------------------------+ + +### Provisioning workflow + +A typical provisioning workflow follows these steps: + +1. **Discovery**: The PKI owner queries `OCP_GET_SLOT_ID_MAPPING` to understand the device's slot allocation +2. **CSR Generation**: The PKI owner requests an envelope-signed CSR for their chosen identity key using `GET_ENVELOPE_SIGNED_CSR` +3. **Certificate Issuance**: The PKI owner validates the CSR and issues an identity certificate +4. **Chain Provisioning**: The PKI owner provisions their endorsement chain (excluding the newly issued LEAF certificate) using `OCP_SET_ENDORSEMENT` +5. **Verification**: The PKI owner can verify successful provisioning by retrieving the chain using `OCP_GET_ENDORSEMENT` + +### Compatibility considerations + +For devices that support both SPDM and OCP attestation paths: + +- The same SlotID namespace is shared between SPDM and OCP commands +- `OCP_SET_ENDORSEMENT` provisions to the same underlying storage accessed by SPDM +- `GET_CERTIFICATE` (SPDM) returns the endorsement chain plus any associated LEAF certificate +- `OCP_GET_ENDORSEMENT` returns only the endorsement chain + +This unified approach ensures consistent certificate management regardless of the attestation path used. + +### Certificate chain validation + +When provisioning certificate chains, devices SHALL validate: + +- The certificate chain is properly formed and each certificate correctly signs the next +- The chain terminates at a self-signed root or a certificate that can be verified against pre-existing trust anchors +- All certificates in the chain are within their validity periods +- The certificate chain length does not exceed device storage capabilities + +### Error handling + +The following error conditions SHALL be reported: + +- **SLOT_OCCUPIED**: Attempting to provision a slot that already contains a certificate chain when FORCE flag is not set +- **INVALID_SLOT**: Specified slot ID is outside the valid range +- **CHAIN_TOO_LONG**: Certificate chain exceeds device storage capacity +- **INVALID_CHAIN**: Certificate chain validation failed +- **INSUFFICIENT_RESOURCES**: Device lacks resources to complete the operation + +### Security considerations + +#### Protection of provisioning operations + +Certificate provisioning operations SHOULD be performed over authenticated and encrypted channels: + +- For SPDM paths: Use SPDM secured messages when available +- For out-of-band provisioning: Use platform-specific secure channels + +#### Slot update policy + +To prevent unauthorized certificate replacement: + +- Devices MAY implement policies restricting certificate updates based on: + - Physical presence assertions + - Platform ownership state + - Secure boot state +- Once provisioned, slots SHALL NOT be overwritable without the FORCE flag being explicitly set +- When FORCE flag is used to overwrite an existing endorsement, devices SHOULD log this as a security-relevant event + +#### Certificate lifecycle management + +PKI owners are responsible for: + +- Tracking certificate expiration dates +- Implementing certificate renewal procedures before expiration +- Maintaining certificate revocation lists (CRLs) for compromised certificates +- Ensuring time synchronization for certificate validity checking + +### Implementation notes + +#### Storage optimization + +Given the limited storage available on many devices: + +- Redundant certificates (e.g., those appearing in multiple chains) MAY be stored once and referenced multiple times + +#### Backwards compatibility + +For devices that only support SPDM without OCP extensions: + +- Standard SPDM `SET_CERTIFICATE` commands remain fully functional + +### Example provisioning sequence + +Here's a complete example of a platform owner provisioning their endorsement chain: + +1. **BMC → Device**: `OCP_GET_SLOT_ID_MAPPING()` + + **Device → BMC**: `{0: OID_VENDOR, 2: OID_OWNER, 4: OID_TENANT}` + +2. **BMC → Device**: `GET_ENVELOPE_SIGNED_CSR(KeyPairID=LDevID, SlotID=0, Nonce)` + + **Device → BMC**: `EAT{CSR for LDevID}` + +3. **BMC validates CSR and issues certificate for LDevID** + +4. **BMC → Device**: `OCP_SET_ENDORSEMENT(SlotID=2, KeyID, OwnerEndorsementChain)` + + **Device → BMC**: `SUCCESS` + +5. **TENANT → Device**: `OCP_GET_ENDORSEMENT(SlotID=2)` + + **Device → TENANT**: `OwnerEndorsementChain` (confirming successful provisioning) + +After this sequence, attestations from the device can reference the owner's endorsement chain. + TODO: fill in additional details. From e2485432e1843d2dbfeca877ad4fe1412160daa6 Mon Sep 17 00:00:00 2001 From: Fabrizio Damato Date: Tue, 30 Sep 2025 19:43:51 -0700 Subject: [PATCH 2/3] Device Identity Provisioning: Replace OIDs for Key Provisioning Entity to Enum type Signed-off-by: Fabrizio Damato --- .../device-identity-provisioning/spec.ocp | 164 ++++++++++-------- 1 file changed, 93 insertions(+), 71 deletions(-) diff --git a/specifications/device-identity-provisioning/spec.ocp b/specifications/device-identity-provisioning/spec.ocp index b00b4d2..bdea19f 100644 --- a/specifications/device-identity-provisioning/spec.ocp +++ b/specifications/device-identity-provisioning/spec.ocp @@ -330,22 +330,7 @@ The following OIDs are defined for key derivation attributes: These OIDs indicate which inputs contribute to the derivation of the identity key for which the CSR is being requested. -**Key Provisioning Entity OID Branch**: `ocp-security-dip-kpe OBJECT IDENTIFIER ::= {ocp-security 4}` - -The following OIDs are defined for key provisioning entities: - -- **Vendor Provisioning Entity**: `ocp-security-dip-kpe-vendor ::= {ocp-security-dip-kpe 1}` - - Used to identify vendor-provisioned endorsements (typically pre-installed in slot 0) - -- **Platform Owner Provisioning Entity**: `ocp-security-dip-kpe-owner ::= {ocp-security-dip-kpe 2}` - - Used to identify platform owner-provisioned endorsements - -- **Tenant Provisioning Entity**: `ocp-security-dip-kpe-tenant ::= {ocp-security-dip-kpe 3}` - - Used to identify tenant-provisioned endorsements in bare metal scenarios - -These OIDs are returned by the `OCP_GET_SLOT_ID_MAPPING` command to indicate which entity's endorsement is associated with each slot. - -Subsequent versions of this specification may be expanded with additional key derivation attribute OIDs and provisioning entity OIDs. +Subsequent versions of this specification may be expanded with additional key derivation attribute OIDs. ## Issuing and provisioning an identity certificate {#sec:issuing-and-provisioning-identity-cert} @@ -380,7 +365,20 @@ Example allocation (vendor-specific): To address the needs of heterogeneous environments where devices may support both SPDM and non-SPDM attestation paths, this specification defines OCP-specific commands transported via SPDM's VENDOR_DEFINED_REQUEST mechanism. -#### OCP_GET_SLOT_ID_MAPPING command +**Transport flexibility**: While this specification defines these commands as SPDM vendor-defined messages, devices that do not support SPDM MAY implement these same commands over alternative transport mechanisms. The definition of transport bindings for non-SPDM attesters is outside the scope of this specification. Regardless of transport, the command and response payload formats defined in this specification SHALL be preserved. + +#### Key Provisioning Entity Enumeration + +The following Key Provisioning Entity values are defined: + +- **VENDOR** (0x00): Vendor-provisioned endorsements (typically pre-installed) +- **OWNER** (0x01): Platform owner-provisioned endorsements +- **TENANT** (0x02): Tenant-provisioned endorsements in bare metal scenarios +Future versions of this specification may define additional entity values. + +#### OCP_GET_SLOT_ID_MAPPING command (Informational) + +This command is provided for informational purposes, primarily for devices that also support SPDM. It allows callers to understand which SPDM slot corresponds to each Key Provisioning Entity. GET_SLOT_ID_MAPPING request and SLOT_ID_MAPPING response messages are transported as follows: @@ -419,20 +417,19 @@ Table: SLOT_ID_MAPPING VendorDefinedRespPayload {#tbl:slot-mapping-resp} +--------+-------------------------+-------------------------+------------------------------------------+ | 2 | Reserved | 4 | Reserved. | +--------+-------------------------+-------------------------+------------------------------------------+ -| 6 | MappingCount | 1 | Number of slot mappings returned. | +| 6 | MappingCount | 1 | Number of mappings returned. | | | | | Shall not exceed 8. | +--------+-------------------------+-------------------------+------------------------------------------+ | 7 | Reserved | 1 | Reserved. | +--------+-------------------------+-------------------------+------------------------------------------+ -| 8 | MappingTable | MappingCount * 16 | Array of slot mappings. Each entry | +| 8 | MappingTable | MappingCount * 2 | Array of mappings. Each entry | | | | | consists of: | +| | | | - KeyProvisioningEntity (1 byte) | | | | | - SlotID (1 byte) | -| | | | - Reserved (3 bytes) | -| | | | - OID Length (2 bytes) | -| | | | - Reserved (2 bytes) | -| | | | - OID (8 bytes, zero-padded) | +--------+-------------------------+-------------------------+------------------------------------------+ +**Note**: The `OCP_GET_SLOT_ID_MAPPING` command is informational only. Devices that support both OCP and SPDM commands use this to report which SPDM slot corresponds to each Key Provisioning Entity. This allows SPDM requesters to understand the side effects of `OCP_SET_ENDORSEMENT` operations. + #### OCP_SET_ENDORSEMENT command SET_ENDORSEMENT request and SET_ENDORSEMENT response messages are transported as follows: @@ -457,16 +454,18 @@ Table: SET_ENDORSEMENT VendorDefinedReqPayload {#tbl:set-endorsement-req} +---------------------+---------------------+---------------------+----------------------------------------------+ | 2 | Reserved | 4 | Reserved. | +---------------------+---------------------+---------------------+----------------------------------------------+ -| 6 | SlotID | 1 | Target slot for the endorsement chain. | -| | | | Shall be a valid slot as indicated by | -| | | | GET_SLOT_ID_MAPPING. | +| 6 | KeyProvisioningEntity| 1 | Entity for which to set endorsement: | +| | | | - 00h: VENDOR | +| | | | - 01h: OWNER | +| | | | - 02h: TENANT | +| | | | Other values reserved. | +---------------------+---------------------+---------------------+----------------------------------------------+ | 7 | Flags | 1 | - Bit [7:1]: Reserved. | | | | | - Bit [0]: FORCE flag. | | | | | If set to 1, allows overwriting an | -| | | | existing endorsement in the slot. | -| | | | If set to 0, returns error if slot | -| | | | is already occupied. | +| | | | existing endorsement. | +| | | | If set to 0, returns error if | +| | | | already provisioned. | +---------------------+---------------------+---------------------+----------------------------------------------+ | 8 | KeyID | 1 | Key identifier for certificate selection. | | | | | Usage is vendor-specific. | @@ -496,8 +495,8 @@ Table: SET_ENDORSEMENT VendorDefinedRespPayload {#tbl:set-endorsement-resp} +--------+-------------------------+-------------------------+------------------------------------------+ | 6 | Status | 1 | Status code: | | | | | - 00h: Success | -| | | | - 01h: Slot occupied | -| | | | - 02h: Invalid slot | +| | | | - 01h: Invalid entity | +| | | | - 02h: Entity already provisioned | | | | | - 03h: Invalid chain | | | | | - 04h: Chain too long | | | | | - 05h: Insufficient resources | @@ -506,7 +505,6 @@ Table: SET_ENDORSEMENT VendorDefinedRespPayload {#tbl:set-endorsement-resp} | 7 | Reserved | 1 | Reserved. | +--------+-------------------------+-------------------------+------------------------------------------+ - #### OCP_GET_ENDORSEMENT command GET_ENDORSEMENT request and GET_ENDORSEMENT response messages are transported as follows: @@ -515,7 +513,7 @@ GET_ENDORSEMENT request and GET_ENDORSEMENT response messages are transported as - 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 04h to indicate GET_ENDORSEMENT. +- The first byte of the VendorDefinedReqPayload/VendorDefinedRespPayload is the Command Code, and must contain the value 05h to indicate GET_ENDORSEMENT. - The GET_ENDORSEMENT request and GET_ENDORSEMENT response forms the payload in the VendorDefinedReqPayload and VendorDefinedRespPayload respectively, defined in Tables [-@tbl:get-endorsement-req] and [-@tbl:get-endorsement-resp]. Table: GET_ENDORSEMENT VendorDefinedReqPayload {#tbl:get-endorsement-req} @@ -526,15 +524,18 @@ Table: GET_ENDORSEMENT VendorDefinedReqPayload {#tbl:get-endorsement-req} | 0 | CommandVersion | 1 | The version of this request structure. | | | | | Shall be zero. | +---------------------+---------------------+---------------------+----------------------------------------------+ -| 1 | CommandCode | 1 | Shall be 04h to indicate | +| 1 | CommandCode | 1 | Shall be 05h to indicate | | | | | GET_ENDORSEMENT. | +---------------------+---------------------+---------------------+----------------------------------------------+ | 2 | Reserved | 4 | Reserved. | +---------------------+---------------------+---------------------+----------------------------------------------+ -| 6 | SlotID | 1 | Slot from which to retrieve the | -| | | | endorsement chain. | +| 6 | KeyProvisioningEntity| 1 | Entity from which to get endorsement: | +| | | | - 00h: VENDOR | +| | | | - 01h: OWNER | +| | | | - 02h: TENANT | +| | | | Other values reserved. | +---------------------+---------------------+---------------------+----------------------------------------------+ -| 7 | Reserved | 1 | Reserved. | +| 7 | Reserved | 1 | Reserved. | +---------------------+---------------------+---------------------+----------------------------------------------+ Table: GET_ENDORSEMENT VendorDefinedRespPayload {#tbl:get-endorsement-resp} @@ -546,15 +547,15 @@ Table: GET_ENDORSEMENT VendorDefinedRespPayload {#tbl:get-endorsement-resp} | 0 | CommandVersion | 1 | The version of this response structure. | | | | | Shall be zero. | +--------+-------------------------+-------------------------+------------------------------------------+ -| 1 | CommandCode | 1 | Shall be 04h to indicate | +| 1 | CommandCode | 1 | Shall be 05h to indicate | | | | | GET_ENDORSEMENT. | +--------+-------------------------+-------------------------+------------------------------------------+ | 2 | Reserved | 4 | Reserved. | +--------+-------------------------+-------------------------+------------------------------------------+ | 6 | Status | 1 | Status code: | | | | | - 00h: Success | -| | | | - 02h: Invalid slot | -| | | | - 06h: Slot not provisioned | +| | | | - 01h: Invalid entity | +| | | | - 02h: Entity not provisioned | | | | | - FFh: General failure | +--------+-------------------------+-------------------------+------------------------------------------+ | 7 | Reserved | 1 | Reserved. | @@ -571,22 +572,25 @@ Table: GET_ENDORSEMENT VendorDefinedRespPayload {#tbl:get-endorsement-resp} A typical provisioning workflow follows these steps: -1. **Discovery**: The PKI owner queries `OCP_GET_SLOT_ID_MAPPING` to understand the device's slot allocation -2. **CSR Generation**: The PKI owner requests an envelope-signed CSR for their chosen identity key using `GET_ENVELOPE_SIGNED_CSR` -3. **Certificate Issuance**: The PKI owner validates the CSR and issues an identity certificate -4. **Chain Provisioning**: The PKI owner provisions their endorsement chain (excluding the newly issued LEAF certificate) using `OCP_SET_ENDORSEMENT` -5. **Verification**: The PKI owner can verify successful provisioning by retrieving the chain using `OCP_GET_ENDORSEMENT` +1. **CSR Generation**: The PKI owner requests an envelope-signed CSR for their chosen identity key using `GET_ENVELOPE_SIGNED_CSR` +2. **Certificate Issuance**: The PKI owner validates the CSR and issues an identity certificate +3. **Chain Provisioning**: The PKI owner provisions their endorsement chain (excluding the newly issued LEAF certificate) using `OCP_SET_ENDORSEMENT` with the appropriate KeyProvisioningEntity value +4. **Verification**: The PKI owner can verify successful provisioning by retrieving the chain using `OCP_GET_ENDORSEMENT` + +For SPDM-aware implementations: + +5. **Optional Mapping Discovery**: Query `OCP_GET_SLOT_ID_MAPPING` to understand which SPDM slots are affected by OCP operations ### Compatibility considerations For devices that support both SPDM and OCP attestation paths: -- The same SlotID namespace is shared between SPDM and OCP commands -- `OCP_SET_ENDORSEMENT` provisions to the same underlying storage accessed by SPDM -- `GET_CERTIFICATE` (SPDM) returns the endorsement chain plus any associated LEAF certificate -- `OCP_GET_ENDORSEMENT` returns only the endorsement chain +- `OCP_SET_ENDORSEMENT` internally manages slot allocation based on the KeyProvisioningEntity +- `OCP_GET_ENDORSEMENT` retrieves endorsements by entity rather than slot number +- `GET_CERTIFICATE` (SPDM) can still be used with the slot numbers reported by `OCP_GET_SLOT_ID_MAPPING` +- The device ensures consistency between OCP entity-based and SPDM slot-based access -This unified approach ensures consistent certificate management regardless of the attestation path used. +This approach simplifies the interface by abstracting slot management while maintaining full compatibility with SPDM. ### Certificate chain validation @@ -597,15 +601,21 @@ When provisioning certificate chains, devices SHALL validate: - All certificates in the chain are within their validity periods - The certificate chain length does not exceed device storage capabilities +Devices MAY additionally validate: + +- Certificate revocation status if CRL or OCSP information is available +- Certificate policy OIDs match expected values for the entity being provisioned + ### Error handling The following error conditions SHALL be reported: -- **SLOT_OCCUPIED**: Attempting to provision a slot that already contains a certificate chain when FORCE flag is not set -- **INVALID_SLOT**: Specified slot ID is outside the valid range +- **ENTITY_ALREADY_PROVISIONED**: Attempting to provision an entity that already has an endorsement when FORCE flag is not set +- **INVALID_ENTITY**: Specified KeyProvisioningEntity value is not supported - **CHAIN_TOO_LONG**: Certificate chain exceeds device storage capacity - **INVALID_CHAIN**: Certificate chain validation failed - **INSUFFICIENT_RESOURCES**: Device lacks resources to complete the operation +- **ENTITY_NOT_PROVISIONED**: Attempting to retrieve endorsement for an entity that has not been provisioned ### Security considerations @@ -616,7 +626,7 @@ Certificate provisioning operations SHOULD be performed over authenticated and e - For SPDM paths: Use SPDM secured messages when available - For out-of-band provisioning: Use platform-specific secure channels -#### Slot update policy +#### Entity update policy To prevent unauthorized certificate replacement: @@ -624,7 +634,7 @@ To prevent unauthorized certificate replacement: - Physical presence assertions - Platform ownership state - Secure boot state -- Once provisioned, slots SHALL NOT be overwritable without the FORCE flag being explicitly set +- Once provisioned, entities SHALL NOT be overwritable without the FORCE flag being explicitly set - When FORCE flag is used to overwrite an existing endorsement, devices SHOULD log this as a security-relevant event #### Certificate lifecycle management @@ -638,41 +648,53 @@ PKI owners are responsible for: ### Implementation notes +#### Internal slot management + +Devices implementing these OCP commands: + +- SHALL internally manage the mapping between KeyProvisioningEntity values and storage slots +- MAY use any slot allocation strategy as long as it supports the minimum required entities +- SHOULD use consistent slot assignments across device resets for predictability + #### Storage optimization Given the limited storage available on many devices: - Redundant certificates (e.g., those appearing in multiple chains) MAY be stored once and referenced multiple times -#### Backwards compatibility +#### Minimal implementation -For devices that only support SPDM without OCP extensions: +Devices that only support OCP commands (not SPDM): -- Standard SPDM `SET_CERTIFICATE` commands remain fully functional +- MAY omit implementation of `OCP_GET_SLOT_ID_MAPPING` +- SHALL still support all KeyProvisioningEntity values defined in this specification +- Focus on entity-based access without exposing slot details ### Example provisioning sequence Here's a complete example of a platform owner provisioning their endorsement chain: -1. **BMC → Device**: `OCP_GET_SLOT_ID_MAPPING()` - - **Device → BMC**: `{0: OID_VENDOR, 2: OID_OWNER, 4: OID_TENANT}` - -2. **BMC → Device**: `GET_ENVELOPE_SIGNED_CSR(KeyPairID=LDevID, SlotID=0, Nonce)` - - **Device → BMC**: `EAT{CSR for LDevID}` - -3. **BMC validates CSR and issues certificate for LDevID** +1. **BMC → Device**: `GET_ENVELOPE_SIGNED_CSR(KeyPairID=LDevID, SlotID=0, Nonce)` + + **Device → BMC**: `EAT{CSR for LDevID, signed by IDevID}` -4. **BMC → Device**: `OCP_SET_ENDORSEMENT(SlotID=2, KeyID, OwnerEndorsementChain)` +2. **BMC validates CSR and issues certificate for LDevID** - **Device → BMC**: `SUCCESS` +3. **BMC → Device**: `OCP_SET_ENDORSEMENT(KeyProvisioningEntity=OWNER, Flags=0, KeyID, OwnerEndorsementChain)` + + **Device → BMC**: `Status=SUCCESS` -5. **TENANT → Device**: `OCP_GET_ENDORSEMENT(SlotID=2)` +4. **BMC → Device**: `OCP_GET_ENDORSEMENT(KeyProvisioningEntity=OWNER)` + + **Device → BMC**: `Status=SUCCESS, OwnerEndorsementChain` (confirming successful provisioning) - **Device → TENANT**: `OwnerEndorsementChain` (confirming successful provisioning) +5. **Optional - BMC → Device**: `OCP_GET_SLOT_ID_MAPPING()` + + **Device → BMC**: `[{VENDOR: 0}, {OWNER: 2}, {TENANT: 4}]` + + (BMC now knows that the OWNER endorsement was stored in SPDM slot 2) -After this sequence, attestations from the device can reference the owner's endorsement chain. +After this sequence, attestations from the device can reference the owner's endorsement chain TODO: fill in additional details. From 3fb23545a2cafa29ce90f4b1f101d925c90e0ef8 Mon Sep 17 00:00:00 2001 From: Fabrizio Damato Date: Wed, 1 Oct 2025 20:25:26 -0700 Subject: [PATCH 3/3] Device Identity Provisioning: Set Certificate, address reviews and consistency cleanup Signed-off-by: Fabrizio Damato --- .../bibliography.yaml | 7 + .../device-identity-provisioning/spec.ocp | 282 +++++++++--------- 2 files changed, 145 insertions(+), 144 deletions(-) diff --git a/specifications/device-identity-provisioning/bibliography.yaml b/specifications/device-identity-provisioning/bibliography.yaml index b771a7a..39731d0 100644 --- a/specifications/device-identity-provisioning/bibliography.yaml +++ b/specifications/device-identity-provisioning/bibliography.yaml @@ -45,3 +45,10 @@ references: year: 2000 month: 11 url: "https://datatracker.ietf.org/doc/html/rfc2986" + - id: "ocp-command-registry" + title: "OCP Command Registry" + publisher: "Open Compute Project" + issued: + year: 2025 + month: 9 + url: "https://github.com/opencomputeproject/ocp-registry/blob/main/command-registry.md" \ No newline at end of file diff --git a/specifications/device-identity-provisioning/spec.ocp b/specifications/device-identity-provisioning/spec.ocp index bdea19f..7451a18 100644 --- a/specifications/device-identity-provisioning/spec.ocp +++ b/specifications/device-identity-provisioning/spec.ocp @@ -193,16 +193,11 @@ Some devices may not support the generation of self-signed CSRs for certain keys ![Envelope-signed Non-self-signed CSR](./diagrams/envelope_signed_csr_non_self_signed.drawio.svg){#fig:envelope-signed-csr-non-self-signed} -This specification provides a definition for a vendor-defined SPDM command, utilizing VENDOR_DEFINED_REQUEST from SPDM 1.3, which can be used to surface these envelope-signed CSRs. +**Transport**: These commands follow the transport bindings defined in [@{ocp-command-registry}]. -GET_ENVELOPE_SIGNED_CSR request and ENVELOPE_SIGNED_CSR response messages are transported as follows: +### GET_ENVELOPE_SIGNED_CSR command -- 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_ENVELOPE_SIGNED_CSR / ENVELOPE_SIGNED_CSR. -- The GET_ENVELOPE_SIGNED_CSR request and ENVELOPE_SIGNED_CSR response forms the payload in the VendorDefinedReqPayload and VendorDefinedRespPayload respectively, defined in Tables [-@tbl:ecsr-req] and [-@tbl:ecsr-resp]. +This command returns an envelope-signed Certificate Signing Request (CSR) that conveys the key derivation properties of the requested identity key, enabling PKI owners to make informed decisions when issuing certificates based on how the key was derived. Table: GET_ENVELOPE_SIGNED_CSR VendorDefinedReqPayload {#tbl:ecsr-req} @@ -281,7 +276,7 @@ Table: ENVELOPE_SIGNED_CSR VendorDefinedRespPayload {#tbl:ecsr-resp} | Byte | Field | Size (bytes) | Description | | offset | | | | +========+=========================+=========================+==========================================+ -| 0 | CommandVersion | 1 | The version of this request structure. | +| 0 | CommandVersion | 1 | The version of this response structure. | | | | | Shall be zero. | +--------+-------------------------+-------------------------+------------------------------------------+ | 1 | CommandCode | 1 | Shall be 01h to indicate | @@ -289,14 +284,19 @@ Table: ENVELOPE_SIGNED_CSR VendorDefinedRespPayload {#tbl:ecsr-resp} +--------+-------------------------+-------------------------+------------------------------------------+ | 2 | Reserved | 4 | Reserved. | +--------+-------------------------+-------------------------+------------------------------------------+ -| 6 | EnvelopeSignedCSRLength | 2 | Shall be the length of the | +| 6 | Reserved | 1 | Reserved. | ++--------+-------------------------+-------------------------+------------------------------------------+ +| 7 | EnvelopeSignedCSRLength | 2 | Shall be the length of the | | | | | EnvelopeSignedCSRdata in bytes. | +| | | | Zero if status is not success. | +--------+-------------------------+-------------------------+------------------------------------------+ -| 8 | EnvelopeSignedCSRdata | EnvelopeSignedCSRLength | Shall be the requested contents of the | +| 9 | EnvelopeSignedCSRdata | EnvelopeSignedCSRLength | Shall be the requested contents of the | | | | | envelope-signed CSR. This field shall be | -| | | | CBOR-encoded. | +| | | | CBOR-encoded. Present only if status | +| | | | is success. | +--------+-------------------------+-------------------------+------------------------------------------+ + The EnvelopeSignedCSRdata shall adhere to the following requirements: - The payload SHALL be an EAT encoded as a CBOR Web Token (CWT) [@{ietf-cwt}]. @@ -334,22 +334,39 @@ Subsequent versions of this specification may be expanded with additional key de ## Issuing and provisioning an identity certificate {#sec:issuing-and-provisioning-identity-cert} -After establishing trust in a device's identity keypair through the envelope-signed CSR mechanism, a PKI owner can issue and provision an identity certificate to the device. This specification defines a standardized approach using OCP-specific extensions transported via SPDM's VENDOR_DEFINED_REQUEST mechanism. +After establishing trust in a device's identity keypair through the envelope-signed CSR mechanism, a PKI owner can issue and provision an identity certificate to the device. This specification defines OCP-specific commands for certificate provisioning. ### Certificate provisioning overview -Identity certificates are provisioned to devices using the OCP-specific `OCP_SET_ENDORSEMENT` command. The PKI owner provisions their endorsement chain (excluding the LEAF certificate) to a specific slot on the device. +When a PKI owner issues an identity certificate for a device key (such as IDevID or LDevID), they provision a certificate chain to the device that includes the PKI-issued identity certificate for the device key. + +**Important**: While devices may expose CSRs for various keys in their hierarchy, endorsement chains provisioned via `OCP_SET_ENDORSEMENT` SHALL NOT include LEAF certificates. This ensures that endorsements work across different use cases (e.g., attestation, secure sessions) since each use case may have different LEAF certificates while sharing the same endorsement chain. + +**Certificate chain composition**: When provisioning via `OCP_SET_ENDORSEMENT`, the certificate chain SHALL include: +- The PKI-issued identity certificate for the device key (e.g., the LDevID certificate issued by the owner's PKI) +- Optionally, any intermediate CA certificates +- Optionally, the root CA certificate + +### Understanding slots + +In this specification, a "slot" refers to a storage location within the device that holds a certificate chain. This concept directly maps to SPDM's certificate slot mechanism: -**Important**: This specification mandates that LEAF certificates (the identity certificates themselves) are NOT included in the provisioned certificate chains. The separation between endorsement chains and LEAF certificates ensures: +- **SPDM context**: SPDM defines 8 possible slots (0-7) where certificate chains can be stored. When an SPDM requester invokes `GET_CERTIFICATE`, they specify which slot's certificate chain they want to retrieve. -- Multiple use cases (attestation, secure sessions) can use different LEAF certificates while sharing the same endorsement point -- The endorsement chain remains stable even as LEAF certificates may change based on key derivation inputs +- **Attestation context**: During attestation, the device uses these certificate chains to establish trust. For example, when generating an EAT, the device may include a LEAF certificate that chains to one of the certificates stored in these slots. The verifier can then retrieve the appropriate certificate chain to validate the complete trust path. + +- **OCP abstraction**: While SPDM uses numeric slot IDs (0-7), the OCP commands abstract this using Key Provisioning Entity identifiers (VENDOR, OWNER, TENANT). The device internally maps these entities to specific slot numbers, which can be discovered via `OCP_GET_SLOT_ID_MAPPING`. + +This abstraction allows: +- Consistent semantics across different device implementations +- Devices to optimize their internal slot allocation +- Compatibility with both SPDM and non-SPDM attestation flows ### Slot allocation and management Devices implementing this specification SHALL support certificate slot allocation with the following requirements: -- **Minimum requirement**: Devices MUST reserve at least 2 slots for OCP provisioning (one for platform owner, one for tenant) +- **Minimum requirement**: Devices MUST present at least three slots for attestation (vendor, owner, tenant), and MUST support in-field provisioning of certificates for the latter two (owner, tenant). - **Vendor flexibility**: The specific slot numbers are determined by the device vendor and discovered via `OCP_GET_SLOT_ID_MAPPING` - **Total slots**: SPDM supports up to 8 slots (0-7), with the allocation between vendor and OCP use defined by the vendor @@ -361,33 +378,32 @@ Example allocation (vendor-specific): **Important**: The actual slot mapping is vendor-defined and discovered at runtime. The device SHALL return an error if attempts are made to provision more slots than physically supported -### OCP extensions for certificate management +#### Key Provisioning Entity Registry -To address the needs of heterogeneous environments where devices may support both SPDM and non-SPDM attestation paths, this specification defines OCP-specific commands transported via SPDM's VENDOR_DEFINED_REQUEST mechanism. +The following Key Provisioning Entity values are defined and SHALL be used consistently across all OCP certificate management commands: -**Transport flexibility**: While this specification defines these commands as SPDM vendor-defined messages, devices that do not support SPDM MAY implement these same commands over alternative transport mechanisms. The definition of transport bindings for non-SPDM attesters is outside the scope of this specification. Regardless of transport, the command and response payload formats defined in this specification SHALL be preserved. +Table: Key Provisioning Entity Values {#tbl:key-provisioning-entity} -#### Key Provisioning Entity Enumeration ++--------+----------+--------------------------------------------------+ +| Value | Name | Description | ++========+==========+==================================================+ +| 0x00 | VENDOR | Vendor-provisioned endorsements | +| | | (typically pre-installed) | ++--------+----------+--------------------------------------------------+ +| 0x01 | OWNER | Platform owner-provisioned endorsements | ++--------+----------+--------------------------------------------------+ +| 0x02 | TENANT | Tenant-provisioned endorsements | +| | | in bare metal scenarios | ++--------+----------+--------------------------------------------------+ +| 0x03- | Reserved | Reserved for future use | +| 0xFF | | | ++--------+----------+--------------------------------------------------+ -The following Key Provisioning Entity values are defined: - -- **VENDOR** (0x00): Vendor-provisioned endorsements (typically pre-installed) -- **OWNER** (0x01): Platform owner-provisioned endorsements -- **TENANT** (0x02): Tenant-provisioned endorsements in bare metal scenarios Future versions of this specification may define additional entity values. -#### OCP_GET_SLOT_ID_MAPPING command (Informational) - -This command is provided for informational purposes, primarily for devices that also support SPDM. It allows callers to understand which SPDM slot corresponds to each Key Provisioning Entity. +#### OCP_GET_SLOT_ID_MAPPING command -GET_SLOT_ID_MAPPING request and SLOT_ID_MAPPING 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 03h to indicate GET_SLOT_ID_MAPPING / SLOT_ID_MAPPING. -- The GET_SLOT_ID_MAPPING request and SLOT_ID_MAPPING response forms the payload in the VendorDefinedReqPayload and VendorDefinedRespPayload respectively, defined in Tables [-@tbl:slot-mapping-req] and [-@tbl:slot-mapping-resp]. +This is an informational command that returns the mapping between Key Provisioning Entities (VENDOR, OWNER, TENANT) and SPDM slot numbers. It enables interoperability between OCP entity-based commands and SPDM slot-based commands on devices that support both SPDM and non-SPDM attesters. Table: GET_SLOT_ID_MAPPING VendorDefinedReqPayload {#tbl:slot-mapping-req} @@ -422,62 +438,50 @@ Table: SLOT_ID_MAPPING VendorDefinedRespPayload {#tbl:slot-mapping-resp} +--------+-------------------------+-------------------------+------------------------------------------+ | 7 | Reserved | 1 | Reserved. | +--------+-------------------------+-------------------------+------------------------------------------+ -| 8 | MappingTable | MappingCount * 2 | Array of mappings. Each entry | +| 8 | MappingTable | MappingCount * 2 | Array of mappings. Each entry | | | | | consists of: | | | | | - KeyProvisioningEntity (1 byte) | | | | | - SlotID (1 byte) | +--------+-------------------------+-------------------------+------------------------------------------+ -**Note**: The `OCP_GET_SLOT_ID_MAPPING` command is informational only. Devices that support both OCP and SPDM commands use this to report which SPDM slot corresponds to each Key Provisioning Entity. This allows SPDM requesters to understand the side effects of `OCP_SET_ENDORSEMENT` operations. - #### OCP_SET_ENDORSEMENT command -SET_ENDORSEMENT request and SET_ENDORSEMENT 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 04h to indicate SET_ENDORSEMENT. -- The SET_ENDORSEMENT request and SET_ENDORSEMENT response forms the payload in the VendorDefinedReqPayload and VendorDefinedRespPayload respectively, defined in Tables [-@tbl:set-endorsement-req] and [-@tbl:set-endorsement-resp]. - Table: SET_ENDORSEMENT VendorDefinedReqPayload {#tbl:set-endorsement-req} -+---------------------+---------------------+---------------------+----------------------------------------------+ -| Byte offset | Field | Size (bytes) | Description | -+=====================+=====================+=====================+==============================================+ -| 0 | CommandVersion | 1 | The version of this request structure. | -| | | | Shall be zero. | -+---------------------+---------------------+---------------------+----------------------------------------------+ -| 1 | CommandCode | 1 | Shall be 04h to indicate | -| | | | SET_ENDORSEMENT. | -+---------------------+---------------------+---------------------+----------------------------------------------+ -| 2 | Reserved | 4 | Reserved. | -+---------------------+---------------------+---------------------+----------------------------------------------+ -| 6 | KeyProvisioningEntity| 1 | Entity for which to set endorsement: | -| | | | - 00h: VENDOR | -| | | | - 01h: OWNER | -| | | | - 02h: TENANT | -| | | | Other values reserved. | -+---------------------+---------------------+---------------------+----------------------------------------------+ -| 7 | Flags | 1 | - Bit [7:1]: Reserved. | -| | | | - Bit [0]: FORCE flag. | -| | | | If set to 1, allows overwriting an | -| | | | existing endorsement. | -| | | | If set to 0, returns error if | -| | | | already provisioned. | -+---------------------+---------------------+---------------------+----------------------------------------------+ -| 8 | KeyID | 1 | Key identifier for certificate selection. | -| | | | Usage is vendor-specific. | -+---------------------+---------------------+---------------------+----------------------------------------------+ -| 9 | Reserved | 1 | Reserved. | -+---------------------+---------------------+---------------------+----------------------------------------------+ -| 10 | CertChainLength | 2 | Length of the certificate chain in bytes. | -| | | | Shall not exceed device capabilities. | -+---------------------+---------------------+---------------------+----------------------------------------------+ -| 12 | CertChain | CertChainLength | DER-encoded certificate chain. | -| | | | Shall NOT include LEAF certificate. | -+---------------------+---------------------+---------------------+----------------------------------------------+ ++---------------------+----------------------+---------------------+----------------------------------------------+ +| Byte offset | Field | Size (bytes) | Description | ++=====================+======================+=====================+==============================================+ +| 0 | CommandVersion | 1 | The version of this request structure. | +| | | | Shall be zero. | ++---------------------+----------------------+---------------------+----------------------------------------------+ +| 1 | CommandCode | 1 | Shall be 04h to indicate | +| | | | SET_ENDORSEMENT. | ++---------------------+----------------------+---------------------+----------------------------------------------+ +| 2 | Reserved | 4 | Reserved. | ++---------------------+----------------------+---------------------+----------------------------------------------+ +| 6 | KeyProvisioningEntity| 1 | Entity from which to get endorsement. | +| | | | See @tbl:key-provisioning-entity. | ++---------------------+----------------------+---------------------+----------------------------------------------+ +| 7 | Flags | 1 | - Bit [7:1]: Reserved. | +| | | | - Bit [0]: FORCE flag. | +| | | | If set to 1, allows overwriting an | +| | | | existing endorsement. | +| | | | If set to 0, returns error if | +| | | | already provisioned. | ++---------------------+----------------------+---------------------+----------------------------------------------+ +| 8 | KeyPairID | 1 | Key identifier for certificate selection. | +| | | | Usage is vendor-specific. | ++---------------------+----------------------+---------------------+----------------------------------------------+ +| 9 | Reserved | 1 | Reserved. | ++---------------------+----------------------+---------------------+----------------------------------------------+ +| 10 | CertChainLength | 2 | Length of the certificate chain in bytes. | +| | | | Shall not exceed device capabilities. | ++---------------------+----------------------+---------------------+----------------------------------------------+ +| 12 | CertChain | CertChainLength | DER-encoded certificate chain. | +| | | | SHALL NOT include LEAF certificates. | +| | | | Device SHALL return POLICY_VIOLATION if | +| | | | LEAF certificate is detected in chain. | ++---------------------+----------------------+---------------------+----------------------------------------------+ Table: SET_ENDORSEMENT VendorDefinedRespPayload {#tbl:set-endorsement-resp} @@ -491,52 +495,30 @@ Table: SET_ENDORSEMENT VendorDefinedRespPayload {#tbl:set-endorsement-resp} | 1 | CommandCode | 1 | Shall be 04h to indicate | | | | | SET_ENDORSEMENT. | +--------+-------------------------+-------------------------+------------------------------------------+ -| 2 | Reserved | 4 | Reserved. | -+--------+-------------------------+-------------------------+------------------------------------------+ -| 6 | Status | 1 | Status code: | -| | | | - 00h: Success | -| | | | - 01h: Invalid entity | -| | | | - 02h: Entity already provisioned | -| | | | - 03h: Invalid chain | -| | | | - 04h: Chain too long | -| | | | - 05h: Insufficient resources | -| | | | - FFh: General failure | +| 2 | Reserved | 2 | Reserved. | +--------+-------------------------+-------------------------+------------------------------------------+ -| 7 | Reserved | 1 | Reserved. | -+--------+-------------------------+-------------------------+------------------------------------------+ - -#### OCP_GET_ENDORSEMENT command -GET_ENDORSEMENT request and GET_ENDORSEMENT 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 05h to indicate GET_ENDORSEMENT. -- The GET_ENDORSEMENT request and GET_ENDORSEMENT response forms the payload in the VendorDefinedReqPayload and VendorDefinedRespPayload respectively, defined in Tables [-@tbl:get-endorsement-req] and [-@tbl:get-endorsement-resp]. +#### OCP_GET_ENDORSEMENT command Table: GET_ENDORSEMENT VendorDefinedReqPayload {#tbl:get-endorsement-req} -+---------------------+---------------------+---------------------+----------------------------------------------+ -| Byte offset | Field | Size (bytes) | Description | -+=====================+=====================+=====================+==============================================+ -| 0 | CommandVersion | 1 | The version of this request structure. | -| | | | Shall be zero. | -+---------------------+---------------------+---------------------+----------------------------------------------+ -| 1 | CommandCode | 1 | Shall be 05h to indicate | -| | | | GET_ENDORSEMENT. | -+---------------------+---------------------+---------------------+----------------------------------------------+ -| 2 | Reserved | 4 | Reserved. | -+---------------------+---------------------+---------------------+----------------------------------------------+ -| 6 | KeyProvisioningEntity| 1 | Entity from which to get endorsement: | -| | | | - 00h: VENDOR | -| | | | - 01h: OWNER | -| | | | - 02h: TENANT | -| | | | Other values reserved. | -+---------------------+---------------------+---------------------+----------------------------------------------+ -| 7 | Reserved | 1 | Reserved. | -+---------------------+---------------------+---------------------+----------------------------------------------+ ++---------------------+----------------------+---------------------+----------------------------------------------+ +| Byte offset | Field | Size (bytes) | Description | ++=====================+======================+=====================+==============================================+ +| 0 | CommandVersion | 1 | The version of this request structure. | +| | | | Shall be zero. | ++---------------------+----------------------+---------------------+----------------------------------------------+ +| 1 | CommandCode | 1 | Shall be 05h to indicate | +| | | | GET_ENDORSEMENT. | ++---------------------+----------------------+---------------------+----------------------------------------------+ +| 2 | Reserved | 4 | Reserved. | ++---------------------+----------------------+---------------------+----------------------------------------------+ +| 6 | KeyProvisioningEntity| 1 | Entity from which to get endorsement. | +| | | | See @tbl:key-provisioning-entity. | ++---------------------+----------------------+---------------------+----------------------------------------------+ +| 7 | Reserved | 1 | Reserved. | ++---------------------+----------------------+---------------------+----------------------------------------------+ Table: GET_ENDORSEMENT VendorDefinedRespPayload {#tbl:get-endorsement-resp} @@ -552,18 +534,12 @@ Table: GET_ENDORSEMENT VendorDefinedRespPayload {#tbl:get-endorsement-resp} +--------+-------------------------+-------------------------+------------------------------------------+ | 2 | Reserved | 4 | Reserved. | +--------+-------------------------+-------------------------+------------------------------------------+ -| 6 | Status | 1 | Status code: | -| | | | - 00h: Success | -| | | | - 01h: Invalid entity | -| | | | - 02h: Entity not provisioned | -| | | | - FFh: General failure | -+--------+-------------------------+-------------------------+------------------------------------------+ -| 7 | Reserved | 1 | Reserved. | +| 6 | Reserved | 1 | Reserved. | +--------+-------------------------+-------------------------+------------------------------------------+ -| 8 | CertChainLength | 2 | Length of the certificate chain. | +| 7 | CertChainLength | 2 | Length of the certificate chain. | | | | | Zero if status is not success. | +--------+-------------------------+-------------------------+------------------------------------------+ -| 10 | CertChain | CertChainLength | DER-encoded certificate chain. | +| 9 | CertChain | CertChainLength | DER-encoded certificate chain. | | | | | Does NOT include LEAF certificate. | | | | | Present only if status is success. | +--------+-------------------------+-------------------------+------------------------------------------+ @@ -574,7 +550,7 @@ A typical provisioning workflow follows these steps: 1. **CSR Generation**: The PKI owner requests an envelope-signed CSR for their chosen identity key using `GET_ENVELOPE_SIGNED_CSR` 2. **Certificate Issuance**: The PKI owner validates the CSR and issues an identity certificate -3. **Chain Provisioning**: The PKI owner provisions their endorsement chain (excluding the newly issued LEAF certificate) using `OCP_SET_ENDORSEMENT` with the appropriate KeyProvisioningEntity value +3. **Chain Provisioning**: The PKI owner provisions their endorsement chain using `OCP_SET_ENDORSEMENT` with the appropriate KeyProvisioningEntity value 4. **Verification**: The PKI owner can verify successful provisioning by retrieving the chain using `OCP_GET_ENDORSEMENT` For SPDM-aware implementations: @@ -608,14 +584,32 @@ Devices MAY additionally validate: ### Error handling -The following error conditions SHALL be reported: +This specification uses error codes defined in the [@{ocp-command-registry}]. The following error conditions are specifically relevant to certificate provisioning operations: + +#### GET_ENVELOPE_SIGNED_CSR errors + +- **INVALID_PARAMETER (0x02)**: Invalid KeyPairID format, malformed SignerSlotIDParam, or invalid Request Attributes +- **INVALID_LENGTH (0x03)**: RequesterInfoLength or OpaqueDataLength exceeds limits +- **INVALID_IDENTIFIER (0x04)**: Requested KeyPairID not found, or SignerSlotIDParam references a non-existent or unprovisioned slot +- **DEVICE_NOT_READY (0x08)**: Device cannot generate CSR in current state + +#### Certificate provisioning errors (SET_ENDORSEMENT) + +- **INVALID_PARAMETER (0x02)**: Invalid KeyProvisioningEntity value +- **INVALID_LENGTH (0x03)**: Certificate chain exceeds device storage capacity +- **INSUFFICIENT_RESOURCES (0x06)**: Device lacks resources to complete the operation +- **POLICY_VIOLATION (0x0E)**: + - Attempting to provision an entity that already has an endorsement when FORCE flag is not set + - Certificate chain includes a LEAF certificate +- **INVALID_STATE (0x0F)**: Certificate chain validation failed + +#### Certificate retrieval errors (GET_ENDORSEMENT) + +- **INVALID_PARAMETER (0x02)**: Invalid KeyProvisioningEntity value +- **RESOURCE_UNAVAILABLE (0x0D)**: Attempting to retrieve endorsement for an entity that has not been provisioned + +Implementations SHALL use these standardized error codes to ensure consistent error reporting across different devices. -- **ENTITY_ALREADY_PROVISIONED**: Attempting to provision an entity that already has an endorsement when FORCE flag is not set -- **INVALID_ENTITY**: Specified KeyProvisioningEntity value is not supported -- **CHAIN_TOO_LONG**: Certificate chain exceeds device storage capacity -- **INVALID_CHAIN**: Certificate chain validation failed -- **INSUFFICIENT_RESOURCES**: Device lacks resources to complete the operation -- **ENTITY_NOT_PROVISIONED**: Attempting to retrieve endorsement for an entity that has not been provisioned ### Security considerations @@ -676,11 +670,11 @@ Here's a complete example of a platform owner provisioning their endorsement cha 1. **BMC → Device**: `GET_ENVELOPE_SIGNED_CSR(KeyPairID=LDevID, SlotID=0, Nonce)` - **Device → BMC**: `EAT{CSR for LDevID, signed by IDevID}` + **Device → BMC**: `EAT{CSR for LDevID, LDEVID Key Derivation Attributes(OIDs), Nonce}` 2. **BMC validates CSR and issues certificate for LDevID** -3. **BMC → Device**: `OCP_SET_ENDORSEMENT(KeyProvisioningEntity=OWNER, Flags=0, KeyID, OwnerEndorsementChain)` +3. **BMC → Device**: `OCP_SET_ENDORSEMENT(KeyProvisioningEntity=OWNER, Flags=0, KeyPairID=LDevID, OwnerEndorsementChain)` **Device → BMC**: `Status=SUCCESS`