mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
zkey: Generalize the master key verification pattern handling
Different crypto card types use different master key verification patterns (MKVPs). Generalize the handling of MKVPs so that the majority of the code does not have to care about the card type when dealing with MKVPs. Also generalize messages about the crypto card's master keys to not mention a specific card type. Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com> Reviewed-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
committed by
Jan Höppner
parent
2ca442feed
commit
ce4704f365
+3
-2
@@ -70,13 +70,14 @@ cca.o: cca.c cca.h pkey.h utils.h
|
||||
utils.o: utils.h pkey.h
|
||||
properties.o: check-dep-zkey properties.c properties.h
|
||||
keystore.o: keystore.c keystore.h properties.h pkey.h cca.h utils.h
|
||||
zkey-cryptsetup.o: check-dep-zkey-cryptsetup zkey-cryptsetup.c pkey.h cca.h misc.h
|
||||
zkey-cryptsetup.o: check-dep-zkey-cryptsetup zkey-cryptsetup.c pkey.h cca.h \
|
||||
misc.h utils.h
|
||||
|
||||
zkey: LDLIBS = -ldl -lcrypto
|
||||
zkey: zkey.o pkey.o cca.o properties.o keystore.o utils.o $(libs)
|
||||
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||
|
||||
zkey-cryptsetup: LDLIBS = -ldl -lcryptsetup -ljson-c
|
||||
zkey-cryptsetup: LDLIBS = -ldl -lcryptsetup -ljson-c -lcrypto
|
||||
zkey-cryptsetup: zkey-cryptsetup.o pkey.o cca.o utils.o $(libs)
|
||||
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||
|
||||
|
||||
+9
-7
@@ -630,7 +630,7 @@ int select_cca_adapter(struct cca_lib *cca, int card, int domain, bool verbose)
|
||||
}
|
||||
|
||||
struct find_mkvp_info {
|
||||
u64 mkvp;
|
||||
u8 mkvp[MKVP_LENGTH];
|
||||
unsigned int flags;
|
||||
bool found;
|
||||
int card;
|
||||
@@ -653,12 +653,12 @@ static int find_mkvp(int card, int domain, void *handler_data)
|
||||
|
||||
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)
|
||||
MKVP_EQ(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)
|
||||
MKVP_EQ(mk_info.old_mk.mkvp, info->mkvp))
|
||||
found = true;
|
||||
|
||||
if (info->flags & FLAG_SEL_CCA_NEW_MUST_BE_SET)
|
||||
@@ -700,18 +700,20 @@ static int find_mkvp(int card, int domain, void *handler_data)
|
||||
* 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,
|
||||
int select_cca_adapter_by_mkvp(struct cca_lib *cca, u8 *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");
|
||||
util_assert(mkvp != NULL, "Internal error: mkvp is NULL");
|
||||
|
||||
pr_verbose(verbose, "Select mkvp %016llx in APQNs %s for the CCA host "
|
||||
"library", mkvp, apqns == 0 ? "ANY" : apqns);
|
||||
pr_verbose(verbose, "Select mkvp %s in APQNs %s for the CCA host "
|
||||
"library", printable_mkvp(CARD_TYPE_CCA, mkvp),
|
||||
apqns == 0 ? "ANY" : apqns);
|
||||
|
||||
info.mkvp = mkvp;
|
||||
memcpy(info.mkvp, mkvp, sizeof(info.mkvp));
|
||||
info.flags = flags;
|
||||
info.found = false;
|
||||
info.card = 0;
|
||||
|
||||
+1
-1
@@ -129,7 +129,7 @@ int select_cca_adapter(struct cca_lib *cca, int card, int domain, bool verbose);
|
||||
#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,
|
||||
int select_cca_adapter_by_mkvp(struct cca_lib *cca, u8 *mkvp, const char *apqns,
|
||||
unsigned int flags, bool verbose);
|
||||
|
||||
void print_msg_for_cca_envvars(const char *key_name);
|
||||
|
||||
+39
-33
@@ -1728,7 +1728,7 @@ int keystore_generate_key(struct keystore *keystore, const char *name,
|
||||
if (rc != 0)
|
||||
goto out_free_key_filenames;
|
||||
|
||||
rc = cross_check_apqns(apqns, 0,
|
||||
rc = cross_check_apqns(apqns, NULL,
|
||||
get_min_card_level_for_keytype(key_type),
|
||||
get_card_type_for_keytype(key_type), true,
|
||||
keystore->verbose);
|
||||
@@ -1822,9 +1822,9 @@ int keystore_import_key(struct keystore *keystore, const char *name,
|
||||
struct properties *key_props = NULL;
|
||||
size_t secure_key_size;
|
||||
const char *key_type;
|
||||
u8 mkvp[MKVP_LENGTH];
|
||||
int selected = 1;
|
||||
u8 *secure_key;
|
||||
u64 mkvp;
|
||||
int rc;
|
||||
|
||||
util_assert(keystore != NULL, "Internal error: keystore is NULL");
|
||||
@@ -1855,7 +1855,7 @@ int keystore_import_key(struct keystore *keystore, const char *name,
|
||||
}
|
||||
|
||||
rc = get_master_key_verification_pattern(secure_key, secure_key_size,
|
||||
&mkvp, keystore->verbose);
|
||||
mkvp, keystore->verbose);
|
||||
if (rc != 0) {
|
||||
warnx("Failed to get the master key verification pattern: %s",
|
||||
strerror(-rc));
|
||||
@@ -1999,9 +1999,9 @@ int keystore_change_key(struct keystore *keystore, const char *name,
|
||||
struct properties *key_props = NULL;
|
||||
char *apqns_prop, *key_type;
|
||||
size_t secure_key_size;
|
||||
u8 mkvp[MKVP_LENGTH];
|
||||
u8 *secure_key;
|
||||
char temp[30];
|
||||
u64 mkvp;
|
||||
int rc;
|
||||
|
||||
util_assert(keystore != NULL, "Internal error: keystore is NULL");
|
||||
@@ -2058,7 +2058,7 @@ int keystore_change_key(struct keystore *keystore, const char *name,
|
||||
|
||||
rc = get_master_key_verification_pattern(secure_key,
|
||||
secure_key_size,
|
||||
&mkvp,
|
||||
mkvp,
|
||||
keystore->verbose);
|
||||
free(secure_key);
|
||||
if (rc)
|
||||
@@ -2283,7 +2283,7 @@ static void _keystore_print_record(struct util_rec *rec,
|
||||
bool validation, const char *skey_filename,
|
||||
size_t secure_key_size, bool is_xts,
|
||||
size_t clear_key_bitsize, bool valid,
|
||||
bool is_old_mk, bool reenc_pending, u64 mkvp)
|
||||
bool is_old_mk, bool reenc_pending, u8 *mkvp)
|
||||
{
|
||||
char temp_vp[VERIFICATION_PATTERN_LEN + 2];
|
||||
char *volumes_argz = NULL;
|
||||
@@ -2347,11 +2347,17 @@ static void _keystore_print_record(struct util_rec *rec,
|
||||
if (validation) {
|
||||
if (valid)
|
||||
util_rec_set(rec, REC_MASTERKEY,
|
||||
"%s CCA master key (MKVP: %016llx)",
|
||||
is_old_mk ? "OLD" : "CURRENT", mkvp);
|
||||
"%s master key (MKVP: %s)",
|
||||
is_old_mk ? "OLD" : "CURRENT",
|
||||
printable_mkvp(
|
||||
get_card_type_for_keytype(key_type),
|
||||
mkvp));
|
||||
else
|
||||
util_rec_set(rec, REC_MASTERKEY,
|
||||
"(unknown, MKVP: %016llx)", mkvp);
|
||||
"(unknown, MKVP: %s)",
|
||||
printable_mkvp(
|
||||
get_card_type_for_keytype(key_type),
|
||||
mkvp));
|
||||
}
|
||||
if (volumes_argz != NULL)
|
||||
util_rec_set_argz(rec, REC_VOLUMES, volumes_argz,
|
||||
@@ -2433,7 +2439,7 @@ struct validate_info {
|
||||
*/
|
||||
static int _keystore_display_apqn_status(struct keystore *keystore,
|
||||
struct properties *properties,
|
||||
u64 mkvp)
|
||||
u8 *mkvp)
|
||||
{
|
||||
int rc, warning = 0;
|
||||
char *apqns;
|
||||
@@ -2525,11 +2531,11 @@ static int _keystore_process_validate(struct keystore *keystore,
|
||||
char **apqn_list = NULL;
|
||||
size_t clear_key_bitsize;
|
||||
size_t secure_key_size;
|
||||
u8 mkvp[MKVP_LENGTH];
|
||||
char *apqns = NULL;
|
||||
u8 *secure_key;
|
||||
int is_old_mk;
|
||||
int rc, valid;
|
||||
u64 mkvp;
|
||||
|
||||
rc = _keystore_ensure_keyfiles_exist(file_names, name);
|
||||
if (rc != 0)
|
||||
@@ -2559,7 +2565,7 @@ static int _keystore_process_validate(struct keystore *keystore,
|
||||
}
|
||||
|
||||
rc = get_master_key_verification_pattern(secure_key, secure_key_size,
|
||||
&mkvp, keystore->verbose);
|
||||
mkvp, keystore->verbose);
|
||||
free(secure_key);
|
||||
if (rc)
|
||||
goto out;
|
||||
@@ -2573,9 +2579,9 @@ static int _keystore_process_validate(struct keystore *keystore,
|
||||
|
||||
if (valid && is_old_mk) {
|
||||
util_print_indented("WARNING: The secure key is currently "
|
||||
"enciphered with the OLD CCA master key. "
|
||||
"enciphered with the OLD master key. "
|
||||
"To mitigate the danger of data loss "
|
||||
"re-encipher it with the CURRENT CCA "
|
||||
"re-encipher it with the CURRENT "
|
||||
"master key\n", 0);
|
||||
info->num_warnings++;
|
||||
}
|
||||
@@ -2685,10 +2691,10 @@ static int _keystore_perform_reencipher(struct keystore *keystore,
|
||||
bool is_old_mk, const char *apqns)
|
||||
{
|
||||
int rc, selected = 1;
|
||||
u64 mkvp;
|
||||
u8 mkvp[MKVP_LENGTH];
|
||||
|
||||
rc = get_master_key_verification_pattern(secure_key, secure_key_size,
|
||||
&mkvp, keystore->verbose);
|
||||
mkvp, keystore->verbose);
|
||||
if (rc != 0) {
|
||||
warnx("Failed to get the master key verification pattern: %s",
|
||||
strerror(-rc));
|
||||
@@ -2700,16 +2706,16 @@ static int _keystore_perform_reencipher(struct keystore *keystore,
|
||||
if (is_old_mk) {
|
||||
params->from_old = 1;
|
||||
util_print_indented("The secure key is currently "
|
||||
"enciphered with the OLD CCA "
|
||||
"enciphered with the OLD "
|
||||
"master key and is being "
|
||||
"re-enciphered with the CURRENT "
|
||||
"CCA master key\n", 0);
|
||||
"master key\n", 0);
|
||||
} else {
|
||||
params->to_new = 1;
|
||||
util_print_indented("The secure key is currently "
|
||||
"enciphered with the CURRENT CCA "
|
||||
"enciphered with the CURRENT "
|
||||
"master key and is being "
|
||||
"re-enciphered with the NEW CCA "
|
||||
"re-enciphered with the NEW "
|
||||
"master key\n", 0);
|
||||
}
|
||||
}
|
||||
@@ -2720,7 +2726,7 @@ static int _keystore_perform_reencipher(struct keystore *keystore,
|
||||
|
||||
pr_verbose(keystore,
|
||||
"Secure key '%s' will be re-enciphered from OLD "
|
||||
"to the CURRENT CCA master key", name);
|
||||
"to the CURRENT master key", name);
|
||||
|
||||
rc = select_cca_adapter_by_mkvp(cca, mkvp, apqns,
|
||||
FLAG_SEL_CCA_MATCH_OLD_MKVP,
|
||||
@@ -2740,7 +2746,7 @@ static int _keystore_perform_reencipher(struct keystore *keystore,
|
||||
keystore->verbose);
|
||||
if (rc != 0) {
|
||||
warnx("Failed to re-encipher '%s' from OLD to "
|
||||
"CURRENT CCA master key", name);
|
||||
"CURRENT master key", name);
|
||||
if (!selected)
|
||||
print_msg_for_cca_envvars("secure AES key");
|
||||
return rc;
|
||||
@@ -2749,7 +2755,7 @@ static int _keystore_perform_reencipher(struct keystore *keystore,
|
||||
if (params->to_new) {
|
||||
pr_verbose(keystore,
|
||||
"Secure key '%s' will be re-enciphered from "
|
||||
"CURRENT to the NEW CCA master key", name);
|
||||
"CURRENT to the NEW master key", name);
|
||||
|
||||
if (params->inplace == -1)
|
||||
params->inplace = 0;
|
||||
@@ -2775,7 +2781,7 @@ static int _keystore_perform_reencipher(struct keystore *keystore,
|
||||
keystore->verbose);
|
||||
if (rc != 0) {
|
||||
warnx("Failed to re-encipher '%s' from CURRENT to "
|
||||
"NEW CCA master key", name);
|
||||
"NEW master key", name);
|
||||
if (!selected)
|
||||
print_msg_for_cca_envvars("secure AES key");
|
||||
return rc;
|
||||
@@ -2857,7 +2863,7 @@ static int _keystore_process_reencipher(struct keystore *keystore,
|
||||
if (params.complete) {
|
||||
warnx("Key '%s' is not valid, re-enciphering is not "
|
||||
"completed", name);
|
||||
warnx("The new CCA master key might yet have to be set "
|
||||
warnx("The new master key might yet have to be set "
|
||||
"as the CURRENT master key.");
|
||||
} else {
|
||||
warnx("Key '%s' is not valid, it is not re-enciphered",
|
||||
@@ -2940,7 +2946,7 @@ static int _keystore_process_reencipher(struct keystore *keystore,
|
||||
|
||||
if (params.inplace != 1) {
|
||||
util_asprintf(&temp, "Staged re-enciphering is initiated for "
|
||||
"key '%s'. After the NEW CCA master key has been "
|
||||
"key '%s'. After the NEW master key has been "
|
||||
"set to become the CURRENT master key run "
|
||||
"'zkey reencipher' with option '--complete' to "
|
||||
"complete the re-enciphering process", name);
|
||||
@@ -2976,17 +2982,17 @@ out:
|
||||
* @param[in] name_filter the name filter to select the key (can be NULL)
|
||||
* @param[in] apqn_filter the APQN filter to seletc the key (can be NULL)
|
||||
* @param[in] from_old If true the key is reenciphered from the OLD to the
|
||||
* CURRENT CCA master key.
|
||||
* CURRENT master key.
|
||||
* @param[in] to_new If true the key is reenciphered from the CURRENT to
|
||||
* the OLD CCA master key.
|
||||
* the OLD master key.
|
||||
* @param[in] inplace if true, the key will be re-enciphere in-place
|
||||
* @param[in] staged if true, the key will be re-enciphere not in-place
|
||||
* @param[in] complete if true, a pending re-encipherment is completed
|
||||
* @param[in] pkey_fd the file descriptor of /dev/pkey
|
||||
* @param[in] cca the CCA library struct
|
||||
* Note: if both from Old and toNew are FALSE, then the reencipherement mode is
|
||||
* Note: if both fromOld and toNew are FALSE, then the reencipherement mode is
|
||||
* detected automatically. If both are TRUE then the key is reenciphered
|
||||
* from the OLD to the NEW CCA master key.
|
||||
* from the OLD to the NEW master key.
|
||||
* Note: if both inplace and staged are FLASE, then the key is re-enciphered
|
||||
* inplace when for OLD-to-CURRENT, and is reenciphered staged for
|
||||
* CURRENT-to-NEW.
|
||||
@@ -3982,9 +3988,9 @@ int keystore_convert_key(struct keystore *keystore, const char *name,
|
||||
char **apqn_list = NULL;
|
||||
size_t secure_key_size;
|
||||
u8 *secure_key = NULL;
|
||||
u8 mkvp[MKVP_LENGTH];
|
||||
char *apqns = NULL;
|
||||
char *temp;
|
||||
u64 mkvp;
|
||||
|
||||
util_assert(keystore != NULL, "Internal error: keystore is NULL");
|
||||
util_assert(name != NULL, "Internal error: name is NULL");
|
||||
@@ -4037,7 +4043,7 @@ int keystore_convert_key(struct keystore *keystore, const char *name,
|
||||
if (apqns != NULL)
|
||||
apqn_list = str_list_split(apqns);
|
||||
|
||||
rc = cross_check_apqns(apqns, 0, min_level,
|
||||
rc = cross_check_apqns(apqns, NULL, min_level,
|
||||
get_card_type_for_keytype(key_type), true,
|
||||
keystore->verbose);
|
||||
if (rc == -EINVAL)
|
||||
@@ -4055,7 +4061,7 @@ int keystore_convert_key(struct keystore *keystore, const char *name,
|
||||
goto out;
|
||||
|
||||
rc = get_master_key_verification_pattern(secure_key, secure_key_size,
|
||||
&mkvp, keystore->verbose);
|
||||
mkvp, keystore->verbose);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
|
||||
+5
-11
@@ -753,7 +753,6 @@ static int build_apqn_list_for_key(int pkey_fd, u8 *key, u32 keylen, u32 flags,
|
||||
u32 *apqn_entries, bool verbose)
|
||||
{
|
||||
struct pkey_apqns4key apqns4key;
|
||||
u64 mkvp;
|
||||
int rc;
|
||||
|
||||
util_assert(pkey_fd != -1, "Internal error: pkey_fd is -1");
|
||||
@@ -796,12 +795,6 @@ static int build_apqn_list_for_key(int pkey_fd, u8 *key, u32 keylen, u32 flags,
|
||||
if (!is_cca_aes_data_key(key, keylen))
|
||||
return -ENOTSUP;
|
||||
|
||||
rc = get_master_key_verification_pattern(key, keylen,
|
||||
&mkvp,
|
||||
verbose);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
rc = build_apqn_list_for_aes_data(apqn_list, apqns,
|
||||
apqn_entries,
|
||||
verbose);
|
||||
@@ -1218,7 +1211,7 @@ static int validate_secure_xts_key(int pkey_fd, struct pkey_apqn *apqn,
|
||||
* @param[out] clear_key_bitsize on return , the cryptographic size of the
|
||||
* clear key
|
||||
* @param[out] is_old_mk in return set to 1 to indicate if the secure key
|
||||
* is currently enciphered by the OLD CCA master key
|
||||
* is currently enciphered by the OLD master key
|
||||
* @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
|
||||
@@ -1454,7 +1447,7 @@ out:
|
||||
}
|
||||
|
||||
int get_master_key_verification_pattern(const u8 *key, size_t key_size,
|
||||
u64 *mkvp, bool UNUSED(verbose))
|
||||
u8 *mkvp, bool UNUSED(verbose))
|
||||
{
|
||||
struct aesdatakeytoken *datakey = (struct aesdatakeytoken *)key;
|
||||
struct aescipherkeytoken *cipherkey = (struct aescipherkeytoken *)key;
|
||||
@@ -1462,10 +1455,11 @@ int get_master_key_verification_pattern(const u8 *key, size_t key_size,
|
||||
util_assert(key != NULL, "Internal error: secure_key is NULL");
|
||||
util_assert(mkvp != NULL, "Internal error: mkvp is NULL");
|
||||
|
||||
memset(mkvp, 0, MKVP_LENGTH);
|
||||
if (is_cca_aes_data_key(key, key_size))
|
||||
*mkvp = datakey->mkvp;
|
||||
memcpy(mkvp, &datakey->mkvp, sizeof(datakey->mkvp));
|
||||
else if (is_cca_aes_cipher_key(key, key_size))
|
||||
memcpy(mkvp, cipherkey->kvp, sizeof(*mkvp));
|
||||
memcpy(mkvp, &cipherkey->kvp, sizeof(cipherkey->kvp));
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
+8
-1
@@ -231,6 +231,13 @@ struct pkey_apqns4keytype {
|
||||
#define ENC_ZERO_LEN (2 * PAES_BLOCK_SIZE)
|
||||
#define VERIFICATION_PATTERN_LEN (2 * ENC_ZERO_LEN + 1)
|
||||
|
||||
#define MKVP_LENGTH 16
|
||||
|
||||
static const u8 zero_mkvp[MKVP_LENGTH] = { 0x00 };
|
||||
|
||||
#define MKVP_EQ(mkvp1, mkvp2) (memcmp(mkvp1, mkvp2, MKVP_LENGTH) == 0)
|
||||
#define MKVP_ZERO(mkvp) (mkvp == NULL || MKVP_EQ(mkvp, zero_mkvp))
|
||||
|
||||
enum card_type {
|
||||
CARD_TYPE_ANY = -1,
|
||||
CARD_TYPE_CCA = 1,
|
||||
@@ -263,7 +270,7 @@ int generate_key_verification_pattern(const u8 *key, size_t key_size,
|
||||
char *vp, size_t vp_len, bool verbose);
|
||||
|
||||
int get_master_key_verification_pattern(const u8 *key, size_t key_size,
|
||||
u64 *mkvp, bool verbose);
|
||||
u8 *mkvp, bool verbose);
|
||||
|
||||
bool is_cca_aes_data_key(const u8 *key, size_t key_size);
|
||||
bool is_cca_aes_cipher_key(const u8 *key, size_t key_size);
|
||||
|
||||
+233
-57
@@ -25,6 +25,8 @@
|
||||
#include "lib/util_rec.h"
|
||||
#include "lib/util_base.h"
|
||||
|
||||
#include <openssl/crypto.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "properties.h"
|
||||
|
||||
@@ -98,6 +100,7 @@ out:
|
||||
*
|
||||
* @param[in] card card number
|
||||
* @param[in] domain the domain
|
||||
* @param[in] cardtype card type (CCA, EP11 or ANY)
|
||||
*
|
||||
* @returns 1 if its card of the specified type and is online,
|
||||
* 0 if offline,
|
||||
@@ -335,11 +338,12 @@ out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int parse_mk_info(char *line, struct mk_info *mk_info)
|
||||
static int parse_cca_mk_info(char *line, struct mk_info *mk_info)
|
||||
{
|
||||
struct mk_info_reg *mk_reg;
|
||||
char *save;
|
||||
char *tok;
|
||||
u64 mkvp;
|
||||
|
||||
tok = strtok_r(line, " ", &save);
|
||||
if (tok == NULL)
|
||||
@@ -382,9 +386,79 @@ static int parse_mk_info(char *line, struct mk_info *mk_info)
|
||||
if (tok == NULL)
|
||||
return -EIO;
|
||||
|
||||
if (sscanf(tok, "%llx", &mk_reg->mkvp) != 1)
|
||||
if (sscanf(tok, "%llx", &mkvp) != 1)
|
||||
return -EIO;
|
||||
|
||||
memcpy(mk_reg->mkvp, &mkvp, sizeof(mkvp));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_ep11_mk_info(char *line, struct mk_info *mk_info)
|
||||
{
|
||||
struct mk_info_reg *mk_reg;
|
||||
unsigned char *buf;
|
||||
char *save;
|
||||
char *tok;
|
||||
long len;
|
||||
|
||||
tok = strtok_r(line, " ", &save);
|
||||
if (tok == NULL)
|
||||
return -EIO;
|
||||
|
||||
if (strcasecmp(tok, "WK") != 0)
|
||||
return 0;
|
||||
|
||||
tok = strtok_r(NULL, " ", &save);
|
||||
if (tok == NULL)
|
||||
return -EIO;
|
||||
|
||||
if (strcasecmp(tok, "NEW:") == 0)
|
||||
mk_reg = &mk_info->new_mk;
|
||||
else if (strcasecmp(tok, "CUR:") == 0)
|
||||
mk_reg = &mk_info->cur_mk;
|
||||
else
|
||||
return -EIO;
|
||||
|
||||
tok = strtok_r(NULL, " ", &save);
|
||||
if (tok == NULL)
|
||||
return -EIO;
|
||||
|
||||
if (strcasecmp(tok, "valid") == 0)
|
||||
mk_reg->mk_state = MK_STATE_VALID;
|
||||
else if (strcasecmp(tok, "invalid") == 0)
|
||||
mk_reg->mk_state = MK_STATE_INVALID;
|
||||
else if (strcasecmp(tok, "empty") == 0)
|
||||
mk_reg->mk_state = MK_STATE_EMPTY;
|
||||
else if (strcasecmp(tok, "uncommitted") == 0)
|
||||
mk_reg->mk_state = MK_STATE_UNCOMMITTED;
|
||||
else if (strcasecmp(tok, "committed") == 0)
|
||||
mk_reg->mk_state = MK_STATE_COMMITTED;
|
||||
else
|
||||
mk_reg->mk_state = MK_STATE_UNKNOWN;
|
||||
|
||||
tok = strtok_r(NULL, " ", &save);
|
||||
if (tok == NULL)
|
||||
return -EIO;
|
||||
|
||||
/*
|
||||
* EP11 uses a 32 byte master key verification pattern.
|
||||
* Usually only the first 16 bytes are used, so we store only up to
|
||||
* 16 bytes.
|
||||
*/
|
||||
if (strlen(tok) >= MKVP_LENGTH * 2) {
|
||||
if (strncmp(tok, "0x", 2) == 0)
|
||||
tok += 2;
|
||||
|
||||
buf = OPENSSL_hexstr2buf(tok, &len);
|
||||
if (buf == NULL)
|
||||
return -EIO;
|
||||
if (len > MKVP_LENGTH)
|
||||
len = MKVP_LENGTH;
|
||||
memcpy(mk_reg->mkvp, buf, len);
|
||||
OPENSSL_free(buf);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -404,6 +478,7 @@ static int parse_mk_info(char *line, struct mk_info *mk_info)
|
||||
*/
|
||||
int sysfs_get_mkvps(int card, int domain, struct mk_info *mk_info, bool verbose)
|
||||
{
|
||||
enum card_type cardtype;
|
||||
char *dev_path;
|
||||
char *p, *end;
|
||||
char buf[100];
|
||||
@@ -421,6 +496,8 @@ int sysfs_get_mkvps(int card, int domain, struct mk_info *mk_info, bool verbose)
|
||||
if (sysfs_is_apqn_online(card, domain, CARD_TYPE_ANY) != 1)
|
||||
return -ENODEV;
|
||||
|
||||
cardtype = sysfs_get_card_type(card);
|
||||
|
||||
dev_path = util_path_sysfs("bus/ap/devices/card%02x/%02x.%04x/mkvps",
|
||||
card, card, domain);
|
||||
if (!util_path_is_reg_file(dev_path)) {
|
||||
@@ -436,14 +513,22 @@ int sysfs_get_mkvps(int card, int domain, struct mk_info *mk_info, bool verbose)
|
||||
|
||||
/*
|
||||
* Expected contents:
|
||||
* AES NEW: <new_mk_state> <new_mk_mkvp>
|
||||
* AES CUR: <cur_mk_state> <cur_mk_mkvp>
|
||||
* AES OLD: <old_mk_state> <old_mk_mkvp>
|
||||
* with
|
||||
* <new_mk_state>: 'empty' or 'partial' or 'full'
|
||||
* <cur_mk_state>, <old_mk_state>: 'valid' or 'invalid'
|
||||
* <new_mk_mkvp>, <cur_mk_mkvp>, <old_mk_mkvp:
|
||||
* 8 byte hex string with leading 0x
|
||||
* For CCA cards:
|
||||
* AES NEW: <new_mk_state> <new_mk_mkvp>
|
||||
* AES CUR: <cur_mk_state> <cur_mk_mkvp>
|
||||
* AES OLD: <old_mk_state> <old_mk_mkvp>
|
||||
* with
|
||||
* <new_mk_state>: 'empty' or 'partial' or 'full'
|
||||
* <cur_mk_state>, <old_mk_state>: 'valid' or 'invalid'
|
||||
* <new_mk_mkvp>, <cur_mk_mkvp>, <old_mk_mkvp>:
|
||||
* 8 byte hex string with leading 0x
|
||||
* For EP11 cards:
|
||||
* WK NEW: <new_wk_state> <new_wk_mkvp>
|
||||
* WK CUR: <cur_wk_state> <cur_wk_mkvp>
|
||||
* with
|
||||
* <wk_cur_state>: 'invalid' or 'valid'
|
||||
* <wk_new_state>: 'empty' or 'uncommitted' or 'committed'
|
||||
* <wk_cur_vp> and <wk_new_vp>: '-' or a 32 byte hash pattern
|
||||
*/
|
||||
while ((p = fgets(buf, sizeof(buf), fp)) != NULL) {
|
||||
end = memchr(buf, '\n', sizeof(buf));
|
||||
@@ -455,7 +540,17 @@ int sysfs_get_mkvps(int card, int domain, struct mk_info *mk_info, bool verbose)
|
||||
pr_verbose(verbose, "mkvp for %02x.%04x: %s", card, domain,
|
||||
buf);
|
||||
|
||||
rc = parse_mk_info(buf, mk_info);
|
||||
switch (cardtype) {
|
||||
case CARD_TYPE_CCA:
|
||||
rc = parse_cca_mk_info(buf, mk_info);
|
||||
break;
|
||||
case CARD_TYPE_EP11:
|
||||
rc = parse_ep11_mk_info(buf, mk_info);
|
||||
break;
|
||||
default:
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
if (rc != 0)
|
||||
break;
|
||||
}
|
||||
@@ -464,7 +559,8 @@ int sysfs_get_mkvps(int card, int domain, struct mk_info *mk_info, bool verbose)
|
||||
|
||||
if (mk_info->new_mk.mk_state == MK_STATE_UNKNOWN &&
|
||||
mk_info->cur_mk.mk_state == MK_STATE_UNKNOWN &&
|
||||
mk_info->old_mk.mk_state == MK_STATE_UNKNOWN)
|
||||
(cardtype == CARD_TYPE_CCA &&
|
||||
mk_info->old_mk.mk_state == MK_STATE_UNKNOWN))
|
||||
rc = -EIO;
|
||||
out:
|
||||
if (rc != 0)
|
||||
@@ -601,6 +697,7 @@ int handle_apqns(const char *apqns, enum card_type cardtype,
|
||||
|
||||
struct print_apqn_info {
|
||||
struct util_rec *rec;
|
||||
enum card_type cardtype;
|
||||
bool verbose;
|
||||
};
|
||||
|
||||
@@ -620,24 +717,30 @@ static int print_apqn_mk_info(int card, int domain, void *handler_data)
|
||||
|
||||
util_rec_set(info->rec, "APQN", "%02x.%04x", card, domain);
|
||||
|
||||
if (info->cardtype != CARD_TYPE_ANY && type != info->cardtype)
|
||||
rc = -EINVAL;
|
||||
|
||||
if (rc == 0) {
|
||||
if (mk_info.new_mk.mk_state == MK_STATE_FULL)
|
||||
util_rec_set(info->rec, "NEW", "%016llx",
|
||||
mk_info.new_mk.mkvp);
|
||||
if (mk_info.new_mk.mk_state == MK_STATE_FULL ||
|
||||
mk_info.new_mk.mk_state == MK_STATE_COMMITTED)
|
||||
util_rec_set(info->rec, "NEW", "%s",
|
||||
printable_mkvp(type, mk_info.new_mk.mkvp));
|
||||
else if (mk_info.new_mk.mk_state == MK_STATE_PARTIAL)
|
||||
util_rec_set(info->rec, "NEW", "partially loaded");
|
||||
else if (mk_info.new_mk.mk_state == MK_STATE_UNCOMMITTED)
|
||||
util_rec_set(info->rec, "NEW", "uncommitted");
|
||||
else
|
||||
util_rec_set(info->rec, "NEW", "-");
|
||||
|
||||
if (mk_info.cur_mk.mk_state == MK_STATE_VALID)
|
||||
util_rec_set(info->rec, "CUR", "%016llx",
|
||||
mk_info.cur_mk.mkvp);
|
||||
util_rec_set(info->rec, "CUR", "%s",
|
||||
printable_mkvp(type, mk_info.cur_mk.mkvp));
|
||||
else
|
||||
util_rec_set(info->rec, "CUR", "-");
|
||||
|
||||
if (mk_info.old_mk.mk_state == MK_STATE_VALID)
|
||||
util_rec_set(info->rec, "OLD", "%016llx",
|
||||
mk_info.old_mk.mkvp);
|
||||
util_rec_set(info->rec, "OLD", "%s",
|
||||
printable_mkvp(type, mk_info.old_mk.mkvp));
|
||||
else
|
||||
util_rec_set(info->rec, "OLD", "-");
|
||||
} else {
|
||||
@@ -673,15 +776,23 @@ static int print_apqn_mk_info(int card, int domain, void *handler_data)
|
||||
int print_mk_info(const char *apqns, enum card_type cardtype, bool verbose)
|
||||
{
|
||||
struct print_apqn_info info;
|
||||
int rc;
|
||||
int rc, mklen;
|
||||
|
||||
info.verbose = verbose;
|
||||
info.cardtype = cardtype;
|
||||
info.rec = util_rec_new_wide("-");
|
||||
|
||||
if (cardtype == CARD_TYPE_CCA)
|
||||
mklen = 16;
|
||||
else
|
||||
mklen = 32;
|
||||
|
||||
util_rec_def(info.rec, "APQN", UTIL_REC_ALIGN_LEFT, 11, "CARD.DOMAIN");
|
||||
util_rec_def(info.rec, "NEW", UTIL_REC_ALIGN_LEFT, 16, "NEW MK");
|
||||
util_rec_def(info.rec, "CUR", UTIL_REC_ALIGN_LEFT, 16, "CURRENT MK");
|
||||
util_rec_def(info.rec, "OLD", UTIL_REC_ALIGN_LEFT, 16, "OLD MK");
|
||||
util_rec_def(info.rec, "NEW", UTIL_REC_ALIGN_LEFT, mklen, "NEW MK");
|
||||
util_rec_def(info.rec, "CUR", UTIL_REC_ALIGN_LEFT, mklen, "CURRENT MK");
|
||||
if (cardtype != CARD_TYPE_EP11)
|
||||
util_rec_def(info.rec, "OLD", UTIL_REC_ALIGN_LEFT, mklen,
|
||||
"OLD MK");
|
||||
util_rec_def(info.rec, "TYPE", UTIL_REC_ALIGN_LEFT, 6, "TYPE");
|
||||
util_rec_print_hdr(info.rec);
|
||||
|
||||
@@ -692,9 +803,10 @@ int print_mk_info(const char *apqns, enum card_type cardtype, bool verbose)
|
||||
}
|
||||
|
||||
struct cross_check_info {
|
||||
u64 mkvp;
|
||||
u64 new_mkvp;
|
||||
u8 mkvp[MKVP_LENGTH];
|
||||
u8 new_mkvp[MKVP_LENGTH];
|
||||
bool key_mkvp;
|
||||
enum card_type cardtype;
|
||||
int min_level;
|
||||
u32 num_cur_match;
|
||||
u32 num_old_match;
|
||||
@@ -708,6 +820,7 @@ 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;
|
||||
enum card_type type;
|
||||
struct mk_info mk_info;
|
||||
char temp[200];
|
||||
int rc, level;
|
||||
@@ -724,6 +837,19 @@ static int cross_check_mk_info(int card, int domain, void *handler_data)
|
||||
|
||||
info->num_checked++;
|
||||
|
||||
if (info->cardtype != CARD_TYPE_ANY) {
|
||||
type = sysfs_get_card_type(card);
|
||||
if (type != info->cardtype) {
|
||||
info->print_mks = 1;
|
||||
info->mismatch = 1;
|
||||
sprintf(temp, "WARNING: APQN %02x.%04x: The card type "
|
||||
"is not CEXn%c.", card, domain,
|
||||
info->cardtype == CARD_TYPE_CCA ? 'C' : 'P');
|
||||
util_print_indented(temp, 0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (info->min_level >= 0) {
|
||||
level = sysfs_get_card_level(card);
|
||||
|
||||
@@ -731,7 +857,7 @@ static int cross_check_mk_info(int card, int domain, void *handler_data)
|
||||
info->print_mks = 1;
|
||||
info->mismatch = 1;
|
||||
sprintf(temp, "WARNING: APQN %02x.%04x: The card level "
|
||||
"is less than CEX%dC.", card, domain,
|
||||
"is less than CEX%dn.", card, domain,
|
||||
info->min_level);
|
||||
util_print_indented(temp, 0);
|
||||
}
|
||||
@@ -743,13 +869,22 @@ static int cross_check_mk_info(int card, int domain, void *handler_data)
|
||||
"register is only partially loaded.", card, domain);
|
||||
util_print_indented(temp, 0);
|
||||
}
|
||||
if (mk_info.new_mk.mk_state == MK_STATE_UNCOMMITTED) {
|
||||
info->print_mks = 1;
|
||||
sprintf(temp, "INFO: APQN %02x.%04x: The NEW master key "
|
||||
"register is loaded but uncommitted.", 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 (MKVP_ZERO(info->new_mkvp) &&
|
||||
(mk_info.new_mk.mk_state == MK_STATE_FULL ||
|
||||
mk_info.new_mk.mk_state == MK_STATE_COMMITTED))
|
||||
memcpy(info->new_mkvp, mk_info.new_mk.mkvp,
|
||||
sizeof(info->new_mkvp));
|
||||
|
||||
if (mk_info.new_mk.mk_state == MK_STATE_FULL &&
|
||||
mk_info.new_mk.mkvp != info->new_mkvp) {
|
||||
if ((mk_info.new_mk.mk_state == MK_STATE_FULL ||
|
||||
mk_info.new_mk.mk_state == MK_STATE_COMMITTED) &&
|
||||
!MKVP_EQ(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 "
|
||||
@@ -767,15 +902,16 @@ static int cross_check_mk_info(int card, int domain, void *handler_data)
|
||||
}
|
||||
|
||||
if (mk_info.old_mk.mk_state == MK_STATE_VALID &&
|
||||
mk_info.old_mk.mkvp == mk_info.cur_mk.mkvp) {
|
||||
MKVP_EQ(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) {
|
||||
if ((mk_info.new_mk.mk_state == MK_STATE_FULL ||
|
||||
mk_info.new_mk.mk_state == MK_STATE_COMMITTED) &&
|
||||
MKVP_EQ(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 "
|
||||
@@ -784,7 +920,7 @@ static int cross_check_mk_info(int card, int domain, void *handler_data)
|
||||
}
|
||||
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) {
|
||||
MKVP_EQ(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 "
|
||||
@@ -792,28 +928,29 @@ static int cross_check_mk_info(int card, int domain, void *handler_data)
|
||||
util_print_indented(temp, 0);
|
||||
}
|
||||
|
||||
if (info->mkvp == 0)
|
||||
info->mkvp = mk_info.cur_mk.mkvp;
|
||||
if (MKVP_ZERO(info->mkvp))
|
||||
memcpy(info->mkvp, mk_info.cur_mk.mkvp, sizeof(info->mkvp));
|
||||
|
||||
if (info->key_mkvp) {
|
||||
if (mk_info.cur_mk.mk_state == MK_STATE_VALID &&
|
||||
mk_info.cur_mk.mkvp == info->mkvp)
|
||||
MKVP_EQ(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)
|
||||
MKVP_EQ(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)
|
||||
if ((mk_info.new_mk.mk_state == MK_STATE_FULL ||
|
||||
mk_info.new_mk.mk_state == MK_STATE_COMMITTED) &&
|
||||
MKVP_EQ(mk_info.new_mk.mkvp, info->mkvp))
|
||||
info->num_new_match++;
|
||||
}
|
||||
|
||||
if (mk_info.cur_mk.mkvp != info->mkvp) {
|
||||
if (!MKVP_EQ(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) {
|
||||
MKVP_EQ(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 "
|
||||
@@ -821,8 +958,10 @@ static int cross_check_mk_info(int card, int domain, void *handler_data)
|
||||
"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) {
|
||||
} else if ((mk_info.new_mk.mk_state == MK_STATE_FULL ||
|
||||
mk_info.new_mk.mk_state ==
|
||||
MK_STATE_COMMITTED) &&
|
||||
MKVP_EQ(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 "
|
||||
@@ -855,11 +994,11 @@ static int cross_check_mk_info(int card, int domain, void *handler_data)
|
||||
* 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
|
||||
* or an empty string, then all online 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.
|
||||
* If this is all zero or NULL, then the master keys are
|
||||
* 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] cardtype card type (CCA, EP11 or ANY)
|
||||
@@ -872,7 +1011,7 @@ static int cross_check_mk_info(int card, int domain, void *handler_data)
|
||||
* -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, int min_level,
|
||||
int cross_check_apqns(const char *apqns, u8 *mkvp, int min_level,
|
||||
enum card_type cardtype, bool print_mks, bool verbose)
|
||||
{
|
||||
struct cross_check_info info;
|
||||
@@ -880,14 +1019,16 @@ int cross_check_apqns(const char *apqns, u64 mkvp, int min_level,
|
||||
int rc;
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.key_mkvp = mkvp != 0;
|
||||
info.mkvp = mkvp;
|
||||
info.key_mkvp = !MKVP_ZERO(mkvp);
|
||||
if (mkvp != NULL)
|
||||
memcpy(info.mkvp, mkvp, sizeof(info.mkvp));
|
||||
info.cardtype = cardtype;
|
||||
info.min_level = min_level;
|
||||
info.verbose = verbose;
|
||||
|
||||
pr_verbose(verbose, "Cross checking APQNs with mkvp 0x%016llx and "
|
||||
"min-level %d: %s", mkvp, min_level,
|
||||
apqns != NULL ? apqns : "ANY");
|
||||
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");
|
||||
|
||||
rc = handle_apqns(apqns, cardtype, cross_check_mk_info, &info, verbose);
|
||||
if (rc != 0)
|
||||
@@ -896,11 +1037,11 @@ int cross_check_apqns(const char *apqns, u64 mkvp, int min_level,
|
||||
if (info.mismatch) {
|
||||
if (info.key_mkvp)
|
||||
printf("WARNING: Not all APQNs have the correct master "
|
||||
"key (%016llx).\n", mkvp);
|
||||
"key (%s) or fulfill the requirements.\n",
|
||||
printable_mkvp(cardtype, info.mkvp));
|
||||
else
|
||||
printf("WARNING: Not all APQNs have the same master "
|
||||
"key.\n");
|
||||
|
||||
"key or fulfill the requirements.\n");
|
||||
rc = -ENODEV;
|
||||
}
|
||||
if (info.num_checked == 0) {
|
||||
@@ -951,3 +1092,38 @@ bool prompt_for_yes(bool verbose)
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a printable version of the specified master key verification pattern
|
||||
* (MKVP) for the specified card type. Different card types use different
|
||||
* number of bytes for MKVP.
|
||||
*
|
||||
* @param[in] cardtype card type (CCA, EP11 or ANY)
|
||||
* @param[in] mkvp the master key verification pattern to print
|
||||
*
|
||||
* @returns address of a static char array containing the printed MKVP, or NULL
|
||||
* in case of an error.
|
||||
*/
|
||||
char *printable_mkvp(enum card_type cardtype, u8 *mkvp)
|
||||
{
|
||||
static char mkvp_print_buf[MKVP_LENGTH * 2 + 1];
|
||||
|
||||
if (mkvp == NULL)
|
||||
return NULL;
|
||||
|
||||
switch (cardtype) {
|
||||
case CARD_TYPE_CCA:
|
||||
/* CCA uses an 8 byte MKVP */
|
||||
sprintf(mkvp_print_buf, "%016llx", *((u64 *)mkvp));
|
||||
break;
|
||||
case CARD_TYPE_EP11:
|
||||
/* EP11 uses an 32 byte MKVP, but truncated to 16 bytes*/
|
||||
sprintf(mkvp_print_buf, "%016llx%016llx", *((u64 *)&mkvp[0]),
|
||||
*((u64 *)&mkvp[8]));
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return mkvp_print_buf;
|
||||
}
|
||||
|
||||
+9
-5
@@ -36,21 +36,23 @@ int sysfs_get_firmware_version(int card, struct fw_version *fw_version,
|
||||
bool verbose);
|
||||
|
||||
#define MK_STATE_EMPTY 0
|
||||
#define MK_STATE_PARTIAL 1
|
||||
#define MK_STATE_FULL 2
|
||||
#define MK_STATE_PARTIAL 1 /* For CCA only */
|
||||
#define MK_STATE_FULL 2 /* For CCA only */
|
||||
#define MK_STATE_VALID 3
|
||||
#define MK_STATE_INVALID 4
|
||||
#define MK_STATE_UNCOMMITTED 5 /* For EP11 only */
|
||||
#define MK_STATE_COMMITTED 6 /* For EP11 only */
|
||||
#define MK_STATE_UNKNOWN -1
|
||||
|
||||
struct mk_info_reg {
|
||||
int mk_state;
|
||||
u64 mkvp;
|
||||
u8 mkvp[MKVP_LENGTH];
|
||||
};
|
||||
|
||||
struct mk_info {
|
||||
struct mk_info_reg new_mk;
|
||||
struct mk_info_reg cur_mk;
|
||||
struct mk_info_reg old_mk;
|
||||
struct mk_info_reg old_mk; /* only available on CCA cards */
|
||||
};
|
||||
|
||||
int sysfs_get_mkvps(int card, int domain, struct mk_info *mk_info,
|
||||
@@ -63,9 +65,11 @@ 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, u64 mkvp, int min_level,
|
||||
int cross_check_apqns(const char *apqns, u8 *mkvp, int min_level,
|
||||
enum card_type cardtype, bool print_mks, bool verbose);
|
||||
|
||||
bool prompt_for_yes(bool verbose);
|
||||
|
||||
char *printable_mkvp(enum card_type cardtype, u8 *mkvp);
|
||||
|
||||
#endif
|
||||
|
||||
+40
-34
@@ -35,6 +35,7 @@
|
||||
#include "misc.h"
|
||||
#include "pkey.h"
|
||||
#include "cca.h"
|
||||
#include "utils.h"
|
||||
|
||||
/* Detect if cryptsetup 2.1 or later is available */
|
||||
#ifdef CRYPT_LOG_DEBUG_JSON
|
||||
@@ -195,7 +196,7 @@ static struct util_opt opt_vec[] = {
|
||||
{
|
||||
.option = {"complete", 0, NULL, 'c'},
|
||||
.desc = "Completes a staged re-enciphering. Use this option "
|
||||
"after the new CCA master key has been set (made "
|
||||
"after the new master key has been set (made "
|
||||
"active)",
|
||||
.command = COMMAND_REENCIPHER,
|
||||
},
|
||||
@@ -1198,7 +1199,7 @@ out:
|
||||
/*
|
||||
* Prompts for yes or no. Returns true if 'y' or 'yes' was entered.
|
||||
*/
|
||||
static bool prompt_for_yes(void)
|
||||
static bool _prompt_for_yes(void)
|
||||
{
|
||||
char str[20];
|
||||
|
||||
@@ -1295,7 +1296,7 @@ static int activate_unbound_keyslot(int token, int keyslot, const char *key,
|
||||
"now in unbound state. Do you want to remove "
|
||||
"these key slots [y/N]?", 0);
|
||||
|
||||
if (!prompt_for_yes())
|
||||
if (!_prompt_for_yes())
|
||||
return 0;
|
||||
|
||||
for (i = 0, n = 0; ; i++) {
|
||||
@@ -1533,6 +1534,7 @@ static int reencipher_prepare(int token)
|
||||
struct reencipher_token reenc_tok;
|
||||
struct vp_token vp_tok;
|
||||
char *password = NULL;
|
||||
u8 mkvp[MKVP_LENGTH];
|
||||
size_t password_len;
|
||||
char *key = NULL;
|
||||
int selected = 1;
|
||||
@@ -1540,7 +1542,6 @@ static int reencipher_prepare(int token)
|
||||
int is_old_mk;
|
||||
char *prompt;
|
||||
char *msg;
|
||||
u64 mkvp;
|
||||
int rc;
|
||||
|
||||
if (token >= 0) {
|
||||
@@ -1551,7 +1552,7 @@ static int reencipher_prepare(int token)
|
||||
util_print_indented(msg, 0);
|
||||
free(msg);
|
||||
|
||||
if (!prompt_for_yes()) {
|
||||
if (!_prompt_for_yes()) {
|
||||
warnx("Device '%s' is left unchanged", g.pos_arg);
|
||||
return -ECANCELED;
|
||||
}
|
||||
@@ -1598,25 +1599,25 @@ static int reencipher_prepare(int token)
|
||||
if (is_old_mk) {
|
||||
g.fromold = 1;
|
||||
util_asprintf(&msg, "The secure volume key of device "
|
||||
"'%s' is enciphered with the OLD CCA "
|
||||
"'%s' is enciphered with the OLD "
|
||||
"master key and is being re-enciphered "
|
||||
"with the CURRENT CCA master key.",
|
||||
"with the CURRENT master key.",
|
||||
g.pos_arg);
|
||||
util_print_indented(msg, 0);
|
||||
free(msg);
|
||||
} else {
|
||||
g.tonew = 1;
|
||||
util_asprintf(&msg, "The secure volume key of device "
|
||||
"'%s' is enciphered with the CURRENT CCA "
|
||||
"'%s' is enciphered with the CURRENT "
|
||||
"master key and is being re-enciphered "
|
||||
"with the NEW CCA master key.",
|
||||
"with the NEW master key.",
|
||||
g.pos_arg);
|
||||
util_print_indented(msg, 0);
|
||||
free(msg);
|
||||
}
|
||||
}
|
||||
|
||||
rc = get_master_key_verification_pattern((u8 *)key, keysize, &mkvp,
|
||||
rc = get_master_key_verification_pattern((u8 *)key, keysize, mkvp,
|
||||
g.verbose);
|
||||
if (rc != 0) {
|
||||
warnx("Failed to get the master key verification pattern: %s",
|
||||
@@ -1636,7 +1637,7 @@ static int reencipher_prepare(int token)
|
||||
util_print_indented("No APQN found that is suitable "
|
||||
"for re-enciphering the secure AES "
|
||||
"volume key from the OLD to the "
|
||||
"CURRENT CCA master key.", 0);
|
||||
"CURRENT master key.", 0);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1666,7 +1667,7 @@ static int reencipher_prepare(int token)
|
||||
util_print_indented("No APQN found that is suitable "
|
||||
"for re-enciphering the secure AES "
|
||||
"volume key from the CURRENT to "
|
||||
"the NEW CCA master key.", 0);
|
||||
"the NEW master key.", 0);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1721,7 +1722,7 @@ static int reencipher_prepare(int token)
|
||||
rc = 0;
|
||||
|
||||
util_asprintf(&msg, "Staged re-enciphering is initiated for "
|
||||
"device '%s'. After the NEW CCA master key has been set "
|
||||
"device '%s'. After the NEW master key has been set "
|
||||
"to become the CURRENT master key, run 'zkey-cryptsetup "
|
||||
"reencipher' with option '--complete' to complete the "
|
||||
"re-enciphering process.", g.pos_arg,
|
||||
@@ -1744,6 +1745,7 @@ static int reencipher_complete(int token)
|
||||
char vp[VERIFICATION_PATTERN_LEN];
|
||||
struct reencipher_token tok;
|
||||
char *password = NULL;
|
||||
u8 mkvp[MKVP_LENGTH];
|
||||
size_t password_len;
|
||||
char *key = NULL;
|
||||
int selected = 1;
|
||||
@@ -1751,7 +1753,6 @@ static int reencipher_complete(int token)
|
||||
int is_old_mk;
|
||||
char *prompt;
|
||||
char *msg;
|
||||
u64 mkvp;
|
||||
int rc;
|
||||
|
||||
rc = get_reencipher_token(g.cd, token, &tok, true);
|
||||
@@ -1762,7 +1763,7 @@ static int reencipher_complete(int token)
|
||||
}
|
||||
|
||||
util_asprintf(&msg, "The re-enciphered secure volume key for "
|
||||
"device '%s' is not valid.\nThe new CCA master key might "
|
||||
"device '%s' is not valid.\nThe new master key might "
|
||||
"yet have to be set as the CURRENT master key.",
|
||||
g.pos_arg);
|
||||
util_asprintf(&prompt, "Enter passphrase for key slot %d of '%s': ",
|
||||
@@ -1780,25 +1781,25 @@ static int reencipher_complete(int token)
|
||||
|
||||
if (is_old_mk) {
|
||||
util_asprintf(&msg, "The re-enciphered secure volume key "
|
||||
"of device '%s' is enciphered with the CCA "
|
||||
"of device '%s' is enciphered with the "
|
||||
"master key from the OLD master key register. "
|
||||
"The CCA master key might have changed again, "
|
||||
"The master key might have changed again, "
|
||||
"before the previous volume key re-enciphering "
|
||||
"was completed.\n"
|
||||
"Do you want to re-encipher the secure key with "
|
||||
"the CCA master key in the CURRENT master key "
|
||||
"the master key in the CURRENT master key "
|
||||
"register [y/N]?", g.pos_arg);
|
||||
util_print_indented(msg, 0);
|
||||
free(msg);
|
||||
|
||||
if (!prompt_for_yes()) {
|
||||
if (!_prompt_for_yes()) {
|
||||
warnx("Re-enciphering was aborted");
|
||||
rc = -ECANCELED;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = get_master_key_verification_pattern((u8 *)key, keysize,
|
||||
&mkvp, g.verbose);
|
||||
mkvp, g.verbose);
|
||||
if (rc != 0) {
|
||||
warnx("Failed to get the master key verification "
|
||||
"pattern: %s",
|
||||
@@ -1817,7 +1818,7 @@ static int reencipher_complete(int token)
|
||||
util_print_indented("No APQN found that is suitable "
|
||||
"for re-enciphering the secure AES "
|
||||
"volume key from the OLD to the "
|
||||
"CURRENT CCA master key.", 0);
|
||||
"CURRENT master key.", 0);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1952,13 +1953,14 @@ static int command_validate(void)
|
||||
int reenc_pending = 0, vp_tok_avail = 0, is_valid = 0, is_old_mk = 0;
|
||||
struct reencipher_token reenc_tok;
|
||||
struct vp_token vp_tok;
|
||||
const char *key_type;
|
||||
u8 mkvp[MKVP_LENGTH];
|
||||
size_t clear_keysize;
|
||||
size_t keysize = 0;
|
||||
char *key = NULL;
|
||||
char *prompt;
|
||||
char *msg;
|
||||
int token;
|
||||
u64 mkvp;
|
||||
int rc;
|
||||
|
||||
util_asprintf(&prompt, "Enter passphrase for '%s': ", g.pos_arg);
|
||||
@@ -1990,28 +1992,32 @@ static int command_validate(void)
|
||||
}
|
||||
|
||||
rc = get_master_key_verification_pattern((u8 *)key, keysize,
|
||||
&mkvp, g.verbose);
|
||||
mkvp, g.verbose);
|
||||
if (rc != 0) {
|
||||
warnx("Failed to get the master key verification pattern: %s",
|
||||
strerror(-rc));
|
||||
goto out;
|
||||
}
|
||||
|
||||
key_type = get_key_type((u8 *)key, keysize);
|
||||
|
||||
printf("Validation of secure volume key of device '%s':\n", g.pos_arg);
|
||||
printf(" Status: %s\n", is_valid ? "Valid" : "Invalid");
|
||||
printf(" Secure key size: %lu bytes\n", keysize);
|
||||
printf(" XTS type key: %s\n",
|
||||
is_xts_key((u8 *)key, keysize) ? "Yes" : "No");
|
||||
printf(" Key type: %s\n",
|
||||
get_key_type((u8 *)key, keysize));
|
||||
printf(" Key type: %s\n", key_type);
|
||||
if (is_valid) {
|
||||
printf(" Clear key size: %lu bits\n", clear_keysize);
|
||||
printf(" Enciphered with: %s CCA master key (MKVP: "
|
||||
"%016llx)\n", is_old_mk ? "OLD" : "CURRENT", mkvp);
|
||||
printf(" Enciphered with: %s master key (MKVP: "
|
||||
"%s)\n", is_old_mk ? "OLD" : "CURRENT",
|
||||
printable_mkvp(get_card_type_for_keytype(key_type),
|
||||
mkvp));
|
||||
} else {
|
||||
printf(" Clear key size: (unknown)\n");
|
||||
printf(" Enciphered with: (unknown, MKVP: %016llx)\n",
|
||||
mkvp);
|
||||
printf(" Enciphered with: (unknown, MKVP: %s)\n",
|
||||
printable_mkvp(get_card_type_for_keytype(key_type),
|
||||
mkvp));
|
||||
}
|
||||
if (vp_tok_avail)
|
||||
print_verification_pattern(vp_tok.verification_pattern);
|
||||
@@ -2029,10 +2035,10 @@ static int command_validate(void)
|
||||
|
||||
if (is_old_mk)
|
||||
util_print_indented("\nWARNING: The secure volume key is "
|
||||
"currently enciphered with the OLD CCA "
|
||||
"currently enciphered with the OLD "
|
||||
"master key. To mitigate the danger of "
|
||||
"data loss re-encipher the volume key with "
|
||||
"the CURRENT CCA master key.", 0);
|
||||
"the CURRENT master key.", 0);
|
||||
|
||||
if (is_valid && !vp_tok_avail) {
|
||||
util_asprintf(&msg, "\nWARNING: The volume key cannot be "
|
||||
@@ -2148,14 +2154,14 @@ static int command_setkey(void)
|
||||
|
||||
if (is_old_mk) {
|
||||
util_asprintf(&msg, "The secure key in file '%s' is "
|
||||
"enciphered with the CCA master key in the OLD "
|
||||
"enciphered with the master key in the OLD "
|
||||
"master key register. Do you want to set this "
|
||||
"key as the new volume key anyway [y/N]?",
|
||||
g.master_key_file);
|
||||
util_print_indented(msg, 0);
|
||||
free(msg);
|
||||
|
||||
if (!prompt_for_yes()) {
|
||||
if (!_prompt_for_yes()) {
|
||||
warnx("Device '%s' is left unchanged", g.pos_arg);
|
||||
rc = -EINVAL;
|
||||
goto out;
|
||||
@@ -2213,7 +2219,7 @@ static int command_setkey(void)
|
||||
util_print_indented(msg, 0);
|
||||
free(msg);
|
||||
|
||||
if (!prompt_for_yes()) {
|
||||
if (!_prompt_for_yes()) {
|
||||
warnx("Device '%s' is left unchanged", g.pos_arg);
|
||||
rc = -EINVAL;
|
||||
goto out;
|
||||
|
||||
+24
-23
@@ -259,7 +259,7 @@ static struct util_opt opt_vec[] = {
|
||||
{
|
||||
.option = {"complete", 0, NULL, 'p'},
|
||||
.desc = "Completes a staged re-enciphering. Use this option "
|
||||
"after the new CCA master key has been set (made "
|
||||
"after the new master key has been set (made "
|
||||
"active)",
|
||||
.command = COMMAND_REENCIPHER,
|
||||
},
|
||||
@@ -874,7 +874,7 @@ static struct zkey_command zkey_commands[] = {
|
||||
.long_desc = "Re-encipher an existing secure AES "
|
||||
"key that is either contained in SECURE-KEY-FILE "
|
||||
"or is stored in the repository with another "
|
||||
"CCA master key",
|
||||
"master key",
|
||||
.has_options = 1,
|
||||
.pos_arg = "[SECURE-KEY-FILE]",
|
||||
.pos_arg_optional = 1,
|
||||
@@ -1171,7 +1171,7 @@ static int command_generate(void)
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
rc = cross_check_apqns(NULL, 0,
|
||||
rc = cross_check_apqns(NULL, NULL,
|
||||
get_min_card_level_for_keytype(g.key_type),
|
||||
get_card_type_for_keytype(g.key_type),
|
||||
true, g.verbose);
|
||||
@@ -1198,10 +1198,10 @@ static int command_generate(void)
|
||||
static int command_reencipher_file(void)
|
||||
{
|
||||
size_t secure_key_size;
|
||||
u8 mkvp[MKVP_LENGTH];
|
||||
int rc, is_old_mk;
|
||||
int selected = 1;
|
||||
u8 *secure_key;
|
||||
u64 mkvp;
|
||||
|
||||
if (g.name != NULL) {
|
||||
warnx("Option '--name|-N' is not valid for "
|
||||
@@ -1248,7 +1248,7 @@ static int command_reencipher_file(void)
|
||||
}
|
||||
|
||||
rc = get_master_key_verification_pattern(secure_key, secure_key_size,
|
||||
&mkvp, g.verbose);
|
||||
mkvp, g.verbose);
|
||||
if (rc != 0) {
|
||||
warnx("Failed to get the master key verification pattern: %s",
|
||||
strerror(-rc));
|
||||
@@ -1261,16 +1261,16 @@ static int command_reencipher_file(void)
|
||||
if (is_old_mk) {
|
||||
g.fromold = 1;
|
||||
util_print_indented("The secure key is currently "
|
||||
"enciphered with the OLD CCA "
|
||||
"enciphered with the OLD "
|
||||
"master key and is being "
|
||||
"re-enciphered with the CURRENT "
|
||||
"CCA master key\n", 0);
|
||||
"master key\n", 0);
|
||||
} else {
|
||||
g.tonew = 1;
|
||||
util_print_indented("The secure key is currently "
|
||||
"enciphered with the CURRENT CCA "
|
||||
"enciphered with the CURRENT "
|
||||
"master key and is being "
|
||||
"re-enciphered with the NEW CCA "
|
||||
"re-enciphered with the NEW "
|
||||
"master key\n", 0);
|
||||
}
|
||||
}
|
||||
@@ -1279,13 +1279,13 @@ static int command_reencipher_file(void)
|
||||
if (g.fromold) {
|
||||
if (!is_old_mk) {
|
||||
warnx("The secure key is already enciphered "
|
||||
"with the CURRENT CCA master key");
|
||||
"with the CURRENT master key");
|
||||
rc = EXIT_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
pr_verbose("Secure key will be re-enciphered from OLD to the "
|
||||
"CURRENT CCA master key");
|
||||
"CURRENT master key");
|
||||
|
||||
rc = select_cca_adapter_by_mkvp(&g.cca, mkvp, NULL,
|
||||
FLAG_SEL_CCA_MATCH_OLD_MKVP,
|
||||
@@ -1305,7 +1305,7 @@ static int command_reencipher_file(void)
|
||||
METHOD_OLD_TO_CURRENT,
|
||||
g.verbose);
|
||||
if (rc != 0) {
|
||||
warnx("Re-encipher from OLD to CURRENT CCA "
|
||||
warnx("Re-encipher from OLD to CURRENT "
|
||||
"master key has failed\n");
|
||||
if (!selected)
|
||||
print_msg_for_cca_envvars("secure AES key");
|
||||
@@ -1315,7 +1315,7 @@ static int command_reencipher_file(void)
|
||||
}
|
||||
if (g.tonew) {
|
||||
pr_verbose("Secure key will be re-enciphered from CURRENT "
|
||||
"to the NEW CCA master key");
|
||||
"to the NEW master key");
|
||||
|
||||
rc = select_cca_adapter_by_mkvp(&g.cca, mkvp, NULL,
|
||||
FLAG_SEL_CCA_MATCH_CUR_MKVP |
|
||||
@@ -1337,7 +1337,7 @@ static int command_reencipher_file(void)
|
||||
rc = key_token_change(&g.cca, secure_key, secure_key_size,
|
||||
METHOD_CURRENT_TO_NEW, g.verbose);
|
||||
if (rc != 0) {
|
||||
warnx("Re-encipher from CURRENT to NEW CCA "
|
||||
warnx("Re-encipher from CURRENT to NEW "
|
||||
"master key has failed\n");
|
||||
if (!selected)
|
||||
print_msg_for_cca_envvars("secure AES key");
|
||||
@@ -1361,7 +1361,7 @@ out:
|
||||
/*
|
||||
* Command handler for 'reencipher in repository'.
|
||||
*
|
||||
* Re-encipher the specified secure key with the NEW or CURRENT CCA master key.
|
||||
* Re-encipher the specified secure key with the NEW or CURRENT master key.
|
||||
*/
|
||||
static int command_reencipher_repository(void)
|
||||
{
|
||||
@@ -1404,7 +1404,7 @@ static int command_reencipher_repository(void)
|
||||
/*
|
||||
* Command handler for 'reencipher'.
|
||||
*
|
||||
* Re-encipher the specified secure key with the NEW or CURRENT CCA master key.
|
||||
* Re-encipher the specified secure key with the NEW or CURRENT master key.
|
||||
*/
|
||||
static int command_reencipher(void)
|
||||
{
|
||||
@@ -1427,9 +1427,9 @@ static int command_validate_file(void)
|
||||
size_t secure_key_size;
|
||||
size_t clear_key_size;
|
||||
const char *key_type;
|
||||
u8 mkvp[MKVP_LENGTH];
|
||||
u8 *secure_key;
|
||||
int is_old_mk;
|
||||
u64 mkvp;
|
||||
int rc;
|
||||
|
||||
if (g.name != NULL) {
|
||||
@@ -1477,7 +1477,7 @@ static int command_validate_file(void)
|
||||
}
|
||||
|
||||
rc = get_master_key_verification_pattern(secure_key, secure_key_size,
|
||||
&mkvp, g.verbose);
|
||||
mkvp, g.verbose);
|
||||
if (rc != 0) {
|
||||
warnx("Failed to get the master key verification pattern: %s",
|
||||
strerror(-rc));
|
||||
@@ -1494,8 +1494,9 @@ static int command_validate_file(void)
|
||||
printf(" Clear key size: %lu bits\n", clear_key_size);
|
||||
printf(" XTS type key: %s\n",
|
||||
is_xts_key(secure_key, secure_key_size) ? "Yes" : "No");
|
||||
printf(" Enciphered with: %s CCA master key (MKVP: %016llx)\n",
|
||||
is_old_mk ? "OLD" : "CURRENT", mkvp);
|
||||
printf(" Enciphered with: %s master key (MKVP: %s)\n",
|
||||
is_old_mk ? "OLD" : "CURRENT",
|
||||
printable_mkvp(get_card_type_for_keytype(key_type), mkvp));
|
||||
printf(" Verification pattern: %.*s\n", VERIFICATION_PATTERN_LEN / 2,
|
||||
vp);
|
||||
printf(" %.*s\n", VERIFICATION_PATTERN_LEN / 2,
|
||||
@@ -1753,11 +1754,11 @@ static int command_convert_file(void)
|
||||
u8 output_key[2 * MAX_SECURE_KEY_SIZE];
|
||||
unsigned int output_key_size;
|
||||
size_t secure_key_size;
|
||||
u8 mkvp[MKVP_LENGTH];
|
||||
int rc, is_old_mk;
|
||||
int selected = 1;
|
||||
u8 *secure_key;
|
||||
int min_level;
|
||||
u64 mkvp;
|
||||
|
||||
if (g.name != NULL) {
|
||||
warnx("Option '--name|-N' is not valid for "
|
||||
@@ -1778,7 +1779,7 @@ static int command_convert_file(void)
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
rc = cross_check_apqns(NULL, 0, min_level,
|
||||
rc = cross_check_apqns(NULL, NULL, min_level,
|
||||
get_card_type_for_keytype(g.key_type), true,
|
||||
g.verbose);
|
||||
if (rc == -EINVAL)
|
||||
@@ -1802,7 +1803,7 @@ static int command_convert_file(void)
|
||||
}
|
||||
|
||||
rc = get_master_key_verification_pattern(secure_key, secure_key_size,
|
||||
&mkvp, g.verbose);
|
||||
mkvp, g.verbose);
|
||||
if (rc != 0) {
|
||||
warnx("Failed to get the master key verification pattern: %s",
|
||||
strerror(-rc));
|
||||
|
||||
Reference in New Issue
Block a user