Commit 41e8a7c2 authored by Dominik Brodowski's avatar Dominik Brodowski Committed by Ard Biesheuvel
Browse files

efi/random: use arch-independent efi_call_proto()



To handle all arch-specific peculiarities when calling an EFI protocol
function, a wrapper efi_call_proto() exists on all relevant architectures.
On arm/arm64, this is merely a plain function call. On x86, a special EFI
entry stub needs to be used, however, as the calling convention differs.
To make the efi/random stub arch-independent, use efi_call_proto()
instead of the existing non-portable calls to the EFI get_rng protocol
function. This also requires the addition of some typedefs.

Signed-off-by: default avatarDominik Brodowski <linux@dominikbrodowski.net>
Signed-off-by: default avatarArd Biesheuvel <ardb@kernel.org>
parent 8b5c712f
Loading
Loading
Loading
Loading
+18 −5
Original line number Diff line number Diff line
@@ -9,6 +9,18 @@

#include "efistub.h"

typedef struct efi_rng_protocol efi_rng_protocol_t;

typedef struct {
	u32 get_info;
	u32 get_rng;
} efi_rng_protocol_32_t;

typedef struct {
	u64 get_info;
	u64 get_rng;
} efi_rng_protocol_64_t;

struct efi_rng_protocol {
	efi_status_t (*get_info)(struct efi_rng_protocol *,
				 unsigned long *, efi_guid_t *);
@@ -28,7 +40,7 @@ efi_status_t efi_get_random_bytes(efi_system_table_t *sys_table_arg,
	if (status != EFI_SUCCESS)
		return status;

	return rng->get_rng(rng, NULL, size, out);
	return efi_call_proto(efi_rng_protocol, get_rng, rng, NULL, size, out);
}

/*
@@ -161,15 +173,16 @@ efi_status_t efi_random_get_seed(efi_system_table_t *sys_table_arg)
	if (status != EFI_SUCCESS)
		return status;

	status = rng->get_rng(rng, &rng_algo_raw, EFI_RANDOM_SEED_SIZE,
			      seed->bits);
	status = efi_call_proto(efi_rng_protocol, get_rng, rng, &rng_algo_raw,
				 EFI_RANDOM_SEED_SIZE, seed->bits);

	if (status == EFI_UNSUPPORTED)
		/*
		 * Use whatever algorithm we have available if the raw algorithm
		 * is not implemented.
		 */
		status = rng->get_rng(rng, NULL, EFI_RANDOM_SEED_SIZE,
				      seed->bits);
		status = efi_call_proto(efi_rng_protocol, get_rng, rng, NULL,
					 EFI_RANDOM_SEED_SIZE, seed->bits);

	if (status != EFI_SUCCESS)
		goto err_freepool;