diff --git a/zkey/keystore.c b/zkey/keystore.c index 02479f1a..67fa837c 100644 --- a/zkey/keystore.c +++ b/zkey/keystore.c @@ -5235,7 +5235,7 @@ static int _keystore_process_kms_import(const char *key1_id, const char *key2_id, const char *key2_label, bool xts, const char *name, - const char *UNUSED(key_type), + const char *key_type, size_t UNUSED(key_bits), const char *description, const char *UNUSED(cipher), @@ -5259,7 +5259,6 @@ static int _keystore_process_kms_import(const char *key1_id, size_t secure_key_size; bool fatal_err = false; char *alt_name = NULL; - const char *key_type; char *apqns = NULL; int rc; @@ -5309,7 +5308,8 @@ prompt_alt_name: secure_key_size = sizeof(secure_key); rc = import_kms_key(keystore->kms_info, key1_id, key2_id, xts, key_name, - secure_key, &secure_key_size, keystore->verbose); + secure_key, &secure_key_size, key_type, + keystore->verbose); if (rc != 0) { warnx("KMS plugin '%s' failed to import key '%s': %s", keystore->kms_info->plugin_name, key_name, strerror(-rc)); @@ -5579,17 +5579,21 @@ static int _keystore_refresh_kms_key(struct keystore *keystore, char *volumes = NULL, *volume_type = NULL; ssize_t sector_size = -1; bool fatal_err = false; + char *key_type = NULL; char sect_size[30]; char *msg; int rc; vol_check.nocheck = refresh_data->novolcheck; + key_type = _keystore_get_key_type(properties); + rc = refresh_kms_key(keystore->kms_info, properties, &description, &cipher, &iv_mode, &volumes, &volume_type, §or_size, file_names->skey_filename, file_names->pass_filename, + key_type, keystore->verbose); if (rc != 0) { warnx("KMS plugin '%s' failed to refresh key '%s': %s", @@ -5711,6 +5715,8 @@ out: free(volumes); if (volume_type != NULL) free(volume_type); + if (key_type != NULL) + free(key_type); return fatal_err ? rc : 0; } diff --git a/zkey/kms-plugin.h b/zkey/kms-plugin.h index 6a5bac57..3d0eae1d 100644 --- a/zkey/kms-plugin.h +++ b/zkey/kms-plugin.h @@ -455,6 +455,9 @@ int kms_list_keys(const kms_handle_t handle, const char *label_pattern, * Imports a key from the KMS and returns a secure key that is * enciphered under the current HSM master key. * + * Note: This function is used for an API version 1 plugin. See function + * kms_import_key2 for the version 2 equivalent. + * * @param handle the KMS plugin handle obtained from kms_initialize() * @param key_id the key-ID of the key to import * @param key_blob a buffer to return the key blob. The size of the @@ -469,7 +472,35 @@ int kms_list_keys(const kms_handle_t handle, const char *label_pattern, int kms_import_key(const kms_handle_t handle, const char *key_id, unsigned char *key_blob, size_t *key_blob_length); +/** + * Imports a key from the KMS and returns a secure key that is + * enciphered under the current HSM master key. + * + * Note: This function should be available for an API version 2 plugin. + * The difference to functionkms_import_key is that it also get the + * desired key type of the key to import. + * + * @param handle the KMS plugin handle obtained from kms_initialize() + * @param key_id the key-ID of the key to import + * @param key_type the zkey key type, such as 'CCA-AESDATA', + * 'CCA-AESCIPHER', 'EP11-AES'. If NULL, then the + * plugin can choose its own default. + * @param key_blob a buffer to return the key blob. The size of the + * buffer is specified in key_blob_length + * @param key_blob_length on entry: the size of the key_blob buffer. + * on exit: the size of the key blob returned. + * + * @returns 0 on success, or a negative errno in case of an error. + * Function kms_get_last_error() can be used to obtain more details about the + * error. + * + */ +int kms_import_key2(const kms_handle_t handle, const char *key_id, + const char *key_type, + unsigned char *key_blob, size_t *key_blob_length); + #define KMS_API_VERSION_1 1 +#define KMS_API_VERSION_2 2 struct kms_functions { unsigned int api_version; @@ -525,6 +556,11 @@ struct kms_functions { int (*kms_import_key)(const kms_handle_t handle, const char *key_id, unsigned char *key_blob, size_t *key_blob_length); + /* Version 2 functions. Only used when api_version is >= 2. */ + int (*kms_import_key2)(const kms_handle_t handle, const char *key_id, + const char *key_type, + unsigned char *key_blob, + size_t *key_blob_length); }; /** diff --git a/zkey/kms.c b/zkey/kms.c index 643de3e2..9892a9e5 100644 --- a/zkey/kms.c +++ b/zkey/kms.c @@ -3067,6 +3067,7 @@ int list_kms_keys(struct kms_info *kms_info, const char *label_filter, * buffer is specified in key_blob_length * @param[out] key_blob_length on entry: the size of the key_blob buffer. * on exit: the size of the key blob returned. + * @param[in] key_type the key type to import (can be NULL) * @param[in] verbose if true, verbose messages are printed * * @returns 0 for success or a negative errno in case of an error. @@ -3074,7 +3075,7 @@ int list_kms_keys(struct kms_info *kms_info, const char *label_filter, int import_kms_key(struct kms_info *kms_info, const char *key1_id, const char *key2_id, bool xts, const char *name, unsigned char *key_blob, size_t *key_blob_length, - bool verbose) + const char *key_type, bool verbose) { size_t key_blob_size, key_blob_ofs, key_size = 0; struct kms_property kms_prop; @@ -3094,7 +3095,10 @@ int import_kms_key(struct kms_info *kms_info, const char *key1_id, return -ENOENT; } - if (kms_info->funcs->kms_import_key == NULL || + if ((kms_info->funcs->kms_import_key == NULL && + (kms_info->funcs->api_version < KMS_API_VERSION_2 || + (kms_info->funcs->api_version >= KMS_API_VERSION_2 && + kms_info->funcs->kms_import_key2 == NULL))) || kms_info->funcs->kms_set_key_properties == NULL) { pr_verbose(verbose, "The KMS plugin does not support to " "import keys"); @@ -3108,8 +3112,14 @@ int import_kms_key(struct kms_info *kms_info, const char *key1_id, key_blob_size = *key_blob_length; memset(key_blob, 0, key_blob_size); - rc = kms_info->funcs->kms_import_key(kms_info->handle, key1_id, - key_blob, &key_blob_size); + if (kms_info->funcs->api_version >= KMS_API_VERSION_2 && + kms_info->funcs->kms_import_key2 != NULL) + rc = kms_info->funcs->kms_import_key2(kms_info->handle, key1_id, + key_type, key_blob, + &key_blob_size); + else + rc = kms_info->funcs->kms_import_key(kms_info->handle, key1_id, + key_blob, &key_blob_size); if (rc != 0) { pr_verbose(verbose, "KMS plugin failed to import key '%s': %s", key1_id, strerror(-rc)); @@ -3134,9 +3144,20 @@ int import_kms_key(struct kms_info *kms_info, const char *key1_id, if (xts) { key_blob_size = key_size; - rc = kms_info->funcs->kms_import_key(kms_info->handle, key2_id, - key_blob + key_blob_ofs, - &key_blob_size); + if (kms_info->funcs->api_version >= KMS_API_VERSION_2 && + kms_info->funcs->kms_import_key2 != NULL) + rc = kms_info->funcs->kms_import_key2(kms_info->handle, + key2_id, + key_type, + key_blob + + key_blob_ofs, + &key_blob_size); + else + rc = kms_info->funcs->kms_import_key(kms_info->handle, + key2_id, + key_blob + + key_blob_ofs, + &key_blob_size); if (rc != 0) { pr_verbose(verbose, "KMS plugin failed to import key #2" "'%s': %s", key2_id, strerror(-rc)); @@ -3193,6 +3214,7 @@ out: * @param[out] sector_size on return: the sector_size property * @param[in] filename the file name to store the refreshed key blob in * @param[in] passphrase_file the file name to store the dummy passphras in + * @param[in] key_type the key type * @param[in] verbose if true, verbose messages are printed * * @returns 0 for success or a negative errno in case of an error. @@ -3201,7 +3223,7 @@ int refresh_kms_key(struct kms_info *kms_info, struct properties *key_props, char **description, char **cipher, char **iv_mode, char **volumes, char **volume_type, ssize_t *sector_size, const char *filename, const char *passphrase_file, - bool verbose) + const char *key_type, bool verbose) { struct kms_property *properties = NULL; u8 key_blob[2 * MAX_SECURE_KEY_SIZE]; @@ -3222,8 +3244,11 @@ int refresh_kms_key(struct kms_info *kms_info, struct properties *key_props, return -ENOENT; } - if (kms_info->funcs->kms_import_key == NULL || - kms_info->funcs->kms_get_key_properties == NULL) { + if ((kms_info->funcs->kms_import_key == NULL && + (kms_info->funcs->api_version < KMS_API_VERSION_2 || + (kms_info->funcs->api_version >= KMS_API_VERSION_2 && + kms_info->funcs->kms_import_key2 == NULL))) || + kms_info->funcs->kms_set_key_properties == NULL) { pr_verbose(verbose, "The KMS plugin does not support to " "import keys or get properties"); return -ENOTSUP; @@ -3321,8 +3346,14 @@ int refresh_kms_key(struct kms_info *kms_info, struct properties *key_props, key_blob_size = sizeof(key_blob); memset(key_blob, 0, key_blob_size); - rc = kms_info->funcs->kms_import_key(kms_info->handle, key1_id, - key_blob, &key_blob_size); + if (kms_info->funcs->api_version >= KMS_API_VERSION_2 && + kms_info->funcs->kms_import_key2 != NULL) + rc = kms_info->funcs->kms_import_key2(kms_info->handle, key1_id, + key_type, key_blob, + &key_blob_size); + else + rc = kms_info->funcs->kms_import_key(kms_info->handle, key1_id, + key_blob, &key_blob_size); if (rc != 0) { pr_verbose(verbose, "KMS plugin failed to import key '%s': %s", key1_id, strerror(-rc)); @@ -3345,9 +3376,20 @@ int refresh_kms_key(struct kms_info *kms_info, struct properties *key_props, if (xts) { key_blob_size = key_size; - rc = kms_info->funcs->kms_import_key(kms_info->handle, key2_id, - key_blob + key_size, - &key_blob_size); + if (kms_info->funcs->api_version >= KMS_API_VERSION_2 && + kms_info->funcs->kms_import_key2 != NULL) + rc = kms_info->funcs->kms_import_key2(kms_info->handle, + key2_id, + key_type, + key_blob + + key_size, + &key_blob_size); + else + rc = kms_info->funcs->kms_import_key(kms_info->handle, + key2_id, + key_blob + + key_size, + &key_blob_size); if (rc != 0) { pr_verbose(verbose, "KMS plugin failed to import key #2" "'%s': %s", key2_id, strerror(-rc)); diff --git a/zkey/kms.h b/zkey/kms.h index 6ce8b11a..42aefe9e 100644 --- a/zkey/kms.h +++ b/zkey/kms.h @@ -117,12 +117,12 @@ int list_kms_keys(struct kms_info *kms_info, const char *label_filter, int import_kms_key(struct kms_info *kms_info, const char *key1_id, const char *key2_id, bool xts, const char *name, unsigned char *key_blob, size_t *key_blob_length, - bool verbose); + const char *key_type, bool verbose); int refresh_kms_key(struct kms_info *kms_info, struct properties *key_props, char **description, char **cipher, char **iv_mode, char **volumes, char **volume_type, ssize_t *sector_size, const char *filename, const char *passphrase_file, - bool verbose); + const char *key_type, bool verbose); #endif