Skip to content

Commit

Permalink
Add support for export cdi crypto api and sign with exported
Browse files Browse the repository at this point in the history
  • Loading branch information
clundin25 committed Jan 24, 2025
1 parent d7d919a commit 6660166
Show file tree
Hide file tree
Showing 23 changed files with 542 additions and 140 deletions.
64 changes: 64 additions & 0 deletions api/src/mailbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ impl CommandId {

// The get IDevID CSR command.
pub const GET_IDEV_CSR: Self = Self(0x4944_4352); // "IDCR"

// The sign with exported command.
pub const SIGN_WITH_EXPORTED: Self = Self(0x5357_4554); // "SWET"
}

impl From<u32> for CommandId {
Expand Down Expand Up @@ -153,6 +156,7 @@ pub enum MailboxResp {
CertifyKeyExtended(CertifyKeyExtendedResp),
AuthorizeAndStash(AuthorizeAndStashResp),
GetIdevCsr(GetIdevCsrResp),
SignWithExported(SignWithExportedResp),
}

impl MailboxResp {
Expand All @@ -174,6 +178,7 @@ impl MailboxResp {
MailboxResp::CertifyKeyExtended(resp) => Ok(resp.as_bytes()),
MailboxResp::AuthorizeAndStash(resp) => Ok(resp.as_bytes()),
MailboxResp::GetIdevCsr(resp) => Ok(resp.as_bytes()),
MailboxResp::SignWithExported(resp) => Ok(resp.as_bytes()),
}
}

Expand All @@ -195,6 +200,7 @@ impl MailboxResp {
MailboxResp::CertifyKeyExtended(resp) => Ok(resp.as_mut_bytes()),
MailboxResp::AuthorizeAndStash(resp) => Ok(resp.as_mut_bytes()),
MailboxResp::GetIdevCsr(resp) => Ok(resp.as_mut_bytes()),
MailboxResp::SignWithExported(resp) => Ok(resp.as_mut_bytes()),
}
}

Expand Down Expand Up @@ -253,6 +259,7 @@ pub enum MailboxReq {
CertifyKeyExtended(CertifyKeyExtendedReq),
SetAuthManifest(SetAuthManifestReq),
AuthorizeAndStash(AuthorizeAndStashReq),
SignWithExported(SignWithExportedReq),
}

impl MailboxReq {
Expand All @@ -278,6 +285,7 @@ impl MailboxReq {
MailboxReq::CertifyKeyExtended(req) => Ok(req.as_bytes()),
MailboxReq::SetAuthManifest(req) => Ok(req.as_bytes()),
MailboxReq::AuthorizeAndStash(req) => Ok(req.as_bytes()),
MailboxReq::SignWithExported(req) => Ok(req.as_bytes()),
}
}

Expand All @@ -303,6 +311,7 @@ impl MailboxReq {
MailboxReq::CertifyKeyExtended(req) => Ok(req.as_mut_bytes()),
MailboxReq::SetAuthManifest(req) => Ok(req.as_mut_bytes()),
MailboxReq::AuthorizeAndStash(req) => Ok(req.as_mut_bytes()),
MailboxReq::SignWithExported(req) => Ok(req.as_mut_bytes()),
}
}

Expand All @@ -328,6 +337,7 @@ impl MailboxReq {
MailboxReq::CertifyKeyExtended(_) => CommandId::CERTIFY_KEY_EXTENDED,
MailboxReq::SetAuthManifest(_) => CommandId::SET_AUTH_MANIFEST,
MailboxReq::AuthorizeAndStash(_) => CommandId::AUTHORIZE_AND_STASH,
MailboxReq::SignWithExported(_) => CommandId::SIGN_WITH_EXPORTED,
}
}

Expand Down Expand Up @@ -1010,6 +1020,60 @@ impl Default for GetIdevCsrResp {
}
}

