diff --git a/zkey/keystore.c b/zkey/keystore.c index 63819a7d..8b5ccc4e 100644 --- a/zkey/keystore.c +++ b/zkey/keystore.c @@ -1801,18 +1801,21 @@ out_free_key_filenames: * default is used. * @param[in] import_file The name of a secure key containing the key to import * @param[in] volume_type the type of volume + * @param[in] cca the CCA library struct * * @returns 0 for success or a negative errno in case of an error */ int keystore_import_key(struct keystore *keystore, const char *name, const char *description, const char *volumes, const char *apqns, bool noapqncheck, size_t sector_size, - const char *import_file, const char *volume_type) + const char *import_file, const char *volume_type, + struct cca_lib *cca) { struct key_filenames file_names = { NULL, NULL, NULL }; struct properties *key_props = NULL; size_t secure_key_size; const char *key_type; + int selected = 1; u8 *secure_key; u64 mkvp; int rc; @@ -1862,6 +1865,51 @@ int keystore_import_key(struct keystore *keystore, const char *name, goto out_free_key; } + if (is_cca_aes_cipher_key(secure_key, secure_key_size)) { + if (cca->lib_csulcca == NULL) { + rc = load_cca_library(cca, keystore->verbose); + if (rc != 0) + goto out_free_key; + } + + rc = select_cca_adapter_by_mkvp(cca, mkvp, apqns, + FLAG_SEL_CCA_MATCH_CUR_MKVP | + FLAG_SEL_CCA_MATCH_OLD_MKVP, + keystore->verbose); + if (rc == -ENOTSUP) { + rc = 0; + selected = 0; + } + if (rc != 0) { + warnx("No APQN found that is suitable for " + "working with the secure AES key '%s'", name); + rc = 0; + goto out_free_key; + } + + rc = restrict_key_export(cca, secure_key, secure_key_size, + keystore->verbose); + if (rc != 0) { + warnx("Failed to export-restrict the imported secure " + "key: %s", strerror(-rc)); + if (!selected) + print_msg_for_cca_envvars("secure AES key"); + goto out_free_key; + } + + rc = check_aes_cipher_key(secure_key, secure_key_size); + if (rc != 0) { + warnx("The secure key to import might not be secure"); + printf("%s: Do you want to import it anyway [y/N]? ", + program_invocation_short_name); + if (!prompt_for_yes(keystore->verbose)) { + warnx("Operation aborted"); + rc = -ECANCELED; + goto out_free_key; + } + } + } + rc = write_secure_key(file_names.skey_filename, secure_key, secure_key_size, keystore->verbose); free(secure_key); @@ -3180,7 +3228,6 @@ static int _keystore_prompt_for_remove(struct keystore *keystore, struct key_filenames *file_names) { struct properties *key_prop; - char str[20]; char *msg; int rc; @@ -3198,14 +3245,7 @@ static int _keystore_prompt_for_remove(struct keystore *keystore, printf("%s: Remove key '%s' [y/N]? ", program_invocation_short_name, name); - if (fgets(str, sizeof(str), stdin) == NULL) { - rc = -EIO; - goto out; - } - if (str[strlen(str) - 1] == '\n') - str[strlen(str) - 1] = '\0'; - pr_verbose(keystore, "Prompt reply: '%s'", str); - if (strcasecmp(str, "y") != 0 && strcasecmp(str, "yes") != 0) { + if (!prompt_for_yes(keystore->verbose)) { warnx("Operation aborted"); rc = -ECANCELED; goto out; diff --git a/zkey/keystore.h b/zkey/keystore.h index d5524de9..d2a97e7d 100644 --- a/zkey/keystore.h +++ b/zkey/keystore.h @@ -37,7 +37,8 @@ int keystore_generate_key(struct keystore *keystore, const char *name, int keystore_import_key(struct keystore *keystore, const char *name, const char *description, const char *volumes, const char *apqns, bool noapqncheck, size_t sector_size, - const char *import_file, const char *volume_type); + const char *import_file, const char *volume_type, + struct cca_lib *cca); int keystore_change_key(struct keystore *keystore, const char *name, const char *description, const char *volumes, diff --git a/zkey/utils.c b/zkey/utils.c index 9b29c751..e70ebcd7 100644 --- a/zkey/utils.c +++ b/zkey/utils.c @@ -793,3 +793,27 @@ int cross_check_apqns(const char *apqns, u64 mkvp, int min_level, return rc; } + +/* + * Prompts for yes or no. Returns true if 'y' or 'yes' was entered. + * + * @param[in] verbose if true, verbose messages are printed + * + * @returns true if 'y' or 'yes' was entered (case insensitive). Returns false + * otherwise. + */ +bool prompt_for_yes(bool verbose) +{ + char str[20]; + + if (fgets(str, sizeof(str), stdin) == NULL) + return false; + + if (str[strlen(str) - 1] == '\n') + str[strlen(str) - 1] = '\0'; + pr_verbose(verbose, "Prompt reply: '%s'", str); + if (strcasecmp(str, "y") == 0 || strcasecmp(str, "yes") == 0) + return true; + + return false; +} diff --git a/zkey/utils.h b/zkey/utils.h index 74c44c1e..2a915eb3 100644 --- a/zkey/utils.h +++ b/zkey/utils.h @@ -53,4 +53,6 @@ int print_mk_info(const char *apqns, bool verbose); int cross_check_apqns(const char *apqns, u64 mkvp, int min_level, bool print_mks, bool verbose); +bool prompt_for_yes(bool verbose); + #endif diff --git a/zkey/zkey.1 b/zkey/zkey.1 index f58fd417..0dc29f5a 100644 --- a/zkey/zkey.1 +++ b/zkey/zkey.1 @@ -349,6 +349,12 @@ additional information can be associated with a secure key using the , or the .B \-\-sector-size options. +.PP +.B Note: +The \fBimport\fP command requires the CCA host library (libcsulcca.so) +to be installed when secure keys of type \fBCCA-AESCIPHER\fP are imported. +For the supported environments and downloads, see: +\fIhttp://www.ibm.com/security/cryptocards\fP . .SS "Export AES secure keys from the secure key repository" . diff --git a/zkey/zkey.c b/zkey/zkey.c index c7509c78..72420078 100644 --- a/zkey/zkey.c +++ b/zkey/zkey.c @@ -1522,7 +1522,7 @@ static int command_import(void) rc = keystore_import_key(g.keystore, g.name, g.description, g.volumes, g.apqns, g.noapqncheck, g.sector_size, - g.pos_arg, g.volume_type); + g.pos_arg, g.volume_type, &g.cca); return rc != 0 ? EXIT_FAILURE : EXIT_SUCCESS; }