diff --git a/crypto/esdm/Kconfig b/crypto/esdm/Kconfig
index eeef71546bc3..43e11484e95c 100644
--- a/crypto/esdm/Kconfig
+++ b/crypto/esdm/Kconfig
@@ -111,6 +111,34 @@ config CRYPTO_ESDM_JENT_ENTROPY_RATE
 	  will provide 256 bits of data without being credited to contain
 	  entropy.
 
+comment "Kernel RNG Entropy Source"
+
+config CRYPTO_ESDM_KERNEL_RNG
+	bool "Enable Kernel RNG as ESDM Seed Source"
+	help
+	  The Linux RNG may use the kernel RNG (random.c) as entropy
+	  source.
+
+config CRYPTO_ESDM_KERNEL_RNG_ENTROPY_RATE
+	int "Kernel RNG Entropy Source Entropy Rate"
+	depends on CRYPTO_ESDM_KERNEL_RNG
+	range 0 256
+	default 256
+	help
+	  The option defines the amount of entropy the ESDM applies to 256
+	  bits of data obtained from the kernel RNG entropy source. The
+	  ESDM enforces the limit that this value must be in the range
+	  between 0 and 256.
+
+	  When configuring this value to 0, the kernel RNG entropy source
+	  will provide 256 bits of data without being credited to contain
+	  entropy.
+
+	  Note: This value is set to 0 automatically when booting the
+	  kernel in FIPS mode (with fips=1 kernel command line option).
+	  This is due to the fact that random.c is not SP800-90B
+	  compliant.
+
 endmenu # "Entropy Source Configuration"
 
 config CRYPTO_ESDM_DRNG_KCAPI
diff --git a/crypto/esdm/Makefile b/crypto/esdm/Makefile
index 99a86ce3e3af..404436de0aa2 100644
--- a/crypto/esdm/Makefile
+++ b/crypto/esdm/Makefile
@@ -9,4 +9,5 @@ obj-$(CONFIG_CRYPTO_ESDM_SHA256)	+= esdm_sha256.o
 
 obj-$(CONFIG_CRYPTO_ESDM_DRNG_KCAPI)	+= esdm_drng_kcapi.o
 
+obj-$(CONFIG_CRYPTO_ESDM_KERNEL_RNG)	+= esdm_es_krng.o
 obj-$(CONFIG_CRYPTO_ESDM_JENT)		+= esdm_es_jent.o
