Sfoglia il codice sorgente

Merge remote-tracking branch 'origin/feature/mbedtls'

Wu Jian Gang 9 anni fa
parent
commit
2efaf42253

+ 1 - 1
.gitlab-ci.yml

@@ -37,7 +37,7 @@ build_template_app:
     # branch
     - git checkout ${CI_BUILD_REF_NAME} || echo "Using esp-idf-template default branch..."
     - make defconfig
-    - make all
+    - make all V=1
 
 
 .build_gitlab: &build_template

+ 0 - 4
components/bootloader/Makefile.projbuild

@@ -18,15 +18,11 @@ BOOTLOADER_BIN=$(BOOTLOADER_BUILD_DIR)/bootloader.bin
 
 $(BOOTLOADER_BIN): $(COMPONENT_PATH)/src/sdkconfig
 	$(Q) PROJECT_PATH= \
-	LDFLAGS= \
-	CFLAGS= \
 	BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) \
 	$(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src MAKEFLAGS= V=$(V) TARGET_BIN_LAYOUT="$(BOOTLOADER_TARGET_BIN_LAYOUT)" $(BOOTLOADER_BIN)
 
 bootloader-clean:
 	$(Q) PROJECT_PATH= \
-	LDFLAGS= \
-	CFLAGS= \
 	BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) \
 	$(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src app-clean MAKEFLAGS= V=$(V)
 

+ 2 - 0
components/esp32/component.mk

@@ -8,6 +8,8 @@
 #
 -include $(PROJECT_PATH)/build/include/config/auto.conf
 
+COMPONENT_SRCDIRS := . hwcrypto
+
 LIBS := crypto core net80211 phy rtc pp wpa wps
 
 ifeq ($(CONFIG_MEMMAP_BT),y)

+ 354 - 0
components/esp32/hwcrypto/aes.c

@@ -0,0 +1,354 @@
+/**
+ * \brief AES block cipher, ESP32 hardware accelerated version
+ * 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.
+ *
+ */
+/*
+ *  The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
+ *
+ *  http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
+ *  http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
+ */
+#include <string.h>
+#include "hwcrypto/aes.h"
+#include "rom/aes.h"
+#include <sys/lock.h>
+
+static _lock_t aes_lock;
+
+void esp_aes_acquire_hardware( void )
+{
+    /* newlib locks lazy initialize on ESP-IDF */
+    _lock_acquire(&aes_lock);
+    ets_aes_enable();
+}
+
+void esp_aes_release_hardware( void )
+{
+    uint8_t zero[256/8] = { 0 };
+    ets_aes_setkey_enc(zero, AES256);
+    ets_aes_disable();
+    _lock_release(&aes_lock);
+}
+
+void esp_aes_init( esp_aes_context *ctx )
+{
+    bzero( ctx, sizeof( esp_aes_context ) );
+}
+
+void esp_aes_free( esp_aes_context *ctx )
+{
+    if ( ctx == NULL ) {
+        return;
+    }
+
+    bzero( ctx, sizeof( esp_aes_context ) );
+}
+
+/* Translate number of bits to an AES_BITS enum */
+static int keybits_to_aesbits(unsigned int keybits)
+{
+    switch (keybits) {
+    case 128:
+        return AES128;
+    case 192:
+        return AES192;
+        break;
+    case 256:
+        return AES256;
+    default:
+        return ( ERR_ESP_AES_INVALID_KEY_LENGTH );
+    }
+}
+
+/*
+ * AES key schedule (encryption)
+ *
+ */
+int esp_aes_setkey_enc( esp_aes_context *ctx, const unsigned char *key,
+                        unsigned int keybits )
+{
+    uint16_t keybytes = keybits / 8;
+    int aesbits = keybits_to_aesbits(keybits);
+    if (aesbits < 0) {
+        return aesbits;
+    }
+    ctx->enc.aesbits = aesbits;
+    bzero(ctx->enc.key, sizeof(ctx->enc.key));
+    memcpy(ctx->enc.key, key, keybytes);
+    return 0;
+}
+
+/*
+ * AES key schedule (decryption)
+ *
+ */
+int esp_aes_setkey_dec( esp_aes_context *ctx, const unsigned char *key,
+                        unsigned int keybits )
+{
+    uint16_t keybytes = keybits / 8;
+    int aesbits = keybits_to_aesbits(keybits);
+    if (aesbits < 0) {
+        return aesbits;
+    }
+    ctx->dec.aesbits = aesbits;
+    bzero(ctx->dec.key, sizeof(ctx->dec.key));
+    memcpy(ctx->dec.key, key, keybytes);
+    return 0;
+}
+
+/*
+ * Helper function to copy key from esp_aes_context buffer
+ * to hardware key registers.
+ *
+ * Only call when protected by esp_aes_acquire_hardware().
+ */
+static inline int esp_aes_setkey_hardware( esp_aes_context *ctx, int mode)
+{
+    if ( mode == ESP_AES_ENCRYPT ) {
+        ets_aes_setkey_enc(ctx->enc.key, ctx->enc.aesbits);
+    } else {
+        ets_aes_setkey_dec(ctx->dec.key, ctx->dec.aesbits);
+    }
+    return 0;
+}
+
+/*
+ * AES-ECB block encryption
+ */
+void esp_aes_encrypt( esp_aes_context *ctx,
+                      const unsigned char input[16],
+                      unsigned char output[16] )
+{
+    esp_aes_acquire_hardware();
+    esp_aes_setkey_hardware(ctx, ESP_AES_ENCRYPT);
+    ets_aes_crypt(input, output);
+    esp_aes_release_hardware();
+}
+
+/*
+ * AES-ECB block decryption
+ */
+
+void esp_aes_decrypt( esp_aes_context *ctx,
+                      const unsigned char input[16],
+                      unsigned char output[16] )
+{
+    esp_aes_acquire_hardware();
+    esp_aes_setkey_hardware(ctx, ESP_AES_DECRYPT);
+    ets_aes_crypt(input, output);
+    esp_aes_release_hardware();
+}
+
+
+/*
+ * AES-ECB block encryption/decryption
+ */
+int esp_aes_crypt_ecb( esp_aes_context *ctx,
+                       int mode,
+                       const unsigned char input[16],
+                       unsigned char output[16] )
+{
+    esp_aes_acquire_hardware();
+    esp_aes_setkey_hardware(ctx, mode);
+    ets_aes_crypt(input, output);
+    esp_aes_release_hardware();
+    return 0;
+}
+
+
+/*
+ * AES-CBC buffer encryption/decryption
+ */
+int esp_aes_crypt_cbc( esp_aes_context *ctx,
+                       int mode,
+                       size_t length,
+                       unsigned char iv[16],
+                       const unsigned char *input,
+                       unsigned char *output )
+{
+    int i;
+    unsigned char temp[16];
+
+    if ( length % 16 ) {
+        return ( ERR_ESP_AES_INVALID_INPUT_LENGTH );
+    }
+
+    esp_aes_acquire_hardware();
+    esp_aes_setkey_hardware(ctx, mode);
+
+    if ( mode == ESP_AES_DECRYPT ) {
+        while ( length > 0 ) {
+            memcpy( temp, input, 16 );
+            ets_aes_crypt(input, output);
+
+            for ( i = 0; i < 16; i++ ) {
+                output[i] = (unsigned char)( output[i] ^ iv[i] );
+            }
+
+            memcpy( iv, temp, 16 );
+
+            input  += 16;
+            output += 16;
+            length -= 16;
+        }
+    } else {
+        while ( length > 0 ) {
+            for ( i = 0; i < 16; i++ ) {
+                output[i] = (unsigned char)( input[i] ^ iv[i] );
+            }
+
+            ets_aes_crypt(output, output);
+            memcpy( iv, output, 16 );
+
+            input  += 16;
+            output += 16;
+            length -= 16;
+        }
+    }
+
+    esp_aes_release_hardware();
+
+    return 0;
+}
+
+/*
+ * AES-CFB128 buffer encryption/decryption
+ */
+int esp_aes_crypt_cfb128( esp_aes_context *ctx,
+                          int mode,
+                          size_t length,
+                          size_t *iv_off,
+                          unsigned char iv[16],
+                          const unsigned char *input,
+                          unsigned char *output )
+{
+    int c;
+    size_t n = *iv_off;
+
+    esp_aes_acquire_hardware();
+    esp_aes_setkey_hardware(ctx, ESP_AES_ENCRYPT);
+
+    if ( mode == ESP_AES_DECRYPT ) {
+        while ( length-- ) {
+            if ( n == 0 ) {
+                ets_aes_crypt(iv, iv );
+            }
+
+            c = *input++;
+            *output++ = (unsigned char)( c ^ iv[n] );
+            iv[n] = (unsigned char) c;
+
+            n = ( n + 1 ) & 0x0F;
+        }
+    } else {
+        while ( length-- ) {
+            if ( n == 0 ) {
+                ets_aes_crypt(iv, iv );
+            }
+
+            iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
+
+            n = ( n + 1 ) & 0x0F;
+        }
+    }
+
+    *iv_off = n;
+
+    esp_aes_release_hardware();
+
+    return 0;
+}
+
+/*
+ * AES-CFB8 buffer encryption/decryption
+ */
+int esp_aes_crypt_cfb8( esp_aes_context *ctx,
+                        int mode,
+                        size_t length,
+                        unsigned char iv[16],
+                        const unsigned char *input,
+                        unsigned char *output )
+{
+    unsigned char c;
+    unsigned char ov[17];
+
+    esp_aes_acquire_hardware();
+    esp_aes_setkey_hardware(ctx, ESP_AES_ENCRYPT);
+
+    while ( length-- ) {
+        memcpy( ov, iv, 16 );
+        ets_aes_crypt(iv, iv);
+
+        if ( mode == ESP_AES_DECRYPT ) {
+            ov[16] = *input;
+        }
+
+        c = *output++ = (unsigned char)( iv[0] ^ *input++ );
+
+        if ( mode == ESP_AES_ENCRYPT ) {
+            ov[16] = c;
+        }
+
+        memcpy( iv, ov + 1, 16 );
+    }
+
+    esp_aes_release_hardware();
+
+    return 0;
+}
+
+/*
+ * AES-CTR buffer encryption/decryption
+ */
+int esp_aes_crypt_ctr( esp_aes_context *ctx,
+                       size_t length,
+                       size_t *nc_off,
+                       unsigned char nonce_counter[16],
+                       unsigned char stream_block[16],
+                       const unsigned char *input,
+                       unsigned char *output )
+{
+    int c, i;
+    size_t n = *nc_off;
+
+    esp_aes_acquire_hardware();
+    esp_aes_setkey_hardware(ctx, ESP_AES_ENCRYPT);
+
+    while ( length-- ) {
+        if ( n == 0 ) {
+            ets_aes_crypt(nonce_counter, stream_block);
+
+            for ( i = 16; i > 0; i-- )
+                if ( ++nonce_counter[i - 1] != 0 ) {
+                    break;
+                }
+        }
+        c = *input++;
+        *output++ = (unsigned char)( c ^ stream_block[n] );
+
+        n = ( n + 1 ) & 0x0F;
+    }
+
+    *nc_off = n;
+
+    esp_aes_release_hardware();
+
+    return 0;
+}

+ 267 - 0
components/esp32/hwcrypto/sha.c

@@ -0,0 +1,267 @@
+/*
+ *  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.
+ *
+ */
+/*
+ *  The SHA-1 standard was published by NIST in 1993.
+ *
+ *  http://www.itl.nist.gov/fipspubs/fip180-1.htm
+ */
+
+#include <string.h>
+#include <sys/lock.h>
+#include "hwcrypto/sha.h"
+#include "rom/ets_sys.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();
+}
+
+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);
+}
+
+/* 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;
+    }
+}
+
+void esp_sha1_init( esp_sha_context *ctx )
+{
+    bzero( ctx, sizeof( esp_sha_context ) );
+}
+
+void esp_sha1_free( esp_sha_context *ctx )
+{
+    if ( ctx == NULL ) {
+        return;
+    }
+
+    bzero( ctx, sizeof( esp_sha_context ) );
+}
+
+void esp_sha1_clone( esp_sha_context *dst, const esp_sha_context *src )
+{
+    *dst = *src;
+}
+
+/*
+ * 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);
+}
+
+/*
+ * SHA-1 process buffer
+ */
+void esp_sha1_update( esp_sha_context *ctx, const unsigned char *input, size_t ilen )
+{
+    esp_sha_update(ctx, input, ilen, 64);
+}
+
+/*
+ * SHA-1 final digest
+ */
+void esp_sha1_finish( esp_sha_context *ctx, unsigned char output[20] )
+{
+    ets_sha_finish(&ctx->context, ctx->context_type, output);
+    esp_sha_release_hardware();
+}
+
+/* Full SHA-1 calculation */
+void esp_sha1( const unsigned char *input, size_t ilen, unsigned char output[20] )
+{
+    esp_sha_context ctx;
+
+    esp_sha1_init( &ctx );
+    esp_sha1_start( &ctx );
+    esp_sha1_update( &ctx, input, ilen );
+    esp_sha1_finish( &ctx, output );
+    esp_sha1_free( &ctx );
+}
+
+void esp_sha256_init( esp_sha_context *ctx )
+{
+    bzero( ctx, sizeof( esp_sha_context ) );
+}
+
+void esp_sha256_free( esp_sha_context *ctx )
+{
+    if ( ctx == NULL ) {
+        return;
+    }
+
+    bzero( ctx, sizeof( esp_sha_context ) );
+}
+
+void esp_sha256_clone( esp_sha_context *dst, const esp_sha_context *src )
+{
+    *dst = *src;
+}
+
+/*
+ * SHA-256 context setup
+ */
+void esp_sha256_start( esp_sha_context *ctx, int is224 )
+{
+    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;
+    }
+}
+
+/*
+ * SHA-256 process buffer
+ */
+void esp_sha256_update( esp_sha_context *ctx, const unsigned char *input, size_t ilen )
+{
+    if( ctx->context_type == SHA2_256 ) {
+        esp_sha_update(ctx, input, ilen, 64);
+    }
+    /* SHA-224 is a no-op */
+}
+
+/*
+ * SHA-256 final digest
+ */
+void esp_sha256_finish( esp_sha_context *ctx, unsigned char output[32] )
+{
+    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 );
+    }
+}
+
+/*
+ * Full SHA-256 calculation
+ */
+void esp_sha256( const unsigned char *input, size_t ilen, unsigned char output[32], int is224 )
+{
+    esp_sha_context ctx;
+
+    esp_sha256_init( &ctx );
+    esp_sha256_start( &ctx, is224 );
+    esp_sha256_update( &ctx, input, ilen );
+    esp_sha256_finish( &ctx, output );
+    esp_sha256_free( &ctx );
+}
+
+
+/////
+void esp_sha512_init( esp_sha_context *ctx )
+{
+    memset( ctx, 0, sizeof( esp_sha_context ) );
+}
+
+void esp_sha512_free( esp_sha_context *ctx )
+{
+    if ( ctx == NULL ) {
+        return;
+    }
+
+    bzero( ctx, sizeof( esp_sha_context ) );
+}
+
+void esp_sha512_clone( esp_sha_context *dst, const esp_sha_context *src )
+{
+    *dst = *src;
+}
+
+/*
+ * SHA-512 context setup
+ */
+void esp_sha512_start( esp_sha_context *ctx, int is384 )
+{
+    if ( is384 == 0 ) {
+        /* SHA-512 */
+        ctx->context_type = SHA2_512;
+    } else {
+        /* SHA-384 */
+        ctx->context_type = SHA2_384;
+    }
+    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);
+}
+
+/*
+ * 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();
+}
+
+/*
+ * Full SHA-512 calculation
+ */
+void esp_sha512( const unsigned char *input, size_t ilen, unsigned char output[64], int is384 )
+{
+    esp_sha_context ctx;
+
+    esp_sha512_init( &ctx );
+    esp_sha512_start( &ctx, is384 );
+    esp_sha512_update( &ctx, input, ilen );
+    esp_sha512_finish( &ctx, output );
+    esp_sha512_free( &ctx );
+}
+
+////
+

