ソースを参照

Merge branch 'feature/sha_tls_integration' into 'master'

SHA acceleration integrated to mbedTLS incl. TLS sessions

Uses hardware SHA acceleration where available, fails over to software where not available.

Ref TW7112

See merge request !232

Angus Gratton 9 年 前
コミット
d0801fdbab

+ 5 - 8
components/bootloader_support/src/secure_boot_signatures.c

@@ -25,7 +25,6 @@
 typedef SHA_CTX sha_context;
 #else
 #include "hwcrypto/sha.h"
-typedef esp_sha_context sha_context;
 #endif
 
 typedef struct {
@@ -42,7 +41,9 @@ extern const uint8_t signature_verification_key_end[] asm("_binary_signature_ver
 
 esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length)
 {
-    sha_context sha;
+#ifdef BOOTLOADER_BUILD
+    SHA_CTX sha;
+#endif
     uint8_t digest[32];
     ptrdiff_t keylen;
     const uint8_t *data;
@@ -83,12 +84,8 @@ esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length)
     ets_sha_finish(&sha, SHA2_256, digest);
     ets_sha_disable();
 #else
-    /* Use thread-safe esp-idf SHA layer */
-    esp_sha256_init(&sha);
-    esp_sha256_start(&sha, false);
-    esp_sha256_update(&sha, data, length);
-    esp_sha256_finish(&sha, digest);
-    esp_sha256_free(&sha);
+    /* Use thread-safe esp-idf SHA function */
+    esp_sha(SHA2_256, data, length, digest);
 #endif
 
     keylen = signature_verification_key_end - signature_verification_key_start;

+ 14 - 4
components/esp32/hwcrypto/aes.c

@@ -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);
 }
 

+ 193 - 171
components/esp32/hwcrypto/sha.c

@@ -26,242 +26,264 @@
  */
 
 #include <string.h>
+#include <stdio.h>
 #include <sys/lock.h>
+#include <byteswap.h>
+#include <assert.h>
+
 #include "hwcrypto/sha.h"
 #include "rom/ets_sys.h"
+#include "soc/dport_reg.h"
+#include "soc/hwcrypto_reg.h"
 
