SHA256
1
0
forked from pool/s390-tools
s390-tools/s390-tools-07-zkey-Support-validation-of-key-of-type-PVSECRET-AES.patch
Nikolay Gueorguiev 27cc4620be - Applied more additional patches (jsc#PED-11870, jec#PED-11958)
* s390-tools-08-rust-pvimg-Fix-flag-parsing-for-allowing-dump.patch
  * s390-tools-09-rust-pvimg-Document-the-change-from--comm-key-to--cck.patch

OBS-URL: https://build.opensuse.org/package/show/Base:System/s390-tools?expand=0&rev=247
2025-02-03 08:20:55 +00:00

408 lines
15 KiB
Diff

From 833a8e7309ebf0ce70f2ee989ced5f87d6c3550b Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Mon, 19 Feb 2024 10:25:54 +0100
Subject: [PATCH] zkey: Support validation of key of type PVSECRET-AES
Keys of type PVSECRET-AES can also be verified via the pkey IOCTL
PKEY_VERIFYKEY2, but the card and domain fields must be zero, because such
a key does not use a crypto card. Also XTS keys of type PVSRCRET-AES are
not represented by 2 concatenated keys but by just one key of type
PVSECRET-AES. Thus, special handling is required for XTS keys.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Jorg Schmidbauer <jschmidb@de.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
---
zkey/keystore.c | 50 ++++++++++++++++++++++--------------
zkey/pkey.c | 46 +++++++++++++++++++++-------------
zkey/zkey-cryptsetup.1 | 4 ++-
zkey/zkey-cryptsetup.c | 45 +++++++++++++++++++--------------
zkey/zkey.1 | 8 +++---
zkey/zkey.c | 57 ++++++++++++++++++++++++------------------
6 files changed, 126 insertions(+), 84 deletions(-)
diff --git a/zkey/keystore.c b/zkey/keystore.c
index 4f795a28..58f27df2 100644
--- a/zkey/keystore.c
+++ b/zkey/keystore.c
@@ -3055,19 +3055,25 @@ static void _keystore_print_record(struct util_rec *rec,
util_rec_set(rec, REC_XTS, is_xts ? "Yes" : "No");
util_rec_set(rec, REC_KEY_TYPE, key_type);
if (validation) {
- if (valid)
- util_rec_set(rec, REC_MASTERKEY,
- "%s master key (MKVP: %s)",
- is_old_mk ? "OLD" : "CURRENT",
- printable_mkvp(
- get_card_type_for_keytype(key_type),
- mkvp));
- else
- util_rec_set(rec, REC_MASTERKEY,
- "(unknown, MKVP: %s)",
- printable_mkvp(
- get_card_type_for_keytype(key_type),
- mkvp));
+ if (mkvp != NULL) {
+ if (valid)
+ util_rec_set(rec, REC_MASTERKEY,
+ "%s master key (MKVP: %s)",
+ is_old_mk ? "OLD" : "CURRENT",
+ printable_mkvp(
+ get_card_type_for_keytype(
+ key_type),
+ mkvp));
+ else
+ util_rec_set(rec, REC_MASTERKEY,
+ "(unknown, MKVP: %s)",
+ printable_mkvp(
+ get_card_type_for_keytype(
+ key_type),
+ mkvp));
+ } else {
+ util_rec_set(rec, REC_MASTERKEY, "(none)");
+ }
}
if (volumes_argz != NULL)
util_rec_set_argz(rec, REC_VOLUMES, volumes_argz,
@@ -3294,17 +3300,22 @@ static int _keystore_process_validate(struct keystore *keystore,
valid = 1;
}
- rc = get_master_key_verification_pattern(secure_key, secure_key_size,
- mkvp, keystore->verbose);
- if (rc != 0)
- goto out;
+ if (is_secure_key(secure_key, secure_key_size)) {
+ rc = get_master_key_verification_pattern(secure_key,
+ secure_key_size,
+ mkvp,
+ keystore->verbose);
+ if (rc != 0)
+ goto out;
+ }
_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,
+ is_secure_key(secure_key, secure_key_size) ?
+ mkvp : NULL,
_keystore_passphrase_file_exists(file_names) ?
file_names->pass_filename : NULL);
@@ -3316,7 +3327,8 @@ static int _keystore_process_validate(struct keystore *keystore,
"master key\n", 0);
info->num_warnings++;
}
- if (info->noapqncheck == 0)
+ if (info->noapqncheck == 0 &&
+ is_secure_key(secure_key, secure_key_size))
if (_keystore_display_apqn_status(keystore, properties,
mkvp) != 0)
info->num_warnings++;
diff --git a/zkey/pkey.c b/zkey/pkey.c
index 53c0a550..25deb05a 100644
--- a/zkey/pkey.c
+++ b/zkey/pkey.c
@@ -1287,33 +1287,43 @@ int validate_secure_key(int pkey_fd,
{
struct pkey_verifykey2 verifykey2;
struct pkey_apqn *list = NULL;
+ bool xts, valid, securekey;
u32 i, list_entries = 0;
- bool xts, valid;
- u32 flags;
+ u32 flags = 0;
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 = is_xts_key(secure_key, secure_key_size);
+ securekey = is_secure_key(secure_key, secure_key_size);
+ xts = securekey ? is_xts_key(secure_key, secure_key_size) : false;
- flags = PKEY_FLAGS_MATCH_CUR_MKVP;
- if (is_cca_aes_data_key(secure_key, secure_key_size) ||
- is_cca_aes_cipher_key(secure_key, secure_key_size))
- flags |= PKEY_FLAGS_MATCH_ALT_MKVP;
+ if (securekey) {
+ flags = PKEY_FLAGS_MATCH_CUR_MKVP;
+ if (is_cca_aes_data_key(secure_key, secure_key_size) ||
+ is_cca_aes_cipher_key(secure_key, secure_key_size))
+ flags |= PKEY_FLAGS_MATCH_ALT_MKVP;
- rc = build_apqn_list_for_key(pkey_fd, secure_key,
- HALF_KEYSIZE_FOR_XTS(secure_key_size, xts),
- flags, 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;
+ rc = build_apqn_list_for_key(pkey_fd, secure_key,
+ HALF_KEYSIZE_FOR_XTS(
+ secure_key_size, xts),
+ flags, 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;
+ }
+ } else {
+ list = util_malloc(sizeof(struct pkey_apqn));
+ list[0].card = 0;
+ list[0].domain = 0;
+ list_entries = 1;
}
if (is_old_mk != NULL)
- *is_old_mk = true;
+ *is_old_mk = securekey ? true : false;
if (clear_key_bitsize != NULL)
*clear_key_bitsize = 0;
@@ -1333,7 +1343,7 @@ int validate_secure_key(int pkey_fd,
continue;
}
- if (is_xts_key(secure_key, secure_key_size)) {
+ if (xts) {
rc = validate_secure_xts_key(pkey_fd, &list[i],
secure_key,
secure_key_size,
@@ -1358,7 +1368,7 @@ int validate_secure_key(int pkey_fd,
* 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 &&
+ if (securekey && is_old_mk &&
(verifykey2.flags & PKEY_FLAGS_MATCH_CUR_MKVP))
*is_old_mk = false;
}
diff --git a/zkey/zkey-cryptsetup.1 b/zkey/zkey-cryptsetup.1
index 185edab9..ffd600d4 100644
--- a/zkey/zkey-cryptsetup.1
+++ b/zkey/zkey-cryptsetup.1
@@ -68,7 +68,9 @@ It also displays the attributes of the secure key, such as key size, whether
it is a secure key that can be used for the XTS cipher mode, and the master key
register (CURRENT or OLD) with which the secure key is enciphered.
For further information about master key registers, see the
-\fBreencipher\fP command.
+\fBreencipher\fP command. Keys of type \fBPVSECRET\-AES\fP do not use a
+cryptographic adapter, thus no master key information is displayed for such
+keys.
.PP
To open a key slot contained in the LUKS2 header of the volume, a passphrase is
required. You are prompted for the passphrase, unless option
diff --git a/zkey/zkey-cryptsetup.c b/zkey/zkey-cryptsetup.c
index 2b018a2a..65716f3b 100644
--- a/zkey/zkey-cryptsetup.c
+++ b/zkey/zkey-cryptsetup.c
@@ -1346,8 +1346,7 @@ static int check_keysize_and_cipher_mode(const u8 *key, size_t keysize)
}
if (strncmp(crypt_get_cipher_mode(g.cd), "xts", 3) == 0) {
- if (keysize < 2 * MIN_SECURE_KEY_SIZE ||
- (key != NULL && !is_xts_key(key, keysize))) {
+ if (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));
@@ -1539,8 +1538,9 @@ static int validate_keyslot(int keyslot, char **key, size_t *keysize,
rc = -EINVAL;
goto out;
}
- pr_verbose("Volume key is currently enciphered with %s master key",
- is_old ? "OLD" : "CURRENT");
+ if (is_secure_key((u8 *)vkey, vkeysize - ikeysize))
+ pr_verbose("Volume key is currently enciphered with %s "
+ "master key", is_old ? "OLD" : "CURRENT");
if (key != NULL)
*key = vkey;
@@ -2023,12 +2023,14 @@ static int command_validate(void)
vp_tok_avail = 1;
}
- rc = get_master_key_verification_pattern((u8 *)key, seckeysize,
- mkvp, g.verbose);
- if (rc != 0) {
- warnx("Failed to get the master key verification pattern: %s",
- strerror(-rc));
- goto out;
+ if (is_secure_key((u8 *)key, seckeysize)) {
+ rc = get_master_key_verification_pattern((u8 *)key, seckeysize,
+ mkvp, g.verbose);
+ if (rc != 0) {
+ warnx("Failed to get the master key verification "
+ "pattern: %s", strerror(-rc));
+ goto out;
+ }
}
key_type = get_key_type((u8 *)key, seckeysize);
@@ -2041,15 +2043,19 @@ static int command_validate(void)
printf(" Key type: %s\n", key_type);
if (is_valid) {
printf(" Clear key size: %lu bits\n", clear_keysize);
- printf(" Enciphered with: %s master key (MKVP: "
- "%s)\n", is_old_mk ? "OLD" : "CURRENT",
- printable_mkvp(get_card_type_for_keytype(key_type),
- mkvp));
+ if (is_secure_key((u8 *)key, seckeysize)) {
+ printf(" Enciphered with: %s master key (MKVP: "
+ "%s)\n", is_old_mk ? "OLD" : "CURRENT",
+ printable_mkvp(get_card_type_for_keytype(
+ key_type), mkvp));
+ }
} else {
printf(" Clear key size: (unknown)\n");
- printf(" Enciphered with: (unknown, MKVP: %s)\n",
- printable_mkvp(get_card_type_for_keytype(key_type),
- mkvp));
+ if (is_secure_key((u8 *)key, seckeysize)) {
+ printf(" Enciphered with: (unknown, MKVP: %s)\n",
+ printable_mkvp(get_card_type_for_keytype(
+ key_type), mkvp));
+ }
}
if (vp_tok_avail)
print_verification_pattern(vp_tok.verification_pattern);
@@ -2065,7 +2071,7 @@ static int command_validate(void)
if (!is_valid)
printf("\nATTENTION: The secure volume key is not valid.\n");
- if (is_old_mk)
+ if (is_secure_key((u8 *)key, seckeysize) && is_old_mk)
util_print_indented("\nWARNING: The secure volume key is "
"currently enciphered with the OLD "
"master key. To mitigate the danger of "
@@ -2195,7 +2201,8 @@ static int command_setkey(void)
goto out;
}
- if (is_old_mk) {
+ if (is_secure_key(newkey, newkey_size - integrity_keysize) &&
+ is_old_mk) {
util_asprintf(&msg, "The secure key in file '%s' is "
"enciphered with the master key in the OLD "
"master key register. Do you want to set this "
diff --git a/zkey/zkey.1 b/zkey/zkey.1
index 316db5f0..b44eadf1 100644
--- a/zkey/zkey.1
+++ b/zkey/zkey.1
@@ -209,7 +209,9 @@ It also displays the attributes of the secure key, such as key sizes, whether
it is a secure key that can be used for the XTS cipher mode, the master key
register (CURRENT or OLD) with which the secure key is enciphered, and other key
attributes. For further information about master key registers, see the
-\fBreencipher\fP command.
+\fBreencipher\fP command. Keys of type \fBPVSECRET\-AES\fP do not use a
+cryptographic adapter, thus no master key information is displayed for such
+keys.
.PP
The secure key can either be contained in a file in the file system, or in a
secure key repository. To validate a secure key contained in a file, specify
@@ -1599,8 +1601,8 @@ 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, \fBCCA\-AESCIPHER\fP, and \fBEP11\-AES\fP. Only keys with
-the specified key type are listed.
+\fBCCA\-AESDATA\fP, \fBCCA\-AESCIPHER\fP, \fBEP11\-AES\fP, and
+\fBPVSECRET\-AES\fP. Only keys with the specified key type are listed.
This option is only used for secure keys contained in the secure key repository.
.TP
.BR \-L ", " \-\-local\fP
diff --git a/zkey/zkey.c b/zkey/zkey.c
index 90b46106..39a527c4 100644
--- a/zkey/zkey.c
+++ b/zkey/zkey.c
@@ -558,9 +558,10 @@ 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_AESCIPHER"' "
- "and '"KEY_TYPE_EP11_AES"'. Use this option to list "
- "all keys with the specified key type.",
+ KEY_TYPE_CCA_AESDATA "', '" KEY_TYPE_CCA_AESCIPHER
+ "', '" KEY_TYPE_EP11_AES "', and '"
+ KEY_TYPE_PVSECRET_AES "'. Use this option to list all "
+ "keys with the specified key type.",
.command = COMMAND_LIST,
},
{
@@ -2345,13 +2346,16 @@ 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;
+ if (is_secure_key(secure_key, secure_key_size)) {
+ 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;
+ }
}
key_type = get_key_type(secure_key, secure_key_size);
@@ -2363,25 +2367,30 @@ static int command_validate_file(void)
printf(" Clear key size: %lu bits\n", clear_key_size);
printf(" XTS type key: %s\n",
is_xts_key(secure_key, secure_key_size) ? "Yes" : "No");
- printf(" Enciphered with: %s master key (MKVP: %s)\n",
- is_old_mk ? "OLD" : "CURRENT",
- printable_mkvp(get_card_type_for_keytype(key_type), mkvp));
+ if (is_secure_key(secure_key, secure_key_size)) {
+ printf(" Enciphered with: %s master key (MKVP: %s)\n",
+ is_old_mk ? "OLD" : "CURRENT",
+ printable_mkvp(get_card_type_for_keytype(key_type),
+ mkvp));
+ }
printf(" Verification pattern: %.*s\n", VERIFICATION_PATTERN_LEN / 2,
vp);
printf(" %.*s\n", VERIFICATION_PATTERN_LEN / 2,
&vp[VERIFICATION_PATTERN_LEN / 2]);
- rc = cross_check_apqns(NULL, mkvp,
- get_min_card_level_for_keytype(key_type),
- get_min_fw_version_for_keytype(key_type),
- get_card_type_for_keytype(key_type),
- 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;
+ if (is_secure_key(secure_key, secure_key_size)) {
+ rc = cross_check_apqns(NULL, mkvp,
+ get_min_card_level_for_keytype(key_type),
+ get_min_fw_version_for_keytype(key_type),
+ get_card_type_for_keytype(key_type),
+ 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: