When I saw the recent announcement that PolarSSL is now owned by ARM and called mbed TLS, I thought it would be interesting to see how easily it could be built using ELLCC.
I downloaded the latest release (mbedtls-1.3.10-gpl.tgz) from the web site on to my x86_64 Linux box. A quick look at the README.txt file showed that mbed TLS can be built with make, cmake, or Microsoft Visual Studio. I opted for make.
It turns out that using ELLCC to cross build this library is very easy. Here is the command line for ARM:
[~/mbedtls] dev% tar xvfpz ~/Downloads/mbedtls-1.3.10-gpl.tgz [~/mbedtls] dev% cd mbedtls-1.3.10/ [~/mbedtls/mbedtls-1.3.10] dev% make CC="~/ellcc/bin/ecc -target arm-linuxlld-engeabihf"
(I happen to have ELLCC installed in my home directory at ~/ellcc.) This single command built the library as well as a test suite. I have binfmt installed on my Linux box, which a cool way of telling my x86_64 Linux kernel how to run foreign executables (in this case ARM binaries). So I decided to try running the test suite.
[~/mbedtls/mbedtls-1.3.10] dev% make check Running checks (Success if all tests PASSED) - test_suite_aes.ecb PASSED (77 / 77 tests (0 skipped)) - test_suite_aes.cbc [many tests deleted] - test_suite_version PASSED (5 / 5 tests (0 skipped)) [~/mbedtls/mbedtls-1.3.10] dev%
All the tests passed. Pretty easy, huh? To prove I’ve really built for ARM, I used the file command:
[~/mbedtls/mbedtls-1.3.10] dev% file tests/test_suite_aes.cbc tests/test_suite_aes.cbc: ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, not stripped [~/mbedtls/mbedtls-1.3.10] dev%
So I thought, “This is cool, how about using ELLCC’s MinGW64 support to try a build for Windows?”. The answer was only slightly more complicated.
First I tried:
[~/mbedtls/mbedtls-1.3.10] dev% make clean [~/mbedtls/mbedtls-1.3.10] dev% make CC="~/ellcc/bin/ecc -target x86_64-w64-mingw32"
This didn’t work out so well. I got:
... CC x509write_crt.c CC x509write_csr.c CC xtea.c AR libmbedtls.a ar: creating libmbedtls.a RL libmbedtls.a LN libpolarssl.a -> libmbedtls.a CC aes/aescrypt2.c ../library/libmbedtls.a: error adding symbols: Archive has no index; run ranlib to add one ecc: error: linker command failed with exit code 1 (use -v to see invocation) make[1]: *** [aes/aescrypt2] Error 1 make: *** [all] Error 2 [~/mbedtls/mbedtls-1.3.10] dev%
Apparently my system ar command doesn’t handles Windows PE object files. No problem. I’ll just tell make to use ELLCC’s ecc-ar, which has been built with PE format support:
[~/mbedtls/mbedtls-1.3.10] dev% make clean [~/mbedtls/mbedtls-1.3.10] dev% make CC="~/ellcc/bin/ecc -target x86_64-w64-mingw32" AR=~/ellcc/bin/ecc-ar
This time, building the test suite failed with errors like:
... ../library/libmbedtls.a(net.o):(.text+0x4ce): undefined reference to `__imp_WSAGetLastError' ../library/libmbedtls.a(net.o):(.text+0x503): undefined reference to `__imp_shutdown' ../library/libmbedtls.a(net.o):(.text+0x513): undefined reference to `__imp_closesocket' ecc: error: linker command failed with exit code 1 (use -v to see invocation) make[1]: *** [pkey/dh_client] Error 1 make: *** [all] Error 2 [~/mbedtls/mbedtls-1.3.10] dev
I seem to be missing a library needed for linking. I needed to find which library was missing, so I used the trusty nm command to find out:
[~/ellcc/libecc/mingw/x86_64-w64-mingw32/sys-root/mingw/lib] dev% ~/ellcc/bin/ecc-nm -A *.a | grep __imp_closesocket /home/rich/ellcc/bin/ecc-nm: libruntimeobject.a: File format not recognized libws2_32.a:dscdbs00149.o:0000000000000000 I __imp_closesocket libwsock32.a:divxs00037.o:0000000000000000 I __imp_closesocket [~/ellcc/libecc/mingw/x86_64-w64-mingw32/sys-root/mingw/lib] dev%
Looks like I have two choices. libws2_32.a sounds newer (grin), so I’ll try that. The tests/Makefile has the line:
LDFLAGS += -L../library -lmbedtls $(SYS_LDFLAGS)
All I have to do is add a define for SYS_LDFLAGS:
[~/mbedtls/mbedtls-1.3.10] dev% make CC="~/ellcc/bin/ecc -target x86_64-w64-mingw32" AR=~/ellcc/bin/ecc-ar SYS_LDFLAGS=-lws2_32 ... Generate test_suite_rsa.c CC test_suite_rsa.c Generate test_suite_shax.c CC test_suite_shax.c Generate test_suite_x509parse.c CC test_suite_x509parse.c Generate test_suite_x509write.c CC test_suite_x509write.c Generate test_suite_xtea.c CC test_suite_xtea.c Generate test_suite_version.c CC test_suite_version.c [~/mbedtls/mbedtls-1.3.10] dev%
Let’s try the file command again.
file tests/test_suite_aes.cbc tests/test_suite_aes.cbc: PE32+ executable (console) x86-64, for MS Windows [~/mbedtls/mbedtls-1.3.10] dev%
Perfect. Now the test suite. Since binfmt can handle Windows executables and run them under Wine, things should just work.
[~/mbedtls/mbedtls-1.3.10] dev% make check ... XTEA Encrypt CBC #4 ............................................... PASS XTEA Encrypt CBC #5 ............................................... PASS XTEA Encrypt CBC #6 ............................................... PASS XTEA Decrypt CBC #1 ............................................... PASS XTEA Decrypt CBC #2 ............................................... PASS XTEA Decrypt CBC #3 ............................................... PASS XTEA Decrypt CBC #4 ............................................... PASS XTEA Decrypt CBC #5 ............................................... PASS XTEA Decrypt CBC #6 ............................................... PASS XTEA Selftest ..................................................... PASS PASSED (25 / 25 tests (0 skipped)) - test_suite_version Check compiletime library version ................................. PASS Check runtime library version ..................................... PASS Check for POLARSSL_VERSION_C ...................................... PASS Check for POLARSSL_AES_C when already present ..................... PASS Check for unknown define .......................................... PASS PASSED (5 / 5 tests (0 skipped)) [~/mbedtls/mbedtls-1.3.10] dev%
Voila!