From: Michael Brown Date: Thu, 11 Dec 2025 14:04:10 +0000 (+0000) Subject: [efi] Retry calls to GetRNG() as needed X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=86c40a8b1ef860c7c092226f95f9c8fe2d140edd;p=thirdparty%2Fipxe.git [efi] Retry calls to GetRNG() as needed The UEFI specification 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. Retry failed calls to GetRNG() up to a maximum number of attempts. Debugged-by: Stoo Davies Signed-off-by: Michael Brown --- diff --git a/src/interface/efi/efi_rng.c b/src/interface/efi/efi_rng.c index b76a6fc0d..058f0ee7d 100644 --- a/src/interface/efi/efi_rng.c +++ b/src/interface/efi/efi_rng.c @@ -54,6 +54,15 @@ EFI_REQUEST_PROTOCOL ( EFI_RNG_PROTOCOL, &efirng ); */ #define EFIRNG_LEN 32 +/** 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. + */ +#define EFIRNG_MAX_RETRY 16 + /** * Enable entropy gathering * @@ -85,29 +94,35 @@ static int efirng_enable ( void ) { */ static int efirng_get_noise ( noise_sample_t *noise ) { uint8_t buf[EFIRNG_LEN]; + unsigned int i; EFI_STATUS efirc; int rc; /* Sanity check */ assert ( efirng != NULL ); - /* Get the minimum allowed number of random bytes */ - if ( ( efirc = efirng->GetRNG ( efirng, NULL, sizeof ( buf ), - buf ) ) != 0 ) { - rc = -EEFI ( efirc ); - DBGC ( &efirng, "ENTROPY could not read from RNG: %s\n", - strerror ( rc ) ); - return rc; + /* Get random bytes, retrying if needed */ + for ( i = 0 ; i < EFIRNG_MAX_RETRY ; i++ ) { + + /* Get the minimum allowed number of random bytes */ + if ( ( efirc = efirng->GetRNG ( efirng, NULL, sizeof ( buf ), + buf ) ) != 0 ) { + rc = -EEFI ( efirc ); + continue; + } + + /* Reduce random bytes to a single noise sample. This + * seems like overkill, but we have no way of knowing + * how much entropy is actually present in the bytes + * returned by the RNG protocol. + */ + *noise = crc32_le ( 0, buf, sizeof ( buf ) ); + return 0; } - /* Reduce random bytes to a single noise sample. This seems - * like overkill, but we have no way of knowing how much - * entropy is actually present in the bytes returned by the - * RNG protocol. - */ - *noise = crc32_le ( 0, buf, sizeof ( buf ) ); - - return 0; + DBGC ( &efirng, "ENTROPY could not read from RNG: %s\n", + strerror ( rc ) ); + return rc; } /** EFI random number generator protocol entropy source */