1
0
mirror of https://github.com/libssh2/libssh2.git synced 2026-10-24 03:48:58 +03:00

mbedtls: require 3.1.0 (2.x no longer supported upstream)

The mbedTLS API is not one API but distinctly incompatible APIs
depending on its version. 2.x is largely incompatible with 3.x, and 4.x
is largely incompatible with 3.x, also dropping certain legacy crypto
primitives.

Following the release of 3.x in 2021, libssh2 added support for 3.x in
2022. 4.x was released in October 2025, and it makes using the PSA
Crypto API mandatory, after adding it in 3.x.

Supporting 2.x while also supporting the PSA Crypto API would mean
supporting 3 different crypto backends meshed together in a single
source file, with various overlapping and per-version parts, with
different features and separate needs to test.

2.x is also no longer maintained, supported, or security patched, as
written in its latest, and final, release notes on 2025-03-24:
https://github.com/Mbed-TLS/mbedtls/releases/tag/mbedtls-2.28.10
The mbedTLS project recommends upgrading to an upper major version.

To allow adding support for the PSA Crypto API and the 4.x series, and
to avoid an unmaintained 2.x major version, this patch drops support for
mbedTLS 2.x.

Also:
- GHA: update CI jobs to either use Linuxbrew mbedtls 3.x, or build from
  source and cache it.
- Require 3.1.0 minimum (instead of 3.0.0), because libssh2 never built
  with 3.0.0 due the use of API `mbedtls_cipher_info_get_key_bitlen()`.
  Nobody complained since the initial commit introducing it.

Refs:
https://github.com/Mbed-TLS/TF-PSA-Crypto/blob/tf-psa-crypto-1.0.0/docs/1.0-migration-guide.md
https://github.com/Mbed-TLS/TF-PSA-Crypto/blob/tf-psa-crypto-1.0.0/docs/psa-transition.md#asymmetric-cryptography

Closes #1727
This commit is contained in:
Viktor Szakats
2025-08-13 11:26:12 +02:00
parent 4aa1720b60
commit f63f68b350
5 changed files with 53 additions and 77 deletions

View File

