1 (edited by labonte_d 2022-06-14 08:10:57)

Topic: WolfSSL compatibility layer and Realm database

Good evening,

I was asked to complete a proof of concept where we want to replace the use of OpenSSL with Realm (realm-core) with WolfSSL. Realm is used on an Android application

I was able to download WolfSSL (5.3.0-stable) and build it using VS 2019 and IDE\VS-ARM\wolfssl.vcxproj, on a Windows 10 machine. I manually modified the vcxproj to add OPENSSL_EXTRA to PreprocessorDefinitions.  The build procedure completes successfully and the library libwolfssl.a is produced.

Now I am trying to compile realm-core (release 10.10.1) and replace OpenSSL libraries with the WolfSSL one. To simplify the build procedure (avoiding CMake and gradle), I used a script available from realm-core (tools\cross_compile.sh), selecting android as the target OS to build the module with OpenSSL, and logged the process steps. I then created a .bat file from the log, listing all the realm-core source files needed for the realm-core module and used the compatibility mode to select WolfSSL headers during compilation.

The toolchain used is Android\Sdk\ndk\23.1.7779620\toolchains\llvm\prebuilt\windows-x86_64; with clang++.exe (version 12.0.8) as compiler

In most cases, the following command and argument list is used when invoking the compiler:

%clangCompiler%\bin\clang++.exe --target=aarch64-none-linux-android21 -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE -I%realmIncludePath% -I%realmCompileSrc% -I%wolfSSLHeaders% -isystem realm-core\wolfssl\wolfssl-5.3.0-stable\wolfssl -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fexceptions -frtti -stdlib=libc++ -O3 -DWOLFSSL_SHA224 -DNDEBUG -fPIC -fvisibility=hidden -Wall -Wextra -Wempty-body -Wparentheses -Wunknown-pragmas -Wunreachable-code -Wunused-parameter -Wno-missing-field-initializers -Wno-uninitialized -Wpartial-availability -Wno-redundant-move -fdiagnostics-color -fdata-sections -ffunction-sections -fomit-frame-pointer -fsigned-char -fstrict-aliasing -funwind-tables -no-canonical-prefixes -Oz -std=c++17 -MD


where
realmIncludePath = PathToFolder\realm-core\src
realmCompileSrc= PathToFolder\realm-core\build-android-arm64-v8a-Release\src
wolfSSLHeaders= PathToFolder\realm-core\wolfssl\wolfssl-5.3.0-stable

For good measure, I added the #define statements for OPENSSL_EXTRA and OPENSSL_ALL in the header file PathToFolder\realm-core\wolfssl\wolfssl-5.3.0-stable\wolfssl\wolfcrypt\settings.h

This is working for all but a few .cpp files. The following errors are reported:

