PolarSSL is now part of ARM Official announcement and rebranded as mbed TLS.

higher heap memory consumption


Sep 27, 2017 07:21
H

Hi,

I am using mbedTLS for running some of the AWS IOT demos. I am creating multiple connections to different remote server each with its own set of keys & certificates. I am seeing that I need to double the heap memory for second connection. I understand there are articles to optimize the memory usage. However i have not yet ventured into any optimization as we are at preliminary stage. My memory usage as of now on cortex-m3 with Keil compiler is

Code memory: 186KB Heap memory: 96KB (less than this breaks SSL handshake)

The heap is similar to what the below link mentions https://www.keil.com/pack/doc/mw/Network/html/nw_resource_requirements.html

With second connection I have to reserve around double the heap (~160KB) else ssl handshake fails for second connection. In future we will need 6-7 parallel connections which we may not be able to support due to the large heap consumption.

I am using [ Ciphersuite TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384 ] with server certificate verification

I would like to get more insight into how the heap is used by mbedTLS and will each new connection need an equal amount of additional heap as I observe?

any suggestion is welcome

thanks

 
Sep 27, 2017 11:57
Ron Eldor

Hi H,
As you can see in the code, every ssl context has its own in and out buffers, which allocate a heap memory of size MBEDTLS_SSL_BUFFER_LEN which is configurable by defining MBEDTLS_SSL_MAX_CONTENT_LEN other than the default 16KB. Note that you should modify this value if you control both peers, as the standard defines 16KB as maximal TLS record length.
In addition, each context may allocate the additional following heap memories:

  • when using Pre Shared Key (not relevant for TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384)
  • in mbedtls_ssl_set_hostname()
  • when using compression
  • In several locations in DTLS
  • every session allocations on heap some internal structures (mbedtls_ssl_transform , mbedtls_ssl_session , mbedtls_ssl_handshake_params)
  • The received certificate is stored on heap

As you can see, the largest heap memory used is the in and out buffer messages. You could try to teak the value of MBEDTLS_SSL_MAX_CONTENT_LEN to see if it suits your needs.
In addition, you should look at the following article for more information. You could also try using static memory instead of heap memory
Regards,
Mbed TLS Team member
Ron

 
Sep 27, 2017 13:44
H

Hi Ron,

Much appreciate your quick suggestions

Since I am only in control of client side I believe I can not modify the value of MBEDTLS_SSL_BUFFER_LEN

In the link you provided where it suggests to use static memory I see the buffer allocator is reserving 100KB memory. Is it the worst case memory needed for mbedTLS per connection? I see similar number of 90K heap for mbedtls here https://www.keil.com/pack/doc/mw/Network/html/nw_resource_requirements.html

Alas even if I convert to static allocation I would have to reserve additional 100K per new connection? This will limit the max number of connections that I can have.

Thanks & regards

 
Sep 27, 2017 14:28
Ron Eldor

HI H,
As mentioned, according to your use case, you could tweak the value of MBEDTLS_SSL_BUFFER_LEN to reduce the value of 8 KB. In common practice, the largest message received is the certificate, and this is dependent on cipher suite used, and the length of the certificate chain.
ECC certificates are smaller in size than the RSA ones.
You could also look at this post for additional information.
Note the list I gave previous does not sum to 100 KB, so I wouldn't allocate 100KB for every session.
Regards,
Mbed TLS Team member
Ron

 
Sep 28, 2017 10:08
H

Thank you Ron

I will test my application by tweaking the mentioned parameter

Will get back in case of other clarifications

Thanks again

Regards

 
Oct 13, 2017 12:08
H

Hello Ron,

I am coming back on the above issue after trying your recommendations. Here is my configuration and parameter settings

Enabled macros in config.h

define MBEDTLS_PLATFORM_MEMORY

define MBEDTLS_PLATFORM_STD_CALLOC

define MBEDTLS_PLATFORM_STD_FREE

define MBEDTLS_ENTROPY_HARDWARE_ALT

define MBEDTLS_CIPHER_MODE_CBC

define MBEDTLS_REMOVE_ARC4_CIPHERSUITES

define MBEDTLS_ECP_DP_SECP256R1_ENABLED

define MBEDTLS_ECP_NIST_OPTIM

define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED

define MBEDTLS_PK_PARSE_EC_EXTENDED

define MBEDTLS_GENPRIME

define MBEDTLS_NO_PLATFORM_ENTROPY

define MBEDTLS_PKCS1_V15

define MBEDTLS_SSL_PROTO_TLS1_2

define MBEDTLS_SSL_ALPN

define MBEDTLS_SSL_SESSION_TICKETS

define MBEDTLS_SSL_SERVER_NAME_INDICATION

define MBEDTLS_AES_C

define MBEDTLS_ASN1_PARSE_C

