Skip to content

Commit

Permalink
[feat] Manifest Based Image Authorization - Runtime commands (#1649)
Browse files Browse the repository at this point in the history
[feat] Manifest Based Image Authorization - Runtime commands

This change contains the runtime commands, "Set Authorization Manifest" and "Authorize and Stash", for the Manifest Based Image Authorization feature.
  • Loading branch information
mhatrevi authored Sep 3, 2024
1 parent 83bc311 commit 593c9bd
Show file tree
Hide file tree
Showing 20 changed files with 1,275 additions and 13 deletions.
4 changes: 4 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

129 changes: 129 additions & 0 deletions api/src/mailbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ impl CommandId {

// The capabilities command.
pub const CAPABILITIES: Self = Self(0x4341_5053); // "CAPS"

// The authorization manifest set command.
pub const SET_AUTH_MANIFEST: Self = Self(0x4154_4D4E); // "ATMN"

// The authorize and stash command.
pub const AUTHORIZE_AND_STASH: Self = Self(0x4154_5348); // "ATSH"
}

impl From<u32> for CommandId {
Expand Down Expand Up @@ -140,6 +146,7 @@ pub enum MailboxResp {
GetRtAliasCert(GetRtAliasCertResp),
QuotePcrs(QuotePcrsResp),
CertifyKeyExtended(CertifyKeyExtendedResp),
AuthorizeAndStash(AuthorizeAndStashResp),
}

impl MailboxResp {
Expand All @@ -159,6 +166,7 @@ impl MailboxResp {
MailboxResp::GetRtAliasCert(resp) => resp.as_bytes_partial(),
MailboxResp::QuotePcrs(resp) => Ok(resp.as_bytes()),
MailboxResp::CertifyKeyExtended(resp) => Ok(resp.as_bytes()),
MailboxResp::AuthorizeAndStash(resp) => Ok(resp.as_bytes()),
}
}

Expand All @@ -178,6 +186,7 @@ impl MailboxResp {
MailboxResp::GetRtAliasCert(resp) => resp.as_bytes_partial_mut(),
MailboxResp::QuotePcrs(resp) => Ok(resp.as_bytes_mut()),
MailboxResp::CertifyKeyExtended(resp) => Ok(resp.as_bytes_mut()),
MailboxResp::AuthorizeAndStash(resp) => Ok(resp.as_bytes_mut()),
}
}

Expand Down Expand Up @@ -236,6 +245,8 @@ pub enum MailboxReq {
ExtendPcr(ExtendPcrReq),
AddSubjectAltName(AddSubjectAltNameReq),
CertifyKeyExtended(CertifyKeyExtendedReq),
SetAuthManifest(SetAuthManifestReq),
AuthorizeAndStash(AuthorizeAndStashReq),
}

impl MailboxReq {
Expand All @@ -259,6 +270,8 @@ impl MailboxReq {
MailboxReq::ExtendPcr(req) => Ok(req.as_bytes()),
MailboxReq::AddSubjectAltName(req) => req.as_bytes_partial(),
MailboxReq::CertifyKeyExtended(req) => Ok(req.as_bytes()),
MailboxReq::SetAuthManifest(req) => Ok(req.as_bytes()),
MailboxReq::AuthorizeAndStash(req) => Ok(req.as_bytes()),
}
}

Expand All @@ -282,6 +295,8 @@ impl MailboxReq {
MailboxReq::ExtendPcr(req) => Ok(req.as_bytes_mut()),
MailboxReq::AddSubjectAltName(req) => req.as_bytes_partial_mut(),
MailboxReq::CertifyKeyExtended(req) => Ok(req.as_bytes_mut()),
MailboxReq::SetAuthManifest(req) => Ok(req.as_bytes_mut()),
MailboxReq::AuthorizeAndStash(req) => Ok(req.as_bytes_mut()),
}
}

Expand All @@ -305,6 +320,8 @@ impl MailboxReq {
MailboxReq::ExtendPcr(_) => CommandId::EXTEND_PCR,
MailboxReq::AddSubjectAltName(_) => CommandId::ADD_SUBJECT_ALT_NAME,
MailboxReq::CertifyKeyExtended(_) => CommandId::CERTIFY_KEY_EXTENDED,
MailboxReq::SetAuthManifest(_) => CommandId::SET_AUTH_MANIFEST,
MailboxReq::AuthorizeAndStash(_) => CommandId::AUTHORIZE_AND_STASH,
}
}

