zkey: Add INTEGRITY volume type

Keys of type PVSECRET-HMAC can be associated to volumes of volume type
'INTEGTRITY' or 'LUKS2'.

Volumes of type 'INTEGTRITY' are set up for standalone dm-integrity via
the 'integritysetup' tool. Volumes of type 'LUKS2' are setup for combined
encryption and integrity using the 'cryptsetup' tool using the integrity
option.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
Ingo Franzki
2024-03-11 11:39:53 +01:00
committed by Jan Höppner
parent d9eee82ab0
commit 0047fc162e
3 changed files with 92 additions and 43 deletions

View File

@@ -57,7 +57,9 @@ struct key_filenames {
#define VOLUME_TYPE_PLAIN "plain"
#define VOLUME_TYPE_LUKS2 "luks2"
#define VOLUME_TYPE_INTEGRITY "integrity"
#define DEFAULT_VOLUME_TYPE VOLUME_TYPE_LUKS2
#define DEFAULT_INTERITY_VOLUME_TYPE VOLUME_TYPE_INTEGRITY
#define REC_KEY "Key"
#define REC_DESCRIPTION "Description"
@@ -292,16 +294,30 @@ static int _keystore_valid_sector_size(size_t sector_size)
/**
* Checks if the volume type is supported.
*
* @param[in] key_type the key type of the key associated to the volume,
* or NULL if the volume type is to be checked
* independent of the key type.
* @param[in] volume_type the volume type
*
* @returns 1 if the volume type is valid, 0 otherwise
*/
static int _keystore_valid_volume_type(const char *volume_type)
static int _keystore_valid_volume_type(const char *key_type,
const char *volume_type)
{
if (strcasecmp(volume_type, VOLUME_TYPE_PLAIN) == 0)
return 1;
if (strcasecmp(volume_type, VOLUME_TYPE_LUKS2) == 0)
return 1;
if (key_type == NULL || is_aes_key_type(key_type)) {
if (strcasecmp(volume_type, VOLUME_TYPE_PLAIN) == 0)
return 1;
if (strcasecmp(volume_type, VOLUME_TYPE_LUKS2) == 0)
return 1;
};
if (key_type == NULL || is_hmac_key_type(key_type)) {
if (strcasecmp(volume_type, VOLUME_TYPE_INTEGRITY) == 0)
return 1;
if (strcasecmp(volume_type, VOLUME_TYPE_LUKS2) == 0)
return 1;
}
return 0;
}
@@ -1863,8 +1879,10 @@ static int _keystore_create_info_props(struct keystore *keystore,
}
if (volume_type == NULL)
volume_type = DEFAULT_VOLUME_TYPE;
if (!_keystore_valid_volume_type(volume_type)) {
volume_type = is_hmac_key_type(key_type) ?
DEFAULT_INTERITY_VOLUME_TYPE :
DEFAULT_VOLUME_TYPE;
if (!_keystore_valid_volume_type(key_type, volume_type)) {
warnx("Invalid volume-type specified");
rc = -EINVAL;
goto out;
@@ -2582,8 +2600,8 @@ int keystore_change_key(struct keystore *keystore, const char *name,
struct key_filenames file_names = { 0 };
struct properties *key_props = NULL;
const char **passphrase_upd = NULL;
char *apqns_prop, *key_type = NULL;
char *upd_volume_type = NULL;
char *apqns_prop, *key_type;
const char *null_ptr = NULL;
char *upd_volumes = NULL;
size_t secure_key_size;
@@ -2618,6 +2636,8 @@ int keystore_change_key(struct keystore *keystore, const char *name,
goto out;
}
key_type = _keystore_get_key_type(key_props);
if (description != NULL) {
rc = properties_set(key_props, PROP_NAME_DESCRIPTION,
description);
@@ -2676,14 +2696,12 @@ int keystore_change_key(struct keystore *keystore, const char *name,
goto out;
apqns_prop = properties_get(key_props, PROP_NAME_APQNS);
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);
free(key_type);
if (rc == -ENOTSUP)
rc = 0;
if (rc != 0 && noapqncheck == 0) {
@@ -2709,7 +2727,7 @@ int keystore_change_key(struct keystore *keystore, const char *name,
}
if (volume_type != NULL) {
if (!_keystore_valid_volume_type(volume_type)) {
if (!_keystore_valid_volume_type(key_type, volume_type)) {
warnx("Invalid volume-type specified");
rc = -EINVAL;
goto out;
@@ -2807,6 +2825,8 @@ out:
free(upd_volume_type);
if (secure_key != NULL)
free(secure_key);
if (key_type != NULL)
free(key_type);
if (rc != 0)
pr_verbose(keystore, "Failed to change key '%s': %s",
@@ -2923,6 +2943,13 @@ int keystore_rename_key(struct keystore *keystore, const char *name,
_keystore_msg_for_volumes(msg, key_props, VOLUME_TYPE_PLAIN);
free(msg);
util_asprintf(&msg, "The following volumes are associated with the "
"renamed key '%s'. You should adjust the corresponding "
"integritytab entries and 'integritysetup open' commands "
"to use the new name.", newname);
_keystore_msg_for_volumes(msg, key_props, VOLUME_TYPE_INTEGRITY);
free(msg);
if (_keystore_passphrase_file_exists(&new_names)) {
util_asprintf(&msg, "The following volumes are associated with "
"the renamed key '%s'. You should adjust the "
@@ -4083,6 +4110,7 @@ static int _keystore_prompt_for_remove(struct keystore *keystore,
util_asprintf(&msg, "When you remove key '%s' the following volumes "
"will no longer be usable:", name);
_keystore_msg_for_volumes(msg, key_prop, VOLUME_TYPE_PLAIN);
_keystore_msg_for_volumes(msg, key_prop, VOLUME_TYPE_INTEGRITY);
free(msg);
printf("%s: Remove key '%s' [y/N]? ", program_invocation_short_name,
@@ -4282,7 +4310,7 @@ int keystore_list_keys(struct keystore *keystore, const char *name_filter,
util_assert(keystore != NULL, "Internal error: keystore is NULL");
if (volume_type != NULL &&
!_keystore_valid_volume_type(volume_type)) {
!_keystore_valid_volume_type(NULL, volume_type)) {
warnx("Invalid volume-type specified");
return -EINVAL;
}
@@ -4754,7 +4782,7 @@ int keystore_cryptsetup(struct keystore *keystore, const char *volume_filter,
volume_filter = "*";
if (volume_type != NULL &&
!_keystore_valid_volume_type(volume_type)) {
!_keystore_valid_volume_type(NULL, volume_type)) {
warnx("Invalid volume-type specified");
return -EINVAL;
}
@@ -4821,7 +4849,7 @@ int keystore_crypttab(struct keystore *keystore, const char *volume_filter,
volume_filter = "*";
if (volume_type != NULL &&
!_keystore_valid_volume_type(volume_type)) {
!_keystore_valid_volume_type(NULL, volume_type)) {
warnx("Invalid volume-type specified");
return -EINVAL;
}
@@ -5683,7 +5711,7 @@ int keystore_import_kms_keys(struct keystore *keystore,
}
if (volume_type != NULL &&
!_keystore_valid_volume_type(volume_type)) {
!_keystore_valid_volume_type(NULL, volume_type)) {
warnx("Invalid volume-type specified");
return -EINVAL;
}
@@ -5820,7 +5848,7 @@ static int _keystore_refresh_kms_key(struct keystore *keystore,
}
if (volume_type != NULL) {
if (!_keystore_valid_volume_type(volume_type)) {
if (!_keystore_valid_volume_type(key_type, volume_type)) {
warnx("Invalid volume-type specified");
rc = -EINVAL;
goto out;
@@ -5927,7 +5955,7 @@ int keystore_refresh_kms_keys(struct keystore *keystore,
}
if (volume_type != NULL &&
!_keystore_valid_volume_type(volume_type)) {
!_keystore_valid_volume_type(NULL, volume_type)) {
warnx("Invalid volume-type specified");
return -EINVAL;
}

View File

@@ -1384,9 +1384,10 @@ sector size is used.
This option is only used for secure keys contained in the secure key repository.
.TP
.BR \-t ", " \-\-volume\-type\~\fItype\fP
Specifies the volume type of the associated volumes used with \fBdm\-crypt\fP.
Possible values are \fBplain\fP and \fBluks2\fP. If omitted, \fBluks2\fP is
used.
Specifies the volume type of the associated volumes used with \fBdm\-crypt\fP or
\fBdm\-integrity\fP. Possible values for AES keys are \fBplain\fP and
\fBluks2\fP, and \fBintegrity\fP and \fBluks2\fP for HMAC keys. If omitted,
\fBluks2\fP is used for AES keys, and \fBintegrity\fP for HMAC keys.
This option is only used for secure keys contained in the secure key repository.
.TP
.BR \-K ", " \-\-key\-type\~\fItype\fP
@@ -1557,8 +1558,9 @@ This option is only used for secure keys contained in the secure key repository.
.TP
.BR \-t ", " \-\-volume\-type\~\fItype\fP
Specifies the volume type of the associated volumes used with \fBdm\-crypt\fP or
\fBdm\-integrity\fP. Possible values are \fBplain\fP and \fBluks2\fP. If
omitted, \fBluks2\fP is used.
\fBdm\-integrity\fP. Possible values for AES keys are \fBplain\fP and
\fBluks2\fP, and \fBintegrity\fP and \fBluks2\fP for HMAC keys. If omitted,
\fBluks2\fP is used for AES keys, and \fBintegrity\fP for HMAC keys.
This option is only used for secure keys contained in the secure key repository.
.TP
.BR \-\-gen\-dummy\-passphrase
@@ -1624,8 +1626,9 @@ This option is only used for secure keys contained in the secure key repository.
.TP
.BR \-t ", " \-\-volume\-type\~\fItype\fP
Specifies the volume type of the associated volumes used with \fBdm\-crypt\fP or
\fBdm\-integrity\fP. Possible values are \fBplain\fP and \fBluks2\fP. Only keys
with the specified volume type are listed.
\fBdm\-integrity\fP. Possible values for AES keys are \fBplain\fP and
\fBluks2\fP, and \fBintegrity\fP and \fBluks2\fP for HMAC keys.
Only keys with the specified volume type are listed.
This option is only used for secure keys contained in the secure key repository.
.TP
.BR \-K ", " \-\-key\-type\~\fItype\fP
@@ -1725,7 +1728,8 @@ This option is only used for secure keys contained in the secure key repository.
.TP
.BR \-t ", " \-\-volume\-type\~\fItype\fP
Specifies the volume type of the associated volumes used with \fBdm\-crypt\fP or
\fBdm\-integrity\fP. Possible values are \fBplain\fP and \fBluks2\fP.
\fBdm\-integrity\fP. Possible values for AES keys are \fBplain\fP and
\fBluks2\fP, and \fBintegrity\fP and \fBluks2\fP for HMAC keys.
This option is only used for secure keys contained in the secure key repository.
.TP
.BR \-\-gen\-dummy\-passphrase
@@ -2049,7 +2053,8 @@ When wildcards are used you must quote the value.
.TP
.BR \-t ", " \-\-volume\-type\~\fItype\fP
Specifies the volume type of the associated volumes used with \fBdm\-crypt\fP or
\fBdm\-integrity\fP. Possible values are \fBplain\fP and \fBluks2\fP. Only keys
\fBdm\-integrity\fP. Possible values for AES keys are \fBplain\fP and
\fBluks2\fP, and \fBintegrity\fP and \fBluks2\fP for HMAC keys. Only keys
with the specified volume type are listed.
.
.
@@ -2081,7 +2086,8 @@ When wildcards are used you must quote the value.
.TP
.BR \-t ", " \-\-volume\-type\~\fItype\fP
Specifies the volume type of the associated volumes used with \fBdm\-crypt\fP or
\fBdm\-integrity\fP. Possible values are \fBplain\fP and \fBluks2\fP. Only keys
\fBdm\-integrity\fP. Possible values for AES keys are \fBplain\fP and
\fBluks2\fP, and \fBintegrity\fP and \fBluks2\fP for HMAC keys. Only keys
with the specified volume type are imported.
.TP
.BR \-q ", " \-\-batch\-mode
@@ -2117,7 +2123,8 @@ When wildcards are used you must quote the value.
.TP
.BR \-t ", " \-\-volume\-type\~\fItype\fP
Specifies the volume type of the associated volumes used with \fBdm\-crypt\fP or
\fBdm\-integrity\fP. Possible values are \fBplain\fP and \fBluks2\fP. Only keys
\fBdm\-integrity\fP. Possible values for AES keys are \fBplain\fP and
\fBluks2\fP, and \fBintegrity\fP and \fBluks2\fP for HMAC keys. Only keys
with the specified volume type are refreshed.
.TP
.BR \-K ", " \-\-key\-type\~\fItype\fP
@@ -2228,7 +2235,9 @@ bytes. If omitted, the system default sector size is used.
.TP
.BR \-t ", " \-\-volume\-type\~\fItype\fP
Specifies the volume type of the associated volumes used with \fBdm\-crypt\fP or
\fBdm\-integrity\fP. Possible values are \fBplain\fP and \fBluks2\fP. If
\fBdm\-integrity\fP. Possible values for AES keys are \fBplain\fP and
\fBluks2\fP, and \fBintegrity\fP and \fBluks2\fP for HMAC keys. If omitted,
\fBluks2\fP is used for AES keys, and \fBintegrity\fP for HMAC keys. If
omitted, \fBluks2\fP is used.
.TP
.BR \-\-gen\-dummy\-passphrase

View File

@@ -271,8 +271,10 @@ static struct util_opt opt_vec[] = {
.option = { "volume-type", required_argument, NULL, 't'},
.argument = "type",
.desc = "The type of the associated volume(s). Possible values "
"are 'plain' and 'luks2'. When this option is omitted, "
"the default is 'luks2'",
"for AES keys are 'plain' and 'luks2', and 'integrity' "
"and 'luks2' for HMAC keys. When this option is omitted, "
"the default is 'luks2' for AES keys and 'integrity' "
"for HMAC keys.",
.command = COMMAND_GENERATE,
},
{
@@ -491,8 +493,10 @@ static struct util_opt opt_vec[] = {
.option = { "volume-type", required_argument, NULL, 't'},
.argument = "type",
.desc = "The type of the associated volume(s). Possible values "
"are 'plain' and 'luks2'. When this option is omitted, "
"the default is 'luks2'",
"for AES keys are 'plain' and 'luks2', and 'integrity' "
"and 'luks2' for HMAC keys. When this option is omitted, "
"the default is 'luks2' for AES keys and 'integrity' "
"for HMAC keys.",
.command = COMMAND_IMPORT,
},
{
@@ -585,8 +589,9 @@ static struct util_opt opt_vec[] = {
.option = { "volume-type", required_argument, NULL, 't'},
.argument = "type",
.desc = "The type of the associated volume(s). Possible values "
"are 'plain' and 'luks2'. Use this option to list all "
"keys with the specified volumes type.",
"are 'plain', 'luks2', and 'integrity'. Use this "
"option to list all keys with the specified volumes "
"type.",
.command = COMMAND_LIST,
},
{
@@ -692,7 +697,8 @@ static struct util_opt opt_vec[] = {
.option = { "volume-type", required_argument, NULL, 't'},
.argument = "type",
.desc = "The type of the associated volume(s). Possible values "
"are 'plain' and 'luks2'",
"for AES keys are 'plain' and 'luks2', and 'integrity' "
"and 'luks2' for HMAC keys.",
.command = COMMAND_CHANGE,
},
{
@@ -1102,8 +1108,9 @@ static struct util_opt opt_vec[] = {
.option = { "volume-type", required_argument, NULL, 't'},
.argument = "type",
.desc = "The type of the associated volume(s). Possible values "
"are 'plain' and 'luks2'. Use this option to list all "
"keys with the specified volumes type.",
"are 'plain', 'luks2', and 'integrity'. Use this "
"option to list all keys with the specified volumes "
"type.",
.command = COMMAND_KMS " " COMMAND_KMS_LIST,
},
/***********************************************************/
@@ -1144,8 +1151,10 @@ static struct util_opt opt_vec[] = {
.option = { "volume-type", required_argument, NULL, 't'},
.argument = "type",
.desc = "The type of the associated volume(s). Possible values "
"are 'plain' and 'luks2'. Use this option to import "
"all keys with the specified volumes type.",
"for AES keys are 'plain' and 'luks2', and 'integrity' "
"and 'luks2' for HMAC keys. When this option is omitted, "
"the default is 'luks2' for AES keys and 'integrity' "
"for HMAC keys.",
.command = COMMAND_KMS " " COMMAND_KMS_IMPORT,
},
{
@@ -1194,7 +1203,8 @@ static struct util_opt opt_vec[] = {
.option = { "volume-type", required_argument, NULL, 't'},
.argument = "type",
.desc = "The type of the associated volume(s). Possible values "
"are 'plain' and 'luks2'. Use this option to refresh "
"for AES keys are 'plain' and 'luks2', and 'integrity' "
"and 'luks2' for HMAC keys. Use this option to refresh "
"all keys with the specified volumes type.",
.command = COMMAND_KMS " " COMMAND_KMS_REFRESH,
},
@@ -1327,8 +1337,10 @@ static struct util_opt opt_vec[] = {
.option = { "volume-type", required_argument, NULL, 't'},
.argument = "type",
.desc = "The type of the associated volume(s). Possible values "
"are 'plain' and 'luks2'. When this option is omitted, "
"the default is 'luks2'",
"for AES keys are 'plain' and 'luks2', and 'integrity' "
"and 'luks2' for HMAC keys. When this option is omitted, "
"the default is 'luks2' for AES keys and 'integrity' "
"for HMAC keys.",
.command = COMMAND_PVSECRETS " " COMMAND_PVSECRETS_IMPORT,
},
{