// SIGN_WITH_EXPORTED
#[repr(C)]
#[derive(Debug, IntoBytes, FromBytes, KnownLayout, Immutable, PartialEq, Eq)]
pub struct SignWithExportedReq {
pub hdr: MailboxReqHeader,
pub exported_cdi: [u8; Self::EXPORTED_CDI_MAX_SIZE],
pub digest: [u8; Self::MAX_DIGEST_SIZE],
}

impl Default for SignWithExportedReq {
fn default() -> Self {
Self {
hdr: MailboxReqHeader::default(),
exported_cdi: [0u8; Self::EXPORTED_CDI_MAX_SIZE],
digest: [0u8; Self::MAX_DIGEST_SIZE],
}
}
}

impl SignWithExportedReq {
pub const EXPORTED_CDI_MAX_SIZE: usize = 32;
pub const MAX_DIGEST_SIZE: usize = 48;
}

impl Request for SignWithExportedReq {
const ID: CommandId = CommandId::SIGN_WITH_EXPORTED;
type Resp = SignWithExportedResp;
}

#[repr(C)]
#[derive(Debug, IntoBytes, FromBytes, KnownLayout, Immutable, PartialEq, Eq)]
pub struct SignWithExportedResp {
pub hdr: MailboxRespHeader,
pub signature_r: [u8; Self::R_SIZE],
pub signature_s: [u8; Self::S_SIZE],
}

impl SignWithExportedResp {
pub const R_SIZE: usize = 48;
pub const S_SIZE: usize = 48;
}

impl ResponseVarSize for SignWithExportedResp {}

impl Default for SignWithExportedResp {
fn default() -> Self {
Self {
hdr: MailboxRespHeader::default(),
signature_r: [0u8; Self::R_SIZE],
signature_s: [0u8; Self::S_SIZE],
}
}
}

