Implementing HTTP/2 with mbed TLS

I’ve recently been exploring mbed TLS and thought I’d share some numbers I’ve found.

First, the specifics:

  • mbed TLS version: 1.3.10
  • Compiler: arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 4.9.3 20141119 (release) [ARM/embedded-4_9-branch revision 218278]
  • Processor: TI CC3200 (ARM Cortex-M4 core)

As I’ve been primarily focused on an HTTP/2 server here, I configured mbed TLS to support the mandatory to implement (MTI) ciphersuite for HTTP/2, TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256, along with various required features such as SNI, ALPN, and X.509 certificates. This resulted in a config.h file with the following items #define’ed:

  • POLARSSL_HAVE_LONGLONG
  • POLARSSL_HAVE_ASM
  • POLARSSL_HAVE_IPV6
  • POLARSSL_PLATFORM_PRINTF_ALT
  • POLARSSL_PLATFORM_FPRINTF_ALT
  • POLARSSL_REMOVE_ARC4_CIPHERSUITES
  • POLARSSL_ECP_DP_SECP256R1_ENABLED
  • POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED
  • POLARSSL_NO_PLATFORM_ENTROPY
  • POLARSSL_PKCS1_V15
  • POLARSSL_SSL_EXTENDED_MASTER_SECRET
  • POLARSSL_SSL_DISABLE_RENEGOTIATION
  • POLARSSL_SSL_MAX_FRAGMENT_LENGTH
  • POLARSSL_SSL_PROTO_TLS1_2
  • POLARSSL_SSL_ALPN
  • POLARSSL_SSL_SERVER_NAME_INDICATION
  • POLARSSL_SSL_TRUNCATED_HMAC
  • POLARSSL_SSL_SET_CURVES
  • POLARSSL_X509_CHECK_KEY_USAGE
  • POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE
  • POLARSSL_AES_C
  • POLARSSL_ASN1_PARSE_C
  • POLARSSL_BIGNUM_C
  • POLARSSL_CIPHER_C
  • POLARSSL_CTR_DRBG_C
  • POLARSSL_ECDH_C
  • POLARSSL_ECP_C
  • POLARSSL_ENTROPY_C
  • POLARSSL_GCM_C
  • POLARSSL_MD_C
  • POLARSSL_OID_C
  • POLARSSL_PK_C
  • POLARSSL_PK_PARSE_C
  • POLARSSL_PLATFORM_C
  • POLARSSL_RSA_C
  • POLARSSL_SHA256_C
  • POLARSSL_SSL_CACHE_C
  • POLARSSL_SSL_SRV_C
  • POLARSSL_SSL_TLS_C
  • POLARSSL_X509_USE_C
  • POLARSSL_X509_CRT_PARSE_C
  • SSL_CIPHERSUITES TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

With this config.h in place, I executed the following command:
CC=arm-none-eabi-gcc AR=arm-none-eabi-ar CFLAGS+=”-mthumb -mcpu=cortex-m4 -ffunction-sections -fdata-sections” make lib

This resulted in a static library (libmbedtls.a) with a size of 238972 bytes. Keep in mind that this is doing everything in software (AES, SHA, ECC, etc.).

One trick I learned along the way: It’s best to store your certificates and keys in DER format — no PEM. This allows you to remove POLARSSL_PEM_PARSE_C and POLARSSL_BASE64_C. With this trick, I went from a static library (libmbedtls.a) with a size of 243536 bytes to one with a size of 238972 bytes. This method also reduces size of the certificates and keys themselves.

If you have any optimizations or findings with mbed TLS, particularly for HTTP/2, please share in the comments!

Leave a Reply

Your email address will not be published. Required fields are marked *