From 7e8b34210d22d3be7b8ac683befc4cc18f1b3e42506d19d2b5688332dd262382 Mon Sep 17 00:00:00 2001 From: Mark Post Date: Tue, 8 Dec 2020 19:29:12 +0000 Subject: [PATCH 1/2] Accepting request 854117 from home:markkp:branches:Base:System - Upgraded to version 2.15.1. (bsc#1178250, jsc#SLE-13663) - Added s390-tools-sles15sp3-dasdfmt-Fix-segfault-when-an-incorrect-option-is-spe.patch (bsc#1178313). When specifying an incorrect program option, dasdfmt segfaults as the format string for the corresponding error message has no parameter. - Added s390-tools-sles15sp3-libutil-Compare-proc-entries-to-vfstype.patch (bsc#1178315). The fdasd command was failing if sysfs was mounted this way: mount -t sysfs none /sys To make sure that the mount point of the sysfs is still found when mounted with a device keyword specified other than 'sysfs', check for the filesystem type instead, which is more specific. - Added the following patches for bsc#1178427, and jsc#SLE-13768, Log DASD info for endpoint security * s390-tools-sles15sp3-01-zdev-Add-FC-Endpoint-Security-information-for-DASD-d.patch * s390-tools-sles15sp3-02-lsdasd-Add-FC-Endpoint-Security-information.patch - Added the following patch for bsc#1178628 and jsc#SLE-13765, Converged HiperSockets/Ethernet Interface * s390-tools-sles15sp3-hsci-Add-new-tool-to-control-HiperSockets-Converged-.patch - Added the following patches for bsc#1178992 and jsc#SLE-13772, Add host-key document verification support to genprotimg. * s390-tools-sles15sp3-01-genprotimg-abort-if-one-of-the-recursive-targets-is-.patch * s390-tools-sles15sp3-02-genprotimg-fix-two-memory-leaks.patch * s390-tools-sles15sp3-03-genprotimg-require-argument-for-ramdisk-and-parmfile.patch * s390-tools-sles15sp3-04-genprotimg-add-host-key-document-verification-suppor.patch - Added the following patch for bsc#1178734. Running zcryptstats when many domains are available per cryto card does not produce any output, and is hanging in a loop. * s390-tools-sles15sp3-zcryptstats-Fix-handling-of-partial-results-with-man.patch - Reworked and renamed the following patches to accommodate changes made by IBM to the structure of the dasdfmt command. * s390-tools-sles15-Allow-multiple-device-arguments.patch renamed to s390-tools-sles15sp3-Allow-multiple-device-arguments.patch. * s390-tools-sles15-Format-devices-in-parallel.patch renamed to s390-tools-sles15sp3-Format-devices-in-parallel.patch * dasdfmt-retry-BIODASDINFO-if-device-is-busy.patch renamed to s390-tools-sles15sp3-dasdfmt-retry-BIODASDINFO-if-device-is-busy.patch * s390-tools-sles15-Implement-f-for-backwards-compability.patch renamed to s390-tools-sles15-Implement-Y-yast_mode.patch - Upgraded to version 2.15.0 (jsc#SLE-13662, jsc#SLE-13663, jsc#SLE-13667, jsc#SLE-13724, jsc#SLE-13728, jsc#SLE-13730, jsc#SLE-13739, jsc#SLE-13744, jsc#SLE-13751, jsc#SLE-13755, jsc#SLE-13765, jsc#SLE-13768, jsc#SLE-13777, jsc#SLE-13814, jsc#SLE-13819, jsc#SLE-13820) - Reworked s390-tools-sles12-sysconfig-compatible-dumpconf.patch to fit the current version and renamed it to s390-tools-sles15-sysconfig-compatible-dumpconf.patch - Removed the following obsolete patches: * s390-tools-sles15sp2-01-zkey-Separate-and-rework-CCA-host-library-loading.patch * s390-tools-sles15sp2-02-zkey-Move-utility-functions-into-separate-source-fil.patch * s390-tools-sles15sp2-03-zkey-Add-utility-function-to-get-the-serial-number-o.patch * s390-tools-sles15sp2-04-zkey-Add-utility-function-to-get-the-mkvp-of-a-crypt.patch * s390-tools-sles15sp2-05-zkey-add-function-to-iterate-over-all-available-CCA-.patch * s390-tools-sles15sp2-06-zkey-Add-function-to-print-the-MKVPs-of-APQNs.patch * s390-tools-sles15sp2-07-zkey-Add-function-to-cross-check-APQNs-for-valid-mas.patch * s390-tools-sles15sp2-08-zkey-Add-function-to-obtain-the-mkvp-of-a-secure-key.patch * s390-tools-sles15sp2-09-zkey-Display-MKVP-when-validating-a-secure-key.patch * s390-tools-sles15sp2-10-zkey-Cross-check-APQNs-when-generating-secure-keys.patch * s390-tools-sles15sp2-11-zkey-Cross-check-APQNs-when-validating-secure-keys.patch * s390-tools-sles15sp2-12-zkey-Cross-check-APQNs-when-importing-secure-keys.patch * s390-tools-sles15sp2-13-zkey-Cross-check-APQNs-when-changing-APQN-associatio.patch * s390-tools-sles15sp2-14-zkey-Add-function-to-select-a-specific-CCA-adapter.patch * s390-tools-sles15sp2-15-zkey-Add-function-to-select-a-CCA-adapter-by-mkvp.patch * s390-tools-sles15sp2-16-zkey-Select-CCA-adapter-when-re-enciphering.patch * s390-tools-sles15sp2-17-zkey-cryptsetup-Add-to-new-and-from-old-options.patch * s390-tools-sles15sp2-18-zkey-Display-key-type-with-list-and-validate-command.patch * s390-tools-sles15sp2-19-zkey-Allow-to-filter-list-output-by-key-type.patch * s390-tools-sles15sp2-20-zkey-Allow-to-specify-the-key-type-with-the-generate.patch * s390-tools-sles15sp2-21-zkey-Preparations-for-introducing-a-new-key-type.patch * s390-tools-sles15sp2-22-zkey-Introduce-the-CCA-AESCIPHER-key-type.patch * s390-tools-sles15sp2-23-zkey-Add-wrappers-for-the-new-IOCTLs-with-fallback-t.patch * s390-tools-sles15sp2-24-zkey-Add-helper-functions-to-build-lists-of-APQNs.patch * s390-tools-sles15sp2-25-zkey-Add-support-for-generating-AES-CIPHER-keys.patch * s390-tools-sles15sp2-26-zkey-Add-support-for-validating-AES-CIPHER-keys.patch * s390-tools-sles15sp2-27-zkey-Add-support-for-re-enciphering-AES-CIPHER-keys.patch * s390-tools-sles15sp2-28-zkey-Check-crypto-card-level-during-APQN-cross-check.patch * s390-tools-sles15sp2-29-zkey-Add-helper-function-to-query-the-CCA-firmware-v.patch * s390-tools-sles15sp2-30-zkey-Add-helper-function-to-convert-secure-keys-betw.patch * s390-tools-sles15sp2-31-zkey-Add-helper-function-to-restrict-export-of-secur.patch * s390-tools-sles15sp2-32-zkey-Add-helper-function-to-check-an-AES-CIPHER-key.patch * s390-tools-sles15sp2-33-zkey-Add-key-checks-when-importing-a-CCA-AESCIPHER-k.patch * s390-tools-sles15sp2-34-zkey-Add-convert-command-to-convert-keys-from-one-ty.patch * s390-tools-sles15sp2-35-zkey-Allow-zkey-cryptsetup-setkey-to-set-different-k.patch * s390-tools-sles15sp2-zcrypt-CEX7S-exploitation-support.patch * s390-tools-sles15sp2-zcryptstats-Add-support-for-CEX7.patch * s390-tools-sles15sp2-zkey-Fix-listing-of-keys-on-file-systems-reporting-D.patch * s390-tools-sles15sp2-zkey-Fix-display-of-clear-key-size-for-XTS-keys.patch * s390-tools-sles15sp2-zkey-Fix-display-of-XTS-attribute-for-validate-comma.patch * s390-tools-sles15sp2-zkey-Fix-display-of-clear-key-size-for-CCA-AESCIPHER.patch * s390-tools-sles15sp2-01-zipl-libc-Introduce-vsnprintf.patch * s390-tools-sles15sp2-02-zipl-libc-Fix-potential-buffer-overflow-in-printf.patch * s390-tools-sles15sp2-03-zipl-libc-Replace-sprintf-with-snprintf.patch * s390-tools-sles15sp2-04-zipl-libc-Indicate-truncated-lines-in-printf-with.patch * s390-tools-sles15sp2-01-zpcictl-Initiate-recover-after-reset.patch * s390-tools-sles15sp2-02-zpcictl-Rename-misleading-sysfs_write_data.patch * s390-tools-sles15sp2-03-zpcitctl-Exit-on-error-in-sysfs_report_error.patch * s390-tools-sles15sp2-01-zipl-fix-Wdiscarded-qualifiers.patch * s390-tools-sles15sp2-02-zipl-fix-Waddress-of-packed-member.patch * s390-tools-sles15sp2-03-zipl-remove-some-useless-__packed___-attributes.patch * s390-tools-sles15sp2-04-zipl-Fix-entry-point-for-stand-alone-kdump.patch * s390-tools-sles15sp2-05-zipl-Fix-dependency-generation-in-zipl-boot.patch * s390-tools-sles15sp2-06-zipl-Make-use-of-__packed-macro.patch * s390-tools-sles15sp2-07-zipl-define-__section-macro-and-make-use-of-it.patch * s390-tools-sles15sp2-08-zipl-Make-use-of-__noreturn-macro.patch * s390-tools-sles15sp2-09-zipl-Define-__noinline-macro-and-make-use-of-it.patch * s390-tools-sles15sp2-10-zipl-stage3-Mark-start_kernel-__noreturn.patch * s390-tools-sles15sp2-11-zipl-sclp-Remove-duplicate-macros.patch * s390-tools-sles15sp2-12-zipl-Make-address-size-mask-macros-UL.patch * s390-tools-sles15sp2-13-zipl-libc-Use-stdint.h-instead-of-self-defined-macro.patch * s390-tools-sles15sp2-14-zipl-Consolidate-IMAGE-macros.patch * s390-tools-sles15sp2-15-zipl-Consolidate-STAGE-2-3-macros.patch * s390-tools-sles15sp2-16-zipl-stfle-use-uint64_t-instead-of-u64.patch * s390-tools-sles15sp2-17-zipl-boot-fix-comment-in-stage3.lds.patch * s390-tools-sles15sp2-18-lib-zt_common-add-STATIC_ASSERT-macro.patch * s390-tools-sles15sp2-19-zipl-use-STATIC_ASSERT-macro-for-no-padding-verifica.patch * s390-tools-sles15sp2-20-Support-lib-zt_common.h-to-be-used-in-assembler-and-.patch * s390-tools-sles15sp2-21-zipl-move-IPL-related-definitions-into-separate-head.patch * s390-tools-sles15sp2-22-zipl-move-SIGP-related-functions-and-definitions-int.patch * s390-tools-sles15sp2-23-zipl-add-SIGP_SET_ARCHITECTURE-to-sigp.h-and-use-it.patch * s390-tools-sles15sp2-24-zipl-stage3-make-IPL_DEVICE-definition-consistent-wi.patch * s390-tools-sles15sp2-25-zipl-move-Linux-layout-definitions-into-separate-hea.patch * s390-tools-sles15sp2-26-zipl-tape0-use-constants-defined-in-linux_layout.h.patch * s390-tools-sles15sp2-27-zipl-use-STAGE3_ENTRY-for-STAGE3_LOAD_ADDRESS.patch * s390-tools-sles15sp2-28-zipl-move-loaders-layout-definitions-into-separate-h.patch * s390-tools-sles15sp2-29-zipl-s390.h-rename-inline-macro-into-__always_inline.patch * s390-tools-sles15sp2-30-zipl-move-__always_inline-barrier-__pa32-pa-to-zt_co.patch * s390-tools-sles15sp2-31-zipl-make-BLK_PWRT-unsigned-int.patch * s390-tools-sles15sp2-32-Consolidate-MIN-and-MAX-macros.patch * s390-tools-sles15sp2-33-zipl-remove-libc.h-include-in-s390.h.patch * s390-tools-sles15sp2-34-zipl-move-s390.h-to-include-boot-s390.h.patch * s390-tools-sles15sp2-35-zipl-libc-include-s390.h.patch * s390-tools-sles15sp2-36-include-boot-s390.h-move-panic-and-panic_notify-to-l.patch * s390-tools-sles15sp2-37-include-boot-s390.h-fixes-for-Werror-sign-conversion.patch * s390-tools-sles15sp2-38-zipl-refactor-all-EBCDIC-code-into-separate-files.patch * s390-tools-sles15sp2-39-zipl-sclp-add-macros-for-the-control-program-masks.patch * s390-tools-sles15sp2-40-zipl-sclp-add-sclp_print_ascii.patch * s390-tools-sles15sp2-41-zipl-libc-printf-print-on-linemode-and-ASCII-console.patch * s390-tools-sles15sp2-42-Consolidate-ALIGN-__ALIGN_MASK-ARRAY_SIZE-macros.patch * s390-tools-sles15sp2-43-genprotimg-boot-initial-bootloader-support.patch * s390-tools-sles15sp2-44-genprotimg-boot-use-C-pre-processor-for-linker-scrip.patch * s390-tools-sles15sp2-45-genprotimg-add-relocator-for-stage3b.patch * s390-tools-sles15sp2-46-README.md-remove-useless-empty-line.patch * s390-tools-sles15sp2-47-include-boot-s390.h-add-guard-for-struct-__vector128.patch * s390-tools-sles15sp2-48-genprotimg-introduce-new-tool-for-the-creation-of-PV.patch * s390-tools-sles15sp2-01-zipl-Add-missing-options-to-help-output.patch * s390-tools-sles15sp2-02-zipl-allow-stand-alone-secure-option-on-command-l.patch * s390-tools-sles15sp2-03-zipl-correct-secure-boot-config-handling.patch * s390-tools-sles15sp2-04-zipl-fix-zipl.conf-man-page-example-for-secure-boot.patch * s390-tools-sles15sp2-01-cpumf-add-new-deflate-counters-for-z15.patch * s390-tools-sles15sp2-vmcp-exit-code.patch * s390-tools-sles15sp2-zipl-prevent-endless-loop-during-IPL.patch * s390-tools-sles15sp2-zipl-check-for-valid-ipl-parmblock-lowcore-pointer.patch * s390-tools-sles15sp2-01-zipl-libc-libc_stop-move-noreturn-to-declaration.patch * s390-tools-sles15sp2-02-zipl-stage3-correctly-handle-diag308-response-code.patch * s390-tools-sles15sp2-lsluns-try-harder-to-find-udevadm.patch * s390-tools-sles15sp2-znetconf-introduce-better-ways-to-locate-udevadm.patch * s390-tools-sles15sp2-mon_tools-update-udevadm-location.patch * s390-tools-sles15sp2-lscpumf-change-dflt-ccerror-counter-name.patch * s390-tools-sles15sp2-01-zdev-Introduce-read-only-attributes.patch * s390-tools-sles15sp2-02-zdev-Handle-special-case-in-if-case.patch * s390-tools-sles15sp2-03-zdev-Report-FC-Endpoint-Security-of-zfcp-devices.patch * s390-tools-sles15sp2-04-zfcpdbf-print-HBA-FC-Endpoint-Security-trace-records.patch * s390-tools-sles15sp1-zdev-Also-include-the-ctc-driver-in-the-initrd.patch not in spec file * s390-tools-sles15sp2-Close-file-descriptor-when-checking-for-read-only.patch not in spec file - Added s390-tools-sles15sp2-lscpumf-change-dflt-ccerror-counter-name.patch (bsc#1176508) lscpumf displays counter number 265 as DFLT_CCERROR. This is wrong and differs from the counter name as defined in the Linux kernel version 5.8 and later. - Added the following patches to implement the post-GA feature jsc#ECO-2636 Log FCP link info for endpoint security (bsc#1175477) * s390-tools-sles15sp2-01-zdev-Introduce-read-only-attributes.patch * s390-tools-sles15sp2-02-zdev-Handle-special-case-in-if-case.patch * s390-tools-sles15sp2-03-zdev-Report-FC-Endpoint-Security-of-zfcp-devices.patch * s390-tools-sles15sp2-04-zfcpdbf-print-HBA-FC-Endpoint-Security-trace-records.patch OBS-URL: https://build.opensuse.org/request/show/854117 OBS-URL: https://build.opensuse.org/package/show/Base:System/s390-tools?expand=0&rev=101 --- s390-tools-2.11.0.tar.gz | 3 - s390-tools-2.15.1.tar.gz | 3 + ...es15-Allow-multiple-device-arguments.patch | 436 -- ...sles15-sysconfig-compatible-dumpconf.patch | 121 +- ...include-the-ctc-driver-in-the-initrd.patch | 11 - ...umf-add-new-deflate-counters-for-z15.patch | 442 -- ...l-Add-missing-options-to-help-output.patch | 63 - ...p2-01-zipl-fix-Wdiscarded-qualifiers.patch | 45 - ...sp2-01-zipl-libc-Introduce-vsnprintf.patch | 319 - ...bc_stop-move-noreturn-to-declaration.patch | 72 - ...-and-rework-CCA-host-library-loading.patch | 795 --- ...zpcictl-Initiate-recover-after-reset.patch | 70 - ...and-alone-secure-option-on-command-l.patch | 170 - ...2-zipl-fix-Waddress-of-packed-member.patch | 102 - ...-potential-buffer-overflow-in-printf.patch | 63 - ...rrectly-handle-diag308-response-code.patch | 87 - ...y-functions-into-separate-source-fil.patch | 297 - ...l-Rename-misleading-sysfs_write_data.patch | 51 - ...-correct-secure-boot-config-handling.patch | 187 - ...l-libc-Replace-sprintf-with-snprintf.patch | 236 - ...-some-useless-__packed___-attributes.patch | 143 - ...-function-to-get-the-serial-number-o.patch | 112 - ...-Exit-on-error-in-sysfs_report_error.patch | 119 - ...ix-entry-point-for-stand-alone-kdump.patch | 95 - ...onf-man-page-example-for-secure-boot.patch | 70 - ...icate-truncated-lines-in-printf-with.patch | 82 - ...-function-to-get-the-mkvp-of-a-crypt.patch | 213 - ...x-dependency-generation-in-zipl-boot.patch | 76 - ...n-to-iterate-over-all-available-CCA-.patch | 197 - ...2-06-zipl-Make-use-of-__packed-macro.patch | 349 -- ...function-to-print-the-MKVPs-of-APQNs.patch | 131 - ...e-__section-macro-and-make-use-of-it.patch | 188 - ...n-to-cross-check-APQNs-for-valid-mas.patch | 271 - ...08-zipl-Make-use-of-__noreturn-macro.patch | 61 - ...n-to-obtain-the-mkvp-of-a-secure-key.patch | 74 - ...-__noinline-macro-and-make-use-of-it.patch | 66 - ...ay-MKVP-when-validating-a-secure-key.patch | 176 - ...-stage3-Mark-start_kernel-__noreturn.patch | 49 - ...ck-APQNs-when-generating-secure-keys.patch | 91 - ...11-zipl-sclp-Remove-duplicate-macros.patch | 41 - ...ck-APQNs-when-validating-secure-keys.patch | 123 - ...ipl-Make-address-size-mask-macros-UL.patch | 116 - ...eck-APQNs-when-importing-secure-keys.patch | 85 - ...dint.h-instead-of-self-defined-macro.patch | 52 - ...-APQNs-when-changing-APQN-associatio.patch | 86 - ...sp2-14-zipl-Consolidate-IMAGE-macros.patch | 199 - ...ion-to-select-a-specific-CCA-adapter.patch | 455 -- ...15-zipl-Consolidate-STAGE-2-3-macros.patch | 110 - ...tion-to-select-a-CCA-adapter-by-mkvp.patch | 162 - ...pl-stfle-use-uint64_t-instead-of-u64.patch | 53 - ...lect-CCA-adapter-when-re-enciphering.patch | 397 -- ...-zipl-boot-fix-comment-in-stage3.lds.patch | 42 - ...etup-Add-to-new-and-from-old-options.patch | 289 - ...ib-zt_common-add-STATIC_ASSERT-macro.patch | 50 - ...-type-with-list-and-validate-command.patch | 202 - ...ASSERT-macro-for-no-padding-verifica.patch | 91 - ...ow-to-filter-list-output-by-key-type.patch | 331 -- ...ommon.h-to-be-used-in-assembler-and-.patch | 65 - ...ecify-the-key-type-with-the-generate.patch | 348 -- ...lated-definitions-into-separate-head.patch | 359 -- ...tions-for-introducing-a-new-key-type.patch | 665 --- ...elated-functions-and-definitions-int.patch | 148 - ...Introduce-the-CCA-AESCIPHER-key-type.patch | 452 -- ...ET_ARCHITECTURE-to-sigp.h-and-use-it.patch | 117 - ...s-for-the-new-IOCTLs-with-fallback-t.patch | 278 - ...-IPL_DEVICE-definition-consistent-wi.patch | 56 - ...er-functions-to-build-lists-of-APQNs.patch | 439 -- ...layout-definitions-into-separate-hea.patch | 109 - ...pport-for-generating-AES-CIPHER-keys.patch | 542 -- ...-constants-defined-in-linux_layout.h.patch | 79 - ...pport-for-validating-AES-CIPHER-keys.patch | 425 -- ...STAGE3_ENTRY-for-STAGE3_LOAD_ADDRESS.patch | 45 - ...t-for-re-enciphering-AES-CIPHER-keys.patch | 194 - ...s-layout-definitions-into-separate-h.patch | 105 - ...o-card-level-during-APQN-cross-check.patch | 361 -- ...me-inline-macro-into-__always_inline.patch | 192 - ...function-to-query-the-CCA-firmware-v.patch | 101 - ...ys_inline-barrier-__pa32-pa-to-zt_co.patch | 74 - ...function-to-convert-secure-keys-betw.patch | 279 - ...2-31-zipl-make-BLK_PWRT-unsigned-int.patch | 44 - ...function-to-restrict-export-of-secur.patch | 182 - ...p2-32-Consolidate-MIN-and-MAX-macros.patch | 105 - ...-function-to-check-an-AES-CIPHER-key.patch | 192 - ...zipl-remove-libc.h-include-in-s390.h.patch | 76 - ...cks-when-importing-a-CCA-AESCIPHER-k.patch | 225 - ...l-move-s390.h-to-include-boot-s390.h.patch | 1129 ---- ...-command-to-convert-keys-from-one-ty.patch | 679 --- ...les15sp2-35-zipl-libc-include-s390.h.patch | 51 - ...cryptsetup-setkey-to-set-different-k.patch | 63 - ...0.h-move-panic-and-panic_notify-to-l.patch | 69 - ...0.h-fixes-for-Werror-sign-conversion.patch | 73 - ...-all-EBCDIC-code-into-separate-files.patch | 640 -- ...macros-for-the-control-program-masks.patch | 79 - ...p2-40-zipl-sclp-add-sclp_print_ascii.patch | 163 - ...-print-on-linemode-and-ASCII-console.patch | 47 - ...ALIGN-__ALIGN_MASK-ARRAY_SIZE-macros.patch | 134 - ...timg-boot-initial-bootloader-support.patch | 803 --- ...use-C-pre-processor-for-linker-scrip.patch | 479 -- ...genprotimg-add-relocator-for-stage3b.patch | 120 - ...-README.md-remove-useless-empty-line.patch | 38 - ...0.h-add-guard-for-struct-__vector128.patch | 54 - ...duce-new-tool-for-the-creation-of-PV.patch | 5198 ----------------- ...scriptor-when-checking-for-read-only.patch | 10 - ...p2-lsluns-try-harder-to-find-udevadm.patch | 59 - ...p2-mon_tools-update-udevadm-location.patch | 64 - s390-tools-sles15sp2-vmcp-exit-code.patch | 73 - ...p2-zcrypt-CEX7S-exploitation-support.patch | 131 - ...sp2-zcryptstats-Add-support-for-CEX7.patch | 78 - ...-valid-ipl-parmblock-lowcore-pointer.patch | 81 - ...zipl-prevent-endless-loop-during-IPL.patch | 33 - ...-of-XTS-attribute-for-validate-comma.patch | 54 - ...-of-clear-key-size-for-CCA-AESCIPHER.patch | 48 - ...splay-of-clear-key-size-for-XTS-keys.patch | 60 - ...-of-keys-on-file-systems-reporting-D.patch | 62 - ...roduce-better-ways-to-locate-udevadm.patch | 89 - ...-if-one-of-the-recursive-targets-is-.patch | 38 + ...oint-Security-information-for-DASD-d.patch | 47 + ...3-02-genprotimg-fix-two-memory-leaks.patch | 56 + ...Add-FC-Endpoint-Security-information.patch | 58 + ...re-argument-for-ramdisk-and-parmfile.patch | 49 + ...ost-key-document-verification-suppor.patch | 2410 ++++++++ ...5sp3-Allow-multiple-device-arguments.patch | 473 ++ ...sles15sp3-Format-devices-in-parallel.patch | 131 +- ...ools-sles15sp3-Implement-Y-yast_mode.patch | 88 +- ...mplement-f-for-backwards-compability.patch | 15 +- ...ault-when-an-incorrect-option-is-spe.patch | 34 + ...-retry-BIODASDINFO-if-device-is-busy.patch | 27 +- ...l-to-control-HiperSockets-Converged-.patch | 633 ++ ...util-Compare-proc-entries-to-vfstype.patch | 41 + ...handling-of-partial-results-with-man.patch | 73 + s390-tools.changes | 197 +- s390-tools.spec | 189 +- 132 files changed, 4343 insertions(+), 26154 deletions(-) delete mode 100644 s390-tools-2.11.0.tar.gz create mode 100644 s390-tools-2.15.1.tar.gz delete mode 100644 s390-tools-sles15-Allow-multiple-device-arguments.patch rename s390-tools-sles12-sysconfig-compatible-dumpconf.patch => s390-tools-sles15-sysconfig-compatible-dumpconf.patch (82%) delete mode 100644 s390-tools-sles15sp1-zdev-Also-include-the-ctc-driver-in-the-initrd.patch delete mode 100644 s390-tools-sles15sp2-01-cpumf-add-new-deflate-counters-for-z15.patch delete mode 100644 s390-tools-sles15sp2-01-zipl-Add-missing-options-to-help-output.patch delete mode 100644 s390-tools-sles15sp2-01-zipl-fix-Wdiscarded-qualifiers.patch delete mode 100644 s390-tools-sles15sp2-01-zipl-libc-Introduce-vsnprintf.patch delete mode 100644 s390-tools-sles15sp2-01-zipl-libc-libc_stop-move-noreturn-to-declaration.patch delete mode 100644 s390-tools-sles15sp2-01-zkey-Separate-and-rework-CCA-host-library-loading.patch delete mode 100644 s390-tools-sles15sp2-01-zpcictl-Initiate-recover-after-reset.patch delete mode 100644 s390-tools-sles15sp2-02-zipl-allow-stand-alone-secure-option-on-command-l.patch delete mode 100644 s390-tools-sles15sp2-02-zipl-fix-Waddress-of-packed-member.patch delete mode 100644 s390-tools-sles15sp2-02-zipl-libc-Fix-potential-buffer-overflow-in-printf.patch delete mode 100644 s390-tools-sles15sp2-02-zipl-stage3-correctly-handle-diag308-response-code.patch delete mode 100644 s390-tools-sles15sp2-02-zkey-Move-utility-functions-into-separate-source-fil.patch delete mode 100644 s390-tools-sles15sp2-02-zpcictl-Rename-misleading-sysfs_write_data.patch delete mode 100644 s390-tools-sles15sp2-03-zipl-correct-secure-boot-config-handling.patch delete mode 100644 s390-tools-sles15sp2-03-zipl-libc-Replace-sprintf-with-snprintf.patch delete mode 100644 s390-tools-sles15sp2-03-zipl-remove-some-useless-__packed___-attributes.patch delete mode 100644 s390-tools-sles15sp2-03-zkey-Add-utility-function-to-get-the-serial-number-o.patch delete mode 100644 s390-tools-sles15sp2-03-zpcitctl-Exit-on-error-in-sysfs_report_error.patch delete mode 100644 s390-tools-sles15sp2-04-zipl-Fix-entry-point-for-stand-alone-kdump.patch delete mode 100644 s390-tools-sles15sp2-04-zipl-fix-zipl.conf-man-page-example-for-secure-boot.patch delete mode 100644 s390-tools-sles15sp2-04-zipl-libc-Indicate-truncated-lines-in-printf-with.patch delete mode 100644 s390-tools-sles15sp2-04-zkey-Add-utility-function-to-get-the-mkvp-of-a-crypt.patch delete mode 100644 s390-tools-sles15sp2-05-zipl-Fix-dependency-generation-in-zipl-boot.patch delete mode 100644 s390-tools-sles15sp2-05-zkey-add-function-to-iterate-over-all-available-CCA-.patch delete mode 100644 s390-tools-sles15sp2-06-zipl-Make-use-of-__packed-macro.patch delete mode 100644 s390-tools-sles15sp2-06-zkey-Add-function-to-print-the-MKVPs-of-APQNs.patch delete mode 100644 s390-tools-sles15sp2-07-zipl-define-__section-macro-and-make-use-of-it.patch delete mode 100644 s390-tools-sles15sp2-07-zkey-Add-function-to-cross-check-APQNs-for-valid-mas.patch delete mode 100644 s390-tools-sles15sp2-08-zipl-Make-use-of-__noreturn-macro.patch delete mode 100644 s390-tools-sles15sp2-08-zkey-Add-function-to-obtain-the-mkvp-of-a-secure-key.patch delete mode 100644 s390-tools-sles15sp2-09-zipl-Define-__noinline-macro-and-make-use-of-it.patch delete mode 100644 s390-tools-sles15sp2-09-zkey-Display-MKVP-when-validating-a-secure-key.patch delete mode 100644 s390-tools-sles15sp2-10-zipl-stage3-Mark-start_kernel-__noreturn.patch delete mode 100644 s390-tools-sles15sp2-10-zkey-Cross-check-APQNs-when-generating-secure-keys.patch delete mode 100644 s390-tools-sles15sp2-11-zipl-sclp-Remove-duplicate-macros.patch delete mode 100644 s390-tools-sles15sp2-11-zkey-Cross-check-APQNs-when-validating-secure-keys.patch delete mode 100644 s390-tools-sles15sp2-12-zipl-Make-address-size-mask-macros-UL.patch delete mode 100644 s390-tools-sles15sp2-12-zkey-Cross-check-APQNs-when-importing-secure-keys.patch delete mode 100644 s390-tools-sles15sp2-13-zipl-libc-Use-stdint.h-instead-of-self-defined-macro.patch delete mode 100644 s390-tools-sles15sp2-13-zkey-Cross-check-APQNs-when-changing-APQN-associatio.patch delete mode 100644 s390-tools-sles15sp2-14-zipl-Consolidate-IMAGE-macros.patch delete mode 100644 s390-tools-sles15sp2-14-zkey-Add-function-to-select-a-specific-CCA-adapter.patch delete mode 100644 s390-tools-sles15sp2-15-zipl-Consolidate-STAGE-2-3-macros.patch delete mode 100644 s390-tools-sles15sp2-15-zkey-Add-function-to-select-a-CCA-adapter-by-mkvp.patch delete mode 100644 s390-tools-sles15sp2-16-zipl-stfle-use-uint64_t-instead-of-u64.patch delete mode 100644 s390-tools-sles15sp2-16-zkey-Select-CCA-adapter-when-re-enciphering.patch delete mode 100644 s390-tools-sles15sp2-17-zipl-boot-fix-comment-in-stage3.lds.patch delete mode 100644 s390-tools-sles15sp2-17-zkey-cryptsetup-Add-to-new-and-from-old-options.patch delete mode 100644 s390-tools-sles15sp2-18-lib-zt_common-add-STATIC_ASSERT-macro.patch delete mode 100644 s390-tools-sles15sp2-18-zkey-Display-key-type-with-list-and-validate-command.patch delete mode 100644 s390-tools-sles15sp2-19-zipl-use-STATIC_ASSERT-macro-for-no-padding-verifica.patch delete mode 100644 s390-tools-sles15sp2-19-zkey-Allow-to-filter-list-output-by-key-type.patch delete mode 100644 s390-tools-sles15sp2-20-Support-lib-zt_common.h-to-be-used-in-assembler-and-.patch delete mode 100644 s390-tools-sles15sp2-20-zkey-Allow-to-specify-the-key-type-with-the-generate.patch delete mode 100644 s390-tools-sles15sp2-21-zipl-move-IPL-related-definitions-into-separate-head.patch delete mode 100644 s390-tools-sles15sp2-21-zkey-Preparations-for-introducing-a-new-key-type.patch delete mode 100644 s390-tools-sles15sp2-22-zipl-move-SIGP-related-functions-and-definitions-int.patch delete mode 100644 s390-tools-sles15sp2-22-zkey-Introduce-the-CCA-AESCIPHER-key-type.patch delete mode 100644 s390-tools-sles15sp2-23-zipl-add-SIGP_SET_ARCHITECTURE-to-sigp.h-and-use-it.patch delete mode 100644 s390-tools-sles15sp2-23-zkey-Add-wrappers-for-the-new-IOCTLs-with-fallback-t.patch delete mode 100644 s390-tools-sles15sp2-24-zipl-stage3-make-IPL_DEVICE-definition-consistent-wi.patch delete mode 100644 s390-tools-sles15sp2-24-zkey-Add-helper-functions-to-build-lists-of-APQNs.patch delete mode 100644 s390-tools-sles15sp2-25-zipl-move-Linux-layout-definitions-into-separate-hea.patch delete mode 100644 s390-tools-sles15sp2-25-zkey-Add-support-for-generating-AES-CIPHER-keys.patch delete mode 100644 s390-tools-sles15sp2-26-zipl-tape0-use-constants-defined-in-linux_layout.h.patch delete mode 100644 s390-tools-sles15sp2-26-zkey-Add-support-for-validating-AES-CIPHER-keys.patch delete mode 100644 s390-tools-sles15sp2-27-zipl-use-STAGE3_ENTRY-for-STAGE3_LOAD_ADDRESS.patch delete mode 100644 s390-tools-sles15sp2-27-zkey-Add-support-for-re-enciphering-AES-CIPHER-keys.patch delete mode 100644 s390-tools-sles15sp2-28-zipl-move-loaders-layout-definitions-into-separate-h.patch delete mode 100644 s390-tools-sles15sp2-28-zkey-Check-crypto-card-level-during-APQN-cross-check.patch delete mode 100644 s390-tools-sles15sp2-29-zipl-s390.h-rename-inline-macro-into-__always_inline.patch delete mode 100644 s390-tools-sles15sp2-29-zkey-Add-helper-function-to-query-the-CCA-firmware-v.patch delete mode 100644 s390-tools-sles15sp2-30-zipl-move-__always_inline-barrier-__pa32-pa-to-zt_co.patch delete mode 100644 s390-tools-sles15sp2-30-zkey-Add-helper-function-to-convert-secure-keys-betw.patch delete mode 100644 s390-tools-sles15sp2-31-zipl-make-BLK_PWRT-unsigned-int.patch delete mode 100644 s390-tools-sles15sp2-31-zkey-Add-helper-function-to-restrict-export-of-secur.patch delete mode 100644 s390-tools-sles15sp2-32-Consolidate-MIN-and-MAX-macros.patch delete mode 100644 s390-tools-sles15sp2-32-zkey-Add-helper-function-to-check-an-AES-CIPHER-key.patch delete mode 100644 s390-tools-sles15sp2-33-zipl-remove-libc.h-include-in-s390.h.patch delete mode 100644 s390-tools-sles15sp2-33-zkey-Add-key-checks-when-importing-a-CCA-AESCIPHER-k.patch delete mode 100644 s390-tools-sles15sp2-34-zipl-move-s390.h-to-include-boot-s390.h.patch delete mode 100644 s390-tools-sles15sp2-34-zkey-Add-convert-command-to-convert-keys-from-one-ty.patch delete mode 100644 s390-tools-sles15sp2-35-zipl-libc-include-s390.h.patch delete mode 100644 s390-tools-sles15sp2-35-zkey-Allow-zkey-cryptsetup-setkey-to-set-different-k.patch delete mode 100644 s390-tools-sles15sp2-36-include-boot-s390.h-move-panic-and-panic_notify-to-l.patch delete mode 100644 s390-tools-sles15sp2-37-include-boot-s390.h-fixes-for-Werror-sign-conversion.patch delete mode 100644 s390-tools-sles15sp2-38-zipl-refactor-all-EBCDIC-code-into-separate-files.patch delete mode 100644 s390-tools-sles15sp2-39-zipl-sclp-add-macros-for-the-control-program-masks.patch delete mode 100644 s390-tools-sles15sp2-40-zipl-sclp-add-sclp_print_ascii.patch delete mode 100644 s390-tools-sles15sp2-41-zipl-libc-printf-print-on-linemode-and-ASCII-console.patch delete mode 100644 s390-tools-sles15sp2-42-Consolidate-ALIGN-__ALIGN_MASK-ARRAY_SIZE-macros.patch delete mode 100644 s390-tools-sles15sp2-43-genprotimg-boot-initial-bootloader-support.patch delete mode 100644 s390-tools-sles15sp2-44-genprotimg-boot-use-C-pre-processor-for-linker-scrip.patch delete mode 100644 s390-tools-sles15sp2-45-genprotimg-add-relocator-for-stage3b.patch delete mode 100644 s390-tools-sles15sp2-46-README.md-remove-useless-empty-line.patch delete mode 100644 s390-tools-sles15sp2-47-include-boot-s390.h-add-guard-for-struct-__vector128.patch delete mode 100644 s390-tools-sles15sp2-48-genprotimg-introduce-new-tool-for-the-creation-of-PV.patch delete mode 100644 s390-tools-sles15sp2-Close-file-descriptor-when-checking-for-read-only.patch delete mode 100644 s390-tools-sles15sp2-lsluns-try-harder-to-find-udevadm.patch delete mode 100644 s390-tools-sles15sp2-mon_tools-update-udevadm-location.patch delete mode 100644 s390-tools-sles15sp2-vmcp-exit-code.patch delete mode 100644 s390-tools-sles15sp2-zcrypt-CEX7S-exploitation-support.patch delete mode 100644 s390-tools-sles15sp2-zcryptstats-Add-support-for-CEX7.patch delete mode 100644 s390-tools-sles15sp2-zipl-check-for-valid-ipl-parmblock-lowcore-pointer.patch delete mode 100644 s390-tools-sles15sp2-zipl-prevent-endless-loop-during-IPL.patch delete mode 100644 s390-tools-sles15sp2-zkey-Fix-display-of-XTS-attribute-for-validate-comma.patch delete mode 100644 s390-tools-sles15sp2-zkey-Fix-display-of-clear-key-size-for-CCA-AESCIPHER.patch delete mode 100644 s390-tools-sles15sp2-zkey-Fix-display-of-clear-key-size-for-XTS-keys.patch delete mode 100644 s390-tools-sles15sp2-zkey-Fix-listing-of-keys-on-file-systems-reporting-D.patch delete mode 100644 s390-tools-sles15sp2-znetconf-introduce-better-ways-to-locate-udevadm.patch create mode 100644 s390-tools-sles15sp3-01-genprotimg-abort-if-one-of-the-recursive-targets-is-.patch create mode 100644 s390-tools-sles15sp3-01-zdev-Add-FC-Endpoint-Security-information-for-DASD-d.patch create mode 100644 s390-tools-sles15sp3-02-genprotimg-fix-two-memory-leaks.patch create mode 100644 s390-tools-sles15sp3-02-lsdasd-Add-FC-Endpoint-Security-information.patch create mode 100644 s390-tools-sles15sp3-03-genprotimg-require-argument-for-ramdisk-and-parmfile.patch create mode 100644 s390-tools-sles15sp3-04-genprotimg-add-host-key-document-verification-suppor.patch create mode 100644 s390-tools-sles15sp3-Allow-multiple-device-arguments.patch rename s390-tools-sles15-Format-devices-in-parallel.patch => s390-tools-sles15sp3-Format-devices-in-parallel.patch (66%) rename s390-tools-sles15-Implement-Y-yast_mode.patch => s390-tools-sles15sp3-Implement-Y-yast_mode.patch (52%) rename s390-tools-sles15-Implement-f-for-backwards-compability.patch => s390-tools-sles15sp3-Implement-f-for-backwards-compability.patch (85%) create mode 100644 s390-tools-sles15sp3-dasdfmt-Fix-segfault-when-an-incorrect-option-is-spe.patch rename dasdfmt-retry-BIODASDINFO-if-device-is-busy.patch => s390-tools-sles15sp3-dasdfmt-retry-BIODASDINFO-if-device-is-busy.patch (72%) create mode 100644 s390-tools-sles15sp3-hsci-Add-new-tool-to-control-HiperSockets-Converged-.patch create mode 100644 s390-tools-sles15sp3-libutil-Compare-proc-entries-to-vfstype.patch create mode 100644 s390-tools-sles15sp3-zcryptstats-Fix-handling-of-partial-results-with-man.patch diff --git a/s390-tools-2.11.0.tar.gz b/s390-tools-2.11.0.tar.gz deleted file mode 100644 index 60048ed..0000000 --- a/s390-tools-2.11.0.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fd1883e12f9da16be6b081508108abd3ce8cd80168efe4cd339ba33837f8f4aa -size 1164539 diff --git a/s390-tools-2.15.1.tar.gz b/s390-tools-2.15.1.tar.gz new file mode 100644 index 0000000..1150a71 --- /dev/null +++ b/s390-tools-2.15.1.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8dc1180031018756ccd5acf6c26c4175bcac79e512e8a2ea8569fdf5d3f9bd6c +size 1390556 diff --git a/s390-tools-sles15-Allow-multiple-device-arguments.patch b/s390-tools-sles15-Allow-multiple-device-arguments.patch deleted file mode 100644 index 82442ab..0000000 --- a/s390-tools-sles15-Allow-multiple-device-arguments.patch +++ /dev/null @@ -1,436 +0,0 @@ -From d6582bbaf0f3986a42f562046dc0caa9de89c75e Mon Sep 17 00:00:00 2001 -From: Hannes Reinecke -Date: Fri, 6 Oct 2017 08:58:17 +0200 -Subject: [PATCH] dasdfmt: Allow multiple device arguments - -Allow the user to specify several devices as arguments to dasdfmt. - -Signed-off-by: Hannes Reinecke ---- - dasdfmt/dasdfmt.8 | 5 +- - dasdfmt/dasdfmt.c | 175 ++++++++++++++++++++++++++++++------------------------ - 2 files changed, 100 insertions(+), 80 deletions(-) - -diff --git a/dasdfmt/dasdfmt.8 b/dasdfmt/dasdfmt.8 -index 99da9ed..e7fc501 100644 ---- a/dasdfmt/dasdfmt.8 -+++ b/dasdfmt/dasdfmt.8 -@@ -11,14 +11,15 @@ dasdfmt \- formatting of DASD (ECKD) disk drives. - .br - [-r \fIcylinder\fR] [-b \fIblksize\fR] [-l \fIvolser\fR] [-d \fIlayout\fR] - .br -- [-L] [-V] [-F] [-k] [-C] [-M \fImode\fR] \fIdevice\fR -+ [-L] [-V] [-F] [-k] [-C] [-M \fImode\fR] \fIdevice\fR [\fIdevice\fR] - - .SH DESCRIPTION --\fBdasdfmt\fR formats a DASD (ECKD) disk drive to prepare it -+\fBdasdfmt\fR formats one or several DASD (ECKD) disk drive to prepare it - for usage with Linux for S/390. - The \fIdevice\fR is the node of the device (e.g. '/dev/dasda'). - Any device node created by udev for kernel 2.6 can be used - (e.g. '/dev/dasd/0.0.b100/disc'). -+It is possible to specify up to 512 devices. - .br - - \fBWARNING\fR: Careless usage of \fBdasdfmt\fR can result in -diff --git a/dasdfmt/dasdfmt.c b/dasdfmt/dasdfmt.c -index b79cff0..607fd1c 100644 ---- a/dasdfmt/dasdfmt.c -+++ b/dasdfmt/dasdfmt.c -@@ -23,6 +23,7 @@ - - #include "dasdfmt.h" - -+#define MAX_DEVICES 512 - #define BUSIDSIZE 8 - #define SEC_PER_DAY (60 * 60 * 24) - #define SEC_PER_HOUR (60 * 60) -@@ -463,44 +464,40 @@ static void program_interrupt_signal(int sig) - /* - * check given device name for blanks and some special characters - */ --static void get_device_name(char *devname, -- int optind, int argc, char *argv[]) -+static void get_device_name(char **devname, int numdev, -+ char argv[]) - { - struct util_proc_dev_entry dev_entry; - struct stat dev_stat; - -- if (optind + 1 < argc) -- ERRMSG_EXIT(EXIT_MISUSE, -- "%s: More than one device specified!\n", prog_name); -- -- if (optind >= argc) -- ERRMSG_EXIT(EXIT_MISUSE, "%s: No device specified!\n", -- prog_name); -- -- if (strlen(argv[optind]) >= PATH_MAX) -+ if (strlen(argv) >= PATH_MAX) - ERRMSG_EXIT(EXIT_MISUSE, "%s: device name too long!\n", - prog_name); -- strcpy(devname, argv[optind]); - -- if (stat(devname, &dev_stat) != 0) -- ERRMSG_EXIT(EXIT_MISUSE, "%s: Could not get information for " -- "device node %s: %s\n", prog_name, devname, -- strerror(errno)); -+ devname[numdev] = argv; -+ if (stat(devname[numdev], &dev_stat) != 0) -+ ERRMSG_EXIT(EXIT_MISUSE, -+ "%s: Could not get information for " -+ "device node %s: %s\n", prog_name, -+ devname[numdev], strerror(errno)); - - if (minor(dev_stat.st_rdev) & PARTN_MASK) { -- ERRMSG_EXIT(EXIT_MISUSE, "%s: Unable to format partition %s. " -+ ERRMSG_EXIT(EXIT_MISUSE, -+ "%s: Unable to format partition %s. " - "Please specify a device.\n", prog_name, -- devname); -+ devname[numdev]); - } - -- if (util_proc_dev_get_entry(dev_stat.st_rdev, 1, &dev_entry) == 0) { -+ if (util_proc_dev_get_entry(dev_stat.st_rdev, 1, -+ &dev_entry) == 0) { - if (strncmp(dev_entry.name, "dasd", 4) != 0) - ERRMSG_EXIT(EXIT_MISUSE, - "%s: Unsupported device type '%s'.\n", - prog_name, dev_entry.name); - } else { -- printf("%s WARNING: Unable to get driver name for device node %s", -- prog_name, devname); -+ printf("%s WARNING: Unable to get driver name" -+ " for device node %s", -+ prog_name, devname[numdev]); - } - } - -@@ -518,7 +515,7 @@ static void get_blocksize(const char *de - /* - * Check whether a specified blocksize matches the blocksize of the device - */ --static void check_blocksize(dasdfmt_info_t *info, unsigned int blksize) -+static void check_blocksize(dasdfmt_info_t *info, char *dev_filename, unsigned int blksize) - { - unsigned int dev_blksize; - -@@ -756,7 +753,7 @@ static void check_hashmarks(dasdfmt_info - * This function checks whether a range of tracks is in regular format - * with the specified block size. - */ --static format_check_t check_track_format(dasdfmt_info_t *info, format_data_t *p) -+static format_check_t check_track_format(dasdfmt_info_t *info, char *dev_filename, format_data_t *p) - { - format_check_t cdata = { - .expect = { -@@ -812,7 +809,7 @@ static int process_tracks(dasdfmt_info_t - step.stop_unit = cur_trk + step_value - 1; - - if (info->check) { -- cdata = check_track_format(info, &step); -+ cdata = check_track_format(info, dev_filename, &step); - if (cdata.result) { - cyl = cur_trk / heads + 1; - draw_progress(info, cyl, cylinders, 1); -@@ -858,7 +855,7 @@ static void check_disk_format(dasdfmt_in - return; - } - -- check_blocksize(info, check_params->blksize); -+ check_blocksize(info, dev_filename, check_params->blksize); - check_layout(info, check_params->intensity); - - /* -@@ -1188,7 +1185,7 @@ static void dasdfmt_write_labels(dasdfmt - * that the device is formatted to a certain extent. Otherwise the - * process is terminated. - */ --static void dasdfmt_find_start(dasdfmt_info_t *info, unsigned int cylinders, -+static void dasdfmt_find_start(dasdfmt_info_t *info, char *dev_filename, unsigned int cylinders, - unsigned heads, format_data_t *format_params) - { - format_check_t cdata; -@@ -1197,11 +1194,11 @@ static void dasdfmt_find_start(dasdfmt_i - unsigned int right = (cylinders * heads) - 1; - unsigned int first = left; - -- check_blocksize(info, format_params->blksize); -+ check_blocksize(info, dev_filename, format_params->blksize); - - format_params->start_unit = 0; - format_params->stop_unit = 4; -- cdata = check_track_format(info, format_params); -+ cdata = check_track_format(info, dev_filename, format_params); - - if (cdata.result) { - evaluate_format_error(info, &cdata, heads); -@@ -1217,7 +1214,7 @@ static void dasdfmt_find_start(dasdfmt_i - - format_params->start_unit = middle; - format_params->stop_unit = middle; -- cdata = check_track_format(info, format_params); -+ cdata = check_track_format(info, dev_filename, format_params); - if (cdata.blksize != format_params->blksize) { - first = middle; - right = middle - 1; -@@ -1266,6 +1263,7 @@ static void dasdfmt_release_space(dasdfm - } - - static void dasdfmt_prepare_and_format(dasdfmt_info_t *info, -+ char *dev_filename, - unsigned int cylinders, - unsigned int heads, format_data_t *p) - { -@@ -1324,7 +1322,7 @@ static void dasdfmt_prepare_and_format(d - /* - * This function will start the expand format process. - */ --static void dasdfmt_expand_format(dasdfmt_info_t *info, unsigned int cylinders, -+static void dasdfmt_expand_format(dasdfmt_info_t *info, char *dev_filename, unsigned int cylinders, - unsigned int heads, format_data_t *p) - { - if (!(info->withoutprompt && (info->verbosity < 1))) -@@ -1351,7 +1349,7 @@ static void dasdfmt_expand_format(dasdfm - * This function will only format the first two tracks of a DASD. - * The rest of the DASD is untouched and left as is. - */ --static void dasdfmt_quick_format(dasdfmt_info_t *info, unsigned int cylinders, -+static void dasdfmt_quick_format(dasdfmt_info_t *info, char *dev_filename, unsigned int cylinders, - unsigned int heads, format_data_t *p) - { - format_check_t cdata = { .expect = {0}, 0 }; -@@ -1363,18 +1361,18 @@ static void dasdfmt_quick_format(dasdfmt - } else if (info->ese) { - printf("Skipping format check due to thin-provisioned device.\n"); - } else { -- check_blocksize(info, p->blksize); -+ check_blocksize(info, dev_filename, p->blksize); - - printf("Checking the format of selected tracks...\n"); - - /* Check device format on the first and last 3 regular tracks */ - tmp.start_unit = 2; - tmp.stop_unit = 4; -- cdata = check_track_format(info, &tmp); -+ cdata = check_track_format(info, dev_filename, &tmp); - if (!cdata.result) { - tmp.start_unit = (cylinders * heads) - 3; - tmp.stop_unit = (cylinders * heads) - 1; -- cdata = check_track_format(info, &tmp); -+ cdata = check_track_format(info, dev_filename, &tmp); - } - if (cdata.result) { - evaluate_format_error(info, &cdata, heads); -@@ -1419,7 +1417,7 @@ static void do_format_dasd(dasdfmt_info_ - p->stop_unit = 1; - break; - case EXPAND: /* only the end of the disk */ -- dasdfmt_find_start(info, cylinders, heads, p); -+ dasdfmt_find_start(info, devname, cylinders, heads, p); - p->stop_unit = (cylinders * heads) - 1; - break; - } -@@ -1468,24 +1466,24 @@ static void do_format_dasd(dasdfmt_info_ - - switch (mode) { - case FULL: -- dasdfmt_prepare_and_format(info, cylinders, heads, p); -+ dasdfmt_prepare_and_format(info, devname, cylinders, heads, p); - break; - case QUICK: - dasdfmt_release_space(info); -- dasdfmt_quick_format(info, cylinders, heads, p); -+ dasdfmt_quick_format(info, devname, cylinders, heads, p); - break; - case EXPAND: -- dasdfmt_expand_format(info, cylinders, heads, p); -+ dasdfmt_expand_format(info, devname, cylinders, heads, p); - break; - } - - printf("Finished formatting the device.\n"); - - if (!(info->writenolabel || mode == EXPAND)) -- dasdfmt_write_labels(info, vlabel, cylinders, heads); -+ dasdfmt_write_labels(info, devname, vlabel, cylinders, heads); - - printf("Rereading the partition table... "); -- err = dasd_reread_partition_table(dev_filename, 5); -+ err = dasd_reread_partition_table(devname, 5); - if (err != 0) { - ERRMSG("%s: error during rereading the partition " - "table: %s.\n", prog_name, strerror(err)); -@@ -1508,23 +1506,88 @@ static void do_format_dasd(dasdfmt_info_t *info, char *devname, - mode = info->ese ? QUICK : FULL; - } - -+void do_dasdfmt(char *dev_filename, dasdfmt_info_t info, -+ volume_label_t *orig_vlabel, format_data_t format_params) -+{ -+ volume_label_t vlabel; -+ char old_volser[7]; -+ char str[ERR_LENGTH]; -+ unsigned int cylinders, heads; int rc; -+ -+ filedes = open(dev_filename, O_RDWR); -+ if (filedes == -1) -+ ERRMSG_EXIT(EXIT_FAILURE, "%s: Unable to open device %s: %s\n", -+ prog_name, dev_filename, strerror(errno)); -+ close(filedes); -+ -+ rc = dasd_get_info(dev_filename, &info.dasd_info); -+ if (rc != 0) -+ ERRMSG_EXIT(EXIT_FAILURE, "%s: the ioctl call to retrieve " -+ "device information for %s failed (%s).\n", -+ prog_name, dev_filename, strerror(rc)); -+ -+ memcpy(&vlabel, orig_vlabel, sizeof(vlabel)); -+ /* Either let the user specify the blksize or get it from the kernel */ -+ if (!info.blksize_specified) { -+ if (!(mode == FULL || -+ info.dasd_info.format == DASD_FORMAT_NONE) -+ || info.check) -+ get_blocksize(dev_filename, &format_params.blksize); -+ else -+ format_params = ask_user_for_blksize(format_params); -+ } -+ -+ if (info.keep_volser) { -+ if (info.labelspec) { -+ ERRMSG_EXIT(EXIT_MISUSE, "%s: The -k and -l options " -+ "are mutually exclusive\n", prog_name); -+ } -+ if (!(format_params.intensity & DASD_FMT_INT_COMPAT)) { -+ printf("WARNING: VOLSER cannot be kept " -+ "when using the ldl format!\n"); -+ exit(1); -+ } -+ -+ if (dasdfmt_get_volser(dev_filename, -+ &info.dasd_info, old_volser) == 0) -+ vtoc_volume_label_set_volser(&vlabel, old_volser); -+ else -+ ERRMSG_EXIT(EXIT_FAILURE, -+ "%s: VOLSER not found on device %s\n", -+ prog_name, dev_filename); -+ } -+ -+ check_disk(&info, dev_filename); -+ -+ if (check_param(str, ERR_LENGTH, &format_params) < 0) -+ ERRMSG_EXIT(EXIT_MISUSE, "%s: %s\n", prog_name, str); -+ -+ set_geo(&info, &cylinders, &heads); -+ set_label(&info, &vlabel, &format_params, cylinders); -+ -+ if (info.check) -+ check_disk_format(&info, cylinders, heads, &format_params); -+ else -+ do_format_dasd(&info, dev_filename, &vlabel, -+ &format_params, cylinders, heads); -+ -+} -+ - int main(int argc, char *argv[]) - { - dasdfmt_info_t info = { - .dasd_info = {0}, - }; - volume_label_t vlabel; -- char old_volser[7]; - -- char str[ERR_LENGTH]; -+ char *dev_filename[MAX_DEVICES]; - char buf[7]; - - char *blksize_param_str = NULL; - char *reqsize_param_str = NULL; - char *hashstep_str = NULL; - -- int rc; -- unsigned int cylinders, heads; -+ int rc, numdev = 0, i; - - /* Establish a handler for interrupt signals. */ - signal(SIGTERM, program_interrupt_signal); -@@ -1686,59 +1751,24 @@ int main(int argc, char *argv[]) - if (info.print_hashmarks) - PARSE_PARAM_INTO(info.hashstep, hashstep_str, 10, "hashstep"); - -- get_device_name(dev_filename, optind, argc, argv); -- -- rc = dasd_get_info(dev_filename, &info.dasd_info); -- if (rc != 0) -- ERRMSG_EXIT(EXIT_FAILURE, "%s: the ioctl call to retrieve " -- "device information failed (%s).\n", -- prog_name, strerror(rc)); -- -- info.ese = dasd_sys_ese(dev_filename); -- eval_format_mode(&info); -- -- /* Either let the user specify the blksize or get it from the kernel */ -- if (!info.blksize_specified) { -- if (!(mode == FULL || -- info.dasd_info.format == DASD_FORMAT_NONE) || info.check) -- get_blocksize(dev_filename, &format_params.blksize); -- else -- format_params = ask_user_for_blksize(format_params); -- } -- -- if (info.keep_volser) { -- if (info.labelspec) { -- ERRMSG_EXIT(EXIT_MISUSE, "%s: The -k and -l options " -- "are mutually exclusive\n", prog_name); -- } -- if (!(format_params.intensity & DASD_FMT_INT_COMPAT)) { -- printf("WARNING: VOLSER cannot be kept " -- "when using the ldl format!\n"); -- exit(1); -- } -- -- if (dasdfmt_get_volser(dev_filename, -- &info.dasd_info, old_volser) == 0) -- vtoc_volume_label_set_volser(&vlabel, old_volser); -- else -- ERRMSG_EXIT(EXIT_FAILURE, -- "%s: VOLSER not found on device %s\n", -- prog_name, dev_filename); -+ while (optind < argc) { -+ if (optind >= argc) -+ ERRMSG_EXIT(EXIT_MISUSE, "%s: No device specified!\n", -+ prog_name); -+ -+ info.ese = dasd_sys_ese(dev_filename[numdev]); -+ eval_format_mode(&info); -+ -+ get_device_name(dev_filename, numdev, argv[optind]); -+ optind++; -+ numdev++; - } - -- check_disk(&info, dev_filename); -- -- if (check_param(str, ERR_LENGTH, &format_params) < 0) -- ERRMSG_EXIT(EXIT_MISUSE, "%s: %s\n", prog_name, str); -- -- set_geo(&info, &cylinders, &heads); -- set_label(&info, &vlabel, &format_params, cylinders); -- -- if (info.check) -- check_disk_format(&info, cylinders, heads, &format_params); -- else -- do_format_dasd(&info, dev_filename, &vlabel, -- &format_params, cylinders, heads); -+ if (!numdev) -+ ERRMSG_EXIT(EXIT_MISUSE, "%s: No device specified!\n", -+ prog_name); - -+ for (i = 0; i < numdev; i++) -+ do_dasdfmt(dev_filename[i], info, &vlabel, format_params); - return 0; - } --- -1.7.12.4 - diff --git a/s390-tools-sles12-sysconfig-compatible-dumpconf.patch b/s390-tools-sles15-sysconfig-compatible-dumpconf.patch similarity index 82% rename from s390-tools-sles12-sysconfig-compatible-dumpconf.patch rename to s390-tools-sles15-sysconfig-compatible-dumpconf.patch index a550149..fea7fa4 100644 --- a/s390-tools-sles12-sysconfig-compatible-dumpconf.patch +++ b/s390-tools-sles15-sysconfig-compatible-dumpconf.patch @@ -1,21 +1,6 @@ -From c261ec990a8259f2540089827309b918e1c31590 Mon Sep 17 00:00:00 2001 -From: Hannes Reinecke -Date: Fri, 22 Nov 2013 15:34:22 +0100 -Subject: [PATCH] dumpconf: Use compatible sysconfig layout - -SUSE is quite restrictive on how the sysconfig -should look like. - -Signed-off-by: Hannes Reinecke ---- - etc/sysconfig/dumpconf | 134 ++++++++++++++++++++++++++++++++++--------------- - 1 file changed, 93 insertions(+), 41 deletions(-) - -diff --git a/etc/sysconfig/dumpconf b/etc/sysconfig/dumpconf -index a3639cf..76f9040 100644 ---- a/etc/sysconfig/dumpconf -+++ b/etc/sysconfig/dumpconf -@@ -1,61 +1,113 @@ +--- a/etc/sysconfig/dumpconf 2020-10-15 09:56:15.000000000 -0400 ++++ b/etc/sysconfig/dumpconf 2020-10-27 18:47:23.267333389 -0400 +@@ -1,71 +1,137 @@ +## Path: System/Dumpconf +## Description: Configures the actions which should be performed after a kernel panic +## Type: list(stop,dump,vmcmd,reipl,dump_reipl) @@ -26,7 +11,7 @@ index a3639cf..76f9040 100644 -# -# Configures the actions which should be performed after a kernel panic -# and on PSW restart. -+# Define the action that should be taken if a panic happens. ++# Define the action that should be taken if a kernel panic happens. # # The following actions are supported: # @@ -67,16 +52,16 @@ index a3639cf..76f9040 100644 -# Dump on CCW device (DASD) and re-IPL after dump is complete. -# The re-IPL device, as specified under "/sys/firmware/reipl", is used. -# The activation of dumpconf is delayed by 5 minutes. -+## Type: list(ccw,fcp) ++## Type: list(ccw,fcp,nvme) +## Default: "" +## ServiceRestart: dumpconf -+# -+# Define the type, ccw for DASD and fcp for zFCP. # -# ON_PANIC=dump_reipl -# DUMP_TYPE=ccw -# DEVICE=0.0.4e13 -# DELAY_MINUTES=5 ++# Define the type, ccw for DASD, fcp for zFCP, or nvme for NVMe Disk. ++# +DUMP_TYPE="" +## Type: string @@ -100,68 +85,99 @@ index a3639cf..76f9040 100644 +## Type: string +## Default: "" +## ServiceRestart: dumpconf -+# + # +-# Dump on nvme device (NVMe Disk) +# Define the WWPN for a zFCP dump device. # --# Use VMDUMP +-# ON_PANIC=dump +-# DUMP_TYPE=nvme +-# FID=0x00000300 +-# NSID=0x00000001 +-# BOOTPROG=3 +-# BR_LBA=0 +# For example: WWPN=0x5005076303004711 - # --# ON_PANIC=vmcmd --# VMCMD_1="MESSAGE * Starting VMDUMP" --# VMCMD_2="VMDUMP" --# VMCMD_3="IPL 4711" ++# +WWPN="" +## Type: string +## Default: "" +## ServiceRestart: dumpconf -+# + # +-# Use VMDUMP +# Define the LUN for a zFCP dump device. -+# + # +-# ON_PANIC=vmcmd +-# VMCMD_1="MESSAGE * Starting VMDUMP" +-# VMCMD_2="VMDUMP" +-# VMCMD_3="IPL 4711" +# For example: LUN=0x4711000000000000 +# +LUN="" -+ + +## Type: integer(0:30) +## Default: "0" +## ServiceRestart: dumpconf -+# + # +-# Stop Linux (default) +# Define the Boot program selector for a zFCP dump device. -+# + # +-# ON_PANIC=stop +# A decimal value between 0 and 30 specifying the program to be loaded from +# the FCP-I/O device. +# +BOOTPROG="0" -+ -+## Type: string -+## Default: "0" -+## ServiceRestart: dumpconf -+# -+# Define the Boot record logical block address for a zFCP dump device. - # --# Stop Linux (default) -+# The hexadecimal digits designating the logical-block address of the boot record of the FCP-I/O device. -+# It must be a value from 0-FFFFFFFF FFFFFFFF. For values longer than 8 hex characters at least one separator -+# blank is required after the 8th character. - # --# ON_PANIC=stop -+BR_LBA="0" +## Type: string -+## Default: "" ++## Default: "0" +## ServiceRestart: dumpconf # -# Re-IPL Linux -# The re-IPL device, as specified under "/sys/firmware/reipl", is used. -# Since the DELAY_MINUTES keyword is omitted, there is no delay and -# dumpconf becomes active immediately during system startup. ++# Define the Boot record logical block address for a zFCP dump device. + # +-# ON_PANIC=reipl ++# The hexadecimal digits designating the logical-block address of the boot record of the FCP-I/O device. ++# It must be a value from 0-FFFFFFFF FFFFFFFF. For values longer than 8 hex characters at least one separator ++# blank is required after the 8th character. ++# ++BR_LBA="0" ++ ++## Type: string ++## Default: "" ++## ServiceRestart: dumpconf ++# ++# Define the Function ID for NVMe dump device. ++# ++# The hexadecimal digits designating the Function ID for the NMVe disk. ++# ++# For example: FID=0x00000300 ++# ++FID="" ++ ++## Type: string ++## Default: "" ++## ServiceRestart: dumpconf ++# ++# Define the Namespace ID for the NVMe dump device ++# ++# The hexadecimal digits designating the Namespace ID for the NMVe disk. ++# ++# For example: NSID=0x00000001 ++# ++NSID="" ++ ++## Type: string ++## Default: "" ++## ServiceRestart: dumpconf ++# +# VMCMD_ +# Specifies a CP command, is a number from one to eight. You can +# specify up to eight CP commands that are executed in case of a kernel +# panic. Note that VM commands, device adresses, and VM guest names +# must be uppercase. - # --# ON_PANIC=reipl ++# +VMCMD_1="" +VMCMD_2="" +VMCMD_3="" @@ -170,6 +186,3 @@ index a3639cf..76f9040 100644 +VMCMD_6="" +VMCMD_7="" +VMCMD_8="" --- -1.8.1.4 - diff --git a/s390-tools-sles15sp1-zdev-Also-include-the-ctc-driver-in-the-initrd.patch b/s390-tools-sles15sp1-zdev-Also-include-the-ctc-driver-in-the-initrd.patch deleted file mode 100644 index 9b9977c..0000000 --- a/s390-tools-sles15sp1-zdev-Also-include-the-ctc-driver-in-the-initrd.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/zdev/dracut/95zdev/module-setup.sh 2019-01-10 11:39:08.000000000 -0500 -+++ b/zdev/dracut/95zdev/module-setup.sh 2019-01-14 13:28:33.983461097 -0500 -@@ -32,7 +32,7 @@ - installkernel() { - # Add modules for all device types supported by chzdev (required for - # auto-configuration) -- instmods lcs qeth qeth_l2 qeth_l3 dasd_mod dasd_eckd_mod dasd_fba_mod \ -+ instmods ctcm lcs qeth qeth_l2 qeth_l3 dasd_mod dasd_eckd_mod dasd_fba_mod \ - dasd_diag_mod zfcp - } - diff --git a/s390-tools-sles15sp2-01-cpumf-add-new-deflate-counters-for-z15.patch b/s390-tools-sles15sp2-01-cpumf-add-new-deflate-counters-for-z15.patch deleted file mode 100644 index c1ca0bf..0000000 --- a/s390-tools-sles15sp2-01-cpumf-add-new-deflate-counters-for-z15.patch +++ /dev/null @@ -1,442 +0,0 @@ -Subject: [PATCH] [BZ 184585] cpumf/data: Add new deflate counters for IBM z15 -From: Thomas Richter - -Description: lscpumf: New z15 CPU-MF counters not available -Symptom: Command lscpumf -c does not show the new - deflate counters on IBM z15. -Problem: The new counter names have not been published - in document SA23-2261-06 by the time te code was - release. -Solution: Add the definition for the new deflate counters. -Reproduction: Run command lscpumf -c and check for counters - rf7, rfc, r107 and r108. -Upstream-ID: 5d2871d626de6c2b3ab6b12783b87a8b3564cb56 -Problem-ID: 184585 - -Upstream-Description: - - cpumf/data: Add new deflate counters for IBM z15 - - Add support for new deflate counters: - - Counter 247: cycles CPU spent obtaining access to Deflate unit - - Counter 252: cycles CPU is using Deflate unit - - Counter 264: Increments by one for every DEFLATE CONVERSION CALL - instruction executed. - - Counter 265: Increments by one for every DEFLATE CONVERSION CALL - instruction executed that ended in Condition Codes - 0, 1 or 2. - - Signed-off-by: Thomas Richter - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Thomas Richter ---- - cpumf/Makefile | 3 - cpumf/data/cpum-cf-extended-z15.ctr | 376 ++++++++++++++++++++++++++++++++++++ - cpumf/data/cpum-cf-hw-counter.map | 5 - 3 files changed, 380 insertions(+), 4 deletions(-) - ---- a/cpumf/Makefile -+++ b/cpumf/Makefile -@@ -9,7 +9,8 @@ DATA_FILES = cpum-cf-hw-counter.map \ - cpum-cf-csvn-12345.ctr cpum-cf-csvn-6.ctr \ - cpum-cf-extended-z10.ctr cpum-cf-extended-z196.ctr \ - cpum-cf-extended-zEC12.ctr cpum-sf-modes.ctr \ -- cpum-cf-extended-z13.ctr cpum-cf-extended-z14.ctr -+ cpum-cf-extended-z13.ctr cpum-cf-extended-z14.ctr \ -+ cpum-cf-extended-z15.ctr - LIB_FILES = bin/cpumf_helper - USRBIN_SCRIPTS = bin/lscpumf - USRSBIN_SCRIPTS = bin/chcpumf ---- /dev/null -+++ b/cpumf/data/cpum-cf-extended-z15.ctr -@@ -0,0 +1,376 @@ -+# Counter decriptions for the -+# IBM z14 extended counter and MT-diagnostic counter set -+# -+# Notes for transactional-execution mode symbolic names: -+# TX .. transactional-execution mode -+# NC .. nonconstrained -+# C .. constrained -+# -+# Undefined counters in the extended counter set: -+# 142 -+# 158-161 -+# 176-223 -+# 227-231 -+# 233-242 -+# 246-255 -+# Undefined counters in the MT-diagnostic counter set: -+# 450-495 -+# -+# -+# Extended Counter Set -+# --------------------------------------------------------------------- -+Counter:128 Name:L1D_RO_EXCL_WRITES -+Short-Description:L1D Read-only Exclusive Writes -+Description: -+A directory write to the Level-1 Data cache where the line was -+originally in a Read-Only state in the cache but has been updated -+to be in the Exclusive state that allows stores to the cache line -+. -+Counter:129 Name:DTLB2_WRITES -+Short-Description:DTLB2 Writes -+Description: -+A translation has been written into The Translation Lookaside -+Buffer 2 (TLB2) and the request was made by the data cache -+. -+Counter:130 Name:DTLB2_MISSES -+Short-Description:DTLB2 Misses -+Description: -+A TLB2 miss is in progress for a request made by the data cache. -+Incremented by one for every TLB2 miss in progress for the Level-1 -+Data cache on this cycle -+. -+Counter:131 Name:DTLB2_HPAGE_WRITES -+Short-Description:DTLB2 One-Megabyte Page Writes -+Description: -+A translation entry was written into the Combined Region and Segment -+Table Entry array in the Level-2 TLB for a one-megabyte page -+. -+Counter:132 Name:DTLB2_GPAGE_WRITES -+Short-Description:DTLB2 Two-Gigabyte Page Writes -+Description: -+A translation entry for a two-gigabyte page was written into the -+Level-2 TLB -+. -+Counter:133 Name:L1D_L2D_SOURCED_WRITES -+Short-Description:L1D L2D Sourced Writes -+Description: -+A directory write to the Level-1 Data cache directory where the -+returned cache line was sourced from the Level-2 Data cache -+. -+Counter:134 Name:ITLB2_WRITES -+Short-Description:ITLB2 Writes -+Description: -+A translation entry has been written into the Translation Lookaside -+Buffer 2 (TLB2) and the request was made by the instruction cache -+. -+Counter:135 Name:ITLB2_MISSES -+Short-Description:ITLB2 Misses -+Description: -+A TLB2 miss is in progress for a request made by the instruction cache. -+Incremented by one for every TLB2 miss in progress for the Level-1 -+Instruction cache in a cycle -+. -+Counter:136 Name:L1I_L2I_SOURCED_WRITES -+Short-Description:L1I L2I Sourced Writes -+Description: -+A directory write to the Level-1 Instruction cache directory where the -+returned cache line was sourced from the Level-2 Instruction cache -+. -+Counter:137 Name:TLB2_PTE_WRITES -+Short-Description:TLB2 PTE Writes -+Description: -+A translation entry was written into the Page Table Entry array in the -+Level-2 TLB -+. -+Counter:138 Name:TLB2_CRSTE_WRITES -+Short-Description:TLB2 CRSTE Writes -+Description: -+Translation entries were written into the Combined Region and Segment -+Table Entry array and the Page Table Entry array in the Level-2 TLB -+. -+Counter:139 Name:TLB2_ENGINES_BUSY -+Short-Description:TLB2 Engines Busy -+Description: -+The number of Level-2 TLB translation engines busy in a cycle -+. -+Counter:140 Name:TX_C_TEND -+Short-Description:Completed TEND instructions in constrained TX mode -+Description: -+A TEND instruction has completed in a constrained transactional-execution -+mode -+. -+Counter:141 Name:TX_NC_TEND -+Short-Description:Completed TEND instructions in non-constrained TX mode -+Description: -+A TEND instruction has completed in a non-constrained -+transactional-execution mode -+. -+Counter:143 Name:L1C_TLB2_MISSES -+Short-Description:L1C TLB2 Misses -+Description: -+Increments by one for any cycle where a level-1 cache or level-2 TLB miss -+is in progress -+. -+Counter:144 Name:L1D_ONCHIP_L3_SOURCED_WRITES -+Short-Description:L1D On-Chip L3 Sourced Writes -+Description: -+A directory write to the Level-1 Data cache directory where the returned -+cache line was sourced from an On-Chip Level-3 cache without intervention -+. -+Counter:145 Name:L1D_ONCHIP_MEMORY_SOURCED_WRITES -+Short-Description:L1D On-Chip Memory Sourced Writes -+Description: -+A directory write to the Level-1 Data cache directory where the returned -+cache line was sourced from On-Chip memory -+. -+Counter:146 Name:L1D_ONCHIP_L3_SOURCED_WRITES_IV -+Short-Description:L1D On-Chip L3 Sourced Writes with Intervention -+Description: -+A directory write to the Level-1 Data cache directory where the returned -+cache line was sourced from an On-Chip Level-3 cache with intervention -+. -+Counter:147 Name:L1D_ONCLUSTER_L3_SOURCED_WRITES -+Short-Description:L1D On-Cluster L3 Sourced Writes -+Description: -+A directory write to the Level-1 Data cache directory where the returned -+cache line was sourced from On-Cluster Level-3 cache withountervention -+. -+Counter:148 Name:L1D_ONCLUSTER_MEMORY_SOURCED_WRITES -+Short-Description:L1D On-Cluster Memory Sourced Writes -+Description: -+A directory write to the Level-1 Data cache directory where the returned -+cache line was sourced from an On-Cluster memory -+. -+Counter:149 Name:L1D_ONCLUSTER_L3_SOURCED_WRITES_IV -+Short-Description:L1D On-Cluster L3 Sourced Writes with Intervention -+Description: -+A directory write to the Level-1 Data cache directory where the returned -+cache line was sourced from an On-Cluster Level-3 cache with intervention -+. -+Counter:150 Name:L1D_OFFCLUSTER_L3_SOURCED_WRITES -+Short-Description:L1D Off-Cluster L3 Sourced Writes -+Description: -+A directory write to the Level-1 Data cache directory where the returned -+cache line was sourced from an Off-Cluster Level-3 cache without -+intervention -+. -+Counter:151 Name:L1D_OFFCLUSTER_MEMORY_SOURCED_WRITES -+Short-Description:L1D Off-Cluster Memory Sourced Writes -+Description: -+A directory write to the Level-1 Data cache directory where the returned -+cache line was sourced from Off-Cluster memory -+. -+Counter:152 Name:L1D_OFFCLUSTER_L3_SOURCED_WRITES_IV -+Short-Description:L1D Off-Cluster L3 Sourced Writes with Intervention -+Description: -+A directory write to the Level-1 Data cache directory where the returned -+cache line was sourced from an Off-Cluster Level-3 cache with intervention -+. -+Counter:153 Name:L1D_OFFDRAWER_L3_SOURCED_WRITES -+Short-Description:L1D Off-Drawer L3 Sourced Writes -+Description: -+A directory write to the Level-1 Data cache directory where the returned -+cache line was sourced from an Off-Drawer Level-3 cache without -+intervention -+. -+Counter:154 Name:L1D_OFFDRAWER_MEMORY_SOURCED_WRITES -+Short-Description:L1D Off-Drawer Memory Sourced Writes -+Description: -+A directory write to the Level-1 Data cache directory where the returned -+cache line was sourced from Off-Drawer memory -+. -+Counter:155 Name:L1D_OFFDRAWER_L3_SOURCED_WRITES_IV -+Short-Description:L1D Off-Drawer L3 Sourced Writes with Intervention -+Description: -+A directory write to the Level-1 Data cache directory where the returned -+cache line was sourced from an Off-Drawer Level-3 cache with intervention -+. -+Counter:156 Name:L1D_ONDRAWER_L4_SOURCED_WRITES -+Short-Description:L1D On-Drawer L4 Sourced Writes -+Description: -+A directory write to the Level-1 Data cache directory where the returned -+cache line was sourced from On-Drawer Level-4 cache -+. -+Counter:157 Name:L1D_OFFDRAWER_L4_SOURCED_WRITES -+Short-Description:L1D Off-Drawer L4 Sourced Writes -+Description: -+A directory write to the Level-1 Data cache directory where the returned -+cache line was sourced from Off-Drawer Level-4 cache -+. -+Counter:158 Name:L1D_ONCHIP_L3_SOURCED_WRITES_RO -+Short-Description:L1D On-Chip L3 Sourced Writes read-only -+Description: -+A directory write to the Level-1 Data cache directory where the returned -+cache line was sourced from On-Chip L3 but a read-only invalidate was -+done to remove other copies of the cache line -+. -+Counter:162 Name:L1I_ONCHIP_L3_SOURCED_WRITES -+Short-Description:L1I On-Chip L3 Sourced Writes -+Description: -+A directory write to the Level-1 Instruction cache directory where the -+returned cache ine was sourced from an On-Chip Level-3 cache without -+intervention -+. -+Counter:163 Name:L1I_ONCHIP_MEMORY_SOURCED_WRITES -+Short-Description:L1I On-Chip Memory Sourced Writes -+Description: -+A directory write to the Level-1 Instruction cache directory where the -+returned cache ine was sourced from On-Chip memory -+. -+Counter:164 Name:L1I_ONCHIP_L3_SOURCED_WRITES_IV -+Short-Description:L1I On-Chip L3 Sourced Writes with Intervention -+Description: -+A directory write to the Level-1 Instruction cache directory where the -+returned cache ine was sourced from an On-Chip Level-3 cache with -+intervention -+. -+Counter:165 Name:L1I_ONCLUSTER_L3_SOURCED_WRITES -+Short-Description:L1I On-Cluster L3 Sourced Writes -+Description: -+A directory write to the Level-1 Instruction cache directory where the -+returned cache line was sourced from an On-Cluster Level-3 cache without -+intervention -+. -+Counter:166 Name:L1I_ONCLUSTER_MEMORY_SOURCED_WRITES -+Short-Description:L1I On-Cluster Memory Sourced Writes -+Description: -+A directory write to the Level-1 Instruction cache directory where the -+returned cache line was sourced from an On-Cluster memory -+. -+Counter:167 Name:L1I_ONCLUSTER_L3_SOURCED_WRITES_IV -+Short-Description:L1I On-Cluster L3 Sourced Writes with Intervention -+Description: -+A directory write to the Level-1 Instruction cache directory where the -+returned cache line was sourced from On-Cluster Level-3 cache with -+intervention -+. -+Counter:168 Name:L1I_OFFCLUSTER_L3_SOURCED_WRITES -+Short-Description:L1I Off-Cluster L3 Sourced Writes -+Description: -+A directory write to the Level-1 Instruction cache directory where the -+returned cache line was sourced from an Off-Cluster Level-3 cache without -+intervention -+. -+Counter:169 Name:L1I_OFFCLUSTER_MEMORY_SOURCED_WRITES -+Short-Description:L1I Off-Cluster Memory Sourced Writes -+Description: -+A directory write to the Level-1 Instruction cache directory where the -+returned cache line was sourced from Off-Cluster memory -+. -+Counter:170 Name:L1I_OFFCLUSTER_L3_SOURCED_WRITES_IV -+Short-Description:L1I Off-Cluster L3 Sourced Writes with Intervention -+Description: -+A directory write to the Level-1 Instruction cache directory where the -+returned cache line was sourced from an Off-Cluster Level-3 cache with -+intervention -+. -+Counter:171 Name:L1I_OFFDRAWER_L3_SOURCED_WRITES -+Short-Description:L1I Off-Drawer L3 Sourced Writes -+Description: -+A directory write to the Level-1 Instruction cache directory where the -+returned cache line was sourced from an Off-Drawer Level-3 cache without -+intervention -+. -+Counter:172 Name:L1I_OFFDRAWER_MEMORY_SOURCED_WRITES -+Short-Description:L1I Off-Drawer Memory Sourced Writes -+Description: -+A directory write to the Level-1 Instruction cache directory where the -+returned cache line was sourced from Off-Drawer memory -+. -+Counter:173 Name:L1I_OFFDRAWER_L3_SOURCED_WRITES_IV -+Short-Description:L1I Off-Drawer L3 Sourced Writes with Intervention -+Description: -+A directory write to the Level-1 Instruction cache directory where the -+returned cache line was sourced from an Off-Drawer Level-3 cache with -+intervention -+. -+Counter:174 Name:L1I_ONDRAWER_L4_SOURCED_WRITES -+Short-Description:L1I On-Drawer L4 Sourced Writes -+Description: -+A directory write to the Level-1 Instruction cache directory where the -+returned cache line was sourced from On-Drawer Level-4 cache -+. -+Counter:175 Name:L1I_OFFDRAWER_L4_SOURCED_WRITES -+Short-Description:L1I Off-Drawer L4 Sourced Writes -+Description: -+A directory write to the Level-1 Instruction cache directory where the -+returned cache line was sourced from Off-Drawer Level-4 cache -+. -+Counter:224 Name:BCD_DFP_EXECUTION_SLOTS -+Short-Description:BCD DFP Execution Slots -+Description: -+Count of floating point execution slots used for finished Binary Coded -+Decimal to Decimal Floating Point conversions. Instructions: CDZT, -+CXZT, CZDT, CZXT -+. -+Counter:225 Name:VX_BCD_EXECUTION_SLOTS -+Short-Description:VX BCD Execution Slots -+Description: -+Count of floating point execution slots used for finished vector arithmetic -+Binary Coded Decimal instructions. Instructions: VAP, VSP, VMPVMSP, VDP, -+VSDP, VRP, VLIP, VSRP, VPSOPVCP, VTP, VPKZ, VUPKZ, VCVB, VCVBG, VCVDVCVDG -+. -+Counter:226 Name:DECIMAL_INSTRUCTIONS -+Short-Description:Decimal Instructions -+Description: -+Decimal instructions dispatched. Instructions: CVB, CVD, AP, CP, DP, ED, -+EDMK, MP, SRP, SP, ZAP -+. -+Counter:232 Name:LAST_HOST_TRANSLATIONS -+Short-Description:Last host translation done -+Description: -+Last Host Translation done -+. -+Counter:243 Name:TX_NC_TABORT -+Short-Description:Aborted transactions in non-constrained TX mode -+Description: -+A transaction abort has occurred in a non-constrained -+transactional-execution mode -+. -+Counter:244 Name:TX_C_TABORT_NO_SPECIAL -+Short-Description:Aborted transactions in constrained TX mode not using special completion logic -+Description: -+A transaction abort has occurred in a constrained transactional-execution -+mode and the CPU is not using any special logic to allow the transaction -+to complete -+. -+Counter:245 Name:TX_C_TABORT_SPECIAL -+Short-Description:Aborted transactions in constrained TX mode using special completion logic -+Description: -+A transaction abort has occurred in a constrained transactional-execution -+mode and the CPU is using special logic to allow the transaction to -+complete -+. -+Counter:247 Name:DFLT_ACCESS -+Short-Description:Cycles CPU spent obtaining access to Deflate unit -+Description: -+Cycles CPU spent obtaining access to Deflate unit -+. -+Counter:252 Name:DFLT_CYCLES -+Short-Description:Cycles CPU is using Deflate unit -+Description: -+Cycles CPU is using Deflate unit -+. -+Counter:264 Name:DFLT_CC -+Short-Description:Increments by one for every DEFLATE CONVERSION CALL instruction executed -+Description: -+Increments by one for every DEFLATE CONVERSION CALL instruction executed -+. -+Counter:265 Name:DFLT_CCERROR -+Short-Description:Increments by one for every DEFLATE CONVERSION CALL instruction executed that ended in Condition Codes 0, 1 or 2 -+Description: -+Increments by one for every DEFLATE CONVERSION CALL instruction executed that ended in Condition Codes 0, 1 or 2 -+. -+# -+# MT-diagnostic counter set -+# --------------------------------------------------------------------- -+Counter:448 Name:MT_DIAG_CYCLES_ONE_THR_ACTIVE -+Short-Description:Cycle count with one thread active -+Description: -+Cycle count with one thread active -+. -+Counter:449 Name:MT_DIAG_CYCLES_TWO_THR_ACTIVE -+Short-Description:Cycle count with two threads active -+Description: -+Cycle count with two threads active -+. ---- a/cpumf/data/cpum-cf-hw-counter.map -+++ b/cpumf/data/cpum-cf-hw-counter.map -@@ -28,7 +28,6 @@ - 2965 => 'cpum-cf-extended-z13.ctr', - 3906 => 'cpum-cf-extended-z14.ctr', - 3907 => 'cpum-cf-extended-z14.ctr', -- # Identical with z14 -- 8561 => 'cpum-cf-extended-z14.ctr', -- 8562 => 'cpum-cf-extended-z14.ctr', -+ 8561 => 'cpum-cf-extended-z15.ctr', -+ 8562 => 'cpum-cf-extended-z15.ctr', - }; diff --git a/s390-tools-sles15sp2-01-zipl-Add-missing-options-to-help-output.patch b/s390-tools-sles15sp2-01-zipl-Add-missing-options-to-help-output.patch deleted file mode 100644 index 08c4f42..0000000 --- a/s390-tools-sles15sp2-01-zipl-Add-missing-options-to-help-output.patch +++ /dev/null @@ -1,63 +0,0 @@ -Subject: [PATCH] [BZ 184396] zipl: Add missing options to help output -From: Stefan Haberland - -Description: zipl: fix secure boot config handling -Symptom: The config file parsing for secure boot worked not as - it was expected to be. For example a config section - setting was not evaluated properly. - It is not possible to specify command line option -S - without other options. - Additionally the man page showed an invalid example. -Problem: The config file parsing was not implemented properly. -Solution: The hierarchy of the secure boot settings in the config - file is: - defaultboot > menu > section - Allow that --secure or -S is specified on command line - without the need to allow all options on the command - line. Also ensure that the command line option - overrules the config option and correctly ensure that - secure boot is only set for SCSI devices. - Fix man page example. -Reproduction: Run zipl with a secure= setting in a configuration - section or specify -S on command line. -Upstream-ID: dcce14923c3e9615df53773d1d8a3a22cbb23b96 -Problem-ID: 184396 - -Upstream-Description: - - zipl: Add missing options to help output - - Reviewed-by: Stefan Haberland - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Stefan Haberland ---- - zipl/src/zipl.c | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - ---- a/zipl/src/zipl.c -+++ b/zipl/src/zipl.c -@@ -68,6 +68,8 @@ static const char* usage_text[] = { - "-P, --parameters PARMLINE Use specified kernel PARMLINE", - "-T, --tape TAPEDEV Install bootloader on tape device TAPEDEV", - "-s, --segment SEGMENT,ADDR Install a segment from file SEGMENT", -+"-k, --kdump=auto Install a kdump kernel that can be used as a", -+" stand-alone dump tool", - "-d, --dumpto DUMPDEV[,SIZE] Install a system dump record on tape device", - " or disk partition DUMPDEV", - "-M, --mvdump DEVLIST[,SIZE] Install a multi-volume dump record on each", -@@ -78,7 +80,12 @@ static const char* usage_text[] = { - "-n, --noninteractive Answer all confirmation questions with 'yes'", - "-V, --verbose Provide more verbose output", - "-a, --add-files Add all referenced files to bootmap file", --" --dry-run Simulate run but don't modify IPL records" -+" --dry-run Simulate run but don't modify IPL records", -+"-S, --secure SWITCH Control the zIPL secure boot support.", -+" auto (default):", -+" Write signatures if available and supported", -+" 1: Write signatures regardless of support", -+" 0: Do not write signatures" - }; - - diff --git a/s390-tools-sles15sp2-01-zipl-fix-Wdiscarded-qualifiers.patch b/s390-tools-sles15sp2-01-zipl-fix-Wdiscarded-qualifiers.patch deleted file mode 100644 index 8282701..0000000 --- a/s390-tools-sles15sp2-01-zipl-fix-Wdiscarded-qualifiers.patch +++ /dev/null @@ -1,45 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] zipl: fix -Wdiscarded-qualifiers -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: bbc46edaf53c2c148b5c94a2414f6847f67f856a -Problem-ID: VS1804 - -Upstream-Description: - - zipl: fix -Wdiscarded-qualifiers - - Reported by GCC 9.2.1 when building with '-Wdiscarded-qualifiers'. - - job.c: In function 'get_job_from_config_file': - job.c:1810:14: warning: assignment discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers] - - Signed-off-by: Marc Hartmayer - Reviewed-by: Stefan Haberland - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - zipl/src/job.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/zipl/src/job.c -+++ b/zipl/src/job.c -@@ -1796,7 +1796,7 @@ get_job_from_config_file(struct command_ - { - struct scan_token* scan; - struct scan_token* new_scan; -- char* filename; -+ const char *filename; - char *blsdir; - char* source; - int rc, scan_size; diff --git a/s390-tools-sles15sp2-01-zipl-libc-Introduce-vsnprintf.patch b/s390-tools-sles15sp2-01-zipl-libc-Introduce-vsnprintf.patch deleted file mode 100644 index 8da7a48..0000000 --- a/s390-tools-sles15sp2-01-zipl-libc-Introduce-vsnprintf.patch +++ /dev/null @@ -1,319 +0,0 @@ -Subject: [PATCH] [BZ 184060] zipl/libc: Introduce vsnprintf -From: Philipp Rudo - -Description: zipl/libc: Fix potential buffer overflow in printf -Symptom: Crash of the zipl boot loader during boot. -Problem: The zipl boot loaders have their own minimalistic libc - implementation. In it printf and sprintf use vsprintf for string - formatting. Per definition vsprintf assumes that the buffer it - writes to is large enough to contain the formatted string and - performs no size checks. This is problematic for the boot - loaders because the buffer they use are often allocated on the - stack. Thus even small changes to the string format can - potentially cause buffer overflows on the stack. -Solution: Implement vsnprintf and make use of it. -Reproduction: Use printf to print a string with >81 characters (exact number - depends on the stack layout/compiler used). -Upstream-ID: 6fe9e6c55c69c14971dca55551009f5060418aae -Problem-ID: 184060 - -Upstream-Description: - - zipl/libc: Introduce vsnprintf - - The zipl boot loaders have their own minimalistic libc implementation. - In it printf and sprintf use vsprintf for string formatting. Per - definition vsprintf assumes that the buffer it writes to is large enough - to contain the formatted string and performs no size checks. This is - problematic for the boot loaders because the buffer they use are often - allocated on the stack. Thus even small changes to the string format can - potentially cause buffer overflows on the stack with the well known - consequences. Protect against such errors by implementing vsnprintf. - Later patches will make use of it. - - This implementation of vsnprintf only supports a small subset of format - options defined in the C standard. In particular it allows the - specifiers: - * %s (strings) - * %o (unsigned int octal) - * %u (unsigned int decimal) - * %x (unsigned int hexadecimal) - - Integer specifiers (o, u, and x) always use the long form, i.e. assume the - argument to be of type 'unsigned long int'. The length modified 'l' can - be given but is ignored. - - Furthermore, it is possible to provide the optional field width (aligned - to the right only) and precision as decimal integer (i.e. not via '*') - as well as the flag for zero padding integers (i.e. '0'). - - The implementation was heavily inspired by the implementation in - lib/vsprintf.c from the Linux kernel tree. - - Signed-off-by: Philipp Rudo - Reviewed-by: Stefan Haberland - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Philipp Rudo ---- - zipl/boot/libc.c | 248 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 248 insertions(+) - ---- a/zipl/boot/libc.c -+++ b/zipl/boot/libc.c -@@ -218,6 +218,254 @@ unsigned long ebcstrtoul(char *nptr, cha - return val; - } - -+static int skip_atoi(const char **c) -+{ -+ int i = 0; -+ -+ do { -+ i = i*10 + *((*c)++) - '0'; -+ } while (isdigit(**c)); -+ -+ return i; -+} -+ -+enum format_type { -+ FORMAT_TYPE_NONE, -+ FORMAT_TYPE_STR, -+ FORMAT_TYPE_ULONG, -+}; -+ -+struct printf_spec { -+ unsigned int type:8; /* format_type enum */ -+ signed int field_width:24; /* width of output field */ -+ unsigned int zeropad:1; /* pad numbers with zero */ -+ unsigned int base:8; /* number base, 8, 10 or 16 only */ -+ signed int precision:16; /* # of digits/chars */ -+}; -+ -+#define FIELD_WIDTH_MAX ((1 << 23) - 1) -+ -+static int format_decode(const char *fmt, struct printf_spec *spec) -+{ -+ const char *start = fmt; -+ -+ spec->type = FORMAT_TYPE_NONE; -+ while (*fmt) { -+ if (*fmt == '%') -+ break; -+ fmt++; -+ } -+ -+ /* return current non-format string */ -+ if (fmt != start || !*fmt) -+ return fmt - start; -+ -+ /* first char is '%', skip it */ -+ fmt++; -+ if (*fmt == '0') { -+ spec->zeropad = 1; -+ fmt++; -+ } -+ -+ spec->field_width = -1; -+ if (isdigit(*fmt)) -+ spec->field_width = skip_atoi(&fmt); -+ -+ spec->precision = -1; -+ if (*fmt == '.') { -+ fmt++; -+ if (isdigit(*fmt)) -+ spec->precision = skip_atoi(&fmt); -+ } -+ -+ /* always use long form, i.e. ignore long qualifier */ -+ if (*fmt == 'l') -+ fmt++; -+ -+ switch (*fmt) { -+ case 's': -+ spec->type = FORMAT_TYPE_STR; -+ break; -+ -+ case 'o': -+ spec->base = 8; -+ spec->type = FORMAT_TYPE_ULONG; -+ break; -+ -+ case 'u': -+ spec->base = 10; -+ spec->type = FORMAT_TYPE_ULONG; -+ break; -+ -+ case 'x': -+ spec->base = 16; -+ spec->type = FORMAT_TYPE_ULONG; -+ break; -+ -+ default: -+ libc_stop(EINTERNAL); -+ } -+ -+ return ++fmt - start; -+} -+ -+static char *string(char *buf, char *end, const char *s, -+ struct printf_spec *spec) -+{ -+ int limit = spec->precision; -+ int len = 0; -+ int spaces; -+ -+ /* Copy string to buffer */ -+ while (limit--) { -+ char c = *s++; -+ if (!c) -+ break; -+ if (buf < end) -+ *buf = c; -+ buf++; -+ len++; -+ } -+ -+ /* right align if necessary */ -+ if (len < spec->field_width && buf < end) { -+ spaces = spec->field_width - len; -+ if (spaces >= end - buf) -+ spaces = end - buf; -+ memmove(buf + spaces, buf, len); -+ memset(buf, ' ', spaces); -+ buf += spaces; -+ } -+ -+ return buf; -+} -+ -+static char *number(char *buf, char *end, unsigned long val, -+ struct printf_spec *spec) -+{ -+ /* temporary buffer to prepare the string. -+ * Worst case: base = 8 -> 3 bits per char -> 2.67 chars per byte */ -+ char tmp[3 * sizeof(val)]; -+ static const char vec[] = {'0', '1', '2', '3', '4', '5', '6', '7', -+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; -+ int field_width = spec->field_width; -+ int precision = spec->precision; -+ int len; -+ -+ /* prepare string in reverse order */ -+ len = 0; -+ while (val) { -+ tmp[len++] = vec[val % spec->base]; -+ val /= spec->base; -+ } -+ -+ if (len > precision) -+ precision = len; -+ -+ field_width -= precision; -+ while (field_width-- > 0) { -+ char c = spec->zeropad ? '0' : ' '; -+ if (buf < end) -+ *buf = c; -+ buf++; -+ } -+ -+ /* needed if no field width but a precision is given */ -+ while (len < precision--) { -+ if (buf < end) -+ *buf = '0'; -+ buf++; -+ } -+ -+ while (len-- > 0) { -+ if (buf < end) -+ *buf = tmp[len]; -+ buf++; -+ } -+ -+ return buf; -+} -+ -+/* -+ * vsnprintf - Format string and place in a buffer -+ * -+ * This funcion only supports a subset of format options defined in the -+ * C standard, i.e. -+ * specifiers: -+ * * %s (strings) -+ * * %o (unsigned int octal) -+ * * %u (unsigned int decimal) -+ * * %x (unsigned int hexadecimal) -+ * -+ * length modifier: -+ * * 'l' (ignored, see below) -+ * -+ * flag: -+ * * '0' (zero padding for integers) -+ * -+ * precision and field width as integers, i.e. _not_ by asterix '*'. -+ * -+ * The integer specifiers (o, u and, x) always use the long form, i.e. -+ * assume the argument to be of type 'unsigned long int'. -+ * -+ * Returns the number of characters the function would have generated for -+ * the given input (excluding the trailing '\0'. If the return value is -+ * greater than or equal @size the resulting string is trunctuated. -+ */ -+static int vsnprintf(char *buf, unsigned long size, const char *fmt, -+ va_list args) -+{ -+ struct printf_spec spec = {0}; -+ char *str, *end; -+ -+ str = buf; -+ end = buf + size; -+ -+ /* use negative (large positive) buffer sizes as indication for -+ * unknown/unlimited buffer sizes. */ -+ if (end < buf) { -+ end = ((void *)-1); -+ size = end - buf; -+ } -+ -+ while (*fmt) { -+ const char *old_fmt = fmt; -+ int read = format_decode(fmt, &spec); -+ int copy; -+ -+ fmt += read; -+ -+ switch (spec.type) { -+ case FORMAT_TYPE_NONE: -+ copy = read; -+ if (str < end) { -+ if (copy > end - str) -+ copy = end - str; -+ memcpy(str, old_fmt, copy); -+ } -+ str += read; -+ break; -+ -+ case FORMAT_TYPE_STR: -+ str = string(str, end, va_arg(args, char *), &spec); -+ break; -+ -+ case FORMAT_TYPE_ULONG: -+ str = number(str, end, va_arg(args, unsigned long), -+ &spec); -+ break; -+ } -+ } -+ -+ if (size) { -+ if (str < end) -+ *str = '\0'; -+ else -+ end[-1] = '\0'; -+ } -+ return str - buf; -+} -+ - /* - * Convert string to number with given base - */ diff --git a/s390-tools-sles15sp2-01-zipl-libc-libc_stop-move-noreturn-to-declaration.patch b/s390-tools-sles15sp2-01-zipl-libc-libc_stop-move-noreturn-to-declaration.patch deleted file mode 100644 index 2d4324a..0000000 --- a/s390-tools-sles15sp2-01-zipl-libc-libc_stop-move-noreturn-to-declaration.patch +++ /dev/null @@ -1,72 +0,0 @@ -Subject: [PATCH] [BZ 186940] zipl/libc: libc_stop move 'noreturn' to declaration -From: Stefan Haberland - -Description: zipl: Fix KVM IPL without bootindex -Symptom: Failed IPL on KVM when no bootindex is specified. -Problem: Without bootindex specified there is no IPL parmblock - on KVM which can be read by the stage3 loader. -Solution: In case diag308 gives a response code 0x102 the stage3 - loader can safely assume that no secure IPL is required - since no IPL report block exists. -Reproduction: IPL on KVM without 'bootindex=' attached. -Upstream-ID: c9066bf5497300db5e0ba11bf111683ea225d8c8 -Problem-ID: 186940 - -Upstream-Description: - - zipl/libc: libc_stop move 'noreturn' to declaration - - Commit 86856f98dbe3 ("zipl: Make use of __noreturn macro") moved the - 'noreturn' attribute from declaration to definition. With this the - compiler can no longer optimize when the function is called in a - separate source file. Move the attribute back to the declaration - - Reviewed-by: Stefan Haberland - Signed-off-by: Marc Hartmayer - - -Signed-off-by: Stefan Haberland ---- - zipl/boot/libc.c | 3 +-- - zipl/boot/libc.h | 4 +++- - 2 files changed, 4 insertions(+), 3 deletions(-) - ---- a/zipl/boot/libc.c -+++ b/zipl/boot/libc.c -@@ -13,7 +13,6 @@ - - #include - --#include "lib/zt_common.h" - #include "boot/s390.h" - - #include "error.h" -@@ -501,7 +500,7 @@ void initialize(void) - /* - * Load disabled wait PSW with reason code in address field - */ --void __noreturn libc_stop(unsigned long reason) -+void libc_stop(unsigned long reason) - { - struct psw_t psw; - ---- a/zipl/boot/libc.h -+++ b/zipl/boot/libc.h -@@ -15,6 +15,8 @@ - - #define NULL ((void *) 0) - -+#include "lib/zt_common.h" -+ - #define EPERM 1 /* Operation not permitted */ - #define ENOENT 2 /* No such file or directory */ - #define ESRCH 3 /* No such process */ -@@ -56,7 +58,7 @@ char *strcpy(char *, const char *); - unsigned long get_zeroed_page(void); - void free_page(unsigned long); - void initialize(void); --void libc_stop(unsigned long); -+void libc_stop(unsigned long) __noreturn; - void start(void); - void pgm_check_handler(void); - void pgm_check_handler_fn(void); diff --git a/s390-tools-sles15sp2-01-zkey-Separate-and-rework-CCA-host-library-loading.patch b/s390-tools-sles15sp2-01-zkey-Separate-and-rework-CCA-host-library-loading.patch deleted file mode 100644 index 4fa72df..0000000 --- a/s390-tools-sles15sp2-01-zkey-Separate-and-rework-CCA-host-library-loading.patch +++ /dev/null @@ -1,795 +0,0 @@ -Subject: zkey: Separate and rework CCA host library loading -From: Ingo Franzki - -Summary: zkey: check master key consistency -Description: Enhances the zkey tool to perform a cross check whether the - APQNs associated with a secure key have the same master key. - Display the master key verification pattern of a secure key - during the zkey validate command. This helps to better identify - which master key is the correct one, in case of master key - inconsistencies. - Select an appropriate APQN when re-enciphering a secure key. - Re-enciphering is done using the CCA host library. Special - handling is required to select an appropriate APQN for use with - the CCA host library. -Upstream-ID: 95c7258ea783c5bd6aa12fc0e3d5fbe65647af03 -Problem-ID: SEC1916 - -Upstream-Description: - - zkey: Separate and rework CCA host library loading - - As preparation for future changes, rework the loading of the - CCA host library so that the exported symbols are not passed - individually to the functions that use it. Pass a structure - that contains all entry points of all loaded CCA functions - instead. This will make it easier to add further CCA functions - at a later time. - - Also add a version query for the CCA host library since some - future functions might be dependent on the library version. - - While at it, separate the CCA related functions and definitions, - and move them into a separate source file (cca.h/cca.h). - - Signed-off-by: Ingo Franzki - Reviewed-by: Harald Freudenberger - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/Makefile | 11 +- - zkey/cca.c | 215 +++++++++++++++++++++++++++++++++++++++++++++++++ - zkey/cca.h | 54 ++++++++++++ - zkey/keystore.c | 26 ++--- - zkey/keystore.h | 3 - zkey/pkey.c | 142 -------------------------------- - zkey/pkey.h | 17 --- - zkey/zkey-cryptsetup.c | 15 +-- - zkey/zkey.c | 19 +--- - 9 files changed, 306 insertions(+), 196 deletions(-) - ---- a/zkey/Makefile -+++ b/zkey/Makefile -@@ -64,18 +64,19 @@ zkey-cryptsetup-skip-jsonc: - - all: $(BUILD_TARGETS) - --zkey.o: zkey.c pkey.h misc.h -+zkey.o: zkey.c pkey.h cca.h misc.h - pkey.o: pkey.c pkey.h -+cca.o: cca.c cca.h pkey.h - properties.o: check-dep-zkey properties.c properties.h --keystore.o: keystore.c keystore.h properties.h --zkey-cryptsetup.o: check-dep-zkey-cryptsetup zkey-cryptsetup.c pkey.h misc.h -+keystore.o: keystore.c keystore.h properties.h pkey.h cca.h -+zkey-cryptsetup.o: check-dep-zkey-cryptsetup zkey-cryptsetup.c pkey.h cca.h misc.h - - zkey: LDLIBS = -ldl -lcrypto --zkey: zkey.o pkey.o properties.o keystore.o $(libs) -+zkey: zkey.o pkey.o cca.o properties.o keystore.o $(libs) - $(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@ - - zkey-cryptsetup: LDLIBS = -ldl -lcryptsetup -ljson-c --zkey-cryptsetup: zkey-cryptsetup.o pkey.o $(libs) -+zkey-cryptsetup: zkey-cryptsetup.o pkey.o cca.o $(libs) - $(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@ - - install-common: ---- /dev/null -+++ b/zkey/cca.c -@@ -0,0 +1,215 @@ -+/* -+ * zkey - Generate, re-encipher, and validate secure keys -+ * -+ * Copyright IBM Corp. 2019 -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+ -+#include "lib/util_panic.h" -+ -+#include "cca.h" -+#include "pkey.h" -+ -+#define pr_verbose(verbose, fmt...) do { \ -+ if (verbose) \ -+ warnx(fmt); \ -+ } while (0) -+ -+/* -+ * Definitions for the CCA library -+ */ -+#define CCA_LIBRARY_NAME "libcsulcca.so" -+#define CCA_WEB_PAGE "http://www.ibm.com/security/cryptocards" -+ -+/** -+ * Prints CCA return and reason code information for certain known CCA -+ * error situations. -+ * -+ * @param return_code the CCA return code -+ * @param reason_code the CCA reason code -+ */ -+static void print_CCA_error(int return_code, int reason_code) -+{ -+ switch (return_code) { -+ case 8: -+ switch (reason_code) { -+ case 48: -+ warnx("The secure key has a CCA master key " -+ "verification pattern that is not valid"); -+ break; -+ } -+ break; -+ case 12: -+ switch (reason_code) { -+ case 764: -+ warnx("The CCA master key is not loaded and " -+ "therefore a secure key cannot be enciphered"); -+ break; -+ } -+ break; -+ } -+} -+ -+/** -+ * Returns the version, release and modification number of the used CCA library. -+ * -+ * @param[in] cca the CCA library structure -+ * @param[in] verbose if true, verbose messages are printed -+ * -+ * @returns 0 on success, a negative errno in case of an error -+ */ -+static int get_cca_version(struct cca_lib *cca, bool verbose) -+{ -+ unsigned char exit_data[4] = { 0, }; -+ unsigned char version_data[20]; -+ long return_code, reason_code; -+ long version_data_length; -+ long exit_data_len = 0; -+ char date[20]; -+ -+ util_assert(cca != NULL, "Internal error: cca is NULL"); -+ -+ memset(version_data, 0, sizeof(version_data)); -+ version_data_length = sizeof(version_data); -+ cca->dll_CSUACFV(&return_code, &reason_code, -+ &exit_data_len, exit_data, -+ &version_data_length, version_data); -+ pr_verbose(verbose, "CSUACFV (Cryptographic Facility Version) " -+ "returned: return_code: %ld, reason_code: %ld", return_code, -+ reason_code); -+ if (return_code != 0) { -+ print_CCA_error(return_code, reason_code); -+ return -EIO; -+ } -+ -+ version_data[sizeof(version_data) - 1] = '\0'; -+ pr_verbose(verbose, "CCA Version string: %s", version_data); -+ -+ if (sscanf((char *)version_data, "%u.%u.%uz%s", &cca->version.ver, -+ &cca->version.rel, &cca->version.mod, date) != 4) { -+ warnx("CCA library version is invalid: %s", version_data); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+/** -+ * Loads the CCA library and provides the entry point of the CSNBKTC function. -+ * -+ * @param[out] cca on return this contains the address of the CCA -+ * library and certain CCA symbols. dlclose() should -+ * be used to free the library when no longer needed. -+ * @param verbose if true, verbose messages are printed -+ * -+ * @returns 0 on success, -ELIBACC in case of library load errors -+ */ -+int load_cca_library(struct cca_lib *cca, bool verbose) -+{ -+ util_assert(cca != NULL, "Internal error: caa is NULL"); -+ -+ /* Load the CCA library */ -+ cca->lib_csulcca = dlopen(CCA_LIBRARY_NAME, RTLD_GLOBAL | RTLD_NOW); -+ if (cca->lib_csulcca == NULL) { -+ pr_verbose(verbose, "%s", dlerror()); -+ warnx("The command requires the IBM CCA Host Libraries and " -+ "Tools.\nFor the supported environments and downloads, " -+ "see:\n%s", CCA_WEB_PAGE); -+ return -ELIBACC; -+ } -+ -+ /* Get the Cryptographic Facility Version function */ -+ cca->dll_CSUACFV = (t_CSUACFV)dlsym(cca->lib_csulcca, "CSUACFV"); -+ -+ /* Get the Key Token Change function */ -+ cca->dll_CSNBKTC = (t_CSNBKTC)dlsym(cca->lib_csulcca, "CSNBKTC"); -+ -+ if (cca->dll_CSUACFV == NULL || -+ cca->dll_CSNBKTC == NULL) { -+ pr_verbose(verbose, "%s", dlerror()); -+ warnx("The command requires the IBM CCA Host Libraries and " -+ "Tools.\nFor the supported environments and downloads, " -+ "see:\n%s", CCA_WEB_PAGE); -+ dlclose(cca->lib_csulcca); -+ cca->lib_csulcca = NULL; -+ return -ELIBACC; -+ } -+ -+ pr_verbose(verbose, "CCA library '%s' has been loaded successfully", -+ CCA_LIBRARY_NAME); -+ -+ return get_cca_version(cca, verbose); -+} -+ -+/** -+ * Re-enciphers a secure key. -+ * -+ * @param[in] cca the CCA libraray structure -+ * @param[in] secure_key a buffer containing the secure key -+ * @param[in] secure_key_size the size of the secure key -+ * @param[in] method the re-enciphering method. METHOD_OLD_TO_CURRENT -+ * or METHOD_CURRENT_TO_NEW. -+ * @param[in] verbose if true, verbose messages are printed -+ * -+ * @returns 0 on success, -EIO in case of an error -+ */ -+int key_token_change(struct cca_lib *cca, -+ u8 *secure_key, unsigned int secure_key_size, -+ char *method, bool verbose) -+{ -+ long exit_data_len = 0, rule_array_count; -+ unsigned char rule_array[2 * 8] = { 0, }; -+ unsigned char exit_data[4] = { 0, }; -+ long return_code, reason_code; -+ -+ util_assert(cca != NULL, "Internal error: cca is NULL"); -+ util_assert(secure_key != NULL, "Internal error: secure_key is NULL"); -+ util_assert(secure_key_size > 0, -+ "Internal error: secure_key_size is 0"); -+ util_assert(method != NULL, "Internal error: method is NULL"); -+ -+ memcpy(rule_array, method, 8); -+ memcpy(rule_array + 8, "AES ", 8); -+ rule_array_count = 2; -+ -+ cca->dll_CSNBKTC(&return_code, &reason_code, -+ &exit_data_len, exit_data, -+ &rule_array_count, rule_array, -+ secure_key); -+ -+ pr_verbose(verbose, "CSNBKTC (Key Token Change) with '%s' returned: " -+ "return_code: %ld, reason_code: %ld", method, return_code, -+ reason_code); -+ if (return_code != 0) { -+ print_CCA_error(return_code, reason_code); -+ return -EIO; -+ } -+ -+ if (secure_key_size == 2 * SECURE_KEY_SIZE) { -+ cca->dll_CSNBKTC(&return_code, &reason_code, -+ &exit_data_len, exit_data, -+ &rule_array_count, rule_array, -+ secure_key + SECURE_KEY_SIZE); -+ -+ pr_verbose(verbose, "CSNBKTC (Key Token Change) with '%s' " -+ "returned: return_code: %ld, reason_code: %ld", -+ method, return_code, reason_code); -+ if (return_code != 0) { -+ print_CCA_error(return_code, reason_code); -+ return -EIO; -+ } -+ } -+ return 0; -+} ---- /dev/null -+++ b/zkey/cca.h -@@ -0,0 +1,54 @@ -+/* -+ * zkey - Generate, re-encipher, and validate secure keys -+ * -+ * This header file defines the interface to the CCA host library. -+ * -+ * Copyright IBM Corp. 2019 -+ * -+ * s390-tools is free software; you can redistribute it and/or modify -+ * it under the terms of the MIT license. See LICENSE for details. -+ */ -+ -+#ifndef CCA_H -+#define CCA_H -+ -+#include "lib/zt_common.h" -+ -+#define METHOD_OLD_TO_CURRENT "RTCMK " -+#define METHOD_CURRENT_TO_NEW "RTNMK " -+ -+typedef void (*t_CSNBKTC)(long *return_code, -+ long *reason_code, -+ long *exit_data_length, -+ unsigned char *exit_data, -+ long *rule_array_count, -+ unsigned char *rule_array, -+ unsigned char *key_identifier); -+ -+typedef void (*t_CSUACFV)(long *return_code, -+ long *reason_code, -+ long *exit_data_length, -+ unsigned char *exit_data, -+ long *version_data_length, -+ unsigned char *version_data); -+ -+struct cca_version { -+ unsigned int ver; -+ unsigned int rel; -+ unsigned int mod; -+}; -+ -+struct cca_lib { -+ void *lib_csulcca; -+ t_CSNBKTC dll_CSNBKTC; -+ t_CSUACFV dll_CSUACFV; -+ struct cca_version version; -+}; -+ -+int load_cca_library(struct cca_lib *cca, bool verbose); -+ -+int key_token_change(struct cca_lib *cca, -+ u8 *secure_key, unsigned int secure_key_size, -+ char *method, bool verbose); -+ -+#endif ---- a/zkey/keystore.c -+++ b/zkey/keystore.c -@@ -33,6 +33,7 @@ - - #include "keystore.h" - #include "pkey.h" -+#include "cca.h" - #include "properties.h" - - struct key_filenames { -@@ -2522,7 +2523,7 @@ struct reencipher_params { - struct reencipher_info { - struct reencipher_params params; - int pkey_fd; -- t_CSNBKTC dll_CSNBKTC; -+ struct cca_lib *cca; - unsigned long num_reenciphered; - unsigned long num_failed; - unsigned long num_skipped; -@@ -2533,7 +2534,7 @@ struct reencipher_info { - * - * @param[in] keystore the keystore - * @param[in] name the name of the key -- * @param[in] dll_CSNBKTC the CCA key token change function -+ * @param[in] cca the CCA library struct - * @param[in] params reenciphering parameters - * @param[in] secure_key a buffer containing the secure key - * @param[in] secure_key_size the size of the secure key -@@ -2544,7 +2545,7 @@ struct reencipher_info { - */ - static int _keystore_perform_reencipher(struct keystore *keystore, - const char *name, -- t_CSNBKTC dll_CSNBKTC, -+ struct cca_lib *cca, - struct reencipher_params *params, - u8 *secure_key, size_t secure_key_size, - bool is_old_mk) -@@ -2584,8 +2585,7 @@ static int _keystore_perform_reencipher( - "Secure key '%s' will be re-enciphered from OLD " - "to the CURRENT CCA master key", name); - -- rc = key_token_change(dll_CSNBKTC, -- secure_key, secure_key_size, -+ rc = key_token_change(cca, secure_key, secure_key_size, - METHOD_OLD_TO_CURRENT, - keystore->verbose); - if (rc != 0) { -@@ -2602,8 +2602,7 @@ static int _keystore_perform_reencipher( - if (params->inplace == -1) - params->inplace = 0; - -- rc = key_token_change(dll_CSNBKTC, -- secure_key, secure_key_size, -+ rc = key_token_change(cca, secure_key, secure_key_size, - METHOD_CURRENT_TO_NEW, - keystore->verbose); - if (rc != 0) { -@@ -2696,10 +2695,9 @@ static int _keystore_process_reencipher( - if (!params.complete) { - printf("Re-enciphering key '%s'\n", name); - -- rc = _keystore_perform_reencipher(keystore, name, -- info->dll_CSNBKTC, ¶ms, -- secure_key, secure_key_size, -- is_old_mk); -+ rc = _keystore_perform_reencipher(keystore, name, info->cca, -+ ¶ms, secure_key, -+ secure_key_size, is_old_mk); - if (rc < 0) - goto out; - if (rc > 0) { -@@ -2802,6 +2800,8 @@ out: - * @param[in] inplace if true, the key will be re-enciphere in-place - * @param[in] staged if true, the key will be re-enciphere not in-place - * @param[in] complete if true, a pending re-encipherment is completed -+ * @param[in] pkey_fd the file descriptor of /dev/pkey -+ * @param[in] cca the CCA library struct - * Note: if both from Old and toNew are FALSE, then the reencipherement mode is - * detected automatically. If both are TRUE then the key is reenciphered - * from the OLD to the NEW CCA master key. -@@ -2814,7 +2814,7 @@ int keystore_reencipher_key(struct keyst - const char *apqn_filter, - bool from_old, bool to_new, bool inplace, - bool staged, bool complete, int pkey_fd, -- t_CSNBKTC dll_CSNBKTC) -+ struct cca_lib *cca) - { - struct reencipher_info info; - int rc; -@@ -2830,7 +2830,7 @@ int keystore_reencipher_key(struct keyst - info.params.inplace = 0; - info.params.complete = complete; - info.pkey_fd = pkey_fd; -- info.dll_CSNBKTC = dll_CSNBKTC; -+ info.cca = cca; - info.num_failed = 0; - info.num_reenciphered = 0; - info.num_skipped = 0; ---- a/zkey/keystore.h -+++ b/zkey/keystore.h -@@ -14,6 +14,7 @@ - - #include - -+#include "cca.h" - #include "pkey.h" - - struct keystore { -@@ -54,7 +55,7 @@ int keystore_reencipher_key(struct keyst - const char *apqn_filter, - bool from_old, bool to_new, bool inplace, - bool staged, bool complete, int pkey_fd, -- t_CSNBKTC dll_CSNBKTC); -+ struct cca_lib *cca); - - int keystore_copy_key(struct keystore *keystore, const char *name, - const char *newname, const char *volumes); ---- a/zkey/pkey.c -+++ b/zkey/pkey.c -@@ -44,57 +44,7 @@ - - #define MAX_CIPHER_LEN 32 - --/* -- * Definitions for the CCA library -- */ --#define CCA_LIBRARY_NAME "libcsulcca.so" --#define CCA_WEB_PAGE "http://www.ibm.com/security/cryptocards" -- --#define DEFAULT_KEYBITS 256 -- --/** -- * Loads the CCA library and provides the entry point of the CSNBKTC function. -- * -- * @param[out] lib_csulcca on return this contains the address of the CCA -- * library. dlclose() should be used to free this -- * when no longer needed. -- * @param[out] dll_CSNBKTC on return this contains the address of the -- * CSNBKTC function. -- * @param verbose if true, verbose messages are printed -- * -- * @returns 0 on success, -ELIBACC in case of library load errors -- */ --int load_cca_library(void **lib_csulcca, t_CSNBKTC *dll_CSNBKTC, bool verbose) --{ -- util_assert(lib_csulcca != NULL, "Internal error: lib_csulcca is NULL"); -- util_assert(dll_CSNBKTC != NULL, "Internal error: dll_CSNBKTC is NULL"); -- -- /* Load the CCA library */ -- *lib_csulcca = dlopen(CCA_LIBRARY_NAME, RTLD_GLOBAL | RTLD_NOW); -- if (*lib_csulcca == NULL) { -- pr_verbose(verbose, "%s", dlerror()); -- warnx("The command requires the IBM CCA Host Libraries and " -- "Tools.\nFor the supported environments and downloads, " -- "see:\n%s", CCA_WEB_PAGE); -- return -ELIBACC; -- } -- -- /* Get the Key Token Change function */ -- *dll_CSNBKTC = (t_CSNBKTC)dlsym(*lib_csulcca, "CSNBKTC"); -- if (*dll_CSNBKTC == NULL) { -- pr_verbose(verbose, "%s", dlerror()); -- warnx("The command requires the IBM CCA Host Libraries and " -- "Tools.\nFor the supported environments and downloads, " -- "see:\n%s", CCA_WEB_PAGE); -- dlclose(*lib_csulcca); -- *lib_csulcca = NULL; -- return -ELIBACC; -- } -- -- pr_verbose(verbose, "CCA library '%s' has been loaded successfully", -- CCA_LIBRARY_NAME); -- return 0; --} -+#define DEFAULT_KEYBITS 256 - - /** - * Opens the pkey device and returns its file descriptor. -@@ -523,96 +473,6 @@ out: - } - - /** -- * Prints CCA return and reason code information for certain known CCA -- * error situations. -- * -- * @param return_code the CCA return code -- * @param reason_code the CCA reason code -- */ --static void print_CCA_error(int return_code, int reason_code) --{ -- switch (return_code) { -- case 8: -- switch (reason_code) { -- case 48: -- warnx("The secure key has a CCA master key " -- "verification pattern that is not valid"); -- break; -- } -- break; -- case 12: -- switch (reason_code) { -- case 764: -- warnx("The CCA master key is not loaded and " -- "therefore a secure key cannot be enciphered"); -- break; -- } -- break; -- } --} -- --/** -- * Re-enciphers a secure key. -- * -- * @param[in] dll_CSNBKTC the address of the CCA CSNBKTC function -- * @param[in] secure_key a buffer containing the secure key -- * @param[in] secure_key_size the size of the secure key -- * @param[in] method the re-enciphering method. METHOD_OLD_TO_CURRENT -- * or METHOD_CURRENT_TO_NEW. -- * @param[in] verbose if true, verbose messages are printed -- * -- * @returns 0 on success, -EIO in case of an error -- */ --int key_token_change(t_CSNBKTC dll_CSNBKTC, -- u8 *secure_key, unsigned int secure_key_size, -- char *method, bool verbose) --{ -- long exit_data_len = 0, rule_array_count; -- unsigned char rule_array[2 * 80] = { 0, }; -- unsigned char exit_data[4] = { 0, }; -- long return_code, reason_code; -- -- util_assert(dll_CSNBKTC != NULL, "Internal error: dll_CSNBKTC is NULL"); -- util_assert(secure_key != NULL, "Internal error: secure_key is NULL"); -- util_assert(secure_key_size > 0, -- "Internal error: secure_key_size is 0"); -- util_assert(method != NULL, "Internal error: method is NULL"); -- -- memcpy(rule_array, method, 8); -- memcpy(rule_array + 8, "AES ", 8); -- rule_array_count = 2; -- -- dll_CSNBKTC(&return_code, &reason_code, -- &exit_data_len, exit_data, -- &rule_array_count, rule_array, -- secure_key); -- -- pr_verbose(verbose, "CSNBKTC (Key Token Change) with '%s' returned: " -- "return_code: %ld, reason_code: %ld", method, return_code, -- reason_code); -- if (return_code != 0) { -- print_CCA_error(return_code, reason_code); -- return -EIO; -- } -- -- if (secure_key_size == 2 * SECURE_KEY_SIZE) { -- dll_CSNBKTC(&return_code, &reason_code, -- &exit_data_len, exit_data, -- &rule_array_count, rule_array, -- secure_key + SECURE_KEY_SIZE); -- -- pr_verbose(verbose, "CSNBKTC (Key Token Change) with '%s' " -- "returned: return_code: %ld, reason_code: %ld", -- method, return_code, reason_code); -- if (return_code != 0) { -- print_CCA_error(return_code, reason_code); -- return -EIO; -- } -- } -- return 0; --} -- --/** - * Validates an XTS secure key (the second part) - * - * @param[in] pkey_fd the pkey file descriptor ---- a/zkey/pkey.h -+++ b/zkey/pkey.h -@@ -82,23 +82,10 @@ struct pkey_verifykey { - - #define PKEY_VERIFYKEY _IOWR(PKEY_IOCTL_MAGIC, 0x07, struct pkey_verifykey) - --#define METHOD_OLD_TO_CURRENT "RTCMK " --#define METHOD_CURRENT_TO_NEW "RTNMK " -- --typedef void (*t_CSNBKTC)(long *return_code, -- long *reason_code, -- long *exit_data_length, -- unsigned char *exit_data, -- long *rule_array_count, -- unsigned char *rule_array, -- unsigned char *key_identifier); -- - #define PAES_BLOCK_SIZE 16 - #define ENC_ZERO_LEN (2 * PAES_BLOCK_SIZE) - #define VERIFICATION_PATTERN_LEN (2 * ENC_ZERO_LEN + 1) - --int load_cca_library(void **lib_csulcca, t_CSNBKTC *dll_CSNBKTC, bool verbose); -- - int open_pkey_device(bool verbose); - - int generate_secure_key_random(int pkey_fd, const char *keyfile, -@@ -122,10 +109,6 @@ int validate_secure_key(int pkey_fd, - size_t *clear_key_bitsize, int *is_old_mk, - bool verbose); - --int key_token_change(t_CSNBKTC dll_CSNBKTC, -- u8 *secure_key, unsigned int secure_key_size, -- char *method, bool verbose); -- - int generate_key_verification_pattern(const char *key, size_t key_size, - char *vp, size_t vp_len, bool verbose); - ---- a/zkey/zkey-cryptsetup.c -+++ b/zkey/zkey-cryptsetup.c -@@ -34,6 +34,7 @@ - - #include "misc.h" - #include "pkey.h" -+#include "cca.h" - - /* Detect if cryptsetup 2.1 or later is available */ - #ifdef CRYPT_LOG_DEBUG_JSON -@@ -101,8 +102,7 @@ static struct zkey_cryptsetup_globals { - bool batch_mode; - bool debug; - bool verbose; -- void *lib_csulcca; -- t_CSNBKTC dll_CSNBKTC; -+ struct cca_lib cca; - int pkey_fd; - struct crypt_device *cd; - } g = { -@@ -1578,7 +1578,7 @@ static int reencipher_prepare(int token) - util_print_indented(msg, 0); - free(msg); - -- rc = key_token_change(g.dll_CSNBKTC, (u8 *)key, keysize, -+ rc = key_token_change(&g.cca, (u8 *)key, keysize, - is_old_mk ? METHOD_OLD_TO_CURRENT : - METHOD_CURRENT_TO_NEW, - g.verbose); -@@ -1700,7 +1700,7 @@ static int reencipher_complete(int token - goto out; - } - -- rc = key_token_change(g.dll_CSNBKTC, (u8 *)key, keysize, -+ rc = key_token_change(&g.cca, (u8 *)key, keysize, - METHOD_OLD_TO_CURRENT, g.verbose); - if (rc != 0) { - warnx("Failed to re-encipher the secure volume key for " -@@ -2288,8 +2288,7 @@ int main(int argc, char *argv[]) - } - - if (command->need_cca_library) { -- rc = load_cca_library(&g.lib_csulcca, &g.dll_CSNBKTC, -- g.verbose); -+ rc = load_cca_library(&g.cca, g.verbose); - if (rc != 0) { - rc = EXIT_FAILURE; - goto out; -@@ -2331,8 +2330,8 @@ int main(int argc, char *argv[]) - rc = command->function(); - - out: -- if (g.lib_csulcca) -- dlclose(g.lib_csulcca); -+ if (g.cca.lib_csulcca) -+ dlclose(g.cca.lib_csulcca); - if (g.pkey_fd >= 0) - close(g.pkey_fd); - if (g.cd) ---- a/zkey/zkey.c -+++ b/zkey/zkey.c -@@ -27,6 +27,7 @@ - #include "lib/util_prg.h" - #include "lib/zt_common.h" - -+#include "cca.h" - #include "keystore.h" - #include "misc.h" - #include "pkey.h" -@@ -80,8 +81,7 @@ static struct zkey_globals { - bool force; - bool open; - bool format; -- void *lib_csulcca; -- t_CSNBKTC dll_CSNBKTC; -+ struct cca_lib cca; - int pkey_fd; - struct keystore *keystore; - } g = { -@@ -1194,8 +1194,7 @@ static int command_reencipher_file(void) - pr_verbose("Secure key will be re-enciphered from OLD to the " - "CURRENT CCA master key"); - -- rc = key_token_change(g.dll_CSNBKTC, -- secure_key, secure_key_size, -+ rc = key_token_change(&g.cca, secure_key, secure_key_size, - METHOD_OLD_TO_CURRENT, - g.verbose); - if (rc != 0) { -@@ -1209,8 +1208,7 @@ static int command_reencipher_file(void) - pr_verbose("Secure key will be re-enciphered from CURRENT " - "to the NEW CCA master key"); - -- rc = key_token_change(g.dll_CSNBKTC, -- secure_key, secure_key_size, -+ rc = key_token_change(&g.cca, secure_key, secure_key_size, - METHOD_CURRENT_TO_NEW, g.verbose); - if (rc != 0) { - warnx("Re-encipher from CURRENT to NEW CCA " -@@ -1270,7 +1268,7 @@ static int command_reencipher_repository - - rc = keystore_reencipher_key(g.keystore, g.name, g.apqns, g.fromold, - g.tonew, g.inplace, g.staged, g.complete, -- g.pkey_fd, g.dll_CSNBKTC); -+ g.pkey_fd, &g.cca); - - return rc != 0 ? EXIT_FAILURE : EXIT_SUCCESS; - } -@@ -1867,8 +1865,7 @@ int main(int argc, char *argv[]) - } - - if (command->need_cca_library) { -- rc = load_cca_library(&g.lib_csulcca, &g.dll_CSNBKTC, -- g.verbose); -+ rc = load_cca_library(&g.cca, g.verbose); - if (rc != 0) { - rc = EXIT_FAILURE; - goto out; -@@ -1887,8 +1884,8 @@ int main(int argc, char *argv[]) - rc = command->function(); - - out: -- if (g.lib_csulcca) -- dlclose(g.lib_csulcca); -+ if (g.cca.lib_csulcca) -+ dlclose(g.cca.lib_csulcca); - if (g.pkey_fd >= 0) - close(g.pkey_fd); - if (g.keystore) diff --git a/s390-tools-sles15sp2-01-zpcictl-Initiate-recover-after-reset.patch b/s390-tools-sles15sp2-01-zpcictl-Initiate-recover-after-reset.patch deleted file mode 100644 index 91aa36c..0000000 --- a/s390-tools-sles15sp2-01-zpcictl-Initiate-recover-after-reset.patch +++ /dev/null @@ -1,70 +0,0 @@ -Subject: [PATCH] [BZ 184174] zpcictl: Initiate recover after reset -From: Jan Hoeppner - -Description: zpcictl: Initiate recover after reset -Symptom: If a PCI function is reset using zpcictl --reset, the function - is in an error state. -Problem: zpcictl --reset only issues a SCLP reset and leaves the PCI - function in an error state. -Solution: Initiate an OS level recovery by calling - /sys/bus/devices//recover after the SCLP reset. -Reproduction: Call zpcictl --reset - Under z/VM check the state of the function with 'vmcp q pcif' -Upstream-ID: bc0d40c5803d4c5426b17b6d59aa0f1e46a2aacc -Problem-ID: 184174 - -Upstream-Description: - - zpcictl: Initiate recover after reset - - After a zpcitctl --reset the PCI function is currently left in an error - state. This seems unexpected, so follow the SCLP reset with an OS level - recovery using /sys/bus/devices//recover. - - Signed-off-by: Niklas Schnelle - Reviewed-by: Jan Hoeppner - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Jan Hoeppner ---- - zpcictl/zpcictl.c | 21 +++++++++++++++++++++ - 1 file changed, 21 insertions(+) - ---- a/zpcictl/zpcictl.c -+++ b/zpcictl/zpcictl.c -@@ -163,6 +163,26 @@ static unsigned int sysfs_read_value(str - return val; - } - -+static void sysfs_write_value(struct zpci_device *pdev, const char *attr, -+ unsigned int val) -+{ -+ char *path; -+ FILE *fp; -+ -+ path = util_path_sysfs("bus/pci/devices/%s/%s", pdev->slot, attr); -+ fp = fopen(path, "w"); -+ if (!fp) -+ fopen_err(path); -+ if (fprintf(fp, "%x", val) < 0) { -+ fclose(fp); -+ warnx("Could not write to file %s: %s", path, strerror(errno)); -+ free(path); -+ exit(EXIT_FAILURE); -+ } -+ fclose(fp); -+ free(path); -+} -+ - static void sysfs_write_data(struct zpci_report_error *report, char *slot) - { - size_t r_size; -@@ -297,6 +317,7 @@ static void sclp_issue_action(struct zpc - static void sclp_reset_device(struct zpci_device *pdev) - { - sclp_issue_action(pdev, SCLP_ERRNOTIFY_AQ_RESET); -+ sysfs_write_value(pdev, "recover", 1); - } - - /* diff --git a/s390-tools-sles15sp2-02-zipl-allow-stand-alone-secure-option-on-command-l.patch b/s390-tools-sles15sp2-02-zipl-allow-stand-alone-secure-option-on-command-l.patch deleted file mode 100644 index d93b981..0000000 --- a/s390-tools-sles15sp2-02-zipl-allow-stand-alone-secure-option-on-command-l.patch +++ /dev/null @@ -1,170 +0,0 @@ -Subject: [PATCH] [BZ 184396] zipl: allow stand alone secure option on command line -From: Stefan Haberland - -Description: zipl: fix secure boot config handling -Symptom: The config file parsing for secure boot worked not as - it was expected to be. For example a config section - setting was not evaluated properly. - It is not possible to specify command line option -S - without other options. - Additionally the man page showed an invalid example. -Problem: The config file parsing was not implemented properly. -Solution: The hierarchy of the secure boot settings in the config - file is: - defaultboot > menu > section - Allow that --secure or -S is specified on command line - without the need to allow all options on the command - line. Also ensure that the command line option - overrules the config option and correctly ensure that - secure boot is only set for SCSI devices. - Fix man page example. -Reproduction: Run zipl with a secure= setting in a configuration - section or specify -S on command line. -Upstream-ID: 27f6c0a167da8d08f7f3343360528528f85d661f -Problem-ID: 184396 - -Upstream-Description: - - zipl: allow stand alone secure option on command line - - Allow that --secure or -S is specified on command line without the need to - allow all options on the command line. - Also ensure that the command line option overrules the config option and - correctly ensure that secure boot is only set for SCSI devices. - - Signed-off-by: Stefan Haberland - Reviewed-by: Philipp Rudo - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Stefan Haberland ---- - zipl/src/bootmap.c | 6 ++++++ - zipl/src/job.c | 52 +++++++++++++++++++++++++--------------------------- - 2 files changed, 31 insertions(+), 27 deletions(-) - ---- a/zipl/src/bootmap.c -+++ b/zipl/src/bootmap.c -@@ -1133,6 +1133,12 @@ bootmap_create(struct job_data *job, dis - disk_get_type_name(info->type)); - goto out_disk_free_info; - } -+ /* Check if secure boot was enabled only for SCSI */ -+ if (job->is_secure == SECURE_BOOT_ENABLED && -+ info->type != disk_type_scsi) { -+ error_reason("Secure boot forced for non-SCSI disk type"); -+ goto out_disk_free_info; -+ } - if (verbose) { - printf("Target device information\n"); - disk_print_info(info); ---- a/zipl/src/job.c -+++ b/zipl/src/job.c -@@ -72,6 +72,7 @@ struct command_line { - int add_files; - int dry_run; - int force; -+ int is_secure; - enum scan_section_type type; - }; - -@@ -89,6 +90,22 @@ store_option(struct command_line* cmdlin - return 0; - } - -+static int -+set_secure_ipl(char *keyword, int *is_secure) -+{ -+ if (strcmp(keyword, "auto") == 0) { -+ *is_secure = SECURE_BOOT_AUTO; -+ } else if (strcmp(keyword, "0") == 0) { -+ *is_secure = SECURE_BOOT_DISABLED; -+ } else if (strcmp(keyword, "1") == 0) { -+ *is_secure = SECURE_BOOT_ENABLED; -+ } else { -+ error_reason("Invalid secure boot setting '%s'", -+ keyword); -+ return -1; -+ } -+ return 0; -+} - - static int - get_command_line(int argc, char* argv[], struct command_line* line) -@@ -217,9 +234,7 @@ get_command_line(int argc, char* argv[], - cmdline.menu = optarg; - break; - case 'S': -- is_keyword = 1; -- rc = store_option(&cmdline, scan_keyword_secure, -- optarg); -+ rc = set_secure_ipl(optarg, &cmdline.is_secure); - break; - case 'h': - cmdline.help = 1; -@@ -1270,27 +1285,6 @@ type_from_target(char *target, disk_type - } - - static int --set_secure_ipl(char *keyword, struct job_data *job) --{ -- if (strcmp(keyword, "auto") == 0) { -- job->is_secure = SECURE_BOOT_AUTO; -- } else if (strcmp(keyword, "0") == 0) { -- job->is_secure = SECURE_BOOT_DISABLED; -- } else if (strcmp(keyword, "1") == 0) { -- if (job->target.targettype != disk_type_scsi) { -- error_reason("Secure boot forced for non-SCSI disk type"); -- return -1; -- } -- job->is_secure = SECURE_BOOT_ENABLED; -- } else { -- error_reason("Invalid secure boot setting '%s'", -- keyword); -- return -1; -- } -- return 0; --} -- --static int - get_job_from_section_data(char* data[], struct job_data* job, char* section) - { - int rc; -@@ -1374,7 +1368,7 @@ get_job_from_section_data(char* data[], - /* Fill in secure boot */ - if (data[(int) scan_keyword_secure] != NULL) { - rc = set_secure_ipl(data[(int) scan_keyword_secure], -- job); -+ &job->is_secure); - if (rc) - return rc; - } -@@ -1538,7 +1532,7 @@ get_menu_job(struct scan_token* scan, ch - case scan_keyword_secure: - rc = set_secure_ipl( - scan[i].content.keyword.value, -- job); -+ &job->is_secure); - if (rc) - return rc; - break; -@@ -1880,7 +1874,6 @@ job_get(int argc, char* argv[], struct j - job->add_files = cmdline.add_files; - job->data.mvdump.force = cmdline.force; - job->dry_run = cmdline.dry_run; -- job->is_secure = SECURE_BOOT_AUTO; - /* Get job data from user input */ - if (cmdline.help) { - job->command_line = 1; -@@ -1899,6 +1892,11 @@ job_get(int argc, char* argv[], struct j - job_free(job); - return rc; - } -+ if (cmdline.is_secure) -+ job->is_secure = cmdline.is_secure; -+ else -+ job->is_secure = job->is_secure ? : SECURE_BOOT_AUTO; -+ - /* Check job data for validity */ - rc = check_job_data(job); - if (rc) { diff --git a/s390-tools-sles15sp2-02-zipl-fix-Waddress-of-packed-member.patch b/s390-tools-sles15sp2-02-zipl-fix-Waddress-of-packed-member.patch deleted file mode 100644 index 8416766..0000000 --- a/s390-tools-sles15sp2-02-zipl-fix-Waddress-of-packed-member.patch +++ /dev/null @@ -1,102 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] zipl: fix -Waddress-of-packed-member -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: aa09b292483eb2d79247260fccc2b456dee01e8d -Problem-ID: VS1804 - -Upstream-Description: - - zipl: fix -Waddress-of-packed-member - - Reported by GCC 9.2.1 when building with '-Waddress-of-packed-member'. - - menu.c: In function 'menu_read': - menu.c:30:22: warning: taking address of packed member of 'struct boot_stage2_params' may result in an unaligned pointer value [-Waddress-of-packed-member] - 30 | uint16_t *configs = __stage2_params.config; - | ^~~~~~~~~~~~~~~ - menu.c: In function 'menu_list': - menu.c:83:22: warning: taking address of packed member of 'struct boot_stage2_params' may result in an unaligned pointer value [-Waddress-of-packed-member] - 83 | uint16_t *configs = __stage2_params.config; - | ^~~~~~~~~~~~~~~ - menu.c: In function 'menu': - menu.c:139:22: warning: taking address of packed member of 'struct boot_stage2_params' may result in an unaligned pointer value [-Waddress-of-packed-member] - 139 | uint16_t *configs = __stage2_params.config; - | ^~~~~~~~~~~~~~~ - - Signed-off-by: Marc Hartmayer - Reviewed-by: Stefan Haberland - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - zipl/boot/menu.c | 13 +++++-------- - 1 file changed, 5 insertions(+), 8 deletions(-) - ---- a/zipl/boot/menu.c -+++ b/zipl/boot/menu.c -@@ -27,7 +27,6 @@ static void menu_prompt(int timeout) - static int menu_read(void) - { - char *temp_area = (char *)get_zeroed_page(); -- uint16_t *configs = __stage2_params.config; - int timeout, rc, i, count = 0; - char *endptr; - int value; -@@ -60,7 +59,7 @@ static int menu_read(void) - value = ebcstrtoul((char *)temp_area, &endptr, 10); - - if ((endptr != temp_area) && (value < BOOT_MENU_ENTRIES - 1) && -- (configs[value] != 0)) { -+ (__stage2_params.config[value] != 0)) { - /* valid config found - finish */ - break; - } else { -@@ -80,14 +79,13 @@ out_free_page: - - static int menu_list(void) - { -- uint16_t *configs = __stage2_params.config; - char *name; - int i; - - for (i = 0; i < BOOT_MENU_ENTRIES; i++) { -- if (configs[i] == 0) -+ if (__stage2_params.config[i] == 0) - continue; -- name = configs[i] + ((void *)&__stage2_params); -+ name = __stage2_params.config[i] + ((void *)&__stage2_params); - printf("%s\n", name); - if (i == 0) - printf("\n"); -@@ -136,7 +134,6 @@ static int menu_param(unsigned long *val - - int menu(void) - { -- uint16_t *configs = __stage2_params.config; - unsigned long value = 0; - char *cmd_line_extra; - char endstring[15]; -@@ -181,11 +178,11 @@ int menu(void) - - boot: - /* sanity - config entry not valid */ -- if (configs[value] == 0) -+ if (__stage2_params.config[value] == 0) - panic(EINTERNAL, "%s", msg_econfig); - - printf("Booting %s\n", -- (char *)(configs[value] + -+ (char *)(__stage2_params.config[value] + - (void *)&__stage2_params + TEXT_OFFSET)); - - /* append 'BOOT_IMAGE=' to parmline */ diff --git a/s390-tools-sles15sp2-02-zipl-libc-Fix-potential-buffer-overflow-in-printf.patch b/s390-tools-sles15sp2-02-zipl-libc-Fix-potential-buffer-overflow-in-printf.patch deleted file mode 100644 index c322f35..0000000 --- a/s390-tools-sles15sp2-02-zipl-libc-Fix-potential-buffer-overflow-in-printf.patch +++ /dev/null @@ -1,63 +0,0 @@ -Subject: [PATCH] [BZ 184060] zipl/libc: Fix potential buffer overflow in printf -From: Philipp Rudo - -Description: zipl/libc: Fix potential buffer overflow in printf -Symptom: Crash of the zipl boot loader during boot. -Problem: The zipl boot loaders have their own minimalistic libc - implementation. In it printf and sprintf use vsprintf for string - formatting. Per definition vsprintf assumes that the buffer it - writes to is large enough to contain the formatted string and - performs no size checks. This is problematic for the boot - loaders because the buffer they use are often allocated on the - stack. Thus even small changes to the string format can - potentially cause buffer overflows on the stack. -Solution: Implement vsnprintf and make use of it. -Reproduction: Use printf to print a string with >81 characters (exact number - depends on the stack layout/compiler used). -Upstream-ID: 8874b908254c47c8a6fd7a1aca2c7371c11035c4 -Problem-ID: 184060 - -Upstream-Description: - - zipl/libc: Fix potential buffer overflow in printf - - Per definition vsprint assumes that the provided buffer it writes to is - large enough to contain the formatted string. As printf uses a fixed - sized buffer (81 bytes) and has no size checks the use of vsprintf can - easily cause buffer overflows. Protect against these buffer overflows by - using vsnprintf instead. - - While at it fix a typo in the comment. - - Reported-by: Marc Hartmayer - Signed-off-by: Philipp Rudo - Reviewed-by: Marc Hartmayer - Reviewed-by: Stefan Haberland - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Philipp Rudo ---- - zipl/boot/libc.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/zipl/boot/libc.c -+++ b/zipl/boot/libc.c -@@ -530,7 +530,7 @@ void sprintf(char *str, const char *fmt, - } - - /* -- * Print formated string -+ * Print formatted string to console - */ - void printf(const char *fmt, ...) - { -@@ -538,7 +538,7 @@ void printf(const char *fmt, ...) - va_list va; - - va_start(va, fmt); -- vsprintf(buf, fmt, va); -+ vsnprintf(buf, sizeof(buf), fmt, va); - sclp_print(buf); - va_end(va); - } diff --git a/s390-tools-sles15sp2-02-zipl-stage3-correctly-handle-diag308-response-code.patch b/s390-tools-sles15sp2-02-zipl-stage3-correctly-handle-diag308-response-code.patch deleted file mode 100644 index ed1c4b9..0000000 --- a/s390-tools-sles15sp2-02-zipl-stage3-correctly-handle-diag308-response-code.patch +++ /dev/null @@ -1,87 +0,0 @@ -Subject: [PATCH] [BZ 186940] zipl/stage3: correctly handle diag308 response code -From: Stefan Haberland - -Description: zipl: Fix KVM IPL without bootindex -Symptom: Failed IPL on KVM when no bootindex is specified. -Problem: Without bootindex specified there is no IPL parmblock - on KVM which can be read by the stage3 loader. -Solution: In case diag308 gives a response code 0x102 the stage3 - loader can safely assume that no secure IPL is required - since no IPL report block exists. -Reproduction: IPL on KVM without 'bootindex=' attached. -Upstream-ID: b7f1977d3f9332f82e7f388fb18076b89b83944e -Problem-ID: 186940 - -Upstream-Description: - - zipl/stage3: correctly handle diag308 response code - - In case diag308 gives a response code 0x102 the stage3 loader can - safely assume that no secure IPL is required since no IPL report - block exists. - - Suggested-by: Marc Hartmayer - Signed-off-by: Stefan Haberland - Reviewed-by: Marc Hartmayer - Reviewed-by: Philipp Rudo - Tested-by: Marc Hartmayer - - -Signed-off-by: Stefan Haberland ---- - include/boot/s390.h | 1 + - zipl/boot/stage3.c | 25 +++++++++++-------------- - 2 files changed, 12 insertions(+), 14 deletions(-) - ---- a/include/boot/s390.h -+++ b/include/boot/s390.h -@@ -279,6 +279,7 @@ enum diag308_subcode { - - enum diag308_rc { - DIAG308_RC_OK = 0x0001, -+ DIAG308_RC_NO_CONF = 0x0102, - }; - - static __always_inline unsigned long diag308(unsigned long subcode, void *addr) ---- a/zipl/boot/stage3.c -+++ b/zipl/boot/stage3.c -@@ -55,18 +55,6 @@ static inline void __noreturn start_kern - while (1); - } - --unsigned int store_ipl_parmblock(struct ipl_pl_hdr *pl_hdr) --{ -- int rc; -- -- rc = diag308(DIAG308_STORE, pl_hdr); -- if (rc == DIAG308_RC_OK && -- pl_hdr->version <= IPL_MAX_SUPPORTED_VERSION) -- return 0; -- -- return 1; --} -- - unsigned int - is_verified_address(unsigned long image_addr) - { -@@ -124,9 +112,18 @@ secure_boot_enabled() - unsigned int rc; - - pl_hdr = (void *)get_zeroed_page(); -- if (!pl_hdr || store_ipl_parmblock(pl_hdr)) -+ switch (diag308(DIAG308_STORE, pl_hdr)) { -+ case DIAG308_RC_OK: -+ rc = pl_hdr->version <= IPL_MAX_SUPPORTED_VERSION && -+ !!(pl_hdr->flags & IPL_FLAG_SECURE); -+ break; -+ case DIAG308_RC_NO_CONF: -+ rc = 0; -+ break; -+ default: - panic(ESECUREBOOT, "%s", msg_sipl_noparm); -- rc = !!(pl_hdr->flags & IPL_FLAG_SECURE); -+ break; -+ } - free_page((unsigned long) pl_hdr); - - return rc; diff --git a/s390-tools-sles15sp2-02-zkey-Move-utility-functions-into-separate-source-fil.patch b/s390-tools-sles15sp2-02-zkey-Move-utility-functions-into-separate-source-fil.patch deleted file mode 100644 index 6c379bd..0000000 --- a/s390-tools-sles15sp2-02-zkey-Move-utility-functions-into-separate-source-fil.patch +++ /dev/null @@ -1,297 +0,0 @@ -Subject: zkey: Move utility functions into separate source file -From: Ingo Franzki - -Summary: zkey: check master key consistency -Description: Enhances the zkey tool to perform a cross check whether the - APQNs associated with a secure key have the same master key. - Display the master key verification pattern of a secure key - during the zkey validate command. This helps to better identify - which master key is the correct one, in case of master key - inconsistencies. - Select an appropriate APQN when re-enciphering a secure key. - Re-enciphering is done using the CCA host library. Special - handling is required to select an appropriate APQN for use with - the CCA host library. -Upstream-ID: 696e8458f0c117e3a084e1a083de89ec19baaff9 -Problem-ID: SEC1916 - -Upstream-Description: - - zkey: Move utility functions into separate source file - - As preparation for future changes, move a sysfs specific functions - into a separate source file (utils.c). - - Signed-off-by: Ingo Franzki - Reviewed-by: Harald Freudenberger - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/Makefile | 5 +- - zkey/keystore.c | 69 +---------------------------------- - zkey/utils.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - zkey/utils.h | 21 ++++++++++ - 4 files changed, 136 insertions(+), 68 deletions(-) - ---- a/zkey/Makefile -+++ b/zkey/Makefile -@@ -67,12 +67,13 @@ all: $(BUILD_TARGETS) - zkey.o: zkey.c pkey.h cca.h misc.h - pkey.o: pkey.c pkey.h - cca.o: cca.c cca.h pkey.h -+utils.o: utils.h - properties.o: check-dep-zkey properties.c properties.h --keystore.o: keystore.c keystore.h properties.h pkey.h cca.h -+keystore.o: keystore.c keystore.h properties.h pkey.h cca.h utils.h - zkey-cryptsetup.o: check-dep-zkey-cryptsetup zkey-cryptsetup.c pkey.h cca.h misc.h - - zkey: LDLIBS = -ldl -lcrypto --zkey: zkey.o pkey.o cca.o properties.o keystore.o $(libs) -+zkey: zkey.o pkey.o cca.o properties.o keystore.o utils.o $(libs) - $(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@ - - zkey-cryptsetup: LDLIBS = -ldl -lcryptsetup -ljson-c ---- a/zkey/keystore.c -+++ b/zkey/keystore.c -@@ -25,7 +25,6 @@ - #include - - #include "lib/util_base.h" --#include "lib/util_file.h" - #include "lib/util_libc.h" - #include "lib/util_panic.h" - #include "lib/util_path.h" -@@ -35,6 +34,7 @@ - #include "pkey.h" - #include "cca.h" - #include "properties.h" -+#include "utils.h" - - struct key_filenames { - char *skey_filename; -@@ -1010,69 +1010,6 @@ free: - return rc; - } - --/** -- * Checks if the specified APQN is of type CCA and is online -- * -- * @param[in] card card number -- * @param[in] domain the domain -- * -- * @returns 1 if its a CCA card and is online, 0 if offline and -1 if its -- * not a CCA card. -- */ --static int _keystore_is_apqn_online(int card, int domain) --{ -- long int online; -- char *dev_path; -- char type[20]; -- int rc = 1; -- -- dev_path = util_path_sysfs("bus/ap/devices/card%02x", card); -- if (!util_path_is_dir(dev_path)) { -- rc = 0; -- goto out; -- } -- if (util_file_read_l(&online, 10, "%s/online", dev_path) != 0) { -- rc = 0; -- goto out; -- } -- if (online == 0) { -- rc = 0; -- goto out; -- } -- if (util_file_read_line(type, sizeof(type), "%s/type", dev_path) != 0) { -- rc = 0; -- goto out; -- } -- if (strncmp(type, "CEX", 3) != 0 || strlen(type) < 5) { -- rc = 0; -- goto out; -- } -- if (type[4] != 'C') { -- rc = -1; -- goto out; -- } -- free(dev_path); -- -- dev_path = util_path_sysfs("bus/ap/devices/card%02x/%02x.%04x", card, -- card, domain); -- if (!util_path_is_dir(dev_path)) { -- rc = 0; -- goto out; -- } -- if (util_file_read_l(&online, 10, "%s/online", dev_path) != 0) { -- rc = 0; -- goto out; -- } -- if (online == 0) { -- rc = 0; -- goto out; -- } -- --out: -- free(dev_path); -- return rc; --} -- - struct apqn_check { - bool noonlinecheck; - bool nomsg; -@@ -1124,7 +1061,7 @@ static int _keystore_apqn_check(const ch - goto out; - } - -- rc = _keystore_is_apqn_online(card, domain); -+ rc = sysfs_is_apqn_online(card, domain); - if (rc != 1) { - if (info->nomsg == 0) - warnx("The APQN %02x.%04x is %s", card, domain, -@@ -2329,7 +2266,7 @@ static int _keystore_display_apqn_status - if (sscanf(apqn_list[i], "%x.%x", &card, &domain) != 2) - continue; - -- rc = _keystore_is_apqn_online(card, domain); -+ rc = sysfs_is_apqn_online(card, domain); - if (rc != 1) { - printf("WARNING: The APQN %02x.%04x associated with " - "key '%s' is %s\n", card, domain, name, ---- /dev/null -+++ b/zkey/utils.c -@@ -0,0 +1,109 @@ -+/* -+ * zkey - Generate, re-encipher, and validate secure keys -+ * -+ * Copyright IBM Corp. 2019 -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+ -+#include "lib/util_path.h" -+#include "lib/util_file.h" -+ -+#include "utils.h" -+ -+/** -+ * Checks if the specified card is of type CCA and is online -+ * -+ * @param[in] card card number -+ * -+ * @returns 1 if its a CCA card and is online, 0 if offline and -1 if its -+ * not a CCA card. -+ */ -+int sysfs_is_card_online(int card) -+{ -+ long int online; -+ char *dev_path; -+ char type[20]; -+ int rc = 1; -+ -+ dev_path = util_path_sysfs("bus/ap/devices/card%02x", card); -+ if (!util_path_is_dir(dev_path)) { -+ rc = 0; -+ goto out; -+ } -+ if (util_file_read_l(&online, 10, "%s/online", dev_path) != 0) { -+ rc = 0; -+ goto out; -+ } -+ if (online == 0) { -+ rc = 0; -+ goto out; -+ } -+ if (util_file_read_line(type, sizeof(type), "%s/type", dev_path) != 0) { -+ rc = 0; -+ goto out; -+ } -+ if (strncmp(type, "CEX", 3) != 0 || strlen(type) < 5) { -+ rc = 0; -+ goto out; -+ } -+ if (type[4] != 'C') { -+ rc = -1; -+ goto out; -+ } -+ -+out: -+ free(dev_path); -+ return rc; -+} -+ -+/** -+ * Checks if the specified APQN is of type CCA and is online -+ * -+ * @param[in] card card number -+ * @param[in] domain the domain -+ * -+ * @returns 1 if its a CCA card and is online, 0 if offline and -1 if its -+ * not a CCA card. -+ */ -+int sysfs_is_apqn_online(int card, int domain) -+{ -+ long int online; -+ char *dev_path; -+ int rc = 1; -+ -+ rc = sysfs_is_card_online(card); -+ if (rc != 1) -+ return rc; -+ -+ dev_path = util_path_sysfs("bus/ap/devices/card%02x/%02x.%04x", card, -+ card, domain); -+ if (!util_path_is_dir(dev_path)) { -+ rc = 0; -+ goto out; -+ } -+ if (util_file_read_l(&online, 10, "%s/online", dev_path) != 0) { -+ rc = 0; -+ goto out; -+ } -+ if (online == 0) { -+ rc = 0; -+ goto out; -+ } -+ -+out: -+ free(dev_path); -+ return rc; -+} -+ ---- /dev/null -+++ b/zkey/utils.h -@@ -0,0 +1,21 @@ -+/* -+ * zkey - Generate, re-encipher, and validate secure keys -+ * -+ * This header file defines the interface to the CCA host library. -+ * -+ * Copyright IBM Corp. 2019 -+ * -+ * s390-tools is free software; you can redistribute it and/or modify -+ * it under the terms of the MIT license. See LICENSE for details. -+ */ -+ -+#ifndef UTILS_H -+#define UTILS_H -+ -+#include "lib/zt_common.h" -+ -+int sysfs_is_card_online(int card); -+ -+int sysfs_is_apqn_online(int card, int domain); -+ -+#endif diff --git a/s390-tools-sles15sp2-02-zpcictl-Rename-misleading-sysfs_write_data.patch b/s390-tools-sles15sp2-02-zpcictl-Rename-misleading-sysfs_write_data.patch deleted file mode 100644 index 29107f3..0000000 --- a/s390-tools-sles15sp2-02-zpcictl-Rename-misleading-sysfs_write_data.patch +++ /dev/null @@ -1,51 +0,0 @@ -Subject: [PATCH] [BZ 184174] zpcictl: Rename misleading sysfs_write_data -From: Jan Hoeppner - -Description: zpcictl: Initiate recover after reset -Symptom: If a PCI function is reset using zpcictl --reset, the function - is in an error state. -Problem: zpcictl --reset only issues a SCLP reset and leaves the PCI - function in an error state. -Solution: Initiate an OS level recovery by calling - /sys/bus/devices//recover after the SCLP reset. -Reproduction: Call zpcictl --reset - Under z/VM check the state of the function with 'vmcp q pcif' -Upstream-ID: d77234ddb68719819c7e8380c71dbebc555539ab -Problem-ID: 184174 - -Upstream-Description: - - zpcictl: Rename misleading sysfs_write_data - - To sysfs_report_error as it only writes to the report_error attribute. - - Signed-off-by: Niklas Schnelle - Reviewed-by: Jan Hoeppner - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Jan Hoeppner ---- - zpcictl/zpcictl.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/zpcictl/zpcictl.c -+++ b/zpcictl/zpcictl.c -@@ -183,7 +183,7 @@ static void sysfs_write_value(struct zpc - free(path); - } - --static void sysfs_write_data(struct zpci_report_error *report, char *slot) -+static void sysfs_report_error(struct zpci_report_error *report, char *slot) - { - size_t r_size; - char *path; -@@ -308,7 +308,7 @@ static void sclp_issue_action(struct zpc - sizeof(report.data.log_data)); - free(sdata); - } -- sysfs_write_data(&report, pdev->slot); -+ sysfs_report_error(&report, pdev->slot); - } - - /* diff --git a/s390-tools-sles15sp2-03-zipl-correct-secure-boot-config-handling.patch b/s390-tools-sles15sp2-03-zipl-correct-secure-boot-config-handling.patch deleted file mode 100644 index 39dc9b7..0000000 --- a/s390-tools-sles15sp2-03-zipl-correct-secure-boot-config-handling.patch +++ /dev/null @@ -1,187 +0,0 @@ -Subject: [PATCH] [BZ 184396] zipl: correct secure boot config handling -From: Stefan Haberland - -Description: zipl: fix secure boot config handling -Symptom: The config file parsing for secure boot worked not as - it was expected to be. For example a config section - setting was not evaluated properly. - It is not possible to specify command line option -S - without other options. - Additionally the man page showed an invalid example. -Problem: The config file parsing was not implemented properly. -Solution: The hierarchy of the secure boot settings in the config - file is: - defaultboot > menu > section - Allow that --secure or -S is specified on command line - without the need to allow all options on the command - line. Also ensure that the command line option - overrules the config option and correctly ensure that - secure boot is only set for SCSI devices. - Fix man page example. -Reproduction: Run zipl with a secure= setting in a configuration - section or specify -S on command line. -Upstream-ID: 6f9337d1016e00f360cf4a81d39a42df5184b3a2 -Problem-ID: 184396 - -Upstream-Description: - - zipl: correct secure boot config handling - - The hierarchy of the secure boot settings in the config file should be: - - defaultboot > menu > section - - This patch implements this hierarchy and adds a check if a valid option is - specified and prints an error message otherwise. - - Signed-off-by: Stefan Haberland - Reviewed-by: Philipp Rudo - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Stefan Haberland ---- - zipl/include/job.h | 1 + - zipl/include/zipl.h | 1 + - zipl/src/bootmap.c | 8 +++++++- - zipl/src/job.c | 29 ++++++++++++++++++++++++++--- - 4 files changed, 35 insertions(+), 4 deletions(-) - ---- a/zipl/include/job.h -+++ b/zipl/include/job.h -@@ -94,6 +94,7 @@ struct job_menu_entry { - char* name; - enum job_id id; - union job_menu_entry_data data; -+ int is_secure; - }; - - struct job_menu_data { ---- a/zipl/include/zipl.h -+++ b/zipl/include/zipl.h -@@ -57,6 +57,7 @@ - - #define MAX_DUMP_VOLUMES 32 - -+#define SECURE_BOOT_UNDEFINED -1 - #define SECURE_BOOT_DISABLED 0 - #define SECURE_BOOT_ENABLED 1 - #define SECURE_BOOT_AUTO 2 ---- a/zipl/src/bootmap.c -+++ b/zipl/src/bootmap.c -@@ -945,6 +945,7 @@ build_program_table(int fd, struct job_d - { - disk_blockptr_t* table; - int entries, component_header; -+ int is_secure; - int i; - int rc; - -@@ -1016,13 +1017,18 @@ build_program_table(int fd, struct job_d - component_header_ipl; - printf("\n"); - } -+ if (job->is_secure != SECURE_BOOT_UNDEFINED) -+ is_secure = job->is_secure; -+ else -+ is_secure = -+ job->data.menu.entry[i].is_secure; - rc = add_ipl_program(fd, - &job->data.menu.entry[i].data.ipl, - &table[job->data.menu.entry[i].pos], - verbose || job->command_line, - job->add_files, component_header, - info, &job->target, -- job->is_secure); -+ is_secure); - break; - case job_print_usage: - case job_print_version: ---- a/zipl/src/job.c -+++ b/zipl/src/job.c -@@ -119,6 +119,7 @@ get_command_line(int argc, char* argv[], - memset((void *) &cmdline, 0, sizeof(struct command_line)); - cmdline.type = section_invalid; - is_keyword = 0; -+ cmdline.is_secure = SECURE_BOOT_UNDEFINED; - /* Process options */ - do { - opt = getopt_long(argc, argv, option_string, options, NULL); -@@ -1055,6 +1056,21 @@ check_job_mvdump_data(struct job_mvdump_ - return 0; - } - -+static int -+check_secure_boot(struct job_data *job) -+{ -+ switch (job->is_secure) { -+ case SECURE_BOOT_UNDEFINED: -+ case SECURE_BOOT_DISABLED: -+ case SECURE_BOOT_ENABLED: -+ case SECURE_BOOT_AUTO: -+ return 0; -+ default: -+ error_reason("Invalid secure boot setting '%d'", -+ job->is_secure); -+ return -1; -+ } -+} - - static int - check_job_data(struct job_data* job) -@@ -1099,6 +1115,8 @@ check_job_data(struct job_data* job) - case job_mvdump: - rc = check_job_mvdump_data(&job->data.mvdump, job->name); - } -+ if (!rc) -+ rc = check_secure_boot(job); - return rc; - } - -@@ -1594,6 +1612,7 @@ get_menu_job(struct scan_token* scan, ch - sizeof(struct job_menu_entry) * job->data.menu.num); - /* Fill in data */ - current = 0; -+ job->data.menu.entry->is_secure = SECURE_BOOT_UNDEFINED; - for (i=index+1; (scan[i].id != scan_id_empty) && - (scan[i].id != scan_id_section_heading) && - (scan[i].id != scan_id_menu_heading); i++) { -@@ -1625,6 +1644,7 @@ get_menu_job(struct scan_token* scan, ch - if (temp_job == NULL) - return -1; - memset((void *) temp_job, 0, sizeof(struct job_data)); -+ temp_job->is_secure = SECURE_BOOT_UNDEFINED; - rc = get_job_from_section_data(data, temp_job, - job->data.menu.entry[current].name); - if (rc) { -@@ -1637,6 +1657,8 @@ get_menu_job(struct scan_token* scan, ch - job->data.menu.entry[current].id = job_ipl; - job->data.menu.entry[current].data.ipl = - temp_job->data.ipl; -+ job->data.menu.entry[current].is_secure = -+ temp_job->is_secure; - memset((void *) &temp_job->data.ipl, 0, - sizeof(struct job_ipl_data)); - break; -@@ -1874,6 +1896,7 @@ job_get(int argc, char* argv[], struct j - job->add_files = cmdline.add_files; - job->data.mvdump.force = cmdline.force; - job->dry_run = cmdline.dry_run; -+ job->is_secure = SECURE_BOOT_UNDEFINED; - /* Get job data from user input */ - if (cmdline.help) { - job->command_line = 1; -@@ -1892,10 +1915,10 @@ job_get(int argc, char* argv[], struct j - job_free(job); - return rc; - } -- if (cmdline.is_secure) -+ if (cmdline.is_secure != SECURE_BOOT_UNDEFINED) - job->is_secure = cmdline.is_secure; -- else -- job->is_secure = job->is_secure ? : SECURE_BOOT_AUTO; -+ else if (job->id != job_menu && job->is_secure == SECURE_BOOT_UNDEFINED) -+ job->is_secure = SECURE_BOOT_AUTO; - - /* Check job data for validity */ - rc = check_job_data(job); diff --git a/s390-tools-sles15sp2-03-zipl-libc-Replace-sprintf-with-snprintf.patch b/s390-tools-sles15sp2-03-zipl-libc-Replace-sprintf-with-snprintf.patch deleted file mode 100644 index d6b9a30..0000000 --- a/s390-tools-sles15sp2-03-zipl-libc-Replace-sprintf-with-snprintf.patch +++ /dev/null @@ -1,236 +0,0 @@ -Subject: [PATCH] [BZ 184060] zipl/libc: Replace sprintf with snprintf -From: Philipp Rudo - -Description: zipl/libc: Fix potential buffer overflow in printf -Symptom: Crash of the zipl boot loader during boot. -Problem: The zipl boot loaders have their own minimalistic libc - implementation. In it printf and sprintf use vsprintf for string - formatting. Per definition vsprintf assumes that the buffer it - writes to is large enough to contain the formatted string and - performs no size checks. This is problematic for the boot - loaders because the buffer they use are often allocated on the - stack. Thus even small changes to the string format can - potentially cause buffer overflows on the stack. -Solution: Implement vsnprintf and make use of it. -Reproduction: Use printf to print a string with >81 characters (exact number - depends on the stack layout/compiler used). -Upstream-ID: f7430027b41d5ad6220e962a179c2a5213330a44 -Problem-ID: 184060 - -Upstream-Description: - - zipl/libc: Replace sprintf with snprintf - - The use of sprintf can easily result in buffer overflows as it assumes - that the buffer it writes to is large enough to contain the formatted - string. Thus replace sprintf by snprintf and update its users. - - This removes the last user of vsprintf. Thus also remove vsprintf and - its dependencies. - - Signed-off-by: Philipp Rudo - Reviewed-by: Marc Hartmayer - Reviewed-by: Stefan Haberland - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Philipp Rudo ---- - zipl/boot/libc.c | 132 +------------------------------------------------- - zipl/boot/libc.h | 3 - - zipl/boot/menu.c | 2 - zipl/boot/tape2dump.c | 2 - 4 files changed, 6 insertions(+), 133 deletions(-) - ---- a/zipl/boot/libc.c -+++ b/zipl/boot/libc.c -@@ -126,81 +126,6 @@ int strncmp(const char *s1, const char * - } - - /* -- * Convert number to string -- * -- * Parameters: -- * -- * - buf: Output buffer -- * - base: Base used for formatting (e.g. 10 or 16) -- * - val: Number to format -- * - zero: If > 0, fill with leading zeros, otherwise use blanks -- * - count: Minimum number of characters used for output string -- */ --static int num_to_str(char *buf, int base, unsigned long val, int zero, -- unsigned long count) --{ -- static const char conv_vec[] = {'0', '1', '2', '3', '4', '5', '6', '7', -- '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; -- unsigned long num = 0, val_work = val, in_number = 1; -- int i; -- -- /* Count number of characters needed for number */ -- do { -- num++; -- val_work /= base; -- } while (val_work); -- /* Real character number overwrites count */ -- if (count < num) -- count = num; -- /* Format number */ -- for (i = count - 1; i >= 0; i--) { -- if (in_number) { -- buf[i] = conv_vec[val % base]; -- val /= base; -- in_number = val ? 1 : 0; -- } else { -- buf[i] = zero ? '0' : ' '; -- } -- } -- buf[count] = 0; -- return count; --} -- --/* -- * Convert string to string with indentation -- */ --static int str_to_str(char *buf, const char *str, unsigned long count) --{ -- unsigned long size; -- -- size = strlen(str); -- if (count < size) -- count = size; -- else -- memset(buf, ' ', count - size); -- strcpy(buf + (count - size), str); -- return count; --} -- --/* -- * Convert string to number with given base -- */ --unsigned long strtoul(const char *nptr, char **endptr, int base) --{ -- unsigned long val = 0; -- -- while (isdigit(*nptr)) { -- if (val != 0) -- val *= base; -- val += *nptr - '0'; -- nptr++; -- } -- if (endptr) -- *endptr = (char *) nptr; -- return val; --} -- --/* - * Convert ebcdic string to number with given base - */ - unsigned long ebcstrtoul(char *nptr, char **endptr, int base) -@@ -467,65 +392,14 @@ static int vsnprintf(char *buf, unsigned - } - - /* -- * Convert string to number with given base -- */ --static int sprintf_fmt(char type, char *buf, unsigned long val, int zero, -- int count) --{ -- switch (type) { -- case 's': -- return str_to_str(buf, (const char *) val, count); -- case 'x': -- return num_to_str(buf, 16, val, zero, count); -- case 'u': -- return num_to_str(buf, 10, val, zero, count); -- default: -- libc_stop(EINTERNAL); -- } -- return 0; --} -- --/* -- * Print formated string (va version) -- */ --static void vsprintf(char *str, const char *fmt, va_list va) --{ -- unsigned long val, zero, count; -- char *fmt_next; -- -- do { -- if (*fmt == '%') { -- fmt++; -- if (*fmt == '0') { -- zero = 1; -- fmt++; -- } else { -- zero = 0; -- } -- /* No number found by strtoul: count=0 fmt_next=fmt */ -- count = strtoul(fmt, &fmt_next, 10); -- fmt = fmt_next; -- if (*fmt == 'l') -- fmt++; -- val = va_arg(va, unsigned long); -- str += sprintf_fmt(*fmt, str, val, zero, count); -- fmt++; -- } else { -- *str++ = *fmt++; -- } -- } while (*fmt); -- *str = 0; --} -- --/* -- * Write formated string to string -+ * Write formatted string to buffer - */ --void sprintf(char *str, const char *fmt, ...) -+void snprintf(char *buf, unsigned long size, const char *fmt, ...) - { - va_list va; - - va_start(va, fmt); -- vsprintf(str, fmt, va); -+ vsnprintf(buf, size, fmt, va); - va_end(va); - } - ---- a/zipl/boot/libc.h -+++ b/zipl/boot/libc.h -@@ -47,13 +47,12 @@ typedef unsigned short uint16_t; - typedef unsigned char uint8_t; - - void printf(const char *, ...); --void sprintf(char *, const char *, ...); -+void snprintf(char *buf, unsigned long size, const char *fmt, ...); - void *memcpy(void *, const void *, unsigned long); - void *memmove(void *, const void *, unsigned long); - void *memset(void *, int c, unsigned long); - char *strcat(char *, const char *); - int strncmp(const char *, const char *, unsigned long); --unsigned long strtoul(const char *, char **, int); - unsigned long ebcstrtoul(char *, char **, int); - int strlen(const char *); - char *strcpy(char *, const char *); ---- a/zipl/boot/menu.c -+++ b/zipl/boot/menu.c -@@ -189,7 +189,7 @@ boot: - (void *)&__stage2_params + TEXT_OFFSET)); - - /* append 'BOOT_IMAGE=' to parmline */ -- sprintf(endstring, " BOOT_IMAGE=%u", value); -+ snprintf(endstring, sizeof(endstring), " BOOT_IMAGE=%u", value); - if ((strlen(cmd_line_extra) + strlen(endstring)) < COMMAND_LINE_SIZE) - strcat(cmd_line_extra, endstring); - ---- a/zipl/boot/tape2dump.c -+++ b/zipl/boot/tape2dump.c -@@ -186,7 +186,7 @@ static void progress_print_disp(unsigned - - if (addr % (1024 * 1024 * 16) != 0) - return; -- sprintf(msg, "%08u", addr >> 20); -+ snprintf(msg, sizeof(msg), "%08u", addr >> 20); - ccw_load_display(msg); - } - diff --git a/s390-tools-sles15sp2-03-zipl-remove-some-useless-__packed___-attributes.patch b/s390-tools-sles15sp2-03-zipl-remove-some-useless-__packed___-attributes.patch deleted file mode 100644 index 4deac13..0000000 --- a/s390-tools-sles15sp2-03-zipl-remove-some-useless-__packed___-attributes.patch +++ /dev/null @@ -1,143 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] zipl: remove some useless __packed___ attributes -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: 2227bb8330aea1368ba234ae6f24fe0b5779d67d -Problem-ID: VS1804 - -Upstream-Description: - - zipl: remove some useless __packed___ attributes - - The __packed__ attribute is not needed for these structures as they - don't need any padding to meet the size and alignment constraints - defined in the Linux for zSeries ABI. - - Reported by GCC 9.2.1 when building with '-Waddress-of-packed-member'. - - stage3.c: In function 'is_verified_address': - stage3.c:241:26: warning: taking address of packed member of 'struct ipl_rb_components' may result in an unaligned pointer value [-Waddress-of-packed-member] - 241 | for_each_rb_entry(comp, comps) { - | ^~~~~ - stage3.c:18:15: note: in definition of macro 'for_each_rb_entry' - 18 | for (entry = rb->entries; \ - | ^~ - CC zipl/boot/kdump3.o - CC zipl/boot/sclp_stage3.o - sclp_stage3.c: In function '__sclp_hsa_copy': - sclp_stage3.c:75:34: warning: converting a packed 'struct sdias_sccb' pointer (alignment 1) to a 'struct read_sccb' pointer (alignment 4096) may result in an unaligned pointer value [-Waddress-of-packed-member] - 75 | if (sclp_hsa_copy_wait((struct read_sccb *)sccb)) - | ^~~~~~~~~ - In file included from sclp_stage3.c:13: - sclp_stage3.h:43:8: note: defined here - 43 | struct sdias_sccb { - | ^~~~~~~~~~ - In file included from sclp_stage3.c:12: - sclp.h:149:8: note: defined here - 149 | struct read_sccb { - | ^~~~~~~~~ - sclp_stage3.c: In function 'sclp_hsa_get_size': - sclp_stage3.c:126:34: warning: converting a packed 'struct sdias_sccb' pointer (alignment 1) to a 'struct read_sccb' pointer (alignment 4096) may result in an unaligned pointer value [-Waddress-of-packed-member] - 126 | if (sclp_hsa_copy_wait((struct read_sccb *)sccb)) - | ^~~~~~~~~ - In file included from sclp_stage3.c:13: - sclp_stage3.h:43:8: note: defined here - 43 | struct sdias_sccb { - | ^~~~~~~~~~ - In file included from sclp_stage3.c:12: - sclp.h:149:8: note: defined here - 149 | struct read_sccb { - | ^~~~~~~~~ - - Signed-off-by: Marc Hartmayer - Reviewed-by: Stefan Haberland - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - zipl/boot/sclp.h | 6 ++++-- - zipl/boot/sclp_stage3.h | 3 ++- - zipl/boot/stage3.h | 6 ++++-- - 3 files changed, 10 insertions(+), 5 deletions(-) - ---- a/zipl/boot/sclp.h -+++ b/zipl/boot/sclp.h -@@ -53,19 +53,21 @@ struct gds_subvector { - uint8_t key; - } __packed; - -+/* Structure must not have any padding */ - struct sccb_header { - uint16_t length; - uint8_t function_code; - uint8_t control_mask[3]; - uint16_t response_code; --} __packed; -+}; - -+/* Structure must not have any padding */ - struct evbuf_header { - uint16_t length; - uint8_t type; - uint8_t flags; - uint16_t _reserved; --} __packed; -+}; - - struct mto { - uint16_t length; ---- a/zipl/boot/sclp_stage3.h -+++ b/zipl/boot/sclp_stage3.h -@@ -40,10 +40,11 @@ struct sdias_evbuf { - uint16_t dbs; - } __packed; - -+/* Structure must not have any padding */ - struct sdias_sccb { - struct sccb_header header; - struct sdias_evbuf evbuf; --} __packed; -+}; - - - int sclp_hsa_copy(void *, unsigned long, unsigned long); ---- a/zipl/boot/stage3.h -+++ b/zipl/boot/stage3.h -@@ -124,11 +124,12 @@ struct ipl_rl_hdr { - } __packed; - - /* IPL Report Block header */ -+/* Structure must not have any padding */ - struct ipl_rb_hdr { - uint32_t len; - uint8_t rbt; - uint8_t reserved1[11]; --} __packed; -+}; - - /* IPL Report Block types */ - enum ipl_rbt { -@@ -162,12 +163,13 @@ struct ipl_rb_component_entry { - #define IPL_RB_COMPONENT_FLAG_SIGNED 0x80 - #define IPL_RB_COMPONENT_FLAG_VERIFIED 0x40 - -+/* Structure must not have any padding */ - struct ipl_rb_components { - uint32_t len; - uint8_t rbt; - uint8_t reserved1[11]; - struct ipl_rb_component_entry entries[]; --} __packed; -+}; - - extern unsigned long long _parm_addr; /* address of parmline */ - extern unsigned long long _initrd_addr; /* address of initrd */ diff --git a/s390-tools-sles15sp2-03-zkey-Add-utility-function-to-get-the-serial-number-o.patch b/s390-tools-sles15sp2-03-zkey-Add-utility-function-to-get-the-serial-number-o.patch deleted file mode 100644 index af6965a..0000000 --- a/s390-tools-sles15sp2-03-zkey-Add-utility-function-to-get-the-serial-number-o.patch +++ /dev/null @@ -1,112 +0,0 @@ -Subject: zkey: Add utility function to get the serial number of a crypto card -From: Ingo Franzki - -Summary: zkey: check master key consistency -Description: Enhances the zkey tool to perform a cross check whether the - APQNs associated with a secure key have the same master key. - Display the master key verification pattern of a secure key - during the zkey validate command. This helps to better identify - which master key is the correct one, in case of master key - inconsistencies. - Select an appropriate APQN when re-enciphering a secure key. - Re-enciphering is done using the CCA host library. Special - handling is required to select an appropriate APQN for use with - the CCA host library. -Upstream-ID: a84d1c5d58fa4a0c9e087357eec009803ea06ef2 -Problem-ID: SEC1916 - -Upstream-Description: - - zkey: Add utility function to get the serial number of a crypto card - - With recent changes in the zcrypt device driver, the serial number of - a crypto card can be obtained by reading the sysfs attribute 'serialnr' - of a crypto card device of type CCA-Coprocessor. The sysfs attribute - can be found under '/sys/devices/ap/cardnn/', where nn specifies the - card number in hex. - - Signed-off-by: Ingo Franzki - Reviewed-by: Harald Freudenberger - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/utils.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ - zkey/utils.h | 2 ++ - 2 files changed, 54 insertions(+) - ---- a/zkey/utils.c -+++ b/zkey/utils.c -@@ -22,6 +22,11 @@ - - #include "utils.h" - -+#define pr_verbose(verbose, fmt...) do { \ -+ if (verbose) \ -+ warnx(fmt); \ -+ } while (0) -+ - /** - * Checks if the specified card is of type CCA and is online - * -@@ -107,3 +112,50 @@ out: - return rc; - } - -+/** -+ * Gets the 8 character ASCII serial number string of an card from the sysfs. -+ * -+ * @param[in] card card number -+ * @param[out] serialnr Result buffer -+ * @param[in] verbose if true, verbose messages are printed -+ * -+ * @returns 0 if the serial number was returned. -ENODEV if the APQN is not -+ * available, or is not a CCA card. -ENOTSUP if the serialnr sysfs -+ * attribute is not available, because the zcrypt kernel module is -+ * on an older level. -+ */ -+int sysfs_get_serialnr(int card, char serialnr[9], bool verbose) -+{ -+ char *dev_path; -+ int rc = 0; -+ -+ if (serialnr == NULL) -+ return -EINVAL; -+ -+ if (sysfs_is_card_online(card) != 1) -+ return -ENODEV; -+ -+ dev_path = util_path_sysfs("bus/ap/devices/card%02x", card); -+ if (!util_path_is_dir(dev_path)) { -+ rc = -ENODEV; -+ goto out; -+ } -+ if (util_file_read_line(serialnr, 9, "%s/serialnr", dev_path) != 0) { -+ rc = -ENOTSUP; -+ goto out; -+ } -+ -+ if (strlen(serialnr) == 0) { -+ rc = -ENODEV; -+ goto out; -+ } -+ -+ pr_verbose(verbose, "Serial number of %02x: %s", card, serialnr); -+out: -+ if (rc != 0) -+ pr_verbose(verbose, "Failed to get serial number for " -+ "%02x: %s", card, strerror(-rc)); -+ -+ free(dev_path); -+ return rc; -+} ---- a/zkey/utils.h -+++ b/zkey/utils.h -@@ -18,4 +18,6 @@ int sysfs_is_card_online(int card); - - int sysfs_is_apqn_online(int card, int domain); - -+int sysfs_get_serialnr(int card, char serialnr[9], bool verbose); -+ - #endif diff --git a/s390-tools-sles15sp2-03-zpcitctl-Exit-on-error-in-sysfs_report_error.patch b/s390-tools-sles15sp2-03-zpcitctl-Exit-on-error-in-sysfs_report_error.patch deleted file mode 100644 index 6580a79..0000000 --- a/s390-tools-sles15sp2-03-zpcitctl-Exit-on-error-in-sysfs_report_error.patch +++ /dev/null @@ -1,119 +0,0 @@ -Subject: [PATCH] [BZ 184174] zpcitctl: Exit on error in sysfs_report_error -From: Jan Hoeppner - -Description: zpcictl: Initiate recover after reset -Symptom: If a PCI function is reset using zpcictl --reset, the function - is in an error state. -Problem: zpcictl --reset only issues a SCLP reset and leaves the PCI - function in an error state. -Solution: Initiate an OS level recovery by calling - /sys/bus/devices//recover after the SCLP reset. -Reproduction: Call zpcictl --reset - Under z/VM check the state of the function with 'vmcp q pcif' -Upstream-ID: 304c3d8086bc2a9230c5404f9c9fec72de08d229 -Problem-ID: 184174 - -Upstream-Description: - - zpcitctl: Exit on error in sysfs_report_error - - This also makes sure that we don't try to write to the - /sys/bus/pci/device//recover attribute if reset failed. - - Signed-off-by: Niklas Schnelle - Reviewed-by: Jan Hoeppner - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Jan Hoeppner ---- - zpcictl/zpcictl.c | 55 +++++++++++++++++++++++++++++++++++++----------------- - 1 file changed, 38 insertions(+), 17 deletions(-) - ---- a/zpcictl/zpcictl.c -+++ b/zpcictl/zpcictl.c -@@ -97,6 +97,35 @@ static void fopen_err(char *path) - exit(EXIT_FAILURE); - } - -+static void fclose_err(char *path) -+{ -+ if (errno == EIO || errno == EOPNOTSUPP) -+ warnx("Unsupported operation: %s: %s", path, strerror(errno)); -+ else -+ warnx("Could not close file: %s: %s", path, strerror(errno)); -+ free(path); -+ exit(EXIT_FAILURE); -+ -+} -+ -+static void fread_err(FILE *fp, char *path) -+{ -+ warnx("Could not read file: %s: %s", path, strerror(errno)); -+ if (fclose(fp)) -+ fclose_err(path); -+ free(path); -+ exit(EXIT_FAILURE); -+} -+ -+static void fwrite_err(FILE *fp, char *path) -+{ -+ warnx("Could not write to file: %s: %s", path, strerror(errno)); -+ if (fclose(fp)) -+ fclose_err(path); -+ free(path); -+ exit(EXIT_FAILURE); -+} -+ - #define READ_CHUNK_SIZE 512 - - static char *collect_smart_data(struct zpci_device *pdev) -@@ -152,12 +181,10 @@ static unsigned int sysfs_read_value(str - if (!fp) - fopen_err(path); - if (fscanf(fp, "%x", &val) != 1) { -- fclose(fp); -- warnx("Could not read file %s: %s", path, strerror(errno)); -- free(path); -- exit(EXIT_FAILURE); -+ fread_err(fp, path); - } -- fclose(fp); -+ if (fclose(fp)) -+ fclose_err(path); - free(path); - - return val; -@@ -174,12 +201,10 @@ static void sysfs_write_value(struct zpc - if (!fp) - fopen_err(path); - if (fprintf(fp, "%x", val) < 0) { -- fclose(fp); -- warnx("Could not write to file %s: %s", path, strerror(errno)); -- free(path); -- exit(EXIT_FAILURE); -+ fwrite_err(fp, path); - } -- fclose(fp); -+ if (fclose(fp)) -+ fclose_err(path); - free(path); - } - -@@ -196,13 +221,9 @@ static void sysfs_report_error(struct zp - if (!fp) - fopen_err(path); - if (fwrite(report, 1, r_size, fp) != r_size) -- warnx("Could not write to file: %s: %s", path, strerror(errno)); -- if (fclose(fp)) { -- if (errno == EIO || errno == EOPNOTSUPP) -- warnx("Unsupported operation: %s: %s", path, strerror(errno)); -- else -- warnx("Could not close file: %s: %s", path, strerror(errno)); -- } -+ fwrite_err(fp, path); -+ if (fclose(fp)) -+ fclose_err(path); - free(path); - } - diff --git a/s390-tools-sles15sp2-04-zipl-Fix-entry-point-for-stand-alone-kdump.patch b/s390-tools-sles15sp2-04-zipl-Fix-entry-point-for-stand-alone-kdump.patch deleted file mode 100644 index b7522c7..0000000 --- a/s390-tools-sles15sp2-04-zipl-Fix-entry-point-for-stand-alone-kdump.patch +++ /dev/null @@ -1,95 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] zipl: Fix entry point for stand-alone kdump -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: abe0ba7412f4398973235497754b05a199aec818 -Problem-ID: VS1804 - -Upstream-Description: - - zipl: Fix entry point for stand-alone kdump - - Currently zipl doesn't differentiate between the load address and the - entry point of an image, causing stage3 to strip away the entry point at - 0x10000 for stand-alone kdump. This breaks the kdump kernel as it jumps - to 0x10000 after the special handling needed for kdump has been - performed. - - Fix this by differentiating between the load address and the entry point - of an image. - - Fixes: d142fbd5 ("zipl: Do not strip kernel image IPL header") - Signed-off-by: Philipp Rudo - Reviewed-by: Stefan Haberland - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - zipl/include/boot.h | 4 ++-- - zipl/src/boot.c | 10 +++++----- - zipl/src/bootmap.c | 2 +- - 3 files changed, 8 insertions(+), 8 deletions(-) - ---- a/zipl/include/boot.h -+++ b/zipl/include/boot.h -@@ -310,8 +310,8 @@ int boot_init_fba_stage1b(struct boot_fb - int boot_get_eckd_stage2(void** data, size_t* size, struct job_data* job); - int boot_get_stage3_parms(void **buffer, size_t *bytecount, address_t parm_addr, - address_t initrd_addr, size_t initrd_len, -- address_t load_addr, int extra_parm, uint16_t flags, -- size_t image_len); -+ address_t entry, int extra_parm, uint16_t flags, -+ address_t image_addr, size_t image_len); - int boot_get_tape_ipl(void** data, size_t* size, address_t parm_addr, - address_t initrd_addr, address_t image_addr); - int boot_get_tape_dump(void** data, size_t* size, uint64_t mem); ---- a/zipl/src/boot.c -+++ b/zipl/src/boot.c -@@ -79,14 +79,14 @@ boot_check_data(void) - int - boot_get_stage3_parms(void **buffer, size_t *bytecount, address_t parm_addr, - address_t initrd_addr, size_t initrd_len, -- address_t image_addr, int extra_parm, uint16_t flags, -- size_t image_len) -+ address_t entry, int extra_parm, uint16_t flags, -+ address_t image_addr, size_t image_len) - { - struct boot_stage3_params params; - void* data; - -- if (image_addr != (image_addr & PSW_ADDRESS_MASK)) { -- error_reason("Kernel image load address to high (31 bit " -+ if (entry != (entry & PSW_ADDRESS_MASK)) { -+ error_reason("Kernel image entry point to high (31 bit " - "addressing mode)"); - return -1; - } -@@ -99,7 +99,7 @@ boot_get_stage3_parms(void **buffer, siz - params.parm_addr = (uint64_t) parm_addr; - params.initrd_addr = (uint64_t) initrd_addr; - params.initrd_len = (uint64_t) initrd_len; -- params.load_psw = (uint64_t)(image_addr | PSW_LOAD); -+ params.load_psw = (uint64_t)(entry | PSW_LOAD); - params.extra_parm = (uint64_t) extra_parm; - params.flags = flags; - params.image_len = (uint64_t) image_len; ---- a/zipl/src/bootmap.c -+++ b/zipl/src/bootmap.c -@@ -646,7 +646,7 @@ add_ipl_program(int fd, struct job_ipl_d - ipl->is_kdump ? ipl->image_addr + 0x10 : - ipl->image_addr, - (info->type == disk_type_scsi) ? 0 : 1, -- flags, image_size); -+ flags, ipl->image_addr, image_size); - if (rc) { - free(table); - return rc; diff --git a/s390-tools-sles15sp2-04-zipl-fix-zipl.conf-man-page-example-for-secure-boot.patch b/s390-tools-sles15sp2-04-zipl-fix-zipl.conf-man-page-example-for-secure-boot.patch deleted file mode 100644 index 2582941..0000000 --- a/s390-tools-sles15sp2-04-zipl-fix-zipl.conf-man-page-example-for-secure-boot.patch +++ /dev/null @@ -1,70 +0,0 @@ -Subject: [PATCH] [BZ 184396] zipl: fix zipl.conf man page example for secure boot -From: Stefan Haberland - -Description: zipl: fix secure boot config handling -Symptom: The config file parsing for secure boot worked not as - it was expected to be. For example a config section - setting was not evaluated properly. - It is not possible to specify command line option -S - without other options. - Additionally the man page showed an invalid example. -Problem: The config file parsing was not implemented properly. -Solution: The hierarchy of the secure boot settings in the config - file is: - defaultboot > menu > section - Allow that --secure or -S is specified on command line - without the need to allow all options on the command - line. Also ensure that the command line option - overrules the config option and correctly ensure that - secure boot is only set for SCSI devices. - Fix man page example. -Reproduction: Run zipl with a secure= setting in a configuration - section or specify -S on command line. -Upstream-ID: 299fd2b7729f35c6fe3be18964f7e5e6a365f94d -Problem-ID: 184396 - -Upstream-Description: - - zipl: fix zipl.conf man page example for secure boot - - The secure= option is not supported in the defaultboot section when a - menu is used. It should be placed in the menu section in this case. - - Signed-off-by: Stefan Haberland - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Stefan Haberland ---- - zipl/man/zipl.conf.5 | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/zipl/man/zipl.conf.5 -+++ b/zipl/man/zipl.conf.5 -@@ -82,8 +82,6 @@ below). - .br - defaultmenu = menu1 - .br --secure = auto --.br - - [linux] - .br -@@ -117,6 +115,8 @@ prompt = 1 - .br - timeout = 0 - .br -+secure = auto -+.br - .PP - - .B BootLoaderSpec configuration files -@@ -522,7 +522,7 @@ non-default memory location. - .B secure - = - .IR auto / 1 / 0 --(configuration only) -+(configuration and menu) - .IP - .B Configuration section: - .br diff --git a/s390-tools-sles15sp2-04-zipl-libc-Indicate-truncated-lines-in-printf-with.patch b/s390-tools-sles15sp2-04-zipl-libc-Indicate-truncated-lines-in-printf-with.patch deleted file mode 100644 index 608931a..0000000 --- a/s390-tools-sles15sp2-04-zipl-libc-Indicate-truncated-lines-in-printf-with.patch +++ /dev/null @@ -1,82 +0,0 @@ -Subject: [PATCH] [BZ 184060] zipl/libc: Indicate truncated lines in printf with '...' -From: Philipp Rudo - -Description: zipl/libc: Fix potential buffer overflow in printf -Symptom: Crash of the zipl boot loader during boot. -Problem: The zipl boot loaders have their own minimalistic libc - implementation. In it printf and sprintf use vsprintf for string - formatting. Per definition vsprintf assumes that the buffer it - writes to is large enough to contain the formatted string and - performs no size checks. This is problematic for the boot - loaders because the buffer they use are often allocated on the - stack. Thus even small changes to the string format can - potentially cause buffer overflows on the stack. -Solution: Implement vsnprintf and make use of it. -Reproduction: Use printf to print a string with >81 characters (exact number - depends on the stack layout/compiler used). -Upstream-ID: 36fed0e6c6590631c4ce1707c8fe3c3397bcce4d -Problem-ID: 184060 - -Upstream-Description: - - zipl/libc: Indicate truncated lines in printf with '...' - - Append '...' to lines exceeding the maximum line length instead of - silently truncating them. - - Suggested-by: Marc Hartmayer - Signed-off-by: Philipp Rudo - Reviewed-by: Marc Hartmayer - Reviewed-by: Stefan Haberland - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Philipp Rudo ---- - zipl/boot/libc.c | 10 ++++++++-- - zipl/boot/libc.h | 1 + - zipl/boot/menu.h | 1 - - 3 files changed, 9 insertions(+), 3 deletions(-) - ---- a/zipl/boot/libc.c -+++ b/zipl/boot/libc.c -@@ -408,11 +408,17 @@ void snprintf(char *buf, unsigned long s - */ - void printf(const char *fmt, ...) - { -- char buf[81]; -+ char buf[LINE_LENGTH + 1]; -+ int len; - va_list va; - - va_start(va, fmt); -- vsnprintf(buf, sizeof(buf), fmt, va); -+ len = vsnprintf(buf, sizeof(buf), fmt, va); -+ if (len > LINE_LENGTH) { -+ buf[LINE_LENGTH - 1] = '.'; -+ buf[LINE_LENGTH - 2] = '.'; -+ buf[LINE_LENGTH - 3] = '.'; -+ } - sclp_print(buf); - va_end(va); - } ---- a/zipl/boot/libc.h -+++ b/zipl/boot/libc.h -@@ -40,6 +40,7 @@ - #define ENOTTY 25 /* Not a typewriter */ - - #define MIB (1024ULL * 1024) -+#define LINE_LENGTH 80 /* max line length printed by printf */ - - typedef unsigned long long uint64_t; - typedef unsigned int uint32_t; ---- a/zipl/boot/menu.h -+++ b/zipl/boot/menu.h -@@ -20,7 +20,6 @@ - /* max command line length */ - #define COMMAND_LINE_SIZE 896 - #define BOOT_MENU_ENTRIES 63 --#define LINE_LENGTH 80 - #define PARAM_SIZE 8 - #define TEXT_OFFSET 4 - diff --git a/s390-tools-sles15sp2-04-zkey-Add-utility-function-to-get-the-mkvp-of-a-crypt.patch b/s390-tools-sles15sp2-04-zkey-Add-utility-function-to-get-the-mkvp-of-a-crypt.patch deleted file mode 100644 index b04274d..0000000 --- a/s390-tools-sles15sp2-04-zkey-Add-utility-function-to-get-the-mkvp-of-a-crypt.patch +++ /dev/null @@ -1,213 +0,0 @@ -Subject: zkey: Add utility function to get the mkvp of a crypto card -From: Ingo Franzki - -Summary: zkey: check master key consistency -Description: Enhances the zkey tool to perform a cross check whether the - APQNs associated with a secure key have the same master key. - Display the master key verification pattern of a secure key - during the zkey validate command. This helps to better identify - which master key is the correct one, in case of master key - inconsistencies. - Select an appropriate APQN when re-enciphering a secure key. - Re-enciphering is done using the CCA host library. Special - handling is required to select an appropriate APQN for use with - the CCA host library. -Upstream-ID: bf8872e94a2dc4810df388d1539560b00b1acf6e -Problem-ID: SEC1916 - -Upstream-Description: - - zkey: Add utility function to get the mkvp of a crypto card - - With recent changes in the zcrypt device driver, the master key verifi- - cation patterns of the AES master key of am APQN can be obtained by - reading the sysfs attribute 'mkvps' of an APQN device of type CCA- - Coprocessor. The sysfs attribute can be found under - '/sys/devices/ap/cardnn/nn.mmmm/', where nn specifies the card number - in hex, and mmmm specifies the domain number on hex. - - Signed-off-by: Ingo Franzki - Reviewed-by: Harald Freudenberger - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/utils.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - zkey/utils.h | 21 ++++++++ - 2 files changed, 161 insertions(+) - ---- a/zkey/utils.c -+++ b/zkey/utils.c -@@ -159,3 +159,143 @@ out: - free(dev_path); - return rc; - } -+ -+static int parse_mk_info(char *line, struct mk_info *mk_info) -+{ -+ struct mk_info_reg *mk_reg; -+ char *save; -+ char *tok; -+ -+ tok = strtok_r(line, " ", &save); -+ if (tok == NULL) -+ return -EIO; -+ -+ if (strcasecmp(tok, "AES") != 0) -+ return 0; -+ -+ tok = strtok_r(NULL, " ", &save); -+ if (tok == NULL) -+ return -EIO; -+ -+ if (strcasecmp(tok, "NEW:") == 0) -+ mk_reg = &mk_info->new_mk; -+ else if (strcasecmp(tok, "CUR:") == 0) -+ mk_reg = &mk_info->cur_mk; -+ else if (strcasecmp(tok, "OLD:") == 0) -+ mk_reg = &mk_info->old_mk; -+ else -+ return -EIO; -+ -+ tok = strtok_r(NULL, " ", &save); -+ if (tok == NULL) -+ return -EIO; -+ -+ if (strcasecmp(tok, "empty") == 0) -+ mk_reg->mk_state = MK_STATE_EMPTY; -+ else if (strcasecmp(tok, "partial") == 0) -+ mk_reg->mk_state = MK_STATE_PARTIAL; -+ else if (strcasecmp(tok, "full") == 0) -+ mk_reg->mk_state = MK_STATE_FULL; -+ else if (strcasecmp(tok, "valid") == 0) -+ mk_reg->mk_state = MK_STATE_VALID; -+ else if (strcasecmp(tok, "invalid") == 0) -+ mk_reg->mk_state = MK_STATE_INVALID; -+ else -+ mk_reg->mk_state = MK_STATE_UNKNOWN; -+ -+ tok = strtok_r(NULL, " ", &save); -+ if (tok == NULL) -+ return -EIO; -+ -+ if (sscanf(tok, "%llx", &mk_reg->mkvp) != 1) -+ return -EIO; -+ -+ return 0; -+} -+ -+/** -+ * Gets the master key states and verification patterns of an APQN from the -+ * sysfs. -+ * -+ * @param[in] card card number -+ * @param[in] domain the domain -+ * @param[out] mk_info structure is filled on return with master key infos -+ * @param[in] verbose if true, verbose messages are printed -+ * -+ * @returns 0 if the master key info was returned. -ENODEV if the APQN is not -+ * available, or is not a CCA card. -ENOTSUP if the mkvps sysfs -+ * attribute is not available, because the zcrypt kernel module is -+ * on an older level. -+ */ -+int sysfs_get_mkvps(int card, int domain, struct mk_info *mk_info, bool verbose) -+{ -+ char *dev_path; -+ char *p, *end; -+ char buf[100]; -+ int rc = 0; -+ FILE *fp; -+ -+ if (mk_info == NULL) -+ return -EINVAL; -+ -+ memset(mk_info, 0, sizeof(struct mk_info)); -+ mk_info->new_mk.mk_state = MK_STATE_UNKNOWN; -+ mk_info->cur_mk.mk_state = MK_STATE_UNKNOWN; -+ mk_info->old_mk.mk_state = MK_STATE_UNKNOWN; -+ -+ if (sysfs_is_apqn_online(card, domain) != 1) -+ return -ENODEV; -+ -+ dev_path = util_path_sysfs("bus/ap/devices/card%02x/%02x.%04x/mkvps", -+ card, card, domain); -+ if (!util_path_is_reg_file(dev_path)) { -+ rc = -ENOTSUP; -+ goto out; -+ } -+ -+ fp = fopen(dev_path, "r"); -+ if (fp == NULL) { -+ rc = -ENOTSUP; -+ goto out; -+ } -+ -+ /* -+ * Expected contents: -+ * AES NEW: -+ * AES CUR: -+ * AES OLD: -+ * with -+ * : 'empty' or 'partial' or 'full' -+ * , : 'valid' or 'invalid' -+ * , , new_mk.mk_state == MK_STATE_UNKNOWN && -+ mk_info->cur_mk.mk_state == MK_STATE_UNKNOWN && -+ mk_info->old_mk.mk_state == MK_STATE_UNKNOWN) -+ rc = -EIO; -+out: -+ if (rc != 0) -+ pr_verbose(verbose, "Failed to get mkvps for %02x.%04x: %s", -+ card, domain, strerror(-rc)); -+ -+ free(dev_path); -+ return rc; -+} ---- a/zkey/utils.h -+++ b/zkey/utils.h -@@ -20,4 +20,25 @@ int sysfs_is_apqn_online(int card, int d - - int sysfs_get_serialnr(int card, char serialnr[9], bool verbose); - -+#define MK_STATE_EMPTY 0 -+#define MK_STATE_PARTIAL 1 -+#define MK_STATE_FULL 2 -+#define MK_STATE_VALID 3 -+#define MK_STATE_INVALID 4 -+#define MK_STATE_UNKNOWN -1 -+ -+struct mk_info_reg { -+ int mk_state; -+ u64 mkvp; -+}; -+ -+struct mk_info { -+ struct mk_info_reg new_mk; -+ struct mk_info_reg cur_mk; -+ struct mk_info_reg old_mk; -+}; -+ -+int sysfs_get_mkvps(int card, int domain, struct mk_info *mk_info, -+ bool verbose); -+ - #endif diff --git a/s390-tools-sles15sp2-05-zipl-Fix-dependency-generation-in-zipl-boot.patch b/s390-tools-sles15sp2-05-zipl-Fix-dependency-generation-in-zipl-boot.patch deleted file mode 100644 index 754114a..0000000 --- a/s390-tools-sles15sp2-05-zipl-Fix-dependency-generation-in-zipl-boot.patch +++ /dev/null @@ -1,76 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] zipl: Fix dependency generation in zipl/boot -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: 121d5d80137f270e4828f457f717e9ab365f303b -Problem-ID: VS1804 - -Upstream-Description: - - zipl: Fix dependency generation in zipl/boot - - When adding new header from zipl/include to a .c file within zipl/boot - a compiler error appears - - stage3.c:16:10: fatal error: zipl.h: No such file or directory - #include "zipl.h" - ^~~~~~~~ - compilation terminated. - CC zipl/boot/stage3.o - - This is because the rule to generate dependencies (*.o.d) does not use - the CFLAGS_BOOT. Thus it cannot find the header and fails. Note this - only applies to the dependency generation, the actual build succeeds. - - To fix this rename the CFLAGS_BOOT to ALL_CFLAGS. Using ALL_CFLAGS - instead of e.g. ALL_CPPFLAGS is important to also overwrite flags given - on the commandline via OPT_FLAGS, e.g. - - make V=1 OPT_FLAGS="-D__FOO__" - - While at it also remove the unused and wrong '-D__ASSEMBLY__'. - - Fixes: 5a6605fe ("zipl: Ensure that boot loader CFLAGS are not overwritten") - Fixes: aa913b1e ("build process: Add automatic dependency generation") - Signed-off-by: Philipp Rudo - Reviewed-by: Stefan Haberland - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - zipl/boot/Makefile | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/zipl/boot/Makefile -+++ b/zipl/boot/Makefile -@@ -1,7 +1,7 @@ - # Common definitions - include ../../common.mak - --CFLAGS_BOOT = $(NO_PIE_CFLAGS) -Os -g -I../include -D__ASSEMBLY__ \ -+ALL_CFLAGS = $(NO_PIE_CFLAGS) -Os -g -I $(rootdir)/zipl/include \ - -DS390_TOOLS_RELEASE=$(S390_TOOLS_RELEASE) \ - -fno-builtin -ffreestanding -fno-asynchronous-unwind-tables \ - -fno-delete-null-pointer-checks \ -@@ -21,10 +21,10 @@ all: data.o data.h tape0.bin stage3.bin - %: %.S - - %.o: %.S -- $(CC) $(CFLAGS_BOOT) -c -o $@ $< -+ $(CC) $(ALL_CFLAGS) -c -o $@ $< - - %.o: %.c -- $(CC) $(CFLAGS_BOOT) -c -o $@ $< -+ $(CC) $(ALL_CFLAGS) -c -o $@ $< - - eckd2dump_sv.exec: \ - head.o stage2dump.o cio.o eckd2dump.o eckd2dump_sv.o \ diff --git a/s390-tools-sles15sp2-05-zkey-add-function-to-iterate-over-all-available-CCA-.patch b/s390-tools-sles15sp2-05-zkey-add-function-to-iterate-over-all-available-CCA-.patch deleted file mode 100644 index 7059fa4..0000000 --- a/s390-tools-sles15sp2-05-zkey-add-function-to-iterate-over-all-available-CCA-.patch +++ /dev/null @@ -1,197 +0,0 @@ -Subject: zkey: add function to iterate over all available CCA APQNs -From: Ingo Franzki - -Summary: zkey: check master key consistency -Description: Enhances the zkey tool to perform a cross check whether the - APQNs associated with a secure key have the same master key. - Display the master key verification pattern of a secure key - during the zkey validate command. This helps to better identify - which master key is the correct one, in case of master key - inconsistencies. - Select an appropriate APQN when re-enciphering a secure key. - Re-enciphering is done using the CCA host library. Special - handling is required to select an appropriate APQN for use with - the CCA host library. -Upstream-ID: 625b81130ab2c9d184aaede2749f1fd776f51062 -Problem-ID: SEC1916 - -Upstream-Description: - - zkey: add function to iterate over all available CCA APQNs - - Add a utility function to iterate over all available APQNs of - type CCA-Coprocessor. This function is required for various - future enhancements. - - Signed-off-by: Ingo Franzki - Reviewed-by: Harald Freudenberger - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/utils.c | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - zkey/utils.h | 5 ++ - 2 files changed, 132 insertions(+) - ---- a/zkey/utils.c -+++ b/zkey/utils.c -@@ -7,6 +7,7 @@ - * it under the terms of the MIT license. See LICENSE for details. - */ - -+#include - #include - #include - #include -@@ -19,8 +20,13 @@ - - #include "lib/util_path.h" - #include "lib/util_file.h" -+#include "lib/util_scandir.h" -+#include "lib/util_libc.h" -+#include "lib/util_rec.h" -+#include "lib/util_base.h" - - #include "utils.h" -+#include "properties.h" - - #define pr_verbose(verbose, fmt...) do { \ - if (verbose) \ -@@ -299,3 +305,124 @@ out: - free(dev_path); - return rc; - } -+ -+static int scan_for_domains(int card, apqn_handler_t handler, -+ void *handler_data, bool verbose) -+{ -+ struct dirent **namelist; -+ char fname[290]; -+ int i, n, domain, rc = 0; -+ -+ sprintf(fname, "/sys/devices/ap/card%02x/", card); -+ n = util_scandir(&namelist, alphasort, fname, -+ "[0-9a-fA-F]+\\.[0-9a-fA-F]+"); -+ -+ if (n < 0) -+ return -EIO; -+ -+ for (i = 0; i < n; i++) { -+ if (sscanf(namelist[i]->d_name, "%x.%x", &card, &domain) != 2) -+ continue; -+ -+ pr_verbose(verbose, "Found %02x.%04x", card, domain); -+ -+ if (sysfs_is_apqn_online(card, domain) != 1) { -+ pr_verbose(verbose, "APQN %02x.%04x is offline or not " -+ "CCA", card, domain); -+ continue; -+ } -+ -+ rc = handler(card, domain, handler_data); -+ if (rc != 0) -+ break; -+ } -+ -+ util_scandir_free(namelist, n); -+ return rc; -+} -+ -+ -+static int scan_for_apqns(apqn_handler_t handler, void *handler_data, -+ bool verbose) -+{ -+ struct dirent **namelist; -+ int i, n, card, rc = 0; -+ -+ if (handler == NULL) -+ return -EINVAL; -+ -+ n = util_scandir(&namelist, alphasort, "/sys/devices/ap/", -+ "card[0-9a-fA-F]+"); -+ if (n < 0) -+ return -EIO; -+ -+ for (i = 0; i < n; i++) { -+ if (sscanf(namelist[i]->d_name, "card%x", &card) != 1) -+ continue; -+ -+ pr_verbose(verbose, "Found card %02x", card); -+ -+ if (sysfs_is_card_online(card) != 1) { -+ pr_verbose(verbose, "Card %02x is offline or not CCA", -+ card); -+ continue; -+ } -+ -+ rc = scan_for_domains(card, handler, handler_data, verbose); -+ if (rc != 0) -+ break; -+ } -+ -+ util_scandir_free(namelist, n); -+ return rc; -+} -+ -+/** -+ * Calls the handler for all APQNs specified in the apqns parameter, or of this -+ * is NULL, for all online CCA APQNs found in sysfs. In case sysfs is inspected, -+ * the cards and domains are processed in alphabetical order. -+ * -+ * @param[in] apqns a comma separated list of APQNs. If NULL is specified, -+ * or an empty string, then all online CCA APQNs are -+ * handled. -+ * @param[in] handler a handler function that is called for each APQN -+ * @param[in] handler_data private data that is passed to the handler -+ * @param[in] verbose if true, verbose messages are printed -+ * -+ * @returns 0 for success or a negative errno in case of an error -+ */ -+int handle_apqns(const char *apqns, apqn_handler_t handler, void *handler_data, -+ bool verbose) -+{ -+ int card, domain; -+ char *copy, *tok; -+ char *save; -+ int rc = 0; -+ -+ if (apqns == NULL || (apqns != NULL && strlen(apqns) == 0)) { -+ rc = scan_for_apqns(handler, handler_data, verbose); -+ } else { -+ copy = util_strdup(apqns); -+ tok = strtok_r(copy, ",", &save); -+ while (tok != NULL) { -+ -+ if (sscanf(tok, "%x.%x", &card, &domain) != 2) { -+ warnx("the APQN '%s' is not valid", -+ tok); -+ rc = -EINVAL; -+ break; -+ } -+ -+ pr_verbose(verbose, "Specified: %02x.%04x", card, -+ domain); -+ rc = handler(card, domain, handler_data); -+ if (rc != 0) -+ break; -+ -+ tok = strtok_r(NULL, ",", &save); -+ } -+ free(copy); -+ } -+ -+ return rc; -+} ---- a/zkey/utils.h -+++ b/zkey/utils.h -@@ -41,4 +41,9 @@ struct mk_info { - int sysfs_get_mkvps(int card, int domain, struct mk_info *mk_info, - bool verbose); - -+typedef int(*apqn_handler_t) (int card, int domain, void *handler_data); -+ -+int handle_apqns(const char *apqns, apqn_handler_t handler, void *handler_data, -+ bool verbose); -+ - #endif diff --git a/s390-tools-sles15sp2-06-zipl-Make-use-of-__packed-macro.patch b/s390-tools-sles15sp2-06-zipl-Make-use-of-__packed-macro.patch deleted file mode 100644 index 58c67f8..0000000 --- a/s390-tools-sles15sp2-06-zipl-Make-use-of-__packed-macro.patch +++ /dev/null @@ -1,349 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] zipl: Make use of __packed macro -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: 0f7ed7d4fc86041a8646ce7abb615849e1298cca -Problem-ID: VS1804 - -Upstream-Description: - - zipl: Make use of __packed macro - - Make use of the pre-defined __packed macro throughout zipl. This - requires adding the global include dir to ALL_CFLAGS. - - Signed-off-by: Philipp Rudo - Reviewed-by: Stefan Haberland - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - zipl/boot/Makefile | 2 - - zipl/boot/s390.h | 2 - - zipl/include/boot.h | 52 +++++++++++++++++++++++++------------------------ - zipl/include/bootmap.h | 4 ++- - zipl/src/bootmap.c | 5 ++-- - zipl/src/install.c | 3 +- - 6 files changed, 37 insertions(+), 31 deletions(-) - ---- a/zipl/boot/Makefile -+++ b/zipl/boot/Makefile -@@ -2,7 +2,7 @@ - include ../../common.mak - - ALL_CFLAGS = $(NO_PIE_CFLAGS) -Os -g -I $(rootdir)/zipl/include \ -- -DS390_TOOLS_RELEASE=$(S390_TOOLS_RELEASE) \ -+ -I $(rootdir)/include -DS390_TOOLS_RELEASE=$(S390_TOOLS_RELEASE) \ - -fno-builtin -ffreestanding -fno-asynchronous-unwind-tables \ - -fno-delete-null-pointer-checks \ - -fexec-charset=IBM1047 -m64 -mpacked-stack \ ---- a/zipl/boot/s390.h -+++ b/zipl/boot/s390.h -@@ -11,7 +11,7 @@ - #ifndef S390_H - #define S390_H - --#include "../../include/lib/zt_common.h" -+#include "lib/zt_common.h" - #include "libc.h" - - #define __pa32(x) ((uint32_t)(unsigned long)(x)) ---- a/zipl/include/boot.h -+++ b/zipl/include/boot.h -@@ -14,6 +14,8 @@ - - #include - -+#include "lib/zt_common.h" -+ - #include "disk.h" - #include "job.h" - #include "zipl.h" -@@ -51,7 +53,7 @@ struct scsi_dump_sb { - uint64_t csum_offset; - uint64_t csum_size; - uint64_t csum; --} __attribute((packed)); -+} __packed; - - #define SCSI_DUMP_SB_MAGIC 0x5a46435044554d50ULL; /* ZFCPDUMP */ - /* To avoid a csum entry of 0 a seed is used */ -@@ -63,7 +65,7 @@ struct scsi_dump_sb { - struct scsi_dump_param { - uint64_t block; - uint64_t reserved; --} __attribute((packed)); -+} __packed; - /* ECKD dump parameter */ - - struct eckd_dump_param { -@@ -73,14 +75,14 @@ struct eckd_dump_param { - uint8_t num_heads; - uint8_t bpt; - char reserved[4]; --} __attribute((packed, may_alias)); -+} __packed __may_alias; - - /* FBA dump parameter */ - - struct fba_dump_param { - uint64_t start_blk; - uint64_t blockct; --} __attribute((packed)); -+} __packed; - - struct boot_info_bp_dump { - union { -@@ -89,7 +91,7 @@ struct boot_info_bp_dump { - struct scsi_dump_param scsi; - } param; - uint8_t unused[16]; --} __attribute__ ((packed)); -+} __packed; - - /* - * Layout of block pointer for linear devices -@@ -101,7 +103,7 @@ struct linear_blockptr { - uint16_t size; - uint16_t blockct; - uint8_t reserved[4]; --} __attribute((packed)); -+} __packed; - - /* - * Layout of block pointer for cylinder/head/sector devices -@@ -115,7 +117,7 @@ struct eckd_blockptr { - uint16_t size; - uint8_t blockct; - uint8_t reserved[8]; --} __attribute((packed)); -+} __packed; - - struct boot_info_bp_ipl { - union { -@@ -123,7 +125,7 @@ struct boot_info_bp_ipl { - struct linear_blockptr lin; - } bm_ptr; - uint8_t unused[16]; --} __attribute__ ((packed)); -+} __packed; - - struct boot_info { - char magic[4]; -@@ -135,7 +137,7 @@ struct boot_info { - struct boot_info_bp_dump dump; - struct boot_info_bp_ipl ipl; - } bp; --} __attribute__ ((packed)); -+} __packed; - - struct boot_ccw0 { - uint8_t cmd; -@@ -144,21 +146,21 @@ struct boot_ccw0 { - uint8_t flags; - uint8_t pad; - uint16_t count; --} __attribute__ ((packed)); -+} __packed; - - /* Boot data structures for FBA disks */ - - struct boot_fba_locread { - struct boot_ccw0 locate; - struct boot_ccw0 read; --} __attribute__ ((packed)); -+} __packed; - - struct boot_fba_locdata { - uint8_t command; - uint8_t dummy; - uint16_t blockct; - uint32_t blocknr; --} __attribute__ ((packed)); -+} __packed; - - struct boot_fba_stage0 { - uint64_t psw; -@@ -169,13 +171,13 @@ struct boot_fba_stage0 { - struct boot_fba_locdata locdata[2]; - uint64_t reserved[4]; - struct boot_info boot_info; --} __attribute__ ((packed)); -+} __packed; - - struct boot_fba_stage1b { - struct boot_fba_locread locread[STAGE2_BLK_CNT_MAX]; - struct boot_fba_locdata locdata[STAGE2_BLK_CNT_MAX]; - uint8_t unused[448]; --} __attribute__ ((packed)); -+} __packed; - - /* Boot data structures for ECKD disks */ - -@@ -184,14 +186,14 @@ struct boot_eckd_ccw1 { - uint8_t flags; - uint16_t count; - uint32_t address; --} __attribute__ ((packed)); -+} __packed; - - struct boot_eckd_ssrt { - struct boot_ccw0 seek; - struct boot_ccw0 search; - struct boot_ccw0 tic; - struct boot_ccw0 read; --} __attribute__ ((packed)); -+} __packed; - - struct boot_eckd_seekarg { - uint16_t pad; -@@ -199,32 +201,32 @@ struct boot_eckd_seekarg { - uint16_t head; - uint8_t sec; - uint8_t pad2; --} __attribute__ ((packed)); -+} __packed; - - struct boot_eckd_cdl_stage0 { - uint64_t psw; - struct boot_ccw0 read; - struct boot_ccw0 tic; --} __attribute__ ((packed)); -+} __packed; - - struct boot_eckd_ldl_stage0 { - uint64_t psw; - struct boot_ccw0 read_r0; - struct boot_ccw0 read_r1; --} __attribute__ ((packed)); -+} __packed; - - struct boot_eckd_stage1 { - struct boot_eckd_ssrt ssrt[2]; - struct boot_ccw0 tic1b; - struct boot_eckd_seekarg seek[2]; - struct boot_info boot_info; --} __attribute__ ((packed)); -+} __packed; - - struct boot_eckd_stage1b { - struct boot_eckd_ssrt ssrt[STAGE2_BLK_CNT_MAX]; - struct boot_eckd_seekarg seek[STAGE2_BLK_CNT_MAX]; - uint8_t unused[64]; --} __attribute__ ((packed)); -+} __packed; - - /* Stage 2 boot menu parameter structure */ - -@@ -236,7 +238,7 @@ struct boot_stage2_params { - uint16_t banner; - uint16_t config[BOOT_MENU_ENTRIES + 1]; - uint64_t config_kdump; --} __attribute__ ((packed)); -+} __packed; - - - /* Stage 3 bootloader parameter structure */ -@@ -251,7 +253,7 @@ struct boot_stage3_params { - uint16_t reserved[3]; - uint64_t image_len; - uint64_t image_addr; --} __attribute__ ((packed)); -+} __packed; - - #define STAGE3_FLAG_SCSI 0x0001 - #define STAGE3_FLAG_KDUMP 0x0002 -@@ -275,7 +277,7 @@ struct mvdump_param { - uint8_t blocksize; - uint8_t bpt; - uint8_t num_heads; --} __attribute__ ((packed)); -+} __packed; - - struct mvdump_parm_table { - uint64_t timestamp; -@@ -284,7 +286,7 @@ struct mvdump_parm_table { - uint8_t ssid[MAX_DUMP_VOLUMES]; - unsigned char reserved[512 - sizeof(uint64_t) - sizeof(uint16_t) - - (MAX_DUMP_VOLUMES * (sizeof(struct mvdump_param) + 1))]; --} __attribute__ ((packed)); -+} __packed; - - void boot_get_dump_info(struct boot_info *boot_info, uint8_t dev_type, - void *param); ---- a/zipl/include/bootmap.h -+++ b/zipl/include/bootmap.h -@@ -12,6 +12,8 @@ - #ifndef BOOTMAP_H - #define BOOTMAP_H - -+#include "lib/zt_common.h" -+ - #include "disk.h" - #include "job.h" - #include "zipl.h" -@@ -23,7 +25,7 @@ struct signature_header { - uint8_t format; - uint8_t reserved[3]; - uint32_t length; --} __attribute((packed)); -+} __packed; - - typedef union { - uint64_t load_address; ---- a/zipl/src/bootmap.c -+++ b/zipl/src/bootmap.c -@@ -18,6 +18,7 @@ - #include - #include - -+#include "lib/zt_common.h" - #include "lib/util_part.h" - #include "lib/util_path.h" - -@@ -223,7 +224,7 @@ struct component_entry { - uint8_t data[23]; - uint8_t type; - component_data compdat; --} __attribute((packed)); -+} __packed; - - typedef enum { - component_execute = 0x01, -@@ -263,7 +264,7 @@ struct component_header { - uint8_t magic[4]; - uint8_t type; - uint8_t reserved[27]; --} __attribute((packed)); -+} __packed; - - typedef enum { - component_header_ipl = 0x00, ---- a/zipl/src/install.c -+++ b/zipl/src/install.c -@@ -23,6 +23,7 @@ - #include - #include - -+#include "lib/zt_common.h" - #include "lib/util_sys.h" - - #include "boot.h" -@@ -89,7 +90,7 @@ update_scsi_mbr(void* bootblock, disk_bl - uint8_t program_table_pointer[16]; - uint8_t reserved2[0x50]; - struct boot_info boot_info; -- } __attribute__ ((packed))* mbr; -+ } __packed* mbr; - struct scsi_dump_param param; - void* buffer; - diff --git a/s390-tools-sles15sp2-06-zkey-Add-function-to-print-the-MKVPs-of-APQNs.patch b/s390-tools-sles15sp2-06-zkey-Add-function-to-print-the-MKVPs-of-APQNs.patch deleted file mode 100644 index 5ab337b..0000000 --- a/s390-tools-sles15sp2-06-zkey-Add-function-to-print-the-MKVPs-of-APQNs.patch +++ /dev/null @@ -1,131 +0,0 @@ -Subject: zkey: Add function to print the MKVPs of APQNs -From: Ingo Franzki - -Summary: zkey: check master key consistency -Description: Enhances the zkey tool to perform a cross check whether the - APQNs associated with a secure key have the same master key. - Display the master key verification pattern of a secure key - during the zkey validate command. This helps to better identify - which master key is the correct one, in case of master key - inconsistencies. - Select an appropriate APQN when re-enciphering a secure key. - Re-enciphering is done using the CCA host library. Special - handling is required to select an appropriate APQN for use with - the CCA host library. -Upstream-ID: bfc3dd018c4f0cc17f8463d8bd6be16aab8de4a4 -Problem-ID: SEC1916 - -Upstream-Description: - - zkey: Add function to print the MKVPs of APQNs - - Add a utility function to print the master key verification patterns - of a set of APQNs. This allows the user to visually check which - master keys are set on which APQNs. - - Signed-off-by: Ingo Franzki - Reviewed-by: Harald Freudenberger - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/utils.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - zkey/utils.h | 2 + - 2 files changed, 82 insertions(+) - ---- a/zkey/utils.c -+++ b/zkey/utils.c -@@ -426,3 +426,83 @@ int handle_apqns(const char *apqns, apqn - - return rc; - } -+ -+struct print_apqn_info { -+ struct util_rec *rec; -+ bool verbose; -+}; -+ -+static int print_apqn_mk_info(int card, int domain, void *handler_data) -+{ -+ struct print_apqn_info *info = (struct print_apqn_info *)handler_data; -+ struct mk_info mk_info; -+ int rc; -+ -+ rc = sysfs_get_mkvps(card, domain, &mk_info, info->verbose); -+ if (rc == -ENOTSUP) -+ return rc; -+ -+ util_rec_set(info->rec, "APQN", "%02x.%04x", card, domain); -+ -+ if (rc == 0) { -+ if (mk_info.new_mk.mk_state == MK_STATE_FULL) -+ util_rec_set(info->rec, "NEW", "%016llx", -+ mk_info.new_mk.mkvp); -+ else if (mk_info.new_mk.mk_state == MK_STATE_PARTIAL) -+ util_rec_set(info->rec, "NEW", "partially loaded"); -+ else -+ util_rec_set(info->rec, "NEW", "-"); -+ -+ if (mk_info.cur_mk.mk_state == MK_STATE_VALID) -+ util_rec_set(info->rec, "CUR", "%016llx", -+ mk_info.cur_mk.mkvp); -+ else -+ util_rec_set(info->rec, "CUR", "-"); -+ -+ if (mk_info.old_mk.mk_state == MK_STATE_VALID) -+ util_rec_set(info->rec, "OLD", "%016llx", -+ mk_info.old_mk.mkvp); -+ else -+ util_rec_set(info->rec, "OLD", "-"); -+ } else { -+ util_rec_set(info->rec, "NEW", "?"); -+ util_rec_set(info->rec, "CUR", "?"); -+ util_rec_set(info->rec, "OLD", "?"); -+ } -+ -+ util_rec_print(info->rec); -+ -+ return 0; -+} -+ -+/** -+ * Prints master key information for all specified APQNs -+ * -+ * @param[in] apqns a comma separated list of APQNs. If NULL is specified, -+ * or an empty string, then all online CCA APQNs are -+ * printed. -+ * @param[in] verbose if true, verbose messages are printed -+ * -+ * @returns 0 for success or a negative errno in case of an error. -ENOTSUP is -+ * returned when the mkvps sysfs attribute is not available, because -+ * the zcrypt kernel module is on an older level. -+ */ -+int print_mk_info(const char *apqns, bool verbose) -+{ -+ struct print_apqn_info info; -+ int rc; -+ -+ info.verbose = verbose; -+ info.rec = util_rec_new_wide("-"); -+ -+ util_rec_def(info.rec, "APQN", UTIL_REC_ALIGN_LEFT, 11, "CARD.DOMAIN"); -+ util_rec_def(info.rec, "NEW", UTIL_REC_ALIGN_LEFT, 16, "NEW MK"); -+ util_rec_def(info.rec, "CUR", UTIL_REC_ALIGN_LEFT, 16, "CURRENT MK"); -+ util_rec_def(info.rec, "OLD", UTIL_REC_ALIGN_LEFT, 16, "OLD MK"); -+ util_rec_print_hdr(info.rec); -+ -+ rc = handle_apqns(apqns, print_apqn_mk_info, &info, verbose); -+ -+ util_rec_free(info.rec); -+ return rc; -+} ---- a/zkey/utils.h -+++ b/zkey/utils.h -@@ -46,4 +46,6 @@ typedef int(*apqn_handler_t) (int card, - int handle_apqns(const char *apqns, apqn_handler_t handler, void *handler_data, - bool verbose); - -+int print_mk_info(const char *apqns, bool verbose); -+ - #endif diff --git a/s390-tools-sles15sp2-07-zipl-define-__section-macro-and-make-use-of-it.patch b/s390-tools-sles15sp2-07-zipl-define-__section-macro-and-make-use-of-it.patch deleted file mode 100644 index 605ca13..0000000 --- a/s390-tools-sles15sp2-07-zipl-define-__section-macro-and-make-use-of-it.patch +++ /dev/null @@ -1,188 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] zipl: define __section macro and make use of it -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: 154734efc7ffeb1e51dd2be62561a364fdc6117c -Problem-ID: VS1804 - -Upstream-Description: - - zipl: define __section macro and make use of it - - Signed-off-by: Philipp Rudo - Reviewed-by: Stefan Haberland - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - include/lib/zt_common.h | 1 + - zipl/boot/eckd2dump_mv.c | 8 ++++---- - zipl/boot/eckd2dump_sv.c | 5 +++-- - zipl/boot/fba2dump.c | 4 ++-- - zipl/boot/stage2.c | 4 +++- - zipl/boot/stage2dump.c | 5 +++-- - zipl/boot/stage2dump.h | 3 +-- - zipl/boot/tape2dump.c | 4 +++- - 8 files changed, 20 insertions(+), 14 deletions(-) - ---- a/include/lib/zt_common.h -+++ b/include/lib/zt_common.h -@@ -31,6 +31,7 @@ - #define __packed __attribute__((packed)) - #define __aligned(x) __attribute__((aligned(x))) - #define __may_alias __attribute__((may_alias)) -+#define __section(x) __attribute__((__section__(#x))) - - typedef unsigned long long u64; - typedef signed long long s64; ---- a/zipl/boot/eckd2dump_mv.c -+++ b/zipl/boot/eckd2dump_mv.c -@@ -9,6 +9,8 @@ - * it under the terms of the MIT license. See LICENSE for details. - */ - -+#include "lib/zt_common.h" -+ - #include "eckd2dump.h" - #include "error.h" - #include "stage2dump.h" -@@ -19,8 +21,7 @@ - /* - * Magic number at start of dump record - */ --uint64_t magic __attribute__((section(".stage2.head"))) -- = 0x584d554c54363401ULL; /* XMULT64, version 1 */ -+uint64_t __section(.stage2.head) magic = 0x584d554c54363401ULL; /* XMULT64, version 1 */ - - /* - * Parameter format for ECKD MV dumper (13 bytes): -@@ -59,8 +60,7 @@ struct mvdump_parm_table { - (MAX_DUMP_VOLUMES * (sizeof(struct mvdump_param) + 1))]; - } __packed; - --static struct mvdump_parm_table mvdump_table -- __attribute__((section(".eckd2dump_mv.tail"))); -+static struct mvdump_parm_table __section(.eckd2dump_mv.tail) mvdump_table; - - static int volnr_current; - ---- a/zipl/boot/eckd2dump_sv.c -+++ b/zipl/boot/eckd2dump_sv.c -@@ -9,6 +9,8 @@ - * it under the terms of the MIT license. See LICENSE for details. - */ - -+#include "lib/zt_common.h" -+ - #include "eckd2dump.h" - #include "error.h" - #include "stage2dump.h" -@@ -16,8 +18,7 @@ - /* - * Magic number at start of dump record - */ --uint64_t magic __attribute__((section(".stage2.head"))) = -- 0x5845434b44363401ULL; /* "XECKD64", version 1 */ -+uint64_t __section(.stage2.head) magic = 0x5845434b44363401ULL; /* "XECKD64", version 1 */ - - /* - * ECKD parameter block passed by zipl ---- a/zipl/boot/fba2dump.c -+++ b/zipl/boot/fba2dump.c -@@ -9,6 +9,7 @@ - * it under the terms of the MIT license. See LICENSE for details. - */ - -+#include "lib/zt_common.h" - #include "error.h" - #include "fba.h" - #include "stage2dump.h" -@@ -20,8 +21,7 @@ - /* - * Magic number at start of dump record - */ --uint64_t magic __attribute__((section(".stage2.head"))) -- = 0x5844464241363401ULL; /* XDFBA64, version 1 */ -+uint64_t __section(.stage2.head) magic = 0x5844464241363401ULL; /* XDFBA64, version 1 */ - - /* - * FBA dump device partition specification ---- a/zipl/boot/stage2.c -+++ b/zipl/boot/stage2.c -@@ -9,6 +9,8 @@ - * it under the terms of the MIT license. See LICENSE for details. - */ - -+#include "lib/zt_common.h" -+ - #include "error.h" - #include "libc.h" - #include "menu.h" -@@ -141,4 +143,4 @@ void panic_notify(unsigned long UNUSED(r - { - } - --uint64_t stage2_head __attribute__((section(".stage2.head"))); -+uint64_t __section(.stage2.head) stage2_head; ---- a/zipl/boot/stage2dump.c -+++ b/zipl/boot/stage2dump.c -@@ -11,6 +11,8 @@ - - #include - -+#include "lib/zt_common.h" -+ - #include "error.h" - #include "sclp.h" - #include "stage2dump.h" -@@ -34,8 +36,7 @@ struct ipib_info { - /* - * Tail parameters - */ --struct stage2dump_parm_tail parm_tail -- __attribute__ ((section(".stage2dump.tail"))) = { -+struct stage2dump_parm_tail parm_tail = { - .mem_upper_limit = 0xffffffffffffffffULL, - }; - ---- a/zipl/boot/stage2dump.h -+++ b/zipl/boot/stage2dump.h -@@ -28,8 +28,7 @@ struct stage2dump_parm_tail { - uint64_t mem_upper_limit; - } __packed; - --extern struct stage2dump_parm_tail parm_tail -- __attribute__ ((section(".stage2dump.tail"))); -+extern struct stage2dump_parm_tail __section(.stage2dump.tail) parm_tail; - - /* - * S390 dump format defines ---- a/zipl/boot/tape2dump.c -+++ b/zipl/boot/tape2dump.c -@@ -9,6 +9,8 @@ - * it under the terms of the MIT license. See LICENSE for details. - */ - -+#include "lib/zt_common.h" -+ - #include "cio.h" - #include "error.h" - #include "libc.h" -@@ -33,7 +35,7 @@ struct tape_head { - uint64_t ccw2; - } __packed; - --struct tape_head tape_head __attribute__((section(".stage2.head"))) = { -+struct tape_head __section(.stage2.head) tape_head = { - .psw = 0x0008000080002018ULL, /* Start code at 0x2018 */ - .ccw1 = 0x0700000060000001ULL, /* Rewind ccw */ - .ccw2 = 0x0200200020003000ULL, /* CCW to load dump tool to 0x2000 */ diff --git a/s390-tools-sles15sp2-07-zkey-Add-function-to-cross-check-APQNs-for-valid-mas.patch b/s390-tools-sles15sp2-07-zkey-Add-function-to-cross-check-APQNs-for-valid-mas.patch deleted file mode 100644 index 0c45ee8..0000000 --- a/s390-tools-sles15sp2-07-zkey-Add-function-to-cross-check-APQNs-for-valid-mas.patch +++ /dev/null @@ -1,271 +0,0 @@ -Subject: zkey: Add function to cross check APQNs for valid master keys -From: Ingo Franzki - -Summary: zkey: check master key consistency -Description: Enhances the zkey tool to perform a cross check whether the - APQNs associated with a secure key have the same master key. - Display the master key verification pattern of a secure key - during the zkey validate command. This helps to better identify - which master key is the correct one, in case of master key - inconsistencies. - Select an appropriate APQN when re-enciphering a secure key. - Re-enciphering is done using the CCA host library. Special - handling is required to select an appropriate APQN for use with - the CCA host library. -Upstream-ID: b32c0314746ddee69e59f892f105acd720d06452 -Problem-ID: SEC1916 - -Upstream-Description: - - zkey: Add function to cross check APQNs for valid master keys - - Add a utility function to cross check the master keys of a set of - APQNs. It checks for valid master keys in the CURRENT and OLD - master key registers, as well as newly loaded master keys in the NEW - register. It issues information and warning messages for various - findings and also indicates improper master key setup to the caller. - - Signed-off-by: Ingo Franzki - Reviewed-by: Harald Freudenberger - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/utils.c | 217 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - zkey/utils.h | 3 - 2 files changed, 220 insertions(+) - ---- a/zkey/utils.c -+++ b/zkey/utils.c -@@ -506,3 +506,220 @@ int print_mk_info(const char *apqns, boo - util_rec_free(info.rec); - return rc; - } -+ -+struct cross_check_info { -+ u64 mkvp; -+ u64 new_mkvp; -+ bool key_mkvp; -+ u32 num_cur_match; -+ u32 num_old_match; -+ u32 num_new_match; -+ bool mismatch; -+ bool print_mks; -+ int num_checked; -+ bool verbose; -+}; -+ -+static int cross_check_mk_info(int card, int domain, void *handler_data) -+{ -+ struct cross_check_info *info = (struct cross_check_info *)handler_data; -+ struct mk_info mk_info; -+ char temp[200]; -+ int rc; -+ -+ rc = sysfs_get_mkvps(card, domain, &mk_info, info->verbose); -+ if (rc == -ENODEV) { -+ info->print_mks = 1; -+ printf("WARNING: APQN %02x.%04x: Not available or not of " -+ "type CCA\n", card, domain); -+ return 0; -+ } -+ if (rc != 0) -+ return rc; -+ -+ info->num_checked++; -+ -+ if (mk_info.new_mk.mk_state == MK_STATE_PARTIAL) { -+ info->print_mks = 1; -+ sprintf(temp, "INFO: APQN %02x.%04x: The NEW master key " -+ "register is only partially loaded.", card, domain); -+ util_print_indented(temp, 0); -+ } -+ -+ if (info->new_mkvp == 0 && -+ mk_info.new_mk.mk_state == MK_STATE_FULL) -+ info->new_mkvp = mk_info.new_mk.mkvp; -+ -+ if (mk_info.new_mk.mk_state == MK_STATE_FULL && -+ mk_info.new_mk.mkvp != info->new_mkvp) { -+ info->print_mks = 1; -+ sprintf(temp, "WARNING: APQN %02x.%04x: The NEW master key " -+ "register contains a different master key than " -+ "the NEW register of other APQNs.", card, -+ domain); -+ util_print_indented(temp, 0); -+ } -+ -+ if (mk_info.cur_mk.mk_state != MK_STATE_VALID) { -+ info->print_mks = 1; -+ info->mismatch = 1; -+ printf("WARNING: APQN %02x.%04x: No master key is set.\n", card, -+ domain); -+ return 0; -+ } -+ -+ if (mk_info.old_mk.mk_state == MK_STATE_VALID && -+ mk_info.old_mk.mkvp == mk_info.cur_mk.mkvp) { -+ info->print_mks = 1; -+ sprintf(temp, "INFO: APQN %02x.%04x: The OLD master key " -+ "register contains the same master key as the CURRENT " -+ "master key register.", card, domain); -+ util_print_indented(temp, 0); -+ } -+ if (mk_info.new_mk.mk_state == MK_STATE_FULL && -+ mk_info.new_mk.mkvp == mk_info.cur_mk.mkvp) { -+ info->print_mks = 1; -+ sprintf(temp, "INFO: APQN %02x.%04x: The NEW master key " -+ "register contains the same master key as the CURRENT " -+ "master key register.", card, domain); -+ util_print_indented(temp, 0); -+ } -+ if (mk_info.new_mk.mk_state == MK_STATE_FULL && -+ mk_info.old_mk.mk_state == MK_STATE_VALID && -+ mk_info.new_mk.mkvp == mk_info.old_mk.mkvp) { -+ info->print_mks = 1; -+ sprintf(temp, "INFO: APQN %02x.%04x: The NEW master key " -+ "register contains the same master key as the OLD " -+ "master key register.", card, domain); -+ util_print_indented(temp, 0); -+ } -+ -+ if (info->mkvp == 0) -+ info->mkvp = mk_info.cur_mk.mkvp; -+ -+ if (info->key_mkvp) { -+ if (mk_info.cur_mk.mk_state == MK_STATE_VALID && -+ mk_info.cur_mk.mkvp == info->mkvp) -+ info->num_cur_match++; -+ -+ if (mk_info.old_mk.mk_state == MK_STATE_VALID && -+ mk_info.old_mk.mkvp == info->mkvp) -+ info->num_old_match++; -+ -+ if (mk_info.new_mk.mk_state == MK_STATE_FULL && -+ mk_info.new_mk.mkvp == info->mkvp) -+ info->num_new_match++; -+ } -+ -+ if (mk_info.cur_mk.mkvp != info->mkvp) { -+ -+ if (info->key_mkvp) { -+ if (mk_info.old_mk.mk_state == MK_STATE_VALID && -+ mk_info.old_mk.mkvp == info->mkvp) { -+ info->print_mks = 1; -+ sprintf(temp, "INFO: APQN %02x.%04x: The master" -+ " key has been changed to a new " -+ "master key, but the secure key has " -+ "not yet been re-enciphered.", card, -+ domain); -+ util_print_indented(temp, 0); -+ } else if (mk_info.new_mk.mk_state == MK_STATE_FULL && -+ mk_info.new_mk.mkvp == info->mkvp) { -+ info->print_mks = 1; -+ sprintf(temp, "INFO: APQN %02x.%04x: The master" -+ " key has been changed but is not " -+ "yet been set (made active).", card, -+ domain); -+ util_print_indented(temp, 0); -+ } else { -+ info->print_mks = 1; -+ info->mismatch = 1; -+ sprintf(temp, "WARNING: APQN %02x.%04x: The " -+ "CURRENT master key register contains " -+ "a master key that is different from " -+ "the one used by the secure key.", card, -+ domain); -+ util_print_indented(temp, 0); -+ } -+ } else { -+ info->print_mks = 1; -+ info->mismatch = 1; -+ } -+ } -+ -+ return 0; -+} -+ -+/** -+ * Cross checks the master key information for all specified APQNs. It checks -+ * if all specified APQNs have the same current master key, and if it matches -+ * the master key specified by the mkvp parameter (optional). If not, it prints -+ * out an information message about the APQNs that have a different master key. -+ * -+ * @param[in] apqns a comma separated list of APQNs. If NULL is specified, -+ * or an empty string, then all online CCA APQNs are -+ * checked. -+ * @param[in] mkvp The master key verification pattern of a secure key. -+ * If this is all zero, then the master keys are not -+ * matched against it. -+ * @param[in] print_mks if true, then a the full master key info of all -+ * specified APQns is printed, in case of a mismatch. -+ * @param[in] verbose if true, verbose messages are printed -+ * -+ * @returns 0 for success or a negative errno in case of an error. -ENODEV is -+ * returned if at least one APQN has a mismatching master key. -+ * -ENOTSUP is returned when the mkvps sysfs attribute is not -+ * available, because the zcrypt kernel module is on an older level. -+ */ -+int cross_check_apqns(const char *apqns, u64 mkvp, bool print_mks, bool verbose) -+{ -+ struct cross_check_info info; -+ char temp[200]; -+ int rc; -+ -+ memset(&info, 0, sizeof(info)); -+ info.key_mkvp = mkvp != 0; -+ info.mkvp = mkvp; -+ info.verbose = verbose; -+ -+ pr_verbose(verbose, "Cross checking APQNs with mkvp 0x%016llx: %s", -+ mkvp, apqns != NULL ? apqns : "ANY"); -+ -+ rc = handle_apqns(apqns, cross_check_mk_info, &info, verbose); -+ if (rc != 0) -+ return rc; -+ -+ if (info.mismatch) { -+ if (info.key_mkvp) -+ printf("WARNING: Not all APQNs have the correct master " -+ "key (%016llx).\n", mkvp); -+ else -+ printf("WARNING: Not all APQNs have the same master " -+ "key.\n"); -+ -+ rc = -ENODEV; -+ } -+ if (info.num_checked == 0) { -+ printf("WARNING: None of the APQNs is available or of " -+ "type CCA\n"); -+ rc = -ENODEV; -+ } -+ if (info.num_old_match > 0 && info.num_new_match > 0) { -+ sprintf(temp, "WARNING: On %u APQNs the OLD master key " -+ "register contains the master key use by the secure " -+ "key, and on %u APQNs the NEW master key register " -+ "contains the master key use by the secure key.", -+ info.num_old_match, info.num_new_match); -+ util_print_indented(temp, 0); -+ info.print_mks = 1; -+ rc = -ENODEV; -+ } -+ -+ if (print_mks && info.print_mks) { -+ printf("\n"); -+ print_mk_info(apqns, verbose); -+ printf("\n"); -+ } -+ -+ return rc; -+} ---- a/zkey/utils.h -+++ b/zkey/utils.h -@@ -48,4 +48,7 @@ int handle_apqns(const char *apqns, apqn - - int print_mk_info(const char *apqns, bool verbose); - -+int cross_check_apqns(const char *apqns, u64 mkvp, bool print_mks, -+ bool verbose); -+ - #endif diff --git a/s390-tools-sles15sp2-08-zipl-Make-use-of-__noreturn-macro.patch b/s390-tools-sles15sp2-08-zipl-Make-use-of-__noreturn-macro.patch deleted file mode 100644 index f4716ef..0000000 --- a/s390-tools-sles15sp2-08-zipl-Make-use-of-__noreturn-macro.patch +++ /dev/null @@ -1,61 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] zipl: Make use of __noreturn macro -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: 86856f98dbe3f68e34b91b58e9fc92f7cdc8a0d4 -Problem-ID: VS1804 - -Upstream-Description: - - zipl: Make use of __noreturn macro - - Signed-off-by: Philipp Rudo - Reviewed-by: Stefan Haberland - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - zipl/boot/libc.c | 4 +++- - zipl/boot/libc.h | 2 +- - 2 files changed, 4 insertions(+), 2 deletions(-) - ---- a/zipl/boot/libc.c -+++ b/zipl/boot/libc.c -@@ -11,6 +11,8 @@ - - #include - -+#include "lib/zt_common.h" -+ - #include "error.h" - #include "libc.h" - #include "sclp.h" -@@ -511,7 +513,7 @@ void initialize(void) - /* - * Load disabled wait PSW with reason code in address field - */ --void libc_stop(unsigned long reason) -+void __noreturn libc_stop(unsigned long reason) - { - struct psw_t psw; - ---- a/zipl/boot/libc.h -+++ b/zipl/boot/libc.h -@@ -60,7 +60,7 @@ char *strcpy(char *, const char *); - unsigned long get_zeroed_page(void); - void free_page(unsigned long); - void initialize(void); --void libc_stop(unsigned long) __attribute__((noreturn)); -+void libc_stop(unsigned long); - void start(void); - void pgm_check_handler(void); - void pgm_check_handler_fn(void); diff --git a/s390-tools-sles15sp2-08-zkey-Add-function-to-obtain-the-mkvp-of-a-secure-key.patch b/s390-tools-sles15sp2-08-zkey-Add-function-to-obtain-the-mkvp-of-a-secure-key.patch deleted file mode 100644 index 5ee0265..0000000 --- a/s390-tools-sles15sp2-08-zkey-Add-function-to-obtain-the-mkvp-of-a-secure-key.patch +++ /dev/null @@ -1,74 +0,0 @@ -Subject: zkey: Add function to obtain the mkvp of a secure key -From: Ingo Franzki - -Summary: zkey: check master key consistency -Description: Enhances the zkey tool to perform a cross check whether the - APQNs associated with a secure key have the same master key. - Display the master key verification pattern of a secure key - during the zkey validate command. This helps to better identify - which master key is the correct one, in case of master key - inconsistencies. - Select an appropriate APQN when re-enciphering a secure key. - Re-enciphering is done using the CCA host library. Special - handling is required to select an appropriate APQN for use with - the CCA host library. -Upstream-ID: ea7cc9ea606dd879e4cdfae06a6f13d8fa3afff4 -Problem-ID: SEC1916 - -Upstream-Description: - - zkey: Add function to obtain the mkvp of a secure key - - A secure AES key token contains the master key verification pattern - of the master key it is encrypted with. Add a function to obtain the - master key verification pattern of a secure key token. - - Signed-off-by: Ingo Franzki - Reviewed-by: Harald Freudenberger - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/pkey.c | 21 +++++++++++++++++++++ - zkey/pkey.h | 4 ++++ - 2 files changed, 25 insertions(+) - ---- a/zkey/pkey.c -+++ b/zkey/pkey.c -@@ -769,3 +769,24 @@ out: - - return rc; - } -+ -+int get_master_key_verification_pattern(const u8 *secure_key, -+ size_t secure_key_size, u64 *mkvp, -+ bool verbose) -+{ -+ struct secaeskeytoken *token = (struct secaeskeytoken *)secure_key; -+ -+ util_assert(secure_key != NULL, "Internal error: secure_key is NULL"); -+ util_assert(mkvp != NULL, "Internal error: mkvp is NULL"); -+ -+ if (secure_key_size < SECURE_KEY_SIZE) { -+ pr_verbose(verbose, "Size of secure key is too small: " -+ "%lu expected %lu", secure_key_size, -+ SECURE_KEY_SIZE); -+ return -EINVAL; -+ } -+ -+ *mkvp = token->mkvp; -+ -+ return 0; -+} ---- a/zkey/pkey.h -+++ b/zkey/pkey.h -@@ -112,4 +112,8 @@ int validate_secure_key(int pkey_fd, - int generate_key_verification_pattern(const char *key, size_t key_size, - char *vp, size_t vp_len, bool verbose); - -+int get_master_key_verification_pattern(const u8 *secure_key, -+ size_t secure_key_size, u64 *mkvp, -+ bool verbose); -+ - #endif diff --git a/s390-tools-sles15sp2-09-zipl-Define-__noinline-macro-and-make-use-of-it.patch b/s390-tools-sles15sp2-09-zipl-Define-__noinline-macro-and-make-use-of-it.patch deleted file mode 100644 index 4dee5d7..0000000 --- a/s390-tools-sles15sp2-09-zipl-Define-__noinline-macro-and-make-use-of-it.patch +++ /dev/null @@ -1,66 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] zipl: Define __noinline macro and make use of it -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: 5eace91ee7bd76b8ab44291299ac313c87c9ecb8 -Problem-ID: VS1804 - -Upstream-Description: - - zipl: Define __noinline macro and make use of it - - Signed-off-by: Philipp Rudo - Reviewed-by: Stefan Haberland - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - include/lib/zt_common.h | 1 + - libutil/util_panic_example.c | 2 +- - zipl/boot/libc.c | 2 +- - 3 files changed, 3 insertions(+), 2 deletions(-) - ---- a/include/lib/zt_common.h -+++ b/include/lib/zt_common.h -@@ -32,6 +32,7 @@ - #define __aligned(x) __attribute__((aligned(x))) - #define __may_alias __attribute__((may_alias)) - #define __section(x) __attribute__((__section__(#x))) -+#define __noinline __attribute__((__noinline__)) - - typedef unsigned long long u64; - typedef signed long long s64; ---- a/libutil/util_panic_example.c -+++ b/libutil/util_panic_example.c -@@ -15,10 +15,10 @@ - #include - #include - -+#include "lib/zt_common.h" - #include "lib/util_panic.h" - - /* Make functions noinline to have a nice backtrace */ --#define __noinline __attribute__((noinline)) - - /* - * Test util_panic() ---- a/zipl/boot/libc.c -+++ b/zipl/boot/libc.c -@@ -473,7 +473,7 @@ void pgm_check_handler_fn(void) - libc_stop(psw_old->addr); - } - --__attribute__ ((noinline)) void load_wait_psw(uint64_t psw_mask, struct psw_t *psw) -+void __noinline load_wait_psw(uint64_t psw_mask, struct psw_t *psw) - { - struct psw_t wait_psw = { .mask = psw_mask, .addr = 0 }; - struct psw_t old_psw, *wait_psw_ptr = &wait_psw; diff --git a/s390-tools-sles15sp2-09-zkey-Display-MKVP-when-validating-a-secure-key.patch b/s390-tools-sles15sp2-09-zkey-Display-MKVP-when-validating-a-secure-key.patch deleted file mode 100644 index 25f7aac..0000000 --- a/s390-tools-sles15sp2-09-zkey-Display-MKVP-when-validating-a-secure-key.patch +++ /dev/null @@ -1,176 +0,0 @@ -Subject: zkey: Display MKVP when validating a secure key -From: Ingo Franzki - -Summary: zkey: check master key consistency -Description: Enhances the zkey tool to perform a cross check whether the - APQNs associated with a secure key have the same master key. - Display the master key verification pattern of a secure key - during the zkey validate command. This helps to better identify - which master key is the correct one, in case of master key - inconsistencies. - Select an appropriate APQN when re-enciphering a secure key. - Re-enciphering is done using the CCA host library. Special - handling is required to select an appropriate APQN for use with - the CCA host library. -Upstream-ID: c2244a57950f4eb35e3209151dcf48de66828df1 -Problem-ID: SEC1916 - -Upstream-Description: - - zkey: Display MKVP when validating a secure key - - Display the master key verification pattern of a secure key while - 'zkey validate' and 'zkey-cryptsetup validate' - - Signed-off-by: Ingo Franzki - Reviewed-by: Harald Freudenberger - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/keystore.c | 20 ++++++++++++++------ - zkey/zkey-cryptsetup.c | 16 +++++++++++++--- - zkey/zkey.c | 14 ++++++++++++-- - 3 files changed, 39 insertions(+), 11 deletions(-) - ---- a/zkey/keystore.c -+++ b/zkey/keystore.c -@@ -2107,7 +2107,7 @@ static void _keystore_print_record(struc - bool validation, const char *skey_filename, - size_t secure_key_size, - size_t clear_key_bitsize, bool valid, -- bool is_old_mk, bool reenc_pending) -+ bool is_old_mk, bool reenc_pending, u64 mkvp) - { - char temp_vp[VERIFICATION_PATTERN_LEN + 2]; - char *volumes_argz = NULL; -@@ -2169,10 +2169,11 @@ static void _keystore_print_record(struc - if (validation) { - if (valid) - util_rec_set(rec, REC_MASTERKEY, -- is_old_mk ? "OLD CCA master key" : -- "CURRENT CCA master key"); -+ "%s CCA master key (MKVP: %016llx)", -+ is_old_mk ? "OLD" : "CURRENT", mkvp); - else -- util_rec_set(rec, REC_MASTERKEY, "(unknown)"); -+ util_rec_set(rec, REC_MASTERKEY, -+ "(unknown, MKVP: %016llx)", mkvp); - } - if (volumes_argz != NULL) - util_rec_set_argz(rec, REC_VOLUMES, volumes_argz, -@@ -2350,6 +2351,7 @@ static int _keystore_process_validate(st - u8 *secure_key; - int is_old_mk; - int rc, valid; -+ u64 mkvp; - - rc = _keystore_ensure_keyfiles_exist(file_names, name); - if (rc != 0) -@@ -2373,12 +2375,18 @@ static int _keystore_process_validate(st - info->num_valid++; - valid = 1; - } -+ -+ rc = get_master_key_verification_pattern(secure_key, secure_key_size, -+ &mkvp, keystore->verbose); - free(secure_key); -+ if (rc) -+ goto out; - - _keystore_print_record(info->rec, name, properties, 1, - file_names->skey_filename, secure_key_size, - clear_key_bitsize, valid, is_old_mk, -- _keystore_reencipher_key_exists(file_names)); -+ _keystore_reencipher_key_exists(file_names), -+ mkvp); - - if (valid && is_old_mk) { - util_print_indented("WARNING: The secure key is currently " -@@ -3131,7 +3139,7 @@ static int _keystore_display_key(struct - IS_XTS(secure_key_size) ? secure_key->bitsize * 2 - : secure_key->bitsize, - 0, 0, -- _keystore_reencipher_key_exists(file_names)); -+ _keystore_reencipher_key_exists(file_names), 0); - - out: - free(secure_key); ---- a/zkey/zkey-cryptsetup.c -+++ b/zkey/zkey-cryptsetup.c -@@ -1834,6 +1834,7 @@ static int command_validate(void) - char *prompt; - char *msg; - int token; -+ u64 mkvp; - int rc; - - util_asprintf(&prompt, "Enter passphrase for '%s': ", g.pos_arg); -@@ -1864,6 +1865,14 @@ static int command_validate(void) - vp_tok_avail = 1; - } - -+ rc = get_master_key_verification_pattern((u8 *)key, keysize, -+ &mkvp, g.verbose); -+ if (rc != 0) { -+ warnx("Failed to get the master key verification pattern: %s", -+ strerror(-rc)); -+ goto out; -+ } -+ - printf("Validation of secure volume key of device '%s':\n", g.pos_arg); - printf(" Status: %s\n", is_valid ? "Valid" : "Invalid"); - printf(" Secure key size: %lu bytes\n", keysize); -@@ -1871,11 +1880,12 @@ static int command_validate(void) - keysize > SECURE_KEY_SIZE ? "Yes" : "No"); - if (is_valid) { - printf(" Clear key size: %lu bits\n", clear_keysize); -- printf(" Enciphered with: %s CCA master key\n", -- is_old_mk ? "OLD" : "CURRENT"); -+ printf(" Enciphered with: %s CCA master key (MKVP: " -+ "%016llx)\n", is_old_mk ? "OLD" : "CURRENT", mkvp); - } else { - printf(" Clear key size: (unknown)\n"); -- printf(" Enciphered with: (unknown)\n"); -+ printf(" Enciphered with: (unknown, MKVP: %016llx)\n", -+ mkvp); - } - if (vp_tok_avail) - print_verification_pattern(vp_tok.verification_pattern); ---- a/zkey/zkey.c -+++ b/zkey/zkey.c -@@ -1300,6 +1300,7 @@ static int command_validate_file(void) - size_t clear_key_size; - u8 *secure_key; - int is_old_mk; -+ u64 mkvp; - int rc; - - if (g.name != NULL) { -@@ -1346,14 +1347,23 @@ static int command_validate_file(void) - goto out; - } - -+ rc = get_master_key_verification_pattern(secure_key, secure_key_size, -+ &mkvp, g.verbose); -+ if (rc != 0) { -+ warnx("Failed to get the master key verification pattern: %s", -+ strerror(-rc)); -+ rc = EXIT_FAILURE; -+ goto out; -+ } -+ - printf("Validation of secure key in file '%s':\n", g.pos_arg); - printf(" Status: Valid\n"); - printf(" Secure key size: %lu bytes\n", secure_key_size); - printf(" Clear key size: %lu bits\n", clear_key_size); - printf(" XTS type key: %s\n", - secure_key_size > SECURE_KEY_SIZE ? "Yes" : "No"); -- printf(" Enciphered with: %s CCA master key\n", -- is_old_mk ? "OLD" : "CURRENT"); -+ printf(" Enciphered with: %s CCA master key (MKVP: %016llx)\n", -+ is_old_mk ? "OLD" : "CURRENT", mkvp); - printf(" Verification pattern: %.*s\n", VERIFICATION_PATTERN_LEN / 2, - vp); - printf(" %.*s\n", VERIFICATION_PATTERN_LEN / 2, diff --git a/s390-tools-sles15sp2-10-zipl-stage3-Mark-start_kernel-__noreturn.patch b/s390-tools-sles15sp2-10-zipl-stage3-Mark-start_kernel-__noreturn.patch deleted file mode 100644 index c3c9b19..0000000 --- a/s390-tools-sles15sp2-10-zipl-stage3-Mark-start_kernel-__noreturn.patch +++ /dev/null @@ -1,49 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] zipl/stage3: Mark start_kernel __noreturn -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: edfb6a03d862e332223eda02be46109be12c0a4e -Problem-ID: VS1804 - -Upstream-Description: - - zipl/stage3: Mark start_kernel __noreturn - - Signed-off-by: Philipp Rudo - Reviewed-by: Stefan Haberland - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - zipl/boot/stage3.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/zipl/boot/stage3.c -+++ b/zipl/boot/stage3.c -@@ -175,8 +175,7 @@ static void ebcdic_to_ascii(unsigned cha - target[i] = ebc[source[i]]; - } - --static void --start_kernel(void) -+static inline void __noreturn start_kernel(void) - { - struct psw_t *psw = &S390_lowcore.program_new_psw; - unsigned long addr, code; -@@ -199,6 +198,7 @@ start_kernel(void) - : [addr] "=&d" (addr), - [code] "+&d" (code) - : [psw] "a" (psw) ); -+ while (1); - } - - unsigned int diff --git a/s390-tools-sles15sp2-10-zkey-Cross-check-APQNs-when-generating-secure-keys.patch b/s390-tools-sles15sp2-10-zkey-Cross-check-APQNs-when-generating-secure-keys.patch deleted file mode 100644 index 9433f76..0000000 --- a/s390-tools-sles15sp2-10-zkey-Cross-check-APQNs-when-generating-secure-keys.patch +++ /dev/null @@ -1,91 +0,0 @@ -Subject: zkey: Cross check APQNs when generating secure keys -From: Ingo Franzki - -Summary: zkey: check master key consistency -Description: Enhances the zkey tool to perform a cross check whether the - APQNs associated with a secure key have the same master key. - Display the master key verification pattern of a secure key - during the zkey validate command. This helps to better identify - which master key is the correct one, in case of master key - inconsistencies. - Select an appropriate APQN when re-enciphering a secure key. - Re-enciphering is done using the CCA host library. Special - handling is required to select an appropriate APQN for use with - the CCA host library. -Upstream-ID: a5b58038a0dbf1c3eb202a6933265f0d2e57e130 -Problem-ID: SEC1916 - -Upstream-Description: - - zkey: Cross check APQNs when generating secure keys - - Perform a cross check of the APQNs when a new secure AES key is - generated. When a set of APQNs are associated to a new secure key, - these APQNs are cross checked. If a new secure key is generated - outside of the key repository, or no APQNs are associated to a secure - key generated inside the key repository, then all currently available - APQNs are cross checked. If a master key mismatch is detected, then - the key generation is rejected. - - Signed-off-by: Ingo Franzki - Reviewed-by: Harald Freudenberger - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/keystore.c | 8 ++++++++ - zkey/zkey.c | 11 +++++++++++ - 2 files changed, 19 insertions(+) - ---- a/zkey/keystore.c -+++ b/zkey/keystore.c -@@ -1685,6 +1685,14 @@ int keystore_generate_key(struct keystor - if (rc != 0) - goto out_free_key_filenames; - -+ rc = cross_check_apqns(apqns, 0, true, keystore->verbose); -+ if (rc == -EINVAL) -+ goto out_free_key_filenames; -+ if (rc != 0 && rc != -ENOTSUP && noapqncheck == 0) { -+ warnx("Your master key setup is improper"); -+ goto out_free_key_filenames; -+ } -+ - rc = _keystore_get_card_domain(apqns, &card, &domain); - if (rc != 0) - goto out_free_key_filenames; ---- a/zkey/zkey.c -+++ b/zkey/zkey.c -@@ -31,6 +31,7 @@ - #include "keystore.h" - #include "misc.h" - #include "pkey.h" -+#include "utils.h" - - /* - * Program configuration -@@ -1060,6 +1061,8 @@ static int command_generate_repository(v - */ - static int command_generate(void) - { -+ int rc; -+ - if (g.pos_arg != NULL && g.name != NULL) { - warnx(" Option '--name|-N' is not valid for generating a key " - "outside of the repository"); -@@ -1100,6 +1103,14 @@ static int command_generate(void) - return EXIT_FAILURE; - } - -+ rc = cross_check_apqns(NULL, 0, true, g.verbose); -+ if (rc == -EINVAL) -+ return EXIT_FAILURE; -+ if (rc != 0 && rc != -ENOTSUP) { -+ warnx("Your master key setup is improper"); -+ return EXIT_FAILURE; -+ } -+ - return g.clearkeyfile ? command_generate_clear() - : command_generate_random(); - } diff --git a/s390-tools-sles15sp2-11-zipl-sclp-Remove-duplicate-macros.patch b/s390-tools-sles15sp2-11-zipl-sclp-Remove-duplicate-macros.patch deleted file mode 100644 index f97f970..0000000 --- a/s390-tools-sles15sp2-11-zipl-sclp-Remove-duplicate-macros.patch +++ /dev/null @@ -1,41 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] zipl/sclp: Remove duplicate macros -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: b2ae5a91ac16c5facb892dedc2dcb268eff07edf -Problem-ID: VS1804 - -Upstream-Description: - - zipl/sclp: Remove duplicate macros - - Signed-off-by: Philipp Rudo - Reviewed-by: Stefan Haberland - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - zipl/boot/sclp_stage3.h | 3 --- - 1 file changed, 3 deletions(-) - ---- a/zipl/boot/sclp_stage3.h -+++ b/zipl/boot/sclp_stage3.h -@@ -17,9 +17,6 @@ - #define SDIAS_EVSTATE_ALL_STORED 0x00 - #define SDIAS_EVSTATE_PART_STORED 0x10 - --#define SDIAS_EVSTATE_ALL_STORED 0x00 --#define SDIAS_EVSTATE_PART_STORED 0x10 -- - struct sdias_evbuf { - struct evbuf_header header; - uint8_t event_qual; diff --git a/s390-tools-sles15sp2-11-zkey-Cross-check-APQNs-when-validating-secure-keys.patch b/s390-tools-sles15sp2-11-zkey-Cross-check-APQNs-when-validating-secure-keys.patch deleted file mode 100644 index 4515d22..0000000 --- a/s390-tools-sles15sp2-11-zkey-Cross-check-APQNs-when-validating-secure-keys.patch +++ /dev/null @@ -1,123 +0,0 @@ -Subject: zkey: Cross check APQNs when validating secure keys -From: Ingo Franzki - -Summary: zkey: check master key consistency -Description: Enhances the zkey tool to perform a cross check whether the - APQNs associated with a secure key have the same master key. - Display the master key verification pattern of a secure key - during the zkey validate command. This helps to better identify - which master key is the correct one, in case of master key - inconsistencies. - Select an appropriate APQN when re-enciphering a secure key. - Re-enciphering is done using the CCA host library. Special - handling is required to select an appropriate APQN for use with - the CCA host library. -Upstream-ID: 7f8e31e8619b32297b432a4882d78af79de37a58 -Problem-ID: SEC1916 - -Upstream-Description: - - zkey: Cross check APQNs when validating secure keys - - Perform a cross check of the APQNs when a secure AES key is validated. - When a set of APQNs are associated to a secure key, these APQNs are - cross checked. If a secure key is validated outside of the key repository, - or no APQNs are associated to a secure key inside the key repository, - then all currently available APQNs are cross checked. If a master key - mismatch is detected, then an error message is issued. - - Signed-off-by: Ingo Franzki - Reviewed-by: Harald Freudenberger - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/keystore.c | 34 ++++++++++++---------------------- - zkey/zkey.c | 9 +++++++++ - 2 files changed, 21 insertions(+), 22 deletions(-) - ---- a/zkey/keystore.c -+++ b/zkey/keystore.c -@@ -2252,43 +2252,32 @@ struct validate_info { - /** - * Displays the status of the associated APQNs. - * -+ * @param[in] keystore the key store - * @param[in] properties the properties of the key -- * @param[in] name the name of the key -+ * @param[in] mkvp the master key verification pattern of the key - * - * @returns 0 in case of success, 1 if at least one of the APQNs is not -- * available -+ * available or has a master key mismatch - */ --static int _keystore_display_apqn_status(struct properties *properties, -- const char *name) -+static int _keystore_display_apqn_status(struct keystore *keystore, -+ struct properties *properties, -+ u64 mkvp) - { -- int i, rc, card, domain, warning = 0; -- char **apqn_list; -+ int rc, warning = 0; - char *apqns; - - apqns = properties_get(properties, PROP_NAME_APQNS); - if (apqns == NULL) - return 0; -- apqn_list = str_list_split(apqns); -- -- for (i = 0; apqn_list[i] != NULL; i++) { -- -- if (sscanf(apqn_list[i], "%x.%x", &card, &domain) != 2) -- continue; - -- rc = sysfs_is_apqn_online(card, domain); -- if (rc != 1) { -- printf("WARNING: The APQN %02x.%04x associated with " -- "key '%s' is %s\n", card, domain, name, -- rc == -1 ? "not a CCA card" : "not online"); -- warning = 1; -- } -- } -+ rc = cross_check_apqns(apqns, mkvp, true, keystore->verbose); -+ if (rc != 0 && rc != -ENOTSUP) -+ warning = 1; - - if (warning) - printf("\n"); - - free(apqns); -- str_list_free_string_array(apqn_list); - return warning; - } - /** -@@ -2405,7 +2394,8 @@ static int _keystore_process_validate(st - info->num_warnings++; - } - if (info->noapqncheck == 0) -- if (_keystore_display_apqn_status(properties, name) != 0) -+ if (_keystore_display_apqn_status(keystore, properties, -+ mkvp) != 0) - info->num_warnings++; - if (_keystore_display_volume_status(properties, name) != 0) - info->num_warnings++; ---- a/zkey/zkey.c -+++ b/zkey/zkey.c -@@ -1380,6 +1380,15 @@ static int command_validate_file(void) - printf(" %.*s\n", VERIFICATION_PATTERN_LEN / 2, - &vp[VERIFICATION_PATTERN_LEN / 2]); - -+ rc = cross_check_apqns(NULL, mkvp, true, g.verbose); -+ if (rc == -EINVAL) -+ return EXIT_FAILURE; -+ if (rc != 0 && rc != -ENOTSUP) { -+ warnx("Your master key setup is improper"); -+ rc = EXIT_FAILURE; -+ goto out; -+ } -+ - out: - free(secure_key); - return rc; diff --git a/s390-tools-sles15sp2-12-zipl-Make-address-size-mask-macros-UL.patch b/s390-tools-sles15sp2-12-zipl-Make-address-size-mask-macros-UL.patch deleted file mode 100644 index d8463f4..0000000 --- a/s390-tools-sles15sp2-12-zipl-Make-address-size-mask-macros-UL.patch +++ /dev/null @@ -1,116 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] zipl: Make address/size/mask macros UL -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: ea14f5471c6fbc9a8a407aa33324db39082b4689 -Problem-ID: VS1804 - -Upstream-Description: - - zipl: Make address/size/mask macros UL - - While at it also fix some white space damages. - - Signed-off-by: Philipp Rudo - Reviewed-by: Stefan Haberland - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - zipl/boot/stage3.h | 18 +++++++++--------- - zipl/include/zipl.h | 36 ++++++++++++++++++------------------ - 2 files changed, 27 insertions(+), 27 deletions(-) - ---- a/zipl/boot/stage3.h -+++ b/zipl/boot/stage3.h -@@ -15,12 +15,12 @@ - #include "libc.h" - #include "s390.h" - --#define IPL_DEVICE 0x10404 --#define INITRD_START 0x10408 --#define INITRD_SIZE 0x10410 --#define OLDMEM_BASE 0x10418 --#define OLDMEM_SIZE 0x10420 --#define COMMAND_LINE 0x10480 -+#define IPL_DEVICE 0x10404UL -+#define INITRD_START 0x10408UL -+#define INITRD_SIZE 0x10410UL -+#define OLDMEM_BASE 0x10418UL -+#define OLDMEM_SIZE 0x10420UL -+#define COMMAND_LINE 0x10480UL - #define COMMAND_LINE_SIZE 896 - #define COMMAND_LINE_EXTRA 0xE000 - -@@ -30,11 +30,11 @@ - #define IPL_FLAG_SECURE 0x40 - - #define DEFAULT_IMAGE_ADDR 0x10000 --#define DEFAULT_PSW_LOAD 0x0008000080010000L --#define PSW_ADDR_MASK 0x000000007FFFFFFFL -+#define DEFAULT_PSW_LOAD 0x0008000080010000UL -+#define PSW_ADDR_MASK 0x000000007FFFFFFFUL - #define KERNEL_HEADER_SIZE 65536 - --#define UNSPECIFIED_ADDRESS -1ULL -+#define UNSPECIFIED_ADDRESS -1UL - - - /* IPL Parameter List header */ ---- a/zipl/include/zipl.h -+++ b/zipl/include/zipl.h -@@ -19,27 +19,27 @@ - #define ZIPL_MAGIC_SIZE 4 - #define DISK_LAYOUT_ID 0x00000001 - --#define ZIPL_STAGE2_LOAD_ADDRESS 0x2000 --#define ZIPL_STAGE3_ENTRY_ADDRESS 0xa000LL --#define DEFAULT_IMAGE_ADDRESS 0x10000LL --#define KDUMP_IMAGE_ADDRESS 0x10010LL --#define DEFAULT_STAGE3_ADDRESS 0xa000LL --#define DEFAULT_STAGE3_PARAMS_ADDRESS 0x9000LL --#define MINIMUM_ADDRESS 0x10000LL --#define ADDRESS_LIMIT 0x80000000LL -+#define ZIPL_STAGE2_LOAD_ADDRESS 0x2000UL -+#define ZIPL_STAGE3_ENTRY_ADDRESS 0xa000UL -+#define DEFAULT_IMAGE_ADDRESS 0x10000UL -+#define KDUMP_IMAGE_ADDRESS 0x10010UL -+#define DEFAULT_STAGE3_ADDRESS 0xa000UL -+#define DEFAULT_STAGE3_PARAMS_ADDRESS 0x9000UL -+#define MINIMUM_ADDRESS 0x10000UL -+#define ADDRESS_LIMIT 0x80000000UL - #define ADDRESS_LIMIT_KDUMP 0x2000000UL /* HSA size: 32 MiB */ --#define UNSPECIFIED_ADDRESS -1ULL --#define MAXIMUM_PARMLINE_SIZE 0x380 --#define MAXIMUM_PHYSICAL_BLOCKSIZE 0x1000 -+#define UNSPECIFIED_ADDRESS -1UL -+#define MAXIMUM_PARMLINE_SIZE 0x380UL -+#define MAXIMUM_PHYSICAL_BLOCKSIZE 0x1000UL - --#define STAGE3_HEAP_SIZE 0x4000 --#define STAGE3_HEAP_ADDRESS 0x2000 --#define STAGE3_STACK_SIZE 0x1000 --#define STAGE3_STACK_ADDRESS 0xF000 -+#define STAGE3_HEAP_SIZE 0x4000UL -+#define STAGE3_HEAP_ADDRESS 0x2000UL -+#define STAGE3_STACK_SIZE 0x1000UL -+#define STAGE3_STACK_ADDRESS 0xF000UL - --#define PSW_ADDRESS_MASK 0x000000007fffffffLL --#define PSW_LOAD 0x0008000080000000LL --#define PSW_DISABLED_WAIT 0x000a000000000000LL -+#define PSW_ADDRESS_MASK 0x000000007fffffffUL -+#define PSW_LOAD 0x0008000080000000UL -+#define PSW_DISABLED_WAIT 0x000a000000000000UL - - #define BOOTMAP_FILENAME "bootmap" - #define BOOTMAP_TEMPLATE_FILENAME "bootmap_temp.XXXXXX" diff --git a/s390-tools-sles15sp2-12-zkey-Cross-check-APQNs-when-importing-secure-keys.patch b/s390-tools-sles15sp2-12-zkey-Cross-check-APQNs-when-importing-secure-keys.patch deleted file mode 100644 index 9afe279..0000000 --- a/s390-tools-sles15sp2-12-zkey-Cross-check-APQNs-when-importing-secure-keys.patch +++ /dev/null @@ -1,85 +0,0 @@ -Subject: zkey: Cross check APQNs when importing secure keys -From: Ingo Franzki - -Summary: zkey: check master key consistency -Description: Enhances the zkey tool to perform a cross check whether the - APQNs associated with a secure key have the same master key. - Display the master key verification pattern of a secure key - during the zkey validate command. This helps to better identify - which master key is the correct one, in case of master key - inconsistencies. - Select an appropriate APQN when re-enciphering a secure key. - Re-enciphering is done using the CCA host library. Special - handling is required to select an appropriate APQN for use with - the CCA host library. -Upstream-ID: d854aed4b8154e7420def8749db2106a049dd80a -Problem-ID: SEC1916 - -Upstream-Description: - - zkey: Cross check APQNs when importing secure keys - - Perform a cross check of the APQNs when an existing secure AES key is - imported into the key repository. When a set of APQNs are associated to - the imported secure key, these APQNs are cross checked. If no APQNs are - associated to imported secure key, then all currently available - APQNs are cross checked. If a master key mismatch is detected, then - the key import is rejected. - - Signed-off-by: Ingo Franzki - Reviewed-by: Harald Freudenberger - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/keystore.c | 21 +++++++++++++++++++++ - 1 file changed, 21 insertions(+) - ---- a/zkey/keystore.c -+++ b/zkey/keystore.c -@@ -1770,6 +1770,7 @@ int keystore_import_key(struct keystore - struct properties *key_props = NULL; - size_t secure_key_size; - u8 *secure_key; -+ u64 mkvp; - int rc; - - util_assert(keystore != NULL, "Internal error: keystore is NULL"); -@@ -1791,9 +1792,26 @@ int keystore_import_key(struct keystore - goto out_free_key_filenames; - } - -+ rc = get_master_key_verification_pattern(secure_key, secure_key_size, -+ &mkvp, keystore->verbose); -+ if (rc != 0) { -+ warnx("Failed to get the master key verification pattern: %s", -+ strerror(-rc)); -+ goto out_free_key; -+ } -+ -+ rc = cross_check_apqns(apqns, mkvp, true, keystore->verbose); -+ if (rc == -EINVAL) -+ goto out_free_key; -+ if (rc != 0 && rc != -ENOTSUP && noapqncheck == 0) { -+ warnx("Your master key setup is improper"); -+ goto out_free_key; -+ } -+ - rc = write_secure_key(file_names.skey_filename, secure_key, - secure_key_size, keystore->verbose); - free(secure_key); -+ secure_key = NULL; - if (rc != 0) - goto out_free_props; - -@@ -1811,6 +1829,9 @@ int keystore_import_key(struct keystore - "Successfully imported a secure key in '%s' and key info in '%s'", - file_names.skey_filename, file_names.info_filename); - -+out_free_key: -+ if (secure_key != NULL) -+ free(secure_key); - out_free_props: - if (key_props != NULL) - properties_free(key_props); diff --git a/s390-tools-sles15sp2-13-zipl-libc-Use-stdint.h-instead-of-self-defined-macro.patch b/s390-tools-sles15sp2-13-zipl-libc-Use-stdint.h-instead-of-self-defined-macro.patch deleted file mode 100644 index 26ace63..0000000 --- a/s390-tools-sles15sp2-13-zipl-libc-Use-stdint.h-instead-of-self-defined-macro.patch +++ /dev/null @@ -1,52 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] zipl/libc: Use stdint.h instead of self defined macros -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: 8face3e63ed88443392bcbcd93cc0b5e29b40069 -Problem-ID: VS1804 - -Upstream-Description: - - zipl/libc: Use stdint.h instead of self defined macros - - Signed-off-by: Philipp Rudo - Reviewed-by: Stefan Haberland - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - zipl/boot/libc.h | 7 ++----- - 1 file changed, 2 insertions(+), 5 deletions(-) - ---- a/zipl/boot/libc.h -+++ b/zipl/boot/libc.h -@@ -11,6 +11,8 @@ - #ifndef LIBC_H - #define LIBC_H - -+#include -+ - #define NULL ((void *) 0) - - #define EPERM 1 /* Operation not permitted */ -@@ -42,11 +44,6 @@ - #define MIB (1024ULL * 1024) - #define LINE_LENGTH 80 /* max line length printed by printf */ - --typedef unsigned long long uint64_t; --typedef unsigned int uint32_t; --typedef unsigned short uint16_t; --typedef unsigned char uint8_t; -- - void printf(const char *, ...); - void snprintf(char *buf, unsigned long size, const char *fmt, ...); - void *memcpy(void *, const void *, unsigned long); diff --git a/s390-tools-sles15sp2-13-zkey-Cross-check-APQNs-when-changing-APQN-associatio.patch b/s390-tools-sles15sp2-13-zkey-Cross-check-APQNs-when-changing-APQN-associatio.patch deleted file mode 100644 index f78244b..0000000 --- a/s390-tools-sles15sp2-13-zkey-Cross-check-APQNs-when-changing-APQN-associatio.patch +++ /dev/null @@ -1,86 +0,0 @@ -Subject: zkey: Cross check APQNs when changing APQN associations -From: Ingo Franzki - -Summary: zkey: check master key consistency -Description: Enhances the zkey tool to perform a cross check whether the - APQNs associated with a secure key have the same master key. - Display the master key verification pattern of a secure key - during the zkey validate command. This helps to better identify - which master key is the correct one, in case of master key - inconsistencies. - Select an appropriate APQN when re-enciphering a secure key. - Re-enciphering is done using the CCA host library. Special - handling is required to select an appropriate APQN for use with - the CCA host library. -Upstream-ID: 0b4cbf00412f27456d28ff7f86ec5335a39e3416 -Problem-ID: SEC1916 - -Upstream-Description: - - zkey: Cross check APQNs when changing APQN associations - - Perform a cross check of the APQNs when the APQN association of a - secure AES key in the key repository is changed. When adding new APQNs, - or associating a new set of APQNs to a secure key, then the APQNs are - cross checked. If all associated APQNs are removed, then all currently - available APQNs are cross checked. If a master key mismatch is detected, - then the change is rejected. - - Signed-off-by: Ingo Franzki - Reviewed-by: Harald Freudenberger - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/keystore.c | 31 +++++++++++++++++++++++++++++++ - 1 file changed, 31 insertions(+) - ---- a/zkey/keystore.c -+++ b/zkey/keystore.c -@@ -1886,7 +1886,11 @@ int keystore_change_key(struct keystore - .nomsg = 0 }; - struct key_filenames file_names = { NULL, NULL, NULL }; - struct properties *key_props = NULL; -+ size_t secure_key_size; -+ char *apqns_prop; -+ u8 *secure_key; - char temp[30]; -+ u64 mkvp; - int rc; - - util_assert(keystore != NULL, "Internal error: keystore is NULL"); -@@ -1932,6 +1936,33 @@ int keystore_change_key(struct keystore - &apqn_check); - if (rc != 0) - goto out; -+ -+ secure_key = read_secure_key(file_names.skey_filename, -+ &secure_key_size, -+ keystore->verbose); -+ if (secure_key == NULL) { -+ rc = -ENOENT; -+ goto out; -+ } -+ -+ rc = get_master_key_verification_pattern(secure_key, -+ secure_key_size, -+ &mkvp, -+ keystore->verbose); -+ free(secure_key); -+ if (rc) -+ goto out; -+ -+ apqns_prop = properties_get(key_props, PROP_NAME_APQNS); -+ rc = cross_check_apqns(apqns_prop, mkvp, true, -+ keystore->verbose); -+ free(apqns_prop); -+ if (rc == -ENOTSUP) -+ rc = 0; -+ if (rc != 0 && noapqncheck == 0) { -+ warnx("Your master key setup is improper"); -+ goto out; -+ } - } - - if (sector_size >= 0) { diff --git a/s390-tools-sles15sp2-14-zipl-Consolidate-IMAGE-macros.patch b/s390-tools-sles15sp2-14-zipl-Consolidate-IMAGE-macros.patch deleted file mode 100644 index 70ae946..0000000 --- a/s390-tools-sles15sp2-14-zipl-Consolidate-IMAGE-macros.patch +++ /dev/null @@ -1,199 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] zipl: Consolidate IMAGE macros -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: cb614ed1ee61f05fb521a7e3ac0d27eb2eb45672 -Problem-ID: VS1804 - -Upstream-Description: - - zipl: Consolidate IMAGE macros - - Combine the different macros for 0x10000 and use a consistent naming - schema. - - Signed-off-by: Philipp Rudo - Reviewed-by: Stefan Haberland - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - zipl/boot/stage3.c | 7 ++++--- - zipl/boot/stage3.h | 2 -- - zipl/include/zipl.h | 8 +++++--- - zipl/src/bootmap.c | 8 ++++---- - zipl/src/job.c | 17 +++++++++-------- - 5 files changed, 22 insertions(+), 20 deletions(-) - ---- a/zipl/boot/stage3.c -+++ b/zipl/boot/stage3.c -@@ -13,6 +13,7 @@ - #include "s390.h" - #include "stage3.h" - #include "error.h" -+#include "zipl.h" - - #define for_each_rb_entry(entry, rb) \ - for (entry = rb->entries; \ -@@ -272,7 +273,7 @@ void start(void) - * verified component. If it is not IPL is aborted. - */ - if (secure_boot_enabled()) { -- if (_image_addr != DEFAULT_IMAGE_ADDR || -+ if (_image_addr != IMAGE_LOAD_ADDRESS || - _load_psw != DEFAULT_PSW_LOAD) - panic(ESECUREBOOT, "%s", msg_sipl_inval); - -@@ -283,8 +284,8 @@ void start(void) - * cut the kernel header - */ - memmove((void *)_image_addr, -- (void *)_image_addr + KERNEL_HEADER_SIZE, -- _image_len - KERNEL_HEADER_SIZE); -+ (void *)_image_addr + IMAGE_LOAD_ADDRESS, -+ _image_len - IMAGE_LOAD_ADDRESS); - - /* store subchannel ID into low core and into new kernel space */ - subchannel_id = S390_lowcore.subchannel_id; ---- a/zipl/boot/stage3.h -+++ b/zipl/boot/stage3.h -@@ -29,10 +29,8 @@ - - #define IPL_FLAG_SECURE 0x40 - --#define DEFAULT_IMAGE_ADDR 0x10000 - #define DEFAULT_PSW_LOAD 0x0008000080010000UL - #define PSW_ADDR_MASK 0x000000007FFFFFFFUL --#define KERNEL_HEADER_SIZE 65536 - - #define UNSPECIFIED_ADDRESS -1UL - ---- a/zipl/include/zipl.h -+++ b/zipl/include/zipl.h -@@ -19,13 +19,15 @@ - #define ZIPL_MAGIC_SIZE 4 - #define DISK_LAYOUT_ID 0x00000001 - -+#define IMAGE_ENTRY 0x10000UL -+#define IMAGE_ENTRY_KDUMP 0x10010UL -+ - #define ZIPL_STAGE2_LOAD_ADDRESS 0x2000UL - #define ZIPL_STAGE3_ENTRY_ADDRESS 0xa000UL --#define DEFAULT_IMAGE_ADDRESS 0x10000UL --#define KDUMP_IMAGE_ADDRESS 0x10010UL - #define DEFAULT_STAGE3_ADDRESS 0xa000UL - #define DEFAULT_STAGE3_PARAMS_ADDRESS 0x9000UL --#define MINIMUM_ADDRESS 0x10000UL -+#define IMAGE_LOAD_ADDRESS IMAGE_ENTRY -+ - #define ADDRESS_LIMIT 0x80000000UL - #define ADDRESS_LIMIT_KDUMP 0x2000000UL /* HSA size: 32 MiB */ - #define UNSPECIFIED_ADDRESS -1UL ---- a/zipl/src/bootmap.c -+++ b/zipl/src/bootmap.c -@@ -644,8 +644,8 @@ add_ipl_program(int fd, struct job_ipl_d - rc = boot_get_stage3_parms(&stage3_params, &stage3_params_size, - ipl->parm_addr, ipl->ramdisk_addr, - ramdisk_size, -- ipl->is_kdump ? ipl->image_addr + 0x10 : -- ipl->image_addr, -+ ipl->is_kdump ? IMAGE_ENTRY_KDUMP : -+ IMAGE_ENTRY, - (info->type == disk_type_scsi) ? 0 : 1, - flags, ipl->image_addr, image_size); - if (rc) { -@@ -1187,7 +1187,7 @@ bootmap_create(struct job_data *job, dis - ulong unused_size; - - /* Use approximated stage 3 size as starting point */ -- size = MINIMUM_ADDRESS; -+ size = IMAGE_LOAD_ADDRESS; - - /* Ramdisk */ - if (job->data.dump.ramdisk != NULL) { -@@ -1199,7 +1199,7 @@ bootmap_create(struct job_data *job, dis - /* Kernel */ - if (stat(job->data.dump.image, &st)) - goto out_misc_free_temp_dev; -- size += DIV_ROUND_UP(st.st_size - 0x10000, -+ size += DIV_ROUND_UP(st.st_size - IMAGE_LOAD_ADDRESS, - info->phy_block_size); - /* Parmfile */ - size += DIV_ROUND_UP(DUMP_PARAM_MAX_LEN, info->phy_block_size); ---- a/zipl/src/job.c -+++ b/zipl/src/job.c -@@ -23,6 +23,7 @@ - #include "job.h" - #include "misc.h" - #include "scan.h" -+#include "zipl.h" - - /* Command line options */ - static struct option options[] = { -@@ -663,12 +664,12 @@ check_component_address_data(struct comp - address_limit); - return -1; - } -- if (*cl[i].addrp < MINIMUM_ADDRESS) { -+ if (*cl[i].addrp < IMAGE_LOAD_ADDRESS) { - if (name != NULL) - error_text("Section '%s'", name); - error_reason("Component '%s' falls below available " - "address space (limit is 0x%08x)", -- cl[i].name, MINIMUM_ADDRESS); -+ cl[i].name, IMAGE_LOAD_ADDRESS); - return -1; - } - } -@@ -706,12 +707,12 @@ finalize_component_address_data(struct c - for (j = -1; j < i; j++) { - if (j < 0) { - /* Try address before first component */ -- addr = MINIMUM_ADDRESS; -+ addr = IMAGE_LOAD_ADDRESS; - } else { - /* Try address after component j */ - addr = *cl[j].addrp + cl[j].size; -- if (addr < MINIMUM_ADDRESS) -- addr = MINIMUM_ADDRESS; -+ if (addr < IMAGE_LOAD_ADDRESS) -+ addr = IMAGE_LOAD_ADDRESS; - } - addr = ALIGN(addr, cl[i].align); - if (addr + cl[i].size > address_limit) { -@@ -905,7 +906,7 @@ check_job_dump_images(struct job_dump_da - dump->image = misc_strdup(ZFCPDUMP_IMAGE); - if (dump->image == NULL) - return -1; -- dump->image_addr = DEFAULT_IMAGE_ADDRESS; -+ dump->image_addr = IMAGE_LOAD_ADDRESS; - - /* Ramdisk is no longer required with new initramfs dump system */ - if (misc_check_readable_file(ZFCPDUMP_INITRD)) -@@ -1351,7 +1352,7 @@ get_job_from_section_data(char* data[], - return -1; - if (extract_address(job->data.ipl.image, - &job->data.ipl.image_addr)) { -- job->data.ipl.image_addr = DEFAULT_IMAGE_ADDRESS; -+ job->data.ipl.image_addr = IMAGE_LOAD_ADDRESS; - } - /* Fill in parmline */ - rc = get_parmline(data[(int) scan_keyword_parmfile], -@@ -1406,7 +1407,7 @@ get_job_from_section_data(char* data[], - return -1; - if (extract_address(job->data.ipl_tape.image, - &job->data.ipl_tape.image_addr)) { -- job->data.ipl_tape.image_addr = DEFAULT_IMAGE_ADDRESS; -+ job->data.ipl_tape.image_addr = IMAGE_LOAD_ADDRESS; - } - /* Fill in parmline */ - rc = get_parmline(data[(int) scan_keyword_parmfile], diff --git a/s390-tools-sles15sp2-14-zkey-Add-function-to-select-a-specific-CCA-adapter.patch b/s390-tools-sles15sp2-14-zkey-Add-function-to-select-a-specific-CCA-adapter.patch deleted file mode 100644 index 5a208f2..0000000 --- a/s390-tools-sles15sp2-14-zkey-Add-function-to-select-a-specific-CCA-adapter.patch +++ /dev/null @@ -1,455 +0,0 @@ -Subject: zkey: Add function to select a specific CCA adapter -From: Ingo Franzki - -Summary: zkey: check master key consistency -Description: Enhances the zkey tool to perform a cross check whether the - APQNs associated with a secure key have the same master key. - Display the master key verification pattern of a secure key - during the zkey validate command. This helps to better identify - which master key is the correct one, in case of master key - inconsistencies. - Select an appropriate APQN when re-enciphering a secure key. - Re-enciphering is done using the CCA host library. Special - handling is required to select an appropriate APQN for use with - the CCA host library. -Upstream-ID: 016a0a56fcb3dd0bf8bed693e5d64873f6288995 -Problem-ID: SEC1916 - -Upstream-Description: - - zkey: Add function to select a specific CCA adapter - - Some operations require the CCA host library to be used, such as - re-enciphering a secure key. The CCA host library uses a different - approach to select the APQN it operates with. To ensure that the - desired APQN is used for an operation, a utility function is added - to select a specific APQN for usage with the CCA host library. - - The CCA host library allows to set environment variables to override - the default CCA APQN selection. The environment variables are inspected - during CCA host library initialization only. To select a specific - domain for CCA, the CSU_DEFAULT_DOMAIN environment variable is set, - and then the CCA host library is un-loaded and re-loaded again. - Furthermore, the 'Cryptographic Resource Allocate' verb of the CCA - host library is used together with the 'Cryptographic Facility Query - function' verb to iterate over the crypto cards known by the CCA host - library, and to identify the desired crypto card based on its serial - number. That way, a specific APQN can be selected for use with - subsequent CCA verbs. - - Signed-off-by: Ingo Franzki - Reviewed-by: Harald Freudenberger - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/Makefile | 4 - zkey/cca.c | 296 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- - zkey/cca.h | 32 ++++++ - 3 files changed, 329 insertions(+), 3 deletions(-) - ---- a/zkey/Makefile -+++ b/zkey/Makefile -@@ -66,7 +66,7 @@ all: $(BUILD_TARGETS) - - zkey.o: zkey.c pkey.h cca.h misc.h - pkey.o: pkey.c pkey.h --cca.o: cca.c cca.h pkey.h -+cca.o: cca.c cca.h pkey.h utils.h - utils.o: utils.h - properties.o: check-dep-zkey properties.c properties.h - keystore.o: keystore.c keystore.h properties.h pkey.h cca.h utils.h -@@ -77,7 +77,7 @@ zkey: zkey.o pkey.o cca.o properties.o k - $(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@ - - zkey-cryptsetup: LDLIBS = -ldl -lcryptsetup -ljson-c --zkey-cryptsetup: zkey-cryptsetup.o pkey.o cca.o $(libs) -+zkey-cryptsetup: zkey-cryptsetup.o pkey.o cca.o utils.o $(libs) - $(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@ - - install-common: ---- a/zkey/cca.c -+++ b/zkey/cca.c -@@ -12,6 +12,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -21,6 +22,7 @@ - - #include "cca.h" - #include "pkey.h" -+#include "utils.h" - - #define pr_verbose(verbose, fmt...) do { \ - if (verbose) \ -@@ -32,6 +34,8 @@ - */ - #define CCA_LIBRARY_NAME "libcsulcca.so" - #define CCA_WEB_PAGE "http://www.ibm.com/security/cryptocards" -+#define CCA_DOMAIN_ENVAR "CSU_DEFAULT_DOMAIN" -+#define CCA_ADAPTER_ENVAR "CSU_DEFAULT_ADAPTER" - - /** - * Prints CCA return and reason code information for certain known CCA -@@ -136,8 +140,20 @@ int load_cca_library(struct cca_lib *cca - /* Get the Key Token Change function */ - cca->dll_CSNBKTC = (t_CSNBKTC)dlsym(cca->lib_csulcca, "CSNBKTC"); - -+ /* Get the Cryptographic Facility Query function */ -+ cca->dll_CSUACFQ = (t_CSUACFQ)dlsym(cca->lib_csulcca, "CSUACFQ"); -+ -+ /* Get the Cryptographic Resource Allocate function */ -+ cca->dll_CSUACRA = (t_CSUACRA)dlsym(cca->lib_csulcca, "CSUACRA"); -+ -+ /* Cryptographic Resource Deallocate function */ -+ cca->dll_CSUACRD = (t_CSUACRD)dlsym(cca->lib_csulcca, "CSUACRD"); -+ - if (cca->dll_CSUACFV == NULL || -- cca->dll_CSNBKTC == NULL) { -+ cca->dll_CSNBKTC == NULL || -+ cca->dll_CSUACFQ == NULL || -+ cca->dll_CSUACRA == NULL || -+ cca->dll_CSUACRD == NULL) { - pr_verbose(verbose, "%s", dlerror()); - warnx("The command requires the IBM CCA Host Libraries and " - "Tools.\nFor the supported environments and downloads, " -@@ -213,3 +229,281 @@ int key_token_change(struct cca_lib *cca - } - return 0; - } -+ -+/** -+ * Queries the number of adapters known by the CCA host library -+ * -+ * @param[in] cca the CCA library structure -+ * @param[out] adapters the number of adapters -+ * @param[in] verbose if true, verbose messages are printed -+ * -+ * @returns 0 on success, a negative errno in case of an error. -+ */ -+static int get_number_of_cca_adapters(struct cca_lib *cca, -+ unsigned int *adapters, bool verbose) -+{ -+ long exit_data_len = 0, rule_array_count, verb_data_length = 0; -+ unsigned char rule_array[16 * 8] = { 0, }; -+ unsigned char exit_data[4] = { 0, }; -+ long return_code, reason_code; -+ -+ util_assert(cca != NULL, "Internal error: cca is NULL"); -+ util_assert(adapters != NULL, "Internal error: adapters is NULL"); -+ -+ memset(rule_array, 0, sizeof(rule_array)); -+ memcpy(rule_array, "STATCRD2", 8); -+ rule_array_count = 1; -+ -+ cca->dll_CSUACFQ(&return_code, &reason_code, -+ &exit_data_len, exit_data, -+ &rule_array_count, rule_array, -+ &verb_data_length, NULL); -+ -+ pr_verbose(verbose, "CSUACFQ (Cryptographic Facility Query) returned: " -+ "return_code: %ld, reason_code: %ld", return_code, -+ reason_code); -+ if (return_code != 0) { -+ print_CCA_error(return_code, reason_code); -+ return -EIO; -+ } -+ -+ rule_array[8] = '\0'; -+ if (sscanf((char *)rule_array, "%u", adapters) != 1) { -+ pr_verbose(verbose, "Unparsable output: %s", rule_array); -+ return -EIO; -+ } -+ -+ pr_verbose(verbose, "Number of CCA adapters: %u", *adapters); -+ return 0; -+} -+ -+/** -+ * Allocate a specific CCA adapter. -+ * -+ * @param[in] cca the CCA library structure -+ * @param[in] adapter the adapter number, starting at 1. If 0 is -+ * specified, then the AUTOSELECT option is -+ * enabled. -+ * @param[in] verbose if true, verbose messages are printed -+ * -+ * @returns 0 on success, a negative errno in case of an error. -ENODEV is -+ * returned if the adapter is not available. -+ */ -+static int allocate_cca_adapter(struct cca_lib *cca, unsigned int adapter, -+ bool verbose) -+{ -+ long exit_data_len = 0, rule_array_count; -+ unsigned char rule_array[8] = { 0, }; -+ unsigned char exit_data[4] = { 0, }; -+ long return_code, reason_code; -+ char res_name[9]; -+ long res_name_len; -+ -+ util_assert(cca != NULL, "Internal error: cca is NULL"); -+ -+ if (adapter > 0) -+ memcpy(rule_array, "DEVICE ", 8); -+ else -+ memcpy(rule_array, "DEV-ANY ", 8); -+ rule_array_count = 1; -+ -+ sprintf(res_name, "CRP%02d", adapter); -+ res_name_len = strlen(res_name); -+ -+ cca->dll_CSUACRA(&return_code, &reason_code, -+ &exit_data_len, exit_data, -+ &rule_array_count, rule_array, -+ &res_name_len, (unsigned char *)res_name); -+ -+ pr_verbose(verbose, "CSUACRA (Cryptographic Resource Allocate) " -+ "returned: return_code: %ld, reason_code: %ld", return_code, -+ reason_code); -+ if (return_code != 0) { -+ print_CCA_error(return_code, reason_code); -+ return -ENODEV; -+ } -+ -+ pr_verbose(verbose, "Adapter %u (%s) allocated", adapter, res_name); -+ return 0; -+} -+ -+/** -+ * Deallocate a specific CCA adapter. -+ * -+ * @param[in] cca the CCA library structure -+ * @param[in] adapter the adapter number, starting at 1. If 0 is -+ * specified, then the AUTOSELECT option is -+ * disabled. -+ * @param[in] verbose if true, verbose messages are printed -+ * -+ * @returns 0 on success, a negative errno in case of an error. -ENODEV is -+ * returned if the adapter is not available. -+ */ -+static int deallocate_cca_adapter(struct cca_lib *cca, unsigned int adapter, -+ bool verbose) -+{ -+ long exit_data_len = 0, rule_array_count; -+ unsigned char rule_array[8] = { 0, }; -+ unsigned char exit_data[4] = { 0, }; -+ long return_code, reason_code; -+ char res_name[9]; -+ long res_name_len; -+ -+ util_assert(cca != NULL, "Internal error: cca is NULL"); -+ -+ if (adapter > 0) -+ memcpy(rule_array, "DEVICE ", 8); -+ else -+ memcpy(rule_array, "DEV-ANY ", 8); -+ rule_array_count = 1; -+ -+ sprintf(res_name, "CRP%02d", adapter); -+ res_name_len = strlen(res_name); -+ -+ cca->dll_CSUACRD(&return_code, &reason_code, -+ &exit_data_len, exit_data, -+ &rule_array_count, rule_array, -+ &res_name_len, (unsigned char *)res_name); -+ -+ pr_verbose(verbose, "CSUACRD (Cryptographic Resource Deallocate) " -+ "returned: return_code: %ld, reason_code: %ld", return_code, -+ reason_code); -+ if (return_code != 0) { -+ print_CCA_error(return_code, reason_code); -+ return -ENODEV; -+ } -+ -+ pr_verbose(verbose, "Adapter %u (%s) deallocated", adapter, res_name); -+ return 0; -+} -+ -+/** -+ * Queries the serial number of the current CCA adapter -+ * -+ * @param[in] cca the CCA library structure -+ * @param[out] serialnr the buffer where the serial number is returned -+ * @param[in] verbose if true, verbose messages are printed -+ * -+ * @returns 0 on success, a negative errno in case of an error. -+ */ -+static int get_cca_adapter_serialnr(struct cca_lib *cca, char serialnr[9], -+ bool verbose) -+{ -+ long exit_data_len = 0, rule_array_count, verb_data_length = 0; -+ unsigned char rule_array[16 * 8] = { 0, }; -+ unsigned char exit_data[4] = { 0, }; -+ long return_code, reason_code; -+ -+ util_assert(cca != NULL, "Internal error: cca is NULL"); -+ -+ memset(rule_array, 0, sizeof(rule_array)); -+ memcpy(rule_array, "STATCRD2", 8); -+ rule_array_count = 1; -+ -+ cca->dll_CSUACFQ(&return_code, &reason_code, -+ &exit_data_len, exit_data, -+ &rule_array_count, rule_array, -+ &verb_data_length, NULL); -+ -+ pr_verbose(verbose, "CSUACFQ (Cryptographic Facility Query) returned: " -+ "return_code: %ld, reason_code: %ld", return_code, -+ reason_code); -+ if (return_code != 0) { -+ print_CCA_error(return_code, reason_code); -+ return -EIO; -+ } -+ -+ memcpy(serialnr, rule_array+14*8, 8); -+ serialnr[8] = '\0'; -+ -+ pr_verbose(verbose, "Serial number of CCA adapter: %s", serialnr); -+ return 0; -+} -+ -+/** -+ * Selects the specified APQN to be used for the CCA host library. -+ * -+ * @param[in] cca the CCA library structure -+ * @param[in] card the card number -+ * @param[in] domain the domain number -+ * @param[in] verbose if true, verbose messages are printed -+ * -+ * @returns 0 on success, a negative errno in case of an error. -ENOTSUP is -+ * returned when the serialnr sysfs attribute is not available, -+ * because the zcrypt kernel module is on an older level. -ENODEV is -+ * returned if the APQN is not available. -+ */ -+int select_cca_adapter(struct cca_lib *cca, int card, int domain, bool verbose) -+{ -+ unsigned int adapters, adapter; -+ char adapter_serialnr[9]; -+ char apqn_serialnr[9]; -+ char temp[10]; -+ int rc, found = 0; -+ -+ util_assert(cca != NULL, "Internal error: cca is NULL"); -+ -+ pr_verbose(verbose, "Select %02x.%04x for the CCA host library", card, -+ domain); -+ -+ rc = sysfs_get_serialnr(card, apqn_serialnr, verbose); -+ if (rc != 0) { -+ pr_verbose(verbose, "Failed to get the serial number: %s", -+ strerror(-rc)); -+ return rc; -+ } -+ -+ sprintf(temp, "%u", domain); -+ if (setenv(CCA_DOMAIN_ENVAR, temp, 1) != 0) { -+ rc = -errno; -+ pr_verbose(verbose, "Failed to set the %s environment variable:" -+ " %s", CCA_DOMAIN_ENVAR, strerror(-rc)); -+ return rc; -+ } -+ unsetenv(CCA_ADAPTER_ENVAR); -+ -+ /* -+ * Unload and reload the CCA host library so that it recognizes the -+ * changed CSU_DEFAULT_DOMAIN environment variable value. -+ */ -+ if (cca->lib_csulcca != NULL) -+ dlclose(cca->lib_csulcca); -+ memset(cca, 0, sizeof(struct cca_lib)); -+ -+ rc = load_cca_library(cca, verbose); -+ if (rc != 0) -+ return rc; -+ -+ rc = get_number_of_cca_adapters(cca, &adapters, verbose); -+ if (rc != 0) -+ return rc; -+ -+ /* Disable the AUTOSELECT option */ -+ rc = deallocate_cca_adapter(cca, 0, verbose); -+ if (rc != 0) -+ return rc; -+ -+ for (adapter = 1; adapter <= adapters; adapter++) { -+ rc = allocate_cca_adapter(cca, adapter, verbose); -+ if (rc != 0) -+ return rc; -+ -+ rc = get_cca_adapter_serialnr(cca, adapter_serialnr, verbose); -+ if (rc == 0) { -+ if (memcmp(apqn_serialnr, adapter_serialnr, 8) == 0) { -+ found = 1; -+ break; -+ } -+ } -+ -+ rc = deallocate_cca_adapter(cca, adapter, verbose); -+ if (rc != 0) -+ return rc; -+ } -+ -+ if (!found) -+ return -ENODEV; -+ -+ pr_verbose(verbose, "Selected adapter %u (CRP%02d)", adapter, adapter); -+ return 0; -+} ---- a/zkey/cca.h -+++ b/zkey/cca.h -@@ -32,6 +32,33 @@ typedef void (*t_CSUACFV)(long *return_c - long *version_data_length, - unsigned char *version_data); - -+typedef void (*t_CSUACFQ)(long *return_code, -+ long *reason_code, -+ long *exit_data_length, -+ unsigned char *exit_data, -+ long *rule_array_count, -+ unsigned char *rule_array, -+ long *verb_data_length, -+ unsigned char *verb_data); -+ -+typedef void (*t_CSUACRA)(long *return_code, -+ long *reason_code, -+ long *exit_data_length, -+ unsigned char *exit_data, -+ long *rule_array_count, -+ unsigned char *rule_array, -+ long *ressource_name_length, -+ unsigned char *ressource_name); -+ -+typedef void (*t_CSUACRD)(long *return_code, -+ long *reason_code, -+ long *exit_data_length, -+ unsigned char *exit_data, -+ long *rule_array_count, -+ unsigned char *rule_array, -+ long *ressource_name_length, -+ unsigned char *ressource_name); -+ - struct cca_version { - unsigned int ver; - unsigned int rel; -@@ -42,6 +69,9 @@ struct cca_lib { - void *lib_csulcca; - t_CSNBKTC dll_CSNBKTC; - t_CSUACFV dll_CSUACFV; -+ t_CSUACFQ dll_CSUACFQ; -+ t_CSUACRA dll_CSUACRA; -+ t_CSUACRD dll_CSUACRD; - struct cca_version version; - }; - -@@ -51,4 +81,6 @@ int key_token_change(struct cca_lib *cca - u8 *secure_key, unsigned int secure_key_size, - char *method, bool verbose); - -+int select_cca_adapter(struct cca_lib *cca, int card, int domain, bool verbose); -+ - #endif diff --git a/s390-tools-sles15sp2-15-zipl-Consolidate-STAGE-2-3-macros.patch b/s390-tools-sles15sp2-15-zipl-Consolidate-STAGE-2-3-macros.patch deleted file mode 100644 index 2cd33c5..0000000 --- a/s390-tools-sles15sp2-15-zipl-Consolidate-STAGE-2-3-macros.patch +++ /dev/null @@ -1,110 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] zipl: Consolidate STAGE{2,3} macros -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: 4762e65acbc4efe7142ccb5fd2ef86073737ebd8 -Problem-ID: VS1804 - -Upstream-Description: - - zipl: Consolidate STAGE{2,3} macros - - Increase consistency with the other macros by moving and renaming - the STAGE{2,3} macros in zipl.h. - - Signed-off-by: Philipp Rudo - Reviewed-by: Stefan Haberland - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - zipl/include/zipl.h | 8 ++++---- - zipl/src/boot.c | 4 ++-- - zipl/src/bootmap.c | 6 +++--- - 3 files changed, 9 insertions(+), 9 deletions(-) - ---- a/zipl/include/zipl.h -+++ b/zipl/include/zipl.h -@@ -19,13 +19,12 @@ - #define ZIPL_MAGIC_SIZE 4 - #define DISK_LAYOUT_ID 0x00000001 - -+#define STAGE3_ENTRY 0xa000UL - #define IMAGE_ENTRY 0x10000UL - #define IMAGE_ENTRY_KDUMP 0x10010UL - --#define ZIPL_STAGE2_LOAD_ADDRESS 0x2000UL --#define ZIPL_STAGE3_ENTRY_ADDRESS 0xa000UL --#define DEFAULT_STAGE3_ADDRESS 0xa000UL --#define DEFAULT_STAGE3_PARAMS_ADDRESS 0x9000UL -+#define STAGE2_LOAD_ADDRESS 0x2000UL -+#define STAGE3_LOAD_ADDRESS 0xa000UL - #define IMAGE_LOAD_ADDRESS IMAGE_ENTRY - - #define ADDRESS_LIMIT 0x80000000UL -@@ -38,6 +37,7 @@ - #define STAGE3_HEAP_ADDRESS 0x2000UL - #define STAGE3_STACK_SIZE 0x1000UL - #define STAGE3_STACK_ADDRESS 0xF000UL -+#define STAGE3_PARAMS_ADDRESS 0x9000UL - - #define PSW_ADDRESS_MASK 0x000000007fffffffUL - #define PSW_LOAD 0x0008000080000000UL ---- a/zipl/src/boot.c -+++ b/zipl/src/boot.c -@@ -195,7 +195,7 @@ boot_init_fba_stage1b(struct boot_fba_st - stage1b->locdata[i].blocknr = - (uint32_t) stage2_list[i].linear.block; - stage1b->locread[i].read.address_lo = -- ZIPL_STAGE2_LOAD_ADDRESS + i * FBA_BLK_SIZE; -+ STAGE2_LOAD_ADDRESS + i * FBA_BLK_SIZE; - } - /* Terminate CCW chain */ - stage1b->locread[i - 1].read.flags &= ~CCW_FLAG_CC; -@@ -220,7 +220,7 @@ boot_init_eckd_stage1b(struct boot_eckd_ - stage1b->seek[i].head = stage2_list[i].chs.head | - ((stage2_list[i].chs.cyl >> 12) & 0xfff0); - stage1b->seek[i].sec = stage2_list[i].chs.sec; -- stage1b->ssrt[i].read.address_lo = ZIPL_STAGE2_LOAD_ADDRESS + -+ stage1b->ssrt[i].read.address_lo = STAGE2_LOAD_ADDRESS + - i * stage2_list[i].chs.size; - stage1b->ssrt[i].read.flags = CCW_FLAG_CC | CCW_FLAG_SLI; - } ---- a/zipl/src/bootmap.c -+++ b/zipl/src/bootmap.c -@@ -627,7 +627,7 @@ add_ipl_program(int fd, struct job_ipl_d - } - - /* Add stage 3 loader to bootmap */ -- rc = add_component_file(fd, ZIPL_STAGE3_PATH, DEFAULT_STAGE3_ADDRESS, -+ rc = add_component_file(fd, ZIPL_STAGE3_PATH, STAGE3_LOAD_ADDRESS, - signature_size, VOID_ADD(table, offset), 1, - info, target, &comp_loc[comp_nr]); - if (rc) { -@@ -654,7 +654,7 @@ add_ipl_program(int fd, struct job_ipl_d - } - rc = add_component_buffer(fd, stage3_params, stage3_params_size, - (component_data) (uint64_t) -- DEFAULT_STAGE3_PARAMS_ADDRESS, -+ STAGE3_PARAMS_ADDRESS, - VOID_ADD(table, offset), info, - &comp_loc[comp_nr], component_load); - free(stage3_params); -@@ -792,7 +792,7 @@ add_ipl_program(int fd, struct job_ipl_d - create_component_entry(VOID_ADD(table, offset), NULL, - component_execute, - (component_data) (uint64_t) -- (ZIPL_STAGE3_ENTRY_ADDRESS | PSW_LOAD), -+ (STAGE3_ENTRY | PSW_LOAD), - info); - /* Write component table */ - rc = disk_write_block_aligned(fd, table, info->phy_block_size, diff --git a/s390-tools-sles15sp2-15-zkey-Add-function-to-select-a-CCA-adapter-by-mkvp.patch b/s390-tools-sles15sp2-15-zkey-Add-function-to-select-a-CCA-adapter-by-mkvp.patch deleted file mode 100644 index cb40529..0000000 --- a/s390-tools-sles15sp2-15-zkey-Add-function-to-select-a-CCA-adapter-by-mkvp.patch +++ /dev/null @@ -1,162 +0,0 @@ -Subject: zkey: Add function to select a CCA adapter by mkvp -From: Ingo Franzki - -Summary: zkey: check master key consistency -Description: Enhances the zkey tool to perform a cross check whether the - APQNs associated with a secure key have the same master key. - Display the master key verification pattern of a secure key - during the zkey validate command. This helps to better identify - which master key is the correct one, in case of master key - inconsistencies. - Select an appropriate APQN when re-enciphering a secure key. - Re-enciphering is done using the CCA host library. Special - handling is required to select an appropriate APQN for use with - the CCA host library. -Upstream-ID: 1091b0bf65328aff94055a2e333aff2c737b6744 -Problem-ID: SEC1916 - -Upstream-Description: - - zkey: Add function to select a CCA adapter by mkvp - - Add a utility function to select an APQN that is set up with - a specific master key for use with the CCA host library. The - selection is based on the master key verification pattern, which - is typically obtained from an existing secure AES key. - - The function iterates over a set of APQNs to find one that is setup - with the desired master key in the CURRENT or OLD master key register, - and optionally has a new master key loaded. It then selects the found - APQN for use with the CCA host library. - - Signed-off-by: Ingo Franzki - Reviewed-by: Harald Freudenberger - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/cca.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - zkey/cca.h | 7 ++++ - 2 files changed, 107 insertions(+) - ---- a/zkey/cca.c -+++ b/zkey/cca.c -@@ -507,3 +507,103 @@ int select_cca_adapter(struct cca_lib *c - pr_verbose(verbose, "Selected adapter %u (CRP%02d)", adapter, adapter); - return 0; - } -+ -+struct find_mkvp_info { -+ u64 mkvp; -+ unsigned int flags; -+ bool found; -+ int card; -+ int domain; -+ bool verbose; -+}; -+ -+static int find_mkvp(int card, int domain, void *handler_data) -+{ -+ struct find_mkvp_info *info = (struct find_mkvp_info *)handler_data; -+ struct mk_info mk_info; -+ bool found = false; -+ int rc; -+ -+ rc = sysfs_get_mkvps(card, domain, &mk_info, info->verbose); -+ if (rc == -ENODEV) -+ return 0; -+ if (rc != 0) -+ return rc; -+ -+ if (info->flags & FLAG_SEL_CCA_MATCH_CUR_MKVP) -+ if (mk_info.cur_mk.mk_state == MK_STATE_VALID && -+ mk_info.cur_mk.mkvp == info->mkvp) -+ found = true; -+ -+ if (info->flags & FLAG_SEL_CCA_MATCH_OLD_MKVP) -+ if (mk_info.old_mk.mk_state == MK_STATE_VALID && -+ mk_info.old_mk.mkvp == info->mkvp) -+ found = true; -+ -+ if (info->flags & FLAG_SEL_CCA_NEW_MUST_BE_SET) -+ if (mk_info.new_mk.mk_state != MK_STATE_FULL) -+ found = false; -+ -+ -+ if (found) { -+ info->card = card; -+ info->domain = domain; -+ info->found = true; -+ -+ pr_verbose(info->verbose, "%02x.%04x has the desired mkvp%s", -+ card, domain, -+ info->flags & FLAG_SEL_CCA_NEW_MUST_BE_SET ? -+ " and NEW MK set" : ""); -+ -+ return 1; -+ } -+ -+ return 0; -+} -+ -+/** -+ * Selects an APQN to be used for the CCA host library that has the specified -+ * master key verification pattern -+ * -+ * @param[in] cca the CCA library structure -+ * @param[in] mkvp the master key verification pattern to search for -+ * @param[in] apqns a comma separated list of APQNs. If NULL is specified, -+ * or an empty string, then all online CCA APQNs are -+ * checked. -+ * @param[in] flags Flags that control the MKVM matching and NEW register -+ * checking. Multiple flags can be combined. -+ * @param[in] verbose if true, verbose messages are printed -+ * -+ * @returns 0 on success, a negative errno in case of an error. -ENOTSUP is -+ * returned when the serialnr sysfs attribute is not available, -+ * because the zcrypt kernel module is on an older level. -ENODEV is -+ * returned if no APQN is available with the desired mkvp. -+ */ -+int select_cca_adapter_by_mkvp(struct cca_lib *cca, u64 mkvp, const char *apqns, -+ unsigned int flags, bool verbose) -+{ -+ struct find_mkvp_info info; -+ int rc; -+ -+ util_assert(cca != NULL, "Internal error: cca is NULL"); -+ -+ pr_verbose(verbose, "Select mkvp %016llx in APQNs %s for the CCA host " -+ "library", mkvp, apqns == 0 ? "ANY" : apqns); -+ -+ info.mkvp = mkvp; -+ info.flags = flags; -+ info.found = false; -+ info.card = 0; -+ info.domain = 0; -+ info.verbose = verbose; -+ -+ rc = handle_apqns(apqns, find_mkvp, &info, verbose); -+ if (rc < 0) -+ return rc; -+ -+ if (!info.found) -+ return -ENODEV; -+ -+ rc = select_cca_adapter(cca, info.card, info.domain, verbose); -+ return rc; -+} ---- a/zkey/cca.h -+++ b/zkey/cca.h -@@ -83,4 +83,11 @@ int key_token_change(struct cca_lib *cca - - int select_cca_adapter(struct cca_lib *cca, int card, int domain, bool verbose); - -+#define FLAG_SEL_CCA_MATCH_CUR_MKVP 0x01 -+#define FLAG_SEL_CCA_MATCH_OLD_MKVP 0x02 -+#define FLAG_SEL_CCA_NEW_MUST_BE_SET 0x80 -+ -+int select_cca_adapter_by_mkvp(struct cca_lib *cca, u64 mkvp, const char *apqns, -+ unsigned int flags, bool verbose); -+ - #endif diff --git a/s390-tools-sles15sp2-16-zipl-stfle-use-uint64_t-instead-of-u64.patch b/s390-tools-sles15sp2-16-zipl-stfle-use-uint64_t-instead-of-u64.patch deleted file mode 100644 index b42835f..0000000 --- a/s390-tools-sles15sp2-16-zipl-stfle-use-uint64_t-instead-of-u64.patch +++ /dev/null @@ -1,53 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] zipl: stfle: use uint64_t instead of u64 -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: 9d1baaa594d796ca9fe6bdf1282c78e4b2ff5234 -Problem-ID: VS1804 - -Upstream-Description: - - zipl: stfle: use uint64_t instead of u64 - - As the definition of `stfle_fac_list` in the lowcore uses uint64_t, we - should also use uint64_t for the `stfle_fac_list` parameter of the - `stfle/__stfle_asm` function. - - Signed-off-by: Marc Hartmayer - Reviewed-by: Stefan Haberland - - -Signed-off-by: Marc Hartmayer ---- - zipl/boot/s390.h | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/zipl/boot/s390.h -+++ b/zipl/boot/s390.h -@@ -452,7 +452,7 @@ static inline int test_facility(unsigned - return __test_facility(nr, &S390_lowcore.stfle_fac_list); - } - --static inline unsigned long __stfle_asm(u64 *stfle_fac_list, int size) -+static inline unsigned long __stfle_asm(uint64_t *stfle_fac_list, int size) - { - register unsigned long reg0 asm("0") = size - 1; - -@@ -469,7 +469,7 @@ static inline unsigned long __stfle_asm( - * @stfle_fac_list: array where facility list can be stored - * @size: size of passed in array in double words - */ --static inline void stfle(u64 *stfle_fac_list, int size) -+static inline void stfle(uint64_t *stfle_fac_list, int size) - { - unsigned long nr; - diff --git a/s390-tools-sles15sp2-16-zkey-Select-CCA-adapter-when-re-enciphering.patch b/s390-tools-sles15sp2-16-zkey-Select-CCA-adapter-when-re-enciphering.patch deleted file mode 100644 index b9f6f7b..0000000 --- a/s390-tools-sles15sp2-16-zkey-Select-CCA-adapter-when-re-enciphering.patch +++ /dev/null @@ -1,397 +0,0 @@ -Subject: zkey: Select CCA adapter when re-enciphering -From: Ingo Franzki - -Summary: zkey: check master key consistency -Description: Enhances the zkey tool to perform a cross check whether the - APQNs associated with a secure key have the same master key. - Display the master key verification pattern of a secure key - during the zkey validate command. This helps to better identify - which master key is the correct one, in case of master key - inconsistencies. - Select an appropriate APQN when re-enciphering a secure key. - Re-enciphering is done using the CCA host library. Special - handling is required to select an appropriate APQN for use with - the CCA host library. -Upstream-ID: 552a915465301b768268cddc7ccb65a6d167e432 -Problem-ID: SEC1916 - -Upstream-Description: - - zkey: Select CCA adapter when re-enciphering - - When re-enciphering secure AES keys, select the correct APQN for used - with the CCA host library. Re-enciphering a secure key requires the use - of the CCA host library. The APQN is selected based on the master key - verification pattern obtained from the secure key to re-encipher. - - Signed-off-by: Ingo Franzki - Reviewed-by: Harald Freudenberger - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/cca.c | 19 ++++++++++++++ - zkey/cca.h | 2 + - zkey/keystore.c | 57 ++++++++++++++++++++++++++++++++++++------- - zkey/zkey-cryptsetup.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++-- - zkey/zkey.c | 50 ++++++++++++++++++++++++++++++++++++-- - 5 files changed, 179 insertions(+), 13 deletions(-) - ---- a/zkey/cca.c -+++ b/zkey/cca.c -@@ -18,6 +18,8 @@ - #include - #include - -+#include "lib/util_base.h" -+#include "lib/util_libc.h" - #include "lib/util_panic.h" - - #include "cca.h" -@@ -607,3 +609,20 @@ int select_cca_adapter_by_mkvp(struct cc - rc = select_cca_adapter(cca, info.card, info.domain, verbose); - return rc; - } -+ -+void print_msg_for_cca_envvars(const char *key_name) -+{ -+ char *msg; -+ -+ util_asprintf(&msg, "WARNING: You must set environment variables " -+ "%s and %s to the desired card and domain that is " -+ "set up with the AES master key used by this %s. " -+ "%s specifies the domain as decimal number. %s " -+ "specifies the adapter number as 'CRPnn', where " -+ "'nn' is the adapter number. See the CCA " -+ "documentation for more details.\n", -+ CCA_DOMAIN_ENVAR, CCA_ADAPTER_ENVAR, key_name, -+ CCA_DOMAIN_ENVAR, CCA_ADAPTER_ENVAR); -+ util_print_indented(msg, 0); -+ free(msg); -+} ---- a/zkey/cca.h -+++ b/zkey/cca.h -@@ -90,4 +90,6 @@ int select_cca_adapter(struct cca_lib *c - int select_cca_adapter_by_mkvp(struct cca_lib *cca, u64 mkvp, const char *apqns, - unsigned int flags, bool verbose); - -+void print_msg_for_cca_envvars(const char *key_name); -+ - #endif ---- a/zkey/keystore.c -+++ b/zkey/keystore.c -@@ -2535,6 +2535,7 @@ struct reencipher_info { - * @param[in] secure_key_size the size of the secure key - * @param[in] is_old_mk if true the key is currently re-enciphered with the - * OLD master key -+ * @param[in] apqns the associated APQNs (or NULL if none) - * @returns 0 if the re-enciphering is successful, a negative errno value - * otherwise, 1 if it was skipped - */ -@@ -2543,9 +2544,18 @@ static int _keystore_perform_reencipher( - struct cca_lib *cca, - struct reencipher_params *params, - u8 *secure_key, size_t secure_key_size, -- bool is_old_mk) -+ bool is_old_mk, const char *apqns) - { -- int rc; -+ int rc, selected = 1; -+ u64 mkvp; -+ -+ rc = get_master_key_verification_pattern(secure_key, secure_key_size, -+ &mkvp, keystore->verbose); -+ if (rc != 0) { -+ warnx("Failed to get the master key verification pattern: %s", -+ strerror(-rc)); -+ return rc; -+ } - - if (!params->from_old && !params->to_new) { - /* Autodetect reencipher mode */ -@@ -2567,12 +2577,6 @@ static int _keystore_perform_reencipher( - } - - if (params->from_old) { -- if (!is_old_mk) { -- printf("The secure key '%s' is already enciphered " -- "with the CURRENT CCA master key\n", name); -- return 1; -- } -- - if (params->inplace == -1) - params->inplace = 1; - -@@ -2580,12 +2584,27 @@ static int _keystore_perform_reencipher( - "Secure key '%s' will be re-enciphered from OLD " - "to the CURRENT CCA master key", name); - -+ rc = select_cca_adapter_by_mkvp(cca, mkvp, apqns, -+ FLAG_SEL_CCA_MATCH_OLD_MKVP, -+ keystore->verbose); -+ if (rc == -ENOTSUP) { -+ rc = 0; -+ selected = 0; -+ } -+ if (rc != 0) { -+ warnx("No APQN found that is suitable for " -+ "re-enciphering this secure AES key"); -+ return rc; -+ } -+ - rc = key_token_change(cca, secure_key, secure_key_size, - METHOD_OLD_TO_CURRENT, - keystore->verbose); - if (rc != 0) { - warnx("Failed to re-encipher '%s' from OLD to " - "CURRENT CCA master key", name); -+ if (!selected) -+ print_msg_for_cca_envvars("secure AES key"); - return rc; - } - } -@@ -2597,12 +2616,30 @@ static int _keystore_perform_reencipher( - if (params->inplace == -1) - params->inplace = 0; - -+ rc = select_cca_adapter_by_mkvp(cca, mkvp, apqns, -+ FLAG_SEL_CCA_MATCH_CUR_MKVP | -+ FLAG_SEL_CCA_NEW_MUST_BE_SET, -+ keystore->verbose); -+ if (rc == -ENOTSUP) { -+ rc = 0; -+ selected = 0; -+ } -+ if (rc != 0) { -+ util_print_indented("No APQN found that is suitable " -+ "for re-enciphering this secure " -+ "AES key and has the NEW master " -+ "key loaded", 0); -+ return rc; -+ } -+ - rc = key_token_change(cca, secure_key, secure_key_size, - METHOD_CURRENT_TO_NEW, - keystore->verbose); - if (rc != 0) { - warnx("Failed to re-encipher '%s' from CURRENT to " - "NEW CCA master key", name); -+ if (!selected) -+ print_msg_for_cca_envvars("secure AES key"); - return rc; - } - } -@@ -2692,7 +2729,9 @@ static int _keystore_process_reencipher( - - rc = _keystore_perform_reencipher(keystore, name, info->cca, - ¶ms, secure_key, -- secure_key_size, is_old_mk); -+ secure_key_size, is_old_mk, -+ properties_get(properties, -+ PROP_NAME_APQNS)); - if (rc < 0) - goto out; - if (rc > 0) { ---- a/zkey/zkey-cryptsetup.c -+++ b/zkey/zkey-cryptsetup.c -@@ -1514,10 +1514,12 @@ static int reencipher_prepare(int token) - char *password = NULL; - size_t password_len; - char *key = NULL; -+ int selected = 1; - size_t keysize; - int is_old_mk; - char *prompt; - char *msg; -+ u64 mkvp; - int rc; - - if (token >= 0) { -@@ -1578,13 +1580,42 @@ static int reencipher_prepare(int token) - util_print_indented(msg, 0); - free(msg); - -+ rc = get_master_key_verification_pattern((u8 *)key, keysize, &mkvp, -+ g.verbose); -+ if (rc != 0) { -+ warnx("Failed to get the master key verification pattern: %s", -+ strerror(-rc)); -+ goto out; -+ } -+ -+ rc = select_cca_adapter_by_mkvp(&g.cca, mkvp, NULL, -+ is_old_mk ? FLAG_SEL_CCA_MATCH_OLD_MKVP -+ : FLAG_SEL_CCA_MATCH_CUR_MKVP | -+ FLAG_SEL_CCA_NEW_MUST_BE_SET, -+ g.verbose); -+ if (rc == -ENOTSUP) { -+ rc = 0; -+ selected = 0; -+ } -+ if (rc != 0) { -+ util_asprintf(&msg, "No APQN found that is suitable for " -+ "re-enciphering the secure AES volume key%s", -+ !is_old_mk ? " and has the NEW master key loaded" -+ : ""); -+ util_print_indented(msg, 0); -+ free(msg); -+ goto out; -+ } -+ - rc = key_token_change(&g.cca, (u8 *)key, keysize, - is_old_mk ? METHOD_OLD_TO_CURRENT : - METHOD_CURRENT_TO_NEW, - g.verbose); - if (rc != 0) { - warnx("Failed to re-encipher the secure volume key of device " -- "'%s'", g.pos_arg); -+ "'%s'\n", g.pos_arg); -+ if (!selected) -+ print_msg_for_cca_envvars("secure AES volume key"); - rc = -EINVAL; - goto out; - } -@@ -1651,10 +1682,12 @@ static int reencipher_complete(int token - char *password = NULL; - size_t password_len; - char *key = NULL; -+ int selected = 1; - size_t keysize; - int is_old_mk; - char *prompt; - char *msg; -+ u64 mkvp; - int rc; - - rc = get_reencipher_token(g.cd, token, &tok, true); -@@ -1700,11 +1733,38 @@ static int reencipher_complete(int token - goto out; - } - -+ rc = get_master_key_verification_pattern((u8 *)key, keysize, -+ &mkvp, g.verbose); -+ if (rc != 0) { -+ warnx("Failed to get the master key verification " -+ "pattern: %s", -+ strerror(-rc)); -+ goto out; -+ } -+ -+ rc = select_cca_adapter_by_mkvp(&g.cca, mkvp, NULL, -+ FLAG_SEL_CCA_MATCH_OLD_MKVP, -+ g.verbose); -+ if (rc == -ENOTSUP) { -+ rc = 0; -+ selected = 0; -+ } -+ if (rc != 0) { -+ util_print_indented("No APQN found that is suitable " -+ "for re-enciphering the secure AES " -+ "volume key from the OLD to the " -+ "CURRENT CCA master key.", 0); -+ goto out; -+ } -+ - rc = key_token_change(&g.cca, (u8 *)key, keysize, - METHOD_OLD_TO_CURRENT, g.verbose); - if (rc != 0) { - warnx("Failed to re-encipher the secure volume key for " -- "device '%s'", g.pos_arg); -+ "device '%s'\n", g.pos_arg); -+ if (!selected) -+ print_msg_for_cca_envvars( -+ "secure AES volume key"); - rc = -EINVAL; - goto out; - } ---- a/zkey/zkey.c -+++ b/zkey/zkey.c -@@ -1128,7 +1128,9 @@ static int command_reencipher_file(void) - { - size_t secure_key_size; - int rc, is_old_mk; -+ int selected = 1; - u8 *secure_key; -+ u64 mkvp; - - if (g.name != NULL) { - warnx("Option '--name|-N' is not valid for " -@@ -1174,6 +1176,15 @@ static int command_reencipher_file(void) - goto out; - } - -+ rc = get_master_key_verification_pattern(secure_key, secure_key_size, -+ &mkvp, g.verbose); -+ if (rc != 0) { -+ warnx("Failed to get the master key verification pattern: %s", -+ strerror(-rc)); -+ rc = EXIT_FAILURE; -+ goto out; -+ } -+ - if (!g.fromold && !g.tonew) { - /* Autodetect reencipher option */ - if (is_old_mk) { -@@ -1205,12 +1216,28 @@ static int command_reencipher_file(void) - pr_verbose("Secure key will be re-enciphered from OLD to the " - "CURRENT CCA master key"); - -+ rc = select_cca_adapter_by_mkvp(&g.cca, mkvp, NULL, -+ FLAG_SEL_CCA_MATCH_OLD_MKVP, -+ g.verbose); -+ if (rc == -ENOTSUP) { -+ rc = 0; -+ selected = 0; -+ } -+ if (rc != 0) { -+ warnx("No APQN found that is suitable for " -+ "re-enciphering the secure AES volume key"); -+ rc = EXIT_FAILURE; -+ goto out; -+ } -+ - rc = key_token_change(&g.cca, secure_key, secure_key_size, - METHOD_OLD_TO_CURRENT, - g.verbose); - if (rc != 0) { - warnx("Re-encipher from OLD to CURRENT CCA " -- "master key has failed"); -+ "master key has failed\n"); -+ if (!selected) -+ print_msg_for_cca_envvars("secure AES key"); - rc = EXIT_FAILURE; - goto out; - } -@@ -1219,11 +1246,30 @@ static int command_reencipher_file(void) - pr_verbose("Secure key will be re-enciphered from CURRENT " - "to the NEW CCA master key"); - -+ rc = select_cca_adapter_by_mkvp(&g.cca, mkvp, NULL, -+ FLAG_SEL_CCA_MATCH_CUR_MKVP | -+ FLAG_SEL_CCA_NEW_MUST_BE_SET, -+ g.verbose); -+ if (rc == -ENOTSUP) { -+ rc = 0; -+ selected = 0; -+ } -+ if (rc != 0) { -+ util_print_indented("No APQN found that is suitable " -+ "for re-enciphering this secure " -+ "AES key and has the NEW master " -+ "key loaded", 0); -+ rc = EXIT_FAILURE; -+ goto out; -+ } -+ - rc = key_token_change(&g.cca, secure_key, secure_key_size, - METHOD_CURRENT_TO_NEW, g.verbose); - if (rc != 0) { - warnx("Re-encipher from CURRENT to NEW CCA " -- "master key has failed"); -+ "master key has failed\n"); -+ if (!selected) -+ print_msg_for_cca_envvars("secure AES key"); - rc = EXIT_FAILURE; - goto out; - } diff --git a/s390-tools-sles15sp2-17-zipl-boot-fix-comment-in-stage3.lds.patch b/s390-tools-sles15sp2-17-zipl-boot-fix-comment-in-stage3.lds.patch deleted file mode 100644 index 52072cc..0000000 --- a/s390-tools-sles15sp2-17-zipl-boot-fix-comment-in-stage3.lds.patch +++ /dev/null @@ -1,42 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] zipl/boot: fix comment in stage3.lds -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: 971970989bbb1de8887d11b0ab8e4f19adbd484f -Problem-ID: VS1804 - -Upstream-Description: - - zipl/boot: fix comment in stage3.lds - - See STAGE3_STACK_ADDRESS macro. - - Reviewed-by: Jan Höppner - Signed-off-by: Marc Hartmayer - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - zipl/boot/stage3.lds | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/zipl/boot/stage3.lds -+++ b/zipl/boot/stage3.lds -@@ -10,7 +10,7 @@ - * 0x6000-0x8fff free - * 0x9000-0x9fff Stage3 parameter - * 0xa000-0xdfff Stage3 code + data -- * 0xe000-0xffff Stack -+ * 0xf000-0xffff Stack - */ - - SECTIONS diff --git a/s390-tools-sles15sp2-17-zkey-cryptsetup-Add-to-new-and-from-old-options.patch b/s390-tools-sles15sp2-17-zkey-cryptsetup-Add-to-new-and-from-old-options.patch deleted file mode 100644 index 0758cf7..0000000 --- a/s390-tools-sles15sp2-17-zkey-cryptsetup-Add-to-new-and-from-old-options.patch +++ /dev/null @@ -1,289 +0,0 @@ -Subject: zkey-cryptsetup: Add --to-new and --from-old options -From: Ingo Franzki - -Summary: zkey: check master key consistency -Description: Enhances the zkey tool to perform a cross check whether the - APQNs associated with a secure key have the same master key. - Display the master key verification pattern of a secure key - during the zkey validate command. This helps to better identify - which master key is the correct one, in case of master key - inconsistencies. - Select an appropriate APQN when re-enciphering a secure key. - Re-enciphering is done using the CCA host library. Special - handling is required to select an appropriate APQN for use with - the CCA host library. -Upstream-ID: a0ed6709cf3c62b1fc9dfa28358e70215c1da55a -Problem-ID: SEC1916 - -Upstream-Description: - - zkey-cryptsetup: Add --to-new and --from-old options - - To allow better control about the secure AES volume key re-enciphering - with 'zkey-cryptsetup reencipher', add options '--to-new' and '--from-old' - to specify if a re-enciphering from CURRENT to NEW, or OLD to CURRENT master - key registers is to be performed. If these options are not specified, then - it is auto-detected, based on the master key that the secure key is currently - re-enciphered with. - - Signed-off-by: Ingo Franzki - Reviewed-by: Harald Freudenberger - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/zkey-cryptsetup.1 | 49 ++++++++++++++--- - zkey/zkey-cryptsetup.c | 137 ++++++++++++++++++++++++++++++++++++------------- - 2 files changed, 142 insertions(+), 44 deletions(-) - ---- a/zkey/zkey-cryptsetup.1 -+++ b/zkey/zkey-cryptsetup.1 -@@ -91,6 +91,8 @@ behave in the same way as with \fBcrypts - .B zkey\-cryptsetup - .BR reencipher | re - .I device -+.RB [ \-\-to\-new | \-N ] -+.RB [ \-\-from\-old | \-O ] - .RB [ \-\-staged | \-s ] - .RB [ \-\-in\-place | \-i ] - .RB [ \-\-complete | \-c ] -@@ -128,17 +130,36 @@ register can still be used until the mas - The \fBNEW\fP register contains the new master key to be set. - The master key in the \fBNEW\fP register cannot be used until it is made - the current master key. You can pro-actively re-encipher a secure key with the --\fBNEW\fP master key before this key is made the \fBCURRENT\fP key. -+\fBNEW\fP master key before this key is made the \fBCURRENT\fP key. Use the -+.B \-\-to-new -+option to do this. - .RE - .PP --\fBzkey\-cryptsetup\fP automatically detects whether the secure volume key --is currently enciphered with the master key in the \fBOLD\fP register or with --the master key in the \fBCURRENT\fP register. If currently enciphered with the --master key in the \fBOLD\fP register, it is re-enciphered with the master key --in the \fBCURRENT\fP register. If it is currently enciphered with the master --key in the \fBCURRENT\fP register, it is re-enciphered with the master key in --the \fBNEW\fP register. If for this case the \fBNEW\fP register does not --contain a valid master key, then the re-encipher operation fails. -+Use the -+.B \-\-from\-old -+option to re-encipher a secure volume key that is currently enciphered with -+the master key in the \fBOLD\fP register with the master key in the -+\fBCURRENT\fP register. -+.PP -+.PP -+If both the -+.B \-\-from-old -+and -+.B \-\-to-new -+options are specified, a secure volume key that is currently enciphered -+with the master key in the \fBOLD\fP register is re-enciphered with the -+master key in the \fBNEW\fP register. -+.RE -+.PP -+If both options are omitted, \fBzkey-cryptsetup\fP automatically detects whether -+the secure volume key is currently enciphered with the master key in the -+\fBOLD\fP register or with the master key in the \fBCURRENT\fP register. -+If currently enciphered with the master key in the \fBOLD\fP register, -+it is re-enciphered with the master key in the \fBCURRENT\fP register. -+If it is currently enciphered with the master key in the \fBCURRENT\fP -+register, it is re-enciphered with the master key in the \fBNEW\fP register. -+If for this case the \fBNEW\fP register does not contain a valid master key, -+then the re-encipher operation fails. - .PP - Re-enciphering a secure volume key of a volume encrypted with - \fBLUKS2\fP and the \fBpaes\fP cipher can be performed \fBin-place\fP, or in -@@ -326,6 +347,16 @@ relevance. - . - .SS "Options for the reencipher command" - .TP -+.BR \-N ", " \-\-to\-new -+Re-enciphers a secure volume key in the LUKS2 header that is currently -+enciphered with the master key in the CURRENT register with the master key in -+the NEW register. -+.TP -+.BR \-O ", " \-\-from\-old -+Re-enciphers a secure volume key in the LUKS2 header that is currently -+enciphered with the master key in the OLD register with the master key in the -+CURRENT register. -+.TP - .BR \-i ", " \-\-in-place - Forces an in-place re-enciphering of a secure volume key in the LUKS2 - header. This option immediately replaces the secure volume key in the LUKS2 ---- a/zkey/zkey-cryptsetup.c -+++ b/zkey/zkey-cryptsetup.c -@@ -95,6 +95,8 @@ static struct zkey_cryptsetup_globals { - long long keyfile_offset; - long long keyfile_size; - long long tries; -+ bool tonew; -+ bool fromold; - bool complete; - bool inplace; - bool staged; -@@ -163,6 +165,22 @@ static struct util_opt opt_vec[] = { - .command = COMMAND_REENCIPHER, - }, - { -+ .option = {"to-new", 0, NULL, 'N'}, -+ .desc = "Re-enciphers a secure volume key in the LUKS2 header " -+ "that is currently enciphered with the master key in " -+ "the CURRENT register with the master key in the NEW " -+ "register", -+ .command = COMMAND_REENCIPHER, -+ }, -+ { -+ .option = {"from-old", 0, NULL, 'O'}, -+ .desc = "Re-enciphers a secure volume key in the LUKS2 header " -+ "that is currently enciphered with the master key in " -+ "the OLD register with the master key in the CURRENT " -+ "register", -+ .command = COMMAND_REENCIPHER, -+ }, -+ { - .option = {"staged", 0, NULL, 's'}, - .desc = "Forces that the re-enciphering of a secure volume " - "key in the LUKS2 header is performed in staged mode", -@@ -1572,13 +1590,28 @@ static int reencipher_prepare(int token) - if (rc < 0) - goto out; - -- util_asprintf(&msg, "The secure volume key of device '%s' is " -- "enciphered with the %s CCA master key and is being " -- "re-enciphered with the %s CCA master key.", -- g.pos_arg, is_old_mk ? "OLD" : "CURRENT", -- is_old_mk ? "CURRENT" : "NEW"); -- util_print_indented(msg, 0); -- free(msg); -+ if (!g.fromold && !g.tonew) { -+ /* Autodetect reencipher mode */ -+ if (is_old_mk) { -+ g.fromold = 1; -+ util_asprintf(&msg, "The secure volume key of device " -+ "'%s' is enciphered with the OLD CCA " -+ "master key and is being re-enciphered " -+ "with the CURRENT CCA master key.", -+ g.pos_arg); -+ util_print_indented(msg, 0); -+ free(msg); -+ } else { -+ g.tonew = 1; -+ util_asprintf(&msg, "The secure volume key of device " -+ "'%s' is enciphered with the CURRENT CCA " -+ "master key and is being re-enciphered " -+ "with the NEW CCA master key.", -+ g.pos_arg); -+ util_print_indented(msg, 0); -+ free(msg); -+ } -+ } - - rc = get_master_key_verification_pattern((u8 *)key, keysize, &mkvp, - g.verbose); -@@ -1588,36 +1621,64 @@ static int reencipher_prepare(int token) - goto out; - } - -- rc = select_cca_adapter_by_mkvp(&g.cca, mkvp, NULL, -- is_old_mk ? FLAG_SEL_CCA_MATCH_OLD_MKVP -- : FLAG_SEL_CCA_MATCH_CUR_MKVP | -- FLAG_SEL_CCA_NEW_MUST_BE_SET, -- g.verbose); -- if (rc == -ENOTSUP) { -- rc = 0; -- selected = 0; -- } -- if (rc != 0) { -- util_asprintf(&msg, "No APQN found that is suitable for " -- "re-enciphering the secure AES volume key%s", -- !is_old_mk ? " and has the NEW master key loaded" -- : ""); -- util_print_indented(msg, 0); -- free(msg); -- goto out; -+ if (g.fromold) { -+ rc = select_cca_adapter_by_mkvp(&g.cca, mkvp, NULL, -+ FLAG_SEL_CCA_MATCH_OLD_MKVP, -+ g.verbose); -+ if (rc == -ENOTSUP) { -+ rc = 0; -+ selected = 0; -+ } -+ if (rc != 0) { -+ util_print_indented("No APQN found that is suitable " -+ "for re-enciphering the secure AES " -+ "volume key from the OLD to the " -+ "CURRENT CCA master key.", 0); -+ goto out; -+ } -+ -+ rc = key_token_change(&g.cca, (u8 *)key, keysize, -+ METHOD_OLD_TO_CURRENT, g.verbose); -+ if (rc != 0) { -+ warnx("Failed to re-encipher the secure volume key of " -+ "device '%s'\n", g.pos_arg); -+ if (!selected) -+ print_msg_for_cca_envvars( -+ "secure AES volume key"); -+ rc = -EINVAL; -+ goto out; -+ } - } - -- rc = key_token_change(&g.cca, (u8 *)key, keysize, -- is_old_mk ? METHOD_OLD_TO_CURRENT : -- METHOD_CURRENT_TO_NEW, -- g.verbose); -- if (rc != 0) { -- warnx("Failed to re-encipher the secure volume key of device " -- "'%s'\n", g.pos_arg); -- if (!selected) -- print_msg_for_cca_envvars("secure AES volume key"); -- rc = -EINVAL; -- goto out; -+ if (g.tonew) { -+ rc = select_cca_adapter_by_mkvp(&g.cca, mkvp, NULL, -+ FLAG_SEL_CCA_MATCH_CUR_MKVP | -+ FLAG_SEL_CCA_NEW_MUST_BE_SET, -+ g.verbose); -+ if (rc == -ENOTSUP) { -+ rc = 0; -+ selected = 0; -+ } -+ if (rc != 0) { -+ util_print_indented("No APQN found that is suitable " -+ "for re-enciphering the secure AES " -+ "volume key from the CURRENT to " -+ "the NEW CCA master key.", 0); -+ goto out; -+ } -+ -+ rc = key_token_change(&g.cca, (u8 *)key, keysize, -+ METHOD_CURRENT_TO_NEW, -+ g.verbose); -+ if (rc != 0) { -+ warnx("Failed to re-encipher the secure volume key of " -+ "device '%s'\n", g.pos_arg); -+ if (!selected) -+ print_msg_for_cca_envvars( -+ "secure AES volume key"); -+ rc = -EINVAL; -+ goto out; -+ } - } - - rc = crypt_keyslot_add_by_key(g.cd, CRYPT_ANY_SLOT, key, keysize, -@@ -2276,6 +2337,12 @@ int main(int argc, char *argv[]) - if (c == -1) - break; - switch (c) { -+ case 'N': -+ g.tonew = 1; -+ break; -+ case 'O': -+ g.fromold = 1; -+ break; - case 'c': - g.complete = 1; - break; diff --git a/s390-tools-sles15sp2-18-lib-zt_common-add-STATIC_ASSERT-macro.patch b/s390-tools-sles15sp2-18-lib-zt_common-add-STATIC_ASSERT-macro.patch deleted file mode 100644 index ee4a6ab..0000000 --- a/s390-tools-sles15sp2-18-lib-zt_common-add-STATIC_ASSERT-macro.patch +++ /dev/null @@ -1,50 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] lib/zt_common: add STATIC_ASSERT macro -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: bac3f93772bdf8618c2c9677c59569d70e4a39c0 -Problem-ID: VS1804 - -Upstream-Description: - - lib/zt_common: add STATIC_ASSERT macro - - Add `STATIC_ASSERT` macro that uses `_Static_assert` if available (was - introduced with gcc 4.6, see https://gcc.gnu.org/wiki/C11Status). For - example, this could be used for the verification of structure sizes at - compile time. - - Acked-by: Jan Höppner - Signed-off-by: Marc Hartmayer - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - include/lib/zt_common.h | 7 +++++++ - 1 file changed, 7 insertions(+) - ---- a/include/lib/zt_common.h -+++ b/include/lib/zt_common.h -@@ -22,6 +22,13 @@ - # define UNUSED(x) x - #endif - -+#ifdef STATIC_ASSERT -+#elif defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ >= 5) -+# define STATIC_ASSERT(test) _Static_assert((test), "(" #test ") failed"); -+#else -+# define STATIC_ASSERT(test) -+#endif -+ - #define RELEASE_STRING STRINGIFY (S390_TOOLS_RELEASE) - #define TOOLS_LIBDIR STRINGIFY (S390_TOOLS_LIBDIR) - #define TOOLS_SYSCONFDIR STRINGIFY (S390_TOOLS_SYSCONFDIR) diff --git a/s390-tools-sles15sp2-18-zkey-Display-key-type-with-list-and-validate-command.patch b/s390-tools-sles15sp2-18-zkey-Display-key-type-with-list-and-validate-command.patch deleted file mode 100644 index 45cf874..0000000 --- a/s390-tools-sles15sp2-18-zkey-Display-key-type-with-list-and-validate-command.patch +++ /dev/null @@ -1,202 +0,0 @@ -Subject: zkey: Display key type with list and validate commands -From: Ingo Franzki - -Summary: zkey: Add support for CCA AES CIPHER keys -Description: With CCA 5 there is a new secure key type, the so called - variable length symmetric cipher key token. This token format - can hold AES keys with size 128, 192 and 256 bits together - with additional attributes cryptographic bound to the key - token. The attributes may limit the usage of the key, for - example restrict export or usability scope. So this key type - is considered to be even more secure than the traditional - secure key token. This key token type is also called "CCA - AES CIPHER key", where the formerly used key token is called - "CCA AES DATA key". - The zkey as well as the zkey-cryptsetup tools are enhanced - to support AES CIPHER keys. That is, zkey can manage AES DATA - keys, as well as AES CIPHER keys. The key type must be specified - at key generation time, the default is to generate AED DATA - keys. -Upstream-ID: 9de85f42951e0b1a3d083363d7000b1950aebcd7 -Problem-ID: SEC1717 - -Upstream-Description: - - zkey: Display key type with list and validate commands - - For the 'zkey list', 'zkey validate' and 'zkey-cryptsetup validate' - commands, display the key type. - - As of today there is only one possible key type (CCA-AESDATA), - but in the future there might be additional key types. - - Signed-off-by: Ingo Franzki - Reviewed-by: Harald Freudenberger - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/keystore.c | 7 +++++++ - zkey/pkey.c | 39 +++++++++++++++++++++++++++++++++++++++ - zkey/pkey.h | 17 +++++++++++++++++ - zkey/zkey-cryptsetup.c | 2 ++ - zkey/zkey.c | 2 ++ - 5 files changed, 67 insertions(+) - ---- a/zkey/keystore.c -+++ b/zkey/keystore.c -@@ -77,6 +77,7 @@ struct key_filenames { - #define REC_SEC_KEY_SIZE "Secure key size" - #define REC_CLR_KEY_SIZE "Clear key size" - #define REC_XTS "XTS type key" -+#define REC_KEY_TYPE "Key type" - #define REC_VOLUMES "Volumes" - #define REC_APQNS "APQNs" - #define REC_KEY_FILE "Key file name" -@@ -2140,6 +2141,7 @@ static struct util_rec *_keystore_setup_ - util_rec_def(rec, REC_CLR_KEY_SIZE, UTIL_REC_ALIGN_LEFT, 20, - REC_CLR_KEY_SIZE); - util_rec_def(rec, REC_XTS, UTIL_REC_ALIGN_LEFT, 3, REC_XTS); -+ util_rec_def(rec, REC_KEY_TYPE, UTIL_REC_ALIGN_LEFT, 54, REC_KEY_TYPE); - if (validation) - util_rec_def(rec, REC_MASTERKEY, UTIL_REC_ALIGN_LEFT, 54, - REC_MASTERKEY); -@@ -2178,6 +2180,7 @@ static void _keystore_print_record(struc - char *description; - char *volume_type; - char *reencipher; -+ char *key_type; - char *creation; - char *volumes; - char *change; -@@ -2212,6 +2215,7 @@ static void _keystore_print_record(struc - reencipher = properties_get(properties, PROP_NAME_REENC_TIME); - vp = properties_get(properties, PROP_NAME_KEY_VP); - volume_type = _keystore_get_volume_type(properties); -+ key_type = properties_get(properties, PROP_NAME_KEY_TYPE); - - util_rec_set(rec, REC_KEY, name); - if (validation) -@@ -2226,6 +2230,7 @@ static void _keystore_print_record(struc - util_rec_set(rec, REC_CLR_KEY_SIZE, "(unknown)"); - util_rec_set(rec, REC_XTS, - IS_XTS(secure_key_size) ? "Yes" : "No"); -+ util_rec_set(rec, REC_KEY_TYPE, key_type); - if (validation) { - if (valid) - util_rec_set(rec, REC_MASTERKEY, -@@ -2290,6 +2295,8 @@ static void _keystore_print_record(struc - free(vp); - if (volume_type != NULL) - free(volume_type); -+ if (key_type != NULL) -+ free(key_type); - } - - struct validate_info { ---- a/zkey/pkey.c -+++ b/zkey/pkey.c -@@ -790,3 +790,42 @@ int get_master_key_verification_pattern( - - return 0; - } -+ -+/** -+ * Check if the specified key is a CCA AESDATA key token. -+ * -+ * @param[in] key the secure key token -+ * @param[in] key_size the size of the secure key -+ * -+ * @returns true if the key is an CCA AESDATA token type -+ */ -+bool is_cca_aes_data_key(const u8 *key, size_t key_size) -+{ -+ struct tokenheader *hdr = (struct tokenheader *)key; -+ -+ if (key == NULL || key_size < SECURE_KEY_SIZE) -+ return false; -+ -+ if (hdr->type != TOKEN_TYPE_CCA_INTERNAL) -+ return false; -+ if (hdr->version != TOKEN_VERSION_AESDATA) -+ return false; -+ -+ return true; -+} -+ -+/** -+ * Returns the type of the key -+ * -+ * @param[in] key the secure key token -+ * @param[in] key_size the size of the secure key -+ * -+ * @returns a static string on success, NULL in case of an error -+ */ -+const char *get_key_type(const u8 *key, size_t key_size) -+{ -+ if (is_cca_aes_data_key(key, key_size)) -+ return KEY_TYPE_CCA_AESDATA; -+ -+ return NULL; -+} ---- a/zkey/pkey.h -+++ b/zkey/pkey.h -@@ -18,6 +18,18 @@ - /* - * Definitions for the /dev/pkey kernel module interface - */ -+struct tokenheader { -+ u8 type; -+ u8 res0[3]; -+ u8 version; -+ u8 res1[3]; -+} __packed; -+ -+#define TOKEN_TYPE_NON_CCA 0x00 -+#define TOKEN_TYPE_CCA_INTERNAL 0x01 -+ -+#define TOKEN_VERSION_AESDATA 0x04 -+ - struct secaeskeytoken { - u8 type; /* 0x01 for internal key token */ - u8 res0[3]; -@@ -82,6 +94,8 @@ struct pkey_verifykey { - - #define PKEY_VERIFYKEY _IOWR(PKEY_IOCTL_MAGIC, 0x07, struct pkey_verifykey) - -+#define KEY_TYPE_CCA_AESDATA "CCA-AESDATA" -+ - #define PAES_BLOCK_SIZE 16 - #define ENC_ZERO_LEN (2 * PAES_BLOCK_SIZE) - #define VERIFICATION_PATTERN_LEN (2 * ENC_ZERO_LEN + 1) -@@ -116,4 +130,7 @@ int get_master_key_verification_pattern( - size_t secure_key_size, u64 *mkvp, - bool verbose); - -+bool is_cca_aes_data_key(const u8 *key, size_t key_size); -+const char *get_key_type(const u8 *key, size_t key_size); -+ - #endif ---- a/zkey/zkey-cryptsetup.c -+++ b/zkey/zkey-cryptsetup.c -@@ -1999,6 +1999,8 @@ static int command_validate(void) - printf(" Secure key size: %lu bytes\n", keysize); - printf(" XTS type key: %s\n", - keysize > SECURE_KEY_SIZE ? "Yes" : "No"); -+ printf(" Key type: %s\n", -+ get_key_type((u8 *)key, keysize)); - if (is_valid) { - printf(" Clear key size: %lu bits\n", clear_keysize); - printf(" Enciphered with: %s CCA master key (MKVP: " ---- a/zkey/zkey.c -+++ b/zkey/zkey.c -@@ -1416,6 +1416,8 @@ static int command_validate_file(void) - printf("Validation of secure key in file '%s':\n", g.pos_arg); - printf(" Status: Valid\n"); - printf(" Secure key size: %lu bytes\n", secure_key_size); -+ printf(" Key type: %s\n", -+ get_key_type(secure_key, secure_key_size)); - printf(" Clear key size: %lu bits\n", clear_key_size); - printf(" XTS type key: %s\n", - secure_key_size > SECURE_KEY_SIZE ? "Yes" : "No"); diff --git a/s390-tools-sles15sp2-19-zipl-use-STATIC_ASSERT-macro-for-no-padding-verifica.patch b/s390-tools-sles15sp2-19-zipl-use-STATIC_ASSERT-macro-for-no-padding-verifica.patch deleted file mode 100644 index 2a3072b..0000000 --- a/s390-tools-sles15sp2-19-zipl-use-STATIC_ASSERT-macro-for-no-padding-verifica.patch +++ /dev/null @@ -1,91 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] zipl: use STATIC_ASSERT macro for no padding verification -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: cc16e41595d6dcb942f84443f27a1b52d06d17da -Problem-ID: VS1804 - -Upstream-Description: - - zipl: use STATIC_ASSERT macro for no padding verification - - A simple comment above the struct declaration to indicate that the - structure must not have any padding is prone to error. Therefore let's - add a check for the structure size at compile time. - - Reviewed-by: Jan Höppner - Signed-off-by: Marc Hartmayer - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - zipl/boot/sclp.h | 2 ++ - zipl/boot/sclp_stage3.h | 2 ++ - zipl/boot/stage3.h | 4 ++++ - 3 files changed, 8 insertions(+) - ---- a/zipl/boot/sclp.h -+++ b/zipl/boot/sclp.h -@@ -60,6 +60,7 @@ struct sccb_header { - uint8_t control_mask[3]; - uint16_t response_code; - }; -+STATIC_ASSERT(sizeof(struct sccb_header) == 2 + 1 + 3 + 2) - - /* Structure must not have any padding */ - struct evbuf_header { -@@ -68,6 +69,7 @@ struct evbuf_header { - uint8_t flags; - uint16_t _reserved; - }; -+STATIC_ASSERT(sizeof(struct evbuf_header) == 2 + 1 + 1 + 2) - - struct mto { - uint16_t length; ---- a/zipl/boot/sclp_stage3.h -+++ b/zipl/boot/sclp_stage3.h -@@ -42,6 +42,8 @@ struct sdias_sccb { - struct sccb_header header; - struct sdias_evbuf evbuf; - }; -+STATIC_ASSERT(sizeof(struct sdias_sccb) == -+ sizeof(struct sccb_header) + sizeof(struct sdias_evbuf)) - - - int sclp_hsa_copy(void *, unsigned long, unsigned long); ---- a/zipl/boot/stage3.h -+++ b/zipl/boot/stage3.h -@@ -15,6 +15,8 @@ - #include "libc.h" - #include "s390.h" - -+#include "lib/zt_common.h" -+ - #define IPL_DEVICE 0x10404UL - #define INITRD_START 0x10408UL - #define INITRD_SIZE 0x10410UL -@@ -128,6 +130,7 @@ struct ipl_rb_hdr { - uint8_t rbt; - uint8_t reserved1[11]; - }; -+STATIC_ASSERT(sizeof(struct ipl_rb_hdr) == 4 + 1 + 11) - - /* IPL Report Block types */ - enum ipl_rbt { -@@ -168,6 +171,7 @@ struct ipl_rb_components { - uint8_t reserved1[11]; - struct ipl_rb_component_entry entries[]; - }; -+STATIC_ASSERT(sizeof(struct ipl_rb_components) == 4 + 1 + 11) - - extern unsigned long long _parm_addr; /* address of parmline */ - extern unsigned long long _initrd_addr; /* address of initrd */ diff --git a/s390-tools-sles15sp2-19-zkey-Allow-to-filter-list-output-by-key-type.patch b/s390-tools-sles15sp2-19-zkey-Allow-to-filter-list-output-by-key-type.patch deleted file mode 100644 index af776c3..0000000 --- a/s390-tools-sles15sp2-19-zkey-Allow-to-filter-list-output-by-key-type.patch +++ /dev/null @@ -1,331 +0,0 @@ -Subject: zkey: Allow to filter list output by key type -From: Ingo Franzki - -Summary: zkey: Add support for CCA AES CIPHER keys -Description: With CCA 5 there is a new secure key type, the so called - variable length symmetric cipher key token. This token format - can hold AES keys with size 128, 192 and 256 bits together - with additional attributes cryptographic bound to the key - token. The attributes may limit the usage of the key, for - example restrict export or usability scope. So this key type - is considered to be even more secure than the traditional - secure key token. This key token type is also called "CCA - AES CIPHER key", where the formerly used key token is called - "CCA AES DATA key". - The zkey as well as the zkey-cryptsetup tools are enhanced - to support AES CIPHER keys. That is, zkey can manage AES DATA - keys, as well as AES CIPHER keys. The key type must be specified - at key generation time, the default is to generate AED DATA - keys. -Upstream-ID: 91c35543ca7fd25691487c61ec2e308f2903a6b8 -Problem-ID: SEC1717 - -Upstream-Description: - - zkey: Allow to filter list output by key type - - The zkey list command now accepts option --key-type|-K type - to filter the displayed keys by key type. If not specified, - then all key types are displayed. - - Signed-off-by: Ingo Franzki - Reviewed-by: Harald Freudenberger - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/keystore.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++------ - zkey/keystore.h | 2 - - zkey/zkey.1 | 9 ++++- - zkey/zkey.c | 15 +++++++- - 4 files changed, 112 insertions(+), 13 deletions(-) - ---- a/zkey/keystore.c -+++ b/zkey/keystore.c -@@ -315,6 +315,39 @@ static char *_keystore_get_volume_type(s - } - - /** -+ * Returns the key type contained in the properties. If no key type -+ * property is contained, then 'CCA-AESDATA' is assumed (for backward -+ * compatibility). -+ * -+ * @returns a string containing the key type. Must be freed by the caller. -+ */ -+static char *_keystore_get_key_type(struct properties *properties) -+{ -+ char *type; -+ -+ type = properties_get(properties, PROP_NAME_KEY_TYPE); -+ if (type == NULL) -+ type = util_strdup(KEY_TYPE_CCA_AESDATA); -+ -+ return type; -+} -+ -+/** -+ * Checks if the key type is supported. -+ * -+ * @param[in] key_type the key type -+ * -+ * @returns 1 if the key type is valid, 0 otherwise -+ */ -+static int _keystore_valid_key_type(const char *key_type) -+{ -+ if (strcasecmp(key_type, KEY_TYPE_CCA_AESDATA) == 0) -+ return 1; -+ -+ return 0; -+} -+ -+/** - * Prints a message followed by a list of associated volumes, if volumes are - * associated and the volume-type matches (if specified) - * -@@ -817,6 +850,33 @@ static int _keystore_match_volume_type_p - return rc; - } - -+/** -+ * Checks if the key type property matches the specified key type. -+ * If the properties do not contain a key type property, then the default -+ * key type is assumed. -+ * -+ * @param[in] properties a properties object -+ * @param[in] key_type the key type to match. Can be NULL. In this case -+ * it always matches. -+ * -+ * @returns 1 for a match, 0 for not matched -+ */ -+static int _keystore_match_key_type_property(struct properties *properties, -+ const char *key_type) -+{ -+ char *type; -+ int rc = 0; -+ -+ if (key_type == NULL) -+ return 1; -+ -+ type = _keystore_get_key_type(properties); -+ if (strcasecmp(type, key_type) == 0) -+ rc = 1; -+ -+ free(type); -+ return rc; -+} - - /** - * Checks if a key name matches a name filter -@@ -882,6 +942,7 @@ typedef int (*process_key_t)(struct keys - * mutliple APQN filters separated by commas. - * NULL means no APQN filter. - * @param[in] volume_type If not NULL, specifies the volume type. -+ * @param[in] key_type The key type. NULL means no key type filter. - * @param[in] process_func the callback function called for a matching key - * @param[in/out] process_private private data passed to the process_func - * -@@ -894,6 +955,7 @@ static int _keystore_process_filtered(st - const char *volume_filter, - const char *apqn_filter, - const char *volume_type, -+ const char *key_type, - process_key_t process_func, - void *process_private) - { -@@ -985,6 +1047,15 @@ static int _keystore_process_filtered(st - goto free_prop; - } - -+ rc = _keystore_match_key_type_property(key_props, -+ key_type); -+ if (rc == 0) { -+ pr_verbose(keystore, -+ "Key '%s' filtered out due to key type", -+ name); -+ goto free_prop; -+ } -+ - rc = process_func(keystore, name, key_props, &file_names, - process_private); - if (rc != 0) { -@@ -1193,7 +1264,7 @@ static int _keystore_volume_check(const - - info->set = set; - rc = _keystore_process_filtered(info->keystore, NULL, info->volume, -- NULL, NULL, -+ NULL, NULL, NULL, - _keystore_volume_check_process, info); - out: - free((void *)info->volume); -@@ -1454,7 +1525,8 @@ static int _keystore_set_default_propert - { - int rc; - -- rc = properties_set(key_props, PROP_NAME_KEY_TYPE, "CCA-AESDATA"); -+ rc = properties_set(key_props, PROP_NAME_KEY_TYPE, -+ KEY_TYPE_CCA_AESDATA); - if (rc != 0) - return rc; - -@@ -2498,7 +2570,7 @@ int keystore_validate_key(struct keystor - info.num_warnings = 0; - - rc = _keystore_process_filtered(keystore, name_filter, NULL, -- apqn_filter, NULL, -+ apqn_filter, NULL, NULL, - _keystore_process_validate, &info); - - util_rec_free(rec); -@@ -2877,7 +2949,7 @@ int keystore_reencipher_key(struct keyst - info.num_skipped = 0; - - rc = _keystore_process_filtered(keystore, name_filter, NULL, -- apqn_filter, NULL, -+ apqn_filter, NULL, NULL, - _keystore_process_reencipher, &info); - - if (rc != 0) { -@@ -3258,12 +3330,13 @@ out: - * mutliple APQN filters separated by commas. - * NULL means no APQN filter. - * @param[in] volume_type The volume type. NULL means no volume type filter. -+ * @param[in] key_type The key type. NULL means no key type filter. - * - * @returns 0 for success or a negative errno in case of an error - */ - int keystore_list_keys(struct keystore *keystore, const char *name_filter, - const char *volume_filter, const char *apqn_filter, -- const char *volume_type) -+ const char *volume_type, const char *key_type) - { - struct util_rec *rec; - int rc; -@@ -3276,10 +3349,16 @@ int keystore_list_keys(struct keystore * - return -EINVAL; - } - -+ if (key_type != NULL && -+ !_keystore_valid_key_type(key_type)) { -+ warnx("Invalid key-type specified"); -+ return -EINVAL; -+ } -+ - rec = _keystore_setup_record(0); - - rc = _keystore_process_filtered(keystore, name_filter, volume_filter, -- apqn_filter, volume_type, -+ apqn_filter, volume_type, key_type, - _keystore_display_key, rec); - util_rec_free(rec); - -@@ -3773,8 +3852,8 @@ int keystore_cryptsetup(struct keystore - info.process_func = _keystore_process_cryptsetup; - - rc = _keystore_process_filtered(keystore, NULL, volume_filter, NULL, -- volume_type, _keystore_process_crypt, -- &info); -+ volume_type, NULL, -+ _keystore_process_crypt, &info); - - str_list_free_string_array(info.volume_filter); - -@@ -3834,8 +3913,8 @@ int keystore_crypttab(struct keystore *k - info.process_func = _keystore_process_crypttab; - - rc = _keystore_process_filtered(keystore, NULL, volume_filter, NULL, -- volume_type, _keystore_process_crypt, -- &info); -+ volume_type, NULL, -+ _keystore_process_crypt, &info); - - str_list_free_string_array(info.volume_filter); - ---- a/zkey/keystore.h -+++ b/zkey/keystore.h -@@ -68,7 +68,7 @@ int keystore_remove_key(struct keystore - - int keystore_list_keys(struct keystore *keystore, const char *name_filter, - const char *volume_filter, const char *apqn_filter, -- const char *volume_type); -+ const char *volume_type, const char *key_type); - - int keystore_cryptsetup(struct keystore *keystore, const char *volume_filter, - bool execute, const char *volume_type, ---- a/zkey/zkey.1 -+++ b/zkey/zkey.1 -@@ -368,6 +368,8 @@ The exported secure key also remains in - .IR card1.domain1[,card2.domain2[,...]] ] - .RB [ \-\-volume-type | \-t - .IR type ] -+.RB [ \-\-key-type | \-K -+.IR type ] - .RB [ \-\-verbose | \-V ] - . - .PP -@@ -382,7 +384,7 @@ listed that are associated with the spec - .PP - The - .B list --command displays the attributes of the secure keys, such as key sizes, -+command displays the attributes of the secure keys, such as key sizes, key type, - whether it is a secure key that can be used for the XTS cipher mode, the textual - description, associated cryptographic adapters (APQNs) and volumes, the - sector size, the key verification pattern, and timestamps for key creation, last -@@ -907,6 +909,11 @@ This option is only available if - .B zkey - has been compiled with LUKS2 support enabled. - This option is only used for secure keys contained in the secure key repository. -+.TP -+.BR \-K ", " \-\-key-type\~\fItype\fP -+Specifies the key type of the secure key. Possible values are \fBCCA-AESDATA\fP. -+Only keys with the specified key type are listed. -+This option is only used for secure keys contained in the secure key repository. - . - . - . ---- a/zkey/zkey.c -+++ b/zkey/zkey.c -@@ -73,6 +73,7 @@ static struct zkey_globals { - long int sector_size; - char *volume_type; - char *newname; -+ char *key_type; - bool run; - bool batch_mode; - char *keyfile; -@@ -432,6 +433,15 @@ static struct util_opt opt_vec[] = { - .command = COMMAND_LIST, - }, - #endif -+ { -+ .option = { "key-type", required_argument, NULL, 'K'}, -+ .argument = "type", -+ .desc = "The type of the key. Possible values are '" -+ KEY_TYPE_CCA_AESDATA"'. " -+ "Use this option to list all keys with the specified " -+ "key type.", -+ .command = COMMAND_LIST, -+ }, - /***********************************************************/ - { - .flags = UTIL_OPT_FLAG_SECTION, -@@ -1532,7 +1542,7 @@ static int command_list(void) - int rc; - - rc = keystore_list_keys(g.keystore, g.name, g.volumes, g.apqns, -- g.volume_type); -+ g.volume_type, g.key_type); - - return rc != 0 ? EXIT_FAILURE : EXIT_SUCCESS; - } -@@ -1853,6 +1863,9 @@ int main(int argc, char *argv[]) - case 'r': - g.run = 1; - break; -+ case 'K': -+ g.key_type = optarg; -+ break; - case 'F': - g.force = 1; - break; diff --git a/s390-tools-sles15sp2-20-Support-lib-zt_common.h-to-be-used-in-assembler-and-.patch b/s390-tools-sles15sp2-20-Support-lib-zt_common.h-to-be-used-in-assembler-and-.patch deleted file mode 100644 index e354900..0000000 --- a/s390-tools-sles15sp2-20-Support-lib-zt_common.h-to-be-used-in-assembler-and-.patch +++ /dev/null @@ -1,65 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] Support `lib/zt_common.h` to be used in assembler and add `_AC` macro -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: 400167f5128a14ba48b0d05b7b777b42c450c73f -Problem-ID: VS1804 - -Upstream-Description: - - Support `lib/zt_common.h` to be used in assembler and add `_AC` macro - - Support `lib/zt_common.h` to be used in assembler files. In addition, - add the macro `_AC` that can be used to make constant macros usable in - both assembler and C code. - - Suggested-by: Philipp Rudo - Reviewed-by: Stefan Haberland - Reviewed-by: Philipp Rudo - Signed-off-by: Marc Hartmayer - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - include/lib/zt_common.h | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - ---- a/include/lib/zt_common.h -+++ b/include/lib/zt_common.h -@@ -15,6 +15,21 @@ - #define STRINGIFY_1(x) #x - #define STRINGIFY(x) STRINGIFY_1(x) - -+/* Use this macro to make constant macros usable in both assembler and -+ * C code. -+ * -+ * Usage example: -+ * #define IMAGE_ENTRY _AC(0x10000, UL) -+ */ -+#ifdef __ASSEMBLER__ -+#define _AC(X, TYPE) X -+#else -+#define _AC(X, TYPE) X##TYPE -+#endif -+ -+ -+#ifndef __ASSEMBLER__ -+ - #ifdef UNUSED - #elif defined(__GNUC__) - # define UNUSED(x) UNUSED_ ## x __attribute__((unused)) -@@ -50,4 +65,5 @@ typedef signed short int s16; - typedef unsigned char u8; - typedef signed char s8; - -+#endif /* __ASSEMBLER__ */ - #endif /* LIB_ZT_COMMON_H */ diff --git a/s390-tools-sles15sp2-20-zkey-Allow-to-specify-the-key-type-with-the-generate.patch b/s390-tools-sles15sp2-20-zkey-Allow-to-specify-the-key-type-with-the-generate.patch deleted file mode 100644 index dcc8d7a..0000000 --- a/s390-tools-sles15sp2-20-zkey-Allow-to-specify-the-key-type-with-the-generate.patch +++ /dev/null @@ -1,348 +0,0 @@ -Subject: zkey: Allow to specify the key type with the generate command -From: Ingo Franzki - -Summary: zkey: Add support for CCA AES CIPHER keys -Description: With CCA 5 there is a new secure key type, the so called - variable length symmetric cipher key token. This token format - can hold AES keys with size 128, 192 and 256 bits together - with additional attributes cryptographic bound to the key - token. The attributes may limit the usage of the key, for - example restrict export or usability scope. So this key type - is considered to be even more secure than the traditional - secure key token. This key token type is also called "CCA - AES CIPHER key", where the formerly used key token is called - "CCA AES DATA key". - The zkey as well as the zkey-cryptsetup tools are enhanced - to support AES CIPHER keys. That is, zkey can manage AES DATA - keys, as well as AES CIPHER keys. The key type must be specified - at key generation time, the default is to generate AED DATA - keys. -Upstream-ID: b47007b8ac8b446eb94b06e7ed3050b3df3e80e8 -Problem-ID: SEC1717 - -Upstream-Description: - - zkey: Allow to specify the key type with the generate command - - The zkey generate command allows to specify the --key-type|-K - option to specify the key type. If not specified, then the - default is CCA-AESDATA. - - Signed-off-by: Ingo Franzki - Reviewed-by: Harald Freudenberger - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/keystore.c | 35 ++++++++++++++++++++++++----------- - zkey/keystore.h | 2 +- - zkey/pkey.c | 20 +++++++++++++++++--- - zkey/pkey.h | 6 +++--- - zkey/zkey.1 | 14 ++++++++++++++ - zkey/zkey.c | 17 ++++++++++++++--- - 6 files changed, 73 insertions(+), 21 deletions(-) - ---- a/zkey/keystore.c -+++ b/zkey/keystore.c -@@ -1525,11 +1525,6 @@ static int _keystore_set_default_propert - { - int rc; - -- rc = properties_set(key_props, PROP_NAME_KEY_TYPE, -- KEY_TYPE_CCA_AESDATA); -- if (rc != 0) -- return rc; -- - rc = properties_set(key_props, PROP_NAME_CIPHER, "paes"); - if (rc != 0) - return rc; -@@ -1564,6 +1559,7 @@ static int _keystore_set_default_propert - * the sector size is not specified and the system - * default is used. - * @param[in] volume_type the type of volume -+ * @param[in] key_type the type of the key - */ - static int _keystore_create_info_file(struct keystore *keystore, - const char *name, -@@ -1572,7 +1568,8 @@ static int _keystore_create_info_file(st - const char *volumes, const char *apqns, - bool noapqncheck, - size_t sector_size, -- const char *volume_type) -+ const char *volume_type, -+ const char *key_type) - { - struct volume_check vol_check = { .keystore = keystore, .name = name, - .set = 0 }; -@@ -1594,6 +1591,12 @@ static int _keystore_create_info_file(st - goto out; - } - -+ rc = properties_set2(key_props, PROP_NAME_KEY_TYPE, key_type, true); -+ if (rc != 0) { -+ warnx("Invalid characters in key-type"); -+ goto out; -+ } -+ - rc = _keystore_change_association(key_props, PROP_NAME_VOLUMES, - volumes != NULL ? volumes : "", - "volume", _keystore_volume_check, -@@ -1731,6 +1734,7 @@ out: - * clear key contained in the file denoted here. - * if NULL, the secure key is generated by random. - * @param[in] volume_type the type of volume -+ * @param[in] key_type the type of the key - * @param[in] pkey_fd the file descriptor of /dev/pkey - * - * @returns 0 for success or a negative errno in case of an error -@@ -1740,7 +1744,7 @@ int keystore_generate_key(struct keystor - const char *apqns, bool noapqncheck, - size_t sector_size, size_t keybits, bool xts, - const char *clear_key_file, const char *volume_type, -- int pkey_fd) -+ const char *key_type, int pkey_fd) - { - struct key_filenames file_names = { NULL, NULL, NULL }; - struct properties *key_props = NULL; -@@ -1749,6 +1753,12 @@ int keystore_generate_key(struct keystor - - util_assert(keystore != NULL, "Internal error: keystore is NULL"); - util_assert(name != NULL, "Internal error: name is NULL"); -+ util_assert(key_type != NULL, "Internal error: key_type is NULL"); -+ -+ if (!_keystore_valid_key_type(key_type)) { -+ warnx("Invalid key-type specified"); -+ return -EINVAL; -+ } - - rc = _keystore_get_key_filenames(keystore, name, &file_names); - if (rc != 0) -@@ -1773,13 +1783,14 @@ int keystore_generate_key(struct keystor - if (clear_key_file == NULL) - rc = generate_secure_key_random(pkey_fd, - file_names.skey_filename, -- keybits, xts, card, domain, -+ keybits, xts, key_type, -+ card, domain, - keystore->verbose); - else - rc = generate_secure_key_clear(pkey_fd, - file_names.skey_filename, - keybits, xts, clear_key_file, -- card, domain, -+ key_type, card, domain, - keystore->verbose); - if (rc != 0) - goto out_free_props; -@@ -1790,7 +1801,8 @@ int keystore_generate_key(struct keystor - - rc = _keystore_create_info_file(keystore, name, &file_names, - description, volumes, apqns, -- noapqncheck, sector_size, volume_type); -+ noapqncheck, sector_size, volume_type, -+ key_type); - if (rc != 0) - goto out_free_props; - -@@ -1894,7 +1906,8 @@ int keystore_import_key(struct keystore - - rc = _keystore_create_info_file(keystore, name, &file_names, - description, volumes, apqns, -- noapqncheck, sector_size, volume_type); -+ noapqncheck, sector_size, volume_type, -+ KEY_TYPE_CCA_AESDATA); - if (rc != 0) - goto out_free_props; - ---- a/zkey/keystore.h -+++ b/zkey/keystore.h -@@ -32,7 +32,7 @@ int keystore_generate_key(struct keystor - const char *apqns, bool noapqncheck, - size_t sector_size, size_t keybits, bool xts, - const char *clear_key_file, const char *volume_type, -- int pkey_fd); -+ const char *key_type, int pkey_fd); - - int keystore_import_key(struct keystore *keystore, const char *name, - const char *description, const char *volumes, ---- a/zkey/pkey.c -+++ b/zkey/pkey.c -@@ -278,6 +278,7 @@ out: - * @param[in] keyfile the file name of the secure key to generate - * @param[in] keybits the cryptographic size of the key in bits - * @param[in] xts if true an XTS key is generated -+ * @param[in] key_type the type of the key - * @param[in] card the card number to use (or AUTOSELECT) - * @param[in] domain the domain number to use (or AUTOSELECT) - * @param[in] verbose if true, verbose messages are printed -@@ -285,8 +286,8 @@ out: - * @returns 0 on success, a negative errno in case of an error - */ - int generate_secure_key_random(int pkey_fd, const char *keyfile, -- size_t keybits, bool xts, u16 card, u16 domain, -- bool verbose) -+ size_t keybits, bool xts, const char *key_type, -+ u16 card, u16 domain, bool verbose) - { - struct pkey_genseck gensec; - size_t secure_key_size; -@@ -295,6 +296,12 @@ int generate_secure_key_random(int pkey_ - - util_assert(pkey_fd != -1, "Internal error: pkey_fd is -1"); - util_assert(keyfile != NULL, "Internal error: keyfile is NULL"); -+ util_assert(key_type != NULL, "Internal error: key_type is NULL"); -+ -+ if (strcasecmp(key_type, KEY_TYPE_CCA_AESDATA) != 0) { -+ warnx("Invalid key-type: %s", key_type); -+ return -EINVAL; -+ } - - if (keybits == 0) - keybits = DEFAULT_KEYBITS; -@@ -374,6 +381,7 @@ out: - * determines the keybits. - * @param[in] xts if true an XTS key is generated - * @param[in] clearkeyfile the file name of the clear key to read -+ * @param[in] key_type the type of the key - * @param[in] card the card number to use (or AUTOSELECT) - * @param[in] domain the domain number to use (or AUTOSELECT) - * @param[in] verbose if true, verbose messages are printed -@@ -382,7 +390,7 @@ out: - */ - int generate_secure_key_clear(int pkey_fd, const char *keyfile, - size_t keybits, bool xts, -- const char *clearkeyfile, -+ const char *clearkeyfile, const char *key_type, - u16 card, u16 domain, - bool verbose) - { -@@ -397,6 +405,12 @@ int generate_secure_key_clear(int pkey_f - util_assert(keyfile != NULL, "Internal error: keyfile is NULL"); - util_assert(clearkeyfile != NULL, - "Internal error: clearkeyfile is NULL"); -+ util_assert(key_type != NULL, "Internal error: key_type is NULL"); -+ -+ if (strcasecmp(key_type, KEY_TYPE_CCA_AESDATA) != 0) { -+ warnx("Invalid key-type: %s", key_type); -+ return -EINVAL; -+ } - - secure_key_size = DOUBLE_KEYSIZE_FOR_XTS(SECURE_KEY_SIZE, xts); - secure_key = util_malloc(secure_key_size); ---- a/zkey/pkey.h -+++ b/zkey/pkey.h -@@ -103,12 +103,12 @@ struct pkey_verifykey { - int open_pkey_device(bool verbose); - - int generate_secure_key_random(int pkey_fd, const char *keyfile, -- size_t keybits, bool xts, u16 card, u16 domain, -- bool verbose); -+ size_t keybits, bool xts, const char *key_type, -+ u16 card, u16 domain, bool verbose); - - int generate_secure_key_clear(int pkey_fd, const char *keyfile, - size_t keybits, bool xts, -- const char *clearkeyfile, -+ const char *clearkeyfile, const char *key_type, - u16 card, u16 domain, - bool verbose); - ---- a/zkey/zkey.1 -+++ b/zkey/zkey.1 -@@ -79,6 +79,8 @@ key repository. - .RB [ \-\-xts | \-x ] - .RB [ \-\-clearkey | \-c - .IR clear\-key\-file ] -+.RB [ \-\-key-type | \-K -+.IR type ] - .RB [ \-\-verbose | \-V ] - . - .PP -@@ -102,6 +104,8 @@ key repository. - .RB [ \-\-xts | \-x ] - .RB [ \-\-clearkey | \-c - .IR clear\-key\-file ] -+.RB [ \-\-key-type | \-K -+.IR type ] - .RB [ \-\-verbose | \-V ] - .PP - Use the -@@ -129,6 +133,11 @@ additional information can be associated - , or the - .B \-\-sector-size - options. -+.PP -+You can generate different types of secure keys: \fBCCA-AESDATA\fP keys. -+Specify the type of the secure key using the -+.B \-\-key\-type -+option. The default key type is CCA-AESDATA. - . - .SS "Validating secure AES keys" - . -@@ -730,6 +739,11 @@ This option is only available if - has been compiled with LUKS2 support enabled. If LUKS2 support is not enabled, - the default volume type is \fBplain\fP. - This option is only used for secure keys contained in the secure key repository. -+.TP -+.BR \-K ", " \-\-key-type\~\fItype\fP -+Specifies the key type of the secure key. Possible values are \fBCCA-AESDATA\fP. -+If this option is omitted, then a secure key of type -+CCA-AESDATA is generated. - . - . - . ---- a/zkey/zkey.c -+++ b/zkey/zkey.c -@@ -217,6 +217,15 @@ static struct util_opt opt_vec[] = { - .command = COMMAND_GENERATE, - }, - #endif -+ { -+ .option = { "key-type", required_argument, NULL, 'K'}, -+ .argument = "type", -+ .desc = "The type of the key. Possible values are '" -+ KEY_TYPE_CCA_AESDATA"'. " -+ "When this option is omitted, the default is '" -+ KEY_TYPE_CCA_AESDATA"'", -+ .command = COMMAND_GENERATE, -+ }, - /***********************************************************/ - { - .flags = UTIL_OPT_FLAG_SECTION, -@@ -1019,7 +1028,7 @@ static int command_generate_clear(void) - - rc = generate_secure_key_clear(g.pkey_fd, g.pos_arg, - g.keybits, g.xts, -- g.clearkeyfile, -+ g.clearkeyfile, g.key_type, - AUTOSELECT, AUTOSELECT, - g.verbose); - -@@ -1036,7 +1045,7 @@ static int command_generate_random(void) - int rc; - - rc = generate_secure_key_random(g.pkey_fd, g.pos_arg, -- g.keybits, g.xts, -+ g.keybits, g.xts, g.key_type, - AUTOSELECT, AUTOSELECT, - g.verbose); - -@@ -1058,7 +1067,7 @@ static int command_generate_repository(v - rc = keystore_generate_key(g.keystore, g.name, g.description, g.volumes, - g.apqns, g.noapqncheck, g.sector_size, - g.keybits, g.xts, g.clearkeyfile, -- g.volume_type, g.pkey_fd); -+ g.volume_type, g.key_type, g.pkey_fd); - - return rc != 0 ? EXIT_FAILURE : EXIT_SUCCESS; - } -@@ -1085,6 +1094,8 @@ static int command_generate(void) - util_prg_print_parse_error(); - return EXIT_FAILURE; - } -+ if (g.key_type == NULL) -+ g.key_type = KEY_TYPE_CCA_AESDATA; - if (g.name != NULL) - return command_generate_repository(); - if (g.pos_arg != NULL) { diff --git a/s390-tools-sles15sp2-21-zipl-move-IPL-related-definitions-into-separate-head.patch b/s390-tools-sles15sp2-21-zipl-move-IPL-related-definitions-into-separate-head.patch deleted file mode 100644 index 8762137..0000000 --- a/s390-tools-sles15sp2-21-zipl-move-IPL-related-definitions-into-separate-head.patch +++ /dev/null @@ -1,359 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] zipl: move IPL related definitions into separate header -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: 9d39a4bd47008b15bbf4ebe672b91d6d63888536 -Problem-ID: VS1804 - -Upstream-Description: - - zipl: move IPL related definitions into separate header - - Move the IPL related definitions into `include/boot/ipl.h`. This - allows the reuse of the definitions, e.g. in the boot loader for - protected guests. - - Reviewed-by: Stefan Haberland - Reviewed-by: Philipp Rudo - Signed-off-by: Marc Hartmayer - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - include/boot/ipl.h | 159 +++++++++++++++++++++++++++++++++++++++++++++++++++++ - zipl/boot/stage3.h | 140 ---------------------------------------------- - 2 files changed, 160 insertions(+), 139 deletions(-) - ---- /dev/null -+++ b/include/boot/ipl.h -@@ -0,0 +1,159 @@ -+/* -+ * IPL related definitions -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * s390-tools is free software; you can redistribute it and/or modify -+ * it under the terms of the MIT license. See LICENSE for details. -+ */ -+ -+#ifndef IPL_H -+#define IPL_H -+ -+#include "lib/zt_common.h" -+ -+#define IPL_FLAG_SECURE 0x40 -+ -+#define IPL_RB_COMPONENT_FLAG_SIGNED 0x80 -+#define IPL_RB_COMPONENT_FLAG_VERIFIED 0x40 -+ -+ -+#ifndef __ASSEMBLER__ -+ -+#include -+ -+/* IPL Parameter List header */ -+struct ipl_pl_hdr { -+ uint32_t len; -+ uint8_t flags; -+ uint8_t reserved1[2]; -+ uint8_t version; -+} __packed; -+ -+/* IPL Parameter Block header */ -+struct ipl_pb_hdr { -+ uint32_t len; -+ uint8_t pbt; -+} __packed; -+ -+/* IPL Parameter Block 0 with common fields */ -+struct ipl_pb0_common { -+ uint32_t len; -+ uint8_t pbt; -+ uint8_t flags; -+ uint8_t reserved1[2]; -+ uint8_t loadparm[8]; -+ uint8_t reserved2[84]; -+} __packed; -+ -+/* IPL Parameter Block 0 for FCP */ -+struct ipl_pb0_fcp { -+ uint32_t len; -+ uint8_t pbt; -+ uint8_t reserved1[3]; -+ uint8_t loadparm[8]; -+ uint8_t reserved2[304]; -+ uint8_t opt; -+ uint8_t reserved3[3]; -+ uint8_t cssid; -+ uint8_t reserved4[1]; -+ uint8_t devno; -+ uint8_t reserved5[4]; -+ uint64_t wwpn; -+ uint64_t lun; -+ uint32_t bootprog; -+ uint8_t reserved6[12]; -+ uint64_t br_lba; -+ uint32_t scp_data_len; -+ uint8_t reserved7[260]; -+ uint8_t scp_data[]; -+} __packed; -+ -+/* IPL Parameter Block 0 for CCW */ -+struct ipl_pb0_ccw { -+ uint32_t len; -+ uint8_t pbt; -+ uint8_t flags; -+ uint8_t reserved1[2]; -+ uint8_t loadparm[8]; -+ uint8_t reserved2[84]; -+ uint16_t reserved3 : 13; -+ uint8_t ssid : 3; -+ uint16_t devno; -+ uint8_t vm_flags; -+ uint8_t reserved4[3]; -+ uint32_t vm_parm_len; -+ uint8_t nss_name[8]; -+ uint8_t vm_parm[64]; -+ uint8_t reserved5[8]; -+} __packed; -+ -+struct ipl_parameter_block { -+ struct ipl_pl_hdr hdr; -+ union { -+ struct ipl_pb_hdr pb0_hdr; -+ struct ipl_pb0_common common; -+ struct ipl_pb0_fcp fcp; -+ struct ipl_pb0_ccw ccw; -+ char raw[PAGE_SIZE - sizeof(struct ipl_pl_hdr)]; -+ }; -+} __packed __aligned(PAGE_SIZE); -+ -+/* IPL Report List header */ -+struct ipl_rl_hdr { -+ uint32_t len; -+ uint8_t flags; -+ uint8_t reserved1[2]; -+ uint8_t version; -+ uint8_t reserved2[8]; -+} __packed; -+ -+/* IPL Report Block header */ -+/* Structure must not have any padding */ -+struct ipl_rb_hdr { -+ uint32_t len; -+ uint8_t rbt; -+ uint8_t reserved1[11]; -+}; -+STATIC_ASSERT(sizeof(struct ipl_rb_hdr) == 4 + 1 + 11) -+ -+/* IPL Report Block types */ -+enum ipl_rbt { -+ IPL_RBT_CERTIFICATES = 1, -+ IPL_RBT_COMPONENTS = 2, -+}; -+ -+/* IPL Report Block for the certificate list */ -+struct ipl_rb_certificate_entry { -+ uint64_t addr; -+ uint64_t len; -+} __packed; -+ -+struct ipl_rb_certificates { -+ uint32_t len; -+ uint8_t rbt; -+ uint8_t reserved1[11]; -+ struct ipl_rb_certificate_entry entries[]; -+} __packed; -+ -+/* IPL Report Block for the component list */ -+struct ipl_rb_component_entry { -+ uint64_t addr; -+ uint64_t len; -+ uint8_t flags; -+ uint8_t reserved1[5]; -+ uint16_t certificate_index; -+ uint8_t reserved2[8]; -+}; -+ -+/* Structure must not have any padding */ -+struct ipl_rb_components { -+ uint32_t len; -+ uint8_t rbt; -+ uint8_t reserved1[11]; -+ struct ipl_rb_component_entry entries[]; -+}; -+STATIC_ASSERT(sizeof(struct ipl_rb_components) == 4 + 1 + 11) -+ -+#endif /* __ASSEMBLER__ */ -+#endif /* IPL_H */ ---- a/zipl/boot/stage3.h -+++ b/zipl/boot/stage3.h -@@ -15,7 +15,7 @@ - #include "libc.h" - #include "s390.h" - --#include "lib/zt_common.h" -+#include "boot/ipl.h" - - #define IPL_DEVICE 0x10404UL - #define INITRD_START 0x10408UL -@@ -29,150 +29,12 @@ - #define STAGE3_FLAG_SCSI 0x0001000000000000ULL - #define STAGE3_FLAG_KDUMP 0x0002000000000000ULL - --#define IPL_FLAG_SECURE 0x40 -- - #define DEFAULT_PSW_LOAD 0x0008000080010000UL - #define PSW_ADDR_MASK 0x000000007FFFFFFFUL - - #define UNSPECIFIED_ADDRESS -1UL - - --/* IPL Parameter List header */ --struct ipl_pl_hdr { -- uint32_t len; -- uint8_t flags; -- uint8_t reserved1[2]; -- uint8_t version; --} __packed; -- --/* IPL Parameter Block header */ --struct ipl_pb_hdr { -- uint32_t len; -- uint8_t pbt; --} __packed; -- --/* IPL Parameter Block 0 with common fields */ --struct ipl_pb0_common { -- uint32_t len; -- uint8_t pbt; -- uint8_t flags; -- uint8_t reserved1[2]; -- uint8_t loadparm[8]; -- uint8_t reserved2[84]; --} __packed; -- --/* IPL Parameter Block 0 for FCP */ --struct ipl_pb0_fcp { -- uint32_t len; -- uint8_t pbt; -- uint8_t reserved1[3]; -- uint8_t loadparm[8]; -- uint8_t reserved2[304]; -- uint8_t opt; -- uint8_t reserved3[3]; -- uint8_t cssid; -- uint8_t reserved4[1]; -- uint8_t devno; -- uint8_t reserved5[4]; -- uint64_t wwpn; -- uint64_t lun; -- uint32_t bootprog; -- uint8_t reserved6[12]; -- uint64_t br_lba; -- uint32_t scp_data_len; -- uint8_t reserved7[260]; -- uint8_t scp_data[]; --} __packed; -- --/* IPL Parameter Block 0 for CCW */ --struct ipl_pb0_ccw { -- uint32_t len; -- uint8_t pbt; -- uint8_t flags; -- uint8_t reserved1[2]; -- uint8_t loadparm[8]; -- uint8_t reserved2[84]; -- uint16_t reserved3 : 13; -- uint8_t ssid : 3; -- uint16_t devno; -- uint8_t vm_flags; -- uint8_t reserved4[3]; -- uint32_t vm_parm_len; -- uint8_t nss_name[8]; -- uint8_t vm_parm[64]; -- uint8_t reserved5[8]; --} __packed; -- --struct ipl_parameter_block { -- struct ipl_pl_hdr hdr; -- union { -- struct ipl_pb_hdr pb0_hdr; -- struct ipl_pb0_common common; -- struct ipl_pb0_fcp fcp; -- struct ipl_pb0_ccw ccw; -- char raw[PAGE_SIZE - sizeof(struct ipl_pl_hdr)]; -- }; --} __packed __aligned(PAGE_SIZE); -- --/* IPL Report List header */ --struct ipl_rl_hdr { -- uint32_t len; -- uint8_t flags; -- uint8_t reserved1[2]; -- uint8_t version; -- uint8_t reserved2[8]; --} __packed; -- --/* IPL Report Block header */ --/* Structure must not have any padding */ --struct ipl_rb_hdr { -- uint32_t len; -- uint8_t rbt; -- uint8_t reserved1[11]; --}; --STATIC_ASSERT(sizeof(struct ipl_rb_hdr) == 4 + 1 + 11) -- --/* IPL Report Block types */ --enum ipl_rbt { -- IPL_RBT_CERTIFICATES = 1, -- IPL_RBT_COMPONENTS = 2, --}; -- --/* IPL Report Block for the certificate list */ --struct ipl_rb_certificate_entry { -- uint64_t addr; -- uint64_t len; --} __packed; -- --struct ipl_rb_certificates { -- uint32_t len; -- uint8_t rbt; -- uint8_t reserved1[11]; -- struct ipl_rb_certificate_entry entries[]; --} __packed; -- --/* IPL Report Block for the component list */ --struct ipl_rb_component_entry { -- uint64_t addr; -- uint64_t len; -- uint8_t flags; -- uint8_t reserved1[5]; -- uint16_t certificate_index; -- uint8_t reserved2[8]; --}; -- --#define IPL_RB_COMPONENT_FLAG_SIGNED 0x80 --#define IPL_RB_COMPONENT_FLAG_VERIFIED 0x40 -- --/* Structure must not have any padding */ --struct ipl_rb_components { -- uint32_t len; -- uint8_t rbt; -- uint8_t reserved1[11]; -- struct ipl_rb_component_entry entries[]; --}; --STATIC_ASSERT(sizeof(struct ipl_rb_components) == 4 + 1 + 11) -- - extern unsigned long long _parm_addr; /* address of parmline */ - extern unsigned long long _initrd_addr; /* address of initrd */ - extern unsigned long long _initrd_len; /* length of initrd */ diff --git a/s390-tools-sles15sp2-21-zkey-Preparations-for-introducing-a-new-key-type.patch b/s390-tools-sles15sp2-21-zkey-Preparations-for-introducing-a-new-key-type.patch deleted file mode 100644 index a799ab8..0000000 --- a/s390-tools-sles15sp2-21-zkey-Preparations-for-introducing-a-new-key-type.patch +++ /dev/null @@ -1,665 +0,0 @@ -Subject: zkey: Preparations for introducing a new key type -From: Ingo Franzki - -Summary: zkey: Add support for CCA AES CIPHER keys -Description: With CCA 5 there is a new secure key type, the so called - variable length symmetric cipher key token. This token format - can hold AES keys with size 128, 192 and 256 bits together - with additional attributes cryptographic bound to the key - token. The attributes may limit the usage of the key, for - example restrict export or usability scope. So this key type - is considered to be even more secure than the traditional - secure key token. This key token type is also called "CCA - AES CIPHER key", where the formerly used key token is called - "CCA AES DATA key". - The zkey as well as the zkey-cryptsetup tools are enhanced - to support AES CIPHER keys. That is, zkey can manage AES DATA - keys, as well as AES CIPHER keys. The key type must be specified - at key generation time, the default is to generate AED DATA - keys. -Upstream-ID: 298fab68fee86cb9b1862d60ca274971d4c39638 -Problem-ID: SEC1717 - -Upstream-Description: - - zkey: Preparations for introducing a new key type - - Introduce helper functions and definitions to allow key type - independent code in the keystore implementation - - Signed-off-by: Ingo Franzki - Reviewed-by: Harald Freudenberger - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/cca.c | 4 - - zkey/keystore.c | 91 +++++++++++++++---------------------------- - zkey/pkey.c | 103 ++++++++++++++++++++++++++++++++++++------------- - zkey/pkey.h | 17 +++++--- - zkey/zkey-cryptsetup.c | 27 +++++++----- - zkey/zkey.c | 4 - - 6 files changed, 139 insertions(+), 107 deletions(-) - ---- a/zkey/cca.c -+++ b/zkey/cca.c -@@ -215,11 +215,11 @@ int key_token_change(struct cca_lib *cca - return -EIO; - } - -- if (secure_key_size == 2 * SECURE_KEY_SIZE) { -+ if (secure_key_size == 2 * AESDATA_KEY_SIZE) { - cca->dll_CSNBKTC(&return_code, &reason_code, - &exit_data_len, exit_data, - &rule_array_count, rule_array, -- secure_key + SECURE_KEY_SIZE); -+ secure_key + AESDATA_KEY_SIZE); - - pr_verbose(verbose, "CSNBKTC (Key Token Change) with '%s' " - "returned: return_code: %ld, reason_code: %ld", ---- a/zkey/keystore.c -+++ b/zkey/keystore.c -@@ -70,8 +70,6 @@ struct key_filenames { - #define DEFAULT_VOLUME_TYPE VOLUME_TYPE_PLAIN - #endif - --#define IS_XTS(secure_key_size) (secure_key_size > SECURE_KEY_SIZE ? 1 : 0) -- - #define REC_KEY "Key" - #define REC_DESCRIPTION "Description" - #define REC_SEC_KEY_SIZE "Secure key size" -@@ -1440,7 +1438,7 @@ static int _keystore_generate_verificati - if (key == NULL) - return -EIO; - -- rc = generate_key_verification_pattern((const char *)key, key_size, -+ rc = generate_key_verification_pattern(key, key_size, - vp, vp_len, keystore->verbose); - - free(key); -@@ -1854,6 +1852,7 @@ int keystore_import_key(struct keystore - struct key_filenames file_names = { NULL, NULL, NULL }; - struct properties *key_props = NULL; - size_t secure_key_size; -+ const char *key_type; - u8 *secure_key; - u64 mkvp; - int rc; -@@ -1877,6 +1876,14 @@ int keystore_import_key(struct keystore - goto out_free_key_filenames; - } - -+ key_type = get_key_type(secure_key, secure_key_size); -+ if (key_type == NULL) { -+ warnx("Key '%s' is not a valid secure key", name); -+ free(secure_key); -+ rc = -EINVAL; -+ goto out_free_key_filenames; -+ } -+ - rc = get_master_key_verification_pattern(secure_key, secure_key_size, - &mkvp, keystore->verbose); - if (rc != 0) { -@@ -1907,7 +1914,7 @@ int keystore_import_key(struct keystore - rc = _keystore_create_info_file(keystore, name, &file_names, - description, volumes, apqns, - noapqncheck, sector_size, volume_type, -- KEY_TYPE_CCA_AESDATA); -+ key_type); - if (rc != 0) - goto out_free_props; - -@@ -2252,7 +2259,7 @@ static void _keystore_print_record(struc - const char *name, - struct properties *properties, - bool validation, const char *skey_filename, -- size_t secure_key_size, -+ size_t secure_key_size, bool is_xts, - size_t clear_key_bitsize, bool valid, - bool is_old_mk, bool reenc_pending, u64 mkvp) - { -@@ -2308,13 +2315,12 @@ static void _keystore_print_record(struc - util_rec_set(rec, REC_DESCRIPTION, - description != NULL ? description : ""); - util_rec_set(rec, REC_SEC_KEY_SIZE, "%lu bytes", secure_key_size); -- if (!validation || valid) -+ if ((!validation || valid) && clear_key_bitsize != 0) - util_rec_set(rec, REC_CLR_KEY_SIZE, "%lu bits", - clear_key_bitsize); - else - util_rec_set(rec, REC_CLR_KEY_SIZE, "(unknown)"); -- util_rec_set(rec, REC_XTS, -- IS_XTS(secure_key_size) ? "Yes" : "No"); -+ util_rec_set(rec, REC_XTS, is_xts ? "Yes" : "No"); - util_rec_set(rec, REC_KEY_TYPE, key_type); - if (validation) { - if (valid) -@@ -2525,6 +2531,7 @@ static int _keystore_process_validate(st - - _keystore_print_record(info->rec, name, properties, 1, - file_names->skey_filename, secure_key_size, -+ is_xts_key(secure_key, secure_key_size), - clear_key_bitsize, valid, is_old_mk, - _keystore_reencipher_key_exists(file_names), - mkvp); -@@ -3297,29 +3304,29 @@ static int _keystore_display_key(struct - void *private) - { - struct util_rec *rec = (struct util_rec *)private; -- struct secaeskeytoken *secure_key; -- size_t secure_key_size; -+ u8 *secure_key; -+ size_t secure_key_size, clear_key_bitsize = 0; - int rc = 0; - -- secure_key = (struct secaeskeytoken *) -- read_secure_key(file_names->skey_filename, -+ secure_key = read_secure_key(file_names->skey_filename, - &secure_key_size, keystore->verbose); - if (secure_key == NULL) - return -EIO; - -- if (secure_key_size < SECURE_KEY_SIZE) { -+ if (secure_key_size < MIN_SECURE_KEY_SIZE) { - pr_verbose(keystore, - "Size of secure key is too small: %lu expected %lu", -- secure_key_size, SECURE_KEY_SIZE); -+ secure_key_size, MIN_SECURE_KEY_SIZE); - rc = -EIO; - goto out; - } - -+ get_key_bit_size(secure_key, secure_key_size, &clear_key_bitsize); -+ - _keystore_print_record(rec, name, properties, 0, - file_names->skey_filename, secure_key_size, -- IS_XTS(secure_key_size) ? secure_key->bitsize * 2 -- : secure_key->bitsize, -- 0, 0, -+ is_xts_key(secure_key, secure_key_size), -+ clear_key_bitsize, 0, 0, - _keystore_reencipher_key_exists(file_names), 0); - - out: -@@ -3682,37 +3689,6 @@ out: - } - - /** -- * Returns the size of the secure key file -- * -- * @param[in] keystore the keystore -- * @param[in] skey_filename the file name of the secure key -- * -- * @returns the size of the secure key, or -1 in case of an error -- */ --static size_t _keystore_get_key_file_size(struct keystore *keystore, -- const char *skey_filename) --{ -- size_t secure_key_size; -- struct stat sb; -- -- if (stat(skey_filename, &sb)) { -- pr_verbose(keystore, "Key file '%s': %s", -- skey_filename, strerror(errno)); -- return -1; -- } -- -- secure_key_size = sb.st_size; -- if (secure_key_size < SECURE_KEY_SIZE) { -- pr_verbose(keystore, -- "Size of secure key is too small: %lu expected %lu", -- secure_key_size, SECURE_KEY_SIZE); -- return -1; -- } -- -- return secure_key_size; --} -- --/** - * Processing function for the cryptsetup and crypttab functions. - * Extracts the required information and calls the secondary processing function - * contained in struct crypt_info. -@@ -3738,6 +3714,7 @@ static int _keystore_process_crypt(struc - size_t secure_key_size; - size_t sector_size = 0; - char *volumes = NULL; -+ u8 *secure_key = NULL; - char *dmname; - char *temp; - int rc = 0; -@@ -3745,18 +3722,14 @@ static int _keystore_process_crypt(struc - char *ch; - int i; - -- secure_key_size = _keystore_get_key_file_size(keystore, -- file_names->skey_filename); -- if (secure_key_size < SECURE_KEY_SIZE) { -- pr_verbose(keystore, -- "Size of secure key is too small: %lu expected %lu", -- secure_key_size, SECURE_KEY_SIZE); -- rc = -EIO; -- goto out; -- } -+ secure_key = read_secure_key(file_names->skey_filename, -+ &secure_key_size, keystore->verbose); -+ if (secure_key == NULL) -+ return -EIO; - - cipher_spec = _keystore_build_cipher_spec(properties, -- IS_XTS(secure_key_size)); -+ is_xts_key(secure_key, -+ secure_key_size)); - if (cipher_spec == NULL) { - rc = -EINVAL; - goto out; -@@ -3808,6 +3781,8 @@ out: - free(cipher_spec); - if (volume_type != NULL) - free(volume_type); -+ if (secure_key != NULL) -+ free(secure_key); - return rc; - } - ---- a/zkey/pkey.c -+++ b/zkey/pkey.c -@@ -98,10 +98,8 @@ u8 *read_secure_key(const char *keyfile, - } - size = sb.st_size; - -- if (size != SECURE_KEY_SIZE && size != 2*SECURE_KEY_SIZE) { -- warnx("File '%s' has an invalid size, %lu or %lu bytes " -- "expected", keyfile, SECURE_KEY_SIZE, -- 2 * SECURE_KEY_SIZE); -+ if (size < MIN_SECURE_KEY_SIZE || size > 2 * MAX_SECURE_KEY_SIZE) { -+ warnx("File '%s' has an invalid size: %lu", keyfile, size); - return NULL; - } - -@@ -306,7 +304,7 @@ int generate_secure_key_random(int pkey_ - if (keybits == 0) - keybits = DEFAULT_KEYBITS; - -- secure_key_size = DOUBLE_KEYSIZE_FOR_XTS(SECURE_KEY_SIZE, xts); -+ secure_key_size = DOUBLE_KEYSIZE_FOR_XTS(AESDATA_KEY_SIZE, xts); - secure_key = util_malloc(secure_key_size); - - pr_verbose(verbose, "Generate key on card %02x.%04x", card, domain); -@@ -344,7 +342,7 @@ int generate_secure_key_random(int pkey_ - goto out; - } - -- memcpy(secure_key, &gensec.seckey, SECURE_KEY_SIZE); -+ memcpy(secure_key, &gensec.seckey, AESDATA_KEY_SIZE); - - if (xts) { - rc = ioctl(pkey_fd, PKEY_GENSECK, &gensec); -@@ -357,8 +355,8 @@ int generate_secure_key_random(int pkey_ - goto out; - } - -- memcpy(secure_key + SECURE_KEY_SIZE, &gensec.seckey, -- SECURE_KEY_SIZE); -+ memcpy(secure_key + AESDATA_KEY_SIZE, &gensec.seckey, -+ AESDATA_KEY_SIZE); - } - - pr_verbose(verbose, "Successfully generated a secure key"); -@@ -412,7 +410,7 @@ int generate_secure_key_clear(int pkey_f - return -EINVAL; - } - -- secure_key_size = DOUBLE_KEYSIZE_FOR_XTS(SECURE_KEY_SIZE, xts); -+ secure_key_size = DOUBLE_KEYSIZE_FOR_XTS(AESDATA_KEY_SIZE, xts); - secure_key = util_malloc(secure_key_size); - - clear_key = read_clear_key(clearkeyfile, keybits, xts, &clear_key_size, -@@ -453,7 +451,7 @@ int generate_secure_key_clear(int pkey_f - goto out; - } - -- memcpy(secure_key, &clr2sec.seckey, SECURE_KEY_SIZE); -+ memcpy(secure_key, &clr2sec.seckey, AESDATA_KEY_SIZE); - - if (xts) { - memcpy(&clr2sec.clrkey, clear_key + clear_key_size / 2, -@@ -469,8 +467,8 @@ int generate_secure_key_clear(int pkey_f - goto out; - } - -- memcpy(secure_key+SECURE_KEY_SIZE, &clr2sec.seckey, -- SECURE_KEY_SIZE); -+ memcpy(secure_key + AESDATA_KEY_SIZE, &clr2sec.seckey, -+ AESDATA_KEY_SIZE); - } - - pr_verbose(verbose, -@@ -505,21 +503,21 @@ static int validate_secure_xts_key(int p - u16 part1_keysize, u32 part1_attributes, - size_t *clear_key_bitsize, bool verbose) - { -- struct secaeskeytoken *token = (struct secaeskeytoken *)secure_key; -+ struct aesdatakeytoken *token = (struct aesdatakeytoken *)secure_key; - struct pkey_verifykey verifykey; -- struct secaeskeytoken *token2; -+ struct aesdatakeytoken *token2; - int rc; - - util_assert(pkey_fd != -1, "Internal error: pkey_fd is -1"); - util_assert(secure_key != NULL, "Internal error: secure_key is NULL"); - - /* XTS uses 2 secure key tokens concatenated to each other */ -- token2 = (struct secaeskeytoken *)(secure_key + SECURE_KEY_SIZE); -+ token2 = (struct aesdatakeytoken *)(secure_key + AESDATA_KEY_SIZE); - -- if (secure_key_size != 2 * SECURE_KEY_SIZE) { -+ if (secure_key_size != 2 * AESDATA_KEY_SIZE) { - pr_verbose(verbose, "Size of secure key is too small: " - "%lu expected %lu", secure_key_size, -- 2 * SECURE_KEY_SIZE); -+ 2 * AESDATA_KEY_SIZE); - return -EINVAL; - } - -@@ -591,17 +589,17 @@ int validate_secure_key(int pkey_fd, - size_t *clear_key_bitsize, int *is_old_mk, - bool verbose) - { -- struct secaeskeytoken *token = (struct secaeskeytoken *)secure_key; -+ struct aesdatakeytoken *token = (struct aesdatakeytoken *)secure_key; - struct pkey_verifykey verifykey; - int rc; - - util_assert(pkey_fd != -1, "Internal error: pkey_fd is -1"); - util_assert(secure_key != NULL, "Internal error: secure_key is NULL"); - -- if (secure_key_size < SECURE_KEY_SIZE) { -+ if (secure_key_size < AESDATA_KEY_SIZE) { - pr_verbose(verbose, "Size of secure key is too small: " - "%lu expected %lu", secure_key_size, -- SECURE_KEY_SIZE); -+ AESDATA_KEY_SIZE); - return -EINVAL; - } - -@@ -624,7 +622,7 @@ int validate_secure_key(int pkey_fd, - *clear_key_bitsize = verifykey.keysize; - - /* XTS uses 2 secure key tokens concatenated to each other */ -- if (secure_key_size > SECURE_KEY_SIZE) { -+ if (secure_key_size > AESDATA_KEY_SIZE) { - rc = validate_secure_xts_key(pkey_fd, - secure_key, secure_key_size, - verifykey.keysize, -@@ -656,7 +654,7 @@ int validate_secure_key(int pkey_fd, - * - * @returns 0 on success, a negative errno in case of an error - */ --int generate_key_verification_pattern(const char *key, size_t key_size, -+int generate_key_verification_pattern(const u8 *key, size_t key_size, - char *vp, size_t vp_len, bool verbose) - { - int tfmfd = -1, opfd = -1, rc = 0; -@@ -691,7 +689,7 @@ int generate_key_verification_pattern(co - } - - snprintf((char *)sa.salg_name, sizeof(sa.salg_name), "%s(paes)", -- key_size > SECURE_KEY_SIZE ? "xts" : "cbc"); -+ is_xts_key(key, key_size) ? "xts" : "cbc"); - - tfmfd = socket(AF_ALG, SOCK_SEQPACKET, 0); - if (tfmfd < 0) { -@@ -788,15 +786,15 @@ int get_master_key_verification_pattern( - size_t secure_key_size, u64 *mkvp, - bool verbose) - { -- struct secaeskeytoken *token = (struct secaeskeytoken *)secure_key; -+ struct aesdatakeytoken *token = (struct aesdatakeytoken *)secure_key; - - util_assert(secure_key != NULL, "Internal error: secure_key is NULL"); - util_assert(mkvp != NULL, "Internal error: mkvp is NULL"); - -- if (secure_key_size < SECURE_KEY_SIZE) { -+ if (secure_key_size < AESDATA_KEY_SIZE) { - pr_verbose(verbose, "Size of secure key is too small: " - "%lu expected %lu", secure_key_size, -- SECURE_KEY_SIZE); -+ AESDATA_KEY_SIZE); - return -EINVAL; - } - -@@ -817,7 +815,7 @@ bool is_cca_aes_data_key(const u8 *key, - { - struct tokenheader *hdr = (struct tokenheader *)key; - -- if (key == NULL || key_size < SECURE_KEY_SIZE) -+ if (key == NULL || key_size < AESDATA_KEY_SIZE) - return false; - - if (hdr->type != TOKEN_TYPE_CCA_INTERNAL) -@@ -829,6 +827,57 @@ bool is_cca_aes_data_key(const u8 *key, - } - - /** -+ * Check if the specified key is an XTS type key -+ * -+ * @param[in] key the secure key token -+ * @param[in] key_size the size of the secure key -+ * -+ * @returns true if the key is an XTS key type -+ */ -+bool is_xts_key(const u8 *key, size_t key_size) -+{ -+ if (is_cca_aes_data_key(key, key_size)) { -+ if (key_size == 2 * AESDATA_KEY_SIZE && -+ is_cca_aes_data_key(key + AESDATA_KEY_SIZE, -+ key_size - AESDATA_KEY_SIZE)) -+ return true; -+ } -+ -+ return false; -+} -+ -+/** -+ * Gets the size in bits of the effective key of the specified secure key -+ * -+ * @param[in] key the secure key token -+ * @param[in] key_size the size of the secure key -+ * @param[out] bitsize On return, contains the size in bits of the key. -+ * If the key size can not be determined, then 0 is -+ * passed back as bitsize. -+ * -+ * @returns 0 on success, a negative errno in case of an error -+ */ -+int get_key_bit_size(const u8 *key, size_t key_size, size_t *bitsize) -+{ -+ struct aesdatakeytoken *datakey = (struct aesdatakeytoken *)key; -+ -+ util_assert(bitsize != NULL, "Internal error: bitsize is NULL"); -+ -+ if (is_cca_aes_data_key(key, key_size)) { -+ *bitsize = datakey->bitsize; -+ if (key_size == 2 * AESDATA_KEY_SIZE) { -+ datakey = (struct aesdatakeytoken *)key + -+ AESDATA_KEY_SIZE; -+ *bitsize += datakey->bitsize; -+ } -+ } else { -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+/** - * Returns the type of the key - * - * @param[in] key the secure key token ---- a/zkey/pkey.h -+++ b/zkey/pkey.h -@@ -30,10 +30,10 @@ struct tokenheader { - - #define TOKEN_VERSION_AESDATA 0x04 - --struct secaeskeytoken { -- u8 type; /* 0x01 for internal key token */ -+struct aesdatakeytoken { -+ u8 type; /* TOKEN_TYPE_INTERNAL (0x01) for internal key token */ - u8 res0[3]; -- u8 version; /* should be 0x04 */ -+ u8 version; /* should be TOKEN_VERSION_AESDATA (0x04) */ - u8 res1[1]; - u8 flag; /* key flags */ - u8 res2[1]; -@@ -45,10 +45,13 @@ struct secaeskeytoken { - u8 tvv[4]; /* token validation value */ - } __packed; - --#define SECURE_KEY_SIZE sizeof(struct secaeskeytoken) -+#define AESDATA_KEY_SIZE sizeof(struct aesdatakeytoken) -+ -+#define MAX_SECURE_KEY_SIZE AESDATA_KEY_SIZE -+#define MIN_SECURE_KEY_SIZE AESDATA_KEY_SIZE - - struct pkey_seckey { -- u8 seckey[SECURE_KEY_SIZE]; /* the secure key blob */ -+ u8 seckey[AESDATA_KEY_SIZE]; /* the secure key blob */ - }; - - struct pkey_clrkey { -@@ -123,7 +126,7 @@ int validate_secure_key(int pkey_fd, - size_t *clear_key_bitsize, int *is_old_mk, - bool verbose); - --int generate_key_verification_pattern(const char *key, size_t key_size, -+int generate_key_verification_pattern(const u8 *key, size_t key_size, - char *vp, size_t vp_len, bool verbose); - - int get_master_key_verification_pattern(const u8 *secure_key, -@@ -131,6 +134,8 @@ int get_master_key_verification_pattern( - bool verbose); - - bool is_cca_aes_data_key(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); - - #endif ---- a/zkey/zkey-cryptsetup.c -+++ b/zkey/zkey-cryptsetup.c -@@ -1329,22 +1329,25 @@ static int activate_unbound_keyslot(int - return rc; - } - --static int check_keysize_and_cipher_mode(size_t keysize) -+static int check_keysize_and_cipher_mode(const u8 *key, size_t keysize) - { -- if (keysize == 0) { -+ if (keysize < MIN_SECURE_KEY_SIZE || -+ keysize > 2 * MAX_SECURE_KEY_SIZE) { - warnx("Invalid volume key size"); - return -EINVAL; - } - - if (strncmp(crypt_get_cipher_mode(g.cd), "xts", 3) == 0) { -- if (keysize != 2 * SECURE_KEY_SIZE) { -+ if (keysize < 2 * MIN_SECURE_KEY_SIZE || -+ (key != NULL && !is_xts_key(key, keysize))) { - warnx("The volume key size %lu is not valid for the " - "cipher mode '%s'", keysize, - crypt_get_cipher_mode(g.cd)); - return -EINVAL; - } - } else { -- if (keysize != SECURE_KEY_SIZE) { -+ if (keysize > MAX_SECURE_KEY_SIZE || -+ (key != NULL && is_xts_key(key, keysize))) { - warnx("The volume key size %lu is not valid for the " - "cipher mode '%s'", keysize, - crypt_get_cipher_mode(g.cd)); -@@ -1377,7 +1380,7 @@ static int open_keyslot(int keyslot, cha - vkeysize = crypt_get_volume_key_size(g.cd); - pr_verbose("Volume key size: %lu", vkeysize); - -- rc = check_keysize_and_cipher_mode(vkeysize); -+ rc = check_keysize_and_cipher_mode(NULL, vkeysize); - if (rc != 0) - return rc; - -@@ -1571,7 +1574,7 @@ static int reencipher_prepare(int token) - if (rc != 0) - goto out; - -- rc = generate_key_verification_pattern(key, keysize, -+ rc = generate_key_verification_pattern((u8 *)key, keysize, - reenc_tok.verification_pattern, - sizeof(reenc_tok.verification_pattern), - g.verbose); -@@ -1851,8 +1854,8 @@ static int reencipher_complete(int token - - } - -- rc = generate_key_verification_pattern(key, keysize, vp, sizeof(vp), -- g.verbose); -+ rc = generate_key_verification_pattern((u8 *)key, keysize, vp, -+ sizeof(vp), g.verbose); - if (rc != 0) { - warnx("Failed to generate the verification pattern: %s", - strerror(-rc)); -@@ -1998,7 +2001,7 @@ static int command_validate(void) - printf(" Status: %s\n", is_valid ? "Valid" : "Invalid"); - printf(" Secure key size: %lu bytes\n", keysize); - printf(" XTS type key: %s\n", -- keysize > SECURE_KEY_SIZE ? "Yes" : "No"); -+ is_xts_key((u8 *)key, keysize) ? "Yes" : "No"); - printf(" Key type: %s\n", - get_key_type((u8 *)key, keysize)); - if (is_valid) { -@@ -2076,7 +2079,7 @@ static int command_setvp(void) - - token = find_token(g.cd, PAES_VP_TOKEN_NAME); - -- rc = generate_key_verification_pattern(key, keysize, -+ rc = generate_key_verification_pattern((const u8 *)key, keysize, - vp_tok.verification_pattern, - sizeof(vp_tok.verification_pattern), - g.verbose); -@@ -2131,7 +2134,7 @@ static int command_setkey(void) - if (newkey == NULL) - return EXIT_FAILURE; - -- rc = check_keysize_and_cipher_mode(newkey_size); -+ rc = check_keysize_and_cipher_mode(newkey, newkey_size); - if (rc != 0) - goto out; - -@@ -2180,7 +2183,7 @@ static int command_setkey(void) - goto out; - } - -- rc = generate_key_verification_pattern((char *)newkey, newkey_size, vp, -+ rc = generate_key_verification_pattern(newkey, newkey_size, vp, - sizeof(vp), g.verbose); - if (rc != 0) { - warnx("Failed to generate the verification pattern: %s", ---- a/zkey/zkey.c -+++ b/zkey/zkey.c -@@ -1413,7 +1413,7 @@ static int command_validate_file(void) - goto out; - } - -- rc = generate_key_verification_pattern((char *)secure_key, -+ rc = generate_key_verification_pattern(secure_key, - secure_key_size, vp, sizeof(vp), - g.verbose); - if (rc != 0) { -@@ -1441,7 +1441,7 @@ static int command_validate_file(void) - get_key_type(secure_key, secure_key_size)); - printf(" Clear key size: %lu bits\n", clear_key_size); - printf(" XTS type key: %s\n", -- secure_key_size > SECURE_KEY_SIZE ? "Yes" : "No"); -+ is_xts_key(secure_key, secure_key_size) ? "Yes" : "No"); - printf(" Enciphered with: %s CCA master key (MKVP: %016llx)\n", - is_old_mk ? "OLD" : "CURRENT", mkvp); - printf(" Verification pattern: %.*s\n", VERIFICATION_PATTERN_LEN / 2, diff --git a/s390-tools-sles15sp2-22-zipl-move-SIGP-related-functions-and-definitions-int.patch b/s390-tools-sles15sp2-22-zipl-move-SIGP-related-functions-and-definitions-int.patch deleted file mode 100644 index a86d1c5..0000000 --- a/s390-tools-sles15sp2-22-zipl-move-SIGP-related-functions-and-definitions-int.patch +++ /dev/null @@ -1,148 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] zipl: move SIGP related functions and definitions into separate header -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: 675c854fa3239882c59a9419c776eb13bc70cf76 -Problem-ID: VS1804 - -Upstream-Description: - - zipl: move SIGP related functions and definitions into separate header - - Move SIGP related functions and definitions to - `include/boot/sigp.h`. This allows the reuse of the definitions in - assembler files. - - Reviewed-by: Stefan Haberland - Acked-by: Janosch Frank - Reviewed-by: Philipp Rudo - Signed-off-by: Marc Hartmayer - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - include/boot/sigp.h | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++ - zipl/boot/s390.h | 38 ----------------------------------- - 2 files changed, 56 insertions(+), 37 deletions(-) - ---- /dev/null -+++ b/include/boot/sigp.h -@@ -0,0 +1,55 @@ -+/* -+ * SIGP related definitions and functions. -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * s390-tools is free software; you can redistribute it and/or modify -+ * it under the terms of the MIT license. See LICENSE for details. -+ */ -+ -+#ifndef S390_SIGP_H -+#define S390_SIGP_H -+ -+/* Signal Processor Order Codes */ -+#define SIGP_STOP_AND_STORE_STATUS 9 -+#define SIGP_SET_MULTI_THREADING 22 -+#define SIGP_STORE_ASTATUS_AT_ADDRESS 23 -+ -+/* Signal Processor Condition Codes */ -+#define SIGP_CC_ORDER_CODE_ACCEPTED 0 -+#define SIGP_CC_BUSY 2 -+ -+ -+#ifndef __ASSEMBLER__ -+ -+#include -+ -+static inline int sigp(uint16_t addr, uint8_t order, uint32_t parm, -+ uint32_t *status) -+{ -+ register unsigned int reg1 asm ("1") = parm; -+ int cc; -+ -+ asm volatile( -+ " sigp %1,%2,0(%3)\n" -+ " ipm %0\n" -+ " srl %0,28\n" -+ : "=d" (cc), "+d" (reg1) : "d" (addr), "a" (order) : "cc"); -+ if (status && cc == 1) -+ *status = reg1; -+ return cc; -+} -+ -+static inline int sigp_busy(uint16_t addr, uint8_t order, uint32_t parm, -+ uint32_t *status) -+{ -+ int cc; -+ -+ do { -+ cc = sigp(addr, order, parm, status); -+ } while (cc == SIGP_CC_BUSY); -+ return cc; -+} -+ -+#endif /* __ASSEMBLER__ */ -+#endif /* S390_SIGP_H */ ---- a/zipl/boot/s390.h -+++ b/zipl/boot/s390.h -@@ -13,6 +13,7 @@ - - #include "lib/zt_common.h" - #include "libc.h" -+#include "boot/sigp.h" - - #define __pa32(x) ((uint32_t)(unsigned long)(x)) - #define __pa(x) ((unsigned long)(x)) -@@ -295,43 +296,6 @@ static inline int diag308(unsigned long - } - - /* -- * Signal Processor -- */ --#define SIGP_STOP_AND_STORE_STATUS 9 --#define SIGP_SET_MULTI_THREADING 22 --#define SIGP_STORE_ASTATUS_AT_ADDRESS 23 -- --#define SIGP_CC_ORDER_CODE_ACCEPTED 0 --#define SIGP_CC_BUSY 2 -- --static inline int sigp(uint16_t addr, uint8_t order, uint32_t parm, -- uint32_t *status) --{ -- register unsigned int reg1 asm ("1") = parm; -- int cc; -- -- asm volatile( -- " sigp %1,%2,0(%3)\n" -- " ipm %0\n" -- " srl %0,28\n" -- : "=d" (cc), "+d" (reg1) : "d" (addr), "a" (order) : "cc"); -- if (status && cc == 1) -- *status = reg1; -- return cc; --} -- --static inline int sigp_busy(uint16_t addr, uint8_t order, uint32_t parm, -- uint32_t *status) --{ -- int cc; -- -- do { -- cc = sigp(addr, order, parm, status); -- } while (cc == SIGP_CC_BUSY); -- return cc; --} -- --/* - * Store CPU address - */ - static inline unsigned short stap(void) diff --git a/s390-tools-sles15sp2-22-zkey-Introduce-the-CCA-AESCIPHER-key-type.patch b/s390-tools-sles15sp2-22-zkey-Introduce-the-CCA-AESCIPHER-key-type.patch deleted file mode 100644 index 5e3df6c..0000000 --- a/s390-tools-sles15sp2-22-zkey-Introduce-the-CCA-AESCIPHER-key-type.patch +++ /dev/null @@ -1,452 +0,0 @@ -Subject: zkey: Introduce the CCA-AESCIPHER key type -From: Ingo Franzki - -Summary: zkey: Add support for CCA AES CIPHER keys -Description: With CCA 5 there is a new secure key type, the so called - variable length symmetric cipher key token. This token format - can hold AES keys with size 128, 192 and 256 bits together - with additional attributes cryptographic bound to the key - token. The attributes may limit the usage of the key, for - example restrict export or usability scope. So this key type - is considered to be even more secure than the traditional - secure key token. This key token type is also called "CCA - AES CIPHER key", where the formerly used key token is called - "CCA AES DATA key". - The zkey as well as the zkey-cryptsetup tools are enhanced - to support AES CIPHER keys. That is, zkey can manage AES DATA - keys, as well as AES CIPHER keys. The key type must be specified - at key generation time, the default is to generate AED DATA - keys. -Upstream-ID: ddde3f354f3506521877a4e2a6082c4d597629cb -Problem-ID: SEC1717 - -Upstream-Description: - - zkey: Introduce the CCA-AESCIPHER key type - - Add definitions and helper functions to support the new - CCA-AESCIPHER key type. Also enhance existing helper functions - to support CCA-AESCIPHER keys. - - Signed-off-by: Ingo Franzki - Reviewed-by: Harald Freudenberger - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/keystore.c | 2 - zkey/pkey.c | 91 +++++++++++++++++++++++++++++---- - zkey/pkey.h | 150 +++++++++++++++++++++++++++++++++++++++++++++++++++----- - zkey/zkey.1 | 20 ++++--- - zkey/zkey.c | 4 - - 5 files changed, 235 insertions(+), 32 deletions(-) - ---- a/zkey/keystore.c -+++ b/zkey/keystore.c -@@ -341,6 +341,8 @@ static int _keystore_valid_key_type(cons - { - if (strcasecmp(key_type, KEY_TYPE_CCA_AESDATA) == 0) - return 1; -+ if (strcasecmp(key_type, KEY_TYPE_CCA_AESCIPHER) == 0) -+ return 1; - - return 0; - } ---- a/zkey/pkey.c -+++ b/zkey/pkey.c -@@ -782,23 +782,21 @@ out: - return rc; - } - --int get_master_key_verification_pattern(const u8 *secure_key, -- size_t secure_key_size, u64 *mkvp, -- bool verbose) -+int get_master_key_verification_pattern(const u8 *key, size_t key_size, -+ u64 *mkvp, bool UNUSED(verbose)) - { -- struct aesdatakeytoken *token = (struct aesdatakeytoken *)secure_key; -+ struct aesdatakeytoken *datakey = (struct aesdatakeytoken *)key; -+ struct aescipherkeytoken *cipherkey = (struct aescipherkeytoken *)key; - -- util_assert(secure_key != NULL, "Internal error: secure_key is NULL"); -+ util_assert(key != NULL, "Internal error: secure_key is NULL"); - util_assert(mkvp != NULL, "Internal error: mkvp is NULL"); - -- if (secure_key_size < AESDATA_KEY_SIZE) { -- pr_verbose(verbose, "Size of secure key is too small: " -- "%lu expected %lu", secure_key_size, -- AESDATA_KEY_SIZE); -+ if (is_cca_aes_data_key(key, key_size)) -+ *mkvp = datakey->mkvp; -+ else if (is_cca_aes_cipher_key(key, key_size)) -+ memcpy(mkvp, cipherkey->kvp, sizeof(*mkvp)); -+ else - return -EINVAL; -- } -- -- *mkvp = token->mkvp; - - return 0; - } -@@ -827,6 +825,56 @@ bool is_cca_aes_data_key(const u8 *key, - } - - /** -+ * Check if the specified key is a CCA AESCIPHER key token. -+ * -+ * @param[in] key the secure key token -+ * @param[in] key_size the size of the secure key -+ * -+ * @returns true if the key is an CCA AESCIPHER token type -+ */ -+bool is_cca_aes_cipher_key(const u8 *key, size_t key_size) -+{ -+ struct aescipherkeytoken *cipherkey = (struct aescipherkeytoken *)key; -+ -+ if (key == NULL || key_size < AESCIPHER_KEY_SIZE) -+ return false; -+ -+ if (cipherkey->type != TOKEN_TYPE_CCA_INTERNAL) -+ return false; -+ if (cipherkey->version != TOKEN_VERSION_AESCIPHER) -+ return false; -+ if (cipherkey->length > key_size) -+ return false; -+ -+ if (cipherkey->kms != 0x03) /* key wrapped by master key */ -+ return false; -+ if (cipherkey->kwm != 0x02) /* key wrapped using AESKW */ -+ return false; -+ if (cipherkey->pfv != 0x00 && cipherkey->pfv != 0x01) /* V0 or V1 */ -+ return false; -+ if (cipherkey->adv != 0x01) /* Should have ass. data sect. version 1 */ -+ return false; -+ if (cipherkey->at != 0x02) /* Algorithm: AES */ -+ return false; -+ if (cipherkey->kt != 0x0001) /* Key type: CIPHER */ -+ return false; -+ if (cipherkey->adl != 26) /* Ass. data section length should be 26 */ -+ return false; -+ if (cipherkey->kll != 0) /* Should have no key label */ -+ return false; -+ if (cipherkey->eadl != 0) /* Should have no ext associated data */ -+ return false; -+ if (cipherkey->uadl != 0) /* Should have no user associated data */ -+ return false; -+ if (cipherkey->kufc != 2) /* Should have 2 KUFs */ -+ return false; -+ if (cipherkey->kmfc != 3) /* Should have 3 KMFs */ -+ return false; -+ -+ return true; -+} -+ -+/** - * Check if the specified key is an XTS type key - * - * @param[in] key the secure key token -@@ -841,6 +889,11 @@ bool is_xts_key(const u8 *key, size_t ke - is_cca_aes_data_key(key + AESDATA_KEY_SIZE, - key_size - AESDATA_KEY_SIZE)) - return true; -+ } else if (is_cca_aes_cipher_key(key, key_size)) { -+ if (key_size == 2 * AESCIPHER_KEY_SIZE && -+ is_cca_aes_cipher_key(key + AESCIPHER_KEY_SIZE, -+ key_size - AESCIPHER_KEY_SIZE)) -+ return true; - } - - return false; -@@ -860,6 +913,7 @@ bool is_xts_key(const u8 *key, size_t ke - 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; - - util_assert(bitsize != NULL, "Internal error: bitsize is NULL"); - -@@ -870,6 +924,17 @@ int get_key_bit_size(const u8 *key, size - AESDATA_KEY_SIZE; - *bitsize += datakey->bitsize; - } -+ } else if (is_cca_aes_cipher_key(key, key_size)) { -+ if (cipherkey->pfv == 0x00) /* V0 payload */ -+ *bitsize = cipherkey->pl - 384; -+ else -+ *bitsize = 0; /* Unknown */ -+ if (key_size > cipherkey->length) { -+ cipherkey = (struct aescipherkeytoken *)key + -+ cipherkey->length; -+ if (cipherkey->pfv == 0x00) /* V0 payload */ -+ *bitsize += cipherkey->pl - 384; -+ } - } else { - return -EINVAL; - } -@@ -889,6 +954,8 @@ const char *get_key_type(const u8 *key, - { - if (is_cca_aes_data_key(key, key_size)) - return KEY_TYPE_CCA_AESDATA; -+ if (is_cca_aes_cipher_key(key, key_size)) -+ return KEY_TYPE_CCA_AESCIPHER; - - return NULL; - } ---- a/zkey/pkey.h -+++ b/zkey/pkey.h -@@ -29,6 +29,7 @@ struct tokenheader { - #define TOKEN_TYPE_CCA_INTERNAL 0x01 - - #define TOKEN_VERSION_AESDATA 0x04 -+#define TOKEN_VERSION_AESCIPHER 0x05 - - struct aesdatakeytoken { - u8 type; /* TOKEN_TYPE_INTERNAL (0x01) for internal key token */ -@@ -45,10 +46,45 @@ struct aesdatakeytoken { - u8 tvv[4]; /* token validation value */ - } __packed; - -+struct aescipherkeytoken { -+ u8 type; /* TOKEN_TYPE_INTERNAL (0x01) for internal key token */ -+ u8 res0; -+ u16 length; /* length of token */ -+ u8 version; /* should be TOKEN_VERSION_CIPHER (0x05) */ -+ u8 res1[3]; -+ u8 kms; /* key material state, should be 0x03 */ -+ u8 kvptype; /* key verification pattern type */ -+ u8 kvp[16]; /* key verification pattern */ -+ u8 kwm; /* key wrapping method, should be 0x02 */ -+ u8 kwh; /* key wrapping hash algorithm */ -+ u8 pfv; /* payload format version, should be 0x00*/ -+ u8 res2; -+ u8 adv; /* associated data section version */ -+ u8 res3; -+ u16 adl; /* associated data length */ -+ u8 kll; /* length of optional key label */ -+ u8 eadl; /* extended associated data length */ -+ u8 uadl; /* user associated data length */ -+ u8 res4; -+ u16 pl; /* payload bit length */ -+ u8 res5; -+ u8 at; /* algorithm type, should be 0x02 (AES) */ -+ u16 kt; /* key type, should be 0x001 (CIPHER) */ -+ u8 kufc; /* key usage field count */ -+ u16 kuf1; /* key usage field 1 */ -+ u16 kuf2; /* key usage field 2 */ -+ u8 kmfc; /* key management field count */ -+ u16 kmf1; /* key management field 1 */ -+ u16 kmf2; /* key management field 2 */ -+ u16 kmf3; /* key management field 3 */ -+ u8 varpart[80]; /* variable part */ -+} __packed; -+ - #define AESDATA_KEY_SIZE sizeof(struct aesdatakeytoken) -+#define AESCIPHER_KEY_SIZE sizeof(struct aescipherkeytoken) - --#define MAX_SECURE_KEY_SIZE AESDATA_KEY_SIZE --#define MIN_SECURE_KEY_SIZE AESDATA_KEY_SIZE -+#define MAX_SECURE_KEY_SIZE MAX(AESDATA_KEY_SIZE, AESCIPHER_KEY_SIZE) -+#define MIN_SECURE_KEY_SIZE MIN(AESDATA_KEY_SIZE, AESCIPHER_KEY_SIZE) - - struct pkey_seckey { - u8 seckey[AESDATA_KEY_SIZE]; /* the secure key blob */ -@@ -58,12 +94,12 @@ struct pkey_clrkey { - u8 clrkey[32]; /* 16, 24, or 32 byte clear key value */ - }; - --#define PKEY_IOCTL_MAGIC 'p' --#define AUTOSELECT 0xFFFF --#define PKEYDEVICE "/dev/pkey" --#define PKEY_KEYTYPE_AES_128 1 --#define PKEY_KEYTYPE_AES_192 2 --#define PKEY_KEYTYPE_AES_256 3 -+#define PKEY_IOCTL_MAGIC 'p' -+#define AUTOSELECT 0xFFFF -+#define PKEYDEVICE "/dev/pkey" -+#define PKEY_KEYTYPE_AES_128 1 -+#define PKEY_KEYTYPE_AES_192 2 -+#define PKEY_KEYTYPE_AES_256 3 - - struct pkey_genseck { - u16 cardnr; /* in: card to use or FFFF for any */ -@@ -97,7 +133,99 @@ struct pkey_verifykey { - - #define PKEY_VERIFYKEY _IOWR(PKEY_IOCTL_MAGIC, 0x07, struct pkey_verifykey) - -+enum pkey_key_type { -+ PKEY_TYPE_CCA_DATA = (u32) 1, -+ PKEY_TYPE_CCA_CIPHER = (u32) 2, -+}; -+ -+enum pkey_key_size { -+ PKEY_SIZE_AES_128 = (u32) 128, -+ PKEY_SIZE_AES_192 = (u32) 192, -+ PKEY_SIZE_AES_256 = (u32) 256, -+ PKEY_SIZE_UNKNOWN = (u32) 0xFFFFFFFF, -+}; -+ -+#define PKEY_FLAGS_MATCH_CUR_MKVP 0x00000002 -+#define PKEY_FLAGS_MATCH_ALT_MKVP 0x00000004 -+ -+#define PKEY_KEYGEN_XPRT_SYM 0x00008000 -+#define PKEY_KEYGEN_XPRT_UASY 0x00004000 -+#define PKEY_KEYGEN_XPRT_AASY 0x00002000 -+#define PKEY_KEYGEN_XPRT_RAW 0x00001000 -+#define PKEY_KEYGEN_XPRT_CPAC 0x00000800 -+#define PKEY_KEYGEN_XPRT_DES 0x00000080 -+#define PKEY_KEYGEN_XPRT_AES 0x00000040 -+#define PKEY_KEYGEN_XPRT_RSA 0x00000008 -+ -+struct pkey_apqn { -+ u16 card; -+ u16 domain; -+}; -+ -+struct pkey_genseck2 { -+ struct pkey_apqn *apqns; /* in: ptr to list of apqn targets */ -+ u32 apqn_entries; /* in: # of apqn target list entries */ -+ enum pkey_key_type type; /* in: key type to generate */ -+ enum pkey_key_size size; /* in: key size to generate */ -+ u32 keygenflags; /* in: key generation flags */ -+ u8 *key; /* in: pointer to key blob buffer */ -+ u32 keylen; /* in: available key blob buffer size */ -+ /* out: actual key blob size */ -+}; -+ -+#define PKEY_GENSECK2 _IOWR(PKEY_IOCTL_MAGIC, 0x11, struct pkey_genseck2) -+ -+struct pkey_clr2seck2 { -+ struct pkey_apqn *apqns; /* in: ptr to list of apqn targets */ -+ u32 apqn_entries; /* in: # of apqn target list entries */ -+ enum pkey_key_type type; /* in: key type to generate */ -+ enum pkey_key_size size; /* in: key size to generate */ -+ u32 keygenflags; /* in: key generation flags */ -+ struct pkey_clrkey clrkey; /* in: the clear key value */ -+ u8 *key; /* in: pointer to key blob buffer */ -+ u32 keylen; /* in: available key blob buffer size */ -+ /* out: actual key blob size */ -+}; -+ -+#define PKEY_CLR2SECK2 _IOWR(PKEY_IOCTL_MAGIC, 0x12, struct pkey_clr2seck2) -+ -+struct pkey_verifykey2 { -+ u8 *key; /* in: pointer to key blob */ -+ u32 keylen; /* in: key blob size */ -+ u16 cardnr; /* in/out: card number */ -+ u16 domain; /* in/out: domain number */ -+ enum pkey_key_type type; /* out: the key type */ -+ enum pkey_key_size size; /* out: the key size */ -+ u32 flags; /* out: additional key info flags */ -+}; -+ -+#define PKEY_VERIFYKEY2 _IOWR(PKEY_IOCTL_MAGIC, 0x17, struct pkey_verifykey2) -+ -+struct pkey_apqns4key { -+ u8 *key; /* in: pointer to key blob */ -+ u32 keylen; /* in: key blob size */ -+ u32 flags; /* in: match controlling flags */ -+ struct pkey_apqn *apqns; /* in/out: ptr to list of apqn targets*/ -+ u32 apqn_entries; /* in: max # of apqn entries in list */ -+ /* out: # apqns stored into the list */ -+}; -+ -+#define PKEY_APQNS4K _IOWR(PKEY_IOCTL_MAGIC, 0x1B, struct pkey_apqns4key) -+ -+struct pkey_apqns4keytype { -+ enum pkey_key_type type; /* in: key type */ -+ u8 cur_mkvp[32]; /* in: current mkvp */ -+ u8 alt_mkvp[32]; /* in: alternate mkvp */ -+ u32 flags; /* in: match controlling flags */ -+ struct pkey_apqn *apqns; /* in/out: ptr to list of apqn targets*/ -+ u32 apqn_entries; /* in: max # of apqn entries in list */ -+ /* out: # apqns stored into the list */ -+}; -+ -+#define PKEY_APQNS4KT _IOWR(PKEY_IOCTL_MAGIC, 0x1C, struct pkey_apqns4keytype) -+ - #define KEY_TYPE_CCA_AESDATA "CCA-AESDATA" -+#define KEY_TYPE_CCA_AESCIPHER "CCA-AESCIPHER" - - #define PAES_BLOCK_SIZE 16 - #define ENC_ZERO_LEN (2 * PAES_BLOCK_SIZE) -@@ -129,11 +257,11 @@ int validate_secure_key(int pkey_fd, - int generate_key_verification_pattern(const u8 *key, size_t key_size, - char *vp, size_t vp_len, bool verbose); - --int get_master_key_verification_pattern(const u8 *secure_key, -- size_t secure_key_size, u64 *mkvp, -- bool verbose); -+int get_master_key_verification_pattern(const u8 *key, size_t key_size, -+ u64 *mkvp, bool verbose); - - 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_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); ---- a/zkey/zkey.1 -+++ b/zkey/zkey.1 -@@ -134,10 +134,14 @@ additional information can be associated - .B \-\-sector-size - options. - .PP --You can generate different types of secure keys: \fBCCA-AESDATA\fP keys. --Specify the type of the secure key using the -+You can generate different types of secure keys: \fBCCA-AESDATA\fP keys, and -+\fBCCA-AESCIPHER\fP keys. Specify the type of the secure key using the - .B \-\-key\-type - option. The default key type is CCA-AESDATA. -+.PP -+.B Note: -+Secure keys of type \fBCCA-AESCIPHER\fP require an IBM cryptographic -+adapter in CCA coprocessor mode of version 6 or later, e.g. a CEX6C. - . - .SS "Validating secure AES keys" - . -@@ -741,9 +745,11 @@ the default volume type is \fBplain\fP. - This option is only used for secure keys contained in the secure key repository. - .TP - .BR \-K ", " \-\-key-type\~\fItype\fP --Specifies the key type of the secure key. Possible values are \fBCCA-AESDATA\fP. --If this option is omitted, then a secure key of type --CCA-AESDATA is generated. -+Specifies the key type of the secure key. Possible values are \fBCCA-AESDATA\fP -+and \fBCCA-AESCIPHER\fP. If this option is omitted, then a secure key of type -+CCA-AESDATA is generated. Secure keys of type \fBCCA-AESCIPHER\fP require an -+IBM cryptographic adapter in CCA coprocessor mode of version 6 or later, e.g. -+a CEX6C. - . - . - . -@@ -925,8 +931,8 @@ has been compiled with LUKS2 support ena - This option is only used for secure keys contained in the secure key repository. - .TP - .BR \-K ", " \-\-key-type\~\fItype\fP --Specifies the key type of the secure key. Possible values are \fBCCA-AESDATA\fP. --Only keys with the specified key type are listed. -+Specifies the key type of the secure key. Possible values are \fBCCA-AESDATA\fP -+and \fBCCA-AESCIPHER\fP. Only keys with the specified key type are listed. - This option is only used for secure keys contained in the secure key repository. - . - . ---- a/zkey/zkey.c -+++ b/zkey/zkey.c -@@ -221,7 +221,7 @@ static struct util_opt opt_vec[] = { - .option = { "key-type", required_argument, NULL, 'K'}, - .argument = "type", - .desc = "The type of the key. Possible values are '" -- KEY_TYPE_CCA_AESDATA"'. " -+ KEY_TYPE_CCA_AESDATA"' and '"KEY_TYPE_CCA_AESCIPHER"'. " - "When this option is omitted, the default is '" - KEY_TYPE_CCA_AESDATA"'", - .command = COMMAND_GENERATE, -@@ -446,7 +446,7 @@ static struct util_opt opt_vec[] = { - .option = { "key-type", required_argument, NULL, 'K'}, - .argument = "type", - .desc = "The type of the key. Possible values are '" -- KEY_TYPE_CCA_AESDATA"'. " -+ KEY_TYPE_CCA_AESDATA"' and '"KEY_TYPE_CCA_AESCIPHER"'. " - "Use this option to list all keys with the specified " - "key type.", - .command = COMMAND_LIST, diff --git a/s390-tools-sles15sp2-23-zipl-add-SIGP_SET_ARCHITECTURE-to-sigp.h-and-use-it.patch b/s390-tools-sles15sp2-23-zipl-add-SIGP_SET_ARCHITECTURE-to-sigp.h-and-use-it.patch deleted file mode 100644 index bba542b..0000000 --- a/s390-tools-sles15sp2-23-zipl-add-SIGP_SET_ARCHITECTURE-to-sigp.h-and-use-it.patch +++ /dev/null @@ -1,117 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] zipl: add SIGP_SET_ARCHITECTURE to sigp.h and use it -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: 0e385a81caf7c266c0784613e0264c03271eb99a -Problem-ID: VS1804 - -Upstream-Description: - - zipl: add SIGP_SET_ARCHITECTURE to sigp.h and use it - - This makes the code easier to read. - - Reviewed-by: Philipp Rudo - Reviewed-by: Stefan Haberland - Signed-off-by: Marc Hartmayer - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - include/boot/sigp.h | 1 + - zipl/boot/head.S | 6 ++++-- - zipl/boot/stage3.c | 6 ++++-- - zipl/boot/tape0.S | 6 ++++-- - 4 files changed, 13 insertions(+), 6 deletions(-) - ---- a/include/boot/sigp.h -+++ b/include/boot/sigp.h -@@ -12,6 +12,7 @@ - - /* Signal Processor Order Codes */ - #define SIGP_STOP_AND_STORE_STATUS 9 -+#define SIGP_SET_ARCHITECTURE 18 - #define SIGP_SET_MULTI_THREADING 22 - #define SIGP_STORE_ASTATUS_AT_ADDRESS 23 - ---- a/zipl/boot/head.S -+++ b/zipl/boot/head.S -@@ -9,16 +9,18 @@ - * it under the terms of the MIT license. See LICENSE for details. - */ - -+#include "boot/sigp.h" -+ - .section .text.start - .globl _start - _start: - basr %r13,0 - 0: la %r7,2 /* First try code 2: */ - la %r6,0 /* 64 bit psws are restored */ -- sigp %r7,%r6,0x12 /* Switch to 64 bit */ -+ sigp %r7,%r6,SIGP_SET_ARCHITECTURE /* Switch to 64 bit */ - bc 8,.Lswitched_64-0b(%r13) /* Accepted ? */ - la %r7,1 /* Failed - try code 1 */ -- sigp %r7,%r6,0x12 /* Switch to 64 bit */ -+ sigp %r7,%r6,SIGP_SET_ARCHITECTURE /* Switch to 64 bit */ - .Lswitched_64: - sam64 /* Switch to 64 bit addr mode */ - basr %r13,0 ---- a/zipl/boot/stage3.c -+++ b/zipl/boot/stage3.c -@@ -10,6 +10,7 @@ - */ - - #include "libc.h" -+#include "boot/sigp.h" - #include "s390.h" - #include "stage3.h" - #include "error.h" -@@ -194,11 +195,12 @@ static inline void __noreturn start_kern - " sam31\n" - " sr %r1,%r1\n" - " sr %r2,%r2\n" -- " sigp %r1,%r2,0x12\n" -+ " sigp %r1,%r2,%[order]\n" - " lpsw 0\n" - : [addr] "=&d" (addr), - [code] "+&d" (code) -- : [psw] "a" (psw) ); -+ : [psw] "a" (psw), -+ [order] "L" (SIGP_SET_ARCHITECTURE)); - while (1); - } - ---- a/zipl/boot/tape0.S -+++ b/zipl/boot/tape0.S -@@ -7,6 +7,8 @@ - # it under the terms of the MIT license. See LICENSE for details. - # - -+#include "boot/sigp.h" -+ - IPL_BS = 1024 # block size for tape access - IPL_OFF = 0x4000 # temporary kernel load addr - COMMAND_LINE_SIZE = 896 # max command line length -@@ -184,10 +186,10 @@ iplstart: - 0: - la %r7,2 #/* First try code 2: */ - la %r6,0 #/* 64 bit psws are restored */ -- sigp %r7,%r6,0x12 #/* Switch to 64 bit */ -+ sigp %r7,%r6,SIGP_SET_ARCHITECTURE #/* Switch to 64 bit */ - bc 8,.Lswitched_64-0b(%r13) #/* Accepted ? */ - la %r7,1 #/* Failed - try code 1 */ -- sigp %r7,%r6,0x12 #/* Switch to 64 bit */ -+ sigp %r7,%r6,SIGP_SET_ARCHITECTURE #/* Switch to 64 bit */ - .Lswitched_64: - sam64 #/* Switch to 64 bit addr mode */ - basr %r13,0 diff --git a/s390-tools-sles15sp2-23-zkey-Add-wrappers-for-the-new-IOCTLs-with-fallback-t.patch b/s390-tools-sles15sp2-23-zkey-Add-wrappers-for-the-new-IOCTLs-with-fallback-t.patch deleted file mode 100644 index a79d97e..0000000 --- a/s390-tools-sles15sp2-23-zkey-Add-wrappers-for-the-new-IOCTLs-with-fallback-t.patch +++ /dev/null @@ -1,278 +0,0 @@ -Subject: zkey: Add wrappers for the new IOCTLs with fallback to the old once -From: Ingo Franzki - -Summary: zkey: Add support for CCA AES CIPHER keys -Description: With CCA 5 there is a new secure key type, the so called - variable length symmetric cipher key token. This token format - can hold AES keys with size 128, 192 and 256 bits together - with additional attributes cryptographic bound to the key - token. The attributes may limit the usage of the key, for - example restrict export or usability scope. So this key type - is considered to be even more secure than the traditional - secure key token. This key token type is also called "CCA - AES CIPHER key", where the formerly used key token is called - "CCA AES DATA key". - The zkey as well as the zkey-cryptsetup tools are enhanced - to support AES CIPHER keys. That is, zkey can manage AES DATA - keys, as well as AES CIPHER keys. The key type must be specified - at key generation time, the default is to generate AED DATA - keys. -Upstream-ID: d4027e6506963fbf995992e32490d56a6f7ea587 -Problem-ID: SEC1717 - -Upstream-Description: - - zkey: Add wrappers for the new IOCTLs with fallback to the old once - - By default the new pkey IOCTL are used. In case the pkey device does not - support the new IOCTLs (i.e. errno ENOTTY is returned), then the wrapper - falls back to the old IOCTLs. The old IOCTLs only support secure keys of - type CCA-AESDATA. - - Signed-off-by: Ingo Franzki - Reviewed-by: Harald Freudenberger - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/pkey.c | 228 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 228 insertions(+) - ---- a/zkey/pkey.c -+++ b/zkey/pkey.c -@@ -270,6 +270,234 @@ out: - } - - /** -+ * Returns the PKEY_KEYTYPE_xxx value for the specified key size. -+ * -+ * @param[in] keysize the key size in bits -+ * -+ * @returns the PKEY_KEYTYPE_xxx value or 0 for an unknown key size -+ */ -+static u32 keysize_to_keytype(enum pkey_key_size keysize) -+{ -+ switch (keysize) { -+ case PKEY_SIZE_AES_128: -+ return PKEY_KEYTYPE_AES_128; -+ case PKEY_SIZE_AES_192: -+ return PKEY_KEYTYPE_AES_192; -+ case PKEY_SIZE_AES_256: -+ return PKEY_KEYTYPE_AES_256; -+ default: -+ return 0; -+ } -+} -+ -+/** -+ * Returns the PKEY_SIZE_xxx value for the specified keybits. -+ * -+ * @param[in] keybits the key size in bits -+ * -+ * @returns thePKEY_SIZE_xxx value or 0 for an unknown key size -+ */ -+static enum pkey_key_size keybits_to_keysize(u32 keybits) -+{ -+ switch (keybits) { -+ case 128: -+ return PKEY_SIZE_AES_128; -+ case 192: -+ return PKEY_SIZE_AES_192; -+ case 256: -+ return PKEY_SIZE_AES_256; -+ default: -+ return PKEY_SIZE_UNKNOWN; -+ } -+} -+ -+/* -+ * Wrapper for the PKEY_GENSECK/PKEY_GENSECK2 IOCTL to generate a secure -+ * key of any type by random. If the newer PKEY_GENSECK2 IOCTL is not supported -+ * by the pkey device, then it falls back to the older PKEY_GENSECK IOCTL -+ * -+ * @param[in] pkey_fd the pkey file descriptor -+ * @param[in/out] genseck info about key to generate -+ * @param[in] verbose if true, verbose messages are printed -+ * -+ * @returns 0 on success, a negative errno in case of an error -+ */ -+static int pkey_genseck2(int pkey_fd, struct pkey_genseck2 *genseck2, -+ bool verbose) -+{ -+ struct pkey_genseck genseck; -+ int rc; -+ u32 i; -+ -+ util_assert(pkey_fd != -1, "Internal error: pkey_fd is -1"); -+ util_assert(genseck2 != NULL, "Internal error: genseck2 is NULL"); -+ -+ rc = ioctl(pkey_fd, PKEY_GENSECK2, genseck2); -+ if (rc != 0 && errno != ENOTTY) -+ return -errno; -+ if (rc == 0) -+ return 0; -+ -+ /* New IOCTL is not available, fall back to old one */ -+ pr_verbose(verbose, "ioctl PKEY_GENSECK2 not supported, fall back to " -+ "PKEY_GENSECK"); -+ -+ if (genseck2->type != PKEY_TYPE_CCA_DATA) { -+ warnx("Key-type is not supported"); -+ return -ENOTSUP; -+ } -+ -+ if (genseck2->keylen < AESDATA_KEY_SIZE) -+ return -EINVAL; -+ -+ memset(&genseck, 0, sizeof(genseck)); -+ -+ genseck.keytype = keysize_to_keytype(genseck2->size); -+ if (genseck.keytype == 0) -+ return -EINVAL; -+ -+ for (i = 0; i < genseck2->apqn_entries; i++) { -+ genseck.cardnr = genseck2->apqns[i].card; -+ genseck.domain = genseck2->apqns[i].domain; -+ -+ rc = ioctl(pkey_fd, PKEY_GENSECK, &genseck); -+ if (rc != 0) -+ continue; -+ -+ memcpy(genseck2->key, &genseck.seckey.seckey, AESDATA_KEY_SIZE); -+ genseck2->keylen = AESDATA_KEY_SIZE; -+ return 0; -+ } -+ -+ return -errno; -+} -+ -+/* -+ * Wrapper for the PKEY_CLR2SECK/PKEY_CLR2SECK2 IOCTL to generate a secure -+ * key of any type from a clear key. If the newer PKEY_CLR2SECK2 IOCTL is not -+ * supported by the pkey device, then it falls back to the older PKEY_CLR2SECK -+ * IOCTL -+ * -+ * @param[in] pkey_fd the pkey file descriptor -+ * @param[in/out] clr2seck2 info about key to generate -+ * @param[in] verbose if true, verbose messages are printed -+ * -+ * @returns 0 on success, a negative errno in case of an error -+ */ -+static int pkey_clr2seck2(int pkey_fd, struct pkey_clr2seck2 *clr2seck2, -+ bool verbose) -+{ -+ struct pkey_clr2seck clr2seck; -+ int rc; -+ u32 i; -+ -+ util_assert(pkey_fd != -1, "Internal error: pkey_fd is -1"); -+ util_assert(clr2seck2 != NULL, "Internal error: clr2seck2 is NULL"); -+ -+ rc = ioctl(pkey_fd, PKEY_CLR2SECK2, clr2seck2); -+ if (rc != 0 && errno != ENOTTY) -+ return -errno; -+ if (rc == 0) -+ return 0; -+ -+ /* New IOCTL is not available, fall back to old one */ -+ pr_verbose(verbose, "ioctl PKEY_CLR2SECK2 not supported, fall back to " -+ "PKEY_CLR2SECK"); -+ -+ if (clr2seck2->type != PKEY_TYPE_CCA_DATA) { -+ warnx("Key-type is not supported"); -+ return -ENOTSUP; -+ } -+ -+ if (clr2seck2->keylen < AESDATA_KEY_SIZE) -+ return -EINVAL; -+ -+ memset(&clr2seck, 0, sizeof(clr2seck)); -+ clr2seck.clrkey = clr2seck2->clrkey; -+ -+ clr2seck.keytype = keysize_to_keytype(clr2seck2->size); -+ if (clr2seck.keytype == 0) -+ return -EINVAL; -+ -+ for (i = 0; i < clr2seck2->apqn_entries; i++) { -+ clr2seck.cardnr = clr2seck2->apqns[i].card; -+ clr2seck.domain = clr2seck2->apqns[i].domain; -+ -+ rc = ioctl(pkey_fd, PKEY_CLR2SECK, &clr2seck); -+ if (rc != 0) -+ continue; -+ -+ memcpy(clr2seck2->key, &clr2seck.seckey.seckey, -+ AESDATA_KEY_SIZE); -+ clr2seck2->keylen = AESDATA_KEY_SIZE; -+ return 0; -+ } -+ -+ return -errno; -+} -+ -+/* -+ * Wrapper for the PKEY_VERIFYKEY/PKEY_VERIFYKEY2 IOCTL to verify a secure -+ * key of any type. If the newer PKEY_VERIFYKEY2 IOCTL is not supported -+ * by the pkey device, then it falls back to the older PKEY_VERIFYKEY IOCTL -+ * -+ * @param[in] pkey_fd the pkey file descriptor -+ * @param[in/out] verifykey2 info about key to verify -+ * @param[in] verbose if true, verbose messages are printed -+ * -+ * @returns 0 on success, a negative errno in case of an error -+ */ -+static int pkey_verifyseck2(int pkey_fd, struct pkey_verifykey2 *verifykey2, -+ bool verbose) -+{ -+ struct pkey_verifykey verifykey; -+ int rc; -+ -+ util_assert(pkey_fd != -1, "Internal error: pkey_fd is -1"); -+ util_assert(verifykey2 != NULL, "Internal error: verifyseck2 is NULL"); -+ -+ rc = ioctl(pkey_fd, PKEY_VERIFYKEY2, verifykey2); -+ if (rc != 0 && errno != ENOTTY) -+ return -errno; -+ if (rc == 0) -+ return 0; -+ -+ /* New IOCTL is not available, fall back to old one */ -+ pr_verbose(verbose, "ioctl PKEY_VERIFYKEY2 not supported, fall back to " -+ "PKEY_VERIFYKEY"); -+ -+ if (!is_cca_aes_data_key(verifykey2->key, verifykey2->keylen)) -+ return -ENODEV; -+ -+ memset(&verifykey, 0, sizeof(verifykey)); -+ memcpy(&verifykey.seckey, verifykey2->key, sizeof(verifykey.seckey)); -+ -+ /* -+ * Note: the old IOCTL does not support to check a specific card and -+ * domain. If falling back to the old IOCTL, this input is silently -+ * ignored, and all APQNs currently available in the system are used. -+ */ -+ rc = ioctl(pkey_fd, PKEY_VERIFYKEY, &verifykey); -+ if (rc != 0) -+ return -errno; -+ -+ if ((verifykey.attributes & PKEY_VERIFY_ATTR_AES) == 0) -+ return -ENODEV; -+ -+ verifykey2->type = PKEY_TYPE_CCA_DATA; -+ verifykey2->cardnr = verifykey.cardnr; -+ verifykey2->domain = verifykey.domain; -+ verifykey2->size = keybits_to_keysize(verifykey.keysize); -+ -+ if (verifykey.attributes & PKEY_VERIFY_ATTR_OLD_MKVP) -+ verifykey2->flags = PKEY_FLAGS_MATCH_ALT_MKVP; -+ else -+ verifykey2->flags = PKEY_FLAGS_MATCH_CUR_MKVP; -+ -+ return 0; -+} -+ -+/** - * Generate a secure key by random - * - * @param[in] pkey_fd the pkey file descriptor diff --git a/s390-tools-sles15sp2-24-zipl-stage3-make-IPL_DEVICE-definition-consistent-wi.patch b/s390-tools-sles15sp2-24-zipl-stage3-make-IPL_DEVICE-definition-consistent-wi.patch deleted file mode 100644 index 46043aa..0000000 --- a/s390-tools-sles15sp2-24-zipl-stage3-make-IPL_DEVICE-definition-consistent-wi.patch +++ /dev/null @@ -1,56 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] zipl/stage3: make IPL_DEVICE definition consistent with tape0.S -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: d884fb8db4c4f383780d6fc8087abd8f80e1c8b8 -Problem-ID: VS1804 - -Upstream-Description: - - zipl/stage3: make IPL_DEVICE definition consistent with tape0.S - - Make `IPL_DEVICE` definition consistent with the kernel definition and - the definition in tape0.S. This allows us to refactor the code later. - - Reviewed-by: Philipp Rudo - Reviewed-by: Stefan Haberland - Signed-off-by: Marc Hartmayer - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - zipl/boot/stage3.c | 2 +- - zipl/boot/stage3.h | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - ---- a/zipl/boot/stage3.c -+++ b/zipl/boot/stage3.c -@@ -292,7 +292,7 @@ void start(void) - /* store subchannel ID into low core and into new kernel space */ - subchannel_id = S390_lowcore.subchannel_id; - *(unsigned int *)__LC_IPLDEV = subchannel_id; -- *(unsigned int *)IPL_DEVICE = subchannel_id; -+ *(unsigned long long *)IPL_DEVICE = subchannel_id; - - /* if valid command line is given, copy it into new kernel space */ - if (_parm_addr != UNSPECIFIED_ADDRESS) { ---- a/zipl/boot/stage3.h -+++ b/zipl/boot/stage3.h -@@ -17,7 +17,7 @@ - - #include "boot/ipl.h" - --#define IPL_DEVICE 0x10404UL -+#define IPL_DEVICE 0x10400UL - #define INITRD_START 0x10408UL - #define INITRD_SIZE 0x10410UL - #define OLDMEM_BASE 0x10418UL diff --git a/s390-tools-sles15sp2-24-zkey-Add-helper-functions-to-build-lists-of-APQNs.patch b/s390-tools-sles15sp2-24-zkey-Add-helper-functions-to-build-lists-of-APQNs.patch deleted file mode 100644 index f2cbd56..0000000 --- a/s390-tools-sles15sp2-24-zkey-Add-helper-functions-to-build-lists-of-APQNs.patch +++ /dev/null @@ -1,439 +0,0 @@ -Subject: zkey: Add helper functions to build lists of APQNs -From: Ingo Franzki - -Summary: zkey: Add support for CCA AES CIPHER keys -Description: With CCA 5 there is a new secure key type, the so called - variable length symmetric cipher key token. This token format - can hold AES keys with size 128, 192 and 256 bits together - with additional attributes cryptographic bound to the key - token. The attributes may limit the usage of the key, for - example restrict export or usability scope. So this key type - is considered to be even more secure than the traditional - secure key token. This key token type is also called "CCA - AES CIPHER key", where the formerly used key token is called - "CCA AES DATA key". - The zkey as well as the zkey-cryptsetup tools are enhanced - to support AES CIPHER keys. That is, zkey can manage AES DATA - keys, as well as AES CIPHER keys. The key type must be specified - at key generation time, the default is to generate AED DATA - keys. -Upstream-ID: 663d362ff3b1036476bfce9e2563272bab087013 -Problem-ID: SEC1717 - -Upstream-Description: - - zkey: Add helper functions to build lists of APQNs - - The new IOCTLs are based on list of APQNs that they try to send - the request to. Add some helper functions to build such lists - of APQNs based on the key type, and optionally a given mkvp. - - Signed-off-by: Ingo Franzki - Reviewed-by: Harald Freudenberger - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/pkey.c | 383 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 383 insertions(+) - ---- a/zkey/pkey.c -+++ b/zkey/pkey.c -@@ -46,6 +46,8 @@ - - #define DEFAULT_KEYBITS 256 - -+#define INITIAL_APQN_ENTRIES 16 -+ - /** - * Opens the pkey device and returns its file descriptor. - * -@@ -498,6 +500,387 @@ static int pkey_verifyseck2(int pkey_fd, - } - - /** -+ * Print a list of APQNs if verbose is set -+ */ -+static void pr_verbose_apqn_list(bool verbose, struct pkey_apqn *list, u32 num) -+{ -+ u32 i; -+ -+ if (!verbose) -+ return; -+ -+ for (i = 0; i < num ; i++) -+ warnx(" APQN: %02x.%04x", list[i].card, list[i].domain); -+} -+ -+/** -+ * Filter a n array list of APQNs (struct pkey_apqn) by a list of APQN strings. -+ * -+ * @param[in] apqn_list a zero terminated array of pointers to C-strings -+ * @param[in/out] apqns A list of APQNs as array of struct pkey_apqn to -+ * filter. The list is modified during filtering. -+ * @param[in/out] apqn_entries Number of entries in the list of APQNs. The -+ * number is modified during filtering. -+ * -+ * @returns 0 on success, a negative errno in case of an error -+ */ -+static int filter_apqn_list(const char **apqn_list, struct pkey_apqn **apqns, -+ u32 *apqn_entries) -+{ -+ unsigned int count, i, k, card, domain; -+ struct pkey_apqn *list = *apqns; -+ bool found; -+ -+ if (apqn_list == NULL) -+ return 0; -+ -+ for (count = 0; apqn_list[count] != NULL; count++) -+ ; -+ if (count == 0) -+ return 0; -+ -+ for (i = 0; i < *apqn_entries; i++) { -+ found = false; -+ for (k = 0; apqn_list[k] != NULL; k++) { -+ if (sscanf(apqn_list[k], "%x.%x", &card, &domain) != 2) -+ return -EINVAL; -+ -+ if (list[i].card == card && list[i].domain == domain) { -+ found = true; -+ break; -+ } -+ } -+ -+ if (!found) { -+ if (i < *apqn_entries - 1) -+ memmove(&list[i], &list[i+1], -+ (*apqn_entries - i - 1) * -+ sizeof(struct pkey_apqn)); -+ (*apqn_entries)--; -+ i--; -+ } -+ } -+ -+ return 0; -+} -+ -+/** -+ * Build a list of APQNs in the form accepted by the pkey IOCTLs from the -+ * List of APQNs as zero terminated array of pointers to C-strings that -+ * are usable for the CCA-AESDATA key type. -+ * -+ * @param[in] apqn_list a zero terminated array of pointers to C-strings -+ * @param[out] apqns A list of APQNs as array of struct pkey_apqn. The -+ * list must be freed by the caller using free(). -+ * @param[out] apqn_entries Number of entries in the list of APQNs -+ * @param[in] verbose if true, verbose messages are printed -+ * -+ * @returns 0 on success, a negative errno in case of an error -+ */ -+static int build_apqn_list_for_aes_data(const char **apqn_list, -+ struct pkey_apqn **apqns, -+ u32 *apqn_entries, bool verbose) -+{ -+ unsigned int card, domain, count = 0; -+ struct pkey_apqn *list = NULL; -+ u32 list_entries = 0; -+ int i; -+ -+ pr_verbose(verbose, "Build a list of APQNs for CCA-AESDATA"); -+ -+ if (apqn_list != NULL) -+ for (count = 0; apqn_list[count] != NULL; count++) -+ ; -+ -+ if (count > 0) { -+ list = util_malloc(count * sizeof(struct pkey_apqn)); -+ list_entries = count; -+ -+ for (i = 0; apqn_list[i] != NULL; i++) { -+ if (sscanf(apqn_list[i], "%x.%x", &card, &domain) != 2) -+ return -EINVAL; -+ -+ list[i].card = card; -+ list[i].domain = domain; -+ } -+ -+ } else { -+ /* -+ * Although the new pkey IOCTLs do not support APQN entries -+ * with ANY indication, build an ANY-list here. If we get here, -+ * then the new IOCTLs are not available, and it will fall back -+ * to the old IOCTL which do support ANY specifications. -+ */ -+ list = util_malloc(sizeof(struct pkey_apqn)); -+ list_entries = 1; -+ -+ list[0].card = AUTOSELECT; -+ list[0].domain = AUTOSELECT; -+ } -+ -+ *apqns = list; -+ *apqn_entries = list_entries; -+ -+ pr_verbose(verbose, "%u APQNs found", list_entries); -+ pr_verbose_apqn_list(verbose, list, list_entries); -+ return 0; -+} -+ -+/** -+ * Build a list of APQNs in the form accepted by the pkey IOCTLs from the -+ * List of APQNs as zero terminated array of pointers to C-strings that -+ * are usable for the specified key type. -+ * -+ * @param[in] pkey_fd the pkey file descriptor -+ * @param[in] type the key type -+ * @param[in] apqn_list a zero terminated array of pointers to C-strings -+ * @param[out] apqns A list of APQNs as array of struct pkey_apqn. The -+ * list must be freed by the caller using free(). -+ * @param[out] apqn_entries Number of entries in the list of APQNs -+ * @param[in] verbose if true, verbose messages are printed -+ * -+ * @returns 0 on success, a negative errno in case of an error -+ */ -+static int build_apqn_list_for_key_type(int pkey_fd, enum pkey_key_type type, -+ const char **apqn_list, -+ struct pkey_apqn **apqns, -+ u32 *apqn_entries, bool verbose) -+{ -+ struct pkey_apqns4keytype apqns4keytype; -+ int rc; -+ -+ util_assert(pkey_fd != -1, "Internal error: pkey_fd is -1"); -+ util_assert(apqns != NULL, "Internal error: apqns is NULL"); -+ util_assert(apqn_entries != NULL, -+ "Internal error: apqn_entries is NULL"); -+ -+ pr_verbose(verbose, "Build a list of APQNs for key type %d", type); -+ -+ memset(&apqns4keytype, 0, sizeof(apqns4keytype)); -+ apqns4keytype.type = type; -+ apqns4keytype.apqn_entries = INITIAL_APQN_ENTRIES; -+ apqns4keytype.apqns = (struct pkey_apqn *)util_malloc( -+ apqns4keytype.apqn_entries * sizeof(struct pkey_apqn)); -+ -+ do { -+ rc = ioctl(pkey_fd, PKEY_APQNS4KT, &apqns4keytype); -+ if (rc == 0) -+ break; -+ rc = -errno; -+ pr_verbose(verbose, "ioctl PKEY_APQNS4KT rc: %s", -+ strerror(-rc)); -+ -+ switch (rc) { -+ case -ENOSPC: -+ free(apqns4keytype.apqns); -+ apqns4keytype.apqns = (struct pkey_apqn *) -+ util_malloc(apqns4keytype.apqn_entries * -+ sizeof(struct pkey_apqn)); -+ continue; -+ case -ENOTTY: -+ /* -+ * New IOCTL is not available: build the list -+ * manually (Key type CCA-AESDATA only) -+ */ -+ free(apqns4keytype.apqns); -+ -+ if (type != PKEY_TYPE_CCA_DATA) -+ return -ENOTSUP; -+ -+ rc = build_apqn_list_for_aes_data(apqn_list, apqns, -+ apqn_entries, -+ verbose); -+ return rc; -+ default: -+ goto out; -+ } -+ } while (rc != 0); -+ -+ if (apqns4keytype.apqn_entries == 0) { -+ pr_verbose(verbose, "No APQN available for key type %d", type); -+ rc = -ENODEV; -+ goto out; -+ } -+ -+ rc = filter_apqn_list(apqn_list, &apqns4keytype.apqns, -+ &apqns4keytype.apqn_entries); -+ if (rc != 0) -+ goto out; -+ -+ if (apqns4keytype.apqn_entries == 0) { -+ pr_verbose(verbose, "No APQN available for key type %d", type); -+ rc = -ENODEV; -+ goto out; -+ } -+ -+ pr_verbose(verbose, "%u APQNs found", apqns4keytype.apqn_entries); -+ pr_verbose_apqn_list(verbose, apqns4keytype.apqns, -+ apqns4keytype.apqn_entries); -+ -+out: -+ if (rc == 0) { -+ *apqns = apqns4keytype.apqns; -+ *apqn_entries = apqns4keytype.apqn_entries; -+ } else { -+ *apqns = NULL; -+ *apqn_entries = 0; -+ free(apqns4keytype.apqns); -+ } -+ -+ return rc; -+} -+ -+/** -+ * Build a list of APQNs in the form accepted by the pkey IOCTLs from the -+ * List of APQNs as zero terminated array of pointers to C-strings that are -+ * usable for the specufied key. -+ * -+ * @param[in] pkey_fd the pkey file descriptor -+ * @param[in] key the key -+ * @param[in] keylen the length of the key -+ * @param[in] flags PKEY_FLAGS_MATCH_xxx flags -+ * @param[in] apqn_list a zero terminated array of pointers to C-strings -+ * @param[out] apqns A list of APQNs as array of struct pkey_apqn. The -+ * list must be freed by the caller using free(). -+ * @param[out] apqn_entries Number of entries in the list of APQNs -+ * @param[in] verbose if true, verbose messages are printed -+ * -+ * @returns 0 on success, a negative errno in case of an error -+ */ -+static int build_apqn_list_for_key(int pkey_fd, u8 *key, u32 keylen, u32 flags, -+ const char **apqn_list, -+ struct pkey_apqn **apqns, -+ u32 *apqn_entries, bool verbose) -+{ -+ struct pkey_apqns4key apqns4key; -+ u64 mkvp; -+ int rc; -+ -+ util_assert(pkey_fd != -1, "Internal error: pkey_fd is -1"); -+ util_assert(key != NULL, "Internal error: key is NULL"); -+ util_assert(apqns != NULL, "Internal error: apqns is NULL"); -+ util_assert(apqn_entries != NULL, -+ "Internal error: apqn_entries is NULL"); -+ -+ pr_verbose(verbose, "Build a list of APQNs for the key"); -+ -+ memset(&apqns4key, 0, sizeof(apqns4key)); -+ apqns4key.key = key; -+ apqns4key.keylen = keylen; -+ apqns4key.flags = flags; -+ apqns4key.apqn_entries = INITIAL_APQN_ENTRIES; -+ apqns4key.apqns = (struct pkey_apqn *)util_malloc( -+ apqns4key.apqn_entries * sizeof(struct pkey_apqn)); -+ -+ do { -+ rc = ioctl(pkey_fd, PKEY_APQNS4K, &apqns4key); -+ if (rc == 0) -+ break; -+ rc = -errno; -+ pr_verbose(verbose, "ioctl PKEY_APQNS4K rc: %s", strerror(-rc)); -+ -+ switch (rc) { -+ case -ENOSPC: -+ free(apqns4key.apqns); -+ apqns4key.apqns = (struct pkey_apqn *) -+ util_malloc(apqns4key.apqn_entries * -+ sizeof(struct pkey_apqn)); -+ continue; -+ case -ENOTTY: -+ /* -+ * New IOCTL is not available: build the list manually -+ * (Key type CCA-AESDATA only) -+ */ -+ free(apqns4key.apqns); -+ -+ if (!is_cca_aes_data_key(key, keylen)) -+ return -ENOTSUP; -+ -+ rc = get_master_key_verification_pattern(key, keylen, -+ &mkvp, -+ verbose); -+ if (rc != 0) -+ return rc; -+ -+ rc = build_apqn_list_for_aes_data(apqn_list, apqns, -+ apqn_entries, -+ verbose); -+ return rc; -+ default: -+ goto out; -+ } -+ } while (rc != 0); -+ -+ if (apqns4key.apqn_entries == 0) { -+ pr_verbose(verbose, "No APQN available for the key"); -+ rc = -ENODEV; -+ goto out; -+ } -+ -+ rc = filter_apqn_list(apqn_list, &apqns4key.apqns, -+ &apqns4key.apqn_entries); -+ if (rc != 0) -+ goto out; -+ -+ if (apqns4key.apqn_entries == 0) { -+ pr_verbose(verbose, "No APQN available for the key"); -+ rc = -ENODEV; -+ goto out; -+ } -+ -+ pr_verbose(verbose, "%u APQNs found", apqns4key.apqn_entries); -+ pr_verbose_apqn_list(verbose, apqns4key.apqns, apqns4key.apqn_entries); -+ -+out: -+ if (rc == 0) { -+ *apqns = apqns4key.apqns; -+ *apqn_entries = apqns4key.apqn_entries; -+ } else { -+ *apqns = NULL; -+ *apqn_entries = 0; -+ free(apqns4key.apqns); -+ } -+ -+ return rc; -+} -+ -+/** -+ * Convert the key type string into the pkey enumeration -+ * -+ * @param[in] key_type the type of the key -+ * -+ * @returns the pkey key type or 0 for an u known key type -+ */ -+static enum pkey_key_type key_type_to_pkey_type(const char *key_type) -+{ -+ if (strcasecmp(key_type, KEY_TYPE_CCA_AESDATA) == 0) -+ return PKEY_TYPE_CCA_DATA; -+ if (strcasecmp(key_type, KEY_TYPE_CCA_AESCIPHER) == 0) -+ return PKEY_TYPE_CCA_CIPHER; -+ -+ return 0; -+} -+ -+/** -+ * Return the size of a key blob for a specific type -+ * -+ * @param[in] type the type of the key -+ * -+ * @returns the size of the key or 0 for an invalid key type -+ */ -+static size_t key_size_for_type(enum pkey_key_type type) -+{ -+ switch (type) { -+ case PKEY_TYPE_CCA_DATA: -+ return AESDATA_KEY_SIZE; -+ case PKEY_TYPE_CCA_CIPHER: -+ return AESCIPHER_KEY_SIZE; -+ default: -+ return 0; -+ } -+} -+ -+/** - * Generate a secure key by random - * - * @param[in] pkey_fd the pkey file descriptor diff --git a/s390-tools-sles15sp2-25-zipl-move-Linux-layout-definitions-into-separate-hea.patch b/s390-tools-sles15sp2-25-zipl-move-Linux-layout-definitions-into-separate-hea.patch deleted file mode 100644 index f556c50..0000000 --- a/s390-tools-sles15sp2-25-zipl-move-Linux-layout-definitions-into-separate-hea.patch +++ /dev/null @@ -1,109 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] zipl: move Linux layout definitions into separate header -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: 7e37a1d4e0605ea120db18f82d039c055fd5d737 -Problem-ID: VS1804 - -Upstream-Description: - - zipl: move Linux layout definitions into separate header - - Move the Linux layout values to `include/boot/linux_layout.h`. This - allows the reuse of the definitions, e.g. in assembler files, and - later for the creation of linker scripts. - - Reviewed-by: Stefan Haberland - Reviewed-by: Philipp Rudo - Signed-off-by: Marc Hartmayer - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - include/boot/linux_layout.h | 33 +++++++++++++++++++++++++++++++++ - zipl/boot/stage3.h | 9 ++------- - zipl/include/zipl.h | 3 +-- - 3 files changed, 36 insertions(+), 9 deletions(-) - ---- /dev/null -+++ b/include/boot/linux_layout.h -@@ -0,0 +1,33 @@ -+/* -+ * s390 Linux layout definitions -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * s390-tools is free software; you can redistribute it and/or modify -+ * it under the terms of the MIT license. See LICENSE for details. -+ */ -+ -+#ifndef LINUX_LAYOUT_H -+#define LINUX_LAYOUT_H -+ -+#include "lib/zt_common.h" -+ -+/* Entry address offsets */ -+#define IMAGE_ENTRY _AC(0x10000, UL) -+#define IMAGE_ENTRY_KDUMP _AC(0x10010, UL) -+ -+/* Parameter address offsets */ -+#define IPL_DEVICE _AC(0x10400, UL) -+#define INITRD_START _AC(0x10408, UL) -+#define INITRD_SIZE _AC(0x10410, UL) -+#define OLDMEM_BASE _AC(0x10418, UL) -+#define OLDMEM_SIZE _AC(0x10420, UL) -+#define COMMAND_LINE _AC(0x10480, UL) -+ -+/* Parameter sizes */ -+#define COMMAND_LINE_SIZE 896 -+ -+ -+#ifndef __ASSEMBLER__ -+#endif /* __ASSEMBLER__ */ -+#endif /* LINUX_LAYOUT_H */ ---- a/zipl/boot/stage3.h -+++ b/zipl/boot/stage3.h -@@ -16,14 +16,9 @@ - #include "s390.h" - - #include "boot/ipl.h" -+#include "boot/linux_layout.h" -+ - --#define IPL_DEVICE 0x10400UL --#define INITRD_START 0x10408UL --#define INITRD_SIZE 0x10410UL --#define OLDMEM_BASE 0x10418UL --#define OLDMEM_SIZE 0x10420UL --#define COMMAND_LINE 0x10480UL --#define COMMAND_LINE_SIZE 896 - #define COMMAND_LINE_EXTRA 0xE000 - - #define STAGE3_FLAG_SCSI 0x0001000000000000ULL ---- a/zipl/include/zipl.h -+++ b/zipl/include/zipl.h -@@ -14,14 +14,13 @@ - - #include - #include "lib/zt_common.h" -+#include "boot/linux_layout.h" - - #define ZIPL_MAGIC "zIPL" - #define ZIPL_MAGIC_SIZE 4 - #define DISK_LAYOUT_ID 0x00000001 - - #define STAGE3_ENTRY 0xa000UL --#define IMAGE_ENTRY 0x10000UL --#define IMAGE_ENTRY_KDUMP 0x10010UL - - #define STAGE2_LOAD_ADDRESS 0x2000UL - #define STAGE3_LOAD_ADDRESS 0xa000UL diff --git a/s390-tools-sles15sp2-25-zkey-Add-support-for-generating-AES-CIPHER-keys.patch b/s390-tools-sles15sp2-25-zkey-Add-support-for-generating-AES-CIPHER-keys.patch deleted file mode 100644 index ec41a28..0000000 --- a/s390-tools-sles15sp2-25-zkey-Add-support-for-generating-AES-CIPHER-keys.patch +++ /dev/null @@ -1,542 +0,0 @@ -Subject: zkey: Add support for generating AES CIPHER keys -From: Ingo Franzki - -Summary: zkey: Add support for CCA AES CIPHER keys -Description: With CCA 5 there is a new secure key type, the so called - variable length symmetric cipher key token. This token format - can hold AES keys with size 128, 192 and 256 bits together - with additional attributes cryptographic bound to the key - token. The attributes may limit the usage of the key, for - example restrict export or usability scope. So this key type - is considered to be even more secure than the traditional - secure key token. This key token type is also called "CCA - AES CIPHER key", where the formerly used key token is called - "CCA AES DATA key". - The zkey as well as the zkey-cryptsetup tools are enhanced - to support AES CIPHER keys. That is, zkey can manage AES DATA - keys, as well as AES CIPHER keys. The key type must be specified - at key generation time, the default is to generate AED DATA - keys. -Upstream-ID: b56c74fe7b6100b9a2ef17b8847cd850309cf487 -Problem-ID: SEC1717 - -Upstream-Description: - - zkey: Add support for generating AES CIPHER keys - - Add support for generating secure keys using the new pkey - IOCTLs. This allows to generate secure keys of type CCA-AESDATA - as well as CCA-AESCIPHER, either by random inside the crypto - card, or from a given clear key. - - Signed-off-by: Ingo Franzki - Reviewed-by: Harald Freudenberger - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/keystore.c | 60 +------------ - zkey/pkey.c | 258 +++++++++++++++++++++++++++++++++----------------------- - zkey/pkey.h | 5 - - zkey/zkey.c | 6 - - 4 files changed, 168 insertions(+), 161 deletions(-) - ---- a/zkey/keystore.c -+++ b/zkey/keystore.c -@@ -1667,52 +1667,6 @@ out: - } - - /** -- * Extracts an online card/domain pair from the specified APQns. If none of the -- * specified APQNs are online, then -ENODEV is returned. -- * If no APQNs are specified at all, then it uses AUTOSELECT and returns zero. -- */ --static int _keystore_get_card_domain(const char *apqns, unsigned int *card, -- unsigned int *domain) --{ -- struct apqn_check apqn_check = { .noonlinecheck = 0, .nomsg = 1 }; -- char **apqn_list; -- char *normalized = NULL; -- int rc = 0; -- int i; -- -- *card = AUTOSELECT; -- *domain = AUTOSELECT; -- -- if (apqns == NULL) -- return 0; -- -- apqn_list = str_list_split(apqns); -- if (apqn_list[0] == NULL) -- goto out; -- -- for (i = 0; apqn_list[i] != NULL; i++) { -- rc = _keystore_apqn_check(apqn_list[i], 0, 0, &normalized, -- &apqn_check); -- if (normalized != NULL) -- free(normalized); -- if (rc == -EINVAL) -- goto out; -- if (rc != 0) -- continue; -- -- if (sscanf(apqn_list[i], "%x.%x", card, domain) == 2) -- goto found; -- } -- -- warnx("None of the specified APQNs is online or of type CCA"); -- rc = -ENODEV; --found: --out: -- str_list_free_string_array(apqn_list); -- return rc; --} -- --/** - * Generates a secure key by random and adds it to the key store - * - * @param[in] keystore the key store -@@ -1748,7 +1702,7 @@ int keystore_generate_key(struct keystor - { - struct key_filenames file_names = { NULL, NULL, NULL }; - struct properties *key_props = NULL; -- unsigned int card, domain; -+ char **apqn_list = NULL; - int rc; - - util_assert(keystore != NULL, "Internal error: keystore is NULL"); -@@ -1776,21 +1730,21 @@ int keystore_generate_key(struct keystor - goto out_free_key_filenames; - } - -- rc = _keystore_get_card_domain(apqns, &card, &domain); -- if (rc != 0) -- goto out_free_key_filenames; -+ if (apqns != NULL) -+ apqn_list = str_list_split(apqns); - - if (clear_key_file == NULL) - rc = generate_secure_key_random(pkey_fd, - file_names.skey_filename, - keybits, xts, key_type, -- card, domain, -+ (const char **)apqn_list, - keystore->verbose); - else - rc = generate_secure_key_clear(pkey_fd, - file_names.skey_filename, - keybits, xts, clear_key_file, -- key_type, card, domain, -+ key_type, -+ (const char **)apqn_list, - keystore->verbose); - if (rc != 0) - goto out_free_props; -@@ -1812,6 +1766,8 @@ int keystore_generate_key(struct keystor - file_names.info_filename); - - out_free_props: -+ if (apqn_list != NULL) -+ str_list_free_string_array(apqn_list); - if (key_props != NULL) - properties_free(key_props); - if (rc != 0) ---- a/zkey/pkey.c -+++ b/zkey/pkey.c -@@ -888,86 +888,109 @@ static size_t key_size_for_type(enum pke - * @param[in] keybits the cryptographic size of the key in bits - * @param[in] xts if true an XTS key is generated - * @param[in] key_type the type of the key -- * @param[in] card the card number to use (or AUTOSELECT) -- * @param[in] domain the domain number to use (or AUTOSELECT) -+ * @param[in] apqns a zero terminated array of pointers to APQN-strings, -+ * or NULL for AUTOSELECT - * @param[in] verbose if true, verbose messages are printed - * - * @returns 0 on success, a negative errno in case of an error - */ - int generate_secure_key_random(int pkey_fd, const char *keyfile, - size_t keybits, bool xts, const char *key_type, -- u16 card, u16 domain, bool verbose) -+ const char **apqns, bool verbose) - { -- struct pkey_genseck gensec; -- size_t secure_key_size; -- u8 *secure_key; -+ struct pkey_genseck2 genseck2; -+ size_t secure_key_size, size; -+ u8 *secure_key = NULL; - int rc; - - util_assert(pkey_fd != -1, "Internal error: pkey_fd is -1"); - util_assert(keyfile != NULL, "Internal error: keyfile is NULL"); - util_assert(key_type != NULL, "Internal error: key_type is NULL"); - -- if (strcasecmp(key_type, KEY_TYPE_CCA_AESDATA) != 0) { -- warnx("Invalid key-type: %s", key_type); -- return -EINVAL; -- } -- - if (keybits == 0) - keybits = DEFAULT_KEYBITS; - -- secure_key_size = DOUBLE_KEYSIZE_FOR_XTS(AESDATA_KEY_SIZE, xts); -- secure_key = util_malloc(secure_key_size); -+ pr_verbose(verbose, "Generate secure key by random"); - -- pr_verbose(verbose, "Generate key on card %02x.%04x", card, domain); -+ memset(&genseck2, 0, sizeof(genseck2)); - -- gensec.cardnr = card; -- gensec.domain = domain; -- switch (keybits) { -- case 128: -- gensec.keytype = PKEY_KEYTYPE_AES_128; -- break; -- case 192: -- if (xts) { -- warnx("Invalid value for '--keybits'|'-c' " -- "for XTS: '%lu'", keybits); -- rc = -EINVAL; -- goto out; -- } -- gensec.keytype = PKEY_KEYTYPE_AES_192; -- break; -- case 256: -- gensec.keytype = PKEY_KEYTYPE_AES_256; -- break; -- default: -+ genseck2.type = key_type_to_pkey_type(key_type); -+ if (genseck2.type == 0) { -+ warnx("Key-type not supported; %s", key_type); -+ return -ENOTSUP; -+ } -+ -+ genseck2.size = keybits_to_keysize(keybits); -+ if (genseck2.size == 0) { - warnx("Invalid value for '--keybits'/'-c': '%lu'", keybits); -- rc = -EINVAL; -- goto out; -+ return -EINVAL; -+ } -+ if (keybits == 192 && xts) { -+ warnx("Invalid value for '--keybits'|'-c' " -+ "for XTS: '%lu'", keybits); -+ return -EINVAL; - } - -- rc = ioctl(pkey_fd, PKEY_GENSECK, &gensec); -- if (rc < 0) { -- rc = -errno; -- warnx("Failed to generate a secure key: %s", strerror(errno)); -- warnx("Make sure that all available CCA crypto adapters are " -- "setup with the same master key"); -- goto out; -+ rc = build_apqn_list_for_key_type(pkey_fd, genseck2.type, apqns, -+ &genseck2.apqns, -+ &genseck2.apqn_entries, verbose); -+ if (rc != 0) { -+ if (rc == -ENODEV || rc == -ENOTSUP) -+ warnx("No APQN is available that can generate a secure " -+ "key of type %s", key_type); -+ else -+ warnx("Failed to build a list of APQNs that can " -+ "generate a secure key of type %s: %s", key_type, -+ strerror(-rc)); -+ return rc; - } - -- memcpy(secure_key, &gensec.seckey, AESDATA_KEY_SIZE); -+ size = key_size_for_type(genseck2.type); -+ secure_key_size = DOUBLE_KEYSIZE_FOR_XTS(size, xts); -+ secure_key = util_zalloc(secure_key_size); -+ -+ genseck2.key = secure_key; -+ genseck2.keylen = size; -+ -+ rc = pkey_genseck2(pkey_fd, &genseck2, verbose); -+ if (rc != 0) { -+ warnx("Failed to generate a secure key: %s", strerror(-rc)); -+ goto out; -+ } - - if (xts) { -- rc = ioctl(pkey_fd, PKEY_GENSECK, &gensec); -- if (rc < 0) { -- rc = -errno; -- warnx("Failed to generate a secure key: %s", -- strerror(errno)); -- warnx("Make sure that all available CCA crypto " -- "adapters are setup with the same master key"); -+ free(genseck2.apqns); -+ genseck2.apqns = NULL; -+ genseck2.apqn_entries = 0; -+ -+ /* -+ * Ensure to generate 2nd key with an APQN that has the same -+ * master key that is used by the 1st key. -+ */ -+ rc = build_apqn_list_for_key(pkey_fd, secure_key, size, -+ PKEY_FLAGS_MATCH_CUR_MKVP, apqns, -+ &genseck2.apqns, -+ &genseck2.apqn_entries, verbose); -+ if (rc != 0) { -+ if (rc == -ENODEV || rc == -ENOTSUP) -+ warnx("No APQN is available that can generate " -+ "a secure key of type %s", key_type); -+ else -+ warnx("Failed to build a list of APQNs that " -+ "can generate a secure key of type %s: " -+ "%s", key_type, strerror(-rc)); - goto out; - } - -- memcpy(secure_key + AESDATA_KEY_SIZE, &gensec.seckey, -- AESDATA_KEY_SIZE); -+ genseck2.key = secure_key + size; -+ genseck2.keylen = size; -+ -+ rc = pkey_genseck2(pkey_fd, &genseck2, verbose); -+ if (rc != 0) { -+ warnx("Failed to generate a secure key: %s", -+ strerror(-rc)); -+ goto out; -+ } - } - - pr_verbose(verbose, "Successfully generated a secure key"); -@@ -975,6 +998,7 @@ int generate_secure_key_random(int pkey_ - rc = write_secure_key(keyfile, secure_key, secure_key_size, verbose); - - out: -+ free(genseck2.apqns); - free(secure_key); - return rc; - } -@@ -991,8 +1015,8 @@ out: - * @param[in] xts if true an XTS key is generated - * @param[in] clearkeyfile the file name of the clear key to read - * @param[in] key_type the type of the key -- * @param[in] card the card number to use (or AUTOSELECT) -- * @param[in] domain the domain number to use (or AUTOSELECT) -+ * @param[in] apqns a zero terminated array of pointers to APQN-strings, -+ * or NULL for AUTOSELECT - * @param[in] verbose if true, verbose messages are printed - * - * @returns 0 on success, a negative errno in case of an error -@@ -1000,14 +1024,14 @@ out: - int generate_secure_key_clear(int pkey_fd, const char *keyfile, - size_t keybits, bool xts, - const char *clearkeyfile, const char *key_type, -- u16 card, u16 domain, -- bool verbose) -+ const char **apqns, bool verbose) - { -- struct pkey_clr2seck clr2sec; -+ struct pkey_clr2seck2 clr2seck2; - size_t secure_key_size; - size_t clear_key_size; - u8 *secure_key; - u8 *clear_key; -+ size_t size; - int rc; - - util_assert(pkey_fd != -1, "Internal error: pkey_fd is -1"); -@@ -1016,70 +1040,99 @@ int generate_secure_key_clear(int pkey_f - "Internal error: clearkeyfile is NULL"); - util_assert(key_type != NULL, "Internal error: key_type is NULL"); - -- if (strcasecmp(key_type, KEY_TYPE_CCA_AESDATA) != 0) { -- warnx("Invalid key-type: %s", key_type); -- return -EINVAL; -- } -- -- secure_key_size = DOUBLE_KEYSIZE_FOR_XTS(AESDATA_KEY_SIZE, xts); -- secure_key = util_malloc(secure_key_size); -+ pr_verbose(verbose, "Generate secure key from a clear key"); - - clear_key = read_clear_key(clearkeyfile, keybits, xts, &clear_key_size, - verbose); - if (clear_key == NULL) - return -EINVAL; - -- pr_verbose(verbose, "Generate key on card %02x.%04x", card, domain); -+ memset(&clr2seck2, 0, sizeof(clr2seck2)); -+ -+ memcpy(&clr2seck2.clrkey, clear_key, -+ HALF_KEYSIZE_FOR_XTS(clear_key_size, xts)); -+ -+ clr2seck2.type = key_type_to_pkey_type(key_type); -+ if (clr2seck2.type == 0) { -+ warnx("Key-type not supported; %s", key_type); -+ return -ENOTSUP; -+ } - -- clr2sec.cardnr = card; -- clr2sec.domain = domain; -- switch (HALF_KEYSIZE_FOR_XTS(clear_key_size * 8, xts)) { -- case 128: -- clr2sec.keytype = PKEY_KEYTYPE_AES_128; -- break; -- case 192: -- clr2sec.keytype = PKEY_KEYTYPE_AES_192; -- break; -- case 256: -- clr2sec.keytype = PKEY_KEYTYPE_AES_256; -- break; -- default: -+ clr2seck2.size = keybits_to_keysize(HALF_KEYSIZE_FOR_XTS( -+ clear_key_size * 8, xts)); -+ if (clr2seck2.size == 0) { - warnx("Invalid clear key size: '%lu' bytes", clear_key_size); -- rc = -EINVAL; -- goto out; -+ return -EINVAL; -+ } -+ if (keybits == 192 && xts) { -+ warnx("Invalid clear key size for XTS: '%lu' bytes", -+ clear_key_size); -+ return -EINVAL; - } - -- memcpy(&clr2sec.clrkey, clear_key, -- HALF_KEYSIZE_FOR_XTS(clear_key_size, xts)); -+ rc = build_apqn_list_for_key_type(pkey_fd, clr2seck2.type, apqns, -+ &clr2seck2.apqns, -+ &clr2seck2.apqn_entries, verbose); -+ if (rc != 0) { -+ if (rc == -ENODEV || rc == -ENOTSUP) -+ warnx("No APQN is available that can generate a secure " -+ "key of type %s", key_type); -+ else -+ warnx("Failed to build a list of APQNs that can " -+ "generate a secure key of type %s: %s", key_type, -+ strerror(-rc)); -+ return rc; -+ } - -- rc = ioctl(pkey_fd, PKEY_CLR2SECK, &clr2sec); -- if (rc < 0) { -- rc = -errno; -- warnx("Failed to generate a secure key from a " -- "clear key: %s", strerror(errno)); -- warnx("Make sure that all available CCA crypto adapters are " -- "setup with the same master key"); -+ size = key_size_for_type(clr2seck2.type); -+ secure_key_size = DOUBLE_KEYSIZE_FOR_XTS(size, xts); -+ secure_key = util_zalloc(secure_key_size); -+ -+ clr2seck2.key = secure_key; -+ clr2seck2.keylen = size; -+ -+ rc = pkey_clr2seck2(pkey_fd, &clr2seck2, verbose); -+ if (rc != 0) { -+ warnx("Failed to generate a secure key: %s", strerror(-rc)); - goto out; - } - -- memcpy(secure_key, &clr2sec.seckey, AESDATA_KEY_SIZE); -- - if (xts) { -- memcpy(&clr2sec.clrkey, clear_key + clear_key_size / 2, -+ free(clr2seck2.apqns); -+ clr2seck2.apqns = NULL; -+ clr2seck2.apqn_entries = 0; -+ -+ memcpy(&clr2seck2.clrkey, clear_key + clear_key_size / 2, - clear_key_size / 2); - -- rc = ioctl(pkey_fd, PKEY_CLR2SECK, &clr2sec); -- if (rc < 0) { -- rc = -errno; -- warnx("Failed to generate a secure key from " -- "a clear key: %s", strerror(errno)); -- warnx("Make sure that all available CCA crypto " -- "adapters are setup with the same master key"); -+ /* -+ * Ensure to generate 2nd key with an APQN that has the same -+ * master key that is used by the 1st key. -+ */ -+ rc = build_apqn_list_for_key(pkey_fd, secure_key, size, -+ PKEY_FLAGS_MATCH_CUR_MKVP, apqns, -+ &clr2seck2.apqns, -+ &clr2seck2.apqn_entries, verbose); -+ if (rc != 0) { -+ if (rc == -ENODEV || rc == -ENOTSUP) -+ warnx("No APQN is available that can generate " -+ "a secure key of type %s", key_type); -+ else -+ warnx("Failed to build a list of APQNs that " -+ "can generate a secure key of type %s: " -+ "%s", key_type, strerror(-rc)); - goto out; - } - -- memcpy(secure_key + AESDATA_KEY_SIZE, &clr2sec.seckey, -- AESDATA_KEY_SIZE); -+ clr2seck2.key = secure_key + size; -+ clr2seck2.keylen = size; -+ -+ rc = pkey_clr2seck2(pkey_fd, &clr2seck2, verbose); -+ if (rc != 0) { -+ warnx("Failed to generate a secure key: %s", -+ strerror(-rc)); -+ goto out; -+ } - } - - pr_verbose(verbose, -@@ -1088,10 +1141,11 @@ int generate_secure_key_clear(int pkey_f - rc = write_secure_key(keyfile, secure_key, secure_key_size, verbose); - - out: -- memset(&clr2sec, 0, sizeof(clr2sec)); -+ memset(&clr2seck2, 0, sizeof(clr2seck2)); - memset(clear_key, 0, clear_key_size); - free(clear_key); - free(secure_key); -+ free(clr2seck2.apqns); - return rc; - } - ---- a/zkey/pkey.h -+++ b/zkey/pkey.h -@@ -235,13 +235,12 @@ int open_pkey_device(bool verbose); - - int generate_secure_key_random(int pkey_fd, const char *keyfile, - size_t keybits, bool xts, const char *key_type, -- u16 card, u16 domain, bool verbose); -+ const char **apqns, bool verbose); - - int generate_secure_key_clear(int pkey_fd, const char *keyfile, - size_t keybits, bool xts, - const char *clearkeyfile, const char *key_type, -- u16 card, u16 domain, -- bool verbose); -+ const char **apqns, bool verbose); - - u8 *read_secure_key(const char *keyfile, size_t *secure_key_size, - bool verbose); ---- a/zkey/zkey.c -+++ b/zkey/zkey.c -@@ -1029,8 +1029,7 @@ static int command_generate_clear(void) - rc = generate_secure_key_clear(g.pkey_fd, g.pos_arg, - g.keybits, g.xts, - g.clearkeyfile, g.key_type, -- AUTOSELECT, AUTOSELECT, -- g.verbose); -+ NULL, g.verbose); - - return rc != 0 ? EXIT_FAILURE : EXIT_SUCCESS; - } -@@ -1046,8 +1045,7 @@ static int command_generate_random(void) - - rc = generate_secure_key_random(g.pkey_fd, g.pos_arg, - g.keybits, g.xts, g.key_type, -- AUTOSELECT, AUTOSELECT, -- g.verbose); -+ NULL, g.verbose); - - return rc != 0 ? EXIT_FAILURE : EXIT_SUCCESS; - } diff --git a/s390-tools-sles15sp2-26-zipl-tape0-use-constants-defined-in-linux_layout.h.patch b/s390-tools-sles15sp2-26-zipl-tape0-use-constants-defined-in-linux_layout.h.patch deleted file mode 100644 index 744dc4d..0000000 --- a/s390-tools-sles15sp2-26-zipl-tape0-use-constants-defined-in-linux_layout.h.patch +++ /dev/null @@ -1,79 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] zipl: tape0: use constants defined in linux_layout.h -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: c871050097ecb2ec83cf3018ea36e01cd22cbe7d -Problem-ID: VS1804 - -Upstream-Description: - - zipl: tape0: use constants defined in linux_layout.h - - Use the constants defined in `linux_layout.h`. Therefore move the - `PARMAREA` address offset to `linux_layout.h` and include the header. - - Reviewed-by: Philipp Rudo - Reviewed-by: Stefan Haberland - Signed-off-by: Marc Hartmayer - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - include/boot/linux_layout.h | 1 + - zipl/boot/tape0.S | 14 +++----------- - 2 files changed, 4 insertions(+), 11 deletions(-) - ---- a/include/boot/linux_layout.h -+++ b/include/boot/linux_layout.h -@@ -17,6 +17,7 @@ - #define IMAGE_ENTRY_KDUMP _AC(0x10010, UL) - - /* Parameter address offsets */ -+#define PARMAREA _AC(0x10400, UL) - #define IPL_DEVICE _AC(0x10400, UL) - #define INITRD_START _AC(0x10408, UL) - #define INITRD_SIZE _AC(0x10410, UL) ---- a/zipl/boot/tape0.S -+++ b/zipl/boot/tape0.S -@@ -8,29 +8,21 @@ - # - - #include "boot/sigp.h" -+#include "boot/linux_layout.h" - - IPL_BS = 1024 # block size for tape access - IPL_OFF = 0x4000 # temporary kernel load addr --COMMAND_LINE_SIZE = 896 # max command line length --KERNEL_OFF = 0x10000 # kernel start code offset -+KERNEL_OFF = IMAGE_ENTRY # kernel start code offset - # relative to image start - __LC_IO_NEW_PSW = 0x1f0 # IO New PSW addr - - --# Parameter address offsets -- --PARMAREA = 0x10400 # Parameter area offset --IPL_DEVICE = 0x10400 # IPL device offset --INITRD_START = 0x10408 # ramdisk addr offset --INITRD_SIZE = 0x10410 # ramdisk size offset --COMMAND_LINE = 0x10480 # command line offset -- - # Default IPL parameter - will be overwritten by zIPL - - RAMDISK_ORIGIN = 0x800000 # default ramdisk load addr - RAMDISK_SIZE = 0x800000 # default ramdisk size - PARMFILE_ADDR = 0x1000 # default parmfile load addr --KERNEL_ADDR = 0x10000 # default kernel load addr -+KERNEL_ADDR = IMAGE_ENTRY # default kernel load addr - - - .org 0x0 diff --git a/s390-tools-sles15sp2-26-zkey-Add-support-for-validating-AES-CIPHER-keys.patch b/s390-tools-sles15sp2-26-zkey-Add-support-for-validating-AES-CIPHER-keys.patch deleted file mode 100644 index a37e90d..0000000 --- a/s390-tools-sles15sp2-26-zkey-Add-support-for-validating-AES-CIPHER-keys.patch +++ /dev/null @@ -1,425 +0,0 @@ -Subject: zkey: Add support for validating AES CIPHER keys -From: Ingo Franzki - -Summary: zkey: Add support for CCA AES CIPHER keys -Description: With CCA 5 there is a new secure key type, the so called - variable length symmetric cipher key token. This token format - can hold AES keys with size 128, 192 and 256 bits together - with additional attributes cryptographic bound to the key - token. The attributes may limit the usage of the key, for - example restrict export or usability scope. So this key type - is considered to be even more secure than the traditional - secure key token. This key token type is also called "CCA - AES CIPHER key", where the formerly used key token is called - "CCA AES DATA key". - The zkey as well as the zkey-cryptsetup tools are enhanced - to support AES CIPHER keys. That is, zkey can manage AES DATA - keys, as well as AES CIPHER keys. The key type must be specified - at key generation time, the default is to generate AED DATA - keys. -Upstream-ID: 0fab6bdf2aa01e093f8a4f3d86c9183889a587fe -Problem-ID: SEC1717 - -Upstream-Description: - - zkey: Add support for validating AES CIPHER keys - - Add support for validating secure keys using the new pkey - IOCTLs. This allows to validate secure keys of type CCA-AESDATA - as well as CCA-AESCIPHER. - - Signed-off-by: Ingo Franzki - Reviewed-by: Harald Freudenberger - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/keystore.c | 24 ++++++ - zkey/pkey.c | 178 +++++++++++++++++++++++++------------------------ - zkey/pkey.h | 2 - zkey/zkey-cryptsetup.c | 6 - - zkey/zkey.c | 4 - - 5 files changed, 120 insertions(+), 94 deletions(-) - ---- a/zkey/keystore.c -+++ b/zkey/keystore.c -@@ -2451,8 +2451,10 @@ static int _keystore_process_validate(st - void *private) - { - struct validate_info *info = (struct validate_info *)private; -+ char **apqn_list = NULL; - size_t clear_key_bitsize; - size_t secure_key_size; -+ char *apqns = NULL; - u8 *secure_key; - int is_old_mk; - int rc, valid; -@@ -2469,9 +2471,13 @@ static int _keystore_process_validate(st - goto out; - } - -+ apqns = properties_get(properties, PROP_NAME_APQNS); -+ if (apqns != NULL) -+ apqn_list = str_list_split(apqns); -+ - rc = validate_secure_key(info->pkey_fd, secure_key, secure_key_size, - &clear_key_bitsize, &is_old_mk, -- keystore->verbose); -+ (const char **)apqn_list, keystore->verbose); - if (rc != 0) { - valid = 0; - info->num_invalid++; -@@ -2510,6 +2516,10 @@ static int _keystore_process_validate(st - info->num_warnings++; - - out: -+ if (apqns != NULL) -+ free(apqns); -+ if (apqn_list != NULL) -+ str_list_free_string_array(apqn_list); - if (rc != 0) - pr_verbose(keystore, "Failed to validate key '%s': %s", - name, strerror(-rc)); -@@ -2726,7 +2736,9 @@ static int _keystore_process_reencipher( - struct reencipher_params params = info->params; - size_t clear_key_bitsize; - size_t secure_key_size; -+ char **apqn_list = NULL; - u8 *secure_key = NULL; -+ char *apqns = NULL; - char *out_file; - int is_old_mk; - char *temp; -@@ -2763,9 +2775,13 @@ static int _keystore_process_reencipher( - goto out; - } - -+ apqns = properties_get(properties, PROP_NAME_APQNS); -+ if (apqns != NULL) -+ apqn_list = str_list_split(apqns); -+ - rc = validate_secure_key(info->pkey_fd, secure_key, secure_key_size, - &clear_key_bitsize, &is_old_mk, -- keystore->verbose); -+ (const char **)apqn_list, keystore->verbose); - if (rc != 0) { - if (params.complete) { - warnx("Key '%s' is not valid, re-enciphering is not " -@@ -2864,6 +2880,10 @@ static int _keystore_process_reencipher( - info->num_reenciphered++; - - out: -+ if (apqns != NULL) -+ free(apqns); -+ if (apqn_list != NULL) -+ str_list_free_string_array(apqn_list); - if (secure_key != NULL) - free(secure_key); - ---- a/zkey/pkey.c -+++ b/zkey/pkey.c -@@ -1153,84 +1153,58 @@ out: - * Validates an XTS secure key (the second part) - * - * @param[in] pkey_fd the pkey file descriptor -+ * @param[in] apqn the APQN to verify the key with - * @param[in] secure_key a buffer containing the secure key - * @param[in] secure_key_size the secure key size - * @param[in] part1_keysize the key size of the first key part -- * @param[in] part1_attributes the attributes of the first key part -+ * @param[in] part1_flags the flags of the first key part - * @param[out] clear_key_bitsize on return , the cryptographic size of the - * clear key - * @param[in] verbose if true, verbose messages are printed - * - * @returns 0 on success, a negative errno in case of an error - */ --static int validate_secure_xts_key(int pkey_fd, -+static int validate_secure_xts_key(int pkey_fd, struct pkey_apqn *apqn, - u8 *secure_key, size_t secure_key_size, -- u16 part1_keysize, u32 part1_attributes, -- size_t *clear_key_bitsize, bool verbose) -+ enum pkey_key_size part1_keysize, -+ u32 part1_flags, size_t *clear_key_bitsize, -+ bool verbose) - { -- struct aesdatakeytoken *token = (struct aesdatakeytoken *)secure_key; -- struct pkey_verifykey verifykey; -- struct aesdatakeytoken *token2; -+ struct pkey_verifykey2 verifykey2; - int rc; - - util_assert(pkey_fd != -1, "Internal error: pkey_fd is -1"); - util_assert(secure_key != NULL, "Internal error: secure_key is NULL"); -+ util_assert(apqn != NULL, "Internal error: apqn is NULL"); - -- /* XTS uses 2 secure key tokens concatenated to each other */ -- token2 = (struct aesdatakeytoken *)(secure_key + AESDATA_KEY_SIZE); -+ memset(&verifykey2, 0, sizeof(verifykey2)); -+ verifykey2.key = secure_key + (secure_key_size / 2); -+ verifykey2.keylen = secure_key_size / 2; -+ verifykey2.cardnr = apqn->card; -+ verifykey2.domain = apqn->domain; - -- if (secure_key_size != 2 * AESDATA_KEY_SIZE) { -- pr_verbose(verbose, "Size of secure key is too small: " -- "%lu expected %lu", secure_key_size, -- 2 * AESDATA_KEY_SIZE); -- return -EINVAL; -- } -- -- if (token->bitsize != token2->bitsize) { -- pr_verbose(verbose, "XTS secure key contains 2 clear keys of " -- "different sizes"); -- return -EINVAL; -- } -- if (token->keysize != token2->keysize) { -- pr_verbose(verbose, "XTS secure key contains 2 keys of " -- "different sizes"); -- return -EINVAL; -- } -- if (memcmp(&token->mkvp, &token2->mkvp, sizeof(token->mkvp)) != 0) { -- pr_verbose(verbose, "XTS secure key contains 2 keys using " -- "different CCA master keys"); -- return -EINVAL; -- } -- -- memcpy(&verifykey.seckey, token2, sizeof(verifykey.seckey)); -- -- rc = ioctl(pkey_fd, PKEY_VERIFYKEY, &verifykey); -+ rc = pkey_verifyseck2(pkey_fd, &verifykey2, verbose); - if (rc < 0) { -- rc = -errno; -- pr_verbose(verbose, "Failed to validate a secure key: %s", -- strerror(-rc)); -+ pr_verbose(verbose, "Failed to validate the 2nd part of the " -+ "XTS secure key on APQN %02x.%04x: %s", apqn->card, -+ apqn->domain, strerror(-rc)); - return rc; - } - -- if ((verifykey.attributes & PKEY_VERIFY_ATTR_AES) == 0) { -- pr_verbose(verbose, "Secure key is not an AES key"); -- return -EINVAL; -- } -- -- if (verifykey.keysize != part1_keysize) { -+ if (verifykey2.size != part1_keysize) { - pr_verbose(verbose, "XTS secure key contains 2 keys using " - "different key sizes"); - return -EINVAL; - } - -- if (verifykey.attributes != part1_attributes) { -+ if (verifykey2.flags != part1_flags) { - pr_verbose(verbose, "XTS secure key contains 2 keys using " -- "different attributes"); -+ "different master keys"); - return -EINVAL; - } - -- if (clear_key_bitsize) -- *clear_key_bitsize += verifykey.keysize; -+ if (clear_key_bitsize && verifykey2.size != PKEY_SIZE_UNKNOWN) -+ *clear_key_bitsize += verifykey2.size; - - return 0; - } -@@ -1245,6 +1219,8 @@ static int validate_secure_xts_key(int p - * clear key - * @param[out] is_old_mk in return set to 1 to indicate if the secure key - * is currently enciphered by the OLD CCA master key -+ * @param[in] apqns a zero terminated array of pointers to APQN-strings, -+ * or NULL for AUTOSELECT - * @param[in] verbose if true, verbose messages are printed - * - * @returns 0 on success, a negative errno in case of an error -@@ -1252,59 +1228,89 @@ static int validate_secure_xts_key(int p - int validate_secure_key(int pkey_fd, - u8 *secure_key, size_t secure_key_size, - size_t *clear_key_bitsize, int *is_old_mk, -- bool verbose) -+ const char **apqns, bool verbose) - { -- struct aesdatakeytoken *token = (struct aesdatakeytoken *)secure_key; -- struct pkey_verifykey verifykey; -+ struct pkey_verifykey2 verifykey2; -+ struct pkey_apqn *list = NULL; -+ u32 i, list_entries = 0; -+ bool xts, valid; - int rc; - - util_assert(pkey_fd != -1, "Internal error: pkey_fd is -1"); - util_assert(secure_key != NULL, "Internal error: secure_key is NULL"); - -- if (secure_key_size < AESDATA_KEY_SIZE) { -- pr_verbose(verbose, "Size of secure key is too small: " -- "%lu expected %lu", secure_key_size, -- AESDATA_KEY_SIZE); -- return -EINVAL; -- } -- -- memcpy(&verifykey.seckey, token, sizeof(verifykey.seckey)); -+ xts = is_xts_key(secure_key, secure_key_size); - -- rc = ioctl(pkey_fd, PKEY_VERIFYKEY, &verifykey); -- if (rc < 0) { -- rc = -errno; -- pr_verbose(verbose, "Failed to validate a secure key: %s", -- strerror(-rc)); -+ rc = build_apqn_list_for_key(pkey_fd, secure_key, -+ HALF_KEYSIZE_FOR_XTS(secure_key_size, xts), -+ PKEY_FLAGS_MATCH_CUR_MKVP | -+ PKEY_FLAGS_MATCH_ALT_MKVP, -+ apqns, &list, &list_entries, verbose); -+ if (rc != 0) { -+ pr_verbose(verbose, "Failed to build a list of APQNs that can " -+ "validate this secure key: %s", strerror(-rc)); - return rc; - } - -- if ((verifykey.attributes & PKEY_VERIFY_ATTR_AES) == 0) { -- pr_verbose(verbose, "Secure key is not an AES key"); -- return -EINVAL; -- } -- -- if (clear_key_bitsize) -- *clear_key_bitsize = verifykey.keysize; -- -- /* XTS uses 2 secure key tokens concatenated to each other */ -- if (secure_key_size > AESDATA_KEY_SIZE) { -- rc = validate_secure_xts_key(pkey_fd, -- secure_key, secure_key_size, -- verifykey.keysize, -- verifykey.attributes, -- clear_key_bitsize, -- verbose); -- if (rc != 0) -- return rc; -+ if (is_old_mk != NULL) -+ *is_old_mk = true; -+ if (clear_key_bitsize != NULL) -+ *clear_key_bitsize = 0; -+ -+ valid = false; -+ for (i = 0; i < list_entries; i++) { -+ memset(&verifykey2, 0, sizeof(verifykey2)); -+ verifykey2.key = secure_key; -+ verifykey2.keylen = HALF_KEYSIZE_FOR_XTS(secure_key_size, xts); -+ verifykey2.cardnr = list[i].card; -+ verifykey2.domain = list[i].domain; -+ -+ rc = pkey_verifyseck2(pkey_fd, &verifykey2, verbose); -+ if (rc < 0) { -+ pr_verbose(verbose, "Failed to validate the secure key " -+ "on APQN %02x.%04x: %s", list[i].card, -+ list[i].domain, strerror(-rc)); -+ continue; -+ } -+ -+ if (is_xts_key(secure_key, secure_key_size)) { -+ rc = validate_secure_xts_key(pkey_fd, &list[i], -+ secure_key, -+ secure_key_size, -+ verifykey2.size, -+ verifykey2.flags, -+ clear_key_bitsize, -+ verbose); -+ if (rc != 0) -+ continue; -+ -+ } -+ -+ valid = true; -+ -+ if (clear_key_bitsize) { -+ if (verifykey2.size != PKEY_SIZE_UNKNOWN) -+ *clear_key_bitsize += verifykey2.size; -+ clear_key_bitsize = NULL; /* Set it only once */ -+ } -+ -+ /* -+ * If at least one of the APQNs have a matching current MK, -+ * then don't report OLD, even if some match the old MK. -+ */ -+ if (is_old_mk && -+ (verifykey2.flags & PKEY_FLAGS_MATCH_CUR_MKVP)) -+ *is_old_mk = false; - } - -- if (is_old_mk) -- *is_old_mk = (verifykey.attributes & -- PKEY_VERIFY_ATTR_OLD_MKVP) != 0; -+ if (!valid) -+ return -ENODEV; - - pr_verbose(verbose, "Secure key validation completed successfully"); - -- return 0; -+ if (list != NULL) -+ free(list); -+ return rc; - } - - /** ---- a/zkey/pkey.h -+++ b/zkey/pkey.h -@@ -251,7 +251,7 @@ int write_secure_key(const char *keyfile - int validate_secure_key(int pkey_fd, - u8 *secure_key, size_t secure_key_size, - size_t *clear_key_bitsize, int *is_old_mk, -- bool verbose); -+ const char **apqns, bool verbose); - - int generate_key_verification_pattern(const u8 *key, size_t key_size, - char *vp, size_t vp_len, bool verbose); ---- a/zkey/zkey-cryptsetup.c -+++ b/zkey/zkey-cryptsetup.c -@@ -1492,7 +1492,7 @@ static int validate_keyslot(int keyslot, - keyslot = rc; - - rc = validate_secure_key(g.pkey_fd, (u8 *)vkey, vkeysize, clear_keysize, -- &is_old, g.verbose); -+ &is_old, NULL, g.verbose); - if (rc != 0) { - if (invalid_msg != NULL) - warnx("%s", invalid_msg); -@@ -1972,7 +1972,7 @@ static int command_validate(void) - goto out; - - rc = validate_secure_key(g.pkey_fd, (u8 *)key, keysize, &clear_keysize, -- &is_old_mk, g.verbose); -+ &is_old_mk, NULL, g.verbose); - is_valid = (rc == 0); - - token = find_token(g.cd, PAES_REENC_TOKEN_NAME); -@@ -2139,7 +2139,7 @@ static int command_setkey(void) - goto out; - - rc = validate_secure_key(g.pkey_fd, newkey, newkey_size, NULL, -- &is_old_mk, g.verbose); -+ &is_old_mk, NULL, g.verbose); - if (rc != 0) { - warnx("The secure key in file '%s' is not valid", - g.master_key_file); ---- a/zkey/zkey.c -+++ b/zkey/zkey.c -@@ -1188,7 +1188,7 @@ static int command_reencipher_file(void) - return EXIT_FAILURE; - - rc = validate_secure_key(g.pkey_fd, secure_key, secure_key_size, NULL, -- &is_old_mk, g.verbose); -+ &is_old_mk, NULL, g.verbose); - if (rc != 0) { - warnx("The secure key in file '%s' is not valid", g.pos_arg); - rc = EXIT_FAILURE; -@@ -1404,7 +1404,7 @@ static int command_validate_file(void) - return EXIT_FAILURE; - - rc = validate_secure_key(g.pkey_fd, secure_key, secure_key_size, -- &clear_key_size, &is_old_mk, g.verbose); -+ &clear_key_size, &is_old_mk, NULL, g.verbose); - if (rc != 0) { - warnx("The secure key in file '%s' is not valid", g.pos_arg); - rc = EXIT_FAILURE; diff --git a/s390-tools-sles15sp2-27-zipl-use-STAGE3_ENTRY-for-STAGE3_LOAD_ADDRESS.patch b/s390-tools-sles15sp2-27-zipl-use-STAGE3_ENTRY-for-STAGE3_LOAD_ADDRESS.patch deleted file mode 100644 index 31b649d..0000000 --- a/s390-tools-sles15sp2-27-zipl-use-STAGE3_ENTRY-for-STAGE3_LOAD_ADDRESS.patch +++ /dev/null @@ -1,45 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] zipl: use STAGE3_ENTRY for STAGE3_LOAD_ADDRESS -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: c07104dbc734ec6e55accf1bd2091b251f312ed8 -Problem-ID: VS1804 - -Upstream-Description: - - zipl: use STAGE3_ENTRY for STAGE3_LOAD_ADDRESS - - Use STAGE3_ENTRY for STAGE3_LOAD_ADDRESS as they have the same value - and this makes it more clear that the load address of stage3 is also - its entry point. - - Reviewed-by: Stefan Haberland - Reviewed-by: Philipp Rudo - Signed-off-by: Marc Hartmayer - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - zipl/include/zipl.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/zipl/include/zipl.h -+++ b/zipl/include/zipl.h -@@ -23,7 +23,7 @@ - #define STAGE3_ENTRY 0xa000UL - - #define STAGE2_LOAD_ADDRESS 0x2000UL --#define STAGE3_LOAD_ADDRESS 0xa000UL -+#define STAGE3_LOAD_ADDRESS STAGE3_ENTRY - #define IMAGE_LOAD_ADDRESS IMAGE_ENTRY - - #define ADDRESS_LIMIT 0x80000000UL diff --git a/s390-tools-sles15sp2-27-zkey-Add-support-for-re-enciphering-AES-CIPHER-keys.patch b/s390-tools-sles15sp2-27-zkey-Add-support-for-re-enciphering-AES-CIPHER-keys.patch deleted file mode 100644 index 970025a..0000000 --- a/s390-tools-sles15sp2-27-zkey-Add-support-for-re-enciphering-AES-CIPHER-keys.patch +++ /dev/null @@ -1,194 +0,0 @@ -Subject: zkey: Add support for re-enciphering AES CIPHER keys -From: Ingo Franzki - -Summary: zkey: Add support for CCA AES CIPHER keys -Description: With CCA 5 there is a new secure key type, the so called - variable length symmetric cipher key token. This token format - can hold AES keys with size 128, 192 and 256 bits together - with additional attributes cryptographic bound to the key - token. The attributes may limit the usage of the key, for - example restrict export or usability scope. So this key type - is considered to be even more secure than the traditional - secure key token. This key token type is also called "CCA - AES CIPHER key", where the formerly used key token is called - "CCA AES DATA key". - The zkey as well as the zkey-cryptsetup tools are enhanced - to support AES CIPHER keys. That is, zkey can manage AES DATA - keys, as well as AES CIPHER keys. The key type must be specified - at key generation time, the default is to generate AED DATA - keys. -Upstream-ID: 560b672bfad3c7bb6631ed4e1676a8b2c836e030 -Problem-ID: SEC1717 - -Upstream-Description: - - zkey: Add support for re-enciphering AES CIPHER keys - - For secure keys of type CCA-AESCIPHER the CCA verb CSNBKTC2 - (Key Token Change2) is used. CCA-AESDATA keys will continue - to use CCA verb CSNBKTC (Key Token Change). - - Signed-off-by: Ingo Franzki - Reviewed-by: Harald Freudenberger - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/cca.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++------------ - zkey/cca.h | 10 +++++++ - 2 files changed, 76 insertions(+), 15 deletions(-) - ---- a/zkey/cca.c -+++ b/zkey/cca.c -@@ -142,6 +142,9 @@ int load_cca_library(struct cca_lib *cca - /* Get the Key Token Change function */ - cca->dll_CSNBKTC = (t_CSNBKTC)dlsym(cca->lib_csulcca, "CSNBKTC"); - -+ /* Get the Key Token Change 2 function */ -+ cca->dll_CSNBKTC2 = (t_CSNBKTC2)dlsym(cca->lib_csulcca, "CSNBKTC2"); -+ - /* Get the Cryptographic Facility Query function */ - cca->dll_CSUACFQ = (t_CSUACFQ)dlsym(cca->lib_csulcca, "CSUACFQ"); - -@@ -153,6 +156,7 @@ int load_cca_library(struct cca_lib *cca - - if (cca->dll_CSUACFV == NULL || - cca->dll_CSNBKTC == NULL || -+ cca->dll_CSNBKTC2 == NULL || - cca->dll_CSUACFQ == NULL || - cca->dll_CSUACRA == NULL || - cca->dll_CSUACRD == NULL) { -@@ -187,10 +191,13 @@ int key_token_change(struct cca_lib *cca - u8 *secure_key, unsigned int secure_key_size, - char *method, bool verbose) - { -+ struct aescipherkeytoken *cipherkey = -+ (struct aescipherkeytoken *)secure_key; - long exit_data_len = 0, rule_array_count; - unsigned char rule_array[2 * 8] = { 0, }; - unsigned char exit_data[4] = { 0, }; - long return_code, reason_code; -+ long key_token_length; - - util_assert(cca != NULL, "Internal error: cca is NULL"); - util_assert(secure_key != NULL, "Internal error: secure_key is NULL"); -@@ -202,33 +209,77 @@ int key_token_change(struct cca_lib *cca - memcpy(rule_array + 8, "AES ", 8); - rule_array_count = 2; - -- cca->dll_CSNBKTC(&return_code, &reason_code, -- &exit_data_len, exit_data, -- &rule_array_count, rule_array, -- secure_key); -- -- pr_verbose(verbose, "CSNBKTC (Key Token Change) with '%s' returned: " -- "return_code: %ld, reason_code: %ld", method, return_code, -- reason_code); -- if (return_code != 0) { -- print_CCA_error(return_code, reason_code); -- return -EIO; -- } -- -- if (secure_key_size == 2 * AESDATA_KEY_SIZE) { -+ if (is_cca_aes_data_key(secure_key, secure_key_size)) { - cca->dll_CSNBKTC(&return_code, &reason_code, - &exit_data_len, exit_data, - &rule_array_count, rule_array, -- secure_key + AESDATA_KEY_SIZE); -+ secure_key); - - pr_verbose(verbose, "CSNBKTC (Key Token Change) with '%s' " - "returned: return_code: %ld, reason_code: %ld", - method, return_code, reason_code); -+ } else if (is_cca_aes_cipher_key(secure_key, secure_key_size)) { -+ key_token_length = cipherkey->length; -+ cca->dll_CSNBKTC2(&return_code, &reason_code, -+ &exit_data_len, exit_data, -+ &rule_array_count, rule_array, -+ &key_token_length, -+ (unsigned char *)cipherkey); -+ -+ pr_verbose(verbose, "CSNBKTC2 (Key Token Change2) with '%s' " -+ "returned: return_code: %ld, reason_code: %ld", -+ method, return_code, reason_code); -+ -+ pr_verbose(verbose, "key_token_length: %lu", key_token_length); -+ } else { -+ warnx("Invalid key type specified"); -+ return -EINVAL; -+ } -+ -+ if (return_code != 0) { -+ print_CCA_error(return_code, reason_code); -+ return -EIO; -+ } -+ -+ if (is_xts_key(secure_key, secure_key_size)) { -+ if (is_cca_aes_data_key(secure_key, secure_key_size)) { -+ cca->dll_CSNBKTC(&return_code, &reason_code, -+ &exit_data_len, exit_data, -+ &rule_array_count, rule_array, -+ secure_key + AESDATA_KEY_SIZE); -+ -+ pr_verbose(verbose, "CSNBKTC (Key Token Change) with " -+ "'%s' returned: return_code: %ld, " -+ "reason_code: %ld", method, return_code, -+ reason_code); -+ } else if (is_cca_aes_cipher_key(secure_key, secure_key_size)) { -+ cipherkey = (struct aescipherkeytoken *)(secure_key + -+ AESCIPHER_KEY_SIZE); -+ key_token_length = cipherkey->length; -+ cca->dll_CSNBKTC2(&return_code, &reason_code, -+ &exit_data_len, exit_data, -+ &rule_array_count, rule_array, -+ &key_token_length, -+ (unsigned char *)cipherkey); -+ -+ pr_verbose(verbose, "CSNBKTC2 (Key Token Change2) with " -+ "'%s' returned: return_code: %ld, " -+ "reason_code: %ld", method, return_code, -+ reason_code); -+ -+ pr_verbose(verbose, "key_token_length: %lu", -+ key_token_length); -+ } else { -+ warnx("Invalid key type specified"); -+ return -EINVAL; -+ } -+ - if (return_code != 0) { - print_CCA_error(return_code, reason_code); - return -EIO; - } - } -+ - return 0; - } - ---- a/zkey/cca.h -+++ b/zkey/cca.h -@@ -25,6 +25,15 @@ typedef void (*t_CSNBKTC)(long *return_c - unsigned char *rule_array, - unsigned char *key_identifier); - -+typedef void (*t_CSNBKTC2)(long *return_code, -+ long *reason_code, -+ long *exit_data_length, -+ unsigned char *exit_data, -+ long *rule_array_count, -+ unsigned char *rule_array, -+ long *key_identifier_length, -+ unsigned char *key_identifier); -+ - typedef void (*t_CSUACFV)(long *return_code, - long *reason_code, - long *exit_data_length, -@@ -68,6 +77,7 @@ struct cca_version { - struct cca_lib { - void *lib_csulcca; - t_CSNBKTC dll_CSNBKTC; -+ t_CSNBKTC2 dll_CSNBKTC2; - t_CSUACFV dll_CSUACFV; - t_CSUACFQ dll_CSUACFQ; - t_CSUACRA dll_CSUACRA; diff --git a/s390-tools-sles15sp2-28-zipl-move-loaders-layout-definitions-into-separate-h.patch b/s390-tools-sles15sp2-28-zipl-move-loaders-layout-definitions-into-separate-h.patch deleted file mode 100644 index e49d0f3..0000000 --- a/s390-tools-sles15sp2-28-zipl-move-loaders-layout-definitions-into-separate-h.patch +++ /dev/null @@ -1,105 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] zipl: move loaders layout definitions into separate header -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: 97ab8fb4e98c84a89d421c08b392db665125a3c0 -Problem-ID: VS1804 - -Upstream-Description: - - zipl: move loaders layout definitions into separate header - - Move the loaders (stage2/stage3) layout values to - `include/boot/loaders_layout.h` and use the `_AC` macro for the - constants. This allows the reuse of the definitions, e.g. in assembler - files, and later for the creation of linker scripts. - - Reviewed-by: Stefan Haberland - Reviewed-by: Philipp Rudo - Signed-off-by: Marc Hartmayer - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - include/boot/loaders_layout.h | 32 ++++++++++++++++++++++++++++++++ - zipl/include/zipl.h | 14 +------------- - 2 files changed, 33 insertions(+), 13 deletions(-) - ---- /dev/null -+++ b/include/boot/loaders_layout.h -@@ -0,0 +1,32 @@ -+/* -+ * zipl stage2/stage3 layout definitions -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * s390-tools is free software; you can redistribute it and/or modify -+ * it under the terms of the MIT license. See LICENSE for details. -+ * -+ */ -+ -+#ifndef LOADERS_LAYOUT_H -+#define LOADERS_LAYOUT_H -+ -+#include "lib/zt_common.h" -+#include "linux_layout.h" -+ -+#define STAGE3_ENTRY _AC(0xa000, UL) -+ -+#define STAGE2_LOAD_ADDRESS _AC(0x2000, UL) -+#define STAGE3_LOAD_ADDRESS STAGE3_ENTRY -+#define IMAGE_LOAD_ADDRESS IMAGE_ENTRY -+ -+#define STAGE3_HEAP_SIZE _AC(0x4000, UL) -+#define STAGE3_HEAP_ADDRESS _AC(0x2000, UL) -+#define STAGE3_STACK_SIZE _AC(0x1000, UL) -+#define STAGE3_STACK_ADDRESS _AC(0xF000, UL) -+#define STAGE3_PARAMS_ADDRESS _AC(0x9000, UL) -+ -+ -+#ifndef __ASSEMBLER__ -+#endif /* __ASSEMBLER__ */ -+#endif /* LOADERS_LAYOUT_H */ ---- a/zipl/include/zipl.h -+++ b/zipl/include/zipl.h -@@ -14,30 +14,18 @@ - - #include - #include "lib/zt_common.h" --#include "boot/linux_layout.h" -+#include "boot/loaders_layout.h" - - #define ZIPL_MAGIC "zIPL" - #define ZIPL_MAGIC_SIZE 4 - #define DISK_LAYOUT_ID 0x00000001 - --#define STAGE3_ENTRY 0xa000UL -- --#define STAGE2_LOAD_ADDRESS 0x2000UL --#define STAGE3_LOAD_ADDRESS STAGE3_ENTRY --#define IMAGE_LOAD_ADDRESS IMAGE_ENTRY -- - #define ADDRESS_LIMIT 0x80000000UL - #define ADDRESS_LIMIT_KDUMP 0x2000000UL /* HSA size: 32 MiB */ - #define UNSPECIFIED_ADDRESS -1UL - #define MAXIMUM_PARMLINE_SIZE 0x380UL - #define MAXIMUM_PHYSICAL_BLOCKSIZE 0x1000UL - --#define STAGE3_HEAP_SIZE 0x4000UL --#define STAGE3_HEAP_ADDRESS 0x2000UL --#define STAGE3_STACK_SIZE 0x1000UL --#define STAGE3_STACK_ADDRESS 0xF000UL --#define STAGE3_PARAMS_ADDRESS 0x9000UL -- - #define PSW_ADDRESS_MASK 0x000000007fffffffUL - #define PSW_LOAD 0x0008000080000000UL - #define PSW_DISABLED_WAIT 0x000a000000000000UL diff --git a/s390-tools-sles15sp2-28-zkey-Check-crypto-card-level-during-APQN-cross-check.patch b/s390-tools-sles15sp2-28-zkey-Check-crypto-card-level-during-APQN-cross-check.patch deleted file mode 100644 index e765c10..0000000 --- a/s390-tools-sles15sp2-28-zkey-Check-crypto-card-level-during-APQN-cross-check.patch +++ /dev/null @@ -1,361 +0,0 @@ -Subject: zkey: Check crypto card level during APQN cross checking -From: Ingo Franzki - -Summary: zkey: Add support for CCA AES CIPHER keys -Description: With CCA 5 there is a new secure key type, the so called - variable length symmetric cipher key token. This token format - can hold AES keys with size 128, 192 and 256 bits together - with additional attributes cryptographic bound to the key - token. The attributes may limit the usage of the key, for - example restrict export or usability scope. So this key type - is considered to be even more secure than the traditional - secure key token. This key token type is also called "CCA - AES CIPHER key", where the formerly used key token is called - "CCA AES DATA key". - The zkey as well as the zkey-cryptsetup tools are enhanced - to support AES CIPHER keys. That is, zkey can manage AES DATA - keys, as well as AES CIPHER keys. The key type must be specified - at key generation time, the default is to generate AED DATA - keys. -Upstream-ID: b7bb90c552f9b62c0b4ddc1295e76769149ee6bb -Problem-ID: SEC1717 - -Upstream-Description: - - zkey: Check crypto card level during APQN cross checking - - Secure keys of type CCA-AESCIPHER require a CEX6C or newer crypto - card. Also check for the minimum required card level during cross - checking of APQNs. Also display the card level in the APQN report. - - Signed-off-by: Ingo Franzki - Reviewed-by: Harald Freudenberger - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/keystore.c | 25 +++++++++++++---- - zkey/pkey.c | 20 ++++++++++++++ - zkey/pkey.h | 1 - zkey/utils.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- - zkey/utils.h | 6 ++-- - zkey/zkey.c | 9 ++++-- - 6 files changed, 126 insertions(+), 15 deletions(-) - ---- a/zkey/keystore.c -+++ b/zkey/keystore.c -@@ -1722,7 +1722,9 @@ int keystore_generate_key(struct keystor - if (rc != 0) - goto out_free_key_filenames; - -- rc = cross_check_apqns(apqns, 0, true, keystore->verbose); -+ rc = cross_check_apqns(apqns, 0, -+ get_min_card_level_for_keytype(key_type), true, -+ keystore->verbose); - if (rc == -EINVAL) - goto out_free_key_filenames; - if (rc != 0 && rc != -ENOTSUP && noapqncheck == 0) { -@@ -1850,7 +1852,9 @@ int keystore_import_key(struct keystore - goto out_free_key; - } - -- rc = cross_check_apqns(apqns, mkvp, true, keystore->verbose); -+ rc = cross_check_apqns(apqns, mkvp, -+ get_min_card_level_for_keytype(key_type), true, -+ keystore->verbose); - if (rc == -EINVAL) - goto out_free_key; - if (rc != 0 && rc != -ENOTSUP && noapqncheck == 0) { -@@ -1937,8 +1941,8 @@ int keystore_change_key(struct keystore - .nomsg = 0 }; - struct key_filenames file_names = { NULL, NULL, NULL }; - struct properties *key_props = NULL; -+ char *apqns_prop, *key_type; - size_t secure_key_size; -- char *apqns_prop; - u8 *secure_key; - char temp[30]; - u64 mkvp; -@@ -2005,9 +2009,12 @@ int keystore_change_key(struct keystore - goto out; - - apqns_prop = properties_get(key_props, PROP_NAME_APQNS); -- rc = cross_check_apqns(apqns_prop, mkvp, true, -- keystore->verbose); -+ key_type = properties_get(key_props, PROP_NAME_KEY_TYPE); -+ rc = cross_check_apqns(apqns_prop, mkvp, -+ get_min_card_level_for_keytype(key_type), -+ true, keystore->verbose); - free(apqns_prop); -+ free(key_type); - if (rc == -ENOTSUP) - rc = 0; - if (rc != 0 && noapqncheck == 0) { -@@ -2373,12 +2380,17 @@ static int _keystore_display_apqn_status - { - int rc, warning = 0; - char *apqns; -+ char *key_type; - - apqns = properties_get(properties, PROP_NAME_APQNS); - if (apqns == NULL) - return 0; - -- rc = cross_check_apqns(apqns, mkvp, true, keystore->verbose); -+ apqns = properties_get(properties, PROP_NAME_APQNS); -+ key_type = properties_get(properties, PROP_NAME_KEY_TYPE); -+ rc = cross_check_apqns(apqns, mkvp, -+ get_min_card_level_for_keytype(key_type), true, -+ keystore->verbose); - if (rc != 0 && rc != -ENOTSUP) - warning = 1; - -@@ -2386,6 +2398,7 @@ static int _keystore_display_apqn_status - printf("\n"); - - free(apqns); -+ free(key_type); - return warning; - } - /** ---- a/zkey/pkey.c -+++ b/zkey/pkey.c -@@ -1630,3 +1630,23 @@ const char *get_key_type(const u8 *key, - - return NULL; - } -+ -+/** -+ * Returns the minimum card level for a specific key type -+ * -+ * @param[in] key_type the type of the key -+ * -+ * @returns the minimum card level, or -1 for unknown key types -+ */ -+int get_min_card_level_for_keytype(const char *key_type) -+{ -+ if (key_type == NULL) -+ return -1; -+ -+ if (strcasecmp(key_type, KEY_TYPE_CCA_AESDATA) == 0) -+ return 3; -+ if (strcasecmp(key_type, KEY_TYPE_CCA_AESCIPHER) == 0) -+ return 6; -+ -+ return -1; -+} ---- a/zkey/pkey.h -+++ b/zkey/pkey.h -@@ -264,5 +264,6 @@ bool is_cca_aes_cipher_key(const u8 *key - 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); -+int get_min_card_level_for_keytype(const char *key_type); - - #endif ---- a/zkey/utils.c -+++ b/zkey/utils.c -@@ -119,6 +119,49 @@ out: - } - - /** -+ * Returns the level of the card. For a CEX3C 3 is returned, for a CEX4C 4, -+ * and so on. -+ * -+ * @param[in] card card number -+ * -+ * @returns The card level, or -1 of the level can not be determined. -+ */ -+int sysfs_get_card_level(int card) -+{ -+ char *dev_path; -+ char type[20]; -+ int rc; -+ -+ dev_path = util_path_sysfs("bus/ap/devices/card%02x", card); -+ if (!util_path_is_dir(dev_path)) { -+ rc = -1; -+ goto out; -+ } -+ if (util_file_read_line(type, sizeof(type), "%s/type", dev_path) != 0) { -+ rc = -1; -+ goto out; -+ } -+ if (strncmp(type, "CEX", 3) != 0 || strlen(type) < 5) { -+ rc = -1; -+ goto out; -+ } -+ if (type[4] != 'C') { -+ rc = -1; -+ goto out; -+ } -+ if (type[3] < '1' || type[3] > '9') { -+ rc = -1; -+ goto out; -+ } -+ -+ rc = type[3] - '0'; -+ -+out: -+ free(dev_path); -+ return rc; -+} -+ -+/** - * Gets the 8 character ASCII serial number string of an card from the sysfs. - * - * @param[in] card card number -@@ -436,12 +479,14 @@ static int print_apqn_mk_info(int card, - { - struct print_apqn_info *info = (struct print_apqn_info *)handler_data; - struct mk_info mk_info; -- int rc; -+ int rc, level; - - rc = sysfs_get_mkvps(card, domain, &mk_info, info->verbose); - if (rc == -ENOTSUP) - return rc; - -+ level = sysfs_get_card_level(card); -+ - util_rec_set(info->rec, "APQN", "%02x.%04x", card, domain); - - if (rc == 0) { -@@ -470,6 +515,11 @@ static int print_apqn_mk_info(int card, - util_rec_set(info->rec, "OLD", "?"); - } - -+ if (level > 0) -+ util_rec_set(info->rec, "TYPE", "CEX%dC", level); -+ else -+ util_rec_set(info->rec, "TYPE", "?"); -+ - util_rec_print(info->rec); - - return 0; -@@ -499,6 +549,7 @@ int print_mk_info(const char *apqns, boo - util_rec_def(info.rec, "NEW", UTIL_REC_ALIGN_LEFT, 16, "NEW MK"); - util_rec_def(info.rec, "CUR", UTIL_REC_ALIGN_LEFT, 16, "CURRENT MK"); - util_rec_def(info.rec, "OLD", UTIL_REC_ALIGN_LEFT, 16, "OLD MK"); -+ util_rec_def(info.rec, "TYPE", UTIL_REC_ALIGN_LEFT, 6, "TYPE"); - util_rec_print_hdr(info.rec); - - rc = handle_apqns(apqns, print_apqn_mk_info, &info, verbose); -@@ -511,6 +562,7 @@ struct cross_check_info { - u64 mkvp; - u64 new_mkvp; - bool key_mkvp; -+ int min_level; - u32 num_cur_match; - u32 num_old_match; - u32 num_new_match; -@@ -525,7 +577,7 @@ static int cross_check_mk_info(int card, - struct cross_check_info *info = (struct cross_check_info *)handler_data; - struct mk_info mk_info; - char temp[200]; -- int rc; -+ int rc, level; - - rc = sysfs_get_mkvps(card, domain, &mk_info, info->verbose); - if (rc == -ENODEV) { -@@ -539,6 +591,19 @@ static int cross_check_mk_info(int card, - - info->num_checked++; - -+ if (info->min_level >= 0) { -+ level = sysfs_get_card_level(card); -+ -+ if (level < info->min_level) { -+ info->print_mks = 1; -+ info->mismatch = 1; -+ sprintf(temp, "WARNING: APQN %02x.%04x: The card level " -+ "is less than CEX%dC.", card, domain, -+ info->min_level); -+ util_print_indented(temp, 0); -+ } -+ } -+ - if (mk_info.new_mk.mk_state == MK_STATE_PARTIAL) { - info->print_mks = 1; - sprintf(temp, "INFO: APQN %02x.%04x: The NEW master key " -@@ -662,6 +727,8 @@ static int cross_check_mk_info(int card, - * @param[in] mkvp The master key verification pattern of a secure key. - * If this is all zero, then the master keys are not - * matched against it. -+ * @param[in] min_level The minimum card level required. If min_level is -1 then -+ * the card level is not checked. - * @param[in] print_mks if true, then a the full master key info of all - * specified APQns is printed, in case of a mismatch. - * @param[in] verbose if true, verbose messages are printed -@@ -671,7 +738,8 @@ static int cross_check_mk_info(int card, - * -ENOTSUP is returned when the mkvps sysfs attribute is not - * available, because the zcrypt kernel module is on an older level. - */ --int cross_check_apqns(const char *apqns, u64 mkvp, bool print_mks, bool verbose) -+int cross_check_apqns(const char *apqns, u64 mkvp, int min_level, -+ bool print_mks, bool verbose) - { - struct cross_check_info info; - char temp[200]; -@@ -680,10 +748,12 @@ int cross_check_apqns(const char *apqns, - memset(&info, 0, sizeof(info)); - info.key_mkvp = mkvp != 0; - info.mkvp = mkvp; -+ info.min_level = min_level; - info.verbose = verbose; - -- pr_verbose(verbose, "Cross checking APQNs with mkvp 0x%016llx: %s", -- mkvp, apqns != NULL ? apqns : "ANY"); -+ pr_verbose(verbose, "Cross checking APQNs with mkvp 0x%016llx and " -+ "min-level %d: %s", mkvp, min_level, -+ apqns != NULL ? apqns : "ANY"); - - rc = handle_apqns(apqns, cross_check_mk_info, &info, verbose); - if (rc != 0) ---- a/zkey/utils.h -+++ b/zkey/utils.h -@@ -18,6 +18,8 @@ int sysfs_is_card_online(int card); - - int sysfs_is_apqn_online(int card, int domain); - -+int sysfs_get_card_level(int card); -+ - int sysfs_get_serialnr(int card, char serialnr[9], bool verbose); - - #define MK_STATE_EMPTY 0 -@@ -48,7 +50,7 @@ int handle_apqns(const char *apqns, apqn - - int print_mk_info(const char *apqns, bool verbose); - --int cross_check_apqns(const char *apqns, u64 mkvp, bool print_mks, -- bool verbose); -+int cross_check_apqns(const char *apqns, u64 mkvp, int min_level, -+ bool print_mks, bool verbose); - - #endif ---- a/zkey/zkey.c -+++ b/zkey/zkey.c -@@ -1122,7 +1122,9 @@ static int command_generate(void) - return EXIT_FAILURE; - } - -- rc = cross_check_apqns(NULL, 0, true, g.verbose); -+ rc = cross_check_apqns(NULL, 0, -+ get_min_card_level_for_keytype(g.key_type), -+ true, g.verbose); - if (rc == -EINVAL) - return EXIT_FAILURE; - if (rc != 0 && rc != -ENOTSUP) { -@@ -1447,7 +1449,10 @@ static int command_validate_file(void) - printf(" %.*s\n", VERIFICATION_PATTERN_LEN / 2, - &vp[VERIFICATION_PATTERN_LEN / 2]); - -- rc = cross_check_apqns(NULL, mkvp, true, g.verbose); -+ rc = cross_check_apqns(NULL, mkvp, -+ get_min_card_level_for_keytype( -+ get_key_type(secure_key, secure_key_size)), -+ true, g.verbose); - if (rc == -EINVAL) - return EXIT_FAILURE; - if (rc != 0 && rc != -ENOTSUP) { diff --git a/s390-tools-sles15sp2-29-zipl-s390.h-rename-inline-macro-into-__always_inline.patch b/s390-tools-sles15sp2-29-zipl-s390.h-rename-inline-macro-into-__always_inline.patch deleted file mode 100644 index 1835dc1..0000000 --- a/s390-tools-sles15sp2-29-zipl-s390.h-rename-inline-macro-into-__always_inline.patch +++ /dev/null @@ -1,192 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] zipl/s390.h: rename `inline` macro into `__always_inline` -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: 67e76b8ebd8acb4aef1d22309287776892b7267e -Problem-ID: VS1804 - -Upstream-Description: - - zipl/s390.h: rename `inline` macro into `__always_inline` - - Rename `inline` macro into `__always_inline` so one can differentiate - between the macro and the C keyword. While at it, undefine the - previous `__always_inline` macro so s390.h can be used in combination - with glibc. - - Reviewed-by: Philipp Rudo - Reviewed-by: Stefan Haberland - Signed-off-by: Marc Hartmayer - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - zipl/boot/s390.h | 39 ++++++++++++++++++++++----------------- - 1 file changed, 22 insertions(+), 17 deletions(-) - ---- a/zipl/boot/s390.h -+++ b/zipl/boot/s390.h -@@ -19,7 +19,12 @@ - #define __pa(x) ((unsigned long)(x)) - #define MIN(x, y) ((x) < (y) ? (x) : (y)) - #define barrier() __asm__ __volatile__("": : :"memory") --#define inline inline __attribute__((always_inline)) -+/* The Linux kernel (in stddef.h) and glibc (sys/cdefs.h) define -+ * __always_inline. Therefore undefine it first to allow the headers -+ * to be included first. -+ */ -+#undef __always_inline -+#define __always_inline inline __attribute__((always_inline)) - - /* - * Helper macro for exception table entries -@@ -214,7 +219,7 @@ do { \ - libc_stop(reason); \ - } while (0) - --static inline int page_is_valid(unsigned long addr) -+static __always_inline int page_is_valid(unsigned long addr) - { - unsigned long tmp; - int rc; -@@ -234,7 +239,7 @@ static inline int page_is_valid(unsigned - return rc; - } - --static inline uint32_t csum_partial(const void *buf, int len, uint32_t sum) -+static __always_inline uint32_t csum_partial(const void *buf, int len, uint32_t sum) - { - register unsigned long reg2 asm("2") = (unsigned long) buf; - register unsigned long reg3 asm("3") = (unsigned long) len; -@@ -262,7 +267,7 @@ static inline uint32_t csum_partial(cons - "i" (low), "i" (high)); \ - }) - --static inline void __ctl_set_bit(unsigned int cr, unsigned int bit) -+static __always_inline void __ctl_set_bit(unsigned int cr, unsigned int bit) - { - unsigned long reg; - -@@ -282,7 +287,7 @@ enum diag308_subcode { - DIAG308_STORE = 6, - }; - --static inline int diag308(unsigned long subcode, void *addr) -+static __always_inline int diag308(unsigned long subcode, void *addr) - { - register unsigned long _addr asm("0") = (unsigned long) addr; - register unsigned long _rc asm("1") = 0; -@@ -298,7 +303,7 @@ static inline int diag308(unsigned long - /* - * Store CPU address - */ --static inline unsigned short stap(void) -+static __always_inline unsigned short stap(void) - { - unsigned short cpu_address; - -@@ -309,7 +314,7 @@ static inline unsigned short stap(void) - /* - * Program the clock comparator - */ --static inline void set_clock_comparator(uint64_t time) -+static __always_inline void set_clock_comparator(uint64_t time) - { - asm volatile("sckc %0" : : "Q" (time)); - } -@@ -317,7 +322,7 @@ static inline void set_clock_comparator( - /* - * Program the CPU timer - */ --static inline void set_cpu_timer(uint64_t timer) -+static __always_inline void set_cpu_timer(uint64_t timer) - { - asm volatile("spt %0" : : "Q" (timer)); - } -@@ -325,7 +330,7 @@ static inline void set_cpu_timer(uint64_ - /* - * Get current time (store clock) - */ --static inline unsigned long long get_tod_clock(void) -+static __always_inline unsigned long long get_tod_clock(void) - { - unsigned long long clk; - -@@ -343,7 +348,7 @@ struct cpuid { - unsigned int unused:16; - } __packed __aligned(8); - --static inline void get_cpu_id(struct cpuid *ptr) -+static __always_inline void get_cpu_id(struct cpuid *ptr) - { - asm volatile("stidp %0" : "=Q" (*ptr)); - } -@@ -351,7 +356,7 @@ static inline void get_cpu_id(struct cpu - /* - * Check if we run under z/VM - */ --static inline int is_zvm(void) -+static __always_inline int is_zvm(void) - { - struct cpuid cpuid; - -@@ -369,7 +374,7 @@ typedef struct { - /* - * Save vector registers - */ --static inline void save_vx_regs(__vector128 *vxrs) -+static __always_inline void save_vx_regs(__vector128 *vxrs) - { - typedef struct { __vector128 _[32]; } addrtype; - -@@ -383,7 +388,7 @@ static inline void save_vx_regs(__vector - /* - * Save vector registers safe - */ --static inline void save_vx_regs_safe(__vector128 *vxrs) -+static __always_inline void save_vx_regs_safe(__vector128 *vxrs) - { - unsigned long cr0; - -@@ -396,7 +401,7 @@ static inline void save_vx_regs_safe(__v - - #define MAX_FACILITY_BIT (256*8) /* stfle_fac_list has 256 bytes */ - --static inline int __test_facility(unsigned long nr, void *facilities) -+static __always_inline int __test_facility(unsigned long nr, void *facilities) - { - unsigned char *ptr; - -@@ -411,12 +416,12 @@ static inline int __test_facility(unsign - * That makes it easier to query facility bits with the bit number as - * documented in the Principles of Operation. - */ --static inline int test_facility(unsigned long nr) -+static __always_inline int test_facility(unsigned long nr) - { - return __test_facility(nr, &S390_lowcore.stfle_fac_list); - } - --static inline unsigned long __stfle_asm(uint64_t *stfle_fac_list, int size) -+static __always_inline unsigned long __stfle_asm(uint64_t *stfle_fac_list, int size) - { - register unsigned long reg0 asm("0") = size - 1; - -@@ -433,7 +438,7 @@ static inline unsigned long __stfle_asm( - * @stfle_fac_list: array where facility list can be stored - * @size: size of passed in array in double words - */ --static inline void stfle(uint64_t *stfle_fac_list, int size) -+static __always_inline void stfle(uint64_t *stfle_fac_list, int size) - { - unsigned long nr; - diff --git a/s390-tools-sles15sp2-29-zkey-Add-helper-function-to-query-the-CCA-firmware-v.patch b/s390-tools-sles15sp2-29-zkey-Add-helper-function-to-query-the-CCA-firmware-v.patch deleted file mode 100644 index c95a443..0000000 --- a/s390-tools-sles15sp2-29-zkey-Add-helper-function-to-query-the-CCA-firmware-v.patch +++ /dev/null @@ -1,101 +0,0 @@ -Subject: zkey: Add helper function to query the CCA firmware version -From: Ingo Franzki - -Summary: zkey: Add support for CCA AES CIPHER keys -Description: With CCA 5 there is a new secure key type, the so called - variable length symmetric cipher key token. This token format - can hold AES keys with size 128, 192 and 256 bits together - with additional attributes cryptographic bound to the key - token. The attributes may limit the usage of the key, for - example restrict export or usability scope. So this key type - is considered to be even more secure than the traditional - secure key token. This key token type is also called "CCA - AES CIPHER key", where the formerly used key token is called - "CCA AES DATA key". - The zkey as well as the zkey-cryptsetup tools are enhanced - to support AES CIPHER keys. That is, zkey can manage AES DATA - keys, as well as AES CIPHER keys. The key type must be specified - at key generation time, the default is to generate AED DATA - keys. -Upstream-ID: b0cc0e47378de9cd82b0cd14228b26be4d615ffc -Problem-ID: SEC1717 - -Upstream-Description: - - zkey: Add helper function to query the CCA firmware version - - Some future functions are dependent on the firmware version of the - CCA crypto adapter. This helper function allows to query the version - of the currently selected CCA adapter. - - Signed-off-by: Ingo Franzki - Reviewed-by: Harald Freudenberger - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/cca.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 52 insertions(+) - ---- a/zkey/cca.c -+++ b/zkey/cca.c -@@ -474,6 +474,58 @@ static int get_cca_adapter_serialnr(stru - } - - /** -+ * Queries the firmware version of the current CCA adapter -+ * -+ * @param[in] cca the CCA library structure -+ * @param[out] version the struct where the version is returned -+ * @param[in] verbose if true, verbose messages are printed -+ * -+ * @returns 0 on success, a negative errno in case of an error. -+ */ -+static int get_cca_adapter_version(struct cca_lib *cca, -+ struct cca_version *version, -+ bool verbose) -+{ -+ long exit_data_len = 0, rule_array_count, verb_data_length = 0; -+ unsigned char rule_array[6 * 8] = { 0, }; -+ unsigned char exit_data[4] = { 0, }; -+ long return_code, reason_code; -+ char version_data[9]; -+ -+ util_assert(cca != NULL, "Internal error: cca is NULL"); -+ -+ memset(rule_array, 0, sizeof(rule_array)); -+ memcpy(rule_array, "STATCCA ", 8); -+ rule_array_count = 1; -+ -+ cca->dll_CSUACFQ(&return_code, &reason_code, -+ &exit_data_len, exit_data, -+ &rule_array_count, rule_array, -+ &verb_data_length, NULL); -+ -+ pr_verbose(verbose, "CSUACFQ (Cryptographic Facility Query) returned: " -+ "return_code: %ld, reason_code: %ld", return_code, -+ reason_code); -+ if (return_code != 0) { -+ print_CCA_error(return_code, reason_code); -+ return -EIO; -+ } -+ -+ memcpy(version_data, rule_array+3*8, 8); -+ version_data[8] = '\0'; -+ -+ pr_verbose(verbose, "CCA firmware version string: %s", version_data); -+ -+ if (sscanf((char *)version_data, "%u.%u.%uz", &version->ver, -+ &version->rel, &version->mod) != 3) { -+ warnx("CCA formware version is invalid: %s", version_data); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+/** - * Selects the specified APQN to be used for the CCA host library. - * - * @param[in] cca the CCA library structure diff --git a/s390-tools-sles15sp2-30-zipl-move-__always_inline-barrier-__pa32-pa-to-zt_co.patch b/s390-tools-sles15sp2-30-zipl-move-__always_inline-barrier-__pa32-pa-to-zt_co.patch deleted file mode 100644 index c59e0d7..0000000 --- a/s390-tools-sles15sp2-30-zipl-move-__always_inline-barrier-__pa32-pa-to-zt_co.patch +++ /dev/null @@ -1,74 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] zipl: move __always_inline/barrier/__pa32/pa to zt_common.h -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: 24fe8c1d1b75185f341ec2d0efc6c34f0b9263f1 -Problem-ID: VS1804 - -Upstream-Description: - - zipl: move __always_inline/barrier/__pa32/pa to zt_common.h - - Move `__always_inline/barrier/__pa32/pa` to `lib/zt_common.h` as this - is non-architecture dependent code. - - Reviewed-by: Philipp Rudo - Reviewed-by: Stefan Haberland - Signed-off-by: Marc Hartmayer - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - include/lib/zt_common.h | 12 ++++++++++++ - zipl/boot/s390.h | 9 --------- - 2 files changed, 12 insertions(+), 9 deletions(-) - ---- a/include/lib/zt_common.h -+++ b/include/lib/zt_common.h -@@ -55,6 +55,18 @@ - #define __may_alias __attribute__((may_alias)) - #define __section(x) __attribute__((__section__(#x))) - #define __noinline __attribute__((__noinline__)) -+/* The Linux kernel (in stddef.h) and glibc (sys/cdefs.h) define -+ * __always_inline. Therefore undefine it first to allow the headers -+ * to be included first. -+ */ -+#undef __always_inline -+#define __always_inline inline __attribute__((always_inline)) -+ -+#define __pa32(x) ((uint32_t)(unsigned long)(x)) -+#define __pa(x) ((unsigned long)(x)) -+ -+#define barrier() __asm__ __volatile__("": : :"memory") -+ - - typedef unsigned long long u64; - typedef signed long long s64; ---- a/zipl/boot/s390.h -+++ b/zipl/boot/s390.h -@@ -15,16 +15,7 @@ - #include "libc.h" - #include "boot/sigp.h" - --#define __pa32(x) ((uint32_t)(unsigned long)(x)) --#define __pa(x) ((unsigned long)(x)) - #define MIN(x, y) ((x) < (y) ? (x) : (y)) --#define barrier() __asm__ __volatile__("": : :"memory") --/* The Linux kernel (in stddef.h) and glibc (sys/cdefs.h) define -- * __always_inline. Therefore undefine it first to allow the headers -- * to be included first. -- */ --#undef __always_inline --#define __always_inline inline __attribute__((always_inline)) - - /* - * Helper macro for exception table entries diff --git a/s390-tools-sles15sp2-30-zkey-Add-helper-function-to-convert-secure-keys-betw.patch b/s390-tools-sles15sp2-30-zkey-Add-helper-function-to-convert-secure-keys-betw.patch deleted file mode 100644 index 65da9e0..0000000 --- a/s390-tools-sles15sp2-30-zkey-Add-helper-function-to-convert-secure-keys-betw.patch +++ /dev/null @@ -1,279 +0,0 @@ -Subject: zkey: Add helper function to convert secure keys between key types -From: Ingo Franzki - -Summary: zkey: Add support for CCA AES CIPHER keys -Description: With CCA 5 there is a new secure key type, the so called - variable length symmetric cipher key token. This token format - can hold AES keys with size 128, 192 and 256 bits together - with additional attributes cryptographic bound to the key - token. The attributes may limit the usage of the key, for - example restrict export or usability scope. So this key type - is considered to be even more secure than the traditional - secure key token. This key token type is also called "CCA - AES CIPHER key", where the formerly used key token is called - "CCA AES DATA key". - The zkey as well as the zkey-cryptsetup tools are enhanced - to support AES CIPHER keys. That is, zkey can manage AES DATA - keys, as well as AES CIPHER keys. The key type must be specified - at key generation time, the default is to generate AED DATA - keys. -Upstream-ID: 7d4b1e18b6195f48414f42b4655f900872fed1e7 -Problem-ID: SEC1717 - -Upstream-Description: - - zkey: Add helper function to convert secure keys between key types - - Add a helper function to convert a secure key from key type - CCA-AESDATA to CCA-AESCIPHER. - - Signed-off-by: Ingo Franzki - Reviewed-by: Harald Freudenberger - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/cca.c | 171 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- - zkey/cca.h | 22 +++++++ - 2 files changed, 192 insertions(+), 1 deletion(-) - ---- a/zkey/cca.c -+++ b/zkey/cca.c -@@ -55,6 +55,14 @@ static void print_CCA_error(int return_c - warnx("The secure key has a CCA master key " - "verification pattern that is not valid"); - break; -+ case 90: -+ warnx("The operation has been rejected due to access " -+ "control checking"); -+ break; -+ case 2143: -+ warnx("The operation has been rejected due to key " -+ "export restrictions of the secure key"); -+ break; - } - break; - case 12: -@@ -154,12 +162,16 @@ int load_cca_library(struct cca_lib *cca - /* Cryptographic Resource Deallocate function */ - cca->dll_CSUACRD = (t_CSUACRD)dlsym(cca->lib_csulcca, "CSUACRD"); - -+ /* Get the Key Translate 2 function */ -+ cca->dll_CSNBKTR2 = (t_CSNBKTR2)dlsym(cca->lib_csulcca, "CSNBKTR2"); -+ - if (cca->dll_CSUACFV == NULL || - cca->dll_CSNBKTC == NULL || - cca->dll_CSNBKTC2 == NULL || - cca->dll_CSUACFQ == NULL || - cca->dll_CSUACRA == NULL || -- cca->dll_CSUACRD == NULL) { -+ cca->dll_CSUACRD == NULL || -+ cca->dll_CSNBKTR2 == NULL) { - pr_verbose(verbose, "%s", dlerror()); - warnx("The command requires the IBM CCA Host Libraries and " - "Tools.\nFor the supported environments and downloads, " -@@ -729,3 +741,160 @@ void print_msg_for_cca_envvars(const cha - util_print_indented(msg, 0); - free(msg); - } -+ -+/* -+ * Convert a secure key of type CCA-AESDATA into a secure key of type -+ * CCA-AESCIPHER. -+ * -+ * @param[in] cca the CCA library structure -+ * @param[in] input_key the secure key to convert -+ * @param[in] input_key_size the size of the secure key to convert -+ * @param[in] output_key buffer for the converted secure key -+ * @param[in/out] output_key_size on input: size of the output buffer. -+ * on exit: size of the converted secure key -+ * @param[in] verbose if true, verbose messages are printed -+ * -+ * @returns 0 on success, a negative errno in case of an error. -+ */ -+int convert_aes_data_to_cipher_key(struct cca_lib *cca, -+ u8 *input_key, unsigned int input_key_size, -+ u8 *output_key, -+ unsigned int *output_key_size, -+ bool verbose) -+{ -+ long input_token_size, output_token_size, zero = 0; -+ long exit_data_len = 0, rule_array_count = 0; -+ unsigned char *input_token, *output_token; -+ unsigned char rule_array[8 * 2] = { 0, }; -+ unsigned char null_token[64] = { 0, }; -+ long null_token_len = sizeof(null_token); -+ unsigned char exit_data[4] = { 0, }; -+ struct aescipherkeytoken *cipherkey; -+ long return_code, reason_code; -+ struct cca_version version; -+ unsigned char buffer[800]; -+ int rc; -+ -+ util_assert(cca != NULL, "Internal error: cca is NULL"); -+ util_assert(input_key != NULL, "Internal error: input_key is NULL"); -+ util_assert(output_key != NULL, "Internal error: output_key is NULL"); -+ util_assert(output_key_size != NULL, -+ "Internal error: output_key_size is NULL"); -+ -+ if (is_cca_aes_cipher_key(input_key, input_key_size)) { -+ warnx("Invalid key-type specified"); -+ return -EINVAL; -+ } -+ -+ if (*output_key_size < (is_xts_key(input_key, input_key_size) ? -+ 2 * AESCIPHER_KEY_SIZE : AESCIPHER_KEY_SIZE)) -+ return -EINVAL; -+ -+ /* -+ * We need a CCA firmware version 6.3.27 or later to support -+ * conversion of secure keys that are exportable to CPACF protected keys -+ */ -+ rc = get_cca_adapter_version(cca, &version, verbose); -+ if (rc != 0) -+ return rc; -+ if (version.ver < 6 || -+ (version.ver == 6 && version.rel < 3) || -+ (version.ver == 6 && version.rel < 3 && version.mod < 27)) { -+ util_print_indented("The used CCA firmware version does not " -+ "support converting a secure key that can " -+ "be used with the PAES cipher. The " -+ "required CCA firmware version is 6.3.27 " -+ "or later. For the supported environments " -+ "and updates, see: " CCA_WEB_PAGE, 0); -+ return -ENOTSUP; -+ } -+ -+ input_token = input_key; -+ input_token_size = AESDATA_KEY_SIZE; -+ output_token = buffer; -+ output_token_size = sizeof(buffer); -+ memset(buffer, 0, sizeof(buffer)); -+ -+ memcpy(rule_array, "AES ", 8); -+ memcpy(rule_array + 8, "REFORMAT", 8); -+ rule_array_count = 2; -+ -+ cca->dll_CSNBKTR2(&return_code, &reason_code, -+ &exit_data_len, exit_data, -+ &rule_array_count, rule_array, -+ &input_token_size, input_token, -+ &null_token_len, null_token, -+ &zero, NULL, -+ &output_token_size, output_token); -+ -+ pr_verbose(verbose, "CSNBKTR2 (Key Translate2) " -+ "returned: return_code: %ld, reason_code: %ld", return_code, -+ reason_code); -+ if (return_code != 0) { -+ print_CCA_error(return_code, reason_code); -+ return -EIO; -+ } -+ -+ pr_verbose(verbose, "output_token_size: %lu", output_token_size); -+ if (output_token_size > (long)AESCIPHER_KEY_SIZE) { -+ pr_verbose(verbose, "Output key token too large"); -+ return -EINVAL; -+ } -+ -+ /* -+ * Check if the converted key allows export to CPACF protected key. -+ * If not, then the CCA host library or firmware code level is too low. -+ */ -+ cipherkey = (struct aescipherkeytoken *)buffer; -+ if ((cipherkey->kmf1 & 0x0800) == 0) { -+ util_print_indented("The used CCA firmware version does not " -+ "support converting a secure key that can " -+ "be used with the PAES cipher. The " -+ "required CCA firmware version is 6.3.27 " -+ "or later. For the supported environments " -+ "and updates, see: " CCA_WEB_PAGE, 0); -+ return -ENOTSUP; -+ } -+ -+ memset(output_key, 0, *output_key_size); -+ memcpy(output_key, buffer, output_token_size); -+ *output_key_size = AESCIPHER_KEY_SIZE; -+ -+ if (is_xts_key(input_key, input_key_size)) { -+ input_token = input_key + AESDATA_KEY_SIZE; -+ input_token_size = AESDATA_KEY_SIZE; -+ output_token = buffer; -+ output_token_size = sizeof(buffer); -+ memset(buffer, 0, sizeof(buffer)); -+ -+ cca->dll_CSNBKTR2(&return_code, &reason_code, -+ &exit_data_len, exit_data, -+ &rule_array_count, rule_array, -+ &input_token_size, input_token, -+ &null_token_len, null_token, -+ &zero, NULL, -+ &output_token_size, output_token); -+ -+ pr_verbose(verbose, "CSNBKTR2 (Key Translate2) " -+ "returned: return_code: %ld, reason_code: %ld", -+ return_code, reason_code); -+ if (return_code != 0) { -+ print_CCA_error(return_code, reason_code); -+ return -EIO; -+ } -+ -+ pr_verbose(verbose, "output_token_size: %lu", -+ output_token_size); -+ if (output_token_size > (long)AESCIPHER_KEY_SIZE) { -+ pr_verbose(verbose, "Output key token too large"); -+ return -EINVAL; -+ } -+ -+ memcpy(output_key + AESCIPHER_KEY_SIZE, buffer, -+ output_token_size); -+ *output_key_size += AESCIPHER_KEY_SIZE; -+ } -+ -+ return 0; -+} -+ ---- a/zkey/cca.h -+++ b/zkey/cca.h -@@ -68,6 +68,21 @@ typedef void (*t_CSUACRD)(long *return_c - long *ressource_name_length, - unsigned char *ressource_name); - -+typedef void (*t_CSNBKTR2)(long *return_code, -+ long *reason_code, -+ long *exit_data_length, -+ unsigned char *exit_data, -+ long *rule_array_count, -+ unsigned char *rule_array, -+ long *input_key_token_length, -+ unsigned char *input_key_token, -+ long *input_KEK_key_identifier_length, -+ unsigned char *input_KEK_key_identifier, -+ long *output_KEK_key_identifier_length, -+ unsigned char *output_KEK_key_identifier, -+ long *output_key_token_length, -+ unsigned char *output_key_token); -+ - struct cca_version { - unsigned int ver; - unsigned int rel; -@@ -82,6 +97,7 @@ struct cca_lib { - t_CSUACFQ dll_CSUACFQ; - t_CSUACRA dll_CSUACRA; - t_CSUACRD dll_CSUACRD; -+ t_CSNBKTR2 dll_CSNBKTR2; - struct cca_version version; - }; - -@@ -102,4 +118,10 @@ int select_cca_adapter_by_mkvp(struct cc - - void print_msg_for_cca_envvars(const char *key_name); - -+int convert_aes_data_to_cipher_key(struct cca_lib *cca, -+ u8 *input_key, unsigned int input_key_size, -+ u8 *output_key, -+ unsigned int *output_key_size, -+ bool verbose); -+ - #endif diff --git a/s390-tools-sles15sp2-31-zipl-make-BLK_PWRT-unsigned-int.patch b/s390-tools-sles15sp2-31-zipl-make-BLK_PWRT-unsigned-int.patch deleted file mode 100644 index e90f038..0000000 --- a/s390-tools-sles15sp2-31-zipl-make-BLK_PWRT-unsigned-int.patch +++ /dev/null @@ -1,44 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] zipl: make BLK_PWRT unsigned int -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: 2e28291c75d73b92921f7769eaa803fe3222f383 -Problem-ID: VS1804 - -Upstream-Description: - - zipl: make BLK_PWRT unsigned int - - Otherwise there might be a compiler warning when using 'MIN(bl_count, - BLK_PWRT)'. - - Reviewed-by: Philipp Rudo - Reviewed-by: Stefan Haberland - Signed-off-by: Marc Hartmayer - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - zipl/boot/fba2dump.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/zipl/boot/fba2dump.c -+++ b/zipl/boot/fba2dump.c -@@ -14,7 +14,7 @@ - #include "fba.h" - #include "stage2dump.h" - --#define BLK_PWRT 64 /* Blocks per write */ -+#define BLK_PWRT 64U /* Blocks per write */ - #define BLK_SIZE 0x200 /* FBA block size */ - #define BLK_PER_PAGE (PAGE_SIZE / BLK_SIZE) /* FBA blocks per page */ - diff --git a/s390-tools-sles15sp2-31-zkey-Add-helper-function-to-restrict-export-of-secur.patch b/s390-tools-sles15sp2-31-zkey-Add-helper-function-to-restrict-export-of-secur.patch deleted file mode 100644 index a1742c8..0000000 --- a/s390-tools-sles15sp2-31-zkey-Add-helper-function-to-restrict-export-of-secur.patch +++ /dev/null @@ -1,182 +0,0 @@ -Subject: zkey: Add helper function to restrict export of secure keys -From: Ingo Franzki - -Summary: zkey: Add support for CCA AES CIPHER keys -Description: With CCA 5 there is a new secure key type, the so called - variable length symmetric cipher key token. This token format - can hold AES keys with size 128, 192 and 256 bits together - with additional attributes cryptographic bound to the key - token. The attributes may limit the usage of the key, for - example restrict export or usability scope. So this key type - is considered to be even more secure than the traditional - secure key token. This key token type is also called "CCA - AES CIPHER key", where the formerly used key token is called - "CCA AES DATA key". - The zkey as well as the zkey-cryptsetup tools are enhanced - to support AES CIPHER keys. That is, zkey can manage AES DATA - keys, as well as AES CIPHER keys. The key type must be specified - at key generation time, the default is to generate AED DATA - keys. -Upstream-ID: e7d79d5c5c0928c1bdbd6b669a6e70b8fd3352a5 -Problem-ID: SEC1717 - -Upstream-Description: - - zkey: Add helper function to restrict export of secure keys - - Secure keys of type CCA-AESCIPHER can be export restricted, so that - these keys can not be exported by another key. - - Signed-off-by: Ingo Franzki - Reviewed-by: Harald Freudenberger - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/cca.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- - zkey/cca.h | 19 +++++++++++++ - 2 files changed, 101 insertions(+), 1 deletion(-) - ---- a/zkey/cca.c -+++ b/zkey/cca.c -@@ -165,13 +165,17 @@ int load_cca_library(struct cca_lib *cca - /* Get the Key Translate 2 function */ - cca->dll_CSNBKTR2 = (t_CSNBKTR2)dlsym(cca->lib_csulcca, "CSNBKTR2"); - -+ /* Get the Restrict Key Attribute function */ -+ cca->dll_CSNBRKA = (t_CSNBRKA)dlsym(cca->lib_csulcca, "CSNBRKA"); -+ - if (cca->dll_CSUACFV == NULL || - cca->dll_CSNBKTC == NULL || - cca->dll_CSNBKTC2 == NULL || - cca->dll_CSUACFQ == NULL || - cca->dll_CSUACRA == NULL || - cca->dll_CSUACRD == NULL || -- cca->dll_CSNBKTR2 == NULL) { -+ cca->dll_CSNBKTR2 == NULL || -+ cca->dll_CSNBRKA == NULL) { - pr_verbose(verbose, "%s", dlerror()); - warnx("The command requires the IBM CCA Host Libraries and " - "Tools.\nFor the supported environments and downloads, " -@@ -898,3 +902,80 @@ int convert_aes_data_to_cipher_key(struc - return 0; - } - -+/* -+ * Restrict the exportability of an AES CIPHER key. It restricts export by means -+ * of NOEX-AES, NOEX-DES, NOEX-RSA, NOEX-SYM, NOEXUASY, NOEXAASY, NOEX-RAW -+ * keywords. -+ * When this function is called with an AES DATA key, it does nothing and -+ * returns 0. AES DATA keys can not be export restricted. -+ * -+ * @param[in] cca the CCA library structure -+ * @param[in] secure_key the secure key to restrict -+ * @param[in] secure_key_size the size of the secure key to restrict -+ * @param[in] verbose if true, verbose messages are printed -+ * -+ * @returns 0 on success, a negative errno in case of an error. -+ */ -+int restrict_key_export(struct cca_lib *cca, u8 *secure_key, -+ unsigned int secure_key_size, bool verbose) -+{ -+ struct aescipherkeytoken *cipherkey = -+ (struct aescipherkeytoken *)secure_key; -+ long exit_data_len = 0, rule_array_count = 0; -+ unsigned char rule_array[8 * 8] = { 0, }; -+ unsigned char exit_data[4] = { 0, }; -+ long return_code, reason_code; -+ long token_length, zero = 0; -+ -+ util_assert(cca != NULL, "Internal error: cca is NULL"); -+ util_assert(secure_key != NULL, "Internal error: secure_key is NULL"); -+ -+ if (!is_cca_aes_cipher_key(secure_key, secure_key_size)) -+ return 0; -+ -+ memcpy(rule_array, "AES ", 8); -+ memcpy(rule_array + 8, "NOEX-AES", 8); -+ memcpy(rule_array + 16, "NOEX-DES", 8); -+ memcpy(rule_array + 24, "NOEX-RSA", 8); -+ memcpy(rule_array + 32, "NOEX-SYM", 8); -+ memcpy(rule_array + 40, "NOEXUASY", 8); -+ memcpy(rule_array + 48, "NOEXAASY", 8); -+ memcpy(rule_array + 56, "NOEX-RAW", 8); -+ rule_array_count = 8; -+ -+ token_length = cipherkey->length; -+ cca->dll_CSNBRKA(&return_code, &reason_code, -+ &exit_data_len, exit_data, -+ &rule_array_count, rule_array, -+ &token_length, (unsigned char *)secure_key, -+ &zero, NULL, &zero, NULL, &zero, NULL); -+ -+ pr_verbose(verbose, "CSNBRKA (Restrict Key Attribute) " -+ "returned: return_code: %ld, reason_code: %ld", return_code, -+ reason_code); -+ if (return_code != 0) { -+ print_CCA_error(return_code, reason_code); -+ return -EIO; -+ } -+ -+ if (is_xts_key(secure_key, secure_key_size)) { -+ cipherkey = (struct aescipherkeytoken *)(secure_key + -+ AESCIPHER_KEY_SIZE); -+ token_length = cipherkey->length; -+ cca->dll_CSNBRKA(&return_code, &reason_code, -+ &exit_data_len, exit_data, -+ &rule_array_count, rule_array, -+ &token_length, (unsigned char *)cipherkey, -+ &zero, NULL, &zero, NULL, &zero, NULL); -+ -+ pr_verbose(verbose, "CSNBRKA (Restrict Key Attribute) " -+ "returned: return_code: %ld, reason_code: %ld", -+ return_code, reason_code); -+ if (return_code != 0) { -+ print_CCA_error(return_code, reason_code); -+ return -EIO; -+ } -+ } -+ -+ return 0; -+} ---- a/zkey/cca.h -+++ b/zkey/cca.h -@@ -83,6 +83,21 @@ typedef void (*t_CSNBKTR2)(long *return_ - long *output_key_token_length, - unsigned char *output_key_token); - -+typedef void (*t_CSNBRKA)(long *return_code, -+ long *reason_code, -+ long *exit_data_length, -+ unsigned char *exit_data, -+ long *rule_array_count, -+ unsigned char *rule_array, -+ long *key_identifier_length, -+ unsigned char *key_identifier, -+ long *ey_encrypting_key_identifier_length, -+ unsigned char *ey_encrypting_key_identifier, -+ long *opt_parameter1_length, -+ unsigned char *opt_parameter1, -+ long *opt_parameter2_length, -+ unsigned char *opt_parameter2); -+ - struct cca_version { - unsigned int ver; - unsigned int rel; -@@ -98,6 +113,7 @@ struct cca_lib { - t_CSUACRA dll_CSUACRA; - t_CSUACRD dll_CSUACRD; - t_CSNBKTR2 dll_CSNBKTR2; -+ t_CSNBRKA dll_CSNBRKA; - struct cca_version version; - }; - -@@ -124,4 +140,7 @@ int convert_aes_data_to_cipher_key(struc - unsigned int *output_key_size, - bool verbose); - -+int restrict_key_export(struct cca_lib *cca, u8 *secure_key, -+ unsigned int secure_key_size, bool verbose); -+ - #endif diff --git a/s390-tools-sles15sp2-32-Consolidate-MIN-and-MAX-macros.patch b/s390-tools-sles15sp2-32-Consolidate-MIN-and-MAX-macros.patch deleted file mode 100644 index ddab384..0000000 --- a/s390-tools-sles15sp2-32-Consolidate-MIN-and-MAX-macros.patch +++ /dev/null @@ -1,105 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] Consolidate MIN and MAX macros -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: c55ceabc6726a7806922d288149003661f673a2f -Problem-ID: VS1804 - -Upstream-Description: - - Consolidate MIN and MAX macros - - Consolidate MIN and MAX macros and make sure it can be used in - combination with glib. - - Reviewed-by: Philipp Rudo - Reviewed-by: Stefan Haberland - Acked-by: Jan Höppner - Signed-off-by: Marc Hartmayer - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - include/lib/util_base.h | 17 +---------------- - include/lib/zt_common.h | 17 +++++++++++++++++ - zipl/boot/s390.h | 1 - - 3 files changed, 18 insertions(+), 17 deletions(-) - ---- a/include/lib/util_base.h -+++ b/include/lib/util_base.h -@@ -14,6 +14,7 @@ - - #include - #include -+#include "zt_common.h" - - void util_hexdump(FILE *fh, const char *tag, const void *data, int cnt); - void util_hexdump_grp(FILE *fh, const char *tag, const void *data, int group, -@@ -22,22 +23,6 @@ void util_print_indented(const char *str - - #define UTIL_ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) - --#define MIN(x, y) \ --({ \ -- __typeof__(x) _x = (x); \ -- __typeof__(y) _y = (y); \ -- \ -- _x < _y ? _x : _y; \ --}) -- --#define MAX(x, y) \ --({ \ -- __typeof__(x) _x = (x); \ -- __typeof__(y) _y = (y); \ -- \ -- _x > _y ? _x : _y; \ --}) -- - static inline void util_ptr_vec_free(void **ptr_vec, int count) - { - int i; ---- a/include/lib/zt_common.h -+++ b/include/lib/zt_common.h -@@ -67,6 +67,23 @@ - - #define barrier() __asm__ __volatile__("": : :"memory") - -+#undef MIN -+#define MIN(x, y) \ -+ ({ \ -+ __typeof__(x) _x = (x); \ -+ __typeof__(y) _y = (y); \ -+ \ -+ _x < _y ? _x : _y; \ -+ }) -+ -+#undef MAX -+#define MAX(x, y) \ -+ ({ \ -+ __typeof__(x) _x = (x); \ -+ __typeof__(y) _y = (y); \ -+ \ -+ _x > _y ? _x : _y; \ -+ }) - - typedef unsigned long long u64; - typedef signed long long s64; ---- a/zipl/boot/s390.h -+++ b/zipl/boot/s390.h -@@ -15,7 +15,6 @@ - #include "libc.h" - #include "boot/sigp.h" - --#define MIN(x, y) ((x) < (y) ? (x) : (y)) - - /* - * Helper macro for exception table entries diff --git a/s390-tools-sles15sp2-32-zkey-Add-helper-function-to-check-an-AES-CIPHER-key.patch b/s390-tools-sles15sp2-32-zkey-Add-helper-function-to-check-an-AES-CIPHER-key.patch deleted file mode 100644 index 467ad07..0000000 --- a/s390-tools-sles15sp2-32-zkey-Add-helper-function-to-check-an-AES-CIPHER-key.patch +++ /dev/null @@ -1,192 +0,0 @@ -Subject: zkey: Add helper function to check an AES CIPHER key -From: Ingo Franzki - -Summary: zkey: Add support for CCA AES CIPHER keys -Description: With CCA 5 there is a new secure key type, the so called - variable length symmetric cipher key token. This token format - can hold AES keys with size 128, 192 and 256 bits together - with additional attributes cryptographic bound to the key - token. The attributes may limit the usage of the key, for - example restrict export or usability scope. So this key type - is considered to be even more secure than the traditional - secure key token. This key token type is also called "CCA - AES CIPHER key", where the formerly used key token is called - "CCA AES DATA key". - The zkey as well as the zkey-cryptsetup tools are enhanced - to support AES CIPHER keys. That is, zkey can manage AES DATA - keys, as well as AES CIPHER keys. The key type must be specified - at key generation time, the default is to generate AED DATA - keys. -Upstream-ID: 7fede7021ece58b9960532e17d963f844fe0de02 -Problem-ID: SEC1717 - -Upstream-Description: - - zkey: Add helper function to check an AES CIPHER key - - The helper function performs a deep check of the AES CIPHER key - token and checks for any potentially insecure attributes. - - Signed-off-by: Ingo Franzki - Reviewed-by: Harald Freudenberger - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/pkey.c | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - zkey/pkey.h | 1 - 2 files changed, 138 insertions(+) - ---- a/zkey/pkey.c -+++ b/zkey/pkey.c -@@ -1650,3 +1650,140 @@ int get_min_card_level_for_keytype(const - - return -1; - } -+ -+/** -+ * Performs extended checks on an AES CIPHER key. It checks the key usage -+ * fields (KUFs) and key management fields (KMFs) of the key. The function -+ * returns -EINVAL and issues warning messages if a mismatch is detected. -+ * -+ * @param[in] key the secure key token -+ * @param[in] key_size the size of the secure key -+ * -+ * @returns 0 on success, a negative errno in case of an error -+ */ -+int check_aes_cipher_key(const u8 *key, size_t key_size) -+{ -+ struct aescipherkeytoken *cipherkey = (struct aescipherkeytoken *)key; -+ bool mismatch = false; -+ -+ if (!is_cca_aes_cipher_key(key, key_size)) { -+ warnx("The key is not of type '"KEY_TYPE_CCA_AESCIPHER"'"); -+ return -EINVAL; -+ } -+ -+ if ((cipherkey->kuf1 & 0x8000) == 0) { -+ printf("WARNING: The secure key can not be used for " -+ "encryption\n"); -+ mismatch = true; -+ } -+ if ((cipherkey->kuf1 & 0x4000) == 0) { -+ printf("WARNING: The secure key can not be used for " -+ "decryption\n"); -+ mismatch = true; -+ } -+ if (cipherkey->kuf1 & 0x2000) { -+ printf("INFO: The secure key can be used for data translate\n"); -+ mismatch = true; -+ } -+ if (cipherkey->kuf1 & 0x1000) { -+ printf("WARNING: The secure key can only be used in UDXs\n"); -+ mismatch = true; -+ } -+ -+ if (cipherkey->kmf1 & 0x8000) { -+ printf("WARNING: The secure key can be exported using a " -+ "symmetric key\n"); -+ mismatch = true; -+ } -+ if (cipherkey->kmf1 & 0x4000) { -+ printf("WARNING: The secure key can be exported using an " -+ "unauthenticated asymmetric key\n"); -+ mismatch = true; -+ } -+ if (cipherkey->kmf1 & 0x2000) { -+ printf("WARNING: The secure key can be exported using an " -+ "authenticated asymmetric key\n"); -+ mismatch = true; -+ } -+ if (cipherkey->kmf1 & 0x1000) { -+ printf("WARNING: The secure key can be exported using a RAW " -+ "key\n"); -+ mismatch = true; -+ } -+ if ((cipherkey->kmf1 & 0x0800) == 0) { -+ printf("WARNING: The secure key can not be transformed into a " -+ "CPACF protected key\n"); -+ mismatch = true; -+ } -+ if ((cipherkey->kmf1 & 0x0080) == 0) { -+ printf("WARNING: The secure key can be exported using a DES " -+ "key\n"); -+ mismatch = true; -+ } -+ if ((cipherkey->kmf1 & 0x0040) == 0) { -+ printf("WARNING: The secure key can be exported using an AES " -+ "key\n"); -+ mismatch = true; -+ } -+ if ((cipherkey->kmf1 & 0x0008) == 0) { -+ printf("WARNING: The secure key can be exported using an RSA " -+ "key\n"); -+ mismatch = true; -+ } -+ -+ if (cipherkey->kmf2 & 0xC000) { -+ printf("WARNING: The secure key is incomplete\n"); -+ mismatch = true; -+ } -+ if (cipherkey->kmf2 & 0x0010) { -+ printf("WARNING: The secure key was previously encrypted with " -+ "an untrusted KEK\n"); -+ mismatch = true; -+ } -+ if (cipherkey->kmf2 & 0x0008) { -+ printf("WARNING: The secure key was previously in a format " -+ "without type or usage attributes\n"); -+ mismatch = true; -+ } -+ if (cipherkey->kmf2 & 0x0004) { -+ printf("WARNING: The secure key was previously encrypted with " -+ "a key weaker than itself\n"); -+ mismatch = true; -+ } -+ if (cipherkey->kmf2 & 0x0002) { -+ printf("WARNING: The secure key was previously in a non-CCA " -+ "format\n"); -+ mismatch = true; -+ } -+ if (cipherkey->kmf2 & 0x0001) { -+ printf("WARNING: The secure key was previously encrypted in " -+ "ECB mode\n"); -+ mismatch = true; -+ } -+ -+ if ((cipherkey->kmf3 & 0xFF00) == 0x0000 || -+ (cipherkey->kmf3 & 0x00FF) == 0x0000) { -+ printf("WARNING: The secure key was created by an unknown " -+ "method\n"); -+ mismatch = true; -+ } -+ if ((cipherkey->kmf3 & 0xFF00) == 0x0400 || -+ (cipherkey->kmf3 & 0x00FF) == 0x0004) { -+ printf("WARNING: The secure key was created from cleartext key " -+ "components\n"); -+ mismatch = true; -+ } -+ if ((cipherkey->kmf3 & 0xFF00) == 0x0500 || -+ (cipherkey->kmf3 & 0x00FF) == 0x0005) { -+ printf("WARNING: The secure key was entered as a cleartext key " -+ "value\n"); -+ mismatch = true; -+ } -+ if ((cipherkey->kmf3 & 0x00FF) == 0x0012) { -+ printf("WARNING: The secure key was converted from a CCA " -+ "key-token that had no export control attributes\n"); -+ mismatch = true; -+ } -+ -+ return mismatch ? -EINVAL : 0; -+} ---- a/zkey/pkey.h -+++ b/zkey/pkey.h -@@ -265,5 +265,6 @@ bool is_xts_key(const u8 *key, size_t ke - 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); - int get_min_card_level_for_keytype(const char *key_type); -+int check_aes_cipher_key(const u8 *key, size_t key_size); - - #endif diff --git a/s390-tools-sles15sp2-33-zipl-remove-libc.h-include-in-s390.h.patch b/s390-tools-sles15sp2-33-zipl-remove-libc.h-include-in-s390.h.patch deleted file mode 100644 index 1bc0ab3..0000000 --- a/s390-tools-sles15sp2-33-zipl-remove-libc.h-include-in-s390.h.patch +++ /dev/null @@ -1,76 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] zipl: remove libc.h include in s390.h -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: f454c6825f5087cf671d0dfbe96f7f3d148569d6 -Problem-ID: VS1804 - -Upstream-Description: - - zipl: remove libc.h include in s390.h - - This allows the use of s390.h in combination with other libc - implementations than our minimal libc, e.g. with glibc. - - Reviewed-by: Philipp Rudo - Reviewed-by: Stefan Haberland - Signed-off-by: Marc Hartmayer - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - zipl/boot/s390.h | 1 - - zipl/boot/sclp.c | 1 + - zipl/boot/sclp_stage3.c | 1 + - zipl/boot/stage2dump.c | 1 + - 4 files changed, 3 insertions(+), 1 deletion(-) - ---- a/zipl/boot/s390.h -+++ b/zipl/boot/s390.h -@@ -12,7 +12,6 @@ - #define S390_H - - #include "lib/zt_common.h" --#include "libc.h" - #include "boot/sigp.h" - - ---- a/zipl/boot/sclp.c -+++ b/zipl/boot/sclp.c -@@ -9,6 +9,7 @@ - * it under the terms of the MIT license. See LICENSE for details. - */ - -+#include "libc.h" - #include "error.h" - #include "s390.h" - #include "sclp.h" ---- a/zipl/boot/sclp_stage3.c -+++ b/zipl/boot/sclp_stage3.c -@@ -9,6 +9,7 @@ - * it under the terms of the MIT license. See LICENSE for details. - */ - -+#include "libc.h" - #include "sclp.h" - #include "sclp_stage3.h" - ---- a/zipl/boot/stage2dump.c -+++ b/zipl/boot/stage2dump.c -@@ -13,6 +13,7 @@ - - #include "lib/zt_common.h" - -+#include "libc.h" - #include "error.h" - #include "sclp.h" - #include "stage2dump.h" diff --git a/s390-tools-sles15sp2-33-zkey-Add-key-checks-when-importing-a-CCA-AESCIPHER-k.patch b/s390-tools-sles15sp2-33-zkey-Add-key-checks-when-importing-a-CCA-AESCIPHER-k.patch deleted file mode 100644 index 3e11e0a..0000000 --- a/s390-tools-sles15sp2-33-zkey-Add-key-checks-when-importing-a-CCA-AESCIPHER-k.patch +++ /dev/null @@ -1,225 +0,0 @@ -Subject: zkey: Add key checks when importing a CCA-AESCIPHER key -From: Ingo Franzki - -Summary: zkey: Add support for CCA AES CIPHER keys -Description: With CCA 5 there is a new secure key type, the so called - variable length symmetric cipher key token. This token format - can hold AES keys with size 128, 192 and 256 bits together - with additional attributes cryptographic bound to the key - token. The attributes may limit the usage of the key, for - example restrict export or usability scope. So this key type - is considered to be even more secure than the traditional - secure key token. This key token type is also called "CCA - AES CIPHER key", where the formerly used key token is called - "CCA AES DATA key". - The zkey as well as the zkey-cryptsetup tools are enhanced - to support AES CIPHER keys. That is, zkey can manage AES DATA - keys, as well as AES CIPHER keys. The key type must be specified - at key generation time, the default is to generate AED DATA - keys. -Upstream-ID: 0d9e42264db9935e28f663802c5b95795af79160 -Problem-ID: SEC1717 - -Upstream-Description: - - zkey: Add key checks when importing a CCA-AESCIPHER key - - Perform extended checks on a secure key that is imported into - the key repository. Warn the user if the imported key is by - any means insecure, e.g. has been originally created in an - insecure way. Prompt the user to continue the import if a - potential insecurity is detected. - - Signed-off-by: Ingo Franzki - Reviewed-by: Harald Freudenberger - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/keystore.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++---------- - zkey/keystore.h | 3 +- - zkey/utils.c | 24 ++++++++++++++++++++++ - zkey/utils.h | 2 + - zkey/zkey.1 | 6 +++++ - zkey/zkey.c | 2 - - 6 files changed, 85 insertions(+), 12 deletions(-) - ---- a/zkey/keystore.c -+++ b/zkey/keystore.c -@@ -1801,18 +1801,21 @@ out_free_key_filenames: - * default is used. - * @param[in] import_file The name of a secure key containing the key to import - * @param[in] volume_type the type of volume -+ * @param[in] cca the CCA library struct - * - * @returns 0 for success or a negative errno in case of an error - */ - int keystore_import_key(struct keystore *keystore, const char *name, - const char *description, const char *volumes, - const char *apqns, bool noapqncheck, size_t sector_size, -- const char *import_file, const char *volume_type) -+ const char *import_file, const char *volume_type, -+ struct cca_lib *cca) - { - struct key_filenames file_names = { NULL, NULL, NULL }; - struct properties *key_props = NULL; - size_t secure_key_size; - const char *key_type; -+ int selected = 1; - u8 *secure_key; - u64 mkvp; - int rc; -@@ -1862,6 +1865,51 @@ int keystore_import_key(struct keystore - goto out_free_key; - } - -+ if (is_cca_aes_cipher_key(secure_key, secure_key_size)) { -+ if (cca->lib_csulcca == NULL) { -+ rc = load_cca_library(cca, keystore->verbose); -+ if (rc != 0) -+ goto out_free_key; -+ } -+ -+ rc = select_cca_adapter_by_mkvp(cca, mkvp, apqns, -+ FLAG_SEL_CCA_MATCH_CUR_MKVP | -+ FLAG_SEL_CCA_MATCH_OLD_MKVP, -+ keystore->verbose); -+ if (rc == -ENOTSUP) { -+ rc = 0; -+ selected = 0; -+ } -+ if (rc != 0) { -+ warnx("No APQN found that is suitable for " -+ "working with the secure AES key '%s'", name); -+ rc = 0; -+ goto out_free_key; -+ } -+ -+ rc = restrict_key_export(cca, secure_key, secure_key_size, -+ keystore->verbose); -+ if (rc != 0) { -+ warnx("Failed to export-restrict the imported secure " -+ "key: %s", strerror(-rc)); -+ if (!selected) -+ print_msg_for_cca_envvars("secure AES key"); -+ goto out_free_key; -+ } -+ -+ rc = check_aes_cipher_key(secure_key, secure_key_size); -+ if (rc != 0) { -+ warnx("The secure key to import might not be secure"); -+ printf("%s: Do you want to import it anyway [y/N]? ", -+ program_invocation_short_name); -+ if (!prompt_for_yes(keystore->verbose)) { -+ warnx("Operation aborted"); -+ rc = -ECANCELED; -+ goto out_free_key; -+ } -+ } -+ } -+ - rc = write_secure_key(file_names.skey_filename, secure_key, - secure_key_size, keystore->verbose); - free(secure_key); -@@ -3180,7 +3228,6 @@ static int _keystore_prompt_for_remove(s - struct key_filenames *file_names) - { - struct properties *key_prop; -- char str[20]; - char *msg; - int rc; - -@@ -3198,14 +3245,7 @@ static int _keystore_prompt_for_remove(s - - printf("%s: Remove key '%s' [y/N]? ", program_invocation_short_name, - name); -- if (fgets(str, sizeof(str), stdin) == NULL) { -- rc = -EIO; -- goto out; -- } -- if (str[strlen(str) - 1] == '\n') -- str[strlen(str) - 1] = '\0'; -- pr_verbose(keystore, "Prompt reply: '%s'", str); -- if (strcasecmp(str, "y") != 0 && strcasecmp(str, "yes") != 0) { -+ if (!prompt_for_yes(keystore->verbose)) { - warnx("Operation aborted"); - rc = -ECANCELED; - goto out; ---- a/zkey/keystore.h -+++ b/zkey/keystore.h -@@ -37,7 +37,8 @@ int keystore_generate_key(struct keystor - int keystore_import_key(struct keystore *keystore, const char *name, - const char *description, const char *volumes, - const char *apqns, bool noapqncheck, size_t sector_size, -- const char *import_file, const char *volume_type); -+ const char *import_file, const char *volume_type, -+ struct cca_lib *cca); - - int keystore_change_key(struct keystore *keystore, const char *name, - const char *description, const char *volumes, ---- a/zkey/utils.c -+++ b/zkey/utils.c -@@ -793,3 +793,27 @@ int cross_check_apqns(const char *apqns, - - return rc; - } -+ -+/* -+ * Prompts for yes or no. Returns true if 'y' or 'yes' was entered. -+ * -+ * @param[in] verbose if true, verbose messages are printed -+ * -+ * @returns true if 'y' or 'yes' was entered (case insensitive). Returns false -+ * otherwise. -+ */ -+bool prompt_for_yes(bool verbose) -+{ -+ char str[20]; -+ -+ if (fgets(str, sizeof(str), stdin) == NULL) -+ return false; -+ -+ if (str[strlen(str) - 1] == '\n') -+ str[strlen(str) - 1] = '\0'; -+ pr_verbose(verbose, "Prompt reply: '%s'", str); -+ if (strcasecmp(str, "y") == 0 || strcasecmp(str, "yes") == 0) -+ return true; -+ -+ return false; -+} ---- a/zkey/utils.h -+++ b/zkey/utils.h -@@ -53,4 +53,6 @@ int print_mk_info(const char *apqns, boo - int cross_check_apqns(const char *apqns, u64 mkvp, int min_level, - bool print_mks, bool verbose); - -+bool prompt_for_yes(bool verbose); -+ - #endif ---- a/zkey/zkey.1 -+++ b/zkey/zkey.1 -@@ -349,6 +349,12 @@ additional information can be associated - , or the - .B \-\-sector-size - options. -+.PP -+.B Note: -+The \fBimport\fP command requires the CCA host library (libcsulcca.so) -+to be installed when secure keys of type \fBCCA-AESCIPHER\fP are imported. -+For the supported environments and downloads, see: -+\fIhttp://www.ibm.com/security/cryptocards\fP - . - .SS "Export AES secure keys from the secure key repository" - . ---- a/zkey/zkey.c -+++ b/zkey/zkey.c -@@ -1522,7 +1522,7 @@ static int command_import(void) - - rc = keystore_import_key(g.keystore, g.name, g.description, g.volumes, - g.apqns, g.noapqncheck, g.sector_size, -- g.pos_arg, g.volume_type); -+ g.pos_arg, g.volume_type, &g.cca); - - return rc != 0 ? EXIT_FAILURE : EXIT_SUCCESS; - } diff --git a/s390-tools-sles15sp2-34-zipl-move-s390.h-to-include-boot-s390.h.patch b/s390-tools-sles15sp2-34-zipl-move-s390.h-to-include-boot-s390.h.patch deleted file mode 100644 index 12c7097..0000000 --- a/s390-tools-sles15sp2-34-zipl-move-s390.h-to-include-boot-s390.h.patch +++ /dev/null @@ -1,1129 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] zipl: move s390.h to include/boot/s390.h -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: b83c8944f195117609a36f383f32377014e34c31 -Problem-ID: VS1804 - -Upstream-Description: - - zipl: move s390.h to include/boot/s390.h - - Now that we made sure that s390.h can be used with our minimal libc - implementation and glibc move s390.h to `include/boot/s390.h`. While - at it, make sure that s390.h is assembler compatible as it will be - used later in the PV boot loader and include s390.h in ipl.h as - PAGE_SIZE is used there. - - Reviewed-by: Philipp Rudo - Reviewed-by: Stefan Haberland - Signed-off-by: Marc Hartmayer - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - include/boot/ipl.h | 1 - include/boot/s390.h | 452 +++++++++++++++++++++++++++++++++++++++++++++++++ - zipl/boot/cio.c | 2 - zipl/boot/cio.h | 2 - zipl/boot/eckd2.c | 2 - zipl/boot/eckd2dump.c | 2 - zipl/boot/fba2.c | 2 - zipl/boot/kdump.c | 2 - zipl/boot/kdump.h | 2 - zipl/boot/s390.h | 449 ------------------------------------------------ - zipl/boot/sclp.c | 2 - zipl/boot/sclp.h | 2 - zipl/boot/stage2.c | 2 - zipl/boot/stage2.h | 3 - zipl/boot/stage2dump.h | 2 - zipl/boot/stage3.c | 2 - zipl/boot/stage3.h | 2 - 17 files changed, 467 insertions(+), 464 deletions(-) - ---- a/include/boot/ipl.h -+++ b/include/boot/ipl.h -@@ -11,6 +11,7 @@ - #define IPL_H - - #include "lib/zt_common.h" -+#include "s390.h" - - #define IPL_FLAG_SECURE 0x40 - ---- /dev/null -+++ b/include/boot/s390.h -@@ -0,0 +1,452 @@ -+/* -+ * s390 related definitions and functions. -+ * -+ * Copyright IBM Corp. 2013, 2020 -+ * -+ * s390-tools is free software; you can redistribute it and/or modify -+ * it under the terms of the MIT license. See LICENSE for details. -+ */ -+ -+#ifndef S390_H -+#define S390_H -+ -+#include "lib/zt_common.h" -+#include "boot/sigp.h" -+ -+#define __LC_IPLDEV 0x0c6c -+#define __LC_OS_INFO 0x0e18 -+ -+#define PAGE_SIZE _AC(4096, UL) -+ -+ -+#ifndef __ASSEMBLER__ -+ -+/* -+ * Helper macro for exception table entries -+ */ -+#define EX_TABLE(_fault, _target) \ -+ ".section .ex_table,\"a\"\n" \ -+ ".align 4\n" \ -+ ".long (" #_fault ")\n" \ -+ ".long (" #_target ")\n" \ -+ ".previous\n" -+ -+struct psw_t { -+ uint64_t mask; -+ uint64_t addr; -+} __aligned(8); -+ -+struct psw32_t { -+ uint32_t mask; -+ uint32_t addr; -+} __aligned(8); -+ -+void load_wait_psw(uint64_t, struct psw_t *); -+ -+struct _lowcore { -+ uint8_t pad_0x0000[0x0014-0x0000]; /* 0x0000 */ -+ uint32_t ipl_parmblock_ptr; /* 0x0014 */ -+ uint8_t pad_0x0018[0x0080-0x0018]; /* 0x0018 */ -+ uint32_t ext_params; /* 0x0080 */ -+ uint16_t ext_cpu_addr; /* 0x0084 */ -+ uint16_t ext_int_code; /* 0x0086 */ -+ uint16_t svc_ilc; /* 0x0088 */ -+ uint16_t svc_code; /* 0x008a */ -+ uint16_t pgm_ilc; /* 0x008c */ -+ uint16_t pgm_code; /* 0x008e */ -+ uint32_t data_exc_code; /* 0x0090 */ -+ uint16_t mon_class_num; /* 0x0094 */ -+ uint16_t per_perc_atmid; /* 0x0096 */ -+ uint64_t per_address; /* 0x0098 */ -+ uint8_t exc_access_id; /* 0x00a0 */ -+ uint8_t per_access_id; /* 0x00a1 */ -+ uint8_t op_access_id; /* 0x00a2 */ -+ uint8_t ar_access_id; /* 0x00a3 */ -+ uint8_t pad_0x00a4[0x00a8-0x00a4]; /* 0x00a4 */ -+ uint64_t trans_exc_code; /* 0x00a8 */ -+ uint64_t monitor_code; /* 0x00b0 */ -+ uint16_t subchannel_id; /* 0x00b8 */ -+ uint16_t subchannel_nr; /* 0x00ba */ -+ uint32_t io_int_parm; /* 0x00bc */ -+ uint32_t io_int_word; /* 0x00c0 */ -+ uint8_t pad_0x00c4[0x00c8-0x00c4]; /* 0x00c4 */ -+ uint32_t stfl_fac_list; /* 0x00c8 */ -+ uint8_t pad_0x00cc[0x00e8-0x00cc]; /* 0x00cc */ -+ uint32_t mcck_interruption_code[2]; /* 0x00e8 */ -+ uint8_t pad_0x00f0[0x00f4-0x00f0]; /* 0x00f0 */ -+ uint32_t external_damage_code; /* 0x00f4 */ -+ uint64_t failing_storage_address; /* 0x00f8 */ -+ uint8_t pad_0x0100[0x0110-0x0100]; /* 0x0100 */ -+ uint64_t breaking_event_addr; /* 0x0110 */ -+ uint8_t pad_0x0118[0x0120-0x0118]; /* 0x0118 */ -+ struct psw_t restart_old_psw; /* 0x0120 */ -+ struct psw_t external_old_psw; /* 0x0130 */ -+ struct psw_t svc_old_psw; /* 0x0140 */ -+ struct psw_t program_old_psw; /* 0x0150 */ -+ struct psw_t mcck_old_psw; /* 0x0160 */ -+ struct psw_t io_old_psw; /* 0x0170 */ -+ uint8_t pad_0x0180[0x01a0-0x0180]; /* 0x0180 */ -+ struct psw_t restart_psw; /* 0x01a0 */ -+ struct psw_t external_new_psw; /* 0x01b0 */ -+ struct psw_t svc_new_psw; /* 0x01c0 */ -+ struct psw_t program_new_psw; /* 0x01d0 */ -+ struct psw_t mcck_new_psw; /* 0x01e0 */ -+ struct psw_t io_new_psw; /* 0x01f0 */ -+ -+ /* Save areas. */ -+ uint64_t save_area_sync[8]; /* 0x0200 */ -+ uint64_t save_area_async[8]; /* 0x0240 */ -+ uint64_t save_area_restart[1]; /* 0x0280 */ -+ uint8_t pad_0x0288[0x0290-0x0288]; /* 0x0288 */ -+ -+ /* Return psws. */ -+ struct psw_t return_psw; /* 0x0290 */ -+ struct psw_t return_mcck_psw; /* 0x02a0 */ -+ -+ /* CPU accounting and timing values. */ -+ uint64_t sync_enter_timer; /* 0x02b0 */ -+ uint64_t async_enter_timer; /* 0x02b8 */ -+ uint64_t mcck_enter_timer; /* 0x02c0 */ -+ uint64_t exit_timer; /* 0x02c8 */ -+ uint64_t user_timer; /* 0x02d0 */ -+ uint64_t system_timer; /* 0x02d8 */ -+ uint64_t steal_timer; /* 0x02e0 */ -+ uint64_t last_update_timer; /* 0x02e8 */ -+ uint64_t last_update_clock; /* 0x02f0 */ -+ uint64_t int_clock; /* 0x02f8 */ -+ uint64_t mcck_clock; /* 0x0300 */ -+ uint64_t clock_comparator; /* 0x0308 */ -+ -+ /* Current process. */ -+ uint64_t current_task; /* 0x0310 */ -+ uint64_t thread_info; /* 0x0318 */ -+ uint64_t kernel_stack; /* 0x0320 */ -+ -+ /* Interrupt, panic and restart stack. */ -+ uint64_t async_stack; /* 0x0328 */ -+ uint64_t panic_stack; /* 0x0330 */ -+ uint64_t restart_stack; /* 0x0338 */ -+ -+ /* Restart function and parameter. */ -+ uint64_t restart_fn; /* 0x0340 */ -+ uint64_t restart_data; /* 0x0348 */ -+ uint64_t restart_source; /* 0x0350 */ -+ -+ /* Address space pointer. */ -+ uint64_t kernel_asce; /* 0x0358 */ -+ uint64_t user_asce; /* 0x0360 */ -+ uint64_t current_pid; /* 0x0368 */ -+ -+ /* SMP info area */ -+ uint32_t cpu_nr; /* 0x0370 */ -+ uint32_t softirq_pending; /* 0x0374 */ -+ uint64_t percpu_offset; /* 0x0378 */ -+ uint64_t vdso_per_cpu_data; /* 0x0380 */ -+ uint64_t machine_flags; /* 0x0388 */ -+ uint64_t ftrace_func; /* 0x0390 */ -+ uint64_t gmap; /* 0x0398 */ -+ uint8_t pad_0x03a0[0x0400-0x03a0]; /* 0x03a0 */ -+ -+ /* Interrupt response block. */ -+ uint8_t irb[64]; /* 0x0400 */ -+ -+ /* Per cpu primary space access list */ -+ uint32_t paste[16]; /* 0x0440 */ -+ -+ uint8_t pad_0x0480[0x0e00-0x0480]; /* 0x0480 */ -+ -+ /* -+ * 0xe00 contains the address of the IPL Parameter Information -+ * block. Dump tools need IPIB for IPL after dump. -+ * Note: do not change the position of any fields in 0x0e00-0x0f00 -+ */ -+ uint64_t ipib; /* 0x0e00 */ -+ uint32_t ipib_checksum; /* 0x0e08 */ -+ uint64_t vmcore_info; /* 0x0e0c */ -+ uint8_t pad_0x0e14[0x0e18-0x0e14]; /* 0x0e14 */ -+ uint64_t os_info; /* 0x0e18 */ -+ uint8_t pad_0x0e20[0x0f00-0x0e20]; /* 0x0e20 */ -+ -+ /* Extended facility list */ -+ uint64_t stfle_fac_list[32]; /* 0x0f00 */ -+ uint8_t pad_0x1000[0x11b0-0x1000]; /* 0x1000 */ -+ uint64_t vector_save_area_addr; /* 0x11b0 */ -+ /* 64 bit extparam used for pfault/diag 250: defined by architecture */ -+ uint64_t ext_params2; /* 0x11B8 */ -+ uint8_t pad_0x11c0[0x1200-0x11C0]; /* 0x11C0 */ -+ -+ /* CPU register save area: defined by architecture */ -+ uint64_t floating_pt_save_area[16]; /* 0x1200 */ -+ uint64_t gpregs_save_area[16]; /* 0x1280 */ -+ struct psw_t psw_save_area; /* 0x1300 */ -+ uint8_t pad_0x1310[0x1318-0x1310]; /* 0x1310 */ -+ uint32_t prefixreg_save_area; /* 0x1318 */ -+ uint32_t fpt_creg_save_area; /* 0x131c */ -+ uint8_t pad_0x1320[0x1324-0x1320]; /* 0x1320 */ -+ uint32_t tod_progreg_save_area; /* 0x1324 */ -+ uint32_t cpu_timer_save_area[2]; /* 0x1328 */ -+ uint32_t clock_comp_save_area[2]; /* 0x1330 */ -+ uint8_t pad_0x1338[0x1340-0x1338]; /* 0x1338 */ -+ uint32_t access_regs_save_area[16]; /* 0x1340 */ -+ uint64_t cregs_save_area[16]; /* 0x1380 */ -+ uint8_t pad_0x1400[0x1800-0x1400]; /* 0x1400 */ -+ -+ /* Transaction abort diagnostic block */ -+ uint8_t pgm_tdb[256]; /* 0x1800 */ -+ -+ /* align to the top of the prefix area */ -+ uint8_t pad_0x1900[0x2000-0x1900]; /* 0x1900 */ -+} __packed __aligned(8192); -+ -+#define S390_lowcore (*((struct _lowcore *) 0)) -+ -+ -+void panic_notify(unsigned long reason); -+ -+#define panic(reason, x...) \ -+do { \ -+ printf(x); \ -+ panic_notify(reason); \ -+ libc_stop(reason); \ -+} while (0) -+ -+static __always_inline int page_is_valid(unsigned long addr) -+{ -+ unsigned long tmp; -+ int rc; -+ -+ asm volatile( -+ "0: ic %1,%2\n" -+ "1: lhi %0,1\n" -+ "2:\n" -+ ".pushsection .fixup, \"ax\"\n" -+ "3: xr %0,%0\n" -+ " jg 2b\n" -+ ".popsection\n" -+ EX_TABLE(0b, 3b) EX_TABLE(1b, 3b) -+ : "=d" (rc), "=d" (tmp) -+ : "Q" (*(unsigned long *) addr) -+ : "cc"); -+ return rc; -+} -+ -+static __always_inline uint32_t csum_partial(const void *buf, int len, uint32_t sum) -+{ -+ register unsigned long reg2 asm("2") = (unsigned long) buf; -+ register unsigned long reg3 asm("3") = (unsigned long) len; -+ -+ asm volatile( -+ "0: cksm %0,%1\n" /* do checksum on longs */ -+ " jo 0b\n" -+ : "+d" (sum), "+d" (reg2), "+d" (reg3) : : "cc", "memory"); -+ return sum; -+} -+ -+#define __ctl_store(array, low, high) ({ \ -+ typedef struct { char _[sizeof(array)]; } __may_alias addrtype;\ -+ asm volatile( \ -+ " stctg %1,%2,%0\n" \ -+ : "=Q" (*(addrtype *)(&array)) \ -+ : "i" (low), "i" (high)); \ -+}) -+ -+#define __ctl_load(array, low, high) ({ \ -+ typedef struct { char _[sizeof(array)]; } __may_alias addrtype; \ -+ asm volatile( \ -+ " lctlg %1,%2,%0\n" \ -+ : : "Q" (*(addrtype *)(&array)), \ -+ "i" (low), "i" (high)); \ -+}) -+ -+static __always_inline void __ctl_set_bit(unsigned int cr, unsigned int bit) -+{ -+ unsigned long reg; -+ -+ __ctl_store(reg, cr, cr); -+ reg |= 1UL << bit; -+ __ctl_load(reg, cr, cr); -+} -+ -+/* -+ * DIAG 308 support -+ */ -+enum diag308_subcode { -+ DIAG308_REL_HSA = 2, -+ DIAG308_IPL = 3, -+ DIAG308_DUMP = 4, -+ DIAG308_SET = 5, -+ DIAG308_STORE = 6, -+}; -+ -+static __always_inline int diag308(unsigned long subcode, void *addr) -+{ -+ register unsigned long _addr asm("0") = (unsigned long) addr; -+ register unsigned long _rc asm("1") = 0; -+ -+ asm volatile( -+ " diag %0,%2,0x308\n" -+ "0:\n" -+ : "+d" (_addr), "+d" (_rc) -+ : "d" (subcode) : "cc", "memory"); -+ return _rc; -+} -+ -+/* -+ * Store CPU address -+ */ -+static __always_inline unsigned short stap(void) -+{ -+ unsigned short cpu_address; -+ -+ asm volatile("stap %0" : "=m" (cpu_address)); -+ return cpu_address; -+} -+ -+/* -+ * Program the clock comparator -+ */ -+static __always_inline void set_clock_comparator(uint64_t time) -+{ -+ asm volatile("sckc %0" : : "Q" (time)); -+} -+ -+/* -+ * Program the CPU timer -+ */ -+static __always_inline void set_cpu_timer(uint64_t timer) -+{ -+ asm volatile("spt %0" : : "Q" (timer)); -+} -+ -+/* -+ * Get current time (store clock) -+ */ -+static __always_inline unsigned long long get_tod_clock(void) -+{ -+ unsigned long long clk; -+ -+ asm volatile("stck %0" : "=Q" (clk) : : "cc"); -+ return clk; -+} -+ -+/* -+ * Get ID of current CPU -+ */ -+struct cpuid { -+ unsigned int version:8; -+ unsigned int ident:24; -+ unsigned int machine:16; -+ unsigned int unused:16; -+} __packed __aligned(8); -+ -+static __always_inline void get_cpu_id(struct cpuid *ptr) -+{ -+ asm volatile("stidp %0" : "=Q" (*ptr)); -+} -+ -+/* -+ * Check if we run under z/VM -+ */ -+static __always_inline int is_zvm(void) -+{ -+ struct cpuid cpuid; -+ -+ get_cpu_id(&cpuid); -+ return cpuid.version == 0xff; -+} -+ -+/* -+ * Vector register definition -+ */ -+typedef struct { -+ uint32_t u[4]; -+} __vector128; -+ -+/* -+ * Save vector registers -+ */ -+static __always_inline void save_vx_regs(__vector128 *vxrs) -+{ -+ typedef struct { __vector128 _[32]; } addrtype; -+ -+ asm volatile( -+ " la 1,%0\n" -+ " .word 0xe70f,0x1000,0x003e\n" /* vstm 0,15,0(1) */ -+ " .word 0xe70f,0x1100,0x0c3e\n" /* vstm 16,31,256(1) */ -+ : "=Q" (*(addrtype *) vxrs) : : "1"); -+} -+ -+/* -+ * Save vector registers safe -+ */ -+static __always_inline void save_vx_regs_safe(__vector128 *vxrs) -+{ -+ unsigned long cr0; -+ -+ __ctl_store(cr0, 0, 0); -+ __ctl_set_bit(0, 17); -+ __ctl_set_bit(0, 18); /* AFP-register-control */ -+ save_vx_regs(vxrs); -+ __ctl_load(cr0, 0, 0); -+} -+ -+#define MAX_FACILITY_BIT (256*8) /* stfle_fac_list has 256 bytes */ -+ -+static __always_inline int __test_facility(unsigned long nr, void *facilities) -+{ -+ unsigned char *ptr; -+ -+ if (nr >= MAX_FACILITY_BIT) -+ return 0; -+ ptr = (unsigned char *) facilities + (nr >> 3); -+ return (*ptr & (0x80 >> (nr & 7))) != 0; -+} -+ -+/* -+ * The test_facility function uses the bit odering where the MSB is bit 0. -+ * That makes it easier to query facility bits with the bit number as -+ * documented in the Principles of Operation. -+ */ -+static __always_inline int test_facility(unsigned long nr) -+{ -+ return __test_facility(nr, &S390_lowcore.stfle_fac_list); -+} -+ -+static __always_inline unsigned long __stfle_asm(uint64_t *stfle_fac_list, int size) -+{ -+ register unsigned long reg0 asm("0") = size - 1; -+ -+ asm volatile( -+ ".insn s,0xb2b00000,0(%1)" /* stfle */ -+ : "+d" (reg0) -+ : "a" (stfle_fac_list) -+ : "memory", "cc"); -+ return reg0; -+} -+ -+/** -+ * stfle - Store facility list extended -+ * @stfle_fac_list: array where facility list can be stored -+ * @size: size of passed in array in double words -+ */ -+static __always_inline void stfle(uint64_t *stfle_fac_list, int size) -+{ -+ unsigned long nr; -+ -+ asm volatile( -+ " .insn s,0xb2b10000,0(0)\n" /* stfl */ -+ "0:\n" -+ EX_TABLE(0b, 0b) -+ : "+m" (S390_lowcore.stfl_fac_list)); -+ nr = 4; /* bytes stored by stfl */ -+ memcpy(stfle_fac_list, &S390_lowcore.stfl_fac_list, 4); -+ if (S390_lowcore.stfl_fac_list & 0x01000000) { -+ /* More facility bits available with stfle */ -+ nr = __stfle_asm(stfle_fac_list, size); -+ nr = MIN((nr + 1) * 8, size * 8UL); -+ } -+ memset((char *) stfle_fac_list + nr, 0, size * 8 - nr); -+} -+ -+#endif /* __ASSEMBLER__ */ -+#endif /* S390_H */ ---- a/zipl/boot/cio.c -+++ b/zipl/boot/cio.c -@@ -12,7 +12,7 @@ - #include "cio.h" - #include "error.h" - #include "libc.h" --#include "s390.h" -+#include "boot/s390.h" - - static unsigned long initial_lpm = 0x00; - static const char *msg_essch = "Start subchannel failed"; ---- a/zipl/boot/cio.h -+++ b/zipl/boot/cio.h -@@ -12,7 +12,7 @@ - #define CIO_H - - #include "libc.h" --#include "s390.h" -+#include "boot/s390.h" - - /* Condition codes */ - #define CC_INITIATED 0 ---- a/zipl/boot/eckd2.c -+++ b/zipl/boot/eckd2.c -@@ -10,7 +10,7 @@ - */ - - #include "eckd.h" --#include "s390.h" -+#include "boot/s390.h" - #include "stage2.h" - - int extract_length(void *data) ---- a/zipl/boot/eckd2dump.c -+++ b/zipl/boot/eckd2dump.c -@@ -12,7 +12,7 @@ - #include "cio.h" - #include "eckd2dump.h" - #include "error.h" --#include "s390.h" -+#include "boot/s390.h" - #include "stage2dump.h" - - #define ECKD_CCW_LOCATE_RECORD 0x47 ---- a/zipl/boot/fba2.c -+++ b/zipl/boot/fba2.c -@@ -11,7 +11,7 @@ - - #include "fba.h" - #include "libc.h" --#include "s390.h" -+#include "boot/s390.h" - - int extract_length(void *data) { - struct linear_blockptr *blockptr = (struct linear_blockptr *)data; ---- a/zipl/boot/kdump.c -+++ b/zipl/boot/kdump.c -@@ -13,7 +13,7 @@ - #include "kdump.h" - #include "libc.h" - #include "menu.h" --#include "s390.h" -+#include "boot/s390.h" - - void kdump_failed(unsigned long reason) - { ---- a/zipl/boot/kdump.h -+++ b/zipl/boot/kdump.h -@@ -14,7 +14,7 @@ - #define KDUMP_H - - #include "libc.h" --#include "s390.h" -+#include "boot/s390.h" - - #define OS_INFO_VERSION_MAJOR_SUPPORTED 1 - #define OS_INFO_MAGIC 0x4f53494e464f535aULL /* OSINFOSZ */ ---- a/zipl/boot/s390.h -+++ /dev/null -@@ -1,449 +0,0 @@ --/* -- * zipl - zSeries Initial Program Loader tool -- * -- * System z specific functions -- * -- * Copyright IBM Corp. 2013, 2017 -- * -- * s390-tools is free software; you can redistribute it and/or modify -- * it under the terms of the MIT license. See LICENSE for details. -- */ --#ifndef S390_H --#define S390_H -- --#include "lib/zt_common.h" --#include "boot/sigp.h" -- -- --/* -- * Helper macro for exception table entries -- */ --#define EX_TABLE(_fault, _target) \ -- ".section .ex_table,\"a\"\n" \ -- ".align 4\n" \ -- ".long (" #_fault ")\n" \ -- ".long (" #_target ")\n" \ -- ".previous\n" -- --struct psw_t { -- uint64_t mask; -- uint64_t addr; --} __aligned(8); -- --struct psw32_t { -- uint32_t mask; -- uint32_t addr; --} __aligned(8); -- --void load_wait_psw(uint64_t, struct psw_t *); -- --struct _lowcore { -- uint8_t pad_0x0000[0x0014-0x0000]; /* 0x0000 */ -- uint32_t ipl_parmblock_ptr; /* 0x0014 */ -- uint8_t pad_0x0018[0x0080-0x0018]; /* 0x0018 */ -- uint32_t ext_params; /* 0x0080 */ -- uint16_t ext_cpu_addr; /* 0x0084 */ -- uint16_t ext_int_code; /* 0x0086 */ -- uint16_t svc_ilc; /* 0x0088 */ -- uint16_t svc_code; /* 0x008a */ -- uint16_t pgm_ilc; /* 0x008c */ -- uint16_t pgm_code; /* 0x008e */ -- uint32_t data_exc_code; /* 0x0090 */ -- uint16_t mon_class_num; /* 0x0094 */ -- uint16_t per_perc_atmid; /* 0x0096 */ -- uint64_t per_address; /* 0x0098 */ -- uint8_t exc_access_id; /* 0x00a0 */ -- uint8_t per_access_id; /* 0x00a1 */ -- uint8_t op_access_id; /* 0x00a2 */ -- uint8_t ar_access_id; /* 0x00a3 */ -- uint8_t pad_0x00a4[0x00a8-0x00a4]; /* 0x00a4 */ -- uint64_t trans_exc_code; /* 0x00a8 */ -- uint64_t monitor_code; /* 0x00b0 */ -- uint16_t subchannel_id; /* 0x00b8 */ -- uint16_t subchannel_nr; /* 0x00ba */ -- uint32_t io_int_parm; /* 0x00bc */ -- uint32_t io_int_word; /* 0x00c0 */ -- uint8_t pad_0x00c4[0x00c8-0x00c4]; /* 0x00c4 */ -- uint32_t stfl_fac_list; /* 0x00c8 */ -- uint8_t pad_0x00cc[0x00e8-0x00cc]; /* 0x00cc */ -- uint32_t mcck_interruption_code[2]; /* 0x00e8 */ -- uint8_t pad_0x00f0[0x00f4-0x00f0]; /* 0x00f0 */ -- uint32_t external_damage_code; /* 0x00f4 */ -- uint64_t failing_storage_address; /* 0x00f8 */ -- uint8_t pad_0x0100[0x0110-0x0100]; /* 0x0100 */ -- uint64_t breaking_event_addr; /* 0x0110 */ -- uint8_t pad_0x0118[0x0120-0x0118]; /* 0x0118 */ -- struct psw_t restart_old_psw; /* 0x0120 */ -- struct psw_t external_old_psw; /* 0x0130 */ -- struct psw_t svc_old_psw; /* 0x0140 */ -- struct psw_t program_old_psw; /* 0x0150 */ -- struct psw_t mcck_old_psw; /* 0x0160 */ -- struct psw_t io_old_psw; /* 0x0170 */ -- uint8_t pad_0x0180[0x01a0-0x0180]; /* 0x0180 */ -- struct psw_t restart_psw; /* 0x01a0 */ -- struct psw_t external_new_psw; /* 0x01b0 */ -- struct psw_t svc_new_psw; /* 0x01c0 */ -- struct psw_t program_new_psw; /* 0x01d0 */ -- struct psw_t mcck_new_psw; /* 0x01e0 */ -- struct psw_t io_new_psw; /* 0x01f0 */ -- -- /* Save areas. */ -- uint64_t save_area_sync[8]; /* 0x0200 */ -- uint64_t save_area_async[8]; /* 0x0240 */ -- uint64_t save_area_restart[1]; /* 0x0280 */ -- uint8_t pad_0x0288[0x0290-0x0288]; /* 0x0288 */ -- -- /* Return psws. */ -- struct psw_t return_psw; /* 0x0290 */ -- struct psw_t return_mcck_psw; /* 0x02a0 */ -- -- /* CPU accounting and timing values. */ -- uint64_t sync_enter_timer; /* 0x02b0 */ -- uint64_t async_enter_timer; /* 0x02b8 */ -- uint64_t mcck_enter_timer; /* 0x02c0 */ -- uint64_t exit_timer; /* 0x02c8 */ -- uint64_t user_timer; /* 0x02d0 */ -- uint64_t system_timer; /* 0x02d8 */ -- uint64_t steal_timer; /* 0x02e0 */ -- uint64_t last_update_timer; /* 0x02e8 */ -- uint64_t last_update_clock; /* 0x02f0 */ -- uint64_t int_clock; /* 0x02f8 */ -- uint64_t mcck_clock; /* 0x0300 */ -- uint64_t clock_comparator; /* 0x0308 */ -- -- /* Current process. */ -- uint64_t current_task; /* 0x0310 */ -- uint64_t thread_info; /* 0x0318 */ -- uint64_t kernel_stack; /* 0x0320 */ -- -- /* Interrupt, panic and restart stack. */ -- uint64_t async_stack; /* 0x0328 */ -- uint64_t panic_stack; /* 0x0330 */ -- uint64_t restart_stack; /* 0x0338 */ -- -- /* Restart function and parameter. */ -- uint64_t restart_fn; /* 0x0340 */ -- uint64_t restart_data; /* 0x0348 */ -- uint64_t restart_source; /* 0x0350 */ -- -- /* Address space pointer. */ -- uint64_t kernel_asce; /* 0x0358 */ -- uint64_t user_asce; /* 0x0360 */ -- uint64_t current_pid; /* 0x0368 */ -- -- /* SMP info area */ -- uint32_t cpu_nr; /* 0x0370 */ -- uint32_t softirq_pending; /* 0x0374 */ -- uint64_t percpu_offset; /* 0x0378 */ -- uint64_t vdso_per_cpu_data; /* 0x0380 */ -- uint64_t machine_flags; /* 0x0388 */ -- uint64_t ftrace_func; /* 0x0390 */ -- uint64_t gmap; /* 0x0398 */ -- uint8_t pad_0x03a0[0x0400-0x03a0]; /* 0x03a0 */ -- -- /* Interrupt response block. */ -- uint8_t irb[64]; /* 0x0400 */ -- -- /* Per cpu primary space access list */ -- uint32_t paste[16]; /* 0x0440 */ -- -- uint8_t pad_0x0480[0x0e00-0x0480]; /* 0x0480 */ -- -- /* -- * 0xe00 contains the address of the IPL Parameter Information -- * block. Dump tools need IPIB for IPL after dump. -- * Note: do not change the position of any fields in 0x0e00-0x0f00 -- */ -- uint64_t ipib; /* 0x0e00 */ -- uint32_t ipib_checksum; /* 0x0e08 */ -- uint64_t vmcore_info; /* 0x0e0c */ -- uint8_t pad_0x0e14[0x0e18-0x0e14]; /* 0x0e14 */ -- uint64_t os_info; /* 0x0e18 */ -- uint8_t pad_0x0e20[0x0f00-0x0e20]; /* 0x0e20 */ -- -- /* Extended facility list */ -- uint64_t stfle_fac_list[32]; /* 0x0f00 */ -- uint8_t pad_0x1000[0x11b0-0x1000]; /* 0x1000 */ -- uint64_t vector_save_area_addr; /* 0x11b0 */ -- /* 64 bit extparam used for pfault/diag 250: defined by architecture */ -- uint64_t ext_params2; /* 0x11B8 */ -- uint8_t pad_0x11c0[0x1200-0x11C0]; /* 0x11C0 */ -- -- /* CPU register save area: defined by architecture */ -- uint64_t floating_pt_save_area[16]; /* 0x1200 */ -- uint64_t gpregs_save_area[16]; /* 0x1280 */ -- struct psw_t psw_save_area; /* 0x1300 */ -- uint8_t pad_0x1310[0x1318-0x1310]; /* 0x1310 */ -- uint32_t prefixreg_save_area; /* 0x1318 */ -- uint32_t fpt_creg_save_area; /* 0x131c */ -- uint8_t pad_0x1320[0x1324-0x1320]; /* 0x1320 */ -- uint32_t tod_progreg_save_area; /* 0x1324 */ -- uint32_t cpu_timer_save_area[2]; /* 0x1328 */ -- uint32_t clock_comp_save_area[2]; /* 0x1330 */ -- uint8_t pad_0x1338[0x1340-0x1338]; /* 0x1338 */ -- uint32_t access_regs_save_area[16]; /* 0x1340 */ -- uint64_t cregs_save_area[16]; /* 0x1380 */ -- uint8_t pad_0x1400[0x1800-0x1400]; /* 0x1400 */ -- -- /* Transaction abort diagnostic block */ -- uint8_t pgm_tdb[256]; /* 0x1800 */ -- -- /* align to the top of the prefix area */ -- uint8_t pad_0x1900[0x2000-0x1900]; /* 0x1900 */ --} __packed __aligned(8192); -- --#define S390_lowcore (*((struct _lowcore *) 0)) -- --#define __LC_IPLDEV 0x0c6c --#define __LC_OS_INFO 0x0e18 -- --#define PAGE_SIZE 4096 -- --void panic_notify(unsigned long reason); -- --#define panic(reason, x...) \ --do { \ -- printf(x); \ -- panic_notify(reason); \ -- libc_stop(reason); \ --} while (0) -- --static __always_inline int page_is_valid(unsigned long addr) --{ -- unsigned long tmp; -- int rc; -- -- asm volatile( -- "0: ic %1,%2\n" -- "1: lhi %0,1\n" -- "2:\n" -- ".pushsection .fixup, \"ax\"\n" -- "3: xr %0,%0\n" -- " jg 2b\n" -- ".popsection\n" -- EX_TABLE(0b, 3b) EX_TABLE(1b, 3b) -- : "=d" (rc), "=d" (tmp) -- : "Q" (*(unsigned long *) addr) -- : "cc"); -- return rc; --} -- --static __always_inline uint32_t csum_partial(const void *buf, int len, uint32_t sum) --{ -- register unsigned long reg2 asm("2") = (unsigned long) buf; -- register unsigned long reg3 asm("3") = (unsigned long) len; -- -- asm volatile( -- "0: cksm %0,%1\n" /* do checksum on longs */ -- " jo 0b\n" -- : "+d" (sum), "+d" (reg2), "+d" (reg3) : : "cc", "memory"); -- return sum; --} -- --#define __ctl_store(array, low, high) ({ \ -- typedef struct { char _[sizeof(array)]; } __may_alias addrtype;\ -- asm volatile( \ -- " stctg %1,%2,%0\n" \ -- : "=Q" (*(addrtype *)(&array)) \ -- : "i" (low), "i" (high)); \ --}) -- --#define __ctl_load(array, low, high) ({ \ -- typedef struct { char _[sizeof(array)]; } __may_alias addrtype; \ -- asm volatile( \ -- " lctlg %1,%2,%0\n" \ -- : : "Q" (*(addrtype *)(&array)), \ -- "i" (low), "i" (high)); \ --}) -- --static __always_inline void __ctl_set_bit(unsigned int cr, unsigned int bit) --{ -- unsigned long reg; -- -- __ctl_store(reg, cr, cr); -- reg |= 1UL << bit; -- __ctl_load(reg, cr, cr); --} -- --/* -- * DIAG 308 support -- */ --enum diag308_subcode { -- DIAG308_REL_HSA = 2, -- DIAG308_IPL = 3, -- DIAG308_DUMP = 4, -- DIAG308_SET = 5, -- DIAG308_STORE = 6, --}; -- --static __always_inline int diag308(unsigned long subcode, void *addr) --{ -- register unsigned long _addr asm("0") = (unsigned long) addr; -- register unsigned long _rc asm("1") = 0; -- -- asm volatile( -- " diag %0,%2,0x308\n" -- "0:\n" -- : "+d" (_addr), "+d" (_rc) -- : "d" (subcode) : "cc", "memory"); -- return _rc; --} -- --/* -- * Store CPU address -- */ --static __always_inline unsigned short stap(void) --{ -- unsigned short cpu_address; -- -- asm volatile("stap %0" : "=m" (cpu_address)); -- return cpu_address; --} -- --/* -- * Program the clock comparator -- */ --static __always_inline void set_clock_comparator(uint64_t time) --{ -- asm volatile("sckc %0" : : "Q" (time)); --} -- --/* -- * Program the CPU timer -- */ --static __always_inline void set_cpu_timer(uint64_t timer) --{ -- asm volatile("spt %0" : : "Q" (timer)); --} -- --/* -- * Get current time (store clock) -- */ --static __always_inline unsigned long long get_tod_clock(void) --{ -- unsigned long long clk; -- -- asm volatile("stck %0" : "=Q" (clk) : : "cc"); -- return clk; --} -- --/* -- * Get ID of current CPU -- */ --struct cpuid { -- unsigned int version:8; -- unsigned int ident:24; -- unsigned int machine:16; -- unsigned int unused:16; --} __packed __aligned(8); -- --static __always_inline void get_cpu_id(struct cpuid *ptr) --{ -- asm volatile("stidp %0" : "=Q" (*ptr)); --} -- --/* -- * Check if we run under z/VM -- */ --static __always_inline int is_zvm(void) --{ -- struct cpuid cpuid; -- -- get_cpu_id(&cpuid); -- return cpuid.version == 0xff; --} -- --/* -- * Vector register definition -- */ --typedef struct { -- uint32_t u[4]; --} __vector128; -- --/* -- * Save vector registers -- */ --static __always_inline void save_vx_regs(__vector128 *vxrs) --{ -- typedef struct { __vector128 _[32]; } addrtype; -- -- asm volatile( -- " la 1,%0\n" -- " .word 0xe70f,0x1000,0x003e\n" /* vstm 0,15,0(1) */ -- " .word 0xe70f,0x1100,0x0c3e\n" /* vstm 16,31,256(1) */ -- : "=Q" (*(addrtype *) vxrs) : : "1"); --} -- --/* -- * Save vector registers safe -- */ --static __always_inline void save_vx_regs_safe(__vector128 *vxrs) --{ -- unsigned long cr0; -- -- __ctl_store(cr0, 0, 0); -- __ctl_set_bit(0, 17); -- __ctl_set_bit(0, 18); /* AFP-register-control */ -- save_vx_regs(vxrs); -- __ctl_load(cr0, 0, 0); --} -- --#define MAX_FACILITY_BIT (256*8) /* stfle_fac_list has 256 bytes */ -- --static __always_inline int __test_facility(unsigned long nr, void *facilities) --{ -- unsigned char *ptr; -- -- if (nr >= MAX_FACILITY_BIT) -- return 0; -- ptr = (unsigned char *) facilities + (nr >> 3); -- return (*ptr & (0x80 >> (nr & 7))) != 0; --} -- --/* -- * The test_facility function uses the bit odering where the MSB is bit 0. -- * That makes it easier to query facility bits with the bit number as -- * documented in the Principles of Operation. -- */ --static __always_inline int test_facility(unsigned long nr) --{ -- return __test_facility(nr, &S390_lowcore.stfle_fac_list); --} -- --static __always_inline unsigned long __stfle_asm(uint64_t *stfle_fac_list, int size) --{ -- register unsigned long reg0 asm("0") = size - 1; -- -- asm volatile( -- ".insn s,0xb2b00000,0(%1)" /* stfle */ -- : "+d" (reg0) -- : "a" (stfle_fac_list) -- : "memory", "cc"); -- return reg0; --} -- --/** -- * stfle - Store facility list extended -- * @stfle_fac_list: array where facility list can be stored -- * @size: size of passed in array in double words -- */ --static __always_inline void stfle(uint64_t *stfle_fac_list, int size) --{ -- unsigned long nr; -- -- asm volatile( -- " .insn s,0xb2b10000,0(0)\n" /* stfl */ -- "0:\n" -- EX_TABLE(0b, 0b) -- : "+m" (S390_lowcore.stfl_fac_list)); -- nr = 4; /* bytes stored by stfl */ -- memcpy(stfle_fac_list, &S390_lowcore.stfl_fac_list, 4); -- if (S390_lowcore.stfl_fac_list & 0x01000000) { -- /* More facility bits available with stfle */ -- nr = __stfle_asm(stfle_fac_list, size); -- nr = MIN((nr + 1) * 8, size * 8UL); -- } -- memset((char *) stfle_fac_list + nr, 0, size * 8 - nr); --} -- --#endif /* S390_H */ ---- a/zipl/boot/sclp.c -+++ b/zipl/boot/sclp.c -@@ -11,7 +11,7 @@ - - #include "libc.h" - #include "error.h" --#include "s390.h" -+#include "boot/s390.h" - #include "sclp.h" - - /* Perform service call. Return 0 on success, non-zero otherwise. */ ---- a/zipl/boot/sclp.h -+++ b/zipl/boot/sclp.h -@@ -13,7 +13,7 @@ - #define SCLP_H - - #include "libc.h" --#include "s390.h" -+#include "boot/s390.h" - - /* vector keys and ids */ - #define GDS_ID_MDSMU 0x1310 ---- a/zipl/boot/stage2.c -+++ b/zipl/boot/stage2.c -@@ -14,7 +14,7 @@ - #include "error.h" - #include "libc.h" - #include "menu.h" --#include "s390.h" -+#include "boot/s390.h" - #include "stage2.h" - - static int is_null_descriptor(disk_blockptr_t *address) ---- a/zipl/boot/stage2.h -+++ b/zipl/boot/stage2.h -@@ -15,7 +15,7 @@ - #include "cio.h" - #include "error.h" - #include "libc.h" --#include "s390.h" -+#include "boot/s390.h" - - #define DESCR_PER_BLOCK 16 - -@@ -76,4 +76,3 @@ void kdump_stage2(unsigned long); - - - #endif /* COMMON_H */ -- ---- a/zipl/boot/stage2dump.h -+++ b/zipl/boot/stage2dump.h -@@ -13,7 +13,7 @@ - #define STAGE2DUMP_H - - #include "libc.h" --#include "s390.h" -+#include "boot/s390.h" - - #define IPL_SC *((struct subchannel_id *) &S390_lowcore.subchannel_id) - #define ROUND_DOWN(x, a) ((x) & ~((typeof(x))(a) - 1)) ---- a/zipl/boot/stage3.c -+++ b/zipl/boot/stage3.c -@@ -11,7 +11,7 @@ - - #include "libc.h" - #include "boot/sigp.h" --#include "s390.h" -+#include "boot/s390.h" - #include "stage3.h" - #include "error.h" - #include "zipl.h" ---- a/zipl/boot/stage3.h -+++ b/zipl/boot/stage3.h -@@ -13,8 +13,8 @@ - #define STAGE3_H - - #include "libc.h" --#include "s390.h" - -+#include "boot/s390.h" - #include "boot/ipl.h" - #include "boot/linux_layout.h" - diff --git a/s390-tools-sles15sp2-34-zkey-Add-convert-command-to-convert-keys-from-one-ty.patch b/s390-tools-sles15sp2-34-zkey-Add-convert-command-to-convert-keys-from-one-ty.patch deleted file mode 100644 index 3023efb..0000000 --- a/s390-tools-sles15sp2-34-zkey-Add-convert-command-to-convert-keys-from-one-ty.patch +++ /dev/null @@ -1,679 +0,0 @@ -Subject: zkey: Add 'convert' command to convert keys from one type to another -From: Ingo Franzki - -Summary: zkey: Add support for CCA AES CIPHER keys -Description: With CCA 5 there is a new secure key type, the so called - variable length symmetric cipher key token. This token format - can hold AES keys with size 128, 192 and 256 bits together - with additional attributes cryptographic bound to the key - token. The attributes may limit the usage of the key, for - example restrict export or usability scope. So this key type - is considered to be even more secure than the traditional - secure key token. This key token type is also called "CCA - AES CIPHER key", where the formerly used key token is called - "CCA AES DATA key". - The zkey as well as the zkey-cryptsetup tools are enhanced - to support AES CIPHER keys. That is, zkey can manage AES DATA - keys, as well as AES CIPHER keys. The key type must be specified - at key generation time, the default is to generate AED DATA - keys. -Upstream-ID: a86e41a51827b524c5f88db5e24282166df9b3c8 -Problem-ID: SEC1717 - -Upstream-Description: - - zkey: Add 'convert' command to convert keys from one type to another - - Add a new 'convert' command. It allows to convert a secure key from - one key type to another. Currently only keys of type CCA-AESDATA can be - converted to CCA-AESCIPHER. - - Signed-off-by: Ingo Franzki - Reviewed-by: Harald Freudenberger - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/keystore.c | 212 +++++++++++++++++++++++++++++++++++++++++++++++ - zkey/keystore.h | 4 - zkey/zkey.1 | 93 ++++++++++++++++++++ - zkey/zkey.c | 249 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - 4 files changed, 557 insertions(+), 1 deletion(-) - ---- a/zkey/keystore.c -+++ b/zkey/keystore.c -@@ -3947,6 +3947,218 @@ int keystore_crypttab(struct keystore *k - } - - /** -+ * Converts a secure keys in the keystore -+ * -+ * @param[in] keystore the key store -+ * @param[in] name the name of the key to convert -+ * @param[in] key_type the type of the key to convert it to -+ * @param[in] noapqncheck if true, the specified APQN(s) are not checked for -+ * existence and type. -+ * @param[in] pkey_fd the file descriptor of /dev/pkey -+ * @param[in] cca the CCA library struct -+ * -+ * @returns 0 for success or a negative errno in case of an error -+ */ -+int keystore_convert_key(struct keystore *keystore, const char *name, -+ const char *key_type, bool noapqncheck, bool quiet, -+ int pkey_fd, struct cca_lib *cca) -+{ -+ struct key_filenames file_names = { NULL, NULL, NULL }; -+ u8 output_key[2 * MAX_SECURE_KEY_SIZE]; -+ struct properties *properties = NULL; -+ int rc, min_level, selected = 1; -+ unsigned int output_key_size; -+ char *cur_key_type = NULL; -+ char **apqn_list = NULL; -+ size_t secure_key_size; -+ u8 *secure_key = NULL; -+ char *apqns = NULL; -+ char *temp; -+ u64 mkvp; -+ -+ util_assert(keystore != NULL, "Internal error: keystore is NULL"); -+ util_assert(name != NULL, "Internal error: name is NULL"); -+ -+ rc = _keystore_get_key_filenames(keystore, name, &file_names); -+ if (rc != 0) -+ goto out; -+ -+ rc = _keystore_ensure_keyfiles_exist(&file_names, name); -+ if (rc != 0) -+ goto out; -+ -+ properties = properties_new(); -+ rc = properties_load(properties, file_names.info_filename, 1); -+ if (rc != 0) { -+ warnx("Key '%s' does not exist or is invalid", name); -+ goto out; -+ } -+ -+ cur_key_type = _keystore_get_key_type(properties); -+ if (strcasecmp(cur_key_type, key_type) == 0) { -+ warnx("The secure key '%s' is already of type %s", name, -+ cur_key_type); -+ rc = 0; -+ goto out; -+ } -+ if (strcasecmp(cur_key_type, KEY_TYPE_CCA_AESDATA) != 0) { -+ warnx("Only secure keys of type %s can " -+ "be converted. The secure key '%s' is of type %s", -+ KEY_TYPE_CCA_AESDATA, name, cur_key_type); -+ rc = 0; -+ goto out; -+ } -+ -+ secure_key = read_secure_key(file_names.skey_filename, -+ &secure_key_size, keystore->verbose); -+ if (secure_key == NULL) { -+ rc = -ENOENT; -+ goto out; -+ } -+ -+ min_level = get_min_card_level_for_keytype(key_type); -+ if (min_level < 0) { -+ warnx("Invalid key-type specified: %s", key_type); -+ rc = -EINVAL; -+ goto out; -+ } -+ -+ apqns = properties_get(properties, PROP_NAME_APQNS); -+ if (apqns != NULL) -+ apqn_list = str_list_split(apqns); -+ -+ rc = cross_check_apqns(apqns, 0, min_level, true, keystore->verbose); -+ if (rc == -EINVAL) -+ goto out; -+ if (rc != 0 && rc != -ENOTSUP && !noapqncheck) { -+ warnx("Your master key setup is improper for converting key " -+ "'%s'", name); -+ goto out; -+ } -+ -+ rc = validate_secure_key(pkey_fd, secure_key, secure_key_size, -+ NULL, NULL, (const char **)apqn_list, -+ keystore->verbose); -+ if (rc != 0) -+ goto out; -+ -+ rc = get_master_key_verification_pattern(secure_key, secure_key_size, -+ &mkvp, keystore->verbose); -+ if (rc) -+ goto out; -+ -+ rc = select_cca_adapter_by_mkvp(cca, mkvp, NULL, -+ FLAG_SEL_CCA_MATCH_CUR_MKVP, -+ keystore->verbose); -+ if (rc == -ENOTSUP) { -+ rc = 0; -+ selected = 0; -+ } -+ if (rc != 0) { -+ warnx("No APQN found that is suitable for " -+ "converting the secure AES key '%s'", name); -+ goto out; -+ } -+ -+ if (!quiet) { -+ util_print_indented("ATTENTION: Converting a secure key is " -+ "irreversible, and might have an effect " -+ "on the volumes encrypted with it!", 0); -+ _keystore_msg_for_volumes("The following volumes are encrypted " -+ "with this key:", properties, NULL); -+ printf("%s: Convert key '%s [y/N]'? ", -+ program_invocation_short_name, name); -+ if (!prompt_for_yes(keystore->verbose)) { -+ warnx("Operation aborted"); -+ rc = -ECANCELED; -+ goto out; -+ } -+ } -+ -+ memset(output_key, 0, sizeof(output_key)); -+ output_key_size = sizeof(output_key); -+ rc = convert_aes_data_to_cipher_key(cca, secure_key, -+ secure_key_size, output_key, -+ &output_key_size, -+ keystore->verbose); -+ if (rc != 0) { -+ warnx("Converting the secure key '%s' from %s to %s has failed", -+ name, KEY_TYPE_CCA_AESDATA, key_type); -+ if (!selected) -+ print_msg_for_cca_envvars("secure AES key"); -+ goto out; -+ } -+ -+ rc = restrict_key_export(cca, output_key, output_key_size, -+ keystore->verbose); -+ if (rc != 0) { -+ warnx("Export restricting the converted secure key '%s' has " -+ "failed", name); -+ if (!selected) -+ print_msg_for_cca_envvars("secure AES key"); -+ goto out; -+ } -+ -+ rc = properties_set2(properties, PROP_NAME_KEY_TYPE, key_type, true); -+ if (rc != 0) { -+ warnx("Invalid characters in key-type"); -+ goto out; -+ } -+ -+ rc = properties_save(properties, file_names.info_filename, 1); -+ if (rc != 0) { -+ pr_verbose(keystore, -+ "Failed to write key info file '%s': %s", -+ file_names.info_filename, strerror(-rc)); -+ goto out; -+ } -+ -+ rc = write_secure_key(file_names.skey_filename, output_key, -+ output_key_size, keystore->verbose); -+ if (rc != 0) -+ goto out; -+ -+ pr_verbose(keystore, "Secure key '%s' was converted successfully", -+ name); -+ -+ util_asprintf(&temp, "The following LUKS2 volumes are " -+ "encrypted with key '%s'. These volumes still contain " -+ "the secure AES volume key of type CCA-AESDATA. To " -+ "change the secure AES volume key in the LUKS2 header, " -+ "run command 'zkey-cryptsetup setkey " -+ "--master-key-file %s':", name, -+ file_names.skey_filename); -+ _keystore_msg_for_volumes(temp, properties, VOLUME_TYPE_LUKS2); -+ free(temp); -+ util_asprintf(&temp, "The following plain mode volumes are " -+ "encrypted with key '%s'. You must adapt the crypttab " -+ "entries for this volumes and change the key size " -+ "parameter to 'size=%u' or run command 'zkey crypttab " -+ "--volumes ' for each volume to re-generate the " -+ "crypttab entries:", name, output_key_size * 8, name); -+ _keystore_msg_for_volumes(temp, properties, VOLUME_TYPE_PLAIN); -+ free(temp); -+ -+out: -+ _keystore_free_key_filenames(&file_names); -+ if (properties != NULL) -+ properties_free(properties); -+ if (secure_key != NULL) -+ free(secure_key); -+ if (apqns != NULL) -+ free(apqns); -+ if (apqn_list != NULL) -+ str_list_free_string_array(apqn_list); -+ if (cur_key_type != NULL) -+ free(cur_key_type); -+ -+ if (rc != 0) -+ pr_verbose(keystore, "Failed to convert key '%s': %s", -+ name, strerror(-rc)); -+ return rc; -+} -+ -+/** - * Frees a keystore object - * - * @param[in] keystore the key store ---- a/zkey/keystore.h -+++ b/zkey/keystore.h -@@ -81,6 +81,10 @@ int keystore_crypttab(struct keystore *k - const char *volume_type, const char *keyfile, - size_t keyfile_offset, size_t keyfile_size, size_t tries); - -+int keystore_convert_key(struct keystore *keystore, const char *name, -+ const char *key_type, bool noapqncheck, bool quiet, -+ int pkey_fd, struct cca_lib *cca); -+ - void keystore_free(struct keystore *keystore); - - ---- a/zkey/zkey.1 -+++ b/zkey/zkey.1 -@@ -62,7 +62,8 @@ in size. - The \fBzkey\fP tool can operate in two modes. When argument - .I secure\-key\-file - is specified then it operates on the secure key contained in the specified file. --This applies to commands \fBgenerate\fP, \fBvalidate\fP, and \fBreencipher\fP. -+This applies to commands \fBgenerate\fP, \fBvalidate\fP, \fBreencipher\fP, and -+\fBconvert\fP. - When the - .B \-\-name - option is specified then it operates on a secure key contained in the secure -@@ -680,6 +681,72 @@ questions, you can specify the - option. These options are passed to the generated command(s) and behave in the - same way as with \fBcryptsetup\fP. - . -+.SS "Convert existing AES secure keys from one key type to another type" -+. -+.B zkey -+.BR convert | con -+.I secure\-key\-file -+.RB \-\-key-type | \-K -+.IR type -+.RB [ \-\-no\-apqn\-check ] -+.RB [ \-\-force | \-F ] -+.RB [ \-\-verbose | \-V ] -+. -+.PP -+.B zkey -+.BR convert | con -+.B \-\-name | \-N -+.IR key-name -+.RB \-\-key-type | \-K -+.IR type -+.RB [ \-\-no\-apqn\-check ] -+.RB [ \-\-force | \-F ] -+.RB [ \-\-verbose | \-V ] -+. -+.PP -+Use the -+.B convert -+command to convert an existing secure key from one key type to another type. -+You can convert secure keys of type CCA-AESDATA to type CCA-AESCIPHER only. -+ -+.B Note: -+Secure keys converted to type \fBCCA-AESCIPHER\fP require an IBM cryptographic -+adapter in CCA coprocessor mode of version 6 or later, e.g. a CEX6C. -+ -+The secure key can either be contained in a file in the file system, or in a -+secure key repository. To convert a secure key contained in a file, specify -+the file name with option \fIsecure\-key\-file\fP. To convert a secure key -+contained in the secure key repository, specify the name of the key -+that is to be converted using the -+.B \-\-name -+option. You cannot use wildcards. The convert command prompts for -+a confirmation, unless you specify the -+.B \-\-force -+option. -+.PP -+.B Note: -+Converting a secure key is irreversible! -+When converting a secure key that is associated with one or multiple volumes, -+a message informs you about the associated volumes. When the secure key is -+converted, this might have an effect on these volumes. -+.P -+For volumes with volume type \fBplain\fP, you must adapt the crypttab entries -+and change the key size parameter to \fBsize=\fP or run -+command \fBzkey crypttab --volumes \fP for each associated volume to -+re-generate the crypttab entries. -+.P -+Associated volumes of type \fLUKS2\fP still contain the secure AES volume key of -+the original type. To change the secure AES volume key in the LUKS2 header, -+run command \fBzkey-cryptsetup setkey --master-key-file -+\fP for each associated volume. -+. -+.P -+.B Note: -+The \fBconvert\fP command requires the CCA host library (libcsulcca.so) -+to be installed. The required CCA IBM cryptographic adapter firmware version -+is 6.3.27 or later. For the supported environments and downloads, see: -+\fIhttp://www.ibm.com/security/cryptocards\fP -+. - . - . - . -@@ -1203,6 +1270,30 @@ cryptsetup command(s). - . - . - . -+.SS "Options for the convert command" -+.TP -+.BR \-N ", " \-\-name\~\fIkey-name\fP -+Specifies the name of the secure key in the secure key repository. You cannot -+use wildcards. -+This option is only used for secure keys contained in the secure key repository. -+.TP -+.BR \-K ", " \-\-key-type\~\fItype\fP -+Specifies the key type to which the secure key shall be converted to. -+Possible values are \fBCCA-AESCIPHER\fP. Secure keys of type \fBCCA-AESCIPHER\fP -+require an IBM cryptographic adapter in CCA coprocessor mode of version 6 or -+later, e.g. a CEX6C. -+.TP -+.BR \-\-no\-apqn\-check -+Do not check if the associated APQNs are available and capable of converting -+the secure key to type CCA-AESCIPHER. -+This option is only used for secure keys contained in the secure key repository. -+.TP -+.BR \-F ", " \-\-force\fP -+The user is prompted to confirm the convertion of a secure key. Use this option -+to convert a secure key without prompting for a confirmation. -+. -+. -+. - .SS "General options" - .TP - .BR \-V ", " \-\-verbose ---- a/zkey/zkey.c -+++ b/zkey/zkey.c -@@ -106,6 +106,7 @@ static struct zkey_globals { - #define COMMAND_COPY "copy " - #define COMMAND_CRYPTTAB "crypttab" - #define COMMAND_CRYPTSETUP "cryptsetup" -+#define COMMAND_CONVERT "convert" - - #define ZKEY_COMMAND_MAX_LEN 10 - -@@ -767,6 +768,38 @@ static struct util_opt opt_vec[] = { - /***********************************************************/ - { - .flags = UTIL_OPT_FLAG_SECTION, -+ .desc = "OPTIONS", -+ .command = COMMAND_CONVERT, -+ }, -+ { -+ .option = { "name", required_argument, NULL, 'N'}, -+ .argument = "NAME", -+ .desc = "Name of the secure AES key in the repository that is " -+ "to be converted", -+ .command = COMMAND_CONVERT, -+ }, -+ { -+ .option = { "key-type", required_argument, NULL, 'K'}, -+ .argument = "type", -+ .desc = "The type of the key to convert the secure key to. " -+ "Possible values are '"KEY_TYPE_CCA_AESCIPHER"'. ", -+ .command = COMMAND_CONVERT, -+ }, -+ { -+ .option = {"no-apqn-check", 0, NULL, OPT_NO_APQN_CHECK}, -+ .desc = "Do not check if the associated APQN(s) are available", -+ .command = COMMAND_CONVERT, -+ .flags = UTIL_OPT_FLAG_NOSHORT, -+ }, -+ { -+ .option = {"force", 0, NULL, 'F'}, -+ .desc = "Do not prompt for a confirmation when converting a " -+ "key", -+ .command = COMMAND_CONVERT, -+ }, -+ /***********************************************************/ -+ { -+ .flags = UTIL_OPT_FLAG_SECTION, - .desc = "COMMON OPTIONS" - }, - { -@@ -812,6 +845,7 @@ static int command_rename(void); - static int command_copy(void); - static int command_crypttab(void); - static int command_cryptsetup(void); -+static int command_convert(void); - - static struct zkey_command zkey_commands[] = { - { -@@ -946,6 +980,21 @@ static struct zkey_command zkey_commands - .has_options = 1, - .need_keystore = 1, - }, -+ { -+ .command = COMMAND_CONVERT, -+ .abbrev_len = 3, -+ .function = command_convert, -+ .need_cca_library = 1, -+ .need_pkey_device = 1, -+ .short_desc = "Convert a secure AES key", -+ .long_desc = "Convert an existing secure AES key that is " -+ "either contained in SECURE-KEY-FILE or is stored " -+ "in the repository from one key type to another " -+ "type.", -+ .has_options = 1, -+ .pos_arg = "[SECURE-KEY-FILE]", -+ .pos_arg_optional = 1, -+ }, - { .command = NULL } - }; - -@@ -1691,6 +1740,206 @@ static int command_cryptsetup(void) - return rc != 0 ? EXIT_FAILURE : EXIT_SUCCESS; - } - -+/* -+ * Command handler for 'convert'. -+ * -+ * Converts secure keys from one key type to another -+ */ -+static int command_convert_file(void) -+{ -+ u8 output_key[2 * MAX_SECURE_KEY_SIZE]; -+ unsigned int output_key_size; -+ size_t secure_key_size; -+ int rc, is_old_mk; -+ int selected = 1; -+ u8 *secure_key; -+ int min_level; -+ u64 mkvp; -+ -+ if (g.name != NULL) { -+ warnx("Option '--name|-N' is not valid for " -+ "re-enciphering a key outside of the repository"); -+ util_prg_print_parse_error(); -+ return EXIT_FAILURE; -+ } -+ if (g.noapqncheck) { -+ warnx("Option '--no-apqn-check' is not valid for " -+ "converting a key outside of the repository"); -+ util_prg_print_parse_error(); -+ return EXIT_FAILURE; -+ } -+ -+ min_level = get_min_card_level_for_keytype(g.key_type); -+ if (min_level < 0) { -+ warnx("Invalid key-type specified: %s", g.key_type); -+ return EXIT_FAILURE; -+ } -+ -+ rc = cross_check_apqns(NULL, 0, min_level, true, g.verbose); -+ if (rc == -EINVAL) -+ return EXIT_FAILURE; -+ if (rc != 0 && rc != -ENOTSUP) { -+ warnx("Your master key setup is improper"); -+ return EXIT_FAILURE; -+ } -+ -+ /* Read the secure key to be re-enciphered */ -+ secure_key = read_secure_key(g.pos_arg, &secure_key_size, g.verbose); -+ if (secure_key == NULL) -+ return EXIT_FAILURE; -+ -+ rc = validate_secure_key(g.pkey_fd, secure_key, secure_key_size, NULL, -+ &is_old_mk, NULL, g.verbose); -+ if (rc != 0) { -+ warnx("The secure key in file '%s' is not valid", g.pos_arg); -+ rc = EXIT_FAILURE; -+ goto out; -+ } -+ -+ rc = get_master_key_verification_pattern(secure_key, secure_key_size, -+ &mkvp, g.verbose); -+ if (rc != 0) { -+ warnx("Failed to get the master key verification pattern: %s", -+ strerror(-rc)); -+ rc = EXIT_FAILURE; -+ goto out; -+ } -+ -+ if (strcasecmp(get_key_type(secure_key, secure_key_size), -+ g.key_type) == 0) { -+ warnx("The secure key in file '%s' is already of type %s", -+ g.pos_arg, get_key_type(secure_key, secure_key_size)); -+ rc = EXIT_FAILURE; -+ goto out; -+ } -+ -+ if (is_cca_aes_data_key(secure_key, secure_key_size)) { -+ if (strcasecmp(g.key_type, KEY_TYPE_CCA_AESCIPHER) != 0) { -+ warnx("The secure key in file '%s' can not be " -+ "converted into type %s", g.pos_arg, g.key_type); -+ rc = EXIT_FAILURE; -+ goto out; -+ } -+ } else if (is_cca_aes_cipher_key(secure_key, secure_key_size)) { -+ warnx("The secure key in file '%s' is already of type %s", -+ g.pos_arg, KEY_TYPE_CCA_AESCIPHER); -+ rc = EXIT_FAILURE; -+ goto out; -+ } else { -+ warnx("The secure key in file '%s' has an unsupported key type", -+ g.pos_arg); -+ rc = EXIT_FAILURE; -+ goto out; -+ } -+ -+ rc = select_cca_adapter_by_mkvp(&g.cca, mkvp, NULL, -+ FLAG_SEL_CCA_MATCH_CUR_MKVP, -+ g.verbose); -+ if (rc == -ENOTSUP) { -+ rc = 0; -+ selected = 0; -+ } -+ if (rc != 0) { -+ warnx("No APQN found that is suitable for " -+ "converting the secure AES key in file '%s'", g.pos_arg); -+ rc = EXIT_FAILURE; -+ goto out; -+ } -+ -+ if (!g.force) { -+ util_print_indented("ATTENTION: Converting a secure key is " -+ "irreversible, and might have an effect " -+ "on the volumes encrypted with it!", 0); -+ printf("%s: Convert key in file '%s' [y/N]? ", -+ program_invocation_short_name, g.pos_arg); -+ if (!prompt_for_yes(g.verbose)) { -+ warnx("Operation aborted"); -+ rc = EXIT_FAILURE; -+ goto out; -+ } -+ } -+ -+ memset(output_key, 0, sizeof(output_key)); -+ output_key_size = sizeof(output_key); -+ rc = convert_aes_data_to_cipher_key(&g.cca, secure_key, secure_key_size, -+ output_key, &output_key_size, -+ g.verbose); -+ if (rc != 0) { -+ warnx("Converting the secure key from %s to %s has failed", -+ get_key_type(secure_key, secure_key_size), g.key_type); -+ if (!selected) -+ print_msg_for_cca_envvars("secure AES key"); -+ rc = EXIT_FAILURE; -+ goto out; -+ } -+ -+ rc = restrict_key_export(&g.cca, output_key, output_key_size, -+ g.verbose); -+ if (rc != 0) { -+ warnx("Export restricting the converted secure key has failed"); -+ if (!selected) -+ print_msg_for_cca_envvars("secure AES key"); -+ rc = EXIT_FAILURE; -+ goto out; -+ } -+ -+ pr_verbose("Secure key was converted successfully"); -+ -+ /* Write the converted secure key */ -+ rc = write_secure_key(g.outputfile ? g.outputfile : g.pos_arg, -+ output_key, output_key_size, g.verbose); -+ if (rc != 0) -+ rc = EXIT_FAILURE; -+out: -+ free(secure_key); -+ return rc; -+} -+ -+/* -+ * Command handler for 'convert in repository'. -+ * -+ * Converts secure keys from one key type to another -+ */ -+static int command_convert_repository(void) -+{ -+ int rc; -+ -+ if (g.name == NULL) { -+ misc_print_required_parm("--name/-N"); -+ return EXIT_FAILURE; -+ } -+ -+ rc = keystore_convert_key(g.keystore, g.name, g.key_type, g.noapqncheck, -+ g.force, g.pkey_fd, &g.cca); -+ -+ return rc != 0 ? EXIT_FAILURE : EXIT_SUCCESS; -+} -+ -+/* -+ * Command handler for 'convert'. -+ * -+ * Converts secure keys from one key type to another -+ */ -+static int command_convert(void) -+{ -+ if (g.key_type == NULL) { -+ misc_print_required_parm("--key-type/-K"); -+ return EXIT_FAILURE; -+ } -+ if (strcasecmp(g.key_type, KEY_TYPE_CCA_AESCIPHER) != 0) { -+ warnx("Secure keys can only be converted into key type %s", -+ KEY_TYPE_CCA_AESCIPHER); -+ return EXIT_FAILURE; -+ } -+ -+ if (g.pos_arg != NULL) -+ return command_convert_file(); -+ else -+ return command_convert_repository(); -+ -+ return EXIT_SUCCESS; -+} -+ - /** - * Opens the keystore. The keystore directory is either the - * default directory or as specified in an environment variable diff --git a/s390-tools-sles15sp2-35-zipl-libc-include-s390.h.patch b/s390-tools-sles15sp2-35-zipl-libc-include-s390.h.patch deleted file mode 100644 index 9789bcd..0000000 --- a/s390-tools-sles15sp2-35-zipl-libc-include-s390.h.patch +++ /dev/null @@ -1,51 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] zipl/libc: include 's390.h' -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: b0f82d22f9f60a0a8db1976751aa5a875e7c5f80 -Problem-ID: VS1804 - -Upstream-Description: - - zipl/libc: include 's390.h' - - Include 'boot/s390.h' in 'libc.c' as `PAGE_SIZE` is used there and - move the 'libc.h' include directive to the top. - - Reviewed-by: Philipp Rudo - Reviewed-by: Stefan Haberland - Signed-off-by: Marc Hartmayer - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - zipl/boot/libc.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - ---- a/zipl/boot/libc.c -+++ b/zipl/boot/libc.c -@@ -9,12 +9,14 @@ - * it under the terms of the MIT license. See LICENSE for details. - */ - -+#include "libc.h" -+ - #include - - #include "lib/zt_common.h" -+#include "boot/s390.h" - - #include "error.h" --#include "libc.h" - #include "sclp.h" - - extern char __heap_start[]; diff --git a/s390-tools-sles15sp2-35-zkey-Allow-zkey-cryptsetup-setkey-to-set-different-k.patch b/s390-tools-sles15sp2-35-zkey-Allow-zkey-cryptsetup-setkey-to-set-different-k.patch deleted file mode 100644 index 8da0631..0000000 --- a/s390-tools-sles15sp2-35-zkey-Allow-zkey-cryptsetup-setkey-to-set-different-k.patch +++ /dev/null @@ -1,63 +0,0 @@ -Subject: zkey: Allow 'zkey-cryptsetup setkey' to set different key types -From: Ingo Franzki - -Summary: zkey: Add support for CCA AES CIPHER keys -Description: With CCA 5 there is a new secure key type, the so called - variable length symmetric cipher key token. This token format - can hold AES keys with size 128, 192 and 256 bits together - with additional attributes cryptographic bound to the key - token. The attributes may limit the usage of the key, for - example restrict export or usability scope. So this key type - is considered to be even more secure than the traditional - secure key token. This key token type is also called "CCA - AES CIPHER key", where the formerly used key token is called - "CCA AES DATA key". - The zkey as well as the zkey-cryptsetup tools are enhanced - to support AES CIPHER keys. That is, zkey can manage AES DATA - keys, as well as AES CIPHER keys. The key type must be specified - at key generation time, the default is to generate AED DATA - keys. -Upstream-ID: bc987c8d18ddeb6fec46113a7fe7588555b592e7 -Problem-ID: SEC1717 - -Upstream-Description: - - zkey: Allow 'zkey-cryptsetup setkey' to set different key types - - When a secure key has been converted from type CCA-AESDATA to type - CCA-AESCIPHER, the secure key stored in the LUKS2 header of a volume - encrypted with that key should also changed. - - Command 'zkey-cryptsetup setkey' allows to set (replace) the volume - key in the LUKS2 header. It now accepts keys to be set that have - a different size of the original volume keys. CCA-AESCIPHER keys - are larger than CCA-AESDATA keys. - - Signed-off-by: Ingo Franzki - Reviewed-by: Harald Freudenberger - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/zkey-cryptsetup.c | 9 +-------- - 1 file changed, 1 insertion(+), 8 deletions(-) - ---- a/zkey/zkey-cryptsetup.c -+++ b/zkey/zkey-cryptsetup.c -@@ -2169,14 +2169,7 @@ static int command_setkey(void) - if (rc < 0) - goto out; - -- if (keysize != newkey_size) { -- warnx("The secure key in file '%s' has an invalid size", -- g.master_key_file); -- rc = -EINVAL; -- goto out; -- } -- -- if (memcmp(newkey, key, keysize) == 0) { -+ if (keysize == newkey_size && memcmp(newkey, key, keysize) == 0) { - warnx("The secure key in file '%s' is equal to the current " - "volume key, setkey is ignored", g.master_key_file); - rc = 0; diff --git a/s390-tools-sles15sp2-36-include-boot-s390.h-move-panic-and-panic_notify-to-l.patch b/s390-tools-sles15sp2-36-include-boot-s390.h-move-panic-and-panic_notify-to-l.patch deleted file mode 100644 index bb13ac3..0000000 --- a/s390-tools-sles15sp2-36-include-boot-s390.h-move-panic-and-panic_notify-to-l.patch +++ /dev/null @@ -1,69 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] include/boot/s390.h: move panic and panic_notify to libc.h -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: 2568863f581cff9bf3b1e27c2d2917b5ae3b5177 -Problem-ID: VS1804 - -Upstream-Description: - - include/boot/s390.h: move panic and panic_notify to libc.h - - ... as this code is not s390 specific and not every user of s390.h - wants to implement `panic_notify`. - - Reviewed-by: Philipp Rudo - Reviewed-by: Stefan Haberland - Signed-off-by: Marc Hartmayer - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - include/boot/s390.h | 9 --------- - zipl/boot/libc.h | 8 ++++++++ - 2 files changed, 8 insertions(+), 9 deletions(-) - ---- a/include/boot/s390.h -+++ b/include/boot/s390.h -@@ -201,15 +201,6 @@ struct _lowcore { - #define S390_lowcore (*((struct _lowcore *) 0)) - - --void panic_notify(unsigned long reason); -- --#define panic(reason, x...) \ --do { \ -- printf(x); \ -- panic_notify(reason); \ -- libc_stop(reason); \ --} while (0) -- - static __always_inline int page_is_valid(unsigned long addr) - { - unsigned long tmp; ---- a/zipl/boot/libc.h -+++ b/zipl/boot/libc.h -@@ -61,6 +61,14 @@ void libc_stop(unsigned long); - void start(void); - void pgm_check_handler(void); - void pgm_check_handler_fn(void); -+void panic_notify(unsigned long reason); -+ -+#define panic(reason, ...) \ -+ do { \ -+ printf(__VA_ARGS__); \ -+ panic_notify(reason); \ -+ libc_stop(reason); \ -+ } while (0) - - static inline int isdigit(int c) - { diff --git a/s390-tools-sles15sp2-37-include-boot-s390.h-fixes-for-Werror-sign-conversion.patch b/s390-tools-sles15sp2-37-include-boot-s390.h-fixes-for-Werror-sign-conversion.patch deleted file mode 100644 index e781b65..0000000 --- a/s390-tools-sles15sp2-37-include-boot-s390.h-fixes-for-Werror-sign-conversion.patch +++ /dev/null @@ -1,73 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] include/boot/s390.h: fixes for -Werror=sign-conversion -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: 305235a7bce814f71ec113a612b6117c96894e23 -Problem-ID: VS1804 - -Upstream-Description: - - include/boot/s390.h: fixes for -Werror=sign-conversion - - Errors fixed: - - ../../include/boot/s390.h: In function '__stfle_asm': - ../../include/boot/s390.h:424:41: error: conversion to 'long unsigned int' from 'int' may change the sign of the result [-Werror=sign-conversion] - register unsigned long reg0 asm("0") = size - 1; - - ../../include/boot/s390.h: In function 'stfle': - ../../include/boot/s390.h:453:31: error: conversion to 'long unsigned int' from 'int' may change the sign of the result [-Werror=sign-conversion] - nr = MIN((nr + 1) * 8, size * 8UL); - - ../../include/boot/s390.h: In function 'diag308': - ../../include/boot/s390.h:296:9: error: conversion from 'long unsigned int' to 'int' may change value [-Werror=conversion] - return _rc; - - Reviewed-by: Philipp Rudo - Reviewed-by: Stefan Haberland - Signed-off-by: Marc Hartmayer - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - include/boot/s390.h | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/include/boot/s390.h -+++ b/include/boot/s390.h -@@ -269,7 +269,7 @@ enum diag308_subcode { - DIAG308_STORE = 6, - }; - --static __always_inline int diag308(unsigned long subcode, void *addr) -+static __always_inline unsigned long diag308(unsigned long subcode, void *addr) - { - register unsigned long _addr asm("0") = (unsigned long) addr; - register unsigned long _rc asm("1") = 0; -@@ -403,7 +403,7 @@ static __always_inline int test_facility - return __test_facility(nr, &S390_lowcore.stfle_fac_list); - } - --static __always_inline unsigned long __stfle_asm(uint64_t *stfle_fac_list, int size) -+static __always_inline unsigned long __stfle_asm(uint64_t *stfle_fac_list, unsigned int size) - { - register unsigned long reg0 asm("0") = size - 1; - -@@ -420,7 +420,7 @@ static __always_inline unsigned long __s - * @stfle_fac_list: array where facility list can be stored - * @size: size of passed in array in double words - */ --static __always_inline void stfle(uint64_t *stfle_fac_list, int size) -+static __always_inline void stfle(uint64_t *stfle_fac_list, unsigned int size) - { - unsigned long nr; - diff --git a/s390-tools-sles15sp2-38-zipl-refactor-all-EBCDIC-code-into-separate-files.patch b/s390-tools-sles15sp2-38-zipl-refactor-all-EBCDIC-code-into-separate-files.patch deleted file mode 100644 index 0662a64..0000000 --- a/s390-tools-sles15sp2-38-zipl-refactor-all-EBCDIC-code-into-separate-files.patch +++ /dev/null @@ -1,640 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] zipl: refactor all EBCDIC code into separate files -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: a37170b8bec07a0ffc3270a4c78124e1117f0337 -Problem-ID: VS1804 - -Upstream-Description: - - zipl: refactor all EBCDIC code into separate files - - This allows the reuse of the code later in sclp.c. While at it, also - declare @source parameter of `ebcdic_to_ascii` function as `const` and - rename all `ebc_` function name prefixes into `ebcdic_`. Move - conversion tables to separate file so it only gets linked into loaders - that need it. - - Reviewed-by: Philipp Rudo - Reviewed-by: Stefan Haberland - Signed-off-by: Marc Hartmayer - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - zipl/boot/Makefile | 16 ++-- - zipl/boot/ebcdic.c | 30 ++++++++ - zipl/boot/ebcdic.h | 45 ++++++++++++ - zipl/boot/ebcdic_conv.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++++ - zipl/boot/ebcdic_conv.h | 21 ++++++ - zipl/boot/libc.c | 19 ----- - zipl/boot/libc.h | 25 ------- - zipl/boot/menu.c | 9 +- - zipl/boot/stage3.c | 156 -------------------------------------------- - 9 files changed, 280 insertions(+), 208 deletions(-) - ---- a/zipl/boot/Makefile -+++ b/zipl/boot/Makefile -@@ -28,22 +28,22 @@ all: data.o data.h tape0.bin stage3.bin - - eckd2dump_sv.exec: \ - head.o stage2dump.o cio.o eckd2dump.o eckd2dump_sv.o \ -- libc.o sclp.o entry.o -+ libc.o ebcdic.o sclp.o entry.o - eckd2dump_mv.exec: \ - head.o stage2dump.o cio.o eckd2dump.o eckd2dump_mv.o \ -- libc.o sclp.o entry.o -+ libc.o ebcdic.o sclp.o entry.o - fba2dump.exec: \ - head.o stage2dump.o cio.o fba2dump.o \ -- libc.o sclp.o entry.o -+ libc.o ebcdic.o sclp.o entry.o - tape2dump.exec: \ - head.o stage2dump.o cio.o tape2dump.o \ -- libc.o sclp.o entry.o --eckd2.exec: head.o stage2.o cio.o eckd2.o libc.o menu.o sclp.o \ -+ libc.o ebcdic.o sclp.o entry.o -+eckd2.exec: head.o stage2.o cio.o eckd2.o libc.o ebcdic.o menu.o sclp.o \ - kdump2.o kdump.o entry.o --fba2.exec: head.o stage2.o cio.o fba2.o libc.o menu.o sclp.o \ -+fba2.exec: head.o stage2.o cio.o fba2.o libc.o ebcdic.o menu.o sclp.o \ - kdump2.o kdump.o entry.o --stage3.exec: head.o stage3.o kdump3.o libc.o sclp.o sclp_stage3.o \ -- kdump.o entry.o stage3.lds -+stage3.exec: head.o stage3.o kdump3.o libc.o ebcdic.o ebcdic_conv.o sclp.o \ -+ sclp_stage3.o kdump.o entry.o stage3.lds - - %.exec: %.o - STAGE=$$( \ ---- /dev/null -+++ b/zipl/boot/ebcdic.c -@@ -0,0 +1,30 @@ -+/* -+ * EBCDIC specific functions -+ * -+ * Copyright IBM Corp. 2013, 2020 -+ * -+ * 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 "ebcdic.h" -+ -+ -+/* -+ * Convert ebcdic string to number with given base -+ */ -+unsigned long ebcdic_strtoul(char *nptr, char **endptr, int base) -+{ -+ unsigned long val = 0; -+ -+ while (ebcdic_isdigit(*nptr)) { -+ if (val != 0) -+ val *= base; -+ val += *nptr - 0xf0; -+ nptr++; -+ } -+ if (endptr) -+ *endptr = (char *)nptr; -+ return val; -+} ---- /dev/null -+++ b/zipl/boot/ebcdic.h -@@ -0,0 +1,45 @@ -+/* -+ * EBCDIC specific functions -+ * -+ * Copyright IBM Corp. 2013, 2020 -+ * -+ * s390-tools is free software; you can redistribute it and/or modify -+ * it under the terms of the MIT license. See LICENSE for details. -+ * -+ */ -+ -+#ifndef EBCDIC_H -+#define EBCDIC_H -+ -+#include "lib/zt_common.h" -+ -+ -+#ifndef __ASSEMBLER__ -+ -+unsigned long ebcdic_strtoul(char *, char **, int); -+ -+static __always_inline int ecbdic_isspace(char c) -+{ -+ return (c == 0x40) || (c == 0x05) || (c == 0x15) || (c == 0x25) || -+ (c == 0x0b) || (c == 0x0c) || (c == 0x0d); -+} -+ -+static __always_inline int ebcdic_isdigit(char c) -+{ -+ return (c >= 0xf0) && (c <= 0xf9); -+} -+ -+static __always_inline int ebcdic_isupper(char c) -+{ -+ return (c >= 0xC1 && c <= 0xC9) || (c >= 0xD1 && c <= 0xD9) || -+ (c >= 0xE2 && c <= 0xE9); -+} -+ -+static __always_inline char ebcdic_tolower(char c) -+{ -+ if (ebcdic_isupper(c)) -+ c -= 0x40; -+ return c; -+} -+#endif /* __ASSEMBLER__ */ -+#endif /* EBCDIC_H */ ---- /dev/null -+++ b/zipl/boot/ebcdic_conv.c -@@ -0,0 +1,167 @@ -+/* -+ * EBCDIC conversion functions -+ * -+ * Copyright IBM Corp. 2013, 2020 -+ * -+ * 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 "ebcdic_conv.h" -+#include "libc.h" -+#include "boot/s390.h" -+ -+ -+static unsigned char ebcdic_037[256] = { -+/* 0x00 NUL SOH STX ETX *SEL HT *RNL DEL */ -+ 0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F, -+/* 0x08 -GE -SPS -RPT VT FF CR SO SI */ -+ 0x07, 0x07, 0x07, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, -+/* 0x10 DLE DC1 DC2 DC3 -RES -NL BS -POC -+ -ENP ->LF */ -+ 0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07, -+/* 0x18 CAN EM -UBS -CU1 -IFS -IGS -IRS -ITB -+ -IUS */ -+ 0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, -+/* 0x20 -DS -SOS FS -WUS -BYP LF ETB ESC -+ -INP */ -+ 0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B, -+/* 0x28 -SA -SFE -SM -CSP -MFA ENQ ACK BEL -+ -SW */ -+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07, -+/* 0x30 ---- ---- SYN -IR -PP -TRN -NBS EOT */ -+ 0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04, -+/* 0x38 -SBS -IT -RFF -CU3 DC4 NAK ---- SUB */ -+ 0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A, -+/* 0x40 SP RSP ä ---- */ -+ 0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86, -+/* 0x48 . < ( + | */ -+ 0x87, 0xA4, 0x9B, 0x2E, 0x3C, 0x28, 0x2B, 0x7C, -+/* 0x50 & ---- */ -+ 0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07, -+/* 0x58 ß ! $ * ) ; */ -+ 0x8D, 0xE1, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0xAA, -+/* 0x60 - / ---- Ä ---- ---- ---- */ -+ 0x2D, 0x2F, 0x07, 0x8E, 0x07, 0x07, 0x07, 0x8F, -+/* 0x68 ---- , % _ > ? */ -+ 0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F, -+/* 0x70 --- ---- ---- ---- ---- ---- ---- */ -+ 0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, -+/* 0x78 * ` : # @ ' = " */ -+ 0x70, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22, -+/* 0x80 * a b c d e f g */ -+ 0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, -+/* 0x88 h i ---- ---- ---- */ -+ 0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1, -+/* 0x90 ° j k l m n o p */ -+ 0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, -+/* 0x98 q r ---- ---- */ -+ 0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07, -+/* 0xA0 ~ s t u v w x */ -+ 0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, -+/* 0xA8 y z ---- ---- ---- ---- */ -+ 0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07, -+/* 0xB0 ^ ---- § ---- */ -+ 0x5E, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC, -+/* 0xB8 ---- [ ] ---- ---- ---- ---- */ -+ 0xAB, 0x07, 0x5B, 0x5D, 0x07, 0x07, 0x07, 0x07, -+/* 0xC0 { A B C D E F G */ -+ 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, -+/* 0xC8 H I ---- ö ---- */ -+ 0x48, 0x49, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07, -+/* 0xD0 } J K L M N O P */ -+ 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, -+/* 0xD8 Q R ---- ü */ -+ 0x51, 0x52, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98, -+/* 0xE0 \ S T U V W X */ -+ 0x5C, 0xF6, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, -+/* 0xE8 Y Z ---- Ö ---- ---- ---- */ -+ 0x59, 0x5A, 0xFD, 0x07, 0x99, 0x07, 0x07, 0x07, -+/* 0xF0 0 1 2 3 4 5 6 7 */ -+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, -+/* 0xF8 8 9 ---- ---- Ü ---- ---- ---- */ -+ 0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07 -+}; -+ -+static unsigned char ebcdic_500[256] = { -+/* 0x00 NUL SOH STX ETX *SEL HT *RNL DEL */ -+ 0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F, -+/* 0x08 -GE -SPS -RPT VT FF CR SO SI */ -+ 0x07, 0x07, 0x07, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, -+/* 0x10 DLE DC1 DC2 DC3 -RES -NL BS -POC -+ -ENP ->LF */ -+ 0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07, -+/* 0x18 CAN EM -UBS -CU1 -IFS -IGS -IRS -ITB -+ -IUS */ -+ 0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, -+/* 0x20 -DS -SOS FS -WUS -BYP LF ETB ESC -+ -INP */ -+ 0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B, -+/* 0x28 -SA -SFE -SM -CSP -MFA ENQ ACK BEL -+ -SW */ -+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07, -+/* 0x30 ---- ---- SYN -IR -PP -TRN -NBS EOT */ -+ 0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04, -+/* 0x38 -SBS -IT -RFF -CU3 DC4 NAK ---- SUB */ -+ 0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A, -+/* 0x40 SP RSP ä ---- */ -+ 0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86, -+/* 0x48 . < ( + | */ -+ 0x87, 0xA4, 0x9B, 0x2E, 0x3C, 0x28, 0x2B, 0x7C, -+/* 0x50 & ---- */ -+ 0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07, -+/* 0x58 ß ! $ * ) ; */ -+ 0x8D, 0xE1, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0xAA, -+/* 0x60 - / ---- Ä ---- ---- ---- */ -+ 0x2D, 0x2F, 0x07, 0x8E, 0x07, 0x07, 0x07, 0x8F, -+/* 0x68 ---- , % _ > ? */ -+ 0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F, -+/* 0x70 --- ---- ---- ---- ---- ---- ---- */ -+ 0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, -+/* 0x78 * ` : # @ ' = " */ -+ 0x70, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22, -+/* 0x80 * a b c d e f g */ -+ 0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, -+/* 0x88 h i ---- ---- ---- */ -+ 0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1, -+/* 0x90 ° j k l m n o p */ -+ 0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, -+/* 0x98 q r ---- ---- */ -+ 0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07, -+/* 0xA0 ~ s t u v w x */ -+ 0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, -+/* 0xA8 y z ---- ---- ---- ---- */ -+ 0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07, -+/* 0xB0 ^ ---- § ---- */ -+ 0x5E, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC, -+/* 0xB8 ---- [ ] ---- ---- ---- ---- */ -+ 0xAB, 0x07, 0x5B, 0x5D, 0x07, 0x07, 0x07, 0x07, -+/* 0xC0 { A B C D E F G */ -+ 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, -+/* 0xC8 H I ---- ö ---- */ -+ 0x48, 0x49, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07, -+/* 0xD0 } J K L M N O P */ -+ 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, -+/* 0xD8 Q R ---- ü */ -+ 0x51, 0x52, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98, -+/* 0xE0 \ S T U V W X */ -+ 0x5C, 0xF6, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, -+/* 0xE8 Y Z ---- Ö ---- ---- ---- */ -+ 0x59, 0x5A, 0xFD, 0x07, 0x99, 0x07, 0x07, 0x07, -+/* 0xF0 0 1 2 3 4 5 6 7 */ -+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, -+/* 0xF8 8 9 ---- ---- Ü ---- ---- ---- */ -+ 0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07 -+}; -+ -+void ebcdic_to_ascii(unsigned char *target, const unsigned char *source, -+ unsigned int l) -+{ -+ unsigned char *ebc; -+ unsigned int i; -+ -+ ebc = is_zvm() ? ebcdic_037 : ebcdic_500; -+ for (i = 0; i < l; i++) -+ target[i] = ebc[source[i]]; -+} ---- /dev/null -+++ b/zipl/boot/ebcdic_conv.h -@@ -0,0 +1,21 @@ -+/* -+ * EBCDIC conversion functions -+ * -+ * Copyright IBM Corp. 2013, 2020 -+ * -+ * s390-tools is free software; you can redistribute it and/or modify -+ * it under the terms of the MIT license. See LICENSE for details. -+ * -+ */ -+ -+#ifndef EBCDIC_CONV_H -+#define EBCDIC_CONV_H -+ -+ -+#ifndef __ASSEMBLER__ -+ -+void ebcdic_to_ascii(unsigned char *target, const unsigned char *source, -+ unsigned int l); -+ -+#endif /* __ASSEMBLER__ */ -+#endif /* EBCDIC_CONV_H */ ---- a/zipl/boot/libc.c -+++ b/zipl/boot/libc.c -@@ -18,6 +18,7 @@ - - #include "error.h" - #include "sclp.h" -+#include "ebcdic.h" - - extern char __heap_start[]; - extern char __heap_stop[]; -@@ -129,24 +130,6 @@ int strncmp(const char *s1, const char * - return 0; - } - --/* -- * Convert ebcdic string to number with given base -- */ --unsigned long ebcstrtoul(char *nptr, char **endptr, int base) --{ -- unsigned long val = 0; -- -- while (ebc_isdigit(*nptr)) { -- if (val != 0) -- val *= base; -- val += *nptr - 0xf0; -- nptr++; -- } -- if (endptr) -- *endptr = (char *) nptr; -- return val; --} -- - static int skip_atoi(const char **c) - { - int i = 0; ---- a/zipl/boot/libc.h -+++ b/zipl/boot/libc.h -@@ -51,7 +51,6 @@ void *memmove(void *, const void *, unsi - void *memset(void *, int c, unsigned long); - char *strcat(char *, const char *); - int strncmp(const char *, const char *, unsigned long); --unsigned long ebcstrtoul(char *, char **, int); - int strlen(const char *); - char *strcpy(char *, const char *); - unsigned long get_zeroed_page(void); -@@ -80,28 +79,4 @@ static inline int isspace(char c) - return (c == 32) || (c >= 9 && c <= 13); - } - --static inline int ebc_isspace(char c) --{ -- return (c == 0x40) || (c == 0x05) || (c == 0x15) || (c == 0x25) || -- (c == 0x0b) || (c == 0x0c) || (c == 0x0d); --} -- --static inline int ebc_isdigit(char c) --{ -- return (c >= 0xf0) && (c <= 0xf9); --} -- --static inline int ebc_isupper(char c) --{ -- return (c >= 0xC1 && c <= 0xC9) || (c >= 0xD1 && c <= 0xD9) || -- (c >= 0xE2 && c <= 0xE9); --} -- --static inline char ebc_tolower(char c) --{ -- if (ebc_isupper(c)) -- c -= 0x40; -- return c; --} -- - #endif /* LIBC_H */ ---- a/zipl/boot/menu.c -+++ b/zipl/boot/menu.c -@@ -12,6 +12,7 @@ - #include "libc.h" - #include "menu.h" - #include "sclp.h" -+#include "ebcdic.h" - - static const char *msg_econfig = "Error: undefined configuration\n"; - -@@ -55,8 +56,8 @@ static int menu_read(void) - /* input under zVM needs to be converted to lower case */ - if (is_zvm()) - for (i = 0; i < count; i++) -- temp_area[i] = ebc_tolower(temp_area[i]); -- value = ebcstrtoul((char *)temp_area, &endptr, 10); -+ temp_area[i] = ebcdic_tolower(temp_area[i]); -+ value = ebcdic_strtoul((char *)temp_area, &endptr, 10); - - if ((endptr != temp_area) && (value < BOOT_MENU_ENTRIES - 1) && - (__stage2_params.config[value] != 0)) { -@@ -112,7 +113,7 @@ static int menu_param(unsigned long *val - int i; - - if (!sclp_param(loadparm)) -- *value = ebcstrtoul(loadparm, &endptr, 10); -+ *value = ebcdic_strtoul(loadparm, &endptr, 10); - - /* got number, done */ - if (endptr != loadparm) -@@ -121,7 +122,7 @@ static int menu_param(unsigned long *val - /* no number, check for keyword */ - i = 0; - /* skip leading whitespaces */ -- while ((i < PARAM_SIZE) && ebc_isspace(loadparm[i])) -+ while ((i < PARAM_SIZE) && ecbdic_isspace(loadparm[i])) - i++; - - if (!strncmp(&loadparm[i], "PROMPT", 6)) { ---- a/zipl/boot/stage3.c -+++ b/zipl/boot/stage3.c -@@ -12,9 +12,12 @@ - #include "libc.h" - #include "boot/sigp.h" - #include "boot/s390.h" -+#include "boot/sigp.h" - #include "stage3.h" - #include "error.h" - #include "zipl.h" -+#include "ebcdic.h" -+#include "ebcdic_conv.h" - - #define for_each_rb_entry(entry, rb) \ - for (entry = rb->entries; \ -@@ -24,159 +27,6 @@ - static const char *msg_sipl_inval = "Secure boot failure: invalid load address"; - static const char *msg_sipl_unverified = "Secure boot failure: unverified load address"; - --static unsigned char ebc_037[256] = { --/* 0x00 NUL SOH STX ETX *SEL HT *RNL DEL */ -- 0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F, --/* 0x08 -GE -SPS -RPT VT FF CR SO SI */ -- 0x07, 0x07, 0x07, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, --/* 0x10 DLE DC1 DC2 DC3 -RES -NL BS -POC -- -ENP ->LF */ -- 0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07, --/* 0x18 CAN EM -UBS -CU1 -IFS -IGS -IRS -ITB -- -IUS */ -- 0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, --/* 0x20 -DS -SOS FS -WUS -BYP LF ETB ESC -- -INP */ -- 0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B, --/* 0x28 -SA -SFE -SM -CSP -MFA ENQ ACK BEL -- -SW */ -- 0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07, --/* 0x30 ---- ---- SYN -IR -PP -TRN -NBS EOT */ -- 0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04, --/* 0x38 -SBS -IT -RFF -CU3 DC4 NAK ---- SUB */ -- 0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A, --/* 0x40 SP RSP ä ---- */ -- 0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86, --/* 0x48 . < ( + | */ -- 0x87, 0xA4, 0x9B, 0x2E, 0x3C, 0x28, 0x2B, 0x7C, --/* 0x50 & ---- */ -- 0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07, --/* 0x58 ß ! $ * ) ; */ -- 0x8D, 0xE1, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0xAA, --/* 0x60 - / ---- Ä ---- ---- ---- */ -- 0x2D, 0x2F, 0x07, 0x8E, 0x07, 0x07, 0x07, 0x8F, --/* 0x68 ---- , % _ > ? */ -- 0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F, --/* 0x70 --- ---- ---- ---- ---- ---- ---- */ -- 0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, --/* 0x78 * ` : # @ ' = " */ -- 0x70, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22, --/* 0x80 * a b c d e f g */ -- 0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, --/* 0x88 h i ---- ---- ---- */ -- 0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1, --/* 0x90 ° j k l m n o p */ -- 0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, --/* 0x98 q r ---- ---- */ -- 0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07, --/* 0xA0 ~ s t u v w x */ -- 0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, --/* 0xA8 y z ---- ---- ---- ---- */ -- 0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07, --/* 0xB0 ^ ---- § ---- */ -- 0x5E, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC, --/* 0xB8 ---- [ ] ---- ---- ---- ---- */ -- 0xAB, 0x07, 0x5B, 0x5D, 0x07, 0x07, 0x07, 0x07, --/* 0xC0 { A B C D E F G */ -- 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, --/* 0xC8 H I ---- ö ---- */ -- 0x48, 0x49, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07, --/* 0xD0 } J K L M N O P */ -- 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, --/* 0xD8 Q R ---- ü */ -- 0x51, 0x52, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98, --/* 0xE0 \ S T U V W X */ -- 0x5C, 0xF6, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, --/* 0xE8 Y Z ---- Ö ---- ---- ---- */ -- 0x59, 0x5A, 0xFD, 0x07, 0x99, 0x07, 0x07, 0x07, --/* 0xF0 0 1 2 3 4 5 6 7 */ -- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, --/* 0xF8 8 9 ---- ---- Ü ---- ---- ---- */ -- 0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07 --}; -- --static unsigned char ebc_500[256] = { --/* 0x00 NUL SOH STX ETX *SEL HT *RNL DEL */ -- 0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F, --/* 0x08 -GE -SPS -RPT VT FF CR SO SI */ -- 0x07, 0x07, 0x07, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, --/* 0x10 DLE DC1 DC2 DC3 -RES -NL BS -POC -- -ENP ->LF */ -- 0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07, --/* 0x18 CAN EM -UBS -CU1 -IFS -IGS -IRS -ITB -- -IUS */ -- 0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, --/* 0x20 -DS -SOS FS -WUS -BYP LF ETB ESC -- -INP */ -- 0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B, --/* 0x28 -SA -SFE -SM -CSP -MFA ENQ ACK BEL -- -SW */ -- 0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07, --/* 0x30 ---- ---- SYN -IR -PP -TRN -NBS EOT */ -- 0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04, --/* 0x38 -SBS -IT -RFF -CU3 DC4 NAK ---- SUB */ -- 0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A, --/* 0x40 SP RSP ä ---- */ -- 0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86, --/* 0x48 . < ( + | */ -- 0x87, 0xA4, 0x9B, 0x2E, 0x3C, 0x28, 0x2B, 0x7C, --/* 0x50 & ---- */ -- 0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07, --/* 0x58 ß ! $ * ) ; */ -- 0x8D, 0xE1, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0xAA, --/* 0x60 - / ---- Ä ---- ---- ---- */ -- 0x2D, 0x2F, 0x07, 0x8E, 0x07, 0x07, 0x07, 0x8F, --/* 0x68 ---- , % _ > ? */ -- 0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F, --/* 0x70 --- ---- ---- ---- ---- ---- ---- */ -- 0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, --/* 0x78 * ` : # @ ' = " */ -- 0x70, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22, --/* 0x80 * a b c d e f g */ -- 0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, --/* 0x88 h i ---- ---- ---- */ -- 0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1, --/* 0x90 ° j k l m n o p */ -- 0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, --/* 0x98 q r ---- ---- */ -- 0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07, --/* 0xA0 ~ s t u v w x */ -- 0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, --/* 0xA8 y z ---- ---- ---- ---- */ -- 0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07, --/* 0xB0 ^ ---- § ---- */ -- 0x5E, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC, --/* 0xB8 ---- [ ] ---- ---- ---- ---- */ -- 0xAB, 0x07, 0x5B, 0x5D, 0x07, 0x07, 0x07, 0x07, --/* 0xC0 { A B C D E F G */ -- 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, --/* 0xC8 H I ---- ö ---- */ -- 0x48, 0x49, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07, --/* 0xD0 } J K L M N O P */ -- 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, --/* 0xD8 Q R ---- ü */ -- 0x51, 0x52, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98, --/* 0xE0 \ S T U V W X */ -- 0x5C, 0xF6, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, --/* 0xE8 Y Z ---- Ö ---- ---- ---- */ -- 0x59, 0x5A, 0xFD, 0x07, 0x99, 0x07, 0x07, 0x07, --/* 0xF0 0 1 2 3 4 5 6 7 */ -- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, --/* 0xF8 8 9 ---- ---- Ü ---- ---- ---- */ -- 0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07 --}; -- --static void ebcdic_to_ascii(unsigned char *target, unsigned char *source, -- unsigned int l) --{ -- unsigned char *ebc; -- unsigned int i; -- -- ebc = is_zvm() ? ebc_037 : ebc_500; -- for (i = 0; i < l; i++) -- target[i] = ebc[source[i]]; --} -- - static inline void __noreturn start_kernel(void) - { - struct psw_t *psw = &S390_lowcore.program_new_psw; diff --git a/s390-tools-sles15sp2-39-zipl-sclp-add-macros-for-the-control-program-masks.patch b/s390-tools-sles15sp2-39-zipl-sclp-add-macros-for-the-control-program-masks.patch deleted file mode 100644 index 633d5c4..0000000 --- a/s390-tools-sles15sp2-39-zipl-sclp-add-macros-for-the-control-program-masks.patch +++ /dev/null @@ -1,79 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] zipl/sclp: add macros for the control-program masks -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: 303a3707e2e59e0ad581876db426a52fffa606b0 -Problem-ID: VS1804 - -Upstream-Description: - - zipl/sclp: add macros for the control-program masks - - Add macros for the control-program masks and use them. - - Reviewed-by: Philipp Rudo - Reviewed-by: Stefan Haberland - Signed-off-by: Marc Hartmayer - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - zipl/boot/sclp.c | 16 ++++++++-------- - zipl/boot/sclp.h | 6 ++++++ - 2 files changed, 14 insertions(+), 8 deletions(-) - ---- a/zipl/boot/sclp.c -+++ b/zipl/boot/sclp.c -@@ -126,20 +126,20 @@ int sclp_setup(int initialise) - - switch (initialise) { - case SCLP_INIT: -- sccb->receive_mask = 0x80000000; -- sccb->send_mask = 0x40000000; -+ sccb->receive_mask = SCLP_EVENT_MASK_OPCMD; -+ sccb->send_mask = SCLP_EVENT_MASK_MSG; - break; - case SCLP_DISABLE: -- sccb->receive_mask = 0x0; -- sccb->send_mask = 0x0; -+ sccb->receive_mask = SCLP_EVENT_MASK_DISABLE; -+ sccb->send_mask = SCLP_EVENT_MASK_DISABLE; - break; - case SCLP_HSA_INIT: -- sccb->receive_mask = 0x0; -- sccb->send_mask = 0x40000010; -+ sccb->receive_mask = SCLP_EVENT_MASK_DISABLE; -+ sccb->send_mask = SCLP_EVENT_MASK_MSG | SCLP_EVENT_MASK_SDIAS; - break; - case SCLP_HSA_INIT_ASYNC: -- sccb->receive_mask = 0x00000010; -- sccb->send_mask = 0x40000010; -+ sccb->receive_mask = SCLP_EVENT_MASK_SDIAS; -+ sccb->send_mask = SCLP_EVENT_MASK_MSG | SCLP_EVENT_MASK_SDIAS; - break; - } - ---- a/zipl/boot/sclp.h -+++ b/zipl/boot/sclp.h -@@ -28,6 +28,12 @@ - #define SCLP_CMD_READ_INFO2 0x00020001 - #define SCLP_CMD_READ_DATA 0x00770005 - -+/* SCLP event masks */ -+#define SCLP_EVENT_MASK_DISABLE 0x00000000 -+#define SCLP_EVENT_MASK_SDIAS 0x00000010 -+#define SCLP_EVENT_MASK_MSG 0x40000000 -+#define SCLP_EVENT_MASK_OPCMD 0x80000000 -+ - #define PSW_EXT_MASK 0x00080000ULL - #define PSW_EXT_ADDR 0x80000000ULL - #define PSW_WAIT_MASK 0x010a0000ULL diff --git a/s390-tools-sles15sp2-40-zipl-sclp-add-sclp_print_ascii.patch b/s390-tools-sles15sp2-40-zipl-sclp-add-sclp_print_ascii.patch deleted file mode 100644 index ff94983..0000000 --- a/s390-tools-sles15sp2-40-zipl-sclp-add-sclp_print_ascii.patch +++ /dev/null @@ -1,163 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] zipl/sclp: add `sclp_print_ascii` -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: f99560f734e8101a0e8195d73e3350d9211335b8 -Problem-ID: VS1804 - -Upstream-Description: - - zipl/sclp: add `sclp_print_ascii` - - Add `sclp_print_ascii` function that can be used to print output on - the SCLP ASCII console. This would increase the size of the - loaders (e.g. eckd2.bin and fba2.bin) and therefore might break the - compilation. In order to avoid that add a macro 'ENABLE_SCLP_ASCII' - which must be defined by the users of the `sclp_print_ascii` function. - - Reviewed-by: Philipp Rudo - Reviewed-by: Stefan Haberland - Signed-off-by: Marc Hartmayer - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - zipl/boot/sclp.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ - zipl/boot/sclp.h | 20 +++++++++++++++++++- - 2 files changed, 69 insertions(+), 1 deletion(-) - ---- a/zipl/boot/sclp.c -+++ b/zipl/boot/sclp.c -@@ -13,6 +13,10 @@ - #include "error.h" - #include "boot/s390.h" - #include "sclp.h" -+#include "ebcdic.h" -+#ifdef ENABLE_SCLP_ASCII -+# include "ebcdic_conv.h" -+#endif /* ENABLE_SCLP_ASCII */ - - /* Perform service call. Return 0 on success, non-zero otherwise. */ - static int sclp_service_call(unsigned int command, void *sccb) -@@ -133,6 +137,10 @@ int sclp_setup(int initialise) - sccb->receive_mask = SCLP_EVENT_MASK_DISABLE; - sccb->send_mask = SCLP_EVENT_MASK_DISABLE; - break; -+ case SCLP_LINE_ASCII_INIT: -+ sccb->receive_mask = SCLP_EVENT_MASK_DISABLE; -+ sccb->send_mask = SCLP_EVENT_MASK_MSG | SCLP_EVENT_MASK_ASCII; -+ break; - case SCLP_HSA_INIT: - sccb->receive_mask = SCLP_EVENT_MASK_DISABLE; - sccb->send_mask = SCLP_EVENT_MASK_MSG | SCLP_EVENT_MASK_SDIAS; -@@ -161,6 +169,48 @@ out_free_page: - return rc; - } - -+#ifdef ENABLE_SCLP_ASCII -+/* Content of @buffer must be EBCDIC encoded. The function used for -+ * the conversion `ebcdic_to_ascii` differentiates whether the code -+ * runs on z/VM or not and then selects the appropriate EBCDIC -+ * coding. -+ */ -+int sclp_print_ascii(const char *buffer) -+{ -+ struct write_sccb *sccb = NULL; -+ int rc, str_len = strlen(buffer); -+ unsigned long data_len = str_len + 1; -+ -+ /* don't overflow the sccb buffer */ -+ if (data_len > SCCB_MAX_DATA_LEN) -+ data_len = SCCB_MAX_DATA_LEN; -+ -+ sccb = (void *)get_zeroed_page(); -+ sccb->header.length = sizeof(struct write_sccb) - sizeof(struct mdb) -+ + data_len; -+ sccb->header.function_code = SCLP_FC_NORMAL_WRITE; -+ sccb->msg_buf.header.length = sizeof(struct msg_buf) - sizeof(struct mdb) -+ + data_len; -+ sccb->msg_buf.header.type = SCLP_EVENT_DATA_ASCII; -+ sccb->msg_buf.header.flags = 0; -+ ebcdic_to_ascii(sccb->msg_buf.data, -+ (const unsigned char *)buffer, -+ data_len - 1); -+ sccb->msg_buf.data[data_len - 1] = '\0'; -+ -+ /* SCLP command for write data */ -+ rc = start_sclp(SCLP_CMD_WRITE_DATA, sccb); -+ if (rc || sccb->header.response_code != 0x20) { -+ rc = 1; -+ goto out_free_page; -+ } -+ rc = 0; -+out_free_page: -+ free_page((unsigned long) sccb); -+ return rc; -+} -+#endif /* ENABLE_SCLP_ASCII */ -+ - int sclp_print(char *buffer) - { - struct write_sccb *sccb; ---- a/zipl/boot/sclp.h -+++ b/zipl/boot/sclp.h -@@ -28,9 +28,16 @@ - #define SCLP_CMD_READ_INFO2 0x00020001 - #define SCLP_CMD_READ_DATA 0x00770005 - -+/* SCLP function codes */ -+#define SCLP_FC_NORMAL_WRITE 0 -+ -+/* SCLP event data types */ -+#define SCLP_EVENT_DATA_ASCII 0x1a -+ - /* SCLP event masks */ - #define SCLP_EVENT_MASK_DISABLE 0x00000000 - #define SCLP_EVENT_MASK_SDIAS 0x00000010 -+#define SCLP_EVENT_MASK_ASCII 0x00000040 - #define SCLP_EVENT_MASK_MSG 0x40000000 - #define SCLP_EVENT_MASK_OPCMD 0x80000000 - -@@ -46,6 +53,11 @@ - #define SCLP_DISABLE 0x1 - #define SCLP_HSA_INIT 0x2 - #define SCLP_HSA_INIT_ASYNC 0x3 -+#define SCLP_LINE_ASCII_INIT 0x4 -+ -+#define SCCB_SIZE PAGE_SIZE -+#define SCCB_MAX_DATA_LEN (SCCB_SIZE - sizeof(struct sccb_header) \ -+ - sizeof(struct evbuf_header)) - - typedef uint32_t sccb_mask_t; - -@@ -114,7 +126,10 @@ struct mdb { - - struct msg_buf { - struct evbuf_header header; -- struct mdb mdb; -+ union { -+ struct mdb mdb; -+ uint8_t data[0]; -+ }; - } __packed; - - struct write_sccb { -@@ -164,6 +179,9 @@ struct read_sccb { - int start_sclp(unsigned int, void *); - int sclp_setup(int); - int sclp_print(char *); -+# ifdef ENABLE_SCLP_ASCII -+int sclp_print_ascii(const char *); -+# endif /* ENABLE_SCLP_ASCII */ - int sclp_param(char *); - int sclp_read(unsigned long, void *, int *); - int sclp_read_info(struct read_info_sccb *sccb); diff --git a/s390-tools-sles15sp2-41-zipl-libc-printf-print-on-linemode-and-ASCII-console.patch b/s390-tools-sles15sp2-41-zipl-libc-printf-print-on-linemode-and-ASCII-console.patch deleted file mode 100644 index 38499c0..0000000 --- a/s390-tools-sles15sp2-41-zipl-libc-printf-print-on-linemode-and-ASCII-console.patch +++ /dev/null @@ -1,47 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] zipl/libc: printf: print on linemode and ASCII console -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: e51663bbca8770c1f7986dac47a59193dbf96010 -Problem-ID: VS1804 - -Upstream-Description: - - zipl/libc: printf: print on linemode and ASCII console - - ... if the `ENABLE_SCLP_ASCII` macro is defined. - - Reviewed-by: Philipp Rudo - Reviewed-by: Stefan Haberland - Signed-off-by: Marc Hartmayer - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - zipl/boot/libc.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - ---- a/zipl/boot/libc.c -+++ b/zipl/boot/libc.c -@@ -406,8 +406,11 @@ void printf(const char *fmt, ...) - buf[LINE_LENGTH - 2] = '.'; - buf[LINE_LENGTH - 3] = '.'; - } -- sclp_print(buf); - va_end(va); -+ sclp_print(buf); -+#ifdef ENABLE_SCLP_ASCII -+ sclp_print_ascii(buf); -+#endif /* ENABLE_SCLP_ASCII */ - } - - /* diff --git a/s390-tools-sles15sp2-42-Consolidate-ALIGN-__ALIGN_MASK-ARRAY_SIZE-macros.patch b/s390-tools-sles15sp2-42-Consolidate-ALIGN-__ALIGN_MASK-ARRAY_SIZE-macros.patch deleted file mode 100644 index ceec37a..0000000 --- a/s390-tools-sles15sp2-42-Consolidate-ALIGN-__ALIGN_MASK-ARRAY_SIZE-macros.patch +++ /dev/null @@ -1,134 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] Consolidate `ALIGN, __ALIGN_MASK, ARRAY_SIZE` macros -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: 67aef9bbf3b5d18c70e8c4a45734bcb6d6744a8c -Problem-ID: VS1804 - -Upstream-Description: - - Consolidate `ALIGN, __ALIGN_MASK, ARRAY_SIZE` macros - - Consolidate `ALIGN, __ALIGN_MASK, ARRAY_SIZE` macros and add them to - lib/zt_common.h. While at it, adapt coding style. - - Reviewed-by: Philipp Rudo - Reviewed-by: Stefan Haberland - Signed-off-by: Marc Hartmayer - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - cmsfs-fuse/dasd.c | 1 + - cmsfs-fuse/helper.h | 2 -- - include/lib/zt_common.h | 4 ++++ - zconf/qeth/misc.h | 2 -- - zdev/include/misc.h | 2 +- - zdump/zg.c | 2 +- - zdump/zg.h | 3 --- - zipl/include/zipl.h | 4 ---- - 8 files changed, 7 insertions(+), 13 deletions(-) - ---- a/cmsfs-fuse/dasd.c -+++ b/cmsfs-fuse/dasd.c -@@ -19,6 +19,7 @@ - #include - #include - -+#include "lib/zt_common.h" - #include "cmsfs-fuse.h" - #include "edf.h" - #include "helper.h" ---- a/cmsfs-fuse/helper.h -+++ b/cmsfs-fuse/helper.h -@@ -49,6 +49,4 @@ extern FILE *logfile; - fprintf(stderr, COMP "Warning, " __VA_ARGS__); \ - } while (0) - --#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) -- - #endif ---- a/include/lib/zt_common.h -+++ b/include/lib/zt_common.h -@@ -44,6 +44,10 @@ - # define STATIC_ASSERT(test) - #endif - -+#define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a) - 1) -+#define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask)) -+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) -+ - #define RELEASE_STRING STRINGIFY (S390_TOOLS_RELEASE) - #define TOOLS_LIBDIR STRINGIFY (S390_TOOLS_LIBDIR) - #define TOOLS_SYSCONFDIR STRINGIFY (S390_TOOLS_SYSCONFDIR) ---- a/zconf/qeth/misc.h -+++ b/zconf/qeth/misc.h -@@ -12,8 +12,6 @@ - - #include - --#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) -- - char *misc_link_target(const char *fmt, ...); - bool misc_str_in_list(const char *str, const char *strings[], int array_size); - int misc_argz_add_from_file(char **argz, size_t *argz_len, ---- a/zdev/include/misc.h -+++ b/zdev/include/misc.h -@@ -15,10 +15,10 @@ - #include - #include - -+#include "lib/zt_common.h" - #include "lib/util_list.h" - #include "exit_code.h" - --#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) - #define SCOPE_ACTIVE(x) ((x) & config_active ? 1 : 0) - #define SCOPE_PERSISTENT(x) ((x) & config_persistent ? 1 : 0) - #define SCOPE_AUTOCONF(x) ((x) & config_autoconf ? 1 : 0) ---- a/zdump/zg.c -+++ b/zdump/zg.c -@@ -432,7 +432,7 @@ char *zg_devnode_create(dev_t dev) - char *file_path; - unsigned int i; - -- for (i = 0; i < ARRAY_ELEMENT_CNT(dir_vec); i++) { -+ for (i = 0; i < ARRAY_SIZE(dir_vec); i++) { - if (dir_vec[i] == NULL) - continue; - file_path = devnode_create_dir(dir_vec[i], dev); ---- a/zdump/zg.h -+++ b/zdump/zg.h -@@ -122,10 +122,7 @@ do { \ - * Misc - */ - #define PAGE_SIZE 4096UL --#define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a)-1) --#define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask)) - #define PAGE_ALIGN(addr) ALIGN(addr, PAGE_SIZE) --#define ARRAY_ELEMENT_CNT(x) (sizeof(x) / sizeof(x[0])) - #define ROUNDUP(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) - - static inline u32 zg_csum_partial(const void *buf, int len, u32 sum) ---- a/zipl/include/zipl.h -+++ b/zipl/include/zipl.h -@@ -62,10 +62,6 @@ typedef uint64_t address_t; - * resulting return code or 0. */ - #define DRY_RUN_FUNC(x) (dry_run ? 0 : (x)) - --#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1) --#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask)) --#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) -- - extern int verbose; - extern int interactive; - extern int dry_run; diff --git a/s390-tools-sles15sp2-43-genprotimg-boot-initial-bootloader-support.patch b/s390-tools-sles15sp2-43-genprotimg-boot-initial-bootloader-support.patch deleted file mode 100644 index 5270fc7..0000000 --- a/s390-tools-sles15sp2-43-genprotimg-boot-initial-bootloader-support.patch +++ /dev/null @@ -1,803 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] genprotimg: boot: initial bootloader support -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: 3356d6f4facd748f8f5cf24ffc5056db3e915f2c -Problem-ID: VS1804 - -Upstream-Description: - - genprotimg: boot: initial bootloader support - - Add a boot loader for protected virtualization (PV) that can be - combined with a kernel/initrd/parmfile to form a single bootable file. - This file must be constructed in a way that it can be used (1) for a - QEMU direct kernel boot and (2) it can be zipl'ed by the normal, - unmodified zipl program. - - This new boot loader consists of two parts: - - 1. stage3a boot loader (cleartext), this loader is responsible for - the transition into the protected mode by doing diag308 subcode 8 - and 10 calls. - - 2. stage3b boot loader (encrypted), this loader is very similar to the - normal zipl stage3 boot loader. It will be loaded by the Ultravisor - after the successful transition into protected mode. Like the zipl - stage3 boot loader it moves the kernel and patches in the values - for initrd and parmline. - - The requirements for (1) and (2) result in the following constraints: - - 1. It must be possible to place stage3a and stage3b at a location >= - 0x10000 because the zipl stage3 loader zeroes out everything at - addresses lower than 0x10000 of the image. - - 2. As the stage3 loader of zipl assumes that the passed kernel image - looks like a normal kernel image, the zipl stage3 loader modifies the - content at the memory area 0x10400 - 0x10800, therefore we leave this - area unused in our stage3a loader. - - 3. The default entry address used by the zipl stage3 loader is 0x10000 - so we add a simple branch to 0x11000 at 0x10000 so the zipl stage3 - loader can modify the area 0x10400 - 0x10800 without affecting the - stage3a loader. - - The stage3b loader is linked at address 0x9000, therefore it will not - work at another address. The relocation support for the stage3b - loader, so that it can be placed at addresses != 0x9000, is added in - the next patch. This loader with relocation support has the name - 'stage3b_reloc'. - - The memory layout of the single bootable file looks like: - - +-----------------------+-----------+------------------------+ - |Start |End |Use | - +=======================+===========+========================+ - |0 |0x7 |Short PSW, starting | - | | |instruction at 0x11000 | - +-----------------------+-----------+------------------------+ - |0x10000 |0x10012 |Branch to 0x11000 | - +-----------------------+-----------+------------------------+ - |0x10013 |0x10fff |Left intentionally | - | | |unused | - +-----------------------+-----------+------------------------+ - |0x11000 |0x12fff |Stage3a | - +-----------------------+-----------+------------------------+ - |0x13000 |0x13fff |IPIB used as argument | - | | |for the diag308 call | - +-----------------------+-----------+------------------------+ - |0x14000 |0x1[45]fff |UV header used for the | - | | |diag308 call (size can | - | | |be either 1 or 2 pages) | - +-----------------------+-----------+------------------------+ - |NEXT_PAGE_ALIGNED_ADDR | |Encrypted Kernel | - +-----------------------+-----------+------------------------+ - |NEXT_PAGE_ALIGNED_ADDR | |Encrypted Cmdline | - +-----------------------+-----------+------------------------+ - |NEXT_PAGE_ALIGNED_ADDR | |Encrypted Initrd | - +-----------------------+-----------+------------------------+ - |NEXT_PAGE_ALIGNED_ADDR | |Encrypted Stage3b_reloc | - +-----------------------+-----------+------------------------+ - - Reviewed-by: Philipp Rudo - Signed-off-by: Marc Hartmayer - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - genprotimg/boot/.gitignore | 3 - genprotimg/boot/Makefile | 83 +++++++++++++++++++++++++++ - genprotimg/boot/common_memory_layout.h | 25 ++++++++ - genprotimg/boot/head.S | 29 +++++++++ - genprotimg/boot/stage3a.c | 62 ++++++++++++++++++++ - genprotimg/boot/stage3a.h | 34 +++++++++++ - genprotimg/boot/stage3a.lds | 101 +++++++++++++++++++++++++++++++++ - genprotimg/boot/stage3a_init.S | 26 ++++++++ - genprotimg/boot/stage3b.c | 77 +++++++++++++++++++++++++ - genprotimg/boot/stage3b.h | 38 ++++++++++++ - genprotimg/boot/stage3b.lds | 87 ++++++++++++++++++++++++++++ - include/boot/ipl.h | 25 ++++++++ - include/boot/s390.h | 22 +++++-- - zipl/boot/error.h | 6 + - 14 files changed, 613 insertions(+), 5 deletions(-) - ---- /dev/null -+++ b/genprotimg/boot/.gitignore -@@ -0,0 +1,3 @@ -+*.elf -+*.bin -+*.d ---- /dev/null -+++ b/genprotimg/boot/Makefile -@@ -0,0 +1,83 @@ -+# Common definitions -+include ../../common.mak -+ -+ZIPL_DIR := $(rootdir)/zipl -+ZIPL_BOOT_DIR := $(ZIPL_DIR)/boot -+ -+INCLUDE_PATHS := $(ZIPL_BOOT_DIR) $(ZIPL_DIR)/include $(rootdir)/include -+INCLUDE_PARMS := $(addprefix -I,$(INCLUDE_PATHS)) -+ -+ALL_CFLAGS := $(NO_PIE_CFLAGS) -Os -g \ -+ $(INCLUDE_PARMS) \ -+ -DENABLE_SCLP_ASCII=1 \ -+ -DS390_TOOLS_RELEASE=$(S390_TOOLS_RELEASE) \ -+ -fno-builtin -ffreestanding -fno-asynchronous-unwind-tables \ -+ -fno-delete-null-pointer-checks \ -+ -fexec-charset=IBM1047 -m64 -mpacked-stack \ -+ -mstack-size=4096 -mstack-guard=128 -msoft-float \ -+ -Wall -Wformat-security -Wextra -Werror -+ -+FILES := stage3a.bin stage3b.bin -+ -+ZIPL_SRCS_C := libc.c ebcdic.c ebcdic_conv.c sclp.c -+ZIPL_SRCS_ASM := entry.S -+ -+ZIPL_OBJS_C := $(ZIPL_SRCS_C:%.c=%.o) -+ZIPL_OBJS_ASM := $(ZIPL_SRCS_ASM:%.S=%.o) -+ZIPL_OBJS := $(ZIPL_OBJS_C) $(ZIPL_OBJS_ASM) -+ -+ -+all: $(FILES) -+ -+# Prevent make from using some default rules... -+%: %.S -+ -+%.o: %.S Makefile -+ $(CC) $(ALL_CFLAGS) -c -o $@ $< -+ -+%.o: %.c Makefile -+ $(CC) $(ALL_CFLAGS) -c -o $@ $< -+ -+ -+# Special rules for zipl object files -+$(ZIPL_OBJS_C): %.o : $(ZIPL_BOOT_DIR)/%.c -+ $(CC) $(ALL_CFLAGS) -c -o $@ $< -+ -+$(ZIPL_OBJS_ASM): %.o : $(ZIPL_BOOT_DIR)/%.S -+ $(CC) $(ALL_CFLAGS) -c -o $@ $< -+ -+dependencies_zipl_c := $(ZIPL_SRCS_C:%.c=.%.o.d) -+ -+$(dependencies_zipl_c): .%.o.d : $(ZIPL_BOOT_DIR)/%.c -+ $(CC_SILENT) -MM $(ALL_CPPFLAGS) $(ALL_CFLAGS) $< > $@ -+ -+ifneq ($(MAKECMDGOALS),clean) -+-include $(dependencies_zipl_c) -+endif -+ -+ -+stage3a.elf: head.o stage3a_init.o stage3a.o stage3a.lds $(ZIPL_OBJS) -+stage3b.elf: head.o stage3b.o stage3b.lds $(ZIPL_OBJS) -+ -+%.elf: %.o -+ case $* in \ -+ stage3a) SFLAGS="$(NO_PIE_LINKFLAGS) -nostdlib -Wl,-T,stage3a.lds";; \ -+ stage3b) SFLAGS="$(NO_PIE_LINKFLAGS) -nostdlib -Wl,-T,stage3b.lds";; \ -+ esac; \ -+ $(LINK) $$SFLAGS -m64 $(filter %.o, $^) -o $@ -+ @chmod a-x $@ -+ -+%.bin: %.elf -+ $(OBJCOPY) -O binary \ -+ --only-section=.text* \ -+ --only-section=.ex_table* \ -+ --only-section=.fixup* \ -+ --only-section=.data* \ -+ --only-section=.rodata* \ -+ $< $@ -+ @chmod a-x $@ -+ -+clean: -+ rm -f *.o *.elf *.bin *.map .*.d -+ -+.PHONY: all clean ---- /dev/null -+++ b/genprotimg/boot/common_memory_layout.h -@@ -0,0 +1,25 @@ -+/* -+ * Common memory layout for stage3a and stage3b bootloader. -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * s390-tools is free software; you can redistribute it and/or modify -+ * it under the terms of the MIT license. See LICENSE for details. -+ */ -+ -+#ifndef COMMON_MEMORY_LAYOUT_H -+#define COMMON_MEMORY_LAYOUT_H -+ -+#include "boot/loaders_layout.h" -+ -+#define STACK_ADDRESS STAGE3_STACK_ADDRESS -+#define STACK_SIZE STAGE3_STACK_SIZE -+ -+#define HEAP_ADDRESS STAGE3_HEAP_ADDRESS -+#define HEAP_SIZE STAGE3_HEAP_SIZE -+ -+ -+#ifndef __ASSEMBLER__ -+ -+#endif /* __ASSEMBLER__ */ -+#endif /* COMMON_MEMORY_LAYOUT_H */ ---- /dev/null -+++ b/genprotimg/boot/head.S -@@ -0,0 +1,29 @@ -+/* -+ * Entry code for stage 3a boot loader -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * 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 "common_memory_layout.h" -+ -+#include "boot/s390.h" -+#include "boot/sigp.h" -+ -+.section .text.start -+.globl _start -+_start: -+ /* Might be called after a diag308 so better set -+ * architecture and addressing mode -+ */ -+ lhi %r1, 1 -+ sigp %r1, %r0, SIGP_SET_ARCHITECTURE -+ sam64 -+ -+ /* Initialize stack */ -+ lgfi %r15, STACK_ADDRESS + STACK_SIZE - STACK_FRAME_OVERHEAD -+ brasl %r14, initialize -+.previous ---- /dev/null -+++ b/genprotimg/boot/stage3a.c -@@ -0,0 +1,62 @@ -+/* -+ * Main program for stage3a bootloader -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * 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 "libc.h" -+#include "stage3a.h" -+ -+#include "lib/zt_common.h" -+#include "boot/s390.h" -+#include "boot/ipl.h" -+#include "sclp.h" -+#include "error.h" -+ -+ -+static volatile struct stage3a_args __section(".loader_parms") loader_parms; -+ -+void __noreturn start(void) -+{ -+ int rc; -+ volatile struct stage3a_args *args = &loader_parms; -+ /* calculate the IPIB memory address */ -+ struct ipl_parameter_block *ipib = (void *)((uint64_t)args + args->ipib_offs); -+ -+ /* Calculate the PV header memory address and set it and its -+ * size in the IPIB. This allows the PV header to be position -+ * independent. -+ */ -+ ipib->pv.pv_hdr_addr = (uint64_t)args + args->hdr_offs; -+ ipib->pv.pv_hdr_size = args->hdr_size; -+ -+ /* set up ASCII and line-mode */ -+ sclp_setup(SCLP_LINE_ASCII_INIT); -+ -+ /* test if Secure Execution Unpack facility is available */ -+ stfle(S390_lowcore.stfle_fac_list, -+ ARRAY_SIZE(S390_lowcore.stfle_fac_list)); -+ rc = test_facility(UNPACK_FACILITY); -+ if (rc == 0) -+ panic(ENOPV, "Secure unpack facility is not available\n"); -+ -+ rc = diag308(DIAG308_SET_PV, ipib); -+ if (rc != DIAG308_RC_OK) -+ panic(EPV, "Protected boot setup has failed: 0x%x\n", rc); -+ -+ rc = diag308(DIAG308_UNPACK_PV, 0x0); -+ if (rc != DIAG308_RC_OK) { -+ sclp_setup(SCLP_LINE_ASCII_INIT); -+ panic(EPV, "Protected boot has failed: 0x%x\n", rc); -+ } -+ -+ while (1) -+ ; -+} -+ -+void panic_notify(unsigned long UNUSED(rc)) -+{ -+} ---- /dev/null -+++ b/genprotimg/boot/stage3a.h -@@ -0,0 +1,34 @@ -+/* -+ * Main program for stage3a bootloader. -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * s390-tools is free software; you can redistribute it and/or modify -+ * it under the terms of the MIT license. See LICENSE for details. -+ */ -+ -+#ifndef STAGE3A_H -+#define STAGE3A_H -+ -+#include "lib/zt_common.h" -+#include "boot/loaders_layout.h" -+ -+#define STAGE3A_INIT_ENTRY IMAGE_ENTRY -+#define STAGE3A_ENTRY (STAGE3A_INIT_ENTRY + _AC(0x1000, UL)) -+#define STAGE3A_LOAD_ADDRESS IMAGE_LOAD_ADDRESS -+ -+ -+#ifndef __ASSEMBLER__ -+ -+#include -+ -+/* Must not have any padding */ -+struct stage3a_args { -+ uint64_t hdr_offs; -+ uint64_t hdr_size; -+ uint64_t ipib_offs; -+}; -+STATIC_ASSERT(sizeof(struct stage3a_args) == 3 * 8) -+ -+#endif /* __ASSEMBLER__ */ -+#endif /* STAGE3A_H */ ---- /dev/null -+++ b/genprotimg/boot/stage3a.lds -@@ -0,0 +1,101 @@ -+/* -+ * Memory layout for stage 3a -+ * ========================== -+ * -+ * General memory layout -+ * --------------------- -+ * -+ * 0x00000 - 0x01fff Lowcore -+ * 0x02000 - 0x05fff Memory allocation (heap) -+ * 0x0f000 - 0x0ffff Stack -+ * 0x10000 - 0x10012 Jump to the "actual" stage3a code -+ * 0x11000 - 0x12fff Stage3a code + arguments (offsets and lengths to the -+ * actual data: IPIB and UV header) -+ */ -+ -+OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390") -+OUTPUT_ARCH(s390:64-bit) -+ -+ENTRY(_init) -+ -+__heap_size__ = 0x4000; -+__stack_size__ = 0x1000; -+ -+SECTIONS -+{ -+ . = 0x0; -+ -+ . = 0x2000; -+ __heap_start = .; -+ .heap : { -+ . = . + __heap_size__; -+ ASSERT(__heap_stop - __heap_start == __heap_size__, -+ "Heap section doesn't conform to the described memory layout"); -+ } -+ __heap_stop = .; -+ -+ . = 0xf000; -+ __stack_start = .; -+ .stack : { -+ . = . + __stack_size__; -+ ASSERT(__stack_end - __stack_start == __stack_size__, -+ "Stack section doesn't conform to the described memory layout"); -+ } -+ __stack_end = .; -+ -+ . = 0x10000; -+ __text_init_start = .; -+ .text : { -+ stage3a_init.o(.text.init) -+ __text_init_stop = ABSOLUTE(.); -+ /* Text size of text_init must be smaller than 'PARMAREA - IMAGE_ENTRY', -+ * otherwise the text data could be overwritten by the original zipl stage3 -+ * boot loader */ -+ ASSERT(__text_init_stop - __text_init_start < 0x400, -+ "Text size must be smaller than 'PARMAREA - IMAGE_ENTRY'"); -+ . = 0x1000; -+ head.o(.text.start) -+ *(.text) -+ } -+ -+ .ex_table ALIGN(16) : { -+ __ex_table_start = .; -+ *(.ex_table) -+ __ex_table_stop = .; -+ } -+ -+ .bss ALIGN(16) : { -+ __bss_start = .; -+ *(.bss) -+ __bss_stop = .; -+ } -+ -+ .rodata ALIGN(16) : { -+ *(.rodata) -+ *(.rodata.*) -+ } -+ -+ .data ALIGN(16) : { -+ *(.data) -+ . = ALIGN(16); -+ /* The IPIB offset and the UV header offset and size will be -+ * saved in 'loader_parms' */ -+ __loader_parms_start = .; -+ KEEP(*(.loader_parms)); -+ __loader_parms_stop = .; -+ ASSERT(__loader_parms_stop - __loader_parms_start == 3 * 8, -+ "Data size must be equal to 'sizeof(struct stage3a_args)'"); -+ ASSERT(ABSOLUTE(.) < 0x13000, "Data section doesn't conform to the described memory layout"); -+ } -+ -+ /* List this explicitly as otherwise .note.gnu.build-id will be -+ * put at 0x0 */ -+ .notes : { -+ *(.note.*) -+ } -+ -+ /* Sections to be discarded */ -+ /DISCARD/ : { -+ *(.eh_frame) -+ } -+} ---- /dev/null -+++ b/genprotimg/boot/stage3a_init.S -@@ -0,0 +1,26 @@ -+/* -+ * Entry code for stage 3a boot loader -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * 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 "stage3a.h" -+#include "boot/sigp.h" -+ -+.section .text.init -+.globl _init -+_init: -+ /* set architecture and switch to 64bit */ -+ lhi %r1, 1 -+ sigp %r1, %r0, SIGP_SET_ARCHITECTURE -+ sam64 -+ /* The original stage3 boot loader will try to store the -+ * kernel command line and the address and size of the -+ * ramdisk. Simply ignore this by starting at 0x11000. -+ */ -+ lgfi %r1, STAGE3A_ENTRY -+ br %r1 -+.previous ---- /dev/null -+++ b/genprotimg/boot/stage3b.c -@@ -0,0 +1,77 @@ -+/* -+ * Main program for stage3b bootloader -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * 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 "libc.h" -+#include "stage3b.h" -+ -+#include "lib/zt_common.h" -+#include "boot/s390.h" -+#include "boot/linux_layout.h" -+#include "boot/loaders_layout.h" -+#include "sclp.h" -+#include "error.h" -+ -+ -+static volatile struct stage3b_args __section(".loader_parms") loader_parms; -+ -+static inline void __noreturn load_psw(struct psw_t psw) -+{ -+ asm volatile("lpswe %0" : : "Q"(psw) : "cc"); -+ -+ while (1) -+ ; -+} -+ -+void __noreturn start(void) -+{ -+ volatile struct stage3b_args *args = &loader_parms; -+ volatile struct memblob *kernel = &args->kernel; -+ volatile struct memblob *cmdline = &args->cmdline; -+ volatile struct memblob *initrd = &args->initrd; -+ volatile struct psw_t psw = args->psw; -+ -+ /* set up ASCII and line-mode */ -+ sclp_setup(SCLP_LINE_ASCII_INIT); -+ -+ if (kernel->size < IMAGE_LOAD_ADDRESS) -+ panic(EINTERNAL, "Invalid kernel\n"); -+ -+ if (cmdline->size > COMMAND_LINE_SIZE) -+ panic(EINTERNAL, "Command line is too large\n"); -+ -+ /* move the kernel and cut the kernel header */ -+ memmove((void *)IMAGE_LOAD_ADDRESS, -+ (void *)(kernel->src + IMAGE_LOAD_ADDRESS), -+ kernel->size - IMAGE_LOAD_ADDRESS); -+ -+ /* move the kernel cmdline */ -+ memmove((void *)COMMAND_LINE, -+ (void *)cmdline->src, -+ cmdline->size); -+ /* the initrd does not need to be moved */ -+ -+ if (initrd->size != 0) { -+ /* copy initrd start address and size into new kernel space */ -+ *(unsigned long long *)INITRD_START = initrd->src; -+ *(unsigned long long *)INITRD_SIZE = initrd->size; -+ } -+ -+ /* disable ASCII and line-mode */ -+ sclp_setup(SCLP_DISABLE); -+ -+ /* use lpswe instead of diag308 as a I/O subsystem reset is not -+ * needed as this was already done by the diag308 subcode 10 call -+ * in stage3a -+ */ -+ load_psw(psw); -+} -+ -+void panic_notify(unsigned long UNUSED(rc)) -+{ -+} ---- /dev/null -+++ b/genprotimg/boot/stage3b.h -@@ -0,0 +1,38 @@ -+/* -+ * Main program for stage3b bootloader -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * s390-tools is free software; you can redistribute it and/or modify -+ * it under the terms of the MIT license. See LICENSE for details. -+ */ -+ -+#ifndef STAGE3B_H -+#define STAGE3B_H -+ -+#include "lib/zt_common.h" -+ -+ -+#ifndef __ASSEMBLER__ -+ -+#include -+ -+#include "boot/s390.h" -+ -+/* Must not have any padding included */ -+struct memblob { -+ uint64_t src; -+ uint64_t size; -+}; -+STATIC_ASSERT(sizeof(struct memblob) == 2 * 8) -+ -+/* Must not have any padding included */ -+struct stage3b_args { -+ struct memblob kernel; -+ struct memblob cmdline; -+ struct memblob initrd; -+ struct psw_t psw; -+}; -+STATIC_ASSERT(sizeof(struct stage3b_args) == 3 * sizeof(struct memblob) + 16) -+#endif /* __ASSEMBLER__ */ -+#endif /* STAGE3B_H */ ---- /dev/null -+++ b/genprotimg/boot/stage3b.lds -@@ -0,0 +1,87 @@ -+/* -+ * Memory layout for stage 3b -+ * ========================== -+ * -+ * General memory layout -+ * --------------------- -+ * -+ * 0x00000 - 0x01fff Lowcore -+ * 0x02000 - 0x05fff Memory allocation (heap) -+ * 0x0a000 - 0x0efff Stage3b code -+ * 0x0f000 - 0x0ffff Stack -+ */ -+ -+OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390") -+OUTPUT_ARCH(s390:64-bit) -+ -+ENTRY(_start) -+ -+__heap_size__ = 0x4000; -+__stack_size__ = 0x1000; -+ -+SECTIONS -+{ -+ . = 0x0; -+ -+ . = 0x2000; -+ __heap_start = .; -+ .heap : { -+ . = . + __heap_size__; -+ ASSERT(__heap_stop - __heap_start == __heap_size__, -+ "Heap section doesn't conform to the described memory layout"); -+ } -+ __heap_stop = .; -+ -+ . = 0xa000; -+ .text : { -+ head.o(.text.start) -+ *(.text) -+ } -+ -+ .ex_table ALIGN(16) : { -+ __ex_table_start = .; -+ *(.ex_table) -+ __ex_table_stop = .; -+ } -+ -+ .bss ALIGN(16) : { -+ __bss_start = .; -+ *(.bss) -+ __bss_stop = .; -+ } -+ -+ .rodata ALIGN(16) : { -+ *(.rodata) -+ *(.rodata.*) -+ } -+ -+ .data ALIGN(16) : { -+ *(.data) -+ . = ALIGN(16); -+ __loader_parms_start = .; -+ KEEP(*(.loader_parms)); -+ __loader_parms_end = .; -+ ASSERT(__loader_parms_end - __loader_parms_start == 3 * 16 + 16, -+ "Data size must be equal to 'sizeof(struct stage3b_args)'"); -+ } -+ -+ . = 0xf000; -+ __stack_start = .; -+ .stack : { -+ . = . + __stack_size__; -+ ASSERT(__stack_end - __stack_start == __stack_size__, -+ "Stack section doesn't conform to the described memory layout"); -+ } -+ __stack_end = .; -+ -+ /* List this explicitly as otherwise .note.gnu.build-id will be -+ * put at 0x0 */ -+ .notes : { -+ *(.note.*) -+ } -+ -+ /* Sections to be discarded */ -+ /DISCARD/ : { -+ *(.eh_frame) -+ } -+} ---- a/include/boot/ipl.h -+++ b/include/boot/ipl.h -@@ -89,6 +89,30 @@ struct ipl_pb0_ccw { - uint8_t reserved5[8]; - } __packed; - -+/* Structure must not have any padding */ -+struct ipl_pb0_pv_comp { -+ uint64_t tweak_pref; -+ uint64_t addr; -+ uint64_t len; -+}; -+STATIC_ASSERT(sizeof(struct ipl_pb0_pv_comp) == 3 * 8) -+ -+/* IPL Parameter Block 0 for PV */ -+struct ipl_pb0_pv { -+ uint32_t len; -+ uint8_t pbt; -+ uint8_t reserved1[3]; -+ uint8_t loadparm[8]; -+ uint8_t reserved2[84]; -+ uint8_t reserved3[3]; -+ uint8_t version; -+ uint8_t reserved4[4]; -+ uint32_t num_comp; -+ uint64_t pv_hdr_addr; -+ uint64_t pv_hdr_size; -+ struct ipl_pb0_pv_comp components[]; -+} __packed; -+ - struct ipl_parameter_block { - struct ipl_pl_hdr hdr; - union { -@@ -96,6 +120,7 @@ struct ipl_parameter_block { - struct ipl_pb0_common common; - struct ipl_pb0_fcp fcp; - struct ipl_pb0_ccw ccw; -+ struct ipl_pb0_pv pv; - char raw[PAGE_SIZE - sizeof(struct ipl_pl_hdr)]; - }; - } __packed __aligned(PAGE_SIZE); ---- a/include/boot/s390.h -+++ b/include/boot/s390.h -@@ -18,6 +18,12 @@ - - #define PAGE_SIZE _AC(4096, UL) - -+/* Minimum size of a stack frame in bytes */ -+#define STACK_FRAME_OVERHEAD _AC(160, U) -+ -+/* Facilities */ -+#define UNPACK_FACILITY _AC(161, U) -+ - - #ifndef __ASSEMBLER__ - -@@ -262,11 +268,17 @@ static __always_inline void __ctl_set_bi - * DIAG 308 support - */ - enum diag308_subcode { -- DIAG308_REL_HSA = 2, -- DIAG308_IPL = 3, -- DIAG308_DUMP = 4, -- DIAG308_SET = 5, -- DIAG308_STORE = 6, -+ DIAG308_REL_HSA = 2, -+ DIAG308_IPL = 3, -+ DIAG308_DUMP = 4, -+ DIAG308_SET = 5, -+ DIAG308_STORE = 6, -+ DIAG308_SET_PV = 8, -+ DIAG308_UNPACK_PV = 10, -+}; -+ -+enum diag308_rc { -+ DIAG308_RC_OK = 0x0001, - }; - - static __always_inline unsigned long diag308(unsigned long subcode, void *addr) ---- a/zipl/boot/error.h -+++ b/zipl/boot/error.h -@@ -71,4 +71,10 @@ - #define ENOTIME 0x00004605 /* The zipl time stamps do not match */ - #define ENOMSS 0x00004606 /* Could not enable MSS */ - -+/* -+ * PV error codes -+ */ -+#define ENOPV 0x00004607 /* No support for PV */ -+#define EPV 0x00004608 /* PV error */ -+ - #endif /* ERROR_H */ diff --git a/s390-tools-sles15sp2-44-genprotimg-boot-use-C-pre-processor-for-linker-scrip.patch b/s390-tools-sles15sp2-44-genprotimg-boot-use-C-pre-processor-for-linker-scrip.patch deleted file mode 100644 index 2d11de2..0000000 --- a/s390-tools-sles15sp2-44-genprotimg-boot-use-C-pre-processor-for-linker-scrip.patch +++ /dev/null @@ -1,479 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] genprotimg: boot: use C pre-processor for linker script generation -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: 2d600570df98a1d26a6f3947ae8c39bcde00b464 -Problem-ID: VS1804 - -Upstream-Description: - - genprotimg: boot: use C pre-processor for linker script generation - - Use C pre-processor for linker script generation. This allows the - usage of constants in our "linker scripts" `*.lds.S` (actually, these - are assembler files, so we can make us of the C pre-processor and its - capabilities). - - Suggested-by: Philipp Rudo - Reviewed-by: Philipp Rudo - Signed-off-by: Marc Hartmayer - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - genprotimg/boot/.gitignore | 1 - genprotimg/boot/Makefile | 13 ++++- - genprotimg/boot/stage3a.lds | 101 ----------------------------------------- - genprotimg/boot/stage3a.lds.S | 103 ++++++++++++++++++++++++++++++++++++++++++ - genprotimg/boot/stage3b.h | 4 + - genprotimg/boot/stage3b.lds | 87 ----------------------------------- - genprotimg/boot/stage3b.lds.S | 87 +++++++++++++++++++++++++++++++++++ - 7 files changed, 207 insertions(+), 189 deletions(-) - ---- a/genprotimg/boot/.gitignore -+++ b/genprotimg/boot/.gitignore -@@ -1,3 +1,4 @@ - *.elf -+*.lds - *.bin - *.d ---- a/genprotimg/boot/Makefile -+++ b/genprotimg/boot/Makefile -@@ -39,6 +39,17 @@ all: $(FILES) - $(CC) $(ALL_CFLAGS) -c -o $@ $< - - -+# Dependencies for the .lds generation -+sources_lds_S = $(wildcard *.lds.S) -+dependencies_lds_S = $(sources_lds_s:%.lds.S=.%.lds.d) -+# Include all ".lds.d" dependency files for all make targets except for "clean" -+ifneq ($(MAKECMDGOALS),clean) -+-include $(dependencies_lds_S) -+endif -+ -+%.lds: %.lds.S Makefile -+ $(CPP) -Wp,-MD,.$@.d,-MT,$@ $(INCLUDE_PARMS) -P -C -o $@ $< -+ - # Special rules for zipl object files - $(ZIPL_OBJS_C): %.o : $(ZIPL_BOOT_DIR)/%.c - $(CC) $(ALL_CFLAGS) -c -o $@ $< -@@ -78,6 +89,6 @@ stage3b.elf: head.o stage3b.o stage3b.ld - @chmod a-x $@ - - clean: -- rm -f *.o *.elf *.bin *.map .*.d -+ rm -f *.o *.elf *.bin *.map .*.d *.lds - - .PHONY: all clean ---- a/genprotimg/boot/stage3a.lds -+++ /dev/null -@@ -1,101 +0,0 @@ --/* -- * Memory layout for stage 3a -- * ========================== -- * -- * General memory layout -- * --------------------- -- * -- * 0x00000 - 0x01fff Lowcore -- * 0x02000 - 0x05fff Memory allocation (heap) -- * 0x0f000 - 0x0ffff Stack -- * 0x10000 - 0x10012 Jump to the "actual" stage3a code -- * 0x11000 - 0x12fff Stage3a code + arguments (offsets and lengths to the -- * actual data: IPIB and UV header) -- */ -- --OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390") --OUTPUT_ARCH(s390:64-bit) -- --ENTRY(_init) -- --__heap_size__ = 0x4000; --__stack_size__ = 0x1000; -- --SECTIONS --{ -- . = 0x0; -- -- . = 0x2000; -- __heap_start = .; -- .heap : { -- . = . + __heap_size__; -- ASSERT(__heap_stop - __heap_start == __heap_size__, -- "Heap section doesn't conform to the described memory layout"); -- } -- __heap_stop = .; -- -- . = 0xf000; -- __stack_start = .; -- .stack : { -- . = . + __stack_size__; -- ASSERT(__stack_end - __stack_start == __stack_size__, -- "Stack section doesn't conform to the described memory layout"); -- } -- __stack_end = .; -- -- . = 0x10000; -- __text_init_start = .; -- .text : { -- stage3a_init.o(.text.init) -- __text_init_stop = ABSOLUTE(.); -- /* Text size of text_init must be smaller than 'PARMAREA - IMAGE_ENTRY', -- * otherwise the text data could be overwritten by the original zipl stage3 -- * boot loader */ -- ASSERT(__text_init_stop - __text_init_start < 0x400, -- "Text size must be smaller than 'PARMAREA - IMAGE_ENTRY'"); -- . = 0x1000; -- head.o(.text.start) -- *(.text) -- } -- -- .ex_table ALIGN(16) : { -- __ex_table_start = .; -- *(.ex_table) -- __ex_table_stop = .; -- } -- -- .bss ALIGN(16) : { -- __bss_start = .; -- *(.bss) -- __bss_stop = .; -- } -- -- .rodata ALIGN(16) : { -- *(.rodata) -- *(.rodata.*) -- } -- -- .data ALIGN(16) : { -- *(.data) -- . = ALIGN(16); -- /* The IPIB offset and the UV header offset and size will be -- * saved in 'loader_parms' */ -- __loader_parms_start = .; -- KEEP(*(.loader_parms)); -- __loader_parms_stop = .; -- ASSERT(__loader_parms_stop - __loader_parms_start == 3 * 8, -- "Data size must be equal to 'sizeof(struct stage3a_args)'"); -- ASSERT(ABSOLUTE(.) < 0x13000, "Data section doesn't conform to the described memory layout"); -- } -- -- /* List this explicitly as otherwise .note.gnu.build-id will be -- * put at 0x0 */ -- .notes : { -- *(.note.*) -- } -- -- /* Sections to be discarded */ -- /DISCARD/ : { -- *(.eh_frame) -- } --} ---- /dev/null -+++ b/genprotimg/boot/stage3a.lds.S -@@ -0,0 +1,103 @@ -+/* -+ * Memory layout for stage 3a -+ * ========================== -+ * -+ * General memory layout -+ * --------------------- -+ * -+ * 0x00000 - 0x01fff Lowcore -+ * 0x02000 - 0x05fff Memory allocation (heap) -+ * 0x0f000 - 0x0ffff Stack -+ * 0x10000 - 0x10012 Jump to the "actual" stage3a code -+ * 0x11000 - 0x12fff Stage3a code + arguments (offsets and lengths to the -+ * actual data: IPIB and UV header) -+ */ -+ -+#include "stage3a.h" -+#include "common_memory_layout.h" -+ -+OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390") -+OUTPUT_ARCH(s390:64-bit) -+ -+ENTRY(_init) -+ -+SECTIONS -+{ -+ . = 0x0; -+ -+ . = HEAP_ADDRESS; -+ __heap_start = .; -+ .heap : { -+ . = . + HEAP_SIZE; -+ ASSERT(__heap_stop - __heap_start == HEAP_SIZE, -+ "Heap section doesn't conform to the described memory layout"); -+ } -+ __heap_stop = .; -+ -+ . = STACK_ADDRESS; -+ __stack_start = .; -+ .stack : { -+ . = . + STACK_SIZE; -+ ASSERT(__stack_end - __stack_start == STACK_SIZE, -+ "Stack section doesn't conform to the described memory layout"); -+ } -+ __stack_end = .; -+ -+ . = STAGE3A_INIT_ENTRY; -+ __text_init_start = .; -+ .text : { -+ stage3a_init.o(.text.init) -+ __text_init_stop = ABSOLUTE(.); -+ /* Text size of text_init must be smaller than 'PARMAREA - IMAGE_ENTRY', -+ * otherwise the text data could be overwritten by the original zipl stage3 -+ * boot loader */ -+ ASSERT(__text_init_stop - __text_init_start < PARMAREA - IMAGE_ENTRY, -+ "Text size must be smaller than 'PARMAREA - IMAGE_ENTRY'"); -+ . = 0x1000; -+ ASSERT(ABSOLUTE(.) == STAGE3A_ENTRY, -+ "Text section doesn't conform to the described memory layout"); -+ head.o(.text.start) -+ *(.text) -+ } -+ -+ .ex_table ALIGN(16) : { -+ __ex_table_start = .; -+ *(.ex_table) -+ __ex_table_stop = .; -+ } -+ -+ .bss ALIGN(16) : { -+ __bss_start = .; -+ *(.bss) -+ __bss_stop = .; -+ } -+ -+ .rodata ALIGN(16) : { -+ *(.rodata) -+ *(.rodata.*) -+ } -+ -+ .data ALIGN(16) : { -+ *(.data) -+ . = ALIGN(16); -+ /* The IPIB offset and the UV header offset and size will be -+ * saved in 'loader_parms' */ -+ __loader_parms_start = .; -+ KEEP(*(.loader_parms)); -+ __loader_parms_stop = .; -+ ASSERT(__loader_parms_stop - __loader_parms_start == 3 * 8, -+ "Data size must be equal to 'sizeof(struct stage3a_args)'"); -+ ASSERT(ABSOLUTE(.) < 0x13000, "Data section doesn't conform to the described memory layout"); -+ } -+ -+ /* List this explicitly as otherwise .note.gnu.build-id will be -+ * put at 0x0 */ -+ .notes : { -+ *(.note.*) -+ } -+ -+ /* Sections to be discarded */ -+ /DISCARD/ : { -+ *(.eh_frame) -+ } -+} ---- a/genprotimg/boot/stage3b.h -+++ b/genprotimg/boot/stage3b.h -@@ -11,6 +11,10 @@ - #define STAGE3B_H - - #include "lib/zt_common.h" -+#include "boot/loaders_layout.h" -+ -+#define STAGE3B_ENTRY STAGE3_ENTRY -+#define STAGE3B_LOAD_ADDRESS STAGE3B_ENTRY - - - #ifndef __ASSEMBLER__ ---- a/genprotimg/boot/stage3b.lds -+++ /dev/null -@@ -1,87 +0,0 @@ --/* -- * Memory layout for stage 3b -- * ========================== -- * -- * General memory layout -- * --------------------- -- * -- * 0x00000 - 0x01fff Lowcore -- * 0x02000 - 0x05fff Memory allocation (heap) -- * 0x0a000 - 0x0efff Stage3b code -- * 0x0f000 - 0x0ffff Stack -- */ -- --OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390") --OUTPUT_ARCH(s390:64-bit) -- --ENTRY(_start) -- --__heap_size__ = 0x4000; --__stack_size__ = 0x1000; -- --SECTIONS --{ -- . = 0x0; -- -- . = 0x2000; -- __heap_start = .; -- .heap : { -- . = . + __heap_size__; -- ASSERT(__heap_stop - __heap_start == __heap_size__, -- "Heap section doesn't conform to the described memory layout"); -- } -- __heap_stop = .; -- -- . = 0xa000; -- .text : { -- head.o(.text.start) -- *(.text) -- } -- -- .ex_table ALIGN(16) : { -- __ex_table_start = .; -- *(.ex_table) -- __ex_table_stop = .; -- } -- -- .bss ALIGN(16) : { -- __bss_start = .; -- *(.bss) -- __bss_stop = .; -- } -- -- .rodata ALIGN(16) : { -- *(.rodata) -- *(.rodata.*) -- } -- -- .data ALIGN(16) : { -- *(.data) -- . = ALIGN(16); -- __loader_parms_start = .; -- KEEP(*(.loader_parms)); -- __loader_parms_end = .; -- ASSERT(__loader_parms_end - __loader_parms_start == 3 * 16 + 16, -- "Data size must be equal to 'sizeof(struct stage3b_args)'"); -- } -- -- . = 0xf000; -- __stack_start = .; -- .stack : { -- . = . + __stack_size__; -- ASSERT(__stack_end - __stack_start == __stack_size__, -- "Stack section doesn't conform to the described memory layout"); -- } -- __stack_end = .; -- -- /* List this explicitly as otherwise .note.gnu.build-id will be -- * put at 0x0 */ -- .notes : { -- *(.note.*) -- } -- -- /* Sections to be discarded */ -- /DISCARD/ : { -- *(.eh_frame) -- } --} ---- /dev/null -+++ b/genprotimg/boot/stage3b.lds.S -@@ -0,0 +1,87 @@ -+/* -+ * Memory layout for stage 3b -+ * ========================== -+ * -+ * General memory layout -+ * --------------------- -+ * -+ * 0x00000 - 0x01fff Lowcore -+ * 0x02000 - 0x05fff Memory allocation (heap) -+ * 0x0a000 - 0x0efff Stage3b code -+ * 0x0f000 - 0x0ffff Stack -+ */ -+ -+#include "stage3b.h" -+#include "common_memory_layout.h" -+ -+OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390") -+OUTPUT_ARCH(s390:64-bit) -+ -+ENTRY(_start) -+ -+SECTIONS -+{ -+ . = 0x0; -+ -+ . = HEAP_ADDRESS; -+ __heap_start = .; -+ .heap : { -+ . = . + HEAP_SIZE; -+ ASSERT(__heap_stop - __heap_start == HEAP_SIZE, -+ "Heap section doesn't conform to the described memory layout"); -+ } -+ __heap_stop = .; -+ -+ . = STAGE3B_ENTRY; -+ .text : { -+ head.o(.text.start) -+ *(.text) -+ } -+ -+ .ex_table ALIGN(16) : { -+ __ex_table_start = .; -+ *(.ex_table) -+ __ex_table_stop = .; -+ } -+ -+ .bss ALIGN(16) : { -+ __bss_start = .; -+ *(.bss) -+ __bss_stop = .; -+ } -+ -+ .rodata ALIGN(16) : { -+ *(.rodata) -+ *(.rodata.*) -+ } -+ -+ .data ALIGN(16) : { -+ *(.data) -+ . = ALIGN(16); -+ __loader_parms_start = .; -+ KEEP(*(.loader_parms)); -+ __loader_parms_end = .; -+ ASSERT(__loader_parms_end - __loader_parms_start == 3 * 16 + 16, -+ "Data size must be equal to 'sizeof(struct stage3b_args)'"); -+ } -+ -+ . = STACK_ADDRESS; -+ __stack_start = .; -+ .stack : { -+ . = . + STACK_SIZE; -+ ASSERT(__stack_end - __stack_start == STACK_SIZE, -+ "Stack section doesn't conform to the described memory layout"); -+ } -+ __stack_end = .; -+ -+ /* List this explicitly as otherwise .note.gnu.build-id will be -+ * put at 0x0 */ -+ .notes : { -+ *(.note.*) -+ } -+ -+ /* Sections to be discarded */ -+ /DISCARD/ : { -+ *(.eh_frame) -+ } -+} diff --git a/s390-tools-sles15sp2-45-genprotimg-add-relocator-for-stage3b.patch b/s390-tools-sles15sp2-45-genprotimg-add-relocator-for-stage3b.patch deleted file mode 100644 index bc68a2b..0000000 --- a/s390-tools-sles15sp2-45-genprotimg-add-relocator-for-stage3b.patch +++ /dev/null @@ -1,120 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] genprotimg: add relocator for stage3b -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: d2f8f972cff7aacbef8e72577af70dbf59ba3ead -Problem-ID: VS1804 - -Upstream-Description: - - genprotimg: add relocator for stage3b - - Add support for the placement of the stage3b loader at other addresses - than 0xa000. For this add a position independent relocator that first - copies the original stage3b code to the memory location 0xa000 and - then starts it. - - Reviewed-by: Philipp Rudo - Signed-off-by: Marc Hartmayer - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - genprotimg/boot/Makefile | 5 +++ - genprotimg/boot/stage3b_reloc.S | 53 ++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 57 insertions(+), 1 deletion(-) - ---- a/genprotimg/boot/Makefile -+++ b/genprotimg/boot/Makefile -@@ -17,7 +17,7 @@ ALL_CFLAGS := $(NO_PIE_CFLAGS) -Os -g \ - -mstack-size=4096 -mstack-guard=128 -msoft-float \ - -Wall -Wformat-security -Wextra -Werror - --FILES := stage3a.bin stage3b.bin -+FILES := stage3a.bin stage3b.bin stage3b_reloc.bin - - ZIPL_SRCS_C := libc.c ebcdic.c ebcdic_conv.c sclp.c - ZIPL_SRCS_ASM := entry.S -@@ -66,14 +66,17 @@ ifneq ($(MAKECMDGOALS),clean) - -include $(dependencies_zipl_c) - endif - -+stage3b_reloc.o: stage3b.bin - - stage3a.elf: head.o stage3a_init.o stage3a.o stage3a.lds $(ZIPL_OBJS) - stage3b.elf: head.o stage3b.o stage3b.lds $(ZIPL_OBJS) -+stage3b_reloc.elf: - - %.elf: %.o - case $* in \ - stage3a) SFLAGS="$(NO_PIE_LINKFLAGS) -nostdlib -Wl,-T,stage3a.lds";; \ - stage3b) SFLAGS="$(NO_PIE_LINKFLAGS) -nostdlib -Wl,-T,stage3b.lds";; \ -+ stage3b_reloc) SFLAGS="$(NO_PIE_LINKFLAGS) -nostdlib -Wl,-estage3b_reloc_start,-Ttext,0";; \ - esac; \ - $(LINK) $$SFLAGS -m64 $(filter %.o, $^) -o $@ - @chmod a-x $@ ---- /dev/null -+++ b/genprotimg/boot/stage3b_reloc.S -@@ -0,0 +1,53 @@ -+/* -+ * Relocator code for stage 3b boot loader -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * 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 "stage3b.h" -+#include "boot/sigp.h" -+ -+.macro MEMCPY dst,src,len -+ lgr %r0, \dst -+ lgr %r1, \len -+ lgr %r2, \src -+ lgr %r3, \len -+ -+20: mvcle %r0, %r2, 0 -+ jo 20b -+.endm -+ -+.org 0x0 -+.section .text.start -+.globl stage3b_reloc_start -+stage3b_reloc_start: -+ /* Might be called after a diag308 so better set -+ * architecture and addressing mode -+ */ -+ lhi %r1, 1 -+ sigp %r1, %r0, SIGP_SET_ARCHITECTURE -+ sam64 -+ -+.copy_stage3b: -+ /* Location of stage3b in memory */ -+ larl %r8, stage3b_start -+ -+ /* Destination for stage3b */ -+ lgfi %r9, STAGE3B_LOAD_ADDRESS -+ -+ /* Size of stage3b */ -+ lghi %r11, stage3b_end - stage3b_start -+ -+ /* Copy the stage3b loader to address STAGE3B_LOAD_ADDRESS */ -+ MEMCPY %r9, %r8, %r11 -+ -+ /* Branch to STAGE3B_ENTRY */ -+ lgfi %r9, STAGE3B_ENTRY -+ br %r9 -+stage3b_start: -+ .incbin "stage3b.bin" -+stage3b_end: -+.previous diff --git a/s390-tools-sles15sp2-46-README.md-remove-useless-empty-line.patch b/s390-tools-sles15sp2-46-README.md-remove-useless-empty-line.patch deleted file mode 100644 index b8c3afd..0000000 --- a/s390-tools-sles15sp2-46-README.md-remove-useless-empty-line.patch +++ /dev/null @@ -1,38 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] README.md: remove useless empty line -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: b06af6026f08d67339a109ba7457373ab82d3248 -Problem-ID: VS1804 - -Upstream-Description: - - README.md: remove useless empty line - - Remove useless empty line. - - Reviewed-by: Jan Höppner - Signed-off-by: Marc Hartmayer - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - README.md | 1 - - 1 file changed, 1 deletion(-) - ---- a/README.md -+++ b/README.md -@@ -1,4 +1,3 @@ -- - s390-tools - ========== - diff --git a/s390-tools-sles15sp2-47-include-boot-s390.h-add-guard-for-struct-__vector128.patch b/s390-tools-sles15sp2-47-include-boot-s390.h-add-guard-for-struct-__vector128.patch deleted file mode 100644 index 114e0cc..0000000 --- a/s390-tools-sles15sp2-47-include-boot-s390.h-add-guard-for-struct-__vector128.patch +++ /dev/null @@ -1,54 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] include/boot/s390.h: add guard for `struct __vector128` -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: 11bdab26297e508fdab29f9457094eedf681de53 -Problem-ID: VS1804 - -Upstream-Description: - - include/boot/s390.h: add guard for `struct __vector128` - - `linux/asm/types.h` also defines the struct `__vector128` so in order - to avoid definition conflicts add the macro guard _S390_TYPES_H, which - is defined in `linux/asm/types`. `linux/asm/types.h` is included by - glib2, which is used by the PV tooling. - - Reviewed-by: Jan Höppner - Signed-off-by: Marc Hartmayer - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - include/boot/s390.h | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/include/boot/s390.h -+++ b/include/boot/s390.h -@@ -358,12 +358,17 @@ static __always_inline int is_zvm(void) - return cpuid.version == 0xff; - } - -+/* To avoid conflicts add a macro guard since __vector128 is also -+ * defined in 'linux/asm/types.h'. -+ */ -+#ifndef _S390_TYPES_H - /* - * Vector register definition - */ - typedef struct { - uint32_t u[4]; - } __vector128; -+#endif - - /* - * Save vector registers diff --git a/s390-tools-sles15sp2-48-genprotimg-introduce-new-tool-for-the-creation-of-PV.patch b/s390-tools-sles15sp2-48-genprotimg-introduce-new-tool-for-the-creation-of-PV.patch deleted file mode 100644 index 20241da..0000000 --- a/s390-tools-sles15sp2-48-genprotimg-introduce-new-tool-for-the-creation-of-PV.patch +++ /dev/null @@ -1,5198 +0,0 @@ -Subject: [PATCH] [FEAT VS1804] genprotimg: introduce new tool for the creation of PV images -From: Marc Hartmayer - -Summary: genprotimg: Introduce new tool for the creation of PV images -Description: genprotimg takes a kernel, host-key documents, optionally an - initrd, optionally a file with the kernel command line, and it - generates a single, loadable image file. The image consists of a - concatenation of a plain text boot loader, the encrypted - components for kernel, initrd, and cmdline, and the - integrity-protected PV header, containing metadata necessary for - running the guest in PV mode. It's possible to use this image file - as a kernel for zIPL or for a direct kernel boot using QEMU. -Upstream-ID: 65b9fc442c1a4ff24583171e714e5fdb1e92c8fd -Problem-ID: VS1804 - -Upstream-Description: - - genprotimg: introduce new tool for the creation of PV images - - Protected VMs (PVM) are KVM VMs, where KVM can't access the VM's state - like guest memory and guest registers anymore. Instead the PVMs are - mostly managed by a new entity called Ultravisor (UV), which provides - an API, so KVM and the PV can request management actions. - - PVMs are encrypted at rest and protected from hypervisor access while - running. They switch from a normal operation into protected mode, so - we can still use the standard boot process to load an encrypted image - and then move it into protected mode. - - This commit adds the tool 'genprotimg'. It takes a kernel, key files, - optionally an initrd, optionally a file with the kernel command line, - and it generates a single, loadable image file. The image consists of - a concatenation of a plain text boot loader, the encrypted components - for kernel, initrd, and cmdline, and the integrity-protected PV - header, containing metadata necessary for running the guest in PV - mode. - - It's possible to use this image file as a kernel for zipl or for a - direct kernel boot using QEMU. - - Reviewed-by: Bjoern Walk - Acked-by: Patrick Steuer - Reviewed-by: Claudio Imbrenda - Reviewed-by: Jan Höppner - Signed-off-by: Marc Hartmayer - Signed-off-by: Jan Höppner - - -Signed-off-by: Marc Hartmayer ---- - Makefile | 4 - README.md | 6 - genprotimg/.gitignore | 5 - genprotimg/Makefile | 26 + - genprotimg/README.md | 101 ++++ - genprotimg/man/Makefile | 12 - genprotimg/man/genprotimg.8 | 97 +++ - genprotimg/src/Makefile | 101 ++++ - genprotimg/src/common.h | 39 + - genprotimg/src/genprotimg.c | 181 +++++++ - genprotimg/src/include/pv_crypto_def.h | 25 + - genprotimg/src/include/pv_hdr_def.h | 84 +++ - genprotimg/src/pv/pv_args.c | 405 ++++++++++++++++ - genprotimg/src/pv/pv_args.h | 53 ++ - genprotimg/src/pv/pv_comp.c | 446 +++++++++++++++++ - genprotimg/src/pv/pv_comp.h | 78 +++ - genprotimg/src/pv/pv_comps.c | 252 ++++++++++ - genprotimg/src/pv/pv_comps.h | 42 + - genprotimg/src/pv/pv_error.c | 37 + - genprotimg/src/pv/pv_error.h | 62 ++ - genprotimg/src/pv/pv_hdr.c | 293 +++++++++++ - genprotimg/src/pv/pv_hdr.h | 36 + - genprotimg/src/pv/pv_image.c | 820 +++++++++++++++++++++++++++++++++ - genprotimg/src/pv/pv_image.h | 68 ++ - genprotimg/src/pv/pv_ipib.c | 128 +++++ - genprotimg/src/pv/pv_ipib.h | 27 + - genprotimg/src/pv/pv_opt_item.c | 26 + - genprotimg/src/pv/pv_opt_item.h | 20 - genprotimg/src/pv/pv_stage3.c | 164 ++++++ - genprotimg/src/pv/pv_stage3.h | 30 + - genprotimg/src/utils/align.h | 24 - genprotimg/src/utils/buffer.c | 69 ++ - genprotimg/src/utils/buffer.h | 31 + - genprotimg/src/utils/crypto.c | 798 ++++++++++++++++++++++++++++++++ - genprotimg/src/utils/crypto.h | 104 ++++ - genprotimg/src/utils/file_utils.c | 234 +++++++++ - genprotimg/src/utils/file_utils.h | 34 + - include/boot/ipl.h | 5 - 38 files changed, 4965 insertions(+), 2 deletions(-) - ---- a/Makefile -+++ b/Makefile -@@ -8,7 +8,9 @@ TOOL_DIRS = zipl zdump fdasd dasdfmt das - tape390 osasnmpd qetharp ip_watcher qethconf scripts zconf \ - vmconvert vmcp man mon_tools dasdinfo vmur cpuplugd ipl_tools \ - ziomon iucvterm hyptop cmsfs-fuse qethqoat zfcpdump zdsfs cpumf \ -- systemd hmcdrvfs cpacfstats zdev dump2tar zkey netboot etc zpcictl -+ systemd hmcdrvfs cpacfstats zdev dump2tar zkey netboot etc zpcictl \ -+ genprotimg -+ - SUB_DIRS = $(LIB_DIRS) $(TOOL_DIRS) - - all: $(TOOL_DIRS) ---- a/README.md -+++ b/README.md -@@ -30,6 +30,9 @@ Package contents - * dasdinfo: - Display unique DASD ID, either UID or volser. - -+ * genprotimg: -+ Create a protected virtualization image. -+ - * udev rules: - - 59-dasd.rules: rules for unique DASD device nodes created in /dev/disk/. - - 57-osasnmpd.rules: udev rules for osasnmpd. -@@ -264,9 +267,10 @@ build options: - | pfm | `HAVE_PFM` | cpacfstats | - | net-snmp | `HAVE_SNMP` | osasnmpd | - | glibc-static | `HAVE_LIBC_STATIC` | zfcpdump | --| openssl | `HAVE_OPENSSL` | zkey | -+| openssl | `HAVE_OPENSSL` | genprotimg,zkey | - | cryptsetup | `HAVE_CRYPTSETUP2` | zkey-cryptsetup | - | json-c | `HAVE_JSONC` | zkey-cryptsetup | -+| glib2 | `HAVE_GLIB2` | genprotimg | - - This table lists additional build or install options: - ---- /dev/null -+++ b/genprotimg/.gitignore -@@ -0,0 +1,5 @@ -+tags -+compile_commands.json -+src/.check-dep-genprotimg -+src/.detect-openssl.dep.c -+src/genprotimg ---- /dev/null -+++ b/genprotimg/Makefile -@@ -0,0 +1,26 @@ -+# Common definitions -+include ../common.mak -+ -+.DEFAULT_GOAL := all -+ -+PKGDATADIR := "$(DESTDIR)$(TOOLS_DATADIR)/genprotimg" -+TESTS := -+SUBDIRS := boot src man -+RECURSIVE_TARGETS := all-recursive install-recursive clean-recursive -+ -+all: all-recursive -+ -+install: all install-recursive -+ $(INSTALL) -d -m 755 "$(PKGDATADIR)" -+ $(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 boot/stage3a.bin "$(PKGDATADIR)" -+ $(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 boot/stage3b_reloc.bin "$(PKGDATADIR)" -+ -+clean: clean-recursive -+ -+$(RECURSIVE_TARGETS): -+ @target=`echo $@ |sed s/-recursive//`; \ -+ for d in $(SUBDIRS); do \ -+ $(MAKE) -C $$d $$target; \ -+ done -+ -+.PHONY: all install clean $(RECURSIVE_TARGETS) ---- /dev/null -+++ b/genprotimg/README.md -@@ -0,0 +1,101 @@ -+# genprotimg -+ -+`genprotimg` takes a kernel, key files, optionally an initrd image, -+optionally a file containing the kernel command line parameters, and -+generates a single, bootable image file. The generated image file -+consists of a concatenation of a plain text boot loader, the encrypted -+components for kernel, initrd, kernel command line, and the -+integrity-protected PV header, containing the metadata necessary for -+running the guest in protected mode. See [Memory Layout](#memory-layout) -+for details about the internal structure of the created image. -+ -+It is possible to use the generated image as a kernel for zipl or for -+a direct kernel boot using QEMU. -+ -+## Getting started -+ -+If all dependencies are met a simple `make` call in the source tree -+should be enough for building `genprotimg`. -+ -+## Details -+ -+The main idea of `genprotimg` is: -+ -+1. read in all keys, IVs, and other information needed for the -+ encryption of the components and the generation of the PV header -+2. add stub stage3a (so we can calculate the memory addresses) -+3. add components: prepare the components (alignment and encryption) -+ and add them to the memory layout -+4. build and add stage3b: generate the stage3b and add it to the memory layout -+5. generate the PV header: generate the hashes (pld, ald, and tld) of -+ the components and create the PV header and IPIB -+6. parameterize the stub stage3a: uses the IPIB and PV header -+7. write the final image to the specified output path -+ -+### Boot Loader -+ -+The boot loader consists of two parts: -+ -+1. stage3a boot loader (cleartext), this loader is responsible for the -+ transition into the protected mode by doing diag308 subcode 8 and -+ 10 calls. -+2. stage3b boot loader (encrypted), this loader is very similar to the -+ normal zipl stage3 boot loader. It will be loaded by the Ultravisor -+ after the successful transition into protected mode. Like the zipl -+ stage3 boot loader it moves the kernel and patches in the values -+ for initrd and parmline. -+ -+The loaders have the following constraints: -+ -+1. It must be possible to place stage3a and stage3b at a location -+ greater than 0x10000 because the zipl stage3 loader zeroes out -+ everything at addresses lower than 0x10000 of the image. -+2. As the stage3 loader of zipl assumes that the passed kernel image -+ looks like a normal kernel image, the zipl stage3 loader modifies the -+ content at the memory area 0x10400 - 0x10800, therefore we leave this -+ area unused in our stage3a loader. -+3. The default entry address used by the zipl stage3 loader is 0x10000 -+ so we add a simple branch to 0x11000 at 0x10000 so the zipl stage3 -+ loader can modify the area 0x10400 - 0x10800 without affecting the -+ stage3a loader. -+ -+#### Detail about stage3b -+ -+The stage3b.bin is linked at address 0x9000, therefore it will not -+work at another address. The relocation support for the stage3b -+loader, so that it can be placed at addresses != 0x9000, is added in -+the loader with the name stage3b_reloc.bin. By default, if we're -+talking about stage3b we refer to stage3b_reloc.bin. -+ -+### Memory Layout -+ -+The memory layout of the bootable file looks like: -+ -++-----------------------+-----------+------------------------+ -+|Start |End |Use | -++=======================+===========+========================+ -+|0 |0x7 |Short PSW, starting | -+| | |instruction at 0x11000 | -++-----------------------+-----------+------------------------+ -+|0x10000 |0x10012 |Branch to 0x11000 | -++-----------------------+-----------+------------------------+ -+|0x10013 |0x10fff |Left intentionally | -+| | |unused | -++-----------------------+-----------+------------------------+ -+|0x11000 |0x12fff |Stage3a | -++-----------------------+-----------+------------------------+ -+|0x13000 |0x13fff |IPIB used as argument | -+| | |for the diag308 call | -++-----------------------+-----------+------------------------+ -+|0x14000 |0x1[45]fff |UV header used for the | -+| | |diag308 call (size can | -+| | |be either 1 or 2 pages) | -++-----------------------+-----------+------------------------+ -+|NEXT_PAGE_ALIGNED_ADDR | |Encrypted Kernel | -++-----------------------+-----------+------------------------+ -+|NEXT_PAGE_ALIGNED_ADDR | |Encrypted Cmdline | -++-----------------------+-----------+------------------------+ -+|NEXT_PAGE_ALIGNED_ADDR | |Encrypted Initrd | -++-----------------------+-----------+------------------------+ -+|NEXT_PAGE_ALIGNED_ADDR | |Encrypted Stage3b_reloc | -++-----------------------+-----------+------------------------+ ---- /dev/null -+++ b/genprotimg/man/Makefile -@@ -0,0 +1,12 @@ -+# Common definitions -+include ../../common.mak -+ -+all: -+ -+install: -+ $(INSTALL) -d -m 755 $(DESTDIR)$(MANDIR)/man8 -+ $(INSTALL) -m 644 -c genprotimg.8 $(DESTDIR)$(MANDIR)/man8 -+ -+clean: -+ -+.PHONY: all install clean ---- /dev/null -+++ b/genprotimg/man/genprotimg.8 -@@ -0,0 +1,97 @@ -+.\" Copyright 2020 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 GENPROTIMG 8 "March 2020" "s390-tools" -+.SH NAME -+genprotimg \- Create a protected virtualization image -+ -+.SH SYNOPSIS -+.SY -+.B genprotimg -+\fB\-k\fR \fIHOST_KEY_DOCUMENT\fR... -+\fB\-i\fR \fIVMLINUZ\fR -+[\fB\-r\fR \fIRAMDISK\fR] -+[\fB\-p\fR \fIPARMFILE\fR] -+\fB\-o\fR \fIOUTFILE\fR -+[\fIOPTION\fR]... -+.YS -+ -+.SH DESCRIPTION -+.PP -+Use \fBgenprotimg\fR to generate a single bootable image file with -+encrypted and integrity-protected parts. The command requires a kernel -+image, a host-key document, and an output file name. Optionally, -+specify an initial RAM filesystem, and a file containing the kernel -+parameters. Should special circumstances require it, you can -+optionally specify your own keys for the encryption by using the -+experimental options. In the resulting image file, a plain text boot -+loader, the encrypted components for kernel, initial RAM disk, kernel -+parameters, and the encrypted and integrity-protected header are -+concatenated. The header contains metadata necessary for running the -+guest in protected mode. -+.PP -+Use this image file as a kernel image for zipl or for a direct kernel -+boot using QEMU. -+ -+.SH OPTIONS -+.TP -+\fB\-h\fR, \fB\-\-help\fR -+Prints usage information, then exits. -+.TP -+\fB\-\-help-experimental\fR -+Prints experimental usage information, then exits. -+.TP -+\fB\-\-help-all\fR -+Prints all usage information, then exits. -+.TP -+\fB\-V\fR, \fB\-\-verbose\fR -+Provides more detailed output. -+.TP -+\fB\-k\fR, \fB\-\-host-key-document\fR=\fI\,HOST_KEY_DOCUMENT\/\fR -+Specifies a host-key document. At least one is required. Specify this -+option multiple times to enable the image to run on more than one -+host. -+.TP -+\fB\-o\fR, \fB\-\-output\fR=\fI\,OUTPUT_FILE\/\fR -+Specifies the output file. Required. -+.TP -+\fB\-i\fR, \fB\-\-image\fR=\fI\,VMLINUZ\/\fR -+Specifies the Linux kernel image file. Required. -+.TP -+\fB\-r\fR, \fB\-\-ramdisk\fR=\fI\,RAMDISK\/\fR -+Specifies the RAM disk image. Optional. -+.TP -+\fB\-p\fR, \fB\-\-parmfile\fR=\fI\,PARMFILE\/\fR -+Specifies the kernel command line stored in \fI\,PARMFILE\/\fR. Optional. -+.TP -+\fB\-\-no-verify\fR -+Do not require the host-key documents to be valid. For testing -+purposes, do not use for a production image. Optional. -+.TP -+\fB\-v\fR, \fB\-\-version\fR -+Prints version information, then exits. -+ -+.SH EXAMPLE -+.PP -+Generate a protected virtualization image in -+\fI\,/boot/vmlinuz.pv\/\fR, using the kernel file \fI\,vmlinuz\/\fR, -+the initrd in \fI\,initramfs\/\fR, the kernel parameters contained in -+\fI\,parmfile\/\fR, and the host-key document in \fI\,host_key.crt\/\fR: -+.PP -+.Vb 1 -+.EX -+\& genprotimg \-i \fI\,vmlinuz\/\fR \-r \fI\,initramfs\/\fR \-p \fI\,parmfile\/\fR \-k \fI\,host_key.crt\/\fR \-o \fI\,/boot/vmlinuz.pv\/\fR -+.EE -+.Ve -+.PP -+ -+.SH NOTES -+.IP "1." 4 -+An ELF file cannot be used as a Linux kernel image. -+.IP "2." 4 -+Remember to re-run \fBzipl\fR after updating a protected -+virtualization image. -+ -+.SH SEE ALSO -+\&\fBzipl\fR\|(5), \fBqemu\fR\|(1) ---- /dev/null -+++ b/genprotimg/src/Makefile -@@ -0,0 +1,101 @@ -+# Common definitions -+include ../../common.mak -+ -+bin_PROGRAM = genprotimg -+ -+PKGDATADIR ?= "$(DESTDIR)$(TOOLS_DATADIR)/genprotimg" -+SRC_DIR := $(dir $(realpath $(firstword $(MAKEFILE_LIST)))) -+TOP_SRCDIR := $(SRC_DIR)/../ -+ROOT_DIR = $(TOP_SRC_DIR)/../../ -+ZIPL_DIR = $(ROOT_DIR)/zipl -+LOADER_DIR = $(TOP_SRCDIR)/boot -+ -+INCLUDE_PATHS = "$(SRC_DIR)" "$(TOP_SRCDIR)" "$(ROOTDIR)/include" -+INCLUDE_PARMS = $(addprefix -I,$(INCLUDE_PATHS)) -+ -+WARNINGS := -Wall -Wextra -Wshadow \ -+ -Wcast-align -Wwrite-strings -Wmissing-prototypes \ -+ -Wmissing-declarations -Wredundant-decls -Wnested-externs -Winline \ -+ -Wno-long-long -Wuninitialized -Wconversion -Wstrict-prototypes \ -+ -Wpointer-arith -Werror \ -+ $(NULL) -+ -+$(bin_PROGRAM)_SRCS := $(bin_PROGRAM).c pv/pv_stage3.c pv/pv_image.c \ -+ pv/pv_comp.c pv/pv_hdr.c pv/pv_ipib.c utils/crypto.c utils/file_utils.c \ -+ pv/pv_args.c utils/buffer.c pv/pv_comps.c pv/pv_error.c \ -+ pv/pv_opt_item.c \ -+ $(NULL) -+$(bin_PROGRAM)_OBJS := $($(bin_PROGRAM)_SRCS:.c=.o) -+ -+ALL_CFLAGS += -std=gnu11 -DPKGDATADIR=$(PKGDATADIR) \ -+ $(GLIB2_CFLAGS) $(LIBCRYPTO_CFLAGS) \ -+ $(WARNINGS) \ -+ $(NULL) -+ALL_CPPFLAGS += $(INCLUDE_PARMS) -+LDLIBS += $(GLIB2_LIBS) $(LIBCRYPTO_LIBS) -+ -+ -+ifneq ($(shell sh -c 'command -v pkg-config'),) -+GLIB2_CFLAGS := $(shell pkg-config --silence-errors --cflags glib-2.0) -+GLIB2_LIBS := $(shell pkg-config --silence-errors --libs glib-2.0) -+LIBCRYPTO_CFLAGS := $(shell pkg-config --silence-errors --cflags libcrypto) -+LIBCRYPTO_LIBS := $(shell pkg-config --silence-errors --libs libcrypto) -+else -+GLIB2_CFLAGS := -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -+GLIB2_LIBS := -lglib-2.0 -+LIBCRYPTO_CFLAGS := -+LIBCRYPTO_LIBS := -lcrypto -+endif -+ -+BUILD_TARGETS := skip-$(bin_PROGRAM) -+INSTALL_TARGETS := skip-$(bin_PROGRAM) -+ifneq (${HAVE_OPENSSL},0) -+ifneq (${HAVE_GLIB2},0) -+BUILD_TARGETS := $(bin_PROGRAM) -+INSTALL_TARGETS := install-$(bin_PROGRAM) -+endif -+endif -+ -+all: $(BUILD_TARGETS) -+ -+install: $(INSTALL_TARGETS) -+ -+$(bin_PROGRAM): $($(bin_PROGRAM)_OBJS) -+ -+skip-$(bin_PROGRAM): -+ echo " SKIP $(bin_PROGRAM) due to unresolved dependencies" -+ -+install-$(bin_PROGRAM): $(bin_PROGRAM) -+ $(INSTALL) -d -m 755 $(DESTDIR)$(USRBINDIR) -+ $(INSTALL) -c $^ $(DESTDIR)$(USRBINDIR) -+ -+clean: -+ $(RM) -f $($(bin_PROGRAM)_OBJS) $(bin_PROGRAM) .check-dep-$(bin_PROGRAM) .detect-openssl.dep.c -+ -+.PHONY: all install clean skip-$(bin_PROGRAM) install-$(bin_PROGRAM) -+ -+$($(bin_PROGRAM)_OBJS): .check-dep-$(bin_PROGRAM) -+ -+.detect-openssl.dep.c: -+ echo "#include " > $@ -+ echo "#if OPENSSL_VERSION_NUMBER < 0x10100000L" >> $@ -+ echo " #error openssl version 1.1.0 is required" >> $@ -+ echo "#endif" >> $@ -+ echo "static void __attribute__((unused)) test(void) {" >> $@ -+ echo " EVP_MD_CTX *ctx = EVP_MD_CTX_new();" >> $@ -+ echo " EVP_MD_CTX_free(ctx);" >> $@ -+ echo "}" >> $@ -+ -+.check-dep-$(bin_PROGRAM): .detect-openssl.dep.c -+ $(call check_dep, \ -+ "$(bin_PROGRAM)", \ -+ "glib.h", \ -+ "glib2-devel / libglib2.0-dev", \ -+ "HAVE_GLIB2=0") -+ $(call check_dep, \ -+ "$(bin_PROGRAM)", \ -+ $^, \ -+ "openssl-devel / libssl-dev version >= 1.1.0", \ -+ "HAVE_OPENSSL=0", \ -+ "-I.") -+ touch $@ ---- /dev/null -+++ b/genprotimg/src/common.h -@@ -0,0 +1,39 @@ -+#ifndef COMMON_H -+#define COMMON_H -+ -+#define GETTEXT_PACKAGE "genprotimg" -+#include -+#include -+ -+#include "boot/linux_layout.h" -+#include "lib/zt_common.h" -+ -+static const gchar tool_name[] = "genprotimg"; -+static const gchar copyright_notice[] = "Copyright IBM Corp. 2020"; -+ -+/* default values */ -+#define GENPROTIMG_STAGE3A_PATH (STRINGIFY(PKGDATADIR) "/stage3a.bin") -+#define GENPROTIMG_STAGE3B_PATH (STRINGIFY(PKGDATADIR) "/stage3b_reloc.bin") -+ -+#define PSW_SHORT_ADDR_MASK 0x000000007FFFFFFFULL -+#define PSW_MASK_BA 0x0000000080000000ULL -+#define PSW_MASK_EA 0x0000000100000000ULL -+#define PSW_MASK_BIT_12 0x0008000000000000ULL -+ -+#define DEFAULT_INITIAL_PSW_ADDR IMAGE_ENTRY -+#define DEFAULT_INITIAL_PSW_MASK (PSW_MASK_EA | PSW_MASK_BA) -+ -+#define DO_PRAGMA(x) _Pragma(#x) -+ -+# ifdef __clang__ -+# define WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(...) \ -+ DO_PRAGMA(clang diagnostic push) \ -+ DO_PRAGMA(clang diagnostic ignored "-Wunused-function") \ -+ G_DEFINE_AUTOPTR_CLEANUP_FUNC(__VA_ARGS__) \ -+ DO_PRAGMA(clang diagnostic pop) -+# else -+# define WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(...) \ -+ G_DEFINE_AUTOPTR_CLEANUP_FUNC(__VA_ARGS__) -+# endif -+ -+#endif ---- /dev/null -+++ b/genprotimg/src/genprotimg.c -@@ -0,0 +1,181 @@ -+/* -+ * genprotimg - build relocatable secure images -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * 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 -+#include -+#include -+#include -+ -+#include "common.h" -+#include "pv/pv_args.h" -+#include "pv/pv_image.h" -+ -+enum { -+ LOG_LEVEL_CRITICAL = 0, -+ LOG_LEVEL_INFO = 1, -+ LOG_LEVEL_DEBUG = 2, -+}; -+ -+static gint log_level = LOG_LEVEL_CRITICAL; -+static gchar *tmp_dir; -+ -+static void rmdir_recursive(gchar *dir_path, GError **err) -+{ -+ const gchar *file = NULL; -+ g_autoptr(GDir) d = NULL; -+ -+ if (!dir_path) -+ return; -+ -+ d = g_dir_open(dir_path, 0, err); -+ if (!d) { -+ g_set_error(err, G_FILE_ERROR, -+ (gint)g_file_error_from_errno(errno), -+ _("Failed to open directory '%s': %s"), dir_path, -+ g_strerror(errno)); -+ return; -+ } -+ -+ while ((file = g_dir_read_name(d)) != NULL) { -+ g_autofree gchar *file_path = -+ g_build_filename(dir_path, file, NULL); -+ /* ignore error */ -+ (void)g_unlink(file_path); -+ } -+ -+ if (g_rmdir(dir_path) != 0) { -+ g_set_error(err, G_FILE_ERROR, -+ (gint)g_file_error_from_errno(errno), -+ _("Failed to remove directory '%s': %s"), dir_path, -+ g_strerror(errno)); -+ return; -+ } -+} -+ -+static void sig_term_handler(int signal G_GNUC_UNUSED) -+{ -+ rmdir_recursive(tmp_dir, NULL); -+ exit(EXIT_FAILURE); -+} -+ -+static void log_handler_cb(const gchar *log_domain G_GNUC_UNUSED, -+ GLogLevelFlags level, const gchar *message, -+ gpointer user_data G_GNUC_UNUSED) -+{ -+ const gchar *prefix = ""; -+ -+ /* filter out messages depending on debugging level */ -+ if ((level & G_LOG_LEVEL_DEBUG) && log_level < LOG_LEVEL_DEBUG) -+ return; -+ -+ if ((level & G_LOG_LEVEL_INFO) && log_level < LOG_LEVEL_INFO) -+ return; -+ -+ if (level & G_LOG_LEVEL_WARNING) -+ prefix = "WARNING: "; -+ -+ if (level & G_LOG_LEVEL_ERROR) -+ prefix = "ERROR: "; -+ -+ if (level & (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_ERROR)) -+ g_printerr("%s%s\n", prefix, message); -+ else -+ g_print("%s%s\n", prefix, message); -+} -+ -+static void setup_prgname(const gchar *name) -+{ -+ g_set_prgname(name); -+ g_set_application_name(_(name)); -+} -+ -+static void setup_handler(const gint *signals, const gsize signals_n) -+{ -+ /* set up logging handler */ -+ g_log_set_handler(NULL, -+ G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | -+ G_LOG_FLAG_RECURSION, -+ log_handler_cb, NULL); -+ -+ /* set signal handler */ -+ for (gsize i = 0; i < signals_n; i++) -+ signal(signals[i], sig_term_handler); -+} -+ -+static void remove_signal_handler(const gint *signals, const gsize signals_n) -+{ -+ for (gsize i = 0; i < signals_n; i++) -+ signal(signals[i], SIG_DFL); -+} -+ -+gint main(gint argc, gchar *argv[]) -+{ -+ g_autoptr(PvArgs) args = pv_args_new(); -+ gint signals[] = { SIGINT, SIGTERM }; -+ g_autoptr(PvImage) img = NULL; -+ gint ret = EXIT_FAILURE; -+ GError *err = NULL; -+ -+ setlocale(LC_CTYPE, ""); -+ setup_prgname(tool_name); -+ setup_handler(signals, G_N_ELEMENTS(signals)); -+ -+ if (pv_args_parse_options(args, &argc, &argv, &err) < 0) -+ goto error; -+ -+ /* set new log level */ -+ log_level = args->log_level; -+ -+ /* if the user has not specified a temporary directory let's -+ * create one -+ */ -+ if (!args->tmp_dir) { -+ tmp_dir = g_dir_make_tmp("genprotimg-XXXXXX", &err); -+ if (!tmp_dir) -+ goto error; -+ args->tmp_dir = g_strdup(tmp_dir); -+ } -+ -+ /* allocate and initialize ``pv_img`` data structure */ -+ img = pv_img_new(args, GENPROTIMG_STAGE3A_PATH, &err); -+ if (!img) -+ goto error; -+ -+ /* add user components: `args->comps` must be sorted by the -+ * component type => by memory address -+ */ -+ for (GSList *iterator = args->comps; iterator; iterator = iterator->next) { -+ const PvArg *arg = iterator->data; -+ -+ if (pv_img_add_component(img, arg, &err) < 0) -+ goto error; -+ } -+ -+ if (pv_img_finalize(img, GENPROTIMG_STAGE3B_PATH, &err) < 0) -+ goto error; -+ -+ if (pv_img_write(img, args->output_path, &err) < 0) -+ goto error; -+ -+ ret = EXIT_SUCCESS; -+ -+error: -+ if (err) { -+ fputs(err->message, stderr); -+ fputc('\n', stderr); -+ g_clear_error(&err); -+ } -+ rmdir_recursive(tmp_dir, NULL); -+ remove_signal_handler(signals, G_N_ELEMENTS(signals)); -+ g_free(tmp_dir); -+ exit(ret); -+} ---- /dev/null -+++ b/genprotimg/src/include/pv_crypto_def.h -@@ -0,0 +1,25 @@ -+/* -+ * PV cryptography related definitions -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * s390-tools is free software; you can redistribute it and/or modify -+ * it under the terms of the MIT license. See LICENSE for details. -+ */ -+ -+#ifndef PV_CRYPTO_DEF_H -+#define PV_CRYPTO_DEF_H -+ -+#include -+ -+#include "lib/zt_common.h" -+ -+union ecdh_pub_key { -+ struct { -+ uint8_t x[80]; -+ uint8_t y[80]; -+ }; -+ uint8_t data[160]; -+} __packed; -+ -+#endif ---- /dev/null -+++ b/genprotimg/src/include/pv_hdr_def.h -@@ -0,0 +1,84 @@ -+/* -+ * PV header definitions -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * s390-tools is free software; you can redistribute it and/or modify -+ * it under the terms of the MIT license. See LICENSE for details. -+ */ -+ -+#ifndef PV_HDR_DEF_H -+#define PV_HDR_DEF_H -+ -+#include -+ -+#include "boot/s390.h" -+#include "lib/zt_common.h" -+#include "utils/crypto.h" -+ -+#include "pv_crypto_def.h" -+ -+/* Magic number which is used to identify the file containing the PV -+ * header -+ */ -+#define PV_MAGIC_NUMBER 0x49424d5365634578ULL -+#define PV_VERSION_1 0x00000100U -+ -+/* prevent Ultravisor decryption during unpack operation */ -+#define PV_CFLAG_NO_DECRYPTION 0x10000000ULL -+ -+/* maxima for the PV version 1 */ -+#define PV_V1_IPIB_MAX_SIZE PAGE_SIZE -+#define PV_V1_PV_HDR_MAX_SIZE (2 * PAGE_SIZE) -+ -+typedef struct pv_hdr_key_slot { -+ uint8_t digest_key[SHA256_DIGEST_LENGTH]; -+ uint8_t wrapped_key[32]; -+ uint8_t tag[AES_256_GCM_TAG_SIZE]; -+} __packed PvHdrKeySlot; -+ -+typedef struct pv_hdr_opt_item { -+ uint32_t otype; -+ uint8_t ibk[32]; -+ uint8_t data[]; -+} __packed PvHdrOptItem; -+ -+/* integrity protected data (by GCM tag), but non-encrypted */ -+struct pv_hdr_head { -+ uint64_t magic; -+ uint32_t version; -+ uint32_t phs; -+ uint8_t iv[AES_256_GCM_IV_SIZE]; -+ uint32_t res1; -+ uint64_t nks; -+ uint64_t sea; -+ uint64_t nep; -+ uint64_t pcf; -+ union ecdh_pub_key cust_pub_key; -+ uint8_t pld[SHA512_DIGEST_LENGTH]; -+ uint8_t ald[SHA512_DIGEST_LENGTH]; -+ uint8_t tld[SHA512_DIGEST_LENGTH]; -+} __packed; -+ -+/* Must not have any padding */ -+struct pv_hdr_encrypted { -+ uint8_t cust_comm_key[32]; -+ uint8_t img_enc_key_1[AES_256_XTS_KEY_SIZE / 2]; -+ uint8_t img_enc_key_2[AES_256_XTS_KEY_SIZE / 2]; -+ struct psw_t psw; -+ uint64_t scf; -+ uint32_t noi; -+ uint32_t res2; -+}; -+STATIC_ASSERT(sizeof(struct pv_hdr_encrypted) == -+ 32 + 32 + 32 + sizeof(struct psw_t) + 8 + 4 + 4) -+ -+typedef struct pv_hdr { -+ struct pv_hdr_head head; -+ struct pv_hdr_key_slot *slots; -+ struct pv_hdr_encrypted *encrypted; -+ struct pv_hdr_opt_item **optional_items; -+ uint8_t tag[AES_256_GCM_TAG_SIZE]; -+} PvHdr; -+ -+#endif ---- /dev/null -+++ b/genprotimg/src/pv/pv_args.c -@@ -0,0 +1,405 @@ -+/* -+ * PV arguments related definitions and functions -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * 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 "common.h" -+ -+#include "pv_comp.h" -+#include "pv_error.h" -+#include "pv_args.h" -+ -+static gchar summary[] = -+ "Use genprotimg to create a protected virtualization kernel image file,\n" -+ "which can be loaded using zipl or QEMU."; -+ -+static gint pv_arg_compare(gconstpointer arg_1, gconstpointer arg_2) -+{ -+ g_assert(arg_1); -+ g_assert(arg_2); -+ -+ PvComponentType a = ((PvArg *)arg_1)->type; -+ PvComponentType b = ((PvArg *)arg_2)->type; -+ -+ if (a < b) -+ return -1; -+ if (a == b) -+ return 0; -+ return 1; -+} -+ -+static gint pv_arg_has_type(gconstpointer arg, gconstpointer type) -+{ -+ const PvArg *c = arg; -+ const PvComponentType *t = type; -+ -+ g_assert(arg); -+ -+ if (c->type == *t) -+ return 0; -+ if (c->type < *t) -+ return -1; -+ return 1; -+} -+ -+static gint pv_args_set_defaults(PvArgs *args, GError **err G_GNUC_UNUSED) -+{ -+ if (!args->psw_addr) -+ args->psw_addr = -+ g_strdup_printf("0x%lx", DEFAULT_INITIAL_PSW_ADDR); -+ -+ return 0; -+} -+ -+static gint pv_args_validate_options(PvArgs *args, GError **err) -+{ -+ PvComponentType KERNEL = PV_COMP_TYPE_KERNEL; -+ -+ if (args->unused_values->len > 0) { -+ g_autofree gchar *unused = NULL; -+ -+ for (gsize i = args->unused_values->len; i > 0; i--) { -+ g_autofree gchar *tmp = unused; -+ -+ unused = g_strjoin(" ", g_ptr_array_index(args->unused_values, i - 1), -+ tmp, -+ NULL); -+ } -+ -+ g_set_error(err, PV_PARSE_ERROR, PR_PARSE_ERROR_INVALID_ARGUMENT, -+ _("Unrecognized arguments: '%s'.\nUse 'genprotimg --help' for more information"), -+ unused); -+ return -1; -+ } -+ -+ if (!args->output_path) { -+ g_set_error(err, PV_PARSE_ERROR, PR_PARSE_ERROR_MISSING_ARGUMENT, -+ _("Option '--output' is required.\nUse 'genprotimg --help' for more information")); -+ return -1; -+ } -+ -+ if (!g_slist_find_custom(args->comps, &KERNEL, pv_arg_has_type)) { -+ g_set_error(err, PV_PARSE_ERROR, PR_PARSE_ERROR_MISSING_ARGUMENT, -+ _("Option '--image' is required.\nUse 'genprotimg --help' for more information")); -+ return -1; -+ } -+ -+ if (!args->host_keys || g_strv_length(args->host_keys) == 0) { -+ g_set_error(err, PV_PARSE_ERROR, PR_PARSE_ERROR_MISSING_ARGUMENT, -+ _("Option '--host-key-document' is required.\nUse 'genprotimg --help' for more information")); -+ return -1; -+ } -+ -+ if (!args->no_verify) { -+ g_set_error(err, PV_PARSE_ERROR, PR_PARSE_ERROR_MISSING_ARGUMENT, -+ _("Use the option '--no-verify' as the verification support is not available yet.")); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static gboolean cb_add_component(const gchar *option, const gchar *value, -+ PvArgs *args, GError **err) -+{ -+ PvArg *comp = NULL; -+ gint type = -1; -+ -+ if (g_str_equal(option, "-i") || g_str_equal(option, "--image")) -+ type = PV_COMP_TYPE_KERNEL; -+ if (g_str_equal(option, "-r") || g_str_equal(option, "--ramdisk")) -+ type = PV_COMP_TYPE_INITRD; -+ if (g_str_equal(option, "-p") || g_str_equal(option, "--parmfile")) -+ type = PV_COMP_TYPE_CMDLINE; -+ -+ if (type < 0) { -+ g_set_error(err, PV_PARSE_ERROR, PV_PARSE_ERROR_SYNTAX, -+ _("Invalid option '%s': "), option); -+ return FALSE; -+ } -+ -+ if (g_slist_find_custom(args->comps, &type, pv_arg_has_type)) { -+ g_set_error(err, PV_PARSE_ERROR, PV_PARSE_ERROR_SYNTAX, -+ _("Multiple values for option '%s'"), option); -+ return FALSE; -+ } -+ -+ comp = pv_arg_new((PvComponentType)type, value); -+ args->comps = g_slist_insert_sorted(args->comps, comp, pv_arg_compare); -+ return TRUE; -+} -+ -+static gboolean cb_set_string_option(const gchar *option, const gchar *value, -+ PvArgs *args, GError **err) -+{ -+ gchar **args_option = NULL; -+ -+ if (g_str_equal(option, "-o") || g_str_equal(option, "--output")) -+ args_option = &args->output_path; -+ if (g_str_equal(option, "--x-comp-key")) -+ args_option = &args->xts_key_path; -+ if (g_str_equal(option, "--x-comm-key")) -+ args_option = &args->cust_comm_key_path; -+ if (g_str_equal(option, "--x-header-key")) -+ args_option = &args->cust_root_key_path; -+ if (g_str_equal(option, "--x-pcf")) -+ args_option = &args->pcf; -+ if (g_str_equal(option, "--x-psw")) -+ args_option = &args->psw_addr; -+ if (g_str_equal(option, "--x-scf")) -+ args_option = &args->scf; -+ -+ if (!args_option) { -+ g_set_error(err, PV_PARSE_ERROR, PV_PARSE_ERROR_SYNTAX, -+ _("Invalid option '%s': "), option); -+ return FALSE; -+ } -+ -+ if (*args_option) { -+ g_set_error(err, PV_PARSE_ERROR, PV_PARSE_ERROR_SYNTAX, -+ _("Multiple values for option '%s'"), option); -+ return FALSE; -+ } -+ -+ *args_option = g_strdup(value); -+ 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) -+{ -+ args->log_level++; -+ return TRUE; -+} -+ -+static gboolean cb_remaining_values(const gchar *option G_GNUC_UNUSED, -+ const gchar *value, PvArgs *args, -+ GError **err G_GNUC_UNUSED) -+{ -+ g_ptr_array_add(args->unused_values, g_strdup(value)); -+ return TRUE; -+} -+ -+#define INDENT " " -+ -+gint pv_args_parse_options(PvArgs *args, gint *argc, gchar **argv[], -+ GError **err) -+{ -+ g_autoptr(GOptionContext) context = NULL; -+ gboolean print_version = FALSE; -+ GOptionGroup *group, *x_group; -+ -+ g_autofree gchar *psw_desc = g_strdup_printf( -+ _("Load from the specified hexadecimal ADDRESS.\n" INDENT -+ "Optional; default: '0x%lx'."), -+ DEFAULT_INITIAL_PSW_ADDR); -+ GOptionEntry entries[] = { -+ { .long_name = "host-key-document", -+ .short_name = 'k', -+ .flags = G_OPTION_FLAG_NONE, -+ .arg = G_OPTION_ARG_FILENAME_ARRAY, -+ .arg_data = &args->host_keys, -+ .description = -+ _("FILE specifies a host-key document. At least\n" INDENT -+ "one is required."), -+ .arg_description = _("FILE") }, -+ { .long_name = "output", -+ .short_name = 'o', -+ .flags = G_OPTION_FLAG_FILENAME, -+ .arg = G_OPTION_ARG_CALLBACK, -+ .arg_data = cb_set_string_option, -+ .description = _("Set FILE as the output file."), -+ .arg_description = _("FILE") }, -+ { .long_name = "image", -+ .short_name = 'i', -+ .flags = G_OPTION_FLAG_FILENAME, -+ .arg = G_OPTION_ARG_CALLBACK, -+ .arg_data = cb_add_component, -+ .description = _("Use IMAGE as the Linux kernel image."), -+ .arg_description = _("IMAGE") }, -+ { .long_name = "ramdisk", -+ .short_name = 'r', -+ .flags = G_OPTION_FLAG_OPTIONAL_ARG | G_OPTION_FLAG_FILENAME, -+ .arg = G_OPTION_ARG_CALLBACK, -+ .arg_data = cb_add_component, -+ .description = _("Use RAMDISK as the initial RAM disk\n" INDENT -+ "(optional)."), -+ .arg_description = _("RAMDISK") }, -+ { .long_name = "parmfile", -+ .short_name = 'p', -+ .flags = G_OPTION_FLAG_OPTIONAL_ARG | G_OPTION_FLAG_FILENAME, -+ .arg = G_OPTION_ARG_CALLBACK, -+ .arg_data = cb_add_component, -+ .description = _("Use the kernel parameters stored in PARMFILE\n" INDENT -+ "(optional)."), -+ .arg_description = _("PARMFILE") }, -+ { .long_name = "no-verify", -+ .short_name = 0, -+ .flags = G_OPTION_FLAG_NONE, -+ .arg = G_OPTION_ARG_NONE, -+ .arg_data = &args->no_verify, -+ .description = _("Disable the host-key document verification\n" INDENT -+ "(optional)."), -+ .arg_description = NULL }, -+ { .long_name = "verbose", -+ .short_name = 'V', -+ .flags = G_OPTION_FLAG_NO_ARG, -+ .arg = G_OPTION_ARG_CALLBACK, -+ .arg_data = cb_set_log_level, -+ .description = _("Provide more detailed output (optional)."), -+ .arg_description = NULL }, -+ { .long_name = "version", -+ .short_name = 'v', -+ .flags = G_OPTION_FLAG_NONE, -+ .arg = G_OPTION_ARG_NONE, -+ .arg_data = &print_version, -+ .description = _("Print the version and exit."), -+ .arg_description = NULL }, -+ { .long_name = G_OPTION_REMAINING, -+ .short_name = 0, -+ .flags = 0, -+ .arg = G_OPTION_ARG_CALLBACK, -+ .arg_data = cb_remaining_values, -+ .description = NULL, -+ .arg_description = NULL }, -+ { 0 }, -+ }; -+ -+ GOptionEntry x_entries[] = { -+ { .long_name = "x-comm-key", -+ .short_name = 0, -+ .flags = G_OPTION_FLAG_FILENAME, -+ .arg = G_OPTION_ARG_CALLBACK, -+ .arg_data = cb_set_string_option, -+ .description = _( -+ "Use FILE as the customer communication key.\n" INDENT -+ "Optional; default: auto-generated."), -+ .arg_description = _("FILE") }, -+ { .long_name = "x-comp-key", -+ .short_name = 0, -+ .flags = G_OPTION_FLAG_FILENAME, -+ .arg = G_OPTION_ARG_CALLBACK, -+ .arg_data = cb_set_string_option, -+ .description = _( -+ "Use FILE as the AES 256-bit XTS key\n" INDENT -+ "that is used for the component encryption.\n" INDENT -+ "Optional; default: auto-generated."), -+ .arg_description = _("FILE") }, -+ { .long_name = "x-header-key", -+ .short_name = 0, -+ .flags = G_OPTION_FLAG_FILENAME, -+ .arg = G_OPTION_ARG_CALLBACK, -+ .arg_data = cb_set_string_option, -+ .description = _( -+ "Use FILE as the AES 256-bit GCM header key\n" INDENT -+ "that protects the PV header.\n" INDENT -+ "Optional; default: auto-generated."), -+ .arg_description = _("FILE") }, -+ { .long_name = "x-pcf", -+ .short_name = 0, -+ .flags = G_OPTION_FLAG_NONE, -+ .arg = G_OPTION_ARG_CALLBACK, -+ .arg_data = cb_set_string_option, -+ .description = -+ _("Specify the plaintext control flags\n" INDENT -+ "as a hexadecimal value.\n" INDENT -+ "Optional; default: '0x0'."), -+ .arg_description = _("VALUE") }, -+ { .long_name = "x-psw", -+ .short_name = 0, -+ .flags = G_OPTION_FLAG_NONE, -+ .arg = G_OPTION_ARG_CALLBACK, -+ .arg_data = cb_set_string_option, -+ .description = psw_desc, -+ .arg_description = _("ADDRESS") }, -+ { .long_name = "x-scf", -+ .short_name = 0, -+ .flags = G_OPTION_FLAG_NONE, -+ .arg = G_OPTION_ARG_CALLBACK, -+ .arg_data = cb_set_string_option, -+ .description = _("Specify the secret control flags\n" INDENT -+ "as a hexadecimal value.\n" INDENT -+ "Optional; default: '0x0'."), -+ .arg_description = _("VALUE") }, -+ { 0 }, -+ }; -+ -+ context = g_option_context_new( -+ _("- Create a protected virtualization image")); -+ g_option_context_set_summary(context, _(summary)); -+ group = g_option_group_new(GETTEXT_PACKAGE, _("Application Options:"), -+ _("Show help options"), args, NULL); -+ g_option_group_add_entries(group, entries); -+ g_option_context_set_main_group(context, group); -+ -+ x_group = g_option_group_new("experimental", _("Experimental Options:"), -+ _("Show experimental options"), args, NULL); -+ g_option_group_add_entries(x_group, x_entries); -+ g_option_context_add_group(context, x_group); -+ if (!g_option_context_parse(context, argc, argv, err)) -+ return -1; -+ -+ if (print_version) { -+ g_printf(_("%s version %s\n"), tool_name, RELEASE_STRING); -+ g_printf("%s\n", copyright_notice); -+ exit(EXIT_SUCCESS); -+ } -+ -+ if (pv_args_set_defaults(args, err) < 0) -+ return -1; -+ -+ return pv_args_validate_options(args, err); -+} -+ -+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); -+ return g_steal_pointer(&args); -+} -+ -+void pv_args_free(PvArgs *args) -+{ -+ if (!args) -+ return; -+ -+ g_free(args->pcf); -+ g_free(args->scf); -+ g_free(args->psw_addr); -+ g_free(args->cust_root_key_path); -+ g_free(args->cust_comm_key_path); -+ g_free(args->gcm_iv_path); -+ g_strfreev(args->host_keys); -+ g_free(args->xts_key_path); -+ g_slist_free_full(args->comps, (GDestroyNotify)pv_arg_free); -+ g_ptr_array_free(args->unused_values, TRUE); -+ g_free(args->output_path); -+ g_free(args->tmp_dir); -+ g_free(args); -+} -+ -+void pv_arg_free(PvArg *arg) -+{ -+ if (!arg) -+ return; -+ -+ g_free(arg->path); -+ g_free(arg); -+} -+PvArg *pv_arg_new(PvComponentType type, const gchar *path) -+{ -+ g_autoptr(PvArg) ret = g_new0(struct pv_arg, 1); -+ -+ ret->type = type; -+ ret->path = g_strdup(path); -+ return g_steal_pointer(&ret); -+} ---- /dev/null -+++ b/genprotimg/src/pv/pv_args.h -@@ -0,0 +1,53 @@ -+/* -+ * PV arguments related definitions and functions -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * s390-tools is free software; you can redistribute it and/or modify -+ * it under the terms of the MIT license. See LICENSE for details. -+ */ -+ -+#ifndef PV_ARGS_H -+#define PV_ARGS_H -+ -+#include -+ -+#include "pv_comp.h" -+ -+typedef struct pv_arg { -+ PvComponentType type; -+ gchar *path; -+} PvArg; -+ -+PvArg *pv_arg_new(PvComponentType type, const gchar *path); -+void pv_arg_free(PvArg *arg); -+ -+typedef struct { -+ gint log_level; -+ gint no_verify; -+ gchar *pcf; -+ gchar *scf; -+ gchar *psw_addr; /* PSW address which will be used for the start of -+ * the actual component (e.g. Linux kernel) -+ */ -+ gchar *cust_root_key_path; -+ gchar *cust_comm_key_path; -+ gchar *gcm_iv_path; -+ gchar **host_keys; -+ gchar *xts_key_path; -+ GSList *comps; -+ gchar *output_path; -+ gchar *tmp_dir; -+ GPtrArray *unused_values; -+} PvArgs; -+ -+PvArgs *pv_args_new(void); -+void pv_args_free(PvArgs *args); -+ -+gint pv_args_parse_options(PvArgs *args, gint *argc, gchar **argv[], -+ GError **err); -+ -+WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(PvArg, pv_arg_free) -+WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(PvArgs, pv_args_free) -+ -+#endif ---- /dev/null -+++ b/genprotimg/src/pv/pv_comp.c -@@ -0,0 +1,446 @@ -+/* -+ * PV component related definitions and functions -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * 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 -+#include -+#include -+#include -+ -+#include "boot/s390.h" -+#include "common.h" -+#include "utils/align.h" -+#include "utils/buffer.h" -+#include "utils/crypto.h" -+#include "utils/file_utils.h" -+ -+#include "pv_comp.h" -+#include "pv_error.h" -+ -+static void comp_file_free(CompFile *comp) -+{ -+ if (!comp) -+ return; -+ -+ g_free(comp->path); -+ g_free(comp); -+} -+ -+WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(CompFile, comp_file_free) -+ -+static PvComponent *pv_component_new(PvComponentType type, gsize size, -+ PvComponentDataType d_type, void **data, -+ GError **err) -+{ -+ g_autoptr(PvComponent) ret = g_new0(PvComponent, 1); -+ -+ g_assert(type >= 0 && type <= UINT16_MAX); -+ -+ ret->type = (int)type; -+ ret->d_type = (int)d_type; -+ ret->data = g_steal_pointer(data); -+ ret->orig_size = size; -+ -+ if (generate_tweak(&ret->tweak, (uint16_t)type, err) < 0) -+ return NULL; -+ -+ return g_steal_pointer(&ret); -+} -+ -+PvComponent *pv_component_new_file(PvComponentType type, const gchar *path, -+ GError **err) -+{ -+ g_autoptr(CompFile) file = g_new0(CompFile, 1); -+ gsize size; -+ gint rc; -+ -+ g_assert(path != NULL); -+ -+ rc = file_size(path, &size, err); -+ if (rc < 0) -+ return NULL; -+ -+ file->path = g_strdup(path); -+ file->size = size; -+ return pv_component_new(type, size, DATA_FILE, (void **)&file, err); -+} -+ -+PvComponent *pv_component_new_buf(PvComponentType type, const Buffer *buf, -+ GError **err) -+{ -+ g_assert(buf); -+ -+ g_autoptr(Buffer) dup_buf = buffer_dup(buf, FALSE); -+ return pv_component_new(type, buf->size, DATA_BUFFER, (void **)&dup_buf, -+ err); -+} -+ -+void pv_component_free(PvComponent *component) -+{ -+ if (!component) -+ return; -+ -+ switch ((PvComponentDataType)component->d_type) { -+ case DATA_BUFFER: -+ buffer_clear(&component->buf); -+ break; -+ case DATA_FILE: -+ comp_file_free(component->file); -+ break; -+ } -+ -+ g_free(component); -+} -+ -+gint pv_component_type(const PvComponent *component) -+{ -+ return component->type; -+} -+ -+const gchar *pv_component_name(const PvComponent *component) -+{ -+ gint type = pv_component_type(component); -+ -+ switch ((PvComponentType)type) { -+ case PV_COMP_TYPE_KERNEL: -+ return "kernel"; -+ case PV_COMP_TYPE_INITRD: -+ return "ramdisk"; -+ case PV_COMP_TYPE_CMDLINE: -+ return "parmline"; -+ case PV_COMP_TYPE_STAGE3B: -+ return "stage3b"; -+ } -+ -+ g_assert_not_reached(); -+} -+ -+uint64_t pv_component_size(const PvComponent *component) -+{ -+ switch ((PvComponentDataType)component->d_type) { -+ case DATA_BUFFER: -+ return component->buf->size; -+ case DATA_FILE: -+ return component->file->size; -+ } -+ -+ g_assert_not_reached(); -+} -+ -+uint64_t pv_component_get_src_addr(const PvComponent *component) -+{ -+ return component->src_addr; -+} -+ -+uint64_t pv_component_get_orig_size(const PvComponent *component) -+{ -+ return component->orig_size; -+} -+ -+uint64_t pv_component_get_tweak_prefix(const PvComponent *component) -+{ -+ return GUINT64_FROM_BE(component->tweak.cmp_idx.data); -+} -+ -+gboolean pv_component_is_stage3b(const PvComponent *component) -+{ -+ return pv_component_type(component) == PV_COMP_TYPE_STAGE3B; -+} -+ -+gint pv_component_align_and_encrypt(PvComponent *component, const gchar *tmp_path, -+ void *opaque, GError **err) -+{ -+ struct cipher_parms *parms = opaque; -+ -+ switch ((PvComponentDataType)component->d_type) { -+ case DATA_BUFFER: { -+ g_autoptr(Buffer) enc_buf = NULL; -+ -+ if (!(IS_PAGE_ALIGNED(pv_component_size(component)))) { -+ g_autoptr(Buffer) new = NULL; -+ -+ /* create a page aligned copy */ -+ new = buffer_dup(component->buf, TRUE); -+ buffer_clear(&component->buf); -+ component->buf = g_steal_pointer(&new); -+ } -+ enc_buf = encrypt_buf(parms, component->buf, err); -+ if (!enc_buf) -+ return -1; -+ -+ buffer_clear(&component->buf); -+ component->buf = g_steal_pointer(&enc_buf); -+ return 0; -+ } -+ case DATA_FILE: { -+ const gchar *comp_name = pv_component_name(component); -+ gchar *path_in = component->file->path; -+ g_autofree gchar *path_out = NULL; -+ gsize orig_size; -+ gsize prep_size; -+ -+ g_assert(path_in); -+ -+ path_out = g_build_filename(tmp_path, comp_name, NULL); -+ if (encrypt_file(parms, path_in, path_out, &orig_size, -+ &prep_size, err) < 0) -+ return -1; -+ -+ if (component->orig_size != orig_size) { -+ g_set_error(err, G_FILE_ERROR, PV_ERROR_INTERNAL, -+ _("File has changed during the preparation '%s'"), -+ path_out); -+ return -1; -+ } -+ -+ g_free(component->file->path); -+ component->file->size = prep_size; -+ component->file->path = g_steal_pointer(&path_out); -+ return 0; -+ } -+ } -+ -+ g_assert_not_reached(); -+} -+ -+/* Page align the size of the component */ -+gint pv_component_align(PvComponent *component, const gchar *tmp_path, -+ void *opaque G_GNUC_UNUSED, GError **err) -+{ -+ if (IS_PAGE_ALIGNED(pv_component_size(component))) -+ return 0; -+ -+ switch (component->d_type) { -+ case DATA_BUFFER: { -+ g_autoptr(Buffer) buf = NULL; -+ -+ buf = buffer_dup(component->buf, TRUE); -+ buffer_clear(&component->buf); -+ component->buf = g_steal_pointer(&buf); -+ return 0; -+ } break; -+ case DATA_FILE: { -+ const gchar *comp_name = pv_component_name(component); -+ g_autofree gchar *path_out = -+ g_build_filename(tmp_path, comp_name, NULL); -+ gchar *path_in = component->file->path; -+ gsize size_out; -+ -+ if (pad_file_right(path_out, path_in, &size_out, PAGE_SIZE, -+ err) < 0) -+ return -1; -+ -+ g_free(component->file->path); -+ component->file->path = g_steal_pointer(&path_out); -+ component->file->size = size_out; -+ return 0; -+ } break; -+ } -+ -+ g_assert_not_reached(); -+} -+ -+/* Convert uint64_t address to byte array */ -+static void uint64_to_uint8_buf(uint8_t dst[8], uint64_t addr) -+{ -+ uint8_t *p = (uint8_t *)&addr; -+ -+ g_assert(dst); -+ -+ for (gint i = 0; i < 8; i++) { -+ /* cppcheck-suppress objectIndex */ -+ dst[i] = p[i]; -+ } -+} -+ -+int64_t pv_component_update_ald(const PvComponent *comp, EVP_MD_CTX *ctx, -+ GError **err) -+{ -+ uint64_t addr = pv_component_get_src_addr(comp); -+ uint64_t size = pv_component_size(comp); -+ uint64_t cur = addr; -+ int64_t nep = 0; -+ -+ g_assert(IS_PAGE_ALIGNED(size) && size != 0); -+ -+ do { -+ uint64_t cur_be = GUINT64_TO_BE(cur); -+ uint8_t addr_buf[8]; -+ -+ uint64_to_uint8_buf(addr_buf, cur_be); -+ -+ if (EVP_DigestUpdate(ctx, addr_buf, sizeof(addr_buf)) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_INTERNAL, -+ _("EVP_DigestUpdate failed")); -+ return -1; -+ } -+ -+ cur += PAGE_SIZE; -+ nep++; -+ } while (cur < addr + size); -+ -+ return nep; -+} -+ -+int64_t pv_component_update_pld(const PvComponent *comp, EVP_MD_CTX *ctx, -+ GError **err) -+{ -+ uint64_t size = pv_component_size(comp); -+ int64_t nep = 0; -+ -+ g_assert(IS_PAGE_ALIGNED(size) && size != 0); -+ -+ switch (comp->d_type) { -+ case DATA_BUFFER: { -+ const Buffer *buf = comp->buf; -+ -+ g_assert(buf->size <= INT64_MAX); -+ g_assert(buf->size == size); -+ -+ if (EVP_DigestUpdate(ctx, buf->data, buf->size) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_INTERNAL, -+ _("EVP_DigestUpdate failed")); -+ return -1; -+ } -+ -+ nep = (int64_t)(buf->size / PAGE_SIZE); -+ break; -+ } -+ case DATA_FILE: { -+ const gchar *in_path = comp->file->path; -+ guchar in_buf[PAGE_SIZE]; -+ gsize num_bytes_read_total = 0; -+ gsize num_bytes_read = 0; -+ FILE *f_in; -+ -+ f_in = file_open(in_path, "rb", err); -+ if (!f_in) -+ return -1; -+ -+ do { -+ /* Read data in blocks. Update the digest -+ * context each read. -+ */ -+ if (file_read(f_in, in_buf, sizeof(*in_buf), -+ sizeof(in_buf), &num_bytes_read, -+ err) < 0) { -+ fclose(f_in); -+ return -1; -+ } -+ num_bytes_read_total += num_bytes_read; -+ -+ if (EVP_DigestUpdate(ctx, in_buf, sizeof(in_buf)) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_INTERNAL, -+ _("EVP_DigestUpdate failed")); -+ fclose(f_in); -+ return -1; -+ } -+ -+ nep++; -+ } while (num_bytes_read_total < pv_component_size(comp) && -+ num_bytes_read != 0); -+ -+ if (num_bytes_read_total != pv_component_size(comp)) { -+ g_set_error(err, G_FILE_ERROR, PV_ERROR_INTERNAL, -+ _("'%s' has changed during the preparation"), -+ in_path); -+ fclose(f_in); -+ return -1; -+ } -+ fclose(f_in); -+ break; -+ } -+ default: -+ g_assert_not_reached(); -+ } -+ -+ return nep; -+} -+ -+int64_t pv_component_update_tld(const PvComponent *comp, EVP_MD_CTX *ctx, -+ GError **err) -+{ -+ uint64_t size = pv_component_size(comp); -+ const union tweak *tweak = &comp->tweak; -+ g_autoptr(BIGNUM) tweak_num = NULL; -+ int64_t nep = 0; -+ -+ g_assert(IS_PAGE_ALIGNED(size) && size != 0); -+ -+ tweak_num = BN_bin2bn(tweak->data, sizeof(tweak->data), NULL); -+ if (!tweak_num) { -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_INTERNAL, -+ _("BN_bin2bn failed")); -+ } -+ -+ for (uint64_t cur = 0; cur < size; cur += PAGE_SIZE) { -+ guchar tmp[sizeof(tweak->data)] = { 0 }; -+ -+ g_assert(BN_num_bytes(tweak_num) >= 0); -+ g_assert(sizeof(tmp) - (guint)BN_num_bytes(tweak_num) > 0); -+ -+ if (BN_bn2binpad(tweak_num, tmp, sizeof(tmp)) < 0) { -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_INTERNAL, -+ _("BN_bn2binpad failed")); -+ } -+ -+ if (EVP_DigestUpdate(ctx, tmp, sizeof(tmp)) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_INTERNAL, -+ _("EVP_DigestUpdate failed")); -+ return -1; -+ } -+ -+ /* calculate new tweak value */ -+ if (BN_add_word(tweak_num, PAGE_SIZE) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_INTERNAL, -+ _("BN_add_word failed")); -+ } -+ -+ nep++; -+ } -+ -+ return nep; -+} -+ -+gint pv_component_write(const PvComponent *component, FILE *f, GError **err) -+{ -+ uint64_t offset = pv_component_get_src_addr(component); -+ -+ g_assert(f); -+ -+ switch (component->d_type) { -+ case DATA_BUFFER: { -+ const Buffer *buf = component->buf; -+ -+ if (seek_and_write_buffer(f, buf, offset, err) < 0) -+ return -1; -+ -+ return 0; -+ } -+ case DATA_FILE: { -+ const CompFile *file = component->file; -+ -+ if (seek_and_write_file(f, file, offset, err) < 0) -+ return -1; -+ -+ return 0; -+ } -+ } -+ -+ g_assert_not_reached(); -+} ---- /dev/null -+++ b/genprotimg/src/pv/pv_comp.h -@@ -0,0 +1,78 @@ -+/* -+ * PV component related definitions and functions -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * s390-tools is free software; you can redistribute it and/or modify -+ * it under the terms of the MIT license. See LICENSE for details. -+ */ -+ -+#ifndef PV_COMP_H -+#define PV_COMP_H -+ -+#include -+#include -+#include -+ -+#include "utils/crypto.h" -+ -+/* The order of this enum also implicitly defines the order of the -+ * components within the PV image! -+ */ -+typedef enum { -+ PV_COMP_TYPE_KERNEL = 0, -+ PV_COMP_TYPE_CMDLINE = 1, -+ PV_COMP_TYPE_INITRD = 2, -+ PV_COMP_TYPE_STAGE3B = 3, -+} PvComponentType; -+ -+typedef enum { -+ DATA_FILE = 0, -+ DATA_BUFFER, -+} PvComponentDataType; -+ -+typedef struct comp_file { -+ gchar *path; -+ gsize size; -+} CompFile; -+ -+typedef struct { -+ gint type; /* PvComponentType */ -+ gint d_type; /* PvComponentDataType */ -+ union { -+ struct comp_file *file; -+ Buffer *buf; -+ void *data; -+ }; -+ uint64_t src_addr; -+ uint64_t orig_size; -+ union tweak tweak; /* used for the AES XTS encryption */ -+} PvComponent; -+ -+PvComponent *pv_component_new_file(PvComponentType type, const gchar *path, -+ GError **err); -+PvComponent *pv_component_new_buf(PvComponentType type, const Buffer *buf, -+ GError **err); -+void pv_component_free(PvComponent *component); -+gint pv_component_type(const PvComponent *component); -+const gchar *pv_component_name(const PvComponent *component); -+uint64_t pv_component_size(const PvComponent *component); -+uint64_t pv_component_get_src_addr(const PvComponent *component); -+uint64_t pv_component_get_orig_size(const PvComponent *component); -+uint64_t pv_component_get_tweak_prefix(const PvComponent *component); -+gboolean pv_component_is_stage3b(const PvComponent *component); -+gint pv_component_align_and_encrypt(PvComponent *component, const gchar *tmp_path, -+ void *opaque, GError **err); -+gint pv_component_align(PvComponent *component, const gchar *tmp_path, -+ void *opaque G_GNUC_UNUSED, GError **err); -+int64_t pv_component_update_pld(const PvComponent *comp, EVP_MD_CTX *ctx, -+ GError **err); -+int64_t pv_component_update_ald(const PvComponent *comp, EVP_MD_CTX *ctx, -+ GError **err); -+int64_t pv_component_update_tld(const PvComponent *comp, EVP_MD_CTX *ctx, -+ GError **err); -+gint pv_component_write(const PvComponent *component, FILE *f, GError **err); -+ -+WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(PvComponent, pv_component_free) -+ -+#endif ---- /dev/null -+++ b/genprotimg/src/pv/pv_comps.c -@@ -0,0 +1,252 @@ -+/* -+ * PV components related definitions and functions -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * 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 -+ -+#include "boot/s390.h" -+#include "boot/stage3b.h" -+#include "common.h" -+#include "utils/align.h" -+#include "utils/crypto.h" -+ -+#include "pv_comp.h" -+#include "pv_comps.h" -+#include "pv_error.h" -+#include "pv_stage3.h" -+ -+struct _pv_img_comps { -+ gboolean finalized; -+ uint64_t next_src; -+ uint64_t nep; -+ EVP_MD_CTX *ald; /* context used for the hash of the addresses */ -+ EVP_MD_CTX *pld; /* context used for the hash of the pages content */ -+ EVP_MD_CTX *tld; /* context used for the hash of the tweaks */ -+ GSList *comps; /* elements sorted by component type */ -+}; -+ -+void pv_img_comps_free(PvImgComps *comps) -+{ -+ if (!comps) -+ return; -+ -+ EVP_MD_CTX_free(comps->ald); -+ EVP_MD_CTX_free(comps->pld); -+ EVP_MD_CTX_free(comps->tld); -+ g_slist_free_full(comps->comps, (GDestroyNotify)pv_component_free); -+ g_free(comps); -+} -+ -+PvImgComps *pv_img_comps_new(const EVP_MD *ald_md, const EVP_MD *pld_md, -+ const EVP_MD *tld_md, GError **err) -+{ -+ g_autoptr(PvImgComps) ret = g_new0(PvImgComps, 1); -+ -+ ret->ald = digest_ctx_new(ald_md, err); -+ if (!ret->ald) -+ return NULL; -+ -+ ret->pld = digest_ctx_new(pld_md, err); -+ if (!ret->pld) -+ return NULL; -+ -+ ret->tld = digest_ctx_new(tld_md, err); -+ if (!ret->tld) -+ return NULL; -+ -+ return g_steal_pointer(&ret); -+} -+ -+guint pv_img_comps_length(const PvImgComps *comps) -+{ -+ return g_slist_length(comps->comps); -+} -+ -+/* Update hashes and nep */ -+/* Returns 0 in case of success and -1 in case of a failure */ -+static gint pv_img_comps_hash_comp(PvImgComps *comps, const PvComponent *comp, -+ GError **err) -+{ -+ int64_t nep_1 = 0; -+ int64_t nep_2 = 0; -+ int64_t nep_3 = 0; -+ -+ /* update pld */ -+ nep_1 = pv_component_update_pld(comp, comps->pld, err); -+ if (nep_1 < 0) -+ return -1; -+ -+ /* update ald */ -+ nep_2 = pv_component_update_ald(comp, comps->ald, err); -+ if (nep_2 < 0) -+ return -1; -+ -+ /* update tld */ -+ nep_3 = pv_component_update_tld(comp, comps->tld, err); -+ if (nep_3 < 0) -+ return -1; -+ -+ g_assert(nep_1 == nep_2); -+ g_assert(nep_2 == nep_3); -+ -+ /* update comps->nep */ -+ g_assert_true(g_uint64_checked_add(&comps->nep, comps->nep, -+ (uint64_t)nep_1)); -+ return 0; -+} -+ -+gint pv_img_comps_add_component(PvImgComps *comps, PvComponent **comp, -+ GError **err) -+{ -+ g_assert(comp); -+ g_assert(*comp); -+ g_assert(comps); -+ g_assert(IS_PAGE_ALIGNED(comps->next_src)); -+ -+ uint64_t src_addr = comps->next_src; -+ uint64_t src_size = pv_component_size(*comp) -+ ? PAGE_ALIGN(pv_component_size(*comp)) -+ : PAGE_SIZE; -+ -+ if (comps->finalized) { -+ g_set_error(err, PV_COMPONENT_ERROR, PV_COMPONENT_ERROR_FINALIZED, -+ _("Failed to add component, image is already finalized")); -+ return -1; -+ } -+ -+ /* set the address of the component in the memory layout */ -+ (*comp)->src_addr = src_addr; -+ -+ g_info("%12s:\t0x%012lx (%12ld / %12ld Bytes)", -+ pv_component_name(*comp), pv_component_get_src_addr(*comp), -+ pv_component_size(*comp), pv_component_get_orig_size(*comp)); -+ -+ /* append the component and pass the responsibility of @comp -+ * to @comps -+ */ -+ comps->comps = g_slist_append(comps->comps, g_steal_pointer(comp)); -+ comps->next_src += src_size; -+ -+ g_assert(IS_PAGE_ALIGNED(comps->next_src)); -+ g_assert(!*comp); -+ return 0; -+} -+ -+struct stage3b_args *pv_img_comps_get_stage3b_args(const PvImgComps *comps, -+ struct psw_t *psw) -+{ -+ g_autofree struct stage3b_args *ret = g_new0(struct stage3b_args, 1); -+ -+ for (GSList *iterator = comps->comps; iterator; iterator = iterator->next) { -+ const PvComponent *img_comp = iterator->data; -+ uint64_t src_addr, dst_size; -+ -+ g_assert(img_comp); -+ -+ src_addr = pv_component_get_src_addr(img_comp); -+ dst_size = pv_component_get_orig_size(img_comp); -+ -+ g_assert(dst_size <= pv_component_size(img_comp)); -+ -+ switch ((PvComponentType)pv_component_type(img_comp)) { -+ case PV_COMP_TYPE_KERNEL: -+ memblob_init(&ret->kernel, src_addr, dst_size); -+ break; -+ case PV_COMP_TYPE_CMDLINE: -+ memblob_init(&ret->cmdline, src_addr, dst_size); -+ break; -+ case PV_COMP_TYPE_INITRD: -+ memblob_init(&ret->initrd, src_addr, dst_size); -+ break; -+ case PV_COMP_TYPE_STAGE3B: -+ /* nothing needs to be done since it is the -+ * stage3b itself -+ */ -+ break; -+ default: -+ g_assert_not_reached(); -+ break; -+ } -+ } -+ -+ /* for `stage3b_args` big-endian format must be used */ -+ ret->psw.mask = GUINT64_TO_BE(psw->mask); -+ ret->psw.addr = GUINT64_TO_BE(psw->addr); -+ return g_steal_pointer(&ret); -+} -+ -+gint pv_img_comps_set_offset(PvImgComps *comps, gsize offset, GError **err) -+{ -+ g_assert(IS_PAGE_ALIGNED(comps->next_src)); -+ -+ if (!IS_PAGE_ALIGNED(offset)) { -+ g_set_error(err, PV_IMAGE_ERROR, PV_IMAGE_ERROR_OFFSET, -+ _("Offset must be page aligned")); -+ return -1; -+ } -+ -+ if (pv_img_comps_length(comps) > 0) { -+ g_set_error(err, PV_IMAGE_ERROR, PV_IMAGE_ERROR_OFFSET, -+ _("Offset cannot be changed after a component was added")); -+ return -1; -+ } -+ -+ comps->next_src += offset; -+ -+ g_assert(IS_PAGE_ALIGNED(comps->next_src)); -+ return 0; -+} -+ -+GSList *pv_img_comps_get_comps(const PvImgComps *comps) -+{ -+ return comps->comps; -+} -+ -+gint pv_img_comps_finalize(PvImgComps *comps, Buffer **pld_digest, -+ Buffer **ald_digest, Buffer **tld_digest, -+ uint64_t *nep, GError **err) -+{ -+ g_autoptr(Buffer) tmp_pld_digest = NULL; -+ g_autoptr(Buffer) tmp_ald_digest = NULL; -+ g_autoptr(Buffer) tmp_tld_digest = NULL; -+ -+ comps->finalized = TRUE; -+ for (GSList *iterator = comps->comps; iterator; iterator = iterator->next) { -+ const PvComponent *comp = iterator->data; -+ -+ /* update hashes and nep */ -+ if (pv_img_comps_hash_comp(comps, comp, err) < 0) -+ return -1; -+ } -+ -+ tmp_pld_digest = digest_ctx_finalize(comps->pld, err); -+ if (!tmp_pld_digest) -+ return -1; -+ -+ tmp_ald_digest = digest_ctx_finalize(comps->ald, err); -+ if (!tmp_ald_digest) -+ return -1; -+ -+ tmp_tld_digest = digest_ctx_finalize(comps->tld, err); -+ if (!tmp_tld_digest) -+ return -1; -+ -+ *pld_digest = g_steal_pointer(&tmp_pld_digest); -+ *ald_digest = g_steal_pointer(&tmp_ald_digest); -+ *tld_digest = g_steal_pointer(&tmp_tld_digest); -+ *nep = comps->nep; -+ return 0; -+} -+ -+PvComponent *pv_img_comps_get_nth_comp(PvImgComps *comps, guint n) -+{ -+ return g_slist_nth_data(comps->comps, n); -+} ---- /dev/null -+++ b/genprotimg/src/pv/pv_comps.h -@@ -0,0 +1,42 @@ -+/* -+ * PV components related definitions and functions -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * s390-tools is free software; you can redistribute it and/or modify -+ * it under the terms of the MIT license. See LICENSE for details. -+ */ -+ -+#ifndef PV_COMPS_H -+#define PV_COMPS_H -+ -+#include -+#include -+#include -+ -+#include "boot/s390.h" -+#include "boot/stage3b.h" -+#include "utils/buffer.h" -+ -+#include "pv_comp.h" -+ -+typedef struct _pv_img_comps PvImgComps; -+ -+PvImgComps *pv_img_comps_new(const EVP_MD *ald_md, const EVP_MD *pld_md, -+ const EVP_MD *tld_md, GError **err); -+guint pv_img_comps_length(const PvImgComps *comps); -+GSList *pv_img_comps_get_comps(const PvImgComps *comps); -+struct stage3b_args *pv_img_comps_get_stage3b_args(const PvImgComps *comps, -+ struct psw_t *psw); -+gint pv_img_comps_add_component(PvImgComps *comps, PvComponent **comp, -+ GError **err); -+PvComponent *pv_img_comps_get_nth_comp(PvImgComps *comps, guint n); -+gint pv_img_comps_set_offset(PvImgComps *comps, gsize offset, GError **err); -+gint pv_img_comps_finalize(PvImgComps *comps, Buffer **pld_digest, -+ Buffer **ald_digest, Buffer **tld_digest, -+ uint64_t *nep, GError **err); -+void pv_img_comps_free(PvImgComps *comps); -+ -+WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(PvImgComps, pv_img_comps_free) -+ -+#endif ---- /dev/null -+++ b/genprotimg/src/pv/pv_error.c -@@ -0,0 +1,37 @@ -+/* -+ * PV error related functions -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * 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 "pv_error.h" -+ -+GQuark pv_error_quark(void) -+{ -+ return g_quark_from_static_string("pv-error-quark"); -+} -+ -+GQuark pv_crypto_error_quark(void) -+{ -+ return g_quark_from_static_string("pv-crypto-error-quark"); -+} -+ -+GQuark pv_component_error_quark(void) -+{ -+ return g_quark_from_static_string("pv-component-error-quark"); -+} -+ -+GQuark pv_image_error_quark(void) -+{ -+ return g_quark_from_static_string("pv-image-error-quark"); -+} -+ -+GQuark pv_parse_error_quark(void) -+{ -+ return g_quark_from_static_string("pv-parse-error-quark"); -+} ---- /dev/null -+++ b/genprotimg/src/pv/pv_error.h -@@ -0,0 +1,62 @@ -+/* -+ * PV error related definitions and functions -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * s390-tools is free software; you can redistribute it and/or modify -+ * it under the terms of the MIT license. See LICENSE for details. -+ */ -+ -+#ifndef PV_ERROR_H -+#define PV_ERROR_H -+ -+#include -+ -+GQuark pv_error_quark(void); -+GQuark pv_parse_error_quark(void); -+GQuark pv_component_error_quark(void); -+GQuark pv_crypto_error_quark(void); -+GQuark pv_image_error_quark(void); -+ -+#define PV_ERROR pv_error_quark() -+#define PV_PARSE_ERROR pv_parse_error_quark() -+#define PV_CRYPTO_ERROR pv_crypto_error_quark() -+#define PV_COMPONENT_ERROR pv_component_error_quark() -+#define PV_IMAGE_ERROR pv_image_error_quark() -+ -+typedef enum { -+ PV_ERROR_IPIB_SIZE, -+ PV_ERROR_PV_HDR_SIZE, -+ PV_ERROR_INTERNAL, -+} PvErrors; -+ -+typedef enum { -+ PV_PARSE_ERROR_OK = 0, -+ PV_PARSE_ERROR_SYNTAX, -+ PR_PARSE_ERROR_INVALID_ARGUMENT, -+ PR_PARSE_ERROR_MISSING_ARGUMENT, -+} PvParseErrors; -+ -+typedef enum { -+ PV_COMPONENT_ERROR_UNALIGNED, -+ PV_COMPONENT_ERROR_FINALIZED, -+} PvComponentErrors; -+ -+typedef enum { -+ PV_IMAGE_ERROR_OFFSET, -+ PV_IMAGE_ERROR_FINALIZED, -+} PvImageErrors; -+ -+typedef enum { -+ PV_CRYPTO_ERROR_VERIFICATION, -+ PV_CRYPTO_ERROR_INIT, -+ PV_CRYPTO_ERROR_READ_CERTIFICATE, -+ PV_CRYPTO_ERROR_INTERNAL, -+ PV_CRYPTO_ERROR_DERIVE, -+ PV_CRYPTO_ERROR_KEYGENERATION, -+ PV_CRYPTO_ERROR_RANDOMIZATION, -+ PV_CRYPTO_ERROR_INVALID_PARM, -+ PV_CRYPTO_ERROR_INVALID_KEY_SIZE, -+} PvCryptoErrors; -+ -+#endif ---- /dev/null -+++ b/genprotimg/src/pv/pv_hdr.c -@@ -0,0 +1,293 @@ -+/* -+ * PV header related functions -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * 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 -+#include -+#include -+ -+#include "boot/s390.h" -+#include "include/pv_crypto_def.h" -+#include "utils/buffer.h" -+#include "utils/crypto.h" -+ -+#include "pv_comp.h" -+#include "pv_hdr.h" -+#include "pv_image.h" -+ -+void pv_hdr_free(PvHdr *hdr) -+{ -+ if (!hdr) -+ return; -+ -+ g_free(hdr->optional_items); -+ g_free(hdr->encrypted); -+ g_free(hdr->slots); -+ g_free(hdr); -+} -+ -+uint32_t pv_hdr_size(const PvHdr *hdr) -+{ -+ return GUINT32_FROM_BE(hdr->head.phs); -+} -+ -+gboolean pv_hdr_uses_encryption(const PvHdr *hdr) -+{ -+ return !(GUINT64_FROM_BE(hdr->head.pcf) & PV_CFLAG_NO_DECRYPTION); -+} -+ -+uint64_t pv_hdr_enc_size(const PvHdr *hdr) -+{ -+ return GUINT64_FROM_BE(hdr->head.sea); -+} -+ -+uint32_t pv_hdr_enc_size_casted(const PvHdr *hdr) -+{ -+ uint64_t size = pv_hdr_enc_size(hdr); -+ -+ if (size > UINT32_MAX) -+ g_abort(); -+ -+ return (uint32_t)size; -+} -+ -+static guint pv_hdr_tag_size(const PvHdr *hdr) -+{ -+ return sizeof(hdr->tag); -+} -+ -+uint32_t pv_hdr_aad_size(const PvHdr *hdr) -+{ -+ return pv_hdr_size(hdr) - pv_hdr_enc_size_casted(hdr) - -+ pv_hdr_tag_size(hdr); -+} -+ -+uint64_t pv_hdr_get_nks(const PvHdr *hdr) -+{ -+ return GUINT64_FROM_BE(hdr->head.nks); -+} -+ -+/* In-place modification of ``buf`` */ -+static gint pv_hdr_encrypt(const PvHdr *hdr, const PvImage *img, Buffer *buf, -+ GError **err) -+{ -+ uint32_t hdr_len = pv_hdr_size(hdr); -+ uint32_t aad_len = pv_hdr_aad_size(hdr); -+ guint tag_len = pv_hdr_tag_size(hdr); -+ uint32_t enc_len = pv_hdr_enc_size_casted(hdr); -+ const Buffer aad_part = { .data = buf->data, .size = aad_len }; -+ Buffer enc_part = { .data = (uint8_t *)buf->data + aad_len, -+ .size = enc_len }; -+ Buffer tag_part = { .data = (uint8_t *)buf->data + hdr_len - tag_len, -+ .size = tag_len }; -+ struct cipher_parms parms; -+ int64_t c_len; -+ -+ g_assert(aad_part.size + enc_part.size + tag_part.size == buf->size); -+ g_assert(img->cust_root_key->size <= INT_MAX); -+ g_assert(img->gcm_iv->size <= INT_MAX); -+ g_assert(EVP_CIPHER_key_length(img->gcm_cipher) == -+ (int)img->cust_root_key->size); -+ g_assert(EVP_CIPHER_iv_length(img->gcm_cipher) == (int)img->gcm_iv->size); -+ -+ parms.key = img->cust_root_key; -+ parms.iv_or_tweak = img->gcm_iv; -+ parms.cipher = img->gcm_cipher; -+ -+ /* in-place encryption */ -+ c_len = gcm_encrypt(&enc_part, &aad_part, &parms, &enc_part, &tag_part, err); -+ if (c_len < 0) -+ return -1; -+ -+ g_assert(c_len == enc_len); -+ return 0; -+} -+ -+/* Initializes the unencrypted, but integrity protected part of the PV -+ * header -+ */ -+static gint pv_hdr_aad_init(PvHdr *hdr, const PvImage *img, GError **err) -+{ -+ g_autofree union ecdh_pub_key *cust_pub_key = NULL; -+ struct pv_hdr_key_slot *hdr_slot = hdr->slots; -+ struct pv_hdr_head *head = &hdr->head; -+ g_autoptr(Buffer) pld = NULL; -+ g_autoptr(Buffer) ald = NULL; -+ g_autoptr(Buffer) tld = NULL; -+ uint64_t nep = 0; -+ -+ g_assert(sizeof(head->iv) == img->gcm_iv->size); -+ g_assert(sizeof(head->cust_pub_key) == sizeof(*cust_pub_key)); -+ -+ cust_pub_key = evp_pkey_to_ecdh_pub_key(img->cust_pub_priv_key, err); -+ if (!cust_pub_key) -+ return -1; -+ -+ head->magic = GUINT64_TO_BE(PV_MAGIC_NUMBER); -+ head->version = GUINT32_TO_BE(PV_VERSION_1); -+ /* ``phs`` is already set so we can skip it here */ -+ memcpy(head->iv, img->gcm_iv->data, sizeof(head->iv)); -+ /* ``nks`` is already set so we can skip it here */ -+ /* ``sea`` is already set so we can skip it here */ -+ head->pcf = GUINT64_TO_BE(img->pcf); -+ memcpy(head->cust_pub_key.data, cust_pub_key, -+ sizeof(head->cust_pub_key)); -+ -+ if (pv_img_calc_pld_ald_tld_nep(img, &pld, &ald, &tld, &nep, err) < 0) -+ return -1; -+ -+ g_assert(sizeof(head->pld) == pld->size); -+ g_assert(sizeof(head->ald) == ald->size); -+ g_assert(sizeof(head->tld) == tld->size); -+ -+ head->nep = GUINT64_TO_BE(nep); -+ memcpy(head->pld, pld->data, sizeof(head->pld)); -+ memcpy(head->ald, ald->data, sizeof(head->ald)); -+ memcpy(head->tld, tld->data, sizeof(head->tld)); -+ -+ /* set the key slots */ -+ for (GSList *iterator = img->key_slots; iterator; iterator = iterator->next) { -+ const PvHdrKeySlot *slot = iterator->data; -+ -+ g_assert(slot); -+ -+ /* the memory for the slots is pre-allocated so we -+ * have not to allocate and since PvHdrKeySlot is -+ * stored in the big-edian format we can simply use -+ * memcpy. -+ */ -+ memcpy(hdr_slot++, slot, sizeof(*slot)); -+ } -+ -+ return 0; -+} -+ -+/* Initializes the encrypted and also integrity protected part of the -+ * PV header -+ */ -+static gint pv_hdr_enc_init(PvHdr *hdr, const PvImage *img, GError **err) -+{ -+ struct pv_hdr_encrypted *enc = hdr->encrypted; -+ const PvComponent *stage3b; -+ struct psw_t psw; -+ -+ g_assert(sizeof(enc->img_enc_key_1) + sizeof(enc->img_enc_key_2) == -+ EVP_CIPHER_key_length(img->xts_cipher)); -+ g_assert(sizeof(enc->cust_comm_key) == img->cust_comm_key->size); -+ g_assert(img->xts_key->size == -+ (guint)EVP_CIPHER_key_length(img->xts_cipher)); -+ -+ stage3b = pv_img_get_stage3b_comp(img, err); -+ if (!stage3b) -+ return -1; -+ -+ memcpy(enc->cust_comm_key, img->cust_comm_key->data, -+ sizeof(enc->cust_comm_key)); -+ memcpy(enc->img_enc_key_1, img->xts_key->data, -+ sizeof(enc->img_enc_key_1)); -+ memcpy(enc->img_enc_key_2, -+ (uint8_t *)img->xts_key->data + sizeof(enc->img_enc_key_1), -+ sizeof(enc->img_enc_key_2)); -+ -+ /* Setup program check handler */ -+ psw.mask = GUINT64_TO_BE(DEFAULT_INITIAL_PSW_MASK); -+ psw.addr = GUINT64_TO_BE(pv_component_get_src_addr(stage3b)); -+ enc->psw = psw; -+ enc->scf = GUINT64_TO_BE(img->scf); -+ enc->noi = GUINT32_TO_BE(g_slist_length(img->optional_items)); -+ -+ /* set the optional items */ -+ for (GSList *iterator = img->optional_items; iterator; -+ iterator = iterator->next) { -+ const struct pv_hdr_opt_item *item = iterator->data; -+ -+ g_assert(item); -+ -+ /* not supported in the first version */ -+ g_assert_not_reached(); -+ } -+ -+ return 0; -+} -+ -+PvHdr *pv_hdr_new(const PvImage *img, GError **err) -+{ -+ uint32_t noi = g_slist_length(img->optional_items); -+ uint32_t hdr_size = pv_img_get_pv_hdr_size(img); -+ gsize nks = g_slist_length(img->key_slots); -+ uint32_t sea = pv_img_get_enc_size(img); -+ g_autoptr(PvHdr) ret = NULL; -+ -+ g_assert(nks > 0); -+ /* must be a multiple of AES block size */ -+ g_assert(sea % AES_BLOCK_SIZE == 0); -+ g_assert(sea >= sizeof(struct pv_hdr_encrypted)); -+ -+ ret = g_new0(PvHdr, 1); -+ ret->slots = g_new0(struct pv_hdr_key_slot, nks); -+ ret->head.phs = GUINT32_TO_BE(hdr_size); -+ ret->head.nks = GUINT64_TO_BE(nks); -+ ret->head.sea = GUINT64_TO_BE(sea); -+ -+ ret->encrypted = g_new0(struct pv_hdr_encrypted, 1); -+ ret->optional_items = g_malloc0(sea - sizeof(struct pv_hdr_encrypted)); -+ ret->encrypted->noi = GUINT32_TO_BE(noi); -+ -+ if (pv_hdr_aad_init(ret, img, err) < 0) -+ return NULL; -+ -+ if (pv_hdr_enc_init(ret, img, err) < 0) -+ return NULL; -+ -+ return g_steal_pointer(&ret); -+} -+ -+static void pv_hdr_memcpy(const PvHdr *hdr, const Buffer *dst) -+{ -+ uint64_t nks = pv_hdr_get_nks(hdr); -+ uint8_t *data; -+ -+ g_assert(dst->size == pv_hdr_size(hdr)); -+ g_assert(pv_hdr_enc_size_casted(hdr) >= sizeof(*hdr->encrypted)); -+ -+ data = memcpy(dst->data, &hdr->head, sizeof(hdr->head)); -+ data = memcpy(data + sizeof(hdr->head), hdr->slots, -+ sizeof(struct pv_hdr_key_slot) * nks); -+ data = memcpy(data + sizeof(struct pv_hdr_key_slot) * nks, -+ hdr->encrypted, sizeof(*hdr->encrypted)); -+ if (pv_hdr_enc_size_casted(hdr) - sizeof(*hdr->encrypted) > 0) { -+ (void)memcpy(data + sizeof(*hdr->encrypted), -+ hdr->optional_items, -+ pv_hdr_enc_size_casted(hdr) - sizeof(*hdr->encrypted)); -+ } -+} -+ -+Buffer *pv_hdr_serialize(const PvHdr *hdr, const PvImage *img, -+ enum PvCryptoMode mode, GError **err) -+{ -+ uint32_t hdr_size = pv_hdr_size(hdr); -+ g_autoptr(Buffer) ret = NULL; -+ -+ ret = buffer_alloc(hdr_size); -+ pv_hdr_memcpy(hdr, ret); -+ -+ if (mode == PV_ENCRYPT) { -+ /* The buffer @ret is modified in-place */ -+ if (pv_hdr_encrypt(hdr, img, ret, err) < 0) -+ return NULL; -+ } else { -+ /* Simply copy the tag */ -+ memcpy((uint8_t *)ret->data + hdr_size - pv_hdr_tag_size(hdr), -+ hdr->tag, pv_hdr_tag_size(hdr)); -+ } -+ -+ return g_steal_pointer(&ret); -+} ---- /dev/null -+++ b/genprotimg/src/pv/pv_hdr.h -@@ -0,0 +1,36 @@ -+/* -+ * PV header related functions -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * s390-tools is free software; you can redistribute it and/or modify -+ * it under the terms of the MIT license. See LICENSE for details. -+ */ -+ -+#ifndef PV_HDR_H -+#define PV_HDR_H -+ -+#include -+#include -+ -+#include "boot/s390.h" -+#include "include/pv_hdr_def.h" -+#include "utils/crypto.h" -+#include "utils/buffer.h" -+ -+#include "pv_image.h" -+ -+PvHdr *pv_hdr_new(const PvImage *img, GError **err); -+void pv_hdr_free(PvHdr *hdr); -+G_GNUC_UNUSED gboolean pv_hdr_uses_encryption(const PvHdr *hdr); -+Buffer *pv_hdr_serialize(const PvHdr *hdr, const PvImage *img, -+ enum PvCryptoMode mode, GError **err); -+uint32_t pv_hdr_size(const PvHdr *hdr); -+uint32_t pv_hdr_aad_size(const PvHdr *hdr); -+uint64_t pv_hdr_enc_size(const PvHdr *hdr); -+uint32_t pv_hdr_enc_size_casted(const PvHdr *hdr); -+uint64_t pv_hdr_get_nks(const PvHdr *hdr); -+ -+WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(PvHdr, pv_hdr_free) -+ -+#endif ---- /dev/null -+++ b/genprotimg/src/pv/pv_image.c -@@ -0,0 +1,820 @@ -+/* -+ * PV image related definitions and functions -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * 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 -+#include -+#include -+ -+#include "boot/stage3a.h" -+#include "common.h" -+#include "include/pv_crypto_def.h" -+#include "include/pv_hdr_def.h" -+#include "utils/align.h" -+#include "utils/crypto.h" -+#include "utils/file_utils.h" -+ -+#include "pv_args.h" -+#include "pv_comps.h" -+#include "pv_error.h" -+#include "pv_hdr.h" -+#include "pv_image.h" -+#include "pv_ipib.h" -+#include "pv_opt_item.h" -+#include "pv_stage3.h" -+ -+const PvComponent *pv_img_get_stage3b_comp(const PvImage *img, GError **err) -+{ -+ const PvComponent *comp; -+ -+ g_return_val_if_fail(pv_img_comps_length(img->comps) >= 1, NULL); -+ -+ comp = pv_img_comps_get_nth_comp(img->comps, -+ pv_img_comps_length(img->comps) - 1); -+ if (!pv_component_is_stage3b(comp)) { -+ g_set_error(err, PV_ERROR, PV_ERROR_INTERNAL, -+ _("Failed to get 'stage3b' component")); -+ return NULL; -+ } -+ return comp; -+} -+ -+typedef gint (*prepare_func)(PvComponent *obj, const gchar *tmp_path, -+ void *opaque, GError **err); -+ -+static gint pv_img_prepare_component(const PvImage *img, PvComponent *comp, -+ GError **err) -+{ -+ struct cipher_parms parms = { 0 }; -+ g_autoptr(Buffer) tweak = NULL; -+ prepare_func func = NULL; -+ void *opaque = NULL; -+ gint rc; -+ -+ if (img->pcf & PV_CFLAG_NO_DECRYPTION) { -+ /* we only need to align the components */ -+ func = pv_component_align; -+ opaque = NULL; -+ } else { -+ const EVP_CIPHER *cipher = img->xts_cipher; -+ -+ g_assert_cmpint((int)img->xts_key->size, ==, -+ EVP_CIPHER_key_length(cipher)); -+ g_assert_cmpint((int)PAGE_SIZE % EVP_CIPHER_block_size(cipher), -+ ==, 0); -+ g_assert_cmpint(sizeof(comp->tweak), ==, -+ EVP_CIPHER_iv_length(cipher)); -+ g_assert(img->xts_key->size <= UINT_MAX); -+ -+ tweak = buffer_alloc(sizeof(comp->tweak.data)); -+ memcpy(tweak->data, comp->tweak.data, tweak->size); -+ func = pv_component_align_and_encrypt; -+ parms.cipher = cipher; -+ parms.key = img->xts_key; -+ parms.iv_or_tweak = tweak; -+ -+ opaque = &parms; -+ } -+ -+ rc = (*func)(comp, img->tmp_dir, opaque, err); -+ if (rc < 0) -+ return -1; -+ -+ return 0; -+} -+ -+static Buffer *pv_img_read_key(const gchar *path, guint key_size, -+ GError **err) -+{ -+ g_autoptr(Buffer) tmp_ret = NULL; -+ Buffer *ret = NULL; -+ gsize bytes_read; -+ FILE *f = NULL; -+ gsize size; -+ -+ if (file_size(path, &size, err) != 0) -+ return NULL; -+ -+ if (size - key_size != 0) { -+ g_set_error(err, PV_ERROR, PV_CRYPTO_ERROR_INVALID_KEY_SIZE, -+ _("Wrong file size '%s': read %zd, expected %u"), path, size, -+ key_size); -+ return NULL; -+ } -+ -+ f = file_open(path, "rb", err); -+ if (!f) -+ return NULL; -+ -+ tmp_ret = buffer_alloc(size); -+ if (file_read(f, tmp_ret->data, 1, tmp_ret->size, &bytes_read, err) < 0) -+ goto err; -+ -+ if (bytes_read - key_size != 0) { -+ g_set_error(err, PV_ERROR, PV_CRYPTO_ERROR_INVALID_KEY_SIZE, -+ _("Wrong file size '%s': read %zd, expected %u"), -+ path, bytes_read, key_size); -+ goto err; -+ } -+ -+ ret = g_steal_pointer(&tmp_ret); -+err: -+ if (f) -+ fclose(f); -+ return ret; -+} -+ -+static EVP_PKEY *pv_img_get_cust_pub_priv_key(gint nid, GError **err) -+{ -+ return generate_ec_key(nid, err); -+} -+ -+static HostKeyList *pv_img_get_host_keys(gchar **host_cert_paths, -+ X509_STORE *store, gint nid, -+ GError **err) -+{ -+ g_autoslist(EVP_PKEY) ret = NULL; -+ -+ g_assert(host_cert_paths); -+ -+ for (gchar **iterator = host_cert_paths; iterator != NULL && *iterator != NULL; -+ iterator++) { -+ g_autoptr(EVP_PKEY) host_key = NULL; -+ const gchar *path = *iterator; -+ -+ g_assert(path); -+ -+ host_key = read_ec_pubkey_cert(store, nid, path, err); -+ if (!host_key) -+ return NULL; -+ -+ ret = g_slist_append(ret, g_steal_pointer(&host_key)); -+ } -+ -+ return g_steal_pointer(&ret); -+} -+ -+static Buffer *pv_img_get_key(const EVP_CIPHER *cipher, const gchar *path, -+ GError **err) -+{ -+ gint key_len = EVP_CIPHER_key_length(cipher); -+ -+ g_assert(key_len > 0); -+ -+ if (path) -+ return pv_img_read_key(path, (guint)key_len, err); -+ -+ return generate_aes_key((guint)key_len, err); -+} -+ -+static Buffer *pv_img_get_iv(const EVP_CIPHER *cipher, const gchar *path, -+ GError **err) -+{ -+ gint iv_len = EVP_CIPHER_iv_length(cipher); -+ -+ g_assert(iv_len > 0); -+ -+ if (path) -+ return pv_img_read_key(path, (guint)iv_len, err); -+ -+ return generate_aes_iv((guint)iv_len, err); -+} -+ -+static int hex_str_toull(const gchar *nptr, uint64_t *dst, -+ GError **err) -+{ -+ uint64_t value; -+ gchar *end; -+ -+ g_assert(dst); -+ -+ if (!g_str_is_ascii(nptr)) { -+ g_set_error(err, PV_ERROR, EINVAL, -+ _("Invalid value: '%s'. A hexadecimal value is required, for example '0xcfe'"), -+ nptr); -+ return -1; -+ } -+ -+ value = g_ascii_strtoull(nptr, &end, 16); -+ if ((value == G_MAXUINT64 && errno == ERANGE) || -+ (end && *end != '\0')) { -+ g_set_error(err, PV_ERROR, EINVAL, -+ _("Invalid value: '%s'. A hexadecimal value is required, for example '0xcfe'"), -+ nptr); -+ return -1; -+ } -+ *dst = value; -+ return 0; -+} -+ -+static gint pv_img_set_psw_addr(PvImage *img, const gchar *psw_addr_s, -+ GError **err) -+{ -+ if (psw_addr_s) { -+ uint64_t psw_addr; -+ -+ if (hex_str_toull(psw_addr_s, &psw_addr, err) < 0) -+ return -1; -+ -+ img->initial_psw.addr = psw_addr; -+ } -+ -+ return 0; -+} -+ -+static gint pv_img_set_control_flags(PvImage *img, const gchar *pcf_s, -+ const gchar *scf_s, GError **err) -+{ -+ uint64_t flags; -+ -+ if (pcf_s) { -+ if (hex_str_toull(pcf_s, &flags, err) < 0) -+ return -1; -+ -+ img->pcf = flags; -+ } -+ -+ if (scf_s) { -+ if (hex_str_toull(scf_s, &flags, err) < 0) -+ return -1; -+ -+ img->scf = flags; -+ } -+ -+ return 0; -+} -+ -+/* read in the keys or auto-generate them */ -+static gint pv_img_set_keys(PvImage *img, const PvArgs *args, GError **err) -+{ -+ g_autoptr(X509_STORE) store = NULL; -+ -+ g_assert(img->xts_cipher); -+ g_assert(img->cust_comm_cipher); -+ g_assert(img->gcm_cipher); -+ g_assert(img->nid); -+ -+ img->xts_key = pv_img_get_key(img->xts_cipher, args->xts_key_path, err); -+ if (!img->xts_key) -+ return -1; -+ -+ img->cust_comm_key = pv_img_get_key(img->cust_comm_cipher, -+ args->cust_comm_key_path, err); -+ if (!img->cust_comm_key) -+ return -1; -+ -+ img->cust_root_key = -+ pv_img_get_key(img->gcm_cipher, args->cust_root_key_path, err); -+ if (!img->cust_root_key) -+ return -1; -+ -+ img->gcm_iv = pv_img_get_iv(img->gcm_cipher, args->gcm_iv_path, err); -+ if (!img->gcm_iv) -+ return -1; -+ -+ img->cust_pub_priv_key = pv_img_get_cust_pub_priv_key(img->nid, err); -+ if (!img->cust_pub_priv_key) -+ return -1; -+ -+ img->host_pub_keys = -+ pv_img_get_host_keys(args->host_keys, store, img->nid, err); -+ if (!img->host_pub_keys) -+ return -1; -+ -+ return 0; -+} -+ -+static void pv_img_add_host_slot(PvImage *img, PvHdrKeySlot *slot) -+{ -+ img->key_slots = g_slist_append(img->key_slots, slot); -+} -+ -+static void pv_hdr_key_slot_free(PvHdrKeySlot *slot) -+{ -+ if (!slot) -+ return; -+ -+ g_free(slot); -+} -+ -+WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(PvHdrKeySlot, pv_hdr_key_slot_free) -+ -+static PvHdrKeySlot *pv_hdr_key_slot_new(const EVP_CIPHER *gcm_cipher, -+ const Buffer *cust_root_key, -+ EVP_PKEY *cust_key, EVP_PKEY *host_key, -+ GError **err) -+{ -+ g_autoptr(PvHdrKeySlot) ret = g_new0(PvHdrKeySlot, 1); -+ g_autofree union ecdh_pub_key *pub = NULL; -+ g_autoptr(Buffer) exchange_key = NULL; -+ g_autoptr(Buffer) digest_key = NULL; -+ g_autoptr(Buffer) iv = NULL; -+ Buffer pub_buf; -+ /* No AAD data is used */ -+ Buffer aad = { .data = NULL, .size = 0 }; -+ /* Set the output buffers for the encrypted data and the -+ * generated GCM tag -+ */ -+ Buffer enc = { .data = ret->wrapped_key, .size = sizeof(ret->wrapped_key) }; -+ Buffer tag = { .data = ret->tag, .size = sizeof(ret->tag) }; -+ struct cipher_parms parms; -+ int64_t c_len = 0; -+ -+ g_assert(EVP_CIPHER_iv_length(gcm_cipher) >= 0); -+ -+ pub = evp_pkey_to_ecdh_pub_key(host_key, err); -+ if (!pub) -+ return NULL; -+ -+ pub_buf.data = pub->data; -+ pub_buf.size = sizeof(*pub); -+ digest_key = sha256_buffer(&pub_buf, err); -+ if (!digest_key) -+ return NULL; -+ -+ g_assert(digest_key->size == sizeof(ret->digest_key)); -+ /* set `digest_key` field */ -+ memcpy(ret->digest_key, digest_key->data, sizeof(ret->digest_key)); -+ -+ exchange_key = compute_exchange_key(cust_key, host_key, err); -+ if (!exchange_key) -+ return NULL; -+ -+ /* initialize cipher parameters */ -+ g_assert(exchange_key->size <= INT_MAX); -+ g_assert(exchange_key->size == (guint)EVP_CIPHER_key_length(gcm_cipher)); -+ -+ /* create zero IV */ -+ iv = buffer_alloc((guint)EVP_CIPHER_iv_length(gcm_cipher)); -+ parms.iv_or_tweak = iv; -+ parms.key = exchange_key; -+ parms.cipher = gcm_cipher; -+ -+ /* Encrypt the customer root key that is used for the encryption -+ * of the PV header -+ */ -+ c_len = gcm_encrypt(cust_root_key, &aad, &parms, &enc, &tag, err); -+ if (c_len < 0) -+ return NULL; -+ -+ g_assert(c_len == (int64_t)cust_root_key->size); -+ return g_steal_pointer(&ret); -+} -+ -+static gint pv_img_set_host_slots(PvImage *img, GError **err) -+{ -+ for (GSList *iterator = img->host_pub_keys; iterator; iterator = iterator->next) { -+ EVP_PKEY *host_key = iterator->data; -+ -+ g_assert(host_key); -+ -+ PvHdrKeySlot *slot = pv_hdr_key_slot_new(img->gcm_cipher, -+ img->cust_root_key, -+ img->cust_pub_priv_key, -+ host_key, err); -+ if (!slot) -+ return -1; -+ -+ pv_img_add_host_slot(img, slot); -+ } -+ -+ return 0; -+} -+ -+static gint pv_img_set_comps_offset(PvImage *img, uint64_t offset, GError **err) -+{ -+ return pv_img_comps_set_offset(img->comps, offset, err); -+} -+ -+PvImage *pv_img_new(PvArgs *args, const gchar *stage3a_path, GError **err) -+{ -+ g_autoptr(PvImage) ret = g_new0(PvImage, 1); -+ uint64_t offset; -+ -+ g_assert(args->tmp_dir); -+ g_assert(stage3a_path); -+ -+ if (args->no_verify) -+ g_warning(_("host-key document verification is disabled. Your workload is not secured.")); -+ -+ ret->comps = pv_img_comps_new(EVP_sha512(), EVP_sha512(), EVP_sha512(), err); -+ if (!ret->comps) -+ return NULL; -+ -+ ret->cust_comm_cipher = EVP_aes_256_gcm(); -+ ret->gcm_cipher = EVP_aes_256_gcm(); -+ ret->initial_psw.addr = DEFAULT_INITIAL_PSW_ADDR; -+ ret->initial_psw.mask = DEFAULT_INITIAL_PSW_MASK; -+ ret->nid = NID_secp521r1; -+ ret->tmp_dir = g_strdup(args->tmp_dir); -+ ret->xts_cipher = EVP_aes_256_xts(); -+ -+ /* set initial PSW that will be loaded by the stage3b */ -+ if (pv_img_set_psw_addr(ret, args->psw_addr, err) < 0) -+ return NULL; -+ -+ /* set the control flags: PCF and SCF */ -+ if (pv_img_set_control_flags(ret, args->pcf, args->scf, err) < 0) -+ return NULL; -+ -+ /* read in the keys */ -+ if (pv_img_set_keys(ret, args, err) < 0) -+ return NULL; -+ -+ if (pv_img_set_host_slots(ret, err) < 0) -+ return NULL; -+ -+ /* allocate enough memory for the stage3a args and load the -+ * stage3a template into memory and set the loader_psw -+ */ -+ if (pv_img_load_and_set_stage3a(ret, stage3a_path, err) < 0) -+ return NULL; -+ -+ offset = PAGE_ALIGN(STAGE3A_LOAD_ADDRESS + ret->stage3a->size); -+ -+ /* shift right all components by the size of stage3a loader */ -+ if (pv_img_set_comps_offset(ret, offset, err) < 0) -+ return NULL; -+ -+ return g_steal_pointer(&ret); -+} -+ -+void pv_img_free(PvImage *img) -+{ -+ if (!img) -+ return; -+ -+ g_slist_free_full(img->optional_items, -+ (GDestroyNotify)pv_opt_item_free); -+ g_slist_free_full(img->key_slots, (GDestroyNotify)pv_hdr_key_slot_free); -+ g_slist_free_full(img->host_pub_keys, (GDestroyNotify)EVP_PKEY_free); -+ EVP_PKEY_free(img->cust_pub_priv_key); -+ buffer_clear(&img->stage3a); -+ pv_img_comps_free(img->comps); -+ g_free(img->tmp_dir); -+ buffer_free(img->xts_key); -+ buffer_free(img->cust_root_key); -+ buffer_free(img->gcm_iv); -+ buffer_free(img->cust_comm_key); -+ g_free(img); -+} -+ -+static gint pv_img_prepare_and_add_component(PvImage *img, PvComponent **comp, -+ GError **err) -+{ -+ g_assert(comp); -+ g_assert(*comp); -+ -+ /* prepares the component: does the alignment and encryption -+ * if required -+ */ -+ if (pv_img_prepare_component(img, *comp, err) < 0) -+ return -1; -+ -+ /* calculates the memory layout and adds the component to its -+ * internal list -+ */ -+ if (pv_img_comps_add_component(img->comps, comp, err) < 0) -+ return -1; -+ -+ g_assert(!*comp); -+ return 0; -+} -+ -+gint pv_img_add_component(PvImage *img, const PvArg *arg, GError **err) -+{ -+ g_autoptr(PvComponent) comp = NULL; -+ -+ comp = pv_component_new_file(arg->type, arg->path, err); -+ if (!comp) -+ return -1; -+ -+ if (pv_img_prepare_and_add_component(img, &comp, err) < 0) -+ return -1; -+ -+ g_assert(!comp); -+ return 0; -+} -+ -+gint pv_img_calc_pld_ald_tld_nep(const PvImage *img, Buffer **pld, Buffer **ald, -+ Buffer **tld, uint64_t *nep, GError **err) -+{ -+ return pv_img_comps_finalize(img->comps, pld, ald, tld, nep, err); -+} -+ -+static gint pv_img_build_stage3b(PvImage *img, Buffer *stage3b, GError **err) -+{ -+ g_autofree struct stage3b_args *args = NULL; -+ -+ args = pv_img_comps_get_stage3b_args(img->comps, &img->initial_psw); -+ if (!args) { -+ g_set_error(err, PV_ERROR, PV_ERROR_INTERNAL, -+ _("Cannot generate stage3b arguments")); -+ return -1; -+ } -+ -+ build_stage3b(stage3b, args); -+ return 0; -+} -+ -+gint pv_img_add_stage3b_comp(PvImage *img, const gchar *path, GError **err) -+{ -+ g_autoptr(PvComponent) comp = NULL; -+ g_autoptr(Buffer) stage3b = NULL; -+ -+ stage3b = stage3b_getblob(path, err); -+ if (!stage3b) -+ return -1; -+ -+ /* set the stage3b data */ -+ if (pv_img_build_stage3b(img, stage3b, err) < 0) -+ return -1; -+ -+ comp = pv_component_new_buf(PV_COMP_TYPE_STAGE3B, stage3b, err); -+ if (!comp) -+ return -1; -+ -+ if (pv_img_prepare_and_add_component(img, &comp, err) < 0) -+ return -1; -+ -+ g_assert(!comp); -+ return 0; -+} -+ -+static uint32_t pv_img_get_aad_size(const PvImage *img) -+{ -+ uint32_t key_size, size = 0; -+ -+ g_assert(sizeof(struct pv_hdr_head) <= UINT32_MAX); -+ g_assert(sizeof(struct pv_hdr_key_slot) <= UINT32_MAX); -+ -+ g_assert_true(g_uint_checked_add(&size, size, -+ (uint32_t)sizeof(struct pv_hdr_head))); -+ g_assert_true(g_uint_checked_mul(&key_size, -+ (uint32_t)sizeof(struct pv_hdr_key_slot), -+ g_slist_length(img->key_slots))); -+ g_assert_true(g_uint_checked_add(&size, size, key_size)); -+ return size; -+} -+ -+static uint32_t pv_img_get_opt_items_size(const PvImage *img) -+{ -+ uint32_t ret = 0; -+ -+ g_assert(img); -+ -+ for (GSList *iterator = img->optional_items; iterator; -+ iterator = iterator->next) { -+ const struct pv_hdr_opt_item *item = iterator->data; -+ -+ g_assert(item); -+ g_assert_true(g_uint_checked_add(&ret, ret, pv_opt_item_size(item))); -+ } -+ return ret; -+} -+ -+uint32_t pv_img_get_enc_size(const PvImage *img) -+{ -+ uint32_t ret = 0; -+ -+ g_assert(sizeof(struct pv_hdr_encrypted) <= UINT32_MAX); -+ -+ g_assert_true(g_uint_checked_add( -+ &ret, ret, (uint32_t)sizeof(struct pv_hdr_encrypted))); -+ g_assert_true( -+ g_uint_checked_add(&ret, ret, pv_img_get_opt_items_size(img))); -+ return ret; -+} -+ -+static uint32_t pv_img_get_tag_size(const PvImage *img G_GNUC_UNUSED) -+{ -+ g_assert(sizeof(((struct pv_hdr *)0)->tag) <= UINT32_MAX); -+ -+ return (uint32_t)sizeof(((struct pv_hdr *)0)->tag); -+} -+ -+uint32_t pv_img_get_pv_hdr_size(const PvImage *img) -+{ -+ uint32_t size = 0; -+ -+ g_assert_true( -+ g_uint_checked_add(&size, size, pv_img_get_aad_size(img))); -+ g_assert_true( -+ g_uint_checked_add(&size, size, pv_img_get_enc_size(img))); -+ g_assert_true( -+ g_uint_checked_add(&size, size, pv_img_get_tag_size(img))); -+ return size; -+} -+ -+static gint get_stage3a_data_size(const PvImage *img, gsize *data_size, -+ GError **err) -+{ -+ gsize ipib_size, hdr_size; -+ -+ g_assert(data_size); -+ g_assert(*data_size == 0); -+ -+ ipib_size = pv_ipib_get_size(pv_img_comps_length(img->comps)); -+ if (ipib_size > PV_V1_IPIB_MAX_SIZE) { -+ g_set_error(err, PV_ERROR, PV_ERROR_IPIB_SIZE, -+ _("IPIB size is too large: '%zu' > '%zu'"), -+ ipib_size, PV_V1_IPIB_MAX_SIZE); -+ return -1; -+ } -+ -+ hdr_size = pv_img_get_pv_hdr_size(img); -+ if (hdr_size > PV_V1_PV_HDR_MAX_SIZE) { -+ g_set_error(err, PV_ERROR, PV_ERROR_PV_HDR_SIZE, -+ _("PV header size is too large: '%zu' > '%zu'"), -+ hdr_size, PV_V1_PV_HDR_MAX_SIZE); -+ return -1; -+ } -+ -+ *data_size += PAGE_ALIGN(ipib_size); -+ *data_size += PAGE_ALIGN(hdr_size); -+ return 0; -+} -+ -+gint pv_img_load_and_set_stage3a(PvImage *img, const gchar *path, GError **err) -+{ -+ g_autoptr(Buffer) stage3a = NULL; -+ gsize bin_size, data_size = 0; -+ -+ if (get_stage3a_data_size(img, &data_size, err) < 0) -+ return -1; -+ -+ stage3a = stage3a_getblob(path, &bin_size, data_size, err); -+ if (!stage3a) -+ return -1; -+ -+ img->stage3a_psw.addr = STAGE3A_ENTRY; -+ img->stage3a_psw.mask = DEFAULT_INITIAL_PSW_MASK; -+ -+ /* set addresses and size */ -+ img->stage3a = g_steal_pointer(&stage3a); -+ img->stage3a_bin_size = bin_size; -+ return 0; -+} -+ -+/* Creates the PV IPIB and sets the stage3a arguments */ -+static gint pv_img_build_stage3a(Buffer *stage3a, gsize stage3a_bin_size, -+ GSList *comps, const Buffer *hdr, GError **err) -+{ -+ g_autofree struct ipl_parameter_block *ipib = NULL; -+ -+ g_assert(stage3a); -+ g_assert(hdr); -+ -+ ipib = pv_ipib_new(comps, hdr, err); -+ if (!ipib) -+ return -1; -+ -+ if (build_stage3a(stage3a, stage3a_bin_size, hdr, ipib, err) < 0) -+ return -1; -+ -+ g_info("%12s:\t0x%012lx (%12ld / %12ld Bytes)", "stage3a", -+ STAGE3A_LOAD_ADDRESS, stage3a->size, stage3a->size); -+ return 0; -+} -+ -+/* Creates the actual PV header (serialized and AES-GCM encrypted) */ -+static Buffer *pv_img_create_pv_hdr(PvImage *img, GError **err) -+{ -+ g_autoptr(Buffer) hdr_buf = NULL; -+ g_autoptr(PvHdr) hdr = NULL; -+ -+ hdr = pv_hdr_new(img, err); -+ if (!hdr) -+ return NULL; -+ -+ hdr_buf = pv_hdr_serialize(hdr, img, PV_ENCRYPT, err); -+ if (!hdr_buf) -+ return NULL; -+ -+ return g_steal_pointer(&hdr_buf); -+} -+ -+/* No changes to the components are allowed after calling this -+ * function -+ */ -+gint pv_img_finalize(PvImage *pv, const gchar *stage3b_path, GError **err) -+{ -+ g_autoptr(Buffer) hdr = NULL; -+ -+ /* load stage3b template into memory and add it to the list of -+ * components. This must be done before calling -+ * `pv_img_load_and_set_stage3a`. -+ */ -+ if (pv_img_add_stage3b_comp(pv, stage3b_path, err) < 0) -+ return -1; -+ -+ /* create the PV header */ -+ hdr = pv_img_create_pv_hdr(pv, err); -+ if (!hdr) -+ return -1; -+ -+ /* generate stage3a. At this point in time the PV header and -+ * the stage3b must be generated and encrypted -+ */ -+ if (pv_img_build_stage3a(pv->stage3a, pv->stage3a_bin_size, -+ pv_img_comps_get_comps(pv->comps), hdr, err) < 0) -+ return -1; -+ -+ return 0; -+} -+ -+static gint convert_psw_to_short_psw(const struct psw_t *psw, uint64_t *dst, -+ GError **err) -+{ -+ g_assert(psw); -+ g_assert(dst); -+ -+ uint64_t psw_addr = psw->addr; -+ uint64_t psw_mask = psw->mask; -+ -+ /* test if PSW mask can be converted */ -+ if (psw_mask & PSW_SHORT_ADDR_MASK) { -+ g_set_error(err, PV_ERROR, PV_ERROR_INTERNAL, -+ _("Failed to convert PSW to short PSW")); -+ return -1; -+ } -+ -+ /* test for bit 12 */ -+ if (psw_mask & PSW_MASK_BIT_12) { -+ g_set_error(err, PV_ERROR, PV_ERROR_INTERNAL, -+ _("Failed to convert PSW to short PSW")); -+ return -1; -+ } -+ -+ /* test if PSW addr can be converted */ -+ if (psw_addr & ~PSW_SHORT_ADDR_MASK) { -+ g_set_error(err, PV_ERROR, PV_ERROR_INTERNAL, -+ _("Failed to convert PSW to short PSW")); -+ return -1; -+ } -+ -+ *dst = psw_mask; -+ /* set bit 12 to 1 */ -+ *dst |= PSW_MASK_BIT_12; -+ *dst |= psw_addr; -+ return 0; -+} -+ -+static gint write_short_psw(FILE *f, struct psw_t *psw, GError **err) -+{ -+ uint64_t short_psw, short_psw_be; -+ -+ if (convert_psw_to_short_psw(psw, &short_psw, err) < 0) -+ return -1; -+ -+ short_psw_be = GUINT64_TO_BE(short_psw); -+ return file_write(f, &short_psw_be, 1, sizeof(short_psw_be), NULL, err); -+} -+ -+gint pv_img_write(PvImage *img, const gchar *path, GError **err) -+{ -+ gint ret = -1; -+ FILE *f = file_open(path, "wb", err); -+ -+ if (!f) -+ return -1; -+ -+ if (write_short_psw(f, &img->stage3a_psw, err) < 0) { -+ g_prefix_error(err, _("Failed to write image '%s': "), path); -+ goto err; -+ } -+ -+ if (seek_and_write_buffer(f, img->stage3a, STAGE3A_LOAD_ADDRESS, err) < -+ 0) { -+ g_prefix_error(err, _("Failed to write image '%s': "), path); -+ goto err; -+ } -+ -+ /* list is sorted by component type => by address */ -+ for (GSList *iterator = pv_img_comps_get_comps(img->comps); iterator; -+ iterator = iterator->next) { -+ gint rc; -+ const PvComponent *comp = iterator->data; -+ -+ rc = pv_component_write(comp, f, err); -+ if (rc < 0) { -+ g_prefix_error(err, _("Failed to write image '%s': "), -+ path); -+ goto err; -+ } -+ } -+ -+ ret = 0; -+err: -+ if (f) -+ fclose(f); -+ return ret; -+} ---- /dev/null -+++ b/genprotimg/src/pv/pv_image.h -@@ -0,0 +1,68 @@ -+/* -+ * PV image related definitions and functions -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * s390-tools is free software; you can redistribute it and/or modify -+ * it under the terms of the MIT license. See LICENSE for details. -+ */ -+ -+#ifndef PV_IMAGE_H -+#define PV_IMAGE_H -+ -+#include -+#include -+#include -+#include -+ -+#include "boot/s390.h" -+#include "utils/buffer.h" -+ -+#include "pv_args.h" -+#include "pv_comp.h" -+#include "pv_comps.h" -+#include "pv_stage3.h" -+ -+typedef struct { -+ gchar *tmp_dir; /* directory used for temporary files */ -+ Buffer *stage3a; /* stage3a containing IPIB and PV header */ -+ gsize stage3a_bin_size; /* size of stage3a.bin */ -+ struct psw_t stage3a_psw; /* (short) PSW that is written to -+ * location 0 of the created image -+ */ -+ struct psw_t initial_psw; /* PSW loaded by stage3b */ -+ EVP_PKEY *cust_pub_priv_key; /* customer private/public key */ -+ GSList *host_pub_keys; /* public host keys */ -+ gint nid; /* Elliptic Curve used for the key derivation */ -+ /* keys and cipher used for the AES-GCM encryption */ -+ Buffer *cust_root_key; -+ Buffer *gcm_iv; -+ const EVP_CIPHER *gcm_cipher; -+ /* Information for the IPIB and PV header */ -+ uint64_t pcf; -+ uint64_t scf; -+ Buffer *cust_comm_key; -+ const EVP_CIPHER *cust_comm_cipher; -+ Buffer *xts_key; -+ const EVP_CIPHER *xts_cipher; -+ GSList *key_slots; -+ GSList *optional_items; -+ PvImgComps *comps; -+} PvImage; -+ -+PvImage *pv_img_new(PvArgs *args, const gchar *stage3a_path, GError **err); -+void pv_img_free(PvImage *img); -+gint pv_img_add_component(PvImage *img, const PvArg *arg, GError **err); -+gint pv_img_finalize(PvImage *img, const gchar *stage3b_path, GError **err); -+gint pv_img_calc_pld_ald_tld_nep(const PvImage *img, Buffer **pld, Buffer **ald, -+ Buffer **tld, uint64_t *nep, GError **err); -+gint pv_img_load_and_set_stage3a(PvImage *img, const gchar *path, GError **err); -+const PvComponent *pv_img_get_stage3b_comp(const PvImage *img, GError **err); -+gint pv_img_add_stage3b_comp(PvImage *img, const gchar *path, GError **err); -+uint32_t pv_img_get_enc_size(const PvImage *img); -+uint32_t pv_img_get_pv_hdr_size(const PvImage *img); -+gint pv_img_write(PvImage *img, const gchar *path, GError **err); -+ -+G_DEFINE_AUTOPTR_CLEANUP_FUNC(PvImage, pv_img_free) -+ -+#endif ---- /dev/null -+++ b/genprotimg/src/pv/pv_ipib.c -@@ -0,0 +1,128 @@ -+/* -+ * PV IPIB related definitions and functions -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * 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 -+ -+#include "boot/ipl.h" -+#include "boot/s390.h" -+#include "common.h" -+#include "include/pv_hdr_def.h" -+#include "lib/zt_common.h" -+#include "utils/align.h" -+#include "utils/buffer.h" -+ -+#include "pv_comp.h" -+#include "pv_error.h" -+#include "pv_ipib.h" -+ -+uint64_t pv_ipib_get_size(uint32_t num_comp) -+{ -+ gsize ipib_size = sizeof(struct ipl_pl_hdr) + -+ sizeof(struct ipl_pb0_pv) + -+ num_comp * sizeof(struct ipl_pb0_pv_comp); -+ -+ /* the minimal size is one page */ -+ return MAX(ipib_size, PAGE_SIZE); -+} -+ -+static gint pv_ipib_init(IplParameterBlock *ipib, GSList *comps, -+ const Buffer *hdr) -+{ -+ g_assert(sizeof(struct ipl_pl_hdr) <= UINT32_MAX); -+ g_assert(sizeof(struct ipl_pb0_pv_comp) <= UINT32_MAX); -+ g_assert(sizeof(struct ipl_pb0_pv) <= UINT32_MAX); -+ g_assert(ipib); -+ -+ guint comps_length = g_slist_length(comps); -+ uint32_t ipl_pl_hdr_size = (uint32_t)sizeof(struct ipl_pl_hdr); -+ struct ipl_pb0_pv *pv = &ipib->pv; -+ uint32_t ipib_comps_size; -+ uint32_t blk0_len; -+ uint32_t ipib_size; -+ gsize i; -+ -+ g_assert_true( -+ g_uint_checked_mul(&ipib_comps_size, comps_length, -+ (uint32_t)sizeof(struct ipl_pb0_pv_comp))); -+ g_assert_true(g_uint_checked_add(&blk0_len, (uint32_t)sizeof(*pv), -+ ipib_comps_size)); -+ g_assert(ipl_pl_hdr_size + blk0_len <= PAGE_SIZE); -+ -+ ipib_size = MAX(ipl_pl_hdr_size + blk0_len, (uint32_t)PAGE_SIZE); -+ g_assert(pv_ipib_get_size(comps_length) == ipib_size); -+ -+ pv->pbt = IPL_TYPE_PV; -+ pv->len = GUINT32_TO_BE(blk0_len); -+ pv->num_comp = GUINT32_TO_BE(comps_length); -+ /* both values will be overwritten during the IPL process by -+ * the stage3a loader -+ */ -+ pv->pv_hdr_addr = GUINT64_TO_BE(0x0); -+ pv->pv_hdr_size = GUINT64_TO_BE(hdr->size); -+ -+ ipib->hdr.len = GUINT32_TO_BE(ipib_size); -+ ipib->hdr.version = IPL_PARM_BLOCK_VERSION; -+ -+ i = 0; -+ for (GSList *iterator = comps; iterator; iterator = iterator->next, i++) { -+ const PvComponent *comp = iterator->data; -+ uint64_t comp_addr, comp_size; -+ -+ g_assert(comp); -+ -+ comp_addr = pv_component_get_src_addr(comp); -+ comp_size = pv_component_size(comp); -+ -+ g_assert(IS_PAGE_ALIGNED(comp_size)); -+ -+ pv->components[i].addr = GUINT64_TO_BE(comp_addr); -+ pv->components[i].len = GUINT64_TO_BE(comp_size); -+ pv->components[i].tweak_pref = -+ GUINT64_TO_BE(pv_component_get_tweak_prefix(comp)); -+ if (i > 0) { -+ /* tweak prefixes of the components must grow -+ * strictly monotonous -+ */ -+ g_assert(GUINT64_FROM_BE(pv->components[i].tweak_pref) > -+ GUINT64_FROM_BE(pv->components[i - 1].tweak_pref)); -+ } -+ } -+ -+ return 0; -+} -+ -+IplParameterBlock *pv_ipib_new(GSList *comps, const Buffer *hdr, GError **err) -+{ -+ uint64_t ipib_size = pv_ipib_get_size(g_slist_length(comps)); -+ g_autoptr(IplParameterBlock) ret = NULL; -+ -+ if (ipib_size > PV_V1_IPIB_MAX_SIZE) { -+ g_set_error(err, PV_ERROR, PV_ERROR_IPIB_SIZE, -+ _("IPIB size is too large: %lu < %lu"), ipib_size, -+ PAGE_SIZE); -+ return NULL; -+ } -+ -+ ret = g_malloc0(ipib_size); -+ if (pv_ipib_init(ret, comps, hdr) < 0) -+ return NULL; -+ -+ return g_steal_pointer(&ret); -+} -+ -+void pv_ipib_free(IplParameterBlock *ipib) -+{ -+ if (!ipib) -+ return; -+ -+ g_free(ipib); -+} ---- /dev/null -+++ b/genprotimg/src/pv/pv_ipib.h -@@ -0,0 +1,27 @@ -+/* -+ * PV IPIB related definitions and functions -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * s390-tools is free software; you can redistribute it and/or modify -+ * it under the terms of the MIT license. See LICENSE for details. -+ */ -+ -+#ifndef PV_IPIB_H -+#define PV_IPIB_H -+ -+#include -+#include -+ -+#include "boot/ipl.h" -+#include "utils/buffer.h" -+ -+typedef struct ipl_parameter_block IplParameterBlock; -+ -+uint64_t pv_ipib_get_size(uint32_t num_comp); -+IplParameterBlock *pv_ipib_new(GSList *comps, const Buffer *hdr, GError **err); -+void pv_ipib_free(IplParameterBlock *ipib); -+ -+WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(IplParameterBlock, pv_ipib_free) -+ -+#endif ---- /dev/null -+++ b/genprotimg/src/pv/pv_opt_item.c -@@ -0,0 +1,26 @@ -+/* -+ * PV optional item related definitions and functions -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * 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 "pv_opt_item.h" -+ -+uint32_t pv_opt_item_size(const struct pv_hdr_opt_item *item G_GNUC_UNUSED) -+{ -+ /* not implemented yet */ -+ g_assert_not_reached(); -+} -+ -+void pv_opt_item_free(struct pv_hdr_opt_item *item) -+{ -+ if (!item) -+ return; -+ -+ g_free(item); -+} ---- /dev/null -+++ b/genprotimg/src/pv/pv_opt_item.h -@@ -0,0 +1,20 @@ -+/* -+ * PV optional item related definitions and functions -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * s390-tools is free software; you can redistribute it and/or modify -+ * it under the terms of the MIT license. See LICENSE for details. -+ */ -+ -+#ifndef PV_OPT_ITEM_H -+#define PV_OPT_ITEM_H -+ -+#include -+ -+#include "include/pv_hdr_def.h" -+ -+uint32_t pv_opt_item_size(const struct pv_hdr_opt_item *item); -+void pv_opt_item_free(struct pv_hdr_opt_item *item); -+ -+#endif ---- /dev/null -+++ b/genprotimg/src/pv/pv_stage3.c -@@ -0,0 +1,164 @@ -+/* -+ * PV stage3 loader related definitions and functions -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * 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 "boot/ipl.h" -+#include "boot/stage3a.h" -+#include "boot/stage3b.h" -+#include "common.h" -+#include "utils/align.h" -+ -+#include "pv_error.h" -+#include "pv_stage3.h" -+ -+#define STAGE3A_ARGS(data_ptr, loader_size) \ -+ ((struct stage3a_args *)((uint64_t)data_ptr + loader_size - \ -+ sizeof(struct stage3a_args))) -+ -+static Buffer *loader_getblob(const gchar *filename, gsize *loader_size, -+ gsize args_size, gsize data_size, -+ gboolean data_aligned, GError **err) -+{ -+ g_autoptr(GMappedFile) mapped_file = NULL; -+ g_autoptr(Buffer) ret = NULL; -+ gsize size, tmp_loader_size; -+ gchar *loader_data; -+ -+ g_assert(loader_size); -+ -+ mapped_file = g_mapped_file_new(filename, FALSE, err); -+ if (!mapped_file) -+ return NULL; -+ -+ loader_data = g_mapped_file_get_contents(mapped_file); -+ if (!loader_data) { -+ g_set_error(err, G_FILE_ERROR, G_FILE_ERROR_BADF, -+ _("File '%s' is empty"), filename); -+ return NULL; -+ } -+ tmp_loader_size = g_mapped_file_get_length(mapped_file); -+ -+ if (tmp_loader_size < args_size) { -+ g_set_error(err, G_FILE_ERROR, G_FILE_ERROR_BADF, -+ _("File size less than expected: %lu < %ln"), -+ tmp_loader_size, loader_size); -+ return NULL; -+ } -+ -+ /* For example, the PV header and IPIB data must be page -+ * aligned. -+ */ -+ size = (data_aligned ? PAGE_ALIGN(tmp_loader_size) : tmp_loader_size) + -+ data_size; -+ -+ ret = buffer_alloc(size); -+ -+ /* copy the loader "template" */ -+ memcpy(ret->data, loader_data, tmp_loader_size); -+ /* reset our dummy data (offsets and length) to zeros */ -+ memset((uint8_t *)ret->data + tmp_loader_size - args_size, 0, -+ args_size); -+ *loader_size = tmp_loader_size; -+ return g_steal_pointer(&ret); -+} -+ -+Buffer *stage3a_getblob(const gchar *filename, gsize *loader_size, -+ gsize data_size, GError **err) -+{ -+ return loader_getblob(filename, loader_size, -+ sizeof(struct stage3a_args), data_size, TRUE, -+ err); -+} -+ -+/* For the memory layout see stage3a.lds */ -+/* Set the right offsets and sizes in the stage3a template + add -+ * the IPIB block with the PV header -+ */ -+static gint stage3a_set_data(Buffer *loader, gsize loader_size, -+ const Buffer *hdr, struct ipl_parameter_block *ipib, -+ GError **err) -+{ -+ uint32_t ipib_size = GUINT32_FROM_BE(ipib->hdr.len); -+ gsize args_size = sizeof(struct stage3a_args); -+ uint32_t hdr_size = (uint32_t)hdr->size; -+ uint64_t args_addr, next_data_addr; -+ -+ if (hdr->size > UINT32_MAX) { -+ g_set_error(err, PV_ERROR, PV_ERROR_INTERNAL, -+ _("Invalid header size: %zu"), hdr->size); -+ return -1; -+ } -+ -+ /* we assume here that the loader ``stage3a`` is loaded page -+ * aligned in the guest -+ */ -+ args_addr = (uint64_t)loader->data + loader_size - args_size; -+ -+ /* therefore `next_data_addr` is also page aligned */ -+ next_data_addr = (uint64_t)loader->data + PAGE_ALIGN(loader_size); -+ -+ /* copy IPIB data */ -+ memcpy((void *)next_data_addr, ipib, ipib_size); -+ -+ /* set IPIB offset in relation to the stage3a arguments */ -+ STAGE3A_ARGS(loader->data, loader_size)->ipib_offs = -+ GUINT64_TO_BE(next_data_addr - args_addr); -+ -+ next_data_addr = next_data_addr + PAGE_ALIGN(ipib_size); -+ /* copy PV header */ -+ memcpy((void *)next_data_addr, hdr->data, hdr_size); -+ /* set PV header size and offset in relation to the stage3a -+ * arguments -+ */ -+ STAGE3A_ARGS(loader->data, loader_size)->hdr_offs = -+ GUINT64_TO_BE(next_data_addr - args_addr); -+ STAGE3A_ARGS(loader->data, loader_size)->hdr_size = GUINT64_TO_BE(hdr_size); -+ -+ return 0; -+} -+ -+gint build_stage3a(Buffer *loader, gsize loader_size, const Buffer *hdr, -+ struct ipl_parameter_block *ipib, GError **err) -+{ -+ return stage3a_set_data(loader, loader_size, hdr, ipib, err); -+} -+ -+Buffer *stage3b_getblob(const gchar *filename, GError **err) -+{ -+ g_autoptr(Buffer) ret = NULL; -+ gsize rb_size; -+ -+ ret = loader_getblob(filename, &rb_size, sizeof(struct stage3b_args), 0, -+ FALSE, err); -+ if (!ret) -+ return NULL; -+ -+ g_assert(ret->size == rb_size); -+ return g_steal_pointer(&ret); -+} -+ -+void build_stage3b(Buffer *stage3b, const struct stage3b_args *args) -+{ -+ g_assert(stage3b->size > sizeof(*args)); -+ -+ /* at the end of the stage3b there are the stage3b args -+ * positioned -+ */ -+ memcpy((uint8_t *)stage3b->data + stage3b->size - sizeof(*args), args, -+ sizeof(*args)); -+} -+ -+void memblob_init(struct memblob *arg, uint64_t src, uint64_t size) -+{ -+ arg->src = GUINT64_TO_BE(src); -+ arg->size = GUINT64_TO_BE(size); -+} ---- /dev/null -+++ b/genprotimg/src/pv/pv_stage3.h -@@ -0,0 +1,30 @@ -+/* -+ * PV stage3 loader related definitions and functions -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * s390-tools is free software; you can redistribute it and/or modify -+ * it under the terms of the MIT license. See LICENSE for details. -+ */ -+ -+#ifndef PV_STAGE3_H -+#define PV_STAGE3_H -+ -+#include -+#include -+#include -+ -+#include "boot/ipl.h" -+#include "boot/s390.h" -+#include "boot/stage3b.h" -+#include "utils/buffer.h" -+ -+Buffer *stage3a_getblob(const gchar *filename, gsize *loader_size, -+ gsize data_size, GError **err); -+gint build_stage3a(Buffer *dc, gsize dc_size, const Buffer *hdr, -+ struct ipl_parameter_block *ipib, GError **err); -+Buffer *stage3b_getblob(const gchar *filename, GError **err); -+void build_stage3b(Buffer *stage3b, const struct stage3b_args *args); -+void memblob_init(struct memblob *arg, uint64_t src, uint64_t size); -+ -+#endif ---- /dev/null -+++ b/genprotimg/src/utils/align.h -@@ -0,0 +1,24 @@ -+/* -+ * Alignment utils -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * s390-tools is free software; you can redistribute it and/or modify -+ * it under the terms of the MIT license. See LICENSE for details. -+ */ -+ -+#ifndef PV_UTILS_ALIGN_H -+#define PV_UTILS_ALIGN_H -+ -+#include "boot/s390.h" -+#include "lib/zt_common.h" -+ -+#define IS_ALIGNED(addr, size) (!(addr & (size - 1))) -+ -+/* align addr to the next page boundary */ -+#define PAGE_ALIGN(addr) ALIGN((unsigned long)addr, PAGE_SIZE) -+ -+/* test whether an address is aligned to PAGE_SIZE or not */ -+#define IS_PAGE_ALIGNED(addr) IS_ALIGNED((unsigned long)(addr), PAGE_SIZE) -+ -+#endif ---- /dev/null -+++ b/genprotimg/src/utils/buffer.c -@@ -0,0 +1,69 @@ -+/* -+ * Buffer functions -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * 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 -+ -+#include "align.h" -+#include "buffer.h" -+#include "common.h" -+#include "file_utils.h" -+ -+Buffer *buffer_alloc(gsize size) -+{ -+ Buffer *ret = g_new0(Buffer, 1); -+ -+ ret->data = g_malloc0(size); -+ ret->size = size; -+ return ret; -+} -+ -+Buffer *buffer_dup(const Buffer *buf, gboolean page_aligned) -+{ -+ Buffer *ret; -+ gsize size; -+ -+ if (!buf) -+ return NULL; -+ -+ size = buf->size; -+ if (page_aligned) -+ size = PAGE_ALIGN(size); -+ -+ ret = buffer_alloc(size); -+ -+ /* content will be 0-right-padded */ -+ memcpy(ret->data, buf->data, buf->size); -+ return ret; -+} -+ -+gint buffer_write(const Buffer *buf, FILE *file, GError **err) -+{ -+ return file_write(file, buf->data, buf->size, 1, NULL, err); -+} -+ -+void buffer_free(Buffer *buf) -+{ -+ if (!buf) -+ return; -+ -+ g_free(buf->data); -+ g_free(buf); -+} -+ -+void buffer_clear(Buffer **buf) -+{ -+ if (!buf || !*buf) -+ return; -+ -+ buffer_free(*buf); -+ *buf = NULL; -+} ---- /dev/null -+++ b/genprotimg/src/utils/buffer.h -@@ -0,0 +1,31 @@ -+/* -+ * Buffer definition and functions -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * s390-tools is free software; you can redistribute it and/or modify -+ * it under the terms of the MIT license. See LICENSE for details. -+ */ -+ -+#ifndef PV_UTILS_BUFFER_H -+#define PV_UTILS_BUFFER_H -+ -+#include -+#include -+ -+#include "common.h" -+ -+typedef struct Buffer { -+ void *data; -+ gsize size; /* in bytes */ -+} Buffer; -+ -+Buffer *buffer_alloc(gsize size); -+void buffer_free(Buffer *buf); -+void buffer_clear(Buffer **buf); -+gint buffer_write(const Buffer *buf, FILE *file, GError **err); -+Buffer *buffer_dup(const Buffer *buf, gboolean page_aligned); -+ -+WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(Buffer, buffer_free) -+ -+#endif ---- /dev/null -+++ b/genprotimg/src/utils/crypto.c -@@ -0,0 +1,798 @@ -+/* -+ * General cryptography helper functions -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "boot/s390.h" -+#include "common.h" -+#include "include/pv_crypto_def.h" -+#include "pv/pv_error.h" -+ -+#include "buffer.h" -+#include "crypto.h" -+ -+EVP_MD_CTX *digest_ctx_new(const EVP_MD *md, GError **err) -+{ -+ g_autoptr(EVP_MD_CTX) ctx = EVP_MD_CTX_new(); -+ -+ if (!ctx) -+ g_abort(); -+ -+ if (EVP_DigestInit_ex(ctx, md, NULL) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, -+ _("EVP_DigestInit_ex failed")); -+ return NULL; -+ } -+ -+ return g_steal_pointer(&ctx); -+} -+ -+Buffer *digest_ctx_finalize(EVP_MD_CTX *ctx, GError **err) -+{ -+ gint md_size = EVP_MD_size(EVP_MD_CTX_md(ctx)); -+ g_autoptr(Buffer) ret = NULL; -+ guint digest_size; -+ -+ g_assert(md_size > 0); -+ -+ ret = buffer_alloc((guint)md_size); -+ if (EVP_DigestFinal_ex(ctx, ret->data, &digest_size) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, -+ _("EVP_DigestFinal_ex failed")); -+ return NULL; -+ } -+ -+ g_assert(digest_size == (guint)md_size); -+ g_assert(digest_size == ret->size); -+ return g_steal_pointer(&ret); -+} -+ -+/* Returns the digest of @buf using the hash algorithm @md */ -+static Buffer *digest_buffer(const EVP_MD *md, const Buffer *buf, GError **err) -+{ -+ g_autoptr(EVP_MD_CTX) md_ctx = NULL; -+ g_autoptr(Buffer) ret = NULL; -+ g_assert(buf); -+ -+ md_ctx = digest_ctx_new(md, err); -+ if (!md_ctx) -+ return NULL; -+ -+ if (EVP_DigestUpdate(md_ctx, buf->data, buf->size) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, -+ _("EVP_DigestUpdate failed")); -+ return NULL; -+ } -+ -+ ret = digest_ctx_finalize(md_ctx, err); -+ if (!ret) -+ return NULL; -+ -+ return g_steal_pointer(&ret); -+} -+ -+/* Returns the SHA256 digest of @buf */ -+Buffer *sha256_buffer(const Buffer *buf, GError **err) -+{ -+ g_autoptr(Buffer) ret = NULL; -+ -+ ret = digest_buffer(EVP_sha256(), buf, err); -+ if (!ret) -+ return NULL; -+ -+ g_assert(ret->size == SHA256_DIGEST_LENGTH); -+ return g_steal_pointer(&ret); -+} -+ -+/* Convert a EVP_PKEY to the key format used in the PV header */ -+union ecdh_pub_key *evp_pkey_to_ecdh_pub_key(EVP_PKEY *key, GError **err) -+{ -+ g_autofree union ecdh_pub_key *ret = g_new0(union ecdh_pub_key, 1); -+ g_autoptr(BIGNUM) pub_x_big = NULL; -+ g_autoptr(BIGNUM) pub_y_big = NULL; -+ g_autoptr(EC_KEY) ec_key = NULL; -+ const EC_POINT *pub_key; -+ const EC_GROUP *grp; -+ -+ ec_key = EVP_PKEY_get1_EC_KEY(key); -+ if (!ec_key) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, -+ _("Key has the wrong type")); -+ return NULL; -+ } -+ -+ pub_key = EC_KEY_get0_public_key(ec_key); -+ if (!pub_key) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, -+ _("Failed to get public key")); -+ return NULL; -+ } -+ -+ grp = EC_KEY_get0_group(ec_key); -+ if (!grp) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, -+ _("Failed to get EC group")); -+ return NULL; -+ } -+ -+ pub_x_big = BN_new(); -+ if (!pub_x_big) -+ g_abort(); -+ -+ pub_y_big = BN_new(); -+ if (!pub_y_big) -+ g_abort(); -+ -+ if (EC_POINT_get_affine_coordinates_GFp(grp, pub_key, pub_x_big, -+ pub_y_big, NULL) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, -+ _("Cannot convert key to internal format")); -+ return NULL; -+ } -+ -+ if (BN_bn2binpad(pub_x_big, ret->x, sizeof(ret->x)) < 0) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, -+ _("Cannot convert key to internal format")); -+ return NULL; -+ } -+ -+ if (BN_bn2binpad(pub_y_big, ret->y, sizeof(ret->y)) < 0) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, -+ _("Cannot convert key to internal format")); -+ return NULL; -+ } -+ -+ return g_steal_pointer(&ret); -+} -+ -+static Buffer *derive_key(EVP_PKEY *cust, EVP_PKEY *host, GError **err) -+{ -+ g_autoptr(EVP_PKEY_CTX) ctx = NULL; -+ g_autoptr(Buffer) ret = NULL; -+ gsize key_size; -+ -+ ctx = EVP_PKEY_CTX_new(cust, NULL); -+ if (!ctx) -+ g_abort(); -+ -+ if (EVP_PKEY_derive_init(ctx) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, -+ _("Key derivation failed")); -+ return NULL; -+ } -+ -+ if (EVP_PKEY_derive_set_peer(ctx, host) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, -+ _("Key derivation failed")); -+ return NULL; -+ } -+ -+ /* Determine buffer length */ -+ if (EVP_PKEY_derive(ctx, NULL, &key_size) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_DERIVE, -+ _("Key derivation failed")); -+ return NULL; -+ } -+ -+ ret = buffer_alloc(key_size); -+ if (EVP_PKEY_derive(ctx, ret->data, &key_size) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_DERIVE, -+ _("Key derivation failed")); -+ return NULL; -+ } -+ -+ g_assert(ret->size == key_size); -+ return g_steal_pointer(&ret); -+} -+ -+Buffer *compute_exchange_key(EVP_PKEY *cust, EVP_PKEY *host, GError **err) -+{ -+ g_autoptr(Buffer) raw = buffer_alloc(70); -+ g_autoptr(Buffer) ret = NULL; -+ g_autoptr(Buffer) key = NULL; -+ guchar *data; -+ -+ key = derive_key(cust, host, err); -+ if (!key) -+ return NULL; -+ -+ g_assert(key->size == 66); -+ g_assert(key->size < raw->size); -+ -+ /* ANSI X.9.63-2011: 66 bytes x with leading 7 bits and -+ * concatenate 32 bit int '1' -+ */ -+ memcpy(raw->data, key->data, key->size); -+ data = raw->data; -+ data[66] = 0x00; -+ data[67] = 0x00; -+ data[68] = 0x00; -+ data[69] = 0x01; -+ -+ ret = sha256_buffer(raw, err); -+ if (!ret) -+ return NULL; -+ -+ return g_steal_pointer(&ret); -+} -+ -+gint generate_tweak(union tweak *tweak, uint16_t i, GError **err) -+{ -+ tweak->cmp_idx.idx = GUINT16_TO_BE(i); -+ if (RAND_bytes(tweak->cmp_idx.rand, sizeof(tweak->cmp_idx.rand)) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_RANDOMIZATION, -+ _("Generating a tweak failed because the required amount of random data is not available")); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static Buffer *generate_rand_data(guint size, const gchar *err_msg, -+ GError **err) -+{ -+ g_autoptr(Buffer) buf = buffer_alloc(size); -+ -+ g_assert(size <= INT_MAX); -+ -+ if (RAND_bytes(buf->data, (int)size) != 1) { -+ g_set_error_literal(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_RANDOMIZATION, -+ err_msg); -+ return NULL; -+ } -+ -+ return g_steal_pointer(&buf); -+} -+ -+Buffer *generate_aes_iv(guint size, GError **err) -+{ -+ return generate_rand_data(size, -+ _("Generating a IV failed because the required amount of random data is not available"), -+ err); -+} -+ -+Buffer *generate_aes_key(guint size, GError **err) -+{ -+ return generate_rand_data(size, -+ _("Generating a key failed because the required amount of random data is not available"), -+ err); -+} -+ -+EVP_PKEY *generate_ec_key(gint nid, GError **err) -+{ -+ g_autoptr(EVP_PKEY_CTX) ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); -+ g_autoptr(EVP_PKEY) ret = NULL; -+ -+ if (!ctx) -+ g_abort(); -+ -+ if (EVP_PKEY_keygen_init(ctx) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_KEYGENERATION, -+ _("EC key could not be auto-generated")); -+ return NULL; -+ } -+ -+ if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_KEYGENERATION, -+ _("EC key could not be auto-generated")); -+ return NULL; -+ } -+ -+ if (EVP_PKEY_keygen(ctx, &ret) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_KEYGENERATION, -+ _("EC key could not be auto-generated")); -+ return NULL; -+ } -+ -+ return g_steal_pointer(&ret); -+} -+ -+static gboolean certificate_uses_correct_curve(EVP_PKEY *key, gint nid, -+ GError **err) -+{ -+ g_autoptr(EC_KEY) ec = NULL; -+ gint rc; -+ -+ g_assert(key); -+ -+ if (EVP_PKEY_id(key) != EVP_PKEY_EC) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INVALID_PARM, -+ _("No EC key found")); -+ return FALSE; -+ } -+ -+ ec = EVP_PKEY_get1_EC_KEY(key); -+ if (!ec) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INVALID_PARM, -+ _("No EC key found")); -+ return FALSE; -+ } -+ -+ if (EC_KEY_check_key(ec) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INVALID_PARM, -+ _("Invalid EC key")); -+ return FALSE; -+ } -+ -+ rc = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)); -+ if (rc != nid) { -+ /* maybe the NID is unset */ -+ if (rc == 0) { -+ g_autoptr(EC_GROUP) grp = EC_GROUP_new_by_curve_name(nid); -+ const EC_POINT *pub = EC_KEY_get0_public_key(ec); -+ g_autoptr(BN_CTX) ctx = BN_CTX_new(); -+ -+ if (EC_POINT_is_on_curve(grp, pub, ctx) != 1) { -+ g_set_error_literal(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_INVALID_PARM, -+ _("Invalid EC curve")); -+ return FALSE; -+ } -+ } else { -+ /* NID was set but doesn't match with the expected NID -+ */ -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_INVALID_PARM, -+ _("Wrong NID used: '%d'"), -+ EC_GROUP_get_curve_name(EC_KEY_get0_group(ec))); -+ return FALSE; -+ } -+ } -+ -+ return TRUE; -+} -+ -+static gboolean verify_certificate(X509_STORE *store, X509 *cert, GError **err) -+{ -+ g_autoptr(X509_STORE_CTX) csc = X509_STORE_CTX_new(); -+ if (!csc) -+ g_abort(); -+ -+ if (X509_STORE_CTX_init(csc, store, cert, NULL) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INIT, -+ _("Failed to initialize X.509 store")); -+ return FALSE; -+ } -+ -+ if (X509_verify_cert(csc) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_VERIFICATION, -+ _("Failed to verify host-key document")); -+ return FALSE; -+ } -+ -+ return TRUE; -+} -+ -+static X509 *load_certificate(const gchar *path, GError **err) -+{ -+ g_autoptr(X509) ret = NULL; -+ g_autoptr(BIO) bio = BIO_new_file(path, "rb"); -+ -+ if (!bio) { -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_READ_CERTIFICATE, -+ _("Failed to read host-key document: '%s'"), path); -+ return NULL; -+ } -+ -+ ret = PEM_read_bio_X509(bio, NULL, 0, NULL); -+ if (!ret) { -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_READ_CERTIFICATE, -+ _("Failed to load host-key document: '%s'"), path); -+ return NULL; -+ } -+ -+ return g_steal_pointer(&ret); -+} -+ -+EVP_PKEY *read_ec_pubkey_cert(X509_STORE *store, gint nid, const gchar *path, -+ GError **err) -+{ -+ g_autoptr(EVP_PKEY) ret = NULL; -+ g_autoptr(X509) cert = NULL; -+ -+ cert = load_certificate(path, err); -+ if (!cert) -+ return NULL; -+ -+ if (store && !verify_certificate(store, cert, err)) { -+ g_prefix_error(err, -+ _("Failed to load host-key document: '%s': "), -+ path); -+ return NULL; -+ } -+ -+ ret = X509_get_pubkey(cert); -+ if (!ret) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INVALID_PARM, -+ _("Failed to get public key from host-key document: '%s'"), -+ path); -+ return NULL; -+ } -+ -+ if (!certificate_uses_correct_curve(ret, nid, err)) { -+ g_prefix_error(err, -+ _("Failed to load host-key document: '%s': "), -+ path); -+ return NULL; -+ } -+ -+ return g_steal_pointer(&ret); -+} -+ -+static gint __encrypt_decrypt_bio(const struct cipher_parms *parms, BIO *b_in, -+ BIO *b_out, gsize *size_in, gsize *size_out, -+ gboolean encrypt, GError **err) -+{ -+ gint num_bytes_read, num_bytes_written; -+ g_autoptr(EVP_CIPHER_CTX) ctx = NULL; -+ g_autoptr(BIGNUM) tweak_num = NULL; -+ const EVP_CIPHER *cipher = parms->cipher; -+ gint cipher_block_size = EVP_CIPHER_block_size(cipher); -+ guchar in_buf[PAGE_SIZE], -+ out_buf[PAGE_SIZE + (guint)cipher_block_size]; -+ const Buffer *key = parms->key; -+ const Buffer *tweak = parms->iv_or_tweak; -+ g_autofree guchar *tmp_tweak = NULL; -+ gint out_len, tweak_size; -+ gsize tmp_size_in = 0, tmp_size_out = 0; -+ -+ g_assert(cipher_block_size > 0); -+ g_assert(key); -+ g_assert(tweak); -+ g_assert(tweak->size <= INT_MAX); -+ -+ /* copy the value for leaving the original value untouched */ -+ tmp_tweak = g_malloc0(tweak->size); -+ memcpy(tmp_tweak, tweak->data, tweak->size); -+ tweak_size = (int)tweak->size; -+ tweak_num = BN_bin2bn(tmp_tweak, tweak_size, NULL); -+ if (!tweak_num) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, -+ _("BN_bin2bn failed")); -+ return -1; -+ } -+ -+ ctx = EVP_CIPHER_CTX_new(); -+ if (!ctx) -+ g_abort(); -+ -+ /* don't set the key or tweak right away as we want to check -+ * lengths before -+ */ -+ if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, encrypt) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, -+ _("EVP_CipherInit_ex failed")); -+ return -1; -+ } -+ -+ /* Now we can set the key and tweak */ -+ if (EVP_CipherInit_ex(ctx, NULL, NULL, key->data, tmp_tweak, encrypt) != -+ 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, -+ _("EVP_CipherInit_ex failed")); -+ return -1; -+ } -+ -+ do { -+ memset(in_buf, 0, sizeof(in_buf)); -+ /* Read in data in 4096 bytes blocks. Update the ciphering -+ * with each read. -+ */ -+ num_bytes_read = BIO_read(b_in, in_buf, (int)PAGE_SIZE); -+ if (num_bytes_read < 0) { -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_INTERNAL, -+ _("Failed to read")); -+ return -1; -+ } -+ tmp_size_in += (guint)num_bytes_read; -+ -+ /* in case we reached the end and it's not the special -+ * case of an empty component we can break here -+ */ -+ if (num_bytes_read == 0 && tmp_size_in != 0) -+ break; -+ -+ if (EVP_CipherUpdate(ctx, out_buf, &out_len, in_buf, -+ sizeof(in_buf)) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_INTERNAL, -+ _("EVP_CipherUpdate failed")); -+ return -1; -+ } -+ g_assert(out_len >= 0); -+ -+ num_bytes_written = BIO_write(b_out, out_buf, out_len); -+ if (num_bytes_written < 0) { -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_INTERNAL, -+ _("Failed to write")); -+ return -1; -+ } -+ g_assert(num_bytes_written == out_len); -+ -+ tmp_size_out += (guint)num_bytes_written; -+ -+ /* Set new tweak value. Please keep in mind that the -+ * tweaks are stored in big-endian form. Therefore we -+ * must use the correct OpenSSL functions -+ */ -+ if (BN_add_word(tweak_num, PAGE_SIZE) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_INTERNAL, -+ _("BN_add_word failed")); -+ } -+ g_assert(BN_num_bytes(tweak_num) > 0); -+ g_assert(BN_num_bytes(tweak_num) <= tweak_size); -+ -+ if (BN_bn2binpad(tweak_num, tmp_tweak, tweak_size) < 0) { -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_INTERNAL, -+ _("BN_bn2binpad failed")); -+ }; -+ -+ /* set new tweak */ -+ if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, tmp_tweak, -+ encrypt) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_INTERNAL, -+ _("EVP_CipherInit_ex failed")); -+ return -1; -+ } -+ } while (num_bytes_read == PAGE_SIZE); -+ -+ /* Now cipher the final block and write it out to file */ -+ if (EVP_CipherFinal_ex(ctx, out_buf, &out_len) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, -+ _("EVP_CipherFinal_ex failed")); -+ return -1; -+ } -+ g_assert(out_len >= 0); -+ -+ num_bytes_written = BIO_write(b_out, out_buf, out_len); -+ if (num_bytes_written < 0) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, -+ _("Failed to write")); -+ return -1; -+ } -+ g_assert(out_len == num_bytes_written); -+ tmp_size_out += (guint)out_len; -+ -+ if (BIO_flush(b_out) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, -+ _("Failed to flush")); -+ return -1; -+ } -+ -+ *size_in = tmp_size_in; -+ *size_out = tmp_size_out; -+ return 0; -+} -+ -+static Buffer *__encrypt_decrypt_buffer(const struct cipher_parms *parms, -+ const Buffer *in, gboolean encrypt, -+ GError **err) -+{ -+ g_autoptr(Buffer) ret = NULL; -+ g_autoptr(BIO) b_out = NULL; -+ g_autoptr(BIO) b_in = NULL; -+ gsize in_size, out_size; -+ gchar *data = NULL; -+ long data_size; -+ -+ g_assert(in->size <= INT_MAX); -+ -+ b_in = BIO_new_mem_buf(in->data, (int)in->size); -+ if (!b_in) -+ g_abort(); -+ -+ b_out = BIO_new(BIO_s_mem()); -+ if (!b_out) -+ g_abort(); -+ -+ if (__encrypt_decrypt_bio(parms, b_in, b_out, &in_size, &out_size, -+ encrypt, err) < 0) -+ return NULL; -+ -+ data_size = BIO_get_mem_data(b_out, &data); -+ if (data_size < 0) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, -+ _("Could not read buffer")); -+ return NULL; -+ } -+ -+ ret = buffer_alloc((unsigned long)data_size); -+ memcpy(ret->data, data, ret->size); -+ return g_steal_pointer(&ret); -+} -+ -+Buffer *encrypt_buf(const struct cipher_parms *parms, const Buffer *in, -+ GError **err) -+{ -+ return __encrypt_decrypt_buffer(parms, in, TRUE, err); -+} -+ -+Buffer *decrypt_buf(const struct cipher_parms *parms, const Buffer *in, -+ GError **err) -+{ -+ return __encrypt_decrypt_buffer(parms, in, FALSE, err); -+} -+ -+static gint __encrypt_decrypt_file(const struct cipher_parms *parms, -+ const gchar *path_in, const gchar *path_out, -+ gsize *size_in, gsize *size_out, gboolean encrypt, -+ GError **err) -+{ -+ g_autoptr(BIO) b_out = NULL; -+ g_autoptr(BIO) b_in = NULL; -+ -+ b_in = BIO_new_file(path_in, "rb"); -+ if (!b_in) { -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_READ_CERTIFICATE, -+ _("Failed to read file '%s'"), path_in); -+ return -1; -+ } -+ -+ b_out = BIO_new_file(path_out, "wb"); -+ if (!b_out) { -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_READ_CERTIFICATE, -+ _("Failed to write file '%s'"), path_out); -+ return -1; -+ } -+ -+ if (__encrypt_decrypt_bio(parms, b_in, b_out, size_in, size_out, -+ encrypt, err) < 0) -+ return -1; -+ -+ return 0; -+} -+ -+gint encrypt_file(const struct cipher_parms *parms, const gchar *path_in, -+ const gchar *path_out, gsize *in_size, gsize *out_size, -+ GError **err) -+{ -+ return __encrypt_decrypt_file(parms, path_in, path_out, in_size, -+ out_size, TRUE, err); -+} -+ -+G_GNUC_UNUSED static gint decrypt_file(const struct cipher_parms *parms, -+ const gchar *path_in, const gchar *path_out, -+ gsize *in_size, gsize *out_size, -+ GError **err) -+{ -+ return __encrypt_decrypt_file(parms, path_in, path_out, in_size, -+ out_size, FALSE, err); -+} -+ -+/* GCM mode uses (zero-)padding */ -+static int64_t gcm_encrypt_decrypt(const Buffer *in, const Buffer *aad, -+ const struct cipher_parms *parms, -+ Buffer *out, Buffer *tag, -+ enum PvCryptoMode mode, GError **err) -+{ -+ g_autoptr(EVP_CIPHER_CTX) ctx = NULL; -+ const EVP_CIPHER *cipher = parms->cipher; -+ const Buffer *iv = parms->iv_or_tweak; -+ gboolean encrypt = mode == PV_ENCRYPT; -+ const Buffer *key = parms->key; -+ int64_t ret = -1; -+ gint len = -1; -+ -+ g_assert(cipher); -+ g_assert(key); -+ g_assert(iv); -+ /* Checks for later casts */ -+ g_assert(aad->size <= INT_MAX); -+ g_assert(in->size <= INT_MAX); -+ g_assert(tag->size <= INT_MAX); -+ g_assert(iv->size <= INT_MAX); -+ g_assert(out->size == in->size); -+ -+ ctx = EVP_CIPHER_CTX_new(); -+ if (!ctx) -+ g_abort(); -+ -+ /* First, set the cipher algorithm so we can verify our key/IV lengths -+ */ -+ if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, encrypt) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, -+ _("EVP_CIPHER_CTX_new failed")); -+ return -1; -+ } -+ -+ /* Set IV length */ -+ if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, (int)iv->size, NULL) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, -+ _("EVP_CIPHER_CTX_ex failed")); -+ return -1; -+ } -+ -+ /* Initialise key and IV */ -+ if (EVP_CipherInit_ex(ctx, NULL, NULL, key->data, iv->data, encrypt) != -+ 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, -+ _("EVP_CipherInit_ex failed")); -+ return -1; -+ } -+ -+ if (aad->size > 0) { -+ /* Provide any AAD data */ -+ if (EVP_CipherUpdate(ctx, NULL, &len, aad->data, -+ (int)aad->size) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_INTERNAL, -+ _("EVP_CipherUpdate failed")); -+ return -1; -+ } -+ g_assert(len == (int)aad->size); -+ } -+ -+ /* Provide data to be en/decrypted */ -+ if (EVP_CipherUpdate(ctx, out->data, &len, in->data, (int)in->size) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, -+ _("EVP_CipherUpdate failed")); -+ return -1; -+ } -+ ret = len; -+ -+ if (!encrypt) { -+ /* Set expected tag value */ -+ if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, -+ (int)tag->size, tag->data) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_INTERNAL, -+ _("Setting the GCM tag failed")); -+ return -1; -+ } -+ } -+ -+ /* Finalize the en/decryption */ -+ if (EVP_CipherFinal_ex(ctx, (guchar *)out->data + len, &len) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, -+ _("EVP_CipherFinal_ex failed")); -+ return -1; -+ } -+ ret += len; -+ -+ if (encrypt) { -+ /* Get the tag */ -+ if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, -+ (int)tag->size, tag->data) != 1) { -+ g_set_error(err, PV_CRYPTO_ERROR, -+ PV_CRYPTO_ERROR_INTERNAL, -+ _("Getting the GCM tag failed")); -+ return -1; -+ } -+ } -+ -+ g_assert(ret == (int)in->size); -+ return ret; -+} -+ -+int64_t gcm_encrypt(const Buffer *in, const Buffer *aad, -+ const struct cipher_parms *parms, Buffer *out, Buffer *tag, -+ GError **err) -+{ -+ return gcm_encrypt_decrypt(in, aad, parms, out, tag, PV_ENCRYPT, err); -+} ---- /dev/null -+++ b/genprotimg/src/utils/crypto.h -@@ -0,0 +1,104 @@ -+/* -+ * General cryptography helper functions and definitions -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * s390-tools is free software; you can redistribute it and/or modify -+ * it under the terms of the MIT license. See LICENSE for details. -+ */ -+ -+#ifndef PV_UTILS_CRYPTO_H -+#define PV_UTILS_CRYPTO_H -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "common.h" -+#include "include/pv_crypto_def.h" -+#include "lib/zt_common.h" -+ -+#include "buffer.h" -+ -+#define AES_256_GCM_IV_SIZE 12 -+#define AES_256_GCM_TAG_SIZE 16 -+ -+#define AES_256_XTS_TWEAK_SIZE 16 -+#define AES_256_XTS_KEY_SIZE 64 -+ -+enum PvCryptoMode { -+ PV_ENCRYPT, -+ PV_DECRYPT, -+}; -+ -+typedef GSList HostKeyList; -+ -+/* Register auto cleanup functions */ -+WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(BIGNUM, BN_free) -+WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(BIO, BIO_free_all) -+WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(BN_CTX, BN_CTX_free) -+WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EC_GROUP, EC_GROUP_free) -+WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EC_KEY, EC_KEY_free) -+WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EC_POINT, EC_POINT_free) -+WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_CIPHER_CTX, EVP_CIPHER_CTX_free) -+WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_MD_CTX, EVP_MD_CTX_free) -+WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_PKEY, EVP_PKEY_free) -+WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_PKEY_CTX, EVP_PKEY_CTX_free) -+WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509, X509_free) -+WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_LOOKUP, X509_LOOKUP_free) -+WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_STORE, X509_STORE_free) -+WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_STORE_CTX, X509_STORE_CTX_free) -+ -+union cmp_index { -+ struct { -+ uint16_t idx; -+ guchar rand[6]; -+ } __packed; -+ uint64_t data; -+}; -+ -+/* The tweak is always stored in big endian format */ -+union tweak { -+ struct { -+ union cmp_index cmp_idx; -+ uint64_t page_idx; /* page index */ -+ } __packed; -+ uint8_t data[AES_256_XTS_TWEAK_SIZE]; -+}; -+ -+struct cipher_parms { -+ const EVP_CIPHER *cipher; -+ const Buffer *key; -+ const Buffer *iv_or_tweak; -+}; -+ -+EVP_PKEY *read_ec_pubkey_cert(X509_STORE *store, gint nid, const gchar *path, -+ GError **err); -+Buffer *compute_exchange_key(EVP_PKEY *cust, EVP_PKEY *host, GError **err); -+Buffer *generate_aes_key(guint size, GError **err); -+Buffer *generate_aes_iv(guint size, GError **err); -+EVP_PKEY *generate_ec_key(gint nid, GError **err); -+gint generate_tweak(union tweak *tweak, uint16_t i, GError **err); -+union ecdh_pub_key *evp_pkey_to_ecdh_pub_key(EVP_PKEY *key, GError **err); -+EVP_MD_CTX *digest_ctx_new(const EVP_MD *md, GError **err); -+Buffer *digest_ctx_finalize(EVP_MD_CTX *ctx, GError **err); -+Buffer *sha256_buffer(const Buffer *buf, GError **err); -+int64_t gcm_encrypt(const Buffer *in, const Buffer *aad, -+ const struct cipher_parms *parms, Buffer *out, -+ Buffer *tag, GError **err); -+gint encrypt_file(const struct cipher_parms *parms, const gchar *in_path, -+ const gchar *path_out, gsize *in_size, gsize *out_size, -+ GError **err); -+Buffer *encrypt_buf(const struct cipher_parms *parms, const Buffer *in, -+ GError **err); -+G_GNUC_UNUSED Buffer *decrypt_buf(const struct cipher_parms *parms, -+ const Buffer *in, GError **err); -+ -+#endif ---- /dev/null -+++ b/genprotimg/src/utils/file_utils.c -@@ -0,0 +1,234 @@ -+/* -+ * General file utils -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * 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 -+#include -+#include -+#include -+#include -+ -+#include "pv/pv_error.h" -+ -+#include "align.h" -+#include "buffer.h" -+#include "common.h" -+#include "file_utils.h" -+ -+FILE *file_open(const gchar *filename, const gchar *mode, GError **err) -+{ -+ FILE *f = fopen(filename, mode); -+ -+ if (!f) { -+ g_set_error(err, G_FILE_ERROR, -+ (gint)g_file_error_from_errno(errno), -+ _("Failed to open file '%s': %s"), filename, -+ g_strerror(errno)); -+ return NULL; -+ } -+ -+ return f; -+} -+ -+gint file_size(const gchar *filename, gsize *size, GError **err) -+{ -+ GStatBuf st_buf; -+ -+ g_assert(size); -+ -+ if (g_stat(filename, &st_buf) != 0) { -+ g_set_error(err, G_FILE_ERROR, -+ (gint)g_file_error_from_errno(errno), -+ _("Failed to get file status '%s': %s"), filename, -+ g_strerror(errno)); -+ return -1; -+ } -+ -+ if (!S_ISREG(st_buf.st_mode)) { -+ g_set_error(err, G_FILE_ERROR, PV_ERROR_INTERNAL, -+ _("File '%s' is not a regular file"), filename); -+ return -1; -+ } -+ -+ if (st_buf.st_size < 0) { -+ g_set_error(err, G_FILE_ERROR, PV_ERROR_INTERNAL, -+ _("Invalid file size for '%s': %zu"), filename, -+ st_buf.st_size); -+ return -1; -+ } -+ -+ *size = (gsize)st_buf.st_size; -+ return 0; -+} -+ -+/* Returns 0 on success, otherwise -1. Stores the total number of -+ * elements successfully read in @count_read -+ */ -+gint file_read(FILE *in, void *ptr, gsize size, gsize count, -+ gsize *count_read, GError **err) -+{ -+ gsize tmp_count_read; -+ -+ tmp_count_read = fread(ptr, size, count, in); -+ if (count_read) -+ *count_read = tmp_count_read; -+ -+ if (ferror(in)) { -+ g_set_error(err, G_FILE_ERROR, 0, _("Failed to read file")); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+gint file_write(FILE *out, const void *ptr, gsize size, gsize count, -+ gsize *count_written, GError **err) -+{ -+ gsize tmp_count_written; -+ -+ tmp_count_written = fwrite(ptr, size, count, out); -+ if (count_written) -+ *count_written = tmp_count_written; -+ -+ if (tmp_count_written != count || ferror(out)) { -+ g_set_error(err, G_FILE_ERROR, 0, _("Failed to write file")); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static gint file_seek(FILE *f, uint64_t offset, GError **err) -+{ -+ gint rc; -+ -+ if (offset > LONG_MAX) { -+ g_set_error(err, PV_ERROR, 0, _("Offset is too large")); -+ return -1; -+ } -+ -+ rc = fseek(f, (long)offset, SEEK_SET); -+ if (rc != 0) { -+ g_set_error(err, G_FILE_ERROR, -+ (gint)g_file_error_from_errno(errno), -+ _("Failed to seek: '%s'"), g_strerror(errno)); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+gint seek_and_write_file(FILE *o, const CompFile *ifile, uint64_t offset, -+ GError **err) -+{ -+ gsize bytes_read, bytes_written; -+ gsize total_bytes_read = 0; -+ FILE *i = NULL; -+ gchar buf[4096]; -+ gint ret = -1; -+ -+ if (file_seek(o, offset, err) < 0) -+ return -1; -+ -+ i = file_open(ifile->path, "rb", err); -+ if (!i) -+ return -1; -+ -+ do { -+ if (file_read(i, buf, 1, sizeof(buf), &bytes_read, err) < 0) { -+ g_prefix_error(err, _("Failed to read file '%s': "), -+ ifile->path); -+ goto err; -+ } -+ -+ if (bytes_read == 0) -+ break; -+ -+ total_bytes_read += bytes_read; -+ -+ if (file_write(o, buf, bytes_read, 1, &bytes_written, err) < 0) -+ goto err; -+ } while (bytes_written != 0); -+ -+ if (ifile->size != total_bytes_read) { -+ g_set_error(err, PV_ERROR, PV_ERROR_INTERNAL, -+ _("'%s' has changed during the preparation"), -+ ifile->path); -+ goto err; -+ } -+ -+ ret = 0; -+err: -+ fclose(i); -+ return ret; -+} -+ -+gint seek_and_write_buffer(FILE *o, const Buffer *buf, uint64_t offset, -+ GError **err) -+{ -+ if (file_seek(o, offset, err) < 0) -+ return -1; -+ -+ if (buffer_write(buf, o, err) < 0) -+ return -1; -+ -+ return 0; -+} -+ -+gint pad_file_right(const gchar *path_out, const gchar *path_in, gsize *size_out, -+ guint padding, GError **err) -+{ -+ FILE *f_in, *f_out = NULL; -+ guchar buf[padding]; -+ gsize num_bytes_written; -+ gsize num_bytes_read; -+ uint64_t size_in = 0; -+ gint ret = -1; -+ -+ *size_out = 0; -+ f_in = file_open(path_in, "rb", err); -+ if (!f_in) -+ goto err; -+ -+ f_out = file_open(path_out, "wb", err); -+ if (!f_out) -+ goto err; -+ -+ do { -+ memset(buf, 0, sizeof(buf)); -+ -+ if (file_read(f_in, buf, 1, sizeof(buf), &num_bytes_read, err) < 0) { -+ g_prefix_error(err, _("Failed to read file '%s': "), -+ path_in); -+ goto err; -+ } -+ -+ size_in += num_bytes_read; -+ -+ if (file_write(f_out, buf, 1, sizeof(buf), &num_bytes_written, err)) { -+ g_prefix_error(err, _("Failed to write file '%s': "), -+ path_out); -+ goto err; -+ } -+ -+ *size_out += num_bytes_written; -+ } while (num_bytes_read == padding); -+ -+ g_assert(num_bytes_written == ALIGN(num_bytes_read, padding)); -+ -+ ret = 0; -+err: -+ if (f_out) -+ fclose(f_out); -+ if (f_in) -+ fclose(f_in); -+ return ret; -+} ---- /dev/null -+++ b/genprotimg/src/utils/file_utils.h -@@ -0,0 +1,34 @@ -+/* -+ * General file utils -+ * -+ * Copyright IBM Corp. 2020 -+ * -+ * s390-tools is free software; you can redistribute it and/or modify -+ * it under the terms of the MIT license. See LICENSE for details. -+ */ -+ -+#ifndef PV_FILE_UTILS_H -+#define PV_FILE_UTILS_H -+ -+#include -+#include -+#include -+ -+#include "pv/pv_comp.h" -+ -+#include "buffer.h" -+ -+FILE *file_open(const gchar *filename, const gchar *mode, GError **err); -+gint file_size(const gchar *filename, gsize *size, GError **err); -+gint file_read(FILE *in, void *ptr, gsize size, gsize count, -+ gsize *count_read, GError **err); -+gint file_write(FILE *out, const void *ptr, gsize size, gsize count, -+ gsize *count_written, GError **err); -+gint pad_file_right(const gchar *path_out, const gchar *path_in, -+ gsize *size_out, guint padding, GError **err); -+gint seek_and_write_buffer(FILE *out, const Buffer *buf, uint64_t offset, -+ GError **err); -+gint seek_and_write_file(FILE *o, const CompFile *ifile, uint64_t offset, -+ GError **err); -+ -+#endif ---- a/include/boot/ipl.h -+++ b/include/boot/ipl.h -@@ -18,6 +18,11 @@ - #define IPL_RB_COMPONENT_FLAG_SIGNED 0x80 - #define IPL_RB_COMPONENT_FLAG_VERIFIED 0x40 - -+#define IPL_PARM_BLOCK_VERSION 0x1 -+ -+/* IPL Types */ -+#define IPL_TYPE_PV 0x5 -+ - - #ifndef __ASSEMBLER__ - diff --git a/s390-tools-sles15sp2-Close-file-descriptor-when-checking-for-read-only.patch b/s390-tools-sles15sp2-Close-file-descriptor-when-checking-for-read-only.patch deleted file mode 100644 index 188b54f..0000000 --- a/s390-tools-sles15sp2-Close-file-descriptor-when-checking-for-read-only.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- s390-tools-2.11.0/libdasd/dasd_ioctl.c 2019-09-06 08:13:09.000000000 -0400 -+++ s390-tools-2.11.0/libdasd/dasd_ioctl.c 2019-11-25 14:03:25.452391000 -0500 -@@ -149,6 +149,7 @@ - fd = dasd_open_device(device, O_RDWR); - RUN_IOCTL(fd, BLKROGET, &val); - *ro = (val != 0) ? true : false; -+ dasd_close_device(fd); - - return 0; - } diff --git a/s390-tools-sles15sp2-lsluns-try-harder-to-find-udevadm.patch b/s390-tools-sles15sp2-lsluns-try-harder-to-find-udevadm.patch deleted file mode 100644 index 5d6bad9..0000000 --- a/s390-tools-sles15sp2-lsluns-try-harder-to-find-udevadm.patch +++ /dev/null @@ -1,59 +0,0 @@ -From e679a4002ecea6d8177430d6efde2b3ef2b89d0e Mon Sep 17 00:00:00 2001 -From: Julian Wiedmann -Date: Wed, 13 May 2020 18:19:35 +0200 -Subject: [PATCH] lsluns: try harder to find udevadm -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Hard-coding udevadm's location isn't robust enough - for instance, -Ubuntu 20.04 moved it to /usr/bin. - -First see if we can reach it through $PATH, then fall back to hard-coded -locations that we know about. -Also when finally falling back to udevsettle, check that it exists. -Otherwise we end up throwing tons of "No such file or directory" error -messages at the user. - -Signed-off-by: Julian Wiedmann -Reviewed-by: Steffen Maier -Reviewed-by: Fedor Loshakov -Signed-off-by: Jan Höppner ---- - zconf/lsluns | 17 +++++++++++++---- - 1 file changed, 13 insertions(+), 4 deletions(-) - -diff --git a/zconf/lsluns b/zconf/lsluns -index bfe48f1..7144c78 100755 ---- a/zconf/lsluns -+++ b/zconf/lsluns -@@ -24,13 +24,22 @@ my $wlun = "0xc101000000000000"; - my $lun0 = "0x0000000000000000"; - my $sg_dir = "/sys/class/scsi_generic"; - my $udevsettle_call; --my $udevadm = "/sbin/udevadm"; - - --if (! -e $udevadm) { -- $udevsettle_call = "/sbin/udevsettle"; -+# See if we can find udevadm through $PATH: -+if (!system("udevadm --version > /dev/null 2>&1")) { -+ $udevsettle_call = "udevadm settle"; -+# Search udevadm in well-known locations: -+} elsif (-e "/sbin/udevadm") { -+ $udevsettle_call = "/sbin/udevadm settle"; -+} elsif (-e "/usr/bin/udevadm") { -+ $udevsettle_call = "/usr/bin/udevadm settle"; -+# Fall back to udevsettle: -+} elsif (-e "/sbin/udevsettle") { -+ $udevsettle_call = "/sbin/udevsettle"; - } else { -- $udevsettle_call = "$udevadm settle"; -+ $udevsettle_call = ""; -+ print "Failed to find any candidate for udevsettle.\n"; - } - - # read the first line of a sysfs-entry and compare it to a given string --- -2.26.2 - diff --git a/s390-tools-sles15sp2-mon_tools-update-udevadm-location.patch b/s390-tools-sles15sp2-mon_tools-update-udevadm-location.patch deleted file mode 100644 index d7741fd..0000000 --- a/s390-tools-sles15sp2-mon_tools-update-udevadm-location.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 2215ba672e2f1e69b21b8b852db566b87df7adf7 Mon Sep 17 00:00:00 2001 -From: Gerald Schaefer -Date: Mon, 6 Jul 2020 13:30:40 +0200 -Subject: [PATCH] mon_tools: update udevadm location -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Modern distributions do not provide the symlink /sbin/udevadm any more. -Use /usr/bin/udevadm instead for the example init script / systemd units. -Note that those are meant for example purpose and would need to be adjusted -by distributions, so no extra effort is taken to determine the actual -location of udevadm. - -Signed-off-by: Gerald Schaefer -Signed-off-by: Jan Höppner ---- - etc/init.d/mon_statd | 2 +- - systemd/mon_fsstatd.service.in | 2 +- - systemd/mon_procd.service.in | 2 +- - 3 files changed, 3 insertions(+), 3 deletions(-) - -diff --git a/etc/init.d/mon_statd b/etc/init.d/mon_statd -index 90bd565..68f6d91 100755 ---- a/etc/init.d/mon_statd -+++ b/etc/init.d/mon_statd -@@ -31,7 +31,7 @@ if [ -f $CONFIG_FILE ]; then - . $CONFIG_FILE - fi - --UDEVSETTLE=/sbin/udevadm -+UDEVSETTLE=/usr/bin/udevadm - if [ ! -e $UDEVSETTLE ] - then - UDEVSETTLE=/sbin/udevsettle -diff --git a/systemd/mon_fsstatd.service.in b/systemd/mon_fsstatd.service.in -index 8620d3b..cdba480 100644 ---- a/systemd/mon_fsstatd.service.in -+++ b/systemd/mon_fsstatd.service.in -@@ -29,7 +29,7 @@ EnvironmentFile=@sysconf_path@/sysconfig/mon_fsstatd - #Environment=FSSTAT_INTERVAL=30 - - ExecStartPre=-/sbin/modprobe monwriter --ExecStartPre=/sbin/udevadm settle --timeout=10 -+ExecStartPre=/usr/bin/udevadm settle --timeout=10 - ExecStart=@usrsbin_path@/mon_fsstatd -i $FSSTAT_INTERVAL - ExecReload=/bin/kill -HUP $MAINPID - KillMode=process -diff --git a/systemd/mon_procd.service.in b/systemd/mon_procd.service.in -index 512e584..1c5b3f4 100644 ---- a/systemd/mon_procd.service.in -+++ b/systemd/mon_procd.service.in -@@ -29,7 +29,7 @@ EnvironmentFile=@sysconf_path@/sysconfig/mon_procd - #Environment=PROC_INTERVAL=30 - - ExecStartPre=-/sbin/modprobe monwriter --ExecStartPre=/sbin/udevadm settle --timeout=10 -+ExecStartPre=/usr/bin/udevadm settle --timeout=10 - ExecStart=@usrsbin_path@/mon_procd -i $PROC_INTERVAL - ExecReload=/bin/kill -HUP $MAINPID - KillMode=process --- -2.26.2 - diff --git a/s390-tools-sles15sp2-vmcp-exit-code.patch b/s390-tools-sles15sp2-vmcp-exit-code.patch deleted file mode 100644 index e24ed8e..0000000 --- a/s390-tools-sles15sp2-vmcp-exit-code.patch +++ /dev/null @@ -1,73 +0,0 @@ -Subject: [PATCH] [BZ 186342] vmcp: Change sequence of failed exit -From: Thomas Richter - -Description: vmcp: Change sequence of failed exit -Symptom: VMCP command fails to execute commands with a very large - response on a very memory constraint system. A kernel log - message appears in the kernel log file: - 2020-05-29T10:57:16.543860-05:00 xdrf1 kernel: cma: - cma_alloc: alloc failed, req-size: 8 pages, ret: -16 - The vmcp command fails and indicates this in the exit code. - -Problem: When vmcp fails to execute a CP command with both error - conditions - - response buffer is too small - - CP command failed - then the vmcp program exits with 'response buffer too small' - indication. However, an exit code indicating - 'CP command failed' would be more important in this case. - So change the vmcp exit code and return 'CP command failed' - for above error scenario. - -Solution: Change the vmcp exit code and return 'CP command failed' - when both error conditions are true. -Reproduction: Issue vmcp varyoff command on system with low memory and - many DASD devices. -Upstream-ID: 53b949926f1bf0c6070650aae5f474e8df5378df -Problem-ID: 186342 - -Upstream-Description: - - vmcp: Change sequence of failed exit - - When vmcp fails to execute a CP command with both error conditions - - response buffer is too small - - CP command failed - then the vmcp program exits with 'response buffer too small' indication. - However, an exit code indicating 'CP command failed' would be more - important in this case. - So change the vmcp exit code and return 'CP command failed' for above - error scenario. - - Signed-off-by: Thomas Richter - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Thomas Richter ---- - vmcp/vmcp.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - ---- a/vmcp/vmcp.c -+++ b/vmcp/vmcp.c -@@ -235,15 +235,15 @@ int main(int argc, char **argv) - write_buffer(STDOUT_FILENO, cp.response, - MIN(cp.response_size, cp.buffer_size)); - free(cp.response); -- if (ret == VMCP_ERR_TOOSMALL) { -- fprintf(stderr, "Error: output (%d bytes) was truncated, try " -- "--buffer to increase size\n", cp.response_size); -- return VMCP_BUF; -- } - if (cp.cprc > 0) { - fprintf(stderr, "Error: non-zero CP response for command '%s': " - "#%d\n", command, cp.cprc); - return VMCP_CP; - } -+ if (ret == VMCP_ERR_TOOSMALL) { -+ fprintf(stderr, "Error: output (%d bytes) was truncated, try " -+ "--buffer to increase size\n", cp.response_size); -+ return VMCP_BUF; -+ } - return EXIT_SUCCESS; - } diff --git a/s390-tools-sles15sp2-zcrypt-CEX7S-exploitation-support.patch b/s390-tools-sles15sp2-zcrypt-CEX7S-exploitation-support.patch deleted file mode 100644 index 7c1bcea..0000000 --- a/s390-tools-sles15sp2-zcrypt-CEX7S-exploitation-support.patch +++ /dev/null @@ -1,131 +0,0 @@ -Subject: zcrypt: CEX7S exploitation support -From: Harald Freudenberger - -Summary: s390-tools: CEX7S exploitation support -Description: CEX7S exploitation support to lszcrypt, chzcrypt - and zcryptstats. -Upstream-ID: 4fc0c3cfefb8fb23a83ef629ac3f4a967fc0e77f -Problem-ID: SEC1808 - -Upstream-Description: - - zcrypt: CEX7S exploitation support - - This patch adds CEX7S exploitation support to lszcrypt and chzcrypt. - - Signed-off-by: Harald Freudenberger - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Harald Freudenberger ---- - zconf/zcrypt/chzcrypt.8 | 4 ++-- - zconf/zcrypt/chzcrypt.c | 4 ++-- - zconf/zcrypt/lszcrypt.8 | 8 ++++---- - zconf/zcrypt/lszcrypt.c | 11 ++++++----- - 4 files changed, 14 insertions(+), 13 deletions(-) - ---- a/zconf/zcrypt/chzcrypt.8 -+++ b/zconf/zcrypt/chzcrypt.8 -@@ -1,8 +1,8 @@ --.\" Copyright 2017 IBM Corp. -+.\" Copyright 2019 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 2017" "s390-tools" -+.TH CHZCRYPT 8 "AUG 2019" "s390-tools" - .SH NAME - chzcrypt \- modify zcrypt configuration - .SH SYNOPSIS ---- a/zconf/zcrypt/chzcrypt.c -+++ b/zconf/zcrypt/chzcrypt.c -@@ -1,7 +1,7 @@ - /* - * chzcrypt - Tool to modify zcrypt configuration - * -- * Copyright IBM Corp. 2008, 2017 -+ * Copyright IBM Corp. 2008, 2019 - * - * s390-tools is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See LICENSE for details. -@@ -47,7 +47,7 @@ const struct util_prg prg = { - { - .owner = "IBM Corp.", - .pub_first = 2008, -- .pub_last = 2017, -+ .pub_last = 2019, - }, - UTIL_PRG_COPYRIGHT_END - } ---- a/zconf/zcrypt/lszcrypt.8 -+++ b/zconf/zcrypt/lszcrypt.8 -@@ -1,6 +1,6 @@ - .\" lszcrypt.8 - .\" --.\" Copyright 2017 IBM Corp. -+.\" Copyright 2019 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. - .\" -@@ -10,7 +10,7 @@ - .\" nroff -man lszcrypt.8 - .\" to process this source - .\" --.TH LSZCRYPT 8 "JAN 2019" "s390-tools" -+.TH LSZCRYPT 8 "AUG 2019" "s390-tools" - .SH NAME - lszcrypt \- display zcrypt device and configuration information - .SH SYNOPSIS -@@ -118,7 +118,7 @@ explanation: - .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 and 12=CEX6. -+are 7=CEX3C, 8=CEX3A, 10=CEX4, 11=CEX5, 12=CEX6 and 13=CEX7. - .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 -@@ -167,7 +167,7 @@ operations within the guests. - .B DRIVER - .br - Shows which card or queue device driver currently handles this crypto --resource. Currently known drivers are cex4card/cex4queue (CEX4-CEX6 -+resource. Currently known drivers are cex4card/cex4queue (CEX4-CEX7 - 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 ---- 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, 2018 -+ * Copyright IBM Corp. 2008, 2019 - * - * s390-tools is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See LICENSE for details. -@@ -86,7 +86,7 @@ const struct util_prg prg = { - { - .owner = "IBM Corp.", - .pub_first = 2008, -- .pub_last = 2018, -+ .pub_last = 2019, - }, - UTIL_PRG_COPYRIGHT_END - } -@@ -302,9 +302,10 @@ static void show_capability(const char * - printf("%s\n", CAP_CCA); - printf("%s", CAP_RNG); - break; -- case 10: -- case 11: -- case 12: -+ case 10: /* CEX4S */ -+ case 11: /* CEX5S */ -+ case 12: /* CEX6S */ -+ case 13: /* CEX7S */ - if (func_val & MASK_ACCEL) { - if (func_val & MASK_RSA4K) - printf("%s", CAP_RSA4K); diff --git a/s390-tools-sles15sp2-zcryptstats-Add-support-for-CEX7.patch b/s390-tools-sles15sp2-zcryptstats-Add-support-for-CEX7.patch deleted file mode 100644 index dcd75c8..0000000 --- a/s390-tools-sles15sp2-zcryptstats-Add-support-for-CEX7.patch +++ /dev/null @@ -1,78 +0,0 @@ -Subject: zcryptstats: Add support for CEX7 -From: Harald Freudenberger - -Summary: s390-tools: CEX7S exploitation support -Description: CEX7S exploitation support to lszcrypt, chzcrypt - and zcryptstats. -Upstream-ID: e15e8a1bfa15e2179f30c6fe2e937ddd1a5e53c1 -Problem-ID: SEC1808 - -Upstream-Description: - - zcryptstats: Add support for CEX7 - - Add the CEX7 crypto card to the list of known crypto cards. - - Signed-off-by: Ingo Franzki - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Harald Freudenberger ---- - zconf/zcrypt/zcryptstats.c | 23 +++++++++++++---------- - 1 file changed, 13 insertions(+), 10 deletions(-) - ---- a/zconf/zcrypt/zcryptstats.c -+++ b/zconf/zcrypt/zcryptstats.c -@@ -147,8 +147,9 @@ struct chsc_cmb_area { - #define CRYPTO_TYPE_CEX4S 10 - #define CRYPTO_TYPE_CEX5S 11 - #define CRYPTO_TYPE_CEX6S 12 -+#define CRYPTO_TYPE_CEX7S 13 - --#define CRYPTO_TYPE_TOLERATION CRYPTO_TYPE_CEX6S -+#define CRYPTO_TYPE_TOLERATION CRYPTO_TYPE_CEX7S - - struct crypto_counter { - const char *name; -@@ -235,8 +236,8 @@ const struct crypto_mode mode_pcica[1] = - .counters = counter_pcica }, - }; - --#define NUM_CEX456_MODES 11 --const struct crypto_mode mode_cex456[NUM_CEX456_MODES] = { -+#define NUM_CEX4567_MODES 11 -+const struct crypto_mode mode_cex4567[NUM_CEX4567_MODES] = { - { 0 }, - { 0 }, - { 0 }, -@@ -256,7 +257,7 @@ const struct crypto_mode mode_cex456[NUM - .counters = counter_ep11 }, - }; - --#define NUM_CRYPTO_TYPES 13 -+#define NUM_CRYPTO_TYPES 14 - const struct crypto_type crypto_types[NUM_CRYPTO_TYPES] = { - { 0 }, - { 0 }, -@@ -275,12 +276,14 @@ const struct crypto_type crypto_types[NU - .modes = mode_accel }, - { .name = "CEX3C", .num_modes = NUM_COPROC_MODES, - .modes = mode_coproc }, -- { .name = "CEX4", .num_modes = NUM_CEX456_MODES, -- .modes = mode_cex456 }, -- { .name = "CEX5", .num_modes = NUM_CEX456_MODES, -- .modes = mode_cex456 }, -- { .name = "CEX6", .num_modes = NUM_CEX456_MODES, -- .modes = mode_cex456 }, -+ { .name = "CEX4", .num_modes = NUM_CEX4567_MODES, -+ .modes = mode_cex4567 }, -+ { .name = "CEX5", .num_modes = NUM_CEX4567_MODES, -+ .modes = mode_cex4567 }, -+ { .name = "CEX6", .num_modes = NUM_CEX4567_MODES, -+ .modes = mode_cex4567 }, -+ { .name = "CEX7", .num_modes = NUM_CEX4567_MODES, -+ .modes = mode_cex4567 }, - }; - - diff --git a/s390-tools-sles15sp2-zipl-check-for-valid-ipl-parmblock-lowcore-pointer.patch b/s390-tools-sles15sp2-zipl-check-for-valid-ipl-parmblock-lowcore-pointer.patch deleted file mode 100644 index 6abb67b..0000000 --- a/s390-tools-sles15sp2-zipl-check-for-valid-ipl-parmblock-lowcore-pointer.patch +++ /dev/null @@ -1,81 +0,0 @@ -Subject: [PATCH] [BZ 186938] zipl: check for valid ipl parmblock lowcore pointer -From: Stefan Haberland - -Description: zipl: check for valid ipl parmblock lowcore pointer -Symptom: For CCW type IPL the IPL might fail. -Problem: The lowcore parmblock pointer is not valid in every - case. For example it is invalid for CCW type IPL. -Solution: To have an indication if the pointer is valid do a - diag308 to store the parmblock and check if secure boot - is enabled. If it is enabled the lowcore pointer is - valid and the ipl report that is needed for secure boot - can be found right behind the ipl parmblock. -Reproduction: IPL from CCW devices. -Upstream-ID: ee9d606f800741eedeec1dcf1d2ddbfccbc21140 -Problem-ID: 186938 - -Signed-off-by: Stefan Haberland ---- - include/boot/ipl.h | 1 + - zipl/boot/stage3.c | 24 ++++++++++++++++++++---- - 2 files changed, 21 insertions(+), 4 deletions(-) - ---- a/include/boot/ipl.h -+++ b/include/boot/ipl.h -@@ -18,6 +18,7 @@ - #define IPL_RB_COMPONENT_FLAG_SIGNED 0x80 - #define IPL_RB_COMPONENT_FLAG_VERIFIED 0x40 - -+#define IPL_MAX_SUPPORTED_VERSION 0 - #define IPL_PARM_BLOCK_VERSION 0x1 - - /* IPL Types */ ---- a/zipl/boot/stage3.c -+++ b/zipl/boot/stage3.c -@@ -26,6 +26,7 @@ - - static const char *msg_sipl_inval = "Secure boot failure: invalid load address"; - static const char *msg_sipl_unverified = "Secure boot failure: unverified load address"; -+static const char *msg_sipl_noparm = "Secure boot failure: unable to load ipl parameter"; - - static inline void __noreturn start_kernel(void) - { -@@ -54,6 +55,18 @@ static inline void __noreturn start_kern - while (1); - } - -+unsigned int store_ipl_parmblock(struct ipl_pl_hdr *pl_hdr) -+{ -+ int rc; -+ -+ rc = diag308(DIAG308_STORE, pl_hdr); -+ if (rc == DIAG308_RC_OK && -+ pl_hdr->version <= IPL_MAX_SUPPORTED_VERSION) -+ return 0; -+ -+ return 1; -+} -+ - unsigned int - is_verified_address(unsigned long image_addr) - { -@@ -104,12 +117,15 @@ unsigned int - secure_boot_enabled() - { - struct ipl_pl_hdr *pl_hdr; -- unsigned long tmp; -+ unsigned int rc; - -- tmp = (unsigned long) S390_lowcore.ipl_parmblock_ptr; -- pl_hdr = (struct ipl_pl_hdr *) tmp; -+ pl_hdr = (void *)get_zeroed_page(); -+ if (!pl_hdr || store_ipl_parmblock(pl_hdr)) -+ panic(ESECUREBOOT, "%s", msg_sipl_noparm); -+ rc = !!(pl_hdr->flags & IPL_FLAG_SECURE); -+ free_page((unsigned long) pl_hdr); - -- return pl_hdr->flags & IPL_FLAG_SECURE; -+ return rc; - } - - void start(void) diff --git a/s390-tools-sles15sp2-zipl-prevent-endless-loop-during-IPL.patch b/s390-tools-sles15sp2-zipl-prevent-endless-loop-during-IPL.patch deleted file mode 100644 index 5046ef3..0000000 --- a/s390-tools-sles15sp2-zipl-prevent-endless-loop-during-IPL.patch +++ /dev/null @@ -1,33 +0,0 @@ -Subject: [PATCH] [BZ 186939] zipl: prevent endless loop during secure IPL -From: Stefan Haberland - -Description: zipl: prevent endless loop during secure IPL -Symptom: During IPL with secure boot enabled the loader may loop - infinitely. -Problem: In case secure boot is enabled but no components in the - IPL report are found it ends up in an endless loop in - the component verification. -Solution: To prevent this check if components are found and exit - if not. -Reproduction: IPL with secure boot enabled. -Upstream-ID: d5a88c1e56852881e8b0bb4056ffaa25bea818c5 -Problem-ID: 186939 - -Signed-off-by: Stefan Haberland ---- - zipl/boot/stage3.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/zipl/boot/stage3.c -+++ b/zipl/boot/stage3.c -@@ -104,6 +104,10 @@ is_verified_address(unsigned long image_ - - rb_hdr = (void *) rb_hdr + rb_hdr->len; - } -+ -+ if (!comps) -+ return 0; -+ - for_each_rb_entry(comp, comps) { - if (image_addr == comp->addr && - comp->flags & IPL_RB_COMPONENT_FLAG_SIGNED && diff --git a/s390-tools-sles15sp2-zkey-Fix-display-of-XTS-attribute-for-validate-comma.patch b/s390-tools-sles15sp2-zkey-Fix-display-of-XTS-attribute-for-validate-comma.patch deleted file mode 100644 index c825b87..0000000 --- a/s390-tools-sles15sp2-zkey-Fix-display-of-XTS-attribute-for-validate-comma.patch +++ /dev/null @@ -1,54 +0,0 @@ -Subject: [PATCH] [BZ 183669] zkey: Fix display of XTS attribute for validate command -From: Ingo Franzki - -Description: zkey: Fix display of XTS attribute for validate command -Symptom: The 'zkey validate' command shows an invalid value for - the XTS attribute. -Problem: Due to a use after free of the secure key, the XTS attribute - is not determined correctly, and is displayed incorrectly. - Function is_xts_key() is called with a secure key that has - already been freed and thus most likely returns false. - This bug has been introduced with feature SEC1717 "Cipher - key support" with commit 298fab68fee8 "zkey: Preparations for - introducing a new key type" -Solution: Free the secure key only after the last use. -Reproduction: Generate an XTS key of type CCA-AESDATA or CCA-AESCIPHER - and then run 'zkey validate'. -Upstream-ID: f75f4aff8f6e4ae148bde858ee1cb7f1066f5f23 -Problem-ID: 183669 - -Signed-off-by: Ingo Franzki ---- - zkey/keystore.c | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - ---- a/zkey/keystore.c -+++ b/zkey/keystore.c -@@ -2516,7 +2516,7 @@ static int _keystore_process_validate(st - size_t clear_key_bitsize; - size_t secure_key_size; - char *apqns = NULL; -- u8 *secure_key; -+ u8 *secure_key = NULL; - int is_old_mk; - int rc, valid; - u64 mkvp; -@@ -2550,8 +2550,7 @@ static int _keystore_process_validate(st - - rc = get_master_key_verification_pattern(secure_key, secure_key_size, - &mkvp, keystore->verbose); -- free(secure_key); -- if (rc) -+ if (rc != 0) - goto out; - - _keystore_print_record(info->rec, name, properties, 1, -@@ -2577,6 +2576,8 @@ static int _keystore_process_validate(st - info->num_warnings++; - - out: -+ if (secure_key != NULL) -+ free(secure_key); - if (apqns != NULL) - free(apqns); - if (apqn_list != NULL) diff --git a/s390-tools-sles15sp2-zkey-Fix-display-of-clear-key-size-for-CCA-AESCIPHER.patch b/s390-tools-sles15sp2-zkey-Fix-display-of-clear-key-size-for-CCA-AESCIPHER.patch deleted file mode 100644 index 80714c5..0000000 --- a/s390-tools-sles15sp2-zkey-Fix-display-of-clear-key-size-for-CCA-AESCIPHER.patch +++ /dev/null @@ -1,48 +0,0 @@ -Subject: [PATCH] [BZ 183875] zkey: Fix display of clear key size for CCA-AESCIPHER keys -From: Ingo Franzki - -Description: zkey: Fix display of clear key size for CCA-AESCIPHER keys -Symptom: The 'zkey list' command shows bogus values for the - keys 'Clear key size' for keys of type CCA-AESCIPHER. -Problem: Secure keys of type CCA-AESCIPHER are variable length, - dependent on the effective key size (e.g. 128, 192, or 256 - bits). However, the key blob stored is padded to a fixed - length, so that all key blobs of type CCA-AESCIPHER are - the same size, regardless of the effective key bit size. - To code to display the clear key bitsize does not correctly - handle the padding and may treat a non-XTS key like an XTS - key and thus reads past the end of the key blob. This - results in bogus values reported as clear key size. - This bug has been introduced with feature SEC1717 "Cipher - key support" with commit ddde3f354f35 ("zkey: Introduce th - CCA-AESCIPHER key type"). -Solution: Correct the handling of key of type CCA-AESCIPHER. -Reproduction: Generate a key of type CCA-AESCIPHER and then run - 'zkey list'. -Upstream-ID: 49cbaba302f002aa7f148631a76fc21a3069bc25 -Problem-ID: 183875 - -Upstream-Description: - - zkey: Fix display of clear key size for CCA-AESCIPHER keys - - Fixes: ddde3f354f35 ("zkey: Introduce the CCA-AESCIPHER key type") - Signed-off-by: Ingo Franzki - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- a/zkey/pkey.c -+++ b/zkey/pkey.c -@@ -1600,9 +1600,9 @@ int get_key_bit_size(const u8 *key, size - *bitsize = cipherkey->pl - 384; - else - *bitsize = 0; /* Unknown */ -- if (key_size > cipherkey->length) { -+ if (key_size == 2 * AESCIPHER_KEY_SIZE) { - cipherkey = (struct aescipherkeytoken *)(key + -- cipherkey->length); -+ AESCIPHER_KEY_SIZE); - if (cipherkey->pfv == 0x00) /* V0 payload */ - *bitsize += cipherkey->pl - 384; - } diff --git a/s390-tools-sles15sp2-zkey-Fix-display-of-clear-key-size-for-XTS-keys.patch b/s390-tools-sles15sp2-zkey-Fix-display-of-clear-key-size-for-XTS-keys.patch deleted file mode 100644 index 8d298f4..0000000 --- a/s390-tools-sles15sp2-zkey-Fix-display-of-clear-key-size-for-XTS-keys.patch +++ /dev/null @@ -1,60 +0,0 @@ -Subject: [PATCH] [BZ 183401] zkey: Fix display of clear key size for XTS keys -From: Ingo Franzki - -Description: zkey: Fix display of clear key size for XTS keys -Symptom: The 'zkey list' command shows bogus values for the - keys 'Clear key size' for XTS keys of type CCA-AESDATA - or CCA-AESCIPHER. -Problem: XTS keys consist of 2 keys concatenated to each other. - To calculate the clear key size, the clear key size of - both keys must be added. The code does not address the - second key correctly, and thus reads the clear key size - of the second key from an invalid memory location. This - results in bogus values reported as clear key size. - This bug has been introduced with feature SEC1717 "Cipher - key support" with commit 298fab68fee8 "zkey: Preparations - for introducing a new key type". -Solution: Correct the addressing of the second key. -Reproduction: Generate an XTS key of type CCA-AESDATA or CCA-AESCIPHER - and then run 'zkey list'. -Upstream-ID: e7f446432b92b293e758099842843cfb1f18fa97 -Problem-ID: 183401 - -Upstream-Description: - - zkey: Fix display of clear key size for XTS keys - - Fixes: 298fab68fee8 ("zkey: Preparations for introducing a new key type") - Signed-off-by: Ingo Franzki - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/pkey.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - ---- a/zkey/pkey.c -+++ b/zkey/pkey.c -@@ -1591,8 +1591,8 @@ int get_key_bit_size(const u8 *key, size - if (is_cca_aes_data_key(key, key_size)) { - *bitsize = datakey->bitsize; - if (key_size == 2 * AESDATA_KEY_SIZE) { -- datakey = (struct aesdatakeytoken *)key + -- AESDATA_KEY_SIZE; -+ datakey = (struct aesdatakeytoken *)(key + -+ AESDATA_KEY_SIZE); - *bitsize += datakey->bitsize; - } - } else if (is_cca_aes_cipher_key(key, key_size)) { -@@ -1601,8 +1601,8 @@ int get_key_bit_size(const u8 *key, size - else - *bitsize = 0; /* Unknown */ - if (key_size > cipherkey->length) { -- cipherkey = (struct aescipherkeytoken *)key + -- cipherkey->length; -+ cipherkey = (struct aescipherkeytoken *)(key + -+ cipherkey->length); - if (cipherkey->pfv == 0x00) /* V0 payload */ - *bitsize += cipherkey->pl - 384; - } diff --git a/s390-tools-sles15sp2-zkey-Fix-listing-of-keys-on-file-systems-reporting-D.patch b/s390-tools-sles15sp2-zkey-Fix-listing-of-keys-on-file-systems-reporting-D.patch deleted file mode 100644 index 76ce461..0000000 --- a/s390-tools-sles15sp2-zkey-Fix-listing-of-keys-on-file-systems-reporting-D.patch +++ /dev/null @@ -1,62 +0,0 @@ -Subject: [PATCH] [BZ 183125] zkey: Fix listing of keys on file systems reporting DT_UNKNOWN. -From: Ingo Franzki - -Description: zkey: Fix listing of keys on file systems reporting DT_UNKNOWN. -Symptom: When the zkey key repository is located in a file system that - does not have full support for report the file type, such as - XFS, the 'zkey list' command does not show any keys, although - keys exist in the repository. -Problem: The zkey list function uses scandir() to look for files in the - zkey key repository directory. It checks the dirent.d_type field - to consider only regular files, but skips all others. File - systems that do not have full support for returning the file - type in d_type will return DT_UNKNOWN instead. zkey skips - those directory entries and thus does not show any keys. -Solution: Also consider directory entries with d_type = DT_UNKNOWN. -Reproduction: Use zkey with a zkey repository directory located in a file - system that does not have full support for returning the file - type, such as XFS. Generate a key in the repository and then - list the key s with 'zkey list'. - Note: Newly created XFS file systems usually support returning - the file type, but existing XFS file systems might not. To - create an XFS file system that does not support returning the - file type, use 'mkfs.xfs -f -m crc=0 -n ftype=0' to create - the file system. -Upstream-ID: 0de533aef9def920fed751c6025e4f19c4cba763~ -Problem-ID: 183125 - -Upstream-Description: - - zkey: Fix listing of keys on file systems reporting DT_UNKNOWN - - The zkey list function uses scandir() to look for files in the - zkey key repository directory. It checks the dirent.d_type field - to consider only regular files, but skip all others. - - Unfortunately, not all file systems have full support for returning - the file type in d_type. When the zkey repository is located in a file - system that does not support d_type, such as xfs, zkey list shows no - keys, although the key repository contains keys. - - Fix this by also considering directory entries with d_type = DT_UNKNOWN. - - Signed-off-by: Ingo Franzki - Signed-off-by: Jan Hoeppner - - -Signed-off-by: Ingo Franzki ---- - zkey/keystore.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/zkey/keystore.c -+++ b/zkey/keystore.c -@@ -906,7 +906,7 @@ static int _keystore_info_file_filter(co - { - size_t len; - -- if (dirent->d_type != DT_REG) -+ if (dirent->d_type != DT_REG && dirent->d_type != DT_UNKNOWN) - return 0; - - len = strlen(dirent->d_name); diff --git a/s390-tools-sles15sp2-znetconf-introduce-better-ways-to-locate-udevadm.patch b/s390-tools-sles15sp2-znetconf-introduce-better-ways-to-locate-udevadm.patch deleted file mode 100644 index 1247c79..0000000 --- a/s390-tools-sles15sp2-znetconf-introduce-better-ways-to-locate-udevadm.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 1003d8141209fdbd50d02aec2cad4690aec48702 Mon Sep 17 00:00:00 2001 -From: Guevenc Guelce -Date: Wed, 8 Jul 2020 18:31:34 +0200 -Subject: [PATCH] znetconf: introduce better ways to locate udevadm -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -When udevadm is going to be used, try to locate it -in $PATH and if it fails, try to locate it in well-known -binary paths. - -Signed-off-by: Guevenc Guelce -Signed-off-by: Jan Höppner ---- - zconf/znetconf | 42 +++++++++++++++++++++++++++++++++--------- - 1 file changed, 33 insertions(+), 9 deletions(-) - -diff --git a/zconf/znetconf b/zconf/znetconf -index ba8dec4..497e97f 100755 ---- a/zconf/znetconf -+++ b/zconf/znetconf -@@ -63,14 +63,8 @@ CMD=$(basename $0) - LSZNET=/lib/s390-tools/lsznet.raw - LSZNET_ARGS=-a - LSZNET_CALL="$LSZNET $LSZNET_ARGS" --UDEVSETTLE=/sbin/udevadm --if [ ! -e $UDEVSETTLE ] --then -- UDEVSETTLE=/sbin/udevsettle -- UDEVSETTLE_CALL="$UDEVSETTLE --timeout=10" --else -- UDEVSETTLE_CALL="$UDEVSETTLE settle --timeout=10" --fi -+UDEVSETTLE=udevadm -+UDEVSETTLE_CALL="$UDEVSETTLE settle --timeout=10" - SYSFSDIR=$(cat /proc/mounts|awk '$3=="sysfs"{print $2; exit}') - CCWGROUPBUS_DIR=$SYSFSDIR/bus/ccwgroup - CCWDEV_DIR=$SYSFSDIR/bus/ccw/devices -@@ -261,6 +255,35 @@ function lookup_lan_layer() - - #============================================================================== - -+function prepare_udevsettle_cmd() -+{ -+ # is the command available in $PATH -+ if ! [ -x "$(command -v $UDEVSETTLE)" ] -+ then -+ # check the well known locations. -+ if [ -e "/sbin/udevadm" ] -+ then -+ UDEVSETTLE=/sbin/udevadm -+ UDEVSETTLE_CALL="$UDEVSETTLE settle --timeout=10" -+ elif [ -e "/usr/bin/udevadm" ] -+ then -+ UDEVSETTLE=/usr/bin/udevadm -+ UDEVSETTLE_CALL="$UDEVSETTLE settle --timeout=10" -+ elif [ -e "/sbin/udevsettle" ] -+ then -+ # Fallback to udevsettle -+ UDEVSETTLE=/sbin/udevsettle -+ UDEVSETTLE_CALL="$UDEVSETTLE --timeout=10" -+ else -+ UDEVSETTLE="" -+ UDEVSETTLE_CALL="" -+ echo "Failed to find any candidate for udevsettle" -+ fi -+ fi -+} -+ -+#============================================================================== -+ - function lookup_type_and_lan_or_vswitch_name() - { - local DEVNO="$1" -@@ -506,8 +529,9 @@ function wait_for_net_device() - local CMD_FINDNETLINK="find $CCWGROUPBUS_DEVICEDIR/$CCWGROUPDEVNO/ -type l -name net*" - local LINKNAME="" - -+ prepare_udevsettle_cmd - # polling loop to wait for net device to become available -- if [ -e $UDEVSETTLE ] -+ if [ "$UDEVSETTLE" != "" ] - then - $UDEVSETTLE_CALL - fi --- -2.26.2 - diff --git a/s390-tools-sles15sp3-01-genprotimg-abort-if-one-of-the-recursive-targets-is-.patch b/s390-tools-sles15sp3-01-genprotimg-abort-if-one-of-the-recursive-targets-is-.patch new file mode 100644 index 0000000..0f690cb --- /dev/null +++ b/s390-tools-sles15sp3-01-genprotimg-abort-if-one-of-the-recursive-targets-is-.patch @@ -0,0 +1,38 @@ +Subject: [PATCH] [FEAT VS2010] genprotimg: abort if one of the recursive targets is failing +From: Marc Hartmayer + +Summary: genprotimg: add host-key document verification +Description: Add host-key document verification support to genprotimg. This + ensures that a host-key document is genuine and provided by + IBM. For this the user must provide the IBM Z signing key, the + intermediate CA certificate (signed by the root CA used) so a + chain of trust starting from the host-key document and ending in + the root CA can be established. +Upstream-ID: 6db7fbe0187042f44a63a5c7dbeb9f116909d02e +Problem-ID: VS2010 + +Upstream-Description: + + genprotimg: abort if one of the recursive targets is failing + + Abort compilation as soon as one of the recursive targets is failing. + + Fixes: 65b9fc442c1a ("genprotimg: introduce new tool for the creation of PV images") + Signed-off-by: Marc Hartmayer + Signed-off-by: Jan Hoeppner + + +Signed-off-by: Marc Hartmayer +Index: s390-tools-service/genprotimg/Makefile +=================================================================== +--- s390-tools-service.orig/genprotimg/Makefile ++++ s390-tools-service/genprotimg/Makefile +@@ -21,7 +21,7 @@ clean: clean-recursive + $(RECURSIVE_TARGETS): + @target=`echo $@ |sed s/-recursive//`; \ + for d in $(SUBDIRS); do \ +- $(MAKE) -C $$d $$target; \ ++ $(MAKE) -C $$d $$target || exit 1; \ + done + + .PHONY: all install clean $(RECURSIVE_TARGETS) diff --git a/s390-tools-sles15sp3-01-zdev-Add-FC-Endpoint-Security-information-for-DASD-d.patch b/s390-tools-sles15sp3-01-zdev-Add-FC-Endpoint-Security-information-for-DASD-d.patch new file mode 100644 index 0000000..4f57c10 --- /dev/null +++ b/s390-tools-sles15sp3-01-zdev-Add-FC-Endpoint-Security-information-for-DASD-d.patch @@ -0,0 +1,47 @@ +Subject: [PATCH] [FEAT IO1812] zdev/lsdasd: Add FC Endpoint Security information +From: Jan Hoeppner + +Summary: zdev/lsdasd: Add FC Endpoint Security information +Description: Provide the status of the FC Endpoint Security information via the + long output of lsdasd for online Base and Alias devices. +Upstream-ID: - +Problem-ID: IO1812 + +Signed-off-by: Jan Hoeppner +--- + zdev/src/dasd.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +--- a/zdev/src/dasd.c ++++ b/zdev/src/dasd.c +@@ -313,6 +313,22 @@ static struct attrib dasd_attr_safe_offl + .writeonly = 1, + }; + ++static struct attrib dasd_attr_fc_security = { ++ .name = "fc_security", ++ .title = "Show FC Endpoint Security state of DASD device", ++ .desc = ++ "This read-only attribute shows the Fibre Channel Endpoint Security\n" ++ "status of the connection to the DASD device:\n" ++ " Unsupported : The DASD device does not support Fibre Channel\n" ++ " Endpoint Security\n" ++ " Inconsistent : The operational channel paths of the DASD device\n" ++ " report inconsistent Fibre Channel Endpoint\n" ++ " Security status\n" ++ " Authentication: The connection has been authenticated\n" ++ " Encryption : The connection is encrypted\n", ++ .readonly = 1, ++}; ++ + /* + * DASD subtype methods. + */ +@@ -617,6 +633,7 @@ struct subtype dasd_subtype_eckd = { + &dasd_attr_reservation_policy, + &dasd_attr_last_known_reservation_state, + &dasd_attr_safe_offline, ++ &dasd_attr_fc_security, + &internal_attr_early, + ), + .unknown_dev_attribs = 1, diff --git a/s390-tools-sles15sp3-02-genprotimg-fix-two-memory-leaks.patch b/s390-tools-sles15sp3-02-genprotimg-fix-two-memory-leaks.patch new file mode 100644 index 0000000..170b42b --- /dev/null +++ b/s390-tools-sles15sp3-02-genprotimg-fix-two-memory-leaks.patch @@ -0,0 +1,56 @@ +Subject: [PATCH] [FEAT VS2010] genprotimg: fix two memory leaks +From: Marc Hartmayer + +Summary: genprotimg: add host-key document verification +Description: Add host-key document verification support to genprotimg. This + ensures that a host-key document is genuine and provided by + IBM. For this the user must provide the IBM Z signing key, the + intermediate CA certificate (signed by the root CA used) so a + chain of trust starting from the host-key document and ending in + the root CA can be established. +Upstream-ID: db6f272607842a6279fee589fb101f3a1f6148f3 +Problem-ID: VS2010 + +Upstream-Description: + + genprotimg: fix two memory leaks + + ==1005844== HEAP SUMMARY: + ==1005844== in use at exit: 18,907 bytes in 14 blocks + ==1005844== total heap usage: 82 allocs, 68 frees, 32,529 bytes allocated + ==1005844== + ==1005844== 136 (104 direct, 32 indirect) bytes in 1 blocks are definitely lost in loss record 12 of 14 + ==1005844== at 0x483885A: calloc (vg_replace_malloc.c:760) + ==1005844== by 0x48C950D: g_malloc0 (gmem.c:132) + ==1005844== by 0x100EC41: pv_args_new (pv_args.c:364) + ==1005844== by 0x100587F: main (genprotimg.c:122) + ==1005844== + ==1005844== LEAK SUMMARY: + ==1005844== definitely lost: 104 bytes in 1 blocks + ==1005844== indirectly lost: 32 bytes in 1 blocks + ==1005844== possibly lost: 0 bytes in 0 blocks + ==1005844== still reachable: 18,771 bytes in 12 blocks + ==1005844== suppressed: 0 bytes in 0 blocks + ==1005844== Reachable blocks (those to which a pointer was found) are not shown. + ==1005844== To see them, rerun with: --leak-check=full --show-leak-kinds=all + ==1005844== + ==1005844== For lists of detected and suppressed errors, rerun with: -s + ==1005844== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) + + Signed-off-by: Marc Hartmayer + Signed-off-by: Jan Hoeppner + + +Signed-off-by: Marc Hartmayer +Index: s390-tools-service/genprotimg/src/genprotimg.c +=================================================================== +--- s390-tools-service.orig/genprotimg/src/genprotimg.c ++++ s390-tools-service/genprotimg/src/genprotimg.c +@@ -177,5 +177,7 @@ error: + rmdir_recursive(tmp_dir, NULL); + remove_signal_handler(signals, G_N_ELEMENTS(signals)); + g_free(tmp_dir); ++ g_clear_pointer(&img, pv_img_free); ++ g_clear_pointer(&args, pv_args_free); + exit(ret); + } diff --git a/s390-tools-sles15sp3-02-lsdasd-Add-FC-Endpoint-Security-information.patch b/s390-tools-sles15sp3-02-lsdasd-Add-FC-Endpoint-Security-information.patch new file mode 100644 index 0000000..573c66f --- /dev/null +++ b/s390-tools-sles15sp3-02-lsdasd-Add-FC-Endpoint-Security-information.patch @@ -0,0 +1,58 @@ +Subject: [PATCH] [FEAT IO1812] zdev/lsdasd: Add FC Endpoint Security information +From: Jan Hoeppner + +Summary: zdev/lsdasd: Add FC Endpoint Security information +Description: Provide the status of the FC Endpoint Security information via the + long output of lsdasd for online Base and Alias devices. +Upstream-ID: - +Problem-ID: IO1812 + +Signed-off-by: Jan Hoeppner +--- + zconf/lsdasd | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/zconf/lsdasd ++++ b/zconf/lsdasd +@@ -387,6 +387,7 @@ function extended() + read EXTSZ 2> /dev/null < $DEVPATH/extent_pool/extent_size + read CAPACITY 2> /dev/null < $DEVPATH/capacity/logical_capacity + read ALLOCATED 2> /dev/null < $DEVPATH/capacity/space_allocated ++ read FC_SEC 2> /dev/null < $DEVPATH/fc_security + + # convert to hexadecimal values + PIM=0x$PIM +@@ -521,7 +522,7 @@ function extended() + elif [[ "$ALIAS" == 1 ]]; then + if [[ "$BASEONLY" == "false" ]]; then + ACTIVE="alias" +- printf "%s:%s:%s# status:\t\t\t\t%s# type: \t\t\t\t%s# use_diag:\t\t\t\t%s# readonly:\t\t\t\t%s# eer_enabled:\t\t\t\t%s# erplog:\t\t\t\t%s# hpf:\t\t\t\t\t%s # uid: \t\t\t\t%s# paths_installed: \t\t\t%s %s %s %s %s %s %s %s# paths_in_use: \t\t\t%s %s %s %s %s %s %s %s# paths_non_preferred: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_cabling: \t\t%s %s %s %s %s %s %s %s# paths_cuir_quiesced: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_hpf_characteristics: \t%s %s %s %s %s %s %s %s# paths_error_threshold_exceeded: \t%s %s %s %s %s %s %s %s#\n" \ ++ printf "%s:%s:%s# status:\t\t\t\t%s# type: \t\t\t\t%s# use_diag:\t\t\t\t%s# readonly:\t\t\t\t%s# eer_enabled:\t\t\t\t%s# erplog:\t\t\t\t%s# hpf:\t\t\t\t\t%s # uid: \t\t\t\t%s# fc_security: \t\t\t\t%s# paths_installed: \t\t\t%s %s %s %s %s %s %s %s# paths_in_use: \t\t\t%s %s %s %s %s %s %s %s# paths_non_preferred: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_cabling: \t\t%s %s %s %s %s %s %s %s# paths_cuir_quiesced: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_hpf_characteristics: \t%s %s %s %s %s %s %s %s# paths_error_threshold_exceeded: \t%s %s %s %s %s %s %s %s#\n" \ + "$SORTKEYLEN" "$SORTKEY" \ + "$BUSID" \ + "$ACTIVE" \ +@@ -532,6 +533,7 @@ function extended() + "$ERP" \ + "$HPF" \ + "$DEV_UID" \ ++ "$FC_SEC" \ + "${INSTALLED_PATHS[@]}" \ + "${USED_PATHS[@]}" \ + "${NP_PATHS[@]}" \ +@@ -563,7 +565,7 @@ function extended() + DISCIPLINE="${DISCIPLINE} (ESE)" + fi + +- printf "%s:%s:%s/%s/%s%s%s# status:\t\t\t\t%s# type: \t\t\t\t%s# blksz:\t\t\t\t%s# size: \t\t\t\t%s# blocks:\t\t\t\t%s# extent_size:\t\t\t\t%s# logical_capacity:\t\t\t%s# space_allocated:\t\t\t%s# use_diag:\t\t\t\t%s# readonly:\t\t\t\t%s# eer_enabled:\t\t\t\t%s# erplog:\t\t\t\t%s# hpf:\t\t\t\t\t%s# uid: \t\t\t\t%s# paths_installed: \t\t\t%s %s %s %s %s %s %s %s# paths_in_use: \t\t\t%s %s %s %s %s %s %s %s# paths_non_preferred: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_cabling: \t\t%s %s %s %s %s %s %s %s# paths_cuir_quiesced: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_hpf_characteristics: \t%s %s %s %s %s %s %s %s# paths_error_threshold_exceeded: \t%s %s %s %s %s %s %s %s#\n" \ ++ printf "%s:%s:%s/%s/%s%s%s# status:\t\t\t\t%s# type: \t\t\t\t%s# blksz:\t\t\t\t%s# size: \t\t\t\t%s# blocks:\t\t\t\t%s# extent_size:\t\t\t\t%s# logical_capacity:\t\t\t%s# space_allocated:\t\t\t%s# use_diag:\t\t\t\t%s# readonly:\t\t\t\t%s# eer_enabled:\t\t\t\t%s# erplog:\t\t\t\t%s# hpf:\t\t\t\t\t%s# uid: \t\t\t\t%s# fc_security: \t\t\t\t%s# paths_installed: \t\t\t%s %s %s %s %s %s %s %s# paths_in_use: \t\t\t%s %s %s %s %s %s %s %s# paths_non_preferred: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_cabling: \t\t%s %s %s %s %s %s %s %s# paths_cuir_quiesced: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_hpf_characteristics: \t%s %s %s %s %s %s %s %s# paths_error_threshold_exceeded: \t%s %s %s %s %s %s %s %s#\n" \ + "$SORTKEYLEN" "$SORTKEY" \ + "$BUSID" \ + "$BLOCKNAME" \ +@@ -584,6 +586,7 @@ function extended() + "$ERP" \ + "$HPF" \ + "$DEV_UID" \ ++ "$FC_SEC" \ + "${INSTALLED_PATHS[@]}" \ + "${USED_PATHS[@]}" \ + "${NP_PATHS[@]}" \ diff --git a/s390-tools-sles15sp3-03-genprotimg-require-argument-for-ramdisk-and-parmfile.patch b/s390-tools-sles15sp3-03-genprotimg-require-argument-for-ramdisk-and-parmfile.patch new file mode 100644 index 0000000..e8d4cf7 --- /dev/null +++ b/s390-tools-sles15sp3-03-genprotimg-require-argument-for-ramdisk-and-parmfile.patch @@ -0,0 +1,49 @@ +Subject: [PATCH] [FEAT VS2010] genprotimg: require argument for 'ramdisk' and 'parmfile' options +From: Marc Hartmayer + +Summary: genprotimg: add host-key document verification +Description: Add host-key document verification support to genprotimg. This + ensures that a host-key document is genuine and provided by + IBM. For this the user must provide the IBM Z signing key, the + intermediate CA certificate (signed by the root CA used) so a + chain of trust starting from the host-key document and ending in + the root CA can be established. +Upstream-ID: 895a88b2f8d775e45ab1251f0b4bb275efd44a64 +Problem-ID: VS2010 + +Upstream-Description: + + genprotimg: require argument for 'ramdisk' and 'parmfile' options + + A argument is required for the optional options 'ramdisk' and + 'parmfile'. + + Fixes: 65b9fc442c1a ("genprotimg: introduce new tool for the creation of PV images") + Reviewed-by: Bjoern Walk + Signed-off-by: Marc Hartmayer + Signed-off-by: Jan Hoeppner + + +Signed-off-by: Marc Hartmayer +Index: s390-tools-service/genprotimg/src/pv/pv_args.c +=================================================================== +--- s390-tools-service.orig/genprotimg/src/pv/pv_args.c ++++ s390-tools-service/genprotimg/src/pv/pv_args.c +@@ -227,7 +227,7 @@ gint pv_args_parse_options(PvArgs *args, + .arg_description = _("IMAGE") }, + { .long_name = "ramdisk", + .short_name = 'r', +- .flags = G_OPTION_FLAG_OPTIONAL_ARG | G_OPTION_FLAG_FILENAME, ++ .flags = G_OPTION_FLAG_FILENAME, + .arg = G_OPTION_ARG_CALLBACK, + .arg_data = cb_add_component, + .description = _("Use RAMDISK as the initial RAM disk\n" INDENT +@@ -235,7 +235,7 @@ gint pv_args_parse_options(PvArgs *args, + .arg_description = _("RAMDISK") }, + { .long_name = "parmfile", + .short_name = 'p', +- .flags = G_OPTION_FLAG_OPTIONAL_ARG | G_OPTION_FLAG_FILENAME, ++ .flags = G_OPTION_FLAG_FILENAME, + .arg = G_OPTION_ARG_CALLBACK, + .arg_data = cb_add_component, + .description = _("Use the kernel parameters stored in PARMFILE\n" INDENT diff --git a/s390-tools-sles15sp3-04-genprotimg-add-host-key-document-verification-suppor.patch b/s390-tools-sles15sp3-04-genprotimg-add-host-key-document-verification-suppor.patch new file mode 100644 index 0000000..214ec21 --- /dev/null +++ b/s390-tools-sles15sp3-04-genprotimg-add-host-key-document-verification-suppor.patch @@ -0,0 +1,2410 @@ +Subject: [PATCH] [FEAT VS2010] genprotimg: add host-key document verification support +From: Marc Hartmayer + +Summary: genprotimg: add host-key document verification +Description: Add host-key document verification support to genprotimg. This + ensures that a host-key document is genuine and provided by + IBM. For this the user must provide the IBM Z signing key, the + intermediate CA certificate (signed by the root CA used) so a + chain of trust starting from the host-key document and ending in + the root CA can be established. +Upstream-ID: 074de1e14ed785c18f55ecf9762ac3f5de3465b4 +Problem-ID: VS2010 + +Upstream-Description: + + genprotimg: add host-key document verification support + + Add host-key document verification support to genprotimg. This ensures + that a host-key document is genuine and provided by IBM. For this the + user must provide the IBM Z signing key, the intermediate CA + certificate (signed by the root CA used) so a chain of trust starting + from the host-key document and ending in the root CA can be + established. + + By default, genprotimg tries to download all revocation lists needed + by looking up in the corresponding certificate on how CRL information + can be obtained (see https://tools.ietf.org/html/rfc5280#section-4.2.1.13 + for details). + + Acked-by: Patrick Steuer + Signed-off-by: Marc Hartmayer + Signed-off-by: Jan Hoeppner + + +Signed-off-by: Marc Hartmayer +Index: s390-tools-service/genprotimg/man/genprotimg.8 +=================================================================== +--- s390-tools-service.orig/genprotimg/man/genprotimg.8 ++++ s390-tools-service/genprotimg/man/genprotimg.8 +@@ -2,7 +2,7 @@ + .\" 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 GENPROTIMG 8 "March 2020" "s390-tools" ++.TH GENPROTIMG 8 "November 2020" "s390-tools" + .SH NAME + genprotimg \- Create a protected virtualization image + +@@ -10,6 +10,7 @@ genprotimg \- Create a protected virtual + .SY + .B genprotimg + \fB\-k\fR \fIHOST_KEY_DOCUMENT\fR... ++\fB\-C\fR \fICERTIFICATE\fR... + \fB\-i\fR \fIVMLINUZ\fR + [\fB\-r\fR \fIRAMDISK\fR] + [\fB\-p\fR \fIPARMFILE\fR] +@@ -21,15 +22,19 @@ genprotimg \- Create a protected virtual + .PP + Use \fBgenprotimg\fR to generate a single bootable image file with + encrypted and integrity-protected parts. The command requires a kernel +-image, a host-key document, and an output file name. Optionally, +-specify an initial RAM filesystem, and a file containing the kernel +-parameters. Should special circumstances require it, you can ++image, a host-key document, certificates for the host-key document ++verification, and an output file name. Optionally, specify an initial ++RAM filesystem, and a file containing the kernel parameters. If the ++command should be run offline, use the \fB\-\-offline\fR option and ++specify the certificate revocation lists (CRLs) by using the ++\fB\-\-crl\fR option. Should special circumstances require it, you can + optionally specify your own keys for the encryption by using the +-experimental options. In the resulting image file, a plain text boot +-loader, the encrypted components for kernel, initial RAM disk, kernel +-parameters, and the encrypted and integrity-protected header are +-concatenated. The header contains metadata necessary for running the +-guest in protected mode. ++experimental options. For all certificates, CRLs, and host-key ++documents, both the PEM and DER input formats are supported. In the ++resulting image file, a plain text boot loader, the encrypted ++components for kernel, initial RAM disk, kernel parameters, and the ++encrypted and integrity-protected header are concatenated. The header ++contains metadata necessary for running the guest in protected mode. + .PP + Use this image file as a kernel image for zipl or for a direct kernel + boot using QEMU. +@@ -53,6 +58,12 @@ Specifies a host-key document. At least + option multiple times to enable the image to run on more than one + host. + .TP ++\fB\-C\fR, \fB\-\-cert\fR=\fI\,FILE\/\fR ++Specifies the certificate that is used to establish a chain of trust ++for the verification of the host-key documents. Specify this option ++twice to specify the IBM Z signing key and the intermediate CA ++certificate (signed by the root CA). Required. ++.TP + \fB\-o\fR, \fB\-\-output\fR=\fI\,OUTPUT_FILE\/\fR + Specifies the output file. Required. + .TP +@@ -65,6 +76,20 @@ Specifies the RAM disk image. Optional. + \fB\-p\fR, \fB\-\-parmfile\fR=\fI\,PARMFILE\/\fR + Specifies the kernel command line stored in \fI\,PARMFILE\/\fR. Optional. + .TP ++\fB\-\-crl\fR=\fI\,FILE\/\fR ++Specifies the revocation list that is used to check whether a ++certificate of the chain of trust is revoked. Specify this option ++multiple times to use multiple CRLs. Optional. ++.TP ++\fB\-\-offline\fR ++Specifies offline mode, in which no attempt is made to download ++CRLs. Optional. ++.TP ++\fB\-\-root\-ca\fR=\fI\,FILE\/\fR ++Specifies the root CA certificate for the verification. If omitted, ++the DigiCert root CA certificate installed on the system is used. Use ++this only if you trust the specified certificate. Optional. ++.TP + \fB\-\-no-verify\fR + Do not require the host-key documents to be valid. For testing + purposes, do not use for a production image. Optional. +@@ -77,11 +102,13 @@ Prints version information, then exits. + Generate a protected virtualization image in + \fI\,/boot/vmlinuz.pv\/\fR, using the kernel file \fI\,vmlinuz\/\fR, + the initrd in \fI\,initramfs\/\fR, the kernel parameters contained in +-\fI\,parmfile\/\fR, and the host-key document in \fI\,host_key.crt\/\fR: ++\fI\,parmfile\/\fR, the intermediate CA in \fI\,DigiCertCA.crt\/\fR, ++the IBM Z signing key in \fI\,ibm-z-host-key-signing.crt\/\fR, and the ++host-key document in \fI\,host_key.crt\/\fR: + .PP + .Vb 1 + .EX +-\& genprotimg \-i \fI\,vmlinuz\/\fR \-r \fI\,initramfs\/\fR \-p \fI\,parmfile\/\fR \-k \fI\,host_key.crt\/\fR \-o \fI\,/boot/vmlinuz.pv\/\fR ++\& genprotimg \-i \fI\,vmlinuz\/\fR \-r \fI\,initramfs\/\fR \-p \fI\,parmfile\/\fR \-k \fI\,host_key.crt\/\fR \-C \fI\,ibm-z-host-key-signing.crt\/\fR \-C \fI\,DigiCertCA.crt \-o \fI\,/boot/vmlinuz.pv\/\fR + .EE + .Ve + .PP +Index: s390-tools-service/genprotimg/src/Makefile +=================================================================== +--- s390-tools-service.orig/genprotimg/src/Makefile ++++ s390-tools-service/genprotimg/src/Makefile +@@ -23,16 +23,16 @@ WARNINGS := -Wall -Wextra -Wshadow \ + $(bin_PROGRAM)_SRCS := $(bin_PROGRAM).c pv/pv_stage3.c pv/pv_image.c \ + pv/pv_comp.c pv/pv_hdr.c pv/pv_ipib.c utils/crypto.c utils/file_utils.c \ + pv/pv_args.c utils/buffer.c pv/pv_comps.c pv/pv_error.c \ +- pv/pv_opt_item.c \ ++ pv/pv_opt_item.c utils/curl.c \ + $(NULL) + $(bin_PROGRAM)_OBJS := $($(bin_PROGRAM)_SRCS:.c=.o) + + ALL_CFLAGS += -std=gnu11 -DPKGDATADIR=$(PKGDATADIR) \ +- $(GLIB2_CFLAGS) $(LIBCRYPTO_CFLAGS) \ ++ $(GLIB2_CFLAGS) $(LIBCRYPTO_CFLAGS) $(LIBCURL_CFLAGS) \ + $(WARNINGS) \ + $(NULL) + ALL_CPPFLAGS += $(INCLUDE_PARMS) +-LDLIBS += $(GLIB2_LIBS) $(LIBCRYPTO_LIBS) ++LDLIBS += $(GLIB2_LIBS) $(LIBCRYPTO_LIBS) $(LIBCURL_LIBS) + + + ifneq ($(shell sh -c 'command -v pkg-config'),) +@@ -40,21 +40,27 @@ GLIB2_CFLAGS := $(shell pkg-config --sil + GLIB2_LIBS := $(shell pkg-config --silence-errors --libs glib-2.0) + LIBCRYPTO_CFLAGS := $(shell pkg-config --silence-errors --cflags libcrypto) + LIBCRYPTO_LIBS := $(shell pkg-config --silence-errors --libs libcrypto) ++LIBCURL_CFLAGS := $(shell pkg-config --silence-errors --cflags libcurl) ++LIBCURL_LIBS := $(shell pkg-config --silence-errors --libs libcurl) + else + GLIB2_CFLAGS := -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include + GLIB2_LIBS := -lglib-2.0 + LIBCRYPTO_CFLAGS := + LIBCRYPTO_LIBS := -lcrypto ++LIBCURL_CFLAGS := ++LIBCURL_LIBS := -lcurl + endif + + BUILD_TARGETS := skip-$(bin_PROGRAM) + INSTALL_TARGETS := skip-$(bin_PROGRAM) + ifneq (${HAVE_OPENSSL},0) + ifneq (${HAVE_GLIB2},0) ++ifneq (${HAVE_LIBCURL},0) + BUILD_TARGETS := $(bin_PROGRAM) + INSTALL_TARGETS := install-$(bin_PROGRAM) + endif + endif ++endif + + all: $(BUILD_TARGETS) + +@@ -98,4 +104,9 @@ $($(bin_PROGRAM)_OBJS): .check-dep-$(bin + "openssl-devel / libssl-dev version >= 1.1.0", \ + "HAVE_OPENSSL=0", \ + "-I.") ++ $(call check_dep, \ ++ "$(bin_PROGRAM)", \ ++ "curl/curl.h", \ ++ "libcurl-devel", \ ++ "HAVE_LIBCURL=0") + touch $@ +Index: s390-tools-service/genprotimg/src/genprotimg.c +=================================================================== +--- s390-tools-service.orig/genprotimg/src/genprotimg.c ++++ s390-tools-service/genprotimg/src/genprotimg.c +@@ -18,6 +18,8 @@ + #include "common.h" + #include "pv/pv_args.h" + #include "pv/pv_image.h" ++#include "utils/crypto.h" ++#include "utils/curl.h" + + enum { + LOG_LEVEL_CRITICAL = 0, +@@ -117,6 +119,8 @@ static void remove_signal_handler(const + signal(signals[i], SIG_DFL); + } + ++static void __attribute__((constructor)) __init(void); ++static void __attribute__((destructor)) __cleanup(void); + gint main(gint argc, gchar *argv[]) + { + g_autoptr(PvArgs) args = pv_args_new(); +@@ -181,3 +185,16 @@ error: + g_clear_pointer(&args, pv_args_free); + exit(ret); + } ++ ++static void __init(void) ++{ ++ pv_crypto_init(); ++ if (curl_init() != 0) ++ g_abort(); ++} ++ ++static void __cleanup(void) ++{ ++ curl_cleanup(); ++ pv_crypto_cleanup(); ++} +Index: s390-tools-service/genprotimg/src/include/pv_crypto_def.h +=================================================================== +--- s390-tools-service.orig/genprotimg/src/include/pv_crypto_def.h ++++ s390-tools-service/genprotimg/src/include/pv_crypto_def.h +@@ -14,6 +14,24 @@ + + #include "lib/zt_common.h" + ++/* IBM signing key subject */ ++#define PV_IBM_Z_SUBJECT_COMMON_NAME "International Business Machines Corporation" ++#define PV_IBM_Z_SUBJECT_COUNTRY_NAME "US" ++#define PV_IBM_Z_SUBJECT_LOCALITY_NAME "Poughkeepsie" ++#define PV_IBM_Z_SUBJECT_ORGANIZATIONONAL_UNIT_NAME_SUFFIX "Key Signing Service" ++#define PV_IBM_Z_SUBJECT_ORGANIZATION_NAME "International Business Machines Corporation" ++#define PV_IBM_Z_SUBJECT_STATE "New York" ++#define PV_IMB_Z_SUBJECT_ENTRY_COUNT 6 ++ ++/* Minimum security level for the keys/certificates used to establish a chain of ++ * trust (see https://www.openssl.org/docs/man1.1.1/man3/X509_VERIFY_PARAM_set_auth_level.html ++ * for details). ++ */ ++#define PV_CERTS_SECURITY_LEVEL 2 ++ ++/* SKID for DigiCert Assured ID Root CA */ ++#define DIGICERT_ASSURED_ID_ROOT_CA_SKID "45EBA2AFF492CB82312D518BA7A7219DF36DC80F" ++ + union ecdh_pub_key { + struct { + uint8_t x[80]; +Index: s390-tools-service/genprotimg/src/pv/pv_args.c +=================================================================== +--- s390-tools-service.orig/genprotimg/src/pv/pv_args.c ++++ s390-tools-service/genprotimg/src/pv/pv_args.c +@@ -18,7 +18,9 @@ + + static gchar summary[] = + "Use genprotimg to create a protected virtualization kernel image file,\n" +- "which can be loaded using zipl or QEMU."; ++ "which can be loaded using zipl or QEMU. For all certificates, revocation\n" ++ "lists, and host-key documents, both the PEM and DER input formats are\n" ++ "supported."; + + static gint pv_arg_compare(gconstpointer arg_1, gconstpointer arg_2) + { +@@ -97,9 +99,14 @@ static gint pv_args_validate_options(PvA + return -1; + } + +- if (!args->no_verify) { +- g_set_error(err, PV_PARSE_ERROR, PR_PARSE_ERROR_MISSING_ARGUMENT, +- _("Use the option '--no-verify' as the verification support is not available yet.")); ++ if (!args->no_verify && ++ (!args->untrusted_cert_paths || ++ g_strv_length(args->untrusted_cert_paths) == 0)) { ++ g_set_error( ++ err, PV_PARSE_ERROR, PR_PARSE_ERROR_MISSING_ARGUMENT, ++ _("Either specify the IBM Z signing key and (DigiCert) intermediate CA certificate\n" ++ "by using the '--cert' option, or use the '--no-verify' flag to disable the\n" ++ "host-key document verification completely (at your own risk).")); + return -1; + } + +@@ -141,6 +148,8 @@ static gboolean cb_set_string_option(con + { + gchar **args_option = NULL; + ++ if (g_str_equal(option, "--root-ca")) ++ args_option = &args->root_ca_path; + if (g_str_equal(option, "-o") || g_str_equal(option, "--output")) + args_option = &args->output_path; + if (g_str_equal(option, "--x-comp-key")) +@@ -211,6 +220,18 @@ gint pv_args_parse_options(PvArgs *args, + _("FILE specifies a host-key document. At least\n" INDENT + "one is required."), + .arg_description = _("FILE") }, ++ { .long_name = "cert", ++ .short_name = 'C', ++ .flags = G_OPTION_FLAG_NONE, ++ .arg = G_OPTION_ARG_FILENAME_ARRAY, ++ .arg_data = &args->untrusted_cert_paths, ++ .description = _( ++ "FILE contains a certificate that is used to\n" INDENT ++ "establish a chain of trust for the verification\n" INDENT ++ "of the host-key documents. The IBM Z signing\n" INDENT ++ "key and intermediate CA certificate (signed\n" INDENT ++ "by the root CA) are required."), ++ .arg_description = _("FILE") }, + { .long_name = "output", + .short_name = 'o', + .flags = G_OPTION_FLAG_FILENAME, +@@ -241,6 +262,31 @@ gint pv_args_parse_options(PvArgs *args, + .description = _("Use the kernel parameters stored in PARMFILE\n" INDENT + "(optional)."), + .arg_description = _("PARMFILE") }, ++ { .long_name = "crl", ++ .short_name = 0, ++ .flags = G_OPTION_FLAG_NONE, ++ .arg = G_OPTION_ARG_FILENAME_ARRAY, ++ .arg_data = &args->crl_paths, ++ .description = _( ++ "FILE contains a certificate revocation list\n" INDENT ++ "(optional)."), ++ .arg_description = _("FILE") }, ++ { .long_name = "offline", ++ .short_name = 0, ++ .flags = G_OPTION_FLAG_NONE, ++ .arg = G_OPTION_ARG_NONE, ++ .arg_data = &args->offline, ++ .description = _("Don't download CRLs (optional)."), ++ .arg_description = NULL }, ++ { .long_name = "root-ca", ++ .short_name = 0, ++ .flags = G_OPTION_FLAG_FILENAME, ++ .arg = G_OPTION_ARG_CALLBACK, ++ .arg_data = cb_set_string_option, ++ .description = _( ++ "Set FILE as the trusted root CA and don't use the\n" INDENT ++ "root CAs that are installed on the system (optional)."), ++ .arg_description = _("FILE") }, + { .long_name = "no-verify", + .short_name = 0, + .flags = G_OPTION_FLAG_NONE, +@@ -378,6 +424,9 @@ void pv_args_free(PvArgs *args) + g_free(args->cust_root_key_path); + g_free(args->cust_comm_key_path); + g_free(args->gcm_iv_path); ++ g_free(args->root_ca_path); ++ g_strfreev(args->crl_paths); ++ g_strfreev(args->untrusted_cert_paths); + g_strfreev(args->host_keys); + g_free(args->xts_key_path); + g_slist_free_full(args->comps, (GDestroyNotify)pv_arg_free); +Index: s390-tools-service/genprotimg/src/pv/pv_args.h +=================================================================== +--- s390-tools-service.orig/genprotimg/src/pv/pv_args.h ++++ s390-tools-service/genprotimg/src/pv/pv_args.h +@@ -25,6 +25,7 @@ void pv_arg_free(PvArg *arg); + typedef struct { + gint log_level; + gint no_verify; ++ gboolean offline; + gchar *pcf; + gchar *scf; + gchar *psw_addr; /* PSW address which will be used for the start of +@@ -34,6 +35,11 @@ typedef struct { + gchar *cust_comm_key_path; + gchar *gcm_iv_path; + gchar **host_keys; ++ gchar *root_ca_path; /* Trusted root CA used for the verification of the ++ * chain of trust (if specified). ++ */ ++ gchar **untrusted_cert_paths; ++ gchar **crl_paths; + gchar *xts_key_path; + GSList *comps; + gchar *output_path; +Index: s390-tools-service/genprotimg/src/pv/pv_error.h +=================================================================== +--- s390-tools-service.orig/genprotimg/src/pv/pv_error.h ++++ s390-tools-service/genprotimg/src/pv/pv_error.h +@@ -28,6 +28,8 @@ typedef enum { + PV_ERROR_IPIB_SIZE, + PV_ERROR_PV_HDR_SIZE, + PV_ERROR_INTERNAL, ++ PV_ERROR_CURL_INIT_FAILED, ++ PV_ERROR_DOWNLOAD_FAILED, + } PvErrors; + + typedef enum { +@@ -57,6 +59,31 @@ typedef enum { + PV_CRYPTO_ERROR_RANDOMIZATION, + PV_CRYPTO_ERROR_INVALID_PARM, + PV_CRYPTO_ERROR_INVALID_KEY_SIZE, ++ PV_CRYPTO_ERROR_INVALID_VALIDITY_PERIOD, ++ PV_CRYPTO_ERROR_EXPIRED, ++ PV_CRYPTO_ERROR_NOT_VALID_YET, ++ PV_CRYPTO_ERROR_LOAD_CRL, ++ PV_CRYPTO_ERROR_NO_PUBLIC_KEY, ++ PV_CRYPTO_ERROR_INVALID_SIGNATURE_ALGORITHM, ++ PV_CRYPTO_ERROR_SIGNATURE_ALGORITHM_MISMATCH, ++ PV_CRYPTO_ERROR_INVALID_URI, ++ PV_CRYPTO_ERROR_CRL_DOWNLOAD_FAILED, ++ PV_CRYPTO_ERROR_CERT_SIGNATURE_INVALID, ++ PV_CRYPTO_ERROR_CRL_SIGNATURE_INVALID, ++ PV_CRYPTO_ERROR_CERT_SUBJECT_ISSUER_MISMATCH, ++ PV_CRYPTO_ERROR_CRL_SUBJECT_ISSUER_MISMATCH, ++ PV_CRYPTO_ERROR_NO_IBM_Z_SIGNING_KEY, ++ PV_CRYPTO_ERROR_MALFORMED_CERTIFICATE, ++ PV_CRYPTO_ERROR_NO_CRL, ++ PV_CRYPTO_ERROR_LOAD_ROOT_CA, ++ PV_CRYPTO_ERROR_LOAD_DEFAULT_CA, ++ PV_CRYPTO_ERROR_MALFORMED_ROOT_CA, ++ PV_CRYPTO_ERROR_WRONG_CA_USED, ++ PV_CRYPTO_ERROR_SKID_AKID_MISMATCH, ++ PV_CRYPTO_ERROR_NO_ISSUER_IBM_Z_FOUND, ++ PV_CRYPTO_ERROR_FAILED_DOWNLOAD_CRL, ++ PV_CRYPTO_ERROR_NO_CRLDP, ++ PV_CRYPTO_ERROR_CERT_REVOKED, + } PvCryptoErrors; + + #endif +Index: s390-tools-service/genprotimg/src/pv/pv_image.c +=================================================================== +--- s390-tools-service.orig/genprotimg/src/pv/pv_image.c ++++ s390-tools-service/genprotimg/src/pv/pv_image.c +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -138,22 +139,18 @@ static EVP_PKEY *pv_img_get_cust_pub_pri + return generate_ec_key(nid, err); + } + +-static HostKeyList *pv_img_get_host_keys(gchar **host_cert_paths, +- X509_STORE *store, gint nid, ++static HostKeyList *pv_img_get_host_keys(GSList *host_keys_with_path, gint nid, + GError **err) + { + g_autoslist(EVP_PKEY) ret = NULL; + +- g_assert(host_cert_paths); +- +- for (gchar **iterator = host_cert_paths; iterator != NULL && *iterator != NULL; +- iterator++) { ++ for (GSList *iterator = host_keys_with_path; iterator; ++ iterator = iterator->next) { ++ x509_with_path *cert_with_path = iterator->data; + g_autoptr(EVP_PKEY) host_key = NULL; +- const gchar *path = *iterator; +- +- g_assert(path); ++ X509 *cert = cert_with_path->cert; + +- host_key = read_ec_pubkey_cert(store, nid, path, err); ++ host_key = read_ec_pubkey_cert(cert, nid, err); + if (!host_key) + return NULL; + +@@ -253,10 +250,172 @@ static gint pv_img_set_control_flags(PvI + return 0; + } + ++static gint pv_img_hostkey_verify(GSList *host_key_certs, ++ const gchar *root_ca_path, ++ const gchar *const *crl_paths, ++ const gchar *const *untrusted_cert_paths, ++ gboolean offline, GError **err) ++{ ++ g_autoslist(x509_with_path) untrusted_certs_with_path = NULL; ++ g_autoptr(STACK_OF_X509) ibm_signing_certs = NULL; ++ g_autoptr(STACK_OF_X509) untrusted_certs = NULL; ++ g_autoslist(x509_pair) ibm_z_pairs = NULL; ++ g_autoptr(X509_STORE) trusted = NULL; ++ gint ibm_signing_certs_count; ++ ++ /* Load trusted root CAs of the system if and only if @root_ca_path is ++ * NULL, otherwise use the root CA specified by @root_ca_path. ++ */ ++ trusted = store_setup(root_ca_path, crl_paths, err); ++ if (!trusted) ++ goto error; ++ ++ if (!offline) { ++ g_autoptr(STACK_OF_X509_CRL) downloaded_ibm_signing_crls = NULL; ++ ++ /* Set up the download routine for the lookup of CRLs. */ ++ store_setup_crl_download(trusted); ++ ++ /* Try to download the CRLs of the IBM Z signing certificates ++ * specified in the host-key documents. Ignore download errors ++ * as it's still possible that a CRL is specified via command ++ * line. ++ */ ++ downloaded_ibm_signing_crls = try_load_crls_by_certs(host_key_certs); ++ ++ /* Add the downloaded CRLs to the store so they can be used for ++ * the verification later. ++ */ ++ for (int i = 0; i < sk_X509_CRL_num(downloaded_ibm_signing_crls); i++) { ++ X509_CRL *crl = sk_X509_CRL_value(downloaded_ibm_signing_crls, i); ++ ++ if (X509_STORE_add_crl(trusted, crl) != 1) { ++ g_set_error(err, PV_CRYPTO_ERROR, ++ PV_CRYPTO_ERROR_INTERNAL, ++ _("failed to load CRL")); ++ goto error; ++ } ++ } ++ } ++ ++ /* Load all untrusted certificates (e.g. IBM Z signing key and ++ * DigiCert intermediate CA) that are required to establish a chain of ++ * trust starting from the host-key document up to the root CA (if not ++ * otherwise specified that's the DigiCert Assured ID Root CA). ++ */ ++ untrusted_certs_with_path = load_certificates(untrusted_cert_paths, err); ++ if (!untrusted_certs_with_path) ++ goto error; ++ ++ /* Convert to STACK_OF(X509) */ ++ untrusted_certs = get_x509_stack(untrusted_certs_with_path); ++ ++ /* Find all IBM Z signing keys and remove them from the chain as we ++ * have to verify that they're valid. The last step of the chain of ++ * trust verification must be done manually, as the IBM Z signing keys ++ * are not marked as (intermediate) CA and therefore the standard ++ * `X509_verify_cert` function of OpenSSL cannot be used to verify the ++ * actual host-key documents. ++ */ ++ ibm_signing_certs = delete_ibm_signing_certs(untrusted_certs); ++ ibm_signing_certs_count = sk_X509_num(ibm_signing_certs); ++ if (ibm_signing_certs_count < 1) { ++ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_NO_IBM_Z_SIGNING_KEY, ++ _("please specify at least one IBM Z signing key")); ++ goto error; ++ } else if (ibm_signing_certs_count > 1) { ++ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_NO_IBM_Z_SIGNING_KEY, ++ _("please specify only one IBM Z signing key")); ++ goto error; ++ } ++ ++ if (store_set_verify_param(trusted, err) < 0) ++ goto error; ++ ++ /* Verify that the IBM Z signing keys are trustable. ++ * For this we must check: ++ * ++ * 1. Can a chain of trust be established ending in a root CA ++ * 2. Is the correct root CA ued? It has either to be the ++ * 'DigiCert Assured ID Root CA' or the root CA specified via ++ * command line. ++ */ ++ for (gint i = 0; i < sk_X509_num(ibm_signing_certs); ++i) { ++ X509 *ibm_signing_cert = sk_X509_value(ibm_signing_certs, i); ++ g_autoptr(STACK_OF_X509_CRL) ibm_signing_crls = NULL; ++ g_autoptr(X509_STORE_CTX) ctx = NULL; ++ x509_pair *pair = NULL; ++ ++ g_assert(ibm_signing_cert); ++ ++ /* Create the verification context and set the trusted ++ * and chain parameters. ++ */ ++ ctx = create_store_ctx(trusted, untrusted_certs, err); ++ if (!ctx) ++ goto error; ++ ++ /* Verify the IBM Z signing key */ ++ if (verify_cert(ibm_signing_cert, ctx, err) < 0) ++ goto error; ++ ++ /* Verify the build chain of trust chain. If the user passes a ++ * trusted root CA on the command line then the check for the ++ * Subject Key Identifier (SKID) is skipped, otherwise let's ++ * check if the SKID meets our expectation. ++ */ ++ if (!root_ca_path && ++ check_chain_parameters(X509_STORE_CTX_get0_chain(ctx), ++ get_digicert_assured_id_root_ca_skid(), ++ err) < 0) { ++ goto error; ++ } ++ ++ ibm_signing_crls = store_ctx_find_valid_crls(ctx, ibm_signing_cert, err); ++ if (!ibm_signing_crls) { ++ g_prefix_error(err, _("IBM Z signing key: ")); ++ goto error; ++ } ++ ++ /* Increment reference counter of @ibm_signing_cert as the ++ * certificate will now also be owned by @ibm_z_pairs. ++ */ ++ if (X509_up_ref(ibm_signing_cert) != 1) ++ g_abort(); ++ ++ pair = x509_pair_new(&ibm_signing_cert, &ibm_signing_crls); ++ ibm_z_pairs = g_slist_append(ibm_z_pairs, pair); ++ g_assert(!ibm_signing_cert); ++ g_assert(!ibm_signing_crls); ++ } ++ ++ /* Verify host-key documents by using the IBM Z signing ++ * certificates and the corresponding certificate revocation ++ * lists. ++ */ ++ for (GSList *iterator = host_key_certs; iterator; iterator = iterator->next) { ++ x509_with_path *host_key_with_path = iterator->data; ++ const gchar *host_key_path = host_key_with_path->path; ++ X509 *host_key = host_key_with_path->cert; ++ gint flags = X509_V_FLAG_CRL_CHECK; ++ ++ if (verify_host_key(host_key, ibm_z_pairs, flags, ++ PV_CERTS_SECURITY_LEVEL, err) < 0) { ++ g_prefix_error(err, "'%s': ", host_key_path); ++ goto error; ++ } ++ } ++ ++ return 0; ++error: ++ g_prefix_error(err, _("Failed to verify host-key document: ")); ++ return -1; ++} ++ + /* read in the keys or auto-generate them */ + static gint pv_img_set_keys(PvImage *img, const PvArgs *args, GError **err) + { +- g_autoptr(X509_STORE) store = NULL; ++ g_autoslist(x509_with_path) host_key_certs = NULL; + + g_assert(img->xts_cipher); + g_assert(img->cust_comm_cipher); +@@ -285,8 +444,25 @@ static gint pv_img_set_keys(PvImage *img + if (!img->cust_pub_priv_key) + return -1; + ++ /* Load all host-key documents specified on the command line */ ++ host_key_certs = load_certificates((const gchar **)args->host_keys, ++ err); ++ if (!host_key_certs) ++ return -1; ++ ++ if (!args->no_verify && ++ pv_img_hostkey_verify(host_key_certs, args->root_ca_path, ++ (const gchar * const *)args->crl_paths, ++ (const gchar * const *)args->untrusted_cert_paths, ++ args->offline, err) < 0) { ++ return -1; ++ } ++ ++ /* Loads the public keys stored in the host-key documents and verify ++ * that the correct elliptic curve is used. ++ */ + img->host_pub_keys = +- pv_img_get_host_keys(args->host_keys, store, img->nid, err); ++ pv_img_get_host_keys(host_key_certs, img->nid, err); + if (!img->host_pub_keys) + return -1; + +@@ -406,6 +582,9 @@ PvImage *pv_img_new(PvArgs *args, const + if (args->no_verify) + g_warning(_("host-key document verification is disabled. Your workload is not secured.")); + ++ if (args->root_ca_path) ++ g_warning(_("A different root CA than the default DigiCert root CA is selected. Ensure that this root CA is trusted.")); ++ + ret->comps = pv_img_comps_new(EVP_sha512(), EVP_sha512(), EVP_sha512(), err); + if (!ret->comps) + return NULL; +Index: s390-tools-service/genprotimg/src/utils/crypto.c +=================================================================== +--- s390-tools-service.orig/genprotimg/src/utils/crypto.c ++++ s390-tools-service/genprotimg/src/utils/crypto.c +@@ -16,6 +16,11 @@ + #include + #include + #include ++#include ++#include ++#include ++#include ++#include + #include + #include + +@@ -25,8 +30,49 @@ + #include "pv/pv_error.h" + + #include "buffer.h" ++#include "curl.h" + #include "crypto.h" + ++#define DEFINE_GSLIST_MAP(t2, t1) \ ++ typedef t1 *(*g_slist_map_func_##t2##_##t1)(const t2 *x, \ ++ GError **err); \ ++ G_GNUC_UNUSED static GSList *g_slist_map_##t2##_##t1(const GSList *list, \ ++ g_slist_map_func_##t2##_##t1 func, \ ++ GError **err) \ ++ { \ ++ g_autoslist(t1) ret = NULL; \ ++ for (const GSList *iterator = list; iterator; \ ++ iterator = iterator->next) { \ ++ const t2 *value = iterator->data; \ ++ t1 *new_value = NULL; \ ++ g_assert(value); \ ++ new_value = func(value, err); \ ++ if (!new_value) \ ++ return NULL; \ ++ ret = g_slist_append(ret, g_steal_pointer(&new_value)); \ ++ } \ ++ return g_steal_pointer(&ret); \ ++ } ++ ++#define DEFINE_GSLIST_TO_STACK(t1) \ ++ G_GNUC_UNUSED static STACK_OF(t1) *g_slist_to_stack_of_##t1(GSList **list) \ ++ { \ ++ g_assert(list); \ ++ g_autoptr(STACK_OF_##t1) ret = sk_##t1##_new_null(); \ ++ if (!ret) \ ++ g_abort(); \ ++ for (GSList *iterator = *list; iterator; \ ++ iterator = iterator->next) { \ ++ if (sk_##t1##_push(ret, g_steal_pointer(&iterator->data)) == 0) \ ++ g_abort(); \ ++ } \ ++ g_clear_pointer(list, g_slist_free); \ ++ return g_steal_pointer(&ret); \ ++ } ++ ++DEFINE_GSLIST_MAP(x509_with_path, X509) ++DEFINE_GSLIST_TO_STACK(X509) ++ + EVP_MD_CTX *digest_ctx_new(const EVP_MD *md, GError **err) + { + g_autoptr(EVP_MD_CTX) ctx = EVP_MD_CTX_new(); +@@ -359,79 +405,1340 @@ static gboolean certificate_uses_correct + return TRUE; + } + +-static gboolean verify_certificate(X509_STORE *store, X509 *cert, GError **err) ++/* Verify that the used public key algorithm matches the subject signature ++ * algorithm ++ */ ++static int check_signature_algo_match(const EVP_PKEY *pkey, const X509 *subject, ++ GError **err) + { +- g_autoptr(X509_STORE_CTX) csc = X509_STORE_CTX_new(); +- if (!csc) ++ gint pkey_nid; ++ ++ if (!pkey) { ++ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_NO_PUBLIC_KEY, ++ _("no public key")); ++ return -1; ++ } ++ ++ if (OBJ_find_sigid_algs(X509_get_signature_nid(subject), NULL, ++ &pkey_nid) != 1) { ++ g_set_error(err, PV_CRYPTO_ERROR, ++ PV_CRYPTO_ERROR_INVALID_SIGNATURE_ALGORITHM, ++ _("unsupported signature algorithm")); ++ return -1; ++ } ++ ++ if (EVP_PKEY_type(pkey_nid) != EVP_PKEY_base_id(pkey)) { ++ g_set_error(err, PV_CRYPTO_ERROR, ++ PV_CRYPTO_ERROR_SIGNATURE_ALGORITHM_MISMATCH, ++ _("signature algorithm mismatch")); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static X509_CRL *load_crl_from_bio(BIO *bio) ++{ ++ g_autoptr(X509_CRL) crl = PEM_read_bio_X509_CRL(bio, NULL, 0, NULL); ++ if (crl) ++ return g_steal_pointer(&crl); ++ ERR_clear_error(); ++ BIO_reset(bio); ++ ++ /* maybe the CRL is stored in DER format */ ++ crl = d2i_X509_CRL_bio(bio, NULL); ++ if (crl) ++ return g_steal_pointer(&crl); ++ return NULL; ++} ++ ++static X509_CRL *GByteArray_to_X509_CRL(const GByteArray *data) ++{ ++ g_autoptr(X509_CRL) ret = NULL; ++ g_autoptr(BIO) bio = NULL; ++ ++ g_assert(data); ++ ++ if (data->len > INT_MAX) ++ return NULL; ++ ++ bio = BIO_new_mem_buf(data->data, (int)data->len); ++ if (!bio) + g_abort(); + +- if (X509_STORE_CTX_init(csc, store, cert, NULL) != 1) { +- g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INIT, +- _("Failed to initialize X.509 store")); +- return FALSE; ++ ret = load_crl_from_bio(bio); ++ if (!ret) ++ return NULL; ++ ++ return g_steal_pointer(&ret); ++} ++ ++static gint load_crl_from_web(const gchar *url, X509_CRL **crl, GError **err) ++{ ++ g_autoptr(X509_CRL) tmp_crl = NULL; ++ g_autoptr(GByteArray) data = NULL; ++ g_assert(crl); ++ ++ data = curl_download(url, CRL_DOWNLOAD_TIMEOUT_MS, ++ CRL_DOWNLOAD_MAX_SIZE, err); ++ if (!data) { ++ g_prefix_error(err, _("unable to download CRL: ")); ++ return -1; + } ++ tmp_crl = GByteArray_to_X509_CRL(data); ++ if (!tmp_crl) { ++ g_set_error(err, PV_CRYPTO_ERROR, ++ PV_CRYPTO_ERROR_CRL_DOWNLOAD_FAILED, ++ _("unable to load CRL from '%s'"), url); ++ return -1; ++ } ++ *crl = g_steal_pointer(&tmp_crl); ++ return 0; ++} + +- if (X509_verify_cert(csc) != 1) { +- g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_VERIFICATION, +- _("Failed to verify host-key document")); ++static BIO *bio_read_from_file(const char *path) ++{ ++ g_autoptr(BIO) bio = BIO_new_file(path, "r"); ++ ++ if (!bio) ++ return NULL; ++ ++ return g_steal_pointer(&bio); ++} ++ ++/* This function reads in only the first certificate and ignores all other. This ++ * is only relevant for the PEM file format. For the host-key document and the ++ * root CA this behavior is expected. ++ */ ++X509 *load_cert_from_file(const char *path, GError **err) ++{ ++ g_autoptr(BIO) bio = bio_read_from_file(path); ++ g_autoptr(X509) cert = NULL; ++ ++ if (!bio) { ++ g_set_error(err, PV_CRYPTO_ERROR, ++ PV_CRYPTO_ERROR_READ_CERTIFICATE, ++ _("unable to read certificate: '%s'"), path); ++ return NULL; ++ } ++ ++ cert = PEM_read_bio_X509(bio, NULL, NULL, NULL); ++ if (cert) ++ return g_steal_pointer(&cert); ++ ERR_clear_error(); ++ BIO_reset(bio); ++ ++ /* maybe the certificate is stored in DER format */ ++ cert = d2i_X509_bio(bio, NULL); ++ if (cert) ++ return g_steal_pointer(&cert); ++ ++ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_READ_CERTIFICATE, ++ _("unable to load certificate: '%s'"), path); ++ return NULL; ++} ++ ++/* @crl_paths is allowed to be NULL */ ++static int load_crls_to_store(X509_STORE *store, const gchar *const *crl_paths, ++ gboolean err_out_empty_crls, GError **err) ++{ ++ for (const gchar *const *iterator = crl_paths; ++ iterator != NULL && *iterator != NULL; iterator++) { ++ const gchar *crl_path = *iterator; ++ X509_LOOKUP *lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); ++ int count; ++ ++ g_assert(crl_path); ++ ++ if (!lookup) { ++ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, ++ _("X509 store initialization failed")); ++ return -1; ++ } ++ ++ /* support *.pem files containing multiple CRLs */ ++ count = X509_load_crl_file(lookup, crl_path, X509_FILETYPE_PEM); ++ if (count > 0) ++ continue; ++ ++ count = X509_load_crl_file(lookup, crl_path, X509_FILETYPE_ASN1); ++ if (count == 1) ++ continue; ++ ++ if (err_out_empty_crls) { ++ g_set_error(err, PV_CRYPTO_ERROR, ++ PV_CRYPTO_ERROR_LOAD_CRL, ++ _("unable to load CRL from: '%s'"), crl_path); ++ return -1; ++ } ++ } ++ ++ return 0; ++} ++ ++/* returns ++ * 0 when the certificate is valid, ++ * -1 when not yet valid, ++ * 1 when expired ++ */ ++static int check_validity_period(const ASN1_TIME *not_before, const ASN1_TIME *not_after) ++{ ++ if (X509_cmp_current_time(not_before) != -1) ++ return -1; ++ ++ if (X509_cmp_current_time(not_after) != 1) ++ return 1; ++ ++ return 0; ++} ++ ++static gint x509_name_entry_get_data0(X509_NAME_ENTRY *entry, const guchar **data, ++ gsize *data_len) ++{ ++ const ASN1_STRING *asn1_str; ++ gint tmp_data_len; ++ ++ g_assert(data); ++ g_assert(data_len); ++ ++ asn1_str = X509_NAME_ENTRY_get_data(entry); ++ if (!asn1_str) ++ return -1; ++ ++ tmp_data_len = ASN1_STRING_length(asn1_str); ++ if (tmp_data_len < 0) ++ return -1; ++ ++ *data = ASN1_STRING_get0_data(asn1_str); ++ *data_len = (gsize)tmp_data_len; ++ return 0; ++} ++ ++/* The caller must not free *data! */ ++static gint x509_name_get_data0_by_NID(X509_NAME *name, gint nid, ++ const guchar **data, gsize *data_len) ++{ ++ ++ X509_NAME_ENTRY *entry = NULL; ++ gint lastpos = -1; ++ ++ lastpos = X509_NAME_get_index_by_NID(name, nid, lastpos); ++ if (lastpos == -1) ++ return -1; ++ ++ entry = X509_NAME_get_entry(name, lastpos); ++ if (!entry) ++ return -1; ++ ++ if (x509_name_entry_get_data0(entry, data, data_len) < 0) ++ return -1; ++ ++ return 0; ++} ++ ++/* @y must be a NULL-terminated string */ ++static gboolean x509_name_data_by_nid_equal(X509_NAME *name, gint nid, ++ const gchar *y) ++{ ++ const guchar *data = NULL; ++ gsize y_len = strlen(y); ++ gsize data_len; ++ ++ if (x509_name_get_data0_by_NID(name, nid, &data, &data_len) < 0) ++ return FALSE; ++ ++ if (data_len != y_len) ++ return FALSE; ++ ++ return memcmp(data, y, data_len) == 0; ++} ++ ++static gboolean own_X509_NAME_ENTRY_equal(const X509_NAME_ENTRY *x, ++ const X509_NAME_ENTRY *y) ++{ ++ const ASN1_OBJECT *x_obj = X509_NAME_ENTRY_get_object(x); ++ const ASN1_STRING *x_data = X509_NAME_ENTRY_get_data(x); ++ const ASN1_OBJECT *y_obj = X509_NAME_ENTRY_get_object(y); ++ const ASN1_STRING *y_data = X509_NAME_ENTRY_get_data(y); ++ gint x_len = ASN1_STRING_length(x_data); ++ gint y_len = ASN1_STRING_length(y_data); ++ ++ if (x_len < 0 || x_len != y_len) + return FALSE; ++ ++ /* ASN1_STRING_cmp(x_data, y_data) == 0 doesn't work because it also ++ * compares the type, which is sometimes different. ++ */ ++ return OBJ_cmp(x_obj, y_obj) == 0 && ++ memcmp(ASN1_STRING_get0_data(x_data), ++ ASN1_STRING_get0_data(y_data), ++ (unsigned long)x_len) == 0; ++} ++ ++static gboolean own_X509_NAME_equal(const X509_NAME *x, const X509_NAME *y) ++{ ++ gint x_count = X509_NAME_entry_count(x); ++ gint y_count = X509_NAME_entry_count(y); ++ ++ if (x != y && (!x || !y)) ++ return FALSE; ++ ++ if (x_count != y_count) ++ return FALSE; ++ ++ for (gint i = 0; i < x_count; i++) { ++ const X509_NAME_ENTRY *entry_i = X509_NAME_get_entry(x, i); ++ gboolean entry_found = FALSE; ++ ++ for (gint j = 0; j < y_count; j++) { ++ const X509_NAME_ENTRY *entry_j = ++ X509_NAME_get_entry(y, j); ++ ++ if (own_X509_NAME_ENTRY_equal(entry_i, entry_j)) { ++ entry_found = TRUE; ++ break; ++ } ++ } ++ ++ if (!entry_found) ++ return FALSE; + } ++ return TRUE; ++} ++ ++/* Checks whether the subject of @cert is a IBM signing key subject. For this we ++ * must check that the subject is equal to: 'C = US, ST = New York, L = ++ * Poughkeepsie, O = International Business Machines Corporation, CN = ++ * International Business Machines Corporation' and the organization unit (OUT) ++ * must end with the suffix ' Key Signing Service'. ++ */ ++static gboolean has_ibm_signing_subject(X509 *cert) ++{ ++ X509_NAME *subject = X509_get_subject_name(cert); ++ /* X509_NAME_entry_count is safe to be used with NULL */ ++ gint entry_count = X509_NAME_entry_count(subject); ++ g_autofree gchar *data_str = NULL; ++ const guchar *data; ++ gsize data_len; ++ ++ if (entry_count != PV_IMB_Z_SUBJECT_ENTRY_COUNT) ++ return FALSE; ++ ++ if (!x509_name_data_by_nid_equal(subject, NID_countryName, ++ PV_IBM_Z_SUBJECT_COUNTRY_NAME)) ++ return FALSE; ++ ++ if (!x509_name_data_by_nid_equal(subject, NID_stateOrProvinceName, ++ PV_IBM_Z_SUBJECT_STATE)) ++ return FALSE; ++ ++ if (!x509_name_data_by_nid_equal(subject, NID_localityName, ++ PV_IBM_Z_SUBJECT_LOCALITY_NAME)) ++ return FALSE; ++ ++ if (!x509_name_data_by_nid_equal(subject, NID_organizationName, ++ PV_IBM_Z_SUBJECT_ORGANIZATION_NAME)) ++ return FALSE; ++ ++ if (!x509_name_data_by_nid_equal(subject, NID_commonName, ++ PV_IBM_Z_SUBJECT_COMMON_NAME)) ++ return FALSE; ++ ++ if (x509_name_get_data0_by_NID(subject, NID_organizationalUnitName, ++ &data, &data_len) < 0) ++ return FALSE; ++ ++ /* Make sure that data_str is null-terminated as in general it cannot be ++ * assumed that @data is null-terminated. ++ */ ++ data_str = g_strndup((const gchar *)data, data_len); ++ if (!g_str_has_suffix(data_str, ++ PV_IBM_Z_SUBJECT_ORGANIZATIONONAL_UNIT_NAME_SUFFIX)) ++ return FALSE; + + return TRUE; + } + +-static X509 *load_certificate(const gchar *path, GError **err) ++static X509_NAME *x509_name_reorder_attributes(const X509_NAME *name, const gint nids[], ++ gsize nids_len) + { +- g_autoptr(X509) ret = NULL; +- g_autoptr(BIO) bio = BIO_new_file(path, "rb"); ++ gint entry_count = X509_NAME_entry_count(name); ++ g_autoptr(X509_NAME) ret = NULL; ++ ++ if (entry_count < 0) ++ return NULL; ++ ++ if (nids_len != (gsize) entry_count) ++ return NULL; ++ ++ ret = X509_NAME_new(); ++ if (!ret) ++ g_abort(); ++ ++ for (gsize i = 0; i < nids_len; i++) { ++ const X509_NAME_ENTRY *entry = NULL; ++ gint nid = nids[i]; ++ gint lastpos = -1; ++ ++ lastpos = X509_NAME_get_index_by_NID((X509_NAME *)name, nid, lastpos); ++ if (lastpos == -1) ++ return NULL; ++ ++ entry = X509_NAME_get_entry(name, lastpos); ++ if (!entry) ++ return NULL; ++ ++ if (X509_NAME_add_entry(ret, entry, -1, 0) != 1) ++ return NULL; ++ } ++ ++ return g_steal_pointer(&ret); ++} ++ ++/* In RFC 5280 the attributes of a (subject/issuer) name is not mandatory ++ * ordered. The problem is that our certificates are not consistent in the order ++ * (see https://tools.ietf.org/html/rfc5280#section-4.1.2.4 for details). ++ * ++ * This function converts a correct X509_NAME into the broken one. The caller is ++ * responsible to free the returned value. ++ */ ++X509_NAME *c2b_name(const X509_NAME *name) ++{ ++ gint nids[] = { NID_countryName, NID_organizationName, NID_organizationalUnitName, ++ NID_localityName, NID_stateOrProvinceName, NID_commonName }; ++ g_autoptr(X509_NAME) broken_name = NULL; ++ ++ g_assert(name); ++ ++ /* Try to reorder the attributes */ ++ broken_name = x509_name_reorder_attributes(name, nids, G_N_ELEMENTS(nids)); ++ if (broken_name) ++ return g_steal_pointer(&broken_name); ++ return X509_NAME_dup((X509_NAME *)name); ++} ++ ++/* Verify that: subject(issuer) == issuer(crl) and SKID(issuer) == AKID(crl) */ ++static gint check_crl_issuer(X509_CRL *crl, X509 *issuer, GError **err) ++{ ++ const X509_NAME *crl_issuer = X509_CRL_get_issuer(crl); ++ const X509_NAME *issuer_subject = X509_get_subject_name(issuer); ++ AUTHORITY_KEYID *akid = NULL; ++ ++ if (!own_X509_NAME_equal(issuer_subject, crl_issuer)) { ++ g_autofree char *issuer_subject_str = X509_NAME_oneline(issuer_subject, ++ NULL, 0); ++ g_autofree char *crl_issuer_str = X509_NAME_oneline(crl_issuer, NULL, 0); + +- if (!bio) { + g_set_error(err, PV_CRYPTO_ERROR, +- PV_CRYPTO_ERROR_READ_CERTIFICATE, +- _("Failed to read host-key document: '%s'"), path); ++ PV_CRYPTO_ERROR_CRL_SUBJECT_ISSUER_MISMATCH, ++ _("issuer mismatch:\n%s\n%s"), ++ issuer_subject_str, crl_issuer_str); ++ return -1; ++ } ++ ++ /* If AKID(@crl) is specified it must match with SKID(@issuer) */ ++ akid = X509_CRL_get_ext_d2i(crl, NID_authority_key_identifier, NULL, NULL); ++ if (akid && X509_check_akid(issuer, akid) != X509_V_OK) { ++ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_SKID_AKID_MISMATCH, ++ _("AKID mismatch")); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++/* Verify whether a revocation list @crl is valid and is issued by @cert. For ++ * this multiple steps must be done: ++ * ++ * 1. verify issuer of the CRL matches with the suject name of @cert ++ * 2. verify the validity period of the CRL ++ * 3. verify the signature of the CRL ++ * ++ * Important: This function doesn't verify whether @cert is allowed to issue a ++ * CRL. Returns 0 if @crl is valid and issued by @cert, otherwise -1. ++ */ ++gint check_crl_valid_for_cert(X509_CRL *crl, X509 *cert, ++ gint verify_flags, GError **err) ++{ ++ EVP_PKEY *pkey = X509_get0_pubkey(cert); ++ ++ g_assert(crl); ++ ++ if (!pkey) { ++ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, ++ _("failed to retrieve public key from the certificate")); ++ return -1; ++ } ++ ++ /* check that the @crl issuer matches with the subject name of @cert*/ ++ if (check_crl_issuer(crl, cert, err) < 0) ++ return -1; ++ ++ /* verify the validity period of the CRL */ ++ if (!(verify_flags & X509_V_FLAG_NO_CHECK_TIME)) { ++ const ASN1_TIME *last = X509_CRL_get0_lastUpdate(crl); ++ const ASN1_TIME *next = X509_CRL_get0_nextUpdate(crl); ++ ++ if (!last || !next || check_validity_period(last, next)) { ++ g_set_error(err, PV_CRYPTO_ERROR, ++ PV_CRYPTO_ERROR_INVALID_VALIDITY_PERIOD, ++ _("validity period is not valid")); ++ return -1; ++ } ++ } else { ++ verify_flags &= ~X509_V_FLAG_NO_CHECK_TIME; ++ } ++ ++ /* verify the signature */ ++ if (X509_CRL_verify(crl, pkey) != 1) { ++ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_CRL_SIGNATURE_INVALID, ++ _("signature is not valid")); ++ return -1; ++ } ++ g_assert(verify_flags == 0); ++ return 0; ++} ++ ++/* Given a certificate @cert try to find valid revocation lists in @ctx. If no ++ * valid CRL was found NULL is returned. ++ */ ++STACK_OF_X509_CRL *store_ctx_find_valid_crls(X509_STORE_CTX *ctx, X509 *cert, ++ GError **err) ++{ ++ g_autoptr(STACK_OF_X509_CRL) ret = NULL; ++ const gint verify_flags = 0; ++ X509_NAME *subject = NULL; ++ ++ subject = X509_get_subject_name(cert); ++ if (!subject) { ++ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_MALFORMED_CERTIFICATE, ++ _("certificate is malformed")); + return NULL; + } + +- ret = PEM_read_bio_X509(bio, NULL, 0, NULL); ++ ret = X509_STORE_CTX_get1_crls(ctx, subject); + if (!ret) { +- g_set_error(err, PV_CRYPTO_ERROR, +- PV_CRYPTO_ERROR_READ_CERTIFICATE, +- _("Failed to load host-key document: '%s'"), path); ++ /* Workaround to fix the mismatch between issuer name of the ++ * IBM Z signing CRLs and the IBM Z signing key subject name. ++ */ ++ g_autoptr(X509_NAME) broken_subject = c2b_name(subject); ++ ++ ret = X509_STORE_CTX_get1_crls(ctx, broken_subject); ++ if (!ret) { ++ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_NO_CRL, ++ _("no CRL found")); ++ return NULL; ++ } ++ } ++ ++ /* Filter out non-valid CRLs for @cert */ ++ for (gint i = 0; i < sk_X509_CRL_num(ret); i++) { ++ X509_CRL *crl = sk_X509_CRL_value(ret, i); ++ ++ g_assert(crl); ++ ++ /* If @crl is not valid remove it from the array and log a ++ * warning. ++ */ ++ if (check_crl_valid_for_cert(crl, cert, verify_flags, err) < 0) { ++ g_assert(err); ++ g_warning(_("CRL is not valid: %s"), (*err)->message); ++ g_clear_error(err); ++ ++ /* Remove this certificate from the list and change i-- as the ++ * array has changed - this is not beautfiul, but right now the ++ * easiest solution I came up with ++ */ ++ if (sk_X509_CRL_delete(ret, i--) != crl) ++ g_abort(); ++ ++ g_clear_pointer(&crl, X509_CRL_free); ++ } ++ } ++ ++ if (sk_X509_CRL_num(ret) < 1) { ++ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_NO_CRL, ++ _("no valid CRL found")); + return NULL; + } ++ return g_steal_pointer(&ret); ++} ++ ++/* Return a list of all IBM Z signing key certificates in @certs and remove them ++ * from the chain. Return empty stack if no IBM Z signing key is found. ++ */ ++STACK_OF_X509 *delete_ibm_signing_certs(STACK_OF_X509 *certs) ++{ ++ g_autoptr(STACK_OF_X509) ret = sk_X509_new_null(); ++ ++ for (gint i = 0; i < sk_X509_num(certs); i++) { ++ X509 *cert = sk_X509_value(certs, i); ++ ++ g_assert(cert); ++ ++ if (!has_ibm_signing_subject(cert)) ++ continue; ++ ++ /* Remove this certificate from the list and change i-- as the ++ * array has changed - this is not beautfiul, but right now the ++ * easiest solution I came up with. ++ */ ++ if (sk_X509_delete(certs, i--) != cert) ++ g_abort(); ++ ++ if (sk_X509_push(ret, g_steal_pointer(&cert)) == 0) ++ g_abort(); ++ } + + return g_steal_pointer(&ret); + } + +-EVP_PKEY *read_ec_pubkey_cert(X509_STORE *store, gint nid, const gchar *path, +- GError **err) ++X509_STORE *store_setup(const gchar *root_ca_path, const gchar * const *crl_paths, ++ GError **err) ++{ ++ g_autoptr(X509_STORE) store = X509_STORE_new(); ++ ++ g_assert(store); ++ ++ /* if @root_ca_path != NULL use the specified root CA only, otherwise use the ++ * default root CAs found on the system ++ */ ++ if (root_ca_path) { ++ X509_LOOKUP *lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); ++ int count; ++ ++ if (!lookup) { ++ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, ++ _("X509 store initialization failed")); ++ return NULL; ++ } ++ ++ count = X509_load_cert_file(lookup, root_ca_path, X509_FILETYPE_PEM); ++ if (count > 1) { ++ g_set_error(err, PV_CRYPTO_ERROR, ++ PV_CRYPTO_ERROR_LOAD_ROOT_CA, ++ _("multiple certificates in one PEM file is not supported: '%s'"), ++ root_ca_path); ++ return NULL; ++ } else if (count < 1) { ++ count = X509_load_cert_file(lookup, root_ca_path, ++ X509_FILETYPE_ASN1); ++ if (count != 1) { ++ g_set_error(err, PV_CRYPTO_ERROR, ++ PV_CRYPTO_ERROR_LOAD_ROOT_CA, ++ _("failed to load root certificate from '%s'"), ++ root_ca_path); ++ return NULL; ++ } ++ } ++ } else { ++ /* Load certificates into @store from the hardcoded OpenSSL ++ * default paths ++ */ ++ if (X509_STORE_set_default_paths(store) != 1) { ++ g_set_error(err, PV_CRYPTO_ERROR, ++ PV_CRYPTO_ERROR_LOAD_DEFAULT_CA, ++ _("failed to load system root certificates")); ++ return NULL; ++ } ++ } ++ ++ /* Error out if a CRL file was provided that has not at least one CRL*/ ++ if (load_crls_to_store(store, crl_paths, TRUE, err) < 0) ++ return NULL; ++ ++ return g_steal_pointer(&store); ++} ++ ++int store_set_verify_param(X509_STORE *store, GError **err) ++{ ++ g_autoptr(X509_VERIFY_PARAM) param = NULL; ++ unsigned long flags = X509_V_FLAG_CRL_CHECK | ++ X509_V_FLAG_CRL_CHECK_ALL | ++ X509_V_FLAG_TRUSTED_FIRST | ++ X509_V_FLAG_CHECK_SS_SIGNATURE | ++ X509_V_FLAG_X509_STRICT | ++ X509_V_FLAG_POLICY_CHECK; ++ ++ /* Create a X509_VERIFY_PARAM structure, which specifies which checks ++ * should be done by the certificate verification operation ++ */ ++ param = X509_VERIFY_PARAM_new(); ++ if (!param) ++ g_abort(); ++ ++ /* The maximum depth level of the chain of trust for the verification of ++ * the IBM Z signing key is 2, i.e. IBM Z signing key -> (DigiCert) ++ * intermediate CA -> (DigiCert) root CA ++ */ ++ X509_VERIFY_PARAM_set_depth(param, 2); ++ ++ /* Set minimum allowed security level to at least 112 bits. */ ++ X509_VERIFY_PARAM_set_auth_level(param, PV_CERTS_SECURITY_LEVEL); ++ ++ /* Set verification purpose to 'Any Purpose' and specify that the ++ * associated trust setting of the default purpose should be used. ++ */ ++ if (X509_VERIFY_PARAM_set_purpose(param, ++ X509_PURPOSE_ANY | X509_TRUST_DEFAULT) != 1) ++ goto error; ++ ++ /* Each certificate from the chain of trust must be checked against a ++ * CRL to see if it has been revoked. In addition, use trusted ++ * certificates first mode, check signature of the last certificate, ++ * strict mode, and verify the policies. ++ */ ++ if (X509_VERIFY_PARAM_set_flags(param, flags) != 1) ++ goto error; ++ ++ if (X509_STORE_set1_param(store, param) != 1) ++ goto error; ++ ++ return 0; ++ ++error: ++ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, ++ _("X509 store initialization failed")); ++ return -1; ++} ++ ++/* @cert_paths must contain at least one element, otherwise an error is ++ * reported. ++ */ ++GSList *load_certificates(const gchar *const *cert_paths, GError **err) ++{ ++ g_autoslist(x509_with_path) ret = NULL; ++ ++ for (const gchar *const *iterator = cert_paths; ++ iterator != NULL && *iterator != NULL; iterator++) { ++ const gchar *cert_path = *iterator; ++ g_autoptr(X509) cert = NULL; ++ ++ g_assert(cert_path); ++ ++ cert = load_cert_from_file(cert_path, err); ++ if (!cert) ++ return NULL; ++ ++ ret = g_slist_append(ret, x509_with_path_new(cert, cert_path)); ++ } ++ if (!ret) { ++ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_READ_CERTIFICATE, ++ _("no certificates specified")); ++ return NULL; ++ } ++ ++ return g_steal_pointer(&ret); ++} ++ ++static X509 *get_cert(const x509_with_path *cert_with_path, G_GNUC_UNUSED GError **err) + { +- g_autoptr(EVP_PKEY) ret = NULL; + g_autoptr(X509) cert = NULL; + +- cert = load_certificate(path, err); ++ g_assert(cert_with_path && cert_with_path->cert); ++ ++ cert = cert_with_path->cert; ++ if (X509_up_ref(cert) != 1) ++ g_abort(); ++ return g_steal_pointer(&cert); ++} ++ ++STACK_OF_X509 *get_x509_stack(const GSList *x509_with_path_list) ++{ ++ g_autoslist(X509) certs = NULL; ++ g_autoptr(GError) err = NULL; ++ ++ certs = g_slist_map_x509_with_path_X509(x509_with_path_list, ++ get_cert, &err); ++ g_assert_null(err); ++ return g_slist_to_stack_of_X509(&certs); ++} ++ ++x509_with_path *x509_with_path_new(X509 *cert, const gchar *path) ++{ ++ g_autoptr(x509_with_path) ret = g_new(x509_with_path, 1); ++ ++ g_assert(cert && path); ++ ++ if (X509_up_ref(cert) != 1) ++ g_abort(); ++ ret->cert = cert; ++ ret->path = g_strdup(path); ++ return g_steal_pointer(&ret); ++} ++ ++void x509_with_path_free(x509_with_path *cert) ++{ + if (!cert) ++ return; ++ ++ X509_free(cert->cert); ++ g_free((gchar *)cert->path); ++ g_free(cert); ++} ++ ++x509_pair *x509_pair_new(X509 **cert, STACK_OF_X509_CRL **crls) ++{ ++ g_autoptr(x509_pair) ret = g_new0(x509_pair, 1); ++ ++ g_assert(cert); ++ g_assert(crls); ++ ++ ret->cert = g_steal_pointer(cert); ++ ret->crls = g_steal_pointer(crls); ++ return g_steal_pointer(&ret); ++} ++ ++void x509_pair_free(x509_pair *pair) ++{ ++ if (!pair) ++ return; ++ ++ sk_X509_CRL_pop_free(pair->crls, X509_CRL_free); ++ X509_free(pair->cert); ++ g_free(pair); ++} ++ ++X509_STORE_CTX *create_store_ctx(X509_STORE *trusted, STACK_OF_X509 *chain, ++ GError **err) ++{ ++ g_autoptr(X509_STORE_CTX) ctx = X509_STORE_CTX_new(); ++ ++ if (!ctx || !X509_STORE_CTX_init(ctx, trusted, NULL, chain)) { ++ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, ++ _("X509 store initialization failed: %s"), ++ X509_verify_cert_error_string(X509_STORE_CTX_get_error(ctx))); + return NULL; ++ } + +- if (store && !verify_certificate(store, cert, err)) { +- g_prefix_error(err, +- _("Failed to load host-key document: '%s': "), +- path); ++ return g_steal_pointer(&ctx); ++} ++ ++gint verify_cert(X509 *cert, X509_STORE_CTX *ctx, GError **err) ++{ ++ gint rc; ++ ++ X509_STORE_CTX_set_cert(ctx, cert); ++ rc = X509_verify_cert(ctx); ++ if (rc != 1) { ++ X509 *tmp_cert = NULL; ++ ++ tmp_cert = X509_STORE_CTX_get_current_cert(ctx); ++ if (tmp_cert) { ++ g_autofree char *subj_name = X509_NAME_oneline( ++ X509_get_subject_name(tmp_cert), NULL, 0); ++ g_set_error(err, PV_CRYPTO_ERROR, ++ PV_CRYPTO_ERROR_INTERNAL, ++ _("failed to verify certificate '%s': %s"), ++ subj_name, ++ X509_verify_cert_error_string( ++ X509_STORE_CTX_get_error(ctx))); ++ } else { ++ g_set_error(err, PV_CRYPTO_ERROR, ++ PV_CRYPTO_ERROR_INTERNAL, ++ _("failed to verify certificate: %s"), ++ X509_verify_cert_error_string( ++ X509_STORE_CTX_get_error(ctx))); ++ } ++ ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static int security_level_to_bits(int level) ++{ ++ static int security_bits[] = { 0, 80, 112, 128, 192, 256 }; ++ ++ g_assert(level > 0 && level < (int)G_N_ELEMENTS(security_bits)); ++ ++ return security_bits[level]; ++} ++ ++static ASN1_OCTET_STRING *digicert_assured_id_root_ca; ++ ++const ASN1_OCTET_STRING *get_digicert_assured_id_root_ca_skid(void) ++{ ++ pv_crypto_init(); ++ return digicert_assured_id_root_ca; ++} ++ ++/* Used for the caching of the downloaded CRLs */ ++static GHashTable *cached_crls; ++ ++void pv_crypto_init(void) ++{ ++ if (digicert_assured_id_root_ca) ++ return; ++ ++ cached_crls = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, ++ (GDestroyNotify)X509_CRL_free); ++ digicert_assured_id_root_ca = s2i_ASN1_OCTET_STRING( ++ NULL, NULL, DIGICERT_ASSURED_ID_ROOT_CA_SKID); ++} ++ ++void pv_crypto_cleanup(void) ++{ ++ if (!digicert_assured_id_root_ca) ++ return; ++ g_clear_pointer(&cached_crls, g_hash_table_destroy); ++ g_clear_pointer(&digicert_assured_id_root_ca, ASN1_OCTET_STRING_free); ++} ++ ++gint check_chain_parameters(const STACK_OF_X509 *chain, ++ const ASN1_OCTET_STRING *skid, GError **err) ++{ ++ const ASN1_OCTET_STRING *ca_skid = NULL; ++ gint len = sk_X509_num(chain); ++ X509 *ca = NULL; ++ ++ g_assert(skid); ++ /* at least one root and one leaf certificate must be defined */ ++ g_assert(len >= 2); ++ ++ /* get the root certificate of the chain of trust */ ++ ca = sk_X509_value(chain, len - 1); ++ if (!ca) { ++ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, ++ _("no root certificate found")); ++ return -1; ++ } ++ ++ ca_skid = X509_get0_subject_key_id(ca); ++ if (!ca_skid) { ++ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_MALFORMED_ROOT_CA, ++ _("malformed root certificate")); ++ return -1; ++ } ++ ++ if (ASN1_STRING_cmp(ca_skid, skid) != 0) { ++ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_WRONG_CA_USED, ++ _("expecting DigiCert root CA to be used")); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++/* It's almost the same as X509_check_issed from OpenSSL does except that we ++ * don't check the key usage of the potential issuer. This means we check: ++ * 1. issuer_name(cert) == subject_name(issuer) ++ * 2. Check whether the akid(cert) (if available) matches the issuer skid ++ * 3. Check that the cert algrithm matches the subject algorithm ++ * 4. Verify the signature of certificate @cert is using the public key of ++ * @issuer. ++ */ ++static gint check_host_key_issued(X509 *cert, X509 *issuer, GError **err) ++{ ++ const X509_NAME *issuer_subject = X509_get_subject_name(issuer); ++ const X509_NAME *cert_issuer = X509_get_issuer_name(cert); ++ AUTHORITY_KEYID *akid = NULL; ++ ++ /* We cannot use X509_NAME_cmp() because it considers the order of the ++ * X509_NAME_Entries. ++ */ ++ if (!own_X509_NAME_equal(issuer_subject, cert_issuer)) { ++ g_autofree char *issuer_subject_str = ++ X509_NAME_oneline(issuer_subject, NULL, 0); ++ g_autofree char *cert_issuer_str = ++ X509_NAME_oneline(cert_issuer, NULL, 0); ++ g_set_error(err, PV_CRYPTO_ERROR, ++ PV_CRYPTO_ERROR_CERT_SUBJECT_ISSUER_MISMATCH, ++ _("Subject issuer mismatch:\n'%s'\n'%s'"), ++ issuer_subject_str, cert_issuer_str); ++ return -1; ++ } ++ ++ akid = X509_get_ext_d2i(cert, NID_authority_key_identifier, NULL, NULL); ++ if (akid && X509_check_akid(issuer, akid) != X509_V_OK) { ++ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_SKID_AKID_MISMATCH, ++ _("AKID mismatch")); ++ return -1; ++ } ++ ++ if (check_signature_algo_match(X509_get0_pubkey(issuer), cert, err) < 0) ++ return -1; ++ ++ if (X509_verify(cert, X509_get0_pubkey(issuer)) != 1) { ++ g_set_error(err, PV_CRYPTO_ERROR, ++ PV_CRYPTO_ERROR_CERT_SIGNATURE_INVALID, ++ _("Signature verification failed")); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static gboolean is_cert_revoked(X509 *cert, X509_CRL *crl) ++{ ++ X509_REVOKED *revoked = NULL; ++ gint rc; ++ ++ if (!cert || !crl) ++ g_abort(); ++ ++ rc = X509_CRL_get0_by_serial(crl, &revoked, ++ (ASN1_INTEGER *)X509_get0_serialNumber(cert)); ++ if (rc == 0) ++ return FALSE; ++ ++ if (revoked) ++ return TRUE; ++ ++ return FALSE; ++} ++ ++/* Get the first http[s] URL from a DIST_POINT */ ++static const char *get_first_dp_url(DIST_POINT *dp) ++{ ++ GENERAL_NAMES *general_names; ++ ++ g_assert(dp); ++ ++ if (!dp->distpoint || dp->distpoint->type != 0) ++ return NULL; ++ ++ general_names = dp->distpoint->name.fullname; ++ for (gint i = 0; i < sk_GENERAL_NAME_num(general_names); i++) { ++ GENERAL_NAME *name = sk_GENERAL_NAME_value(general_names, i); ++ g_autofree const gchar *uri_str = NULL; ++ ASN1_STRING *uri_asn1; ++ const gchar *uri_data; ++ gint uri_data_len; ++ gint type; ++ ++ uri_asn1 = GENERAL_NAME_get0_value(name, &type); ++ if (type != GEN_URI) ++ continue; ++ uri_data_len = ASN1_STRING_length(uri_asn1); ++ if (uri_data_len < 0) ++ continue; ++ uri_data = (const gchar *)ASN1_STRING_get0_data(uri_asn1); ++ /* Make sure that uri_str is null-terminated as in general it ++ * cannot be assumed that @uri_data is null-terminated. ++ */ ++ uri_str = g_strndup(uri_data, ++ (gsize)uri_data_len); ++ if (g_str_has_prefix(uri_str, "http://")) ++ return uri_data; ++ if (g_str_has_prefix(uri_str, "https://")) ++ return uri_data; ++ } ++ return NULL; ++} ++ ++static gboolean insert_crl(X509_NAME *name, X509_CRL *crl) ++{ ++ g_autofree gchar *key = NULL; ++ ++ g_assert(name); ++ ++ key = X509_NAME_oneline(name, NULL, 0); ++ if (!key) ++ g_abort(); ++ if (X509_CRL_up_ref(crl) != 1) ++ g_abort(); ++ return g_hash_table_insert(cached_crls, g_steal_pointer(&key), crl); ++} ++ ++/* Caller is responsible for free'ing */ ++static X509_CRL *lookup_crl(X509_NAME *name) ++{ ++ g_autoptr(X509_CRL) crl = NULL; ++ g_autofree gchar *key = NULL; ++ ++ g_assert(name); ++ ++ key = X509_NAME_oneline(name, NULL, 0); ++ if (!key) ++ g_abort(); ++ crl = g_hash_table_lookup(cached_crls, key); ++ if (crl) { ++ if (X509_CRL_up_ref(crl) != 1) ++ g_abort(); ++ return g_steal_pointer(&crl); ++ } ++ return NULL; ++} ++ ++/* Returns empty stack if no CRL downloaded. */ ++static STACK_OF_X509_CRL *crls_download_cb(X509_STORE_CTX *ctx, X509_NAME *nm) ++{ ++ g_autoptr(STACK_OF_X509_CRL) crls = NULL; ++ g_autoptr(X509_CRL) crl = NULL; ++ /* must not be free'd */ ++ X509 *cert = NULL; ++ ++ crls = sk_X509_CRL_new_null(); ++ if (!crls) ++ g_abort(); ++ cert = X509_STORE_CTX_get_current_cert(ctx); ++ if (!cert) ++ g_steal_pointer(&crls); ++ g_assert(X509_NAME_cmp(X509_get_issuer_name(cert), nm) == 0); ++ crl = lookup_crl(nm); ++ if (!crl) { ++ /* ignore error */ ++ crl = load_crl_by_cert(cert, NULL); ++ if (!crl) ++ return g_steal_pointer(&crls); ++ g_assert_true(insert_crl(nm, crl)); ++ } ++ if (sk_X509_CRL_push(crls, g_steal_pointer(&crl)) == 0) ++ g_abort(); ++ return g_steal_pointer(&crls); ++} ++ ++void STACK_OF_DIST_POINT_free(STACK_OF_DIST_POINT *stack) ++{ ++ if (!stack) ++ return; ++ ++ sk_DIST_POINT_pop_free(stack, DIST_POINT_free); ++} ++ ++void STACK_OF_X509_free(STACK_OF_X509 *stack) ++{ ++ if (!stack) ++ return; ++ ++ sk_X509_pop_free(stack, X509_free); ++} ++ ++void STACK_OF_X509_CRL_free(STACK_OF_X509_CRL *stack) ++{ ++ if (!stack) ++ return; ++ ++ sk_X509_CRL_pop_free(stack, X509_CRL_free); ++} ++ ++/* Downloaded CRLs have a higher precedence than the CRLs specified on the ++ * command line. ++ */ ++static STACK_OF_X509_CRL *crls_cb(X509_STORE_CTX *ctx, X509_NAME *nm) ++{ ++ g_autoptr(STACK_OF_X509_CRL) crls = crls_download_cb(ctx, nm); ++ ++ if (sk_X509_CRL_num(crls) > 0) ++ return g_steal_pointer(&crls); ++ return X509_STORE_CTX_get1_crls(ctx, nm); ++} ++ ++/* Set up CRL lookup with download support */ ++void store_setup_crl_download(X509_STORE *st) ++{ ++ X509_STORE_set_lookup_crls(st, crls_cb); ++} ++ ++/* Download a CRL using the URI specified in the distribution @crldp */ ++static X509_CRL *load_crl_by_dist_point(DIST_POINT *crldp, GError **err) ++{ ++ const gchar *uri = get_first_dp_url(crldp); ++ g_autoptr(X509_CRL) crl = NULL; ++ ++ if (!uri) { ++ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, ++ _("no valid URL specified in distribution point")); + return NULL; + } + ++ if (load_crl_from_web(uri, &crl, err) < 0) ++ return NULL; ++ ++ return g_steal_pointer(&crl); ++} ++ ++/* This function returns the first X509_CRL found from the CRL distribution ++ * points specified in @cert. This function could be optimized by filtering ++ * duplicate certificates and/or filtering duplicated URIs. ++ */ ++X509_CRL *load_crl_by_cert(X509 *cert, GError **err) ++{ ++ g_autoptr(STACK_OF_DIST_POINT) crldps = NULL; ++ g_autoptr(X509_CRL) ret = NULL; ++ ++ g_assert(cert); ++ ++ crldps = X509_get_ext_d2i(cert, NID_crl_distribution_points, NULL, NULL); ++ if (!crldps || sk_DIST_POINT_num(crldps) == 0) { ++ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_NO_CRLDP, ++ _("no distribution point found")); ++ return NULL; ++ } ++ ++ for (int i = 0; i < sk_DIST_POINT_num(crldps); i++) { ++ DIST_POINT *crldp = sk_DIST_POINT_value(crldps, i); ++ ++ g_assert(crldp); ++ ++ /* ignore error */ ++ ret = load_crl_by_dist_point(crldp, NULL); ++ if (ret) ++ return g_steal_pointer(&ret); ++ } ++ ++ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_FAILED_DOWNLOAD_CRL, ++ _("failed to download CRL")); ++ return NULL; ++} ++ ++STACK_OF_X509_CRL *try_load_crls_by_certs(GSList *certs_with_path) ++{ ++ g_autoptr(STACK_OF_X509_CRL) ret = sk_X509_CRL_new_null(); ++ if (!ret) ++ g_abort(); ++ ++ for (GSList *iterator = certs_with_path; iterator; ++ iterator = iterator->next) { ++ x509_with_path *cert_with_path = iterator->data; ++ X509 *cert = cert_with_path->cert; ++ g_autoptr(X509_CRL) crl = NULL; ++ ++ g_assert(cert); ++ ++ /* ignore error */ ++ crl = load_crl_by_cert(cert, NULL); ++ if (!crl) ++ continue; ++ ++ if (sk_X509_CRL_push(ret, g_steal_pointer(&crl)) == 0) ++ g_abort(); ++ } ++ ++ return g_steal_pointer(&ret); ++} ++ ++/* Assumptions are that the issuer_crt and issuer_crl is a trusted IBM Z ++ * signing certificate/revocation list. This function verifies a host-key ++ * document. To do so multiple steps are required: ++ * ++ * 1. issuer(host_key) == subject(issuer_crt) ++ * 2. Signature verification ++ * 3. @host_key must not be expired ++ * 4. @host_key must not be revoked ++ */ ++gint verify_host_key(X509 *host_key, GSList *issuer_pairs, ++ gint verify_flags, int level, GError **err) ++{ ++ g_assert(host_key); ++ ++ const gint exp_security_bits = security_level_to_bits(level); ++ EVP_PKEY *pkey = X509_get0_pubkey(host_key); ++ gboolean successfully_checked = FALSE; ++ gint pkey_security_bits; ++ ++ if (!pkey) { ++ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, ++ _("failed to retrieve public key")); ++ return -1; ++ } ++ ++ /* check key level, if necessary */ ++ pkey_security_bits = EVP_PKEY_security_bits(pkey); ++ if (exp_security_bits > 0 && pkey_security_bits < exp_security_bits) { ++ g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_VERIFICATION, ++ _("not enough bits of security (%d, %d expected)"), ++ pkey_security_bits, exp_security_bits); ++ return -1; ++ } ++ ++ if (!(verify_flags & X509_V_FLAG_NO_CHECK_TIME)) { ++ const ASN1_TIME *last = X509_get_notBefore(host_key); ++ const ASN1_TIME *next = X509_get_notAfter(host_key); ++ ++ if (!last || !next || check_validity_period(last, next)) { ++ g_set_error(err, PV_CRYPTO_ERROR, ++ PV_CRYPTO_ERROR_INVALID_VALIDITY_PERIOD, ++ _("validity period is not valid")); ++ return -1; ++ } ++ } else { ++ verify_flags &= ~X509_V_FLAG_NO_CHECK_TIME; ++ } ++ ++ /* Verify that the host_key was issued by a certificate and that it ++ * wasn't revoked. ++ */ ++ for (GSList *iterator = issuer_pairs; iterator; ++ iterator = iterator->next) { ++ const x509_pair *pair = iterator->data; ++ STACK_OF_X509_CRL *issuer_crls = NULL; ++ X509 *issuer_cert = NULL; ++ ++ g_assert(pair); ++ ++ issuer_cert = pair->cert; ++ issuer_crls = pair->crls; ++ ++ g_assert(issuer_cert); ++ ++ /* Verify that the issuer(host_key) == subject(issuer_cert) and ++ * that the signature is valid ++ */ ++ if (check_host_key_issued(host_key, issuer_cert, NULL) < 0) ++ continue; ++ ++ /* Check against CRL */ ++ if (verify_flags & X509_V_FLAG_CRL_CHECK) { ++ gboolean crl_checked = FALSE; ++ ++ verify_flags &= ~X509_V_FLAG_CRL_CHECK; ++ for (gint i = 0; i < sk_X509_CRL_num(issuer_crls); i++) { ++ X509_CRL *issuer_crl = ++ sk_X509_CRL_value(issuer_crls, i); ++ ++ g_assert(issuer_crl); ++ ++ if (is_cert_revoked(host_key, issuer_crl)) { ++ g_set_error(err, PV_CRYPTO_ERROR, ++ PV_CRYPTO_ERROR_CERT_REVOKED, ++ _("certificate revoked")); ++ return -1; ++ } ++ ++ crl_checked = TRUE; ++ } ++ ++ if (!crl_checked) { ++ g_set_error(err, PV_CRYPTO_ERROR, ++ PV_CRYPTO_ERROR_INTERNAL, ++ _("no valid CRL found")); ++ return -1; ++ } ++ successfully_checked = TRUE; ++ break; ++ } ++ } ++ ++ if (!successfully_checked) { ++ g_set_error(err, PV_CRYPTO_ERROR, ++ PV_CRYPTO_ERROR_NO_ISSUER_IBM_Z_FOUND, ++ _("no IBM Z signing key that issued this host-key document found")); ++ return -1; ++ } ++ ++ /* were some unsupported flags specified? */ ++ g_assert(verify_flags == 0); ++ return 0; ++} ++ ++EVP_PKEY *read_ec_pubkey_cert(X509 *cert, gint nid, ++ GError **err) ++{ ++ g_autoptr(EVP_PKEY) ret = NULL; ++ + ret = X509_get_pubkey(cert); + if (!ret) { + g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INVALID_PARM, +- _("Failed to get public key from host-key document: '%s'"), +- path); ++ _("Failed to get public key from host-key document")); + return NULL; + } + + if (!certificate_uses_correct_curve(ret, nid, err)) { + g_prefix_error(err, +- _("Failed to load host-key document: '%s': "), +- path); ++ _("Host-key document doesn\'t use correct EC curve")); + return NULL; + } + +Index: s390-tools-service/genprotimg/src/utils/crypto.h +=================================================================== +--- s390-tools-service.orig/genprotimg/src/utils/crypto.h ++++ s390-tools-service/genprotimg/src/utils/crypto.h +@@ -11,14 +11,18 @@ + #define PV_UTILS_CRYPTO_H + + #include ++#include + #include + #include + #include + #include + #include ++#include + #include ++#include + #include + #include ++#include + #include + + #include "common.h" +@@ -33,6 +37,9 @@ + #define AES_256_XTS_TWEAK_SIZE 16 + #define AES_256_XTS_KEY_SIZE 64 + ++#define CRL_DOWNLOAD_TIMEOUT_MS 3000 ++#define CRL_DOWNLOAD_MAX_SIZE (1024 * 1024) /* in bytes */ ++ + enum PvCryptoMode { + PV_ENCRYPT, + PV_DECRYPT, +@@ -40,7 +47,34 @@ enum PvCryptoMode { + + typedef GSList HostKeyList; + ++/* play nice with g_autoptr */ ++typedef STACK_OF(DIST_POINT) STACK_OF_DIST_POINT; ++typedef STACK_OF(X509) STACK_OF_X509; ++typedef STACK_OF(X509_CRL) STACK_OF_X509_CRL; ++ ++void STACK_OF_DIST_POINT_free(STACK_OF_DIST_POINT *stack); ++void STACK_OF_X509_free(STACK_OF_X509 *stack); ++void STACK_OF_X509_CRL_free(STACK_OF_X509_CRL *stack); ++ ++typedef struct { ++ X509 *cert; ++ const gchar *path; ++} x509_with_path; ++ ++x509_with_path *x509_with_path_new(X509 *cert, const gchar *path); ++void x509_with_path_free(x509_with_path *cert); ++ ++typedef struct { ++ X509 *cert; ++ STACK_OF_X509_CRL *crls; ++} x509_pair; ++ ++x509_pair *x509_pair_new(X509 **cert, STACK_OF_X509_CRL **crls); ++void x509_pair_free(x509_pair *pair); ++ + /* Register auto cleanup functions */ ++WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(ASN1_INTEGER, ASN1_INTEGER_free) ++WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(ASN1_OCTET_STRING, ASN1_OCTET_STRING_free) + WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(BIGNUM, BN_free) + WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(BIO, BIO_free_all) + WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(BN_CTX, BN_CTX_free) +@@ -51,10 +85,18 @@ WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EV + WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_MD_CTX, EVP_MD_CTX_free) + WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_PKEY, EVP_PKEY_free) + WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_PKEY_CTX, EVP_PKEY_CTX_free) ++WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(STACK_OF_DIST_POINT, STACK_OF_DIST_POINT_free); ++WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(STACK_OF_X509, STACK_OF_X509_free); ++WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(STACK_OF_X509_CRL, STACK_OF_X509_CRL_free); + WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509, X509_free) ++WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_CRL, X509_CRL_free) + WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_LOOKUP, X509_LOOKUP_free) ++WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_NAME, X509_NAME_free) ++WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(x509_pair, x509_pair_free) + WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_STORE, X509_STORE_free) + WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_STORE_CTX, X509_STORE_CTX_free) ++WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_VERIFY_PARAM, X509_VERIFY_PARAM_free) ++WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(x509_with_path, x509_with_path_free) + + union cmp_index { + struct { +@@ -79,8 +121,37 @@ struct cipher_parms { + const Buffer *iv_or_tweak; + }; + +-EVP_PKEY *read_ec_pubkey_cert(X509_STORE *store, gint nid, const gchar *path, +- GError **err); ++int check_crl_valid_for_cert(X509_CRL *crl, X509 *cert, ++ gint verify_flags, GError **err); ++void pv_crypto_init(void); ++void pv_crypto_cleanup(void); ++const ASN1_OCTET_STRING *get_digicert_assured_id_root_ca_skid(void); ++gint verify_host_key(X509 *host_key, GSList *issuer_pairs, ++ gint verify_flags, int level, GError **err); ++X509 *load_cert_from_file(const char *path, GError **err); ++X509_CRL *load_crl_from_file(const gchar *path, GError **err); ++GSList *load_certificates(const gchar *const *cert_paths, GError **err); ++STACK_OF_X509 *get_x509_stack(const GSList *x509_with_path_list); ++X509_STORE *store_setup(const gchar *root_ca_path, ++ const gchar * const *crl_paths, ++ GError **err); ++int store_set_verify_param(X509_STORE *store, GError **err); ++X509_CRL *load_crl_by_cert(X509 *cert, GError **err); ++STACK_OF_X509_CRL *try_load_crls_by_certs(GSList *certs_with_path); ++gint check_chain_parameters(const STACK_OF_X509 *chain, ++ const ASN1_OCTET_STRING *skid, GError **err); ++X509_NAME *c2b_name(const X509_NAME *name); ++ ++STACK_OF_X509 *delete_ibm_signing_certs(STACK_OF_X509 *certs); ++STACK_OF_X509_CRL *store_ctx_find_valid_crls(X509_STORE_CTX *ctx, X509 *cert, ++ GError **err); ++X509_STORE_CTX *create_store_ctx(X509_STORE *trusted, STACK_OF_X509 *chain, ++ GError **err); ++gint verify_cert(X509 *cert, X509_STORE_CTX *ctx, GError **err); ++X509_CRL *get_first_valid_crl(X509_STORE_CTX *ctx, X509 *cert, GError **err); ++void store_setup_crl_download(X509_STORE *st); ++EVP_PKEY *read_ec_pubkey_cert(X509 *cert, gint nid, GError **err); ++ + Buffer *compute_exchange_key(EVP_PKEY *cust, EVP_PKEY *host, GError **err); + Buffer *generate_aes_key(guint size, GError **err); + Buffer *generate_aes_iv(guint size, GError **err); +Index: s390-tools-service/genprotimg/src/utils/curl.c +=================================================================== +--- /dev/null ++++ s390-tools-service/genprotimg/src/utils/curl.c +@@ -0,0 +1,121 @@ ++/* ++ * Libcurl utils ++ * ++ * Copyright IBM Corp. 2020 ++ * ++ * 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 ++ ++#include "lib/zt_common.h" ++#include "pv/pv_error.h" ++ ++#include "curl.h" ++ ++struct UserData { ++ GByteArray *buffer; ++ guint max_size; ++}; ++ ++static size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata) ++{ ++ g_assert(userdata); ++ struct UserData *data = (struct UserData *)userdata; ++ GByteArray *buffer = data->buffer; ++ guint64 actual_size; ++ size_t err; ++ ++ g_assert(buffer); ++ ++ if (!g_uint64_checked_mul(&actual_size, size, nmemb)) ++ g_abort(); ++ ++ /* Signal an error condition by returning a amount that differs ++ * from the amount passed to the callback. This results in a ++ * CURLE_WRITE_ERROR. ++ */ ++ err = actual_size + 1; ++ ++ if (actual_size > G_MAXUINT) ++ return err; ++ ++ data->buffer = g_byte_array_append(buffer, (guchar *)ptr, (guint)actual_size); ++ if (data->buffer->len > data->max_size) ++ return err; ++ ++ return actual_size; ++} ++ ++gint curl_init(void) ++{ ++ if (curl_global_init(CURL_GLOBAL_ALL) != 0) ++ return -1; ++ return 0; ++} ++ ++void curl_cleanup(void) ++{ ++ curl_global_cleanup(); ++} ++ ++GByteArray *curl_download(const gchar *url, long timeout_ms, guint max_size, ++ GError **err) ++{ ++ g_autoptr(GByteArray) ret = NULL; ++ g_autoptr(CURL) handle = NULL; ++ g_autofree gchar *agent = NULL; ++ struct UserData userdata; ++ CURLcode rc; ++ ++ /* set up curl session */ ++ handle = curl_easy_init(); ++ if (!handle) ++ g_abort(); ++ ++ /* follow redirection */ ++ rc = curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1l); ++ if (rc != CURLE_OK) ++ goto curl_err; ++ rc = curl_easy_setopt(handle, CURLOPT_TIMEOUT_MS, timeout_ms); ++ if (rc != CURLE_OK) ++ goto curl_err; ++ rc = curl_easy_setopt(handle, CURLOPT_NOSIGNAL, 1l); ++ if (rc != CURLE_OK) ++ goto curl_err; ++ agent = g_strdup_printf("%s/%s", tool_name, RELEASE_STRING); ++ rc = curl_easy_setopt(handle, CURLOPT_USERAGENT, agent); ++ if (rc != CURLE_OK) ++ goto curl_err; ++ rc = curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_callback); ++ if (rc != CURLE_OK) ++ goto curl_err; ++ ret = g_byte_array_new(); ++ userdata.buffer = ret; ++ userdata.max_size = max_size; ++ rc = curl_easy_setopt(handle, CURLOPT_WRITEDATA, (void *)&userdata); ++ if (rc != CURLE_OK) ++ goto curl_err; ++ rc = curl_easy_setopt(handle, CURLOPT_URL, url); ++ if (rc != CURLE_OK) ++ goto curl_err; ++ ++ rc = curl_easy_perform(handle); ++ if (rc != CURLE_OK) { ++ g_set_error(err, PV_ERROR, PV_ERROR_DOWNLOAD_FAILED, ++ _("download failed: %s"), curl_easy_strerror(rc)); ++ return NULL; ++ } ++ ++ return g_steal_pointer(&ret); ++curl_err: ++ g_set_error(err, PV_ERROR, ++ PV_ERROR_CURL_INIT_FAILED, ++ _("cURL initialization failed: %s"), ++ curl_easy_strerror(rc)); ++ return NULL; ++} +Index: s390-tools-service/genprotimg/src/utils/curl.h +=================================================================== +--- /dev/null ++++ s390-tools-service/genprotimg/src/utils/curl.h +@@ -0,0 +1,25 @@ ++/* ++ * Libcurl utils ++ * ++ * Copyright IBM Corp. 2020 ++ * ++ * s390-tools is free software; you can redistribute it and/or modify ++ * it under the terms of the MIT license. See LICENSE for details. ++ */ ++ ++#ifndef PV_UTILS_LIBCURL_H ++#define PV_UTILS_LIBCURL_H ++ ++#include ++#include ++ ++#include "common.h" ++ ++WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(CURL, curl_easy_cleanup) ++ ++GByteArray *curl_download(const gchar *url, long timeout_ms, guint max_size, ++ GError **err); ++gint curl_init(void); ++void curl_cleanup(void); ++ ++#endif /* PV_UTILS_LIBCURL_H */ diff --git a/s390-tools-sles15sp3-Allow-multiple-device-arguments.patch b/s390-tools-sles15sp3-Allow-multiple-device-arguments.patch new file mode 100644 index 0000000..a8b114a --- /dev/null +++ b/s390-tools-sles15sp3-Allow-multiple-device-arguments.patch @@ -0,0 +1,473 @@ +From d6582bbaf0f3986a42f562046dc0caa9de89c75e Mon Sep 17 00:00:00 2001 +From: Hannes Reinecke +Date: Fri, 6 Oct 2017 08:58:17 +0200 +Subject: [PATCH] dasdfmt: Allow multiple device arguments + +Allow the user to specify several devices as arguments to dasdfmt. + +Signed-off-by: Hannes Reinecke +--- + dasdfmt/dasdfmt.8 | 5 +- + dasdfmt/dasdfmt.c | 175 ++++++++++++++++++++++++++++++------------------------ + 2 files changed, 100 insertions(+), 80 deletions(-) + +diff --git a/dasdfmt/dasdfmt.8 b/dasdfmt/dasdfmt.8 +index 99da9ed..e7fc501 100644 +--- a/dasdfmt/dasdfmt.8 ++++ b/dasdfmt/dasdfmt.8 +@@ -11,14 +11,15 @@ dasdfmt \- formatting of DASD (ECKD) disk drives. + .br + [-r \fIcylinder\fR] [-b \fIblksize\fR] [-l \fIvolser\fR] [-d \fIlayout\fR] + .br +- [-L] [-V] [-F] [-k] [-C] [-M \fImode\fR] \fIdevice\fR ++ [-L] [-V] [-F] [-k] [-C] [-M \fImode\fR] \fIdevice\fR [\fIdevice\fR] + + .SH DESCRIPTION +-\fBdasdfmt\fR formats a DASD (ECKD) disk drive to prepare it ++\fBdasdfmt\fR formats one or several DASD (ECKD) disk drive to prepare it + for usage with Linux for S/390. + The \fIdevice\fR is the node of the device (e.g. '/dev/dasda'). + Any device node created by udev for kernel 2.6 can be used + (e.g. '/dev/dasd/0.0.b100/disc'). ++It is possible to specify up to 512 devices. + .br + + \fBWARNING\fR: Careless usage of \fBdasdfmt\fR can result in +--- s390-tools-2.15.1/dasdfmt/dasdfmt.c 2020-10-30 20:43:30.853044638 +0000 ++++ s390-tools-2.15.1/dasdfmt/dasdfmt.c 2020-11-17 23:38:56.457778633 +0000 +@@ -25,6 +25,8 @@ + + #include "dasdfmt.h" + ++#define MAX_DEVICES 512 ++#define MAX_LENGTH 256 + #define BUSIDSIZE 8 + #define SEC_PER_DAY (60 * 60 * 24) + #define SEC_PER_HOUR (60 * 60) +@@ -57,7 +59,9 @@ + static struct dasdfmt_globals { + dasd_information2_t dasd_info; + char *dev_path; /* device path entered by user */ ++ char dev_path_array[MAX_DEVICES][MAX_LENGTH]; /* Array of device paths entered by user */ + char *dev_node; /* reliable device node determined by dasdfmt */ ++ char dev_node_array[MAX_DEVICES][MAX_LENGTH]; /* Array of reliable device nodes determined by dasdfmt */ + int verbosity; + int testmode; + int withoutprompt; +@@ -484,15 +488,15 @@ + program_interrupt_in_progress = 1; + + if (disk_disabled) { +- printf("Re-accessing the device...\n"); ++ printf("Re-accessing %s...\n", g.dev_path); + disk_enable(); + } + +- printf("Rereading the partition table...\n"); ++ printf("Rereading the partition table for %s...\n", g.dev_path); + rc = dasd_reread_partition_table(g.dev_node, 5); + if (rc) { + ERRMSG("%s: (signal handler) Re-reading partition table " +- "failed. (%s)\n", prog_name, strerror(rc)); ++ "for %s failed. (%s)\n", prog_name, g.dev_path, strerror(rc)); + } else { + printf("Exiting...\n"); + } +@@ -512,9 +516,6 @@ + unsigned int maj, min; + struct stat dev_stat; + +- if (optind + 1 < argc) +- error("More than one device specified!"); +- + if (optind >= argc) + error("No device specified!"); + +@@ -610,10 +611,10 @@ + error("the ioctl call to retrieve read/write status information failed: %s", + strerror(err)); + if (ro) +- error("Disk is read only!"); ++ error("Disk %s is read only!", g.dev_path); + if (!g.force) { + if (g.dasd_info.open_count > 1) +- error("Disk in use!"); ++ error("Disk %s is in use!", g.dev_path); + } + if (strncmp(g.dasd_info.type, "ECKD", 4) != 0) { + warnx("Unsupported disk type"); +@@ -700,7 +701,7 @@ + struct dasd_eckd_characteristics *characteristics; + + if (g.verbosity > 0) +- printf("Retrieving disk geometry...\n"); ++ printf("Retrieving disk geometry for %s...\n", g.dev_path); + + characteristics = (struct dasd_eckd_characteristics *) + &g.dasd_info.characteristics; +@@ -728,13 +729,13 @@ + "Cylinders above this limit will not be" + " accessible as a linux partition!\n" + "Type \"yes\" to continue, no will leave" +- " the disk untouched: ", LV_COMPAT_CYL); ++ " the %s disk untouched: ", LV_COMPAT_CYL, g.dev_path); + if (fgets(inp_buffer, sizeof(inp_buffer), stdin) == NULL) + return; + if (strcasecmp(inp_buffer, "yes") && + strcasecmp(inp_buffer, "yes\n")) { +- printf("Omitting ioctl call (disk will " +- "NOT be formatted).\n"); ++ printf("Omitting ioctl call (disk %s will " ++ "NOT be formatted).\n", g.dev_path); + return; + } + } +@@ -872,7 +873,7 @@ + check_params->start_unit = 0; + check_params->stop_unit = (cylinders * heads) - 1; + +- printf("Checking format of the entire disk...\n"); ++ printf("Checking format of the entire %s disk...\n", g.dev_path); + + if (g.testmode) { + printf("Test mode active, omitting ioctl.\n"); +@@ -896,7 +897,7 @@ + if (process_tracks(cylinders, heads, check_params)) + error("Use --mode=full to perform a clean format."); + +- printf("Done. Disk is fine.\n"); ++ printf("Done. Disk %s is fine.\n", g.dev_path); + } + + /* +@@ -946,8 +947,8 @@ + + printf("Device Type: %s Provisioned\n", + g.ese ? "Thinly" : "Fully"); +- printf("\nI am going to format the device "); +- printf("%s in the following way:\n", g.dev_path); ++ printf("\nI am going to format %s ", g.dev_path); ++ printf("in the following way:\n"); + printf(" Device number of device : 0x%x\n", g.dasd_info.devno); + printf(" Labelling device : %s\n", + (g.writenolabel) ? "no" : "yes"); +@@ -1012,7 +1013,7 @@ + int ipl1_record_len, ipl2_record_len; + + if (g.verbosity > 0) +- printf("Retrieving dasd information... "); ++ printf("Retrieving dasd information for %s... ", g.dev_path); + + get_blocksize(&blksize); + +@@ -1030,7 +1031,7 @@ + + /* write empty bootstrap (initial IPL records) */ + if (g.verbosity > 0) +- printf("Writing empty bootstrap...\n"); ++ printf("Writing empty bootstrap to %s...\n", g.dev_path); + + /* + * Note: ldl labels do not contain the key field +@@ -1089,7 +1090,7 @@ + label_position = g.dasd_info.label_block * blksize; + + if (g.verbosity > 0) +- printf("Writing label...\n"); ++ printf("Writing label to %s...\n", g.dev_path); + + rc = lseek(fd, label_position, SEEK_SET); + if (rc != label_position) { +@@ -1120,7 +1121,7 @@ + } + + if (g.verbosity > 0) +- printf("Writing VTOC... "); ++ printf("Writing VTOC to %s... ", g.dev_path); + + label_position = (VTOC_START_CC * heads + VTOC_START_HH) * + geo.sectors * blksize; +@@ -1242,7 +1243,7 @@ + if (!g.ese || g.no_discard) + return; + +- printf("Releasing space for the entire device...\n"); ++ printf("Releasing space for the entire %s device...\n", g.dev_path); + err = dasd_release_space(g.dev_node, &r); + if (err) + error("Could not release space: %s", strerror(err)); +@@ -1261,20 +1262,21 @@ + int err; + + if (!(g.withoutprompt && g.verbosity < 1)) +- printf("Formatting the device. This may take a while " +- "(get yourself a coffee).\n"); ++ printf("Formatting the %s device. This may take a while " ++ "(get yourself a coffee).\n", g.dev_path); + + if (g.verbosity > 0) +- printf("Detaching the device...\n"); ++ printf("Detaching the %s device...\n", g.dev_path); + + disk_disable(g.dev_node); + + if (g.verbosity > 0) +- printf("Invalidate first track...\n"); ++ printf("Invalidate first track on %s...\n", g.dev_path); + + err = dasd_format_disk(filedes, &temp); + if (err != 0) +- error("(invalidate first track) IOCTL BIODASDFMT failed: %s", strerror(err)); ++ error("(invalidate first track) IOCTL BIODASDFMT failed for %s: %s", ++ g.dev_path, strerror(err)); + + /* except track 0 from standard formatting procss */ + p->start_unit = 1; +@@ -1282,19 +1284,19 @@ + process_tracks(cylinders, heads, p); + + if (g.verbosity > 0) +- printf("formatting tracks complete...\n"); ++ printf("formatting tracks for %s complete...\n", g.dev_path); + + temp.intensity = p->intensity; + + if (g.verbosity > 0) +- printf("Revalidate first track...\n"); ++ printf("Revalidate first track on %s...\n", g.dev_path); + + err = dasd_format_disk(filedes, &temp); + if (err != 0) + error("(re-validate first track) IOCTL BIODASDFMT failed: %s", strerror(err)); + + if (g.verbosity > 0) +- printf("Re-accessing the device...\n"); ++ printf("Re-accessing the %s device...\n", g.dev_path); + + disk_enable(); + } +@@ -1306,18 +1308,18 @@ + format_data_t *p) + { + if (!(g.withoutprompt && g.verbosity < 1)) +- printf("Formatting the device. This may take a while " +- "(get yourself a coffee).\n"); ++ printf("Formatting the %s device. This may take a while " ++ "(get yourself a coffee).\n", g.dev_path); + + if (g.verbosity > 0) +- printf("Detaching the device...\n"); ++ printf("Detaching the %s device...\n", g.dev_path); + + disk_disable(g.dev_node); + + process_tracks(cylinders, heads, p); + + if (g.verbosity > 0) +- printf("Formatting tracks complete...\n"); ++ printf("formatting tracks for %s complete...\n", g.dev_path); + + if (g.verbosity > 0) + printf("Re-accessing the device...\n"); +@@ -1426,16 +1428,16 @@ + if (!g.withoutprompt) { + printf("\n"); + if (mode != EXPAND) +- printf("--->> ATTENTION! <<---\nAll data of " +- "that device will be lost.\n"); ++ printf("--->> ATTENTION! <<---\nAll data on " ++ "the %s device will be lost.\n", g.dev_path); + printf("Type \"yes\" to continue, no will leave the " + "disk untouched: "); + if (fgets(inp_buffer, sizeof(inp_buffer), stdin) == NULL) + return; + if (strcasecmp(inp_buffer, "yes") && + strcasecmp(inp_buffer, "yes\n")) { +- printf("Omitting ioctl call (disk will " +- "NOT be formatted).\n"); ++ printf("Omitting ioctl call (disk %s will " ++ "NOT be formatted).\n", g.dev_path); + return; + } + } +@@ -1453,12 +1455,12 @@ + break; + } + +- printf("Finished formatting the device.\n"); ++ printf("Finished formatting the %s device.\n", g.dev_path); + + if (!(g.writenolabel || mode == EXPAND)) + dasdfmt_write_labels(vlabel, cylinders, heads); + +- printf("Rereading the partition table... "); ++ printf("Rereading the partition table for %s... ", g.dev_path); + err = dasd_reread_partition_table(g.dev_node, 5); + if (err != 0) { + ERRMSG("%s: error during rereading the partition " +@@ -1472,7 +1473,7 @@ + static void eval_format_mode(void) + { + if (!g.force && g.mode_specified && g.ese && mode == EXPAND) { +- warnx("WARNING: The specified device is thin-provisioned"); ++ warnx("WARNING: The specified device, %s, is thin-provisioned", g.dev_path); + warnx("Format mode 'expand' is not feasible."); + error("Use --mode=full or --mode=quick to perform a clean format"); + } +@@ -1495,20 +1496,70 @@ + prog_name = p + 1; + } + ++void process_dasd(volume_label_t *orig_vlabel, format_data_t format_params) ++{ ++ volume_label_t vlabel; ++ char old_volser[7]; ++ char str[ERR_LENGTH]; ++ unsigned int cylinders, heads; int rc; ++ ++ rc = dasd_get_info(g.dev_node, &g.dasd_info); ++ if (rc != 0) ++ error("the ioctl call to retrieve device information failed: %s", strerror(rc)); ++ ++ g.ese = dasd_sys_ese(g.dev_node); ++ eval_format_mode(); ++ ++ /* Not sure this next line is needed in the new version of the code. */ ++ memcpy(&vlabel, orig_vlabel, sizeof(vlabel)); ++ ++ /* Either let the user specify the blksize or get it from the kernel */ ++ if (!g.blksize_specified) { ++ if (!(mode == FULL || ++ g.dasd_info.format == DASD_FORMAT_NONE) || g.check) ++ get_blocksize(&format_params.blksize); ++ else ++ format_params = ask_user_for_blksize(format_params); ++ } ++ ++ if (g.keep_volser) { ++ if (g.labelspec) ++ error("The -k and -l options are mutually exclusive"); ++ if (!(format_params.intensity & DASD_FMT_INT_COMPAT)) ++ error("WARNING: VOLSER cannot be kept when using the ldl format!"); ++ ++ if (dasdfmt_get_volser(old_volser) == 0) ++ vtoc_volume_label_set_volser(&vlabel, old_volser); ++ else ++ error("VOLSER not found on device %s", g.dev_path); ++ } ++ ++ check_disk(); ++ ++ if (check_param(str, ERR_LENGTH, &format_params) < 0) ++ error("%s", str); ++ ++ set_geo(&cylinders, &heads); ++ set_label(&vlabel, &format_params, cylinders); ++ ++ if (g.check) ++ check_disk_format(cylinders, heads, &format_params); ++ else ++ do_format_dasd(&vlabel, &format_params, cylinders, heads); ++ ++} ++ + int main(int argc, char *argv[]) + { + volume_label_t vlabel; +- char old_volser[7]; + +- char str[ERR_LENGTH]; + char buf[7]; + + char *blksize_param_str = NULL; + char *reqsize_param_str = NULL; + char *hashstep_str = NULL; + +- int rc; +- unsigned int cylinders, heads; ++ int rc, numdev = 0, i; + + /* Establish a handler for interrupt signals. */ + signal(SIGTERM, program_interrupt_signal); +@@ -1644,6 +1695,9 @@ + break; /* exit loop if finished */ + } + ++ /* Reset the value of rc since we're going to use it again later. */ ++ rc = 0; ++ + CHECK_SPEC_MAX_ONCE(g.blksize_specified, "blocksize"); + CHECK_SPEC_MAX_ONCE(g.labelspec, "label"); + CHECK_SPEC_MAX_ONCE(g.writenolabel, "omit-label-writing flag"); +@@ -1662,49 +1716,29 @@ + if (g.print_hashmarks) + PARSE_PARAM_INTO(g.hashstep, hashstep_str, 10, "hashstep"); + +- get_device_name(optind, argc, argv); +- +- rc = dasd_get_info(g.dev_node, &g.dasd_info); +- if (rc != 0) +- error("the ioctl call to retrieve device information failed: %s", strerror(rc)); +- +- g.ese = dasd_sys_ese(g.dev_node); +- eval_format_mode(); +- +- /* Either let the user specify the blksize or get it from the kernel */ +- if (!g.blksize_specified) { +- if (!(mode == FULL || +- g.dasd_info.format == DASD_FORMAT_NONE) || g.check) +- get_blocksize(&format_params.blksize); +- else +- format_params = ask_user_for_blksize(format_params); +- } +- +- if (g.keep_volser) { +- if (g.labelspec) +- error("The -k and -l options are mutually exclusive"); +- if (!(format_params.intensity & DASD_FMT_INT_COMPAT)) +- error("WARNING: VOLSER cannot be kept when using the ldl format!"); +- +- if (dasdfmt_get_volser(old_volser) == 0) +- vtoc_volume_label_set_volser(&vlabel, old_volser); +- else +- error("VOLSER not found on device %s", g.dev_path); +- } +- +- check_disk(); +- +- if (check_param(str, ERR_LENGTH, &format_params) < 0) +- error("%s", str); +- +- set_geo(&cylinders, &heads); +- set_label(&vlabel, &format_params, cylinders); +- +- if (g.check) +- check_disk_format(cylinders, heads, &format_params); +- else +- do_format_dasd(&vlabel, &format_params, cylinders, heads); ++ while (optind < argc) { ++ get_device_name(optind, argc, argv); ++ strncpy(g.dev_path_array[numdev], g.dev_path, strlen(g.dev_path)); ++ strncpy(g.dev_node_array[numdev], g.dev_node, strlen(g.dev_node)); ++ ++ optind++; ++ numdev++; ++ } ++ ++ if (!numdev) ++ error("%s: No device specified!\n", ++ prog_name); ++ ++ if (numdev > 1 && g.labelspec) ++ error("Specifying a volser to be written doesn't make sense when formatting multiple DASD volumes."); ++ ++ for (i = 0; i < numdev; i++) ++ { ++ strncpy(g.dev_path, g.dev_path_array[i], strlen(g.dev_path_array[i])+1); ++ strncpy(g.dev_node, g.dev_node_array[i], strlen(g.dev_node_array[i])+1); ++ process_dasd(&vlabel, format_params); ++ } + + free(g.dev_path); + free(g.dev_node); + diff --git a/s390-tools-sles15-Format-devices-in-parallel.patch b/s390-tools-sles15sp3-Format-devices-in-parallel.patch similarity index 66% rename from s390-tools-sles15-Format-devices-in-parallel.patch rename to s390-tools-sles15sp3-Format-devices-in-parallel.patch index 9d773dd..da0eb26 100644 --- a/s390-tools-sles15-Format-devices-in-parallel.patch +++ b/s390-tools-sles15sp3-Format-devices-in-parallel.patch @@ -53,11 +53,9 @@ index e7fc501..07c674b 100644 \fB-l\fR \fIvolser\fR or \fB--label\fR=\fIvolser\fR Specify the volume serial number or volume identifier to be written to disk after formatting. If no label is specified, a sensible default -diff --git a/dasdfmt/dasdfmt.c b/dasdfmt/dasdfmt.c -index 607fd1c..6dd28fa 100644 ---- a/dasdfmt/dasdfmt.c -+++ b/dasdfmt/dasdfmt.c -@@ -12,6 +12,7 @@ +--- s390-tools-2.15.1/dasdfmt/dasdfmt.c 2020-12-04 23:22:51.418265761 +0100 ++++ s390-tools-2.15.1/dasdfmt/dasdfmt.c 2020-12-04 23:29:26.165601000 +0100 +@@ -13,6 +13,7 @@ #include #include #include @@ -65,7 +63,15 @@ index 607fd1c..6dd28fa 100644 #include "lib/dasd_base.h" #include "lib/dasd_sys.h" -@@ -71,6 +72,11 @@ static struct util_opt opt_vec[] = { +@@ -81,6 +82,7 @@ + int mode_specified; + int ese; + int no_discard; ++ int procnum; + } g = { + .dasd_info = { 0 }, + }; +@@ -105,6 +107,11 @@ .desc = "Perform complete format check on device", .flags = UTIL_OPT_FLAG_NOSHORT, }, @@ -77,7 +83,7 @@ index 607fd1c..6dd28fa 100644 UTIL_OPT_SECTION("FORMAT OPTIONS"), { .option = { "blocksize", required_argument, NULL, 'b' }, -@@ -128,7 +134,7 @@ static struct util_opt opt_vec[] = { +@@ -162,7 +170,7 @@ .desc = "Show a progressbar", }, { @@ -86,74 +92,71 @@ index 607fd1c..6dd28fa 100644 .desc = "Show progress in percent", }, UTIL_OPT_SECTION("MISC"), -@@ -262,7 +268,7 @@ static void draw_progress(dasdfmt_info_t *info, int cyl, unsigned int cylinders, - - if (info->print_hashmarks && - (cyl / info->hashstep - hashcount) != 0) { -- printf("#"); -+ printf("%d|", info->procnum); - fflush(stdout); - hashcount++; - } -@@ -1587,7 +1593,8 @@ int main(int argc, char *argv[]) +@@ -297,7 +305,7 @@ + p_old = p_new; + barlength = cyl * 33 / cylinders; + for (i = 1; i <= barlength; i++) +- printf("#"); ++ printf("%d|", g.procnum); + for (i = barlength + 1; i <= 33; i++) + printf("-"); + printf("|%3d%%", p_new); +@@ -1560,7 +1568,11 @@ char *reqsize_param_str = NULL; char *hashstep_str = NULL; - int rc, numdev = 0, i; -+ int max_parallel = 1, running = 0; -+ int rc, numdev = 0, i, status; ++ int rc, numdev = 0, numproc = 0, status; ++ int max_parallel =1 ; ++ int running = 0; ++ int chpid; ++ int tmp; /* Establish a handler for interrupt signals. */ signal(SIGTERM, program_interrupt_signal); -@@ -1652,7 +1659,7 @@ int main(int argc, char *argv[]) - info.print_hashmarks = 1; +@@ -1623,7 +1635,7 @@ + g.print_hashmarks = 1; } break; - case 'P': + case 'Q': - if (!(info.print_hashmarks || info.print_progressbar)) - info.print_percentage = 1; + if (!(g.print_hashmarks || g.print_progressbar)) + g.print_percentage = 1; break; -@@ -1714,6 +1721,9 @@ int main(int argc, char *argv[]) +@@ -1682,6 +1694,9 @@ case OPT_NODISCARD: - info.no_discard = 1; + g.no_discard = 1; break; + case 'P': + max_parallel = atoi(optarg); + break; case OPT_CHECK: - info.check = 1; + g.check = 1; break; -@@ -1729,6 +1739,9 @@ - break; /* exit loop if finished */ - } +@@ -1733,15 +1748,35 @@ + if (numdev > 1 && g.labelspec) + error("Specifying a volser to be written doesn't make sense when formatting multiple DASD volumes."); -+ /* Reset the value of rc since we're going to use it again later. */ -+ rc = 0; -+ - CHECK_SPEC_MAX_ONCE(info.blksize_specified, "blocksize"); - CHECK_SPEC_MAX_ONCE(info.labelspec, "label"); - CHECK_SPEC_MAX_ONCE(info.writenolabel, "omit-label-writing flag"); -@@ -1766,7 +1779,33 @@ int main(int argc, char *argv[]) - ERRMSG_EXIT(EXIT_MISUSE, "%s: No device specified!\n", - prog_name); - - for (i = 0; i < numdev; i++) -- do_dasdfmt(dev_filename[i], info, &vlabel, format_params); -- return 0; -+ for (i = 0; i < numdev; i++) { -+ int chpid; -+ int tmp; -+ +- { +- strncpy(g.dev_path, g.dev_path_array[i], strlen(g.dev_path_array[i])+1); +- strncpy(g.dev_node, g.dev_node_array[i], strlen(g.dev_node_array[i])+1); +- process_dasd(&vlabel, format_params); ++ for (numproc = 0; numproc < numdev; numproc++) { + chpid = fork(); -+ if (chpid == -1) ++ if (chpid == -1 ) + ERRMSG_EXIT(EXIT_FAILURE, -+ "%s: Unable to create child process: %s\n", -+ prog_name, strerror(errno)); ++ "%s: Unable to create child process: %s\n", ++ prog_name, strerror(errno)); + if (!chpid) { -+ info.procnum = i; -+ do_dasdfmt(dev_filename[i], info, &vlabel, format_params); -+ exit(0); ++ g.procnum = numproc; ++ strncpy(g.dev_path, g.dev_path_array[numproc], strlen(g.dev_path_array[numproc])+1); ++ strncpy(g.dev_node, g.dev_node_array[numproc], strlen(g.dev_node_array[numproc])+1); ++ process_dasd(&vlabel, format_params); ++ ++ free(g.dev_path); ++ free(g.dev_node); ++ exit(0); + } else { + running++; + if (running >= max_parallel) { @@ -162,27 +165,15 @@ index 607fd1c..6dd28fa 100644 + running--; + } + } -+ } -+ + } + +- free(g.dev_path); +- free(g.dev_node); + /* wait until all formatting children have finished */ + while(wait(&status) > 0) + if (WEXITSTATUS(status)) + rc = WEXITSTATUS(status); -+ -+ return rc; + +- return 0; ++ return rc; } -diff --git a/dasdfmt/dasdfmt.h b/dasdfmt/dasdfmt.h -index a5581f1..fb6fc34 100644 ---- a/dasdfmt/dasdfmt.h -+++ b/dasdfmt/dasdfmt.h -@@ -95,6 +95,7 @@ typedef struct dasdfmt_info { - int mode_specified; - int ese; - int no_discard; -+ int procnum; - } dasdfmt_info_t; - - --- -1.7.12.4 - diff --git a/s390-tools-sles15-Implement-Y-yast_mode.patch b/s390-tools-sles15sp3-Implement-Y-yast_mode.patch similarity index 52% rename from s390-tools-sles15-Implement-Y-yast_mode.patch rename to s390-tools-sles15sp3-Implement-Y-yast_mode.patch index 436b148..e13bd6b 100644 --- a/s390-tools-sles15-Implement-Y-yast_mode.patch +++ b/s390-tools-sles15sp3-Implement-Y-yast_mode.patch @@ -41,7 +41,15 @@ diff --git a/dasdfmt/dasdfmt.c b/dasdfmt/dasdfmt.c index 6dd28fa..5b6023a 100644 --- a/dasdfmt/dasdfmt.c +++ b/dasdfmt/dasdfmt.c -@@ -137,6 +137,10 @@ static struct util_opt opt_vec[] = { +@@ -83,6 +83,7 @@ static struct dasdfmt_globals { + int ese; + int no_discard; + int procnum; ++ int yast_mode; + } g = { + .dasd_info = { 0 }, + }; +@@ -172,6 +173,10 @@ static struct util_opt opt_vec[] = { .option = { "percentage", no_argument, NULL, 'Q' }, .desc = "Show progress in percent", }, @@ -52,93 +60,61 @@ index 6dd28fa..5b6023a 100644 UTIL_OPT_SECTION("MISC"), { .option = { "check_host_count", no_argument, NULL, 'C' }, -@@ -343,7 +347,8 @@ static void evaluate_format_error(dasdfmt_info_t *info, format_check_t *cdata, +@@ -392,7 +397,7 @@ static void evaluate_format_error(format unsigned int kl = 0; int blksize = cdata->expect.blksize; -- if (info->print_progressbar || info->print_hashmarks) -+ if ((info->print_progressbar || info->print_hashmarks) && -+ !info->yast_mode) +- if (g.print_progressbar || g.print_hashmarks) ++ if ((g.print_progressbar || g.print_hashmarks) && !g.yast_mode) printf("\n"); /* -@@ -749,9 +754,9 @@ static void check_hashmarks(dasdfmt_info_t *info) - "using the default.\n"); - info->hashstep = 10; +@@ -780,8 +785,9 @@ static void check_hashmarks(void) + g.hashstep = 10; } -- + - printf("Printing hashmark every %d cylinders.\n", -- info->hashstep); -+ if (!info->yast_mode) +- g.hashstep); ++ if (!g.yast_mode) + printf("Printing hashmark every %d cylinders.\n", -+ info->hashstep); ++ g.hashstep); } } -@@ -985,7 +990,7 @@ static int dasdfmt_get_volser(char *devn - /* - * do all the labeling (volume label and initial VTOC) - */ --static void dasdfmt_write_labels(dasdfmt_info_t *info, volume_label_t *vlabel, -+static void dasdfmt_write_labels(dasdfmt_info_t *info, char *dev_filename, volume_label_t *vlabel, - unsigned int cylinders, unsigned int heads) - { - int label_position; -@@ -1483,17 +1488,19 @@ static void do_format_dasd(dasdfmt_info_t *info, char *devname, +@@ -1462,17 +1468,19 @@ static void do_format_dasd(volume_label_ break; } -- printf("Finished formatting the device.\n"); -+ if (!info->yast_mode) -+ printf("Finished formatting the device.\n"); +- printf("Finished formatting the %s device.\n", g.dev_path); ++ if (!g.yast_mode) ++ printf("Finished formatting the %s device.\n", g.dev_path); - if (!(info->writenolabel || mode == EXPAND)) - dasdfmt_write_labels(info, devname, vlabel, cylinders, heads); + if (!(g.writenolabel || mode == EXPAND)) + dasdfmt_write_labels(vlabel, cylinders, heads); -- printf("Rereading the partition table... "); -+ if (!info->yast_mode) -+ printf("Rereading the partition table... "); - err = dasd_reread_partition_table(devname, 5); +- printf("Rereading the partition table for %s... ", g.dev_path); ++ if (!g.yast_mode) ++ printf("Rereading the partition table for %s... ", g.dev_path); + err = dasd_reread_partition_table(g.dev_node, 5); if (err != 0) { ERRMSG("%s: error during rereading the partition " "table: %s.\n", prog_name, strerror(err)); - } else { -+ } else if (!info->yast_mode) { ++ } else if (!g.yast_mode) { printf("ok\n"); } } -@@ -1569,6 +1576,8 @@ void do_dasdfmt(char *dev_filename, dasdfmt_info_t *info, - ERRMSG_EXIT(EXIT_MISUSE, "%s: %s\n", prog_name, str); - - set_geo(&info, &cylinders, &heads); -+ if (info.yast_mode) -+ printf("%d\n", cylinders); - set_label(&info, &vlabel, &format_params, cylinders); - - if (info.check) -@@ -1721,6 +1730,10 @@ int main(int argc, char *argv[]) +@@ -1693,6 +1701,10 @@ int main(int argc, char *argv[]) case OPT_NODISCARD: - info.no_discard = 1; + g.no_discard = 1; break; + case 'Y': + /* YaST mode */ -+ info.yast_mode = 1; ++ g.yast_mode = 1; + break; case 'P': max_parallel = atoi(optarg); break; -diff --git a/dasdfmt/dasdfmt.h b/dasdfmt/dasdfmt.h -index fb6fc34..fe0cc7f 100644 ---- a/dasdfmt/dasdfmt.h -+++ b/dasdfmt/dasdfmt.h -@@ -96,6 +96,7 @@ typedef struct dasdfmt_info { - int ese; - int no_discard; - int procnum; -+ int yast_mode; - } dasdfmt_info_t; - - -- 1.7.12.4 diff --git a/s390-tools-sles15-Implement-f-for-backwards-compability.patch b/s390-tools-sles15sp3-Implement-f-for-backwards-compability.patch similarity index 85% rename from s390-tools-sles15-Implement-f-for-backwards-compability.patch rename to s390-tools-sles15sp3-Implement-f-for-backwards-compability.patch index 7a50f3c..19f4367 100644 --- a/s390-tools-sles15-Implement-f-for-backwards-compability.patch +++ b/s390-tools-sles15sp3-Implement-f-for-backwards-compability.patch @@ -41,28 +41,29 @@ diff --git a/dasdfmt/dasdfmt.c b/dasdfmt/dasdfmt.c index 5b6023a..cdd80df 100644 --- a/dasdfmt/dasdfmt.c +++ b/dasdfmt/dasdfmt.c -@@ -77,6 +77,10 @@ static struct util_opt opt_vec[] = { +@@ -113,6 +113,10 @@ .desc = "Format devices in parallel", .flags = UTIL_OPT_FLAG_NOLONG, }, + { + .option = { "device", required_argument, NULL, 'f' }, -+ .desc = "Spedify device to format", ++ .desc = "Specify device to format", + }, UTIL_OPT_SECTION("FORMAT OPTIONS"), { .option = { "blocksize", required_argument, NULL, 'b' }, -@@ -1649,6 +1653,10 @@ int main(int argc, char *argv[]) +@@ -1623,6 +1627,12 @@ } - info.layout_specified = 1; + g.layout_specified = 1; break; + case 'f': -+ get_device_name(dev_filename, numdev, optarg); ++ get_device_name(optind-1, argc, argv); ++ strncpy(g.dev_path_array[numdev], g.dev_path, strlen(g.dev_path)); ++ strncpy(g.dev_node_array[numdev], g.dev_node, strlen(g.dev_node)); + numdev++; + break; case 'y': - info.withoutprompt = 1; + g.withoutprompt = 1; break; -- 1.7.12.4 - diff --git a/s390-tools-sles15sp3-dasdfmt-Fix-segfault-when-an-incorrect-option-is-spe.patch b/s390-tools-sles15sp3-dasdfmt-Fix-segfault-when-an-incorrect-option-is-spe.patch new file mode 100644 index 0000000..9566601 --- /dev/null +++ b/s390-tools-sles15sp3-dasdfmt-Fix-segfault-when-an-incorrect-option-is-spe.patch @@ -0,0 +1,34 @@ +From 148d3f9b64da599adf453baf65e7a8596e2e7d97 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jan=20H=C3=B6ppner?= +Date: Mon, 2 Nov 2020 09:09:51 +0100 +Subject: [PATCH] dasdfmt: Fix segfault when an incorrect option is specified +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When specifying an incorrect program option, dasdfmt segfaults as the +format string for the corresponding error message has no parameter. +Add the missing parameter to fix this. + +Fixes: 732b3dddab84 ("dasdfmt: Replace ERRMSG_EXIT macro with an error handling function") +Signed-off-by: Jan Höppner +--- + dasdfmt/dasdfmt.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dasdfmt/dasdfmt.c b/dasdfmt/dasdfmt.c +index a424f3c..5665f64 100644 +--- a/dasdfmt/dasdfmt.c ++++ b/dasdfmt/dasdfmt.c +@@ -1637,7 +1637,7 @@ int main(int argc, char *argv[]) + /* End of options string - start of devices list */ + break; + default: +- error("Try '%s --help' for more information."); ++ error("Try '%s --help' for more information.", prog_name); + } + + if (rc == -1) +-- +2.26.2 + diff --git a/dasdfmt-retry-BIODASDINFO-if-device-is-busy.patch b/s390-tools-sles15sp3-dasdfmt-retry-BIODASDINFO-if-device-is-busy.patch similarity index 72% rename from dasdfmt-retry-BIODASDINFO-if-device-is-busy.patch rename to s390-tools-sles15sp3-dasdfmt-retry-BIODASDINFO-if-device-is-busy.patch index 6dd0d83..d0cd974 100644 --- a/dasdfmt-retry-BIODASDINFO-if-device-is-busy.patch +++ b/s390-tools-sles15sp3-dasdfmt-retry-BIODASDINFO-if-device-is-busy.patch @@ -23,21 +23,19 @@ diff --git a/dasdfmt/dasdfmt.c b/dasdfmt/dasdfmt.c index e1877ac..f03cbad 100644 --- a/dasdfmt/dasdfmt.c +++ b/dasdfmt/dasdfmt.c -@@ -580,7 +580,7 @@ +@@ -619,7 +619,7 @@ */ - static void check_disk(dasdfmt_info_t *info, char *devname) + static void check_disk(void) { - int err; + int err, index = 0 ; bool ro; - err = dasd_is_ro(devname, &ro); -@@ -593,9 +593,27 @@ + err = dasd_is_ro(g.dev_node, &ro); +@@ -629,6 +629,23 @@ if (ro) - ERRMSG_EXIT(EXIT_FAILURE, "Disk is read only!\n"); - -- if (!info->force) -+ if (!info->force) { + error("Disk %s is read only!", g.dev_path); + if (!g.force) { + /* + * udev strikes again. + * Modern udev will issue a 'change' event whenever @@ -48,19 +46,16 @@ index e1877ac..f03cbad 100644 + * Bah. + */ + for ( index = 0 ; index < 6 ; index++ ) { -+ if (info->dasd_info.open_count > 1) { -+ dasd_get_info(dev_filename, &info->dasd_info); ++ if (g.dasd_info.open_count > 1) { ++ dasd_get_info(g.dev_node, &g.dasd_info); + sleep(1); + } + else break; + + } - if (info->dasd_info.open_count > 1) - ERRMSG_EXIT(EXIT_BUSY, "Disk in use!\n"); -+ } - - if (strncmp(info->dasd_info.type, "ECKD", 4) != 0) { - ERRMSG_EXIT(EXIT_FAILURE, + if (g.dasd_info.open_count > 1) + error("Disk %s is in use!", g.dev_path); + } -- 1.8.4.5 diff --git a/s390-tools-sles15sp3-hsci-Add-new-tool-to-control-HiperSockets-Converged-.patch b/s390-tools-sles15sp3-hsci-Add-new-tool-to-control-HiperSockets-Converged-.patch new file mode 100644 index 0000000..eff7b6d --- /dev/null +++ b/s390-tools-sles15sp3-hsci-Add-new-tool-to-control-HiperSockets-Converged-.patch @@ -0,0 +1,633 @@ +From ef090dda8333a778cb2d9e7f65ca8021e2ae9e67 Mon Sep 17 00:00:00 2001 +From: Karsten Graul +Date: Tue, 10 Nov 2020 12:07:03 +0100 +Subject: [PATCH] hsci: Add new tool to control HiperSockets Converged + Interfaces +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +hsci is used to control and show HSCI (HiperSockets Converged Interfaces) +settings. A HiperSockets interface and an external network interface are +converged to an HSCI interface. + +Signed-off-by: Alexandra Winter +Signed-off-by: Wenjia Zhang +Reviewed-by: Jan Hoeppner +Signed-off-by: Jan Hoeppner +--- + Makefile | 2 +- + README.md | 3 + + hsci/Makefile | 16 ++ + hsci/hsci | 441 ++++++++++++++++++++++++++++++++++++++++++++++++++ + hsci/hsci.8 | 100 ++++++++++++ + 5 files changed, 561 insertions(+), 1 deletion(-) + create mode 100644 hsci/Makefile + create mode 100755 hsci/hsci + create mode 100644 hsci/hsci.8 + +diff --git a/Makefile b/Makefile +index cc277b8e..cfbbd950 100644 +--- a/Makefile ++++ b/Makefile +@@ -9,7 +9,7 @@ TOOL_DIRS = zipl zdump fdasd dasdfmt dasdview tunedasd \ + vmconvert vmcp man mon_tools dasdinfo vmur cpuplugd ipl_tools \ + ziomon iucvterm hyptop cmsfs-fuse qethqoat zfcpdump zdsfs cpumf \ + systemd hmcdrvfs cpacfstats zdev dump2tar zkey netboot etc zpcictl \ +- genprotimg lsstp ++ genprotimg lsstp hsci + + SUB_DIRS = $(LIB_DIRS) $(TOOL_DIRS) + +diff --git a/README.md b/README.md +index aa2188a5..581353fd 100644 +--- a/README.md ++++ b/README.md +@@ -249,6 +249,9 @@ Package contents + Management Foundation - Web Edition, and is used to manage keys in an + enterprise. + ++ * hsci: ++ Manage HiperSockets Converged Interfaces (HSCI). ++ + For more information refer to the following publications: + + * "Device Drivers, Features, and Commands" chapter "Useful Linux commands" +diff --git a/hsci/Makefile b/hsci/Makefile +new file mode 100644 +index 00000000..6f7474c5 +--- /dev/null ++++ b/hsci/Makefile +@@ -0,0 +1,16 @@ ++include ../common.mak ++ ++all: ++ ++install: hsci ++ $(SED) -e 's/%S390_TOOLS_VERSION%/$(S390_TOOLS_RELEASE)/' \ ++ < hsci >$(DESTDIR)$(BINDIR)/hsci; \ ++ chown $(OWNER).$(GROUP) $(DESTDIR)$(BINDIR)/hsci; \ ++ chmod 755 $(DESTDIR)$(BINDIR)/hsci; \ ++ $(INSTALL) -d -m 755 $(DESTDIR)$(BINDIR) $(DESTDIR)$(MANDIR)/man8 ++ $(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 hsci.8 \ ++ $(DESTDIR)$(MANDIR)/man8 ++ ++clean: ++ ++.PHONY: all install clean +diff --git a/hsci/hsci b/hsci/hsci +new file mode 100755 +index 00000000..9a56aa0d +--- /dev/null ++++ b/hsci/hsci +@@ -0,0 +1,441 @@ ++#!/bin/bash ++# ++# hsci - Tool to manage HiperSockets Converged Interfaces (HSCI) ++# ++# Copyright IBM Corp. 2020 ++# ++# s390-tools is free software; you can redistribute it and/or modify ++# it under the terms of the MIT license. See LICENSE for details. ++# ++ ++hsdev="" ++ndev="" ++hsci="" ++hsdev_mac="" ++hsif_pnetid="" ++netif_pnetid="" ++hsci_pnetid="" ++ ++function usage { ++cat <<-EOD ++Usage: hsci COMMAND [OPTION] ++ ++This tool is designed to control and show HSCI (HiperSockets Converged ++Interfaces) settings. A HiperSockets interface and an external network ++ ++COMMANDS ++ add HIPERSOCKETS_DEV NET_DEV Adds an HSCI interface ++ del HSCI_NAME Deletes an HSCI interface ++ show Lists the configured HSCI interfaces ++ ++OPTIONS: ++ -v, --version Prints the version number of the hsci tool and exits ++ -h, --help Displays the help information for the command ++EOD ++} ++ ++function prereqs_check { ++ if ! [ -x "$(command -v ip)" ]; then ++ echo "Error: No iproute2 installed on this system" >&2 ++ return 1 ++ fi ++} ++ ++function check_pnetids { ++ # get PNETID of the HS ++ local hsif_pnetids="" ++ local netif_pnetids="" ++ ++ if [ -e /sys/class/net/$hsdev/device/util_string ]; then ++ hsif_pnetids="$(cat /sys/class/net/$hsdev/device/util_string | tr -d '\000' | iconv -f IBM-1047 -t ASCII)" ++ else ++ if [ -e /sys/class/net/$hsdev/device/chpid ]; then ++ chpid="$(cat /sys/class/net/$hsdev/device/chpid | tr [:upper:] [:lower:])" ++ hsif_pnetids="$(cat /sys/devices/css0/chp0.$chpid/util_string | tr -d '\000' | iconv -f IBM-1047 -t ASCII)" ++ fi ++ fi ++ if [ "$hsif_pnetids" != "" ]; then ++ port_hsif="$(cat /sys/class/net/$hsdev/dev_port)" ++ (( idx=16*$port_hsif+1 )) ++ (( end=$idx+15 )) ++ hsif_pnetid="$(echo "$hsif_pnetids" | cut -c $idx-$end | tr -d ' ')" ++ fi ++ ++ # get PNETID of the NET_DEV ++ if [ -e /sys/class/net/$ndev/device/util_string ]; then ++ netif_pnetids="$(cat /sys/class/net/$ndev/device/util_string | tr -d '\000' | iconv -f IBM-1047 -t ASCII)" ++ else ++ if [ -e /sys/class/net/$ndev/device/chpid ]; then ++ chpid="$(cat /sys/class/net/$ndev/device/chpid | tr [:upper:] [:lower:])" ++ netif_pnetids="$(cat /sys/devices/css0/chp0.$chpid/util_string | tr -d '\000' | iconv -f IBM-1047 -t ASCII)" ++ fi ++ fi ++ if [ "$netif_pnetids" != "" ]; then ++ port_netif="$(cat /sys/class/net/$ndev/dev_port)" ++ (( idx=16*$port_netif+1 )) ++ (( end=$idx+15 )) ++ netif_pnetid="$(echo "$netif_pnetids" | cut -c $idx-$end | tr -d ' ')" ++ fi ++ ++ #Check PNETIDs ++ if [ "$hsif_pnetid" != "" ] && [ "$netif_pnetid" != "" ] && [ "$netif_pnetid" != "$hsif_pnetid" ]; then ++ echo "Error: $hsdev and $ndev have different PNETIDs! They are $hsif_pnetid and $netif_pnetid respectively" >&2 ++ return 1 ++ fi ++ ++ if [ "$hsif_pnetid" != "" ] && [ "$netif_pnetid" != "" ] && [ "$netif_pnetid" == "$hsif_pnetid" ]; then ++ hsci_pnetid=$hsif_pnetid ++ fi ++} ++ ++function verify_precon { ++ echo "Verifying net dev $ndev and HiperSockets dev $hsdev" ++ ++ if [ ! -e /sys/class/net/$hsdev ]; then ++ echo "Error: $hsdev does not exist" >&2 ++ return 1 ++ fi ++ if [ "$(cat /sys/class/net/$hsdev/device/card_type)" != "HiperSockets" ]; then ++ echo "Error: $hsdev is not a HiperSockets device" >&2 ++ return 1 ++ fi ++ if [ "$(cat /sys/class/net/$hsdev/device/layer2)" != "1" ]; then ++ echo "Error: $hsdev is not in layer 2 mode" >&2 ++ return 1 ++ fi ++ if [ ! -e /sys/class/net/$hsdev/device/vnicc/bridge_invisible ]; then ++ echo "Error: Missing vnic-characteristics support" >&2 ++ return 1 ++ fi ++ if [ "$(cat /sys/class/net/$hsdev/device/vnicc/bridge_invisible)" == "n/a" ]; then ++ echo "Error: $hsdev does not support vnicc" >&2 ++ return 1 ++ fi ++ if [ $(ip link show $hsdev | grep UP | wc -l) -eq 0 ]; then ++ echo "Error: $hsdev is not in state UP" >&2 ++ return 1 ++ fi ++ if [ $(bridge -d link show dev $hsdev self | grep learning_sync | wc -l) -eq 0 ]; then ++ echo "Error: $hsdev does not support attribute learning_sync" >&2 ++ return 1 ++ fi ++ if [ $(ip link show $hsdev | grep master | wc -l) -ne 0 ]; then ++ echo "Error: $hsdev is already a bridge port" >&2 ++ return 1 ++ fi ++ ++ #Pre-verify net_dev ++ if [ ! -e /sys/class/net/$ndev ]; then ++ echo "Error: $ndev does not exist" >&2 ++ return 1 ++ fi ++ if [ "$(cat /sys/class/net/$ndev/device/card_type)" == "HiperSockets" ]; then ++ echo "Error: $ndev is also a HiperSockets device" >&2 ++ return 1 ++ fi ++ if [ $(ip link show $ndev | grep UP | wc -l) -eq 0 ]; then ++ echo "Error: $ndev is not in state UP" >&2 ++ return 1 ++ fi ++ if [ $(ip link show $ndev | grep master | wc -l) -ne 0 ]; then ++ echo "Error: $ndev is already a bridge port" >&2 ++ return 1 ++ fi ++ ++ #Check PNETIDs ++ check_pnetids ++ if [ $? -ne 0 ]; then ++ return $? ++ fi ++ ++ return 0 ++} ++ ++function clean_up { ++ bridge link set dev $hsdev learning_sync off self >/dev/null 2>&1 ++ echo 0 > /sys/class/net/$hsdev/device/vnicc/bridge_invisible >/dev/null 2>&1 ++ bridge fdb del $hsdev_mac dev $ndev >/dev/null 2>&1 ++ ip link del $hsci >/dev/null 2>&1 ++} ++ ++############################################################################## ++## add a new HSCI interface ++############################################################################## ++function add_hsci { ++ ++ if [ $# != 2 ]; then ++ echo "hsci: Invalid parameters" >&2 ++ echo "Use 'hsci --help' for more information" >&2 ++ return 1 ++ fi ++ hsdev=$1 ++ ndev=$2 ++ ++ #### Verify preconditions ++ verify_precon ++ if [ $? -ne 0 ]; then ++ return $? ++ fi ++ ++ hsci_postfix="$(readlink /sys/class/net/$hsdev/device/cdev0 | tail -c5)" ++ hsci=hsci$hsci_postfix ++ ++ echo "Adding $hsci with a HiperSockets dev $hsdev and an external dev $ndev" ++ ++ #### Create bridge ++ ip link add name $hsci type bridge stp_state 0 >/dev/null 2>&1 ++ if [ $? -ne 0 ]; then ++ echo "Error: Could not create a bridge" >&2 ++ return 1 ++ fi ++ ++ #### Prepare hsdev ++ # Set VNICC of hsdev to invisible ++ #(mandatory for co-existence with HS-OSA bridges!) ++ echo 1 > /sys/class/net/$hsdev/device/vnicc/bridge_invisible ++ ++ #### Create bridge ports ++ ip link set dev $ndev master $hsci >/dev/null 2>&1 ++ if [ $? -ne 0 ]; then ++ echo "Error: Could not set master for $ndev" >&2 ++ clean_up ++ return 1 ++ fi ++ ip link set dev $hsdev master $hsci >/dev/null 2>&1 ++ if [ $? -ne 0 ]; then ++ echo "Error: Could not set master for $hsdev" >&2 ++ clean_up ++ return 1 ++ fi ++ ++ # no forwarding between ndev and hsdev -> isolated on ++ # ndev is default for outgoing unknown targets -> flood on ++ # no need to learn external LAN targets into fdb -> learning off ++ bridge link set dev $ndev isolated on learning off flood on mcast_flood on >/dev/null 2>&1 ++ if [ $? -ne 0 ]; then ++ echo "Error: Failed to set bridge attributes on $ndev" >&2 ++ clean_up ++ return 1 ++ fi ++ ++ # no forwarding between ndev and hsdev -> isolated on ++ # fdb will be populated by dev-to-bridge-notification, no need to learn ++ # -> learning off ++ # only send to hsdev, if listed in fdb -> flood off ++ # don't send MC/BC on hsdev -> mcast_flood off ++ bridge link set dev $hsdev isolated on learning off flood off mcast_flood off >/dev/null 2>&1 ++ if [ $? -ne 0 ]; then ++ echo "Error: Failed to set bridge attributes on $hsdev" >&2 ++ clean_up ++ return 1 ++ fi ++ ++ # NOTE: Although not required, BCs will be sent out on hsdev. ++ # NOTE: We need to receive BCs on hsdev, as z/OS HSCI does ARP requests on HS. ++ ++ hsdev_mac="$(cat /sys/class/net/$hsdev/address)" ++ echo "Set $hsdev MAC $hsdev_mac on $ndev and $hsci" ++ ++ # set HS MAC on OSA as secondary MAC ++ bridge fdb add $hsdev_mac dev $ndev >/dev/null 2>&1 ++ if [ $? -ne 0 ]; then ++ echo "Error: Failed to set HS MAC on OSA as secondary MAC" >&2 ++ clean_up ++ return 1 ++ fi ++ ++ # set HS MAC (common MAC) on HSCI as primary MAC ++ ip link set address $hsdev_mac dev $hsci >/dev/null 2>&1 ++ if [ $? -ne 0 ]; then ++ echo "Error: Failed to set HiperSockets MAC (common MAC) on HSCI as primary MAC" >&2 ++ clean_up ++ return 1 ++ fi ++ ++ # use hsdev MTU ++ if [ -e /sys/class/net/$hsdev/mtu ]; then ++ hs_mtu="$(cat /sys/class/net/$hsdev/mtu)" ++ ip link set dev $hsci mtu $hs_mtu >/dev/null 2>&1 ++ if [ $? -ne 0 ]; then ++ echo "Error: Failed to set MTU for $hsci " >&2 ++ clean_up ++ return 1 ++ fi ++ fi ++ ip link set dev $hsci up >/dev/null 2>&1 ++ if [ $? -ne 0 ]; then ++ echo "Error: Failed to set $hsci up" >&2 ++ clean_up ++ return 1 ++ fi ++ ++ # Turn on device for bridge notification ++ bridge link set dev $hsdev learning_sync on self >/dev/null 2>&1 ++ if [ $? -ne 0 ]; then ++ echo "Error: Failed to turn on device for bridge notification" >&2 ++ clean_up ++ return 1 ++ fi ++ echo "Successfully added HSCI interface $hsci" ++ return 0 ++} ++ ++############################################################################## ++## Delete HSCI ++############################################################################## ++ ++function del_hsci { ++ if [ $# != 1 ]; then ++ echo "hsci: invalid parameters" >&2 ++ echo "Use 'hsci --help' for more information" >&2 ++ return 1 ++ fi ++ hsci=$1 ++ if [ $(ip link show dev $hsci | wc -l) -eq 0 ]; then ++ echo "Error: $hsci does not exit" >&2 ++ return 1 ++ fi ++ if [ $(ip link show | grep "master $hsci" | wc -l) -eq 0 ]; then ++ echo "Error: $hsci is not an active HSCI interface" >&2 ++ return 1 ++ fi ++ ++ bports="$(ip link show | grep "master $hsci" | awk '{print $2}')" ++ for bport in $bports; do ++ if [ $(bridge -d link show dev $bport | grep "learning_sync on" | wc -l) -ne 0 ]; then ++ hsdev=${bport%:} ++ else ++ ndev=${bport%:} ++ fi ++ done ++ if [ "$hsdev" == "" ]; then ++ echo "Error: $hsci has no active HiperSockets port" >&2 ++ return 1 ++ fi ++ echo "Deleting HSCI interface $hsci with the HiperSockets $hsdev and the external $ndev" ++ ++ bridge link set dev $hsdev learning_sync off self >/dev/null 2>&1 ++ if [ $? -ne 0 ]; then ++ echo "Error: Failed to turn off learning_sync on $hsdev" >&2 ++ return 1 ++ fi ++ echo 0 > /sys/class/net/$hsdev/device/vnicc/bridge_invisible ++ ++ hsdev_mac="$(cat /sys/class/net/$hsdev/address)" ++ echo "Deleting $hsev MAC $hsdev_mac on $ndev" ++ bridge fdb del $hsdev_mac dev $ndev >/dev/null 2>&1 ++ if [ $? -ne 0 ]; then ++ echo "Error: Failed to delete $hsev MAC $hsdev_mac on $ndev" >&2 ++ return 1 ++ fi ++ ++ ip link del $hsci >/dev/null 2>&1 ++ if [ $? -ne 0 ]; then ++ echo "Error: Failed to delete $hsci" >&2 ++ return 1 ++ fi ++ echo "Successfully deleted device $hsci" ++ ++ return 0 ++} ++ ++############################################################################## ++## Show HSCI ++############################################################################## ++ ++function list_active { ++ hsdev=$1 ++ local ext="" ++ ++ hsci="$(ip link show dev $hsdev | awk '{for(x=1;x&2 ++ echo "Use 'hsci --help' for more information" >&2 ++ return 1 ++ fi ++ header=0 ++ ++ for hs_net_dev in $(ls -1 /sys/class/net/); do ++ list_one $hs_net_dev ++ done ++ ++ return 0 ++} ++ ++#============================================================================== ++ ++function print_version() ++{ ++ echo "hsci utility: version %S390_TOOLS_VERSION%" ++ echo "Copyright IBM Corp. 2020" ++} ++ ++############################################################################## ++##### Main ++############################################################################## ++prereqs_check ++ ++args="$(getopt -u -o hv -l help,version -- $*)" ++[ $? -ne 0 ] && exit 2 ++set -- $args ++while true; do ++ case $1 in ++ -v | --version) ++ print_version ++ exit 0 ++ ;; ++ -h | --help) ++ usage ++ exit 0 ++ ;; ++ --) ++ ;; ++ add) shift ++ add_hsci "$@" ++ exit $? ++ ;; ++ del) shift ++ del_hsci "$@" ++ exit $? ++ ;; ++ show) shift ++ show_hsci "$@" ++ exit $? ++ ;; ++ *) echo "hsci: Please specify a valid command or option" >&2 ++ echo "Use 'hsci --help' for more information" >&2 ++ exit 1 ++ esac ++ shift ++done ++ +diff --git a/hsci/hsci.8 b/hsci/hsci.8 +new file mode 100644 +index 00000000..fc170532 +--- /dev/null ++++ b/hsci/hsci.8 +@@ -0,0 +1,100 @@ ++.\" Copyright IBM Corp. 2020 ++ ++.TH HSCI 8 "November 2020" "s390-tools" "Linux Programmer's Manual" ++ ++ ++.SH NAME ++.B hsci ++\- control and show HSCI settings. ++ ++ ++.SH SYNOPSIS ++.B hsci add ++.I HSDEV ++.I NETDEV ++.br ++.B hsci del ++.I HSCINAME ++.br ++.B hsci show ++.br ++.B hsci [\-hv] ++ ++.SH DESCRIPTION ++.BI hsci ++is used to control and show HSCI (HiperSockets Converged Interfaces) settings. A HiperSockets interface and an external network interface are converged into an HSCI interface. ++ ++.SH COMMANDS ++.TP ++.B add \fIHSDEV\fR \fINETDEV\fR ++.RS .4i ++.PP ++Adds an HSCI interface ++.PP ++.I HSDEV ++is the interface name of the HiperSockets device to be converged into the HSCI interface. ++.PP ++.I NETDEV ++is the interface name of the external network device to be converged into the HSCI interface. ++.RE ++ ++.TP ++.B del \fIHSCINAME\fR ++.RS .4i ++.PP ++Deletes an HSCI interface ++.PP ++.I HSCINAME ++is the name of the HSCI interface for the HiperSockets device and the external network device. ++.RE ++ ++.TP ++.B show ++.RS .4i ++.PP ++Lists the configured HSCI interfaces. ++.RE ++ ++.SH OPTIONS ++.TP ++.BR \-v ", " \-\-version ++Prints the version number of hsci and exits. ++.TP ++.BR \-h ", " \-\-help ++Displays the help information for the command. ++ ++.SH EXIT CODES ++.TP ++.BR "0" ++The hsci command ran successfully. ++ ++.TP ++.BR "1" ++An error occurred. ++ ++.SH EXAMPLE ++.BR "hsci show" ++.TP ++.RB ++Lists the configured HSCI interfaces: ++.RS 1.2i ++ ++HSCI PNET_ID HiperSockets External ++.br ++----------------------------------------- ++.br ++hsci8410 NET1 enc8410 encb040 ++ ++.RE ++ ++.SH SEE ALSO ++.nf ++ip(8), bridge(8) ++.fi ++ ++.SH AUTHOR ++.nf ++Written by Alexandra Winter ++ Wenjia Zhang ++.fi ++ +-- +2.17.1 + diff --git a/s390-tools-sles15sp3-libutil-Compare-proc-entries-to-vfstype.patch b/s390-tools-sles15sp3-libutil-Compare-proc-entries-to-vfstype.patch new file mode 100644 index 0000000..e79af9f --- /dev/null +++ b/s390-tools-sles15sp3-libutil-Compare-proc-entries-to-vfstype.patch @@ -0,0 +1,41 @@ +From 8ec47052397a868c0764900db69fda4a892bd512 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jan=20H=C3=B6ppner?= +Date: Fri, 6 Nov 2020 18:47:07 +0100 +Subject: [PATCH] libutil: Compare proc entries to vfstype +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Modern systems have systemd manage system mount points like sysfs which +specify 'sysfs' as a keyword for the device as there is no device +associated with this special filesystem. However, any arbitrary string +could be specified here and the determination of the sysfs mount point +would fail in such a case. +To make sure that the mount point of the sysfs is still found when +mounted with a device keyword specified other than 'sysfs', check for +the filesystem type instead, which is more specific. + +Fixes: https://github.com/ibm-s390-tools/s390-tools/issues/91 +Suggested-by: Mark Post +Reviewed-by: Stefan Haberland +Signed-off-by: Jan Höppner +--- + libutil/util_proc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libutil/util_proc.c b/libutil/util_proc.c +index 080f831..9ac4381 100644 +--- a/libutil/util_proc.c ++++ b/libutil/util_proc.c +@@ -460,7 +460,7 @@ int util_proc_mnt_get_entry(const char *file_name, const char *spec, + rc = scan_mnt_entry(&file, entry); + if (rc) + goto out_free; +- if (!strcmp(entry->spec, spec)) { ++ if (!strcmp(entry->vfstype, spec)) { + rc = 0; + goto out_free; + } +-- +2.26.2 + diff --git a/s390-tools-sles15sp3-zcryptstats-Fix-handling-of-partial-results-with-man.patch b/s390-tools-sles15sp3-zcryptstats-Fix-handling-of-partial-results-with-man.patch new file mode 100644 index 0000000..95703e3 --- /dev/null +++ b/s390-tools-sles15sp3-zcryptstats-Fix-handling-of-partial-results-with-man.patch @@ -0,0 +1,73 @@ +Subject: [PATCH] [BZ 189239] zcryptstats: Fix handling of partial results with many domains +From: Ingo Franzki + +Description: zcryptstats: Fix handling of partial results with many domains +Symptom: Running zcryptstats when many domains are available per cryto + card does not produce any output, and is hanging in a loop. +Problem: When many domains per card are available, then the results of + the SCDMD CHSC call may not fit into the output area, and a + partial result is returned. The further results must be + retrieved with another CHSC call. Fix the code to pass the + correct next-domain to the subsequent CHSC call of a partial + response. Otherwise the same set of domains 1 to n are retrieved + again, resulting in an infinite loop, because this will always + produce a partial result. +Solution: Fix the code to pass the correct next-domain to the subsequent + CHSC call of a partial response. +Reproduction: Run zcryptstats on a system with many domains per card. +Upstream-ID: cf2311f1f1de17435b49ba8c8697be91705ba031 +Problem-ID: 189239 + +Upstream-Description: + + zcryptstats: Fix handling of partial results with many domains + + When many domains per card are available, then the results of the SCDMD + CHSC call may not fit into the output area, and a partial result is + returned. The further results must be retrieved with another CHSC call. + + Fix the code to pass the correct next-domain to the subsequent CHSC call + of a partial response. Otherwise the same set of domains 1 to n are + retrieved again, resulting in an infinite loop, because this will always + produce a partial result. + + Signed-off-by: Ingo Franzki + Reviewed-by: Harald Freudenberger + Signed-off-by: Jan Hoeppner + + +Signed-off-by: Ingo Franzki +--- + zconf/zcrypt/zcryptstats.c | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +--- a/zconf/zcrypt/zcryptstats.c ++++ b/zconf/zcrypt/zcryptstats.c +@@ -1178,8 +1178,14 @@ static int get_apqn_measurement_data(uin + scdmd_area.request.header.code = 0x102d; + scdmd_area.request.header.length = + sizeof(struct chsc_scdmd_request); +- scdmd_area.request.first_drid.ap_index = card; +- scdmd_area.request.first_drid.domain_index = g.min_domain; ++ if (scdmd_area.response.p) { ++ scdmd_area.request.first_drid = ++ scdmd_area.response.crid; ++ } else { ++ scdmd_area.request.first_drid.ap_index = card; ++ scdmd_area.request.first_drid.domain_index = ++ g.min_domain; ++ } + scdmd_area.request.last_drid.ap_index = card; + scdmd_area.request.last_drid.domain_index = g.max_domain; + scdmd_area.request.s = 1; +@@ -1217,10 +1223,6 @@ static int get_apqn_measurement_data(uin + rc = process_apqn_measurement_data(&scdmd_area); + if (rc != 0) + break; +- +- if (scdmd_area.response.p) +- scdmd_area.request.first_drid = +- scdmd_area.response.crid; + } while (scdmd_area.response.p); + + return rc; diff --git a/s390-tools.changes b/s390-tools.changes index 1a1ccd6..3742e89 100644 --- a/s390-tools.changes +++ b/s390-tools.changes @@ -1,3 +1,186 @@ +------------------------------------------------------------------- +Mon Dec 7 17:53:46 UTC 2020 - Mark Post + +- Upgraded to version 2.15.1. (bsc#1178250, jsc#SLE-13663) +- Added s390-tools-sles15sp3-dasdfmt-Fix-segfault-when-an-incorrect-option-is-spe.patch + (bsc#1178313). When specifying an incorrect program option, dasdfmt segfaults + as the format string for the corresponding error message has no parameter. +- Added s390-tools-sles15sp3-libutil-Compare-proc-entries-to-vfstype.patch + (bsc#1178315). The fdasd command was failing if sysfs was mounted this way: + mount -t sysfs none /sys + To make sure that the mount point of the sysfs is still found when mounted + with a device keyword specified other than 'sysfs', check for the filesystem + type instead, which is more specific. +- Added the following patches for bsc#1178427, and jsc#SLE-13768, + Log DASD info for endpoint security + * s390-tools-sles15sp3-01-zdev-Add-FC-Endpoint-Security-information-for-DASD-d.patch + * s390-tools-sles15sp3-02-lsdasd-Add-FC-Endpoint-Security-information.patch +- Added the following patch for bsc#1178628 and jsc#SLE-13765, Converged + HiperSockets/Ethernet Interface + * s390-tools-sles15sp3-hsci-Add-new-tool-to-control-HiperSockets-Converged-.patch +- Added the following patches for bsc#1178992 and jsc#SLE-13772, Add host-key + document verification support to genprotimg. + * s390-tools-sles15sp3-01-genprotimg-abort-if-one-of-the-recursive-targets-is-.patch + * s390-tools-sles15sp3-02-genprotimg-fix-two-memory-leaks.patch + * s390-tools-sles15sp3-03-genprotimg-require-argument-for-ramdisk-and-parmfile.patch + * s390-tools-sles15sp3-04-genprotimg-add-host-key-document-verification-suppor.patch +- Added the following patch for bsc#1178734. Running zcryptstats when many domains + are available per cryto card does not produce any output, and is hanging in a loop. + * s390-tools-sles15sp3-zcryptstats-Fix-handling-of-partial-results-with-man.patch +- Reworked and renamed the following patches to accommodate changes made by IBM + to the structure of the dasdfmt command. + * s390-tools-sles15-Allow-multiple-device-arguments.patch renamed to + s390-tools-sles15sp3-Allow-multiple-device-arguments.patch. + * s390-tools-sles15-Format-devices-in-parallel.patch renamed to + s390-tools-sles15sp3-Format-devices-in-parallel.patch + * dasdfmt-retry-BIODASDINFO-if-device-is-busy.patch renamed to + s390-tools-sles15sp3-dasdfmt-retry-BIODASDINFO-if-device-is-busy.patch + * s390-tools-sles15-Implement-f-for-backwards-compability.patch renamed to + s390-tools-sles15-Implement-Y-yast_mode.patch + +------------------------------------------------------------------- +Tue Oct 27 23:06:45 UTC 2020 - Mark Post + +- Upgraded to version 2.15.0 (jsc#SLE-13662, jsc#SLE-13663, + jsc#SLE-13667, jsc#SLE-13724, jsc#SLE-13728, jsc#SLE-13730, + jsc#SLE-13739, jsc#SLE-13744, jsc#SLE-13751, jsc#SLE-13755, + jsc#SLE-13765, jsc#SLE-13768, jsc#SLE-13777, jsc#SLE-13814, + jsc#SLE-13819, jsc#SLE-13820) +- Reworked s390-tools-sles12-sysconfig-compatible-dumpconf.patch to fit the + current version and renamed it to s390-tools-sles15-sysconfig-compatible-dumpconf.patch +- Removed the following obsolete patches: + * s390-tools-sles15sp2-01-zkey-Separate-and-rework-CCA-host-library-loading.patch + * s390-tools-sles15sp2-02-zkey-Move-utility-functions-into-separate-source-fil.patch + * s390-tools-sles15sp2-03-zkey-Add-utility-function-to-get-the-serial-number-o.patch + * s390-tools-sles15sp2-04-zkey-Add-utility-function-to-get-the-mkvp-of-a-crypt.patch + * s390-tools-sles15sp2-05-zkey-add-function-to-iterate-over-all-available-CCA-.patch + * s390-tools-sles15sp2-06-zkey-Add-function-to-print-the-MKVPs-of-APQNs.patch + * s390-tools-sles15sp2-07-zkey-Add-function-to-cross-check-APQNs-for-valid-mas.patch + * s390-tools-sles15sp2-08-zkey-Add-function-to-obtain-the-mkvp-of-a-secure-key.patch + * s390-tools-sles15sp2-09-zkey-Display-MKVP-when-validating-a-secure-key.patch + * s390-tools-sles15sp2-10-zkey-Cross-check-APQNs-when-generating-secure-keys.patch + * s390-tools-sles15sp2-11-zkey-Cross-check-APQNs-when-validating-secure-keys.patch + * s390-tools-sles15sp2-12-zkey-Cross-check-APQNs-when-importing-secure-keys.patch + * s390-tools-sles15sp2-13-zkey-Cross-check-APQNs-when-changing-APQN-associatio.patch + * s390-tools-sles15sp2-14-zkey-Add-function-to-select-a-specific-CCA-adapter.patch + * s390-tools-sles15sp2-15-zkey-Add-function-to-select-a-CCA-adapter-by-mkvp.patch + * s390-tools-sles15sp2-16-zkey-Select-CCA-adapter-when-re-enciphering.patch + * s390-tools-sles15sp2-17-zkey-cryptsetup-Add-to-new-and-from-old-options.patch + * s390-tools-sles15sp2-18-zkey-Display-key-type-with-list-and-validate-command.patch + * s390-tools-sles15sp2-19-zkey-Allow-to-filter-list-output-by-key-type.patch + * s390-tools-sles15sp2-20-zkey-Allow-to-specify-the-key-type-with-the-generate.patch + * s390-tools-sles15sp2-21-zkey-Preparations-for-introducing-a-new-key-type.patch + * s390-tools-sles15sp2-22-zkey-Introduce-the-CCA-AESCIPHER-key-type.patch + * s390-tools-sles15sp2-23-zkey-Add-wrappers-for-the-new-IOCTLs-with-fallback-t.patch + * s390-tools-sles15sp2-24-zkey-Add-helper-functions-to-build-lists-of-APQNs.patch + * s390-tools-sles15sp2-25-zkey-Add-support-for-generating-AES-CIPHER-keys.patch + * s390-tools-sles15sp2-26-zkey-Add-support-for-validating-AES-CIPHER-keys.patch + * s390-tools-sles15sp2-27-zkey-Add-support-for-re-enciphering-AES-CIPHER-keys.patch + * s390-tools-sles15sp2-28-zkey-Check-crypto-card-level-during-APQN-cross-check.patch + * s390-tools-sles15sp2-29-zkey-Add-helper-function-to-query-the-CCA-firmware-v.patch + * s390-tools-sles15sp2-30-zkey-Add-helper-function-to-convert-secure-keys-betw.patch + * s390-tools-sles15sp2-31-zkey-Add-helper-function-to-restrict-export-of-secur.patch + * s390-tools-sles15sp2-32-zkey-Add-helper-function-to-check-an-AES-CIPHER-key.patch + * s390-tools-sles15sp2-33-zkey-Add-key-checks-when-importing-a-CCA-AESCIPHER-k.patch + * s390-tools-sles15sp2-34-zkey-Add-convert-command-to-convert-keys-from-one-ty.patch + * s390-tools-sles15sp2-35-zkey-Allow-zkey-cryptsetup-setkey-to-set-different-k.patch + * s390-tools-sles15sp2-zcrypt-CEX7S-exploitation-support.patch + * s390-tools-sles15sp2-zcryptstats-Add-support-for-CEX7.patch + * s390-tools-sles15sp2-zkey-Fix-listing-of-keys-on-file-systems-reporting-D.patch + * s390-tools-sles15sp2-zkey-Fix-display-of-clear-key-size-for-XTS-keys.patch + * s390-tools-sles15sp2-zkey-Fix-display-of-XTS-attribute-for-validate-comma.patch + * s390-tools-sles15sp2-zkey-Fix-display-of-clear-key-size-for-CCA-AESCIPHER.patch + * s390-tools-sles15sp2-01-zipl-libc-Introduce-vsnprintf.patch + * s390-tools-sles15sp2-02-zipl-libc-Fix-potential-buffer-overflow-in-printf.patch + * s390-tools-sles15sp2-03-zipl-libc-Replace-sprintf-with-snprintf.patch + * s390-tools-sles15sp2-04-zipl-libc-Indicate-truncated-lines-in-printf-with.patch + * s390-tools-sles15sp2-01-zpcictl-Initiate-recover-after-reset.patch + * s390-tools-sles15sp2-02-zpcictl-Rename-misleading-sysfs_write_data.patch + * s390-tools-sles15sp2-03-zpcitctl-Exit-on-error-in-sysfs_report_error.patch + * s390-tools-sles15sp2-01-zipl-fix-Wdiscarded-qualifiers.patch + * s390-tools-sles15sp2-02-zipl-fix-Waddress-of-packed-member.patch + * s390-tools-sles15sp2-03-zipl-remove-some-useless-__packed___-attributes.patch + * s390-tools-sles15sp2-04-zipl-Fix-entry-point-for-stand-alone-kdump.patch + * s390-tools-sles15sp2-05-zipl-Fix-dependency-generation-in-zipl-boot.patch + * s390-tools-sles15sp2-06-zipl-Make-use-of-__packed-macro.patch + * s390-tools-sles15sp2-07-zipl-define-__section-macro-and-make-use-of-it.patch + * s390-tools-sles15sp2-08-zipl-Make-use-of-__noreturn-macro.patch + * s390-tools-sles15sp2-09-zipl-Define-__noinline-macro-and-make-use-of-it.patch + * s390-tools-sles15sp2-10-zipl-stage3-Mark-start_kernel-__noreturn.patch + * s390-tools-sles15sp2-11-zipl-sclp-Remove-duplicate-macros.patch + * s390-tools-sles15sp2-12-zipl-Make-address-size-mask-macros-UL.patch + * s390-tools-sles15sp2-13-zipl-libc-Use-stdint.h-instead-of-self-defined-macro.patch + * s390-tools-sles15sp2-14-zipl-Consolidate-IMAGE-macros.patch + * s390-tools-sles15sp2-15-zipl-Consolidate-STAGE-2-3-macros.patch + * s390-tools-sles15sp2-16-zipl-stfle-use-uint64_t-instead-of-u64.patch + * s390-tools-sles15sp2-17-zipl-boot-fix-comment-in-stage3.lds.patch + * s390-tools-sles15sp2-18-lib-zt_common-add-STATIC_ASSERT-macro.patch + * s390-tools-sles15sp2-19-zipl-use-STATIC_ASSERT-macro-for-no-padding-verifica.patch + * s390-tools-sles15sp2-20-Support-lib-zt_common.h-to-be-used-in-assembler-and-.patch + * s390-tools-sles15sp2-21-zipl-move-IPL-related-definitions-into-separate-head.patch + * s390-tools-sles15sp2-22-zipl-move-SIGP-related-functions-and-definitions-int.patch + * s390-tools-sles15sp2-23-zipl-add-SIGP_SET_ARCHITECTURE-to-sigp.h-and-use-it.patch + * s390-tools-sles15sp2-24-zipl-stage3-make-IPL_DEVICE-definition-consistent-wi.patch + * s390-tools-sles15sp2-25-zipl-move-Linux-layout-definitions-into-separate-hea.patch + * s390-tools-sles15sp2-26-zipl-tape0-use-constants-defined-in-linux_layout.h.patch + * s390-tools-sles15sp2-27-zipl-use-STAGE3_ENTRY-for-STAGE3_LOAD_ADDRESS.patch + * s390-tools-sles15sp2-28-zipl-move-loaders-layout-definitions-into-separate-h.patch + * s390-tools-sles15sp2-29-zipl-s390.h-rename-inline-macro-into-__always_inline.patch + * s390-tools-sles15sp2-30-zipl-move-__always_inline-barrier-__pa32-pa-to-zt_co.patch + * s390-tools-sles15sp2-31-zipl-make-BLK_PWRT-unsigned-int.patch + * s390-tools-sles15sp2-32-Consolidate-MIN-and-MAX-macros.patch + * s390-tools-sles15sp2-33-zipl-remove-libc.h-include-in-s390.h.patch + * s390-tools-sles15sp2-34-zipl-move-s390.h-to-include-boot-s390.h.patch + * s390-tools-sles15sp2-35-zipl-libc-include-s390.h.patch + * s390-tools-sles15sp2-36-include-boot-s390.h-move-panic-and-panic_notify-to-l.patch + * s390-tools-sles15sp2-37-include-boot-s390.h-fixes-for-Werror-sign-conversion.patch + * s390-tools-sles15sp2-38-zipl-refactor-all-EBCDIC-code-into-separate-files.patch + * s390-tools-sles15sp2-39-zipl-sclp-add-macros-for-the-control-program-masks.patch + * s390-tools-sles15sp2-40-zipl-sclp-add-sclp_print_ascii.patch + * s390-tools-sles15sp2-41-zipl-libc-printf-print-on-linemode-and-ASCII-console.patch + * s390-tools-sles15sp2-42-Consolidate-ALIGN-__ALIGN_MASK-ARRAY_SIZE-macros.patch + * s390-tools-sles15sp2-43-genprotimg-boot-initial-bootloader-support.patch + * s390-tools-sles15sp2-44-genprotimg-boot-use-C-pre-processor-for-linker-scrip.patch + * s390-tools-sles15sp2-45-genprotimg-add-relocator-for-stage3b.patch + * s390-tools-sles15sp2-46-README.md-remove-useless-empty-line.patch + * s390-tools-sles15sp2-47-include-boot-s390.h-add-guard-for-struct-__vector128.patch + * s390-tools-sles15sp2-48-genprotimg-introduce-new-tool-for-the-creation-of-PV.patch + * s390-tools-sles15sp2-01-zipl-Add-missing-options-to-help-output.patch + * s390-tools-sles15sp2-02-zipl-allow-stand-alone-secure-option-on-command-l.patch + * s390-tools-sles15sp2-03-zipl-correct-secure-boot-config-handling.patch + * s390-tools-sles15sp2-04-zipl-fix-zipl.conf-man-page-example-for-secure-boot.patch + * s390-tools-sles15sp2-01-cpumf-add-new-deflate-counters-for-z15.patch + * s390-tools-sles15sp2-vmcp-exit-code.patch + * s390-tools-sles15sp2-zipl-prevent-endless-loop-during-IPL.patch + * s390-tools-sles15sp2-zipl-check-for-valid-ipl-parmblock-lowcore-pointer.patch + * s390-tools-sles15sp2-01-zipl-libc-libc_stop-move-noreturn-to-declaration.patch + * s390-tools-sles15sp2-02-zipl-stage3-correctly-handle-diag308-response-code.patch + * s390-tools-sles15sp2-lsluns-try-harder-to-find-udevadm.patch + * s390-tools-sles15sp2-znetconf-introduce-better-ways-to-locate-udevadm.patch + * s390-tools-sles15sp2-mon_tools-update-udevadm-location.patch + * s390-tools-sles15sp2-lscpumf-change-dflt-ccerror-counter-name.patch + * s390-tools-sles15sp2-01-zdev-Introduce-read-only-attributes.patch + * s390-tools-sles15sp2-02-zdev-Handle-special-case-in-if-case.patch + * s390-tools-sles15sp2-03-zdev-Report-FC-Endpoint-Security-of-zfcp-devices.patch + * s390-tools-sles15sp2-04-zfcpdbf-print-HBA-FC-Endpoint-Security-trace-records.patch + * s390-tools-sles15sp1-zdev-Also-include-the-ctc-driver-in-the-initrd.patch not in spec file + * s390-tools-sles15sp2-Close-file-descriptor-when-checking-for-read-only.patch not in spec file + +------------------------------------------------------------------- +Thu Sep 17 20:16:08 UTC 2020 - Mark Post + +- Added s390-tools-sles15sp2-lscpumf-change-dflt-ccerror-counter-name.patch + (bsc#1176508) + lscpumf displays counter number 265 as DFLT_CCERROR. This is wrong + and differs from the counter name as defined in the Linux kernel + version 5.8 and later. +- Added the following patches to implement the post-GA feature jsc#ECO-2636 + Log FCP link info for endpoint security (bsc#1175477) + * s390-tools-sles15sp2-01-zdev-Introduce-read-only-attributes.patch + * s390-tools-sles15sp2-02-zdev-Handle-special-case-in-if-case.patch + * s390-tools-sles15sp2-03-zdev-Report-FC-Endpoint-Security-of-zfcp-devices.patch + * s390-tools-sles15sp2-04-zfcpdbf-print-HBA-FC-Endpoint-Security-trace-records.patch + ------------------------------------------------------------------- Tue Sep 15 18:46:04 CEST 2020 - ro@suse.de @@ -13,19 +196,7 @@ Fri Jul 24 21:17:36 UTC 2020 - Mark Post Added the following patches for bsc#1171587 * s390-tools-sles15sp2-lsluns-try-harder-to-find-udevadm.patch * s390-tools-sles15sp2-znetconf-introduce-better-ways-to-locate-udevadm.patch - *s390-tools-sles15sp2-mon_tools-update-udevadm-location.patch - -------------------------------------------------------------------- -Thu Jul 23 19:28:25 UTC 2020 - Mark Post - -- Added s390-tools-sles15sp2-zipl-prevent-endless-loop-during-IPL.patch - (bsc#1174309) zipl: prevent endless loop during secure IPL -- Added s390-tools-sles15sp2-zipl-check-for-valid-ipl-parmblock-lowcore-pointer.patch - (bsc#1174310) zipl: check for valid ipl parmblock lowcore pointer -- Added s390-tools-sles15sp2-01-zipl-libc-libc_stop-move-noreturn-to-declaration.patch - s390-tools-sles15sp2-02-zipl-stage3-correctly-handle-diag308-response-code.patch - (bsc1174311) zipl: Fix KVM IPL without bootindex -- Updated cputype and read_values to recognize the new z15 models. + * s390-tools-sles15sp2-mon_tools-update-udevadm-location.patch ------------------------------------------------------------------- Thu Jul 23 19:28:25 UTC 2020 - Mark Post diff --git a/s390-tools.spec b/s390-tools.spec index a99a385..4605d83 100644 --- a/s390-tools.spec +++ b/s390-tools.spec @@ -1,7 +1,7 @@ # # spec file for package s390-tools # -# Copyright (c) 2020 SUSE LLC +# Copyright (c) 2001-2020 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -23,7 +23,7 @@ %endif Name: s390-tools -Version: 2.11.0 +Version: 2.15.1 Release: 0 Summary: S/390 tools like zipl and dasdfmt License: MIT @@ -87,132 +87,32 @@ Source98: zfcp_disk_configure.8 Source99: zfcp_host_configure.8 ### -Patch1: s390-tools-sles15sp2-01-zkey-Separate-and-rework-CCA-host-library-loading.patch -Patch2: s390-tools-sles15sp2-02-zkey-Move-utility-functions-into-separate-source-fil.patch -Patch3: s390-tools-sles15sp2-03-zkey-Add-utility-function-to-get-the-serial-number-o.patch -Patch4: s390-tools-sles15sp2-04-zkey-Add-utility-function-to-get-the-mkvp-of-a-crypt.patch -Patch5: s390-tools-sles15sp2-05-zkey-add-function-to-iterate-over-all-available-CCA-.patch -Patch6: s390-tools-sles15sp2-06-zkey-Add-function-to-print-the-MKVPs-of-APQNs.patch -Patch7: s390-tools-sles15sp2-07-zkey-Add-function-to-cross-check-APQNs-for-valid-mas.patch -Patch8: s390-tools-sles15sp2-08-zkey-Add-function-to-obtain-the-mkvp-of-a-secure-key.patch -Patch9: s390-tools-sles15sp2-09-zkey-Display-MKVP-when-validating-a-secure-key.patch -Patch10: s390-tools-sles15sp2-10-zkey-Cross-check-APQNs-when-generating-secure-keys.patch -Patch11: s390-tools-sles15sp2-11-zkey-Cross-check-APQNs-when-validating-secure-keys.patch -Patch12: s390-tools-sles15sp2-12-zkey-Cross-check-APQNs-when-importing-secure-keys.patch -Patch13: s390-tools-sles15sp2-13-zkey-Cross-check-APQNs-when-changing-APQN-associatio.patch -Patch14: s390-tools-sles15sp2-14-zkey-Add-function-to-select-a-specific-CCA-adapter.patch -Patch15: s390-tools-sles15sp2-15-zkey-Add-function-to-select-a-CCA-adapter-by-mkvp.patch -Patch16: s390-tools-sles15sp2-16-zkey-Select-CCA-adapter-when-re-enciphering.patch -Patch17: s390-tools-sles15sp2-17-zkey-cryptsetup-Add-to-new-and-from-old-options.patch -Patch18: s390-tools-sles15sp2-18-zkey-Display-key-type-with-list-and-validate-command.patch -Patch19: s390-tools-sles15sp2-19-zkey-Allow-to-filter-list-output-by-key-type.patch -Patch20: s390-tools-sles15sp2-20-zkey-Allow-to-specify-the-key-type-with-the-generate.patch -Patch21: s390-tools-sles15sp2-21-zkey-Preparations-for-introducing-a-new-key-type.patch -Patch22: s390-tools-sles15sp2-22-zkey-Introduce-the-CCA-AESCIPHER-key-type.patch -Patch23: s390-tools-sles15sp2-23-zkey-Add-wrappers-for-the-new-IOCTLs-with-fallback-t.patch -Patch24: s390-tools-sles15sp2-24-zkey-Add-helper-functions-to-build-lists-of-APQNs.patch -Patch25: s390-tools-sles15sp2-25-zkey-Add-support-for-generating-AES-CIPHER-keys.patch -Patch26: s390-tools-sles15sp2-26-zkey-Add-support-for-validating-AES-CIPHER-keys.patch -Patch27: s390-tools-sles15sp2-27-zkey-Add-support-for-re-enciphering-AES-CIPHER-keys.patch -Patch28: s390-tools-sles15sp2-28-zkey-Check-crypto-card-level-during-APQN-cross-check.patch -Patch29: s390-tools-sles15sp2-29-zkey-Add-helper-function-to-query-the-CCA-firmware-v.patch -Patch30: s390-tools-sles15sp2-30-zkey-Add-helper-function-to-convert-secure-keys-betw.patch -Patch31: s390-tools-sles15sp2-31-zkey-Add-helper-function-to-restrict-export-of-secur.patch -Patch32: s390-tools-sles15sp2-32-zkey-Add-helper-function-to-check-an-AES-CIPHER-key.patch -Patch33: s390-tools-sles15sp2-33-zkey-Add-key-checks-when-importing-a-CCA-AESCIPHER-k.patch -Patch34: s390-tools-sles15sp2-34-zkey-Add-convert-command-to-convert-keys-from-one-ty.patch -Patch35: s390-tools-sles15sp2-35-zkey-Allow-zkey-cryptsetup-setkey-to-set-different-k.patch -Patch36: s390-tools-sles15sp2-zcrypt-CEX7S-exploitation-support.patch -Patch37: s390-tools-sles15sp2-zcryptstats-Add-support-for-CEX7.patch -Patch38: s390-tools-sles15sp2-zkey-Fix-listing-of-keys-on-file-systems-reporting-D.patch -Patch39: s390-tools-sles15sp2-zkey-Fix-display-of-clear-key-size-for-XTS-keys.patch -Patch40: s390-tools-sles15sp2-zkey-Fix-display-of-XTS-attribute-for-validate-comma.patch -Patch41: s390-tools-sles15sp2-zkey-Fix-display-of-clear-key-size-for-CCA-AESCIPHER.patch -Patch42: s390-tools-sles15sp2-01-zipl-libc-Introduce-vsnprintf.patch -Patch43: s390-tools-sles15sp2-02-zipl-libc-Fix-potential-buffer-overflow-in-printf.patch -Patch44: s390-tools-sles15sp2-03-zipl-libc-Replace-sprintf-with-snprintf.patch -Patch45: s390-tools-sles15sp2-04-zipl-libc-Indicate-truncated-lines-in-printf-with.patch -Patch46: s390-tools-sles15sp2-01-zpcictl-Initiate-recover-after-reset.patch -Patch47: s390-tools-sles15sp2-02-zpcictl-Rename-misleading-sysfs_write_data.patch -Patch48: s390-tools-sles15sp2-03-zpcitctl-Exit-on-error-in-sysfs_report_error.patch -Patch49: s390-tools-sles15sp2-01-zipl-fix-Wdiscarded-qualifiers.patch -Patch50: s390-tools-sles15sp2-02-zipl-fix-Waddress-of-packed-member.patch -Patch51: s390-tools-sles15sp2-03-zipl-remove-some-useless-__packed___-attributes.patch -Patch52: s390-tools-sles15sp2-04-zipl-Fix-entry-point-for-stand-alone-kdump.patch -Patch53: s390-tools-sles15sp2-05-zipl-Fix-dependency-generation-in-zipl-boot.patch -Patch54: s390-tools-sles15sp2-06-zipl-Make-use-of-__packed-macro.patch -Patch55: s390-tools-sles15sp2-07-zipl-define-__section-macro-and-make-use-of-it.patch -Patch56: s390-tools-sles15sp2-08-zipl-Make-use-of-__noreturn-macro.patch -Patch57: s390-tools-sles15sp2-09-zipl-Define-__noinline-macro-and-make-use-of-it.patch -Patch58: s390-tools-sles15sp2-10-zipl-stage3-Mark-start_kernel-__noreturn.patch -Patch59: s390-tools-sles15sp2-11-zipl-sclp-Remove-duplicate-macros.patch -Patch60: s390-tools-sles15sp2-12-zipl-Make-address-size-mask-macros-UL.patch -Patch61: s390-tools-sles15sp2-13-zipl-libc-Use-stdint.h-instead-of-self-defined-macro.patch -Patch62: s390-tools-sles15sp2-14-zipl-Consolidate-IMAGE-macros.patch -Patch63: s390-tools-sles15sp2-15-zipl-Consolidate-STAGE-2-3-macros.patch -Patch64: s390-tools-sles15sp2-16-zipl-stfle-use-uint64_t-instead-of-u64.patch -Patch65: s390-tools-sles15sp2-17-zipl-boot-fix-comment-in-stage3.lds.patch -Patch66: s390-tools-sles15sp2-18-lib-zt_common-add-STATIC_ASSERT-macro.patch -Patch67: s390-tools-sles15sp2-19-zipl-use-STATIC_ASSERT-macro-for-no-padding-verifica.patch -Patch68: s390-tools-sles15sp2-20-Support-lib-zt_common.h-to-be-used-in-assembler-and-.patch -Patch69: s390-tools-sles15sp2-21-zipl-move-IPL-related-definitions-into-separate-head.patch -Patch70: s390-tools-sles15sp2-22-zipl-move-SIGP-related-functions-and-definitions-int.patch -Patch71: s390-tools-sles15sp2-23-zipl-add-SIGP_SET_ARCHITECTURE-to-sigp.h-and-use-it.patch -Patch72: s390-tools-sles15sp2-24-zipl-stage3-make-IPL_DEVICE-definition-consistent-wi.patch -Patch73: s390-tools-sles15sp2-25-zipl-move-Linux-layout-definitions-into-separate-hea.patch -Patch74: s390-tools-sles15sp2-26-zipl-tape0-use-constants-defined-in-linux_layout.h.patch -Patch75: s390-tools-sles15sp2-27-zipl-use-STAGE3_ENTRY-for-STAGE3_LOAD_ADDRESS.patch -Patch76: s390-tools-sles15sp2-28-zipl-move-loaders-layout-definitions-into-separate-h.patch -Patch77: s390-tools-sles15sp2-29-zipl-s390.h-rename-inline-macro-into-__always_inline.patch -Patch78: s390-tools-sles15sp2-30-zipl-move-__always_inline-barrier-__pa32-pa-to-zt_co.patch -Patch79: s390-tools-sles15sp2-31-zipl-make-BLK_PWRT-unsigned-int.patch -Patch80: s390-tools-sles15sp2-32-Consolidate-MIN-and-MAX-macros.patch -Patch81: s390-tools-sles15sp2-33-zipl-remove-libc.h-include-in-s390.h.patch -Patch82: s390-tools-sles15sp2-34-zipl-move-s390.h-to-include-boot-s390.h.patch -Patch83: s390-tools-sles15sp2-35-zipl-libc-include-s390.h.patch -Patch84: s390-tools-sles15sp2-36-include-boot-s390.h-move-panic-and-panic_notify-to-l.patch -Patch85: s390-tools-sles15sp2-37-include-boot-s390.h-fixes-for-Werror-sign-conversion.patch -Patch86: s390-tools-sles15sp2-38-zipl-refactor-all-EBCDIC-code-into-separate-files.patch -Patch87: s390-tools-sles15sp2-39-zipl-sclp-add-macros-for-the-control-program-masks.patch -Patch88: s390-tools-sles15sp2-40-zipl-sclp-add-sclp_print_ascii.patch -Patch89: s390-tools-sles15sp2-41-zipl-libc-printf-print-on-linemode-and-ASCII-console.patch -Patch90: s390-tools-sles15sp2-42-Consolidate-ALIGN-__ALIGN_MASK-ARRAY_SIZE-macros.patch -Patch91: s390-tools-sles15sp2-43-genprotimg-boot-initial-bootloader-support.patch -Patch92: s390-tools-sles15sp2-44-genprotimg-boot-use-C-pre-processor-for-linker-scrip.patch -Patch93: s390-tools-sles15sp2-45-genprotimg-add-relocator-for-stage3b.patch -Patch94: s390-tools-sles15sp2-46-README.md-remove-useless-empty-line.patch -Patch95: s390-tools-sles15sp2-47-include-boot-s390.h-add-guard-for-struct-__vector128.patch -Patch96: s390-tools-sles15sp2-48-genprotimg-introduce-new-tool-for-the-creation-of-PV.patch -Patch97: s390-tools-sles15sp2-01-zipl-Add-missing-options-to-help-output.patch -Patch98: s390-tools-sles15sp2-02-zipl-allow-stand-alone-secure-option-on-command-l.patch -Patch99: s390-tools-sles15sp2-03-zipl-correct-secure-boot-config-handling.patch -Patch100: s390-tools-sles15sp2-04-zipl-fix-zipl.conf-man-page-example-for-secure-boot.patch -Patch101: s390-tools-sles15sp2-01-cpumf-add-new-deflate-counters-for-z15.patch -Patch102: s390-tools-sles15sp2-vmcp-exit-code.patch -Patch103: s390-tools-sles15sp2-zipl-prevent-endless-loop-during-IPL.patch -Patch104: s390-tools-sles15sp2-zipl-check-for-valid-ipl-parmblock-lowcore-pointer.patch -Patch105: s390-tools-sles15sp2-01-zipl-libc-libc_stop-move-noreturn-to-declaration.patch -Patch106: s390-tools-sles15sp2-02-zipl-stage3-correctly-handle-diag308-response-code.patch -Patch107: s390-tools-sles15sp2-lsluns-try-harder-to-find-udevadm.patch -Patch108: s390-tools-sles15sp2-znetconf-introduce-better-ways-to-locate-udevadm.patch -Patch109: s390-tools-sles15sp2-mon_tools-update-udevadm-location.patch +Patch1: s390-tools-sles15sp3-dasdfmt-Fix-segfault-when-an-incorrect-option-is-spe.patch +Patch2: s390-tools-sles15sp3-libutil-Compare-proc-entries-to-vfstype.patch +Patch3: s390-tools-sles15sp3-01-zdev-Add-FC-Endpoint-Security-information-for-DASD-d.patch +Patch4: s390-tools-sles15sp3-02-lsdasd-Add-FC-Endpoint-Security-information.patch +Patch5: s390-tools-sles15sp3-hsci-Add-new-tool-to-control-HiperSockets-Converged-.patch +Patch6: s390-tools-sles15sp3-zcryptstats-Fix-handling-of-partial-results-with-man.patch +Patch7: s390-tools-sles15sp3-01-genprotimg-abort-if-one-of-the-recursive-targets-is-.patch +Patch8: s390-tools-sles15sp3-02-genprotimg-fix-two-memory-leaks.patch +Patch9: s390-tools-sles15sp3-03-genprotimg-require-argument-for-ramdisk-and-parmfile.patch +Patch10: s390-tools-sles15sp3-04-genprotimg-add-host-key-document-verification-suppor.patch # SUSE patches Patch900: s390-tools-sles12-zipl_boot_msg.patch -Patch901: s390-tools-sles12-sysconfig-compatible-dumpconf.patch +Patch901: s390-tools-sles15-sysconfig-compatible-dumpconf.patch Patch902: s390-tools-sles12-create-filesystem-links.patch Patch903: s390-tools-sles12-update-by_id-links-on-change-and-add-action.patch -Patch904: s390-tools-sles15-Allow-multiple-device-arguments.patch -Patch905: s390-tools-sles15-Format-devices-in-parallel.patch -Patch906: s390-tools-sles15-Implement-Y-yast_mode.patch -Patch907: s390-tools-sles15-Implement-f-for-backwards-compability.patch -Patch908: dasdfmt-retry-BIODASDINFO-if-device-is-busy.patch +Patch904: s390-tools-sles15sp3-Allow-multiple-device-arguments.patch +Patch905: s390-tools-sles15sp3-Format-devices-in-parallel.patch +Patch906: s390-tools-sles15sp3-Implement-Y-yast_mode.patch +Patch907: s390-tools-sles15sp3-Implement-f-for-backwards-compability.patch +Patch908: s390-tools-sles15sp3-dasdfmt-retry-BIODASDINFO-if-device-is-busy.patch Patch909: 59-dasd.rules-wait_for.patch Patch910: s390-tools-sles12-fdasd-skip-partition-check-and-BLKRRPART-ioctl.patch -Patch911: s390-tools-sles15sp2-Close-file-descriptor-when-checking-for-read-only.patch -Patch912: s390-tools-sles15sp1-zdev-Also-include-the-ctc-driver-in-the-initrd.patch -Patch913: s390-tools-sles15sp1-11-zdev-Do-not-call-zipl-on-initrd-update.patch +Patch911: s390-tools-sles15sp1-11-zdev-Do-not-call-zipl-on-initrd-update.patch +BuildRequires: curl-devel BuildRequires: dracut BuildRequires: fuse-devel BuildRequires: gcc-c++ @@ -292,6 +192,29 @@ Requires: fuse This package contains a HMC drive file system based on FUSE and a tool to list files and directories. +%package -n libekmfweb1 +Summary: IBM Enterprise Key Management Foundation - Web Edition client library +License: MIT +Group: System/Libraries + +%description -n libekmfweb1 +libekmfweb1 is a client library that provides access to IBM' Enterprise Key +Management Foundation – Web Edition.0 EKMF Web provides efficient and +security-rich centralized key management for IBM z/OS data set encryption +on IBM Z servers. + +%package -n libekmfweb1-devel +Summary: IBM Enterprise Key Management Foundation - Web Edition client library +License: MIT +Group: Development/Libraries/C and C++ +Requires: libekmfweb1 + +%description -n libekmfweb1-devel +libekmfweb1 is a client library that provides access to IBM' Enterprise Key +Management Foundation – Web Edition.0 EKMF Web provides efficient and +security-rich centralized key management for IBM z/OS data set encryption +on IBM Z servers. + %prep %autosetup -p1 @@ -416,7 +339,7 @@ rm -fv %{buildroot}/%{_sbindir}/chmem find . ! -type d | sed 's/^.//;\-/man/-s/^.*$/%doc &.gz/' > %{_builddir}/%{name}-filelist -grep -v -E 'osasnmp|*\.conf$' %{_builddir}/%{name}-filelist >%{_builddir}/%{name}.list +grep -v -E 'osasnmp|*\.conf$|ekmfweb.so|ekmfweb.h' %{_builddir}/%{name}-filelist >%{_builddir}/%{name}.list grep osasnmp[^-] %{_builddir}/%{name}-filelist >%{_builddir}/%{name}.osasnmp touch boot/zipl/active_devices.txt @@ -440,7 +363,7 @@ chmod 755 osasnmpd export BRP_PESIGN_FILES='/lib/s390-tools/stage3.bin' %verifyscript -%verify_permissions -e %{_localstatedir}/log/ts-shell +%verify_permissions -e %{_localstatedir}/log/ts-shell/ %pre # check for ts-shell group or create it @@ -469,7 +392,7 @@ if [ "${INITPGM}" = "systemd" ]; then systemctl daemon-reload fi -%set_permissions %{_localstatedir}/log/ts-shell +%set_permissions %{_localstatedir}/log/ts-shell/ # Create symbolic links to the scripts from setup and boot directories %service_add_post appldata.service @@ -505,6 +428,9 @@ grep -q '^%{_bindir}/ts-shell$' %{_sysconfdir}/shells \ %post -n osasnmpd %{fillup_only -n osasnmpd} +%post -n libekmfweb1 +ldconfig + %preun %service_del_preun appldata.service %service_del_preun cio_ignore.service @@ -533,6 +459,9 @@ grep -q '^%{_bindir}/ts-shell$' %{_sysconfdir}/shells \ %service_del_postun vmlogrdr.service %service_del_postun xpram.service +%postun -n libekmfweb1 +ldconfig + # Even though SLES15+ is systemd based, the build service doesn't # run it, so we have to make sure we can safely issue the # systemctl command. @@ -579,6 +508,7 @@ fi %dir %attr(0770,root,zkeyadm) %{_sysconfdir}/zkey/repository %config %{_sysconfdir}/modprobe.d/90-s390-tools.conf %config %{_sysconfdir}/cpuplugd.conf +%config %{_sysconfdir}/zkey/kms-plugins.conf %config(noreplace) /boot/zipl/active_devices.txt %dir %attr(2770,root,ts-shell) %{_localstatedir}/log/ts-shell %dir %{_sysconfdir}/cmsfs-fuse @@ -588,12 +518,12 @@ fi %dir %{_prefix}/lib/udev/rules.d %dir %{_prefix}/lib/systemd/scripts %dir %{_datadir}/s390-tools -%dir %{_datadir}/s390-tools/cpumf %dir %{_datadir}/s390-tools/netboot %dir %{_datadir}/s390-tools/genprotimg %dir %{_prefix}/lib/dracut/modules.d/95zdev %dir /boot/zipl %dir /lib/s390-tools/ +/lib/s390-tools/zipl.conf %{_prefix}/lib/modules-load.d/pkey.conf %exclude %{_prefix}/lib/udev/rules.d/57-osasnmpd.rules %exclude %{_bindir}/zdsfs @@ -620,4 +550,15 @@ fi %{_mandir}/man1/hmcdrvfs.1%{?ext_man} %{_mandir}/man8/lshmc.8%{?ext_man} +%files -n libekmfweb1 +%defattr(-,root,root) +%{_libdir}/libekmfweb.so.* +%dir %{_libdir}/zkey +%{_libdir}/zkey/zkey-ekmfweb.so + +%files -n libekmfweb1-devel +%{_libdir}/libekmfweb.so +%dir %attr(755,root,root) %{_includedir}/ekmfweb +%attr(644,root,root) %{_includedir}/ekmfweb/ekmfweb.h + %changelog From 6d6e14484a409c25059fbd7af9113c145f82caa00a0bbce3e67e913a9c404542 Mon Sep 17 00:00:00 2001 From: Mark Post Date: Tue, 8 Dec 2020 19:59:20 +0000 Subject: [PATCH 2/2] Accepting request 854128 from home:markkp:branches:Base:System - Upgraded to version 2.15.1. (bsc#1178250, jsc#SLE-13663) - Added s390-tools-sles15sp3-dasdfmt-Fix-segfault-when-an-incorrect-option-is-spe.patch (bsc#1178313). When specifying an incorrect program option, dasdfmt segfaults as the format string for the corresponding error message has no parameter. - Added s390-tools-sles15sp3-libutil-Compare-proc-entries-to-vfstype.patch (bsc#1178315). The fdasd command was failing if sysfs was mounted this way: mount -t sysfs none /sys To make sure that the mount point of the sysfs is still found when mounted with a device keyword specified other than 'sysfs', check for the filesystem type instead, which is more specific. - Added the following patches for bsc#1178427, and jsc#SLE-13768, Log DASD info for endpoint security * s390-tools-sles15sp3-01-zdev-Add-FC-Endpoint-Security-information-for-DASD-d.patch * s390-tools-sles15sp3-02-lsdasd-Add-FC-Endpoint-Security-information.patch - Added the following patch for bsc#1178628 and jsc#SLE-13765, Converged HiperSockets/Ethernet Interface * s390-tools-sles15sp3-hsci-Add-new-tool-to-control-HiperSockets-Converged-.patch - Added the following patches for bsc#1178992 and jsc#SLE-13772, Add host-key document verification support to genprotimg. * s390-tools-sles15sp3-01-genprotimg-abort-if-one-of-the-recursive-targets-is-.patch * s390-tools-sles15sp3-02-genprotimg-fix-two-memory-leaks.patch * s390-tools-sles15sp3-03-genprotimg-require-argument-for-ramdisk-and-parmfile.patch * s390-tools-sles15sp3-04-genprotimg-add-host-key-document-verification-suppor.patch - Added the following patch for bsc#1178734. Running zcryptstats when many domains are available per cryto card does not produce any output, and is hanging in a loop. * s390-tools-sles15sp3-zcryptstats-Fix-handling-of-partial-results-with-man.patch - Reworked and renamed the following patches to accommodate changes made by IBM to the structure of the dasdfmt command. * s390-tools-sles15-Allow-multiple-device-arguments.patch renamed to s390-tools-sles15sp3-Allow-multiple-device-arguments.patch. * s390-tools-sles15-Format-devices-in-parallel.patch renamed to s390-tools-sles15sp3-Format-devices-in-parallel.patch * dasdfmt-retry-BIODASDINFO-if-device-is-busy.patch renamed to s390-tools-sles15sp3-dasdfmt-retry-BIODASDINFO-if-device-is-busy.patch * s390-tools-sles15-Implement-f-for-backwards-compability.patch renamed to s390-tools-sles15sp3-Implement-f-for-backwards-compability.patch renamed to * s390-tools-sles15-Implement-Y-yast_mode.patch s390-tools-sles15sp3-Implement-Y-yast_mode.patch - Upgraded to version 2.15.0 (jsc#SLE-13662, jsc#SLE-13663, jsc#SLE-13667, jsc#SLE-13724, jsc#SLE-13728, jsc#SLE-13730, jsc#SLE-13739, jsc#SLE-13744, jsc#SLE-13751, jsc#SLE-13755, jsc#SLE-13765, jsc#SLE-13768, jsc#SLE-13777, jsc#SLE-13814, jsc#SLE-13819, jsc#SLE-13820) - Reworked s390-tools-sles12-sysconfig-compatible-dumpconf.patch to fit the current version and renamed it to s390-tools-sles15-sysconfig-compatible-dumpconf.patch - Removed the following obsolete patches: * s390-tools-sles15sp2-01-zkey-Separate-and-rework-CCA-host-library-loading.patch * s390-tools-sles15sp2-02-zkey-Move-utility-functions-into-separate-source-fil.patch * s390-tools-sles15sp2-03-zkey-Add-utility-function-to-get-the-serial-number-o.patch * s390-tools-sles15sp2-04-zkey-Add-utility-function-to-get-the-mkvp-of-a-crypt.patch * s390-tools-sles15sp2-05-zkey-add-function-to-iterate-over-all-available-CCA-.patch * s390-tools-sles15sp2-06-zkey-Add-function-to-print-the-MKVPs-of-APQNs.patch * s390-tools-sles15sp2-07-zkey-Add-function-to-cross-check-APQNs-for-valid-mas.patch * s390-tools-sles15sp2-08-zkey-Add-function-to-obtain-the-mkvp-of-a-secure-key.patch * s390-tools-sles15sp2-09-zkey-Display-MKVP-when-validating-a-secure-key.patch * s390-tools-sles15sp2-10-zkey-Cross-check-APQNs-when-generating-secure-keys.patch * s390-tools-sles15sp2-11-zkey-Cross-check-APQNs-when-validating-secure-keys.patch * s390-tools-sles15sp2-12-zkey-Cross-check-APQNs-when-importing-secure-keys.patch * s390-tools-sles15sp2-13-zkey-Cross-check-APQNs-when-changing-APQN-associatio.patch * s390-tools-sles15sp2-14-zkey-Add-function-to-select-a-specific-CCA-adapter.patch * s390-tools-sles15sp2-15-zkey-Add-function-to-select-a-CCA-adapter-by-mkvp.patch * s390-tools-sles15sp2-16-zkey-Select-CCA-adapter-when-re-enciphering.patch * s390-tools-sles15sp2-17-zkey-cryptsetup-Add-to-new-and-from-old-options.patch * s390-tools-sles15sp2-18-zkey-Display-key-type-with-list-and-validate-command.patch * s390-tools-sles15sp2-19-zkey-Allow-to-filter-list-output-by-key-type.patch * s390-tools-sles15sp2-20-zkey-Allow-to-specify-the-key-type-with-the-generate.patch * s390-tools-sles15sp2-21-zkey-Preparations-for-introducing-a-new-key-type.patch * s390-tools-sles15sp2-22-zkey-Introduce-the-CCA-AESCIPHER-key-type.patch * s390-tools-sles15sp2-23-zkey-Add-wrappers-for-the-new-IOCTLs-with-fallback-t.patch * s390-tools-sles15sp2-24-zkey-Add-helper-functions-to-build-lists-of-APQNs.patch * s390-tools-sles15sp2-25-zkey-Add-support-for-generating-AES-CIPHER-keys.patch * s390-tools-sles15sp2-26-zkey-Add-support-for-validating-AES-CIPHER-keys.patch * s390-tools-sles15sp2-27-zkey-Add-support-for-re-enciphering-AES-CIPHER-keys.patch * s390-tools-sles15sp2-28-zkey-Check-crypto-card-level-during-APQN-cross-check.patch * s390-tools-sles15sp2-29-zkey-Add-helper-function-to-query-the-CCA-firmware-v.patch * s390-tools-sles15sp2-30-zkey-Add-helper-function-to-convert-secure-keys-betw.patch * s390-tools-sles15sp2-31-zkey-Add-helper-function-to-restrict-export-of-secur.patch * s390-tools-sles15sp2-32-zkey-Add-helper-function-to-check-an-AES-CIPHER-key.patch * s390-tools-sles15sp2-33-zkey-Add-key-checks-when-importing-a-CCA-AESCIPHER-k.patch * s390-tools-sles15sp2-34-zkey-Add-convert-command-to-convert-keys-from-one-ty.patch * s390-tools-sles15sp2-35-zkey-Allow-zkey-cryptsetup-setkey-to-set-different-k.patch * s390-tools-sles15sp2-zcrypt-CEX7S-exploitation-support.patch * s390-tools-sles15sp2-zcryptstats-Add-support-for-CEX7.patch * s390-tools-sles15sp2-zkey-Fix-listing-of-keys-on-file-systems-reporting-D.patch * s390-tools-sles15sp2-zkey-Fix-display-of-clear-key-size-for-XTS-keys.patch * s390-tools-sles15sp2-zkey-Fix-display-of-XTS-attribute-for-validate-comma.patch * s390-tools-sles15sp2-zkey-Fix-display-of-clear-key-size-for-CCA-AESCIPHER.patch * s390-tools-sles15sp2-01-zipl-libc-Introduce-vsnprintf.patch * s390-tools-sles15sp2-02-zipl-libc-Fix-potential-buffer-overflow-in-printf.patch * s390-tools-sles15sp2-03-zipl-libc-Replace-sprintf-with-snprintf.patch * s390-tools-sles15sp2-04-zipl-libc-Indicate-truncated-lines-in-printf-with.patch * s390-tools-sles15sp2-01-zpcictl-Initiate-recover-after-reset.patch * s390-tools-sles15sp2-02-zpcictl-Rename-misleading-sysfs_write_data.patch * s390-tools-sles15sp2-03-zpcitctl-Exit-on-error-in-sysfs_report_error.patch * s390-tools-sles15sp2-01-zipl-fix-Wdiscarded-qualifiers.patch * s390-tools-sles15sp2-02-zipl-fix-Waddress-of-packed-member.patch * s390-tools-sles15sp2-03-zipl-remove-some-useless-__packed___-attributes.patch * s390-tools-sles15sp2-04-zipl-Fix-entry-point-for-stand-alone-kdump.patch * s390-tools-sles15sp2-05-zipl-Fix-dependency-generation-in-zipl-boot.patch * s390-tools-sles15sp2-06-zipl-Make-use-of-__packed-macro.patch * s390-tools-sles15sp2-07-zipl-define-__section-macro-and-make-use-of-it.patch * s390-tools-sles15sp2-08-zipl-Make-use-of-__noreturn-macro.patch * s390-tools-sles15sp2-09-zipl-Define-__noinline-macro-and-make-use-of-it.patch * s390-tools-sles15sp2-10-zipl-stage3-Mark-start_kernel-__noreturn.patch * s390-tools-sles15sp2-11-zipl-sclp-Remove-duplicate-macros.patch * s390-tools-sles15sp2-12-zipl-Make-address-size-mask-macros-UL.patch * s390-tools-sles15sp2-13-zipl-libc-Use-stdint.h-instead-of-self-defined-macro.patch * s390-tools-sles15sp2-14-zipl-Consolidate-IMAGE-macros.patch * s390-tools-sles15sp2-15-zipl-Consolidate-STAGE-2-3-macros.patch * s390-tools-sles15sp2-16-zipl-stfle-use-uint64_t-instead-of-u64.patch * s390-tools-sles15sp2-17-zipl-boot-fix-comment-in-stage3.lds.patch * s390-tools-sles15sp2-18-lib-zt_common-add-STATIC_ASSERT-macro.patch * s390-tools-sles15sp2-19-zipl-use-STATIC_ASSERT-macro-for-no-padding-verifica.patch * s390-tools-sles15sp2-20-Support-lib-zt_common.h-to-be-used-in-assembler-and-.patch * s390-tools-sles15sp2-21-zipl-move-IPL-related-definitions-into-separate-head.patch * s390-tools-sles15sp2-22-zipl-move-SIGP-related-functions-and-definitions-int.patch * s390-tools-sles15sp2-23-zipl-add-SIGP_SET_ARCHITECTURE-to-sigp.h-and-use-it.patch * s390-tools-sles15sp2-24-zipl-stage3-make-IPL_DEVICE-definition-consistent-wi.patch * s390-tools-sles15sp2-25-zipl-move-Linux-layout-definitions-into-separate-hea.patch * s390-tools-sles15sp2-26-zipl-tape0-use-constants-defined-in-linux_layout.h.patch * s390-tools-sles15sp2-27-zipl-use-STAGE3_ENTRY-for-STAGE3_LOAD_ADDRESS.patch * s390-tools-sles15sp2-28-zipl-move-loaders-layout-definitions-into-separate-h.patch * s390-tools-sles15sp2-29-zipl-s390.h-rename-inline-macro-into-__always_inline.patch * s390-tools-sles15sp2-30-zipl-move-__always_inline-barrier-__pa32-pa-to-zt_co.patch * s390-tools-sles15sp2-31-zipl-make-BLK_PWRT-unsigned-int.patch * s390-tools-sles15sp2-32-Consolidate-MIN-and-MAX-macros.patch * s390-tools-sles15sp2-33-zipl-remove-libc.h-include-in-s390.h.patch * s390-tools-sles15sp2-34-zipl-move-s390.h-to-include-boot-s390.h.patch * s390-tools-sles15sp2-35-zipl-libc-include-s390.h.patch * s390-tools-sles15sp2-36-include-boot-s390.h-move-panic-and-panic_notify-to-l.patch * s390-tools-sles15sp2-37-include-boot-s390.h-fixes-for-Werror-sign-conversion.patch * s390-tools-sles15sp2-38-zipl-refactor-all-EBCDIC-code-into-separate-files.patch * s390-tools-sles15sp2-39-zipl-sclp-add-macros-for-the-control-program-masks.patch * s390-tools-sles15sp2-40-zipl-sclp-add-sclp_print_ascii.patch * s390-tools-sles15sp2-41-zipl-libc-printf-print-on-linemode-and-ASCII-console.patch * s390-tools-sles15sp2-42-Consolidate-ALIGN-__ALIGN_MASK-ARRAY_SIZE-macros.patch * s390-tools-sles15sp2-43-genprotimg-boot-initial-bootloader-support.patch * s390-tools-sles15sp2-44-genprotimg-boot-use-C-pre-processor-for-linker-scrip.patch * s390-tools-sles15sp2-45-genprotimg-add-relocator-for-stage3b.patch * s390-tools-sles15sp2-46-README.md-remove-useless-empty-line.patch * s390-tools-sles15sp2-47-include-boot-s390.h-add-guard-for-struct-__vector128.patch * s390-tools-sles15sp2-48-genprotimg-introduce-new-tool-for-the-creation-of-PV.patch * s390-tools-sles15sp2-01-zipl-Add-missing-options-to-help-output.patch * s390-tools-sles15sp2-02-zipl-allow-stand-alone-secure-option-on-command-l.patch * s390-tools-sles15sp2-03-zipl-correct-secure-boot-config-handling.patch * s390-tools-sles15sp2-04-zipl-fix-zipl.conf-man-page-example-for-secure-boot.patch * s390-tools-sles15sp2-01-cpumf-add-new-deflate-counters-for-z15.patch * s390-tools-sles15sp2-vmcp-exit-code.patch * s390-tools-sles15sp2-zipl-prevent-endless-loop-during-IPL.patch * s390-tools-sles15sp2-zipl-check-for-valid-ipl-parmblock-lowcore-pointer.patch * s390-tools-sles15sp2-01-zipl-libc-libc_stop-move-noreturn-to-declaration.patch * s390-tools-sles15sp2-02-zipl-stage3-correctly-handle-diag308-response-code.patch * s390-tools-sles15sp2-lsluns-try-harder-to-find-udevadm.patch * s390-tools-sles15sp2-znetconf-introduce-better-ways-to-locate-udevadm.patch * s390-tools-sles15sp2-mon_tools-update-udevadm-location.patch * s390-tools-sles15sp2-lscpumf-change-dflt-ccerror-counter-name.patch * s390-tools-sles15sp2-01-zdev-Introduce-read-only-attributes.patch * s390-tools-sles15sp2-02-zdev-Handle-special-case-in-if-case.patch * s390-tools-sles15sp2-03-zdev-Report-FC-Endpoint-Security-of-zfcp-devices.patch * s390-tools-sles15sp2-04-zfcpdbf-print-HBA-FC-Endpoint-Security-trace-records.patch * s390-tools-sles15sp1-zdev-Also-include-the-ctc-driver-in-the-initrd.patch not in spec file * s390-tools-sles15sp2-Close-file-descriptor-when-checking-for-read-only.patch not in spec file - Added s390-tools-sles15sp2-lscpumf-change-dflt-ccerror-counter-name.patch (bsc#1176508) lscpumf displays counter number 265 as DFLT_CCERROR. This is wrong and differs from the counter name as defined in the Linux kernel version 5.8 and later. - Added the following patches to implement the post-GA feature jsc#ECO-2636 Log FCP link info for endpoint security (bsc#1175477) OBS-URL: https://build.opensuse.org/request/show/854128 OBS-URL: https://build.opensuse.org/package/show/Base:System/s390-tools?expand=0&rev=102 --- s390-tools.changes | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/s390-tools.changes b/s390-tools.changes index 3742e89..eae36b3 100644 --- a/s390-tools.changes +++ b/s390-tools.changes @@ -36,7 +36,9 @@ Mon Dec 7 17:53:46 UTC 2020 - Mark Post * dasdfmt-retry-BIODASDINFO-if-device-is-busy.patch renamed to s390-tools-sles15sp3-dasdfmt-retry-BIODASDINFO-if-device-is-busy.patch * s390-tools-sles15-Implement-f-for-backwards-compability.patch renamed to - s390-tools-sles15-Implement-Y-yast_mode.patch + s390-tools-sles15sp3-Implement-f-for-backwards-compability.patch renamed to + * s390-tools-sles15-Implement-Y-yast_mode.patch + s390-tools-sles15sp3-Implement-Y-yast_mode.patch ------------------------------------------------------------------- Tue Oct 27 23:06:45 UTC 2020 - Mark Post