+ 281 - 0
components/esp32/include/hwcrypto/aes.h

@@ -0,0 +1,281 @@
+/**
+ * \brief AES block cipher, ESP32 hardware accelerated version
+ * 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.
+ *
+ *
+ */
+
+#ifndef ESP_AES_H
+#define ESP_AES_H
+
+#include "esp_types.h"
+#include "rom/aes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* padlock.c and aesni.c rely on these values! */
+#define ESP_AES_ENCRYPT     1
+#define ESP_AES_DECRYPT     0
+
+#define ERR_ESP_AES_INVALID_KEY_LENGTH                -0x0020  /**< Invalid key length. */
+#define ERR_ESP_AES_INVALID_INPUT_LENGTH              -0x0022  /**< Invalid data input length. */
+
+typedef struct {
+    enum AES_BITS aesbits;
+    uint8_t key[32];
+} key_context, KEY_CTX;
+
+/**
+ * \brief          AES context structure
+ *
+ * \note           buf is able to hold 32 extra bytes, which can be used:
+ *                 - for alignment purposes if VIA padlock is used, and/or
+ *                 - to simplify key expansion in the 256-bit case by
+ *                 generating an extra round key
+ */
+typedef struct {
+    int nr;                     /*!<  number of rounds  */
+    uint32_t *rk;               /*!<  AES round keys    */
+    KEY_CTX enc;
+    KEY_CTX dec;
+} esp_aes_context;
+
+/**
+ * \brief Lock access to AES hardware unit
+ *
+ * AES hardware unit can only be used by one
+ * consumer at a time.
+ *
+ * esp_aes_xxx API calls automatically manage locking & unlocking of
+ * hardware, this function is only needed if you want to call
+ * ets_aes_xxx functions directly.
+ */
+void esp_aes_acquire_hardware( void );
+
+/**
+ * \brief Unlock access to AES hardware unit
+ *
+ * esp_aes_xxx API calls automatically manage locking & unlocking of
+ * hardware, this function is only needed if you want to call
+ * ets_aes_xxx functions directly.
+ */
+void esp_aes_release_hardware( void );
+
+/**
+ * \brief          Initialize AES context
+ *
+ * \param ctx      AES context to be initialized
+ */
+void esp_aes_init( esp_aes_context *ctx );
+
+/**
+ * \brief          Clear AES context
+ *
+ * \param ctx      AES context to be cleared
+ */
+void esp_aes_free( esp_aes_context *ctx );
+
+/**
+ * \brief          AES key schedule (encryption)
+ *
+ * \param ctx      AES context to be initialized
+ * \param key      encryption key
+ * \param keybits  must be 128, 192 or 256
+ *
+ * \return         0 if successful, or ERR_AES_INVALID_KEY_LENGTH
+ */
+int esp_aes_setkey_enc( esp_aes_context *ctx, const unsigned char *key, unsigned int keybits );
+
+/**
+ * \brief          AES key schedule (decryption)
+ *
+ * \param ctx      AES context to be initialized
+ * \param key      decryption key
+ * \param keybits  must be 128, 192 or 256
+ *
+ * \return         0 if successful, or ERR_AES_INVALID_KEY_LENGTH
+ */
+int esp_aes_setkey_dec( esp_aes_context *ctx, const unsigned char *key, unsigned int keybits );
+
+/**
+ * \brief          AES-ECB block encryption/decryption
+ *
+ * \param ctx      AES context
+ * \param mode     AES_ENCRYPT or AES_DECRYPT
+ * \param input    16-byte input block
+ * \param output   16-byte output block
+ *
+ * \return         0 if successful
+ */
+int esp_aes_crypt_ecb( esp_aes_context *ctx, int mode, const unsigned char input[16], unsigned char output[16] );
+
+/**
+ * \brief          AES-CBC buffer encryption/decryption
+ *                 Length should be a multiple of the block
+ *                 size (16 bytes)
+ *
+ * \note           Upon exit, the content of the IV is updated so that you can
+ *                 call the function same function again on the following
+ *                 block(s) of data and get the same result as if it was
+ *                 encrypted in one call. This allows a "streaming" usage.
+ *                 If on the other hand you need to retain the contents of the
+ *                 IV, you should either save it manually or use the cipher
+ *                 module instead.
+ *
+ * \param ctx      AES context
+ * \param mode     AES_ENCRYPT or AES_DECRYPT
+ * \param length   length of the input data
+ * \param iv       initialization vector (updated after use)
+ * \param input    buffer holding the input data
+ * \param output   buffer holding the output data
+ *
+ * \return         0 if successful, or ERR_AES_INVALID_INPUT_LENGTH
+ */
+int esp_aes_crypt_cbc( esp_aes_context *ctx,
+                       int mode,
+                       size_t length,
+                       unsigned char iv[16],
+                       const unsigned char *input,
+                       unsigned char *output );
+
+
+/**
+ * \brief          AES-CFB128 buffer encryption/decryption.
+ *
+ * Note: Due to the nature of CFB you should use the same key schedule for
+ * both encryption and decryption. So a context initialized with
+ * esp_aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT.
+ *
+ * \note           Upon exit, the content of the IV is updated so that you can
+ *                 call the function same function again on the following
+ *                 block(s) of data and get the same result as if it was
+ *                 encrypted in one call. This allows a "streaming" usage.
+ *                 If on the other hand you need to retain the contents of the
+ *                 IV, you should either save it manually or use the cipher
+ *                 module instead.
+ *
+ * \param ctx      AES context
+ * \param mode     AES_ENCRYPT or AES_DECRYPT
+ * \param length   length of the input data
+ * \param iv_off   offset in IV (updated after use)
+ * \param iv       initialization vector (updated after use)
+ * \param input    buffer holding the input data
+ * \param output   buffer holding the output data
+ *
+ * \return         0 if successful
+ */
+int esp_aes_crypt_cfb128( esp_aes_context *ctx,
+                          int mode,
+                          size_t length,
+                          size_t *iv_off,
+                          unsigned char iv[16],
+                          const unsigned char *input,
+                          unsigned char *output );
+
+/**
+ * \brief          AES-CFB8 buffer encryption/decryption.
+ *
+ * Note: Due to the nature of CFB you should use the same key schedule for
+ * both encryption and decryption. So a context initialized with
+ * esp_aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT.
+ *
+ * \note           Upon exit, the content of the IV is updated so that you can
+ *                 call the function same function again on the following
+ *                 block(s) of data and get the same result as if it was
+ *                 encrypted in one call. This allows a "streaming" usage.
+ *                 If on the other hand you need to retain the contents of the
+ *                 IV, you should either save it manually or use the cipher
+ *                 module instead.
+ *
+ * \param ctx      AES context
+ * \param mode     AES_ENCRYPT or AES_DECRYPT
+ * \param length   length of the input data
+ * \param iv       initialization vector (updated after use)
+ * \param input    buffer holding the input data
+ * \param output   buffer holding the output data
+ *
+ * \return         0 if successful
+ */
+int esp_aes_crypt_cfb8( esp_aes_context *ctx,
+                        int mode,
+                        size_t length,
+                        unsigned char iv[16],
+                        const unsigned char *input,
+                        unsigned char *output );
+
+/**
+ * \brief               AES-CTR buffer encryption/decryption
+ *
+ * Warning: You have to keep the maximum use of your counter in mind!
+ *
+ * Note: Due to the nature of CTR you should use the same key schedule for
+ * both encryption and decryption. So a context initialized with
+ * esp_aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT.
+ *
+ * \param ctx           AES context
+ * \param length        The length of the data
+ * \param nc_off        The offset in the current stream_block (for resuming
+ *                      within current cipher stream). The offset pointer to
+ *                      should be 0 at the start of a stream.
+ * \param nonce_counter The 128-bit nonce and counter.
+ * \param stream_block  The saved stream-block for resuming. Is overwritten
+ *                      by the function.
+ * \param input         The input data stream
+ * \param output        The output data stream
+ *
+ * \return         0 if successful
+ */
+int esp_aes_crypt_ctr( esp_aes_context *ctx,
+                       size_t length,
+                       size_t *nc_off,
+                       unsigned char nonce_counter[16],
+                       unsigned char stream_block[16],
+                       const unsigned char *input,
+                       unsigned char *output );
+
+
+/**
+ * \brief           Internal AES block encryption function
+ *                  (Only exposed to allow overriding it,
+ *                  see AES_ENCRYPT_ALT)
+ *
+ * \param ctx       AES context
+ * \param input     Plaintext block
+ * \param output    Output (ciphertext) block
+ */
+void esp_aes_encrypt( esp_aes_context *ctx, const unsigned char input[16], unsigned char output[16] );
+
+/**
+ * \brief           Internal AES block decryption function
+ *                  (Only exposed to allow overriding it,
+ *                  see AES_DECRYPT_ALT)
+ *
+ * \param ctx       AES context
+ * \param input     Ciphertext block
+ * \param output    Output (plaintext) block
+ */
+void esp_aes_decrypt( esp_aes_context *ctx, const unsigned char input[16], unsigned char output[16] );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* aes.h */

