summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--boot/pxe_utils.c75
-rw-r--r--doc/README.pxe2
-rw-r--r--include/pxe_utils.h2
3 files changed, 79 insertions, 0 deletions
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;
};