tree: https://git.kernel.org/pub/scm/linux/kernel/git/efi/efi.git next head: ff1f49b2ed7c150a69d1537a374c27e9db8acbb0 commit: 19c5678d5c1bad385a1beb8eaa00c9d50f4ce836 [2/3] efi/random: Increase size of firmware supplied randomness config: arm64-defconfig (attached as .config) compiler: aarch64-linux-gnu-gcc (Debian 6.1.1-9) 6.1.1 20160705 reproduce: wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross git checkout 19c5678d5c1bad385a1beb8eaa00c9d50f4ce836 # save the attached .config to linux build tree make.cross ARCH=arm64
All errors (new ones prefixed by >>):
In file included from drivers/firmware/efi/libstub/random.c:12:0:
drivers/firmware/efi/libstub/random.c: In function 'efi_random_get_seed':
>> drivers/firmware/efi/libstub/random.c:163:21: error: 'RANDOM_SEED_SIZE'
>> undeclared (first use in this function)
sizeof(*seed) + RANDOM_SEED_SIZE,
^
arch/arm64/include/asm/efi.h:73:60: note: in definition of macro
'efi_call_early'
#define efi_call_early(f, ...) sys_table_arg->boottime->f(__VA_ARGS__)
^~~~~~~~~~~
drivers/firmware/efi/libstub/random.c:163:21: note: each undeclared
identifier is reported only once for each function it appears in
sizeof(*seed) + RANDOM_SEED_SIZE,
^
arch/arm64/include/asm/efi.h:73:60: note: in definition of macro
'efi_call_early'
#define efi_call_early(f, ...) sys_table_arg->boottime->f(__VA_ARGS__)
^~~~~~~~~~~
vim +/RANDOM_SEED_SIZE +163 drivers/firmware/efi/libstub/random.c
e4fbf476 Ard Biesheuvel 2016-01-10 @12 #include <asm/efi.h>
e4fbf476 Ard Biesheuvel 2016-01-10 13
e4fbf476 Ard Biesheuvel 2016-01-10 14 #include "efistub.h"
e4fbf476 Ard Biesheuvel 2016-01-10 15
e4fbf476 Ard Biesheuvel 2016-01-10 16 struct efi_rng_protocol {
e4fbf476 Ard Biesheuvel 2016-01-10 17 efi_status_t (*get_info)(struct
efi_rng_protocol *,
e4fbf476 Ard Biesheuvel 2016-01-10 18
unsigned long *, efi_guid_t *);
e4fbf476 Ard Biesheuvel 2016-01-10 19 efi_status_t (*get_rng)(struct
efi_rng_protocol *,
e4fbf476 Ard Biesheuvel 2016-01-10 20
efi_guid_t *, unsigned long, u8 *out);
e4fbf476 Ard Biesheuvel 2016-01-10 21 };
e4fbf476 Ard Biesheuvel 2016-01-10 22
e4fbf476 Ard Biesheuvel 2016-01-10 23 efi_status_t
efi_get_random_bytes(efi_system_table_t *sys_table_arg,
e4fbf476 Ard Biesheuvel 2016-01-10 24
unsigned long size, u8 *out)
e4fbf476 Ard Biesheuvel 2016-01-10 25 {
e4fbf476 Ard Biesheuvel 2016-01-10 26 efi_guid_t rng_proto =
EFI_RNG_PROTOCOL_GUID;
e4fbf476 Ard Biesheuvel 2016-01-10 27 efi_status_t status;
e4fbf476 Ard Biesheuvel 2016-01-10 28 struct efi_rng_protocol *rng;
e4fbf476 Ard Biesheuvel 2016-01-10 29
e4fbf476 Ard Biesheuvel 2016-01-10 30 status =
efi_call_early(locate_protocol, &rng_proto, NULL,
e4fbf476 Ard Biesheuvel 2016-01-10 31 (void
**)&rng);
e4fbf476 Ard Biesheuvel 2016-01-10 32 if (status != EFI_SUCCESS)
e4fbf476 Ard Biesheuvel 2016-01-10 33 return status;
e4fbf476 Ard Biesheuvel 2016-01-10 34
e4fbf476 Ard Biesheuvel 2016-01-10 35 return rng->get_rng(rng, NULL,
size, out);
e4fbf476 Ard Biesheuvel 2016-01-10 36 }
2ddbfc81 Ard Biesheuvel 2016-01-11 37
2ddbfc81 Ard Biesheuvel 2016-01-11 38 /*
2ddbfc81 Ard Biesheuvel 2016-01-11 39 * Return the number of slots covered
by this entry, i.e., the number of
2ddbfc81 Ard Biesheuvel 2016-01-11 40 * addresses it covers that are
suitably aligned and supply enough room
2ddbfc81 Ard Biesheuvel 2016-01-11 41 * for the allocation.
2ddbfc81 Ard Biesheuvel 2016-01-11 42 */
2ddbfc81 Ard Biesheuvel 2016-01-11 43 static unsigned long
get_entry_num_slots(efi_memory_desc_t *md,
2ddbfc81 Ard Biesheuvel 2016-01-11 44
unsigned long size,
a6a14469 Ard Biesheuvel 2016-11-12 45
unsigned long align_shift)
2ddbfc81 Ard Biesheuvel 2016-01-11 46 {
a6a14469 Ard Biesheuvel 2016-11-12 47 unsigned long align = 1UL <<
align_shift;
018edcfa Ard Biesheuvel 2016-11-24 48 u64 first_slot, last_slot,
region_end;
2ddbfc81 Ard Biesheuvel 2016-01-11 49
2ddbfc81 Ard Biesheuvel 2016-01-11 50 if (md->type !=
EFI_CONVENTIONAL_MEMORY)
2ddbfc81 Ard Biesheuvel 2016-01-11 51 return 0;
2ddbfc81 Ard Biesheuvel 2016-01-11 52
018edcfa Ard Biesheuvel 2016-11-24 53 region_end =
min((u64)ULONG_MAX, md->phys_addr + md->num_pages*EFI_PAGE_SIZE - 1);
2ddbfc81 Ard Biesheuvel 2016-01-11 54
018edcfa Ard Biesheuvel 2016-11-24 55 first_slot =
round_up(md->phys_addr, align);
018edcfa Ard Biesheuvel 2016-11-24 56 last_slot =
round_down(region_end - size + 1, align);
018edcfa Ard Biesheuvel 2016-11-24 57
018edcfa Ard Biesheuvel 2016-11-24 58 if (first_slot > last_slot)
2ddbfc81 Ard Biesheuvel 2016-01-11 59 return 0;
2ddbfc81 Ard Biesheuvel 2016-01-11 60
018edcfa Ard Biesheuvel 2016-11-24 61 return ((unsigned
long)(last_slot - first_slot) >> align_shift) + 1;
2ddbfc81 Ard Biesheuvel 2016-01-11 62 }
2ddbfc81 Ard Biesheuvel 2016-01-11 63
2ddbfc81 Ard Biesheuvel 2016-01-11 64 /*
2ddbfc81 Ard Biesheuvel 2016-01-11 65 * The UEFI memory descriptors have a
virtual address field that is only used
2ddbfc81 Ard Biesheuvel 2016-01-11 66 * when installing the virtual mapping
using SetVirtualAddressMap(). Since it
2ddbfc81 Ard Biesheuvel 2016-01-11 67 * is unused here, we can reuse it to
keep track of each descriptor's slot
2ddbfc81 Ard Biesheuvel 2016-01-11 68 * count.
2ddbfc81 Ard Biesheuvel 2016-01-11 69 */
2ddbfc81 Ard Biesheuvel 2016-01-11 70 #define MD_NUM_SLOTS(md)
((md)->virt_addr)
2ddbfc81 Ard Biesheuvel 2016-01-11 71
2ddbfc81 Ard Biesheuvel 2016-01-11 72 efi_status_t
efi_random_alloc(efi_system_table_t *sys_table_arg,
2ddbfc81 Ard Biesheuvel 2016-01-11 73 unsigned
long size,
2ddbfc81 Ard Biesheuvel 2016-01-11 74 unsigned
long align,
2ddbfc81 Ard Biesheuvel 2016-01-11 75 unsigned
long *addr,
2ddbfc81 Ard Biesheuvel 2016-01-11 76 unsigned
long random_seed)
2ddbfc81 Ard Biesheuvel 2016-01-11 77 {
2ddbfc81 Ard Biesheuvel 2016-01-11 78 unsigned long map_size,
desc_size, total_slots = 0, target_slot;
dadb57ab Jeffrey Hugo 2016-08-29 79 unsigned long buff_size;
2ddbfc81 Ard Biesheuvel 2016-01-11 80 efi_status_t status;
2ddbfc81 Ard Biesheuvel 2016-01-11 81 efi_memory_desc_t *memory_map;
2ddbfc81 Ard Biesheuvel 2016-01-11 82 int map_offset;
dadb57ab Jeffrey Hugo 2016-08-29 83 struct efi_boot_memmap map;
2ddbfc81 Ard Biesheuvel 2016-01-11 84
dadb57ab Jeffrey Hugo 2016-08-29 85 map.map = &memory_map;
dadb57ab Jeffrey Hugo 2016-08-29 86 map.map_size = &map_size;
dadb57ab Jeffrey Hugo 2016-08-29 87 map.desc_size = &desc_size;
dadb57ab Jeffrey Hugo 2016-08-29 88 map.desc_ver = NULL;
dadb57ab Jeffrey Hugo 2016-08-29 89 map.key_ptr = NULL;
dadb57ab Jeffrey Hugo 2016-08-29 90 map.buff_size = &buff_size;
dadb57ab Jeffrey Hugo 2016-08-29 91
dadb57ab Jeffrey Hugo 2016-08-29 92 status =
efi_get_memory_map(sys_table_arg, &map);
2ddbfc81 Ard Biesheuvel 2016-01-11 93 if (status != EFI_SUCCESS)
2ddbfc81 Ard Biesheuvel 2016-01-11 94 return status;
2ddbfc81 Ard Biesheuvel 2016-01-11 95
2ddbfc81 Ard Biesheuvel 2016-01-11 96 if (align < EFI_ALLOC_ALIGN)
2ddbfc81 Ard Biesheuvel 2016-01-11 97 align = EFI_ALLOC_ALIGN;
2ddbfc81 Ard Biesheuvel 2016-01-11 98
2ddbfc81 Ard Biesheuvel 2016-01-11 99 /* count the suitable slots in
each memory map entry */
2ddbfc81 Ard Biesheuvel 2016-01-11 100 for (map_offset = 0; map_offset
< map_size; map_offset += desc_size) {
2ddbfc81 Ard Biesheuvel 2016-01-11 101 efi_memory_desc_t *md =
(void *)memory_map + map_offset;
2ddbfc81 Ard Biesheuvel 2016-01-11 102 unsigned long slots;
2ddbfc81 Ard Biesheuvel 2016-01-11 103
a6a14469 Ard Biesheuvel 2016-11-12 104 slots =
get_entry_num_slots(md, size, ilog2(align));
2ddbfc81 Ard Biesheuvel 2016-01-11 105 MD_NUM_SLOTS(md) =
slots;
2ddbfc81 Ard Biesheuvel 2016-01-11 106 total_slots += slots;
2ddbfc81 Ard Biesheuvel 2016-01-11 107 }
2ddbfc81 Ard Biesheuvel 2016-01-11 108
2ddbfc81 Ard Biesheuvel 2016-01-11 109 /* find a random number between
0 and total_slots */
2ddbfc81 Ard Biesheuvel 2016-01-11 110 target_slot = (total_slots *
(u16)random_seed) >> 16;
2ddbfc81 Ard Biesheuvel 2016-01-11 111
2ddbfc81 Ard Biesheuvel 2016-01-11 112 /*
2ddbfc81 Ard Biesheuvel 2016-01-11 113 * target_slot is now a value
in the range [0, total_slots), and so
2ddbfc81 Ard Biesheuvel 2016-01-11 114 * it corresponds with exactly
one of the suitable slots we recorded
2ddbfc81 Ard Biesheuvel 2016-01-11 115 * when iterating over the
memory map the first time around.
2ddbfc81 Ard Biesheuvel 2016-01-11 116 *
2ddbfc81 Ard Biesheuvel 2016-01-11 117 * So iterate over the memory
map again, subtracting the number of
2ddbfc81 Ard Biesheuvel 2016-01-11 118 * slots of each entry at each
iteration, until we have found the entry
2ddbfc81 Ard Biesheuvel 2016-01-11 119 * that covers our chosen slot.
Use the residual value of target_slot
2ddbfc81 Ard Biesheuvel 2016-01-11 120 * to calculate the randomly
chosen address, and allocate it directly
2ddbfc81 Ard Biesheuvel 2016-01-11 121 * using EFI_ALLOCATE_ADDRESS.
2ddbfc81 Ard Biesheuvel 2016-01-11 122 */
2ddbfc81 Ard Biesheuvel 2016-01-11 123 for (map_offset = 0; map_offset
< map_size; map_offset += desc_size) {
2ddbfc81 Ard Biesheuvel 2016-01-11 124 efi_memory_desc_t *md =
(void *)memory_map + map_offset;
2ddbfc81 Ard Biesheuvel 2016-01-11 125 efi_physical_addr_t
target;
2ddbfc81 Ard Biesheuvel 2016-01-11 126 unsigned long pages;
2ddbfc81 Ard Biesheuvel 2016-01-11 127
2ddbfc81 Ard Biesheuvel 2016-01-11 128 if (target_slot >=
MD_NUM_SLOTS(md)) {
2ddbfc81 Ard Biesheuvel 2016-01-11 129 target_slot -=
MD_NUM_SLOTS(md);
2ddbfc81 Ard Biesheuvel 2016-01-11 130 continue;
2ddbfc81 Ard Biesheuvel 2016-01-11 131 }
2ddbfc81 Ard Biesheuvel 2016-01-11 132
2ddbfc81 Ard Biesheuvel 2016-01-11 133 target =
round_up(md->phys_addr, align) + target_slot * align;
2ddbfc81 Ard Biesheuvel 2016-01-11 134 pages = round_up(size,
EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
2ddbfc81 Ard Biesheuvel 2016-01-11 135
2ddbfc81 Ard Biesheuvel 2016-01-11 136 status =
efi_call_early(allocate_pages, EFI_ALLOCATE_ADDRESS,
2ddbfc81 Ard Biesheuvel 2016-01-11 137
EFI_LOADER_DATA, pages, &target);
2ddbfc81 Ard Biesheuvel 2016-01-11 138 if (status ==
EFI_SUCCESS)
2ddbfc81 Ard Biesheuvel 2016-01-11 139 *addr = target;
2ddbfc81 Ard Biesheuvel 2016-01-11 140 break;
2ddbfc81 Ard Biesheuvel 2016-01-11 141 }
2ddbfc81 Ard Biesheuvel 2016-01-11 142
2ddbfc81 Ard Biesheuvel 2016-01-11 143 efi_call_early(free_pool,
memory_map);
2ddbfc81 Ard Biesheuvel 2016-01-11 144
2ddbfc81 Ard Biesheuvel 2016-01-11 145 return status;
2ddbfc81 Ard Biesheuvel 2016-01-11 146 }
568bc4e8 Ard Biesheuvel 2016-11-12 147
568bc4e8 Ard Biesheuvel 2016-11-12 148 efi_status_t
efi_random_get_seed(efi_system_table_t *sys_table_arg)
568bc4e8 Ard Biesheuvel 2016-11-12 149 {
568bc4e8 Ard Biesheuvel 2016-11-12 150 efi_guid_t rng_proto =
EFI_RNG_PROTOCOL_GUID;
568bc4e8 Ard Biesheuvel 2016-11-12 151 efi_guid_t rng_algo_raw =
EFI_RNG_ALGORITHM_RAW;
568bc4e8 Ard Biesheuvel 2016-11-12 152 efi_guid_t rng_table_guid =
LINUX_EFI_RANDOM_SEED_TABLE_GUID;
568bc4e8 Ard Biesheuvel 2016-11-12 153 struct efi_rng_protocol *rng;
568bc4e8 Ard Biesheuvel 2016-11-12 154 struct linux_efi_random_seed
*seed;
568bc4e8 Ard Biesheuvel 2016-11-12 155 efi_status_t status;
568bc4e8 Ard Biesheuvel 2016-11-12 156
568bc4e8 Ard Biesheuvel 2016-11-12 157 status =
efi_call_early(locate_protocol, &rng_proto, NULL,
568bc4e8 Ard Biesheuvel 2016-11-12 158 (void
**)&rng);
568bc4e8 Ard Biesheuvel 2016-11-12 159 if (status != EFI_SUCCESS)
568bc4e8 Ard Biesheuvel 2016-11-12 160 return status;
568bc4e8 Ard Biesheuvel 2016-11-12 161
568bc4e8 Ard Biesheuvel 2016-11-12 162 status =
efi_call_early(allocate_pool, EFI_RUNTIME_SERVICES_DATA,
568bc4e8 Ard Biesheuvel 2016-11-12 @163
sizeof(*seed) + RANDOM_SEED_SIZE,
:::::: The code at line 163 was first introduced by commit
:::::: 568bc4e87033d232c5fd00d5b0cd22a2ccc04944 efi/arm*/libstub: Invoke
EFI_RNG_PROTOCOL to seed the UEFI RNG table
:::::: TO: Ard Biesheuvel <[email protected]>
:::::: CC: Ingo Molnar <[email protected]>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
.config.gz
Description: application/gzip
