diff --git a/s390utils-2.27.0-rhel.patch b/s390utils-2.27.0-rhel.patch deleted file mode 100644 index 0ab3339..0000000 --- a/s390utils-2.27.0-rhel.patch +++ /dev/null @@ -1,1578 +0,0 @@ -From 368c5581b8e7f9f796764c3f697babd63d637767 Mon Sep 17 00:00:00 2001 -From: Stefan Haberland -Date: Mon, 8 May 2023 14:52:54 +0200 -Subject: [PATCH 1/7] zdev: add support for autoquiesce related sysfs - attributes (#2196517) - -Autoquiesce is a mechanism that tells Linux to stop issuing I/Os to a -specific DASD after certain events. - -Add support for configuring related DASD device attributes -that govern the following aspects of autoquiesce: - -aq_mask - Configure which events lead to autoquiesce. -aq_requeue - Configure if autoquiesce will requeue all I/O to blocklayer. -aq_timeouts - Configure the number of timeouts before autoquiesce. - -Signed-off-by: Stefan Haberland -Reviewed-by: Peter Oberparleiter -Signed-off-by: Steffen Eiden -(cherry picked from commit 493af760ed47454f5719f05a6e6316f43a3be98a) ---- - zdev/src/dasd.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 65 insertions(+) - -diff --git a/zdev/src/dasd.c b/zdev/src/dasd.c -index f9fd231..4330229 100644 ---- a/zdev/src/dasd.c -+++ b/zdev/src/dasd.c -@@ -344,6 +344,68 @@ static struct attrib dasd_attr_fc_security = { - .readonly = 1, - }; - -+static struct attrib dasd_attr_aq_mask = { -+ .name = "aq_mask", -+ .title = "Specify autoquiesce triggers", -+ .desc = -+ "Use the aq_mask attribute to automatically quiesce a device and block\n" -+ "new I/O after certain events.\n" -+ "\n" -+ "The value is a bitmask in decimal or hexadecimal format where each set bit\n" -+ "indicates that the associated event shown in the table below triggers an\n" -+ "autoquiesce.\n" -+ " Bit 0 is not used.\n" -+ " 1 - 0x02 - A terminal I/O error occurred\n" -+ " 2 - 0x04 - No active channel paths remain for the device\n" -+ " 3 - 0x08 - A state change interrupt occurred\n" -+ " 4 - 0x10 - The device is PPRC suspended\n" -+ " 5 - 0x20 - No space is left on an ESE device\n" -+ " 6 - 0x40 – The number of timeouts specified in aq_timeouts is reached\n" -+ " 7 - 0x80 - I/O was not started because of an error in the start function\n" -+ "\n" -+ "For example bits 1,3 and 5 set (0010 1010) lead to an integer value of 42\n" -+ "or 0x2A.\n" -+ "An integer value of 0 turns off the autoquiesce function.\n", -+ .order_cmp = ccw_online_only_order_cmp, -+ .check = ccw_online_only_check, -+ .defval = "0", -+ /* -+ * Currently only 8 bits are defined and the max value is 255. -+ * This needs to be adjusted if more bits are defined. -+ */ -+ .accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 255)), -+}; -+ -+static struct attrib dasd_attr_aq_requeue = { -+ .name = "aq_requeue", -+ .title = "Control I/O requeing during autoquiesce", -+ .desc = -+ "Use the aq_requeue attribute to control whether outstanding I/O\n" -+ "operations to the blocklayer should be automatically requeued after\n" -+ "an autoquiesce event.\n" -+ "Valid values are 1 for requeuing, or 0 for no requeueing.\n" -+ "Requeing the I/O requests to the blocklayer might benefit I/O\n" -+ "in case of a copy_pair swap operation.\n", -+ .order_cmp = ccw_online_only_order_cmp, -+ .check = ccw_online_only_check, -+ .defval = "0", -+ .accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)), -+}; -+ -+static struct attrib dasd_attr_aq_timeouts = { -+ .name = "aq_timeouts", -+ .title = "Specify timeout retry threshold", -+ .desc = -+ "Specify the number of sequential timeout events for an I/O operation\n" -+ "before an autoquiesce is triggered on a device.\n" -+ "This requires that the corresponding trigger bit 6 is set\n" -+ "in the aq_mask attribute.\n", -+ .order_cmp = ccw_online_only_order_cmp, -+ .check = ccw_online_only_check, -+ .defval = "32768", -+ .accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 32768)), -+}; -+ - /* - * DASD subtype methods. - */ -@@ -725,6 +787,9 @@ struct subtype dasd_subtype_eckd = { - &dasd_attr_safe_offline, - &dasd_attr_fc_security, - &dasd_attr_copy_pair, -+ &dasd_attr_aq_mask, -+ &dasd_attr_aq_requeue, -+ &dasd_attr_aq_timeouts, - &internal_attr_early, - ), - .unknown_dev_attribs = 1, --- -2.41.0 - - -From 21a9e00ffeb5ef885ad52b73f2724cef6d1ae73d Mon Sep 17 00:00:00 2001 -From: Vineeth Vijayan -Date: Wed, 7 Jun 2023 14:10:56 +0200 -Subject: [PATCH 2/7] zdev: add proper value input for the ZDEV_SITE_ID key - (#2223304) -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -udev does not allow an empty value for keys when importing output -from an external program. Providing an empty value for any key -invokes a warning during the parsing. Currently, ZDEV_SITE_ID for -fallback sites are not assigned any value. Add an empty double -quotes as the value in case of failover sites. - -This modification is tested on udevadm version 253 on fedora38. - -Also verify that the ZDEV_SITE_ID is properly written, if not log -the error. - -Fixes: c8ad5f57d0fc ("zdev: modify zdev_id to read the site_id from loadparm") -Reported-by: Alexander Egorenkov -Signed-off-by: Vineeth Vijayan -Reviewed-by: Peter Oberparleiter -Signed-off-by: Jan Höppner -(cherry picked from commit 27902c91064f5900fa0ae8116d3e1d0bcd9477bc) ---- - zdev/src/zdev_id.c | 22 +++++++++++++++++----- - 1 file changed, 17 insertions(+), 5 deletions(-) - -diff --git a/zdev/src/zdev_id.c b/zdev/src/zdev_id.c -index c341d31..9ad9961 100644 ---- a/zdev/src/zdev_id.c -+++ b/zdev/src/zdev_id.c -@@ -213,16 +213,28 @@ out: - static void write_zdev_site_id(int site_id) - { - FILE *fd; -+ int rc; - - fd = fopen(ZDEV_SITE_ID_FILE, "w"); - if (!fd) -- err(1, "Could not write to zdev_site_id file"); -+ goto err; -+ - if (site_id == SITE_FALLBACK) -- fprintf(fd, "ZDEV_SITE_ID=\n"); -+ rc = fprintf(fd, "ZDEV_SITE_ID=\"\"\n"); - else -- fprintf(fd, "ZDEV_SITE_ID=%d\n", site_id); -+ rc = fprintf(fd, "ZDEV_SITE_ID=%d\n", site_id); - -- fclose(fd); -+ if (rc < 0) { -+ fclose(fd); -+ goto err; -+ } -+ -+ if (fclose(fd)) -+ goto err; -+ -+ return; -+err: -+ err(1, "Could not write to zdev_site_id file"); - } - - /* Read the loadparm and extract the current site_id. -@@ -265,7 +277,7 @@ static void process_loadparm(const char *filename) - out: - write_zdev_site_id(site_id); - if (site_id == SITE_FALLBACK) -- printf("ZDEV_SITE_ID=\n"); -+ printf("ZDEV_SITE_ID=\"\"\n"); - else - printf("ZDEV_SITE_ID=%d\n", site_id); - } --- -2.41.0 - - -From 90bab830c617cbecdc51ef9f6f2a19d14e6445c5 Mon Sep 17 00:00:00 2001 -From: Vineeth Vijayan -Date: Wed, 7 Jun 2023 14:10:57 +0200 -Subject: [PATCH 3/7] zdev: use rename-file to avoid any symlinks created - (#2223304) -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -During the boot, the ZDEV_SITE_ID is derived with the help -of loadparm and will be saved in ZDEV_SITE_ID_FILE, which -will be the used by the udev-rules. - -ZDEV_SITE_ID_FILE creation can have a surface of symlink attack -as we are directly using the fopen and fprintf on it. To avoid -this, make sure that we are writing the ZDEV_SITE_ID to a temporary -file, which will then be renamed to ZDEV_SITE_ID_FILE, which will -remove all the existing symlinks associated with the target file. - -Reported-by: Marc Hartmayer -Signed-off-by: Vineeth Vijayan -Reviewed-by: Peter Oberparleiter -Signed-off-by: Jan Höppner -(cherry picked from commit 09c01e580abc519976c8e20c5d867b3d1a31e062) ---- - zdev/src/zdev_id.c | 17 +++++++++++++++-- - 1 file changed, 15 insertions(+), 2 deletions(-) - -diff --git a/zdev/src/zdev_id.c b/zdev/src/zdev_id.c -index 9ad9961..2464b16 100644 ---- a/zdev/src/zdev_id.c -+++ b/zdev/src/zdev_id.c -@@ -213,9 +213,16 @@ out: - static void write_zdev_site_id(int site_id) - { - FILE *fd; -- int rc; -+ int tmpfd, rc; -+ const char zdev_id_file[] = ZDEV_SITE_ID_FILE; -+ char zdev_id_tmpfile[] = ZDEV_SITE_ID_FILE "-XXXXXX"; - -- fd = fopen(ZDEV_SITE_ID_FILE, "w"); -+ tmpfd = mkstemp(zdev_id_tmpfile); -+ if (tmpfd == -1) -+ goto err; -+ -+ /* Open the temp file to use with fprintf */ -+ fd = fdopen(tmpfd, "w"); - if (!fd) - goto err; - -@@ -232,6 +239,12 @@ static void write_zdev_site_id(int site_id) - if (fclose(fd)) - goto err; - -+ /* Rename the temporary file to ZDEV_SITE_ID_FILE*/ -+ if (rename(zdev_id_tmpfile, zdev_id_file) == -1) { -+ remove(zdev_id_tmpfile); -+ goto err; -+ } -+ - return; - err: - err(1, "Could not write to zdev_site_id file"); --- -2.41.0 - - -From 5e9a117d1da306ad13b46612b709d769c792baae Mon Sep 17 00:00:00 2001 -From: Vineeth Vijayan -Date: Mon, 19 Jun 2023 11:32:15 +0200 -Subject: [PATCH 4/7] zdev: add missing label in the udev-rules (#2222900) -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The udev-rules generated with the current version of chzdev command -is missing the configuration label, incase of auto configuration, -resulting in an ineffective configuration logic. -Add the missing configuration start label for autoconfig. - -Fixes: 2e89722ef0ec ("zdev: make site specific udev-rule for ccw") -Signed-off-by: Vineeth Vijayan -Reviewed-by: Peter Oberparleiter -Signed-off-by: Jan Höppner -(cherry picked from commit 2a1a821bb3941ddd341b52068d5c05e06d907355) ---- - zdev/src/udev_ccw.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/zdev/src/udev_ccw.c b/zdev/src/udev_ccw.c -index 3375a5e..1881337 100644 ---- a/zdev/src/udev_ccw.c -+++ b/zdev/src/udev_ccw.c -@@ -295,6 +295,7 @@ static exit_code_t udev_ccw_write_device_legacy(struct device *dev, bool autocon - } - fprintf(fd, "GOTO=\"%s\"\n", end_label); - fprintf(fd, "\n"); -+ fprintf(fd, "LABEL=\"%s\"\n", cfg_label); - - write_attr_to_file(fd, state, id); - --- -2.41.0 - - -From 17d87f75f0e461429962f312fe3bf73ecd7d353a Mon Sep 17 00:00:00 2001 -From: Harald Freudenberger -Date: Wed, 17 May 2023 11:43:08 +0200 -Subject: [PATCH 5/7] lszcrypt: Support for SE AP pass-through support - (#2110521) -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This patch adds support for Secure Execution with AP pass-through -support for lszcrypt. - -lszcrypt details: -* extension to -b: list AP bus features -* extension to -c: now also valid for queue devices, shows - bind and assoicate state in SE environment; - shows MK states (only for current MKs). -* extension to -V: new column SESTAT within an SE guest, shows text - for the BS bits within an SE environment: - "usable", "bond", "avail", "unuse". - -Signed-off-by: Harald Freudenberger -Reviewed-by: Holger Dengler -Signed-off-by: Jan Höppner -(cherry picked from commit f821f31a51e395c0d0b048413360eeff92eaee9c) ---- - zconf/zcrypt/lszcrypt.8 | 195 +++++++++++++++++++++++++--------------- - zconf/zcrypt/lszcrypt.c | 136 ++++++++++++++++++++++++---- - zconf/zcrypt/misc.c | 38 +++++++- - zconf/zcrypt/misc.h | 3 +- - 4 files changed, 278 insertions(+), 94 deletions(-) - -diff --git a/zconf/zcrypt/lszcrypt.8 b/zconf/zcrypt/lszcrypt.8 -index e1de2e9..536a3e3 100644 ---- a/zconf/zcrypt/lszcrypt.8 -+++ b/zconf/zcrypt/lszcrypt.8 -@@ -1,6 +1,6 @@ - .\" lszcrypt.8 - .\" --.\" Copyright IBM Corp. 2019, 2022 -+.\" Copyright IBM Corp. 2019, 2023 - .\" s390-tools is free software; you can redistribute it and/or modify - .\" it under the terms of the MIT license. See LICENSE for details. - .\" -@@ -10,7 +10,7 @@ - .\" nroff -man lszcrypt.8 - .\" to process this source - .\" --.TH LSZCRYPT 8 "FEB 2022" "s390-tools" -+.TH LSZCRYPT 8 "MAY 2023" "s390-tools" - .SH NAME - lszcrypt \- display zcrypt device and configuration information - .SH SYNOPSIS -@@ -24,7 +24,7 @@ lszcrypt \- display zcrypt device and configuration information - .TP - .B lszcrypt - .B -c -- -+ - .TP - .B lszcrypt -b - .TP -@@ -41,43 +41,60 @@ lszcrypt \- display zcrypt device and configuration information - .SH DESCRIPTION - The - .B lszcrypt --command is used to display information about cryptographic devices managed by --zcrypt and the AP bus attributes of zcrypt. Displayed information depends on the --kernel version. -+command is used to display information about cryptographic devices -+managed by zcrypt and the AP bus attributes of zcrypt. Displayed -+information depends on the kernel version. - .B lszcrypt - requires that sysfs is mounted. - .P - The following information can be displayed for each cryptographic - device: card ID, domain ID, card type (symbolic), mode, online status, --hardware card type (numeric), installed function facilities, card capability, --hardware queue depth, request count, number of requests in hardware queue, and --the number of outstanding requests. --The following AP bus attributes can be displayed: AP domain, Max AP domain, --configuration timer, poll thread status, poll timeout, and AP interrupt --status. -+hardware card type (numeric), installed function facilities, card -+capability, hardware queue depth, request count, number of requests in -+hardware queue, and the number of outstanding requests. The following -+AP bus attributes can be displayed: AP domain, Max AP domain, -+configuration timer, poll thread status, poll timeout, and AP -+interrupt status. - .SH OPTIONS - .TP 8 - .B -V, --verbose --The verbose level for cryptographic device information. --With this verbose level additional information like hardware card type, --hardware queue depth, pending requests count, installed function --facilities and driver binding is displayed. -+The verbose level for cryptographic device information. With this -+verbose level additional information like hardware card type, hardware -+queue depth, pending requests count, installed function facilities and -+driver binding is displayed. - .TP 8 - .B --Specifies a cryptographic device to display. A cryptographic device can be --either a card device or a queue device. If no devices are specified information --about all available devices is displayed. -+Specifies a cryptographic device to display. A cryptographic device -+can be either a card device or a queue device. If no devices are -+specified information about all available devices is displayed. - Please note that the card device representation and the queue device - are both in hexadecimal notation. - .TP 8 - .B -b, --bus - Displays the AP bus attributes and exits. -+ -+There is also a list of AP bus features shown here: -+.RS -+.IP "o" 3 -+APSC - Extended TAPQ (Test AP Queue) support. -+.IP "o" -+APXA - Support for more than 16 domains per card. -+.IP "o" -+QACT - QACT support for toleration of new unknown crypto cards. -+.IP "o" -+RC8A - Firmware reports 0x8A instead of 0x42 on some error conditions. -+.IP "o" -+APSB - AP bus has Secure Execution AP pass-through support. -+.RE - .TP 8 --.B -c, --capability --Shows the capabilities of a cryptographic card device of hardware type 6 or --higher. The card device id value may be given as decimal or hex value (with --a leading 0x). The capabilities of a cryptographic card device depend on --the card type and the installed function facilities. A cryptographic card -+.B -c, --capability -+Shows the capabilities of a cryptographic card or queue device of -+hardware type 6 or higher. A card device id value may be given as -+decimal or hex value (with a leading 0x), a queue device needs to be -+given as xy.abcd (as it is displayed by lszcrypt). -+ -+The capabilities of a cryptographic card device depend on the card -+type and the installed function facilities. A cryptographic card - device can provide one or more of the following capabilities: - .RS - .IP "o" 3 -@@ -94,14 +111,25 @@ Long RNG - - .RS 8 - The CCA Secure Key capability may be limited by a hypervisor --layer. The remarks 'full function set' or 'restricted function set' may --reflect this. For details about these limitations please check the -+layer. The remarks 'full function set' or 'restricted function set' -+may reflect this. For details about these limitations please check the - hypervisor documentation. - .RE -+ -+.RS 8 -+The capabilities of a cryptographic queue device may vary depending -+on some state or environment. However if a queue device is given here, -+and the runtime environment is a KVM guest in Secure Execution mode -+with AP pass-through support, then the AP queue bind state and AP -+queue association state is shown here. Furthermore the state(s) and -+mkvp(s) (Master Key Verification Pattern) of the current master WK -+(Wrapping Key - EP11 mode) or current master AES, APKA and ASYM (CCA -+mode) are shown here. -+.RE - .TP 8 - .B -d, --domains --Shows the usage and control domains of the cryptographic devices. --The displayed domains of the cryptographic device depends on the initial -+Shows the usage and control domains of the cryptographic devices. The -+displayed domains of the cryptographic device depends on the initial - cryptographic configuration. - .RS - .IP "o" 3 -@@ -140,18 +168,20 @@ Here is an explanation of the columns displayed. Please note that some - of the columns show up in verbose mode only. - .TP - .B CARD.DOM --The crypto card number in hexadecimal for a crypto card line or --the crypto card number and the domain id both in hex separated by a single -+The crypto card number in hexadecimal for a crypto card line or the -+crypto card number and the domain id both in hex separated by a single - dot for a queue line. - .TP - .B TYPE and HWTYPE --The HWTYPE is a numeric value showing which type of hardware the zcrypt --device driver presumes that this crypto card is. The currently known values --are 7=CEX3C, 8=CEX3A, 10=CEX4, 11=CEX5, 12=CEX6, 13=CEX7 and 14=CEX8. -+The HWTYPE is a numeric value showing which type of hardware the -+zcrypt device driver presumes that this crypto card is. The currently -+known values are 7=CEX3C, 8=CEX3A, 10=CEX4, 11=CEX5, 12=CEX6, 13=CEX7 -+and 14=CEX8. - .br --The TYPE is a human readable value showing the hardware type and the basic --function type (A=Accelerator, C=CCA Coprocessor, P=EP11 Coprocessor). So --for example CEX6P means a CEX6 card in EP11 Coprocessor mode. -+The TYPE is a human readable value showing the hardware type and the -+basic function type (A=Accelerator, C=CCA Coprocessor, P=EP11 -+Coprocessor). So for example CEX6P means a CEX6 card in EP11 -+Coprocessor mode. - .TP - .B MODE - A crypto card can be configured to run into one of 3 modes: -@@ -170,13 +200,13 @@ online/offline state is kept by the zcrypt device driver and can be - switched on or off with the help of the chzcrypt application. - .br - A crypto card can also be 'configured' or 'deconfigured'. This state --may be adjusted on the HMC or SE. The chzcrypt application can also --trigger this state with the --config-on and --config-off options. -+may be adjusted on the HMC. The chzcrypt application can also trigger -+this state with the --config-on and --config-off options. - .br - lszcrypt shows 'online' when a card or queue is available for - cryptographic operations. 'offline' is displayed when a card or queue - is switched to (software) offline. If a card is 'deconfigured' via --HMC, SE or chzcrypt the field shows 'deconfig'. -+HMC or chzcrypt the field shows 'deconfig'. - .br - A crypto card may also reach a 'checkstopped' state. lszcrypt shows - this as 'chkstop'. -@@ -184,21 +214,22 @@ this as 'chkstop'. - If a queue is not bound to a device driver there is no detailed - information available and thus the status shows only '-'. - .br --If a queue is bound to the vfio-ap device driver it is up to this driver --to give some status information and what exactly this means. So lszcrypt --shows the text retrieved from the underlying sysfs attribute here. -+If a queue is bound to the vfio-ap device driver it is up to this -+driver to give some status information and what exactly this means. So -+lszcrypt shows the text retrieved from the underlying sysfs attribute -+here. - .TP - .B REQUESTS --This is the counter value of successful processed requests on card or queue --level. Successful here means the request was processed without any failure --in the whole processing chain. -+This is the counter value of successful processed requests on card or -+queue level. Successful here means the request was processed without -+any failure in the whole processing chain. - .TP - .B PENDING --The underlying firmware and hardware layer usually provide some queuing --space for requests. When this queue is already filled up, the zcrypt device --driver maintains a software queue of pending requests. The sum of these --both values is displayed here and shows the amount of requests waiting for --processing on card or queue level. -+The underlying firmware and hardware layer usually provide some -+queuing space for requests. When this queue is already filled up, the -+zcrypt device driver maintains a software queue of pending -+requests. The sum of these both values is displayed here and shows the -+amount of requests waiting for processing on card or queue level. - .TP - .B FUNCTIONS - This column shows firmware and hardware function details: -@@ -224,48 +255,64 @@ F - Full function support (opposed to restricted function support, see below). - .br - R - Restricted function support. The F and R flag both reflect if a - hypervisor is somehow restricting this crypto resource in a virtual --environment. Dependent on the hypervisor configuration the crypto requests --may be filtered by the hypervisor to allow only a subset of functions --within the virtual runtime environment. For example a shared CCA --Coprocessor may be restricted by the hypervisor to allow only clear key --operations within the guests. -+environment. Dependent on the hypervisor configuration the crypto -+requests may be filtered by the hypervisor to allow only a subset of -+functions within the virtual runtime environment. For example a shared -+CCA Coprocessor may be restricted by the hypervisor to allow only -+clear key operations within the guests. - .TP - .B DRIVER - .br - Shows which card or queue device driver currently handles this crypto - resource. Currently known drivers are cex4card/cex4queue (CEX4-CEX8 - hardware), cex2card/cex2cqueue (CEX2C and CEX3C hardware), --cex2acard/cex2aqueue (CEX2A and CEX3A hardware) and vfio_ap (queue reserved --for use by kvm hypervisor for kvm guests and not accessible to host --applications). It is also valid to have no driver handling a queue which is --shown as a -no-driver- entry. -+cex2acard/cex2aqueue (CEX2A and CEX3A hardware) and vfio_ap (queue -+reserved for use by KVM hypervisor for KVM guests and not accessible -+to host applications). It is also valid to have no driver handling a -+queue which is shown as a -no-driver- entry. -+.TP -+.B SESTAT -+.br -+Shows the state of the BS bits associated with every AP queue within a -+Secure Execution guest when AP Pass-through support is available: -+.br -+usable - AP queue is usable for crypto load. -+.br -+bound - AP queue is bound but not yet associated. -+.br -+unbound - AP queue is unbound and needs to get bound to this Secure -+Execution guest. -+.br -+illicit - AP queue is not available for this Secure Execution guest. - .SH NOTES --Use only one of the mode filtering options --accelonly, --ccaonly, --ep11only. --Same with card/queue filtering: Use only one of --cardonly, --queueonly. --However, one of the mode filtering options and one of the card/queue filtering --can be combined. -+Use only one of the mode filtering options --accelonly, --ccaonly, -+--ep11only. Same with card/queue filtering: Use only one of -+--cardonly, --queueonly. However, one of the mode filtering options -+and one of the card/queue filtering can be combined. - .SH EXAMPLES - .TP - .B lszcrypt --Displays the card/domain ID, card type (short name), mode (long name), online --status and request count of all available cryptographic devices. -+Displays the card/domain ID, card type (short name), mode (long name), -+online status and request count of all available cryptographic -+devices. - .TP - .B lszcrypt 1 3 5 --Displays the card/domain ID, card type, mode, online status and request count --for cryptographic devices 1, 3, and 5. -+Displays the card/domain ID, card type, mode, online status and -+request count for cryptographic devices 1, 3, and 5. - .TP - .B lszcrypt -V 3 7 11 --Displays the card/domain ID, card type, mode, online status, request count, --number of requests in the hardware queue, number of outstanding requests and --installed function facilities for cryptographic devices 3, 7 and 17 (0x11). -+Displays the card/domain ID, card type, mode, online status, request -+count, number of requests in the hardware queue, number of outstanding -+requests and installed function facilities for cryptographic devices -+3, 7 and 17 (0x11). - .TP - .B lszcrypt 10.0038 --Displays information of the cryptographic device '10.0038' respectively card --id 16 (0x10) with domain 56 (0x38). -+Displays information of the cryptographic device '10.0038' -+respectively card id 16 (0x10) with domain 56 (0x38). - .TP - .B lszcrypt .0038 --Displays information of all available queue devices (potentially multiple --adapters) with domain 56 (0x38). -+Displays information of all available queue devices (potentially -+multiple adapters) with domain 56 (0x38). - .TP - .B lszcrypt -b - Displays AP bus information. -diff --git a/zconf/zcrypt/lszcrypt.c b/zconf/zcrypt/lszcrypt.c -index 43a3c39..09de77e 100644 ---- a/zconf/zcrypt/lszcrypt.c -+++ b/zconf/zcrypt/lszcrypt.c -@@ -1,7 +1,7 @@ - /** - * lszcrypt - Display zcrypt devices and configuration settings - * -- * Copyright IBM Corp. 2008, 2022 -+ * Copyright IBM Corp. 2008, 2023 - * - * s390-tools is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See LICENSE for details. -@@ -55,7 +55,7 @@ static struct lszcrypt_l { - #define MASK_COPRO 0x10000000 - #define MASK_ACCEL 0x08000000 - #define MASK_EP11 0x04000000 --#define MASK_HSL 0x01000000 -+#define MASK_HSL 0x01000000 - - /* - * Classification -@@ -85,6 +85,8 @@ static struct fac_bits_s { - { 0x00400000, 'R' }, /* bit 9, restricted function set */ - }; - -+#define EXTRACT_BS_BITS(f) (((f) & 0x0000c000UL) >> 14) -+ - /* - * Program configuration - */ -@@ -95,7 +97,7 @@ static const struct util_prg prg = { - { - .owner = "IBM Corp.", - .pub_first = 2008, -- .pub_last = 2020, -+ .pub_last = 2023, - }, - UTIL_PRG_COPYRIGHT_END - } -@@ -169,8 +171,9 @@ static struct util_opt opt_vec[] = { - static void show_bus(void) - { - long domain, max_domain, config_time, value; -- unsigned long long poll_timeout; - const char *poll_thread, *ap_interrupts; -+ unsigned long long poll_timeout; -+ char features[256]; - char *ap; - - /* check if ap driver is available */ -@@ -178,6 +181,10 @@ static void show_bus(void) - if (!util_path_is_dir(ap)) - errx(EXIT_FAILURE, "Crypto device driver not available."); - -+ if (util_path_is_readable("%s/features", ap)) -+ util_file_read_line(features, sizeof(features), "%s/features", ap); -+ else -+ features[0] = '\0'; - util_file_read_l(&domain, 10, "%s/ap_domain", ap); - util_file_read_l(&max_domain, 10, "%s/ap_max_domain_id", ap); - util_file_read_l(&config_time, 10, "%s/config_time", ap); -@@ -192,6 +199,8 @@ static void show_bus(void) - ap_interrupts = "enabled"; - else - ap_interrupts = "disabled"; -+ if (features[0]) -+ printf("features: %s\n", features); - printf("ap_domain=0x%lx\n", domain); - printf("ap_max_domain_id=0x%lx\n", max_domain); - if (util_path_is_reg_file("%s/ap_interrupts", ap)) -@@ -374,23 +383,15 @@ next: - } - - /* -- * Show capability -+ * Show card capability - */ --static void show_capability(const char *id_str) -+static void show_card_capability(int id) - { - unsigned long func_val; -- long hwtype, id, max_msg_size; -- char *p, *ap, *dev, card[16], cbuf[256]; -- -- /* check if ap driver is available */ -- ap = util_path_sysfs("bus/ap"); -- if (!util_path_is_dir(ap)) -- errx(EXIT_FAILURE, "Crypto device driver not available."); -+ long hwtype, max_msg_size; -+ char *dev, card[16], cbuf[256]; - -- id = strtol(id_str, &p, 0); -- if (id < 0 || id > 255 || p == id_str || *p != '\0') -- errx(EXIT_FAILURE, "Error - '%s' is an invalid cryptographic device id.", id_str); -- snprintf(card, sizeof(card), "card%02lx", id); -+ snprintf(card, sizeof(card), "card%02x", id); - dev = util_path_sysfs("devices/ap/%s", card); - if (!util_path_is_dir(dev)) - errx(EXIT_FAILURE, "Error - cryptographic device %s does not exist.", card); -@@ -464,6 +465,78 @@ static void show_capability(const char *id_str) - card, hwtype); - break; - } -+ -+ free(dev); -+} -+ -+/* -+ * Show queue capability -+ */ -+static void show_queue_capability(int id, int dom) -+{ -+ char *dev, card[16], queue[16], buf[256]; -+ -+ snprintf(card, sizeof(card), "card%02x", id); -+ snprintf(queue, sizeof(queue), "%02x.%04x", id, dom); -+ dev = util_path_sysfs("devices/ap/%s/%s", card, queue); -+ if (!util_path_is_dir(dev)) -+ errx(EXIT_FAILURE, "Error - cryptographic queue device %02x.%04x does not exist.", -+ id, dom); -+ -+ printf("queue %02x.%04x capabilities:\n", id, dom); -+ -+ if (util_path_is_reg_file("%s/se_bind", dev)) { -+ util_file_read_line(buf, sizeof(buf), "%s/se_bind", dev); -+ printf("SE bind state: %s\n", buf); -+ } -+ if (util_path_is_reg_file("%s/se_associate", dev)) { -+ util_file_read_line(buf, sizeof(buf), "%s/se_associate", dev); -+ printf("SE association state: %s\n", buf); -+ } -+ if (util_path_is_reg_file("%s/mkvps", dev)) { -+ char *mkvps = util_path_sysfs("devices/ap/%s/%s/mkvps", card, queue); -+ FILE *f = fopen(mkvps, "r"); -+ -+ if (!f) -+ errx(EXIT_FAILURE, "Error - failed to open sysfs file %s.", -+ mkvps); -+ while (fgets(buf, sizeof(buf), f)) { -+ if (strstr(buf, "WK CUR") || -+ strstr(buf, "AES CUR") || -+ strstr(buf, "APKA CUR") || -+ strstr(buf, "ASYM CUR")) -+ printf("MK %s", buf); /* no newline here */ -+ } -+ fclose(f); -+ free(mkvps); -+ } -+ -+ free(dev); -+} -+ -+/* -+ * Show capability -+ */ -+static void show_capability(const char *id_str) -+{ -+ char *p, *ap; -+ int id, dom; -+ -+ /* check if ap driver is available */ -+ ap = util_path_sysfs("bus/ap"); -+ if (!util_path_is_dir(ap)) -+ errx(EXIT_FAILURE, "Crypto device driver not available."); -+ -+ if (sscanf(id_str, "%x.%x", &id, &dom) == 2) { -+ show_queue_capability(id, dom); -+ } else { -+ id = strtol(id_str, &p, 0); -+ if (id < 0 || id > 255 || p == id_str || *p != '\0') -+ errx(EXIT_FAILURE, -+ "Error - '%s' is an invalid cryptographic device id.", -+ id_str); -+ show_card_capability(id); -+ } - } - - /* -@@ -601,11 +674,33 @@ static void read_subdev_rec_verbose(struct util_rec *rec, const char *grp_dev, - util_file_read_l(&depth, 10, "%s/depth", grp_dev); - util_rec_set(rec, "depth", "%02d", depth + 1); - -- util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev); -+ if (util_path_is_readable("%s/%s/ap_functions", grp_dev, sub_dev)) -+ util_file_read_ul(&facility, 16, "%s/%s/ap_functions", grp_dev, sub_dev); -+ else -+ util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev); - for (i = 0; i < MAX_FAC_BITS; i++) - buf[i] = facility & fac_bits[i].mask ? fac_bits[i].c : '-'; - buf[i] = '\0'; - util_rec_set(rec, "facility", buf); -+ -+ if (ap_bus_has_SB_support()) { -+ switch (EXTRACT_BS_BITS(facility)) { -+ case 0: -+ util_rec_set(rec, "sestat", "usable"); -+ break; -+ case 1: -+ util_rec_set(rec, "sestat", "bound"); -+ break; -+ case 2: -+ util_rec_set(rec, "sestat", "unbound"); -+ break; -+ case 3: -+ util_rec_set(rec, "sestat", "illicit"); -+ break; -+ default: -+ util_rec_set(rec, "sestat", "-"); -+ } -+ } - } - - /* -@@ -750,6 +845,9 @@ static void read_rec_verbose(struct util_rec *rec, const char *grp_dev) - - i = read_driver(grp_dev, NULL, buf, sizeof(buf)); - util_rec_set(rec, "driver", i > 0 ? buf : "-no-driver-"); -+ -+ if (ap_bus_has_SB_support()) -+ util_rec_set(rec, "sestat", "-"); - } - - /* -@@ -818,6 +916,8 @@ static void define_rec_verbose(struct util_rec *rec) - util_rec_def(rec, "depth", UTIL_REC_ALIGN_RIGHT, 6, "QDEPTH"); - util_rec_def(rec, "facility", UTIL_REC_ALIGN_LEFT, 10, "FUNCTIONS"); - util_rec_def(rec, "driver", UTIL_REC_ALIGN_LEFT, 11, "DRIVER"); -+ if (ap_bus_has_SB_support()) -+ util_rec_def(rec, "sestat", UTIL_REC_ALIGN_LEFT, 11, "SESTAT"); - } - - /* -diff --git a/zconf/zcrypt/misc.c b/zconf/zcrypt/misc.c -index 4296cb1..05913d6 100644 ---- a/zconf/zcrypt/misc.c -+++ b/zconf/zcrypt/misc.c -@@ -1,16 +1,20 @@ - /* - * Misc - Local helper functions - * -- * Copyright IBM Corp. 2016, 2017 -+ * Copyright IBM Corp. 2016, 2023 - * - * s390-tools is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See LICENSE for details. - */ - - #include -+#include - #include - -+#include "lib/util_base.h" -+#include "lib/util_file.h" - #include "lib/util_panic.h" -+#include "lib/util_path.h" - #include "misc.h" - - /** -@@ -35,3 +39,35 @@ bool misc_regex_match(const char *str, const char *regex) - regfree(&preg); - return rc == 0 ? true : false; - } -+ -+/** -+ * Test if AP bus has SB support available. -+ * -+ * @returns true Yes, SB support is available -+ * false No -+ */ -+bool ap_bus_has_SB_support(void) -+{ -+ static int sb_support = -1; -+ -+ if (sb_support < 0) { -+ char *ap, buf[256]; -+ -+ ap = util_path_sysfs("bus/ap"); -+ if (!util_path_is_dir(ap)) { -+ sb_support = 0; -+ } else { -+ if (!util_path_is_readable("%s/features", ap)) { -+ sb_support = 0; -+ } else { -+ util_file_read_line(buf, sizeof(buf), -+ "%s/features", ap); -+ if (strstr(buf, "APSB")) -+ sb_support = 1; -+ } -+ } -+ free(ap); -+ } -+ -+ return sb_support > 0 ? true : false; -+} -diff --git a/zconf/zcrypt/misc.h b/zconf/zcrypt/misc.h -index 502a687..92cf453 100644 ---- a/zconf/zcrypt/misc.h -+++ b/zconf/zcrypt/misc.h -@@ -1,7 +1,7 @@ - /* - * misc - Local helper functions - * -- * Copyright IBM Corp. 2016, 2017 -+ * Copyright IBM Corp. 2016, 2023 - * - * s390-tools is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See LICENSE for details. -@@ -13,5 +13,6 @@ - #include - - bool misc_regex_match(const char *str, const char *regex); -+bool ap_bus_has_SB_support(void); - - #endif /* MISC_H */ --- -2.41.0 - - -From f5c3fabce59c71fb9fbf2d21ab4bbf909c2653b5 Mon Sep 17 00:00:00 2001 -From: Harald Freudenberger -Date: Wed, 17 May 2023 13:13:09 +0200 -Subject: [PATCH 6/7] chzcrypt: Support for SE bind, unbind and associate - (#2110521) -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This patch adds support for Secure Execution with AP pass-through -support for chzcrypt. - -chzcrypt details: -* new command: --se-associate -* new command: --se-bind -* new command: --se-unbind - -Signed-off-by: Harald Freudenberger -Reviewed-by: Holger Dengler -Signed-off-by: Jan Höppner -(cherry picked from commit e35e73d2a3f60d43b109168cc37f9c43bc35b0a4) ---- - zconf/zcrypt/chzcrypt.8 | 72 +++++++---- - zconf/zcrypt/chzcrypt.c | 278 +++++++++++++++++++++++++++++++++++++--- - 2 files changed, 310 insertions(+), 40 deletions(-) - -diff --git a/zconf/zcrypt/chzcrypt.8 b/zconf/zcrypt/chzcrypt.8 -index a73ff27..94e32fb 100644 ---- a/zconf/zcrypt/chzcrypt.8 -+++ b/zconf/zcrypt/chzcrypt.8 -@@ -1,10 +1,16 @@ - .\" chzcrypt.8 - .\" --.\" Copyright 2020 IBM Corp. -+.\" Copyright 2020, 2023 IBM Corp. - .\" s390-tools is free software; you can redistribute it and/or modify - .\" it under the terms of the MIT license. See LICENSE for details. - .\" --.TH CHZCRYPT 8 "OCT 2020" "s390-tools" -+.\" use -+.\" groff -man -Tutf8 chzcrypt.8 -+.\" or -+.\" nroff -man chzcrypt.8 -+.\" to process this source -+.\" -+.TH CHZCRYPT 8 "MAY 2023" "s390-tools" - .SH NAME - chzcrypt \- modify zcrypt configuration - .SH SYNOPSIS -@@ -46,8 +52,8 @@ chzcrypt \- modify zcrypt configuration - .SH DESCRIPTION - The - .B chzcrypt --command is used to configure cryptographic devices managed by zcrypt and --modify zcrypt's AP bus attributes. -+command is used to configure cryptographic devices managed by zcrypt -+and modify zcrypt's AP bus attributes. - - Attributes may vary depending on the kernel - version. -@@ -70,19 +76,6 @@ Set the given cryptographic card device(s) config on ('configured'). - .B --config-off - Set the given cryptographic card device(s) config off ('deconfigured'). - .TP 8 --.B --Specifies a cryptographic device which will be set either online or --offline or configured on or off. For online and offline the device can --either be a card device or a queue device. A queue device can only get --switched online when the providing card is online. --.br --For config on/off the device needs to be a card device. A card or --queue device cannot get switched online if the card is in deconfigured --state. --.br --Please note that the card device and queue device representation are both --in hexadecimal notation. --.TP 8 - .B -p, --poll-thread-enable - Enable zcrypt's poll thread. - .TP 8 -@@ -94,15 +87,28 @@ Set configuration timer for re-scanning the AP bus to - .I - seconds. - .TP 8 -+.B --se-associate -+Associate the given queue device with the given association -+index. This command is only valid within an Secure Execution guest -+with AP pass-through support enabled. -+.TP 8 -+.B --se-bind -+Bind the given queue device. This command is only valid within an -+Secure Execution guest with AP pass-through support enabled. -+.TP 8 -+.B --se-unbind -+Unbind the given queue device. This command is only valid within an -+Secure Execution guest with AP pass-through support enabled. -+.TP 8 - .BI "-t, --poll-timeout" " " - Set poll timer to run poll tasklet all - .I - nanoseconds. - .TP 8 - .BI "-q, --default-domain" " " --Set the new default domain of the AP bus to . --The number of available domains can be retrieved with the lszcrypt --command ('-d' option). -+Set the new default domain of the AP bus to . The number of -+available domains can be retrieved with the lszcrypt command ('-d' -+option). - .TP 8 - .B -V, --verbose - Print verbose messages. -@@ -112,6 +118,22 @@ Print help text and exit. - .TP 8 - .B -v, --version - Print version information and exit. -+.TP 8 -+.B -+Specifies a cryptographic device which will be set either online or -+offline or configured on or off. For online and offline the device can -+either be a card device or a queue device. A queue device can only get -+switched online when the providing card is online. -+.br -+For config on/off the device needs to be a card device. A card or -+queue device cannot get switched online if the card is in deconfigured -+state. -+.br -+Please note that the card device and queue device representation are -+both in hexadecimal notation. -+.TP 8 -+.B -+An APQN queue device given as xy.abcd as it is listed by lszcrypt -V. - .SH EXAMPLES - .TP - .B chzcrypt -e 0 1 12 -@@ -131,8 +153,8 @@ Set all available crypto cards to config on, be verbose. - Switch the two crypto cards 1 and 3 to deconfigured, be verbose. - .TP - .B chzcrypt -c 60 -n --Will set configuration timer for re-scanning the AP bus to 60 seconds and --disable zcrypt's poll thread. -+Will set configuration timer for re-scanning the AP bus to 60 seconds -+and disable zcrypt's poll thread. - .TP - .B chzcrypt -q 67 - Will set the default domain to 67. -@@ -144,5 +166,11 @@ chzcrypt exits with an appropriate message. Even more config on/off - may require support from a hypervisor like KVM or zVM and may fail if - the Linux kernel is unable to perform the SCLP command. Check syslog - on failure. -+.TP -+Bind, associate and unbind command on an queue device are only -+available and valid within an Secure Execution environment with AP -+pass-through enabled and a Linux kernel providing the low level sysfs -+API. If these conditions are not fulfilled, the command will fail with -+an appropriate error messages. - .SH SEE ALSO - \fBlszcrypt\fR(8) -diff --git a/zconf/zcrypt/chzcrypt.c b/zconf/zcrypt/chzcrypt.c -index 68b36a5..b04bcfa 100644 ---- a/zconf/zcrypt/chzcrypt.c -+++ b/zconf/zcrypt/chzcrypt.c -@@ -1,7 +1,7 @@ - /* - * chzcrypt - Tool to modify zcrypt configuration - * -- * Copyright IBM Corp. 2008, 2020 -+ * Copyright IBM Corp. 2008, 2023 - * - * s390-tools is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See LICENSE for details. -@@ -28,6 +28,12 @@ - - #include "misc.h" - -+/* max seconds the se-association command will wait for completion */ -+#define MAX_ASSOC_POLL_TIME_IN_S 30 -+ -+/* max seconds the se-unbind command will wait for unbind complete */ -+#define MAX_UNBIND_POLL_TIME_IN_S 30 -+ - /* - * Private data - */ -@@ -45,7 +51,7 @@ static const struct util_prg prg = { - { - .owner = "IBM Corp.", - .pub_first = 2008, -- .pub_last = 2020, -+ .pub_last = 2023, - }, - UTIL_PRG_COPYRIGHT_END - } -@@ -57,6 +63,9 @@ static const struct util_prg prg = { - - #define OPT_CONFIG_ON 0x80 - #define OPT_CONFIG_OFF 0x81 -+#define OPT_SE_ASSOC 0x82 -+#define OPT_SE_BIND 0x83 -+#define OPT_SE_UNBIND 0x84 - - static struct util_opt opt_vec[] = { - { -@@ -116,6 +125,22 @@ static struct util_opt opt_vec[] = { - .option = { "verbose", no_argument, NULL, 'V'}, - .desc = "Print verbose messages", - }, -+ { -+ .option = { "se-associate", required_argument, NULL, OPT_SE_ASSOC}, -+ .argument = "assoc_idx", -+ .flags = UTIL_OPT_FLAG_NOSHORT, -+ .desc = "SE guest with AP support only: Associate the given queue device", -+ }, -+ { -+ .option = { "se-bind", no_argument, NULL, OPT_SE_BIND}, -+ .flags = UTIL_OPT_FLAG_NOSHORT, -+ .desc = "SE guest with AP support only: Bind the given queue device", -+ }, -+ { -+ .option = { "se-unbind", no_argument, NULL, OPT_SE_UNBIND}, -+ .flags = UTIL_OPT_FLAG_NOSHORT, -+ .desc = "SE guest with AP support only: Unbind the given queue device", -+ }, - UTIL_OPT_HELP, - UTIL_OPT_VERSION, - UTIL_OPT_END -@@ -336,6 +361,186 @@ next: - } - } - -+static void se_assoc(const char *assoc_idx, const char *dev) -+{ -+ int i, idx, rc, ap, dom, loop; -+ char *dev_path, *attr; -+ char buf[256]; -+ -+ if (!ap_bus_has_SB_support()) -+ errx(EXIT_FAILURE, "Error - AP bus: SE bind support is not available."); -+ -+ if (sscanf(dev, "%02x.%04x", &ap, &dom) != 2) -+ errx(EXIT_FAILURE, "Error - Can't parse queue device '%s' as xy.abcd.", -+ dev); -+ dev_path = util_path_sysfs("bus/ap/devices/card%02x/%02x.%04x", -+ ap, ap, dom); -+ if (!util_path_is_dir(dev_path)) -+ errx(EXIT_FAILURE, "Error - Queue device %s does not exist.", -+ dev); -+ -+ if (sscanf(assoc_idx, "%i", &idx) != 1) -+ errx(EXIT_FAILURE, "Error - Can't parse association index '%s' as number.", -+ assoc_idx); -+ if (idx < 0 || idx > 0xFFFF) -+ errx(EXIT_FAILURE, "Error - Association index needs to be in range [0...%d].", -+ 0xffff); -+ -+ attr = util_path_sysfs("bus/ap/devices/card%02x/%02x.%04x/se_associate", -+ ap, ap, dom); -+ if (!util_path_is_writable(attr)) -+ errx(EXIT_FAILURE, "Error - Can't write to %s (errno '%s').", -+ attr, strerror(errno)); -+ -+ /* read se_associate attribute and check for 'unassociated' */ -+ rc = util_file_read_line(buf, sizeof(buf), attr); -+ if (rc) -+ errx(EXIT_FAILURE, "Error - Failure reading from %s (errno '%s').", -+ attr, strerror(errno)); -+ if (strcmp(buf, "unassociated")) -+ errx(EXIT_FAILURE, -+ "Error - Queue device %s is NOT in 'unassociated' state (state '%s' found).", -+ dev, buf); -+ -+ /* write assocition index to the se_associate attribute */ -+ rc = util_file_write_l(idx, 10, attr); -+ if (rc) -+ errx(EXIT_FAILURE, "Error - Failure writing to %s (errno '%s').", -+ attr, strerror(errno)); -+ -+ /* loop up to MAX_ASSOC_POLL_TIME_IN_S seconds for completion */ -+ for (loop = 0; loop < 2 * MAX_ASSOC_POLL_TIME_IN_S; usleep(500000), loop++) { -+ rc = util_file_read_line(buf, sizeof(buf), attr); -+ if (rc) -+ errx(EXIT_FAILURE, "Error - Failure reading from %s (errno '%s').", -+ attr, strerror(errno)); -+ if (!strncmp(buf, "associated", strlen("associated"))) -+ break; -+ if (!strcmp(buf, "unassociated")) -+ errx(EXIT_FAILURE, -+ "Error - Failure associating queue device %s (state '%s' found).", -+ dev, buf); -+ } -+ if (loop >= 2 * MAX_ASSOC_POLL_TIME_IN_S) -+ errx(EXIT_FAILURE, -+ "Error - Failure associating queue device %s (timeout after %d s).", -+ dev, MAX_ASSOC_POLL_TIME_IN_S); -+ -+ if (sscanf(buf, "associated %d", &i) != 1 || idx != i) -+ errx(EXIT_FAILURE, -+ "Error - Failure associating queue device %s (state '%s' found).", -+ dev, buf); -+ -+ verbose("Queue device %s successful associated with index %d.\n", -+ dev, idx); -+ -+ free(dev_path); -+ free(attr); -+} -+ -+static void se_bind(const char *dev) -+{ -+ char *dev_path, *attr; -+ int rc, ap, dom; -+ char buf[256]; -+ -+ if (!ap_bus_has_SB_support()) -+ errx(EXIT_FAILURE, "Error - AP bus: SE bind support is not available."); -+ -+ if (sscanf(dev, "%02x.%04x", &ap, &dom) != 2) -+ errx(EXIT_FAILURE, "Error - Can't parse queue device '%s' as xy.abcd.", -+ dev); -+ dev_path = util_path_sysfs("bus/ap/devices/card%02x/%02x.%04x", -+ ap, ap, dom); -+ if (!util_path_is_dir(dev_path)) -+ errx(EXIT_FAILURE, "Error - Queue device %s does not exist.", -+ dev); -+ -+ attr = util_path_sysfs("bus/ap/devices/card%02x/%02x.%04x/se_bind", -+ ap, ap, dom); -+ if (!util_path_is_writable(attr)) -+ errx(EXIT_FAILURE, "Error - Can't write to %s (errno '%s').", -+ attr, strerror(errno)); -+ -+ /* read se_bind attribute and check for 'unboud' */ -+ rc = util_file_read_line(buf, sizeof(buf), attr); -+ if (rc) -+ errx(EXIT_FAILURE, "Error - Failure reading from %s (errno '%s').", -+ attr, strerror(errno)); -+ if (strcmp(buf, "unbound")) -+ errx(EXIT_FAILURE, -+ "Error - Queue device %s is NOT in 'unbound' state (state '%s' found).", -+ dev, buf); -+ -+ /* write se_bind attribute, check for 'bound' afterwards */ -+ rc = util_file_write_l(1, 10, attr); -+ if (rc) -+ errx(EXIT_FAILURE, "Error - Failure writing to %s (errno '%s').", -+ attr, strerror(errno)); -+ rc = util_file_read_line(buf, sizeof(buf), attr); -+ if (rc) -+ errx(EXIT_FAILURE, "Error - Failure reading from %s (errno '%s').", -+ attr, strerror(errno)); -+ if (strcmp(buf, "bound")) -+ errx(EXIT_FAILURE, "Error - Failure binding queue device %s (state '%s' found).", -+ dev, buf); -+ -+ verbose("Queue device %s successful bound.\n", dev); -+ -+ free(dev_path); -+ free(attr); -+} -+ -+static void se_unbind(const char *dev) -+{ -+ int rc, ap, dom, loop; -+ char *dev_path, *attr; -+ char buf[256]; -+ -+ if (!ap_bus_has_SB_support()) -+ errx(EXIT_FAILURE, "Error - AP bus: SE bind support is not available."); -+ -+ if (sscanf(dev, "%02x.%04x", &ap, &dom) != 2) -+ errx(EXIT_FAILURE, "Error - Can't parse queue device '%s' as xy.abcd.", -+ dev); -+ dev_path = util_path_sysfs("bus/ap/devices/card%02x/%02x.%04x", -+ ap, ap, dom); -+ if (!util_path_is_dir(dev_path)) -+ errx(EXIT_FAILURE, "Error - Queue device %s does not exist.", -+ dev); -+ -+ attr = util_path_sysfs("bus/ap/devices/card%02x/%02x.%04x/se_bind", -+ ap, ap, dom); -+ if (!util_path_is_writable(attr)) -+ errx(EXIT_FAILURE, "Error - Can't write to %s (errno '%s').", -+ attr, strerror(errno)); -+ -+ /* write se_bind attribute */ -+ rc = util_file_write_l(0, 10, attr); -+ if (rc) -+ errx(EXIT_FAILURE, "Error - Failure writing to %s (errno '%s').", -+ attr, strerror(errno)); -+ -+ /* loop up to MAX_UNBIND_POLL_TIME_IN_S seconds for completion */ -+ for (loop = 0; loop < 2 * MAX_UNBIND_POLL_TIME_IN_S; usleep(500000), loop++) { -+ rc = util_file_read_line(buf, sizeof(buf), attr); -+ if (rc) -+ errx(EXIT_FAILURE, "Error - Failure reading from %s (errno '%s').", -+ attr, strerror(errno)); -+ if (!strcmp(buf, "unbound")) -+ break; -+ } -+ if (loop >= 2 * MAX_UNBIND_POLL_TIME_IN_S) -+ errx(EXIT_FAILURE, -+ "Error - Failure unbinding queue device %s (timeout after %d s).", -+ dev, MAX_UNBIND_POLL_TIME_IN_S); -+ -+ verbose("Queue device %s successful unbound.\n", dev); -+ -+ free(dev_path); -+ free(attr); -+} -+ - /* - * Print invalid commandline error message and then exit with error code - */ -@@ -389,10 +594,10 @@ static void print_adapter_id_help(void) - printf("DEVICE_IDS\n"); - printf(" List of cryptographic device ids separated by blanks which will be set\n"); - printf(" online/offline. Must be used in conjunction with the enable or disable option.\n"); -- - printf(" DEVICE_ID could either be card device id ('') or queue device id\n"); -- printf(" '.').\n"); -- printf(" \n"); -+ printf(" '.').\n\n"); -+ printf("QUEUE_DEVICE:\n"); -+ printf(" An APQN queue device given as xy.abcd as it is listed by lszcrypt -V.\n\n"); - printf("EXAMPLE:\n"); - printf(" Disable the cryptographic device with card id '02' (inclusive all queues).\n"); - printf(" #>chzcrypt -d 02\n"); -@@ -407,13 +612,14 @@ static void print_adapter_id_help(void) - */ - int main(int argc, char *argv[]) - { -+ const char *default_domain = NULL, *config = NULL, *config_text = NULL; - const char *online = NULL, *online_text = NULL, *poll_thread = NULL; - const char *config_time = NULL, *poll_timeout = NULL; -- const char *default_domain = NULL, *config = NULL, *config_text = NULL; -+ const char *queue_device = NULL, *assoc_idx = NULL; -+ int c, i, j, action = 0; - char *path, *dev_list; -- bool all = false, actionset = false; -+ bool all = false; - size_t len; -- int c, i, j; - - for (i=0; i < argc; i++) - for (j=2; j < (int) strlen(argv[i]); j++) -@@ -428,12 +634,12 @@ int main(int argc, char *argv[]) - break; - switch (c) { - case 'e': -- actionset = true; -+ action = c; - online = "1"; - online_text = "online"; - break; - case 'd': -- actionset = true; -+ action = c; - online = "0"; - online_text = "offline"; - break; -@@ -441,23 +647,23 @@ int main(int argc, char *argv[]) - all = true; - break; - case 'p': -- actionset = true; -+ action = c; - poll_thread = "1"; - break; - case 'n': -- actionset = true; -+ action = c; - poll_thread = "0"; - break; - case 'c': -- actionset = true; -+ action = c; - config_time = optarg; - break; - case 't': -- actionset = true; -+ action = c; - poll_timeout = optarg; - break; - case 'q': -- actionset = true; -+ action = c; - default_domain = optarg; - break; - case 'V': -@@ -472,21 +678,31 @@ int main(int argc, char *argv[]) - util_prg_print_version(); - return EXIT_SUCCESS; - case OPT_CONFIG_ON: -- actionset = true; -+ action = c; - config = "1"; - config_text = "config on"; - break; - case OPT_CONFIG_OFF: -- actionset = true; -+ action = c; - config = "0"; - config_text = "config off"; - break; -+ case OPT_SE_ASSOC: -+ action = c; -+ assoc_idx = optarg; -+ break; -+ case OPT_SE_BIND: -+ action = c; -+ break; -+ case OPT_SE_UNBIND: -+ action = c; -+ break; - default: - util_opt_print_parse_error(c, argv); - return EXIT_FAILURE; - } - } -- if (!actionset) -+ if (!action) - invalid_cmdline_exit("Error - missing argument.\n"); - path = util_path_sysfs("bus/ap"); - if (!util_path_is_dir(path)) -@@ -508,6 +724,32 @@ int main(int argc, char *argv[]) - default_domain_set(default_domain); - return EXIT_SUCCESS; - } -+ -+ if (action == OPT_SE_ASSOC) { -+ if (optind >= argc) -+ errx(EXIT_FAILURE, -+ "Error - The --se-associate needs a queue device given."); -+ queue_device = argv[optind]; -+ se_assoc(assoc_idx, queue_device); -+ return EXIT_SUCCESS; -+ } -+ if (action == OPT_SE_BIND) { -+ if (optind >= argc) -+ errx(EXIT_FAILURE, -+ "Error - The --se-bind needs a queue device given."); -+ queue_device = argv[optind]; -+ se_bind(queue_device); -+ return EXIT_SUCCESS; -+ } -+ if (action == OPT_SE_UNBIND) { -+ if (optind >= argc) -+ errx(EXIT_FAILURE, -+ "Error - The --se-unbind needs a queue device given."); -+ queue_device = argv[optind]; -+ se_unbind(queue_device); -+ return EXIT_SUCCESS; -+ } -+ - if (all) - dev_list_all(&dev_list, &len); - else --- -2.41.0 - - -From a2a364b456185eebca87f43b280c4f25b323f65b Mon Sep 17 00:00:00 2001 -From: Steffen Maier -Date: Tue, 1 Aug 2023 18:58:45 +0200 -Subject: [PATCH 7/7] zdev/dracut: fix kdump build to integrate with site - support (#2229177) -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This complements v2.27.0 commit 73c46a30563d ("zdev/dracut: fix kdump by -only activating required devices"). On older distributions, the absence of -zdev_id can cause the following harmless error messages for each udev -event: - -(spawn)[387]: failed to execute '/lib/s390-tools/zdev_id' \ -'/lib/s390-tools/zdev_id': No such file or directory - -Kdump is still functional nonetheless. - -As of v2.24.0 commit 2e89722ef0ec ("zdev: make site specific udev-rule for -ccw"), the invocations of chzdev within -zdev/dracut/95zdev-kdump/module-setup.sh generate -/etc/udev/rules.d/40-zdev-id.rules. And so even though zdev-kdump -intentionally does not install zdev_id and its previous singular user -zdev/udev/81-dpm.rules into the kdump initrd, because DPM device auto -configuration is not desired in the kdump environment, zdev_id meanwhile -has an additional functionality for site-support and the generated -40-zdev-id.rules calls /lib/s390-tools/zdev_id. By installing zdev_id into -the kdump initrd, 40-zdev-id.rules can work without error. - -Fixes: 73c46a30563d ("zdev/dracut: fix kdump by only activating required devices") -Reviewed-by: Alexander Egorenkov -Reviewed-by: Vineeth Vijayan -Signed-off-by: Steffen Maier -Signed-off-by: Jan Höppner -(cherry picked from commit 4b486e87cc2875f532784bd69ee680e714508059) ---- - zdev/dracut/95zdev-kdump/module-setup.sh | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/zdev/dracut/95zdev-kdump/module-setup.sh b/zdev/dracut/95zdev-kdump/module-setup.sh -index ad8e309..4ce2fc6 100755 ---- a/zdev/dracut/95zdev-kdump/module-setup.sh -+++ b/zdev/dracut/95zdev-kdump/module-setup.sh -@@ -46,6 +46,10 @@ installkernel() { - install() { - local _tempfile - -+ # zdev_id is not functionally required for kdump but optionally -+ # installing avoids error messages from zdev site udev rule processing -+ inst_multiple -o /lib/s390-tools/zdev_id -+ - # Obtain kdump target device configuration - - _tempfile=$(mktemp --tmpdir dracut-zdev.XXXXXX) --- -2.41.0 - diff --git a/s390utils-2.29.0-rhel.patch b/s390utils-2.29.0-rhel.patch new file mode 100644 index 0000000..91f8809 --- /dev/null +++ b/s390utils-2.29.0-rhel.patch @@ -0,0 +1,734 @@ +From a32824922cb273703bacd44e6a29cbc33ae48cf5 Mon Sep 17 00:00:00 2001 +From: Ingo Franzki +Date: Fri, 21 Jul 2023 14:06:18 +0200 +Subject: [PATCH] zkey: Support EP11 AES keys with prepended header to retain + EP11 session (RHEL-11440) + +The pkey kernel module supports two key blob formats for EP11 AES keys. +The first one (PKEY_TYPE_EP11) contains a 16 bytes header that overlays +the first 32 bytes of the key blob which usually contain the ID of the +EP11 session to which the key is bound. For zkey/dm-crypt that session +ID used to be all zeros. The second blob format (PKEY_TYPE_EP11_AES) +prepends the 16 bytes header to the blob, an thus does not overlay the +blob. This format can be used for key blobs that are session-bound, i.e. +have a non-zero session ID in the first 32 bytes. + +Change zkey to generate EP11 keys using the new format (i.e. pkey type +PKEY_TYPE_EP11_AES), but existing key blobs using the old format can +still be used. + +Signed-off-by: Ingo Franzki +Reviewed-by: Joerg Schmidbauer +Signed-off-by: Steffen Eiden +(cherry picked from commit 1b044b8a40ab59e4f5ffe66e3ad81499b0beccce) +--- + zkey/ep11.c | 48 +++++++++----- + zkey/keystore.c | 4 +- + zkey/kmip/zkey-kmip.c | 76 ++++++++++++++++++---- + zkey/kms.c | 9 ++- + zkey/pkey.c | 141 +++++++++++++++++++++++++++++++++++++++-- + zkey/pkey.h | 45 +++++++++---- + zkey/zkey-cryptsetup.c | 15 ++++- + zkey/zkey.c | 8 ++- + 8 files changed, 295 insertions(+), 51 deletions(-) + +diff --git a/zkey/ep11.c b/zkey/ep11.c +index 8359929..df8b57d 100644 +--- a/zkey/ep11.c ++++ b/zkey/ep11.c +@@ -365,8 +365,9 @@ int select_ep11_apqn_by_mkvp(struct ep11_lib *ep11, u8 *mkvp, + * @param[in] target the target handle to use for the re-encipher operation + * @param[in] card the card that corresponds to the target handle + * @param[in] domain the domain that corresponds to the target handle +- * @param[in/out] ep11key the EP11 key token to reencipher. The re-enciphered +- * secure key will be returned in this buffer. ++ * @param[in/out] ep11key_blob the EP11 key token to reencipher. The ++ * re-enciphered secure key will be returned in this ++ * buffer. + * @param[in] ep11key_size the size of the secure key + * @param[in] verbose if true, verbose messages are printed + * +@@ -374,21 +375,29 @@ int select_ep11_apqn_by_mkvp(struct ep11_lib *ep11, u8 *mkvp, + */ + static int ep11_adm_reencrypt(struct ep11_lib *ep11, target_t target, + unsigned int card, unsigned int domain, +- struct ep11keytoken *ep11key, ++ u8 *ep11key_blob, + unsigned int ep11key_size, bool verbose) + { ++ struct ep11kblob_header *hdr = (struct ep11kblob_header *)ep11key_blob; ++ struct ep11keytoken *ep11key; + CK_BYTE resp[MAX_BLOBSIZE]; + CK_BYTE req[MAX_BLOBSIZE]; +- char ep11_token_header[sizeof(ep11key->head)]; ++ char ep11_token_header[sizeof(ep11key->head)] = { 0 }; + struct XCPadmresp lrb; + struct XCPadmresp rb; ++ bool with_header; + size_t resp_len; + size_t blob_len; + long req_len; + CK_RV rv; + int rc; + +- blob_len = ep11key->head.length; ++ with_header = is_ep11_aes_key_with_header(ep11key_blob, ep11key_size); ++ ep11key = (struct ep11keytoken *)(with_header ? ++ ep11key_blob + sizeof(struct ep11kblob_header) : ++ ep11key_blob); ++ blob_len = with_header ? hdr->len - sizeof(struct ep11kblob_header) : ++ ep11key->head.len; + if (blob_len > ep11key_size) { + pr_verbose(verbose, "Blob length larger than secure key size"); + return -EINVAL; +@@ -397,9 +406,14 @@ static int ep11_adm_reencrypt(struct ep11_lib *ep11, target_t target, + rb.domain = domain; + lrb.domain = domain; + +- /* The token header is an overlay over the (all zero) session field */ +- memcpy(ep11_token_header, ep11key, sizeof(ep11_token_header)); +- memset(ep11key->session, 0, sizeof(ep11key->session)); ++ if (!with_header) { ++ /* ++ * The token header is an overlay over the (all zero) session ++ * field ++ */ ++ memcpy(ep11_token_header, ep11key, sizeof(ep11_token_header)); ++ memset(ep11key->session, 0, sizeof(ep11key->session)); ++ } + + resp_len = sizeof(resp); + req_len = ep11->dll_xcpa_cmdblock(req, sizeof(req), XCP_ADM_REENCRYPT, +@@ -446,7 +460,8 @@ static int ep11_adm_reencrypt(struct ep11_lib *ep11, target_t target, + } + + memcpy(ep11key, lrb.payload, blob_len); +- memcpy(ep11key, ep11_token_header, sizeof(ep11_token_header)); ++ if (!with_header) ++ memcpy(ep11key, ep11_token_header, sizeof(ep11_token_header)); + + return 0; + } +@@ -469,7 +484,6 @@ int reencipher_ep11_key(struct ep11_lib *ep11, target_t target, + unsigned int card, unsigned int domain, u8 *secure_key, + unsigned int secure_key_size, bool verbose) + { +- struct ep11keytoken *ep11key = (struct ep11keytoken *)secure_key; + CK_IBM_DOMAIN_INFO dinf; + CK_ULONG dinf_len = sizeof(dinf); + CK_RV rv; +@@ -493,17 +507,21 @@ int reencipher_ep11_key(struct ep11_lib *ep11, target_t target, + return -ENODEV; + } + +- rc = ep11_adm_reencrypt(ep11, target, card, domain, ep11key, ++ rc = ep11_adm_reencrypt(ep11, target, card, domain, secure_key, + secure_key_size, verbose); + if (rc != 0) + return rc; + + if (is_xts_key(secure_key, secure_key_size)) { +- secure_key += EP11_KEY_SIZE; +- secure_key_size -= EP11_KEY_SIZE; +- ep11key = (struct ep11keytoken *)secure_key; ++ if (is_ep11_aes_key_with_header(secure_key, secure_key_size)) { ++ secure_key += EP11_AES_KEY_SIZE; ++ secure_key_size -= EP11_AES_KEY_SIZE; ++ } else { ++ secure_key += EP11_KEY_SIZE; ++ secure_key_size -= EP11_KEY_SIZE; ++ } + +- rc = ep11_adm_reencrypt(ep11, target, card, domain, ep11key, ++ rc = ep11_adm_reencrypt(ep11, target, card, domain, secure_key, + secure_key_size, verbose); + if (rc != 0) + return rc; +diff --git a/zkey/keystore.c b/zkey/keystore.c +index 4efa2e4..c0a7037 100644 +--- a/zkey/keystore.c ++++ b/zkey/keystore.c +@@ -3398,7 +3398,9 @@ static int _keystore_perform_reencipher(struct keystore *keystore, + "CURRENT master key", name); + if (!selected && + !is_ep11_aes_key(secure_key, +- secure_key_size)) ++ secure_key_size) && ++ !is_ep11_aes_key_with_header(secure_key, ++ secure_key_size)) + print_msg_for_cca_envvars( + "secure AES key"); + } +diff --git a/zkey/kmip/zkey-kmip.c b/zkey/kmip/zkey-kmip.c +index a00c5dd..e7b7c73 100644 +--- a/zkey/kmip/zkey-kmip.c ++++ b/zkey/kmip/zkey-kmip.c +@@ -5278,9 +5278,11 @@ static int _ep11_unwrap_key_rsa(struct plugin_handle *ph, + m_UnwrapKey_t dll_m_UnwrapKey; + const unsigned char *key_blob; + struct ep11keytoken *ep11key; ++ struct ep11kblob_header *hdr; + CK_MECHANISM mech = { 0 }; + CK_BYTE csum[7] = { 0 }; + CK_BBOOL ck_true = true; ++ int pkey_fd, rc; + CK_RV rv; + + CK_ATTRIBUTE template[] = { +@@ -5306,7 +5308,8 @@ static int _ep11_unwrap_key_rsa(struct plugin_handle *ph, + pr_verbose(&ph->pd, "Wrap hashing algorithm: %d", + ph->profile->wrap_hashing_algo); + +- if (*unwrapped_key_len < sizeof(struct ep11keytoken)) { ++ if (*unwrapped_key_len < sizeof(struct ep11kblob_header) + ++ sizeof(struct ep11keytoken)) { + _set_error(ph, "Key buffer is too small"); + return -EINVAL; + } +@@ -5381,19 +5384,68 @@ static int _ep11_unwrap_key_rsa(struct plugin_handle *ph, + 256 * 256 * csum[csum_len - 3] + + 256 * 256 * 256 * csum[csum_len - 4]; + +- /* Setup the EP11 token header */ +- ep11key = (struct ep11keytoken *)unwrapped_key; +- memset(&ep11key->session, 0, sizeof(ep11key->session)); +- ep11key->head.type = TOKEN_TYPE_NON_CCA; +- ep11key->head.length = *unwrapped_key_len; +- ep11key->head.version = TOKEN_VERSION_EP11_AES; +- ep11key->head.keybitlen = bit_len; +- +- pr_verbose(&ph->pd, "unwrapped bit length: %u", +- ep11key->head.keybitlen); ++ /* Prepend and setup the EP11 token header */ ++ hdr = (struct ep11kblob_header *)unwrapped_key; ++ ep11key = (struct ep11keytoken *) ++ (unwrapped_key + sizeof(struct ep11kblob_header)); ++ memmove(ep11key, unwrapped_key, *unwrapped_key_len); ++ *unwrapped_key_len += sizeof(struct ep11kblob_header); ++ memset(hdr, 0, sizeof(struct ep11kblob_header)); ++ hdr->type = TOKEN_TYPE_NON_CCA; ++ hdr->hver = 0; ++ hdr->len = *unwrapped_key_len; ++ hdr->version = TOKEN_VERSION_EP11_AES_WITH_HEADER; ++ hdr->bitlen = bit_len; ++ ++ pr_verbose(&ph->pd, "unwrapped bit length: %u", hdr->bitlen); + + /* return full length, blob is already zero padded */ +- *unwrapped_key_len = sizeof(struct ep11keytoken); ++ *unwrapped_key_len = ++ sizeof(struct ep11kblob_header) + sizeof(struct ep11keytoken); ++ ++ /* ++ * Check if the pkey module supports keys of type ++ * TOKEN_VERSION_EP11_AES_WITH_HEADER, older kernels may not support ++ * such keys. If it does not support such keys, convert the key to ++ * TOKEN_VERSION_EP11_AES type, if its session field is all zero ++ * (i.e. the key is not session bound). ++ */ ++ pkey_fd = open_pkey_device(ph->pd.verbose); ++ if (pkey_fd < 0) { ++ _set_error(ph, "Failed to open pkey device"); ++ return -EIO; ++ } ++ ++ rc = validate_secure_key(pkey_fd, unwrapped_key, *unwrapped_key_len, ++ NULL, NULL, NULL, ph->pd.verbose); ++ close(pkey_fd); ++ if (rc == -EINVAL || rc == -ENODEV) { ++ pr_verbose(&ph->pd, "The pkey kernel module does not support " ++ "PKEY_TYPE_EP11_AES, fall back to PKEY_TYPE_EP11"); ++ ++ if (is_ep11_key_session_bound(unwrapped_key, ++ *unwrapped_key_len)) { ++ _set_error(ph, "The unwrapped key is session bound. " ++ "Kernel support is required for such keys"); ++ return -EIO; ++ } ++ ++ key_blob_len = hdr->len; ++ *unwrapped_key_len -= sizeof(struct ep11kblob_header); ++ memmove(unwrapped_key, ++ unwrapped_key + sizeof(struct ep11kblob_header), ++ *unwrapped_key_len); ++ ep11key = (struct ep11keytoken *)unwrapped_key; ++ memset(&ep11key->session, 0, sizeof(ep11key->session)); ++ ep11key->head.type = TOKEN_TYPE_NON_CCA; ++ ep11key->head.len = key_blob_len - ++ sizeof(struct ep11kblob_header); ++ ep11key->head.version = TOKEN_VERSION_EP11_AES; ++ ep11key->head.bitlen = bit_len; ++ } else if (rc != 0) { ++ _set_error(ph, "Failed to validate unwrapped key"); ++ return rc; ++ } + + return 0; + } +diff --git a/zkey/kms.c b/zkey/kms.c +index 9892a9e..2e33b22 100644 +--- a/zkey/kms.c ++++ b/zkey/kms.c +@@ -2175,7 +2175,7 @@ int generate_kms_key(struct kms_info *kms_info, const char *name, + else if (strcasecmp(key_type, KEY_TYPE_CCA_AESCIPHER) == 0) + key_size = AESCIPHER_KEY_SIZE; + else if (strcasecmp(key_type, KEY_TYPE_EP11_AES) == 0) +- key_size = EP11_KEY_SIZE; ++ key_size = EP11_AES_KEY_SIZE; + else + return -ENOTSUP; + +@@ -2248,6 +2248,9 @@ int generate_kms_key(struct kms_info *kms_info, const char *name, + if (verbose) + util_hexdump_grp(stderr, NULL, key_blob, 4, key_blob_size, 0); + ++ if (is_ep11_aes_key(key_blob, key_blob_size)) ++ key_size = EP11_KEY_SIZE; ++ + /* Save ID and label of 1st key */ + rc = properties_set(key_props, xts ? PROP_NAME_KMS_XTS_KEY1_ID : + PROP_NAME_KMS_KEY_ID, key1_id); +@@ -3132,6 +3135,8 @@ int import_kms_key(struct kms_info *kms_info, const char *key1_id, + key_size = AESCIPHER_KEY_SIZE; + else if (is_ep11_aes_key(key_blob, key_blob_size)) + key_size = EP11_KEY_SIZE; ++ else if (is_ep11_aes_key_with_header(key_blob, key_blob_size)) ++ key_size = EP11_AES_KEY_SIZE; + + if (key_size == 0 || key_blob_size > key_size) { + pr_verbose(verbose, "Key '%s' has an unknown or unsupported " +@@ -3366,6 +3371,8 @@ int refresh_kms_key(struct kms_info *kms_info, struct properties *key_props, + key_size = AESCIPHER_KEY_SIZE; + else if (is_ep11_aes_key(key_blob, key_blob_size)) + key_size = EP11_KEY_SIZE; ++ else if (is_ep11_aes_key_with_header(key_blob, key_blob_size)) ++ key_size = EP11_AES_KEY_SIZE; + + if (key_size == 0 || key_blob_size > key_size) { + pr_verbose(verbose, "Key '%s' has an unknown or unsupported " +diff --git a/zkey/pkey.c b/zkey/pkey.c +index e013e06..2582088 100644 +--- a/zkey/pkey.c ++++ b/zkey/pkey.c +@@ -858,7 +858,7 @@ static enum pkey_key_type key_type_to_pkey_type(const char *key_type) + if (strcasecmp(key_type, KEY_TYPE_CCA_AESCIPHER) == 0) + return PKEY_TYPE_CCA_CIPHER; + if (strcasecmp(key_type, KEY_TYPE_EP11_AES) == 0) +- return PKEY_TYPE_EP11; ++ return PKEY_TYPE_EP11_AES; + + return 0; + } +@@ -879,6 +879,8 @@ static size_t key_size_for_type(enum pkey_key_type type) + return AESCIPHER_KEY_SIZE; + case PKEY_TYPE_EP11: + return EP11_KEY_SIZE; ++ case PKEY_TYPE_EP11_AES: ++ return EP11_AES_KEY_SIZE; + default: + return 0; + } +@@ -924,6 +926,7 @@ int generate_secure_key_random(int pkey_fd, const char *keyfile, + return -ENOTSUP; + } + ++retry: + genseck2.size = keybits_to_keysize(keybits); + if (genseck2.size == 0) { + warnx("Invalid value for '--keybits'/'-c': '%lu'", keybits); +@@ -957,10 +960,33 @@ int generate_secure_key_random(int pkey_fd, const char *keyfile, + genseck2.keylen = size; + + rc = pkey_genseck2(pkey_fd, &genseck2, verbose); ++ if (rc == -EINVAL && genseck2.type == PKEY_TYPE_EP11_AES) { ++ /* ++ * Older kernels may not support gensek2 with key type ++ * PKEY_TYPE_EP11_AES, retry with PKEY_TYPE_EP11. ++ */ ++ pr_verbose(verbose, ++ "ioctl PKEY_GENSECK2 does not support " ++ "PKEY_TYPE_EP11_AES, fall back to PKEY_TYPE_EP11"); ++ ++ genseck2.type = PKEY_TYPE_EP11; ++ free(genseck2.apqns); ++ genseck2.apqns = NULL; ++ genseck2.apqn_entries = 0; ++ free(secure_key); ++ goto retry; ++ } + if (rc != 0) { + warnx("Failed to generate a secure key: %s", strerror(-rc)); + goto out; + } ++ if (rc == 0 && genseck2.type == PKEY_TYPE_EP11) { ++ if (is_ep11_key_session_bound(secure_key, size)) { ++ warnx("The generated key is session bound. Kernel " ++ "support is required for such keys"); ++ goto out; ++ } ++ } + + if (xts) { + free(genseck2.apqns); +@@ -1062,6 +1088,7 @@ int generate_secure_key_clear(int pkey_fd, const char *keyfile, + return -ENOTSUP; + } + ++retry: + clr2seck2.size = keybits_to_keysize(HALF_KEYSIZE_FOR_XTS( + clear_key_size * 8, xts)); + if (clr2seck2.size == 0) { +@@ -1096,10 +1123,33 @@ int generate_secure_key_clear(int pkey_fd, const char *keyfile, + clr2seck2.keylen = size; + + rc = pkey_clr2seck2(pkey_fd, &clr2seck2, verbose); ++ if (rc == -EINVAL && clr2seck2.type == PKEY_TYPE_EP11_AES) { ++ /* ++ * Older kernels may not support clr2seck2 with key type ++ * PKEY_TYPE_EP11_AES, retry with PKEY_TYPE_EP11. ++ */ ++ pr_verbose(verbose, ++ "ioctl PKEY_CLR2SECK2 does not support " ++ "PKEY_TYPE_EP11_AES, fall back to PKEY_TYPE_EP11"); ++ ++ clr2seck2.type = PKEY_TYPE_EP11; ++ free(clr2seck2.apqns); ++ clr2seck2.apqns = NULL; ++ clr2seck2.apqn_entries = 0; ++ free(secure_key); ++ goto retry; ++ } + if (rc != 0) { + warnx("Failed to generate a secure key: %s", strerror(-rc)); + goto out; + } ++ if (rc == 0 && clr2seck2.type == PKEY_TYPE_EP11) { ++ if (is_ep11_key_session_bound(secure_key, size)) { ++ warnx("The generated key is session bound. Kernel " ++ "support is required for such keys"); ++ goto out; ++ } ++ } + + if (xts) { + free(clr2seck2.apqns); +@@ -1486,6 +1536,8 @@ int get_master_key_verification_pattern(const u8 *key, size_t key_size, + struct aesdatakeytoken *datakey = (struct aesdatakeytoken *)key; + struct aescipherkeytoken *cipherkey = (struct aescipherkeytoken *)key; + struct ep11keytoken *ep11key = (struct ep11keytoken *)key; ++ struct ep11keytoken *ep11key2 = ++ (struct ep11keytoken *)(key + sizeof(struct ep11kblob_header)); + + util_assert(key != NULL, "Internal error: secure_key is NULL"); + util_assert(mkvp != NULL, "Internal error: mkvp is NULL"); +@@ -1497,6 +1549,8 @@ int get_master_key_verification_pattern(const u8 *key, size_t key_size, + memcpy(mkvp, &cipherkey->kvp, sizeof(cipherkey->kvp)); + else if (is_ep11_aes_key(key, key_size)) + memcpy(mkvp, &ep11key->wkvp, sizeof(ep11key->wkvp)); ++ else if (is_ep11_aes_key_with_header(key, key_size)) ++ memcpy(mkvp, &ep11key2->wkvp, sizeof(ep11key2->wkvp)); + else + return -EINVAL; + +@@ -1593,9 +1647,43 @@ bool is_ep11_aes_key(const u8 *key, size_t key_size) + + if (ep11key->head.type != TOKEN_TYPE_NON_CCA) + return false; ++ if (ep11key->head.hver != 0) ++ return false; + if (ep11key->head.version != TOKEN_VERSION_EP11_AES) + return false; +- if (ep11key->head.length > key_size) ++ if (ep11key->head.len > key_size) ++ return false; ++ ++ if (ep11key->version != 0x1234) ++ return false; ++ ++ return true; ++} ++ ++/** ++ * Check if the specified key is a EP11 AES key token with external header. ++ * ++ * @param[in] key the secure key token ++ * @param[in] key_size the size of the secure key ++ * ++ * @returns true if the key is an EP11 AES token with external header type ++ */ ++bool is_ep11_aes_key_with_header(const u8 *key, size_t key_size) ++{ ++ struct ep11kblob_header *header = (struct ep11kblob_header *)key; ++ struct ep11keytoken *ep11key = ++ (struct ep11keytoken *)(key + sizeof(struct ep11kblob_header)); ++ ++ if (key == NULL || key_size < EP11_AES_KEY_SIZE) ++ return false; ++ ++ if (header->type != TOKEN_TYPE_NON_CCA) ++ return false; ++ if (header->hver != 0) ++ return false; ++ if (header->version != TOKEN_VERSION_EP11_AES_WITH_HEADER) ++ return false; ++ if (header->len > key_size) + return false; + + if (ep11key->version != 0x1234) +@@ -1604,6 +1692,33 @@ bool is_ep11_aes_key(const u8 *key, size_t key_size) + return true; + } + ++/** ++ * Check if the specified EP11 AES key is session bound. ++ * ++ * @param[in] key the secure key token ++ * @param[in] key_size the size of the secure key ++ * ++ * @returns true if the key is an EP11 AES token type ++ */ ++bool is_ep11_key_session_bound(const u8 *key, size_t key_size) ++{ ++ struct ep11keytoken *ep11key; ++ ++ if (is_ep11_aes_key(key, key_size)) { ++ ep11key = (struct ep11keytoken *)key; ++ return memcmp(ep11key->session + sizeof(ep11key->head), ++ ZERO_SESSION, sizeof(ep11key->session) - ++ sizeof(ep11key->head)) != 0; ++ } else if (is_ep11_aes_key_with_header(key, key_size)) { ++ ep11key = (struct ep11keytoken *) ++ (key + sizeof(struct ep11kblob_header)); ++ return memcmp(ep11key->session, ZERO_SESSION, ++ sizeof(ep11key->session)) != 0; ++ } else { ++ return false; ++ } ++} ++ + /** + * Check if the specified key is an XTS type key + * +@@ -1629,6 +1744,11 @@ bool is_xts_key(const u8 *key, size_t key_size) + is_ep11_aes_key(key + EP11_KEY_SIZE, + key_size - EP11_KEY_SIZE)) + return true; ++ } else if (is_ep11_aes_key_with_header(key, key_size)) { ++ if (key_size == 2 * EP11_AES_KEY_SIZE && ++ is_ep11_aes_key_with_header(key + EP11_AES_KEY_SIZE, ++ key_size - EP11_AES_KEY_SIZE)) ++ return true; + } + + return false; +@@ -1650,6 +1770,7 @@ int get_key_bit_size(const u8 *key, size_t key_size, size_t *bitsize) + struct aesdatakeytoken *datakey = (struct aesdatakeytoken *)key; + struct aescipherkeytoken *cipherkey = (struct aescipherkeytoken *)key; + struct ep11keytoken *ep11key = (struct ep11keytoken *)key; ++ struct ep11kblob_header *hdr = (struct ep11kblob_header *)key; + + util_assert(bitsize != NULL, "Internal error: bitsize is NULL"); + +@@ -1672,10 +1793,17 @@ int get_key_bit_size(const u8 *key, size_t key_size, size_t *bitsize) + *bitsize += cipherkey->pl - 384; + } + } else if (is_ep11_aes_key(key, key_size)) { +- *bitsize = ep11key->head.keybitlen; ++ *bitsize = ep11key->head.bitlen; + if (key_size == 2 * EP11_KEY_SIZE) { + ep11key = (struct ep11keytoken *)(key + EP11_KEY_SIZE); +- *bitsize += ep11key->head.keybitlen; ++ *bitsize += ep11key->head.bitlen; ++ } ++ } else if (is_ep11_aes_key_with_header(key, key_size)) { ++ *bitsize = hdr->bitlen; ++ if (key_size == 2 * EP11_AES_KEY_SIZE) { ++ hdr = (struct ep11kblob_header *) ++ (key + EP11_AES_KEY_SIZE); ++ *bitsize += hdr->bitlen; + } + } else { + return -EINVAL; +@@ -1700,6 +1828,8 @@ const char *get_key_type(const u8 *key, size_t key_size) + return KEY_TYPE_CCA_AESCIPHER; + if (is_ep11_aes_key(key, key_size)) + return KEY_TYPE_EP11_AES; ++ if (is_ep11_aes_key_with_header(key, key_size)) ++ return KEY_TYPE_EP11_AES; + return NULL; + } + +@@ -2016,7 +2146,8 @@ int reencipher_secure_key(struct ext_lib *lib, u8 *secure_key, + return rc; + } + +- if (is_ep11_aes_key(secure_key, secure_key_size)) { ++ if (is_ep11_aes_key(secure_key, secure_key_size) || ++ is_ep11_aes_key_with_header(secure_key, secure_key_size)) { + /* EP11 secure key: need the EP11 host library */ + if (lib->ep11->lib_ep11 == NULL) { + rc = load_ep11_library(lib->ep11, verbose); +diff --git a/zkey/pkey.h b/zkey/pkey.h +index 5a5bc3c..3b57c5f 100644 +--- a/zkey/pkey.h ++++ b/zkey/pkey.h +@@ -39,6 +39,8 @@ struct tokenheader { + #define TOKEN_VERSION_PROTECTED_KEY 0x01 + #define TOKEN_VERSION_CLEAR_KEY 0x02 + #define TOKEN_VERSION_EP11_AES 0x03 ++#define TOKEN_VERSION_EP11_AES_WITH_HEADER 0x06 ++#define TOKEN_VERSION_EP11_ECC_WITH_HEADER 0x07 + + struct aesdatakeytoken { + u8 type; /* TOKEN_TYPE_INTERNAL (0x01) for internal key token */ +@@ -89,17 +91,20 @@ struct aescipherkeytoken { + u8 varpart[80]; /* variable part */ + } __packed; + ++struct ep11kblob_header { ++ u8 type; /* always 0x00 */ ++ u8 hver; /* header version, currently needs to be 0x00 */ ++ u16 len; /* total length in bytes (including this header) */ ++ u8 version; /* PKEY_TYPE_EP11_AES or PKEY_TYPE_EP11_ECC */ ++ u8 res0; /* unused */ ++ u16 bitlen; /* clear key bit len, 0 for unknown */ ++ u8 res1[8]; /* unused */ ++} __packed; ++ + struct ep11keytoken { + union { + u8 session[32]; +- struct { +- u8 type; /* TOKEN_TYPE_NON_CCA (0x00) */ +- u8 res0; /* unused */ +- u16 length; /* length of token */ +- u8 version; /* TOKEN_VERSION_EP11_AES (0x03) */ +- u8 res1; /* unused */ +- u16 keybitlen; /* clear key bit len, 0 for unknown */ +- } head; ++ struct ep11kblob_header head; + }; + u8 wkvp[16]; /* wrapping key verification pattern */ + u64 attr; /* boolean key attributes */ +@@ -111,18 +116,29 @@ struct ep11keytoken { + u8 padding[64]; + } __packed; + ++#define ZERO_SESSION \ ++ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" ++ + #define AESDATA_KEY_SIZE sizeof(struct aesdatakeytoken) + #define AESCIPHER_KEY_SIZE sizeof(struct aescipherkeytoken) + #define EP11_KEY_SIZE sizeof(struct ep11keytoken) ++#define EP11_AES_KEY_SIZE (sizeof(struct ep11kblob_header) + \ ++ sizeof(struct ep11keytoken)) + + /* MAX/MIN from zt_common.h produces warnings for variable length arrays */ + #define _MIN(a, b) ((a) < (b) ? (a) : (b)) + #define _MAX(a, b) ((a) > (b) ? (a) : (b)) + +-#define MAX_SECURE_KEY_SIZE _MAX(EP11_KEY_SIZE, \ +- _MAX(AESDATA_KEY_SIZE, AESCIPHER_KEY_SIZE)) +-#define MIN_SECURE_KEY_SIZE _MIN(EP11_KEY_SIZE, \ +- _MIN(AESDATA_KEY_SIZE, AESCIPHER_KEY_SIZE)) ++#define MAX_SECURE_KEY_SIZE _MAX( \ ++ _MAX(EP11_KEY_SIZE, \ ++ EP11_AES_KEY_SIZE), \ ++ _MAX(AESDATA_KEY_SIZE, \ ++ AESCIPHER_KEY_SIZE)) ++#define MIN_SECURE_KEY_SIZE _MIN( \ ++ _MIN(EP11_KEY_SIZE, \ ++ EP11_AES_KEY_SIZE), \ ++ _MIN(AESDATA_KEY_SIZE, \ ++ AESCIPHER_KEY_SIZE)) + + struct pkey_seckey { + u8 seckey[AESDATA_KEY_SIZE]; /* the secure key blob */ +@@ -175,6 +191,9 @@ enum pkey_key_type { + PKEY_TYPE_CCA_DATA = (u32) 1, + PKEY_TYPE_CCA_CIPHER = (u32) 2, + PKEY_TYPE_EP11 = (u32) 3, ++ PKEY_TYPE_CCA_ECC = (u32) 0x1f, ++ PKEY_TYPE_EP11_AES = (u32) 6, ++ PKEY_TYPE_EP11_ECC = (u32) 7, + }; + + enum pkey_key_size { +@@ -321,6 +340,8 @@ int get_master_key_verification_pattern(const u8 *key, size_t key_size, + bool is_cca_aes_data_key(const u8 *key, size_t key_size); + bool is_cca_aes_cipher_key(const u8 *key, size_t key_size); + bool is_ep11_aes_key(const u8 *key, size_t key_size); ++bool is_ep11_aes_key_with_header(const u8 *key, size_t key_size); ++bool is_ep11_key_session_bound(const u8 *key, size_t key_size); + bool is_xts_key(const u8 *key, size_t key_size); + int get_key_bit_size(const u8 *key, size_t key_size, size_t *bitsize); + const char *get_key_type(const u8 *key, size_t key_size); +diff --git a/zkey/zkey-cryptsetup.c b/zkey/zkey-cryptsetup.c +index fae78c7..8b55f7d 100644 +--- a/zkey/zkey-cryptsetup.c ++++ b/zkey/zkey-cryptsetup.c +@@ -1673,7 +1673,10 @@ static int reencipher_prepare(int token) + warnx("Failed to re-encipher the secure volume " + "key for device '%s'\n", g.pos_arg); + if (!selected && +- !is_ep11_aes_key((u8 *)key, securekeysize)) ++ !is_ep11_aes_key((u8 *)key, ++ securekeysize) && ++ !is_ep11_aes_key_with_header((u8 *)key, ++ securekeysize)) + print_msg_for_cca_envvars( + "secure AES volume key"); + rc = -EINVAL; +@@ -1696,7 +1699,10 @@ static int reencipher_prepare(int token) + warnx("Failed to re-encipher the secure volume " + "key for device '%s'\n", g.pos_arg); + if (!selected && +- !is_ep11_aes_key((u8 *)key, securekeysize)) ++ !is_ep11_aes_key((u8 *)key, ++ securekeysize) && ++ !is_ep11_aes_key_with_header((u8 *)key, ++ securekeysize)) + print_msg_for_cca_envvars( + "secure AES volume key"); + rc = -EINVAL; +@@ -1836,7 +1842,10 @@ static int reencipher_complete(int token) + warnx("Failed to re-encipher the secure volume " + "key for device '%s'\n", g.pos_arg); + if (!selected && +- !is_ep11_aes_key((u8 *)key, securekeysize)) ++ !is_ep11_aes_key((u8 *)key, ++ securekeysize) && ++ !is_ep11_aes_key_with_header((u8 *)key, ++ securekeysize)) + print_msg_for_cca_envvars( + "secure AES volume key"); + rc = -EINVAL; +diff --git a/zkey/zkey.c b/zkey/zkey.c +index 3000290..843e554 100644 +--- a/zkey/zkey.c ++++ b/zkey/zkey.c +@@ -1968,7 +1968,9 @@ static int command_reencipher_file(void) + "master key has failed\n"); + if (!selected && + !is_ep11_aes_key(secure_key, +- secure_key_size)) ++ secure_key_size) && ++ !is_ep11_aes_key_with_header(secure_key, ++ secure_key_size)) + print_msg_for_cca_envvars( + "secure AES key"); + } +@@ -1993,7 +1995,9 @@ static int command_reencipher_file(void) + "master key has failed\n"); + if (!selected && + !is_ep11_aes_key(secure_key, +- secure_key_size)) ++ secure_key_size) && ++ !is_ep11_aes_key_with_header(secure_key, ++ secure_key_size)) + print_msg_for_cca_envvars( + "secure AES key"); + } +-- +2.43.0 + diff --git a/s390utils.spec b/s390utils.spec index 5395d5a..e971414 100644 --- a/s390utils.spec +++ b/s390utils.spec @@ -9,8 +9,8 @@ Name: s390utils Summary: Utilities and daemons for IBM z Systems -Version: 2.27.0 -Release: 4%{?dist} +Version: 2.29.0 +Release: 1%{?dist} Epoch: 2 License: MIT ExclusiveArch: s390 s390x @@ -76,6 +76,7 @@ find . -name Makefile | xargs sed -i 's/$(INSTALL) -s/$(INSTALL)/g' %build make \ CFLAGS="%{build_cflags}" CXXFLAGS="%{build_cxxflags}" LDFLAGS="%{build_ldflags}" \ + HAVE_CARGO=0 \ HAVE_DRACUT=1 \ %if 0%{?with_pandoc} ENABLE_DOC=1 \ @@ -88,6 +89,7 @@ make \ %install make install \ + HAVE_CARGO=0 \ HAVE_DRACUT=1 \ %if 0%{?with_pandoc} ENABLE_DOC=1 \ @@ -898,6 +900,15 @@ User-space development files for the s390/s390x architecture. %changelog +* Fri Nov 24 2023 Dan Horák - 2:2.29.0-1 +- rebased to 2.29.0 (RHEL-11408) +- KVM: Support AP Bindings in SE Header (RHEL-10572) +- KVM: Userspace Tool for IBK Request Generation and Insertion (RHEL-10578) +- zkey: support for key type PKEY_TYPE_EP11_AES (RHEL-11440) +- vmur: fix handling of option -t (RHEL-11480) +- dbginfo.sh: global original Input Field Separator (IFS) (RHEL-16527) +- Resolves: RHEL-11408 RHEL-10572 RHEL-10578 RHEL-11440 RHEL-11480 RHEL-16527 + * Mon Aug 7 2023 Dan Horák - 2:2.27.0-4 - zdev/dracut: fix kdump build to integrate with site support (#2229177) - Resolves: #2229177 diff --git a/sources b/sources index 95bf181..6100d46 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (s390-tools-2.27.0.tar.gz) = 8ec83718639d17fe7b1990f4e492f1e1bdd11e814b7838c921733eeccb212f417141042118eadf1e8db498e3ff2ce0c8d404189e436cefe17d9a3dacea22429f +SHA512 (s390-tools-2.29.0.tar.gz) = 3eeaab0e0c6559b9fb0b4c7cca49358a7cc7fe0cb11684d2d761fe105cc2bfd791d33ecc2070e3dfd877039b68e868699cd3cea318e64aee1cc0f348c7b41617