1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * The 'kaslrseed' command takes bytes from the hardware random number 4 * generator and uses them to set the kaslr-seed value in the chosen node. 5 * 6 * Copyright (c) 2021, Chris Morgan <macromorgan@hotmail.com> 7 */ 8 9#include <common.h> 10#include <command.h> 11#include <dm.h> 12#include <hexdump.h> 13#include <malloc.h> 14#include <rng.h> 15#include <fdt_support.h> 16 17static int do_kaslr_seed(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) 18{ 19 size_t n = 0x8; 20 struct udevice *dev; 21 u64 *buf; 22 int nodeoffset; 23 int ret = CMD_RET_SUCCESS; 24 25 if (uclass_get_device(UCLASS_RNG, 0, &dev) || !dev) { 26 printf("No RNG device\n"); 27 return CMD_RET_FAILURE; 28 } 29 30 buf = malloc(n); 31 if (!buf) { 32 printf("Out of memory\n"); 33 return CMD_RET_FAILURE; 34 } 35 36 if (dm_rng_read(dev, buf, n)) { 37 printf("Reading RNG failed\n"); 38 return CMD_RET_FAILURE; 39 } 40 41 if (!working_fdt) { 42 printf("No FDT memory address configured. Please configure\n" 43 "the FDT address via \"fdt addr <address>\" command.\n" 44 "Aborting!\n"); 45 return CMD_RET_FAILURE; 46 } 47 48 ret = fdt_check_header(working_fdt); 49 if (ret < 0) { 50 printf("fdt_chosen: %s\n", fdt_strerror(ret)); 51 return CMD_RET_FAILURE; 52 } 53 54 nodeoffset = fdt_find_or_add_subnode(working_fdt, 0, "chosen"); 55 if (nodeoffset < 0) { 56 printf("Reading chosen node failed\n"); 57 return CMD_RET_FAILURE; 58 } 59 60 ret = fdt_setprop(working_fdt, nodeoffset, "kaslr-seed", buf, sizeof(buf)); 61 if (ret < 0) { 62 printf("Unable to set kaslr-seed on chosen node: %s\n", fdt_strerror(ret)); 63 return CMD_RET_FAILURE; 64 } 65 66 free(buf); 67 68 return ret; 69} 70 71U_BOOT_LONGHELP(kaslrseed, 72 "[n]\n" 73 " - append random bytes to chosen kaslr-seed node\n"); 74 75U_BOOT_CMD( 76 kaslrseed, 1, 0, do_kaslr_seed, 77 "feed bytes from the hardware random number generator to the kaslr-seed", 78 kaslrseed_help_text 79); 80