]> granicus.if.org Git - esp-idf/commitdiff
hwcrypto: Fixes for disabling one hardware unit causing reset of a different unit
authorAngus Gratton <angus@espressif.com>
Tue, 22 Nov 2016 07:09:32 +0000 (18:09 +1100)
committerAngus Gratton <angus@espressif.com>
Tue, 22 Nov 2016 09:42:38 +0000 (20:42 +1100)
ROM functions reset related units, but this can have problems in a
multithreaded environment.

components/esp32/hwcrypto/aes.c
components/esp32/hwcrypto/sha.c
components/esp32/include/soc/dport_reg.h
components/esp32/include/soc/hwcrypto_reg.h
components/mbedtls/port/esp_bignum.c

index 169465822d96e6f6ba38d3048871d0a55eeace39..8f27cd17c228de9115643c1d04bef1ca40f6dad6 100644 (file)
@@ -28,6 +28,7 @@
 #include <string.h>
 #include "hwcrypto/aes.h"
 #include "rom/aes.h"
+#include "soc/dport_reg.h"
 #include <sys/lock.h>
 
 static _lock_t aes_lock;
@@ -36,14 +37,23 @@ void esp_aes_acquire_hardware( void )
 {
     /* newlib locks lazy initialize on ESP-IDF */
     _lock_acquire(&aes_lock);
-    ets_aes_enable();
+    /* Enable AES hardware */
+    REG_SET_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_AES);
+    /* Clear reset on digital signature & secure boot units,
+       otherwise AES unit is held in reset also. */
+    REG_CLR_BIT(DPORT_PERI_RST_EN_REG,
+                DPORT_PERI_EN_AES
+                | DPORT_PERI_EN_DIGITAL_SIGNATURE
+                | DPORT_PERI_EN_SECUREBOOT);
 }
 
 void esp_aes_release_hardware( void )
 {
-    uint8_t zero[256/8] = { 0 };
-    ets_aes_setkey_enc(zero, AES256);
-    ets_aes_disable();
+    /* Disable AES hardware */
+    REG_SET_BIT(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_AES);
+    /* Don't return other units to reset, as this pulls
+       reset on RSA & SHA units, respectively. */
+    REG_CLR_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_AES);
     _lock_release(&aes_lock);
 }
 
index d58bda7f2efb459a001a55ad1b4551438c06ddd3..fd8075fc72250f8b950df52fdb4e3cfc7b6d6b3c 100644 (file)
@@ -143,15 +143,21 @@ bool esp_sha_try_lock_engine(esp_sha_type sha_type)
 
     _lock_acquire(&state_change_lock);
 
-    assert( !engine->in_use && "in_use flag should be cleared" );
-
     if (sha_engines_all_idle()) {
+        /* Enable SHA hardware */
+        REG_SET_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_SHA);
+        /* also clear reset on secure boot, otherwise SHA is held in reset */
+        REG_CLR_BIT(DPORT_PERI_RST_EN_REG,
+                    DPORT_PERI_EN_SHA
+                    | DPORT_PERI_EN_SECUREBOOT);
         ets_sha_enable();
     }
 
     _lock_release(&state_change_lock);
 
+    assert( !engine->in_use && "in_use flag should be cleared" );
     engine->in_use = true;
+
     return true;
 }
 
@@ -165,7 +171,10 @@ void esp_sha_unlock_engine(esp_sha_type sha_type)
     engine->in_use = false;
 
     if (sha_engines_all_idle()) {
-        ets_sha_disable();
+        /* Disable SHA hardware */
+        /* Don't assert reset on secure boot, otherwise AES is held in reset */
+        REG_SET_BIT(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_SHA);
+        REG_CLR_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_SHA);
     }
 
     _lock_release(&state_change_lock);
index 1be0fdee1492293aa6132df2fa6caf18d61c5965..f84346717c3809a1d400d79e8378313382fde551 100644 (file)
 #define DPORT_PERI_RST_EN_V  0xFFFFFFFF
 #define DPORT_PERI_RST_EN_S  0
 
+/* The following bits apply to DPORT_PERI_CLK_EN_REG, DPORT_PERI_RST_EN_REG
+ */
+#define DPORT_PERI_EN_AES (1<<0)
+#define DPORT_PERI_EN_SHA (1<<1)
+#define DPORT_PERI_EN_RSA (1<<2)
+/* NB: Secure boot reset will hold SHA & AES in reset */
+#define DPORT_PERI_EN_SECUREBOOT (1<<3)
+/* NB: Digital signature reset will hold AES & RSA in reset */
+#define DPORT_PERI_EN_DIGITAL_SIGNATURE (1<<4)
+
 #define DPORT_WIFI_BB_CFG_REG          (DR_REG_DPORT_BASE + 0x024)
 /* DPORT_WIFI_BB_CFG : R/W ;bitpos:[31:0] ;default: 32'h0 ; */
 /*description: */
index c187117af2fba492e81fa35c0ed24a8b6e94badc..10e80d935f3942db2c630310c51c9cccece69ee4 100644 (file)
@@ -30,7 +30,7 @@
 #define RSA_MULT_MODE_REG             (DR_REG_RSA_BASE + 0x80c)
 #define RSA_MULT_START_REG            (DR_REG_RSA_BASE + 0x810)
 
-#define RSA_INTERRUPT_REG             (DR_REG_RSA_BASE + 0X814)
+#define RSA_INTERRUPT_REG             (DR_REG_RSA_BASE + 0x814)
 
 #define RSA_CLEAN_REG                 (DR_REG_RSA_BASE + 0x818)
 
index 7570820e3ba523b4b0bf367d9dc8b2cc476530b1..6c214b7414b008f14d55f2522912729de285c3f4 100644 (file)
@@ -33,6 +33,8 @@
 #include "esp_intr.h"
 #include "esp_attr.h"
 
+#include "soc/dport_reg.h"
+
 #include "freertos/FreeRTOS.h"
 #include "freertos/task.h"
 #include "freertos/semphr.h"
@@ -71,7 +73,16 @@ void esp_mpi_acquire_hardware( void )
 {
     /* newlib locks lazy initialize on ESP-IDF */
     _lock_acquire(&mpi_lock);
-    ets_bigint_enable();
+    REG_SET_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_RSA);
+    /* also clear reset on digital signature, otherwise RSA is held in reset */
+    REG_CLR_BIT(DPORT_PERI_RST_EN_REG,
+                DPORT_PERI_EN_RSA
+                | DPORT_PERI_EN_DIGITAL_SIGNATURE);
+
+    REG_CLR_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD);
+
+    while(REG_READ(RSA_CLEAN_REG) != 1);
+
 #ifdef CONFIG_MBEDTLS_MPI_USE_INTERRUPT
     rsa_isr_initialise();
 #endif
@@ -79,7 +90,12 @@ void esp_mpi_acquire_hardware( void )
 
 void esp_mpi_release_hardware( void )
 {
-    ets_bigint_disable();
+    REG_SET_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD);
+
+    /* don't reset digital signature unit, as this resets AES also */
+    REG_SET_BIT(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_RSA);
+    REG_CLR_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_RSA);
+
     _lock_release(&mpi_lock);
 }