diff mbox series

dm-verity: Add support for fdt root-hash signature

Message ID 20230806102130.164565-1-loic.poulain@linaro.org (mailing list archive)
State New, archived
Headers show
Series dm-verity: Add support for fdt root-hash signature | expand

Commit Message

Loic Poulain Aug. 6, 2023, 10:21 a.m. UTC
Allow root_hash_sig_key_desc to be in the form of a fdt-path:fdt-prop
string so that the root hash signature is extracted from the devicetree
instead of the Linux keyring.

This allows passing a root hash signature for a mapping without the need
for a userspace signature loader (no ramdisk).

Example:
dm-mod.create="vroot,,0,ro,0 1372664 verity ... 2 root_hash_sig_key_desc /verity:vroot-hash-sig"

Will read signature from the vroot-hash-sig prop of verity node:
/ {
    verity {
        vroot-hash-sig = [ 00 3f 45 42 ... ];
    };
};

Typically, the root hash signature can be injected in fdt by the
bootloader.

Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
---
 drivers/md/dm-verity-verify-sig.c | 53 ++++++++++++++++++++++++++++++-
 1 file changed, 52 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/drivers/md/dm-verity-verify-sig.c b/drivers/md/dm-verity-verify-sig.c
index 4836508ea50c..ad42e8527dd8 100644
--- a/drivers/md/dm-verity-verify-sig.c
+++ b/drivers/md/dm-verity-verify-sig.c
@@ -9,6 +9,7 @@ 
 #include <linux/verification.h>
 #include <keys/user-type.h>
 #include <linux/module.h>
+#include <linux/of.h>
 #include "dm-verity.h"
 #include "dm-verity-verify-sig.h"
 
@@ -64,6 +65,52 @@  static int verity_verify_get_sig_from_key(const char *key_desc,
 	return ret;
 }
 
+static int verity_verify_get_sig_from_fdt(const char *key_desc,
+					  struct dm_verity_sig_opts *sig_opts)
+{
+	struct device_node *node;
+	char *path, *name, *str;
+	struct property *prop;
+	int ret = 0;
+
+	str = kstrdup(key_desc, GFP_KERNEL);
+	if (!str)
+		return -ENOMEM;
+
+	path = strsep(&str, ":");
+	name = str;
+
+	if (!path || !name) {
+		ret = -EINVAL;
+		goto end;
+	}
+
+	node = of_find_node_by_path(path);
+	if (!node) {
+		ret = -ENOENT;
+		goto end;
+	}
+
+	prop = of_find_property(node, name, NULL);
+	if (!prop) {
+		ret = -ENOENT;
+		goto end;
+	}
+
+	sig_opts->sig = kmalloc(prop->length, GFP_KERNEL);
+	if (!sig_opts->sig) {
+		ret = -ENOMEM;
+		goto end;
+	}
+
+	memcpy(sig_opts->sig, prop->value, prop->length);
+	sig_opts->sig_size = prop->length;
+
+end:
+	kfree(str);
+	return ret;
+}
+
 int verity_verify_sig_parse_opt_args(struct dm_arg_set *as,
 				     struct dm_verity *v,
 				     struct dm_verity_sig_opts *sig_opts,
@@ -82,7 +129,11 @@  int verity_verify_sig_parse_opt_args(struct dm_arg_set *as,
 	sig_key = dm_shift_arg(as);
 	(*argc)--;
 
-	ret = verity_verify_get_sig_from_key(sig_key, sig_opts);
+	if (sig_key[0] == '/') /* this is a fdt path */
+		ret = verity_verify_get_sig_from_fdt(sig_key, sig_opts);
+	else
+		ret = verity_verify_get_sig_from_key(sig_key, sig_opts);
+
 	if (ret < 0)
 		ti->error = DM_VERITY_VERIFY_ERR("Invalid key specified");