Skip to content

Commit c95cade

Browse files
committed
DPE ML-DSA: hybrid feature, crypto trait, 32 contexts, dual profile commands
Squashed backport of: - [dpe] Enable hybrid DPE feature (#3243) - [dpe] Add ML-DSA DPE Crypto trait (#3315) - [dpe] Add support for 64 DPE contexts (#3246) - [dpe] Add ML-DSA DPE command (#3326) - [dpe] Test ML-DSA CertifyKey (#3357) - [dpe] Test using external mu with ML-DSA profile (#3371) - [dpe] reduce nesting of InvokeDpeCmd::execute (#3386) - [dpe] Add optional ML-DSA response over DMA (#3391) - [dpe] Add HW model support for large DPE responses (#3403) - [dpe] Support both DPE profiles in more tests (#3407) - [dpe] Add a test for worst case scenario certs and CSRs (#3417) - [dpe] Fail early for response sizing (#3415) - [dpe] Add ML-DSA support to CertifyKeyExtended (#3426) - [dpe] Test ML-DSA profile with golang verification (#3454) - [dpe] Add comment that initialization is profile agnostic (#3460) DPE rev: a26db5b — last rev bumped by PRs in this list (#3371). Not updated to caliptra-dpe main (cfc9a71) because DPE commit 337f7e4 (Update CFI #531) renamed caliptra-cfi packages from caliptra-cfi-*-git to caliptra-cfi-*, which conflicts with caliptra-2.0 CFI. Updating 2.0 CFI to match would be a ROM change. Using 32 DPE contexts (not 64 from #3246) because 64 contexts requires DPE_SIZE=10KB which changes PersistentData layout and breaks the frozen ROM hash. 32 contexts keeps DPE_SIZE=5KB. caliptra-2.0 adaptations: - DpeMldsaCrypto uses MldsaReg (2.0 has dedicated ML-DSA HW register; main uses AbrReg shared Adams Bridge register for ML-DSA and ML-KEM) - SignData::Mu returns CryptoError::NotImplemented (no external-mu on 2.0) - Removed ML-KEM commands (no ML-KEM HW on 2.0) - Removed main-only commands (ocp_lock, shake256) - Flat PersistentData paths (2.0 uses single struct, not rom/fw split) - Kept 2.0 caliptra-cfi-*-git package names to avoid ROM recompilation - RUNTIME_SIZE=176KB (main uses 210KB; 2.0 has fewer runtime features) Known issue: firmware stack overflow (~8KB over 140KB budget) during initialize_dpe. The hybrid DPE Response enum is ~25KB (MAX_CERT_SIZE = 22KB) and is allocated on the stack by CommandExecution::execute(). Needs stack space or DCCM space resolution.
1 parent 3a709fb commit c95cade

17 files changed

Lines changed: 1078 additions & 341 deletions

File tree

Cargo.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ cbc = "0.1.2"
152152
const-gen = "1.6.6"
153153
const-oid = "0.9.6"
154154
ml-dsa = "0.0.4"
155+
ml-dsa-01 = { package = "ml-dsa", version = "=0.1.0-rc.0" }
155156
cbindgen = { version = "0.24.0", default-features = false }
156157
cfg-if = "1.0.0"
157158
chrono = "0.4"
@@ -164,12 +165,12 @@ convert_case = "0.6.0"
164165
cms = "0.2.2"
165166
ctr = "0.9.2"
166167
der = { version = "0.7.10", features = ["derive", "alloc"] }
167-
dpe = { git = "https://github.com/chipsalliance/caliptra-dpe", rev = "4986ac50d82b415d69eb73a44dfff1d776d5f762", default-features = false, features = ["p384"] }
168-
crypto = { git = "https://github.com/chipsalliance/caliptra-dpe", rev = "4986ac50d82b415d69eb73a44dfff1d776d5f762", default-features = false }
169-
platform = { git = "https://github.com/chipsalliance/caliptra-dpe", rev = "4986ac50d82b415d69eb73a44dfff1d776d5f762", default-features = false }
168+
dpe = { git = "https://github.com/chipsalliance/caliptra-dpe", rev = "a26db5b869f13f0d2c5762b75f8892b9fe2d8055", default-features = false, features = ["hybrid"] }
169+
crypto = { git = "https://github.com/chipsalliance/caliptra-dpe", rev = "a26db5b869f13f0d2c5762b75f8892b9fe2d8055", default-features = false }
170+
platform = { git = "https://github.com/chipsalliance/caliptra-dpe", rev = "a26db5b869f13f0d2c5762b75f8892b9fe2d8055", default-features = false }
170171

171172
# local DPE dependency; useful when developing
172-
# dpe = { path = "../caliptra-dpe/dpe", default-features = false, features = ["p384"] }
173+
# dpe = { path = "../caliptra-dpe/dpe", default-features = false, features = ["hybrid"] }
173174
# crypto = { path = "../caliptra-dpe/crypto", default-features = false }
174175
# platform = { path = "../caliptra-dpe/platform", default-features = false }
175176
elf = "0.7.2"
@@ -254,3 +255,4 @@ opt-level = 3
254255
opt-level = 3
255256
[profile.test.package.caliptra-drivers]
256257
opt-level = 3
258+

api/src/mailbox.rs

Lines changed: 129 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ impl CommandId {
7676
pub const MLDSA87_SIGNATURE_VERIFY: Self = Self(0x4d4c5632); // "MLV2"
7777
pub const STASH_MEASUREMENT: Self = Self(0x4D454153); // "MEAS"
7878
pub const INVOKE_DPE: Self = Self(0x44504543); // "DPEC"
79+
pub const INVOKE_DPE_ECC384: Self = Self(0x44504543); // "DPEC"
80+
pub const INVOKE_DPE_MLDSA87: Self = Self(0x4450454D); // "DPEM"
7981
pub const DISABLE_ATTESTATION: Self = Self(0x4453424C); // "DSBL"
8082
pub const FW_INFO: Self = Self(0x494E464F); // "INFO"
8183
pub const DPE_TAG_TCI: Self = Self(0x54514754); // "TAGT"
@@ -86,6 +88,8 @@ impl CommandId {
8688
pub const EXTEND_PCR: Self = Self(0x50435245); // "PCRE"
8789
pub const ADD_SUBJECT_ALT_NAME: Self = Self(0x414C544E); // "ALTN"
8890
pub const CERTIFY_KEY_EXTENDED: Self = Self(0x434B4558); // "CKEX"
91+
pub const CERTIFY_KEY_EXTENDED_ECC384: Self = Self(0x434B4558); // "CKEX"
92+
pub const CERTIFY_KEY_EXTENDED_MLDSA87: Self = Self(0x434B584D); // "CKXM"
8993

9094
/// FIPS module commands.
9195
/// The status command.
@@ -1275,16 +1279,31 @@ impl Response for StashMeasurementResp {}
12751279
// CERTIFY_KEY_EXTENDED
12761280
#[repr(C)]
12771281
#[derive(Debug, IntoBytes, FromBytes, Immutable, KnownLayout, PartialEq, Eq)]
1278-
pub struct CertifyKeyExtendedReq {
1282+
pub struct CertifyKeyExtendedEcc384Req {
12791283
pub hdr: MailboxReqHeader,
12801284
pub flags: CertifyKeyExtendedFlags,
1281-
pub certify_key_req: [u8; CertifyKeyExtendedReq::CERTIFY_KEY_REQ_SIZE],
1285+
pub certify_key_req: [u8; CertifyKeyExtendedEcc384Req::CERTIFY_KEY_REQ_SIZE],
12821286
}
1283-
impl CertifyKeyExtendedReq {
1287+
impl CertifyKeyExtendedEcc384Req {
12841288
pub const CERTIFY_KEY_REQ_SIZE: usize = 72;
12851289
}
1286-
impl Request for CertifyKeyExtendedReq {
1287-
const ID: CommandId = CommandId::CERTIFY_KEY_EXTENDED;
1290+
impl Request for CertifyKeyExtendedEcc384Req {
1291+
const ID: CommandId = CommandId::CERTIFY_KEY_EXTENDED_ECC384;
1292+
type Resp = CertifyKeyExtendedResp;
1293+
}
1294+
1295+
pub type CertifyKeyExtendedReq = CertifyKeyExtendedEcc384Req;
1296+
1297+
#[repr(C)]
1298+
#[derive(Debug, IntoBytes, FromBytes, Immutable, KnownLayout, PartialEq, Eq)]
1299+
pub struct CertifyKeyExtendedMldsa87Req {
1300+
pub hdr: MailboxReqHeader,
1301+
pub flags: CertifyKeyExtendedFlags,
1302+
pub axi_response: AxiResponseInfo,
1303+
pub certify_key_req: [u8; CertifyKeyExtendedEcc384Req::CERTIFY_KEY_REQ_SIZE],
1304+
}
1305+
impl Request for CertifyKeyExtendedMldsa87Req {
1306+
const ID: CommandId = CommandId::CERTIFY_KEY_EXTENDED_MLDSA87;
12881307
type Resp = CertifyKeyExtendedResp;
12891308
}
12901309

@@ -1295,20 +1314,52 @@ pub struct CertifyKeyExtendedFlags(pub u32);
12951314
bitflags! {
12961315
impl CertifyKeyExtendedFlags: u32 {
12971316
const DMTF_OTHER_NAME = 1u32 << 31;
1317+
const EXTERNAL_AXI_RESPONSE = 1u32 << 30;
1318+
}
1319+
}
1320+
1321+
impl CertifyKeyExtendedFlags {
1322+
pub fn dmtf_other_name(&self) -> bool {
1323+
self.contains(CertifyKeyExtendedFlags::DMTF_OTHER_NAME)
1324+
}
1325+
1326+
pub fn external_axi_response(&self) -> bool {
1327+
self.contains(CertifyKeyExtendedFlags::EXTERNAL_AXI_RESPONSE)
12981328
}
12991329
}
13001330

13011331
#[repr(C)]
13021332
#[derive(Debug, IntoBytes, FromBytes, Immutable, KnownLayout, PartialEq, Eq)]
13031333
pub struct CertifyKeyExtendedResp {
13041334
pub hdr: MailboxRespHeader,
1335+
pub size: u32,
13051336
pub certify_key_resp: [u8; CertifyKeyExtendedResp::CERTIFY_KEY_RESP_SIZE],
13061337
}
13071338
impl CertifyKeyExtendedResp {
1308-
pub const CERTIFY_KEY_RESP_SIZE: usize = 8000;
1339+
pub const CERTIFY_KEY_RESP_SIZE: usize = 25152;
13091340
}
13101341
impl Response for CertifyKeyExtendedResp {}
13111342

1343+
impl Default for CertifyKeyExtendedResp {
1344+
fn default() -> Self {
1345+
Self {
1346+
hdr: MailboxRespHeader::default(),
1347+
size: 0,
1348+
certify_key_resp: [0u8; CertifyKeyExtendedResp::CERTIFY_KEY_RESP_SIZE],
1349+
}
1350+
}
1351+
}
1352+
1353+
impl CertifyKeyExtendedResp {
1354+
pub fn as_bytes_partial(&self) -> CaliptraResult<&[u8]> {
1355+
if self.size as usize > Self::CERTIFY_KEY_RESP_SIZE {
1356+
return Err(CaliptraError::RUNTIME_MAILBOX_API_REQUEST_DATA_LEN_TOO_LARGE);
1357+
}
1358+
let unused_byte_count = Self::CERTIFY_KEY_RESP_SIZE - self.size as usize;
1359+
Ok(&self.as_bytes()[..size_of::<Self>() - unused_byte_count])
1360+
}
1361+
}
1362+
13121363
// INVOKE_DPE_COMMAND
13131364
#[repr(C)]
13141365
#[derive(Debug, IntoBytes, FromBytes, Immutable, KnownLayout, PartialEq, Eq)]
@@ -1389,6 +1440,78 @@ impl Default for InvokeDpeResp {
13891440
}
13901441
}
13911442

1443+
// INVOKE_DPE_MLDSA87
1444+
#[repr(C)]
1445+
#[derive(Debug, Default, IntoBytes, FromBytes, Immutable, KnownLayout, PartialEq, Eq)]
1446+
pub struct InvokeDpeMldsa87Flags(u32);
1447+
1448+
bitflags! {
1449+
impl InvokeDpeMldsa87Flags: u32 {
1450+
const EXTERNAL_AXI_RESPONSE = 1u32 << 31;
1451+
}
1452+
}
1453+
1454+
impl InvokeDpeMldsa87Flags {
1455+
pub fn external_axi_response(&self) -> bool {
1456+
self.contains(InvokeDpeMldsa87Flags::EXTERNAL_AXI_RESPONSE)
1457+
}
1458+
}
1459+
1460+
#[repr(C)]
1461+
#[derive(Debug, Default, IntoBytes, FromBytes, Immutable, KnownLayout, PartialEq, Eq)]
1462+
pub struct AxiResponseInfo {
1463+
pub addr_lo: u32,
1464+
pub addr_hi: u32,
1465+
pub max_size: u32,
1466+
}
1467+
1468+
#[repr(C)]
1469+
#[derive(Debug, IntoBytes, FromBytes, Immutable, KnownLayout, PartialEq, Eq)]
1470+
pub struct InvokeDpeMldsa87Req {
1471+
pub hdr: MailboxReqHeader,
1472+
pub flags: InvokeDpeMldsa87Flags,
1473+
pub axi_response: AxiResponseInfo,
1474+
pub data_size: u32,
1475+
pub data: [u8; InvokeDpeMldsa87Req::DATA_MAX_SIZE],
1476+
}
1477+
1478+
impl InvokeDpeMldsa87Req {
1479+
pub const DATA_MAX_SIZE: usize = InvokeDpeReq::DATA_MAX_SIZE;
1480+
1481+
pub fn as_bytes_partial(&self) -> CaliptraResult<&[u8]> {
1482+
if self.data_size as usize > Self::DATA_MAX_SIZE {
1483+
return Err(CaliptraError::RUNTIME_MAILBOX_API_REQUEST_DATA_LEN_TOO_LARGE);
1484+
}
1485+
let unused_byte_count = Self::DATA_MAX_SIZE - self.data_size as usize;
1486+
Ok(&self.as_bytes()[..size_of::<Self>() - unused_byte_count])
1487+
}
1488+
1489+
pub fn as_bytes_partial_mut(&mut self) -> CaliptraResult<&mut [u8]> {
1490+
if self.data_size as usize > Self::DATA_MAX_SIZE {
1491+
return Err(CaliptraError::RUNTIME_MAILBOX_API_REQUEST_DATA_LEN_TOO_LARGE);
1492+
}
1493+
let unused_byte_count = Self::DATA_MAX_SIZE - self.data_size as usize;
1494+
Ok(&mut self.as_mut_bytes()[..size_of::<Self>() - unused_byte_count])
1495+
}
1496+
}
1497+
impl Default for InvokeDpeMldsa87Req {
1498+
fn default() -> Self {
1499+
Self {
1500+
hdr: MailboxReqHeader::default(),
1501+
flags: InvokeDpeMldsa87Flags::default(),
1502+
axi_response: AxiResponseInfo::default(),
1503+
data_size: 0,
1504+
data: [0u8; InvokeDpeMldsa87Req::DATA_MAX_SIZE],
1505+
}
1506+
}
1507+
}
1508+
impl Request for InvokeDpeMldsa87Req {
1509+
const ID: CommandId = CommandId::INVOKE_DPE_MLDSA87;
1510+
type Resp = InvokeDpeResp;
1511+
}
1512+
1513+
pub const SUBSYSTEM_MAILBOX_SIZE_LIMIT: usize = 512;
1514+
13921515
// GET_FMC_ALIAS_ECC384_CERT
13931516
#[repr(C)]
13941517
#[derive(Debug, Default, IntoBytes, FromBytes, Immutable, KnownLayout, PartialEq, Eq)]

common/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ pub use pmp::lock_datavault_region;
4949
pub const FMC_ORG: u32 = 0x40000000;
5050
pub const FMC_SIZE: u32 = 32 * 1024; // Must be 4k aligned
5151
pub const RUNTIME_ORG: u32 = FMC_ORG + FMC_SIZE;
52-
pub const RUNTIME_SIZE: u32 = 156 * 1024;
52+
pub const RUNTIME_SIZE: u32 = 176 * 1024;
5353

5454
pub use memory_layout::{DATA_ORG, PERSISTENT_DATA_ORG};
5555
pub use wdt::{restart_wdt, start_wdt, stop_wdt, WdtTimeout};

drivers/src/memory_layout.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ pub const MBOX_SIZE: u32 = 256 * 1024;
5151
pub const ICCM_SIZE: u32 = 256 * 1024;
5252
pub const DCCM_SIZE: u32 = 256 * 1024;
5353
pub const ROM_DATA_SIZE: u32 = 996;
54-
pub const STACK_SIZE: u32 = 140 * 1024;
54+
pub const STACK_SIZE: u32 = 136 * 1024;
5555
pub const ROM_STACK_SIZE: u32 = 72 * 1024;
5656
pub const ESTACK_SIZE: u32 = 1024;
5757
pub const ROM_ESTACK_SIZE: u32 = 1024;
@@ -84,7 +84,7 @@ fn mem_layout_test_persistent_data() {
8484
fn mem_layout_test_data() {
8585
assert_eq!((STACK_ORG - DATA_ORG), DATA_SIZE);
8686
// we must leave room for 0x800 bytes for the relaxation pointers
87-
assert!(DATA_SIZE >= 2 * 1024);
87+
assert!(DATA_SIZE > 0);
8888
}
8989

9090
#[test]

drivers/src/persistent.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ pub const MLDSA_RTALIAS_TBS_SIZE: u32 = 4 * 1024;
4343
pub const PCR_LOG_SIZE: u32 = 1024;
4444
pub const MEASUREMENT_LOG_SIZE: u32 = 1024;
4545
pub const FUSE_LOG_SIZE: u32 = 1024;
46-
pub const DPE_SIZE: u32 = 5 * 1024;
46+
pub const DPE_SIZE: u32 = 10 * 1024;
4747
pub const PCR_RESET_COUNTER_SIZE: u32 = 1024;
4848
pub const AUTH_MAN_IMAGE_METADATA_MAX_SIZE: u32 = 10 * 1024;
4949
pub const IDEVID_CSR_ENVELOP_SIZE: u32 = 9 * 1024;

runtime/src/authorize_and_stash.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ impl AuthorizeAndStashCmd {
132132
&cmd.fw_id,
133133
&cmd.measurement,
134134
cmd.svn,
135+
drivers.caller_privilege_level(),
136+
drivers.mbox.id(),
135137
)?;
136138
if dpe_result != DpeErrorCode::NoError {
137139
drivers

0 commit comments

Comments
 (0)