Expand Down Expand Up @@ -918,6 +935,118 @@ impl Request for QuotePcrsReq {
type Resp = QuotePcrsResp;
}

// SET_AUTH_MANIFEST
#[repr(C)]
#[derive(Debug, AsBytes, FromBytes, PartialEq, Eq)]
pub struct SetAuthManifestReq {
pub hdr: MailboxReqHeader,
pub manifest_size: u32,
pub manifest: [u8; SetAuthManifestReq::MAX_MAN_SIZE],
}
impl SetAuthManifestReq {
pub const MAX_MAN_SIZE: usize = 8192;

pub fn as_bytes_partial(&self) -> CaliptraResult<&[u8]> {
if self.manifest_size as usize > Self::MAX_MAN_SIZE {
return Err(CaliptraError::RUNTIME_MAILBOX_API_REQUEST_DATA_LEN_TOO_LARGE);
}
let unused_byte_count = Self::MAX_MAN_SIZE - self.manifest_size as usize;
Ok(&self.as_bytes()[..size_of::<Self>() - unused_byte_count])
}

pub fn as_bytes_partial_mut(&mut self) -> CaliptraResult<&mut [u8]> {
if self.manifest_size as usize > Self::MAX_MAN_SIZE {
return Err(CaliptraError::RUNTIME_MAILBOX_API_REQUEST_DATA_LEN_TOO_LARGE);
}
let unused_byte_count = Self::MAX_MAN_SIZE - self.manifest_size as usize;
Ok(&mut self.as_bytes_mut()[..size_of::<Self>() - unused_byte_count])
}
}
impl Default for SetAuthManifestReq {
fn default() -> Self {
Self {
hdr: MailboxReqHeader::default(),
manifest_size: 0,
manifest: [0u8; SetAuthManifestReq::MAX_MAN_SIZE],
}
}
}

#[repr(u32)]
#[derive(Debug, PartialEq, Eq)]
pub enum ImageHashSource {
Invalid = 0,
InRequest,
ShaAcc,
}

impl From<u32> for ImageHashSource {
fn from(val: u32) -> Self {
match val {
1_u32 => ImageHashSource::InRequest,
2_u32 => ImageHashSource::ShaAcc,
_ => ImageHashSource::Invalid,
}
}
}

bitflags::bitflags! {
pub struct AuthAndStashFlags : u32 {
const SKIP_STASH = 0x1;
}
}

impl From<u32> for AuthAndStashFlags {
/// Converts to this type from the input type.
fn from(value: u32) -> Self {
AuthAndStashFlags::from_bits_truncate(value)
}
}

impl AuthAndStashFlags {
pub fn set_skip_stash(&mut self, skip_stash: bool) {
self.set(AuthAndStashFlags::SKIP_STASH, skip_stash);
}
}

// AUTHORIZE_AND_STASH
#[repr(C)]
#[derive(Debug, AsBytes, FromBytes, PartialEq, Eq)]
pub struct AuthorizeAndStashReq {
pub hdr: MailboxReqHeader,
pub metadata: [u8; 4],
pub measurement: [u8; 48],
pub context: [u8; 48],
pub svn: u32,
pub flags: u32,
pub source: u32,
}
impl Default for AuthorizeAndStashReq {
fn default() -> Self {
Self {
hdr: Default::default(),
metadata: Default::default(),
measurement: [0u8; 48],
context: [0u8; 48],
svn: Default::default(),
flags: AuthAndStashFlags::SKIP_STASH.bits(),
source: ImageHashSource::InRequest as u32,
}
}
}
impl Request for AuthorizeAndStashReq {
const ID: CommandId = CommandId::AUTHORIZE_AND_STASH;
type Resp = StashMeasurementResp;
}

