]> granicus.if.org Git - esp-idf/commitdiff
esp32: Rewrite esp_sha function
authorKonstantin Kondrashov <konstantin@espressif.com>
Mon, 13 May 2019 04:32:45 +0000 (12:32 +0800)
committerAngus Gratton <angus@espressif.com>
Mon, 13 May 2019 04:32:45 +0000 (12:32 +0800)
It removes using a STALL_OTHER_CPU while sha operations.
It improves performance with SHA.

components/esp_rom/include/esp32/rom/sha.h
components/mbedtls/CMakeLists.txt
components/mbedtls/port/esp32/sha.c
components/mbedtls/port/esp_sha.c [new file with mode: 0644]

index 888c32c3c8cc1702fc3859c3e5ada1e730c5d580..323749efddab0b0288bf0e40c720eb33ada1353e 100644 (file)
@@ -44,6 +44,9 @@ enum SHA_TYPE {
     SHA_INVALID = -1,
 };
 
+/* Do not use these function in multi core mode due to 
+ * inside they have no safe implementation (without DPORT workaround).
+*/
 void ets_sha_init(SHA_CTX *ctx);
 
 void ets_sha_enable(void);
index 364923427d61c1e9989271bddccc94636ee10dca..09abc2fff08bd224e4a9ffa6e0133f622cba68a0 100644 (file)
@@ -81,6 +81,7 @@ set(mbedtls_targets mbedtls mbedcrypto mbedx509)
 target_sources(mbedtls PRIVATE "${COMPONENT_PATH}/port/esp_bignum.c"
                                 "${COMPONENT_PATH}/port/esp_hardware.c"
                                 "${COMPONENT_PATH}/port/esp_mem.c"
+                                "${COMPONENT_PATH}/port/esp_sha.c"
                                 "${COMPONENT_PATH}/port/esp_sha1.c"
                                 "${COMPONENT_PATH}/port/esp_sha256.c"
                                 "${COMPONENT_PATH}/port/esp_sha512.c"
index 4cff99575f50c0869cfd1aef7ae1ab67cd8960da..0f8a4ca0affb0c9ae16ee06b306172e0a334bea8 100644 (file)
@@ -183,9 +183,6 @@ static bool esp_sha_lock_engine_common(esp_sha_type sha_type, TickType_t ticks_t
         /* Just locked first engine,
            so enable SHA hardware */
         periph_module_enable(PERIPH_SHA_MODULE);
-        DPORT_STALL_OTHER_CPU_START();
-        ets_sha_enable();
-        DPORT_STALL_OTHER_CPU_END();
     }
 
     engines_in_use++;
@@ -305,61 +302,3 @@ void esp_sha_block(esp_sha_type sha_type, const void *data_block, bool is_first_
        unit, instead.
     */
 }
-
-void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output)
-{
-    size_t block_len = block_length(sha_type);
-
-    // Max number of blocks to pass per each call to esp_sha_lock_memory_block()
-    // (keep low enough to avoid starving interrupt handlers, especially if reading
-    // data into SHA via flash cache, but high enough that spinlock overhead is low)
-    const size_t BLOCKS_PER_CHUNK = 100;
-    const size_t MAX_CHUNK_LEN = BLOCKS_PER_CHUNK * block_len;
-
-    SHA_CTX ctx;
-
-    esp_sha_lock_engine(sha_type);
-
-    ets_sha_init(&ctx);
-
-    while (ilen > 0) {
-        size_t chunk_len = (ilen > MAX_CHUNK_LEN) ? MAX_CHUNK_LEN : ilen;
-
-        // Wait for idle before entering critical section
-        // (to reduce time spent in it), then check again after
-        esp_sha_wait_idle();
-        esp_sha_lock_memory_block();
-        esp_sha_wait_idle();
-
-        DPORT_STALL_OTHER_CPU_START();
-        while (chunk_len > 0) {
-            // This SHA ROM function reads DPORT regs
-            // (can accept max one SHA block each call)
-            size_t update_len = (chunk_len > block_len) ? block_len : chunk_len;
-            ets_sha_update(&ctx, sha_type, input, update_len * 8);
-
-            input += update_len;
-            chunk_len -= update_len;
-            ilen -= update_len;
-        }
-        DPORT_STALL_OTHER_CPU_END();
-
-        if (ilen == 0) {
-            /* Finish the last block before releasing the memory
-               block lock, as ets_sha_update() may have written data to
-               the memory block already (partial last block) and hardware
-               hasn't yet processed it.
-            */
-            DPORT_STALL_OTHER_CPU_START();
-            {
-                // This SHA ROM function also reads DPORT regs
-                ets_sha_finish(&ctx, sha_type, output);
-            }
-            DPORT_STALL_OTHER_CPU_END();
-        }
-
-        esp_sha_unlock_memory_block();
-    }
-
-    esp_sha_unlock_engine(sha_type);
-}
diff --git a/components/mbedtls/port/esp_sha.c b/components/mbedtls/port/esp_sha.c
new file mode 100644 (file)
index 0000000..2c40f2c
--- /dev/null
@@ -0,0 +1,79 @@
+// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <string.h>
+#include <stdio.h>
+#include <assert.h>
+
+#include "esp32/sha.h"
+#include <mbedtls/sha1.h>
+#include <mbedtls/sha256.h>
+#include <mbedtls/sha512.h>
+
+void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output)
+{
+    int ret;
+    assert(input != NULL && output != NULL);
+
+    if (sha_type == SHA1) {
+
+        mbedtls_sha1_context *ctx1 = (mbedtls_sha1_context *)malloc(sizeof(mbedtls_sha1_context));
+        assert(ctx1 != NULL);
+        mbedtls_sha1_starts_ret(ctx1);
+        ret = mbedtls_sha1_update_ret(ctx1, input, ilen);
+        assert(ret == 0);
+        ret = mbedtls_sha1_finish_ret(ctx1, output);
+        assert(ret == 0);
+        mbedtls_sha1_free(ctx1);
+        free(ctx1);
+
+    } else if (sha_type == SHA2_256) {
+
+        mbedtls_sha256_context *ctx256 = (mbedtls_sha256_context *)malloc(sizeof(mbedtls_sha256_context));
+        assert(ctx256 != NULL);
+        mbedtls_sha256_starts_ret(ctx256, 0);
+        ret = mbedtls_sha256_update_ret(ctx256, input, ilen);
+        assert(ret == 0);
+        ret = mbedtls_sha256_finish_ret(ctx256, output);
+        assert(ret == 0);
+        mbedtls_sha256_free(ctx256);
+        free(ctx256);
+
+    } else if (sha_type == SHA2_384) {
+
+        mbedtls_sha512_context *ctx384 = (mbedtls_sha512_context *)malloc(sizeof(mbedtls_sha512_context));
+        assert(ctx384 != NULL);
+        mbedtls_sha512_starts_ret(ctx384, 1);
+        ret = mbedtls_sha512_update_ret(ctx384, input, ilen);
+        assert(ret == 0);
+        ret = mbedtls_sha512_finish_ret(ctx384, output);
+        assert(ret == 0);
+        mbedtls_sha512_free(ctx384);
+        free(ctx384);
+
+    } else if (sha_type == SHA2_512) {
+
+        mbedtls_sha512_context *ctx512 = (mbedtls_sha512_context *)malloc(sizeof(mbedtls_sha512_context));
+        assert(ctx512 != NULL);
+        mbedtls_sha512_starts_ret(ctx512, 0);
+        ret = mbedtls_sha512_update_ret(ctx512, input, ilen);
+        assert(ret == 0);
+        ret = mbedtls_sha512_finish_ret(ctx512, output);
+        assert(ret == 0);
+        mbedtls_sha512_free(ctx512);
+        free(ctx512);
+
+    }
+
+}