mirror of
https://github.com/ipxe/ipxe
synced 2026-02-14 02:31:26 +03:00
[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 <sdavies@nvidia.com> Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -54,6 +54,15 @@ EFI_REQUEST_PROTOCOL ( EFI_RNG_PROTOCOL, &efirng );
|
|||||||
*/
|
*/
|
||||||
#define EFIRNG_LEN 32
|
#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
|
* Enable entropy gathering
|
||||||
*
|
*
|
||||||
@@ -85,29 +94,35 @@ static int efirng_enable ( void ) {
|
|||||||
*/
|
*/
|
||||||
static int efirng_get_noise ( noise_sample_t *noise ) {
|
static int efirng_get_noise ( noise_sample_t *noise ) {
|
||||||
uint8_t buf[EFIRNG_LEN];
|
uint8_t buf[EFIRNG_LEN];
|
||||||
|
unsigned int i;
|
||||||
EFI_STATUS efirc;
|
EFI_STATUS efirc;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* Sanity check */
|
/* Sanity check */
|
||||||
assert ( efirng != NULL );
|
assert ( efirng != NULL );
|
||||||
|
|
||||||
/* Get the minimum allowed number of random bytes */
|
/* Get random bytes, retrying if needed */
|
||||||
if ( ( efirc = efirng->GetRNG ( efirng, NULL, sizeof ( buf ),
|
for ( i = 0 ; i < EFIRNG_MAX_RETRY ; i++ ) {
|
||||||
buf ) ) != 0 ) {
|
|
||||||
rc = -EEFI ( efirc );
|
/* Get the minimum allowed number of random bytes */
|
||||||
DBGC ( &efirng, "ENTROPY could not read from RNG: %s\n",
|
if ( ( efirc = efirng->GetRNG ( efirng, NULL, sizeof ( buf ),
|
||||||
strerror ( rc ) );
|
buf ) ) != 0 ) {
|
||||||
return rc;
|
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
|
DBGC ( &efirng, "ENTROPY could not read from RNG: %s\n",
|
||||||
* like overkill, but we have no way of knowing how much
|
strerror ( rc ) );
|
||||||
* entropy is actually present in the bytes returned by the
|
return rc;
|
||||||
* RNG protocol.
|
|
||||||
*/
|
|
||||||
*noise = crc32_le ( 0, buf, sizeof ( buf ) );
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** EFI random number generator protocol entropy source */
|
/** EFI random number generator protocol entropy source */
|
||||||
|
|||||||
Reference in New Issue
Block a user