From d0c300c52d32bfd970bf5ecc3dc04c3e23b42ad1 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 16 Aug 2017 12:15:37 +1000 Subject: [PATCH] hwcrypto: SHA acceleration using safe DPORT reads --- components/esp32/hwcrypto/sha.c | 86 +++++++++++++++++++++------------ 1 file changed, 56 insertions(+), 30 deletions(-) diff --git a/components/esp32/hwcrypto/sha.c b/components/esp32/hwcrypto/sha.c index c9c8d33eee..0c0c8ddb5a 100644 --- a/components/esp32/hwcrypto/sha.c +++ b/components/esp32/hwcrypto/sha.c @@ -159,13 +159,17 @@ static void esp_sha_lock_engine_inner(sha_engine_state *engine) _lock_acquire(&state_change_lock); if (sha_engines_all_idle()) { - /* Enable SHA hardware */ - DPORT_REG_SET_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_SHA); - /* also clear reset on secure boot, otherwise SHA is held in reset */ - DPORT_REG_CLR_BIT(DPORT_PERI_RST_EN_REG, - DPORT_PERI_EN_SHA - | DPORT_PERI_EN_SECUREBOOT); - ets_sha_enable(); + DPORT_STALL_OTHER_CPU_START(); + { + /* Enable SHA hardware */ + _DPORT_REG_SET_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_SHA); + /* also clear reset on secure boot, otherwise SHA is held in reset */ + _DPORT_REG_CLR_BIT(DPORT_PERI_RST_EN_REG, + DPORT_PERI_EN_SHA + | DPORT_PERI_EN_SECUREBOOT); + ets_sha_enable(); + } + DPORT_STALL_OTHER_CPU_END(); } _lock_release(&state_change_lock); @@ -187,8 +191,12 @@ void esp_sha_unlock_engine(esp_sha_type sha_type) if (sha_engines_all_idle()) { /* Disable SHA hardware */ /* Don't assert reset on secure boot, otherwise AES is held in reset */ - DPORT_REG_SET_BIT(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_SHA); - DPORT_REG_CLR_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_SHA); + DPORT_STALL_OTHER_CPU_START(); + { + _DPORT_REG_SET_BIT(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_SHA); + _DPORT_REG_CLR_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_SHA); + } + DPORT_STALL_OTHER_CPU_END(); } _lock_release(&state_change_lock); @@ -198,10 +206,16 @@ void esp_sha_unlock_engine(esp_sha_type sha_type) void esp_sha_wait_idle(void) { - while(REG_READ(SHA_1_BUSY_REG) == 1) {} - while(REG_READ(SHA_256_BUSY_REG) == 1) {} - while(REG_READ(SHA_384_BUSY_REG) == 1) {} - while(REG_READ(SHA_512_BUSY_REG) == 1) {} + DPORT_STALL_OTHER_CPU_START(); + while(1) { + if(_DPORT_REG_READ(SHA_1_BUSY_REG) == 0 + && _DPORT_REG_READ(SHA_256_BUSY_REG) == 0 + && _DPORT_REG_READ(SHA_384_BUSY_REG) == 0 + && _DPORT_REG_READ(SHA_512_BUSY_REG) == 0) { + break; + } + } + DPORT_STALL_OTHER_CPU_END(); } void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state) @@ -211,23 +225,26 @@ void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state) esp_sha_lock_memory_block(); - esp_sha_wait_idle(); + DPORT_STALL_OTHER_CPU_START(); // This block reads from DPORT memory (reg_addr_buf) + { + esp_sha_wait_idle(); - REG_WRITE(SHA_LOAD_REG(sha_type), 1); - while(REG_READ(SHA_BUSY_REG(sha_type)) == 1) { } + _DPORT_REG_WRITE(SHA_LOAD_REG(sha_type), 1); + while(_DPORT_REG_READ(SHA_BUSY_REG(sha_type)) == 1) { } - uint32_t *digest_state_words = (uint32_t *)digest_state; - uint32_t *reg_addr_buf = (uint32_t *)(SHA_TEXT_BASE); - if(sha_type == SHA2_384 || sha_type == SHA2_512) { - /* for these ciphers using 64-bit states, swap each pair of words */ - for(int i = 0; i < sha_length(sha_type)/4; i += 2) { - digest_state_words[i+1] = reg_addr_buf[i]; - digest_state_words[i]= reg_addr_buf[i+1]; + uint32_t *digest_state_words = (uint32_t *)digest_state; + uint32_t *reg_addr_buf = (uint32_t *)(SHA_TEXT_BASE); + if(sha_type == SHA2_384 || sha_type == SHA2_512) { + /* for these ciphers using 64-bit states, swap each pair of words */ + for(int i = 0; i < sha_length(sha_type)/4; i += 2) { + digest_state_words[i+1] = reg_addr_buf[i]; + digest_state_words[i]= reg_addr_buf[i+1]; + } + } else { + memcpy(digest_state_words, reg_addr_buf, sha_length(sha_type)); } - } else { - memcpy(digest_state_words, reg_addr_buf, sha_length(sha_type)); } - asm volatile ("memw"); + DPORT_STALL_OTHER_CPU_END(); esp_sha_unlock_memory_block(); } @@ -250,9 +267,9 @@ void esp_sha_block(esp_sha_type sha_type, const void *data_block, bool is_first_ asm volatile ("memw"); if(is_first_block) { - REG_WRITE(SHA_START_REG(sha_type), 1); + DPORT_REG_WRITE(SHA_START_REG(sha_type), 1); } else { - REG_WRITE(SHA_CONTINUE_REG(sha_type), 1); + DPORT_REG_WRITE(SHA_CONTINUE_REG(sha_type), 1); } esp_sha_unlock_memory_block(); @@ -275,14 +292,23 @@ void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, uns size_t chunk_len = (ilen > block_len) ? block_len : ilen; esp_sha_lock_memory_block(); esp_sha_wait_idle(); - ets_sha_update(&ctx, sha_type, input, chunk_len * 8); + DPORT_STALL_OTHER_CPU_START(); + { + // This SHA ROM function reads DPORT regs + ets_sha_update(&ctx, sha_type, input, chunk_len * 8); + } + DPORT_STALL_OTHER_CPU_END(); esp_sha_unlock_memory_block(); input += chunk_len; ilen -= chunk_len; } esp_sha_lock_memory_block(); esp_sha_wait_idle(); - ets_sha_finish(&ctx, sha_type, output); + DPORT_STALL_OTHER_CPU_START(); + { + ets_sha_finish(&ctx, sha_type, output); + } + DPORT_STALL_OTHER_CPU_END(); esp_sha_unlock_memory_block(); esp_sha_unlock_engine(sha_type);