From 32afec8fccd77a264e6104764986ce46d120f5ff Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Fri, 5 Apr 2024 23:20:17 +0900 Subject: [PATCH] Add option to dynamically load libcrypto.so.* (#1603) * sha2: Use EVP_MD_CTX_free instead of EVP_MD_CTX_destroy According to the manual page, EVP_MD_CTX_destroy has been renamed to EVP_MD_CTX_free in OpenSSL 1.1.0 and only provided as a compatibility macro in later OpenSSL releases: https://www.openssl.org/docs/man1.1.1/man3/EVP_MD_CTX_free.html Signed-off-by: Daiki Ueno * ossl_helpers: Use pthread_once instead of CRYPTO_THREAD_run_once Throughout the code base, liboqs uses pthread_once for one-shot initialization and falls back to thread-unsafe code if it is not supported nor enabled on the system. For consistency and to remove additional dependency on OpenSSL, this switches the use of CRYPTO_THREAD_run_once with that. Signed-off-by: Daiki Ueno * Make common algorithms pluggable This allows applications to replace the implementation of common cryptographic algorithms at runtime, by setting callback functions for each operations with OQS_AES_set_callbacks, OQS_SHA2_set_callbacks, OQS_SHA3_set_callbacks, and OQS_SHA3_x4_callbacks. Those functions may be called once before OQS_init; otherwise the default implementation will be used. Signed-off-by: Daiki Ueno * Add option to dynamically load libcrypto.so.* This adds OQS_DLOPEN_OPENSSL build option to use OpenSSL through dynamically loaded libcrypto.so.* with dlopen, instead of linking to the library at build time. That way the applications could use their favorite implementation of common cryptographic primitives without pulling in the OpenSSL as a hard dependency. Signed-off-by: Daiki Ueno * Add tests for OQS_*_set_callbacks This adds tests that exercise OQS_*_set_callbacks by overriding one of the function of each and ensuring the wrapper function is called. Signed-off-by: Daiki Ueno --------- Signed-off-by: Daiki Ueno --- .CMake/alg_support.cmake | 2 + .github/workflows/unix.yml | 4 + CMakeLists.txt | 14 ++ CONFIGURE.md | 10 +- src/CMakeLists.txt | 5 + src/common/CMakeLists.txt | 16 +- src/common/aes/aes.c | 117 +++---------- src/common/aes/aes.h | 82 +++++++++ src/common/aes/aes_impl.c | 160 ++++++++++++++++++ src/common/aes/aes_local.h | 2 + src/common/aes/aes_ossl.c | 79 +++++---- src/common/common.c | 6 +- src/common/ossl_functions.h | 51 ++++++ src/common/ossl_helpers.c | 304 +++++++++++++++++++++++++--------- src/common/ossl_helpers.h | 24 ++- src/common/rand/rand.c | 8 +- src/common/rand/rand_nist.c | 13 +- src/common/sha2/sha2.c | 90 +++------- src/common/sha2/sha2.h | 113 ++++++++++++- src/common/sha2/sha2_impl.c | 123 ++++++++++++++ src/common/sha2/sha2_local.h | 2 + src/common/sha2/sha2_ossl.c | 127 ++++++++------ src/common/sha3/ossl_sha3.c | 237 +++++++++++++++----------- src/common/sha3/ossl_sha3x4.c | 245 ++++++++++++++------------- src/common/sha3/sha3.c | 161 ++++++++++++++++++ src/common/sha3/sha3.h | 201 ++++++++++++++++++++++ src/common/sha3/sha3x4.c | 77 +++++++++ src/common/sha3/sha3x4.h | 145 ++++++++++++++++ src/common/sha3/xkcp_sha3.c | 116 ++++++++----- src/common/sha3/xkcp_sha3x4.c | 53 ++++-- src/oqsconfig.h.cmake | 2 + tests/test_aes.c | 19 +++ tests/test_hash.c | 44 +++-- tests/test_sha3.c | 38 +++++ 34 files changed, 2060 insertions(+), 630 deletions(-) create mode 100644 src/common/aes/aes_impl.c create mode 100644 src/common/ossl_functions.h create mode 100644 src/common/sha2/sha2_impl.c create mode 100644 src/common/sha3/sha3.c create mode 100644 src/common/sha3/sha3x4.c diff --git a/.CMake/alg_support.cmake b/.CMake/alg_support.cmake index 66449097..3bdb103a 100644 --- a/.CMake/alg_support.cmake +++ b/.CMake/alg_support.cmake @@ -69,6 +69,8 @@ cmake_dependent_option(OQS_USE_SHA3_OPENSSL "" OFF "OQS_USE_OPENSSL" OFF) # sanity check: Disable OpenSSL if not a single OpenSSL component define is on cmake_dependent_option(OQS_USE_OPENSSL "" ON "OQS_USE_AES_OPENSSL OR OQS_USE_SHA2_OPENSSL OR OQS_USE_SHA3_OPENSSL" OFF) +option(OQS_DLOPEN_OPENSSL "Enable OpenSSL through dlopen" OFF) + if(CMAKE_SYSTEM_NAME MATCHES "Linux|Darwin") if(OQS_DIST_X86_64_BUILD OR OQS_USE_AVX2_INSTRUCTIONS) cmake_dependent_option(OQS_ENABLE_SHA3_xkcp_low_avx2 "" ON "NOT OQS_USE_SHA3_OPENSSL" OFF) diff --git a/.github/workflows/unix.yml b/.github/workflows/unix.yml index b4effa7a..b3dd56b7 100644 --- a/.github/workflows/unix.yml +++ b/.github/workflows/unix.yml @@ -92,6 +92,10 @@ jobs: container: openquantumsafe/ci-ubuntu-jammy:latest CMAKE_ARGS: -DOQS_STRICT_WARNINGS=ON -DOQS_ALGS_ENABLED=STD -DBUILD_SHARED_LIBS=ON PYTEST_ARGS: --ignore=tests/test_leaks.py --ignore=tests/test_kat_all.py + - name: jammy-std-openssl3-dlopen + container: openquantumsafe/ci-ubuntu-jammy:latest + CMAKE_ARGS: -DOQS_STRICT_WARNINGS=ON -DOQS_ALGS_ENABLED=STD -DBUILD_SHARED_LIBS=ON -DOQS_DLOPEN_OPENSSL=ON + PYTEST_ARGS: --ignore=tests/test_leaks.py --ignore=tests/test_kat_all.py - name: address-sanitizer container: openquantumsafe/ci-ubuntu-focal-x86_64:latest CMAKE_ARGS: -DCMAKE_C_COMPILER=clang-9 -DCMAKE_BUILD_TYPE=Debug -DUSE_SANITIZER=Address diff --git a/CMakeLists.txt b/CMakeLists.txt index 60cdfc66..77da3023 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -133,6 +133,20 @@ if(${OQS_USE_OPENSSL}) endif() endif() find_package(OpenSSL 1.1.1 REQUIRED) + + if(OQS_DLOPEN_OPENSSL) + find_program(OBJDUMP objdump) + if(NOT OBJDUMP) + message(FATAL_ERROR "objdump not found. Please install it from binutils.") + endif() + execute_process( + COMMAND ${OBJDUMP} -p ${OPENSSL_CRYPTO_LIBRARY} + COMMAND sed -n "s/[ ]\\{1,\\}SONAME[ ]\\{1,\\}//p" + OUTPUT_VARIABLE OQS_OPENSSL_CRYPTO_SONAME + OUTPUT_STRIP_TRAILING_WHITESPACE + COMMAND_ERROR_IS_FATAL ANY) + message(STATUS "OpenSSL dlopen SONAME: " ${OQS_OPENSSL_CRYPTO_SONAME}) + endif() endif() set(PUBLIC_HEADERS ${PROJECT_SOURCE_DIR}/src/oqs.h diff --git a/CONFIGURE.md b/CONFIGURE.md index 397aa2cd..8adcbb2d 100644 --- a/CONFIGURE.md +++ b/CONFIGURE.md @@ -96,7 +96,7 @@ These can be set to `ON` or `OFF` and take an effect if liboqs is built for use ## OQS_USE_OPENSSL -In order to save size and limit the mount of different cryptographic code bases, it is possible to use OpenSSL as a crypto code provider by setting this configuration option. +In order to save size and limit the amount of different cryptographic code bases, it is possible to use OpenSSL as a crypto code provider by setting this configuration option. This can be set to `ON` or `OFF`. When `ON`, the additional options `OQS_USE_AES_OPENSSL`, `OQS_USE_SHA2_OPENSSL`, and `OQS_USE_SHA3_OPENSSL` are made available to control whether liboqs uses OpenSSL's AES, SHA-2, and SHA-3 implementations. @@ -111,6 +111,14 @@ When `OQS_USE_OPENSSL` is `ON`, CMake also scans the filesystem to find the mini **Default**: `ON`. +### OQS_DLOPEN_OPENSSL + +Dynamically load OpenSSL through `dlopen`. When using liboqs from other cryptographic libraries, hard dependency on OpenSSL is sometimes undesirable. If this option is `ON`, loading of OpenSSL will be deferred until any of the OpenSSL functions is used. + +Only has an effect if the system supports `dlopen` and ELF binary format, such as Linux or BSD family. + +**Default**: `OFF`. + ## OQS_OPT_TARGET An optimization target. Only has an effect if the compiler is GCC or Clang and `OQS_DIST_BUILD=OFF`. Can take any valid input to the `-march` (on x86-64) or `-mcpu` (on ARM32v7 or ARM64v8) option for `CMAKE_C_COMPILER`. Can also be set to one of the following special values. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 51e887fe..d0dfb6f0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -70,8 +70,13 @@ if(DEFINED SANITIZER_LD_FLAGS) target_link_libraries(oqs-internal PUBLIC ${SANITIZER_LD_FLAGS}) endif() if(${OQS_USE_OPENSSL}) + if(${OQS_DLOPEN_OPENSSL}) + target_link_libraries(oqs PRIVATE ${CMAKE_DL_LIBS}) + target_link_libraries(oqs-internal PRIVATE ${CMAKE_DL_LIBS}) + else() target_link_libraries(oqs PRIVATE ${OPENSSL_CRYPTO_LIBRARY}) target_link_libraries(oqs-internal PRIVATE ${OPENSSL_CRYPTO_LIBRARY}) + endif() endif() target_include_directories(oqs diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 79172404..73b917e0 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -22,7 +22,7 @@ if(${OQS_USE_AES_OPENSSL}) set(AES_IMPL aes/aes_ossl.c) set(OSSL_HELPERS ossl_helpers.c) else() - set(AES_IMPL aes/aes.c aes/aes_c.c) + set(AES_IMPL aes/aes_impl.c aes/aes_c.c) if (OQS_DIST_X86_64_BUILD OR OQS_USE_AES_INSTRUCTIONS) set(AES_IMPL ${AES_IMPL} aes/aes128_ni.c) set(AES_IMPL ${AES_IMPL} aes/aes256_ni.c) @@ -47,7 +47,7 @@ if(${OQS_USE_SHA2_OPENSSL}) set(SHA2_IMPL sha2/sha2_ossl.c) set(OSSL_HELPERS ossl_helpers.c) else() - set(SHA2_IMPL sha2/sha2.c sha2/sha2_c.c) + set(SHA2_IMPL sha2/sha2_impl.c sha2/sha2_c.c) if (OQS_DIST_ARM64_V8_BUILD) set(SHA2_IMPL ${SHA2_IMPL} sha2/sha2_armv8.c) set_source_files_properties(sha2/sha2_armv8.c PROPERTIES COMPILE_FLAGS -mcpu=cortex-a53+crypto) @@ -71,9 +71,9 @@ else() # using XKCP set(SHA3_IMPL sha3/xkcp_sha3.c sha3/xkcp_sha3x4.c) endif() -add_library(common OBJECT ${AES_IMPL} - ${SHA2_IMPL} - ${SHA3_IMPL} +add_library(common OBJECT ${AES_IMPL} aes/aes.c + ${SHA2_IMPL} sha2/sha2.c + ${SHA3_IMPL} sha3/sha3.c sha3/sha3x4.c ${OSSL_HELPERS} common.c pqclean_shims/fips202.c @@ -81,9 +81,9 @@ add_library(common OBJECT ${AES_IMPL} rand/rand.c) # Implementations of the internal API to be exposed to test programs -add_library(internal OBJECT ${AES_IMPL} - ${SHA2_IMPL} - ${SHA3_IMPL} +add_library(internal OBJECT ${AES_IMPL} aes/aes.c + ${SHA2_IMPL} sha2/sha2.c + ${SHA3_IMPL} sha3/sha3.c sha3/sha3x4.c ${OSSL_HELPERS} common.c rand/rand_nist.c) diff --git a/src/common/aes/aes.c b/src/common/aes/aes.c index 1fef083a..3ac87949 100644 --- a/src/common/aes/aes.c +++ b/src/common/aes/aes.c @@ -9,129 +9,60 @@ #include "aes.h" #include "aes_local.h" -#if defined(OQS_DIST_X86_64_BUILD) -#define C_OR_NI_OR_ARM(stmt_c, stmt_ni, stmt_arm) \ - do { \ - if (OQS_CPU_has_extension(OQS_CPU_EXT_AES)) { \ - stmt_ni; \ - } else { \ - stmt_c; \ - } \ - } while(0) -#elif defined(OQS_DIST_ARM64_V8_BUILD) -#define C_OR_NI_OR_ARM(stmt_c, stmt_ni, stmt_arm) \ - do { \ - if (OQS_CPU_has_extension(OQS_CPU_EXT_ARM_AES)) { \ - stmt_arm; \ - } else { \ - stmt_c; \ - } \ - } while(0) -#elif defined(OQS_USE_AES_INSTRUCTIONS) -#define C_OR_NI_OR_ARM(stmt_c, stmt_ni, stmt_arm) \ - stmt_ni -#elif defined(OQS_USE_ARM_AES_INSTRUCTIONS) -#define C_OR_NI_OR_ARM(stmt_c, stmt_ni, stmt_arm) \ - stmt_arm -#else -#define C_OR_NI_OR_ARM(stmt_c, stmt_ni, stmt_arm) \ - stmt_c -#endif - -void OQS_AES128_ECB_load_schedule(const uint8_t *key, void **_schedule) { - C_OR_NI_OR_ARM( - oqs_aes128_load_schedule_c(key, _schedule), - oqs_aes128_load_schedule_ni(key, _schedule), - oqs_aes128_load_schedule_no_bitslice(key, _schedule) - ); +static struct OQS_AES_callbacks *callbacks = &aes_default_callbacks; + +OQS_API void OQS_AES_set_callbacks(struct OQS_AES_callbacks *new_callbacks) { + callbacks = new_callbacks; +} + +void OQS_AES128_ECB_load_schedule(const uint8_t *key, void **schedule) { + callbacks->AES128_ECB_load_schedule(key, schedule); } void OQS_AES128_free_schedule(void *schedule) { - C_OR_NI_OR_ARM( - oqs_aes128_free_schedule_c(schedule), - oqs_aes128_free_schedule_ni(schedule), - oqs_aes128_free_schedule_no_bitslice(schedule) - ); + callbacks->AES128_free_schedule(schedule); } -void OQS_AES256_ECB_load_schedule(const uint8_t *key, void **_schedule) { - C_OR_NI_OR_ARM( - oqs_aes256_load_schedule_c(key, _schedule), - oqs_aes256_load_schedule_ni(key, _schedule), - oqs_aes256_load_schedule_no_bitslice(key, _schedule) - ); +void OQS_AES256_ECB_load_schedule(const uint8_t *key, void **schedule) { + callbacks->AES256_ECB_load_schedule(key, schedule); } -void OQS_AES256_CTR_inc_init(const uint8_t *key, void **_schedule) { - OQS_AES256_ECB_load_schedule(key, _schedule); +void OQS_AES256_CTR_inc_init(const uint8_t *key, void **schedule) { + callbacks->AES256_CTR_inc_init(key, schedule); } -void OQS_AES256_CTR_inc_iv(const uint8_t *iv, size_t iv_len, void *_schedule) { - C_OR_NI_OR_ARM( - oqs_aes256_load_iv_c(iv, iv_len, _schedule), - oqs_aes256_load_iv_ni(iv, iv_len, _schedule), - oqs_aes256_load_iv_armv8(iv, iv_len, _schedule) - ); +void OQS_AES256_CTR_inc_iv(const uint8_t *iv, size_t iv_len, void *schedule) { + callbacks->AES256_CTR_inc_iv(iv, iv_len, schedule); } -void OQS_AES256_CTR_inc_ivu64(uint64_t iv, void *_schedule) { - C_OR_NI_OR_ARM( - oqs_aes256_load_iv_u64_c(iv, _schedule), - oqs_aes256_load_iv_u64_ni(iv, _schedule), - (void) iv; (void) _schedule - ); +void OQS_AES256_CTR_inc_ivu64(uint64_t iv, void *schedule) { + callbacks->AES256_CTR_inc_ivu64(iv, schedule); } void OQS_AES256_free_schedule(void *schedule) { - C_OR_NI_OR_ARM( - oqs_aes256_free_schedule_c(schedule), - oqs_aes256_free_schedule_ni(schedule), - oqs_aes256_free_schedule_no_bitslice(schedule) - ); + callbacks->AES256_free_schedule(schedule); } void OQS_AES128_ECB_enc(const uint8_t *plaintext, const size_t plaintext_len, const uint8_t *key, uint8_t *ciphertext) { - void *schedule = NULL; - OQS_AES128_ECB_load_schedule(key, &schedule); - OQS_AES128_ECB_enc_sch(plaintext, plaintext_len, schedule, ciphertext); - OQS_AES128_free_schedule(schedule); + callbacks->AES128_ECB_enc(plaintext, plaintext_len, key, ciphertext); } void OQS_AES128_ECB_enc_sch(const uint8_t *plaintext, const size_t plaintext_len, const void *schedule, uint8_t *ciphertext) { - C_OR_NI_OR_ARM( - oqs_aes128_ecb_enc_sch_c(plaintext, plaintext_len, schedule, ciphertext), - oqs_aes128_ecb_enc_sch_ni(plaintext, plaintext_len, schedule, ciphertext), - oqs_aes128_ecb_enc_sch_armv8(plaintext, plaintext_len, schedule, ciphertext) - ); + callbacks->AES128_ECB_enc_sch(plaintext, plaintext_len, schedule, ciphertext); } void OQS_AES256_ECB_enc(const uint8_t *plaintext, const size_t plaintext_len, const uint8_t *key, uint8_t *ciphertext) { - void *schedule = NULL; - OQS_AES256_ECB_load_schedule(key, &schedule); - OQS_AES256_ECB_enc_sch(plaintext, plaintext_len, schedule, ciphertext); - OQS_AES256_free_schedule(schedule); + callbacks->AES256_ECB_enc(plaintext, plaintext_len, key, ciphertext); } void OQS_AES256_ECB_enc_sch(const uint8_t *plaintext, const size_t plaintext_len, const void *schedule, uint8_t *ciphertext) { - C_OR_NI_OR_ARM( - oqs_aes256_ecb_enc_sch_c(plaintext, plaintext_len, schedule, ciphertext), - oqs_aes256_ecb_enc_sch_ni(plaintext, plaintext_len, schedule, ciphertext), - oqs_aes256_ecb_enc_sch_armv8(plaintext, plaintext_len, schedule, ciphertext) - ); + callbacks->AES256_ECB_enc_sch(plaintext, plaintext_len, schedule, ciphertext); } void OQS_AES256_CTR_inc_stream_iv(const uint8_t *iv, const size_t iv_len, const void *schedule, uint8_t *out, size_t out_len) { - C_OR_NI_OR_ARM( - oqs_aes256_ctr_enc_sch_c(iv, iv_len, schedule, out, out_len), - oqs_aes256_ctr_enc_sch_ni(iv, iv_len, schedule, out, out_len), - oqs_aes256_ctr_enc_sch_armv8(iv, iv_len, schedule, out, out_len) - ); + callbacks->AES256_CTR_inc_stream_iv(iv, iv_len, schedule, out, out_len); } void OQS_AES256_CTR_inc_stream_blks(void *schedule, uint8_t *out, size_t out_blks) { - C_OR_NI_OR_ARM( - oqs_aes256_ctr_enc_sch_upd_blks_c(schedule, out, out_blks), - oqs_aes256_ctr_enc_sch_upd_blks_ni(schedule, out, out_blks), - oqs_aes256_ctr_enc_sch_upd_blks_armv8(schedule, out, out_blks) - ); + callbacks->AES256_CTR_inc_stream_blks(schedule, out, out_blks); } diff --git a/src/common/aes/aes.h b/src/common/aes/aes.h index 83649dbe..0194b907 100644 --- a/src/common/aes/aes.h +++ b/src/common/aes/aes.h @@ -14,6 +14,8 @@ #include #include +#include + #if defined(__cplusplus) extern "C" { #endif @@ -147,6 +149,86 @@ void OQS_AES256_CTR_inc_stream_iv(const uint8_t *iv, size_t iv_len, const void * */ void OQS_AES256_CTR_inc_stream_blks(void *ctx, uint8_t *out, size_t out_blks); +/** Data structure implemented by cryptographic provider for AES operations. + */ +struct OQS_AES_callbacks { + /** + * Implementation of function OQS_AES128_ECB_load_schedule. + */ + void (*AES128_ECB_load_schedule)(const uint8_t *key, void **ctx); + + /** + * Implementation of function OQS_AES128_free_schedule. + */ + void (*AES128_free_schedule)(void *ctx); + + /** + * Implementation of function OQS_AES128_ECB_enc. + */ + void (*AES128_ECB_enc)(const uint8_t *plaintext, const size_t plaintext_len, const uint8_t *key, uint8_t *ciphertext); + + /** + * Implementation of function OQS_AES128_ECB_enc_sch. + */ + void (*AES128_ECB_enc_sch)(const uint8_t *plaintext, const size_t plaintext_len, const void *schedule, uint8_t *ciphertext); + + /** + * Implementation of function OQS_AES256_ECB_load_schedule. + */ + void (*AES256_ECB_load_schedule)(const uint8_t *key, void **ctx); + + /** + * Implementation of function OQS_AES256_CTR_inc_init. + */ + void (*AES256_CTR_inc_init)(const uint8_t *key, void **ctx); + + /** + * Implementation of function OQS_AES256_CTR_inc_iv. + */ + void (*AES256_CTR_inc_iv)(const uint8_t *iv, size_t iv_len, void *ctx); + + /** + * Implementation of function OQS_AES256_CTR_inc_ivu64. + */ + void (*AES256_CTR_inc_ivu64)(uint64_t iv, void *ctx); + + /** + * Implementation of function OQS_AES256_free_schedule. + */ + void (*AES256_free_schedule)(void *ctx); + + /** + * Implementation of function OQS_AES256_ECB_enc. + */ + void (*AES256_ECB_enc)(const uint8_t *plaintext, const size_t plaintext_len, const uint8_t *key, uint8_t *ciphertext); + + /** + * Implementation of function OQS_AES256_ECB_enc_sch. + */ + void (*AES256_ECB_enc_sch)(const uint8_t *plaintext, const size_t plaintext_len, const void *schedule, uint8_t *ciphertext); + + /** + * Implementation of function OQS_AES256_CTR_inc_stream_iv. + */ + void (*AES256_CTR_inc_stream_iv)(const uint8_t *iv, size_t iv_len, const void *ctx, uint8_t *out, size_t out_len); + + /** + * Implementation of function OQS_AES256_CTR_inc_stream_blks. + */ + void (*AES256_CTR_inc_stream_blks)(void *ctx, uint8_t *out, size_t out_blks); +}; + +/** + * Set callback functions for AES operations. + * + * This function may be called before OQS_init to switch the + * cryptographic provider for AES operations. If it is not called, the + * default provider determined at build time will be used. + * + * @param[in] new_callbacks Callback functions defined in OQS_AES_callbacks + */ +OQS_API void OQS_AES_set_callbacks(struct OQS_AES_callbacks *new_callbacks); + #if defined(__cplusplus) } // extern "C" #endif diff --git a/src/common/aes/aes_impl.c b/src/common/aes/aes_impl.c new file mode 100644 index 00000000..ae9be662 --- /dev/null +++ b/src/common/aes/aes_impl.c @@ -0,0 +1,160 @@ +// SPDX-License-Identifier: MIT + +#include +#include +#include + +#include + +#include "aes.h" +#include "aes_local.h" + +#if defined(OQS_DIST_X86_64_BUILD) +#define C_OR_NI_OR_ARM(stmt_c, stmt_ni, stmt_arm) \ + do { \ + if (OQS_CPU_has_extension(OQS_CPU_EXT_AES)) { \ + stmt_ni; \ + } else { \ + stmt_c; \ + } \ + } while(0) +#elif defined(OQS_DIST_ARM64_V8_BUILD) +#define C_OR_NI_OR_ARM(stmt_c, stmt_ni, stmt_arm) \ + do { \ + if (OQS_CPU_has_extension(OQS_CPU_EXT_ARM_AES)) { \ + stmt_arm; \ + } else { \ + stmt_c; \ + } \ + } while(0) +#elif defined(OQS_USE_AES_INSTRUCTIONS) +#define C_OR_NI_OR_ARM(stmt_c, stmt_ni, stmt_arm) \ + stmt_ni +#elif defined(OQS_USE_ARM_AES_INSTRUCTIONS) +#define C_OR_NI_OR_ARM(stmt_c, stmt_ni, stmt_arm) \ + stmt_arm +#else +#define C_OR_NI_OR_ARM(stmt_c, stmt_ni, stmt_arm) \ + stmt_c +#endif + +static void AES128_ECB_load_schedule(const uint8_t *key, void **_schedule) { + C_OR_NI_OR_ARM( + oqs_aes128_load_schedule_c(key, _schedule), + oqs_aes128_load_schedule_ni(key, _schedule), + oqs_aes128_load_schedule_no_bitslice(key, _schedule) + ); +} + +static void AES128_free_schedule(void *schedule) { + C_OR_NI_OR_ARM( + oqs_aes128_free_schedule_c(schedule), + oqs_aes128_free_schedule_ni(schedule), + oqs_aes128_free_schedule_no_bitslice(schedule) + ); +} + +static void AES256_ECB_load_schedule(const uint8_t *key, void **_schedule) { + C_OR_NI_OR_ARM( + oqs_aes256_load_schedule_c(key, _schedule), + oqs_aes256_load_schedule_ni(key, _schedule), + oqs_aes256_load_schedule_no_bitslice(key, _schedule) + ); +} + +static void AES256_CTR_inc_init(const uint8_t *key, void **_schedule) { + AES256_ECB_load_schedule(key, _schedule); +} + +static void AES256_CTR_inc_iv(const uint8_t *iv, size_t iv_len, void *_schedule) { + C_OR_NI_OR_ARM( + oqs_aes256_load_iv_c(iv, iv_len, _schedule), + oqs_aes256_load_iv_ni(iv, iv_len, _schedule), + oqs_aes256_load_iv_armv8(iv, iv_len, _schedule) + ); +} + +static void AES256_CTR_inc_ivu64(uint64_t iv, void *_schedule) { + C_OR_NI_OR_ARM( + oqs_aes256_load_iv_u64_c(iv, _schedule), + oqs_aes256_load_iv_u64_ni(iv, _schedule), + (void) iv; (void) _schedule + ); +} + +static void AES256_free_schedule(void *schedule) { + C_OR_NI_OR_ARM( + oqs_aes256_free_schedule_c(schedule), + oqs_aes256_free_schedule_ni(schedule), + oqs_aes256_free_schedule_no_bitslice(schedule) + ); +} + +static void AES128_ECB_enc_sch(const uint8_t *plaintext, const size_t plaintext_len, const void *schedule, uint8_t *ciphertext); + +static void AES128_ECB_enc(const uint8_t *plaintext, const size_t plaintext_len, const uint8_t *key, uint8_t *ciphertext) { + void *schedule = NULL; + AES128_ECB_load_schedule(key, &schedule); + AES128_ECB_enc_sch(plaintext, plaintext_len, schedule, ciphertext); + AES128_free_schedule(schedule); +} + +static void AES128_ECB_enc_sch(const uint8_t *plaintext, const size_t plaintext_len, const void *schedule, uint8_t *ciphertext) { + C_OR_NI_OR_ARM( + oqs_aes128_ecb_enc_sch_c(plaintext, plaintext_len, schedule, ciphertext), + oqs_aes128_ecb_enc_sch_ni(plaintext, plaintext_len, schedule, ciphertext), + oqs_aes128_ecb_enc_sch_armv8(plaintext, plaintext_len, schedule, ciphertext) + ); +} + +static void AES256_ECB_enc_sch(const uint8_t *plaintext, const size_t plaintext_len, const void *schedule, uint8_t *ciphertext); + +static void AES256_ECB_enc(const uint8_t *plaintext, const size_t plaintext_len, const uint8_t *key, uint8_t *ciphertext) { + void *schedule = NULL; + AES256_ECB_load_schedule(key, &schedule); + AES256_ECB_enc_sch(plaintext, plaintext_len, schedule, ciphertext); + AES256_free_schedule(schedule); +} + +static void AES256_ECB_enc_sch(const uint8_t *plaintext, const size_t plaintext_len, const void *schedule, uint8_t *ciphertext) { + C_OR_NI_OR_ARM( + oqs_aes256_ecb_enc_sch_c(plaintext, plaintext_len, schedule, ciphertext), + oqs_aes256_ecb_enc_sch_ni(plaintext, plaintext_len, schedule, ciphertext), + oqs_aes256_ecb_enc_sch_armv8(plaintext, plaintext_len, schedule, ciphertext) + ); +} + +static void AES256_CTR_inc_stream_iv(const uint8_t *iv, const size_t iv_len, const void *schedule, uint8_t *out, size_t out_len) { + C_OR_NI_OR_ARM( + oqs_aes256_ctr_enc_sch_c(iv, iv_len, schedule, out, out_len), + oqs_aes256_ctr_enc_sch_ni(iv, iv_len, schedule, out, out_len), + oqs_aes256_ctr_enc_sch_armv8(iv, iv_len, schedule, out, out_len) + ); +} + +static void AES256_CTR_inc_stream_blks(void *schedule, uint8_t *out, size_t out_blks) { + C_OR_NI_OR_ARM( + oqs_aes256_ctr_enc_sch_upd_blks_c(schedule, out, out_blks), + oqs_aes256_ctr_enc_sch_upd_blks_ni(schedule, out, out_blks), + oqs_aes256_ctr_enc_sch_upd_blks_armv8(schedule, out, out_blks) + ); +} + +struct OQS_AES_callbacks aes_default_callbacks = { + AES128_ECB_load_schedule, + AES128_free_schedule, + AES128_ECB_enc, + AES128_ECB_enc_sch, + AES256_ECB_load_schedule, + AES256_CTR_inc_init, + AES256_CTR_inc_iv, + AES256_CTR_inc_ivu64, + AES256_free_schedule, + AES256_ECB_enc, + AES256_ECB_enc_sch, + AES256_CTR_inc_stream_iv, + AES256_CTR_inc_stream_blks, +}; + +void OQS_AES_init(void) { +} diff --git a/src/common/aes/aes_local.h b/src/common/aes/aes_local.h index eac87935..4c9942a0 100644 --- a/src/common/aes/aes_local.h +++ b/src/common/aes/aes_local.h @@ -40,3 +40,5 @@ void oqs_aes256_enc_sch_block_armv8(const uint8_t *plaintext, const void *_sched void oqs_aes256_ecb_enc_sch_armv8(const uint8_t *plaintext, const size_t plaintext_len, const void *schedule, uint8_t *ciphertext); void oqs_aes256_ctr_enc_sch_armv8(const uint8_t *iv, const size_t iv_len, const void *schedule, uint8_t *out, size_t out_len); void oqs_aes256_ctr_enc_sch_upd_blks_armv8(void *schedule, uint8_t *out, size_t out_blks); + +extern struct OQS_AES_callbacks aes_default_callbacks; diff --git a/src/common/aes/aes_ossl.c b/src/common/aes/aes_ossl.c index 67193292..feaff395 100644 --- a/src/common/aes/aes_ossl.c +++ b/src/common/aes/aes_ossl.c @@ -7,7 +7,6 @@ #include "aes.h" -#include #include "../ossl_helpers.h" struct key_schedule { @@ -28,60 +27,60 @@ static inline void br_enc64be(unsigned char *dst, uint64_t x) { dst[0] = (unsigned char)x; } -void OQS_AES128_ECB_load_schedule(const uint8_t *key, void **schedule) { +static void AES128_ECB_load_schedule(const uint8_t *key, void **schedule) { *schedule = malloc(sizeof(struct key_schedule)); OQS_EXIT_IF_NULLPTR(*schedule, "OpenSSL"); struct key_schedule *ks = (struct key_schedule *) *schedule; ks->for_ECB = 1; - ks->ctx = EVP_CIPHER_CTX_new(); + ks->ctx = OSSL_FUNC(EVP_CIPHER_CTX_new)(); OQS_EXIT_IF_NULLPTR(ks->ctx, "OpenSSL"); - OQS_OPENSSL_GUARD(EVP_EncryptInit_ex(ks->ctx, oqs_aes_128_ecb(), NULL, key, NULL)); - EVP_CIPHER_CTX_set_padding(ks->ctx, 0); + OQS_OPENSSL_GUARD(OSSL_FUNC(EVP_EncryptInit_ex)(ks->ctx, oqs_aes_128_ecb(), NULL, key, NULL)); + OSSL_FUNC(EVP_CIPHER_CTX_set_padding)(ks->ctx, 0); } -void OQS_AES128_free_schedule(void *schedule) { +static void AES128_free_schedule(void *schedule) { if (schedule != NULL) { struct key_schedule *ks = (struct key_schedule *) schedule; if (ks->ctx != NULL) { - EVP_CIPHER_CTX_free(ks->ctx); + OSSL_FUNC(EVP_CIPHER_CTX_free)(ks->ctx); } OQS_MEM_cleanse(ks->key, 32); OQS_MEM_secure_free(schedule, sizeof(struct key_schedule)); } } -void OQS_AES128_ECB_enc(const uint8_t *plaintext, const size_t plaintext_len, const uint8_t *key, uint8_t *ciphertext) { +static void AES128_ECB_enc(const uint8_t *plaintext, const size_t plaintext_len, const uint8_t *key, uint8_t *ciphertext) { void *schedule = NULL; OQS_AES128_ECB_load_schedule(key, &schedule); OQS_AES128_ECB_enc_sch(plaintext, plaintext_len, schedule, ciphertext); OQS_AES128_free_schedule(schedule); } -void OQS_AES128_ECB_enc_sch(const uint8_t *plaintext, const size_t plaintext_len, const void *schedule, uint8_t *ciphertext) { +static void AES128_ECB_enc_sch(const uint8_t *plaintext, const size_t plaintext_len, const void *schedule, uint8_t *ciphertext) { assert(plaintext_len % 16 == 0); int outlen; const struct key_schedule *ks = (const struct key_schedule *) schedule; SIZE_T_TO_INT_OR_EXIT(plaintext_len, plaintext_len_int) - OQS_OPENSSL_GUARD(EVP_EncryptUpdate(ks->ctx, ciphertext, &outlen, plaintext, plaintext_len_int)); + OQS_OPENSSL_GUARD(OSSL_FUNC(EVP_EncryptUpdate)(ks->ctx, ciphertext, &outlen, plaintext, plaintext_len_int)); assert(outlen == plaintext_len_int); - OQS_OPENSSL_GUARD(EVP_EncryptFinal_ex(ks->ctx, ciphertext, &outlen)); + OQS_OPENSSL_GUARD(OSSL_FUNC(EVP_EncryptFinal_ex)(ks->ctx, ciphertext, &outlen)); } -void OQS_AES256_ECB_load_schedule(const uint8_t *key, void **schedule) { +static void AES256_ECB_load_schedule(const uint8_t *key, void **schedule) { *schedule = malloc(sizeof(struct key_schedule)); OQS_EXIT_IF_NULLPTR(*schedule, "OpenSSL"); struct key_schedule *ks = (struct key_schedule *) *schedule; ks->for_ECB = 1; - ks->ctx = EVP_CIPHER_CTX_new(); + ks->ctx = OSSL_FUNC(EVP_CIPHER_CTX_new)(); OQS_EXIT_IF_NULLPTR(ks->ctx, "OpenSSL"); - OQS_OPENSSL_GUARD(EVP_EncryptInit_ex(ks->ctx, oqs_aes_256_ecb(), NULL, key, NULL)); - EVP_CIPHER_CTX_set_padding(ks->ctx, 0); + OQS_OPENSSL_GUARD(OSSL_FUNC(EVP_EncryptInit_ex)(ks->ctx, oqs_aes_256_ecb(), NULL, key, NULL)); + OSSL_FUNC(EVP_CIPHER_CTX_set_padding)(ks->ctx, 0); } -void OQS_AES256_CTR_inc_init(const uint8_t *key, void **schedule) { +static void AES256_CTR_inc_init(const uint8_t *key, void **schedule) { *schedule = malloc(sizeof(struct key_schedule)); struct key_schedule *ks = (struct key_schedule *) *schedule; - EVP_CIPHER_CTX *ctr_ctx = EVP_CIPHER_CTX_new(); + EVP_CIPHER_CTX *ctr_ctx = OSSL_FUNC(EVP_CIPHER_CTX_new)(); assert(ctr_ctx != NULL); OQS_EXIT_IF_NULLPTR(*schedule, "OpenSSL"); @@ -90,7 +89,7 @@ void OQS_AES256_CTR_inc_init(const uint8_t *key, void **schedule) { memcpy(ks->key, key, 32); } -void OQS_AES256_CTR_inc_iv(const uint8_t *iv, size_t iv_len, void *schedule) { +static void AES256_CTR_inc_iv(const uint8_t *iv, size_t iv_len, void *schedule) { OQS_EXIT_IF_NULLPTR(schedule, "OpenSSL"); struct key_schedule *ks = (struct key_schedule *) schedule; if (iv_len == 12) { @@ -101,36 +100,36 @@ void OQS_AES256_CTR_inc_iv(const uint8_t *iv, size_t iv_len, void *schedule) { } else { exit(EXIT_FAILURE); } - OQS_OPENSSL_GUARD(EVP_EncryptInit_ex(ks->ctx, oqs_aes_256_ctr(), NULL, ks->key, ks->iv)); + OQS_OPENSSL_GUARD(OSSL_FUNC(EVP_EncryptInit_ex)(ks->ctx, oqs_aes_256_ctr(), NULL, ks->key, ks->iv)); } -void OQS_AES256_CTR_inc_ivu64(uint64_t iv, void *schedule) { +static void AES256_CTR_inc_ivu64(uint64_t iv, void *schedule) { OQS_EXIT_IF_NULLPTR(schedule, "OpenSSL"); struct key_schedule *ks = (struct key_schedule *) schedule; br_enc64be(ks->iv, iv); memset(&ks->iv[8], 0, 8); - OQS_OPENSSL_GUARD(EVP_EncryptInit_ex(ks->ctx, oqs_aes_256_ctr(), NULL, ks->key, ks->iv)); + OQS_OPENSSL_GUARD(OSSL_FUNC(EVP_EncryptInit_ex)(ks->ctx, oqs_aes_256_ctr(), NULL, ks->key, ks->iv)); } -void OQS_AES256_free_schedule(void *schedule) { +static void AES256_free_schedule(void *schedule) { // actually same code as AES 128 OQS_AES128_free_schedule(schedule); } -void OQS_AES256_ECB_enc(const uint8_t *plaintext, const size_t plaintext_len, const uint8_t *key, uint8_t *ciphertext) { +static void AES256_ECB_enc(const uint8_t *plaintext, const size_t plaintext_len, const uint8_t *key, uint8_t *ciphertext) { void *schedule = NULL; OQS_AES256_ECB_load_schedule(key, &schedule); OQS_AES256_ECB_enc_sch(plaintext, plaintext_len, schedule, ciphertext); OQS_AES256_free_schedule(schedule); } -void OQS_AES256_ECB_enc_sch(const uint8_t *plaintext, const size_t plaintext_len, const void *schedule, uint8_t *ciphertext) { +static void AES256_ECB_enc_sch(const uint8_t *plaintext, const size_t plaintext_len, const void *schedule, uint8_t *ciphertext) { // actually same code as AES 128 OQS_AES128_ECB_enc_sch(plaintext, plaintext_len, schedule, ciphertext); } -void OQS_AES256_CTR_inc_stream_iv(const uint8_t *iv, size_t iv_len, const void *schedule, uint8_t *out, size_t out_len) { - EVP_CIPHER_CTX *ctr_ctx = EVP_CIPHER_CTX_new(); +static void AES256_CTR_inc_stream_iv(const uint8_t *iv, size_t iv_len, const void *schedule, uint8_t *out, size_t out_len) { + EVP_CIPHER_CTX *ctr_ctx = OSSL_FUNC(EVP_CIPHER_CTX_new)(); assert(ctr_ctx != NULL); uint8_t iv_ctr[16]; if (iv_len == 12) { @@ -145,21 +144,37 @@ void OQS_AES256_CTR_inc_stream_iv(const uint8_t *iv, size_t iv_len, const void * exit(EXIT_FAILURE); } const struct key_schedule *ks = (const struct key_schedule *) schedule; - OQS_OPENSSL_GUARD(EVP_EncryptInit_ex(ctr_ctx, oqs_aes_256_ctr(), NULL, ks->key, iv_ctr)); + OQS_OPENSSL_GUARD(OSSL_FUNC(EVP_EncryptInit_ex)(ctr_ctx, oqs_aes_256_ctr(), NULL, ks->key, iv_ctr)); SIZE_T_TO_INT_OR_EXIT(out_len, out_len_input_int) memset(out, 0, (size_t)out_len_input_int); int out_len_output; - OQS_OPENSSL_GUARD(EVP_EncryptUpdate(ctr_ctx, out, &out_len_output, out, out_len_input_int)); - OQS_OPENSSL_GUARD(EVP_EncryptFinal_ex(ctr_ctx, out + out_len_output, &out_len_output)); - EVP_CIPHER_CTX_free(ctr_ctx); + OQS_OPENSSL_GUARD(OSSL_FUNC(EVP_EncryptUpdate)(ctr_ctx, out, &out_len_output, out, out_len_input_int)); + OQS_OPENSSL_GUARD(OSSL_FUNC(EVP_EncryptFinal_ex)(ctr_ctx, out + out_len_output, &out_len_output)); + OSSL_FUNC(EVP_CIPHER_CTX_free)(ctr_ctx); } -void OQS_AES256_CTR_inc_stream_blks(void *schedule, uint8_t *out, size_t out_blks) { +static void AES256_CTR_inc_stream_blks(void *schedule, uint8_t *out, size_t out_blks) { size_t out_len = out_blks * 16; struct key_schedule *ks = (struct key_schedule *) schedule; int out_len_output; SIZE_T_TO_INT_OR_EXIT(out_len, out_len_input_int); memset(out, 0, (size_t)out_len_input_int); - OQS_OPENSSL_GUARD(EVP_EncryptUpdate(ks->ctx, out, &out_len_output, out, (int) out_len)); + OQS_OPENSSL_GUARD(OSSL_FUNC(EVP_EncryptUpdate)(ks->ctx, out, &out_len_output, out, (int) out_len)); } + +struct OQS_AES_callbacks aes_default_callbacks = { + AES128_ECB_load_schedule, + AES128_free_schedule, + AES128_ECB_enc, + AES128_ECB_enc_sch, + AES256_ECB_load_schedule, + AES256_CTR_inc_init, + AES256_CTR_inc_iv, + AES256_CTR_inc_ivu64, + AES256_free_schedule, + AES256_ECB_enc, + AES256_ECB_enc_sch, + AES256_CTR_inc_stream_iv, + AES256_CTR_inc_stream_blks, +}; diff --git a/src/common/common.c b/src/common/common.c index 9d6fc9f0..7de1e658 100644 --- a/src/common/common.c +++ b/src/common/common.c @@ -26,9 +26,7 @@ #endif #if defined(OQS_USE_OPENSSL) -#include #include "ossl_helpers.h" -CRYPTO_ONCE OQS_ONCE_STATIC_FREE; #endif /* Identifying the CPU is expensive so we cache the results in cpu_ext_data */ @@ -233,7 +231,6 @@ OQS_API void OQS_init(void) { #if defined(OQS_DIST_BUILD) OQS_CPU_has_extension(OQS_CPU_EXT_INIT); #endif - return; } OQS_API const char *OQS_version(void) { @@ -242,9 +239,8 @@ OQS_API const char *OQS_version(void) { OQS_API void OQS_destroy(void) { #if defined(OQS_USE_OPENSSL) - CRYPTO_THREAD_run_once(&OQS_ONCE_STATIC_FREE, oqs_free_ossl_objects); + oqs_ossl_destroy(); #endif - return; } OQS_API int OQS_MEM_secure_bcmp(const void *a, const void *b, size_t len) { diff --git a/src/common/ossl_functions.h b/src/common/ossl_functions.h new file mode 100644 index 00000000..cece5c95 --- /dev/null +++ b/src/common/ossl_functions.h @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: MIT + +// This file lists all OpenSSL functions used throughout the liboqs source code. +// +// Note that this file is included multiple times to generate custom +// code by definining the FUNC macro, so no header guard should be +// added here. + +VOID_FUNC(void, ERR_print_errors_fp, (FILE *fp), (fp)) +VOID_FUNC(void, EVP_CIPHER_CTX_free, (EVP_CIPHER_CTX *c), (c)) +FUNC(EVP_CIPHER_CTX *, EVP_CIPHER_CTX_new, (void), ()) +FUNC(int, EVP_CIPHER_CTX_set_padding, (EVP_CIPHER_CTX *c, int pad), (c, pad)) +FUNC(int, EVP_DigestFinalXOF, (EVP_MD_CTX *ctx, unsigned char *md, size_t len), (ctx, md, len)) +FUNC(int, EVP_DigestFinal_ex, (EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s), (ctx, md, s)) +FUNC(int, EVP_DigestInit_ex, (EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl), (ctx, type, impl)) +FUNC(int, EVP_DigestUpdate, (EVP_MD_CTX *ctx, const void *d, size_t cnt), (ctx, d, cnt)) +FUNC(int, EVP_EncryptFinal_ex, (EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl), (ctx, out, outl)) +FUNC(int, EVP_EncryptInit_ex, (EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl, const unsigned char *key, const unsigned char *iv), + (ctx, cipher, impl, key, iv)) +FUNC(int, EVP_EncryptUpdate, (EVP_CIPHER_CTX *ctx, unsigned char *out, + int *outl, const unsigned char *in, int inl), + (ctx, out, outl, in, inl)) +FUNC(int, EVP_MD_CTX_copy_ex, (EVP_MD_CTX *out, const EVP_MD_CTX *in), (out, in)) +VOID_FUNC(void, EVP_MD_CTX_free, (EVP_MD_CTX *ctx), (ctx)) +FUNC(EVP_MD_CTX *, EVP_MD_CTX_new, (void), ()) +FUNC(int, EVP_MD_CTX_reset, (EVP_MD_CTX *ctx), (ctx)) +FUNC(const EVP_CIPHER *, EVP_aes_128_ecb, (void), ()) +FUNC(const EVP_CIPHER *, EVP_aes_256_ecb, (void), ()) +FUNC(const EVP_CIPHER *, EVP_aes_256_ctr, (void), ()) +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +FUNC(EVP_CIPHER *, EVP_CIPHER_fetch, (OSSL_LIB_CTX *ctx, const char *algorithm, + const char *properties), + (ctx, algorithm, properties)) +VOID_FUNC(void, EVP_CIPHER_free, (EVP_CIPHER *cipher), (cipher)) +FUNC(EVP_MD *, EVP_MD_fetch, (OSSL_LIB_CTX *ctx, const char *algorithm, + const char *properties), + (ctx, algorithm, properties)) +VOID_FUNC(void, EVP_MD_free, (EVP_MD *md), (md)) +#else +FUNC(const EVP_MD *, EVP_sha256, (void), ()) +FUNC(const EVP_MD *, EVP_sha384, (void), ()) +FUNC(const EVP_MD *, EVP_sha3_256, (void), ()) +FUNC(const EVP_MD *, EVP_sha3_384, (void), ()) +FUNC(const EVP_MD *, EVP_sha3_512, (void), ()) +FUNC(const EVP_MD *, EVP_sha512, (void), ()) +FUNC(const EVP_MD *, EVP_shake128, (void), ()) +FUNC(const EVP_MD *, EVP_shake256, (void), ()) +#endif +FUNC(int, RAND_bytes, (unsigned char *buf, int num), (buf, num)) +FUNC(int, RAND_poll, (void), ()) +FUNC(int, RAND_status, (void), ()) diff --git a/src/common/ossl_helpers.c b/src/common/ossl_helpers.c index f52ceaef..1c73d8b9 100644 --- a/src/common/ossl_helpers.c +++ b/src/common/ossl_helpers.c @@ -1,33 +1,39 @@ // SPDX-License-Identifier: MIT #include #if defined(OQS_USE_OPENSSL) -#include +#define OQS_OSSL_NO_EXTERN 1 #include "ossl_helpers.h" +#include +#include + #if OPENSSL_VERSION_NUMBER >= 0x30000000L +#if defined(OQS_USE_PTHREADS) +#include + +static pthread_once_t init_once_control = PTHREAD_ONCE_INIT; +static pthread_once_t free_once_control = PTHREAD_ONCE_INIT; +#endif + static EVP_MD *sha256_ptr, *sha384_ptr, *sha512_ptr, *sha3_256_ptr, *sha3_384_ptr, *sha3_512_ptr, *shake128_ptr, *shake256_ptr; static EVP_CIPHER *aes128_ecb_ptr, *aes256_ecb_ptr, *aes256_ctr_ptr; -#endif -CRYPTO_ONCE OQS_ONCE_STATIC_INIT; +static void fetch_ossl_objects(void) { + sha256_ptr = OSSL_FUNC(EVP_MD_fetch)(NULL, "SHA256", NULL); + sha384_ptr = OSSL_FUNC(EVP_MD_fetch)(NULL, "SHA384", NULL); + sha512_ptr = OSSL_FUNC(EVP_MD_fetch)(NULL, "SHA512", NULL); -#if OPENSSL_VERSION_NUMBER >= 0x30000000L -static void oqs_fetch_ossl_objects(void) { - sha256_ptr = EVP_MD_fetch(NULL, "SHA256", NULL); - sha384_ptr = EVP_MD_fetch(NULL, "SHA384", NULL); - sha512_ptr = EVP_MD_fetch(NULL, "SHA512", NULL); - - sha3_256_ptr = EVP_MD_fetch(NULL, "SHA3-256", NULL); - sha3_384_ptr = EVP_MD_fetch(NULL, "SHA3-384", NULL); - sha3_512_ptr = EVP_MD_fetch(NULL, "SHA3-512", NULL); - shake128_ptr = EVP_MD_fetch(NULL, "SHAKE128", NULL); - shake256_ptr = EVP_MD_fetch(NULL, "SHAKE256", NULL); + sha3_256_ptr = OSSL_FUNC(EVP_MD_fetch)(NULL, "SHA3-256", NULL); + sha3_384_ptr = OSSL_FUNC(EVP_MD_fetch)(NULL, "SHA3-384", NULL); + sha3_512_ptr = OSSL_FUNC(EVP_MD_fetch)(NULL, "SHA3-512", NULL); + shake128_ptr = OSSL_FUNC(EVP_MD_fetch)(NULL, "SHAKE128", NULL); + shake256_ptr = OSSL_FUNC(EVP_MD_fetch)(NULL, "SHAKE256", NULL); - aes128_ecb_ptr = EVP_CIPHER_fetch(NULL, "AES-128-ECB", NULL); - aes256_ecb_ptr = EVP_CIPHER_fetch(NULL, "AES-256-ECB", NULL); - aes256_ctr_ptr = EVP_CIPHER_fetch(NULL, "AES-256-CTR", NULL); + aes128_ecb_ptr = OSSL_FUNC(EVP_CIPHER_fetch)(NULL, "AES-128-ECB", NULL); + aes256_ecb_ptr = OSSL_FUNC(EVP_CIPHER_fetch)(NULL, "AES-256-ECB", NULL); + aes256_ctr_ptr = OSSL_FUNC(EVP_CIPHER_fetch)(NULL, "AES-256-CTR", NULL); if (!sha256_ptr || !sha384_ptr || !sha512_ptr || !sha3_256_ptr || !sha3_384_ptr || !sha3_512_ptr || !shake128_ptr || !shake256_ptr || @@ -35,164 +41,314 @@ static void oqs_fetch_ossl_objects(void) { fprintf(stderr, "liboqs warning: OpenSSL initialization failure. Is provider for SHA, SHAKE, AES enabled?\n"); } } -#endif -void oqs_free_ossl_objects(void) { +static void free_ossl_objects(void) { + OSSL_FUNC(EVP_MD_free)(sha256_ptr); + sha256_ptr = NULL; + OSSL_FUNC(EVP_MD_free)(sha384_ptr); + sha384_ptr = NULL; + OSSL_FUNC(EVP_MD_free)(sha512_ptr); + sha512_ptr = NULL; + OSSL_FUNC(EVP_MD_free)(sha3_256_ptr); + sha3_256_ptr = NULL; + OSSL_FUNC(EVP_MD_free)(sha3_384_ptr); + sha3_384_ptr = NULL; + OSSL_FUNC(EVP_MD_free)(sha3_512_ptr); + sha3_512_ptr = NULL; + OSSL_FUNC(EVP_MD_free)(shake128_ptr); + shake128_ptr = NULL; + OSSL_FUNC(EVP_MD_free)(shake256_ptr); + shake256_ptr = NULL; + OSSL_FUNC(EVP_CIPHER_free)(aes128_ecb_ptr); + aes128_ecb_ptr = NULL; + OSSL_FUNC(EVP_CIPHER_free)(aes256_ecb_ptr); + aes256_ecb_ptr = NULL; + OSSL_FUNC(EVP_CIPHER_free)(aes256_ctr_ptr); + aes256_ctr_ptr = NULL; +} +#endif // OPENSSL_VERSION_NUMBER >= 0x30000000L + +void oqs_ossl_destroy(void) { #if OPENSSL_VERSION_NUMBER >= 0x30000000L - EVP_MD_free(sha256_ptr); - EVP_MD_free(sha384_ptr); - EVP_MD_free(sha512_ptr); - EVP_MD_free(sha3_256_ptr); - EVP_MD_free(sha3_384_ptr); - EVP_MD_free(sha3_512_ptr); - EVP_MD_free(shake128_ptr); - EVP_MD_free(shake256_ptr); - EVP_CIPHER_free(aes128_ecb_ptr); - EVP_CIPHER_free(aes256_ecb_ptr); - EVP_CIPHER_free(aes256_ctr_ptr); +#if defined(OQS_USE_PTHREADS) + pthread_once(&free_once_control, free_ossl_objects); +#else + if (sha256_ptr || sha384_ptr || sha512_ptr || sha3_256_ptr || + sha3_384_ptr || sha3_512_ptr || shake128_ptr || shake256_ptr || + aes128_ecb_ptr || aes256_ecb_ptr || aes256_ctr_ptr) { + free_ossl_objects(); + } +#endif #endif } const EVP_MD *oqs_sha256(void) { #if OPENSSL_VERSION_NUMBER >= 0x30000000L +#if defined(OQS_USE_PTHREADS) + if (pthread_once(&init_once_control, fetch_ossl_objects)) { + return NULL; + } +#else if (!sha256_ptr) { - if (!CRYPTO_THREAD_run_once(&OQS_ONCE_STATIC_INIT, oqs_fetch_ossl_objects)) { - return NULL; - } + fetch_ossl_objects(); } +#endif return sha256_ptr; #else - return EVP_sha256(); + return OSSL_FUNC(EVP_sha256)(); #endif } const EVP_MD *oqs_sha384(void) { #if OPENSSL_VERSION_NUMBER >= 0x30000000L +#if defined(OQS_USE_PTHREADS) + if (pthread_once(&init_once_control, fetch_ossl_objects)) { + return NULL; + } +#else if (!sha384_ptr) { - if (!CRYPTO_THREAD_run_once(&OQS_ONCE_STATIC_INIT, oqs_fetch_ossl_objects)) { - return NULL; - } + fetch_ossl_objects(); } +#endif return sha384_ptr; #else - return EVP_sha384(); + return OSSL_FUNC(EVP_sha384)(); #endif } const EVP_MD *oqs_sha512(void) { #if OPENSSL_VERSION_NUMBER >= 0x30000000L +#if defined(OQS_USE_PTHREADS) + if (pthread_once(&init_once_control, fetch_ossl_objects)) { + return NULL; + } +#else if (!sha512_ptr) { - if (!CRYPTO_THREAD_run_once(&OQS_ONCE_STATIC_INIT, oqs_fetch_ossl_objects)) { - return NULL; - } + fetch_ossl_objects(); } +#endif return sha512_ptr; #else - return EVP_sha512(); + return OSSL_FUNC(EVP_sha512)(); #endif } const EVP_MD *oqs_shake128(void) { #if OPENSSL_VERSION_NUMBER >= 0x30000000L +#if defined(OQS_USE_PTHREADS) + if (pthread_once(&init_once_control, fetch_ossl_objects)) { + return NULL; + } +#else if (!shake128_ptr) { - if (!CRYPTO_THREAD_run_once(&OQS_ONCE_STATIC_INIT, oqs_fetch_ossl_objects)) { - return NULL; - } + fetch_ossl_objects(); } +#endif return shake128_ptr; #else - return EVP_shake128(); + return OSSL_FUNC(EVP_shake128)(); #endif } const EVP_MD *oqs_shake256(void) { #if OPENSSL_VERSION_NUMBER >= 0x30000000L +#if defined(OQS_USE_PTHREADS) + if (pthread_once(&init_once_control, fetch_ossl_objects)) { + return NULL; + } +#else if (!shake256_ptr) { - if (!CRYPTO_THREAD_run_once(&OQS_ONCE_STATIC_INIT, oqs_fetch_ossl_objects)) { - return NULL; - } + fetch_ossl_objects(); } +#endif return shake256_ptr; #else - return EVP_shake256(); + return OSSL_FUNC(EVP_shake256)(); #endif } const EVP_MD *oqs_sha3_256(void) { #if OPENSSL_VERSION_NUMBER >= 0x30000000L +#if defined(OQS_USE_PTHREADS) + if (pthread_once(&init_once_control, fetch_ossl_objects)) { + return NULL; + } +#else if (!sha3_256_ptr) { - if (!CRYPTO_THREAD_run_once(&OQS_ONCE_STATIC_INIT, oqs_fetch_ossl_objects)) { - return NULL; - } + fetch_ossl_objects(); } +#endif return sha3_256_ptr; #else - return EVP_sha3_256(); + return OSSL_FUNC(EVP_sha3_256)(); #endif } const EVP_MD *oqs_sha3_384(void) { #if OPENSSL_VERSION_NUMBER >= 0x30000000L +#if defined(OQS_USE_PTHREADS) + if (pthread_once(&init_once_control, fetch_ossl_objects)) { + return NULL; + } +#else if (!sha3_384_ptr) { - if (!CRYPTO_THREAD_run_once(&OQS_ONCE_STATIC_INIT, oqs_fetch_ossl_objects)) { - return NULL; - } + fetch_ossl_objects(); } +#endif return sha3_384_ptr; #else - return EVP_sha3_384(); + return OSSL_FUNC(EVP_sha3_384)(); #endif } const EVP_MD *oqs_sha3_512(void) { #if OPENSSL_VERSION_NUMBER >= 0x30000000L +#if defined(OQS_USE_PTHREADS) + if (pthread_once(&init_once_control, fetch_ossl_objects)) { + return NULL; + } +#else if (!sha3_512_ptr) { - if (!CRYPTO_THREAD_run_once(&OQS_ONCE_STATIC_INIT, oqs_fetch_ossl_objects)) { - return NULL; - } + fetch_ossl_objects(); } +#endif return sha3_512_ptr; #else - return EVP_sha3_512(); + return OSSL_FUNC(EVP_sha3_512)(); #endif } const EVP_CIPHER *oqs_aes_128_ecb(void) { #if OPENSSL_VERSION_NUMBER >= 0x30000000L +#if defined(OQS_USE_PTHREADS) + if (pthread_once(&init_once_control, fetch_ossl_objects)) { + return NULL; + } +#else if (!aes128_ecb_ptr) { - if (!CRYPTO_THREAD_run_once(&OQS_ONCE_STATIC_INIT, oqs_fetch_ossl_objects)) { - return NULL; - } + fetch_ossl_objects(); } +#endif return aes128_ecb_ptr; #else - return EVP_aes_128_ecb(); + return OSSL_FUNC(EVP_aes_128_ecb)(); #endif } const EVP_CIPHER *oqs_aes_256_ecb(void) { #if OPENSSL_VERSION_NUMBER >= 0x30000000L +#if defined(OQS_USE_PTHREADS) + if (pthread_once(&init_once_control, fetch_ossl_objects)) { + return NULL; + } +#else if (!aes256_ecb_ptr) { - if (!CRYPTO_THREAD_run_once(&OQS_ONCE_STATIC_INIT, oqs_fetch_ossl_objects)) { - return NULL; - } + fetch_ossl_objects(); } +#endif return aes256_ecb_ptr; #else - return EVP_aes_256_ecb(); + return OSSL_FUNC(EVP_aes_256_ecb)(); #endif } const EVP_CIPHER *oqs_aes_256_ctr(void) { #if OPENSSL_VERSION_NUMBER >= 0x30000000L +#if defined(OQS_USE_PTHREADS) + if (pthread_once(&init_once_control, fetch_ossl_objects)) { + return NULL; + } +#else if (!aes256_ctr_ptr) { - if (!CRYPTO_THREAD_run_once(&OQS_ONCE_STATIC_INIT, oqs_fetch_ossl_objects)) { - return NULL; - } + fetch_ossl_objects(); } +#endif return aes256_ctr_ptr; #else - return EVP_aes_256_ctr(); + return OSSL_FUNC(EVP_aes_256_ctr)(); +#endif +} + +#if defined(OQS_DLOPEN_OPENSSL) + +static void *libcrypto_dlhandle; + +static void ensure_library(void); + +#if defined(OQS_USE_PTHREADS) +static pthread_once_t dlopen_once_control = PTHREAD_ONCE_INIT; + +#define ENSURE_LIBRARY pthread_once(&dlopen_once_control, ensure_library) +#else +#define ENSURE_LIBRARY do { \ + if (!libcrypto_dlhandle) { \ + ensure_library(); \ + } \ + } while (0) +#endif // OQS_USE_PTHREADS + +/* Define redirection symbols */ +#if (2 <= __GNUC__ || (4 <= __clang_major__)) +#define FUNC(ret, name, args, cargs) \ + static __typeof__(name)(*_oqs_ossl_sym_##name); +#else +#define FUNC(ret, name, args, cargs) \ + static ret(*_oqs_ossl_sym_##name)args; #endif +#define VOID_FUNC FUNC +#include "ossl_functions.h" +#undef VOID_FUNC +#undef FUNC + +/* Define redirection wrapper functions */ +#define FUNC(ret, name, args, cargs) \ +ret _oqs_ossl_##name args \ +{ \ + ENSURE_LIBRARY; \ + assert(_oqs_ossl_sym_##name); \ + return _oqs_ossl_sym_##name cargs; \ +} +#define VOID_FUNC(ret, name, args, cargs) \ +ret _oqs_ossl_##name args \ +{ \ + ENSURE_LIBRARY; \ + assert(_oqs_ossl_sym_##name); \ + _oqs_ossl_sym_##name cargs; \ +} +#include "ossl_functions.h" +#undef VOID_FUNC +#undef FUNC + +static void ensure_symbol(const char *name, void **symp) { + if (!*symp) { + void *sym = dlsym(libcrypto_dlhandle, name); + if (!sym) { + exit(EXIT_FAILURE); + } + *symp = sym; + } +} + +static void ensure_library(void) { + if (!libcrypto_dlhandle) { + libcrypto_dlhandle = dlopen(OQS_OPENSSL_CRYPTO_SONAME, + RTLD_LAZY | RTLD_LOCAL); + if (!libcrypto_dlhandle) { + exit(EXIT_FAILURE); + } + } + +#define ENSURE_SYMBOL(name) \ + ensure_symbol(#name, (void **)&_oqs_ossl_sym_##name) +#define FUNC(ret, name, args, cargs) \ + ENSURE_SYMBOL(name); +#define VOID_FUNC FUNC +#include "ossl_functions.h" +#undef VOID_FUNC +#undef FUNC +#undef ENSURE_SYMBOL } + +#endif // OQS_DLOPEN_OPENSSL + #endif diff --git a/src/common/ossl_helpers.h b/src/common/ossl_helpers.h index fd7b0dde..fe6d3468 100644 --- a/src/common/ossl_helpers.h +++ b/src/common/ossl_helpers.h @@ -6,8 +6,12 @@ extern "C" { #endif +#include +#include +#include + #if defined(OQS_USE_OPENSSL) -void oqs_free_ossl_objects(void); +void oqs_ossl_destroy(void); const EVP_MD *oqs_sha256(void); @@ -30,6 +34,24 @@ const EVP_CIPHER *oqs_aes_128_ecb(void); const EVP_CIPHER *oqs_aes_256_ecb(void); const EVP_CIPHER *oqs_aes_256_ctr(void); + +#ifdef OQS_DLOPEN_OPENSSL + +#define FUNC(ret, name, args, cargs) \ + ret _oqs_ossl_##name args; +#define VOID_FUNC FUNC +#include "ossl_functions.h" +#undef VOID_FUNC +#undef FUNC + +#define OSSL_FUNC(name) _oqs_ossl_##name + +#else + +#define OSSL_FUNC(name) name + +#endif + #endif #if defined(__cplusplus) diff --git a/src/common/rand/rand.c b/src/common/rand/rand.c index b48d8030..5ff7efe0 100644 --- a/src/common/rand/rand.c +++ b/src/common/rand/rand.c @@ -23,7 +23,7 @@ void OQS_randombytes_openssl(uint8_t *random_array, size_t bytes_to_read); #endif #ifdef OQS_USE_OPENSSL -#include +#include "../ossl_helpers.h" // Use OpenSSL's RAND_bytes as the default PRNG static void (*oqs_randombytes_algorithm)(uint8_t *, size_t) = &OQS_randombytes_openssl; #else @@ -113,12 +113,12 @@ void OQS_randombytes_openssl(uint8_t *random_array, size_t bytes_to_read) { int rep = OQS_RAND_POLL_RETRY; SIZE_T_TO_INT_OR_EXIT(bytes_to_read, bytes_to_read_int) do { - if (RAND_status() == 1) { + if (OSSL_FUNC(RAND_status)() == 1) { break; } - RAND_poll(); + OSSL_FUNC(RAND_poll)(); } while (rep-- >= 0); - if (RAND_bytes(random_array, bytes_to_read_int) != 1) { + if (OSSL_FUNC(RAND_bytes)(random_array, bytes_to_read_int) != 1) { fprintf(stderr, "No OpenSSL randomness retrieved. DRBG available?\n"); // because of void signature we have no other way to signal the problem // we cannot possibly return without randomness diff --git a/src/common/rand/rand_nist.c b/src/common/rand/rand_nist.c index 5e74b45b..6270a31c 100644 --- a/src/common/rand/rand_nist.c +++ b/src/common/rand/rand_nist.c @@ -22,9 +22,6 @@ You are solely responsible for determining the appropriateness of using and dist #include #ifdef OQS_USE_OPENSSL -#include -#include -#include #include "../ossl_helpers.h" #else #include @@ -42,7 +39,7 @@ __declspec(noreturn) __attribute__((noreturn)) # endif static void handleErrors(void) { - ERR_print_errors_fp(stderr); + OSSL_FUNC(ERR_print_errors_fp)(stderr); abort(); } #endif @@ -58,20 +55,20 @@ static void AES256_ECB(unsigned char *key, unsigned char *ctr, unsigned char *bu int len; /* Create and initialise the context */ - if (!(ctx = EVP_CIPHER_CTX_new())) { + if (!(ctx = OSSL_FUNC(EVP_CIPHER_CTX_new)())) { handleErrors(); } - if (1 != EVP_EncryptInit_ex(ctx, oqs_aes_256_ecb(), NULL, key, NULL)) { + if (1 != OSSL_FUNC(EVP_EncryptInit_ex)(ctx, oqs_aes_256_ecb(), NULL, key, NULL)) { handleErrors(); } - if (1 != EVP_EncryptUpdate(ctx, buffer, &len, ctr, 16)) { + if (1 != OSSL_FUNC(EVP_EncryptUpdate)(ctx, buffer, &len, ctr, 16)) { handleErrors(); } /* Clean up */ - EVP_CIPHER_CTX_free(ctx); + OSSL_FUNC(EVP_CIPHER_CTX_free)(ctx); #else void *schedule = NULL; OQS_AES256_ECB_load_schedule(key, &schedule); diff --git a/src/common/sha2/sha2.c b/src/common/sha2/sha2.c index d622b883..9cc732d1 100644 --- a/src/common/sha2/sha2.c +++ b/src/common/sha2/sha2.c @@ -1,132 +1,84 @@ // SPDX-License-Identifier: MIT #include -#include - #include "sha2.h" #include "sha2_local.h" -#if defined(OQS_DIST_ARM64_V8_BUILD) -#define C_OR_ARM(stmt_c, stmt_arm) \ - do { \ - if (OQS_CPU_has_extension(OQS_CPU_EXT_ARM_SHA2)) { \ - stmt_arm; \ - } else { \ - stmt_c; \ - } \ - } while(0) -#elif defined(OQS_USE_ARM_SHA2_INSTRUCTIONS) -#define C_OR_ARM(stmt_c, stmt_arm) \ - stmt_arm -#else -#define C_OR_ARM(stmt_c, stmt_arm) \ - stmt_c -#endif -void OQS_SHA2_sha224_inc_init(OQS_SHA2_sha224_ctx *state) { - oqs_sha2_sha224_inc_init_c((sha224ctx *) state); -} - -void OQS_SHA2_sha224_inc_ctx_clone(OQS_SHA2_sha224_ctx *dest, const OQS_SHA2_sha224_ctx *src) { - oqs_sha2_sha224_inc_ctx_clone_c((sha224ctx *) dest, (const sha224ctx *) src); -} - -void OQS_SHA2_sha224_inc_blocks(OQS_SHA2_sha224_ctx *state, const uint8_t *in, size_t inblocks) { - C_OR_ARM( - oqs_sha2_sha224_inc_blocks_c((sha224ctx *) state, in, inblocks), - oqs_sha2_sha224_inc_blocks_armv8((sha224ctx *) state, in, inblocks) - ); -} - -void OQS_SHA2_sha224_inc_finalize(uint8_t *out, OQS_SHA2_sha224_ctx *state, const uint8_t *in, size_t inlen) { - oqs_sha2_sha224_inc_finalize_c(out, (sha224ctx *) state, in, inlen); -} +static struct OQS_SHA2_callbacks *callbacks = &sha2_default_callbacks; -void OQS_SHA2_sha224_inc_ctx_release(OQS_SHA2_sha224_ctx *state) { - oqs_sha2_sha224_inc_ctx_release_c((sha224ctx *) state); +OQS_API void OQS_SHA2_set_callbacks(struct OQS_SHA2_callbacks *new_callbacks) { + callbacks = new_callbacks; } void OQS_SHA2_sha256_inc_init(OQS_SHA2_sha256_ctx *state) { - oqs_sha2_sha256_inc_init_c((sha256ctx *) state); + callbacks->SHA2_sha256_inc_init(state); } void OQS_SHA2_sha256_inc_ctx_clone(OQS_SHA2_sha256_ctx *dest, const OQS_SHA2_sha256_ctx *src) { - oqs_sha2_sha256_inc_ctx_clone_c((sha256ctx *) dest, (const sha256ctx *) src); + callbacks->SHA2_sha256_inc_ctx_clone(dest, src); } void OQS_SHA2_sha256_inc_blocks(OQS_SHA2_sha256_ctx *state, const uint8_t *in, size_t inblocks) { - C_OR_ARM( - oqs_sha2_sha256_inc_blocks_c((sha256ctx *) state, in, inblocks), - oqs_sha2_sha256_inc_blocks_armv8((sha256ctx *) state, in, inblocks) - ); + callbacks->SHA2_sha256_inc_blocks(state, in, inblocks); } void OQS_SHA2_sha256_inc_finalize(uint8_t *out, OQS_SHA2_sha256_ctx *state, const uint8_t *in, size_t inlen) { - oqs_sha2_sha256_inc_finalize_c(out, (sha256ctx *) state, in, inlen); + callbacks->SHA2_sha256_inc_finalize(out, state, in, inlen); } void OQS_SHA2_sha256_inc_ctx_release(OQS_SHA2_sha256_ctx *state) { - oqs_sha2_sha256_inc_ctx_release_c((sha256ctx *) state); + callbacks->SHA2_sha256_inc_ctx_release(state); } void OQS_SHA2_sha384_inc_init(OQS_SHA2_sha384_ctx *state) { - oqs_sha2_sha384_inc_init_c((sha384ctx *)state); + callbacks->SHA2_sha384_inc_init(state); } void OQS_SHA2_sha384_inc_ctx_clone(OQS_SHA2_sha384_ctx *dest, const OQS_SHA2_sha384_ctx *src) { - oqs_sha2_sha384_inc_ctx_clone_c((sha384ctx *) dest, (const sha384ctx *) src); + callbacks->SHA2_sha384_inc_ctx_clone(dest, src); } void OQS_SHA2_sha384_inc_blocks(OQS_SHA2_sha384_ctx *state, const uint8_t *in, size_t inblocks) { - oqs_sha2_sha384_inc_blocks_c((sha384ctx *) state, in, inblocks); + callbacks->SHA2_sha384_inc_blocks(state, in, inblocks); } void OQS_SHA2_sha384_inc_finalize(uint8_t *out, OQS_SHA2_sha384_ctx *state, const uint8_t *in, size_t inlen) { - oqs_sha2_sha384_inc_finalize_c(out, (sha384ctx *) state, in, inlen); + callbacks->SHA2_sha384_inc_finalize(out, state, in, inlen); } void OQS_SHA2_sha384_inc_ctx_release(OQS_SHA2_sha384_ctx *state) { - oqs_sha2_sha384_inc_ctx_release_c((sha384ctx *) state); + callbacks->SHA2_sha384_inc_ctx_release(state); } void OQS_SHA2_sha512_inc_init(OQS_SHA2_sha512_ctx *state) { - oqs_sha2_sha512_inc_init_c((sha512ctx *)state); + callbacks->SHA2_sha512_inc_init(state); } void OQS_SHA2_sha512_inc_ctx_clone(OQS_SHA2_sha512_ctx *dest, const OQS_SHA2_sha512_ctx *src) { - oqs_sha2_sha512_inc_ctx_clone_c((sha512ctx *) dest, (const sha512ctx *) src); + callbacks->SHA2_sha512_inc_ctx_clone(dest, src); } void OQS_SHA2_sha512_inc_blocks(OQS_SHA2_sha512_ctx *state, const uint8_t *in, size_t inblocks) { - oqs_sha2_sha512_inc_blocks_c((sha512ctx *) state, in, inblocks); + callbacks->SHA2_sha512_inc_blocks(state, in, inblocks); } void OQS_SHA2_sha512_inc_finalize(uint8_t *out, OQS_SHA2_sha512_ctx *state, const uint8_t *in, size_t inlen) { - oqs_sha2_sha512_inc_finalize_c(out, (sha512ctx *) state, in, inlen); + callbacks->SHA2_sha512_inc_finalize(out, state, in, inlen); } void OQS_SHA2_sha512_inc_ctx_release(OQS_SHA2_sha512_ctx *state) { - oqs_sha2_sha512_inc_ctx_release_c((sha512ctx *) state); -} - -void OQS_SHA2_sha224(uint8_t *out, const uint8_t *in, size_t inlen) { - C_OR_ARM ( - oqs_sha2_sha224_c(out, in, inlen), - oqs_sha2_sha224_armv8(out, in, inlen) - ); + callbacks->SHA2_sha512_inc_ctx_release(state); } void OQS_SHA2_sha256(uint8_t *out, const uint8_t *in, size_t inlen) { - C_OR_ARM ( - oqs_sha2_sha256_c(out, in, inlen), - oqs_sha2_sha256_armv8(out, in, inlen) - ); + callbacks->SHA2_sha256(out, in, inlen); } void OQS_SHA2_sha384(uint8_t *out, const uint8_t *in, size_t inlen) { - oqs_sha2_sha384_c(out, in, inlen); + callbacks->SHA2_sha384(out, in, inlen); } void OQS_SHA2_sha512(uint8_t *out, const uint8_t *in, size_t inlen) { - oqs_sha2_sha512_c(out, in, inlen); + callbacks->SHA2_sha512(out, in, inlen); } diff --git a/src/common/sha2/sha2.h b/src/common/sha2/sha2.h index e50a1639..41562f8f 100644 --- a/src/common/sha2/sha2.h +++ b/src/common/sha2/sha2.h @@ -18,16 +18,12 @@ #include #include +#include + #if defined(__cplusplus) extern "C" { #endif -/** Data structure for the state of the SHA-224 incremental hashing API. */ -typedef struct { - /** Internal state */ - void *ctx; -} OQS_SHA2_sha224_ctx; - /** * \brief Process a message with SHA-256 and return the hash code in the output byte array. * @@ -250,6 +246,111 @@ void OQS_SHA2_sha512_inc_finalize(uint8_t *out, OQS_SHA2_sha512_ctx *state, cons */ void OQS_SHA2_sha512_inc_ctx_release(OQS_SHA2_sha512_ctx *state); +/** Data structure implemented by cryptographic provider for SHA-2 operations. + */ +struct OQS_SHA2_callbacks { + /** + * Implementation of function OQS_SHA2_sha256. + */ + void (*SHA2_sha256)(uint8_t *output, const uint8_t *input, size_t inplen); + + /** + * Implementation of function OQS_SHA2_sha256_inc_init. + */ + void (*SHA2_sha256_inc_init)(OQS_SHA2_sha256_ctx *state); + + /** + * Implementation of function OQS_SHA2_sha256_inc_ctx_clone. + */ + void (*SHA2_sha256_inc_ctx_clone)(OQS_SHA2_sha256_ctx *dest, const OQS_SHA2_sha256_ctx *src); + + /** + * Implementation of function OQS_SHA2_sha256_inc_blocks. + */ + void (*SHA2_sha256_inc_blocks)(OQS_SHA2_sha256_ctx *state, const uint8_t *in, size_t inblocks); + + /** + * Implementation of function OQS_SHA2_sha256_inc_finalize. + */ + void (*SHA2_sha256_inc_finalize)(uint8_t *out, OQS_SHA2_sha256_ctx *state, const uint8_t *in, size_t inlen); + + /** + * Implementation of function OQS_SHA2_sha256_inc_ctx_release. + */ + void (*SHA2_sha256_inc_ctx_release)(OQS_SHA2_sha256_ctx *state); + + /** + * Implementation of function OQS_SHA2_sha384. + */ + void (*SHA2_sha384)(uint8_t *output, const uint8_t *input, size_t inplen); + + /** + * Implementation of function OQS_SHA2_sha384_inc_init. + */ + void (*SHA2_sha384_inc_init)(OQS_SHA2_sha384_ctx *state); + + /** + * Implementation of function OQS_SHA2_sha384_inc_ctx_clone. + */ + void (*SHA2_sha384_inc_ctx_clone)(OQS_SHA2_sha384_ctx *dest, const OQS_SHA2_sha384_ctx *src); + + /** + * Implementation of function OQS_SHA2_sha384_inc_blocks. + */ + void (*SHA2_sha384_inc_blocks)(OQS_SHA2_sha384_ctx *state, const uint8_t *in, size_t inblocks); + + /** + * Implementation of function OQS_SHA2_sha384_inc_finalize. + */ + void (*SHA2_sha384_inc_finalize)(uint8_t *out, OQS_SHA2_sha384_ctx *state, const uint8_t *in, size_t inlen); + + /** + * Implementation of function OQS_SHA2_sha384_inc_ctx_release. + */ + void (*SHA2_sha384_inc_ctx_release)(OQS_SHA2_sha384_ctx *state); + + /** + * Implementation of function OQS_SHA2_sha512. + */ + void (*SHA2_sha512)(uint8_t *output, const uint8_t *input, size_t inplen); + + /** + * Implementation of function OQS_SHA2_sha512_inc_init. + */ + void (*SHA2_sha512_inc_init)(OQS_SHA2_sha512_ctx *state); + + /** + * Implementation of function OQS_SHA2_sha512_inc_ctx_clone. + */ + void (*SHA2_sha512_inc_ctx_clone)(OQS_SHA2_sha512_ctx *dest, const OQS_SHA2_sha512_ctx *src); + + /** + * Implementation of function OQS_SHA2_sha512_inc_blocks. + */ + void (*SHA2_sha512_inc_blocks)(OQS_SHA2_sha512_ctx *state, const uint8_t *in, size_t inblocks); + + /** + * Implementation of function OQS_SHA2_sha512_inc_finalize. + */ + void (*SHA2_sha512_inc_finalize)(uint8_t *out, OQS_SHA2_sha512_ctx *state, const uint8_t *in, size_t inlen); + + /** + * Implementation of function OQS_SHA2_sha512_inc_ctx_release. + */ + void (*SHA2_sha512_inc_ctx_release)(OQS_SHA2_sha512_ctx *state); +}; + +/** + * Set callback functions for SHA2 operations. + * + * This function may be called before OQS_init to switch the + * cryptographic provider for SHA2 operations. If it is not called, + * the default provider determined at build time will be used. + * + * @param[in] new_callbacks Callback functions defined in OQS_SHA2_callbacks + */ +OQS_API void OQS_SHA2_set_callbacks(struct OQS_SHA2_callbacks *new_callbacks); + #if defined(__cplusplus) } // extern "C" #endif diff --git a/src/common/sha2/sha2_impl.c b/src/common/sha2/sha2_impl.c new file mode 100644 index 00000000..f7f01b24 --- /dev/null +++ b/src/common/sha2/sha2_impl.c @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: MIT +#include + +#include + +#include "sha2.h" +#include "sha2_local.h" + +#if defined(OQS_DIST_ARM64_V8_BUILD) +#define C_OR_ARM(stmt_c, stmt_arm) \ + do { \ + if (OQS_CPU_has_extension(OQS_CPU_EXT_ARM_SHA2)) { \ + stmt_arm; \ + } else { \ + stmt_c; \ + } \ + } while(0) +#elif defined(OQS_USE_ARM_SHA2_INSTRUCTIONS) +#define C_OR_ARM(stmt_c, stmt_arm) \ + stmt_arm +#else +#define C_OR_ARM(stmt_c, stmt_arm) \ + stmt_c +#endif + +static void SHA2_sha256_inc_init(OQS_SHA2_sha256_ctx *state) { + oqs_sha2_sha256_inc_init_c((sha256ctx *) state); +} + +static void SHA2_sha256_inc_ctx_clone(OQS_SHA2_sha256_ctx *dest, const OQS_SHA2_sha256_ctx *src) { + oqs_sha2_sha256_inc_ctx_clone_c((sha256ctx *) dest, (const sha256ctx *) src); +} + +static void SHA2_sha256_inc_blocks(OQS_SHA2_sha256_ctx *state, const uint8_t *in, size_t inblocks) { + C_OR_ARM( + oqs_sha2_sha256_inc_blocks_c((sha256ctx *) state, in, inblocks), + oqs_sha2_sha256_inc_blocks_armv8((sha256ctx *) state, in, inblocks) + ); +} + +static void SHA2_sha256_inc_finalize(uint8_t *out, OQS_SHA2_sha256_ctx *state, const uint8_t *in, size_t inlen) { + oqs_sha2_sha256_inc_finalize_c(out, (sha256ctx *) state, in, inlen); +} + +static void SHA2_sha256_inc_ctx_release(OQS_SHA2_sha256_ctx *state) { + oqs_sha2_sha256_inc_ctx_release_c((sha256ctx *) state); +} + +static void SHA2_sha384_inc_init(OQS_SHA2_sha384_ctx *state) { + oqs_sha2_sha384_inc_init_c((sha384ctx *)state); +} + +static void SHA2_sha384_inc_ctx_clone(OQS_SHA2_sha384_ctx *dest, const OQS_SHA2_sha384_ctx *src) { + oqs_sha2_sha384_inc_ctx_clone_c((sha384ctx *) dest, (const sha384ctx *) src); +} + +static void SHA2_sha384_inc_blocks(OQS_SHA2_sha384_ctx *state, const uint8_t *in, size_t inblocks) { + oqs_sha2_sha384_inc_blocks_c((sha384ctx *) state, in, inblocks); +} + +static void SHA2_sha384_inc_finalize(uint8_t *out, OQS_SHA2_sha384_ctx *state, const uint8_t *in, size_t inlen) { + oqs_sha2_sha384_inc_finalize_c(out, (sha384ctx *) state, in, inlen); +} + +static void SHA2_sha384_inc_ctx_release(OQS_SHA2_sha384_ctx *state) { + oqs_sha2_sha384_inc_ctx_release_c((sha384ctx *) state); +} + +static void SHA2_sha512_inc_init(OQS_SHA2_sha512_ctx *state) { + oqs_sha2_sha512_inc_init_c((sha512ctx *)state); +} + +static void SHA2_sha512_inc_ctx_clone(OQS_SHA2_sha512_ctx *dest, const OQS_SHA2_sha512_ctx *src) { + oqs_sha2_sha512_inc_ctx_clone_c((sha512ctx *) dest, (const sha512ctx *) src); +} + +static void SHA2_sha512_inc_blocks(OQS_SHA2_sha512_ctx *state, const uint8_t *in, size_t inblocks) { + oqs_sha2_sha512_inc_blocks_c((sha512ctx *) state, in, inblocks); +} + +static void SHA2_sha512_inc_finalize(uint8_t *out, OQS_SHA2_sha512_ctx *state, const uint8_t *in, size_t inlen) { + oqs_sha2_sha512_inc_finalize_c(out, (sha512ctx *) state, in, inlen); +} + +static void SHA2_sha512_inc_ctx_release(OQS_SHA2_sha512_ctx *state) { + oqs_sha2_sha512_inc_ctx_release_c((sha512ctx *) state); +} + +static void SHA2_sha256(uint8_t *out, const uint8_t *in, size_t inlen) { + C_OR_ARM ( + oqs_sha2_sha256_c(out, in, inlen), + oqs_sha2_sha256_armv8(out, in, inlen) + ); +} + +static void SHA2_sha384(uint8_t *out, const uint8_t *in, size_t inlen) { + oqs_sha2_sha384_c(out, in, inlen); +} + +static void SHA2_sha512(uint8_t *out, const uint8_t *in, size_t inlen) { + oqs_sha2_sha512_c(out, in, inlen); +} + +struct OQS_SHA2_callbacks sha2_default_callbacks = { + SHA2_sha256, + SHA2_sha256_inc_init, + SHA2_sha256_inc_ctx_clone, + SHA2_sha256_inc_blocks, + SHA2_sha256_inc_finalize, + SHA2_sha256_inc_ctx_release, + SHA2_sha384, + SHA2_sha384_inc_init, + SHA2_sha384_inc_ctx_clone, + SHA2_sha384_inc_blocks, + SHA2_sha384_inc_finalize, + SHA2_sha384_inc_ctx_release, + SHA2_sha512, + SHA2_sha512_inc_init, + SHA2_sha512_inc_ctx_clone, + SHA2_sha512_inc_blocks, + SHA2_sha512_inc_finalize, + SHA2_sha512_inc_ctx_release, +}; diff --git a/src/common/sha2/sha2_local.h b/src/common/sha2/sha2_local.h index 028de764..dcb13928 100644 --- a/src/common/sha2/sha2_local.h +++ b/src/common/sha2/sha2_local.h @@ -79,6 +79,8 @@ void oqs_sha2_sha256_c(uint8_t *out, const uint8_t *in, size_t inlen); void oqs_sha2_sha384_c(uint8_t *out, const uint8_t *in, size_t inlen); void oqs_sha2_sha512_c(uint8_t *out, const uint8_t *in, size_t inlen); +extern struct OQS_SHA2_callbacks sha2_default_callbacks; + #if defined(__cplusplus) } // extern "C" #endif diff --git a/src/common/sha2/sha2_ossl.c b/src/common/sha2/sha2_ossl.c index c94a07b7..0953feb1 100644 --- a/src/common/sha2/sha2_ossl.c +++ b/src/common/sha2/sha2_ossl.c @@ -11,35 +11,34 @@ #include "sha2.h" -#include #include "../ossl_helpers.h" static void 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_new(); + mdctx = OSSL_FUNC(EVP_MD_CTX_new)(); OQS_EXIT_IF_NULLPTR(mdctx, "OpenSSL"); - OQS_OPENSSL_GUARD(EVP_DigestInit_ex(mdctx, md, NULL)); - OQS_OPENSSL_GUARD(EVP_DigestUpdate(mdctx, input, inplen)); - OQS_OPENSSL_GUARD(EVP_DigestFinal_ex(mdctx, output, &outlen)); - EVP_MD_CTX_free(mdctx); + OSSL_FUNC(EVP_DigestInit_ex)(mdctx, md, NULL); + OSSL_FUNC(EVP_DigestUpdate)(mdctx, input, inplen); + OSSL_FUNC(EVP_DigestFinal_ex)(mdctx, output, &outlen); + OSSL_FUNC(EVP_MD_CTX_free)(mdctx); } -void OQS_SHA2_sha256(uint8_t *output, const uint8_t *input, size_t inplen) { +static void SHA2_sha256(uint8_t *output, const uint8_t *input, size_t inplen) { const EVP_MD *md; md = oqs_sha256(); OQS_EXIT_IF_NULLPTR(md, "OpenSSL"); do_hash(output, input, inplen, md); } -void OQS_SHA2_sha384(uint8_t *output, const uint8_t *input, size_t inplen) { +static void SHA2_sha384(uint8_t *output, const uint8_t *input, size_t inplen) { const EVP_MD *md; md = oqs_sha384(); OQS_EXIT_IF_NULLPTR(md, "OpenSSL"); do_hash(output, input, inplen, md); } -void OQS_SHA2_sha512(uint8_t *output, const uint8_t *input, size_t inplen) { +static void SHA2_sha512(uint8_t *output, const uint8_t *input, size_t inplen) { const EVP_MD *md; md = oqs_sha512(); OQS_EXIT_IF_NULLPTR(md, "OpenSSL"); @@ -48,109 +47,127 @@ void OQS_SHA2_sha512(uint8_t *output, const uint8_t *input, size_t inplen) { #define SHA2_BLOCK_SIZE 64 -void OQS_SHA2_sha256_inc_init(OQS_SHA2_sha256_ctx *state) { +static void SHA2_sha256_inc_init(OQS_SHA2_sha256_ctx *state) { EVP_MD_CTX *mdctx; const EVP_MD *md = NULL; md = oqs_sha256(); OQS_EXIT_IF_NULLPTR(md, "OpenSSL"); - mdctx = EVP_MD_CTX_new(); + mdctx = OSSL_FUNC(EVP_MD_CTX_new)(); OQS_EXIT_IF_NULLPTR(mdctx, "OpenSSL"); - OQS_OPENSSL_GUARD(EVP_DigestInit_ex(mdctx, md, NULL)); + OQS_OPENSSL_GUARD(OSSL_FUNC(EVP_DigestInit_ex)(mdctx, md, NULL)); state->ctx = mdctx; } -void OQS_SHA2_sha256_inc_blocks(OQS_SHA2_sha256_ctx *state, const uint8_t *in, size_t inblocks) { - OQS_OPENSSL_GUARD(EVP_DigestUpdate((EVP_MD_CTX *) state->ctx, in, inblocks * SHA2_BLOCK_SIZE)); +static void SHA2_sha256_inc_blocks(OQS_SHA2_sha256_ctx *state, const uint8_t *in, size_t inblocks) { + OQS_OPENSSL_GUARD(OSSL_FUNC(EVP_DigestUpdate)((EVP_MD_CTX *) state->ctx, in, inblocks * SHA2_BLOCK_SIZE)); } -void OQS_SHA2_sha256_inc_finalize(uint8_t *out, OQS_SHA2_sha256_ctx *state, const uint8_t *in, size_t inlen) { +static void SHA2_sha256_inc_finalize(uint8_t *out, OQS_SHA2_sha256_ctx *state, const uint8_t *in, size_t inlen) { unsigned int md_len; if (inlen > 0) { - OQS_OPENSSL_GUARD(EVP_DigestUpdate((EVP_MD_CTX *) state->ctx, in, inlen)); + OQS_OPENSSL_GUARD(OSSL_FUNC(EVP_DigestUpdate)((EVP_MD_CTX *) state->ctx, in, inlen)); } - OQS_OPENSSL_GUARD(EVP_DigestFinal_ex((EVP_MD_CTX *) state->ctx, out, &md_len)); - EVP_MD_CTX_free((EVP_MD_CTX *) state->ctx); - state->ctx = NULL; + OQS_OPENSSL_GUARD(OSSL_FUNC(EVP_DigestFinal_ex)((EVP_MD_CTX *) state->ctx, out, &md_len)); + OSSL_FUNC(EVP_MD_CTX_free)((EVP_MD_CTX *) state->ctx); } -void OQS_SHA2_sha256_inc_ctx_release(OQS_SHA2_sha256_ctx *state) { - EVP_MD_CTX_destroy((EVP_MD_CTX *) state->ctx); +static void SHA2_sha256_inc_ctx_release(OQS_SHA2_sha256_ctx *state) { + OSSL_FUNC(EVP_MD_CTX_free)((EVP_MD_CTX *) state->ctx); state->ctx = NULL; } -void OQS_SHA2_sha256_inc_ctx_clone(OQS_SHA2_sha256_ctx *dest, const OQS_SHA2_sha256_ctx *src) { - OQS_SHA2_sha256_inc_init(dest); - OQS_OPENSSL_GUARD(EVP_MD_CTX_copy_ex((EVP_MD_CTX *) dest->ctx, (EVP_MD_CTX *) src->ctx)); +static void SHA2_sha256_inc_ctx_clone(OQS_SHA2_sha256_ctx *dest, const OQS_SHA2_sha256_ctx *src) { + SHA2_sha256_inc_init(dest); + OQS_OPENSSL_GUARD(OSSL_FUNC(EVP_MD_CTX_copy_ex)((EVP_MD_CTX *) dest->ctx, (EVP_MD_CTX *) src->ctx)); } -void OQS_SHA2_sha384_inc_init(OQS_SHA2_sha384_ctx *state) { +static void SHA2_sha384_inc_init(OQS_SHA2_sha384_ctx *state) { EVP_MD_CTX *mdctx; const EVP_MD *md = NULL; md = oqs_sha384(); OQS_EXIT_IF_NULLPTR(md, "OpenSSL"); - mdctx = EVP_MD_CTX_new(); + mdctx = OSSL_FUNC(EVP_MD_CTX_new)(); OQS_EXIT_IF_NULLPTR(mdctx, "OpenSSL"); - OQS_OPENSSL_GUARD(EVP_DigestInit_ex(mdctx, md, NULL)); + OQS_OPENSSL_GUARD(OSSL_FUNC(EVP_DigestInit_ex)(mdctx, md, NULL)); state->ctx = mdctx; } -void OQS_SHA2_sha384_inc_blocks(OQS_SHA2_sha384_ctx *state, const uint8_t *in, size_t inblocks) { - OQS_OPENSSL_GUARD(EVP_DigestUpdate((EVP_MD_CTX *) state->ctx, in, inblocks * 2 * SHA2_BLOCK_SIZE)); +static void SHA2_sha384_inc_blocks(OQS_SHA2_sha384_ctx *state, const uint8_t *in, size_t inblocks) { + OQS_OPENSSL_GUARD(OSSL_FUNC(EVP_DigestUpdate)((EVP_MD_CTX *) state->ctx, in, inblocks * SHA2_BLOCK_SIZE)); } -void OQS_SHA2_sha384_inc_finalize(uint8_t *out, OQS_SHA2_sha384_ctx *state, const uint8_t *in, size_t inlen) { +static void SHA2_sha384_inc_finalize(uint8_t *out, OQS_SHA2_sha384_ctx *state, const uint8_t *in, size_t inlen) { unsigned int md_len; if (inlen > 0) { - OQS_OPENSSL_GUARD(EVP_DigestUpdate((EVP_MD_CTX *) state->ctx, in, inlen)); + OQS_OPENSSL_GUARD(OSSL_FUNC(EVP_DigestUpdate)((EVP_MD_CTX *) state->ctx, in, inlen)); } - OQS_OPENSSL_GUARD(EVP_DigestFinal_ex((EVP_MD_CTX *) state->ctx, out, &md_len)); - EVP_MD_CTX_free((EVP_MD_CTX *) state->ctx); - state->ctx = NULL; + OQS_OPENSSL_GUARD(OSSL_FUNC(EVP_DigestFinal_ex)((EVP_MD_CTX *) state->ctx, out, &md_len)); + OSSL_FUNC(EVP_MD_CTX_free)((EVP_MD_CTX *) state->ctx); } -void OQS_SHA2_sha384_inc_ctx_release(OQS_SHA2_sha384_ctx *state) { - EVP_MD_CTX_destroy((EVP_MD_CTX *) state->ctx); +static void SHA2_sha384_inc_ctx_release(OQS_SHA2_sha384_ctx *state) { + OSSL_FUNC(EVP_MD_CTX_free)((EVP_MD_CTX *) state->ctx); state->ctx = NULL; } -void OQS_SHA2_sha384_inc_ctx_clone(OQS_SHA2_sha384_ctx *dest, const OQS_SHA2_sha384_ctx *src) { - OQS_SHA2_sha384_inc_init(dest); - OQS_OPENSSL_GUARD(EVP_MD_CTX_copy_ex((EVP_MD_CTX *) dest->ctx, (EVP_MD_CTX *) src->ctx)); +static void SHA2_sha384_inc_ctx_clone(OQS_SHA2_sha384_ctx *dest, const OQS_SHA2_sha384_ctx *src) { + SHA2_sha384_inc_init(dest); + OQS_OPENSSL_GUARD(OSSL_FUNC(EVP_MD_CTX_copy_ex)((EVP_MD_CTX *) dest->ctx, (EVP_MD_CTX *) src->ctx)); } -void OQS_SHA2_sha512_inc_init(OQS_SHA2_sha512_ctx *state) { +static void SHA2_sha512_inc_init(OQS_SHA2_sha512_ctx *state) { EVP_MD_CTX *mdctx; const EVP_MD *md = NULL; md = oqs_sha512(); OQS_EXIT_IF_NULLPTR(md, "OpenSSL"); - mdctx = EVP_MD_CTX_new(); + mdctx = OSSL_FUNC(EVP_MD_CTX_new)(); OQS_EXIT_IF_NULLPTR(mdctx, "OpenSSL"); - OQS_OPENSSL_GUARD(EVP_DigestInit_ex(mdctx, md, NULL)); + OQS_OPENSSL_GUARD(OSSL_FUNC(EVP_DigestInit_ex)(mdctx, md, NULL)); state->ctx = mdctx; } -void OQS_SHA2_sha512_inc_blocks(OQS_SHA2_sha512_ctx *state, const uint8_t *in, size_t inblocks) { - OQS_OPENSSL_GUARD(EVP_DigestUpdate((EVP_MD_CTX *) state->ctx, in, inblocks * 2 * SHA2_BLOCK_SIZE)); +static void SHA2_sha512_inc_blocks(OQS_SHA2_sha512_ctx *state, const uint8_t *in, size_t inblocks) { + OQS_OPENSSL_GUARD(OSSL_FUNC(EVP_DigestUpdate)((EVP_MD_CTX *) state->ctx, in, inblocks * 2 * SHA2_BLOCK_SIZE)); } -void OQS_SHA2_sha512_inc_finalize(uint8_t *out, OQS_SHA2_sha512_ctx *state, const uint8_t *in, size_t inlen) { +static void SHA2_sha512_inc_finalize(uint8_t *out, OQS_SHA2_sha512_ctx *state, const uint8_t *in, size_t inlen) { unsigned int md_len; if (inlen > 0) { - OQS_OPENSSL_GUARD(EVP_DigestUpdate((EVP_MD_CTX *) state->ctx, in, inlen)); + OQS_OPENSSL_GUARD(OSSL_FUNC(EVP_DigestUpdate)((EVP_MD_CTX *) state->ctx, in, inlen)); } - OQS_OPENSSL_GUARD(EVP_DigestFinal_ex((EVP_MD_CTX *) state->ctx, out, &md_len)); - EVP_MD_CTX_free((EVP_MD_CTX *) state->ctx); - state->ctx = NULL; + OQS_OPENSSL_GUARD(OSSL_FUNC(EVP_DigestFinal_ex)((EVP_MD_CTX *) state->ctx, out, &md_len)); + OSSL_FUNC(EVP_MD_CTX_free)((EVP_MD_CTX *) state->ctx); } -void OQS_SHA2_sha512_inc_ctx_release(OQS_SHA2_sha512_ctx *state) { - EVP_MD_CTX_destroy((EVP_MD_CTX *) state->ctx); +static void SHA2_sha512_inc_ctx_release(OQS_SHA2_sha512_ctx *state) { + OSSL_FUNC(EVP_MD_CTX_free)((EVP_MD_CTX *) state->ctx); state->ctx = NULL; } -void OQS_SHA2_sha512_inc_ctx_clone(OQS_SHA2_sha512_ctx *dest, const OQS_SHA2_sha512_ctx *src) { - OQS_SHA2_sha512_inc_init(dest); - OQS_OPENSSL_GUARD(EVP_MD_CTX_copy_ex((EVP_MD_CTX *) dest->ctx, (EVP_MD_CTX *) src->ctx)); -} +static void SHA2_sha512_inc_ctx_clone(OQS_SHA2_sha512_ctx *dest, const OQS_SHA2_sha512_ctx *src) { + SHA2_sha512_inc_init(dest); + OQS_OPENSSL_GUARD(OSSL_FUNC(EVP_MD_CTX_copy_ex)((EVP_MD_CTX *) dest->ctx, (EVP_MD_CTX *) src->ctx)); +} + +struct OQS_SHA2_callbacks sha2_default_callbacks = { + SHA2_sha256, + SHA2_sha256_inc_init, + SHA2_sha256_inc_ctx_clone, + SHA2_sha256_inc_blocks, + SHA2_sha256_inc_finalize, + SHA2_sha256_inc_ctx_release, + SHA2_sha384, + SHA2_sha384_inc_init, + SHA2_sha384_inc_ctx_clone, + SHA2_sha384_inc_blocks, + SHA2_sha384_inc_finalize, + SHA2_sha384_inc_ctx_release, + SHA2_sha512, + SHA2_sha512_inc_init, + SHA2_sha512_inc_ctx_clone, + SHA2_sha512_inc_blocks, + SHA2_sha512_inc_finalize, + SHA2_sha512_inc_ctx_release, +}; #endif diff --git a/src/common/sha3/ossl_sha3.c b/src/common/sha3/ossl_sha3.c index 8b8678a2..de95fc39 100644 --- a/src/common/sha3/ossl_sha3.c +++ b/src/common/sha3/ossl_sha3.c @@ -11,136 +11,135 @@ #include "sha3.h" -#include #include "../ossl_helpers.h" #include static void do_hash(uint8_t *output, const uint8_t *input, size_t inplen, const EVP_MD *md) { EVP_MD_CTX *mdctx; - mdctx = EVP_MD_CTX_new(); - EVP_DigestInit_ex(mdctx, md, NULL); - EVP_DigestUpdate(mdctx, input, inplen); - EVP_DigestFinal_ex(mdctx, output, NULL); - EVP_MD_CTX_free(mdctx); + mdctx = OSSL_FUNC(EVP_MD_CTX_new)(); + OSSL_FUNC(EVP_DigestInit_ex)(mdctx, md, NULL); + OSSL_FUNC(EVP_DigestUpdate)(mdctx, input, inplen); + OSSL_FUNC(EVP_DigestFinal_ex)(mdctx, output, NULL); + OSSL_FUNC(EVP_MD_CTX_free)(mdctx); } static void do_xof(uint8_t *output, size_t outlen, const uint8_t *input, size_t inplen, const EVP_MD *md) { EVP_MD_CTX *mdctx; - mdctx = EVP_MD_CTX_new(); - EVP_DigestInit_ex(mdctx, md, NULL); - EVP_DigestUpdate(mdctx, input, inplen); - EVP_DigestFinalXOF(mdctx, output, outlen); - EVP_MD_CTX_free(mdctx); + mdctx = OSSL_FUNC(EVP_MD_CTX_new)(); + OSSL_FUNC(EVP_DigestInit_ex)(mdctx, md, NULL); + OSSL_FUNC(EVP_DigestUpdate)(mdctx, input, inplen); + OSSL_FUNC(EVP_DigestFinalXOF)(mdctx, output, outlen); + OSSL_FUNC(EVP_MD_CTX_free)(mdctx); } /* SHA3-256 */ -void OQS_SHA3_sha3_256(uint8_t *output, const uint8_t *input, size_t inplen) { +static void SHA3_sha3_256(uint8_t *output, const uint8_t *input, size_t inplen) { do_hash(output, input, inplen, oqs_sha3_256()); } /* SHA3-256 incremental */ -void OQS_SHA3_sha3_256_inc_init(OQS_SHA3_sha3_256_inc_ctx *state) { - state->ctx = EVP_MD_CTX_new(); +static void SHA3_sha3_256_inc_init(OQS_SHA3_sha3_256_inc_ctx *state) { + state->ctx = OSSL_FUNC(EVP_MD_CTX_new)(); EVP_MD_CTX *s = (EVP_MD_CTX *)state->ctx; - EVP_DigestInit_ex(s, oqs_sha3_256(), NULL); + OSSL_FUNC(EVP_DigestInit_ex)(s, oqs_sha3_256(), NULL); } -void OQS_SHA3_sha3_256_inc_absorb(OQS_SHA3_sha3_256_inc_ctx *state, const uint8_t *input, size_t inplen) { - EVP_DigestUpdate((EVP_MD_CTX *)state->ctx, input, inplen); +static void SHA3_sha3_256_inc_absorb(OQS_SHA3_sha3_256_inc_ctx *state, const uint8_t *input, size_t inplen) { + OSSL_FUNC(EVP_DigestUpdate)((EVP_MD_CTX *)state->ctx, input, inplen); } -void OQS_SHA3_sha3_256_inc_finalize(uint8_t *output, OQS_SHA3_sha3_256_inc_ctx *state) { - EVP_DigestFinal_ex((EVP_MD_CTX *)state->ctx, output, NULL); +static void SHA3_sha3_256_inc_finalize(uint8_t *output, OQS_SHA3_sha3_256_inc_ctx *state) { + OSSL_FUNC(EVP_DigestFinal_ex)((EVP_MD_CTX *)state->ctx, output, NULL); } -void OQS_SHA3_sha3_256_inc_ctx_release(OQS_SHA3_sha3_256_inc_ctx *state) { - EVP_MD_CTX_free((EVP_MD_CTX *)state->ctx); +static void SHA3_sha3_256_inc_ctx_release(OQS_SHA3_sha3_256_inc_ctx *state) { + OSSL_FUNC(EVP_MD_CTX_free)((EVP_MD_CTX *)state->ctx); } -void OQS_SHA3_sha3_256_inc_ctx_clone(OQS_SHA3_sha3_256_inc_ctx *dest, const OQS_SHA3_sha3_256_inc_ctx *src) { - EVP_MD_CTX_copy_ex((EVP_MD_CTX *)dest->ctx, (EVP_MD_CTX *)src->ctx); +static void SHA3_sha3_256_inc_ctx_clone(OQS_SHA3_sha3_256_inc_ctx *dest, const OQS_SHA3_sha3_256_inc_ctx *src) { + OSSL_FUNC(EVP_MD_CTX_copy_ex)((EVP_MD_CTX *)dest->ctx, (EVP_MD_CTX *)src->ctx); } -void OQS_SHA3_sha3_256_inc_ctx_reset(OQS_SHA3_sha3_256_inc_ctx *state) { +static void SHA3_sha3_256_inc_ctx_reset(OQS_SHA3_sha3_256_inc_ctx *state) { EVP_MD_CTX *s = state->ctx; - EVP_MD_CTX_reset(s); - EVP_DigestInit_ex(s, oqs_sha3_256(), NULL); + OSSL_FUNC(EVP_MD_CTX_reset)(s); + OSSL_FUNC(EVP_DigestInit_ex)(s, oqs_sha3_256(), NULL); } /* SHA3-384 */ -void OQS_SHA3_sha3_384(uint8_t *output, const uint8_t *input, size_t inplen) { +static void SHA3_sha3_384(uint8_t *output, const uint8_t *input, size_t inplen) { do_hash(output, input, inplen, oqs_sha3_384()); } /* SHA3-384 incremental */ -void OQS_SHA3_sha3_384_inc_init(OQS_SHA3_sha3_384_inc_ctx *state) { - state->ctx = EVP_MD_CTX_new(); - EVP_DigestInit_ex((EVP_MD_CTX *)state->ctx, oqs_sha3_384(), NULL); +static void SHA3_sha3_384_inc_init(OQS_SHA3_sha3_384_inc_ctx *state) { + state->ctx = OSSL_FUNC(EVP_MD_CTX_new)(); + OSSL_FUNC(EVP_DigestInit_ex)((EVP_MD_CTX *)state->ctx, oqs_sha3_384(), NULL); } -void OQS_SHA3_sha3_384_inc_absorb(OQS_SHA3_sha3_384_inc_ctx *state, const uint8_t *input, size_t inplen) { - EVP_DigestUpdate((EVP_MD_CTX *)state->ctx, input, inplen); +static void SHA3_sha3_384_inc_absorb(OQS_SHA3_sha3_384_inc_ctx *state, const uint8_t *input, size_t inplen) { + OSSL_FUNC(EVP_DigestUpdate)((EVP_MD_CTX *)state->ctx, input, inplen); } -void OQS_SHA3_sha3_384_inc_finalize(uint8_t *output, OQS_SHA3_sha3_384_inc_ctx *state) { - EVP_DigestFinal_ex((EVP_MD_CTX *)state->ctx, output, NULL); +static void SHA3_sha3_384_inc_finalize(uint8_t *output, OQS_SHA3_sha3_384_inc_ctx *state) { + OSSL_FUNC(EVP_DigestFinal_ex)((EVP_MD_CTX *)state->ctx, output, NULL); } -void OQS_SHA3_sha3_384_inc_ctx_release(OQS_SHA3_sha3_384_inc_ctx *state) { - EVP_MD_CTX_free((EVP_MD_CTX *)state->ctx); +static void SHA3_sha3_384_inc_ctx_release(OQS_SHA3_sha3_384_inc_ctx *state) { + OSSL_FUNC(EVP_MD_CTX_free)((EVP_MD_CTX *)state->ctx); } -void OQS_SHA3_sha3_384_inc_ctx_clone(OQS_SHA3_sha3_384_inc_ctx *dest, const OQS_SHA3_sha3_384_inc_ctx *src) { - EVP_MD_CTX_copy_ex((EVP_MD_CTX *)dest->ctx, (EVP_MD_CTX *)src->ctx); +static void SHA3_sha3_384_inc_ctx_clone(OQS_SHA3_sha3_384_inc_ctx *dest, const OQS_SHA3_sha3_384_inc_ctx *src) { + OSSL_FUNC(EVP_MD_CTX_copy_ex)((EVP_MD_CTX *)dest->ctx, (EVP_MD_CTX *)src->ctx); } -void OQS_SHA3_sha3_384_inc_ctx_reset(OQS_SHA3_sha3_384_inc_ctx *state) { +static void SHA3_sha3_384_inc_ctx_reset(OQS_SHA3_sha3_384_inc_ctx *state) { EVP_MD_CTX *s = state->ctx; - EVP_MD_CTX_reset(s); - EVP_DigestInit_ex(s, oqs_sha3_384(), NULL); + OSSL_FUNC(EVP_MD_CTX_reset)(s); + OSSL_FUNC(EVP_DigestInit_ex)(s, oqs_sha3_384(), NULL); } /* SHA3-512 */ -void OQS_SHA3_sha3_512(uint8_t *output, const uint8_t *input, size_t inplen) { +static void SHA3_sha3_512(uint8_t *output, const uint8_t *input, size_t inplen) { do_hash(output, input, inplen, oqs_sha3_512()); } /* SHA3-512 incremental */ -void OQS_SHA3_sha3_512_inc_init(OQS_SHA3_sha3_512_inc_ctx *state) { - state->ctx = EVP_MD_CTX_new(); - EVP_DigestInit_ex((EVP_MD_CTX *)state->ctx, oqs_sha3_512(), NULL); +static void SHA3_sha3_512_inc_init(OQS_SHA3_sha3_512_inc_ctx *state) { + state->ctx = OSSL_FUNC(EVP_MD_CTX_new)(); + OSSL_FUNC(EVP_DigestInit_ex)((EVP_MD_CTX *)state->ctx, oqs_sha3_512(), NULL); } -void OQS_SHA3_sha3_512_inc_absorb(OQS_SHA3_sha3_512_inc_ctx *state, const uint8_t *input, size_t inplen) { - EVP_DigestUpdate((EVP_MD_CTX *)state->ctx, input, inplen); +static void SHA3_sha3_512_inc_absorb(OQS_SHA3_sha3_512_inc_ctx *state, const uint8_t *input, size_t inplen) { + OSSL_FUNC(EVP_DigestUpdate)((EVP_MD_CTX *)state->ctx, input, inplen); } -void OQS_SHA3_sha3_512_inc_finalize(uint8_t *output, OQS_SHA3_sha3_512_inc_ctx *state) { - EVP_DigestFinal_ex((EVP_MD_CTX *)state->ctx, output, NULL); +static void SHA3_sha3_512_inc_finalize(uint8_t *output, OQS_SHA3_sha3_512_inc_ctx *state) { + OSSL_FUNC(EVP_DigestFinal_ex)((EVP_MD_CTX *)state->ctx, output, NULL); } -void OQS_SHA3_sha3_512_inc_ctx_release(OQS_SHA3_sha3_512_inc_ctx *state) { - EVP_MD_CTX_free((EVP_MD_CTX *)state->ctx); +static void SHA3_sha3_512_inc_ctx_release(OQS_SHA3_sha3_512_inc_ctx *state) { + OSSL_FUNC(EVP_MD_CTX_free)((EVP_MD_CTX *)state->ctx); } -void OQS_SHA3_sha3_512_inc_ctx_clone(OQS_SHA3_sha3_512_inc_ctx *dest, const OQS_SHA3_sha3_512_inc_ctx *src) { - EVP_MD_CTX_copy_ex((EVP_MD_CTX *)dest->ctx, (EVP_MD_CTX *)src->ctx); +static void SHA3_sha3_512_inc_ctx_clone(OQS_SHA3_sha3_512_inc_ctx *dest, const OQS_SHA3_sha3_512_inc_ctx *src) { + OSSL_FUNC(EVP_MD_CTX_copy_ex)((EVP_MD_CTX *)dest->ctx, (EVP_MD_CTX *)src->ctx); } -void OQS_SHA3_sha3_512_inc_ctx_reset(OQS_SHA3_sha3_512_inc_ctx *state) { +static void SHA3_sha3_512_inc_ctx_reset(OQS_SHA3_sha3_512_inc_ctx *state) { EVP_MD_CTX *s = state->ctx; - EVP_MD_CTX_reset(s); - EVP_DigestInit_ex(s, oqs_sha3_512(), NULL); + OSSL_FUNC(EVP_MD_CTX_reset)(s); + OSSL_FUNC(EVP_DigestInit_ex)(s, oqs_sha3_512(), NULL); } /* SHAKE-128 */ -void OQS_SHA3_shake128(uint8_t *output, size_t outlen, const uint8_t *input, size_t inplen) { +static void SHA3_shake128(uint8_t *output, size_t outlen, const uint8_t *input, size_t inplen) { do_xof(output, outlen, input, inplen, oqs_shake128()); } @@ -166,70 +165,70 @@ typedef struct { size_t n_out; } intrn_shake128_inc_ctx; -void OQS_SHA3_shake128_inc_init(OQS_SHA3_shake128_inc_ctx *state) { +static void SHA3_shake128_inc_init(OQS_SHA3_shake128_inc_ctx *state) { state->ctx = malloc(sizeof(intrn_shake128_inc_ctx)); intrn_shake128_inc_ctx *s = (intrn_shake128_inc_ctx *)state->ctx; - s->mdctx = EVP_MD_CTX_new(); + s->mdctx = OSSL_FUNC(EVP_MD_CTX_new)(); s->n_out = 0; - EVP_DigestInit_ex(s->mdctx, oqs_shake128(), NULL); + OSSL_FUNC(EVP_DigestInit_ex)(s->mdctx, oqs_shake128(), NULL); } -void OQS_SHA3_shake128_inc_absorb(OQS_SHA3_shake128_inc_ctx *state, const uint8_t *input, size_t inplen) { +static void SHA3_shake128_inc_absorb(OQS_SHA3_shake128_inc_ctx *state, const uint8_t *input, size_t inplen) { intrn_shake128_inc_ctx *s = (intrn_shake128_inc_ctx *)state->ctx; - EVP_DigestUpdate(s->mdctx, input, inplen); + OSSL_FUNC(EVP_DigestUpdate)(s->mdctx, input, inplen); } -void OQS_SHA3_shake128_inc_finalize(OQS_SHA3_shake128_inc_ctx *state) { +static void SHA3_shake128_inc_finalize(OQS_SHA3_shake128_inc_ctx *state) { (void)state; } -void OQS_SHA3_shake128_inc_squeeze(uint8_t *output, size_t outlen, OQS_SHA3_shake128_inc_ctx *state) { +static void SHA3_shake128_inc_squeeze(uint8_t *output, size_t outlen, OQS_SHA3_shake128_inc_ctx *state) { intrn_shake128_inc_ctx *s = (intrn_shake128_inc_ctx *)state->ctx; EVP_MD_CTX *clone; - clone = EVP_MD_CTX_new(); - EVP_DigestInit_ex(clone, oqs_shake128(), NULL); - EVP_MD_CTX_copy_ex(clone, s->mdctx); + clone = OSSL_FUNC(EVP_MD_CTX_new)(); + OSSL_FUNC(EVP_DigestInit_ex)(clone, oqs_shake128(), NULL); + OSSL_FUNC(EVP_MD_CTX_copy_ex)(clone, s->mdctx); if (s->n_out == 0) { - EVP_DigestFinalXOF(clone, output, outlen); + OSSL_FUNC(EVP_DigestFinalXOF)(clone, output, outlen); } else { uint8_t *tmp; tmp = malloc(s->n_out + outlen); if (tmp == NULL) { exit(111); } - EVP_DigestFinalXOF(clone, tmp, s->n_out + outlen); + OSSL_FUNC(EVP_DigestFinalXOF)(clone, tmp, s->n_out + outlen); memcpy(output, tmp + s->n_out, outlen); free(tmp); // IGNORE free-check } - EVP_MD_CTX_free(clone); + OSSL_FUNC(EVP_MD_CTX_free)(clone); s->n_out += outlen; } -void OQS_SHA3_shake128_inc_ctx_release(OQS_SHA3_shake128_inc_ctx *state) { +static void SHA3_shake128_inc_ctx_release(OQS_SHA3_shake128_inc_ctx *state) { intrn_shake128_inc_ctx *s = (intrn_shake128_inc_ctx *)state->ctx; - EVP_MD_CTX_free(s->mdctx); + OSSL_FUNC(EVP_MD_CTX_free)(s->mdctx); free(s); // IGNORE free-check } -void OQS_SHA3_shake128_inc_ctx_clone(OQS_SHA3_shake128_inc_ctx *dest, const OQS_SHA3_shake128_inc_ctx *src) { +static void SHA3_shake128_inc_ctx_clone(OQS_SHA3_shake128_inc_ctx *dest, const OQS_SHA3_shake128_inc_ctx *src) { intrn_shake128_inc_ctx *s = (intrn_shake128_inc_ctx *)src->ctx; intrn_shake128_inc_ctx *d = (intrn_shake128_inc_ctx *)dest->ctx; - EVP_MD_CTX_copy_ex(d->mdctx, s->mdctx); + OSSL_FUNC(EVP_MD_CTX_copy_ex)(d->mdctx, s->mdctx); d->n_out = s->n_out; } -void OQS_SHA3_shake128_inc_ctx_reset(OQS_SHA3_shake128_inc_ctx *state) { +static void SHA3_shake128_inc_ctx_reset(OQS_SHA3_shake128_inc_ctx *state) { intrn_shake128_inc_ctx *s = (intrn_shake128_inc_ctx *)state->ctx; - EVP_MD_CTX_reset(s->mdctx); - EVP_DigestInit_ex(s->mdctx, oqs_shake128(), NULL); + OSSL_FUNC(EVP_MD_CTX_reset)(s->mdctx); + OSSL_FUNC(EVP_DigestInit_ex)(s->mdctx, oqs_shake128(), NULL); s->n_out = 0; } /* SHAKE-256 */ -void OQS_SHA3_shake256(uint8_t *output, size_t outlen, const uint8_t *input, size_t inplen) { +static void SHA3_shake256(uint8_t *output, size_t outlen, const uint8_t *input, size_t inplen) { do_xof(output, outlen, input, inplen, oqs_shake256()); } @@ -243,65 +242,107 @@ typedef struct { size_t n_out; } intrn_shake256_inc_ctx; -void OQS_SHA3_shake256_inc_init(OQS_SHA3_shake256_inc_ctx *state) { +static void SHA3_shake256_inc_init(OQS_SHA3_shake256_inc_ctx *state) { state->ctx = malloc(sizeof(intrn_shake256_inc_ctx)); intrn_shake256_inc_ctx *s = (intrn_shake256_inc_ctx *)state->ctx; - s->mdctx = EVP_MD_CTX_new(); + s->mdctx = OSSL_FUNC(EVP_MD_CTX_new)(); s->n_out = 0; - EVP_DigestInit_ex(s->mdctx, oqs_shake256(), NULL); + OSSL_FUNC(EVP_DigestInit_ex)(s->mdctx, oqs_shake256(), NULL); } -void OQS_SHA3_shake256_inc_absorb(OQS_SHA3_shake256_inc_ctx *state, const uint8_t *input, size_t inplen) { +static void SHA3_shake256_inc_absorb(OQS_SHA3_shake256_inc_ctx *state, const uint8_t *input, size_t inplen) { intrn_shake256_inc_ctx *s = (intrn_shake256_inc_ctx *)state->ctx; - EVP_DigestUpdate(s->mdctx, input, inplen); + OSSL_FUNC(EVP_DigestUpdate)(s->mdctx, input, inplen); } -void OQS_SHA3_shake256_inc_finalize(OQS_SHA3_shake256_inc_ctx *state) { +static void SHA3_shake256_inc_finalize(OQS_SHA3_shake256_inc_ctx *state) { (void)state; } -void OQS_SHA3_shake256_inc_squeeze(uint8_t *output, size_t outlen, OQS_SHA3_shake256_inc_ctx *state) { +static void SHA3_shake256_inc_squeeze(uint8_t *output, size_t outlen, OQS_SHA3_shake256_inc_ctx *state) { intrn_shake256_inc_ctx *s = (intrn_shake256_inc_ctx *)state->ctx; EVP_MD_CTX *clone; - clone = EVP_MD_CTX_new(); - EVP_DigestInit_ex(clone, oqs_shake256(), NULL); - EVP_MD_CTX_copy_ex(clone, s->mdctx); + clone = OSSL_FUNC(EVP_MD_CTX_new)(); + OSSL_FUNC(EVP_DigestInit_ex)(clone, oqs_shake256(), NULL); + OSSL_FUNC(EVP_MD_CTX_copy_ex)(clone, s->mdctx); if (s->n_out == 0) { - EVP_DigestFinalXOF(clone, output, outlen); + OSSL_FUNC(EVP_DigestFinalXOF)(clone, output, outlen); } else { uint8_t *tmp; tmp = malloc(s->n_out + outlen); if (tmp == NULL) { exit(111); } - EVP_DigestFinalXOF(clone, tmp, s->n_out + outlen); + OSSL_FUNC(EVP_DigestFinalXOF)(clone, tmp, s->n_out + outlen); memcpy(output, tmp + s->n_out, outlen); free(tmp); // IGNORE free-check } - EVP_MD_CTX_free(clone); + OSSL_FUNC(EVP_MD_CTX_free)(clone); s->n_out += outlen; } -void OQS_SHA3_shake256_inc_ctx_release(OQS_SHA3_shake256_inc_ctx *state) { +static void SHA3_shake256_inc_ctx_release(OQS_SHA3_shake256_inc_ctx *state) { intrn_shake256_inc_ctx *s = (intrn_shake256_inc_ctx *)state->ctx; - EVP_MD_CTX_free(s->mdctx); + OSSL_FUNC(EVP_MD_CTX_free)(s->mdctx); free(s); // IGNORE free-check } -void OQS_SHA3_shake256_inc_ctx_clone(OQS_SHA3_shake256_inc_ctx *dest, const OQS_SHA3_shake256_inc_ctx *src) { +static void SHA3_shake256_inc_ctx_clone(OQS_SHA3_shake256_inc_ctx *dest, const OQS_SHA3_shake256_inc_ctx *src) { intrn_shake256_inc_ctx *s = (intrn_shake256_inc_ctx *)src->ctx; intrn_shake256_inc_ctx *d = (intrn_shake256_inc_ctx *)dest->ctx; - EVP_MD_CTX_copy_ex(d->mdctx, s->mdctx); + OSSL_FUNC(EVP_MD_CTX_copy_ex)(d->mdctx, s->mdctx); d->n_out = s->n_out; } -void OQS_SHA3_shake256_inc_ctx_reset(OQS_SHA3_shake256_inc_ctx *state) { +static void SHA3_shake256_inc_ctx_reset(OQS_SHA3_shake256_inc_ctx *state) { intrn_shake256_inc_ctx *s = (intrn_shake256_inc_ctx *)state->ctx; - EVP_MD_CTX_reset(s->mdctx); - EVP_DigestInit_ex(s->mdctx, oqs_shake256(), NULL); + OSSL_FUNC(EVP_MD_CTX_reset)(s->mdctx); + OSSL_FUNC(EVP_DigestInit_ex)(s->mdctx, oqs_shake256(), NULL); s->n_out = 0; } +extern struct OQS_SHA3_callbacks sha3_default_callbacks; + +struct OQS_SHA3_callbacks sha3_default_callbacks = { + SHA3_sha3_256, + SHA3_sha3_256_inc_init, + SHA3_sha3_256_inc_absorb, + SHA3_sha3_256_inc_finalize, + SHA3_sha3_256_inc_ctx_release, + SHA3_sha3_256_inc_ctx_reset, + SHA3_sha3_256_inc_ctx_clone, + SHA3_sha3_384, + SHA3_sha3_384_inc_init, + SHA3_sha3_384_inc_absorb, + SHA3_sha3_384_inc_finalize, + SHA3_sha3_384_inc_ctx_release, + SHA3_sha3_384_inc_ctx_reset, + SHA3_sha3_384_inc_ctx_clone, + SHA3_sha3_512, + SHA3_sha3_512_inc_init, + SHA3_sha3_512_inc_absorb, + SHA3_sha3_512_inc_finalize, + SHA3_sha3_512_inc_ctx_release, + SHA3_sha3_512_inc_ctx_reset, + SHA3_sha3_512_inc_ctx_clone, + SHA3_shake128, + SHA3_shake128_inc_init, + SHA3_shake128_inc_absorb, + SHA3_shake128_inc_finalize, + SHA3_shake128_inc_squeeze, + SHA3_shake128_inc_ctx_release, + SHA3_shake128_inc_ctx_clone, + SHA3_shake128_inc_ctx_reset, + SHA3_shake256, + SHA3_shake256_inc_init, + SHA3_shake256_inc_absorb, + SHA3_shake256_inc_finalize, + SHA3_shake256_inc_squeeze, + SHA3_shake256_inc_ctx_release, + SHA3_shake256_inc_ctx_clone, + SHA3_shake256_inc_ctx_reset, +}; + #endif diff --git a/src/common/sha3/ossl_sha3x4.c b/src/common/sha3/ossl_sha3x4.c index 1e469720..fec62ad6 100644 --- a/src/common/sha3/ossl_sha3x4.c +++ b/src/common/sha3/ossl_sha3x4.c @@ -14,8 +14,8 @@ /* SHAKE-128 */ -void OQS_SHA3_shake128_x4(uint8_t *output0, uint8_t *output1, uint8_t *output2, uint8_t *output3, size_t outlen, - const uint8_t *in0, const uint8_t *in1, const uint8_t *in2, const uint8_t *in3, size_t inplen) { +static void SHA3_shake128_x4(uint8_t *output0, uint8_t *output1, uint8_t *output2, uint8_t *output3, size_t outlen, + const uint8_t *in0, const uint8_t *in1, const uint8_t *in2, const uint8_t *in3, size_t inplen) { OQS_SHA3_shake128(output0, outlen, in0, inplen); OQS_SHA3_shake128(output1, outlen, in1, inplen); OQS_SHA3_shake128(output2, outlen, in2, inplen); @@ -32,108 +32,108 @@ typedef struct { size_t n_out; } intrn_shake128_x4_inc_ctx; -void OQS_SHA3_shake128_x4_inc_init(OQS_SHA3_shake128_x4_inc_ctx *state) { +static void SHA3_shake128_x4_inc_init(OQS_SHA3_shake128_x4_inc_ctx *state) { state->ctx = malloc(sizeof(intrn_shake128_x4_inc_ctx)); intrn_shake128_x4_inc_ctx *s = (intrn_shake128_x4_inc_ctx *)state->ctx; - s->mdctx0 = EVP_MD_CTX_new(); - s->mdctx1 = EVP_MD_CTX_new(); - s->mdctx2 = EVP_MD_CTX_new(); - s->mdctx3 = EVP_MD_CTX_new(); - EVP_DigestInit_ex(s->mdctx0, oqs_shake128(), NULL); - EVP_DigestInit_ex(s->mdctx1, oqs_shake128(), NULL); - EVP_DigestInit_ex(s->mdctx2, oqs_shake128(), NULL); - EVP_DigestInit_ex(s->mdctx3, oqs_shake128(), NULL); + s->mdctx0 = OSSL_FUNC(EVP_MD_CTX_new)(); + s->mdctx1 = OSSL_FUNC(EVP_MD_CTX_new)(); + s->mdctx2 = OSSL_FUNC(EVP_MD_CTX_new)(); + s->mdctx3 = OSSL_FUNC(EVP_MD_CTX_new)(); + OSSL_FUNC(EVP_DigestInit_ex)(s->mdctx0, oqs_shake128(), NULL); + OSSL_FUNC(EVP_DigestInit_ex)(s->mdctx1, oqs_shake128(), NULL); + OSSL_FUNC(EVP_DigestInit_ex)(s->mdctx2, oqs_shake128(), NULL); + OSSL_FUNC(EVP_DigestInit_ex)(s->mdctx3, oqs_shake128(), NULL); s->n_out = 0; } -void OQS_SHA3_shake128_x4_inc_absorb(OQS_SHA3_shake128_x4_inc_ctx *state, const uint8_t *in0, const uint8_t *in1, const uint8_t *in2, const uint8_t *in3, size_t inplen) { +static void SHA3_shake128_x4_inc_absorb(OQS_SHA3_shake128_x4_inc_ctx *state, const uint8_t *in0, const uint8_t *in1, const uint8_t *in2, const uint8_t *in3, size_t inplen) { intrn_shake128_x4_inc_ctx *s = (intrn_shake128_x4_inc_ctx *)state->ctx; - EVP_DigestUpdate(s->mdctx0, in0, inplen); - EVP_DigestUpdate(s->mdctx1, in1, inplen); - EVP_DigestUpdate(s->mdctx2, in2, inplen); - EVP_DigestUpdate(s->mdctx3, in3, inplen); + OSSL_FUNC(EVP_DigestUpdate)(s->mdctx0, in0, inplen); + OSSL_FUNC(EVP_DigestUpdate)(s->mdctx1, in1, inplen); + OSSL_FUNC(EVP_DigestUpdate)(s->mdctx2, in2, inplen); + OSSL_FUNC(EVP_DigestUpdate)(s->mdctx3, in3, inplen); } -void OQS_SHA3_shake128_x4_inc_finalize(OQS_SHA3_shake128_x4_inc_ctx *state) { +static void SHA3_shake128_x4_inc_finalize(OQS_SHA3_shake128_x4_inc_ctx *state) { (void)state; } -void OQS_SHA3_shake128_x4_inc_squeeze(uint8_t *out0, uint8_t *out1, uint8_t *out2, uint8_t *out3, size_t outlen, OQS_SHA3_shake128_x4_inc_ctx *state) { +static void SHA3_shake128_x4_inc_squeeze(uint8_t *out0, uint8_t *out1, uint8_t *out2, uint8_t *out3, size_t outlen, OQS_SHA3_shake128_x4_inc_ctx *state) { intrn_shake128_x4_inc_ctx *s = (intrn_shake128_x4_inc_ctx *)state->ctx; EVP_MD_CTX *clone; - clone = EVP_MD_CTX_new(); - EVP_DigestInit_ex(clone, oqs_shake128(), NULL); + clone = OSSL_FUNC(EVP_MD_CTX_new)(); + OSSL_FUNC(EVP_DigestInit_ex)(clone, oqs_shake128(), NULL); if (s->n_out == 0) { - EVP_MD_CTX_copy_ex(clone, s->mdctx0); - EVP_DigestFinalXOF(clone, out0, outlen); - EVP_MD_CTX_copy_ex(clone, s->mdctx1); - EVP_DigestFinalXOF(clone, out1, outlen); - EVP_MD_CTX_copy_ex(clone, s->mdctx2); - EVP_DigestFinalXOF(clone, out2, outlen); - EVP_MD_CTX_copy_ex(clone, s->mdctx3); - EVP_DigestFinalXOF(clone, out3, outlen); + OSSL_FUNC(EVP_MD_CTX_copy_ex)(clone, s->mdctx0); + OSSL_FUNC(EVP_DigestFinalXOF)(clone, out0, outlen); + OSSL_FUNC(EVP_MD_CTX_copy_ex)(clone, s->mdctx1); + OSSL_FUNC(EVP_DigestFinalXOF)(clone, out1, outlen); + OSSL_FUNC(EVP_MD_CTX_copy_ex)(clone, s->mdctx2); + OSSL_FUNC(EVP_DigestFinalXOF)(clone, out2, outlen); + OSSL_FUNC(EVP_MD_CTX_copy_ex)(clone, s->mdctx3); + OSSL_FUNC(EVP_DigestFinalXOF)(clone, out3, outlen); } else { uint8_t *tmp; tmp = malloc(s->n_out + outlen); if (tmp == NULL) { exit(111); } - EVP_MD_CTX_copy_ex(clone, s->mdctx0); - EVP_DigestFinalXOF(clone, tmp, s->n_out + outlen); + OSSL_FUNC(EVP_MD_CTX_copy_ex)(clone, s->mdctx0); + OSSL_FUNC(EVP_DigestFinalXOF)(clone, tmp, s->n_out + outlen); memcpy(out0, tmp + s->n_out, outlen); - EVP_MD_CTX_copy_ex(clone, s->mdctx1); - EVP_DigestFinalXOF(clone, tmp, s->n_out + outlen); + OSSL_FUNC(EVP_MD_CTX_copy_ex)(clone, s->mdctx1); + OSSL_FUNC(EVP_DigestFinalXOF)(clone, tmp, s->n_out + outlen); memcpy(out1, tmp + s->n_out, outlen); - EVP_MD_CTX_copy_ex(clone, s->mdctx2); - EVP_DigestFinalXOF(clone, tmp, s->n_out + outlen); + OSSL_FUNC(EVP_MD_CTX_copy_ex)(clone, s->mdctx2); + OSSL_FUNC(EVP_DigestFinalXOF)(clone, tmp, s->n_out + outlen); memcpy(out2, tmp + s->n_out, outlen); - EVP_MD_CTX_copy_ex(clone, s->mdctx3); - EVP_DigestFinalXOF(clone, tmp, s->n_out + outlen); + OSSL_FUNC(EVP_MD_CTX_copy_ex)(clone, s->mdctx3); + OSSL_FUNC(EVP_DigestFinalXOF)(clone, tmp, s->n_out + outlen); memcpy(out3, tmp + s->n_out, outlen); free(tmp); // IGNORE free-check } - EVP_MD_CTX_free(clone); + OSSL_FUNC(EVP_MD_CTX_free)(clone); s->n_out += outlen; } -void OQS_SHA3_shake128_x4_inc_ctx_clone(OQS_SHA3_shake128_x4_inc_ctx *dest, const OQS_SHA3_shake128_x4_inc_ctx *src) { +static void SHA3_shake128_x4_inc_ctx_clone(OQS_SHA3_shake128_x4_inc_ctx *dest, const OQS_SHA3_shake128_x4_inc_ctx *src) { intrn_shake128_x4_inc_ctx *s = (intrn_shake128_x4_inc_ctx *)src->ctx; intrn_shake128_x4_inc_ctx *d = (intrn_shake128_x4_inc_ctx *)dest->ctx; - EVP_MD_CTX_copy_ex(d->mdctx0, s->mdctx0); - EVP_MD_CTX_copy_ex(d->mdctx1, s->mdctx1); - EVP_MD_CTX_copy_ex(d->mdctx2, s->mdctx2); - EVP_MD_CTX_copy_ex(d->mdctx3, s->mdctx3); + OSSL_FUNC(EVP_MD_CTX_copy_ex)(d->mdctx0, s->mdctx0); + OSSL_FUNC(EVP_MD_CTX_copy_ex)(d->mdctx1, s->mdctx1); + OSSL_FUNC(EVP_MD_CTX_copy_ex)(d->mdctx2, s->mdctx2); + OSSL_FUNC(EVP_MD_CTX_copy_ex)(d->mdctx3, s->mdctx3); d->n_out = s->n_out; } -void OQS_SHA3_shake128_x4_inc_ctx_release(OQS_SHA3_shake128_x4_inc_ctx *state) { +static void SHA3_shake128_x4_inc_ctx_release(OQS_SHA3_shake128_x4_inc_ctx *state) { intrn_shake128_x4_inc_ctx *s = (intrn_shake128_x4_inc_ctx *)state->ctx; - EVP_MD_CTX_free(s->mdctx0); - EVP_MD_CTX_free(s->mdctx1); - EVP_MD_CTX_free(s->mdctx2); - EVP_MD_CTX_free(s->mdctx3); + OSSL_FUNC(EVP_MD_CTX_free)(s->mdctx0); + OSSL_FUNC(EVP_MD_CTX_free)(s->mdctx1); + OSSL_FUNC(EVP_MD_CTX_free)(s->mdctx2); + OSSL_FUNC(EVP_MD_CTX_free)(s->mdctx3); free(s); // IGNORE free-check } -void OQS_SHA3_shake128_x4_inc_ctx_reset(OQS_SHA3_shake128_x4_inc_ctx *state) { +static void SHA3_shake128_x4_inc_ctx_reset(OQS_SHA3_shake128_x4_inc_ctx *state) { intrn_shake128_x4_inc_ctx *s = (intrn_shake128_x4_inc_ctx *)state->ctx; - EVP_MD_CTX_reset(s->mdctx0); - EVP_MD_CTX_reset(s->mdctx1); - EVP_MD_CTX_reset(s->mdctx2); - EVP_MD_CTX_reset(s->mdctx3); - EVP_DigestInit_ex(s->mdctx0, oqs_shake128(), NULL); - EVP_DigestInit_ex(s->mdctx1, oqs_shake128(), NULL); - EVP_DigestInit_ex(s->mdctx2, oqs_shake128(), NULL); - EVP_DigestInit_ex(s->mdctx3, oqs_shake128(), NULL); + OSSL_FUNC(EVP_MD_CTX_reset)(s->mdctx0); + OSSL_FUNC(EVP_MD_CTX_reset)(s->mdctx1); + OSSL_FUNC(EVP_MD_CTX_reset)(s->mdctx2); + OSSL_FUNC(EVP_MD_CTX_reset)(s->mdctx3); + OSSL_FUNC(EVP_DigestInit_ex)(s->mdctx0, oqs_shake128(), NULL); + OSSL_FUNC(EVP_DigestInit_ex)(s->mdctx1, oqs_shake128(), NULL); + OSSL_FUNC(EVP_DigestInit_ex)(s->mdctx2, oqs_shake128(), NULL); + OSSL_FUNC(EVP_DigestInit_ex)(s->mdctx3, oqs_shake128(), NULL); s->n_out = 0; } /* SHAKE-256 */ -void OQS_SHA3_shake256_x4(uint8_t *output0, uint8_t *output1, uint8_t *output2, uint8_t *output3, size_t outlen, - const uint8_t *in0, const uint8_t *in1, const uint8_t *in2, const uint8_t *in3, size_t inplen) { +static void SHA3_shake256_x4(uint8_t *output0, uint8_t *output1, uint8_t *output2, uint8_t *output3, size_t outlen, + const uint8_t *in0, const uint8_t *in1, const uint8_t *in2, const uint8_t *in3, size_t inplen) { OQS_SHA3_shake256(output0, outlen, in0, inplen); OQS_SHA3_shake256(output1, outlen, in1, inplen); OQS_SHA3_shake256(output2, outlen, in2, inplen); @@ -150,102 +150,123 @@ typedef struct { size_t n_out; } intrn_shake256_x4_inc_ctx; -void OQS_SHA3_shake256_x4_inc_init(OQS_SHA3_shake256_x4_inc_ctx *state) { +static void SHA3_shake256_x4_inc_init(OQS_SHA3_shake256_x4_inc_ctx *state) { state->ctx = malloc(sizeof(intrn_shake256_x4_inc_ctx)); intrn_shake256_x4_inc_ctx *s = (intrn_shake256_x4_inc_ctx *)state->ctx; - s->mdctx0 = EVP_MD_CTX_new(); - s->mdctx1 = EVP_MD_CTX_new(); - s->mdctx2 = EVP_MD_CTX_new(); - s->mdctx3 = EVP_MD_CTX_new(); - EVP_DigestInit_ex(s->mdctx0, oqs_shake256(), NULL); - EVP_DigestInit_ex(s->mdctx1, oqs_shake256(), NULL); - EVP_DigestInit_ex(s->mdctx2, oqs_shake256(), NULL); - EVP_DigestInit_ex(s->mdctx3, oqs_shake256(), NULL); + s->mdctx0 = OSSL_FUNC(EVP_MD_CTX_new)(); + s->mdctx1 = OSSL_FUNC(EVP_MD_CTX_new)(); + s->mdctx2 = OSSL_FUNC(EVP_MD_CTX_new)(); + s->mdctx3 = OSSL_FUNC(EVP_MD_CTX_new)(); + OSSL_FUNC(EVP_DigestInit_ex)(s->mdctx0, oqs_shake256(), NULL); + OSSL_FUNC(EVP_DigestInit_ex)(s->mdctx1, oqs_shake256(), NULL); + OSSL_FUNC(EVP_DigestInit_ex)(s->mdctx2, oqs_shake256(), NULL); + OSSL_FUNC(EVP_DigestInit_ex)(s->mdctx3, oqs_shake256(), NULL); s->n_out = 0; } -void OQS_SHA3_shake256_x4_inc_absorb(OQS_SHA3_shake256_x4_inc_ctx *state, const uint8_t *in0, const uint8_t *in1, const uint8_t *in2, const uint8_t *in3, size_t inplen) { +static void SHA3_shake256_x4_inc_absorb(OQS_SHA3_shake256_x4_inc_ctx *state, const uint8_t *in0, const uint8_t *in1, const uint8_t *in2, const uint8_t *in3, size_t inplen) { intrn_shake256_x4_inc_ctx *s = (intrn_shake256_x4_inc_ctx *)state->ctx; - EVP_DigestUpdate(s->mdctx0, in0, inplen); - EVP_DigestUpdate(s->mdctx1, in1, inplen); - EVP_DigestUpdate(s->mdctx2, in2, inplen); - EVP_DigestUpdate(s->mdctx3, in3, inplen); + OSSL_FUNC(EVP_DigestUpdate)(s->mdctx0, in0, inplen); + OSSL_FUNC(EVP_DigestUpdate)(s->mdctx1, in1, inplen); + OSSL_FUNC(EVP_DigestUpdate)(s->mdctx2, in2, inplen); + OSSL_FUNC(EVP_DigestUpdate)(s->mdctx3, in3, inplen); } -void OQS_SHA3_shake256_x4_inc_finalize(OQS_SHA3_shake256_x4_inc_ctx *state) { +static void SHA3_shake256_x4_inc_finalize(OQS_SHA3_shake256_x4_inc_ctx *state) { (void)state; } -void OQS_SHA3_shake256_x4_inc_squeeze(uint8_t *out0, uint8_t *out1, uint8_t *out2, uint8_t *out3, size_t outlen, OQS_SHA3_shake256_x4_inc_ctx *state) { +static void SHA3_shake256_x4_inc_squeeze(uint8_t *out0, uint8_t *out1, uint8_t *out2, uint8_t *out3, size_t outlen, OQS_SHA3_shake256_x4_inc_ctx *state) { intrn_shake256_x4_inc_ctx *s = (intrn_shake256_x4_inc_ctx *)state->ctx; EVP_MD_CTX *clone; - clone = EVP_MD_CTX_new(); - EVP_DigestInit_ex(clone, oqs_shake256(), NULL); + clone = OSSL_FUNC(EVP_MD_CTX_new)(); + OSSL_FUNC(EVP_DigestInit_ex)(clone, oqs_shake256(), NULL); if (s->n_out == 0) { - EVP_MD_CTX_copy_ex(clone, s->mdctx0); - EVP_DigestFinalXOF(clone, out0, outlen); - EVP_MD_CTX_copy_ex(clone, s->mdctx1); - EVP_DigestFinalXOF(clone, out1, outlen); - EVP_MD_CTX_copy_ex(clone, s->mdctx2); - EVP_DigestFinalXOF(clone, out2, outlen); - EVP_MD_CTX_copy_ex(clone, s->mdctx3); - EVP_DigestFinalXOF(clone, out3, outlen); + OSSL_FUNC(EVP_MD_CTX_copy_ex)(clone, s->mdctx0); + OSSL_FUNC(EVP_DigestFinalXOF)(clone, out0, outlen); + OSSL_FUNC(EVP_MD_CTX_copy_ex)(clone, s->mdctx1); + OSSL_FUNC(EVP_DigestFinalXOF)(clone, out1, outlen); + OSSL_FUNC(EVP_MD_CTX_copy_ex)(clone, s->mdctx2); + OSSL_FUNC(EVP_DigestFinalXOF)(clone, out2, outlen); + OSSL_FUNC(EVP_MD_CTX_copy_ex)(clone, s->mdctx3); + OSSL_FUNC(EVP_DigestFinalXOF)(clone, out3, outlen); } else { uint8_t *tmp; tmp = malloc(s->n_out + outlen); if (tmp == NULL) { exit(111); } - EVP_MD_CTX_copy_ex(clone, s->mdctx0); - EVP_DigestFinalXOF(clone, tmp, s->n_out + outlen); + OSSL_FUNC(EVP_MD_CTX_copy_ex)(clone, s->mdctx0); + OSSL_FUNC(EVP_DigestFinalXOF)(clone, tmp, s->n_out + outlen); memcpy(out0, tmp + s->n_out, outlen); - EVP_MD_CTX_copy_ex(clone, s->mdctx1); - EVP_DigestFinalXOF(clone, tmp, s->n_out + outlen); + OSSL_FUNC(EVP_MD_CTX_copy_ex)(clone, s->mdctx1); + OSSL_FUNC(EVP_DigestFinalXOF)(clone, tmp, s->n_out + outlen); memcpy(out1, tmp + s->n_out, outlen); - EVP_MD_CTX_copy_ex(clone, s->mdctx2); - EVP_DigestFinalXOF(clone, tmp, s->n_out + outlen); + OSSL_FUNC(EVP_MD_CTX_copy_ex)(clone, s->mdctx2); + OSSL_FUNC(EVP_DigestFinalXOF)(clone, tmp, s->n_out + outlen); memcpy(out2, tmp + s->n_out, outlen); - EVP_MD_CTX_copy_ex(clone, s->mdctx3); - EVP_DigestFinalXOF(clone, tmp, s->n_out + outlen); + OSSL_FUNC(EVP_MD_CTX_copy_ex)(clone, s->mdctx3); + OSSL_FUNC(EVP_DigestFinalXOF)(clone, tmp, s->n_out + outlen); memcpy(out3, tmp + s->n_out, outlen); free(tmp); // IGNORE free-check } - EVP_MD_CTX_free(clone); + OSSL_FUNC(EVP_MD_CTX_free)(clone); s->n_out += outlen; } -void OQS_SHA3_shake256_x4_inc_ctx_clone(OQS_SHA3_shake256_x4_inc_ctx *dest, const OQS_SHA3_shake256_x4_inc_ctx *src) { +static void SHA3_shake256_x4_inc_ctx_clone(OQS_SHA3_shake256_x4_inc_ctx *dest, const OQS_SHA3_shake256_x4_inc_ctx *src) { intrn_shake256_x4_inc_ctx *s = (intrn_shake256_x4_inc_ctx *)src->ctx; intrn_shake256_x4_inc_ctx *d = (intrn_shake256_x4_inc_ctx *)dest->ctx; - EVP_MD_CTX_copy_ex(d->mdctx0, s->mdctx0); - EVP_MD_CTX_copy_ex(d->mdctx1, s->mdctx1); - EVP_MD_CTX_copy_ex(d->mdctx2, s->mdctx2); - EVP_MD_CTX_copy_ex(d->mdctx3, s->mdctx3); + OSSL_FUNC(EVP_MD_CTX_copy_ex)(d->mdctx0, s->mdctx0); + OSSL_FUNC(EVP_MD_CTX_copy_ex)(d->mdctx1, s->mdctx1); + OSSL_FUNC(EVP_MD_CTX_copy_ex)(d->mdctx2, s->mdctx2); + OSSL_FUNC(EVP_MD_CTX_copy_ex)(d->mdctx3, s->mdctx3); d->n_out = s->n_out; } -void OQS_SHA3_shake256_x4_inc_ctx_release(OQS_SHA3_shake256_x4_inc_ctx *state) { +static void SHA3_shake256_x4_inc_ctx_release(OQS_SHA3_shake256_x4_inc_ctx *state) { intrn_shake256_x4_inc_ctx *s = (intrn_shake256_x4_inc_ctx *)state->ctx; - EVP_MD_CTX_free(s->mdctx0); - EVP_MD_CTX_free(s->mdctx1); - EVP_MD_CTX_free(s->mdctx2); - EVP_MD_CTX_free(s->mdctx3); + OSSL_FUNC(EVP_MD_CTX_free)(s->mdctx0); + OSSL_FUNC(EVP_MD_CTX_free)(s->mdctx1); + OSSL_FUNC(EVP_MD_CTX_free)(s->mdctx2); + OSSL_FUNC(EVP_MD_CTX_free)(s->mdctx3); free(s); // IGNORE free-check } -void OQS_SHA3_shake256_x4_inc_ctx_reset(OQS_SHA3_shake256_x4_inc_ctx *state) { +static void SHA3_shake256_x4_inc_ctx_reset(OQS_SHA3_shake256_x4_inc_ctx *state) { intrn_shake256_x4_inc_ctx *s = (intrn_shake256_x4_inc_ctx *)state->ctx; - EVP_MD_CTX_reset(s->mdctx0); - EVP_MD_CTX_reset(s->mdctx1); - EVP_MD_CTX_reset(s->mdctx2); - EVP_MD_CTX_reset(s->mdctx3); - EVP_DigestInit_ex(s->mdctx0, oqs_shake256(), NULL); - EVP_DigestInit_ex(s->mdctx1, oqs_shake256(), NULL); - EVP_DigestInit_ex(s->mdctx2, oqs_shake256(), NULL); - EVP_DigestInit_ex(s->mdctx3, oqs_shake256(), NULL); + OSSL_FUNC(EVP_MD_CTX_reset)(s->mdctx0); + OSSL_FUNC(EVP_MD_CTX_reset)(s->mdctx1); + OSSL_FUNC(EVP_MD_CTX_reset)(s->mdctx2); + OSSL_FUNC(EVP_MD_CTX_reset)(s->mdctx3); + OSSL_FUNC(EVP_DigestInit_ex)(s->mdctx0, oqs_shake256(), NULL); + OSSL_FUNC(EVP_DigestInit_ex)(s->mdctx1, oqs_shake256(), NULL); + OSSL_FUNC(EVP_DigestInit_ex)(s->mdctx2, oqs_shake256(), NULL); + OSSL_FUNC(EVP_DigestInit_ex)(s->mdctx3, oqs_shake256(), NULL); s->n_out = 0; } +extern struct OQS_SHA3_x4_callbacks sha3_x4_default_callbacks; + +struct OQS_SHA3_x4_callbacks sha3_x4_default_callbacks = { + SHA3_shake128_x4, + SHA3_shake128_x4_inc_init, + SHA3_shake128_x4_inc_absorb, + SHA3_shake128_x4_inc_finalize, + SHA3_shake128_x4_inc_squeeze, + SHA3_shake128_x4_inc_ctx_release, + SHA3_shake128_x4_inc_ctx_clone, + SHA3_shake128_x4_inc_ctx_reset, + SHA3_shake256_x4, + SHA3_shake256_x4_inc_init, + SHA3_shake256_x4_inc_absorb, + SHA3_shake256_x4_inc_finalize, + SHA3_shake256_x4_inc_squeeze, + SHA3_shake256_x4_inc_ctx_release, + SHA3_shake256_x4_inc_ctx_clone, + SHA3_shake256_x4_inc_ctx_reset, +}; + #endif diff --git a/src/common/sha3/sha3.c b/src/common/sha3/sha3.c new file mode 100644 index 00000000..600fc198 --- /dev/null +++ b/src/common/sha3/sha3.c @@ -0,0 +1,161 @@ +// SPDX-License-Identifier: MIT + +#include + +#include "sha3.h" + +extern struct OQS_SHA3_callbacks sha3_default_callbacks; + +static struct OQS_SHA3_callbacks *callbacks = &sha3_default_callbacks; + +OQS_API void OQS_SHA3_set_callbacks(struct OQS_SHA3_callbacks *new_callbacks) { + callbacks = new_callbacks; +} + +void OQS_SHA3_sha3_256(uint8_t *output, const uint8_t *input, size_t inplen) { + callbacks->SHA3_sha3_256(output, input, inplen); +} + +void OQS_SHA3_sha3_256_inc_init(OQS_SHA3_sha3_256_inc_ctx *state) { + callbacks->SHA3_sha3_256_inc_init(state); +} + +void OQS_SHA3_sha3_256_inc_absorb(OQS_SHA3_sha3_256_inc_ctx *state, const uint8_t *input, size_t inlen) { + callbacks->SHA3_sha3_256_inc_absorb(state, input, inlen); +} + +void OQS_SHA3_sha3_256_inc_finalize(uint8_t *output, OQS_SHA3_sha3_256_inc_ctx *state) { + callbacks->SHA3_sha3_256_inc_finalize(output, state); +} + +void OQS_SHA3_sha3_256_inc_ctx_release(OQS_SHA3_sha3_256_inc_ctx *state) { + callbacks->SHA3_sha3_256_inc_ctx_release(state); +} + +void OQS_SHA3_sha3_256_inc_ctx_reset(OQS_SHA3_sha3_256_inc_ctx *state) { + callbacks->SHA3_sha3_256_inc_ctx_reset(state); +} + +void OQS_SHA3_sha3_256_inc_ctx_clone(OQS_SHA3_sha3_256_inc_ctx *dest, const OQS_SHA3_sha3_256_inc_ctx *src) { + callbacks->SHA3_sha3_256_inc_ctx_clone(dest, src); +} + +void OQS_SHA3_sha3_384(uint8_t *output, const uint8_t *input, size_t inplen) { + callbacks->SHA3_sha3_384(output, input, inplen); +} + +void OQS_SHA3_sha3_384_inc_init(OQS_SHA3_sha3_384_inc_ctx *state) { + callbacks->SHA3_sha3_384_inc_init(state); +} + +void OQS_SHA3_sha3_384_inc_absorb(OQS_SHA3_sha3_384_inc_ctx *state, const uint8_t *input, size_t inlen) { + callbacks->SHA3_sha3_384_inc_absorb(state, input, inlen); +} + +void OQS_SHA3_sha3_384_inc_finalize(uint8_t *output, OQS_SHA3_sha3_384_inc_ctx *state) { + callbacks->SHA3_sha3_384_inc_finalize(output, state); +} + +void OQS_SHA3_sha3_384_inc_ctx_release(OQS_SHA3_sha3_384_inc_ctx *state) { + callbacks->SHA3_sha3_384_inc_ctx_release(state); +} + +void OQS_SHA3_sha3_384_inc_ctx_reset(OQS_SHA3_sha3_384_inc_ctx *state) { + callbacks->SHA3_sha3_384_inc_ctx_reset(state); +} + +void OQS_SHA3_sha3_384_inc_ctx_clone(OQS_SHA3_sha3_384_inc_ctx *dest, const OQS_SHA3_sha3_384_inc_ctx *src) { + callbacks->SHA3_sha3_384_inc_ctx_clone(dest, src); +} + +void OQS_SHA3_sha3_512(uint8_t *output, const uint8_t *input, size_t inplen) { + callbacks->SHA3_sha3_512(output, input, inplen); +} + +void OQS_SHA3_sha3_512_inc_init(OQS_SHA3_sha3_512_inc_ctx *state) { + callbacks->SHA3_sha3_512_inc_init(state); +} + +void OQS_SHA3_sha3_512_inc_absorb(OQS_SHA3_sha3_512_inc_ctx *state, const uint8_t *input, size_t inlen) { + callbacks->SHA3_sha3_512_inc_absorb(state, input, inlen); +} + +void OQS_SHA3_sha3_512_inc_finalize(uint8_t *output, OQS_SHA3_sha3_512_inc_ctx *state) { + callbacks->SHA3_sha3_512_inc_finalize(output, state); +} + +void OQS_SHA3_sha3_512_inc_ctx_release(OQS_SHA3_sha3_512_inc_ctx *state) { + callbacks->SHA3_sha3_512_inc_ctx_release(state); +} + +void OQS_SHA3_sha3_512_inc_ctx_reset(OQS_SHA3_sha3_512_inc_ctx *state) { + callbacks->SHA3_sha3_512_inc_ctx_reset(state); +} + +void OQS_SHA3_sha3_512_inc_ctx_clone(OQS_SHA3_sha3_512_inc_ctx *dest, const OQS_SHA3_sha3_512_inc_ctx *src) { + callbacks->SHA3_sha3_512_inc_ctx_clone(dest, src); +} + +void OQS_SHA3_shake128(uint8_t *output, size_t outlen, const uint8_t *input, size_t inplen) { + callbacks->SHA3_shake128(output, outlen, input, inplen); +} + +void OQS_SHA3_shake128_inc_init(OQS_SHA3_shake128_inc_ctx *state) { + callbacks->SHA3_shake128_inc_init(state); +} + +void OQS_SHA3_shake128_inc_absorb(OQS_SHA3_shake128_inc_ctx *state, const uint8_t *input, size_t inlen) { + callbacks->SHA3_shake128_inc_absorb(state, input, inlen); +} + +void OQS_SHA3_shake128_inc_finalize(OQS_SHA3_shake128_inc_ctx *state) { + callbacks->SHA3_shake128_inc_finalize(state); +} + +void OQS_SHA3_shake128_inc_squeeze(uint8_t *output, size_t outlen, OQS_SHA3_shake128_inc_ctx *state) { + callbacks->SHA3_shake128_inc_squeeze(output, outlen, state); +} + +void OQS_SHA3_shake128_inc_ctx_release(OQS_SHA3_shake128_inc_ctx *state) { + callbacks->SHA3_shake128_inc_ctx_release(state); +} + +void OQS_SHA3_shake128_inc_ctx_clone(OQS_SHA3_shake128_inc_ctx *dest, const OQS_SHA3_shake128_inc_ctx *src) { + callbacks->SHA3_shake128_inc_ctx_clone(dest, src); +} + +void OQS_SHA3_shake128_inc_ctx_reset(OQS_SHA3_shake128_inc_ctx *state) { + callbacks->SHA3_shake128_inc_ctx_reset(state); +} + +void OQS_SHA3_shake256(uint8_t *output, size_t outlen, const uint8_t *input, size_t inplen) { + callbacks->SHA3_shake256(output, outlen, input, inplen); +} + +void OQS_SHA3_shake256_inc_init(OQS_SHA3_shake256_inc_ctx *state) { + callbacks->SHA3_shake256_inc_init(state); +} + +void OQS_SHA3_shake256_inc_absorb(OQS_SHA3_shake256_inc_ctx *state, const uint8_t *input, size_t inlen) { + callbacks->SHA3_shake256_inc_absorb(state, input, inlen); +} + +void OQS_SHA3_shake256_inc_finalize(OQS_SHA3_shake256_inc_ctx *state) { + callbacks->SHA3_shake256_inc_finalize(state); +} + +void OQS_SHA3_shake256_inc_squeeze(uint8_t *output, size_t outlen, OQS_SHA3_shake256_inc_ctx *state) { + callbacks->SHA3_shake256_inc_squeeze(output, outlen, state); +} + +void OQS_SHA3_shake256_inc_ctx_release(OQS_SHA3_shake256_inc_ctx *state) { + callbacks->SHA3_shake256_inc_ctx_release(state); +} + +void OQS_SHA3_shake256_inc_ctx_clone(OQS_SHA3_shake256_inc_ctx *dest, const OQS_SHA3_shake256_inc_ctx *src) { + callbacks->SHA3_shake256_inc_ctx_clone(dest, src); +} + +void OQS_SHA3_shake256_inc_ctx_reset(OQS_SHA3_shake256_inc_ctx *state) { + callbacks->SHA3_shake256_inc_ctx_reset(state); +} diff --git a/src/common/sha3/sha3.h b/src/common/sha3/sha3.h index d66c7289..ef259f42 100644 --- a/src/common/sha3/sha3.h +++ b/src/common/sha3/sha3.h @@ -18,6 +18,8 @@ #include #include +#include + #if defined(__cplusplus) extern "C" { #endif @@ -421,6 +423,205 @@ void OQS_SHA3_shake256_inc_ctx_clone(OQS_SHA3_shake256_inc_ctx *dest, const OQS_ */ void OQS_SHA3_shake256_inc_ctx_reset(OQS_SHA3_shake256_inc_ctx *state); +/** Data structure implemented by cryptographic provider for SHA-3 operations. + */ +struct OQS_SHA3_callbacks { + /** + * Implementation of function OQS_SHA3_sha3_256. + */ + void (*SHA3_sha3_256)(uint8_t *output, const uint8_t *input, size_t inplen); + + /** + * Implementation of function OQS_SHA3_sha3_256_inc_init. + */ + void (*SHA3_sha3_256_inc_init)(OQS_SHA3_sha3_256_inc_ctx *state); + + /** + * Implementation of function OQS_SHA3_sha3_256_inc_absorb. + */ + void (*SHA3_sha3_256_inc_absorb)(OQS_SHA3_sha3_256_inc_ctx *state, const uint8_t *input, size_t inlen); + + /** + * Implementation of function OQS_SHA3_sha3_256_inc_finalize. + */ + void (*SHA3_sha3_256_inc_finalize)(uint8_t *output, OQS_SHA3_sha3_256_inc_ctx *state); + + /** + * Implementation of function OQS_SHA3_sha3_256_inc_ctx_release. + */ + void (*SHA3_sha3_256_inc_ctx_release)(OQS_SHA3_sha3_256_inc_ctx *state); + + /** + * Implementation of function OQS_SHA3_sha3_256_inc_ctx_reset. + */ + void (*SHA3_sha3_256_inc_ctx_reset)(OQS_SHA3_sha3_256_inc_ctx *state); + + /** + * Implementation of function OQS_SHA3_sha3_256_inc_ctx_clone. + */ + void (*SHA3_sha3_256_inc_ctx_clone)(OQS_SHA3_sha3_256_inc_ctx *dest, const OQS_SHA3_sha3_256_inc_ctx *src); + + /** + * Implementation of function OQS_SHA3_sha3_384. + */ + void (*SHA3_sha3_384)(uint8_t *output, const uint8_t *input, size_t inplen); + + /** + * Implementation of function OQS_SHA3_sha3_384_inc_init. + */ + void (*SHA3_sha3_384_inc_init)(OQS_SHA3_sha3_384_inc_ctx *state); + + /** + * Implementation of function OQS_SHA3_sha3_384_inc_absorb. + */ + void (*SHA3_sha3_384_inc_absorb)(OQS_SHA3_sha3_384_inc_ctx *state, const uint8_t *input, size_t inlen); + + /** + * Implementation of function OQS_SHA3_sha3_384_inc_finalize. + */ + void (*SHA3_sha3_384_inc_finalize)(uint8_t *output, OQS_SHA3_sha3_384_inc_ctx *state); + + /** + * Implementation of function OQS_SHA3_sha3_384_inc_ctx_release. + */ + void (*SHA3_sha3_384_inc_ctx_release)(OQS_SHA3_sha3_384_inc_ctx *state); + + /** + * Implementation of function OQS_SHA3_sha3_384_inc_ctx_reset. + */ + void (*SHA3_sha3_384_inc_ctx_reset)(OQS_SHA3_sha3_384_inc_ctx *state); + + /** + * Implementation of function OQS_SHA3_sha3_384_inc_ctx_clone. + */ + void (*SHA3_sha3_384_inc_ctx_clone)(OQS_SHA3_sha3_384_inc_ctx *dest, const OQS_SHA3_sha3_384_inc_ctx *src); + + /** + * Implementation of function OQS_SHA3_sha3_512. + */ + void (*SHA3_sha3_512)(uint8_t *output, const uint8_t *input, size_t inplen); + + /** + * Implementation of function OQS_SHA3_sha3_512_inc_init. + */ + void (*SHA3_sha3_512_inc_init)(OQS_SHA3_sha3_512_inc_ctx *state); + + /** + * Implementation of function OQS_SHA3_sha3_512_inc_absorb. + */ + void (*SHA3_sha3_512_inc_absorb)(OQS_SHA3_sha3_512_inc_ctx *state, const uint8_t *input, size_t inlen); + + /** + * Implementation of function OQS_SHA3_sha3_512_inc_finalize. + */ + void (*SHA3_sha3_512_inc_finalize)(uint8_t *output, OQS_SHA3_sha3_512_inc_ctx *state); + + /** + * Implementation of function OQS_SHA3_sha3_512_inc_ctx_release. + */ + void (*SHA3_sha3_512_inc_ctx_release)(OQS_SHA3_sha3_512_inc_ctx *state); + + /** + * Implementation of function OQS_SHA3_sha3_512_inc_ctx_reset. + */ + void (*SHA3_sha3_512_inc_ctx_reset)(OQS_SHA3_sha3_512_inc_ctx *state); + + /** + * Implementation of function OQS_SHA3_sha3_512_inc_ctx_clone. + */ + void (*SHA3_sha3_512_inc_ctx_clone)(OQS_SHA3_sha3_512_inc_ctx *dest, const OQS_SHA3_sha3_512_inc_ctx *src); + + /** + * Implementation of function OQS_SHA3_shake128. + */ + void (*SHA3_shake128)(uint8_t *output, size_t outlen, const uint8_t *input, size_t inplen); + + /** + * Implementation of function OQS_SHA3_shake128_inc_init. + */ + void (*SHA3_shake128_inc_init)(OQS_SHA3_shake128_inc_ctx *state); + + /** + * Implementation of function OQS_SHA3_shake128_inc_absorb. + */ + void (*SHA3_shake128_inc_absorb)(OQS_SHA3_shake128_inc_ctx *state, const uint8_t *input, size_t inlen); + + /** + * Implementation of function OQS_SHA3_shake128_inc_finalize. + */ + void (*SHA3_shake128_inc_finalize)(OQS_SHA3_shake128_inc_ctx *state); + + /** + * Implementation of function OQS_SHA3_shake128_inc_squeeze. + */ + void (*SHA3_shake128_inc_squeeze)(uint8_t *output, size_t outlen, OQS_SHA3_shake128_inc_ctx *state); + + /** + * Implementation of function OQS_SHA3_shake128_inc_ctx_release. + */ + void (*SHA3_shake128_inc_ctx_release)(OQS_SHA3_shake128_inc_ctx *state); + + /** + * Implementation of function OQS_SHA3_shake128_inc_ctx_clone. + */ + void (*SHA3_shake128_inc_ctx_clone)(OQS_SHA3_shake128_inc_ctx *dest, const OQS_SHA3_shake128_inc_ctx *src); + + /** + * Implementation of function OQS_SHA3_shake128_inc_ctx_reset. + */ + void (*SHA3_shake128_inc_ctx_reset)(OQS_SHA3_shake128_inc_ctx *state); + + /** + * Implementation of function OQS_SHA3_shake256. + */ + void (*SHA3_shake256)(uint8_t *output, size_t outlen, const uint8_t *input, size_t inplen); + + /** + * Implementation of function OQS_SHA3_shake256_inc_init. + */ + void (*SHA3_shake256_inc_init)(OQS_SHA3_shake256_inc_ctx *state); + + /** + * Implementation of function OQS_SHA3_shake256_inc_absorb. + */ + void (*SHA3_shake256_inc_absorb)(OQS_SHA3_shake256_inc_ctx *state, const uint8_t *input, size_t inlen); + + /** + * Implementation of function OQS_SHA3_shake256_inc_finalize. + */ + void (*SHA3_shake256_inc_finalize)(OQS_SHA3_shake256_inc_ctx *state); + + /** + * Implementation of function OQS_SHA3_shake256_inc_squeeze. + */ + void (*SHA3_shake256_inc_squeeze)(uint8_t *output, size_t outlen, OQS_SHA3_shake256_inc_ctx *state); + + /** + * Implementation of function OQS_SHA3_shake256_inc_ctx_release. + */ + void (*SHA3_shake256_inc_ctx_release)(OQS_SHA3_shake256_inc_ctx *state); + + /** + * Implementation of function OQS_SHA3_shake256_inc_ctx_clone. + */ + void (*SHA3_shake256_inc_ctx_clone)(OQS_SHA3_shake256_inc_ctx *dest, const OQS_SHA3_shake256_inc_ctx *src); + + /** + * Implementation of function OQS_SHA3_shake256_inc_ctx_reset. + */ + void (*SHA3_shake256_inc_ctx_reset)(OQS_SHA3_shake256_inc_ctx *state); +}; + +/** + * Set callback functions for SHA3 operations. + * + * This function may be called before OQS_init to switch the + * cryptographic provider for SHA3 operations. If it is not called, + * the default provider determined at build time will be used. + * + * @param new_callbacks Callback functions defined in OQS_SHA3_callbacks struct + */ +OQS_API void OQS_SHA3_set_callbacks(struct OQS_SHA3_callbacks *new_callbacks); #if defined(__cplusplus) } // extern "C" diff --git a/src/common/sha3/sha3x4.c b/src/common/sha3/sha3x4.c new file mode 100644 index 00000000..b41ea08d --- /dev/null +++ b/src/common/sha3/sha3x4.c @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: MIT + +#include + +#include "sha3x4.h" + +extern struct OQS_SHA3_x4_callbacks sha3_x4_default_callbacks; + +static struct OQS_SHA3_x4_callbacks *callbacks = &sha3_x4_default_callbacks; + +OQS_API void OQS_SHA3_x4_set_callbacks(struct OQS_SHA3_x4_callbacks *new_callbacks) { + callbacks = new_callbacks; +} + +void OQS_SHA3_shake128_x4(uint8_t *out0, uint8_t *out1, uint8_t *out2, uint8_t *out3, size_t outlen, const uint8_t *in0, const uint8_t *in1, const uint8_t *in2, const uint8_t *in3, size_t inlen) { + callbacks->SHA3_shake128_x4(out0, out1, out2, out3, outlen, in0, in1, in2, in3, inlen); +} + +void OQS_SHA3_shake128_x4_inc_init(OQS_SHA3_shake128_x4_inc_ctx *state) { + callbacks->SHA3_shake128_x4_inc_init(state); +} + +void OQS_SHA3_shake128_x4_inc_absorb(OQS_SHA3_shake128_x4_inc_ctx *state, const uint8_t *in0, const uint8_t *in1, const uint8_t *in2, const uint8_t *in3, size_t inlen) { + callbacks->SHA3_shake128_x4_inc_absorb(state, in0, in1, in2, in3, inlen); +} + +void OQS_SHA3_shake128_x4_inc_finalize(OQS_SHA3_shake128_x4_inc_ctx *state) { + callbacks->SHA3_shake128_x4_inc_finalize(state); +} + +void OQS_SHA3_shake128_x4_inc_squeeze(uint8_t *out0, uint8_t *out1, uint8_t *out2, uint8_t *out3, size_t outlen, OQS_SHA3_shake128_x4_inc_ctx *state) { + callbacks->SHA3_shake128_x4_inc_squeeze(out0, out1, out2, out3, outlen, state); +} + +void OQS_SHA3_shake128_x4_inc_ctx_release(OQS_SHA3_shake128_x4_inc_ctx *state) { + callbacks->SHA3_shake128_x4_inc_ctx_release(state); +} + +void OQS_SHA3_shake128_x4_inc_ctx_clone(OQS_SHA3_shake128_x4_inc_ctx *dest, const OQS_SHA3_shake128_x4_inc_ctx *src) { + callbacks->SHA3_shake128_x4_inc_ctx_clone(dest, src); +} + +void OQS_SHA3_shake128_x4_inc_ctx_reset(OQS_SHA3_shake128_x4_inc_ctx *state) { + callbacks->SHA3_shake128_x4_inc_ctx_reset(state); +} + +void OQS_SHA3_shake256_x4(uint8_t *out0, uint8_t *out1, uint8_t *out2, uint8_t *out3, size_t outlen, const uint8_t *in0, const uint8_t *in1, const uint8_t *in2, const uint8_t *in3, size_t inlen) { + callbacks->SHA3_shake256_x4(out0, out1, out2, out3, outlen, in0, in1, in2, in3, inlen); +} + +void OQS_SHA3_shake256_x4_inc_init(OQS_SHA3_shake256_x4_inc_ctx *state) { + callbacks->SHA3_shake256_x4_inc_init(state); +} + +void OQS_SHA3_shake256_x4_inc_absorb(OQS_SHA3_shake256_x4_inc_ctx *state, const uint8_t *in0, const uint8_t *in1, const uint8_t *in2, const uint8_t *in3, size_t inlen) { + callbacks->SHA3_shake256_x4_inc_absorb(state, in0, in1, in2, in3, inlen); +} + +void OQS_SHA3_shake256_x4_inc_finalize(OQS_SHA3_shake256_x4_inc_ctx *state) { + callbacks->SHA3_shake256_x4_inc_finalize(state); +} + +void OQS_SHA3_shake256_x4_inc_squeeze(uint8_t *out0, uint8_t *out1, uint8_t *out2, uint8_t *out3, size_t outlen, OQS_SHA3_shake256_x4_inc_ctx *state) { + callbacks->SHA3_shake256_x4_inc_squeeze(out0, out1, out2, out3, outlen, state); +} + +void OQS_SHA3_shake256_x4_inc_ctx_release(OQS_SHA3_shake256_x4_inc_ctx *state) { + callbacks->SHA3_shake256_x4_inc_ctx_release(state); +} + +void OQS_SHA3_shake256_x4_inc_ctx_clone(OQS_SHA3_shake256_x4_inc_ctx *dest, const OQS_SHA3_shake256_x4_inc_ctx *src) { + callbacks->SHA3_shake256_x4_inc_ctx_clone(dest, src); +} + +void OQS_SHA3_shake256_x4_inc_ctx_reset(OQS_SHA3_shake256_x4_inc_ctx *state) { + callbacks->SHA3_shake256_x4_inc_ctx_reset(state); +} diff --git a/src/common/sha3/sha3x4.h b/src/common/sha3/sha3x4.h index cef4e675..1dc3c79e 100644 --- a/src/common/sha3/sha3x4.h +++ b/src/common/sha3/sha3x4.h @@ -18,6 +18,8 @@ #include #include +#include + #if defined(__cplusplus) extern "C" { #endif @@ -255,6 +257,149 @@ void OQS_SHA3_shake256_x4_inc_ctx_clone( */ void OQS_SHA3_shake256_x4_inc_ctx_reset(OQS_SHA3_shake256_x4_inc_ctx *state); +/** Data structure implemented by cryptographic provider for the + * four-way parallel incremental SHAKE-256 operations. + */ +struct OQS_SHA3_x4_callbacks { + /** + * Implementation of function OQS_SHA3_shake128_x4. + */ + void (*SHA3_shake128_x4)( + uint8_t *out0, + uint8_t *out1, + uint8_t *out2, + uint8_t *out3, + size_t outlen, + const uint8_t *in0, + const uint8_t *in1, + const uint8_t *in2, + const uint8_t *in3, + size_t inlen); + + /** + * Implementation of function OQS_SHA3_shake128_x4_inc_init. + */ + void (*SHA3_shake128_x4_inc_init)(OQS_SHA3_shake128_x4_inc_ctx *state); + + /** + * Implementation of function OQS_SHA3_shake128_x4_inc_absorb. + */ + void (*SHA3_shake128_x4_inc_absorb)( + OQS_SHA3_shake128_x4_inc_ctx *state, + const uint8_t *in0, + const uint8_t *in1, + const uint8_t *in2, + const uint8_t *in3, + size_t inlen); + + /** + * Implementation of function OQS_SHA3_shake128_x4_inc_finalize. + */ + void (*SHA3_shake128_x4_inc_finalize)(OQS_SHA3_shake128_x4_inc_ctx *state); + + /** + * Implementation of function OQS_SHA3_shake128_x4_inc_squeeze. + */ + void (*SHA3_shake128_x4_inc_squeeze)( + uint8_t *out0, + uint8_t *out1, + uint8_t *out2, + uint8_t *out3, + size_t outlen, + OQS_SHA3_shake128_x4_inc_ctx *state); + + /** + * Implementation of function OQS_SHA3_shake128_x4_inc_ctx_release. + */ + void (*SHA3_shake128_x4_inc_ctx_release)(OQS_SHA3_shake128_x4_inc_ctx *state); + + /** + * Implementation of function OQS_SHA3_shake128_x4_inc_ctx_clone. + */ + void (*SHA3_shake128_x4_inc_ctx_clone)( + OQS_SHA3_shake128_x4_inc_ctx *dest, + const OQS_SHA3_shake128_x4_inc_ctx *src); + + /** + * Implementation of function OQS_SHA3_shake128_x4_inc_ctx_reset. + */ + void (*SHA3_shake128_x4_inc_ctx_reset)(OQS_SHA3_shake128_x4_inc_ctx *state); + + /** + * Implementation of function OQS_SHA3_shake256_x4. + */ + void (*SHA3_shake256_x4)( + uint8_t *out0, + uint8_t *out1, + uint8_t *out2, + uint8_t *out3, + size_t outlen, + const uint8_t *in0, + const uint8_t *in1, + const uint8_t *in2, + const uint8_t *in3, + size_t inlen); + + /** + * Implementation of function OQS_SHA3_shake256_x4_inc_init. + */ + void (*SHA3_shake256_x4_inc_init)(OQS_SHA3_shake256_x4_inc_ctx *state); + + /** + * Implementation of function OQS_SHA3_shake256_x4_inc_absorb. + */ + void (*SHA3_shake256_x4_inc_absorb)( + OQS_SHA3_shake256_x4_inc_ctx *state, + const uint8_t *in0, + const uint8_t *in1, + const uint8_t *in2, + const uint8_t *in3, + size_t inlen); + + /** + * Implementation of function OQS_SHA3_shake256_x4_inc_finalize. + */ + void (*SHA3_shake256_x4_inc_finalize)(OQS_SHA3_shake256_x4_inc_ctx *state); + + /** + * Implementation of function OQS_SHA3_shake256_x4_inc_squeeze. + */ + void (*SHA3_shake256_x4_inc_squeeze)( + uint8_t *out0, + uint8_t *out1, + uint8_t *out2, + uint8_t *out3, + size_t outlen, + OQS_SHA3_shake256_x4_inc_ctx *state); + + /** + * Implementation of function OQS_SHA3_shake256_x4_inc_ctx_release. + */ + void (*SHA3_shake256_x4_inc_ctx_release)(OQS_SHA3_shake256_x4_inc_ctx *state); + + /** + * Implementation of function OQS_SHA3_shake256_x4_inc_ctx_clone. + */ + void (*SHA3_shake256_x4_inc_ctx_clone)( + OQS_SHA3_shake256_x4_inc_ctx *dest, + const OQS_SHA3_shake256_x4_inc_ctx *src); + + /** + * Implementation of function OQS_SHA3_shake256_x4_inc_ctx_reset. + */ + void (*SHA3_shake256_x4_inc_ctx_reset)(OQS_SHA3_shake256_x4_inc_ctx *state); +}; + +/** + * Set callback functions for 4-parallel SHA3 operations. + * + * This function may be called before OQS_init to switch the + * cryptographic provider for 4-parallel SHA3 operations. If it is not + * called, the default provider determined at build time will be used. + * + * @param new_callbacks Callback functions defined in OQS_SHA3_x4_callbacks struct + */ +OQS_API void OQS_SHA3_x4_set_callbacks(struct OQS_SHA3_x4_callbacks *new_callbacks); #if defined(__cplusplus) } // extern "C" diff --git a/src/common/sha3/xkcp_sha3.c b/src/common/sha3/xkcp_sha3.c index e9192862..2fce9d9f 100644 --- a/src/common/sha3/xkcp_sha3.c +++ b/src/common/sha3/xkcp_sha3.c @@ -190,7 +190,7 @@ static void keccak_inc_squeeze(uint8_t *h, size_t outlen, /* SHA3-256 */ -void OQS_SHA3_sha3_256(uint8_t *output, const uint8_t *input, size_t inlen) { +static void SHA3_sha3_256(uint8_t *output, const uint8_t *input, size_t inlen) { OQS_SHA3_sha3_256_inc_ctx s; OQS_SHA3_sha3_256_inc_init(&s); OQS_SHA3_sha3_256_inc_absorb(&s, input, inlen); @@ -198,7 +198,7 @@ void OQS_SHA3_sha3_256(uint8_t *output, const uint8_t *input, size_t inlen) { OQS_SHA3_sha3_256_inc_ctx_release(&s); } -void OQS_SHA3_sha3_256_inc_init(OQS_SHA3_sha3_256_inc_ctx *state) { +static void SHA3_sha3_256_inc_init(OQS_SHA3_sha3_256_inc_ctx *state) { state->ctx = OQS_MEM_aligned_alloc(KECCAK_CTX_ALIGNMENT, KECCAK_CTX_BYTES); if (state->ctx == NULL) { exit(111); @@ -206,30 +206,30 @@ void OQS_SHA3_sha3_256_inc_init(OQS_SHA3_sha3_256_inc_ctx *state) { keccak_inc_reset((uint64_t *)state->ctx); } -void OQS_SHA3_sha3_256_inc_absorb(OQS_SHA3_sha3_256_inc_ctx *state, const uint8_t *input, size_t inlen) { +static void SHA3_sha3_256_inc_absorb(OQS_SHA3_sha3_256_inc_ctx *state, const uint8_t *input, size_t inlen) { keccak_inc_absorb((uint64_t *)state->ctx, OQS_SHA3_SHA3_256_RATE, input, inlen); } -void OQS_SHA3_sha3_256_inc_finalize(uint8_t *output, OQS_SHA3_sha3_256_inc_ctx *state) { +static void SHA3_sha3_256_inc_finalize(uint8_t *output, OQS_SHA3_sha3_256_inc_ctx *state) { keccak_inc_finalize((uint64_t *)state->ctx, OQS_SHA3_SHA3_256_RATE, 0x06); keccak_inc_squeeze(output, 32, (uint64_t *)state->ctx, OQS_SHA3_SHA3_256_RATE); } -void OQS_SHA3_sha3_256_inc_ctx_release(OQS_SHA3_sha3_256_inc_ctx *state) { +static void SHA3_sha3_256_inc_ctx_release(OQS_SHA3_sha3_256_inc_ctx *state) { OQS_MEM_aligned_free(state->ctx); } -void OQS_SHA3_sha3_256_inc_ctx_clone(OQS_SHA3_sha3_256_inc_ctx *dest, const OQS_SHA3_sha3_256_inc_ctx *src) { +static void SHA3_sha3_256_inc_ctx_clone(OQS_SHA3_sha3_256_inc_ctx *dest, const OQS_SHA3_sha3_256_inc_ctx *src) { memcpy(dest->ctx, src->ctx, KECCAK_CTX_BYTES); } -void OQS_SHA3_sha3_256_inc_ctx_reset(OQS_SHA3_sha3_256_inc_ctx *state) { +static void SHA3_sha3_256_inc_ctx_reset(OQS_SHA3_sha3_256_inc_ctx *state) { keccak_inc_reset((uint64_t *)state->ctx); } /* SHA3-384 */ -void OQS_SHA3_sha3_384(uint8_t *output, const uint8_t *input, size_t inlen) { +static void SHA3_sha3_384(uint8_t *output, const uint8_t *input, size_t inlen) { OQS_SHA3_sha3_384_inc_ctx s; OQS_SHA3_sha3_384_inc_init(&s); OQS_SHA3_sha3_384_inc_absorb(&s, input, inlen); @@ -237,7 +237,7 @@ void OQS_SHA3_sha3_384(uint8_t *output, const uint8_t *input, size_t inlen) { OQS_SHA3_sha3_384_inc_ctx_release(&s); } -void OQS_SHA3_sha3_384_inc_init(OQS_SHA3_sha3_384_inc_ctx *state) { +static void SHA3_sha3_384_inc_init(OQS_SHA3_sha3_384_inc_ctx *state) { state->ctx = OQS_MEM_aligned_alloc(KECCAK_CTX_ALIGNMENT, KECCAK_CTX_BYTES); if (state->ctx == NULL) { exit(111); @@ -245,30 +245,30 @@ void OQS_SHA3_sha3_384_inc_init(OQS_SHA3_sha3_384_inc_ctx *state) { keccak_inc_reset((uint64_t *)state->ctx); } -void OQS_SHA3_sha3_384_inc_absorb(OQS_SHA3_sha3_384_inc_ctx *state, const uint8_t *input, size_t inlen) { +static void SHA3_sha3_384_inc_absorb(OQS_SHA3_sha3_384_inc_ctx *state, const uint8_t *input, size_t inlen) { keccak_inc_absorb((uint64_t *)state->ctx, OQS_SHA3_SHA3_384_RATE, input, inlen); } -void OQS_SHA3_sha3_384_inc_finalize(uint8_t *output, OQS_SHA3_sha3_384_inc_ctx *state) { +static void SHA3_sha3_384_inc_finalize(uint8_t *output, OQS_SHA3_sha3_384_inc_ctx *state) { keccak_inc_finalize((uint64_t *)state->ctx, OQS_SHA3_SHA3_384_RATE, 0x06); keccak_inc_squeeze(output, 48, (uint64_t *)state->ctx, OQS_SHA3_SHA3_384_RATE); } -void OQS_SHA3_sha3_384_inc_ctx_release(OQS_SHA3_sha3_384_inc_ctx *state) { +static void SHA3_sha3_384_inc_ctx_release(OQS_SHA3_sha3_384_inc_ctx *state) { OQS_MEM_aligned_free(state->ctx); } -void OQS_SHA3_sha3_384_inc_ctx_clone(OQS_SHA3_sha3_384_inc_ctx *dest, const OQS_SHA3_sha3_384_inc_ctx *src) { +static void SHA3_sha3_384_inc_ctx_clone(OQS_SHA3_sha3_384_inc_ctx *dest, const OQS_SHA3_sha3_384_inc_ctx *src) { memcpy(dest->ctx, src->ctx, KECCAK_CTX_BYTES); } -void OQS_SHA3_sha3_384_inc_ctx_reset(OQS_SHA3_sha3_384_inc_ctx *state) { +static void SHA3_sha3_384_inc_ctx_reset(OQS_SHA3_sha3_384_inc_ctx *state) { keccak_inc_reset((uint64_t *)state->ctx); } /* SHA3-512 */ -void OQS_SHA3_sha3_512(uint8_t *output, const uint8_t *input, size_t inlen) { +static void SHA3_sha3_512(uint8_t *output, const uint8_t *input, size_t inlen) { OQS_SHA3_sha3_512_inc_ctx s; OQS_SHA3_sha3_512_inc_init(&s); OQS_SHA3_sha3_512_inc_absorb(&s, input, inlen); @@ -276,7 +276,7 @@ void OQS_SHA3_sha3_512(uint8_t *output, const uint8_t *input, size_t inlen) { OQS_SHA3_sha3_512_inc_ctx_release(&s); } -void OQS_SHA3_sha3_512_inc_init(OQS_SHA3_sha3_512_inc_ctx *state) { +static void SHA3_sha3_512_inc_init(OQS_SHA3_sha3_512_inc_ctx *state) { state->ctx = OQS_MEM_aligned_alloc(KECCAK_CTX_ALIGNMENT, KECCAK_CTX_BYTES); if (state->ctx == NULL) { exit(111); @@ -284,30 +284,30 @@ void OQS_SHA3_sha3_512_inc_init(OQS_SHA3_sha3_512_inc_ctx *state) { keccak_inc_reset((uint64_t *)state->ctx); } -void OQS_SHA3_sha3_512_inc_absorb(OQS_SHA3_sha3_512_inc_ctx *state, const uint8_t *input, size_t inlen) { +static void SHA3_sha3_512_inc_absorb(OQS_SHA3_sha3_512_inc_ctx *state, const uint8_t *input, size_t inlen) { keccak_inc_absorb((uint64_t *)state->ctx, OQS_SHA3_SHA3_512_RATE, input, inlen); } -void OQS_SHA3_sha3_512_inc_finalize(uint8_t *output, OQS_SHA3_sha3_512_inc_ctx *state) { +static void SHA3_sha3_512_inc_finalize(uint8_t *output, OQS_SHA3_sha3_512_inc_ctx *state) { keccak_inc_finalize((uint64_t *)state->ctx, OQS_SHA3_SHA3_512_RATE, 0x06); keccak_inc_squeeze(output, 64, (uint64_t *)state->ctx, OQS_SHA3_SHA3_512_RATE); } -void OQS_SHA3_sha3_512_inc_ctx_release(OQS_SHA3_sha3_512_inc_ctx *state) { +static void SHA3_sha3_512_inc_ctx_release(OQS_SHA3_sha3_512_inc_ctx *state) { OQS_MEM_aligned_free(state->ctx); } -void OQS_SHA3_sha3_512_inc_ctx_clone(OQS_SHA3_sha3_512_inc_ctx *dest, const OQS_SHA3_sha3_512_inc_ctx *src) { +static void SHA3_sha3_512_inc_ctx_clone(OQS_SHA3_sha3_512_inc_ctx *dest, const OQS_SHA3_sha3_512_inc_ctx *src) { memcpy(dest->ctx, src->ctx, KECCAK_CTX_BYTES); } -void OQS_SHA3_sha3_512_inc_ctx_reset(OQS_SHA3_sha3_512_inc_ctx *state) { +static void SHA3_sha3_512_inc_ctx_reset(OQS_SHA3_sha3_512_inc_ctx *state) { keccak_inc_reset((uint64_t *)state->ctx); } /* SHAKE128 */ -void OQS_SHA3_shake128(uint8_t *output, size_t outlen, const uint8_t *input, size_t inlen) { +static void SHA3_shake128(uint8_t *output, size_t outlen, const uint8_t *input, size_t inlen) { OQS_SHA3_shake128_inc_ctx s; OQS_SHA3_shake128_inc_init(&s); OQS_SHA3_shake128_inc_absorb(&s, input, inlen); @@ -318,7 +318,7 @@ void OQS_SHA3_shake128(uint8_t *output, size_t outlen, const uint8_t *input, siz /* SHAKE128 incremental */ -void OQS_SHA3_shake128_inc_init(OQS_SHA3_shake128_inc_ctx *state) { +static void SHA3_shake128_inc_init(OQS_SHA3_shake128_inc_ctx *state) { state->ctx = OQS_MEM_aligned_alloc(KECCAK_CTX_ALIGNMENT, KECCAK_CTX_BYTES); if (state->ctx == NULL) { exit(111); @@ -326,33 +326,33 @@ void OQS_SHA3_shake128_inc_init(OQS_SHA3_shake128_inc_ctx *state) { keccak_inc_reset((uint64_t *)state->ctx); } -void OQS_SHA3_shake128_inc_absorb(OQS_SHA3_shake128_inc_ctx *state, const uint8_t *input, size_t inlen) { +static void SHA3_shake128_inc_absorb(OQS_SHA3_shake128_inc_ctx *state, const uint8_t *input, size_t inlen) { keccak_inc_absorb((uint64_t *)state->ctx, OQS_SHA3_SHAKE128_RATE, input, inlen); } -void OQS_SHA3_shake128_inc_finalize(OQS_SHA3_shake128_inc_ctx *state) { +static void SHA3_shake128_inc_finalize(OQS_SHA3_shake128_inc_ctx *state) { keccak_inc_finalize((uint64_t *)state->ctx, OQS_SHA3_SHAKE128_RATE, 0x1F); } -void OQS_SHA3_shake128_inc_squeeze(uint8_t *output, size_t outlen, OQS_SHA3_shake128_inc_ctx *state) { +static void SHA3_shake128_inc_squeeze(uint8_t *output, size_t outlen, OQS_SHA3_shake128_inc_ctx *state) { keccak_inc_squeeze(output, outlen, (uint64_t *)state->ctx, OQS_SHA3_SHAKE128_RATE); } -void OQS_SHA3_shake128_inc_ctx_clone(OQS_SHA3_shake128_inc_ctx *dest, const OQS_SHA3_shake128_inc_ctx *src) { +static void SHA3_shake128_inc_ctx_clone(OQS_SHA3_shake128_inc_ctx *dest, const OQS_SHA3_shake128_inc_ctx *src) { memcpy(dest->ctx, src->ctx, KECCAK_CTX_BYTES); } -void OQS_SHA3_shake128_inc_ctx_release(OQS_SHA3_shake128_inc_ctx *state) { +static void SHA3_shake128_inc_ctx_release(OQS_SHA3_shake128_inc_ctx *state) { OQS_MEM_aligned_free(state->ctx); } -void OQS_SHA3_shake128_inc_ctx_reset(OQS_SHA3_shake128_inc_ctx *state) { +static void SHA3_shake128_inc_ctx_reset(OQS_SHA3_shake128_inc_ctx *state) { keccak_inc_reset((uint64_t *)state->ctx); } /* SHAKE256 */ -void OQS_SHA3_shake256(uint8_t *output, size_t outlen, const uint8_t *input, size_t inlen) { +static void SHA3_shake256(uint8_t *output, size_t outlen, const uint8_t *input, size_t inlen) { OQS_SHA3_shake256_inc_ctx s; OQS_SHA3_shake256_inc_init(&s); OQS_SHA3_shake256_inc_absorb(&s, input, inlen); @@ -363,7 +363,7 @@ void OQS_SHA3_shake256(uint8_t *output, size_t outlen, const uint8_t *input, siz /* SHAKE256 incremental */ -void OQS_SHA3_shake256_inc_init(OQS_SHA3_shake256_inc_ctx *state) { +static void SHA3_shake256_inc_init(OQS_SHA3_shake256_inc_ctx *state) { state->ctx = OQS_MEM_aligned_alloc(KECCAK_CTX_ALIGNMENT, KECCAK_CTX_BYTES); if (state->ctx == NULL) { exit(111); @@ -371,26 +371,68 @@ void OQS_SHA3_shake256_inc_init(OQS_SHA3_shake256_inc_ctx *state) { keccak_inc_reset((uint64_t *)state->ctx); } -void OQS_SHA3_shake256_inc_absorb(OQS_SHA3_shake256_inc_ctx *state, const uint8_t *input, size_t inlen) { +static void SHA3_shake256_inc_absorb(OQS_SHA3_shake256_inc_ctx *state, const uint8_t *input, size_t inlen) { keccak_inc_absorb((uint64_t *)state->ctx, OQS_SHA3_SHAKE256_RATE, input, inlen); } -void OQS_SHA3_shake256_inc_finalize(OQS_SHA3_shake256_inc_ctx *state) { +static void SHA3_shake256_inc_finalize(OQS_SHA3_shake256_inc_ctx *state) { keccak_inc_finalize((uint64_t *)state->ctx, OQS_SHA3_SHAKE256_RATE, 0x1F); } -void OQS_SHA3_shake256_inc_squeeze(uint8_t *output, size_t outlen, OQS_SHA3_shake256_inc_ctx *state) { +static void SHA3_shake256_inc_squeeze(uint8_t *output, size_t outlen, OQS_SHA3_shake256_inc_ctx *state) { keccak_inc_squeeze(output, outlen, state->ctx, OQS_SHA3_SHAKE256_RATE); } -void OQS_SHA3_shake256_inc_ctx_release(OQS_SHA3_shake256_inc_ctx *state) { +static void SHA3_shake256_inc_ctx_release(OQS_SHA3_shake256_inc_ctx *state) { OQS_MEM_aligned_free(state->ctx); } -void OQS_SHA3_shake256_inc_ctx_clone(OQS_SHA3_shake256_inc_ctx *dest, const OQS_SHA3_shake256_inc_ctx *src) { +static void SHA3_shake256_inc_ctx_clone(OQS_SHA3_shake256_inc_ctx *dest, const OQS_SHA3_shake256_inc_ctx *src) { memcpy(dest->ctx, src->ctx, KECCAK_CTX_BYTES); } -void OQS_SHA3_shake256_inc_ctx_reset(OQS_SHA3_shake256_inc_ctx *state) { +static void SHA3_shake256_inc_ctx_reset(OQS_SHA3_shake256_inc_ctx *state) { keccak_inc_reset((uint64_t *)state->ctx); } + +extern struct OQS_SHA3_callbacks sha3_default_callbacks; + +struct OQS_SHA3_callbacks sha3_default_callbacks = { + SHA3_sha3_256, + SHA3_sha3_256_inc_init, + SHA3_sha3_256_inc_absorb, + SHA3_sha3_256_inc_finalize, + SHA3_sha3_256_inc_ctx_release, + SHA3_sha3_256_inc_ctx_reset, + SHA3_sha3_256_inc_ctx_clone, + SHA3_sha3_384, + SHA3_sha3_384_inc_init, + SHA3_sha3_384_inc_absorb, + SHA3_sha3_384_inc_finalize, + SHA3_sha3_384_inc_ctx_release, + SHA3_sha3_384_inc_ctx_reset, + SHA3_sha3_384_inc_ctx_clone, + SHA3_sha3_512, + SHA3_sha3_512_inc_init, + SHA3_sha3_512_inc_absorb, + SHA3_sha3_512_inc_finalize, + SHA3_sha3_512_inc_ctx_release, + SHA3_sha3_512_inc_ctx_reset, + SHA3_sha3_512_inc_ctx_clone, + SHA3_shake128, + SHA3_shake128_inc_init, + SHA3_shake128_inc_absorb, + SHA3_shake128_inc_finalize, + SHA3_shake128_inc_squeeze, + SHA3_shake128_inc_ctx_release, + SHA3_shake128_inc_ctx_clone, + SHA3_shake128_inc_ctx_reset, + SHA3_shake256, + SHA3_shake256_inc_init, + SHA3_shake256_inc_absorb, + SHA3_shake256_inc_finalize, + SHA3_shake256_inc_squeeze, + SHA3_shake256_inc_ctx_release, + SHA3_shake256_inc_ctx_clone, + SHA3_shake256_inc_ctx_reset, +}; diff --git a/src/common/sha3/xkcp_sha3x4.c b/src/common/sha3/xkcp_sha3x4.c index fbd9a0e8..8ed5da87 100644 --- a/src/common/sha3/xkcp_sha3x4.c +++ b/src/common/sha3/xkcp_sha3x4.c @@ -155,7 +155,7 @@ static void keccak_x4_inc_squeeze(uint8_t *out0, uint8_t *out1, uint8_t *out2, u /********** SHAKE128 ***********/ -void OQS_SHA3_shake128_x4(uint8_t *out0, uint8_t *out1, uint8_t *out2, uint8_t *out3, size_t outlen, const uint8_t *in0, const uint8_t *in1, const uint8_t *in2, const uint8_t *in3, size_t inlen) { +static void SHA3_shake128_x4(uint8_t *out0, uint8_t *out1, uint8_t *out2, uint8_t *out3, size_t outlen, const uint8_t *in0, const uint8_t *in1, const uint8_t *in2, const uint8_t *in3, size_t inlen) { OQS_SHA3_shake128_x4_inc_ctx s; OQS_SHA3_shake128_x4_inc_init(&s); OQS_SHA3_shake128_x4_inc_absorb(&s, in0, in1, in2, in3, inlen); @@ -166,7 +166,7 @@ void OQS_SHA3_shake128_x4(uint8_t *out0, uint8_t *out1, uint8_t *out2, uint8_t * /* SHAKE128 incremental */ -void OQS_SHA3_shake128_x4_inc_init(OQS_SHA3_shake128_x4_inc_ctx *state) { +static void SHA3_shake128_x4_inc_init(OQS_SHA3_shake128_x4_inc_ctx *state) { state->ctx = OQS_MEM_aligned_alloc(KECCAK_X4_CTX_ALIGNMENT, KECCAK_X4_CTX_BYTES); if (state->ctx == NULL) { exit(111); @@ -174,33 +174,33 @@ void OQS_SHA3_shake128_x4_inc_init(OQS_SHA3_shake128_x4_inc_ctx *state) { keccak_x4_inc_reset((uint64_t *)state->ctx); } -void OQS_SHA3_shake128_x4_inc_absorb(OQS_SHA3_shake128_x4_inc_ctx *state, const uint8_t *in0, const uint8_t *in1, const uint8_t *in2, const uint8_t *in3, size_t inlen) { +static void SHA3_shake128_x4_inc_absorb(OQS_SHA3_shake128_x4_inc_ctx *state, const uint8_t *in0, const uint8_t *in1, const uint8_t *in2, const uint8_t *in3, size_t inlen) { keccak_x4_inc_absorb((uint64_t *)state->ctx, OQS_SHA3_SHAKE128_RATE, in0, in1, in2, in3, inlen); } -void OQS_SHA3_shake128_x4_inc_finalize(OQS_SHA3_shake128_x4_inc_ctx *state) { +static void SHA3_shake128_x4_inc_finalize(OQS_SHA3_shake128_x4_inc_ctx *state) { keccak_x4_inc_finalize((uint64_t *)state->ctx, OQS_SHA3_SHAKE128_RATE, 0x1F); } -void OQS_SHA3_shake128_x4_inc_squeeze(uint8_t *out0, uint8_t *out1, uint8_t *out2, uint8_t *out3, size_t outlen, OQS_SHA3_shake128_x4_inc_ctx *state) { +static void SHA3_shake128_x4_inc_squeeze(uint8_t *out0, uint8_t *out1, uint8_t *out2, uint8_t *out3, size_t outlen, OQS_SHA3_shake128_x4_inc_ctx *state) { keccak_x4_inc_squeeze(out0, out1, out2, out3, outlen, (uint64_t *)state->ctx, OQS_SHA3_SHAKE128_RATE); } -void OQS_SHA3_shake128_x4_inc_ctx_clone(OQS_SHA3_shake128_x4_inc_ctx *dest, const OQS_SHA3_shake128_x4_inc_ctx *src) { +static void SHA3_shake128_x4_inc_ctx_clone(OQS_SHA3_shake128_x4_inc_ctx *dest, const OQS_SHA3_shake128_x4_inc_ctx *src) { memcpy(dest->ctx, src->ctx, KECCAK_X4_CTX_BYTES); } -void OQS_SHA3_shake128_x4_inc_ctx_release(OQS_SHA3_shake128_x4_inc_ctx *state) { +static void SHA3_shake128_x4_inc_ctx_release(OQS_SHA3_shake128_x4_inc_ctx *state) { OQS_MEM_aligned_free(state->ctx); } -void OQS_SHA3_shake128_x4_inc_ctx_reset(OQS_SHA3_shake128_x4_inc_ctx *state) { +static void SHA3_shake128_x4_inc_ctx_reset(OQS_SHA3_shake128_x4_inc_ctx *state) { keccak_x4_inc_reset((uint64_t *)state->ctx); } /********** SHAKE256 ***********/ -void OQS_SHA3_shake256_x4(uint8_t *out0, uint8_t *out1, uint8_t *out2, uint8_t *out3, size_t outlen, const uint8_t *in0, const uint8_t *in1, const uint8_t *in2, const uint8_t *in3, size_t inlen) { +static void SHA3_shake256_x4(uint8_t *out0, uint8_t *out1, uint8_t *out2, uint8_t *out3, size_t outlen, const uint8_t *in0, const uint8_t *in1, const uint8_t *in2, const uint8_t *in3, size_t inlen) { OQS_SHA3_shake256_x4_inc_ctx s; OQS_SHA3_shake256_x4_inc_init(&s); OQS_SHA3_shake256_x4_inc_absorb(&s, in0, in1, in2, in3, inlen); @@ -211,7 +211,7 @@ void OQS_SHA3_shake256_x4(uint8_t *out0, uint8_t *out1, uint8_t *out2, uint8_t * /* SHAKE256 incremental */ -void OQS_SHA3_shake256_x4_inc_init(OQS_SHA3_shake256_x4_inc_ctx *state) { +static void SHA3_shake256_x4_inc_init(OQS_SHA3_shake256_x4_inc_ctx *state) { state->ctx = OQS_MEM_aligned_alloc(KECCAK_X4_CTX_ALIGNMENT, KECCAK_X4_CTX_BYTES); if (state->ctx == NULL) { exit(111); @@ -219,26 +219,47 @@ void OQS_SHA3_shake256_x4_inc_init(OQS_SHA3_shake256_x4_inc_ctx *state) { keccak_x4_inc_reset((uint64_t *)state->ctx); } -void OQS_SHA3_shake256_x4_inc_absorb(OQS_SHA3_shake256_x4_inc_ctx *state, const uint8_t *in0, const uint8_t *in1, const uint8_t *in2, const uint8_t *in3, size_t inlen) { +static void SHA3_shake256_x4_inc_absorb(OQS_SHA3_shake256_x4_inc_ctx *state, const uint8_t *in0, const uint8_t *in1, const uint8_t *in2, const uint8_t *in3, size_t inlen) { keccak_x4_inc_absorb((uint64_t *)state->ctx, OQS_SHA3_SHAKE256_RATE, in0, in1, in2, in3, inlen); } -void OQS_SHA3_shake256_x4_inc_finalize(OQS_SHA3_shake256_x4_inc_ctx *state) { +static void SHA3_shake256_x4_inc_finalize(OQS_SHA3_shake256_x4_inc_ctx *state) { keccak_x4_inc_finalize((uint64_t *)state->ctx, OQS_SHA3_SHAKE256_RATE, 0x1F); } -void OQS_SHA3_shake256_x4_inc_squeeze(uint8_t *out0, uint8_t *out1, uint8_t *out2, uint8_t *out3, size_t outlen, OQS_SHA3_shake256_x4_inc_ctx *state) { +static void SHA3_shake256_x4_inc_squeeze(uint8_t *out0, uint8_t *out1, uint8_t *out2, uint8_t *out3, size_t outlen, OQS_SHA3_shake256_x4_inc_ctx *state) { keccak_x4_inc_squeeze(out0, out1, out2, out3, outlen, (uint64_t *)state->ctx, OQS_SHA3_SHAKE256_RATE); } -void OQS_SHA3_shake256_x4_inc_ctx_clone(OQS_SHA3_shake256_x4_inc_ctx *dest, const OQS_SHA3_shake256_x4_inc_ctx *src) { +static void SHA3_shake256_x4_inc_ctx_clone(OQS_SHA3_shake256_x4_inc_ctx *dest, const OQS_SHA3_shake256_x4_inc_ctx *src) { memcpy(dest->ctx, src->ctx, KECCAK_X4_CTX_BYTES); } -void OQS_SHA3_shake256_x4_inc_ctx_release(OQS_SHA3_shake256_x4_inc_ctx *state) { +static void SHA3_shake256_x4_inc_ctx_release(OQS_SHA3_shake256_x4_inc_ctx *state) { OQS_MEM_aligned_free(state->ctx); } -void OQS_SHA3_shake256_x4_inc_ctx_reset(OQS_SHA3_shake256_x4_inc_ctx *state) { +static void SHA3_shake256_x4_inc_ctx_reset(OQS_SHA3_shake256_x4_inc_ctx *state) { keccak_x4_inc_reset((uint64_t *)state->ctx); } + +extern struct OQS_SHA3_x4_callbacks sha3_x4_default_callbacks; + +struct OQS_SHA3_x4_callbacks sha3_x4_default_callbacks = { + SHA3_shake128_x4, + SHA3_shake128_x4_inc_init, + SHA3_shake128_x4_inc_absorb, + SHA3_shake128_x4_inc_finalize, + SHA3_shake128_x4_inc_squeeze, + SHA3_shake128_x4_inc_ctx_release, + SHA3_shake128_x4_inc_ctx_clone, + SHA3_shake128_x4_inc_ctx_reset, + SHA3_shake256_x4, + SHA3_shake256_x4_inc_init, + SHA3_shake256_x4_inc_absorb, + SHA3_shake256_x4_inc_finalize, + SHA3_shake256_x4_inc_squeeze, + SHA3_shake256_x4_inc_ctx_release, + SHA3_shake256_x4_inc_ctx_clone, + SHA3_shake256_x4_inc_ctx_reset, +}; diff --git a/src/oqsconfig.h.cmake b/src/oqsconfig.h.cmake index 165d5473..f3b2e7c4 100644 --- a/src/oqsconfig.h.cmake +++ b/src/oqsconfig.h.cmake @@ -22,6 +22,8 @@ #cmakedefine OQS_USE_AES_OPENSSL 1 #cmakedefine OQS_USE_SHA2_OPENSSL 1 #cmakedefine OQS_USE_SHA3_OPENSSL 1 +#cmakedefine OQS_DLOPEN_OPENSSL 1 +#cmakedefine OQS_OPENSSL_CRYPTO_SONAME "@OQS_OPENSSL_CRYPTO_SONAME@" #cmakedefine OQS_EMBEDDED_BUILD 1 diff --git a/tests/test_aes.c b/tests/test_aes.c index f1fab56a..4ba265c6 100644 --- a/tests/test_aes.c +++ b/tests/test_aes.c @@ -116,9 +116,21 @@ static void speed_aes256(void) { OQS_AES256_free_schedule(schedule_dec); } +extern struct OQS_AES_callbacks aes_default_callbacks; + +static bool aes_callback_called = false; +static void override_AES128_ECB_load_schedule(const uint8_t *key, void **_schedule) { + aes_callback_called = true; + aes_default_callbacks.AES128_ECB_load_schedule(key, _schedule); +} + int main(int argc, char **argv) { bool bench = false; + struct OQS_AES_callbacks callbacks = aes_default_callbacks; + callbacks.AES128_ECB_load_schedule = override_AES128_ECB_load_schedule; + OQS_AES_set_callbacks(&callbacks); + OQS_init(); for (int i = 1; i < argc; i++) { if (argv[i][0] == '-') { @@ -156,6 +168,13 @@ int main(int argc, char **argv) { OQS_destroy(); return EXIT_FAILURE; } + + if (!aes_callback_called) { + printf("AES callback was not called\n"); + OQS_destroy(); + return EXIT_FAILURE; + } + printf("Tests passed.\n\n"); if (bench) { diff --git a/tests/test_hash.c b/tests/test_hash.c index d83f08eb..022fb61a 100644 --- a/tests/test_hash.c +++ b/tests/test_hash.c @@ -14,6 +14,8 @@ #define BUFFER_SIZE 30000 +static bool sha2_callback_called = false; + static int read_stdin(uint8_t **msg, size_t *msg_len) { *msg = malloc(BUFFER_SIZE); if (*msg == NULL) { @@ -198,7 +200,20 @@ static int do_arbitrary_hash(void (*hash)(uint8_t *, const uint8_t *, size_t), s return 0; } +extern struct OQS_SHA2_callbacks sha2_default_callbacks; + +static void override_SHA2_sha256_inc_init(OQS_SHA2_sha256_ctx *state) { + sha2_callback_called = true; + sha2_default_callbacks.SHA2_sha256_inc_init(state); +} + int main(int argc, char **argv) { + int ret; + struct OQS_SHA2_callbacks sha2_callbacks = sha2_default_callbacks; + + sha2_callbacks.SHA2_sha256_inc_init = override_SHA2_sha256_inc_init; + OQS_SHA2_set_callbacks(&sha2_callbacks); + OQS_init(); if (argc != 2) { fprintf(stderr, "Usage: test_hash algname\n"); @@ -213,26 +228,33 @@ int main(int argc, char **argv) { char *hash_alg = argv[1]; if (strcmp(hash_alg, "sha256inc") == 0) { - return do_sha256(); + ret = do_sha256(); } else if (strcmp(hash_alg, "sha384inc") == 0) { - return do_sha384(); + ret = do_sha384(); } else if (strcmp(hash_alg, "sha512inc") == 0) { - return do_sha512(); + ret = do_sha512(); } else if (strcmp(hash_alg, "sha256") == 0) { - return do_arbitrary_hash(&OQS_SHA2_sha256, 32); + ret = do_arbitrary_hash(&OQS_SHA2_sha256, 32); } else if (strcmp(hash_alg, "sha384") == 0) { - return do_arbitrary_hash(&OQS_SHA2_sha384, 48); + ret = do_arbitrary_hash(&OQS_SHA2_sha384, 48); } else if (strcmp(hash_alg, "sha512") == 0) { - return do_arbitrary_hash(&OQS_SHA2_sha512, 64); + ret = do_arbitrary_hash(&OQS_SHA2_sha512, 64); } else if (strcmp(hash_alg, "sha3_256") == 0) { - return do_arbitrary_hash(&OQS_SHA3_sha3_256, 32); + ret = do_arbitrary_hash(&OQS_SHA3_sha3_256, 32); } else if (strcmp(hash_alg, "sha3_384") == 0) { - return do_arbitrary_hash(&OQS_SHA3_sha3_384, 48); + ret = do_arbitrary_hash(&OQS_SHA3_sha3_384, 48); } else if (strcmp(hash_alg, "sha3_512") == 0) { - return do_arbitrary_hash(&OQS_SHA3_sha3_512, 64); + ret = do_arbitrary_hash(&OQS_SHA3_sha3_512, 64); } else { fprintf(stderr, "ERROR: Test not implemented\n"); - OQS_destroy(); - return EXIT_FAILURE; + ret = EXIT_FAILURE; } + + if (strcmp(hash_alg, "sha256inc") == 0 && !sha2_callback_called) { + fprintf(stderr, "ERROR: SHA2 callback was not called\n"); + ret = EXIT_FAILURE; + } + + OQS_destroy(); + return ret; } diff --git a/tests/test_sha3.c b/tests/test_sha3.c index 43e1296c..eadd9a09 100644 --- a/tests/test_sha3.c +++ b/tests/test_sha3.c @@ -17,6 +17,9 @@ #define UNUSED #endif +static bool sha3_callback_called = false; +static bool sha3_x4_callback_called = false; + /** * \file sha3_test.h * \brief SHA3 Known Answer Tests \n @@ -1037,12 +1040,36 @@ int shake_256_x4_kat_test(void) { return status; } +extern struct OQS_SHA3_callbacks sha3_default_callbacks; + +static void override_SHA3_sha3_256_inc_init(OQS_SHA3_sha3_256_inc_ctx *state) { + sha3_callback_called = true; + sha3_default_callbacks.SHA3_sha3_256_inc_init(state); +} + +extern struct OQS_SHA3_x4_callbacks sha3_x4_default_callbacks; + +static void override_SHA3_shake128_x4_inc_init(OQS_SHA3_shake128_x4_inc_ctx *state) { + sha3_x4_callback_called = true; + sha3_x4_default_callbacks.SHA3_shake128_x4_inc_init(state); +} + /** * \brief Run the SHA3 and SHAKE KAT tests */ int main(UNUSED int argc, UNUSED char **argv) { int ret = EXIT_SUCCESS; + struct OQS_SHA3_callbacks sha3_callbacks = sha3_default_callbacks; + + sha3_callbacks.SHA3_sha3_256_inc_init = override_SHA3_sha3_256_inc_init; + OQS_SHA3_set_callbacks(&sha3_callbacks); + + struct OQS_SHA3_x4_callbacks sha3_x4_callbacks = sha3_x4_default_callbacks; + + sha3_x4_callbacks.SHA3_shake128_x4_inc_init = override_SHA3_shake128_x4_inc_init; + OQS_SHA3_x4_set_callbacks(&sha3_x4_callbacks); + OQS_init(); print_system_info(); @@ -1087,6 +1114,17 @@ int main(UNUSED int argc, UNUSED char **argv) { printf("Failure! failed four-way parallel shake-256 known answer tests \n"); ret = EXIT_FAILURE; } + + if (!sha3_callback_called) { + printf("Failure! SHA3 callback was not called\n"); + ret = EXIT_FAILURE; + } + + if (!sha3_x4_callback_called) { + printf("Failure! SHA3_x4 callback was not called\n"); + ret = EXIT_FAILURE; + } + OQS_destroy(); -- 2.44.0