-
-static _lock_t sha_lock;
-
-void esp_sha_acquire_hardware( void )
-{
-    /* newlib locks lazy initialize on ESP-IDF */
-    _lock_acquire(&sha_lock);
-    ets_sha_enable();
+inline static uint32_t SHA_LOAD_REG(esp_sha_type sha_type) {
+    return SHA_1_LOAD_REG + sha_type * 0x10;
 }
 
-void esp_sha_release_hardware( void )
-{
-    /* Want to empty internal SHA buffers where possible,
-       need to check if this is sufficient for this. */
-    SHA_CTX zero = { 0 };
-    ets_sha_init(&zero);
-    ets_sha_disable();
-    _lock_release(&sha_lock);
+inline static uint32_t SHA_BUSY_REG(esp_sha_type sha_type) {
+    return SHA_1_BUSY_REG + sha_type * 0x10;
 }
 
-/* Generic esp_shaX_update implementation */
-static void esp_sha_update( esp_sha_context *ctx, const unsigned char *input, size_t ilen, size_t block_size)
-{
-    /* Feed the SHA engine one block at a time */
-    while(ilen > 0) {
-        size_t chunk_len = (ilen > block_size) ? block_size : ilen;
-        ets_sha_update(&ctx->context, ctx->context_type, input, chunk_len * 8);
-        input += chunk_len;
-        ilen -= chunk_len;
-    }
+inline static uint32_t SHA_START_REG(esp_sha_type sha_type) {
+    return SHA_1_START_REG + sha_type * 0x10;
 }
 
-void esp_sha1_init( esp_sha_context *ctx )
-{
-    bzero( ctx, sizeof( esp_sha_context ) );
+inline static uint32_t SHA_CONTINUE_REG(esp_sha_type sha_type) {
+    return SHA_1_CONTINUE_REG + sha_type * 0x10;
 }
 
-void esp_sha1_free( esp_sha_context *ctx )
-{
-    if ( ctx == NULL ) {
-        return;
+/* Single lock for SHA engine memory block
+*/
+static _lock_t memory_block_lock;
+
+typedef struct {
+    _lock_t lock;
+    bool in_use;
+} sha_engine_state;
+
+/* Pointer to state of each concurrent SHA engine.
+
+   Indexes:
+   0 = SHA1
+   1 = SHA2_256
+   2 = SHA2_384 or SHA2_512
+*/
+static sha_engine_state engine_states[3];
+
+/* Index into the sha_engine_state array */
+inline static size_t sha_engine_index(esp_sha_type type) {
+    switch(type) {
+    case SHA1:
+        return 0;
+    case SHA2_256:
+        return 1;
+    default:
+        return 2;
     }
-
-    bzero( ctx, sizeof( esp_sha_context ) );
 }
 
-void esp_sha1_clone( esp_sha_context *dst, const esp_sha_context *src )
-{
-    *dst = *src;
+/* Return state & digest length (in bytes) for a given SHA type */
+inline static size_t sha_length(esp_sha_type type) {
+    switch(type) {
+    case SHA1:
+        return 20;
+    case SHA2_256:
+        return 32;
+    case SHA2_384:
+        return 64;
+    case SHA2_512:
+        return 64;
+    default:
+        return 0;
+    }
 }
 
-/*
- * SHA-1 context setup
- */
-void esp_sha1_start( esp_sha_context *ctx )
-{
-    ctx->context_type = SHA1;
-    esp_sha_acquire_hardware();
-    ets_sha_init(&ctx->context);
+/* Return block size (in bytes) for a given SHA type */
+inline static size_t block_length(esp_sha_type type) {
+    switch(type) {
+    case SHA1:
+    case SHA2_256:
+        return 64;
+    case SHA2_384:
+    case SHA2_512:
+        return 128;
+    default:
+        return 0;
+    }
 }
 
-/*
- * SHA-1 process buffer
- */
-void esp_sha1_update( esp_sha_context *ctx, const unsigned char *input, size_t ilen )
+void esp_sha_lock_memory_block(void)
 {
-    esp_sha_update(ctx, input, ilen, 64);
+    _lock_acquire(&memory_block_lock);
 }
 
-/*
- * SHA-1 final digest
- */
-void esp_sha1_finish( esp_sha_context *ctx, unsigned char output[20] )
+void esp_sha_unlock_memory_block(void)
 {
-    ets_sha_finish(&ctx->context, ctx->context_type, output);
-    esp_sha_release_hardware();
+    _lock_release(&memory_block_lock);
 }
 
-/* Full SHA-1 calculation */
-void esp_sha1( const unsigned char *input, size_t ilen, unsigned char output[20] )
-{
-    esp_sha_context ctx;
+/* Lock to hold when changing SHA engine state,
+   allows checking of sha_engines_all_idle()
+*/
+static _lock_t state_change_lock;
 
-    esp_sha1_init( &ctx );
-    esp_sha1_start( &ctx );
-    esp_sha1_update( &ctx, input, ilen );
-    esp_sha1_finish( &ctx, output );
-    esp_sha1_free( &ctx );
+inline static bool sha_engines_all_idle() {
+    return !engine_states[0].in_use
+        && !engine_states[1].in_use
+        && !engine_states[2].in_use;
 }
 
-void esp_sha256_init( esp_sha_context *ctx )
-{
-    bzero( ctx, sizeof( esp_sha_context ) );
-}
+static void esp_sha_lock_engine_inner(sha_engine_state *engine);
 
-void esp_sha256_free( esp_sha_context *ctx )
+bool esp_sha_try_lock_engine(esp_sha_type sha_type)
 {
-    if ( ctx == NULL ) {
-        return;
+    sha_engine_state *engine = &engine_states[sha_engine_index(sha_type)];
+    if(_lock_try_acquire(&engine->lock) != 0) {
+        /* This SHA engine is already in use */
+        return false;
+    } else {
+        esp_sha_lock_engine_inner(engine);
+        return true;
     }
-
-    bzero( ctx, sizeof( esp_sha_context ) );
 }
 
-void esp_sha256_clone( esp_sha_context *dst, const esp_sha_context *src )
+void esp_sha_lock_engine(esp_sha_type sha_type)
 {
-    *dst = *src;
+    sha_engine_state *engine = &engine_states[sha_engine_index(sha_type)];
+    _lock_acquire(&engine->lock);
+    esp_sha_lock_engine_inner(engine);
 }
 
-/*
- * SHA-256 context setup
- */
-void esp_sha256_start( esp_sha_context *ctx, int is224 )
+static void esp_sha_lock_engine_inner(sha_engine_state *engine)
 {
-    if ( is224 == 0 ) {
-        /* SHA-256 */
-        ctx->context_type = SHA2_256;
-        esp_sha_acquire_hardware();
-        ets_sha_init(&ctx->context);
-    } else {
-        /* SHA-224 is not supported! */
-        ctx->context_type = SHA_INVALID;
+    _lock_acquire(&state_change_lock);
+
+    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;
 }
 
-/*
- * SHA-256 process buffer
- */
-void esp_sha256_update( esp_sha_context *ctx, const unsigned char *input, size_t ilen )
+
+void esp_sha_unlock_engine(esp_sha_type sha_type)
 {
-    if( ctx->context_type == SHA2_256 ) {
-        esp_sha_update(ctx, input, ilen, 64);
+    sha_engine_state *engine = &engine_states[sha_engine_index(sha_type)];
+
+    _lock_acquire(&state_change_lock);
+
+    assert( engine->in_use && "in_use flag should be set" );
+    engine->in_use = false;
+
+    if (sha_engines_all_idle()) {
+        /* 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);
     }
-    /* SHA-224 is a no-op */
+
+    _lock_release(&state_change_lock);
+
+    _lock_release(&engine->lock);
 }
 
-/*
- * SHA-256 final digest
- */
-void esp_sha256_finish( esp_sha_context *ctx, unsigned char output[32] )
+void esp_sha_wait_idle(void)
 {
-    if ( ctx->context_type == SHA2_256 ) {
-        ets_sha_finish(&ctx->context, ctx->context_type, output);
-        esp_sha_release_hardware();
-    } else {
-        /* No hardware SHA-224 support, but mbedTLS API doesn't allow failure.
-           For now, zero the output to make it clear it's not valid. */
-        bzero( output, 28 );
-    }
+    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) {}
 }
 
-/*
- * Full SHA-256 calculation
- */
-void esp_sha256( const unsigned char *input, size_t ilen, unsigned char output[32], int is224 )
+void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state)
 {
-    esp_sha_context ctx;
+    sha_engine_state *engine = &engine_states[sha_engine_index(sha_type)];
+    assert(engine->in_use && "SHA engine should be locked" );
 
-    esp_sha256_init( &ctx );
-    esp_sha256_start( &ctx, is224 );
-    esp_sha256_update( &ctx, input, ilen );
-    esp_sha256_finish( &ctx, output );
-    esp_sha256_free( &ctx );
-}
+    esp_sha_lock_memory_block();
 
+    esp_sha_wait_idle();
 
-/////
-void esp_sha512_init( esp_sha_context *ctx )
-{
-    memset( ctx, 0, sizeof( esp_sha_context ) );
-}
+    REG_WRITE(SHA_LOAD_REG(sha_type), 1);
+    while(REG_READ(SHA_BUSY_REG(sha_type)) == 1) { }
 
-void esp_sha512_free( esp_sha_context *ctx )
-{
-    if ( ctx == NULL ) {
-        return;
+    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));
     }
+    asm volatile ("memw");
 
-    bzero( ctx, sizeof( esp_sha_context ) );
+    esp_sha_unlock_memory_block();
 }
 
-void esp_sha512_clone( esp_sha_context *dst, const esp_sha_context *src )
+void esp_sha_block(esp_sha_type sha_type, const void *data_block, bool is_first_block)
 {
-    *dst = *src;
-}
+    sha_engine_state *engine = &engine_states[sha_engine_index(sha_type)];
+    assert(engine->in_use && "SHA engine should be locked" );
 
-/*
- * SHA-512 context setup
- */
-void esp_sha512_start( esp_sha_context *ctx, int is384 )
-{
-    if ( is384 == 0 ) {
-        /* SHA-512 */
-        ctx->context_type = SHA2_512;
+    esp_sha_lock_memory_block();
+
+    esp_sha_wait_idle();
+
+    /* Fill the data block */
+    uint32_t *reg_addr_buf = (uint32_t *)(SHA_TEXT_BASE);
+    uint32_t *data_words = (uint32_t *)data_block;
+    for (int i = 0; i < block_length(sha_type) / 4; i++) {
+        reg_addr_buf[i] = __bswap_32(data_words[i]);
+    }
+    asm volatile ("memw");
+
+    if(is_first_block) {
+        REG_WRITE(SHA_START_REG(sha_type), 1);
     } else {
-        /* SHA-384 */
-        ctx->context_type = SHA2_384;
+        REG_WRITE(SHA_CONTINUE_REG(sha_type), 1);
     }
-    esp_sha_acquire_hardware();
-    ets_sha_init(&ctx->context);
-}
 
-/*
- * SHA-512 process buffer
- */
-void esp_sha512_update( esp_sha_context *ctx, const unsigned char *input, size_t ilen )
-{
-    esp_sha_update(ctx, input, ilen, 128);
-}
+    esp_sha_unlock_memory_block();
 
-/*
- * SHA-512 final digest
- */
-void esp_sha512_finish( esp_sha_context *ctx, unsigned char output[64] )
-{
-    ets_sha_finish(&ctx->context, ctx->context_type, output);
-    esp_sha_release_hardware();
+    /* Note: deliberately not waiting for this operation to complete,
+       as a performance tweak - delay waiting until the next time we need the SHA
+       unit, instead.
+    */
 }
 
-/*
- * Full SHA-512 calculation
- */
-void esp_sha512( const unsigned char *input, size_t ilen, unsigned char output[64], int is384 )
+void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output)
 {
-    esp_sha_context ctx;
+    size_t block_len = block_length(sha_type);
 
-    esp_sha512_init( &ctx );
-    esp_sha512_start( &ctx, is384 );
-    esp_sha512_update( &ctx, input, ilen );
-    esp_sha512_finish( &ctx, output );
-    esp_sha512_free( &ctx );
-}
+    esp_sha_lock_engine(sha_type);
 
-////
+    SHA_CTX ctx;
+    ets_sha_init(&ctx);
+    while(ilen > 0) {
+        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);
+        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);
+    esp_sha_unlock_memory_block();
 
+    esp_sha_unlock_engine(sha_type);
+}

+ 139 - 185
components/esp32/include/hwcrypto/sha.h

@@ -1,246 +1,200 @@
-/*
- *  ESP32 hardware accelerated SHA1/256/512 implementation
- *  based on mbedTLS FIPS-197 compliant version.
- *
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- *  Additions Copyright (C) 2016, Espressif Systems (Shanghai) PTE Ltd
- *  SPDX-License-Identifier: Apache-2.0
- *
- *  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.
- *
- */
+// Copyright 2015-2016 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.
 #ifndef _ESP_SHA_H_
 #define _ESP_SHA_H_
 
 #include "rom/sha.h"
-
 #include "esp_types.h"
 
+/** @brief Low-level support functions for the hardware SHA engine
+ *
+ * @note If you're looking for a SHA API to use, try mbedtls component
+ * mbedtls/shaXX.h. That API supports hardware acceleration.
+ *
+ * The API in this header provides some building blocks for implementing a
+ * full SHA API such as the one in mbedtls, and also a basic SHA function esp_sha().
+ *
+ * Some technical details about the hardware SHA engine:
+ *
+ * - SHA accelerator engine calculates one digest at a time, per SHA
+ *   algorithm type. It initialises and maintains the digest state
+ *   internally. It is possible to read out an in-progress SHA digest
+ *   state, but it is not possible to restore a SHA digest state
+ *   into the engine.
+ *
+ * - The memory block SHA_TEXT_BASE is shared between all SHA digest
+ *   engines, so all engines must be idle before this memory block is
+ *   modified.
+ *
+ */
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-/**
- * \brief          SHA-1 context structure
- */
-typedef struct {
-    /* both types defined in rom/sha.h */
-    SHA_CTX context;
-    enum SHA_TYPE context_type;
-} esp_sha_context;
+/* Defined in rom/sha.h */
+typedef enum SHA_TYPE esp_sha_type;
 
-/**
- * \brief Lock access to SHA hardware unit
+/** @brief Calculate SHA1 or SHA2 sum of some data, using hardware SHA engine
  *
- * SHA hardware unit can only be used by one
- * consumer at a time.
+ * @note For more versatile SHA calculations, where data doesn't need
+ * to be passed all at once, try the mbedTLS mbedtls/shaX.h APIs. The
+ * hardware-accelerated mbedTLS implementation is also faster when
+ * hashing large amounts of data.
  *
- * esp_sha_xxx API calls automatically manage locking & unlocking of
- * hardware, this function is only needed if you want to call
- * ets_sha_xxx functions directly.
- */
-void esp_sha_acquire_hardware( void );
-
-/**
- * \brief Unlock access to SHA hardware unit
+ * @note It is not necessary to lock any SHA hardware before calling
+ * this function, thread safety is managed internally.
  *
- * esp_sha_xxx API calls automatically manage locking & unlocking of
- * hardware, this function is only needed if you want to call
- * ets_sha_xxx functions directly.
- */
-void esp_sha_release_hardware( void );
-
-/**
- * \brief          Initialize SHA-1 context
+ * @note If a TLS connection is open then this function may block
+ * indefinitely waiting for a SHA engine to become available. Use the
+ * mbedTLS SHA API to avoid this problem.
  *
- * \param ctx      SHA-1 context to be initialized
- */
-void esp_sha1_init( esp_sha_context *ctx );
-
-/**
- * \brief          Clear SHA-1 context
+ * @param sha_type SHA algorithm to use.
  *
- * \param ctx      SHA-1 context to be cleared
- */
-void esp_sha1_free( esp_sha_context *ctx );
-
-/**
- * \brief          Clone (the state of) a SHA-1 context
+ * @param input Input data buffer.
  *
- * \param dst      The destination context
- * \param src      The context to be cloned
- */
-void esp_sha1_clone( esp_sha_context *dst, const esp_sha_context *src );
-
-/**
- * \brief          SHA-1 context setup
+ * @param ilen Length of input data in bytes.
  *
- * \param ctx      context to be initialized
+ * @param output Buffer for output SHA digest. Output is 20 bytes for
+ * sha_type SHA1, 32 bytes for sha_type SHA2_256, 48 bytes for
+ * sha_type SHA2_384, 64 bytes for sha_type SHA2_512.
  */
-void esp_sha1_start( esp_sha_context *ctx );
+void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output);
 
-/**
- * \brief          SHA-1 process buffer
+/* @brief Begin to execute a single SHA block operation
  *
- * \param ctx      SHA-1 context
- * \param input    buffer holding the  data
- * \param ilen     length of the input data
- */
-void esp_sha1_update( esp_sha_context *ctx, const unsigned char *input, size_t ilen );
-
-/**
- * \brief          SHA-1 final digest
+ * @note This is a piece of a SHA algorithm, rather than an entire SHA
+ * algorithm.
  *
- * \param ctx      SHA-1 context
- * \param output   SHA-1 checksum result
- */
-void esp_sha1_finish( esp_sha_context *ctx, unsigned char output[20] );
-
-/**
- * \brief          Calculate SHA-1 of input buffer
+ * @note Call esp_sha_try_lock_engine() before calling this
+ * function. Do not call esp_sha_lock_memory_block() beforehand, this
+ * is done inside the function.
  *
- * \param input    buffer holding the data
- * \param ilen     length of the input data
- * \param output   SHA-1 checksum result
- */
-void esp_sha1( const unsigned char *input, size_t ilen, unsigned char output[20] );
-
-/**
- * \brief          SHA-256 context structure
- */
-
-/**
- * \brief          Initialize SHA-256 context
+ * @param sha_type SHA algorithm to use.
  *
- * \param ctx      SHA-256 context to be initialized
- */
-void esp_sha256_init( esp_sha_context *ctx );
-
-/**
- * \brief          Clear SHA-256 context
+ * @param data_block Pointer to block of data. Block size is
+ * determined by algorithm (SHA1/SHA2_256 = 64 bytes,
+ * SHA2_384/SHA2_512 = 128 bytes)
  *
- * \param ctx      SHA-256 context to be cleared
- */
-void esp_sha256_free( esp_sha_context *ctx );
-
-/**
- * \brief          Clone (the state of) a SHA-256 context
+ * @param is_first_block If this parameter is true, the SHA state will
+ * be initialised (with the initial state of the given SHA algorithm)
+ * before the block is calculated. If false, the existing state of the
+ * SHA engine will be used.
  *
- * \param dst      The destination context
- * \param src      The context to be cloned
+ * @return As a performance optimisation, this function returns before
+ * the SHA block operation is complete. Both this function and
+ * esp_sha_read_state() will automatically wait for any previous
+ * operation to complete before they begin. If using the SHA registers
+ * directly in another way, call esp_sha_wait_idle() after calling this
+ * function but before accessing the SHA registers.
  */
-void esp_sha256_clone( esp_sha_context *dst, const esp_sha_context *src );
+void esp_sha_block(esp_sha_type sha_type, const void *data_block, bool is_first_block);
 
-/**
- * \brief          SHA-256 context setup
+/** @brief Read out the current state of the SHA digest loaded in the engine.
  *
- * \param ctx      context to be initialized
- * \param is224    0 = use SHA256, 1 = use SHA224
- */
-void esp_sha256_start( esp_sha_context *ctx, int is224 );
-
-/**
- * \brief          SHA-256 process buffer
+ * @note This is a piece of a SHA algorithm, rather than an entire SHA algorithm.
  *
- * \param ctx      SHA-256 context
- * \param input    buffer holding the  data
- * \param ilen     length of the input data
- */
-void esp_sha256_update( esp_sha_context *ctx, const unsigned char *input, size_t ilen );
-
-/**
- * \brief          SHA-256 final digest
+ * @note Call esp_sha_try_lock_engine() before calling this
+ * function. Do not call esp_sha_lock_memory_block() beforehand, this
+ * is done inside the function.
  *
- * \param ctx      SHA-256 context
- * \param output   SHA-224/256 checksum result
- */
-void esp_sha256_finish( esp_sha_context *ctx, unsigned char output[32] );
-
-/**
- * \brief          Calculate SHA-256 of input buffer
+ * If the SHA suffix padding block has been executed already, the
+ * value that is read is the SHA digest (in big endian
+ * format). Otherwise, the value that is read is an interim SHA state.
  *
- * \param input    buffer holding the data
- * \param ilen     length of the input data
- * \param output   SHA-224/256 checksum result
- * \param is224    0 = use SHA256, 1 = use SHA224
- */
-void esp_sha256( const unsigned char *input, size_t ilen, unsigned char output[32], int is224 );
-
-//
-
-/**
- * \brief          SHA-512 context structure
- */
-
-/**
- * \brief          Initialize SHA-512 context
+ * @param sha_type SHA algorithm in use.
+ *
+ * @param state Pointer to a memory buffer to hold the SHA state. Size
+ * is 20 bytes (SHA1), 64 bytes (SHA2_256), or 128 bytes (SHA2_384 or
+ * SHA2_512).
  *
- * \param ctx      SHA-512 context to be initialized
  */
-void esp_sha512_init( esp_sha_context *ctx );
+void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state);
 
 /**
- * \brief          Clear SHA-512 context
+ * @brief Obtain exclusive access to a particular SHA engine
+ *
+ * @param sha_type Type of SHA engine to use.
  *
- * \param ctx      SHA-512 context to be cleared
+ * Blocks until engine is available. Note: Can block indefinitely
+ * while a TLS connection is open, suggest using
+ * esp_sha_try_lock_engine() and failing over to software SHA.
  */
-void esp_sha512_free( esp_sha_context *ctx );
+void esp_sha_lock_engine(esp_sha_type sha_type);
 
 /**
- * \brief          Clone (the state of) a SHA-512 context
+ * @brief Try and obtain exclusive access to a particular SHA engine
  *
- * \param dst      The destination context
- * \param src      The context to be cloned
+ * @param sha_type Type of SHA engine to use.
+ *
+ * @return Returns true if the SHA engine is locked for exclusive
+ * use. Call esp_sha_unlock_sha_engine() when done.  Returns false if
+ * the SHA engine is already in use, caller should use software SHA
+ * algorithm for this digest.
  */
-void esp_sha512_clone( esp_sha_context *dst, const esp_sha_context *src );
+bool esp_sha_try_lock_engine(esp_sha_type sha_type);
 
 /**
- * \brief          SHA-512 context setup
+ * @brief Unlock an engine previously locked with esp_sha_lock_engine() or esp_sha_try_lock_engine()
  *
- * \param ctx      context to be initialized
- * \param is384    0 = use SHA512, 1 = use SHA384
+ * @param sha_type Type of engine to release.
  */
-void esp_sha512_start( esp_sha_context *ctx, int is384 );
+void esp_sha_unlock_engine(esp_sha_type sha_type);
 
 /**
- * \brief          SHA-512 process buffer
+ * @brief Acquire exclusive access to the SHA shared memory block at SHA_TEXT_BASE
+ *
+ * This memory block is shared across all the SHA algorithm types.
  *
- * \param ctx      SHA-512 context
- * \param input    buffer holding the  data
- * \param ilen     length of the input data
+ * Caller should have already locked a SHA engine before calling this function.
+ *
+ * Note that it is possible to obtain exclusive access to the memory block even
+ * while it is in use by the SHA engine. Caller should use esp_sha_wait_idle()
+ * to ensure the SHA engine is not reading from the memory block in hardware.
+ *
+ * @note You do not need to lock the memory block before calling esp_sha_block() or esp_sha_read_digest_state(), these functions handle memory block locking internally.
+ *
+ * Call esp_sha_unlock_memory_block() when done.
  */
-void esp_sha512_update( esp_sha_context *ctx, const unsigned char *input, size_t ilen );
+void esp_sha_lock_memory_block(void);
 
 /**
- * \brief          SHA-512 final digest
+ * @brief Release exclusive access to the SHA register memory block at SHA_TEXT_BASE
  *
- * \param ctx      SHA-512 context
- * \param output   SHA-384/512 checksum result
+ * Caller should have already locked a SHA engine before calling this function.
+ *
+ * Call following esp_sha_lock_memory_block().
  */
-void esp_sha512_finish( esp_sha_context *ctx, unsigned char output[64] );
+void esp_sha_unlock_memory_block(void);
 
-/**
- * \brief          Calculate SHA-512 of input buffer.
+/** @brief Wait for the SHA engine to finish any current operation
+ *
+ * @note This function does not ensure exclusive access to any SHA
+ * engine. Caller should use esp_sha_try_lock_engine() and
+ * esp_sha_lock_memory_block() as required.
+ *
+ * @note Functions declared in this header file wait for SHA engine
+ * completion automatically, so you don't need to use this API for
+ * these. However if accessing SHA registers directly, you will need
+ * to call this before accessing SHA registers if using the
+ * esp_sha_block() function.
+ *
+ * @note This function busy-waits, so wastes CPU resources.
+ * Best to delay calling until you are about to need it.
  *
- * \param input    buffer holding the data
- * \param ilen     length of the input data
- * \param output   SHA-384/512 checksum result
- * \param is384    0 = use SHA512, 1 = use SHA384
  */
-void esp_sha512( const unsigned char *input, size_t ilen, unsigned char output[64], int is384 );
-
-//
+void esp_sha_wait_idle(void);
 
 #ifdef __cplusplus
 }

+ 6 - 3
components/esp32/include/rom/sha.h

@@ -1,9 +1,10 @@
 /*
   ROM functions for hardware SHA support.
 
-  It is not recommended to use these functions directly,
-  use the wrapper functions in hwcrypto/sha.h instead.
-
+  It is not recommended to use these functions directly.  If using
+  them from esp-idf then use the esp_sha_lock_engine() and
+  esp_sha_lock_memory_block() functions in hwcrypto/sha.h to ensure
+  exclusive access.
  */
 // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
 //
@@ -38,6 +39,8 @@ enum SHA_TYPE {
     SHA2_256,
     SHA2_384,
     SHA2_512,
+
+
     SHA_INVALID = -1,
 };
 

+ 10 - 0
components/esp32/include/soc/dport_reg.h

@@ -94,6 +94,16 @@
 #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: */

+ 25 - 2
components/esp32/include/soc/hwcrypto_reg.h

@@ -30,8 +30,31 @@
 #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_ADDR                (DR_REG_RSA_BASE + 0X818)
+#define RSA_CLEAN_REG                 (DR_REG_RSA_BASE + 0x818)
+
+/* SHA acceleration registers */
+#define SHA_TEXT_BASE          ((DR_REG_SHA_BASE) + 0x00)
+
+#define SHA_1_START_REG         ((DR_REG_SHA_BASE) + 0x80)
+#define SHA_1_CONTINUE_REG      ((DR_REG_SHA_BASE) + 0x84)
+#define SHA_1_LOAD_REG          ((DR_REG_SHA_BASE) + 0x88)
+#define SHA_1_BUSY_REG          ((DR_REG_SHA_BASE) + 0x8c)
+
+#define SHA_256_START_REG       ((DR_REG_SHA_BASE) + 0x90)
+#define SHA_256_CONTINUE_REG    ((DR_REG_SHA_BASE) + 0x94)
+#define SHA_256_LOAD_REG        ((DR_REG_SHA_BASE) + 0x98)
+#define SHA_256_BUSY_REG        ((DR_REG_SHA_BASE) + 0x9c)
+
+#define SHA_384_START_REG       ((DR_REG_SHA_BASE) + 0xa0)
+#define SHA_384_CONTINUE_REG    ((DR_REG_SHA_BASE) + 0xa4)
+#define SHA_384_LOAD_REG        ((DR_REG_SHA_BASE) + 0xa8)
+#define SHA_384_BUSY_REG        ((DR_REG_SHA_BASE) + 0xac)
+
+#define SHA_512_START_REG       ((DR_REG_SHA_BASE) + 0xb0)
+#define SHA_512_CONTINUE_REG    ((DR_REG_SHA_BASE) + 0xb4)
+#define SHA_512_LOAD_REG        ((DR_REG_SHA_BASE) + 0xb8)
+#define SHA_512_BUSY_REG        ((DR_REG_SHA_BASE) + 0xbc)
 
 #endif

+ 1 - 0
components/esp32/include/soc/soc.h

@@ -142,6 +142,7 @@
 
 #define DR_REG_DPORT_BASE                       0x3ff00000
 #define DR_REG_RSA_BASE                         0x3ff02000
+#define DR_REG_SHA_BASE                         0x3ff03000
 #define DR_REG_UART_BASE                        0x3ff40000
 #define DR_REG_SPI1_BASE                        0x3ff42000
 #define DR_REG_SPI0_BASE                        0x3ff43000

+ 12 - 0
components/mbedtls/Kconfig

@@ -69,4 +69,16 @@ config MBEDTLS_MPI_INTERRUPT_NUM
         CPU interrupt number for MPI interrupt to connect to. Must be otherwise unused.
         Eventually this assignment will be handled automatically at runtime.
 
+config MBEDTLS_HARDWARE_SHA
+   bool "Enable hardware SHA acceleration"
+   default y
+   help
+       Enable hardware accelerated SHA1, SHA256, SHA384 & SHA512 in mbedTLS.
+
+       Due to a hardware limitation, hardware acceleration is only
+       guaranteed if SHA digests are calculated one at a time. If more
+       than one SHA digest is calculated at the same time, only will
+       be calculated fully in hardware and the rest will be calculated
+       (at least partially calculated) in software.
+
 endmenu

+ 0 - 1
components/mbedtls/component.mk

@@ -5,4 +5,3 @@
 COMPONENT_ADD_INCLUDEDIRS := port/include include
 
 COMPONENT_SRCDIRS := library port
-

+ 18 - 2
components/mbedtls/port/esp_bignum.c

@@ -34,6 +34,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"
@@ -72,7 +74,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
@@ -80,7 +91,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);
 }
 

+ 395 - 0
components/mbedtls/port/esp_sha1.c

@@ -0,0 +1,395 @@
+/*
+ *  SHA-1 implementation with hardware ESP32 support added.
+ *  Uses mbedTLS software implementation for failover when concurrent
+ *  SHA operations are in use.
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  Additions Copyright (C) 2016, Espressif Systems (Shanghai) PTE LTD
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ */
+/*
+ *  The SHA-1 standard was published by NIST in 1993.
+ *
+ *  http://www.itl.nist.gov/fipspubs/fip180-1.htm
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_SHA1_C) && defined(MBEDTLS_SHA1_ALT)
+
+#include "mbedtls/sha1.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_SELF_TEST)
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_printf printf
+#endif /* MBEDTLS_PLATFORM_C */
+#endif /* MBEDTLS_SELF_TEST */
+
+#include "hwcrypto/sha.h"
+
+/* Implementation that should never be optimized out by the compiler */
+static void mbedtls_zeroize( void *v, size_t n ) {
+    volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
+}
+
+/*
+ * 32-bit integer manipulation macros (big endian)
+ */
+#ifndef GET_UINT32_BE
+#define GET_UINT32_BE(n,b,i)                            \
+{                                                       \
+    (n) = ( (uint32_t) (b)[(i)    ] << 24 )             \
+        | ( (uint32_t) (b)[(i) + 1] << 16 )             \
+        | ( (uint32_t) (b)[(i) + 2] <<  8 )             \
+        | ( (uint32_t) (b)[(i) + 3]       );            \
+}
+#endif
+
+#ifndef PUT_UINT32_BE
+#define PUT_UINT32_BE(n,b,i)                            \
+{                                                       \
+    (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \
+    (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \
+    (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \
+    (b)[(i) + 3] = (unsigned char) ( (n)       );       \
+}
+#endif
+
+void mbedtls_sha1_init( mbedtls_sha1_context *ctx )
+{
+    memset( ctx, 0, sizeof( mbedtls_sha1_context ) );
+}
+
+void mbedtls_sha1_free( mbedtls_sha1_context *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    if (ctx->mode == ESP_MBEDTLS_SHA1_HARDWARE) {
+        esp_sha_unlock_engine(SHA1);
+    }
+    mbedtls_zeroize( ctx, sizeof( mbedtls_sha1_context ) );
+}
+
+void mbedtls_sha1_clone( mbedtls_sha1_context *dst,
+                         const mbedtls_sha1_context *src )
+{
+    *dst = *src;
+
+    if (src->mode == ESP_MBEDTLS_SHA1_HARDWARE) {
+        /* Copy hardware digest state out to cloned state,
+           which will be a software digest.
+        */
+        esp_sha_read_digest_state(SHA1, dst->state);
+        dst->mode = ESP_MBEDTLS_SHA1_SOFTWARE;
+    }
+}
+
+
+/*
+ * SHA-1 context setup
+ */
+void mbedtls_sha1_starts( mbedtls_sha1_context *ctx )
+{
+    ctx->total[0] = 0;
+    ctx->total[1] = 0;
+
+    ctx->state[0] = 0x67452301;
+    ctx->state[1] = 0xEFCDAB89;
+    ctx->state[2] = 0x98BADCFE;
+    ctx->state[3] = 0x10325476;
+    ctx->state[4] = 0xC3D2E1F0;
+
+    if (ctx->mode == ESP_MBEDTLS_SHA1_HARDWARE) {
+        esp_sha_unlock_engine(SHA1);
+    }
+    ctx->mode = ESP_MBEDTLS_SHA1_UNUSED;
+}
+
+static void mbedtls_sha1_software_process( mbedtls_sha1_context *ctx, const unsigned char data[64] );
+
+void mbedtls_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] )
+{
+    bool first_block = false;
+    if (ctx->mode == ESP_MBEDTLS_SHA1_UNUSED) {
+        /* try to use hardware for this digest */
+        if (esp_sha_try_lock_engine(SHA1)) {
+            ctx->mode = ESP_MBEDTLS_SHA1_HARDWARE;
+            first_block = true;
+        } else {
+            ctx->mode = ESP_MBEDTLS_SHA1_SOFTWARE;
+        }
+    }
+
+    if (ctx->mode == ESP_MBEDTLS_SHA1_HARDWARE) {
+        esp_sha_block(SHA1, data, first_block);
+    } else {
+        mbedtls_sha1_software_process(ctx, data);
+    }
+}
+
+
+static void mbedtls_sha1_software_process( mbedtls_sha1_context *ctx, const unsigned char data[64] )
+{
+    uint32_t temp, W[16], A, B, C, D, E;
+
+    GET_UINT32_BE( W[ 0], data,  0 );
+    GET_UINT32_BE( W[ 1], data,  4 );
+    GET_UINT32_BE( W[ 2], data,  8 );
+    GET_UINT32_BE( W[ 3], data, 12 );
+    GET_UINT32_BE( W[ 4], data, 16 );
+    GET_UINT32_BE( W[ 5], data, 20 );
+    GET_UINT32_BE( W[ 6], data, 24 );
+    GET_UINT32_BE( W[ 7], data, 28 );
+    GET_UINT32_BE( W[ 8], data, 32 );
+    GET_UINT32_BE( W[ 9], data, 36 );
+    GET_UINT32_BE( W[10], data, 40 );
+    GET_UINT32_BE( W[11], data, 44 );
+    GET_UINT32_BE( W[12], data, 48 );
+    GET_UINT32_BE( W[13], data, 52 );
+    GET_UINT32_BE( W[14], data, 56 );
+    GET_UINT32_BE( W[15], data, 60 );
+
+#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
+
+#define R(t)                                            \
+(                                                       \
+    temp = W[( t -  3 ) & 0x0F] ^ W[( t - 8 ) & 0x0F] ^ \
+           W[( t - 14 ) & 0x0F] ^ W[  t       & 0x0F],  \
+    ( W[t & 0x0F] = S(temp,1) )                         \
+)
+
+#define P(a,b,c,d,e,x)                                  \
+{                                                       \
+    e += S(a,5) + F(b,c,d) + K + x; b = S(b,30);        \
+}
+
+    A = ctx->state[0];
+    B = ctx->state[1];
+    C = ctx->state[2];
+    D = ctx->state[3];
+    E = ctx->state[4];
+
+#define F(x,y,z) (z ^ (x & (y ^ z)))
+#define K 0x5A827999
+
+    P( A, B, C, D, E, W[0]  );
+    P( E, A, B, C, D, W[1]  );
+    P( D, E, A, B, C, W[2]  );
+    P( C, D, E, A, B, W[3]  );
+    P( B, C, D, E, A, W[4]  );
+    P( A, B, C, D, E, W[5]  );
+    P( E, A, B, C, D, W[6]  );
+    P( D, E, A, B, C, W[7]  );
+    P( C, D, E, A, B, W[8]  );
+    P( B, C, D, E, A, W[9]  );
+    P( A, B, C, D, E, W[10] );
+    P( E, A, B, C, D, W[11] );
+    P( D, E, A, B, C, W[12] );
+    P( C, D, E, A, B, W[13] );
+    P( B, C, D, E, A, W[14] );
+    P( A, B, C, D, E, W[15] );
+    P( E, A, B, C, D, R(16) );
+    P( D, E, A, B, C, R(17) );
+    P( C, D, E, A, B, R(18) );
+    P( B, C, D, E, A, R(19) );
+
+#undef K
+#undef F
+
+#define F(x,y,z) (x ^ y ^ z)
+#define K 0x6ED9EBA1
+
+    P( A, B, C, D, E, R(20) );
+    P( E, A, B, C, D, R(21) );
+    P( D, E, A, B, C, R(22) );
+    P( C, D, E, A, B, R(23) );
+    P( B, C, D, E, A, R(24) );
+    P( A, B, C, D, E, R(25) );
+    P( E, A, B, C, D, R(26) );
+    P( D, E, A, B, C, R(27) );
+    P( C, D, E, A, B, R(28) );
+    P( B, C, D, E, A, R(29) );
+    P( A, B, C, D, E, R(30) );
+    P( E, A, B, C, D, R(31) );
+    P( D, E, A, B, C, R(32) );
+    P( C, D, E, A, B, R(33) );
+    P( B, C, D, E, A, R(34) );
+    P( A, B, C, D, E, R(35) );
+    P( E, A, B, C, D, R(36) );
+    P( D, E, A, B, C, R(37) );
+    P( C, D, E, A, B, R(38) );
+    P( B, C, D, E, A, R(39) );
+
+#undef K
+#undef F
+
+#define F(x,y,z) ((x & y) | (z & (x | y)))
+#define K 0x8F1BBCDC
+
+    P( A, B, C, D, E, R(40) );
+    P( E, A, B, C, D, R(41) );
+    P( D, E, A, B, C, R(42) );
+    P( C, D, E, A, B, R(43) );
+    P( B, C, D, E, A, R(44) );
+    P( A, B, C, D, E, R(45) );
+    P( E, A, B, C, D, R(46) );
+    P( D, E, A, B, C, R(47) );
+    P( C, D, E, A, B, R(48) );
+    P( B, C, D, E, A, R(49) );
+    P( A, B, C, D, E, R(50) );
+    P( E, A, B, C, D, R(51) );
+    P( D, E, A, B, C, R(52) );
+    P( C, D, E, A, B, R(53) );
+    P( B, C, D, E, A, R(54) );
+    P( A, B, C, D, E, R(55) );
+    P( E, A, B, C, D, R(56) );
+    P( D, E, A, B, C, R(57) );
+    P( C, D, E, A, B, R(58) );
+    P( B, C, D, E, A, R(59) );
+
+#undef K
+#undef F
+
+#define F(x,y,z) (x ^ y ^ z)
+#define K 0xCA62C1D6
+
+    P( A, B, C, D, E, R(60) );
+    P( E, A, B, C, D, R(61) );
+    P( D, E, A, B, C, R(62) );
+    P( C, D, E, A, B, R(63) );
+    P( B, C, D, E, A, R(64) );
+    P( A, B, C, D, E, R(65) );
+    P( E, A, B, C, D, R(66) );
+    P( D, E, A, B, C, R(67) );
+    P( C, D, E, A, B, R(68) );
+    P( B, C, D, E, A, R(69) );
+    P( A, B, C, D, E, R(70) );
+    P( E, A, B, C, D, R(71) );
+    P( D, E, A, B, C, R(72) );
+    P( C, D, E, A, B, R(73) );
+    P( B, C, D, E, A, R(74) );
+    P( A, B, C, D, E, R(75) );
+    P( E, A, B, C, D, R(76) );
+    P( D, E, A, B, C, R(77) );
+    P( C, D, E, A, B, R(78) );
+    P( B, C, D, E, A, R(79) );
+
+#undef K
+#undef F
+
+    ctx->state[0] += A;
+    ctx->state[1] += B;
+    ctx->state[2] += C;
+    ctx->state[3] += D;
+    ctx->state[4] += E;
+}
+
+/*
+ * SHA-1 process buffer
+ */
+void mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen )
+{
+    size_t fill;
+    uint32_t left;
+
+    if( ilen == 0 )
+        return;
+
+    left = ctx->total[0] & 0x3F;
+    fill = 64 - left;
+
+    ctx->total[0] += (uint32_t) ilen;
+    ctx->total[0] &= 0xFFFFFFFF;
+
+    if( ctx->total[0] < (uint32_t) ilen )
+        ctx->total[1]++;
+
+    if( left && ilen >= fill )
+    {
+        memcpy( (void *) (ctx->buffer + left), input, fill );
+        mbedtls_sha1_process( ctx, ctx->buffer );
+        input += fill;
+        ilen  -= fill;
+        left = 0;
+    }
+
+    while( ilen >= 64 )
+    {
+        mbedtls_sha1_process( ctx, input );
+        input += 64;
+        ilen  -= 64;
+    }
+
+    if( ilen > 0 )
+        memcpy( (void *) (ctx->buffer + left), input, ilen );
+}
+
+static const unsigned char sha1_padding[64] =
+{
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*
+* SHA-1 final digest
+ */
+void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] )
+{
+    uint32_t last, padn;
+    uint32_t high, low;
+    unsigned char msglen[8];
+
+    high = ( ctx->total[0] >> 29 )
+         | ( ctx->total[1] <<  3 );
+    low  = ( ctx->total[0] <<  3 );
+
+    PUT_UINT32_BE( high, msglen, 0 );
+    PUT_UINT32_BE( low,  msglen, 4 );
+
+    last = ctx->total[0] & 0x3F;
+    padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
+
+    mbedtls_sha1_update( ctx, sha1_padding, padn );
+    mbedtls_sha1_update( ctx, msglen, 8 );
+
+    /* if state is in hardware, read it out */
+    if (ctx->mode == ESP_MBEDTLS_SHA1_HARDWARE) {
+        esp_sha_read_digest_state(SHA1, ctx->state);
+        esp_sha_unlock_engine(SHA1);
+        ctx->mode = ESP_MBEDTLS_SHA1_SOFTWARE;
+    }
+
+    PUT_UINT32_BE( ctx->state[0], output,  0 );
+    PUT_UINT32_BE( ctx->state[1], output,  4 );
+    PUT_UINT32_BE( ctx->state[2], output,  8 );
+    PUT_UINT32_BE( ctx->state[3], output, 12 );
+    PUT_UINT32_BE( ctx->state[4], output, 16 );
+
+}
+
+#endif /* MBEDTLS_SHA1_C && MBEDTLS_SHA1_ALT */

+ 367 - 0
components/mbedtls/port/esp_sha256.c

@@ -0,0 +1,367 @@
+/*
+ *  SHA-256 implementation with hardware ESP32 support added.
+ *  Uses mbedTLS software implementation for failover when concurrent
+ *  SHA operations are in use.
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  Additions Copyright (C) 2016, Espressif Systems (Shanghai) PTE LTD
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ */
+
+/*
+ *  The SHA-256 Secure Hash Standard was published by NIST in 2002.
+ *
+ *  http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_SHA256_C) && defined(MBEDTLS_SHA256_ALT)
+
+#include "mbedtls/sha256.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_SELF_TEST)
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_printf printf
+#endif /* MBEDTLS_PLATFORM_C */
+#endif /* MBEDTLS_SELF_TEST */
+
+#include "hwcrypto/sha.h"
+
+/* Implementation that should never be optimized out by the compiler */
+static void mbedtls_zeroize( void *v, size_t n ) {
+    volatile unsigned char *p = v; while( n-- ) *p++ = 0;
+}
+
+/*
+ * 32-bit integer manipulation macros (big endian)
+ */
+#ifndef GET_UINT32_BE
+#define GET_UINT32_BE(n,b,i)                            \
+do {                                                    \
+    (n) = ( (uint32_t) (b)[(i)    ] << 24 )             \
+        | ( (uint32_t) (b)[(i) + 1] << 16 )             \
+        | ( (uint32_t) (b)[(i) + 2] <<  8 )             \
+        | ( (uint32_t) (b)[(i) + 3]       );            \
+} while( 0 )
+#endif
+
+#ifndef PUT_UINT32_BE
+#define PUT_UINT32_BE(n,b,i)                            \
+do {                                                    \
+    (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \
+    (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \
+    (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \
+    (b)[(i) + 3] = (unsigned char) ( (n)       );       \
+} while( 0 )
+#endif
+
+void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
+{
+    memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
+}
+
+void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    if (ctx->mode == ESP_MBEDTLS_SHA256_HARDWARE) {
+        esp_sha_unlock_engine(SHA2_256);
+    }
+    mbedtls_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
+}
+
+void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
+                           const mbedtls_sha256_context *src )
+{
+    *dst = *src;
+
+    if (src->mode == ESP_MBEDTLS_SHA256_HARDWARE) {
+        /* Copy hardware digest state out to cloned state,
+           which will become a software digest.
+        */
+        esp_sha_read_digest_state(SHA2_256, dst->state);
+        dst->mode = ESP_MBEDTLS_SHA256_SOFTWARE;
+    }
+}
+
+/*
+ * SHA-256 context setup
+ */
+void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 )
+{
+    ctx->total[0] = 0;
+    ctx->total[1] = 0;
+
+    if( is224 == 0 )
+    {
+        /* SHA-256 */
+        ctx->state[0] = 0x6A09E667;
+        ctx->state[1] = 0xBB67AE85;
+        ctx->state[2] = 0x3C6EF372;
+        ctx->state[3] = 0xA54FF53A;
+        ctx->state[4] = 0x510E527F;
+        ctx->state[5] = 0x9B05688C;
+        ctx->state[6] = 0x1F83D9AB;
+        ctx->state[7] = 0x5BE0CD19;
+    }
+    else
+    {
+        /* SHA-224 */
+        ctx->state[0] = 0xC1059ED8;
+        ctx->state[1] = 0x367CD507;
+        ctx->state[2] = 0x3070DD17;
+        ctx->state[3] = 0xF70E5939;
+        ctx->state[4] = 0xFFC00B31;
+        ctx->state[5] = 0x68581511;
+        ctx->state[6] = 0x64F98FA7;
+        ctx->state[7] = 0xBEFA4FA4;
+    }
+
+    ctx->is224 = is224;
+    if (ctx->mode == ESP_MBEDTLS_SHA256_HARDWARE) {
+        esp_sha_unlock_engine(SHA2_256);
+    }
+    ctx->mode = ESP_MBEDTLS_SHA256_UNUSED;
+}
+
+#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
+static const uint32_t K[] =
+{
+    0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
+    0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
+    0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
+    0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
+    0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
+    0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
+    0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
+    0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
+    0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
+    0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
+    0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
+    0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
+    0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
+    0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
+    0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
+    0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
+};
+
+#define  SHR(x,n) ((x & 0xFFFFFFFF) >> n)
+#define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
+
+#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^  SHR(x, 3))
+#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^  SHR(x,10))
+
+#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
+#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
+
+#define F0(x,y,z) ((x & y) | (z & (x | y)))
+#define F1(x,y,z) (z ^ (x & (y ^ z)))
+
+#define R(t)                                    \
+(                                               \
+    W[t] = S1(W[t -  2]) + W[t -  7] +          \
+           S0(W[t - 15]) + W[t - 16]            \
+)
+
+#define P(a,b,c,d,e,f,g,h,x,K)                  \
+{                                               \
+    temp1 = h + S3(e) + F1(e,f,g) + K + x;      \
+    temp2 = S2(a) + F0(a,b,c);                  \
+    d += temp1; h = temp1 + temp2;              \
+}
+
+static void mbedtls_sha256_software_process( mbedtls_sha256_context *ctx, const unsigned char data[64] );
+
+void mbedtls_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] )
+{
+    bool first_block = false;
+
+    if (ctx->mode == ESP_MBEDTLS_SHA256_UNUSED) {
+        /* try to use hardware for this digest */
+        if (!ctx->is224 && esp_sha_try_lock_engine(SHA2_256)) {
+            ctx->mode = ESP_MBEDTLS_SHA256_HARDWARE;
+            first_block = true;
+        } else {
+            ctx->mode = ESP_MBEDTLS_SHA256_SOFTWARE;
+        }
+    }
+
+    if (ctx->mode == ESP_MBEDTLS_SHA256_HARDWARE) {
+        esp_sha_block(SHA2_256, data, first_block);
+    } else {
+        mbedtls_sha256_software_process(ctx, data);
+    }
+}
+
+
+static void mbedtls_sha256_software_process( mbedtls_sha256_context *ctx, const unsigned char data[64] )
+{
+    uint32_t temp1, temp2, W[64];
+    uint32_t A[8];
+    unsigned int i;
+
+    for( i = 0; i < 8; i++ )
+        A[i] = ctx->state[i];
+
+#if defined(MBEDTLS_SHA256_SMALLER)
+    for( i = 0; i < 64; i++ )
+    {
+        if( i < 16 )
+            GET_UINT32_BE( W[i], data, 4 * i );
+        else
+            R( i );
+
+        P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] );
+
+        temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3];
+        A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1;
+    }
+#else /* MBEDTLS_SHA256_SMALLER */
+    for( i = 0; i < 16; i++ )
+        GET_UINT32_BE( W[i], data, 4 * i );
+
+    for( i = 0; i < 16; i += 8 )
+    {
+        P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i+0], K[i+0] );
+        P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i+1], K[i+1] );
+        P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i+2], K[i+2] );
+        P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i+3], K[i+3] );
+        P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i+4], K[i+4] );
+        P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i+5], K[i+5] );
+        P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i+6], K[i+6] );
+        P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i+7], K[i+7] );
+    }
+
+    for( i = 16; i < 64; i += 8 )
+    {
+        P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(i+0), K[i+0] );
+        P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(i+1), K[i+1] );
+        P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(i+2), K[i+2] );
+        P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(i+3), K[i+3] );
+        P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(i+4), K[i+4] );
+        P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(i+5), K[i+5] );
+        P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(i+6), K[i+6] );
+        P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(i+7), K[i+7] );
+    }
+#endif /* MBEDTLS_SHA256_SMALLER */
+
+    for( i = 0; i < 8; i++ )
+        ctx->state[i] += A[i];
+}
+#endif /* !MBEDTLS_SHA256_PROCESS_ALT */
+
+/*
+ * SHA-256 process buffer
+ */
+void mbedtls_sha256_update( mbedtls_sha256_context *ctx, const unsigned char *input,
+                    size_t ilen )
+{
+    size_t fill;
+    uint32_t left;
+
+    if( ilen == 0 )
+        return;
+
+    left = ctx->total[0] & 0x3F;
+    fill = 64 - left;
+
+    ctx->total[0] += (uint32_t) ilen;
+    ctx->total[0] &= 0xFFFFFFFF;
+
+    if( ctx->total[0] < (uint32_t) ilen )
+        ctx->total[1]++;
+
+    if( left && ilen >= fill )
+    {
+        memcpy( (void *) (ctx->buffer + left), input, fill );
+        mbedtls_sha256_process( ctx, ctx->buffer );
+        input += fill;
+        ilen  -= fill;
+        left = 0;
+    }
+
+    while( ilen >= 64 )
+    {
+        mbedtls_sha256_process( ctx, input );
+        input += 64;
+        ilen  -= 64;
+    }
+
+    if( ilen > 0 )
+        memcpy( (void *) (ctx->buffer + left), input, ilen );
+}
+
+static const unsigned char sha256_padding[64] =
+{
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*
+ * SHA-256 final digest
+ */
+void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char output[32] )
+{
+    uint32_t last, padn;
+    uint32_t high, low;
+    unsigned char msglen[8];
+
+    high = ( ctx->total[0] >> 29 )
+         | ( ctx->total[1] <<  3 );
+    low  = ( ctx->total[0] <<  3 );
+
+    PUT_UINT32_BE( high, msglen, 0 );
+    PUT_UINT32_BE( low,  msglen, 4 );
+
+    last = ctx->total[0] & 0x3F;
+    padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
+
+    mbedtls_sha256_update( ctx, sha256_padding, padn );
+    mbedtls_sha256_update( ctx, msglen, 8 );
+
+    /* if state is in hardware, read it out */
+    if (ctx->mode == ESP_MBEDTLS_SHA256_HARDWARE) {
+        esp_sha_read_digest_state(SHA2_256, ctx->state);
+        esp_sha_unlock_engine(SHA2_256);
+        ctx->mode = ESP_MBEDTLS_SHA256_SOFTWARE;
+    }
+
+    PUT_UINT32_BE( ctx->state[0], output,  0 );
+    PUT_UINT32_BE( ctx->state[1], output,  4 );
+    PUT_UINT32_BE( ctx->state[2], output,  8 );
+    PUT_UINT32_BE( ctx->state[3], output, 12 );
+    PUT_UINT32_BE( ctx->state[4], output, 16 );
+    PUT_UINT32_BE( ctx->state[5], output, 20 );
+    PUT_UINT32_BE( ctx->state[6], output, 24 );
+
+    if( ctx->is224 == 0 )
+        PUT_UINT32_BE( ctx->state[7], output, 28 );
+}
+
+#endif /* MBEDTLS_SHA256_C && MBEDTLS_SHA256_ALT */