#[repr(C)]
#[derive(Debug, Default, AsBytes, FromBytes, PartialEq, Eq)]
pub struct AuthorizeAndStashResp {
pub hdr: MailboxRespHeader,
pub auth_req_result: u32,
}
impl Response for AuthorizeAndStashResp {}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
2 changes: 1 addition & 1 deletion auth-manifest/gen/src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ impl<Crypto: ImageGeneratorCrypto> AuthManifestGenerator<Crypto> {

// Generate the Image Metadata List.
let slice = config.image_metadata_list.as_slice();
auth_manifest.image_metadata_col.image_metadata_array[..slice.len()].copy_from_slice(slice);
auth_manifest.image_metadata_col.image_metadata_list[..slice.len()].copy_from_slice(slice);

auth_manifest.image_metadata_col.header.entry_count =
config.image_metadata_list.len() as u32;
Expand Down
10 changes: 8 additions & 2 deletions auth-manifest/types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ use zeroize::Zeroize;

pub const AUTH_MANIFEST_MARKER: u32 = 0x4154_4D4E;
pub const AUTH_MANIFEST_IMAGE_METADATA_MAX_COUNT: usize = 16;
pub const AUTH_MANIFEST_VENDOR_SIGNATURE_REQURIED_FLAG: u32 = 0x1;

bitflags::bitflags! {
#[derive(Default, Copy, Clone, Debug)]
Expand All @@ -33,6 +32,13 @@ bitflags::bitflags! {
}
}

impl From<u32> for AuthManifestFlags {
/// Converts to this type from the input type.
fn from(value: u32) -> Self {
AuthManifestFlags::from_bits_truncate(value)
}
}

#[repr(C)]
#[derive(AsBytes, FromBytes, Default, Debug, Clone, Copy, Zeroize)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
Expand Down Expand Up @@ -161,7 +167,7 @@ impl Default for AuthManifestImageMetadata {
pub struct AuthManifestImageMetadataCollection {
pub header: AuthManifestImageMetadataCollectionHeader,

pub image_metadata_array: [AuthManifestImageMetadata; AUTH_MANIFEST_IMAGE_METADATA_MAX_COUNT],
pub image_metadata_list: [AuthManifestImageMetadata; AUTH_MANIFEST_IMAGE_METADATA_MAX_COUNT],
}

/// Caliptra Image Authorization Manifest
Expand Down
2 changes: 1 addition & 1 deletion common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub use pcr::{PcrLogEntry, PcrLogEntryId, RT_FW_CURRENT_PCR, RT_FW_JOURNEY_PCR};
pub const FMC_ORG: u32 = 0x40000000;
pub const FMC_SIZE: u32 = 20 * 1024;
pub const RUNTIME_ORG: u32 = FMC_ORG + FMC_SIZE;
pub const RUNTIME_SIZE: u32 = 94 * 1024;
pub const RUNTIME_SIZE: u32 = 97 * 1024;

pub use memory_layout::{DATA_ORG, FHT_ORG, FHT_SIZE, MAN1_ORG};
pub use wdt::{restart_wdt, start_wdt, stop_wdt, WdtTimeout};
1 change: 1 addition & 0 deletions drivers/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ bitflags.workspace = true
caliptra-error = { workspace = true, default-features = false }
caliptra-image-types.workspace = true
caliptra-lms-types.workspace = true
caliptra-auth-man-types.workspace = true
caliptra-registers.workspace = true
cfg-if.workspace = true
dpe = { workspace = true, optional = true }
Expand Down
2 changes: 2 additions & 0 deletions drivers/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ pub use okref::okmutref;
pub use okref::okref;
pub use pcr_bank::{PcrBank, PcrId};
pub use pcr_reset::PcrResetCounter;
#[cfg(feature = "runtime")]
pub use persistent::{AuthManifestImageMetadataList, AUTH_MANIFEST_IMAGE_METADATA_LIST_MAX_COUNT};
pub use persistent::{
FuseLogArray, PcrLogArray, PersistentData, PersistentDataAccessor, StashMeasurementArray,
FUSE_LOG_MAX_COUNT, MEASUREMENT_MAX_COUNT, PCR_LOG_MAX_COUNT,
Expand Down
11 changes: 8 additions & 3 deletions drivers/src/memory_layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ pub const MEASUREMENT_LOG_ORG: u32 = 0x50004C00;
pub const FUSE_LOG_ORG: u32 = 0x50005000;
pub const DPE_ORG: u32 = 0x50005400;
pub const PCR_RESET_COUNTER_ORG: u32 = 0x50006800;
pub const DATA_ORG: u32 = 0x50006C00;
pub const AUTH_MAN_IMAGE_METADATA_LIST_ORG: u32 = 0x50006C00;
pub const DATA_ORG: u32 = 0x50007000;

pub const STACK_ORG: u32 = 0x5001A000;
pub const ROM_STACK_ORG: u32 = 0x5001C000;
Expand Down Expand Up @@ -70,7 +71,8 @@ pub const MEASUREMENT_LOG_SIZE: u32 = 1024;
pub const FUSE_LOG_SIZE: u32 = 1024;
pub const DPE_SIZE: u32 = 5 * 1024;
pub const PCR_RESET_COUNTER_SIZE: u32 = 1024;
pub const DATA_SIZE: u32 = 77 * 1024;
pub const AUTH_MAN_IMAGE_METADATA_LIST_MAX_SIZE: u32 = 1024;
pub const DATA_SIZE: u32 = 76 * 1024;
pub const STACK_SIZE: u32 = 22 * 1024;
pub const ROM_STACK_SIZE: u32 = 14 * 1024;
pub const ESTACK_SIZE: u32 = 1024;
Expand Down Expand Up @@ -145,7 +147,10 @@ fn mem_layout_test_dpe() {
#[test]
#[allow(clippy::assertions_on_constants)]
fn mem_layout_test_pcr_reset_counter() {
assert_eq!((DATA_ORG - PCR_RESET_COUNTER_ORG), PCR_RESET_COUNTER_SIZE);
assert_eq!(
(AUTH_MAN_IMAGE_METADATA_LIST_ORG - PCR_RESET_COUNTER_ORG),
PCR_RESET_COUNTER_SIZE
);
}

#[test]
Expand Down
26 changes: 25 additions & 1 deletion drivers/src/persistent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

use core::{marker::PhantomData, mem::size_of, ptr::addr_of};

#[cfg(feature = "runtime")]
use caliptra_auth_man_types::AuthManifestImageMetadata;
#[cfg(feature = "runtime")]
use caliptra_auth_man_types::AuthManifestImageMetadataCollection;
use caliptra_image_types::ImageManifest;
#[cfg(feature = "runtime")]
use dpe::{DpeInstance, U8Bool, MAX_HANDLES};
Expand All @@ -21,6 +25,8 @@ use crate::pcr_reset::PcrResetCounter;
pub const PCR_LOG_MAX_COUNT: usize = 17;
pub const FUSE_LOG_MAX_COUNT: usize = 62;
pub const MEASUREMENT_MAX_COUNT: usize = 8;
#[cfg(feature = "runtime")]
pub const AUTH_MANIFEST_IMAGE_METADATA_LIST_MAX_COUNT: usize = 8;

#[cfg(feature = "runtime")]
const DPE_DCCM_STORAGE: usize = size_of::<DpeInstance>()
Expand All @@ -34,6 +40,9 @@ const _: () = assert!(DPE_DCCM_STORAGE < memory_layout::DPE_SIZE as usize);
pub type PcrLogArray = [PcrLogEntry; PCR_LOG_MAX_COUNT];
pub type FuseLogArray = [FuseLogEntry; FUSE_LOG_MAX_COUNT];
pub type StashMeasurementArray = [MeasurementLogEntry; MEASUREMENT_MAX_COUNT];
#[cfg(feature = "runtime")]
pub type AuthManifestImageMetadataList =
[AuthManifestImageMetadata; AUTH_MANIFEST_IMAGE_METADATA_LIST_MAX_COUNT];

#[derive(FromBytes, AsBytes, Zeroize)]
#[repr(C)]
Expand Down Expand Up @@ -82,6 +91,16 @@ pub struct PersistentData {

#[cfg(not(feature = "runtime"))]
pcr_reset: [u8; memory_layout::PCR_RESET_COUNTER_SIZE as usize],

#[cfg(feature = "runtime")]
pub auth_manifest_image_metadata_col: AuthManifestImageMetadataCollection,
#[cfg(feature = "runtime")]
reserved9: [u8; memory_layout::AUTH_MAN_IMAGE_METADATA_LIST_MAX_SIZE as usize
- size_of::<AuthManifestImageMetadataCollection>()],

#[cfg(not(feature = "runtime"))]
pub auth_manifest_image_metadata_col:
[u8; memory_layout::AUTH_MAN_IMAGE_METADATA_LIST_MAX_SIZE as usize],
}
impl PersistentData {
pub fn assert_matches_layout() {
Expand All @@ -105,9 +124,14 @@ impl PersistentData {
addr_of!((*P).pcr_reset) as u32,
memory_layout::PCR_RESET_COUNTER_ORG
);
assert_eq!(
addr_of!((*P).auth_manifest_image_metadata_col) as u32,
memory_layout::AUTH_MAN_IMAGE_METADATA_LIST_ORG
);
assert_eq!(
P.add(1) as u32,
memory_layout::PCR_RESET_COUNTER_ORG + memory_layout::PCR_RESET_COUNTER_SIZE
memory_layout::AUTH_MAN_IMAGE_METADATA_LIST_ORG
+ memory_layout::AUTH_MAN_IMAGE_METADATA_LIST_MAX_SIZE
);
}
}
Expand Down
Loading

0 comments on commit 593c9bd

Please sign in to comment.