iPXE
efi_rng.c File Reference

EFI random number generator protocol entropy source. More...

#include <errno.h>
#include <ipxe/entropy.h>
#include <ipxe/crc32.h>
#include <ipxe/efi/efi.h>
#include <ipxe/efi/Protocol/Rng.h>

Go to the source code of this file.

Macros

#define EFIRNG_LEN   32
 Minimum number of bytes to request from RNG.
#define EFIRNG_MAX_RETRY   16
 Maximum number of times to attempting requesting data from RNG.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
struct entropy_source efirng_entropy __entropy_source (ENTROPY_NORMAL)
 EFI random number generator protocol entropy source.
 EFI_REQUEST_PROTOCOL (EFI_RNG_PROTOCOL, &efirng)
static int efirng_enable (void)
 Enable entropy gathering.
static int efirng_get_noise (noise_sample_t *noise)
 Get noise sample from RNG protocol.

Variables

static EFI_RNG_PROTOCOLefirng
 Random number generator protocol.

Detailed Description

EFI random number generator protocol entropy source.

Definition in file efi_rng.c.

Macro Definition Documentation

◆ EFIRNG_LEN

#define EFIRNG_LEN   32

Minimum number of bytes to request from RNG.

The UEFI spec states (for no apparently good reason) that "When a Deterministic Random Bit Generator (DRBG) is used on the output of a (raw) entropy source, its security level must be at least 256 bits." The EDK2 codebase (mis)interprets this to mean that the call to GetRNG() should fail if given a buffer less than 32 bytes.

Incidentally, nothing in the EFI RNG protocol provides any way to report the actual amount of entropy returned by GetRNG().

Definition at line 56 of file efi_rng.c.

Referenced by efirng_get_noise().

◆ EFIRNG_MAX_RETRY

#define EFIRNG_MAX_RETRY   16

Maximum number of times to attempting requesting data from RNG.

The UEFI spec allows GetRNG() to return EFI_NOT_READY, which is not a particularly helpful error status since there is nothing that can sensibly be done except to retry immediately. We retry failed calls to GetRNG() (for any reason) up to this number of times.

Definition at line 65 of file efi_rng.c.

Referenced by efirng_get_noise().

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ __entropy_source()

struct entropy_source rtc_entropy __entropy_source ( ENTROPY_NORMAL )
Initial value:
= {
.name = "efirng",
.enable = efirng_enable,
.get_noise = efirng_get_noise,
}
static int efirng_enable(void)
Enable entropy gathering.
Definition efi_rng.c:72
static int efirng_get_noise(noise_sample_t *noise)
Get noise sample from RNG protocol.
Definition efi_rng.c:96

EFI random number generator protocol entropy source.

RTC entropy source.

References __entropy_source, and ENTROPY_NORMAL.

◆ EFI_REQUEST_PROTOCOL()

EFI_REQUEST_PROTOCOL ( EFI_RNG_PROTOCOL ,
& efirng )

References efirng.

◆ efirng_enable()

int efirng_enable ( void )
static

Enable entropy gathering.

Return values
rcReturn status code

Definition at line 72 of file efi_rng.c.

72 {
73
74 /* Check for RNG protocol support */
75 if ( ! efirng ) {
76 DBGC ( &efirng, "EFIRNG has no RNG protocol\n" );
77 return -ENOTSUP;
78 }
79
80 /* Nothing in the EFI specification provides any clue as to
81 * how much entropy will be returned by GetRNG(). Make a
82 * totally uninformed (and conservative guess) that each
83 * sample will contain at least one bit of entropy.
84 */
85 entropy_init ( &efirng_entropy, MIN_ENTROPY ( 1.0 ) );
86
87 return 0;
88}
static EFI_RNG_PROTOCOL * efirng
Random number generator protocol.
Definition efi_rng.c:42
#define DBGC(...)
Definition compiler.h:505
#define ENOTSUP
Operation not supported.
Definition errno.h:590
static void entropy_init(struct entropy_source *source, min_entropy_t min_entropy_per_sample)
Initialise entropy source.
Definition entropy.h:490
#define MIN_ENTROPY(bits)
Construct a min-entropy fixed-point value.
Definition entropy.h:43

References DBGC, efirng, ENOTSUP, entropy_init(), and MIN_ENTROPY.

◆ efirng_get_noise()

int efirng_get_noise ( noise_sample_t * noise)
static

Get noise sample from RNG protocol.

Return values
noiseNoise sample
rcReturn status code

Definition at line 96 of file efi_rng.c.

96 {
98 unsigned int i;
99 EFI_STATUS efirc;
100 int rc;
101
102 /* Sanity check */
103 assert ( efirng != NULL );
104
105 /* Get random bytes, retrying if needed */
106 for ( i = 0 ; i < EFIRNG_MAX_RETRY ; i++ ) {
107
108 /* Get the minimum allowed number of random bytes */
109 if ( ( efirc = efirng->GetRNG ( efirng, NULL, sizeof ( buf ),
110 buf ) ) != 0 ) {
111 rc = -EEFI ( efirc );
112 continue;
113 }
114
115 /* Reduce random bytes to a single noise sample. This
116 * seems like overkill, but we have no way of knowing
117 * how much entropy is actually present in the bytes
118 * returned by the RNG protocol.
119 */
120 *noise = crc32_le ( 0, buf, sizeof ( buf ) );
121 return 0;
122 }
123
124 DBGC ( &efirng, "ENTROPY could not read from RNG: %s\n",
125 strerror ( rc ) );
126 return rc;
127}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
unsigned char uint8_t
Definition stdint.h:10
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
u32 crc32_le(u32 seed, const void *data, size_t len)
Calculate 32-bit little-endian CRC checksum.
Definition crc32.c:40
#define EFIRNG_LEN
Minimum number of bytes to request from RNG.
Definition efi_rng.c:56
#define EFIRNG_MAX_RETRY
Maximum number of times to attempting requesting data from RNG.
Definition efi_rng.c:65
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition efi.h:175
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79

References assert, crc32_le(), DBGC, EEFI, efirng, EFIRNG_LEN, EFIRNG_MAX_RETRY, NULL, rc, and strerror().

Variable Documentation

◆ efirng

EFI_RNG_PROTOCOL* efirng
static

Random number generator protocol.

Definition at line 42 of file efi_rng.c.

Referenced by EFI_REQUEST_PROTOCOL(), efirng_enable(), and efirng_get_noise().