this will add kaslrseed keyword to sysboot lable,
when it set, it will request to genarate random number
from hwrng as kaslr-seed.

with this patch exlinux.conf label looks like

label l0
        menu testing
        linux /boot/vmlinuz-5.15.16-arm
        initrd /boot/initramfs-5.15.16-arm.img
        fdtdir /boot/dtbs/5.15.16-arm/
        kaslrseed
        append root=UUID=92ae1e50-eeeb-4c5b-8939-7e1cd6cfb059 ro

Tested on Khadas VIM with kernel 5.16.0-rc5-arm64, Debian 11.

Signed-off-by: Zhang Ning <zhangn1...@qq.com>
---
 boot/pxe_utils.c    | 75 +++++++++++++++++++++++++++++++++++++++++++++
 doc/README.pxe      |  2 ++
 include/pxe_utils.h |  2 ++
 3 files changed, 79 insertions(+)

diff --git a/boot/pxe_utils.c b/boot/pxe_utils.c
index bb231b11a2..0c24becae3 100644
--- a/boot/pxe_utils.c
+++ b/boot/pxe_utils.c
@@ -20,6 +20,11 @@
 #include <errno.h>
 #include <linux/list.h>
 
+#ifdef CONFIG_DM_RNG
+#include <dm.h>
+#include <rng.h>
+#endif
+
 #include <splash.h>
 #include <asm/io.h>
 
@@ -311,6 +316,67 @@ static int label_localboot(struct pxe_label *label)
        return run_command_list(localcmd, strlen(localcmd), 0);
 }
 
+/*
+ * label_boot_kaslrseed generate kaslrseed from hw rng
+ */
+
+static void label_boot_kaslrseed(void)
+{
+#ifdef CONFIG_DM_RNG
+       ulong fdt_addr;
+       struct fdt_header *working_fdt;
+       size_t n = 0x8;
+       struct udevice *dev;
+       u64 *buf;
+       int nodeoffset;
+       int err;
+
+       /* Get the main fdt and map it */
+       fdt_addr = hextoul(env_get("fdt_addr_r"), NULL);
+       working_fdt = map_sysmem(fdt_addr, 0);
+       err = fdt_check_header(working_fdt);
+       if (err)
+               return;
+
+       /* add extra size for holding kaslr-seed */
+       /* err is new fdt size, 0 or negtive */
+       err = fdt_shrink_to_minimum(working_fdt, 512);
+       if (err <= 0)
+               return;
+
+       if (uclass_get_device(UCLASS_RNG, 0, &dev) || !dev) {
+               printf("No RNG device\n");
+               return;
+       }
+
+       nodeoffset = fdt_find_or_add_subnode(working_fdt, 0, "chosen");
+       if (nodeoffset < 0) {
+               printf("Reading chosen node failed\n");
+               return;
+       }
+
+       buf = malloc(n);
+       if (!buf) {
+               printf("Out of memory\n");
+               return;
+       }
+
+       if (dm_rng_read(dev, buf, n)) {
+               printf("Reading RNG failed\n");
+               goto err;
+       }
+
+       err = fdt_setprop(working_fdt, nodeoffset, "kaslr-seed", buf, 
sizeof(buf));
+       if (err < 0) {
+               printf("Unable to set kaslr-seed on chosen node: %s\n", 
fdt_strerror(err));
+               goto err;
+       }
+err:
+       free(buf);
+#endif
+       return;
+}
+
 /**
  * label_boot_fdtoverlay() - Loads fdt overlays specified in 'fdtoverlays'
  *
@@ -631,6 +697,9 @@ static int label_boot(struct pxe_context *ctx, struct 
pxe_label *label)
                                }
                        }
 
+               if (label->kaslrseed)
+                       label_boot_kaslrseed();
+
 #ifdef CONFIG_OF_LIBFDT_OVERLAY
                        if (label->fdtoverlays)
                                label_boot_fdtoverlay(ctx, label);
@@ -710,6 +779,7 @@ enum token_type {
        T_ONTIMEOUT,
        T_IPAPPEND,
        T_BACKGROUND,
+       T_KASLRSEED,
        T_INVALID
 };
 
@@ -741,6 +811,7 @@ static const struct token keywords[] = {
        {"ontimeout", T_ONTIMEOUT,},
        {"ipappend", T_IPAPPEND,},
        {"background", T_BACKGROUND,},
+       {"kaslrseed", T_KASLRSEED,},
        {NULL, T_INVALID}
 };
 
@@ -1194,6 +1265,10 @@ static int parse_label(char **c, struct pxe_menu *cfg)
                        err = parse_integer(c, &label->ipappend);
                        break;
 
+               case T_KASLRSEED:
+                       label->kaslrseed = 1;
+                       break;
+
                case T_EOL:
                        break;
 
diff --git a/doc/README.pxe b/doc/README.pxe
index a1f0423adb..75caa01c4a 100644
--- a/doc/README.pxe
+++ b/doc/README.pxe
@@ -163,6 +163,8 @@ fdtoverlays <path> [...] - if this label is chosen, use 
tftp to retrieve the DT
                       and then applied in the load order to the fdt blob 
stored at the
                       address indicated in the fdt_addr_r environment variable.
 
+kaslrseed           - set this label to request random number from hwrng as 
kaslr seed.
+
 append <string>            - use <string> as the kernel command line when 
booting this
                      label.
 
diff --git a/include/pxe_utils.h b/include/pxe_utils.h
index dad2668818..4a73b2aace 100644
--- a/include/pxe_utils.h
+++ b/include/pxe_utils.h
@@ -33,6 +33,7 @@
  * initrd - path to the initrd to use for this label.
  * attempted - 0 if we haven't tried to boot this label, 1 if we have.
  * localboot - 1 if this label specified 'localboot', 0 otherwise.
+ * kaslrseed - 1 if generate kaslrseed from hw_rng
  * list - lets these form a list, which a pxe_menu struct will hold.
  */
 struct pxe_label {
@@ -50,6 +51,7 @@ struct pxe_label {
        int attempted;
        int localboot;
        int localboot_val;
+       int kaslrseed;
        struct list_head list;
 };
 
-- 
2.34.1

Reply via email to