Library / SDK
Mbed-TLS/mbedtls avatar
Mbed-TLS/mbedtls

Mbed TLS: a C TLS and X.509 library for embedded targets

An open source, portable, easy to use, readable and flexible TLS library, and reference implementation of the PSA Cryptography API. Releases are on a varying cadence, typically around 3 - 6 months between releases.

6,970 stars2,975 forksCNOASSERTION

At a glance

What is it?
Mbed TLS implements TLS, DTLS and X.509 certificate handling in C, with a build split across three libraries and a PSA Cryptography API implementation in a submodule. It fits firmware and constrained devices; it is a poor fit if you want a batteries-included application stack.
Who is it for?
Adopt Mbed TLS if you are writing C or C++ firmware that needs TLS, DTLS or X.509 parsing and you want to control the feature set at compile time. Do not adopt it if you want a packaged HTTP or MQTT client with certificate management handled for you; Mbed TLS stops at the protocol and certificate layer.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 4 days ago.
What is it written in?
Mainly C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 28, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What Mbed TLS actually provides, and to whom

Mbed TLS is a C library that implements X.509 certificate manipulation plus the TLS and DTLS protocols. The README states its small code footprint makes it suitable for embedded systems, and that framing explains most of its design decisions. The target reader is someone writing firmware or a constrained native application who needs to terminate a TLS connection or parse certificates without pulling in a general-purpose operating system's crypto stack.

It is also the reference implementation of the PSA Cryptography API. That implementation now lives in a separate repository, TF-PSA-Crypto, which is pulled in as a submodule and built as its own library. So the project is two things at once: a TLS and X.509 library, and a cryptography API implementation that other code can call directly. If you only want AES or ECDSA without TLS, the PSA layer is usable on its own, but you are then depending on the submodule's release cycle as well as Mbed TLS's own.

Three libraries, two config headers, one dependency chain

The build produces three libraries: libtfpsacrypto, libmbedx509, and libmbedtls. The dependency direction is fixed. libmbedtls depends on libmbedx509 and libtfpsacrypto, and libmbedx509 depends on libtfpsacrypto. The README warns that some linkers expect flags in a specific order, giving the GNU linker example -lmbedtls -lmbedx509 -ltfpsacrypto. If you link in the wrong order and see undefined symbols, this is why. The cryptographic library is also shipped under its legacy name libmbedcrypto.

Configuration is split too, and this is the part that surprises people. X.509 and TLS options live in include/mbedtls/mbedtls_config.h. Cryptography and platform options live in the TF-PSA-Crypto file tf-psa-crypto/include/psa/crypto_config.h. Two headers, two concerns. You can edit them by hand, or drive them with the Python script scripts/config.py, which the README says takes --help for usage instructions. The configs/ directory holds non-standard configurations for specific use cases, documented in configs/README.txt.

Installing Mbed TLS and making a first build

The supported branches use Git submodules, so a clone is not immediately buildable. The README instructs you to run this after cloning or checking out a branch or tag:

bash
git submodule update --init --recursive

There are two submodules, the framework and tf-psa-crypto. The 3.6 LTS branch contains only the framework submodule. Official source release tarballs already include the submodule contents, so if you download a release tarball you can skip this step. That is the easier route for a first look.

You need CMake 3.20.2 or later, a build system such as Make or Ninja, a C99 toolchain, Python 3.8 or later for the test code, and Perl to run tests. Out-of-tree builds are recommended:

bash
mkdir /path/to/build_dir && cd /path/to/build_dir
cmake /path/to/mbedtls_source
cmake --build .

If Python is not available and you want to skip the test suites, the README gives this flag:

bash
cmake -DENABLE_TESTING=Off /path/to/mbedtls_source

For shared libraries instead of static ones, the documented option is -DUSE_SHARED_MBEDTLS_LIBRARY=On. CMake build types include Release, Debug, Coverage and ASan; the ASan type instruments the code with AddressSanitizer to check for memory errors. Once built, ctest runs the test suites. If you are working from the development branch rather than a release, some source files are generated and absent, and the README points at framework/scripts/make_generated_files.py, with Python packages installed via python3 -m pip install --user -r scripts/basic.requirements.txt. The generator looks for a host compiler in the HOSTCC variable, then CC, then an executable called cc on the path.

Where the development branch bites you

The generated-source section of the README is the clearest limitation in the whole document. Files whose content depends only on the Mbed TLS source are not committed to the development branch; they are generated by scripts. Official releases do include them. So a fresh checkout of the default branch, which is development, can fail to build until you either run the generator or let CMake do it. On non-Windows systems, when not cross-compiling, CMake generates the required files automatically, which hides the problem for most desktop users. Cross-compiling is exactly where it stops being automatic, and the README's advice is to set CC or HOSTCC to the intended host compiler before generating files.

