CC3XX: Separate RNG, Entropy and TRNG modules

Follow the logic where RNG exposes methods to access
randomness, entropy exposes a SP800-90B compliant
entropy source and TRNG just deals with the hardware
regarded as a noise source.

Signed-off-by: Antonio de Angelis <antonio.deangelis@arm.com>
Change-Id: I4c2aca6a262cd66ff69341322bf442755a41ef0b
diff --git a/platform/ext/target/arm/drivers/cc3xx/low_level_driver/CMakeLists.txt b/platform/ext/target/arm/drivers/cc3xx/low_level_driver/CMakeLists.txt
index 806ce7e..e83a422 100644
--- a/platform/ext/target/arm/drivers/cc3xx/low_level_driver/CMakeLists.txt
+++ b/platform/ext/target/arm/drivers/cc3xx/low_level_driver/CMakeLists.txt
@@ -38,6 +38,7 @@
         src/cc3xx_ecdh.c
         src/cc3xx_dcu.c
         src/cc3xx_trng.c
+        src/cc3xx_entropy.c
         ../common/cc3xx_stdlib.c
 )
 
diff --git a/platform/ext/target/arm/drivers/cc3xx/low_level_driver/include/cc3xx_entropy.h b/platform/ext/target/arm/drivers/cc3xx/low_level_driver/include/cc3xx_entropy.h
new file mode 100644
index 0000000..3dd60dd
--- /dev/null
+++ b/platform/ext/target/arm/drivers/cc3xx/low_level_driver/include/cc3xx_entropy.h
@@ -0,0 +1,58 @@
+/*
+ * SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef CC3XX_ENTROPY_H
+#define CC3XX_ENTROPY_H
+
+#include "cc3xx_error.h"
+#include "cc3xx_trng.h"
+
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CC3XX_ENTROPY_SIZE (CC3XX_TRNG_SAMPLE_SIZE)
+
+/**
+ * @brief                       SP800-90B section 4.4 recommends two continuous health tests
+ *                              to be performed at startup and during normal operation of the
+ *                              noise source to verify the quality ot the entropy bits produced,
+ *                              namely the Repetition Count Test (4.4.1) and Adaptive Proportion
+ *                              Test (4.4.2)
+ *
+ * @param[in] enable            Set to \a true to put the RNG entropy source in SP800-90B compatible
+ *                              mode, i.e. enable continuous health tests as recommended by SP800-90B
+ *
+ * @return cc3xx_err_t          CC3XX_ERR_SUCCESS on success, or
+ *                              CC3XX_ERR_NOT_IMPLEMENTED in case the firmware is built
+ *                              without support for the continuous health tests, i.e.
+ *                              \a CC3XX_CONFIG_RNG_CONTINUOUS_HEALTH_TESTS_ENABLE is not
+ *                              set in the CC3XX configuration \a cc3xx_config.h
+ */
+cc3xx_err_t cc3xx_lowlevel_entropy_sp800_90b_mode(bool enable);
+
+/**
+ * @brief                        Requires an amount of entropy from the TRNG
+ *
+ * @param[out] entropy           Buffer containing the requested entropy
+ * @param[in]  entropy_len       Size in bytes of the \p entropy buffer. Must be an
+ *                               integer multiple of \def CC3XX_ENTROPY_SIZE
+ *
+ * @return                       CC3XX_ERR_SUCCESS on success, another
+ *                               cc3xx_err_t on error.
+ */
+cc3xx_err_t cc3xx_lowlevel_entropy_get(uint32_t *entropy, size_t entropy_len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CC3XX_ENTROPY_H */
diff --git a/platform/ext/target/arm/drivers/cc3xx/low_level_driver/include/cc3xx_rng.h b/platform/ext/target/arm/drivers/cc3xx/low_level_driver/include/cc3xx_rng.h
index 77ab6a4..e895529 100644
--- a/platform/ext/target/arm/drivers/cc3xx/low_level_driver/include/cc3xx_rng.h
+++ b/platform/ext/target/arm/drivers/cc3xx/low_level_driver/include/cc3xx_rng.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2025, The TrustedFirmware-M Contributors. All rights reserved.
+ * SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -9,7 +9,6 @@
 #define CC3XX_RNG_H
 
 #include "cc3xx_error.h"
-#include "cc3xx_trng.h"
 
 #include <stdint.h>
 #include <stddef.h>
@@ -29,36 +28,6 @@
 };
 
 /**
- * @brief                       SP800-90B section 4.4 recommends two continuous health tests
- *                              to be performed at startup and during normal operation of the
- *                              noise source to verify the quality ot the entropy bits produced,
- *                              namely the Repetition Count Test (4.4.1) and Adaptive Proportion
- *                              Test (4.4.2)
- *
- * @param[in] enable            Set to \a true to put the RNG entropy source in SP800-90B compatible
- *                              mode, i.e. enable continuous health tests as recommended by SP800-90B
- *
- * @return cc3xx_err_t          CC3XX_ERR_SUCCESS on success, or
- *                              CC3XX_ERR_NOT_IMPLEMENTED in case the firmware is built
- *                              without support for the continuous health tests, i.e.
- *                              \a CC3XX_CONFIG_RNG_CONTINUOUS_HEALTH_TESTS_ENABLE is not
- *                              set in the CC3XX configuration \a cc3xx_config.h
- */
-cc3xx_err_t cc3xx_lowlevel_rng_sp800_90b_mode(bool enable);
-
-/**
- * @brief                        Requires an amount of entropy from the TRNG
- *
- * @param[out] entropy           Buffer containing the requested entropy
- * @param[in]  entropy_len       Size in bytes of the \p entropy buffer. Must be an
- *                               integer multiple of \def CC3XX_RNG_ENTROPY_SIZE
- *
- * @return                       CC3XX_ERR_SUCCESS on success, another
- *                               cc3xx_err_t on error.
- */
-cc3xx_err_t cc3xx_lowlevel_rng_get_entropy(uint32_t *entropy, size_t entropy_len);
-
-/**
  * @brief                        Get random bytes from the CC3XX TRNG.
  *
  * @note                         This function may take a variable amount of
diff --git a/platform/ext/target/arm/drivers/cc3xx/low_level_driver/include/cc3xx_trng.h b/platform/ext/target/arm/drivers/cc3xx/low_level_driver/include/cc3xx_trng.h
index 5dd6427..b9fb87e 100644
--- a/platform/ext/target/arm/drivers/cc3xx/low_level_driver/include/cc3xx_trng.h
+++ b/platform/ext/target/arm/drivers/cc3xx/low_level_driver/include/cc3xx_trng.h
@@ -21,9 +21,9 @@
 
 /**
  * @brief Size in bytes of the generated entropy per each generation from the TRNG
- *        It is equal to the sizeof(P_CC3XX->rng.ehr_data)
+ *
  */
