Changes to Runtime Specification

Comparing version 1.3 to 1.2
+451 additions -28 deletions
@@ -1,5 +1,5 @@
11 <div style="font-size: 0.85em; color: #656d76; margin-bottom: 1em; padding: 0.5em; background: #f6f8fa; border-radius: 4px;">
2-📄 Source: <a href="https://github.com/chipsalliance/caliptra-sw/blob/b8d1f5916a778e2f34976ea021459fc6575032a2/runtime/README.md" target="_blank">chipsalliance/caliptra-sw/runtime/README.md</a> @ <code>b8d1f59</code>
2+📄 Source: <a href="https://github.com/chipsalliance/caliptra-sw/blob/54565c255b9e4c4bf434b36e009dd427755b9b06/runtime/README.md" target="_blank">chipsalliance/caliptra-sw/runtime/README.md</a> @ <code>54565c2</code>
33 </div>
44
55 # Caliptra Runtime Firmware v1.2
@@ -73,7 +73,7 @@
7373
7474 Each of these abilities are tied to Caliptra Vendor and Owner FW signing keys and should be independent of any SoC RoT FW signing keys.
7575
76-Manifest-based image authorization is implemented via two mailbox commands: [`SET_AUTH_MANIFEST`](#set-auth-manifest) and [`AUTHORIZE_AND_STASH`](#authorize-and-stash). For image format of the manifest, please refer [this file](https://github.com/chipsalliance/caliptra-sw/blob/b8d1f5916a778e2f34976ea021459fc6575032a2/auth-manifest/README.md).
76+Manifest-based image authorization is implemented via two mailbox commands: [`SET_AUTH_MANIFEST`](#set-auth-manifest) and [`AUTHORIZE_AND_STASH`](#authorize-and-stash). For image format of the manifest, please refer [this file](https://github.com/chipsalliance/caliptra-sw/blob/54565c255b9e4c4bf434b36e009dd427755b9b06/auth-manifest/README.md).
7777
7878 ### Caliptra-Endorsed Aggregated Measured Boot
7979
@@ -177,6 +177,82 @@
177177 * CPTRA\_FW\_ERROR\_NON\_FATAL: Status code of mailbox command. Any result
178178 other than `SUCCESS` signifies a mailbox command failure.
179179
180+### Mailbox command privilege levels
181+
182+Mailbox commands maintain the PL information of their caller and can allow or
183+disallow clients from invoking a call based on their PL level. Callers are
184+classified as PL0 or PL1 by comparing the mailbox PAUSER against the `pl0_pauser`
185+field of the signed firmware image header; see [PAUSER privilege levels](#pauser-privilege-levels).
186+
187+A command marked `PL0` is rejected outright for PL1 callers. A command marked
188+`PL0 or PL1` is available to every caller. `INVOKE_DPE_COMMAND` and
189+`INVOKE_DPE_MLDSA87` are available to both levels, but restrict a subset of the
190+DPE commands they carry to PL0.
191+
192+If the PL0 PAUSER flag is not set in the firmware image header, no caller is
193+PL0, so every PL0 command is unavailable for that firmware image. Independently
194+of privilege level, commands from the reserved PAUSER are rejected outright.
195+
196+Privilege level is not the only caller-dependent restriction. Commands that
197+operate on DPE contexts are also scoped by locality, and PAUSER maps 1:1 to
198+locality, so a caller can generally only reach the contexts it created. The
199+`PL0-only functionality` column below calls out where that matters.
200+
201+*Table: Mailbox command privilege levels*
202+
203+| **Command** | **Privilege Level** | **PL0-only functionality**
204+| ----------- | ------------------- | --------------------------
205+| `CALIPTRA_FW_LOAD` | PL0 or PL1 |
206+| `CAPABILITIES` | PL0 or PL1 |
207+| `GET_IDEV_CERT` | PL0 or PL1 |
208+
209+| `POPULATE_IDEV_CERT` | PL0 | Entire command
210+| `GET_IDEV_INFO` | PL0 or PL1 |
211+| `GET_LDEV_CERT` | PL0 or PL1 |
212+| `GET_FMC_ALIAS_CERT` | PL0 or PL1 |
213+| `GET_RT_ALIAS_CERT` | PL0 or PL1 |
214+| `ECDSA384_SIGNATURE_VERIFY` | PL0 or PL1 |
215+| `LMS_SIGNATURE_VERIFY` | PL0 or PL1 |
216+| `MLDSA87_SIGNATURE_VERIFY` | PL0 or PL1 |
217+
218+| `STASH_MEASUREMENT` | PL0 | Entire command
219+| `DISABLE_ATTESTATION` | PL0 | Entire command
220+| `INVOKE_DPE_COMMAND` | PL0 or PL1 | `CertifyKey` with `format=X509`; `DeriveContext` with the `export-cdi` flag; `DeriveContext` with `change-locality` targeting the PL0 PAUSER
221+| `QUOTE_PCRS` | PL0 or PL1 |
222+| `EXTEND_PCR` | PL0 or PL1 |
223+| `GET_PCR_LOG` | PL0 or PL1 |
224+| `INCREMENT_PCR_RESET_COUNTER` | PL0 or PL1 |
225+
226+| `DPE_TAG_TCI` | PL0 or PL1 | Tags only contexts in the caller's own locality, so PL1 cannot tag a PL0 context (and vice versa)
227+| `DPE_GET_TAGGED_TCI` | PL0 or PL1 | Looks up by tag only; either level can read any tagged TCI
228+| `FW_INFO` | PL0 or PL1 |
229+| `VERSION` | PL0 or PL1 |
230+| `SELF_TEST_START` | PL0 or PL1 |
231+| `SELF_TEST_GET_RESULTS` | PL0 or PL1 |
232+| `SHUTDOWN` | PL0 or PL1 |
233+| `ADD_SUBJECT_ALT_NAME` | PL0 or PL1 |
234+
235+| `CERTIFY_KEY_EXTENDED` | PL0 | Entire command
236+| `SET_AUTH_MANIFEST` | PL0 | Entire command
237+| `AUTHORIZE_AND_STASH` | PL0 or PL1 | Stashing the measurement. A PL1 caller must set the `SKIP_STASH` flag; otherwise an authorized image fails when the measurement is stashed into DPE
238+| `GET_IDEVID_CSR` | PL0 or PL1 |
239+| `GET_FMC_ALIAS_CSR` | PL0 or PL1 |
240+
241+| `SIGN_WITH_EXPORTED_ECDSA` | PL0 | Entire command
242+| `REVOKE_EXPORTED_CDI_HANDLE` | PL0 | Entire command
243+| `REALLOCATE_DPE_CONTEXT_LIMITS` | PL0 | Entire command
244+| `SET_PQ_SEED` | PL0 | Entire command
245+| `GET_PQ_CSR` | PL0 or PL1 |
246+| `GET_PQ_INFO` | PL0 or PL1 |
247+| `GET_ATTESTED_PQ_CSR` | PL0 or PL1 |
248+
249+| `POPULATE_PQ_CERT` | PL0 | Entire command
250+| `GET_PQ_CERT` | PL0 or PL1 |
251+
252+| `INVOKE_DPE_MLDSA87` | PL0 or PL1 | Same DPE command restrictions as `INVOKE_DPE_COMMAND`
253+| `CERTIFY_KEY_EXTENDED_MLDSA87` | PL0 | Entire command
254+| `SIGN_WITH_EXPORTED_MLDSA` | PL0 | Entire command
255+
180256 ### CALIPTRA\_FW\_LOAD
181257
182258 The `CALIPTRA_FW_LOAD` command is handled by both ROM and Runtime Firmware.
@@ -194,6 +270,8 @@
194270
195271 Command Code: `0x4657_4C44` ("FWLD")
196272
273+Privilege Level: PL0 or PL1
274+
197275 *Table: `CALIPTRA_FW_LOAD` input arguments*
198276
199277 | **Name** | **Type** | **Description**
@@ -207,6 +285,8 @@
207285 Exposes a command to retrieve firmware capabilities
208286
209287 Command Code: `0x4341_5053` ("CAPS")
288+
289+Privilege Level: PL0 or PL1
210290
211291 *Table: `CAPABILITIES` input arguments*
212292
@@ -227,6 +307,8 @@
227307 Exposes a command to reconstruct the IDEVID CERT.
228308
229309 Command Code: `0x4944_4543` ("IDEC")
310+
311+Privilege Level: PL0 or PL1
230312
231313 *Table: `GET_IDEV_CERT` input arguments*
232314
@@ -255,6 +337,8 @@
255337
256338 Command Code: `0x4944_4550` ("IDEP")
257339
340+Privilege Level: PL0
341+
258342 *Table: `POPULATE_IDEV_CERT` input arguments*
259343
260344 | **Name** | **Type** | **Description**
@@ -275,6 +359,8 @@
275359 Exposes a command to get an IDEVID public key.
276360
277361 Command Code: `0x4944_4549` ("IDEI")
362+
363+Privilege Level: PL0 or PL1
278364
279365 *Table: `GET_IDEV_INFO` input arguments*
280366
@@ -297,6 +383,8 @@
297383
298384 Command Code: `0x4C44_4556` ("LDEV")
299385
386+Privilege Level: PL0 or PL1
387+
300388 *Table: `GET_LDEV_CERT` input arguments*
301389
302390 | **Name** | **Type** | **Description**
@@ -318,6 +406,8 @@
318406
319407 Command Code: `0x4345_5246` ("CERF")
320408
409+Privilege Level: PL0 or PL1
410+
321411 *Table: `GET_FMC_ALIAS_CERT` input arguments*
322412
323413 | **Name** | **Type** | **Description**
@@ -339,6 +429,8 @@
339429
340430 Command Code: `0x4345_5252` ("CERR")
341431
432+Privilege Level: PL0 or PL1
433+
342434 *Table: `GET_RT_ALIAS_CERT` input arguments*
343435
344436 | **Name** | **Type** | **Description**
@@ -363,6 +455,8 @@
363455 and the cause will be logged as a non-fatal error.
364456
365457 Command Code: `0x5349_4756` ("SIGV")
458+
459+Privilege Level: PL0 or PL1
366460
367461 *Table: `ECDSA384_SIGNATURE_VERIFY` input arguments*
368462
@@ -400,6 +494,8 @@
400494 | h | 15 | Height of the tree
401495
402496 Command Code: `0x4C4D_5356` ("LMSV")
497+
498+Privilege Level: PL0 or PL1
403499
404500 *Table: `LMS_SIGNATURE_VERIFY` input arguments*
405501
@@ -422,6 +518,41 @@
422518 | chksum | u32 | Checksum over other output arguments, computed by Caliptra. Little endian.
423519 | fips\_status | u32 | Indicates if the command is FIPS approved or an error.
424520
521+### MLDSA87\_SIGNATURE\_VERIFY
522+
523+Verifies an ML-DSA-87 (FIPS 204) signature. As with the ECDSA and LMS
524+verify commands, the message digest to be verified is taken from
525+Caliptra's SHA384 accelerator peripheral. Callers must stream the
526+message through the SHA accelerator before issuing this command;
527+carrying the raw message in-band would put hashing outside the FIPS
528+module boundary and is therefore disallowed.
529+
530+ML-DSA-87 is stateless and does not have the per-key signature budget that
531+LMS does, which is the primary motivation for adding this command alongside
532+the existing `LMS_SIGNATURE_VERIFY`.
533+
534+In the event of an invalid signature, the mailbox command will report
535+`CMD_FAILURE` and the cause will be logged as a non-fatal error.
536+
537+Command Code: `0x4D44_5356` ("MDSV")
538+
539+Privilege Level: PL0 or PL1
540+
541+*Table: `MLDSA87_SIGNATURE_VERIFY` input arguments*
542+
543+| **Name** | **Type** | **Description**
544+| -------- | --------- | ---------------
545+| chksum | u32 | Checksum over other input arguments, computed by the caller. Little endian.
546+| pub\_key | u8[2592] | Encoded ML-DSA-87 public key (FIPS 204).
547+| signature | u8[4627] | Encoded ML-DSA-87 signature (FIPS 204).
548+
549+*Table: `MLDSA87_SIGNATURE_VERIFY` output arguments*
550+
551+| **Name** | **Type** | **Description**
552+| -------- | -------- | ---------------
553+| chksum | u32 | Checksum over other output arguments, computed by Caliptra. Little endian.
554+| fips\_status | u32 | Indicates if the command is FIPS approved or an error.
555+
425556 ### STASH\_MEASUREMENT
426557
427558 Makes a measurement into the DPE default context. This command is intended for
@@ -430,9 +561,10 @@
430561 * Call the DPE DeriveContext command with the DefaultContext in the locality of
431562 the PL0 PAUSER.
432563 * Extend the measurement into PCR31 (`PCR_ID_STASH_MEASUREMENT`).
433-* **Note**: This command can only be called in the locality of the PL0 PAUSER.
434564
435565 Command Code: `0x4D45_4153` ("MEAS")
566+
567+Privilege Level: PL0
436568
437569 *Table: `STASH_MEASUREMENT` input arguments*
438570
@@ -469,6 +601,8 @@
469601
470602 Command Code: `0x4453_424C` ("DSBL")
471603
604+Privilege Level: PL0
605+
472606 *Table: `DISABLE_ATTESTATION` input arguments*
473607
474608 | **Name** | **Type** | **Description**
@@ -487,6 +621,8 @@
487621 Invokes a serialized DPE command.
488622
489623 Command Code: `0x4450_4543` ("DPEC")
624+
625+Privilege Level: PL0 or PL1; a subset of DPE commands requires PL0 (see [Mailbox command privilege levels](#mailbox-command-privilege-levels))
490626
491627 *Table: `INVOKE_DPE_COMMAND` input arguments*
492628
@@ -511,6 +647,8 @@
511647 All PCR values are hashed together with the nonce to produce the quote.
512648
513649 Command Code: `0x5043_5251` ("PCRQ")
650+
651+Privilege Level: PL0 or PL1
514652
515653 *Table: `QUOTE_PCRS` input arguments*
516654
@@ -536,9 +674,13 @@
536674
537675 ### EXTEND\_PCR
538676
539-Extends a Caliptra hardware PCR.
677+Extends a Caliptra hardware PCR. This command is restricted to the PL0 PAUSER.
678+PCR0 through PCR3 are reserved and cannot be extended with this command. PCR31
679+is available to PL0 for MCU-managed SoC firmware measurements.
540680
541681 Command Code: `0x5043_5245` ("PCRE")
682+
683+Privilege Level: PL0 or PL1
542684
543685 *Table: `EXTEND_PCR` input arguments*
544686
@@ -555,6 +697,10 @@
555697 | chksum | u32 | Checksum over other output arguments, computed by Caliptra. Little endian.
556698 | fips\_status | u32 | Indicates if the command is FIPS approved or an error.
557699
700+PCRs 0-3 (the FMC/RT current and journey PCRs) and PCR31 (the stash-measurement
701+PCR) are reserved for Caliptra's own use and cannot be extended through this
702+command by any caller; requests targeting them fail with `RUNTIME_PCR_RESERVED`.
703+
558704 Note that extensions made into Caliptra's PCRs are _not_ appended to Caliptra's internal PCR log.
559705
560706 ### GET\_PCR\_LOG
@@ -562,6 +708,8 @@
562708 Gets Caliptra's internal PCR log.
563709
564710 Command Code: `0x504C_4F47` ("PLOG")
711+
712+Privilege Level: PL0 or PL1
565713
566714 *Table: `GET_PCR_LOG` input arguments*
567715
@@ -590,6 +738,8 @@
590738
591739 Command Code: `0x5043_5252` ("PCRR")
592740
741+Privilege Level: PL0 or PL1
742+
593743 *Table: `INCREMENT_PCR_RESET_COUNTER` input arguments*
594744
595745 | **Name** | **Type** | **Description**
@@ -609,6 +759,8 @@
609759 Associates a unique tag with a DPE context.
610760
611761 Command Code: `0x5451_4754` ("TAGT")
762+
763+Privilege Level: PL0 or PL1; tags only contexts in the caller's own locality
612764
613765 *Table: `DPE_TAG_TCI` input arguments*
614766
@@ -630,6 +782,8 @@
630782 Retrieves the TCI measurements corresponding to the tagged DPE context.
631783
632784 Command Code: `0x4754_4744` ("GTGD")
785+
786+Privilege Level: PL0 or PL1; not locality-scoped, either level can read any tagged TCI
633787
634788 *Table: `DPE_GET_TAGGED_TCI` input arguments*
635789
@@ -654,6 +808,8 @@
654808 NOTE: Additional fields and info may be appended to the response in subsequent FW versions.
655809
656810 Command Code: `0x494E_464F` ("INFO")
811+
812+Privilege Level: PL0 or PL1
657813
658814 *Table: `FW_INFO` input arguments*
659815
@@ -686,6 +842,8 @@
686842
687843 Command Code: `0x4650_5652` ("FPVR")
688844
845+Privilege Level: PL0 or PL1
846+
689847 Table: `VERSION` input arguments
690848
691849 | **Name** | **Type** | **Description**
@@ -708,6 +866,8 @@
708866
709867 Command Code: `0x4650_4C54`
710868
869+Privilege Level: PL0 or PL1
870+
711871 Table: `SELF_TEST_START` input arguments
712872
713873 | **Name** | **Type** | **Description**
@@ -727,6 +887,8 @@
727887
728888 Command Code: `0x4650_4C67`
729889
890+Privilege Level: PL0 or PL1
891+
730892 Table: `SELF_TEST_GET_RESULTS` input arguments
731893
732894 | **Name** | **Type** | **Description**
@@ -745,6 +907,8 @@
745907 FIPS command to zeroize and shut down the module
746908
747909 Command Code: `0x4650_5344` ("FPSD")
910+
911+Privilege Level: PL0 or PL1
748912
749913 Table: `SHUTDOWN` input arguments
750914
@@ -769,6 +933,8 @@
769933
770934 Command Code: `0x414C_544E` ("ALTN")
771935
936+Privilege Level: PL0 or PL1
937+
772938 *Table: `ADD_SUBJECT_ALT_NAME` input arguments*
773939
774940 | **Name** | **Type** | **Description**
@@ -790,6 +956,8 @@
790956
791957 Command Code: `0x434B_4558` ("CKEX")
792958
959+Privilege Level: PL0
960+
793961 *Table: `CERTIFY_KEY_EXTENDED` input arguments*
794962
795963 | **Name** | **Type** | **Description**
@@ -815,6 +983,8 @@
815983 ### SET\_AUTH\_MANIFEST
816984
817985 Command Code: `0x4154_4D4E` ("ATMN")
986+
987+Privilege Level: PL0
818988
819989 *Table: `SET_AUTH_MANIFEST` input arguments*
820990
@@ -881,6 +1051,8 @@
8811051
8821052 Command Code: `0x4154_5348` ("ATSH")
8831053
1054+Privilege Level: PL0 or PL1; stashing the measurement requires PL0, so a PL1 caller must set the `SKIP_STASH` flag
1055+
8841056 *Table: `AUTHORIZE_AND_STASH` input arguments*
8851057
8861058 | **Name** | **Type** | **Description** |
@@ -913,6 +1085,8 @@
9131085
9141086 Command Code: `0x4944_4352` ("IDCR")
9151087
1088+Privilege Level: PL0 or PL1
1089+
9161090 *Table: `GET_IDEVID_CSR` input arguments*
9171091
9181092 | **Name** | **Type** | **Description**
@@ -942,6 +1116,8 @@
9421116
9431117 Command Code: `0x464D_4352` ("FMCR")
9441118
1119+Privilege Level: PL0 or PL1
1120+
9451121 *Table: `GET_FMC_ALIAS_CSR` input arguments*
9461122
9471123 | **Name** | **Type** | **Description**
@@ -963,7 +1139,7 @@
9631139
9641140 Command Code: `0x5357_4545` ("SWEE")
9651141
966-**Note**: This command is only available in the locality of the PL0 PAUSER.
1142+Privilege Level: PL0
9671143
9681144 *Table: `SIGN_WITH_EXPORTED_ECDSA` input arguments*
9691145
@@ -983,13 +1159,13 @@
9831159 | signature_s | u8[48] | The S BigNum of an ECDSA signature. |
9841160
9851161
986-The `exported_cdi` can be created by calling `DeriveContext` with the `export-cdi` and `create-certificate` flags.
1162+The `exported_cdi_handle` can be created by calling `DeriveContext` with the `export-cdi` and `create-certificate` flags.
9871163
9881164 ### REVOKE\_EXPORTED\_CDI\_HANDLE
9891165
9901166 Command Code: `5256_4348` ("RVCH")
9911167
992-**Note**: This command is only available in the locality of the PL0 PAUSER.
1168+Privilege Level: PL0
9931169
9941170 *Table: `REVOKE_EXPORTED_CDI_HANDLE` input arguments*
9951171
@@ -999,16 +1175,16 @@
9991175 | exported_cdi_handle | u8[32] | The Exported CDI handle returned by the DPE `DeriveContext` command. Little endian. |
10001176
10011177
1002-The `exported_cdi` can be created by calling `DeriveContext` with the `export-cdi` and `create-certificate` flags.
1003-
1004-The `exported_cdi_handle` is no longer usable after calling `REVOKE_EXPORTED_CDI_HANDLE` with it. After the `exported_cdi_handle`
1005-has been revoked, a new exported CDI can be created by calling `DeriveContext` with the `export-cdi` and `create-certificate` flags.
1178+The `exported_cdi_handle` can be created by calling `DeriveContext` with the `export-cdi` and `create-certificate` flags.
1179+
1180+The `exported_cdi_handle` is no longer usable after calling `REVOKE_EXPORTED_CDI_HANDLE` with it. After the `exported_cdi_handle`
1181+has been revoked, a new exported CDI handle can be created by calling `DeriveContext` with the `export-cdi` and `create-certificate` flags.
10061182
10071183 ### REALLOCATE\_DPE\_CONTEXT\_LIMITS
10081184
10091185 Command Code: '5243_5458` ("RCTX")
10101186
1011-**Note**: This command is only available in the locality of the PL0 PAUSER.
1187+Privilege Level: PL0
10121188
10131189 *Table: `REALLOCATE_DPE_CONTEXT_LIMITS` input arguments*
10141190
@@ -1030,6 +1206,250 @@
10301206 This allows the user to reallocate the 32 DPE contexts between PL0 and PL1. By default, each gets 16 contexts.
10311207
10321208 **Note**: 2 PL0 contexts are used by Caliptra itself during initialization.
1209+
1210+## PQC (ML-DSA-87) commands
1211+
1212+The following commands implement the `PQ.DevID` post-quantum identity retrofit described in [Software-based PQC features](https://github.com/chipsalliance/Caliptra/blob/main/doc/caliptra_1x/Caliptra.md#software-based-pqc-features-caliptra-13). All ML-DSA-87 cryptography is implemented in software; there is no hardware PQC accelerator on Caliptra 1.x silicon.
1213+The availability of these commands is advertised to the SoC via the `RT_MLDSA_ATTESTATION` bit in the [`CAPABILITIES`](#capabilities) output.
1214+
1215+### SET\_PQ\_SEED
1216+
1217+Delivers `PQ.DevID.Seed` from the SoC to Caliptra. Caliptra derives `PQ.DevID.CDI` from the seed via an HMAC-based KDF, derives the ML-DSA-87 `PQ.DevID` keypair, and caches the public key digest in persistent data.
1218+
1219+Command Code: `0x5051_5344` ("PQSD")
1220+
1221+Privilege Level: PL0
1222+
1223+*Table: `SET_PQ_SEED` input arguments*
1224+
1225+| **Name** | **Type** | **Description**
1226+| -------- | --------- | ---------------
1227+| chksum | u32 | Checksum over other input arguments, computed by the caller. Little endian.
1228+| seed | u8[48] | `PQ.DevID.Seed`. Per-device unique symmetric seed, provided by the SoC.
1229+
1230+*Table: `SET_PQ_SEED` output arguments*
1231+
1232+| **Name** | **Type** | **Description**
1233+| -------- | -------- | ---------------
1234+| chksum | u32 | Checksum over other output arguments, computed by Caliptra. Little endian.
1235+| fips\_status | u32 | Indicates if the command is FIPS approved or an error.
1236+
1237+Deriving `PQ.DevID.CDI` and the ML-DSA-87 key material can exceed the default mailbox command watchdog budget; Runtime Firmware extends the watchdog for this command.
1238+The production `PQ.DevID.Seed` must never be delivered while Caliptra is `DebugUnlocked`.
1239+Integrators may still call `SET_PQ_SEED` with a non-production seed while `DebugUnlocked` for local bring-up and debug.
1240+
1241+### GET\_PQ\_CSR
1242+
1243+Returns a CSR for the `PQ.DevID` ML-DSA-87 public key, for collection during manufacturing/provisioning, mirroring [`GET_IDEVID_CSR`](#get_idevid_csr).
1244+
1245+Command Code: `0x5051_4353` ("PQCS")
1246+
1247+Privilege Level: PL0 or PL1
1248+
1249+*Table: `GET_PQ_CSR` input arguments*
1250+
1251+| **Name** | **Type** | **Description**
1252+| -------- | -------- | ---------------
1253+| chksum | u32 | Checksum over other input arguments, computed by the caller. Little endian.
1254+
1255+*Table: `GET_PQ_CSR` output arguments*
1256+
1257+| **Name** | **Type** | **Description**
1258+| -------- | --------- | ---------------
1259+| chksum | u32 | Checksum over other output arguments, computed by Caliptra. Little endian.
1260+| fips\_status | u32 | Indicates if the command is FIPS approved or an error.
1261+| data\_size | u32 | Length in bytes of the valid data in the data field, with a maximum of 12800.
1262+| data | u8[12800] | DER-encoded ML-DSA-87 `PQ.DevID` certificate signing request.
1263+
1264+### GET\_ATTESTED\_PQ\_CSR
1265+
1266+Returns the `PQ.DevID` ML-DSA-87 CSR as an attested CSR Entity Attestation Token (EAT), per the [OCP Device Identity Provisioning](https://opencomputeproject.github.io/Security/device-identity-provisioning/HEAD/) specification. When `key_id` is 0, it returns the keypair inventory discovery token instead. The token is a CWT-tagged (61) COSE\_Sign1 signed with the `RT Alias` ECC P-384 key (`alg` ESP384, -51). The protected header `kid` is the `RT Alias` certificate subject key identifier. The request and response format matches `GET_ATTESTED_ECC384_CSR` on Caliptra 2.x.
1267+
1268+The CSR embedded in the token is byte-identical to the [`GET_PQ_CSR`](#get_pq_csr) output.
1269+
1270+The EAT claims are:
1271+
1272+| **Claim key** | **Name** | **Value**
1273+| ------------- | ------------------------ | ---------
1274+| 10 | nonce | `nonce` from the request.
1275+| -70001 | attested CSR | DER-encoded `PQ.DevID` CSR (`key_id` 1 only).
1276+| -70002 | key attributes | `{ 111(OCP KDA OID 1.3.6.1.4.1.42623.1.2): 0 }` (`key_id` 1 only). The derivation-component bitfield is 0: `PQ.DevID` is derived solely from the SoC-provisioned `PQ.DevID.Seed`, so none of the OCP-defined components (UDS, field entropy, fuses, FMC, runtime firmware) apply.
1277+| -70003 | keypair inventory | `[[1, <key attributes>]]` (`key_id` 0 only).
1278+
1279+Command Code: `0x4150_5143` ("APQC")
1280+
1281+Privilege Level: PL0 or PL1
1282+
1283+*Table: `GET_ATTESTED_PQ_CSR` input arguments*
1284+
1285+| **Name** | **Type** | **Description**
1286+| -------- | -------- | ---------------
1287+| chksum | u32 | Checksum over other input arguments, computed by the caller. Little endian.
1288+| key\_id | u32 | **0x0000\_0000:** Keypair inventory discovery <br> **0x0000\_0001:** `PQ.DevID`
1289+| nonce | u8[32] | Nonce to include in the EAT.
1290+
1291+*Table: `GET_ATTESTED_PQ_CSR` output arguments*
1292+
1293+| **Name** | **Type** | **Description**
1294+| -------- | --------- | ---------------
1295+| chksum | u32 | Checksum over other output arguments, computed by Caliptra. Little endian.
1296+| fips\_status | u32 | Indicates if the command is FIPS approved or an error.
1297+| data\_size | u32 | Length in bytes of the valid data in the data field, with a maximum of 12800.
1298+| data | u8[12800] | CWT-tagged COSE\_Sign1 EAT.
1299+
1300+`key_id` 1 requires `SET_PQ_SEED` to have been performed; otherwise the command fails with `RUNTIME_PQC_NOT_INITIALIZED`. Re-deriving the `PQ.DevID` key and signing the CSR can exceed the default mailbox command watchdog budget, so Runtime Firmware extends the watchdog for this request. Any other `key_id` fails with `RUNTIME_MAILBOX_INVALID_PARAMS`.
1301+
1302+### GET\_PQ\_INFO
1303+
1304+Returns the raw ML-DSA-87 `PQ.DevID` public key.
1305+
1306+Command Code: `0x5051_494E` ("PQIN")
1307+
1308+Privilege Level: PL0 or PL1
1309+
1310+*Table: `GET_PQ_INFO` input arguments*
1311+
1312+| **Name** | **Type** | **Description**
1313+| -------- | -------- | ---------------
1314+| chksum | u32 | Checksum over other input arguments, computed by the caller. Little endian.
1315+
1316+*Table: `GET_PQ_INFO` output arguments*
1317+
1318+| **Name** | **Type** | **Description**
1319+| -------- | --------- | ---------------
1320+| chksum | u32 | Checksum over other output arguments, computed by Caliptra. Little endian.
1321+| fips\_status | u32 | Indicates if the command is FIPS approved or an error.
1322+| pq\_pub\_key | u8[2592] | Encoded ML-DSA-87 `PQ.DevID` public key (FIPS 204).
1323+
1324+### POPULATE\_PQ\_CERT
1325+
1326+Allows the SoC to provide a DER-encoded `PQ.DevID` certificate on every boot, once it has been issued by the vendor/owner PQC provisioning CA. Mirrors [`POPULATE_IDEV_CERT`](#populate_idev_cert).
1327+
1328+Command Code: `0x5050_5143` ("PPQC")
1329+
1330+Privilege Level: PL0
1331+
1332+*Table: `POPULATE_PQ_CERT` input arguments*
1333+
1334+| **Name** | **Type** | **Description**
1335+| -------- | -------- | ---------------
1336+| chksum | u32 | Checksum over other input arguments, computed by the caller. Little endian.
1337+| cert\_size | u32 | Size of the DER-encoded `PQ.DevID` certificate, with a maximum of 8192.
1338+| cert | u8[8192] | DER-encoded `PQ.DevID` certificate.
1339+
1340+*Table: `POPULATE_PQ_CERT` output arguments*
1341+
1342+| **Name** | **Type** | **Description**
1343+| -------- | -------- | ---------------
1344+| chksum | u32 | Checksum over other output arguments, computed by Caliptra. Little endian.
1345+| fips\_status | u32 | Indicates if the command is FIPS approved or an error.
1346+
1347+### GET\_PQ\_CERT
1348+
1349+Given a caller-supplied TBS and ML-DSA-87 signature over that TBS, DER-assembles and returns the resulting `PQ.DevID` certificate. Stateless: it does not read the certificate buffer populated by `POPULATE_PQ_CERT`. Mirrors [`GET_IDEV_CERT`](#get_idev_cert).
1350+
1351+Command Code: `0x4750_5143` ("GPQC")
1352+
1353+Privilege Level: PL0 or PL1
1354+
1355+*Table: `GET_PQ_CERT` input arguments*
1356+
1357+| **Name** | **Type** | **Description**
1358+| -------- | -------- | ---------------
1359+| chksum | u32 | Checksum over other input arguments, computed by the caller. Little endian.
1360+| tbs\_size | u32 | Size of the TBS, with a maximum of 3543.
1361+| signature | u8[4627] | ML-DSA-87 signature (FIPS 204) over the TBS, supplied by the caller. Not verified or computed by Caliptra; used as-is to assemble the certificate's `signatureValue`.
1362+| tbs | u8[3543] | TBS. Only bytes up to tbs_size are used.
1363+
1364+*Table: `GET_PQ_CERT` output arguments*
1365+
1366+| **Name** | **Type** | **Description**
1367+| -------- | -------- | ---------------
1368+| chksum | u32 | Checksum over other output arguments, computed by Caliptra. Little endian.
1369+| fips\_status | u32 | Indicates if the command is FIPS approved or an error.
1370+| cert\_size | u32 | Length in bytes of the valid data in the cert field, with a maximum of 8192.
1371+| cert | u8[8192] | DER-encoded `PQ.DevID` certificate.
1372+
1373+### INVOKE\_DPE\_MLDSA87
1374+
1375+Invokes a DPE command using the ML-DSA-87 crypto backend, mirroring [`INVOKE_DPE_COMMAND`](#invoke_dpe_command) but rooted in the ML-DSA-87 DPE profile.
1376+
1377+Command Code: `0x4D4C_4450` ("MLDP")
1378+
1379+Privilege Level: PL0 or PL1; a subset of DPE commands requires PL0 (see [Mailbox command privilege levels](#mailbox-command-privilege-levels))
1380+
1381+*Table: `INVOKE_DPE_MLDSA87` input arguments*
1382+
1383+| **Name** | **Type** | **Description**
1384+| -------- | -------- | ---------------
1385+| chksum | u32 | Checksum over other input arguments, computed by the caller. Little endian.
1386+| data\_size | u32 | Length in bytes of the valid data in the data field.
1387+| data | u8[512] | Encoded DPE command. Only bytes up to data_size are used.
1388+
1389+*Table: `INVOKE_DPE_MLDSA87` output arguments*
1390+
1391+| **Name** | **Type** | **Description**
1392+| -------- | ----------- | ---------------
1393+| chksum | u32 | Checksum over other output arguments, computed by Caliptra. Little endian.
1394+| fips\_status | u32 | Indicates if the command is FIPS approved or an error.
1395+| data\_size | u32 | Length in bytes of the valid data in the data field.
1396+| data | u8[25168] | Encoded DPE response. Only bytes up to data_size are used.
1397+
1398+### CERTIFY\_KEY\_EXTENDED\_MLDSA87
1399+
1400+The ML-DSA-87 counterpart to [`CERTIFY_KEY_EXTENDED`](#certify_key_extended): produces a DPE leaf certificate or CSR, signed with ML-DSA-87, containing custom extensions provided by the SoC.
1401+
1402+Command Code: `0x434B_454D` ("CKEM")
1403+
1404+Privilege Level: PL0
1405+
1406+*Table: `CERTIFY_KEY_EXTENDED_MLDSA87` input arguments*
1407+
1408+| **Name** | **Type** | **Description**
1409+| -------- | -------- | ---------------
1410+| chksum | u32 | Checksum over other input arguments, computed by the caller. Little endian.
1411+| flags | u32 | Flags determining which custom extensions to include in the certificate. See [`CERTIFY_KEY_EXTENDED` input flags](#certify_key_extended).
1412+| certify\_key\_req | u8[72] | Certify Key Request.
1413+
1414+*Table: `CERTIFY_KEY_EXTENDED_MLDSA87` output arguments*
1415+
1416+| **Name** | **Type** | **Description**
1417+| -------- | -------- | ---------------
1418+| chksum | u32 | Checksum over other output arguments, computed by Caliptra. Little endian.
1419+| fips\_status | u32 | Indicates if the command is FIPS approved or an error.
1420+| size | u32 | Length in bytes of the valid data in the certify_key_resp field.
1421+| certify\_key\_resp | u8[25152] | Certify Key Response.
1422+
1423+This command can take tens of millions of CPU cycles due to the software ML-DSA-87 implementation; see [Performance considerations](https://github.com/chipsalliance/Caliptra/blob/main/doc/caliptra_1x/Caliptra.md#performance-considerations).
1424+
1425+### SIGN\_WITH\_EXPORTED\_MLDSA
1426+
1427+The ML-DSA-87 counterpart to [`SIGN_WITH_EXPORTED_ECDSA`](#sign_with_exported_ecdsa): signs with an ML-DSA-87 key pair derived from a previously exported DPE CDI handle.
1428+
1429+Command Code: `0x5357_4D4C` ("SWML")
1430+
1431+Privilege Level: PL0
1432+
1433+*Table: `SIGN_WITH_EXPORTED_MLDSA` input arguments*
1434+
1435+| **Name** | **Type** | **Description**
1436+| -------- | -------- | ---------------
1437+| chksum | u32 | Checksum over other input arguments, computed by the caller. Little endian.
1438+| exported\_cdi\_handle | u8[32] | The Exported CDI handle returned by the DPE `DeriveContext` command.
1439+| sign\_mode | u32 | `0` (`SIGN_MODE_DATA`): `message[..message_size]` is the raw message to sign, and Caliptra computes `mu` internally. `1` (`SIGN_MODE_EXTERNAL_MU`): `message[..MU_SIZE]` is a caller-supplied external `mu`; `message_size` must equal `MU_SIZE`.
1440+| message\_size | u32 | Length in bytes of the valid data in the message field.
1441+| message | u8[1024] | Raw message (`SIGN_MODE_DATA`) or external `mu` (`SIGN_MODE_EXTERNAL_MU`). Only bytes up to message_size are used.
1442+
1443+*Table: `SIGN_WITH_EXPORTED_MLDSA` output arguments*
1444+
1445+| **Name** | **Type** | **Description**
1446+| -------- | --------- | ---------------
1447+| chksum | u32 | Checksum over other output arguments, computed by Caliptra. Little endian.
1448+| fips\_status | u32 | Indicates if the command is FIPS approved or an error.
1449+| derived\_pubkey | u8[2592] | The ML-DSA-87 public key associated with the signing key.
1450+| signature | u8[4627] | The ML-DSA-87 signature.
1451+
1452+The `exported_cdi_handle` can be created by calling `DeriveContext` with the `export-cdi` and `create-certificate` flags, as with `SIGN_WITH_EXPORTED_ECDSA`.
10331453
10341454 ## Checksum
10351455
@@ -1118,8 +1538,9 @@
11181538 * PL0 - High privilege. Only 1 PAUSER in the SoC may be at PL0. The PL0 PAUSER
11191539 is denoted in the signed Caliptra firmware image. The PL0 PAUSER may call any
11201540 supported DPE commands. Only PL0 can use the CertifyKey command. Success of the
1121- CertifyKey command signifies to the caller that it is at PL0. Only PL0 can use
1122- the POPULATE\_IDEV\_CERT mailbox command.
1541+ CertifyKey command signifies to the caller that it is at PL0. A number of
1542+ mailbox commands are also restricted to PL0; see
1543+ [Mailbox command privilege levels](#mailbox-command-privilege-levels).
11231544 * PL1 - Restricted privilege. All other PAUSERs in the SoC are PL1. Caliptra
11241545 SHALL fail any calls to the DPE CertifyKey with format=X509 by PL1 callers.
11251546 PL1 callers should use the CSR format instead.
@@ -1154,20 +1575,21 @@
11541575 Further, it is not allowed for PL1 to call DeriveContext with the intent to change locality to PL0's locality; this would increase the number
11551576 of active contexts in PL0's locality, and hence allow PL1 to DOS PL0.
11561577
1157-### DPE profile implementation
1158-
1159-The DPE iRoT profile leaves some choices up to implementers. This section
1160-describes specific requirements for the Caliptra DPE implementation.
1161-
1162-| Name | Value | Description
1163-| ---- | ----- | -----------
1164-| Profile Variant | `DPE_PROFILE_IROT_P384_SHA384` | The profile variant that Caliptra implements.
1165-| KDF | SP800-108 HMAC-CTR | KDF to use for CDI (tcg.derive.kdf-sha384) and asymmetric key (tcg.derive.kdf-sha384-p384) derivation.
1166-| Simulation Context Support | Yes | Whether Caliptra implements the optional Simulation Contexts feature.
1167-| Supports ExtendTci | Yes | Whether Caliptra implements the optional ExtendTci command.
1168-| Supports Auto Init | Yes | Whether Caliptra will automatically initialize the default DPE context.
1169-| Supports Rotate Context | Yes | Whether Caliptra supports the optional RotateContextHandle command.
1170-| CertifyKey Alias Key | Caliptra Runtime Alias Key | The key that will be used to sign certificates that are produced by the DPE CertifyKey command.
1578+### Caliptra DPE Profile
1579+
1580+Caliptra defines the **Caliptra DPE Profile**, which inherits from the [OCP DPE iRoT Profile](https://github.com/opencomputeproject/Security/tree/main/specifications/dpe-irot-profile) (`DPE_PROFILE_IROT_P384_SHA384`) with some modifications. This section describes the profile attributes and specific requirements for the Caliptra DPE implementation.
1581+
1582+| Name | Value | Description |
1583+| -------------------------- | ------------------------------ | ------------------------------------------------------------------------------------------------------ |
1584+| Profile Variant | `Caliptra DPE Profile` | Derived from `DPE_PROFILE_IROT_P384_SHA384`. |
1585+| KDF | SP800-108 HMAC-CTR | KDF to use for CDI (tcg.derive.kdf-sha384) and asymmetric key (tcg.derive.kdf-sha384-p384) derivation. |
1586+| Simulation Context Support | Yes | Whether Caliptra implements the optional Simulation Contexts feature. |
1587+| Supports ExtendTci | Yes | Whether Caliptra implements the optional ExtendTci command. |
1588+| Supports Auto Init | Yes | Whether Caliptra will automatically initialize the default DPE context. |
1589+| Supports Rotate Context | Yes | Whether Caliptra supports the optional RotateContextHandle command. |
1590+| CertifyKey Alias Key | Caliptra Runtime Alias Key | The key that will be used to sign certificates that are produced by the DPE CertifyKey command. |
1591+| `export-cdi-format` | KeyVault Slot Handle | Overrides the iRoT profile default (which returns the actual CDI) to return a 32-byte handle to a KeyVault slot instead. |
1592+
11711593
11721594 ### Supported DPE commands
11731595
@@ -1176,6 +1598,7 @@
11761598 * GetProfile
11771599 * InitializeContext
11781600 * DeriveContext
1601+ * **Note**: The value returned when `export-cdi` is requested is a 32-byte handle to a KeyVault slot containing the CDI, not the actual CDI. This overrides the default iRoT profile behavior.
11791602 * **Note**: The "export-cdi" flag is only available in the locality of the PL0 PAUSER.
11801603 * CertifyKey
11811604 * Caliptra DPE supports two formats for CertifyKey: X.509 and PKCS#10 CSR.