+ 408 - 0
components/mbedtls/port/esp_sha512.c

@@ -0,0 +1,408 @@
+/*
+ *  SHA-512 implementation with hardware ESP32 support added.
+ *  Uses mbedTLS software implementation for failover when concurrent
+ *  SHA operations are in use.
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  Additions Copyright (C) 2016, Espressif Systems (Shanghai) PTE LTD
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ */
+
+/*
+ *  The SHA-512 Secure Hash Standard was published by NIST in 2002.
+ *
+ *  http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_SHA512_ALT)
+
+#include "mbedtls/sha512.h"
+
+#if defined(_MSC_VER) || defined(__WATCOMC__)
+  #define UL64(x) x##ui64
+#else
+  #define UL64(x) x##ULL
+#endif
+
+#include <string.h>
+
+#if defined(MBEDTLS_SELF_TEST)
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_printf printf
+#endif /* MBEDTLS_PLATFORM_C */
+#endif /* MBEDTLS_SELF_TEST */
+
+#include "hwcrypto/sha.h"
+
+inline static esp_sha_type sha_type(const mbedtls_sha512_context *ctx)
+{
+    return ctx->is384 ? SHA2_384 : SHA2_512;
+}
+
+/* Implementation that should never be optimized out by the compiler */
+static void mbedtls_zeroize( void *v, size_t n ) {
+    volatile unsigned char *p = v; while( n-- ) *p++ = 0;
+}
+
+/*
+ * 64-bit integer manipulation macros (big endian)
+ */
+#ifndef GET_UINT64_BE
+#define GET_UINT64_BE(n,b,i)                            \
+{                                                       \
+    (n) = ( (uint64_t) (b)[(i)    ] << 56 )       \
+        | ( (uint64_t) (b)[(i) + 1] << 48 )       \
+        | ( (uint64_t) (b)[(i) + 2] << 40 )       \
+        | ( (uint64_t) (b)[(i) + 3] << 32 )       \
+        | ( (uint64_t) (b)[(i) + 4] << 24 )       \
+        | ( (uint64_t) (b)[(i) + 5] << 16 )       \
+        | ( (uint64_t) (b)[(i) + 6] <<  8 )       \
+        | ( (uint64_t) (b)[(i) + 7]       );      \
+}
+#endif /* GET_UINT64_BE */
+
+#ifndef PUT_UINT64_BE
+#define PUT_UINT64_BE(n,b,i)                            \
+{                                                       \
+    (b)[(i)    ] = (unsigned char) ( (n) >> 56 );       \
+    (b)[(i) + 1] = (unsigned char) ( (n) >> 48 );       \
+    (b)[(i) + 2] = (unsigned char) ( (n) >> 40 );       \
+    (b)[(i) + 3] = (unsigned char) ( (n) >> 32 );       \
+    (b)[(i) + 4] = (unsigned char) ( (n) >> 24 );       \
+    (b)[(i) + 5] = (unsigned char) ( (n) >> 16 );       \
+    (b)[(i) + 6] = (unsigned char) ( (n) >>  8 );       \
+    (b)[(i) + 7] = (unsigned char) ( (n)       );       \
+}
+#endif /* PUT_UINT64_BE */
+
+void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
+{
+    memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
+}
+
+void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    if (ctx->mode == ESP_MBEDTLS_SHA512_HARDWARE) {
+        esp_sha_unlock_engine(sha_type(ctx));
+    }
+    mbedtls_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
+}
+
+void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
+                           const mbedtls_sha512_context *src )
+{
+    *dst = *src;
+
+    if (src->mode == ESP_MBEDTLS_SHA512_HARDWARE) {
+        /* Copy hardware digest state out to cloned state,
+           which will be a software digest.
+        */
+        esp_sha_read_digest_state(sha_type(dst), dst->state);
+        dst->mode = ESP_MBEDTLS_SHA512_SOFTWARE;
+    }
+}
+
+
+/*
+ * SHA-512 context setup
+ */
+void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, int is384 )
+{
+    ctx->total[0] = 0;
+    ctx->total[1] = 0;
+
+    if( is384 == 0 )
+    {
+        /* SHA-512 */
+        ctx->state[0] = UL64(0x6A09E667F3BCC908);
+        ctx->state[1] = UL64(0xBB67AE8584CAA73B);
+        ctx->state[2] = UL64(0x3C6EF372FE94F82B);
+        ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
+        ctx->state[4] = UL64(0x510E527FADE682D1);
+        ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
+        ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
+        ctx->state[7] = UL64(0x5BE0CD19137E2179);
+    }
+    else
+    {
+        /* SHA-384 */
+        ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
+        ctx->state[1] = UL64(0x629A292A367CD507);
+        ctx->state[2] = UL64(0x9159015A3070DD17);
+        ctx->state[3] = UL64(0x152FECD8F70E5939);
+        ctx->state[4] = UL64(0x67332667FFC00B31);
+        ctx->state[5] = UL64(0x8EB44A8768581511);
+        ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
+        ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
+    }
+
+    ctx->is384 = is384;
+    if (ctx->mode == ESP_MBEDTLS_SHA512_HARDWARE) {
+        esp_sha_unlock_engine(sha_type(ctx));
+    }
+    ctx->mode = ESP_MBEDTLS_SHA512_UNUSED;
+}
+
+
+/*
+ * Round constants
+ */
+static const uint64_t K[80] =
+{
+    UL64(0x428A2F98D728AE22),  UL64(0x7137449123EF65CD),
+    UL64(0xB5C0FBCFEC4D3B2F),  UL64(0xE9B5DBA58189DBBC),
+    UL64(0x3956C25BF348B538),  UL64(0x59F111F1B605D019),
+    UL64(0x923F82A4AF194F9B),  UL64(0xAB1C5ED5DA6D8118),
+    UL64(0xD807AA98A3030242),  UL64(0x12835B0145706FBE),
+    UL64(0x243185BE4EE4B28C),  UL64(0x550C7DC3D5FFB4E2),
+    UL64(0x72BE5D74F27B896F),  UL64(0x80DEB1FE3B1696B1),
+    UL64(0x9BDC06A725C71235),  UL64(0xC19BF174CF692694),
+    UL64(0xE49B69C19EF14AD2),  UL64(0xEFBE4786384F25E3),
+    UL64(0x0FC19DC68B8CD5B5),  UL64(0x240CA1CC77AC9C65),
+    UL64(0x2DE92C6F592B0275),  UL64(0x4A7484AA6EA6E483),
+    UL64(0x5CB0A9DCBD41FBD4),  UL64(0x76F988DA831153B5),
+    UL64(0x983E5152EE66DFAB),  UL64(0xA831C66D2DB43210),
+    UL64(0xB00327C898FB213F),  UL64(0xBF597FC7BEEF0EE4),
+    UL64(0xC6E00BF33DA88FC2),  UL64(0xD5A79147930AA725),
+    UL64(0x06CA6351E003826F),  UL64(0x142929670A0E6E70),
+    UL64(0x27B70A8546D22FFC),  UL64(0x2E1B21385C26C926),
+    UL64(0x4D2C6DFC5AC42AED),  UL64(0x53380D139D95B3DF),
+    UL64(0x650A73548BAF63DE),  UL64(0x766A0ABB3C77B2A8),
+    UL64(0x81C2C92E47EDAEE6),  UL64(0x92722C851482353B),
+    UL64(0xA2BFE8A14CF10364),  UL64(0xA81A664BBC423001),
+    UL64(0xC24B8B70D0F89791),  UL64(0xC76C51A30654BE30),
+    UL64(0xD192E819D6EF5218),  UL64(0xD69906245565A910),
+    UL64(0xF40E35855771202A),  UL64(0x106AA07032BBD1B8),
+    UL64(0x19A4C116B8D2D0C8),  UL64(0x1E376C085141AB53),
+    UL64(0x2748774CDF8EEB99),  UL64(0x34B0BCB5E19B48A8),
+    UL64(0x391C0CB3C5C95A63),  UL64(0x4ED8AA4AE3418ACB),
+    UL64(0x5B9CCA4F7763E373),  UL64(0x682E6FF3D6B2B8A3),
+    UL64(0x748F82EE5DEFB2FC),  UL64(0x78A5636F43172F60),
+    UL64(0x84C87814A1F0AB72),  UL64(0x8CC702081A6439EC),
+    UL64(0x90BEFFFA23631E28),  UL64(0xA4506CEBDE82BDE9),
+    UL64(0xBEF9A3F7B2C67915),  UL64(0xC67178F2E372532B),
+    UL64(0xCA273ECEEA26619C),  UL64(0xD186B8C721C0C207),
+    UL64(0xEADA7DD6CDE0EB1E),  UL64(0xF57D4F7FEE6ED178),
+    UL64(0x06F067AA72176FBA),  UL64(0x0A637DC5A2C898A6),
+    UL64(0x113F9804BEF90DAE),  UL64(0x1B710B35131C471B),
+    UL64(0x28DB77F523047D84),  UL64(0x32CAAB7B40C72493),
+    UL64(0x3C9EBE0A15C9BEBC),  UL64(0x431D67C49C100D4C),
+    UL64(0x4CC5D4BECB3E42B6),  UL64(0x597F299CFC657E2A),
+    UL64(0x5FCB6FAB3AD6FAEC),  UL64(0x6C44198C4A475817)
+};
+
+static void mbedtls_sha512_software_process( mbedtls_sha512_context *ctx, const unsigned char data[128] );
+
+void mbedtls_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] )
+{
+    bool first_block = false;
+
+    if (ctx->mode == ESP_MBEDTLS_SHA512_UNUSED) {
+        /* try to use hardware for this digest */
+        if (esp_sha_try_lock_engine(sha_type(ctx))) {
+            ctx->mode = ESP_MBEDTLS_SHA512_HARDWARE;
+            first_block = true;
+        } else {
+            ctx->mode = ESP_MBEDTLS_SHA512_SOFTWARE;
+        }
+    }
+
+    if (ctx->mode == ESP_MBEDTLS_SHA512_HARDWARE) {
+        esp_sha_block(sha_type(ctx), data, first_block);
+    } else {
+        mbedtls_sha512_software_process(ctx, data);
+    }
+}
+
+
+
+static void mbedtls_sha512_software_process( mbedtls_sha512_context *ctx, const unsigned char data[128] )
+{
+    int i;
+    uint64_t temp1, temp2, W[80];
+    uint64_t A, B, C, D, E, F, G, H;
+
+#define  SHR(x,n) (x >> n)
+#define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
+
+#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^  SHR(x, 7))
+#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^  SHR(x, 6))
+
+#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
+#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
+
+#define F0(x,y,z) ((x & y) | (z & (x | y)))
+#define F1(x,y,z) (z ^ (x & (y ^ z)))
+
+#define P(a,b,c,d,e,f,g,h,x,K)                  \
+{                                               \
+    temp1 = h + S3(e) + F1(e,f,g) + K + x;      \
+    temp2 = S2(a) + F0(a,b,c);                  \
+    d += temp1; h = temp1 + temp2;              \
+}
+
+    for( i = 0; i < 16; i++ )
+    {
+        GET_UINT64_BE( W[i], data, i << 3 );
+    }
+
+    for( ; i < 80; i++ )
+    {
+        W[i] = S1(W[i -  2]) + W[i -  7] +
+               S0(W[i - 15]) + W[i - 16];
+    }
+
+    A = ctx->state[0];
+    B = ctx->state[1];
+    C = ctx->state[2];
+    D = ctx->state[3];
+    E = ctx->state[4];
+    F = ctx->state[5];
+    G = ctx->state[6];
+    H = ctx->state[7];
+    i = 0;
+
+    do
+    {
+        P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
+        P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
+        P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
+        P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
+        P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
+        P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
+        P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
+        P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
+    }
+    while( i < 80 );
+
+    ctx->state[0] += A;
+    ctx->state[1] += B;
+    ctx->state[2] += C;
+    ctx->state[3] += D;
+    ctx->state[4] += E;
+    ctx->state[5] += F;
+    ctx->state[6] += G;
+    ctx->state[7] += H;
+}
+
+/*
+ * SHA-512 process buffer
+ */
+void mbedtls_sha512_update( mbedtls_sha512_context *ctx, const unsigned char *input,
+                    size_t ilen )
+{
+    size_t fill;
+    unsigned int left;
+
+    if( ilen == 0 )
+        return;
+
+    left = (unsigned int) (ctx->total[0] & 0x7F);
+    fill = 128 - left;
+
+    ctx->total[0] += (uint64_t) ilen;
+
+    if( ctx->total[0] < (uint64_t) ilen )
+        ctx->total[1]++;
+
+    if( left && ilen >= fill )
+    {
+        memcpy( (void *) (ctx->buffer + left), input, fill );
+        mbedtls_sha512_process( ctx, ctx->buffer );
+        input += fill;
+        ilen  -= fill;
+        left = 0;
+    }
+
+    while( ilen >= 128 )
+    {
+        mbedtls_sha512_process( ctx, input );
+        input += 128;
+        ilen  -= 128;
+    }
+
+    if( ilen > 0 )
+        memcpy( (void *) (ctx->buffer + left), input, ilen );
+}
+
+static const unsigned char sha512_padding[128] =
+{
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*
+ * SHA-512 final digest
+ */
+void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, unsigned char output[64] )
+{
+    size_t last, padn;
+    uint64_t high, low;
+    unsigned char msglen[16];
+
+    high = ( ctx->total[0] >> 61 )
+         | ( ctx->total[1] <<  3 );
+    low  = ( ctx->total[0] <<  3 );
+
+    PUT_UINT64_BE( high, msglen, 0 );
+    PUT_UINT64_BE( low,  msglen, 8 );
+
+    last = (size_t)( ctx->total[0] & 0x7F );
+    padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
+
+    mbedtls_sha512_update( ctx, sha512_padding, padn );
+    mbedtls_sha512_update( ctx, msglen, 16 );
+
+    /* if state is in hardware, read it out */
+    if (ctx->mode == ESP_MBEDTLS_SHA512_HARDWARE) {
+        esp_sha_read_digest_state(sha_type(ctx), ctx->state);
+        esp_sha_unlock_engine(sha_type(ctx));
+        ctx->mode = ESP_MBEDTLS_SHA512_SOFTWARE;
+    }
+
+    PUT_UINT64_BE( ctx->state[0], output,  0 );
+    PUT_UINT64_BE( ctx->state[1], output,  8 );
+    PUT_UINT64_BE( ctx->state[2], output, 16 );
+    PUT_UINT64_BE( ctx->state[3], output, 24 );
+    PUT_UINT64_BE( ctx->state[4], output, 32 );
+    PUT_UINT64_BE( ctx->state[5], output, 40 );
+
+    if( ctx->is384 == 0 )
+    {
+        PUT_UINT64_BE( ctx->state[6], output, 48 );
+        PUT_UINT64_BE( ctx->state[7], output, 56 );
+    }
+}
+
+#endif /* MBEDTLS_SHA512_C && MBEDTLS_SHA512_ALT */

