diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
index d0537573501e..3b3c67001566 100644
--- a/drivers/firmware/efi/libstub/Makefile
+++ b/drivers/firmware/efi/libstub/Makefile
@@ -55,6 +55,7 @@ KCOV_INSTRUMENT			:= n
 lib-y				:= efi-stub-helper.o gop.o secureboot.o tpm.o \
 				   file.o mem.o random.o randomalloc.o pci.o \
 				   skip_spaces.o lib-cmdline.o lib-ctype.o \
+				   libcrypto-blake2s.o libcrypto-blake2s-generic.o \
 				   alignedmem.o relocate.o vsprintf.o
 
 # include the stub's generic dependencies from lib/ when building for ARM/arm64
@@ -63,6 +64,9 @@ efi-deps-y := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c fdt_empty_tree.c fdt_sw.c
 $(obj)/lib-%.o: $(srctree)/lib/%.c FORCE
 	$(call if_changed_rule,cc_o_c)
 
+$(obj)/libcrypto-%.o: $(srctree)/lib/crypto/%.c FORCE
+	$(call if_changed_rule,cc_o_c)
+
 lib-$(CONFIG_EFI_GENERIC_STUB)	+= efi-stub.o fdt.o string.o \
 				   $(patsubst %.c,lib-%.o,$(efi-deps-y))
 
diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
index b0ae0a454404..fc32897de5e8 100644
--- a/drivers/firmware/efi/libstub/efistub.h
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -873,6 +873,8 @@ efi_status_t efi_get_random_bytes(unsigned long size, u8 *out);
 efi_status_t efi_random_alloc(unsigned long size, unsigned long align,
 			      unsigned long *addr, unsigned long random_seed);
 
+void efi_random_get_seed(void);
+
 efi_status_t check_platform_features(void);
 
 void *get_efi_config_table(efi_guid_t guid);
diff --git a/drivers/firmware/efi/libstub/random.c b/drivers/firmware/efi/libstub/random.c
index 183dc5cdb8ed..87fcd73ef615 100644
--- a/drivers/firmware/efi/libstub/random.c
+++ b/drivers/firmware/efi/libstub/random.c
@@ -5,6 +5,7 @@
 
 #include <linux/efi.h>
 #include <asm/efi.h>
+#include <crypto/blake2s.h>
 
 #include "efistub.h"
 
@@ -49,60 +50,74 @@ efi_status_t efi_get_random_bytes(unsigned long size, u8 *out)
 	return efi_call_proto(rng, get_rng, NULL, size, out);
 }
 
+static char const pstr[] = "Linux EFI Stub RNG Seed Label v1";
+
 /**
  * efi_random_get_seed() - provide random seed as configuration table
  *
  * The EFI_RNG_PROTOCOL is used to read random bytes. These random bytes are
  * saved as a configuration table which can be used as entropy by the kernel
  * for the initialization of its pseudo random number generator.
- *
- * If the EFI_RNG_PROTOCOL is not available or there are not enough random bytes
- * available, the configuration table will not be installed and an error code
- * will be returned.
- *
- * Return:	status code
  */