-#define CC3XX_RNG_ENTROPY_SIZE (sizeof(P_CC3XX->rng.ehr_data))
+#define CC3XX_TRNG_SAMPLE_SIZE (sizeof(P_CC3XX->rng.ehr_data))
 
 #ifndef __PACKED_ENUM
 #define __PACKED_ENUM enum __attribute__((packed))
@@ -94,17 +94,18 @@
 void cc3xx_lowlevel_trng_set_hw_test_bypass(bool bypass_autocorr, bool bypass_crngt, bool bypass_vnc);
 
 /**
- * @brief                       Reads the entropy out of the TRNG
+ * @brief                       Reads the sample out of the TRNG
  *
  * @param[out] buf              Output buffer, word aligned, into which the entropy is read
  * @param[in]  word_count       Size in words of the \p buf output buffer, must be equal to
- *                              the number of words of P_CC3XX->rng.ehr_data
+ *                              the number of words of P_CC3XX->rng.ehr_data, i.e. CC3XX_TRNG_SAMPLE_SIZE
+ *                              when expressed in bytes
  *
  * @return cc3xx_err_t          CC3XX_ERR_SUCCESS on success, CC3XX_ERR_RNG_TOO_MANY_ATTEMPTS in
  *                              case errors have been detected on each generation. The maximum
  *                              number of generations is controlled by CC3XX_CONFIG_RNG_MAX_ATTEMPTS
  */