+ 8 - 5
components/mbedtls/port/include/mbedtls/esp_config.h

@@ -243,11 +243,14 @@
 #define MBEDTLS_AES_ALT
 #endif
 
-/* Currently hardware SHA does not work with TLS handshake,
-   due to concurrency issue. Internal TW#7111. */
-//#define MBEDTLS_SHA1_ALT
-//#define MBEDTLS_SHA256_ALT
-//#define MBEDTLS_SHA512_ALT
+/* MBEDTLS_SHAxx_ALT to enable hardware SHA support
+   with software fallback.
+*/
+#ifdef CONFIG_MBEDTLS_HARDWARE_SHA
+#define MBEDTLS_SHA1_ALT
+#define MBEDTLS_SHA256_ALT
+#define MBEDTLS_SHA512_ALT
+#endif
 
 /* The following MPI (bignum) functions have ESP32 hardware support,
    Uncommenting these macros will use the hardware-accelerated

+ 87 - 22
components/mbedtls/port/include/sha1_alt.h

@@ -1,16 +1,25 @@
-// Copyright 2015-2016 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.
+/*
+ *  SHA-1 implementation with hardware ESP32 support added.
+ *  Uses mbedTLS software implementation for failover when concurrent
+ *  SHA operations are in use.
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  Additions Copyright (C) 2016, Espressif Systems (Shanghai) PTE LTD
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ */
 #ifndef _SHA1_ALT_H_
 #define _SHA1_ALT_H_
 
