* 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
408 lines
15 KiB
Diff
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:
|