Arm Mbed and Pelion Device Management support forum

Reduce MbedTLS flash Size

Hi,

I’m working to add mbedTLS to tiva C and I’m able to do HTTPS Post but my flash is only 512KB and mbedTLS is occupying a lot of it around 240K which is an issue for me as I need space for other piece of code.

So I want to reduce mbedTLS flash size and remove unnecessary data which is not used for HTTPS. Is there any documentation that can help me do it or any one has any ideas?

Regards,
Deepak

Hi @dpkrai93
Thank you for using Mbed TLS!

I would recommend you look at the following articles that may assist you:

There are other articles inthe KB that may assisst you as well.

Regards,
Mbed TLS Support
Ron

Hi Ron,

I went though the documents and most of it is regarding RAM usage reduction but I need to reduce the flash size it takes.

Is there any document that lets you know what are the features that can be disabled in config.h for https as that is the only thing i need.

I’m really new to this and i appreciate any help that i can get.

Regards,
Deepak

Hi @dpkrai93
Yes, the document is mostly on RAM size. Sorry for confusion.

Mbed TLS does not really use Flash as part of the library, assuming you disable MBEDTLS_FS_IO. The only thing I can think of, is the library itself.
You should be able to configure Mbed TLS only with your relevant features, and see the code size of your library,
Other than that, Mbed TLS library uses RAM mostly.
Regards

Sorry to poke my nose in here, but is it possible to use external resources for TLS storage?
FileSystem for instance in Storage API’s.
It’s a bit dated but the LPC1768 does have a lot of external R/W FLASH and is overall fast enough.
Perhaps just too complicated?
Using TLS does wipe out a lot of platforms due to smaller RAM.
Could this be done using a SD card?
I can’t use over 50% of my boards now due to insufficient RAM for TLS.
Paul

Hi @star297
I’m sorry, but I don’t understand your question. Do you want to use SD card instead of RAM usage?
The SD could be replaced for all the FS operations, however I don’t see how you can avoid RAM limitations by using SD card. What am I missing?

You can, however, reduce RAM usage by configuring only what you need
Regards

The TLS handshaking Ron,

From this:
https://os.mbed.com/teams/sandbox/code/mbed-http/

Memory usage

Small requests where the body of the response is cached by the library (like the one found in main-http.cpp), require 4K of RAM. When the request is finished they require 1.5K of RAM, depending on the size of the response. This applies both to HTTP and HTTPS. If you need to handle requests that return a large response body, see ‘Dealing with large body’.

HTTPS requires additional memory: on FRDM-K64F about 50K of heap space (at its peak). This means that you cannot use HTTPS on devices with less than 128K of memory, asyou also need to reserve memory for the stack and network interface.

Can the TLS handshaking use external memory device, SD, SPI Flash chip, etc?

Hi Ron,

I understand what you’re saying and my config file has MBEDTLS_FS_IO disabled. but still I can see my flash being used a lot by mbed.

I have a function in which i’m using mbedTLS functions to do a HTTPS Post and whenever I have a call to that function in my code I can see the memory being used and if I just remove the call to that function I can see that it’s not the case.

void cloud_post(void) {
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;

mbedtls_x509_crt cacert;
mbedtls_ssl_config conf;
mbedtls_ssl_context ssl;

mbedtls_entropy_init(&entropy);

ret = mbedtls_entropy_add_source(&entropy, entropy_source, NULL, 128,
                                 MBEDTLS_ENTROPY_SOURCE_STRONG);
if (ret != 0) {
    printError("failed\n  ! mbedtls_entropy_add_source returned \n", ret);
}

mbedtls_ctr_drbg_init(&ctr_drbg);
ret =mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func,
                           &entropy, NULL, 0);
if (ret != 0) {
    printError("failed\n  ! mbedtls_drbg_seed returned \n", ret);
}



mbedtls_x509_crt_init( &cacert );
ret = mbedtls_x509_crt_parse( &cacert, (const unsigned char *)ca,
                              sizeof(ca) ); //1595
if( ret < 0 )
{
   printError(" failed\n  !  mbedtls_x509_crt_parse returned -0x%x\n\n", ret);
}

mbedtls_ssl_config_init( &conf );
ret = mbedtls_ssl_config_defaults( &conf,
                    MBEDTLS_SSL_IS_CLIENT,
                    MBEDTLS_SSL_TRANSPORT_STREAM,
                    MBEDTLS_SSL_PRESET_DEFAULT);
if (ret != 0) {
    printError("httpTask: ssl_config failed", ret);
}

mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_REQUIRED);
mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL );
mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );

mbedtls_ssl_init( &ssl );
ret = mbedtls_ssl_setup( &ssl, &conf );

if (ret != 0) {
        printError("httpTask: ssl_setup failed", ret);
    }

ret = mbedtls_ssl_set_hostname( &ssl, "ats-2161.internal.atsclock.com" ); ![With_Mbed|355x499](upload://uUNowYIdFCH7ADC10MhJ82rS8TW.jpeg) 

if (ret != 0) {
        printError("httpTask: ssl_set_hostname failed", ret);
    }

mbedtls_ssl_set_bio(&ssl, handshake.handshakepcb, netSend, netRecv, NULL);

while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) {
    if ((ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED)) {
         /*
          * If hello verify fails, return error. Client sd needs to be
          * closed and recvfrom called again before app
          * can call startSec on the new sd
          */
        printError("httpTask: HELLO_VERIFY_ERROR failed", ret);
    }
    if (ret != MBEDTLS_ERR_SSL_WANT_READ
            && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
        printError("httpTask: CODE_FUNCTION_FAILED", ret);
    }
}

    uint32_t flags;

    if( ( flags = mbedtls_ssl_get_verify_result( &ssl ) ) != 0 )
    {
        char vrfy_buf[512];

        printError( " failed\n",-10 );

        mbedtls_x509_crt_verify_info( vrfy_buf, sizeof( vrfy_buf ), "  ! ", flags );

    }

    handshake.len=0;
    handshake.previous_recv=0;

    len = sprintf( (char *) buf_request, POST_REQUEST );

    while( ( ret = mbedtls_ssl_write( &ssl, buf_request, len ) ) <= 0 )
    {
        if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
        {
            printError(" failed\n  ! mbedtls_ssl_write returned %d\n\n", ret );
        }
    }

    len = sprintf( (char *) buf1, SEND_FIELD1 );

    while( ( ret = mbedtls_ssl_write( &ssl, buf1, len ) ) <= 0 )
    {
        if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
        {
            printError(" failed\n  ! mbedtls_ssl_write returned %d\n\n", ret );
        }
    }

    len = sprintf( (char *) buf2, SEND_FIELD2 );

    while( ( ret = mbedtls_ssl_write( &ssl, buf2, len ) ) <= 0 )
    {
        if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
        {
            printError(" failed\n  ! mbedtls_ssl_write returned %d\n\n", ret );
        }
    }

    len = strlen(myPacket);

    while( ( ret = mbedtls_ssl_write( &ssl, (const unsigned char *)myPacket, len ) ) <= 0 )
    {
        if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
        {
            printError(" failed\n  ! mbedtls_ssl_write returned %d\n\n", ret );
        }
    }

    while(handshake.len==0)
    {

    }

    do
    {
        len = sizeof( myPacket ) - 1;
        memset( myPacket, 0, sizeof( myPacket ) );
        ret = mbedtls_ssl_read( &ssl, (unsigned char *)myPacket, len );

        if( ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE )
            continue;

        if( ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY )
            break;

        if( ret < 0 )
        {
            printError( "failed\n  ! mbedtls_ssl_read returned %d\n\n", ret );
            break;
        }

        if( ret >= 0 )
        {
            //System_printf( "\n\nEOF\n\n" );
            break;
        }

        len = ret;
        //System_printf( " %d bytes read\n\n%s", len, (char *) myPacket );
       //get the HTTP STATUS
    }
    while( 1 );

sscanf( myPacket, "%s %d", httpver, &status);

mbedtls_x509_crt_free( &cacert );
mbedtls_ssl_free( &ssl );
mbedtls_ssl_config_free( &conf );
mbedtls_ctr_drbg_free( &ctr_drbg );
mbedtls_entropy_free( &entropy );

}

this is my function and I have attached the memory allocation image as well.
In the image you can see everything in black is because of MBED and rest in blue is my code for rest of the stuff.

Do you have any idea what can be causing this?

Regards,
Deepak

HI Deepak,
I believe that the issue is that when you remove the function, the linker will remove all the relevant symbols, reducing the code size, and hence reduce Flash usage.
I would recommend you configure in the library only what you really need, to have the smallest code size as possible.
For example, if I had to guess, I believe you can disable MBEDTLS_SHA1_C, MBEDTLS_MD5_C, MBEDTLS_DES_C and MBEDTLS_RIPEMD160_C. This should reduce the code size by ~20KB
Regards