File s390-tools-sles15sp2-15-zkey-Add-function-to-select-a-CCA-adapter-by-mkvp.patch of Package s390-tools.19608

Subject: zkey: Add function to select a CCA adapter by mkvp
From: Ingo Franzki <ifranzki@linux.ibm.com>

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 <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/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
openSUSE Build Service is sponsored by