+ 250 - 0
components/esp32/include/hwcrypto/sha.h

@@ -0,0 +1,250 @@
+/*
+ *  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.
+ *
+ */
+
+#ifndef _ESP_SHA_H_
+#define _ESP_SHA_H_
+
+#include "rom/sha.h"
+
+#include "esp_types.h"
+
+#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;
+
+/**
+ * \brief Lock access to SHA hardware unit
+ *
+ * SHA hardware unit can only be used by one
+ * consumer at a time.
+ *
+ * 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
+ *
+ * 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
+ *
+ * \param ctx      SHA-1 context to be initialized
+ */
+void esp_sha1_init( esp_sha_context *ctx );
+
+/**
+ * \brief          Clear SHA-1 context
+ *
+ * \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 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 ctx      context to be initialized
+ */
+void esp_sha1_start( esp_sha_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 esp_sha1_update( esp_sha_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 esp_sha1_finish( esp_sha_context *ctx, unsigned char output[20] );
+
+/**
+ * \brief          Calculate SHA-1 of input buffer
+ *
+ * \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 ctx      SHA-256 context to be initialized
+ */
+void esp_sha256_init( esp_sha_context *ctx );
+
+/**
+ * \brief          Clear SHA-256 context
+ *
+ * \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 dst      The destination context
+ * \param src      The context to be cloned
+ */
+void esp_sha256_clone( esp_sha_context *dst, const esp_sha_context *src );
+
+/**
+ * \brief          SHA-256 context setup
+ *
+ * \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
+ *
+ * \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
+ *
+ * \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
+ *
+ * \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 ctx      SHA-512 context to be initialized
+ */
+void esp_sha512_init( esp_sha_context *ctx );
+
+/**
+ * \brief          Clear SHA-512 context
+ *
+ * \param ctx      SHA-512 context to be cleared
+ */
+void esp_sha512_free( esp_sha_context *ctx );
+
+/**
+ * \brief          Clone (the state of) a SHA-512 context
+ *
+ * \param dst      The destination context
+ * \param src      The context to be cloned
+ */
+void esp_sha512_clone( esp_sha_context *dst, const esp_sha_context *src );
+
+/**
+ * \brief          SHA-512 context setup
+ *
+ * \param ctx      context to be initialized
+ * \param is384    0 = use SHA512, 1 = use SHA384
+ */
+void esp_sha512_start( esp_sha_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 esp_sha512_update( esp_sha_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 esp_sha512_finish( esp_sha_context *ctx, unsigned char output[64] );
+
+/**
+ * \brief          Calculate SHA-512 of input buffer.
+ *
+ * \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 );
+
+//
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+

+ 7 - 0
components/esp32/include/rom/aes.h

@@ -1,3 +1,10 @@
+/*
+  ROM functions for hardware AES support.
+
+  It is not recommended to use these functions directly,
+  use the wrapper functions in hwcrypto/aes.h instead.
+
+ */
 // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
 //
 // Licensed under the Apache License, Version 2.0 (the "License");

+ 7 - 0
components/esp32/include/rom/bigint.h

@@ -1,3 +1,10 @@
+/*
+  ROM functions for hardware bigint support.
+
+  It is not recommended to use these functions directly,
+  use the wrapper functions in hwcrypto/mpi.h instead.
+
+ */
 // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
 //
 // Licensed under the Apache License, Version 2.0 (the "License");

+ 9 - 1
components/esp32/include/rom/sha.h

@@ -1,3 +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.
+
+ */
 // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
@@ -30,7 +37,8 @@ enum SHA_TYPE {
     SHA1 = 0,
     SHA2_256,
     SHA2_384,
-    SHA2_512
+    SHA2_512,
+    SHA_INVALID = -1,
 };
 
 void ets_sha_init(SHA_CTX *ctx);

+ 2 - 2
components/expat/Makefile → components/expat/component.mk

@@ -10,6 +10,6 @@ COMPONENT_ADD_INCLUDEDIRS := port/include include/expat
 
 COMPONENT_SRCDIRS := library port
 
-EXTRA_CFLAGS := -Wno-error=address -Waddress -DHAVE_EXPAT_CONFIG_H
+CFLAGS += -Wno-error=address -Waddress -DHAVE_EXPAT_CONFIG_H
 
-include $(IDF_PATH)/make/component.mk
+include $(IDF_PATH)/make/component_common.mk

+ 1 - 1
components/json/Makefile → components/json/component.mk

@@ -10,4 +10,4 @@ COMPONENT_ADD_INCLUDEDIRS := include port/include
 
 COMPONENT_SRCDIRS := library port
 
-include $(IDF_PATH)/make/component.mk
+include $(IDF_PATH)/make/component_common.mk

+ 2 - 2
components/lwip/component.mk

@@ -2,10 +2,10 @@
 # Component Makefile
 #
 
-COMPONENT_ADD_INCLUDEDIRS := include/lwip include/lwip/port
+COMPONENT_ADD_INCLUDEDIRS := include/lwip include/lwip/port include/lwip/posix
 
 COMPONENT_SRCDIRS := api apps/sntp apps core/ipv4 core/ipv6 core netif port/freertos port/netif port
 
-EXTRA_CFLAGS := -Wno-error=address -Waddress
+CFLAGS += -Wno-error=address -Waddress
 
 include $(IDF_PATH)/make/component_common.mk

+ 0 - 8
components/mbedtls/Makefile

@@ -1,8 +0,0 @@
-#
-# Component Makefile
-
-COMPONENT_SRCDIRS := library port
-
-EXTRA_CFLAGS += -DMBEDTLS_CONFIG_FILE='"mbedtls/esp_config.h"'
-
-include $(IDF_PATH)/make/component.mk

+ 4 - 0
components/mbedtls/Makefile.projbuild

@@ -0,0 +1,4 @@
+# Anyone compiling mbedTLS code needs the name of the
+# alternative config file
+CFLAGS += -DMBEDTLS_CONFIG_FILE='"mbedtls/esp_config.h"'
+

+ 9 - 0
components/mbedtls/component.mk

@@ -0,0 +1,9 @@
+#
+# Component Makefile
+#
+
+COMPONENT_ADD_INCLUDEDIRS := port/include include
+
+COMPONENT_SRCDIRS := library port
+
+include $(IDF_PATH)/make/component_common.mk

+ 5 - 0
components/mbedtls/include/mbedtls/bignum.h

@@ -100,6 +100,8 @@
 #define MBEDTLS_LN_2_DIV_LN_10_SCALE100                 332
 #define MBEDTLS_MPI_RW_BUFFER_SIZE             ( ((MBEDTLS_MPI_MAX_BITS_SCALE100 + MBEDTLS_LN_2_DIV_LN_10_SCALE100 - 1) / MBEDTLS_LN_2_DIV_LN_10_SCALE100) + 10 + 6 )
 
+#if !defined(MBEDTLS_BIGNUM_ALT)
+
 /*
  * Define the base integer type, architecture-wise.
  *
@@ -702,6 +704,9 @@ int mbedtls_mpi_is_prime( const mbedtls_mpi *X,
 int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int dh_flag,
                    int (*f_rng)(void *, unsigned char *, size_t),
                    void *p_rng );
+#else /* MBEDTLS_BIGNUM_ALT */
+#include "bignum_alt.h"
+#endif /* MBEDTLS_BIGNUM_ALT */
 
 /**
  * \brief          Checkup routine

+ 3 - 3
components/mbedtls/include/mbedtls/sha512.h

@@ -101,6 +101,9 @@ void mbedtls_sha512_update( mbedtls_sha512_context *ctx, const unsigned char *in
  */
 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] );
+
 #ifdef __cplusplus
 }
 #endif
@@ -131,9 +134,6 @@ void mbedtls_sha512( const unsigned char *input, size_t ilen,
  */
 int mbedtls_sha512_self_test( int verbose );
 
-/* Internal use */
-void mbedtls_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] );
-
 #ifdef __cplusplus
 }
 #endif