@@ -139,7 +139,8 @@ jobs:
sha256sum pkg.bin && sha256sum pkg.bin | grep -qwF -- "${OLD_CMAKE_SHA256_WIN_INTEL}" && unzip -q pkg.bin && rm -f pkg.bin
printf '%s' ~/cmake-"${OLD_CMAKE_VERSION}"-win64-x64/bin/cmake.exe > ~/old-cmake-path.txt
elif [[ "${MATRIX_IMAGE}" = *'ubuntu'* ]]; then
sudo apt-get -o Dpkg::Use-Pty=0 install libgcrypt-dev libssl-dev libmbedtls-dev libwolfssl-dev
sudo apt-get -o Dpkg::Use-Pty=0 install libgcrypt-dev libssl-dev libwolfssl-dev
/home/linuxbrew/.linuxbrew/bin/brew install mbedtls@3
cd ~
curl --disable --fail --silent --show-error --connect-timeout 15 --max-time 60 --retry 3 --retry-connrefused \
--location "https://github.com/Kitware/CMake/releases/download/v${OLD_CMAKE_VERSION}/cmake-${OLD_CMAKE_VERSION}-Linux-aarch64.tar.gz" --output pkg.bin
@@ -175,6 +176,10 @@ jobs:
run: |
if [[ "${MATRIX_IMAGE}" = *'macos'* ]]; then
export PKG_CONFIG_PATH; PKG_CONFIG_PATH="$(brew --prefix mbedtls@3)"/lib/pkgconfig
elif [[ "${MATRIX_IMAGE}" = *'ubuntu'* ]]; then
eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
export PKG_CONFIG_PATH; PKG_CONFIG_PATH="$(brew --prefix mbedtls@3)/lib/pkgconfig"
export LDFLAGS; LDFLAGS="-Wl,-rpath,$(brew --prefix mbedtls@3)/lib"
fi
./tests/cmake/test.sh find_package -DCRYPTO_BACKEND=mbedTLS
@@ -224,7 +229,7 @@ jobs:
matrix:
compiler: [gcc, clang, clang-tidy]
arch: [amd64]
crypto: [OpenSSL, Libgcrypt, mbedTLS, wolfSSL]
crypto: [OpenSSL, Libgcrypt, mbedTLS-prev, wolfSSL]
build: [cmake]
zlib: ['OFF', 'ON']
exclude:
@@ -302,6 +307,8 @@ jobs:
FIXTURE_TRACE_ALL_CONNECT: 0
MBEDTLS_VERSION: 3.6.6
MBEDTLS_SHA256: 8fb65fae8dcae5840f793c0a334860a411f884cc537ea290ce1c52bb64ca007a
MBEDTLS_VERSION_PREV: 3.1.0
MBEDTLS_SHA256_PREV: b02df6f68dd1537e115a8497d5c173dc71edc55ad084756e57a30f951b725acd
WOLFSSL_VERSION: 5.9.0
WOLFSSL_SHA256: 6efc62b86f145a5c52bfd62294ca66c20ce85b54e9033f5d7e0ee73eb30306c1
WOLFSSL_VERSION_PREV: 5.5.4
@@ -329,7 +336,6 @@ jobs:
run: |
[ "${MATRIX_CRYPTO}" = 'OpenSSL' ] && pkg='libssl-dev'
[ "${MATRIX_CRYPTO}" = 'Libgcrypt' ] && pkg='libgcrypt-dev'
[ "${MATRIX_CRYPTO}" = 'mbedTLS' ] && pkg='libmbedtls-dev'
[ "${MATRIX_CRYPTO}" = 'wolfSSL' ] && pkg='libwolfssl-dev'
if [ -n "${pkg}" ]; then
sudo apt-get -o Dpkg::Use-Pty=0 install "${pkg}:${MATRIX_ARCH}"
@@ -364,6 +370,31 @@ jobs:
cmake --build .
cmake --install .
- name: 'cache mbedTLS (prev)'
if: ${{ matrix.crypto == 'mbedTLS-prev' }}
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
id: cache-mbedtls-prev
with:
path: ~/usr
key: ${{ runner.os }}-mbedtls-${{ env.MBEDTLS_VERSION_PREV }}-${{ matrix.arch }}
- name: 'install mbedTLS (prev) from source'
if: ${{ matrix.crypto == 'mbedTLS-prev' && !steps.cache-mbedtls-prev.outputs.cache-hit }}
run: |
curl --disable --fail --silent --show-error --connect-timeout 15 --max-time 120 --retry 6 --retry-connrefused \
--location "https://github.com/Mbed-TLS/mbedtls/archive/refs/tags/v${MBEDTLS_VERSION_PREV}.tar.gz" --output pkg.bin
sha256sum pkg.bin | tee /dev/stderr | grep -qwF -- "${MBEDTLS_SHA256_PREV}" && tar -xzf pkg.bin && rm -f pkg.bin
cd "mbedtls-${MBEDTLS_VERSION_PREV}"
export CC=gcc # compiler warning promoted to error when using clang (as tested with 3.0.0/3.1.0)
cmake -B . -G Ninja \
-DENABLE_PROGRAMS=OFF \
-DENABLE_TESTING=OFF \
-DUSE_STATIC_MBEDTLS_LIBRARY=OFF \
-DUSE_SHARED_MBEDTLS_LIBRARY=ON \
-DCMAKE_INSTALL_PREFIX="$HOME"/usr
cmake --build .
cmake --install .
- name: 'install wolfSSL from source'
if: ${{ startsWith(matrix.crypto, 'wolfSSL-from-source') }}
run: |

View File

@@ -62,7 +62,8 @@ jobs:
run: |
sudo rm -f /etc/apt/sources.list.d/{azure-cli.sources,microsoft-prod.list,ondrej-ubuntu-php-noble.sources}
sudo apt-get -o Dpkg::Use-Pty=0 update
sudo apt-get -o Dpkg::Use-Pty=0 install zlib1g-dev libssl-dev libgcrypt-dev libmbedtls-dev libwolfssl-dev
sudo apt-get -o Dpkg::Use-Pty=0 install zlib1g-dev libssl-dev libgcrypt-dev libwolfssl-dev
/home/linuxbrew/.linuxbrew/bin/brew install mbedtls@3
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
@@ -83,6 +84,8 @@ jobs:
cmake -B . -DCRYPTO_BACKEND=WinCNG -DCMAKE_VS_GLOBALS=TrackFileAccess=false
cmake --build . --verbose
else
eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
export PKG_CONFIG_PATH; PKG_CONFIG_PATH="$(brew --prefix mbedtls@3)/lib/pkgconfig"
for crypto in OpenSSL Libgcrypt mbedTLS wolfSSL; do
cmake -B _bld-"${crypto}" -G Ninja -DCRYPTO_BACKEND="${crypto}" -DENABLE_ZLIB_COMPRESSION=ON
cmake --build _bld-"${crypto}" --verbose