#[repr(u32)]
#[derive(Debug, PartialEq, Eq)]
pub enum ImageHashSource {
Expand Down
2 changes: 2 additions & 0 deletions common/src/keyids.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,7 @@ pub const KEY_ID_RT_PRIV_KEY: KeyId = KeyId::KeyId5;
pub const KEY_ID_DPE_CDI: KeyId = KeyId::KeyId8;
#[cfg(feature = "runtime")]
pub const KEY_ID_DPE_PRIV_KEY: KeyId = KeyId::KeyId9;
#[cfg(feature = "runtime")]
pub const KEY_ID_EXPORTED_DPE_CDI: KeyId = KeyId::KeyId10;

pub const KEY_ID_TMP: KeyId = KeyId::KeyId3;
8 changes: 8 additions & 0 deletions error/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,14 @@ impl CaliptraError {
CaliptraError::new_const(0x000E0052);
pub const RUNTIME_AUTH_MANIFEST_IMAGE_METADATA_LIST_DUPLICATE_FIRMWARE_ID: CaliptraError =
CaliptraError::new_const(0x000E0053);
pub const RUNTIME_SIGN_WITH_EXPORTED_KEY_DERIVIATION_FAILED: CaliptraError =
CaliptraError::new_const(0x000E0054);
pub const RUNTIME_SIGN_WITH_EXPORTED_SIGNATURE_FAILED: CaliptraError =
CaliptraError::new_const(0x000E0055);
pub const RUNTIME_SIGN_WITH_EXPORTED_INVALID_DIGEST: CaliptraError =
CaliptraError::new_const(0x000E0056);
pub const RUNTIME_SIGN_WITH_EXPORTED_INVALID_SIGNATURE: CaliptraError =
CaliptraError::new_const(0x000E0057);

/// FMC Errors
pub const FMC_GLOBAL_NMI: CaliptraError = CaliptraError::new_const(0x000F0001);
Expand Down
3 changes: 3 additions & 0 deletions libcaliptra/inc/caliptra_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,9 @@ int caliptra_fips_version(struct caliptra_fips_version_resp *resp, bool async);
// Get IDev CSR
int caliptra_get_idev_csr(struct caliptra_get_idev_csr_resp *resp, bool async);

// Sign with Exported
int caliptra_sign_with_exported(struct caliptra_sign_with_exported_req *req, struct caliptra_sign_with_exported_resp *resp, bool async);

// Self test start
int caliptra_self_test_start(bool async);

Expand Down
12 changes: 12 additions & 0 deletions libcaliptra/inc/caliptra_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,18 @@ struct caliptra_get_idev_csr_resp {
uint8_t data[512];
};

struct caliptra_sign_with_exported_req {
struct caliptra_req_header hdr;
uint8_t exported_cdi[32];
uint8_t digest[48];
};

struct caliptra_sign_with_exported_resp {
struct caliptra_resp_header hdr;
uint8_t signature_r[48];
uint8_t signature_s[48];
};

// DPE commands

#define DPE_MAGIC 0x44504543 // "DPEC"
Expand Down
13 changes: 13 additions & 0 deletions libcaliptra/src/caliptra_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -1215,6 +1215,19 @@ int caliptra_get_idev_csr(struct caliptra_get_idev_csr_resp *resp, bool async)
return pack_and_execute_command(&p, async);
}

// Sign with Exported
int caliptra_sign_with_exported(struct caliptra_sign_with_exported_req *req, struct caliptra_sign_with_exported_resp *resp, bool async)
{
if (!req || !resp)
{
return INVALID_PARAMS;
}

CREATE_PARCEL(p, OP_SIGN_WITH_EXPORTED, req, resp);

return pack_and_execute_command(&p, async);
}

// Self test start
int caliptra_self_test_start(bool async)
{
Expand Down
1 change: 1 addition & 0 deletions libcaliptra/src/caliptra_mbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ enum mailbox_command {
OP_SHUTDOWN = 0x46505344, // "FPSD"
OP_CAPABILITIES = 0x43415053, // "CAPS"
OP_GET_IDEV_CSR = 0x49444352, // "IDCR"
OP_SIGN_WITH_EXPORTED = 0x53574554, // "SWET"
};

struct parcel {
Expand Down
20 changes: 20 additions & 0 deletions runtime/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -831,6 +831,26 @@ When called from runtime, if the CSR was not previously provisioned this command

When the `mfg_flag_gen_idev_id_csr` flag has been set, the SoC **MUST** wait for the `flow_status_set_idevid_csr_ready` bit to be set by Caliptra. Once set, the SoC **MUST** clear the `mfg_flag_gen_idev_id_csr` flag for Caliptra to progress.

### SIGN\_WITH\_EXPORTED

Command Code: `0x5357_4554` ("SWET")

*Table: `SIGN_WITH_EXPORTED` input arguments*

| **Name** | **Type** | **Description**
| -------- | -------- | ---------------
| chksum | u32 | Checksum over other input arguments, computed by the caller. Little endian. |
| exported_cdi | u8[32] | The Exported CDI returned by the DPE `DeriveContext` command. Little endian. |
| digest | u8[48] | The digest to be signed. Little endian. |

*Table: `SIGN_WITH_EXPORTED` output arguments*
| **Name** | **Type** | **Description**
| -------- | -------- | ---------------
| signature_r | u8[48] | The R BigNum of an ECDSA signature. |
| signature_s | u8[48] | The S BigNum of an ECDSA signature. |

The `exported_cdi` can be created by calling `DeriveContext` with the `export-cdi` and `create-certificate` flags.

## Checksum

For every command except for FW_LOAD, the request and response feature a checksum. This
Expand Down
1 change: 1 addition & 0 deletions runtime/src/certify_key_extended.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ impl CertifyKeyExtendedCmd {
&mut pdata.fht.rt_dice_pub_key,
key_id_rt_cdi,
key_id_rt_priv_key,
&mut drivers.exported_cdi_slots,
);
let pl0_pauser = pdata.manifest1.header.pl0_pauser;
let (nb, nf) = Drivers::get_cert_validity_info(&pdata.manifest1);
Expand Down
Loading

0 comments on commit 6660166

Please sign in to comment.