@@ -20,17 +29,73 @@ extern "C" {
 
 #if defined(MBEDTLS_SHA1_ALT)
 
-#include "hwcrypto/sha.h"
+typedef enum {
+    ESP_MBEDTLS_SHA1_UNUSED, /* first block hasn't been processed yet */
+    ESP_MBEDTLS_SHA1_HARDWARE, /* using hardware SHA engine */
+    ESP_MBEDTLS_SHA1_SOFTWARE, /* using software SHA */
+} esp_mbedtls_sha1_mode;
 
-typedef esp_sha_context mbedtls_sha1_context;
+/**
+ * \brief          SHA-1 context structure
+ */
+typedef struct
+{
+    uint32_t total[2];          /*!< number of bytes processed  */
+    uint32_t state[5];          /*!< intermediate digest state  */
+    unsigned char buffer[64];   /*!< data block being processed */
+    esp_mbedtls_sha1_mode mode;
+}
+mbedtls_sha1_context;
+
+/**
+ * \brief          Initialize SHA-1 context
+ *
+ * \param ctx      SHA-1 context to be initialized
+ */
+void mbedtls_sha1_init( mbedtls_sha1_context *ctx );
+
+/**
+ * \brief          Clear SHA-1 context
+ *
+ * \param ctx      SHA-1 context to be cleared
+ */
+void mbedtls_sha1_free( mbedtls_sha1_context *ctx );
+
+/**
+ * \brief          Clone (the state of) a SHA-1 context
+ *
+ * \param dst      The destination context
+ * \param src      The context to be cloned
+ */
+void mbedtls_sha1_clone( mbedtls_sha1_context *dst,
+                         const mbedtls_sha1_context *src );
+
+/**
+ * \brief          SHA-1 context setup
+ *
+ * \param ctx      context to be initialized
+ */
+void mbedtls_sha1_starts( mbedtls_sha1_context *ctx );
+
+/**
+ * \brief          SHA-1 process buffer
+ *
+ * \param ctx      SHA-1 context
+ * \param input    buffer holding the  data
+ * \param ilen     length of the input data
+ */
+void mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen );
+
+/**
+ * \brief          SHA-1 final digest
+ *
+ * \param ctx      SHA-1 context
+ * \param output   SHA-1 checksum result
+ */
+void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] );
 