-cc3xx_err_t cc3xx_lowlevel_trng_get_entropy(uint32_t *buf, size_t word_count);
+cc3xx_err_t cc3xx_lowlevel_trng_get_sample(uint32_t *buf, size_t word_count);
 
 /**
  * @brief                       Initialises the TRNG before a call to \a cc3xx_lowlevel_trng_get_entropy
diff --git a/platform/ext/target/arm/drivers/cc3xx/low_level_driver/src/cc3xx_entropy.c b/platform/ext/target/arm/drivers/cc3xx/low_level_driver/src/cc3xx_entropy.c
new file mode 100644
index 0000000..fb70f66
--- /dev/null
+++ b/platform/ext/target/arm/drivers/cc3xx/low_level_driver/src/cc3xx_entropy.c
@@ -0,0 +1,261 @@
+/*
+ * SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef CC3XX_CONFIG_FILE
+#include "cc3xx_config.h"
+#else
+#include CC3XX_CONFIG_FILE
+#endif
+
+#include "cc3xx_error.h"
+
+#ifdef CC3XX_CONFIG_RNG_EXTERNAL_TRNG
+#include "cc3xx_rng_external_trng.h"
+#else
+#include "cc3xx_trng.h"
+#endif /* CC3XX_CONFIG_RNG_EXTERNAL_TRNG */
+
+#include <assert.h>
+#include <stdint.h>
+#include <stddef.h>
+#include <string.h>
+#include <stdbool.h>
+
+#include "fatal_error.h"
+
+#ifdef CC3XX_CONFIG_RNG_EXTERNAL_ZERO_COUNT
+int32_t count_zero_bits_external(uint8_t *, size_t, uint32_t *);
+#endif /* CC3XX_CONFIG_RNG_EXTERNAL_ZERO_COUNT */
+
+/* Specific defines required to enable Continuous testing as per NIST SP800-90B */
+#define BYTES_TO_BITS(x) ((x)*8)
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+
+/**
+ * @brief Window size (W) for the Adaptive Proportion Test in SP800-90B section 4.4.2
+ *
+ * @note For binary entropy sources this is fixed to 1024 bits
+ *
+ */
+#define SP800_90B_ADAPTIVE_PROPORTION_WINDOW_SIZE (1024UL)
+
+/**
+ * @brief Cutoff rate (C) for the Adaptive Proportion Test in SP800-90B section 4.4.2
+ *
+ * @note This is computed using the formula:
+ *
+ *       CRITBINOM(W, power(2,(-H)), 1-a) with W = 1024, a = 2^(-40), H = 0.5 bits/sample
+ *
+ *       The cutoff rate is chosen such that the probability of observing B identical
+ *       samples in an observation window of length W is Pr{B >= C} < a
+ */
+#define SP800_90B_ADAPTIVE_PROPORTION_CUTOFF_RATE (821UL)
+
+/**
+ * @brief Cutoff rate (C) for the Repetition Count Test in SP800-90B section 4.4.1
+ *
+ * @note  This is computed using the formula:
+ *
+ *        1 + ceil(-log(2,a) / H) with a = 2^(-40), H = 0.5 bits/sample a
+ *
+ *        The cutoff rate is chosen such that C is the smallest integer satisfying
+ *        a >= 2^(-H * (C-1)), i.e. the probability of getting C consecutive identical
+ *        samples is at most a
+ */
+#define SP800_90B_REPETITION_COUNT_CUTOFF_RATE (81UL)
+
+/* Static context of the TRNG continuous health tests */
+static struct health_tests_ctx_t {
+    size_t total_bits_count;        /*!< Number of total bits observed for the Adaptive Proportion Test window */
+    size_t number_of_0s;            /*!< Number of zeros observed in the Adaptive Proportion Test window */
+    size_t number_of_contiguous_0s; /*!< Number of contiguous zeros observed in the Repetition Count Test */
+    size_t number_of_contiguous_1s; /*!< Number of contiguous ones observed in the Repetition Count Test */
+    bool   continuous;              /*!< Continous Health tests enabled, i.e. both Adaptive Proportion and Repetition Count */
+    bool   startup;                 /*!< Indicates whether a full startup test is performed on next call to get_entropy */
+} g_entropy_tests = {0};
+
+/* See https://en.wikipedia.org/wiki/Hamming_weight */
+static size_t popcount32(uint32_t x)
+{
+    const uint32_t m1  = 0x55555555; /* binary: 0101 ... */
+    const uint32_t m2  = 0x33333333; /* binary: 00110011 ... */
+    const uint32_t m4  = 0x0f0f0f0f; /* binary:  4 zeros,  4 ones ... */
+    const uint32_t h01 = 0x01010101; /* Sum of 256 to the power of 0, 1, 2, 3 ...  */
+    x -= (x >> 1) & m1;              /* put count of each 2 bits into those 2 bits */
+    x = (x & m2) + ((x >> 2) & m2);  /* put count of each 4 bits into those 4 bits */
+    x = (x + (x >> 4)) & m4;         /* put count of each 8 bits into those 8 bits */
+    return (x * h01) >> 24;          /* returns left 8 bits of x + (x<<8) + (x<<16) + ... */
+}
+
+static cc3xx_err_t count_zero_bits(uint8_t *buf, size_t buf_len, uint32_t *zero_count)
+{
+#ifndef CC3XX_CONFIG_RNG_EXTERNAL_ZERO_COUNT
+    assert((((uintptr_t) buf & 0x3) == 0) && ((buf_len & 0x3) == 0));
+
+    for (size_t i = 0; i < buf_len / sizeof(uint32_t); i++) {
+        *zero_count += BYTES_TO_BITS(sizeof(uint32_t)) - popcount32(((uint32_t *)buf)[i]);
+    }
+    return CC3XX_ERR_SUCCESS;
+#else
+    return count_zero_bits_external(buf, buf_len, zero_count);
+#endif /* CC3XX_CONFIG_RNG_EXTERNAL_ZERO_COUNT */
+}
+
+/* SP800-90B section 4.4.1 */
+static cc3xx_err_t repetition_count_test(const uint32_t *buf, size_t buf_size, size_t *number_of_contiguous_0s, size_t *number_of_contiguous_1s)
+{
+    for (size_t idx = 0; idx < buf_size; idx++) {
+        uint8_t byte = ((uint8_t *)buf)[idx];
+        for (size_t bit = 0; bit < 8; bit++) {
+            if ((byte >> bit) & 0x01) {
+                (*number_of_contiguous_1s)++;
+                *number_of_contiguous_0s = 0;
+            } else {
+                (*number_of_contiguous_0s)++;
+                *number_of_contiguous_1s = 0;
+            }
+            if (((*number_of_contiguous_0s) == SP800_90B_REPETITION_COUNT_CUTOFF_RATE) ||
+                ((*number_of_contiguous_1s) == SP800_90B_REPETITION_COUNT_CUTOFF_RATE)) {
+                FATAL_ERR(CC3XX_ERR_RNG_SP800_90B_REPETITION_COUNT_TEST_FAIL);
+                return CC3XX_ERR_RNG_SP800_90B_REPETITION_COUNT_TEST_FAIL;
+            }
+        }
+    }
+
+    return CC3XX_ERR_SUCCESS;
+}
+
+/* SP800-90B section 4.4.2 */
+static cc3xx_err_t adaptive_proportion_test(const uint32_t *buf, size_t buf_size, size_t *total_bits_count, size_t *number_of_0s)
+{
+    while (buf_size) {
+
+        /* Compute the words that we still have to count until the end of the window */
+        const size_t words_left_to_count =
+            (SP800_90B_ADAPTIVE_PROPORTION_WINDOW_SIZE - *total_bits_count) / BYTES_TO_BITS(sizeof(uint32_t));
+        const size_t bytes_left_to_count = words_left_to_count * sizeof(uint32_t);
+        const size_t counted_bytes = MIN(buf_size, bytes_left_to_count);
+
+        count_zero_bits((uint8_t *)buf, counted_bytes, (uint32_t *)number_of_0s);
+
+        *total_bits_count += BYTES_TO_BITS(counted_bytes);
+        buf_size -= counted_bytes;
+
+        if (*total_bits_count == SP800_90B_ADAPTIVE_PROPORTION_WINDOW_SIZE) {
+            if ((*number_of_0s >= SP800_90B_ADAPTIVE_PROPORTION_CUTOFF_RATE) ||
+                ((SP800_90B_ADAPTIVE_PROPORTION_WINDOW_SIZE - *number_of_0s) >=
+                                                    SP800_90B_ADAPTIVE_PROPORTION_CUTOFF_RATE)) {
+                FATAL_ERR(CC3XX_ERR_RNG_SP800_90B_ADAPTIVE_PROPORTION_TEST_FAIL);
+                return CC3XX_ERR_RNG_SP800_90B_ADAPTIVE_PROPORTION_TEST_FAIL;
+            } else {
+                *number_of_0s = 0;
+                *total_bits_count = 0;
+            }
+        }
+
+        /* Move the buf pointer in case we still have to process bits from this entropy collection */
+        buf += counted_bytes / sizeof(uint32_t);
+    }
+
+    return CC3XX_ERR_SUCCESS;
+}
+
+/* SP800-90B section 4.4 */
+static cc3xx_err_t continuous_health_test(const uint32_t *buf, size_t buf_size, struct health_tests_ctx_t *ctx)
+{
+    cc3xx_err_t err = repetition_count_test(
+        buf, buf_size, &(ctx->number_of_contiguous_0s), &(ctx->number_of_contiguous_1s));
+
+    if (err != CC3XX_ERR_SUCCESS) {
+        return err;
+    }
+
+    return adaptive_proportion_test(buf, buf_size, &(ctx->total_bits_count), &(ctx->number_of_0s));
+}
+
+/**
+ * @brief To be performed on the first call to get_entropy(),
+ *        after the cc3xx_lowlevel_trng_init() is completed
+ *
+ * @return cc3xx_err_t
+ */
+static cc3xx_err_t startup_test(size_t entropy_byte_size)
+{
+    assert(entropy_byte_size == CC3XX_TRNG_SAMPLE_SIZE);
+
+    cc3xx_err_t err;
+    uint32_t random_bits[entropy_byte_size / sizeof(uint32_t)];
+
+    /* Collects 528 sample bytes on startup for testing */
+    for (size_t i = 0; i < 22; i++) {
+        err = cc3xx_lowlevel_trng_get_sample(random_bits, entropy_byte_size / sizeof(uint32_t));
+        if (err != CC3XX_ERR_SUCCESS) {
+            break;
+        }
+    }
+
+    return err;
+}
+
+cc3xx_err_t cc3xx_lowlevel_entropy_sp800_90b_mode(bool enable)
+{
+    if (enable) {
+        g_entropy_tests = (struct health_tests_ctx_t){.startup = true};
+    } else {
+        g_entropy_tests = (struct health_tests_ctx_t){0};
+    }
+
+    cc3xx_lowlevel_trng_sp800_90b_mode(enable);
+
+    return CC3XX_ERR_SUCCESS;
+}
+
+cc3xx_err_t cc3xx_lowlevel_entropy_get(uint32_t *entropy, size_t entropy_len)
+{
+    cc3xx_err_t err;
+    size_t num_words = 0;
+
+    assert((entropy_len % CC3XX_TRNG_SAMPLE_SIZE) == 0);
+
+    err = cc3xx_lowlevel_trng_validate_config();
+    if (err != CC3XX_ERR_SUCCESS) {
+        return err;
+    }
+
+    cc3xx_lowlevel_trng_init();
+
+    if (g_entropy_tests.startup) {
+        err = startup_test(CC3XX_TRNG_SAMPLE_SIZE);
+        if (err != CC3XX_ERR_SUCCESS) {
+            goto cleanup;
+        }
+        g_entropy_tests.startup = false;
+    }
+
+    for (size_t i = 0; i < entropy_len / CC3XX_TRNG_SAMPLE_SIZE; i++) {
+
+        err = cc3xx_lowlevel_trng_get_sample(&entropy[num_words], CC3XX_TRNG_SAMPLE_SIZE / sizeof(uint32_t));
+        if (err != CC3XX_ERR_SUCCESS) {
+            goto cleanup;
+        }
+
+        if (g_entropy_tests.continuous) {
+            err = continuous_health_test(
+                        &entropy[num_words], CC3XX_TRNG_SAMPLE_SIZE, &g_entropy_tests);
+            if (err != CC3XX_ERR_SUCCESS) {
+                goto cleanup;
+            }
+        }
+
+        num_words += CC3XX_TRNG_SAMPLE_SIZE / sizeof(uint32_t);
+    }
+
+cleanup:
+    cc3xx_lowlevel_trng_finish();
+
+    return err;
+}
diff --git a/platform/ext/target/arm/drivers/cc3xx/low_level_driver/src/cc3xx_rng.c b/platform/ext/target/arm/drivers/cc3xx/low_level_driver/src/cc3xx_rng.c
index 50139a3..f3fb2d7 100644
--- a/platform/ext/target/arm/drivers/cc3xx/low_level_driver/src/cc3xx_rng.c
+++ b/platform/ext/target/arm/drivers/cc3xx/low_level_driver/src/cc3xx_rng.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2025, The TrustedFirmware-M Contributors. All rights reserved.
+ * SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -16,6 +16,7 @@
 #include "cc3xx_error.h"
 #include "cc3xx_dev.h"
 #include "cc3xx_stdlib.h"
