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