diff --git a/crypto/esdm/esdm_es_krng.c b/crypto/esdm/esdm_es_krng.c
new file mode 100644
index 000000000000..d536a9139276
--- /dev/null
+++ b/crypto/esdm/esdm_es_krng.c
@@ -0,0 +1,120 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * ESDM Fast Entropy Source: Linux kernel RNG (random.c)
+ *
+ * Copyright (C) 2022, Stephan Mueller <smueller@chronox.de>
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/fips.h>
+#include <linux/module.h>
+#include <linux/random.h>
+#include <linux/types.h>
+
+#include "esdm_es_aux.h"
+#include "esdm_es_krng.h"
+
+static u32 krng_entropy = CONFIG_CRYPTO_ESDM_KERNEL_RNG_ENTROPY_RATE;
+#ifdef CONFIG_CRYPTO_ESDM_RUNTIME_ES_CONFIG
+module_param(krng_entropy, uint, 0644);
+MODULE_PARM_DESC(krng_entropy, "Entropy in bits of 256 data bits from the kernel RNG noise source");
+#endif
+
+static atomic_t esdm_krng_initial_rate = ATOMIC_INIT(0);
+
+static struct random_ready_callback esdm_krng_ready = {
+	.owner = THIS_MODULE,
+	.func = NULL,
+};
+
+static u32 esdm_krng_fips_entropylevel(u32 entropylevel)
+{
+	return fips_enabled ? 0 : entropylevel;
+}
+
+static void esdm_krng_adjust_entropy(struct random_ready_callback *rdy)
+{
+	u32 entropylevel;
+
+	krng_entropy = atomic_read_u32(&esdm_krng_initial_rate);
+
+	entropylevel = esdm_krng_fips_entropylevel(krng_entropy);
+	pr_debug("Kernel RNG is fully seeded, setting entropy rate to %u bits of entropy\n",
+		 entropylevel);
+	esdm_drng_force_reseed();
+	if (entropylevel)
+		esdm_es_add_entropy();
+}
+
+static u32 esdm_krng_entropylevel(u32 requested_bits)
+{
+	if (esdm_krng_ready.func == NULL) {
+		int err;
+
+		esdm_krng_ready.func = esdm_krng_adjust_entropy;
+
+		err = add_random_ready_callback(&esdm_krng_ready);
+		switch (err) {
+		case 0:
+			atomic_set(&esdm_krng_initial_rate, krng_entropy);
+			krng_entropy = 0;
+			pr_debug("Kernel RNG is not yet seeded, setting entropy rate to 0 bits of entropy\n");
+			break;
+
+		case -EALREADY:
+			pr_debug("Kernel RNG is fully seeded, setting entropy rate to %u bits of entropy\n",
+				 esdm_krng_fips_entropylevel(krng_entropy));
+			break;
+		default:
+			esdm_krng_ready.func = NULL;
+			return 0;
+		}
+	}
+
+	return esdm_fast_noise_entropylevel(
+		esdm_krng_fips_entropylevel(krng_entropy), requested_bits);
+}
+
+static u32 esdm_krng_poolsize(void)
+{
+	return esdm_krng_entropylevel(esdm_security_strength());
+}
+
+/*
+ * esdm_krng_get() - Get kernel RNG entropy
+ *
+ * @eb: entropy buffer to store entropy
+ * @requested_bits: requested entropy in bits
+ */
+static void esdm_krng_get(struct entropy_buf *eb, u32 requested_bits,
+			  bool __unused)
+{
+	u32 ent_bits = esdm_krng_entropylevel(requested_bits);
+
+	get_random_bytes(eb->e[esdm_ext_es_krng], requested_bits >> 3);
+
+	pr_debug("obtained %u bits of entropy from kernel RNG noise source\n",
+		 ent_bits);
+
+	eb->e_bits[esdm_ext_es_krng] = ent_bits;
+}
+
+static void esdm_krng_es_state(unsigned char *buf, size_t buflen)
+{
+	snprintf(buf, buflen,
+		 " Available entropy: %u\n"
+		 " Entropy Rate per 256 data bits: %u\n",
+		 esdm_krng_poolsize(),
+		 esdm_krng_entropylevel(256));
+}
+
+struct esdm_es_cb esdm_es_krng = {
+	.name			= "KernelRNG",
+	.get_ent		= esdm_krng_get,
+	.curr_entropy		= esdm_krng_entropylevel,
+	.max_entropy		= esdm_krng_poolsize,
+	.state			= esdm_krng_es_state,
+	.reset			= NULL,
+	.switch_hash		= NULL,
+};
diff --git a/crypto/esdm/esdm_es_krng.h b/crypto/esdm/esdm_es_krng.h
new file mode 100644
index 000000000000..b164594bfe79
--- /dev/null
+++ b/crypto/esdm/esdm_es_krng.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */
+/*
+ * Copyright (C) 2022, Stephan Mueller <smueller@chronox.de>
+ */
+
+#ifndef _ESDM_ES_RANDOM_H
+#define _ESDM_ES_RANDOM_H
+
+#include "esdm_es_mgr_cb.h"
+
+#ifdef CONFIG_CRYPTO_ESDM_KERNEL_RNG
+
+extern struct esdm_es_cb esdm_es_krng;
+
+#endif /* CONFIG_CRYPTO_ESDM_KERNEL_RNG */
+
+#endif /* _ESDM_ES_RANDOM_H */
diff --git a/crypto/esdm/esdm_es_mgr.c b/crypto/esdm/esdm_es_mgr.c
index b7b1a4151137..0a65aafac8d2 100644
--- a/crypto/esdm/esdm_es_mgr.c
+++ b/crypto/esdm/esdm_es_mgr.c
@@ -14,6 +14,7 @@
 #include "esdm_drng_mgr.h"
 #include "esdm_es_aux.h"
 #include "esdm_es_jent.h"
+#include "esdm_es_krng.h"
 #include "esdm_es_mgr.h"
 
 struct esdm_state {
@@ -57,6 +58,9 @@ u32 esdm_write_wakeup_bits = (ESDM_WRITE_WAKEUP_ENTROPY << 3);
 struct esdm_es_cb *esdm_es[] = {
 #ifdef CONFIG_CRYPTO_ESDM_JENT
 	&esdm_es_jent,
+#endif
+#ifdef CONFIG_CRYPTO_ESDM_KERNEL_RNG
+	&esdm_es_krng,
 #endif
 	&esdm_es_aux
 };
diff --git a/crypto/esdm/esdm_es_mgr_cb.h b/crypto/esdm/esdm_es_mgr_cb.h
index 18f0e4317691..a94ad28f7d0f 100644
--- a/crypto/esdm/esdm_es_mgr_cb.h
+++ b/crypto/esdm/esdm_es_mgr_cb.h
@@ -16,6 +16,9 @@
 enum esdm_external_es {
 #ifdef CONFIG_CRYPTO_ESDM_JENT
 	esdm_ext_es_jitter,			/* Jitter RNG */
+#endif
+#ifdef CONFIG_CRYPTO_ESDM_KERNEL_RNG
+	esdm_ext_es_krng,			/* random.c */
 #endif
 	esdm_ext_es_aux,			/* MUST BE LAST ES! */
 	esdm_ext_es_last			/* MUST be the last entry */
