diff --git a/components/esp32/hwcrypto/sha.c b/components/esp32/hwcrypto/sha.c index 7a064340a..3ffc43078 100644 --- a/components/esp32/hwcrypto/sha.c +++ b/components/esp32/hwcrypto/sha.c @@ -226,6 +226,9 @@ void esp_sha_wait_idle(void) void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state) { + uint32_t *digest_state_words = NULL; + uint32_t *reg_addr_buf = NULL; + uint32_t word_len = sha_length(sha_type)/4; #ifndef NDEBUG { SemaphoreHandle_t *engine_state = sha_get_engine_state(sha_type); @@ -243,20 +246,30 @@ void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state) 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); + digest_state_words = (uint32_t *)digest_state; + 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 */ DPORT_INTERRUPT_DISABLE(); // Disable interrupt only on current CPU. - for(int i = 0; i < sha_length(sha_type)/4; i += 2) { + for(int i = 0; i < word_len; i += 2) { digest_state_words[i+1] = DPORT_SEQUENCE_REG_READ((uint32_t)®_addr_buf[i]); digest_state_words[i] = DPORT_SEQUENCE_REG_READ((uint32_t)®_addr_buf[i+1]); } DPORT_INTERRUPT_RESTORE(); // restore the previous interrupt level } else { - esp_dport_access_read_buffer(digest_state_words, (uint32_t)®_addr_buf[0], sha_length(sha_type)/4); + esp_dport_access_read_buffer(digest_state_words, (uint32_t)®_addr_buf[0], word_len); } esp_sha_unlock_memory_block(); + + /* Fault injection check: verify SHA engine actually ran, + state is not all zeroes. + */ + for (int i = 0; i < word_len; i++) { + if (digest_state_words[i] != 0) { + return; + } + } + abort(); // SHA peripheral returned all zero state, probably due to fault injection } void esp_sha_block(esp_sha_type sha_type, const void *data_block, bool is_first_block) @@ -310,6 +323,8 @@ void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, uns esp_sha_lock_engine(sha_type); + bzero(output, sha_length(sha_type)); + SHA_CTX ctx; ets_sha_init(&ctx); @@ -353,4 +368,14 @@ void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, uns } esp_sha_unlock_engine(sha_type); + + /* Fault injection check: verify SHA engine actually ran, + state is not all zeroes. + */ + for (int i = 0; i < sha_length(sha_type); i++) { + if (output[i] != 0) { + return; + } + } + abort(); // SHA peripheral returned all zero state, probably due to fault injection }