+#include "cc3xx_entropy.h"
 #if defined(CC3XX_CONFIG_RNG_DRBG_HMAC)
 #include "cc3xx_drbg_hmac.h"
 #elif defined(CC3XX_CONFIG_RNG_DRBG_HASH)
@@ -32,203 +33,7 @@
 
 #include "fatal_error.h"
 
-#ifdef CC3XX_CONFIG_RNG_EXTERNAL_TRNG
-#include "cc3xx_rng_external_trng.h"
-#endif /* CC3XX_CONFIG_RNG_EXTERNAL_TRNG */
-
-#ifdef CC3XX_CONFIG_RNG_EXTERNAL_ZERO_COUNT
-int32_t count_zero_bits_external(uint8_t *, size_t, uint32_t *);
-#endif /* CC3XX_CONFIG_RNG_EXTERNAL_ZERO_COUNT */
-
-/* Specific defines required to enable Continuous testing as per NIST SP800-90B */
-#define BYTES_TO_BITS(x) ((x)*8)
-#define MIN(a, b) ((a) < (b) ? (a) : (b))
-
-/**
- * @brief Window size (W) for the Adaptive Proportion Test in SP800-90B section 4.4.2
- *
- * @note For binary entropy sources this is fixed to 1024 bits
- *
- */
-#define SP800_90B_ADAPTIVE_PROPORTION_WINDOW_SIZE (1024UL)
-
-/**
- * @brief Cutoff rate (C) for the Adaptive Proportion Test in SP800-90B section 4.4.2
- *
- * @note This is computed using the formula:
- *
- *       CRITBINOM(W, power(2,(-H)), 1-a) with W = 1024, a = 2^(-40), H = 0.5 bits/sample
- *
- *       The cutoff rate is chosen such that the probability of observing B identical
- *       samples in an observation window of length W is Pr{B >= C} < a
- */
-#define SP800_90B_ADAPTIVE_PROPORTION_CUTOFF_RATE (821UL)
-
-/**
- * @brief Cutoff rate (C) for the Repetition Count Test in SP800-90B section 4.4.1
- *
- * @note  This is computed using the formula:
- *
- *        1 + ceil(-log(2,a) / H) with a = 2^(-40), H = 0.5 bits/sample a
- *
- *        The cutoff rate is chosen such that C is the smallest integer satisfying
- *        a >= 2^(-H * (C-1)), i.e. the probability of getting C consecutive identical
- *        samples is at most a
- */
-#define SP800_90B_REPETITION_COUNT_CUTOFF_RATE (81UL)
-
 #ifdef CC3XX_CONFIG_RNG_ENABLE
