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.poul...@linaro.org>
---
 drivers/md/dm-verity-verify-sig.c | 53 ++++++++++++++++++++++++++++++-
 1 file changed, 52 insertions(+), 1 deletion(-)

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");
 
-- 
2.34.1

--
dm-devel mailing list
dm-devel@redhat.com
https://listman.redhat.com/mailman/listinfo/dm-devel

Reply via email to