From 703cfded28e75665d4c315caf88a3ef653d9ecdc Mon Sep 17 00:00:00 2001 From: Mikhail Paulyshka Date: Fri, 15 Sep 2023 15:47:17 +0300 Subject: [PATCH 01/63] cmake: introduce `WOLFSSL_X86_64_BUILD` variable --- CMakeLists.txt | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 338dacf4ea..84a1acbed8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1568,17 +1568,13 @@ if(WOLFSSL_FAST_MATH) list(APPEND WOLFSSL_DEFINITIONS "-DUSE_FAST_MATH") set(WOLFSSL_SLOWMATH "no") endif() - - if("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "x86_64|AMD64") - # Have settings.h set FP_MAX_BITS higher if user didn't set directly - list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_X86_64_BUILD") - endif() endif() # TODO: - Fast huge math # Set processor-specific build macros if("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "x86_64|AMD64") + set(WOLFSSL_X86_64_BUILD ON) list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_X86_64_BUILD") elseif("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "aarch64|arm64") list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_AARCH64_BUILD") From 7adddc5fb8aa66827878ee15b79d9ed4ada5198a Mon Sep 17 00:00:00 2001 From: Mikhail Paulyshka Date: Fri, 15 Sep 2023 15:48:08 +0300 Subject: [PATCH 02/63] cmake/functions: do not try to build x86_64 assembler on non-AMD64 platforms --- cmake/functions.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/functions.cmake b/cmake/functions.cmake index 47ab832653..58ea8a37cf 100644 --- a/cmake/functions.cmake +++ b/cmake/functions.cmake @@ -280,7 +280,7 @@ function(generate_build_flags) if(WOLFSSL_SP_ARM_CORTEX_ASM OR WOLFSSL_USER_SETTINGS) set(BUILD_SP_ARM_CORTEX "yes" PARENT_SCOPE) endif() - if(WOLFSSL_SP_X86_64_ASM OR WOLFSSL_USER_SETTINGS) + if(WOLFSSL_X86_64_BUILD AND (WOLFSSL_SP_X86_64_ASM OR WOLFSSL_USER_SETTINGS)) set(BUILD_SP_X86_64 "yes" PARENT_SCOPE) endif() if(WOLFSSL_SP_MATH OR WOLFSSL_SP_MATH_ALL OR WOLFSSL_USER_SETTINGS) From fca2f14f48df485d17bea38bf18a5a0b3dab7104 Mon Sep 17 00:00:00 2001 From: Mikhail Paulyshka Date: Fri, 15 Sep 2023 16:27:11 +0300 Subject: [PATCH 03/63] cmake: guard installation with WOLFSSL_INSTALL option --- CMakeLists.txt | 158 +++++++++++++++++++++++++------------------------ 1 file changed, 82 insertions(+), 76 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 84a1acbed8..642ad494c7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -214,6 +214,8 @@ if(WOLFSSL_REPRODUCIBLE_BUILD) set(CMAKE_C_ARCHIVE_FINISH " -D ") endif() +add_option("WOLFSSL_INSTALL" "Create install target for WolfSSL project" "no" "yes;no") + # Support for forcing 32-bit mode # TODO: detect platform from other options add_option("WOLFSSL_32BIT" @@ -2409,82 +2411,86 @@ list(JOIN HEADER_EXCLUDE "|" EXCLUDED_HEADERS_REGEX) string(PREPEND EXCLUDED_HEADERS_REGEX "(") string(APPEND EXCLUDED_HEADERS_REGEX ")") -set(INSTALLED_EXAMPLES - ${CMAKE_CURRENT_SOURCE_DIR}/examples/echoserver/echoserver.c - ${CMAKE_CURRENT_SOURCE_DIR}/examples/sctp/sctp-server.c - ${CMAKE_CURRENT_SOURCE_DIR}/examples/sctp/sctp-client-dtls.c - ${CMAKE_CURRENT_SOURCE_DIR}/examples/sctp/sctp-client.c - ${CMAKE_CURRENT_SOURCE_DIR}/examples/sctp/sctp-server-dtls.c - ${CMAKE_CURRENT_SOURCE_DIR}/examples/echoclient/echoclient.c - ${CMAKE_CURRENT_SOURCE_DIR}/examples/server/server.c - ${CMAKE_CURRENT_SOURCE_DIR}/examples/benchmark/tls_bench.c - ${CMAKE_CURRENT_SOURCE_DIR}/examples/client/client.c) - -# Install the library -install(TARGETS wolfssl - EXPORT wolfssl-targets - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib - RUNTIME DESTINATION bin - ) -# Install the headers -install(DIRECTORY ${WOLFSSL_OUTPUT_BASE}/wolfssl/ - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/wolfssl - FILES_MATCHING PATTERN "*.h" - REGEX ${EXCLUDED_HEADERS_REGEX} EXCLUDE) -install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/wolfssl/ - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/wolfssl - FILES_MATCHING PATTERN "*.h" - REGEX ${EXCLUDED_HEADERS_REGEX} EXCLUDE) - -# Install the examples -install(FILES ${INSTALLED_EXAMPLES} - DESTINATION ${CMAKE_INSTALL_DOCDIR}/example) -# Install README.txt and taoCert.txt -install(FILES - ${CMAKE_CURRENT_SOURCE_DIR}/doc/README.txt - ${CMAKE_CURRENT_SOURCE_DIR}/certs/taoCert.txt - DESTINATION ${CMAKE_INSTALL_DOCDIR}) -# Install the export set -install(EXPORT wolfssl-targets - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/wolfssl - FILE wolfssl-targets.cmake - NAMESPACE wolfssl::) - -# TODO: Distro build + rules for what to include in the distro. -# See various include.am files. - -set(prefix ${CMAKE_INSTALL_PREFIX}) -set(exec_prefix "\${prefix}") -set(libdir "\${exec_prefix}/lib") -set(includedir "\${prefix}/include") -set(VERSION ${PROJECT_VERSION}) - -configure_file(support/wolfssl.pc.in ${CMAKE_CURRENT_BINARY_DIR}/support/wolfssl.pc @ONLY) -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/support/wolfssl.pc - DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) - -include(CMakePackageConfigHelpers) -configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Config.cmake.in - "${CMAKE_CURRENT_BINARY_DIR}/wolfssl-config.cmake" - INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/wolfssl" - NO_SET_AND_CHECK_MACRO - NO_CHECK_REQUIRED_COMPONENTS_MACRO -) +if(WOLFSSL_INSTALL) + + set(INSTALLED_EXAMPLES + ${CMAKE_CURRENT_SOURCE_DIR}/examples/echoserver/echoserver.c + ${CMAKE_CURRENT_SOURCE_DIR}/examples/sctp/sctp-server.c + ${CMAKE_CURRENT_SOURCE_DIR}/examples/sctp/sctp-client-dtls.c + ${CMAKE_CURRENT_SOURCE_DIR}/examples/sctp/sctp-client.c + ${CMAKE_CURRENT_SOURCE_DIR}/examples/sctp/sctp-server-dtls.c + ${CMAKE_CURRENT_SOURCE_DIR}/examples/echoclient/echoclient.c + ${CMAKE_CURRENT_SOURCE_DIR}/examples/server/server.c + ${CMAKE_CURRENT_SOURCE_DIR}/examples/benchmark/tls_bench.c + ${CMAKE_CURRENT_SOURCE_DIR}/examples/client/client.c) -export(EXPORT wolfssl-targets - FILE "${CMAKE_CURRENT_BINARY_DIR}/wolfssl-targets.cmake" - NAMESPACE wolfssl:: -) -write_basic_package_version_file( - "${CMAKE_CURRENT_BINARY_DIR}/wolfssl-config-version.cmake" - VERSION "${wolfssl_VERSION_MAJOR}.${wolfssl_VERSION_MINOR}" - COMPATIBILITY AnyNewerVersion -) + # Install the library + install(TARGETS wolfssl + EXPORT wolfssl-targets + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + RUNTIME DESTINATION bin + ) + # Install the headers + install(DIRECTORY ${WOLFSSL_OUTPUT_BASE}/wolfssl/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/wolfssl + FILES_MATCHING PATTERN "*.h" + REGEX ${EXCLUDED_HEADERS_REGEX} EXCLUDE) + install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/wolfssl/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/wolfssl + FILES_MATCHING PATTERN "*.h" + REGEX ${EXCLUDED_HEADERS_REGEX} EXCLUDE) + + # Install the examples + install(FILES ${INSTALLED_EXAMPLES} + DESTINATION ${CMAKE_INSTALL_DOCDIR}/example) + # Install README.txt and taoCert.txt + install(FILES + ${CMAKE_CURRENT_SOURCE_DIR}/doc/README.txt + ${CMAKE_CURRENT_SOURCE_DIR}/certs/taoCert.txt + DESTINATION ${CMAKE_INSTALL_DOCDIR}) + # Install the export set + install(EXPORT wolfssl-targets + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/wolfssl + FILE wolfssl-targets.cmake + NAMESPACE wolfssl::) + + # TODO: Distro build + rules for what to include in the distro. + # See various include.am files. + + set(prefix ${CMAKE_INSTALL_PREFIX}) + set(exec_prefix "\${prefix}") + set(libdir "\${exec_prefix}/lib") + set(includedir "\${prefix}/include") + set(VERSION ${PROJECT_VERSION}) + + configure_file(support/wolfssl.pc.in ${CMAKE_CURRENT_BINARY_DIR}/support/wolfssl.pc @ONLY) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/support/wolfssl.pc + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) + + include(CMakePackageConfigHelpers) + configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Config.cmake.in + "${CMAKE_CURRENT_BINARY_DIR}/wolfssl-config.cmake" + INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/wolfssl" + NO_SET_AND_CHECK_MACRO + NO_CHECK_REQUIRED_COMPONENTS_MACRO + ) -install(FILES - ${CMAKE_CURRENT_BINARY_DIR}/wolfssl-config.cmake - ${CMAKE_CURRENT_BINARY_DIR}/wolfssl-config-version.cmake - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/wolfssl -) + export(EXPORT wolfssl-targets + FILE "${CMAKE_CURRENT_BINARY_DIR}/wolfssl-targets.cmake" + NAMESPACE wolfssl:: + ) + + write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/wolfssl-config-version.cmake" + VERSION "${wolfssl_VERSION_MAJOR}.${wolfssl_VERSION_MINOR}" + COMPATIBILITY AnyNewerVersion + ) + + install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/wolfssl-config.cmake + ${CMAKE_CURRENT_BINARY_DIR}/wolfssl-config-version.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/wolfssl + ) +endif() From 944c7e175bc95e9f7f7a01fc09a45fc0657fcd17 Mon Sep 17 00:00:00 2001 From: Mikhail Paulyshka Date: Fri, 27 Oct 2023 17:06:07 +0300 Subject: [PATCH 04/63] cmake: add WOLFSSL_X86_64_BUILD_ASM option --- CMakeLists.txt | 1 + cmake/functions.cmake | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 642ad494c7..99fdc57ee0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1577,6 +1577,7 @@ endif() # Set processor-specific build macros if("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "x86_64|AMD64") set(WOLFSSL_X86_64_BUILD ON) + add_option("WOLFSSL_X86_64_BUILD_ASM" "Build ASM files" "yes" "yes;no") list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_X86_64_BUILD") elseif("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "aarch64|arm64") list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_AARCH64_BUILD") diff --git a/cmake/functions.cmake b/cmake/functions.cmake index 58ea8a37cf..757054a251 100644 --- a/cmake/functions.cmake +++ b/cmake/functions.cmake @@ -510,9 +510,10 @@ function(generate_lib_src_list LIB_SOURCES) endif() if(BUILD_SP_X86_64) - list(APPEND LIB_SOURCES - wolfcrypt/src/sp_x86_64.c - wolfcrypt/src/sp_x86_64_asm.S) + list(APPEND LIB_SOURCES wolfcrypt/src/sp_x86_64.c) + if(WOLFSSL_X86_64_BUILD_ASM) + list(APPEND LIB_SOURCES wolfcrypt/src/sp_x86_64_asm.S) + endif() endif() if(NOT BUILD_FIPS_V2 AND BUILD_SP_ARM32) From 999f84518c0b2820565f69eda001ab79664d634c Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Wed, 24 Jan 2024 16:09:15 +1000 Subject: [PATCH 05/63] RSA Decryption: check private value after decryption --- wolfcrypt/src/rsa.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index 3382a5db2d..af7abd5865 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -2723,6 +2723,17 @@ static int RsaFunctionSync(const byte* in, word32 inLen, byte* out, if (mp_to_unsigned_bin_len_ct(tmp, out, (int)*outLen) != MP_OKAY) ret = MP_TO_E; } +#ifdef WOLFSSL_RSA_CHECK_D_ON_DECRYPT + if ((ret == 0) && (type == RSA_PRIVATE_DECRYPT)) { + mp_sub(&key->n, &key->p, tmp); + mp_sub(tmp, &key->q, tmp); + mp_add_d(tmp, 1, tmp); + mp_mulmod(&key->d, &key->e, tmp, tmp); + if (!mp_isone(tmp)) { + ret = MP_EXPTMOD_E; + } + } +#endif #else (void)type; (void)key; From ac6181d7ae8600cab87a4a6f7fdd37369d13fb92 Mon Sep 17 00:00:00 2001 From: gojimmypi Date: Thu, 25 Jan 2024 15:23:58 -0800 Subject: [PATCH 06/63] Improved Espressif SHA HW/SW selection --- wolfcrypt/src/port/Espressif/esp32_sha.c | 22 ++++++++++++++----- wolfcrypt/src/sha256.c | 10 ++++----- wolfcrypt/src/sha512.c | 5 ++++- .../wolfcrypt/port/Espressif/esp32-crypt.h | 22 +++++++++++++++++-- wolfssl/wolfcrypt/settings.h | 10 +++++++++ 5 files changed, 56 insertions(+), 13 deletions(-) diff --git a/wolfcrypt/src/port/Espressif/esp32_sha.c b/wolfcrypt/src/port/Espressif/esp32_sha.c index 30ba0e7bba..f6ad645c73 100644 --- a/wolfcrypt/src/port/Espressif/esp32_sha.c +++ b/wolfcrypt/src/port/Espressif/esp32_sha.c @@ -679,7 +679,10 @@ int esp_sha256_ctx_copy(struct wc_Sha256* src, struct wc_Sha256* dst) } /* esp_sha256_ctx_copy */ #endif -#if defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512) +#if !(defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA384) && \ + defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512) \ + ) && \ + (defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512)) /* ** internal sha384 ctx copy for ESP HW */ @@ -744,7 +747,10 @@ int esp_sha384_ctx_copy(struct wc_Sha512* src, struct wc_Sha512* dst) } /* esp_sha384_ctx_copy */ #endif -#if defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512) +#if !(defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA384) && \ + defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512) \ + ) && \ + (defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512)) /* ** Internal sha512 ctx copy for ESP HW. ** If HW already active, fall back to SW for this ctx. @@ -1190,7 +1196,7 @@ int esp_sha_try_hw_lock(WC_ESP32SHA* ctx) ESP_LOGE(TAG, "unexpected error in esp_sha_try_hw_lock."); return ESP_FAIL; } -#else /* not ESP_FAILfined(SINGLE_THREADED) */ +#else /* not SINGLE_THREADED */ /* ** there's only one SHA engine for all the hash types ** so when any hash is in use, no others can use it. @@ -2013,7 +2019,7 @@ int wc_esp_digest_state(WC_ESP32SHA* ctx, byte* hash) pwrd1[i] ^= pwrd1[i + 1]; } } -#endif +#endif /* SHA512 or SHA384*/ #endif /* not CONFIG_IDF_TARGET_ESP32S3, C3, else... */ ESP_LOGV(TAG, "leave esp_digest_state"); @@ -2122,6 +2128,9 @@ int esp_sha256_digest_process(struct wc_Sha256* sha, byte blockprocess) } wc_esp_digest_state(&sha->ctx, (byte*)sha->digest); +#else + ESP_LOGE(TAG, "Call esp_sha256_digest_process with " + "NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256 "); #endif ESP_LOGV(TAG, "leave esp_sha256_digest_process"); return ret; @@ -2130,7 +2139,10 @@ int esp_sha256_digest_process(struct wc_Sha256* sha, byte blockprocess) #endif /* NO_SHA256 */ -#if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384) +#if !(defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA384) && \ + defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512) \ + ) && \ + (defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)) /* ** sha512 process. this is used for sha384 too. */ diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index 427927cd8c..2143dfc1fc 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -109,7 +109,8 @@ on the specific device platform. ** ** Beware of possible conflict in test.c (that one now named TEST_TAG) */ - #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) + #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \ + !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256) static const char* TAG = "wc_sha256"; #endif #endif @@ -731,7 +732,7 @@ static int InitSha256(wc_Sha256* sha256) sha256->hiLen = 0; #ifndef NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256 - ret = esp_sha_init(&(sha256->ctx), WC_HASH_TYPE_SHA256); + ret = esp_sha_init((WC_ESP32SHA*)&(sha256->ctx), WC_HASH_TYPE_SHA256); #endif return ret; } @@ -748,15 +749,14 @@ static int InitSha256(wc_Sha256* sha256) return BAD_FUNC_ARG; } - #ifdef WOLFSSL_USE_ESP32_CRYPT_HASH_HW -#ifndef NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256 + #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \ + !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256) /* We know this is a fresh, uninitialized item, so set to INIT */ if (sha256->ctx.mode != ESP32_SHA_INIT) { ESP_LOGV(TAG, "Set ctx mode from prior value: " "%d", sha256->ctx.mode); } sha256->ctx.mode = ESP32_SHA_INIT; -#endif #endif return InitSha256(sha256); diff --git a/wolfcrypt/src/sha512.c b/wolfcrypt/src/sha512.c index 90e86adfe6..263971729d 100644 --- a/wolfcrypt/src/sha512.c +++ b/wolfcrypt/src/sha512.c @@ -40,7 +40,10 @@ * but individual components can be turned off. See user_settings.h */ #define WOLFSSL_USE_ESP32_CRYPT_HASH_HW - static const char* TAG = "wc_sha_512"; + #if !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA384) && \ + !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512) + static const char* TAG = "wc_sha_512"; + #endif #else #undef WOLFSSL_USE_ESP32_CRYPT_HASH_HW #endif diff --git a/wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h b/wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h index f8d88ef8c3..b97e2a7b85 100644 --- a/wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h +++ b/wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h @@ -238,6 +238,11 @@ enum { ** See NO_HW_MATH_TEST. ** ******************************************************************************* +** WOLFSSL_FULL_WOLFSSH_SUPPORT +** TODO - there's a known, unresolved problem with SHA256 in wolfSSH +** Until fixed by a release version or this macro being define once resolved, +** this macro should remain undefined. +** */ #ifdef WOLFSSL_ESP32_CRYPT_DEBUG #undef LOG_LOCAL_LEVEL @@ -452,7 +457,10 @@ enum { #endif #ifdef SINGLE_THREADED - #undef ESP_MONITOR_HW_TASK_LOCK + #ifdef WOLFSSL_DEBUG_MUTEX + #undef ESP_MONITOR_HW_TASK_LOCK + #define ESP_MONITOR_HW_TASK_LOCK + #endif #else /* Unless explicitly disabled, monitor task lock when not single thread. */ #ifndef ESP_DISABLE_HW_TASK_LOCK @@ -616,7 +624,7 @@ extern "C" { /* pointer to object the initialized HW; to track copies */ void* initializer; -#ifndef SINGLE_THREADED +#if !defined(SINGLE_THREADED) || defined(ESP_MONITOR_HW_TASK_LOCK) void* task_owner; #endif @@ -857,6 +865,16 @@ extern "C" } #endif +/* Compatibility checks */ +#if defined(DEBUG_WOLFSSH) || defined(ESP_ENABLE_WOLFSSH) || \ + defined(WOLFSSH_TERM) || defined(WOLFSSH_TEST_SERVER) + #ifndef NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256 + /* need to add this line to wolfssl component user_settings.h + * #define NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256 */ + #error "ESP32_CRYPT_HASH_SHA256 not supported on wolfSSL at this time" + #endif +#endif /* SSH SHA256 HW check */ + #endif /* WOLFSSL_ESPIDF (entire contents excluded when not Espressif ESP-IDF) */ #endif /* __ESP32_CRYPT_H__ */ diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index c34f7f9966..8091b02c56 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -436,6 +436,16 @@ #define WC_NO_CACHE_RESISTANT #endif /* !WOLFSSL_ESPIDF_NO_DEFAULT */ + #if defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA384) && \ + !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512) + #error "NO_WOLFSSL_ESP32_CRYPT_HASH_SHA384 cannot be defined without" \ + "NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512 (enable or disable both)" + #endif + #if defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512) && \ + !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA384) + #error "NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512 cannot be defined without" \ + "NO_WOLFSSL_ESP32_CRYPT_HASH_SHA384 (enable or disable both)" + #endif #if defined(WOLFSSL_ESPWROOM32) /* WOLFSSL_ESPWROOM32 is a legacy macro gate. ** Not be be confused with WOLFSSL_ESPWROOM32SE, naming a specific board */ From 6dab75368d19649fe80bebce98296a8665505c3c Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Fri, 26 Jan 2024 10:20:03 +0100 Subject: [PATCH 07/63] [IoT-Safe] Add support sha384 + sha512 --- wolfcrypt/src/port/iotsafe/iotsafe.c | 44 ++++++++++++---------------- 1 file changed, 18 insertions(+), 26 deletions(-) diff --git a/wolfcrypt/src/port/iotsafe/iotsafe.c b/wolfcrypt/src/port/iotsafe/iotsafe.c index 8a3af53d99..e592fbcb06 100644 --- a/wolfcrypt/src/port/iotsafe/iotsafe.c +++ b/wolfcrypt/src/port/iotsafe/iotsafe.c @@ -749,43 +749,37 @@ static int iotsafe_hkdf_extract(byte* prk, const byte* salt, word32 saltLen, int ret; char *resp; uint16_t hash_algo = 0; - int len; + int hash_len; uint16_t hash_algo_be = 0; WOLFSSL_MSG("Enter iotsafe_hkdf_extract"); - switch (digest) { - #ifndef NO_SHA256 + switch (digest) { +#ifndef NO_SHA256 case WC_SHA256: - hash_algo = (uint16_t)1; - if (ikmLen == 0) { - len = WC_SHA256_DIGEST_SIZE; - } + hash_algo = (uint16_t)1; + hash_len = WC_SHA256_DIGEST_SIZE; break; - #endif - #ifdef WOLFSSL_SHA384 +#endif +#ifdef WOLFSSL_SHA384 case WC_SHA384: - hash_algo = (uint16_t)2; - if (ikmLen == 0) { - len = WC_SHA384_DIGEST_SIZE; - } + hash_algo = (uint16_t)2; + hash_len = WC_SHA384_DIGEST_SIZE; break; - #endif - #ifdef WOLFSSL_TLS13_SHA512 +#endif +#ifdef WOLFSSL_TLS13_SHA512 case WC_SHA512: - hash_algo = (uint16_t)4; - if (ikmLen == 0) { - len = WC_SHA512_DIGEST_SIZE; - } + hash_algo = (uint16_t)4; + hash_len = WC_SHA512_DIGEST_SIZE; break; - #endif +#endif default: return BAD_FUNC_ARG; break; - } + } if (ikmLen == 0) { - ikmLen = len; - XMEMSET(ikm, 0, len); + ikmLen = hash_len; + XMEMSET(ikm, 0, hash_len); } #ifdef DEBUG_IOTSAFE @@ -812,14 +806,12 @@ static int iotsafe_hkdf_extract(byte* prk, const byte* salt, word32 saltLen, WOLFSSL_MSG("Unexpected reply from HKDF extract"); ret = WC_HW_E; } else { - - ret = hexbuffer_conv(resp, prk, 32); + ret = hexbuffer_conv(resp, prk, hash_len); if (ret < 0) ret = WC_HW_E; else ret = 0; } - return ret; } #endif From 5b3ba8f4bba70d3f32b8c5bf8c578599a1747947 Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Fri, 26 Jan 2024 10:22:40 +0100 Subject: [PATCH 08/63] Removed "256-bit hash" references from doxygen --- doc/dox_comments/header_files/iotsafe.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/dox_comments/header_files/iotsafe.h b/doc/dox_comments/header_files/iotsafe.h index d04d8f31f8..46bd2e5da1 100644 --- a/doc/dox_comments/header_files/iotsafe.h +++ b/doc/dox_comments/header_files/iotsafe.h @@ -346,7 +346,7 @@ int wc_iotsafe_ecc_export_private_ex(ecc_key *key, byte *key_id, word16 id_size) /*! \ingroup IoTSafe - \brief Sign a pre-computed 256-bit HASH, using a private key previously stored, or pre-provisioned, + \brief Sign a pre-computed HASH, using a private key previously stored, or pre-provisioned, in the IoT-Safe applet. \param in pointer to the buffer containing the message hash to sign @@ -367,7 +367,7 @@ int wc_iotsafe_ecc_sign_hash(byte *in, word32 inlen, byte *out, word32 *outlen, /*! \ingroup IoTSafe - \brief Sign a pre-computed 256-bit HASH, using a private key previously stored, or pre-provisioned, + \brief Sign a pre-computed HASH, using a private key previously stored, or pre-provisioned, in the IoT-Safe applet. Equivalent to \ref wc_iotsafe_ecc_sign_hash "wc_iotsafe_ecc_sign_hash", except that it can be invoked with a key ID of two or more bytes. @@ -390,7 +390,7 @@ int wc_iotsafe_ecc_sign_hash_ex(byte *in, word32 inlen, byte *out, word32 *outle /*! \ingroup IoTSafe - \brief Verify an ECC signature against a pre-computed 256-bit HASH, using a public key previously stored, or pre-provisioned, + \brief Verify an ECC signature against a pre-computed HASH, using a public key previously stored, or pre-provisioned, in the IoT-Safe applet. Result is written to res. 1 is valid, 0 is invalid. Note: Do not use the return value to test for valid. Only use res. @@ -412,7 +412,7 @@ int wc_iotsafe_ecc_verify_hash(byte *sig, word32 siglen, byte *hash, word32 hash /*! \ingroup IoTSafe - \brief Verify an ECC signature against a pre-computed 256-bit HASH, using a public key previously stored, or pre-provisioned, + \brief Verify an ECC signature against a pre-computed HASH, using a public key previously stored, or pre-provisioned, in the IoT-Safe applet. Result is written to res. 1 is valid, 0 is invalid. Note: Do not use the return value to test for valid. Only use res. Equivalent to \ref wc_iotsafe_ecc_verify_hash "wc_iotsafe_ecc_verify_hash", From 72e34a829afeb6f1e0df49877b28e2abe6ee3759 Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Fri, 26 Jan 2024 16:35:08 +0100 Subject: [PATCH 09/63] Fixed wrong define --- wolfcrypt/src/port/iotsafe/iotsafe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wolfcrypt/src/port/iotsafe/iotsafe.c b/wolfcrypt/src/port/iotsafe/iotsafe.c index e592fbcb06..8a7ec2e635 100644 --- a/wolfcrypt/src/port/iotsafe/iotsafe.c +++ b/wolfcrypt/src/port/iotsafe/iotsafe.c @@ -766,7 +766,7 @@ static int iotsafe_hkdf_extract(byte* prk, const byte* salt, word32 saltLen, hash_len = WC_SHA384_DIGEST_SIZE; break; #endif -#ifdef WOLFSSL_TLS13_SHA512 +#ifdef WOLFSSL_SHA512 case WC_SHA512: hash_algo = (uint16_t)4; hash_len = WC_SHA512_DIGEST_SIZE; From fe87f161145c8ebe281a5874e76e78f22e0f5be4 Mon Sep 17 00:00:00 2001 From: Anthony Hu Date: Fri, 26 Jan 2024 14:51:51 -0500 Subject: [PATCH 10/63] Fixes that prevent memory leaks when using OQS. Fixes ZD 17177. --- src/tls.c | 28 +++++++++++++++++++++----- wolfcrypt/src/port/liboqs/liboqs.c | 5 +++++ wolfcrypt/src/wc_port.c | 4 ++++ wolfssl/internal.h | 1 + wolfssl/wolfcrypt/port/liboqs/liboqs.h | 2 ++ 5 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/tls.c b/src/tls.c index 04794ae944..c32aa31062 100644 --- a/src/tls.c +++ b/src/tls.c @@ -7658,6 +7658,13 @@ static int TLSX_KeyShare_GenPqcKey(WOLFSSL *ssl, KeyShareEntry* kse) word32 privSz = 0; word32 pubSz = 0; + /* This gets called twice. Once during parsing of the key share and once + * during the population of the extension. No need to do work the second + * time. Just return success if its already been done. */ + if (kse->pubKey != NULL) { + return ret; + } + findEccPqc(&ecc_group, &oqs_group, kse->group); ret = kyber_id2type(oqs_group, &type); if (ret == NOT_COMPILED_IN) { @@ -7735,10 +7742,11 @@ static int TLSX_KeyShare_GenPqcKey(WOLFSSL *ssl, KeyShareEntry* kse) /* Note we are saving the OQS private key and ECC private key * separately. That's because the ECC private key is not simply a - * buffer. Its is an ecc_key struct. - */ + * buffer. Its is an ecc_key struct. Typically do not need the private + * key size, but will need to zero it out upon freeing. */ kse->privKey = privKey; privKey = NULL; + kse->privKeyLen = privSz; kse->key = ecc_kse->key; ecc_kse->key = NULL; @@ -7814,9 +7822,19 @@ static void TLSX_KeyShare_FreeAll(KeyShareEntry* list, void* heap) #endif } #ifdef HAVE_PQC - else if (WOLFSSL_NAMED_GROUP_IS_PQC(current->group) && - current->key != NULL) { - ForceZero((byte*)current->key, current->keyLen); + else if (WOLFSSL_NAMED_GROUP_IS_PQC(current->group)) { + if (current->key != NULL) { + ForceZero((byte*)current->key, current->keyLen); + } + if (current->pubKey != NULL) { + XFREE(current->pubKey, heap, DYNAMIC_TYPE_PUBLIC_KEY); + current->pubKey = NULL; + } + if (current->privKey != NULL) { + ForceZero(current->privKey, current->privKeyLen); + XFREE(current->privKey, heap, DYNAMIC_TYPE_PRIVATE_KEY); + current->privKey = NULL; + } } #endif else { diff --git a/wolfcrypt/src/port/liboqs/liboqs.c b/wolfcrypt/src/port/liboqs/liboqs.c index 2568330529..f04cab02c7 100644 --- a/wolfcrypt/src/port/liboqs/liboqs.c +++ b/wolfcrypt/src/port/liboqs/liboqs.c @@ -99,6 +99,11 @@ int wolfSSL_liboqsInit(void) return ret; } +void wolfSSL_liboqsClose(void) +{ + wc_FreeRng(&liboqsDefaultRNG); +} + int wolfSSL_liboqsRngMutexLock(WC_RNG* rng) { int ret = wolfSSL_liboqsInit(); diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index a6ebe7e91c..8cb8a0c189 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -493,6 +493,10 @@ int wolfCrypt_Cleanup(void) #endif } +#if defined(HAVE_LIBOQS) + wolfSSL_liboqsClose(); +#endif + return ret; } diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 5baeb93b0f..572114e52a 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -3365,6 +3365,7 @@ typedef struct KeyShareEntry { word32 pubKeyLen; /* Public key length */ #if !defined(NO_DH) || defined(HAVE_PQC) byte* privKey; /* Private key - DH and PQ KEMs only */ + word32 privKeyLen;/* Only for PQ KEMs. */ #endif #ifdef WOLFSSL_ASYNC_CRYPT int lastRet; diff --git a/wolfssl/wolfcrypt/port/liboqs/liboqs.h b/wolfssl/wolfcrypt/port/liboqs/liboqs.h index d93ec2f2b7..58da9ba2be 100644 --- a/wolfssl/wolfcrypt/port/liboqs/liboqs.h +++ b/wolfssl/wolfcrypt/port/liboqs/liboqs.h @@ -47,6 +47,8 @@ implementations for Post-Quantum cryptography algorithms. int wolfSSL_liboqsInit(void); +void wolfSSL_liboqsClose(void); + int wolfSSL_liboqsRngMutexLock(WC_RNG* rng); int wolfSSL_liboqsRngMutexUnlock(void); From 6e559ed015806d5c40bd7b569cb095c3281eada2 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Fri, 26 Jan 2024 14:04:02 -0600 Subject: [PATCH 11/63] linuxkm: squash of philljj's POC work integrating libwolfssl.ko with crypto_register_skcipher/crypto_register_aead, start 2022-12-26, end 2023-01-14. --- linuxkm/Kbuild | 7 +- linuxkm/module_hooks.c | 1183 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1189 insertions(+), 1 deletion(-) diff --git a/linuxkm/Kbuild b/linuxkm/Kbuild index 093a7a112f..6eac94d282 100644 --- a/linuxkm/Kbuild +++ b/linuxkm/Kbuild @@ -49,7 +49,12 @@ hostprogs := linuxkm/get_thread_size always-y := $(hostprogs) # "-mindirect-branch=keep -mfunction-return=keep" to avoid "undefined reference # to `__x86_return_thunk'" on CONFIG_RETHUNK kernels (5.19.0-rc7) -HOST_EXTRACFLAGS += $(NOSTDINC_FLAGS) $(LINUXINCLUDE) $(KBUILD_CFLAGS) -static -fno-omit-frame-pointer -mindirect-branch=keep -mfunction-return=keep +ifeq "$(KERNEL_ARCH)" "aarch64" + HOST_EXTRACFLAGS += $(NOSTDINC_FLAGS) $(LINUXINCLUDE) $(KBUILD_CFLAGS) -static -fno-omit-frame-pointer +else + HOST_EXTRACFLAGS += $(NOSTDINC_FLAGS) $(LINUXINCLUDE) $(KBUILD_CFLAGS) -static -fno-omit-frame-pointer -mindirect-branch=keep -mfunction-return=keep +endif + # this rule is needed to get build to succeed in 4.x (get_thread_size still doesn't get built) $(obj)/linuxkm/get_thread_size: $(src)/linuxkm/get_thread_size.c diff --git a/linuxkm/module_hooks.c b/linuxkm/module_hooks.c index 8ee34dff61..73673631d9 100644 --- a/linuxkm/module_hooks.c +++ b/linuxkm/module_hooks.c @@ -126,6 +126,34 @@ static int updateFipsHash(void); #include "wolfcrypt/benchmark/benchmark.c" #endif /* WOLFSSL_LINUXKM_BENCHMARKS */ +#ifdef LINUXKM_REGISTER_ALG +#if defined(NO_AES) + #error LINUXKM_REGISTER_ALG requires AES. +#endif + +#if !defined(HAVE_AESGCM) && !defined(HAVe_AES_CBC) && !defined(WOLFSSL_AES_CFB) + #error LINUXKM_REGISTER_ALG requires AES-CBC, CFB, or GCM. +#endif + +#if defined(HAVE_AESGCM) && !defined(WOLFSSL_AESGCM_STREAM) + #error LINUXKM_REGISTER_ALG requires AESGCM_STREAM. +#endif + +#define WOLFKM_CBC_NAME "cbc(aes)" +#define WOLFKM_CFB_NAME "cfb(aes)" +#define WOLFKM_GCM_NAME "gcm(aes)" +#define WOLFKM_CBC_DRIVER "cbc-aes-wolfcrypt" +#define WOLFKM_CFB_DRIVER "cfb-aes-wolfcrypt" +#define WOLFKM_GCM_DRIVER "gcm-aes-wolfcrypt" +#define WOLFKM_ALG_PRIORITY (100) +static int linuxkm_register_alg(void); +static void linuxkm_unregister_alg(void); +static int linuxkm_test_alg(void); +static int linuxkm_test_cbc(void); +static int linuxkm_test_cfb(void); +static int linuxkm_test_gcm(void); +#endif /* endif LINUXKM_REGISTER_ALG */ + #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0) static int __init wolfssl_init(void) #else @@ -315,6 +343,27 @@ static int wolfssl_init(void) ); #endif +#if defined(LINUXKM_REGISTER_ALG) && !defined(NO_AES) + ret = linuxkm_register_alg(); + + if (ret) { + pr_err("linuxkm_register_alg failed with return code %d.\n", ret); + (void)libwolfssl_cleanup(); + linuxkm_unregister_alg(); + msleep(10); + return -ECANCELED; + } + + ret = linuxkm_test_alg(); + + if (ret) { + pr_err("linuxkm_test_alg failed with return code %d.\n", ret); + (void)libwolfssl_cleanup(); + linuxkm_unregister_alg(); + msleep(10); + return -ECANCELED; + } +#endif return 0; } @@ -328,6 +377,9 @@ static void wolfssl_exit(void) { (void)libwolfssl_cleanup(); +#if defined(LINUXKM_REGISTER_ALG) && !defined(NO_AES) + linuxkm_unregister_alg(); +#endif return; } @@ -739,3 +791,1134 @@ static int updateFipsHash(void) } #endif /* WOLFCRYPT_FIPS_CORE_DYNAMIC_HASH_VALUE */ + + +#if defined(LINUXKM_REGISTER_ALG) && !defined(NO_AES) +#include + +PRAGMA_GCC_DIAG_PUSH; +PRAGMA_GCC("GCC diagnostic ignored \"-Wnested-externs\""); +PRAGMA_GCC("GCC diagnostic ignored \"-Wpointer-arith\""); +PRAGMA_GCC("GCC diagnostic ignored \"-Wpointer-sign\""); +PRAGMA_GCC("GCC diagnostic ignored \"-Wbad-function-cast\""); +PRAGMA_GCC("GCC diagnostic ignored \"-Wunused-parameter\""); +#include +#include +#include +#include +PRAGMA_GCC_DIAG_POP; + +/* km_AesX(): wrappers to wolfcrypt wc_AesX functions and + * structures. */ + +struct km_AesCtx { + Aes aes; + u8 key[AES_MAX_KEY_SIZE / 8]; + unsigned int keylen; +}; + +static inline void km_ForceZero(struct km_AesCtx * ctx) +{ + memzero_explicit(ctx->key, sizeof(ctx->key)); + ctx->keylen = 0; +} + +static int km_AesInitCommon(struct km_AesCtx * ctx, const char * name) +{ + int err = wc_AesInit(&ctx->aes, NULL, INVALID_DEVID); + + if (unlikely(err)) { + pr_err("error: km_AesInitCommon %s failed: %d\n", name, err); + return err; + } + + return 0; +} + +static void km_AesExitCommon(struct km_AesCtx * ctx) +{ + wc_AesFree(&ctx->aes); + km_ForceZero(ctx); +} + +static int km_AesSetKeyCommon(struct km_AesCtx * ctx, const u8 *in_key, + unsigned int key_len, const char * name) +{ + int err = wc_AesSetKey(&ctx->aes, in_key, key_len, NULL, 0); + + if (unlikely(err)) { + pr_err("error: km_AesSetKeyCommon %s failed: %d\n", name, err); + return err; + } + + XMEMCPY(ctx->key, in_key, key_len); + ctx->keylen = key_len; + + return 0; +} + +static int km_AesInit(struct crypto_skcipher *tfm) +{ + struct km_AesCtx * ctx = crypto_skcipher_ctx(tfm); + return km_AesInitCommon(ctx, WOLFKM_CBC_DRIVER); +} + +static void km_AesExit(struct crypto_skcipher *tfm) +{ + struct km_AesCtx * ctx = crypto_skcipher_ctx(tfm); + km_AesExitCommon(ctx); +} + +static int km_AesSetKey(struct crypto_skcipher *tfm, const u8 *in_key, + unsigned int key_len) +{ + struct km_AesCtx * ctx = crypto_skcipher_ctx(tfm); + return km_AesSetKeyCommon(ctx, in_key, key_len, WOLFKM_CBC_DRIVER); +} + +#if defined(HAVE_AES_CBC) +static int km_AesCbcEncrypt(struct skcipher_request *req) +{ + struct crypto_skcipher * tfm = NULL; + struct km_AesCtx * ctx = NULL; + struct skcipher_walk walk; + unsigned int nbytes = 0; + int err = 0; + + tfm = crypto_skcipher_reqtfm(req); + ctx = crypto_skcipher_ctx(tfm); + + err = skcipher_walk_virt(&walk, req, false); + + while ((nbytes = walk.nbytes)) { + err = wc_AesSetKey(&ctx->aes, ctx->key, ctx->keylen, walk.iv, + AES_ENCRYPTION); + + if (unlikely(err)) { + pr_err("wc_AesSetKey failed: %d\n", err); + return err; + } + + err = wc_AesCbcEncrypt(&ctx->aes, walk.dst.virt.addr, + walk.src.virt.addr, nbytes); + + if (unlikely(err)) { + pr_err("wc_AesCbcEncrypt failed %d\n", err); + return err; + } + + err = skcipher_walk_done(&walk, walk.nbytes - nbytes); + } + + return err; +} + +static int km_AesCbcDecrypt(struct skcipher_request *req) +{ + struct crypto_skcipher * tfm = NULL; + struct km_AesCtx * ctx = NULL; + struct skcipher_walk walk; + unsigned int nbytes = 0; + int err = 0; + + tfm = crypto_skcipher_reqtfm(req); + ctx = crypto_skcipher_ctx(tfm); + + err = skcipher_walk_virt(&walk, req, false); + + while ((nbytes = walk.nbytes)) { + err = wc_AesSetKey(&ctx->aes, ctx->key, ctx->keylen, walk.iv, + AES_DECRYPTION); + + if (unlikely(err)) { + pr_err("wc_AesSetKey failed"); + return err; + } + + err = wc_AesCbcDecrypt(&ctx->aes, walk.dst.virt.addr, + walk.src.virt.addr, nbytes); + + if (unlikely(err)) { + pr_err("wc_AesCbcDecrypt failed"); + return err; + } + + err = skcipher_walk_done(&walk, walk.nbytes - nbytes); + } + + return err; +} +#endif /* endif HAVE_AES_CBC */ + +#if defined(WOLFSSL_AES_CFB) +static int km_AesCfbEncrypt(struct skcipher_request *req) +{ + struct crypto_skcipher * tfm = NULL; + struct km_AesCtx * ctx = NULL; + struct skcipher_walk walk; + unsigned int nbytes = 0; + int err = 0; + + tfm = crypto_skcipher_reqtfm(req); + ctx = crypto_skcipher_ctx(tfm); + + err = skcipher_walk_virt(&walk, req, false); + + while ((nbytes = walk.nbytes)) { + err = wc_AesSetKey(&ctx->aes, ctx->key, ctx->keylen, walk.iv, + AES_ENCRYPTION); + + if (unlikely(err)) { + pr_err("wc_AesSetKey failed: %d\n", err); + return err; + } + + err = wc_AesCfbEncrypt(&ctx->aes, walk.dst.virt.addr, + walk.src.virt.addr, nbytes); + + if (unlikely(err)) { + pr_err("wc_AesCfbEncrypt failed %d\n", err); + return err; + } + + err = skcipher_walk_done(&walk, walk.nbytes - nbytes); + } + + return err; +} + +static int km_AesCfbDecrypt(struct skcipher_request *req) +{ + struct crypto_skcipher * tfm = NULL; + struct km_AesCtx * ctx = NULL; + struct skcipher_walk walk; + unsigned int nbytes = 0; + int err = 0; + + tfm = crypto_skcipher_reqtfm(req); + ctx = crypto_skcipher_ctx(tfm); + + err = skcipher_walk_virt(&walk, req, false); + + while ((nbytes = walk.nbytes)) { + err = wc_AesSetKey(&ctx->aes, ctx->key, ctx->keylen, walk.iv, + AES_ENCRYPTION); + + if (unlikely(err)) { + pr_err("wc_AesSetKey failed"); + return err; + } + + err = wc_AesCfbDecrypt(&ctx->aes, walk.dst.virt.addr, + walk.src.virt.addr, nbytes); + + if (unlikely(err)) { + pr_err("wc_AesCfbDecrypt failed"); + return err; + } + + err = skcipher_walk_done(&walk, walk.nbytes - nbytes); + } + + return err; +} +#endif /* endif WOLFSSL_AES_CFB */ + + +#if defined(HAVE_AESGCM) +static int km_AesGcmInit(struct crypto_aead * tfm) +{ + struct km_AesCtx * ctx = crypto_aead_ctx(tfm); + km_ForceZero(ctx); + return km_AesInitCommon(ctx, WOLFKM_GCM_DRIVER); +} + +static void km_AesGcmExit(struct crypto_aead * tfm) +{ + struct km_AesCtx * ctx = crypto_aead_ctx(tfm); + km_AesExitCommon(ctx); +} + +static int km_AesGcmSetKey(struct crypto_aead *tfm, const u8 *in_key, + unsigned int key_len) +{ + struct km_AesCtx * ctx = crypto_aead_ctx(tfm); + return km_AesSetKeyCommon(ctx, in_key, key_len, WOLFKM_GCM_DRIVER); +} + +static int km_AesGcmSetAuthsize(struct crypto_aead *tfm, unsigned int authsize) +{ + (void)tfm; + if (authsize > AES_BLOCK_SIZE || + authsize < WOLFSSL_MIN_AUTH_TAG_SZ) { + pr_err("error: invalid authsize: %d\n", authsize); + return -EINVAL; + } + return 0; +} + +/* + * aead ciphers recieve data in scatterlists in following order: + * encrypt + * req->src: aad||plaintext + * req->dst: aad||ciphertext||tag + * decrypt + * req->src: aad||ciphertext||tag + * req->dst: aad||plaintext, return 0 or -EBADMSG + */ + +static int km_AesGcmEncrypt(struct aead_request *req) +{ + struct crypto_aead * tfm = NULL; + struct km_AesCtx * ctx = NULL; + struct skcipher_walk walk; + struct scatter_walk assocSgWalk; + unsigned int nbytes = 0; + u8 authTag[AES_BLOCK_SIZE]; + int err = 0; + unsigned int assocLeft = 0; + unsigned int cryptLeft = 0; + u8 * assoc = NULL; + + tfm = crypto_aead_reqtfm(req); + ctx = crypto_aead_ctx(tfm); + assocLeft = req->assoclen; + cryptLeft = req->cryptlen; + + scatterwalk_start(&assocSgWalk, req->src); + + err = skcipher_walk_aead_encrypt(&walk, req, false); + if (unlikely(err)) { + pr_err("error: skcipher_walk_aead_encrypt: %d\n", err); + return -1; + } + + err = wc_AesGcmInit(&ctx->aes, ctx->key, ctx->keylen, walk.iv, + AES_BLOCK_SIZE); + if (unlikely(err)) { + pr_err("error: wc_AesGcmInit failed with return code %d.\n", err); + return err; + } + + assoc = scatterwalk_map(&assocSgWalk); + if (unlikely(IS_ERR(assoc))) { + pr_err("error: scatterwalk_map failed %ld\n", PTR_ERR(assoc)); + return err; + } + + err = wc_AesGcmEncryptUpdate(&ctx->aes, NULL, NULL, 0, assoc, assocLeft); + assocLeft -= assocLeft; + scatterwalk_unmap(assoc); + assoc = NULL; + + if (unlikely(err)) { + pr_err("error: wc_AesGcmEncryptUpdate failed %d\n", err); + return err; + } + + while ((nbytes = walk.nbytes)) { + int n = nbytes; + + if (likely(cryptLeft && nbytes)) { + n = cryptLeft < nbytes ? cryptLeft : nbytes; + + err = wc_AesGcmEncryptUpdate(&ctx->aes, walk.dst.virt.addr, + walk.src.virt.addr, cryptLeft, NULL, 0); + nbytes -= n; + cryptLeft -= n; + } + + if (unlikely(err)) { + pr_err("wc_AesGcmEncryptUpdate failed %d\n", err); + return err; + } + + err = skcipher_walk_done(&walk, nbytes); + } + + err = wc_AesGcmEncryptFinal(&ctx->aes, authTag, tfm->authsize); + if (unlikely(err)) { + pr_err("error: wc_AesGcmEncryptFinal failed with return code %d\n", err); + return err; + } + + /* Now copy the auth tag into request scatterlist. */ + scatterwalk_map_and_copy(authTag, req->dst, + req->assoclen + req->cryptlen, + tfm->authsize, 1); + + return err; +} + +static int km_AesGcmDecrypt(struct aead_request *req) +{ + struct crypto_aead * tfm = NULL; + struct km_AesCtx * ctx = NULL; + struct skcipher_walk walk; + struct scatter_walk assocSgWalk; + unsigned int nbytes = 0; + u8 origAuthTag[AES_BLOCK_SIZE]; + int err = 0; + unsigned int assocLeft = 0; + unsigned int cryptLeft = 0; + u8 * assoc = NULL; + + tfm = crypto_aead_reqtfm(req); + ctx = crypto_aead_ctx(tfm); + assocLeft = req->assoclen; + cryptLeft = req->cryptlen - tfm->authsize; + + /* Copy out original auth tag from req->src. */ + scatterwalk_map_and_copy(origAuthTag, req->src, + req->assoclen + req->cryptlen - tfm->authsize, + tfm->authsize, 0); + + scatterwalk_start(&assocSgWalk, req->src); + + err = skcipher_walk_aead_decrypt(&walk, req, false); + if (unlikely(err)) { + pr_err("error: skcipher_walk_aead_decrypt: %d\n", err); + return -1; + } + + err = wc_AesGcmInit(&ctx->aes, ctx->key, ctx->keylen, walk.iv, + AES_BLOCK_SIZE); + if (unlikely(err)) { + pr_err("error: wc_AesGcmInit failed with return code %d.\n", err); + return err; + } + + assoc = scatterwalk_map(&assocSgWalk); + if (unlikely(IS_ERR(assoc))) { + pr_err("error: scatterwalk_map failed %ld\n", PTR_ERR(assoc)); + return err; + } + + err = wc_AesGcmDecryptUpdate(&ctx->aes, NULL, NULL, 0, assoc, assocLeft); + assocLeft -= assocLeft; + scatterwalk_unmap(assoc); + assoc = NULL; + + if (unlikely(err)) { + pr_err("error: wc_AesGcmDecryptUpdate failed %d\n", err); + return err; + } + + while ((nbytes = walk.nbytes)) { + int n = nbytes; + + if (likely(cryptLeft && nbytes)) { + n = cryptLeft < nbytes ? cryptLeft : nbytes; + + err = wc_AesGcmDecryptUpdate(&ctx->aes, walk.dst.virt.addr, + walk.src.virt.addr, cryptLeft, NULL, 0); + nbytes -= n; + cryptLeft -= n; + } + + if (unlikely(err)) { + pr_err("wc_AesGcmDecryptUpdate failed %d\n", err); + return err; + } + + err = skcipher_walk_done(&walk, nbytes); + } + + err = wc_AesGcmDecryptFinal(&ctx->aes, origAuthTag, tfm->authsize); + if (unlikely(err)) { + pr_err("error: wc_AesGcmDecryptFinal failed with return code %d\n", err); + + if (err == AES_GCM_AUTH_E) { + return -EBADMSG; + } + else { + return err; + } + } + + return err; +} +#endif /* endif HAVE_AESGCM */ + +#if defined(HAVE_AES_CBC) +static struct skcipher_alg cbcAesAlg = { + .base.cra_name = WOLFKM_CBC_NAME, + .base.cra_driver_name = WOLFKM_CBC_DRIVER, + .base.cra_priority = WOLFKM_ALG_PRIORITY, + .base.cra_blocksize = AES_BLOCK_SIZE, + .base.cra_ctxsize = sizeof(struct km_AesCtx), + .base.cra_module = THIS_MODULE, + .init = km_AesInit, + .exit = km_AesExit, + .min_keysize = (128 / 8), + .max_keysize = (AES_MAX_KEY_SIZE / 8), + .ivsize = AES_BLOCK_SIZE, + .setkey = km_AesSetKey, + .encrypt = km_AesCbcEncrypt, + .decrypt = km_AesCbcDecrypt, +}; +#endif + +#if defined(WOLFSSL_AES_CFB) +static struct skcipher_alg cfbAesAlg = { + .base.cra_name = WOLFKM_CFB_NAME, + .base.cra_driver_name = WOLFKM_CFB_DRIVER, + .base.cra_priority = WOLFKM_ALG_PRIORITY, + .base.cra_blocksize = AES_BLOCK_SIZE, + .base.cra_ctxsize = sizeof(struct km_AesCtx), + .base.cra_module = THIS_MODULE, + .init = km_AesInit, + .exit = km_AesExit, + .min_keysize = (128 / 8), + .max_keysize = (AES_MAX_KEY_SIZE / 8), + .ivsize = AES_BLOCK_SIZE, + .setkey = km_AesSetKey, + .encrypt = km_AesCfbEncrypt, + .decrypt = km_AesCfbDecrypt, +}; +#endif + +#if defined(HAVE_AESGCM) +static struct aead_alg gcmAesAead = { + .base.cra_name = WOLFKM_GCM_NAME, + .base.cra_driver_name = WOLFKM_GCM_DRIVER, + .base.cra_priority = WOLFKM_ALG_PRIORITY, + .base.cra_blocksize = 1, + .base.cra_ctxsize = sizeof(struct km_AesCtx), + .base.cra_module = THIS_MODULE, + .init = km_AesGcmInit, + .exit = km_AesGcmExit, + .setkey = km_AesGcmSetKey, + .setauthsize = km_AesGcmSetAuthsize, + .encrypt = km_AesGcmEncrypt, + .decrypt = km_AesGcmDecrypt, + .ivsize = AES_BLOCK_SIZE, + .maxauthsize = AES_BLOCK_SIZE, + .chunksize = AES_BLOCK_SIZE, +}; +#endif + +static int linuxkm_register_alg(void) +{ + int ret = 0; +#if defined(HAVE_AES_CBC) + ret = crypto_register_skcipher(&cbcAesAlg); + + if (ret) { + pr_err("crypto_register_skcipher failed with return code %d.\n", ret); + return ret; + } +#endif + +#if defined(WOLFSSL_AES_CFB) + ret = crypto_register_skcipher(&cfbAesAlg); + + if (ret) { + pr_err("crypto_register_skcipher failed with return code %d.\n", ret); + return ret; + } +#endif + +#if defined(HAVE_AESGCM) + ret = crypto_register_aead(&gcmAesAead); + + if (ret) { + pr_err("crypto_register_aead failed with return code %d.\n", ret); + return ret; + } +#endif + + return 0; +} + +static void linuxkm_unregister_alg(void) +{ +#if defined(HAVE_AES_CBC) + crypto_unregister_skcipher(&cbcAesAlg); +#endif +#if defined(WOLFSSL_AES_CFB) + crypto_unregister_skcipher(&cfbAesAlg); +#endif +#if defined(HAVE_AESGCM) + crypto_unregister_aead(&gcmAesAead); +#endif +} + +/* Given registered wolfcrypt kernel crypto, sanity test against + * direct wolfcrypt calls. */ + +static int linuxkm_test_alg(void) +{ + int ret = 0; + + ret = linuxkm_test_cbc(); + if (ret) { return ret; } + + ret = linuxkm_test_cfb(); + if (ret) { return ret; } + + ret = linuxkm_test_gcm(); + if (ret) { return ret; } + + return 0; +} + +static int linuxkm_test_cbc(void) +{ + int ret = 0; +#if defined(HAVE_AES_CBC) + struct crypto_skcipher * tfm = NULL; + struct skcipher_request * req = NULL; + struct scatterlist src, dst; + Aes aes; + byte key32[] = + { + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66 + }; + byte vector[] = /* Now is the time for all good men w/o trailing 0 */ + { + 0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74, + 0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20, + 0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20, + 0x67,0x6f,0x6f,0x64,0x20,0x6d,0x65,0x6e + }; + byte iv[] = "1234567890abcdef"; + byte enc[sizeof(vector)]; + byte dec[sizeof(vector)]; + u8 * enc2 = NULL; + u8 * dec2 = NULL; + + XMEMSET(enc, 0, sizeof(enc)); + XMEMSET(dec, 0, sizeof(enc)); + + ret = wc_AesInit(&aes, NULL, INVALID_DEVID); + if (ret) { + pr_err("wolfcrypt wc_AesInit failed with return code %d.\n", ret); + return -1; + } + + ret = wc_AesSetKey(&aes, key32, AES_BLOCK_SIZE * 2, iv, AES_ENCRYPTION); + if (ret) { + pr_err("wolfcrypt wc_AesSetKey failed with return code %d\n", ret); + return -1; + } + + ret = wc_AesCbcEncrypt(&aes, enc, vector, sizeof(vector)); + if (ret) { + pr_err("wolfcrypt wc_AesCbcEncrypt failed with return code %d\n", ret); + return -1; + } + + /* Re init for decrypt and set flag. */ + wc_AesFree(&aes); + + ret = wc_AesInit(&aes, NULL, INVALID_DEVID); + if (ret) { + pr_err("wolfcrypt wc_AesInit failed with return code %d.\n", ret); + return -1; + } + + ret = wc_AesSetKey(&aes, key32, AES_BLOCK_SIZE * 2, iv, AES_DECRYPTION); + if (ret) { + pr_err("wolfcrypt wc_AesSetKey failed with return code %d.\n", ret); + return -1; + } + + ret = wc_AesCbcDecrypt(&aes, dec, enc, sizeof(vector)); + if (ret) { + pr_err("wolfcrypt wc_AesCbcDecrypt failed with return code %d\n", ret); + return -1; + } + + ret = XMEMCMP(vector, dec, sizeof(vector)); + if (ret) { + pr_err("error: vector and dec do not match: %d\n", ret); + return -1; + } + + /* now the kernel crypto part */ + enc2 = kmalloc(sizeof(vector), GFP_KERNEL); + if (!enc2) { + pr_err("error: kmalloc failed\n"); + goto test_cbc_end; + } + + dec2 = kmalloc(sizeof(vector), GFP_KERNEL); + if (!dec2) { + pr_err("error: kmalloc failed\n"); + goto test_cbc_end; + } + + memcpy(dec2, vector, sizeof(vector)); + + tfm = crypto_alloc_skcipher(WOLFKM_CBC_DRIVER, 0, 0); + if (IS_ERR(tfm)) { + pr_err("error: allocating AES skcipher algorithm %s failed: %ld\n", + WOLFKM_CBC_DRIVER, PTR_ERR(tfm)); + goto test_cbc_end; + } + + ret = crypto_skcipher_setkey(tfm, key32, AES_BLOCK_SIZE * 2); + if (ret) { + pr_err("error: crypto_skcipher_setkey returned: %d\n", ret); + goto test_cbc_end; + } + + req = skcipher_request_alloc(tfm, GFP_KERNEL); + if (IS_ERR(req)) { + pr_err("error: allocating AES skcipher request %s failed\n", + WOLFKM_CBC_DRIVER); + goto test_cbc_end; + } + + sg_init_one(&src, dec2, sizeof(vector)); + sg_init_one(&dst, enc2, sizeof(vector)); + + skcipher_request_set_crypt(req, &src, &dst, sizeof(vector), iv); + + ret = crypto_skcipher_encrypt(req); + + if (ret) { + pr_err("error: crypto_skcipher_encrypt returned: %d\n", ret); + goto test_cbc_end; + } + + ret = XMEMCMP(enc, enc2, sizeof(vector)); + if (ret) { + pr_err("error: enc and enc2 do not match: %d\n", ret); + goto test_cbc_end; + } + + memset(dec2, 0, sizeof(vector)); + sg_init_one(&src, enc2, sizeof(vector)); + sg_init_one(&dst, dec2, sizeof(vector)); + + skcipher_request_set_crypt(req, &src, &dst, sizeof(vector), iv); + + ret = crypto_skcipher_decrypt(req); + + if (ret) { + pr_err("error: crypto_skcipher_decrypt returned: %d\n", ret); + goto test_cbc_end; + } + + ret = XMEMCMP(dec, dec2, sizeof(vector)); + if (ret) { + pr_err("error: dec and dec2 do not match: %d\n", ret); + goto test_cbc_end; + } + + pr_info("info: test driver %s: good\n", WOLFKM_CBC_DRIVER); + +test_cbc_end: + + if (enc2) { kfree(enc2); enc2 = NULL; } + if (dec2) { kfree(dec2); dec2 = NULL; } + if (req) { skcipher_request_free(req); req = NULL; } + if (tfm) { crypto_free_skcipher(tfm); tfm = NULL; } + +#endif /* if defined HAVE_AES_CBC */ + return ret; +} + +static int linuxkm_test_cfb(void) +{ + int ret = 0; +#if defined(WOLFSSL_AES_CFB) + struct crypto_skcipher * tfm = NULL; + struct skcipher_request * req = NULL; + struct scatterlist src, dst; + Aes aes; + byte key32[] = + { + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66 + }; + byte vector[] = /* Now is the time for all good men w/o trailing 0 */ + { + 0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74, + 0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20, + 0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20, + 0x67,0x6f,0x6f,0x64,0x20,0x6d,0x65,0x6e + }; + byte iv[] = "1234567890abcdef"; + byte enc[sizeof(vector)]; + byte dec[sizeof(vector)]; + u8 * enc2 = NULL; + u8 * dec2 = NULL; + + XMEMSET(enc, 0, sizeof(enc)); + XMEMSET(dec, 0, sizeof(enc)); + + ret = wc_AesInit(&aes, NULL, INVALID_DEVID); + if (ret) { + pr_err("wolfcrypt wc_AesInit failed with return code %d.\n", ret); + return -1; + } + + ret = wc_AesSetKey(&aes, key32, AES_BLOCK_SIZE * 2, iv, AES_ENCRYPTION); + if (ret) { + pr_err("wolfcrypt wc_AesSetKey failed with return code %d\n", ret); + return -1; + } + + ret = wc_AesCfbEncrypt(&aes, enc, vector, sizeof(vector)); + if (ret) { + pr_err("wolfcrypt wc_AesCfbEncrypt failed with return code %d\n", ret); + return -1; + } + + /* Re init for decrypt and set flag. */ + wc_AesFree(&aes); + + ret = wc_AesInit(&aes, NULL, INVALID_DEVID); + if (ret) { + pr_err("wolfcrypt wc_AesInit failed with return code %d.\n", ret); + return -1; + } + + ret = wc_AesSetKey(&aes, key32, AES_BLOCK_SIZE * 2, iv, AES_ENCRYPTION); + if (ret) { + pr_err("wolfcrypt wc_AesSetKey failed with return code %d.\n", ret); + return -1; + } + + ret = wc_AesCfbDecrypt(&aes, dec, enc, sizeof(vector)); + if (ret) { + pr_err("wolfcrypt wc_AesCfbDecrypt failed with return code %d\n", ret); + return -1; + } + + ret = XMEMCMP(vector, dec, sizeof(vector)); + if (ret) { + pr_err("error: vector and dec do not match: %d\n", ret); + return -1; + } + + /* now the kernel crypto part */ + enc2 = kmalloc(sizeof(vector), GFP_KERNEL); + if (!enc2) { + pr_err("error: kmalloc failed\n"); + goto test_cfb_end; + } + + dec2 = kmalloc(sizeof(vector), GFP_KERNEL); + if (!dec2) { + pr_err("error: kmalloc failed\n"); + goto test_cfb_end; + } + + memcpy(dec2, vector, sizeof(vector)); + + tfm = crypto_alloc_skcipher(WOLFKM_CFB_DRIVER, 0, 0); + if (IS_ERR(tfm)) { + pr_err("error: allocating AES skcipher algorithm %s failed: %ld\n", + WOLFKM_CFB_DRIVER, PTR_ERR(tfm)); + goto test_cfb_end; + } + + ret = crypto_skcipher_setkey(tfm, key32, AES_BLOCK_SIZE * 2); + if (ret) { + pr_err("error: crypto_skcipher_setkey returned: %d\n", ret); + goto test_cfb_end; + } + + req = skcipher_request_alloc(tfm, GFP_KERNEL); + if (IS_ERR(req)) { + pr_err("error: allocating AES skcipher request %s failed\n", + WOLFKM_CFB_DRIVER); + goto test_cfb_end; + } + + sg_init_one(&src, dec2, sizeof(vector)); + sg_init_one(&dst, enc2, sizeof(vector)); + + skcipher_request_set_crypt(req, &src, &dst, sizeof(vector), iv); + + ret = crypto_skcipher_encrypt(req); + + if (ret) { + pr_err("error: crypto_skcipher_encrypt returned: %d\n", ret); + goto test_cfb_end; + } + + ret = XMEMCMP(enc, enc2, sizeof(vector)); + if (ret) { + pr_err("error: enc and enc2 do not match: %d\n", ret); + goto test_cfb_end; + } + + memset(dec2, 0, sizeof(vector)); + sg_init_one(&src, enc2, sizeof(vector)); + sg_init_one(&dst, dec2, sizeof(vector)); + + skcipher_request_set_crypt(req, &src, &dst, sizeof(vector), iv); + + ret = crypto_skcipher_decrypt(req); + + if (ret) { + pr_err("error: crypto_skcipher_decrypt returned: %d\n", ret); + goto test_cfb_end; + } + + ret = XMEMCMP(dec, dec2, sizeof(vector)); + if (ret) { + pr_err("error: dec and dec2 do not match: %d\n", ret); + goto test_cfb_end; + } + + pr_info("info: test driver %s: good\n", WOLFKM_CFB_DRIVER); + +test_cfb_end: + + if (enc2) { kfree(enc2); enc2 = NULL; } + if (dec2) { kfree(dec2); dec2 = NULL; } + if (req) { skcipher_request_free(req); req = NULL; } + if (tfm) { crypto_free_skcipher(tfm); tfm = NULL; } +#endif /* if defined WOLFSSL_AES_CFB */ + + return ret; +} + +static int linuxkm_test_gcm(void) +{ + int ret = 0; +#if defined(HAVE_AESGCM) + struct crypto_aead * tfm = NULL; + struct aead_request * req = NULL; + struct scatterlist * src = NULL; + struct scatterlist * dst = NULL; + Aes aes; + byte key32[] = + { + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66 + }; + byte vector[] = /* Now is the time for all w/o trailing 0 */ + { + 0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74, + 0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20, + 0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20 + }; + const byte assoc[] = + { + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2 + }; + byte ivstr[] = "1234567890abcdef"; + byte enc[sizeof(vector)]; + byte authTag[AES_BLOCK_SIZE]; + byte dec[sizeof(vector)]; + u8 * assoc2 = NULL; + u8 * enc2 = NULL; + u8 * dec2 = NULL; + u8 * iv = NULL; + size_t encryptLen = sizeof(vector); + size_t decryptLen = sizeof(vector) + sizeof(authTag); + + /* Init stack variables. */ + XMEMSET(enc, 0, sizeof(vector)); + XMEMSET(dec, 0, sizeof(vector)); + XMEMSET(authTag, 0, AES_BLOCK_SIZE); + + ret = wc_AesInit(&aes, NULL, INVALID_DEVID); + if (ret) { + pr_err("error: wc_AesInit failed with return code %d.\n", ret); + goto test_gcm_end; + } + + ret = wc_AesGcmInit(&aes, key32, sizeof(key32)/sizeof(byte), ivstr, + AES_BLOCK_SIZE); + if (ret) { + pr_err("error: wc_AesGcmInit failed with return code %d.\n", ret); + goto test_gcm_end; + } + + ret = wc_AesGcmEncryptUpdate(&aes, NULL, NULL, 0, assoc, sizeof(assoc)); + if (ret) { + pr_err("error: wc_AesGcmEncryptUpdate failed with return code %d\n", ret); + goto test_gcm_end; + } + + ret = wc_AesGcmEncryptUpdate(&aes, enc, vector, sizeof(vector), NULL, 0); + if (ret) { + pr_err("error: wc_AesGcmEncryptUpdate failed with return code %d\n", ret); + goto test_gcm_end; + } + + ret = wc_AesGcmEncryptFinal(&aes, authTag, AES_BLOCK_SIZE); + if (ret) { + pr_err("error: wc_AesGcmEncryptFinal failed with return code %d\n", ret); + goto test_gcm_end; + } + + ret = wc_AesGcmInit(&aes, key32, sizeof(key32)/sizeof(byte), ivstr, + AES_BLOCK_SIZE); + if (ret) { + pr_err("error: wc_AesGcmInit failed with return code %d.\n", ret); + goto test_gcm_end; + } + + ret = wc_AesGcmDecryptUpdate(&aes, dec, enc, sizeof(vector), assoc, sizeof(assoc)); + if (ret) { + pr_err("error: wc_AesGcmDecryptUpdate failed with return code %d\n", ret); + goto test_gcm_end; + } + + ret = wc_AesGcmDecryptFinal(&aes, authTag, AES_BLOCK_SIZE); + if (ret) { + pr_err("error: wc_AesGcmEncryptFinal failed with return code %d\n", ret); + goto test_gcm_end; + } + + ret = XMEMCMP(vector, dec, sizeof(vector)); + if (ret) { + pr_err("error: gcm: vector and dec do not match: %d\n", ret); + goto test_gcm_end; + } + + /* now the kernel crypto part */ + assoc2 = kmalloc(sizeof(assoc), GFP_KERNEL); + if (IS_ERR(assoc2)) { + pr_err("error: kmalloc failed\n"); + goto test_gcm_end; + } + memset(assoc2, 0, sizeof(assoc)); + memcpy(assoc2, assoc, sizeof(assoc)); + + iv = kmalloc(AES_BLOCK_SIZE, GFP_KERNEL); + if (IS_ERR(iv)) { + pr_err("error: kmalloc failed\n"); + goto test_gcm_end; + } + memset(iv, 0, AES_BLOCK_SIZE); + memcpy(iv, ivstr, AES_BLOCK_SIZE); + + enc2 = kmalloc(decryptLen, GFP_KERNEL); + if (IS_ERR(enc2)) { + pr_err("error: kmalloc failed\n"); + goto test_gcm_end; + } + + dec2 = kmalloc(decryptLen, GFP_KERNEL); + if (IS_ERR(dec2)) { + pr_err("error: kmalloc failed\n"); + goto test_gcm_end; + } + + memset(enc2, 0, decryptLen); + memset(dec2, 0, decryptLen); + memcpy(dec2, vector, sizeof(vector)); + + tfm = crypto_alloc_aead(WOLFKM_GCM_DRIVER, 0, 0); + if (IS_ERR(tfm)) { + pr_err("error: allocating AES skcipher algorithm %s failed: %ld\n", + WOLFKM_GCM_DRIVER, PTR_ERR(tfm)); + goto test_gcm_end; + } + + ret = crypto_aead_setkey(tfm, key32, AES_BLOCK_SIZE * 2); + if (ret) { + pr_err("error: crypto_aead_setkey returned: %d\n", ret); + goto test_gcm_end; + } + + ret = crypto_aead_setauthsize(tfm, sizeof(authTag)); + if (ret) { + pr_err("error: crypto_aead_setauthsize returned: %d\n", ret); + goto test_gcm_end; + } + + req = aead_request_alloc(tfm, GFP_KERNEL); + if (IS_ERR(req)) { + pr_err("error: allocating AES aead request %s failed: %ld\n", + WOLFKM_CBC_DRIVER, PTR_ERR(req)); + goto test_gcm_end; + } + + src = kmalloc(sizeof(struct scatterlist) * 2, GFP_KERNEL); + dst = kmalloc(sizeof(struct scatterlist) * 2, GFP_KERNEL); + + if (IS_ERR(src) || IS_ERR(dst)) { + pr_err("error: kmalloc src or dst failed: %ld, %ld\n", + PTR_ERR(src), PTR_ERR(dst)); + goto test_gcm_end; + } + + sg_init_table(src, 2); + sg_set_buf(src, assoc2, sizeof(assoc)); + sg_set_buf(&src[1], dec2, sizeof(vector)); + + sg_init_table(dst, 2); + sg_set_buf(dst, assoc2, sizeof(assoc)); + sg_set_buf(&dst[1], enc2, decryptLen); + + aead_request_set_callback(req, 0, NULL, NULL); + aead_request_set_ad(req, sizeof(assoc)); + aead_request_set_crypt(req, src, dst, sizeof(vector), iv); + + ret = crypto_aead_encrypt(req); + + if (ret) { + pr_err("error: crypto_aead_encrypt returned: %d\n", ret); + goto test_gcm_end; + } + + ret = XMEMCMP(enc, enc2, sizeof(vector)); + if (ret) { + pr_err("error: enc and enc2 do not match: %d\n", ret); + goto test_gcm_end; + } + + ret = XMEMCMP(authTag, enc2 + encryptLen, sizeof(authTag)); + if (ret) { + pr_err("error: authTags do not match: %d\n", ret); + goto test_gcm_end; + } + + /* Now decrypt crypto request. Reverse src and dst. */ + memset(dec2, 0, decryptLen); + aead_request_set_ad(req, sizeof(assoc)); + aead_request_set_crypt(req, dst, src, decryptLen, iv); + + ret = crypto_aead_decrypt(req); + + if (ret) { + pr_err("error: crypto_aead_decrypt returned: %d\n", ret); + goto test_gcm_end; + } + + ret = XMEMCMP(dec, dec2, sizeof(vector)); + if (ret) { + pr_err("error: dec and dec2 do not match: %d\n", ret); + goto test_gcm_end; + } + + pr_info("info: test driver %s: good\n", WOLFKM_GCM_DRIVER); + +test_gcm_end: + if (req) { aead_request_free(req); req = NULL; } + if (tfm) { crypto_free_aead(tfm); tfm = NULL; } + + if (src) { kfree(src); src = NULL; } + if (dst) { kfree(dst); dst = NULL; } + + if (dec2) { kfree(dec2); dec2 = NULL; } + if (enc2) { kfree(enc2); enc2 = NULL; } + + if (assoc2) { kfree(assoc2); assoc2 = NULL; } + if (iv) { kfree(iv); iv = NULL; } +#endif /* if defined HAVE_AESGCM */ + + return 0; +} + +#endif /* LINUXKM_REGISTER_ALG && !defined(NO_AES) */ From 1f4cf4188dbae97f64b1571018e387828360d7c7 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Fri, 26 Jan 2024 14:07:58 -0600 Subject: [PATCH 12/63] linuxkm: * LKCAPI integration tweaks for buildability and streamlining. * add DEBUG_VECTOR_REGISTER_ACCESS_FUZZING && !DEBUG_VECTOR_REGISTER_ACCESS, with a kernel-compatible implementation of SAVE_VECTOR_REGISTERS2_fuzzer(). --- linuxkm/linuxkm_wc_port.h | 17 ++++++++++++-- linuxkm/module_hooks.c | 45 ++++++++++++++++++++------------------ wolfcrypt/src/memory.c | 33 ++++++++++++++++++++++++++-- wolfssl/wolfcrypt/memory.h | 12 +++++----- 4 files changed, 77 insertions(+), 30 deletions(-) diff --git a/linuxkm/linuxkm_wc_port.h b/linuxkm/linuxkm_wc_port.h index f815ec354f..97273939c1 100644 --- a/linuxkm/linuxkm_wc_port.h +++ b/linuxkm/linuxkm_wc_port.h @@ -146,6 +146,14 @@ #include #include + #ifdef LINUXKM_REGISTER_ALG + #include + #include + #include + #include + #include + #endif + #if defined(WOLFSSL_AESNI) || defined(USE_INTEL_SPEEDUP) || defined(WOLFSSL_SP_X86_64_ASM) #ifndef CONFIG_X86 #error X86 SIMD extensions requested, but CONFIG_X86 is not set. @@ -185,7 +193,11 @@ #endif #ifndef SAVE_VECTOR_REGISTERS #define SAVE_VECTOR_REGISTERS(fail_clause) { int _svr_ret = save_vector_registers_x86(); if (_svr_ret != 0) { fail_clause } } - #define SAVE_VECTOR_REGISTERS2() save_vector_registers_x86() + #ifdef DEBUG_VECTOR_REGISTER_ACCESS_FUZZING + #define SAVE_VECTOR_REGISTERS2() ({ int _fuzzer_ret = SAVE_VECTOR_REGISTERS2_fuzzer(); (_fuzzer_ret == 0) ? save_vector_registers_x86() : _fuzzer_ret; }) + #else + #define SAVE_VECTOR_REGISTERS2() save_vector_registers_x86() + #endif #endif #ifndef RESTORE_VECTOR_REGISTERS #define RESTORE_VECTOR_REGISTERS() restore_vector_registers_x86() @@ -643,8 +655,9 @@ #define realloc(ptr, newsize) krealloc(ptr, WC_LINUXKM_ROUND_UP_P_OF_2(newsize), GFP_KERNEL) #endif -#ifdef WOLFSSL_TRACK_MEMORY #include + +#ifdef WOLFSSL_TRACK_MEMORY #define XMALLOC(s, h, t) ({(void)(h); (void)(t); wolfSSL_Malloc(s);}) #ifdef WOLFSSL_XFREE_NO_NULLNESS_CHECK #define XFREE(p, h, t) ({(void)(h); (void)(t); wolfSSL_Free(p);}) diff --git a/linuxkm/module_hooks.c b/linuxkm/module_hooks.c index 73673631d9..5e8f7caaaf 100644 --- a/linuxkm/module_hooks.c +++ b/linuxkm/module_hooks.c @@ -317,6 +317,28 @@ static int wolfssl_init(void) pr_info("wolfCrypt self-test passed.\n"); #endif +#if defined(LINUXKM_REGISTER_ALG) && !defined(NO_AES) + ret = linuxkm_register_alg(); + + if (ret) { + pr_err("linuxkm_register_alg failed with return code %d.\n", ret); + linuxkm_unregister_alg(); + (void)libwolfssl_cleanup(); + msleep(10); + return -ECANCELED; + } + + ret = linuxkm_test_alg(); + + if (ret) { + pr_err("linuxkm_test_alg failed with return code %d.\n", ret); + (void)libwolfssl_cleanup(); + linuxkm_unregister_alg(); + msleep(10); + return -ECANCELED; + } +#endif + #ifdef WOLFSSL_LINUXKM_BENCHMARKS wolfcrypt_benchmark_main(0, (char**)NULL); #endif @@ -343,27 +365,6 @@ static int wolfssl_init(void) ); #endif -#if defined(LINUXKM_REGISTER_ALG) && !defined(NO_AES) - ret = linuxkm_register_alg(); - - if (ret) { - pr_err("linuxkm_register_alg failed with return code %d.\n", ret); - (void)libwolfssl_cleanup(); - linuxkm_unregister_alg(); - msleep(10); - return -ECANCELED; - } - - ret = linuxkm_test_alg(); - - if (ret) { - pr_err("linuxkm_test_alg failed with return code %d.\n", ret); - (void)libwolfssl_cleanup(); - linuxkm_unregister_alg(); - msleep(10); - return -ECANCELED; - } -#endif return 0; } @@ -811,6 +812,8 @@ PRAGMA_GCC_DIAG_POP; /* km_AesX(): wrappers to wolfcrypt wc_AesX functions and * structures. */ +#include + struct km_AesCtx { Aes aes; u8 key[AES_MAX_KEY_SIZE / 8]; diff --git a/wolfcrypt/src/memory.c b/wolfcrypt/src/memory.c index 565d91075d..f51e02a404 100644 --- a/wolfcrypt/src/memory.c +++ b/wolfcrypt/src/memory.c @@ -1534,9 +1534,38 @@ WOLFSSL_LOCAL int SAVE_VECTOR_REGISTERS2_fuzzer(void) { return 0; } -#endif +#endif /* DEBUG_VECTOR_REGISTER_ACCESS_FUZZING */ -#endif +#elif defined(DEBUG_VECTOR_REGISTER_ACCESS_FUZZING) + +/* DEBUG_VECTOR_REGISTER_ACCESS is undefined but fuzzing requested -- + * fuzz vector register access without the detailed debugging. + * this is useful for testing in the kernel module build, where glibc and + * thread-local storage are unavailable. + */ + +WOLFSSL_LOCAL int SAVE_VECTOR_REGISTERS2_fuzzer(void) { + static unsigned long prn = WC_DEBUG_VECTOR_REGISTERS_FUZZING_SEED; + unsigned long popcount; + /* access to prn is racey, but it doesn't matter. */ + unsigned long new_prn = prn ^ 0xba86943da66ee701ul; + if (new_prn & 0x3f) + new_prn = (new_prn << (new_prn & 0x3f)) | (new_prn >> (0x40 - (new_prn & 0x3f))); + __asm__ volatile ("popcnt %1, %0;" + :"=r"(popcount) + :"r"(new_prn) + : + ); + new_prn ^= popcount; + prn = new_prn; + + if (prn & 1) + return IO_FAILED_E; + else + return 0; +} + +#endif /* DEBUG_VECTOR_REGISTER_ACCESS || DEBUG_VECTOR_REGISTER_ACCESS_FUZZING */ #ifdef WOLFSSL_LINUXKM #include "../../linuxkm/linuxkm_memory.c" diff --git a/wolfssl/wolfcrypt/memory.h b/wolfssl/wolfcrypt/memory.h index cf83273161..1b5b82e351 100644 --- a/wolfssl/wolfcrypt/memory.h +++ b/wolfssl/wolfcrypt/memory.h @@ -267,6 +267,13 @@ WOLFSSL_LOCAL int wc_debug_CipherLifecycleFree(void **CipherLifecycleTag, ((void)(CipherLifecycleTag), (void)(heap), (void)(abort_p), 0) #endif +#ifdef DEBUG_VECTOR_REGISTER_ACCESS_FUZZING + WOLFSSL_LOCAL int SAVE_VECTOR_REGISTERS2_fuzzer(void); + #ifndef WC_DEBUG_VECTOR_REGISTERS_FUZZING_SEED + #define WC_DEBUG_VECTOR_REGISTERS_FUZZING_SEED 0 + #endif +#endif + #ifdef DEBUG_VECTOR_REGISTER_ACCESS WOLFSSL_API extern THREAD_LS_T int wc_svr_count; WOLFSSL_API extern THREAD_LS_T const char *wc_svr_last_file; @@ -320,11 +327,6 @@ WOLFSSL_LOCAL int wc_debug_CipherLifecycleFree(void **CipherLifecycleTag, } while (0) #ifdef DEBUG_VECTOR_REGISTER_ACCESS_FUZZING - #ifndef WC_DEBUG_VECTOR_REGISTERS_FUZZING_SEED - #define WC_DEBUG_VECTOR_REGISTERS_FUZZING_SEED 0 - #endif - WOLFSSL_LOCAL int SAVE_VECTOR_REGISTERS2_fuzzer(void); - #define SAVE_VECTOR_REGISTERS2(...) ({ \ int _svr2_val = SAVE_VECTOR_REGISTERS2_fuzzer(); \ if (_svr2_val == 0) { \ From ec60f91b4a065603b839fb62cd866cb22d89a4cd Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Fri, 26 Jan 2024 14:20:57 -0600 Subject: [PATCH 13/63] linuxkm: add linuxkm/lkcapi_glue.c. --- linuxkm/lkcapi_glue.c | 2448 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2448 insertions(+) create mode 100644 linuxkm/lkcapi_glue.c diff --git a/linuxkm/lkcapi_glue.c b/linuxkm/lkcapi_glue.c new file mode 100644 index 0000000000..170bdbaf35 --- /dev/null +++ b/linuxkm/lkcapi_glue.c @@ -0,0 +1,2448 @@ +/* lkcapi_glue.c -- glue logic to register wolfCrypt implementations with + * the Linux Kernel Cryptosystem + * + * Copyright (C) 2006-2024 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifndef LINUXKM_LKCAPI_REGISTER + #error lkcapi_glue.c included in non-LINUXKM_LKCAPI_REGISTER project. +#endif + +#if defined(LINUXKM_LKCAPI_REGISTER_AESGCM) && defined(WOLFSSL_AESNI) && defined(WC_AES_C_DYNAMIC_FALLBACK) + /* xxx temporary */ + #error LINUXKM_LKCAPI_REGISTER_AESGCM is incompatible with WOLFSSL_AESNI && WC_AES_C_DYNAMIC_FALLBACK +#endif + +#if defined(LINUXKM_LKCAPI_REGISTER_AESGCM) && !defined(WOLFSSL_AESGCM_STREAM) + #error LINUXKM_REGISTER_ALG requires AESGCM_STREAM. +#endif + +#ifndef WOLFSSL_LINUXKM_LKCAPI_PRIORITY +/* Larger number means higher priority. The highest in-tree priority is 4001, + * in the Cavium driver. + */ +#define WOLFSSL_LINUXKM_LKCAPI_PRIORITY 10000 +#endif + +#ifndef NO_AES + +#define WOLFKM_AESCBC_NAME "cbc(aes)" +#define WOLFKM_AESCFB_NAME "cfb(aes)" +#define WOLFKM_AESGCM_NAME "gcm(aes)" +#define WOLFKM_AESXTS_NAME "xts(aes)" +#define WOLFKM_AESCBC_DRIVER "cbc-aes-wolfcrypt" +#define WOLFKM_AESCFB_DRIVER "cfb-aes-wolfcrypt" +#define WOLFKM_AESGCM_DRIVER "gcm-aes-wolfcrypt" +#define WOLFKM_AESXTS_DRIVER "xts-aes-wolfcrypt" + +#if defined(HAVE_AES_CBC) && \ + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESCBC)) +static int linuxkm_test_aescbc(void); +#endif +#if defined(WOLFSSL_AES_CFB) && \ + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESCFB)) +static int linuxkm_test_aescfb(void); +#endif +#if defined(HAVE_AESGCM) && \ + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESGCM)) && \ + (! (defined(WOLFSSL_AESNI) && defined(WC_AES_C_DYNAMIC_FALLBACK))) +static int linuxkm_test_aesgcm(void); +#endif +#if defined(WOLFSSL_AES_XTS) && \ + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESXTS)) +static int linuxkm_test_aesxts(void); +#endif + +/* km_AesX(): wrappers to wolfcrypt wc_AesX functions and + * structures. */ + +#include + +struct km_AesCtx { + Aes *aes; /* must be pointer to control alignment, needed for AESNI. */ + u8 key[AES_MAX_KEY_SIZE / 8]; + unsigned int keylen; +}; + +static inline void km_ForceZero(struct km_AesCtx * ctx) +{ + memzero_explicit(ctx->key, sizeof(ctx->key)); + ctx->keylen = 0; +} + +#if defined(LINUXKM_LKCAPI_REGISTER_ALL) || \ + defined(LINUXKM_LKCAPI_REGISTER_AESCBC) || \ + defined(LINUXKM_LKCAPI_REGISTER_AESCFB) || \ + defined(LINUXKM_LKCAPI_REGISTER_AESGCM) + +static int km_AesInitCommon(struct km_AesCtx * ctx, const char * name) +{ + int err; + + ctx->aes = (Aes *)malloc(sizeof(*ctx->aes)); + + if (! ctx->aes) + return MEMORY_E; + + err = wc_AesInit(ctx->aes, NULL, INVALID_DEVID); + + if (unlikely(err)) { + pr_err("error: km_AesInitCommon %s failed: %d\n", name, err); + return err; + } + + return 0; +} + +static void km_AesExitCommon(struct km_AesCtx * ctx) +{ + wc_AesFree(ctx->aes); + free(ctx->aes); + ctx->aes = NULL; + km_ForceZero(ctx); +} + +static int km_AesSetKeyCommon(struct km_AesCtx * ctx, const u8 *in_key, + unsigned int key_len, const char * name) +{ + int err; + + err = wc_AesSetKey(ctx->aes, in_key, key_len, NULL, 0); + + if (unlikely(err)) { + pr_err("error: km_AesSetKeyCommon %s failed: %d\n", name, err); + return err; + } + + XMEMCPY(ctx->key, in_key, key_len); + ctx->keylen = key_len; + + return 0; +} + +#if defined(LINUXKM_LKCAPI_REGISTER_ALL) || \ + defined(LINUXKM_LKCAPI_REGISTER_AESCBC) || \ + defined(LINUXKM_LKCAPI_REGISTER_AESCFB) + +static int km_AesInit(struct crypto_skcipher *tfm) +{ + struct km_AesCtx * ctx = crypto_skcipher_ctx(tfm); + return km_AesInitCommon(ctx, WOLFKM_AESCBC_DRIVER); +} + +static void km_AesExit(struct crypto_skcipher *tfm) +{ + struct km_AesCtx * ctx = crypto_skcipher_ctx(tfm); + km_AesExitCommon(ctx); +} + +static int km_AesSetKey(struct crypto_skcipher *tfm, const u8 *in_key, + unsigned int key_len) +{ + struct km_AesCtx * ctx = crypto_skcipher_ctx(tfm); + return km_AesSetKeyCommon(ctx, in_key, key_len, WOLFKM_AESCBC_DRIVER); +} + +#endif /* LINUXKM_LKCAPI_REGISTER_ALL || + * LINUXKM_LKCAPI_REGISTER_AESCBC || + * LINUXKM_LKCAPI_REGISTER_AESCFB + */ + +#endif /* LINUXKM_LKCAPI_REGISTER_ALL || LINUXKM_LKCAPI_REGISTER_AESCBC || + * LINUXKM_LKCAPI_REGISTER_AESCFB || LINUXKM_LKCAPI_REGISTER_AESGCM + */ + +#if defined(HAVE_AES_CBC) && \ + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESCBC)) + +static int km_AesCbcEncrypt(struct skcipher_request *req) +{ + struct crypto_skcipher * tfm = NULL; + struct km_AesCtx * ctx = NULL; + struct skcipher_walk walk; + unsigned int nbytes = 0; + int err = 0; + + tfm = crypto_skcipher_reqtfm(req); + ctx = crypto_skcipher_ctx(tfm); + + err = skcipher_walk_virt(&walk, req, false); + + while ((nbytes = walk.nbytes)) { + err = wc_AesSetKey(ctx->aes, ctx->key, ctx->keylen, walk.iv, + AES_ENCRYPTION); + + if (unlikely(err)) { + pr_err("wc_AesSetKey failed: %d\n", err); + return err; + } + + err = wc_AesCbcEncrypt(ctx->aes, walk.dst.virt.addr, + walk.src.virt.addr, nbytes); + + if (unlikely(err)) { + pr_err("wc_AesCbcEncrypt failed %d\n", err); + return err; + } + + err = skcipher_walk_done(&walk, walk.nbytes - nbytes); + } + + return err; +} + +static int km_AesCbcDecrypt(struct skcipher_request *req) +{ + struct crypto_skcipher * tfm = NULL; + struct km_AesCtx * ctx = NULL; + struct skcipher_walk walk; + unsigned int nbytes = 0; + int err = 0; + + tfm = crypto_skcipher_reqtfm(req); + ctx = crypto_skcipher_ctx(tfm); + + err = skcipher_walk_virt(&walk, req, false); + + while ((nbytes = walk.nbytes)) { + err = wc_AesSetKey(ctx->aes, ctx->key, ctx->keylen, walk.iv, + AES_DECRYPTION); + + if (unlikely(err)) { + pr_err("wc_AesSetKey failed"); + return err; + } + + err = wc_AesCbcDecrypt(ctx->aes, walk.dst.virt.addr, + walk.src.virt.addr, nbytes); + + if (unlikely(err)) { + pr_err("wc_AesCbcDecrypt failed"); + return err; + } + + err = skcipher_walk_done(&walk, walk.nbytes - nbytes); + } + + return err; +} + +static struct skcipher_alg cbcAesAlg = { + .base.cra_name = WOLFKM_AESCBC_NAME, + .base.cra_driver_name = WOLFKM_AESCBC_DRIVER, + .base.cra_priority = WOLFSSL_LINUXKM_LKCAPI_PRIORITY, + .base.cra_blocksize = AES_BLOCK_SIZE, + .base.cra_ctxsize = sizeof(struct km_AesCtx), + .base.cra_module = THIS_MODULE, + .init = km_AesInit, + .exit = km_AesExit, + .min_keysize = AES_128_KEY_SIZE, + .max_keysize = AES_256_KEY_SIZE, + .ivsize = AES_BLOCK_SIZE, + .setkey = km_AesSetKey, + .encrypt = km_AesCbcEncrypt, + .decrypt = km_AesCbcDecrypt, +}; +static int cbcAesAlg_loaded = 0; + +#endif /* HAVE_AES_CBC && + * (LINUXKM_LKCAPI_REGISTER_ALL || LINUXKM_LKCAPI_REGISTER_AESCBC) + */ + +#if defined(WOLFSSL_AES_CFB) && \ + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESCFB)) + +static int km_AesCfbEncrypt(struct skcipher_request *req) +{ + struct crypto_skcipher * tfm = NULL; + struct km_AesCtx * ctx = NULL; + struct skcipher_walk walk; + unsigned int nbytes = 0; + int err = 0; + + tfm = crypto_skcipher_reqtfm(req); + ctx = crypto_skcipher_ctx(tfm); + + err = skcipher_walk_virt(&walk, req, false); + + while ((nbytes = walk.nbytes)) { + err = wc_AesSetKey(ctx->aes, ctx->key, ctx->keylen, walk.iv, + AES_ENCRYPTION); + + if (unlikely(err)) { + pr_err("wc_AesSetKey failed: %d\n", err); + return err; + } + + err = wc_AesCfbEncrypt(ctx->aes, walk.dst.virt.addr, + walk.src.virt.addr, nbytes); + + if (unlikely(err)) { + pr_err("wc_AesCfbEncrypt failed %d\n", err); + return err; + } + + err = skcipher_walk_done(&walk, walk.nbytes - nbytes); + } + + return err; +} + +static int km_AesCfbDecrypt(struct skcipher_request *req) +{ + struct crypto_skcipher * tfm = NULL; + struct km_AesCtx * ctx = NULL; + struct skcipher_walk walk; + unsigned int nbytes = 0; + int err = 0; + + tfm = crypto_skcipher_reqtfm(req); + ctx = crypto_skcipher_ctx(tfm); + + err = skcipher_walk_virt(&walk, req, false); + + while ((nbytes = walk.nbytes)) { + err = wc_AesSetKey(ctx->aes, ctx->key, ctx->keylen, walk.iv, + AES_ENCRYPTION); + + if (unlikely(err)) { + pr_err("wc_AesSetKey failed"); + return err; + } + + err = wc_AesCfbDecrypt(ctx->aes, walk.dst.virt.addr, + walk.src.virt.addr, nbytes); + + if (unlikely(err)) { + pr_err("wc_AesCfbDecrypt failed"); + return err; + } + + err = skcipher_walk_done(&walk, walk.nbytes - nbytes); + } + + return err; +} + +static struct skcipher_alg cfbAesAlg = { + .base.cra_name = WOLFKM_AESCFB_NAME, + .base.cra_driver_name = WOLFKM_AESCFB_DRIVER, + .base.cra_priority = WOLFSSL_LINUXKM_LKCAPI_PRIORITY, + .base.cra_blocksize = AES_BLOCK_SIZE, + .base.cra_ctxsize = sizeof(struct km_AesCtx), + .base.cra_module = THIS_MODULE, + .init = km_AesInit, + .exit = km_AesExit, + .min_keysize = AES_128_KEY_SIZE, + .max_keysize = AES_256_KEY_SIZE, + .ivsize = AES_BLOCK_SIZE, + .setkey = km_AesSetKey, + .encrypt = km_AesCfbEncrypt, + .decrypt = km_AesCfbDecrypt, +}; +static int cfbAesAlg_loaded = 0; + +#endif /* WOLFSSL_AES_CFB && + * (LINUXKM_LKCAPI_REGISTER_ALL || LINUXKM_LKCAPI_REGISTER_AESCBC) + */ + +#if defined(HAVE_AESGCM) && \ + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESGCM)) && \ + (! (defined(WOLFSSL_AESNI) && defined(WC_AES_C_DYNAMIC_FALLBACK))) + +static int km_AesGcmInit(struct crypto_aead * tfm) +{ + struct km_AesCtx * ctx = crypto_aead_ctx(tfm); + km_ForceZero(ctx); + return km_AesInitCommon(ctx, WOLFKM_AESGCM_DRIVER); +} + +static void km_AesGcmExit(struct crypto_aead * tfm) +{ + struct km_AesCtx * ctx = crypto_aead_ctx(tfm); + km_AesExitCommon(ctx); +} + +static int km_AesGcmSetKey(struct crypto_aead *tfm, const u8 *in_key, + unsigned int key_len) +{ + struct km_AesCtx * ctx = crypto_aead_ctx(tfm); + return km_AesSetKeyCommon(ctx, in_key, key_len, WOLFKM_AESGCM_DRIVER); +} + +static int km_AesGcmSetAuthsize(struct crypto_aead *tfm, unsigned int authsize) +{ + (void)tfm; + if (authsize > AES_BLOCK_SIZE || + authsize < WOLFSSL_MIN_AUTH_TAG_SZ) { + pr_err("error: invalid authsize: %d\n", authsize); + return -EINVAL; + } + return 0; +} + +/* + * aead ciphers recieve data in scatterlists in following order: + * encrypt + * req->src: aad||plaintext + * req->dst: aad||ciphertext||tag + * decrypt + * req->src: aad||ciphertext||tag + * req->dst: aad||plaintext, return 0 or -EBADMSG + */ + +static int km_AesGcmEncrypt(struct aead_request *req) +{ + struct crypto_aead * tfm = NULL; + struct km_AesCtx * ctx = NULL; + struct skcipher_walk walk; + struct scatter_walk assocSgWalk; + unsigned int nbytes = 0; + u8 authTag[AES_BLOCK_SIZE]; + int err = 0; + unsigned int assocLeft = 0; + unsigned int cryptLeft = 0; + u8 * assoc = NULL; + + tfm = crypto_aead_reqtfm(req); + ctx = crypto_aead_ctx(tfm); + assocLeft = req->assoclen; + cryptLeft = req->cryptlen; + + scatterwalk_start(&assocSgWalk, req->src); + + err = skcipher_walk_aead_encrypt(&walk, req, false); + if (unlikely(err)) { + pr_err("error: skcipher_walk_aead_encrypt: %d\n", err); + return -1; + } + + err = wc_AesGcmInit(ctx->aes, ctx->key, ctx->keylen, walk.iv, + AES_BLOCK_SIZE); + if (unlikely(err)) { + pr_err("error: wc_AesGcmInit failed with return code %d.\n", err); + return err; + } + + assoc = scatterwalk_map(&assocSgWalk); + if (unlikely(IS_ERR(assoc))) { + pr_err("error: scatterwalk_map failed %ld\n", PTR_ERR(assoc)); + return err; + } + + err = wc_AesGcmEncryptUpdate(ctx->aes, NULL, NULL, 0, assoc, assocLeft); + assocLeft -= assocLeft; + scatterwalk_unmap(assoc); + assoc = NULL; + + if (unlikely(err)) { + pr_err("error: wc_AesGcmEncryptUpdate failed %d\n", err); + return err; + } + + while ((nbytes = walk.nbytes)) { + int n = nbytes; + + if (likely(cryptLeft && nbytes)) { + n = cryptLeft < nbytes ? cryptLeft : nbytes; + + err = wc_AesGcmEncryptUpdate(ctx->aes, walk.dst.virt.addr, + walk.src.virt.addr, cryptLeft, NULL, 0); + nbytes -= n; + cryptLeft -= n; + } + + if (unlikely(err)) { + pr_err("wc_AesGcmEncryptUpdate failed %d\n", err); + return err; + } + + err = skcipher_walk_done(&walk, nbytes); + } + + err = wc_AesGcmEncryptFinal(ctx->aes, authTag, tfm->authsize); + if (unlikely(err)) { + pr_err("error: wc_AesGcmEncryptFinal failed with return code %d\n", err); + return err; + } + + /* Now copy the auth tag into request scatterlist. */ + scatterwalk_map_and_copy(authTag, req->dst, + req->assoclen + req->cryptlen, + tfm->authsize, 1); + + return err; +} + +static int km_AesGcmDecrypt(struct aead_request *req) +{ + struct crypto_aead * tfm = NULL; + struct km_AesCtx * ctx = NULL; + struct skcipher_walk walk; + struct scatter_walk assocSgWalk; + unsigned int nbytes = 0; + u8 origAuthTag[AES_BLOCK_SIZE]; + int err = 0; + unsigned int assocLeft = 0; + unsigned int cryptLeft = 0; + u8 * assoc = NULL; + + tfm = crypto_aead_reqtfm(req); + ctx = crypto_aead_ctx(tfm); + assocLeft = req->assoclen; + cryptLeft = req->cryptlen - tfm->authsize; + + /* Copy out original auth tag from req->src. */ + scatterwalk_map_and_copy(origAuthTag, req->src, + req->assoclen + req->cryptlen - tfm->authsize, + tfm->authsize, 0); + + scatterwalk_start(&assocSgWalk, req->src); + + err = skcipher_walk_aead_decrypt(&walk, req, false); + if (unlikely(err)) { + pr_err("error: skcipher_walk_aead_decrypt: %d\n", err); + return -1; + } + + err = wc_AesGcmInit(ctx->aes, ctx->key, ctx->keylen, walk.iv, + AES_BLOCK_SIZE); + if (unlikely(err)) { + pr_err("error: wc_AesGcmInit failed with return code %d.\n", err); + return err; + } + + assoc = scatterwalk_map(&assocSgWalk); + if (unlikely(IS_ERR(assoc))) { + pr_err("error: scatterwalk_map failed %ld\n", PTR_ERR(assoc)); + return err; + } + + err = wc_AesGcmDecryptUpdate(ctx->aes, NULL, NULL, 0, assoc, assocLeft); + assocLeft -= assocLeft; + scatterwalk_unmap(assoc); + assoc = NULL; + + if (unlikely(err)) { + pr_err("error: wc_AesGcmDecryptUpdate failed %d\n", err); + return err; + } + + while ((nbytes = walk.nbytes)) { + int n = nbytes; + + if (likely(cryptLeft && nbytes)) { + n = cryptLeft < nbytes ? cryptLeft : nbytes; + + err = wc_AesGcmDecryptUpdate(ctx->aes, walk.dst.virt.addr, + walk.src.virt.addr, cryptLeft, NULL, 0); + nbytes -= n; + cryptLeft -= n; + } + + if (unlikely(err)) { + pr_err("wc_AesGcmDecryptUpdate failed %d\n", err); + return err; + } + + err = skcipher_walk_done(&walk, nbytes); + } + + err = wc_AesGcmDecryptFinal(ctx->aes, origAuthTag, tfm->authsize); + if (unlikely(err)) { + pr_err("error: wc_AesGcmDecryptFinal failed with return code %d\n", err); + + if (err == AES_GCM_AUTH_E) { + return -EBADMSG; + } + else { + return err; + } + } + + return err; +} + +static struct aead_alg gcmAesAead = { + .base.cra_name = WOLFKM_AESGCM_NAME, + .base.cra_driver_name = WOLFKM_AESGCM_DRIVER, + .base.cra_priority = WOLFSSL_LINUXKM_LKCAPI_PRIORITY, + .base.cra_blocksize = 1, + .base.cra_ctxsize = sizeof(struct km_AesCtx), + .base.cra_module = THIS_MODULE, + .init = km_AesGcmInit, + .exit = km_AesGcmExit, + .setkey = km_AesGcmSetKey, + .setauthsize = km_AesGcmSetAuthsize, + .encrypt = km_AesGcmEncrypt, + .decrypt = km_AesGcmDecrypt, + .ivsize = AES_BLOCK_SIZE, + .maxauthsize = AES_BLOCK_SIZE, + .chunksize = AES_BLOCK_SIZE, +}; +static int gcmAesAead_loaded = 0; + +#endif /* HAVE_AESGCM && + * (LINUXKM_LKCAPI_REGISTER_ALL || LINUXKM_LKCAPI_REGISTER_AESGCM) && + * (! (WOLFSSL_AESNI && WC_AES_C_DYNAMIC_FALLBACK)) + */ + +#if defined(WOLFSSL_AES_XTS) && \ + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESXTS)) + +struct km_AesXtsCtx { + XtsAes *aesXts; /* allocated here, with correct alignment, for AESNI. */ +}; + +static int km_AesXtsInitCommon(struct km_AesXtsCtx * ctx, const char * name) +{ + int err; + + ctx->aesXts = (XtsAes *)malloc(sizeof(*ctx->aesXts)); + + if (! ctx->aesXts) + return -MEMORY_E; + + err = wc_AesXtsInit(ctx->aesXts, NULL, INVALID_DEVID); + + if (unlikely(err)) { + pr_err("error: km_AesXtsInitCommon %s failed: %d\n", name, err); + return err; + } + + return 0; +} + +static int km_AesXtsInit(struct crypto_skcipher *tfm) +{ + struct km_AesXtsCtx * ctx = crypto_skcipher_ctx(tfm); + return km_AesXtsInitCommon(ctx, WOLFKM_AESXTS_DRIVER); +} + +static void km_AesXtsExit(struct crypto_skcipher *tfm) +{ + struct km_AesXtsCtx * ctx = crypto_skcipher_ctx(tfm); + wc_AesXtsFree(ctx->aesXts); + free(ctx->aesXts); + ctx->aesXts = NULL; +#if 0 + km_ForceZeroXts(ctx); +#endif +} + +static int km_AesXtsSetKey(struct crypto_skcipher *tfm, const u8 *in_key, + unsigned int key_len) +{ + int err; + struct km_AesXtsCtx * ctx = crypto_skcipher_ctx(tfm); + + err = wc_AesXtsSetKeyNoInit(ctx->aesXts, in_key, key_len, AES_ENCRYPTION_AND_DECRYPTION); + + if (unlikely(err)) { + pr_err("error: km_AesXtsSetKey %s failed: %d\n", WOLFKM_AESXTS_DRIVER, err); + return err; + } + +#if 0 + XMEMCPY(ctx->key, in_key, key_len); + ctx->keylen = key_len; +#endif + + return 0; +} + +/* see /usr/src/linux/drivers/md/dm-crypt.c */ + +static int km_AesXtsEncrypt(struct skcipher_request *req) +{ + int err = 0; + + struct crypto_skcipher * tfm = NULL; + struct km_AesXtsCtx * ctx = NULL; + struct skcipher_walk walk; + unsigned int nbytes = 0; + + tfm = crypto_skcipher_reqtfm(req); + ctx = crypto_skcipher_ctx(tfm); + + err = skcipher_walk_virt(&walk, req, false); + + if (unlikely(err)) { + pr_err("skcipher_walk_virt() failed: %d\n", err); + return err; + } + + while ((nbytes = walk.nbytes)) { + err = wc_AesXtsEncrypt(ctx->aesXts, walk.dst.virt.addr, + walk.src.virt.addr, nbytes, + walk.iv, walk.ivsize); + + if (unlikely(err)) { + pr_err("wc_AesXtsEncrypt failed: %d\n", err); + return err; + } + + err = skcipher_walk_done(&walk, walk.nbytes - nbytes); + + if (unlikely(err)) { + pr_err("skcipher_walk_done() failed: %d\n", err); + return err; + } + } + + return err; +} + +static int km_AesXtsDecrypt(struct skcipher_request *req) +{ + int err = 0; + struct crypto_skcipher * tfm = NULL; + struct km_AesXtsCtx * ctx = NULL; + struct skcipher_walk walk; + unsigned int nbytes = 0; + + tfm = crypto_skcipher_reqtfm(req); + ctx = crypto_skcipher_ctx(tfm); + + err = skcipher_walk_virt(&walk, req, false); + + if (unlikely(err)) { + pr_err("skcipher_walk_virt() failed: %d\n", err); + return err; + } + + while ((nbytes = walk.nbytes)) { + err = wc_AesXtsDecrypt(ctx->aesXts, walk.dst.virt.addr, + walk.src.virt.addr, nbytes, + walk.iv, walk.ivsize); + + if (unlikely(err)) { + pr_err("wc_AesCbcDecrypt failed"); + return err; + } + + err = skcipher_walk_done(&walk, walk.nbytes - nbytes); + + if (unlikely(err)) { + pr_err("skcipher_walk_done() failed: %d\n", err); + return err; + } + } + + return err; +} + +static struct skcipher_alg xtsAesAlg = { + .base.cra_name = WOLFKM_AESXTS_NAME, + .base.cra_driver_name = WOLFKM_AESXTS_DRIVER, + .base.cra_priority = WOLFSSL_LINUXKM_LKCAPI_PRIORITY, + .base.cra_blocksize = AES_BLOCK_SIZE, + .base.cra_ctxsize = sizeof(struct km_AesXtsCtx), + .base.cra_module = THIS_MODULE, + + .min_keysize = 2 * AES_128_KEY_SIZE, + .max_keysize = 2 * AES_256_KEY_SIZE, + .ivsize = AES_BLOCK_SIZE, + .walksize = 2 * AES_BLOCK_SIZE, + .init = km_AesXtsInit, + .exit = km_AesXtsExit, + .setkey = km_AesXtsSetKey, + .encrypt = km_AesXtsEncrypt, + .decrypt = km_AesXtsDecrypt +}; +static int xtsAesAlg_loaded = 0; + +#endif /* WOLFSSL_AES_XTS && + * (LINUXKM_LKCAPI_REGISTER_ALL || LINUXKM_LKCAPI_REGISTER_AESXTS) + */ + +/* cipher tests, cribbed from test.c, with supplementary LKCAPI tests: */ + +#if defined(HAVE_AES_CBC) && \ + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESCBC)) + +static int linuxkm_test_aescbc(void) +{ + int ret = 0; + struct crypto_skcipher * tfm = NULL; + struct skcipher_request * req = NULL; + struct scatterlist src, dst; + Aes aes; + WOLFSSL_SMALL_STACK_STATIC const byte key32[] = + { + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66 + }; + WOLFSSL_SMALL_STACK_STATIC const byte vector[] = /* Now is the time for all good men w/o trailing 0 */ + { + 0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74, + 0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20, + 0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20, + 0x67,0x6f,0x6f,0x64,0x20,0x6d,0x65,0x6e + }; + WOLFSSL_SMALL_STACK_STATIC const byte iv[] = "1234567890abcdef"; + byte iv_copy[sizeof iv]; + byte enc[sizeof(vector)]; + byte dec[sizeof(vector)]; + u8 * enc2 = NULL; + u8 * dec2 = NULL; + + XMEMSET(enc, 0, sizeof(enc)); + XMEMSET(dec, 0, sizeof(enc)); + + ret = wc_AesInit(&aes, NULL, INVALID_DEVID); + if (ret) { + pr_err("wolfcrypt wc_AesInit failed with return code %d.\n", ret); + return -1; + } + + ret = wc_AesSetKey(&aes, key32, AES_BLOCK_SIZE * 2, iv, AES_ENCRYPTION); + if (ret) { + pr_err("wolfcrypt wc_AesSetKey failed with return code %d\n", ret); + return -1; + } + + ret = wc_AesCbcEncrypt(&aes, enc, vector, sizeof(vector)); + if (ret) { + pr_err("wolfcrypt wc_AesCbcEncrypt failed with return code %d\n", ret); + return -1; + } + + /* Re init for decrypt and set flag. */ + wc_AesFree(&aes); + + ret = wc_AesInit(&aes, NULL, INVALID_DEVID); + if (ret) { + pr_err("wolfcrypt wc_AesInit failed with return code %d.\n", ret); + return -1; + } + + ret = wc_AesSetKey(&aes, key32, AES_BLOCK_SIZE * 2, iv, AES_DECRYPTION); + if (ret) { + pr_err("wolfcrypt wc_AesSetKey failed with return code %d.\n", ret); + return -1; + } + + ret = wc_AesCbcDecrypt(&aes, dec, enc, sizeof(vector)); + if (ret) { + pr_err("wolfcrypt wc_AesCbcDecrypt failed with return code %d\n", ret); + return -1; + } + + ret = XMEMCMP(vector, dec, sizeof(vector)); + if (ret) { + pr_err("error: vector and dec do not match: %d\n", ret); + return -1; + } + + /* now the kernel crypto part */ + enc2 = kmalloc(sizeof(vector), GFP_KERNEL); + if (!enc2) { + pr_err("error: kmalloc failed\n"); + goto test_cbc_end; + } + + dec2 = kmalloc(sizeof(vector), GFP_KERNEL); + if (!dec2) { + pr_err("error: kmalloc failed\n"); + goto test_cbc_end; + } + + memcpy(dec2, vector, sizeof(vector)); + + tfm = crypto_alloc_skcipher(WOLFKM_AESCBC_DRIVER, 0, 0); + if (IS_ERR(tfm)) { + pr_err("error: allocating AES skcipher algorithm %s failed: %ld\n", + WOLFKM_AESCBC_DRIVER, PTR_ERR(tfm)); + goto test_cbc_end; + } + + ret = crypto_skcipher_setkey(tfm, key32, AES_BLOCK_SIZE * 2); + if (ret) { + pr_err("error: crypto_skcipher_setkey returned: %d\n", ret); + goto test_cbc_end; + } + + req = skcipher_request_alloc(tfm, GFP_KERNEL); + if (IS_ERR(req)) { + pr_err("error: allocating AES skcipher request %s failed\n", + WOLFKM_AESCBC_DRIVER); + goto test_cbc_end; + } + + sg_init_one(&src, dec2, sizeof(vector)); + sg_init_one(&dst, enc2, sizeof(vector)); + + XMEMCPY(iv_copy, iv, sizeof iv); + skcipher_request_set_crypt(req, &src, &dst, sizeof(vector), iv_copy); + + ret = crypto_skcipher_encrypt(req); + + if (ret) { + pr_err("error: crypto_skcipher_encrypt returned: %d\n", ret); + goto test_cbc_end; + } + + ret = XMEMCMP(enc, enc2, sizeof(vector)); + if (ret) { + pr_err("error: enc and enc2 do not match: %d\n", ret); + goto test_cbc_end; + } + + memset(dec2, 0, sizeof(vector)); + sg_init_one(&src, enc2, sizeof(vector)); + sg_init_one(&dst, dec2, sizeof(vector)); + + XMEMCPY(iv_copy, iv, sizeof iv); + skcipher_request_set_crypt(req, &src, &dst, sizeof(vector), iv_copy); + + ret = crypto_skcipher_decrypt(req); + + if (ret) { + pr_err("ERROR: crypto_skcipher_decrypt returned %d\n", ret); + goto test_cbc_end; + } + + ret = XMEMCMP(dec, dec2, sizeof(vector)); + if (ret) { + pr_err("error: dec and dec2 do not match: %d\n", ret); + goto test_cbc_end; + } + +test_cbc_end: + + if (enc2) { kfree(enc2); enc2 = NULL; } + if (dec2) { kfree(dec2); dec2 = NULL; } + if (req) { skcipher_request_free(req); req = NULL; } + if (tfm) { crypto_free_skcipher(tfm); tfm = NULL; } + + return ret; +} + +#endif /* HAVE_AES_CBC && + * (LINUXKM_LKCAPI_REGISTER_ALL || LINUXKM_LKCAPI_REGISTER_AESCBC) + */ + +#if defined(WOLFSSL_AES_CFB) && \ + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESCFB)) + +static int linuxkm_test_aescfb(void) +{ + int ret = 0; + struct crypto_skcipher * tfm = NULL; + struct skcipher_request * req = NULL; + struct scatterlist src, dst; + Aes aes; + WOLFSSL_SMALL_STACK_STATIC const byte key32[] = + { + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66 + }; + WOLFSSL_SMALL_STACK_STATIC const byte vector[] = /* Now is the time for all good men w/o trailing 0 */ + { + 0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74, + 0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20, + 0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20, + 0x67,0x6f,0x6f,0x64,0x20,0x6d,0x65,0x6e + }; + WOLFSSL_SMALL_STACK_STATIC const byte iv[] = "1234567890abcdef"; + byte iv_copy[sizeof iv]; + byte enc[sizeof(vector)]; + byte dec[sizeof(vector)]; + u8 * enc2 = NULL; + u8 * dec2 = NULL; + + XMEMSET(enc, 0, sizeof(enc)); + XMEMSET(dec, 0, sizeof(enc)); + + ret = wc_AesInit(&aes, NULL, INVALID_DEVID); + if (ret) { + pr_err("wolfcrypt wc_AesInit failed with return code %d.\n", ret); + return -1; + } + + ret = wc_AesSetKey(&aes, key32, AES_BLOCK_SIZE * 2, iv, AES_ENCRYPTION); + if (ret) { + pr_err("wolfcrypt wc_AesSetKey failed with return code %d\n", ret); + return -1; + } + + ret = wc_AesCfbEncrypt(&aes, enc, vector, sizeof(vector)); + if (ret) { + pr_err("wolfcrypt wc_AesCfbEncrypt failed with return code %d\n", ret); + return -1; + } + + /* Re init for decrypt and set flag. */ + wc_AesFree(&aes); + + ret = wc_AesInit(&aes, NULL, INVALID_DEVID); + if (ret) { + pr_err("wolfcrypt wc_AesInit failed with return code %d.\n", ret); + return -1; + } + + ret = wc_AesSetKey(&aes, key32, AES_BLOCK_SIZE * 2, iv, AES_ENCRYPTION); + if (ret) { + pr_err("wolfcrypt wc_AesSetKey failed with return code %d.\n", ret); + return -1; + } + + ret = wc_AesCfbDecrypt(&aes, dec, enc, sizeof(vector)); + if (ret) { + pr_err("wolfcrypt wc_AesCfbDecrypt failed with return code %d\n", ret); + return -1; + } + + ret = XMEMCMP(vector, dec, sizeof(vector)); + if (ret) { + pr_err("error: vector and dec do not match: %d\n", ret); + return -1; + } + + /* now the kernel crypto part */ + enc2 = kmalloc(sizeof(vector), GFP_KERNEL); + if (!enc2) { + pr_err("error: kmalloc failed\n"); + goto test_cfb_end; + } + + dec2 = kmalloc(sizeof(vector), GFP_KERNEL); + if (!dec2) { + pr_err("error: kmalloc failed\n"); + goto test_cfb_end; + } + + memcpy(dec2, vector, sizeof(vector)); + + tfm = crypto_alloc_skcipher(WOLFKM_AESCFB_DRIVER, 0, 0); + if (IS_ERR(tfm)) { + pr_err("error: allocating AES skcipher algorithm %s failed: %ld\n", + WOLFKM_AESCFB_DRIVER, PTR_ERR(tfm)); + goto test_cfb_end; + } + + ret = crypto_skcipher_setkey(tfm, key32, AES_BLOCK_SIZE * 2); + if (ret) { + pr_err("error: crypto_skcipher_setkey returned: %d\n", ret); + goto test_cfb_end; + } + + req = skcipher_request_alloc(tfm, GFP_KERNEL); + if (IS_ERR(req)) { + pr_err("error: allocating AES skcipher request %s failed\n", + WOLFKM_AESCFB_DRIVER); + goto test_cfb_end; + } + + sg_init_one(&src, dec2, sizeof(vector)); + sg_init_one(&dst, enc2, sizeof(vector)); + + XMEMCPY(iv_copy, iv, sizeof iv); + skcipher_request_set_crypt(req, &src, &dst, sizeof(vector), iv_copy); + + ret = crypto_skcipher_encrypt(req); + + if (ret) { + pr_err("error: crypto_skcipher_encrypt returned: %d\n", ret); + goto test_cfb_end; + } + + ret = XMEMCMP(enc, enc2, sizeof(vector)); + if (ret) { + pr_err("error: enc and enc2 do not match: %d\n", ret); + goto test_cfb_end; + } + + memset(dec2, 0, sizeof(vector)); + sg_init_one(&src, enc2, sizeof(vector)); + sg_init_one(&dst, dec2, sizeof(vector)); + + XMEMCPY(iv_copy, iv, sizeof iv); + skcipher_request_set_crypt(req, &src, &dst, sizeof(vector), iv_copy); + + ret = crypto_skcipher_decrypt(req); + + if (ret) { + pr_err("error: crypto_skcipher_decrypt returned: %d\n", ret); + goto test_cfb_end; + } + + ret = XMEMCMP(dec, dec2, sizeof(vector)); + if (ret) { + pr_err("error: dec and dec2 do not match: %d\n", ret); + goto test_cfb_end; + } + +test_cfb_end: + + if (enc2) { kfree(enc2); enc2 = NULL; } + if (dec2) { kfree(dec2); dec2 = NULL; } + if (req) { skcipher_request_free(req); req = NULL; } + if (tfm) { crypto_free_skcipher(tfm); tfm = NULL; } + + return ret; +} + +#endif /* WOLFSSL_AES_CFB && + * (LINUXKM_LKCAPI_REGISTER_ALL || LINUXKM_LKCAPI_REGISTER_AESCFB) + */ + +#if defined(HAVE_AESGCM) && \ + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESGCM)) && \ + (! (defined(WOLFSSL_AESNI) && defined(WC_AES_C_DYNAMIC_FALLBACK))) + +static int linuxkm_test_aesgcm(void) +{ + int ret = 0; + struct crypto_aead * tfm = NULL; + struct aead_request * req = NULL; + struct scatterlist * src = NULL; + struct scatterlist * dst = NULL; + Aes aes; + WOLFSSL_SMALL_STACK_STATIC const byte key32[] = + { + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66 + }; + WOLFSSL_SMALL_STACK_STATIC const byte vector[] = /* Now is the time for all w/o trailing 0 */ + { + 0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74, + 0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20, + 0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20 + }; + WOLFSSL_SMALL_STACK_STATIC const byte assoc[] = + { + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2 + }; + WOLFSSL_SMALL_STACK_STATIC const byte ivstr[] = "1234567890abcdef"; + byte enc[sizeof(vector)]; + byte authTag[AES_BLOCK_SIZE]; + byte dec[sizeof(vector)]; + u8 * assoc2 = NULL; + u8 * enc2 = NULL; + u8 * dec2 = NULL; + u8 * iv = NULL; + size_t encryptLen = sizeof(vector); + size_t decryptLen = sizeof(vector) + sizeof(authTag); + + /* Init stack variables. */ + XMEMSET(enc, 0, sizeof(vector)); + XMEMSET(dec, 0, sizeof(vector)); + XMEMSET(authTag, 0, AES_BLOCK_SIZE); + + ret = wc_AesInit(&aes, NULL, INVALID_DEVID); + if (ret) { + pr_err("error: wc_AesInit failed with return code %d.\n", ret); + goto test_gcm_end; + } + + ret = wc_AesGcmInit(&aes, key32, sizeof(key32)/sizeof(byte), ivstr, + AES_BLOCK_SIZE); + if (ret) { + pr_err("error: wc_AesGcmInit failed with return code %d.\n", ret); + goto test_gcm_end; + } + + ret = wc_AesGcmEncryptUpdate(&aes, NULL, NULL, 0, assoc, sizeof(assoc)); + if (ret) { + pr_err("error: wc_AesGcmEncryptUpdate failed with return code %d\n", ret); + goto test_gcm_end; + } + + ret = wc_AesGcmEncryptUpdate(&aes, enc, vector, sizeof(vector), NULL, 0); + if (ret) { + pr_err("error: wc_AesGcmEncryptUpdate failed with return code %d\n", ret); + goto test_gcm_end; + } + + ret = wc_AesGcmEncryptFinal(&aes, authTag, AES_BLOCK_SIZE); + if (ret) { + pr_err("error: wc_AesGcmEncryptFinal failed with return code %d\n", ret); + goto test_gcm_end; + } + + ret = wc_AesGcmInit(&aes, key32, sizeof(key32)/sizeof(byte), ivstr, + AES_BLOCK_SIZE); + if (ret) { + pr_err("error: wc_AesGcmInit failed with return code %d.\n", ret); + goto test_gcm_end; + } + + ret = wc_AesGcmDecryptUpdate(&aes, dec, enc, sizeof(vector), assoc, sizeof(assoc)); + if (ret) { + pr_err("error: wc_AesGcmDecryptUpdate failed with return code %d\n", ret); + goto test_gcm_end; + } + + ret = wc_AesGcmDecryptFinal(&aes, authTag, AES_BLOCK_SIZE); + if (ret) { + pr_err("error: wc_AesGcmEncryptFinal failed with return code %d\n", ret); + goto test_gcm_end; + } + + ret = XMEMCMP(vector, dec, sizeof(vector)); + if (ret) { + pr_err("error: gcm: vector and dec do not match: %d\n", ret); + goto test_gcm_end; + } + + /* now the kernel crypto part */ + assoc2 = kmalloc(sizeof(assoc), GFP_KERNEL); + if (IS_ERR(assoc2)) { + pr_err("error: kmalloc failed\n"); + goto test_gcm_end; + } + memset(assoc2, 0, sizeof(assoc)); + memcpy(assoc2, assoc, sizeof(assoc)); + + iv = kmalloc(AES_BLOCK_SIZE, GFP_KERNEL); + if (IS_ERR(iv)) { + pr_err("error: kmalloc failed\n"); + goto test_gcm_end; + } + memset(iv, 0, AES_BLOCK_SIZE); + memcpy(iv, ivstr, AES_BLOCK_SIZE); + + enc2 = kmalloc(decryptLen, GFP_KERNEL); + if (IS_ERR(enc2)) { + pr_err("error: kmalloc failed\n"); + goto test_gcm_end; + } + + dec2 = kmalloc(decryptLen, GFP_KERNEL); + if (IS_ERR(dec2)) { + pr_err("error: kmalloc failed\n"); + goto test_gcm_end; + } + + memset(enc2, 0, decryptLen); + memset(dec2, 0, decryptLen); + memcpy(dec2, vector, sizeof(vector)); + + tfm = crypto_alloc_aead(WOLFKM_AESGCM_DRIVER, 0, 0); + if (IS_ERR(tfm)) { + pr_err("error: allocating AES skcipher algorithm %s failed: %ld\n", + WOLFKM_AESGCM_DRIVER, PTR_ERR(tfm)); + goto test_gcm_end; + } + + ret = crypto_aead_setkey(tfm, key32, AES_BLOCK_SIZE * 2); + if (ret) { + pr_err("error: crypto_aead_setkey returned: %d\n", ret); + goto test_gcm_end; + } + + ret = crypto_aead_setauthsize(tfm, sizeof(authTag)); + if (ret) { + pr_err("error: crypto_aead_setauthsize returned: %d\n", ret); + goto test_gcm_end; + } + + req = aead_request_alloc(tfm, GFP_KERNEL); + if (IS_ERR(req)) { + pr_err("error: allocating AES aead request %s failed: %ld\n", + WOLFKM_AESCBC_DRIVER, PTR_ERR(req)); + goto test_gcm_end; + } + + src = kmalloc(sizeof(struct scatterlist) * 2, GFP_KERNEL); + dst = kmalloc(sizeof(struct scatterlist) * 2, GFP_KERNEL); + + if (IS_ERR(src) || IS_ERR(dst)) { + pr_err("error: kmalloc src or dst failed: %ld, %ld\n", + PTR_ERR(src), PTR_ERR(dst)); + goto test_gcm_end; + } + + sg_init_table(src, 2); + sg_set_buf(src, assoc2, sizeof(assoc)); + sg_set_buf(&src[1], dec2, sizeof(vector)); + + sg_init_table(dst, 2); + sg_set_buf(dst, assoc2, sizeof(assoc)); + sg_set_buf(&dst[1], enc2, decryptLen); + + aead_request_set_callback(req, 0, NULL, NULL); + aead_request_set_ad(req, sizeof(assoc)); + aead_request_set_crypt(req, src, dst, sizeof(vector), iv); + + ret = crypto_aead_encrypt(req); + + if (ret) { + pr_err("error: crypto_aead_encrypt returned: %d\n", ret); + goto test_gcm_end; + } + + ret = XMEMCMP(enc, enc2, sizeof(vector)); + if (ret) { + pr_err("error: enc and enc2 do not match: %d\n", ret); + goto test_gcm_end; + } + + ret = XMEMCMP(authTag, enc2 + encryptLen, sizeof(authTag)); + if (ret) { + pr_err("error: authTags do not match: %d\n", ret); + goto test_gcm_end; + } + + /* Now decrypt crypto request. Reverse src and dst. */ + memset(dec2, 0, decryptLen); + aead_request_set_ad(req, sizeof(assoc)); + aead_request_set_crypt(req, dst, src, decryptLen, iv); + + ret = crypto_aead_decrypt(req); + + if (ret) { + pr_err("error: crypto_aead_decrypt returned: %d\n", ret); + goto test_gcm_end; + } + + ret = XMEMCMP(dec, dec2, sizeof(vector)); + if (ret) { + pr_err("error: dec and dec2 do not match: %d\n", ret); + goto test_gcm_end; + } + +test_gcm_end: + if (req) { aead_request_free(req); req = NULL; } + if (tfm) { crypto_free_aead(tfm); tfm = NULL; } + + if (src) { kfree(src); src = NULL; } + if (dst) { kfree(dst); dst = NULL; } + + if (dec2) { kfree(dec2); dec2 = NULL; } + if (enc2) { kfree(enc2); enc2 = NULL; } + + if (assoc2) { kfree(assoc2); assoc2 = NULL; } + if (iv) { kfree(iv); iv = NULL; } + + return ret; +} + +#endif /* HAVE_AESGCM && + * (LINUXKM_LKCAPI_REGISTER_ALL || LINUXKM_LKCAPI_REGISTER_AESGCM) && + * (! (WOLFSSL_AESNI && WC_AES_C_DYNAMIC_FALLBACK)) + */ + +#if defined(WOLFSSL_AES_XTS) && \ + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESXTS)) + +#ifndef HEAP_HINT +#define HEAP_HINT NULL +#endif + +#ifndef ERROR_OUT +#define ERROR_OUT(err, eLabel) do { ret = (err); goto eLabel; } while (0) +#endif + +#ifndef WC_TEST_RET_ENC_EC +#define WC_TEST_RET_ENC_EC(ret) (ret) +#endif + +#ifndef WC_TEST_RET_ENC_NC +#define WC_TEST_RET_ENC_NC (-1) +#endif + +#ifndef WC_USE_DEVID +#define WC_USE_DEVID INVALID_DEVID +#endif +static const int devId = WC_USE_DEVID; + +/* test vectors from http://csrc.nist.gov/groups/STM/cavp/block-cipher-modes.html */ +#ifdef WOLFSSL_AES_128 +static int aes_xts_128_test(void) +{ +#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) + XtsAes *aes = NULL; +#else + XtsAes aes[1]; +#endif + int aes_inited = 0; + int ret = 0; + unsigned char buf[AES_BLOCK_SIZE * 2 + 8]; + unsigned char cipher[AES_BLOCK_SIZE * 2 + 8]; + + /* 128 key tests */ + WOLFSSL_SMALL_STACK_STATIC const unsigned char k1[] = { + 0xa1, 0xb9, 0x0c, 0xba, 0x3f, 0x06, 0xac, 0x35, + 0x3b, 0x2c, 0x34, 0x38, 0x76, 0x08, 0x17, 0x62, + 0x09, 0x09, 0x23, 0x02, 0x6e, 0x91, 0x77, 0x18, + 0x15, 0xf2, 0x9d, 0xab, 0x01, 0x93, 0x2f, 0x2f + }; + + WOLFSSL_SMALL_STACK_STATIC const unsigned char i1[] = { + 0x4f, 0xae, 0xf7, 0x11, 0x7c, 0xda, 0x59, 0xc6, + 0x6e, 0x4b, 0x92, 0x01, 0x3e, 0x76, 0x8a, 0xd5 + }; + + WOLFSSL_SMALL_STACK_STATIC const unsigned char p1[] = { + 0xeb, 0xab, 0xce, 0x95, 0xb1, 0x4d, 0x3c, 0x8d, + 0x6f, 0xb3, 0x50, 0x39, 0x07, 0x90, 0x31, 0x1c + }; + + /* plain text test of partial block is not from NIST test vector list */ + WOLFSSL_SMALL_STACK_STATIC const unsigned char pp[] = { + 0xeb, 0xab, 0xce, 0x95, 0xb1, 0x4d, 0x3c, 0x8d, + 0x6f, 0xb3, 0x50, 0x39, 0x07, 0x90, 0x31, 0x1c, + 0x6e, 0x4b, 0x92, 0x01, 0x3e, 0x76, 0x8a, 0xd5 + }; + + WOLFSSL_SMALL_STACK_STATIC const unsigned char c1[] = { + 0x77, 0x8a, 0xe8, 0xb4, 0x3c, 0xb9, 0x8d, 0x5a, + 0x82, 0x50, 0x81, 0xd5, 0xbe, 0x47, 0x1c, 0x63 + }; + + WOLFSSL_SMALL_STACK_STATIC const unsigned char cp[] = { + 0x2b, 0xf7, 0x2c, 0xf3, 0xeb, 0x85, 0xef, 0x7b, + 0x0b, 0x76, 0xa0, 0xaa, 0xf3, 0x3f, 0x25, 0x8b, + 0x77, 0x8a, 0xe8, 0xb4, 0x3c, 0xb9, 0x8d, 0x5a + }; + + WOLFSSL_SMALL_STACK_STATIC const unsigned char k2[] = { + 0x39, 0x25, 0x79, 0x05, 0xdf, 0xcc, 0x77, 0x76, + 0x6c, 0x87, 0x0a, 0x80, 0x6a, 0x60, 0xe3, 0xc0, + 0x93, 0xd1, 0x2a, 0xcf, 0xcb, 0x51, 0x42, 0xfa, + 0x09, 0x69, 0x89, 0x62, 0x5b, 0x60, 0xdb, 0x16 + }; + + WOLFSSL_SMALL_STACK_STATIC const unsigned char i2[] = { + 0x5c, 0xf7, 0x9d, 0xb6, 0xc5, 0xcd, 0x99, 0x1a, + 0x1c, 0x78, 0x81, 0x42, 0x24, 0x95, 0x1e, 0x84 + }; + + WOLFSSL_SMALL_STACK_STATIC const unsigned char p2[] = { + 0xbd, 0xc5, 0x46, 0x8f, 0xbc, 0x8d, 0x50, 0xa1, + 0x0d, 0x1c, 0x85, 0x7f, 0x79, 0x1c, 0x5c, 0xba, + 0xb3, 0x81, 0x0d, 0x0d, 0x73, 0xcf, 0x8f, 0x20, + 0x46, 0xb1, 0xd1, 0x9e, 0x7d, 0x5d, 0x8a, 0x56 + }; + + WOLFSSL_SMALL_STACK_STATIC const unsigned char c2[] = { + 0xd6, 0xbe, 0x04, 0x6d, 0x41, 0xf2, 0x3b, 0x5e, + 0xd7, 0x0b, 0x6b, 0x3d, 0x5c, 0x8e, 0x66, 0x23, + 0x2b, 0xe6, 0xb8, 0x07, 0xd4, 0xdc, 0xc6, 0x0e, + 0xff, 0x8d, 0xbc, 0x1d, 0x9f, 0x7f, 0xc8, 0x22 + }; + + WOLFSSL_SMALL_STACK_STATIC const unsigned char cp2[] = { + 0x2b, 0xf7, 0x2c, 0xf3, 0xeb, 0x85, 0xef, 0x7b, + 0x0b, 0x76, 0xa0, 0xaa, 0xf3, 0x3f, 0x25, 0x8b, + 0x77, 0x8a, 0xe8, 0xb4, 0x3c, 0xb9, 0x8d, 0x5a + }; + +#ifndef HAVE_FIPS_VERSION /* FIPS requires different keys for main and tweak. */ + WOLFSSL_SMALL_STACK_STATIC const unsigned char k3[] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + }; + WOLFSSL_SMALL_STACK_STATIC const unsigned char i3[] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + }; + WOLFSSL_SMALL_STACK_STATIC const unsigned char p3[] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0xff, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 + }; + WOLFSSL_SMALL_STACK_STATIC const unsigned char c3[] = { + 0xA2, 0x07, 0x47, 0x76, 0x3F, 0xEC, 0x0C, 0x23, + 0x1B, 0xD0, 0xBD, 0x46, 0x9A, 0x27, 0x38, 0x12, + 0x95, 0x02, 0x3D, 0x5D, 0xC6, 0x94, 0x51, 0x36, + 0xA0, 0x85, 0xD2, 0x69, 0x6E, 0x87, 0x0A, 0xBF, + 0xB5, 0x5A, 0xDD, 0xCB, 0x80, 0xE0, 0xFC, 0xCD + }; +#endif /* HAVE_FIPS_VERSION */ + +#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) + if ((aes = (XtsAes *)XMALLOC(sizeof *aes, HEAP_HINT, DYNAMIC_TYPE_AES)) == NULL) + ERROR_OUT(MEMORY_E, out); +#endif + +#if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY) \ + && !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS) + ret = EVP_test(EVP_aes_128_xts(), k2, i2, p2, sizeof(p2), c2, sizeof(c2)); + if (ret != 0) { + printf("EVP_aes_128_xts failed!\n"); + goto out; + } +#endif + + XMEMSET(buf, 0, sizeof(buf)); + ret = wc_AesXtsInit(aes, HEAP_HINT, devId); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + else + aes_inited = 1; + + ret = wc_AesXtsSetKeyNoInit(aes, k2, sizeof(k2), AES_ENCRYPTION); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + + ret = wc_AesXtsEncrypt(aes, buf, p2, sizeof(p2), i2, sizeof(i2)); +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); +#endif + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + if (XMEMCMP(c2, buf, sizeof(c2))) + ERROR_OUT(WC_TEST_RET_ENC_NC, out); + +#if defined(DEBUG_VECTOR_REGISTER_ACCESS) && defined(WC_AES_C_DYNAMIC_FALLBACK) + WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(SYSLIB_FAILED_E); + ret = wc_AesXtsEncrypt(aes, buf, p2, sizeof(p2), i2, sizeof(i2)); +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); +#endif + WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(0); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + if (XMEMCMP(c2, buf, sizeof(c2))) + ERROR_OUT(WC_TEST_RET_ENC_NC, out); +#endif + + XMEMSET(buf, 0, sizeof(buf)); + + ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_ENCRYPTION); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ret = wc_AesXtsEncrypt(aes, buf, p1, sizeof(p1), i1, sizeof(i1)); +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); +#endif + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + if (XMEMCMP(c1, buf, AES_BLOCK_SIZE)) + ERROR_OUT(WC_TEST_RET_ENC_NC, out); + +#if defined(DEBUG_VECTOR_REGISTER_ACCESS) && defined(WC_AES_C_DYNAMIC_FALLBACK) + WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(SYSLIB_FAILED_E); + ret = wc_AesXtsEncrypt(aes, buf, p1, sizeof(p1), i1, sizeof(i1)); +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); +#endif + WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(0); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + if (XMEMCMP(c1, buf, AES_BLOCK_SIZE)) + ERROR_OUT(WC_TEST_RET_ENC_NC, out); +#endif + + /* partial block encryption test */ + XMEMSET(cipher, 0, sizeof(cipher)); + ret = wc_AesXtsEncrypt(aes, cipher, pp, sizeof(pp), i1, sizeof(i1)); +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); +#endif + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + if (XMEMCMP(cp2, cipher, sizeof(cp2))) + ERROR_OUT(WC_TEST_RET_ENC_NC, out); + +#if defined(DEBUG_VECTOR_REGISTER_ACCESS) && defined(WC_AES_C_DYNAMIC_FALLBACK) + WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(SYSLIB_FAILED_E); + XMEMSET(cipher, 0, sizeof(cipher)); + ret = wc_AesXtsEncrypt(aes, cipher, pp, sizeof(pp), i1, sizeof(i1)); +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); +#endif + WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(0); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + if (XMEMCMP(cp2, cipher, sizeof(cp2))) + ERROR_OUT(WC_TEST_RET_ENC_NC, out); +#endif + + /* partial block decrypt test */ + XMEMSET(buf, 0, sizeof(buf)); + ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_DECRYPTION); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ret = wc_AesXtsDecrypt(aes, buf, cipher, sizeof(pp), i1, sizeof(i1)); +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); +#endif + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + if (XMEMCMP(pp, buf, sizeof(pp))) + ERROR_OUT(WC_TEST_RET_ENC_NC, out); + +#if defined(DEBUG_VECTOR_REGISTER_ACCESS) && defined(WC_AES_C_DYNAMIC_FALLBACK) + WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(SYSLIB_FAILED_E); + XMEMSET(buf, 0, sizeof(buf)); + ret = wc_AesXtsDecrypt(aes, buf, cipher, sizeof(pp), i1, sizeof(i1)); +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); +#endif + WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(0); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + if (XMEMCMP(pp, buf, sizeof(pp))) + ERROR_OUT(WC_TEST_RET_ENC_NC, out); +#endif + + /* NIST decrypt test vector */ + XMEMSET(buf, 0, sizeof(buf)); + ret = wc_AesXtsDecrypt(aes, buf, c1, sizeof(c1), i1, sizeof(i1)); +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); +#endif + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + if (XMEMCMP(p1, buf, AES_BLOCK_SIZE)) + ERROR_OUT(WC_TEST_RET_ENC_NC, out); + +#if defined(DEBUG_VECTOR_REGISTER_ACCESS) && defined(WC_AES_C_DYNAMIC_FALLBACK) + WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(SYSLIB_FAILED_E); + XMEMSET(buf, 0, sizeof(buf)); + ret = wc_AesXtsDecrypt(aes, buf, c1, sizeof(c1), i1, sizeof(i1)); +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); +#endif + WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(0); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + if (XMEMCMP(p1, buf, AES_BLOCK_SIZE)) + ERROR_OUT(WC_TEST_RET_ENC_NC, out); +#endif + + /* fail case with decrypting using wrong key */ + XMEMSET(buf, 0, sizeof(buf)); + ret = wc_AesXtsDecrypt(aes, buf, c2, sizeof(c2), i2, sizeof(i2)); +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); +#endif + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + if (XMEMCMP(p2, buf, sizeof(p2)) == 0) /* fail case with wrong key */ + ERROR_OUT(WC_TEST_RET_ENC_NC, out); + + /* set correct key and retest */ + XMEMSET(buf, 0, sizeof(buf)); + ret = wc_AesXtsSetKeyNoInit(aes, k2, sizeof(k2), AES_DECRYPTION); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ret = wc_AesXtsDecrypt(aes, buf, c2, sizeof(c2), i2, sizeof(i2)); +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); +#endif + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + if (XMEMCMP(p2, buf, sizeof(p2))) + ERROR_OUT(WC_TEST_RET_ENC_NC, out); + +#ifndef HAVE_FIPS_VERSION + + /* Test ciphertext stealing in-place. */ + XMEMCPY(buf, p3, sizeof(p3)); + ret = wc_AesXtsSetKeyNoInit(aes, k3, sizeof(k3), AES_ENCRYPTION); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + + ret = wc_AesXtsEncrypt(aes, buf, buf, sizeof(p3), i3, sizeof(i3)); +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); +#endif + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + if (XMEMCMP(c3, buf, sizeof(c3))) + ERROR_OUT(WC_TEST_RET_ENC_NC, out); + + ret = wc_AesXtsSetKeyNoInit(aes, k3, sizeof(k3), AES_DECRYPTION); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ret = wc_AesXtsDecrypt(aes, buf, buf, sizeof(c3), i3, sizeof(i3)); +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); +#endif + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + if (XMEMCMP(p3, buf, sizeof(p3))) + ERROR_OUT(WC_TEST_RET_ENC_NC, out); + +#endif /* HAVE_FIPS_VERSION */ + +#if !defined(BENCH_EMBEDDED) && !defined(HAVE_CAVIUM) && \ + !defined(WOLFSSL_AFALG) + { + #define LARGE_XTS_SZ 1024 + #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) + byte* large_input = (byte *)XMALLOC(LARGE_XTS_SZ, HEAP_HINT, + DYNAMIC_TYPE_TMP_BUFFER); + #else + byte large_input[LARGE_XTS_SZ]; + #endif + int i; + int j; + #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) + if (large_input == NULL) + ERROR_OUT(WC_TEST_RET_ENC_EC(MEMORY_E), out); + #endif + + for (i = 0; i < (int)LARGE_XTS_SZ; i++) + large_input[i] = (byte)i; + + for (j = 16; j < (int)LARGE_XTS_SZ; j++) { + ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_ENCRYPTION); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ret = wc_AesXtsEncrypt(aes, large_input, large_input, j, i1, + sizeof(i1)); + #if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + #endif + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + + ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_DECRYPTION); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ret = wc_AesXtsDecrypt(aes, large_input, large_input, j, i1, + sizeof(i1)); + #if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + #endif + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + for (i = 0; i < j; i++) { + if (large_input[i] != (byte)i) { + ERROR_OUT(WC_TEST_RET_ENC_NC, out); + } + } + } + #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) + XFREE(large_input, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + #endif + } +#endif /* !BENCH_EMBEDDED && !HAVE_CAVIUM && + * !WOLFSSL_AFALG + */ + + /* now the kernel crypto part */ + + { + u8 * enc2 = NULL; + u8 * dec2 = NULL; + struct scatterlist * src = NULL; + struct scatterlist * dst = NULL; + struct crypto_skcipher *tfm = NULL; + struct skcipher_request *req = NULL; + u8 iv[AES_BLOCK_SIZE]; + const char *driver_name; + + enc2 = XMALLOC(sizeof(p1), NULL, DYNAMIC_TYPE_AES); + if (!enc2) { + pr_err("error: malloc failed\n"); + ret = -ENOMEM; + goto test_xts_end; + } + + dec2 = XMALLOC(sizeof(p1), NULL, DYNAMIC_TYPE_AES); + if (!dec2) { + pr_err("error: malloc failed\n"); + ret = -ENOMEM; + goto test_xts_end; + } + + src = XMALLOC(sizeof(*src) * 2, NULL, DYNAMIC_TYPE_AES); + if (! src) { + pr_err("error: malloc failed\n"); + ret = -ENOMEM; + goto test_xts_end; + } + + dst = XMALLOC(sizeof(*dst) * 2, NULL, DYNAMIC_TYPE_AES); + if (! dst) { + pr_err("error: malloc failed\n"); + ret = -ENOMEM; + goto test_xts_end; + } + + tfm = crypto_alloc_skcipher(WOLFKM_AESXTS_NAME, 0, 0); + if (IS_ERR(tfm)) { + ret = PTR_ERR(tfm); + pr_err("error: allocating AES skcipher algorithm %s failed: %d\n", + WOLFKM_AESXTS_DRIVER, ret); + goto test_xts_end; + } + + driver_name = crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)); + if (strcmp(driver_name, WOLFKM_AESXTS_DRIVER)) { + pr_err("error: unexpected implementation for %s: %s (expected %s)\n", + WOLFKM_AESXTS_NAME, driver_name, WOLFKM_AESXTS_DRIVER); + ret = -ENOENT; + goto test_xts_end; + } + + ret = crypto_skcipher_ivsize(tfm); + if (ret != sizeof iv) { + pr_err("error: AES skcipher algorithm %s crypto_skcipher_ivsize()" + " returned %d but expected %d\n", + WOLFKM_AESXTS_DRIVER, ret, (int)sizeof iv); + ret = -EINVAL; + goto test_xts_end; + } + + ret = crypto_skcipher_setkey(tfm, k1, sizeof(k1)); + if (ret) { + pr_err("error: crypto_skcipher_setkey for %s returned: %d\n", WOLFKM_AESXTS_NAME, ret); + goto test_xts_end; + } + + req = skcipher_request_alloc(tfm, GFP_KERNEL); + if (IS_ERR(req)) { + ret = PTR_ERR(req); + pr_err("error: allocating AES skcipher request %s failed: %d\n", + WOLFKM_AESXTS_DRIVER, ret); + goto test_xts_end; + } + + memcpy(dec2, p1, sizeof(p1)); + memset(enc2, 0, sizeof(p1)); + + sg_init_one(src, dec2, sizeof(p1)); + sg_init_one(dst, enc2, sizeof(p1)); + + memcpy(iv, i1, sizeof iv); + skcipher_request_set_crypt(req, src, dst, sizeof(p1), iv); + + ret = crypto_skcipher_encrypt(req); + + if (ret) { + pr_err("error: crypto_skcipher_encrypt returned: %d\n", ret); + goto test_xts_end; + } + + ret = XMEMCMP(c1, enc2, sizeof(enc2)); + if (ret) { + pr_err("error: c1 and enc2 do not match: %d\n", ret); + ret = -EINVAL; + goto test_xts_end; + } + + memset(dec2, 0, sizeof(p1)); + sg_init_one(src, enc2, sizeof(p1)); + sg_init_one(dst, dec2, sizeof(p1)); + + memcpy(iv, i1, sizeof iv); + skcipher_request_set_crypt(req, src, dst, sizeof(p1), iv); + + ret = crypto_skcipher_decrypt(req); + + if (ret) { + pr_err("ERROR: crypto_skcipher_decrypt returned %d\n", ret); + goto test_xts_end; + } + + ret = XMEMCMP(p1, dec2, sizeof(p1)); + if (ret) { + pr_err("error: p1 and dec2 do not match: %d\n", ret); + ret = -EINVAL; + goto test_xts_end; + } + + memcpy(dec2, pp, sizeof(pp)); + memset(enc2, 0, sizeof(pp)); + + sg_init_one(src, dec2, sizeof(pp)); + sg_init_one(dst, enc2, sizeof(pp)); + + memcpy(iv, i1, sizeof iv); + skcipher_request_set_crypt(req, src, dst, sizeof(pp), iv); + + ret = crypto_skcipher_encrypt(req); + + if (ret) { + pr_err("error: crypto_skcipher_encrypt returned: %d\n", ret); + goto test_xts_end; + } + + ret = XMEMCMP(cp, enc2, sizeof(cp)); + if (ret) { + pr_err("error: cp and enc2 do not match: %d\n", ret); + ret = -EINVAL; + goto test_xts_end; + } + + memset(dec2, 0, sizeof(pp)); + sg_init_one(src, enc2, sizeof(pp)); + sg_init_one(dst, dec2, sizeof(pp)); + + memcpy(iv, i1, sizeof iv); + skcipher_request_set_crypt(req, src, dst, sizeof(pp), iv); + + ret = crypto_skcipher_decrypt(req); + + if (ret) { + pr_err("ERROR: crypto_skcipher_decrypt returned %d\n", ret); + goto test_xts_end; + } + + ret = XMEMCMP(pp, dec2, sizeof(pp)); + if (ret) { + pr_err("error: pp and dec2 do not match: %d\n", ret); + ret = -EINVAL; + goto test_xts_end; + } + + test_xts_end: + + if (enc2) + XFREE(enc2, NULL, DYNAMIC_TYPE_AES); + if (dec2) + XFREE(dec2, NULL, DYNAMIC_TYPE_AES); + if (src) + XFREE(src, NULL, DYNAMIC_TYPE_AES); + if (dst) + XFREE(dst, NULL, DYNAMIC_TYPE_AES); + if (req) + skcipher_request_free(req); + if (tfm) + crypto_free_skcipher(tfm); + + } + + out: + + if (aes_inited) + wc_AesXtsFree(aes); + +#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) + if (aes) + XFREE(aes, HEAP_HINT, DYNAMIC_TYPE_AES); +#endif + + return ret; +} +#endif /* WOLFSSL_AES_128 */ + +#ifdef WOLFSSL_AES_256 +static int aes_xts_256_test(void) +{ +#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) + XtsAes *aes = NULL; +#else + XtsAes aes[1]; +#endif + int aes_inited = 0; + int ret = 0; + unsigned char buf[AES_BLOCK_SIZE * 3]; + unsigned char cipher[AES_BLOCK_SIZE * 3]; + + /* 256 key tests */ + WOLFSSL_SMALL_STACK_STATIC const unsigned char k1[] = { + 0x1e, 0xa6, 0x61, 0xc5, 0x8d, 0x94, 0x3a, 0x0e, + 0x48, 0x01, 0xe4, 0x2f, 0x4b, 0x09, 0x47, 0x14, + 0x9e, 0x7f, 0x9f, 0x8e, 0x3e, 0x68, 0xd0, 0xc7, + 0x50, 0x52, 0x10, 0xbd, 0x31, 0x1a, 0x0e, 0x7c, + 0xd6, 0xe1, 0x3f, 0xfd, 0xf2, 0x41, 0x8d, 0x8d, + 0x19, 0x11, 0xc0, 0x04, 0xcd, 0xa5, 0x8d, 0xa3, + 0xd6, 0x19, 0xb7, 0xe2, 0xb9, 0x14, 0x1e, 0x58, + 0x31, 0x8e, 0xea, 0x39, 0x2c, 0xf4, 0x1b, 0x08 + }; + + WOLFSSL_SMALL_STACK_STATIC const unsigned char i1[] = { + 0xad, 0xf8, 0xd9, 0x26, 0x27, 0x46, 0x4a, 0xd2, + 0xf0, 0x42, 0x8e, 0x84, 0xa9, 0xf8, 0x75, 0x64 + }; + + WOLFSSL_SMALL_STACK_STATIC const unsigned char p1[] = { + 0x2e, 0xed, 0xea, 0x52, 0xcd, 0x82, 0x15, 0xe1, + 0xac, 0xc6, 0x47, 0xe8, 0x10, 0xbb, 0xc3, 0x64, + 0x2e, 0x87, 0x28, 0x7f, 0x8d, 0x2e, 0x57, 0xe3, + 0x6c, 0x0a, 0x24, 0xfb, 0xc1, 0x2a, 0x20, 0x2e + }; + + WOLFSSL_SMALL_STACK_STATIC const unsigned char c1[] = { + 0xcb, 0xaa, 0xd0, 0xe2, 0xf6, 0xce, 0xa3, 0xf5, + 0x0b, 0x37, 0xf9, 0x34, 0xd4, 0x6a, 0x9b, 0x13, + 0x0b, 0x9d, 0x54, 0xf0, 0x7e, 0x34, 0xf3, 0x6a, + 0xf7, 0x93, 0xe8, 0x6f, 0x73, 0xc6, 0xd7, 0xdb + }; + + /* plain text test of partial block is not from NIST test vector list */ + WOLFSSL_SMALL_STACK_STATIC const unsigned char pp[] = { + 0xeb, 0xab, 0xce, 0x95, 0xb1, 0x4d, 0x3c, 0x8d, + 0x6f, 0xb3, 0x50, 0x39, 0x07, 0x90, 0x31, 0x1c, + 0x6e, 0x4b, 0x92, 0x01, 0x3e, 0x76, 0x8a, 0xd5 + }; + + WOLFSSL_SMALL_STACK_STATIC const unsigned char cp[] = { + 0x65, 0x5e, 0x1d, 0x37, 0x4a, 0x91, 0xe7, 0x6c, + 0x4f, 0x83, 0x92, 0xbc, 0x5a, 0x10, 0x55, 0x27, + 0x61, 0x0e, 0x5a, 0xde, 0xca, 0xc5, 0x12, 0xd8 + }; + + WOLFSSL_SMALL_STACK_STATIC const unsigned char k2[] = { + 0xad, 0x50, 0x4b, 0x85, 0xd7, 0x51, 0xbf, 0xba, + 0x69, 0x13, 0xb4, 0xcc, 0x79, 0xb6, 0x5a, 0x62, + 0xf7, 0xf3, 0x9d, 0x36, 0x0f, 0x35, 0xb5, 0xec, + 0x4a, 0x7e, 0x95, 0xbd, 0x9b, 0xa5, 0xf2, 0xec, + 0xc1, 0xd7, 0x7e, 0xa3, 0xc3, 0x74, 0xbd, 0x4b, + 0x13, 0x1b, 0x07, 0x83, 0x87, 0xdd, 0x55, 0x5a, + 0xb5, 0xb0, 0xc7, 0xe5, 0x2d, 0xb5, 0x06, 0x12, + 0xd2, 0xb5, 0x3a, 0xcb, 0x47, 0x8a, 0x53, 0xb4 + }; + + WOLFSSL_SMALL_STACK_STATIC const unsigned char i2[] = { + 0xe6, 0x42, 0x19, 0xed, 0xe0, 0xe1, 0xc2, 0xa0, + 0x0e, 0xf5, 0x58, 0x6a, 0xc4, 0x9b, 0xeb, 0x6f + }; + + WOLFSSL_SMALL_STACK_STATIC const unsigned char p2[] = { + 0x24, 0xcb, 0x76, 0x22, 0x55, 0xb5, 0xa8, 0x00, + 0xf4, 0x6e, 0x80, 0x60, 0x56, 0x9e, 0x05, 0x53, + 0xbc, 0xfe, 0x86, 0x55, 0x3b, 0xca, 0xd5, 0x89, + 0xc7, 0x54, 0x1a, 0x73, 0xac, 0xc3, 0x9a, 0xbd, + 0x53, 0xc4, 0x07, 0x76, 0xd8, 0xe8, 0x22, 0x61, + 0x9e, 0xa9, 0xad, 0x77, 0xa0, 0x13, 0x4c, 0xfc + }; + + WOLFSSL_SMALL_STACK_STATIC const unsigned char c2[] = { + 0xa3, 0xc6, 0xf3, 0xf3, 0x82, 0x79, 0x5b, 0x10, + 0x87, 0xd7, 0x02, 0x50, 0xdb, 0x2c, 0xd3, 0xb1, + 0xa1, 0x62, 0xa8, 0xb6, 0xdc, 0x12, 0x60, 0x61, + 0xc1, 0x0a, 0x84, 0xa5, 0x85, 0x3f, 0x3a, 0x89, + 0xe6, 0x6c, 0xdb, 0xb7, 0x9a, 0xb4, 0x28, 0x9b, + 0xc3, 0xea, 0xd8, 0x10, 0xe9, 0xc0, 0xaf, 0x92 + }; + +#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) + if ((aes = (XtsAes *)XMALLOC(sizeof *aes, HEAP_HINT, DYNAMIC_TYPE_AES)) == NULL) + ERROR_OUT(MEMORY_E, out); +#endif + +#if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY) \ + && !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS) + ret = EVP_test(EVP_aes_256_xts(), k2, i2, p2, sizeof(p2), c2, sizeof(c2)); + if (ret != 0) { + printf("EVP_aes_256_xts failed\n"); + goto out; + } +#endif + + ret = wc_AesXtsInit(aes, HEAP_HINT, devId); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + else + aes_inited = 1; + + XMEMSET(buf, 0, sizeof(buf)); + ret = wc_AesXtsSetKeyNoInit(aes, k2, sizeof(k2), AES_ENCRYPTION); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + + ret = wc_AesXtsEncrypt(aes, buf, p2, sizeof(p2), i2, sizeof(i2)); +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); +#endif + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + if (XMEMCMP(c2, buf, sizeof(c2))) + ERROR_OUT(WC_TEST_RET_ENC_NC, out); + + XMEMSET(buf, 0, sizeof(buf)); + ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_ENCRYPTION); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ret = wc_AesXtsEncrypt(aes, buf, p1, sizeof(p1), i1, sizeof(i1)); +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); +#endif + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + if (XMEMCMP(c1, buf, AES_BLOCK_SIZE)) + ERROR_OUT(WC_TEST_RET_ENC_NC, out); + + /* partial block encryption test */ + XMEMSET(cipher, 0, sizeof(cipher)); + ret = wc_AesXtsEncrypt(aes, cipher, pp, sizeof(pp), i1, sizeof(i1)); +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); +#endif + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + + /* partial block decrypt test */ + XMEMSET(buf, 0, sizeof(buf)); + ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_DECRYPTION); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ret = wc_AesXtsDecrypt(aes, buf, cipher, sizeof(pp), i1, sizeof(i1)); +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); +#endif + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + if (XMEMCMP(pp, buf, sizeof(pp))) + ERROR_OUT(WC_TEST_RET_ENC_NC, out); + + /* NIST decrypt test vector */ + XMEMSET(buf, 0, sizeof(buf)); + ret = wc_AesXtsDecrypt(aes, buf, c1, sizeof(c1), i1, sizeof(i1)); +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); +#endif + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + if (XMEMCMP(p1, buf, AES_BLOCK_SIZE)) + ERROR_OUT(WC_TEST_RET_ENC_NC, out); + + XMEMSET(buf, 0, sizeof(buf)); + ret = wc_AesXtsSetKeyNoInit(aes, k2, sizeof(k2), AES_DECRYPTION); + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ret = wc_AesXtsDecrypt(aes, buf, c2, sizeof(c2), i2, sizeof(i2)); +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); +#endif + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + if (XMEMCMP(p2, buf, sizeof(p2))) + ERROR_OUT(WC_TEST_RET_ENC_NC, out); + + /* now the kernel crypto part */ + + { + u8 * enc2 = NULL; + u8 * dec2 = NULL; + struct scatterlist * src = NULL; + struct scatterlist * dst = NULL; + struct crypto_skcipher *tfm = NULL; + struct skcipher_request *req = NULL; + u8 iv[AES_BLOCK_SIZE]; + const char *driver_name; + + enc2 = XMALLOC(sizeof(p1), NULL, DYNAMIC_TYPE_AES); + if (!enc2) { + pr_err("error: malloc failed\n"); + ret = -ENOMEM; + goto test_xts_end; + } + + dec2 = XMALLOC(sizeof(p1), NULL, DYNAMIC_TYPE_AES); + if (!dec2) { + pr_err("error: malloc failed\n"); + ret = -ENOMEM; + goto test_xts_end; + } + + src = XMALLOC(sizeof(*src) * 2, NULL, DYNAMIC_TYPE_AES); + if (! src) { + pr_err("error: malloc failed\n"); + ret = -ENOMEM; + goto test_xts_end; + } + + dst = XMALLOC(sizeof(*dst) * 2, NULL, DYNAMIC_TYPE_AES); + if (! dst) { + pr_err("error: malloc failed\n"); + ret = -ENOMEM; + goto test_xts_end; + } + + tfm = crypto_alloc_skcipher(WOLFKM_AESXTS_NAME, 0, 0); + if (IS_ERR(tfm)) { + ret = PTR_ERR(tfm); + pr_err("error: allocating AES skcipher algorithm %s failed: %d\n", + WOLFKM_AESXTS_DRIVER, ret); + goto test_xts_end; + } + + driver_name = crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)); + if (strcmp(driver_name, WOLFKM_AESXTS_DRIVER)) { + pr_err("error: unexpected implementation for %s: %s (expected %s)\n", + WOLFKM_AESXTS_NAME, driver_name, WOLFKM_AESXTS_DRIVER); + ret = -ENOENT; + goto test_xts_end; + } + + ret = crypto_skcipher_ivsize(tfm); + if (ret != sizeof iv) { + pr_err("error: AES skcipher algorithm %s crypto_skcipher_ivsize()" + " returned %d but expected %d\n", + WOLFKM_AESXTS_DRIVER, ret, (int)sizeof iv); + ret = -EINVAL; + goto test_xts_end; + } + + ret = crypto_skcipher_setkey(tfm, k1, sizeof(k1)); + if (ret) { + pr_err("error: crypto_skcipher_setkey for %s returned: %d\n", WOLFKM_AESXTS_NAME, ret); + goto test_xts_end; + } + + req = skcipher_request_alloc(tfm, GFP_KERNEL); + if (IS_ERR(req)) { + ret = PTR_ERR(req); + pr_err("error: allocating AES skcipher request %s failed: %d\n", + WOLFKM_AESXTS_DRIVER, ret); + goto test_xts_end; + } + + memcpy(dec2, p1, sizeof(p1)); + memset(enc2, 0, sizeof(p1)); + + sg_init_one(src, dec2, sizeof(p1)); + sg_init_one(dst, enc2, sizeof(p1)); + + memcpy(iv, i1, sizeof iv); + skcipher_request_set_crypt(req, src, dst, sizeof(p1), iv); + + ret = crypto_skcipher_encrypt(req); + + if (ret) { + pr_err("error: crypto_skcipher_encrypt returned: %d\n", ret); + goto test_xts_end; + } + + ret = XMEMCMP(c1, enc2, sizeof(enc2)); + if (ret) { + pr_err("error: c1 and enc2 do not match: %d\n", ret); + ret = -EINVAL; + goto test_xts_end; + } + + memset(dec2, 0, sizeof(p1)); + sg_init_one(src, enc2, sizeof(p1)); + sg_init_one(dst, dec2, sizeof(p1)); + + memcpy(iv, i1, sizeof iv); + skcipher_request_set_crypt(req, src, dst, sizeof(p1), iv); + + ret = crypto_skcipher_decrypt(req); + + if (ret) { + pr_err("ERROR: crypto_skcipher_decrypt returned %d\n", ret); + goto test_xts_end; + } + + ret = XMEMCMP(p1, dec2, sizeof(p1)); + if (ret) { + pr_err("error: p1 and dec2 do not match: %d\n", ret); + ret = -EINVAL; + goto test_xts_end; + } + + memcpy(dec2, pp, sizeof(pp)); + memset(enc2, 0, sizeof(pp)); + + sg_init_one(src, dec2, sizeof(pp)); + sg_init_one(dst, enc2, sizeof(pp)); + + memcpy(iv, i1, sizeof iv); + skcipher_request_set_crypt(req, src, dst, sizeof(pp), iv); + + ret = crypto_skcipher_encrypt(req); + + if (ret) { + pr_err("error: crypto_skcipher_encrypt returned: %d\n", ret); + goto test_xts_end; + } + + ret = XMEMCMP(cp, enc2, sizeof(cp)); + if (ret) { + pr_err("error: cp and enc2 do not match: %d\n", ret); + ret = -EINVAL; + goto test_xts_end; + } + + memset(dec2, 0, sizeof(pp)); + sg_init_one(src, enc2, sizeof(pp)); + sg_init_one(dst, dec2, sizeof(pp)); + + memcpy(iv, i1, sizeof iv); + skcipher_request_set_crypt(req, src, dst, sizeof(pp), iv); + + ret = crypto_skcipher_decrypt(req); + + if (ret) { + pr_err("ERROR: crypto_skcipher_decrypt returned %d\n", ret); + goto test_xts_end; + } + + ret = XMEMCMP(pp, dec2, sizeof(pp)); + if (ret) { + pr_err("error: pp and dec2 do not match: %d\n", ret); + ret = -EINVAL; + goto test_xts_end; + } + + test_xts_end: + + if (enc2) + XFREE(enc2, NULL, DYNAMIC_TYPE_AES); + if (dec2) + XFREE(dec2, NULL, DYNAMIC_TYPE_AES); + if (src) + XFREE(src, NULL, DYNAMIC_TYPE_AES); + if (dst) + XFREE(dst, NULL, DYNAMIC_TYPE_AES); + if (req) + skcipher_request_free(req); + if (tfm) + crypto_free_skcipher(tfm); + + } + + out: + + if (aes_inited) + wc_AesXtsFree(aes); + +#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) + if (aes) + XFREE(aes, HEAP_HINT, DYNAMIC_TYPE_AES); +#endif + + return ret; +} +#endif /* WOLFSSL_AES_256 */ + +static int linuxkm_test_aesxts(void) { + int ret; + + #ifdef WOLFSSL_AES_128 + ret = aes_xts_128_test(); + if (ret != 0) { + pr_err("aes_xts_128_test() failed with retval %d.\n", ret); + goto out; + } + #endif + #ifdef WOLFSSL_AES_256 + ret = aes_xts_256_test(); + if (ret != 0) { + pr_err("aes_xts_256_test() failed with retval %d.\n", ret); + goto out; + } + #endif + +out: + + return ret; +} + +#endif /* WOLFSSL_AES_XTS && + * (LINUXKM_LKCAPI_REGISTER_ALL || LINUXKM_LKCAPI_REGISTER_AESXTS) + */ + +#endif /* !NO_AES */ + +static int linuxkm_lkcapi_register(void) +{ + int ret = 0; + +#define REGISTER_ALG(alg, installer, tester) do { \ + if (alg ## _loaded) {\ + pr_err("ERROR: %s is already registered.\n", (alg).base.cra_driver_name); \ + return -EEXIST; \ + } \ + \ + ret = (installer)(&(alg)); \ + \ + if (ret) { \ + pr_err("ERROR: " #installer " for %s failed with return code %d.\n", (alg).base.cra_driver_name, ret); \ + return ret; \ + } \ + \ + alg ## _loaded = 1; \ + \ + ret = (tester()); \ + \ + if (ret) { \ + pr_err("ERROR: self-test for %s failed with return code %d.\n", (alg).base.cra_driver_name, ret); \ + return ret; \ + } \ + pr_info("%s self-test OK -- registered for %s with priority %d.\n", (alg).base.cra_driver_name, (alg).base.cra_name, (alg).base.cra_priority); \ + } while (0) + +#if defined(HAVE_AES_CBC) && \ + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESCBC)) + + REGISTER_ALG(cbcAesAlg, crypto_register_skcipher, linuxkm_test_aescbc); +#endif + +#if defined(WOLFSSL_AES_CFB) && \ + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESCFB)) + + REGISTER_ALG(cfbAesAlg, crypto_register_skcipher, linuxkm_test_aescfb); +#endif + +#if defined(HAVE_AESGCM) && \ + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESGCM)) && \ + (! (defined(WOLFSSL_AESNI) && defined(WC_AES_C_DYNAMIC_FALLBACK))) + + REGISTER_ALG(gcmAesAead, crypto_register_aead, linuxkm_test_aesgcm); +#endif + +#if defined(WOLFSSL_AES_XTS) && \ + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESXTS)) + + REGISTER_ALG(xtsAesAlg, crypto_register_skcipher, linuxkm_test_aesxts); +#endif + +#undef REGISTER_ALG + + return 0; +} + +static void linuxkm_lkcapi_unregister(void) +{ +#if defined(HAVE_AES_CBC) && \ + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESCBC)) + if (cbcAesAlg_loaded) { + crypto_unregister_skcipher(&cbcAesAlg); + cbcAesAlg_loaded = 0; + } +#endif +#if defined(WOLFSSL_AES_CFB) && \ + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESCFB)) + if (cfbAesAlg_loaded) { + crypto_unregister_skcipher(&cfbAesAlg); + cfbAesAlg_loaded = 0; + } +#endif +#if defined(HAVE_AESGCM) && \ + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESGCM)) && \ + (! (defined(WOLFSSL_AESNI) && defined(WC_AES_C_DYNAMIC_FALLBACK))) + if (gcmAesAead_loaded) { + crypto_unregister_aead(&gcmAesAead); + gcmAesAead_loaded = 0; + } +#endif +#if defined(WOLFSSL_AES_XTS) && \ + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESXTS)) + if (xtsAesAlg_loaded) { + crypto_unregister_skcipher(&xtsAesAlg); + xtsAesAlg_loaded = 0; + } +#endif +} From 39c74a9bf8f1e73a1cbe2bbedbaf32cd354b60cc Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Fri, 26 Jan 2024 15:08:22 -0600 Subject: [PATCH 14/63] AES-XTS: split XtsAes.aes in two, XtsAes.aes_encrypt and XtsAes.aes_decrypt, and add AES_ENCRYPTION_AND_DECRYPTION option constant, to accommodate Linux kernel crypto API model. in wc_AesXtsSetKeyNoInit(), add FIPS check that main and tweak keys differ, and allow setting encrypt and decrypt keys simultaneously using AES_ENCRYPTION_AND_DECRYPTION. in wc_AesXtsEncrypt() and wc_AesXtsDecrypt(), error if the required subkey has not been set. --- wolfcrypt/src/aes.c | 125 +++++++++++++++++++++++++++------------- wolfssl/wolfcrypt/aes.h | 4 +- 2 files changed, 88 insertions(+), 41 deletions(-) diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 2214f8a712..7308178232 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -6383,7 +6383,6 @@ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len) #endif return BAD_FUNC_ARG; } - #ifdef OPENSSL_EXTRA XMEMSET(aes->gcm.aadH, 0, sizeof(aes->gcm.aadH)); aes->gcm.aadLen = 0; @@ -12250,7 +12249,7 @@ int wc_AesKeyUnWrap(const byte* key, word32 keySz, const byte* in, word32 inSz, #ifdef WOLFSSL_AES_XTS -/* Galios Field to use */ +/* Galois Field to use */ #define GF_XTS 0x87 int wc_AesXtsInit(XtsAes* aes, void* heap, int devId) @@ -12264,21 +12263,28 @@ int wc_AesXtsInit(XtsAes* aes, void* heap, int devId) if ((ret = wc_AesInit(&aes->tweak, heap, devId)) != 0) { return ret; } - if ((ret = wc_AesInit(&aes->aes, heap, devId)) != 0) { + if ((ret = wc_AesInit(&aes->aes_encrypt, heap, devId)) != 0) { + (void)wc_AesFree(&aes->tweak); + return ret; + } + if ((ret = wc_AesInit(&aes->aes_decrypt, heap, devId)) != 0) { + (void)wc_AesFree(&aes->tweak); + (void)wc_AesFree(&aes->aes_encrypt); return ret; } return 0; } -/* This is to help with setting keys to correct encrypt or decrypt type. +/* Set up keys for encryption and/or decryption. * * tweak AES key for tweak in XTS * aes AES key for encrypt/decrypt process * key buffer holding aes key | tweak key * len length of key buffer in bytes. Should be twice that of key size. i.e. * 32 for a 16 byte key. - * dir direction, either AES_ENCRYPTION or AES_DECRYPTION + * dir direction: AES_ENCRYPTION, AES_DECRYPTION, or + * AES_ENCRYPTION_AND_DECRYPTION * heap heap hint to use for memory. Can be NULL * devId id to use with async crypto. Can be 0 * @@ -12294,26 +12300,49 @@ int wc_AesXtsSetKeyNoInit(XtsAes* aes, const byte* key, word32 len, int dir) } keySz = len/2; - if (keySz != 16 && keySz != 32) { + if (keySz != AES_128_KEY_SIZE && keySz != AES_256_KEY_SIZE) { WOLFSSL_MSG("Unsupported key size"); return WC_KEY_SIZE_E; } - if ((ret = wc_AesSetKey(&aes->aes, key, keySz, NULL, dir)) == 0) { +#ifdef HAVE_FIPS_VERSION + if (XMEMCMP(key, key + keySz, keySz) == 0) { + WOLFSSL_MSG("FIPS AES-XTS main and tweak keys must differ"); + return BAD_FUNC_ARG; + } +#endif + + if ((dir == AES_ENCRYPTION) || (dir == AES_ENCRYPTION_AND_DECRYPTION)) + ret = wc_AesSetKey(&aes->aes_encrypt, key, keySz, NULL, AES_ENCRYPTION); + + if ((ret == 0) && ((dir == AES_DECRYPTION) || (dir == AES_ENCRYPTION_AND_DECRYPTION))) + ret = wc_AesSetKey(&aes->aes_decrypt, key, keySz, NULL, AES_DECRYPTION); + + if (ret == 0) ret = wc_AesSetKey(&aes->tweak, key + keySz, keySz, NULL, AES_ENCRYPTION); - if (ret != 0) { - wc_AesFree(&aes->aes); - } + #ifdef WOLFSSL_AESNI - if (aes->aes.use_aesni != aes->tweak.use_aesni) { - if (aes->aes.use_aesni) - aes->aes.use_aesni = 0; - else - aes->tweak.use_aesni = 0; - } + if (ret == 0) { + /* With WC_AES_C_DYNAMIC_FALLBACK, the main and tweak keys could have + * conflicting _aesni status, but the AES-XTS asm implementations need + * them to all be AESNI. If any aren't, disable AESNI on all. + */ + if ((((dir == AES_ENCRYPTION) || (dir == AES_ENCRYPTION_AND_DECRYPTION)) && + (aes->aes_encrypt.use_aesni != aes->tweak.use_aesni)) || + (((dir == AES_DECRYPTION) || (dir == AES_ENCRYPTION_AND_DECRYPTION)) && + (aes->aes_decrypt.use_aesni != aes->tweak.use_aesni))) + { +#ifdef WC_AES_C_DYNAMIC_FALLBACK + aes->aes_encrypt.use_aesni = 0; + aes->aes_decrypt.use_aesni = 0; + aes->tweak.use_aesni = 0; +#else + ret = SYSLIB_FAILED_E; #endif + } } +#endif return ret; } @@ -12355,7 +12384,8 @@ int wc_AesXtsSetKey(XtsAes* aes, const byte* key, word32 len, int dir, int wc_AesXtsFree(XtsAes* aes) { if (aes != NULL) { - wc_AesFree(&aes->aes); + wc_AesFree(&aes->aes_encrypt); + wc_AesFree(&aes->aes_decrypt); wc_AesFree(&aes->tweak); } @@ -12512,7 +12542,7 @@ static int AesXtsEncrypt_sw(XtsAes* xaes, byte* out, const byte* in, word32 sz, { int ret = 0; word32 blocks = (sz / AES_BLOCK_SIZE); - Aes *aes = &xaes->aes; + Aes *aes = &xaes->aes_encrypt; Aes *tweak = &xaes->tweak; byte tmp[AES_BLOCK_SIZE]; @@ -12619,6 +12649,11 @@ int wc_AesXtsEncrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz, return BAD_FUNC_ARG; } + if (xaes->aes_encrypt.keylen == 0) { + WOLFSSL_MSG("wc_AesXtsEncrypt called with unset encryption key."); + return BAD_FUNC_ARG; + } + if (iSz < AES_BLOCK_SIZE) { return BAD_FUNC_ARG; } @@ -12631,28 +12666,29 @@ int wc_AesXtsEncrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz, { #ifdef WOLFSSL_AESNI #ifdef WC_AES_C_DYNAMIC_FALLBACK - int orig_use_aesni = xaes->aes.use_aesni; + int orig_use_aesni = xaes->aes_encrypt.use_aesni; #endif - if (xaes->aes.use_aesni && ((ret = SAVE_VECTOR_REGISTERS2()) != 0)) { + + if (xaes->aes_encrypt.use_aesni && ((ret = SAVE_VECTOR_REGISTERS2()) != 0)) { #ifdef WC_AES_C_DYNAMIC_FALLBACK - xaes->aes.use_aesni = 0; + xaes->aes_encrypt.use_aesni = 0; xaes->tweak.use_aesni = 0; #else return ret; #endif } - if (xaes->aes.use_aesni) { + if (xaes->aes_encrypt.use_aesni) { #if defined(HAVE_INTEL_AVX1) if (IS_INTEL_AVX1(intel_flags)) { - AES_XTS_encrypt_avx1(in, out, sz, i, (const byte*)xaes->aes.key, - (const byte*)xaes->tweak.key, (int)xaes->aes.rounds); + AES_XTS_encrypt_avx1(in, out, sz, i, (const byte*)xaes->aes_encrypt.key, + (const byte*)xaes->tweak.key, (int)xaes->aes_encrypt.rounds); ret = 0; } else #endif { - AES_XTS_encrypt_aesni(in, out, sz, i, (const byte*)xaes->aes.key, - (const byte*)xaes->tweak.key, (int)xaes->aes.rounds); + AES_XTS_encrypt_aesni(in, out, sz, i, (const byte*)xaes->aes_encrypt.key, + (const byte*)xaes->tweak.key, (int)xaes->aes_encrypt.rounds); ret = 0; } } @@ -12663,11 +12699,11 @@ int wc_AesXtsEncrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz, } #ifdef WOLFSSL_AESNI - if (xaes->aes.use_aesni) + if (xaes->aes_encrypt.use_aesni) RESTORE_VECTOR_REGISTERS(); #ifdef WC_AES_C_DYNAMIC_FALLBACK else if (orig_use_aesni) { - xaes->aes.use_aesni = orig_use_aesni; + xaes->aes_encrypt.use_aesni = orig_use_aesni; xaes->tweak.use_aesni = orig_use_aesni; } #endif @@ -12677,7 +12713,7 @@ int wc_AesXtsEncrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz, return ret; } -/* Same process as encryption but Aes key is AES_DECRYPTION type. +/* Same process as encryption but use aes_decrypt key. * * xaes AES keys to use for block encrypt/decrypt * out output buffer to hold plain text @@ -12693,7 +12729,7 @@ static int AesXtsDecrypt_sw(XtsAes* xaes, byte* out, const byte* in, word32 sz, { int ret = 0; word32 blocks = (sz / AES_BLOCK_SIZE); - Aes *aes = &xaes->aes; + Aes *aes = &xaes->aes_decrypt; Aes *tweak = &xaes->tweak; word32 j; byte carry = 0; @@ -12826,6 +12862,11 @@ int wc_AesXtsDecrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz, return BAD_FUNC_ARG; } + if (xaes->aes_decrypt.keylen == 0) { + WOLFSSL_MSG("wc_AesXtsDecrypt called with unset decryption key."); + return BAD_FUNC_ARG; + } + if (iSz < AES_BLOCK_SIZE) { return BAD_FUNC_ARG; } @@ -12838,25 +12879,29 @@ int wc_AesXtsDecrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz, { #ifdef WOLFSSL_AESNI #ifdef WC_AES_C_DYNAMIC_FALLBACK - int orig_use_aesni = xaes->aes.use_aesni; + int orig_use_aesni = xaes->aes_decrypt.use_aesni; #endif - if (xaes->aes.use_aesni && (SAVE_VECTOR_REGISTERS2() != 0)) { - xaes->aes.use_aesni = 0; + if (xaes->aes_decrypt.use_aesni && ((ret = SAVE_VECTOR_REGISTERS2() != 0))) { +#ifdef WC_AES_C_DYNAMIC_FALLBACK + xaes->aes_decrypt.use_aesni = 0; xaes->tweak.use_aesni = 0; +#else + return ret; +#endif } - if (xaes->aes.use_aesni) { + if (xaes->aes_decrypt.use_aesni) { #if defined(HAVE_INTEL_AVX1) if (IS_INTEL_AVX1(intel_flags)) { - AES_XTS_decrypt_avx1(in, out, sz, i, (const byte*)xaes->aes.key, - (const byte*)xaes->tweak.key, (int)xaes->aes.rounds); + AES_XTS_decrypt_avx1(in, out, sz, i, (const byte*)xaes->aes_decrypt.key, + (const byte*)xaes->tweak.key, (int)xaes->aes_decrypt.rounds); ret = 0; } else #endif { - AES_XTS_decrypt_aesni(in, out, sz, i, (const byte*)xaes->aes.key, - (const byte*)xaes->tweak.key, (int)xaes->aes.rounds); + AES_XTS_decrypt_aesni(in, out, sz, i, (const byte*)xaes->aes_decrypt.key, + (const byte*)xaes->tweak.key, (int)xaes->aes_decrypt.rounds); ret = 0; } } @@ -12867,11 +12912,11 @@ int wc_AesXtsDecrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz, } #ifdef WOLFSSL_AESNI - if (xaes->aes.use_aesni) + if (xaes->aes_decrypt.use_aesni) RESTORE_VECTOR_REGISTERS(); #ifdef WC_AES_C_DYNAMIC_FALLBACK else if (orig_use_aesni) { - xaes->aes.use_aesni = orig_use_aesni; + xaes->aes_decrypt.use_aesni = orig_use_aesni; xaes->tweak.use_aesni = orig_use_aesni; } #endif diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index dcd3320dee..cb24bd36d6 100644 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -179,6 +179,7 @@ enum { AES_ENC_TYPE = WC_CIPHER_AES, /* cipher unique type */ AES_ENCRYPTION = 0, AES_DECRYPTION = 1, + AES_ENCRYPTION_AND_DECRYPTION = 2, AES_BLOCK_SIZE = 16, @@ -398,7 +399,8 @@ struct Aes { #ifdef WOLFSSL_AES_XTS typedef struct XtsAes { - Aes aes; + Aes aes_encrypt; + Aes aes_decrypt; Aes tweak; } XtsAes; #endif From 947528ee16c7902efa1e7a3cb77dad9fb1c1db99 Mon Sep 17 00:00:00 2001 From: jordan Date: Fri, 26 Jan 2024 17:07:43 -0600 Subject: [PATCH 15/63] Fix ext_xmss SigsLeft. --- wolfcrypt/src/ext_xmss.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/wolfcrypt/src/ext_xmss.c b/wolfcrypt/src/ext_xmss.c index 4a97d09a85..c08db07239 100644 --- a/wolfcrypt/src/ext_xmss.c +++ b/wolfcrypt/src/ext_xmss.c @@ -763,7 +763,7 @@ int wc_XmssKey_Sign(XmssKey* key, byte * sig, word32 * sigLen, const byte * msg, */ int wc_XmssKey_SigsLeft(XmssKey* key) { - int ret; + int ret = 0; /* Validate parameter. */ if (key == NULL) { @@ -785,13 +785,30 @@ int wc_XmssKey_SigsLeft(XmssKey* key) ret = 0; } else { - xmss_params* params = &key->params; - unsigned long long idx; + /* The following assumes core_fast implementation is used + * from patched xmss-reference. */ + const unsigned char* sk = (key->sk + XMSS_OID_LEN); + const xmss_params* params = &key->params; + unsigned long long idx = 0; + + if (key->is_xmssmt) { + for (uint64_t i = 0; i < params->index_bytes; i++) { + idx |= ((unsigned long long)sk[i]) + << 8 * (params->index_bytes - 1 - i); + } + } + else { + idx = ((unsigned long)sk[0] << 24) | + ((unsigned long)sk[1] << 16) | + ((unsigned long)sk[2] << 8) | sk[3]; + } - idx = (unsigned long)bytes_to_ull(key->sk, params->index_bytes); ret = idx < ((1ULL << params->full_height) - 1); } + /* Force zero the secret key from memory always. */ + ForceZero(key->sk, key->sk_len); + return ret; } #endif /* ifndef WOLFSSL_XMSS_VERIFY_ONLY*/ From b1e5d0f9bbce2a1528a9eb311510386bbf1add05 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Fri, 26 Jan 2024 20:01:19 -0600 Subject: [PATCH 16/63] linuxkm: completion and stabilization of LKCAPI integration for AES-CBC, AES-CFB, AES-GCM, and AES-XTS: linuxkm/lkcapi_glue.c (added in earlier commit): implement linuxkm_lkcapi_register() and linuxkm_lkcapi_unregister() with idempotency. add AES-XTS algorithm glue and self-test implementations. add per-algorithm gating: LINUXKM_LKCAPI_REGISTER_AESCBC, _AESCFB, _AESGCM, and _AESXTS. carry forward philljj's implementations for AES-CBC, AES-CFB, and AES-GCM, with various cleanups. linuxkm/module_hooks.c: print the "wolfCrypt container hashes" message only if DEBUG_LINUXKM_PIE_SUPPORT is set. render the FIPS version for the self-test success message using the HAVE_FIPS_VERSION* macros. add a "skipping full wolfcrypt_test() ..." message for --disable-crypttests builds. add CONFIG_FORTIFY_SOURCE gates. configure.ac: add support for --enable-linuxkm-lkcapi-register; add AES-XTS to output config summary; rename --enable-xts to --enable-aesxts (retaining old option for backward compatibility). linuxkm/linuxkm_wc_port.h: add support for CONFIG_FORTIFY_SOURCE. linuxkm/linuxkm_memory.c: fix retvals in save_vector_registers_x86() (wc-style MEMORY_E, not sys-style ENOMEM). add __my_fortify_panic() implementation. linuxkm/Kbuild: for ENABLED_LINUXKM_PIE in rename-pie-text-and-data-sections recipe, create an .rodata.wolfcrypt section. linuxkm/include.am: add linuxkm/lkcapi_glue.c to EXTRA_DIST. wolfcrypt/test/test.c: when defined(HAVE_FIPS_VERSION), inhibit a test clause in aes_xts_128_test() disallowed by FIPS ("FIPS AES-XTS main and tweak keys must differ"). fix out-of-order user message in ecc_test(). --- configure.ac | 51 +- linuxkm/Kbuild | 4 +- linuxkm/include.am | 3 +- linuxkm/linuxkm_memory.c | 12 +- linuxkm/linuxkm_wc_port.h | 91 ++- linuxkm/lkcapi_glue.c | 149 +++-- linuxkm/module_hooks.c | 1241 ++----------------------------------- wolfcrypt/src/aes.c | 39 +- wolfcrypt/src/memory.c | 37 +- wolfcrypt/test/test.c | 72 ++- 10 files changed, 380 insertions(+), 1319 deletions(-) diff --git a/configure.ac b/configure.ac index 1da02cc48e..c00818b7c9 100644 --- a/configure.ac +++ b/configure.ac @@ -745,7 +745,7 @@ then test "$enable_psk" = "" && enable_psk=yes test "$enable_cmac" = "" && enable_cmac=yes test "$enable_siphash" = "" && enable_siphash=yes - test "$enable_xts" = "" && enable_xts=yes + test "$enable_aesxts" = "" && enable_aesxts=yes test "$enable_ocsp" = "" && enable_ocsp=yes test "$enable_ocspstapling" = "" && test "$enable_ocsp" != "no" && enable_ocspstapling=yes test "$enable_ocspstapling2" = "" && test "$enable_ocsp" != "no" && enable_ocspstapling2=yes @@ -933,7 +933,7 @@ then test "$enable_psk" = "" && enable_psk=yes test "$enable_cmac" = "" && enable_cmac=yes test "$enable_siphash" = "" && enable_siphash=yes - test "$enable_xts" = "" && enable_xts=yes + test "$enable_aesxts" = "" && enable_aesxts=yes test "$enable_ocsp" = "" && enable_ocsp=yes test "$enable_ocspstapling" = "" && test "$enable_ocsp" != "no" && enable_ocspstapling=yes test "$enable_ocspstapling2" = "" && test "$enable_ocsp" != "no" && enable_ocspstapling2=yes @@ -4836,17 +4836,23 @@ AS_IF([test "x$ENABLED_CMAC" = "xyes"], # AES-XTS +AC_ARG_ENABLE([aesxts], + [AS_HELP_STRING([--enable-aesxts],[Enable AES XTS (default: disabled)])], + [ ENABLED_AESXTS=$enableval ], + [ ENABLED_AESXTS=no ] + ) + +# legacy old option name, for compatibility: AC_ARG_ENABLE([xts], - [AS_HELP_STRING([--enable-xts],[Enable XTS (default: disabled)])], - [ ENABLED_XTS=$enableval ], - [ ENABLED_XTS=no ] + [AS_HELP_STRING([--enable-xts],[Please use --enable-aesxts])], + [ ENABLED_AESXTS=$enableval ] ) -AS_IF([test "x$ENABLED_XTS" = "xyes"], +AS_IF([test "x$ENABLED_AESXTS" = "xyes"], [AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_AES_XTS -DWOLFSSL_AES_DIRECT"]) -AS_IF([test "x$ENABLED_XTS" = "xyes" && test "x$ENABLED_INTELASM" = "xyes"], +AS_IF([test "x$ENABLED_AESXTS" = "xyes" && test "x$ENABLED_INTELASM" = "xyes"], [AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_AES_XTS"]) -AS_IF([test "x$ENABLED_XTS" = "xyes" && test "x$ENABLED_AESNI" = "xyes"], +AS_IF([test "x$ENABLED_AESXTS" = "xyes" && test "x$ENABLED_AESNI" = "xyes"], [AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_AES_XTS"]) # Web Server Build @@ -8028,6 +8034,32 @@ if test -n "$MPI_MAX_KEY_BITS" -o -n "$WITH_MAX_ECC_BITS"; then fi fi +AC_ARG_ENABLE([linuxkm-lkcapi-register], + [AS_HELP_STRING([--enable-linuxkm-lkcapi-register],[Register wolfCrypt implementations with the Linux Kernel Crypto API backplane. Possible values are "none", "all", "cbc(aes)", "cfb(aes)", "gcm(aes)", and "xts(aes)", or a comma-separate combination. (default: none)])], + [ENABLED_LINUXKM_LKCAPI_REGISTER=$enableval], + [ENABLED_LINUXKM_LKCAPI_REGISTER=none] + ) +if test "$ENABLED_LINUXKM_LKCAPI_REGISTER" != "none" +then + AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_REGISTER" + for lkcapi_alg in $(echo "$ENABLED_LINUXKM_LKCAPI_REGISTER" | tr ',' ' ') + do + case "$lkcapi_alg" in + all) AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_REGISTER_ALL" ;; + 'cbc(aes)') test "$ENABLED_AESCBC" != "no" || AC_MSG_ERROR([linuxkm-lkcapi-register ${lkcapi_alg}: AES-CBC implementation not enabled.]) + AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_REGISTER_AESCBC" ;; + 'cfb(aes)') test "$ENABLED_AESCFB" != "no" || AC_MSG_ERROR([linuxkm-lkcapi-register ${lkcapi_alg}: AES-CFB implementation not enabled.]) + AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_REGISTER_AESCFB" ;; + 'gcm(aes)') test "$ENABLED_AESGCM" != "no" || AC_MSG_ERROR([linuxkm-lkcapi-register ${lkcapi_alg}: AES-GCM implementation not enabled.]) + test "$ENABLED_AESGCM_STREAM" != "no" || AC_MSG_ERROR([linuxkm-lkcapi-register ${lkcapi_alg}: --enable-aesgcm-stream is required for LKCAPI.]) + AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_REGISTER_AESGCM" ;; + 'xts(aes)') test "$ENABLED_AESXTS" != "no" || AC_MSG_ERROR([linuxkm-lkcapi-register ${lkcapi_alg}: AES-XTS implementation not enabled.]) + AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_REGISTER_AESXTS" ;; + *) AC_MSG_ERROR([Unsupported LKCAPI algorithm "$lkcapi_alg".]) ;; + esac + done +fi + # Library Suffix LIBSUFFIX="" AC_ARG_WITH([libsuffix], @@ -8958,7 +8990,7 @@ AM_CONDITIONAL([BUILD_SNIFFER], [ test "x$ENABLED_SNIFFER" = "xyes" || test " AM_CONDITIONAL([BUILD_SNIFFTEST],[ test "x$ENABLED_SNIFFTEST" = "xyes"]) AM_CONDITIONAL([BUILD_AESGCM],[test "x$ENABLED_AESGCM" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_AESCCM],[test "x$ENABLED_AESCCM" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) -AM_CONDITIONAL([BUILD_XTS],[test "x$ENABLED_XTS" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_AESXTS],[test "x$ENABLED_AESXTS" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_ARMASM],[test "x$ENABLED_ARMASM" = "xyes"]) AM_CONDITIONAL([BUILD_ARMASM_INLINE],[test "x$ENABLED_ARMASM_INLINE" = "xyes"]) AM_CONDITIONAL([BUILD_ARMASM_CRYPTO],[test "x$ENABLED_ARMASM_CRYPTO" = "xyes"]) @@ -9397,6 +9429,7 @@ echo " * AES-CCM: $ENABLED_AESCCM" echo " * AES-CTR: $ENABLED_AESCTR" echo " * AES-CFB: $ENABLED_AESCFB" echo " * AES-OFB: $ENABLED_AESOFB" +echo " * AES-XTS: $ENABLED_AESXTS" echo " * AES-SIV: $ENABLED_AESSIV" echo " * AES-EAX: $ENABLED_AESEAX" echo " * AES Bitspliced: $ENABLED_AESBS" diff --git a/linuxkm/Kbuild b/linuxkm/Kbuild index 6eac94d282..4abe731091 100644 --- a/linuxkm/Kbuild +++ b/linuxkm/Kbuild @@ -154,10 +154,10 @@ ifneq "$(quiet)" "silent_" endif @cd "$(obj)" || exit $$?; \ for file in $(WOLFCRYPT_PIE_FILES); do \ - $(OBJCOPY) --rename-section .text=.text.wolfcrypt --rename-section .data=.data.wolfcrypt "$$file" || exit $$?; \ + $(OBJCOPY) --rename-section .text=.text.wolfcrypt --rename-section .data=.data.wolfcrypt --rename-section .rodata=.rodata.wolfcrypt "$$file" || exit $$?; \ done ifneq "$(quiet)" "silent_" - @echo ' wolfCrypt .{text,data} sections containerized to .{text,data}.wolfcrypt' + @echo ' wolfCrypt .{text,data,rodata} sections containerized to .{text,data,rodata}.wolfcrypt' endif $(src)/linuxkm/module_exports.c: rename-pie-text-and-data-sections diff --git a/linuxkm/include.am b/linuxkm/include.am index cec11ad2d3..b89aab40a0 100644 --- a/linuxkm/include.am +++ b/linuxkm/include.am @@ -12,4 +12,5 @@ EXTRA_DIST += m4/ax_linuxkm.m4 \ linuxkm/pie_redirect_table.c \ linuxkm/pie_last.c \ linuxkm/linuxkm_memory.c \ - linuxkm/linuxkm_wc_port.h + linuxkm/linuxkm_wc_port.h \ + linuxkm/lkcapi_glue.c diff --git a/linuxkm/linuxkm_memory.c b/linuxkm/linuxkm_memory.c index 58131606e2..81a7dfab36 100644 --- a/linuxkm/linuxkm_memory.c +++ b/linuxkm/linuxkm_memory.c @@ -275,7 +275,7 @@ WARN_UNUSED_RESULT int save_vector_registers_x86(void) { struct wc_thread_fpu_count_ent *pstate = wc_linuxkm_fpu_state_assoc(1); if (pstate == NULL) - return ENOMEM; + return MEMORY_E; /* allow for nested calls */ if (pstate->fpu_state != 0U) { @@ -314,7 +314,7 @@ WARN_UNUSED_RESULT int save_vector_registers_x86(void) if (! warned_fpu_forbidden) pr_err("save_vector_registers_x86 called from IRQ handler.\n"); wc_linuxkm_fpu_state_release(pstate); - return EPERM; + return BAD_STATE_E; } else { #if defined(CONFIG_SMP) && !defined(CONFIG_PREEMPT_COUNT) && \ (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)) && \ @@ -380,3 +380,11 @@ void my__show_free_areas( return; } #endif + +#if defined(__PIE__) && defined(CONFIG_FORTIFY_SOURCE) +/* needed because FORTIFY_SOURCE inline implementations call fortify_panic(). */ +void __my_fortify_panic(const char *name) { + pr_emerg("__my_fortify_panic in %s\n", name); + BUG(); +} +#endif diff --git a/linuxkm/linuxkm_wc_port.h b/linuxkm/linuxkm_wc_port.h index 97273939c1..255cf52fa1 100644 --- a/linuxkm/linuxkm_wc_port.h +++ b/linuxkm/linuxkm_wc_port.h @@ -119,8 +119,87 @@ #include #include #include + + #ifdef CONFIG_FORTIFY_SOURCE + #ifdef __PIE__ + /* the inline definitions in fortify-string.h use non-inline + * fortify_panic(). + */ + extern void __my_fortify_panic(const char *name) __noreturn __cold; + #define fortify_panic __my_fortify_panic + #endif + + /* the _FORTIFY_SOURCE macros and implementations for several string + * functions are incompatible with libwolfssl, so just reimplement with + * inlines and remap with macros. + */ + + #define __ARCH_STRLEN_NO_REDIRECT + #define __ARCH_MEMCPY_NO_REDIRECT + #define __ARCH_MEMSET_NO_REDIRECT + #define __ARCH_MEMMOVE_NO_REDIRECT + + /* the inline definitions in fortify-string.h use non-inline + * strlen(). + */ + static inline size_t strlen(const char *s) { + const char *s_start = s; + while (*s) + ++s; + return (size_t)s - (size_t)s_start; + } + + #include + + #undef strlen + #define strlen(s) \ + ((__builtin_constant_p(s) && __builtin_constant_p(*(s))) ? \ + (sizeof(s) - 1) : strlen(s)) + + static inline void *my_memcpy(void *dest, const void *src, size_t n) { + u8 *src_bytes = (u8 *)src, + *dest_bytes = (u8 *)dest, + *endp = src_bytes + n; + while (src_bytes < endp) + *dest_bytes++ = *src_bytes++; + return dest; + } + #undef memcpy + #define memcpy my_memcpy + + static inline void *my_memset(void *dest, int c, size_t n) { + u8 *dest_bytes = (u8 *)dest, *endp = dest_bytes + n; + while (dest_bytes < endp) + *dest_bytes++ = (u8)c; + return dest; + } + #undef memset + #define memset my_memset + + static inline void *my_memmove(void *dest, const void *src, size_t n) { + u8 *src_bytes = (u8 *)src, *dest_bytes = (u8 *)dest; + if (src_bytes < dest_bytes) { + u8 *startp = src_bytes; + src_bytes += n - 1; + dest_bytes += n - 1; + while (src_bytes >= startp) + *dest_bytes-- = *src_bytes--; + } else if (src_bytes > dest_bytes) { + u8 *endp = src_bytes + n; + while (src_bytes < endp) + *dest_bytes++ = *src_bytes++; + } + return dest; + } + #undef memmove + #define memmove my_memmove + + #endif /* CONFIG_FORTIFY_SOURCE */ + #include #include + #include + #ifdef __PIE__ /* without this, mm.h brings in static, but not inline, pmd_to_page(), * with direct references to global vmem variables. @@ -146,7 +225,7 @@ #include #include - #ifdef LINUXKM_REGISTER_ALG + #ifdef LINUXKM_LKCAPI_REGISTER #include #include #include @@ -303,6 +382,11 @@ #else typeof(printk) *printk; #endif + +#ifdef CONFIG_FORTIFY_SOURCE + typeof(__warn_printk) *__warn_printk; +#endif + typeof(snprintf) *snprintf; const unsigned char *_ctype; @@ -446,6 +530,11 @@ #else #define printk (wolfssl_linuxkm_get_pie_redirect_table()->printk) #endif + + #ifdef CONFIG_FORTIFY_SOURCE + #define __warn_printk (wolfssl_linuxkm_get_pie_redirect_table()->__warn_printk) + #endif + #define snprintf (wolfssl_linuxkm_get_pie_redirect_table()->snprintf) #define _ctype (wolfssl_linuxkm_get_pie_redirect_table()->_ctype) diff --git a/linuxkm/lkcapi_glue.c b/linuxkm/lkcapi_glue.c index 170bdbaf35..2ec81eedbe 100644 --- a/linuxkm/lkcapi_glue.c +++ b/linuxkm/lkcapi_glue.c @@ -46,10 +46,31 @@ #define WOLFKM_AESCFB_NAME "cfb(aes)" #define WOLFKM_AESGCM_NAME "gcm(aes)" #define WOLFKM_AESXTS_NAME "xts(aes)" -#define WOLFKM_AESCBC_DRIVER "cbc-aes-wolfcrypt" -#define WOLFKM_AESCFB_DRIVER "cfb-aes-wolfcrypt" -#define WOLFKM_AESGCM_DRIVER "gcm-aes-wolfcrypt" -#define WOLFKM_AESXTS_DRIVER "xts-aes-wolfcrypt" + +#ifdef WOLFSSL_AESNI + #define WOLFKM_DRIVER_ISA_EXT "-aesni" +#else + #define WOLFKM_DRIVER_ISA_EXT "" +#endif + +#ifdef HAVE_FIPS_VERSION + #if HAVE_FIPS_VERSION >= 5 + #define WOLFKM_DRIVER_FIPS "-fips-140-3" + #elif HAVE_FIPS_VERSION == 2 + #define WOLFKM_DRIVER_FIPS "-fips-140-2" + #else + #define WOLFKM_DRIVER_FIPS "-fips-140" + #endif +#else + #define WOLFKM_DRIVER_FIPS "" +#endif + +#define WOLFKM_DRIVER_SUFFIX WOLFKM_DRIVER_ISA_EXT WOLFKM_DRIVER_FIPS "-wolfcrypt" + +#define WOLFKM_AESCBC_DRIVER ("cbc-aes" WOLFKM_DRIVER_SUFFIX) +#define WOLFKM_AESCFB_DRIVER ("cfb-aes" WOLFKM_DRIVER_SUFFIX) +#define WOLFKM_AESGCM_DRIVER ("gcm-aes" WOLFKM_DRIVER_SUFFIX) +#define WOLFKM_AESXTS_DRIVER ("xts-aes" WOLFKM_DRIVER_SUFFIX) #if defined(HAVE_AES_CBC) && \ (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESCBC)) @@ -1509,7 +1530,7 @@ static int aes_xts_128_test(void) ret = wc_AesXtsEncrypt(aes, buf, p2, sizeof(p2), i2, sizeof(i2)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -1520,7 +1541,7 @@ static int aes_xts_128_test(void) WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(SYSLIB_FAILED_E); ret = wc_AesXtsEncrypt(aes, buf, p2, sizeof(p2), i2, sizeof(i2)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(0); if (ret != 0) @@ -1536,7 +1557,7 @@ static int aes_xts_128_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsEncrypt(aes, buf, p1, sizeof(p1), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -1547,7 +1568,7 @@ static int aes_xts_128_test(void) WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(SYSLIB_FAILED_E); ret = wc_AesXtsEncrypt(aes, buf, p1, sizeof(p1), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(0); if (ret != 0) @@ -1560,7 +1581,7 @@ static int aes_xts_128_test(void) XMEMSET(cipher, 0, sizeof(cipher)); ret = wc_AesXtsEncrypt(aes, cipher, pp, sizeof(pp), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -1572,7 +1593,7 @@ static int aes_xts_128_test(void) XMEMSET(cipher, 0, sizeof(cipher)); ret = wc_AesXtsEncrypt(aes, cipher, pp, sizeof(pp), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(0); if (ret != 0) @@ -1588,7 +1609,7 @@ static int aes_xts_128_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecrypt(aes, buf, cipher, sizeof(pp), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -1600,7 +1621,7 @@ static int aes_xts_128_test(void) XMEMSET(buf, 0, sizeof(buf)); ret = wc_AesXtsDecrypt(aes, buf, cipher, sizeof(pp), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(0); if (ret != 0) @@ -1613,7 +1634,7 @@ static int aes_xts_128_test(void) XMEMSET(buf, 0, sizeof(buf)); ret = wc_AesXtsDecrypt(aes, buf, c1, sizeof(c1), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -1625,7 +1646,7 @@ static int aes_xts_128_test(void) XMEMSET(buf, 0, sizeof(buf)); ret = wc_AesXtsDecrypt(aes, buf, c1, sizeof(c1), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(0); if (ret != 0) @@ -1638,7 +1659,7 @@ static int aes_xts_128_test(void) XMEMSET(buf, 0, sizeof(buf)); ret = wc_AesXtsDecrypt(aes, buf, c2, sizeof(c2), i2, sizeof(i2)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -1652,7 +1673,7 @@ static int aes_xts_128_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecrypt(aes, buf, c2, sizeof(c2), i2, sizeof(i2)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -1669,7 +1690,7 @@ static int aes_xts_128_test(void) ret = wc_AesXtsEncrypt(aes, buf, buf, sizeof(p3), i3, sizeof(i3)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -1681,7 +1702,7 @@ static int aes_xts_128_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecrypt(aes, buf, buf, sizeof(c3), i3, sizeof(i3)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -1717,7 +1738,7 @@ static int aes_xts_128_test(void) ret = wc_AesXtsEncrypt(aes, large_input, large_input, j, i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -1728,7 +1749,7 @@ static int aes_xts_128_test(void) ret = wc_AesXtsDecrypt(aes, large_input, large_input, j, i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -2062,7 +2083,7 @@ static int aes_xts_256_test(void) ret = wc_AesXtsEncrypt(aes, buf, p2, sizeof(p2), i2, sizeof(i2)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -2075,7 +2096,7 @@ static int aes_xts_256_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsEncrypt(aes, buf, p1, sizeof(p1), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -2086,7 +2107,7 @@ static int aes_xts_256_test(void) XMEMSET(cipher, 0, sizeof(cipher)); ret = wc_AesXtsEncrypt(aes, cipher, pp, sizeof(pp), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -2098,7 +2119,7 @@ static int aes_xts_256_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecrypt(aes, buf, cipher, sizeof(pp), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -2109,7 +2130,7 @@ static int aes_xts_256_test(void) XMEMSET(buf, 0, sizeof(buf)); ret = wc_AesXtsDecrypt(aes, buf, c1, sizeof(c1), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -2122,7 +2143,7 @@ static int aes_xts_256_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecrypt(aes, buf, c2, sizeof(c2), i2, sizeof(i2)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -2361,15 +2382,18 @@ static int linuxkm_lkcapi_register(void) int ret = 0; #define REGISTER_ALG(alg, installer, tester) do { \ - if (alg ## _loaded) {\ - pr_err("ERROR: %s is already registered.\n", (alg).base.cra_driver_name); \ + if (alg ## _loaded) { \ + pr_err("ERROR: %s is already registered.\n", \ + (alg).base.cra_driver_name); \ return -EEXIST; \ } \ \ ret = (installer)(&(alg)); \ \ if (ret) { \ - pr_err("ERROR: " #installer " for %s failed with return code %d.\n", (alg).base.cra_driver_name, ret); \ + pr_err("ERROR: " #installer " for %s failed " \ + "with return code %d.\n", \ + (alg).base.cra_driver_name, ret); \ return ret; \ } \ \ @@ -2378,33 +2402,43 @@ static int linuxkm_lkcapi_register(void) ret = (tester()); \ \ if (ret) { \ - pr_err("ERROR: self-test for %s failed with return code %d.\n", (alg).base.cra_driver_name, ret); \ + pr_err("ERROR: self-test for %s failed " \ + "with return code %d.\n", \ + (alg).base.cra_driver_name, ret); \ return ret; \ } \ - pr_info("%s self-test OK -- registered for %s with priority %d.\n", (alg).base.cra_driver_name, (alg).base.cra_name, (alg).base.cra_priority); \ + pr_info("%s self-test OK -- " \ + "registered for %s with priority %d.\n", \ + (alg).base.cra_driver_name, \ + (alg).base.cra_name, \ + (alg).base.cra_priority); \ } while (0) #if defined(HAVE_AES_CBC) && \ - (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESCBC)) + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || \ + defined(LINUXKM_LKCAPI_REGISTER_AESCBC)) REGISTER_ALG(cbcAesAlg, crypto_register_skcipher, linuxkm_test_aescbc); #endif #if defined(WOLFSSL_AES_CFB) && \ - (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESCFB)) + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || \ + defined(LINUXKM_LKCAPI_REGISTER_AESCFB)) REGISTER_ALG(cfbAesAlg, crypto_register_skcipher, linuxkm_test_aescfb); #endif #if defined(HAVE_AESGCM) && \ - (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESGCM)) && \ + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || \ + defined(LINUXKM_LKCAPI_REGISTER_AESGCM)) && \ (! (defined(WOLFSSL_AESNI) && defined(WC_AES_C_DYNAMIC_FALLBACK))) REGISTER_ALG(gcmAesAead, crypto_register_aead, linuxkm_test_aesgcm); #endif #if defined(WOLFSSL_AES_XTS) && \ - (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESXTS)) + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || \ + defined(LINUXKM_LKCAPI_REGISTER_AESXTS)) REGISTER_ALG(xtsAesAlg, crypto_register_skcipher, linuxkm_test_aesxts); #endif @@ -2416,33 +2450,38 @@ static int linuxkm_lkcapi_register(void) static void linuxkm_lkcapi_unregister(void) { +#define UNREGISTER_ALG(alg, uninstaller) do { \ + if (alg ## _loaded) { \ + (uninstaller)(&(alg)); \ + alg ## _loaded = 0; \ + } \ + } while (0) + #if defined(HAVE_AES_CBC) && \ - (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESCBC)) - if (cbcAesAlg_loaded) { - crypto_unregister_skcipher(&cbcAesAlg); - cbcAesAlg_loaded = 0; - } + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || \ + defined(LINUXKM_LKCAPI_REGISTER_AESCBC)) + + UNREGISTER_ALG(cbcAesAlg, crypto_unregister_skcipher); #endif #if defined(WOLFSSL_AES_CFB) && \ - (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESCFB)) - if (cfbAesAlg_loaded) { - crypto_unregister_skcipher(&cfbAesAlg); - cfbAesAlg_loaded = 0; - } + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || \ + defined(LINUXKM_LKCAPI_REGISTER_AESCFB)) + + UNREGISTER_ALG(cfbAesAlg, crypto_unregister_skcipher); #endif #if defined(HAVE_AESGCM) && \ - (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESGCM)) && \ + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || \ + defined(LINUXKM_LKCAPI_REGISTER_AESGCM)) && \ (! (defined(WOLFSSL_AESNI) && defined(WC_AES_C_DYNAMIC_FALLBACK))) - if (gcmAesAead_loaded) { - crypto_unregister_aead(&gcmAesAead); - gcmAesAead_loaded = 0; - } + + UNREGISTER_ALG(gcmAesAead, crypto_unregister_aead); #endif #if defined(WOLFSSL_AES_XTS) && \ - (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESXTS)) - if (xtsAesAlg_loaded) { - crypto_unregister_skcipher(&xtsAesAlg); - xtsAesAlg_loaded = 0; - } + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || \ + defined(LINUXKM_LKCAPI_REGISTER_AESXTS)) + + UNREGISTER_ALG(xtsAesAlg, crypto_unregister_skcipher); #endif + +#undef UNREGISTER_ALG } diff --git a/linuxkm/module_hooks.c b/linuxkm/module_hooks.c index 5e8f7caaaf..6d6ff6c8cf 100644 --- a/linuxkm/module_hooks.c +++ b/linuxkm/module_hooks.c @@ -47,7 +47,6 @@ #endif #ifndef NO_CRYPT_TEST #include - #include #endif static int libwolfssl_cleanup(void) { @@ -71,6 +70,8 @@ static int libwolfssl_cleanup(void) { #ifdef HAVE_LINUXKM_PIE_SUPPORT +#ifdef DEBUG_LINUXKM_PIE_SUPPORT + extern int wolfCrypt_PIE_first_function(void); extern int wolfCrypt_PIE_last_function(void); extern const unsigned int wolfCrypt_PIE_rodata_start[]; @@ -90,6 +91,8 @@ static unsigned int hash_span(char *start, char *end) { return sum; } +#endif /* DEBUG_LINUXKM_PIE_SUPPORT */ + #ifdef USE_WOLFSSL_LINUXKM_PIE_REDIRECT_TABLE extern struct wolfssl_linuxkm_pie_redirect_table wolfssl_linuxkm_pie_redirect_table; static int set_up_wolfssl_linuxkm_pie_redirect_table(void); @@ -126,34 +129,10 @@ static int updateFipsHash(void); #include "wolfcrypt/benchmark/benchmark.c" #endif /* WOLFSSL_LINUXKM_BENCHMARKS */ -#ifdef LINUXKM_REGISTER_ALG -#if defined(NO_AES) - #error LINUXKM_REGISTER_ALG requires AES. -#endif - -#if !defined(HAVE_AESGCM) && !defined(HAVe_AES_CBC) && !defined(WOLFSSL_AES_CFB) - #error LINUXKM_REGISTER_ALG requires AES-CBC, CFB, or GCM. +#ifdef LINUXKM_LKCAPI_REGISTER + #include "linuxkm/lkcapi_glue.c" #endif -#if defined(HAVE_AESGCM) && !defined(WOLFSSL_AESGCM_STREAM) - #error LINUXKM_REGISTER_ALG requires AESGCM_STREAM. -#endif - -#define WOLFKM_CBC_NAME "cbc(aes)" -#define WOLFKM_CFB_NAME "cfb(aes)" -#define WOLFKM_GCM_NAME "gcm(aes)" -#define WOLFKM_CBC_DRIVER "cbc-aes-wolfcrypt" -#define WOLFKM_CFB_DRIVER "cfb-aes-wolfcrypt" -#define WOLFKM_GCM_DRIVER "gcm-aes-wolfcrypt" -#define WOLFKM_ALG_PRIORITY (100) -static int linuxkm_register_alg(void); -static void linuxkm_unregister_alg(void); -static int linuxkm_test_alg(void); -static int linuxkm_test_cbc(void); -static int linuxkm_test_cfb(void); -static int linuxkm_test_gcm(void); -#endif /* endif LINUXKM_REGISTER_ALG */ - #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0) static int __init wolfssl_init(void) #else @@ -180,7 +159,7 @@ static int wolfssl_init(void) return ret; #endif -#ifdef HAVE_LINUXKM_PIE_SUPPORT +#if defined(HAVE_LINUXKM_PIE_SUPPORT) && defined(DEBUG_LINUXKM_PIE_SUPPORT) #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0) /* see linux commit ac3b432839 */ @@ -247,7 +226,7 @@ static int wolfssl_init(void) text_hash, pie_text_end-pie_text_start, rodata_hash, pie_rodata_end-pie_rodata_start); } -#endif /* HAVE_LINUXKM_PIE_SUPPORT */ +#endif /* HAVE_LINUXKM_PIE_SUPPORT && DEBUG_LINUXKM_PIE_SUPPORT */ #ifdef HAVE_FIPS ret = wolfCrypt_SetCb_fips(lkmFipsCb); @@ -267,19 +246,31 @@ static int wolfssl_init(void) return -ECANCELED; } - pr_info("wolfCrypt FIPS [" - -#if defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION == 3) - "ready" -#elif defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION == 2) \ - && defined(WOLFCRYPT_FIPS_RAND) - "140-2 rand" -#elif defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION == 2) - "140-2" + pr_info("FIPS 140-3 wolfCrypt-fips v%d.%d.%d%s%s startup self-test succeeded.\n", +#ifdef HAVE_FIPS_VERSION_MAJOR + HAVE_FIPS_VERSION_MAJOR, +#else + HAVE_FIPS_VERSION, +#endif +#ifdef HAVE_FIPS_VERSION_MINOR + HAVE_FIPS_VERSION_MINOR, +#else + 0, +#endif +#ifdef HAVE_FIPS_VERSION_PATCH + HAVE_FIPS_VERSION_PATCH, #else - "140" + 0, #endif - "] POST succeeded.\n"); +#ifdef HAVE_FIPS_VERSION_PORT + "-", + HAVE_FIPS_VERSION_PORT +#else + "", + "" +#endif + ); + #endif /* HAVE_FIPS */ #ifdef WC_RNG_SEED_CB @@ -315,25 +306,17 @@ static int wolfssl_init(void) return -ECANCELED; } pr_info("wolfCrypt self-test passed.\n"); +#else + pr_info("skipping full wolfcrypt_test() (configure with --enable-crypttests to enable).\n"); #endif -#if defined(LINUXKM_REGISTER_ALG) && !defined(NO_AES) - ret = linuxkm_register_alg(); - - if (ret) { - pr_err("linuxkm_register_alg failed with return code %d.\n", ret); - linuxkm_unregister_alg(); - (void)libwolfssl_cleanup(); - msleep(10); - return -ECANCELED; - } - - ret = linuxkm_test_alg(); +#ifdef LINUXKM_LKCAPI_REGISTER + ret = linuxkm_lkcapi_register(); if (ret) { - pr_err("linuxkm_test_alg failed with return code %d.\n", ret); + pr_err("linuxkm_lkcapi_register() failed with return code %d.\n", ret); + linuxkm_lkcapi_unregister(); (void)libwolfssl_cleanup(); - linuxkm_unregister_alg(); msleep(10); return -ECANCELED; } @@ -376,11 +359,12 @@ static void __exit wolfssl_exit(void) static void wolfssl_exit(void) #endif { +#ifdef LINUXKM_LKCAPI_REGISTER + linuxkm_lkcapi_unregister(); +#endif + (void)libwolfssl_cleanup(); -#if defined(LINUXKM_REGISTER_ALG) && !defined(NO_AES) - linuxkm_unregister_alg(); -#endif return; } @@ -428,6 +412,7 @@ static int set_up_wolfssl_linuxkm_pie_redirect_table(void) { #ifndef __ARCH_MEMCMP_NO_REDIRECT wolfssl_linuxkm_pie_redirect_table.memcmp = memcmp; #endif +#ifndef CONFIG_FORTIFY_SOURCE #ifndef __ARCH_MEMCPY_NO_REDIRECT wolfssl_linuxkm_pie_redirect_table.memcpy = memcpy; #endif @@ -437,6 +422,7 @@ static int set_up_wolfssl_linuxkm_pie_redirect_table(void) { #ifndef __ARCH_MEMMOVE_NO_REDIRECT wolfssl_linuxkm_pie_redirect_table.memmove = memmove; #endif +#endif /* !CONFIG_FORTIFY_SOURCE */ #ifndef __ARCH_STRCMP_NO_REDIRECT wolfssl_linuxkm_pie_redirect_table.strcmp = strcmp; #endif @@ -468,6 +454,11 @@ static int set_up_wolfssl_linuxkm_pie_redirect_table(void) { #else wolfssl_linuxkm_pie_redirect_table.printk = printk; #endif + +#ifdef CONFIG_FORTIFY_SOURCE + wolfssl_linuxkm_pie_redirect_table.__warn_printk = __warn_printk; +#endif + wolfssl_linuxkm_pie_redirect_table.snprintf = snprintf; wolfssl_linuxkm_pie_redirect_table._ctype = _ctype; @@ -573,7 +564,8 @@ static int set_up_wolfssl_linuxkm_pie_redirect_table(void) { i < (unsigned long *)&wolfssl_linuxkm_pie_redirect_table._last_slot; ++i) if (*i == 0) { - pr_err("wolfCrypt container redirect table initialization was incomplete.\n"); + pr_err("wolfCrypt container redirect table initialization was incomplete [%lu].\n", + i - (unsigned long *)&wolfssl_linuxkm_pie_redirect_table); return -EFAULT; } } @@ -792,1136 +784,3 @@ static int updateFipsHash(void) } #endif /* WOLFCRYPT_FIPS_CORE_DYNAMIC_HASH_VALUE */ - - -#if defined(LINUXKM_REGISTER_ALG) && !defined(NO_AES) -#include - -PRAGMA_GCC_DIAG_PUSH; -PRAGMA_GCC("GCC diagnostic ignored \"-Wnested-externs\""); -PRAGMA_GCC("GCC diagnostic ignored \"-Wpointer-arith\""); -PRAGMA_GCC("GCC diagnostic ignored \"-Wpointer-sign\""); -PRAGMA_GCC("GCC diagnostic ignored \"-Wbad-function-cast\""); -PRAGMA_GCC("GCC diagnostic ignored \"-Wunused-parameter\""); -#include -#include -#include -#include -PRAGMA_GCC_DIAG_POP; - -/* km_AesX(): wrappers to wolfcrypt wc_AesX functions and - * structures. */ - -#include - -struct km_AesCtx { - Aes aes; - u8 key[AES_MAX_KEY_SIZE / 8]; - unsigned int keylen; -}; - -static inline void km_ForceZero(struct km_AesCtx * ctx) -{ - memzero_explicit(ctx->key, sizeof(ctx->key)); - ctx->keylen = 0; -} - -static int km_AesInitCommon(struct km_AesCtx * ctx, const char * name) -{ - int err = wc_AesInit(&ctx->aes, NULL, INVALID_DEVID); - - if (unlikely(err)) { - pr_err("error: km_AesInitCommon %s failed: %d\n", name, err); - return err; - } - - return 0; -} - -static void km_AesExitCommon(struct km_AesCtx * ctx) -{ - wc_AesFree(&ctx->aes); - km_ForceZero(ctx); -} - -static int km_AesSetKeyCommon(struct km_AesCtx * ctx, const u8 *in_key, - unsigned int key_len, const char * name) -{ - int err = wc_AesSetKey(&ctx->aes, in_key, key_len, NULL, 0); - - if (unlikely(err)) { - pr_err("error: km_AesSetKeyCommon %s failed: %d\n", name, err); - return err; - } - - XMEMCPY(ctx->key, in_key, key_len); - ctx->keylen = key_len; - - return 0; -} - -static int km_AesInit(struct crypto_skcipher *tfm) -{ - struct km_AesCtx * ctx = crypto_skcipher_ctx(tfm); - return km_AesInitCommon(ctx, WOLFKM_CBC_DRIVER); -} - -static void km_AesExit(struct crypto_skcipher *tfm) -{ - struct km_AesCtx * ctx = crypto_skcipher_ctx(tfm); - km_AesExitCommon(ctx); -} - -static int km_AesSetKey(struct crypto_skcipher *tfm, const u8 *in_key, - unsigned int key_len) -{ - struct km_AesCtx * ctx = crypto_skcipher_ctx(tfm); - return km_AesSetKeyCommon(ctx, in_key, key_len, WOLFKM_CBC_DRIVER); -} - -#if defined(HAVE_AES_CBC) -static int km_AesCbcEncrypt(struct skcipher_request *req) -{ - struct crypto_skcipher * tfm = NULL; - struct km_AesCtx * ctx = NULL; - struct skcipher_walk walk; - unsigned int nbytes = 0; - int err = 0; - - tfm = crypto_skcipher_reqtfm(req); - ctx = crypto_skcipher_ctx(tfm); - - err = skcipher_walk_virt(&walk, req, false); - - while ((nbytes = walk.nbytes)) { - err = wc_AesSetKey(&ctx->aes, ctx->key, ctx->keylen, walk.iv, - AES_ENCRYPTION); - - if (unlikely(err)) { - pr_err("wc_AesSetKey failed: %d\n", err); - return err; - } - - err = wc_AesCbcEncrypt(&ctx->aes, walk.dst.virt.addr, - walk.src.virt.addr, nbytes); - - if (unlikely(err)) { - pr_err("wc_AesCbcEncrypt failed %d\n", err); - return err; - } - - err = skcipher_walk_done(&walk, walk.nbytes - nbytes); - } - - return err; -} - -static int km_AesCbcDecrypt(struct skcipher_request *req) -{ - struct crypto_skcipher * tfm = NULL; - struct km_AesCtx * ctx = NULL; - struct skcipher_walk walk; - unsigned int nbytes = 0; - int err = 0; - - tfm = crypto_skcipher_reqtfm(req); - ctx = crypto_skcipher_ctx(tfm); - - err = skcipher_walk_virt(&walk, req, false); - - while ((nbytes = walk.nbytes)) { - err = wc_AesSetKey(&ctx->aes, ctx->key, ctx->keylen, walk.iv, - AES_DECRYPTION); - - if (unlikely(err)) { - pr_err("wc_AesSetKey failed"); - return err; - } - - err = wc_AesCbcDecrypt(&ctx->aes, walk.dst.virt.addr, - walk.src.virt.addr, nbytes); - - if (unlikely(err)) { - pr_err("wc_AesCbcDecrypt failed"); - return err; - } - - err = skcipher_walk_done(&walk, walk.nbytes - nbytes); - } - - return err; -} -#endif /* endif HAVE_AES_CBC */ - -#if defined(WOLFSSL_AES_CFB) -static int km_AesCfbEncrypt(struct skcipher_request *req) -{ - struct crypto_skcipher * tfm = NULL; - struct km_AesCtx * ctx = NULL; - struct skcipher_walk walk; - unsigned int nbytes = 0; - int err = 0; - - tfm = crypto_skcipher_reqtfm(req); - ctx = crypto_skcipher_ctx(tfm); - - err = skcipher_walk_virt(&walk, req, false); - - while ((nbytes = walk.nbytes)) { - err = wc_AesSetKey(&ctx->aes, ctx->key, ctx->keylen, walk.iv, - AES_ENCRYPTION); - - if (unlikely(err)) { - pr_err("wc_AesSetKey failed: %d\n", err); - return err; - } - - err = wc_AesCfbEncrypt(&ctx->aes, walk.dst.virt.addr, - walk.src.virt.addr, nbytes); - - if (unlikely(err)) { - pr_err("wc_AesCfbEncrypt failed %d\n", err); - return err; - } - - err = skcipher_walk_done(&walk, walk.nbytes - nbytes); - } - - return err; -} - -static int km_AesCfbDecrypt(struct skcipher_request *req) -{ - struct crypto_skcipher * tfm = NULL; - struct km_AesCtx * ctx = NULL; - struct skcipher_walk walk; - unsigned int nbytes = 0; - int err = 0; - - tfm = crypto_skcipher_reqtfm(req); - ctx = crypto_skcipher_ctx(tfm); - - err = skcipher_walk_virt(&walk, req, false); - - while ((nbytes = walk.nbytes)) { - err = wc_AesSetKey(&ctx->aes, ctx->key, ctx->keylen, walk.iv, - AES_ENCRYPTION); - - if (unlikely(err)) { - pr_err("wc_AesSetKey failed"); - return err; - } - - err = wc_AesCfbDecrypt(&ctx->aes, walk.dst.virt.addr, - walk.src.virt.addr, nbytes); - - if (unlikely(err)) { - pr_err("wc_AesCfbDecrypt failed"); - return err; - } - - err = skcipher_walk_done(&walk, walk.nbytes - nbytes); - } - - return err; -} -#endif /* endif WOLFSSL_AES_CFB */ - - -#if defined(HAVE_AESGCM) -static int km_AesGcmInit(struct crypto_aead * tfm) -{ - struct km_AesCtx * ctx = crypto_aead_ctx(tfm); - km_ForceZero(ctx); - return km_AesInitCommon(ctx, WOLFKM_GCM_DRIVER); -} - -static void km_AesGcmExit(struct crypto_aead * tfm) -{ - struct km_AesCtx * ctx = crypto_aead_ctx(tfm); - km_AesExitCommon(ctx); -} - -static int km_AesGcmSetKey(struct crypto_aead *tfm, const u8 *in_key, - unsigned int key_len) -{ - struct km_AesCtx * ctx = crypto_aead_ctx(tfm); - return km_AesSetKeyCommon(ctx, in_key, key_len, WOLFKM_GCM_DRIVER); -} - -static int km_AesGcmSetAuthsize(struct crypto_aead *tfm, unsigned int authsize) -{ - (void)tfm; - if (authsize > AES_BLOCK_SIZE || - authsize < WOLFSSL_MIN_AUTH_TAG_SZ) { - pr_err("error: invalid authsize: %d\n", authsize); - return -EINVAL; - } - return 0; -} - -/* - * aead ciphers recieve data in scatterlists in following order: - * encrypt - * req->src: aad||plaintext - * req->dst: aad||ciphertext||tag - * decrypt - * req->src: aad||ciphertext||tag - * req->dst: aad||plaintext, return 0 or -EBADMSG - */ - -static int km_AesGcmEncrypt(struct aead_request *req) -{ - struct crypto_aead * tfm = NULL; - struct km_AesCtx * ctx = NULL; - struct skcipher_walk walk; - struct scatter_walk assocSgWalk; - unsigned int nbytes = 0; - u8 authTag[AES_BLOCK_SIZE]; - int err = 0; - unsigned int assocLeft = 0; - unsigned int cryptLeft = 0; - u8 * assoc = NULL; - - tfm = crypto_aead_reqtfm(req); - ctx = crypto_aead_ctx(tfm); - assocLeft = req->assoclen; - cryptLeft = req->cryptlen; - - scatterwalk_start(&assocSgWalk, req->src); - - err = skcipher_walk_aead_encrypt(&walk, req, false); - if (unlikely(err)) { - pr_err("error: skcipher_walk_aead_encrypt: %d\n", err); - return -1; - } - - err = wc_AesGcmInit(&ctx->aes, ctx->key, ctx->keylen, walk.iv, - AES_BLOCK_SIZE); - if (unlikely(err)) { - pr_err("error: wc_AesGcmInit failed with return code %d.\n", err); - return err; - } - - assoc = scatterwalk_map(&assocSgWalk); - if (unlikely(IS_ERR(assoc))) { - pr_err("error: scatterwalk_map failed %ld\n", PTR_ERR(assoc)); - return err; - } - - err = wc_AesGcmEncryptUpdate(&ctx->aes, NULL, NULL, 0, assoc, assocLeft); - assocLeft -= assocLeft; - scatterwalk_unmap(assoc); - assoc = NULL; - - if (unlikely(err)) { - pr_err("error: wc_AesGcmEncryptUpdate failed %d\n", err); - return err; - } - - while ((nbytes = walk.nbytes)) { - int n = nbytes; - - if (likely(cryptLeft && nbytes)) { - n = cryptLeft < nbytes ? cryptLeft : nbytes; - - err = wc_AesGcmEncryptUpdate(&ctx->aes, walk.dst.virt.addr, - walk.src.virt.addr, cryptLeft, NULL, 0); - nbytes -= n; - cryptLeft -= n; - } - - if (unlikely(err)) { - pr_err("wc_AesGcmEncryptUpdate failed %d\n", err); - return err; - } - - err = skcipher_walk_done(&walk, nbytes); - } - - err = wc_AesGcmEncryptFinal(&ctx->aes, authTag, tfm->authsize); - if (unlikely(err)) { - pr_err("error: wc_AesGcmEncryptFinal failed with return code %d\n", err); - return err; - } - - /* Now copy the auth tag into request scatterlist. */ - scatterwalk_map_and_copy(authTag, req->dst, - req->assoclen + req->cryptlen, - tfm->authsize, 1); - - return err; -} - -static int km_AesGcmDecrypt(struct aead_request *req) -{ - struct crypto_aead * tfm = NULL; - struct km_AesCtx * ctx = NULL; - struct skcipher_walk walk; - struct scatter_walk assocSgWalk; - unsigned int nbytes = 0; - u8 origAuthTag[AES_BLOCK_SIZE]; - int err = 0; - unsigned int assocLeft = 0; - unsigned int cryptLeft = 0; - u8 * assoc = NULL; - - tfm = crypto_aead_reqtfm(req); - ctx = crypto_aead_ctx(tfm); - assocLeft = req->assoclen; - cryptLeft = req->cryptlen - tfm->authsize; - - /* Copy out original auth tag from req->src. */ - scatterwalk_map_and_copy(origAuthTag, req->src, - req->assoclen + req->cryptlen - tfm->authsize, - tfm->authsize, 0); - - scatterwalk_start(&assocSgWalk, req->src); - - err = skcipher_walk_aead_decrypt(&walk, req, false); - if (unlikely(err)) { - pr_err("error: skcipher_walk_aead_decrypt: %d\n", err); - return -1; - } - - err = wc_AesGcmInit(&ctx->aes, ctx->key, ctx->keylen, walk.iv, - AES_BLOCK_SIZE); - if (unlikely(err)) { - pr_err("error: wc_AesGcmInit failed with return code %d.\n", err); - return err; - } - - assoc = scatterwalk_map(&assocSgWalk); - if (unlikely(IS_ERR(assoc))) { - pr_err("error: scatterwalk_map failed %ld\n", PTR_ERR(assoc)); - return err; - } - - err = wc_AesGcmDecryptUpdate(&ctx->aes, NULL, NULL, 0, assoc, assocLeft); - assocLeft -= assocLeft; - scatterwalk_unmap(assoc); - assoc = NULL; - - if (unlikely(err)) { - pr_err("error: wc_AesGcmDecryptUpdate failed %d\n", err); - return err; - } - - while ((nbytes = walk.nbytes)) { - int n = nbytes; - - if (likely(cryptLeft && nbytes)) { - n = cryptLeft < nbytes ? cryptLeft : nbytes; - - err = wc_AesGcmDecryptUpdate(&ctx->aes, walk.dst.virt.addr, - walk.src.virt.addr, cryptLeft, NULL, 0); - nbytes -= n; - cryptLeft -= n; - } - - if (unlikely(err)) { - pr_err("wc_AesGcmDecryptUpdate failed %d\n", err); - return err; - } - - err = skcipher_walk_done(&walk, nbytes); - } - - err = wc_AesGcmDecryptFinal(&ctx->aes, origAuthTag, tfm->authsize); - if (unlikely(err)) { - pr_err("error: wc_AesGcmDecryptFinal failed with return code %d\n", err); - - if (err == AES_GCM_AUTH_E) { - return -EBADMSG; - } - else { - return err; - } - } - - return err; -} -#endif /* endif HAVE_AESGCM */ - -#if defined(HAVE_AES_CBC) -static struct skcipher_alg cbcAesAlg = { - .base.cra_name = WOLFKM_CBC_NAME, - .base.cra_driver_name = WOLFKM_CBC_DRIVER, - .base.cra_priority = WOLFKM_ALG_PRIORITY, - .base.cra_blocksize = AES_BLOCK_SIZE, - .base.cra_ctxsize = sizeof(struct km_AesCtx), - .base.cra_module = THIS_MODULE, - .init = km_AesInit, - .exit = km_AesExit, - .min_keysize = (128 / 8), - .max_keysize = (AES_MAX_KEY_SIZE / 8), - .ivsize = AES_BLOCK_SIZE, - .setkey = km_AesSetKey, - .encrypt = km_AesCbcEncrypt, - .decrypt = km_AesCbcDecrypt, -}; -#endif - -#if defined(WOLFSSL_AES_CFB) -static struct skcipher_alg cfbAesAlg = { - .base.cra_name = WOLFKM_CFB_NAME, - .base.cra_driver_name = WOLFKM_CFB_DRIVER, - .base.cra_priority = WOLFKM_ALG_PRIORITY, - .base.cra_blocksize = AES_BLOCK_SIZE, - .base.cra_ctxsize = sizeof(struct km_AesCtx), - .base.cra_module = THIS_MODULE, - .init = km_AesInit, - .exit = km_AesExit, - .min_keysize = (128 / 8), - .max_keysize = (AES_MAX_KEY_SIZE / 8), - .ivsize = AES_BLOCK_SIZE, - .setkey = km_AesSetKey, - .encrypt = km_AesCfbEncrypt, - .decrypt = km_AesCfbDecrypt, -}; -#endif - -#if defined(HAVE_AESGCM) -static struct aead_alg gcmAesAead = { - .base.cra_name = WOLFKM_GCM_NAME, - .base.cra_driver_name = WOLFKM_GCM_DRIVER, - .base.cra_priority = WOLFKM_ALG_PRIORITY, - .base.cra_blocksize = 1, - .base.cra_ctxsize = sizeof(struct km_AesCtx), - .base.cra_module = THIS_MODULE, - .init = km_AesGcmInit, - .exit = km_AesGcmExit, - .setkey = km_AesGcmSetKey, - .setauthsize = km_AesGcmSetAuthsize, - .encrypt = km_AesGcmEncrypt, - .decrypt = km_AesGcmDecrypt, - .ivsize = AES_BLOCK_SIZE, - .maxauthsize = AES_BLOCK_SIZE, - .chunksize = AES_BLOCK_SIZE, -}; -#endif - -static int linuxkm_register_alg(void) -{ - int ret = 0; -#if defined(HAVE_AES_CBC) - ret = crypto_register_skcipher(&cbcAesAlg); - - if (ret) { - pr_err("crypto_register_skcipher failed with return code %d.\n", ret); - return ret; - } -#endif - -#if defined(WOLFSSL_AES_CFB) - ret = crypto_register_skcipher(&cfbAesAlg); - - if (ret) { - pr_err("crypto_register_skcipher failed with return code %d.\n", ret); - return ret; - } -#endif - -#if defined(HAVE_AESGCM) - ret = crypto_register_aead(&gcmAesAead); - - if (ret) { - pr_err("crypto_register_aead failed with return code %d.\n", ret); - return ret; - } -#endif - - return 0; -} - -static void linuxkm_unregister_alg(void) -{ -#if defined(HAVE_AES_CBC) - crypto_unregister_skcipher(&cbcAesAlg); -#endif -#if defined(WOLFSSL_AES_CFB) - crypto_unregister_skcipher(&cfbAesAlg); -#endif -#if defined(HAVE_AESGCM) - crypto_unregister_aead(&gcmAesAead); -#endif -} - -/* Given registered wolfcrypt kernel crypto, sanity test against - * direct wolfcrypt calls. */ - -static int linuxkm_test_alg(void) -{ - int ret = 0; - - ret = linuxkm_test_cbc(); - if (ret) { return ret; } - - ret = linuxkm_test_cfb(); - if (ret) { return ret; } - - ret = linuxkm_test_gcm(); - if (ret) { return ret; } - - return 0; -} - -static int linuxkm_test_cbc(void) -{ - int ret = 0; -#if defined(HAVE_AES_CBC) - struct crypto_skcipher * tfm = NULL; - struct skcipher_request * req = NULL; - struct scatterlist src, dst; - Aes aes; - byte key32[] = - { - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66 - }; - byte vector[] = /* Now is the time for all good men w/o trailing 0 */ - { - 0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74, - 0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20, - 0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20, - 0x67,0x6f,0x6f,0x64,0x20,0x6d,0x65,0x6e - }; - byte iv[] = "1234567890abcdef"; - byte enc[sizeof(vector)]; - byte dec[sizeof(vector)]; - u8 * enc2 = NULL; - u8 * dec2 = NULL; - - XMEMSET(enc, 0, sizeof(enc)); - XMEMSET(dec, 0, sizeof(enc)); - - ret = wc_AesInit(&aes, NULL, INVALID_DEVID); - if (ret) { - pr_err("wolfcrypt wc_AesInit failed with return code %d.\n", ret); - return -1; - } - - ret = wc_AesSetKey(&aes, key32, AES_BLOCK_SIZE * 2, iv, AES_ENCRYPTION); - if (ret) { - pr_err("wolfcrypt wc_AesSetKey failed with return code %d\n", ret); - return -1; - } - - ret = wc_AesCbcEncrypt(&aes, enc, vector, sizeof(vector)); - if (ret) { - pr_err("wolfcrypt wc_AesCbcEncrypt failed with return code %d\n", ret); - return -1; - } - - /* Re init for decrypt and set flag. */ - wc_AesFree(&aes); - - ret = wc_AesInit(&aes, NULL, INVALID_DEVID); - if (ret) { - pr_err("wolfcrypt wc_AesInit failed with return code %d.\n", ret); - return -1; - } - - ret = wc_AesSetKey(&aes, key32, AES_BLOCK_SIZE * 2, iv, AES_DECRYPTION); - if (ret) { - pr_err("wolfcrypt wc_AesSetKey failed with return code %d.\n", ret); - return -1; - } - - ret = wc_AesCbcDecrypt(&aes, dec, enc, sizeof(vector)); - if (ret) { - pr_err("wolfcrypt wc_AesCbcDecrypt failed with return code %d\n", ret); - return -1; - } - - ret = XMEMCMP(vector, dec, sizeof(vector)); - if (ret) { - pr_err("error: vector and dec do not match: %d\n", ret); - return -1; - } - - /* now the kernel crypto part */ - enc2 = kmalloc(sizeof(vector), GFP_KERNEL); - if (!enc2) { - pr_err("error: kmalloc failed\n"); - goto test_cbc_end; - } - - dec2 = kmalloc(sizeof(vector), GFP_KERNEL); - if (!dec2) { - pr_err("error: kmalloc failed\n"); - goto test_cbc_end; - } - - memcpy(dec2, vector, sizeof(vector)); - - tfm = crypto_alloc_skcipher(WOLFKM_CBC_DRIVER, 0, 0); - if (IS_ERR(tfm)) { - pr_err("error: allocating AES skcipher algorithm %s failed: %ld\n", - WOLFKM_CBC_DRIVER, PTR_ERR(tfm)); - goto test_cbc_end; - } - - ret = crypto_skcipher_setkey(tfm, key32, AES_BLOCK_SIZE * 2); - if (ret) { - pr_err("error: crypto_skcipher_setkey returned: %d\n", ret); - goto test_cbc_end; - } - - req = skcipher_request_alloc(tfm, GFP_KERNEL); - if (IS_ERR(req)) { - pr_err("error: allocating AES skcipher request %s failed\n", - WOLFKM_CBC_DRIVER); - goto test_cbc_end; - } - - sg_init_one(&src, dec2, sizeof(vector)); - sg_init_one(&dst, enc2, sizeof(vector)); - - skcipher_request_set_crypt(req, &src, &dst, sizeof(vector), iv); - - ret = crypto_skcipher_encrypt(req); - - if (ret) { - pr_err("error: crypto_skcipher_encrypt returned: %d\n", ret); - goto test_cbc_end; - } - - ret = XMEMCMP(enc, enc2, sizeof(vector)); - if (ret) { - pr_err("error: enc and enc2 do not match: %d\n", ret); - goto test_cbc_end; - } - - memset(dec2, 0, sizeof(vector)); - sg_init_one(&src, enc2, sizeof(vector)); - sg_init_one(&dst, dec2, sizeof(vector)); - - skcipher_request_set_crypt(req, &src, &dst, sizeof(vector), iv); - - ret = crypto_skcipher_decrypt(req); - - if (ret) { - pr_err("error: crypto_skcipher_decrypt returned: %d\n", ret); - goto test_cbc_end; - } - - ret = XMEMCMP(dec, dec2, sizeof(vector)); - if (ret) { - pr_err("error: dec and dec2 do not match: %d\n", ret); - goto test_cbc_end; - } - - pr_info("info: test driver %s: good\n", WOLFKM_CBC_DRIVER); - -test_cbc_end: - - if (enc2) { kfree(enc2); enc2 = NULL; } - if (dec2) { kfree(dec2); dec2 = NULL; } - if (req) { skcipher_request_free(req); req = NULL; } - if (tfm) { crypto_free_skcipher(tfm); tfm = NULL; } - -#endif /* if defined HAVE_AES_CBC */ - return ret; -} - -static int linuxkm_test_cfb(void) -{ - int ret = 0; -#if defined(WOLFSSL_AES_CFB) - struct crypto_skcipher * tfm = NULL; - struct skcipher_request * req = NULL; - struct scatterlist src, dst; - Aes aes; - byte key32[] = - { - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66 - }; - byte vector[] = /* Now is the time for all good men w/o trailing 0 */ - { - 0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74, - 0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20, - 0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20, - 0x67,0x6f,0x6f,0x64,0x20,0x6d,0x65,0x6e - }; - byte iv[] = "1234567890abcdef"; - byte enc[sizeof(vector)]; - byte dec[sizeof(vector)]; - u8 * enc2 = NULL; - u8 * dec2 = NULL; - - XMEMSET(enc, 0, sizeof(enc)); - XMEMSET(dec, 0, sizeof(enc)); - - ret = wc_AesInit(&aes, NULL, INVALID_DEVID); - if (ret) { - pr_err("wolfcrypt wc_AesInit failed with return code %d.\n", ret); - return -1; - } - - ret = wc_AesSetKey(&aes, key32, AES_BLOCK_SIZE * 2, iv, AES_ENCRYPTION); - if (ret) { - pr_err("wolfcrypt wc_AesSetKey failed with return code %d\n", ret); - return -1; - } - - ret = wc_AesCfbEncrypt(&aes, enc, vector, sizeof(vector)); - if (ret) { - pr_err("wolfcrypt wc_AesCfbEncrypt failed with return code %d\n", ret); - return -1; - } - - /* Re init for decrypt and set flag. */ - wc_AesFree(&aes); - - ret = wc_AesInit(&aes, NULL, INVALID_DEVID); - if (ret) { - pr_err("wolfcrypt wc_AesInit failed with return code %d.\n", ret); - return -1; - } - - ret = wc_AesSetKey(&aes, key32, AES_BLOCK_SIZE * 2, iv, AES_ENCRYPTION); - if (ret) { - pr_err("wolfcrypt wc_AesSetKey failed with return code %d.\n", ret); - return -1; - } - - ret = wc_AesCfbDecrypt(&aes, dec, enc, sizeof(vector)); - if (ret) { - pr_err("wolfcrypt wc_AesCfbDecrypt failed with return code %d\n", ret); - return -1; - } - - ret = XMEMCMP(vector, dec, sizeof(vector)); - if (ret) { - pr_err("error: vector and dec do not match: %d\n", ret); - return -1; - } - - /* now the kernel crypto part */ - enc2 = kmalloc(sizeof(vector), GFP_KERNEL); - if (!enc2) { - pr_err("error: kmalloc failed\n"); - goto test_cfb_end; - } - - dec2 = kmalloc(sizeof(vector), GFP_KERNEL); - if (!dec2) { - pr_err("error: kmalloc failed\n"); - goto test_cfb_end; - } - - memcpy(dec2, vector, sizeof(vector)); - - tfm = crypto_alloc_skcipher(WOLFKM_CFB_DRIVER, 0, 0); - if (IS_ERR(tfm)) { - pr_err("error: allocating AES skcipher algorithm %s failed: %ld\n", - WOLFKM_CFB_DRIVER, PTR_ERR(tfm)); - goto test_cfb_end; - } - - ret = crypto_skcipher_setkey(tfm, key32, AES_BLOCK_SIZE * 2); - if (ret) { - pr_err("error: crypto_skcipher_setkey returned: %d\n", ret); - goto test_cfb_end; - } - - req = skcipher_request_alloc(tfm, GFP_KERNEL); - if (IS_ERR(req)) { - pr_err("error: allocating AES skcipher request %s failed\n", - WOLFKM_CFB_DRIVER); - goto test_cfb_end; - } - - sg_init_one(&src, dec2, sizeof(vector)); - sg_init_one(&dst, enc2, sizeof(vector)); - - skcipher_request_set_crypt(req, &src, &dst, sizeof(vector), iv); - - ret = crypto_skcipher_encrypt(req); - - if (ret) { - pr_err("error: crypto_skcipher_encrypt returned: %d\n", ret); - goto test_cfb_end; - } - - ret = XMEMCMP(enc, enc2, sizeof(vector)); - if (ret) { - pr_err("error: enc and enc2 do not match: %d\n", ret); - goto test_cfb_end; - } - - memset(dec2, 0, sizeof(vector)); - sg_init_one(&src, enc2, sizeof(vector)); - sg_init_one(&dst, dec2, sizeof(vector)); - - skcipher_request_set_crypt(req, &src, &dst, sizeof(vector), iv); - - ret = crypto_skcipher_decrypt(req); - - if (ret) { - pr_err("error: crypto_skcipher_decrypt returned: %d\n", ret); - goto test_cfb_end; - } - - ret = XMEMCMP(dec, dec2, sizeof(vector)); - if (ret) { - pr_err("error: dec and dec2 do not match: %d\n", ret); - goto test_cfb_end; - } - - pr_info("info: test driver %s: good\n", WOLFKM_CFB_DRIVER); - -test_cfb_end: - - if (enc2) { kfree(enc2); enc2 = NULL; } - if (dec2) { kfree(dec2); dec2 = NULL; } - if (req) { skcipher_request_free(req); req = NULL; } - if (tfm) { crypto_free_skcipher(tfm); tfm = NULL; } -#endif /* if defined WOLFSSL_AES_CFB */ - - return ret; -} - -static int linuxkm_test_gcm(void) -{ - int ret = 0; -#if defined(HAVE_AESGCM) - struct crypto_aead * tfm = NULL; - struct aead_request * req = NULL; - struct scatterlist * src = NULL; - struct scatterlist * dst = NULL; - Aes aes; - byte key32[] = - { - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66 - }; - byte vector[] = /* Now is the time for all w/o trailing 0 */ - { - 0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74, - 0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20, - 0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20 - }; - const byte assoc[] = - { - 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, - 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, - 0xab, 0xad, 0xda, 0xd2 - }; - byte ivstr[] = "1234567890abcdef"; - byte enc[sizeof(vector)]; - byte authTag[AES_BLOCK_SIZE]; - byte dec[sizeof(vector)]; - u8 * assoc2 = NULL; - u8 * enc2 = NULL; - u8 * dec2 = NULL; - u8 * iv = NULL; - size_t encryptLen = sizeof(vector); - size_t decryptLen = sizeof(vector) + sizeof(authTag); - - /* Init stack variables. */ - XMEMSET(enc, 0, sizeof(vector)); - XMEMSET(dec, 0, sizeof(vector)); - XMEMSET(authTag, 0, AES_BLOCK_SIZE); - - ret = wc_AesInit(&aes, NULL, INVALID_DEVID); - if (ret) { - pr_err("error: wc_AesInit failed with return code %d.\n", ret); - goto test_gcm_end; - } - - ret = wc_AesGcmInit(&aes, key32, sizeof(key32)/sizeof(byte), ivstr, - AES_BLOCK_SIZE); - if (ret) { - pr_err("error: wc_AesGcmInit failed with return code %d.\n", ret); - goto test_gcm_end; - } - - ret = wc_AesGcmEncryptUpdate(&aes, NULL, NULL, 0, assoc, sizeof(assoc)); - if (ret) { - pr_err("error: wc_AesGcmEncryptUpdate failed with return code %d\n", ret); - goto test_gcm_end; - } - - ret = wc_AesGcmEncryptUpdate(&aes, enc, vector, sizeof(vector), NULL, 0); - if (ret) { - pr_err("error: wc_AesGcmEncryptUpdate failed with return code %d\n", ret); - goto test_gcm_end; - } - - ret = wc_AesGcmEncryptFinal(&aes, authTag, AES_BLOCK_SIZE); - if (ret) { - pr_err("error: wc_AesGcmEncryptFinal failed with return code %d\n", ret); - goto test_gcm_end; - } - - ret = wc_AesGcmInit(&aes, key32, sizeof(key32)/sizeof(byte), ivstr, - AES_BLOCK_SIZE); - if (ret) { - pr_err("error: wc_AesGcmInit failed with return code %d.\n", ret); - goto test_gcm_end; - } - - ret = wc_AesGcmDecryptUpdate(&aes, dec, enc, sizeof(vector), assoc, sizeof(assoc)); - if (ret) { - pr_err("error: wc_AesGcmDecryptUpdate failed with return code %d\n", ret); - goto test_gcm_end; - } - - ret = wc_AesGcmDecryptFinal(&aes, authTag, AES_BLOCK_SIZE); - if (ret) { - pr_err("error: wc_AesGcmEncryptFinal failed with return code %d\n", ret); - goto test_gcm_end; - } - - ret = XMEMCMP(vector, dec, sizeof(vector)); - if (ret) { - pr_err("error: gcm: vector and dec do not match: %d\n", ret); - goto test_gcm_end; - } - - /* now the kernel crypto part */ - assoc2 = kmalloc(sizeof(assoc), GFP_KERNEL); - if (IS_ERR(assoc2)) { - pr_err("error: kmalloc failed\n"); - goto test_gcm_end; - } - memset(assoc2, 0, sizeof(assoc)); - memcpy(assoc2, assoc, sizeof(assoc)); - - iv = kmalloc(AES_BLOCK_SIZE, GFP_KERNEL); - if (IS_ERR(iv)) { - pr_err("error: kmalloc failed\n"); - goto test_gcm_end; - } - memset(iv, 0, AES_BLOCK_SIZE); - memcpy(iv, ivstr, AES_BLOCK_SIZE); - - enc2 = kmalloc(decryptLen, GFP_KERNEL); - if (IS_ERR(enc2)) { - pr_err("error: kmalloc failed\n"); - goto test_gcm_end; - } - - dec2 = kmalloc(decryptLen, GFP_KERNEL); - if (IS_ERR(dec2)) { - pr_err("error: kmalloc failed\n"); - goto test_gcm_end; - } - - memset(enc2, 0, decryptLen); - memset(dec2, 0, decryptLen); - memcpy(dec2, vector, sizeof(vector)); - - tfm = crypto_alloc_aead(WOLFKM_GCM_DRIVER, 0, 0); - if (IS_ERR(tfm)) { - pr_err("error: allocating AES skcipher algorithm %s failed: %ld\n", - WOLFKM_GCM_DRIVER, PTR_ERR(tfm)); - goto test_gcm_end; - } - - ret = crypto_aead_setkey(tfm, key32, AES_BLOCK_SIZE * 2); - if (ret) { - pr_err("error: crypto_aead_setkey returned: %d\n", ret); - goto test_gcm_end; - } - - ret = crypto_aead_setauthsize(tfm, sizeof(authTag)); - if (ret) { - pr_err("error: crypto_aead_setauthsize returned: %d\n", ret); - goto test_gcm_end; - } - - req = aead_request_alloc(tfm, GFP_KERNEL); - if (IS_ERR(req)) { - pr_err("error: allocating AES aead request %s failed: %ld\n", - WOLFKM_CBC_DRIVER, PTR_ERR(req)); - goto test_gcm_end; - } - - src = kmalloc(sizeof(struct scatterlist) * 2, GFP_KERNEL); - dst = kmalloc(sizeof(struct scatterlist) * 2, GFP_KERNEL); - - if (IS_ERR(src) || IS_ERR(dst)) { - pr_err("error: kmalloc src or dst failed: %ld, %ld\n", - PTR_ERR(src), PTR_ERR(dst)); - goto test_gcm_end; - } - - sg_init_table(src, 2); - sg_set_buf(src, assoc2, sizeof(assoc)); - sg_set_buf(&src[1], dec2, sizeof(vector)); - - sg_init_table(dst, 2); - sg_set_buf(dst, assoc2, sizeof(assoc)); - sg_set_buf(&dst[1], enc2, decryptLen); - - aead_request_set_callback(req, 0, NULL, NULL); - aead_request_set_ad(req, sizeof(assoc)); - aead_request_set_crypt(req, src, dst, sizeof(vector), iv); - - ret = crypto_aead_encrypt(req); - - if (ret) { - pr_err("error: crypto_aead_encrypt returned: %d\n", ret); - goto test_gcm_end; - } - - ret = XMEMCMP(enc, enc2, sizeof(vector)); - if (ret) { - pr_err("error: enc and enc2 do not match: %d\n", ret); - goto test_gcm_end; - } - - ret = XMEMCMP(authTag, enc2 + encryptLen, sizeof(authTag)); - if (ret) { - pr_err("error: authTags do not match: %d\n", ret); - goto test_gcm_end; - } - - /* Now decrypt crypto request. Reverse src and dst. */ - memset(dec2, 0, decryptLen); - aead_request_set_ad(req, sizeof(assoc)); - aead_request_set_crypt(req, dst, src, decryptLen, iv); - - ret = crypto_aead_decrypt(req); - - if (ret) { - pr_err("error: crypto_aead_decrypt returned: %d\n", ret); - goto test_gcm_end; - } - - ret = XMEMCMP(dec, dec2, sizeof(vector)); - if (ret) { - pr_err("error: dec and dec2 do not match: %d\n", ret); - goto test_gcm_end; - } - - pr_info("info: test driver %s: good\n", WOLFKM_GCM_DRIVER); - -test_gcm_end: - if (req) { aead_request_free(req); req = NULL; } - if (tfm) { crypto_free_aead(tfm); tfm = NULL; } - - if (src) { kfree(src); src = NULL; } - if (dst) { kfree(dst); dst = NULL; } - - if (dec2) { kfree(dec2); dec2 = NULL; } - if (enc2) { kfree(enc2); enc2 = NULL; } - - if (assoc2) { kfree(assoc2); assoc2 = NULL; } - if (iv) { kfree(iv); iv = NULL; } -#endif /* if defined HAVE_AESGCM */ - - return 0; -} - -#endif /* LINUXKM_REGISTER_ALG && !defined(NO_AES) */ diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 7308178232..bc32148728 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -12252,6 +12252,14 @@ int wc_AesKeyUnWrap(const byte* key, word32 keySz, const byte* in, word32 inSz, /* Galois Field to use */ #define GF_XTS 0x87 +/* Set up keys for encryption and/or decryption. + * + * aes buffer holding aes subkeys + * heap heap hint to use for memory. Can be NULL + * devId id to use with async crypto. Can be 0 + * + * return 0 on success + */ int wc_AesXtsInit(XtsAes* aes, void* heap, int devId) { int ret = 0; @@ -12278,15 +12286,12 @@ int wc_AesXtsInit(XtsAes* aes, void* heap, int devId) /* Set up keys for encryption and/or decryption. * - * tweak AES key for tweak in XTS - * aes AES key for encrypt/decrypt process - * key buffer holding aes key | tweak key + * aes buffer holding aes subkeys + * key AES key for encrypt/decrypt and tweak process (concatenated) * len length of key buffer in bytes. Should be twice that of key size. i.e. * 32 for a 16 byte key. * dir direction: AES_ENCRYPTION, AES_DECRYPTION, or * AES_ENCRYPTION_AND_DECRYPTION - * heap heap hint to use for memory. Can be NULL - * devId id to use with async crypto. Can be 0 * * return 0 on success */ @@ -12680,15 +12685,19 @@ int wc_AesXtsEncrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz, if (xaes->aes_encrypt.use_aesni) { #if defined(HAVE_INTEL_AVX1) if (IS_INTEL_AVX1(intel_flags)) { - AES_XTS_encrypt_avx1(in, out, sz, i, (const byte*)xaes->aes_encrypt.key, - (const byte*)xaes->tweak.key, (int)xaes->aes_encrypt.rounds); + AES_XTS_encrypt_avx1(in, out, sz, i, + (const byte*)xaes->aes_encrypt.key, + (const byte*)xaes->tweak.key, + (int)xaes->aes_encrypt.rounds); ret = 0; } else #endif { - AES_XTS_encrypt_aesni(in, out, sz, i, (const byte*)xaes->aes_encrypt.key, - (const byte*)xaes->tweak.key, (int)xaes->aes_encrypt.rounds); + AES_XTS_encrypt_aesni(in, out, sz, i, + (const byte*)xaes->aes_encrypt.key, + (const byte*)xaes->tweak.key, + (int)xaes->aes_encrypt.rounds); ret = 0; } } @@ -12893,15 +12902,19 @@ int wc_AesXtsDecrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz, if (xaes->aes_decrypt.use_aesni) { #if defined(HAVE_INTEL_AVX1) if (IS_INTEL_AVX1(intel_flags)) { - AES_XTS_decrypt_avx1(in, out, sz, i, (const byte*)xaes->aes_decrypt.key, - (const byte*)xaes->tweak.key, (int)xaes->aes_decrypt.rounds); + AES_XTS_decrypt_avx1(in, out, sz, i, + (const byte*)xaes->aes_decrypt.key, + (const byte*)xaes->tweak.key, + (int)xaes->aes_decrypt.rounds); ret = 0; } else #endif { - AES_XTS_decrypt_aesni(in, out, sz, i, (const byte*)xaes->aes_decrypt.key, - (const byte*)xaes->tweak.key, (int)xaes->aes_decrypt.rounds); + AES_XTS_decrypt_aesni(in, out, sz, i, + (const byte*)xaes->aes_decrypt.key, + (const byte*)xaes->tweak.key, + (int)xaes->aes_decrypt.rounds); ret = 0; } } diff --git a/wolfcrypt/src/memory.c b/wolfcrypt/src/memory.c index f51e02a404..c4cbeabfc0 100644 --- a/wolfcrypt/src/memory.c +++ b/wolfcrypt/src/memory.c @@ -1542,27 +1542,40 @@ WOLFSSL_LOCAL int SAVE_VECTOR_REGISTERS2_fuzzer(void) { * fuzz vector register access without the detailed debugging. * this is useful for testing in the kernel module build, where glibc and * thread-local storage are unavailable. + * + * note this is not a well-behaved PRNG, but is adequate for fuzzing purposes. + * the prn sequence is incompressible according to ent and xz, and does not + * cycle within 10M iterations with various seeds including zero, but the Chi + * square distribution is poor, and the unconditioned lsb bit balance is ~54% + * regardless of seed. */ WOLFSSL_LOCAL int SAVE_VECTOR_REGISTERS2_fuzzer(void) { static unsigned long prn = WC_DEBUG_VECTOR_REGISTERS_FUZZING_SEED; - unsigned long popcount; + static int balance_bit = 0; /* access to prn is racey, but it doesn't matter. */ - unsigned long new_prn = prn ^ 0xba86943da66ee701ul; + unsigned long new_prn = prn ^ 0xba86943da66ee701ul; /* note this magic + * random number is + * bit-balanced. + */ + /* barrel-roll using the bottom 6 bits. */ if (new_prn & 0x3f) new_prn = (new_prn << (new_prn & 0x3f)) | (new_prn >> (0x40 - (new_prn & 0x3f))); - __asm__ volatile ("popcnt %1, %0;" - :"=r"(popcount) - :"r"(new_prn) - : - ); - new_prn ^= popcount; prn = new_prn; - if (prn & 1) - return IO_FAILED_E; - else - return 0; + balance_bit = !balance_bit; + + if (balance_bit) { + if (prn & 1) + return IO_FAILED_E; + else + return 0; + } else { + if (prn & 1) + return 0; + else + return IO_FAILED_E; + } } #endif /* DEBUG_VECTOR_REGISTER_ACCESS || DEBUG_VECTOR_REGISTER_ACCESS_FUZZING */ diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 6e215f52a0..7f50ee7c1f 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -9438,6 +9438,7 @@ static wc_test_ret_t aes_xts_128_test(void) 0x77, 0x8a, 0xe8, 0xb4, 0x3c, 0xb9, 0x8d, 0x5a }; +#ifndef HAVE_FIPS_VERSION /* FIPS requires different keys for main and tweak. */ WOLFSSL_SMALL_STACK_STATIC unsigned char k3[] = { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, @@ -9462,6 +9463,7 @@ static wc_test_ret_t aes_xts_128_test(void) 0xA0, 0x85, 0xD2, 0x69, 0x6E, 0x87, 0x0A, 0xBF, 0xB5, 0x5A, 0xDD, 0xCB, 0x80, 0xE0, 0xFC, 0xCD }; +#endif /* HAVE_FIPS_VERSION */ #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) if ((aes = (XtsAes *)XMALLOC(sizeof *aes, HEAP_HINT, DYNAMIC_TYPE_AES)) == NULL) @@ -9490,7 +9492,7 @@ static wc_test_ret_t aes_xts_128_test(void) ret = wc_AesXtsEncrypt(aes, buf, p2, sizeof(p2), i2, sizeof(i2)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -9501,7 +9503,7 @@ static wc_test_ret_t aes_xts_128_test(void) WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(SYSLIB_FAILED_E); ret = wc_AesXtsEncrypt(aes, buf, p2, sizeof(p2), i2, sizeof(i2)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(0); if (ret != 0) @@ -9517,7 +9519,7 @@ static wc_test_ret_t aes_xts_128_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsEncrypt(aes, buf, p1, sizeof(p1), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -9528,7 +9530,7 @@ static wc_test_ret_t aes_xts_128_test(void) WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(SYSLIB_FAILED_E); ret = wc_AesXtsEncrypt(aes, buf, p1, sizeof(p1), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(0); if (ret != 0) @@ -9541,7 +9543,7 @@ static wc_test_ret_t aes_xts_128_test(void) XMEMSET(cipher, 0, sizeof(cipher)); ret = wc_AesXtsEncrypt(aes, cipher, pp, sizeof(pp), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -9553,7 +9555,7 @@ static wc_test_ret_t aes_xts_128_test(void) XMEMSET(cipher, 0, sizeof(cipher)); ret = wc_AesXtsEncrypt(aes, cipher, pp, sizeof(pp), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(0); if (ret != 0) @@ -9569,7 +9571,7 @@ static wc_test_ret_t aes_xts_128_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecrypt(aes, buf, cipher, sizeof(pp), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -9581,7 +9583,7 @@ static wc_test_ret_t aes_xts_128_test(void) XMEMSET(buf, 0, sizeof(buf)); ret = wc_AesXtsDecrypt(aes, buf, cipher, sizeof(pp), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(0); if (ret != 0) @@ -9594,7 +9596,7 @@ static wc_test_ret_t aes_xts_128_test(void) XMEMSET(buf, 0, sizeof(buf)); ret = wc_AesXtsDecrypt(aes, buf, c1, sizeof(c1), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -9606,7 +9608,7 @@ static wc_test_ret_t aes_xts_128_test(void) XMEMSET(buf, 0, sizeof(buf)); ret = wc_AesXtsDecrypt(aes, buf, c1, sizeof(c1), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(0); if (ret != 0) @@ -9619,7 +9621,7 @@ static wc_test_ret_t aes_xts_128_test(void) XMEMSET(buf, 0, sizeof(buf)); ret = wc_AesXtsDecrypt(aes, buf, c2, sizeof(c2), i2, sizeof(i2)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -9633,13 +9635,15 @@ static wc_test_ret_t aes_xts_128_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecrypt(aes, buf, c2, sizeof(c2), i2, sizeof(i2)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); if (XMEMCMP(p2, buf, sizeof(p2))) ERROR_OUT(WC_TEST_RET_ENC_NC, out); +#ifndef HAVE_FIPS_VERSION + /* Test ciphertext stealing in-place. */ XMEMCPY(buf, p3, sizeof(p3)); ret = wc_AesXtsSetKeyNoInit(aes, k3, sizeof(k3), AES_ENCRYPTION); @@ -9648,7 +9652,7 @@ static wc_test_ret_t aes_xts_128_test(void) ret = wc_AesXtsEncrypt(aes, buf, buf, sizeof(p3), i3, sizeof(i3)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -9660,13 +9664,15 @@ static wc_test_ret_t aes_xts_128_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecrypt(aes, buf, buf, sizeof(c3), i3, sizeof(i3)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); if (XMEMCMP(p3, buf, sizeof(p3))) ERROR_OUT(WC_TEST_RET_ENC_NC, out); +#endif /* !HAVE_FIPS_VERSION */ + #if !defined(BENCH_EMBEDDED) && !defined(HAVE_CAVIUM) && \ !defined(WOLFSSL_AFALG) { @@ -9694,7 +9700,7 @@ static wc_test_ret_t aes_xts_128_test(void) ret = wc_AesXtsEncrypt(aes, large_input, large_input, j, i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -9705,7 +9711,7 @@ static wc_test_ret_t aes_xts_128_test(void) ret = wc_AesXtsDecrypt(aes, large_input, large_input, j, i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -9850,7 +9856,7 @@ static wc_test_ret_t aes_xts_256_test(void) ret = wc_AesXtsEncrypt(aes, buf, p2, sizeof(p2), i2, sizeof(i2)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -9863,7 +9869,7 @@ static wc_test_ret_t aes_xts_256_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsEncrypt(aes, buf, p1, sizeof(p1), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -9874,7 +9880,7 @@ static wc_test_ret_t aes_xts_256_test(void) XMEMSET(cipher, 0, sizeof(cipher)); ret = wc_AesXtsEncrypt(aes, cipher, pp, sizeof(pp), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -9886,7 +9892,7 @@ static wc_test_ret_t aes_xts_256_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecrypt(aes, buf, cipher, sizeof(pp), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -9897,7 +9903,7 @@ static wc_test_ret_t aes_xts_256_test(void) XMEMSET(buf, 0, sizeof(buf)); ret = wc_AesXtsDecrypt(aes, buf, c1, sizeof(c1), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -9910,7 +9916,7 @@ static wc_test_ret_t aes_xts_256_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecrypt(aes, buf, c2, sizeof(c2), i2, sizeof(i2)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -10127,7 +10133,7 @@ static wc_test_ret_t aes_xts_sector_test(void) ret = wc_AesXtsEncryptSector(aes, buf, p1, sizeof(p1), s1); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -10141,7 +10147,7 @@ static wc_test_ret_t aes_xts_sector_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecryptSector(aes, buf, c1, sizeof(c1), s1); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -10155,7 +10161,7 @@ static wc_test_ret_t aes_xts_sector_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsEncryptSector(aes, buf, p2, sizeof(p2), s2); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -10169,7 +10175,7 @@ static wc_test_ret_t aes_xts_sector_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecryptSector(aes, buf, c2, sizeof(c2), s2); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -10186,7 +10192,7 @@ static wc_test_ret_t aes_xts_sector_test(void) ret = wc_AesXtsEncryptConsecutiveSectors(aes, data, p3, sizeof(p3), s3, sectorSz); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -10201,7 +10207,7 @@ static wc_test_ret_t aes_xts_sector_test(void) ret = wc_AesXtsDecryptConsecutiveSectors(aes, data, c3, sizeof(c3), s3, sectorSz); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -10280,14 +10286,14 @@ static wc_test_ret_t aes_xts_args_test(void) ret = wc_AesXtsEncryptSector(NULL, buf, p1, sizeof(p1), s1); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret == 0) ERROR_OUT(WC_TEST_RET_ENC_NC, out); ret = wc_AesXtsEncryptSector(aes, NULL, p1, sizeof(p1), s1); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret == 0) ERROR_OUT(WC_TEST_RET_ENC_NC, out); @@ -10298,14 +10304,14 @@ static wc_test_ret_t aes_xts_args_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecryptSector(NULL, buf, c1, sizeof(c1), s1); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret == 0) ERROR_OUT(WC_TEST_RET_ENC_NC, out); ret = wc_AesXtsDecryptSector(aes, NULL, c1, sizeof(c1), s1); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret == 0) ERROR_OUT(WC_TEST_RET_ENC_NC, out); @@ -30070,8 +30076,8 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t ecc_test(void) #endif /* HAVE_ECC160 */ #if (defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 192 ret = ecc_test_curve(&rng, 24, ECC_CURVE_DEF); - printf("keySize=24, Default\n"); if (ret < 0) { + printf("keySize=24, Default\n"); goto done; } #endif /* HAVE_ECC192 */ From a0415ce8552954d2ad873d26d839022771fb241d Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Fri, 26 Jan 2024 20:19:52 -0600 Subject: [PATCH 17/63] wolfcrypt/src/port/arm/armv8-aes.c: fix for AesXts.aes_encrypt and AesXts.aes_decrypt. --- wolfcrypt/src/port/arm/armv8-aes.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/wolfcrypt/src/port/arm/armv8-aes.c b/wolfcrypt/src/port/arm/armv8-aes.c index 455d30bba3..8430ec5191 100644 --- a/wolfcrypt/src/port/arm/armv8-aes.c +++ b/wolfcrypt/src/port/arm/armv8-aes.c @@ -15624,7 +15624,7 @@ int wc_AesXtsEncrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz, : [blocks] "+r" (blocks), [in] "+r" (in), [out] "+r" (out), [sz] "+r" (sz) - : [key] "r" (xaes->aes.key), [rounds] "r" (xaes->aes.rounds), + : [key] "r" (xaes->aes_encrypt.key), [rounds] "r" (xaes->aes_encrypt.rounds), [key2] "r" (xaes->tweak.key), [i] "r" (i), [tmp] "r" (tmp) : "cc", "memory", @@ -15972,7 +15972,7 @@ int wc_AesXtsDecrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz, : [blocks] "+r" (blocks), [in] "+r" (in), [out] "+r" (out), [sz] "+r" (sz) - : [key] "r" (xaes->aes.key), [rounds] "r" (xaes->aes.rounds), + : [key] "r" (xaes->aes_decrypt.key), [rounds] "r" (xaes->aes_decrypt.rounds), [key2] "r" (xaes->tweak.key), [i] "r" (i), [tmp] "r" (tmp) : "cc", "memory", @@ -16298,7 +16298,7 @@ int wc_AesXtsEncrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz, : [blocks] "+r" (blocks), [in] "+r" (in), [out] "+r" (out), [sz] "+r" (sz), [i] "+r" (i), [key2] "+r" (key2) - : [key] "r" (xaes->aes.key), [rounds] "r" (xaes->aes.rounds), + : [key] "r" (xaes->aes_encrypt.key), [rounds] "r" (xaes->aes_encrypt.rounds), [tmp] "r" (tmp) : "cc", "memory", "r9", "r10", "r11", "r12", "r14", @@ -16455,7 +16455,7 @@ int wc_AesXtsDecrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz, : [blocks] "+r" (blocks), [in] "+r" (in), [out] "+r" (out), [sz] "+r" (sz), [i] "+r" (i), [key2] "+r" (key2) - : [key] "r" (xaes->aes.key), [rounds] "r" (xaes->aes.rounds), + : [key] "r" (xaes->aes_decrypt.key), [rounds] "r" (xaes->aes_decrypt.rounds), [tmp] "r" (tmp) : "cc", "memory", "r9", "r10", "r11", "r12", "r14", From 82d94dab68b49a45fd1cec2fb7c96de6e9fcfdab Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Sat, 27 Jan 2024 23:10:12 -0600 Subject: [PATCH 18/63] linuxkm: move "#undef HAVE_PTHREAD" from linuxkm/module_hooks.c to wolfssl/wolfcrypt/settings.h. --- linuxkm/module_hooks.c | 1 - wolfssl/wolfcrypt/settings.h | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/linuxkm/module_hooks.c b/linuxkm/module_hooks.c index 6d6ff6c8cf..ce9371ef2c 100644 --- a/linuxkm/module_hooks.c +++ b/linuxkm/module_hooks.c @@ -121,7 +121,6 @@ static int updateFipsHash(void); #endif #ifdef WOLFSSL_LINUXKM_BENCHMARKS -#undef HAVE_PTHREAD #define STRING_USER #define NO_MAIN_FUNCTION #define current_time benchmark_current_time diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 8091b02c56..444cd60022 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -2771,6 +2771,7 @@ extern void uITRON4_free(void *p) ; #ifndef WOLFSSL_TEST_SUBROUTINE #define WOLFSSL_TEST_SUBROUTINE static #endif + #undef HAVE_PTHREAD #undef HAVE_STRINGS_H #undef HAVE_ERRNO_H #undef HAVE_THREAD_LS From 8ae031a5edbc384acc21318d4b9c5d003251e0e5 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Sat, 27 Jan 2024 23:12:37 -0600 Subject: [PATCH 19/63] linuxkm/linuxkm_wc_port.h: improve my_memcpy(), my_memset(), and my_memmove() (CONFIG_FORTIFY_SOURCE workarounds) with copy-by-words codepaths. --- linuxkm/linuxkm_wc_port.h | 78 +++++++++++++++++++++++++++++---------- 1 file changed, 58 insertions(+), 20 deletions(-) diff --git a/linuxkm/linuxkm_wc_port.h b/linuxkm/linuxkm_wc_port.h index 255cf52fa1..16a07c628b 100644 --- a/linuxkm/linuxkm_wc_port.h +++ b/linuxkm/linuxkm_wc_port.h @@ -146,7 +146,7 @@ const char *s_start = s; while (*s) ++s; - return (size_t)s - (size_t)s_start; + return (size_t)((uintptr_t)s - (uintptr_t)s_start); } #include @@ -157,37 +157,75 @@ (sizeof(s) - 1) : strlen(s)) static inline void *my_memcpy(void *dest, const void *src, size_t n) { - u8 *src_bytes = (u8 *)src, - *dest_bytes = (u8 *)dest, - *endp = src_bytes + n; - while (src_bytes < endp) - *dest_bytes++ = *src_bytes++; + if (! (((uintptr_t)dest | (uintptr_t)src | (uintptr_t)n) & (uintptr_t)(sizeof(uintptr_t) - 1))) { + uintptr_t *src_longs = (uintptr_t *)src, + *dest_longs = (uintptr_t *)dest, + *endp = (uintptr_t *)((u8 *)src + n); + while (src_longs < endp) + *dest_longs++ = *src_longs++; + } else { + u8 *src_bytes = (u8 *)src, + *dest_bytes = (u8 *)dest, + *endp = src_bytes + n; + while (src_bytes < endp) + *dest_bytes++ = *src_bytes++; + } return dest; } #undef memcpy #define memcpy my_memcpy static inline void *my_memset(void *dest, int c, size_t n) { - u8 *dest_bytes = (u8 *)dest, *endp = dest_bytes + n; - while (dest_bytes < endp) - *dest_bytes++ = (u8)c; + if (! (((uintptr_t)dest | (uintptr_t)n) & (uintptr_t)(sizeof(uintptr_t) - 1))) { + uintptr_t c_long = __builtin_choose_expr( + sizeof(uintptr_t) == 8, + (uintptr_t)(u8)c * 0x0101010101010101UL, + (uintptr_t)(u8)c * 0x01010101U + ); + uintptr_t *dest_longs = (uintptr_t *)dest, *endp = (uintptr_t *)((u8 *)dest_longs + n); + while (dest_longs < endp) + *dest_longs++ = c_long; + } else { + u8 *dest_bytes = (u8 *)dest, *endp = dest_bytes + n; + while (dest_bytes < endp) + *dest_bytes++ = (u8)c; + } return dest; } #undef memset #define memset my_memset static inline void *my_memmove(void *dest, const void *src, size_t n) { - u8 *src_bytes = (u8 *)src, *dest_bytes = (u8 *)dest; - if (src_bytes < dest_bytes) { - u8 *startp = src_bytes; - src_bytes += n - 1; - dest_bytes += n - 1; - while (src_bytes >= startp) - *dest_bytes-- = *src_bytes--; - } else if (src_bytes > dest_bytes) { - u8 *endp = src_bytes + n; - while (src_bytes < endp) - *dest_bytes++ = *src_bytes++; + if (! (((uintptr_t)dest | (uintptr_t)src | (uintptr_t)n) & (uintptr_t)(sizeof(uintptr_t) - 1))) { + uintptr_t *src_longs = (uintptr_t *)src, *dest_longs = (uintptr_t *)dest; + n >>= __builtin_choose_expr( + sizeof(uintptr_t) == 8, + 3U, + 2U); + if (src_longs < dest_longs) { + uintptr_t *startp = src_longs; + src_longs += n - 1; + dest_longs += n - 1; + while (src_longs >= startp) + *dest_longs-- = *src_longs--; + } else if (src_longs > dest_longs) { + uintptr_t *endp = src_longs + n; + while (src_longs < endp) + *dest_longs++ = *src_longs++; + } + } else { + u8 *src_bytes = (u8 *)src, *dest_bytes = (u8 *)dest; + if (src_bytes < dest_bytes) { + u8 *startp = src_bytes; + src_bytes += n - 1; + dest_bytes += n - 1; + while (src_bytes >= startp) + *dest_bytes-- = *src_bytes--; + } else if (src_bytes > dest_bytes) { + u8 *endp = src_bytes + n; + while (src_bytes < endp) + *dest_bytes++ = *src_bytes++; + } } return dest; } From 957fc7460c46836cb1c4d8079fbbb74d1ba314f9 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Sat, 27 Jan 2024 23:16:02 -0600 Subject: [PATCH 20/63] linuxkm/lkcapi_glue.c: refactor AES-CBC, AES-CFB, and AES-GCM glue around struct km_AesCtx with separate aes_encrypt and aes_decrypt Aes pointers, and no cached key, to avoid AesSetKey operations at encrypt/decrypt time. --- linuxkm/lkcapi_glue.c | 172 +++++++++++++++++++++++++++--------------- 1 file changed, 111 insertions(+), 61 deletions(-) diff --git a/linuxkm/lkcapi_glue.c b/linuxkm/lkcapi_glue.c index 2ec81eedbe..6cf84d98cd 100644 --- a/linuxkm/lkcapi_glue.c +++ b/linuxkm/lkcapi_glue.c @@ -96,35 +96,57 @@ static int linuxkm_test_aesxts(void); #include struct km_AesCtx { - Aes *aes; /* must be pointer to control alignment, needed for AESNI. */ - u8 key[AES_MAX_KEY_SIZE / 8]; - unsigned int keylen; + Aes *aes_encrypt; /* must be pointer to control alignment, needed for AESNI. */ + Aes *aes_decrypt; /* same. */ }; -static inline void km_ForceZero(struct km_AesCtx * ctx) -{ - memzero_explicit(ctx->key, sizeof(ctx->key)); - ctx->keylen = 0; -} - #if defined(LINUXKM_LKCAPI_REGISTER_ALL) || \ defined(LINUXKM_LKCAPI_REGISTER_AESCBC) || \ defined(LINUXKM_LKCAPI_REGISTER_AESCFB) || \ defined(LINUXKM_LKCAPI_REGISTER_AESGCM) -static int km_AesInitCommon(struct km_AesCtx * ctx, const char * name) +static void km_AesExitCommon(struct km_AesCtx * ctx); + +static int km_AesInitCommon(struct km_AesCtx * ctx, const char * name, int need_decryption) { int err; - ctx->aes = (Aes *)malloc(sizeof(*ctx->aes)); + ctx->aes_encrypt = (Aes *)malloc(sizeof(*ctx->aes_encrypt)); - if (! ctx->aes) + if (! ctx->aes_encrypt) { + pr_err("error: km_AesInitCommon %s failed: %d\n", name, MEMORY_E); return MEMORY_E; + } - err = wc_AesInit(ctx->aes, NULL, INVALID_DEVID); + err = wc_AesInit(ctx->aes_encrypt, NULL, INVALID_DEVID); if (unlikely(err)) { pr_err("error: km_AesInitCommon %s failed: %d\n", name, err); + free(ctx->aes_encrypt); + ctx->aes_encrypt = NULL; + return err; + } + + if (! need_decryption) { + ctx->aes_decrypt = NULL; + return 0; + } + + ctx->aes_decrypt = (Aes *)malloc(sizeof(*ctx->aes_decrypt)); + + if (! ctx->aes_encrypt) { + pr_err("error: km_AesInitCommon %s failed: %d\n", name, MEMORY_E); + km_AesExitCommon(ctx); + return MEMORY_E; + } + + err = wc_AesInit(ctx->aes_decrypt, NULL, INVALID_DEVID); + + if (unlikely(err)) { + pr_err("error: km_AesInitCommon %s failed: %d\n", name, err); + free(ctx->aes_decrypt); + ctx->aes_decrypt = NULL; + km_AesExitCommon(ctx); return err; } @@ -133,10 +155,16 @@ static int km_AesInitCommon(struct km_AesCtx * ctx, const char * name) static void km_AesExitCommon(struct km_AesCtx * ctx) { - wc_AesFree(ctx->aes); - free(ctx->aes); - ctx->aes = NULL; - km_ForceZero(ctx); + if (ctx->aes_encrypt) { + wc_AesFree(ctx->aes_encrypt); + free(ctx->aes_encrypt); + ctx->aes_encrypt = NULL; + } + if (ctx->aes_decrypt) { + wc_AesFree(ctx->aes_decrypt); + free(ctx->aes_decrypt); + ctx->aes_decrypt = NULL; + } } static int km_AesSetKeyCommon(struct km_AesCtx * ctx, const u8 *in_key, @@ -144,15 +172,21 @@ static int km_AesSetKeyCommon(struct km_AesCtx * ctx, const u8 *in_key, { int err; - err = wc_AesSetKey(ctx->aes, in_key, key_len, NULL, 0); + err = wc_AesSetKey(ctx->aes_encrypt, in_key, key_len, NULL, AES_ENCRYPTION); if (unlikely(err)) { pr_err("error: km_AesSetKeyCommon %s failed: %d\n", name, err); return err; } - XMEMCPY(ctx->key, in_key, key_len); - ctx->keylen = key_len; + if (ctx->aes_decrypt) { + err = wc_AesSetKey(ctx->aes_decrypt, in_key, key_len, NULL, AES_DECRYPTION); + + if (unlikely(err)) { + pr_err("error: km_AesSetKeyCommon %s failed: %d\n", name, err); + return err; + } + } return 0; } @@ -161,25 +195,12 @@ static int km_AesSetKeyCommon(struct km_AesCtx * ctx, const u8 *in_key, defined(LINUXKM_LKCAPI_REGISTER_AESCBC) || \ defined(LINUXKM_LKCAPI_REGISTER_AESCFB) -static int km_AesInit(struct crypto_skcipher *tfm) -{ - struct km_AesCtx * ctx = crypto_skcipher_ctx(tfm); - return km_AesInitCommon(ctx, WOLFKM_AESCBC_DRIVER); -} - static void km_AesExit(struct crypto_skcipher *tfm) { struct km_AesCtx * ctx = crypto_skcipher_ctx(tfm); km_AesExitCommon(ctx); } -static int km_AesSetKey(struct crypto_skcipher *tfm, const u8 *in_key, - unsigned int key_len) -{ - struct km_AesCtx * ctx = crypto_skcipher_ctx(tfm); - return km_AesSetKeyCommon(ctx, in_key, key_len, WOLFKM_AESCBC_DRIVER); -} - #endif /* LINUXKM_LKCAPI_REGISTER_ALL || * LINUXKM_LKCAPI_REGISTER_AESCBC || * LINUXKM_LKCAPI_REGISTER_AESCFB @@ -192,6 +213,19 @@ static int km_AesSetKey(struct crypto_skcipher *tfm, const u8 *in_key, #if defined(HAVE_AES_CBC) && \ (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESCBC)) +static int km_AesCbcInit(struct crypto_skcipher *tfm) +{ + struct km_AesCtx * ctx = crypto_skcipher_ctx(tfm); + return km_AesInitCommon(ctx, WOLFKM_AESCBC_DRIVER, 1); +} + +static int km_AesCbcSetKey(struct crypto_skcipher *tfm, const u8 *in_key, + unsigned int key_len) +{ + struct km_AesCtx * ctx = crypto_skcipher_ctx(tfm); + return km_AesSetKeyCommon(ctx, in_key, key_len, WOLFKM_AESCBC_DRIVER); +} + static int km_AesCbcEncrypt(struct skcipher_request *req) { struct crypto_skcipher * tfm = NULL; @@ -206,15 +240,14 @@ static int km_AesCbcEncrypt(struct skcipher_request *req) err = skcipher_walk_virt(&walk, req, false); while ((nbytes = walk.nbytes)) { - err = wc_AesSetKey(ctx->aes, ctx->key, ctx->keylen, walk.iv, - AES_ENCRYPTION); + err = wc_AesSetIV(ctx->aes_encrypt, walk.iv); if (unlikely(err)) { - pr_err("wc_AesSetKey failed: %d\n", err); + pr_err("wc_AesSetIV failed: %d\n", err); return err; } - err = wc_AesCbcEncrypt(ctx->aes, walk.dst.virt.addr, + err = wc_AesCbcEncrypt(ctx->aes_encrypt, walk.dst.virt.addr, walk.src.virt.addr, nbytes); if (unlikely(err)) { @@ -242,15 +275,14 @@ static int km_AesCbcDecrypt(struct skcipher_request *req) err = skcipher_walk_virt(&walk, req, false); while ((nbytes = walk.nbytes)) { - err = wc_AesSetKey(ctx->aes, ctx->key, ctx->keylen, walk.iv, - AES_DECRYPTION); + err = wc_AesSetIV(ctx->aes_decrypt, walk.iv); if (unlikely(err)) { pr_err("wc_AesSetKey failed"); return err; } - err = wc_AesCbcDecrypt(ctx->aes, walk.dst.virt.addr, + err = wc_AesCbcDecrypt(ctx->aes_decrypt, walk.dst.virt.addr, walk.src.virt.addr, nbytes); if (unlikely(err)) { @@ -271,12 +303,12 @@ static struct skcipher_alg cbcAesAlg = { .base.cra_blocksize = AES_BLOCK_SIZE, .base.cra_ctxsize = sizeof(struct km_AesCtx), .base.cra_module = THIS_MODULE, - .init = km_AesInit, + .init = km_AesCbcInit, .exit = km_AesExit, .min_keysize = AES_128_KEY_SIZE, .max_keysize = AES_256_KEY_SIZE, .ivsize = AES_BLOCK_SIZE, - .setkey = km_AesSetKey, + .setkey = km_AesCbcSetKey, .encrypt = km_AesCbcEncrypt, .decrypt = km_AesCbcDecrypt, }; @@ -289,6 +321,19 @@ static int cbcAesAlg_loaded = 0; #if defined(WOLFSSL_AES_CFB) && \ (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESCFB)) +static int km_AesCfbInit(struct crypto_skcipher *tfm) +{ + struct km_AesCtx * ctx = crypto_skcipher_ctx(tfm); + return km_AesInitCommon(ctx, WOLFKM_AESCFB_DRIVER, 0); +} + +static int km_AesCfbSetKey(struct crypto_skcipher *tfm, const u8 *in_key, + unsigned int key_len) +{ + struct km_AesCtx * ctx = crypto_skcipher_ctx(tfm); + return km_AesSetKeyCommon(ctx, in_key, key_len, WOLFKM_AESCFB_DRIVER); +} + static int km_AesCfbEncrypt(struct skcipher_request *req) { struct crypto_skcipher * tfm = NULL; @@ -303,15 +348,14 @@ static int km_AesCfbEncrypt(struct skcipher_request *req) err = skcipher_walk_virt(&walk, req, false); while ((nbytes = walk.nbytes)) { - err = wc_AesSetKey(ctx->aes, ctx->key, ctx->keylen, walk.iv, - AES_ENCRYPTION); + err = wc_AesSetIV(ctx->aes_encrypt, walk.iv); if (unlikely(err)) { pr_err("wc_AesSetKey failed: %d\n", err); return err; } - err = wc_AesCfbEncrypt(ctx->aes, walk.dst.virt.addr, + err = wc_AesCfbEncrypt(ctx->aes_encrypt, walk.dst.virt.addr, walk.src.virt.addr, nbytes); if (unlikely(err)) { @@ -339,15 +383,14 @@ static int km_AesCfbDecrypt(struct skcipher_request *req) err = skcipher_walk_virt(&walk, req, false); while ((nbytes = walk.nbytes)) { - err = wc_AesSetKey(ctx->aes, ctx->key, ctx->keylen, walk.iv, - AES_ENCRYPTION); + err = wc_AesSetIV(ctx->aes_encrypt, walk.iv); if (unlikely(err)) { pr_err("wc_AesSetKey failed"); return err; } - err = wc_AesCfbDecrypt(ctx->aes, walk.dst.virt.addr, + err = wc_AesCfbDecrypt(ctx->aes_encrypt, walk.dst.virt.addr, walk.src.virt.addr, nbytes); if (unlikely(err)) { @@ -368,12 +411,12 @@ static struct skcipher_alg cfbAesAlg = { .base.cra_blocksize = AES_BLOCK_SIZE, .base.cra_ctxsize = sizeof(struct km_AesCtx), .base.cra_module = THIS_MODULE, - .init = km_AesInit, + .init = km_AesCfbInit, .exit = km_AesExit, .min_keysize = AES_128_KEY_SIZE, .max_keysize = AES_256_KEY_SIZE, .ivsize = AES_BLOCK_SIZE, - .setkey = km_AesSetKey, + .setkey = km_AesCfbSetKey, .encrypt = km_AesCfbEncrypt, .decrypt = km_AesCfbDecrypt, }; @@ -390,8 +433,7 @@ static int cfbAesAlg_loaded = 0; static int km_AesGcmInit(struct crypto_aead * tfm) { struct km_AesCtx * ctx = crypto_aead_ctx(tfm); - km_ForceZero(ctx); - return km_AesInitCommon(ctx, WOLFKM_AESGCM_DRIVER); + return km_AesInitCommon(ctx, WOLFKM_AESGCM_DRIVER, 0); } static void km_AesGcmExit(struct crypto_aead * tfm) @@ -403,8 +445,16 @@ static void km_AesGcmExit(struct crypto_aead * tfm) static int km_AesGcmSetKey(struct crypto_aead *tfm, const u8 *in_key, unsigned int key_len) { + int err; struct km_AesCtx * ctx = crypto_aead_ctx(tfm); - return km_AesSetKeyCommon(ctx, in_key, key_len, WOLFKM_AESGCM_DRIVER); + + err = wc_AesGcmSetKey(ctx->aes_encrypt, in_key, key_len); + + if (err) { + pr_err("error: km_AesGcmSetKey %s failed: %d\n", WOLFKM_AESGCM_DRIVER, err); + } + + return err; } static int km_AesGcmSetAuthsize(struct crypto_aead *tfm, unsigned int authsize) @@ -454,7 +504,7 @@ static int km_AesGcmEncrypt(struct aead_request *req) return -1; } - err = wc_AesGcmInit(ctx->aes, ctx->key, ctx->keylen, walk.iv, + err = wc_AesGcmInit(ctx->aes_encrypt, NULL /* key */, 0 /* keylen */, walk.iv, AES_BLOCK_SIZE); if (unlikely(err)) { pr_err("error: wc_AesGcmInit failed with return code %d.\n", err); @@ -467,7 +517,7 @@ static int km_AesGcmEncrypt(struct aead_request *req) return err; } - err = wc_AesGcmEncryptUpdate(ctx->aes, NULL, NULL, 0, assoc, assocLeft); + err = wc_AesGcmEncryptUpdate(ctx->aes_encrypt, NULL, NULL, 0, assoc, assocLeft); assocLeft -= assocLeft; scatterwalk_unmap(assoc); assoc = NULL; @@ -483,7 +533,7 @@ static int km_AesGcmEncrypt(struct aead_request *req) if (likely(cryptLeft && nbytes)) { n = cryptLeft < nbytes ? cryptLeft : nbytes; - err = wc_AesGcmEncryptUpdate(ctx->aes, walk.dst.virt.addr, + err = wc_AesGcmEncryptUpdate(ctx->aes_encrypt, walk.dst.virt.addr, walk.src.virt.addr, cryptLeft, NULL, 0); nbytes -= n; cryptLeft -= n; @@ -497,7 +547,7 @@ static int km_AesGcmEncrypt(struct aead_request *req) err = skcipher_walk_done(&walk, nbytes); } - err = wc_AesGcmEncryptFinal(ctx->aes, authTag, tfm->authsize); + err = wc_AesGcmEncryptFinal(ctx->aes_encrypt, authTag, tfm->authsize); if (unlikely(err)) { pr_err("error: wc_AesGcmEncryptFinal failed with return code %d\n", err); return err; @@ -542,7 +592,7 @@ static int km_AesGcmDecrypt(struct aead_request *req) return -1; } - err = wc_AesGcmInit(ctx->aes, ctx->key, ctx->keylen, walk.iv, + err = wc_AesGcmInit(ctx->aes_encrypt, NULL /* key */, 0 /* keylen */, walk.iv, AES_BLOCK_SIZE); if (unlikely(err)) { pr_err("error: wc_AesGcmInit failed with return code %d.\n", err); @@ -555,7 +605,7 @@ static int km_AesGcmDecrypt(struct aead_request *req) return err; } - err = wc_AesGcmDecryptUpdate(ctx->aes, NULL, NULL, 0, assoc, assocLeft); + err = wc_AesGcmDecryptUpdate(ctx->aes_encrypt, NULL, NULL, 0, assoc, assocLeft); assocLeft -= assocLeft; scatterwalk_unmap(assoc); assoc = NULL; @@ -571,7 +621,7 @@ static int km_AesGcmDecrypt(struct aead_request *req) if (likely(cryptLeft && nbytes)) { n = cryptLeft < nbytes ? cryptLeft : nbytes; - err = wc_AesGcmDecryptUpdate(ctx->aes, walk.dst.virt.addr, + err = wc_AesGcmDecryptUpdate(ctx->aes_encrypt, walk.dst.virt.addr, walk.src.virt.addr, cryptLeft, NULL, 0); nbytes -= n; cryptLeft -= n; @@ -585,7 +635,7 @@ static int km_AesGcmDecrypt(struct aead_request *req) err = skcipher_walk_done(&walk, nbytes); } - err = wc_AesGcmDecryptFinal(ctx->aes, origAuthTag, tfm->authsize); + err = wc_AesGcmDecryptFinal(ctx->aes_encrypt, origAuthTag, tfm->authsize); if (unlikely(err)) { pr_err("error: wc_AesGcmDecryptFinal failed with return code %d\n", err); From 4585c6d508b872a08778a380a691a1429997cdf3 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Mon, 29 Jan 2024 11:03:40 +1000 Subject: [PATCH 21/63] ARMv8 32 bit ChaCha20 ASM: loading from in/out Input and output buffers come from the application and are not necessarily alighed. Use instructions that allow unaligned access to these buffers. --- wolfcrypt/src/port/arm/armv8-chacha.c | 34 ++++++++++++++------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/wolfcrypt/src/port/arm/armv8-chacha.c b/wolfcrypt/src/port/arm/armv8-chacha.c index 94e645049f..18dd9e596e 100644 --- a/wolfcrypt/src/port/arm/armv8-chacha.c +++ b/wolfcrypt/src/port/arm/armv8-chacha.c @@ -1666,7 +1666,10 @@ static WC_INLINE int wc_Chacha_encrypt_128(const word32 input[CHACHA_CHUNK_WORDS "VADD.I32 q6, q6, q12 \n\t" "VADD.I32 q7, q7, q13 \n\t" - "VLDM %[m], { q8-q15 } \n\t" + "VLD1.8 { q8, q9 }, [%[m]]! \n\t" + "VLD1.8 { q10, q11 }, [%[m]]! \n\t" + "VLD1.8 { q12, q13 }, [%[m]]! \n\t" + "VLD1.8 { q14, q15 }, [%[m]]! \n\t" "VEOR q0, q0, q8 \n\t" "VEOR q1, q1, q9 \n\t" "VEOR q2, q2, q10 \n\t" @@ -1675,7 +1678,10 @@ static WC_INLINE int wc_Chacha_encrypt_128(const word32 input[CHACHA_CHUNK_WORDS "VEOR q5, q5, q13 \n\t" "VEOR q6, q6, q14 \n\t" "VEOR q7, q7, q15 \n\t" - "VSTM %[c], { q0-q7 } \n\t" + "VST1.8 { q0, q1 }, [%[c]]! \n\t" + "VST1.8 { q2, q3 }, [%[c]]! \n\t" + "VST1.8 { q4, q5 }, [%[c]]! \n\t" + "VST1.8 { q6, q7 }, [%[c]]! \n\t" : [c] "+r" (c), [m] "+r" (m) : [rounds] "I" (ROUNDS/2), [input] "r" (input), @@ -2725,14 +2731,14 @@ static WC_INLINE void wc_Chacha_encrypt_64(const word32* input, const byte* m, "CMP %[bytes], #64 \n\t" "BLT L_chacha20_arm32_64_lt_64_%= \n\t" /* XOR full 64 byte block */ - "VLDM %[m], { q4-q7 } \n\t" - "ADD %[m], %[m], #64 \n\t" + "VLD1.8 { q4, q5 }, [%[m]]! \n\t" + "VLD1.8 { q6, q7 }, [%[m]]! \n\t" "VEOR q0, q0, q4 \n\t" "VEOR q1, q1, q5 \n\t" "VEOR q2, q2, q6 \n\t" "VEOR q3, q3, q7 \n\t" - "VSTM %[c], { q0-q3 } \n\t" - "ADD %[c], %[c], #64 \n\t" + "VST1.8 { q0, q1 }, [%[c]]! \n\t" + "VST1.8 { q2, q3 }, [%[c]]! \n\t" "SUBS %[bytes], %[bytes], #64 \n\t" "VADD.I32 q11, q11, q14 \n\t" "BNE L_chacha20_arm32_64_outer_loop_%= \n\t" @@ -2743,12 +2749,10 @@ static WC_INLINE void wc_Chacha_encrypt_64(const word32* input, const byte* m, /* XOR 32 bytes */ "CMP %[bytes], #32 \n\t" "BLT L_chacha20_arm32_64_lt_32_%= \n\t" - "VLDM %[m], { q4-q5 } \n\t" - "ADD %[m], %[m], #32 \n\t" + "VLD1.8 { q4, q5 }, [%[m]]! \n\t" "VEOR q4, q4, q0 \n\t" "VEOR q5, q5, q1 \n\t" - "VSTM %[c], { q4-q5 } \n\t" - "ADD %[c], %[c], #32 \n\t" + "VST1.8 { q4, q5 }, [%[c]]! \n\t" "SUBS %[bytes], %[bytes], #32 \n\t" "VMOV q0, q2 \n\t" "VMOV q1, q3 \n\t" @@ -2758,11 +2762,9 @@ static WC_INLINE void wc_Chacha_encrypt_64(const word32* input, const byte* m, /* XOR 16 bytes */ "CMP %[bytes], #16 \n\t" "BLT L_chacha20_arm32_64_lt_16_%= \n\t" - "VLDM %[m], { q4 } \n\t" - "ADD %[m], %[m], #16 \n\t" + "VLD1.8 { q4 }, [%[m]]! \n\t" "VEOR q4, q4, q0 \n\t" - "VSTM %[c], { q4 } \n\t" - "ADD %[c], %[c], #16 \n\t" + "VST1.8 { q4 }, [%[c]]! \n\t" "SUBS %[bytes], %[bytes], #16 \n\t" "VMOV q0, q1 \n\t" "BEQ L_chacha20_arm32_64_done_%= \n\t" @@ -2771,9 +2773,9 @@ static WC_INLINE void wc_Chacha_encrypt_64(const word32* input, const byte* m, /* XOR 8 bytes */ "CMP %[bytes], #8 \n\t" "BLT L_chacha20_arm32_64_lt_8_%= \n\t" - "VLD1.64 { d8 }, [%[m]]! \n\t" + "VLD1.8 { d8 }, [%[m]]! \n\t" "VEOR d8, d8, d0 \n\t" - "VST1.64 { d8 }, [%[c]]! \n\t" + "VST1.8 { d8 }, [%[c]]! \n\t" "SUBS %[bytes], %[bytes], #8 \n\t" "VMOV d0, d1 \n\t" "BEQ L_chacha20_arm32_64_done_%= \n\t" From 1fc67183a56b1a4cc2684e4a4a9537817b286f7e Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Sun, 28 Jan 2024 23:58:46 -0600 Subject: [PATCH 22/63] linuxkm: address peer review: * support AES_ENCRYPTION_AND_DECRYPTION only if WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS is defined, and define it in linuxkm_wc_port.h if LINUXKM_LKCAPI_REGISTER. * fix a typo in km_AesInitCommon(). * remove #if 0 code in lkcapi_glue.c. --- linuxkm/linuxkm_wc_port.h | 4 ++ linuxkm/lkcapi_glue.c | 26 ++++------ wolfcrypt/src/aes.c | 99 +++++++++++++++++++++++++++------------ wolfcrypt/test/test.c | 96 ++++++++++++++++++++++++++++++------- wolfssl/wolfcrypt/aes.h | 4 +- 5 files changed, 165 insertions(+), 64 deletions(-) diff --git a/linuxkm/linuxkm_wc_port.h b/linuxkm/linuxkm_wc_port.h index 16a07c628b..c197e5d9ec 100644 --- a/linuxkm/linuxkm_wc_port.h +++ b/linuxkm/linuxkm_wc_port.h @@ -269,6 +269,10 @@ #include #include #include + + #ifndef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS + #define WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS + #endif #endif #if defined(WOLFSSL_AESNI) || defined(USE_INTEL_SPEEDUP) || defined(WOLFSSL_SP_X86_64_ASM) diff --git a/linuxkm/lkcapi_glue.c b/linuxkm/lkcapi_glue.c index 6cf84d98cd..6757fa4e8d 100644 --- a/linuxkm/lkcapi_glue.c +++ b/linuxkm/lkcapi_glue.c @@ -134,7 +134,7 @@ static int km_AesInitCommon(struct km_AesCtx * ctx, const char * name, int need_ ctx->aes_decrypt = (Aes *)malloc(sizeof(*ctx->aes_decrypt)); - if (! ctx->aes_encrypt) { + if (! ctx->aes_decrypt) { pr_err("error: km_AesInitCommon %s failed: %d\n", name, MEMORY_E); km_AesExitCommon(ctx); return MEMORY_E; @@ -239,7 +239,7 @@ static int km_AesCbcEncrypt(struct skcipher_request *req) err = skcipher_walk_virt(&walk, req, false); - while ((nbytes = walk.nbytes)) { + while ((nbytes = walk.nbytes) != 0) { err = wc_AesSetIV(ctx->aes_encrypt, walk.iv); if (unlikely(err)) { @@ -274,7 +274,7 @@ static int km_AesCbcDecrypt(struct skcipher_request *req) err = skcipher_walk_virt(&walk, req, false); - while ((nbytes = walk.nbytes)) { + while ((nbytes = walk.nbytes) != 0) { err = wc_AesSetIV(ctx->aes_decrypt, walk.iv); if (unlikely(err)) { @@ -347,7 +347,7 @@ static int km_AesCfbEncrypt(struct skcipher_request *req) err = skcipher_walk_virt(&walk, req, false); - while ((nbytes = walk.nbytes)) { + while ((nbytes = walk.nbytes) != 0) { err = wc_AesSetIV(ctx->aes_encrypt, walk.iv); if (unlikely(err)) { @@ -382,7 +382,7 @@ static int km_AesCfbDecrypt(struct skcipher_request *req) err = skcipher_walk_virt(&walk, req, false); - while ((nbytes = walk.nbytes)) { + while ((nbytes = walk.nbytes) != 0) { err = wc_AesSetIV(ctx->aes_encrypt, walk.iv); if (unlikely(err)) { @@ -527,7 +527,7 @@ static int km_AesGcmEncrypt(struct aead_request *req) return err; } - while ((nbytes = walk.nbytes)) { + while ((nbytes = walk.nbytes) != 0) { int n = nbytes; if (likely(cryptLeft && nbytes)) { @@ -615,7 +615,7 @@ static int km_AesGcmDecrypt(struct aead_request *req) return err; } - while ((nbytes = walk.nbytes)) { + while ((nbytes = walk.nbytes) != 0) { int n = nbytes; if (likely(cryptLeft && nbytes)) { @@ -712,9 +712,6 @@ static void km_AesXtsExit(struct crypto_skcipher *tfm) wc_AesXtsFree(ctx->aesXts); free(ctx->aesXts); ctx->aesXts = NULL; -#if 0 - km_ForceZeroXts(ctx); -#endif } static int km_AesXtsSetKey(struct crypto_skcipher *tfm, const u8 *in_key, @@ -730,11 +727,6 @@ static int km_AesXtsSetKey(struct crypto_skcipher *tfm, const u8 *in_key, return err; } -#if 0 - XMEMCPY(ctx->key, in_key, key_len); - ctx->keylen = key_len; -#endif - return 0; } @@ -759,7 +751,7 @@ static int km_AesXtsEncrypt(struct skcipher_request *req) return err; } - while ((nbytes = walk.nbytes)) { + while ((nbytes = walk.nbytes) != 0) { err = wc_AesXtsEncrypt(ctx->aesXts, walk.dst.virt.addr, walk.src.virt.addr, nbytes, walk.iv, walk.ivsize); @@ -798,7 +790,7 @@ static int km_AesXtsDecrypt(struct skcipher_request *req) return err; } - while ((nbytes = walk.nbytes)) { + while ((nbytes = walk.nbytes) != 0) { err = wc_AesXtsDecrypt(ctx->aesXts, walk.dst.virt.addr, walk.src.virt.addr, nbytes, walk.iv, walk.ivsize); diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index bc32148728..72e1efeff9 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -12271,15 +12271,17 @@ int wc_AesXtsInit(XtsAes* aes, void* heap, int devId) if ((ret = wc_AesInit(&aes->tweak, heap, devId)) != 0) { return ret; } - if ((ret = wc_AesInit(&aes->aes_encrypt, heap, devId)) != 0) { + if ((ret = wc_AesInit(&aes->aes, heap, devId)) != 0) { (void)wc_AesFree(&aes->tweak); return ret; } +#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS if ((ret = wc_AesInit(&aes->aes_decrypt, heap, devId)) != 0) { (void)wc_AesFree(&aes->tweak); - (void)wc_AesFree(&aes->aes_encrypt); + (void)wc_AesFree(&aes->aes); return ret; } +#endif return 0; } @@ -12304,6 +12306,15 @@ int wc_AesXtsSetKeyNoInit(XtsAes* aes, const byte* key, word32 len, int dir) return BAD_FUNC_ARG; } + if ((dir != AES_ENCRYPTION) && (dir != AES_DECRYPTION) +#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS + && (dir != AES_ENCRYPTION_AND_DECRYPTION) +#endif + ) + { + return BAD_FUNC_ARG; + } + keySz = len/2; if (keySz != AES_128_KEY_SIZE && keySz != AES_256_KEY_SIZE) { WOLFSSL_MSG("Unsupported key size"); @@ -12318,10 +12329,15 @@ int wc_AesXtsSetKeyNoInit(XtsAes* aes, const byte* key, word32 len, int dir) #endif if ((dir == AES_ENCRYPTION) || (dir == AES_ENCRYPTION_AND_DECRYPTION)) - ret = wc_AesSetKey(&aes->aes_encrypt, key, keySz, NULL, AES_ENCRYPTION); + ret = wc_AesSetKey(&aes->aes, key, keySz, NULL, AES_ENCRYPTION); +#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS if ((ret == 0) && ((dir == AES_DECRYPTION) || (dir == AES_ENCRYPTION_AND_DECRYPTION))) ret = wc_AesSetKey(&aes->aes_decrypt, key, keySz, NULL, AES_DECRYPTION); +#else + if (dir == AES_DECRYPTION) + ret = wc_AesSetKey(&aes->aes, key, keySz, NULL, AES_DECRYPTION); +#endif if (ret == 0) ret = wc_AesSetKey(&aes->tweak, key + keySz, keySz, NULL, @@ -12334,13 +12350,19 @@ int wc_AesXtsSetKeyNoInit(XtsAes* aes, const byte* key, word32 len, int dir) * them to all be AESNI. If any aren't, disable AESNI on all. */ if ((((dir == AES_ENCRYPTION) || (dir == AES_ENCRYPTION_AND_DECRYPTION)) && - (aes->aes_encrypt.use_aesni != aes->tweak.use_aesni)) || + (aes->aes.use_aesni != aes->tweak.use_aesni)) +#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS + || (((dir == AES_DECRYPTION) || (dir == AES_ENCRYPTION_AND_DECRYPTION)) && - (aes->aes_decrypt.use_aesni != aes->tweak.use_aesni))) + (aes->aes_decrypt.use_aesni != aes->tweak.use_aesni)) +#endif + ) { #ifdef WC_AES_C_DYNAMIC_FALLBACK - aes->aes_encrypt.use_aesni = 0; + aes->aes.use_aesni = 0; +#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS aes->aes_decrypt.use_aesni = 0; +#endif aes->tweak.use_aesni = 0; #else ret = SYSLIB_FAILED_E; @@ -12389,8 +12411,10 @@ int wc_AesXtsSetKey(XtsAes* aes, const byte* key, word32 len, int dir, int wc_AesXtsFree(XtsAes* aes) { if (aes != NULL) { - wc_AesFree(&aes->aes_encrypt); + wc_AesFree(&aes->aes); +#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS wc_AesFree(&aes->aes_decrypt); +#endif wc_AesFree(&aes->tweak); } @@ -12547,7 +12571,7 @@ static int AesXtsEncrypt_sw(XtsAes* xaes, byte* out, const byte* in, word32 sz, { int ret = 0; word32 blocks = (sz / AES_BLOCK_SIZE); - Aes *aes = &xaes->aes_encrypt; + Aes *aes = &xaes->aes; Aes *tweak = &xaes->tweak; byte tmp[AES_BLOCK_SIZE]; @@ -12650,11 +12674,15 @@ int wc_AesXtsEncrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz, { int ret; + Aes *aes; + if (xaes == NULL || out == NULL || in == NULL) { return BAD_FUNC_ARG; } - if (xaes->aes_encrypt.keylen == 0) { + aes = &xaes->aes; + + if (aes->keylen == 0) { WOLFSSL_MSG("wc_AesXtsEncrypt called with unset encryption key."); return BAD_FUNC_ARG; } @@ -12671,33 +12699,33 @@ int wc_AesXtsEncrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz, { #ifdef WOLFSSL_AESNI #ifdef WC_AES_C_DYNAMIC_FALLBACK - int orig_use_aesni = xaes->aes_encrypt.use_aesni; + int orig_use_aesni = aes->use_aesni; #endif - if (xaes->aes_encrypt.use_aesni && ((ret = SAVE_VECTOR_REGISTERS2()) != 0)) { + if (aes->use_aesni && ((ret = SAVE_VECTOR_REGISTERS2()) != 0)) { #ifdef WC_AES_C_DYNAMIC_FALLBACK - xaes->aes_encrypt.use_aesni = 0; + aes->use_aesni = 0; xaes->tweak.use_aesni = 0; #else return ret; #endif } - if (xaes->aes_encrypt.use_aesni) { + if (aes->use_aesni) { #if defined(HAVE_INTEL_AVX1) if (IS_INTEL_AVX1(intel_flags)) { AES_XTS_encrypt_avx1(in, out, sz, i, - (const byte*)xaes->aes_encrypt.key, + (const byte*)aes->key, (const byte*)xaes->tweak.key, - (int)xaes->aes_encrypt.rounds); + (int)aes->rounds); ret = 0; } else #endif { AES_XTS_encrypt_aesni(in, out, sz, i, - (const byte*)xaes->aes_encrypt.key, + (const byte*)aes->key, (const byte*)xaes->tweak.key, - (int)xaes->aes_encrypt.rounds); + (int)aes->rounds); ret = 0; } } @@ -12708,11 +12736,11 @@ int wc_AesXtsEncrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz, } #ifdef WOLFSSL_AESNI - if (xaes->aes_encrypt.use_aesni) + if (aes->use_aesni) RESTORE_VECTOR_REGISTERS(); #ifdef WC_AES_C_DYNAMIC_FALLBACK else if (orig_use_aesni) { - xaes->aes_encrypt.use_aesni = orig_use_aesni; + aes->use_aesni = orig_use_aesni; xaes->tweak.use_aesni = orig_use_aesni; } #endif @@ -12738,7 +12766,11 @@ static int AesXtsDecrypt_sw(XtsAes* xaes, byte* out, const byte* in, word32 sz, { int ret = 0; word32 blocks = (sz / AES_BLOCK_SIZE); +#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS Aes *aes = &xaes->aes_decrypt; +#else + Aes *aes = &xaes->aes; +#endif Aes *tweak = &xaes->tweak; word32 j; byte carry = 0; @@ -12866,12 +12898,19 @@ int wc_AesXtsDecrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz, const byte* i, word32 iSz) { int ret; + Aes *aes; if (xaes == NULL || out == NULL || in == NULL) { return BAD_FUNC_ARG; } - if (xaes->aes_decrypt.keylen == 0) { +#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS + aes = &xaes->aes_decrypt; +#else + aes = &xaes->aes; +#endif + + if (aes->keylen == 0) { WOLFSSL_MSG("wc_AesXtsDecrypt called with unset decryption key."); return BAD_FUNC_ARG; } @@ -12888,33 +12927,33 @@ int wc_AesXtsDecrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz, { #ifdef WOLFSSL_AESNI #ifdef WC_AES_C_DYNAMIC_FALLBACK - int orig_use_aesni = xaes->aes_decrypt.use_aesni; + int orig_use_aesni = aes->use_aesni; #endif - if (xaes->aes_decrypt.use_aesni && ((ret = SAVE_VECTOR_REGISTERS2() != 0))) { + if (aes->use_aesni && ((ret = SAVE_VECTOR_REGISTERS2() != 0))) { #ifdef WC_AES_C_DYNAMIC_FALLBACK - xaes->aes_decrypt.use_aesni = 0; + aes->use_aesni = 0; xaes->tweak.use_aesni = 0; #else return ret; #endif } - if (xaes->aes_decrypt.use_aesni) { + if (aes->use_aesni) { #if defined(HAVE_INTEL_AVX1) if (IS_INTEL_AVX1(intel_flags)) { AES_XTS_decrypt_avx1(in, out, sz, i, - (const byte*)xaes->aes_decrypt.key, + (const byte*)aes->key, (const byte*)xaes->tweak.key, - (int)xaes->aes_decrypt.rounds); + (int)aes->rounds); ret = 0; } else #endif { AES_XTS_decrypt_aesni(in, out, sz, i, - (const byte*)xaes->aes_decrypt.key, + (const byte*)aes->key, (const byte*)xaes->tweak.key, - (int)xaes->aes_decrypt.rounds); + (int)aes->rounds); ret = 0; } } @@ -12925,11 +12964,11 @@ int wc_AesXtsDecrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz, } #ifdef WOLFSSL_AESNI - if (xaes->aes_decrypt.use_aesni) + if (aes->use_aesni) RESTORE_VECTOR_REGISTERS(); #ifdef WC_AES_C_DYNAMIC_FALLBACK else if (orig_use_aesni) { - xaes->aes_decrypt.use_aesni = orig_use_aesni; + aes->use_aesni = orig_use_aesni; xaes->tweak.use_aesni = orig_use_aesni; } #endif diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 7f50ee7c1f..e33909dbe2 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -9492,7 +9492,7 @@ static wc_test_ret_t aes_xts_128_test(void) ret = wc_AesXtsEncrypt(aes, buf, p2, sizeof(p2), i2, sizeof(i2)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -9503,7 +9503,7 @@ static wc_test_ret_t aes_xts_128_test(void) WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(SYSLIB_FAILED_E); ret = wc_AesXtsEncrypt(aes, buf, p2, sizeof(p2), i2, sizeof(i2)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(0); if (ret != 0) @@ -9519,7 +9519,7 @@ static wc_test_ret_t aes_xts_128_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsEncrypt(aes, buf, p1, sizeof(p1), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -9530,7 +9530,7 @@ static wc_test_ret_t aes_xts_128_test(void) WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(SYSLIB_FAILED_E); ret = wc_AesXtsEncrypt(aes, buf, p1, sizeof(p1), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(0); if (ret != 0) @@ -9543,7 +9543,7 @@ static wc_test_ret_t aes_xts_128_test(void) XMEMSET(cipher, 0, sizeof(cipher)); ret = wc_AesXtsEncrypt(aes, cipher, pp, sizeof(pp), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -9555,7 +9555,7 @@ static wc_test_ret_t aes_xts_128_test(void) XMEMSET(cipher, 0, sizeof(cipher)); ret = wc_AesXtsEncrypt(aes, cipher, pp, sizeof(pp), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(0); if (ret != 0) @@ -9571,7 +9571,11 @@ static wc_test_ret_t aes_xts_128_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecrypt(aes, buf, cipher, sizeof(pp), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) + #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); + #else + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + #endif #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -9583,7 +9587,11 @@ static wc_test_ret_t aes_xts_128_test(void) XMEMSET(buf, 0, sizeof(buf)); ret = wc_AesXtsDecrypt(aes, buf, cipher, sizeof(pp), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) + #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); + #else + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + #endif #endif WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(0); if (ret != 0) @@ -9596,7 +9604,11 @@ static wc_test_ret_t aes_xts_128_test(void) XMEMSET(buf, 0, sizeof(buf)); ret = wc_AesXtsDecrypt(aes, buf, c1, sizeof(c1), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) + #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); + #else + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + #endif #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -9608,7 +9620,11 @@ static wc_test_ret_t aes_xts_128_test(void) XMEMSET(buf, 0, sizeof(buf)); ret = wc_AesXtsDecrypt(aes, buf, c1, sizeof(c1), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) + #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); + #else + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + #endif #endif WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(0); if (ret != 0) @@ -9621,7 +9637,11 @@ static wc_test_ret_t aes_xts_128_test(void) XMEMSET(buf, 0, sizeof(buf)); ret = wc_AesXtsDecrypt(aes, buf, c2, sizeof(c2), i2, sizeof(i2)); #if defined(WOLFSSL_ASYNC_CRYPT) + #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); + #else + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + #endif #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -9635,7 +9655,11 @@ static wc_test_ret_t aes_xts_128_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecrypt(aes, buf, c2, sizeof(c2), i2, sizeof(i2)); #if defined(WOLFSSL_ASYNC_CRYPT) + #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); + #else + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + #endif #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -9652,7 +9676,7 @@ static wc_test_ret_t aes_xts_128_test(void) ret = wc_AesXtsEncrypt(aes, buf, buf, sizeof(p3), i3, sizeof(i3)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -9664,7 +9688,11 @@ static wc_test_ret_t aes_xts_128_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecrypt(aes, buf, buf, sizeof(c3), i3, sizeof(i3)); #if defined(WOLFSSL_ASYNC_CRYPT) + #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); + #else + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + #endif #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -9700,7 +9728,7 @@ static wc_test_ret_t aes_xts_128_test(void) ret = wc_AesXtsEncrypt(aes, large_input, large_input, j, i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -9711,7 +9739,11 @@ static wc_test_ret_t aes_xts_128_test(void) ret = wc_AesXtsDecrypt(aes, large_input, large_input, j, i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) + #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); + #else + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + #endif #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -9856,7 +9888,7 @@ static wc_test_ret_t aes_xts_256_test(void) ret = wc_AesXtsEncrypt(aes, buf, p2, sizeof(p2), i2, sizeof(i2)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -9869,7 +9901,7 @@ static wc_test_ret_t aes_xts_256_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsEncrypt(aes, buf, p1, sizeof(p1), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -9880,7 +9912,7 @@ static wc_test_ret_t aes_xts_256_test(void) XMEMSET(cipher, 0, sizeof(cipher)); ret = wc_AesXtsEncrypt(aes, cipher, pp, sizeof(pp), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -9892,7 +9924,11 @@ static wc_test_ret_t aes_xts_256_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecrypt(aes, buf, cipher, sizeof(pp), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) + #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); + #else + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + #endif #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -9903,7 +9939,11 @@ static wc_test_ret_t aes_xts_256_test(void) XMEMSET(buf, 0, sizeof(buf)); ret = wc_AesXtsDecrypt(aes, buf, c1, sizeof(c1), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) + #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); + #else + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + #endif #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -9916,7 +9956,11 @@ static wc_test_ret_t aes_xts_256_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecrypt(aes, buf, c2, sizeof(c2), i2, sizeof(i2)); #if defined(WOLFSSL_ASYNC_CRYPT) + #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); + #else + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + #endif #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -10133,7 +10177,7 @@ static wc_test_ret_t aes_xts_sector_test(void) ret = wc_AesXtsEncryptSector(aes, buf, p1, sizeof(p1), s1); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -10147,7 +10191,11 @@ static wc_test_ret_t aes_xts_sector_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecryptSector(aes, buf, c1, sizeof(c1), s1); #if defined(WOLFSSL_ASYNC_CRYPT) + #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); + #else + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + #endif #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -10161,7 +10209,7 @@ static wc_test_ret_t aes_xts_sector_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsEncryptSector(aes, buf, p2, sizeof(p2), s2); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -10175,7 +10223,11 @@ static wc_test_ret_t aes_xts_sector_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecryptSector(aes, buf, c2, sizeof(c2), s2); #if defined(WOLFSSL_ASYNC_CRYPT) + #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); + #else + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + #endif #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -10192,7 +10244,7 @@ static wc_test_ret_t aes_xts_sector_test(void) ret = wc_AesXtsEncryptConsecutiveSectors(aes, data, p3, sizeof(p3), s3, sectorSz); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -10207,7 +10259,11 @@ static wc_test_ret_t aes_xts_sector_test(void) ret = wc_AesXtsDecryptConsecutiveSectors(aes, data, c3, sizeof(c3), s3, sectorSz); #if defined(WOLFSSL_ASYNC_CRYPT) + #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); + #else + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + #endif #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -10286,14 +10342,14 @@ static wc_test_ret_t aes_xts_args_test(void) ret = wc_AesXtsEncryptSector(NULL, buf, p1, sizeof(p1), s1); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret == 0) ERROR_OUT(WC_TEST_RET_ENC_NC, out); ret = wc_AesXtsEncryptSector(aes, NULL, p1, sizeof(p1), s1); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret == 0) ERROR_OUT(WC_TEST_RET_ENC_NC, out); @@ -10304,14 +10360,22 @@ static wc_test_ret_t aes_xts_args_test(void) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ret = wc_AesXtsDecryptSector(NULL, buf, c1, sizeof(c1), s1); #if defined(WOLFSSL_ASYNC_CRYPT) + #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); + #else + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + #endif #endif if (ret == 0) ERROR_OUT(WC_TEST_RET_ENC_NC, out); ret = wc_AesXtsDecryptSector(aes, NULL, c1, sizeof(c1), s1); #if defined(WOLFSSL_ASYNC_CRYPT) + #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); + #else + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + #endif #endif if (ret == 0) ERROR_OUT(WC_TEST_RET_ENC_NC, out); diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index cb24bd36d6..7825c43dc8 100644 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -399,8 +399,10 @@ struct Aes { #ifdef WOLFSSL_AES_XTS typedef struct XtsAes { - Aes aes_encrypt; + Aes aes; +#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS Aes aes_decrypt; +#endif Aes tweak; } XtsAes; #endif From 856c9a9a7ff4562bf0872b83e1898f4ffe3f8995 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Mon, 29 Jan 2024 00:17:19 -0600 Subject: [PATCH 23/63] wolfcrypt/src/port/arm/armv8-aes.c: revert changes in a0415ce855. --- wolfcrypt/src/port/arm/armv8-aes.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/wolfcrypt/src/port/arm/armv8-aes.c b/wolfcrypt/src/port/arm/armv8-aes.c index 8430ec5191..455d30bba3 100644 --- a/wolfcrypt/src/port/arm/armv8-aes.c +++ b/wolfcrypt/src/port/arm/armv8-aes.c @@ -15624,7 +15624,7 @@ int wc_AesXtsEncrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz, : [blocks] "+r" (blocks), [in] "+r" (in), [out] "+r" (out), [sz] "+r" (sz) - : [key] "r" (xaes->aes_encrypt.key), [rounds] "r" (xaes->aes_encrypt.rounds), + : [key] "r" (xaes->aes.key), [rounds] "r" (xaes->aes.rounds), [key2] "r" (xaes->tweak.key), [i] "r" (i), [tmp] "r" (tmp) : "cc", "memory", @@ -15972,7 +15972,7 @@ int wc_AesXtsDecrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz, : [blocks] "+r" (blocks), [in] "+r" (in), [out] "+r" (out), [sz] "+r" (sz) - : [key] "r" (xaes->aes_decrypt.key), [rounds] "r" (xaes->aes_decrypt.rounds), + : [key] "r" (xaes->aes.key), [rounds] "r" (xaes->aes.rounds), [key2] "r" (xaes->tweak.key), [i] "r" (i), [tmp] "r" (tmp) : "cc", "memory", @@ -16298,7 +16298,7 @@ int wc_AesXtsEncrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz, : [blocks] "+r" (blocks), [in] "+r" (in), [out] "+r" (out), [sz] "+r" (sz), [i] "+r" (i), [key2] "+r" (key2) - : [key] "r" (xaes->aes_encrypt.key), [rounds] "r" (xaes->aes_encrypt.rounds), + : [key] "r" (xaes->aes.key), [rounds] "r" (xaes->aes.rounds), [tmp] "r" (tmp) : "cc", "memory", "r9", "r10", "r11", "r12", "r14", @@ -16455,7 +16455,7 @@ int wc_AesXtsDecrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz, : [blocks] "+r" (blocks), [in] "+r" (in), [out] "+r" (out), [sz] "+r" (sz), [i] "+r" (i), [key2] "+r" (key2) - : [key] "r" (xaes->aes_decrypt.key), [rounds] "r" (xaes->aes_decrypt.rounds), + : [key] "r" (xaes->aes.key), [rounds] "r" (xaes->aes.rounds), [tmp] "r" (tmp) : "cc", "memory", "r9", "r10", "r11", "r12", "r14", From 13591dcae8f7dde77c3ec04e88a131fa506a3ca3 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Mon, 29 Jan 2024 23:05:46 +1000 Subject: [PATCH 24/63] Regression testing fixes internal.c: NO_CERT, privateKeySz not used. ./configure --disable-shared --disable-asn --disable-rsa --disable-ecc --enable-psk sp_int.c: fix when sp_gcm is available ./configure --disable-shared --disable-shared --disable-ecc --disable-dh --disable-aes --disable-aesgcm --disable-sha512 --disable-sha384 --disable-sha --disable-poly1305 --disable-chacha --disable-md5 --disable-sha3 --enable-cryptonly --disable-inline --enable-rsavfy --disable-asn --disable-oaep --disable-rng --disable-filesystem --enable-sp=rsa2048 --disable-sp-asm --enable-sp-math --- src/internal.c | 2 ++ wolfcrypt/src/sp_int.c | 10 ++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/internal.c b/src/internal.c index b8fae80972..c61db68e1d 100644 --- a/src/internal.c +++ b/src/internal.c @@ -26623,6 +26623,8 @@ static int ParseCipherList(Suites* suites, suites->setSuites = 1; } + (void)privateKeySz; + return ret; } diff --git a/wolfcrypt/src/sp_int.c b/wolfcrypt/src/sp_int.c index dff11b4c06..3f8bfabfad 100644 --- a/wolfcrypt/src/sp_int.c +++ b/wolfcrypt/src/sp_int.c @@ -5408,7 +5408,8 @@ int sp_cmp_mag(const sp_int* a, const sp_int* b) #if defined(WOLFSSL_SP_MATH_ALL) || defined(HAVE_ECC) || !defined(NO_DSA) || \ defined(OPENSSL_EXTRA) || !defined(NO_DH) || \ - (!defined(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) + (!defined(NO_RSA) && (!defined(WOLFSSL_RSA_VERIFY_ONLY) || \ + defined(WOLFSSL_KEY_GEN))) /* Compare two multi-precision numbers. * * Assumes a and b are not NULL. @@ -19260,7 +19261,7 @@ int sp_prime_is_prime_ex(const sp_int* a, int trials, int* result, WC_RNG* rng) } #endif /* WOLFSSL_SP_PRIME_GEN */ -#if !defined(NO_RSA) || defined(WOLFSSL_KEY_GEN) +#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) /* Calculates the Greatest Common Denominator (GCD) of a and b into r. * @@ -19428,7 +19429,7 @@ int sp_gcd(const sp_int* a, const sp_int* b, sp_int* r) return err; } -#endif /* WOLFSSL_SP_MATH_ALL && !NO_RSA && WOLFSSL_KEY_GEN */ +#endif /* !NO_RSA && WOLFSSL_KEY_GEN */ #if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) && \ (!defined(WC_RSA_BLINDING) || defined(HAVE_FIPS) || defined(HAVE_SELFTEST)) @@ -19554,7 +19555,8 @@ int sp_lcm(const sp_int* a, const sp_int* b, sp_int* r) return err; } -#endif /* WOLFSSL_SP_MATH_ALL && !NO_RSA && WOLFSSL_KEY_GEN */ +#endif /* !NO_RSA && WOLFSSL_KEY_GEN && (!WC_RSA_BLINDING || HAVE_FIPS || + * HAVE_SELFTEST) */ /* Returns the run time settings. * From 920abd8b46d5004396bdab7480e6f1f5ddeca0c5 Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Mon, 29 Jan 2024 15:02:58 -0700 Subject: [PATCH 25/63] only download parts of zephyr sdk needed for test --- .github/workflows/zephyr.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/zephyr.yml b/.github/workflows/zephyr.yml index decdba2563..baad958afd 100644 --- a/.github/workflows/zephyr.yml +++ b/.github/workflows/zephyr.yml @@ -64,10 +64,10 @@ jobs: - name: Install zephyr SDK run: | - wget -q https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v${{ matrix.config.zephyr-sdk }}/zephyr-sdk-${{ matrix.config.zephyr-sdk }}_linux-x86_64.tar.xz - tar xf zephyr-sdk-${{ matrix.config.zephyr-sdk }}_linux-x86_64.tar.xz + wget -q https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v${{ matrix.config.zephyr-sdk }}/zephyr-sdk-${{ matrix.config.zephyr-sdk }}_linux-x86_64_minimal.tar.xz + tar xf zephyr-sdk-${{ matrix.config.zephyr-sdk }}_linux-x86_64_minimal.tar.xz cd zephyr-sdk-${{ matrix.config.zephyr-sdk }} - ./setup.sh -h -c + ./setup.sh -h -c -t x86_64-zephyr-elf - name: Run wolfssl test id: wolfssl-test From 6261108d498a9ca1339c2ac8948221ffa7aa94a4 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Mon, 29 Jan 2024 17:48:31 -0600 Subject: [PATCH 26/63] linuxkm: fix line lengths throughout; in linuxkm/lkcapi_glue.c: fix/harmonize error catching, reporting, and error codes; further address peer review feedback. --- linuxkm/linuxkm_wc_port.h | 62 +++- linuxkm/lkcapi_glue.c | 641 ++++++++++++++++++++++++-------------- linuxkm/module_hooks.c | 13 +- wolfcrypt/src/aes.c | 22 +- wolfcrypt/src/memory.c | 19 +- wolfcrypt/test/test.c | 3 +- wolfssl/wolfcrypt/aes.h | 2 + 7 files changed, 494 insertions(+), 268 deletions(-) diff --git a/linuxkm/linuxkm_wc_port.h b/linuxkm/linuxkm_wc_port.h index c197e5d9ec..6048589cb8 100644 --- a/linuxkm/linuxkm_wc_port.h +++ b/linuxkm/linuxkm_wc_port.h @@ -65,8 +65,8 @@ (int)_xatoi_res; \ }) - /* Kbuild+gcc on x86 doesn't consistently honor the default ALIGN16 on stack objects, - * but gives adequate alignment with "32". + /* Kbuild+gcc on x86 doesn't consistently honor the default ALIGN16 on stack + * objects, but gives adequate alignment with "32". */ #if defined(CONFIG_X86) && !defined(ALIGN16) #define ALIGN16 __attribute__ ( (aligned (32))) @@ -157,7 +157,9 @@ (sizeof(s) - 1) : strlen(s)) static inline void *my_memcpy(void *dest, const void *src, size_t n) { - if (! (((uintptr_t)dest | (uintptr_t)src | (uintptr_t)n) & (uintptr_t)(sizeof(uintptr_t) - 1))) { + if (! (((uintptr_t)dest | (uintptr_t)src | (uintptr_t)n) + & (uintptr_t)(sizeof(uintptr_t) - 1))) + { uintptr_t *src_longs = (uintptr_t *)src, *dest_longs = (uintptr_t *)dest, *endp = (uintptr_t *)((u8 *)src + n); @@ -176,13 +178,16 @@ #define memcpy my_memcpy static inline void *my_memset(void *dest, int c, size_t n) { - if (! (((uintptr_t)dest | (uintptr_t)n) & (uintptr_t)(sizeof(uintptr_t) - 1))) { + if (! (((uintptr_t)dest | (uintptr_t)n) + & (uintptr_t)(sizeof(uintptr_t) - 1))) + { uintptr_t c_long = __builtin_choose_expr( sizeof(uintptr_t) == 8, (uintptr_t)(u8)c * 0x0101010101010101UL, (uintptr_t)(u8)c * 0x01010101U ); - uintptr_t *dest_longs = (uintptr_t *)dest, *endp = (uintptr_t *)((u8 *)dest_longs + n); + uintptr_t *dest_longs = (uintptr_t *)dest, + *endp = (uintptr_t *)((u8 *)dest_longs + n); while (dest_longs < endp) *dest_longs++ = c_long; } else { @@ -196,8 +201,11 @@ #define memset my_memset static inline void *my_memmove(void *dest, const void *src, size_t n) { - if (! (((uintptr_t)dest | (uintptr_t)src | (uintptr_t)n) & (uintptr_t)(sizeof(uintptr_t) - 1))) { - uintptr_t *src_longs = (uintptr_t *)src, *dest_longs = (uintptr_t *)dest; + if (! (((uintptr_t)dest | (uintptr_t)src | (uintptr_t)n) + & (uintptr_t)(sizeof(uintptr_t) - 1))) + { + uintptr_t *src_longs = (uintptr_t *)src, + *dest_longs = (uintptr_t *)dest; n >>= __builtin_choose_expr( sizeof(uintptr_t) == 8, 3U, @@ -270,12 +278,26 @@ #include #include + /* the LKCAPI assumes that expanded encrypt and decrypt keys will stay + * loaded simultaneously, and the Linux in-tree implementations have two + * AES key structs in each context, one for each direction. in + * linuxkm/lkcapi_glue.c (used for CBC, CFB, and GCM), we do the same + * thing with "struct km_AesCtx". however, wolfCrypt struct AesXts + * already has two AES expanded keys, the main and tweak, and the tweak + * is always used in the encrypt direction regardless of the main + * direction. to avoid allocating and computing a duplicate second + * tweak encrypt key, we set + * WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS, which adds a second + * Aes slot to wolfCrypt's struct AesXts, and activates support for + * AES_ENCRYPTION_AND_DECRYPTION on AES-XTS. + */ #ifndef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS #define WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS #endif #endif - #if defined(WOLFSSL_AESNI) || defined(USE_INTEL_SPEEDUP) || defined(WOLFSSL_SP_X86_64_ASM) + #if defined(WOLFSSL_AESNI) || defined(USE_INTEL_SPEEDUP) || \ + defined(WOLFSSL_SP_X86_64_ASM) #ifndef CONFIG_X86 #error X86 SIMD extensions requested, but CONFIG_X86 is not set. #endif @@ -301,21 +323,35 @@ #endif #endif - /* benchmarks.c uses floating point math, so needs a working SAVE_VECTOR_REGISTERS(). */ - #if defined(WOLFSSL_LINUXKM_BENCHMARKS) && !defined(WOLFSSL_LINUXKM_USE_SAVE_VECTOR_REGISTERS) + /* benchmarks.c uses floating point math, so needs a working + * SAVE_VECTOR_REGISTERS(). + */ + #if defined(WOLFSSL_LINUXKM_BENCHMARKS) && \ + !defined(WOLFSSL_LINUXKM_USE_SAVE_VECTOR_REGISTERS) #define WOLFSSL_LINUXKM_USE_SAVE_VECTOR_REGISTERS #endif - #if defined(WOLFSSL_LINUXKM_USE_SAVE_VECTOR_REGISTERS) && defined(CONFIG_X86) + #if defined(WOLFSSL_LINUXKM_USE_SAVE_VECTOR_REGISTERS) && \ + defined(CONFIG_X86) #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0) #include #else #include #endif #ifndef SAVE_VECTOR_REGISTERS - #define SAVE_VECTOR_REGISTERS(fail_clause) { int _svr_ret = save_vector_registers_x86(); if (_svr_ret != 0) { fail_clause } } + #define SAVE_VECTOR_REGISTERS(fail_clause) { \ + int _svr_ret = save_vector_registers_x86(); \ + if (_svr_ret != 0) { \ + fail_clause \ + } \ + } #ifdef DEBUG_VECTOR_REGISTER_ACCESS_FUZZING - #define SAVE_VECTOR_REGISTERS2() ({ int _fuzzer_ret = SAVE_VECTOR_REGISTERS2_fuzzer(); (_fuzzer_ret == 0) ? save_vector_registers_x86() : _fuzzer_ret; }) + #define SAVE_VECTOR_REGISTERS2() ({ \ + int _fuzzer_ret = SAVE_VECTOR_REGISTERS2_fuzzer(); \ + (_fuzzer_ret == 0) ? \ + save_vector_registers_x86() : \ + _fuzzer_ret; \ + }) #else #define SAVE_VECTOR_REGISTERS2() save_vector_registers_x86() #endif diff --git a/linuxkm/lkcapi_glue.c b/linuxkm/lkcapi_glue.c index 6757fa4e8d..8ed9e5108e 100644 --- a/linuxkm/lkcapi_glue.c +++ b/linuxkm/lkcapi_glue.c @@ -24,7 +24,8 @@ #error lkcapi_glue.c included in non-LINUXKM_LKCAPI_REGISTER project. #endif -#if defined(LINUXKM_LKCAPI_REGISTER_AESGCM) && defined(WOLFSSL_AESNI) && defined(WC_AES_C_DYNAMIC_FALLBACK) +#if defined(LINUXKM_LKCAPI_REGISTER_AESGCM) && defined(WOLFSSL_AESNI) && \ + defined(WC_AES_C_DYNAMIC_FALLBACK) /* xxx temporary */ #error LINUXKM_LKCAPI_REGISTER_AESGCM is incompatible with WOLFSSL_AESNI && WC_AES_C_DYNAMIC_FALLBACK #endif @@ -65,7 +66,8 @@ #define WOLFKM_DRIVER_FIPS "" #endif -#define WOLFKM_DRIVER_SUFFIX WOLFKM_DRIVER_ISA_EXT WOLFKM_DRIVER_FIPS "-wolfcrypt" +#define WOLFKM_DRIVER_SUFFIX \ + WOLFKM_DRIVER_ISA_EXT WOLFKM_DRIVER_FIPS "-wolfcrypt" #define WOLFKM_AESCBC_DRIVER ("cbc-aes" WOLFKM_DRIVER_SUFFIX) #define WOLFKM_AESCFB_DRIVER ("cfb-aes" WOLFKM_DRIVER_SUFFIX) @@ -73,20 +75,24 @@ #define WOLFKM_AESXTS_DRIVER ("xts-aes" WOLFKM_DRIVER_SUFFIX) #if defined(HAVE_AES_CBC) && \ - (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESCBC)) + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || \ + defined(LINUXKM_LKCAPI_REGISTER_AESCBC)) static int linuxkm_test_aescbc(void); #endif #if defined(WOLFSSL_AES_CFB) && \ - (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESCFB)) + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || \ + defined(LINUXKM_LKCAPI_REGISTER_AESCFB)) static int linuxkm_test_aescfb(void); #endif #if defined(HAVE_AESGCM) && \ - (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESGCM)) && \ + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || \ + defined(LINUXKM_LKCAPI_REGISTER_AESGCM)) && \ (! (defined(WOLFSSL_AESNI) && defined(WC_AES_C_DYNAMIC_FALLBACK))) static int linuxkm_test_aesgcm(void); #endif #if defined(WOLFSSL_AES_XTS) && \ - (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESXTS)) + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || \ + defined(LINUXKM_LKCAPI_REGISTER_AESXTS)) static int linuxkm_test_aesxts(void); #endif @@ -96,7 +102,9 @@ static int linuxkm_test_aesxts(void); #include struct km_AesCtx { - Aes *aes_encrypt; /* must be pointer to control alignment, needed for AESNI. */ + Aes *aes_encrypt; /* allocated in km_AesInitCommon() to assure + * alignment, needed for AESNI. + */ Aes *aes_decrypt; /* same. */ }; @@ -107,24 +115,28 @@ struct km_AesCtx { static void km_AesExitCommon(struct km_AesCtx * ctx); -static int km_AesInitCommon(struct km_AesCtx * ctx, const char * name, int need_decryption) +static int km_AesInitCommon( + struct km_AesCtx * ctx, + const char * name, + int need_decryption) { int err; ctx->aes_encrypt = (Aes *)malloc(sizeof(*ctx->aes_encrypt)); if (! ctx->aes_encrypt) { - pr_err("error: km_AesInitCommon %s failed: %d\n", name, MEMORY_E); + pr_err("%s: allocation of %zu bytes for encryption key failed.\n", + name, sizeof(*ctx->aes_encrypt)); return MEMORY_E; } err = wc_AesInit(ctx->aes_encrypt, NULL, INVALID_DEVID); if (unlikely(err)) { - pr_err("error: km_AesInitCommon %s failed: %d\n", name, err); + pr_err("%s: wc_AesInit failed: %d\n", name, err); free(ctx->aes_encrypt); ctx->aes_encrypt = NULL; - return err; + return -EINVAL; } if (! need_decryption) { @@ -135,7 +147,8 @@ static int km_AesInitCommon(struct km_AesCtx * ctx, const char * name, int need_ ctx->aes_decrypt = (Aes *)malloc(sizeof(*ctx->aes_decrypt)); if (! ctx->aes_decrypt) { - pr_err("error: km_AesInitCommon %s failed: %d\n", name, MEMORY_E); + pr_err("%s: allocation of %zu bytes for decryption key failed.\n", + name, sizeof(*ctx->aes_decrypt)); km_AesExitCommon(ctx); return MEMORY_E; } @@ -143,11 +156,11 @@ static int km_AesInitCommon(struct km_AesCtx * ctx, const char * name, int need_ err = wc_AesInit(ctx->aes_decrypt, NULL, INVALID_DEVID); if (unlikely(err)) { - pr_err("error: km_AesInitCommon %s failed: %d\n", name, err); + pr_err("%s: wc_AesInit failed: %d\n", name, err); free(ctx->aes_decrypt); ctx->aes_decrypt = NULL; km_AesExitCommon(ctx); - return err; + return -EINVAL; } return 0; @@ -175,16 +188,18 @@ static int km_AesSetKeyCommon(struct km_AesCtx * ctx, const u8 *in_key, err = wc_AesSetKey(ctx->aes_encrypt, in_key, key_len, NULL, AES_ENCRYPTION); if (unlikely(err)) { - pr_err("error: km_AesSetKeyCommon %s failed: %d\n", name, err); - return err; + pr_err("%s: wc_AesSetKey for encryption key failed: %d\n", name, err); + return -ENOKEY; } if (ctx->aes_decrypt) { - err = wc_AesSetKey(ctx->aes_decrypt, in_key, key_len, NULL, AES_DECRYPTION); + err = wc_AesSetKey(ctx->aes_decrypt, in_key, key_len, NULL, + AES_DECRYPTION); if (unlikely(err)) { - pr_err("error: km_AesSetKeyCommon %s failed: %d\n", name, err); - return err; + pr_err("%s: wc_AesSetKey for decryption key failed: %d\n", + name, err); + return -ENOKEY; } } @@ -211,7 +226,8 @@ static void km_AesExit(struct crypto_skcipher *tfm) */ #if defined(HAVE_AES_CBC) && \ - (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESCBC)) + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || \ + defined(LINUXKM_LKCAPI_REGISTER_AESCBC)) static int km_AesCbcInit(struct crypto_skcipher *tfm) { @@ -239,23 +255,37 @@ static int km_AesCbcEncrypt(struct skcipher_request *req) err = skcipher_walk_virt(&walk, req, false); + if (unlikely(err)) { + pr_err("%s: skcipher_walk_virt failed: %d\n", + crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); + return err; + } + while ((nbytes = walk.nbytes) != 0) { err = wc_AesSetIV(ctx->aes_encrypt, walk.iv); if (unlikely(err)) { - pr_err("wc_AesSetIV failed: %d\n", err); - return err; + pr_err("%s: wc_AesSetIV failed: %d\n", + crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); + return -EINVAL; } err = wc_AesCbcEncrypt(ctx->aes_encrypt, walk.dst.virt.addr, walk.src.virt.addr, nbytes); if (unlikely(err)) { - pr_err("wc_AesCbcEncrypt failed %d\n", err); - return err; + pr_err("%s: wc_AesCbcEncrypt failed: %d\n", + crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); + return -EINVAL; } err = skcipher_walk_done(&walk, walk.nbytes - nbytes); + + if (unlikely(err)) { + pr_err("%s: skcipher_walk_done failed: %d\n", + crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); + return err; + } } return err; @@ -274,23 +304,37 @@ static int km_AesCbcDecrypt(struct skcipher_request *req) err = skcipher_walk_virt(&walk, req, false); + if (unlikely(err)) { + pr_err("%s: skcipher_walk_virt failed: %d\n", + crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); + return err; + } + while ((nbytes = walk.nbytes) != 0) { err = wc_AesSetIV(ctx->aes_decrypt, walk.iv); if (unlikely(err)) { - pr_err("wc_AesSetKey failed"); - return err; + pr_err("%s: wc_AesSetKey failed: %d\n", + crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); + return -EINVAL; } err = wc_AesCbcDecrypt(ctx->aes_decrypt, walk.dst.virt.addr, walk.src.virt.addr, nbytes); if (unlikely(err)) { - pr_err("wc_AesCbcDecrypt failed"); - return err; + pr_err("%s: wc_AesCbcDecrypt failed: %d\n", + crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); + return -EINVAL; } err = skcipher_walk_done(&walk, walk.nbytes - nbytes); + + if (unlikely(err)) { + pr_err("%s: skcipher_walk_done failed: %d\n", + crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); + return err; + } } return err; @@ -319,7 +363,8 @@ static int cbcAesAlg_loaded = 0; */ #if defined(WOLFSSL_AES_CFB) && \ - (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESCFB)) + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || \ + defined(LINUXKM_LKCAPI_REGISTER_AESCFB)) static int km_AesCfbInit(struct crypto_skcipher *tfm) { @@ -347,23 +392,37 @@ static int km_AesCfbEncrypt(struct skcipher_request *req) err = skcipher_walk_virt(&walk, req, false); + if (unlikely(err)) { + pr_err("%s: skcipher_walk_virt failed: %d\n", + crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); + return err; + } + while ((nbytes = walk.nbytes) != 0) { err = wc_AesSetIV(ctx->aes_encrypt, walk.iv); if (unlikely(err)) { - pr_err("wc_AesSetKey failed: %d\n", err); - return err; + pr_err("%s: wc_AesSetKey failed: %d\n", + crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); + return -EINVAL; } err = wc_AesCfbEncrypt(ctx->aes_encrypt, walk.dst.virt.addr, walk.src.virt.addr, nbytes); if (unlikely(err)) { - pr_err("wc_AesCfbEncrypt failed %d\n", err); - return err; + pr_err("%s: wc_AesCfbEncrypt failed %d\n", + crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); + return -EINVAL; } err = skcipher_walk_done(&walk, walk.nbytes - nbytes); + + if (unlikely(err)) { + pr_err("%s: skcipher_walk_done failed: %d\n", + crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); + return err; + } } return err; @@ -382,23 +441,37 @@ static int km_AesCfbDecrypt(struct skcipher_request *req) err = skcipher_walk_virt(&walk, req, false); + if (unlikely(err)) { + pr_err("%s: skcipher_walk_virt failed: %d\n", + crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); + return err; + } + while ((nbytes = walk.nbytes) != 0) { err = wc_AesSetIV(ctx->aes_encrypt, walk.iv); if (unlikely(err)) { - pr_err("wc_AesSetKey failed"); - return err; + pr_err("%s: wc_AesSetKey failed: %d\n", + crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); + return -EINVAL; } err = wc_AesCfbDecrypt(ctx->aes_encrypt, walk.dst.virt.addr, walk.src.virt.addr, nbytes); if (unlikely(err)) { - pr_err("wc_AesCfbDecrypt failed"); - return err; + pr_err("%s: wc_AesCfbDecrypt failed: %d\n", + crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); + return -EINVAL; } err = skcipher_walk_done(&walk, walk.nbytes - nbytes); + + if (unlikely(err)) { + pr_err("%s: skcipher_walk_done failed: %d\n", + crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); + return err; + } } return err; @@ -427,7 +500,8 @@ static int cfbAesAlg_loaded = 0; */ #if defined(HAVE_AESGCM) && \ - (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESGCM)) && \ + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || \ + defined(LINUXKM_LKCAPI_REGISTER_AESGCM)) && \ (! (defined(WOLFSSL_AESNI) && defined(WC_AES_C_DYNAMIC_FALLBACK))) static int km_AesGcmInit(struct crypto_aead * tfm) @@ -450,11 +524,13 @@ static int km_AesGcmSetKey(struct crypto_aead *tfm, const u8 *in_key, err = wc_AesGcmSetKey(ctx->aes_encrypt, in_key, key_len); - if (err) { - pr_err("error: km_AesGcmSetKey %s failed: %d\n", WOLFKM_AESGCM_DRIVER, err); + if (unlikely(err)) { + pr_err("%s: wc_AesGcmSetKey failed: %d\n", + crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)), err); + return -ENOKEY; } - return err; + return 0; } static int km_AesGcmSetAuthsize(struct crypto_aead *tfm, unsigned int authsize) @@ -462,7 +538,8 @@ static int km_AesGcmSetAuthsize(struct crypto_aead *tfm, unsigned int authsize) (void)tfm; if (authsize > AES_BLOCK_SIZE || authsize < WOLFSSL_MIN_AUTH_TAG_SZ) { - pr_err("error: invalid authsize: %d\n", authsize); + pr_err("%s: invalid authsize: %d\n", + crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)), authsize); return -EINVAL; } return 0; @@ -500,31 +577,37 @@ static int km_AesGcmEncrypt(struct aead_request *req) err = skcipher_walk_aead_encrypt(&walk, req, false); if (unlikely(err)) { - pr_err("error: skcipher_walk_aead_encrypt: %d\n", err); + pr_err("%s: skcipher_walk_aead_encrypt: %d\n", + crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)), err); return -1; } - err = wc_AesGcmInit(ctx->aes_encrypt, NULL /* key */, 0 /* keylen */, walk.iv, + err = wc_AesGcmInit(ctx->aes_encrypt, NULL /*key*/, 0 /*keylen*/, walk.iv, AES_BLOCK_SIZE); if (unlikely(err)) { - pr_err("error: wc_AesGcmInit failed with return code %d.\n", err); - return err; + pr_err("%s: wc_AesGcmInit failed: %d\n", + crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)), err); + return -EINVAL; } assoc = scatterwalk_map(&assocSgWalk); if (unlikely(IS_ERR(assoc))) { - pr_err("error: scatterwalk_map failed %ld\n", PTR_ERR(assoc)); + pr_err("%s: scatterwalk_map failed: %ld\n", + crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)), + PTR_ERR(assoc)); return err; } - err = wc_AesGcmEncryptUpdate(ctx->aes_encrypt, NULL, NULL, 0, assoc, assocLeft); + err = wc_AesGcmEncryptUpdate(ctx->aes_encrypt, NULL, NULL, 0, + assoc, assocLeft); assocLeft -= assocLeft; scatterwalk_unmap(assoc); assoc = NULL; if (unlikely(err)) { - pr_err("error: wc_AesGcmEncryptUpdate failed %d\n", err); - return err; + pr_err("%s: wc_AesGcmEncryptUpdate failed: %d\n", + crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)), err); + return -EINVAL; } while ((nbytes = walk.nbytes) != 0) { @@ -533,24 +616,36 @@ static int km_AesGcmEncrypt(struct aead_request *req) if (likely(cryptLeft && nbytes)) { n = cryptLeft < nbytes ? cryptLeft : nbytes; - err = wc_AesGcmEncryptUpdate(ctx->aes_encrypt, walk.dst.virt.addr, - walk.src.virt.addr, cryptLeft, NULL, 0); + err = wc_AesGcmEncryptUpdate( + ctx->aes_encrypt, + walk.dst.virt.addr, + walk.src.virt.addr, + cryptLeft, + NULL, 0); nbytes -= n; cryptLeft -= n; } if (unlikely(err)) { - pr_err("wc_AesGcmEncryptUpdate failed %d\n", err); - return err; + pr_err("%s: wc_AesGcmEncryptUpdate failed: %d\n", + crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)), err); + return -EINVAL; } err = skcipher_walk_done(&walk, nbytes); + + if (unlikely(err)) { + pr_err("%s: skcipher_walk_done failed: %d\n", + crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)), err); + return err; + } } err = wc_AesGcmEncryptFinal(ctx->aes_encrypt, authTag, tfm->authsize); if (unlikely(err)) { - pr_err("error: wc_AesGcmEncryptFinal failed with return code %d\n", err); - return err; + pr_err("%s: wc_AesGcmEncryptFinal failed with return code %d\n", + crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)), err); + return -EINVAL; } /* Now copy the auth tag into request scatterlist. */ @@ -588,31 +683,37 @@ static int km_AesGcmDecrypt(struct aead_request *req) err = skcipher_walk_aead_decrypt(&walk, req, false); if (unlikely(err)) { - pr_err("error: skcipher_walk_aead_decrypt: %d\n", err); - return -1; + pr_err("%s: skcipher_walk_aead_decrypt: %d\n", + crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)), err); + return err; } - err = wc_AesGcmInit(ctx->aes_encrypt, NULL /* key */, 0 /* keylen */, walk.iv, + err = wc_AesGcmInit(ctx->aes_encrypt, NULL /*key*/, 0 /*keylen*/, walk.iv, AES_BLOCK_SIZE); if (unlikely(err)) { - pr_err("error: wc_AesGcmInit failed with return code %d.\n", err); - return err; + pr_err("%s: wc_AesGcmInit failed: %d\n", + crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)), err); + return -EINVAL; } assoc = scatterwalk_map(&assocSgWalk); if (unlikely(IS_ERR(assoc))) { - pr_err("error: scatterwalk_map failed %ld\n", PTR_ERR(assoc)); + pr_err("%s: scatterwalk_map failed: %ld\n", + crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)), + PTR_ERR(assoc)); return err; } - err = wc_AesGcmDecryptUpdate(ctx->aes_encrypt, NULL, NULL, 0, assoc, assocLeft); + err = wc_AesGcmDecryptUpdate(ctx->aes_encrypt, NULL, NULL, 0, + assoc, assocLeft); assocLeft -= assocLeft; scatterwalk_unmap(assoc); assoc = NULL; if (unlikely(err)) { - pr_err("error: wc_AesGcmDecryptUpdate failed %d\n", err); - return err; + pr_err("%s: wc_AesGcmDecryptUpdate failed: %d\n", + crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)), err); + return -EINVAL; } while ((nbytes = walk.nbytes) != 0) { @@ -621,29 +722,41 @@ static int km_AesGcmDecrypt(struct aead_request *req) if (likely(cryptLeft && nbytes)) { n = cryptLeft < nbytes ? cryptLeft : nbytes; - err = wc_AesGcmDecryptUpdate(ctx->aes_encrypt, walk.dst.virt.addr, - walk.src.virt.addr, cryptLeft, NULL, 0); + err = wc_AesGcmDecryptUpdate( + ctx->aes_encrypt, + walk.dst.virt.addr, + walk.src.virt.addr, + cryptLeft, + NULL, 0); nbytes -= n; cryptLeft -= n; } if (unlikely(err)) { - pr_err("wc_AesGcmDecryptUpdate failed %d\n", err); - return err; + pr_err("%s: wc_AesGcmDecryptUpdate failed: %d\n", + crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)), err); + return -EINVAL; } err = skcipher_walk_done(&walk, nbytes); + + if (unlikely(err)) { + pr_err("%s: skcipher_walk_done failed: %d\n", + crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)), err); + return err; + } } err = wc_AesGcmDecryptFinal(ctx->aes_encrypt, origAuthTag, tfm->authsize); if (unlikely(err)) { - pr_err("error: wc_AesGcmDecryptFinal failed with return code %d\n", err); + pr_err("%s: wc_AesGcmDecryptFinal failed with return code %d\n", + crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)), err); if (err == AES_GCM_AUTH_E) { return -EBADMSG; } else { - return err; + return -EINVAL; } } @@ -675,10 +788,13 @@ static int gcmAesAead_loaded = 0; */ #if defined(WOLFSSL_AES_XTS) && \ - (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESXTS)) + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || \ + defined(LINUXKM_LKCAPI_REGISTER_AESXTS)) struct km_AesXtsCtx { - XtsAes *aesXts; /* allocated here, with correct alignment, for AESNI. */ + XtsAes *aesXts; /* allocated in km_AesXtsInitCommon() to assure alignment + * for AESNI. + */ }; static int km_AesXtsInitCommon(struct km_AesXtsCtx * ctx, const char * name) @@ -693,8 +809,8 @@ static int km_AesXtsInitCommon(struct km_AesXtsCtx * ctx, const char * name) err = wc_AesXtsInit(ctx->aesXts, NULL, INVALID_DEVID); if (unlikely(err)) { - pr_err("error: km_AesXtsInitCommon %s failed: %d\n", name, err); - return err; + pr_err("%s: km_AesXtsInitCommon failed: %d\n", name, err); + return -EINVAL; } return 0; @@ -720,11 +836,13 @@ static int km_AesXtsSetKey(struct crypto_skcipher *tfm, const u8 *in_key, int err; struct km_AesXtsCtx * ctx = crypto_skcipher_ctx(tfm); - err = wc_AesXtsSetKeyNoInit(ctx->aesXts, in_key, key_len, AES_ENCRYPTION_AND_DECRYPTION); + err = wc_AesXtsSetKeyNoInit(ctx->aesXts, in_key, key_len, + AES_ENCRYPTION_AND_DECRYPTION); if (unlikely(err)) { - pr_err("error: km_AesXtsSetKey %s failed: %d\n", WOLFKM_AESXTS_DRIVER, err); - return err; + pr_err("%s: wc_AesXtsSetKeyNoInit failed: %d\n", + crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); + return -EINVAL; } return 0; @@ -747,7 +865,8 @@ static int km_AesXtsEncrypt(struct skcipher_request *req) err = skcipher_walk_virt(&walk, req, false); if (unlikely(err)) { - pr_err("skcipher_walk_virt() failed: %d\n", err); + pr_err("%s: skcipher_walk_virt failed: %d\n", + crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); return err; } @@ -757,14 +876,16 @@ static int km_AesXtsEncrypt(struct skcipher_request *req) walk.iv, walk.ivsize); if (unlikely(err)) { - pr_err("wc_AesXtsEncrypt failed: %d\n", err); - return err; + pr_err("%s: wc_AesXtsEncrypt failed: %d\n", + crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); + return -EINVAL; } err = skcipher_walk_done(&walk, walk.nbytes - nbytes); if (unlikely(err)) { - pr_err("skcipher_walk_done() failed: %d\n", err); + pr_err("%s: skcipher_walk_done failed: %d\n", + crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); return err; } } @@ -786,7 +907,8 @@ static int km_AesXtsDecrypt(struct skcipher_request *req) err = skcipher_walk_virt(&walk, req, false); if (unlikely(err)) { - pr_err("skcipher_walk_virt() failed: %d\n", err); + pr_err("%s: skcipher_walk_virt failed: %d\n", + crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); return err; } @@ -796,14 +918,16 @@ static int km_AesXtsDecrypt(struct skcipher_request *req) walk.iv, walk.ivsize); if (unlikely(err)) { - pr_err("wc_AesCbcDecrypt failed"); - return err; + pr_err("%s: wc_AesCbcDecrypt failed: %d\n", + crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); + return -EINVAL; } err = skcipher_walk_done(&walk, walk.nbytes - nbytes); if (unlikely(err)) { - pr_err("skcipher_walk_done() failed: %d\n", err); + pr_err("%s: skcipher_walk_done failed: %d\n", + crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); return err; } } @@ -838,7 +962,8 @@ static int xtsAesAlg_loaded = 0; /* cipher tests, cribbed from test.c, with supplementary LKCAPI tests: */ #if defined(HAVE_AES_CBC) && \ - (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESCBC)) + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || \ + defined(LINUXKM_LKCAPI_REGISTER_AESCBC)) static int linuxkm_test_aescbc(void) { @@ -854,7 +979,8 @@ static int linuxkm_test_aescbc(void) 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66 }; - WOLFSSL_SMALL_STACK_STATIC const byte vector[] = /* Now is the time for all good men w/o trailing 0 */ + WOLFSSL_SMALL_STACK_STATIC const byte vector[] = + /* Now is the time for all good men w/o trailing 0 */ { 0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74, 0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20, @@ -862,7 +988,7 @@ static int linuxkm_test_aescbc(void) 0x67,0x6f,0x6f,0x64,0x20,0x6d,0x65,0x6e }; WOLFSSL_SMALL_STACK_STATIC const byte iv[] = "1234567890abcdef"; - byte iv_copy[sizeof iv]; + byte iv_copy[sizeof(iv)]; byte enc[sizeof(vector)]; byte dec[sizeof(vector)]; u8 * enc2 = NULL; @@ -874,19 +1000,19 @@ static int linuxkm_test_aescbc(void) ret = wc_AesInit(&aes, NULL, INVALID_DEVID); if (ret) { pr_err("wolfcrypt wc_AesInit failed with return code %d.\n", ret); - return -1; + return ret; } ret = wc_AesSetKey(&aes, key32, AES_BLOCK_SIZE * 2, iv, AES_ENCRYPTION); if (ret) { pr_err("wolfcrypt wc_AesSetKey failed with return code %d\n", ret); - return -1; + return ret; } ret = wc_AesCbcEncrypt(&aes, enc, vector, sizeof(vector)); if (ret) { pr_err("wolfcrypt wc_AesCbcEncrypt failed with return code %d\n", ret); - return -1; + return ret; } /* Re init for decrypt and set flag. */ @@ -895,25 +1021,25 @@ static int linuxkm_test_aescbc(void) ret = wc_AesInit(&aes, NULL, INVALID_DEVID); if (ret) { pr_err("wolfcrypt wc_AesInit failed with return code %d.\n", ret); - return -1; + return ret; } ret = wc_AesSetKey(&aes, key32, AES_BLOCK_SIZE * 2, iv, AES_DECRYPTION); if (ret) { pr_err("wolfcrypt wc_AesSetKey failed with return code %d.\n", ret); - return -1; + return ret; } ret = wc_AesCbcDecrypt(&aes, dec, enc, sizeof(vector)); if (ret) { pr_err("wolfcrypt wc_AesCbcDecrypt failed with return code %d\n", ret); - return -1; + return ret; } ret = XMEMCMP(vector, dec, sizeof(vector)); if (ret) { pr_err("error: vector and dec do not match: %d\n", ret); - return -1; + return ret; } /* now the kernel crypto part */ @@ -954,7 +1080,7 @@ static int linuxkm_test_aescbc(void) sg_init_one(&src, dec2, sizeof(vector)); sg_init_one(&dst, enc2, sizeof(vector)); - XMEMCPY(iv_copy, iv, sizeof iv); + XMEMCPY(iv_copy, iv, sizeof(iv)); skcipher_request_set_crypt(req, &src, &dst, sizeof(vector), iv_copy); ret = crypto_skcipher_encrypt(req); @@ -974,7 +1100,7 @@ static int linuxkm_test_aescbc(void) sg_init_one(&src, enc2, sizeof(vector)); sg_init_one(&dst, dec2, sizeof(vector)); - XMEMCPY(iv_copy, iv, sizeof iv); + XMEMCPY(iv_copy, iv, sizeof(iv)); skcipher_request_set_crypt(req, &src, &dst, sizeof(vector), iv_copy); ret = crypto_skcipher_decrypt(req); @@ -1005,7 +1131,8 @@ static int linuxkm_test_aescbc(void) */ #if defined(WOLFSSL_AES_CFB) && \ - (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESCFB)) + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || \ + defined(LINUXKM_LKCAPI_REGISTER_AESCFB)) static int linuxkm_test_aescfb(void) { @@ -1021,7 +1148,8 @@ static int linuxkm_test_aescfb(void) 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66 }; - WOLFSSL_SMALL_STACK_STATIC const byte vector[] = /* Now is the time for all good men w/o trailing 0 */ + WOLFSSL_SMALL_STACK_STATIC const byte vector[] = + /* Now is the time for all good men w/o trailing 0 */ { 0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74, 0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20, @@ -1029,7 +1157,7 @@ static int linuxkm_test_aescfb(void) 0x67,0x6f,0x6f,0x64,0x20,0x6d,0x65,0x6e }; WOLFSSL_SMALL_STACK_STATIC const byte iv[] = "1234567890abcdef"; - byte iv_copy[sizeof iv]; + byte iv_copy[sizeof(iv)]; byte enc[sizeof(vector)]; byte dec[sizeof(vector)]; u8 * enc2 = NULL; @@ -1041,19 +1169,19 @@ static int linuxkm_test_aescfb(void) ret = wc_AesInit(&aes, NULL, INVALID_DEVID); if (ret) { pr_err("wolfcrypt wc_AesInit failed with return code %d.\n", ret); - return -1; + return ret; } ret = wc_AesSetKey(&aes, key32, AES_BLOCK_SIZE * 2, iv, AES_ENCRYPTION); if (ret) { pr_err("wolfcrypt wc_AesSetKey failed with return code %d\n", ret); - return -1; + return ret; } ret = wc_AesCfbEncrypt(&aes, enc, vector, sizeof(vector)); if (ret) { pr_err("wolfcrypt wc_AesCfbEncrypt failed with return code %d\n", ret); - return -1; + return ret; } /* Re init for decrypt and set flag. */ @@ -1062,25 +1190,25 @@ static int linuxkm_test_aescfb(void) ret = wc_AesInit(&aes, NULL, INVALID_DEVID); if (ret) { pr_err("wolfcrypt wc_AesInit failed with return code %d.\n", ret); - return -1; + return ret; } ret = wc_AesSetKey(&aes, key32, AES_BLOCK_SIZE * 2, iv, AES_ENCRYPTION); if (ret) { pr_err("wolfcrypt wc_AesSetKey failed with return code %d.\n", ret); - return -1; + return ret; } ret = wc_AesCfbDecrypt(&aes, dec, enc, sizeof(vector)); if (ret) { pr_err("wolfcrypt wc_AesCfbDecrypt failed with return code %d\n", ret); - return -1; + return ret; } ret = XMEMCMP(vector, dec, sizeof(vector)); if (ret) { pr_err("error: vector and dec do not match: %d\n", ret); - return -1; + return ret; } /* now the kernel crypto part */ @@ -1121,7 +1249,7 @@ static int linuxkm_test_aescfb(void) sg_init_one(&src, dec2, sizeof(vector)); sg_init_one(&dst, enc2, sizeof(vector)); - XMEMCPY(iv_copy, iv, sizeof iv); + XMEMCPY(iv_copy, iv, sizeof(iv)); skcipher_request_set_crypt(req, &src, &dst, sizeof(vector), iv_copy); ret = crypto_skcipher_encrypt(req); @@ -1141,7 +1269,7 @@ static int linuxkm_test_aescfb(void) sg_init_one(&src, enc2, sizeof(vector)); sg_init_one(&dst, dec2, sizeof(vector)); - XMEMCPY(iv_copy, iv, sizeof iv); + XMEMCPY(iv_copy, iv, sizeof(iv)); skcipher_request_set_crypt(req, &src, &dst, sizeof(vector), iv_copy); ret = crypto_skcipher_decrypt(req); @@ -1172,7 +1300,8 @@ static int linuxkm_test_aescfb(void) */ #if defined(HAVE_AESGCM) && \ - (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESGCM)) && \ + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || \ + defined(LINUXKM_LKCAPI_REGISTER_AESGCM)) && \ (! (defined(WOLFSSL_AESNI) && defined(WC_AES_C_DYNAMIC_FALLBACK))) static int linuxkm_test_aesgcm(void) @@ -1190,7 +1319,8 @@ static int linuxkm_test_aesgcm(void) 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66 }; - WOLFSSL_SMALL_STACK_STATIC const byte vector[] = /* Now is the time for all w/o trailing 0 */ + WOLFSSL_SMALL_STACK_STATIC const byte vector[] = + /* Now is the time for all w/o trailing 0 */ { 0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74, 0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20, @@ -1233,19 +1363,22 @@ static int linuxkm_test_aesgcm(void) ret = wc_AesGcmEncryptUpdate(&aes, NULL, NULL, 0, assoc, sizeof(assoc)); if (ret) { - pr_err("error: wc_AesGcmEncryptUpdate failed with return code %d\n", ret); + pr_err("error: wc_AesGcmEncryptUpdate failed with return code %d\n", + ret); goto test_gcm_end; } ret = wc_AesGcmEncryptUpdate(&aes, enc, vector, sizeof(vector), NULL, 0); if (ret) { - pr_err("error: wc_AesGcmEncryptUpdate failed with return code %d\n", ret); + pr_err("error: wc_AesGcmEncryptUpdate failed with return code %d\n", + ret); goto test_gcm_end; } ret = wc_AesGcmEncryptFinal(&aes, authTag, AES_BLOCK_SIZE); if (ret) { - pr_err("error: wc_AesGcmEncryptFinal failed with return code %d\n", ret); + pr_err("error: wc_AesGcmEncryptFinal failed with return code %d\n", + ret); goto test_gcm_end; } @@ -1256,15 +1389,18 @@ static int linuxkm_test_aesgcm(void) goto test_gcm_end; } - ret = wc_AesGcmDecryptUpdate(&aes, dec, enc, sizeof(vector), assoc, sizeof(assoc)); + ret = wc_AesGcmDecryptUpdate(&aes, dec, enc, sizeof(vector), + assoc, sizeof(assoc)); if (ret) { - pr_err("error: wc_AesGcmDecryptUpdate failed with return code %d\n", ret); + pr_err("error: wc_AesGcmDecryptUpdate failed with return code %d\n", + ret); goto test_gcm_end; } ret = wc_AesGcmDecryptFinal(&aes, authTag, AES_BLOCK_SIZE); if (ret) { - pr_err("error: wc_AesGcmEncryptFinal failed with return code %d\n", ret); + pr_err("error: wc_AesGcmEncryptFinal failed with return code %d\n", + ret); goto test_gcm_end; } @@ -1413,7 +1549,8 @@ static int linuxkm_test_aesgcm(void) */ #if defined(WOLFSSL_AES_XTS) && \ - (defined(LINUXKM_LKCAPI_REGISTER_ALL) || defined(LINUXKM_LKCAPI_REGISTER_AESXTS)) + (defined(LINUXKM_LKCAPI_REGISTER_ALL) || \ + defined(LINUXKM_LKCAPI_REGISTER_AESXTS)) #ifndef HEAP_HINT #define HEAP_HINT NULL @@ -1423,20 +1560,17 @@ static int linuxkm_test_aesgcm(void) #define ERROR_OUT(err, eLabel) do { ret = (err); goto eLabel; } while (0) #endif -#ifndef WC_TEST_RET_ENC_EC -#define WC_TEST_RET_ENC_EC(ret) (ret) -#endif - -#ifndef WC_TEST_RET_ENC_NC -#define WC_TEST_RET_ENC_NC (-1) -#endif +/* note the FIPS code will be returned on failure even in non-FIPS builds. */ +#define LINUXKM_LKCAPI_AES_KAT_MISMATCH_E AES_KAT_FIPS_E #ifndef WC_USE_DEVID #define WC_USE_DEVID INVALID_DEVID #endif static const int devId = WC_USE_DEVID; -/* test vectors from http://csrc.nist.gov/groups/STM/cavp/block-cipher-modes.html */ +/* test vectors from + * http://csrc.nist.gov/groups/STM/cavp/block-cipher-modes.html + */ #ifdef WOLFSSL_AES_128 static int aes_xts_128_test(void) { @@ -1447,8 +1581,9 @@ static int aes_xts_128_test(void) #endif int aes_inited = 0; int ret = 0; - unsigned char buf[AES_BLOCK_SIZE * 2 + 8]; - unsigned char cipher[AES_BLOCK_SIZE * 2 + 8]; +#define AES_XTS_128_TEST_BUF_SIZ (AES_BLOCK_SIZE * 2 + 8) + unsigned char *buf = NULL; + unsigned char *cipher = NULL; /* 128 key tests */ WOLFSSL_SMALL_STACK_STATIC const unsigned char k1[] = { @@ -1480,6 +1615,7 @@ static int aes_xts_128_test(void) 0x82, 0x50, 0x81, 0xd5, 0xbe, 0x47, 0x1c, 0x63 }; + /* plain text test of partial block is not from NIST test vector list */ WOLFSSL_SMALL_STACK_STATIC const unsigned char cp[] = { 0x2b, 0xf7, 0x2c, 0xf3, 0xeb, 0x85, 0xef, 0x7b, 0x0b, 0x76, 0xa0, 0xaa, 0xf3, 0x3f, 0x25, 0x8b, @@ -1512,12 +1648,6 @@ static int aes_xts_128_test(void) 0xff, 0x8d, 0xbc, 0x1d, 0x9f, 0x7f, 0xc8, 0x22 }; - WOLFSSL_SMALL_STACK_STATIC const unsigned char cp2[] = { - 0x2b, 0xf7, 0x2c, 0xf3, 0xeb, 0x85, 0xef, 0x7b, - 0x0b, 0x76, 0xa0, 0xaa, 0xf3, 0x3f, 0x25, 0x8b, - 0x77, 0x8a, 0xe8, 0xb4, 0x3c, 0xb9, 0x8d, 0x5a - }; - #ifndef HAVE_FIPS_VERSION /* FIPS requires different keys for main and tweak. */ WOLFSSL_SMALL_STACK_STATIC const unsigned char k3[] = { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, @@ -1546,10 +1676,24 @@ static int aes_xts_128_test(void) #endif /* HAVE_FIPS_VERSION */ #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) - if ((aes = (XtsAes *)XMALLOC(sizeof *aes, HEAP_HINT, DYNAMIC_TYPE_AES)) == NULL) + if ((aes = (XtsAes *)XMALLOC(sizeof(*aes), HEAP_HINT, DYNAMIC_TYPE_AES)) + == NULL) + { ERROR_OUT(MEMORY_E, out); + } #endif + if ((buf = (unsigned char *)XMALLOC(AES_XTS_128_TEST_BUF_SIZ, HEAP_HINT, + DYNAMIC_TYPE_AES)) == NULL) + { + ERROR_OUT(MEMORY_E, out); + } + if ((cipher = (unsigned char *)XMALLOC(AES_XTS_128_TEST_BUF_SIZ, HEAP_HINT, + DYNAMIC_TYPE_AES)) == NULL) + { + ERROR_OUT(MEMORY_E, out); + } + #if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY) \ && !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS) ret = EVP_test(EVP_aes_128_xts(), k2, i2, p2, sizeof(p2), c2, sizeof(c2)); @@ -1559,25 +1703,25 @@ static int aes_xts_128_test(void) } #endif - XMEMSET(buf, 0, sizeof(buf)); + XMEMSET(buf, 0, AES_XTS_128_TEST_BUF_SIZ); ret = wc_AesXtsInit(aes, HEAP_HINT, devId); if (ret != 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ERROR_OUT(ret, out); else aes_inited = 1; ret = wc_AesXtsSetKeyNoInit(aes, k2, sizeof(k2), AES_ENCRYPTION); if (ret != 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ERROR_OUT(ret, out); ret = wc_AesXtsEncrypt(aes, buf, p2, sizeof(p2), i2, sizeof(i2)); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ERROR_OUT(ret, out); if (XMEMCMP(c2, buf, sizeof(c2))) - ERROR_OUT(WC_TEST_RET_ENC_NC, out); + ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); #if defined(DEBUG_VECTOR_REGISTER_ACCESS) && defined(WC_AES_C_DYNAMIC_FALLBACK) WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(SYSLIB_FAILED_E); @@ -1587,24 +1731,24 @@ static int aes_xts_128_test(void) #endif WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(0); if (ret != 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ERROR_OUT(ret, out); if (XMEMCMP(c2, buf, sizeof(c2))) - ERROR_OUT(WC_TEST_RET_ENC_NC, out); + ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); #endif - XMEMSET(buf, 0, sizeof(buf)); + XMEMSET(buf, 0, AES_XTS_128_TEST_BUF_SIZ); ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_ENCRYPTION); if (ret != 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ERROR_OUT(ret, out); ret = wc_AesXtsEncrypt(aes, buf, p1, sizeof(p1), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ERROR_OUT(ret, out); if (XMEMCMP(c1, buf, AES_BLOCK_SIZE)) - ERROR_OUT(WC_TEST_RET_ENC_NC, out); + ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); #if defined(DEBUG_VECTOR_REGISTER_ACCESS) && defined(WC_AES_C_DYNAMIC_FALLBACK) WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(SYSLIB_FAILED_E); @@ -1614,113 +1758,113 @@ static int aes_xts_128_test(void) #endif WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(0); if (ret != 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ERROR_OUT(ret, out); if (XMEMCMP(c1, buf, AES_BLOCK_SIZE)) - ERROR_OUT(WC_TEST_RET_ENC_NC, out); + ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); #endif /* partial block encryption test */ - XMEMSET(cipher, 0, sizeof(cipher)); + XMEMSET(cipher, 0, AES_XTS_128_TEST_BUF_SIZ); ret = wc_AesXtsEncrypt(aes, cipher, pp, sizeof(pp), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); - if (XMEMCMP(cp2, cipher, sizeof(cp2))) - ERROR_OUT(WC_TEST_RET_ENC_NC, out); + ERROR_OUT(ret, out); + if (XMEMCMP(cp, cipher, sizeof(cp))) + ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); #if defined(DEBUG_VECTOR_REGISTER_ACCESS) && defined(WC_AES_C_DYNAMIC_FALLBACK) WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(SYSLIB_FAILED_E); - XMEMSET(cipher, 0, sizeof(cipher)); + XMEMSET(cipher, 0, AES_XTS_128_TEST_BUF_SIZ); ret = wc_AesXtsEncrypt(aes, cipher, pp, sizeof(pp), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(0); if (ret != 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); - if (XMEMCMP(cp2, cipher, sizeof(cp2))) - ERROR_OUT(WC_TEST_RET_ENC_NC, out); + ERROR_OUT(ret, out); + if (XMEMCMP(cp, cipher, sizeof(cp))) + ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); #endif /* partial block decrypt test */ - XMEMSET(buf, 0, sizeof(buf)); + XMEMSET(buf, 0, AES_XTS_128_TEST_BUF_SIZ); ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_DECRYPTION); if (ret != 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ERROR_OUT(ret, out); ret = wc_AesXtsDecrypt(aes, buf, cipher, sizeof(pp), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ERROR_OUT(ret, out); if (XMEMCMP(pp, buf, sizeof(pp))) - ERROR_OUT(WC_TEST_RET_ENC_NC, out); + ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); #if defined(DEBUG_VECTOR_REGISTER_ACCESS) && defined(WC_AES_C_DYNAMIC_FALLBACK) WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(SYSLIB_FAILED_E); - XMEMSET(buf, 0, sizeof(buf)); + XMEMSET(buf, 0, AES_XTS_128_TEST_BUF_SIZ); ret = wc_AesXtsDecrypt(aes, buf, cipher, sizeof(pp), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(0); if (ret != 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ERROR_OUT(ret, out); if (XMEMCMP(pp, buf, sizeof(pp))) - ERROR_OUT(WC_TEST_RET_ENC_NC, out); + ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); #endif /* NIST decrypt test vector */ - XMEMSET(buf, 0, sizeof(buf)); + XMEMSET(buf, 0, AES_XTS_128_TEST_BUF_SIZ); ret = wc_AesXtsDecrypt(aes, buf, c1, sizeof(c1), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ERROR_OUT(ret, out); if (XMEMCMP(p1, buf, AES_BLOCK_SIZE)) - ERROR_OUT(WC_TEST_RET_ENC_NC, out); + ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); #if defined(DEBUG_VECTOR_REGISTER_ACCESS) && defined(WC_AES_C_DYNAMIC_FALLBACK) WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(SYSLIB_FAILED_E); - XMEMSET(buf, 0, sizeof(buf)); + XMEMSET(buf, 0, AES_XTS_128_TEST_BUF_SIZ); ret = wc_AesXtsDecrypt(aes, buf, c1, sizeof(c1), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(0); if (ret != 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ERROR_OUT(ret, out); if (XMEMCMP(p1, buf, AES_BLOCK_SIZE)) - ERROR_OUT(WC_TEST_RET_ENC_NC, out); + ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); #endif /* fail case with decrypting using wrong key */ - XMEMSET(buf, 0, sizeof(buf)); + XMEMSET(buf, 0, AES_XTS_128_TEST_BUF_SIZ); ret = wc_AesXtsDecrypt(aes, buf, c2, sizeof(c2), i2, sizeof(i2)); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ERROR_OUT(ret, out); if (XMEMCMP(p2, buf, sizeof(p2)) == 0) /* fail case with wrong key */ - ERROR_OUT(WC_TEST_RET_ENC_NC, out); + ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); /* set correct key and retest */ - XMEMSET(buf, 0, sizeof(buf)); + XMEMSET(buf, 0, AES_XTS_128_TEST_BUF_SIZ); ret = wc_AesXtsSetKeyNoInit(aes, k2, sizeof(k2), AES_DECRYPTION); if (ret != 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ERROR_OUT(ret, out); ret = wc_AesXtsDecrypt(aes, buf, c2, sizeof(c2), i2, sizeof(i2)); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ERROR_OUT(ret, out); if (XMEMCMP(p2, buf, sizeof(p2))) - ERROR_OUT(WC_TEST_RET_ENC_NC, out); + ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); #ifndef HAVE_FIPS_VERSION @@ -1728,28 +1872,28 @@ static int aes_xts_128_test(void) XMEMCPY(buf, p3, sizeof(p3)); ret = wc_AesXtsSetKeyNoInit(aes, k3, sizeof(k3), AES_ENCRYPTION); if (ret != 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ERROR_OUT(ret, out); ret = wc_AesXtsEncrypt(aes, buf, buf, sizeof(p3), i3, sizeof(i3)); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ERROR_OUT(ret, out); if (XMEMCMP(c3, buf, sizeof(c3))) - ERROR_OUT(WC_TEST_RET_ENC_NC, out); + ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); ret = wc_AesXtsSetKeyNoInit(aes, k3, sizeof(k3), AES_DECRYPTION); if (ret != 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ERROR_OUT(ret, out); ret = wc_AesXtsDecrypt(aes, buf, buf, sizeof(c3), i3, sizeof(i3)); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ERROR_OUT(ret, out); if (XMEMCMP(p3, buf, sizeof(p3))) - ERROR_OUT(WC_TEST_RET_ENC_NC, out); + ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); #endif /* HAVE_FIPS_VERSION */ @@ -1767,7 +1911,7 @@ static int aes_xts_128_test(void) int j; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) if (large_input == NULL) - ERROR_OUT(WC_TEST_RET_ENC_EC(MEMORY_E), out); + ERROR_OUT(MEMORY_E, out); #endif for (i = 0; i < (int)LARGE_XTS_SZ; i++) @@ -1776,28 +1920,30 @@ static int aes_xts_128_test(void) for (j = 16; j < (int)LARGE_XTS_SZ; j++) { ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_ENCRYPTION); if (ret != 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ERROR_OUT(ret, out); ret = wc_AesXtsEncrypt(aes, large_input, large_input, j, i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, + WC_ASYNC_FLAG_NONE); #endif if (ret != 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ERROR_OUT(ret, out); ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_DECRYPTION); if (ret != 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ERROR_OUT(ret, out); ret = wc_AesXtsDecrypt(aes, large_input, large_input, j, i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, + WC_ASYNC_FLAG_NONE); #endif if (ret != 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ERROR_OUT(ret, out); for (i = 0; i < j; i++) { if (large_input[i] != (byte)i) { - ERROR_OUT(WC_TEST_RET_ENC_NC, out); + ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); } } } @@ -1866,17 +2012,18 @@ static int aes_xts_128_test(void) } ret = crypto_skcipher_ivsize(tfm); - if (ret != sizeof iv) { + if (ret != sizeof(iv)) { pr_err("error: AES skcipher algorithm %s crypto_skcipher_ivsize()" " returned %d but expected %d\n", - WOLFKM_AESXTS_DRIVER, ret, (int)sizeof iv); + WOLFKM_AESXTS_DRIVER, ret, (int)sizeof(iv)); ret = -EINVAL; goto test_xts_end; } ret = crypto_skcipher_setkey(tfm, k1, sizeof(k1)); if (ret) { - pr_err("error: crypto_skcipher_setkey for %s returned: %d\n", WOLFKM_AESXTS_NAME, ret); + pr_err("error: crypto_skcipher_setkey for %s returned: %d\n", + WOLFKM_AESXTS_NAME, ret); goto test_xts_end; } @@ -1894,7 +2041,7 @@ static int aes_xts_128_test(void) sg_init_one(src, dec2, sizeof(p1)); sg_init_one(dst, enc2, sizeof(p1)); - memcpy(iv, i1, sizeof iv); + memcpy(iv, i1, sizeof(iv)); skcipher_request_set_crypt(req, src, dst, sizeof(p1), iv); ret = crypto_skcipher_encrypt(req); @@ -1904,7 +2051,7 @@ static int aes_xts_128_test(void) goto test_xts_end; } - ret = XMEMCMP(c1, enc2, sizeof(enc2)); + ret = XMEMCMP(c1, enc2, sizeof(c1)); if (ret) { pr_err("error: c1 and enc2 do not match: %d\n", ret); ret = -EINVAL; @@ -1915,7 +2062,7 @@ static int aes_xts_128_test(void) sg_init_one(src, enc2, sizeof(p1)); sg_init_one(dst, dec2, sizeof(p1)); - memcpy(iv, i1, sizeof iv); + memcpy(iv, i1, sizeof(iv)); skcipher_request_set_crypt(req, src, dst, sizeof(p1), iv); ret = crypto_skcipher_decrypt(req); @@ -1938,7 +2085,7 @@ static int aes_xts_128_test(void) sg_init_one(src, dec2, sizeof(pp)); sg_init_one(dst, enc2, sizeof(pp)); - memcpy(iv, i1, sizeof iv); + memcpy(iv, i1, sizeof(iv)); skcipher_request_set_crypt(req, src, dst, sizeof(pp), iv); ret = crypto_skcipher_encrypt(req); @@ -1959,7 +2106,7 @@ static int aes_xts_128_test(void) sg_init_one(src, enc2, sizeof(pp)); sg_init_one(dst, dec2, sizeof(pp)); - memcpy(iv, i1, sizeof iv); + memcpy(iv, i1, sizeof(iv)); skcipher_request_set_crypt(req, src, dst, sizeof(pp), iv); ret = crypto_skcipher_decrypt(req); @@ -1998,11 +2145,18 @@ static int aes_xts_128_test(void) if (aes_inited) wc_AesXtsFree(aes); + if (buf) + XFREE(buf, HEAP_HINT, DYNAMIC_TYPE_AES); + if (cipher) + XFREE(cipher, HEAP_HINT, DYNAMIC_TYPE_AES); + #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) if (aes) XFREE(aes, HEAP_HINT, DYNAMIC_TYPE_AES); #endif +#undef AES_XTS_128_TEST_BUF_SIZ + return ret; } #endif /* WOLFSSL_AES_128 */ @@ -2017,8 +2171,9 @@ static int aes_xts_256_test(void) #endif int aes_inited = 0; int ret = 0; - unsigned char buf[AES_BLOCK_SIZE * 3]; - unsigned char cipher[AES_BLOCK_SIZE * 3]; +#define AES_XTS_256_TEST_BUF_SIZ (AES_BLOCK_SIZE * 3) + unsigned char *buf = NULL; + unsigned char *cipher = NULL; /* 256 key tests */ WOLFSSL_SMALL_STACK_STATIC const unsigned char k1[] = { @@ -2099,10 +2254,24 @@ static int aes_xts_256_test(void) }; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) - if ((aes = (XtsAes *)XMALLOC(sizeof *aes, HEAP_HINT, DYNAMIC_TYPE_AES)) == NULL) + if ((aes = (XtsAes *)XMALLOC(sizeof(*aes), HEAP_HINT, DYNAMIC_TYPE_AES)) + == NULL) + { ERROR_OUT(MEMORY_E, out); + } #endif + if ((buf = (unsigned char *)XMALLOC(AES_XTS_256_TEST_BUF_SIZ, HEAP_HINT, + DYNAMIC_TYPE_AES)) == NULL) + { + ERROR_OUT(MEMORY_E, out); + } + if ((cipher = (unsigned char *)XMALLOC(AES_XTS_256_TEST_BUF_SIZ, HEAP_HINT, + DYNAMIC_TYPE_AES)) == NULL) + { + ERROR_OUT(MEMORY_E, out); + } + #if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY) \ && !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS) ret = EVP_test(EVP_aes_256_xts(), k2, i2, p2, sizeof(p2), c2, sizeof(c2)); @@ -2114,83 +2283,83 @@ static int aes_xts_256_test(void) ret = wc_AesXtsInit(aes, HEAP_HINT, devId); if (ret != 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ERROR_OUT(ret, out); else aes_inited = 1; - XMEMSET(buf, 0, sizeof(buf)); + XMEMSET(buf, 0, AES_XTS_256_TEST_BUF_SIZ); ret = wc_AesXtsSetKeyNoInit(aes, k2, sizeof(k2), AES_ENCRYPTION); if (ret != 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ERROR_OUT(ret, out); ret = wc_AesXtsEncrypt(aes, buf, p2, sizeof(p2), i2, sizeof(i2)); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ERROR_OUT(ret, out); if (XMEMCMP(c2, buf, sizeof(c2))) - ERROR_OUT(WC_TEST_RET_ENC_NC, out); + ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); - XMEMSET(buf, 0, sizeof(buf)); + XMEMSET(buf, 0, AES_XTS_256_TEST_BUF_SIZ); ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_ENCRYPTION); if (ret != 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ERROR_OUT(ret, out); ret = wc_AesXtsEncrypt(aes, buf, p1, sizeof(p1), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ERROR_OUT(ret, out); if (XMEMCMP(c1, buf, AES_BLOCK_SIZE)) - ERROR_OUT(WC_TEST_RET_ENC_NC, out); + ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); /* partial block encryption test */ - XMEMSET(cipher, 0, sizeof(cipher)); + XMEMSET(cipher, 0, AES_XTS_256_TEST_BUF_SIZ); ret = wc_AesXtsEncrypt(aes, cipher, pp, sizeof(pp), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ERROR_OUT(ret, out); /* partial block decrypt test */ - XMEMSET(buf, 0, sizeof(buf)); + XMEMSET(buf, 0, AES_XTS_256_TEST_BUF_SIZ); ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_DECRYPTION); if (ret != 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ERROR_OUT(ret, out); ret = wc_AesXtsDecrypt(aes, buf, cipher, sizeof(pp), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ERROR_OUT(ret, out); if (XMEMCMP(pp, buf, sizeof(pp))) - ERROR_OUT(WC_TEST_RET_ENC_NC, out); + ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); /* NIST decrypt test vector */ - XMEMSET(buf, 0, sizeof(buf)); + XMEMSET(buf, 0, AES_XTS_256_TEST_BUF_SIZ); ret = wc_AesXtsDecrypt(aes, buf, c1, sizeof(c1), i1, sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ERROR_OUT(ret, out); if (XMEMCMP(p1, buf, AES_BLOCK_SIZE)) - ERROR_OUT(WC_TEST_RET_ENC_NC, out); + ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); - XMEMSET(buf, 0, sizeof(buf)); + XMEMSET(buf, 0, AES_XTS_256_TEST_BUF_SIZ); ret = wc_AesXtsSetKeyNoInit(aes, k2, sizeof(k2), AES_DECRYPTION); if (ret != 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ERROR_OUT(ret, out); ret = wc_AesXtsDecrypt(aes, buf, c2, sizeof(c2), i2, sizeof(i2)); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + ERROR_OUT(ret, out); if (XMEMCMP(p2, buf, sizeof(p2))) - ERROR_OUT(WC_TEST_RET_ENC_NC, out); + ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); /* now the kernel crypto part */ @@ -2249,17 +2418,18 @@ static int aes_xts_256_test(void) } ret = crypto_skcipher_ivsize(tfm); - if (ret != sizeof iv) { + if (ret != sizeof(iv)) { pr_err("error: AES skcipher algorithm %s crypto_skcipher_ivsize()" " returned %d but expected %d\n", - WOLFKM_AESXTS_DRIVER, ret, (int)sizeof iv); + WOLFKM_AESXTS_DRIVER, ret, (int)sizeof(iv)); ret = -EINVAL; goto test_xts_end; } ret = crypto_skcipher_setkey(tfm, k1, sizeof(k1)); if (ret) { - pr_err("error: crypto_skcipher_setkey for %s returned: %d\n", WOLFKM_AESXTS_NAME, ret); + pr_err("error: crypto_skcipher_setkey for %s returned: %d\n", + WOLFKM_AESXTS_NAME, ret); goto test_xts_end; } @@ -2277,7 +2447,7 @@ static int aes_xts_256_test(void) sg_init_one(src, dec2, sizeof(p1)); sg_init_one(dst, enc2, sizeof(p1)); - memcpy(iv, i1, sizeof iv); + memcpy(iv, i1, sizeof(iv)); skcipher_request_set_crypt(req, src, dst, sizeof(p1), iv); ret = crypto_skcipher_encrypt(req); @@ -2287,7 +2457,7 @@ static int aes_xts_256_test(void) goto test_xts_end; } - ret = XMEMCMP(c1, enc2, sizeof(enc2)); + ret = XMEMCMP(c1, enc2, sizeof(c1)); if (ret) { pr_err("error: c1 and enc2 do not match: %d\n", ret); ret = -EINVAL; @@ -2298,7 +2468,7 @@ static int aes_xts_256_test(void) sg_init_one(src, enc2, sizeof(p1)); sg_init_one(dst, dec2, sizeof(p1)); - memcpy(iv, i1, sizeof iv); + memcpy(iv, i1, sizeof(iv)); skcipher_request_set_crypt(req, src, dst, sizeof(p1), iv); ret = crypto_skcipher_decrypt(req); @@ -2321,7 +2491,7 @@ static int aes_xts_256_test(void) sg_init_one(src, dec2, sizeof(pp)); sg_init_one(dst, enc2, sizeof(pp)); - memcpy(iv, i1, sizeof iv); + memcpy(iv, i1, sizeof(iv)); skcipher_request_set_crypt(req, src, dst, sizeof(pp), iv); ret = crypto_skcipher_encrypt(req); @@ -2342,7 +2512,7 @@ static int aes_xts_256_test(void) sg_init_one(src, enc2, sizeof(pp)); sg_init_one(dst, dec2, sizeof(pp)); - memcpy(iv, i1, sizeof iv); + memcpy(iv, i1, sizeof(iv)); skcipher_request_set_crypt(req, src, dst, sizeof(pp), iv); ret = crypto_skcipher_decrypt(req); @@ -2381,11 +2551,18 @@ static int aes_xts_256_test(void) if (aes_inited) wc_AesXtsFree(aes); + if (buf) + XFREE(buf, HEAP_HINT, DYNAMIC_TYPE_AES); + if (cipher) + XFREE(cipher, HEAP_HINT, DYNAMIC_TYPE_AES); + #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) if (aes) XFREE(aes, HEAP_HINT, DYNAMIC_TYPE_AES); #endif +#undef AES_XTS_256_TEST_BUF_SIZ + return ret; } #endif /* WOLFSSL_AES_256 */ diff --git a/linuxkm/module_hooks.c b/linuxkm/module_hooks.c index ce9371ef2c..6c5a62ce7f 100644 --- a/linuxkm/module_hooks.c +++ b/linuxkm/module_hooks.c @@ -245,7 +245,8 @@ static int wolfssl_init(void) return -ECANCELED; } - pr_info("FIPS 140-3 wolfCrypt-fips v%d.%d.%d%s%s startup self-test succeeded.\n", + pr_info("FIPS 140-3 wolfCrypt-fips v%d.%d.%d%s%s startup " + "self-test succeeded.\n", #ifdef HAVE_FIPS_VERSION_MAJOR HAVE_FIPS_VERSION_MAJOR, #else @@ -306,7 +307,8 @@ static int wolfssl_init(void) } pr_info("wolfCrypt self-test passed.\n"); #else - pr_info("skipping full wolfcrypt_test() (configure with --enable-crypttests to enable).\n"); + pr_info("skipping full wolfcrypt_test() " + "(configure with --enable-crypttests to enable).\n"); #endif #ifdef LINUXKM_LKCAPI_REGISTER @@ -559,12 +561,15 @@ static int set_up_wolfssl_linuxkm_pie_redirect_table(void) { /* runtime assert that the table has no null slots after initialization. */ { unsigned long *i; + static_assert(sizeof(unsigned long) == sizeof(void *), + "unexpected pointer size"); for (i = (unsigned long *)&wolfssl_linuxkm_pie_redirect_table; i < (unsigned long *)&wolfssl_linuxkm_pie_redirect_table._last_slot; ++i) if (*i == 0) { - pr_err("wolfCrypt container redirect table initialization was incomplete [%lu].\n", - i - (unsigned long *)&wolfssl_linuxkm_pie_redirect_table); + pr_err("wolfCrypt container redirect table initialization was " + "incomplete [%lu].\n", + i-(unsigned long *)&wolfssl_linuxkm_pie_redirect_table); return -EFAULT; } } diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 72e1efeff9..4a4afe90a3 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -12321,18 +12321,25 @@ int wc_AesXtsSetKeyNoInit(XtsAes* aes, const byte* key, word32 len, int dir) return WC_KEY_SIZE_E; } -#ifdef HAVE_FIPS_VERSION +#ifdef HAVE_FIPS if (XMEMCMP(key, key + keySz, keySz) == 0) { WOLFSSL_MSG("FIPS AES-XTS main and tweak keys must differ"); return BAD_FUNC_ARG; } #endif - if ((dir == AES_ENCRYPTION) || (dir == AES_ENCRYPTION_AND_DECRYPTION)) + if ((dir == AES_ENCRYPTION) +#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS + || (dir == AES_ENCRYPTION_AND_DECRYPTION) +#endif + ) + { ret = wc_AesSetKey(&aes->aes, key, keySz, NULL, AES_ENCRYPTION); + } #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS - if ((ret == 0) && ((dir == AES_DECRYPTION) || (dir == AES_ENCRYPTION_AND_DECRYPTION))) + if ((ret == 0) && ((dir == AES_DECRYPTION) + || (dir == AES_ENCRYPTION_AND_DECRYPTION))) ret = wc_AesSetKey(&aes->aes_decrypt, key, keySz, NULL, AES_DECRYPTION); #else if (dir == AES_DECRYPTION) @@ -12349,11 +12356,16 @@ int wc_AesXtsSetKeyNoInit(XtsAes* aes, const byte* key, word32 len, int dir) * conflicting _aesni status, but the AES-XTS asm implementations need * them to all be AESNI. If any aren't, disable AESNI on all. */ - if ((((dir == AES_ENCRYPTION) || (dir == AES_ENCRYPTION_AND_DECRYPTION)) && + if ((((dir == AES_ENCRYPTION) +#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS + || (dir == AES_ENCRYPTION_AND_DECRYPTION) +#endif + ) && (aes->aes.use_aesni != aes->tweak.use_aesni)) #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS || - (((dir == AES_DECRYPTION) || (dir == AES_ENCRYPTION_AND_DECRYPTION)) && + (((dir == AES_DECRYPTION) + || (dir == AES_ENCRYPTION_AND_DECRYPTION)) && (aes->aes_decrypt.use_aesni != aes->tweak.use_aesni)) #endif ) diff --git a/wolfcrypt/src/memory.c b/wolfcrypt/src/memory.c index c4cbeabfc0..c01af6272a 100644 --- a/wolfcrypt/src/memory.c +++ b/wolfcrypt/src/memory.c @@ -1560,25 +1560,18 @@ WOLFSSL_LOCAL int SAVE_VECTOR_REGISTERS2_fuzzer(void) { */ /* barrel-roll using the bottom 6 bits. */ if (new_prn & 0x3f) - new_prn = (new_prn << (new_prn & 0x3f)) | (new_prn >> (0x40 - (new_prn & 0x3f))); + new_prn = (new_prn << (new_prn & 0x3f)) | + (new_prn >> (0x40 - (new_prn & 0x3f))); prn = new_prn; balance_bit = !balance_bit; - if (balance_bit) { - if (prn & 1) - return IO_FAILED_E; - else - return 0; - } else { - if (prn & 1) - return 0; - else - return IO_FAILED_E; - } + return ((prn & 1) ^ balance_bit) ? IO_FAILED_E : 0; } -#endif /* DEBUG_VECTOR_REGISTER_ACCESS || DEBUG_VECTOR_REGISTER_ACCESS_FUZZING */ +#endif /* DEBUG_VECTOR_REGISTER_ACCESS || + * DEBUG_VECTOR_REGISTER_ACCESS_FUZZING + */ #ifdef WOLFSSL_LINUXKM #include "../../linuxkm/linuxkm_memory.c" diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index e33909dbe2..b878869317 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -9740,7 +9740,8 @@ static wc_test_ret_t aes_xts_128_test(void) sizeof(i1)); #if defined(WOLFSSL_ASYNC_CRYPT) #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS - ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); + ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, + WC_ASYNC_FLAG_NONE); #else ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index 7825c43dc8..1c369cef50 100644 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -179,7 +179,9 @@ enum { AES_ENC_TYPE = WC_CIPHER_AES, /* cipher unique type */ AES_ENCRYPTION = 0, AES_DECRYPTION = 1, +#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS AES_ENCRYPTION_AND_DECRYPTION = 2, +#endif AES_BLOCK_SIZE = 16, From 11e8a89f67223be0326f89be2748c9a506e3e32e Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Mon, 29 Jan 2024 17:58:13 -0600 Subject: [PATCH 27/63] wolfcrypt/src/aes.c: coddle XCode (clang) to clear frivolous -Wparentheses-equality. --- wolfcrypt/src/aes.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 4a4afe90a3..510e395dd7 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -12328,9 +12328,9 @@ int wc_AesXtsSetKeyNoInit(XtsAes* aes, const byte* key, word32 len, int dir) } #endif - if ((dir == AES_ENCRYPTION) + if (dir == AES_ENCRYPTION #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS - || (dir == AES_ENCRYPTION_AND_DECRYPTION) + || dir == AES_ENCRYPTION_AND_DECRYPTION #endif ) { From 67bbe1e1bbb632abf3aaaae532606cc34d671c0c Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Mon, 29 Jan 2024 22:00:20 -0600 Subject: [PATCH 28/63] wolfcrypt/src/rsa.c: in wc_RsaFunction_ex(), if defined(WOLF_CRYPTO_CB_ONLY_RSA), add clause to return NO_VALID_DEVID if key->devId == INVALID_DEVID. fixes "control reaches end of non-void function" in PRB-single-flag.txt. --- wolfcrypt/src/rsa.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index 301139df24..56a6efa833 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -3141,7 +3141,9 @@ static int wc_RsaFunction_ex(const byte* in, word32 inLen, byte* out, } #endif -#ifndef WOLF_CRYPTO_CB_ONLY_RSA +#ifdef WOLF_CRYPTO_CB_ONLY_RSA + return NO_VALID_DEVID; +#else /* !WOLF_CRYPTO_CB_ONLY_RSA */ SAVE_VECTOR_REGISTERS(return _svr_ret;); #if !defined(WOLFSSL_RSA_VERIFY_ONLY) && !defined(TEST_UNPAD_CONSTANT_TIME) && \ @@ -3192,7 +3194,7 @@ static int wc_RsaFunction_ex(const byte* in, word32 inLen, byte* out, wc_RsaCleanup(key); } return ret; -#endif /* WOLF_CRYPTO_CB_ONLY_RSA */ +#endif /* !WOLF_CRYPTO_CB_ONLY_RSA */ } int wc_RsaFunction(const byte* in, word32 inLen, byte* out, From 3d3c07944e60f7b2d87a3c34f89d8a14b8466d44 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Mon, 29 Jan 2024 22:30:33 -0600 Subject: [PATCH 29/63] wolfcrypt/src/ecc.c: fix logic around WOLF_CRYPTO_CB_ONLY_ECC in wc_ecc_shared_secret(), _ecc_make_key_ex(), wc_ecc_sign_hash(), and wc_ecc_verify_hash() (defects reported by -Wreturn-type, -Wmaybe-uninitialized around err, and a failure of ecc_onlycb_test()). --- wolfcrypt/src/ecc.c | 78 +++++++++++++++------------------------------ 1 file changed, 26 insertions(+), 52 deletions(-) diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 9d028d7457..fcbe8e7761 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -4570,20 +4570,15 @@ int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out, #endif { err = wc_CryptoCb_Ecdh(private_key, public_key, out, outlen); - #ifndef WOLF_CRYPTO_CB_ONLY_ECC if (err != CRYPTOCB_UNAVAILABLE) return err; /* fall-through when unavailable */ - #endif - #ifdef WOLF_CRYPTO_CB_ONLY_ECC - if (err == CRYPTOCB_UNAVAILABLE) { - err = NO_VALID_DEVID; - } - #endif } #endif -#ifndef WOLF_CRYPTO_CB_ONLY_ECC +#ifdef WOLF_CRYPTO_CB_ONLY_ECC + return NO_VALID_DEVID; +#else /* !WOLF_CRYPTO_CB_ONLY_ECC */ /* type valid? */ if (private_key->type != ECC_PRIVATEKEY && private_key->type != ECC_PRIVATEKEY_ONLY) { @@ -4632,7 +4627,7 @@ int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out, #else err = wc_ecc_shared_secret_ex(private_key, &public_key->pubkey, out, outlen); #endif /* WOLFSSL_ATECC508A */ -#endif /* WOLF_CRYPTO_CB_ONLY_ECC */ +#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */ return err; } @@ -5529,21 +5524,15 @@ static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, #endif { err = wc_CryptoCb_MakeEccKey(rng, keysize, key, curve_id); - #ifndef WOLF_CRYPTO_CB_ONLY_ECC if (err != CRYPTOCB_UNAVAILABLE) return err; /* fall-through when unavailable */ - #endif - #ifdef WOLF_CRYPTO_CB_ONLY_ECC - if (err == CRYPTOCB_UNAVAILABLE) { - return NO_VALID_DEVID; - } - return err; - #endif } #endif -#ifndef WOLF_CRYPTO_CB_ONLY_ECC +#ifdef WOLF_CRYPTO_CB_ONLY_ECC + return NO_VALID_DEVID; +#else /* !WOLF_CRYPTO_CB_ONLY_ECC */ #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) { #ifdef HAVE_CAVIUM @@ -5859,7 +5848,7 @@ static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, #endif /* HAVE_ECC_MAKE_PUB */ return err; -#endif /* WOLF_CRYPTO_CB_ONLY_ECC */ +#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */ } @@ -6563,20 +6552,20 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen, #endif { err = wc_CryptoCb_EccSign(in, inlen, out, outlen, rng, key); - #ifndef WOLF_CRYPTO_CB_ONLY_ECC if (err != CRYPTOCB_UNAVAILABLE) return err; /* fall-through when unavailable */ - #endif - #ifdef WOLF_CRYPTO_CB_ONLY_ECC - if (err == CRYPTOCB_UNAVAILABLE) { - err = NO_VALID_DEVID; - } - #endif } #endif -#ifndef WOLF_CRYPTO_CB_ONLY_ECC +#ifdef WOLF_CRYPTO_CB_ONLY_ECC + (void)rng; + (void)inlen; + (void)s; + (void)r; + (void)err; + return NO_VALID_DEVID; +#else /* !WOLF_CRYPTO_CB_ONLY_ECC */ if (rng == NULL) { WOLFSSL_MSG("ECC sign RNG missing"); return ECC_BAD_ARG_E; @@ -6640,15 +6629,8 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen, FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC); FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC); #endif /* WOLFSSL_ASYNC_CRYPT */ -#else - (void)rng; - (void)inlen; - (void)s; - (void)r; - (void)err; -#endif /* WOLF_CRYPTO_CB_ONLY_ECC */ - return err; +#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */ } #endif /* !NO_ASN */ @@ -8289,21 +8271,20 @@ int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash, #endif { err = wc_CryptoCb_EccVerify(sig, siglen, hash, hashlen, res, key); - #ifndef WOLF_CRYPTO_CB_ONLY_ECC if (err != CRYPTOCB_UNAVAILABLE) return err; /* fall-through when unavailable */ - #endif - #ifdef WOLF_CRYPTO_CB_ONLY_ECC - if (err == CRYPTOCB_UNAVAILABLE) { - err = NO_VALID_DEVID; - } - #endif } #endif -#ifndef WOLF_CRYPTO_CB_ONLY_ECC - +#ifdef WOLF_CRYPTO_CB_ONLY_ECC + (void)siglen; + (void)hashlen; + (void)s; + (void)r; + (void)err; + return NO_VALID_DEVID; +#else /* !WOLF_CRYPTO_CB_ONLY_ECC */ #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) err = wc_ecc_alloc_async(key); if (err != 0) @@ -8415,15 +8396,8 @@ int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash, /* make sure required variables are reset */ wc_ecc_reset(key); -#else - (void)siglen; - (void)hashlen; - (void)s; - (void)r; - (void)err; -#endif /* WOLF_CRYPTO_CB_ONLY_ECC */ - return err; +#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */ } #endif /* !NO_ASN */ From 492490f7e63d9156d2d68fb4ff9866bfe7a9be09 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Tue, 30 Jan 2024 16:47:38 +1000 Subject: [PATCH 30/63] SHA-256: Implementation using Intel instructions Detects Intel SHA-256 instructions available for CPU. Preferences implementation using Intel instructions. --- wolfcrypt/src/cpuid.c | 1 + wolfcrypt/src/sha256.c | 24 ++ wolfcrypt/src/sha256_asm.S | 812 +++++++++++++++++++++++++++++++++++++ wolfssl/wolfcrypt/cpuid.h | 2 + 4 files changed, 839 insertions(+) diff --git a/wolfcrypt/src/cpuid.c b/wolfcrypt/src/cpuid.c index c1924c1e5c..fa7ee43675 100644 --- a/wolfcrypt/src/cpuid.c +++ b/wolfcrypt/src/cpuid.c @@ -96,6 +96,7 @@ if (cpuid_flag(7, 0, EBX, 19)) { cpuid_flags |= CPUID_ADX ; } if (cpuid_flag(1, 0, ECX, 22)) { cpuid_flags |= CPUID_MOVBE ; } if (cpuid_flag(7, 0, EBX, 3)) { cpuid_flags |= CPUID_BMI1 ; } + if (cpuid_flag(7, 0, EBX, 29)) { cpuid_flags |= CPUID_SHA ; } cpuid_check = 1; } diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index 2143dfc1fc..bbaad7fab0 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -302,7 +302,15 @@ static int InitSha256(wc_Sha256* sha256) extern "C" { #endif + extern int Transform_Sha256_SSE2_Sha(wc_Sha256 *sha256, + const byte* data); + extern int Transform_Sha256_SSE2_Sha_Len(wc_Sha256* sha256, + const byte* data, word32 len); #if defined(HAVE_INTEL_AVX1) + extern int Transform_Sha256_AVX1_Sha(wc_Sha256 *sha256, + const byte* data); + extern int Transform_Sha256_AVX1_Sha_Len(wc_Sha256* sha256, + const byte* data, word32 len); extern int Transform_Sha256_AVX1(wc_Sha256 *sha256, const byte* data); extern int Transform_Sha256_AVX1_Len(wc_Sha256* sha256, const byte* data, word32 len); @@ -356,6 +364,22 @@ static int InitSha256(wc_Sha256* sha256) intel_flags = cpuid_get_flags(); + if (IS_INTEL_SHA(intel_flags)) { + #ifdef HAVE_INTEL_AVX1 + if (IS_INTEL_AVX1(intel_flags)) { + Transform_Sha256_p = Transform_Sha256_AVX1_Sha; + Transform_Sha256_Len_p = Transform_Sha256_AVX1_Sha_Len; + Transform_Sha256_is_vectorized = 1; + } + else + #endif + { + Transform_Sha256_p = Transform_Sha256_SSE2_Sha; + Transform_Sha256_Len_p = Transform_Sha256_SSE2_Sha_Len; + Transform_Sha256_is_vectorized = 1; + } + } + else #ifdef HAVE_INTEL_AVX2 if (IS_INTEL_AVX2(intel_flags)) { #ifdef HAVE_INTEL_RORX diff --git a/wolfcrypt/src/sha256_asm.S b/wolfcrypt/src/sha256_asm.S index 6d1c8ea79d..67145b9cc3 100644 --- a/wolfcrypt/src/sha256_asm.S +++ b/wolfcrypt/src/sha256_asm.S @@ -46,6 +46,440 @@ #endif /* NO_AVX2_SUPPORT */ #ifdef WOLFSSL_X86_64_BUILD +#ifndef __APPLE__ +.data +#else +.section __DATA,__data +#endif /* __APPLE__ */ +L_sse2_sha256_sha_k: +.long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 +.long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 +.long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 +.long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 +.long 0xe49b69c1,0xefbe4786,0xfc19dc6,0x240ca1cc +.long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da +.long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 +.long 0xc6e00bf3,0xd5a79147,0x6ca6351,0x14292967 +.long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 +.long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 +.long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 +.long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 +.long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 +.long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 +.long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 +.long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 +#ifndef __APPLE__ +.data +#else +.section __DATA,__data +#endif /* __APPLE__ */ +#ifndef __APPLE__ +.align 16 +#else +.p2align 4 +#endif /* __APPLE__ */ +L_sse2_sha256_shuf_mask: +.quad 0x405060700010203, 0xc0d0e0f08090a0b +#ifndef __APPLE__ +.text +.globl Transform_Sha256_SSE2_Sha +.type Transform_Sha256_SSE2_Sha,@function +.align 16 +Transform_Sha256_SSE2_Sha: +#else +.section __TEXT,__text +.globl _Transform_Sha256_SSE2_Sha +.p2align 4 +_Transform_Sha256_SSE2_Sha: +#endif /* __APPLE__ */ + leaq 32(%rdi), %rdx + movdqa L_sse2_sha256_shuf_mask(%rip), %xmm10 + movq (%rdi), %xmm1 + movq 8(%rdi), %xmm2 + movhpd 16(%rdi), %xmm1 + movhpd 24(%rdi), %xmm2 + pshufd $27, %xmm1, %xmm1 + pshufd $27, %xmm2, %xmm2 + movdqu (%rdx), %xmm3 + movdqu 16(%rdx), %xmm4 + movdqu 32(%rdx), %xmm5 + movdqu 48(%rdx), %xmm6 + pshufb %xmm10, %xmm3 + movdqa %xmm1, %xmm8 + movdqa %xmm2, %xmm9 + # Rounds: 0-3 + movdqa %xmm3, %xmm0 + paddd 0+L_sse2_sha256_sha_k(%rip), %xmm0 + sha256rnds2 %xmm1, %xmm2 + pshufd $14, %xmm0, %xmm0 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 4-7 + pshufb %xmm10, %xmm4 + movdqa %xmm4, %xmm0 + paddd 16+L_sse2_sha256_sha_k(%rip), %xmm0 + sha256rnds2 %xmm1, %xmm2 + pshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm4, %xmm3 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 8-11 + pshufb %xmm10, %xmm5 + movdqa %xmm5, %xmm0 + paddd 32+L_sse2_sha256_sha_k(%rip), %xmm0 + sha256rnds2 %xmm1, %xmm2 + pshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm5, %xmm4 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 12-15 + pshufb %xmm10, %xmm6 + movdqa %xmm6, %xmm0 + paddd 48+L_sse2_sha256_sha_k(%rip), %xmm0 + sha256rnds2 %xmm1, %xmm2 + movdqa %xmm6, %xmm7 + palignr $4, %xmm5, %xmm7 + paddd %xmm7, %xmm3 + sha256msg2 %xmm6, %xmm3 + pshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm6, %xmm5 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 16-19 + movdqa %xmm3, %xmm0 + paddd 64+L_sse2_sha256_sha_k(%rip), %xmm0 + sha256rnds2 %xmm1, %xmm2 + movdqa %xmm3, %xmm7 + palignr $4, %xmm6, %xmm7 + paddd %xmm7, %xmm4 + sha256msg2 %xmm3, %xmm4 + pshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm3, %xmm6 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 20-23 + movdqa %xmm4, %xmm0 + paddd 80+L_sse2_sha256_sha_k(%rip), %xmm0 + sha256rnds2 %xmm1, %xmm2 + movdqa %xmm4, %xmm7 + palignr $4, %xmm3, %xmm7 + paddd %xmm7, %xmm5 + sha256msg2 %xmm4, %xmm5 + pshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm4, %xmm3 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 24-27 + movdqa %xmm5, %xmm0 + paddd 96+L_sse2_sha256_sha_k(%rip), %xmm0 + sha256rnds2 %xmm1, %xmm2 + movdqa %xmm5, %xmm7 + palignr $4, %xmm4, %xmm7 + paddd %xmm7, %xmm6 + sha256msg2 %xmm5, %xmm6 + pshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm5, %xmm4 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 28-31 + movdqa %xmm6, %xmm0 + paddd 112+L_sse2_sha256_sha_k(%rip), %xmm0 + sha256rnds2 %xmm1, %xmm2 + movdqa %xmm6, %xmm7 + palignr $4, %xmm5, %xmm7 + paddd %xmm7, %xmm3 + sha256msg2 %xmm6, %xmm3 + pshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm6, %xmm5 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 32-35 + movdqa %xmm3, %xmm0 + paddd 128+L_sse2_sha256_sha_k(%rip), %xmm0 + sha256rnds2 %xmm1, %xmm2 + movdqa %xmm3, %xmm7 + palignr $4, %xmm6, %xmm7 + paddd %xmm7, %xmm4 + sha256msg2 %xmm3, %xmm4 + pshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm3, %xmm6 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 36-39 + movdqa %xmm4, %xmm0 + paddd 144+L_sse2_sha256_sha_k(%rip), %xmm0 + sha256rnds2 %xmm1, %xmm2 + movdqa %xmm4, %xmm7 + palignr $4, %xmm3, %xmm7 + paddd %xmm7, %xmm5 + sha256msg2 %xmm4, %xmm5 + pshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm4, %xmm3 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 40-43 + movdqa %xmm5, %xmm0 + paddd 160+L_sse2_sha256_sha_k(%rip), %xmm0 + sha256rnds2 %xmm1, %xmm2 + movdqa %xmm5, %xmm7 + palignr $4, %xmm4, %xmm7 + paddd %xmm7, %xmm6 + sha256msg2 %xmm5, %xmm6 + pshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm5, %xmm4 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 44-47 + movdqa %xmm6, %xmm0 + paddd 176+L_sse2_sha256_sha_k(%rip), %xmm0 + sha256rnds2 %xmm1, %xmm2 + movdqa %xmm6, %xmm7 + palignr $4, %xmm5, %xmm7 + paddd %xmm7, %xmm3 + sha256msg2 %xmm6, %xmm3 + pshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm6, %xmm5 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 48-51 + movdqa %xmm3, %xmm0 + paddd 192+L_sse2_sha256_sha_k(%rip), %xmm0 + sha256rnds2 %xmm1, %xmm2 + movdqa %xmm3, %xmm7 + palignr $4, %xmm6, %xmm7 + paddd %xmm7, %xmm4 + sha256msg2 %xmm3, %xmm4 + pshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm3, %xmm6 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 52-63 + movdqa %xmm4, %xmm0 + paddd 208+L_sse2_sha256_sha_k(%rip), %xmm0 + sha256rnds2 %xmm1, %xmm2 + movdqa %xmm4, %xmm7 + palignr $4, %xmm3, %xmm7 + paddd %xmm7, %xmm5 + sha256msg2 %xmm4, %xmm5 + pshufd $14, %xmm0, %xmm0 + sha256rnds2 %xmm2, %xmm1 + movdqa %xmm5, %xmm0 + paddd 224+L_sse2_sha256_sha_k(%rip), %xmm0 + sha256rnds2 %xmm1, %xmm2 + movdqa %xmm5, %xmm7 + palignr $4, %xmm4, %xmm7 + paddd %xmm7, %xmm6 + sha256msg2 %xmm5, %xmm6 + pshufd $14, %xmm0, %xmm0 + sha256rnds2 %xmm2, %xmm1 + movdqa %xmm6, %xmm0 + paddd 240+L_sse2_sha256_sha_k(%rip), %xmm0 + sha256rnds2 %xmm1, %xmm2 + pshufd $14, %xmm0, %xmm0 + sha256rnds2 %xmm2, %xmm1 + paddd %xmm8, %xmm1 + paddd %xmm9, %xmm2 + pshufd $27, %xmm1, %xmm1 + pshufd $27, %xmm2, %xmm2 + movq %xmm1, (%rdi) + movq %xmm2, 8(%rdi) + movhpd %xmm1, 16(%rdi) + movhpd %xmm2, 24(%rdi) + xorq %rax, %rax + vzeroupper + repz retq +#ifndef __APPLE__ +.size Transform_Sha256_SSE2_Sha,.-Transform_Sha256_SSE2_Sha +#endif /* __APPLE__ */ +#ifndef __APPLE__ +.text +.globl Transform_Sha256_SSE2_Sha_Len +.type Transform_Sha256_SSE2_Sha_Len,@function +.align 16 +Transform_Sha256_SSE2_Sha_Len: +#else +.section __TEXT,__text +.globl _Transform_Sha256_SSE2_Sha_Len +.p2align 4 +_Transform_Sha256_SSE2_Sha_Len: +#endif /* __APPLE__ */ + movdqa L_sse2_sha256_shuf_mask(%rip), %xmm10 + movq (%rdi), %xmm1 + movq 8(%rdi), %xmm2 + movhpd 16(%rdi), %xmm1 + movhpd 24(%rdi), %xmm2 + pshufd $27, %xmm1, %xmm1 + pshufd $27, %xmm2, %xmm2 + # Start of loop processing a block +L_sha256_sha_len_sse2_start: + movdqu (%rsi), %xmm3 + movdqu 16(%rsi), %xmm4 + movdqu 32(%rsi), %xmm5 + movdqu 48(%rsi), %xmm6 + pshufb %xmm10, %xmm3 + movdqa %xmm1, %xmm8 + movdqa %xmm2, %xmm9 + # Rounds: 0-3 + movdqa %xmm3, %xmm0 + paddd 0+L_sse2_sha256_sha_k(%rip), %xmm0 + sha256rnds2 %xmm1, %xmm2 + pshufd $14, %xmm0, %xmm0 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 4-7 + pshufb %xmm10, %xmm4 + movdqa %xmm4, %xmm0 + paddd 16+L_sse2_sha256_sha_k(%rip), %xmm0 + sha256rnds2 %xmm1, %xmm2 + pshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm4, %xmm3 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 8-11 + pshufb %xmm10, %xmm5 + movdqa %xmm5, %xmm0 + paddd 32+L_sse2_sha256_sha_k(%rip), %xmm0 + sha256rnds2 %xmm1, %xmm2 + pshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm5, %xmm4 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 12-15 + pshufb %xmm10, %xmm6 + movdqa %xmm6, %xmm0 + paddd 48+L_sse2_sha256_sha_k(%rip), %xmm0 + sha256rnds2 %xmm1, %xmm2 + movdqa %xmm6, %xmm7 + palignr $4, %xmm5, %xmm7 + paddd %xmm7, %xmm3 + sha256msg2 %xmm6, %xmm3 + pshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm6, %xmm5 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 16-19 + movdqa %xmm3, %xmm0 + paddd 64+L_sse2_sha256_sha_k(%rip), %xmm0 + sha256rnds2 %xmm1, %xmm2 + movdqa %xmm3, %xmm7 + palignr $4, %xmm6, %xmm7 + paddd %xmm7, %xmm4 + sha256msg2 %xmm3, %xmm4 + pshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm3, %xmm6 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 20-23 + movdqa %xmm4, %xmm0 + paddd 80+L_sse2_sha256_sha_k(%rip), %xmm0 + sha256rnds2 %xmm1, %xmm2 + movdqa %xmm4, %xmm7 + palignr $4, %xmm3, %xmm7 + paddd %xmm7, %xmm5 + sha256msg2 %xmm4, %xmm5 + pshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm4, %xmm3 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 24-27 + movdqa %xmm5, %xmm0 + paddd 96+L_sse2_sha256_sha_k(%rip), %xmm0 + sha256rnds2 %xmm1, %xmm2 + movdqa %xmm5, %xmm7 + palignr $4, %xmm4, %xmm7 + paddd %xmm7, %xmm6 + sha256msg2 %xmm5, %xmm6 + pshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm5, %xmm4 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 28-31 + movdqa %xmm6, %xmm0 + paddd 112+L_sse2_sha256_sha_k(%rip), %xmm0 + sha256rnds2 %xmm1, %xmm2 + movdqa %xmm6, %xmm7 + palignr $4, %xmm5, %xmm7 + paddd %xmm7, %xmm3 + sha256msg2 %xmm6, %xmm3 + pshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm6, %xmm5 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 32-35 + movdqa %xmm3, %xmm0 + paddd 128+L_sse2_sha256_sha_k(%rip), %xmm0 + sha256rnds2 %xmm1, %xmm2 + movdqa %xmm3, %xmm7 + palignr $4, %xmm6, %xmm7 + paddd %xmm7, %xmm4 + sha256msg2 %xmm3, %xmm4 + pshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm3, %xmm6 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 36-39 + movdqa %xmm4, %xmm0 + paddd 144+L_sse2_sha256_sha_k(%rip), %xmm0 + sha256rnds2 %xmm1, %xmm2 + movdqa %xmm4, %xmm7 + palignr $4, %xmm3, %xmm7 + paddd %xmm7, %xmm5 + sha256msg2 %xmm4, %xmm5 + pshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm4, %xmm3 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 40-43 + movdqa %xmm5, %xmm0 + paddd 160+L_sse2_sha256_sha_k(%rip), %xmm0 + sha256rnds2 %xmm1, %xmm2 + movdqa %xmm5, %xmm7 + palignr $4, %xmm4, %xmm7 + paddd %xmm7, %xmm6 + sha256msg2 %xmm5, %xmm6 + pshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm5, %xmm4 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 44-47 + movdqa %xmm6, %xmm0 + paddd 176+L_sse2_sha256_sha_k(%rip), %xmm0 + sha256rnds2 %xmm1, %xmm2 + movdqa %xmm6, %xmm7 + palignr $4, %xmm5, %xmm7 + paddd %xmm7, %xmm3 + sha256msg2 %xmm6, %xmm3 + pshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm6, %xmm5 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 48-51 + movdqa %xmm3, %xmm0 + paddd 192+L_sse2_sha256_sha_k(%rip), %xmm0 + sha256rnds2 %xmm1, %xmm2 + movdqa %xmm3, %xmm7 + palignr $4, %xmm6, %xmm7 + paddd %xmm7, %xmm4 + sha256msg2 %xmm3, %xmm4 + pshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm3, %xmm6 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 52-63 + movdqa %xmm4, %xmm0 + paddd 208+L_sse2_sha256_sha_k(%rip), %xmm0 + sha256rnds2 %xmm1, %xmm2 + movdqa %xmm4, %xmm7 + palignr $4, %xmm3, %xmm7 + paddd %xmm7, %xmm5 + sha256msg2 %xmm4, %xmm5 + pshufd $14, %xmm0, %xmm0 + sha256rnds2 %xmm2, %xmm1 + movdqa %xmm5, %xmm0 + paddd 224+L_sse2_sha256_sha_k(%rip), %xmm0 + sha256rnds2 %xmm1, %xmm2 + movdqa %xmm5, %xmm7 + palignr $4, %xmm4, %xmm7 + paddd %xmm7, %xmm6 + sha256msg2 %xmm5, %xmm6 + pshufd $14, %xmm0, %xmm0 + sha256rnds2 %xmm2, %xmm1 + movdqa %xmm6, %xmm0 + paddd 240+L_sse2_sha256_sha_k(%rip), %xmm0 + sha256rnds2 %xmm1, %xmm2 + pshufd $14, %xmm0, %xmm0 + sha256rnds2 %xmm2, %xmm1 + addq $0x40, %rsi + subl $0x40, %edx + paddd %xmm8, %xmm1 + paddd %xmm9, %xmm2 + jnz L_sha256_sha_len_sse2_start + pshufd $27, %xmm1, %xmm1 + pshufd $27, %xmm2, %xmm2 + movq %xmm1, (%rdi) + movq %xmm2, 8(%rdi) + movhpd %xmm1, 16(%rdi) + movhpd %xmm2, 24(%rdi) + xorq %rax, %rax + vzeroupper + repz retq +#ifndef __APPLE__ +.size Transform_Sha256_SSE2_Sha_Len,.-Transform_Sha256_SSE2_Sha_Len +#endif /* __APPLE__ */ #ifdef HAVE_INTEL_AVX1 #ifndef __APPLE__ .data @@ -9672,6 +10106,384 @@ L_sha256_len_avx1_len_rorx_start: #ifndef __APPLE__ .size Transform_Sha256_AVX1_RORX_Len,.-Transform_Sha256_AVX1_RORX_Len #endif /* __APPLE__ */ +#ifndef __APPLE__ +.data +#else +.section __DATA,__data +#endif /* __APPLE__ */ +L_avx1_sha256_sha_k: +.long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 +.long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 +.long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 +.long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 +.long 0xe49b69c1,0xefbe4786,0xfc19dc6,0x240ca1cc +.long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da +.long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 +.long 0xc6e00bf3,0xd5a79147,0x6ca6351,0x14292967 +.long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 +.long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 +.long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 +.long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 +.long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 +.long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 +.long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 +.long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 +#ifndef __APPLE__ +.data +#else +.section __DATA,__data +#endif /* __APPLE__ */ +#ifndef __APPLE__ +.align 16 +#else +.p2align 4 +#endif /* __APPLE__ */ +L_avx1_sha256_shuf_mask: +.quad 0x405060700010203, 0xc0d0e0f08090a0b +#ifndef __APPLE__ +.text +.globl Transform_Sha256_AVX1_Sha +.type Transform_Sha256_AVX1_Sha,@function +.align 16 +Transform_Sha256_AVX1_Sha: +#else +.section __TEXT,__text +.globl _Transform_Sha256_AVX1_Sha +.p2align 4 +_Transform_Sha256_AVX1_Sha: +#endif /* __APPLE__ */ + leaq 32(%rdi), %rdx + vmovdqa L_avx1_sha256_shuf_mask(%rip), %xmm10 + vmovq (%rdi), %xmm1 + vmovq 8(%rdi), %xmm2 + vmovhpd 16(%rdi), %xmm1, %xmm1 + vmovhpd 24(%rdi), %xmm2, %xmm2 + vpshufd $27, %xmm1, %xmm1 + vpshufd $27, %xmm2, %xmm2 + vmovdqu (%rdx), %xmm3 + vmovdqu 16(%rdx), %xmm4 + vmovdqu 32(%rdx), %xmm5 + vmovdqu 48(%rdx), %xmm6 + vpshufb %xmm10, %xmm3, %xmm3 + vmovdqa %xmm1, %xmm8 + vmovdqa %xmm2, %xmm9 + # Rounds: 0-3 + vpaddd 0+L_avx1_sha256_sha_k(%rip), %xmm3, %xmm0 + sha256rnds2 %xmm1, %xmm2 + vpshufd $14, %xmm0, %xmm0 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 4-7 + vpshufb %xmm10, %xmm4, %xmm4 + vpaddd 16+L_avx1_sha256_sha_k(%rip), %xmm4, %xmm0 + sha256rnds2 %xmm1, %xmm2 + vpshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm4, %xmm3 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 8-11 + vpshufb %xmm10, %xmm5, %xmm5 + vpaddd 32+L_avx1_sha256_sha_k(%rip), %xmm5, %xmm0 + sha256rnds2 %xmm1, %xmm2 + vpshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm5, %xmm4 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 12-15 + vpshufb %xmm10, %xmm6, %xmm6 + vpaddd 48+L_avx1_sha256_sha_k(%rip), %xmm6, %xmm0 + sha256rnds2 %xmm1, %xmm2 + vpalignr $4, %xmm5, %xmm6, %xmm7 + vpaddd %xmm7, %xmm3, %xmm3 + sha256msg2 %xmm6, %xmm3 + vpshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm6, %xmm5 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 16-19 + vpaddd 64+L_avx1_sha256_sha_k(%rip), %xmm3, %xmm0 + sha256rnds2 %xmm1, %xmm2 + vpalignr $4, %xmm6, %xmm3, %xmm7 + vpaddd %xmm7, %xmm4, %xmm4 + sha256msg2 %xmm3, %xmm4 + vpshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm3, %xmm6 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 20-23 + vpaddd 80+L_avx1_sha256_sha_k(%rip), %xmm4, %xmm0 + sha256rnds2 %xmm1, %xmm2 + vpalignr $4, %xmm3, %xmm4, %xmm7 + vpaddd %xmm7, %xmm5, %xmm5 + sha256msg2 %xmm4, %xmm5 + vpshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm4, %xmm3 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 24-27 + vpaddd 96+L_avx1_sha256_sha_k(%rip), %xmm5, %xmm0 + sha256rnds2 %xmm1, %xmm2 + vpalignr $4, %xmm4, %xmm5, %xmm7 + vpaddd %xmm7, %xmm6, %xmm6 + sha256msg2 %xmm5, %xmm6 + vpshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm5, %xmm4 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 28-31 + vpaddd 112+L_avx1_sha256_sha_k(%rip), %xmm6, %xmm0 + sha256rnds2 %xmm1, %xmm2 + vpalignr $4, %xmm5, %xmm6, %xmm7 + vpaddd %xmm7, %xmm3, %xmm3 + sha256msg2 %xmm6, %xmm3 + vpshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm6, %xmm5 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 32-35 + vpaddd 128+L_avx1_sha256_sha_k(%rip), %xmm3, %xmm0 + sha256rnds2 %xmm1, %xmm2 + vpalignr $4, %xmm6, %xmm3, %xmm7 + vpaddd %xmm7, %xmm4, %xmm4 + sha256msg2 %xmm3, %xmm4 + vpshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm3, %xmm6 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 36-39 + vpaddd 144+L_avx1_sha256_sha_k(%rip), %xmm4, %xmm0 + sha256rnds2 %xmm1, %xmm2 + vpalignr $4, %xmm3, %xmm4, %xmm7 + vpaddd %xmm7, %xmm5, %xmm5 + sha256msg2 %xmm4, %xmm5 + vpshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm4, %xmm3 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 40-43 + vpaddd 160+L_avx1_sha256_sha_k(%rip), %xmm5, %xmm0 + sha256rnds2 %xmm1, %xmm2 + vpalignr $4, %xmm4, %xmm5, %xmm7 + vpaddd %xmm7, %xmm6, %xmm6 + sha256msg2 %xmm5, %xmm6 + vpshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm5, %xmm4 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 44-47 + vpaddd 176+L_avx1_sha256_sha_k(%rip), %xmm6, %xmm0 + sha256rnds2 %xmm1, %xmm2 + vpalignr $4, %xmm5, %xmm6, %xmm7 + vpaddd %xmm7, %xmm3, %xmm3 + sha256msg2 %xmm6, %xmm3 + vpshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm6, %xmm5 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 48-51 + vpaddd 192+L_avx1_sha256_sha_k(%rip), %xmm3, %xmm0 + sha256rnds2 %xmm1, %xmm2 + vpalignr $4, %xmm6, %xmm3, %xmm7 + vpaddd %xmm7, %xmm4, %xmm4 + sha256msg2 %xmm3, %xmm4 + vpshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm3, %xmm6 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 52-63 + vpaddd 208+L_avx1_sha256_sha_k(%rip), %xmm4, %xmm0 + sha256rnds2 %xmm1, %xmm2 + vpalignr $4, %xmm3, %xmm4, %xmm7 + vpaddd %xmm7, %xmm5, %xmm5 + sha256msg2 %xmm4, %xmm5 + vpshufd $14, %xmm0, %xmm0 + sha256rnds2 %xmm2, %xmm1 + vpaddd 224+L_avx1_sha256_sha_k(%rip), %xmm5, %xmm0 + sha256rnds2 %xmm1, %xmm2 + vpalignr $4, %xmm4, %xmm5, %xmm7 + vpaddd %xmm7, %xmm6, %xmm6 + sha256msg2 %xmm5, %xmm6 + vpshufd $14, %xmm0, %xmm0 + sha256rnds2 %xmm2, %xmm1 + vpaddd 240+L_avx1_sha256_sha_k(%rip), %xmm6, %xmm0 + sha256rnds2 %xmm1, %xmm2 + vpshufd $14, %xmm0, %xmm0 + sha256rnds2 %xmm2, %xmm1 + vpaddd %xmm8, %xmm1, %xmm1 + vpaddd %xmm9, %xmm2, %xmm2 + vpshufd $27, %xmm1, %xmm1 + vpshufd $27, %xmm2, %xmm2 + vmovq %xmm1, (%rdi) + vmovq %xmm2, 8(%rdi) + vmovhpd %xmm1, 16(%rdi) + vmovhpd %xmm2, 24(%rdi) + xorq %rax, %rax + vzeroupper + repz retq +#ifndef __APPLE__ +.size Transform_Sha256_AVX1_Sha,.-Transform_Sha256_AVX1_Sha +#endif /* __APPLE__ */ +#ifndef __APPLE__ +.text +.globl Transform_Sha256_AVX1_Sha_Len +.type Transform_Sha256_AVX1_Sha_Len,@function +.align 16 +Transform_Sha256_AVX1_Sha_Len: +#else +.section __TEXT,__text +.globl _Transform_Sha256_AVX1_Sha_Len +.p2align 4 +_Transform_Sha256_AVX1_Sha_Len: +#endif /* __APPLE__ */ + vmovdqa L_avx1_sha256_shuf_mask(%rip), %xmm10 + vmovq (%rdi), %xmm1 + vmovq 8(%rdi), %xmm2 + vmovhpd 16(%rdi), %xmm1, %xmm1 + vmovhpd 24(%rdi), %xmm2, %xmm2 + vpshufd $27, %xmm1, %xmm1 + vpshufd $27, %xmm2, %xmm2 + # Start of loop processing a block +L_sha256_sha_len_avx1_start: + vmovdqu (%rsi), %xmm3 + vmovdqu 16(%rsi), %xmm4 + vmovdqu 32(%rsi), %xmm5 + vmovdqu 48(%rsi), %xmm6 + vpshufb %xmm10, %xmm3, %xmm3 + vmovdqa %xmm1, %xmm8 + vmovdqa %xmm2, %xmm9 + # Rounds: 0-3 + vpaddd 0+L_avx1_sha256_sha_k(%rip), %xmm3, %xmm0 + sha256rnds2 %xmm1, %xmm2 + vpshufd $14, %xmm0, %xmm0 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 4-7 + vpshufb %xmm10, %xmm4, %xmm4 + vpaddd 16+L_avx1_sha256_sha_k(%rip), %xmm4, %xmm0 + sha256rnds2 %xmm1, %xmm2 + vpshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm4, %xmm3 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 8-11 + vpshufb %xmm10, %xmm5, %xmm5 + vpaddd 32+L_avx1_sha256_sha_k(%rip), %xmm5, %xmm0 + sha256rnds2 %xmm1, %xmm2 + vpshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm5, %xmm4 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 12-15 + vpshufb %xmm10, %xmm6, %xmm6 + vpaddd 48+L_avx1_sha256_sha_k(%rip), %xmm6, %xmm0 + sha256rnds2 %xmm1, %xmm2 + vpalignr $4, %xmm5, %xmm6, %xmm7 + vpaddd %xmm7, %xmm3, %xmm3 + sha256msg2 %xmm6, %xmm3 + vpshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm6, %xmm5 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 16-19 + vpaddd 64+L_avx1_sha256_sha_k(%rip), %xmm3, %xmm0 + sha256rnds2 %xmm1, %xmm2 + vpalignr $4, %xmm6, %xmm3, %xmm7 + vpaddd %xmm7, %xmm4, %xmm4 + sha256msg2 %xmm3, %xmm4 + vpshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm3, %xmm6 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 20-23 + vpaddd 80+L_avx1_sha256_sha_k(%rip), %xmm4, %xmm0 + sha256rnds2 %xmm1, %xmm2 + vpalignr $4, %xmm3, %xmm4, %xmm7 + vpaddd %xmm7, %xmm5, %xmm5 + sha256msg2 %xmm4, %xmm5 + vpshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm4, %xmm3 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 24-27 + vpaddd 96+L_avx1_sha256_sha_k(%rip), %xmm5, %xmm0 + sha256rnds2 %xmm1, %xmm2 + vpalignr $4, %xmm4, %xmm5, %xmm7 + vpaddd %xmm7, %xmm6, %xmm6 + sha256msg2 %xmm5, %xmm6 + vpshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm5, %xmm4 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 28-31 + vpaddd 112+L_avx1_sha256_sha_k(%rip), %xmm6, %xmm0 + sha256rnds2 %xmm1, %xmm2 + vpalignr $4, %xmm5, %xmm6, %xmm7 + vpaddd %xmm7, %xmm3, %xmm3 + sha256msg2 %xmm6, %xmm3 + vpshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm6, %xmm5 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 32-35 + vpaddd 128+L_avx1_sha256_sha_k(%rip), %xmm3, %xmm0 + sha256rnds2 %xmm1, %xmm2 + vpalignr $4, %xmm6, %xmm3, %xmm7 + vpaddd %xmm7, %xmm4, %xmm4 + sha256msg2 %xmm3, %xmm4 + vpshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm3, %xmm6 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 36-39 + vpaddd 144+L_avx1_sha256_sha_k(%rip), %xmm4, %xmm0 + sha256rnds2 %xmm1, %xmm2 + vpalignr $4, %xmm3, %xmm4, %xmm7 + vpaddd %xmm7, %xmm5, %xmm5 + sha256msg2 %xmm4, %xmm5 + vpshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm4, %xmm3 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 40-43 + vpaddd 160+L_avx1_sha256_sha_k(%rip), %xmm5, %xmm0 + sha256rnds2 %xmm1, %xmm2 + vpalignr $4, %xmm4, %xmm5, %xmm7 + vpaddd %xmm7, %xmm6, %xmm6 + sha256msg2 %xmm5, %xmm6 + vpshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm5, %xmm4 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 44-47 + vpaddd 176+L_avx1_sha256_sha_k(%rip), %xmm6, %xmm0 + sha256rnds2 %xmm1, %xmm2 + vpalignr $4, %xmm5, %xmm6, %xmm7 + vpaddd %xmm7, %xmm3, %xmm3 + sha256msg2 %xmm6, %xmm3 + vpshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm6, %xmm5 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 48-51 + vpaddd 192+L_avx1_sha256_sha_k(%rip), %xmm3, %xmm0 + sha256rnds2 %xmm1, %xmm2 + vpalignr $4, %xmm6, %xmm3, %xmm7 + vpaddd %xmm7, %xmm4, %xmm4 + sha256msg2 %xmm3, %xmm4 + vpshufd $14, %xmm0, %xmm0 + sha256msg1 %xmm3, %xmm6 + sha256rnds2 %xmm2, %xmm1 + # Rounds: 52-63 + vpaddd 208+L_avx1_sha256_sha_k(%rip), %xmm4, %xmm0 + sha256rnds2 %xmm1, %xmm2 + vpalignr $4, %xmm3, %xmm4, %xmm7 + vpaddd %xmm7, %xmm5, %xmm5 + sha256msg2 %xmm4, %xmm5 + vpshufd $14, %xmm0, %xmm0 + sha256rnds2 %xmm2, %xmm1 + vpaddd 224+L_avx1_sha256_sha_k(%rip), %xmm5, %xmm0 + sha256rnds2 %xmm1, %xmm2 + vpalignr $4, %xmm4, %xmm5, %xmm7 + vpaddd %xmm7, %xmm6, %xmm6 + sha256msg2 %xmm5, %xmm6 + vpshufd $14, %xmm0, %xmm0 + sha256rnds2 %xmm2, %xmm1 + vpaddd 240+L_avx1_sha256_sha_k(%rip), %xmm6, %xmm0 + sha256rnds2 %xmm1, %xmm2 + vpshufd $14, %xmm0, %xmm0 + sha256rnds2 %xmm2, %xmm1 + addq $0x40, %rsi + subl $0x40, %edx + vpaddd %xmm8, %xmm1, %xmm1 + vpaddd %xmm9, %xmm2, %xmm2 + jnz L_sha256_sha_len_avx1_start + vpshufd $27, %xmm1, %xmm1 + vpshufd $27, %xmm2, %xmm2 + vmovq %xmm1, (%rdi) + vmovq %xmm2, 8(%rdi) + vmovhpd %xmm1, 16(%rdi) + vmovhpd %xmm2, 24(%rdi) + xorq %rax, %rax + vzeroupper + repz retq +#ifndef __APPLE__ +.size Transform_Sha256_AVX1_Sha_Len,.-Transform_Sha256_AVX1_Sha_Len +#endif /* __APPLE__ */ #endif /* HAVE_INTEL_AVX1 */ #ifdef HAVE_INTEL_AVX2 #ifndef __APPLE__ diff --git a/wolfssl/wolfcrypt/cpuid.h b/wolfssl/wolfcrypt/cpuid.h index 9e04328f7b..9d25dcf327 100644 --- a/wolfssl/wolfcrypt/cpuid.h +++ b/wolfssl/wolfcrypt/cpuid.h @@ -50,6 +50,7 @@ #define CPUID_ADX 0x0040 /* ADCX, ADOX */ #define CPUID_MOVBE 0x0080 /* Move and byte swap */ #define CPUID_BMI1 0x0100 /* ANDN */ + #define CPUID_SHA 0x0200 /* SHA-1 and SHA-256 instructions */ #define IS_INTEL_AVX1(f) ((f) & CPUID_AVX1) #define IS_INTEL_AVX2(f) ((f) & CPUID_AVX2) @@ -60,6 +61,7 @@ #define IS_INTEL_ADX(f) ((f) & CPUID_ADX) #define IS_INTEL_MOVBE(f) ((f) & CPUID_MOVBE) #define IS_INTEL_BMI1(f) ((f) & CPUID_BMI1) + #define IS_INTEL_SHA(f) ((f) & CPUID_SHA) #endif From 7ddf20851d6c719a063ad4aaf3476140e4bc7d9b Mon Sep 17 00:00:00 2001 From: jordan Date: Tue, 30 Jan 2024 09:00:02 -0600 Subject: [PATCH 31/63] Fix WOLFSSL_NO_MALLOC build. --- wolfcrypt/test/test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 6e215f52a0..d598046e8d 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -12556,7 +12556,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t aesgcm_test(void) #else byte large_input[BENCH_AESGCM_LARGE]; - byte large_output[BENCH_AESGCM_LARGE]; + byte large_output[BENCH_AESGCM_LARGE + AES_BLOCK_SIZE]; byte large_outdec[BENCH_AESGCM_LARGE]; #endif From f228a85cee52d44dc727d563bd869ee445b9ea64 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Tue, 30 Jan 2024 17:16:37 -0600 Subject: [PATCH 32/63] AES-XTS: fix FIPS gating to use defined(HAVE_FIPS), not defined(HAVE_FIPS_VERSION). --- linuxkm/lkcapi_glue.c | 14 ++++++++------ wolfcrypt/test/test.c | 8 ++++---- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/linuxkm/lkcapi_glue.c b/linuxkm/lkcapi_glue.c index 8ed9e5108e..72998d3f90 100644 --- a/linuxkm/lkcapi_glue.c +++ b/linuxkm/lkcapi_glue.c @@ -54,8 +54,10 @@ #define WOLFKM_DRIVER_ISA_EXT "" #endif -#ifdef HAVE_FIPS_VERSION - #if HAVE_FIPS_VERSION >= 5 +#ifdef HAVE_FIPS + #ifndef HAVE_FIPS_VERSION + #define WOLFKM_DRIVER_FIPS "-fips-140" + #elif HAVE_FIPS_VERSION >= 5 #define WOLFKM_DRIVER_FIPS "-fips-140-3" #elif HAVE_FIPS_VERSION == 2 #define WOLFKM_DRIVER_FIPS "-fips-140-2" @@ -1648,7 +1650,7 @@ static int aes_xts_128_test(void) 0xff, 0x8d, 0xbc, 0x1d, 0x9f, 0x7f, 0xc8, 0x22 }; -#ifndef HAVE_FIPS_VERSION /* FIPS requires different keys for main and tweak. */ +#ifndef HAVE_FIPS /* FIPS requires different keys for main and tweak. */ WOLFSSL_SMALL_STACK_STATIC const unsigned char k3[] = { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, @@ -1673,7 +1675,7 @@ static int aes_xts_128_test(void) 0xA0, 0x85, 0xD2, 0x69, 0x6E, 0x87, 0x0A, 0xBF, 0xB5, 0x5A, 0xDD, 0xCB, 0x80, 0xE0, 0xFC, 0xCD }; -#endif /* HAVE_FIPS_VERSION */ +#endif /* HAVE_FIPS */ #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) if ((aes = (XtsAes *)XMALLOC(sizeof(*aes), HEAP_HINT, DYNAMIC_TYPE_AES)) @@ -1866,7 +1868,7 @@ static int aes_xts_128_test(void) if (XMEMCMP(p2, buf, sizeof(p2))) ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); -#ifndef HAVE_FIPS_VERSION +#ifndef HAVE_FIPS /* Test ciphertext stealing in-place. */ XMEMCPY(buf, p3, sizeof(p3)); @@ -1895,7 +1897,7 @@ static int aes_xts_128_test(void) if (XMEMCMP(p3, buf, sizeof(p3))) ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); -#endif /* HAVE_FIPS_VERSION */ +#endif /* HAVE_FIPS */ #if !defined(BENCH_EMBEDDED) && !defined(HAVE_CAVIUM) && \ !defined(WOLFSSL_AFALG) diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index b878869317..41e52d1cc7 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -9438,7 +9438,7 @@ static wc_test_ret_t aes_xts_128_test(void) 0x77, 0x8a, 0xe8, 0xb4, 0x3c, 0xb9, 0x8d, 0x5a }; -#ifndef HAVE_FIPS_VERSION /* FIPS requires different keys for main and tweak. */ +#ifndef HAVE_FIPS /* FIPS requires different keys for main and tweak. */ WOLFSSL_SMALL_STACK_STATIC unsigned char k3[] = { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, @@ -9463,7 +9463,7 @@ static wc_test_ret_t aes_xts_128_test(void) 0xA0, 0x85, 0xD2, 0x69, 0x6E, 0x87, 0x0A, 0xBF, 0xB5, 0x5A, 0xDD, 0xCB, 0x80, 0xE0, 0xFC, 0xCD }; -#endif /* HAVE_FIPS_VERSION */ +#endif /* HAVE_FIPS */ #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) if ((aes = (XtsAes *)XMALLOC(sizeof *aes, HEAP_HINT, DYNAMIC_TYPE_AES)) == NULL) @@ -9666,7 +9666,7 @@ static wc_test_ret_t aes_xts_128_test(void) if (XMEMCMP(p2, buf, sizeof(p2))) ERROR_OUT(WC_TEST_RET_ENC_NC, out); -#ifndef HAVE_FIPS_VERSION +#ifndef HAVE_FIPS /* Test ciphertext stealing in-place. */ XMEMCPY(buf, p3, sizeof(p3)); @@ -9699,7 +9699,7 @@ static wc_test_ret_t aes_xts_128_test(void) if (XMEMCMP(p3, buf, sizeof(p3))) ERROR_OUT(WC_TEST_RET_ENC_NC, out); -#endif /* !HAVE_FIPS_VERSION */ +#endif /* !HAVE_FIPS */ #if !defined(BENCH_EMBEDDED) && !defined(HAVE_CAVIUM) && \ !defined(WOLFSSL_AFALG) From e1ee5e4421ef4caba7cfdc47ab150c56a4200bda Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Wed, 31 Jan 2024 11:49:46 -0600 Subject: [PATCH 33/63] linuxkm: spruce up arch-dependent CFLAGS setup in linuxkm/Kbuild; add "failed:" to error messages in km_AesGcmEncrypt() and km_AesGcmDecrypt(). --- linuxkm/Kbuild | 14 +++++++++----- linuxkm/lkcapi_glue.c | 4 ++-- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/linuxkm/Kbuild b/linuxkm/Kbuild index 4abe731091..aa1e1c661a 100644 --- a/linuxkm/Kbuild +++ b/linuxkm/Kbuild @@ -32,6 +32,10 @@ WOLFSSL_CFLAGS += -ffreestanding -Wframe-larger-than=$(MAX_STACK_FRAME_SIZE) -is ifeq "$(KERNEL_ARCH)" "x86" WOLFSSL_CFLAGS += -mpreferred-stack-boundary=4 +else ifeq "$(KERNEL_ARCH)" "aarch64" + WOLFSSL_CFLAGS += -mno-outline-atomics +else ifeq "$(KERNEL_ARCH)" "arm64" + WOLFSSL_CFLAGS += -mno-outline-atomics endif obj-m := libwolfssl.o @@ -47,15 +51,15 @@ $(obj)/linuxkm/module_exports.o: $(WOLFSSL_OBJ_TARGETS) # this mechanism only works in kernel 5.x+ (fallback to hardcoded value) hostprogs := linuxkm/get_thread_size always-y := $(hostprogs) + +HOST_EXTRACFLAGS += $(NOSTDINC_FLAGS) $(LINUXINCLUDE) $(KBUILD_CFLAGS) -static -fno-omit-frame-pointer + # "-mindirect-branch=keep -mfunction-return=keep" to avoid "undefined reference # to `__x86_return_thunk'" on CONFIG_RETHUNK kernels (5.19.0-rc7) -ifeq "$(KERNEL_ARCH)" "aarch64" - HOST_EXTRACFLAGS += $(NOSTDINC_FLAGS) $(LINUXINCLUDE) $(KBUILD_CFLAGS) -static -fno-omit-frame-pointer -else - HOST_EXTRACFLAGS += $(NOSTDINC_FLAGS) $(LINUXINCLUDE) $(KBUILD_CFLAGS) -static -fno-omit-frame-pointer -mindirect-branch=keep -mfunction-return=keep +ifeq "$(KERNEL_ARCH)" "x86" + HOST_EXTRACFLAGS += -mindirect-branch=keep -mfunction-return=keep endif - # this rule is needed to get build to succeed in 4.x (get_thread_size still doesn't get built) $(obj)/linuxkm/get_thread_size: $(src)/linuxkm/get_thread_size.c diff --git a/linuxkm/lkcapi_glue.c b/linuxkm/lkcapi_glue.c index 72998d3f90..d1e8081edf 100644 --- a/linuxkm/lkcapi_glue.c +++ b/linuxkm/lkcapi_glue.c @@ -579,7 +579,7 @@ static int km_AesGcmEncrypt(struct aead_request *req) err = skcipher_walk_aead_encrypt(&walk, req, false); if (unlikely(err)) { - pr_err("%s: skcipher_walk_aead_encrypt: %d\n", + pr_err("%s: skcipher_walk_aead_encrypt failed: %d\n", crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)), err); return -1; } @@ -685,7 +685,7 @@ static int km_AesGcmDecrypt(struct aead_request *req) err = skcipher_walk_aead_decrypt(&walk, req, false); if (unlikely(err)) { - pr_err("%s: skcipher_walk_aead_decrypt: %d\n", + pr_err("%s: skcipher_walk_aead_decrypt failed: %d\n", crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)), err); return err; } From 9e47703402f6739dfc85cc959577c0e1b09778be Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 31 Jan 2024 10:13:31 -0800 Subject: [PATCH 34/63] Template for TLS v1.2 only. --- .github/workflows/os-check.yml | 1 + examples/configs/include.am | 1 + examples/configs/user_settings_tls12.h | 152 +++++++++++++++++++++++++ 3 files changed, 154 insertions(+) create mode 100644 examples/configs/user_settings_tls12.h diff --git a/.github/workflows/os-check.yml b/.github/workflows/os-check.yml index 08134c4a21..0f18277de3 100644 --- a/.github/workflows/os-check.yml +++ b/.github/workflows/os-check.yml @@ -67,6 +67,7 @@ jobs: 'examples/configs/user_settings_min_ecc.h', 'examples/configs/user_settings_wolfboot_keytools.h', 'examples/configs/user_settings_wolftpm.h', + 'examples/configs/user_settings_tls12.h', ] name: make user_setting.h (testwolfcrypt only) runs-on: ${{ matrix.os }} diff --git a/examples/configs/include.am b/examples/configs/include.am index 781fbcbcab..a507e1c4ec 100644 --- a/examples/configs/include.am +++ b/examples/configs/include.am @@ -9,5 +9,6 @@ EXTRA_DIST += examples/configs/user_settings_template.h EXTRA_DIST += examples/configs/user_settings_fipsv2.h EXTRA_DIST += examples/configs/user_settings_fipsv5.h EXTRA_DIST += examples/configs/user_settings_stm32.h +EXTRA_DIST += examples/configs/user_settings_tls12.h EXTRA_DIST += examples/configs/user_settings_wolftpm.h EXTRA_DIST += examples/configs/user_settings_EBSnet.h diff --git a/examples/configs/user_settings_tls12.h b/examples/configs/user_settings_tls12.h new file mode 100644 index 0000000000..c4a1fa31f8 --- /dev/null +++ b/examples/configs/user_settings_tls12.h @@ -0,0 +1,152 @@ +/* user_settings_tls12.h + * + * Copyright (C) 2006-2024 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* Example for TLS v1.2 client only, ECC only, AES GCM only, SHA2-256 only */ +/* Derived using: + * ./configure --disable-rsa --disable-dh --disable-tls13 --disable-chacha --disable-poly1305 --disable-sha224 --disable-sha --disable-md5 + * And generated wolfssl/options.h + */ + +#ifndef WOLFSSL_USER_SETTINGS_H +#define WOLFSSL_USER_SETTINGS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* ------------------------------------------------------------------------- */ +/* Platform */ +/* ------------------------------------------------------------------------- */ +#define WOLFSSL_USER_IO /* Use the SetIO callbacks, not the internal wolfio.c socket code */ +#define WOLFSSL_IGNORE_FILE_WARN /* ignore file includes not required */ +//#define WOLFSSL_SMALL_STACK /* option to reduce stack size, offload to heap */ +#define NO_FILESYSTEM +#define NO_WRITEV +#define NO_SIG_WRAPPER + +/* ------------------------------------------------------------------------- */ +/* Math */ +/* ------------------------------------------------------------------------- */ +/* Math Options */ +#if 1 /* Single-precision (SP) wolf math - ECC only */ + #define WOLFSSL_HAVE_SP_ECC /* use sp_c32.c for math */ + #define WOLFSSL_SP_SMALL /* use smaller version of code */ + #define WOLFSSL_SP_MATH /* only SP math - eliminates fast math code */ + /* optional Cortex-M3+ speedup with inline assembly */ + //#define WOLFSSL_SP_ARM_CORTEX_M_ASM +#elif 1 + /* Multi-precision wolf math */ + #define WOLFSSL_SP_MATH_ALL /* use sp_int.c generic math */ + #define WOLFSSL_SP_SMALL /* use smaller version of code */ +#else + /* Fast Math - tfm.c */ + #define USE_FAST_MATH + #define TFM_TIMING_RESISTANT + #define WOLFSSL_NO_ASM +#endif + +/* ------------------------------------------------------------------------- */ +/* TLS */ +/* ------------------------------------------------------------------------- */ +/* Enable TLS v1.2 (on by default) */ +#undef WOLFSSL_NO_TLS12 +/* Disable TLS server code */ +#define NO_WOLFSSL_SERVER +//#define NO_WOLFSSL_CLIENT +/* Disable TLS v1.3 code */ +#undef WOLFSSL_TLS13 +/* Disable older TLS version prior to 1.2 */ +#define NO_OLD_TLS + +/* Enable default TLS extensions */ +#define HAVE_TLS_EXTENSIONS +#define HAVE_SUPPORTED_CURVES +#define HAVE_EXTENDED_MASTER +#define HAVE_ENCRYPT_THEN_MAC +#define HAVE_SERVER_RENEGOTIATION_INFO +//#define HAVE_SNI /* optional Server Name Indicator (SNI) */ + +/* ASN */ +#define WOLFSSL_ASN_TEMPLATE /* use newer ASN template asn.c code (default) */ + +/* Disable Features */ +#define NO_SESSION_CACHE /* disable session resumption */ +#define NO_PSK /* pre-shared-key support */ + +/* ------------------------------------------------------------------------- */ +/* Algorithms */ +/* ------------------------------------------------------------------------- */ +/* RNG */ +#define HAVE_HASHDRBG /* Use DRBG SHA2-256 and seed */ + +/* Enable ECC */ +#define HAVE_ECC +#define ECC_USER_CURVES /* Enable only ECC curves specific */ +#undef NO_ECC256 /* Enable SECP256R1 only (on by default) */ +#define ECC_TIMING_RESISTANT /* Enable Timing Resistance */ +/* Optional ECC calculation speed improvement if not using SP implementation */ +//#define ECC_SHAMIR + +/* Enable SHA2-256 only (on by default) */ +#undef NO_SHA256 +//#define USE_SLOW_SHA256 /* Reduces code size by not partially unrolling */ + +/* Enable AES GCM only */ +#define HAVE_AESGCM +#define GCM_SMALL /* use small GHASH table */ +#define NO_AES_CBC /* Disable AES CBC */ + +/* Optional Features */ +//#define WOLFSSL_BASE64_ENCODE /* Enable Base64 encoding */ + + +/* Disable Algorithms */ +#define NO_RSA +#define NO_DH +#define NO_SHA +#define NO_DSA +#define NO_RC4 +#define NO_MD4 +#define NO_MD5 +#define NO_DES3 +#define NO_PWDBASED +#define WOLFSSL_NO_SHAKE128 +#define WOLFSSL_NO_SHAKE256 + +/* ------------------------------------------------------------------------- */ +/* Debugging */ +/* ------------------------------------------------------------------------- */ +#undef DEBUG_WOLFSSL +#undef NO_ERROR_STRINGS +#if 0 + #define DEBUG_WOLFSSL +#else + #if 1 + #define NO_ERROR_STRINGS + #endif +#endif + +#ifdef __cplusplus +} +#endif + + +#endif /* WOLFSSL_USER_SETTINGS_H */ From 65902308e88c19193bf1c28b46de58eec389f9db Mon Sep 17 00:00:00 2001 From: Andras Fekete Date: Wed, 31 Jan 2024 15:56:17 -0500 Subject: [PATCH 35/63] Snapshots disappear after a while. Versioned releases stay. --- .github/workflows/docker-OpenWrt.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-OpenWrt.yml b/.github/workflows/docker-OpenWrt.yml index aa8278950a..aa89f450b0 100644 --- a/.github/workflows/docker-OpenWrt.yml +++ b/.github/workflows/docker-OpenWrt.yml @@ -34,7 +34,7 @@ jobs: strategy: fail-fast: false matrix: - release: [ "22.03-SNAPSHOT", "21.02-SNAPSHOT" ] # some other versions: 21.02.0 21.02.5 22.03.0 22.03.3 snapshot + release: [ "22.03.6", "21.02.7" ] # some other versions: 21.02.0 21.02.5 22.03.0 22.03.3 snapshot steps: - uses: actions/checkout@v3 - uses: docker/setup-buildx-action@v2 From f48eb638daa57000305bdf538f8e4a1847fcd3b8 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Wed, 31 Jan 2024 07:26:25 +1000 Subject: [PATCH 36/63] TLS 1.3, HRR Cookie: send cookie back in new ClientHello Make it mandatory that the cookie is sent back in new ClientHello when seen in a HelloRetryRequest. --- src/tls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tls.c b/src/tls.c index 04794ae944..7ce612cc19 100644 --- a/src/tls.c +++ b/src/tls.c @@ -6479,7 +6479,7 @@ static int TLSX_Cookie_Parse(WOLFSSL* ssl, const byte* input, word16 length, return BUFFER_E; if (msgType == hello_retry_request) - return TLSX_Cookie_Use(ssl, input + idx, len, NULL, 0, 0, + return TLSX_Cookie_Use(ssl, input + idx, len, NULL, 0, 1, &ssl->extensions); /* client_hello */ From 335c51987e5b58dff019a1f7522a76fb00621401 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 31 Jan 2024 13:36:34 +0100 Subject: [PATCH 37/63] openssh 9.6p1 fixes - wolfSSL_DSA_set0_key: allow setting just the public key - radix16: allow skipping the end of line whitespace - Add openssh action --- .github/workflows/openssh.yml | 72 +++++++++++++++++++++++++++++++++++ src/pk.c | 14 ++++--- wolfcrypt/src/misc.c | 12 ++++++ wolfcrypt/src/sp_int.c | 7 ++++ wolfcrypt/src/tfm.c | 5 +++ wolfssl/openssl/opensslv.h | 5 ++- wolfssl/wolfcrypt/misc.h | 1 + 7 files changed, 109 insertions(+), 7 deletions(-) create mode 100644 .github/workflows/openssh.yml diff --git a/.github/workflows/openssh.yml b/.github/workflows/openssh.yml new file mode 100644 index 0000000000..77b93c0b6d --- /dev/null +++ b/.github/workflows/openssh.yml @@ -0,0 +1,72 @@ +name: openssh Tests + +on: + workflow_call: + # TODO: remove this from PR + push: + +jobs: + build_wolfssl: + name: Build wolfSSL + # Just to keep it the same as the testing target + runs-on: ubuntu-latest + # This should be a safe limit for the tests to run. + timeout-minutes: 4 + steps: + - name: Build wolfSSL + uses: wolfSSL/actions-build-autotools-project@v1 + with: + path: wolfssl + configure: >- + --enable-openssh --enable-dsa --with-max-rsa-bits=8192 + --enable-intelasm --enable-sp-asm + install: true + + - name: Upload built lib + uses: actions/upload-artifact@v4 + with: + name: wolf-install-openssh + path: build-dir + retention-days: 1 + + openssh_check: + strategy: + fail-fast: false + matrix: + include: + - git_ref: 'V_9_6_P1' + osp_ver: '9.6' + name: ${{ matrix.ref }} + runs-on: ubuntu-latest + needs: build_wolfssl + steps: + - name: Download lib + uses: actions/download-artifact@v4 + with: + name: wolf-install-openssh + path: build-dir + + - name: Checkout OSP + uses: actions/checkout@v4 + with: + # TODO: update with wolfssl repo after merge + repository: julek-wolfssl/osp + ref: openssh-9.6 + path: osp + + - name: Build and test openssh + uses: wolfSSL/actions-build-autotools-project@v1 + with: + repository: openssh/openssh-portable + ref: ${{ matrix.git_ref }} + path: openssh + patch-file: $GITHUB_WORKSPACE/osp/openssh-patches/openssh-${{ matrix.osp_ver }}.patch + configure: --with-wolfssl=$GITHUB_WORKSPACE/build-dir --with-rpath=-Wl,-rpath= + check: false + + # make tests take >20 minutes. Consider limiting? + - name: Run tests + working-directory: ./openssh + run: | + # Run all the tests except (t-exec) as it takes too long + make file-tests interop-tests extra-tests unit diff --git a/src/pk.c b/src/pk.c index dfc362f699..4518766463 100644 --- a/src/pk.c +++ b/src/pk.c @@ -5033,15 +5033,19 @@ int wolfSSL_DSA_set0_key(WOLFSSL_DSA *d, WOLFSSL_BIGNUM *pub_key, WOLFSSL_ENTER("wolfSSL_DSA_set0_key"); /* The private key may be NULL */ - if (pub_key == NULL) { + if (d->pub_key == NULL && pub_key == NULL) { WOLFSSL_MSG("Bad parameter"); return 0; } - wolfSSL_BN_free(d->pub_key); - wolfSSL_BN_free(d->priv_key); - d->pub_key = pub_key; - d->priv_key = priv_key; + if (pub_key != NULL) { + wolfSSL_BN_free(d->pub_key); + d->pub_key = pub_key; + } + if (priv_key != NULL) { + wolfSSL_BN_free(d->priv_key); + d->priv_key = priv_key; + } return 1; } diff --git a/wolfcrypt/src/misc.c b/wolfcrypt/src/misc.c index c1726be217..6be10f665a 100644 --- a/wolfcrypt/src/misc.c +++ b/wolfcrypt/src/misc.c @@ -545,6 +545,18 @@ WC_MISC_STATIC WC_INLINE int ByteToHexStr(byte in, char* out) return 0; } +WC_MISC_STATIC WC_INLINE int CharIsWhiteSpace(char ch) +{ + switch (ch) { + case ' ': + case '\t': + case '\n': + return 1; + default: + return 0; + } +} + #ifndef WOLFSSL_NO_CT_OPS /* Constant time - mask set when a > b. */ WC_MISC_STATIC WC_INLINE byte ctMaskGT(int a, int b) diff --git a/wolfcrypt/src/sp_int.c b/wolfcrypt/src/sp_int.c index 3f8bfabfad..1b5cda87af 100644 --- a/wolfcrypt/src/sp_int.c +++ b/wolfcrypt/src/sp_int.c @@ -18068,6 +18068,8 @@ static int _sp_read_radix_16(sp_int* a, const char* in) unsigned int s = 0; unsigned int j = 0; sp_int_digit d; + /* Skip whitespace at end of line */ + int eol_done = 0; /* Make all nibbles in digit 0. */ d = 0; @@ -18078,9 +18080,12 @@ static int _sp_read_radix_16(sp_int* a, const char* in) int ch = (int)HexCharToByte(in[i]); /* Check for invalid character. */ if (ch < 0) { + if (!eol_done && CharIsWhiteSpace(in[i])) + continue; err = MP_VAL; break; } + eol_done = 1; /* Check whether we have filled the digit. */ if (s == SP_WORD_SIZE) { @@ -18150,6 +18155,8 @@ static int _sp_read_radix_10(sp_int* a, const char* in) ch -= '0'; } else { + if (CharIsWhiteSpace(ch)) + continue; /* Return error on invalid character. */ err = MP_VAL; break; diff --git a/wolfcrypt/src/tfm.c b/wolfcrypt/src/tfm.c index 1b07f5d597..ff895c8ac6 100644 --- a/wolfcrypt/src/tfm.c +++ b/wolfcrypt/src/tfm.c @@ -5945,6 +5945,8 @@ static int fp_read_radix_16(fp_int *a, const char *str) { int i, j, k, neg; int ch; + /* Skip whitespace at end of line */ + int eol_done = 0; /* if the leading digit is a * minus set the sign to negative. @@ -5961,8 +5963,11 @@ static int fp_read_radix_16(fp_int *a, const char *str) for (i = (int)(XSTRLEN(str) - 1); i >= 0; i--) { ch = (int)HexCharToByte(str[i]); if (ch < 0) { + if (!eol_done && CharIsWhiteSpace(str[i])) + continue; return FP_VAL; } + eol_done = 1; k += j == DIGIT_BIT; j &= DIGIT_BIT - 1; diff --git a/wolfssl/openssl/opensslv.h b/wolfssl/openssl/opensslv.h index c43e507baa..c426ef4311 100644 --- a/wolfssl/openssl/opensslv.h +++ b/wolfssl/openssl/opensslv.h @@ -36,7 +36,8 @@ /* valid version */ #elif defined(WOLFSSL_APACHE_HTTPD) || defined(HAVE_LIBEST) || \ defined(WOLFSSL_BIND) || defined(WOLFSSL_NGINX) || \ - defined(WOLFSSL_RSYSLOG) || defined(WOLFSSL_KRB) || defined(HAVE_STUNNEL) + defined(WOLFSSL_RSYSLOG) || defined(WOLFSSL_KRB) || defined(HAVE_STUNNEL) || \ + defined(WOLFSSL_OPENSSH) /* For Apache httpd, Use 1.1.0 compatibility */ #define OPENSSL_VERSION_NUMBER 0x10100003L #elif defined(WOLFSSL_QT) || defined(WOLFSSL_PYTHON) || defined(WOLFSSL_KRB) @@ -45,7 +46,7 @@ #elif defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_FFMPEG) #define OPENSSL_VERSION_NUMBER 0x1010000fL #elif defined(OPENSSL_ALL) || defined(HAVE_LIGHTY) || \ - defined(WOLFSSL_NGINX) || defined(WOLFSSL_OPENSSH) || defined(WOLFSSL_OPENVPN) + defined(WOLFSSL_NGINX) || defined(WOLFSSL_OPENVPN) /* version number can be increased for Lighty after compatibility for ECDH is added */ #define OPENSSL_VERSION_NUMBER 0x10001040L diff --git a/wolfssl/wolfcrypt/misc.h b/wolfssl/wolfcrypt/misc.h index 07d23e3898..2685c6cddd 100644 --- a/wolfssl/wolfcrypt/misc.h +++ b/wolfssl/wolfcrypt/misc.h @@ -114,6 +114,7 @@ word32 btoi(byte b); WOLFSSL_LOCAL signed char HexCharToByte(char ch); WOLFSSL_LOCAL char ByteToHex(byte in); WOLFSSL_LOCAL int ByteToHexStr(byte in, char* out); +WOLFSSL_LOCAL int CharIsWhiteSpace(char ch); WOLFSSL_LOCAL byte ctMaskGT(int a, int b); WOLFSSL_LOCAL byte ctMaskGTE(int a, int b); From 75762d44b6ac979a0c385730d0f8d27b1ae18f09 Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Mon, 29 Jan 2024 10:45:55 -0700 Subject: [PATCH 38/63] PKCS7 streaming with encode/sign --- wolfcrypt/src/asn.c | 95 ++++++++++++ wolfcrypt/src/pkcs7.c | 307 +++++++++++++++++++++++++++++++++----- wolfssl/wolfcrypt/asn.h | 4 + wolfssl/wolfcrypt/pkcs7.h | 8 + 4 files changed, 378 insertions(+), 36 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 3b61f6fb5f..fa1ab69934 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -3460,6 +3460,101 @@ word32 SetBitString(word32 len, byte unusedBits, byte* output) #endif /* !NO_RSA || HAVE_ECC || HAVE_ED25519 || HAVE_ED448 */ #ifdef ASN_BER_TO_DER + +#define BER_OCTET_LENGTH 4096 + + +/* Breaks an octet string up into chunks for use with streaming + * returns 0 on success and updates idx */ +int StreamOctetString(const byte* in, word32 inSz, byte* out, word32* outSz, + word32* idx) +{ + word32 i = 0; + word32 outIdx = *idx; + byte* tmp = out; + + if (tmp) tmp += outIdx; + + while (i < inSz) { + int ret, sz; + + sz = BER_OCTET_LENGTH; + + if ((sz + i) > inSz) { + sz = inSz - i; + } + + ret = SetOctetString(sz, tmp); + if (ret > 0) { + outIdx += ret; + } + + if (tmp) { + if (ret + sz + i + outIdx > *outSz) { + return BUFFER_E; + } + XMEMCPY(tmp + ret, in + i, sz); + tmp += sz + ret; + } + outIdx += sz; + i += sz; + } + + if (tmp) { + *idx = outIdx; + return 0; + } + else { + *outSz = outIdx; + return LENGTH_ONLY_E; + } +} + +long SetImplicitBer(byte tag, byte num, const byte* data, word32 dataSz, + byte* out, word32* outSz) +{ + word32 sz = 0; + long outIdx = 0; + byte berTag = tag; + + (void)num; + if (outSz == NULL || data == NULL) { + return BAD_FUNC_ARG; + } + + /* create a list of chuncked up octets */ + if (tag == ASN_OCTET_STRING) { + berTag = ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC; + } + + if (out != NULL) { + if (*outSz < 2) { + return BUFFER_E; + } + out[outIdx] = berTag; + out[outIdx + 1] = ASN_INDEF_LENGTH; + } + outIdx += 2; + + sz = *outSz; + StreamOctetString(data, dataSz, out, &sz, (word32*)&outIdx); + + if (out) { + out[outIdx] = 0x00; + out[outIdx + 1] = 0x00; + } + outIdx += 2; + + if (out) { + return outIdx; + } + else { + *outSz = outIdx; + return LENGTH_ONLY_E; + } +} + + /* Convert BER to DER */ /* Pull informtation from the ASN.1 BER encoded item header */ diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index e312520a1c..31da976bea 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -2462,7 +2462,22 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, esd->innerContSeqSz = 0; esd->contentInfoSeqSz = SetSequence(pkcs7->contentTypeSz, esd->contentInfoSeq); - } else { + } + else if (pkcs7->encodeStream) { + byte tmp[] = { 0xA0, 0x80 }; + byte tmpSeq[] = { 0x30, 0x80 }; + byte tmpStr[] = { 0x24, 0x80 }; + + XMEMCPY(esd->innerContSeq, tmp, 2); + esd->innerContSeqSz = 2; + + XMEMCPY(esd->contentInfoSeq, tmpSeq, 2); + esd->contentInfoSeqSz = 2; + + XMEMCPY(esd->innerOctets, tmpStr, 2); + esd->innerOctetsSz = 2; + } + else { esd->innerOctetsSz = SetOctetString(pkcs7->contentSz, esd->innerOctets); esd->innerContSeqSz = SetExplicit(0, esd->innerOctetsSz + pkcs7->contentSz, esd->innerContSeq); @@ -2577,10 +2592,12 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, /* certificates [0] IMPLICIT CertificateSet */ /* get total certificates size */ - certPtr = pkcs7->certList; - while (certPtr != NULL) { - certSetSz += certPtr->derSz; - certPtr = certPtr->next; + if (pkcs7->noCerts != 1) { + certPtr = pkcs7->certList; + while (certPtr != NULL) { + certSetSz += certPtr->derSz; + certPtr = certPtr->next; + } } certPtr = NULL; @@ -2603,19 +2620,48 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, totalSz = esd->versionSz + esd->singleDigAlgoIdSz + esd->digAlgoIdSetSz + esd->contentInfoSeqSz + pkcs7->contentTypeSz + - esd->innerContSeqSz + esd->innerOctetsSz + pkcs7->contentSz; + esd->innerContSeqSz + esd->innerOctetsSz; + + if (pkcs7->encodeStream) { + word32 sz = 0, tmpIdx = 0; + totalSz += 6; /* 00's for BER with inner content */ + + StreamOctetString(pkcs7->content, pkcs7->contentSz, NULL, &sz, &tmpIdx); + totalSz += sz + 6; + } + else { + totalSz += pkcs7->contentSz; + } total2Sz = esd->certsSetSz + certSetSz + signerInfoSz; if (pkcs7->detached) { totalSz -= pkcs7->contentSz; } - esd->innerSeqSz = SetSequence(totalSz + total2Sz, esd->innerSeq); - totalSz += esd->innerSeqSz; - esd->outerContentSz = SetExplicit(0, totalSz + total2Sz, esd->outerContent); - totalSz += esd->outerContentSz + signedDataOidSz; - esd->outerSeqSz = SetSequence(totalSz + total2Sz, esd->outerSeq); - totalSz += esd->outerSeqSz; + if (pkcs7->encodeStream) { + byte tmp[] = { 0xA0, 0x80 }; + byte tmpSeq[] = { 0x30, 0x80 }; + + XMEMCPY(esd->innerSeq, tmpSeq, 2); + esd->innerSeqSz = 2; + totalSz += esd->innerSeqSz + 2; + + XMEMCPY(esd->outerContent, tmp, 2); + esd->outerContentSz = 2; + totalSz += esd->outerContentSz + 2 + signedDataOidSz; + + XMEMCPY(esd->outerSeq, tmpSeq, 2); + esd->outerSeqSz = 2; + totalSz += esd->outerSeqSz + 2; + } + else { + esd->innerSeqSz = SetSequence(totalSz + total2Sz, esd->innerSeq); + totalSz += esd->innerSeqSz; + esd->outerContentSz = SetExplicit(0, totalSz + total2Sz, esd->outerContent); + totalSz += esd->outerContentSz + signedDataOidSz; + esd->outerSeqSz = SetSequence(totalSz + total2Sz, esd->outerSeq); + totalSz += esd->outerSeqSz; + } /* if using header/footer, we are not returning the content */ if (output2 && output2Sz) { @@ -2690,8 +2736,20 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, } else { if (!pkcs7->detached && pkcs7->content != NULL && pkcs7->contentSz > 0) { - XMEMCPY(output + idx, pkcs7->content, pkcs7->contentSz); - idx += pkcs7->contentSz; + if (pkcs7->encodeStream) { + StreamOctetString(pkcs7->content, pkcs7->contentSz, output, + outputSz, (word32*)&idx); + output[idx++] = 0x00; + output[idx++] = 0x00; + output[idx++] = 0x00; + output[idx++] = 0x00; + output[idx++] = 0x00; + output[idx++] = 0x00; + } + else { + XMEMCPY(output + idx, pkcs7->content, pkcs7->contentSz); + idx += pkcs7->contentSz; + } } output2 = output; } @@ -2699,12 +2757,16 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, /* certificates */ XMEMCPY(output2 + idx, esd->certsSet, esd->certsSetSz); idx += esd->certsSetSz; - certPtr = pkcs7->certList; - while (certPtr != NULL) { - XMEMCPY(output2 + idx, certPtr->der, certPtr->derSz); - idx += certPtr->derSz; - certPtr = certPtr->next; + + if (pkcs7->noCerts != 1) { + certPtr = pkcs7->certList; + while (certPtr != NULL) { + XMEMCPY(output2 + idx, certPtr->der, certPtr->derSz); + idx += certPtr->derSz; + certPtr = certPtr->next; + } } + wc_PKCS7_FreeCertSet(pkcs7); XMEMCPY(output2 + idx, esd->signerInfoSet, esd->signerInfoSetSz); @@ -2756,6 +2818,19 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, XMEMCPY(output2 + idx, esd->encContentDigest, esd->encContentDigestSz); idx += esd->encContentDigestSz; + if (pkcs7->encodeStream) { + byte tmp[] = { 0x00, 0x00 }; + + XMEMCPY(output2 + idx, tmp, 2); + idx += 2; + + XMEMCPY(output2 + idx, tmp, 2); + idx += 2; + + XMEMCPY(output2 + idx, tmp, 2); + idx += 2; + } + if (output2Sz) { *output2Sz = idx; idx = 0; /* success */ @@ -8584,13 +8659,29 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) return ret; } - encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0, encryptedOutSz, - encContentOctet); + if (pkcs7->encodeStream) { + int err; + byte tmp[] = { 0x30, 0x80}; - encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz + + err = SetImplicitBer(ASN_OCTET_STRING, 0, encryptedContent, + encryptedOutSz, NULL, (word32*)&encContentOctetSz); + + if (err != LENGTH_ONLY_E) { + + } + encContentOctetSz -= encryptedOutSz; + + XMEMCPY(encContentSeq, tmp, 2); + encContentSeqSz = 2; + } + else { + encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0, encryptedOutSz, + encContentOctet); + encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz + ivOctetStringSz + blockSz + encContentOctetSz + encryptedOutSz, encContentSeq); + } /* keep track of sizes for outer wrapper layering */ totalSz = verSz + recipSetSz + recipSz + encContentSeqSz + contentTypeSz + @@ -8598,18 +8689,46 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) encContentOctetSz + encryptedOutSz; /* EnvelopedData */ - envDataSeqSz = SetSequence(totalSz, envDataSeq); + if (pkcs7->encodeStream) { + byte tmp[] = { 0x30, 0x80}; + + /* account for ending of encContentSeq */ + totalSz += 2; + + XMEMCPY(envDataSeq, tmp, 2); + envDataSeqSz = 2; + totalSz += 2; /* 30 80 00 00 */ + } + else { + envDataSeqSz = SetSequence(totalSz, envDataSeq); + } totalSz += envDataSeqSz; /* outer content */ - outerContentSz = SetExplicit(0, totalSz, outerContent); + if (pkcs7->encodeStream) { + byte tmp[] = { 0xA0, 0x80}; + XMEMCPY(outerContent, tmp, 2); + outerContentSz = 2; + totalSz += 2; /* A0 80 00 00 */ + } + else { + outerContentSz = SetExplicit(0, totalSz, outerContent); + } totalSz += outerContentTypeSz; totalSz += outerContentSz; if (pkcs7->contentOID != FIRMWARE_PKG_DATA) { /* ContentInfo */ - contentInfoSeqSz = SetSequence(totalSz, contentInfoSeq); - totalSz += contentInfoSeqSz; + if (pkcs7->encodeStream) { + byte tmp[] = { 0x30, 0x80}; + XMEMCPY(contentInfoSeq, tmp, 2); + contentInfoSeqSz = 2; + totalSz += contentInfoSeqSz + 2; /* 30 80 00 00 */ + } + else { + contentInfoSeqSz = SetSequence(totalSz, contentInfoSeq); + totalSz += contentInfoSeqSz; + } } if (totalSz > (int)outputSz) { @@ -8628,6 +8747,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) XMEMCPY(output + idx, outerContent, outerContentSz); idx += outerContentSz; } + XMEMCPY(output + idx, envDataSeq, envDataSeqSz); idx += envDataSeqSz; XMEMCPY(output + idx, ver, verSz); @@ -8642,6 +8762,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) tmpRecip = tmpRecip->next; } wc_PKCS7_FreeEncodedRecipientSet(pkcs7); + XMEMCPY(output + idx, encContentSeq, encContentSeqSz); idx += encContentSeqSz; XMEMCPY(output + idx, contentType, contentTypeSz); @@ -8652,10 +8773,50 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) idx += ivOctetStringSz; XMEMCPY(output + idx, tmpIv, blockSz); idx += blockSz; - XMEMCPY(output + idx, encContentOctet, encContentOctetSz); - idx += encContentOctetSz; - XMEMCPY(output + idx, encryptedContent, encryptedOutSz); - idx += encryptedOutSz; + + /* stream the content (octet string with multiple octet elements) */ + if (pkcs7->encodeStream) { + int err; + byte* tmp; + byte tmpPad[] = { 0x00, 0x00}; + + tmp = XMALLOC(encContentOctetSz + encryptedOutSz, pkcs7->heap, + DYNAMIC_TYPE_PKCS7); + if (tmp == NULL) { + return MEMORY_E; + } + + err = SetImplicitBer(ASN_OCTET_STRING, 0, encryptedContent, + encryptedOutSz, tmp, (word32*)&encContentOctetSz); + if (err <= 0) { + return ASN_PARSE_E; + } + XMEMCPY(output + idx, tmp, err); + idx += err; + + /* end of encrypted content info */ + XMEMCPY(output + idx, tmpPad, 2); + idx += 2; + + /* end of Enveloped Data seq */ + XMEMCPY(output + idx, tmpPad, 2); + idx += 2; + + /* end of outer content set */ + XMEMCPY(output + idx, tmpPad, 2); + idx += 2; + + /* end of outer content info seq */ + XMEMCPY(output + idx, tmpPad, 2); + idx += 2; + XFREE(tmp, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + } + else { + XMEMCPY(output + idx, encContentOctet, encContentOctetSz); + idx += encContentOctetSz; + XMEMCPY(output + idx, encryptedContent, encryptedOutSz); + idx += encryptedOutSz; + } XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7); XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7); @@ -11655,9 +11816,21 @@ int wc_PKCS7_EncodeAuthEnvelopedData(PKCS7* pkcs7, byte* output, return BAD_FUNC_ARG; } - encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0, encryptedOutSz, - encContentOctet); + if (pkcs7->encodeStream) { + int err; + + err = SetImplicitBer(ASN_OCTET_STRING, 0, encryptedContent, + encryptedOutSz, NULL, (word32*)&encContentOctetSz); + if (err != LENGTH_ONLY_E) { + + } + encContentOctetSz -= encryptedOutSz; + } + else { + encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0, encryptedOutSz, + encContentOctet); + } encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz + nonceOctetStringSz + nonceSz + macIntSz + algoParamSeqSz + encContentOctetSz + @@ -11730,10 +11903,27 @@ int wc_PKCS7_EncodeAuthEnvelopedData(PKCS7* pkcs7, byte* output, idx += nonceSz; XMEMCPY(output + idx, macInt, macIntSz); idx += macIntSz; - XMEMCPY(output + idx, encContentOctet, encContentOctetSz); - idx += encContentOctetSz; - XMEMCPY(output + idx, encryptedContent, encryptedOutSz); - idx += encryptedOutSz; + + + if (pkcs7->encodeStream) { + int err; + + byte* tmp = malloc(encContentOctetSz + encryptedOutSz); + + err = SetImplicitBer(ASN_OCTET_STRING, 0, encryptedContent, + encryptedOutSz, tmp, (word32*)&encContentOctetSz); + if (err <= 0) { + return ASN_PARSE_E; + } + XMEMCPY(output + idx, tmp, encContentOctetSz); + idx += encContentOctetSz; + } + else { + XMEMCPY(output + idx, encContentOctet, encContentOctetSz); + idx += encContentOctetSz; + XMEMCPY(output + idx, encryptedContent, encryptedOutSz); + idx += encryptedOutSz; + } /* authenticated attributes */ if (flatAuthAttribs && authAttribsSz > 0) { @@ -13095,6 +13285,51 @@ int wc_PKCS7_SetDecodeEncryptedCtx(PKCS7* pkcs7, void* ctx) } #endif /* NO_PKCS7_ENCRYPTED_DATA */ + +/* set stream mode for encoding and signing + * returns 0 on success */ +int wc_PKCS7_SetStreamMode(PKCS7* pkcs7, byte flag) +{ + if (pkcs7 == NULL) { + return BAD_FUNC_ARG; + } + pkcs7->encodeStream = flag; + return 0; +} + + +/* returns to current stream mode flag on success, negative values on fail */ +int wc_PKCS7_GetStreamMode(PKCS7* pkcs7) +{ + if (pkcs7 == NULL) { + return BAD_FUNC_ARG; + } + return pkcs7->encodeStream; +} + + +/* set option to not include certificates when creating a bundle + * returns 0 on success */ +int wc_PKCS7_SetNoCerts(PKCS7* pkcs7, byte flag) +{ + if (pkcs7 == NULL) { + return BAD_FUNC_ARG; + } + pkcs7->noCerts = flag; + return 0; +} + + +/* returns the current noCerts flag value on success, negative values on fail */ +int wc_PKCS7_GetNoCerts(PKCS7* pkcs7) +{ + if (pkcs7 == NULL) { + return BAD_FUNC_ARG; + } + return pkcs7->noCerts; +} + + #if defined(HAVE_LIBZ) && !defined(NO_PKCS7_COMPRESSED_DATA) /* build PKCS#7 compressedData content type, return encrypted size */ diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index a1a5e0f620..ccc10e66ea 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -2100,6 +2100,8 @@ WOLFSSL_LOCAL int GetName(DecodedCert* cert, int nameType, int maxIdx); WOLFSSL_ASN_API int wc_BerToDer(const byte* ber, word32 berSz, byte* der, word32* derSz); +WOLFSSL_LOCAL int StreamOctetString(const byte* in, word32 inSz, byte* out, word32* outSz, + word32* idx); WOLFSSL_ASN_API void FreeAltNames(DNS_entry* altNames, void* heap); WOLFSSL_ASN_API DNS_entry* AltNameNew(void* heap); @@ -2279,6 +2281,8 @@ WOLFSSL_LOCAL word32 SetOctetString(word32 len, byte* output); WOLFSSL_LOCAL int SetASNInt(int len, byte firstByte, byte* output); WOLFSSL_LOCAL word32 SetBitString(word32 len, byte unusedBits, byte* output); WOLFSSL_LOCAL word32 SetImplicit(byte tag,byte number,word32 len,byte* output); +WOLFSSL_LOCAL long SetImplicitBer(byte tag, byte num, const byte* data, word32 dataSz, + byte* out, word32* outSz); WOLFSSL_LOCAL word32 SetExplicit(byte number, word32 len, byte* output); WOLFSSL_LOCAL word32 SetSet(word32 len, byte* output); WOLFSSL_API word32 SetAlgoID(int algoOID, byte* output, int type, int curveSz); diff --git a/wolfssl/wolfcrypt/pkcs7.h b/wolfssl/wolfcrypt/pkcs7.h index 1e2733c83a..556a54483c 100644 --- a/wolfssl/wolfcrypt/pkcs7.h +++ b/wolfssl/wolfcrypt/pkcs7.h @@ -247,7 +247,10 @@ struct PKCS7 { #ifdef ASN_BER_TO_DER byte* der; /* DER encoded version of message */ word32 derSz; + byte encodeStream; /* use BER when encoding */ #endif + byte noCerts:1; /* if certificates should be added into bundle + during creation */ byte* cert[MAX_PKCS7_CERTS]; /* array of certs parsed from bundle */ byte* verifyCert; /* cert from array used for verify */ word32 verifyCertSz; @@ -495,6 +498,11 @@ WOLFSSL_API int wc_PKCS7_SetDecodeEncryptedCb(PKCS7* pkcs7, WOLFSSL_API int wc_PKCS7_SetDecodeEncryptedCtx(PKCS7* pkcs7, void* ctx); #endif /* NO_PKCS7_ENCRYPTED_DATA */ +WOLFSSL_API int wc_PKCS7_SetStreamMode(PKCS7* pkcs7, byte flag); +WOLFSSL_API int wc_PKCS7_GetStreamMode(PKCS7* pkcs7); +WOLFSSL_API int wc_PKCS7_SetNoCerts(PKCS7* pkcs7, byte flag); +WOLFSSL_API int wc_PKCS7_GetNoCerts(PKCS7* pkcs7); + /* CMS/PKCS#7 CompressedData */ #if defined(HAVE_LIBZ) && !defined(NO_PKCS7_COMPRESSED_DATA) WOLFSSL_API int wc_PKCS7_EncodeCompressedData(PKCS7* pkcs7, byte* output, From c843064681046c878d2baa7e8e44118fded39f87 Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Tue, 30 Jan 2024 15:23:41 -0700 Subject: [PATCH 39/63] update macro guard --- wolfcrypt/src/pkcs7.c | 63 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 53 insertions(+), 10 deletions(-) diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 31da976bea..fb501781ce 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -2463,6 +2463,7 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, esd->contentInfoSeqSz = SetSequence(pkcs7->contentTypeSz, esd->contentInfoSeq); } +#ifdef ASN_BER_TO_DER else if (pkcs7->encodeStream) { byte tmp[] = { 0xA0, 0x80 }; byte tmpSeq[] = { 0x30, 0x80 }; @@ -2477,6 +2478,7 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, XMEMCPY(esd->innerOctets, tmpStr, 2); esd->innerOctetsSz = 2; } +#endif else { esd->innerOctetsSz = SetOctetString(pkcs7->contentSz, esd->innerOctets); esd->innerContSeqSz = SetExplicit(0, esd->innerOctetsSz + @@ -2622,6 +2624,7 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, esd->contentInfoSeqSz + pkcs7->contentTypeSz + esd->innerContSeqSz + esd->innerOctetsSz; +#ifdef ASN_BER_TO_DER if (pkcs7->encodeStream) { word32 sz = 0, tmpIdx = 0; totalSz += 6; /* 00's for BER with inner content */ @@ -2629,7 +2632,9 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, StreamOctetString(pkcs7->content, pkcs7->contentSz, NULL, &sz, &tmpIdx); totalSz += sz + 6; } - else { + else +#endif + { totalSz += pkcs7->contentSz; } total2Sz = esd->certsSetSz + certSetSz + signerInfoSz; @@ -2638,6 +2643,7 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, totalSz -= pkcs7->contentSz; } +#ifdef ASN_BER_TO_DER if (pkcs7->encodeStream) { byte tmp[] = { 0xA0, 0x80 }; byte tmpSeq[] = { 0x30, 0x80 }; @@ -2654,7 +2660,9 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, esd->outerSeqSz = 2; totalSz += esd->outerSeqSz + 2; } - else { + else +#endif + { esd->innerSeqSz = SetSequence(totalSz + total2Sz, esd->innerSeq); totalSz += esd->innerSeqSz; esd->outerContentSz = SetExplicit(0, totalSz + total2Sz, esd->outerContent); @@ -2736,6 +2744,7 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, } else { if (!pkcs7->detached && pkcs7->content != NULL && pkcs7->contentSz > 0) { + #ifdef ASN_BER_TO_DER if (pkcs7->encodeStream) { StreamOctetString(pkcs7->content, pkcs7->contentSz, output, outputSz, (word32*)&idx); @@ -2746,7 +2755,9 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, output[idx++] = 0x00; output[idx++] = 0x00; } - else { + else + #endif + { XMEMCPY(output + idx, pkcs7->content, pkcs7->contentSz); idx += pkcs7->contentSz; } @@ -2818,6 +2829,7 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, XMEMCPY(output2 + idx, esd->encContentDigest, esd->encContentDigestSz); idx += esd->encContentDigestSz; +#ifdef ASN_BER_TO_DER if (pkcs7->encodeStream) { byte tmp[] = { 0x00, 0x00 }; @@ -2830,6 +2842,7 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, XMEMCPY(output2 + idx, tmp, 2); idx += 2; } +#endif if (output2Sz) { *output2Sz = idx; @@ -8659,6 +8672,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) return ret; } +#ifdef ASN_BER_TO_DER if (pkcs7->encodeStream) { int err; byte tmp[] = { 0x30, 0x80}; @@ -8674,7 +8688,9 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) XMEMCPY(encContentSeq, tmp, 2); encContentSeqSz = 2; } - else { + else +#endif + { encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0, encryptedOutSz, encContentOctet); encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz + @@ -8689,6 +8705,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) encContentOctetSz + encryptedOutSz; /* EnvelopedData */ +#ifdef ASN_BER_TO_DER if (pkcs7->encodeStream) { byte tmp[] = { 0x30, 0x80}; @@ -8699,19 +8716,24 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) envDataSeqSz = 2; totalSz += 2; /* 30 80 00 00 */ } - else { + else +#endif + { envDataSeqSz = SetSequence(totalSz, envDataSeq); } totalSz += envDataSeqSz; /* outer content */ +#ifdef ASN_BER_TO_DER if (pkcs7->encodeStream) { byte tmp[] = { 0xA0, 0x80}; XMEMCPY(outerContent, tmp, 2); outerContentSz = 2; totalSz += 2; /* A0 80 00 00 */ } - else { + else +#endif + { outerContentSz = SetExplicit(0, totalSz, outerContent); } totalSz += outerContentTypeSz; @@ -8719,13 +8741,16 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) if (pkcs7->contentOID != FIRMWARE_PKG_DATA) { /* ContentInfo */ + #ifdef ASN_BER_TO_DER if (pkcs7->encodeStream) { byte tmp[] = { 0x30, 0x80}; XMEMCPY(contentInfoSeq, tmp, 2); contentInfoSeqSz = 2; totalSz += contentInfoSeqSz + 2; /* 30 80 00 00 */ } - else { + else + #endif + { contentInfoSeqSz = SetSequence(totalSz, contentInfoSeq); totalSz += contentInfoSeqSz; } @@ -8775,6 +8800,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) idx += blockSz; /* stream the content (octet string with multiple octet elements) */ +#ifdef ASN_BER_TO_DER if (pkcs7->encodeStream) { int err; byte* tmp; @@ -8811,7 +8837,9 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) idx += 2; XFREE(tmp, pkcs7->heap, DYNAMIC_TYPE_PKCS7); } - else { + else +#endif + { XMEMCPY(output + idx, encContentOctet, encContentOctetSz); idx += encContentOctetSz; XMEMCPY(output + idx, encryptedContent, encryptedOutSz); @@ -11816,6 +11844,7 @@ int wc_PKCS7_EncodeAuthEnvelopedData(PKCS7* pkcs7, byte* output, return BAD_FUNC_ARG; } +#ifdef ASN_BER_TO_DER if (pkcs7->encodeStream) { int err; @@ -11827,7 +11856,9 @@ int wc_PKCS7_EncodeAuthEnvelopedData(PKCS7* pkcs7, byte* output, } encContentOctetSz -= encryptedOutSz; } - else { + else +#endif + { encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0, encryptedOutSz, encContentOctet); } @@ -11905,6 +11936,7 @@ int wc_PKCS7_EncodeAuthEnvelopedData(PKCS7* pkcs7, byte* output, idx += macIntSz; +#ifdef ASN_BER_TO_DER if (pkcs7->encodeStream) { int err; @@ -11918,7 +11950,9 @@ int wc_PKCS7_EncodeAuthEnvelopedData(PKCS7* pkcs7, byte* output, XMEMCPY(output + idx, tmp, encContentOctetSz); idx += encContentOctetSz; } - else { + else +#endif + { XMEMCPY(output + idx, encContentOctet, encContentOctetSz); idx += encContentOctetSz; XMEMCPY(output + idx, encryptedContent, encryptedOutSz); @@ -13293,8 +13327,13 @@ int wc_PKCS7_SetStreamMode(PKCS7* pkcs7, byte flag) if (pkcs7 == NULL) { return BAD_FUNC_ARG; } +#ifdef ASN_BER_TO_DER pkcs7->encodeStream = flag; return 0; +#else + (void)flag; + return NOT_COMPILED_IN; +#endif } @@ -13304,7 +13343,11 @@ int wc_PKCS7_GetStreamMode(PKCS7* pkcs7) if (pkcs7 == NULL) { return BAD_FUNC_ARG; } +#ifdef ASN_BER_TO_DER return pkcs7->encodeStream; +#else + return 0; +#endif } From bf23357c8c18f3ed982240495fc46bc6caf81907 Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Thu, 1 Feb 2024 09:55:18 -0700 Subject: [PATCH 40/63] refactor streaming and additional comments --- wolfcrypt/src/asn.c | 123 +++++++-------- wolfcrypt/src/pkcs12.c | 2 +- wolfcrypt/src/pkcs7.c | 306 +++++++++++++------------------------- wolfssl/wolfcrypt/asn.h | 13 +- wolfssl/wolfcrypt/pkcs7.h | 2 +- 5 files changed, 181 insertions(+), 265 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index fa1ab69934..b3210fb40b 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -3463,6 +3463,18 @@ word32 SetBitString(word32 len, byte unusedBits, byte* output) #define BER_OCTET_LENGTH 4096 +/* sets the terminating 0x00 0x00 at the end of an indefinite length + * returns the number of bytes written */ +word32 SetIndefEnd(byte* in) +{ + byte terminate[] = { 0x00, 0x00 }; + + if (in != NULL) { + XMEMCPY(in, terminate, 2); + } + return 2; +} + /* Breaks an octet string up into chunks for use with streaming * returns 0 on success and updates idx */ @@ -3510,50 +3522,6 @@ int StreamOctetString(const byte* in, word32 inSz, byte* out, word32* outSz, } } -long SetImplicitBer(byte tag, byte num, const byte* data, word32 dataSz, - byte* out, word32* outSz) -{ - word32 sz = 0; - long outIdx = 0; - byte berTag = tag; - - (void)num; - if (outSz == NULL || data == NULL) { - return BAD_FUNC_ARG; - } - - /* create a list of chuncked up octets */ - if (tag == ASN_OCTET_STRING) { - berTag = ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC; - } - - if (out != NULL) { - if (*outSz < 2) { - return BUFFER_E; - } - out[outIdx] = berTag; - out[outIdx + 1] = ASN_INDEF_LENGTH; - } - outIdx += 2; - - sz = *outSz; - StreamOctetString(data, dataSz, out, &sz, (word32*)&outIdx); - - if (out) { - out[outIdx] = 0x00; - out[outIdx + 1] = 0x00; - } - outIdx += 2; - - if (out) { - return outIdx; - } - else { - *outSz = outIdx; - return LENGTH_ONLY_E; - } -} - /* Convert BER to DER */ @@ -15429,6 +15397,16 @@ word32 SetLength(word32 length, byte* output) return i; } +word32 SetLengthEx(word32 length, byte* output, byte isIndef) +{ + if (isIndef) { + output[0] = ASN_INDEF_LENGTH; + return 1; + } + else { + return SetLength(length, output); + } +} /* Encode a DER header - type/tag and length. * * @param [in] tag DER tag of ASN.1 item. @@ -15436,14 +15414,15 @@ word32 SetLength(word32 length, byte* output) * @param [out] output Buffer to encode into. * @return Number of bytes encoded. */ -static word32 SetHeader(byte tag, word32 len, byte* output) +static word32 SetHeader(byte tag, word32 len, byte* output, byte isIndef) { if (output) { /* Encode tag first. */ output[0] = tag; } /* Encode the length. */ - return SetLength(len, output ? output + ASN_TAG_SZ : NULL) + ASN_TAG_SZ; + return SetLengthEx(len, output ? output + ASN_TAG_SZ : NULL, isIndef) + + ASN_TAG_SZ; } /* Encode a SEQUENCE header in DER. @@ -15454,7 +15433,12 @@ static word32 SetHeader(byte tag, word32 len, byte* output) */ word32 SetSequence(word32 len, byte* output) { - return SetHeader(ASN_SEQUENCE | ASN_CONSTRUCTED, len, output); + return SetHeader(ASN_SEQUENCE | ASN_CONSTRUCTED, len, output, 0); +} + +word32 SetSequenceEx(word32 len, byte* output, byte isIndef) +{ + return SetHeader(ASN_SEQUENCE | ASN_CONSTRUCTED, len, output, isIndef); } /* Encode an OCTET STRING header in DER. @@ -15465,7 +15449,14 @@ word32 SetSequence(word32 len, byte* output) */ word32 SetOctetString(word32 len, byte* output) { - return SetHeader(ASN_OCTET_STRING, len, output); + return SetHeader(ASN_OCTET_STRING, len, output, 0); +} + +word32 SetOctetStringEx(word32 len, byte* output, byte indef) +{ + if (indef) + return SetHeader(ASN_OCTET_STRING | ASN_CONSTRUCTED, len, output, indef); + return SetOctetString(len, output); } /* Encode a SET header in DER. @@ -15476,7 +15467,7 @@ word32 SetOctetString(word32 len, byte* output) */ word32 SetSet(word32 len, byte* output) { - return SetHeader(ASN_SET | ASN_CONSTRUCTED, len, output); + return SetHeader(ASN_SET | ASN_CONSTRUCTED, len, output, 0); } /* Encode an implicit context specific header in DER. @@ -15489,11 +15480,23 @@ word32 SetSet(word32 len, byte* output) * @param [out] output Buffer to encode into. * @return Number of bytes encoded. */ -word32 SetImplicit(byte tag, byte number, word32 len, byte* output) +word32 SetImplicit(byte tag, byte number, word32 len, byte* output, byte isIndef) { - tag = (byte)(((tag == ASN_SEQUENCE || tag == ASN_SET) ? ASN_CONSTRUCTED : 0) - | ASN_CONTEXT_SPECIFIC | number); - return SetHeader(tag, len, output); + int useIndef = 0; + + if ((tag == ASN_OCTET_STRING) && isIndef) { + tag = ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | number; + } + else { + tag = (byte)(((tag == ASN_SEQUENCE || tag == ASN_SET) ? + ASN_CONSTRUCTED : 0) | ASN_CONTEXT_SPECIFIC | number); + } + + if (isIndef && (tag & ASN_CONSTRUCTED)) { + useIndef = 1; + } + + return SetHeader(tag, len, output, useIndef); } /* Encode an explicit context specific header in DER. @@ -15505,10 +15508,10 @@ word32 SetImplicit(byte tag, byte number, word32 len, byte* output) * @param [out] output Buffer to encode into. * @return Number of bytes encoded. */ -word32 SetExplicit(byte number, word32 len, byte* output) +word32 SetExplicit(byte number, word32 len, byte* output, byte isIndef) { return SetHeader((byte)(ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | number), - len, output); + len, output, isIndef); } #if defined(OPENSSL_EXTRA) @@ -15534,8 +15537,8 @@ word32 SetOthername(void *name, byte *output) nameSz = (word32)nm->value->value.utf8string->length; len = nm->type_id->objSz + - SetHeader(ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC, nameSz + 2, NULL) + - SetHeader(CTC_UTF8, nameSz, NULL) + nameSz; + SetHeader(ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC, nameSz + 2, NULL, 0) + + SetHeader(CTC_UTF8, nameSz, NULL, 0) + nameSz; if (output != NULL) { /* otherName OID */ @@ -15543,9 +15546,9 @@ word32 SetOthername(void *name, byte *output) output += nm->type_id->objSz; output += SetHeader(ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC, nameSz + 2, - output); + output, 0); - output += SetHeader(CTC_UTF8, nameSz, output); + output += SetHeader(CTC_UTF8, nameSz, output, 0); XMEMCPY(output, nameStr, nameSz); } @@ -34549,7 +34552,7 @@ int SetAsymKeyDer(const byte* privKey, word32 privKeyLen, /* pubKey */ if (pubKey) { idx += SetHeader(ASN_CONTEXT_SPECIFIC | ASN_ASYMKEY_PUBKEY | - 1, pubKeyLen, output + idx); + 1, pubKeyLen, output + idx, 0); XMEMCPY(output + idx, pubKey, pubKeyLen); idx += pubKeyLen; } diff --git a/wolfcrypt/src/pkcs12.c b/wolfcrypt/src/pkcs12.c index 22e641508d..123b2e9db4 100644 --- a/wolfcrypt/src/pkcs12.c +++ b/wolfcrypt/src/pkcs12.c @@ -1836,7 +1836,7 @@ static int wc_PKCS12_shroud_key(WC_PKCS12* pkcs12, WC_RNG* rng, /* rewind index and set tag and length */ tmpIdx -= MAX_LENGTH_SZ + 1; - sz = (word32)SetExplicit(0, (word32)ret, out + tmpIdx); + sz = (word32)SetExplicit(0, (word32)ret, out + tmpIdx, 0); tmpIdx += sz; totalSz += sz; XMEMMOVE(out + tmpIdx, out + MAX_LENGTH_SZ + 1, (size_t)ret); diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index fb501781ce..4998205e52 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -2463,29 +2463,16 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, esd->contentInfoSeqSz = SetSequence(pkcs7->contentTypeSz, esd->contentInfoSeq); } -#ifdef ASN_BER_TO_DER - else if (pkcs7->encodeStream) { - byte tmp[] = { 0xA0, 0x80 }; - byte tmpSeq[] = { 0x30, 0x80 }; - byte tmpStr[] = { 0x24, 0x80 }; - - XMEMCPY(esd->innerContSeq, tmp, 2); - esd->innerContSeqSz = 2; - - XMEMCPY(esd->contentInfoSeq, tmpSeq, 2); - esd->contentInfoSeqSz = 2; - - XMEMCPY(esd->innerOctets, tmpStr, 2); - esd->innerOctetsSz = 2; - } -#endif else { - esd->innerOctetsSz = SetOctetString(pkcs7->contentSz, esd->innerOctets); + esd->innerOctetsSz = SetOctetStringEx(pkcs7->contentSz, esd->innerOctets, + pkcs7->encodeStream); esd->innerContSeqSz = SetExplicit(0, esd->innerOctetsSz + - pkcs7->contentSz, esd->innerContSeq); - esd->contentInfoSeqSz = SetSequence(pkcs7->contentSz + + pkcs7->contentSz, esd->innerContSeq, + pkcs7->encodeStream); + esd->contentInfoSeqSz = SetSequenceEx(pkcs7->contentSz + esd->innerOctetsSz + pkcs7->contentTypeSz + - esd->innerContSeqSz, esd->contentInfoSeq); + esd->innerContSeqSz, esd->contentInfoSeq, + pkcs7->encodeStream); } /* SignerIdentifier */ @@ -2512,7 +2499,7 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, /* SubjectKeyIdentifier */ esd->issuerSKIDSz = SetOctetString(keyIdSize, esd->issuerSKID); esd->issuerSKIDSeqSz = SetExplicit(0, esd->issuerSKIDSz + keyIdSize, - esd->issuerSKIDSeq); + esd->issuerSKIDSeq, 0); signerInfoSz += (esd->issuerSKIDSz + esd->issuerSKIDSeqSz + keyIdSize); /* version MUST be 3 */ @@ -2567,7 +2554,7 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, FlattenAttributes(pkcs7, flatSignedAttribs, esd->signedAttribs, esd->signedAttribsCount); esd->signedAttribSetSz = SetImplicit(ASN_SET, 0, esd->signedAttribsSz, - esd->signedAttribSet); + esd->signedAttribSet, 0); } else { esd->signedAttribSetSz = 0; } @@ -2604,7 +2591,7 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, certPtr = NULL; if (certSetSz > 0) - esd->certsSetSz = SetImplicit(ASN_SET, 0, certSetSz, esd->certsSet); + esd->certsSetSz = SetImplicit(ASN_SET, 0, certSetSz, esd->certsSet, 0); if (pkcs7->sidType != DEGENERATE_SID) { esd->singleDigAlgoIdSz = SetAlgoID(pkcs7->hashOID, esd->singleDigAlgoId, @@ -2627,10 +2614,10 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, #ifdef ASN_BER_TO_DER if (pkcs7->encodeStream) { word32 sz = 0, tmpIdx = 0; - totalSz += 6; /* 00's for BER with inner content */ + totalSz += (3 * ASN_INDEF_END_SZ) ; /* 00's for BER with inner content */ StreamOctetString(pkcs7->content, pkcs7->contentSz, NULL, &sz, &tmpIdx); - totalSz += sz + 6; + totalSz += sz + (3 * ASN_INDEF_END_SZ); } else #endif @@ -2643,32 +2630,27 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, totalSz -= pkcs7->contentSz; } -#ifdef ASN_BER_TO_DER - if (pkcs7->encodeStream) { - byte tmp[] = { 0xA0, 0x80 }; - byte tmpSeq[] = { 0x30, 0x80 }; - - XMEMCPY(esd->innerSeq, tmpSeq, 2); - esd->innerSeqSz = 2; - totalSz += esd->innerSeqSz + 2; - - XMEMCPY(esd->outerContent, tmp, 2); - esd->outerContentSz = 2; - totalSz += esd->outerContentSz + 2 + signedDataOidSz; - - XMEMCPY(esd->outerSeq, tmpSeq, 2); - esd->outerSeqSz = 2; - totalSz += esd->outerSeqSz + 2; - } - else -#endif { - esd->innerSeqSz = SetSequence(totalSz + total2Sz, esd->innerSeq); + esd->innerSeqSz = SetSequenceEx(totalSz + total2Sz, esd->innerSeq, + pkcs7->encodeStream); totalSz += esd->innerSeqSz; - esd->outerContentSz = SetExplicit(0, totalSz + total2Sz, esd->outerContent); + if (pkcs7->encodeStream) { + totalSz += ASN_INDEF_END_SZ; + } + + esd->outerContentSz = SetExplicit(0, totalSz + total2Sz, + esd->outerContent, pkcs7->encodeStream); totalSz += esd->outerContentSz + signedDataOidSz; - esd->outerSeqSz = SetSequence(totalSz + total2Sz, esd->outerSeq); + if (pkcs7->encodeStream) { + totalSz += ASN_INDEF_END_SZ; + } + + esd->outerSeqSz = SetSequenceEx(totalSz + total2Sz, esd->outerSeq, + pkcs7->encodeStream); totalSz += esd->outerSeqSz; + if (pkcs7->encodeStream) { + totalSz += ASN_INDEF_END_SZ; + } } /* if using header/footer, we are not returning the content */ @@ -2748,12 +2730,15 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, if (pkcs7->encodeStream) { StreamOctetString(pkcs7->content, pkcs7->contentSz, output, outputSz, (word32*)&idx); - output[idx++] = 0x00; - output[idx++] = 0x00; - output[idx++] = 0x00; - output[idx++] = 0x00; - output[idx++] = 0x00; - output[idx++] = 0x00; + + /* end of content octet string */ + idx += SetIndefEnd(output + idx); + + /* end of inner content seq */ + idx += SetIndefEnd(output + idx); + + /* end of inner content info seq */ + idx += SetIndefEnd(output + idx); } else #endif @@ -2831,16 +2816,14 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, #ifdef ASN_BER_TO_DER if (pkcs7->encodeStream) { - byte tmp[] = { 0x00, 0x00 }; - - XMEMCPY(output2 + idx, tmp, 2); - idx += 2; + /* end of signedData seq */ + idx += SetIndefEnd(output2 + idx); - XMEMCPY(output2 + idx, tmp, 2); - idx += 2; + /* end of outer content set */ + idx += SetIndefEnd(output2 + idx); - XMEMCPY(output2 + idx, tmp, 2); - idx += 2; + /* end of outer content info seq */ + idx += SetIndefEnd(output2 + idx); } #endif @@ -6097,7 +6080,7 @@ static int wc_PKCS7_KariGenerateSharedInfo(WC_PKCS7_KARI* kari, int keyWrapOID) /* suppPubInfo */ suppPubInfoSeqSz = SetImplicit(ASN_SEQUENCE, 2, kekOctetSz + sizeof(word32), - suppPubInfoSeq); + suppPubInfoSeq, 0); sharedInfoSz += suppPubInfoSeqSz; /* optional ukm/entityInfo */ @@ -6107,7 +6090,7 @@ static int wc_PKCS7_KariGenerateSharedInfo(WC_PKCS7_KARI* kari, int keyWrapOID) entityUInfoExplicitSz = SetExplicit(0, entityUInfoOctetSz + kari->ukmSz, - entityUInfoExplicitSeq); + entityUInfoExplicitSeq, 0); sharedInfoSz += entityUInfoExplicitSz; } @@ -6483,7 +6466,7 @@ int wc_PKCS7_AddRecipient_KARI(PKCS7* pkcs7, const byte* cert, word32 certSz, /* RecipientKeyIdentifier IMPLICIT [0] */ recipKeyIdSeqSz = SetImplicit(ASN_SEQUENCE, 0, subjKeyIdOctetSz + - keyIdSize, recipKeyIdSeq); + keyIdSize, recipKeyIdSeq, 0); totalSz += recipKeyIdSeqSz; /* RecipientEncryptedKey */ @@ -6501,7 +6484,7 @@ int wc_PKCS7_AddRecipient_KARI(PKCS7* pkcs7, const byte* cert, word32 certSz, totalSz += (ukmOctetSz + kari->ukmSz); ukmExplicitSz = SetExplicit(1, ukmOctetSz + kari->ukmSz, - ukmExplicitSeq); + ukmExplicitSeq, 0); totalSz += ukmExplicitSz; } @@ -6535,14 +6518,14 @@ int wc_PKCS7_AddRecipient_KARI(PKCS7* pkcs7, const byte* cert, word32 certSz, /* outer OriginatorPublicKey IMPLICIT [1] */ origPubKeySeqSz = SetImplicit(ASN_SEQUENCE, 1, origAlgIdSz + origPubKeyStrSz + - kari->senderKeyExportSz, origPubKeySeq); + kari->senderKeyExportSz, origPubKeySeq, 0); totalSz += origPubKeySeqSz; /* outer OriginatorIdentifierOrKey IMPLICIT [0] */ origIdOrKeySeqSz = SetImplicit(ASN_SEQUENCE, 0, origPubKeySeqSz + origAlgIdSz + origPubKeyStrSz + kari->senderKeyExportSz, - origIdOrKeySeq); + origIdOrKeySeq, 0); totalSz += origIdOrKeySeqSz; /* version, always 3 */ @@ -6551,7 +6534,7 @@ int wc_PKCS7_AddRecipient_KARI(PKCS7* pkcs7, const byte* cert, word32 certSz, recip->recipVersion = 3; /* outer IMPLICIT [1] kari */ - kariSeqSz = SetImplicit(ASN_SEQUENCE, 1, totalSz, kariSeq); + kariSeqSz = SetImplicit(ASN_SEQUENCE, 1, totalSz, kariSeq, 0); totalSz += kariSeqSz; if (totalSz > MAX_RECIP_SZ) { @@ -7666,7 +7649,7 @@ int wc_PKCS7_AddRecipient_ORI(PKCS7* pkcs7, CallbackOriEncrypt oriEncryptCb, oriTypeLenSz = SetLength(oriTypeSz, oriTypeLen); recipSeqSz = SetImplicit(ASN_SEQUENCE, 4, 1 + oriTypeLenSz + oriTypeSz + - oriValueSz, recipSeq); + oriValueSz, recipSeq, 0); idx = 0; XMEMCPY(recip->recip + idx, recipSeq, recipSeqSz); @@ -8116,7 +8099,7 @@ int wc_PKCS7_AddRecipient_PWRI(PKCS7* pkcs7, byte* passwd, word32 pLen, /* set KeyDerivationAlgorithmIdentifier EXPLICIT [0] SEQ */ kdfAlgoIdSeqSz = SetExplicit(0, kdfAlgoIdSz + kdfParamsSeqSz + kdfSaltOctetStrSz + saltSz + kdfIterationsSz, - kdfAlgoIdSeq); + kdfAlgoIdSeq, 0); totalSz += kdfAlgoIdSeqSz; /* set PasswordRecipientInfo CMSVersion, MUST be 0 */ @@ -8125,7 +8108,7 @@ int wc_PKCS7_AddRecipient_PWRI(PKCS7* pkcs7, byte* passwd, word32 pLen, recip->recipVersion = 0; /* set PasswordRecipientInfo SEQ */ - recipSeqSz = SetImplicit(ASN_SEQUENCE, 3, totalSz, recipSeq); + recipSeqSz = SetImplicit(ASN_SEQUENCE, 3, totalSz, recipSeq, 0); totalSz += recipSeqSz; if (totalSz > MAX_RECIP_SZ) { @@ -8368,7 +8351,7 @@ int wc_PKCS7_AddRecipient_KEKRI(PKCS7* pkcs7, int keyWrapOID, byte* kek, recip->recipVersion = 4; /* KEKRecipientInfo SEQ */ - recipSeqSz = SetImplicit(ASN_SEQUENCE, 2, totalSz, recipSeq); + recipSeqSz = SetImplicit(ASN_SEQUENCE, 2, totalSz, recipSeq, 0); totalSz += recipSeqSz; if (totalSz > MAX_RECIP_SZ) { @@ -8672,32 +8655,12 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) return ret; } -#ifdef ASN_BER_TO_DER - if (pkcs7->encodeStream) { - int err; - byte tmp[] = { 0x30, 0x80}; - - err = SetImplicitBer(ASN_OCTET_STRING, 0, encryptedContent, - encryptedOutSz, NULL, (word32*)&encContentOctetSz); - - if (err != LENGTH_ONLY_E) { - - } - encContentOctetSz -= encryptedOutSz; - - XMEMCPY(encContentSeq, tmp, 2); - encContentSeqSz = 2; - } - else -#endif - { - encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0, encryptedOutSz, - encContentOctet); - encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz + - ivOctetStringSz + blockSz + - encContentOctetSz + encryptedOutSz, - encContentSeq); - } + encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0, encryptedOutSz, + encContentOctet, pkcs7->encodeStream); + encContentSeqSz = SetSequenceEx(contentTypeSz + contentEncAlgoSz + + ivOctetStringSz + blockSz + + encContentOctetSz + encryptedOutSz, + encContentSeq, pkcs7->encodeStream); /* keep track of sizes for outer wrapper layering */ totalSz = verSz + recipSetSz + recipSz + encContentSeqSz + contentTypeSz + @@ -8707,53 +8670,47 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) /* EnvelopedData */ #ifdef ASN_BER_TO_DER if (pkcs7->encodeStream) { - byte tmp[] = { 0x30, 0x80}; + word32 streamSz = 0, tmpIdx = 0; + + /* account for ending of encContentOctet */ + totalSz += ASN_INDEF_END_SZ; /* account for ending of encContentSeq */ - totalSz += 2; + totalSz += ASN_INDEF_END_SZ; - XMEMCPY(envDataSeq, tmp, 2); - envDataSeqSz = 2; - totalSz += 2; /* 30 80 00 00 */ + /* account for asn1 syntax around octet strings */ + StreamOctetString(NULL, encryptedOutSz, NULL, &streamSz, &tmpIdx); + totalSz += (streamSz - encryptedOutSz); } - else #endif - { - envDataSeqSz = SetSequence(totalSz, envDataSeq); - } + envDataSeqSz = SetSequenceEx(totalSz, envDataSeq, pkcs7->encodeStream); totalSz += envDataSeqSz; +#ifdef ASN_BER_TO_DER + if (pkcs7->encodeStream) { + totalSz += ASN_INDEF_END_SZ; + } +#endif /* outer content */ + outerContentSz = SetExplicit(0, totalSz, outerContent, pkcs7->encodeStream); #ifdef ASN_BER_TO_DER if (pkcs7->encodeStream) { - byte tmp[] = { 0xA0, 0x80}; - XMEMCPY(outerContent, tmp, 2); - outerContentSz = 2; - totalSz += 2; /* A0 80 00 00 */ + totalSz += ASN_INDEF_END_SZ; } - else #endif - { - outerContentSz = SetExplicit(0, totalSz, outerContent); - } totalSz += outerContentTypeSz; totalSz += outerContentSz; if (pkcs7->contentOID != FIRMWARE_PKG_DATA) { /* ContentInfo */ + contentInfoSeqSz = SetSequenceEx(totalSz, contentInfoSeq, + pkcs7->encodeStream); + totalSz += contentInfoSeqSz; #ifdef ASN_BER_TO_DER if (pkcs7->encodeStream) { - byte tmp[] = { 0x30, 0x80}; - XMEMCPY(contentInfoSeq, tmp, 2); - contentInfoSeqSz = 2; - totalSz += contentInfoSeqSz + 2; /* 30 80 00 00 */ + totalSz += ASN_INDEF_END_SZ; } - else #endif - { - contentInfoSeqSz = SetSequence(totalSz, contentInfoSeq); - totalSz += contentInfoSeqSz; - } } if (totalSz > (int)outputSz) { @@ -8798,50 +8755,35 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) idx += ivOctetStringSz; XMEMCPY(output + idx, tmpIv, blockSz); idx += blockSz; + XMEMCPY(output + idx, encContentOctet, encContentOctetSz); + idx += encContentOctetSz; - /* stream the content (octet string with multiple octet elements) */ #ifdef ASN_BER_TO_DER + /* stream the content (octet string with multiple octet elements) */ if (pkcs7->encodeStream) { - int err; - byte* tmp; - byte tmpPad[] = { 0x00, 0x00}; - - tmp = XMALLOC(encContentOctetSz + encryptedOutSz, pkcs7->heap, - DYNAMIC_TYPE_PKCS7); - if (tmp == NULL) { - return MEMORY_E; + if (StreamOctetString(encryptedContent, encryptedOutSz, output, + &outputSz, (word32*)&idx) != 0) { + return BUFFER_E; } - err = SetImplicitBer(ASN_OCTET_STRING, 0, encryptedContent, - encryptedOutSz, tmp, (word32*)&encContentOctetSz); - if (err <= 0) { - return ASN_PARSE_E; - } - XMEMCPY(output + idx, tmp, err); - idx += err; + /* end of encrypted content */ + idx += SetIndefEnd(output + idx); /* end of encrypted content info */ - XMEMCPY(output + idx, tmpPad, 2); - idx += 2; + idx += SetIndefEnd(output + idx); /* end of Enveloped Data seq */ - XMEMCPY(output + idx, tmpPad, 2); - idx += 2; + idx += SetIndefEnd(output + idx); /* end of outer content set */ - XMEMCPY(output + idx, tmpPad, 2); - idx += 2; + idx += SetIndefEnd(output + idx); /* end of outer content info seq */ - XMEMCPY(output + idx, tmpPad, 2); - idx += 2; - XFREE(tmp, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + idx += SetIndefEnd(output + idx); } else #endif { - XMEMCPY(output + idx, encContentOctet, encContentOctetSz); - idx += encContentOctetSz; XMEMCPY(output + idx, encryptedContent, encryptedOutSz); idx += encryptedOutSz; } @@ -11687,7 +11629,7 @@ int wc_PKCS7_EncodeAuthEnvelopedData(PKCS7* pkcs7, byte* output, } authAttribsSetSz = SetImplicit(ASN_SET, 1, authAttribsSz, - authAttribSet); + authAttribSet, 0); /* From RFC5083, "For the purpose of constructing the AAD, the * IMPLICIT [1] tag in the authAttrs field is not used for the @@ -11733,7 +11675,7 @@ int wc_PKCS7_EncodeAuthEnvelopedData(PKCS7* pkcs7, byte* output, FlattenAttributes(pkcs7, flatUnauthAttribs, unauthAttribs, unauthAttribsCount); unauthAttribsSetSz = SetImplicit(ASN_SET, 2, unauthAttribsSz, - unauthAttribSet); + unauthAttribSet, 0); } /* AES-GCM/CCM does NOT require padding for plaintext content or @@ -11844,24 +11786,8 @@ int wc_PKCS7_EncodeAuthEnvelopedData(PKCS7* pkcs7, byte* output, return BAD_FUNC_ARG; } -#ifdef ASN_BER_TO_DER - if (pkcs7->encodeStream) { - int err; - - err = SetImplicitBer(ASN_OCTET_STRING, 0, encryptedContent, - encryptedOutSz, NULL, (word32*)&encContentOctetSz); - - if (err != LENGTH_ONLY_E) { - - } - encContentOctetSz -= encryptedOutSz; - } - else -#endif - { - encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0, encryptedOutSz, - encContentOctet); - } + encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0, encryptedOutSz, + encContentOctet, 0); encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz + nonceOctetStringSz + nonceSz + macIntSz + algoParamSeqSz + encContentOctetSz + @@ -11881,7 +11807,7 @@ int wc_PKCS7_EncodeAuthEnvelopedData(PKCS7* pkcs7, byte* output, totalSz += envDataSeqSz; /* outer content */ - outerContentSz = SetExplicit(0, totalSz, outerContent); + outerContentSz = SetExplicit(0, totalSz, outerContent, 0); totalSz += outerContentTypeSz; totalSz += outerContentSz; @@ -11936,28 +11862,10 @@ int wc_PKCS7_EncodeAuthEnvelopedData(PKCS7* pkcs7, byte* output, idx += macIntSz; -#ifdef ASN_BER_TO_DER - if (pkcs7->encodeStream) { - int err; - - byte* tmp = malloc(encContentOctetSz + encryptedOutSz); - - err = SetImplicitBer(ASN_OCTET_STRING, 0, encryptedContent, - encryptedOutSz, tmp, (word32*)&encContentOctetSz); - if (err <= 0) { - return ASN_PARSE_E; - } - XMEMCPY(output + idx, tmp, encContentOctetSz); - idx += encContentOctetSz; - } - else -#endif - { - XMEMCPY(output + idx, encContentOctet, encContentOctetSz); - idx += encContentOctetSz; - XMEMCPY(output + idx, encryptedContent, encryptedOutSz); - idx += encryptedOutSz; - } + XMEMCPY(output + idx, encContentOctet, encContentOctetSz); + idx += encContentOctetSz; + XMEMCPY(output + idx, encryptedContent, encryptedOutSz); + idx += encryptedOutSz; /* authenticated attributes */ if (flatAuthAttribs && authAttribsSz > 0) { @@ -12764,7 +12672,7 @@ int wc_PKCS7_EncodeEncryptedData(PKCS7* pkcs7, byte* output, word32 outputSz) } encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0, - encryptedOutSz, encContentOctet); + encryptedOutSz, encContentOctet, 0); encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz + ivOctetStringSz + blockSz + @@ -12810,7 +12718,7 @@ int wc_PKCS7_EncodeEncryptedData(PKCS7* pkcs7, byte* output, word32 outputSz) XFREE(flatAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7); return ret; } - attribsSetSz = SetImplicit(ASN_SET, 1, attribsSz, attribSet); + attribsSetSz = SetImplicit(ASN_SET, 1, attribsSz, attribSet, 0); } else { attribsSz = 0; @@ -12828,7 +12736,7 @@ int wc_PKCS7_EncodeEncryptedData(PKCS7* pkcs7, byte* output, word32 outputSz) if (pkcs7->version != 3) { /* outer content */ - outerContentSz = SetExplicit(0, totalSz, outerContent); + outerContentSz = SetExplicit(0, totalSz, outerContent, 0); totalSz += outerContentTypeSz; totalSz += outerContentSz; /* ContentInfo */ @@ -13427,7 +13335,7 @@ int wc_PKCS7_EncodeCompressedData(PKCS7* pkcs7, byte* output, word32 outputSz) totalSz = contentOctetStrSz + compressedSz; /* EXPLICIT [0] eContentType */ - contentSeqSz = SetExplicit(0, totalSz, contentSeq); + contentSeqSz = SetExplicit(0, totalSz, contentSeq, 0); totalSz += contentSeqSz; /* eContentType OBJECT IDENTIFIER */ @@ -13487,7 +13395,7 @@ int wc_PKCS7_EncodeCompressedData(PKCS7* pkcs7, byte* output, word32 outputSz) */ /* ContentInfo content EXPLICIT SEQUENCE */ - contentInfoContentSeqSz = SetExplicit(0, totalSz, contentInfoContentSeq); + contentInfoContentSeqSz = SetExplicit(0, totalSz, contentInfoContentSeq, 0); totalSz += contentInfoContentSeqSz; ret = wc_SetContentType(COMPRESSED_DATA, contentInfoTypeOid, diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index ccc10e66ea..78a0571314 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -1023,6 +1023,7 @@ enum Misc_ASN { #endif TRAILING_ZERO = 1, /* Used for size of zero pad */ ASN_TAG_SZ = 1, /* single byte ASN.1 tag */ + ASN_INDEF_END_SZ = 2, /* 0x00 0x00 at end of indef */ MIN_VERSION_SZ = 3, /* Min bytes needed for GetMyVersion */ MAX_X509_VERSION = 3, /* Max X509 version allowed */ MIN_X509_VERSION = 0, /* Min X509 version allowed */ @@ -2276,14 +2277,18 @@ WOLFSSL_LOCAL word32 SetASNExplicit(byte number, word32 len, byte* output); WOLFSSL_LOCAL word32 SetASNSet(word32 len, byte* output); WOLFSSL_LOCAL word32 SetLength(word32 length, byte* output); +WOLFSSL_LOCAL word32 SetLengthEx(word32 length, byte* output, byte isIndef); WOLFSSL_LOCAL word32 SetSequence(word32 len, byte* output); +WOLFSSL_LOCAL word32 SetSequenceEx(word32 len, byte* output, byte isIndef); +WOLFSSL_LOCAL word32 SetIndefEnd(byte* in); WOLFSSL_LOCAL word32 SetOctetString(word32 len, byte* output); +WOLFSSL_LOCAL word32 SetOctetStringEx(word32 len, byte* output, byte indef); WOLFSSL_LOCAL int SetASNInt(int len, byte firstByte, byte* output); WOLFSSL_LOCAL word32 SetBitString(word32 len, byte unusedBits, byte* output); -WOLFSSL_LOCAL word32 SetImplicit(byte tag,byte number,word32 len,byte* output); -WOLFSSL_LOCAL long SetImplicitBer(byte tag, byte num, const byte* data, word32 dataSz, - byte* out, word32* outSz); -WOLFSSL_LOCAL word32 SetExplicit(byte number, word32 len, byte* output); +WOLFSSL_LOCAL word32 SetImplicit(byte tag,byte number,word32 len,byte* output, + byte isIndef); +WOLFSSL_LOCAL word32 SetExplicit(byte number, word32 len, byte* output, + byte isIndef); WOLFSSL_LOCAL word32 SetSet(word32 len, byte* output); WOLFSSL_API word32 SetAlgoID(int algoOID, byte* output, int type, int curveSz); WOLFSSL_LOCAL int SetMyVersion(word32 version, byte* output, int header); diff --git a/wolfssl/wolfcrypt/pkcs7.h b/wolfssl/wolfcrypt/pkcs7.h index 556a54483c..f397a8f26b 100644 --- a/wolfssl/wolfcrypt/pkcs7.h +++ b/wolfssl/wolfcrypt/pkcs7.h @@ -247,8 +247,8 @@ struct PKCS7 { #ifdef ASN_BER_TO_DER byte* der; /* DER encoded version of message */ word32 derSz; - byte encodeStream; /* use BER when encoding */ #endif + byte encodeStream:1; /* use BER when encoding */ byte noCerts:1; /* if certificates should be added into bundle during creation */ byte* cert[MAX_PKCS7_CERTS]; /* array of certs parsed from bundle */ From 8d0dc7a56876a19dc61de8bf76606ac5ec291679 Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Thu, 1 Feb 2024 10:57:20 -0700 Subject: [PATCH 41/63] fix asn original build, vs warning, and add test cases --- tests/api.c | 100 +++++++++++++++++++++++++++++++++++++----- wolfcrypt/src/asn.c | 4 +- wolfcrypt/src/pkcs7.c | 36 +++++++-------- 3 files changed, 109 insertions(+), 31 deletions(-) diff --git a/tests/api.c b/tests/api.c index d9c75f6752..b372b402ee 100644 --- a/tests/api.c +++ b/tests/api.c @@ -26916,13 +26916,56 @@ static int test_wc_PKCS7_EncodeSignedData(void) } ExpectIntGT(wc_PKCS7_EncodeSignedData(pkcs7, output, outputSz), 0); - wc_PKCS7_Free(pkcs7); pkcs7 = NULL; + ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId)); ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0); ExpectIntEQ(wc_PKCS7_VerifySignedData(pkcs7, output, outputSz), 0); +#ifdef ASN_BER_TO_DER + wc_PKCS7_Free(pkcs7); + + /* reinitialize and test setting stream mode */ + { + int signedSz; + + ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId)); + ExpectIntEQ(wc_PKCS7_Init(pkcs7, HEAP_HINT, INVALID_DEVID), 0); + + ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, cert, certSz), 0); + + if (pkcs7 != NULL) { + pkcs7->content = data; + pkcs7->contentSz = (word32)sizeof(data); + pkcs7->privateKey = key; + pkcs7->privateKeySz = (word32)sizeof(key); + pkcs7->encryptOID = RSAk; + #ifdef NO_SHA + pkcs7->hashOID = SHA256h; + #else + pkcs7->hashOID = SHAh; + #endif + pkcs7->rng = &rng; + } + ExpectIntEQ(wc_PKCS7_GetStreamMode(pkcs7), 0); + ExpectIntEQ(wc_PKCS7_SetStreamMode(pkcs7, 1), 0); + ExpectIntEQ(wc_PKCS7_SetStreamMode(NULL, 1), BAD_FUNC_ARG); + ExpectIntEQ(wc_PKCS7_GetStreamMode(pkcs7), 1); + + ExpectIntGT(signedSz = wc_PKCS7_EncodeSignedData(pkcs7, output, + outputSz), 0); + wc_PKCS7_Free(pkcs7); + pkcs7 = NULL; + + ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId)); + ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0); + + /* use exact signed buffer size since BER encoded */ + ExpectIntEQ(wc_PKCS7_VerifySignedData(pkcs7, output, signedSz), 0); + } +#endif + /* Pass in bad args. */ ExpectIntEQ(wc_PKCS7_EncodeSignedData(NULL, output, outputSz), BAD_FUNC_ARG); @@ -27953,6 +27996,9 @@ static int test_wc_PKCS7_EncodeDecodeEnvelopedData(void) EXPECT_DECLS; #if defined(HAVE_PKCS7) PKCS7* pkcs7 = NULL; +#ifdef ASN_BER_TO_DER + int encodedSz; +#endif #ifdef ECC_TIMING_RESISTANT WC_RNG rng; #endif @@ -28153,6 +28199,39 @@ static int test_wc_PKCS7_EncodeDecodeEnvelopedData(void) testSz = (int)sizeof(testVectors)/(int)sizeof(pkcs7EnvelopedVector); for (i = 0; i < testSz; i++) { + #ifdef ASN_BER_TO_DER + /* test setting stream mode */ + ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, (testVectors + i)->cert, + (word32)(testVectors + i)->certSz), 0); + if (pkcs7 != NULL) { + #ifdef ECC_TIMING_RESISTANT + pkcs7->rng = &rng; + #endif + + pkcs7->content = (byte*)(testVectors + i)->content; + pkcs7->contentSz = (testVectors + i)->contentSz; + pkcs7->contentOID = (testVectors + i)->contentOID; + pkcs7->encryptOID = (testVectors + i)->encryptOID; + pkcs7->keyWrapOID = (testVectors + i)->keyWrapOID; + pkcs7->keyAgreeOID = (testVectors + i)->keyAgreeOID; + pkcs7->privateKey = (testVectors + i)->privateKey; + pkcs7->privateKeySz = (testVectors + i)->privateKeySz; + } + ExpectIntEQ(wc_PKCS7_SetStreamMode(pkcs7, 1), 0); + + ExpectIntGE(encodedSz = wc_PKCS7_EncodeEnvelopedData(pkcs7, output, + (word32)sizeof(output)), 0); + + decodedSz = wc_PKCS7_DecodeEnvelopedData(pkcs7, output, + (word32)encodedSz, decoded, (word32)sizeof(decoded)); + ExpectIntGE(decodedSz, 0); + /* Verify the size of each buffer. */ + ExpectIntEQ((word32)sizeof(input)/sizeof(char), decodedSz); + wc_PKCS7_Free(pkcs7); + pkcs7 = NULL; + ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId)); + #endif + ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, (testVectors + i)->cert, (word32)(testVectors + i)->certSz), 0); if (pkcs7 != NULL) { @@ -28170,6 +28249,11 @@ static int test_wc_PKCS7_EncodeDecodeEnvelopedData(void) pkcs7->privateKeySz = (testVectors + i)->privateKeySz; } + #ifdef ASN_BER_TO_DER + /* test without setting stream mode */ + ExpectIntEQ(wc_PKCS7_GetStreamMode(pkcs7), 0); + #endif + ExpectIntGE(wc_PKCS7_EncodeEnvelopedData(pkcs7, output, (word32)sizeof(output)), 0); @@ -28178,6 +28262,7 @@ static int test_wc_PKCS7_EncodeDecodeEnvelopedData(void) ExpectIntGE(decodedSz, 0); /* Verify the size of each buffer. */ ExpectIntEQ((word32)sizeof(input)/sizeof(char), decodedSz); + /* Don't free the last time through the loop. */ if (i < testSz - 1) { wc_PKCS7_Free(pkcs7); @@ -28871,7 +28956,6 @@ static int test_wc_PKCS7_signed_enveloped(void) #ifdef HAVE_AES_CBC PKCS7* inner = NULL; #endif - void* pt = NULL; WC_RNG rng; unsigned char key[FOURK_BUF/2]; unsigned char cert[FOURK_BUF/2]; @@ -28958,17 +29042,13 @@ static int test_wc_PKCS7_signed_enveloped(void) pkcs7->rng = &rng; } - /* Set no certs in bundle for this test. Hang on to the pointer though to - * free it later. */ + /* Set no certs in bundle for this test. */ if (pkcs7 != NULL) { - pt = (void*)pkcs7->certList; - pkcs7->certList = NULL; /* no certs in bundle */ + ExpectIntEQ(wc_PKCS7_SetNoCerts(pkcs7, 1), 0); + ExpectIntEQ(wc_PKCS7_SetNoCerts(NULL, 1), BAD_FUNC_ARG); + ExpectIntEQ(wc_PKCS7_GetNoCerts(pkcs7), 1); } ExpectIntGT((sigSz = wc_PKCS7_EncodeSignedData(pkcs7, sig, sigSz)), 0); - if (pkcs7 != NULL) { - /* restore pointer for PKCS7 free call */ - pkcs7->certList = (Pkcs7Cert*)pt; - } wc_PKCS7_Free(pkcs7); pkcs7 = NULL; diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index b3210fb40b..c4e88b3885 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -15482,7 +15482,7 @@ word32 SetSet(word32 len, byte* output) */ word32 SetImplicit(byte tag, byte number, word32 len, byte* output, byte isIndef) { - int useIndef = 0; + byte useIndef = 0; if ((tag == ASN_OCTET_STRING) && isIndef) { tag = ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | number; @@ -36453,7 +36453,7 @@ int EncodeOcspRequest(OcspRequest* req, byte* output, word32 size) */ extSz = EncodeOcspRequestExtensions(req, extArray + 2, OCSP_NONCE_EXT_SZ); - extSz += SetExplicit(2, extSz, extArray); + extSz += SetExplicit(2, extSz, extArray, 0); } totalSz = algoSz + issuerSz + issuerKeySz + snSz; diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 4998205e52..4f7bbc4b18 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -2630,27 +2630,25 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, totalSz -= pkcs7->contentSz; } - { - esd->innerSeqSz = SetSequenceEx(totalSz + total2Sz, esd->innerSeq, - pkcs7->encodeStream); - totalSz += esd->innerSeqSz; - if (pkcs7->encodeStream) { - totalSz += ASN_INDEF_END_SZ; - } + esd->innerSeqSz = SetSequenceEx(totalSz + total2Sz, esd->innerSeq, + pkcs7->encodeStream); + totalSz += esd->innerSeqSz; + if (pkcs7->encodeStream) { + totalSz += ASN_INDEF_END_SZ; + } - esd->outerContentSz = SetExplicit(0, totalSz + total2Sz, - esd->outerContent, pkcs7->encodeStream); - totalSz += esd->outerContentSz + signedDataOidSz; - if (pkcs7->encodeStream) { - totalSz += ASN_INDEF_END_SZ; - } + esd->outerContentSz = SetExplicit(0, totalSz + total2Sz, + esd->outerContent, pkcs7->encodeStream); + totalSz += esd->outerContentSz + signedDataOidSz; + if (pkcs7->encodeStream) { + totalSz += ASN_INDEF_END_SZ; + } - esd->outerSeqSz = SetSequenceEx(totalSz + total2Sz, esd->outerSeq, - pkcs7->encodeStream); - totalSz += esd->outerSeqSz; - if (pkcs7->encodeStream) { - totalSz += ASN_INDEF_END_SZ; - } + esd->outerSeqSz = SetSequenceEx(totalSz + total2Sz, esd->outerSeq, + pkcs7->encodeStream); + totalSz += esd->outerSeqSz; + if (pkcs7->encodeStream) { + totalSz += ASN_INDEF_END_SZ; } /* if using header/footer, we are not returning the content */ From 5fbadbb215cf8f362a031de7d9fed9d6391f3881 Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Thu, 1 Feb 2024 11:00:42 -0700 Subject: [PATCH 42/63] fix warning with test case --- tests/api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/api.c b/tests/api.c index b372b402ee..585c183743 100644 --- a/tests/api.c +++ b/tests/api.c @@ -27997,7 +27997,7 @@ static int test_wc_PKCS7_EncodeDecodeEnvelopedData(void) #if defined(HAVE_PKCS7) PKCS7* pkcs7 = NULL; #ifdef ASN_BER_TO_DER - int encodedSz; + int encodedSz = 0; #endif #ifdef ECC_TIMING_RESISTANT WC_RNG rng; From ed4b87eb37e5b6db821d55e64c1ab785d5eab82d Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Thu, 1 Feb 2024 14:26:13 -0700 Subject: [PATCH 43/63] fix for clang-tidy null dereference error --- wolfcrypt/src/asn.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index c4e88b3885..f29c990e67 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -15400,7 +15400,9 @@ word32 SetLength(word32 length, byte* output) word32 SetLengthEx(word32 length, byte* output, byte isIndef) { if (isIndef) { - output[0] = ASN_INDEF_LENGTH; + if (output != NULL) { + output[0] = ASN_INDEF_LENGTH; + } return 1; } else { From 63f7298be26ef4292da48ebd5f6121aac53627fb Mon Sep 17 00:00:00 2001 From: Lealem Amedie Date: Thu, 1 Feb 2024 14:52:06 -0700 Subject: [PATCH 44/63] Default to ASN TEMPLATE library --- ChangeLog.md | 4 ++++ wolfcrypt/src/asn.c | 12 ++++++++---- wolfssl/wolfcrypt/settings.h | 8 ++++++++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 586adaa456..140d730637 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,3 +1,7 @@ +# wolfSSL Release X.Y.Z (TBD) + +NOTE: This release switches the default ASN.1 parser to the new ASN template code. If the original ASN.1 code is preferred define `WOLFSSL_ASN_ORIGINAL` to use it. See PR #7199. + # wolfSSL Release 5.6.6 (Dec 19, 2023) Release 5.6.6 has been developed according to wolfSSL's development and QA diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 3b61f6fb5f..40ab403006 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -1384,9 +1384,8 @@ int GetASN_Items(const ASNItem* asn, ASNGetData *data, int count, int complete, int len; /* Current index into buffer. */ word32 idx = *inOutIdx; - /* Initialize the end index at each depth to be the length. */ - word32 endIdx[GET_ASN_MAX_DEPTH] = { length, length, length, length, length, - length, length }; + /* Declare the end index array. */ + word32 endIdx[GET_ASN_MAX_DEPTH]; /* Set choices to -1 to indicate they haven't been seen or found. */ signed char choiceMet[GET_ASN_MAX_CHOICES] = { -1, -1 }; /* Not matching a choice right now. */ @@ -1402,6 +1401,11 @@ int GetASN_Items(const ASNItem* asn, ASNGetData *data, int count, int complete, WOLFSSL_ENTER("GetASN_Items"); #endif + /* Set the end index at each depth to be the length. */ + for (i=0; i Date: Thu, 1 Feb 2024 19:04:02 -0600 Subject: [PATCH 45/63] linuxkm: various tweaks: * configure.ac: in linuxkm-lkcapi-register section, force ENABLED_AESGCM_STREAM=yes if ENABLED_AESGCM is yes and there is asm or FIPS in the picture. * linuxkm/module_hooks.c: in updateFipsHash(), if DEBUG_LINUXKM_PIE_SUPPORT || WOLFSSL_LINUXKM_VERBOSE_DEBUG, print the base16 hash to the kernel log. * linuxkm/lkcapi_glue.c: * implement KATs for AES-CBC, AES-CFB, and AES-GCM. * clean out extraneous code and macro usage inherited from test/test.c. * add post-registration crypto_tfm_alg_driver_name() tests for AES-CBC, AES-CFB, and AES-GCM. --- configure.ac | 5 + linuxkm/lkcapi_glue.c | 675 ++++++++++++++++++++--------------------- linuxkm/module_hooks.c | 12 +- 3 files changed, 347 insertions(+), 345 deletions(-) diff --git a/configure.ac b/configure.ac index c00818b7c9..dbb7c5977c 100644 --- a/configure.ac +++ b/configure.ac @@ -8042,6 +8042,11 @@ AC_ARG_ENABLE([linuxkm-lkcapi-register], if test "$ENABLED_LINUXKM_LKCAPI_REGISTER" != "none" then AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_REGISTER" + + if test "$ENABLED_AESGCM" != "no" && test "$ENABLED_AESGCM_STREAM" = "no" && test "$ENABLED_AESNI" = "no" && test "$ENABLED_ARMASM" = "no" && test "$ENABLED_FIPS" = "no"; then + ENABLED_AESGCM_STREAM=yes + fi + for lkcapi_alg in $(echo "$ENABLED_LINUXKM_LKCAPI_REGISTER" | tr ',' ' ') do case "$lkcapi_alg" in diff --git a/linuxkm/lkcapi_glue.c b/linuxkm/lkcapi_glue.c index d1e8081edf..bfed01eb98 100644 --- a/linuxkm/lkcapi_glue.c +++ b/linuxkm/lkcapi_glue.c @@ -30,10 +30,6 @@ #error LINUXKM_LKCAPI_REGISTER_AESGCM is incompatible with WOLFSSL_AESNI && WC_AES_C_DYNAMIC_FALLBACK #endif -#if defined(LINUXKM_LKCAPI_REGISTER_AESGCM) && !defined(WOLFSSL_AESGCM_STREAM) - #error LINUXKM_REGISTER_ALG requires AESGCM_STREAM. -#endif - #ifndef WOLFSSL_LINUXKM_LKCAPI_PRIORITY /* Larger number means higher priority. The highest in-tree priority is 4001, * in the Cavium driver. @@ -43,6 +39,10 @@ #ifndef NO_AES +/* note the FIPS code will be returned on failure even in non-FIPS builds. */ +#define LINUXKM_LKCAPI_AES_KAT_MISMATCH_E AES_KAT_FIPS_E +#define LINUXKM_LKCAPI_AESGCM_KAT_MISMATCH_E AESGCM_KAT_FIPS_E + #define WOLFKM_AESCBC_NAME "cbc(aes)" #define WOLFKM_AESCFB_NAME "cfb(aes)" #define WOLFKM_AESGCM_NAME "gcm(aes)" @@ -506,6 +506,10 @@ static int cfbAesAlg_loaded = 0; defined(LINUXKM_LKCAPI_REGISTER_AESGCM)) && \ (! (defined(WOLFSSL_AESNI) && defined(WC_AES_C_DYNAMIC_FALLBACK))) +#ifndef WOLFSSL_AESGCM_STREAM + #error LKCAPI registration of AES-GCM requires WOLFSSL_AESGCM_STREAM (--enable-aesgcm-stream). +#endif + static int km_AesGcmInit(struct crypto_aead * tfm) { struct km_AesCtx * ctx = crypto_aead_ctx(tfm); @@ -974,14 +978,14 @@ static int linuxkm_test_aescbc(void) struct skcipher_request * req = NULL; struct scatterlist src, dst; Aes aes; - WOLFSSL_SMALL_STACK_STATIC const byte key32[] = + static const byte key32[] = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66 }; - WOLFSSL_SMALL_STACK_STATIC const byte vector[] = + static const byte p_vector[] = /* Now is the time for all good men w/o trailing 0 */ { 0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74, @@ -989,13 +993,24 @@ static int linuxkm_test_aescbc(void) 0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20, 0x67,0x6f,0x6f,0x64,0x20,0x6d,0x65,0x6e }; - WOLFSSL_SMALL_STACK_STATIC const byte iv[] = "1234567890abcdef"; + static const byte iv[] = "1234567890abcdef"; + + static const byte c_vector[] = + { + 0xd7,0xd6,0x04,0x5b,0x4d,0xc4,0x90,0xdf, + 0x4a,0x82,0xed,0x61,0x26,0x4e,0x23,0xb3, + 0xe4,0xb5,0x85,0x30,0x29,0x4c,0x9d,0xcf, + 0x73,0xc9,0x46,0xd1,0xaa,0xc8,0xcb,0x62 + }; + byte iv_copy[sizeof(iv)]; - byte enc[sizeof(vector)]; - byte dec[sizeof(vector)]; + byte enc[sizeof(p_vector)]; + byte dec[sizeof(p_vector)]; u8 * enc2 = NULL; u8 * dec2 = NULL; + const char *driver_name; + XMEMSET(enc, 0, sizeof(enc)); XMEMSET(dec, 0, sizeof(enc)); @@ -1011,12 +1026,17 @@ static int linuxkm_test_aescbc(void) return ret; } - ret = wc_AesCbcEncrypt(&aes, enc, vector, sizeof(vector)); + ret = wc_AesCbcEncrypt(&aes, enc, p_vector, sizeof(p_vector)); if (ret) { pr_err("wolfcrypt wc_AesCbcEncrypt failed with return code %d\n", ret); return ret; } + if (XMEMCMP(enc, c_vector, sizeof(c_vector)) != 0) { + pr_err("wolfcrypt wc_AesCbcEncrypt KAT mismatch\n"); + return LINUXKM_LKCAPI_AES_KAT_MISMATCH_E; + } + /* Re init for decrypt and set flag. */ wc_AesFree(&aes); @@ -1032,40 +1052,48 @@ static int linuxkm_test_aescbc(void) return ret; } - ret = wc_AesCbcDecrypt(&aes, dec, enc, sizeof(vector)); + ret = wc_AesCbcDecrypt(&aes, dec, enc, sizeof(p_vector)); if (ret) { pr_err("wolfcrypt wc_AesCbcDecrypt failed with return code %d\n", ret); return ret; } - ret = XMEMCMP(vector, dec, sizeof(vector)); + ret = XMEMCMP(p_vector, dec, sizeof(p_vector)); if (ret) { - pr_err("error: vector and dec do not match: %d\n", ret); + pr_err("error: p_vector and dec do not match: %d\n", ret); return ret; } /* now the kernel crypto part */ - enc2 = kmalloc(sizeof(vector), GFP_KERNEL); + enc2 = kmalloc(sizeof(p_vector), GFP_KERNEL); if (!enc2) { pr_err("error: kmalloc failed\n"); goto test_cbc_end; } - dec2 = kmalloc(sizeof(vector), GFP_KERNEL); + dec2 = kmalloc(sizeof(p_vector), GFP_KERNEL); if (!dec2) { pr_err("error: kmalloc failed\n"); goto test_cbc_end; } - memcpy(dec2, vector, sizeof(vector)); + memcpy(dec2, p_vector, sizeof(p_vector)); - tfm = crypto_alloc_skcipher(WOLFKM_AESCBC_DRIVER, 0, 0); + tfm = crypto_alloc_skcipher(WOLFKM_AESCBC_NAME, 0, 0); if (IS_ERR(tfm)) { pr_err("error: allocating AES skcipher algorithm %s failed: %ld\n", WOLFKM_AESCBC_DRIVER, PTR_ERR(tfm)); goto test_cbc_end; } + driver_name = crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)); + if (strcmp(driver_name, WOLFKM_AESCBC_DRIVER)) { + pr_err("error: unexpected implementation for %s: %s (expected %s)\n", + WOLFKM_AESCBC_NAME, driver_name, WOLFKM_AESCBC_DRIVER); + ret = -ENOENT; + goto test_cbc_end; + } + ret = crypto_skcipher_setkey(tfm, key32, AES_BLOCK_SIZE * 2); if (ret) { pr_err("error: crypto_skcipher_setkey returned: %d\n", ret); @@ -1079,11 +1107,11 @@ static int linuxkm_test_aescbc(void) goto test_cbc_end; } - sg_init_one(&src, dec2, sizeof(vector)); - sg_init_one(&dst, enc2, sizeof(vector)); + sg_init_one(&src, dec2, sizeof(p_vector)); + sg_init_one(&dst, enc2, sizeof(p_vector)); XMEMCPY(iv_copy, iv, sizeof(iv)); - skcipher_request_set_crypt(req, &src, &dst, sizeof(vector), iv_copy); + skcipher_request_set_crypt(req, &src, &dst, sizeof(p_vector), iv_copy); ret = crypto_skcipher_encrypt(req); @@ -1092,18 +1120,18 @@ static int linuxkm_test_aescbc(void) goto test_cbc_end; } - ret = XMEMCMP(enc, enc2, sizeof(vector)); + ret = XMEMCMP(enc, enc2, sizeof(p_vector)); if (ret) { pr_err("error: enc and enc2 do not match: %d\n", ret); goto test_cbc_end; } - memset(dec2, 0, sizeof(vector)); - sg_init_one(&src, enc2, sizeof(vector)); - sg_init_one(&dst, dec2, sizeof(vector)); + memset(dec2, 0, sizeof(p_vector)); + sg_init_one(&src, enc2, sizeof(p_vector)); + sg_init_one(&dst, dec2, sizeof(p_vector)); XMEMCPY(iv_copy, iv, sizeof(iv)); - skcipher_request_set_crypt(req, &src, &dst, sizeof(vector), iv_copy); + skcipher_request_set_crypt(req, &src, &dst, sizeof(p_vector), iv_copy); ret = crypto_skcipher_decrypt(req); @@ -1112,7 +1140,7 @@ static int linuxkm_test_aescbc(void) goto test_cbc_end; } - ret = XMEMCMP(dec, dec2, sizeof(vector)); + ret = XMEMCMP(dec, dec2, sizeof(p_vector)); if (ret) { pr_err("error: dec and dec2 do not match: %d\n", ret); goto test_cbc_end; @@ -1143,14 +1171,14 @@ static int linuxkm_test_aescfb(void) struct skcipher_request * req = NULL; struct scatterlist src, dst; Aes aes; - WOLFSSL_SMALL_STACK_STATIC const byte key32[] = + static const byte key32[] = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66 }; - WOLFSSL_SMALL_STACK_STATIC const byte vector[] = + static const byte p_vector[] = /* Now is the time for all good men w/o trailing 0 */ { 0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74, @@ -1158,12 +1186,20 @@ static int linuxkm_test_aescfb(void) 0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20, 0x67,0x6f,0x6f,0x64,0x20,0x6d,0x65,0x6e }; - WOLFSSL_SMALL_STACK_STATIC const byte iv[] = "1234567890abcdef"; + static const byte iv[] = "1234567890abcdef"; + static const byte c_vector[] = + { + 0x56,0x35,0x3f,0xdd,0xde,0xa6,0x15,0x87, + 0x57,0xdc,0x34,0x62,0x9a,0x68,0x96,0x51, + 0xc7,0x09,0xb9,0x4e,0x47,0x6b,0x24,0x72, + 0x19,0x5a,0xdf,0x7e,0xba,0xa8,0x01,0xb6 + }; byte iv_copy[sizeof(iv)]; - byte enc[sizeof(vector)]; - byte dec[sizeof(vector)]; + byte enc[sizeof(p_vector)]; + byte dec[sizeof(p_vector)]; u8 * enc2 = NULL; u8 * dec2 = NULL; + const char *driver_name; XMEMSET(enc, 0, sizeof(enc)); XMEMSET(dec, 0, sizeof(enc)); @@ -1180,12 +1216,17 @@ static int linuxkm_test_aescfb(void) return ret; } - ret = wc_AesCfbEncrypt(&aes, enc, vector, sizeof(vector)); + ret = wc_AesCfbEncrypt(&aes, enc, p_vector, sizeof(p_vector)); if (ret) { pr_err("wolfcrypt wc_AesCfbEncrypt failed with return code %d\n", ret); return ret; } + if (XMEMCMP(enc, c_vector, sizeof(c_vector)) != 0) { + pr_err("wolfcrypt wc_AesCfbEncrypt KAT mismatch\n"); + return LINUXKM_LKCAPI_AES_KAT_MISMATCH_E; + } + /* Re init for decrypt and set flag. */ wc_AesFree(&aes); @@ -1201,40 +1242,48 @@ static int linuxkm_test_aescfb(void) return ret; } - ret = wc_AesCfbDecrypt(&aes, dec, enc, sizeof(vector)); + ret = wc_AesCfbDecrypt(&aes, dec, enc, sizeof(p_vector)); if (ret) { pr_err("wolfcrypt wc_AesCfbDecrypt failed with return code %d\n", ret); return ret; } - ret = XMEMCMP(vector, dec, sizeof(vector)); + ret = XMEMCMP(p_vector, dec, sizeof(p_vector)); if (ret) { - pr_err("error: vector and dec do not match: %d\n", ret); + pr_err("error: p_vector and dec do not match: %d\n", ret); return ret; } /* now the kernel crypto part */ - enc2 = kmalloc(sizeof(vector), GFP_KERNEL); + enc2 = kmalloc(sizeof(p_vector), GFP_KERNEL); if (!enc2) { pr_err("error: kmalloc failed\n"); goto test_cfb_end; } - dec2 = kmalloc(sizeof(vector), GFP_KERNEL); + dec2 = kmalloc(sizeof(p_vector), GFP_KERNEL); if (!dec2) { pr_err("error: kmalloc failed\n"); goto test_cfb_end; } - memcpy(dec2, vector, sizeof(vector)); + memcpy(dec2, p_vector, sizeof(p_vector)); - tfm = crypto_alloc_skcipher(WOLFKM_AESCFB_DRIVER, 0, 0); + tfm = crypto_alloc_skcipher(WOLFKM_AESCFB_NAME, 0, 0); if (IS_ERR(tfm)) { pr_err("error: allocating AES skcipher algorithm %s failed: %ld\n", WOLFKM_AESCFB_DRIVER, PTR_ERR(tfm)); goto test_cfb_end; } + driver_name = crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)); + if (strcmp(driver_name, WOLFKM_AESCFB_DRIVER)) { + pr_err("error: unexpected implementation for %s: %s (expected %s)\n", + WOLFKM_AESCFB_NAME, driver_name, WOLFKM_AESCFB_DRIVER); + ret = -ENOENT; + goto test_cfb_end; + } + ret = crypto_skcipher_setkey(tfm, key32, AES_BLOCK_SIZE * 2); if (ret) { pr_err("error: crypto_skcipher_setkey returned: %d\n", ret); @@ -1248,11 +1297,11 @@ static int linuxkm_test_aescfb(void) goto test_cfb_end; } - sg_init_one(&src, dec2, sizeof(vector)); - sg_init_one(&dst, enc2, sizeof(vector)); + sg_init_one(&src, dec2, sizeof(p_vector)); + sg_init_one(&dst, enc2, sizeof(p_vector)); XMEMCPY(iv_copy, iv, sizeof(iv)); - skcipher_request_set_crypt(req, &src, &dst, sizeof(vector), iv_copy); + skcipher_request_set_crypt(req, &src, &dst, sizeof(p_vector), iv_copy); ret = crypto_skcipher_encrypt(req); @@ -1261,18 +1310,18 @@ static int linuxkm_test_aescfb(void) goto test_cfb_end; } - ret = XMEMCMP(enc, enc2, sizeof(vector)); + ret = XMEMCMP(enc, enc2, sizeof(p_vector)); if (ret) { pr_err("error: enc and enc2 do not match: %d\n", ret); goto test_cfb_end; } - memset(dec2, 0, sizeof(vector)); - sg_init_one(&src, enc2, sizeof(vector)); - sg_init_one(&dst, dec2, sizeof(vector)); + memset(dec2, 0, sizeof(p_vector)); + sg_init_one(&src, enc2, sizeof(p_vector)); + sg_init_one(&dst, dec2, sizeof(p_vector)); XMEMCPY(iv_copy, iv, sizeof(iv)); - skcipher_request_set_crypt(req, &src, &dst, sizeof(vector), iv_copy); + skcipher_request_set_crypt(req, &src, &dst, sizeof(p_vector), iv_copy); ret = crypto_skcipher_decrypt(req); @@ -1281,7 +1330,7 @@ static int linuxkm_test_aescfb(void) goto test_cfb_end; } - ret = XMEMCMP(dec, dec2, sizeof(vector)); + ret = XMEMCMP(dec, dec2, sizeof(p_vector)); if (ret) { pr_err("error: dec and dec2 do not match: %d\n", ret); goto test_cfb_end; @@ -1314,40 +1363,52 @@ static int linuxkm_test_aesgcm(void) struct scatterlist * src = NULL; struct scatterlist * dst = NULL; Aes aes; - WOLFSSL_SMALL_STACK_STATIC const byte key32[] = + static const byte key32[] = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66 }; - WOLFSSL_SMALL_STACK_STATIC const byte vector[] = + static const byte p_vector[] = /* Now is the time for all w/o trailing 0 */ { 0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74, 0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20, 0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20 }; - WOLFSSL_SMALL_STACK_STATIC const byte assoc[] = + static const byte assoc[] = { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xab, 0xad, 0xda, 0xd2 }; - WOLFSSL_SMALL_STACK_STATIC const byte ivstr[] = "1234567890abcdef"; - byte enc[sizeof(vector)]; + static const byte ivstr[] = "1234567890abcdef"; + static const byte c_vector[] = + { + 0x0c,0x97,0x05,0x3c,0xef,0x5c,0x63,0x6b, + 0x15,0xe4,0x00,0x63,0xf8,0x8c,0xd0,0x95, + 0x27,0x81,0x90,0x9c,0x9f,0xe6,0x98,0xe9 + }; + static const byte KAT_authTag[] = + { + 0xc9,0xd5,0x7a,0x77,0xac,0x28,0xc2,0xe7, + 0xe4,0x28,0x90,0xaa,0x09,0xab,0xf9,0x7c + }; + byte enc[sizeof(p_vector)]; byte authTag[AES_BLOCK_SIZE]; - byte dec[sizeof(vector)]; + byte dec[sizeof(p_vector)]; u8 * assoc2 = NULL; u8 * enc2 = NULL; u8 * dec2 = NULL; u8 * iv = NULL; - size_t encryptLen = sizeof(vector); - size_t decryptLen = sizeof(vector) + sizeof(authTag); + size_t encryptLen = sizeof(p_vector); + size_t decryptLen = sizeof(p_vector) + sizeof(authTag); + const char *driver_name; /* Init stack variables. */ - XMEMSET(enc, 0, sizeof(vector)); - XMEMSET(dec, 0, sizeof(vector)); + XMEMSET(enc, 0, sizeof(p_vector)); + XMEMSET(dec, 0, sizeof(p_vector)); XMEMSET(authTag, 0, AES_BLOCK_SIZE); ret = wc_AesInit(&aes, NULL, INVALID_DEVID); @@ -1370,13 +1431,19 @@ static int linuxkm_test_aesgcm(void) goto test_gcm_end; } - ret = wc_AesGcmEncryptUpdate(&aes, enc, vector, sizeof(vector), NULL, 0); + ret = wc_AesGcmEncryptUpdate(&aes, enc, p_vector, sizeof(p_vector), NULL, 0); if (ret) { pr_err("error: wc_AesGcmEncryptUpdate failed with return code %d\n", ret); goto test_gcm_end; } + if (XMEMCMP(enc, c_vector, sizeof(c_vector)) != 0) { + pr_err("wolfcrypt AES-GCM KAT mismatch on ciphertext\n"); + ret = LINUXKM_LKCAPI_AESGCM_KAT_MISMATCH_E; + goto test_gcm_end; + } + ret = wc_AesGcmEncryptFinal(&aes, authTag, AES_BLOCK_SIZE); if (ret) { pr_err("error: wc_AesGcmEncryptFinal failed with return code %d\n", @@ -1384,6 +1451,12 @@ static int linuxkm_test_aesgcm(void) goto test_gcm_end; } + if (XMEMCMP(authTag, KAT_authTag, sizeof(KAT_authTag)) != 0) { + pr_err("wolfcrypt AES-GCM KAT mismatch on authTag\n"); + ret = LINUXKM_LKCAPI_AESGCM_KAT_MISMATCH_E; + goto test_gcm_end; + } + ret = wc_AesGcmInit(&aes, key32, sizeof(key32)/sizeof(byte), ivstr, AES_BLOCK_SIZE); if (ret) { @@ -1391,7 +1464,7 @@ static int linuxkm_test_aesgcm(void) goto test_gcm_end; } - ret = wc_AesGcmDecryptUpdate(&aes, dec, enc, sizeof(vector), + ret = wc_AesGcmDecryptUpdate(&aes, dec, enc, sizeof(p_vector), assoc, sizeof(assoc)); if (ret) { pr_err("error: wc_AesGcmDecryptUpdate failed with return code %d\n", @@ -1406,9 +1479,9 @@ static int linuxkm_test_aesgcm(void) goto test_gcm_end; } - ret = XMEMCMP(vector, dec, sizeof(vector)); + ret = XMEMCMP(p_vector, dec, sizeof(p_vector)); if (ret) { - pr_err("error: gcm: vector and dec do not match: %d\n", ret); + pr_err("error: gcm: p_vector and dec do not match: %d\n", ret); goto test_gcm_end; } @@ -1443,15 +1516,23 @@ static int linuxkm_test_aesgcm(void) memset(enc2, 0, decryptLen); memset(dec2, 0, decryptLen); - memcpy(dec2, vector, sizeof(vector)); + memcpy(dec2, p_vector, sizeof(p_vector)); - tfm = crypto_alloc_aead(WOLFKM_AESGCM_DRIVER, 0, 0); + tfm = crypto_alloc_aead(WOLFKM_AESGCM_NAME, 0, 0); if (IS_ERR(tfm)) { pr_err("error: allocating AES skcipher algorithm %s failed: %ld\n", WOLFKM_AESGCM_DRIVER, PTR_ERR(tfm)); goto test_gcm_end; } + driver_name = crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)); + if (strcmp(driver_name, WOLFKM_AESGCM_DRIVER)) { + pr_err("error: unexpected implementation for %s: %s (expected %s)\n", + WOLFKM_AESGCM_NAME, driver_name, WOLFKM_AESGCM_DRIVER); + ret = -ENOENT; + goto test_gcm_end; + } + ret = crypto_aead_setkey(tfm, key32, AES_BLOCK_SIZE * 2); if (ret) { pr_err("error: crypto_aead_setkey returned: %d\n", ret); @@ -1482,7 +1563,7 @@ static int linuxkm_test_aesgcm(void) sg_init_table(src, 2); sg_set_buf(src, assoc2, sizeof(assoc)); - sg_set_buf(&src[1], dec2, sizeof(vector)); + sg_set_buf(&src[1], dec2, sizeof(p_vector)); sg_init_table(dst, 2); sg_set_buf(dst, assoc2, sizeof(assoc)); @@ -1490,7 +1571,7 @@ static int linuxkm_test_aesgcm(void) aead_request_set_callback(req, 0, NULL, NULL); aead_request_set_ad(req, sizeof(assoc)); - aead_request_set_crypt(req, src, dst, sizeof(vector), iv); + aead_request_set_crypt(req, src, dst, sizeof(p_vector), iv); ret = crypto_aead_encrypt(req); @@ -1499,7 +1580,7 @@ static int linuxkm_test_aesgcm(void) goto test_gcm_end; } - ret = XMEMCMP(enc, enc2, sizeof(vector)); + ret = XMEMCMP(enc, enc2, sizeof(p_vector)); if (ret) { pr_err("error: enc and enc2 do not match: %d\n", ret); goto test_gcm_end; @@ -1523,7 +1604,7 @@ static int linuxkm_test_aesgcm(void) goto test_gcm_end; } - ret = XMEMCMP(dec, dec2, sizeof(vector)); + ret = XMEMCMP(dec, dec2, sizeof(p_vector)); if (ret) { pr_err("error: dec and dec2 do not match: %d\n", ret); goto test_gcm_end; @@ -1554,96 +1635,84 @@ static int linuxkm_test_aesgcm(void) (defined(LINUXKM_LKCAPI_REGISTER_ALL) || \ defined(LINUXKM_LKCAPI_REGISTER_AESXTS)) -#ifndef HEAP_HINT -#define HEAP_HINT NULL -#endif - -#ifndef ERROR_OUT -#define ERROR_OUT(err, eLabel) do { ret = (err); goto eLabel; } while (0) -#endif - -/* note the FIPS code will be returned on failure even in non-FIPS builds. */ -#define LINUXKM_LKCAPI_AES_KAT_MISMATCH_E AES_KAT_FIPS_E - -#ifndef WC_USE_DEVID -#define WC_USE_DEVID INVALID_DEVID -#endif -static const int devId = WC_USE_DEVID; - /* test vectors from * http://csrc.nist.gov/groups/STM/cavp/block-cipher-modes.html */ #ifdef WOLFSSL_AES_128 static int aes_xts_128_test(void) { -#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) XtsAes *aes = NULL; -#else - XtsAes aes[1]; -#endif int aes_inited = 0; int ret = 0; #define AES_XTS_128_TEST_BUF_SIZ (AES_BLOCK_SIZE * 2 + 8) unsigned char *buf = NULL; unsigned char *cipher = NULL; + u8 * enc2 = NULL; + u8 * dec2 = NULL; + struct scatterlist * src = NULL; + struct scatterlist * dst = NULL; + struct crypto_skcipher *tfm = NULL; + struct skcipher_request *req = NULL; + u8 iv[AES_BLOCK_SIZE]; + const char *driver_name; /* 128 key tests */ - WOLFSSL_SMALL_STACK_STATIC const unsigned char k1[] = { + static const unsigned char k1[] = { 0xa1, 0xb9, 0x0c, 0xba, 0x3f, 0x06, 0xac, 0x35, 0x3b, 0x2c, 0x34, 0x38, 0x76, 0x08, 0x17, 0x62, 0x09, 0x09, 0x23, 0x02, 0x6e, 0x91, 0x77, 0x18, 0x15, 0xf2, 0x9d, 0xab, 0x01, 0x93, 0x2f, 0x2f }; - WOLFSSL_SMALL_STACK_STATIC const unsigned char i1[] = { + static const unsigned char i1[] = { 0x4f, 0xae, 0xf7, 0x11, 0x7c, 0xda, 0x59, 0xc6, 0x6e, 0x4b, 0x92, 0x01, 0x3e, 0x76, 0x8a, 0xd5 }; - WOLFSSL_SMALL_STACK_STATIC const unsigned char p1[] = { + static const unsigned char p1[] = { 0xeb, 0xab, 0xce, 0x95, 0xb1, 0x4d, 0x3c, 0x8d, 0x6f, 0xb3, 0x50, 0x39, 0x07, 0x90, 0x31, 0x1c }; /* plain text test of partial block is not from NIST test vector list */ - WOLFSSL_SMALL_STACK_STATIC const unsigned char pp[] = { + static const unsigned char pp[] = { 0xeb, 0xab, 0xce, 0x95, 0xb1, 0x4d, 0x3c, 0x8d, 0x6f, 0xb3, 0x50, 0x39, 0x07, 0x90, 0x31, 0x1c, 0x6e, 0x4b, 0x92, 0x01, 0x3e, 0x76, 0x8a, 0xd5 }; - WOLFSSL_SMALL_STACK_STATIC const unsigned char c1[] = { + static const unsigned char c1[] = { 0x77, 0x8a, 0xe8, 0xb4, 0x3c, 0xb9, 0x8d, 0x5a, 0x82, 0x50, 0x81, 0xd5, 0xbe, 0x47, 0x1c, 0x63 }; /* plain text test of partial block is not from NIST test vector list */ - WOLFSSL_SMALL_STACK_STATIC const unsigned char cp[] = { + static const unsigned char cp[] = { 0x2b, 0xf7, 0x2c, 0xf3, 0xeb, 0x85, 0xef, 0x7b, 0x0b, 0x76, 0xa0, 0xaa, 0xf3, 0x3f, 0x25, 0x8b, 0x77, 0x8a, 0xe8, 0xb4, 0x3c, 0xb9, 0x8d, 0x5a }; - WOLFSSL_SMALL_STACK_STATIC const unsigned char k2[] = { + static const unsigned char k2[] = { 0x39, 0x25, 0x79, 0x05, 0xdf, 0xcc, 0x77, 0x76, 0x6c, 0x87, 0x0a, 0x80, 0x6a, 0x60, 0xe3, 0xc0, 0x93, 0xd1, 0x2a, 0xcf, 0xcb, 0x51, 0x42, 0xfa, 0x09, 0x69, 0x89, 0x62, 0x5b, 0x60, 0xdb, 0x16 }; - WOLFSSL_SMALL_STACK_STATIC const unsigned char i2[] = { + static const unsigned char i2[] = { 0x5c, 0xf7, 0x9d, 0xb6, 0xc5, 0xcd, 0x99, 0x1a, 0x1c, 0x78, 0x81, 0x42, 0x24, 0x95, 0x1e, 0x84 }; - WOLFSSL_SMALL_STACK_STATIC const unsigned char p2[] = { + static const unsigned char p2[] = { 0xbd, 0xc5, 0x46, 0x8f, 0xbc, 0x8d, 0x50, 0xa1, 0x0d, 0x1c, 0x85, 0x7f, 0x79, 0x1c, 0x5c, 0xba, 0xb3, 0x81, 0x0d, 0x0d, 0x73, 0xcf, 0x8f, 0x20, 0x46, 0xb1, 0xd1, 0x9e, 0x7d, 0x5d, 0x8a, 0x56 }; - WOLFSSL_SMALL_STACK_STATIC const unsigned char c2[] = { + static const unsigned char c2[] = { 0xd6, 0xbe, 0x04, 0x6d, 0x41, 0xf2, 0x3b, 0x5e, 0xd7, 0x0b, 0x6b, 0x3d, 0x5c, 0x8e, 0x66, 0x23, 0x2b, 0xe6, 0xb8, 0x07, 0xd4, 0xdc, 0xc6, 0x0e, @@ -1651,24 +1720,24 @@ static int aes_xts_128_test(void) }; #ifndef HAVE_FIPS /* FIPS requires different keys for main and tweak. */ - WOLFSSL_SMALL_STACK_STATIC const unsigned char k3[] = { + static const unsigned char k3[] = { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, }; - WOLFSSL_SMALL_STACK_STATIC const unsigned char i3[] = { + static const unsigned char i3[] = { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, }; - WOLFSSL_SMALL_STACK_STATIC const unsigned char p3[] = { + static const unsigned char p3[] = { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xff, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }; - WOLFSSL_SMALL_STACK_STATIC const unsigned char c3[] = { + static const unsigned char c3[] = { 0xA2, 0x07, 0x47, 0x76, 0x3F, 0xEC, 0x0C, 0x23, 0x1B, 0xD0, 0xBD, 0x46, 0x9A, 0x27, 0x38, 0x12, 0x95, 0x02, 0x3D, 0x5D, 0xC6, 0x94, 0x51, 0x36, @@ -1677,196 +1746,176 @@ static int aes_xts_128_test(void) }; #endif /* HAVE_FIPS */ -#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) - if ((aes = (XtsAes *)XMALLOC(sizeof(*aes), HEAP_HINT, DYNAMIC_TYPE_AES)) + if ((aes = (XtsAes *)XMALLOC(sizeof(*aes), NULL, DYNAMIC_TYPE_AES)) == NULL) { - ERROR_OUT(MEMORY_E, out); + ret = MEMORY_E; + goto out; } -#endif - if ((buf = (unsigned char *)XMALLOC(AES_XTS_128_TEST_BUF_SIZ, HEAP_HINT, + if ((buf = (unsigned char *)XMALLOC(AES_XTS_128_TEST_BUF_SIZ, NULL, DYNAMIC_TYPE_AES)) == NULL) { - ERROR_OUT(MEMORY_E, out); + ret = MEMORY_E; + goto out; } - if ((cipher = (unsigned char *)XMALLOC(AES_XTS_128_TEST_BUF_SIZ, HEAP_HINT, + if ((cipher = (unsigned char *)XMALLOC(AES_XTS_128_TEST_BUF_SIZ, NULL, DYNAMIC_TYPE_AES)) == NULL) { - ERROR_OUT(MEMORY_E, out); - } - -#if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY) \ - && !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS) - ret = EVP_test(EVP_aes_128_xts(), k2, i2, p2, sizeof(p2), c2, sizeof(c2)); - if (ret != 0) { - printf("EVP_aes_128_xts failed!\n"); + ret = MEMORY_E; goto out; } -#endif XMEMSET(buf, 0, AES_XTS_128_TEST_BUF_SIZ); - ret = wc_AesXtsInit(aes, HEAP_HINT, devId); + ret = wc_AesXtsInit(aes, NULL, INVALID_DEVID); if (ret != 0) - ERROR_OUT(ret, out); + goto out; else aes_inited = 1; ret = wc_AesXtsSetKeyNoInit(aes, k2, sizeof(k2), AES_ENCRYPTION); if (ret != 0) - ERROR_OUT(ret, out); + goto out; ret = wc_AesXtsEncrypt(aes, buf, p2, sizeof(p2), i2, sizeof(i2)); -#if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); -#endif if (ret != 0) - ERROR_OUT(ret, out); - if (XMEMCMP(c2, buf, sizeof(c2))) - ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); + goto out; + if (XMEMCMP(c2, buf, sizeof(c2))) { + ret = LINUXKM_LKCAPI_AES_KAT_MISMATCH_E; + goto out; + } #if defined(DEBUG_VECTOR_REGISTER_ACCESS) && defined(WC_AES_C_DYNAMIC_FALLBACK) WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(SYSLIB_FAILED_E); ret = wc_AesXtsEncrypt(aes, buf, p2, sizeof(p2), i2, sizeof(i2)); -#if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); -#endif WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(0); if (ret != 0) - ERROR_OUT(ret, out); - if (XMEMCMP(c2, buf, sizeof(c2))) - ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); + goto out; + if (XMEMCMP(c2, buf, sizeof(c2))) { + ret = LINUXKM_LKCAPI_AES_KAT_MISMATCH_E; + goto out; + } #endif XMEMSET(buf, 0, AES_XTS_128_TEST_BUF_SIZ); ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_ENCRYPTION); if (ret != 0) - ERROR_OUT(ret, out); + goto out; ret = wc_AesXtsEncrypt(aes, buf, p1, sizeof(p1), i1, sizeof(i1)); -#if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); -#endif if (ret != 0) - ERROR_OUT(ret, out); - if (XMEMCMP(c1, buf, AES_BLOCK_SIZE)) - ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); + goto out; + if (XMEMCMP(c1, buf, AES_BLOCK_SIZE)) { + ret = LINUXKM_LKCAPI_AES_KAT_MISMATCH_E; + goto out; + } #if defined(DEBUG_VECTOR_REGISTER_ACCESS) && defined(WC_AES_C_DYNAMIC_FALLBACK) WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(SYSLIB_FAILED_E); ret = wc_AesXtsEncrypt(aes, buf, p1, sizeof(p1), i1, sizeof(i1)); -#if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); -#endif WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(0); if (ret != 0) - ERROR_OUT(ret, out); - if (XMEMCMP(c1, buf, AES_BLOCK_SIZE)) - ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); + goto out; + if (XMEMCMP(c1, buf, AES_BLOCK_SIZE)) { + ret = LINUXKM_LKCAPI_AES_KAT_MISMATCH_E; + goto out; + } #endif /* partial block encryption test */ XMEMSET(cipher, 0, AES_XTS_128_TEST_BUF_SIZ); ret = wc_AesXtsEncrypt(aes, cipher, pp, sizeof(pp), i1, sizeof(i1)); -#if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); -#endif if (ret != 0) - ERROR_OUT(ret, out); - if (XMEMCMP(cp, cipher, sizeof(cp))) - ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); + goto out; + if (XMEMCMP(cp, cipher, sizeof(cp))) { + ret = LINUXKM_LKCAPI_AES_KAT_MISMATCH_E; + goto out; + } #if defined(DEBUG_VECTOR_REGISTER_ACCESS) && defined(WC_AES_C_DYNAMIC_FALLBACK) WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(SYSLIB_FAILED_E); XMEMSET(cipher, 0, AES_XTS_128_TEST_BUF_SIZ); ret = wc_AesXtsEncrypt(aes, cipher, pp, sizeof(pp), i1, sizeof(i1)); -#if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); -#endif WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(0); if (ret != 0) - ERROR_OUT(ret, out); - if (XMEMCMP(cp, cipher, sizeof(cp))) - ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); + goto out; + if (XMEMCMP(cp, cipher, sizeof(cp))) { + ret = LINUXKM_LKCAPI_AES_KAT_MISMATCH_E; + goto out; + } #endif /* partial block decrypt test */ XMEMSET(buf, 0, AES_XTS_128_TEST_BUF_SIZ); ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_DECRYPTION); if (ret != 0) - ERROR_OUT(ret, out); + goto out; ret = wc_AesXtsDecrypt(aes, buf, cipher, sizeof(pp), i1, sizeof(i1)); -#if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); -#endif if (ret != 0) - ERROR_OUT(ret, out); - if (XMEMCMP(pp, buf, sizeof(pp))) - ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); + goto out; + if (XMEMCMP(pp, buf, sizeof(pp))) { + ret = LINUXKM_LKCAPI_AES_KAT_MISMATCH_E; + goto out; + } #if defined(DEBUG_VECTOR_REGISTER_ACCESS) && defined(WC_AES_C_DYNAMIC_FALLBACK) WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(SYSLIB_FAILED_E); XMEMSET(buf, 0, AES_XTS_128_TEST_BUF_SIZ); ret = wc_AesXtsDecrypt(aes, buf, cipher, sizeof(pp), i1, sizeof(i1)); -#if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); -#endif WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(0); if (ret != 0) - ERROR_OUT(ret, out); - if (XMEMCMP(pp, buf, sizeof(pp))) - ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); + goto out; + if (XMEMCMP(pp, buf, sizeof(pp))) { + ret = LINUXKM_LKCAPI_AES_KAT_MISMATCH_E; + goto out; + } #endif /* NIST decrypt test vector */ XMEMSET(buf, 0, AES_XTS_128_TEST_BUF_SIZ); ret = wc_AesXtsDecrypt(aes, buf, c1, sizeof(c1), i1, sizeof(i1)); -#if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); -#endif if (ret != 0) - ERROR_OUT(ret, out); - if (XMEMCMP(p1, buf, AES_BLOCK_SIZE)) - ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); + goto out; + if (XMEMCMP(p1, buf, AES_BLOCK_SIZE)) { + ret = LINUXKM_LKCAPI_AES_KAT_MISMATCH_E; + goto out; + } #if defined(DEBUG_VECTOR_REGISTER_ACCESS) && defined(WC_AES_C_DYNAMIC_FALLBACK) WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(SYSLIB_FAILED_E); XMEMSET(buf, 0, AES_XTS_128_TEST_BUF_SIZ); ret = wc_AesXtsDecrypt(aes, buf, c1, sizeof(c1), i1, sizeof(i1)); -#if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); -#endif WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(0); if (ret != 0) - ERROR_OUT(ret, out); - if (XMEMCMP(p1, buf, AES_BLOCK_SIZE)) - ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); + goto out; + if (XMEMCMP(p1, buf, AES_BLOCK_SIZE)) { + ret = LINUXKM_LKCAPI_AES_KAT_MISMATCH_E; + goto out; + } #endif /* fail case with decrypting using wrong key */ XMEMSET(buf, 0, AES_XTS_128_TEST_BUF_SIZ); ret = wc_AesXtsDecrypt(aes, buf, c2, sizeof(c2), i2, sizeof(i2)); -#if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); -#endif if (ret != 0) - ERROR_OUT(ret, out); - if (XMEMCMP(p2, buf, sizeof(p2)) == 0) /* fail case with wrong key */ - ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); + goto out; + if (XMEMCMP(p2, buf, sizeof(p2)) == 0) { /* fail case with wrong key */ + ret = LINUXKM_LKCAPI_AES_KAT_MISMATCH_E; + goto out; + } /* set correct key and retest */ XMEMSET(buf, 0, AES_XTS_128_TEST_BUF_SIZ); ret = wc_AesXtsSetKeyNoInit(aes, k2, sizeof(k2), AES_DECRYPTION); if (ret != 0) - ERROR_OUT(ret, out); + goto out; ret = wc_AesXtsDecrypt(aes, buf, c2, sizeof(c2), i2, sizeof(i2)); -#if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); -#endif if (ret != 0) - ERROR_OUT(ret, out); - if (XMEMCMP(p2, buf, sizeof(p2))) - ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); + goto out; + if (XMEMCMP(p2, buf, sizeof(p2))) { + ret = LINUXKM_LKCAPI_AES_KAT_MISMATCH_E; + goto out; + } #ifndef HAVE_FIPS @@ -1874,47 +1923,39 @@ static int aes_xts_128_test(void) XMEMCPY(buf, p3, sizeof(p3)); ret = wc_AesXtsSetKeyNoInit(aes, k3, sizeof(k3), AES_ENCRYPTION); if (ret != 0) - ERROR_OUT(ret, out); + goto out; ret = wc_AesXtsEncrypt(aes, buf, buf, sizeof(p3), i3, sizeof(i3)); -#if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); -#endif if (ret != 0) - ERROR_OUT(ret, out); - if (XMEMCMP(c3, buf, sizeof(c3))) - ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); + goto out; + if (XMEMCMP(c3, buf, sizeof(c3))) { + ret = LINUXKM_LKCAPI_AES_KAT_MISMATCH_E; + goto out; + } ret = wc_AesXtsSetKeyNoInit(aes, k3, sizeof(k3), AES_DECRYPTION); if (ret != 0) - ERROR_OUT(ret, out); + goto out; ret = wc_AesXtsDecrypt(aes, buf, buf, sizeof(c3), i3, sizeof(i3)); -#if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); -#endif if (ret != 0) - ERROR_OUT(ret, out); - if (XMEMCMP(p3, buf, sizeof(p3))) - ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); + goto out; + if (XMEMCMP(p3, buf, sizeof(p3))) { + ret = LINUXKM_LKCAPI_AES_KAT_MISMATCH_E; + goto out; + } #endif /* HAVE_FIPS */ -#if !defined(BENCH_EMBEDDED) && !defined(HAVE_CAVIUM) && \ - !defined(WOLFSSL_AFALG) { #define LARGE_XTS_SZ 1024 - #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) - byte* large_input = (byte *)XMALLOC(LARGE_XTS_SZ, HEAP_HINT, + byte* large_input = (byte *)XMALLOC(LARGE_XTS_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #else - byte large_input[LARGE_XTS_SZ]; - #endif int i; int j; - #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) + if (large_input == NULL) - ERROR_OUT(MEMORY_E, out); - #endif + ret = MEMORY_E; + goto out; for (i = 0; i < (int)LARGE_XTS_SZ; i++) large_input[i] = (byte)i; @@ -1922,53 +1963,31 @@ static int aes_xts_128_test(void) for (j = 16; j < (int)LARGE_XTS_SZ; j++) { ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_ENCRYPTION); if (ret != 0) - ERROR_OUT(ret, out); + goto out; ret = wc_AesXtsEncrypt(aes, large_input, large_input, j, i1, sizeof(i1)); - #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, - WC_ASYNC_FLAG_NONE); - #endif if (ret != 0) - ERROR_OUT(ret, out); + goto out; ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_DECRYPTION); if (ret != 0) - ERROR_OUT(ret, out); + goto out; ret = wc_AesXtsDecrypt(aes, large_input, large_input, j, i1, sizeof(i1)); - #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, - WC_ASYNC_FLAG_NONE); - #endif if (ret != 0) - ERROR_OUT(ret, out); + goto out; for (i = 0; i < j; i++) { if (large_input[i] != (byte)i) { - ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); + ret = LINUXKM_LKCAPI_AES_KAT_MISMATCH_E; + goto out; } } } - #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) - XFREE(large_input, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - #endif + XFREE(large_input, NULL, DYNAMIC_TYPE_TMP_BUFFER); } -#endif /* !BENCH_EMBEDDED && !HAVE_CAVIUM && - * !WOLFSSL_AFALG - */ /* now the kernel crypto part */ - { - u8 * enc2 = NULL; - u8 * dec2 = NULL; - struct scatterlist * src = NULL; - struct scatterlist * dst = NULL; - struct crypto_skcipher *tfm = NULL; - struct skcipher_request *req = NULL; - u8 iv[AES_BLOCK_SIZE]; - const char *driver_name; - enc2 = XMALLOC(sizeof(p1), NULL, DYNAMIC_TYPE_AES); if (!enc2) { pr_err("error: malloc failed\n"); @@ -2140,22 +2159,18 @@ static int aes_xts_128_test(void) if (tfm) crypto_free_skcipher(tfm); - } - out: if (aes_inited) wc_AesXtsFree(aes); if (buf) - XFREE(buf, HEAP_HINT, DYNAMIC_TYPE_AES); + XFREE(buf, NULL, DYNAMIC_TYPE_AES); if (cipher) - XFREE(cipher, HEAP_HINT, DYNAMIC_TYPE_AES); + XFREE(cipher, NULL, DYNAMIC_TYPE_AES); -#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) if (aes) - XFREE(aes, HEAP_HINT, DYNAMIC_TYPE_AES); -#endif + XFREE(aes, NULL, DYNAMIC_TYPE_AES); #undef AES_XTS_128_TEST_BUF_SIZ @@ -2166,19 +2181,23 @@ static int aes_xts_128_test(void) #ifdef WOLFSSL_AES_256 static int aes_xts_256_test(void) { -#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) XtsAes *aes = NULL; -#else - XtsAes aes[1]; -#endif int aes_inited = 0; int ret = 0; #define AES_XTS_256_TEST_BUF_SIZ (AES_BLOCK_SIZE * 3) unsigned char *buf = NULL; unsigned char *cipher = NULL; + u8 * enc2 = NULL; + u8 * dec2 = NULL; + struct scatterlist * src = NULL; + struct scatterlist * dst = NULL; + struct crypto_skcipher *tfm = NULL; + struct skcipher_request *req = NULL; + u8 iv[AES_BLOCK_SIZE]; + const char *driver_name; /* 256 key tests */ - WOLFSSL_SMALL_STACK_STATIC const unsigned char k1[] = { + static const unsigned char k1[] = { 0x1e, 0xa6, 0x61, 0xc5, 0x8d, 0x94, 0x3a, 0x0e, 0x48, 0x01, 0xe4, 0x2f, 0x4b, 0x09, 0x47, 0x14, 0x9e, 0x7f, 0x9f, 0x8e, 0x3e, 0x68, 0xd0, 0xc7, @@ -2189,19 +2208,19 @@ static int aes_xts_256_test(void) 0x31, 0x8e, 0xea, 0x39, 0x2c, 0xf4, 0x1b, 0x08 }; - WOLFSSL_SMALL_STACK_STATIC const unsigned char i1[] = { + static const unsigned char i1[] = { 0xad, 0xf8, 0xd9, 0x26, 0x27, 0x46, 0x4a, 0xd2, 0xf0, 0x42, 0x8e, 0x84, 0xa9, 0xf8, 0x75, 0x64 }; - WOLFSSL_SMALL_STACK_STATIC const unsigned char p1[] = { + static const unsigned char p1[] = { 0x2e, 0xed, 0xea, 0x52, 0xcd, 0x82, 0x15, 0xe1, 0xac, 0xc6, 0x47, 0xe8, 0x10, 0xbb, 0xc3, 0x64, 0x2e, 0x87, 0x28, 0x7f, 0x8d, 0x2e, 0x57, 0xe3, 0x6c, 0x0a, 0x24, 0xfb, 0xc1, 0x2a, 0x20, 0x2e }; - WOLFSSL_SMALL_STACK_STATIC const unsigned char c1[] = { + static const unsigned char c1[] = { 0xcb, 0xaa, 0xd0, 0xe2, 0xf6, 0xce, 0xa3, 0xf5, 0x0b, 0x37, 0xf9, 0x34, 0xd4, 0x6a, 0x9b, 0x13, 0x0b, 0x9d, 0x54, 0xf0, 0x7e, 0x34, 0xf3, 0x6a, @@ -2209,19 +2228,19 @@ static int aes_xts_256_test(void) }; /* plain text test of partial block is not from NIST test vector list */ - WOLFSSL_SMALL_STACK_STATIC const unsigned char pp[] = { + static const unsigned char pp[] = { 0xeb, 0xab, 0xce, 0x95, 0xb1, 0x4d, 0x3c, 0x8d, 0x6f, 0xb3, 0x50, 0x39, 0x07, 0x90, 0x31, 0x1c, 0x6e, 0x4b, 0x92, 0x01, 0x3e, 0x76, 0x8a, 0xd5 }; - WOLFSSL_SMALL_STACK_STATIC const unsigned char cp[] = { + static const unsigned char cp[] = { 0x65, 0x5e, 0x1d, 0x37, 0x4a, 0x91, 0xe7, 0x6c, 0x4f, 0x83, 0x92, 0xbc, 0x5a, 0x10, 0x55, 0x27, 0x61, 0x0e, 0x5a, 0xde, 0xca, 0xc5, 0x12, 0xd8 }; - WOLFSSL_SMALL_STACK_STATIC const unsigned char k2[] = { + static const unsigned char k2[] = { 0xad, 0x50, 0x4b, 0x85, 0xd7, 0x51, 0xbf, 0xba, 0x69, 0x13, 0xb4, 0xcc, 0x79, 0xb6, 0x5a, 0x62, 0xf7, 0xf3, 0x9d, 0x36, 0x0f, 0x35, 0xb5, 0xec, @@ -2232,12 +2251,12 @@ static int aes_xts_256_test(void) 0xd2, 0xb5, 0x3a, 0xcb, 0x47, 0x8a, 0x53, 0xb4 }; - WOLFSSL_SMALL_STACK_STATIC const unsigned char i2[] = { + static const unsigned char i2[] = { 0xe6, 0x42, 0x19, 0xed, 0xe0, 0xe1, 0xc2, 0xa0, 0x0e, 0xf5, 0x58, 0x6a, 0xc4, 0x9b, 0xeb, 0x6f }; - WOLFSSL_SMALL_STACK_STATIC const unsigned char p2[] = { + static const unsigned char p2[] = { 0x24, 0xcb, 0x76, 0x22, 0x55, 0xb5, 0xa8, 0x00, 0xf4, 0x6e, 0x80, 0x60, 0x56, 0x9e, 0x05, 0x53, 0xbc, 0xfe, 0x86, 0x55, 0x3b, 0xca, 0xd5, 0x89, @@ -2246,7 +2265,7 @@ static int aes_xts_256_test(void) 0x9e, 0xa9, 0xad, 0x77, 0xa0, 0x13, 0x4c, 0xfc }; - WOLFSSL_SMALL_STACK_STATIC const unsigned char c2[] = { + static const unsigned char c2[] = { 0xa3, 0xc6, 0xf3, 0xf3, 0x82, 0x79, 0x5b, 0x10, 0x87, 0xd7, 0x02, 0x50, 0xdb, 0x2c, 0xd3, 0xb1, 0xa1, 0x62, 0xa8, 0xb6, 0xdc, 0x12, 0x60, 0x61, @@ -2255,126 +2274,100 @@ static int aes_xts_256_test(void) 0xc3, 0xea, 0xd8, 0x10, 0xe9, 0xc0, 0xaf, 0x92 }; -#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) - if ((aes = (XtsAes *)XMALLOC(sizeof(*aes), HEAP_HINT, DYNAMIC_TYPE_AES)) + if ((aes = (XtsAes *)XMALLOC(sizeof(*aes), NULL, DYNAMIC_TYPE_AES)) == NULL) { - ERROR_OUT(MEMORY_E, out); + ret = MEMORY_E; + goto out; } -#endif - if ((buf = (unsigned char *)XMALLOC(AES_XTS_256_TEST_BUF_SIZ, HEAP_HINT, + if ((buf = (unsigned char *)XMALLOC(AES_XTS_256_TEST_BUF_SIZ, NULL, DYNAMIC_TYPE_AES)) == NULL) { - ERROR_OUT(MEMORY_E, out); + ret = MEMORY_E; + goto out; } - if ((cipher = (unsigned char *)XMALLOC(AES_XTS_256_TEST_BUF_SIZ, HEAP_HINT, + if ((cipher = (unsigned char *)XMALLOC(AES_XTS_256_TEST_BUF_SIZ, NULL, DYNAMIC_TYPE_AES)) == NULL) { - ERROR_OUT(MEMORY_E, out); - } - -#if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY) \ - && !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS) - ret = EVP_test(EVP_aes_256_xts(), k2, i2, p2, sizeof(p2), c2, sizeof(c2)); - if (ret != 0) { - printf("EVP_aes_256_xts failed\n"); + ret = MEMORY_E; goto out; } -#endif - ret = wc_AesXtsInit(aes, HEAP_HINT, devId); + ret = wc_AesXtsInit(aes, NULL, INVALID_DEVID); if (ret != 0) - ERROR_OUT(ret, out); + goto out; else aes_inited = 1; XMEMSET(buf, 0, AES_XTS_256_TEST_BUF_SIZ); ret = wc_AesXtsSetKeyNoInit(aes, k2, sizeof(k2), AES_ENCRYPTION); if (ret != 0) - ERROR_OUT(ret, out); + goto out; ret = wc_AesXtsEncrypt(aes, buf, p2, sizeof(p2), i2, sizeof(i2)); -#if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); -#endif if (ret != 0) - ERROR_OUT(ret, out); - if (XMEMCMP(c2, buf, sizeof(c2))) - ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); + goto out; + if (XMEMCMP(c2, buf, sizeof(c2))) { + ret = LINUXKM_LKCAPI_AES_KAT_MISMATCH_E; + goto out; + } XMEMSET(buf, 0, AES_XTS_256_TEST_BUF_SIZ); ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_ENCRYPTION); if (ret != 0) - ERROR_OUT(ret, out); + goto out; ret = wc_AesXtsEncrypt(aes, buf, p1, sizeof(p1), i1, sizeof(i1)); -#if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); -#endif if (ret != 0) - ERROR_OUT(ret, out); - if (XMEMCMP(c1, buf, AES_BLOCK_SIZE)) - ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); + goto out; + if (XMEMCMP(c1, buf, AES_BLOCK_SIZE)) { + ret = LINUXKM_LKCAPI_AES_KAT_MISMATCH_E; + goto out; + } /* partial block encryption test */ XMEMSET(cipher, 0, AES_XTS_256_TEST_BUF_SIZ); ret = wc_AesXtsEncrypt(aes, cipher, pp, sizeof(pp), i1, sizeof(i1)); -#if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_encrypt.asyncDev, WC_ASYNC_FLAG_NONE); -#endif if (ret != 0) - ERROR_OUT(ret, out); + goto out; /* partial block decrypt test */ XMEMSET(buf, 0, AES_XTS_256_TEST_BUF_SIZ); ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_DECRYPTION); if (ret != 0) - ERROR_OUT(ret, out); + goto out; ret = wc_AesXtsDecrypt(aes, buf, cipher, sizeof(pp), i1, sizeof(i1)); -#if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); -#endif if (ret != 0) - ERROR_OUT(ret, out); - if (XMEMCMP(pp, buf, sizeof(pp))) - ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); + goto out; + if (XMEMCMP(pp, buf, sizeof(pp))) { + ret = LINUXKM_LKCAPI_AES_KAT_MISMATCH_E; + goto out; + } /* NIST decrypt test vector */ XMEMSET(buf, 0, AES_XTS_256_TEST_BUF_SIZ); ret = wc_AesXtsDecrypt(aes, buf, c1, sizeof(c1), i1, sizeof(i1)); -#if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); -#endif if (ret != 0) - ERROR_OUT(ret, out); - if (XMEMCMP(p1, buf, AES_BLOCK_SIZE)) - ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); + goto out; + if (XMEMCMP(p1, buf, AES_BLOCK_SIZE)) { + ret = LINUXKM_LKCAPI_AES_KAT_MISMATCH_E; + goto out; + } XMEMSET(buf, 0, AES_XTS_256_TEST_BUF_SIZ); ret = wc_AesXtsSetKeyNoInit(aes, k2, sizeof(k2), AES_DECRYPTION); if (ret != 0) - ERROR_OUT(ret, out); + goto out; ret = wc_AesXtsDecrypt(aes, buf, c2, sizeof(c2), i2, sizeof(i2)); -#if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, WC_ASYNC_FLAG_NONE); -#endif if (ret != 0) - ERROR_OUT(ret, out); - if (XMEMCMP(p2, buf, sizeof(p2))) - ERROR_OUT(LINUXKM_LKCAPI_AES_KAT_MISMATCH_E, out); + goto out; + if (XMEMCMP(p2, buf, sizeof(p2))) { + ret = LINUXKM_LKCAPI_AES_KAT_MISMATCH_E; + goto out; + } /* now the kernel crypto part */ - { - u8 * enc2 = NULL; - u8 * dec2 = NULL; - struct scatterlist * src = NULL; - struct scatterlist * dst = NULL; - struct crypto_skcipher *tfm = NULL; - struct skcipher_request *req = NULL; - u8 iv[AES_BLOCK_SIZE]; - const char *driver_name; - enc2 = XMALLOC(sizeof(p1), NULL, DYNAMIC_TYPE_AES); if (!enc2) { pr_err("error: malloc failed\n"); @@ -2546,22 +2539,18 @@ static int aes_xts_256_test(void) if (tfm) crypto_free_skcipher(tfm); - } - out: if (aes_inited) wc_AesXtsFree(aes); if (buf) - XFREE(buf, HEAP_HINT, DYNAMIC_TYPE_AES); + XFREE(buf, NULL, DYNAMIC_TYPE_AES); if (cipher) - XFREE(cipher, HEAP_HINT, DYNAMIC_TYPE_AES); + XFREE(cipher, NULL, DYNAMIC_TYPE_AES); -#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) if (aes) - XFREE(aes, HEAP_HINT, DYNAMIC_TYPE_AES); -#endif + XFREE(aes, NULL, DYNAMIC_TYPE_AES); #undef AES_XTS_256_TEST_BUF_SIZ diff --git a/linuxkm/module_hooks.c b/linuxkm/module_hooks.c index 6c5a62ce7f..76c104db9b 100644 --- a/linuxkm/module_hooks.c +++ b/linuxkm/module_hooks.c @@ -760,11 +760,19 @@ static int updateFipsHash(void) } } - if (XMEMCMP(hash, binVerify, WC_SHA256_DIGEST_SIZE) == 0) + if (XMEMCMP(hash, binVerify, WC_SHA256_DIGEST_SIZE) == 0) { +#if defined(DEBUG_LINUXKM_PIE_SUPPORT) || defined(WOLFSSL_LINUXKM_VERBOSE_DEBUG) + pr_info("updateFipsHash: verifyCore already matches [%s]\n", verifyCore); +#else pr_info("updateFipsHash: verifyCore already matches.\n"); - else { +#endif + } else { XMEMCPY(verifyCore, base16_hash, WC_SHA256_DIGEST_SIZE*2 + 1); +#if defined(DEBUG_LINUXKM_PIE_SUPPORT) || defined(WOLFSSL_LINUXKM_VERBOSE_DEBUG) + pr_info("updateFipsHash: verifyCore updated [%s].\n", base16_hash); +#else pr_info("updateFipsHash: verifyCore updated.\n"); +#endif } ret = 0; From c8b0aac144821f8707598aa95fbc8291154a338c Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Fri, 2 Feb 2024 12:35:39 +1000 Subject: [PATCH 46/63] SHA-256 Aarch64: fix alignments on loads and stores Input buffer must be loaded with a byte alignment. Fix other loads and stores to be consistent. --- wolfcrypt/src/port/arm/armv8-sha256.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/wolfcrypt/src/port/arm/armv8-sha256.c b/wolfcrypt/src/port/arm/armv8-sha256.c index 2fa9adfb33..e65e2104ee 100644 --- a/wolfcrypt/src/port/arm/armv8-sha256.c +++ b/wolfcrypt/src/port/arm/armv8-sha256.c @@ -281,7 +281,7 @@ static WC_INLINE void Sha256Transform(wc_Sha256* sha256, const byte* data, "CBZ w8, 2f \n" "#load in message and schedule updates \n" - "LD1 {v0.2d-v3.2d}, [%[dataIn]], #64 \n" + "LD1 {v0.16b-v3.16b}, [%[dataIn]], #64 \n" "MOV v14.16b, v12.16b \n" "MOV v15.16b, v13.16b \n" "REV32 v0.16b, v0.16b \n" @@ -291,7 +291,7 @@ static WC_INLINE void Sha256Transform(wc_Sha256* sha256, const byte* data, "B 1b \n" /* do another block */ "2:\n" - "STP q12, q13, %[out] \n" + "ST1 {v12.2d-v13.2d}, %[out] \n" : [out] "=m" (sha256->digest), "=m" (sha256->buffer), "=r" (numBlocks), "=r" (data), "=r" (k) @@ -378,7 +378,7 @@ static WC_INLINE int Sha256Final(wc_Sha256* sha256, byte* hash) "MOV v16.16b, v20.16b \n" "MOV v17.16b, v21.16b \n" - "LD1 {v22.16b-v25.16b}, [%[k]], #64 \n" + "LD1 {v22.4s-v25.4s}, [%[k]], #64 \n" "SHA256SU0 v4.4s, v1.4s \n" "ADD v0.4s, v0.4s, v22.4s \n" "MOV v6.16b, v2.16b \n" @@ -411,7 +411,7 @@ static WC_INLINE int Sha256Final(wc_Sha256* sha256, byte* hash) "SHA256H q16, q17, v3.4s \n" "SHA256H2 q17, q18, v3.4s \n" - "LD1 {v22.16b-v25.16b}, [%[k]], #64 \n" + "LD1 {v22.4s-v25.4s}, [%[k]], #64 \n" "SHA256SU0 v8.4s, v5.4s \n" "ADD v4.4s, v4.4s, v22.4s \n" "MOV v18.16b, v16.16b \n" @@ -444,7 +444,7 @@ static WC_INLINE int Sha256Final(wc_Sha256* sha256, byte* hash) "SHA256H q16, q17, v7.4s \n" "SHA256H2 q17, q18, v7.4s \n" - "LD1 {v22.16b-v25.16b}, [%[k]], #64 \n" + "LD1 {v22.4s-v25.4s}, [%[k]], #64 \n" "SHA256SU0 v12.4s, v9.4s \n" "ADD v8.4s, v8.4s, v22.4s \n" "MOV v18.16b, v16.16b \n" @@ -475,7 +475,7 @@ static WC_INLINE int Sha256Final(wc_Sha256* sha256, byte* hash) "SHA256H q16, q17, v11.4s \n" "SHA256H2 q17, q18, v11.4s \n" - "LD1 {v22.16b-v25.16b}, [%[k]] \n" + "LD1 {v22.4s-v25.4s}, [%[k]] \n" "ADD v12.4s, v12.4s, v22.4s \n" "MOV v18.16b, v16.16b \n" "SHA256H q16, q17, v12.4s \n" @@ -499,7 +499,7 @@ static WC_INLINE int Sha256Final(wc_Sha256* sha256, byte* hash) "#Add working vars back into digest state \n" "ADD v16.4s, v16.4s, v20.4s \n" "ADD v17.4s, v17.4s, v21.4s \n" - "STP q16, q17, %[out] \n" + "ST1 {v16.2d-v17.2d}, %[out] \n" : [out] "=m" (sha256->digest), [k] "+r" (k) : [digest] "m" (sha256->digest), @@ -549,7 +549,7 @@ static WC_INLINE int Sha256Final(wc_Sha256* sha256, byte* hash) "MOV v16.16b, v20.16b \n" "MOV v17.16b, v21.16b \n" - "LD1 {v22.16b-v25.16b}, [%[k]], #64 \n" + "LD1 {v22.4s-v25.4s}, [%[k]], #64 \n" "SHA256SU0 v4.4s, v1.4s \n" "ADD v0.4s, v0.4s, v22.4s \n" "MOV v6.16b, v2.16b \n" @@ -582,7 +582,7 @@ static WC_INLINE int Sha256Final(wc_Sha256* sha256, byte* hash) "SHA256H q16, q17, v3.4s \n" "SHA256H2 q17, q18, v3.4s \n" - "LD1 {v22.16b-v25.16b}, [%[k]], #64 \n" + "LD1 {v22.4s-v25.4s}, [%[k]], #64 \n" "SHA256SU0 v8.4s, v5.4s \n" "ADD v4.4s, v4.4s, v22.4s \n" "MOV v18.16b, v16.16b \n" @@ -615,7 +615,7 @@ static WC_INLINE int Sha256Final(wc_Sha256* sha256, byte* hash) "SHA256H q16, q17, v7.4s \n" "SHA256H2 q17, q18, v7.4s \n" - "LD1 {v22.16b-v25.16b}, [%[k]], #64 \n" + "LD1 {v22.4s-v25.4s}, [%[k]], #64 \n" "SHA256SU0 v12.4s, v9.4s \n" "ADD v8.4s, v8.4s, v22.4s \n" "MOV v18.16b, v16.16b \n" @@ -646,7 +646,7 @@ static WC_INLINE int Sha256Final(wc_Sha256* sha256, byte* hash) "SHA256H q16, q17, v11.4s \n" "SHA256H2 q17, q18, v11.4s \n" - "LD1 {v22.16b-v25.16b}, [%[k]] \n" + "LD1 {v22.4s-v25.4s}, [%[k]] \n" "ADD v12.4s, v12.4s, v22.4s \n" "MOV v18.16b, v16.16b \n" "SHA256H q16, q17, v12.4s \n" From d3b0a26b3bf3c4a1e34e78fd17da24315cb5a9af Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 2 Feb 2024 11:02:39 +0100 Subject: [PATCH 47/63] If bio.h is included first then it can't include options.h on its own When EXTERNAL_OPTS_OPENVPN is defined, we should be including options.h internally. When bio.h is included first, we don't include options.h and we don't pass the `#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)` guard. --- wolfssl/openssl/bio.h | 1 + 1 file changed, 1 insertion(+) diff --git a/wolfssl/openssl/bio.h b/wolfssl/openssl/bio.h index e6f5a709ca..9206b092a9 100644 --- a/wolfssl/openssl/bio.h +++ b/wolfssl/openssl/bio.h @@ -25,6 +25,7 @@ #ifndef WOLFSSL_BIO_H_ #define WOLFSSL_BIO_H_ +#include #ifdef __cplusplus extern "C" { From 7ebb8cd00786a8ac501a83c0773e52d94199d49d Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 2 Feb 2024 12:09:50 +0100 Subject: [PATCH 48/63] Update radix tests --- wolfcrypt/test/test.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index d598046e8d..7921d68cca 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -44708,7 +44708,7 @@ static wc_test_ret_t mp_test_radix_10(mp_int* a, mp_int* r, WC_RNG* rng) char str[30]; WOLFSSL_SMALL_STACK_STATIC const char* badStr1 = "A"; WOLFSSL_SMALL_STACK_STATIC const char* badStr2 = "a"; - WOLFSSL_SMALL_STACK_STATIC const char* badStr3 = " "; + WOLFSSL_SMALL_STACK_STATIC const char* empty2 = " "; WOLFSSL_SMALL_STACK_STATIC const char* zeros = "000"; WOLFSSL_SMALL_STACK_STATIC const char* empty = ""; @@ -44740,8 +44740,8 @@ static wc_test_ret_t mp_test_radix_10(mp_int* a, mp_int* r, WC_RNG* rng) ret = mp_read_radix(r, badStr2, MP_RADIX_DEC); if (ret != MP_VAL) return WC_TEST_RET_ENC_EC(ret); - ret = mp_read_radix(r, badStr3, MP_RADIX_DEC); - if (ret != MP_VAL) + ret = mp_read_radix(r, empty2, MP_RADIX_DEC); + if (ret != MP_OKAY) return WC_TEST_RET_ENC_EC(ret); ret = mp_read_radix(r, zeros, MP_RADIX_DEC); @@ -44788,7 +44788,7 @@ static wc_test_ret_t mp_test_radix_16(mp_int* a, mp_int* r, WC_RNG* rng) #if defined(WOLFSSL_SP_MATH) || defined(USE_FAST_MATH) static char longStr[2 * sizeof(a->dp) + 2]; #endif - WOLFSSL_SMALL_STACK_STATIC const char* badStr1 = " "; + WOLFSSL_SMALL_STACK_STATIC const char* empty2 = " "; WOLFSSL_SMALL_STACK_STATIC const char* badStr2 = "}"; WOLFSSL_SMALL_STACK_STATIC const char* empty = ""; @@ -44808,8 +44808,8 @@ static wc_test_ret_t mp_test_radix_16(mp_int* a, mp_int* r, WC_RNG* rng) } } - ret = mp_read_radix(r, badStr1, MP_RADIX_HEX); - if (ret != MP_VAL) + ret = mp_read_radix(r, empty2, MP_RADIX_HEX); + if (ret != MP_OKAY) return WC_TEST_RET_ENC_EC(ret); ret = mp_read_radix(r, badStr2, MP_RADIX_HEX); if (ret != MP_VAL) From be90fe073e6859c97cabeaf89c057820985edcf7 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 2 Feb 2024 14:38:40 +0100 Subject: [PATCH 49/63] tfm and integer: skip whitespace at end in radix read --- wolfcrypt/src/integer.c | 3 +++ wolfcrypt/src/tfm.c | 8 +++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/wolfcrypt/src/integer.c b/wolfcrypt/src/integer.c index 21ae2353a4..dadfeb4eef 100644 --- a/wolfcrypt/src/integer.c +++ b/wolfcrypt/src/integer.c @@ -5358,6 +5358,9 @@ int mp_read_radix (mp_int * a, const char *str, int radix) ++str; } + /* Skip whitespace at end of str */ + while (CharIsWhiteSpace(*str)) + ++str; /* if digit in isn't null term, then invalid character was found */ if (*str != '\0') { mp_zero (a); diff --git a/wolfcrypt/src/tfm.c b/wolfcrypt/src/tfm.c index ff895c8ac6..65d92ffa10 100644 --- a/wolfcrypt/src/tfm.c +++ b/wolfcrypt/src/tfm.c @@ -6029,7 +6029,13 @@ static int fp_read_radix(fp_int *a, const char *str, int radix) } } if (y >= radix) { - return FP_VAL; + /* Check if whitespace at end of line */ + while (CharIsWhiteSpace(*str)) + ++str; + if (*str) + return FP_VAL; + else + break; } /* if the char was found in the map From 188a69e6497af85d41849eac29d35ebfe30ee6b9 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 2 Feb 2024 18:29:15 +0100 Subject: [PATCH 50/63] test_wolfSSL_OPENSSL_hexstr2buf: test was always skipped --- tests/api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/api.c b/tests/api.c index d9c75f6752..7f53844ccb 100644 --- a/tests/api.c +++ b/tests/api.c @@ -47311,7 +47311,7 @@ static int test_wolfSSL_OPENSSL_hexstr2buf(void) long len = 0; unsigned char* returnedBuf = NULL; - for (i = 0; i < NUM_CASES && EXPECT_SUCCESS(); ++i) { + for (i = 0; i < NUM_CASES && !EXPECT_FAIL(); ++i) { returnedBuf = wolfSSL_OPENSSL_hexstr2buf(inputs[i], &len); if (returnedBuf == NULL) { ExpectIntEQ(expectedOutputs[i].ret, 0); From 5b5d6481de7b528ec1eb8b9340b569a5ade406b3 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 2 Feb 2024 19:47:25 +0100 Subject: [PATCH 51/63] Fix write_dup with chacha-poly --- src/ssl.c | 12 +++++ tests/api.c | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 153 insertions(+) diff --git a/src/ssl.c b/src/ssl.c index b4cac31053..ff88531f86 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -1582,6 +1582,18 @@ static int DupSSL(WOLFSSL* dup, WOLFSSL* ssl) XMEMCPY(&dup->version, &ssl->version, sizeof(ProtocolVersion)); XMEMCPY(&dup->chVersion, &ssl->chVersion, sizeof(ProtocolVersion)); +#ifdef HAVE_ONE_TIME_AUTH +#ifdef HAVE_POLY1305 + if (ssl->auth.setup && ssl->auth.poly1305 != NULL) { + dup->auth.poly1305 = + (Poly1305*)XMALLOC(sizeof(Poly1305), dup->heap, DYNAMIC_TYPE_CIPHER); + if (dup->auth.poly1305 == NULL) + return MEMORY_E; + dup->auth.setup = 1; + } +#endif +#endif + /* dup side now owns encrypt/write ciphers */ XMEMSET(&ssl->encrypt, 0, sizeof(Ciphers)); diff --git a/tests/api.c b/tests/api.c index d9c75f6752..8f7280d7ea 100644 --- a/tests/api.c +++ b/tests/api.c @@ -69273,6 +69273,146 @@ static int test_tls_multi_handshakes_one_record(void) return EXPECT_RESULT(); } + +static int test_write_dup(void) +{ + EXPECT_DECLS; +#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(HAVE_WRITE_DUP) + size_t i, j; + char hiWorld[] = "dup message"; + char readData[sizeof(hiWorld) + 5]; + struct { + method_provider client_meth; + method_provider server_meth; + const char* version_name; + int version; + } methods[] = { +#ifndef WOLFSSL_NO_TLS12 + {wolfTLSv1_2_client_method, wolfTLSv1_2_server_method, "TLS 1.2", WOLFSSL_TLSV1_2}, +#endif +#ifdef WOLFSSL_TLS13 + {wolfTLSv1_3_client_method, wolfTLSv1_3_server_method, "TLS 1.3", WOLFSSL_TLSV1_3}, +#endif + }; + struct { + const char* cipher; + int version; + } ciphers[] = { +/* For simplicity the macros are copied from internal.h */ +/* TLS 1.2 */ +#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) && !defined(NO_SHA256) + #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) + #ifndef NO_RSA + {"ECDHE-RSA-CHACHA20-POLY1305", WOLFSSL_TLSV1_2}, + #endif + #endif + #if !defined(NO_DH) && !defined(NO_RSA) && !defined(NO_TLS_DH) + {"DHE-RSA-CHACHA20-POLY1305", WOLFSSL_TLSV1_2}, + #endif +#endif +#if !defined(NO_DH) && !defined(NO_AES) && !defined(NO_TLS) && \ + !defined(NO_RSA) && defined(HAVE_AESGCM) && !defined(NO_TLS_DH) + #if !defined(NO_SHA256) && defined(WOLFSSL_AES_128) + {"DHE-RSA-AES128-GCM-SHA256", WOLFSSL_TLSV1_2}, + #endif + #if defined(WOLFSSL_SHA384) && defined(WOLFSSL_AES_256) + {"DHE-RSA-AES256-GCM-SHA384", WOLFSSL_TLSV1_2}, + #endif +#endif +#if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)) \ + && !defined(NO_TLS) && !defined(NO_AES) + #ifdef HAVE_AESGCM + #if !defined(NO_SHA256) && defined(WOLFSSL_AES_128) + #ifndef NO_RSA + {"ECDHE-RSA-AES128-GCM-SHA256", WOLFSSL_TLSV1_2}, + #endif + #endif + #if defined(WOLFSSL_SHA384) && defined(WOLFSSL_AES_256) + #ifndef NO_RSA + {"ECDHE-RSA-AES256-GCM-SHA384", WOLFSSL_TLSV1_2}, + #endif + #endif + #endif +#endif +/* TLS 1.3 */ +#ifdef WOLFSSL_TLS13 + #ifdef HAVE_AESGCM + #if !defined(NO_SHA256) && defined(WOLFSSL_AES_128) + {"TLS13-AES128-GCM-SHA256", WOLFSSL_TLSV1_3}, + #endif + #if defined(WOLFSSL_SHA384) && defined(WOLFSSL_AES_256) + {"TLS13-AES256-GCM-SHA384", WOLFSSL_TLSV1_3}, + #endif + #endif + #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) + #ifndef NO_SHA256 + {"TLS13-CHACHA20-POLY1305-SHA256", WOLFSSL_TLSV1_3}, + #endif + #endif + #ifdef HAVE_AESCCM + #if !defined(NO_SHA256) && defined(WOLFSSL_AES_128) + {"TLS13-AES128-CCM-SHA256", WOLFSSL_TLSV1_3}, + #endif + #endif +#endif + }; + + for (i = 0; i < XELEM_CNT(methods); i++) { + for (j = 0; j < XELEM_CNT(ciphers) && !EXPECT_FAIL(); j++) { + struct test_memio_ctx test_ctx; + WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL; + WOLFSSL *ssl_c = NULL, *ssl_s = NULL; + WOLFSSL *ssl_c2 = NULL; + + if (methods[i].version != ciphers[j].version) + continue; + + if (i == 0 && j == 0) + printf("\n"); + + printf("Testing %s with %s... ", methods[i].version_name, + ciphers[j].cipher); + + XMEMSET(&test_ctx, 0, sizeof(test_ctx)); + + test_ctx.c_ciphers = test_ctx.s_ciphers = ciphers[j].cipher; + + ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s, + methods[i].client_meth, methods[i].server_meth), 0); + ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0); + + ExpectNotNull(ssl_c2 = wolfSSL_write_dup(ssl_c)); + ExpectIntEQ(wolfSSL_write(ssl_c, hiWorld, sizeof(hiWorld)), + WRITE_DUP_WRITE_E); + ExpectIntEQ(wolfSSL_write(ssl_c2, hiWorld, sizeof(hiWorld)), + sizeof(hiWorld)); + + ExpectIntEQ(wolfSSL_read(ssl_s, readData, sizeof(readData)), + sizeof(hiWorld)); + ExpectIntEQ(wolfSSL_write(ssl_s, hiWorld, sizeof(hiWorld)), + sizeof(hiWorld)); + + ExpectIntEQ(wolfSSL_read(ssl_c2, readData, sizeof(readData)), + WRITE_DUP_READ_E); + ExpectIntEQ(wolfSSL_read(ssl_c, readData, sizeof(readData)), + sizeof(hiWorld)); + + if (EXPECT_SUCCESS()) + printf("ok\n"); + else + printf("failed\n"); + + wolfSSL_free(ssl_c); + wolfSSL_free(ssl_c2); + wolfSSL_free(ssl_s); + wolfSSL_CTX_free(ctx_c); + wolfSSL_CTX_free(ctx_s); + } + } +#endif + return EXPECT_RESULT(); +} + /*----------------------------------------------------------------------------* | Main *----------------------------------------------------------------------------*/ @@ -70577,6 +70717,7 @@ TEST_CASE testCases[] = { TEST_DECL(test_tls13_pq_groups), TEST_DECL(test_tls13_early_data), TEST_DECL(test_tls_multi_handshakes_one_record), + TEST_DECL(test_write_dup), /* This test needs to stay at the end to clean up any caches allocated. */ TEST_DECL(test_wolfSSL_Cleanup) }; From 31bfac43ea9e2c92639b150a5e3c1a090a2b298c Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 2 Feb 2024 20:14:28 +0100 Subject: [PATCH 52/63] Update github actions Many of these updates should also speed up some steps --- .github/workflows/async.yml | 2 +- .github/workflows/curl.yml | 4 ++-- .github/workflows/docker-Espressif.yml | 6 +++--- .github/workflows/docker-OpenWrt.yml | 12 ++++++------ .github/workflows/haproxy.yml | 4 ++-- .github/workflows/hitch.yml | 8 ++++---- .github/workflows/hostap.yml | 12 ++++++------ .github/workflows/krb5.yml | 8 ++++---- .github/workflows/libssh2.yml | 4 ++-- .github/workflows/memcached.yml | 8 ++++---- .github/workflows/multi-arch.yml | 2 +- .github/workflows/multi-compiler.yml | 2 +- .github/workflows/nginx.yml | 10 +++++----- .github/workflows/openvpn.yml | 4 ++-- .github/workflows/os-check.yml | 6 +++--- .github/workflows/packaging.yml | 2 +- .github/workflows/stunnel.yml | 6 +++--- .github/workflows/zephyr.yml | 2 +- 18 files changed, 51 insertions(+), 51 deletions(-) diff --git a/.github/workflows/async.yml b/.github/workflows/async.yml index 84eb4c5882..36f50265a7 100644 --- a/.github/workflows/async.yml +++ b/.github/workflows/async.yml @@ -18,7 +18,7 @@ jobs: # This should be a safe limit for the tests to run. timeout-minutes: 6 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 name: Checkout wolfSSL - name: Test wolfSSL async diff --git a/.github/workflows/curl.yml b/.github/workflows/curl.yml index e9556da5a0..1b440e428e 100644 --- a/.github/workflows/curl.yml +++ b/.github/workflows/curl.yml @@ -18,7 +18,7 @@ jobs: install: true - name: Upload built lib - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: wolf-install-curl path: build-dir @@ -42,7 +42,7 @@ jobs: sudo pip install impacket - name: Download lib - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: wolf-install-curl path: build-dir diff --git a/.github/workflows/docker-Espressif.yml b/.github/workflows/docker-Espressif.yml index 9b9b9be203..4990e92850 100644 --- a/.github/workflows/docker-Espressif.yml +++ b/.github/workflows/docker-Espressif.yml @@ -11,7 +11,7 @@ jobs: container: image: espressif/idf:latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Initialize Espressif IDE and build examples run: . /opt/esp/idf/export.sh; IDE/Espressif/ESP-IDF/compileAllExamples.sh espressif_v4_4: @@ -20,7 +20,7 @@ jobs: container: image: espressif/idf:release-v4.4 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Initialize Espressif IDE and build examples run: . /opt/esp/idf/export.sh; IDE/Espressif/ESP-IDF/compileAllExamples.sh espressif_v5_0: @@ -29,6 +29,6 @@ jobs: container: image: espressif/idf:release-v5.0 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Initialize Espressif IDE and build examples run: . /opt/esp/idf/export.sh; IDE/Espressif/ESP-IDF/compileAllExamples.sh diff --git a/.github/workflows/docker-OpenWrt.yml b/.github/workflows/docker-OpenWrt.yml index aa89f450b0..8ae62b6bde 100644 --- a/.github/workflows/docker-OpenWrt.yml +++ b/.github/workflows/docker-OpenWrt.yml @@ -16,11 +16,11 @@ jobs: steps: - name: Install required tools run: apk add argp-standalone asciidoc bash bc binutils bzip2 cdrkit coreutils diffutils elfutils-dev findutils flex musl-fts-dev g++ gawk gcc gettext git grep intltool libxslt linux-headers make musl-libintl musl-obstack-dev ncurses-dev openssl-dev patch perl python3-dev rsync tar unzip util-linux wget zlib-dev autoconf automake libtool - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Compile libwolfssl.so run: ./autogen.sh && ./configure --enable-all && make - name: Upload libwolfssl.so - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: openwrt-libwolfssl.so path: src/.libs/libwolfssl.so @@ -36,14 +36,14 @@ jobs: matrix: release: [ "22.03.6", "21.02.7" ] # some other versions: 21.02.0 21.02.5 22.03.0 22.03.3 snapshot steps: - - uses: actions/checkout@v3 - - uses: docker/setup-buildx-action@v2 - - uses: actions/download-artifact@v3 + - uses: actions/checkout@v4 + - uses: docker/setup-buildx-action@v3 + - uses: actions/download-artifact@v4 with: name: openwrt-libwolfssl.so path: Docker/OpenWrt/. - name: Build but dont push - uses: docker/build-push-action@v3 + uses: docker/build-push-action@v5 with: context: Docker/OpenWrt platforms: linux/amd64 diff --git a/.github/workflows/haproxy.yml b/.github/workflows/haproxy.yml index 54a52b8cf3..9c7047bc24 100644 --- a/.github/workflows/haproxy.yml +++ b/.github/workflows/haproxy.yml @@ -21,7 +21,7 @@ jobs: install: true - name: Checkout VTest - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: vtest/VTest path: VTest @@ -32,7 +32,7 @@ jobs: run: make FLAGS='-O2 -s -Wall' - name: Checkout HaProxy - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: haproxy/haproxy path: haproxy diff --git a/.github/workflows/hitch.yml b/.github/workflows/hitch.yml index a7f745dbf8..466451df61 100644 --- a/.github/workflows/hitch.yml +++ b/.github/workflows/hitch.yml @@ -19,7 +19,7 @@ jobs: install: true - name: Upload built lib - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: wolf-install-hitch path: build-dir @@ -41,13 +41,13 @@ jobs: needs: build_wolfssl steps: - name: Download lib - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: wolf-install-hitch path: build-dir - name: Checkout OSP - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: wolfssl/osp path: osp @@ -59,7 +59,7 @@ jobs: sudo apt-get install -y libev-dev libssl-dev automake python3-docutils flex bison pkg-config make - name: Checkout hitch - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: varnish/hitch ref: 1.7.3 diff --git a/.github/workflows/hostap.yml b/.github/workflows/hostap.yml index 84ea1009e1..9bfb22f7c7 100644 --- a/.github/workflows/hostap.yml +++ b/.github/workflows/hostap.yml @@ -40,7 +40,7 @@ jobs: install: true - name: Upload built lib - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{ matrix.build_id }} path: build-dir @@ -113,7 +113,7 @@ jobs: echo Our job run ID is $SHA_SUM - name: Checkout wolfSSL - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: path: wolfssl @@ -140,7 +140,7 @@ jobs: echo "hostap_debug_flags=-d" >> $GITHUB_ENV - name: Download lib - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: ${{ matrix.config.build_id }} path: build-dir @@ -170,7 +170,7 @@ jobs: sudo rmmod mac80211_hwsim - name: Checkout hostap - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: julek-wolfssl/hostap-mirror path: hostap @@ -185,7 +185,7 @@ jobs: - if: ${{ matrix.config.osp_ref }} name: Checkout OSP - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: wolfssl/osp path: osp @@ -275,7 +275,7 @@ jobs: - name: Upload failure logs if: ${{ failure() && steps.testing.outcome == 'failure' }} - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: hostap-logs-${{ env.our_job_run_id }} path: hostap/tests/hwsim/logs.zip diff --git a/.github/workflows/krb5.yml b/.github/workflows/krb5.yml index f03237c857..d62614429f 100644 --- a/.github/workflows/krb5.yml +++ b/.github/workflows/krb5.yml @@ -19,7 +19,7 @@ jobs: install: true - name: Upload built lib - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: wolf-install-krb5 path: build-dir @@ -38,19 +38,19 @@ jobs: needs: build_wolfssl steps: - name: Download lib - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: wolf-install-krb5 path: build-dir - name: Checkout OSP - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: wolfssl/osp path: osp - name: Checkout krb5 - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: krb5/krb5 ref: krb5-${{ matrix.ref }}-final diff --git a/.github/workflows/libssh2.yml b/.github/workflows/libssh2.yml index ec82ce1daa..ee83b49791 100644 --- a/.github/workflows/libssh2.yml +++ b/.github/workflows/libssh2.yml @@ -20,7 +20,7 @@ jobs: install: true - name: Upload built lib - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: wolf-install-libssh2 path: build-dir @@ -39,7 +39,7 @@ jobs: needs: build_wolfssl steps: - name: Download lib - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: wolf-install-libssh2 path: build-dir diff --git a/.github/workflows/memcached.yml b/.github/workflows/memcached.yml index 9a4c813177..ea5b11759e 100644 --- a/.github/workflows/memcached.yml +++ b/.github/workflows/memcached.yml @@ -20,7 +20,7 @@ jobs: run: cp wolfssl/.github/workflows/memcached.sh build-dir/bin - name: Upload built lib - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: wolf-install-memcached path: build-dir @@ -38,13 +38,13 @@ jobs: needs: build_wolfssl steps: - name: Download lib - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: wolf-install-memcached path: build-dir - name: Checkout OSP - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: wolfssl/osp path: osp @@ -56,7 +56,7 @@ jobs: sudo apt-get install -y libevent-dev libevent-2.1-7 automake pkg-config make libio-socket-ssl-perl - name: Checkout memcached - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: memcached/memcached ref: 1.6.22 diff --git a/.github/workflows/multi-arch.yml b/.github/workflows/multi-arch.yml index e5b9859ad6..031ca802e8 100644 --- a/.github/workflows/multi-arch.yml +++ b/.github/workflows/multi-arch.yml @@ -35,7 +35,7 @@ jobs: run: | sudo apt update sudo apt install -y crossbuild-essential-${{ matrix.ARCH }} qemu-user - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Build env: CC: ${{ matrix.CC }} diff --git a/.github/workflows/multi-compiler.yml b/.github/workflows/multi-compiler.yml index 48512df295..b63fd0f2f3 100644 --- a/.github/workflows/multi-compiler.yml +++ b/.github/workflows/multi-compiler.yml @@ -41,7 +41,7 @@ jobs: # This should be a safe limit for the tests to run. timeout-minutes: 4 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Build env: CC: ${{ matrix.CC }} diff --git a/.github/workflows/nginx.yml b/.github/workflows/nginx.yml index 05f2ed7c47..70aaaba134 100644 --- a/.github/workflows/nginx.yml +++ b/.github/workflows/nginx.yml @@ -25,7 +25,7 @@ jobs: install: true - name: Upload built lib - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: wolf-install-nginx path: build-dir @@ -99,7 +99,7 @@ jobs: needs: build_wolfssl steps: - name: Download lib - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: wolf-install-nginx path: build-dir @@ -109,13 +109,13 @@ jobs: sudo cpan -iT Proc::Find Net::SSLeay IO::Socket::SSL - name: Checkout wolfssl-nginx - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: wolfssl/wolfssl-nginx path: wolfssl-nginx - name: Checkout nginx - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: nginx/nginx path: nginx @@ -131,7 +131,7 @@ jobs: run: patch -p1 < ../wolfssl-nginx/nginx-${{ matrix.ref }}-wolfssl-debug.patch - name: Checkout nginx-tests - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: nginx/nginx-tests path: nginx-tests diff --git a/.github/workflows/openvpn.yml b/.github/workflows/openvpn.yml index 10f206ff6f..f29acd61cb 100644 --- a/.github/workflows/openvpn.yml +++ b/.github/workflows/openvpn.yml @@ -19,7 +19,7 @@ jobs: install: true - name: Upload built lib - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: wolf-install-openvpn path: build-dir @@ -38,7 +38,7 @@ jobs: needs: build_wolfssl steps: - name: Download lib - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: wolf-install-openvpn path: build-dir diff --git a/.github/workflows/os-check.yml b/.github/workflows/os-check.yml index 08134c4a21..579e471fe6 100644 --- a/.github/workflows/os-check.yml +++ b/.github/workflows/os-check.yml @@ -94,7 +94,7 @@ jobs: # This should be a safe limit for the tests to run. timeout-minutes: 14 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - if: ${{ matrix.os == 'macos-latest' }} run: brew install automake libtool - run: ./autogen.sh @@ -121,10 +121,10 @@ jobs: BUILD_CONFIGURATION: Release BUILD_PLATFORM: x64 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Add MSBuild to PATH - uses: microsoft/setup-msbuild@v1 + uses: microsoft/setup-msbuild@v2 - name: Restore NuGet packages working-directory: ${{env.GITHUB_WORKSPACE}} diff --git a/.github/workflows/packaging.yml b/.github/workflows/packaging.yml index 42e213593f..50f2a0863b 100644 --- a/.github/workflows/packaging.yml +++ b/.github/workflows/packaging.yml @@ -11,7 +11,7 @@ jobs: timeout-minutes: 10 steps: - name: Checkout wolfSSL - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Configure wolfSSL run: | diff --git a/.github/workflows/stunnel.yml b/.github/workflows/stunnel.yml index ac25126d56..5e51433bca 100644 --- a/.github/workflows/stunnel.yml +++ b/.github/workflows/stunnel.yml @@ -19,7 +19,7 @@ jobs: install: true - name: Upload built lib - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: wolf-install-stunnel path: build-dir @@ -38,13 +38,13 @@ jobs: needs: build_wolfssl steps: - name: Download lib - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: wolf-install-stunnel path: build-dir - name: Checkout OSP - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: wolfssl/osp path: osp diff --git a/.github/workflows/zephyr.yml b/.github/workflows/zephyr.yml index baad958afd..c7f1bc8ee3 100644 --- a/.github/workflows/zephyr.yml +++ b/.github/workflows/zephyr.yml @@ -97,7 +97,7 @@ jobs: - name: Upload failure logs if: ${{ failure() && (steps.wolfssl-test.outcome == 'failure' || steps.wolfssl-tls-sock.outcome == 'failure' || steps.wolfssl-tls-thread.outcome == 'failure') }} - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: zephyr-client-test-logs path: logs.zip From 7592559fd31735189808d5f19cc4ac19050db001 Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Fri, 2 Feb 2024 14:50:50 -0700 Subject: [PATCH 53/63] rename argument, fix warnings on casts --- wolfcrypt/src/asn.c | 25 +++++++++++++------------ wolfssl/wolfcrypt/asn.h | 6 +++--- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index f29c990e67..b38ee124da 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -3465,20 +3465,21 @@ word32 SetBitString(word32 len, byte unusedBits, byte* output) /* sets the terminating 0x00 0x00 at the end of an indefinite length * returns the number of bytes written */ -word32 SetIndefEnd(byte* in) +word32 SetIndefEnd(byte* output) { - byte terminate[] = { 0x00, 0x00 }; + byte terminate[ASN_INDEF_END_SZ] = { 0x00, 0x00 }; - if (in != NULL) { - XMEMCPY(in, terminate, 2); + if (output != NULL) { + XMEMCPY(output, terminate, ASN_INDEF_END_SZ); } - return 2; + + return (word32)ASN_INDEF_END_SZ; } /* Breaks an octet string up into chunks for use with streaming * returns 0 on success and updates idx */ -int StreamOctetString(const byte* in, word32 inSz, byte* out, word32* outSz, +int StreamOctetString(const byte* inBuf, word32 inBufSz, byte* out, word32* outSz, word32* idx) { word32 i = 0; @@ -3487,13 +3488,13 @@ int StreamOctetString(const byte* in, word32 inSz, byte* out, word32* outSz, if (tmp) tmp += outIdx; - while (i < inSz) { - int ret, sz; + while (i < inBufSz) { + word32 ret, sz; sz = BER_OCTET_LENGTH; - if ((sz + i) > inSz) { - sz = inSz - i; + if ((sz + i) > inBufSz) { + sz = inBufSz - i; } ret = SetOctetString(sz, tmp); @@ -3502,10 +3503,10 @@ int StreamOctetString(const byte* in, word32 inSz, byte* out, word32* outSz, } if (tmp) { - if (ret + sz + i + outIdx > *outSz) { + if ((word32)ret + sz + i + outIdx > *outSz) { return BUFFER_E; } - XMEMCPY(tmp + ret, in + i, sz); + XMEMCPY(tmp + ret, inBuf + i, sz); tmp += sz + ret; } outIdx += sz; diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 78a0571314..395981407e 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -2101,8 +2101,8 @@ WOLFSSL_LOCAL int GetName(DecodedCert* cert, int nameType, int maxIdx); WOLFSSL_ASN_API int wc_BerToDer(const byte* ber, word32 berSz, byte* der, word32* derSz); -WOLFSSL_LOCAL int StreamOctetString(const byte* in, word32 inSz, byte* out, word32* outSz, - word32* idx); +WOLFSSL_LOCAL int StreamOctetString(const byte* inBuf, word32 inBufSz, + byte* out, word32* outSz, word32* idx); WOLFSSL_ASN_API void FreeAltNames(DNS_entry* altNames, void* heap); WOLFSSL_ASN_API DNS_entry* AltNameNew(void* heap); @@ -2280,7 +2280,7 @@ WOLFSSL_LOCAL word32 SetLength(word32 length, byte* output); WOLFSSL_LOCAL word32 SetLengthEx(word32 length, byte* output, byte isIndef); WOLFSSL_LOCAL word32 SetSequence(word32 len, byte* output); WOLFSSL_LOCAL word32 SetSequenceEx(word32 len, byte* output, byte isIndef); -WOLFSSL_LOCAL word32 SetIndefEnd(byte* in); +WOLFSSL_LOCAL word32 SetIndefEnd(byte* output); WOLFSSL_LOCAL word32 SetOctetString(word32 len, byte* output); WOLFSSL_LOCAL word32 SetOctetStringEx(word32 len, byte* output, byte indef); WOLFSSL_LOCAL int SetASNInt(int len, byte firstByte, byte* output); From 13e427433c0abcf5d45029817c001b31ce3e99d5 Mon Sep 17 00:00:00 2001 From: jordan Date: Fri, 2 Feb 2024 16:04:23 -0600 Subject: [PATCH 54/63] Fix ext_xmss sigsleft null deref. --- wolfcrypt/src/ext_xmss.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wolfcrypt/src/ext_xmss.c b/wolfcrypt/src/ext_xmss.c index c08db07239..84498d9a37 100644 --- a/wolfcrypt/src/ext_xmss.c +++ b/wolfcrypt/src/ext_xmss.c @@ -804,10 +804,10 @@ int wc_XmssKey_SigsLeft(XmssKey* key) } ret = idx < ((1ULL << params->full_height) - 1); - } - /* Force zero the secret key from memory always. */ - ForceZero(key->sk, key->sk_len); + /* Force zero the secret key from memory always. */ + ForceZero(key->sk, key->sk_len); + } return ret; } From d111d7da1bf080fbfe2f5e29ef6aa4c538f8d0d8 Mon Sep 17 00:00:00 2001 From: jordan Date: Fri, 2 Feb 2024 19:50:22 -0600 Subject: [PATCH 55/63] Fix MD5 and SHA buffer overrun. --- wolfcrypt/src/md5.c | 4 +++- wolfcrypt/src/sha256.c | 7 +++++-- wolfcrypt/src/sha512.c | 6 +++++- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/wolfcrypt/src/md5.c b/wolfcrypt/src/md5.c index 1f61302646..6700fdc946 100644 --- a/wolfcrypt/src/md5.c +++ b/wolfcrypt/src/md5.c @@ -461,7 +461,9 @@ int wc_Md5Final(wc_Md5* md5, byte* hash) /* pad with zeros */ if (md5->buffLen > WC_MD5_PAD_SIZE) { - XMEMSET(&local[md5->buffLen], 0, WC_MD5_BLOCK_SIZE - md5->buffLen); + if (md5->buffLen < WC_MD5_BLOCK_SIZE) { + XMEMSET(&local[md5->buffLen], 0, WC_MD5_BLOCK_SIZE - md5->buffLen); + } md5->buffLen += WC_MD5_BLOCK_SIZE - md5->buffLen; #if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA) diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index bbaad7fab0..e4e1ddf933 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -1321,8 +1321,11 @@ static int InitSha256(wc_Sha256* sha256) /* pad with zeros */ if (sha256->buffLen > WC_SHA256_PAD_SIZE) { - XMEMSET(&local[sha256->buffLen], 0, - WC_SHA256_BLOCK_SIZE - sha256->buffLen); + if (sha256->buffLen < WC_SHA256_BLOCK_SIZE) { + XMEMSET(&local[sha256->buffLen], 0, + WC_SHA256_BLOCK_SIZE - sha256->buffLen); + } + sha256->buffLen += WC_SHA256_BLOCK_SIZE - sha256->buffLen; #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \ diff --git a/wolfcrypt/src/sha512.c b/wolfcrypt/src/sha512.c index 263971729d..3cc2d5f437 100644 --- a/wolfcrypt/src/sha512.c +++ b/wolfcrypt/src/sha512.c @@ -942,7 +942,11 @@ static WC_INLINE int Sha512Final(wc_Sha512* sha512) /* pad with zeros */ if (sha512->buffLen > WC_SHA512_PAD_SIZE) { - XMEMSET(&local[sha512->buffLen], 0, WC_SHA512_BLOCK_SIZE - sha512->buffLen); + if (sha512->buffLen < WC_SHA512_BLOCK_SIZE ) { + XMEMSET(&local[sha512->buffLen], 0, + WC_SHA512_BLOCK_SIZE - sha512->buffLen); + } + sha512->buffLen += WC_SHA512_BLOCK_SIZE - sha512->buffLen; #if defined(LITTLE_ENDIAN_ORDER) #if defined(USE_INTEL_SPEEDUP) && \ From ca726e97f8fd4cc61fd304719c3f99ec10c344c8 Mon Sep 17 00:00:00 2001 From: David Garske Date: Sat, 3 Feb 2024 10:43:46 -0800 Subject: [PATCH 56/63] Peer review fixes. --- examples/configs/user_settings_tls12.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/examples/configs/user_settings_tls12.h b/examples/configs/user_settings_tls12.h index c4a1fa31f8..c8ec7fce80 100644 --- a/examples/configs/user_settings_tls12.h +++ b/examples/configs/user_settings_tls12.h @@ -21,8 +21,13 @@ /* Example for TLS v1.2 client only, ECC only, AES GCM only, SHA2-256 only */ /* Derived using: - * ./configure --disable-rsa --disable-dh --disable-tls13 --disable-chacha --disable-poly1305 --disable-sha224 --disable-sha --disable-md5 - * And generated wolfssl/options.h + * ./configure --disable-rsa --disable-dh --disable-tls13 --disable-chacha \ + * --disable-poly1305 --disable-sha224 --disable-sha --disable-md5 + * From generated wolfssl/options.h + * Build and Test using: + * ./configure --enable-usersettings --disable-examples + * make + * ./wolfcrypt/test/testwolfcrypt */ #ifndef WOLFSSL_USER_SETTINGS_H @@ -35,7 +40,8 @@ extern "C" { /* ------------------------------------------------------------------------- */ /* Platform */ /* ------------------------------------------------------------------------- */ -#define WOLFSSL_USER_IO /* Use the SetIO callbacks, not the internal wolfio.c socket code */ +/* Use the SetIO callbacks, not the internal wolfio.c socket code */ +#define WOLFSSL_USER_IO #define WOLFSSL_IGNORE_FILE_WARN /* ignore file includes not required */ //#define WOLFSSL_SMALL_STACK /* option to reduce stack size, offload to heap */ #define NO_FILESYSTEM From 3a280e829582b408d452f627a0da23a3bbe24243 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Sat, 3 Feb 2024 13:46:45 -0600 Subject: [PATCH 57/63] linuxkm fixes: linuxkm/linuxkm_wc_port.h: add fallback definition for static_assert() to support legacy kernels. wolfcrypt/src/aes.c: fix AESNI runtime failure/fallback logic in wc_AesXtsSetKeyNoInit(). --- linuxkm/linuxkm_wc_port.h | 11 ++++++++--- wolfcrypt/src/aes.c | 39 +++++++++++++++++++++------------------ 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/linuxkm/linuxkm_wc_port.h b/linuxkm/linuxkm_wc_port.h index 6048589cb8..2580e406d3 100644 --- a/linuxkm/linuxkm_wc_port.h +++ b/linuxkm/linuxkm_wc_port.h @@ -292,7 +292,7 @@ * AES_ENCRYPTION_AND_DECRYPTION on AES-XTS. */ #ifndef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS - #define WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS + #define WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS #endif #endif @@ -822,6 +822,11 @@ #define realloc(ptr, newsize) krealloc(ptr, WC_LINUXKM_ROUND_UP_P_OF_2(newsize), GFP_KERNEL) #endif + #ifndef static_assert + #define static_assert(expr, ...) __static_assert(expr, ##__VA_ARGS__, #expr) + #define __static_assert(expr, msg, ...) _Static_assert(expr, msg) + #endif + #include #ifdef WOLFSSL_TRACK_MEMORY @@ -848,7 +853,7 @@ * them to be evaluable by the preprocessor, for use in sp_int.h. */ #if BITS_PER_LONG == 64 - _Static_assert(sizeof(ULONG_MAX) == 8, + static_assert(sizeof(ULONG_MAX) == 8, "BITS_PER_LONG is 64, but ULONG_MAX is not."); #undef UCHAR_MAX @@ -870,7 +875,7 @@ #elif BITS_PER_LONG == 32 - _Static_assert(sizeof(ULONG_MAX) == 4, + static_assert(sizeof(ULONG_MAX) == 4, "BITS_PER_LONG is 32, but ULONG_MAX is not."); #undef UCHAR_MAX diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 510e395dd7..b18350c9d6 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -12356,32 +12356,35 @@ int wc_AesXtsSetKeyNoInit(XtsAes* aes, const byte* key, word32 len, int dir) * conflicting _aesni status, but the AES-XTS asm implementations need * them to all be AESNI. If any aren't, disable AESNI on all. */ - if ((((dir == AES_ENCRYPTION) -#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS - || (dir == AES_ENCRYPTION_AND_DECRYPTION) -#endif - ) && - (aes->aes.use_aesni != aes->tweak.use_aesni)) -#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS + #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS + if ((((dir == AES_ENCRYPTION) || + (dir == AES_ENCRYPTION_AND_DECRYPTION)) + && (aes->aes.use_aesni != aes->tweak.use_aesni)) || - (((dir == AES_DECRYPTION) - || (dir == AES_ENCRYPTION_AND_DECRYPTION)) && - (aes->aes_decrypt.use_aesni != aes->tweak.use_aesni)) -#endif - ) + (((dir == AES_DECRYPTION) || + (dir == AES_ENCRYPTION_AND_DECRYPTION)) + && (aes->aes_decrypt.use_aesni != aes->tweak.use_aesni))) { -#ifdef WC_AES_C_DYNAMIC_FALLBACK + #ifdef WC_AES_C_DYNAMIC_FALLBACK aes->aes.use_aesni = 0; -#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS aes->aes_decrypt.use_aesni = 0; -#endif aes->tweak.use_aesni = 0; -#else + #else ret = SYSLIB_FAILED_E; -#endif + #endif } + #else /* !WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS */ + if (aes->aes.use_aesni != aes->tweak.use_aesni) { + #ifdef WC_AES_C_DYNAMIC_FALLBACK + aes->aes.use_aesni = 0; + aes->tweak.use_aesni = 0; + #else + ret = SYSLIB_FAILED_E; + #endif + } + #endif /* !WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS */ } -#endif +#endif /* WOLFSSL_AESNI */ return ret; } From 83169f91e9f0db88633ac1d1cfb60d1b71c0c68e Mon Sep 17 00:00:00 2001 From: jordan Date: Sat, 3 Feb 2024 17:36:26 -0600 Subject: [PATCH 58/63] Fix ShaFinal overrun. --- wolfcrypt/src/sha.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/wolfcrypt/src/sha.c b/wolfcrypt/src/sha.c index 1f4439f0fe..69990791fd 100644 --- a/wolfcrypt/src/sha.c +++ b/wolfcrypt/src/sha.c @@ -841,7 +841,10 @@ int wc_ShaFinal(wc_Sha* sha, byte* hash) /* pad with zeros */ if (sha->buffLen > WC_SHA_PAD_SIZE) { - XMEMSET(&local[sha->buffLen], 0, WC_SHA_BLOCK_SIZE - sha->buffLen); + if (sha->buffLen < WC_SHA_BLOCK_SIZE) { + XMEMSET(&local[sha->buffLen], 0, WC_SHA_BLOCK_SIZE - sha->buffLen); + } + sha->buffLen += WC_SHA_BLOCK_SIZE - sha->buffLen; #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) From 9ea52c3a51d8cfc565007ec7bc740450017344db Mon Sep 17 00:00:00 2001 From: jordan Date: Mon, 5 Feb 2024 15:01:07 -0600 Subject: [PATCH 59/63] Update IAR-EWARM project user-settings.h. --- IDE/IAR-EWARM/Projects/user_settings.h | 52 +++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/IDE/IAR-EWARM/Projects/user_settings.h b/IDE/IAR-EWARM/Projects/user_settings.h index 289a4d7187..c6274a29df 100644 --- a/IDE/IAR-EWARM/Projects/user_settings.h +++ b/IDE/IAR-EWARM/Projects/user_settings.h @@ -1,4 +1,3 @@ - #define NO_MAIN_DRIVER #define BENCH_EMBEDDED #define NO_WRITEV @@ -17,10 +16,59 @@ #define WOLFSSL_GENSEED_FORTEST /* Warning: define your own seed gen */ -#define TFM_TIMING_RESISTANT +/* A few examples of different math options below. + * + * See examples/configs/user_settings_template.h for a more + * detailed template. */ +#if 1 + /* Use only single precision (SP) math and algorithms. + * SP math is written to accelerate specific/common key + * sizes and curves. This adds code from sp_c32.c, or one of the specific + * assembly implementations like sp_cortexm.c. This code is faster than the + * multi-precision support because it's optimized for the key/curve. + * The SP math can be used together with any multi-precision math library + * if WOLFSSL_SP_MATH is removed. If only standard keys/curves are being + * used the multi-precision math is not required. + */ + #define WOLFSSL_SP_MATH + /* Enable SP ECC support */ + #define WOLFSSL_HAVE_SP_ECC + /* Enable SP RSA support */ + #define WOLFSSL_HAVE_SP_RSA + /* Enable SP DH support */ + #define WOLFSSL_HAVE_SP_DH + /* Reduce stack use specifically in SP implementation. */ + #define WOLFSSL_SP_SMALL_STACK + /* use smaller version of code */ + #define WOLFSSL_SP_SMALL + /* Assembly optimized version - sp_cortexm.c */ + //#define WOLFSSL_SP_ARM_CORTEX_M_ASM +#elif 1 + /* Use SP math for all key sizes and curves. This will use + * the multi-precision (MP) math implementation in sp_int.c */ + #define WOLFSSL_SP_MATH_ALL + /* Disable use of dynamic stack items */ + #define WOLFSSL_SP_NO_DYN_STACK + /* use smaller version of code */ + #define WOLFSSL_SP_SMALL +#elif 1 + /* Fast Math (tfm.c) (stack based and timing resistant) */ + #define USE_FAST_MATH + /* Enable Fast Math Timing Resistance */ + #define TFM_TIMING_RESISTANT +#else + /* Normal (integer.c) (heap based, not timing resistant) - not recommended*/ + #define USE_INTEGER_HEAP_MATH +#endif + +/* Enable ECC Timing Resistance */ #define ECC_TIMING_RESISTANT +/* Enables blinding mode, to prevent timing attacks */ #define WC_RSA_BLINDING +/* reduce stack use. For variables over 100 bytes allocate from heap */ +#define WOLFSSL_SMALL_STACK +/* disable mutex locking */ #define SINGLE_THREADED /* or define RTOS option */ /* #define WOLFSSL_CMSIS_RTOS */ #define NO_FILESYSTEM From d36bd47a2708be818a23ec8e967916833e147f19 Mon Sep 17 00:00:00 2001 From: Lealem Amedie Date: Mon, 5 Feb 2024 15:09:05 -0700 Subject: [PATCH 60/63] For cppcheck: Explicitly initialize some variables --- wolfcrypt/src/asn.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 40ab403006..e5d5df1727 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -3018,7 +3018,7 @@ int GetMyVersion(const byte* input, word32* inOutIdx, #else ASNGetData dataASN[intASN_Length]; int ret; - byte num; + byte num = 0; /* Clear dynamic data and set the version number variable. */ XMEMSET(dataASN, 0, sizeof(dataASN)); @@ -3085,7 +3085,7 @@ int GetShortInt(const byte* input, word32* inOutIdx, int* number, word32 maxIdx) #else ASNGetData dataASN[intASN_Length]; int ret; - word32 num; + word32 num = 0; /* Clear dynamic data and set the 32-bit number variable. */ XMEMSET(dataASN, 0, sizeof(dataASN)); @@ -6767,7 +6767,7 @@ int ToTraditionalInline_ex(const byte* input, word32* inOutIdx, word32 sz, DECL_ASNGETDATA(dataASN, pkcs8KeyASN_Length); int ret = 0; word32 oid = 9; - byte version; + byte version = 0; word32 idx; /* Check validity of parameters. */ @@ -8685,7 +8685,7 @@ int DecryptContent(byte* input, word32 sz, const char* password, int passwordSz) int version; word32 idx = 0; word32 pIdx = 0; - word32 iterations; + word32 iterations = 0; word32 keySz = 0; word32 saltSz = 0; word32 shaOid = 0; @@ -33081,7 +33081,7 @@ int wc_EccPrivateKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key, return ret; #else DECL_ASNGETDATA(dataASN, eccKeyASN_Length); - byte version; + byte version = 0; int ret = 0; int curve_id = ECC_CURVE_DEF; #if defined(HAVE_PKCS8) || defined(HAVE_PKCS12) || defined(SM2) @@ -36113,7 +36113,7 @@ int OcspResponseDecode(OcspResponse* resp, void* cm, void* heap, int noVerify) int ret = 0; word32 idx = 0, size = resp->maxIdx; byte* source = resp->source; - byte status; + byte status = 0; byte* basic; word32 basicSz; From c69442375b2da4054f0839966a16b33b1611ceeb Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Tue, 6 Feb 2024 12:08:57 -0600 Subject: [PATCH 61/63] CMakeLists.txt: include the install rule by default, disabled with -DWOLFSSL_INSTALL=no, to restore status quo ante. see #7188 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 74df3f226a..a71ece1226 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -215,7 +215,7 @@ if(WOLFSSL_REPRODUCIBLE_BUILD) set(CMAKE_C_ARCHIVE_FINISH " -D ") endif() -add_option("WOLFSSL_INSTALL" "Create install target for WolfSSL project" "no" "yes;no") +add_option("WOLFSSL_INSTALL" "Create install target for WolfSSL project" "yes" "yes;no") # Support for forcing 32-bit mode # TODO: detect platform from other options From 10b5c375ef2710c73a170cf6054235ecc60630f8 Mon Sep 17 00:00:00 2001 From: gojimmypi Date: Tue, 6 Feb 2024 14:07:50 -0800 Subject: [PATCH 62/63] introduce MICRO_SESSION_CACHE, update comments --- src/ssl.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index b4cac31053..d07d08f6a2 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -6002,10 +6002,15 @@ int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify) aren't under heavy load, basically allows 200 new sessions per minute SMALL_SESSION_CACHE only stores 6 sessions, good for embedded clients - or systems where the default of nearly 3kB is too much RAM, this define - uses less than 500 bytes RAM + or systems where the default of is too much RAM. + SessionCache takes about 2K, ClientCache takes about 3Kbytes + + MICRO_SESSION_CACHE only stores 1 session, good for embedded clients + or systems where memory is at a premium. + SessionCache takes about 400 bytes, ClientCache takes 576 bytes default SESSION_CACHE stores 33 sessions (no XXX_SESSION_CACHE defined) + SessionCache takes about 13K bytes, ClientCache takes 17K bytes */ #if defined(TITAN_SESSION_CACHE) #define SESSIONS_PER_ROW 31 @@ -6025,6 +6030,9 @@ int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify) #elif defined(SMALL_SESSION_CACHE) #define SESSIONS_PER_ROW 2 #define SESSION_ROWS 3 + #elif defined(MICRO_SESSION_CACHE) + #define SESSIONS_PER_ROW 1 + #define SESSION_ROWS 1 #else #define SESSIONS_PER_ROW 3 #define SESSION_ROWS 11 From fff4effe31c789eae349a0410272a5879512ddf3 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Wed, 7 Feb 2024 10:24:54 +1000 Subject: [PATCH 63/63] Thumbs inline ASM IAR: fix register clobber list Change register clobber list so that it reserves the same registers for constants regardless of WOLFSSL_NO_VAR_ASSIGN_REG. --- wolfcrypt/src/port/arm/thumb2-aes-asm_c.c | 69 +++++++++++++++----- wolfcrypt/src/port/arm/thumb2-sha256-asm_c.c | 3 +- wolfcrypt/src/port/arm/thumb2-sha512-asm_c.c | 3 +- 3 files changed, 58 insertions(+), 17 deletions(-) diff --git a/wolfcrypt/src/port/arm/thumb2-aes-asm_c.c b/wolfcrypt/src/port/arm/thumb2-aes-asm_c.c index 0574f0562c..9699ac29c2 100644 --- a/wolfcrypt/src/port/arm/thumb2-aes-asm_c.c +++ b/wolfcrypt/src/port/arm/thumb2-aes-asm_c.c @@ -310,11 +310,12 @@ void AES_invert_key(unsigned char* ks, word32 rounds) : [ks] "+r" (ks), [rounds] "+r" (rounds), [L_AES_Thumb2_te] "+r" (L_AES_Thumb2_te_c), [L_AES_Thumb2_td] "+r" (L_AES_Thumb2_td_c) : + : "memory", "r12", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "cc" #else : [ks] "+r" (ks), [rounds] "+r" (rounds) : [L_AES_Thumb2_te] "r" (L_AES_Thumb2_te), [L_AES_Thumb2_td] "r" (L_AES_Thumb2_td) -#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "r12", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "cc" +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ ); } @@ -558,11 +559,12 @@ void AES_set_encrypt_key(const unsigned char* key, word32 len, unsigned char* ks : [key] "+r" (key), [len] "+r" (len), [ks] "+r" (ks), [L_AES_Thumb2_te] "+r" (L_AES_Thumb2_te_c), [L_AES_Thumb2_rcon] "+r" (L_AES_Thumb2_rcon_c) : + : "memory", "r12", "lr", "r5", "r6", "r7", "r8", "r9", "r10", "cc" #else : [key] "+r" (key), [len] "+r" (len), [ks] "+r" (ks) : [L_AES_Thumb2_te] "r" (L_AES_Thumb2_te), [L_AES_Thumb2_rcon] "r" (L_AES_Thumb2_rcon) -#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "r12", "lr", "r5", "r6", "r7", "r8", "r9", "r10", "cc" +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ ); } @@ -969,12 +971,16 @@ void AES_ECB_encrypt(const unsigned char* in, unsigned char* out, unsigned long : [in] "+r" (in), [out] "+r" (out), [len] "+r" (len), [ks] "+r" (ks), [nr] "+r" (nr), [L_AES_Thumb2_te_ecb] "+r" (L_AES_Thumb2_te_ecb_c) : + : "memory", "r12", "lr", "r6", "r7", "r8", "r9", "r10", "r11", "cc" #else - : [in] "+r" (in), [out] "+r" (out), [len] "+r" (len), [ks] "+r" (ks), [nr] "+r" (nr) + : [in] "+r" (in), [out] "+r" (out), [len] "+r" (len), [ks] "+r" (ks) : [L_AES_Thumb2_te_ecb] "r" (L_AES_Thumb2_te_ecb) + : "memory", "r12", "lr", "r4", "r6", "r7", "r8", "r9", "r10", "r11", "cc" #endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ - : "memory", "r12", "lr", "r6", "r7", "r8", "r9", "r10", "r11", "cc" ); +#ifdef WOLFSSL_NO_VAR_ASSIGN_REG + (void)nr; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ } #endif /* HAVE_AESCCM || HAVE_AESGCM || WOLFSSL_AES_DIRECT || WOLFSSL_AES_COUNTER */ @@ -1169,12 +1175,19 @@ void AES_CBC_encrypt(const unsigned char* in, unsigned char* out, unsigned long : [in] "+r" (in), [out] "+r" (out), [len] "+r" (len), [ks] "+r" (ks), [nr] "+r" (nr), [iv] "+r" (iv), [L_AES_Thumb2_te_ecb] "+r" (L_AES_Thumb2_te_ecb_c) : + : "memory", "r12", "lr", "r7", "r8", "r9", "r10", "r11", "cc" #else - : [in] "+r" (in), [out] "+r" (out), [len] "+r" (len), [ks] "+r" (ks), [nr] "+r" (nr), [iv] "+r" (iv) + : [in] "+r" (in), [out] "+r" (out), [len] "+r" (len), [ks] "+r" (ks) : [L_AES_Thumb2_te_ecb] "r" (L_AES_Thumb2_te_ecb) + : "memory", "r12", "lr", "r4", "r5", "r7", "r8", "r9", "r10", "r11", "cc" #endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ - : "memory", "r12", "lr", "r7", "r8", "r9", "r10", "r11", "cc" ); +#ifdef WOLFSSL_NO_VAR_ASSIGN_REG + (void)nr; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ +#ifdef WOLFSSL_NO_VAR_ASSIGN_REG + (void)iv; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ } #endif /* HAVE_AES_CBC */ @@ -1390,12 +1403,19 @@ void AES_CTR_encrypt(const unsigned char* in, unsigned char* out, unsigned long : [in] "+r" (in), [out] "+r" (out), [len] "+r" (len), [ks] "+r" (ks), [nr] "+r" (nr), [ctr] "+r" (ctr), [L_AES_Thumb2_te_ecb] "+r" (L_AES_Thumb2_te_ecb_c) : + : "memory", "r12", "lr", "r7", "r8", "r9", "r10", "r11", "cc" #else - : [in] "+r" (in), [out] "+r" (out), [len] "+r" (len), [ks] "+r" (ks), [nr] "+r" (nr), [ctr] "+r" (ctr) + : [in] "+r" (in), [out] "+r" (out), [len] "+r" (len), [ks] "+r" (ks) : [L_AES_Thumb2_te_ecb] "r" (L_AES_Thumb2_te_ecb) + : "memory", "r12", "lr", "r4", "r5", "r7", "r8", "r9", "r10", "r11", "cc" #endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ - : "memory", "r12", "lr", "r7", "r8", "r9", "r10", "r11", "cc" ); +#ifdef WOLFSSL_NO_VAR_ASSIGN_REG + (void)nr; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ +#ifdef WOLFSSL_NO_VAR_ASSIGN_REG + (void)ctr; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ } #endif /* WOLFSSL_AES_COUNTER */ @@ -1834,12 +1854,16 @@ void AES_ECB_decrypt(const unsigned char* in, unsigned char* out, unsigned long : [in] "+r" (in), [out] "+r" (out), [len] "+r" (len), [ks] "+r" (ks), [nr] "+r" (nr), [L_AES_Thumb2_td_ecb] "+r" (L_AES_Thumb2_td_ecb_c), [L_AES_Thumb2_td4] "+r" (L_AES_Thumb2_td4_c) : + : "memory", "r12", "lr", "r7", "r8", "r9", "r10", "r11", "cc" #else - : [in] "+r" (in), [out] "+r" (out), [len] "+r" (len), [ks] "+r" (ks), [nr] "+r" (nr) + : [in] "+r" (in), [out] "+r" (out), [len] "+r" (len), [ks] "+r" (ks) : [L_AES_Thumb2_td_ecb] "r" (L_AES_Thumb2_td_ecb), [L_AES_Thumb2_td4] "r" (L_AES_Thumb2_td4) + : "memory", "r12", "lr", "r4", "r7", "r8", "r9", "r10", "r11", "cc" #endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ - : "memory", "r12", "lr", "r7", "r8", "r9", "r10", "r11", "cc" ); +#ifdef WOLFSSL_NO_VAR_ASSIGN_REG + (void)nr; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ } #endif /* WOLFSSL_AES_DIRECT || WOLFSSL_AES_COUNTER */ @@ -2193,12 +2217,19 @@ void AES_CBC_decrypt(const unsigned char* in, unsigned char* out, unsigned long : [in] "+r" (in), [out] "+r" (out), [len] "+r" (len), [ks] "+r" (ks), [nr] "+r" (nr), [iv] "+r" (iv), [L_AES_Thumb2_td_ecb] "+r" (L_AES_Thumb2_td_ecb_c), [L_AES_Thumb2_td4] "+r" (L_AES_Thumb2_td4_c) : + : "memory", "r12", "lr", "r8", "r9", "r10", "r11", "cc" #else - : [in] "+r" (in), [out] "+r" (out), [len] "+r" (len), [ks] "+r" (ks), [nr] "+r" (nr), [iv] "+r" (iv) + : [in] "+r" (in), [out] "+r" (out), [len] "+r" (len), [ks] "+r" (ks) : [L_AES_Thumb2_td_ecb] "r" (L_AES_Thumb2_td_ecb), [L_AES_Thumb2_td4] "r" (L_AES_Thumb2_td4) + : "memory", "r12", "lr", "r4", "r5", "r8", "r9", "r10", "r11", "cc" #endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ - : "memory", "r12", "lr", "r8", "r9", "r10", "r11", "cc" ); +#ifdef WOLFSSL_NO_VAR_ASSIGN_REG + (void)nr; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ +#ifdef WOLFSSL_NO_VAR_ASSIGN_REG + (void)iv; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ } #endif /* HAVE_AES_CBC */ @@ -2785,11 +2816,12 @@ void GCM_gmult_len(unsigned char* x, const unsigned char** m, const unsigned cha : [x] "+r" (x), [m] "+r" (m), [data] "+r" (data), [len] "+r" (len), [L_GCM_gmult_len_r] "+r" (L_GCM_gmult_len_r_c) : + : "memory", "r12", "lr", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "cc" #else : [x] "+r" (x), [m] "+r" (m), [data] "+r" (data), [len] "+r" (len) : [L_GCM_gmult_len_r] "r" (L_GCM_gmult_len_r) -#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "r12", "lr", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "cc" +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ ); } @@ -2996,12 +3028,19 @@ void AES_GCM_encrypt(const unsigned char* in, unsigned char* out, unsigned long : [in] "+r" (in), [out] "+r" (out), [len] "+r" (len), [ks] "+r" (ks), [nr] "+r" (nr), [ctr] "+r" (ctr), [L_AES_Thumb2_te_gcm] "+r" (L_AES_Thumb2_te_gcm_c) : + : "memory", "r12", "lr", "r7", "r8", "r9", "r10", "r11", "cc" #else - : [in] "+r" (in), [out] "+r" (out), [len] "+r" (len), [ks] "+r" (ks), [nr] "+r" (nr), [ctr] "+r" (ctr) + : [in] "+r" (in), [out] "+r" (out), [len] "+r" (len), [ks] "+r" (ks) : [L_AES_Thumb2_te_gcm] "r" (L_AES_Thumb2_te_gcm) + : "memory", "r12", "lr", "r4", "r5", "r7", "r8", "r9", "r10", "r11", "cc" #endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ - : "memory", "r12", "lr", "r7", "r8", "r9", "r10", "r11", "cc" ); +#ifdef WOLFSSL_NO_VAR_ASSIGN_REG + (void)nr; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ +#ifdef WOLFSSL_NO_VAR_ASSIGN_REG + (void)ctr; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ } #endif /* HAVE_AESGCM */ diff --git a/wolfcrypt/src/port/arm/thumb2-sha256-asm_c.c b/wolfcrypt/src/port/arm/thumb2-sha256-asm_c.c index 704fb8599b..93f8078ad5 100644 --- a/wolfcrypt/src/port/arm/thumb2-sha256-asm_c.c +++ b/wolfcrypt/src/port/arm/thumb2-sha256-asm_c.c @@ -1459,11 +1459,12 @@ void Transform_Sha256_Len(wc_Sha256* sha256, const byte* data, word32 len) : [sha256] "+r" (sha256), [data] "+r" (data), [len] "+r" (len), [L_SHA256_transform_len_k] "+r" (L_SHA256_transform_len_k_c) : + : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "cc" #else : [sha256] "+r" (sha256), [data] "+r" (data), [len] "+r" (len) : [L_SHA256_transform_len_k] "r" (L_SHA256_transform_len_k) -#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "cc" +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ ); } diff --git a/wolfcrypt/src/port/arm/thumb2-sha512-asm_c.c b/wolfcrypt/src/port/arm/thumb2-sha512-asm_c.c index d7fbd83e37..ab154ada0a 100644 --- a/wolfcrypt/src/port/arm/thumb2-sha512-asm_c.c +++ b/wolfcrypt/src/port/arm/thumb2-sha512-asm_c.c @@ -3574,11 +3574,12 @@ void Transform_Sha512_Len(wc_Sha512* sha512, const byte* data, word32 len) : [sha512] "+r" (sha512), [data] "+r" (data), [len] "+r" (len), [L_SHA512_transform_len_k] "+r" (L_SHA512_transform_len_k_c) : + : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "cc" #else : [sha512] "+r" (sha512), [data] "+r" (data), [len] "+r" (len) : [L_SHA512_transform_len_k] "r" (L_SHA512_transform_len_k) -#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "cc" +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ ); }