-#define mbedtls_sha1_init       esp_sha1_init
-#define mbedtls_sha1_starts     esp_sha1_start
-#define mbedtls_sha1_clone      esp_sha1_clone
-#define mbedtls_sha1_update     esp_sha1_update
-#define mbedtls_sha1_finish     esp_sha1_finish
-#define mbedtls_sha1_free       esp_sha1_free
-#define mbedtls_sha1_process(...)
+/* Internal use */
+void mbedtls_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] );
 
 #endif
 

+ 90 - 22
components/mbedtls/port/include/sha256_alt.h

@@ -1,16 +1,25 @@
-// Copyright 2015-2016 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.
+/*
+ *  SHA-256 implementation with hardware ESP32 support added.
+ *  Uses mbedTLS software implementation for failover when concurrent
+ *  SHA operations are in use.
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  Additions Copyright (C) 2016, Espressif Systems (Shanghai) PTE LTD
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ */
 #ifndef _SHA256_ALT_H_
 #define _SHA256_ALT_H_
 
@@ -20,17 +29,76 @@ extern "C" {
 
 #if defined(MBEDTLS_SHA256_ALT)
 
-#include "hwcrypto/sha.h"
+typedef enum {
+    ESP_MBEDTLS_SHA256_UNUSED, /* first block hasn't been processed yet */
+    ESP_MBEDTLS_SHA256_HARDWARE, /* using hardware SHA engine */
+    ESP_MBEDTLS_SHA256_SOFTWARE, /* using software SHA */
+} esp_mbedtls_sha256_mode;
 
-typedef esp_sha_context mbedtls_sha256_context;
+/**
+ * \brief          SHA-256 context structure
+ */
+typedef struct
+{
+    uint32_t total[2];          /*!< number of bytes processed  */
+    uint32_t state[8];          /*!< intermediate digest state  */
+    unsigned char buffer[64];   /*!< data block being processed */
+    int is224;                  /*!< 0 => SHA-256, else SHA-224 */
+    esp_mbedtls_sha256_mode mode;
+}
+mbedtls_sha256_context;
+
+/**
+ * \brief          Initialize SHA-256 context
+ *
+ * \param ctx      SHA-256 context to be initialized
+ */
+void mbedtls_sha256_init( mbedtls_sha256_context *ctx );
+
+/**
+ * \brief          Clear SHA-256 context
+ *
+ * \param ctx      SHA-256 context to be cleared
+ */
+void mbedtls_sha256_free( mbedtls_sha256_context *ctx );
+
+/**
+ * \brief          Clone (the state of) a SHA-256 context
+ *
+ * \param dst      The destination context
+ * \param src      The context to be cloned
+ */
+void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
+                           const mbedtls_sha256_context *src );
+
+/**
+ * \brief          SHA-256 context setup
+ *
+ * \param ctx      context to be initialized
+ * \param is224    0 = use SHA256, 1 = use SHA224
+ */
+void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 );
+
+/**
+ * \brief          SHA-256 process buffer
+ *
+ * \param ctx      SHA-256 context
+ * \param input    buffer holding the  data
+ * \param ilen     length of the input data
+ */
+void mbedtls_sha256_update( mbedtls_sha256_context *ctx, const unsigned char *input,
+                    size_t ilen );
+
+/**
+ * \brief          SHA-256 final digest
+ *
+ * \param ctx      SHA-256 context
+ * \param output   SHA-224/256 checksum result
+ */
+void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char output[32] );
 
