dm verity: Add root_hash_sig_key_value parameter

With root_hash_sig_key_value parameter, signature can be passed by
kernel command line. So the root has signature verification can be
supported at init time.

Change-Id: Id40b3b781898543a7f5a3ddb75a1e2745e2d74f5
Signed-off-by: Cong Zhang <quic_congzhan@quicinc.com>
This commit is contained in:
Cong Zhang 2023-02-08 02:21:14 -08:00
parent 888ef98cc5
commit 95bfca0d88
4 changed files with 83 additions and 0 deletions

View file

@ -527,6 +527,15 @@ config DM_INIT
If unsure, say N.
config DM_VERITY_SIG_VALUE
bool "DM \"root_hash_sig_key_value\" parameter support"
depends on DM_INIT=y
help
Enable "root_hash_sig_key_value" parameter in "dm-mod.create=" to create
mapped devices at init time. The option is used to directly pass root hash
signature value from kernel command line. So root hash signature
verification can be enabled without initramfs.
config DM_UEVENT
bool "DM uevents"
depends on BLK_DEV_DM

View file

@ -1132,6 +1132,15 @@ static int verity_parse_opt_args(struct dm_arg_set *as, struct dm_verity *v,
* properly parse all options (and their extra args).
*/
continue;
#if defined(CONFIG_DM_VERITY_SIG_VALUE)
} else if (verity_verify_is_sig_value_opt_arg(arg_name)) {
r = verity_verify_sig_value_parse_opt_args(
as, v, verify_args, &argc, arg_name);
if (r)
return r;
continue;
#endif
}
DMERR("Unrecognized verity feature request: %s", arg_name);

View file

@ -93,6 +93,61 @@ int verity_verify_sig_parse_opt_args(struct dm_arg_set *as,
return ret;
}
#if defined(CONFIG_DM_VERITY_SIG_VALUE)
bool verity_verify_is_sig_value_opt_arg(const char *arg_name)
{
return (!strcasecmp(
arg_name, DM_VERITY_ROOT_HASH_VERIFICATION_OPT_SIG_KEY_VALUE));
}
static int
verity_verify_get_sig_from_key_value(const char *key_value,
struct dm_verity_sig_opts *sig_opts)
{
int ret = 0;
if (!key_value)
return -ENOMEM;
sig_opts->sig_size = strlen(key_value) / 2;
sig_opts->sig = kmalloc(sig_opts->sig_size, GFP_KERNEL);
if (!sig_opts->sig) {
ret = -ENOMEM;
goto end;
}
ret = hex2bin(sig_opts->sig, key_value, strlen(key_value) / 2);
end:
return ret;
}
int verity_verify_sig_value_parse_opt_args(struct dm_arg_set *as,
struct dm_verity *v,
struct dm_verity_sig_opts *sig_opts,
unsigned int *argc,
const char *arg_name)
{
struct dm_target *ti = v->ti;
int ret = 0;
const char *sig_key_value = NULL;
if (!*argc) {
ti->error = DM_VERITY_VERIFY_ERR(
"Signature key value not specified");
return -EINVAL;
}
sig_key_value = dm_shift_arg(as);
(*argc)--;
ret = verity_verify_get_sig_from_key_value(sig_key_value, sig_opts);
if (ret < 0)
ti->error = DM_VERITY_VERIFY_ERR("Invalid key specified");
return ret;
}
#endif
/*
* verify_verify_roothash - Verify the root hash of the verity hash device
* using builtin trusted keys.

View file

@ -10,6 +10,7 @@
#define DM_VERITY_ROOT_HASH_VERIFICATION "DM Verity Sig Verification"
#define DM_VERITY_ROOT_HASH_VERIFICATION_OPT_SIG_KEY "root_hash_sig_key_desc"
#define DM_VERITY_ROOT_HASH_VERIFICATION_OPT_SIG_KEY_VALUE "root_hash_sig_key_value"
struct dm_verity_sig_opts {
unsigned int sig_size;
@ -28,6 +29,15 @@ int verity_verify_sig_parse_opt_args(struct dm_arg_set *as, struct dm_verity *v,
struct dm_verity_sig_opts *sig_opts,
unsigned int *argc, const char *arg_name);
#ifdef CONFIG_DM_VERITY_SIG_VALUE
bool verity_verify_is_sig_value_opt_arg(const char *arg_name);
int verity_verify_sig_value_parse_opt_args(struct dm_arg_set *as,
struct dm_verity *v,
struct dm_verity_sig_opts *sig_opts,
unsigned int *argc,
const char *arg_name);
#endif
void verity_verify_sig_opts_cleanup(struct dm_verity_sig_opts *sig_opts);
#else