diff --git a/rust/pvimg/man/pvimg-create.1 b/rust/pvimg/man/pvimg-create.1 index dd232083..844ae72f 100644 --- a/rust/pvimg/man/pvimg-create.1 +++ b/rust/pvimg/man/pvimg-create.1 @@ -3,7 +3,7 @@ .\" it under the terms of the MIT license. See LICENSE for details. .\" -.TH "PVIMG-CREATE" "1" "2024-12-19" "s390-tools" "Pvimg Manual" +.TH "PVIMG-CREATE" "1" "2025-04-24" "s390-tools" "Pvimg Manual" .nh .ad l .SH NAME @@ -139,7 +139,7 @@ Secure Execution header protection key is a randomly generated key. \-\-enable\-dump .RS 4 Enable Secure Execution guest dump support. This option requires the -\fB\-\-cck\fR option. +\fB\-\-cck\fR or \fB\-\-enable\-cck\-update\fR option. .RE .RE .PP @@ -163,6 +163,19 @@ Add\-secret requests don't have to provide the CCK\-derived extension secret .RE .RE .PP +\-\-enable\-cck\-update +.RS 4 +Enable CCK update support. Requires z17 or up. This option cannot be +used in conjunction with the \fB\-\-enable\-cck\-extension\-secret\fR option. +.RE +.RE +.PP +\-\-disable\-cck\-update +.RS 4 +Disable CCK update support (default). +.RE +.RE +.PP \-\-enable\-pckmo .RS 4 Enable the support for the DEA, TDEA, AES, and ECC PCKMO key encryption diff --git a/rust/pvimg/src/cli.rs b/rust/pvimg/src/cli.rs index 1431acba..4bab0b06 100644 --- a/rust/pvimg/src/cli.rs +++ b/rust/pvimg/src/cli.rs @@ -95,11 +95,13 @@ pub struct ComponentPaths { #[derive(Args, Debug)] #[cfg_attr(test, derive(Default))] -#[command(group(ArgGroup::new("header-flags").multiple(true).conflicts_with_all(["x_pcf", "x_scf"])))] +#[command( + group(ArgGroup::new("header-flags").multiple(true).conflicts_with_all(["x_pcf", "x_scf"])), + group(ArgGroup::new("cck-available").multiple(true)))] pub struct CreateBootImageLegacyFlags { /// Enable Secure Execution guest dump support. This option requires the - /// '--cck' option. - #[arg(long, action = clap::ArgAction::SetTrue, requires="cck", group="header-flags")] + /// '--cck' or '--enable-cck-update' option. + #[arg(long, action = clap::ArgAction::SetTrue, requires = "cck-available", group="header-flags")] pub enable_dump: Option, /// Disable Secure Execution guest dump support (default). @@ -117,6 +119,15 @@ pub struct CreateBootImageLegacyFlags { #[arg(long, action = clap::ArgAction::SetTrue, conflicts_with="enable_cck_extension_secret", group="header-flags")] pub disable_cck_extension_secret: Option, + /// Enable CCK update support. Requires z17 or up. This option cannot be + /// used in conjunction with the '--enable-cck-extension-secret' option. + #[arg(long, action = clap::ArgAction::SetTrue, conflicts_with="enable_cck_extension_secret", group="cck-available", group="header-flags")] + pub enable_cck_update: Option, + + /// Disable CCK update support (default). + #[arg(long, action = clap::ArgAction::SetTrue, conflicts_with="enable_cck_update", group="header-flags")] + pub disable_cck_update: Option, + /// Enable the support for the DEA, TDEA, AES, and ECC PCKMO key encryption /// functions (default). #[arg(long, action = clap::ArgAction::SetTrue, group="header-flags")] @@ -335,7 +346,12 @@ pub struct CreateBootImageArgs { /// /// The file must contain exactly 32 bytes of data. This option used to be /// called '--comm-key' in previous versions. - #[arg(long, value_name = "FILE", visible_alias = "comm-key")] + #[arg( + long, + value_name = "FILE", + group = "cck-available", + visible_alias = "comm-key" + )] pub cck: Option, /// Use the content of FILE as the Secure Execution header protection key. @@ -495,7 +511,8 @@ mod test { flat_map_collect(insert(mvca.clone(), vec![CliOption::new("enable-dump", ["--enable-dump"]), CliOption::new("comm-key", ["--cck", "/dev/null"])])), flat_map_collect(insert(mvca.clone(), vec![CliOption::new("enable-dump", ["--enable-dump"]), - CliOption::new("comm-key", ["--comm-key", "/dev/null"])])), + CliOption::new("comm-key", ["--comm-key", "/dev/null"]), + CliOption::new("enable-cck-update", ["--enable-cck-update"])])), flat_map_collect(insert(mvca.clone(), vec![CliOption::new("x-pcf", ["--x-pcf", "0x0"]), CliOption::new("x-scf", ["--x-scf", "0x0"])])), flat_map_collect(insert(mvca.clone(), vec![CliOption::new("x-psw", ["--x-psw", "0x0"])])), @@ -507,6 +524,9 @@ mod test { flat_map_collect(insert(mvca.clone(), vec![CliOption::new("enable-image-encryption", ["--enable-image-encryption"])])), flat_map_collect(insert(mvca.clone(), vec![CliOption::new("x-header-key", ["--x-header-key", "/dev/null"]),])), flat_map_collect(insert(mvca.clone(), vec![CliOption::new("x-header-key", ["--hdr-key", "/dev/null"]),])), + flat_map_collect(insert(mvca.clone(), vec![CliOption::new("enable-cck-update", ["--enable-cck-update"])])), + flat_map_collect(insert(mvca.clone(), vec![CliOption::new("disable-cck-update", ["--disable-cck-update"])])), + flat_map_collect(insert(mvca.clone(), vec![CliOption::new("multiple-cck", ["--disable-cck-update", "--cck", "/dev/null"])])), ]; let invalid_create_args = [ flat_map_collect(remove(mvcanv.clone(), "no-verify")), @@ -514,7 +534,7 @@ mod test { flat_map_collect(remove(mvcanv.clone(), "hkd")), flat_map_collect(remove(mvcanv, "output")), - // missing `--comm-key` + // missing both `--cck' and `--enable-cck-update' flat_map_collect(insert(mvca.clone(), vec![CliOption::new("enable-dump", ["--enable-dump"])])), // -v and -q cannot be combined @@ -535,6 +555,9 @@ mod test { flat_map_collect(insert(mvca.clone(), vec![CliOption::new("enable-image-encryption", ["--enable-image-encryption"]), CliOption::new("disable-image-encryption", ["--disable-image-encryption"])])), flat_map_collect(insert(mvca.clone(), vec![CliOption::new("x-header-key", ["--hdr-key"]),])), + flat_map_collect(insert(mvca.clone(), vec![CliOption::new("extension", ["--enable-cck-extension-secret"]), + CliOption::new("update", ["--enable-cck-update"])])), + ]; let mut genprotimg_valid_args = vec![ diff --git a/rust/pvimg/src/cmd/create.rs b/rust/pvimg/src/cmd/create.rs index f2ae5d03..40afcee7 100644 --- a/rust/pvimg/src/cmd/create.rs +++ b/rust/pvimg/src/cmd/create.rs @@ -92,6 +92,8 @@ fn parse_flags( lf.enable_cck_extension_secret, [ScfV1::CckExtensionSecretEnforcement] ), + flag_disabled!(lf.disable_cck_update, [ScfV1::CckUpdateAllowed]), + flag_enabled!(lf.enable_cck_update, [ScfV1::CckUpdateAllowed]), ] .into_iter() .flatten() @@ -217,14 +219,18 @@ mod test { let args = CreateBootImageArgs { legacy_flags: CreateBootImageLegacyFlags { enable_dump: Some(true), + enable_cck_update: Some(true), ..Default::default() }, ..Default::default() }; let parsed_flags = super::parse_flags(&args).expect("Failed to parse flags {args:?}"); - let mut exp_flags = Vec::from(PlaintextControlFlagsV1::PCKMO); - exp_flags.push(PcfV1::AllowDumping); - let pcf = PlaintextControlFlagsV1::from_flags(PcfV1::all_enabled(exp_flags)); + 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); } } diff --git a/rust/pvimg/src/pv_utils/se_hdr/flags.rs b/rust/pvimg/src/pv_utils/se_hdr/flags.rs index 72ac543f..277c3bb1 100644 --- a/rust/pvimg/src/pv_utils/se_hdr/flags.rs +++ b/rust/pvimg/src/pv_utils/se_hdr/flags.rs @@ -205,6 +205,8 @@ impl ControlFlagTrait for PcfV1 {} pub enum ScfV1 { /// All add-secret requests must provide an extension secret CckExtensionSecretEnforcement = 1, + /// Whether CCK can be updated + CckUpdateAllowed = 2, } pub type SecretControlFlagsV1 = ControlFlags; impl ControlFlagTrait for ScfV1 {}