Repository: nrfconnect/sdk-nrf
Pull request #20821: nrf_security: cracen: add support for l09/l20 to ctr_drbg
Author: login: degjorva
Labels: name: changelog-entry-required
description: Update changelog before merge. Remove label if entry is not needed or already added.
Created: 2025-03-10T09:34:28Z | Merged: 2025-03-14T11:28:26Z

l09/l20 only supports a 16 bit ctr counter. As such we must reseed before this counter overflows, to avoid repeating blocks.
Limited the max output for cracen lite boards and
changed the reseed counter to depend on the amount of blocks given as input to support this.

NIST:800-90A has limits on the maximum number of operations that can be done before a reseed must be done, but there are no limits on the minimum. Likewise there is a limit on the max size of output, but no lower bounds. The divergence from NIST is that the number of operations is not what is kept track of before reseed, but instead the number of blocks given as input. As this will strictly lead to reseeding happening more often it should not affect security and should fall under the NIST "Or equivalent" code specification. 


Diff:
diff --git a/subsys/nrf_security/src/drivers/cracen/Kconfig b/subsys/nrf_security/src/drivers/cracen/Kconfig
index 8d535acb83c9..e1e890a6ea55 100644
--- a/subsys/nrf_security/src/drivers/cracen/Kconfig
+++ b/subsys/nrf_security/src/drivers/cracen/Kconfig
@@ -11,7 +11,7 @@ config CRACEN_HW_VERSION_BASE
 	def_bool SOC_SERIES_NRF54HX || SOC_NRF54L15 || SOC_NRF54L10 || SOC_NRF54L05
 
 config CRACEN_HW_VERSION_LITE
-	def_bool SOC_NRF54L20
+	def_bool SOC_NRF54L20 || SOC_NRF54L09
 
 # Configure CRACEN_LOG_LEVEL
 module = CRACEN
diff --git a/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ctr_drbg.c b/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ctr_drbg.c
index e41b69933772..802fabc02359 100644
--- a/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ctr_drbg.c
+++ b/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ctr_drbg.c
@@ -20,12 +20,17 @@
 #include <sxsymcrypt/trng.h>
 #include <sxsymcrypt/aes.h>
 #include <sxsymcrypt/keyref.h>
-
 #include <zephyr/kernel.h>
 #include <nrf_security_mutexes.h>
 
-#define MAX_BITS_PER_REQUEST (1 << 19)		 /* NIST.SP.800-90Ar1:Table 3 */
-#define RESEED_INTERVAL	     ((uint64_t)1 << 48) /* 2^48 as per NIST spec */
+#ifdef CONFIG_CRACEN_HW_VERSION_LITE
+#define MAX_BITS_PER_REQUEST (1 << 16) /* Cracen Lite only supports 2^16 ctr size */
+/* Cracen Lite only supports 2^16 ctr size so will need to reseed before it overflows */
+#define RESEED_INTERVAL ((uint64_t)1 << 16)
+#else
+#define MAX_BITS_PER_REQUEST (1 << 19) /* NIST.SP.800-90Ar1:Table 3 */
+#define RESEED_INTERVAL ((uint64_t)1 << 48) /* 2^48 as per NIST spec */
+#endif
 
 /** @brief Magic number to signal that PRNG context is initialized */
 #define CRACEN_PRNG_INITIALIZED (0xA5B4A5B4)
@@ -103,6 +108,7 @@ static psa_status_t ctr_drbg_update(uint8_t *data)
 			return status;
 		}
 		temp_length += SX_BLKCIPHER_AES_BLK_SZ;
+		prng.reseed_counter++;
 	}
 
 	if (data) {
@@ -158,12 +164,33 @@ psa_status_t cracen_init_random(cracen_prng_context_t *context)
 	return silex_statuscodes_to_psa(sx_err);
 }
 
