diff --git a/CHANGELOG.md b/CHANGELOG.md index c21bc54f..80138cad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ Release history for s390-tools (MIT version) Changes of existing tools: - genprotimg: Add OpenSSL 3.0 support - genprotimg: Change plaintext control flags defaults so PCKMO functions are allowed + - genprotimg: Add '--(enable|disable)-pckmo' options Bug Fixes: - dbginfo: add KVM data collection for server and guest - fix lszdev diff --git a/genprotimg/man/genprotimg.8 b/genprotimg/man/genprotimg.8 index c08336be..8a481c4b 100644 --- a/genprotimg/man/genprotimg.8 +++ b/genprotimg/man/genprotimg.8 @@ -94,6 +94,14 @@ this only if you trust the specified certificate. Optional. Do not require the host-key documents to be valid. For testing purposes, do not use for a production image. Optional. .TP +\fB\-\-enable\-pckmo\fR +Enable the support for the DEA, TDEA, AES, and ECC PCKMO key encryption +functions. This is the default. Optional. +.TP +\fB\-\-disable\-pckmo\fR +Disable the support for the DEA, TDEA, AES, and ECC PCKMO key encryption +functions. Optional. +.TP \fB\-v\fR, \fB\-\-version\fR Prints version information, then exits. diff --git a/genprotimg/src/pv/pv_args.c b/genprotimg/src/pv/pv_args.c index d48c526b..e644ae7a 100644 --- a/genprotimg/src/pv/pv_args.c +++ b/genprotimg/src/pv/pv_args.c @@ -64,6 +64,13 @@ static gint pv_args_validate_options(PvArgs *args, GError **err) { PvComponentType KERNEL = PV_COMP_TYPE_KERNEL; + if (args->pcf && args->allow_pckmo != PV_NOT_SET) { + g_set_error(err, PV_PARSE_ERROR, PV_PARSE_ERROR_SYNTAX, + _("The '--x-pcf' and '--(enable|disable)-pckmo' options are mutually" + " exclusive.\nUse 'genprotimg --help' for more information")); + return -1; + } + if (args->unused_values->len > 0) { g_autofree gchar *unused = NULL; @@ -181,6 +188,19 @@ static gboolean cb_set_string_option(const gchar *option, const gchar *value, return TRUE; } +static gboolean cb_enable_disable_flag(const gchar *option, const gchar *value G_GNUC_UNUSED, + PvArgs *args, GError **err G_GNUC_UNUSED) +{ + if (g_str_equal(option, "--enable-pckmo")) + args->allow_pckmo = PV_TRUE; + else if (g_str_equal(option, "--disable-pckmo")) + args->allow_pckmo = PV_FALSE; + else + g_assert_not_reached(); + + return TRUE; +} + static gboolean cb_set_log_level(const gchar *option G_GNUC_UNUSED, const gchar *value G_GNUC_UNUSED, PvArgs *args, GError **err G_GNUC_UNUSED) @@ -262,6 +282,21 @@ gint pv_args_parse_options(PvArgs *args, gint *argc, gchar **argv[], .description = _("Use the kernel parameters stored in PARMFILE\n" INDENT "(optional)."), .arg_description = _("PARMFILE") }, + {.long_name = "enable-pckmo", + .short_name = 0, + .flags = G_OPTION_FLAG_NO_ARG, + .arg = G_OPTION_ARG_CALLBACK, + .arg_data = cb_enable_disable_flag, + .description = _("Enable the support for the DEA, TDEA, AES, and\n" INDENT + "ECC PCKMO key encryption functions (default)\n" INDENT + "(optional).")}, + {.long_name = "disable-pckmo", + .short_name = 0, + .flags = G_OPTION_FLAG_NO_ARG, + .arg = G_OPTION_ARG_CALLBACK, + .arg_data = cb_enable_disable_flag, + .description = _("Disable the support for the DEA, TDEA, AES, and\n" INDENT + "ECC PCKMO key encryption functions (optional).")}, { .long_name = "crl", .short_name = 0, .flags = G_OPTION_FLAG_NONE, @@ -357,7 +392,8 @@ gint pv_args_parse_options(PvArgs *args, gint *argc, gchar **argv[], .description = _("Specify the plaintext control flags\n" INDENT "as a hexadecimal value.\n" INDENT - "Optional; default: '0xe0'."), + "Optional; mutually exclusive with\n" INDENT + "'--(enable|disable)-pckmo'; default: '0xe0'."), .arg_description = _("VALUE") }, { .long_name = "x-psw", .short_name = 0, @@ -410,6 +446,7 @@ PvArgs *pv_args_new(void) g_autoptr(PvArgs) args = g_new0(PvArgs, 1); args->unused_values = g_ptr_array_new_with_free_func(g_free); + args->allow_pckmo = PV_NOT_SET; return g_steal_pointer(&args); } diff --git a/genprotimg/src/pv/pv_args.h b/genprotimg/src/pv/pv_args.h index 8939232a..77f55396 100644 --- a/genprotimg/src/pv/pv_args.h +++ b/genprotimg/src/pv/pv_args.h @@ -22,12 +22,19 @@ typedef struct pv_arg { PvArg *pv_arg_new(PvComponentType type, const gchar *path); void pv_arg_free(PvArg *arg); +typedef enum pv_tristate { + PV_NOT_SET = 0, + PV_TRUE, + PV_FALSE, +} PvTristate; + typedef struct { gint log_level; gint no_verify; gboolean offline; gchar *pcf; gchar *scf; + PvTristate allow_pckmo; gchar *psw_addr; /* PSW address which will be used for the start of * the actual component (e.g. Linux kernel) */ diff --git a/genprotimg/src/pv/pv_image.c b/genprotimg/src/pv/pv_image.c index c33f64eb..73592401 100644 --- a/genprotimg/src/pv/pv_image.c +++ b/genprotimg/src/pv/pv_image.c @@ -229,7 +229,7 @@ static gint pv_img_set_psw_addr(PvImage *img, const gchar *psw_addr_s, } static gint pv_img_set_control_flags(PvImage *img, const gchar *pcf_s, - const gchar *scf_s, GError **err) + const gchar *scf_s, PvTristate allow_pckmo, GError **err) { uint64_t flags; @@ -247,6 +247,11 @@ static gint pv_img_set_control_flags(PvImage *img, const gchar *pcf_s, img->scf = flags; } + if (allow_pckmo == PV_TRUE) + img->pcf |= PV_PCF_PCKM_ECC | PV_PCF_PCKMO_AES | PV_PCF_PCKMO_DEA_TDEA; + else if (allow_pckmo == PV_FALSE) + img->pcf &= ~(PV_PCF_PCKM_ECC | PV_PCF_PCKMO_AES | PV_PCF_PCKMO_DEA_TDEA); + return 0; } @@ -603,7 +608,7 @@ PvImage *pv_img_new(PvArgs *args, const gchar *stage3a_path, GError **err) return NULL; /* set the control flags: PCF and SCF */ - if (pv_img_set_control_flags(ret, args->pcf, args->scf, err) < 0) + if (pv_img_set_control_flags(ret, args->pcf, args->scf, args->allow_pckmo, err) < 0) return NULL; /* read in the keys */