ARM-software / MDK-Middleware

MDK-Middleware (file system, network and USB components) source code for Arm Cortex-M using CMSIS-Drivers and CMSIS-RTOS2 APIs.
https://arm-software.github.io/MDK-Middleware/
97 stars 25 forks source link

tls_buf too small for some applications #71

Closed mf301 closed 2 weeks ago

mf301 commented 4 weeks ago

In TLS_mbed.c of the network component, the buffer tls_buf is currently defined with a fixed size of 1460 bytes. This size is insufficient for the application case of my company, as we require the possibility to upload larger data via the web interface (e.g. 2048bit RSA certificate).

It would be good to have a possibility to change the size according to the application requirement. My suggestion would be to introduce a new define MBEDTLS_BUF_SIZE in mbedTLS_config.h for this purpose.

As default the current size of 1460 byte could be used, which wouldn't change existing projects.

furbanc commented 4 weeks ago

The buffer tls_buf is only an internal intermediate buffer that represents the interface to the network stack. It has nothing to do with the certificates or their size.

The maximum size of the certificates that can be used (the size of the entire certificate chain) is defined in mbedTLS_config.h. For the HTTPS example, it is configured as follows:

/* SSL options */
#define MBEDTLS_SSL_IN_CONTENT_LEN  4096 /**< Maximum length (in bytes) of the incoming plaintext fragments. */
#define MBEDTLS_SSL_OUT_CONTENT_LEN 4096 /**< Maximum length (in bytes) of the outgoing plain text fragments. */

The reason for adding these options was to optimize the use of heap memory. If these configuration options are not specified in the mbedTLS_config.h file, mbedTLS uses a default configuration size of 16 KB for both SSL in content len and SSL out content len.

By fine-tuning the above configuration options, you can optimize your secure application in terms of memory usage. However, you should be on the safe side if you use 2048-bit RSA certificates.

mf301 commented 4 weeks ago

Thanks for the fast response. When uploading my 2048-bit RSA test certificate, I observe a call of mbedtls_ssl_read which is given tls_buf and its size as arguments. In case tls_buf has its default size of 1460 byte, the return value of this call for both certificate (.crt file) and key (.key file) is 1460 and the data is truncated. A following check of the certificate fails.

If I increase the size of tls_buf to 3000 byte, the return value is 2342 for the .crt file and 2859 for the .key file. In this case data is not truncated anymore. The following certificate check succeeds and I am able to store and use the new certificate afterwards.

For my given scenario, I have to use a size of at least 2859 byte for tls_buf, otherwise data will be truncated. Without a size adjustment option we have to manually patch the MDK Middleware, which is not practical.

mf301 commented 3 weeks ago

Can you please make the size of tls_buf configurable? As you can see from my previous comment, the current buffer size leads to data truncation. The setting of MBEDTLS_SSL_IN_CONTENT_LEN is not causing the limitation.

furbanc commented 3 weeks ago

The certificates and keys are handled in the TLS_STATE_HANDSHAKE state. In this state, the basic input and output is handled in the bio_recv() and bio_send() functions. The buffer tls_buf is not used. MBEDTLS_SSL_IN_CONTENT_LEN and MBEDTLS_SSL_OUT_CONTENT_LEN limit the size of the certificate chains used.

In the TLS_STATE_APPDATA state, the data can be exchanged in both directions in any size. The data is fragmented and transferred in small encrypted fragments. Simply increasing the size of tls_buf is a hack that can have side effects. A correct way is to handle the file upload in the HTTP_Server_CGI.c module. Take a look at the HTTP_Upload example on how to handle the standard HTTP file upload.

mf301 commented 2 weeks ago

Thanks for the information, I implemented the support for fragmentation and it works.