-#define mbedtls_sha256_init     esp_sha256_init
-#define mbedtls_sha256_clone    esp_sha256_clone
-#define mbedtls_sha256_starts   esp_sha256_start
-#define mbedtls_sha256_update   esp_sha256_update
-#define mbedtls_sha256_finish   esp_sha256_finish
-#define mbedtls_sha256_free     esp_sha256_free
-#define mbedtls_sha256_process(...)
+/* Internal use */
+void mbedtls_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] );
 
 #endif
 

+ 91 - 22
components/mbedtls/port/include/sha512_alt.h

@@ -1,16 +1,25 @@
-// Copyright 2015-2016 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.
+/*
+ *  SHA-512 implementation with hardware ESP32 support added.
+ *  Uses mbedTLS software implementation for failover when concurrent
+ *  SHA operations are in use.
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  Additions Copyright (C) 2016, Espressif Systems (Shanghai) PTE LTD
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ */
 #ifndef _SHA512_ALT_H_
 #define _SHA512_ALT_H_
 
@@ -19,17 +28,77 @@ extern "C" {
 #endif
 
 #if defined(MBEDTLS_SHA512_ALT)
-#include "hwcrypto/sha.h"
 
-typedef esp_sha_context  mbedtls_sha512_context;
+typedef enum {
+    ESP_MBEDTLS_SHA512_UNUSED, /* first block hasn't been processed yet */
+    ESP_MBEDTLS_SHA512_HARDWARE, /* using hardware SHA engine */
+    ESP_MBEDTLS_SHA512_SOFTWARE, /* using software SHA */
+} esp_mbedtls_sha512_mode;
 
-#define mbedtls_sha512_init     esp_sha512_init
-#define mbedtls_sha512_clone    esp_sha512_clone
-#define mbedtls_sha512_starts   esp_sha512_start
-#define mbedtls_sha512_update   esp_sha512_update
-#define mbedtls_sha512_finish   esp_sha512_finish
-#define mbedtls_sha512_free     esp_sha512_free
-#define mbedtls_sha512_process(...)
+/**
+ * \brief          SHA-512 context structure
+ */
+typedef struct
+{
+    uint64_t total[2];          /*!< number of bytes processed  */
+    uint64_t state[8];          /*!< intermediate digest state  */
+    unsigned char buffer[128];  /*!< data block being processed */
+    int is384;                  /*!< 0 => SHA-512, else SHA-384 */
+    esp_mbedtls_sha512_mode mode;
+}
+mbedtls_sha512_context;
+
+/**
+ * \brief          Initialize SHA-512 context
+ *
+ * \param ctx      SHA-512 context to be initialized
+ */
+void mbedtls_sha512_init( mbedtls_sha512_context *ctx );
+
+/**
+ * \brief          Clear SHA-512 context
+ *
+ * \param ctx      SHA-512 context to be cleared
+ */
+void mbedtls_sha512_free( mbedtls_sha512_context *ctx );
+
+/**
+ * \brief          Clone (the state of) a SHA-512 context
+ *
+ * \param dst      The destination context
+ * \param src      The context to be cloned
+ */
+void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
+                           const mbedtls_sha512_context *src );
+
+/**
+ * \brief          SHA-512 context setup
+ *
+ * \param ctx      context to be initialized
+ * \param is384    0 = use SHA512, 1 = use SHA384
+ */
+void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, int is384 );
+
+/**
+ * \brief          SHA-512 process buffer
+ *
+ * \param ctx      SHA-512 context
+ * \param input    buffer holding the  data
+ * \param ilen     length of the input data
+ */
+void mbedtls_sha512_update( mbedtls_sha512_context *ctx, const unsigned char *input,
+                    size_t ilen );
+
+/**
+ * \brief          SHA-512 final digest
+ *
+ * \param ctx      SHA-512 context
+ * \param output   SHA-384/512 checksum result
+ */
+void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, unsigned char output[64] );
+
+/* Internal use */
+void mbedtls_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] );
 
 #endif
 

