No build reason found for pool:ppc64le

File s390-tools-sles15sp2-25-zkey-Add-support-for-generating-AES-CIPHER-keys.patch of Package s390-tools.17983

Subject: zkey: Add support for generating 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: 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 <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 |   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;
 }
openSUSE Build Service is sponsored by