-#if defined(CC3XX_CONFIG_RNG_CONTINUOUS_HEALTH_TESTS_ENABLE)
-/* Static context of the TRNG continuous health tests */
-static struct health_tests_ctx_t {
-    size_t total_bits_count;        /*!< Number of total bits observed for the Adaptive Proportion Test window */
-    size_t number_of_0s;            /*!< Number of zeros observed in the Adaptive Proportion Test window */
-    size_t number_of_contiguous_0s; /*!< Number of contiguous zeros observed in the Repetition Count Test */
-    size_t number_of_contiguous_1s; /*!< Number of contiguous ones observed in the Repetition Count Test */
-    bool   continuous;              /*!< Continous Health tests enabled, i.e. both Adaptive Proportion and Repetition Count */
-    bool   startup;                 /*!< Indicates whether a full startup test is performed on next call to get_entropy */
-} g_trng_tests = {0};
-
-/* See https://en.wikipedia.org/wiki/Hamming_weight */
-static size_t popcount32(uint32_t x)
-{
-    const uint32_t m1  = 0x55555555; /* binary: 0101 ... */
-    const uint32_t m2  = 0x33333333; /* binary: 00110011 ... */
-    const uint32_t m4  = 0x0f0f0f0f; /* binary:  4 zeros,  4 ones ... */
-    const uint32_t h01 = 0x01010101; /* Sum of 256 to the power of 0, 1, 2, 3 ...  */
-    x -= (x >> 1) & m1;              /* put count of each 2 bits into those 2 bits */
-    x = (x & m2) + ((x >> 2) & m2);  /* put count of each 4 bits into those 4 bits */
-    x = (x + (x >> 4)) & m4;         /* put count of each 8 bits into those 8 bits */
-    return (x * h01) >> 24;          /* returns left 8 bits of x + (x<<8) + (x<<16) + ... */
-}
-
-static cc3xx_err_t count_zero_bits(uint8_t *buf, size_t buf_len, uint32_t *zero_count)
-{
-#ifndef CC3XX_CONFIG_RNG_EXTERNAL_ZERO_COUNT
-    assert((((uintptr_t) buf & 0x3) == 0) && ((buf_len & 0x3) == 0));
-
-    for (size_t i = 0; i < buf_len / sizeof(uint32_t); i++) {
-        *zero_count += BYTES_TO_BITS(sizeof(uint32_t)) - popcount32(((uint32_t *)buf)[i]);
-    }
-    return CC3XX_ERR_SUCCESS;
-#else
-    return count_zero_bits_external(buf, buf_len, zero_count);
-#endif /* CC3XX_CONFIG_RNG_EXTERNAL_ZERO_COUNT */
-}
-
-/* SP800-90B section 4.4.1 */
-static cc3xx_err_t repetition_count_test(const uint32_t *buf, size_t buf_size, size_t *number_of_contiguous_0s, size_t *number_of_contiguous_1s)
-{
-    for (size_t idx = 0; idx < buf_size; idx++) {
-        uint8_t byte = ((uint8_t *)buf)[idx];
-        for (size_t bit = 0; bit < 8; bit++) {
-            if ((byte >> bit) & 0x01) {
-                (*number_of_contiguous_1s)++;
-                *number_of_contiguous_0s = 0;
-            } else {
-                (*number_of_contiguous_0s)++;
-                *number_of_contiguous_1s = 0;
-            }
-            if (((*number_of_contiguous_0s) == SP800_90B_REPETITION_COUNT_CUTOFF_RATE) ||
-                ((*number_of_contiguous_1s) == SP800_90B_REPETITION_COUNT_CUTOFF_RATE)) {
-                FATAL_ERR(CC3XX_ERR_RNG_SP800_90B_REPETITION_COUNT_TEST_FAIL);
-                return CC3XX_ERR_RNG_SP800_90B_REPETITION_COUNT_TEST_FAIL;
-            }
-        }
-    }
-
-    return CC3XX_ERR_SUCCESS;
-}
-
-/* SP800-90B section 4.4.2 */
-static cc3xx_err_t adaptive_proportion_test(const uint32_t *buf, size_t buf_size, size_t *total_bits_count, size_t *number_of_0s)
-{
-    while (buf_size) {
-
-        /* Compute the words that we still have to count until the end of the window */
-        const size_t words_left_to_count =
-            (SP800_90B_ADAPTIVE_PROPORTION_WINDOW_SIZE - *total_bits_count) / BYTES_TO_BITS(sizeof(uint32_t));
-        const size_t bytes_left_to_count = words_left_to_count * sizeof(uint32_t);
-        const size_t counted_bytes = MIN(buf_size, bytes_left_to_count);
-
-        count_zero_bits((uint8_t *)buf, counted_bytes, (uint32_t *)number_of_0s);
-
-        *total_bits_count += BYTES_TO_BITS(counted_bytes);
-        buf_size -= counted_bytes;
-
-        if (*total_bits_count == SP800_90B_ADAPTIVE_PROPORTION_WINDOW_SIZE) {
-            if ((*number_of_0s >= SP800_90B_ADAPTIVE_PROPORTION_CUTOFF_RATE) ||
-                ((SP800_90B_ADAPTIVE_PROPORTION_WINDOW_SIZE - *number_of_0s) >=
-                                                    SP800_90B_ADAPTIVE_PROPORTION_CUTOFF_RATE)) {
-                FATAL_ERR(CC3XX_ERR_RNG_SP800_90B_ADAPTIVE_PROPORTION_TEST_FAIL);
-                return CC3XX_ERR_RNG_SP800_90B_ADAPTIVE_PROPORTION_TEST_FAIL;
-            } else {
-                *number_of_0s = 0;
-                *total_bits_count = 0;
-            }
-        }
-
-        /* Move the buf pointer in case we still have to process bits from this entropy collection */
-        buf += counted_bytes / sizeof(uint32_t);
-    }
-
-    return CC3XX_ERR_SUCCESS;
-}
-
-/* SP800-90B section 4.4 */
-static cc3xx_err_t continuous_health_test(const uint32_t *buf, size_t buf_size, struct health_tests_ctx_t *ctx)
-{
-    cc3xx_err_t err = repetition_count_test(
-        buf, buf_size, &(ctx->number_of_contiguous_0s), &(ctx->number_of_contiguous_1s));
-
-    if (err != CC3XX_ERR_SUCCESS) {
-        return err;
-    }
-
-    return adaptive_proportion_test(buf, buf_size, &(ctx->total_bits_count), &(ctx->number_of_0s));
-}
-
-/**
- * @brief To be performed on the first call to get_entropy(),
- *        after the cc3xx_lowlevel_trng_init() is completed
- *
- * @return cc3xx_err_t
- */
-static cc3xx_err_t startup_test(size_t entropy_byte_size)
-{
-    assert(entropy_byte_size == sizeof(P_CC3XX->rng.ehr_data));
-
-    cc3xx_err_t err;
-    uint32_t random_bits[entropy_byte_size / sizeof(uint32_t)];
-
-    /* Collects 528 random bytes on startup for testing */
-    for (size_t i = 0; i < 22; i++) {
-        err = trng_get_random(random_bits, entropy_byte_size / sizeof(uint32_t));
-        if (err != CC3XX_ERR_SUCCESS) {
-            break;
-        }
-    }
-
-    return err;
-}
-#endif /* CC3XX_CONFIG_RNG_CONTINUOUS_HEALTH_TESTS_ENABLE */
-
-cc3xx_err_t cc3xx_lowlevel_rng_sp800_90b_mode(bool enable)
-{
-#if defined(CC3XX_CONFIG_RNG_CONTINUOUS_HEALTH_TESTS_ENABLE)
-    if (enable) {
-        g_trng_tests = (struct health_tests_ctx_t){.startup = true};
-    } else {
-        g_trng_tests = (struct health_tests_ctx_t){0};
-    }
-
-    cc3xx_lowlevel_trng_sp800_90b_mode(enable);
-
-    return CC3XX_ERR_SUCCESS;
-#else
-    return CC3XX_ERR_NOT_IMPLEMENTED;
-#endif
-}
 
 /* Define function pointers to generically access DRBG functionalities */
 #if defined(CC3XX_CONFIG_RNG_DRBG_HMAC)
