Updated TLS (markdown)

s-hadinger 2019-06-22 12:12:12 +02:00
parent b152fd277f
commit 4010cf94c3
1 changed files with 12 additions and 1 deletions

13
TLS.md

@ -51,8 +51,19 @@ The main limitations are:
## Implementation notes
To be completed...
Arduino Core switched form AxTLS to BearSSL in 2.4.2 allowing to optimize further the TLS library footprint. BearSSL is designed for compactness both in code size and memory requirements. Furthermore it is modular and allows to embe only the code necessary for the subset of crypto-algorithms you want to support.
Thanks to BearSSL compactness and aggressive optimization, the minimal TLS configuration requires **34.5k of Flash** and **6.7k of Memory**. The full blown AWS IoT version with full certificate validation requires 48.3k of Flash and 9.4k of Memory.
Here are the tips and tricks used to reduce Flash and Memory:
* **MFLN**: TLS normally uses 16k buffers for send and receive. 32k looks very small on a server but immensly huge for ESP8266. TLS 1.2 introduced MFLN (Maximum Fragment Length Negociation) which allows the TLS Client to reduce both buffers down to 512 bytes. MFLN is not widely supported yet, but it is by recent OpenSSL versions and by AWS IoT. This is a huge improvement in memory footprint. If your server does not support MFLN, it will still work as long as the messages sent by the server do not exceed the buffer length. In Tasmota the buffer length is 1024 bytes for send buffer and 1024 bytes for receive buffer. Goind below creates message fragmentation and much longer TLS connection time (above 3s). If your server does not support MFLN, you'll see a message in the logs.
* **Max Certicate size**: BearSSL normally supports server certificate up to RSA 4096 bits and EC 521 bits. These certificate are very uncommon currently. To save extra memory, the included BearSSL library is trimmed down to maximum RSA 2048 bits certificate and EC 256 bits certiticates. This should not have any impact for you.
* **EC private key**: AWS IoT requires the client to authenticate with its own Private Key and Certificate. By default AWS IoT will generate a RSA 2048 bits private key. In Tasmota, we moved to an EC (Elliptic Curve) Private Key of 256 bits. EC keys are much smaller, and handshake is significantly faster. Note: the key being 256 bits does not mean it's less secure than RSA 2048, it's actually the opposite.
* **Single Cipher**: to reduce code size, we only support a single TLS cipher and embed only the code strictly necessary. When using TLS (e.g. Letsencrypt on Mosquitto) the supported cipher is `RSA_WITH_AES_128_GCM_SHA256` which is a very commonly supported cipher. For AWS IoT, the only supported cipher if `ECDHE_RSA_WITH_AES_128_GCM_SHA256` which is one of the recommended ciphers. Additionally, ECDHE offers Perfect Forward Secrecy which means extra security.
* **Adaptative Thunk Stack**: BearSSL does not allocate memory on its own. It's either the caller's responsibility or memory is taken on the Stack. Stack usage can go above 5k, more than the ESP8266 stack. Arduino created a **Thunk Stack**, a secondary stack of 5.6k, allocated on Heap, and activated when a TLS connection is active. Actually the stack is mostly used during TLS handshake, and much less memory is required during TLS message processing. Tasmota only allocates the Thunk Stack during TLS handshake and swithes back to normal Stack afterwards. See below about actual memory usage.
* **Keys and CA in PROGMEM**: BearSSL was adapted from original source code to push most on the tables and static data into PROGMEM:
https://github.com/earlephilhower/bearssl-esp8266. Additional work let us now to put Client Private Key, Certificate and CA in PROGMEM, saving at leas 3k of Memory.
### Memory usage