define MBEDTLS_ASN1_WRITE_C

define MBEDTLS_BASE64_C

define MBEDTLS_BIGNUM_C

define MBEDTLS_CIPHER_C

define MBEDTLS_CTR_DRBG_C

define MBEDTLS_ECDH_C

define MBEDTLS_ECDSA_C

define MBEDTLS_ECP_C

define MBEDTLS_ENTROPY_C

define MBEDTLS_GCM_C

define MBEDTLS_MD_C

define MBEDTLS_MD5_C

define MBEDTLS_OID_C

define MBEDTLS_PEM_PARSE_C

define MBEDTLS_PK_C

define MBEDTLS_PK_PARSE_C

define MBEDTLS_PLATFORM_C

define MBEDTLS_RSA_C

define MBEDTLS_SHA1_C

define MBEDTLS_SHA256_C

define MBEDTLS_SHA512_C

define MBEDTLS_SSL_CLI_C

define MBEDTLS_SSL_TLS_C

define MBEDTLS_THREADING_C

define MBEDTLS_X509_USE_C

define MBEDTLS_X509_CRT_PARSE_C

MBEDTLS_MPI_MAX_SIZE = 256 MBEDTLS_ECP_WINDOW_SIZE set to 2 MBEDTLS_ECP_FIXED_POINT_OPTIM set to 1 MBEDTLS_SSL_MAX_CONTENT_LEN set to 3072

The heap requirement for each connection still stands at ~32K. Is this expected/reasonable?

compression & dtls is disabled. I checked the certificate memory which is around 3K. I am yet to try static allocation but not sure if it would reduce memory requirement.

How can I track run time memory allocation within mbedTLS?

Thank you

regards

 
Oct 15, 2017 12:20
Ron Eldor

Hi H,
According to your negotiated ciphersuite (TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384), you could try disabling the following definitions:

  • MBEDTLS_RSA_C
  • MBEDTLS_CIPHER_MODE_CBC
  • MBEDTLS_MD5_C
  • MBEDTLS_SHA1_C
  • MBEDTLS_SHA256_C

You could look at the suite-b configuration example as reference, and use only MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 as your MBEDTLS_SSL_CIPHERSUITES Note that these examples will mostly reduce code sze, not neccessary heap size.
To track down your heap usage, you could use your own calloc implementation, and have your implementation print the size and function of the allocation. You should define MBEDTLS_PLATFORM_MEMORY and MBEDTLS_PLATFORM_CALLOC_MACRO

Regards,
Mbed TLS Team member
Ron

 
Oct 16, 2017 07:51
Manuel Pégourié-Gonnard

Hi H,

In addition to what Ron said, if you want to minimize heap usage, you probably want to set MBEDTLS_ECP_FIXED_POINT_OPTIM to 0 rather than 1.

Regards,
mbed TLS team member
Manuel

 
Oct 16, 2017 11:23
H

Hello Ron & Manual,

Thanks for replies. Yes, I did set the MBEDTLS_ECP_FIXED_POINT_OPTIM to 0 after my last post

The problem is I think there is no benchmark to compare against about memory usage for particular configuration. How to understand if I have the truly data optimized mbedTLS for the configuration I am using. Or what is the minimum requirement. Some numbers for any common platforms would help

Here is the breakup I have

--ssl context has its own in and out buffers: 3K each, total 6K (only tested equal buffer size for in & out)

--Root certificate & client keys: 3.5K

--Server certificate: I see two of size ~3K

--memory for other structures (mbedtls_ssl_transform , mbedtls_ssl_session , mbedtls_ssl_handshake_params)

This is roughly 16K which may be needed as long as the connection is active. Rest should be allocated & freed at run time?? I still have a gap of 18K which I can not understand. I may have to add traces @ each place where mbedtls_calloc() & mbedtls_free() is called to understand overall flow of memory allocation during the handshake process or is there any better way?

Thanks

 
Oct 29, 2017 09:12
Ron Eldor

Hi H,

I may have to add traces @ each place where mbedtls_calloc() & mbedtls_free() is called to understand overall flow of memory allocation during the handshake process or is there any better way?

Unless you are using some external tool for analyzing the heap usage, your suggestion should be used for understanding the heap usage on your device.
Regards,
Mbed TLS Team member
Ron

 
Oct 30, 2017 15:16
Manuel Pégourié-Gonnard

Hi H,

Please note that a possibly convenient way of achieving that might be to enable MBEDTLS_PLATFORM_C in your config.h and then use mbedtls_platform_set_calloc_free() to replace calloc() and free() with wrappers that would output the information you need before calling the actual functions (it would be up to you to write these wrappers).

Regards,
Mbed TLS Team member
Manuel

 
Oct 31, 2017 06:53
H

Thank you team for your inputs.

regards