mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
pvimg and create-sehdr: Refactor code to use generic flags
Replace version-specific flag enums (PcfV1, ScfV1) with a unified SeHdrFlag enum and generic ControlFlagsModel. This refactoring provides: - Single SeHdrFlag enum for all control flags across SE header versions - Generic SeHdrControlFlagsModel with version-specific configurations - EffectiveControlFlags type replacing PlaintextControlFlagsV1/SecretControlFlagsV1 - FlagsOverride mechanism for customizing flag configurations - Enhanced FromStr implementation for flag parsing - Comprehensive test coverage for flag operations and conversions The new design improves maintainability by eliminating code duplication and provides a more flexible API for working with SE header control flags. Assisted-by: IBM Bob:1.0.4 Signed-off-by: Marc Hartmayer <marc@linux.ibm.com> Reviewed-by: Steffen Eiden <seiden@linux.ibm.com> Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
This commit is contained in:
committed by
Steffen Eiden
parent
20fffb31d7
commit
c87d11abfe
@@ -17,7 +17,7 @@ use pv::request::SymKeyType;
|
||||
use pv::{Error as PvError, Result};
|
||||
use pvimg::misc::PSW;
|
||||
use pvimg::secured_comp::{ComponentTrait, Layout, SecuredComponentBuilder};
|
||||
use pvimg::uvdata::{BuilderTrait, SeHdrBuilder, SeHdrVersion};
|
||||
use pvimg::uvdata::{BuilderTrait, SeHdrBuilder, SeHdrControlFlags, SeHdrVersion, SeTarget};
|
||||
use utils::{AtomicFile, AtomicFileOperation, HexSlice, PvLogger, VerbosityOptions};
|
||||
|
||||
/// Converts the hexstring into a byte vector.
|
||||
@@ -203,11 +203,8 @@ fn main() -> anyhow::Result<()> {
|
||||
info!("\n# Creating Secure Execution Header");
|
||||
let addr = args.psw_addr;
|
||||
let mask = args.psw_mask;
|
||||
let mut builder = SeHdrBuilder::new(
|
||||
SeHdrVersion::V1,
|
||||
PSW { addr, mask },
|
||||
secure_comp_builer.finish()?,
|
||||
)?;
|
||||
let version = SeHdrVersion::V1;
|
||||
let mut builder = SeHdrBuilder::new(version, PSW { addr, mask }, secure_comp_builer.finish()?)?;
|
||||
let mut target_pub_keys = vec![];
|
||||
for hkd_path in args.host_key_documents {
|
||||
info!(
|
||||
@@ -231,8 +228,9 @@ fn main() -> anyhow::Result<()> {
|
||||
}
|
||||
builder.add_hostkeys(&target_pub_keys)?;
|
||||
|
||||
let pcf = try_parse_u64(&args.pcf, "pcf")?.into();
|
||||
let scf = try_parse_u64(&args.scf, "scf")?.into();
|
||||
let target = SeTarget::from_se_hdr_version(version);
|
||||
let pcf = SeHdrControlFlags::from_u64(try_parse_u64(&args.pcf, "pcf")?, target, true);
|
||||
let scf = SeHdrControlFlags::from_u64(try_parse_u64(&args.scf, "scf")?, target, false);
|
||||
info!(
|
||||
"PSW addr ............: {addr:#018x}\n\
|
||||
PSW mask ............: {mask:#018x}\n\
|
||||
|
||||
@@ -13,7 +13,31 @@ use std::string::ToString;
|
||||
use clap::builder::{PossibleValue, TypedValueParser};
|
||||
use clap::{Arg, ArgGroup, Args, Command, CommandFactory, Parser, ValueEnum, ValueHint};
|
||||
use log::warn;
|
||||
use utils::{CertificateOptions, DeprecatedVerbosityOptions};
|
||||
use utils::{CertificateOptions, DeprecatedVerbosityOptions, ValueEnumDisplay};
|
||||
|
||||
/// SE header control flags for CLI
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, ValueEnum, ValueEnumDisplay)]
|
||||
#[value(rename_all = "kebab-case")]
|
||||
pub enum SeHdrFlagName {
|
||||
/// Confidential guest dump support
|
||||
ConfidentialDump,
|
||||
/// DEA/TDEA PCKMO key encryption support
|
||||
PckmoDeaTdea,
|
||||
/// AES PCKMO key encryption support
|
||||
PckmoAes,
|
||||
/// ECC PCKMO key encryption support
|
||||
PckmoEcc,
|
||||
/// HMAC PCKMO key encryption support
|
||||
PckmoHmac,
|
||||
/// Backup target keys support
|
||||
BackupTargetKeys,
|
||||
/// CCK-derived extension secret enforcement for add-secret requests
|
||||
CckExtensionSecretEnforcement,
|
||||
/// CCK update support
|
||||
CckUpdate,
|
||||
/// Image components without encryption
|
||||
NoComponentEncryption,
|
||||
}
|
||||
|
||||
/// Create and inspect IBM Secure Execution images.
|
||||
///
|
||||
@@ -56,6 +80,28 @@ impl CliOptions {
|
||||
}
|
||||
}
|
||||
|
||||
/// Defines a requirement rule for CLI validation.
|
||||
///
|
||||
/// A requirement specifies that certain flags require a specific option to be present.
|
||||
/// For example, the `ConfidentialDump` flag requires the `--cck` option.
|
||||
struct Requirement {
|
||||
/// The flags that trigger this requirement
|
||||
flags: &'static [SeHdrFlagName],
|
||||
/// The option name that must be present (e.g., "cck")
|
||||
option: &'static str,
|
||||
/// Whether the required option is present
|
||||
present: bool,
|
||||
}
|
||||
|
||||
/// Defines a set of flags that cannot be used together.
|
||||
///
|
||||
/// When multiple flags from this set are present in the command line,
|
||||
/// a validation error is raised with a dynamically generated message
|
||||
/// listing the conflicting flags.
|
||||
struct MutuallyExclusiveFlags {
|
||||
flags: &'static [SeHdrFlagName],
|
||||
}
|
||||
|
||||
/// Validates the given command line options.
|
||||
///
|
||||
/// # Errors
|
||||
@@ -71,6 +117,92 @@ pub fn validate_cli(opts: &CliOptions) -> Result<(), clap::error::Error> {
|
||||
{
|
||||
warn!("Use bootloader directory: {}", dir.display());
|
||||
}
|
||||
|
||||
// Check that a user provided CCK is available
|
||||
let rules = [Requirement {
|
||||
flags: &[
|
||||
SeHdrFlagName::ConfidentialDump,
|
||||
SeHdrFlagName::CckExtensionSecretEnforcement,
|
||||
],
|
||||
option: LONG_FLAG_CCK,
|
||||
present: create_opts.keys.cck.is_some(),
|
||||
}];
|
||||
for r in rules {
|
||||
let offenders: Vec<_> = r
|
||||
.flags
|
||||
.iter()
|
||||
.filter(|f| create_opts.flags.contains(f))
|
||||
.collect();
|
||||
|
||||
if !offenders.is_empty() && !r.present {
|
||||
return Err(clap::Error::raw(
|
||||
clap::error::ErrorKind::MissingRequiredArgument,
|
||||
format!(
|
||||
"flag(s) {} require(s) --{}",
|
||||
offenders
|
||||
.iter()
|
||||
.map(|f| format!("{:?}", f))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
r.option
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// Check for conflicts between --flags and --disable-flags
|
||||
if !create_opts.flags.is_empty() && !create_opts.disable_flags.is_empty() {
|
||||
use std::collections::HashSet;
|
||||
let flags_set: HashSet<_> = create_opts.flags.iter().collect();
|
||||
let disable_flags_set: HashSet<_> = create_opts.disable_flags.iter().collect();
|
||||
|
||||
let conflicts: Vec<_> = flags_set
|
||||
.intersection(&disable_flags_set)
|
||||
.copied()
|
||||
.collect();
|
||||
|
||||
if !conflicts.is_empty() {
|
||||
return Err(clap::Error::raw(
|
||||
clap::error::ErrorKind::ArgumentConflict,
|
||||
// Print the flag name using the kebab-case notation (using to_possible_value)
|
||||
format!(
|
||||
"Conflicting flags detected: the following flags are specified in both --flags and --disable-flags: {}",
|
||||
conflicts.iter().map(|x| format!("{x}")).collect::<Vec<_>>().join(", ")
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// Check for mutually exclusive flags within --flags
|
||||
let exclusion_rules = [MutuallyExclusiveFlags {
|
||||
flags: &[
|
||||
SeHdrFlagName::CckExtensionSecretEnforcement,
|
||||
SeHdrFlagName::CckUpdate,
|
||||
],
|
||||
}];
|
||||
|
||||
for rule in exclusion_rules {
|
||||
let conflicting_flags: Vec<_> = rule
|
||||
.flags
|
||||
.iter()
|
||||
.filter(|f| create_opts.flags.contains(f))
|
||||
.collect();
|
||||
|
||||
if conflicting_flags.len() > 1 {
|
||||
return Err(clap::Error::raw(
|
||||
clap::error::ErrorKind::ArgumentConflict,
|
||||
format!(
|
||||
"The following flags cannot be used together: {}",
|
||||
conflicting_flags
|
||||
.iter()
|
||||
.map(|f| format!("'{}'", f))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
_ => Ok(()),
|
||||
@@ -100,6 +232,8 @@ pub struct ComponentPaths {
|
||||
pub parmfile: Option<PathBuf>,
|
||||
}
|
||||
|
||||
const LONG_FLAG_CCK: &str = "cck";
|
||||
|
||||
/// CLI Argument collection for handling user-provided keys.
|
||||
#[derive(Args, Debug)]
|
||||
#[cfg_attr(test, derive(Default))]
|
||||
@@ -109,7 +243,7 @@ pub struct UserKeys {
|
||||
/// The file must contain exactly 32 bytes of data. In previous versions,
|
||||
/// this option was called '--comm-key'.
|
||||
#[arg(
|
||||
long,
|
||||
long = LONG_FLAG_CCK,
|
||||
value_name = "FILE",
|
||||
group = "cck-available",
|
||||
visible_alias = "comm-key"
|
||||
@@ -546,8 +680,31 @@ pub struct CreateBootImageArgs {
|
||||
pub keys: UserKeys,
|
||||
|
||||
#[clap(flatten)]
|
||||
// TODO Declare as deprecated
|
||||
pub legacy_flags: CreateBootImageLegacyFlags,
|
||||
|
||||
/// Set control flags using comma-separated flag names.
|
||||
///
|
||||
/// Specify flags to enable using their names.
|
||||
#[arg(
|
||||
long,
|
||||
value_name = "FLAGS",
|
||||
value_delimiter = ',',
|
||||
conflicts_with_all = ["header-flags", "x_pcf", "x_scf"]
|
||||
)]
|
||||
pub flags: Vec<SeHdrFlagName>,
|
||||
|
||||
/// Set control flags using comma-separated flag names.
|
||||
///
|
||||
/// Specify flags to disable using their names.
|
||||
#[arg(
|
||||
long,
|
||||
value_name = "FLAGS",
|
||||
value_delimiter = ',',
|
||||
conflicts_with_all = ["header-flags", "x_pcf", "x_scf"]
|
||||
)]
|
||||
pub disable_flags: Vec<SeHdrFlagName>,
|
||||
|
||||
#[clap(flatten)]
|
||||
pub experimental_args: CreateBootImageExperimentalArgs,
|
||||
}
|
||||
@@ -734,14 +891,44 @@ mod test {
|
||||
// --comm-key with --enable-cck-update (alias test)
|
||||
flat_map_collect(insert(mvca.clone(), vec![CliOption::new("comm-key", ["--comm-key", "/dev/null"]),
|
||||
CliOption::new("enable-cck-update", ["--enable-cck-update"])])),
|
||||
|
||||
// --disable-flags tests
|
||||
// Test --disable-flags alone
|
||||
flat_map_collect(insert(mvca.clone(), vec![CliOption::new("disable-flags", ["--disable-flags", &SeHdrFlagName::PckmoHmac.to_string()])])),
|
||||
// Test --flags and --disable-flags without conflict
|
||||
flat_map_collect(insert(mvca.clone(), vec![
|
||||
CliOption::new("flags", ["--flags", &SeHdrFlagName::ConfidentialDump.to_string()]),
|
||||
CliOption::new("disable-flags", ["--disable-flags", &SeHdrFlagName::PckmoHmac.to_string()]),
|
||||
CliOption::new("cck", ["--cck", "/dev/null"])
|
||||
])),
|
||||
// Test multiple --disable-flags
|
||||
flat_map_collect(insert(mvca.clone(), vec![CliOption::new("disable-flags", ["--disable-flags", &format!("{},{}", SeHdrFlagName::PckmoHmac, SeHdrFlagName::BackupTargetKeys)])])),
|
||||
// Test --flags and --disable-flags with different flags
|
||||
flat_map_collect(insert(mvca.clone(), vec![
|
||||
CliOption::new("flags", ["--flags", &format!("{},{}", SeHdrFlagName::ConfidentialDump, SeHdrFlagName::BackupTargetKeys)]),
|
||||
CliOption::new("disable-flags", ["--disable-flags", &format!("{},{}", SeHdrFlagName::PckmoHmac, SeHdrFlagName::NoComponentEncryption)]),
|
||||
CliOption::new("cck", ["--cck", "/dev/null"])
|
||||
])),
|
||||
|
||||
// --flags tests (equivalent to --enable-* tests)
|
||||
// Test --flags with confidential-dump (equivalent to --enable-dump)
|
||||
flat_map_collect(insert(mvca.clone(), vec![
|
||||
CliOption::new("flags", ["--flags", &SeHdrFlagName::ConfidentialDump.to_string()]),
|
||||
CliOption::new("cck", ["--cck", "/dev/null"])
|
||||
])),
|
||||
// Test with all PCKMO flags
|
||||
flat_map_collect(insert(mvca.clone(), vec![CliOption::new("flags", ["--flags", &format!("{},{},{},{}",
|
||||
SeHdrFlagName::PckmoDeaTdea, SeHdrFlagName::PckmoAes, SeHdrFlagName::PckmoEcc, SeHdrFlagName::PckmoHmac)])])),
|
||||
|
||||
// Test with NoComponentEncryption flag
|
||||
flat_map_collect(insert(mvca.clone(), vec![CliOption::new("flags", ["--flags", &SeHdrFlagName::NoComponentEncryption.to_string()])])),
|
||||
];
|
||||
let invalid_create_args = [
|
||||
flat_map_collect(remove(mvcanv.clone(), "no-verify")),
|
||||
flat_map_collect(remove(mvcanv.clone(), "image")),
|
||||
flat_map_collect(remove(mvcanv.clone(), "hkd")),
|
||||
flat_map_collect(remove(mvcanv, "output")),
|
||||
|
||||
// missing both `--cck' and `--enable-cck-update'
|
||||
// missing both `--cck' and `--enable-cck-update' (required by --enable-dump)
|
||||
flat_map_collect(insert(mvca.clone(), vec![CliOption::new("enable-dump", ["--enable-dump"])])),
|
||||
|
||||
// -v and -q cannot be combined
|
||||
@@ -783,6 +970,51 @@ mod test {
|
||||
flat_map_collect(insert(mvca.clone(), vec![CliOption::new("enable-cck-extension-secret", ["--enable-cck-extension-secret"]),
|
||||
CliOption::new("enable-cck-update", ["--enable-cck-update"]),
|
||||
CliOption::new("cck", ["--cck", "/dev/null"])])),
|
||||
|
||||
// --disable-flags conflict tests
|
||||
// Test conflict between --flags and --disable-flags (same flag in both)
|
||||
flat_map_collect(insert(mvca.clone(), vec![
|
||||
CliOption::new("flags", ["--flags", &SeHdrFlagName::ConfidentialDump.to_string()]),
|
||||
CliOption::new("disable-flags", ["--disable-flags", &SeHdrFlagName::ConfidentialDump.to_string()]),
|
||||
CliOption::new("cck", ["--cck", "/dev/null"])
|
||||
])),
|
||||
// Test multiple conflicts
|
||||
flat_map_collect(insert(mvca.clone(), vec![
|
||||
CliOption::new("flags", ["--flags", &format!("{},{}", SeHdrFlagName::ConfidentialDump, SeHdrFlagName::PckmoHmac)]),
|
||||
CliOption::new("disable-flags", ["--disable-flags", &format!("{},{}", SeHdrFlagName::ConfidentialDump, SeHdrFlagName::PckmoHmac)]),
|
||||
CliOption::new("cck", ["--cck", "/dev/null"])
|
||||
])),
|
||||
|
||||
// --flags conflicts with --x-pcf
|
||||
flat_map_collect(insert(mvca.clone(), vec![
|
||||
CliOption::new("flags", ["--flags", &SeHdrFlagName::ConfidentialDump.to_string()]),
|
||||
CliOption::new("x-pcf", ["--x-pcf", "0x0"]),
|
||||
CliOption::new("cck", ["--cck", "/dev/null"])
|
||||
])),
|
||||
// --flags conflicts with --x-scf
|
||||
flat_map_collect(insert(mvca.clone(), vec![
|
||||
CliOption::new("flags", ["--flags", &SeHdrFlagName::ConfidentialDump.to_string()]),
|
||||
CliOption::new("x-scf", ["--x-scf", "0x0"]),
|
||||
CliOption::new("cck", ["--cck", "/dev/null"])
|
||||
])),
|
||||
// --disable-flags conflicts with --x-pcf
|
||||
flat_map_collect(insert(mvca.clone(), vec![
|
||||
CliOption::new("disable-flags", ["--disable-flags", &SeHdrFlagName::PckmoHmac.to_string()]),
|
||||
CliOption::new("x-pcf", ["--x-pcf", "0x0"])
|
||||
])),
|
||||
// --disable-flags conflicts with --x-scf
|
||||
flat_map_collect(insert(mvca.clone(), vec![
|
||||
CliOption::new("disable-flags", ["--disable-flags", &SeHdrFlagName::PckmoHmac.to_string()]),
|
||||
CliOption::new("x-scf", ["--x-scf", "0x0"])
|
||||
])),
|
||||
|
||||
// Test --flags with cck-extension-secret and cck-update and --cck
|
||||
// (conflict, equivalent to --enable-cck-extension-secret)
|
||||
flat_map_collect(insert(mvca, vec![
|
||||
CliOption::new("flags-cck-extension-secret", ["--flags", &SeHdrFlagName::CckExtensionSecretEnforcement.to_string()]),
|
||||
CliOption::new("flags-enable-cck-update", ["--flags", &SeHdrFlagName::CckUpdate.to_string()]),
|
||||
CliOption::new("cck", ["--cck", "/dev/null"])
|
||||
])),
|
||||
];
|
||||
|
||||
let mut genprotimg_valid_args = vec![
|
||||
@@ -825,7 +1057,11 @@ mod test {
|
||||
|
||||
for arg in pvimg_invalid_args {
|
||||
let res = CliOptions::try_parse_from(&arg);
|
||||
assert!(res.is_err());
|
||||
// For some conflict tests, parsing succeeds but validation should fail
|
||||
if let Ok(opts) = res {
|
||||
// This should be caught by validate_cli
|
||||
assert!(validate_cli(&opts).is_err(), "Expected validation to fail for conflicting flags");
|
||||
}
|
||||
}
|
||||
|
||||
for arg in genprotimg_valid_args {
|
||||
@@ -840,7 +1076,12 @@ mod test {
|
||||
|
||||
for arg in genprotimg_invalid_args {
|
||||
let res = GenprotimgCliOptions::try_parse_from(&arg);
|
||||
assert!(res.is_err());
|
||||
// For conflict tests, parsing succeeds but validation should fail
|
||||
if let Ok(genprotimg_opts) = res {
|
||||
let opts: CliOptions = genprotimg_opts.into();
|
||||
// This should be caught by validate_cli
|
||||
assert!(validate_cli(&opts).is_err(), "Expected validation to fail for conflicting flags");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,18 +5,18 @@
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::BufReader;
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use log::{info, debug, warn};
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use log::{debug, info, warn};
|
||||
use pv::misc::{open_file, try_parse_u64};
|
||||
use pvimg::error::OwnExitCode;
|
||||
use pvimg::secured_comp::ComponentTrait;
|
||||
use pvimg::uvdata::{
|
||||
ControlFlagTrait, ControlFlagsTrait, FlagData, PcfV1, PlaintextControlFlagsV1, ScfV1,
|
||||
SeHdrDataV1, SecretControlFlagsV1,
|
||||
EffectiveControlFlags, FlagState, FlagsOverride, SeHdrControlFlags, SeHdrControlFlagsModel,
|
||||
SeHdrDataV1, SeHdrFlag, SeHdrVersion, SeTarget,
|
||||
};
|
||||
use utils::{AtomicFile, AtomicFileOperation};
|
||||
|
||||
use crate::cli::{ComponentPaths, CreateBootImageArgs};
|
||||
use crate::cli::{ComponentPaths, CreateBootImageArgs, SeHdrFlagName};
|
||||
use crate::cmd::common::read_user_provided_keys;
|
||||
use crate::se_img::{SeHdrArgs, SeImgBuilder};
|
||||
use crate::se_img_comps::cmdline::Cmdline;
|
||||
@@ -24,6 +24,21 @@ use crate::se_img_comps::kernel::S390Kernel;
|
||||
use crate::se_img_comps::ramdisk::Ramdisk;
|
||||
use crate::se_img_comps::{check_components, Component};
|
||||
|
||||
/// Convert CLI flag name to internal SeHdrFlag
|
||||
fn convert_flag_name(name: SeHdrFlagName) -> SeHdrFlag {
|
||||
match name {
|
||||
SeHdrFlagName::ConfidentialDump => SeHdrFlag::ConfidentialDump,
|
||||
SeHdrFlagName::PckmoDeaTdea => SeHdrFlag::PckmoDeaTdea,
|
||||
SeHdrFlagName::PckmoAes => SeHdrFlag::PckmoAes,
|
||||
SeHdrFlagName::PckmoEcc => SeHdrFlag::PckmoEcc,
|
||||
SeHdrFlagName::PckmoHmac => SeHdrFlag::PckmoHmac,
|
||||
SeHdrFlagName::BackupTargetKeys => SeHdrFlag::BackupTargetKeys,
|
||||
SeHdrFlagName::CckExtensionSecretEnforcement => SeHdrFlag::CckExtensionSecretEnforcement,
|
||||
SeHdrFlagName::CckUpdate => SeHdrFlag::CckUpdate,
|
||||
SeHdrFlagName::NoComponentEncryption => SeHdrFlag::NoComponentEncryption,
|
||||
}
|
||||
}
|
||||
|
||||
/// The returned vector is sorted by the occurrence in the memory layout:
|
||||
/// First the kernel, then the ramdisk and then the kernel cmdline.
|
||||
///
|
||||
@@ -43,76 +58,218 @@ fn components(component_args: &ComponentPaths) -> Result<Vec<Component>> {
|
||||
Ok(components)
|
||||
}
|
||||
|
||||
fn parse_flags(
|
||||
args: &CreateBootImageArgs,
|
||||
) -> Result<(PlaintextControlFlagsV1, SecretControlFlagsV1)> {
|
||||
let lf = &args.legacy_flags;
|
||||
/// Parse new-style flags (--flags and --disable-flags)
|
||||
fn parse_new_style_flags(
|
||||
flags: &[SeHdrFlagName],
|
||||
disable_flags: &[SeHdrFlagName],
|
||||
version: SeHdrVersion,
|
||||
) -> Result<(FlagsOverride<SeHdrFlag>, FlagsOverride<SeHdrFlag>)> {
|
||||
let target = SeTarget::from_se_hdr_version(version);
|
||||
let mut pcf_overrides: FlagsOverride<SeHdrFlag> = FlagsOverride::new();
|
||||
let mut scf_overrides: FlagsOverride<SeHdrFlag> = FlagsOverride::new();
|
||||
|
||||
if flags.is_empty() && disable_flags.is_empty() {
|
||||
return Ok((pcf_overrides, scf_overrides));
|
||||
}
|
||||
|
||||
let pcf_model = SeHdrControlFlagsModel::pcf_for_target(target);
|
||||
let scf_model = SeHdrControlFlagsModel::scf_for_target(target);
|
||||
let pcf_supported = pcf_model.supported_flags();
|
||||
let scf_supported = scf_model.supported_flags();
|
||||
|
||||
// Helper function to process flags
|
||||
let mut process_flags =
|
||||
|flag_list: &[SeHdrFlagName], enable: bool, flag_type: &str| -> Result<()> {
|
||||
if flag_list.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let converted_flags: Vec<SeHdrFlag> =
|
||||
flag_list.iter().map(|&f| convert_flag_name(f)).collect();
|
||||
|
||||
for flag in &converted_flags {
|
||||
if pcf_supported.contains(flag) {
|
||||
if enable {
|
||||
pcf_overrides.enable(*flag);
|
||||
} else {
|
||||
pcf_overrides.disable(*flag);
|
||||
}
|
||||
}
|
||||
if scf_supported.contains(flag) {
|
||||
if enable {
|
||||
scf_overrides.enable(*flag);
|
||||
} else {
|
||||
scf_overrides.disable(*flag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if all flags were consumed (supported by either pcf or scf)
|
||||
let unsupported_flags: Vec<&SeHdrFlag> = converted_flags
|
||||
.iter()
|
||||
.filter(|flag| !pcf_supported.contains(flag) && !scf_supported.contains(flag))
|
||||
.collect();
|
||||
|
||||
if !unsupported_flags.is_empty() {
|
||||
return Err(anyhow!(
|
||||
"The following {} are not supported for SE header version {:?}: {:?}",
|
||||
flag_type,
|
||||
version,
|
||||
unsupported_flags
|
||||
));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
};
|
||||
|
||||
process_flags(flags, true, "flags")?;
|
||||
process_flags(disable_flags, false, "disable flags")?;
|
||||
|
||||
Ok((pcf_overrides, scf_overrides))
|
||||
}
|
||||
|
||||
/// Parse legacy-style flags
|
||||
fn parse_legacy_flags(
|
||||
legacy_flags: &crate::cli::CreateBootImageLegacyFlags,
|
||||
) -> (FlagsOverride<SeHdrFlag>, FlagsOverride<SeHdrFlag>) {
|
||||
macro_rules! flag_disabled {
|
||||
($cli_flag:expr, $control_flags:expr) => {
|
||||
$cli_flag
|
||||
.filter(|x| *x)
|
||||
.and(Some(ControlFlagTrait::all_disabled($control_flags)))
|
||||
$cli_flag.filter(|x| *x).map(|_| {
|
||||
let mut flags = FlagsOverride::new();
|
||||
flags.disable_all($control_flags);
|
||||
flags
|
||||
})
|
||||
};
|
||||
}
|
||||
macro_rules! flag_enabled {
|
||||
($cli_flag:expr, $control_flags:expr) => {
|
||||
$cli_flag
|
||||
.filter(|x| *x)
|
||||
.and(Some(ControlFlagTrait::all_enabled($control_flags)))
|
||||
$cli_flag.filter(|x| *x).map(|_| {
|
||||
let mut flags = FlagsOverride::new();
|
||||
flags.enable_all($control_flags);
|
||||
flags
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
let plaintext_flags: Vec<FlagData<PcfV1>> = [
|
||||
flag_disabled!(lf.disable_dump, [PcfV1::AllowDumping]),
|
||||
flag_enabled!(lf.enable_dump, [PcfV1::AllowDumping]),
|
||||
flag_disabled!(lf.disable_pckmo, PlaintextControlFlagsV1::PCKMO),
|
||||
flag_enabled!(lf.enable_pckmo, PlaintextControlFlagsV1::PCKMO),
|
||||
flag_disabled!(lf.disable_pckmo_hmac, [PcfV1::PckmoHmac]),
|
||||
flag_enabled!(lf.enable_pckmo_hmac, [PcfV1::PckmoHmac]),
|
||||
flag_disabled!(lf.disable_backup_keys, [PcfV1::BackupTargetKeys]),
|
||||
flag_enabled!(lf.enable_backup_keys, [PcfV1::BackupTargetKeys]),
|
||||
flag_enabled!(lf.disable_image_encryption, [PcfV1::NoComponentEncryption]),
|
||||
flag_disabled!(lf.enable_image_encryption, [PcfV1::NoComponentEncryption]),
|
||||
]
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.flatten()
|
||||
.collect();
|
||||
// This is ensured by Clap's `conflicts_with`.
|
||||
assert!(PlaintextControlFlagsV1::no_duplicates(&plaintext_flags));
|
||||
|
||||
let secret_flags: Vec<FlagData<ScfV1>> = [
|
||||
let pcf_overrides = [
|
||||
flag_disabled!(legacy_flags.disable_dump, [SeHdrFlag::ConfidentialDump]),
|
||||
flag_enabled!(legacy_flags.enable_dump, [SeHdrFlag::ConfidentialDump]),
|
||||
flag_disabled!(legacy_flags.disable_pckmo, SeHdrControlFlagsModel::PCKMO),
|
||||
flag_enabled!(legacy_flags.enable_pckmo, SeHdrControlFlagsModel::PCKMO),
|
||||
flag_disabled!(legacy_flags.disable_pckmo_hmac, [SeHdrFlag::PckmoHmac]),
|
||||
flag_enabled!(legacy_flags.enable_pckmo_hmac, [SeHdrFlag::PckmoHmac]),
|
||||
flag_disabled!(
|
||||
lf.disable_cck_extension_secret,
|
||||
[ScfV1::CckExtensionSecretEnforcement]
|
||||
legacy_flags.disable_backup_keys,
|
||||
[SeHdrFlag::BackupTargetKeys]
|
||||
),
|
||||
flag_enabled!(
|
||||
lf.enable_cck_extension_secret,
|
||||
[ScfV1::CckExtensionSecretEnforcement]
|
||||
legacy_flags.enable_backup_keys,
|
||||
[SeHdrFlag::BackupTargetKeys]
|
||||
),
|
||||
flag_enabled!(
|
||||
legacy_flags.disable_image_encryption,
|
||||
[SeHdrFlag::NoComponentEncryption]
|
||||
),
|
||||
flag_disabled!(
|
||||
legacy_flags.enable_image_encryption,
|
||||
[SeHdrFlag::NoComponentEncryption]
|
||||
),
|
||||
flag_disabled!(lf.disable_cck_update, [ScfV1::CckUpdateAllowed]),
|
||||
flag_enabled!(lf.enable_cck_update, [ScfV1::CckUpdateAllowed]),
|
||||
]
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.fold(FlagsOverride::new(), |mut acc, override_set| {
|
||||
for (flag, state) in override_set.iter() {
|
||||
match state {
|
||||
FlagState::Enabled => acc.enable(*flag),
|
||||
FlagState::Disabled => acc.disable(*flag),
|
||||
}
|
||||
}
|
||||
acc
|
||||
});
|
||||
|
||||
let scf_overrides = [
|
||||
flag_disabled!(
|
||||
legacy_flags.disable_cck_extension_secret,
|
||||
[SeHdrFlag::CckExtensionSecretEnforcement]
|
||||
),
|
||||
flag_enabled!(
|
||||
legacy_flags.enable_cck_extension_secret,
|
||||
[SeHdrFlag::CckExtensionSecretEnforcement]
|
||||
),
|
||||
flag_disabled!(legacy_flags.disable_cck_update, [SeHdrFlag::CckUpdate]),
|
||||
flag_enabled!(legacy_flags.enable_cck_update, [SeHdrFlag::CckUpdate]),
|
||||
]
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.collect();
|
||||
// This is ensured by Clap's `conflicts_with`.
|
||||
assert!(SecretControlFlagsV1::no_duplicates(&secret_flags));
|
||||
.fold(FlagsOverride::new(), |mut acc, override_set| {
|
||||
for (flag, state) in override_set.iter() {
|
||||
match state {
|
||||
FlagState::Enabled => acc.enable(*flag),
|
||||
FlagState::Disabled => acc.disable(*flag),
|
||||
}
|
||||
}
|
||||
acc
|
||||
});
|
||||
|
||||
let mut pcf: PlaintextControlFlagsV1 = match &args.experimental_args.x_pcf {
|
||||
Some(v) => try_parse_u64(v, "x-pcf")?.into(),
|
||||
None => PlaintextControlFlagsV1::default(),
|
||||
};
|
||||
pcf.parse_flags(&plaintext_flags);
|
||||
info!("Using plaintext flags: {pcf:#x}");
|
||||
(pcf_overrides, scf_overrides)
|
||||
}
|
||||
|
||||
let mut scf: SecretControlFlagsV1 = match &args.experimental_args.x_scf {
|
||||
Some(v) => try_parse_u64(v, "x-scf")?.into(),
|
||||
None => SecretControlFlagsV1::default(),
|
||||
/// Apply experimental overrides to control flags
|
||||
fn apply_experimental_overrides(
|
||||
pcf_overrides: &FlagsOverride<SeHdrFlag>,
|
||||
scf_overrides: &FlagsOverride<SeHdrFlag>,
|
||||
x_pcf: &Option<String>,
|
||||
x_scf: &Option<String>,
|
||||
target: SeTarget,
|
||||
) -> Result<(
|
||||
EffectiveControlFlags<SeHdrFlag>,
|
||||
EffectiveControlFlags<SeHdrFlag>,
|
||||
)> {
|
||||
let pcf = match x_pcf {
|
||||
Some(v) => {
|
||||
assert_eq!(pcf_overrides.len(), 0);
|
||||
SeHdrControlFlags::from_u64(try_parse_u64(v, "x-pcf")?, target, true)
|
||||
}
|
||||
None => SeHdrControlFlagsModel::pcf_for_target(target).with_overrides(pcf_overrides)?,
|
||||
};
|
||||
scf.parse_flags(&secret_flags);
|
||||
info!("Using secret flags: {scf:#x}");
|
||||
|
||||
let scf = match x_scf {
|
||||
Some(v) => {
|
||||
assert_eq!(scf_overrides.len(), 0);
|
||||
SeHdrControlFlags::from_u64(try_parse_u64(v, "x-scf")?, target, false)
|
||||
}
|
||||
None => SeHdrControlFlagsModel::scf_for_target(target).with_overrides(scf_overrides)?,
|
||||
};
|
||||
|
||||
Ok((pcf, scf))
|
||||
}
|
||||
|
||||
fn parse_flags(
|
||||
args: &CreateBootImageArgs,
|
||||
version: SeHdrVersion,
|
||||
) -> Result<(
|
||||
EffectiveControlFlags<SeHdrFlag>,
|
||||
EffectiveControlFlags<SeHdrFlag>,
|
||||
)> {
|
||||
let target = SeTarget::from_se_hdr_version(version);
|
||||
|
||||
// Legacy flags and --(disable-)flags are mutually exclusive. Clap semantics
|
||||
// is used for that.
|
||||
let (pcf_overrides, scf_overrides) = if args.flags.is_empty() && args.disable_flags.is_empty() {
|
||||
parse_legacy_flags(&args.legacy_flags)
|
||||
} else {
|
||||
parse_new_style_flags(&args.flags, &args.disable_flags, version)?
|
||||
};
|
||||
|
||||
let (pcf, scf) = apply_experimental_overrides(
|
||||
&pcf_overrides,
|
||||
&scf_overrides,
|
||||
&args.experimental_args.x_pcf,
|
||||
&args.experimental_args.x_scf,
|
||||
target,
|
||||
)?;
|
||||
info!("Using plaintext flags:\n{pcf}");
|
||||
info!("Using secret flags:\n{scf}");
|
||||
|
||||
Ok((pcf, scf))
|
||||
}
|
||||
@@ -125,9 +282,9 @@ pub fn create(opt: &CreateBootImageArgs) -> Result<OwnExitCode> {
|
||||
.certificate_args
|
||||
.get_verified_hkds("Secure Execution image")?;
|
||||
let user_provided_keys = read_user_provided_keys(&opt.keys)?;
|
||||
let (plaintext_flags, secret_flags) = parse_flags(opt)?;
|
||||
let (plaintext_flags, secret_flags) = parse_flags(opt, SeHdrVersion::V1)?;
|
||||
|
||||
if plaintext_flags.is_set(PcfV1::NoComponentEncryption) {
|
||||
if plaintext_flags.has(SeHdrFlag::NoComponentEncryption) {
|
||||
warn!("The components encryption is disabled, make sure that the components do not contain any confidential content.");
|
||||
}
|
||||
|
||||
@@ -144,7 +301,7 @@ pub fn create(opt: &CreateBootImageArgs) -> Result<OwnExitCode> {
|
||||
let mut writer = AtomicFile::with_extension(&opt.output, "part", &mut OpenOptions::new())?;
|
||||
let mut seimg_ctx = SeImgBuilder::new_v1(
|
||||
&mut writer,
|
||||
plaintext_flags.is_unset(PcfV1::NoComponentEncryption),
|
||||
!plaintext_flags.has(SeHdrFlag::NoComponentEncryption),
|
||||
Some(expected_se_hdr_size),
|
||||
opt.experimental_args.x_bootloader_directory.as_ref(),
|
||||
)?;
|
||||
@@ -218,13 +375,104 @@ mod test {
|
||||
},
|
||||
..Default::default()
|
||||
};
|
||||
let parsed_flags = super::parse_flags(&args).expect("Failed to parse flags {args:?}");
|
||||
let mut exp_pcf = Vec::from(PlaintextControlFlagsV1::PCKMO);
|
||||
exp_pcf.push(PcfV1::AllowDumping);
|
||||
let pcf = PlaintextControlFlagsV1::from_flags(PcfV1::all_enabled(exp_pcf));
|
||||
assert_eq!(parsed_flags.0, pcf);
|
||||
let exp_scf = vec![ScfV1::CckUpdateAllowed];
|
||||
let scf = SecretControlFlagsV1::from_flags(ScfV1::all_enabled(exp_scf));
|
||||
assert_eq!(parsed_flags.1, scf);
|
||||
let parsed_flags =
|
||||
super::parse_flags(&args, SeHdrVersion::V1).expect("Failed to parse flags {args:?}");
|
||||
|
||||
// Build expected PCF
|
||||
let mut exp_pcf = Vec::from(SeHdrControlFlagsModel::PCKMO);
|
||||
exp_pcf.push(SeHdrFlag::ConfidentialDump);
|
||||
let mut pcf_overrides = FlagsOverride::new();
|
||||
for flag in &exp_pcf {
|
||||
pcf_overrides.enable(*flag);
|
||||
}
|
||||
let expected_pcf = SeHdrControlFlagsModel::pcf_for_target(SeTarget::V1Max)
|
||||
.with_overrides(&pcf_overrides)
|
||||
.expect("Failed to create expected PCF");
|
||||
assert_eq!(parsed_flags.0, expected_pcf);
|
||||
|
||||
// Build expected SCF
|
||||
let exp_scf = vec![SeHdrFlag::CckUpdate];
|
||||
let mut scf_overrides = FlagsOverride::new();
|
||||
for flag in &exp_scf {
|
||||
scf_overrides.enable(*flag);
|
||||
}
|
||||
let expected_scf = SeHdrControlFlagsModel::scf_for_target(SeTarget::V1Max)
|
||||
.with_overrides(&scf_overrides)
|
||||
.expect("Failed to create expected SCF");
|
||||
assert_eq!(parsed_flags.1, expected_scf);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_flags_with_disable_flags_no_conflict() {
|
||||
let args = CreateBootImageArgs {
|
||||
flags: vec![SeHdrFlagName::ConfidentialDump],
|
||||
disable_flags: vec![SeHdrFlagName::PckmoHmac],
|
||||
..Default::default()
|
||||
};
|
||||
let result = super::parse_flags(&args, SeHdrVersion::V1);
|
||||
assert!(result.is_ok());
|
||||
|
||||
let (pcf, scf) = result.unwrap();
|
||||
// ConfidentialDump should be enabled
|
||||
assert!(pcf.has(SeHdrFlag::ConfidentialDump));
|
||||
// PckmoHmac should be disabled
|
||||
assert!(!pcf.has(SeHdrFlag::PckmoHmac));
|
||||
assert_eq!(pcf.to_u64(), 0b100000000000000000000011100000_u64);
|
||||
assert_eq!(scf.to_u64(), 0b0_u64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_flags_with_multiple_disable_flags() {
|
||||
let args = CreateBootImageArgs {
|
||||
disable_flags: vec![SeHdrFlagName::PckmoHmac, SeHdrFlagName::BackupTargetKeys],
|
||||
..Default::default()
|
||||
};
|
||||
let result = super::parse_flags(&args, SeHdrVersion::V1);
|
||||
assert!(result.is_ok());
|
||||
|
||||
let (pcf, _scf) = result.unwrap();
|
||||
// Both flags should be disabled
|
||||
assert!(!pcf.has(SeHdrFlag::PckmoHmac));
|
||||
assert!(!pcf.has(SeHdrFlag::BackupTargetKeys));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_flags_with_only_disable_flags() {
|
||||
let args = CreateBootImageArgs {
|
||||
disable_flags: vec![SeHdrFlagName::PckmoDeaTdea, SeHdrFlagName::PckmoAes],
|
||||
..Default::default()
|
||||
};
|
||||
let result = super::parse_flags(&args, SeHdrVersion::V1);
|
||||
assert!(result.is_ok());
|
||||
|
||||
let (pcf, _scf) = result.unwrap();
|
||||
// PCKMO DEA/TDEA and AES should be disabled
|
||||
assert!(!pcf.has(SeHdrFlag::PckmoDeaTdea));
|
||||
assert!(!pcf.has(SeHdrFlag::PckmoAes));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_flags_enable_and_disable_different_flags() {
|
||||
let args = CreateBootImageArgs {
|
||||
flags: vec![
|
||||
SeHdrFlagName::ConfidentialDump,
|
||||
SeHdrFlagName::BackupTargetKeys,
|
||||
],
|
||||
disable_flags: vec![
|
||||
SeHdrFlagName::PckmoHmac,
|
||||
SeHdrFlagName::NoComponentEncryption,
|
||||
],
|
||||
..Default::default()
|
||||
};
|
||||
let result = super::parse_flags(&args, SeHdrVersion::V1);
|
||||
assert!(result.is_ok());
|
||||
|
||||
let (pcf, _scf) = result.unwrap();
|
||||
// Enabled flags should be set
|
||||
assert!(pcf.has(SeHdrFlag::ConfidentialDump));
|
||||
assert!(pcf.has(SeHdrFlag::BackupTargetKeys));
|
||||
// Disabled flags should not be set
|
||||
assert!(!pcf.has(SeHdrFlag::PckmoHmac));
|
||||
assert!(!pcf.has(SeHdrFlag::NoComponentEncryption));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,11 +36,11 @@ pub mod misc {
|
||||
|
||||
pub mod uvdata {
|
||||
pub use crate::pv_utils::{
|
||||
AeadPlainDataTrait, BuilderTrait, ComponentMetadataV1, ControlFlagTrait, ControlFlagsTrait,
|
||||
EnvelopeSeHdrV1, FlagData, KeyExchangeTrait, PcfV1, PlaintextControlFlagsV1, ScfV1, SeH,
|
||||
SeHdr, SeHdrAadV1, SeHdrBinV1, SeHdrBuilder, SeHdrData, SeHdrDataV1, SeHdrPlain,
|
||||
SeHdrVersion, SeHdrVersioned, SecretControlFlagsV1, UvDataPlainTrait, UvDataTrait,
|
||||
UvKeyHashesV1,
|
||||
AeadPlainDataTrait, BuilderTrait, ComponentMetadataV1, ControlFlagTrait,
|
||||
EffectiveControlFlags, EnvelopeSeHdrV1, FlagData, FlagState, FlagsOverride,
|
||||
IntoEnumIterator, KeyExchangeTrait, SeH, SeHdr, SeHdrAadV1, SeHdrBinV1, SeHdrBuilder,
|
||||
SeHdrControlFlags, SeHdrControlFlagsModel, SeHdrData, SeHdrDataV1, SeHdrFlag, SeHdrPlain,
|
||||
SeHdrVersion, SeHdrVersioned, SeTarget, UvDataPlainTrait, UvDataTrait, UvKeyHashesV1,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -18,9 +18,10 @@ pub use layout::{Interval, Layout};
|
||||
pub use misc::{round_up, try_copy_slice_to_array};
|
||||
pub use psw::{ShortPsw, PSW, PSW_MASK_BA, PSW_MASK_EA};
|
||||
pub use se_hdr::{
|
||||
ComponentMetadataV1, ControlFlagTrait, ControlFlagsTrait, EnvelopeSeHdrV1, FlagData, PcfV1,
|
||||
PlaintextControlFlagsV1, ScfV1, SeH, SeHdr, SeHdrAadV1, SeHdrBinV1, SeHdrBuilder, SeHdrData,
|
||||
SeHdrDataV1, SeHdrPlain, SeHdrVersion, SeHdrVersioned, SecretControlFlagsV1,
|
||||
ComponentMetadataV1, ControlFlagTrait, EffectiveControlFlags, EnvelopeSeHdrV1, FlagData,
|
||||
FlagState, FlagsOverride, IntoEnumIterator, SeH, SeHdr, SeHdrAadV1, SeHdrBinV1, SeHdrBuilder,
|
||||
SeHdrControlFlags, SeHdrControlFlagsModel, SeHdrData, SeHdrDataV1, SeHdrFlag, SeHdrPlain,
|
||||
SeHdrVersion, SeHdrVersioned, SeTarget,
|
||||
};
|
||||
pub use secured_comp::{ComponentTrait, SecuredComponent, SecuredComponentBuilder};
|
||||
pub use serializing::{bytesize, serialize_to_bytes};
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
mod brb;
|
||||
mod builder;
|
||||
mod flags;
|
||||
mod generic_flags;
|
||||
mod hdr_v1;
|
||||
mod keys;
|
||||
|
||||
@@ -14,7 +15,8 @@ pub use brb::{
|
||||
};
|
||||
pub use builder::SeHdrBuilder;
|
||||
pub use flags::{
|
||||
ControlFlagTrait, ControlFlagsTrait, FlagData, PcfV1, PlaintextControlFlagsV1, ScfV1,
|
||||
SecretControlFlagsV1,
|
||||
ControlFlagTrait, EffectiveControlFlags, FlagData, FlagState, FlagsOverride, SeHdrControlFlags,
|
||||
SeHdrControlFlagsModel, SeHdrFlag, SeTarget,
|
||||
};
|
||||
pub use generic_flags::IntoEnumIterator;
|
||||
pub use hdr_v1::SeHdrAadV1;
|
||||
|
||||
@@ -15,7 +15,7 @@ use serde::{Deserialize, Serialize};
|
||||
use utils::S390ToolsMetaData;
|
||||
|
||||
pub use super::hdr_v1::{SeHdrBinV1, SeHdrDataV1};
|
||||
use super::{PlaintextControlFlagsV1, SecretControlFlagsV1};
|
||||
use super::{EffectiveControlFlags, SeHdrFlag};
|
||||
use crate::misc::PAGESIZE;
|
||||
use crate::pv_utils::error::{Error, Result};
|
||||
use crate::pv_utils::misc::display_indented;
|
||||
@@ -267,7 +267,7 @@ impl AeadCipherBuilderTrait for SeHdrData {
|
||||
pub trait SeHdrPubBuilderTrait {
|
||||
// Payload related methods
|
||||
fn set_components(&mut self, meta: ComponentMetadata) -> Result<()>;
|
||||
fn set_pcf(&mut self, pcf: &PlaintextControlFlagsV1) -> Result<()>;
|
||||
fn set_pcf(&mut self, pcf: &EffectiveControlFlags<SeHdrFlag>) -> Result<()>;
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
@@ -276,7 +276,7 @@ pub trait SeHdrConfBuilderTrait {
|
||||
fn generate_cck(&self) -> Result<SymKey>;
|
||||
fn set_cck(&mut self, cck: Confidential<Vec<u8>>) -> Result<()>;
|
||||
fn set_psw(&mut self, psw: &PSW);
|
||||
fn set_scf(&mut self, scf: &SecretControlFlagsV1) -> Result<()>;
|
||||
fn set_scf(&mut self, scf: &EffectiveControlFlags<SeHdrFlag>) -> Result<()>;
|
||||
}
|
||||
|
||||
#[enum_dispatch(SeHdr)]
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
use pv::request::Confidential;
|
||||
|
||||
use super::hdr_v1::SeHdrDataV1;
|
||||
use super::SeHdr;
|
||||
use super::{EffectiveControlFlags, SeHdr, SeHdrFlag};
|
||||
use crate::pv_utils::error::{Error, Result};
|
||||
use crate::pv_utils::se_hdr::brb::{
|
||||
SeHdrCommon, SeHdrConfBuilderTrait, SeHdrData, SeHdrPubBuilderTrait,
|
||||
@@ -15,7 +15,7 @@ use crate::pv_utils::uvdata::UvDataPlainTrait;
|
||||
use crate::pv_utils::uvdata_builder::{
|
||||
AeadCipherBuilderTrait, BuilderTrait, KeyExchangeBuilderTrait, UvDataBuilder,
|
||||
};
|
||||
use crate::pv_utils::{PlaintextControlFlagsV1, SecretControlFlagsV1, PSW};
|
||||
use crate::pv_utils::PSW;
|
||||
|
||||
/// `SeHdrBuilder`
|
||||
pub type SeHdrBuilder<'a> = UvDataBuilder<'a, SeHdrPlain>;
|
||||
@@ -67,12 +67,12 @@ impl SeHdrBuilder<'_> {
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
pub fn with_pcf(&mut self, flags: &PlaintextControlFlagsV1) -> Result<&mut Self> {
|
||||
pub fn with_pcf(&mut self, flags: &EffectiveControlFlags<SeHdrFlag>) -> Result<&mut Self> {
|
||||
self.plain_data.data.set_pcf(flags)?;
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
pub fn with_scf(&mut self, flags: &SecretControlFlagsV1) -> Result<&mut Self> {
|
||||
pub fn with_scf(&mut self, flags: &EffectiveControlFlags<SeHdrFlag>) -> Result<&mut Self> {
|
||||
self.plain_data.data.set_scf(flags)?;
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -18,6 +18,7 @@ use serde::{Deserialize, Serialize};
|
||||
use utils::HexSlice;
|
||||
|
||||
use super::keys::phkh_v1;
|
||||
use super::{EffectiveControlFlags, SeHdrControlFlags};
|
||||
use crate::error::Error;
|
||||
use crate::misc::PAGESIZE;
|
||||
use crate::pv_utils::error::Result;
|
||||
@@ -37,9 +38,7 @@ use crate::pv_utils::uvdata::{
|
||||
UvDataTrait,
|
||||
};
|
||||
use crate::pv_utils::uvdata_builder::{AeadCipherBuilderTrait, KeyExchangeBuilderTrait};
|
||||
use crate::pv_utils::{
|
||||
try_copy_slice_to_array, PlaintextControlFlagsV1, SecretControlFlagsV1, PSW,
|
||||
};
|
||||
use crate::pv_utils::{try_copy_slice_to_array, SeHdrFlag, SeTarget, PSW};
|
||||
|
||||
#[derive(Debug)]
|
||||
struct HdrSizesV1 {
|
||||
@@ -100,7 +99,7 @@ impl Display for SeHdrAadV1 {
|
||||
writeln!(
|
||||
f,
|
||||
"plaintext control flags:\n{}",
|
||||
PlaintextControlFlagsV1::from(self.pcf)
|
||||
SeHdrControlFlags::from_u64(self.pcf, SeTarget::V1Max, true)
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
@@ -176,7 +175,7 @@ impl Display for SeHdrConfV1 {
|
||||
writeln!(
|
||||
f,
|
||||
"secret control flags:\n{}",
|
||||
SecretControlFlagsV1::from(self.scf)
|
||||
SeHdrControlFlags::from_u64(self.scf, SeTarget::V1Max, false)
|
||||
)?;
|
||||
|
||||
// Support verbose mode if the `alternate` (`{:#}`) flag is used.
|
||||
@@ -483,8 +482,8 @@ impl SeHdrConfBuilderTrait for SeHdrDataV1 {
|
||||
self.data.value_mut().psw = psw.clone();
|
||||
}
|
||||
|
||||
fn set_scf(&mut self, scf: &SecretControlFlagsV1) -> Result<()> {
|
||||
self.data.value_mut().scf = scf.into();
|
||||
fn set_scf(&mut self, scf: &EffectiveControlFlags<SeHdrFlag>) -> Result<()> {
|
||||
self.data.value_mut().scf = scf.to_u64();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -499,8 +498,8 @@ impl SeHdrConfBuilderTrait for SeHdrDataV1 {
|
||||
}
|
||||
|
||||
impl SeHdrPubBuilderTrait for SeHdrDataV1 {
|
||||
fn set_pcf(&mut self, pcf: &PlaintextControlFlagsV1) -> Result<()> {
|
||||
self.aad.pcf = pcf.into();
|
||||
fn set_pcf(&mut self, pcf: &EffectiveControlFlags<SeHdrFlag>) -> Result<()> {
|
||||
self.aad.pcf = pcf.to_u64();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -18,9 +18,7 @@ use pvimg::misc::{round_up, serialize_to_bytes, ShortPsw, PSW, PSW_MASK_BA, PSW_
|
||||
use pvimg::secured_comp::{
|
||||
ComponentTrait, Interval, Layout, SecuredComponent, SecuredComponentBuilder,
|
||||
};
|
||||
use pvimg::uvdata::{
|
||||
BuilderTrait, PlaintextControlFlagsV1, SeHdrBuilder, SeHdrVersion, SecretControlFlagsV1,
|
||||
};
|
||||
use pvimg::uvdata::{BuilderTrait, EffectiveControlFlags, SeHdrBuilder, SeHdrFlag, SeHdrVersion};
|
||||
|
||||
use crate::se_img_comps::ipib::Ipib;
|
||||
use crate::se_img_comps::kernel::S390Kernel;
|
||||
@@ -34,8 +32,8 @@ use crate::se_img_comps::{
|
||||
|
||||
pub struct SeHdrArgs<'a> {
|
||||
pub keys: &'a [PKey<Public>],
|
||||
pub pcf: &'a PlaintextControlFlagsV1,
|
||||
pub scf: &'a SecretControlFlagsV1,
|
||||
pub pcf: &'a EffectiveControlFlags<SeHdrFlag>,
|
||||
pub scf: &'a EffectiveControlFlags<SeHdrFlag>,
|
||||
pub cck: &'a Option<(PathBuf, Confidential<Vec<u8>>)>,
|
||||
pub hdr_aead_key: &'a Option<(PathBuf, Confidential<Vec<u8>>)>,
|
||||
pub psw_addr: &'a Option<u64>,
|
||||
|
||||
Reference in New Issue
Block a user