Mbedtls + esp8266-rtos-sdk

I’m struggling to activate the now-inbuilt mbedtls in esp8266-rtos-sdk. It looks like a linker issue. I have made sure I used extern "C" { when including the headers. Still, I am met with

.pioenvs/esp8266/libfd7/libmc-coap.a(dtls-datapump.o):(.text._ZN7moducom4coap4Dtls8shutdownEv+0x43): undefined reference to `mbedtls_pk_free'
.pioenvs/esp8266/libfd7/libmc-coap.a(dtls-datapump.o):(.text._ZN7moducom4coap4Dtls8shutdownEv+0x4c): undefined reference to `mbedtls_ssl_free'

And many more like 'em

I noticed the pio linker doesn’t include it by default, so I made a custom python command to manually add to the link phase:

env.Append(
  LINKFLAGS=[
      "-lmbedtls"
  ]
)

The above appears to indeed put -lmbedtls on the linker command line, yet still the errors persist. Any suggestions?

EDIT: Added to python script the flag:

"-Wl,-lmbedtls"

since the linker seems to be invoked through elf’s g++. Also added to platformio.ini 's build_flags -lmbedtls (just noticed I could do that). Still no change

It works when you go to your platformio.ini and add the line

build_flags = -Wl,--start-group -lmbedtls -Wl,--end-group

It then makes the linker command add the library in the list of all other libraries instead of a seperate flag.

xtensa-lx106-elf-gcc -o .pioenvs\nodemcuv2\firmware.elf -Os -nostdlib -Wl,--no-check-sections -u call_user_start -u _printf_float -u _scanf_float -Wl,-static -Wl,--gc-sections -Wl,--start-group -Wl,--end-group -Wl,-T"C:\Users\Maxi\.platformio\packages\framework-esp8266-rtos-sdk\ld\eagle.app.v6.ld" .pioenvs\nodemcuv2\src\main.o -LC:\Users\Maxi\.platformio\packages\framework-esp8266-rtos-sdk\lib -L.pioenvs\nodemcuv2 -Wl,--start-group C:\Users\Maxi\.platformio\packages\framework-esp8266-rtos-sdk\lib\libdriver.a -lcirom -lcrypto -ldriver -lespconn -lespnow -lfreertos -lgcc -ljson -lhal -llwip -lmain -lmesh -lmirom -lnet80211 -lnopoll -lphy -lpp -lpwm -lsmartconfig -lspiffs -lssl -lwpa -lwps -lmbedtls -Wl,--end-group

Test code with

#include "mbedtls/pk.h"
void test_crypto() {
	mbedtls_pk_context pkContext;
	mbedtls_pk_init(&pkContext);
	mbedtls_pk_free(&pkContext);
}

compiles fine.

I see what you mean. This did seem to get rid of a few of my errors. I’m still left with

.pioenvs/esp8266/libfd7/libmc-coap.a(dtls-datapump.o):(.text._ZN7moducom4coap4Dtls5setupEv+0x2c): undefined reference to `mbedtls_test_srv_crt'
.pioenvs/esp8266/libfd7/libmc-coap.a(dtls-datapump.o):(.text._ZN7moducom4coap4Dtls5setupEv+0x30): undefined reference to `mbedtls_test_srv_crt_len'
.pioenvs/esp8266/libfd7/libmc-coap.a(dtls-datapump.o):(.text._ZN7moducom4coap4Dtls5setupEv+0x38): undefined reference to `mbedtls_test_cas_pem_len'
.pioenvs/esp8266/libfd7/libmc-coap.a(dtls-datapump.o):(.text._ZN7moducom4coap4Dtls5setupEv+0x3c): undefined reference to `mbedtls_test_cas_pem'
.pioenvs/esp8266/libfd7/libmc-coap.a(dtls-datapump.o):(.text._ZN7moducom4coap4Dtls5setupEv+0x40): undefined reference to `mbedtls_test_srv_key'
.pioenvs/esp8266/libfd7/libmc-coap.a(dtls-datapump.o):(.text._ZN7moducom4coap4Dtls5setupEv+0x44): undefined reference to `mbedtls_test_srv_key_len'
.pioenvs/esp8266/libfd7/libmc-coap.a(dtls-datapump.o):(.text._ZN7moducom4coap4Dtls5setupEv+0x7c): undefined reference to `mbedtls_ssl_cache_get'
.pioenvs/esp8266/libfd7/libmc-coap.a(dtls-datapump.o):(.text._ZN7moducom4coap4Dtls5setupEv+0x80): undefined reference to `mbedtls_ssl_cache_set'
.pioenvs/esp8266/libfd7/libmc-coap.a(dtls-datapump.o):(.text._ZN7moducom4coap4Dtls5setupEv+0x8c): undefined reference to `mbedtls_ssl_cookie_write'
.pioenvs/esp8266/libfd7/libmc-coap.a(dtls-datapump.o):(.text._ZN7moducom4coap4Dtls5setupEv+0x90): undefined reference to `mbedtls_ssl_cookie_check'
.pioenvs/esp8266/libfd7/libmc-coap.a(dtls-datapump.o):(.text._ZN7moducom4coap4Dtls5setupEv+0xa4): undefined reference to `mbedtls_ssl_cookie_init'
.pioenvs/esp8266/libfd7/libmc-coap.a(dtls-datapump.o):(.text._ZN7moducom4coap4Dtls5setupEv+0xa8): undefined reference to `mbedtls_ssl_cache_init'
.pioenvs/esp8266/libfd7/libmc-coap.a(dtls-datapump.o):(.text._ZN7moducom4coap4Dtls5setupEv+0xac): undefined reference to `mbedtls_debug_set_threshold'
.pioenvs/esp8266/libfd7/libmc-coap.a(dtls-datapump.o):(.text._ZN7moducom4coap4Dtls5setupEv+0xb0): undefined reference to `mbedtls_ssl_cookie_setup'
.pioenvs/esp8266/libfd7/libmc-coap.a(dtls-datapump.o):(.text._ZN7moducom4coap4Dtls5setupEv+0xb4): undefined reference to `mbedtls_ssl_conf_dtls_cookies'
.pioenvs/esp8266/libfd7/libmc-coap.a(dtls-datapump.o):(.text._ZN7moducom4coap4Dtls5setupEv+0xe2): undefined reference to `mbedtls_ssl_cookie_init'
.pioenvs/esp8266/libfd7/libmc-coap.a(dtls-datapump.o):(.text._ZN7moducom4coap4Dtls5setupEv+0xeb): undefined reference to `mbedtls_ssl_cache_init'
.pioenvs/esp8266/libfd7/libmc-coap.a(dtls-datapump.o):(.text._ZN7moducom4coap4Dtls5setupEv+0x10b): undefined reference to `mbedtls_debug_set_threshold'
.pioenvs/esp8266/libfd7/libmc-coap.a(dtls-datapump.o): In function `moducom::coap::Dtls::setup()':
dtls-datapump.cpp:(.text._ZN7moducom4coap4Dtls5setupEv+0x283): undefined reference to `mbedtls_ssl_cookie_setup'
dtls-datapump.cpp:(.text._ZN7moducom4coap4Dtls5setupEv+0x2a9): undefined reference to `mbedtls_ssl_conf_dtls_cookies'
.pioenvs/esp8266/libfd7/libmc-coap.a(dtls-datapump.o):(.text._ZN7moducom4coap4Dtls4loopEPi+0x6c): undefined reference to `mbedtls_ssl_set_client_transport_id'
.pioenvs/esp8266/libfd7/libmc-coap.a(dtls-datapump.o):(.text._ZN7moducom4coap4Dtls4loopEPi+0xee): undefined reference to `mbedtls_ssl_set_client_transport_id'
.pioenvs/esp8266/libfd7/libmc-coap.a(dtls-datapump.o):(.text._ZN7moducom4coap4Dtls8shutdownEv+0x0): undefined reference to `mbedtls_ssl_cookie_free'
.pioenvs/esp8266/libfd7/libmc-coap.a(dtls-datapump.o):(.text._ZN7moducom4coap4Dtls8shutdownEv+0x4): undefined reference to `mbedtls_ssl_cache_free'
.pioenvs/esp8266/libfd7/libmc-coap.a(dtls-datapump.o):(.text._ZN7moducom4coap4Dtls8shutdownEv+0x34): undefined reference to `mbedtls_ssl_cookie_free'
.pioenvs/esp8266/libfd7/libmc-coap.a(dtls-datapump.o):(.text._ZN7moducom4coap4Dtls8shutdownEv+0x3d): undefined reference to `mbedtls_ssl_cache_free'

the mbedtls_ssl_test_* stuff I know what to do about. The others… maybe they just aren’t compiled into the libmbedtls.a? I’m pretty tired after troubleshooting all day. Will check out a readelf on this tomorrow…

After doing a

objdump -t libmbedtls.a > symbols.txt

I can see that there is no symbols / function named mbedtls_ssl_set_client_transport_id, mbedtls_ssl_cookie_init et cetera. Looks like you’re better off compiling mbedtls from source with the correct config.h instead of relying on the precompiled blob.

It would seem so. I’ve compiled mbedtls from scratch a few times using esp-open-rtos. Some guidance would be helpful here insofar as:

Thanks for your assistance by the way

I basically took the folder (https://github.com/espressif/ESP8266_RTOS_SDK/tree/master/components/ssl), copied it into the lib/ folder, then had to mangle around with config files and defines to get it to work.

The example code is now

void test_crypto() {
	mbedtls_pk_context pkContext;
	mbedtls_pk_init(&pkContext);
	mbedtls_pk_free(&pkContext);

	mbedtls_ssl_cookie_setup(NULL, NULL, NULL);
	mbedtls_ssl_cache_context cache;
	mbedtls_ssl_cache_init(&cache);
	mbedtls_ssl_conf_dtls_cookies(NULL, NULL, NULL, NULL);
}

which compiles fine with the correctly activated settings. I’ve put it into a repository with build instructions here: GitHub - maxgerhardt/pio-esp8266-rtos-sdk-custom-mbedtls: Contains an example for building a customized mbedtls library with the esp8266-rtos-sdk framework.

Thank you for this, wow. I am gonna hack away with this, will share my results

I’ve run with your idea and did a few things differently. I symlinked things around and made a fake library.json. Then, I too fiddled with some pathing and includes. This has the benefit of ‘following’ upgrades to the underlying rtos sdk. Also has the advantage of needing no modifications to the underlying platformio folders. Example code here:

https://bitbucket.org/malachib/playground.esp/src/master/src/PGESP-11/

It isn’t perfect. Managing dependencies is really hard. But this simple example works. My more complex examples (real use cases) don’t, because I have a lib which wants to depend on mbedtls conditionally and I’m not sure how to do that.