diff --git a/stand/efi/loader/main.c b/stand/efi/loader/main.c --- a/stand/efi/loader/main.c +++ b/stand/efi/loader/main.c @@ -56,6 +56,8 @@ #include #include +#include + #include "efizfs.h" #include "framebuffer.h" @@ -1249,11 +1251,17 @@ { EFI_STATUS status; EFI_RNG_PROTOCOL *rng; + unsigned int size_efi = 2048; unsigned int size = 2048; + void *buf_efi; void *buf; if (argc > 1) { - size = strtol(argv[1], NULL, 0); + size_efi = strtol(argv[1], NULL, 0); + if (size_efi > size) + size = size_efi; + if (size_efi < 64) + size = size_efi; } status = BS->LocateProtocol(&rng_guid, NULL, (VOID **)&rng); @@ -1267,20 +1275,33 @@ return (CMD_ERROR); } + if ((buf_efi = malloc(size_efi)) == NULL) { + command_errmsg = "out of memory"; + return (CMD_ERROR); + } + TSENTER2("rng->GetRNG"); - status = rng->GetRNG(rng, NULL, size, (UINT8 *)buf); + status = rng->GetRNG(rng, NULL, size_efi, (UINT8 *)buf_efi); TSEXIT(); if (status != EFI_SUCCESS) { + free(buf_efi); free(buf); command_errmsg = "GetRNG failed"; return (CMD_ERROR); } + if (size_efi < size) + pkcs5v2_genkey_raw(buf, size, "", 0, buf_efi, size_efi, 1); + else + memcpy(buf, buf_efi, size); if (file_addbuf("efi_rng_seed", "boot_entropy_platform", size, buf) != 0) { + free(buf_efi); free(buf); return (CMD_ERROR); } + explicit_bzero(buf_efi, size_efi); + free(buf_efi); free(buf); return (CMD_OK); }