s390-tools/s390-tools-sles15sp2-26-zkey-Add-support-for-validating-AES-CIPHER-keys.patch
Mark Post 50eb270fbf Accepting request 750974 from home:markkp:branches:Base:System
- Upgraded to version 2.11.0 (jsc#7831)
- Updated the cputype script and read_values program to recognize
  machine types up through the new z15.
- Added the following patches (bsc#1151859)
  * 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
- Added the following patches (bsc#1151858)
  * 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
- Added the following patches (bsc#1153757)
  * s390-tools-sles15sp2-zcrypt-CEX7S-exploitation-support.patch
  * s390-tools-sles15sp2-zcryptstats-Add-support-for-CEX7.patch
- Added s390-tools-sles15sp2-Close-file-descriptor-when-checking-for-read-only.patch
- Forward-ported the following patches to work with the restructuring IBM did for
  this version
  * dasdfmt-retry-BIODASDINFO-if-device-is-busy.patch
  * s390-tools-sles12-fdasd-skip-partition-check-and-BLKRRPART-ioctl.patch
  * s390-tools-sles15-Allow-multiple-device-arguments.patch 
  * s390-tools-sles15-Format-devices-in-parallel.patch
  * s390-tools-sles15-Implement-f-for-backwards-compability.patch
  * s390-tools-sles15-Implement-Y-yast_mode.patch
- Removed the following obsolete patches:
  * s390-tools-sles15-1-lstape-fix-output-with-SCSI-lin_tape-and-multiple-pa.patch
  * s390-tools-sles15-2-lstape-fix-to-prefer-sysfs-to-find-lin_tape-device-n.patch
  * s390-tools-sles15-3-lstape-fix-output-without-SCSI-generic-sg.patch
  * s390-tools-sles15-4-lsluns-fix-to-prevent-error-messages-if-there-are-no.patch
  * s390-tools-sles15-5-lstape-fix-to-prevent-error-messages-if-there-are-no.patch
  * s390-tools-sles15-6-lstape-fix-description-of-type-and-devbusid-filter-f.patch
  * s390-tools-sles15-7-lstape-fix-SCSI-output-description-in-man-page.patch
  * s390-tools-sles15-8-lstape-fix-SCSI-HBA-CCW-device-bus-ID-e.g.-for-virti.patch
  * s390-tools-sles15-cpi-add-unit-install-section.patch
  * s390-tools-sles15-cpuplugd-Improve-systemctl-start-error-handling.patch
  * s390-tools-sles15-dbginfo-add-data-for-ps-cpprot.patch
  * s390-tools-sles15-Drop-device_id-parameter.patch
  * s390-tools-sles15-Fix-truncation-warning.patch
  * s390-tools-sles15-Fixup-dasdfmt_get_volser.patch
  * s390-tools-sles15-Fixup-device-name-handling.patch
  * s390-tools-sles15-hmcdrvfs-fix-parsing-of-link-count.patch
  * s390-tools-sles15-iucvterm-include-ctype-for-toupper.patch
  * s390-tools-sles15-lsluns-clarify-discovery-use-case-relation-to-NPIV-a.patch
  * s390-tools-sles15-lsluns-complement-alternative-tools-with-lszdev.patch
  * s390-tools-sles15-lsluns-document-restriction-to-zfcp-only-systems.patch
  * s390-tools-sles15-lsluns-do-not-print-confusing-messages-when-a-filter.patch
  * s390-tools-sles15-lsluns-do-not-scan-all-if-filters-match-nothing.patch
  * s390-tools-sles15-lsluns-enhance-usage-statement-and-man-page.patch
  * s390-tools-sles15-lsluns-fix-flawed-formatting-of-man-page.patch
  * s390-tools-sles15-lsluns-point-out-IBM-Storwize-configuration-requirem.patch
  * s390-tools-sles15-mon_procd-fix-parsing-of-proc-pid-stat.patch
  * s390-tools-sles15-mon_tools-Improve-systemctl-start-error-handling.patch
  * s390-tools-sles15sp1-0001-zkey-Add-properties-file-handling-routines.patch
  * s390-tools-sles15sp1-0002-zkey-Add-build-dependency-to-OpenSSL-libcrypto.patch
  * s390-tools-sles15sp1-0003-zkey-Add-helper-functions-for-comma-separated-string.patch
  * s390-tools-sles15sp1-0004-zkey-Externalize-secure-key-back-end-functions.patch
  * s390-tools-sles15sp1-0005-zkey-Add-keystore-implementation.patch
  * s390-tools-sles15sp1-0006-zkey-Add-keystore-related-commands.patch
  * s390-tools-sles15sp1-0007-zkey-Create-key-repository-and-group-during-make-ins.patch
  * s390-tools-sles15sp1-0008-zkey-Man-page-updates.patch
  * s390-tools-sles15sp1-0009-zkey-let-packaging-create-the-zkeyadm-group-and-perm.patch
  * s390-tools-sles15sp1-0010-zkey-Update-README-to-add-info-about-packaging-requi.patch
  * s390-tools-sles15sp1-0011-zkey-Typo-in-message.patch
  * s390-tools-sles15sp1-0012-zkey-Fix-memory-leak.patch
  * s390-tools-sles15sp1-0013-zkey-Fix-APQN-validation-routine.patch
  * s390-tools-sles15sp1-0014-zkey-Fix-generate-and-import-leaving-key-in-an-incon.patch
  * s390-tools-sles15sp1-0015-zkey-Add-zkey-cryptsetup-tool.patch
  * s390-tools-sles15sp1-0016-zkey-Add-man-page-for-zkey-cryptsetup.patch
  * s390-tools-sles15sp1-0017-zkey-Add-build-dependency-for-libcryptsetup-and-json.patch
  * s390-tools-sles15sp1-0018-zkey-Add-key-verification-pattern-property.patch
  * s390-tools-sles15sp1-0019-zkey-Add-volume-type-property-to-support-LUKS2-volum.patch
  * s390-tools-sles15sp1-01-chzcrypt-Corrections-at-the-chzcrypt-man-page.patch
  * s390-tools-sles15sp1-01-cpumf-Add-extended-counter-defintion-files-for-IBM-z.patch
  * s390-tools-sles15sp1-01-lszcrypt-CEX6S-exploitation.patch
  * s390-tools-sles15sp1-01-util_path-add-function-to-check-if-a-path-exists.patch
  * s390-tools-sles15sp1-01-zcryptctl-new-tool-zcryptctl-for-multiple-zcrypt-node.patch
  * s390-tools-sles15sp1-01-zdev-use-libutil-provided-path-functions.patch
  * s390-tools-sles15sp1-01-zkey-Include-sbin-into-PATH-when-executing-commands.patch
  * s390-tools-sles15sp1-02-cpumf-z14-split-counter-sets-according-to-CFVN-CSVN-.patch
  * s390-tools-sles15sp1-02-lszcrypt-fix-date-and-wrong-indentation.patch
  * s390-tools-sles15sp1-02-lszcrypt-support-for-alternate-zcrypt-device-drivers.patch
  * s390-tools-sles15sp1-02-util_path-Add-description-for-util_path_exists.patch
  * s390-tools-sles15sp1-02-zdev-Prepare-for-firmware-configuration-file-support.patch
  * s390-tools-sles15sp1-03-cpumf-cpumf_helper-read-split-counter-sets-part-2-2.patch
  * s390-tools-sles15sp1-03-util_path-Make-true-false-handling-consistent-with-o.patch
  * s390-tools-sles15sp1-03-zdev-Add-support-for-reading-firmware-configuration-.patch
  * s390-tools-sles15sp1-04-cpumf-correct-z14-counter-number.patch
  * s390-tools-sles15sp1-04-zdev-Implement-no-settle.patch
  * s390-tools-sles15sp1-04-zpcictl-Introduce-new-tool-zpcictl.patch
  * s390-tools-sles15sp1-05-cpumf-add-missing-Description-tag-for-z13-z14-ctr-12.patch
  * s390-tools-sles15sp1-05-zdev-Write-zfcp-lun-udev-rules-to-separate-files.patch
  * s390-tools-sles15sp1-05-zpcictl-include-sys-sysmacros.h-to-avoid-minor-major.patch
  * s390-tools-sles15sp1-06-cpumf-correct-counter-name-for-z13-and-z14.patch
  * s390-tools-sles15sp1-06-zdev-Add-support-for-handling-auto-configuration-dat.patch
  * s390-tools-sles15sp1-06-zpcictl-Rephrase-man-page-entries-and-tool-output.patch
  * s390-tools-sles15sp1-07-cpumf-Add-IBM-z14-ZR1-to-the-CPU-Measurement-Facilit.patch
  * s390-tools-sles15sp1-07-zdev-Integrate-firmware-auto-configuration-with-drac.patch
  * s390-tools-sles15sp1-07-zpcictl-Use-fopen-instead-of-open-for-writes.patch
  * s390-tools-sles15sp1-08-zdev-Integrate-firmware-auto-configuration-with-init.patch
  * s390-tools-sles15sp1-08-zpcictl-Read-device-link-to-obtain-device-address.patch
  * s390-tools-sles15sp1-09-zdev-Implement-internal-device-attributes.patch
  * s390-tools-sles15sp1-09-zpcictl-Make-device-node-for-NVMe-optional.patch
  * s390-tools-sles15sp1-10-zdev-Implement-support-for-early-device-configuratio.patch
  * s390-tools-sles15sp1-10-zpcictl-Change-wording-of-man-page-and-help-output.patch
  * s390-tools-sles15sp1-11-zdev-Do-not-call-zipl-on-initrd-update.patch
  * s390-tools-sles15sp1-dbginfo-gather-nvme-related-data.patch
  * s390-tools-sles15sp1-qethqoat-add-OSA-Express7S-support.patch
  * s390-tools-sles15sp1-zcrypt-refine-lszcrypt-man-page.patch
  * s390-tools-sles15sp1-zdev-Also-include-the-ctc-driver-in-the-initrd.patch
  * s390-tools-sles15sp1-zdev-fix-qeth-BridgePort-and-VNICC-conflict-checking.patch
  * s390-tools-sles15sp1-zkey-Enhance-error-message-about-missing-CCA-library.patch
  * s390-tools-sles15-zdev-Enable-running-chzdev-from-unknown-root-devices.patch
  * s390-tools-sles15-zdev-Fix-zdev-dracut-module-aborting-on-unknown-root.patch
  * s390-tools-sles15-zdev-Use-correct-path-to-vmcp-binary.patch
  * s390-tools-sles15-ziomon-re-add-missing-line.patch
  * s390-tools-sles15-zipl-remove-invalid-dasdview-command-line-option.patch
- Added s390-tools-sles15sp1-ziomon-fix-utilization-data-recording-with-multi-dig.patch
  ziomon: fix utilization recording with multi-digit scsi hosts
  (bsc#1141876)

OBS-URL: https://build.opensuse.org/request/show/750974
OBS-URL: https://build.opensuse.org/package/show/Base:System/s390-tools?expand=0&rev=83
2019-11-26 09:42:09 +00:00

426 lines
14 KiB
Diff

Subject: zkey: Add support for validating AES CIPHER keys
From: Ingo Franzki <ifranzki@linux.ibm.com>
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 <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
---
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;