s390-tools/s390-tools-sles15sp2-07-zkey-Add-function-to-cross-check-APQNs-for-valid-mas.patch
Mark Post 50eb270fbf Accepting request 750974 from home:markkp:branches:Base:System
- Upgraded to version 2.11.0 (jsc#7831)
- Updated the cputype script and read_values program to recognize
  machine types up through the new z15.
- Added the following patches (bsc#1151859)
  * s390-tools-sles15sp2-01-zkey-Separate-and-rework-CCA-host-library-loading.patch
  * s390-tools-sles15sp2-02-zkey-Move-utility-functions-into-separate-source-fil.patch
  * s390-tools-sles15sp2-03-zkey-Add-utility-function-to-get-the-serial-number-o.patch
  * s390-tools-sles15sp2-04-zkey-Add-utility-function-to-get-the-mkvp-of-a-crypt.patch
  * s390-tools-sles15sp2-05-zkey-add-function-to-iterate-over-all-available-CCA-.patch
  * s390-tools-sles15sp2-06-zkey-Add-function-to-print-the-MKVPs-of-APQNs.patch
  * s390-tools-sles15sp2-07-zkey-Add-function-to-cross-check-APQNs-for-valid-mas.patch
  * s390-tools-sles15sp2-08-zkey-Add-function-to-obtain-the-mkvp-of-a-secure-key.patch
  * s390-tools-sles15sp2-09-zkey-Display-MKVP-when-validating-a-secure-key.patch
  * s390-tools-sles15sp2-10-zkey-Cross-check-APQNs-when-generating-secure-keys.patch
  * s390-tools-sles15sp2-11-zkey-Cross-check-APQNs-when-validating-secure-keys.patch
  * s390-tools-sles15sp2-12-zkey-Cross-check-APQNs-when-importing-secure-keys.patch
  * s390-tools-sles15sp2-13-zkey-Cross-check-APQNs-when-changing-APQN-associatio.patch
  * s390-tools-sles15sp2-14-zkey-Add-function-to-select-a-specific-CCA-adapter.patch
  * s390-tools-sles15sp2-15-zkey-Add-function-to-select-a-CCA-adapter-by-mkvp.patch
  * s390-tools-sles15sp2-16-zkey-Select-CCA-adapter-when-re-enciphering.patch
  * s390-tools-sles15sp2-17-zkey-cryptsetup-Add-to-new-and-from-old-options.patch
- Added the following patches (bsc#1151858)
  * s390-tools-sles15sp2-18-zkey-Display-key-type-with-list-and-validate-command.patch
  * s390-tools-sles15sp2-19-zkey-Allow-to-filter-list-output-by-key-type.patch
  * s390-tools-sles15sp2-20-zkey-Allow-to-specify-the-key-type-with-the-generate.patch
  * s390-tools-sles15sp2-21-zkey-Preparations-for-introducing-a-new-key-type.patch
  * s390-tools-sles15sp2-22-zkey-Introduce-the-CCA-AESCIPHER-key-type.patch
  * s390-tools-sles15sp2-23-zkey-Add-wrappers-for-the-new-IOCTLs-with-fallback-t.patch
  * s390-tools-sles15sp2-24-zkey-Add-helper-functions-to-build-lists-of-APQNs.patch
  * s390-tools-sles15sp2-25-zkey-Add-support-for-generating-AES-CIPHER-keys.patch
  * s390-tools-sles15sp2-26-zkey-Add-support-for-validating-AES-CIPHER-keys.patch
  * s390-tools-sles15sp2-27-zkey-Add-support-for-re-enciphering-AES-CIPHER-keys.patch
  * s390-tools-sles15sp2-28-zkey-Check-crypto-card-level-during-APQN-cross-check.patch
  * s390-tools-sles15sp2-29-zkey-Add-helper-function-to-query-the-CCA-firmware-v.patch
  * s390-tools-sles15sp2-30-zkey-Add-helper-function-to-convert-secure-keys-betw.patch
  * s390-tools-sles15sp2-31-zkey-Add-helper-function-to-restrict-export-of-secur.patch
  * s390-tools-sles15sp2-32-zkey-Add-helper-function-to-check-an-AES-CIPHER-key.patch
  * s390-tools-sles15sp2-33-zkey-Add-key-checks-when-importing-a-CCA-AESCIPHER-k.patch
  * s390-tools-sles15sp2-34-zkey-Add-convert-command-to-convert-keys-from-one-ty.patch
  * s390-tools-sles15sp2-35-zkey-Allow-zkey-cryptsetup-setkey-to-set-different-k.patch
- Added the following patches (bsc#1153757)
  * s390-tools-sles15sp2-zcrypt-CEX7S-exploitation-support.patch
  * s390-tools-sles15sp2-zcryptstats-Add-support-for-CEX7.patch
- Added s390-tools-sles15sp2-Close-file-descriptor-when-checking-for-read-only.patch
- Forward-ported the following patches to work with the restructuring IBM did for
  this version
  * dasdfmt-retry-BIODASDINFO-if-device-is-busy.patch
  * s390-tools-sles12-fdasd-skip-partition-check-and-BLKRRPART-ioctl.patch
  * s390-tools-sles15-Allow-multiple-device-arguments.patch 
  * s390-tools-sles15-Format-devices-in-parallel.patch
  * s390-tools-sles15-Implement-f-for-backwards-compability.patch
  * s390-tools-sles15-Implement-Y-yast_mode.patch
- Removed the following obsolete patches:
  * s390-tools-sles15-1-lstape-fix-output-with-SCSI-lin_tape-and-multiple-pa.patch
  * s390-tools-sles15-2-lstape-fix-to-prefer-sysfs-to-find-lin_tape-device-n.patch
  * s390-tools-sles15-3-lstape-fix-output-without-SCSI-generic-sg.patch
  * s390-tools-sles15-4-lsluns-fix-to-prevent-error-messages-if-there-are-no.patch
  * s390-tools-sles15-5-lstape-fix-to-prevent-error-messages-if-there-are-no.patch
  * s390-tools-sles15-6-lstape-fix-description-of-type-and-devbusid-filter-f.patch
  * s390-tools-sles15-7-lstape-fix-SCSI-output-description-in-man-page.patch
  * s390-tools-sles15-8-lstape-fix-SCSI-HBA-CCW-device-bus-ID-e.g.-for-virti.patch
  * s390-tools-sles15-cpi-add-unit-install-section.patch
  * s390-tools-sles15-cpuplugd-Improve-systemctl-start-error-handling.patch
  * s390-tools-sles15-dbginfo-add-data-for-ps-cpprot.patch
  * s390-tools-sles15-Drop-device_id-parameter.patch
  * s390-tools-sles15-Fix-truncation-warning.patch
  * s390-tools-sles15-Fixup-dasdfmt_get_volser.patch
  * s390-tools-sles15-Fixup-device-name-handling.patch
  * s390-tools-sles15-hmcdrvfs-fix-parsing-of-link-count.patch
  * s390-tools-sles15-iucvterm-include-ctype-for-toupper.patch
  * s390-tools-sles15-lsluns-clarify-discovery-use-case-relation-to-NPIV-a.patch
  * s390-tools-sles15-lsluns-complement-alternative-tools-with-lszdev.patch
  * s390-tools-sles15-lsluns-document-restriction-to-zfcp-only-systems.patch
  * s390-tools-sles15-lsluns-do-not-print-confusing-messages-when-a-filter.patch
  * s390-tools-sles15-lsluns-do-not-scan-all-if-filters-match-nothing.patch
  * s390-tools-sles15-lsluns-enhance-usage-statement-and-man-page.patch
  * s390-tools-sles15-lsluns-fix-flawed-formatting-of-man-page.patch
  * s390-tools-sles15-lsluns-point-out-IBM-Storwize-configuration-requirem.patch
  * s390-tools-sles15-mon_procd-fix-parsing-of-proc-pid-stat.patch
  * s390-tools-sles15-mon_tools-Improve-systemctl-start-error-handling.patch
  * s390-tools-sles15sp1-0001-zkey-Add-properties-file-handling-routines.patch
  * s390-tools-sles15sp1-0002-zkey-Add-build-dependency-to-OpenSSL-libcrypto.patch
  * s390-tools-sles15sp1-0003-zkey-Add-helper-functions-for-comma-separated-string.patch
  * s390-tools-sles15sp1-0004-zkey-Externalize-secure-key-back-end-functions.patch
  * s390-tools-sles15sp1-0005-zkey-Add-keystore-implementation.patch
  * s390-tools-sles15sp1-0006-zkey-Add-keystore-related-commands.patch
  * s390-tools-sles15sp1-0007-zkey-Create-key-repository-and-group-during-make-ins.patch
  * s390-tools-sles15sp1-0008-zkey-Man-page-updates.patch
  * s390-tools-sles15sp1-0009-zkey-let-packaging-create-the-zkeyadm-group-and-perm.patch
  * s390-tools-sles15sp1-0010-zkey-Update-README-to-add-info-about-packaging-requi.patch
  * s390-tools-sles15sp1-0011-zkey-Typo-in-message.patch
  * s390-tools-sles15sp1-0012-zkey-Fix-memory-leak.patch
  * s390-tools-sles15sp1-0013-zkey-Fix-APQN-validation-routine.patch
  * s390-tools-sles15sp1-0014-zkey-Fix-generate-and-import-leaving-key-in-an-incon.patch
  * s390-tools-sles15sp1-0015-zkey-Add-zkey-cryptsetup-tool.patch
  * s390-tools-sles15sp1-0016-zkey-Add-man-page-for-zkey-cryptsetup.patch
  * s390-tools-sles15sp1-0017-zkey-Add-build-dependency-for-libcryptsetup-and-json.patch
  * s390-tools-sles15sp1-0018-zkey-Add-key-verification-pattern-property.patch
  * s390-tools-sles15sp1-0019-zkey-Add-volume-type-property-to-support-LUKS2-volum.patch
  * s390-tools-sles15sp1-01-chzcrypt-Corrections-at-the-chzcrypt-man-page.patch
  * s390-tools-sles15sp1-01-cpumf-Add-extended-counter-defintion-files-for-IBM-z.patch
  * s390-tools-sles15sp1-01-lszcrypt-CEX6S-exploitation.patch
  * s390-tools-sles15sp1-01-util_path-add-function-to-check-if-a-path-exists.patch
  * s390-tools-sles15sp1-01-zcryptctl-new-tool-zcryptctl-for-multiple-zcrypt-node.patch
  * s390-tools-sles15sp1-01-zdev-use-libutil-provided-path-functions.patch
  * s390-tools-sles15sp1-01-zkey-Include-sbin-into-PATH-when-executing-commands.patch
  * s390-tools-sles15sp1-02-cpumf-z14-split-counter-sets-according-to-CFVN-CSVN-.patch
  * s390-tools-sles15sp1-02-lszcrypt-fix-date-and-wrong-indentation.patch
  * s390-tools-sles15sp1-02-lszcrypt-support-for-alternate-zcrypt-device-drivers.patch
  * s390-tools-sles15sp1-02-util_path-Add-description-for-util_path_exists.patch
  * s390-tools-sles15sp1-02-zdev-Prepare-for-firmware-configuration-file-support.patch
  * s390-tools-sles15sp1-03-cpumf-cpumf_helper-read-split-counter-sets-part-2-2.patch
  * s390-tools-sles15sp1-03-util_path-Make-true-false-handling-consistent-with-o.patch
  * s390-tools-sles15sp1-03-zdev-Add-support-for-reading-firmware-configuration-.patch
  * s390-tools-sles15sp1-04-cpumf-correct-z14-counter-number.patch
  * s390-tools-sles15sp1-04-zdev-Implement-no-settle.patch
  * s390-tools-sles15sp1-04-zpcictl-Introduce-new-tool-zpcictl.patch
  * s390-tools-sles15sp1-05-cpumf-add-missing-Description-tag-for-z13-z14-ctr-12.patch
  * s390-tools-sles15sp1-05-zdev-Write-zfcp-lun-udev-rules-to-separate-files.patch
  * s390-tools-sles15sp1-05-zpcictl-include-sys-sysmacros.h-to-avoid-minor-major.patch
  * s390-tools-sles15sp1-06-cpumf-correct-counter-name-for-z13-and-z14.patch
  * s390-tools-sles15sp1-06-zdev-Add-support-for-handling-auto-configuration-dat.patch
  * s390-tools-sles15sp1-06-zpcictl-Rephrase-man-page-entries-and-tool-output.patch
  * s390-tools-sles15sp1-07-cpumf-Add-IBM-z14-ZR1-to-the-CPU-Measurement-Facilit.patch
  * s390-tools-sles15sp1-07-zdev-Integrate-firmware-auto-configuration-with-drac.patch
  * s390-tools-sles15sp1-07-zpcictl-Use-fopen-instead-of-open-for-writes.patch
  * s390-tools-sles15sp1-08-zdev-Integrate-firmware-auto-configuration-with-init.patch
  * s390-tools-sles15sp1-08-zpcictl-Read-device-link-to-obtain-device-address.patch
  * s390-tools-sles15sp1-09-zdev-Implement-internal-device-attributes.patch
  * s390-tools-sles15sp1-09-zpcictl-Make-device-node-for-NVMe-optional.patch
  * s390-tools-sles15sp1-10-zdev-Implement-support-for-early-device-configuratio.patch
  * s390-tools-sles15sp1-10-zpcictl-Change-wording-of-man-page-and-help-output.patch
  * s390-tools-sles15sp1-11-zdev-Do-not-call-zipl-on-initrd-update.patch
  * s390-tools-sles15sp1-dbginfo-gather-nvme-related-data.patch
  * s390-tools-sles15sp1-qethqoat-add-OSA-Express7S-support.patch
  * s390-tools-sles15sp1-zcrypt-refine-lszcrypt-man-page.patch
  * s390-tools-sles15sp1-zdev-Also-include-the-ctc-driver-in-the-initrd.patch
  * s390-tools-sles15sp1-zdev-fix-qeth-BridgePort-and-VNICC-conflict-checking.patch
  * s390-tools-sles15sp1-zkey-Enhance-error-message-about-missing-CCA-library.patch
  * s390-tools-sles15-zdev-Enable-running-chzdev-from-unknown-root-devices.patch
  * s390-tools-sles15-zdev-Fix-zdev-dracut-module-aborting-on-unknown-root.patch
  * s390-tools-sles15-zdev-Use-correct-path-to-vmcp-binary.patch
  * s390-tools-sles15-ziomon-re-add-missing-line.patch
  * s390-tools-sles15-zipl-remove-invalid-dasdview-command-line-option.patch
- Added s390-tools-sles15sp1-ziomon-fix-utilization-data-recording-with-multi-dig.patch
  ziomon: fix utilization recording with multi-digit scsi hosts
  (bsc#1141876)

OBS-URL: https://build.opensuse.org/request/show/750974
OBS-URL: https://build.opensuse.org/package/show/Base:System/s390-tools?expand=0&rev=83
2019-11-26 09:42:09 +00:00

272 lines
8.9 KiB
Diff

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