diff options
Diffstat (limited to 'board/cr50/dcrypto')
-rw-r--r-- | board/cr50/dcrypto/bn.c | 39 | ||||
-rw-r--r-- | board/cr50/dcrypto/dcrypto_runtime.c | 22 | ||||
-rw-r--r-- | board/cr50/dcrypto/sha_hw.c | 9 | ||||
-rw-r--r-- | board/cr50/dcrypto/trng.c | 13 |
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++; |