@@ -290,7 +95,7 @@
     if (!lfsr->seed_done) {
         cc3xx_err_t err;
         do {
-            err = cc3xx_lowlevel_rng_get_entropy(lfsr->entropy, sizeof(lfsr->entropy));
+            err = cc3xx_lowlevel_entropy_get(lfsr->entropy, sizeof(lfsr->entropy));
         } while (err != CC3XX_ERR_SUCCESS);
 
         lfsr->seed_done = true;
@@ -324,11 +129,10 @@
 
     if (!g_drbg.seed_done) {
 
-        /* Get a 24-byte seed from the TRNG */
-        err = cc3xx_lowlevel_rng_get_entropy(entropy, sizeof(entropy));
-        if (err != CC3XX_ERR_SUCCESS) {
-            return err;
-        }
+        /* Get 24 bytes of entropy */
+        do {
+            err = cc3xx_lowlevel_entropy_get(entropy, sizeof(entropy));
+        } while (err != CC3XX_ERR_SUCCESS);
 
         /* Call the seeding API of the desired drbg */
         err = g_drbg.init(&g_drbg.state,
@@ -346,11 +150,10 @@
     /* Add re-seeding capabilities */
     if (g_drbg.state.reseed_counter == UINT32_MAX) {
 
-        /* Get a 24-byte seed from the TRNG */
-        err = cc3xx_lowlevel_rng_get_entropy(entropy, sizeof(entropy));
-        if (err != CC3XX_ERR_SUCCESS) {
-            return err;
-        }
+        /* Get 24 bytes of entropy */
+        do {
+            err = cc3xx_lowlevel_entropy_get(entropy, sizeof(entropy));
+        } while (err != CC3XX_ERR_SUCCESS);
 
         err = g_drbg.reseed(&g_drbg.state,
                     (const uint8_t *)entropy, sizeof(entropy), NULL, 0);
@@ -370,61 +173,6 @@
     return err;
 }
 
-cc3xx_err_t cc3xx_lowlevel_rng_get_entropy(uint32_t *entropy, size_t entropy_len)
-{
-    cc3xx_err_t err;
-    size_t num_words = 0;
-
-    assert((entropy_len % sizeof(P_CC3XX->rng.ehr_data)) == 0);
-
-    err = cc3xx_lowlevel_trng_validate_config();
-    if (err != CC3XX_ERR_SUCCESS) {
-        return err;
-    }
-
-    cc3xx_lowlevel_trng_init();
-
-    /* This is guarded by the continuous tests define because that is the
-     * only type of testing that is being implemented by the startup_test
-     * function although the spec allows for startup tests to be extended
-     * by vendors if required
-     */
-#if defined(CC3XX_CONFIG_RNG_CONTINUOUS_HEALTH_TESTS_ENABLE)
-    if (g_trng_tests.startup) {
-        err = startup_test(sizeof(P_CC3XX->rng.ehr_data));
-        if (err != CC3XX_ERR_SUCCESS) {
-            goto cleanup;
-        }
-        g_trng_tests.startup = false;
-    }
-#endif /* CC3XX_CONFIG_RNG_CONTINUOUS_HEALTH_TESTS_ENABLE */
-
-    for (size_t i = 0; i < entropy_len / sizeof(P_CC3XX->rng.ehr_data); i++) {
-
-        err = cc3xx_lowlevel_trng_get_entropy(&entropy[num_words], sizeof(P_CC3XX->rng.ehr_data) / sizeof(uint32_t));
-        if (err != CC3XX_ERR_SUCCESS) {
-            goto cleanup;
-        }
-
-#if defined(CC3XX_CONFIG_RNG_CONTINUOUS_HEALTH_TESTS_ENABLE)
-        if (g_trng_tests.continuous) {
-            err = continuous_health_test(
-                        (uint8_t *)&entropy[num_words], sizeof(P_CC3XX->rng.ehr_data), &g_trng_tests);
-            if (err != CC3XX_ERR_SUCCESS) {
-                goto cleanup;
-            }
-        }
-#endif /* CC3XX_CONFIG_RNG_CONTINUOUS_HEALTH_TESTS_ENABLE */
-
-        num_words += sizeof(P_CC3XX->rng.ehr_data) / sizeof(uint32_t);
-    }
-
-cleanup:
-    cc3xx_lowlevel_trng_finish();
-
-    return err;
-}
-
 cc3xx_err_t cc3xx_lowlevel_rng_get_random(uint8_t *buf, size_t length,
                                           enum cc3xx_rng_quality_t quality)
 {
diff --git a/platform/ext/target/arm/drivers/cc3xx/low_level_driver/src/cc3xx_trng.c b/platform/ext/target/arm/drivers/cc3xx/low_level_driver/src/cc3xx_trng.c
index cd4f701..8766e06 100644
--- a/platform/ext/target/arm/drivers/cc3xx/low_level_driver/src/cc3xx_trng.c
+++ b/platform/ext/target/arm/drivers/cc3xx/low_level_driver/src/cc3xx_trng.c
@@ -140,15 +140,15 @@
     return CC3XX_ERR_SUCCESS;
 }
 
-cc3xx_err_t cc3xx_lowlevel_trng_get_entropy(uint32_t *buf, size_t word_count)
+cc3xx_err_t cc3xx_lowlevel_trng_get_sample(uint32_t *buf, size_t word_count)
 {
     uint32_t attempt_count = 0;
     uint32_t idx;
 
     assert(word_count == sizeof(P_CC3XX->rng.ehr_data) / sizeof(uint32_t));
 
-    /* Wait until the RNG has finished. Any status other than 0x1 indicates
-     * that either the RNG hasn't finished or a statistical test has been
+    /* Wait until the TRNG has finished. Any status other than 0x1 indicates
+     * that either the TRNG hasn't finished or a statistical test has been
      * failed.
      */
     do {
diff --git a/platform/ext/target/arm/drivers/cc3xx/psa_driver_api/src/cc3xx_psa_entropy.c b/platform/ext/target/arm/drivers/cc3xx/psa_driver_api/src/cc3xx_psa_entropy.c
index 41ef966..0e0a82a 100644
--- a/platform/ext/target/arm/drivers/cc3xx/psa_driver_api/src/cc3xx_psa_entropy.c
+++ b/platform/ext/target/arm/drivers/cc3xx/psa_driver_api/src/cc3xx_psa_entropy.c
@@ -15,7 +15,7 @@
 #include <string.h>
 
 #include "cc3xx_psa_entropy.h"
-#include "cc3xx_rng.h"
+#include "cc3xx_entropy.h"
 #include "cc3xx_misc.h"
 
 /** @defgroup psa_entropy PSA driver entry points for entropy collection
@@ -31,7 +31,7 @@
 {
     cc3xx_err_t err;
     /* Integer multiple of entropy size*/
-    const size_t int_mult = (output_size / CC3XX_RNG_ENTROPY_SIZE) * CC3XX_RNG_ENTROPY_SIZE;
+    const size_t int_mult = (output_size / CC3XX_ENTROPY_SIZE) * CC3XX_ENTROPY_SIZE;
 
     CC3XX_ASSERT(output != NULL);
     CC3XX_ASSERT(output_size != 0);
@@ -40,16 +40,16 @@
         *estimate_bits = 0;
     }
 
-    /* Get a multiple of CC3XX_RNG_ENTROPY_SIZE bytes of entropy */
-    err = cc3xx_lowlevel_rng_get_entropy((uint32_t *)output, int_mult);
+    /* Get a multiple of CC3XX_ENTROPY_SIZE bytes of entropy */
+    err = cc3xx_lowlevel_entropy_get((uint32_t *)output, int_mult);
 
     if (err != CC3XX_ERR_SUCCESS) {
         return cc3xx_to_psa_err(err);
     }
 
-    if ((output_size % CC3XX_RNG_ENTROPY_SIZE) != 0) {
-        uint32_t last[CC3XX_RNG_ENTROPY_SIZE / sizeof(uint32_t)];
-        err = cc3xx_lowlevel_rng_get_entropy(last, sizeof(last));
+    if ((output_size % CC3XX_ENTROPY_SIZE) != 0) {
+        uint32_t last[CC3XX_ENTROPY_SIZE / sizeof(uint32_t)];
+        err = cc3xx_lowlevel_entropy_get(last, sizeof(last));
         if (err != CC3XX_ERR_SUCCESS) {
             return cc3xx_to_psa_err(err);
         }