diff --git a/rust/pvimg/src/pv_utils/se_hdr/flags.rs b/rust/pvimg/src/pv_utils/se_hdr/flags.rs index a1af2509..c0afd60a 100644 --- a/rust/pvimg/src/pv_utils/se_hdr/flags.rs +++ b/rust/pvimg/src/pv_utils/se_hdr/flags.rs @@ -2,24 +2,64 @@ // // Copyright IBM Corp. 2024 +//! Control flags for Secure Execution (SE) headers. +//! +//! This module provides types and traits for managing control flags used in +//! IBM Secure Execution headers. It supports two types of flags: +//! - Plaintext Control Flags (PCF) +//! - Secret Control Flags (SCF) +//! +//! # Examples +//! +//! ``` +//! use pvimg::uvdata::{ControlFlagTrait, ControlFlagsTrait, PcfV1, PlaintextControlFlagsV1}; +//! +//! // Create flags with specific settings +//! let flags = PlaintextControlFlagsV1::from_flags([ +//! PcfV1::AllowDumping.enabled(), +//! PcfV1::PckmoAes.enabled(), +//! ]); +//! +//! // Check if a flag is set +//! assert!(flags.is_set(PcfV1::AllowDumping)); +//! ``` + use std::{fmt::Display, marker::PhantomData, mem::size_of}; use pv::misc::{Flags, Msb0Flags64}; +/// Trait for individual control flag types. +/// +/// This trait defines the interface for control flag enums, providing methods +/// to get the flag's bit position and create enabled/disabled flag data. +/// Implementors must be enum types with `#[repr(u8)]` to ensure proper bit positioning. pub trait ControlFlagTrait: std::fmt::Debug + std::hash::Hash + Copy + Eq + Ord { + /// Returns the bit position (0-63) for this flag in MSB0 ordering. + /// + /// # Safety + /// + /// This method assumes the implementing type is `#[repr(u8)]` and performs + /// an unsafe cast to extract the discriminant value. fn discriminant(&self) -> u8 { assert!(size_of::() == size_of::()); unsafe { *(self as *const Self as *const u8) } } + /// Creates flag data with this flag in the enabled state. fn enabled(self) -> FlagData { FlagData::new(self, FlagState::Enabled) } + /// Creates flag data with this flag in the disabled state. fn disabled(self) -> FlagData { FlagData::new(self, FlagState::Disabled) } + /// Creates a vector of flag data with all specified flags enabled. + /// + /// # Arguments + /// + /// * `flags` - A collection of flags to enable fn all_enabled>(flags: F) -> Vec> { flags .as_ref() @@ -28,6 +68,11 @@ pub trait ControlFlagTrait: std::fmt::Debug + std::hash::Hash + Copy + Eq + Ord .collect() } + /// Creates a vector of flag data with all specified flags disabled. + /// + /// # Arguments + /// + /// * `flags` - A collection of flags to disable fn all_disabled>(flags: F) -> Vec> { flags .as_ref() @@ -37,12 +82,19 @@ pub trait ControlFlagTrait: std::fmt::Debug + std::hash::Hash + Copy + Eq + Ord } } +/// Internal state of a control flag (enabled or disabled). #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)] enum FlagState { + /// Flag is enabled (bit set to 1) Enabled, + /// Flag is disabled (bit set to 0) Disabled, } +/// Represents a control flag with its associated state. +/// +/// This structure pairs a flag with its enabled/disabled state, used when +/// constructing or modifying `ControlFlags` instances. #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)] pub struct FlagData { value: T, @@ -55,16 +107,29 @@ impl FlagData { } } +/// Trait for managing control flags in Secure Execution headers. +/// +/// This trait provides methods for parsing, checking, and validating +/// control flags used in Secure Execution headers. pub trait ControlFlagsTrait: Display { + /// The underlying control flag type type T: ControlFlagTrait; + /// Creates a new instance from a collection of flag data fn from_flags]>>(flags: F) -> Self; + + /// Parses and applies flag data to this instance fn parse_flags]>>(&mut self, flags: F); + + /// Checks if a specific flag is set fn is_set(&self, flag: Self::T) -> bool; + + /// Checks if a specific flag is not set fn is_unset(&self, flag: Self::T) -> bool { !self.is_set(flag) } + /// Validates that there are no duplicate flags in the collection fn no_duplicates]>>(flags: F) -> bool { let mut flags_sorted = flags.as_ref().to_vec(); flags_sorted.sort_by_key(|data| data.value); @@ -73,18 +138,54 @@ pub trait ControlFlagsTrait: Display { flags_sorted.len() == flags.as_ref().len() } + /// Checks if all specified flags are set. + /// + /// # Arguments + /// + /// * `flags` - A collection of flags to check + /// + /// # Returns + /// + /// `true` if all flags are set, `false` otherwise fn all_set>(&self, flags: F) -> bool { flags.as_ref().iter().all(|flag| self.is_set(*flag)) } + /// Checks if all specified flags are unset. + /// + /// # Arguments + /// + /// * `flags` - A collection of flags to check + /// + /// # Returns + /// + /// `true` if all flags are unset, `false` otherwise fn all_unset>(&self, flags: F) -> bool { flags.as_ref().iter().all(|flag| self.is_unset(*flag)) } } -/// Bitflags as used by the Secure Execution in MSB0 ordering +/// Bitflags container for Secure Execution control flags. /// -/// Wraps an u64 to set/get individual bits +/// This structure wraps a 64-bit value with MSB0 (Most Significant Bit first) +/// ordering, as used by IBM Secure Execution. Each bit position corresponds to +/// a specific control flag defined by the generic type parameter `T`. +/// +/// # Type Parameters +/// +/// * `T` - The control flag enum type (e.g., [`PcfV1`] or [`ScfV1`]) +/// +/// # Examples +/// +/// ```rust,ignore +/// use flags::{ControlFlagTrait, ControlFlags, PcfV1}; +/// +/// // Create from u64 +/// let flags: ControlFlags = 0x0000000020000000_u64.into(); +/// +/// // Convert back to u64 +/// let value: u64 = flags.into(); +/// ``` #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct ControlFlags { flags: Msb0Flags64, @@ -92,6 +193,7 @@ pub struct ControlFlags { } impl ControlFlags { + /// Creates a new instance with all flags disabled. fn new() -> Self { Self { flags: 0x0.into(), @@ -149,31 +251,73 @@ impl Display for ControlFlags { } } +/// Plaintext Control Flags for Secure Execution header version 1. +/// +/// These flags control various aspects of Protected Virtualization (PV) guest +/// behavior and capabilities. Each variant represents a specific bit position +/// in the 64-bit control flags field (MSB0 ordering). +/// +/// # Bit Positions +/// +/// The numeric values represent bit positions in MSB0 ordering (bit 0 is the +/// most significant bit). For example, `AllowDumping = 34` means bit 34 from +/// the left (MSB). #[repr(u8)] #[non_exhaustive] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] pub enum PcfV1 { - /// PV guest dump support. + /// Enables Protected Virtualization guest dump support. + /// + /// When set, allows dumping of the PV guest for debugging purposes. AllowDumping = 34, - /// The components are not decrypted during the image unpack. + + /// Disables component encryption during image unpacking. + /// + /// When set, components are not decrypted during the SE image unpack process. NoComponentEncryption = 35, - /// DEA/TDEA PCKMO encryption function are allowed. + + /// Enables DEA/TDEA PCKMO encryption functions. + /// + /// Allows the guest to use Data Encryption Algorithm (DEA) and Triple DEA + /// with the Perform Cryptographic Key Management Operation (PCKMO) instruction. PckmoDeaTdea = 56, - /// AES PCKMO encryption function are allowed. + + /// Enables AES PCKMO encryption functions. + /// + /// Allows the guest to use Advanced Encryption Standard (AES) with PCKMO. PckmoAes = 57, - /// ECC PCKMO encryption function are allowed. + + /// Enables ECC PCKMO encryption functions. + /// + /// Allows the guest to use Elliptic Curve Cryptography (ECC) with PCKMO. PckmoEcc = 58, - /// HMAC PCKMO encryption function are allowed. + + /// Enables HMAC PCKMO encryption functions. + /// + /// Allows the guest to use Hash-based Message Authentication Code (HMAC) with PCKMO. PckmoHmac = 59, - /// Backup target keys can be used. + + /// Enables backup target keys support. + /// + /// When set, allows the use of backup target keys for key management operations. BackupTargetKeys = 62, } + +/// Type alias for plaintext control flags version 1. +/// +/// This is the primary type used for managing plaintext control flags in +/// SE header version 1. pub type PlaintextControlFlagsV1 = ControlFlags; impl PlaintextControlFlagsV1 { + /// Array of all PCKMO-related flags (excluding HMAC). + /// + /// This constant provides convenient access to the three main PCKMO flags + /// that are typically enabled together. pub const PCKMO: [PcfV1; 3] = [PcfV1::PckmoAes, PcfV1::PckmoDeaTdea, PcfV1::PckmoEcc]; } impl Default for PlaintextControlFlagsV1 { + /// Creates default plaintext control flags with PCKMO support enabled. fn default() -> Self { Self::from_flags(PcfV1::all_enabled(PlaintextControlFlagsV1::PCKMO)) } @@ -199,19 +343,43 @@ impl Display for PcfV1 { impl ControlFlagTrait for PcfV1 {} +/// Secret Control Flags for Secure Execution header version 1. +/// +/// These flags control various aspects of Protected Virtualization (PV) guest +/// behavior and capabilities. Each variant represents a specific bit position +/// in the 64-bit control flags field (MSB0 ordering). +/// +/// # Bit Positions +/// +/// The numeric values represent bit positions in MSB0 ordering (bit 0 is the +/// most significant bit). For example, `CckExtensionSecretEnforcement = 1` means bit 1 from +/// the left (MSB). #[repr(u8)] #[non_exhaustive] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] pub enum ScfV1 { - /// All add-secret requests must provide an extension secret + /// Enforces extension secret requirement for add-secret requests. + /// + /// When set, all add-secret requests must provide an extension secret. + /// This adds an additional layer of security to secret management. CckExtensionSecretEnforcement = 1, - /// Whether CCK can be updated + + /// Allows Customer Communication Key (CCK) updates. + /// + /// When set, permits updating the CCK after initial configuration. CckUpdateAllowed = 2, } + +/// Type alias for secret control flags version 1. +/// +/// This is the primary type used for managing secret control flags in +/// SE header version 1. pub type SecretControlFlagsV1 = ControlFlags; + impl ControlFlagTrait for ScfV1 {} impl Default for SecretControlFlagsV1 { + /// Creates default secret control flags. fn default() -> Self { Self::from_flags(ScfV1::all_enabled([])) } diff --git a/rust/pvimg/src/pv_utils/secured_comp.rs b/rust/pvimg/src/pv_utils/secured_comp.rs index 93a3613b..82bc22d7 100644 --- a/rust/pvimg/src/pv_utils/secured_comp.rs +++ b/rust/pvimg/src/pv_utils/secured_comp.rs @@ -25,14 +25,33 @@ use crate::pv_utils::{ Interval, }; +/// Operation mode for component preparation. #[allow(unused)] #[derive(Copy, Clone, Eq, PartialEq)] pub enum Mode { + /// Encrypt the component data Encrypt, + /// Decrypt the component data Decrypt, + /// Add padding but do not encrypt Padding, } +/// Updates the Address List Digest (ALD) with addresses from the given interval. +/// +/// # Arguments +/// +/// * `hasher` - The hasher to update with address data +/// * `interval` - The memory interval containing addresses to hash +/// * `chunk_size` - Size of each chunk in bytes +/// +/// # Returns +/// +/// The number of chunks processed +/// +/// # Errors +/// +/// Returns an error if the hasher update operation fails fn update_ald_digest(hasher: &mut Hasher, interval: &Interval, chunk_size: usize) -> Result { let mut num_chunks = 0; @@ -45,15 +64,32 @@ fn update_ald_digest(hasher: &mut Hasher, interval: &Interval, chunk_size: usize Ok(num_chunks) } +/// Arguments for preparing a secured component. +/// +/// This struct contains the cryptographic parameters needed to prepare +/// a component for Secure Execution, including encryption settings and +/// memory layout information. pub struct PrepareSecuredComponentArgs<'a> { + /// Starting address of the component in memory pub(crate) addr: u64, + /// OpenSSL cipher to use for encryption/decryption pub(crate) cipher: &'a CipherRef, + /// Operation mode (encrypt, decrypt, or padding only) pub(crate) mode: Mode, + /// Encryption key bytes pub(crate) key: &'a [u8], + /// Initialization vector for the cipher pub(crate) iv: &'a [u8], + /// Size of each chunk in bytes pub(crate) chunk_size: usize, } +/// Metadata collection arguments for component preparation. +/// +/// This struct holds optional hashers and size information that are +/// updated during component preparation to generate metadata like +/// the Payload Digest (PLD), Tweak List Digest (TLD), and Address +/// List Digest (ALD). pub struct MetadataArgs<'a> { pub(crate) content_hasher: Option<&'a mut Hasher>, pub(crate) tweak_hasher: Option<&'a mut Hasher>,