From 36f29017b62336ecf58d52b91f88b3c11ab36fe8 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Fri, 18 Nov 2016 15:53:00 +1100 Subject: [PATCH] mbedtls hardware bignum: Support "RSA" interrupt for end of operation Allows CPU to do other things which bignum operation is in progress. --- components/mbedtls/Kconfig | 16 ++++++++++ components/mbedtls/port/esp_bignum.c | 48 +++++++++++++++++++++++++--- 2 files changed, 60 insertions(+), 4 deletions(-) diff --git a/components/mbedtls/Kconfig b/components/mbedtls/Kconfig index bb2aa8f6a..d6e2a2dcb 100644 --- a/components/mbedtls/Kconfig +++ b/components/mbedtls/Kconfig @@ -51,6 +51,22 @@ config MBEDTLS_HARDWARE_MPI These operations are used by RSA. +config MBEDTLS_MPI_USE_INTERRUPT + bool "Use interrupt for MPI operations" + depends on MBEDTLS_HARDWARE_MPI + default y + help + Use an interrupt to coordinate MPI operations. + This allows other code to run on the CPU while an MPI operation is pending. + Otherwise the CPU busy-waits. + +config MBEDTLS_MPI_INTERRUPT_NUM + int "MPI Interrupt number" + depends on MBEDTLS_MPI_USE_INTERRUPT + default 18 + help + CPU interrupt number for MPI interrupt to connect to. Must be otherwise unused. + Eventually this assignment will be handled automatically at runtime. endmenu diff --git a/components/mbedtls/port/esp_bignum.c b/components/mbedtls/port/esp_bignum.c index 11a1c6397..2133e7cae 100644 --- a/components/mbedtls/port/esp_bignum.c +++ b/components/mbedtls/port/esp_bignum.c @@ -31,12 +31,43 @@ #include "soc/hwcrypto_reg.h" #include "esp_system.h" #include "esp_log.h" +#include "esp_intr.h" +#include "esp_attr.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#include "freertos/semphr.h" #if defined(MBEDTLS_MPI_MUL_MPI_ALT) || defined(MBEDTLS_MPI_EXP_MOD_ALT) +static const char *TAG = "bignum"; + +#if defined(CONFIG_MBEDTLS_MPI_USE_INTERRUPT) +static SemaphoreHandle_t op_complete_sem; + +static IRAM_ATTR void rsa_complete_isr(void *arg) +{ + BaseType_t higher_woken; + REG_WRITE(RSA_INTERRUPT_REG, 1); + xSemaphoreGiveFromISR(op_complete_sem, &higher_woken); + if (higher_woken) { + portYIELD_FROM_ISR(); + } +} + +static void rsa_isr_initialise() +{ + if (op_complete_sem == NULL) { + op_complete_sem = xSemaphoreCreateBinary(); + intr_matrix_set(xPortGetCoreID(), ETS_RSA_INTR_SOURCE, CONFIG_MBEDTLS_MPI_INTERRUPT_NUM); + xt_set_interrupt_handler(CONFIG_MBEDTLS_MPI_INTERRUPT_NUM, &rsa_complete_isr, NULL); + xthal_set_intclear(1 << CONFIG_MBEDTLS_MPI_INTERRUPT_NUM); + xt_ints_on(1 << CONFIG_MBEDTLS_MPI_INTERRUPT_NUM); + } +} + +#endif /* CONFIG_MBEDTLS_MPI_USE_INTERRUPT */ + static _lock_t mpi_lock; /* At the moment these hardware locking functions aren't exposed publically @@ -47,6 +78,9 @@ static void esp_mpi_acquire_hardware( void ) /* newlib locks lazy initialize on ESP-IDF */ _lock_acquire(&mpi_lock); ets_bigint_enable(); +#ifdef CONFIG_MBEDTLS_MPI_USE_INTERRUPT + rsa_isr_initialise(); +#endif } static void esp_mpi_release_hardware( void ) @@ -187,13 +221,21 @@ static int calculate_rinv(mbedtls_mpi *Rinv, const mbedtls_mpi *M, int num_words */ static inline void execute_op(uint32_t op_reg) { - /* Clear interrupt status, start operation */ + /* Clear interrupt status */ REG_WRITE(RSA_INTERRUPT_REG, 1); + REG_WRITE(op_reg, 1); - /* TODO: use interrupt instead of busywaiting */ +#ifdef CONFIG_MBEDTLS_MPI_USE_INTERRUPT + if (!xSemaphoreTake(op_complete_sem, 2000 / portTICK_PERIOD_MS)) { + ESP_LOGE(TAG, "Timed out waiting for RSA operation (op_reg 0x%x int_reg 0x%x)", + op_reg, REG_READ(RSA_INTERRUPT_REG)); + abort(); /* indicates a fundamental problem with driver */ + } +#else while(REG_READ(RSA_INTERRUPT_REG) != 1) { } +#endif /* clear the interrupt */ REG_WRITE(RSA_INTERRUPT_REG, 1); @@ -356,8 +398,6 @@ static int modular_multiply_finish(mbedtls_mpi *Z, const mbedtls_mpi *X, const m #if defined(MBEDTLS_MPI_MUL_MPI_ALT) /* MBEDTLS_MPI_MUL_MPI_ALT */ -static const char *TAG = "bignum"; - static int mpi_mult_mpi_failover_mod_mult(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t num_words); /* Z = X * Y */