xref: /DragonStub/apps/random.c (revision 823f04931913f01ee1fc0dc0c7876156ad150388)
1 #include <dragonstub/dragonstub.h>
2 
3 
4 typedef union efi_rng_protocol efi_rng_protocol_t;
5 
6 union efi_rng_protocol {
7 	struct {
8 		efi_status_t (__efiapi *get_info)(efi_rng_protocol_t *,
9 						  unsigned long *,
10 						  efi_guid_t *);
11 		efi_status_t (__efiapi *get_rng)(efi_rng_protocol_t *,
12 						 efi_guid_t *, unsigned long,
13 						 u8 *out);
14 	};
15 	struct {
16 		u32 get_info;
17 		u32 get_rng;
18 	} mixed_mode;
19 };
20 
21 /**
22  * efi_get_random_bytes() - fill a buffer with random bytes
23  * @size:	size of the buffer
24  * @out:	caller allocated buffer to receive the random bytes
25  *
26  * The call will fail if either the firmware does not implement the
27  * EFI_RNG_PROTOCOL or there are not enough random bytes available to fill
28  * the buffer.
29  *
30  * Return:	status code
31  */
efi_get_random_bytes(unsigned long size,u8 * out)32 efi_status_t efi_get_random_bytes(unsigned long size, u8 *out)
33 {
34 	efi_guid_t rng_proto = EFI_RNG_PROTOCOL_GUID;
35 	efi_status_t status;
36 	efi_rng_protocol_t *rng = NULL;
37 
38 	status = efi_bs_call(LocateProtocol, &rng_proto, NULL, (void **)&rng);
39 	if (status != EFI_SUCCESS)
40 		return status;
41 
42 	return efi_call_proto(rng, get_rng, NULL, size, out);
43 }