diff --git a/.travis.yml b/.travis.yml index 427efb37d..1d8010570 100644 --- a/.travis.yml +++ b/.travis.yml @@ -95,6 +95,7 @@ matrix: env: - CC_OVERRIDE=clang - AES_NI=0 + - WITH_OPENSSL=0 before_install: - brew update - brew install doxygen graphviz diff --git a/config/external-libraries.m4 b/config/external-libraries.m4 index bef37fab7..6f3f72b83 100644 --- a/config/external-libraries.m4 +++ b/config/external-libraries.m4 @@ -9,13 +9,19 @@ AC_DEFUN([ADD_EXTERNAL_LIB],[ [disable OpenSSL; use --with-openssl=dir to specify OpenSSL dir (default /usr or /usr/local/opt/openssl on macOS)] )], [with_openssl=$withval], - [with_openssl=default] + [with_openssl=yes] ) # platform-specific default directory AS_IF( - [test "x${with_openssl}" = "xdefault"], + [test "x${with_openssl}" = "xyes"], [AM_COND_IF(ON_DARWIN, - [with_openssl=/usr/local/opt/openssl], + [ + AS_IF( + [test -d "/usr/local/opt/openssl@1.1"], + [with_openssl=/usr/local/opt/openssl@1.1], + [with_openssl=/usr/local/opt/openssl] + ) + ], [with_openssl=/usr] )] ) @@ -46,4 +52,56 @@ AC_DEFUN([ADD_EXTERNAL_LIB],[ ], [AC_SUBST(M4RI_DIR, /usr)] ) + + # define the --with-sha3 option + AC_ARG_WITH([sha3], + [AS_HELP_STRING( + [--with-sha3=arg], + [SHA3 implementation to use: openssl (default if available), c] + )], + [], + [with_sha3=default] + ) + # if supposed to use the default option + AS_IF( + [test "x${with_sha3}" = "xdefault"], + # if OpenSSL is available + [AM_COND_IF(USE_OPENSSL, + [ + # check whether we have EVP_sha3_256 + # note we need to save then restore CFLAGS/LDFLAGS + old_CFLAGS=${CFLAGS} + old_LDFLAGS=${LDFLAGS} + CFLAGS="${CFLAGS} -I${with_openssl}/include" + LDFLAGS="${LDFLAGS} -L${with_openssl}/lib" + AC_LANG_PUSH([C]) + AC_CHECK_LIB([crypto], [EVP_sha3_256], + [with_sha3=openssl], + [with_sha3=c] + ) + AC_LANG_POP([C]) + CFLAGS=${CFLAGS} + LDFLAGS=${LDFLAGS} + ], + # use C + [with_sha3=c] + )] + ) + # report result + AC_MSG_CHECKING([which SHA-3 implementation to use]) + # check for invalid arguments + AS_IF( + [test "x${with_sha3}" != "xopenssl" -a "x${with_sha3}" != "xc"], + AC_MSG_FAILURE([invalid --with-sha3 option]) + ) + AC_MSG_RESULT([${with_sha3}]) + # set automake variables and C defines + AM_CONDITIONAL(USE_SHA3_OPENSSL, [test "x${with_sha3}" = "xopenssl"]) + AM_CONDITIONAL(USE_SHA3_C, [test "x${with_sha3}" = "xc"]) + AM_COND_IF(USE_SHA3_OPENSSL,[ + AC_DEFINE(USE_SHA3_OPENSSL, [1], [Defined to 1 if liboqs should use OpenSSL for SHA-3 where possible]) + ]) + AM_COND_IF(USE_SHA3_C,[ + AC_DEFINE(USE_SHA3_C, [1], [Define to 1 if liboqs should use built-in C code for SHA-3]) + ]) ]) diff --git a/src/crypto/sha3/Makefile.am b/src/crypto/sha3/Makefile.am index 093cc5999..08eb7737c 100644 --- a/src/crypto/sha3/Makefile.am +++ b/src/crypto/sha3/Makefile.am @@ -2,5 +2,8 @@ AUTOMAKE_OPTIONS = foreign noinst_LTLIBRARIES = libsha3.la libsha3_la_SOURCES = sha3_c.c +if USE_SHA3_OPENSSL +libsha3_la_SOURCES += sha3_ossl.c +endif sha3_c.c: fips202.c sp800-185.c diff --git a/src/crypto/sha3/sha3_c.c b/src/crypto/sha3/sha3_c.c index e9938e215..7a20b647b 100644 --- a/src/crypto/sha3/sha3_c.c +++ b/src/crypto/sha3/sha3_c.c @@ -4,10 +4,16 @@ * from PQClean (https://github.com/PQClean/PQClean/tree/master/common) */ +#include + #include "sha3.h" #define SHA3_256_RATE OQS_SHA3_SHA3_256_RATE +#ifndef USE_SHA3_OPENSSL #define sha3_256 OQS_SHA3_sha3_256 +#else +#define sha3_256 oqs_unused_SHA3_sha3_256 +#endif #define sha3_256incctx OQS_SHA3_sha3_256_inc_ctx #define sha3_256_inc_init OQS_SHA3_sha3_256_inc_init diff --git a/src/crypto/sha3/sha3_ossl.c b/src/crypto/sha3/sha3_ossl.c new file mode 100644 index 000000000..27b3ff4a4 --- /dev/null +++ b/src/crypto/sha3/sha3_ossl.c @@ -0,0 +1,30 @@ +/** + * \file sha3_ossl.c + * \brief Implementation of the OQS SHA3 API via calls to OpenSSL's SHA-3 functions + */ + +#include + +#ifdef USE_SHA3_OPENSSL + +#include "sha3.h" + +#include + +static void inline do_hash(uint8_t *output, const uint8_t *input, size_t inplen, const EVP_MD *md) { + EVP_MD_CTX *mdctx; + unsigned int outlen; + mdctx = EVP_MD_CTX_create(); + EVP_DigestInit_ex(mdctx, md, NULL); + EVP_DigestUpdate(mdctx, input, inplen); + EVP_DigestFinal_ex(mdctx, output, &outlen); + EVP_MD_CTX_destroy(mdctx); +} + +void OQS_SHA3_sha3_256(uint8_t *output, const uint8_t *input, size_t inplen) { + const EVP_MD *md; + md = EVP_sha3_256(); + do_hash(output, input, inplen, md); +} + +#endif