mbed TLS is designed to be used in threaded and non-threaded environments. In order to keep mbed TLS thread-safe it is important to keep a few things in mind.
First, most functions use an explicit context. Most of the time, as long as this context is not shared between threads, you're safe. However, be aware that sometimes a context can be share indirectly, for example an SSL context can point to an RSA context (our private key).
The default philosophy is: a context should only be used or accessed by a single thread at the same time, unless:
- The documentation for the functions that access the shared context explicitly states the function is thread-safe, or
- You perform explicit locking yourself (perhaps in a wrapper function).
Thread Safety with different versions
Starting from the 1.3 branch
PolarSSL 1.3.0 introduced a generic threading layer in the library that already handles some default locks and mutexes for the user and abstracts the threading layer to allow easy pluging in any thread-library.
This threading layer is enabled by defining POLARSSL_THREADING_C in the 1.3 branch and MBEDTLS_THREADING_C in 2.0 and above in config.h, see "How do I configure mbed TLS". It is not enabled by default, as you also need to pick an underlying threading library: we provide built-in support for Pthread with MBEDTS_THREADING_PTHREAD, or you can plug any other thread-library with MBEDTLS_THREADING_ALT and calling
mbedtls_threading_set_alt() at the beginning of your program and
mbedtls_threading_free_alt() at the end.
Before the 1.3 branch
In previous versions of PolarSSL, nothing is wrapped by default, so all relevant wrappers and locks have to be written within the using application.
Status of various contexts and associated functions
Starting with version 1.3.8, all contexts have associated
_free() functions. For contexts that include mutexes, these functions will create/initialize the mutex, then free/destroy it. For obvious reasons, if you share a context between threads, you'll need to call these functions only from the main thread, at the beginning and end of the context's lifetime.
mbed TLS currently provides automatic locking (when the threading layer is enabled) for relevant functions in the following modules (unless indicated otherwise, starting from verions 1.3.0):
- The SSL cache callbacks provided in ssl_cache.c.
- Memory buffer-based allocator.
- Entropy (only
entropy_func()in 1.3.0, all public functions in 1.3.5 and later).
- In the X.509 module, in the 1.3 branch,
x509_crt_parse_path()is generally not thread-safe in the way it reads the directory; since the 2.0 branch,
mbedtls_x509_crt_parse_path()is always thread-safe.
- CTR-DRBG and HMAC-DRBG (since 2.0).
- The SSL session tickets callbacks provided in ssl_ticket.c (since their introduction in 2.0)
- The DTLS CLientHello cookie callbacks provided in ssl_cookie.c (since their introduction in 2.0)
We think this covers all case where a context usually needs to be shared across threads. If you have use cases where another context needs to be shared across threads, please let us know!