BL1: Add an API for stateless access to noise source

Such stateless API is suitable for usage in pre-main where
global variables are not setup yet and for variables that
do not require cryptographic-quality randomness.

Signed-off-by: Antonio de Angelis <antonio.deangelis@arm.com>
Change-Id: I247247dbfdfc826ef654df46b40a4b1c5b8b0277
diff --git a/bl1/bl1_1/shared_lib/interface/bl1_random.h b/bl1/bl1_1/shared_lib/interface/bl1_random.h
index 6ec442b..73f249f 100644
--- a/bl1/bl1_1/shared_lib/interface/bl1_random.h
+++ b/bl1/bl1_1/shared_lib/interface/bl1_random.h
@@ -16,7 +16,7 @@
 #endif
 
 /**
- * @brief Generate random bytes of cryptographic quality
+ * @brief Generate random bytes of cryptographic quality, for example using DRBGs
  *
  * @param[out] output      Output buffer containing the random bytes
  * @param[in]  output_size Size in bytes of the \p output buffer to generate
@@ -27,7 +27,7 @@
 
 /**
  * @brief Generate random bytes fast, for example using LFSRs (Linear Feedback
- *        Shift Registers), which are not of cryptographic quality
+ *        Shift Registers), which are not of cryptographic quality, but are fast
  *
  * @note  Do *NOT* use this function to generate keys or other quantities where
  *        cryptographic-grade randomness is required
@@ -39,6 +39,25 @@
  */
 int32_t bl1_random_generate_fast(uint8_t *output, size_t output_size);
 
+/**
+ * @brief Generate random bytes by directly reading the underlying system noise source
+ *        without any particular guarantee of the cryptographic quality of the returned
+ *        random bytes
+ *
+ * @note  Do *NOT* use this function to generate keys or other quantities where
+ *        cryptographic-grade randomness is required
+ *
+ * @note  This function guarantees that no access to a global state will be required and
+ *        the global state (if present) won't be altered after the call ends, i.e. there
+ *        is no side effect on a global state triggered by a call to this function
+ *
+ * @param[out] output      Output buffer containing the random bytes
+ * @param[in]  output_size Size in bytes of the \p output buffer to generate
+ *
+ * @return int32_t 0 on success
+ */
+int32_t bl1_random_generate_noise_stateless(uint8_t *output, size_t output_size);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/platform/ext/target/arm/rse/common/bl1/cc3xx/cc3xx_rom_random.c b/platform/ext/target/arm/rse/common/bl1/cc3xx/cc3xx_rom_random.c
index 87199b4..3c23099 100644
--- a/platform/ext/target/arm/rse/common/bl1/cc3xx/cc3xx_rom_random.c
+++ b/platform/ext/target/arm/rse/common/bl1/cc3xx/cc3xx_rom_random.c
@@ -7,6 +7,8 @@
 
 #include "bl1_random.h"
 #include "cc3xx_rng.h"
+/* For direct reading of the noise source */
+#include "cc3xx_trng.h"
 
 int32_t bl1_random_generate_secure(uint8_t *output, size_t output_size)
 {
@@ -17,3 +19,20 @@
 {
     return cc3xx_lowlevel_rng_get_random(output, output_size, CC3XX_RNG_LFSR);
 }
+
+int32_t bl1_random_generate_noise_stateless(uint8_t *output, size_t output_size)
+{
+    uint32_t buf[CC3XX_TRNG_SAMPLE_SIZE / sizeof(uint32_t)];
+    cc3xx_err_t err;
+    size_t counter = 0;
+
+    for (counter = 0; counter < output_size; counter++) {
+        if ((counter % CC3XX_TRNG_SAMPLE_SIZE) == 0) {
+            do {
+                err = cc3xx_lowlevel_trng_get_sample_stateless(buf, sizeof(buf) / sizeof(uint32_t));
+            } while (err != CC3XX_ERR_SUCCESS);
+        }
+        output[counter] = ((uint8_t *)buf)[counter];
+    }
+    return 0;
+}
diff --git a/platform/ext/target/arm/rse/common/device/source/startup_rse_bl1_1.c b/platform/ext/target/arm/rse/common/device/source/startup_rse_bl1_1.c
index 3d682f4..c45ebc1 100644
--- a/platform/ext/target/arm/rse/common/device/source/startup_rse_bl1_1.c
+++ b/platform/ext/target/arm/rse/common/device/source/startup_rse_bl1_1.c
@@ -225,20 +225,12 @@
     };
 
     /* Redefine these, as at this point the constants haven't been loaded */
-    struct kmu_dev_cfg_t kmu_dev_cfg_s = {
-        .base = KMU_BASE_S
-    };
-    struct kmu_dev_t kmu_dev_s = {
-        .cfg = &(kmu_dev_cfg_s)
-    };
-    struct tram_dev_cfg_t tram_dev_cfg_s = {
-        .base = TRAM_BASE_S
-    };
-    struct tram_dev_t tram_dev_s = {&tram_dev_cfg_s};
-    struct lcm_dev_cfg_t lcm_dev_cfg_s = {
-        .base = LCM_BASE_S
-    };
-    struct lcm_dev_t lcm_dev_s = {&lcm_dev_cfg_s};
+    struct kmu_dev_cfg_t kmu_dev_cfg_s = {.base = KMU_BASE_S};
+    struct kmu_dev_t kmu_dev_s = {.cfg = &kmu_dev_cfg_s};
+    struct tram_dev_cfg_t tram_dev_cfg_s = {.base = TRAM_BASE_S};
+    struct tram_dev_t tram_dev_s = {.cfg = &tram_dev_cfg_s};
+    struct lcm_dev_cfg_t lcm_dev_cfg_s = {.base = LCM_BASE_S};
+    struct lcm_dev_t lcm_dev_s = {.cfg = &lcm_dev_cfg_s};
 
     stdio_is_initialized_reset();
 
@@ -248,7 +240,7 @@
     lcm_get_sp_enabled(&lcm_dev_s, &sp_enabled);
     lcm_get_lcs(&lcm_dev_s, &lcs);
 
-    bl1_random_generate_secure(prbg_seed, sizeof(prbg_seed));
+    bl1_random_generate_noise_stateless(prbg_seed, sizeof(prbg_seed));
     kmu_init(&kmu_dev_s, prbg_seed);
 
     /* Clear PRBG seed from the stack */
@@ -261,7 +253,7 @@
      * we need to generate a new TRAM key.
      */
     if (sp_enabled == LCM_TRUE && (lcs == LCM_LCS_CM || lcs == LCM_LCS_DM)) {
-        bl1_random_generate_secure(tram_key, sizeof(tram_key));
+        bl1_random_generate_noise_stateless(tram_key, sizeof(tram_key));
 
         kmu_set_key(&kmu_dev_s, RSE_KMU_SLOT_TRAM_KEY, tram_key, sizeof(tram_key));
 
@@ -271,7 +263,7 @@
         }
 
         /* generate a random word to initialise the DTCM */
-        bl1_random_generate_fast((uint8_t *)&random_word, sizeof(random_word));
+        bl1_random_generate_noise_stateless((uint8_t *)&random_word, sizeof(random_word));
     }
 
     kmu_set_key_export_config(&kmu_dev_s, RSE_KMU_SLOT_TRAM_KEY, &tram_key_export_config);