PathToFolder\realm-core\wolfssl\wolfssl-5.3.0-stable\wolfssl/wolfcrypt/settings.h:2375:14: warning: "For timing resistance / side-channel attack prevention consider using harden options" [-W#warnings]
            #warning "For timing resistance / side-channel attack prevention consider using harden options"

PathToFolder\realm-core/src/realm/util/encrypted_file_mapping.cpp:416:5: error: use of undeclared identifier 'SHA224_Init'
    SHA224_Init(&ctx);

PathToFolder\realm-core/src/realm/util/encrypted_file_mapping.cpp:423:30: error: use of undeclared identifier 'SHA224_DIGEST_LENGTH'
    SHA256_Update(&ctx, dst, SHA224_DIGEST_LENGTH);

To address the errors above, I added the argument -DWOLFSSL_SHA224 to the compiler command. Compiling the code resulted in the following:

PathToFolder\realm-core/src/realm/util/encrypted_file_mapping.cpp:416:5: error: no matching function for call to
      'wolfSSL_SHA224_Init'
    SHA224_Init(&ctx);
    ^~~~~~~~~~~

PathToFolder\realm-core\wolfssl\wolfssl-5.3.0-stable\wolfssl/openssl/sha.h:106:17: note: candidate function not viable: no
      known conversion from 'SHA256_CTX *' (aka 'WOLFSSL_SHA256_CTX *') to 'WOLFSSL_SHA224_CTX *' for 1st argument
WOLFSSL_API int wolfSSL_SHA224_Init(WOLFSSL_SHA224_CTX* sha);
                ^
PathToFolder\realm-core/src/realm/util/encrypted_file_mapping.cpp:421:5: error: no matching function for call to
      'wolfSSL_SHA224_Init'
    SHA224_Init(&ctx);

PathToFolder\realm-core\wolfssl\wolfssl-5.3.0-stable\wolfssl/openssl/sha.h:117:23: note: expanded from macro 'SHA224_Init'
#define SHA224_Init   wolfSSL_SHA224_Init

A second file fails to compile with the following error:

PathToFolder\realm-core/src/realm/util/network_ssl.cpp:419:13: error: use of undeclared identifier 'BIO_TYPE_SOCKET'
            BIO_TYPE_SOCKET,      // int type

A quick search reveal the BIO_TYPE_SOCKET is declared in OpenSSL\bio.h but absent in wolfssl\openssl\bio.h

What am I missing to successfully complete building this module? Am I right to assume that the definition of BIO_TYPE_SOCKET is missing from the WolfSSL compatibility layer?

What about the errors related to SHA224_Init definition?

Any suggestions on how I could approach these issues?

Best Regards

Share

Re: WolfSSL compatibility layer and Realm database

Hi labonte_d,

These errors indicate you did not include wolfssl/options.h before any of the wolfSSL headers. When you run ./configure --enable-opensslextra is generated a file containing the build options used in wolfssl/options.h. It is important your application also includes this before any other wolfSSL headers to enable the same build options in the header.

We do support the compatibility functions mentioned above. Make sure you setup the include path for the wolfssl-root and also wolfssl-root/wolfssl. Then make sure you have wolfssl/option.sh included and then openssl/sha.h, openssl/bio.h, etc...

Let me know if that does not help.

Thanks,
David Garske, wolfSSL

Share

Re: WolfSSL compatibility layer and Realm database

Hi labonte_d

Thanks for contacting wolfSSL Support. The compatibility layer of wolfSSL is intended to cover the most widely used OpenSSL API, but there are some gaps. I can open open a feature request for implementing the BIO_TYPE_SOCKET type if you'd like. I'd suggest adding the type define and seeing if there are further issues.

For the SHA224_Init issues, I do see that SHA224_Init is defined to wolfSSL_SHA224_Init in wolfssl/wolfssl/openssl/sha.h

Does realm-core/src/realm/util/encrypted_file_mapping.cpp include options.h before any other wolfSSL headers?

Thanks,
Eric @ wolfSSL Support

Re: WolfSSL compatibility layer and Realm database

Hi,

Thank you for your suggestions. I am running the build from a Windows machine and do not have ./configure or autoconf available. I originally built wolfSSL using the IDE\VS-ARM\wolfssl.vcxproj.

I did add the following defines in wolfssl\wolfcrypt\settings.h

/* Uncomment next line if building for Dolphin Emulator */
/* #define DOLPHIN_EMULATOR */

// DL: Substituting encryption layer with wolfSSL from OpenSSL
#undef  OPENSSL_EXTRA
#define OPENSSL_EXTRA
#undef  OPENSSL_ALL
#define OPENSSL_ALL

I did so after reading the following comment in wolfssl\wolfcrypt\settings.h. The suggestions related to options.h left me puzzled.

/* This flag allows wolfSSL to include options.h instead of having client
 * projects do it themselves. This should *NEVER* be defined when building
 * wolfSSL as it can cause hard to debug problems. */
#ifdef EXTERNAL_OPTS_OPENVPN
#include <wolfssl/options.h>
#endif

I also verified that the header wolfssl\wolfcrypt\settings.h is also included in wolfssl\openssl\sha.h as shown here:

/* sha.h for openssl */


#ifndef WOLFSSL_SHA_H_
#define WOLFSSL_SHA_H_

#include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/wolfcrypt/types.h>

Therefore, the compile errors  related to SHA225_Init(&cx)/wolfSSL_SHA224_Init are still reported.

As suggested, I added the BIO_TYPE_SOCKET definition in wolfssl\openssl\bio.h header file as:

// Copied from openssl\bio.h (original)
/* There are the classes of BIOs */
//# define BIO_TYPE_DESCRIPTOR     0x0100 /* socket, fd, connect or accept */
//# define BIO_TYPE_FILTER         0x0200
//# define BIO_TYPE_SOURCE_SINK    0x0400

/* These are the 'types' of BIOs */
//# define BIO_TYPE_NONE             0
//# define BIO_TYPE_MEM            ( 1|BIO_TYPE_SOURCE_SINK)
//# define BIO_TYPE_FILE           ( 2|BIO_TYPE_SOURCE_SINK)

//# define BIO_TYPE_FD             ( 4|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR)
//# define BIO_TYPE_SOCKET         ( 5|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR)
//# define BIO_TYPE_NULL           ( 6|BIO_TYPE_SOURCE_SINK)

// DL Redefining for WolfSSL; 
# define BIO_TYPE_NONE             WOLFSSL_BIO_UNDEF
# define BIO_TYPE_SOCKET           WOLFSSL_BIO_SOCKET

This addition addressed the undeclared identifier error initially reported. However, casting errors as shown here are now reported. I will be modifying the source code to address these.

PathToFolder/realm-core/src/realm/util/network_ssl.cpp:420:13: error: cannot initialize an array element of type 'char' with an rvalue of type 'nullptr_t'
            nullptr,              // const char* name
            ^~~~~~~

PathToFolder/realm-core/src/realm/util/network_ssl.cpp:421:13: error: cannot initialize an array element of type 'char' with an rvalue of type 'int (*)(BIO *, const char *, int) noexcept' (aka 'int (*)(WOLFSSL_BIO *, const char *, int) noexcept')
            &Stream::bio_write,   // int (*bwrite)(BIO*, const char*, int)
            ^~~~~~~~~~~~~~~~~~

PathToFolder/realm-core/src/realm/util/network_ssl.cpp:422:13: error: cannot initialize an array element of type 'char' with an rvalue of type 'int (*)(BIO *, char *, int) noexcept' (aka 'int (*)(WOLFSSL_BIO *, char *, int) noexcept')
            &Stream::bio_read,    // int (*bread)(BIO*, char*, int)
            ^~~~~~~~~~~~~~~~~

PathToFolder/realm-core/src/realm/util/network_ssl.cpp:423:13: error: cannot initialize an array element of type 'char' with an rvalue of type 'int (*)(BIO *, const char *) noexcept' (aka 'int (*)(WOLFSSL_BIO *, const char *) noexcept')
            &Stream::bio_puts,    // int (*bputs)(BIO*, const char*)
            ^~~~~~~~~~~~~~~~~

PathToFolder/realm-core/src/realm/util/network_ssl.cpp:424:13: error: cannot initialize an array element of type 'char' with an rvalue of type 'nullptr_t'
            nullptr,              // int (*bgets)(BIO*, char*, int)
            ^~~~~~~

PathToFolder/realm-core/src/realm/util/network_ssl.cpp:425:13: error: cannot initialize an array element of type 'char' with an rvalue of type 'long (*)(BIO *, int, long, void *) noexcept' (aka 'long (*)(WOLFSSL_BIO *, int, long, void *) noexcept')
            &Stream::bio_ctrl,    // long (*ctrl)(BIO*, int, long, void*)
            ^~~~~~~~~~~~~~~~~

Best regards,
Daniel

Share

Re: WolfSSL compatibility layer and Realm database

Hi labonte_d,

The Windows build uses the user_settings.h from IDE\VS-ARM. You must define WOLFSSL_USER_SETTINGS in your application "Realm" and make sure the same user_settings.h is in your include path. The changes directly to settings.h should not be made. Instead add them to your customized user_settings.h based on the one in IDE\VS-ARM. In your application code make sure wolfssl/wolfcrypt/settings.h is included before any other wolfssl or compatibility headers. The settings.h includes user_settings.h when WOLFSSL_USER_SETTINGS is defined.

Thanks,
David Garske, wolfSSL

Share