Pārlūkot izejas kodu

Merge branch 'feature/mbedtls_mem_alloc_options' into 'master'

mbedtls: configurable options for controlling dynamic memory allocations

See merge request idf/esp-idf!3343
Angus Gratton 7 gadi atpakaļ
vecāks
revīzija
96cd3b75cd

+ 1 - 0
components/mbedtls/CMakeLists.txt

@@ -80,6 +80,7 @@ set(COMPONENT_SRCS "mbedtls/library/aes.c"
                    "mbedtls/library/xtea.c"
                    "port/esp_bignum.c"
                    "port/esp_hardware.c"
+                   "port/esp_mem.c"
                    "port/esp_sha1.c"
                    "port/esp_sha256.c"
                    "port/esp_sha512.c"

+ 59 - 14
components/mbedtls/Kconfig

@@ -1,25 +1,44 @@
 menu "mbedTLS"
 
-config MBEDTLS_PLATFORM_MEMORY
-   bool "Enable custom mbedTLS memory allocation layer."
-   default n
-   help
-      If this option is disabled, mbed TLS uses the default system
-      calloc() and free() functions.
+choice MBEDTLS_MEM_ALLOC_MODE
+    prompt "Memory allocation strategy"
+    default MBEDTLS_INTERNAL_MEM_ALLOC
+    help
+        Allocation strategy for mbedTLS, essentially provides ability to
+        allocate all required dynamic allocations from,
+
+            - Internal DRAM memory only
+            - External SPIRAM memory only
+            - Either internal or external memory based on default malloc()
+              behavior in ESP-IDF
+            - Custom allocation mode, by overwriting calloc()/free() using
+              mbedtls_platform_set_calloc_free() function
+
+        Recommended mode here is always internal, since that is most preferred
+        from security perspective. But if application requirement does not
+        allow sufficient free internal memory then alternate mode can be
+        selected.
 
-      If this option is enabled, the mbed TLS config macro
-      MBEDTLS_PLATFORM_MEMORY will be defined. The function
-      mbedtls_platform_set_calloc_free() must be called at
-      runtime to provide custom calloc() and free() function
-      pointers for use by mbedTLS.
+config MBEDTLS_INTERNAL_MEM_ALLOC
+    bool "Internal memory"
 
-      This option allows fine-grained control over how mbedTLS
-      allocates heap memory.
+config MBEDTLS_EXTERNAL_MEM_ALLOC
+    bool "External SPIRAM"
+    depends on SPIRAM_SUPPORT
+
+config MBEDTLS_DEFAULT_MEM_ALLOC
+    bool "Default alloc mode"
+
+config MBEDTLS_CUSTOM_MEM_ALLOC
+    bool "Custom alloc mode"
+
+endchoice #MBEDTLS_MEM_ALLOC_MODE
 
 config MBEDTLS_SSL_MAX_CONTENT_LEN
     int "TLS maximum message content length"
     default 16384
     range 512 16384
+    depends on !MBEDTLS_ASYMMETRIC_CONTENT_LEN
     help
         Maximum TLS message length (in bytes) supported by mbedTLS.
         
@@ -36,6 +55,32 @@ config MBEDTLS_SSL_MAX_CONTENT_LEN
         handshake or a return value of MBEDTLS_ERR_SSL_INVALID_RECORD
         (-0x7200).
 
+config MBEDTLS_ASYMMETRIC_CONTENT_LEN
+    bool "Asymmetric in/out fragment length"
+    default n
+    help
+       If enabled, this option allows customizing TLS in/out fragment length
+       in asymmetric way. Please note that enabling this with default values
+       saves 12KB of dynamic memory per TLS connection.
+
+config MBEDTLS_SSL_IN_CONTENT_LEN
+    int "TLS maximum incoming fragment length"
+    default 16384
+    range 512 16384
+    depends on MBEDTLS_ASYMMETRIC_CONTENT_LEN
+    help
+        This defines maximum incoming fragment length, overriding default
+        maximum content length (MBEDTLS_SSL_MAX_CONTENT_LEN).
+
+config MBEDTLS_SSL_OUT_CONTENT_LEN
+    int "TLS maximum outgoing fragment length"
+    default 4096
+    range 512 16384
+    depends on MBEDTLS_ASYMMETRIC_CONTENT_LEN
+    help
+        This defines maximum outgoing fragment length, overriding default
+        maximum content length (MBEDTLS_SSL_MAX_CONTENT_LEN).
+
 config MBEDTLS_DEBUG
    bool "Enable mbedTLS debugging"
    default n
@@ -101,7 +146,7 @@ config MBEDTLS_HAVE_TIME
        The time does not need to be correct, only time differences are used,
 
 config MBEDTLS_HAVE_TIME_DATE
-   bool "Enable mbedtls time data"
+   bool "Enable mbedtls certificate expiry check"
    depends on MBEDTLS_HAVE_TIME
    default n
    help

+ 37 - 0
components/mbedtls/port/esp_mem.c

@@ -0,0 +1,37 @@
+// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <esp_attr.h>
+#include <esp_heap_caps.h>
+#include <sdkconfig.h>
+
+#ifndef CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC
+
+IRAM_ATTR void *esp_mbedtls_mem_calloc(size_t n, size_t size)
+{
+#ifdef CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC
+    return heap_caps_calloc(n, size, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
+#elif CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC
+    return heap_caps_calloc(n, size, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT);
+#else
+    return calloc(n, size);
+#endif
+}
+
+IRAM_ATTR void esp_mbedtls_mem_free(void *ptr)
+{
+    return heap_caps_free(ptr);
+}
+
+#endif /* !CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC */

+ 20 - 0
components/mbedtls/port/include/esp_mem.h

@@ -0,0 +1,20 @@
+// Copyright 2018 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.
+
+#pragma once
+
+#include <stdlib.h>
+
+void *esp_mbedtls_mem_calloc(size_t n, size_t size);
+void esp_mbedtls_mem_free(void *ptr);

+ 44 - 1
components/mbedtls/port/include/mbedtls/esp_config.h

@@ -114,8 +114,13 @@
  *
  * Enable this layer to allow use of alternative memory allocators.
  */
-#ifdef CONFIG_MBEDTLS_PLATFORM_MEMORY
 #define MBEDTLS_PLATFORM_MEMORY
+
+/** Override calloc(), free() except for case where memory allocation scheme is not set to custom */
+#ifndef CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC
+#include "esp_mem.h"
+#define MBEDTLS_PLATFORM_STD_CALLOC		esp_mbedtls_mem_calloc
+#define MBEDTLS_PLATFORM_STD_FREE		esp_mbedtls_mem_free
 #endif
 
 /**
@@ -2618,8 +2623,46 @@
 //#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES      50 /**< Maximum entries in cache */
 
 /* SSL options */
+#ifndef CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN
 
 #define MBEDTLS_SSL_MAX_CONTENT_LEN             CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN /**< Maxium fragment length in bytes, determines the size of each of the two internal I/O buffers */
+
+#else
+
+/** \def MBEDTLS_SSL_IN_CONTENT_LEN
+ *
+ * Maximum incoming fragment length in bytes.
+ *
+ * Uncomment to set the size of the inward TLS buffer independently of the
+ * outward buffer.
+ */
+#define MBEDTLS_SSL_IN_CONTENT_LEN              CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN
+
+/** \def MBEDTLS_SSL_OUT_CONTENT_LEN
+ *
+ * Maximum outgoing fragment length in bytes.
+ *
+ * Uncomment to set the size of the outward TLS buffer independently of the
+ * inward buffer.
+ *
+ * It is possible to save RAM by setting a smaller outward buffer, while keeping
+ * the default inward 16384 byte buffer to conform to the TLS specification.
+ *
+ * The minimum required outward buffer size is determined by the handshake
+ * protocol's usage. Handshaking will fail if the outward buffer is too small.
+ * The specific size requirement depends on the configured ciphers and any
+ * certificate data which is sent during the handshake.
+ *
+ * For absolute minimum RAM usage, it's best to enable
+ * MBEDTLS_SSL_MAX_FRAGMENT_LENGTH and reduce MBEDTLS_SSL_MAX_CONTENT_LEN. This
+ * reduces both incoming and outgoing buffer sizes. However this is only
+ * guaranteed if the other end of the connection also supports the TLS
+ * max_fragment_len extension. Otherwise the connection may fail.
+ */
+#define MBEDTLS_SSL_OUT_CONTENT_LEN             CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN
+
+#endif /* !CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN */
+
 //#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 */

+ 3 - 0
examples/protocols/aws_iot/subscribe_publish/sdkconfig.defaults

@@ -7,3 +7,6 @@ CONFIG_AWS_IOT_SDK=y
 CONFIG_FATFS_READONLY=y
 CONFIG_FATFS_CODEPAGE_437=y
 CONFIG_FATFS_LFN_HEAP=y
+
+# Enable TLS asymmetric in/out content length
+CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y

+ 3 - 0
examples/protocols/aws_iot/thing_shadow/sdkconfig.defaults

@@ -6,3 +6,6 @@ CONFIG_AWS_IOT_SDK=y
 # (if enabled in config)
 CONFIG_FATFS_CODEPAGE_437=y
 CONFIG_FATFS_LFN_HEAP=y
+
+# Enable TLS asymmetric in/out content length
+CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y