+ 7 - 0
components/mbedtls/library/bignum.c

@@ -58,6 +58,8 @@
 #define mbedtls_free       free
 #endif
 
+#if !defined(MBEDTLS_BIGNUM_ALT)
+
 /* Implementation that should never be optimized out by the compiler */
 static void mbedtls_mpi_zeroize( mbedtls_mpi_uint *v, size_t n ) {
     volatile mbedtls_mpi_uint *p = v; while( n-- ) *p++ = 0;
@@ -1162,6 +1164,7 @@ void mpi_mul_hlp( size_t i, mbedtls_mpi_uint *s, mbedtls_mpi_uint *d, mbedtls_mp
     while( c != 0 );
 }
 
+#if !defined(MBEDTLS_MPI_MUL_MPI_ALT)
 /*
  * Baseline multiplication: X = A * B  (HAC 14.12)
  */
@@ -1198,6 +1201,7 @@ cleanup:
 
     return( ret );
 }
+#endif
 
 /*
  * Baseline multiplication: X = A * b
@@ -1596,6 +1600,7 @@ static int mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N, mbedtls_mpi_uint m
     return( mpi_montmul( A, &U, N, mm, T ) );
 }
 
+#if !defined(MBEDTLS_MPI_EXP_MOD_ALT)
 /*
  * Sliding-window exponentiation: X = A^E mod N  (HAC 14.85)
  */
@@ -1803,6 +1808,7 @@ cleanup:
 
     return( ret );
 }
+#endif
 
 /*
  * Greatest common divisor: G = gcd(A, B)  (HAC 14.54)
@@ -2264,6 +2270,7 @@ cleanup:
 }
 
 #endif /* MBEDTLS_GENPRIME */
+#endif /* MBEDTLS_BIGNUM_ALT */
 
 #if defined(MBEDTLS_SELF_TEST)
 

+ 536 - 0
components/mbedtls/port/esp_bignum.c