-efi_status_t efi_random_get_seed(void)
+void efi_random_get_seed(void)
 {
 	efi_guid_t rng_proto = EFI_RNG_PROTOCOL_GUID;
 	efi_guid_t rng_algo_raw = EFI_RNG_ALGORITHM_RAW;
 	efi_guid_t rng_table_guid = LINUX_EFI_RANDOM_SEED_TABLE_GUID;
 	efi_rng_protocol_t *rng = NULL;
 	struct linux_efi_random_seed *seed = NULL;
+	struct blake2s_state state;
+	unsigned int total_len = 0;
 	efi_status_t status;
 
-	status = efi_bs_call(locate_protocol, &rng_proto, NULL, (void **)&rng);
-	if (status != EFI_SUCCESS)
-		return status;
+	// grab the EFI RNG protocol, if it exists
+	efi_bs_call(locate_protocol, &rng_proto, NULL, (void **)&rng);
 
-	status = efi_bs_call(allocate_pool, EFI_ACPI_RECLAIM_MEMORY,
-			     sizeof(*seed) + EFI_RANDOM_SEED_SIZE,
-			     (void **)&seed);
-	if (status != EFI_SUCCESS)
-		return status;
+	// grab the seed provided by the previous boot stages
+	seed = get_efi_config_table(LINUX_EFI_RANDOM_SEED_TABLE_GUID);
+
+	// if neither exists, there is little we can do
+	if (!seed && !rng)
+		return;
+
+	blake2s_init(&state, EFI_RANDOM_SEED_SIZE);
+	blake2s_update(&state, pstr, sizeof(pstr) - 1);
+
+	if (seed) {
+		blake2s_update(&state, (void *)&seed->size, sizeof(seed->size));
+		blake2s_update(&state, seed->bits, seed->size);
+		total_len += seed->size;
+	}
 
-	status = efi_call_proto(rng, get_rng, &rng_algo_raw,
-				 EFI_RANDOM_SEED_SIZE, seed->bits);
+	if (rng) {
+		const int sz = EFI_RANDOM_SEED_SIZE;
+		u8 bits[EFI_RANDOM_SEED_SIZE];
 
-	if (status == EFI_UNSUPPORTED)
-		/*
-		 * Use whatever algorithm we have available if the raw algorithm
-		 * is not implemented.
-		 */
-		status = efi_call_proto(rng, get_rng, NULL,
-					EFI_RANDOM_SEED_SIZE, seed->bits);
+		status = efi_call_proto(rng, get_rng, &rng_algo_raw, sz, bits);
+		if (status == EFI_UNSUPPORTED)
+			/*
+			 * Use whatever algorithm we have available if the raw algorithm
+			 * is not implemented.
+			 */
+			status = efi_call_proto(rng, get_rng, NULL, sz, bits);
 
+		if (status == EFI_SUCCESS) {
+			blake2s_update(&state, (void *)&sz, sizeof(sz));
+			blake2s_update(&state, bits, sz);
+			total_len += sz;
+		}
+	}
+
+	status = efi_bs_call(allocate_pool, EFI_ACPI_RECLAIM_MEMORY,
+			     sizeof(*seed) + EFI_RANDOM_SEED_SIZE,
+			     (void **)&seed);
 	if (status != EFI_SUCCESS)
-		goto err_freepool;
+		return;
 
-	seed->size = EFI_RANDOM_SEED_SIZE;
+	blake2s_final(&state, seed->bits);
+	seed->size = min(total_len, EFI_RANDOM_SEED_SIZE);
 	status = efi_bs_call(install_configuration_table, &rng_table_guid, seed);
 	if (status != EFI_SUCCESS)
-		goto err_freepool;
-
-	return EFI_SUCCESS;
+		efi_warn("Failed to install LINUX_EFI_RANDOM_SEED_TABLE_GUID config table\n");
 
-err_freepool:
-	efi_bs_call(free_pool, seed);
-	return status;
 }
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 7b015508c773..95542148d9d7 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -1142,8 +1142,6 @@ void efi_check_for_embedded_firmwares(void);
 static inline void efi_check_for_embedded_firmwares(void) { }
 #endif
 
-efi_status_t efi_random_get_seed(void);
-
 #define arch_efi_call_virt(p, f, args...)	((p)->f(args))
 
 /*
diff --git a/lib/crypto/blake2s-generic.c b/lib/crypto/blake2s-generic.c
index 75ccb3e633e6..5d16b5a59618 100644
--- a/lib/crypto/blake2s-generic.c
+++ b/lib/crypto/blake2s-generic.c
@@ -110,6 +110,8 @@ void blake2s_compress_generic(struct blake2s_state *state, const u8 *block,
 
 EXPORT_SYMBOL(blake2s_compress_generic);
 
+#ifdef MODULE
 MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("BLAKE2s hash function");
 MODULE_AUTHOR("Jason A. Donenfeld <Jason@zx2c4.com>");
+#endif
diff --git a/lib/crypto/blake2s.c b/lib/crypto/blake2s.c
index 98e688c6d891..dbae6d83027b 100644
--- a/lib/crypto/blake2s.c
+++ b/lib/crypto/blake2s.c
@@ -58,15 +58,18 @@ void blake2s_final(struct blake2s_state *state, u8 *out)
 }
 EXPORT_SYMBOL(blake2s_final);
 
+#if !defined(CONFIG_CRYPTO_MANAGER_DISABLE_TESTS) && !defined(__DISABLE_EXPORTS)
 static int __init blake2s_mod_init(void)
 {
-	if (!IS_ENABLED(CONFIG_CRYPTO_MANAGER_DISABLE_TESTS) &&
-	    WARN_ON(!blake2s_selftest()))
+	if (WARN_ON(!blake2s_selftest()))
 		return -ENODEV;
 	return 0;
 }
 
 module_init(blake2s_mod_init);
+#endif
+#ifdef MODULE
 MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("BLAKE2s hash function");
 MODULE_AUTHOR("Jason A. Donenfeld <Jason@zx2c4.com>");
+#endif
