aboutsummaryrefslogtreecommitdiff
path: root/core/tee
diff options
context:
space:
mode:
authorJens Wiklander <jens.wiklander@linaro.org>2018-06-14 11:12:00 +0200
committerJérôme Forissier <jerome.forissier@linaro.org>2018-06-18 10:01:13 +0200
commit6e954a6e42bd37911605d3b4cd22e4d1d23c2372 (patch)
tree1c305f414f6c5eccc142cbf6d76bf8784836d569 /core/tee
parentb8d0b26e700584b85819b33306d93811deb48800 (diff)
core: add new RNG implementation
Adds a new cryptographically secure pseudo random number generator known as Fortuna. The implementation is based on the description in [0]. This implementation replaces the implementation in LTC which was used until now. Gathering of entropy has been refined with crypto_rng_add_event() to better match how entropy is added to Fortuna. A enum crypto_rng_src identifies the source of the event. The source also controls how the event is added. There are two options available, queue it in a circular buffer for later processing or adding it directly to a pool. The former option is suitable when being called from an interrupt handler or some other place where RPC to normal world is forbidden. plat_prng_add_jitter_entropy_norpc() is removed and plat_prng_add_jitter_entropy() is updated to use this new entropy source scheme. The configuration of LTC is simplified by this, now PRNG is always drawn via prng_mpa_desc. plat_rng_init() takes care of initializing the PRNG in order to allow platforms to override or enhance the Fortuna integration. [0] Link:https://www.schneier.com/academic/paperfiles/fortuna.pdf Reviewed-by: Jerome Forissier <jerome.forissier@linaro.org> Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Diffstat (limited to 'core/tee')
-rw-r--r--core/tee/tee_cryp_utl.c55
1 files changed, 44 insertions, 11 deletions
diff --git a/core/tee/tee_cryp_utl.c b/core/tee/tee_cryp_utl.c
index 78277f35..a7dfe342 100644
--- a/core/tee/tee_cryp_utl.c
+++ b/core/tee/tee_cryp_utl.c
@@ -5,12 +5,14 @@
#include <crypto/crypto.h>
#include <initcall.h>
+#include <kernel/panic.h>
#include <kernel/tee_time.h>
#include <rng_support.h>
#include <stdlib.h>
#include <string_ext.h>
#include <string.h>
#include <tee/tee_cryp_utl.h>
+#include <trace.h>
#include <utee_defines.h>
#if !defined(CFG_WITH_SOFTWARE_PRNG)
@@ -329,34 +331,65 @@ TEE_Result tee_aes_cbc_cts_update(void *cbc_ctx, void *ecb_ctx,
return TEE_SUCCESS;
}
-TEE_Result tee_prng_add_entropy(const uint8_t *in, size_t len)
-{
- return crypto_rng_add_entropy(in, len);
-}
-
/*
* Override this in your platform code to feed the PRNG platform-specific
* jitter entropy. This implementation does not efficiently deliver entropy
* and is here for backwards-compatibility.
*/
-__weak void plat_prng_add_jitter_entropy(void)
+__weak void plat_prng_add_jitter_entropy(enum crypto_rng_src sid,
+ unsigned int *pnum)
{
TEE_Time current;
+#ifdef CFG_SECURE_TIME_SOURCE_REE
+ if (CRYPTO_RNG_SRC_IS_QUICK(sid))
+ return; /* Can't read REE time here */
+#endif
+
if (tee_time_get_sys_time(&current) == TEE_SUCCESS)
- tee_prng_add_entropy((uint8_t *)&current, sizeof(current));
+ crypto_rng_add_event(sid, pnum, &current, sizeof(current));
}
-__weak void plat_prng_add_jitter_entropy_norpc(void)
+__weak void plat_rng_init(void)
{
+ TEE_Result res = TEE_SUCCESS;
+ TEE_Time t;
+
#ifndef CFG_SECURE_TIME_SOURCE_REE
- plat_prng_add_jitter_entropy();
+ /*
+ * This isn't much of a seed. Ideally we should either get a seed from
+ * a hardware RNG or from a previously saved seed.
+ *
+ * Seeding with hardware RNG is currently up to the platform to
+ * override this function.
+ *
+ * Seeding with a saved seed will require cooperation from normal
+ * world, this is still TODO.
+ */
+ res = tee_time_get_sys_time(&t);
+#else
+ EMSG("Warning: seeding RNG with zeroes");
+ memset(&t, 0, sizeof(t));
#endif
+ if (!res)
+ res = crypto_rng_init(&t, sizeof(t));
+ if (res) {
+ EMSG("Failed to initialize RNG: %#" PRIx32, res);
+ panic();
+ }
}
static TEE_Result tee_cryp_init(void)
{
- return crypto_init();
-}
+ TEE_Result res = crypto_init();
+ res = crypto_init();
+ if (res) {
+ EMSG("Failed to initialize crypto API: %#" PRIx32, res);
+ panic();
+ }
+ plat_rng_init();
+
+ return TEE_SUCCESS;
+}
service_init(tee_cryp_init);