summaryrefslogtreecommitdiff
path: root/board/cr50/dcrypto
diff options
context:
space:
mode:
Diffstat (limited to 'board/cr50/dcrypto')
-rw-r--r--board/cr50/dcrypto/bn.c39
-rw-r--r--board/cr50/dcrypto/dcrypto_runtime.c22
-rw-r--r--board/cr50/dcrypto/sha_hw.c9
-rw-r--r--board/cr50/dcrypto/trng.c13
4 files changed, 52 insertions, 31 deletions
diff --git a/board/cr50/dcrypto/bn.c b/board/cr50/dcrypto/bn.c
index 671ce6256e..4f0963d902 100644
--- a/board/cr50/dcrypto/bn.c
+++ b/board/cr50/dcrypto/bn.c
@@ -8,19 +8,11 @@
#endif
#include "dcrypto.h"
+#include "fips.h"
#include "internal.h"
#include "trng.h"
-
-#include <assert.h>
-
-#ifdef CONFIG_WATCHDOG
-extern void watchdog_reload(void);
-#else
-static inline void watchdog_reload(void) { }
-#endif
-
void bn_init(struct LITE_BIGNUM *b, void *buf, size_t len)
{
DCRYPTO_bn_wrap(b, buf, len);
@@ -29,8 +21,12 @@ void bn_init(struct LITE_BIGNUM *b, void *buf, size_t len)
void DCRYPTO_bn_wrap(struct LITE_BIGNUM *b, void *buf, size_t len)
{
- /* Only word-multiple sized buffers accepted. */
- assert((len & 0x3) == 0);
+ /* Note: only word-multiple sized buffers accepted. */
+ if (len & 3) {
+ fips_throw_err(FIPS_FATAL_BN_MATH);
+ return;
+ }
+
b->dmax = len / LITE_BN_BYTES;
b->d = (struct access_helper *) buf;
}
@@ -309,8 +305,23 @@ static void bn_compute_RR(struct LITE_BIGNUM *RR, const struct LITE_BIGNUM *N)
/* Repeat 2 * R % N, log2(R) times. */
for (i = 0; i < N->dmax * LITE_BN_BITS2; i++) {
+ /**
+ * assume RR = N - x, where x is positive, less than N,
+ * let n = RR & N bit size (RR created same size as N).
+ *
+ * if RR * 2 overflows it means 2^n > RR >= 2^(n-1),
+ * 2^n > N - x >= 2^(n-1)
+ * ==> N >= 2^(n-1) + x
+ *
+ * 2*RR - 2^n < N because:
+ * ((2^(n-1) + x) - x)*2 - 2^n < 2^(n-1) + x
+ * 0 < 2^(n-1) + x
+ */
if (bn_lshift(RR))
- assert(bn_sub(RR, N) == -1);
+ if (bn_sub(RR, N) != -1)
+ fips_throw_err(FIPS_FATAL_BN_MATH);
+
+ /* RR < N is invariant of the loop */
if (bn_gte(RR, N))
bn_sub(RR, N);
}
@@ -370,7 +381,9 @@ static void bn_modexp_internal(struct LITE_BIGNUM *output,
* TODO(ngm): may be unnecessary with
* a faster implementation.
*/
- watchdog_reload();
+#ifdef CONFIG_WATCHDOG
+ fips_vtable->watchdog_reload();
+#endif
}
bn_mont_mul(output, NULL, &acc, nprime, N); /* Convert out. */
diff --git a/board/cr50/dcrypto/dcrypto_runtime.c b/board/cr50/dcrypto/dcrypto_runtime.c
index 7de990ea41..db0ab292d7 100644
--- a/board/cr50/dcrypto/dcrypto_runtime.c
+++ b/board/cr50/dcrypto/dcrypto_runtime.c
@@ -4,6 +4,7 @@
*/
#include "flash_log.h"
+#include "fips.h"
#include "internal.h"
#include "registers.h"
#include "task.h"
@@ -51,8 +52,8 @@ static void dcrypto_wipe_imem(void)
void dcrypto_init_and_lock(void)
{
- mutex_lock(&dcrypto_mutex);
- my_task_id = task_get_current();
+ fips_vtable->mutex_lock(&dcrypto_mutex);
+ my_task_id = fips_vtable->task_get_current();
if (dcrypto_is_initialized)
return;
@@ -74,14 +75,14 @@ void dcrypto_init_and_lock(void)
GREG32(CRYPTO, INT_STATE) = -1; /* Reset all the status bits. */
GREG32(CRYPTO, INT_ENABLE) = -1; /* Enable all status bits. */
- task_enable_irq(GC_IRQNUM_CRYPTO0_HOST_CMD_DONE_INT);
+ fips_vtable->task_enable_irq(GC_IRQNUM_CRYPTO0_HOST_CMD_DONE_INT);
dcrypto_is_initialized = 1;
}
void dcrypto_unlock(void)
{
- mutex_unlock(&dcrypto_mutex);
+ fips_vtable->mutex_unlock(&dcrypto_mutex);
}
#ifndef DCRYPTO_CALL_TIMEOUT_US
@@ -105,7 +106,7 @@ uint32_t dcrypto_call(uint32_t adr)
GREG32(CRYPTO, HOST_CMD) = 0x08000000 + adr; /* Call imem:adr. */
- event = task_wait_event_mask(TASK_EVENT_DCRYPTO_DONE,
+ event = fips_vtable->task_wait_event_mask(TASK_EVENT_DCRYPTO_DONE,
DCRYPTO_CALL_TIMEOUT_US);
/* TODO(ngm): switch return value to an enum. */
switch (event) {
@@ -126,19 +127,22 @@ uint32_t dcrypto_call(uint32_t adr)
dcrypto_reset_and_wipe();
#ifdef CONFIG_FLASH_LOG
/* State value of zero indicates event timeout. */
- flash_log_add_event(FE_LOG_DCRYPTO_FAILURE,
+ fips_vtable->flash_log_add_event(FE_LOG_DCRYPTO_FAILURE,
sizeof(state), &state);
#endif
return 1;
}
}
-
+/**
+ * DECLARE_IRQ() referencing this function moved outside FIPS module
+ * into fips_cmd.c to remove direct references to EC OS functions hard-
+ * coded into macro.
+ */
void __keep dcrypto_done_interrupt(void)
{
GREG32(CRYPTO, INT_STATE) = GC_CRYPTO_INT_STATE_HOST_CMD_DONE_MASK;
- task_set_event(my_task_id, TASK_EVENT_DCRYPTO_DONE, 0);
+ fips_vtable->task_set_event(my_task_id, TASK_EVENT_DCRYPTO_DONE, 0);
}
-DECLARE_IRQ(GC_IRQNUM_CRYPTO0_HOST_CMD_DONE_INT, dcrypto_done_interrupt, 1);
void dcrypto_imem_load(size_t offset, const uint32_t *opcodes,
size_t n_opcodes)
diff --git a/board/cr50/dcrypto/sha_hw.c b/board/cr50/dcrypto/sha_hw.c
index acad1ba29d..82f5c6dacf 100644
--- a/board/cr50/dcrypto/sha_hw.c
+++ b/board/cr50/dcrypto/sha_hw.c
@@ -3,6 +3,7 @@
* found in the LICENSE file.
*/
#include "dcrypto.h"
+#include "fips.h"
#include "internal.h"
#include "registers.h"
@@ -27,21 +28,21 @@ int dcrypto_grab_sha_hw(void)
{
int rv = 0;
- mutex_lock(&hw_busy_mutex);
+ fips_vtable->mutex_lock(&hw_busy_mutex);
if (!hw_busy) {
rv = 1;
hw_busy = true;
}
- mutex_unlock(&hw_busy_mutex);
+ fips_vtable->mutex_unlock(&hw_busy_mutex);
return rv;
}
void dcrypto_release_sha_hw(void)
{
- mutex_lock(&hw_busy_mutex);
+ fips_vtable->mutex_lock(&hw_busy_mutex);
hw_busy = false;
- mutex_unlock(&hw_busy_mutex);
+ fips_vtable->mutex_unlock(&hw_busy_mutex);
}
#endif /* ! SECTION_IS_RO */
diff --git a/board/cr50/dcrypto/trng.c b/board/cr50/dcrypto/trng.c
index 6045243615..03a9f756c2 100644
--- a/board/cr50/dcrypto/trng.c
+++ b/board/cr50/dcrypto/trng.c
@@ -47,16 +47,16 @@
void fips_init_trng(void)
{
-#if (!(defined(CONFIG_CUSTOMIZED_RO) && defined(SECTION_IS_RO)))
/*
* Most of the trng initialization requires high permissions. If RO has
* dropped the permission level, dont try to read or write these high
* permission registers because it will cause rolling reboots. RO
* should do the TRNG initialization before dropping the level.
+ *
+ * For Cr50 RO doesn't drop permission level and init_trng() is called
+ * by board_init() before dropping permissions.
*/
- if (!runlevel_is_high())
- return;
-#endif
+
/**
* According to NIST SP 800-90B only vetted conditioning mechanism
* should be used for post-processing raw entropy.
@@ -127,7 +127,10 @@ uint64_t read_rand(void)
empty_count > TRNG_EMPTY_COUNT) {
/* TRNG timed out, restart */
GWRITE(TRNG, STOP_WORK, 1);
- flash_log_add_event(FE_LOG_TRNG_STALL, 0, NULL);
+#ifdef CONFIG_FLASH_LOG
+ fips_vtable->flash_log_add_event(FE_LOG_TRNG_STALL, 0,
+ NULL);
+#endif
GWRITE(TRNG, GO_EVENT, 1);
empty_count = 0;
reset_count++;