efi/random: Increase size of firmware supplied randomness
authorArd Biesheuvel <ard.biesheuvel@linaro.org>
Fri, 25 Aug 2017 15:50:16 +0000 (16:50 +0100)
committerIngo Molnar <mingo@kernel.org>
Sat, 26 Aug 2017 07:20:33 +0000 (09:20 +0200)
The crng code requires at least 64 bytes (2 * CHACHA20_BLOCK_SIZE)
to complete the fast boot-time init, so provide that many bytes
when invoking UEFI protocols to seed the entropy pool. Also, add
a notice so we can tell from the boot log when the seeding actually
took place.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Matt Fleming <matt@codeblueprint.co.uk>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-efi@vger.kernel.org
Link: http://lkml.kernel.org/r/20170825155019.6740-3-ard.biesheuvel@linaro.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
drivers/firmware/efi/efi.c
drivers/firmware/efi/libstub/random.c
include/linux/efi.h

index a32e1460ade80e3c3c8606109110b0565e42ca87..c8a27a2c30c159dedcee472833d715febe9a056a 100644 (file)
@@ -541,6 +541,7 @@ int __init efi_config_parse_tables(void *config_tables, int count, int sz,
                        if (seed != NULL) {
                                add_device_randomness(seed->bits, seed->size);
                                early_memunmap(seed, sizeof(*seed) + size);
+                               pr_notice("seeding entropy pool\n");
                        } else {
                                pr_err("Could not map UEFI random seed!\n");
                        }
@@ -900,7 +901,7 @@ static int update_efi_random_seed(struct notifier_block *nb,
 
        seed = memremap(efi.rng_seed, sizeof(*seed), MEMREMAP_WB);
        if (seed != NULL) {
-               size = min(seed->size, 32U);
+               size = min(seed->size, EFI_RANDOM_SEED_SIZE);
                memunmap(seed);
        } else {
                pr_err("Could not map UEFI random seed!\n");
index 7e72954d58604f7b54a8e09d9d776ce034080b45..e0e603a89aa9fc5169478286668e9b9a7a37ca01 100644 (file)
@@ -145,8 +145,6 @@ 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;
@@ -162,25 +160,25 @@ efi_status_t efi_random_get_seed(efi_system_table_t *sys_table_arg)
                return status;
 
        status = efi_call_early(allocate_pool, EFI_RUNTIME_SERVICES_DATA,
-                               sizeof(*seed) + RANDOM_SEED_SIZE,
+                               sizeof(*seed) + EFI_RANDOM_SEED_SIZE,
                                (void **)&seed);
        if (status != EFI_SUCCESS)
                return status;
 
-       status = rng->get_rng(rng, &rng_algo_raw, RANDOM_SEED_SIZE,
+       status = rng->get_rng(rng, &rng_algo_raw, EFI_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,
+               status = rng->get_rng(rng, NULL, EFI_RANDOM_SEED_SIZE,
                                      seed->bits);
 
        if (status != EFI_SUCCESS)
                goto err_freepool;
 
-       seed->size = RANDOM_SEED_SIZE;
+       seed->size = EFI_RANDOM_SEED_SIZE;
        status = efi_call_early(install_configuration_table, &rng_table_guid,
                                seed);
        if (status != EFI_SUCCESS)
index c241acca0b15414bac9ce824d6638eb75f4fcda5..33d41df062bce250f2f8c227caab86ce1838508b 100644 (file)
@@ -1571,6 +1571,8 @@ efi_status_t efi_exit_boot_services(efi_system_table_t *sys_table,
                                    void *priv,
                                    efi_exit_boot_map_processing priv_func);
 
+#define EFI_RANDOM_SEED_SIZE           64U
+
 struct linux_efi_random_seed {
        u32     size;
        u8      bits[];