+static psa_status_t cracen_reseed(void)
+{
+	psa_status_t status;
+
+	/* DRBG entropy + nonce buffer. */
+	char entropy[CRACEN_PRNG_ENTROPY_SIZE + CRACEN_PRNG_NONCE_SIZE];
+	int sx_err = trng_get_seed(entropy, sizeof(entropy));
+
+	if (sx_err) {
+		return PSA_ERROR_HARDWARE_FAILURE;
+	}
+	status = ctr_drbg_update(entropy);
+	if (status != PSA_SUCCESS) {
+		return status;
+	}
+	safe_memset(entropy, sizeof(entropy), 0, CRACEN_PRNG_ENTROPY_SIZE + CRACEN_PRNG_NONCE_SIZE);
+	prng.reseed_counter = 0;
+	return PSA_SUCCESS;
+}
+
 psa_status_t cracen_get_random(cracen_prng_context_t *context, uint8_t *output, size_t output_size)
 {
 	(void)context;
 
 	psa_status_t status = PSA_SUCCESS;
 	size_t len_left = output_size;
+	size_t number_of_blocks = DIV_ROUND_UP(output_size, SX_BLKCIPHER_AES_BLK_SZ);
 
 	if (output_size > 0 && output == NULL) {
 		return PSA_ERROR_INVALID_ARGUMENT;
@@ -181,29 +208,18 @@ psa_status_t cracen_get_random(cracen_prng_context_t *context, uint8_t *output,
 		 * here even though we hold the mutex.
 		 */
 		status = cracen_init_random(context);
-
 		if (status != PSA_SUCCESS) {
-			goto exit;
+			nrf_security_mutex_unlock(cracen_prng_context_mutex);
+			return status;
 		}
 	}
 
-	if (prng.reseed_counter >= RESEED_INTERVAL) {
-		char entropy[CRACEN_PRNG_ENTROPY_SIZE +
-			     CRACEN_PRNG_NONCE_SIZE]; /* DRBG entropy + nonce buffer. */
-		int sx_err = trng_get_seed(entropy, sizeof(entropy));
-
-		if (sx_err) {
-			status = PSA_ERROR_HARDWARE_FAILURE;
-			goto exit;
-		}
-		status = ctr_drbg_update(entropy);
+	if (prng.reseed_counter + number_of_blocks >= RESEED_INTERVAL) {
+		status = cracen_reseed();
 		if (status != PSA_SUCCESS) {
-			goto exit;
+			nrf_security_mutex_unlock(cracen_prng_context_mutex);
+			return status;
 		}
-		safe_memset(entropy, sizeof(entropy), 0,
-			    CRACEN_PRNG_ENTROPY_SIZE + CRACEN_PRNG_NONCE_SIZE);
-
-		prng.reseed_counter = 0;
 	}
 
 	psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
@@ -212,10 +228,6 @@ psa_status_t cracen_get_random(cracen_prng_context_t *context, uint8_t *output,
 	psa_set_key_bits(&attr, PSA_BYTES_TO_BITS(sizeof(prng.key)));
 	psa_set_key_usage_flags(&attr, PSA_KEY_USAGE_ENCRYPT);
 
-	if (status != PSA_SUCCESS) {
-		return status;
-	}
-
 	while (len_left > 0) {
 		size_t cur_len = MIN(len_left, SX_BLKCIPHER_AES_BLK_SZ);
 		char temp[SX_BLKCIPHER_AES_BLK_SZ] __aligned(CONFIG_DCACHE_LINE_SIZE);
@@ -225,7 +237,8 @@ psa_status_t cracen_get_random(cracen_prng_context_t *context, uint8_t *output,
 						 temp, sizeof(temp));
 
 		if (status != PSA_SUCCESS) {
-			goto exit;
+			nrf_security_mutex_unlock(cracen_prng_context_mutex);
+			return status;
 		}
 
 		for (int i = 0; i < cur_len; i++) {
@@ -234,16 +247,10 @@ psa_status_t cracen_get_random(cracen_prng_context_t *context, uint8_t *output,
 
 		len_left -= cur_len;
 		output += cur_len;
+		prng.reseed_counter++;
 	}
 
 	status = ctr_drbg_update(NULL);
-	if (status != PSA_SUCCESS) {
-		goto exit;
-	}
-
-	prng.reseed_counter += 1;
-
-exit:
 	nrf_security_mutex_unlock(cracen_prng_context_mutex);
 	return status;
 }


Reviews:
user: login: nordicjm
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-10T14:45:59Z
user: login: tomi-font
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-11T13:46:43Z
user: login: degjorva
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-13T09:55:08Z
user: login: tomi-font
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-13T13:47:57Z
user: login: degjorva
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-13T14:06:16Z
user: login: degjorva
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-13T14:06:30Z
user: login: degjorva
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-13T14:06:59Z
user: login: tomi-font
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-14T09:44:18Z
user: login: tomi-font
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-14T09:44:19Z

Review comments:
diff_hunk: @@ -20,12 +20,20 @@
 #include <sxsymcrypt/trng.h>
 #include <sxsymcrypt/aes.h>
 #include <sxsymcrypt/keyref.h>
-
 #include <zephyr/kernel.h>
 #include <nrf_security_mutexes.h>
 
-#define MAX_BITS_PER_REQUEST (1 << 19)		 /* NIST.SP.800-90Ar1:Table 3 */
-#define RESEED_INTERVAL	     ((uint64_t)1 << 48) /* 2^48 as per NIST spec */
+#if CONFIG_CRACEN_HW_VERSION_LITE
+#define MAX_BITS_PER_REQUEST (1 << 16) /* Cracen Lite only supports 2^16 ctr size */
+#else
+#define MAX_BITS_PER_REQUEST (1 << 19) /* NIST.SP.800-90Ar1:Table 3 */
+#endif
+/* Cracen Lite only supports 2^16 ctr size so will need to reseed before it overflows */
+#if CONFIG_CRACEN_HW_VERSION_LITE
+#define RESEED_INTERVAL ((uint64_t)1 << 16)
+#else
+#define RESEED_INTERVAL ((uint64_t)1 << 48) /* 2^48 as per NIST spec */
+#endif
path: subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ctr_drbg.c
user: login: tomi-font
body: Combine both `#if #else #endif` into a single one?
created_at: 2025-03-11T13:19:46Z
author_association: CONTRIBUTOR
diff_hunk: @@ -20,12 +20,20 @@
 #include <sxsymcrypt/trng.h>
 #include <sxsymcrypt/aes.h>
 #include <sxsymcrypt/keyref.h>
-
 #include <zephyr/kernel.h>
 #include <nrf_security_mutexes.h>
 
-#define MAX_BITS_PER_REQUEST (1 << 19)		 /* NIST.SP.800-90Ar1:Table 3 */
-#define RESEED_INTERVAL	     ((uint64_t)1 << 48) /* 2^48 as per NIST spec */
+#if CONFIG_CRACEN_HW_VERSION_LITE
path: subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ctr_drbg.c
user: login: tomi-font
body: ```suggestion
#ifdef CONFIG_CRACEN_HW_VERSION_LITE
```
created_at: 2025-03-11T13:21:19Z
author_association: CONTRIBUTOR
diff_hunk: @@ -158,6 +166,27 @@ psa_status_t cracen_init_random(cracen_prng_context_t *context)
 	return silex_statuscodes_to_psa(sx_err);
 }
 
+psa_status_t cracen_reseed(void)
path: subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ctr_drbg.c
user: login: tomi-font
body: ```suggestion
static psa_status_t cracen_reseed(void)
```
created_at: 2025-03-11T13:22:26Z
author_association: CONTRIBUTOR
diff_hunk: @@ -158,6 +166,27 @@ psa_status_t cracen_init_random(cracen_prng_context_t *context)
 	return silex_statuscodes_to_psa(sx_err);
 }
 
+psa_status_t cracen_reseed(void)
+{
+	psa_status_t status = PSA_SUCCESS;
path: subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ctr_drbg.c
user: login: tomi-font
body: ```suggestion
	psa_status_t status;
```
created_at: 2025-03-11T13:22:48Z
author_association: CONTRIBUTOR
diff_hunk: @@ -158,6 +166,27 @@ psa_status_t cracen_init_random(cracen_prng_context_t *context)
 	return silex_statuscodes_to_psa(sx_err);
 }
 
+psa_status_t cracen_reseed(void)
+{
+	psa_status_t status = PSA_SUCCESS;
+
+	/* DRBG entropy + nonce buffer. */
+	char entropy[CRACEN_PRNG_ENTROPY_SIZE +
+		     CRACEN_PRNG_NONCE_SIZE];
path: subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ctr_drbg.c
user: login: tomi-font
body: No need for newline it seems?
```suggestion
	char entropy[CRACEN_PRNG_ENTROPY_SIZE + CRACEN_PRNG_NONCE_SIZE];
```
created_at: 2025-03-11T13:23:20Z
author_association: CONTRIBUTOR
diff_hunk: @@ -181,37 +210,24 @@ psa_status_t cracen_get_random(cracen_prng_context_t *context, uint8_t *output,
 		 * here even though we hold the mutex.
 		 */
 		status = cracen_init_random(context);
-
 		if (status != PSA_SUCCESS) {
-			goto exit;
+			nrf_security_mutex_unlock(cracen_prng_context_mutex);
+			return status;
 		}
 	}
 
-	if (prng.reseed_counter >= RESEED_INTERVAL) {
-		char entropy[CRACEN_PRNG_ENTROPY_SIZE +
-			     CRACEN_PRNG_NONCE_SIZE]; /* DRBG entropy + nonce buffer. */
-		int sx_err = trng_get_seed(entropy, sizeof(entropy));
-
-		if (sx_err) {
-			status = PSA_ERROR_HARDWARE_FAILURE;
-			goto exit;
-		}
-		status = ctr_drbg_update(entropy);
+	if (prng.reseed_counter + output_size >= RESEED_INTERVAL) {
+		status = cracen_reseed();
 		if (status != PSA_SUCCESS) {
-			goto exit;
+			return status;
path: subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ctr_drbg.c
user: login: tomi-font
body: Mutex unlock?
created_at: 2025-03-11T13:31:47Z
author_association: CONTRIBUTOR
diff_hunk: @@ -158,6 +166,27 @@ psa_status_t cracen_init_random(cracen_prng_context_t *context)
 	return silex_statuscodes_to_psa(sx_err);
 }
 
+psa_status_t cracen_reseed(void)
+{
+	psa_status_t status = PSA_SUCCESS;
+
+	/* DRBG entropy + nonce buffer. */
+	char entropy[CRACEN_PRNG_ENTROPY_SIZE +
+		     CRACEN_PRNG_NONCE_SIZE];
+	int sx_err = trng_get_seed(entropy, sizeof(entropy));
+
+	if (sx_err) {
+		return PSA_ERROR_HARDWARE_FAILURE;
+	}
+	status = ctr_drbg_update(entropy);
+	if (status != PSA_SUCCESS) {
+		return status;
+	}
+	safe_memset(entropy, sizeof(entropy), 0, CRACEN_PRNG_ENTROPY_SIZE + CRACEN_PRNG_NONCE_SIZE);
+	prng.reseed_counter = 0;
+	return status;
path: subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ctr_drbg.c
user: login: tomi-font
body: ```suggestion
	return PSA_SUCCESS;
```
created_at: 2025-03-11T13:34:06Z
author_association: CONTRIBUTOR
diff_hunk: @@ -181,37 +210,24 @@ psa_status_t cracen_get_random(cracen_prng_context_t *context, uint8_t *output,
 		 * here even though we hold the mutex.
 		 */
 		status = cracen_init_random(context);
-
 		if (status != PSA_SUCCESS) {
-			goto exit;
+			nrf_security_mutex_unlock(cracen_prng_context_mutex);
+			return status;
 		}
 	}
 
-	if (prng.reseed_counter >= RESEED_INTERVAL) {
-		char entropy[CRACEN_PRNG_ENTROPY_SIZE +
-			     CRACEN_PRNG_NONCE_SIZE]; /* DRBG entropy + nonce buffer. */
-		int sx_err = trng_get_seed(entropy, sizeof(entropy));
-
-		if (sx_err) {
-			status = PSA_ERROR_HARDWARE_FAILURE;
-			goto exit;
-		}
-		status = ctr_drbg_update(entropy);
+	if (prng.reseed_counter + output_size >= RESEED_INTERVAL) {
+		status = cracen_reseed();
 		if (status != PSA_SUCCESS) {
-			goto exit;
+			return status;
 		}
-		safe_memset(entropy, sizeof(entropy), 0,
-			    CRACEN_PRNG_ENTROPY_SIZE + CRACEN_PRNG_NONCE_SIZE);
-
-		prng.reseed_counter = 0;
 	}
 
 	psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
 
 	psa_set_key_type(&attr, PSA_KEY_TYPE_AES);
 	psa_set_key_bits(&attr, PSA_BYTES_TO_BITS(sizeof(prng.key)));
 	psa_set_key_usage_flags(&attr, PSA_KEY_USAGE_ENCRYPT);
-
 	if (status != PSA_SUCCESS) {
 		return status;
 	}
path: subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ctr_drbg.c
user: login: tomi-font
body: Remove this? (was already present)
created_at: 2025-03-11T13:39:37Z
author_association: CONTRIBUTOR
diff_hunk: @@ -234,16 +251,10 @@ psa_status_t cracen_get_random(cracen_prng_context_t *context, uint8_t *output,
 
 		len_left -= cur_len;
 		output += cur_len;
+		prng.reseed_counter += sizeof(prng.V);
path: subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ctr_drbg.c
user: login: tomi-font
body: Not sure I follow; why not `+= cur_len`?
created_at: 2025-03-11T13:43:33Z
author_association: CONTRIBUTOR
diff_hunk: @@ -234,16 +251,10 @@ psa_status_t cracen_get_random(cracen_prng_context_t *context, uint8_t *output,
 
 		len_left -= cur_len;
 		output += cur_len;
+		prng.reseed_counter += sizeof(prng.V);
path: subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ctr_drbg.c
user: login: degjorva
body: Because that would be too low for the last input case, as it always handles a full block, even when the remaining output asked for is less than the full size. However we can get away with just caring about the blocks which is cleaner anyways. Changed the code to reflect that
created_at: 2025-03-13T09:55:08Z
author_association: CONTRIBUTOR
diff_hunk: @@ -158,12 +165,34 @@ psa_status_t cracen_init_random(cracen_prng_context_t *context)
 	return silex_statuscodes_to_psa(sx_err);
 }
 
+static psa_status_t cracen_reseed(void)
+{
+	psa_status_t status;
+
+	/* DRBG entropy + nonce buffer. */
+	char entropy[CRACEN_PRNG_ENTROPY_SIZE + CRACEN_PRNG_NONCE_SIZE];
+	int sx_err = trng_get_seed(entropy, sizeof(entropy));
+
+	if (sx_err) {
+		return PSA_ERROR_HARDWARE_FAILURE;
+	}
+	status = ctr_drbg_update(entropy);
+	if (status != PSA_SUCCESS) {
+		return status;
+	}
+	safe_memset(entropy, sizeof(entropy), 0, CRACEN_PRNG_ENTROPY_SIZE + CRACEN_PRNG_NONCE_SIZE);
+	prng.reseed_counter = 0;
+	return PSA_SUCCESS;
+}
+
 psa_status_t cracen_get_random(cracen_prng_context_t *context, uint8_t *output, size_t output_size)
 {
 	(void)context;
 
 	psa_status_t status = PSA_SUCCESS;
 	size_t len_left = output_size;
+	size_t number_of_blocks =
+		(output_size + SX_BLKCIPHER_AES_BLK_SZ - 1) / SX_BLKCIPHER_AES_BLK_SZ;
path: subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ctr_drbg.c
user: login: tomi-font
body: Use `ROUND_UP()`?
created_at: 2025-03-13T13:38:19Z
author_association: CONTRIBUTOR
diff_hunk: @@ -103,6 +108,8 @@ static psa_status_t ctr_drbg_update(uint8_t *data)
 			return status;
 		}
 		temp_length += SX_BLKCIPHER_AES_BLK_SZ;
+		prng.reseed_counter++;
+
path: subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ctr_drbg.c
user: login: tomi-font
body: ```suggestion
```
created_at: 2025-03-13T13:41:25Z
author_association: CONTRIBUTOR
diff_hunk: @@ -158,12 +165,34 @@ psa_status_t cracen_init_random(cracen_prng_context_t *context)
 	return silex_statuscodes_to_psa(sx_err);
 }
 
+static psa_status_t cracen_reseed(void)
+{
+	psa_status_t status;
+
+	/* DRBG entropy + nonce buffer. */
+	char entropy[CRACEN_PRNG_ENTROPY_SIZE + CRACEN_PRNG_NONCE_SIZE];
+	int sx_err = trng_get_seed(entropy, sizeof(entropy));
+
+	if (sx_err) {
+		return PSA_ERROR_HARDWARE_FAILURE;
+	}
+	status = ctr_drbg_update(entropy);
+	if (status != PSA_SUCCESS) {
+		return status;
+	}
+	safe_memset(entropy, sizeof(entropy), 0, CRACEN_PRNG_ENTROPY_SIZE + CRACEN_PRNG_NONCE_SIZE);
+	prng.reseed_counter = 0;
+	return PSA_SUCCESS;
+}
+
 psa_status_t cracen_get_random(cracen_prng_context_t *context, uint8_t *output, size_t output_size)
 {
 	(void)context;
 
 	psa_status_t status = PSA_SUCCESS;
 	size_t len_left = output_size;
+	size_t number_of_blocks =
path: subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ctr_drbg.c
user: login: tomi-font
body: This variable is actually unused?
created_at: 2025-03-13T13:42:00Z
author_association: CONTRIBUTOR
diff_hunk: @@ -181,29 +210,18 @@ psa_status_t cracen_get_random(cracen_prng_context_t *context, uint8_t *output,
 		 * here even though we hold the mutex.
 		 */
 		status = cracen_init_random(context);
-
 		if (status != PSA_SUCCESS) {
-			goto exit;
+			nrf_security_mutex_unlock(cracen_prng_context_mutex);
+			return status;
 		}
 	}
 
-	if (prng.reseed_counter >= RESEED_INTERVAL) {
-		char entropy[CRACEN_PRNG_ENTROPY_SIZE +
-			     CRACEN_PRNG_NONCE_SIZE]; /* DRBG entropy + nonce buffer. */
-		int sx_err = trng_get_seed(entropy, sizeof(entropy));
-
-		if (sx_err) {
-			status = PSA_ERROR_HARDWARE_FAILURE;
-			goto exit;
-		}
-		status = ctr_drbg_update(entropy);
+	if (prng.reseed_counter + output_size >= RESEED_INTERVAL) {
path: subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ctr_drbg.c
user: login: tomi-font
body: Minor: this could be `else if`.
created_at: 2025-03-13T13:43:13Z
author_association: CONTRIBUTOR
diff_hunk: @@ -181,29 +210,18 @@ psa_status_t cracen_get_random(cracen_prng_context_t *context, uint8_t *output,
 		 * here even though we hold the mutex.
 		 */
 		status = cracen_init_random(context);
-
 		if (status != PSA_SUCCESS) {
-			goto exit;
+			nrf_security_mutex_unlock(cracen_prng_context_mutex);
+			return status;
 		}
 	}
 
-	if (prng.reseed_counter >= RESEED_INTERVAL) {
-		char entropy[CRACEN_PRNG_ENTROPY_SIZE +
-			     CRACEN_PRNG_NONCE_SIZE]; /* DRBG entropy + nonce buffer. */
-		int sx_err = trng_get_seed(entropy, sizeof(entropy));
-
-		if (sx_err) {
-			status = PSA_ERROR_HARDWARE_FAILURE;
-			goto exit;
-		}
-		status = ctr_drbg_update(entropy);
+	if (prng.reseed_counter + output_size >= RESEED_INTERVAL) {
path: subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ctr_drbg.c
user: login: tomi-font
body: Now you're mixing using `reseed_counter` to count blocks and bytes?
created_at: 2025-03-13T13:44:44Z
author_association: CONTRIBUTOR
diff_hunk: @@ -158,12 +165,34 @@ psa_status_t cracen_init_random(cracen_prng_context_t *context)
 	return silex_statuscodes_to_psa(sx_err);
 }
 
+static psa_status_t cracen_reseed(void)
+{
+	psa_status_t status;
+
+	/* DRBG entropy + nonce buffer. */
+	char entropy[CRACEN_PRNG_ENTROPY_SIZE + CRACEN_PRNG_NONCE_SIZE];
+	int sx_err = trng_get_seed(entropy, sizeof(entropy));
+
+	if (sx_err) {
+		return PSA_ERROR_HARDWARE_FAILURE;
+	}
+	status = ctr_drbg_update(entropy);
+	if (status != PSA_SUCCESS) {
+		return status;
+	}
+	safe_memset(entropy, sizeof(entropy), 0, CRACEN_PRNG_ENTROPY_SIZE + CRACEN_PRNG_NONCE_SIZE);
+	prng.reseed_counter = 0;
+	return PSA_SUCCESS;
+}
+
 psa_status_t cracen_get_random(cracen_prng_context_t *context, uint8_t *output, size_t output_size)
 {
 	(void)context;
 
 	psa_status_t status = PSA_SUCCESS;
 	size_t len_left = output_size;
+	size_t number_of_blocks =
path: subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ctr_drbg.c
user: login: degjorva
body: Oh that should replace output_size for obvious reasons. Fixed
created_at: 2025-03-13T14:06:16Z
author_association: CONTRIBUTOR
diff_hunk: @@ -181,29 +210,18 @@ psa_status_t cracen_get_random(cracen_prng_context_t *context, uint8_t *output,
 		 * here even though we hold the mutex.
 		 */
 		status = cracen_init_random(context);
-
 		if (status != PSA_SUCCESS) {
-			goto exit;
+			nrf_security_mutex_unlock(cracen_prng_context_mutex);
+			return status;
 		}
 	}
 
-	if (prng.reseed_counter >= RESEED_INTERVAL) {
-		char entropy[CRACEN_PRNG_ENTROPY_SIZE +
-			     CRACEN_PRNG_NONCE_SIZE]; /* DRBG entropy + nonce buffer. */
-		int sx_err = trng_get_seed(entropy, sizeof(entropy));
-
-		if (sx_err) {
-			status = PSA_ERROR_HARDWARE_FAILURE;
-			goto exit;
-		}
-		status = ctr_drbg_update(entropy);
+	if (prng.reseed_counter + output_size >= RESEED_INTERVAL) {
path: subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ctr_drbg.c
user: login: degjorva
body: Yeah should be number of blocks. 
created_at: 2025-03-13T14:06:29Z
author_association: CONTRIBUTOR
diff_hunk: @@ -181,29 +210,18 @@ psa_status_t cracen_get_random(cracen_prng_context_t *context, uint8_t *output,
 		 * here even though we hold the mutex.
 		 */
 		status = cracen_init_random(context);
-
 		if (status != PSA_SUCCESS) {
-			goto exit;
+			nrf_security_mutex_unlock(cracen_prng_context_mutex);
+			return status;
 		}
 	}
 
-	if (prng.reseed_counter >= RESEED_INTERVAL) {
-		char entropy[CRACEN_PRNG_ENTROPY_SIZE +
-			     CRACEN_PRNG_NONCE_SIZE]; /* DRBG entropy + nonce buffer. */
-		int sx_err = trng_get_seed(entropy, sizeof(entropy));
-
-		if (sx_err) {
-			status = PSA_ERROR_HARDWARE_FAILURE;
-			goto exit;
-		}
-		status = ctr_drbg_update(entropy);
+	if (prng.reseed_counter + output_size >= RESEED_INTERVAL) {
path: subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ctr_drbg.c
user: login: degjorva
body: Then I would have to wrap the entire last half of the function in an else statement, which is not very pretty
created_at: 2025-03-13T14:06:59Z
author_association: CONTRIBUTOR
diff_hunk: @@ -181,29 +210,18 @@ psa_status_t cracen_get_random(cracen_prng_context_t *context, uint8_t *output,
 		 * here even though we hold the mutex.
 		 */
 		status = cracen_init_random(context);
-
 		if (status != PSA_SUCCESS) {
-			goto exit;
+			nrf_security_mutex_unlock(cracen_prng_context_mutex);
+			return status;
 		}
 	}
 
-	if (prng.reseed_counter >= RESEED_INTERVAL) {
-		char entropy[CRACEN_PRNG_ENTROPY_SIZE +
-			     CRACEN_PRNG_NONCE_SIZE]; /* DRBG entropy + nonce buffer. */
-		int sx_err = trng_get_seed(entropy, sizeof(entropy));
-
-		if (sx_err) {
-			status = PSA_ERROR_HARDWARE_FAILURE;
-			goto exit;
-		}
-		status = ctr_drbg_update(entropy);
+	if (prng.reseed_counter + output_size >= RESEED_INTERVAL) {
path: subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ctr_drbg.c
user: login: tomi-font
body: No. I just meant to change this `if` to an `else if` because if the previous `if` is true (`prng.reseed_counter == 0`) then this one cannot be true.
created_at: 2025-03-14T09:44:18Z
author_association: CONTRIBUTOR

PR comments:
user: login: NordicBuilder
created_at: 2025-03-10T09:37:28Z
body: ## CI Information

<sup>_To view the history of this post, clich the 'edited' button above_</sup>
Build number: 9
### Inputs:
#### Sources:
sdk-nrf: PR head: [8d06cbe4eac944c9929bd8b58f2856662a871e78](https://github.com/nrfconnect/sdk-nrf/pull/20821/commits/8d06cbe4eac944c9929bd8b58f2856662a871e78)
<details><summary> more details</summary>

sdk-nrf:
> PR head: [8d06cbe4eac944c9929bd8b58f2856662a871e78](https://github.com/nrfconnect/sdk-nrf/pull/20821/commits/8d06cbe4eac944c9929bd8b58f2856662a871e78)
> merge base: [00a66504228d36f2a6ff6604a00f4987cfbe1143](https://github.com/nrfconnect/sdk-nrf/commit/00a66504228d36f2a6ff6604a00f4987cfbe1143)
> target head (main): [00a66504228d36f2a6ff6604a00f4987cfbe1143](https://github.com/nrfconnect/sdk-nrf/commit/00a66504228d36f2a6ff6604a00f4987cfbe1143)
> [Diff](https://github.com/nrfconnect/sdk-nrf/compare/00a66504228d36f2a6ff6604a00f4987cfbe1143..8d06cbe4eac944c9929bd8b58f2856662a871e78)</details>

#### Github labels
| Enabled | Name | Description |
| -- | -- | -- |
|| ci-disabled | _Disable the ci execution_ | 
|| ci-all-test | _Run all of ci, no test spec filtering will be done_ | 
|| ci-force-downstream | _Force execution of downstream even if twister fails_ | 
|| ci-run-twister | _Force run twister_ | 
|| ci-run-zephyr-twister | _Force run zephyr twister_ | 

<details><summary> List of changed files detected by CI (2)</summary>

```
subsys
│  ├── nrf_security
│  │  ├── src
│  │  │  ├── drivers
│  │  │  │  ├── cracen
│  │  │  │  │  ├── Kconfig
│  │  │  │  │  ├── cracenpsa
│  │  │  │  │  │  ├── src
│  │  │  │  │  │  │  │ ctr_drbg.c
```
</details>

### Outputs:

#### Toolchain
Version: 4ffa2202d5
Build docker image: docker-dtr.nordicsemi.no/sw-production/ncs-build:4ffa2202d5_e579f9fbe6

#### Test Spec & Results: :white_check_mark: Success; :x: Failure; :orange_circle: Queued; :yellow_circle: Progress; :white_medium_square: Skipped; :warning: Quarantine
- :white_medium_square: Toolchain - Skipped: existing toolchain is used
- :white_check_mark: Build twister
   - sdk-nrf test count: 1747
- :white_check_mark: Integration tests
   - :white_check_mark: test-fw-nrfconnect-chip
   - :white_check_mark: test-fw-nrfconnect-nrf-iot_cloud
   - :white_check_mark: test-fw-nrfconnect-nrf_crypto
   - :white_check_mark: test-fw-nrfconnect-tfm
   - :white_check_mark: test-sdk-find-my
   - :white_check_mark: test-sdk-sidewalk
   - :white_check_mark: test-sdk-dfu

<details><summary>Disabled integration tests</summary>

- 
   - desktop52_verification
   - doc-internal
   - test_ble_nrf_config
   - test-fw-nrfconnect-apps
   - test-fw-nrfconnect-ble_mesh
   - test-fw-nrfconnect-ble_samples
   - test-fw-nrfconnect-boot
   - test-fw-nrfconnect-fem
   - test-fw-nrfconnect-nfc
   - test-fw-nrfconnect-nrf-iot_libmodem-nrf
   - test-fw-nrfconnect-nrf-iot_lwm2m
   - test-fw-nrfconnect-nrf-iot_mosh
   - test-fw-nrfconnect-nrf-iot_positioning
   - test-fw-nrfconnect-nrf-iot_samples
   - test-fw-nrfconnect-nrf-iot_serial_lte_modem
   - test-fw-nrfconnect-nrf-iot_thingy91
   - test-fw-nrfconnect-nrf-iot_zephyr_lwm2m
   - test-fw-nrfconnect-proprietary_esb
   - test-fw-nrfconnect-ps
   - test-fw-nrfconnect-rpc
   - test-fw-nrfconnect-rs
   - test-fw-nrfconnect-thread
   - test-fw-nrfconnect-zigbee
   - test-low-level
   - test-sdk-audio
   - test-sdk-mcuboot
   - test-sdk-pmic-samples
   - test-sdk-wifi
   - test-secdom-samples-public
</details>



*Note: This message is automatically posted and updated by the CI*
author_association: CONTRIBUTOR
user: login: github-actions[bot]
created_at: 2025-03-10T11:42:20Z
body: You can find the documentation preview for this PR [here](https://ncsdoc.z6.web.core.windows.net/PR-20821/).

author_association: NONE
user: login: degjorva
created_at: 2025-03-14T08:39:15Z
body: Rebase
author_association: CONTRIBUTOR
user: login: sonarqubecloud[bot]
created_at: 2025-03-14T08:45:39Z
body: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=nrfconnect_sdk-nrf&pullRequest=20821) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 New issues](https://sonarcloud.io/project/issues?id=nrfconnect_sdk-nrf&pullRequest=20821&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=nrfconnect_sdk-nrf&pullRequest=20821&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=nrfconnect_sdk-nrf&pullRequest=20821&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=nrfconnect_sdk-nrf&pullRequest=20821&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=nrfconnect_sdk-nrf&pullRequest=20821&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=nrfconnect_sdk-nrf&pullRequest=20821)


author_association: NONE