Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Step:FrontRunner
s390-tools.19914
s390-tools-sles15sp2-07-zkey-Add-function-to-cr...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File s390-tools-sles15sp2-07-zkey-Add-function-to-cross-check-APQNs-for-valid-mas.patch of Package s390-tools.19914
Subject: zkey: Add function to cross check APQNs for valid master keys 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: b32c0314746ddee69e59f892f105acd720d06452 Problem-ID: SEC1916 Upstream-Description: zkey: Add function to cross check APQNs for valid master keys Add a utility function to cross check the master keys of a set of APQNs. It checks for valid master keys in the CURRENT and OLD master key registers, as well as newly loaded master keys in the NEW register. It issues information and warning messages for various findings and also indicates improper master key setup to the caller. 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/utils.c | 217 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ zkey/utils.h | 3 2 files changed, 220 insertions(+) --- a/zkey/utils.c +++ b/zkey/utils.c @@ -506,3 +506,220 @@ int print_mk_info(const char *apqns, boo util_rec_free(info.rec); return rc; } + +struct cross_check_info { + u64 mkvp; + u64 new_mkvp; + bool key_mkvp; + u32 num_cur_match; + u32 num_old_match; + u32 num_new_match; + bool mismatch; + bool print_mks; + int num_checked; + bool verbose; +}; + +static int cross_check_mk_info(int card, int domain, void *handler_data) +{ + struct cross_check_info *info = (struct cross_check_info *)handler_data; + struct mk_info mk_info; + char temp[200]; + int rc; + + rc = sysfs_get_mkvps(card, domain, &mk_info, info->verbose); + if (rc == -ENODEV) { + info->print_mks = 1; + printf("WARNING: APQN %02x.%04x: Not available or not of " + "type CCA\n", card, domain); + return 0; + } + if (rc != 0) + return rc; + + info->num_checked++; + + if (mk_info.new_mk.mk_state == MK_STATE_PARTIAL) { + info->print_mks = 1; + sprintf(temp, "INFO: APQN %02x.%04x: The NEW master key " + "register is only partially loaded.", card, domain); + util_print_indented(temp, 0); + } + + if (info->new_mkvp == 0 && + mk_info.new_mk.mk_state == MK_STATE_FULL) + info->new_mkvp = mk_info.new_mk.mkvp; + + if (mk_info.new_mk.mk_state == MK_STATE_FULL && + mk_info.new_mk.mkvp != info->new_mkvp) { + info->print_mks = 1; + sprintf(temp, "WARNING: APQN %02x.%04x: The NEW master key " + "register contains a different master key than " + "the NEW register of other APQNs.", card, + domain); + util_print_indented(temp, 0); + } + + if (mk_info.cur_mk.mk_state != MK_STATE_VALID) { + info->print_mks = 1; + info->mismatch = 1; + printf("WARNING: APQN %02x.%04x: No master key is set.\n", card, + domain); + return 0; + } + + if (mk_info.old_mk.mk_state == MK_STATE_VALID && + mk_info.old_mk.mkvp == mk_info.cur_mk.mkvp) { + info->print_mks = 1; + sprintf(temp, "INFO: APQN %02x.%04x: The OLD master key " + "register contains the same master key as the CURRENT " + "master key register.", card, domain); + util_print_indented(temp, 0); + } + if (mk_info.new_mk.mk_state == MK_STATE_FULL && + mk_info.new_mk.mkvp == mk_info.cur_mk.mkvp) { + info->print_mks = 1; + sprintf(temp, "INFO: APQN %02x.%04x: The NEW master key " + "register contains the same master key as the CURRENT " + "master key register.", card, domain); + util_print_indented(temp, 0); + } + if (mk_info.new_mk.mk_state == MK_STATE_FULL && + mk_info.old_mk.mk_state == MK_STATE_VALID && + mk_info.new_mk.mkvp == mk_info.old_mk.mkvp) { + info->print_mks = 1; + sprintf(temp, "INFO: APQN %02x.%04x: The NEW master key " + "register contains the same master key as the OLD " + "master key register.", card, domain); + util_print_indented(temp, 0); + } + + if (info->mkvp == 0) + info->mkvp = mk_info.cur_mk.mkvp; + + if (info->key_mkvp) { + if (mk_info.cur_mk.mk_state == MK_STATE_VALID && + mk_info.cur_mk.mkvp == info->mkvp) + info->num_cur_match++; + + if (mk_info.old_mk.mk_state == MK_STATE_VALID && + mk_info.old_mk.mkvp == info->mkvp) + info->num_old_match++; + + if (mk_info.new_mk.mk_state == MK_STATE_FULL && + mk_info.new_mk.mkvp == info->mkvp) + info->num_new_match++; + } + + if (mk_info.cur_mk.mkvp != info->mkvp) { + + if (info->key_mkvp) { + if (mk_info.old_mk.mk_state == MK_STATE_VALID && + mk_info.old_mk.mkvp == info->mkvp) { + info->print_mks = 1; + sprintf(temp, "INFO: APQN %02x.%04x: The master" + " key has been changed to a new " + "master key, but the secure key has " + "not yet been re-enciphered.", card, + domain); + util_print_indented(temp, 0); + } else if (mk_info.new_mk.mk_state == MK_STATE_FULL && + mk_info.new_mk.mkvp == info->mkvp) { + info->print_mks = 1; + sprintf(temp, "INFO: APQN %02x.%04x: The master" + " key has been changed but is not " + "yet been set (made active).", card, + domain); + util_print_indented(temp, 0); + } else { + info->print_mks = 1; + info->mismatch = 1; + sprintf(temp, "WARNING: APQN %02x.%04x: The " + "CURRENT master key register contains " + "a master key that is different from " + "the one used by the secure key.", card, + domain); + util_print_indented(temp, 0); + } + } else { + info->print_mks = 1; + info->mismatch = 1; + } + } + + return 0; +} + +/** + * Cross checks the master key information for all specified APQNs. It checks + * if all specified APQNs have the same current master key, and if it matches + * the master key specified by the mkvp parameter (optional). If not, it prints + * out an information message about the APQNs that have a different master key. + * + * @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] mkvp The master key verification pattern of a secure key. + * If this is all zero, then the master keys are not + * matched against it. + * @param[in] print_mks if true, then a the full master key info of all + * specified APQns is printed, in case of a mismatch. + * @param[in] verbose if true, verbose messages are printed + * + * @returns 0 for success or a negative errno in case of an error. -ENODEV is + * returned if at least one APQN has a mismatching master key. + * -ENOTSUP is returned when the mkvps sysfs attribute is not + * available, because the zcrypt kernel module is on an older level. + */ +int cross_check_apqns(const char *apqns, u64 mkvp, bool print_mks, bool verbose) +{ + struct cross_check_info info; + char temp[200]; + int rc; + + memset(&info, 0, sizeof(info)); + info.key_mkvp = mkvp != 0; + info.mkvp = mkvp; + info.verbose = verbose; + + pr_verbose(verbose, "Cross checking APQNs with mkvp 0x%016llx: %s", + mkvp, apqns != NULL ? apqns : "ANY"); + + rc = handle_apqns(apqns, cross_check_mk_info, &info, verbose); + if (rc != 0) + return rc; + + if (info.mismatch) { + if (info.key_mkvp) + printf("WARNING: Not all APQNs have the correct master " + "key (%016llx).\n", mkvp); + else + printf("WARNING: Not all APQNs have the same master " + "key.\n"); + + rc = -ENODEV; + } + if (info.num_checked == 0) { + printf("WARNING: None of the APQNs is available or of " + "type CCA\n"); + rc = -ENODEV; + } + if (info.num_old_match > 0 && info.num_new_match > 0) { + sprintf(temp, "WARNING: On %u APQNs the OLD master key " + "register contains the master key use by the secure " + "key, and on %u APQNs the NEW master key register " + "contains the master key use by the secure key.", + info.num_old_match, info.num_new_match); + util_print_indented(temp, 0); + info.print_mks = 1; + rc = -ENODEV; + } + + if (print_mks && info.print_mks) { + printf("\n"); + print_mk_info(apqns, verbose); + printf("\n"); + } + + return rc; +} --- a/zkey/utils.h +++ b/zkey/utils.h @@ -48,4 +48,7 @@ int handle_apqns(const char *apqns, apqn int print_mk_info(const char *apqns, bool verbose); +int cross_check_apqns(const char *apqns, u64 mkvp, bool print_mks, + bool verbose); + #endif
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor