Sartura adds mbed TLS support to libssh project

Recent Sartura Open Source contributions include the addition of mbed TLS support for libssh project.


Sartura continues to support the Open Source ecosystem by providing mbed TLS support to the libssh project. The end result is visible in commits:

d11869bd pki: Add mbedTLS ECDSA key comparison support
963111b8 tests: Fix segfault with mbedTLS built without threading support
77865246 add mbedtls crypto support

One reason behind for this contribution was a customer requirement for replacing OpenSSL from the customer’s OpenWrt firmware with a SSH library, for which we extended libssh support to use mbed TLS.

libssh & mbed TLS

libssh is a suite of network-level utilities based on the Secure Shell (SSH) protocol. libssh utilities help to secure network communications by encrypting all network traffic (including passwords) over multiple authentication methods and providing secure tunneling capabilities.

Sartura made contributions to the libssh project in the past, mainly concerning C++ bindings support, although some minor contributions were also made for libssh testing and build system infrastructure. The C++ bindings for libssh were completely embedded in a single .hpp file, which benefited both in regards to binary compatibility and performance.

The mbed TLS software is a light-weight open source cryptographic and SSL library written in C. The library is suitable for embedded platforms and has been ported to a number of architectures, including ARM, PowerPC, MIPS and Motorola 68000, x86, x64, and others. The cryptographic components in mbed TLS can be used and compiled separately, and features included or excluded via a single configuration file (include/mbedtls/config.h). Its central SSL module combines cryptographic components, the abstraction layer and support components to provide complete protocol implementation for SSL v3, TLS v1.0, TLS v1.1 and TLS v1.2.

Adding mbed TLS support

The easiest starting point for adding mbed TLS support were the CMake build files, mainly for two reasons. First, because by understanding the build structure we can better understand the whole project structure, and therefore better pinpoint from where we can begin with the patch. Second, because setting up a working build system for mbed TLS allows for early testing of the implemented changes, and thus an easier development process in general.

After the build system was in a working step, the next step were the C headers. Fortunately, the libssh project already contained a wrapper for crypto libraries (defined in wrapper.h), which wraps the calls into OpenSSL-compatible calls. This eased the patching procedure significantly and saved us from the effort of having to write the wrapper ourselves. Before the mbed TLS patch, the only supported library -- other than OpenSSL -- was Libgcrypt. Wrappers defined in Libgcrypt served as a kind of a template for adding mbed TLS support and figuring out which files need to be added and modified.

The largest header addition throughout this process was the libmbedcrypto.h header. Generally, the libLIBNAME headers define wrappers that wrap the library’s calls and types into the format of OpenSSL types and calls. Some minor additions were also made in the crypto key structures.

One of the biggest obstacles when adding mbed TLS support was the lack of support for DSA, since mbedTLS's main use case is TLS/SSL. DSA is not used often nowadays and has been replaced with more secure algorithms, so this issue was not critical and we were able to solve it using #define checks and disabling DSA at compile time. If a more important algorithm was missing, there would be no point in adding support for the library unless the algorithm was added to the crypto library as well.

Another problem that appeared due to mbedTLS mainly being a TLS library is the lack of high-level ECC API support compared to Libgcrypt and OpenSSL. This shortfall was overcomed by adding some low-level functionality.

The C file changes mostly consist of mbed TLS specific files:

- ecdh_mbedcrypto.c - Adds mbed TLS-specific support for elliptic curve Diffie Hellman.

- libmbedcrypto.c - Defines wrappers for symmetric crypto, hash functions and crypto library initialisation functions.

- mbedcrypto_missing.c - Adds missing bignum functionality.

- pki_mbedcrypto.c - Adds wrappers for public key cryptography algorithms.

Testing

The most useful tools for testing were the existing libssh tests and Valgrind. Valgrind's memcheck is the best known Valgrind tool, and most of the detected bugs were found out when libssh tests were run with memcheck. However, there are other, less mentioned Valgrind tools, namely Helgrind and DRD tools which can be used to detect threading errors.

Another extremely useful tool that saved a lot of debugging time is rr which is a wrapper around gdb that allows debugging session recordings and reverse stepping. The recording feature of the tool proved to be really useful when debugging bugs that appeared only occasionally. Unfortunately, rr requires performance counters to work, so only some newer CPU architectures are supported. The cppcheck and flawfinder tools were also used for testing the patch, however the findings were not substantial, particularly considering the setup time required for cppcheck.

Mailing list activity

The patches mentioned in this blog post can also be found on the official libssh project mailing list [1, 2, 3]. Sartura’s team member Juraj Vijtiuk has communicated with upstream libssh developers to make the changes acceptable. Lastly, Sartura would use this opportunity to thank the libssh team for their collaboration on this support and for the continuous work in creating a great SSH library.