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);