@@ -0,0 +1,536 @@
+/**
+ * \brief  Multi-precision integer library, ESP32 hardware accelerated parts
+ *
+ *  based on mbedTLS implementation
+ *
+ *  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.
+ *
+ */
+#include <stdio.h>
+#include <string.h>
+#include <malloc.h>
+#include "mbedtls/bignum.h"
+#include "mbedtls/bn_mul.h"
+#include "rom/bigint.h"
+
+#if defined(MBEDTLS_MPI_MUL_MPI_ALT) || defined(MBEDTLS_MPI_EXP_MOD_ALT)
+
+/* Constants from mbedTLS bignum.c */
+#define ciL    (sizeof(mbedtls_mpi_uint))         /* chars in limb  */
+#define biL    (ciL << 3)               /* bits  in limb  */
+
+static _lock_t mpi_lock;
+
+/* At the moment these hardware locking functions aren't exposed publically
+   for MPI. If you want to use the ROM bigint functions and co-exist with mbedTLS,
+   please raise a feature request.
+*/
+static void esp_mpi_acquire_hardware( void )
+{
+    /* newlib locks lazy initialize on ESP-IDF */
+    _lock_acquire(&mpi_lock);
+    ets_bigint_enable();
+}
+
+static void esp_mpi_release_hardware( void )
+{
+    ets_bigint_disable();
+    _lock_release(&mpi_lock);
+}
+
+/*
+ * Helper for mbedtls_mpi multiplication
+ * copied/trimmed from mbedtls bignum.c
+ */
+static void mpi_mul_hlp( size_t i, mbedtls_mpi_uint *s, mbedtls_mpi_uint *d, mbedtls_mpi_uint b )
+{
+    mbedtls_mpi_uint c = 0, t = 0;
+
+    for( ; i >= 16; i -= 16 )
+    {
+        MULADDC_INIT
+        MULADDC_CORE   MULADDC_CORE
+        MULADDC_CORE   MULADDC_CORE
+        MULADDC_CORE   MULADDC_CORE
+        MULADDC_CORE   MULADDC_CORE
+
+        MULADDC_CORE   MULADDC_CORE
+        MULADDC_CORE   MULADDC_CORE
+        MULADDC_CORE   MULADDC_CORE
+        MULADDC_CORE   MULADDC_CORE
+        MULADDC_STOP
+    }
+
+    for( ; i >= 8; i -= 8 )
+    {
+        MULADDC_INIT
+        MULADDC_CORE   MULADDC_CORE
+        MULADDC_CORE   MULADDC_CORE
+
+        MULADDC_CORE   MULADDC_CORE
+        MULADDC_CORE   MULADDC_CORE
+        MULADDC_STOP
+    }
+
+
+    for( ; i > 0; i-- )
+    {
+        MULADDC_INIT
+        MULADDC_CORE
+        MULADDC_STOP
+    }
+
+    t++;
+
+    do {
+        *d += c; c = ( *d < c ); d++;
+    }
+    while( c != 0 );
+}
+
+
+/*
+ * Helper for mbedtls_mpi subtraction
+ * Copied/adapter from mbedTLS bignum.c
+ */
+static void mpi_sub_hlp( size_t n, mbedtls_mpi_uint *s, mbedtls_mpi_uint *d )
+{
+    size_t i;
+    mbedtls_mpi_uint c, z;
+
+    for( i = c = 0; i < n; i++, s++, d++ )
+    {
+        z = ( *d <  c );     *d -=  c;
+        c = ( *d < *s ) + z; *d -= *s;
+    }
+
+    while( c != 0 )
+    {
+        z = ( *d < c ); *d -= c;
+        c = z; i++; d++;
+    }
+}
+
+
+/* The following 3 Montgomery arithmetic function are
+   copied from mbedTLS bigint.c verbatim as they are static.
+
+   TODO: find a way to support making the versions in mbedtls
+   non-static.
+*/
+
+/*
+ * Fast Montgomery initialization (thanks to Tom St Denis)
+ */
+static void mpi_montg_init( mbedtls_mpi_uint *mm, const mbedtls_mpi *N )
+{
+    mbedtls_mpi_uint x, m0 = N->p[0];
+    unsigned int i;
+
+    x  = m0;
+    x += ( ( m0 + 2 ) & 4 ) << 1;
+
+    for( i = biL; i >= 8; i /= 2 )
+        x *= ( 2 - ( m0 * x ) );
+
+    *mm = ~x + 1;
+}
+
+/*
+ * Montgomery multiplication: A = A * B * R^-1 mod N  (HAC 14.36)
+ */
+static int mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B, const mbedtls_mpi *N, mbedtls_mpi_uint mm,
+                         const mbedtls_mpi *T )
+{
+    size_t i, n, m;
+    mbedtls_mpi_uint u0, u1, *d;
+
+    if( T->n < N->n + 1 || T->p == NULL )
+        return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+
+    memset( T->p, 0, T->n * ciL );
+
+    d = T->p;
+    n = N->n;
+    m = ( B->n < n ) ? B->n : n;
+
+    for( i = 0; i < n; i++ )
+    {
+        /*
+         * T = (T + u0*B + u1*N) / 2^biL
+         */
+        u0 = A->p[i];
+        u1 = ( d[0] + u0 * B->p[0] ) * mm;
+
+        mpi_mul_hlp( m, B->p, d, u0 );
+        mpi_mul_hlp( n, N->p, d, u1 );
+
+        *d++ = u0; d[n + 1] = 0;
+    }
+
+    memcpy( A->p, d, ( n + 1 ) * ciL );
+
+    if( mbedtls_mpi_cmp_abs( A, N ) >= 0 )
+        mpi_sub_hlp( n, N->p, A->p );
+    else
+        /* prevent timing attacks */
+        mpi_sub_hlp( n, A->p, T->p );
+
+    return( 0 );
+}
+
+/*
+ * Montgomery reduction: A = A * R^-1 mod N
+ */
+static int mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N, mbedtls_mpi_uint mm, const mbedtls_mpi *T )
+{
+    mbedtls_mpi_uint z = 1;
+    mbedtls_mpi U;
+
+    U.n = U.s = (int) z;
+    U.p = &z;
+
+    return( mpi_montmul( A, &U, N, mm, T ) );
+}
+
+
+/* Allocate parameters used by hardware MPI multiply,
+ and copy mbedtls_mpi structures into them */
+static int mul_pram_alloc(const mbedtls_mpi *A, const mbedtls_mpi *B, char **pA, char **pB, char **pX, size_t *bites)
+{
+    char *sa, *sb, *sx;
+//	int algn;
+	int words, bytes;
+	int abytes, bbytes;
+
+	if (A->n > B->n)
+		words = A->n;
+	else
+		words = B->n;
+
+	bytes = (words / 16 + ((words % 16) ? 1 : 0 )) * 16 * 4 * 2;
+
+	abytes = A->n * 4;	
+	bbytes = B->n * 4;
+
+	sa = malloc(bytes);
+	if (!sa) {
+       return -1;
+	}
+
+	sb = malloc(bytes);
+	if (!sb) {
+	   free(sa);
+       return -1;
+	}
+
+	sx = malloc(bytes);
+	if (!sx) {
+	   free(sa);
+	   free(sb);
+       return -1;
+	}
+
+	memcpy(sa, A->p, abytes);
+	memset(sa + abytes, 0, bytes - abytes);
+
+	memcpy(sb, B->p, bbytes);
+	memset(sb + bbytes, 0, bytes - bbytes);
+
+	*pA = sa;
+	*pB = sb;
+
+	*pX = sx;
+
+	*bites = bytes * 4;
+
+	return 0;
+}
+
+#if defined(MBEDTLS_MPI_MUL_MPI_ALT)
+
+int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
+{
+    int ret = -1;
+    size_t i, j;
+	char *s1 = NULL, *s2 = NULL, *dest = NULL;
+	size_t bites;
+
+    mbedtls_mpi TA, TB;
+
+    mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TB );
+
+    if( X == A ) { MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TA, A ) ); A = &TA; }
+    if( X == B ) { MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) ); B = &TB; }
+
+    for( i = A->n; i > 0; i-- )
+        if( A->p[i - 1] != 0 )
+            break;
+
+    for( j = B->n; j > 0; j-- )
+        if( B->p[j - 1] != 0 )
+            break;
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i + j ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
+
+	if (mul_pram_alloc(A, B, &s1, &s2, &dest, &bites)) {
+       goto cleanup;
+	}
+
+    esp_mpi_acquire_hardware();
+	if (ets_bigint_mult_prepare((uint32_t *)s1, (uint32_t *)s2, bites)){
+		ets_bigint_wait_finish();
+		if (ets_bigint_mult_getz((uint32_t *)dest, bites) == true) {
+			memcpy(X->p, dest, (i + j) * 4);
+			ret = 0;
+		} else {
+            printf("ets_bigint_mult_getz failed\n");
+		}
+	} else{
+		printf("Baseline multiplication failed\n");
+	}
+    esp_mpi_release_hardware();
+
+    X->s = A->s * B->s;
+
+    free(s1);
+    free(s2);
+    free(dest);
+
+cleanup:
+
+    mbedtls_mpi_free( &TB ); mbedtls_mpi_free( &TA );
+
+    return( ret );
+}
+
+#endif /* MBEDTLS_MPI_MUL_MPI_ALT */
+
+#if defined(MBEDTLS_MPI_EXP_MOD_ALT)
+/*
+ * Sliding-window exponentiation: X = A^E mod N  (HAC 14.85)
+ */
+int mbedtls_mpi_exp_mod( mbedtls_mpi* X, const mbedtls_mpi* A, const mbedtls_mpi* E, const mbedtls_mpi* N, mbedtls_mpi* _RR )
+{
+    int ret;
+    size_t wbits, wsize, one = 1;
+    size_t i, j, nblimbs;
+    size_t bufsize, nbits;
+    mbedtls_mpi_uint ei, mm, state;
+    mbedtls_mpi RR, T, W[ 2 << MBEDTLS_MPI_WINDOW_SIZE ], Apos;
+    int neg;
+
+    if( mbedtls_mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 )
+        return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+
+    if( mbedtls_mpi_cmp_int( E, 0 ) < 0 )
+        return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+
+    /*
+     * Init temps and window size
+     */
+    mpi_montg_init( &mm, N );
+    mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &T );
+    mbedtls_mpi_init( &Apos );
+    memset( W, 0, sizeof( W ) );
+
+    i = mbedtls_mpi_bitlen( E );
+
+    wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
+            ( i >  79 ) ? 4 : ( i >  23 ) ? 3 : 1;
+
+    if( wsize > MBEDTLS_MPI_WINDOW_SIZE )
+        wsize = MBEDTLS_MPI_WINDOW_SIZE;
+
+    j = N->n + 1;
+    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[1],  j ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T, j * 2 ) );
+
+    /*
+     * Compensate for negative A (and correct at the end)
+     */
+    neg = ( A->s == -1 );
+    if( neg )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Apos, A ) );
+        Apos.s = 1;
+        A = &Apos;
+    }
+
+    /*
+     * If 1st call, pre-compute R^2 mod N
+     */
+    if( _RR == NULL || _RR->p == NULL )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &RR, 1 ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &RR, N->n * 2 * biL ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &RR, &RR, N ) );
+
+        if( _RR != NULL )
+            memcpy( _RR, &RR, sizeof( mbedtls_mpi) );
+    }
+    else
+        memcpy( &RR, _RR, sizeof( mbedtls_mpi) );
+
+    /*
+     * W[1] = A * R^2 * R^-1 mod N = A * R mod N
+     */
+    if( mbedtls_mpi_cmp_mpi( A, N ) >= 0 )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &W[1], A, N ) );
+    else
+        MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[1], A ) );
+
+    mpi_montmul( &W[1], &RR, N, mm, &T );
+
+    /*
+     * X = R^2 * R^-1 mod N = R mod N
+     */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, &RR ) );
+    mpi_montred( X, N, mm, &T );
+
+    if( wsize > 1 )
+    {
+        /*
+         * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
+         */
+        j =  one << ( wsize - 1 );
+
+        MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[j], N->n + 1 ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[j], &W[1]    ) );
+
+        for( i = 0; i < wsize - 1; i++ )
+            mpi_montmul( &W[j], &W[j], N, mm, &T );
+
+        /*
+         * W[i] = W[i - 1] * W[1]
+         */
+        for( i = j + 1; i < ( one << wsize ); i++ )
+        {
+            MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[i], N->n + 1 ) );
+            MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[i], &W[i - 1] ) );
+
+            mpi_montmul( &W[i], &W[1], N, mm, &T );
+        }
+    }
+
+    nblimbs = E->n;
+    bufsize = 0;
+    nbits   = 0;
+    wbits   = 0;
+    state   = 0;
+
+    while( 1 )
+    {
+        if( bufsize == 0 )
+        {
+            if( nblimbs == 0 )
+                break;
+
+            nblimbs--;
+
+            bufsize = sizeof( mbedtls_mpi_uint ) << 3;
+        }
+
+        bufsize--;
+
+        ei = (E->p[nblimbs] >> bufsize) & 1;
+
+        /*
+         * skip leading 0s
+         */
+        if( ei == 0 && state == 0 )
+            continue;
+
+        if( ei == 0 && state == 1 )
+        {
+            /*
+             * out of window, square X
+             */
+            mpi_montmul( X, X, N, mm, &T );
+            continue;
+        }
+
+        /*
+         * add ei to current window
+         */
+        state = 2;
+
+        nbits++;
+        wbits |= ( ei << ( wsize - nbits ) );
+
+        if( nbits == wsize )
+        {
+            /*
+             * X = X^wsize R^-1 mod N
+             */
+            for( i = 0; i < wsize; i++ )
+                mpi_montmul( X, X, N, mm, &T );
+
+            /*
+             * X = X * W[wbits] R^-1 mod N
+             */
+            mpi_montmul( X, &W[wbits], N, mm, &T );
+
+            state--;
+            nbits = 0;
+            wbits = 0;
+        }
+    }
+
+    /*
+     * process the remaining bits
+     */
+    for( i = 0; i < nbits; i++ )
+    {
+        mpi_montmul( X, X, N, mm, &T );
+
+        wbits <<= 1;
+
+        if( ( wbits & ( one << wsize ) ) != 0 )
+            mpi_montmul( X, &W[1], N, mm, &T );
+    }
+
+    /*
+     * X = A^E * R * R^-1 mod N = A^E mod N
+     */
+    mpi_montred( X, N, mm, &T );
+
+    if( neg )
+    {
+        X->s = -1;
+        MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( X, N, X ) );
+    }
+
+cleanup:
+
+    for( i = ( one << ( wsize - 1 ) ); i < ( one << wsize ); i++ )
+        mbedtls_mpi_free( &W[i] );
+
+    mbedtls_mpi_free( &W[1] ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &Apos );
+
+    if( _RR == NULL || _RR->p == NULL )
+        mbedtls_mpi_free( &RR );
+
+    return( ret );
+}
+
+#endif /* MBEDTLS_MPI_EXP_MOD_ALT */
+
+#endif /* MBEDTLS_MPI_MUL_MPI_ALT || MBEDTLS_MPI_EXP_MOD_ALT */
+

+ 23 - 0
components/mbedtls/port/esp_hardware.c

