cmd: pxe_utils: sysboot: add kaslr-seed generation support

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 <zhangn1985@qq.com>
This commit is contained in:
Zhang Ning 2022-02-01 08:33:37 +08:00 committed by Tom Rini
parent 86752b2814
commit 0290146943
3 changed files with 79 additions and 0 deletions

View File

@ -20,6 +20,11 @@
#include <errno.h> #include <errno.h>
#include <linux/list.h> #include <linux/list.h>
#ifdef CONFIG_DM_RNG
#include <dm.h>
#include <rng.h>
#endif
#include <splash.h> #include <splash.h>
#include <asm/io.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); 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' * 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 #ifdef CONFIG_OF_LIBFDT_OVERLAY
if (label->fdtoverlays) if (label->fdtoverlays)
label_boot_fdtoverlay(ctx, label); label_boot_fdtoverlay(ctx, label);
@ -710,6 +779,7 @@ enum token_type {
T_ONTIMEOUT, T_ONTIMEOUT,
T_IPAPPEND, T_IPAPPEND,
T_BACKGROUND, T_BACKGROUND,
T_KASLRSEED,
T_INVALID T_INVALID
}; };
@ -741,6 +811,7 @@ static const struct token keywords[] = {
{"ontimeout", T_ONTIMEOUT,}, {"ontimeout", T_ONTIMEOUT,},
{"ipappend", T_IPAPPEND,}, {"ipappend", T_IPAPPEND,},
{"background", T_BACKGROUND,}, {"background", T_BACKGROUND,},
{"kaslrseed", T_KASLRSEED,},
{NULL, T_INVALID} {NULL, T_INVALID}
}; };
@ -1194,6 +1265,10 @@ static int parse_label(char **c, struct pxe_menu *cfg)
err = parse_integer(c, &label->ipappend); err = parse_integer(c, &label->ipappend);
break; break;
case T_KASLRSEED:
label->kaslrseed = 1;
break;
case T_EOL: case T_EOL:
break; break;

View File

@ -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 and then applied in the load order to the fdt blob stored at the
address indicated in the fdt_addr_r environment variable. 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 append <string> - use <string> as the kernel command line when booting this
label. label.

View File

@ -33,6 +33,7 @@
* initrd - path to the initrd to use for this label. * 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. * attempted - 0 if we haven't tried to boot this label, 1 if we have.
* localboot - 1 if this label specified 'localboot', 0 otherwise. * 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. * list - lets these form a list, which a pxe_menu struct will hold.
*/ */
struct pxe_label { struct pxe_label {
@ -50,6 +51,7 @@ struct pxe_label {
int attempted; int attempted;
int localboot; int localboot;
int localboot_val; int localboot_val;
int kaslrseed;
struct list_head list; struct list_head list;
}; };