+ 1 - 0
docs/build_system.rst

@@ -244,6 +244,7 @@ The following variables can be set inside ``component.mk`` to control the build
   settings. Component-specific additions can be made via ``CXXFLAGS
   +=``. It is also possible (although not recommended) to override
   this variable completely for a component.
+- ``FLAGS_basename`` allows you to set compilation flags to apply to a single source file only. For example, this can useful for disabling warnings in a single upstream source file. The ``basename`` portion is the directory (relative to ``COMPONENT_PATH``) and the base filename (without extension) of the source file. For example, if a file inside ``COMPONENT_PATH`` is ``library/alpha/widget.c`` then you can set variable ``FLAGS_library/alpha/widget := -DTEST`` to pass the TEST macro when compiling this source file only.
 
 Component Configuration
 -----------------------

+ 6 - 6
make/component_wrapper.mk

@@ -155,17 +155,17 @@ endif
 # This pattern is generated for each COMPONENT_SRCDIR to compile the files in it.
 define GenerateCompileTargets
 # $(1) - directory containing source files, relative to $(COMPONENT_PATH)
-$(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.c | $(1)
+$(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.c $(COMMON_MAKEFILES) $(COMPONENT_MAKEFILE) | $(1)
 	$$(summary) CC $$@
-	$$(CC) $$(CFLAGS) $$(CPPFLAGS) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@
+	$$(CC) $$(CFLAGS) $$(CPPFLAGS) $$(FLAGS_$$(subst .o,,$$(@))) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@
 
-$(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.cpp | $(1)
+$(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.cpp $(COMMON_MAKEFILES) $(COMPONENT_MAKEFILE) | $(1)
 	$$(summary) CXX $$@
-	$$(CXX) $$(CXXFLAGS) $$(CPPFLAGS) $$(addprefix -I,$$(COMPONENT_INCLUDES)) $$(addprefix -I,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@
+	$$(CXX) $$(CXXFLAGS) $$(CPPFLAGS) $$(FLAGS_$$(subst .o,,$$(@))) $$(addprefix -I,$$(COMPONENT_INCLUDES)) $$(addprefix -I,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@
 
-$(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.S | $(1)
+$(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.S $(COMMON_MAKEFILES) $(COMPONENT_MAKEFILE) | $(1)
 	$$(summary) AS $$@
-	$$(CC) $$(CPPFLAGS) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@
+	$$(CC) $$(CPPFLAGS) $$(FLAGS_$$(subst .o,,$$(@))) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@
 
 # CWD is build dir, create the build subdirectory if it doesn't exist
 $(1):