@@ -0,0 +1,23 @@
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <sys/types.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+
+extern int os_get_random(unsigned char *buf, size_t len);
+int mbedtls_hardware_poll( void *data,
+                           unsigned char *output, size_t len, size_t *olen )
+{
+    os_get_random(output, len);
+    *olen = len;
+
+    return 0;
+}
+#endif
+

+ 59 - 0
components/mbedtls/port/include/aes_alt.h

@@ -0,0 +1,59 @@
+/**
+ * \file aes_alt.h
+ *
+ * \brief AES block cipher
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  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 AES_ALT_H
+#define AES_ALT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(MBEDTLS_AES_ALT)
+#include "hwcrypto/aes.h"
+
+typedef esp_aes_context mbedtls_aes_context;
+
+#define mbedtls_aes_init            esp_aes_init
+#define mbedtls_aes_free            esp_aes_free
+#define mbedtls_aes_setkey_enc      esp_aes_setkey_enc
+#define mbedtls_aes_setkey_dec      esp_aes_setkey_dec
+#define mbedtls_aes_crypt_ecb       esp_aes_crypt_ecb
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+#define mbedtls_aes_crypt_cbc       esp_aes_crypt_cbc
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+#define mbedtls_aes_crypt_cfb128    esp_aes_crypt_cfb128
+#define mbedtls_aes_crypt_cfb8      esp_aes_crypt_cfb8
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+#define mbedtls_aes_crypt_ctr       esp_aes_crypt_ctr
+#endif
+#define mbedtls_aes_encrypt         esp_aes_encrypt
+#define mbedtls_aes_decrypt         esp_aes_decrypt
+#endif /* MBEDTLS_AES_ALT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* aes.h */

+ 22 - 6
components/mbedtls/include/mbedtls/esp_config.h → components/mbedtls/port/include/mbedtls/esp_config.h

@@ -1,7 +1,6 @@
 /**
- * \file config.h
  *
- * \brief Configuration options (set of defines)
+ * \brief Default mbedTLS configuration options for esp-idf
  *
  *  This set of compile-time options may be used to enable
  *  or disable features selectively, and reduce the global
@@ -225,7 +224,6 @@
  * Uncomment a macro to enable alternate implementation of the corresponding
  * module.
  */
-//#define MBEDTLS_AES_ALT
 //#define MBEDTLS_ARC4_ALT
 //#define MBEDTLS_BLOWFISH_ALT
 //#define MBEDTLS_CAMELLIA_ALT
@@ -235,10 +233,27 @@
 //#define MBEDTLS_MD4_ALT
 //#define MBEDTLS_MD5_ALT
 //#define MBEDTLS_RIPEMD160_ALT
+
+/* The following units have ESP32 hardware support,
+   uncommenting each _ALT macro will use the
+   hardware-accelerated implementation. */
+#define MBEDTLS_AES_ALT
+
+/* 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
 
+/* The following MPI (bignum) functions have ESP32 hardware support,
+   Uncommenting these macros will use the hardware-accelerated
+   implementations.
+
+   Disabled as number of limbs limited by bug. Internal TW#7112.
+*/
+//#define MBEDTLS_MPI_EXP_MOD_ALT
+//#define MBEDTLS_MPI_MUL_MPI_ALT
+
 /**
  * \def MBEDTLS_MD2_PROCESS_ALT
  *
@@ -297,7 +312,7 @@
  *
  * Uncomment this macro to store the AES tables in ROM.
  */
-//#define MBEDTLS_AES_ROM_TABLES
+#define MBEDTLS_AES_ROM_TABLES
 
 /**
  * \def MBEDTLS_CAMELLIA_SMALL_MEMORY
@@ -2465,7 +2480,8 @@
 //#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES      50 /**< Maximum entries in cache */
 
 /* SSL options */
-//#define MBEDTLS_SSL_MAX_CONTENT_LEN             16384 /**< Maxium fragment length in bytes, determines the size of each of the two internal I/O buffers */
+
+#define MBEDTLS_SSL_MAX_CONTENT_LEN             5120 /**< Maxium fragment length in bytes, determines the size of each of the two internal I/O buffers */
 //#define MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME     86400 /**< Lifetime of session tickets (if enabled) */
 //#define MBEDTLS_PSK_MAX_LEN               32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */
 //#define MBEDTLS_SSL_COOKIE_TIMEOUT        60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */
@@ -2506,6 +2522,6 @@
 #include MBEDTLS_USER_CONFIG_FILE
 #endif
 
-#include "check_config.h"
+#include "mbedtls/check_config.h"
 
 #endif /* MBEDTLS_CONFIG_H */

+ 33 - 0
components/mbedtls/port/include/sha1_alt.h

@@ -0,0 +1,33 @@
+/*
+ * copyright (c) 2010 - 2012 Espressif System
+ *
+ */
+#ifndef _SHA1_ALT_H_
+#define _SHA1_ALT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(MBEDTLS_SHA1_ALT)
+
+#include "hwcrypto/sha.h"
+
+typedef esp_sha_context mbedtls_sha1_context;
+
+#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(...)
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+

+ 33 - 0
components/mbedtls/port/include/sha256_alt.h

@@ -0,0 +1,33 @@
+/*
+ * copyright (c) 2010 - 2012 Espressif System
+ *
+ */
+
+#ifndef _SHA256_ALT_H_
+#define _SHA256_ALT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(MBEDTLS_SHA256_ALT)
+
+#include "hwcrypto/sha.h"
+
+typedef esp_sha_context mbedtls_sha256_context;
+
+#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(...)
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* sha256.h */

+ 33 - 0
components/mbedtls/port/include/sha512_alt.h

@@ -0,0 +1,33 @@
+/*
+ * copyright (c) 2010 - 2012 Espressif System
+ *
+ * esf Link List Descriptor
+ */
+
+#ifndef _SHA512_ALT_H_
+#define _SHA512_ALT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(MBEDTLS_SHA512_ALT)
+#include "hwcrypto/sha.h"
+
+typedef esp_sha_context  mbedtls_sha512_context;
+
+#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(...)
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* sha512.h */

+ 452 - 0
components/mbedtls/port/net.c

