Index: stand/defaults/loader.conf =================================================================== --- stand/defaults/loader.conf +++ stand/defaults/loader.conf @@ -48,6 +48,10 @@ # the boot-time entropy cache. This # must not change value even if the # _name above does change! +entropy_efi_rng="NO" # Set this to YES to enable loading + # entropy from the UEFI random number generator API + # (note: the kernel only supports one entropy file, so + # you have to disable entropy_cache_load) ### RAM Blacklist configuration ############################ ram_blacklist_load="NO" # Set this to YES to load a file Index: stand/efi/include/efirng.h =================================================================== --- /dev/null +++ stand/efi/include/efirng.h @@ -0,0 +1,35 @@ +#ifndef _EFIRNG_H +#define _EFIRNG_H + +#define EFI_RNG_PROTOCOL_GUID \ + { 0x3152bca5, 0xeade, 0x433d, {0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44} } + +INTERFACE_DECL(_EFI_RNG_PROTOCOL); + +typedef EFI_GUID EFI_RNG_ALGORITHM; + +typedef +EFI_STATUS +(EFIAPI *EFI_RNG_GET_INFO) ( + IN struct _EFI_RNG_PROTOCOL *This, + IN OUT UINTN *RNGAlgorithmListSize, + OUT EFI_RNG_ALGORITHM *RNGAlgorithmList + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_RNG_GET_RNG) ( + IN struct _EFI_RNG_PROTOCOL *This, + IN EFI_RNG_ALGORITHM *RNGAlgorithm, OPTIONAL + IN UINTN RNGValueLength, + OUT UINT8 *RNGValue + ); + +typedef struct _EFI_RNG_PROTOCOL { + EFI_RNG_GET_INFO GetInfo; + EFI_RNG_GET_RNG GetRNG; +} EFI_RNG_PROTOCOL; + +static EFI_GUID rng_guid = EFI_RNG_PROTOCOL_GUID; + +#endif /* _EFIRNG_H */ Index: stand/efi/loader/main.c =================================================================== --- stand/efi/loader/main.c +++ stand/efi/loader/main.c @@ -52,6 +52,7 @@ #include #include #include +#include #include @@ -1206,6 +1207,47 @@ return (EFI_SUCCESS); /* keep compiler happy */ } +COMMAND_SET(efi_seed_entropy, "efi-seed-entropy", "try to get entropy from the EFI RNG", command_seed_entropy); + +static int +command_seed_entropy(int argc, char *argv[]) +{ + EFI_STATUS status; + EFI_RNG_PROTOCOL *rng; + unsigned int size = 2048; + void *buf; + + if (argc > 1) { + size = strtol(argv[1], NULL, 0); + } + + status = BS->LocateProtocol(&rng_guid, NULL, (VOID **)&rng); + if (status != EFI_SUCCESS) { + command_errmsg = "RNG protocol not found"; + return (CMD_ERROR); + } + + if ((buf = malloc(size)) == NULL) { + command_errmsg = "out of memory"; + return (CMD_ERROR); + } + + status = rng->GetRNG(rng, NULL, size, (UINT8 *)buf); + if (status != EFI_SUCCESS) { + free(buf); + command_errmsg = "GetRNG failed"; + return (CMD_ERROR); + } + + if (file_addbuf("efi_rng_seed", "boot_entropy_cache", size, buf) != 0) { + free(buf); + return (CMD_ERROR); + } + + free(buf); + return (CMD_OK); +} + COMMAND_SET(poweroff, "poweroff", "power off the system", command_poweroff); static int Index: stand/lua/config.lua =================================================================== --- stand/lua/config.lua +++ stand/lua/config.lua @@ -728,6 +728,13 @@ hook.runAll("config.reloaded") end +local function loadEntropy() + if loader.getenv("entropy_efi_rng"):lower() == "yes" then + loader.perform("efi-seed-entropy") + end + return true +end + function config.loadelf() local xen_kernel = loader.getenv('xen_kernel') local kernel = config.kernel_selected or config.kernel_loaded @@ -747,7 +754,7 @@ hook.runAll("kernel.loaded") print(MSG_MODLOADING) - status = loadModule(modules, not config.verbose) + status = loadModule(modules, not config.verbose) and loadEntropy() hook.runAll("modules.loaded") return status end