diff --git a/epicardium/modules/rng.c b/epicardium/modules/rng.c
index 0357f10697889798f9bd9c731611f46a7f1bcc7c..3be1d66be3dbddd9fdfde933865e492509874b4c 100644
--- a/epicardium/modules/rng.c
+++ b/epicardium/modules/rng.c
@@ -4,6 +4,7 @@
 
 #include "MAX77650-Arduino-Library.h"
 #include "tiny-AES-c/aes.h"
+#include "SHA256/mark2/sha256.h"
 
 #include "mxc_sys.h"
 #include "adc.h"
@@ -13,7 +14,7 @@
 
 #include <string.h>
 
-static struct AES_ctx ctx;
+static struct AES_ctx aes_ctx;
 
 int epic_trng_read(uint8_t *dest, size_t size)
 {
@@ -30,52 +31,38 @@ int epic_csprng_read(uint8_t *dest, size_t size)
 {
 	if (size >= AES_BLOCKLEN) {
 		int block_count = size / AES_BLOCKLEN;
-		AES_CTR_xcrypt_buffer(&ctx, dest, block_count * AES_BLOCKLEN);
+		AES_CTR_xcrypt_buffer(
+			&aes_ctx, dest, block_count * AES_BLOCKLEN
+		);
 		size -= block_count * AES_BLOCKLEN;
 		dest += block_count * AES_BLOCKLEN;
 	}
 
 	if (size > 0) {
 		uint8_t out[AES_BLOCKLEN];
-		AES_CTR_xcrypt_buffer(&ctx, out, sizeof(out));
+		AES_CTR_xcrypt_buffer(&aes_ctx, out, sizeof(out));
 		memcpy(dest, out, size);
 	}
 
 	return 0;
 }
 
-static void xor
-	(uint8_t * a, uint8_t *b, size_t size) {
-		while (size--) {
-			*a = *a ^ *b;
-			a++;
-			b++;
-		}
-	}
-
-	static void seed(uint8_t *entropy, size_t size)
-{
-	uint8_t key_new[AES_BLOCKLEN];
-	uint8_t iv[AES_BLOCKLEN] = { 0 };
-	epic_csprng_read(key_new, AES_BLOCKLEN);
-	xor(key_new, entropy, size);
-	AES_init_ctx_iv(&ctx, key_new, iv);
-}
-
 void rng_init(void)
 {
-	uint8_t key[AES_BLOCKLEN] = { 0 };
-	uint8_t iv[AES_BLOCKLEN]  = { 0 };
+	uint8_t key[AES_BLOCKLEN];
+	uint8_t iv[AES_BLOCKLEN];
+	uint8_t hash[32];
+	sha256_context ctx;
 	int i;
 
-	AES_init_ctx_iv(&ctx, key, iv);
+	sha256_init(&ctx);
 
 	/* Seed from TRNG.
-	 * Takes about 30 ms. */
+	 * Takes about 10 ms. */
 	for (i = 0; i < 256; i++) {
 		uint8_t entropy[AES_BLOCKLEN];
 		epic_trng_read(entropy, AES_BLOCKLEN);
-		seed(entropy, AES_BLOCKLEN);
+		sha256_hash(&ctx, entropy, AES_BLOCKLEN);
 	}
 
 	// Seed from RTC
@@ -83,15 +70,15 @@ void rng_init(void)
 	while (RTC_GetTime(&sec, &subsec) == E_BUSY) {
 		mxc_delay(4000);
 	}
-	seed((uint8_t *)&sec, sizeof(sec));
-	seed((uint8_t *)&subsec, sizeof(subsec));
+	sha256_hash(&ctx, &sec, sizeof(sec));
+	sha256_hash(&ctx, &subsec, sizeof(subsec));
 
 	// Seed from SysTick
 	uint32_t systick = SysTick->VAL;
-	seed((uint8_t *)&systick, sizeof(systick));
+	sha256_hash(&ctx, &systick, sizeof(systick));
 
 	/* Seed from ADC.
-	 * Takes about 80 ms */
+	 * Takes about 50 ms */
 	ADC_Init(0x9, NULL);
 	GPIO_Config(&gpio_cfg_adc0);
 	MAX77650_setMUX_SEL(PMIC_AMUX_BATT_U);
@@ -99,7 +86,12 @@ void rng_init(void)
 		uint16_t adc_data;
 		ADC_StartConvert(ADC_CH_0, 0, 0);
 		ADC_GetData(&adc_data);
-		seed((uint8_t *)&adc_data, sizeof(adc_data));
+		sha256_hash(&ctx, &adc_data, sizeof(adc_data));
 	}
 	MAX77650_setMUX_SEL(PMIC_AMUX_DISABLED);
+
+	sha256_done(&ctx, hash);
+	memcpy(key, hash, AES_BLOCKLEN);
+	memcpy(iv, hash + AES_BLOCKLEN, AES_BLOCKLEN);
+	AES_init_ctx_iv(&aes_ctx, key, iv);
 }