efi/arm*/libstub: Invoke EFI_RNG_PROTOCOL to seed the UEFI RNG table

Invoke the EFI_RNG_PROTOCOL protocol in the context of the stub and
install the Linux-specific RNG seed UEFI config table. This will be
picked up by the EFI routines in the core kernel to seed the kernel
entropy pool.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Matt Fleming <matt@codeblueprint.co.uk>
Reviewed-by: Kees Cook <keescook@chromium.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-efi@vger.kernel.org
Link: http://lkml.kernel.org/r/20161112213237.8804-6-matt@codeblueprint.co.uk
Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
Ard Biesheuvel 2016-11-12 21:32:33 +00:00 committed by Ingo Molnar
parent a6a144698d
commit 568bc4e870
4 changed files with 53 additions and 0 deletions

View file

@ -143,3 +143,51 @@ efi_status_t efi_random_alloc(efi_system_table_t *sys_table_arg,
return status;
}
#define RANDOM_SEED_SIZE 32
efi_status_t efi_random_get_seed(efi_system_table_t *sys_table_arg)
{
efi_guid_t rng_proto = EFI_RNG_PROTOCOL_GUID;
efi_guid_t rng_algo_raw = EFI_RNG_ALGORITHM_RAW;
efi_guid_t rng_table_guid = LINUX_EFI_RANDOM_SEED_TABLE_GUID;
struct efi_rng_protocol *rng;
struct linux_efi_random_seed *seed;
efi_status_t status;
status = efi_call_early(locate_protocol, &rng_proto, NULL,
(void **)&rng);
if (status != EFI_SUCCESS)
return status;
status = efi_call_early(allocate_pool, EFI_RUNTIME_SERVICES_DATA,
sizeof(*seed) + RANDOM_SEED_SIZE,
(void **)&seed);
if (status != EFI_SUCCESS)
return status;
status = rng->get_rng(rng, &rng_algo_raw, RANDOM_SEED_SIZE,
seed->bits);
if (status == EFI_UNSUPPORTED)
/*
* Use whatever algorithm we have available if the raw algorithm
* is not implemented.
*/
status = rng->get_rng(rng, NULL, RANDOM_SEED_SIZE,
seed->bits);
if (status != EFI_SUCCESS)
goto err_freepool;
seed->size = RANDOM_SEED_SIZE;
status = efi_call_early(install_configuration_table, &rng_table_guid,
seed);
if (status != EFI_SUCCESS)
goto err_freepool;
return EFI_SUCCESS;
err_freepool:
efi_call_early(free_pool, seed);
return status;
}