View File

@@ -481,6 +481,9 @@ endif()
if(CRYPTO_BACKEND STREQUAL "mbedTLS" OR NOT CRYPTO_BACKEND)
find_package(MbedTLS ${_specific_crypto_requirement})
if(MBEDTLS_FOUND)
if(MBEDTLS_VERSION VERSION_LESS 3.1.0)
message(FATAL_ERROR "mbedTLS v3.1.0 or upper required.")
endif()
set(CRYPTO_BACKEND "mbedTLS")
set(CRYPTO_BACKEND_DEFINE "LIBSSH2_MBEDTLS")
list(APPEND LIBSSH2_LIBS libssh2::mbedcrypto)

View File

@@ -36,23 +36,14 @@ else()
find_library(MBEDCRYPTO_LIBRARY NAMES "mbedcrypto" "libmbedcrypto")
unset(MBEDTLS_VERSION CACHE)
if(MBEDTLS_INCLUDE_DIR)
if(EXISTS "${MBEDTLS_INCLUDE_DIR}/mbedtls/build_info.h") # 3.x
set(_version_header "${MBEDTLS_INCLUDE_DIR}/mbedtls/build_info.h")
elseif(EXISTS "${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h") # 2.x
set(_version_header "${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h")
else()
unset(_version_header)
endif()
if(_version_header)
set(_version_regex "#[\t ]*define[\t ]+MBEDTLS_VERSION_STRING[\t ]+\"([0-9.]+)\"")
file(STRINGS "${_version_header}" _version_str REGEX "${_version_regex}")
string(REGEX REPLACE "${_version_regex}" "\\1" _version_str "${_version_str}")
set(MBEDTLS_VERSION "${_version_str}")
unset(_version_regex)
unset(_version_str)
unset(_version_header)
endif()
if(MBEDTLS_INCLUDE_DIR AND EXISTS "${MBEDTLS_INCLUDE_DIR}/mbedtls/build_info.h")
set(_version_regex "#[\t ]*define[\t ]+MBEDTLS_VERSION_STRING[\t ]+\"([0-9.]+)\"")
file(STRINGS "${MBEDTLS_INCLUDE_DIR}/mbedtls/build_info.h" _version_str REGEX "${_version_regex}")
string(REGEX REPLACE "${_version_regex}" "\\1" _version_str "${_version_str}")
set(MBEDTLS_VERSION "${_version_str}")
unset(_version_regex)
unset(_version_str)
unset(_version_header)
endif()
include(FindPackageHandleStandardArgs)

View File

