Index: stand/common/bootstrap.h =================================================================== --- stand/common/bootstrap.h +++ stand/common/bootstrap.h @@ -234,6 +234,9 @@ int mod_loadkld(const char *name, int argc, char *argv[]); void unload(void); +vm_offset_t mod_loadraw_start(char *name); +struct preloaded_file *mod_loadraw_finish(vm_offset_t laddr, char *name, char *type, int insert); + struct preloaded_file *file_alloc(void); struct preloaded_file *file_findfile(const char *name, const char *type); struct file_metadata *file_findmetadata(struct preloaded_file *fp, int type); Index: stand/common/module.c =================================================================== --- stand/common/module.c +++ stand/common/module.c @@ -658,12 +658,8 @@ } #endif - if (archsw.arch_loadaddr != NULL) - loadaddr = archsw.arch_loadaddr(LOAD_RAW, name, loadaddr); + laddr = mod_loadraw_start(name); - printf("%s ", name); - - laddr = loadaddr; for (;;) { /* read in 4k chunks; size is not really important */ got = archsw.arch_readin(fd, laddr, 4096); @@ -679,6 +675,28 @@ laddr += got; } + fp = mod_loadraw_finish(laddr, name, type, insert); + close(fd); + + return (fp); +} + +vm_offset_t +mod_loadraw_start(char *name) +{ + if (archsw.arch_loadaddr != NULL) + loadaddr = archsw.arch_loadaddr(LOAD_RAW, name, loadaddr); + + printf("%s ", name); + + return (loadaddr); +} + +struct preloaded_file * +mod_loadraw_finish(vm_offset_t laddr, char *name, char *type, int insert) +{ + struct preloaded_file *fp; + printf("size=%#jx\n", (uintmax_t)(laddr - loadaddr)); /* Looks OK so far; create & populate control structure */ @@ -687,7 +705,6 @@ snprintf(command_errbuf, sizeof (command_errbuf), "no memory to load %s", name); free(name); - close(fd); return (NULL); } fp->f_name = name; @@ -702,7 +719,6 @@ snprintf(command_errbuf, sizeof (command_errbuf), "no memory to load %s", name); free(name); - close(fd); return (NULL); } /* recognise space consumption */ @@ -711,8 +727,8 @@ /* Add to the list of loaded files */ if (insert != 0) file_insert_tail(fp); - close(fd); - return(fp); + + return (fp); } /* Index: stand/defaults/loader.conf =================================================================== --- stand/defaults/loader.conf +++ stand/defaults/loader.conf @@ -43,6 +43,9 @@ # the boot-time entropy cache. This # must not change value even if the # _name above does change! +entropy_prefer_efi="YES" # Set this to NO to disable usage of the + # UEFI RNG instead of loading the + # entropy cache from disk ### 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,37 @@ +/* $FreeBSD$ */ + +#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 @@ -45,6 +45,7 @@ #include #include #include +#include #include @@ -1123,6 +1124,45 @@ 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; + vm_offset_t laddr; + unsigned int size = 2048; + + 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); + } + + /* We can't load first */ + if ((file_findfile(NULL, NULL)) == NULL) { + command_errmsg = "can't load file before kernel"; + return (CMD_ERROR); + } + + laddr = mod_loadraw_start("efi_rng_seed"); + + status = rng->GetRNG(rng, NULL, size, (UINT8 *)efi_translate(laddr)); + if (status != EFI_SUCCESS) { + command_errmsg = "GetRNG failed"; + return (CMD_ERROR); + } + + laddr += size; + mod_loadraw_finish(laddr, "efi_rng_seed", "boot_entropy_cache", 1); + 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 @@ -290,6 +290,13 @@ end goto continue end + if v.type == "boot_entropy_cache" and + loader.getenv("entropy_prefer_efi"):lower() == "yes" then + local r = loader.perform("efi-seed-entropy") + if r == 0 then + goto continue + end + end if not silent then loader.printc(module_name .. "...") end