Dear Mbed TLS team,
I am trying to integrate Mbed TLS in our platform: - nxp imx rt 1024 CPU (arm based) - FreeRTOS (10.6) - Lwip (2.2) - Mbed TLS (3.6.2)
LWIP supports Mbed TLS when adding defines in their configuration: /* ---------- TLS ------------------------- */ #define LWIP_ALTCP 1 #define LWIP_ALTCP_TLS 1 #define LWIP_ALTCP_TLS_MBEDTLS 1
But, unfortunately this supports an older version of Mbed TLS (I believe 2.2.x).
When I try to compile against the Mbed TLS 3.6.2 libraries, I get a bunch of compiler warnings / errors. Most of them are mentioned in the migration guide, but even then, I have a hard time figuring out how to resolve them "the right way".
1. Private fields The migration guide https://github.com/Mbed-TLS/mbedtls/blob/mbedtls-3.6/docs/3.0-migration-guide.md#most-structure-fields-are-now-private explains that most structs are now considered private.
1.1: The altcp_mbed module in LWIP relies on the *out_left* field of the *ssl context* struct.
/* calculate TLS overhead part to not send it to application */ overhead = state->overhead_bytes_adjust + state->ssl_context.out_left;
I am correct that this field is simply not exposed through accessor functions? I can find functions like mbedtls_ssl_get_avail, so I would expect something like mbedtls_ssl_get_bytes_to_write or something like that?
1.2: The altcp_mbed module in LWIP relies on the *start* field of the *ssl session* struct.
err_t altcp_tls_set_session(struct altcp_pcb *conn, struct altcp_tls_session *session) { if (session && conn && conn->state) { altcp_mbedtls_state_t *state = (altcp_mbedtls_state_t *)conn->state; int ret = -1;
* if (session->data.start)* ret = mbedtls_ssl_set_session(&state->ssl_context, &session->data); return ret < 0 ? ERR_VAL : ERR_OK; } return ERR_ARG; }
I also don't know how to obtain this field "the right way". I know this is a bad idea, but it's all I got if (session->data.*private_start)* ...
2. parse key expects a RNG function
This is also explained in the migration guide:
*Some functions gained an RNG parameterThis affects users of the following functions: `mbedtls_ecp_check_pub_priv()`,`mbedtls_pk_check_pair()`, `mbedtls_pk_parse_key()`, and`mbedtls_pk_parse_keyfile()`.You now need to pass a properly seeded, cryptographically secure RNG whencalling these functions. It is used for blinding, a countermeasure againstside-channel attacks.*
Can you please give me some guidance here? I looked for examples in Mbed TLS repo and ended up with this (bold parts are added, using the key_app.c in your repo as leading example):
* mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; mbedtls_entropy_init(&entropy); mbedtls_ctr_drbg_init(&ctr_drbg); if ((ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, privkey, privkey_len)) != 0) { // TODO: handle error } * ret = mbedtls_pk_parse_key( conf->pkey, privkey, privkey_len, privkey_pass, privkey_pass_len,
*mbedtls_ctr_drbg_random, &ctr_drbg*);
3. The altcp_mbed module in LWIP relies on mbedtls_ssl_flush_output
The altcp_mbed module had an include on ssl internal.
#include "mbedtls/ssl_internal.h" /* to call mbedtls_flush_output after ERR_MEM */
This header seems no longer part of the library. But the prototype of the function is now part of ssl_misc.h, but I don't think I am supposed to rely on this header either.
I have a couple of options: - ignore the compiler warning /home/dev_container/app/thirdparty/lwip/src/apps/altcp_tls/altcp_tls_mbedtls.c:535:5: warning: implicit declaration of function 'mbedtls_ssl_flush_output'; did you mean 'mbedtls_ssl_tls_prf'? [-Wimplicit-function-declaration] 535 | mbedtls_ssl_flush_output(&state->ssl_context);
- copy paste the declaration in the LWIP source file - Or.... don't flush any buffers managed by Mbed TLS in the first place?
For the last one, I could really use your input. Can you say anything meaningful about the flush (line in bold) In the below function, Is it mandatory? Or can I trust the Mbed TLS will flush the output buffer whenever it needs to get flushed?
/** Sent callback from lower connection (i.e. TCP) * This only informs the upper layer the number of ACKed bytes. * This now take care of TLS added bytes so application receive * correct ACKed bytes. */ static err_t altcp_mbedtls_lower_sent(void *arg, struct altcp_pcb *inner_conn, u16_t len) { struct altcp_pcb *conn = (struct altcp_pcb *)arg; LWIP_UNUSED_ARG(inner_conn); /* for LWIP_NOASSERT */ if (conn) { int overhead; u16_t app_len; altcp_mbedtls_state_t *state = (altcp_mbedtls_state_t *)conn->state; LWIP_ASSERT("state", state != NULL); LWIP_ASSERT("pcb mismatch", conn->inner_conn == inner_conn); /* calculate TLS overhead part to not send it to application */ mbedtls_ssl_get_bytes_avail(&state->ssl_context); overhead = state->overhead_bytes_adjust + state->ssl_context.private_out_left; if ((unsigned)overhead > len) { overhead = len; } /* remove ACKed bytes from overhead adjust counter */ state->overhead_bytes_adjust -= len; /* try to send more if we failed before (may increase overhead adjust counter) */ *mbedtls_ssl_flush_output(&state->ssl_context); // Does it make sense this LWIP port is responsible for flushing here??* /* remove calculated overhead from ACKed bytes len */ app_len = len - (u16_t)overhead; /* update application write counter and inform application */ if (app_len) { state->overhead_bytes_adjust += app_len; if (conn->sent) return conn->sent(conn->arg, conn, app_len); } } return ERR_OK; }
After applying the changes I mentioned above, the software compiles against Mbed TLS. I haven't dared to run anything, I just want to enjoy this short moment where I have the feeling I achieved something before runtime errors ruin my day :).
Many thanks in advance for any reply!
Best regards, Bas
[image: image.png]