This is a real friction point for anyone building for an embedded target on a build server. The host compiler used for generating test data is not the target compiler, and mixing the two variables up produces confusing failures. It is also a reason to prefer release tarballs in CI: they carry the generated files, so the toolchain you need is only the target one.

The second limitation is scope. Mbed TLS gives you TLS, DTLS and X.509. It does not give you an HTTP client, a certificate store manager, or a trust-on-first-use policy. Those are application decisions, and the library will happily let you make them badly.

Mbed TLS versus OpenSSL and wolfSSL

The most common comparison is with OpenSSL, and the difference is structural rather than a matter of feature checklists. OpenSSL is built for general-purpose systems and ships a large command-line tool alongside the library. Mbed TLS is built for a small code footprint, and its configuration model reflects that: you choose features at compile time through two header files, and unused code is not linked in. The README's configs/ directory exists precisely because different use cases want different feature sets, which is not a workflow OpenSSL encourages.

wolfSSL is the closer alternative in intent, since it also targets embedded systems, and the search data shows people comparing the two directly. The README does not describe wolfSSL's internals, so the honest statement is that both occupy the embedded-TLS niche and the choice will come down to the API surface and licence terms you can live with. BearSSL also appears in search comparisons; it is a smaller, more minimal TLS implementation, and Mbed TLS offers more protocol and certificate surface than a minimal stack would.

One comparison worth making explicitly: Mbed TLS versus PSA. Those are not competitors. The PSA Cryptography API is implemented inside this project, in the TF-PSA-Crypto submodule, and the TLS layer builds on it. Choosing between them is choosing between the protocol layer and the crypto layer, not between two libraries.

Licence and upgrade cost

The repository metadata does not resolve to a standard SPDX identifier, so the licence text in the LICENSE file is the thing to read rather than any summary, including this one. What the README does support is the release cadence: releases come on a varying cadence, typically around 3 to 6 months apart. Recent tags show a 4.2.0, a 4.1.1 and a 3.6.7 release, all dated 2026-07-07, which is consistent with a maintenance line and a current line being cut together.

The upgrade cost is concentrated in the configuration headers and the library split. Moving from the 3.6 LTS branch to a 4.x branch changes the submodule layout, because 3.6 carries only the framework submodule while 4.x also carries tf-psa-crypto. That is a build-system change, not just a version bump, and it affects the link line. The README's BRANCHES.md is the file that documents which branches are supported, and it is the first thing to read before planning an upgrade. The last push to the repository was on 2026-09-21.

Editorial conclusion

Adopt Mbed TLS if you are writing C or C++ firmware that needs TLS, DTLS or X.509 parsing and you want to control the feature set at compile time. Do not adopt it if you want a packaged HTTP or MQTT client with certificate management handled for you; Mbed TLS stops at the protocol and certificate layer. Before committing, verify which branch you are on, because the 3.6 LTS branch ships only the framework submodule while 4.x branches also carry tf-psa-crypto, and check that your linker accepts the library order -lmbedtls -lmbedx509 -ltfpsacrypto. Then confirm the licence text in the LICENSE file, since the repository metadata does not resolve to a standard SPDX identifier.

Frequently asked questions

What is Mbed TLS used for?

It is a C library that implements X.509 certificate manipulation and the TLS and DTLS protocols, and it is also the reference implementation of the PSA Cryptography API. The README states its small code footprint makes it suitable for embedded systems.

How do I install Mbed TLS on Ubuntu?

The README does not give distribution packages. It documents building from source with CMake: initialize the submodules with git submodule update --init --recursive, then run cmake against the source directory in a separate build directory and build. You need CMake 3.20.2 or later and a C99 toolchain.

Is Mbed TLS open source?

It is published as an open source project on GitHub under the Mbed-TLS organisation. The repository metadata does not resolve to a standard SPDX licence identifier, so the LICENSE file is the authoritative source for the terms.

How does Mbed TLS compare with OpenSSL?

Mbed TLS is built for a small code footprint and lets you select features at compile time through mbedtls_config.h and the TF-PSA-Crypto crypto_config.h. OpenSSL targets general-purpose systems. The README does not include benchmark numbers for either, so performance claims would be speculation.

What is the difference between Mbed TLS and the PSA Cryptography API?

They are not alternatives. The PSA Cryptography API implementation lives in the TF-PSA-Crypto submodule inside this project, and the TLS and X.509 layers depend on it.

Official sources

  1. Issues
  2. Mbed-TLS/mbedtls on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/mbed-tls-mbedtls.svg)](https://hysenlabs.com/projects/mbed-tls-mbedtls)