]> granicus.if.org Git - esp-idf/commitdiff
sha: Add fault injection checks reading hash digest state
authorAngus Gratton <angus@espressif.com>
Wed, 22 May 2019 00:18:55 +0000 (10:18 +1000)
committerAngus Gratton <gus@projectgus.com>
Sun, 11 Aug 2019 01:16:33 +0000 (11:16 +1000)
Vulnerability reported by LimitedResults under Espressif Bug Bounty Program.

components/mbedtls/port/esp32/sha.c

index 7b7a0f415bcd3d45879fae2e57a705cac414fe12..35c52eee3abc700f65cdb9c134b319dae60cb9b5 100644 (file)
@@ -228,6 +228,7 @@ 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);
@@ -250,15 +251,25 @@ void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state)
     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)&reg_addr_buf[i]);
             digest_state_words[i]   = DPORT_SEQUENCE_REG_READ((uint32_t)&reg_addr_buf[i+1]);
         }
         DPORT_INTERRUPT_RESTORE(); // restore the previous interrupt level
     } else {
-        esp_dport_access_read_buffer(digest_state_words, (uint32_t)&reg_addr_buf[0], sha_length(sha_type)/4);
+        esp_dport_access_read_buffer(digest_state_words, (uint32_t)&reg_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)