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.
mhatrevi authored Sep 3, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 83bc311 commit 593c9bd
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
@@ -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 {
@@ -140,6 +146,7 @@ pub enum MailboxResp {
GetRtAliasCert(GetRtAliasCertResp),
QuotePcrs(QuotePcrsResp),
CertifyKeyExtended(CertifyKeyExtendedResp),
AuthorizeAndStash(AuthorizeAndStashResp),
}

impl MailboxResp {
@@ -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()),
}
}

@@ -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()),
}
}

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

impl MailboxReq {
@@ -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()),
}
}

@@ -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()),
}
}

@@ -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,
}
}

@@ -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::*;
2 changes: 1 addition & 1 deletion auth-manifest/gen/src/generator.rs
Original file line number Diff line number Diff line change
@@ -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;
10 changes: 8 additions & 2 deletions auth-manifest/types/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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)]
@@ -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))]
@@ -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
2 changes: 1 addition & 1 deletion common/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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
@@ -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 }
2 changes: 2 additions & 0 deletions drivers/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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,
11 changes: 8 additions & 3 deletions drivers/src/memory_layout.rs
Original file line number Diff line number Diff line change
@@ -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;
@@ -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;
@@ -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]
26 changes: 25 additions & 1 deletion drivers/src/persistent.rs
Original file line number Diff line number Diff line change
@@ -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};
@@ -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>()
@@ -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)]
@@ -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() {
@@ -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
);
}
}
Loading

0 comments on commit 593c9bd

Please sign in to comment.