@@ -0,0 +1,452 @@
+/*
+ *  TCP/IP or UDP/IP networking functions
+ *  modified for LWIP support on ESP32
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  Additions Copyright (C) 2015 Angus Gratton
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if !defined(MBEDTLS_NET_C)
+
+#include "mbedtls/net.h"
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <stdint.h>
+
+/*
+ * Prepare for using the sockets interface
+ */
+static int net_prepare( void )
+{
+    return ( 0 );
+}
+
+static int mbedtls_net_errno(int fd)
+{
+    int sock_errno = 0;
+    u32_t optlen = sizeof(sock_errno);
+
+    getsockopt(fd, SOL_SOCKET, SO_ERROR, &sock_errno, &optlen);
+
+    return sock_errno;
+}
+
+/*
+ * Initialize a context
+ */
+void mbedtls_net_init( mbedtls_net_context *ctx )
+{
+    ctx->fd = -1;
+}
+
+/*
+ * Initiate a TCP connection with host:port and the given protocol
+ */
+int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host, const char *port, int proto )
+{
+    int ret;
+    struct addrinfo hints, *addr_list, *cur;
+
+    if ( ( ret = net_prepare() ) != 0 ) {
+        return ( ret );
+    }
+
+    /* Do name resolution with both IPv6 and IPv4 */
+    memset( &hints, 0, sizeof( hints ) );
+    hints.ai_family = AF_UNSPEC;
+    hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM;
+    hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP;
+
+    if ( getaddrinfo( host, port, &hints, &addr_list ) != 0 ) {
+        return ( MBEDTLS_ERR_NET_UNKNOWN_HOST );
+    }
+
+    /* Try the sockaddrs until a connection succeeds */
+    ret = MBEDTLS_ERR_NET_UNKNOWN_HOST;
+    for ( cur = addr_list; cur != NULL; cur = cur->ai_next ) {
+        ctx->fd = (int) socket( cur->ai_family, cur->ai_socktype,
+                                cur->ai_protocol );
+        if ( ctx->fd < 0 ) {
+            ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
+            continue;
+        }
+
+        if ( connect( ctx->fd, cur->ai_addr, cur->ai_addrlen ) == 0 ) {
+            ret = 0;
+            break;
+        }
+
+        close( ctx->fd );
+        ret = MBEDTLS_ERR_NET_CONNECT_FAILED;
+    }
+
+    freeaddrinfo( addr_list );
+
+    return ( ret );
+}
+
+/*
+ * Create a listening socket on bind_ip:port
+ */
+int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char *port, int proto )
+{
+    int ret;
+    struct addrinfo hints, *addr_list, *cur;
+
+    if ( ( ret = net_prepare() ) != 0 ) {
+        return ( ret );
+    }
+
+    /* Bind to IPv6 and/or IPv4, but only in the desired protocol */
+    memset( &hints, 0, sizeof( hints ) );
+    hints.ai_family = AF_UNSPEC;
+    hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM;
+    hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP;
+
+    if ( getaddrinfo( bind_ip, port, &hints, &addr_list ) != 0 ) {
+        return ( MBEDTLS_ERR_NET_UNKNOWN_HOST );
+    }
+
+    /* Try the sockaddrs until a binding succeeds */
+    ret = MBEDTLS_ERR_NET_UNKNOWN_HOST;
+    for ( cur = addr_list; cur != NULL; cur = cur->ai_next ) {
+        ctx->fd = (int) socket( cur->ai_family, cur->ai_socktype,
+                                cur->ai_protocol );
+        if ( ctx->fd < 0 ) {
+            ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
+            continue;
+        }
+
+        /*SO_REUSEADDR option dafault is disable in source code(lwip)*/
+#if SO_REUSE
+        n = 1;
+        if ( setsockopt( ctx->fd, SOL_SOCKET, SO_REUSEADDR,
+                         (const char *) &n, sizeof( n ) ) != 0 ) {
+            close( ctx->fd );
+            ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
+            continue;
+        }
+#endif
+        /*bind interface dafault don't process the addr is 0xffffffff for TCP Protocol*/
+        struct sockaddr_in *serv_addr = NULL;
+        serv_addr = (struct sockaddr_in *)cur->ai_addr;
+        serv_addr->sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */
+        if ( bind( ctx->fd, (struct sockaddr *)serv_addr, cur->ai_addrlen ) != 0 ) {
+            close( ctx->fd );
+            ret = MBEDTLS_ERR_NET_BIND_FAILED;
+            continue;
+        }
+
+        /* Listen only makes sense for TCP */
+        if ( proto == MBEDTLS_NET_PROTO_TCP ) {
+            if ( listen( ctx->fd, MBEDTLS_NET_LISTEN_BACKLOG ) != 0 ) {
+                close( ctx->fd );
+                ret = MBEDTLS_ERR_NET_LISTEN_FAILED;
+                continue;
+            }
+        }
+
+        /* I we ever get there, it's a success */
+        ret = 0;
+        break;
+    }
+
+    freeaddrinfo( addr_list );
+
+    return ( ret );
+
+}
+
+/*
+ * Check if the requested operation would be blocking on a non-blocking socket
+ * and thus 'failed' with a negative return value.
+ *
+ * Note: on a blocking socket this function always returns 0!
+ */
+static int net_would_block( const mbedtls_net_context *ctx )
+{
+    /*
+     * Never return 'WOULD BLOCK' on a non-blocking socket
+     */
+    if ( ( fcntl( ctx->fd, F_GETFL, 0) & O_NONBLOCK ) != O_NONBLOCK ) {
+        return ( 0 );
+    }
+
+    int error = mbedtls_net_errno(ctx->fd);
+
+    switch ( error ) {
+#if defined EAGAIN
+    case EAGAIN:
+#endif
+#if defined EWOULDBLOCK && EWOULDBLOCK != EAGAIN
+    case EWOULDBLOCK:
+#endif
+        return ( 1 );
+    }
+    return ( 0 );
+}
+
+/*
+ * Accept a connection from a remote client
+ */
+int mbedtls_net_accept( mbedtls_net_context *bind_ctx,
+                        mbedtls_net_context *client_ctx,
+                        void *client_ip, size_t buf_size, size_t *ip_len )
+{
+    int ret;
+    int type;
+
+    struct sockaddr_in client_addr;
+
+    socklen_t n = (socklen_t) sizeof( client_addr );
+    socklen_t type_len = (socklen_t) sizeof( type );
+
+    /* Is this a TCP or UDP socket? */
+    if ( getsockopt( bind_ctx->fd, SOL_SOCKET, SO_TYPE,
+                     (void *) &type, (socklen_t *) &type_len ) != 0 ||
+            ( type != SOCK_STREAM && type != SOCK_DGRAM ) ) {
+        return ( MBEDTLS_ERR_NET_ACCEPT_FAILED );
+    }
+
+    if ( type == SOCK_STREAM ) {
+        /* TCP: actual accept() */
+        ret = client_ctx->fd = (int) accept( bind_ctx->fd,
+                                             (struct sockaddr *) &client_addr, &n );
+    } else {
+        /* UDP: wait for a message, but keep it in the queue */
+        char buf[1] = { 0 };
+
+        ret = recvfrom( bind_ctx->fd, buf, sizeof( buf ), MSG_PEEK,
+                        (struct sockaddr *) &client_addr, &n );
+
+    }
+
+    if ( ret < 0 ) {
+        if ( net_would_block( bind_ctx ) != 0 ) {
+            return ( MBEDTLS_ERR_SSL_WANT_READ );
+        }
+
+        return ( MBEDTLS_ERR_NET_ACCEPT_FAILED );
+    }
+
+    /* UDP: hijack the listening socket to communicate with the client,
+     * then bind a new socket to accept new connections */
+    if ( type != SOCK_STREAM ) {
+        struct sockaddr_in local_addr;
+        int one = 1;
+
+        if ( connect( bind_ctx->fd, (struct sockaddr *) &client_addr, n ) != 0 ) {
+            return ( MBEDTLS_ERR_NET_ACCEPT_FAILED );
+        }
+
+        client_ctx->fd = bind_ctx->fd;
+        bind_ctx->fd   = -1; /* In case we exit early */
+
+        n = sizeof( struct sockaddr_in );
+        if ( getsockname( client_ctx->fd,
+                          (struct sockaddr *) &local_addr, &n ) != 0 ||
+                ( bind_ctx->fd = (int) socket( AF_INET,
+                                               SOCK_DGRAM, IPPROTO_UDP ) ) < 0 ||
+                setsockopt( bind_ctx->fd, SOL_SOCKET, SO_REUSEADDR,
+                            (const char *) &one, sizeof( one ) ) != 0 ) {
+            return ( MBEDTLS_ERR_NET_SOCKET_FAILED );
+        }
+
+        if ( bind( bind_ctx->fd, (struct sockaddr *) &local_addr, n ) != 0 ) {
+            return ( MBEDTLS_ERR_NET_BIND_FAILED );
+        }
+    }
+
+    if ( client_ip != NULL ) {
+        struct sockaddr_in *addr4 = (struct sockaddr_in *) &client_addr;
+        *ip_len = sizeof( addr4->sin_addr.s_addr );
+
+        if ( buf_size < *ip_len ) {
+            return ( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL );
+        }
+
+        memcpy( client_ip, &addr4->sin_addr.s_addr, *ip_len );
+    }
+
+    return ( 0 );
+}
+
+/*
+ * Set the socket blocking or non-blocking
+ */
+int mbedtls_net_set_block( mbedtls_net_context *ctx )
+{
+    return ( fcntl( ctx->fd, F_SETFL, fcntl( ctx->fd, F_GETFL, 0 ) & ~O_NONBLOCK ) );
+}
+
+int mbedtls_net_set_nonblock( mbedtls_net_context *ctx )
+{
+    return ( fcntl( ctx->fd, F_SETFL, fcntl( ctx->fd, F_GETFL, 0 ) | O_NONBLOCK ) );
+}
+
+/*
+ * Portable usleep helper
+ */
+void mbedtls_net_usleep( unsigned long usec )
+{
+    struct timeval tv;
+    tv.tv_sec  = usec / 1000000;
+    tv.tv_usec = usec % 1000000;
+    select( 0, NULL, NULL, NULL, &tv );
+}
+
+/*
+ * Read at most 'len' characters
+ */
+int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len )
+{
+    int ret;
+    int fd = ((mbedtls_net_context *) ctx)->fd;
+    int error = 0;
+
+    if ( fd < 0 ) {
+        return ( MBEDTLS_ERR_NET_INVALID_CONTEXT );
+    }
+
+    ret = (int) read( fd, buf, len );
+
+    if ( ret < 0 ) {
+        if ( net_would_block( ctx ) != 0 ) {
+            return ( MBEDTLS_ERR_SSL_WANT_READ );
+        }
+
+        error = mbedtls_net_errno(fd);
+        if ( error == EPIPE || error == ECONNRESET ) {
+            return ( MBEDTLS_ERR_NET_CONN_RESET );
+        }
+
+        if ( error == EINTR ) {
+            return ( MBEDTLS_ERR_SSL_WANT_READ );
+        }
+
+        return ( MBEDTLS_ERR_NET_RECV_FAILED );
+    }
+
+    return ( ret );
+}
+
+/*
+ * Read at most 'len' characters, blocking for at most 'timeout' ms
+ */
+int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len,
+                              uint32_t timeout )
+{
+    int ret;
+    struct timeval tv;
+    fd_set read_fds;
+    int fd = ((mbedtls_net_context *) ctx)->fd;
+
+    if ( fd < 0 ) {
+        return ( MBEDTLS_ERR_NET_INVALID_CONTEXT );
+    }
+
+    FD_ZERO( &read_fds );
+    FD_SET( fd, &read_fds );
+
+    tv.tv_sec  = timeout / 1000;
+    tv.tv_usec = ( timeout % 1000 ) * 1000;
+
+    ret = select( fd + 1, &read_fds, NULL, NULL, timeout == 0 ? NULL : &tv );
+
+    /* Zero fds ready means we timed out */
+    if ( ret == 0 ) {
+        return ( MBEDTLS_ERR_SSL_TIMEOUT );
+    }
+
+    if ( ret < 0 ) {
+        if ( errno == EINTR ) {
+            return ( MBEDTLS_ERR_SSL_WANT_READ );
+        }
+
+        return ( MBEDTLS_ERR_NET_RECV_FAILED );
+    }
+
+    /* This call will not block */
+    return ( mbedtls_net_recv( ctx, buf, len ) );
+}
+
+/*
+ * Write at most 'len' characters
+ */
+int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len )
+{
+    int ret;
+    int fd = ((mbedtls_net_context *) ctx)->fd;
+
+    int error = 0;
+
+    if ( fd < 0 ) {
+        return ( MBEDTLS_ERR_NET_INVALID_CONTEXT );
+    }
+
+    ret = (int) write( fd, buf, len );
+
+    if ( ret < 0 ) {
+        if ( net_would_block( ctx ) != 0 ) {
+            return ( MBEDTLS_ERR_SSL_WANT_WRITE );
+        }
+
+        error = mbedtls_net_errno(fd);
+        if ( error == EPIPE || error == ECONNRESET ) {
+            return ( MBEDTLS_ERR_NET_CONN_RESET );
+        }
+
+        if ( error == EINTR ) {
+            return ( MBEDTLS_ERR_SSL_WANT_WRITE );
+        }
+
+        return ( MBEDTLS_ERR_NET_SEND_FAILED );
+    }
+
+    return ( ret );
+}
+
+/*
+ * Gracefully close the connection
+ */
+void mbedtls_net_free( mbedtls_net_context *ctx )
+{
+    if ( ctx->fd == -1 ) {
+        return;
+    }
+
+    shutdown( ctx->fd, 2 );
+    close( ctx->fd );
+
+    ctx->fd = -1;
+}
+
+#endif /* MBEDTLS_NET_C */

+ 24 - 11
docs/build_system.rst

@@ -60,7 +60,7 @@ influencing the build process of the component as well as the project it's used
 in. Components may also include a Kconfig file defining the compile-time options that are
 settable by means of the menu system.
 
