zkey: Allow KMS plugin to import a key of a specific type

KMS plugins that support multiple key types need to know which
key type to produce with the kms_import_key() function. Extend
the plugin API to allow a plugin to provide a kms_import_key2()
function, that accepts the key type as additional parameter.

Existing plugins do not need to be changed, as the old function
kms_import_key() still exists, and is still used when the plugin
does not provide a kms_import_key2() function.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
Ingo Franzki
2021-06-07 16:00:00 +02:00
committed by Jan Höppner
parent 56fecf1832
commit 154914ee7a
4 changed files with 104 additions and 20 deletions

View File

@@ -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, &sector_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;
}

View File

@@ -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);
};
/**

View File

@@ -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));

View File

@@ -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