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
#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
/* 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 )
*/
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);
#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 */