xref: /openbsd/sys/arch/amd64/stand/efiboot/efirng.c (revision 147ac6c2)
1 /*	$OpenBSD: efirng.c,v 1.3 2021/06/07 00:04:20 krw Exp $	*/
2 
3 /*
4  * Copyright (c) 2018 Mark Kettenis <kettenis@openbsd.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/param.h>
20 
21 #include <efi.h>
22 #include <efiapi.h>
23 
24 #include "libsa.h"
25 
26 extern EFI_BOOT_SERVICES	*BS;
27 
28 /* Random Number Generator Protocol */
29 
30 #define EFI_RNG_PROTOCOL_GUID \
31     { 0x3152bca5, 0xeade, 0x433d, {0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44} }
32 
33 INTERFACE_DECL(_EFI_RNG_PROTOCOL);
34 
35 typedef EFI_GUID EFI_RNG_ALGORITHM;
36 
37 typedef
38 EFI_STATUS
39 (EFIAPI *EFI_RNG_GET_INFO) (
40     IN struct _EFI_RNG_PROTOCOL		*This,
41     IN  OUT UINTN			*RNGAlgorithmListSize,
42     OUT EFI_RNG_ALGORITHM		*RNGAlgorithmList
43     );
44 
45 typedef
46 EFI_STATUS
47 (EFIAPI *EFI_RNG_GET_RNG) (
48     IN struct _EFI_RNG_PROTOCOL		*This,
49     IN EFI_RNG_ALGORITHM		*RNGAlgorithm, OPTIONAL
50     IN UINTN				RNGValueLength,
51     OUT UINT8				*RNGValue
52     );
53 
54 typedef struct _EFI_RNG_PROTOCOL {
55 	EFI_RNG_GET_INFO	GetInfo;
56 	EFI_RNG_GET_RNG		GetRNG;
57 } EFI_RNG_PROTOCOL;
58 
59 static EFI_GUID			rng_guid = EFI_RNG_PROTOCOL_GUID;
60 
61 int
fwrandom(char * buf,size_t buflen)62 fwrandom(char *buf, size_t buflen)
63 {
64 	EFI_STATUS		 status;
65 	EFI_RNG_PROTOCOL	*rng = NULL;
66 	UINT8			*random;
67 	size_t			 i;
68 	int			 ret = 0;
69 
70 	status = BS->LocateProtocol(&rng_guid, NULL, (void **)&rng);
71 	if (rng == NULL || EFI_ERROR(status))
72 		return -1;
73 
74 	random = alloc(buflen);
75 
76 	status = rng->GetRNG(rng, NULL, buflen, random);
77 	if (EFI_ERROR(status)) {
78 		printf("RNG GetRNG() failed (%d)\n", status);
79 		ret = -1;
80 		goto out;
81 	}
82 
83 	for (i = 0; i < buflen; i++)
84 		buf[i] ^= random[i];
85 
86 out:
87 	free(random, buflen);
88 	return ret;
89 }
90