-Project makefile variables that can be set by the programmer::
+Project Makefile variables that can be set by the programmer::
 
    PROJECT_NAME: Mandatory. Name for the project
    BUILD_DIR_BASE: Set the directory where all objects/libraries/binaries end up in.
@@ -76,17 +76,20 @@ Project makefile variables that can be set by the programmer::
 	  include directories that are passed to the compilation pass of all components and
 	  they do not have a Kconfig option.
 
-Component makefile variables that can be set by the programmer::
+Component-specific component.mk variables that can be set by the programmer::
 
     COMPONENT_ADD_INCLUDEDIRS: Relative path to include directories to be added to
-	    the entire project
+	    the entire project. If an include directory is only needed to compile this
+	    specific component, don't add it here.
     COMPONENT_PRIV_INCLUDEDIRS: Relative path to include directories that are only used
-	    when compiling this specific component
+	    when compiling this specific component.
     COMPONENT_DEPENDS: Names of any components that need to be compiled before this component.
-    COMPONENT_ADD_LDFLAGS: Ld flags to add for this project. Defaults to -l$(COMPONENT_NAME).
+    COMPONENT_ADD_LDFLAGS: LD flags to add for the entire project. Defaults to -l$(COMPONENT_NAME).
 	    Add libraries etc in the current directory as $(abspath libwhatever.a)
-    COMPONENT_EXTRA_INCLUDES: Any extra include paths. These will be prefixed with '-I' and
-	    passed to the compiler; please put absolute paths here.
+    COMPONENT_EXTRA_INCLUDES: Any extra include paths used when compiling the component's
+	    source files. These will be prefixed with '-I' and passed to the compiler.
+		Similar to COMPONENT_PRIV_INCLUDEDIRS, but these paths are passed as-is instead of
+		expanded relative to the component directory.
     COMPONENT_SRCDIRS: Relative directories to look in for sources. Defaults to '.', the current
 	    directory (the root of the component) only. Use this to specify any subdirectories. Note
    	    that specifying this overwrites the default action of compiling everything in the
@@ -114,6 +117,10 @@ be usable in component or project Makefiles::
     COMPONENTS: Name of the components to be included
     CONFIG_*: All values set by 'make menuconfig' have corresponding Makefile variables.
 
+Inside your component's component.mk makefile, you can override or add to these variables
+as necessary. The changes are isolated from other components (see Makefile.projbuild below
+if you want to share these changes with all other components.)
+
 For components, there also are these defines::
 
     COMPONENT_PATH: Absolute path to the root of the source tree of the component we're
@@ -152,10 +159,16 @@ details to add to "menuconfig" for this component.
 Makefile.projbuild
 ------------------
 
-For components that have parts that need to be run when building of the
-project is done, you can create a file called Makefile.projbuild in the
-component root directory. This  file will be included in the main
-Makefile.
+For components that have parts that need to be evaluated in the top-level
+project context, you can create a file called Makefile.projbuild in the
+component root directory. These files is included into the project's
+top-level Makefile.
+
+For example, if your component needs to add to CFLAGS for the entire
+project (not just for its own source files) then you can set
+``CFLAGS +=`` in Makefile.projbuild. Note that this isn't necessary for
+adding include directories to the project, you can set
+``COMPONENT_ADD_INCLUDEDIRS`` (see above) in the component.mk.
 
 
 KConfig.projbuild

+ 0 - 26
make/common.mk

@@ -8,32 +8,6 @@
 # see project_config.mk for details.)
 -include $(PROJECT_PATH)/build/include/config/auto.conf
 
-ifeq ("$(LDFLAGS)","")
-LDFLAGS = -nostdlib \
-	-L$(IDF_PATH)/lib \
-	-L$(IDF_PATH)/ld \
-	$(addprefix -L$(BUILD_DIR_BASE)/,$(COMPONENTS) $(SRCDIRS)) \
-	-u call_user_start_cpu0	\
-	-Wl,--gc-sections	\
-	-Wl,-static	\
-	-Wl,--start-group	\
-	$(COMPONENT_LDFLAGS) \
-	-lgcc \
-	-Wl,--end-group
-endif
-
-ifeq ("$(CFLAGS)","")
-CFLAGS = -DESP_PLATFORM -Og -std=gnu99 -g3 \
-	-Wpointer-arith -Werror -Wno-error=unused-function -Wno-error=unused-but-set-variable -Wno-error=unused-variable \
-	-Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -Wall -ffunction-sections -fdata-sections $(EXTRA_CFLAGS)
-endif
-
-ifeq ("$(CXXFLAGS)","")
-CXXFLAGS = -DESP_PLATFORM -Og -std=gnu++11 -g3 \
-	-Wpointer-arith -Werror -Wno-error=unused-function -Wno-error=unused-but-set-variable -Wno-error=unused-variable \
-	-Wl,-EL -nostdlib -mlongcalls -Wall -ffunction-sections -fdata-sections $(EXTRA_CFLAGS) -fno-exceptions 
-endif
-
 #Handling of V=1/VERBOSE=1 flag
 #
 # if V=1, $(summary) does nothing and $(details) will echo extra details

+ 3 - 5
make/component_common.mk

@@ -25,7 +25,7 @@ export COMPONENT_PATH
 
 include $(IDF_PATH)/make/common.mk
 
-#Some of these options are overridable by the components Makefile.
+#Some of these options are overridable by the component's component.mk Makefile
 
 #Name of the component
 COMPONENT_NAME ?= $(lastword $(subst /, ,$(realpath $(COMPONENT_PATH))))
@@ -58,7 +58,8 @@ COMPONENT_ADD_LDFLAGS ?= -l$(COMPONENT_NAME)
 OWN_INCLUDES:=$(abspath $(addprefix $(COMPONENT_PATH)/,$(COMPONENT_ADD_INCLUDEDIRS) $(COMPONENT_PRIV_INCLUDEDIRS)))
 COMPONENT_INCLUDES := $(OWN_INCLUDES) $(filter-out $(OWN_INCLUDES),$(COMPONENT_INCLUDES))
 
-#This target is used to collect variable values from inside the main makefile
+#This target is used to collect variable values from inside project.mk
+# see project.mk GetVariable macro for details.
 get_variable:
 	@echo "$(GET_VARIABLE)=$(call $(GET_VARIABLE)) "
 
@@ -82,9 +83,6 @@ clean:
 	$(Q) rm -f $(COMPONENT_LIBRARY) $(COMPONENT_OBJS) $(COMPONENT_OBJS:.o=.d) $(COMPONENT_EXTRA_CLEAN)
 endif
 
-#Also generate dependency files
-CFLAGS+=-MMD -MP
-CXXFLAGS+=-MMD -MP
 #Include all dependency files already generated
 -include $(COMPONENT_OBJS:.o=.d)
 

+ 36 - 0
make/project.mk

@@ -133,6 +133,41 @@ export PROJECT_PATH
 #Include functionality common to both project & component
 -include $(IDF_PATH)/make/common.mk
 
+# Set default LDFLAGS
+
+LDFLAGS ?= -nostdlib \
+	-L$(IDF_PATH)/lib \
+	-L$(IDF_PATH)/ld \
+	$(addprefix -L$(BUILD_DIR_BASE)/,$(COMPONENTS) $(SRCDIRS)) \
+	-u call_user_start_cpu0	\
+	-Wl,--gc-sections	\
+	-Wl,-static	\
+	-Wl,--start-group	\
+	$(COMPONENT_LDFLAGS) \
+	-lgcc \
+	-Wl,--end-group \
+	-Wl,-EL
+
+# Set default CPPFLAGS, CFLAGS, CXXFLAGS
+#
+# These are exported so that components can use them when compiling.
+#
+# If you need your component to add CFLAGS/etc for it's own source compilation only, set CFLAGS += in your component's Makefile.
+#
+# If you need your component to add CFLAGS/etc globally for all source
+# files, set CFLAGS += in your component's Makefile.projbuild
+
+# CPPFLAGS used by an compile pass that uses the C preprocessor
+CPPFLAGS = -DESP_PLATFORM -Og -g3 -Wpointer-arith -Werror -Wno-error=unused-function -Wno-error=unused-but-set-variable -Wno-error=unused-variable -Wall -ffunction-sections -fdata-sections -mlongcalls -nostdlib -MMD -MP
+
+# C flags use by C only
+CFLAGS = $(CPPFLAGS) -std=gnu99 -g3 -fno-inline-functions
+
+# CXXFLAGS uses by C++ only
+CXXFLAGS = $(CPPFLAGS) -Og -std=gnu++11 -g3 -fno-exceptions
+
+export CFLAGS CPPFLAGS CXXFLAGS
+
 #Set host compiler and binutils
 HOSTCC := $(CC)
 HOSTLD := $(LD)
@@ -158,6 +193,7 @@ APP_BIN:=$(APP_ELF:.elf=.bin)
 # Include any Makefile.projbuild file letting components add
 # configuration at the project level
 define includeProjBuildMakefile
+$(if $(V),$(if $(wildcard $(1)/Makefile.projbuild),$(info including $(1)/Makefile.projbuild...)))
 COMPONENT_PATH := $(1)
 -include $(1)/Makefile.projbuild
 endef

+ 0 - 2
make/project_config.mk

@@ -10,8 +10,6 @@ KCONFIG_TOOL_DIR=$(IDF_PATH)/tools/kconfig
 # clear MAKEFLAGS as the menuconfig makefile uses implicit compile rules
 $(KCONFIG_TOOL_DIR)/mconf $(KCONFIG_TOOL_DIR)/conf:
 	MAKEFLAGS="" \
-	CFLAGS="" \
-	LDFLAGS="" \
 	CC=$(HOSTCC) LD=$(HOSTLD) \
 	$(MAKE) -C $(KCONFIG_TOOL_DIR)
 

+ 4 - 0
tools/kconfig/Makefile

@@ -18,6 +18,10 @@ endif
 # We need this, in case the user has it in its environment
 unexport CONFIG_
 
+# Unset some environment variables set in the project environment
+CFLAGS :=
+CPPFLAGS :=
+LDFLAGS :=
 
 default: mconf conf