@@ -43,12 +43,8 @@
#include <stdlib.h>
#if MBEDTLS_VERSION_NUMBER < 0x03000000
#define mbedtls_cipher_info_get_key_bitlen(c) (c->key_bitlen)
#define mbedtls_cipher_info_get_iv_size(c) (c->iv_size)
#define mbedtls_rsa_get_len(rsa) (rsa->len)
#define MBEDTLS_PRIVATE(m) m
#if MBEDTLS_VERSION_NUMBER < 0x03010000
#error "mbedTLS 3.1.0 or upper required"
#endif
/*******************************************************************/
@@ -415,13 +411,8 @@ _libssh2_mbedtls_rsa_new(libssh2_rsa_ctx **rsa,
libssh2_rsa_ctx *ctx;
ctx = (libssh2_rsa_ctx *) mbedtls_calloc(1, sizeof(libssh2_rsa_ctx));
if(ctx) {
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
if(ctx)
mbedtls_rsa_init(ctx);
#else
mbedtls_rsa_init(ctx, MBEDTLS_RSA_PKCS_V15, 0);
#endif
}
else
return -1;
@@ -483,20 +474,12 @@ _libssh2_mbedtls_rsa_new_private(libssh2_rsa_ctx **rsa,
if(!*rsa)
return -1;
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
mbedtls_rsa_init(*rsa);
#else
mbedtls_rsa_init(*rsa, MBEDTLS_RSA_PKCS_V15, 0);
#endif
mbedtls_pk_init(&pkey);
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
ret = mbedtls_pk_parse_keyfile(&pkey, filename, (const char *)passphrase,
mbedtls_ctr_drbg_random,
&_libssh2_mbedtls_ctr_drbg);
#else
ret = mbedtls_pk_parse_keyfile(&pkey, filename, (const char *)passphrase);
#endif
if(ret || mbedtls_pk_get_type(&pkey) != MBEDTLS_PK_RSA) {
mbedtls_pk_free(&pkey);
mbedtls_rsa_free(*rsa);
@@ -548,17 +531,11 @@ _libssh2_mbedtls_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa,
mbedtls_pk_init(&pkey);
pwd_len = passphrase ? strlen((const char *)passphrase) : 0;
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
ret = mbedtls_pk_parse_key(&pkey, (unsigned char *)filedata_nullterm,
filedata_len + 1,
passphrase, pwd_len,
mbedtls_ctr_drbg_random,
&_libssh2_mbedtls_ctr_drbg);
#else
ret = mbedtls_pk_parse_key(&pkey, (unsigned char *)filedata_nullterm,
filedata_len + 1,
passphrase, pwd_len);
#endif
_libssh2_mbedtls_safe_free(filedata_nullterm, filedata_len);
if(ret || mbedtls_pk_get_type(&pkey) != MBEDTLS_PK_RSA) {
@@ -615,15 +592,9 @@ _libssh2_mbedtls_rsa_sha2_verify(libssh2_rsa_ctx * rsactx,
return -1; /* failure */
}
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
ret = mbedtls_rsa_pkcs1_verify(rsactx,
md_type, (unsigned int)hash_len,
hash, sig);
#else
ret = mbedtls_rsa_pkcs1_verify(rsactx, NULL, NULL, MBEDTLS_RSA_PUBLIC,
md_type, (unsigned int)hash_len,
hash, sig);
#endif
free(hash);
return (ret == 0) ? 0 : -1;
@@ -673,19 +644,12 @@ _libssh2_mbedtls_rsa_sha2_sign(LIBSSH2_SESSION *session,
"Unsupported hash digest length");
ret = -1;
}
if(ret == 0) {
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
if(ret == 0)
ret = mbedtls_rsa_pkcs1_sign(rsa,
mbedtls_ctr_drbg_random,
&_libssh2_mbedtls_ctr_drbg,
md_type, (unsigned int)hash_len,
hash, sig);
#else
ret = mbedtls_rsa_pkcs1_sign(rsa, NULL, NULL, MBEDTLS_RSA_PRIVATE,
md_type, (unsigned int)hash_len,
hash, sig);
#endif
}
if(ret) {
LIBSSH2_FREE(session, sig);
return -1;
@@ -827,13 +791,9 @@ _libssh2_mbedtls_pub_priv_keyfile(LIBSSH2_SESSION *session,
int ret;
mbedtls_pk_init(&pkey);
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
ret = mbedtls_pk_parse_keyfile(&pkey, privatekey, passphrase,
mbedtls_ctr_drbg_random,
&_libssh2_mbedtls_ctr_drbg);
#else
ret = mbedtls_pk_parse_keyfile(&pkey, privatekey, passphrase);
#endif
if(ret) {
mbedtls_strerror(ret, (char *)buf, sizeof(buf));
mbedtls_pk_free(&pkey);
@@ -877,19 +837,12 @@ _libssh2_mbedtls_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
mbedtls_pk_init(&pkey);
pwd_len = passphrase ? strlen((const char *)passphrase) : 0;
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
ret = mbedtls_pk_parse_key(&pkey,
(unsigned char *)privatekeydata_nullterm,
privatekeydata_len + 1,
(const unsigned char *)passphrase, pwd_len,
mbedtls_ctr_drbg_random,
&_libssh2_mbedtls_ctr_drbg);
#else
ret = mbedtls_pk_parse_key(&pkey,
(unsigned char *)privatekeydata_nullterm,
privatekeydata_len + 1,
(const unsigned char *)passphrase, pwd_len);
#endif
_libssh2_mbedtls_safe_free(privatekeydata_nullterm, privatekeydata_len);
if(ret) {
@@ -1190,16 +1143,11 @@ _libssh2_mbedtls_parse_eckey(libssh2_ecdsa_ctx **ctx,
pwd_len = pwd ? strlen((const char *) pwd) : 0;
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
if(mbedtls_pk_parse_key(pkey, data, data_len, pwd, pwd_len,
mbedtls_ctr_drbg_random,
&_libssh2_mbedtls_ctr_drbg))
goto failed;
#else
if(mbedtls_pk_parse_key(pkey, data, data_len, pwd, pwd_len))
goto failed;
#endif
if(mbedtls_pk_get_type(pkey) != MBEDTLS_PK_ECKEY)
goto failed;