From 17c9c1fcdf48ea033a307ce77c432f039ead4584 Mon Sep 17 00:00:00 2001 From: Hayden Roche Date: Thu, 6 Jan 2022 10:25:34 -0800 Subject: [PATCH] Add support for a wolfSSL crypto backend. (#629) It uses wolfSSL's OpenSSL compatibility layer, so rather than introduce new wolfssl.h/c files, the new backend just reuses openssl.h/c. Additionally, replace EVP_Cipher() calls with EVP_CipherUpdate(), since EVP_Cipher() is not recommended. Credit: Hayden Roche --- Makefile.wolfSSL.inc | 3 +++ acinclude.m4 | 13 +++++++++++++ configure.ac | 1 + src/Makefile.am | 3 +++ src/crypto.h | 2 +- src/openssl.c | 16 +++++---------- src/openssl.h | 46 +++++++++++++++++++++++++++++++++++++++++--- 7 files changed, 69 insertions(+), 15 deletions(-) create mode 100644 Makefile.wolfSSL.inc diff --git a/Makefile.wolfSSL.inc b/Makefile.wolfSSL.inc new file mode 100644 index 00000000..24fed511 --- /dev/null +++ b/Makefile.wolfSSL.inc @@ -0,0 +1,3 @@ +CRYPTO_CSOURCES = openssl.c +CRYPTO_HHEADERS = openssl.h +CRYPTO_LTLIBS = -lwolfssl diff --git a/acinclude.m4 b/acinclude.m4 index 2066f0ec..63d5d5cd 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -431,6 +431,19 @@ m4_case([$1], ]) ], +[wolfssl], [ + if test "${with_libwolfssl_prefix+set}" = set; then + CPPFLAGS="$CPPFLAGS${CPPFLAGS:+ }-I${with_libwolfssl_prefix}/include/wolfssl" + else + AC_MSG_ERROR([When using wolfSSL, must specify prefix with --with-libwolfssl-prefix in order to find OpenSSL compatibility headers.]) + fi + LIBSSH2_LIB_HAVE_LINKFLAGS([wolfssl], [], [#include ], [ + AC_DEFINE(LIBSSH2_WOLFSSL, 1, [Use $1]) + LIBSREQUIRED="$LIBSREQUIRED${LIBSREQUIRED:+ }libwolfssl" + found_crypto="$1" + ]) +], + [libgcrypt], [ LIBSSH2_LIB_HAVE_LINKFLAGS([gcrypt], [], [#include ], [ AC_DEFINE(LIBSSH2_LIBGCRYPT, 1, [Use $1]) diff --git a/configure.ac b/configure.ac index b51bb4b9..ca3cbee1 100644 --- a/configure.ac +++ b/configure.ac @@ -92,6 +92,7 @@ m4_set_add([crypto_backends], [openssl]) m4_set_add([crypto_backends], [libgcrypt]) m4_set_add([crypto_backends], [mbedtls]) m4_set_add([crypto_backends], [wincng]) +m4_set_add([crypto_backends], [wolfssl]) AC_ARG_WITH([crypto], AC_HELP_STRING([--with-crypto=auto|]m4_set_contents([crypto_backends], [|]), diff --git a/src/Makefile.am b/src/Makefile.am index 31d58ed5..46cb88cf 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,6 +5,9 @@ AUTOMAKE_OPTIONS = foreign nostdinc if OPENSSL include ../Makefile.OpenSSL.inc endif +if WOLFSSL +include ../Makefile.wolfSSL.inc +endif if LIBGCRYPT include ../Makefile.libgcrypt.inc endif diff --git a/src/crypto.h b/src/crypto.h index 809aef7e..7a99b4f3 100644 --- a/src/crypto.h +++ b/src/crypto.h @@ -38,7 +38,7 @@ * OF SUCH DAMAGE. */ -#ifdef LIBSSH2_OPENSSL +#if defined(LIBSSH2_OPENSSL) || defined(LIBSSH2_WOLFSSL) #include "openssl.h" #endif diff --git a/src/openssl.c b/src/openssl.c index 72a85b3b..857110f3 100644 --- a/src/openssl.c +++ b/src/openssl.c @@ -40,7 +40,8 @@ #include "libssh2_priv.h" -#ifdef LIBSSH2_OPENSSL /* compile only if we build with openssl */ +/* compile only if we build with openssl or wolfSSL */ +#if defined(LIBSSH2_OPENSSL) || defined(LIBSSH2_WOLFSSL) #include #include "misc.h" @@ -455,27 +456,20 @@ _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx, { unsigned char buf[EVP_MAX_BLOCK_LENGTH]; int ret; + int outlen; (void) algo; (void) encrypt; #ifdef HAVE_OPAQUE_STRUCTS - ret = EVP_Cipher(*ctx, buf, block, blocksize); + ret = EVP_CipherUpdate(*ctx, buf, &outlen, block, blocksize); #else - ret = EVP_Cipher(ctx, buf, block, blocksize); + ret = EVP_CipherUpdate(ctx, buf, &outlen, block, blocksize); #endif -#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3 - if(ret != -1) { -#else if(ret == 1) { -#endif memcpy(block, buf, blocksize); } -#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3 - return ret != -1 ? 0 : 1; -#else return ret == 1 ? 0 : 1; -#endif } #if LIBSSH2_AES_CTR && !defined(HAVE_EVP_AES_128_CTR) diff --git a/src/openssl.h b/src/openssl.h index 2a002b41..3eef0236 100644 --- a/src/openssl.h +++ b/src/openssl.h @@ -39,6 +39,43 @@ * OF SUCH DAMAGE. */ +#ifdef LIBSSH2_WOLFSSL + +#include +#include + +#if defined(NO_DSA) || defined(HAVE_FIPS) +#define OPENSSL_NO_DSA +#endif + +#if defined(NO_MD5) || defined(HAVE_FIPS) +#define OPENSSL_NO_MD5 +#endif + +#if !defined(WOLFSSL_RIPEMD) || defined(HAVE_FIPS) +#define OPENSSL_NO_RIPEMD +#endif + +#if defined(NO_RC4) || defined(HAVE_FIPS) +#define OPENSSL_NO_RC4 +#endif + +#ifdef NO_DES3 +#define OPENSSL_NO_DES +#endif + +#ifdef EVP_aes_128_ctr +#define HAVE_EVP_AES_128_CTR +#endif + +/* wolfSSL doesn't support Blowfish or CAST. */ +#define OPENSSL_NO_BF +#define OPENSSL_NO_CAST +/* wolfSSL has no engine framework. */ +#define OPENSSL_NO_ENGINE + +#endif /* LIBSSH2_WOLFSSL */ + #include #include #include @@ -57,8 +94,10 @@ #include #include -#if OPENSSL_VERSION_NUMBER >= 0x10100000L && \ - !defined(LIBRESSL_VERSION_NUMBER) +#if (OPENSSL_VERSION_NUMBER >= 0x10100000L && \ + !defined(LIBRESSL_VERSION_NUMBER)) || defined(LIBSSH2_WOLFSSL) +/* For wolfSSL, whether the structs are truly opaque or not, it's best to not + * rely on their internal data members being exposed publicly. */ # define HAVE_OPAQUE_STRUCTS 1 #endif @@ -105,7 +144,8 @@ #define LIBSSH2_HMAC_SHA256 1 #define LIBSSH2_HMAC_SHA512 1 -#if OPENSSL_VERSION_NUMBER >= 0x00907000L && !defined(OPENSSL_NO_AES) +#if (OPENSSL_VERSION_NUMBER >= 0x00907000L && !defined(OPENSSL_NO_AES)) || \ + (defined(LIBSSH2_WOLFSSL) && defined(WOLFSSL_AES_COUNTER)) # define LIBSSH2_AES_CTR 1 # define LIBSSH2_AES 1 #else