diff --git a/zkey/Makefile b/zkey/Makefile index 4e65da10..100e4087 100644 --- a/zkey/Makefile +++ b/zkey/Makefile @@ -65,7 +65,7 @@ zkey-cryptsetup-skip-jsonc: all: $(BUILD_TARGETS) zkey.o: zkey.c pkey.h cca.h ep11.h misc.h -pkey.o: pkey.c pkey.h cca.h ep11.h +pkey.o: pkey.c pkey.h cca.h ep11.h utils.h cca.o: cca.c cca.h pkey.h ep11.h utils.h ep11.o: ep11.c ep11.h pkey.h cca.h utils.h utils.o: utils.h pkey.h cca.h ep11.h diff --git a/zkey/keystore.c b/zkey/keystore.c index f02cc6f4..da87d8fa 100644 --- a/zkey/keystore.c +++ b/zkey/keystore.c @@ -1732,8 +1732,9 @@ int keystore_generate_key(struct keystore *keystore, const char *name, rc = cross_check_apqns(apqns, NULL, get_min_card_level_for_keytype(key_type), - get_card_type_for_keytype(key_type), true, - keystore->verbose); + get_min_fw_version_for_keytype(key_type), + get_card_type_for_keytype(key_type), + true, keystore->verbose); if (rc == -EINVAL) goto out_free_key_filenames; if (rc != 0 && rc != -ENOTSUP && noapqncheck == 0) { @@ -1866,8 +1867,9 @@ int keystore_import_key(struct keystore *keystore, const char *name, rc = cross_check_apqns(apqns, mkvp, get_min_card_level_for_keytype(key_type), - get_card_type_for_keytype(key_type), true, - keystore->verbose); + get_min_fw_version_for_keytype(key_type), + get_card_type_for_keytype(key_type), + true, keystore->verbose); if (rc == -EINVAL) goto out_free_key; if (rc != 0 && rc != -ENOTSUP && noapqncheck == 0) { @@ -2070,6 +2072,7 @@ int keystore_change_key(struct keystore *keystore, const char *name, key_type = properties_get(key_props, PROP_NAME_KEY_TYPE); rc = cross_check_apqns(apqns_prop, 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, keystore->verbose); free(apqns_prop); @@ -2455,6 +2458,7 @@ static int _keystore_display_apqn_status(struct keystore *keystore, key_type = properties_get(properties, PROP_NAME_KEY_TYPE); rc = cross_check_apqns(apqns, 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, keystore->verbose); if (rc != 0 && rc != -ENOTSUP) @@ -4046,8 +4050,9 @@ int keystore_convert_key(struct keystore *keystore, const char *name, apqn_list = str_list_split(apqns); rc = cross_check_apqns(apqns, NULL, min_level, - get_card_type_for_keytype(key_type), true, - keystore->verbose); + get_min_fw_version_for_keytype(key_type), + get_card_type_for_keytype(key_type), + true, keystore->verbose); if (rc == -EINVAL) goto out; if (rc != 0 && rc != -ENOTSUP && !noapqncheck) { diff --git a/zkey/pkey.c b/zkey/pkey.c index 837ebfec..578a65a8 100644 --- a/zkey/pkey.c +++ b/zkey/pkey.c @@ -26,6 +26,7 @@ #include "lib/util_panic.h" #include "pkey.h" +#include "utils.h" #ifndef AF_ALG #define AF_ALG 38 @@ -1708,6 +1709,20 @@ int get_min_card_level_for_keytype(const char *key_type) return -1; } +const struct fw_version *get_min_fw_version_for_keytype(const char *key_type) +{ + static const struct fw_version ep11_fw_version = { + .major = 0, .minor = 0, .api_ordinal = 4, }; + + if (key_type == NULL) + return NULL; + + if (strcasecmp(key_type, KEY_TYPE_EP11_AES) == 0) + return &ep11_fw_version; + + return NULL; +} + /** * Returns the card type required for a specific key type * diff --git a/zkey/pkey.h b/zkey/pkey.h index ad1517c9..253cba24 100644 --- a/zkey/pkey.h +++ b/zkey/pkey.h @@ -320,6 +320,7 @@ bool is_xts_key(const u8 *key, size_t key_size); int get_key_bit_size(const u8 *key, size_t key_size, size_t *bitsize); const char *get_key_type(const u8 *key, size_t key_size); int get_min_card_level_for_keytype(const char *key_type); +const struct fw_version *get_min_fw_version_for_keytype(const char *key_type); enum card_type get_card_type_for_keytype(const char *key_type); int check_aes_cipher_key(const u8 *key, size_t key_size); diff --git a/zkey/utils.c b/zkey/utils.c index f0050f28..a2d1c376 100644 --- a/zkey/utils.c +++ b/zkey/utils.c @@ -809,6 +809,7 @@ struct cross_check_info { bool key_mkvp; enum card_type cardtype; int min_level; + const struct fw_version *min_fw_version; u32 num_cur_match; u32 num_old_match; u32 num_new_match; @@ -821,10 +822,11 @@ struct cross_check_info { 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 fw_version fw_version; enum card_type type; struct mk_info mk_info; char temp[200]; - int rc, level; + int rc, level = 0; rc = sysfs_get_mkvps(card, domain, &mk_info, info->verbose); if (rc == -ENODEV) { @@ -864,6 +866,35 @@ static int cross_check_mk_info(int card, int domain, void *handler_data) } } + if (info->min_fw_version != NULL) { + rc = sysfs_get_firmware_version(card, &fw_version, + info->verbose); + if (rc == 0) { + if (fw_version.api_ordinal < + info->min_fw_version->api_ordinal) { + info->print_mks = 1; + info->mismatch = 1; + sprintf(temp, "WARNING: APQN %02x.%04x: The " + "firmware version is too less to " + "support secure keys of that type", + card, domain); + util_print_indented(temp, 0); + } + if (info->min_level > 0 && info->min_level == level && + (fw_version.major < info->min_fw_version->major || + (fw_version.major == info->min_fw_version->major && + fw_version.minor < info->min_fw_version->minor))) { + info->print_mks = 1; + info->mismatch = 1; + sprintf(temp, "WARNING: APQN %02x.%04x: The " + "firmware version is too less to " + "support secure keys of that type", + card, domain); + util_print_indented(temp, 0); + } + } + } + if (mk_info.new_mk.mk_state == MK_STATE_PARTIAL) { info->print_mks = 1; sprintf(temp, "INFO: APQN %02x.%04x: The NEW master key " @@ -1002,6 +1033,8 @@ static int cross_check_mk_info(int card, int domain, void *handler_data) * not matched against it. * @param[in] min_level The minimum card level required. If min_level is -1 then * the card level is not checked. + * @param[in] min_fw_version The minimum firmware version required. If NULL tne + * the firmware version is not checked. * @param[in] cardtype card type (CCA, EP11 or ANY) * @param[in] print_mks if true, then a the full master key info of all * specified APQns is printed, in case of a mismatch. @@ -1013,6 +1046,7 @@ static int cross_check_mk_info(int card, int domain, void *handler_data) * available, because the zcrypt kernel module is on an older level. */ int cross_check_apqns(const char *apqns, u8 *mkvp, int min_level, + const struct fw_version *min_fw_version, enum card_type cardtype, bool print_mks, bool verbose) { struct cross_check_info info; @@ -1025,11 +1059,17 @@ int cross_check_apqns(const char *apqns, u8 *mkvp, int min_level, memcpy(info.mkvp, mkvp, sizeof(info.mkvp)); info.cardtype = cardtype; info.min_level = min_level; + info.min_fw_version = min_fw_version; info.verbose = verbose; - pr_verbose(verbose, "Cross checking APQNs with mkvp %s " - "and min-level %d: %s", printable_mkvp(cardtype, info.mkvp), - min_level, apqns != NULL ? apqns : "ANY"); + pr_verbose(verbose, "Cross checking APQNs with mkvp %s, " + "min-level %d, and min-fw-version %u.%u (api: %u): %s", + printable_mkvp(cardtype, info.mkvp), + min_level, + min_fw_version != NULL ? min_fw_version->major : 0, + min_fw_version != NULL ? min_fw_version->minor : 0, + min_fw_version != NULL ? min_fw_version->api_ordinal : 0, + apqns != NULL ? apqns : "ANY"); rc = handle_apqns(apqns, cardtype, cross_check_mk_info, &info, verbose); if (rc != 0) diff --git a/zkey/utils.h b/zkey/utils.h index 87bb104f..dd743f61 100644 --- a/zkey/utils.h +++ b/zkey/utils.h @@ -68,7 +68,8 @@ int handle_apqns(const char *apqns, enum card_type cardtype, int print_mk_info(const char *apqns, enum card_type cardtype, bool verbose); int cross_check_apqns(const char *apqns, u8 *mkvp, int min_level, - enum card_type cardtype, bool print_mks, bool verbose); + const struct fw_version *min_fw_version, + enum card_type cardtype, bool print_mks, bool verbose); bool prompt_for_yes(bool verbose); diff --git a/zkey/zkey.c b/zkey/zkey.c index 39ee3789..d0fad71b 100644 --- a/zkey/zkey.c +++ b/zkey/zkey.c @@ -1179,6 +1179,7 @@ static int command_generate(void) rc = cross_check_apqns(NULL, NULL, get_min_card_level_for_keytype(g.key_type), + get_min_fw_version_for_keytype(g.key_type), get_card_type_for_keytype(g.key_type), true, g.verbose); if (rc == -EINVAL) @@ -1510,6 +1511,7 @@ static int command_validate_file(void) 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) @@ -1786,8 +1788,9 @@ static int command_convert_file(void) } rc = cross_check_apqns(NULL, NULL, min_level, - get_card_type_for_keytype(g.key_type), true, - g.verbose); + get_min_fw_version_for_keytype(g.key_type), + get_card_type_for_keytype(g.key_type), + true, g.verbose); if (rc == -EINVAL) return EXIT_FAILURE; if (rc != 0 && rc != -ENOTSUP) {