From 54f2d56300a9a265a2458e201b39a3ca7e3dda5d Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Tue, 31 Oct 2023 10:03:21 +1000 Subject: [PATCH] ssl.c: Move out crypto compat APIs ssl_crypto.c contains OpenSSL compatibility APIS for: - MD4, MD5, SHA/SHA-1, SHA2, SHA3 - HMAC, CMAC - DES, DES3, AES, RC4 API implementations reworked. Tests added for coverage. TODOs for future enhancements. --- IDE/Espressif/ESP-IDF/UPDATE.md | 1 + .../components/wolfssl/CMakeLists.txt | 3 +- .../components/wolfssl/CMakeLists.txt | 1 + .../components/wolfssl/CMakeLists.txt | 1 + .../components/wolfssl/CMakeLists.txt | 1 + .../components/wolfssl/CMakeLists.txt | 1 + IDE/Espressif/ESP-IDF/libs/CMakeLists.txt | 6 +- .../wolfssl_new_azsphere/CMakeLists.txt | 4 + src/include.am | 1 + src/ssl.c | 2768 +------------ src/ssl_certman.c | 4 +- src/ssl_crypto.c | 3476 +++++++++++++++++ tests/api.c | 3285 ++++++++++------ wolfcrypt/src/evp.c | 167 +- wolfcrypt/test/test.c | 2 +- 15 files changed, 5621 insertions(+), 4100 deletions(-) create mode 100644 src/ssl_crypto.c diff --git a/IDE/Espressif/ESP-IDF/UPDATE.md b/IDE/Espressif/ESP-IDF/UPDATE.md index 63d3bce7d..010054e9e 100644 --- a/IDE/Espressif/ESP-IDF/UPDATE.md +++ b/IDE/Espressif/ESP-IDF/UPDATE.md @@ -21,3 +21,4 @@ Updates to Espressif ESP-IDF wolfssl_benchmark and wolfssl_test examples: - Added VisualGDB Project file & Visual Studio solution file. - Added optional `time_helper` for wolfssl_test - Exclude `ssl_misc.c` in component cmake to fix warning: #warning ssl_misc.c does not need to be compiled separately from ssl.c +- Exclude `ssl_crypto.c` in component cmake to fix warning: #warning ssl_crypto.c does not need to be compiled separately from ssl.c diff --git a/IDE/Espressif/ESP-IDF/examples/template/components/wolfssl/CMakeLists.txt b/IDE/Espressif/ESP-IDF/examples/template/components/wolfssl/CMakeLists.txt index 34e757706..d64d3fe3b 100644 --- a/IDE/Espressif/ESP-IDF/examples/template/components/wolfssl/CMakeLists.txt +++ b/IDE/Espressif/ESP-IDF/examples/template/components/wolfssl/CMakeLists.txt @@ -353,8 +353,9 @@ else() "\"${WOLFSSL_ROOT}/src/misc.c\"" "\"${WOLFSSL_ROOT}/src/pk.c\"" "\"${WOLFSSL_ROOT}/src/ssl_asn1.c\"" # included by ssl.c - "\"${WOLFSSL_ROOT}/src/ssl_certman.c\"" # included by ssl.c "\"${WOLFSSL_ROOT}/src/ssl_bn.c\"" # included by ssl.c + "\"${WOLFSSL_ROOT}/src/ssl_certman.c\"" # included by ssl.c + "\"${WOLFSSL_ROOT}/src/ssl_crypto.c\"" # included by ssl.c "\"${WOLFSSL_ROOT}/src/ssl_misc.c\"" # included by ssl.c "\"${WOLFSSL_ROOT}/src/x509.c\"" "\"${WOLFSSL_ROOT}/src/x509_str.c\"" diff --git a/IDE/Espressif/ESP-IDF/examples/wolfssl_benchmark/components/wolfssl/CMakeLists.txt b/IDE/Espressif/ESP-IDF/examples/wolfssl_benchmark/components/wolfssl/CMakeLists.txt index 9c27cf68c..e3a8a81f0 100644 --- a/IDE/Espressif/ESP-IDF/examples/wolfssl_benchmark/components/wolfssl/CMakeLists.txt +++ b/IDE/Espressif/ESP-IDF/examples/wolfssl_benchmark/components/wolfssl/CMakeLists.txt @@ -353,6 +353,7 @@ else() "\"${WOLFSSL_ROOT}/src/ssl_asn1.c\"" # included by ssl.c "\"${WOLFSSL_ROOT}/src/ssl_bn.c\"" # included by ssl.c "\"${WOLFSSL_ROOT}/src/ssl_certman.c\"" # included by ssl.c + "\"${WOLFSSL_ROOT}/src/ssl_crypto.c\"" # included by ssl.c "\"${WOLFSSL_ROOT}/src/ssl_misc.c\"" # included by ssl.c "\"${WOLFSSL_ROOT}/src/x509.c\"" "\"${WOLFSSL_ROOT}/src/x509_str.c\"" diff --git a/IDE/Espressif/ESP-IDF/examples/wolfssl_client/components/wolfssl/CMakeLists.txt b/IDE/Espressif/ESP-IDF/examples/wolfssl_client/components/wolfssl/CMakeLists.txt index e74aa716b..b5ee75c61 100644 --- a/IDE/Espressif/ESP-IDF/examples/wolfssl_client/components/wolfssl/CMakeLists.txt +++ b/IDE/Espressif/ESP-IDF/examples/wolfssl_client/components/wolfssl/CMakeLists.txt @@ -393,6 +393,7 @@ else() "\"${WOLFSSL_ROOT}/src/ssl_asn1.c\"" # included by ssl.c "\"${WOLFSSL_ROOT}/src/ssl_bn.c\"" # included by ssl.c "\"${WOLFSSL_ROOT}/src/ssl_certman.c\"" # included by ssl.c + "\"${WOLFSSL_ROOT}/src/ssl_crypto.c\"" # included by ssl.c "\"${WOLFSSL_ROOT}/src/ssl_misc.c\"" # included by ssl.c "\"${WOLFSSL_ROOT}/src/x509.c\"" "\"${WOLFSSL_ROOT}/src/x509_str.c\"" diff --git a/IDE/Espressif/ESP-IDF/examples/wolfssl_server/components/wolfssl/CMakeLists.txt b/IDE/Espressif/ESP-IDF/examples/wolfssl_server/components/wolfssl/CMakeLists.txt index e74aa716b..b5ee75c61 100644 --- a/IDE/Espressif/ESP-IDF/examples/wolfssl_server/components/wolfssl/CMakeLists.txt +++ b/IDE/Espressif/ESP-IDF/examples/wolfssl_server/components/wolfssl/CMakeLists.txt @@ -393,6 +393,7 @@ else() "\"${WOLFSSL_ROOT}/src/ssl_asn1.c\"" # included by ssl.c "\"${WOLFSSL_ROOT}/src/ssl_bn.c\"" # included by ssl.c "\"${WOLFSSL_ROOT}/src/ssl_certman.c\"" # included by ssl.c + "\"${WOLFSSL_ROOT}/src/ssl_crypto.c\"" # included by ssl.c "\"${WOLFSSL_ROOT}/src/ssl_misc.c\"" # included by ssl.c "\"${WOLFSSL_ROOT}/src/x509.c\"" "\"${WOLFSSL_ROOT}/src/x509_str.c\"" diff --git a/IDE/Espressif/ESP-IDF/examples/wolfssl_test/components/wolfssl/CMakeLists.txt b/IDE/Espressif/ESP-IDF/examples/wolfssl_test/components/wolfssl/CMakeLists.txt index aa6a3c35f..f752fa666 100644 --- a/IDE/Espressif/ESP-IDF/examples/wolfssl_test/components/wolfssl/CMakeLists.txt +++ b/IDE/Espressif/ESP-IDF/examples/wolfssl_test/components/wolfssl/CMakeLists.txt @@ -482,6 +482,7 @@ endif() "\"${WOLFSSL_ROOT}/src/ssl_asn1.c\"" # included by ssl.c "\"${WOLFSSL_ROOT}/src/ssl_bn.c\"" # included by ssl.c "\"${WOLFSSL_ROOT}/src/ssl_certman.c\"" # included by ssl.c + "\"${WOLFSSL_ROOT}/src/ssl_crypto.c\"" # included by ssl.c "\"${WOLFSSL_ROOT}/src/ssl_misc.c\"" # included by ssl.c "\"${WOLFSSL_ROOT}/src/x509.c\"" "\"${WOLFSSL_ROOT}/src/x509_str.c\"" diff --git a/IDE/Espressif/ESP-IDF/libs/CMakeLists.txt b/IDE/Espressif/ESP-IDF/libs/CMakeLists.txt index 4f0f4e8ae..ab9cb25f4 100644 --- a/IDE/Espressif/ESP-IDF/libs/CMakeLists.txt +++ b/IDE/Espressif/ESP-IDF/libs/CMakeLists.txt @@ -71,7 +71,11 @@ set(COMPONENT_SRCEXCLUDE "./src/conf.c" "./src/misc.c" "./src/pk.c" - "./src/ssl_misc.c" # included by ssl.c + "./src/ssl_asn1.c" # included by ssl.c + "./src/ssl_bn.c" # included by ssl.c + "./src/ssl_certman.c" # included by ssl.c + "./src/ssl_crypto.c" # included by ssl.c + "./src/ssl_misc.c" # included by ssl.c "./src/x509.c" "./src/x509_str.c" "./wolfcrypt/src/evp.c" diff --git a/IDE/MSVS-2019-AZSPHERE/wolfssl_new_azsphere/CMakeLists.txt b/IDE/MSVS-2019-AZSPHERE/wolfssl_new_azsphere/CMakeLists.txt index 40066d914..902050c27 100644 --- a/IDE/MSVS-2019-AZSPHERE/wolfssl_new_azsphere/CMakeLists.txt +++ b/IDE/MSVS-2019-AZSPHERE/wolfssl_new_azsphere/CMakeLists.txt @@ -37,6 +37,10 @@ list( REMOVE_ITEM SSL_SOURCES ../../../src/conf.c ) list( REMOVE_ITEM SSL_SOURCES ../../../src/x509.c ) list( REMOVE_ITEM SSL_SOURCES ../../../src/x509_str.c ) list( REMOVE_ITEM SSL_SOURCES ../../../src/pk.c ) +list( REMOVE_ITEM SSL_SOURCES ../../../src/ssl_asn1.c ) +list( REMOVE_ITEM SSL_SOURCES ../../../src/ssl_bn.c ) +list( REMOVE_ITEM SSL_SOURCES ../../../src/ssl_certman.c ) +list( REMOVE_ITEM SSL_SOURCES ../../../src/ssl_crypto.c ) list( REMOVE_ITEM SSL_SOURCES ../../../src/ssl_misc.c ) aux_source_directory( ${CRYPTO_SRC_DIR} CRYPTO_SOURCES ) list( REMOVE_ITEM CRYPTO_SOURCES ../../../wolfcrypt/src/evp.c ) diff --git a/src/include.am b/src/include.am index 18696f0da..a69822fff 100644 --- a/src/include.am +++ b/src/include.am @@ -20,6 +20,7 @@ EXTRA_DIST += src/pk.c EXTRA_DIST += src/ssl_asn1.c EXTRA_DIST += src/ssl_bn.c EXTRA_DIST += src/ssl_certman.c +EXTRA_DIST += src/ssl_crypto.c EXTRA_DIST += src/ssl_misc.c EXTRA_DIST += src/x509.c EXTRA_DIST += src/x509_str.c diff --git a/src/ssl.c b/src/ssl.c index 5c7c51c06..7af0aaa08 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -208,13 +208,15 @@ #define WOLFSSL_EVP_INCLUDED #include "wolfcrypt/src/evp.c" +/* Crypto code uses EVP APIs. */ +#define WOLFSSL_SSL_CRYPTO_INCLUDED +#include "src/ssl_crypto.c" + #ifndef WOLFCRYPT_ONLY #define WOLFSSL_SSL_CERTMAN_INCLUDED #include "src/ssl_certman.c" #endif -#define _HMAC_Init _InitHmac - #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \ !defined(WOLFCRYPT_ONLY) /* Convert shortname to NID. @@ -18085,1173 +18087,7 @@ size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out, } #endif /* OPENSSL_EXTRA */ - -#if defined(OPENSSL_EXTRA) || defined(HAVE_CURL) -#ifndef NO_MD5 - int wolfSSL_MD5_Init(WOLFSSL_MD5_CTX* md5) - { - int ret; - typedef char md5_test[sizeof(MD5_CTX) >= sizeof(wc_Md5) ? 1 : -1]; - (void)sizeof(md5_test); - - WOLFSSL_ENTER("MD5_Init"); - ret = wc_InitMd5((wc_Md5*)md5); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - - int wolfSSL_MD5_Update(WOLFSSL_MD5_CTX* md5, const void* input, - unsigned long sz) - { - int ret; - - WOLFSSL_ENTER("MD5_Update"); - ret = wc_Md5Update((wc_Md5*)md5, (const byte*)input, (word32)sz); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - - - int wolfSSL_MD5_Final(byte* output, WOLFSSL_MD5_CTX* md5) - { - int ret; - - WOLFSSL_ENTER("MD5_Final"); - ret = wc_Md5Final((wc_Md5*)md5, output); - - /* have to actually free the resources (if any) here, because the - * OpenSSL API doesn't include SHA*_Free(). - */ - wc_Md5Free((wc_Md5*)md5); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - /* Apply MD5 transformation to the data */ - int wolfSSL_MD5_Transform(WOLFSSL_MD5_CTX* md5, const unsigned char* data) - { - int ret; - - WOLFSSL_ENTER("MD5_Transform"); - - /* sanity check */ - if (md5 == NULL || data == NULL) { - return 0; - } - #if defined(BIG_ENDIAN_ORDER) - ByteReverseWords((word32*)data, (word32*)data, WC_MD5_BLOCK_SIZE); - #endif - - ret = wc_Md5Transform((wc_Md5*)md5, data); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - - unsigned char *wolfSSL_MD5(const unsigned char* data, size_t len, - unsigned char* hash) - { - static unsigned char out[WC_MD5_DIGEST_SIZE]; - - WOLFSSL_ENTER("wolfSSL_MD5"); - - if (hash == NULL) - hash = out; - if (wc_Md5Hash(data, (word32)len, hash) != 0) { - WOLFSSL_MSG("wc_Md5Hash error"); - return NULL; - } - return hash; - } -#endif /* !NO_MD5 */ - - -#ifndef NO_SHA - int wolfSSL_SHA_Init(WOLFSSL_SHA_CTX* sha) - { - int ret; - - typedef char sha_test[sizeof(SHA_CTX) >= sizeof(wc_Sha) ? 1 : -1]; - (void)sizeof(sha_test); - - WOLFSSL_ENTER("SHA_Init"); - ret = wc_InitSha((wc_Sha*)sha); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - - - int wolfSSL_SHA_Update(WOLFSSL_SHA_CTX* sha, const void* input, - unsigned long sz) - { - int ret; - - WOLFSSL_ENTER("SHA_Update"); - ret = wc_ShaUpdate((wc_Sha*)sha, (const byte*)input, (word32)sz); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - - - int wolfSSL_SHA_Final(byte* output, WOLFSSL_SHA_CTX* sha) - { - int ret; - - WOLFSSL_ENTER("SHA_Final"); - ret = wc_ShaFinal((wc_Sha*)sha, output); - - /* have to actually free the resources (if any) here, because the - * OpenSSL API doesn't include SHA*_Free(). - */ - wc_ShaFree((wc_Sha*)sha); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - - #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ - (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) - /* Apply SHA1 transformation to the data */ - int wolfSSL_SHA_Transform(WOLFSSL_SHA_CTX* sha, - const unsigned char* data) - { - int ret; - - WOLFSSL_ENTER("SHA_Transform"); - /* sanity check */ - if (sha == NULL || data == NULL) { - return 0; - } - #if defined(LITTLE_ENDIAN_ORDER) - ByteReverseWords((word32*)data, (word32*)data, WC_SHA_BLOCK_SIZE); - #endif - ret = wc_ShaTransform((wc_Sha*)sha, data); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - #endif - - int wolfSSL_SHA1_Init(WOLFSSL_SHA_CTX* sha) - { - WOLFSSL_ENTER("SHA1_Init"); - return SHA_Init(sha); - } - - - int wolfSSL_SHA1_Update(WOLFSSL_SHA_CTX* sha, const void* input, - unsigned long sz) - { - WOLFSSL_ENTER("SHA1_Update"); - return SHA_Update(sha, input, sz); - } - - - int wolfSSL_SHA1_Final(byte* output, WOLFSSL_SHA_CTX* sha) - { - WOLFSSL_ENTER("SHA1_Final"); - return SHA_Final(output, sha); - } - - #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ - (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) - /* Apply SHA1 transformation to the data */ - int wolfSSL_SHA1_Transform(WOLFSSL_SHA_CTX* sha, - const unsigned char* data) - { - WOLFSSL_ENTER("SHA1_Transform"); - return (wolfSSL_SHA_Transform(sha, data)); - } - #endif -#endif /* !NO_SHA */ - -#ifndef NO_SHA256 -#ifdef WOLFSSL_SHA224 - - int wolfSSL_SHA224_Init(WOLFSSL_SHA224_CTX* sha) - { - int ret; - - typedef char sha_test[sizeof(SHA224_CTX) >= sizeof(wc_Sha224) ? 1 : -1]; - (void)sizeof(sha_test); - - WOLFSSL_ENTER("SHA224_Init"); - ret = wc_InitSha224((wc_Sha224*)sha); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - - - int wolfSSL_SHA224_Update(WOLFSSL_SHA224_CTX* sha, const void* input, - unsigned long sz) - { - int ret; - - WOLFSSL_ENTER("SHA224_Update"); - ret = wc_Sha224Update((wc_Sha224*)sha, (const byte*)input, (word32)sz); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - - - int wolfSSL_SHA224_Final(byte* output, WOLFSSL_SHA224_CTX* sha) - { - int ret; - - WOLFSSL_ENTER("SHA224_Final"); - ret = wc_Sha224Final((wc_Sha224*)sha, output); - - /* have to actually free the resources (if any) here, because the - * OpenSSL API doesn't include SHA*_Free(). - */ - wc_Sha224Free((wc_Sha224*)sha); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - -#endif /* WOLFSSL_SHA224 */ - - int wolfSSL_SHA256_Init(WOLFSSL_SHA256_CTX* sha256) - { - int ret; - - typedef char sha_test[sizeof(SHA256_CTX) >= sizeof(wc_Sha256) ? 1 : -1]; - (void)sizeof(sha_test); - - WOLFSSL_ENTER("SHA256_Init"); - ret = wc_InitSha256((wc_Sha256*)sha256); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - - int wolfSSL_SHA256_Update(WOLFSSL_SHA256_CTX* sha, const void* input, - unsigned long sz) - { - int ret; - - WOLFSSL_ENTER("SHA256_Update"); - ret = wc_Sha256Update((wc_Sha256*)sha, (const byte*)input, (word32)sz); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - - int wolfSSL_SHA256_Final(byte* output, WOLFSSL_SHA256_CTX* sha) - { - int ret; - - WOLFSSL_ENTER("SHA256_Final"); - ret = wc_Sha256Final((wc_Sha256*)sha, output); - - /* have to actually free the resources (if any) here, because the - * OpenSSL API doesn't include SHA*_Free(). - */ - wc_Sha256Free((wc_Sha256*)sha); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - - #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ - (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) && \ - !defined(WOLFSSL_DEVCRYPTO_HASH) && !defined(WOLFSSL_AFALG_HASH) && \ - !defined(WOLFSSL_KCAPI_HASH) /* doesn't support direct transform */ - /* Apply SHA256 transformation to the data */ - int wolfSSL_SHA256_Transform(WOLFSSL_SHA256_CTX* sha256, - const unsigned char* data) - { - int ret; - - WOLFSSL_ENTER("SHA256_Transform"); - /* sanity check */ - if (sha256 == NULL || data == NULL) { - return 0; - } - #if defined(LITTLE_ENDIAN_ORDER) - ByteReverseWords((word32*)data, (word32*)data, WC_SHA256_BLOCK_SIZE); - #endif - ret = wc_Sha256Transform((wc_Sha256*)sha256, data); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - #endif -#endif /* !NO_SHA256 */ - - -#ifdef WOLFSSL_SHA384 - - int wolfSSL_SHA384_Init(WOLFSSL_SHA384_CTX* sha) - { - int ret; - - typedef char sha_test[sizeof(SHA384_CTX) >= sizeof(wc_Sha384) ? 1 : -1]; - (void)sizeof(sha_test); - - WOLFSSL_ENTER("SHA384_Init"); - ret = wc_InitSha384((wc_Sha384*)sha); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - - int wolfSSL_SHA384_Update(WOLFSSL_SHA384_CTX* sha, const void* input, - unsigned long sz) - { - int ret; - - WOLFSSL_ENTER("SHA384_Update"); - ret = wc_Sha384Update((wc_Sha384*)sha, (const byte*)input, (word32)sz); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - - int wolfSSL_SHA384_Final(byte* output, WOLFSSL_SHA384_CTX* sha) - { - int ret; - - WOLFSSL_ENTER("SHA384_Final"); - ret = wc_Sha384Final((wc_Sha384*)sha, output); - - /* have to actually free the resources (if any) here, because the - * OpenSSL API doesn't include SHA*_Free(). - */ - wc_Sha384Free((wc_Sha384*)sha); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - -#endif /* WOLFSSL_SHA384 */ - - -#ifdef WOLFSSL_SHA512 - - int wolfSSL_SHA512_Init(WOLFSSL_SHA512_CTX* sha) - { - int ret; - - typedef char sha_test[sizeof(SHA512_CTX) >= sizeof(wc_Sha512) ? 1 : -1]; - (void)sizeof(sha_test); - - WOLFSSL_ENTER("SHA512_Init"); - ret = wc_InitSha512((wc_Sha512*)sha); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - - int wolfSSL_SHA512_Update(WOLFSSL_SHA512_CTX* sha, const void* input, - unsigned long sz) - { - int ret; - - WOLFSSL_ENTER("SHA512_Update"); - ret = wc_Sha512Update((wc_Sha512*)sha, (const byte*)input, (word32)sz); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - - int wolfSSL_SHA512_Final(byte* output, WOLFSSL_SHA512_CTX* sha) - { - int ret; - - WOLFSSL_ENTER("SHA512_Final"); - ret = wc_Sha512Final((wc_Sha512*)sha, output); - - /* have to actually free the resources (if any) here, because the - * OpenSSL API doesn't include SHA*_Free(). - */ - wc_Sha512Free((wc_Sha512*)sha); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - - #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ - (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) && \ - !defined(WOLFSSL_KCAPI_HASH) /* doesn't support direct transform */ - /* Apply SHA512 transformation to the data */ - int wolfSSL_SHA512_Transform(WOLFSSL_SHA512_CTX* sha512, - const unsigned char* data) - { - int ret; - - WOLFSSL_ENTER("SHA512_Transform"); - /* sanity check */ - if (sha512 == NULL || data == NULL) { - return WOLFSSL_FAILURE; - } - - ret = wc_Sha512Transform((wc_Sha512*)sha512, data); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - #endif /* !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \ - (HAVE_FIPS_VERSION > 2)) && !WOLFSSL_KCAPI_HASH */ - -#if !defined(WOLFSSL_NOSHA512_224) && \ - (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST) - int wolfSSL_SHA512_224_Init(WOLFSSL_SHA512_224_CTX* sha) - { - int ret; - - WOLFSSL_ENTER("SHA512_224_Init"); - ret = wc_InitSha512_224((wc_Sha512*)sha); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - - int wolfSSL_SHA512_224_Update(WOLFSSL_SHA512_224_CTX* sha, - const void* input, unsigned long sz) - { - int ret; - - WOLFSSL_ENTER("SHA512_224_Update"); - ret = wc_Sha512_224Update((wc_Sha512*)sha, (const byte*)input, (word32)sz); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - - int wolfSSL_SHA512_224_Final(byte* output, WOLFSSL_SHA512_224_CTX* sha) - { - int ret; - - WOLFSSL_ENTER("SHA512_224_Final"); - ret = wc_Sha512_224Final((wc_Sha512*)sha, output); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - - #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ - (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) - /* Apply SHA512 transformation to the data */ - int wolfSSL_SHA512_224_Transform(WOLFSSL_SHA512_CTX* sha512, - const unsigned char* data) - { - int ret; - - WOLFSSL_ENTER("SHA512_224_Transform"); - /* sanity check */ - if (sha512 == NULL || data == NULL) { - return WOLFSSL_FAILURE; - } - - ret = wc_Sha512_224Transform((wc_Sha512*)sha512, data); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - #endif /* !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \ - (HAVE_FIPS_VERSION > 2)) */ - -#endif /* !WOLFSSL_NOSHA512_224 && !FIPS ... */ - -#if !defined(WOLFSSL_NOSHA512_256) && \ - (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST) - int wolfSSL_SHA512_256_Init(WOLFSSL_SHA512_256_CTX* sha) - { - int ret; - - WOLFSSL_ENTER("SHA512_256_Init"); - ret = wc_InitSha512_256((wc_Sha512*)sha); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - - int wolfSSL_SHA512_256_Update(WOLFSSL_SHA512_256_CTX* sha, - const void* input, unsigned long sz) - { - int ret; - - WOLFSSL_ENTER("SHA512_256_Update"); - ret = wc_Sha512_256Update((wc_Sha512*)sha, (const byte*)input, (word32)sz); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - - int wolfSSL_SHA512_256_Final(byte* output, WOLFSSL_SHA512_256_CTX* sha) - { - int ret; - - WOLFSSL_ENTER("SHA512_256_Final"); - ret = wc_Sha512_256Final((wc_Sha512*)sha, output); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - - #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ - (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) - /* Apply SHA512 transformation to the data */ - int wolfSSL_SHA512_256_Transform(WOLFSSL_SHA512_CTX* sha512, - const unsigned char* data) - { - int ret; - - WOLFSSL_ENTER("SHA512_256_Transform"); - /* sanity check */ - if (sha512 == NULL || data == NULL) { - return WOLFSSL_FAILURE; - } - - ret = wc_Sha512_256Transform((wc_Sha512*)sha512, data); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - #endif /* !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \ - (HAVE_FIPS_VERSION > 2)) */ - -#endif /* !WOLFSSL_NOSHA512_256 && !FIPS ... */ - -#endif /* WOLFSSL_SHA512 */ - -#ifdef WOLFSSL_SHA3 -#ifndef WOLFSSL_NOSHA3_224 - int wolfSSL_SHA3_224_Init(WOLFSSL_SHA3_224_CTX* sha) - { - int ret; - - typedef char sha_test[sizeof(SHA3_224_CTX) >= sizeof(wc_Sha3) ? 1 : -1]; - (void)sizeof(sha_test); - - WOLFSSL_ENTER("SHA3_224_Init"); - ret = wc_InitSha3_224((wc_Sha3*)sha, NULL, INVALID_DEVID); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - - int wolfSSL_SHA3_224_Update(WOLFSSL_SHA3_224_CTX* sha, const void* input, - unsigned long sz) - { - int ret; - - WOLFSSL_ENTER("SHA3_224_Update"); - ret = wc_Sha3_224_Update((wc_Sha3*)sha, (const byte*)input, (word32)sz); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - - int wolfSSL_SHA3_224_Final(byte* output, WOLFSSL_SHA3_224_CTX* sha) - { - int ret; - - WOLFSSL_ENTER("SHA3_224_Final"); - ret = wc_Sha3_224_Final((wc_Sha3*)sha, output); - - /* have to actually free the resources (if any) here, because the - * OpenSSL API doesn't include SHA*_Free(). - */ - wc_Sha3_224_Free((wc_Sha3*)sha); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - -#endif /* WOLFSSL_NOSHA3_224 */ - -#ifndef WOLFSSL_NOSHA3_256 - int wolfSSL_SHA3_256_Init(WOLFSSL_SHA3_256_CTX* sha3_256) - { - int ret; - - typedef char sha_test[sizeof(SHA3_256_CTX) >= sizeof(wc_Sha3) ? 1 : -1]; - (void)sizeof(sha_test); - - WOLFSSL_ENTER("SHA3_256_Init"); - ret = wc_InitSha3_256((wc_Sha3*)sha3_256, NULL, INVALID_DEVID); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - - int wolfSSL_SHA3_256_Update(WOLFSSL_SHA3_256_CTX* sha, const void* input, - unsigned long sz) - { - int ret; - - WOLFSSL_ENTER("SHA3_256_Update"); - ret = wc_Sha3_256_Update((wc_Sha3*)sha, (const byte*)input, (word32)sz); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - - int wolfSSL_SHA3_256_Final(byte* output, WOLFSSL_SHA3_256_CTX* sha) - { - int ret; - - WOLFSSL_ENTER("SHA3_256_Final"); - ret = wc_Sha3_256_Final((wc_Sha3*)sha, output); - - /* have to actually free the resources (if any) here, because the - * OpenSSL API doesn't include SHA*_Free(). - */ - wc_Sha3_256_Free((wc_Sha3*)sha); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } -#endif /* WOLFSSL_NOSHA3_256 */ - - int wolfSSL_SHA3_384_Init(WOLFSSL_SHA3_384_CTX* sha) - { - int ret; - - typedef char sha_test[sizeof(SHA3_384_CTX) >= sizeof(wc_Sha3) ? 1 : -1]; - (void)sizeof(sha_test); - - WOLFSSL_ENTER("SHA3_384_Init"); - ret = wc_InitSha3_384((wc_Sha3*)sha, NULL, INVALID_DEVID); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - - int wolfSSL_SHA3_384_Update(WOLFSSL_SHA3_384_CTX* sha, const void* input, - unsigned long sz) - { - int ret; - - WOLFSSL_ENTER("SHA3_384_Update"); - ret = wc_Sha3_384_Update((wc_Sha3*)sha, (const byte*)input, (word32)sz); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - - int wolfSSL_SHA3_384_Final(byte* output, WOLFSSL_SHA3_384_CTX* sha) - { - int ret; - - WOLFSSL_ENTER("SHA3_384_Final"); - ret = wc_Sha3_384_Final((wc_Sha3*)sha, output); - - /* have to actually free the resources (if any) here, because the - * OpenSSL API doesn't include SHA*_Free(). - */ - wc_Sha3_384_Free((wc_Sha3*)sha); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - -#ifndef WOLFSSL_NOSHA3_512 - int wolfSSL_SHA3_512_Init(WOLFSSL_SHA3_512_CTX* sha) - { - int ret; - - typedef char sha_test[sizeof(SHA3_512_CTX) >= sizeof(wc_Sha3) ? 1 : -1]; - (void)sizeof(sha_test); - - WOLFSSL_ENTER("SHA3_512_Init"); - ret = wc_InitSha3_512((wc_Sha3*)sha, NULL, INVALID_DEVID); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - - int wolfSSL_SHA3_512_Update(WOLFSSL_SHA3_512_CTX* sha, const void* input, - unsigned long sz) - { - int ret; - - WOLFSSL_ENTER("SHA3_512_Update"); - ret = wc_Sha3_512_Update((wc_Sha3*)sha, (const byte*)input, (word32)sz); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } - - int wolfSSL_SHA3_512_Final(byte* output, WOLFSSL_SHA3_512_CTX* sha) - { - int ret; - - WOLFSSL_ENTER("SHA3_512_Final"); - ret = wc_Sha3_512_Final((wc_Sha3*)sha, output); - - /* have to actually free the resources (if any) here, because the - * OpenSSL API doesn't include SHA*_Free(). - */ - wc_Sha3_512_Free((wc_Sha3*)sha); - - /* return 1 on success, 0 otherwise */ - if (ret == 0) - return WOLFSSL_SUCCESS; - return WOLFSSL_FAILURE; - } -#endif /* WOLFSSL_NOSHA3_512 */ -#endif /* WOLFSSL_SHA3 */ -#endif - #ifdef OPENSSL_EXTRA - - unsigned char* wolfSSL_HMAC(const WOLFSSL_EVP_MD* evp_md, const void* key, - int key_len, const unsigned char* d, int n, - unsigned char* md, unsigned int* md_len) - { - int type; - int mdlen; - unsigned char* ret = NULL; -#ifdef WOLFSSL_SMALL_STACK - Hmac* hmac = NULL; -#else - Hmac hmac[1]; -#endif - void* heap = NULL; - - WOLFSSL_ENTER("wolfSSL_HMAC"); - if (!md) { - WOLFSSL_MSG("Static buffer not supported, pass in md buffer"); - return NULL; /* no static buffer support */ - } - -#ifndef NO_MD5 - if (XSTRCMP(evp_md, "MD5") == 0) { - type = WC_MD5; - mdlen = WC_MD5_DIGEST_SIZE; - } else -#endif -#ifdef WOLFSSL_SHA224 - if (XSTRCMP(evp_md, "SHA224") == 0) { - type = WC_SHA224; - mdlen = WC_SHA224_DIGEST_SIZE; - } else -#endif -#ifndef NO_SHA256 - if (XSTRCMP(evp_md, "SHA256") == 0) { - type = WC_SHA256; - mdlen = WC_SHA256_DIGEST_SIZE; - } else -#endif -#ifdef WOLFSSL_SHA384 - if (XSTRCMP(evp_md, "SHA384") == 0) { - type = WC_SHA384; - mdlen = WC_SHA384_DIGEST_SIZE; - } else -#endif -#ifdef WOLFSSL_SHA512 - if (XSTRCMP(evp_md, "SHA512") == 0) { - type = WC_SHA512; - mdlen = WC_SHA512_DIGEST_SIZE; - } else -#endif -#ifdef WOLFSSL_SHA3 - #ifndef WOLFSSL_NOSHA3_224 - if (XSTRCMP(evp_md, "SHA3_224") == 0) { - type = WC_SHA3_224; - mdlen = WC_SHA3_224_DIGEST_SIZE; - } else - #endif - #ifndef WOLFSSL_NOSHA3_256 - if (XSTRCMP(evp_md, "SHA3_256") == 0) { - type = WC_SHA3_256; - mdlen = WC_SHA3_256_DIGEST_SIZE; - } else - #endif - if (XSTRCMP(evp_md, "SHA3_384") == 0) { - type = WC_SHA3_384; - mdlen = WC_SHA3_384_DIGEST_SIZE; - } else - #ifndef WOLFSSL_NOSHA3_512 - if (XSTRCMP(evp_md, "SHA3_512") == 0) { - type = WC_SHA3_512; - mdlen = WC_SHA3_512_DIGEST_SIZE; - } else - #endif -#endif -#ifndef NO_SHA - if (XSTRCMP(evp_md, "SHA") == 0 || XSTRCMP(evp_md, "SHA1") == 0) { - type = WC_SHA; - mdlen = WC_SHA_DIGEST_SIZE; - } - else -#endif - { - return NULL; - } - - #ifdef WOLFSSL_SMALL_STACK - hmac = (Hmac*)XMALLOC(sizeof(Hmac), heap, DYNAMIC_TYPE_HMAC); - if (hmac == NULL) - return NULL; - #endif - - if (wc_HmacInit(hmac, heap, INVALID_DEVID) == 0) { - if (wc_HmacSetKey(hmac, type, (const byte*)key, key_len) == 0) { - if (wc_HmacUpdate(hmac, d, n) == 0) { - if (wc_HmacFinal(hmac, md) == 0) { - if (md_len) - *md_len = mdlen; - ret = md; - } - } - } - wc_HmacFree(hmac); - } - - #ifdef WOLFSSL_SMALL_STACK - XFREE(hmac, heap, DYNAMIC_TYPE_HMAC); - #endif - - (void)evp_md; - return ret; - } - -#ifndef NO_DES3 - /* 0 on ok */ - int wolfSSL_DES_key_sched(WOLFSSL_const_DES_cblock* key, - WOLFSSL_DES_key_schedule* schedule) - { - WOLFSSL_ENTER("wolfSSL_DES_key_sched"); - - if (key == NULL || schedule == NULL) { - WOLFSSL_MSG("Null argument passed in"); - } - else { - XMEMCPY(schedule, key, sizeof(WOLFSSL_const_DES_cblock)); - } - - return 0; - } - - - /* intended to behave similar to Kerberos mit_des_cbc_cksum - * return the last 4 bytes of cipher text */ - WOLFSSL_DES_LONG wolfSSL_DES_cbc_cksum(const unsigned char* in, - WOLFSSL_DES_cblock* out, long length, WOLFSSL_DES_key_schedule* sc, - WOLFSSL_const_DES_cblock* iv) - { - WOLFSSL_DES_LONG ret; - unsigned char* tmp; - unsigned char* data = (unsigned char*)in; - long dataSz = length; - byte dynamicFlag = 0; /* when padding the buffer created needs free'd */ - - WOLFSSL_ENTER("wolfSSL_DES_cbc_cksum"); - - if (in == NULL || out == NULL || sc == NULL || iv == NULL) { - WOLFSSL_MSG("Bad argument passed in"); - return 0; - } - - /* if input length is not a multiple of DES_BLOCK_SIZE pad with 0s */ - if (dataSz % DES_BLOCK_SIZE) { - dataSz += DES_BLOCK_SIZE - (dataSz % DES_BLOCK_SIZE); - data = (unsigned char*)XMALLOC(dataSz, NULL, - DYNAMIC_TYPE_TMP_BUFFER); - if (data == NULL) { - WOLFSSL_MSG("Issue creating temporary buffer"); - return 0; - } - dynamicFlag = 1; /* set to free buffer at end */ - XMEMCPY(data, in, length); - XMEMSET(data + length, 0, dataSz - length); /* padding */ - } - - tmp = (unsigned char*)XMALLOC(dataSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (tmp == NULL) { - WOLFSSL_MSG("Issue creating temporary buffer"); - if (dynamicFlag == 1) { - XFREE(data, NULL, DYNAMIC_TYPE_TMP_BUFFER); - } - return 0; - } - - wolfSSL_DES_cbc_encrypt(data, tmp, dataSz, sc, - (WOLFSSL_DES_cblock*)iv, 1); - XMEMCPY((unsigned char*)out, tmp + (dataSz - DES_BLOCK_SIZE), - DES_BLOCK_SIZE); - - ret = (((*((unsigned char*)out + 4) & 0xFF) << 24)| - ((*((unsigned char*)out + 5) & 0xFF) << 16)| - ((*((unsigned char*)out + 6) & 0xFF) << 8) | - (*((unsigned char*)out + 7) & 0xFF)); - - XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (dynamicFlag == 1) { - XFREE(data, NULL, DYNAMIC_TYPE_TMP_BUFFER); - } - - return ret; - } - - - void wolfSSL_DES_cbc_encrypt(const unsigned char* input, - unsigned char* output, long length, - WOLFSSL_DES_key_schedule* schedule, - WOLFSSL_DES_cblock* ivec, int enc) - { - Des myDes; - byte lastblock[DES_BLOCK_SIZE]; - int lb_sz; - long blk; - - WOLFSSL_ENTER("wolfSSL_DES_cbc_encrypt"); - - /* OpenSSL compat, no ret */ - if (wc_Des_SetKey(&myDes, (const byte*)schedule, (const byte*)ivec, - !enc) != 0) { - WOLFSSL_MSG("wc_Des_SetKey return error."); - return; - } - lb_sz = length%DES_BLOCK_SIZE; - blk = length/DES_BLOCK_SIZE; - - if (enc == DES_ENCRYPT){ - wc_Des_CbcEncrypt(&myDes, output, input, (word32)blk*DES_BLOCK_SIZE); - if(lb_sz){ - XMEMSET(lastblock, 0, DES_BLOCK_SIZE); - XMEMCPY(lastblock, input+length-lb_sz, lb_sz); - wc_Des_CbcEncrypt(&myDes, output+blk*DES_BLOCK_SIZE, - lastblock, (word32)DES_BLOCK_SIZE); - } - } - else { - wc_Des_CbcDecrypt(&myDes, output, input, (word32)blk*DES_BLOCK_SIZE); - if(lb_sz){ - wc_Des_CbcDecrypt(&myDes, lastblock, input+length-lb_sz, (word32)DES_BLOCK_SIZE); - XMEMCPY(output+length-lb_sz, lastblock, lb_sz); - } - } - } - - - /* WOLFSSL_DES_key_schedule is a unsigned char array of size 8 */ - void wolfSSL_DES_ede3_cbc_encrypt(const unsigned char* input, - unsigned char* output, long sz, - WOLFSSL_DES_key_schedule* ks1, - WOLFSSL_DES_key_schedule* ks2, - WOLFSSL_DES_key_schedule* ks3, - WOLFSSL_DES_cblock* ivec, int enc) - { - int ret; - Des3 des; - byte key[24];/* EDE uses 24 size key */ - byte lastblock[DES_BLOCK_SIZE]; - int lb_sz; - long blk; - - WOLFSSL_ENTER("wolfSSL_DES_ede3_cbc_encrypt"); - - if (sz <= 0) - return; - - XMEMSET(key, 0, sizeof(key)); - XMEMCPY(key, *ks1, DES_BLOCK_SIZE); - XMEMCPY(&key[DES_BLOCK_SIZE], *ks2, DES_BLOCK_SIZE); - XMEMCPY(&key[DES_BLOCK_SIZE * 2], *ks3, DES_BLOCK_SIZE); - lb_sz = sz%DES_BLOCK_SIZE; - blk = sz/DES_BLOCK_SIZE; - - /* OpenSSL compat, no ret */ - (void)wc_Des3Init(&des, NULL, INVALID_DEVID); - - if (enc == DES_ENCRYPT) { - if (wc_Des3_SetKey(&des, key, (const byte*)ivec, - DES_ENCRYPTION) == 0) { - ret = wc_Des3_CbcEncrypt(&des, output, input, (word32)blk*DES_BLOCK_SIZE); - #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &des.asyncDev, WC_ASYNC_FLAG_NONE); - #endif - (void)ret; /* ignore return codes for processing */ - if(lb_sz){ - XMEMSET(lastblock, 0, DES_BLOCK_SIZE); - XMEMCPY(lastblock, input+sz-lb_sz, lb_sz); - ret = wc_Des3_CbcEncrypt(&des, output+blk*DES_BLOCK_SIZE, - lastblock, (word32)DES_BLOCK_SIZE); - #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &des.asyncDev, WC_ASYNC_FLAG_NONE); - #endif - (void)ret; /* ignore return codes for processing */ - XMEMCPY(ivec, output+blk*DES_BLOCK_SIZE, DES_BLOCK_SIZE); - } - else { - XMEMCPY(ivec, output+(blk-1)*DES_BLOCK_SIZE, DES_BLOCK_SIZE); - } - } - } - else { - if (wc_Des3_SetKey(&des, key, (const byte*)ivec, - DES_DECRYPTION) == 0) { - if(lb_sz) - XMEMCPY(ivec, input+sz-lb_sz, DES_BLOCK_SIZE); - else - XMEMCPY(ivec, input+(blk-1)*DES_BLOCK_SIZE, DES_BLOCK_SIZE); - ret = wc_Des3_CbcDecrypt(&des, output, input, (word32)blk*DES_BLOCK_SIZE); - #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &des.asyncDev, WC_ASYNC_FLAG_NONE); - #endif - (void)ret; /* ignore return codes for processing */ - if(lb_sz){ - ret = wc_Des3_CbcDecrypt(&des, lastblock, input+sz-lb_sz, (word32)DES_BLOCK_SIZE); - #if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &des.asyncDev, WC_ASYNC_FLAG_NONE); - #endif - (void)ret; /* ignore return codes for processing */ - XMEMCPY(output+sz-lb_sz, lastblock, lb_sz); - } - } - } - wc_Des3Free(&des); - } - - - /* correctly sets ivec for next call */ - void wolfSSL_DES_ncbc_encrypt(const unsigned char* input, - unsigned char* output, long length, - WOLFSSL_DES_key_schedule* schedule, WOLFSSL_DES_cblock* ivec, - int enc) - { - Des myDes; - byte lastblock[DES_BLOCK_SIZE]; - int lb_sz; - long idx = length; - long blk; - - WOLFSSL_ENTER("wolfSSL_DES_ncbc_encrypt"); - - /* OpenSSL compat, no ret */ - if (wc_Des_SetKey(&myDes, (const byte*)schedule, - (const byte*)ivec, !enc) != 0) { - WOLFSSL_MSG("wc_Des_SetKey return error."); - return; - } - - lb_sz = length%DES_BLOCK_SIZE; - blk = length/DES_BLOCK_SIZE; - idx -= sizeof(DES_cblock); - if (lb_sz) { - idx += DES_BLOCK_SIZE - lb_sz; - } - if (enc == DES_ENCRYPT){ - wc_Des_CbcEncrypt(&myDes, output, input, - (word32)blk * DES_BLOCK_SIZE); - if (lb_sz){ - XMEMSET(lastblock, 0, DES_BLOCK_SIZE); - XMEMCPY(lastblock, input+length-lb_sz, lb_sz); - wc_Des_CbcEncrypt(&myDes, output + blk * DES_BLOCK_SIZE, - lastblock, (word32)DES_BLOCK_SIZE); - } - XMEMCPY(ivec, output + idx, sizeof(DES_cblock)); - } else { - WOLFSSL_DES_cblock tmp; - XMEMCPY(tmp, input + idx, sizeof(DES_cblock)); - wc_Des_CbcDecrypt(&myDes, output, input, - (word32)blk * DES_BLOCK_SIZE); - if (lb_sz){ - wc_Des_CbcDecrypt(&myDes, lastblock, input + length - lb_sz, - (word32)DES_BLOCK_SIZE); - XMEMCPY(output+length-lb_sz, lastblock, lb_sz); - } - XMEMCPY(ivec, tmp, sizeof(WOLFSSL_DES_cblock)); - } - - } - -#endif /* NO_DES3 */ - void wolfSSL_ERR_free_strings(void) { /* handled internally */ @@ -21824,35 +20660,6 @@ int wolfSSL_OCSP_parse_url(char* url, char** host, char** port, char** path, } #endif -#ifndef NO_MD4 - -void wolfSSL_MD4_Init(WOLFSSL_MD4_CTX* md4) -{ - /* make sure we have a big enough buffer */ - typedef char ok[sizeof(md4->buffer) >= sizeof(Md4) ? 1 : -1]; - (void) sizeof(ok); - - WOLFSSL_ENTER("MD4_Init"); - wc_InitMd4((Md4*)md4); -} - - -void wolfSSL_MD4_Update(WOLFSSL_MD4_CTX* md4, const void* data, - unsigned long len) -{ - WOLFSSL_ENTER("MD4_Update"); - wc_Md4Update((Md4*)md4, (const byte*)data, (word32)len); -} - - -void wolfSSL_MD4_Final(unsigned char* digest, WOLFSSL_MD4_CTX* md4) -{ - WOLFSSL_ENTER("MD4_Final"); - wc_Md4Final((Md4*)md4, digest); -} - -#endif /* NO_MD4 */ - #ifndef NO_WOLFSSL_STUB void wolfSSL_RAND_screen(void) { @@ -23448,680 +22255,6 @@ long wolfSSL_CTX_set_tlsext_opaque_prf_input_callback_arg(WOLFSSL_CTX* ctx, return WOLFSSL_SUCCESS; } - -#ifndef NO_DES3 -/* 0 on success */ -int wolfSSL_DES_set_key(WOLFSSL_const_DES_cblock* myDes, - WOLFSSL_DES_key_schedule* key) -{ -#ifdef WOLFSSL_CHECK_DESKEY - return wolfSSL_DES_set_key_checked(myDes, key); -#else - wolfSSL_DES_set_key_unchecked(myDes, key); - return 0; -#endif -} - - - -/* return true in fail case (1) */ -static int DES_check(word32 mask, word32 mask2, unsigned char* key) -{ - word32 value[2]; - - /* sanity check on length made in wolfSSL_DES_set_key_checked */ - value[0] = mask; - value[1] = mask2; - return (XMEMCMP(value, key, sizeof(value)) == 0)? 1: 0; -} - - -/* check that the key is odd parity and is not a weak key - * returns -1 if parity is wrong, -2 if weak/null key and 0 on success */ -int wolfSSL_DES_set_key_checked(WOLFSSL_const_DES_cblock* myDes, - WOLFSSL_DES_key_schedule* key) -{ - if (myDes == NULL || key == NULL) { - WOLFSSL_MSG("Bad argument passed to wolfSSL_DES_set_key_checked"); - return -2; - } - else { - word32 sz = sizeof(WOLFSSL_DES_key_schedule); - - /* sanity check before call to DES_check */ - if (sz != (sizeof(word32) * 2)) { - WOLFSSL_MSG("Unexpected WOLFSSL_DES_key_schedule size"); - return -2; - } - - /* check odd parity */ - if (wolfSSL_DES_check_key_parity(myDes) != 1) { - WOLFSSL_MSG("Odd parity test fail"); - return -1; - } - - if (wolfSSL_DES_is_weak_key(myDes) == 1) { - WOLFSSL_MSG("Weak key found"); - return -2; - } - - /* passed tests, now copy over key */ - XMEMCPY(key, myDes, sizeof(WOLFSSL_const_DES_cblock)); - - return 0; - } -} - - -/* check is not weak. Weak key list from Nist "Recommendation for the Triple - * Data Encryption Algorithm (TDEA) Block Cipher" - * - * returns 1 if is weak 0 if not - */ -int wolfSSL_DES_is_weak_key(WOLFSSL_const_DES_cblock* key) -{ - word32 mask, mask2; - - WOLFSSL_ENTER("wolfSSL_DES_is_weak_key"); - - if (key == NULL) { - WOLFSSL_MSG("NULL key passed in"); - return 1; - } - - mask = 0x01010101; mask2 = 0x01010101; - if (DES_check(mask, mask2, *key)) { - WOLFSSL_MSG("Weak key found"); - return 1; - } - - mask = 0xFEFEFEFE; mask2 = 0xFEFEFEFE; - if (DES_check(mask, mask2, *key)) { - WOLFSSL_MSG("Weak key found"); - return 1; - } - - mask = 0xE0E0E0E0; mask2 = 0xF1F1F1F1; - if (DES_check(mask, mask2, *key)) { - WOLFSSL_MSG("Weak key found"); - return 1; - } - - mask = 0x1F1F1F1F; mask2 = 0x0E0E0E0E; - if (DES_check(mask, mask2, *key)) { - WOLFSSL_MSG("Weak key found"); - return 1; - } - - /* semi-weak *key check (list from same Nist paper) */ - mask = 0x011F011F; mask2 = 0x010E010E; - if (DES_check(mask, mask2, *key) || - DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) { - WOLFSSL_MSG("Weak key found"); - return 1; - } - - mask = 0x01E001E0; mask2 = 0x01F101F1; - if (DES_check(mask, mask2, *key) || - DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) { - WOLFSSL_MSG("Weak key found"); - return 1; - } - - mask = 0x01FE01FE; mask2 = 0x01FE01FE; - if (DES_check(mask, mask2, *key) || - DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) { - WOLFSSL_MSG("Weak key found"); - return 1; - } - - mask = 0x1FE01FE0; mask2 = 0x0EF10EF1; - if (DES_check(mask, mask2, *key) || - DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) { - WOLFSSL_MSG("Weak key found"); - return 1; - } - - mask = 0x1FFE1FFE; mask2 = 0x0EFE0EFE; - if (DES_check(mask, mask2, *key) || - DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) { - WOLFSSL_MSG("Weak key found"); - return 1; - } - - return 0; -} - - -void wolfSSL_DES_set_key_unchecked(WOLFSSL_const_DES_cblock* myDes, - WOLFSSL_DES_key_schedule* key) -{ - if (myDes != NULL && key != NULL) { - XMEMCPY(key, myDes, sizeof(WOLFSSL_const_DES_cblock)); - } -} - - -/* Sets the parity of the DES key for use */ -void wolfSSL_DES_set_odd_parity(WOLFSSL_DES_cblock* myDes) -{ - word32 i; - word32 sz = sizeof(WOLFSSL_DES_cblock); - - WOLFSSL_ENTER("wolfSSL_DES_set_odd_parity"); - - for (i = 0; i < sz; i++) { - unsigned char c = (*myDes)[i]; - if (( - ((c >> 1) & 0x01) ^ - ((c >> 2) & 0x01) ^ - ((c >> 3) & 0x01) ^ - ((c >> 4) & 0x01) ^ - ((c >> 5) & 0x01) ^ - ((c >> 6) & 0x01) ^ - ((c >> 7) & 0x01)) == (c & 0x01)) { - WOLFSSL_MSG("Flipping parity bit"); - (*myDes)[i] = c ^ 0x01; - } - } -} - -int wolfSSL_DES_check_key_parity(WOLFSSL_DES_cblock *myDes) -{ - word32 i; - word32 sz = sizeof(WOLFSSL_DES_cblock); - - WOLFSSL_ENTER("wolfSSL_DES_check_key_parity"); - - for (i = 0; i < sz; i++) { - unsigned char c = (*myDes)[i]; - if (( - ((c >> 1) & 0x01) ^ - ((c >> 2) & 0x01) ^ - ((c >> 3) & 0x01) ^ - ((c >> 4) & 0x01) ^ - ((c >> 5) & 0x01) ^ - ((c >> 6) & 0x01) ^ - ((c >> 7) & 0x01)) == (c & 0x01)) { - return 0; - } - } - return 1; -} - -#ifdef WOLFSSL_DES_ECB -/* Encrypt or decrypt input message desa with key and get output in desb. - * if enc is DES_ENCRYPT,input message is encrypted or - * if enc is DES_DECRYPT,input message is decrypted. - * */ -void wolfSSL_DES_ecb_encrypt(WOLFSSL_DES_cblock* desa, - WOLFSSL_DES_cblock* desb, WOLFSSL_DES_key_schedule* key, int enc) -{ - Des myDes; - - WOLFSSL_ENTER("wolfSSL_DES_ecb_encrypt"); - - if (desa == NULL || key == NULL || desb == NULL || - (enc != DES_ENCRYPT && enc != DES_DECRYPT)) { - WOLFSSL_MSG("Bad argument passed to wolfSSL_DES_ecb_encrypt"); - } else { - if (wc_Des_SetKey(&myDes, (const byte*) key, - (const byte*) NULL, !enc) != 0) { - WOLFSSL_MSG("wc_Des_SetKey return error."); - return; - } - if (enc == DES_ENCRYPT){ - if (wc_Des_EcbEncrypt(&myDes, (byte*) desb, (const byte*) desa, - sizeof(WOLFSSL_DES_cblock)) != 0){ - WOLFSSL_MSG("wc_Des_EcbEncrypt return error."); - } - } else { - if (wc_Des_EcbDecrypt(&myDes, (byte*) desb, (const byte*) desa, - sizeof(WOLFSSL_DES_cblock)) != 0){ - WOLFSSL_MSG("wc_Des_EcbDecrpyt return error."); - } - } - } -} -#endif -#endif /* NO_DES3 */ - -#ifndef NO_RC4 -/* Set the key state for Arc4 structure. - * - * key Arc4 structure to use - * len length of data buffer - * data initial state to set Arc4 structure - */ -void wolfSSL_RC4_set_key(WOLFSSL_RC4_KEY* key, int len, - const unsigned char* data) -{ - typedef char rc4_test[sizeof(WOLFSSL_RC4_KEY) >= sizeof(Arc4) ? 1 : -1]; - (void)sizeof(rc4_test); - - WOLFSSL_ENTER("wolfSSL_RC4_set_key"); - - if (key == NULL || len < 0) { - WOLFSSL_MSG("bad argument passed in"); - return; - } - - XMEMSET(key, 0, sizeof(WOLFSSL_RC4_KEY)); - wc_Arc4SetKey((Arc4*)key, data, (word32)len); -} - - -/* Encrypt/decrypt with Arc4 structure. - * - * len length of buffer to encrypt/decrypt (in/out) - * in buffer to encrypt/decrypt - * out results of encryption/decryption - */ -void wolfSSL_RC4(WOLFSSL_RC4_KEY* key, size_t len, - const unsigned char* in, unsigned char* out) -{ - WOLFSSL_ENTER("wolfSSL_RC4"); - - if (key == NULL || in == NULL || out == NULL) { - WOLFSSL_MSG("Bad argument passed in"); - return; - } - - wc_Arc4Process((Arc4*)key, out, in, (word32)len); -} -#endif /* NO_RC4 */ - -#ifndef NO_AES - -#ifdef WOLFSSL_AES_DIRECT -/* AES encrypt direct, it is expected to be blocks of AES_BLOCK_SIZE for input. - * - * input Data to encrypt - * output Encrypted data after done - * key AES key to use for encryption - */ -void wolfSSL_AES_encrypt(const unsigned char* input, unsigned char* output, - AES_KEY *key) -{ - WOLFSSL_ENTER("wolfSSL_AES_encrypt"); - - if (input == NULL || output == NULL || key == NULL) { - WOLFSSL_MSG("Null argument passed in"); - return; - } - -#if !defined(HAVE_SELFTEST) && \ - (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3))) - if (wc_AesEncryptDirect((Aes*)key, output, input) != 0) { - WOLFSSL_MSG("wc_AesEncryptDirect failed"); - return; - } -#else - wc_AesEncryptDirect((Aes*)key, output, input); -#endif -} - - -/* AES decrypt direct, it is expected to be blocks of AES_BLOCK_SIZE for input. - * - * input Data to decrypt - * output Decrypted data after done - * key AES key to use for encryption - */ -void wolfSSL_AES_decrypt(const unsigned char* input, unsigned char* output, - AES_KEY *key) -{ - WOLFSSL_ENTER("wolfSSL_AES_decrypt"); - - if (input == NULL || output == NULL || key == NULL) { - WOLFSSL_MSG("Null argument passed in"); - return; - } - -#if !defined(HAVE_SELFTEST) && \ - (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3))) - if (wc_AesDecryptDirect((Aes*)key, output, input) != 0) { - WOLFSSL_MSG("wc_AesDecryptDirect failed"); - return; - } -#else - wc_AesDecryptDirect((Aes*)key, output, input); -#endif -} -#endif /* WOLFSSL_AES_DIRECT */ - -/* Setup of an AES key to use for encryption. - * - * key key in bytes to use for encryption - * bits size of key in bits - * aes AES structure to initialize - */ -int wolfSSL_AES_set_encrypt_key(const unsigned char *key, const int bits, - AES_KEY *aes) -{ - typedef char aes_test[sizeof(AES_KEY) >= sizeof(Aes) ? 1 : -1]; - (void)sizeof(aes_test); - - WOLFSSL_ENTER("wolfSSL_AES_set_encrypt_key"); - - if (key == NULL || aes == NULL) { - WOLFSSL_MSG("Null argument passed in"); - return -1; - } - - XMEMSET(aes, 0, sizeof(AES_KEY)); - if (wc_AesSetKey((Aes*)aes, key, ((bits)/8), NULL, AES_ENCRYPT) != 0) { - WOLFSSL_MSG("Error in setting AES key"); - return -1; - } - return 0; -} - - -/* Setup of an AES key to use for decryption. - * - * key key in bytes to use for decryption - * bits size of key in bits - * aes AES structure to initialize - */ -int wolfSSL_AES_set_decrypt_key(const unsigned char *key, const int bits, - AES_KEY *aes) -{ - typedef char aes_test[sizeof(AES_KEY) >= sizeof(Aes) ? 1 : -1]; - (void)sizeof(aes_test); - - WOLFSSL_ENTER("wolfSSL_AES_set_decrypt_key"); - - if (key == NULL || aes == NULL) { - WOLFSSL_MSG("Null argument passed in"); - return -1; - } - - XMEMSET(aes, 0, sizeof(AES_KEY)); - if (wc_AesSetKey((Aes*)aes, key, ((bits)/8), NULL, AES_DECRYPT) != 0) { - WOLFSSL_MSG("Error in setting AES key"); - return -1; - } - return 0; -} - - -#ifdef HAVE_AES_ECB -/* Encrypt/decrypt a 16 byte block of data using the key passed in. - * - * in buffer to encrypt/decrypt - * out buffer to hold result of encryption/decryption - * key AES structure to use with encryption/decryption - * enc AES_ENCRPT for encryption and AES_DECRYPT for decryption - */ -void wolfSSL_AES_ecb_encrypt(const unsigned char *in, unsigned char* out, - AES_KEY *key, const int enc) -{ - Aes* aes; - - WOLFSSL_ENTER("wolfSSL_AES_ecb_encrypt"); - - if (key == NULL || in == NULL || out == NULL) { - WOLFSSL_MSG("Error, Null argument passed in"); - return; - } - - aes = (Aes*)key; - if (enc == AES_ENCRYPT) { - if (wc_AesEcbEncrypt(aes, out, in, AES_BLOCK_SIZE) != 0) { - WOLFSSL_MSG("Error with AES CBC encrypt"); - } - } - else { - #ifdef HAVE_AES_DECRYPT - if (wc_AesEcbDecrypt(aes, out, in, AES_BLOCK_SIZE) != 0) { - WOLFSSL_MSG("Error with AES CBC decrypt"); - } - #else - WOLFSSL_MSG("AES decryption not compiled in"); - #endif - } -} -#endif /* HAVE_AES_ECB */ - -#ifdef HAVE_AES_CBC -/* Encrypt data using key and iv passed in. iv gets updated to most recent iv - * state after encryption/decryption. - * - * in buffer to encrypt/decrypt - * out buffer to hold result of encryption/decryption - * len length of input buffer - * key AES structure to use with encryption/decryption - * iv iv to use with operation - * enc 1 for encryption and 0 for decryption - */ -void wolfSSL_AES_cbc_encrypt(const unsigned char *in, unsigned char* out, - size_t len, AES_KEY *key, unsigned char* iv, const int enc) -{ - Aes* aes; - - WOLFSSL_ENTER("wolfSSL_AES_cbc_encrypt"); - - if (key == NULL || in == NULL || out == NULL || iv == NULL || len == 0) { - WOLFSSL_MSG("Error, Null argument passed in"); - return; - } - - aes = (Aes*)key; - if (wc_AesSetIV(aes, (const byte*)iv) != 0) { - WOLFSSL_MSG("Error with setting iv"); - return; - } - - if (enc == AES_ENCRYPT) { - if (wc_AesCbcEncrypt(aes, out, in, (word32)len) != 0) { - WOLFSSL_MSG("Error with AES CBC encrypt"); - return; - } - } - else { - if (wc_AesCbcDecrypt(aes, out, in, (word32)len) != 0) { - WOLFSSL_MSG("Error with AES CBC decrypt"); - return; - } - } - - /* to be compatible copy iv to iv buffer after completing operation */ - XMEMCPY(iv, (byte*)(aes->reg), AES_BLOCK_SIZE); -} -#endif /* HAVE_AES_CBC */ - - -/* Encrypt data using CFB mode with key and iv passed in. iv gets updated to - * most recent iv state after encryption/decryption. - * - * in buffer to encrypt/decrypt - * out buffer to hold result of encryption/decryption - * len length of input buffer - * key AES structure to use with encryption/decryption - * iv iv to use with operation - * num contains the amount of block used - * enc AES_ENCRYPT for encryption and AES_DECRYPT for decryption - */ -void wolfSSL_AES_cfb128_encrypt(const unsigned char *in, unsigned char* out, - size_t len, AES_KEY *key, unsigned char* iv, int* num, - const int enc) -{ -#ifndef WOLFSSL_AES_CFB - WOLFSSL_MSG("CFB mode not enabled please use macro WOLFSSL_AES_CFB"); - (void)in; - (void)out; - (void)len; - (void)key; - (void)iv; - (void)num; - (void)enc; - - return; -#else - Aes* aes; - - WOLFSSL_ENTER("wolfSSL_AES_cbc_encrypt"); - if (key == NULL || in == NULL || out == NULL || iv == NULL) { - WOLFSSL_MSG("Error, Null argument passed in"); - return; - } - - aes = (Aes*)key; - - /* - * We copy the IV directly into reg here because using wc_AesSetIV will - * clear the leftover bytes field "left", and this function relies on the - * leftover bytes being preserved between calls. - */ - XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE); - - if (enc == AES_ENCRYPT) { - if (wc_AesCfbEncrypt(aes, out, in, (word32)len) != 0) { - WOLFSSL_MSG("Error with AES CBC encrypt"); - return; - } - } - else { - if (wc_AesCfbDecrypt(aes, out, in, (word32)len) != 0) { - WOLFSSL_MSG("Error with AES CBC decrypt"); - return; - } - } - - /* to be compatible copy iv to iv buffer after completing operation */ - XMEMCPY(iv, (byte*)(aes->reg), AES_BLOCK_SIZE); - - /* store number of left over bytes to num */ - *num = (aes->left)? AES_BLOCK_SIZE - aes->left : 0; -#endif /* WOLFSSL_AES_CFB */ -} - -/* wc_AesKey*Wrap_ex API not available in FIPS and SELFTEST */ -#if defined(HAVE_AES_KEYWRAP) && !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) -int wolfSSL_AES_wrap_key(AES_KEY *key, const unsigned char *iv, - unsigned char *out, - const unsigned char *in, unsigned int inlen) -{ - int ret; - - WOLFSSL_ENTER("wolfSSL_AES_wrap_key"); - - if (out == NULL || in == NULL) { - WOLFSSL_MSG("Error, Null argument passed in"); - return WOLFSSL_FAILURE; - } - - ret = wc_AesKeyWrap_ex((Aes*)key, in, inlen, out, inlen + KEYWRAP_BLOCK_SIZE, iv); - - return ret < 0 ? WOLFSSL_FAILURE : ret; -} - -int wolfSSL_AES_unwrap_key(AES_KEY *key, const unsigned char *iv, - unsigned char *out, - const unsigned char *in, unsigned int inlen) -{ - int ret; - - WOLFSSL_ENTER("wolfSSL_AES_wrap_key"); - - if (out == NULL || in == NULL) { - WOLFSSL_MSG("Error, Null argument passed in"); - return WOLFSSL_FAILURE; - } - - ret = wc_AesKeyUnWrap_ex((Aes*)key, in, inlen, out, inlen + KEYWRAP_BLOCK_SIZE, iv); - - return ret < 0 ? WOLFSSL_FAILURE : ret; -} -#endif /* HAVE_AES_KEYWRAP && !HAVE_FIPS && !HAVE_SELFTEST */ - -#ifdef HAVE_CTS -/* - * Ciphertext stealing interface compatible with RFC2040 and RFC3962. - */ -size_t wolfSSL_CRYPTO_cts128_encrypt(const unsigned char *in, - unsigned char *out, size_t len, const void *key, - unsigned char *iv, WOLFSSL_CBC128_CB cbc) -{ - byte lastBlk[WOLFSSL_CTS128_BLOCK_SZ]; - int lastBlkLen = len % WOLFSSL_CTS128_BLOCK_SZ; - WOLFSSL_ENTER("wolfSSL_CRYPTO_cts128_encrypt"); - - if (in == NULL || out == NULL || len < WOLFSSL_CTS128_BLOCK_SZ || - cbc == NULL) { - WOLFSSL_MSG("Bad parameter"); - return WOLFSSL_FAILURE; - } - - if (lastBlkLen == 0) - lastBlkLen = WOLFSSL_CTS128_BLOCK_SZ; - - if (len - lastBlkLen != 0) { - /* Encrypt data up to last block */ - (*cbc)(in, out, len - lastBlkLen, key, iv, AES_ENCRYPT); - - /* Move to last block */ - in += len - lastBlkLen; - out += len - lastBlkLen; - } - - /* RFC2040: Pad Pn with zeros at the end to create P of length BB. */ - XMEMCPY(lastBlk, in, lastBlkLen); - XMEMSET(lastBlk + lastBlkLen, 0, WOLFSSL_CTS128_BLOCK_SZ - lastBlkLen); - /* RFC2040: Select the first Ln bytes of En-1 to create Cn */ - XMEMCPY(out, out - WOLFSSL_CTS128_BLOCK_SZ, lastBlkLen); - (*cbc)(lastBlk, out - WOLFSSL_CTS128_BLOCK_SZ, WOLFSSL_CTS128_BLOCK_SZ, - key, iv, AES_ENCRYPT); - - return len; -} - -size_t wolfSSL_CRYPTO_cts128_decrypt(const unsigned char *in, - unsigned char *out, size_t len, const void *key, - unsigned char *iv, WOLFSSL_CBC128_CB cbc) -{ - byte lastBlk[WOLFSSL_CTS128_BLOCK_SZ]; - byte prevBlk[WOLFSSL_CTS128_BLOCK_SZ]; - int lastBlkLen = len % WOLFSSL_CTS128_BLOCK_SZ; - WOLFSSL_ENTER("wolfSSL_CRYPTO_cts128_decrypt"); - - if (in == NULL || out == NULL || len <= WOLFSSL_CTS128_BLOCK_SZ || - cbc == NULL) { - WOLFSSL_MSG("Bad parameter"); - return WOLFSSL_FAILURE; - } - - if (lastBlkLen == 0) - lastBlkLen = WOLFSSL_CTS128_BLOCK_SZ; - - if (len - lastBlkLen - WOLFSSL_CTS128_BLOCK_SZ != 0) { - /* Decrypt up to last two blocks */ - (*cbc)(in, out, len - lastBlkLen - WOLFSSL_CTS128_BLOCK_SZ, key, iv, - AES_DECRYPTION); - - /* Move to last two blocks */ - in += len - lastBlkLen - WOLFSSL_CTS128_BLOCK_SZ; - out += len - lastBlkLen - WOLFSSL_CTS128_BLOCK_SZ; - } - - /* RFC2040: Decrypt Cn-1 to create Dn. - * Use 0 buffer as IV to do straight decryption. - * This places the Cn-1 block at lastBlk */ - XMEMSET(lastBlk, 0, WOLFSSL_CTS128_BLOCK_SZ); - (*cbc)(in, prevBlk, WOLFSSL_CTS128_BLOCK_SZ, key, lastBlk, AES_DECRYPT); - /* RFC2040: Append the tail (BB minus Ln) bytes of Xn to Cn - * to create En. */ - XMEMCPY(prevBlk, in + WOLFSSL_CTS128_BLOCK_SZ, lastBlkLen); - /* Cn and Cn-1 can now be decrypted */ - (*cbc)(prevBlk, out, WOLFSSL_CTS128_BLOCK_SZ, key, iv, AES_DECRYPT); - (*cbc)(lastBlk, lastBlk, WOLFSSL_CTS128_BLOCK_SZ, key, iv, AES_DECRYPT); - XMEMCPY(out + WOLFSSL_CTS128_BLOCK_SZ, lastBlk, lastBlkLen); - return len; -} -#endif /* HAVE_CTS */ -#endif /* NO_AES */ - #endif /* OPENSSL_EXTRA */ #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) @@ -25631,650 +23764,6 @@ const WOLFSSL_ObjectInfo wolfssl_object_info[] = { const size_t wolfssl_object_info_sz = WOLFSSL_OBJECT_INFO_SZ; #endif -#ifdef OPENSSL_EXTRA -WOLFSSL_HMAC_CTX* wolfSSL_HMAC_CTX_new(void) -{ - WOLFSSL_HMAC_CTX* hmac_ctx = (WOLFSSL_HMAC_CTX*)XMALLOC( - sizeof(WOLFSSL_HMAC_CTX), NULL, DYNAMIC_TYPE_OPENSSL); - if (hmac_ctx != NULL) { - XMEMSET(hmac_ctx, 0, sizeof(WOLFSSL_HMAC_CTX)); - } - return hmac_ctx; -} - -int wolfSSL_HMAC_CTX_Init(WOLFSSL_HMAC_CTX* ctx) -{ - WOLFSSL_MSG("wolfSSL_HMAC_CTX_Init"); - - if (ctx != NULL) { - /* wc_HmacSetKey sets up ctx->hmac */ - XMEMSET(ctx, 0, sizeof(WOLFSSL_HMAC_CTX)); - } - - return WOLFSSL_SUCCESS; -} - - -int wolfSSL_HMAC_Init_ex(WOLFSSL_HMAC_CTX* ctx, const void* key, - int keylen, const EVP_MD* type, WOLFSSL_ENGINE* e) -{ - WOLFSSL_ENTER("wolfSSL_HMAC_Init_ex"); - - /* WOLFSSL_ENGINE not used, call wolfSSL_HMAC_Init */ - (void)e; - return wolfSSL_HMAC_Init(ctx, key, keylen, type); -} - - -/* helper function for Deep copy of internal wolfSSL hmac structure - * returns WOLFSSL_SUCCESS on success */ -int wolfSSL_HmacCopy(Hmac* des, Hmac* src) -{ - void* heap; - int ret; - -#ifndef HAVE_FIPS - heap = src->heap; -#else - heap = NULL; -#endif - if (wc_HmacInit(des, heap, 0) != 0) { - return WOLFSSL_FAILURE; - } - - /* requires that hash structures have no dynamic parts to them */ - switch (src->macType) { - #ifndef NO_MD5 - case WC_MD5: - ret = wc_Md5Copy(&src->hash.md5, &des->hash.md5); - break; - #endif /* !NO_MD5 */ - - #ifndef NO_SHA - case WC_SHA: - ret = wc_ShaCopy(&src->hash.sha, &des->hash.sha); - break; - #endif /* !NO_SHA */ - - #ifdef WOLFSSL_SHA224 - case WC_SHA224: - ret = wc_Sha224Copy(&src->hash.sha224, &des->hash.sha224); - break; - #endif /* WOLFSSL_SHA224 */ - - #ifndef NO_SHA256 - case WC_SHA256: - ret = wc_Sha256Copy(&src->hash.sha256, &des->hash.sha256); - break; - #endif /* !NO_SHA256 */ - - #ifdef WOLFSSL_SHA384 - case WC_SHA384: - ret = wc_Sha384Copy(&src->hash.sha384, &des->hash.sha384); - break; - #endif /* WOLFSSL_SHA384 */ - #ifdef WOLFSSL_SHA512 - case WC_SHA512: - ret = wc_Sha512Copy(&src->hash.sha512, &des->hash.sha512); - break; - #endif /* WOLFSSL_SHA512 */ -#ifdef WOLFSSL_SHA3 - #ifndef WOLFSSL_NOSHA3_224 - case WC_SHA3_224: - ret = wc_Sha3_224_Copy(&src->hash.sha3, &des->hash.sha3); - break; - #endif /* WOLFSSL_NO_SHA3_224 */ - #ifndef WOLFSSL_NOSHA3_256 - case WC_SHA3_256: - ret = wc_Sha3_256_Copy(&src->hash.sha3, &des->hash.sha3); - break; - #endif /* WOLFSSL_NO_SHA3_256 */ - #ifndef WOLFSSL_NOSHA3_384 - case WC_SHA3_384: - ret = wc_Sha3_384_Copy(&src->hash.sha3, &des->hash.sha3); - break; - #endif /* WOLFSSL_NO_SHA3_384 */ - #ifndef WOLFSSL_NOSHA3_512 - case WC_SHA3_512: - ret = wc_Sha3_512_Copy(&src->hash.sha3, &des->hash.sha3); - break; - #endif /* WOLFSSL_NO_SHA3_512 */ -#endif /* WOLFSSL_SHA3 */ - - default: - return WOLFSSL_FAILURE; - } - - if (ret != 0) - return WOLFSSL_FAILURE; - - XMEMCPY((byte*)des->ipad, (byte*)src->ipad, WC_HMAC_BLOCK_SIZE); - XMEMCPY((byte*)des->opad, (byte*)src->opad, WC_HMAC_BLOCK_SIZE); - XMEMCPY((byte*)des->innerHash, (byte*)src->innerHash, WC_MAX_DIGEST_SIZE); -#ifndef HAVE_FIPS - des->heap = heap; -#endif - des->macType = src->macType; - des->innerHashKeyed = src->innerHashKeyed; - -#ifdef WOLFSSL_ASYNC_CRYPT - XMEMCPY(&des->asyncDev, &src->asyncDev, sizeof(WC_ASYNC_DEV)); - des->keyLen = src->keyLen; - #ifdef HAVE_CAVIUM - des->data = (byte*)XMALLOC(src->dataLen, des->heap, - DYNAMIC_TYPE_HMAC); - if (des->data == NULL) { - return BUFFER_E; - } - XMEMCPY(des->data, src->data, src->dataLen); - des->dataLen = src->dataLen; - #endif /* HAVE_CAVIUM */ -#endif /* WOLFSSL_ASYNC_CRYPT */ - return WOLFSSL_SUCCESS; -} - - -/* Deep copy of information from src to des structure - * - * des destination to copy information to - * src structure to get information from - * - * Returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on error - */ -int wolfSSL_HMAC_CTX_copy(WOLFSSL_HMAC_CTX* des, WOLFSSL_HMAC_CTX* src) -{ - WOLFSSL_ENTER("wolfSSL_HMAC_CTX_copy"); - - if (des == NULL || src == NULL) { - return WOLFSSL_FAILURE; - } - - des->type = src->type; - XMEMCPY((byte *)&des->save_ipad, (byte *)&src->hmac.ipad, - WC_HMAC_BLOCK_SIZE); - XMEMCPY((byte *)&des->save_opad, (byte *)&src->hmac.opad, - WC_HMAC_BLOCK_SIZE); - - return wolfSSL_HmacCopy(&des->hmac, &src->hmac); -} - -int wolfSSL_HMAC_Init(WOLFSSL_HMAC_CTX* ctx, const void* key, int keylen, - const EVP_MD* type) -{ - int hmac_error = 0; - void* heap = NULL; - int inited; - - WOLFSSL_MSG("wolfSSL_HMAC_Init"); - - if (ctx == NULL) { - WOLFSSL_MSG("no ctx on init"); - return WOLFSSL_FAILURE; - } - -#ifndef HAVE_FIPS - heap = ctx->hmac.heap; -#endif - - if (type) { - WOLFSSL_MSG("init has type"); - -#ifndef NO_MD5 - if (XSTRNCMP(type, "MD5", 3) == 0) { - WOLFSSL_MSG("md5 hmac"); - ctx->type = WC_MD5; - } - else -#endif -#ifdef WOLFSSL_SHA224 - if (XSTRNCMP(type, "SHA224", 6) == 0) { - WOLFSSL_MSG("sha224 hmac"); - ctx->type = WC_SHA224; - } - else -#endif -#ifndef NO_SHA256 - if (XSTRNCMP(type, "SHA256", 6) == 0) { - WOLFSSL_MSG("sha256 hmac"); - ctx->type = WC_SHA256; - } - else -#endif -#ifdef WOLFSSL_SHA384 - if (XSTRNCMP(type, "SHA384", 6) == 0) { - WOLFSSL_MSG("sha384 hmac"); - ctx->type = WC_SHA384; - } - else -#endif -#ifdef WOLFSSL_SHA512 - if (XSTRNCMP(type, "SHA512", 6) == 0) { - WOLFSSL_MSG("sha512 hmac"); - ctx->type = WC_SHA512; - } - else -#endif -#ifdef WOLFSSL_SHA3 - #ifndef WOLFSSL_NOSHA3_224 - if (XSTRNCMP(type, "SHA3_224", 8) == 0) { - WOLFSSL_MSG("sha3_224 hmac"); - ctx->type = WC_SHA3_224; - } - else - #endif - #ifndef WOLFSSL_NOSHA3_256 - if (XSTRNCMP(type, "SHA3_256", 8) == 0) { - WOLFSSL_MSG("sha3_256 hmac"); - ctx->type = WC_SHA3_256; - } - else - #endif - if (XSTRNCMP(type, "SHA3_384", 8) == 0) { - WOLFSSL_MSG("sha3_384 hmac"); - ctx->type = WC_SHA3_384; - } - else - #ifndef WOLFSSL_NOSHA3_512 - if (XSTRNCMP(type, "SHA3_512", 8) == 0) { - WOLFSSL_MSG("sha3_512 hmac"); - ctx->type = WC_SHA3_512; - } - else - #endif -#endif - -#ifndef NO_SHA - /* has to be last since would pick or 256, 384, or 512 too */ - if (XSTRNCMP(type, "SHA", 3) == 0) { - WOLFSSL_MSG("sha hmac"); - ctx->type = WC_SHA; - } - else -#endif - { - WOLFSSL_MSG("bad init type"); - return WOLFSSL_FAILURE; - } - } - - /* Check if init has been called before */ - inited = (ctx->hmac.macType != WC_HASH_TYPE_NONE); - /* Free if needed */ - if (inited) { - wc_HmacFree(&ctx->hmac); - } - if (key != NULL) { - WOLFSSL_MSG("keying hmac"); - - if (wc_HmacInit(&ctx->hmac, NULL, INVALID_DEVID) == 0) { - hmac_error = wc_HmacSetKey(&ctx->hmac, ctx->type, (const byte*)key, - (word32)keylen); - if (hmac_error < 0){ - /* in FIPS mode a key < 14 characters will fail here */ - WOLFSSL_MSG("hmac set key error"); - WOLFSSL_ERROR(hmac_error); - wc_HmacFree(&ctx->hmac); - return WOLFSSL_FAILURE; - } - XMEMCPY((byte *)&ctx->save_ipad, (byte *)&ctx->hmac.ipad, - WC_HMAC_BLOCK_SIZE); - XMEMCPY((byte *)&ctx->save_opad, (byte *)&ctx->hmac.opad, - WC_HMAC_BLOCK_SIZE); - } - /* OpenSSL compat, no error */ - } - else if (!inited) { - return WOLFSSL_FAILURE; - } - else if (ctx->type >= 0) { /* MD5 == 0 */ - WOLFSSL_MSG("recover hmac"); - if (wc_HmacInit(&ctx->hmac, NULL, INVALID_DEVID) == 0) { - ctx->hmac.macType = (byte)ctx->type; - ctx->hmac.innerHashKeyed = 0; - XMEMCPY((byte *)&ctx->hmac.ipad, (byte *)&ctx->save_ipad, - WC_HMAC_BLOCK_SIZE); - XMEMCPY((byte *)&ctx->hmac.opad, (byte *)&ctx->save_opad, - WC_HMAC_BLOCK_SIZE); - if ((hmac_error = _HMAC_Init(&ctx->hmac, ctx->hmac.macType, heap)) - !=0) { - WOLFSSL_MSG("hmac init error"); - WOLFSSL_ERROR(hmac_error); - return WOLFSSL_FAILURE; - } - } - } - - (void)hmac_error; - - return WOLFSSL_SUCCESS; -} - - -int wolfSSL_HMAC_Update(WOLFSSL_HMAC_CTX* ctx, const unsigned char* data, - int len) -{ - WOLFSSL_MSG("wolfSSL_HMAC_Update"); - - if (ctx == NULL) { - WOLFSSL_MSG("no ctx"); - return WOLFSSL_FAILURE; - } - - if (data) { - int hmac_error = 0; - - WOLFSSL_MSG("updating hmac"); - hmac_error = wc_HmacUpdate(&ctx->hmac, data, (word32)len); - if (hmac_error < 0){ - WOLFSSL_MSG("hmac update error"); - return WOLFSSL_FAILURE; - } - } - - return WOLFSSL_SUCCESS; -} - - -int wolfSSL_HMAC_Final(WOLFSSL_HMAC_CTX* ctx, unsigned char* hash, - unsigned int* len) -{ - int hmac_error; - - WOLFSSL_MSG("wolfSSL_HMAC_Final"); - - /* "len" parameter is optional. */ - if (ctx == NULL || hash == NULL) { - WOLFSSL_MSG("invalid parameter"); - return WOLFSSL_FAILURE; - } - - WOLFSSL_MSG("final hmac"); - hmac_error = wc_HmacFinal(&ctx->hmac, hash); - if (hmac_error < 0){ - WOLFSSL_MSG("final hmac error"); - return WOLFSSL_FAILURE; - } - - if (len) { - WOLFSSL_MSG("setting output len"); - switch (ctx->type) { - #ifndef NO_MD5 - case WC_MD5: - *len = WC_MD5_DIGEST_SIZE; - break; - #endif - - #ifndef NO_SHA - case WC_SHA: - *len = WC_SHA_DIGEST_SIZE; - break; - #endif - - #ifdef WOLFSSL_SHA224 - case WC_SHA224: - *len = WC_SHA224_DIGEST_SIZE; - break; - #endif - - #ifndef NO_SHA256 - case WC_SHA256: - *len = WC_SHA256_DIGEST_SIZE; - break; - #endif - - #ifdef WOLFSSL_SHA384 - case WC_SHA384: - *len = WC_SHA384_DIGEST_SIZE; - break; - #endif - - #ifdef WOLFSSL_SHA512 - case WC_SHA512: - *len = WC_SHA512_DIGEST_SIZE; - break; - #endif - - #ifdef WOLFSSL_SHA3 - #ifndef WOLFSSL_NOSHA3_224 - case WC_SHA3_224: - *len = WC_SHA3_224_DIGEST_SIZE; - break; - #endif - #ifndef WOLFSSL_NOSHA3_256 - case WC_SHA3_256: - *len = WC_SHA3_256_DIGEST_SIZE; - break; - #endif - #ifndef WOLFSSL_NOSHA3_384 - case WC_SHA3_384: - *len = WC_SHA3_384_DIGEST_SIZE; - break; - #endif - #ifndef WOLFSSL_NOSHA3_512 - case WC_SHA3_512: - *len = WC_SHA3_512_DIGEST_SIZE; - break; - #endif - #endif - - default: - WOLFSSL_MSG("bad hmac type"); - return WOLFSSL_FAILURE; - } - } - - return WOLFSSL_SUCCESS; -} - - -int wolfSSL_HMAC_cleanup(WOLFSSL_HMAC_CTX* ctx) -{ - WOLFSSL_MSG("wolfSSL_HMAC_cleanup"); - - if (ctx) { - wc_HmacFree(&ctx->hmac); - } - - return WOLFSSL_SUCCESS; -} - -void wolfSSL_HMAC_CTX_cleanup(WOLFSSL_HMAC_CTX* ctx) -{ - if (ctx) { - wolfSSL_HMAC_cleanup(ctx); - } -} - -void wolfSSL_HMAC_CTX_free(WOLFSSL_HMAC_CTX* ctx) -{ - if (ctx) { - wolfSSL_HMAC_CTX_cleanup(ctx); - XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL); - } -} - -size_t wolfSSL_HMAC_size(const WOLFSSL_HMAC_CTX *ctx) -{ - if (!ctx) { - return 0; - } - - return (size_t)wc_HashGetDigestSize((enum wc_HashType)ctx->hmac.macType); -} - -const WOLFSSL_EVP_MD *wolfSSL_HMAC_CTX_get_md(const WOLFSSL_HMAC_CTX *ctx) -{ - if (!ctx) { - return NULL; - } - - return wolfSSL_macType2EVP_md((enum wc_HashType)ctx->type); -} - -#if defined(WOLFSSL_CMAC) && defined(OPENSSL_EXTRA) && \ - defined(WOLFSSL_AES_DIRECT) -WOLFSSL_CMAC_CTX* wolfSSL_CMAC_CTX_new(void) -{ - WOLFSSL_CMAC_CTX* ctx = NULL; - - ctx = (WOLFSSL_CMAC_CTX*)XMALLOC(sizeof(WOLFSSL_CMAC_CTX), NULL, - DYNAMIC_TYPE_OPENSSL); - if (ctx != NULL) { - ctx->internal = (Cmac*)XMALLOC(sizeof(Cmac), NULL, DYNAMIC_TYPE_CMAC); - if (ctx->internal == NULL) { - XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL); - ctx = NULL; - } - } - if (ctx != NULL) { - ctx->cctx = wolfSSL_EVP_CIPHER_CTX_new(); - if (ctx->cctx == NULL) { - XFREE(ctx->internal, NULL, DYNAMIC_TYPE_CMAC); - XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL); - ctx = NULL; - } - } - - return ctx; -} - -void wolfSSL_CMAC_CTX_free(WOLFSSL_CMAC_CTX *ctx) -{ - if (ctx != NULL) { - if (ctx->internal != NULL) { - XFREE(ctx->internal, NULL, DYNAMIC_TYPE_CMAC); - } - if (ctx->cctx != NULL) { - wolfSSL_EVP_CIPHER_CTX_free(ctx->cctx); - } - XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL); - } -} - -WOLFSSL_EVP_CIPHER_CTX* wolfSSL_CMAC_CTX_get0_cipher_ctx(WOLFSSL_CMAC_CTX* ctx) -{ - WOLFSSL_EVP_CIPHER_CTX* cctx = NULL; - - if (ctx != NULL) { - cctx = ctx->cctx; - } - - return cctx; -} - -int wolfSSL_CMAC_Init(WOLFSSL_CMAC_CTX* ctx, const void *key, size_t keyLen, - const WOLFSSL_EVP_CIPHER* cipher, WOLFSSL_ENGINE* engine) -{ - int ret = WOLFSSL_SUCCESS; - - (void)engine; - - WOLFSSL_ENTER("wolfSSL_CMAC_Init"); - - if (ctx == NULL || cipher == NULL || ( - cipher != EVP_AES_128_CBC && - cipher != EVP_AES_192_CBC && - cipher != EVP_AES_256_CBC)) { - ret = WOLFSSL_FAILURE; - } - - if (ret == WOLFSSL_SUCCESS) { - /* Check input keyLen matches input cipher. */ - if ((int) keyLen != wolfSSL_EVP_Cipher_key_length(cipher)) { - ret = WOLFSSL_FAILURE; - } - } - - if (ret == WOLFSSL_SUCCESS) { - ret = wc_InitCmac((Cmac*)ctx->internal, (const byte*)key, - (word32)keyLen, WC_CMAC_AES, NULL); - if (ret != 0) { - ret = WOLFSSL_FAILURE; - } - else { - ret = WOLFSSL_SUCCESS; - } - } - if (ret == WOLFSSL_SUCCESS) { - ret = wolfSSL_EVP_CipherInit(ctx->cctx, cipher, (const byte*)key, NULL, - 1); - } - - WOLFSSL_LEAVE("wolfSSL_CMAC_Init", ret); - - return ret; -} - -int wolfSSL_CMAC_Update(WOLFSSL_CMAC_CTX* ctx, const void* data, size_t len) -{ - int ret = WOLFSSL_SUCCESS; - - WOLFSSL_ENTER("wolfSSL_CMAC_Update"); - - if (ctx == NULL || ctx->internal == NULL) { - ret = WOLFSSL_FAILURE; - } - - if (ret == WOLFSSL_SUCCESS) { - if (data) { - ret = wc_CmacUpdate((Cmac*)ctx->internal, (const byte*)data, - (word32)len); - if (ret != 0){ - ret = WOLFSSL_FAILURE; - } - else { - ret = WOLFSSL_SUCCESS; - } - } - } - - WOLFSSL_LEAVE("wolfSSL_CMAC_Update", ret); - - return ret; -} - -int wolfSSL_CMAC_Final(WOLFSSL_CMAC_CTX* ctx, unsigned char* out, - size_t* len) -{ - int ret = WOLFSSL_SUCCESS; - int blockSize; - - WOLFSSL_ENTER("wolfSSL_CMAC_Final"); - - if (ctx == NULL || ctx->cctx == NULL || ctx->internal == NULL || - len == NULL) { - ret = WOLFSSL_FAILURE; - } - - if (ret == WOLFSSL_SUCCESS) { - blockSize = EVP_CIPHER_CTX_block_size(ctx->cctx); - if (blockSize <= 0) { - ret = WOLFSSL_FAILURE; - } - else { - *len = blockSize; - } - } - if (ret == WOLFSSL_SUCCESS) { - word32 len32 = (word32)*len; - - ret = wc_CmacFinal((Cmac*)ctx->internal, out, &len32); - *len = (size_t)len32; - if (ret != 0) { - ret = WOLFSSL_FAILURE; - } - else { - ret = WOLFSSL_SUCCESS; - } - } - - WOLFSSL_LEAVE("wolfSSL_CMAC_Final", ret); - - return ret; -} -#endif /* WOLFSSL_CMAC && OPENSSL_EXTRA && WOLFSSL_AES_DIRECT */ -#endif /* OPENSSL_EXTRA */ - #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) /* Free the dynamically allocated data. * @@ -38134,252 +35623,3 @@ void wolfSSL_FIPS_drbg_set_app_data(WOLFSSL_DRBG_CTX *ctx, void *app_data) #endif /* !WOLFCRYPT_ONLY */ -/******************************************************************************* - * START OF CRYPTO-ONLY APIs - ******************************************************************************/ - -#if defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) || \ - defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL) || \ - defined(WOLFSSL_NGINX) || defined(HAVE_POCO_LIB) || \ - defined(WOLFSSL_HAPROXY) - -#ifndef NO_SHA - /* One shot SHA1 hash of message. - * - * d message to hash - * n size of d buffer - * md buffer to hold digest. Should be SHA_DIGEST_SIZE. - * - * Note: if md is null then a static buffer of SHA_DIGEST_SIZE is used. - * When the static buffer is used this function is not thread safe. - * - * Returns a pointer to the message digest on success and NULL on failure. - */ - unsigned char *wolfSSL_SHA1(const unsigned char *d, size_t n, - unsigned char *md) - { - static byte dig[WC_SHA_DIGEST_SIZE]; - byte* ret = md; - wc_Sha sha; - - WOLFSSL_ENTER("wolfSSL_SHA1"); - - if (wc_InitSha_ex(&sha, NULL, INVALID_DEVID) != 0) { - WOLFSSL_MSG("SHA1 Init failed"); - return NULL; - } - - if (wc_ShaUpdate(&sha, (const byte*)d, (word32)n) != 0) { - WOLFSSL_MSG("SHA1 Update failed"); - return NULL; - } - - if (md == NULL) { - WOLFSSL_MSG("STATIC BUFFER BEING USED. wolfSSL_SHA1 IS NOT " - "THREAD SAFE WHEN md == NULL"); - ret = dig; - } - if (wc_ShaFinal(&sha, ret) != 0) { - WOLFSSL_MSG("SHA1 Final failed"); - wc_ShaFree(&sha); - return NULL; - } - wc_ShaFree(&sha); - - return ret; - } -#endif /* ! NO_SHA */ - -#ifdef WOLFSSL_SHA224 - /* One shot SHA224 hash of message. - * - * d message to hash - * n size of d buffer - * md buffer to hold digest. Should be WC_SHA224_DIGEST_SIZE. - * - * Note: if md is null then a static buffer of WC_SHA256_DIGEST_SIZE is used. - * When the static buffer is used this function is not thread safe. - * - * Returns a pointer to the message digest on success and NULL on failure. - */ - unsigned char *wolfSSL_SHA224(const unsigned char *d, size_t n, - unsigned char *md) - { - static byte dig[WC_SHA224_DIGEST_SIZE]; - byte* ret = md; - wc_Sha256 sha; - - WOLFSSL_ENTER("wolfSSL_SHA224"); - - if (wc_InitSha224_ex(&sha, NULL, INVALID_DEVID) != 0) { - WOLFSSL_MSG("SHA224 Init failed"); - return NULL; - } - - if (wc_Sha224Update(&sha, (const byte*)d, (word32)n) != 0) { - WOLFSSL_MSG("SHA224 Update failed"); - return NULL; - } - - if (md == NULL) { - WOLFSSL_MSG("STATIC BUFFER BEING USED. wolfSSL_SHA224 IS NOT " - "THREAD SAFE WHEN md == NULL"); - ret = dig; - } - if (wc_Sha224Final(&sha, ret) != 0) { - WOLFSSL_MSG("SHA224 Final failed"); - wc_Sha224Free(&sha); - return NULL; - } - wc_Sha224Free(&sha); - - return ret; - } -#endif - -#ifndef NO_SHA256 - /* One shot SHA256 hash of message. - * - * d message to hash - * n size of d buffer - * md buffer to hold digest. Should be WC_SHA256_DIGEST_SIZE. - * - * Note: if md is null then a static buffer of WC_SHA256_DIGEST_SIZE is used. - * When the static buffer is used this function is not thread safe. - * - * Returns a pointer to the message digest on success and NULL on failure. - */ - unsigned char *wolfSSL_SHA256(const unsigned char *d, size_t n, - unsigned char *md) - { - static byte dig[WC_SHA256_DIGEST_SIZE]; - byte* ret = md; - wc_Sha256 sha; - - WOLFSSL_ENTER("wolfSSL_SHA256"); - - if (wc_InitSha256_ex(&sha, NULL, INVALID_DEVID) != 0) { - WOLFSSL_MSG("SHA256 Init failed"); - return NULL; - } - - if (wc_Sha256Update(&sha, (const byte*)d, (word32)n) != 0) { - WOLFSSL_MSG("SHA256 Update failed"); - return NULL; - } - - if (md == NULL) { - WOLFSSL_MSG("STATIC BUFFER BEING USED. wolfSSL_SHA256 IS NOT " - "THREAD SAFE WHEN md == NULL"); - ret = dig; - } - if (wc_Sha256Final(&sha, ret) != 0) { - WOLFSSL_MSG("SHA256 Final failed"); - wc_Sha256Free(&sha); - return NULL; - } - wc_Sha256Free(&sha); - - return ret; - } -#endif /* ! NO_SHA256 */ - -#ifdef WOLFSSL_SHA384 - /* One shot SHA384 hash of message. - * - * d message to hash - * n size of d buffer - * md buffer to hold digest. Should be WC_SHA256_DIGEST_SIZE. - * - * Note: if md is null then a static buffer of WC_SHA256_DIGEST_SIZE is used. - * When the static buffer is used this function is not thread safe. - * - * Returns a pointer to the message digest on success and NULL on failure. - */ - unsigned char *wolfSSL_SHA384(const unsigned char *d, size_t n, - unsigned char *md) - { - static byte dig[WC_SHA384_DIGEST_SIZE]; - byte* ret = md; - wc_Sha384 sha; - - WOLFSSL_ENTER("wolfSSL_SHA384"); - - if (wc_InitSha384_ex(&sha, NULL, INVALID_DEVID) != 0) { - WOLFSSL_MSG("SHA384 Init failed"); - return NULL; - } - - if (wc_Sha384Update(&sha, (const byte*)d, (word32)n) != 0) { - WOLFSSL_MSG("SHA384 Update failed"); - return NULL; - } - - if (md == NULL) { - WOLFSSL_MSG("STATIC BUFFER BEING USED. wolfSSL_SHA384 IS NOT " - "THREAD SAFE WHEN md == NULL"); - ret = dig; - } - if (wc_Sha384Final(&sha, ret) != 0) { - WOLFSSL_MSG("SHA384 Final failed"); - wc_Sha384Free(&sha); - return NULL; - } - wc_Sha384Free(&sha); - - return ret; - } -#endif /* WOLFSSL_SHA384 */ - -#if defined(WOLFSSL_SHA512) - /* One shot SHA512 hash of message. - * - * d message to hash - * n size of d buffer - * md buffer to hold digest. Should be WC_SHA256_DIGEST_SIZE. - * - * Note: if md is null then a static buffer of WC_SHA256_DIGEST_SIZE is used. - * When the static buffer is used this function is not thread safe. - * - * Returns a pointer to the message digest on success and NULL on failure. - */ - unsigned char *wolfSSL_SHA512(const unsigned char *d, size_t n, - unsigned char *md) - { - static byte dig[WC_SHA512_DIGEST_SIZE]; - byte* ret = md; - wc_Sha512 sha; - - WOLFSSL_ENTER("wolfSSL_SHA512"); - - if (wc_InitSha512_ex(&sha, NULL, INVALID_DEVID) != 0) { - WOLFSSL_MSG("SHA512 Init failed"); - return NULL; - } - - if (wc_Sha512Update(&sha, (const byte*)d, (word32)n) != 0) { - WOLFSSL_MSG("SHA512 Update failed"); - return NULL; - } - - if (md == NULL) { - WOLFSSL_MSG("STATIC BUFFER BEING USED. wolfSSL_SHA512 IS NOT " - "THREAD SAFE WHEN md == NULL"); - ret = dig; - } - if (wc_Sha512Final(&sha, ret) != 0) { - WOLFSSL_MSG("SHA512 Final failed"); - wc_Sha512Free(&sha); - return NULL; - } - wc_Sha512Free(&sha); - - return ret; - } -#endif /* WOLFSSL_SHA512 */ -#endif /* OPENSSL_EXTRA || HAVE_LIGHTY || WOLFSSL_MYSQL_COMPATIBLE || - * HAVE_STUNNEL || WOLFSSL_NGINX || HAVE_POCO_LIB || WOLFSSL_HAPROXY */ - -/******************************************************************************* - * END OF CRYPTO-ONLY APIs - ******************************************************************************/ diff --git a/src/ssl_certman.c b/src/ssl_certman.c index c7eeb8bc9..65a6c5599 100644 --- a/src/ssl_certman.c +++ b/src/ssl_certman.c @@ -844,7 +844,9 @@ int wolfSSL_CertManagerVerify(WOLFSSL_CERT_MANAGER* cm, const char* fname, if (buff != staticBuffer) #endif { - XFREE(buff, cm->heap, DYNAMIC_TYPE_FILE); + if (cm != NULL) { + XFREE(buff, cm->heap, DYNAMIC_TYPE_FILE); + } } return ret; } diff --git a/src/ssl_crypto.c b/src/ssl_crypto.c new file mode 100644 index 000000000..591e69c21 --- /dev/null +++ b/src/ssl_crypto.c @@ -0,0 +1,3476 @@ +/* ssl_crypto.c + * + * Copyright (C) 2006-2023 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 + */ + + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#ifndef WOLFSSL_SSL_CRYPTO_INCLUDED + #ifndef WOLFSSL_IGNORE_FILE_WARN + #warning ssl_crypto.c does not need to be compiled separately from ssl.c + #endif +#else + +/******************************************************************************* + * START OF Digest APIs + ******************************************************************************/ + +#ifdef OPENSSL_EXTRA +#ifndef NO_MD4 +/* Initialize MD4 hash operation. + * + * @param [in, out] md4 MD4 context object. + */ +void wolfSSL_MD4_Init(WOLFSSL_MD4_CTX* md4) +{ + /* Ensure WOLFSSL_MD4_CTX is big enough for wolfCrypt Md4. */ + typedef char ok[sizeof(md4->buffer) >= sizeof(Md4) ? 1 : -1]; + (void)sizeof(ok); + + WOLFSSL_ENTER("MD4_Init"); + + /* Initialize wolfCrypt MD4 object. */ + wc_InitMd4((Md4*)md4); +} + +/* Update MD4 hash with data. + * + * @param [in, out] md4 MD4 context object. + * @param [in] data Data to be hashed. + * @param [in] len Length of data in bytes. + */ +void wolfSSL_MD4_Update(WOLFSSL_MD4_CTX* md4, const void* data, + unsigned long len) +{ + WOLFSSL_ENTER("MD4_Update"); + + /* Update wolfCrypt MD4 object with data. */ + wc_Md4Update((Md4*)md4, (const byte*)data, (word32)len); +} + +/* Finalize MD4 hash and return output. + * + * @param [out] digest Hash output. + * Must be able to hold MD4_DIGEST_SIZE bytes. + * @param [in, out] md4 MD4 context object. + */ +void wolfSSL_MD4_Final(unsigned char* digest, WOLFSSL_MD4_CTX* md4) +{ + WOLFSSL_ENTER("MD4_Final"); + + /* Finalize wolfCrypt MD4 hash into digest. */ + wc_Md4Final((Md4*)md4, digest); +} + +#endif /* NO_MD4 */ +#endif /* OPENSSL_EXTRA */ + +#if defined(OPENSSL_EXTRA) || defined(HAVE_CURL) +#ifndef NO_MD5 +/* Initialize MD5 hash operation. + * + * @param [in, out] md5 MD5 context object. + * @return 1 on success. + * @return 0 when md5 is NULL. + */ +int wolfSSL_MD5_Init(WOLFSSL_MD5_CTX* md5) +{ + /* Ensure WOLFSSL_MD5_CTX is big enough for wolfCrypt wc_Md5. */ + typedef char md5_test[sizeof(WOLFSSL_MD5_CTX) >= sizeof(wc_Md5) ? 1 : -1]; + (void)sizeof(md5_test); + + WOLFSSL_ENTER("MD5_Init"); + + /* Initialize wolfCrypt MD5 object. */ + return wc_InitMd5((wc_Md5*)md5) == 0; +} + +/* Update MD5 hash with data. + * + * @param [in, out] md5 MD5 context object. + * @param [in] input Data to be hashed. + * @param [in] sz Length of data in bytes. + * @return 1 on success. + * @return 0 when md5 is NULL. + */ +int wolfSSL_MD5_Update(WOLFSSL_MD5_CTX* md5, const void* input, + unsigned long sz) +{ + WOLFSSL_ENTER("MD5_Update"); + + /* Update wolfCrypt MD5 object with data. */ + return wc_Md5Update((wc_Md5*)md5, (const byte*)input, (word32)sz) == 0; +} + +/* Finalize MD5 hash and return output. + * + * @param [out] digest Hash output. + * Must be able to hold MD5_DIGEST_SIZE bytes. + * @param [in, out] md5 MD5 context object. + * @return 1 on success. + * @return 0 when md5 or output is NULL. + */ +int wolfSSL_MD5_Final(byte* output, WOLFSSL_MD5_CTX* md5) +{ + int ret; + + WOLFSSL_ENTER("MD5_Final"); + + /* Finalize wolfCrypt MD5 hash into output. */ + ret = (wc_Md5Final((wc_Md5*)md5, output) == 0); + /* Free resources here, as OpenSSL API doesn't include MD5_Free(). */ + wc_Md5Free((wc_Md5*)md5); + + return ret; +} + +/* Apply MD5 transformation to the data. + * + * 'data' has words reversed in this function when big endian. + * + * @param [in, out] md5 MD5 context object. + * @param [in, out] data One block of data to be hashed. + * @return 1 on success. + * @return 0 when md5 or data is NULL. + */ +int wolfSSL_MD5_Transform(WOLFSSL_MD5_CTX* md5, const unsigned char* data) +{ + WOLFSSL_ENTER("MD5_Transform"); + +#if defined(BIG_ENDIAN_ORDER) + /* Byte reversal done outside transform. */ + if ((md5 != NULL) && (data != NULL)) { + ByteReverseWords((word32*)data, (word32*)data, WC_MD5_BLOCK_SIZE); + } +#endif + /* Transform block of data with wolfCrypt MD5 object. */ + return wc_Md5Transform((wc_Md5*)md5, data) == 0; +} + +/* One shot MD5 hash of data. + * + * When hash is null, a static buffer of MD5_DIGEST_SIZE is used. + * When the static buffer is used this function is not thread safe. + * + * @param [in] data Data to be hashed. + * @param [in] len Length of data in bytes. + * @param [out] hash Buffer to hold digest. May be NULL. + * Must be able to hold MD5_DIGEST_SIZE bytes. + * @return Buffer holding hash on success. + * @return NULL when hashing fails. + */ +unsigned char* wolfSSL_MD5(const unsigned char* data, size_t len, + unsigned char* hash) +{ + /* Buffer to use when hash is NULL. */ + static unsigned char dgst[WC_MD5_DIGEST_SIZE]; + + WOLFSSL_ENTER("wolfSSL_MD5"); + + /* Ensure buffer available for digest result. */ + if (hash == NULL) { + hash = dgst; + } + /* One shot MD5 hash with wolfCrypt. */ + if (wc_Md5Hash(data, (word32)len, hash) != 0) { + WOLFSSL_MSG("wc_Md5Hash error"); + hash = NULL; + } + + return hash; +} +#endif /* !NO_MD5 */ + +#ifndef NO_SHA +/* Initialize SHA hash operation. + * + * @param [in, out] sha SHA context object. + * @return 1 on success. + * @return 0 when sha is NULL. + */ +int wolfSSL_SHA_Init(WOLFSSL_SHA_CTX* sha) +{ + /* Ensure WOLFSSL_SHA_CTX is big enough for wolfCrypt wc_Sha. */ + typedef char sha_test[sizeof(WOLFSSL_SHA_CTX) >= sizeof(wc_Sha) ? 1 : -1]; + (void)sizeof(sha_test); + + WOLFSSL_ENTER("SHA_Init"); + + /* Initialize wolfCrypt SHA object. */ + return wc_InitSha((wc_Sha*)sha) == 0; +} + +/* Update SHA hash with data. + * + * @param [in, out] sha SHA context object. + * @param [in] input Data to be hashed. + * @param [in] sz Length of data in bytes. + * @return 1 on success. + * @return 0 when md5 is NULL. + */ +int wolfSSL_SHA_Update(WOLFSSL_SHA_CTX* sha, const void* input, + unsigned long sz) +{ + WOLFSSL_ENTER("SHA_Update"); + + /* Update wolfCrypt SHA object with data. */ + return wc_ShaUpdate((wc_Sha*)sha, (const byte*)input, (word32)sz) == 0; +} + +/* Finalize SHA hash and return output. + * + * @param [out] output Hash output. + * Must be able to hold SHA_DIGEST_SIZE bytes. + * @param [in, out] sha SHA context object. + * @return 1 on success. + * @return 0 when sha or output is NULL. + */ +int wolfSSL_SHA_Final(byte* output, WOLFSSL_SHA_CTX* sha) +{ + int ret; + + WOLFSSL_ENTER("SHA_Final"); + + /* Finalize wolfCrypt SHA hash into output. */ + ret = (wc_ShaFinal((wc_Sha*)sha, output) == 0); + /* Free resources here, as OpenSSL API doesn't include SHA_Free(). */ + wc_ShaFree((wc_Sha*)sha); + + return ret; +} + +#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) +/* Apply SHA transformation to the data. + * + * 'data' has words reversed in this function when little endian. + * + * @param [in, out] sha SHA context object. + * @param [in, out] data One block of data to be hashed. + * @return 1 on success. + * @return 0 when sha or data is NULL. + */ +int wolfSSL_SHA_Transform(WOLFSSL_SHA_CTX* sha, const unsigned char* data) +{ + WOLFSSL_ENTER("SHA_Transform"); + +#if defined(LITTLE_ENDIAN_ORDER) + /* Byte reversal done outside transform. */ + if ((sha != NULL) && (data != NULL)) { + ByteReverseWords((word32*)data, (word32*)data, WC_SHA_BLOCK_SIZE); + } +#endif + /* Transform block of data with wolfCrypt SHA object. */ + return wc_ShaTransform((wc_Sha*)sha, data) == 0; +} +#endif + +/* Initialize SHA-1 hash operation. + * + * @param [in, out] sha SHA context object. + * @return 1 on success. + * @return 0 when sha is NULL. + */ +int wolfSSL_SHA1_Init(WOLFSSL_SHA_CTX* sha) +{ + WOLFSSL_ENTER("SHA1_Init"); + + return SHA_Init(sha); +} + + +/* Update SHA-1 hash with data. + * + * @param [in, out] sha SHA context object. + * @param [in] input Data to be hashed. + * @param [in] sz Length of data in bytes. + * @return 1 on success. + * @return 0 when sha is NULL. + */ +int wolfSSL_SHA1_Update(WOLFSSL_SHA_CTX* sha, const void* input, + unsigned long sz) +{ + WOLFSSL_ENTER("SHA1_Update"); + + return SHA_Update(sha, input, sz); +} + +/* Finalize SHA-1 hash and return output. + * + * @param [out] output Hash output. + * Must be able to hold SHA_DIGEST_SIZE bytes. + * @param [in, out] sha SHA context object. + * @return 1 on success. + * @return 0 when sha or output is NULL. + */ +int wolfSSL_SHA1_Final(byte* output, WOLFSSL_SHA_CTX* sha) +{ + WOLFSSL_ENTER("SHA1_Final"); + + return SHA_Final(output, sha); +} + +#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) +/* Apply SHA-1 transformation to the data. + * + * 'data' has words reversed in this function when little endian. + * + * @param [in, out] sha SHA context object. + * @param [in, out] data One block of data to be hashed. + * @return 1 on success. + * @return 0 when sha or data is NULL. + */ +int wolfSSL_SHA1_Transform(WOLFSSL_SHA_CTX* sha, const unsigned char* data) +{ + WOLFSSL_ENTER("SHA1_Transform"); + + return wolfSSL_SHA_Transform(sha, data); +} +#endif +#endif /* !NO_SHA */ + +#ifndef NO_SHA256 +#ifdef WOLFSSL_SHA224 +/* Initialize SHA-224 hash operation. + * + * @param [in, out] sha224 SHA-224 context object. + * @return 1 on success. + * @return 0 when sha224 is NULL. + */ +int wolfSSL_SHA224_Init(WOLFSSL_SHA224_CTX* sha224) +{ + /* Ensure WOLFSSL_SHA224_CTX is big enough for wolfCrypt wc_Sha224. */ + typedef char sha_test[sizeof(SHA224_CTX) >= sizeof(wc_Sha224) ? 1 : -1]; + (void)sizeof(sha_test); + + WOLFSSL_ENTER("SHA224_Init"); + + /* Initialize wolfCrypt SHA-224 object. */ + return wc_InitSha224((wc_Sha224*)sha224) == 0; +} + +/* Update SHA-224 hash with data. + * + * @param [in, out] sha224 SHA-224 context object. + * @param [in] input Data to be hashed. + * @param [in] sz Length of data in bytes. + * @return 1 on success. + * @return 0 when sha224 is NULL. + */ +int wolfSSL_SHA224_Update(WOLFSSL_SHA224_CTX* sha224, const void* input, + unsigned long sz) +{ + WOLFSSL_ENTER("SHA224_Update"); + + /* Update wolfCrypt SHA-224 object with data. */ + return wc_Sha224Update((wc_Sha224*)sha224, (const byte*)input, (word32)sz) + == 0; +} + +/* Finalize SHA-224 hash and return output. + * + * @param [out] output Hash output. + * Must be able to hold SHA224_DIGEST_SIZE bytes. + * @param [in, out] sha224 SHA-224 context object. + * @return 1 on success. + * @return 0 when sha224 or output is NULL. + */ +int wolfSSL_SHA224_Final(byte* output, WOLFSSL_SHA224_CTX* sha224) +{ + int ret; + + WOLFSSL_ENTER("SHA224_Final"); + + /* Finalize wolfCrypt SHA-224 hash into output. */ + ret = (wc_Sha224Final((wc_Sha224*)sha224, output) == 0); + /* Free resources here, as OpenSSL API doesn't include SHA224_Free(). */ + wc_Sha224Free((wc_Sha224*)sha224); + + return ret; +} + +#endif /* WOLFSSL_SHA224 */ + +/* Initialize SHA-256 hash operation. + * + * @param [in, out] sha256 SHA-256 context object. + * @return 1 on success. + * @return 0 when sha256 is NULL. + */ +int wolfSSL_SHA256_Init(WOLFSSL_SHA256_CTX* sha256) +{ + /* Ensure WOLFSSL_SHA256_CTX is big enough for wolfCrypt wc_Sha256. */ + typedef char sha_test[sizeof(SHA256_CTX) >= sizeof(wc_Sha256) ? 1 : -1]; + (void)sizeof(sha_test); + + WOLFSSL_ENTER("SHA256_Init"); + + /* Initialize wolfCrypt SHA-256 object. */ + return wc_InitSha256((wc_Sha256*)sha256) == 0; +} + +/* Update SHA-256 hash with data. + * + * @param [in, out] sha256 SHA-256 context object. + * @param [in] input Data to be hashed. + * @param [in] sz Length of data in bytes. + * @return 1 on success. + * @return 0 when sha256 is NULL. + */ +int wolfSSL_SHA256_Update(WOLFSSL_SHA256_CTX* sha256, const void* input, + unsigned long sz) +{ + WOLFSSL_ENTER("SHA256_Update"); + + /* Update wolfCrypt SHA-256 object with data. */ + return wc_Sha256Update((wc_Sha256*)sha256, (const byte*)input, (word32)sz) + == 0; +} + +/* Finalize SHA-256 hash and return output. + * + * @param [out] output Hash output. + * Must be able to hold SHA256_DIGEST_SIZE bytes. + * @param [in, out] sha256 SHA-256 context object. + * @return 1 on success. + * @return 0 when sha256 or output is NULL. + */ +int wolfSSL_SHA256_Final(byte* output, WOLFSSL_SHA256_CTX* sha256) +{ + int ret; + + WOLFSSL_ENTER("SHA256_Final"); + + /* Finalize wolfCrypt SHA-256 hash into output. */ + ret = (wc_Sha256Final((wc_Sha256*)sha256, output) == 0); + /* Free resources here, as OpenSSL API doesn't include SHA256_Free(). */ + wc_Sha256Free((wc_Sha256*)sha256); + + return ret; +} + +#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) && \ + !defined(WOLFSSL_DEVCRYPTO_HASH) && !defined(WOLFSSL_AFALG_HASH) && \ + !defined(WOLFSSL_KCAPI_HASH) /* doesn't support direct transform */ +/* Apply SHA-256 transformation to the data. + * + * 'data' has words reversed in this function when little endian. + * + * @param [in, out] sha256 SHA256 context object. + * @param [in, out] data One block of data to be hashed. + * @return 1 on success. + * @return 0 when sha256 or data is NULL. + */ +int wolfSSL_SHA256_Transform(WOLFSSL_SHA256_CTX* sha256, + const unsigned char* data) +{ + WOLFSSL_ENTER("SHA256_Transform"); + +#if defined(LITTLE_ENDIAN_ORDER) + /* Byte reversal done outside transform. */ + if ((sha256 != NULL) && (data != NULL)) { + ByteReverseWords((word32*)data, (word32*)data, WC_SHA256_BLOCK_SIZE); + } +#endif + /* Transform block of data with wolfCrypt SHA-256 object. */ + return wc_Sha256Transform((wc_Sha256*)sha256, data) == 0; +} +#endif +#endif /* !NO_SHA256 */ + +#ifdef WOLFSSL_SHA384 + +/* Initialize SHA-384 hash operation. + * + * @param [in, out] sha384 SHA-384 context object. + * @return 1 on success. + * @return 0 when sha384 is NULL. + */ +int wolfSSL_SHA384_Init(WOLFSSL_SHA384_CTX* sha384) +{ + /* Ensure WOLFSSL_SHA384_CTX is big enough for wolfCrypt wc_Sha384. */ + typedef char sha_test[sizeof(SHA384_CTX) >= sizeof(wc_Sha384) ? 1 : -1]; + (void)sizeof(sha_test); + + WOLFSSL_ENTER("SHA384_Init"); + + /* Initialize wolfCrypt SHA-384 object. */ + return wc_InitSha384((wc_Sha384*)sha384) == 0; +} + +/* Update SHA-384 hash with data. + * + * @param [in, out] sha384 SHA-384 context object. + * @param [in] input Data to be hashed. + * @param [in] sz Length of data in bytes. + * @return 1 on success. + * @return 0 when sha384 is NULL. + */ +int wolfSSL_SHA384_Update(WOLFSSL_SHA384_CTX* sha384, const void* input, + unsigned long sz) +{ + WOLFSSL_ENTER("SHA384_Update"); + + /* Update wolfCrypt SHA-384 object with data. */ + return wc_Sha384Update((wc_Sha384*)sha384, (const byte*)input, (word32)sz) + == 0; +} + +/* Finalize SHA-384 hash and return output. + * + * @param [out] output Hash output. + * Must be able to hold SHA384_DIGEST_SIZE bytes. + * @param [in, out] sha384 SHA-384 context object. + * @return 1 on success. + * @return 0 when sha384 or output is NULL. + */ +int wolfSSL_SHA384_Final(byte* output, WOLFSSL_SHA384_CTX* sha384) +{ + int ret; + + WOLFSSL_ENTER("SHA384_Final"); + + /* Finalize wolfCrypt SHA-384 hash into output. */ + ret = (wc_Sha384Final((wc_Sha384*)sha384, output) == 0); + /* Free resources here, as OpenSSL API doesn't include SHA384_Free(). */ + wc_Sha384Free((wc_Sha384*)sha384); + + return ret; +} +#endif /* WOLFSSL_SHA384 */ + +#ifdef WOLFSSL_SHA512 +/* Initialize SHA-512 hash operation. + * + * @param [in, out] sha512 SHA-512 context object. + * @return 1 on success. + * @return 0 when sha512 is NULL. + */ +int wolfSSL_SHA512_Init(WOLFSSL_SHA512_CTX* sha512) +{ + /* Ensure WOLFSSL_SHA512_CTX is big enough for wolfCrypt wc_Sha512. */ + typedef char sha_test[sizeof(SHA512_CTX) >= sizeof(wc_Sha512) ? 1 : -1]; + (void)sizeof(sha_test); + + WOLFSSL_ENTER("SHA512_Init"); + + /* Initialize wolfCrypt SHA-512 object. */ + return wc_InitSha512((wc_Sha512*)sha512) == 0; +} + +/* Update SHA-512 hash with data. + * + * @param [in, out] sha512 SHA-512 context object. + * @param [in] input Data to be hashed. + * @param [in] sz Length of data in bytes. + * @return 1 on success. + * @return 0 when sha512 is NULL. + */ +int wolfSSL_SHA512_Update(WOLFSSL_SHA512_CTX* sha512, const void* input, + unsigned long sz) +{ + WOLFSSL_ENTER("SHA512_Update"); + + /* Update wolfCrypt SHA-512 object with data. */ + return wc_Sha512Update((wc_Sha512*)sha512, (const byte*)input, (word32)sz) + == 0; +} + +/* Finalize SHA-512 hash and return output. + * + * @param [out] output Hash output. + * Must be able to hold SHA512_DIGEST_SIZE bytes. + * @param [in, out] sha512 SHA-512 context object. + * @return 1 on success. + * @return 0 when sha512 or output is NULL. + */ +int wolfSSL_SHA512_Final(byte* output, WOLFSSL_SHA512_CTX* sha512) +{ + int ret; + + WOLFSSL_ENTER("SHA512_Final"); + + /* Finalize wolfCrypt SHA-512 hash into output. */ + ret = (wc_Sha512Final((wc_Sha512*)sha512, output) == 0); + /* Free resources here, as OpenSSL API doesn't include SHA512_Free(). */ + wc_Sha512Free((wc_Sha512*)sha512); + + return ret; +} + +#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) && \ + !defined(WOLFSSL_KCAPI_HASH) /* doesn't support direct transform */ +/* Apply SHA-512 transformation to the data. + * + * @param [in, out] sha512 SHA512 context object. + * @param [in] data One block of data to be hashed. + * @return 1 on success. + * @return 0 when sha512 or data is NULL. + */ +int wolfSSL_SHA512_Transform(WOLFSSL_SHA512_CTX* sha512, + const unsigned char* data) +{ + WOLFSSL_ENTER("SHA512_Transform"); + + /* Transform block of data with wolfCrypt SHA-512 object. */ + return wc_Sha512Transform((wc_Sha512*)sha512, data) == 0; +} +#endif /* !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \ + (HAVE_FIPS_VERSION > 2)) && !WOLFSSL_KCAPI_HASH */ + +#if !defined(WOLFSSL_NOSHA512_224) && \ + (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST) +/* Initialize SHA-512-224 hash operation. + * + * @param [in, out] sha512 SHA-512-224 context object. + * @return 1 on success. + * @return 0 when sha512 is NULL. + */ +int wolfSSL_SHA512_224_Init(WOLFSSL_SHA512_224_CTX* sha512) +{ + WOLFSSL_ENTER("SHA512_224_Init"); + + /* Initialize wolfCrypt SHA-512-224 object. */ + return wc_InitSha512_224((wc_Sha512*)sha512) == 0; +} + +/* Update SHA-512-224 hash with data. + * + * @param [in, out] sha512 SHA-512-224 context object. + * @param [in] input Data to be hashed. + * @param [in] sz Length of data in bytes. + * @return 1 on success. + * @return 0 when sha512 is NULL. + */ +int wolfSSL_SHA512_224_Update(WOLFSSL_SHA512_224_CTX* sha512, const void* input, + unsigned long sz) +{ + WOLFSSL_ENTER("SHA512_224_Update"); + + /* Update wolfCrypt SHA-512-224 object with data. */ + return wc_Sha512_224Update((wc_Sha512*)sha512, (const byte*)input, + (word32)sz) == 0; +} + +/* Finalize SHA-512-224 hash and return output. + * + * @param [out] output Hash output. + * Must be able to hold SHA224_DIGEST_SIZE bytes. + * @param [in, out] sha512 SHA-512-224 context object. + * @return 1 on success. + * @return 0 when sha512 or output is NULL. + */ +int wolfSSL_SHA512_224_Final(byte* output, WOLFSSL_SHA512_224_CTX* sha512) +{ + int ret; + + WOLFSSL_ENTER("SHA512_224_Final"); + + /* Finalize wolfCrypt SHA-512-224 hash into output. */ + ret = (wc_Sha512_224Final((wc_Sha512*)sha512, output) == 0); + /* Free resources here, as OpenSSL API doesn't include SHA512_224_Free(). */ + wc_Sha512_224Free((wc_Sha512*)sha512); + + return ret; +} + +#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) +/* Apply SHA-512-224 transformation to the data. + * + * @param [in, out] sha512 SHA512 context object. + * @param [in] data One block of data to be hashed. + * @return 1 on success. + * @return 0 when sha512 or data is NULL. + */ +int wolfSSL_SHA512_224_Transform(WOLFSSL_SHA512_CTX* sha512, + const unsigned char* data) +{ + WOLFSSL_ENTER("SHA512_224_Transform"); + + /* Transform block of data with wolfCrypt SHA-512-224 object. */ + return wc_Sha512_224Transform((wc_Sha512*)sha512, data) == 0; +} +#endif /* !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \ + (HAVE_FIPS_VERSION > 2)) */ + +#endif /* !WOLFSSL_NOSHA512_224 && !FIPS ... */ + +#if !defined(WOLFSSL_NOSHA512_256) && \ + (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST) +/* Initialize SHA-512-256 hash operation. + * + * @param [in, out] sha512 SHA-512-256 context object. + * @return 1 on success. + * @return 0 when sha512 is NULL. + */ +int wolfSSL_SHA512_256_Init(WOLFSSL_SHA512_256_CTX* sha) +{ + WOLFSSL_ENTER("SHA512_256_Init"); + + /* Initialize wolfCrypt SHA-512-256 object. */ + return wc_InitSha512_256((wc_Sha512*)sha) == 0; +} + +/* Update SHA-512-256 hash with data. + * + * @param [in, out] sha512 SHA-512-256 context object. + * @param [in] input Data to be hashed. + * @param [in] sz Length of data in bytes. + * @return 1 on success. + * @return 0 when sha512 is NULL. + */ +int wolfSSL_SHA512_256_Update(WOLFSSL_SHA512_256_CTX* sha512, const void* input, + unsigned long sz) +{ + WOLFSSL_ENTER("SHA512_256_Update"); + + /* Update wolfCrypt SHA-512-256 object with data. */ + return wc_Sha512_256Update((wc_Sha512*)sha512, (const byte*)input, + (word32)sz) == 0; +} + +/* Finalize SHA-512-256 hash and return output. + * + * @param [out] output Hash output. + * Must be able to hold SHA256_DIGEST_SIZE bytes. + * @param [in, out] sha512 SHA-512-256 context object. + * @return 1 on success. + * @return 0 when sha512 or output is NULL. + */ +int wolfSSL_SHA512_256_Final(byte* output, WOLFSSL_SHA512_256_CTX* sha512) +{ + int ret; + + WOLFSSL_ENTER("SHA512_256_Final"); + + /* Finalize wolfCrypt SHA-512-256 hash into output. */ + ret = (wc_Sha512_256Final((wc_Sha512*)sha512, output) == 0); + /* Free resources here, as OpenSSL API doesn't include SHA512_256_Free(). */ + wc_Sha512_224Free((wc_Sha512*)sha512); + + return ret; +} + +#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) +/* Apply SHA-512-256 transformation to the data. + * + * @param [in, out] sha512 SHA512 context object. + * @param [in] data One block of data to be hashed. + * @return 1 on success. + * @return 0 when sha512 or data is NULL. + */ +int wolfSSL_SHA512_256_Transform(WOLFSSL_SHA512_CTX* sha512, + const unsigned char* data) +{ + WOLFSSL_ENTER("SHA512_256_Transform"); + + /* Transform block of data with wolfCrypt SHA-512-256 object. */ + return wc_Sha512_256Transform((wc_Sha512*)sha512, data) == 0; +} +#endif /* !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \ + (HAVE_FIPS_VERSION > 2)) */ +#endif /* !WOLFSSL_NOSHA512_256 && !FIPS ... */ +#endif /* WOLFSSL_SHA512 */ + +#ifdef WOLFSSL_SHA3 +#ifndef WOLFSSL_NOSHA3_224 +/* Initialize SHA3-224 hash operation. + * + * @param [in, out] sha3_224 SHA3-224 context object. + * @return 1 on success. + * @return 0 when sha3_224 is NULL. + */ +int wolfSSL_SHA3_224_Init(WOLFSSL_SHA3_224_CTX* sha3_224) +{ + /* Ensure WOLFSSL_SHA3_224_CTX is big enough for wolfCrypt wc_Sha3. */ + typedef char sha_test[sizeof(SHA3_224_CTX) >= sizeof(wc_Sha3) ? 1 : -1]; + (void)sizeof(sha_test); + + WOLFSSL_ENTER("SHA3_224_Init"); + + /* Initialize wolfCrypt SHA3-224 object. */ + return wc_InitSha3_224((wc_Sha3*)sha3_224, NULL, INVALID_DEVID) == 0; +} + +/* Update SHA3-224 hash with data. + * + * @param [in, out] sha3 SHA3-224 context object. + * @param [in] input Data to be hashed. + * @param [in] sz Length of data in bytes. + * @return 1 on success. + * @return 0 when sha3 is NULL. + */ +int wolfSSL_SHA3_224_Update(WOLFSSL_SHA3_224_CTX* sha3, const void* input, + unsigned long sz) +{ + WOLFSSL_ENTER("SHA3_224_Update"); + + /* Update wolfCrypt SHA3-224 object with data. */ + return wc_Sha3_224_Update((wc_Sha3*)sha3, (const byte*)input, (word32)sz) + == 0; +} + +/* Finalize SHA3-224 hash and return output. + * + * @param [out] output Hash output. + * Must be able to hold SHA3_224_DIGEST_SIZE bytes. + * @param [in, out] sha3 SHA3-224 context object. + * @return 1 on success. + * @return 0 when sha3 or output is NULL. + */ +int wolfSSL_SHA3_224_Final(byte* output, WOLFSSL_SHA3_224_CTX* sha3) +{ + int ret; + + WOLFSSL_ENTER("SHA3_224_Final"); + + /* Finalize wolfCrypt SHA3-224 hash into output. */ + ret = (wc_Sha3_224_Final((wc_Sha3*)sha3, output) == 0); + /* Free resources here, as OpenSSL API doesn't include SHA3_224_Free(). */ + wc_Sha3_224_Free((wc_Sha3*)sha3); + + return ret; +} +#endif /* WOLFSSL_NOSHA3_224 */ + +#ifndef WOLFSSL_NOSHA3_256 +/* Initialize SHA3-256 hash operation. + * + * @param [in, out] sha3_256 SHA3-256 context object. + * @return 1 on success. + * @return 0 when sha3_256 is NULL. + */ +int wolfSSL_SHA3_256_Init(WOLFSSL_SHA3_256_CTX* sha3_256) +{ + /* Ensure WOLFSSL_SHA3_256_CTX is big enough for wolfCrypt wc_Sha3. */ + typedef char sha_test[sizeof(SHA3_256_CTX) >= sizeof(wc_Sha3) ? 1 : -1]; + (void)sizeof(sha_test); + + WOLFSSL_ENTER("SHA3_256_Init"); + + /* Initialize wolfCrypt SHA3-256 object. */ + return wc_InitSha3_256((wc_Sha3*)sha3_256, NULL, INVALID_DEVID) == 0; +} + +/* Update SHA3-256 hash with data. + * + * @param [in, out] sha3 SHA3-256 context object. + * @param [in] input Data to be hashed. + * @param [in] sz Length of data in bytes. + * @return 1 on success. + * @return 0 when sha3 is NULL. + */ +int wolfSSL_SHA3_256_Update(WOLFSSL_SHA3_256_CTX* sha3, const void* input, + unsigned long sz) +{ + WOLFSSL_ENTER("SHA3_256_Update"); + + /* Update wolfCrypt SHA3-256 object with data. */ + return wc_Sha3_256_Update((wc_Sha3*)sha3, (const byte*)input, (word32)sz) + == 0; +} + +/* Finalize SHA3-256 hash and return output. + * + * @param [out] output Hash output. + * Must be able to hold SHA3_256_DIGEST_SIZE bytes. + * @param [in, out] sha3 SHA3-256 context object. + * @return 1 on success. + * @return 0 when sha3 or output is NULL. + */ +int wolfSSL_SHA3_256_Final(byte* output, WOLFSSL_SHA3_256_CTX* sha3) +{ + int ret; + + WOLFSSL_ENTER("SHA3_256_Final"); + + /* Finalize wolfCrypt SHA3-256 hash into output. */ + ret = (wc_Sha3_256_Final((wc_Sha3*)sha3, output) == 0); + /* Free resources here, as OpenSSL API doesn't include SHA3_256_Free(). */ + wc_Sha3_256_Free((wc_Sha3*)sha3); + + return ret; +} +#endif /* WOLFSSL_NOSHA3_256 */ + +#ifndef WOLFSSL_NOSHA3_384 +/* Initialize SHA3-384 hash operation. + * + * @param [in, out] sha3_384 SHA3-384 context object. + * @return 1 on success. + * @return 0 when sha3_384 is NULL. + */ +int wolfSSL_SHA3_384_Init(WOLFSSL_SHA3_384_CTX* sha3_384) +{ + /* Ensure WOLFSSL_SHA3_384_CTX is big enough for wolfCrypt wc_Sha3. */ + typedef char sha_test[sizeof(SHA3_384_CTX) >= sizeof(wc_Sha3) ? 1 : -1]; + (void)sizeof(sha_test); + + WOLFSSL_ENTER("SHA3_384_Init"); + + /* Initialize wolfCrypt SHA3-384 object. */ + return wc_InitSha3_384((wc_Sha3*)sha3_384, NULL, INVALID_DEVID) == 0; +} + +/* Update SHA3-384 hash with data. + * + * @param [in, out] sha3 SHA3-384 context object. + * @param [in] input Data to be hashed. + * @param [in] sz Length of data in bytes. + * @return 1 on success. + * @return 0 when sha3 is NULL. + */ +int wolfSSL_SHA3_384_Update(WOLFSSL_SHA3_384_CTX* sha3, const void* input, + unsigned long sz) +{ + WOLFSSL_ENTER("SHA3_384_Update"); + + /* Update wolfCrypt SHA3-384 object with data. */ + return wc_Sha3_384_Update((wc_Sha3*)sha3, (const byte*)input, (word32)sz) + == 0; +} + +/* Finalize SHA3-384 hash and return output. + * + * @param [out] output Hash output. + * Must be able to hold SHA3_384_DIGEST_SIZE bytes. + * @param [in, out] sha3 SHA3-384 context object. + * @return 1 on success. + * @return 0 when sha3 or output is NULL. + */ +int wolfSSL_SHA3_384_Final(byte* output, WOLFSSL_SHA3_384_CTX* sha3) +{ + int ret; + + WOLFSSL_ENTER("SHA3_384_Final"); + + /* Finalize wolfCrypt SHA3-384 hash into output. */ + ret = (wc_Sha3_384_Final((wc_Sha3*)sha3, output) == 0); + /* Free resources here, as OpenSSL API doesn't include SHA3_384_Free(). */ + wc_Sha3_384_Free((wc_Sha3*)sha3); + + return ret; +} +#endif /* WOLFSSL_NOSHA3_384 */ + +#ifndef WOLFSSL_NOSHA3_512 +/* Initialize SHA3-512 hash operation. + * + * @param [in, out] sha3_512 SHA3-512 context object. + * @return 1 on success. + * @return 0 when sha3_512 is NULL. + */ +int wolfSSL_SHA3_512_Init(WOLFSSL_SHA3_512_CTX* sha3_512) +{ + /* Ensure WOLFSSL_SHA3_512_CTX is big enough for wolfCrypt wc_Sha3. */ + typedef char sha_test[sizeof(SHA3_512_CTX) >= sizeof(wc_Sha3) ? 1 : -1]; + (void)sizeof(sha_test); + + WOLFSSL_ENTER("SHA3_512_Init"); + + /* Initialize wolfCrypt SHA3-512 object. */ + return wc_InitSha3_512((wc_Sha3*)sha3_512, NULL, INVALID_DEVID) == 0; +} + +/* Update SHA3-512 hash with data. + * + * @param [in, out] sha3 SHA3-512 context object. + * @param [in] input Data to be hashed. + * @param [in] sz Length of data in bytes. + * @return 1 on success. + * @return 0 when sha3 is NULL. + */ +int wolfSSL_SHA3_512_Update(WOLFSSL_SHA3_512_CTX* sha3, const void* input, + unsigned long sz) +{ + WOLFSSL_ENTER("SHA3_512_Update"); + + /* Update wolfCrypt SHA3-512 object with data. */ + return wc_Sha3_512_Update((wc_Sha3*)sha3, (const byte*)input, (word32)sz) + == 0; +} + +/* Finalize SHA3-512 hash and return output. + * + * @param [out] output Hash output. + * Must be able to hold SHA3_512_DIGEST_SIZE bytes. + * @param [in, out] sha3 SHA3-512 context object. + * @return 1 on success. + * @return 0 when sha3 or output is NULL. + */ +int wolfSSL_SHA3_512_Final(byte* output, WOLFSSL_SHA3_512_CTX* sha3) +{ + int ret; + + WOLFSSL_ENTER("SHA3_512_Final"); + + /* Finalize wolfCrypt SHA3-512 hash into output. */ + ret = (wc_Sha3_512_Final((wc_Sha3*)sha3, output) == 0); + /* Free resources here, as OpenSSL API doesn't include SHA3_512_Free(). */ + wc_Sha3_512_Free((wc_Sha3*)sha3); + + return ret; +} +#endif /* WOLFSSL_NOSHA3_512 */ +#endif /* WOLFSSL_SHA3 */ +#endif /* OPENSSL_EXTRA || HAVE_CURL */ + +#if defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) || \ + defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL) || \ + defined(WOLFSSL_NGINX) || defined(HAVE_POCO_LIB) || \ + defined(WOLFSSL_HAPROXY) + +#ifndef NO_SHA +/* One shot SHA1 hash of data. + * + * When hash is null, a static buffer of SHA_DIGEST_SIZE is used. + * When the static buffer is used this function is not thread safe. + * + * @param [in] data Data to hash. + * @param [in] len Size of data in bytes. + * @param [out] hash Buffer to hold digest. May be NULL. + * Must be able to hold SHA_DIGEST_SIZE bytes. + * @return Buffer holding hash on success. + * @return NULL when hashing fails. + */ +unsigned char* wolfSSL_SHA1(const unsigned char* data, size_t len, + unsigned char* hash) +{ + /* Buffer to use when hash is NULL. */ + static byte dgst[WC_SHA_DIGEST_SIZE]; +#ifdef WOLFSSL_SMALL_STACK + wc_Sha* sha; +#else + wc_Sha sha[1]; +#endif + int ret = 0; + + WOLFSSL_ENTER("wolfSSL_SHA1"); + + /* Use static buffer if none passed in. */ + if (hash == NULL) { + WOLFSSL_MSG("STATIC BUFFER BEING USED. wolfSSL_SHA1 IS NOT " + "THREAD SAFE WHEN hash == NULL"); + hash = dgst; + } + +#ifdef WOLFSSL_SMALL_STACK + /* Allocate dynamic memory for a wolfSSL SHA object. */ + sha = (wc_Sha*)XMALLOC(sizeof(wc_Sha), NULL, DYNAMIC_TYPE_DIGEST); + if (sha == NULL) { + ret = MEMORY_E; + } +#endif + + if (ret == 0) { + /* Initialize wolfCrypt SHA object. */ + ret = wc_InitSha_ex(sha, NULL, INVALID_DEVID); + if (ret != 0) { + WOLFSSL_MSG("SHA1 Init failed"); + hash = NULL; + } + } + if (ret == 0) { + /* Update wolfCrypt SHA object with data. */ + ret = wc_ShaUpdate(sha, (const byte*)data, (word32)len); + if (ret != 0) { + WOLFSSL_MSG("SHA1 Update failed"); + hash = NULL; + } + + if (ret == 0) { + /* Finalize wolfCrypt SHA hash into hash. */ + ret = wc_ShaFinal(sha, hash); + if (ret != 0) { + WOLFSSL_MSG("SHA1 Final failed"); + hash = NULL; + } + } + /* Dispose of dynamic memory associated with SHA object. */ + wc_ShaFree(sha); + } + +#ifdef WOLFSSL_SMALL_STACK + /* Free dynamic memory of a wolfSSL SHA object. */ + XFREE(sha, NULL, DYNAMIC_TYPE_DIGEST); +#endif + return hash; +} +#endif /* ! NO_SHA */ + +#ifdef WOLFSSL_SHA224 +/* One shot SHA-224 hash of data. + * + * When hash is null, a static buffer of SHA224_DIGEST_SIZE is used. + * When the static buffer is used this function is not thread safe. + * + * @param [in] data Data to hash. + * @param [in] len Size of data in bytes. + * @param [out] hash Buffer to hold digest. May be NULL. + * Must be able to hold SHA224_DIGEST_SIZE bytes. + * @return Buffer holding hash on success. + * @return NULL when hashing fails. + */ +unsigned char* wolfSSL_SHA224(const unsigned char* data, size_t len, + unsigned char* hash) +{ + /* Buffer to use when hash is NULL. */ + static byte dgst[WC_SHA224_DIGEST_SIZE]; +#ifdef WOLFSSL_SMALL_STACK + wc_Sha224* sha224; +#else + wc_Sha224 sha224[1]; +#endif + int ret = 0; + + WOLFSSL_ENTER("wolfSSL_SHA224"); + + /* Use static buffer if none passed in. */ + if (hash == NULL) { + WOLFSSL_MSG("STATIC BUFFER BEING USED. wolfSSL_SHA224 IS NOT " + "THREAD SAFE WHEN hash == NULL"); + hash = dgst; + } + +#ifdef WOLFSSL_SMALL_STACK + /* Allocate dynamic memory for a wolfSSL SHA-224 object. */ + sha224 = (wc_Sha224*)XMALLOC(sizeof(wc_Sha224), NULL, DYNAMIC_TYPE_DIGEST); + if (sha224 == NULL) { + ret = MEMORY_E; + } +#endif + + if (ret == 0) { + /* Initialize wolfCrypt SHA224 object. */ + ret = wc_InitSha224_ex(sha224, NULL, INVALID_DEVID); + if (ret != 0) { + WOLFSSL_MSG("SHA224 Init failed"); + hash = NULL; + } + } + if (ret == 0) { + /* Update wolfCrypt SHA-224 object with data. */ + ret = wc_Sha224Update(sha224, (const byte*)data, (word32)len); + if (ret != 0) { + WOLFSSL_MSG("SHA224 Update failed"); + hash = NULL; + } + + if (ret == 0) { + /* Finalize wolfCrypt SHA-224 hash into hash. */ + ret = wc_Sha224Final(sha224, hash); + if (ret != 0) { + WOLFSSL_MSG("SHA224 Final failed"); + hash = NULL; + } + } + /* Dispose of dynamic memory associated with SHA-224 object. */ + wc_Sha224Free(sha224); + } + +#ifdef WOLFSSL_SMALL_STACK + /* Free dynamic memory of a wolfSSL SHA-224 object. */ + XFREE(sha224, NULL, DYNAMIC_TYPE_DIGEST); +#endif + return hash; +} +#endif + +#ifndef NO_SHA256 +/* One shot SHA-256 hash of data. + * + * When hash is null, a static buffer of SHA256_DIGEST_SIZE is used. + * When the static buffer is used this function is not thread safe. + * + * @param [in] data Data to hash. + * @param [in] len Size of data in bytes. + * @param [out] hash Buffer to hold digest. May be NULL. + * Must be able to hold SHA256_DIGEST_SIZE bytes. + * @return Buffer holding hash on success. + * @return NULL when hashing fails. + */ +unsigned char* wolfSSL_SHA256(const unsigned char* data, size_t len, + unsigned char* hash) +{ + /* Buffer to use when hash is NULL. */ + static byte dgst[WC_SHA256_DIGEST_SIZE]; +#ifdef WOLFSSL_SMALL_STACK + wc_Sha256* sha256; +#else + wc_Sha256 sha256[1]; +#endif + int ret = 0; + + WOLFSSL_ENTER("wolfSSL_SHA256"); + + /* Use static buffer if none passed in. */ + if (hash == NULL) { + WOLFSSL_MSG("STATIC BUFFER BEING USED. wolfSSL_SHA256 IS NOT " + "THREAD SAFE WHEN hash == NULL"); + hash = dgst; + } + +#ifdef WOLFSSL_SMALL_STACK + /* Allocate dynamic memory for a wolfSSL SHA-256 object. */ + sha256 = (wc_Sha256*)XMALLOC(sizeof(wc_Sha256), NULL, DYNAMIC_TYPE_DIGEST); + if (sha256 == NULL) { + ret = MEMORY_E; + } +#endif + + if (ret == 0) { + /* Initialize wolfCrypt SHA256 object. */ + ret = wc_InitSha256_ex(sha256, NULL, INVALID_DEVID); + if (ret != 0) { + WOLFSSL_MSG("SHA256 Init failed"); + hash = NULL; + } + } + if (ret == 0) { + /* Update wolfCrypt SHA-256 object with data. */ + ret = wc_Sha256Update(sha256, (const byte*)data, (word32)len); + if (ret != 0) { + WOLFSSL_MSG("SHA256 Update failed"); + hash = NULL; + } + + if (ret == 0) { + /* Finalize wolfCrypt SHA-256 hash into hash. */ + ret = wc_Sha256Final(sha256, hash); + if (ret != 0) { + WOLFSSL_MSG("SHA256 Final failed"); + hash = NULL; + } + } + /* Dispose of dynamic memory associated with SHA-256 object. */ + wc_Sha256Free(sha256); + } + +#ifdef WOLFSSL_SMALL_STACK + /* Free dynamic memory of a wolfSSL SHA object. */ + XFREE(sha256, NULL, DYNAMIC_TYPE_DIGEST); +#endif + return hash; +} +#endif /* ! NO_SHA256 */ + +#ifdef WOLFSSL_SHA384 +/* One shot SHA-384 hash of data. + * + * When hash is null, a static buffer of SHA384_DIGEST_SIZE is used. + * When the static buffer is used this function is not thread safe. + * + * @param [in] data Data to hash. + * @param [in] len Size of data in bytes. + * @param [out] hash Buffer to hold digest. May be NULL. + * Must be able to hold SHA384_DIGEST_SIZE bytes. + * @return Buffer holding hash on success. + * @return NULL when hashing fails. + */ +unsigned char* wolfSSL_SHA384(const unsigned char* data, size_t len, + unsigned char* hash) +{ + /* Buffer to use when hash is NULL. */ + static byte dgst[WC_SHA384_DIGEST_SIZE]; +#ifdef WOLFSSL_SMALL_STACK + wc_Sha384* sha384; +#else + wc_Sha384 sha384[1]; +#endif + int ret = 0; + + WOLFSSL_ENTER("wolfSSL_SHA384"); + + /* Use static buffer if none passed in. */ + if (hash == NULL) { + WOLFSSL_MSG("STATIC BUFFER BEING USED. wolfSSL_SHA384 IS NOT " + "THREAD SAFE WHEN hash == NULL"); + hash = dgst; + } + +#ifdef WOLFSSL_SMALL_STACK + /* Allocate dynamic memory for a wolfSSL SHA-384 object. */ + sha384 = (wc_Sha384*)XMALLOC(sizeof(wc_Sha384), NULL, DYNAMIC_TYPE_DIGEST); + if (sha384 == NULL) { + ret = MEMORY_E; + } +#endif + + if (ret == 0) { + /* Initialize wolfCrypt SHA384 object. */ + ret = wc_InitSha384_ex(sha384, NULL, INVALID_DEVID); + if (ret != 0) { + WOLFSSL_MSG("SHA384 Init failed"); + hash = NULL; + } + } + if (ret == 0) { + /* Update wolfCrypt SHA-384 object with data. */ + ret = wc_Sha384Update(sha384, (const byte*)data, (word32)len); + if (ret != 0) { + WOLFSSL_MSG("SHA384 Update failed"); + hash = NULL; + } + + if (ret == 0) { + /* Finalize wolfCrypt SHA-384 hash into hash. */ + ret = wc_Sha384Final(sha384, hash); + if (ret != 0) { + WOLFSSL_MSG("SHA384 Final failed"); + hash = NULL; + } + } + /* Dispose of dynamic memory associated with SHA-384 object. */ + wc_Sha384Free(sha384); + } + +#ifdef WOLFSSL_SMALL_STACK + /* Free dynamic memory of a wolfSSL SHA-384 object. */ + XFREE(sha384, NULL, DYNAMIC_TYPE_DIGEST); +#endif + return hash; +} +#endif /* WOLFSSL_SHA384 */ + +#if defined(WOLFSSL_SHA512) +/* One shot SHA-512 hash of data. + * + * When hash is null, a static buffer of SHA512_DIGEST_SIZE is used. + * When the static buffer is used this function is not thread safe. + * + * @param [in] data Data to hash. + * @param [in] len Size of data in bytes. + * @param [out] hash Buffer to hold digest. May be NULL. + * Must be able to hold SHA512_DIGEST_SIZE bytes. + * @return Buffer holding hash on success. + * @return NULL when hashing fails. + */ +unsigned char* wolfSSL_SHA512(const unsigned char* data, size_t len, + unsigned char* hash) +{ + /* Buffer to use when hash is NULL. */ + static byte dgst[WC_SHA512_DIGEST_SIZE]; +#ifdef WOLFSSL_SMALL_STACK + wc_Sha512* sha512; +#else + wc_Sha512 sha512[1]; +#endif + int ret = 0; + + WOLFSSL_ENTER("wolfSSL_SHA512"); + + /* Use static buffer if none passed in. */ + if (hash == NULL) { + WOLFSSL_MSG("STATIC BUFFER BEING USED. wolfSSL_SHA512 IS NOT " + "THREAD SAFE WHEN hash == NULL"); + hash = dgst; + } + +#ifdef WOLFSSL_SMALL_STACK + /* Allocate dynamic memory for a wolfSSL SHA-512 object. */ + sha512 = (wc_Sha512*)XMALLOC(sizeof(wc_Sha512), NULL, DYNAMIC_TYPE_DIGEST); + if (sha512 == NULL) { + ret = MEMORY_E; + } +#endif + + if (ret == 0) { + /* Initialize wolfCrypt SHA512 object. */ + ret = wc_InitSha512_ex(sha512, NULL, INVALID_DEVID); + if (ret != 0) { + WOLFSSL_MSG("SHA512 Init failed"); + hash = NULL; + } + } + if (ret == 0) { + /* Update wolfCrypt SHA-512 object with data. */ + ret = wc_Sha512Update(sha512, (const byte*)data, (word32)len); + if (ret != 0) { + WOLFSSL_MSG("SHA512 Update failed"); + hash = NULL; + } + + if (ret == 0) { + /* Finalize wolfCrypt SHA-512 hash into hash. */ + ret = wc_Sha512Final(sha512, hash); + if (ret != 0) { + WOLFSSL_MSG("SHA512 Final failed"); + hash = NULL; + } + } + /* Dispose of dynamic memory associated with SHA-512 object. */ + wc_Sha512Free(sha512); + } + +#ifdef WOLFSSL_SMALL_STACK + /* Free dynamic memory of a wolfSSL SHA-512 object. */ + XFREE(sha512, NULL, DYNAMIC_TYPE_DIGEST); +#endif + return hash; +} +#endif /* WOLFSSL_SHA512 */ +#endif /* OPENSSL_EXTRA || HAVE_LIGHTY || WOLFSSL_MYSQL_COMPATIBLE || + * HAVE_STUNNEL || WOLFSSL_NGINX || HAVE_POCO_LIB || WOLFSSL_HAPROXY */ + +/******************************************************************************* + * END OF Digest APIs + ******************************************************************************/ + +/******************************************************************************* + * START OF HMAC API + ******************************************************************************/ + +/* _Internal Hmac object initialization. */ +#define _HMAC_Init _InitHmac + +#if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY) + +/* + * Helper Functions + */ + +/* Copy a wolfSSL HMAC object. + * + * Requires that hash structures have no dynamic parts to them. + * + * @param [out] dst Copy into this object. + * @param [in] src Copy from this object. + * @return 1 on success. + * @return 0 on failure. + */ +int wolfSSL_HmacCopy(Hmac* dst, Hmac* src) +{ + void* heap; + int ret = 1; + +#ifndef HAVE_FIPS + heap = src->heap; +#else + heap = NULL; +#endif + + /* Initialize the destination object to reset state. */ + if (wc_HmacInit(dst, heap, 0) != 0) { + ret = 0; + } + + if (ret == 1) { + int rc; + + /* Copy the digest object based on the MAC type. */ + switch (src->macType) { + #ifndef NO_MD5 + case WC_MD5: + rc = wc_Md5Copy(&src->hash.md5, &dst->hash.md5); + break; + #endif /* !NO_MD5 */ + + #ifndef NO_SHA + case WC_SHA: + rc = wc_ShaCopy(&src->hash.sha, &dst->hash.sha); + break; + #endif /* !NO_SHA */ + + #ifdef WOLFSSL_SHA224 + case WC_SHA224: + rc = wc_Sha224Copy(&src->hash.sha224, &dst->hash.sha224); + break; + #endif /* WOLFSSL_SHA224 */ + + #ifndef NO_SHA256 + case WC_SHA256: + rc = wc_Sha256Copy(&src->hash.sha256, &dst->hash.sha256); + break; + #endif /* !NO_SHA256 */ + + #ifdef WOLFSSL_SHA384 + case WC_SHA384: + rc = wc_Sha384Copy(&src->hash.sha384, &dst->hash.sha384); + break; + #endif /* WOLFSSL_SHA384 */ + #ifdef WOLFSSL_SHA512 + case WC_SHA512: + rc = wc_Sha512Copy(&src->hash.sha512, &dst->hash.sha512); + break; + #endif /* WOLFSSL_SHA512 */ +#ifdef WOLFSSL_SHA3 + #ifndef WOLFSSL_NOSHA3_224 + case WC_SHA3_224: + rc = wc_Sha3_224_Copy(&src->hash.sha3, &dst->hash.sha3); + break; + #endif /* WOLFSSL_NO_SHA3_224 */ + #ifndef WOLFSSL_NOSHA3_256 + case WC_SHA3_256: + rc = wc_Sha3_256_Copy(&src->hash.sha3, &dst->hash.sha3); + break; + #endif /* WOLFSSL_NO_SHA3_256 */ + #ifndef WOLFSSL_NOSHA3_384 + case WC_SHA3_384: + rc = wc_Sha3_384_Copy(&src->hash.sha3, &dst->hash.sha3); + break; + #endif /* WOLFSSL_NO_SHA3_384 */ + #ifndef WOLFSSL_NOSHA3_512 + case WC_SHA3_512: + rc = wc_Sha3_512_Copy(&src->hash.sha3, &dst->hash.sha3); + break; + #endif /* WOLFSSL_NO_SHA3_512 */ +#endif /* WOLFSSL_SHA3 */ + + default: + /* Digest algorithm not supported. */ + rc = BAD_FUNC_ARG; + } + + /* Check result of digest object copy. */ + if (rc != 0) { + ret = 0; + } + } + + if (ret == 1) { + /* Copy the pads which are derived from the key. */ + XMEMCPY((byte*)dst->ipad, (byte*)src->ipad, WC_HMAC_BLOCK_SIZE); + XMEMCPY((byte*)dst->opad, (byte*)src->opad, WC_HMAC_BLOCK_SIZE); + /* Copy the inner hash that is the current state. */ + XMEMCPY((byte*)dst->innerHash, (byte*)src->innerHash, + WC_MAX_DIGEST_SIZE); + /* Copy other fields. */ + #ifndef HAVE_FIPS + dst->heap = heap; + #endif + dst->macType = src->macType; + dst->innerHashKeyed = src->innerHashKeyed; + +#ifdef WOLFSSL_ASYNC_CRYPT + XMEMCPY(&dst->asyncDev, &src->asyncDev, sizeof(WC_ASYNC_DEV)); + dst->keyLen = src->keyLen; + #ifdef HAVE_CAVIUM + /* Copy the dynamic data. */ + dst->data = (byte*)XMALLOC(src->dataLen, dst->heap, DYNAMIC_TYPE_HMAC); + if (dst->data == NULL) { + ret = BUFFER_E; + } + else { + XMEMCPY(dst->data, src->data, src->dataLen); + dst->dataLen = src->dataLen; + } + #endif /* HAVE_CAVIUM */ +#endif /* WOLFSSL_ASYNC_CRYPT */ + } + + return ret; +} + + +/* + * wolfSSL_HMAC_CTX APIs. + */ + +/* Allocate a new HMAC context object and initialize. + * + * @return A cleared HMAC context object on success. + * @return NULL on failure. + */ +WOLFSSL_HMAC_CTX* wolfSSL_HMAC_CTX_new(void) +{ + WOLFSSL_HMAC_CTX* hmac_ctx; + + /* Allocate dynamic memory for HMAC context object. */ + hmac_ctx = (WOLFSSL_HMAC_CTX*)XMALLOC(sizeof(WOLFSSL_HMAC_CTX), NULL, + DYNAMIC_TYPE_OPENSSL); + if (hmac_ctx != NULL) { + /* Initialize HMAC context object. */ + wolfSSL_HMAC_CTX_Init(hmac_ctx); + } + + return hmac_ctx; +} + +/* Initialize a HMAC context object. + * + * Not an OpenSSL compatibility API. + * + * @param [in, out] ctx HMAC contect object. + * @return 1 inficating success. + */ +int wolfSSL_HMAC_CTX_Init(WOLFSSL_HMAC_CTX* ctx) +{ + WOLFSSL_MSG("wolfSSL_HMAC_CTX_Init"); + + if (ctx != NULL) { + /* Clear all fields. */ + XMEMSET(ctx, 0, sizeof(WOLFSSL_HMAC_CTX)); + /* type field is 0 == WC_HASH_TYPE_NONE. */ + /* TODO: for FIPS and selftest 0 == WC_HASH_TYPE_MD5 instead. */ + } + + return 1; +} + +/* Deep copy of information from one HMAC context object to another. + * + * @param [out] dst Copy into this object. + * @param [in] src Copy from this object. + * @return 1 on success. + * @return 0 on failure. + */ +int wolfSSL_HMAC_CTX_copy(WOLFSSL_HMAC_CTX* dst, WOLFSSL_HMAC_CTX* src) +{ + int ret = 1; + + WOLFSSL_ENTER("wolfSSL_HMAC_CTX_copy"); + + /* Validate parameters. */ + if ((dst == NULL) || (src == NULL)) { + ret = 0; + } + + if (ret == 1) { + /* Copy hash type. */ + dst->type = src->type; + /* Move pads derived from key into save space. */ + XMEMCPY((byte *)&dst->save_ipad, (byte *)&src->hmac.ipad, + WC_HMAC_BLOCK_SIZE); + XMEMCPY((byte *)&dst->save_opad, (byte *)&src->hmac.opad, + WC_HMAC_BLOCK_SIZE); + /* Copy the wolfSSL Hmac ocbject. */ + ret = wolfSSL_HmacCopy(&dst->hmac, &src->hmac); + } + + return ret; +} + +/* Cleanup internal state of HMAC context object. + * + * Not an OpenSSL compatibility API. + * + * @param [in, out] ctx HMAC context object. + */ +void wolfSSL_HMAC_CTX_cleanup(WOLFSSL_HMAC_CTX* ctx) +{ + if (ctx != NULL) { + /* Cleanup HMAC operation data. */ + wolfSSL_HMAC_cleanup(ctx); + } +} + +/* Free HMAC context object. + * + * ctx is deallocated and can no longer be used after this call. + * + * @param [in] ctx HMAC context object. + */ +void wolfSSL_HMAC_CTX_free(WOLFSSL_HMAC_CTX* ctx) +{ + if (ctx != NULL) { + /* Cleanup HMAC context object, including freeing dynamic data. */ + wolfSSL_HMAC_CTX_cleanup(ctx); + /* Dispose of the memory for the HMAC context object. */ + XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL); + } +} + +/* Get the EVP digest of the HMAC context. + * + * @param [in] ctx HMAC context object. + * @return EVP digest object. + * @return NULL when ctx is NULL or EVP digest not set. + */ +const WOLFSSL_EVP_MD* wolfSSL_HMAC_CTX_get_md(const WOLFSSL_HMAC_CTX* ctx) +{ + const WOLFSSL_EVP_MD* ret = NULL; + + if (ctx != NULL) { + /* Get EVP digest based on digest type. */ + ret = wolfSSL_macType2EVP_md((enum wc_HashType)ctx->type); + } + + return ret; +} + +/* + * wolfSSL_HMAC APIs. + */ + +/* Initialize the HMAC operation. + * + * @param [in, out] ctx HMAC context object. + * @param [in] key Array of bytes representing key. + * May be NULL indicating to use the same key as + * previously. + * @param [in] keySz Number of bytes in key. + * 0+ in non-FIPS, 14+ in FIPS. + * @param [in] type EVP digest indicate digest type. + * May be NULL if initialized previously. + * @param [in] e wolfSSL engine. Ignored. + * @return 1 on success. + * @return 0 on failure. + */ +int wolfSSL_HMAC_Init_ex(WOLFSSL_HMAC_CTX* ctx, const void* key, int keySz, + const EVP_MD* type, WOLFSSL_ENGINE* e) +{ + WOLFSSL_ENTER("wolfSSL_HMAC_Init_ex"); + + /* WOLFSSL_ENGINE not used, call wolfSSL_HMAC_Init */ + (void)e; + + return wolfSSL_HMAC_Init(ctx, key, keySz, type); +} + +/* Initialize the HMAC operation. + * + * @param [in, out] ctx HMAC context object. + * @param [in] key Array of bytes representing key. + * May be NULL indicating to use the same key as + * previously. + * @param [in] keySz Number of bytes in key. + * 0+ in non-FIPS, 14+ in FIPS. + * @param [in] type EVP digest indicate digest type. + * May be NULL if initialized previously. + * @return 1 on success. + * @return 0 on failure. + */ +int wolfSSL_HMAC_Init(WOLFSSL_HMAC_CTX* ctx, const void* key, int keylen, + const EVP_MD* type) +{ + int ret = 1; + void* heap = NULL; + int rc; + + WOLFSSL_MSG("wolfSSL_HMAC_Init"); + + /* Validate parameters. */ + if (ctx == NULL) { + WOLFSSL_MSG("no ctx on init"); + ret = 0; + } + /* Digest type must have been previously set if not specified. */ + if ((ret == 1) && (type == NULL) && (ctx->type == (int)WC_HASH_TYPE_NONE)) { + WOLFSSL_MSG("no hash type"); + ret = 0; + } + /* wolfSSL HMAC object must have been setup with a key if not specified. */ + if ((ret == 1) && (key == NULL) && + (ctx->hmac.macType == (int)WC_HASH_TYPE_NONE)) { + WOLFSSL_MSG("wolfCrypt hash not setup"); + ret = 0; + } + + if (ret == 1) { + #ifndef HAVE_FIPS + heap = ctx->hmac.heap; + #endif + + if (type != NULL) { + WOLFSSL_MSG("init has type"); + /* Get the digest type based on EVP digest. */ + if (wolfssl_evp_md_to_hash_type(type, &ctx->type) != 0) { + WOLFSSL_MSG("bad init type"); + ret = 0; + } + } + } + + if (ret == 1) { + /* Check if init has been called before */ + int inited = (ctx->hmac.macType != WC_HASH_TYPE_NONE); + /* Free if wolfSSL HMAC object when initialized. */ + if (inited) { + wc_HmacFree(&ctx->hmac); + } + /* Initialize wolfSSL HMAC object for new HMAC operation. */ + rc = wc_HmacInit(&ctx->hmac, NULL, INVALID_DEVID); + if (rc != 0) { + ret = 0; + } + } + if ((ret == 1) && (key != NULL)) { + /* Set the key into wolfSSL HMAC object. */ + rc = wc_HmacSetKey(&ctx->hmac, ctx->type, (const byte*)key, + (word32)keylen); + if (rc != 0) { + /* in FIPS mode a key < 14 characters will fail here */ + WOLFSSL_MSG("hmac set key error"); + WOLFSSL_ERROR(rc); + wc_HmacFree(&ctx->hmac); + ret = 0; + } + if (ret == 1) { + /* Save the pads which are derived from the key. Used to re-init. */ + XMEMCPY((byte *)&ctx->save_ipad, (byte *)&ctx->hmac.ipad, + WC_HMAC_BLOCK_SIZE); + XMEMCPY((byte *)&ctx->save_opad, (byte *)&ctx->hmac.opad, + WC_HMAC_BLOCK_SIZE); + } + } + else if (ret == 1) { + WOLFSSL_MSG("recover hmac"); + /* Set state of wolfSSL HMAC object. */ + ctx->hmac.macType = (byte)ctx->type; + ctx->hmac.innerHashKeyed = 0; + /* Restore key by copying in saved pads. */ + XMEMCPY((byte *)&ctx->hmac.ipad, (byte *)&ctx->save_ipad, + WC_HMAC_BLOCK_SIZE); + XMEMCPY((byte *)&ctx->hmac.opad, (byte *)&ctx->save_opad, + WC_HMAC_BLOCK_SIZE); + /* Initialize the wolfSSL HMAC object. */ + rc = _HMAC_Init(&ctx->hmac, ctx->hmac.macType, heap); + if (rc != 0) { + WOLFSSL_MSG("hmac init error"); + WOLFSSL_ERROR(rc); + ret = 0; + } + } + + return ret; +} + +/* Update the HMAC operation with more data. + * + * TODO: 'len' should be a signed type. + * + * @param [in, out] ctx HMAC context object. + * @param [in] data Array of byted to MAC. May be NULL. + * @param [in] len Number of bytes to MAC. May be 0. + * @return 1 on success. + * @return 0 when ctx is NULL or HMAC update fails. + */ +int wolfSSL_HMAC_Update(WOLFSSL_HMAC_CTX* ctx, const unsigned char* data, + int len) +{ + int ret = 1; + + WOLFSSL_MSG("wolfSSL_HMAC_Update"); + + /* Validate parameters. */ + if (ctx == NULL) { + WOLFSSL_MSG("no ctx"); + ret = 0; + } + + /* Update when there is data to add. */ + if ((ret == 1) && (data != NULL) && (len > 0)) { + int rc; + + WOLFSSL_MSG("updating hmac"); + /* Update wolfSSL HMAC object. */ + rc = wc_HmacUpdate(&ctx->hmac, data, (word32)len); + if (rc != 0){ + WOLFSSL_MSG("hmac update error"); + ret = 0; + } + } + + return ret; +} + +/* Finalize HMAC operation. + * + * @param [in, out] ctx HMAC context object. + * @param [out] hash Buffer to hold HMAC result. + * Must be able to hold bytes equivalent to digest size. + * @param [out] len Length of HMAC result. May be NULL. + * @return 1 on success. + * @return 0 when ctx or hash is NULL. + * @return 0 when HMAC finalization fails. + */ +int wolfSSL_HMAC_Final(WOLFSSL_HMAC_CTX* ctx, unsigned char* hash, + unsigned int* len) +{ + int ret = 1; + int rc; + + WOLFSSL_MSG("wolfSSL_HMAC_Final"); + + /* Validate parameters. */ + if ((ctx == NULL) || (hash == NULL)) { + WOLFSSL_MSG("invalid parameter"); + ret = 0; + } + + if (ret == 1) { + WOLFSSL_MSG("final hmac"); + /* Finalize wolfSSL HMAC object. */ + rc = wc_HmacFinal(&ctx->hmac, hash); + if (rc != 0){ + WOLFSSL_MSG("final hmac error"); + ret = 0; + } + } + if ((ret == 1) && (len != NULL)) { + WOLFSSL_MSG("setting output len"); + /* Get the length of the output based on digest type. */ + *len = wolfssl_mac_len((unsigned char)ctx->type); + } + + return ret; +} + + +/* Cleanup the HMAC operation. + * + * Not an OpenSSL compatibility API. + * + * @param [in, out] ctx HMAC context object. + * @return 1 indicating success. + */ +int wolfSSL_HMAC_cleanup(WOLFSSL_HMAC_CTX* ctx) +{ + WOLFSSL_MSG("wolfSSL_HMAC_cleanup"); + + if (ctx != NULL) { + /* Free the dynamic data in the wolfSSL HMAC object. */ + wc_HmacFree(&ctx->hmac); + } + + return 1; +} + +/* HMAC data using the specified EVP digest. + * + * @param [in] evp_md EVP digest. + * @param [in] key Array of bytes representing key. + * @param [in] keySz Number of bytes in key. + * 0+ in non-FIPS, 14+ in FIPS. + * @param [in] data Data to MAC. + * @param [in] len Length in bytes of data to MAC. + * @param [out] md HMAC output. + * @param [out] md_len Length of HMAC output in bytes. May be NULL. + * @return Buffer holding HMAC output. + * @return NULL on failure. + */ +unsigned char* wolfSSL_HMAC(const WOLFSSL_EVP_MD* evp_md, const void* key, + int key_len, const unsigned char* data, int len, unsigned char* md, + unsigned int* md_len) +{ + unsigned char* ret = NULL; + int rc = 0; + int type = 0; + int hmacLen; +#ifdef WOLFSSL_SMALL_STACK + Hmac* hmac = NULL; +#else + Hmac hmac[1]; +#endif + void* heap = NULL; + + /* Validate parameters. */ + if ((evp_md == NULL) || (key == NULL) || (md == NULL)) { + rc = BAD_FUNC_ARG; + } + + if (rc == 0) { + /* Get the hash type corresponding to the EVP digest. */ + rc = wolfssl_evp_md_to_hash_type(evp_md, &type); + } +#ifdef WOLFSSL_SMALL_STACK + if (rc == 0) { + /* Allocate dynamic memory for a wolfSSL HMAC object. */ + hmac = (Hmac*)XMALLOC(sizeof(Hmac), heap, DYNAMIC_TYPE_HMAC); + if (hmac == NULL) { + rc = MEMORY_E; + } + } +#endif + if (rc == 0) { + /* Get the HMAC output length. */ + hmacLen = wolfssl_mac_len((unsigned char)type); + /* 0 indicates the digest is not supported. */ + if (hmacLen == 0) { + rc = BAD_FUNC_ARG; + } + } + /* Initialize the wolfSSL HMAC object. */ + if ((rc == 0) && (wc_HmacInit(hmac, heap, INVALID_DEVID) == 0)) { + /* Set the key into the wolfSSL HMAC object. */ + rc = wc_HmacSetKey(hmac, type, (const byte*)key, key_len); + if (rc == 0) { + /* Update the wolfSSL HMAC object with data. */ + rc = wc_HmacUpdate(hmac, data, len); + } + /* Finalize the wolfSSL HMAC object. */ + if ((rc == 0) && (wc_HmacFinal(hmac, md) == 0)) { + /* Return the length of the HMAC output if required. */ + if (md_len != NULL) { + *md_len = hmacLen; + } + /* Set the buffer to return. */ + ret = md; + } + /* Dispose of dynamic memory associated with the wolfSSL HMAC object. */ + wc_HmacFree(hmac); + } + +#ifdef WOLFSSL_SMALL_STACK + /* Free dynamic memory of a wolfSSL HMAC object. */ + XFREE(hmac, heap, DYNAMIC_TYPE_HMAC); +#endif + return ret; +} + +/* Get the HMAC output size. + * + * @param [in] ctx HMAC context object. + * @return Size of HMAC output in bytes. + * @return 0 when ctx is NULL or no digest algorithm set. + */ +size_t wolfSSL_HMAC_size(const WOLFSSL_HMAC_CTX* ctx) +{ + size_t ret = 0; + + if (ctx != NULL) { + /* Look up digest size with wolfSSL. */ + ret = (size_t)wc_HashGetDigestSize((enum wc_HashType)ctx->hmac.macType); + } + + return ret; +} +#endif /* OPENSSL_EXTRA */ + +/******************************************************************************* + * END OF HMAC API + ******************************************************************************/ + +/******************************************************************************* + * START OF CMAC API + ******************************************************************************/ + +#ifdef OPENSSL_EXTRA +#if defined(WOLFSSL_CMAC) && defined(OPENSSL_EXTRA) && \ + defined(WOLFSSL_AES_DIRECT) +/* Allocate a new CMAC context object. + * + * TODO: make fields static. + * + * @return A CMAC context object on success. + * @return NULL on failure. + */ +WOLFSSL_CMAC_CTX* wolfSSL_CMAC_CTX_new(void) +{ + WOLFSSL_CMAC_CTX* ctx = NULL; + + /* Allocate memory for CMAC context object. */ + ctx = (WOLFSSL_CMAC_CTX*)XMALLOC(sizeof(WOLFSSL_CMAC_CTX), NULL, + DYNAMIC_TYPE_OPENSSL); + if (ctx != NULL) { + /* Allocate memory for wolfSSL CMAC object. */ + ctx->internal = (Cmac*)XMALLOC(sizeof(Cmac), NULL, DYNAMIC_TYPE_CMAC); + if (ctx->internal == NULL) { + XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL); + ctx = NULL; + } + } + if (ctx != NULL) { + /* Allocate memory for EVP cipher context object. */ + ctx->cctx = wolfSSL_EVP_CIPHER_CTX_new(); + if (ctx->cctx == NULL) { + XFREE(ctx->internal, NULL, DYNAMIC_TYPE_CMAC); + XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL); + ctx = NULL; + } + } + + return ctx; +} + +/* Free CMAC context object and dynamically allocated fields. + * + * ctx is deallocated and can no longer be used after this call. + * + * @param [in] ctx CMAC context object. + */ +void wolfSSL_CMAC_CTX_free(WOLFSSL_CMAC_CTX *ctx) +{ + if (ctx != NULL) { + /* Deallocate dynamically allocated fields. */ + if (ctx->internal != NULL) { + XFREE(ctx->internal, NULL, DYNAMIC_TYPE_CMAC); + } + if (ctx->cctx != NULL) { + wolfSSL_EVP_CIPHER_CTX_free(ctx->cctx); + } + /* Deallocate CMAC context object. */ + XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL); + } +} + +/* Return a reference to the EVP cipher context. + * + * @param [in] ctx CMAC context object. + * @return EVP cipher context. + * @return NULL when ctx is NULL. + */ +WOLFSSL_EVP_CIPHER_CTX* wolfSSL_CMAC_CTX_get0_cipher_ctx(WOLFSSL_CMAC_CTX* ctx) +{ + WOLFSSL_EVP_CIPHER_CTX* cctx = NULL; + + if (ctx != NULL) { + /* Return EVP cipher context object. */ + cctx = ctx->cctx; + } + + return cctx; +} + +/* Initialize the CMAC operation. + * + * @param [in, out] cmac CMAC context object. + * @param [in] key Symmetric key to use. + * @param [in] keySz Length of key in bytes. + * @param [in] cipher EVP cipher object describing encryption algorithm + * to use. + * @param [in] engine wolfSSL Engine. Not used. + * @return 1 on success. + * @return 0 when ctx or cipher is NULL. + * @return 0 when cipher is not an AES-CBC algorithm. + * @return 0 when key length does not match cipher. + */ +int wolfSSL_CMAC_Init(WOLFSSL_CMAC_CTX* ctx, const void *key, size_t keySz, + const WOLFSSL_EVP_CIPHER* cipher, WOLFSSL_ENGINE* engine) +{ + int ret = 1; + + (void)engine; + + WOLFSSL_ENTER("wolfSSL_CMAC_Init"); + + /* Validate parameters. */ + if ((ctx == NULL) || (cipher == NULL)) { + ret = 0; + } + /* Only AES-CBC ciphers are supported. */ + if ((ret == 1) && (cipher != EVP_AES_128_CBC) && + (cipher != EVP_AES_192_CBC) && (cipher != EVP_AES_256_CBC)) { + ret = 0; + } + /* Key length must match cipher. */ + if ((ret == 1) && ((int)keySz != wolfSSL_EVP_Cipher_key_length(cipher))) { + ret = 0; + } + + /* Initialize the wolfCrypt CMAC object. */ + if ((ret == 1) && (wc_InitCmac((Cmac*)ctx->internal, (const byte*)key, + (word32)keySz, WC_CMAC_AES, NULL) != 0)) { + ret = 0; + } + if (ret == 1) { + /* Initialize the EVP cipher context object for encryption. */ + ret = wolfSSL_EVP_CipherInit(ctx->cctx, cipher, (const byte*)key, NULL, + 1); + } + + WOLFSSL_LEAVE("wolfSSL_CMAC_Init", ret); + + return ret; +} + +/* Update the CMAC operation with data. + * + * @param [in, out] ctx CMAC context object. + * @param [in] data Data to MAC as a byte array. + * @param [in] len Length of data in bytes. + * @return 1 on success. + * @return 0 when ctx is NULL. + */ +int wolfSSL_CMAC_Update(WOLFSSL_CMAC_CTX* ctx, const void* data, size_t len) +{ + int ret = 1; + + WOLFSSL_ENTER("wolfSSL_CMAC_Update"); + + /* Validate parameters. */ + if (ctx == NULL) { + ret = 0; + } + + /* Update the wolfCrypto CMAC object with data. */ + if ((ret == 1) && (data != NULL) && (wc_CmacUpdate((Cmac*)ctx->internal, + (const byte*)data, (word32)len) != 0)) { + ret = 0; + } + + WOLFSSL_LEAVE("wolfSSL_CMAC_Update", ret); + + return ret; +} + +/* Finalize the CMAC operation into output buffer. + * + * @param [in, out] ctx CMAC context object. + * @param [out] out Buffer to place CMAC result into. + * Must be able to hold AES_BLOCK_SIZE bytes. + * @param [out] len Length of CMAC result. May be NULL. + * @return 1 on success. + * @return 0 when ctx is NULL. + */ +int wolfSSL_CMAC_Final(WOLFSSL_CMAC_CTX* ctx, unsigned char* out, size_t* len) +{ + int ret = 1; + int blockSize; + word32 len32; + + WOLFSSL_ENTER("wolfSSL_CMAC_Final"); + + /* Valiudate parameters. */ + if (ctx == NULL) { + ret = 0; + } + + if (ret == 1) { + /* Get the expected output size. */ + blockSize = EVP_CIPHER_CTX_block_size(ctx->cctx); + /* Check value is valid. */ + if (blockSize <= 0) { + ret = 0; + } + else { + /* wolfCrypt CMAC expects buffer size. */ + len32 = (word32)blockSize; + /* Return size if required. */ + if (len != NULL) { + *len = blockSize; + } + } + } + if ((ret == 1) && (out != NULL)) { + /* Calculate MAC result with wolfCrypt CMAC object. */ + if (wc_CmacFinal((Cmac*)ctx->internal, out, &len32) != 0) { + ret = 0; + } + /* TODO: Is this necessary? Length should not change. */ + /* Return actual size if required. */ + else if (len != NULL) { + *len = (size_t)len32; + } + } + + WOLFSSL_LEAVE("wolfSSL_CMAC_Final", ret); + + return ret; +} +#endif /* WOLFSSL_CMAC && OPENSSL_EXTRA && WOLFSSL_AES_DIRECT */ +#endif /* OPENSSL_EXTRA */ + +/******************************************************************************* + * END OF CMAC API + ******************************************************************************/ + +/******************************************************************************* + * START OF DES API + ******************************************************************************/ + +#ifdef OPENSSL_EXTRA +#ifndef NO_DES3 +/* Set parity of the DES key. + * + * @param [in, out] key DES key. + */ +void wolfSSL_DES_set_odd_parity(WOLFSSL_DES_cblock* key) +{ + int i; + + WOLFSSL_ENTER("wolfSSL_DES_set_odd_parity"); + + for (i = 0; i < DES_KEY_SIZE; i++) { + unsigned char c = (*key)[i]; + /* Set bottom bit to odd parity - XOR of each bit is to be 1. + * XOR 1 to XOR of each bit. + * When even parity, the value will be 1 and the bottom bit will be + * flipped. + * When odd parity, the value will be 0 and the bottom bit will be + * unchanged. + */ + c ^= ((c >> 0) ^ (c >> 1) ^ (c >> 2) ^ (c >> 3) ^ (c >> 4) ^ (c >> 5) ^ + (c >> 6) ^ (c >> 7) ^ 0x01) & 0x01; + (*key)[i] = c; + } +} + +/* Check parity of the DES key. + * + * @param [in] key DES key. + * @return 1 when odd parity on all bytes. + * @return 0 when even parity on any byte. + */ +int wolfSSL_DES_check_key_parity(WOLFSSL_DES_cblock *key) +{ + int i; + /* Assume odd parity. */ + unsigned char p = 1; + + WOLFSSL_ENTER("wolfSSL_DES_check_key_parity"); + + for (i = 0; i < DES_KEY_SIZE; i++) { + unsigned char c = (*key)[i]; + /* p will be 0 when parity is even (XOR of bits is 0). */ + p &= (c >> 0) ^ (c >> 1) ^ (c >> 2) ^ (c >> 3) ^ (c >> 4) ^ (c >> 5) ^ + (c >> 6) ^ (c >> 7); + } + + /* Only care about bottom bit. */ + return p & 1; +} + +/* Check whether key data is the two 32-bit words. + * + * return true in fail case (1) + * + * @param [in] k1 First part of key. + * @param [in] k2 Second part of key. + * @param [in] key DES key as an array of bytes. + **/ +static int wolfssl_des_check(word32 k1, word32 k2, unsigned char* key) +{ + /* Compare the two 32-bit words. */ + return (((word32*)key)[0] == k1) && (((word32*)key)[1] == k2); +} + +/* Check key is not weak. + * + * Weak key list from Nist "Recommendation for the Triple Data Encryption + * Algorithm (TDEA) Block Cipher" + * + * @param [in] key DES key. + * @return 0 when #key is not a weak key. + * @return 1 when #key is a weak key. + */ +int wolfSSL_DES_is_weak_key(WOLFSSL_const_DES_cblock* key) +{ + int ret = 0; + + WOLFSSL_ENTER("wolfSSL_DES_is_weak_key"); + + /* Validate parameter. */ + if (key == NULL) { + WOLFSSL_MSG("NULL key passed in"); + ret = 1; + } + + /* Check weak keys - endian doesn't matter. */ + if ((ret == 0) && (wolfssl_des_check(0x01010101, 0x01010101, *key) || + wolfssl_des_check(0xFEFEFEFE, 0xFEFEFEFE, *key) || + wolfssl_des_check(0xE0E0E0E0, 0xF1F1F1F1, *key) || + wolfssl_des_check(0x1F1F1F1F, 0x0E0E0E0E, *key))) { + WOLFSSL_MSG("Weak key found"); + ret = 1; + } + + /* Check semi-weak keys - endian doesn't matter. */ + if ((ret == 0) && (wolfssl_des_check(0x011F011F, 0x010E010E, *key) || + wolfssl_des_check(0x1F011F01, 0x0E010E01, *key) || + wolfssl_des_check(0x01E001E0, 0x01F101F1, *key) || + wolfssl_des_check(0xE001E001, 0xF101F101, *key) || + wolfssl_des_check(0x01FE01FE, 0x01FE01FE, *key) || + wolfssl_des_check(0xFE01FE01, 0xFE01FE01, *key) || + wolfssl_des_check(0x1FE01FE0, 0x0EF10EF1, *key) || + wolfssl_des_check(0xE01FE01F, 0xF10EF10E, *key) || + wolfssl_des_check(0x1FFE1FFE, 0x0EFE0EFE, *key) || + wolfssl_des_check(0xFE1FFE1F, 0xFE0EFE0E, *key) || + wolfssl_des_check(0xE0FEE0FE, 0xF1FEF1FE, *key) || + wolfssl_des_check(0xFEE0FEE0, 0xFEF1FEF1, *key))) { + WOLFSSL_MSG("Semi-weak key found"); + ret = 1; + } + + return ret; +} + +/* Set key into schedule if key parity is odd and key is not weak. + * + * @param [in] key DES key data. + * @param [out] schedule DES key schedule. + * @return 0 on success. + * @return -1 when parity is not odd. + * @return -2 when key or schedule is NULL. + * @return -2 when key is weak or semi-weak. + */ +int wolfSSL_DES_set_key_checked(WOLFSSL_const_DES_cblock* key, + WOLFSSL_DES_key_schedule* schedule) +{ + int ret = 0; + + /* Validate parameters. */ + if ((key == NULL) || (schedule == NULL)) { + WOLFSSL_MSG("Bad argument passed to wolfSSL_DES_set_key_checked"); + ret = -2; + } + + /* Check key parity is odd. */ + if ((ret == 0) && (!wolfSSL_DES_check_key_parity(key))) { + WOLFSSL_MSG("Odd parity test fail"); + ret = -1; + } + /* Check whether key is weak. */ + if ((ret == 0) && wolfSSL_DES_is_weak_key(key)) { + WOLFSSL_MSG("Weak key found"); + ret = -2; + } + if (ret == 0) { + /* Key data passed checks, now copy key into schedule. */ + XMEMCPY(schedule, key, DES_KEY_SIZE); + } + + return ret; +} + +/* Set key into schedule - no checks on key data performed. + * + * @param [in] key DES key data. + * @param [out] schedule DES key schedule. + */ +void wolfSSL_DES_set_key_unchecked(WOLFSSL_const_DES_cblock* key, + WOLFSSL_DES_key_schedule* schedule) +{ + /* Validate parameters. */ + if ((key != NULL) && (schedule != NULL)) { + /* Copy the key data into the schedule. */ + XMEMCPY(schedule, key, DES_KEY_SIZE); + } +} + +/* Set key into schedule. + * + * @param [in] key DES key data. + * @param [out] schedule DES key schedule. + * @return 0 on success. + * @return -1 when parity is not odd. + * @return -2 when key or schedule is NULL. + * @return -2 when key is weak or semi-weak. + */ +int wolfSSL_DES_set_key(WOLFSSL_const_DES_cblock* key, + WOLFSSL_DES_key_schedule* schedule) +{ +#ifdef WOLFSSL_CHECK_DESKEY + return wolfSSL_DES_set_key_checked(key, schedule); +#else + wolfSSL_DES_set_key_unchecked(key, schedule); + return 0; +#endif +} + +/* Set the key schedule from the DES key. + * + * TODO: OpenSSL checks parity and weak keys. + * + * @param [in] key DES key data. + * @param [out] schedule DES key schedule. + * @return 0 on success. + */ +int wolfSSL_DES_key_sched(WOLFSSL_const_DES_cblock* key, + WOLFSSL_DES_key_schedule* schedule) +{ + WOLFSSL_ENTER("wolfSSL_DES_key_sched"); + + /* Check parameters are usable. */ + if ((key == NULL) || (schedule == NULL)) { + WOLFSSL_MSG("Null argument passed in"); + } + else { + /* Copy the key data into the schedule. */ + XMEMCPY(schedule, key, sizeof(WOLFSSL_const_DES_cblock)); + } + + return 0; +} + +/* Encrypt with DES-CBC to create a checksum. + * + * Intended to behave similar to Kerberos mit_des_cbc_cksum. + * Returns the last 4 bytes of cipher text. + * + * TODO: Encrypt one block at a time instead of allocating a large amount. + * + * @param [in] in Data to encrypt. + * @param [out] out Last encrypted block. + * @param [in] length Length of data to encrypt. + * @param [in] sc Key schedule for encryption. + * @param [in] iv Initialization vector for CBC. + * @return Checksum of encryption. + * @return 0 on error. + */ +WOLFSSL_DES_LONG wolfSSL_DES_cbc_cksum(const unsigned char* in, + WOLFSSL_DES_cblock* out, long length, WOLFSSL_DES_key_schedule* sc, + WOLFSSL_const_DES_cblock* iv) +{ + WOLFSSL_DES_LONG ret = 0; + int err = 0; + unsigned char* data = (unsigned char*)in; + unsigned char* tmp = NULL; + long dataSz = length; + + WOLFSSL_ENTER("wolfSSL_DES_cbc_cksum"); + + /* Validate parameters. */ + if ((in == NULL) || (out == NULL) || (sc == NULL) || (iv == NULL)) { + WOLFSSL_MSG("Bad argument passed in"); + err = 1; + } + + /* When input length is not a multiple of DES_BLOCK_SIZE pad with 0s. */ + if ((!err) && (dataSz % DES_BLOCK_SIZE)) { + /* Allocate a buffer big enough to hold padded input. */ + dataSz += DES_BLOCK_SIZE - (dataSz % DES_BLOCK_SIZE); + data = (unsigned char*)XMALLOC(dataSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (data == NULL) { + WOLFSSL_MSG("Issue creating temporary buffer"); + err = 1; + } + else { + /* Copy input and pad with 0s. */ + XMEMCPY(data, in, length); + XMEMSET(data + length, 0, dataSz - length); + } + } + + if (!err) { + /* Allocate buffer to hold encrypted data. */ + tmp = (unsigned char*)XMALLOC(dataSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (tmp == NULL) { + WOLFSSL_MSG("Issue creating temporary buffer"); + err = 1; + } + } + + if (!err) { + /* Encrypt data into temporary. */ + wolfSSL_DES_cbc_encrypt(data, tmp, dataSz, sc, (WOLFSSL_DES_cblock*)iv, + DES_ENCRYPT); + /* Copy out last block. */ + XMEMCPY((unsigned char*)out, tmp + (dataSz - DES_BLOCK_SIZE), + DES_BLOCK_SIZE); + + /* Use the last half of the encrypted block as the checksum. */ + ret = (((*((unsigned char*)out + 4) & 0xFF) << 24) | + ((*((unsigned char*)out + 5) & 0xFF) << 16) | + ((*((unsigned char*)out + 6) & 0xFF) << 8) | + (*((unsigned char*)out + 7) & 0xFF) ); + } + + /* Dispose of allocated memory. */ + XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (data != in) { + XFREE(data, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } + return ret; +} + +/* Encrypt/decrypt data with DES-CBC. + * + * TODO: OpenSSL expects a length that is a multiple of the block size but + * we are padding the last block. This is not a padding API. + * TODO: Validate parameters? + * + * @param [in] input Data to encipher. + * @param [out] output Enciphered data. + * @param [in] length Length of data to encipher. + * @param [in] schedule Key schedule. + * @param [in] ivec IV for CBC operation. + * @param [in] enc Whether to encrypt. + */ +void wolfSSL_DES_cbc_encrypt(const unsigned char* input, unsigned char* output, + long length, WOLFSSL_DES_key_schedule* schedule, WOLFSSL_DES_cblock* ivec, + int enc) +{ +#ifdef WOLFSSL_SMALL_STACK + Des* des = NULL; +#else + Des des[1]; +#endif + byte lastBlock[DES_BLOCK_SIZE]; + + WOLFSSL_ENTER("wolfSSL_DES_cbc_encrypt"); + +#ifdef WOLFSSL_SMALL_STACK + des = XMALLOC(sizeof(Des3), NULL, DYNAMIC_TYPE_CIPHER); + if (des == NULL) { + WOLFSSL_MSG("Failed to allocate memory for Des object"); + } + else +#endif + /* OpenSSL compat, no ret */ + if (wc_Des_SetKey(des, (const byte*)schedule, (const byte*)ivec, + !enc) != 0) { + WOLFSSL_MSG("wc_Des_SetKey return error."); + } + else { + /* Last incomplete block size. 0 means none over. */ + int lb_sz = length % DES_BLOCK_SIZE; + /* Length of data that is a multiple of a block. */ + word32 len = (word32)(length - lb_sz); + + if (enc == DES_ENCRYPT) { + /* Encrypt full blocks into output. */ + wc_Des_CbcEncrypt(des, output, input, len); + if (lb_sz != 0) { + /* Create a 0 padded block from remaining bytes. */ + XMEMSET(lastBlock, 0, DES_BLOCK_SIZE); + XMEMCPY(lastBlock, input + len, lb_sz); + /* Encrypt last block into output. */ + wc_Des_CbcEncrypt(des, output + len, lastBlock, + (word32)DES_BLOCK_SIZE); + } + } + else { + /* Decrypt full blocks into output. */ + wc_Des_CbcDecrypt(des, output, input, len); + if (lb_sz != 0) { + /* Decrypt the last block that is not going to be full size. */ + wc_Des_CbcDecrypt(des, lastBlock, input + len, + (word32)DES_BLOCK_SIZE); + /* Copy out the required amount of the decrypted block. */ + XMEMCPY(output + len, lastBlock, lb_sz); + } + } + } + +#ifdef WOLFSSL_SMALL_STACK + XFREE(des, NULL, DYNAMIC_TYPE_CIPHER); +#endif +} + +/* Encrypt/decrypt data with DES-CBC. Sets the IV for following operation. + * + * TODO: OpenSSL expects a length that is a multiple of the block size but + * we are padding the last block. This is not a padding API. + * TODO: Validate parameters? + * + * @param [in] input Data to encipher. + * @param [out] output Enciphered data. + * @param [in] length Length of data to encipher. + * @param [in] schedule Key schedule. + * @param [in, out] ivec IV for CBC operation. + * @param [in] enc Whether to encrypt. + */ +void wolfSSL_DES_ncbc_encrypt(const unsigned char* input, unsigned char* output, + long length, WOLFSSL_DES_key_schedule* schedule, WOLFSSL_DES_cblock* ivec, + int enc) +{ + unsigned char tmp[DES_IV_SIZE]; + /* Calculate length to a multiple of block size. */ + size_t offset = (size_t)length; + + WOLFSSL_ENTER("wolfSSL_DES_ncbc_encrypt"); + + offset = (offset + DES_BLOCK_SIZE - 1) / DES_BLOCK_SIZE; + offset *= DES_BLOCK_SIZE; + offset -= DES_BLOCK_SIZE; + if (enc == DES_ENCRYPT) { + /* Encrypt data. */ + wolfSSL_DES_cbc_encrypt(input, output, length, schedule, ivec, enc); + /* Use last encrypted block as new IV. */ + XMEMCPY(ivec, output + offset, DES_IV_SIZE); + } + else { + /* Get last encrypted block for new IV. */ + XMEMCPY(tmp, input + offset, DES_IV_SIZE); + /* Decrypt data. */ + wolfSSL_DES_cbc_encrypt(input, output, length, schedule, ivec, enc); + /* Use last encrypted block as new IV. */ + XMEMCPY(ivec, tmp, DES_IV_SIZE); + } +} + +/* Encrypt/decrypt data with DES-CBC. + * + * WOLFSSL_DES_key_schedule is an unsigned char array of size 8. + * + * TODO: OpenSSL expects a length that is a multiple of the block size but + * we are padding the last block. This is not a padding API. + * TODO: Validate parameters? + * + * @param [in] input Data to encipher. + * @param [out] output Enciphered data. + * @param [in] length Length of data to encipher. + * @param [in] schedule Key schedule. + * @param [in, out] ivec IV for CBC operation. + * @param [in] enc Whether to encrypt. + */ +void wolfSSL_DES_ede3_cbc_encrypt(const unsigned char* input, + unsigned char* output, long sz, WOLFSSL_DES_key_schedule* ks1, + WOLFSSL_DES_key_schedule* ks2, WOLFSSL_DES_key_schedule* ks3, + WOLFSSL_DES_cblock* ivec, int enc) +{ +#ifdef WOLFSSL_SMALL_STACK + Des3* des3; +#else + Des3 des3[1]; +#endif + + WOLFSSL_ENTER("wolfSSL_DES_ede3_cbc_encrypt"); + +#ifdef WOLFSSL_SMALL_STACK + des3 = XMALLOC(sizeof(Des3), NULL, DYNAMIC_TYPE_CIPHER); + if (des3 == NULL) { + WOLFSSL_MSG("Failed to allocate memory for Des3 object"); + sz = 0; + } +#endif + + if (sz > 0) { + int ret; + byte key[DES3_KEY_SIZE]; + byte lastBlock[DES_BLOCK_SIZE]; + int lb_sz; + word32 len; + + /* Copy the three keys into the buffer for wolfCrypt DES. */ + XMEMCPY(key + 0 * DES_BLOCK_SIZE, *ks1, DES_BLOCK_SIZE); + XMEMCPY(key + 1 * DES_BLOCK_SIZE, *ks2, DES_BLOCK_SIZE); + XMEMCPY(key + 2 * DES_BLOCK_SIZE, *ks3, DES_BLOCK_SIZE); + + /* Last incomplete block size. 0 means none over. */ + lb_sz = sz % DES_BLOCK_SIZE; + /* Length of data that is a multiple of a block. */ + len = (word32)(sz - lb_sz); + + /* Initialize wolfCrypt DES3 object. */ + XMEMSET(des3, 0, sizeof(Des3)); + ret = wc_Des3Init(des3, NULL, INVALID_DEVID); + (void)ret; + + if (enc == DES_ENCRYPT) { + /* Initialize wolfCrypt DES3 object. */ + if (wc_Des3_SetKey(des3, key, (const byte*)ivec, DES_ENCRYPTION) + == 0) { + /* Encrypt full blocks into output. */ + ret = wc_Des3_CbcEncrypt(des3, output, input, len); + (void)ret; + #if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &des3->asyncDev, WC_ASYNC_FLAG_NONE); + (void)ret; + #endif + if (lb_sz != 0) { + /* Create a 0 padded block from remaining bytes. */ + XMEMSET(lastBlock, 0, DES_BLOCK_SIZE); + XMEMCPY(lastBlock, input + len, lb_sz); + /* Encrypt last block into output. */ + ret = wc_Des3_CbcEncrypt(des3, output + len, lastBlock, + (word32)DES_BLOCK_SIZE); + (void)ret; + #if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &des3->asyncDev, + WC_ASYNC_FLAG_NONE); + (void)ret; + #endif + /* Copy the last encrypted block as IV for next decrypt. */ + XMEMCPY(ivec, output + len, DES_BLOCK_SIZE); + } + else { + /* Copy the last encrypted block as IV for next decrypt. */ + XMEMCPY(ivec, output + len - DES_BLOCK_SIZE, + DES_BLOCK_SIZE); + } + } + } + else { + /* Initialize wolfCrypt DES3 object. */ + if (wc_Des3_SetKey(des3, key, (const byte*)ivec, DES_DECRYPTION) + == 0) { + /* Copy the last encrypted block as IV for next decrypt. */ + if (lb_sz != 0) { + XMEMCPY(ivec, input + len, DES_BLOCK_SIZE); + } + else { + XMEMCPY(ivec, input + len - DES_BLOCK_SIZE, DES_BLOCK_SIZE); + } + /* Decrypt full blocks into output. */ + ret = wc_Des3_CbcDecrypt(des3, output, input, len); + (void)ret; + #if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &des3->asyncDev, WC_ASYNC_FLAG_NONE); + (void)ret; + #endif + if (lb_sz != 0) { + /* Decrypt the last block that is not going to be full size. + */ + ret = wc_Des3_CbcDecrypt(des3, lastBlock, input + len, + (word32)DES_BLOCK_SIZE); + (void)ret; + #if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &des3->asyncDev, + WC_ASYNC_FLAG_NONE); + (void)ret; + #endif + /* Copy out the required amount of the decrypted block. */ + XMEMCPY(output + len, lastBlock, lb_sz); + } + } + } + wc_Des3Free(des3); + } + +#ifdef WOLFSSL_SMALL_STACK + XFREE(des3, NULL, DYNAMIC_TYPE_CIPHER); +#endif +} + +#ifdef WOLFSSL_DES_ECB +/* Encrypt or decrypt input message desa with key and get output in desb. + * + * @param [in] in Block to encipher with DES-ECB. + * @param [out] out Enciphered block. + * @param [in] key DES key schedule. + * @param [in] enc Whether to encrypt. + */ +void wolfSSL_DES_ecb_encrypt(WOLFSSL_DES_cblock* in, WOLFSSL_DES_cblock* out, + WOLFSSL_DES_key_schedule* key, int enc) +{ +#ifdef WOLFSSL_SMALL_STACK + Des* des = NULL; +#else + Des des[1]; +#endif + + WOLFSSL_ENTER("wolfSSL_DES_ecb_encrypt"); + + /* Validate parameters. */ + if ((in == NULL) || (out == NULL) || (key == NULL) || + ((enc != DES_ENCRYPT) && (enc != DES_DECRYPT))) { + WOLFSSL_MSG("Bad argument passed to wolfSSL_DES_ecb_encrypt"); + } +#ifdef WOLFSSL_SMALL_STACK + else if ((des = XMALLOC(sizeof(Des), NULL, DYNAMIC_TYPE_CIPHER)) == NULL) { + WOLFSSL_MSG("Failed to allocate memory for Des object"); + } +#endif + /* Set key in wolfCrypt DES object for encryption or decryption. + * DES_ENCRYPT = 1, wolfSSL DES_ENCRYPTION = 0. + * DES_DECRYPT = 0, wolfSSL DES_DECRYPTION = 1. + */ + else if (wc_Des_SetKey(des, (const byte*)key, NULL, !enc) != 0) { + WOLFSSL_MSG("wc_Des_SetKey return error."); + } + else if (enc == DES_ENCRYPT) { + /* Encrypt a block with wolfCrypt DES object. */ + if (wc_Des_EcbEncrypt(des, (byte*)out, (const byte*)in, DES_KEY_SIZE) + != 0) { + WOLFSSL_MSG("wc_Des_EcbEncrypt return error."); + } + } + else { + /* Decrypt a block with wolfCrypt DES object. */ + if (wc_Des_EcbDecrypt(des, (byte*)out, (const byte*)in, DES_KEY_SIZE) + != 0) { + WOLFSSL_MSG("wc_Des_EcbDecrpyt return error."); + } + } + +#ifdef WOLFSSL_SMALL_STACK + XFREE(des, NULL, DYNAMIC_TYPE_CIPHER); +#endif +} +#endif +#endif /* NO_DES3 */ +#endif /* OPENSSL_EXTRA */ + +/******************************************************************************* + * END OF DES API + ******************************************************************************/ + +/******************************************************************************* + * START OF AES API + ******************************************************************************/ + +#ifdef OPENSSL_EXTRA + +#ifndef NO_AES + +/* Sets the key into the AES key object for encryption or decryption. + * + * TODO: check bits value? + * TODO: initialize AES key? + * + * @param [in] key Key data. + * @param [in] bits Number of bits in key. + * @param [out] aes AES key object. + * @param [in] enc Whether to encrypt. AES_ENCRYPT or AES_DECRYPT. + * @return 0 on success. + * @return -1 when key or aes is NULL. + * @return -1 when setting key with wolfCrypt fails. + */ +static int wolfssl_aes_set_key(const unsigned char *key, const int bits, + AES_KEY *aes, int enc) +{ + typedef char aes_test[sizeof(AES_KEY) >= sizeof(Aes) ? 1 : -1]; + (void)sizeof(aes_test); + + /* Validate parameters. */ + if ((key == NULL) || (aes == NULL)) { + WOLFSSL_MSG("Null argument passed in"); + return -1; + } + + XMEMSET(aes, 0, sizeof(AES_KEY)); + if (wc_AesSetKey((Aes*)aes, key, ((bits)/8), NULL, enc) != 0) { + WOLFSSL_MSG("Error in setting AES key"); + return -1; + } + return 0; +} + +/* Sets the key into the AES key object for encryption. + * + * @param [in] key Key data. + * @param [in] bits Number of bits in key. + * @param [out] aes AES key object. + * @return 0 on success. + * @return -1 when key or aes is NULL. + * @return -1 when setting key with wolfCrypt fails. + */ +int wolfSSL_AES_set_encrypt_key(const unsigned char *key, const int bits, + AES_KEY *aes) +{ + WOLFSSL_ENTER("wolfSSL_AES_set_encrypt_key"); + + return wolfssl_aes_set_key(key, bits, aes, AES_ENCRYPT); +} + +/* Sets the key into the AES key object for decryption. + * + * @param [in] key Key data. + * @param [in] bits Number of bits in key. + * @param [out] aes AES key object. + * @return 0 on success. + * @return -1 when key or aes is NULL. + * @return -1 when setting key with wolfCrypt fails. + */ +int wolfSSL_AES_set_decrypt_key(const unsigned char *key, const int bits, + AES_KEY *aes) +{ + WOLFSSL_ENTER("wolfSSL_AES_set_decrypt_key"); + + return wolfssl_aes_set_key(key, bits, aes, AES_DECRYPT); +} + +#ifdef WOLFSSL_AES_DIRECT +/* Encrypt a 16-byte block of data using AES-ECB. + * + * wolfSSL_AES_set_encrypt_key() must have been called. + * + * #input must contain AES_BLOCK_SIZE bytes of data. + * #output must be a buffer at least AES_BLOCK_SIZE bytes in length. + * + * @param [in] input Data to encrypt. + * @param [out] output Encrypted data. + * @param [in] key AES key to use for encryption. + */ +void wolfSSL_AES_encrypt(const unsigned char* input, unsigned char* output, + AES_KEY *key) +{ + WOLFSSL_ENTER("wolfSSL_AES_encrypt"); + + /* Validate parameters. */ + if ((input == NULL) || (output == NULL) || (key == NULL)) { + WOLFSSL_MSG("Null argument passed in"); + } + else +#if !defined(HAVE_SELFTEST) && \ + (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3))) + /* Encrypt a block with wolfCrypt AES. */ + if (wc_AesEncryptDirect((Aes*)key, output, input) != 0) { + WOLFSSL_MSG("wc_AesEncryptDirect failed"); + } +#else + { + /* Encrypt a block with wolfCrypt AES. */ + wc_AesEncryptDirect((Aes*)key, output, input); + } +#endif +} + + +/* Decrypt a 16-byte block of data using AES-ECB. + * + * wolfSSL_AES_set_decrypt_key() must have been called. + * + * #input must contain AES_BLOCK_SIZE bytes of data. + * #output must be a buffer at least AES_BLOCK_SIZE bytes in length. + * + * @param [in] input Data to decrypt. + * @param [out] output Decrypted data. + * @param [in] key AES key to use for encryption. + */ +void wolfSSL_AES_decrypt(const unsigned char* input, unsigned char* output, + AES_KEY *key) +{ + WOLFSSL_ENTER("wolfSSL_AES_decrypt"); + + /* Validate parameters. */ + if ((input == NULL) || (output == NULL) || (key == NULL)) { + WOLFSSL_MSG("Null argument passed in"); + } + else +#if !defined(HAVE_SELFTEST) && \ + (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3))) + /* Decrypt a block with wolfCrypt AES. */ + if (wc_AesDecryptDirect((Aes*)key, output, input) != 0) { + WOLFSSL_MSG("wc_AesDecryptDirect failed"); + } +#else + { + /* Decrypt a block with wolfCrypt AES. */ + wc_AesDecryptDirect((Aes*)key, output, input); + } +#endif +} +#endif /* WOLFSSL_AES_DIRECT */ + + + +#ifdef HAVE_AES_ECB +/* Encrypt/decrypt a 16-byte block of data using AES-ECB. + * + * wolfSSL_AES_set_encrypt_key() or wolfSSL_AES_set_decrypt_key ()must have been + * called. + * + * #input must contain AES_BLOCK_SIZE bytes of data. + * #output must be a buffer at least AES_BLOCK_SIZE bytes in length. + * + * @param [in] in Data to encipher. + * @param [out] out Enciphered data. + * @param [in] key AES key to use for encryption/decryption. + * @param [in] enc Whether to encrypt. + * AES_ENCRPT for encryption, AES_DECRYPT for decryption. + */ +void wolfSSL_AES_ecb_encrypt(const unsigned char *in, unsigned char* out, + AES_KEY *key, const int enc) +{ + WOLFSSL_ENTER("wolfSSL_AES_ecb_encrypt"); + + /* Validate parameters. */ + if ((key == NULL) || (in == NULL) || (out == NULL)) { + WOLFSSL_MSG("Error, Null argument passed in"); + } + else if (enc == AES_ENCRYPT) { + /* Encrypt block. */ + if (wc_AesEcbEncrypt((Aes*)key, out, in, AES_BLOCK_SIZE) != 0) { + WOLFSSL_MSG("Error with AES CBC encrypt"); + } + } + else { + #ifdef HAVE_AES_DECRYPT + /* Decrypt block. */ + if (wc_AesEcbDecrypt((Aes*)key, out, in, AES_BLOCK_SIZE) != 0) { + WOLFSSL_MSG("Error with AES CBC decrypt"); + } + #else + WOLFSSL_MSG("AES decryption not compiled in"); + #endif + } +} +#endif /* HAVE_AES_ECB */ + +#ifdef HAVE_AES_CBC +/* Encrypt/decrypt data with IV using AES-CBC. + * + * wolfSSL_AES_set_encrypt_key() or wolfSSL_AES_set_decrypt_key() must have been + * called. + * + * @param [in] in Data to encipher. + * @param [out] out Enciphered data. + * @param [in] len Length of data to encipher. + * @param [in] key AES key to use for encryption/decryption. + * @param [in, out] iv Initialization Vector (IV) of CBC mode. + * On in, used with first block. + * On out, IV for further operations. + * @param [in] enc Whether to encrypt. + * AES_ENCRPT for encryption, AES_DECRYPT for decryption. + */ +void wolfSSL_AES_cbc_encrypt(const unsigned char *in, unsigned char* out, + size_t len, AES_KEY *key, unsigned char* iv, const int enc) +{ + WOLFSSL_ENTER("wolfSSL_AES_cbc_encrypt"); + + /* Validate parameters. */ + if ((key == NULL) || (in == NULL) || (out == NULL) || (iv == NULL) || + (len == 0)) { + WOLFSSL_MSG("Error, Null argument passed in"); + } + /* Set IV for operation. */ + else { + int ret; + Aes* aes = (Aes*)key; + + if ((ret = wc_AesSetIV(aes, (const byte*)iv)) != 0) { + WOLFSSL_MSG("Error with setting iv"); + } + else if (enc == AES_ENCRYPT) { + /* Encrypt with wolfCrypt AES object. */ + if ((ret = wc_AesCbcEncrypt(aes, out, in, (word32)len)) != 0) { + WOLFSSL_MSG("Error with AES CBC encrypt"); + } + } + else { + /* Decrypt with wolfCrypt AES object. */ + if ((ret = wc_AesCbcDecrypt(aes, out, in, (word32)len)) != 0) { + WOLFSSL_MSG("Error with AES CBC decrypt"); + } + } + + if (ret == 0) { + /* Get IV for next operation. */ + XMEMCPY(iv, (byte*)(aes->reg), AES_BLOCK_SIZE); + } + } +} +#endif /* HAVE_AES_CBC */ + + +/* Encrypt/decrypt data with IV using AES-CFB. + * + * wolfSSL_AES_set_encrypt_key() must have been called. + * + * @param [in] in Data to encipher. + * @param [out] out Enciphered data. + * @param [in] len Length of data to encipher. + * @param [in] key AES key to use for encryption/decryption. + * @param [in, out] iv Initialization Vector (IV) of CFB mode. + * On in, used with first block. + * On out, IV for further operations. + * @param [out] num Number of bytes used from last incomplete block. + * @param [in] enc Whether to encrypt. + * AES_ENCRPT for encryption, AES_DECRYPT for decryption. + */ +void wolfSSL_AES_cfb128_encrypt(const unsigned char *in, unsigned char* out, + size_t len, AES_KEY *key, unsigned char* iv, int* num, const int enc) +{ +#ifndef WOLFSSL_AES_CFB + WOLFSSL_MSG("CFB mode not enabled please use macro WOLFSSL_AES_CFB"); + + (void)in; + (void)out; + (void)len; + (void)key; + (void)iv; + (void)num; + (void)enc; +#else + WOLFSSL_ENTER("wolfSSL_AES_cfb_encrypt"); + + /* Validate parameters. */ + if ((key == NULL) || (in == NULL) || (out == NULL) || (iv == NULL)) { + WOLFSSL_MSG("Error, Null argument passed in"); + } + else { + int ret; + Aes* aes = (Aes*)key; + + /* Copy the IV directly into reg here because wc_AesSetIV clears + * leftover bytes field "left", and this function relies on the leftover + * bytes being preserved between calls. + */ + XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE); + + if (enc == AES_ENCRYPT) { + /* Encrypt data with AES-CFB. */ + if ((ret = wc_AesCfbEncrypt(aes, out, in, (word32)len)) != 0) { + WOLFSSL_MSG("Error with AES CBC encrypt"); + } + } + else { + /* Decrypt data with AES-CFB. */ + if ((ret = wc_AesCfbDecrypt(aes, out, in, (word32)len)) != 0) { + WOLFSSL_MSG("Error with AES CBC decrypt"); + } + } + + if (ret == 0) { + /* Copy IV out after operation. */ + XMEMCPY(iv, (byte*)(aes->reg), AES_BLOCK_SIZE); + + /* Store number of left over bytes to num. */ + if (num != NULL) { + *num = (AES_BLOCK_SIZE - aes->left) % AES_BLOCK_SIZE; + } + } + } +#endif /* WOLFSSL_AES_CFB */ +} + +/* wc_AesKey*Wrap_ex API not available in FIPS and SELFTEST */ +#if defined(HAVE_AES_KEYWRAP) && !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) +/* Wrap (encrypt) a key using RFC3394 AES key wrap. + * + * @param [in, out] key AES key. + * @param [in] iv Initialization vector used by encryption mode. + * @param [out] out Wrapped key. + * @param [in] in Key data to wrap. + * @param [in] inSz Length of key to wrap in bytes. + * @return Length of encrypted key in bytes. + * @return 0 when key, iv, out or in is NULL. + * @return 0 when key length is not valid. + */ +int wolfSSL_AES_wrap_key(AES_KEY *key, const unsigned char *iv, + unsigned char *out, const unsigned char *in, unsigned int inSz) +{ + int ret = 0; + int len = 0; + + WOLFSSL_ENTER("wolfSSL_AES_wrap_key"); + + /* Validate parameters. */ + if ((out == NULL) || (in == NULL)) { + WOLFSSL_MSG("Error, Null argument passed in"); + ret = BAD_FUNC_ARG; + } + + /* Wrap key. */ + if ((ret == 0) && ((ret = wc_AesKeyWrap_ex((Aes*)key, in, inSz, out, + inSz + KEYWRAP_BLOCK_SIZE, iv)) > 0)) { + /* Get the length of the wrapped key. */ + len = ret; + } + + return len; +} + +/* Unwrap (decrypt) a key using RFC3394 AES key wrap. + * + * @param [in, out] key AES key. + * @param [in] iv Initialization vector used by decryption mode. + * @param [out] out Unwrapped key. + * @param [in] in Wrapped key data. + * @param [in] inSz Length of wrapped key data in bytes. + * @return Length of decrypted key in bytes. + * @return 0 when key, iv, out or in is NULL. + * @return 0 when wrapped key data length is not valid. + */ +int wolfSSL_AES_unwrap_key(AES_KEY *key, const unsigned char *iv, + unsigned char *out, const unsigned char *in, unsigned int inSz) +{ + int ret = 0; + int len = 0; + + WOLFSSL_ENTER("wolfSSL_AES_wrap_key"); + + /* Validate parameters. */ + if ((out == NULL) || (in == NULL)) { + WOLFSSL_MSG("Error, Null argument passed in"); + ret = BAD_FUNC_ARG; + } + + /* Unwrap key. */ + if ((ret == 0) && ((ret = wc_AesKeyUnWrap_ex((Aes*)key, in, inSz, out, + inSz + KEYWRAP_BLOCK_SIZE, iv)) > 0)) { + /* Get the length of the unwrapped key. */ + len = ret; + } + + return len; +} +#endif /* HAVE_AES_KEYWRAP && !HAVE_FIPS && !HAVE_SELFTEST */ + +#ifdef HAVE_CTS +/* Ciphertext stealing encryption compatible with RFC2040 and RFC3962. + * + * @param [in] in Data to encrypt. + * @param [out] out Encrypted data. + * @param [in] len Length of data to encrypt. + * @param [in] key Symmetric key. + * @param [in] iv Initialization Vector for encryption mode. + * @param [in] cbc CBC mode encryption function. + * @return Length of encrypted data in bytes on success. + * @return 0 when in, out, cbc, key or iv are NULL. + * @return 0 when len is less than or equal to 16 bytes. + */ +size_t wolfSSL_CRYPTO_cts128_encrypt(const unsigned char *in, + unsigned char *out, size_t len, const void *key, unsigned char *iv, + WOLFSSL_CBC128_CB cbc) +{ + byte lastBlk[WOLFSSL_CTS128_BLOCK_SZ]; + int lastBlkLen = len % WOLFSSL_CTS128_BLOCK_SZ; + + WOLFSSL_ENTER("wolfSSL_CRYPTO_cts128_encrypt"); + + /* Validate parameters. */ + if ((in == NULL) || (out == NULL) || (len <= WOLFSSL_CTS128_BLOCK_SZ) || + (cbc == NULL) || (key == NULL) || (iv == NULL)) { + WOLFSSL_MSG("Bad parameter"); + len = 0; + } + + if (len > 0) { + /* Must have a last block. */ + if (lastBlkLen == 0) { + lastBlkLen = WOLFSSL_CTS128_BLOCK_SZ; + } + + /* Encrypt data up to last block */ + (*cbc)(in, out, len - lastBlkLen, key, iv, AES_ENCRYPT); + + /* Move to last block */ + in += len - lastBlkLen; + out += len - lastBlkLen; + + /* RFC2040: Pad Pn with zeros at the end to create P of length BB. */ + XMEMCPY(lastBlk, in, lastBlkLen); + XMEMSET(lastBlk + lastBlkLen, 0, WOLFSSL_CTS128_BLOCK_SZ - lastBlkLen); + /* RFC2040: Select the first Ln bytes of En-1 to create Cn */ + XMEMCPY(out, out - WOLFSSL_CTS128_BLOCK_SZ, lastBlkLen); + /* Encrypt last block. */ + (*cbc)(lastBlk, out - WOLFSSL_CTS128_BLOCK_SZ, WOLFSSL_CTS128_BLOCK_SZ, + key, iv, AES_ENCRYPT); + } + + return len; +} + +/* Ciphertext stealing decryption compatible with RFC2040 and RFC3962. + * + * @param [in] in Data to decrypt. + * @param [out] out Decrypted data. + * @param [in] len Length of data to decrypt. + * @param [in] key Symmetric key. + * @param [in] iv Initialization Vector for decryption mode. + * @param [in] cbc CBC mode encryption function. + * @return Length of decrypted data in bytes on success. + * @return 0 when in, out, cbc, key or iv are NULL. + * @return 0 when len is less than or equal to 16 bytes. + */ +size_t wolfSSL_CRYPTO_cts128_decrypt(const unsigned char *in, + unsigned char *out, size_t len, const void *key, unsigned char *iv, + WOLFSSL_CBC128_CB cbc) +{ + byte lastBlk[WOLFSSL_CTS128_BLOCK_SZ]; + byte prevBlk[WOLFSSL_CTS128_BLOCK_SZ]; + int lastBlkLen = len % WOLFSSL_CTS128_BLOCK_SZ; + + WOLFSSL_ENTER("wolfSSL_CRYPTO_cts128_decrypt"); + + /* Validate parameters. */ + if ((in == NULL) || (out == NULL) || (len <= WOLFSSL_CTS128_BLOCK_SZ) || + (cbc == NULL) || (key == NULL) || (iv == NULL)) { + WOLFSSL_MSG("Bad parameter"); + len = 0; + } + + if (len > 0) { + /* Must have a last block. */ + if (lastBlkLen == 0) { + lastBlkLen = WOLFSSL_CTS128_BLOCK_SZ; + } + + if (len - lastBlkLen - WOLFSSL_CTS128_BLOCK_SZ != 0) { + /* Decrypt up to last two blocks */ + (*cbc)(in, out, len - lastBlkLen - WOLFSSL_CTS128_BLOCK_SZ, key, iv, + AES_DECRYPTION); + + /* Move to last two blocks */ + in += len - lastBlkLen - WOLFSSL_CTS128_BLOCK_SZ; + out += len - lastBlkLen - WOLFSSL_CTS128_BLOCK_SZ; + } + + /* RFC2040: Decrypt Cn-1 to create Dn. + * Use 0 buffer as IV to do straight decryption. + * This places the Cn-1 block at lastBlk */ + XMEMSET(lastBlk, 0, WOLFSSL_CTS128_BLOCK_SZ); + (*cbc)(in, prevBlk, WOLFSSL_CTS128_BLOCK_SZ, key, lastBlk, AES_DECRYPT); + /* RFC2040: Append the tail (BB minus Ln) bytes of Xn to Cn + * to create En. */ + XMEMCPY(prevBlk, in + WOLFSSL_CTS128_BLOCK_SZ, lastBlkLen); + /* Cn and Cn-1 can now be decrypted */ + (*cbc)(prevBlk, out, WOLFSSL_CTS128_BLOCK_SZ, key, iv, AES_DECRYPT); + (*cbc)(lastBlk, lastBlk, WOLFSSL_CTS128_BLOCK_SZ, key, iv, AES_DECRYPT); + XMEMCPY(out + WOLFSSL_CTS128_BLOCK_SZ, lastBlk, lastBlkLen); + } + + return len; +} +#endif /* HAVE_CTS */ +#endif /* NO_AES */ +#endif /* OPENSSL_EXTRA */ + +/******************************************************************************* + * END OF AES API + ******************************************************************************/ + +/******************************************************************************* + * START OF RC4 API + ******************************************************************************/ + +#ifdef OPENSSL_EXTRA + +#ifndef NO_RC4 +/* Set the key state for Arc4 key. + * + * @param [out] key Arc4 key. + * @param [in] len Length of key in buffer. + * @param [in] data Key data buffer. + */ +void wolfSSL_RC4_set_key(WOLFSSL_RC4_KEY* key, int len, + const unsigned char* data) +{ + typedef char rc4_test[sizeof(WOLFSSL_RC4_KEY) >= sizeof(Arc4) ? 1 : -1]; + (void)sizeof(rc4_test); + + WOLFSSL_ENTER("wolfSSL_RC4_set_key"); + + /* Validate parameters. */ + if ((key == NULL) || (len < 0) || (data == NULL)) { + WOLFSSL_MSG("bad argument passed in"); + } + else { + /* Reset wolfCrypt Arc4 object. */ + XMEMSET(key, 0, sizeof(WOLFSSL_RC4_KEY)); + /* Set key into wolfCrypt Arc4 object. */ + wc_Arc4SetKey((Arc4*)key, data, (word32)len); + } +} + + +/* Encrypt/decrypt with Arc4 key. + * + * @param [in] len Length of data to encrypt/decrypt. + * @param [in] in Data to encrypt/decrypt. + * @param [out] out Enciphered data. + */ +void wolfSSL_RC4(WOLFSSL_RC4_KEY* key, size_t len, const unsigned char* in, + unsigned char* out) +{ + WOLFSSL_ENTER("wolfSSL_RC4"); + + /* Validate parameters. */ + if ((key == NULL) || (in == NULL) || (out == NULL)) { + WOLFSSL_MSG("Bad argument passed in"); + } + else { + /* Encrypt/decrypt data. */ + wc_Arc4Process((Arc4*)key, out, in, (word32)len); + } +} +#endif /* NO_RC4 */ + +#endif /* OPENSSL_EXTRA */ + +/******************************************************************************* + * END OF RC4 API + ******************************************************************************/ + +#endif /* WOLFSSL_SSL_CRYPTO_INCLUDED */ + diff --git a/tests/api.c b/tests/api.c index 43774eb6a..9b240408f 100644 --- a/tests/api.c +++ b/tests/api.c @@ -343,6 +343,9 @@ #ifndef NO_DES3 #include #endif +#ifndef NO_RC4 + #include +#endif #ifdef HAVE_ECC #include #endif @@ -385,6 +388,13 @@ #include "tests/utils.h" +/* include misc.c here regardless of NO_INLINE, because misc.c implementations + * have default (hidden) visibility, and in the absence of visibility, it's + * benign to mask out the library implementation. + */ +#define WOLFSSL_MISC_INCLUDED +#include + #ifndef WOLFSSL_HAVE_ECC_KEY_GET_PRIV /* FIPS build has replaced ecc.h. */ #define wc_ecc_key_get_priv(key) (&((key)->k)) @@ -32099,72 +32109,6 @@ static int test_wolfSSL_X509_check_email(void) return EXPECT_RESULT(); } -static int test_wolfSSL_DES(void) -{ - EXPECT_DECLS; -#if defined(OPENSSL_EXTRA) && !defined(NO_DES3) - const_DES_cblock myDes; - DES_cblock iv; - DES_key_schedule key; - word32 i; - DES_LONG dl; - unsigned char msg[] = "hello wolfssl"; - - DES_check_key(1); - DES_set_key(&myDes, &key); - - /* check, check of odd parity */ - XMEMSET(myDes, 4, sizeof(const_DES_cblock)); - myDes[0] = 6; /* set even parity */ - XMEMSET(key, 5, sizeof(DES_key_schedule)); - ExpectIntEQ(DES_set_key_checked(&myDes, &key), -1); - ExpectIntNE(key[0], myDes[0]); /* should not have copied over key */ - - /* set odd parity for success case */ - DES_set_odd_parity(&myDes); - ExpectIntEQ(DES_check_key_parity(&myDes), 1); - fprintf(stderr, "%02x %02x %02x %02x", myDes[0], myDes[1], myDes[2], - myDes[3]); - ExpectIntEQ(DES_set_key_checked(&myDes, &key), 0); - for (i = 0; i < sizeof(DES_key_schedule); i++) { - ExpectIntEQ(key[i], myDes[i]); - } - ExpectIntEQ(DES_is_weak_key(&myDes), 0); - - /* check weak key */ - XMEMSET(myDes, 1, sizeof(const_DES_cblock)); - XMEMSET(key, 5, sizeof(DES_key_schedule)); - ExpectIntEQ(DES_set_key_checked(&myDes, &key), -2); - ExpectIntNE(key[0], myDes[0]); /* should not have copied over key */ - - /* now do unchecked copy of a weak key over */ - DES_set_key_unchecked(&myDes, &key); - /* compare arrays, should be the same */ - for (i = 0; i < sizeof(DES_key_schedule); i++) { - ExpectIntEQ(key[i], myDes[i]); - } - ExpectIntEQ(DES_is_weak_key(&myDes), 1); - - /* check DES_key_sched API */ - XMEMSET(key, 1, sizeof(DES_key_schedule)); - ExpectIntEQ(DES_key_sched(&myDes, NULL), 0); - ExpectIntEQ(DES_key_sched(NULL, &key), 0); - ExpectIntEQ(DES_key_sched(&myDes, &key), 0); - /* compare arrays, should be the same */ - for (i = 0; i < sizeof(DES_key_schedule); i++) { - ExpectIntEQ(key[i], myDes[i]); - } - - /* DES_cbc_cksum should return the last 4 of the last 8 bytes after - * DES_cbc_encrypt on the input */ - XMEMSET(iv, 0, sizeof(DES_cblock)); - XMEMSET(myDes, 5, sizeof(DES_key_schedule)); - ExpectIntGT((dl = DES_cbc_cksum(msg, &key, sizeof(msg), &myDes, &iv)), 0); - ExpectIntEQ(dl, 480052723); -#endif /* defined(OPENSSL_EXTRA) && !defined(NO_DES3) */ - return EXPECT_RESULT(); -} - static int test_wc_PemToDer(void) { EXPECT_DECLS; @@ -39052,40 +38996,6 @@ static int test_wolfSSL_a2i_IPADDRESS(void) return EXPECT_RESULT(); } -static int test_wolfSSL_DES_ecb_encrypt(void) -{ - EXPECT_DECLS; -#if defined(OPENSSL_EXTRA) && !defined(NO_DES3) && defined(WOLFSSL_DES_ECB) - WOLFSSL_DES_cblock input1, input2, output1, output2, back1, back2; - WOLFSSL_DES_key_schedule key; - - XMEMCPY(key, "12345678", sizeof(WOLFSSL_DES_key_schedule)); - XMEMCPY(input1, "Iamhuman", sizeof(WOLFSSL_DES_cblock)); - XMEMCPY(input2, "Whoisit?", sizeof(WOLFSSL_DES_cblock)); - XMEMSET(output1, 0, sizeof(WOLFSSL_DES_cblock)); - XMEMSET(output2, 0, sizeof(WOLFSSL_DES_cblock)); - XMEMSET(back1, 0, sizeof(WOLFSSL_DES_cblock)); - XMEMSET(back2, 0, sizeof(WOLFSSL_DES_cblock)); - - /* Encrypt messages */ - wolfSSL_DES_ecb_encrypt(&input1, &output1, &key, DES_ENCRYPT); - wolfSSL_DES_ecb_encrypt(&input2, &output2, &key, DES_ENCRYPT); - - { - /* Decrypt messages */ - int ret1 = 0; - int ret2 = 0; - wolfSSL_DES_ecb_encrypt(&output1, &back1, &key, DES_DECRYPT); - ExpectIntEQ(ret1 = XMEMCMP((unsigned char *)back1, - (unsigned char *)input1, sizeof(WOLFSSL_DES_cblock)), 0); - wolfSSL_DES_ecb_encrypt(&output2, &back2, &key, DES_DECRYPT); - ExpectIntEQ(ret2 = XMEMCMP((unsigned char *)back2, - (unsigned char *)input2, sizeof(WOLFSSL_DES_cblock)), 0); - } -#endif - return EXPECT_RESULT(); -} - static int test_wolfSSL_X509_cmp_time(void) { @@ -40863,6 +40773,968 @@ static int test_wolfSSL_GetLoggingCb(void) #endif /* !NO_BIO */ +static int test_wolfSSL_MD4(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && !defined(NO_MD4) + MD4_CTX md4; + unsigned char out[16]; /* MD4_DIGEST_SIZE */ + const char* msg = "12345678901234567890123456789012345678901234567890123456" + "789012345678901234567890"; + const char* test = "\xe3\x3b\x4d\xdc\x9c\x38\xf2\x19\x9c\x3e\x7b\x16\x4f" + "\xcc\x05\x36"; + int msgSz = (int)XSTRLEN(msg); + + + XMEMSET(out, 0, sizeof(out)); + MD4_Init(&md4); + MD4_Update(&md4, (const void*)msg, (unsigned long)msgSz); + MD4_Final(out, &md4); + ExpectIntEQ(XMEMCMP(out, test, sizeof(out)), 0); +#endif + return EXPECT_RESULT(); +} + +static int test_wolfSSL_MD5(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && !defined(NO_MD5) + byte input1[] = ""; + byte input2[] = "message digest"; + byte hash[WC_MD5_DIGEST_SIZE]; + unsigned char output1[] = + "\xd4\x1d\x8c\xd9\x8f\x00\xb2\x04\xe9\x80\x09\x98\xec\xf8\x42\x7e"; + unsigned char output2[] = + "\xf9\x6b\x69\x7d\x7c\xb7\x93\x8d\x52\x5a\x2f\x31\xaa\xf1\x61\xd0"; + WOLFSSL_MD5_CTX md5; + + XMEMSET(&md5, 0, sizeof(md5)); + + /* Test cases for illegal parameters */ + ExpectIntEQ(MD5_Init(NULL), 0); + ExpectIntEQ(MD5_Init(&md5), 1); + ExpectIntEQ(MD5_Update(NULL, input1, 0), 0); + ExpectIntEQ(MD5_Update(NULL, NULL, 0), 0); + ExpectIntEQ(MD5_Update(&md5, NULL, 1), 0); + ExpectIntEQ(MD5_Final(NULL, &md5), 0); + ExpectIntEQ(MD5_Final(hash, NULL), 0); + ExpectIntEQ(MD5_Final(NULL, NULL), 0); + + /* Init MD5 CTX */ + ExpectIntEQ(wolfSSL_MD5_Init(&md5), 1); + ExpectIntEQ(wolfSSL_MD5_Update(&md5, input1, XSTRLEN((const char*)&input1)), + 1); + ExpectIntEQ(wolfSSL_MD5_Final(hash, &md5), 1); + ExpectIntEQ(XMEMCMP(&hash, output1, WC_MD5_DIGEST_SIZE), 0); + + /* Init MD5 CTX */ + ExpectIntEQ(wolfSSL_MD5_Init(&md5), 1); + ExpectIntEQ(wolfSSL_MD5_Update(&md5, input2, + (int)XSTRLEN((const char*)input2)), 1); + ExpectIntEQ(wolfSSL_MD5_Final(hash, &md5), 1); + ExpectIntEQ(XMEMCMP(&hash, output2, WC_MD5_DIGEST_SIZE), 0); +#if !defined(NO_OLD_NAMES) && \ + (!defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))) + ExpectPtrNE(MD5(NULL, 1, (byte*)&hash), &hash); + ExpectPtrEq(MD5(input1, 0, (byte*)&hash), &hash); + ExpectPtrNE(MD5(input1, 1, NULL), NULL); + ExpectPtrNE(MD5(NULL, 0, NULL), NULL); + + ExpectPtrEq(MD5(input1, (int)XSTRLEN((const char*)&input1), (byte*)&hash), + &hash); + ExpectIntEQ(XMEMCMP(&hash, output1, WC_MD5_DIGEST_SIZE), 0); + + ExpectPtrEq(MD5(input2, (int)XSTRLEN((const char*)&input2), (byte*)&hash), + &hash); + ExpectIntEQ(XMEMCMP(&hash, output2, WC_MD5_DIGEST_SIZE), 0); + { + byte data[] = "Data to be hashed."; + XMEMSET(hash, 0, WC_MD5_DIGEST_SIZE); + + ExpectNotNull(MD5(data, sizeof(data), NULL)); + ExpectNotNull(MD5(data, sizeof(data), hash)); + ExpectNotNull(MD5(NULL, 0, hash)); + ExpectNull(MD5(NULL, sizeof(data), hash)); + } +#endif +#endif + return EXPECT_RESULT(); +} + +static int test_wolfSSL_MD5_Transform(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && !defined(NO_MD5) + byte input1[] = ""; + byte input2[] = "abc"; + byte local[WC_MD5_BLOCK_SIZE]; + word32 sLen = 0; +#ifdef BIG_ENDIAN_ORDER + unsigned char output1[] = + "\x03\x1f\x1d\xac\x6e\xa5\x8e\xd0\x1f\xab\x67\xb7\x74\x31\x77\x91"; + unsigned char output2[] = + "\xef\xd3\x79\x8d\x67\x17\x25\x90\xa4\x13\x79\xc7\xe3\xa7\x7b\xbc"; +#else + unsigned char output1[] = + "\xac\x1d\x1f\x03\xd0\x8e\xa5\x6e\xb7\x67\xab\x1f\x91\x77\x31\x74"; + unsigned char output2[] = + "\x8d\x79\xd3\xef\x90\x25\x17\x67\xc7\x79\x13\xa4\xbc\x7b\xa7\xe3"; +#endif + + union { + wc_Md5 native; + MD5_CTX compat; + } md5; + + XMEMSET(&md5.compat, 0, sizeof(md5.compat)); + XMEMSET(&local, 0, sizeof(local)); + + /* sanity check */ + ExpectIntEQ(MD5_Transform(NULL, NULL), 0); + ExpectIntEQ(MD5_Transform(NULL, (const byte*)&input1), 0); + ExpectIntEQ(MD5_Transform(&md5.compat, NULL), 0); + ExpectIntEQ(wc_Md5Transform(NULL, NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_Md5Transform(NULL, (const byte*)&input1), BAD_FUNC_ARG); + ExpectIntEQ(wc_Md5Transform(&md5.native, NULL), BAD_FUNC_ARG); + + /* Init MD5 CTX */ + ExpectIntEQ(wolfSSL_MD5_Init(&md5.compat), 1); + /* Do Transform*/ + sLen = (word32)XSTRLEN((char*)input1); + XMEMCPY(local, input1, sLen); + ExpectIntEQ(MD5_Transform(&md5.compat, (const byte*)&local[0]), 1); + + ExpectIntEQ(XMEMCMP(md5.native.digest, output1, WC_MD5_DIGEST_SIZE), 0); + + /* Init MD5 CTX */ + ExpectIntEQ(MD5_Init(&md5.compat), 1); + sLen = (word32)XSTRLEN((char*)input2); + XMEMSET(local, 0, WC_MD5_BLOCK_SIZE); + XMEMCPY(local, input2, sLen); + ExpectIntEQ(MD5_Transform(&md5.compat, (const byte*)&local[0]), 1); + ExpectIntEQ(XMEMCMP(md5.native.digest, output2, WC_MD5_DIGEST_SIZE), 0); +#endif + return EXPECT_RESULT(); +} + +static int test_wolfSSL_SHA(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && !defined(HAVE_SELFTEST) + #if !defined(NO_SHA) && defined(NO_OLD_SHA_NAMES) && \ + (!defined(HAVE_FIPS) || \ + (defined(HAVE_FIPS_VERSION) && HAVE_FIPS_VERSION > 2)) + { + const unsigned char in[] = "abc"; + unsigned char expected[] = "\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E" + "\x25\x71\x78\x50\xC2\x6C\x9C\xD0\xD8\x9D"; + unsigned char out[WC_SHA_DIGEST_SIZE]; + unsigned char* p; + WOLFSSL_SHA_CTX sha; + + XMEMSET(out, 0, WC_SHA_DIGEST_SIZE); + ExpectNotNull(SHA1(in, XSTRLEN((char*)in), out)); + ExpectIntEQ(XMEMCMP(out, expected, WC_SHA_DIGEST_SIZE), 0); + + /* SHA interface test */ + XMEMSET(out, 0, WC_SHA_DIGEST_SIZE); + + ExpectNull(SHA(NULL, XSTRLEN((char*)in), out)); + ExpectNotNull(SHA(in, 0, out)); + ExpectNotNull(SHA(in, XSTRLEN((char*)in), NULL)); + ExpectNotNull(SHA(NULL, 0, out)); + ExpectNotNull(SHA(NULL, 0, NULL)); + + ExpectNotNull(SHA(in, XSTRLEN((char*)in), out)); + ExpectIntEQ(XMEMCMP(out, expected, WC_SHA_DIGEST_SIZE), 0); + ExpectNotNull(p = SHA(in, XSTRLEN((char*)in), NULL)); + ExpectIntEQ(XMEMCMP(p, expected, WC_SHA_DIGEST_SIZE), 0); + + ExpectIntEQ(wolfSSL_SHA_Init(&sha), 1); + ExpectIntEQ(wolfSSL_SHA_Update(&sha, in, XSTRLEN((char*)in)), 1); + ExpectIntEQ(wolfSSL_SHA_Final(out, &sha), 1); + ExpectIntEQ(XMEMCMP(out, expected, WC_SHA_DIGEST_SIZE), 0); + + ExpectIntEQ(wolfSSL_SHA1_Init(&sha), 1); + ExpectIntEQ(wolfSSL_SHA1_Update(&sha, in, XSTRLEN((char*)in)), 1); + ExpectIntEQ(wolfSSL_SHA1_Final(out, &sha), 1); + ExpectIntEQ(XMEMCMP(out, expected, WC_SHA_DIGEST_SIZE), 0); + } + #endif + + #if !defined(NO_SHA256) + { + const unsigned char in[] = "abc"; + unsigned char expected[] = + "\xBA\x78\x16\xBF\x8F\x01\xCF\xEA\x41\x41\x40\xDE\x5D\xAE\x22" + "\x23\xB0\x03\x61\xA3\x96\x17\x7A\x9C\xB4\x10\xFF\x61\xF2\x00" + "\x15\xAD"; + unsigned char out[WC_SHA256_DIGEST_SIZE]; + unsigned char* p; + + XMEMSET(out, 0, WC_SHA256_DIGEST_SIZE); +#if !defined(NO_OLD_NAMES) && !defined(HAVE_FIPS) + ExpectNotNull(SHA256(in, XSTRLEN((char*)in), out)); +#else + ExpectNotNull(wolfSSL_SHA256(in, XSTRLEN((char*)in), out)); +#endif + ExpectIntEQ(XMEMCMP(out, expected, WC_SHA256_DIGEST_SIZE), 0); +#if !defined(NO_OLD_NAMES) && !defined(HAVE_FIPS) + ExpectNotNull(p = SHA256(in, XSTRLEN((char*)in), NULL)); +#else + ExpectNotNull(p = wolfSSL_SHA256(in, XSTRLEN((char*)in), NULL)); +#endif + ExpectIntEQ(XMEMCMP(p, expected, WC_SHA256_DIGEST_SIZE), 0); + } + #endif + + #if defined(WOLFSSL_SHA384) + { + const unsigned char in[] = "abc"; + unsigned char expected[] = + "\xcb\x00\x75\x3f\x45\xa3\x5e\x8b\xb5\xa0\x3d\x69\x9a\xc6\x50" + "\x07\x27\x2c\x32\xab\x0e\xde\xd1\x63\x1a\x8b\x60\x5a\x43\xff" + "\x5b\xed\x80\x86\x07\x2b\xa1\xe7\xcc\x23\x58\xba\xec\xa1\x34" + "\xc8\x25\xa7"; + unsigned char out[WC_SHA384_DIGEST_SIZE]; + unsigned char* p; + + XMEMSET(out, 0, WC_SHA384_DIGEST_SIZE); +#if !defined(NO_OLD_NAMES) && !defined(HAVE_FIPS) + ExpectNotNull(SHA384(in, XSTRLEN((char*)in), out)); +#else + ExpectNotNull(wolfSSL_SHA384(in, XSTRLEN((char*)in), out)); +#endif + ExpectIntEQ(XMEMCMP(out, expected, WC_SHA384_DIGEST_SIZE), 0); +#if !defined(NO_OLD_NAMES) && !defined(HAVE_FIPS) + ExpectNotNull(p = SHA384(in, XSTRLEN((char*)in), NULL)); +#else + ExpectNotNull(p = wolfSSL_SHA384(in, XSTRLEN((char*)in), NULL)); +#endif + ExpectIntEQ(XMEMCMP(p, expected, WC_SHA384_DIGEST_SIZE), 0); + } + #endif + + #if defined(WOLFSSL_SHA512) + { + const unsigned char in[] = "abc"; + unsigned char expected[] = + "\xdd\xaf\x35\xa1\x93\x61\x7a\xba\xcc\x41\x73\x49\xae\x20\x41" + "\x31\x12\xe6\xfa\x4e\x89\xa9\x7e\xa2\x0a\x9e\xee\xe6\x4b\x55" + "\xd3\x9a\x21\x92\x99\x2a\x27\x4f\xc1\xa8\x36\xba\x3c\x23\xa3" + "\xfe\xeb\xbd\x45\x4d\x44\x23\x64\x3c\xe8\x0e\x2a\x9a\xc9\x4f" + "\xa5\x4c\xa4\x9f"; + unsigned char out[WC_SHA512_DIGEST_SIZE]; + unsigned char* p; + + XMEMSET(out, 0, WC_SHA512_DIGEST_SIZE); +#if !defined(NO_OLD_NAMES) && !defined(HAVE_FIPS) + ExpectNotNull(SHA512(in, XSTRLEN((char*)in), out)); +#else + ExpectNotNull(wolfSSL_SHA512(in, XSTRLEN((char*)in), out)); +#endif + ExpectIntEQ(XMEMCMP(out, expected, WC_SHA512_DIGEST_SIZE), 0); +#if !defined(NO_OLD_NAMES) && !defined(HAVE_FIPS) + ExpectNotNull(p = SHA512(in, XSTRLEN((char*)in), NULL)); +#else + ExpectNotNull(p = wolfSSL_SHA512(in, XSTRLEN((char*)in), NULL)); +#endif + ExpectIntEQ(XMEMCMP(p, expected, WC_SHA512_DIGEST_SIZE), 0); + } + #endif +#endif + return EXPECT_RESULT(); +} + +static int test_wolfSSL_SHA_Transform(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && !defined(NO_SHA) +#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) + byte input1[] = ""; + byte input2[] = "abc"; + byte local[WC_SHA_BLOCK_SIZE]; + word32 sLen = 0; +#ifdef BIG_ENDIAN_ORDER + unsigned char output1[] = + "\x92\xb4\x04\xe5\x56\x58\x8c\xed\x6c\x1a\xcd\x4e\xbf\x05\x3f\x68" + "\x09\xf7\x3a\x93"; + unsigned char output2[] = + "\x97\xb2\x74\x8b\x4f\x5b\xbc\xca\x5b\xc0\xe6\xea\x2d\x40\xb4\xa0" + "\x7c\x6e\x08\xb8"; +#else + unsigned char output1[] = + "\xe5\x04\xb4\x92\xed\x8c\x58\x56\x4e\xcd\x1a\x6c\x68\x3f\x05\xbf" + "\x93\x3a\xf7\x09"; + unsigned char output2[] = + "\x8b\x74\xb2\x97\xca\xbc\x5b\x4f\xea\xe6\xc0\x5b\xa0\xb4\x40\x2d" + "\xb8\x08\x6e\x7c"; +#endif + + union { + wc_Sha native; + SHA_CTX compat; + } sha; + union { + wc_Sha native; + SHA_CTX compat; + } sha1; + + XMEMSET(&sha.compat, 0, sizeof(sha.compat)); + XMEMSET(&local, 0, sizeof(local)); + + /* sanity check */ + ExpectIntEQ(SHA_Transform(NULL, NULL), 0); + ExpectIntEQ(SHA_Transform(NULL, (const byte*)&input1), 0); + ExpectIntEQ(SHA_Transform(&sha.compat, NULL), 0); + ExpectIntEQ(SHA1_Transform(NULL, NULL), 0); + ExpectIntEQ(SHA1_Transform(NULL, (const byte*)&input1), 0); + ExpectIntEQ(SHA1_Transform(&sha.compat, NULL), 0); + ExpectIntEQ(wc_ShaTransform(NULL, NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_ShaTransform(NULL, (const byte*)&input1), BAD_FUNC_ARG); + ExpectIntEQ(wc_ShaTransform(&sha.native, NULL), BAD_FUNC_ARG); + + /* Init SHA CTX */ + ExpectIntEQ(SHA_Init(&sha.compat), 1); + /* Do Transform*/ + sLen = (word32)XSTRLEN((char*)input1); + XMEMCPY(local, input1, sLen); + ExpectIntEQ(SHA_Transform(&sha.compat, (const byte*)&local[0]), 1); + ExpectIntEQ(XMEMCMP(sha.native.digest, output1, WC_SHA_DIGEST_SIZE), 0); + ExpectIntEQ(SHA_Final(local, &sha.compat), 1); /* frees resources */ + + /* Init SHA CTX */ + ExpectIntEQ(SHA_Init(&sha.compat), 1); + sLen = (word32)XSTRLEN((char*)input2); + XMEMSET(local, 0, WC_SHA_BLOCK_SIZE); + XMEMCPY(local, input2, sLen); + ExpectIntEQ(SHA_Transform(&sha.compat, (const byte*)&local[0]), 1); + ExpectIntEQ(XMEMCMP(sha.native.digest, output2, WC_SHA_DIGEST_SIZE), 0); + ExpectIntEQ(SHA_Final(local, &sha.compat), 1); /* frees resources */ + + /* SHA1 */ + XMEMSET(local, 0, WC_SHA_BLOCK_SIZE); + /* Init SHA CTX */ + ExpectIntEQ(SHA1_Init(&sha1.compat), 1); + /* Do Transform*/ + sLen = (word32)XSTRLEN((char*)input1); + XMEMCPY(local, input1, sLen); + ExpectIntEQ(SHA1_Transform(&sha1.compat, (const byte*)&local[0]), 1); + ExpectIntEQ(XMEMCMP(sha1.native.digest, output1, WC_SHA_DIGEST_SIZE), 0); + ExpectIntEQ(SHA1_Final(local, &sha1.compat), 1); /* frees resources */ + + /* Init SHA CTX */ + ExpectIntEQ(SHA1_Init(&sha1.compat), 1); + sLen = (word32)XSTRLEN((char*)input2); + XMEMSET(local, 0, WC_SHA_BLOCK_SIZE); + XMEMCPY(local, input2, sLen); + ExpectIntEQ(SHA1_Transform(&sha1.compat, (const byte*)&local[0]), 1); + ExpectIntEQ(XMEMCMP(sha1.native.digest, output2, WC_SHA_DIGEST_SIZE), 0); + ExpectIntEQ(SHA_Final(local, &sha1.compat), 1); /* frees resources */ +#endif +#endif + return EXPECT_RESULT(); +} + +static int test_wolfSSL_SHA224(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SHA224) && \ + !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ + (defined(HAVE_FIPS_VERSION) && HAVE_FIPS_VERSION > 2)) + unsigned char input[] = + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; + unsigned char output[] = + "\x75\x38\x8b\x16\x51\x27\x76\xcc\x5d\xba\x5d\xa1\xfd\x89\x01" + "\x50\xb0\xc6\x45\x5c\xb4\xf5\x8b\x19\x52\x52\x25\x25"; + size_t inLen; + byte hash[WC_SHA224_DIGEST_SIZE]; + unsigned char* p; + + inLen = XSTRLEN((char*)input); + + XMEMSET(hash, 0, WC_SHA224_DIGEST_SIZE); + + ExpectNull(SHA224(NULL, inLen, hash)); + ExpectNotNull(SHA224(input, 0, hash)); + ExpectNotNull(SHA224(input, inLen, NULL)); + ExpectNotNull(SHA224(NULL, 0, hash)); + ExpectNotNull(SHA224(NULL, 0, NULL)); + + ExpectNotNull(SHA224(input, inLen, hash)); + ExpectIntEQ(XMEMCMP(hash, output, WC_SHA224_DIGEST_SIZE), 0); + ExpectNotNull(p = SHA224(input, inLen, NULL)); + ExpectIntEQ(XMEMCMP(p, output, WC_SHA224_DIGEST_SIZE), 0); +#endif + return EXPECT_RESULT(); +} + +static int test_wolfSSL_SHA256(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && !defined(NO_SHA256) && \ + defined(NO_OLD_SHA_NAMES) && !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) + unsigned char input[] = + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; + unsigned char output[] = + "\x24\x8D\x6A\x61\xD2\x06\x38\xB8\xE5\xC0\x26\x93\x0C\x3E\x60" + "\x39\xA3\x3C\xE4\x59\x64\xFF\x21\x67\xF6\xEC\xED\xD4\x19\xDB" + "\x06\xC1"; + size_t inLen; + byte hash[WC_SHA256_DIGEST_SIZE]; + + inLen = XSTRLEN((char*)input); + + XMEMSET(hash, 0, WC_SHA256_DIGEST_SIZE); + ExpectNotNull(SHA256(input, inLen, hash)); + ExpectIntEQ(XMEMCMP(hash, output, WC_SHA256_DIGEST_SIZE), 0); +#endif + return EXPECT_RESULT(); +} + +static int test_wolfSSL_SHA256_Transform(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && !defined(NO_SHA256) +#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) && \ + !defined(WOLFSSL_DEVCRYPTO_HASH) && !defined(WOLFSSL_AFALG_HASH) && \ + !defined(WOLFSSL_KCAPI_HASH) + byte input1[] = ""; + byte input2[] = "abc"; + byte local[WC_SHA256_BLOCK_SIZE]; + word32 sLen = 0; +#ifdef BIG_ENDIAN_ORDER + unsigned char output1[] = + "\xda\x56\x98\xbe\x17\xb9\xb4\x69\x62\x33\x57\x99\x77\x9f\xbe\xca" + "\x8c\xe5\xd4\x91\xc0\xd2\x62\x43\xba\xfe\xf9\xea\x18\x37\xa9\xd8"; + unsigned char output2[] = + "\x1d\x4e\xd4\x67\x67\x7c\x61\x67\x44\x10\x76\x26\x78\x10\xff\xb8" + "\x40\xc8\x9a\x39\x73\x16\x60\x8c\xa6\x61\xd6\x05\x91\xf2\x8c\x35"; +#else + unsigned char output1[] = + "\xbe\x98\x56\xda\x69\xb4\xb9\x17\x99\x57\x33\x62\xca\xbe\x9f\x77" + "\x91\xd4\xe5\x8c\x43\x62\xd2\xc0\xea\xf9\xfe\xba\xd8\xa9\x37\x18"; + unsigned char output2[] = + "\x67\xd4\x4e\x1d\x67\x61\x7c\x67\x26\x76\x10\x44\xb8\xff\x10\x78" + "\x39\x9a\xc8\x40\x8c\x60\x16\x73\x05\xd6\x61\xa6\x35\x8c\xf2\x91"; +#endif + union { + wc_Sha256 native; + SHA256_CTX compat; + } sha256; + + XMEMSET(&sha256.compat, 0, sizeof(sha256.compat)); + XMEMSET(&local, 0, sizeof(local)); + + /* sanity check */ + ExpectIntEQ(SHA256_Transform(NULL, NULL), 0); + ExpectIntEQ(SHA256_Transform(NULL, (const byte*)&input1), 0); + ExpectIntEQ(SHA256_Transform(&sha256.compat, NULL), 0); + ExpectIntEQ(wc_Sha256Transform(NULL, NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sha256Transform(NULL, (const byte*)&input1), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sha256Transform(&sha256.native, NULL), BAD_FUNC_ARG); + + /* Init SHA256 CTX */ + ExpectIntEQ(SHA256_Init(&sha256.compat), 1); + /* Do Transform*/ + sLen = (word32)XSTRLEN((char*)input1); + XMEMCPY(local, input1, sLen); + ExpectIntEQ(SHA256_Transform(&sha256.compat, (const byte*)&local[0]), 1); + ExpectIntEQ(XMEMCMP(sha256.native.digest, output1, WC_SHA256_DIGEST_SIZE), + 0); + ExpectIntEQ(SHA256_Final(local, &sha256.compat), 1); /* frees resources */ + + /* Init SHA256 CTX */ + ExpectIntEQ(SHA256_Init(&sha256.compat), 1); + sLen = (word32)XSTRLEN((char*)input2); + XMEMSET(local, 0, WC_SHA256_BLOCK_SIZE); + XMEMCPY(local, input2, sLen); + ExpectIntEQ(SHA256_Transform(&sha256.compat, (const byte*)&local[0]), 1); + ExpectIntEQ(XMEMCMP(sha256.native.digest, output2, WC_SHA256_DIGEST_SIZE), + 0); + ExpectIntEQ(SHA256_Final(local, &sha256.compat), 1); /* frees resources */ +#endif +#endif + return EXPECT_RESULT(); +} + +static int test_wolfSSL_SHA512_Transform(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SHA512) +#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) && \ + !defined(WOLFSSL_KCAPI_HASH) + byte input1[] = ""; + byte input2[] = "abc"; + byte local[WC_SHA512_BLOCK_SIZE]; + word32 sLen = 0; +#ifdef BIG_ENDIAN_ORDER + unsigned char output1[] = + "\xcf\x78\x81\xd5\x77\x4a\xcb\xe8\x53\x33\x62\xe0\xfb\xc7\x80\x70" + "\x02\x67\x63\x9d\x87\x46\x0e\xda\x30\x86\xcb\x40\xe8\x59\x31\xb0" + "\x71\x7d\xc9\x52\x88\xa0\x23\xa3\x96\xba\xb2\xc1\x4c\xe0\xb5\xe0" + "\x6f\xc4\xfe\x04\xea\xe3\x3e\x0b\x91\xf4\xd8\x0c\xbd\x66\x8b\xee"; + unsigned char output2[] = + "\x11\x10\x93\x4e\xeb\xa0\xcc\x0d\xfd\x33\x43\x9c\xfb\x04\xc8\x21" + "\xa9\xb4\x26\x3d\xca\xab\x31\x41\xe2\xc6\xaa\xaf\xe1\x67\xd7\xab" + "\x31\x8f\x2e\x54\x2c\xba\x4e\x83\xbe\x88\xec\x9d\x8f\x2b\x38\x98" + "\x14\xd2\x4e\x9d\x53\x8b\x5e\x4d\xde\x68\x6c\x69\xaf\x20\x96\xf0"; +#else + unsigned char output1[] = + "\xe8\xcb\x4a\x77\xd5\x81\x78\xcf\x70\x80\xc7\xfb\xe0\x62\x33\x53" + "\xda\x0e\x46\x87\x9d\x63\x67\x02\xb0\x31\x59\xe8\x40\xcb\x86\x30" + "\xa3\x23\xa0\x88\x52\xc9\x7d\x71\xe0\xb5\xe0\x4c\xc1\xb2\xba\x96" + "\x0b\x3e\xe3\xea\x04\xfe\xc4\x6f\xee\x8b\x66\xbd\x0c\xd8\xf4\x91"; + unsigned char output2[] = + "\x0d\xcc\xa0\xeb\x4e\x93\x10\x11\x21\xc8\x04\xfb\x9c\x43\x33\xfd" + "\x41\x31\xab\xca\x3d\x26\xb4\xa9\xab\xd7\x67\xe1\xaf\xaa\xc6\xe2" + "\x83\x4e\xba\x2c\x54\x2e\x8f\x31\x98\x38\x2b\x8f\x9d\xec\x88\xbe" + "\x4d\x5e\x8b\x53\x9d\x4e\xd2\x14\xf0\x96\x20\xaf\x69\x6c\x68\xde"; +#endif + union { + wc_Sha512 native; + SHA512_CTX compat; + } sha512; + + XMEMSET(&sha512.compat, 0, sizeof(sha512.compat)); + XMEMSET(&local, 0, sizeof(local)); + + /* sanity check */ + ExpectIntEQ(SHA512_Transform(NULL, NULL), 0); + ExpectIntEQ(SHA512_Transform(NULL, (const byte*)&input1), 0); + ExpectIntEQ(SHA512_Transform(&sha512.compat, NULL), 0); + ExpectIntEQ(wc_Sha512Transform(NULL, NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sha512Transform(NULL, (const byte*)&input1), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sha512Transform(&sha512.native, NULL), BAD_FUNC_ARG); + + /* Init SHA512 CTX */ + ExpectIntEQ(wolfSSL_SHA512_Init(&sha512.compat), 1); + + /* Do Transform*/ + sLen = (word32)XSTRLEN((char*)input1); + XMEMCPY(local, input1, sLen); + ExpectIntEQ(SHA512_Transform(&sha512.compat, (const byte*)&local[0]), 1); + ExpectIntEQ(XMEMCMP(sha512.native.digest, output1, + WC_SHA512_DIGEST_SIZE), 0); + ExpectIntEQ(SHA512_Final(local, &sha512.compat), 1); /* frees resources */ + + /* Init SHA512 CTX */ + ExpectIntEQ(SHA512_Init(&sha512.compat), 1); + sLen = (word32)XSTRLEN((char*)input2); + XMEMSET(local, 0, WC_SHA512_BLOCK_SIZE); + XMEMCPY(local, input2, sLen); + ExpectIntEQ(SHA512_Transform(&sha512.compat, (const byte*)&local[0]), 1); + ExpectIntEQ(XMEMCMP(sha512.native.digest, output2, + WC_SHA512_DIGEST_SIZE), 0); + ExpectIntEQ(SHA512_Final(local, &sha512.compat), 1); /* frees resources */ + + (void)input1; +#endif +#endif + return EXPECT_RESULT(); +} + +static int test_wolfSSL_SHA512_224_Transform(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SHA512) && \ + !defined(WOLFSSL_NOSHA512_224) +#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) && \ + !defined(WOLFSSL_KCAPI_HASH) + byte input1[] = ""; + byte input2[] = "abc"; + byte local[WC_SHA512_BLOCK_SIZE]; + word32 sLen = 0; + unsigned char output1[] = + "\x94\x24\x66\xd4\x60\x3a\xeb\x23\x1d\xa8\x69\x31\x3c\xd2\xde\x11" + "\x48\x0f\x4a\x5a\xdf\x3a\x8d\x87\xcf\xcd\xbf\xa5\x03\x21\x50\xf1" + "\x8a\x0d\x0f\x0d\x3c\x07\xba\x52\xe0\xaa\x3c\xbb\xf1\xd3\x3f\xca" + "\x12\xa7\x61\xf8\x47\xda\x0d\x1b\x79\xc2\x65\x13\x92\xc1\x9c\xa5"; + unsigned char output2[] = + "\x51\x28\xe7\x0b\xca\x1e\xbc\x5f\xd7\x34\x0b\x48\x30\xd7\xc2\x75" + "\x6d\x8d\x48\x2c\x1f\xc7\x9e\x2b\x20\x5e\xbb\x0f\x0e\x4d\xb7\x61" + "\x31\x76\x33\xa0\xb4\x3d\x5f\x93\xc1\x73\xac\xf7\x21\xff\x69\x17" + "\xce\x66\xe5\x1e\x31\xe7\xf3\x22\x0f\x0b\x34\xd7\x5a\x57\xeb\xbf"; + union { + wc_Sha512 native; + SHA512_CTX compat; + } sha512; + +#ifdef BIG_ENDIAN_ORDER + ByteReverseWords64((word64*)output1, (word64*)output1, sizeof(output1)); + ByteReverseWords64((word64*)output2, (word64*)output2, sizeof(output2)); +#endif + + XMEMSET(&sha512.compat, 0, sizeof(sha512.compat)); + XMEMSET(&local, 0, sizeof(local)); + + /* sanity check */ + ExpectIntEQ(SHA512_224_Transform(NULL, NULL), 0); + ExpectIntEQ(SHA512_224_Transform(NULL, (const byte*)&input1), 0); + ExpectIntEQ(SHA512_224_Transform(&sha512.compat, NULL), 0); + ExpectIntEQ(wc_Sha512_224Transform(NULL, NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sha512_224Transform(NULL, (const byte*)&input1), + BAD_FUNC_ARG); + ExpectIntEQ(wc_Sha512_224Transform(&sha512.native, NULL), BAD_FUNC_ARG); + + /* Init SHA512 CTX */ + ExpectIntEQ(wolfSSL_SHA512_224_Init(&sha512.compat), 1); + + /* Do Transform*/ + sLen = (word32)XSTRLEN((char*)input1); + XMEMCPY(local, input1, sLen); + ExpectIntEQ(SHA512_224_Transform(&sha512.compat, (const byte*)&local[0]), + 1); + ExpectIntEQ(XMEMCMP(sha512.native.digest, output1, + WC_SHA512_DIGEST_SIZE), 0); + /* frees resources */ + ExpectIntEQ(SHA512_224_Final(local, &sha512.compat), 1); + + /* Init SHA512 CTX */ + ExpectIntEQ(SHA512_224_Init(&sha512.compat), 1); + sLen = (word32)XSTRLEN((char*)input2); + XMEMSET(local, 0, WC_SHA512_BLOCK_SIZE); + XMEMCPY(local, input2, sLen); + ExpectIntEQ(SHA512_224_Transform(&sha512.compat, (const byte*)&local[0]), + 1); + ExpectIntEQ(XMEMCMP(sha512.native.digest, output2, + WC_SHA512_DIGEST_SIZE), 0); + /* frees resources */ + ExpectIntEQ(SHA512_224_Final(local, &sha512.compat), 1); +#endif +#endif + return EXPECT_RESULT(); +} + +static int test_wolfSSL_SHA512_256_Transform(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SHA512) && \ + !defined(WOLFSSL_NOSHA512_256) +#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) && \ + !defined(WOLFSSL_KCAPI_HASH) + byte input1[] = ""; + byte input2[] = "abc"; + byte local[WC_SHA512_BLOCK_SIZE]; + word32 sLen = 0; + unsigned char output1[] = + "\xf8\x37\x37\x5a\xd7\x2e\x56\xec\xe2\x51\xa8\x31\x3a\xa0\x63\x2b" + "\x7e\x7c\x64\xcc\xd9\xff\x2b\x6b\xeb\xc3\xd4\x4d\x7f\x8a\x3a\xb5" + "\x61\x85\x0b\x37\x30\x9f\x3b\x08\x5e\x7b\xd3\xbc\x6d\x00\x61\xc0" + "\x65\x9a\xd7\x73\xda\x40\xbe\xc1\xe5\x2f\xc6\x5d\xb7\x9f\xbe\x60"; + unsigned char output2[] = + "\x22\xad\xc0\x30\xee\xd4\x6a\xef\x13\xee\x5a\x95\x8b\x1f\xb7\xb6" + "\xb6\xba\xc0\x44\xb8\x18\x3b\xf0\xf6\x4b\x70\x9f\x03\xba\x64\xa1" + "\xe1\xe3\x45\x15\x91\x7d\xcb\x0b\x9a\xf0\xd2\x8e\x47\x8b\x37\x78" + "\x91\x41\xa6\xc4\xb0\x29\x8f\x8b\xdd\x78\x5c\xf2\x73\x3f\x21\x31"; + union { + wc_Sha512 native; + SHA512_CTX compat; + } sha512; + +#ifdef BIG_ENDIAN_ORDER + ByteReverseWords64((word64*)output1, (word64*)output1, sizeof(output1)); + ByteReverseWords64((word64*)output2, (word64*)output2, sizeof(output2)); +#endif + + XMEMSET(&sha512.compat, 0, sizeof(sha512.compat)); + XMEMSET(&local, 0, sizeof(local)); + + /* sanity check */ + ExpectIntEQ(SHA512_256_Transform(NULL, NULL), 0); + ExpectIntEQ(SHA512_256_Transform(NULL, (const byte*)&input1), 0); + ExpectIntEQ(SHA512_256_Transform(&sha512.compat, NULL), 0); + ExpectIntEQ(wc_Sha512_256Transform(NULL, NULL), BAD_FUNC_ARG); + ExpectIntEQ(wc_Sha512_256Transform(NULL, (const byte*)&input1), + BAD_FUNC_ARG); + ExpectIntEQ(wc_Sha512_256Transform(&sha512.native, NULL), BAD_FUNC_ARG); + + /* Init SHA512 CTX */ + ExpectIntEQ(wolfSSL_SHA512_256_Init(&sha512.compat), 1); + + /* Do Transform*/ + sLen = (word32)XSTRLEN((char*)input1); + XMEMCPY(local, input1, sLen); + ExpectIntEQ(SHA512_256_Transform(&sha512.compat, (const byte*)&local[0]), + 1); + ExpectIntEQ(XMEMCMP(sha512.native.digest, output1, + WC_SHA512_DIGEST_SIZE), 0); + /* frees resources */ + ExpectIntEQ(SHA512_256_Final(local, &sha512.compat), 1); + + /* Init SHA512 CTX */ + ExpectIntEQ(SHA512_256_Init(&sha512.compat), 1); + sLen = (word32)XSTRLEN((char*)input2); + XMEMSET(local, 0, WC_SHA512_BLOCK_SIZE); + XMEMCPY(local, input2, sLen); + ExpectIntEQ(SHA512_256_Transform(&sha512.compat, (const byte*)&local[0]), + 1); + ExpectIntEQ(XMEMCMP(sha512.native.digest, output2, + WC_SHA512_DIGEST_SIZE), 0); + /* frees resources */ + ExpectIntEQ(SHA512_256_Final(local, &sha512.compat), 1); +#endif +#endif + return EXPECT_RESULT(); +} + +#if defined(OPENSSL_EXTRA) && !defined(NO_HMAC) +/* helper function for test_wolfSSL_HMAC_CTX, digest size is expected to be a + * buffer of 64 bytes. + * + * returns the size of the digest buffer on success and a negative value on + * failure. + */ +static int test_HMAC_CTX_helper(const EVP_MD* type, unsigned char* digest, + int* sz) +{ + EXPECT_DECLS; + HMAC_CTX ctx1; + HMAC_CTX ctx2; + + unsigned char key[] = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" + "\x0b\x0b\x0b\x0b\x0b\x0b\x0b"; + unsigned char long_key[] = + "0123456789012345678901234567890123456789" + "0123456789012345678901234567890123456789" + "0123456789012345678901234567890123456789" + "0123456789012345678901234567890123456789"; + + unsigned char msg[] = "message to hash"; + unsigned int digestSz = 64; + int keySz = sizeof(key); + int long_keySz = sizeof(long_key); + int msgSz = sizeof(msg); + + unsigned char digest2[64]; + unsigned int digestSz2 = 64; + + HMAC_CTX_init(&ctx1); + + ExpectIntEQ(HMAC_Init(&ctx1, (const void*)key, keySz, type), SSL_SUCCESS); + ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS); + ExpectIntEQ(HMAC_CTX_copy(&ctx2, &ctx1), SSL_SUCCESS); + + ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS); + ExpectIntEQ(HMAC_Final(&ctx1, digest, &digestSz), SSL_SUCCESS); + HMAC_CTX_cleanup(&ctx1); + + ExpectIntEQ(HMAC_Update(&ctx2, msg, msgSz), SSL_SUCCESS); + ExpectIntEQ(HMAC_Final(&ctx2, digest2, &digestSz2), SSL_SUCCESS); + HMAC_CTX_cleanup(&ctx2); + + ExpectIntEQ(digestSz, digestSz2); + ExpectIntEQ(XMEMCMP(digest, digest2, digestSz), 0); + + /* test HMAC_Init with NULL key */ + + /* init after copy */ + HMAC_CTX_init(&ctx1); + ExpectIntEQ(HMAC_Init(&ctx1, (const void*)key, keySz, type), SSL_SUCCESS); + ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS); + ExpectIntEQ(HMAC_CTX_copy(&ctx2, &ctx1), SSL_SUCCESS); + + ExpectIntEQ(HMAC_Init(&ctx1, NULL, 0, NULL), SSL_SUCCESS); + ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS); + ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS); + ExpectIntEQ(HMAC_Final(&ctx1, digest, &digestSz), SSL_SUCCESS); + HMAC_CTX_cleanup(&ctx1); + + ExpectIntEQ(HMAC_Init(&ctx2, NULL, 0, NULL), SSL_SUCCESS); + ExpectIntEQ(HMAC_Update(&ctx2, msg, msgSz), SSL_SUCCESS); + ExpectIntEQ(HMAC_Update(&ctx2, msg, msgSz), SSL_SUCCESS); + ExpectIntEQ(HMAC_Final(&ctx2, digest2, &digestSz), SSL_SUCCESS); + HMAC_CTX_cleanup(&ctx2); + + ExpectIntEQ(digestSz, digestSz2); + ExpectIntEQ(XMEMCMP(digest, digest2, digestSz), 0); + + /* long key */ + HMAC_CTX_init(&ctx1); + ExpectIntEQ(HMAC_Init(&ctx1, (const void*)long_key, long_keySz, type), + SSL_SUCCESS); + ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS); + ExpectIntEQ(HMAC_CTX_copy(&ctx2, &ctx1), SSL_SUCCESS); + + ExpectIntEQ(HMAC_Init(&ctx1, NULL, 0, NULL), SSL_SUCCESS); + ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS); + ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS); + ExpectIntEQ(HMAC_Final(&ctx1, digest, &digestSz), SSL_SUCCESS); + HMAC_CTX_cleanup(&ctx1); + + ExpectIntEQ(HMAC_Init(&ctx2, NULL, 0, NULL), SSL_SUCCESS); + ExpectIntEQ(HMAC_Update(&ctx2, msg, msgSz), SSL_SUCCESS); + ExpectIntEQ(HMAC_Update(&ctx2, msg, msgSz), SSL_SUCCESS); + ExpectIntEQ(HMAC_Final(&ctx2, digest2, &digestSz), SSL_SUCCESS); + HMAC_CTX_cleanup(&ctx2); + + ExpectIntEQ(digestSz, digestSz2); + ExpectIntEQ(XMEMCMP(digest, digest2, digestSz), 0); + + /* init before copy */ + HMAC_CTX_init(&ctx1); + ExpectIntEQ(HMAC_Init(&ctx1, (const void*)key, keySz, type), SSL_SUCCESS); + ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS); + ExpectIntEQ(HMAC_Init(&ctx1, NULL, 0, NULL), SSL_SUCCESS); + ExpectIntEQ(HMAC_CTX_copy(&ctx2, &ctx1), SSL_SUCCESS); + + ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS); + ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS); + ExpectIntEQ(HMAC_Final(&ctx1, digest, &digestSz), SSL_SUCCESS); + HMAC_CTX_cleanup(&ctx1); + + ExpectIntEQ(HMAC_Update(&ctx2, msg, msgSz), SSL_SUCCESS); + ExpectIntEQ(HMAC_Update(&ctx2, msg, msgSz), SSL_SUCCESS); + ExpectIntEQ(HMAC_Final(&ctx2, digest2, &digestSz), SSL_SUCCESS); + HMAC_CTX_cleanup(&ctx2); + + ExpectIntEQ(digestSz, digestSz2); + ExpectIntEQ(XMEMCMP(digest, digest2, digestSz), 0); + + *sz = digestSz; + return EXPECT_RESULT(); +} +#endif /* defined(OPENSSL_EXTRA) && !defined(NO_HMAC) */ + +static int test_wolfSSL_HMAC_CTX(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && !defined(NO_HMAC) + unsigned char digest[64]; + int digestSz; + WOLFSSL_HMAC_CTX* hmac_ctx = NULL; + WOLFSSL_HMAC_CTX ctx1; + WOLFSSL_HMAC_CTX ctx2; + + ExpectNotNull(hmac_ctx = wolfSSL_HMAC_CTX_new()); + ExpectIntEQ(wolfSSL_HMAC_CTX_Init(NULL), 1); + ExpectIntEQ(wolfSSL_HMAC_CTX_Init(hmac_ctx), 1); + wolfSSL_HMAC_CTX_free(NULL); + wolfSSL_HMAC_CTX_free(hmac_ctx); + + XMEMSET(&ctx2, 0, sizeof(WOLFSSL_HMAC_CTX)); + ExpectIntEQ(HMAC_CTX_init(NULL), 1); + ExpectIntEQ(HMAC_CTX_init(&ctx2), 1); + ExpectIntEQ(HMAC_CTX_copy(NULL, NULL), 0); + ExpectIntEQ(HMAC_CTX_copy(NULL, &ctx2), 0); + ExpectIntEQ(HMAC_CTX_copy(&ctx2, NULL), 0); +#if defined(HAVE_SELFTEST) || (defined(HAVE_FIPS) && \ + ((! defined(HAVE_FIPS_VERSION)) || \ + defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION <= 2))) + /* Copy object that hasn't had a digest set - MD5. */ + ExpectIntEQ(HMAC_CTX_copy(&ctx1, &ctx2), 1); +#else + /* Copy object that hasn't had a digest set. */ + ExpectIntEQ(HMAC_CTX_copy(&ctx1, &ctx2), 0); +#endif + HMAC_CTX_cleanup(NULL); + HMAC_CTX_cleanup(&ctx2); + + ExpectNull(HMAC_CTX_get_md(NULL)); + + #ifndef NO_SHA + ExpectIntEQ((test_HMAC_CTX_helper(EVP_sha1(), digest, &digestSz)), + TEST_SUCCESS); + ExpectIntEQ(digestSz, 20); + ExpectIntEQ(XMEMCMP("\xD9\x68\x77\x23\x70\xFB\x53\x70\x53\xBA\x0E\xDC\xDA" + "\xBF\x03\x98\x31\x19\xB2\xCC", digest, digestSz), 0); + #endif /* !NO_SHA */ + #ifdef WOLFSSL_SHA224 + ExpectIntEQ((test_HMAC_CTX_helper(EVP_sha224(), digest, &digestSz)), + TEST_SUCCESS); + ExpectIntEQ(digestSz, 28); + ExpectIntEQ(XMEMCMP("\x57\xFD\xF4\xE1\x2D\xB0\x79\xD7\x4B\x25\x7E\xB1\x95" + "\x9C\x11\xAC\x2D\x1E\x78\x94\x4F\x3A\x0F\xED\xF8\xAD" + "\x02\x0E", digest, digestSz), 0); + #endif /* WOLFSSL_SHA224 */ + #ifndef NO_SHA256 + ExpectIntEQ((test_HMAC_CTX_helper(EVP_sha256(), digest, &digestSz)), + TEST_SUCCESS); + ExpectIntEQ(digestSz, 32); + ExpectIntEQ(XMEMCMP("\x13\xAB\x76\x91\x0C\x37\x86\x8D\xB3\x7E\x30\x0C\xFC" + "\xB0\x2E\x8E\x4A\xD7\xD4\x25\xCC\x3A\xA9\x0F\xA2\xF2" + "\x47\x1E\x62\x6F\x5D\xF2", digest, digestSz), 0); + #endif /* !NO_SHA256 */ + + #ifdef WOLFSSL_SHA384 + ExpectIntEQ((test_HMAC_CTX_helper(EVP_sha384(), digest, &digestSz)), + TEST_SUCCESS); + ExpectIntEQ(digestSz, 48); + ExpectIntEQ(XMEMCMP("\x9E\xCB\x07\x0C\x11\x76\x3F\x23\xC3\x25\x0E\xC4\xB7" + "\x28\x77\x95\x99\xD5\x9D\x7A\xBB\x1A\x9F\xB7\xFD\x25" + "\xC9\x72\x47\x9F\x8F\x86\x76\xD6\x20\x57\x87\xB7\xE7" + "\xCD\xFB\xC2\xCC\x9F\x2B\xC5\x41\xAB", + digest, digestSz), 0); + #endif /* WOLFSSL_SHA384 */ + #ifdef WOLFSSL_SHA512 + ExpectIntEQ((test_HMAC_CTX_helper(EVP_sha512(), digest, &digestSz)), + TEST_SUCCESS); + ExpectIntEQ(digestSz, 64); + ExpectIntEQ(XMEMCMP("\xD4\x21\x0C\x8B\x60\x6F\xF4\xBF\x07\x2F\x26\xCC\xAD" + "\xBC\x06\x0B\x34\x78\x8B\x4F\xD6\xC0\x42\xF1\x33\x10" + "\x6C\x4F\x1E\x55\x59\xDD\x2A\x9F\x15\x88\x62\xF8\x60" + "\xA3\x99\x91\xE2\x08\x7B\xF7\x95\x3A\xB0\x92\x48\x60" + "\x88\x8B\x5B\xB8\x5F\xE9\xB6\xB1\x96\xE3\xB5\xF0", + digest, digestSz), 0); + #endif /* WOLFSSL_SHA512 */ + +#ifdef WOLFSSL_SHA3 + #ifndef WOLFSSL_NOSHA3_224 + ExpectIntEQ((test_HMAC_CTX_helper(EVP_sha3_224(), digest, &digestSz)), + TEST_SUCCESS); + ExpectIntEQ(digestSz, 28); + ExpectIntEQ(XMEMCMP("\xdc\x53\x25\x3f\xc0\x9d\x2b\x0c\x7f\x59\x11\x17\x08" + "\x5c\xe8\x43\x31\x01\x5a\xb3\xe3\x08\x37\x71\x26\x0b" + "\x29\x0f", digest, digestSz), 0); + #endif + #ifndef WOLFSSL_NOSHA3_256 + ExpectIntEQ((test_HMAC_CTX_helper(EVP_sha3_256(), digest, &digestSz)), + TEST_SUCCESS); + ExpectIntEQ(digestSz, 32); + ExpectIntEQ(XMEMCMP("\x0f\x00\x89\x82\x15\xce\xd6\x45\x01\x83\xce\xc8\x35" + "\xab\x71\x07\xc9\xfe\x61\x22\x38\xf9\x09\xad\x35\x65" + "\x43\x77\x24\xd4\x1e\xf4", digest, digestSz), 0); + #endif + #ifndef WOLFSSL_NOSHA3_384 + ExpectIntEQ((test_HMAC_CTX_helper(EVP_sha3_384(), digest, &digestSz)), + TEST_SUCCESS); + ExpectIntEQ(digestSz, 48); + ExpectIntEQ(XMEMCMP("\x0f\x6a\xc0\xfb\xc3\xf2\x80\xb1\xb4\x04\xb6\xc8\x45" + "\x23\x3b\xb4\xbe\xc6\xea\x85\x07\xca\x8c\x71\xbb\x6e" + "\x79\xf6\xf9\x2b\x98\xf5\xef\x11\x39\xd4\x5d\xd3\xca" + "\xc0\xe6\x81\xf7\x73\xf9\x85\x5d\x4f", + digest, digestSz), 0); + #endif + #ifndef WOLFSSL_NOSHA3_512 + ExpectIntEQ((test_HMAC_CTX_helper(EVP_sha3_512(), digest, &digestSz)), + TEST_SUCCESS); + ExpectIntEQ(digestSz, 64); + ExpectIntEQ(XMEMCMP("\x3e\x77\xe3\x59\x42\x89\xed\xc3\xa4\x26\x3d\xa4\x75" + "\xd2\x84\x8c\xb2\xf3\x25\x04\x47\x61\xce\x1c\x42\x86" + "\xcd\xf4\x56\xaa\x2f\x84\xb1\x3b\x18\xed\xe6\xd6\x48" + "\x15\xb0\x29\xc5\x9d\x32\xef\xdd\x3e\x09\xf6\xed\x9e" + "\x70\xbc\x1c\x63\xf7\x3b\x3e\xe1\xdc\x84\x9c\x1c", + digest, digestSz), 0); + #endif +#endif + + #if !defined(NO_MD5) && (!defined(HAVE_FIPS_VERSION) || \ + HAVE_FIPS_VERSION <= 2) + ExpectIntEQ((test_HMAC_CTX_helper(EVP_md5(), digest, &digestSz)), + TEST_SUCCESS); + ExpectIntEQ(digestSz, 16); + ExpectIntEQ(XMEMCMP("\xB7\x27\xC4\x41\xE5\x2E\x62\xBA\x54\xED\x72\x70\x9F" + "\xE4\x98\xDD", digest, digestSz), 0); + #endif /* !NO_MD5 */ +#endif + return EXPECT_RESULT(); +} + #if defined(OPENSSL_EXTRA) && (!defined(NO_SHA256) || \ defined(WOLFSSL_SHA224) || defined(WOLFSSL_SHA384) || \ defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA3)) @@ -40877,23 +41749,58 @@ static int test_openssl_hmac(const WOLFSSL_EVP_MD* md, int md_len) ExpectNotNull(hmac = HMAC_CTX_new()); HMAC_CTX_init(hmac); - ExpectIntEQ(HMAC_Init_ex(hmac, (void*)key, (int)sizeof(key), md, e), - SSL_SUCCESS); +#if defined(HAVE_SELFTEST) || (defined(HAVE_FIPS) && \ + ((! defined(HAVE_FIPS_VERSION)) || \ + defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION <= 2))) + /* Get size on object that hasn't had a digest set - MD5. */ + ExpectIntEQ(HMAC_size(hmac), 16); + ExpectIntEQ(HMAC_Init(hmac, NULL, 0, NULL), 1); + ExpectIntEQ(HMAC_Init(hmac, (void*)key, (int)sizeof(key), NULL), 1); + ExpectIntEQ(HMAC_Init(hmac, NULL, 0, md), 1); +#else + ExpectIntEQ(HMAC_size(hmac), BAD_FUNC_ARG); + ExpectIntEQ(HMAC_Init(hmac, NULL, 0, NULL), 0); + ExpectIntEQ(HMAC_Init(hmac, (void*)key, (int)sizeof(key), NULL), 0); + ExpectIntEQ(HMAC_Init(hmac, NULL, 0, md), 0); +#endif + ExpectIntEQ(HMAC_Init_ex(NULL, (void*)key, (int)sizeof(key), md, e), 0); + ExpectIntEQ(HMAC_Init_ex(hmac, (void*)key, (int)sizeof(key), md, e), 1); /* re-using test key as data to hash */ - ExpectIntEQ(HMAC_Update(hmac, key, (int)sizeof(key)), SSL_SUCCESS); - ExpectIntEQ(HMAC_Update(hmac, NULL, 0), SSL_SUCCESS); - ExpectIntEQ(HMAC_Final(hmac, hash, &len), SSL_SUCCESS); + ExpectIntEQ(HMAC_Update(NULL, key, (int)sizeof(key)), 0); + ExpectIntEQ(HMAC_Update(hmac, key, (int)sizeof(key)), 1); + ExpectIntEQ(HMAC_Update(hmac, key, 0), 1); + ExpectIntEQ(HMAC_Update(hmac, NULL, 0), 1); + ExpectIntEQ(HMAC_Update(hmac, NULL, (int)sizeof(key)), 1); + ExpectIntEQ(HMAC_Final(NULL, NULL, &len), 0); + ExpectIntEQ(HMAC_Final(hmac, NULL, &len), 0); + ExpectIntEQ(HMAC_Final(NULL, hash, &len), 0); + ExpectIntEQ(HMAC_Final(hmac, hash, &len), 1); + ExpectIntEQ(HMAC_Final(hmac, hash, NULL), 1); ExpectIntEQ(len, md_len); + ExpectIntEQ(HMAC_size(NULL), 0); ExpectIntEQ(HMAC_size(hmac), md_len); ExpectStrEQ(HMAC_CTX_get_md(hmac), md); + HMAC_cleanup(NULL); HMAC_cleanup(hmac); HMAC_CTX_free(hmac); len = 0; + ExpectNull(HMAC(NULL, key, (int)sizeof(key), NULL, 0, hash, &len)); + ExpectNull(HMAC(md, NULL, (int)sizeof(key), NULL, 0, hash, &len)); + ExpectNull(HMAC(md, key, (int)sizeof(key), NULL, 0, NULL, &len)); ExpectNotNull(HMAC(md, key, (int)sizeof(key), NULL, 0, hash, &len)); ExpectIntEQ(len, md_len); + ExpectNotNull(HMAC(md, key, (int)sizeof(key), NULL, 0, hash, NULL)); + /* With data. */ + ExpectNotNull(HMAC(md, key, (int)sizeof(key), key, (int)sizeof(key), hash, + &len)); + /* With NULL data. */ + ExpectNull(HMAC(md, key, (int)sizeof(key), NULL, (int)sizeof(key), hash, + &len)); + /* With zero length data. */ + ExpectNotNull(HMAC(md, key, (int)sizeof(key), key, 0, hash, &len)); return EXPECT_RESULT(); } @@ -40953,37 +41860,1011 @@ static int test_wolfSSL_CMAC(void) #if defined(WOLFSSL_CMAC) && defined(OPENSSL_EXTRA) && \ defined(WOLFSSL_AES_DIRECT) int i; - byte key[AES_128_KEY_SIZE]; + byte key[AES_256_KEY_SIZE]; CMAC_CTX* cmacCtx = NULL; byte out[AES_BLOCK_SIZE]; size_t outLen = AES_BLOCK_SIZE; - for (i=0; i < AES_128_KEY_SIZE; ++i) { + for (i=0; i < AES_256_KEY_SIZE; ++i) { key[i] = i; } ExpectNotNull(cmacCtx = CMAC_CTX_new()); /* Check CMAC_CTX_get0_cipher_ctx; return value not used. */ ExpectNotNull(CMAC_CTX_get0_cipher_ctx(cmacCtx)); ExpectIntEQ(CMAC_Init(cmacCtx, key, AES_128_KEY_SIZE, EVP_aes_128_cbc(), - NULL), SSL_SUCCESS); + NULL), 1); /* re-using test key as data to hash */ - ExpectIntEQ(CMAC_Update(cmacCtx, key, AES_128_KEY_SIZE), SSL_SUCCESS); - ExpectIntEQ(CMAC_Update(cmacCtx, NULL, 0), SSL_SUCCESS); - ExpectIntEQ(CMAC_Final(cmacCtx, out, &outLen), SSL_SUCCESS); + ExpectIntEQ(CMAC_Update(cmacCtx, key, AES_128_KEY_SIZE), 1); + ExpectIntEQ(CMAC_Update(cmacCtx, NULL, 0), 1); + ExpectIntEQ(CMAC_Final(cmacCtx, out, &outLen), 1); ExpectIntEQ(outLen, AES_BLOCK_SIZE); + + /* No Update works. */ + ExpectIntEQ(CMAC_Init(cmacCtx, key, AES_128_KEY_SIZE, EVP_aes_128_cbc(), + NULL), 1); + ExpectIntEQ(CMAC_Final(cmacCtx, out, NULL), 1); + + ExpectIntEQ(CMAC_Init(cmacCtx, key, AES_128_KEY_SIZE, EVP_aes_128_cbc(), + NULL), 1); + /* Test parameters with CMAC_Update. */ + ExpectIntEQ(CMAC_Update(NULL, NULL, 0), 0); + ExpectIntEQ(CMAC_Update(NULL, key, 0), 0); + ExpectIntEQ(CMAC_Update(NULL, NULL, AES_128_KEY_SIZE), 0); + ExpectIntEQ(CMAC_Update(NULL, key, AES_128_KEY_SIZE), 0); + ExpectIntEQ(CMAC_Update(cmacCtx, key, 0), 1); + ExpectIntEQ(CMAC_Update(cmacCtx, NULL, 0), 1); + ExpectIntEQ(CMAC_Update(cmacCtx, NULL, AES_128_KEY_SIZE), 1); + /* Test parameters with CMAC_Final. */ + ExpectIntEQ(CMAC_Final(NULL, NULL, NULL), 0); + ExpectIntEQ(CMAC_Final(NULL, out, NULL), 0); + ExpectIntEQ(CMAC_Final(NULL, NULL, &outLen), 0); + ExpectIntEQ(CMAC_Final(NULL, out, &outLen), 0); + ExpectIntEQ(CMAC_Final(cmacCtx, NULL, NULL), 1); + ExpectIntEQ(CMAC_Final(cmacCtx, NULL, &outLen), 1); + ExpectIntEQ(CMAC_Final(cmacCtx, out, NULL), 1); CMAC_CTX_free(cmacCtx); - /* give a key too small for the cipher, verify we get failure */ + /* Test parameters with CMAC Init. */ cmacCtx = NULL; ExpectNotNull(cmacCtx = CMAC_CTX_new()); ExpectNotNull(CMAC_CTX_get0_cipher_ctx(cmacCtx)); + ExpectIntEQ(CMAC_Init(NULL, NULL, 0, NULL, NULL), 0); + ExpectIntEQ(CMAC_Init(NULL, key, AES_192_KEY_SIZE, EVP_aes_192_cbc(), + NULL), 0); + ExpectIntEQ(CMAC_Init(cmacCtx, NULL, AES_192_KEY_SIZE, EVP_aes_192_cbc(), + NULL), 0); + /* give a key too small for the cipher, verify we get failure */ ExpectIntEQ(CMAC_Init(cmacCtx, key, AES_128_KEY_SIZE, EVP_aes_192_cbc(), - NULL), SSL_FAILURE); + NULL), 0); + ExpectIntEQ(CMAC_Init(cmacCtx, key, AES_192_KEY_SIZE, NULL, NULL), 0); + #if defined(HAVE_AESGCM) && defined(WOLFSSL_AES_128) + /* Only AES-CBC supported. */ + ExpectIntEQ(CMAC_Init(cmacCtx, key, AES_128_KEY_SIZE, EVP_aes_128_gcm(), + NULL), 0); + #endif + CMAC_CTX_free(cmacCtx); + + ExpectNull(CMAC_CTX_get0_cipher_ctx(NULL)); + cmacCtx = NULL; + ExpectNotNull(cmacCtx = CMAC_CTX_new()); + /* No Init. */ + ExpectIntEQ(CMAC_Final(cmacCtx, out, &outLen), 0); + CMAC_CTX_free(cmacCtx); + + /* Test AES-256-CBC */ + cmacCtx = NULL; + ExpectNotNull(cmacCtx = CMAC_CTX_new()); + ExpectIntEQ(CMAC_Init(cmacCtx, key, AES_256_KEY_SIZE, EVP_aes_256_cbc(), + NULL), 1); + ExpectIntEQ(CMAC_Update(cmacCtx, key, AES_128_KEY_SIZE), 1); + ExpectIntEQ(CMAC_Final(cmacCtx, out, NULL), 1); + CMAC_CTX_free(cmacCtx); + + /* Test AES-192-CBC */ + cmacCtx = NULL; + ExpectNotNull(cmacCtx = CMAC_CTX_new()); + ExpectIntEQ(CMAC_Init(cmacCtx, key, AES_192_KEY_SIZE, EVP_aes_192_cbc(), + NULL), 1); + ExpectIntEQ(CMAC_Update(cmacCtx, key, AES_128_KEY_SIZE), 1); + ExpectIntEQ(CMAC_Final(cmacCtx, out, NULL), 1); + CMAC_CTX_free(cmacCtx); + + cmacCtx = NULL; + ExpectNotNull(cmacCtx = CMAC_CTX_new()); CMAC_CTX_free(cmacCtx); #endif /* WOLFSSL_CMAC && OPENSSL_EXTRA && WOLFSSL_AES_DIRECT */ return EXPECT_RESULT(); } +static int test_wolfSSL_DES(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && !defined(NO_DES3) + const_DES_cblock myDes; + DES_cblock iv; + DES_key_schedule key; + word32 i; + DES_LONG dl; + unsigned char msg[] = "hello wolfssl"; + unsigned char weakKey[][8] = { + { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE }, + { 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 }, + { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E } + }; + unsigned char semiWeakKey[][8] = { + { 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E }, + { 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 }, + { 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 }, + { 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 }, + { 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE }, + { 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 }, + { 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 }, + { 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E }, + { 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE }, + { 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E }, + { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE }, + { 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 } + }; + + DES_check_key(1); + DES_set_key(&myDes, &key); + + /* check, check of odd parity */ + XMEMSET(myDes, 4, sizeof(const_DES_cblock)); + myDes[0] = 6; /* set even parity */ + XMEMSET(key, 5, sizeof(DES_key_schedule)); + ExpectIntEQ(DES_set_key_checked(&myDes, &key), -1); + ExpectIntNE(key[0], myDes[0]); /* should not have copied over key */ + ExpectIntEQ(DES_set_key_checked(NULL, NULL), -2); + ExpectIntEQ(DES_set_key_checked(&myDes, NULL), -2); + ExpectIntEQ(DES_set_key_checked(NULL, &key), -2); + + /* set odd parity for success case */ + DES_set_odd_parity(&myDes); + ExpectIntEQ(DES_check_key_parity(&myDes), 1); + fprintf(stderr, "%02x %02x %02x %02x", myDes[0], myDes[1], myDes[2], + myDes[3]); + ExpectIntEQ(DES_set_key_checked(&myDes, &key), 0); + for (i = 0; i < sizeof(DES_key_schedule); i++) { + ExpectIntEQ(key[i], myDes[i]); + } + ExpectIntEQ(DES_is_weak_key(&myDes), 0); + + /* check weak key */ + XMEMSET(myDes, 1, sizeof(const_DES_cblock)); + XMEMSET(key, 5, sizeof(DES_key_schedule)); + ExpectIntEQ(DES_set_key_checked(&myDes, &key), -2); + ExpectIntNE(key[0], myDes[0]); /* should not have copied over key */ + + DES_set_key_unchecked(NULL, NULL); + DES_set_key_unchecked(&myDes, NULL); + DES_set_key_unchecked(NULL, &key); + /* compare arrays, should be the same */ + /* now do unchecked copy of a weak key over */ + DES_set_key_unchecked(&myDes, &key); + /* compare arrays, should be the same */ + for (i = 0; i < sizeof(DES_key_schedule); i++) { + ExpectIntEQ(key[i], myDes[i]); + } + ExpectIntEQ(DES_is_weak_key(&myDes), 1); + + myDes[7] = 2; + ExpectIntEQ(DES_set_key_checked(&myDes, &key), 0); + ExpectIntEQ(DES_is_weak_key(&myDes), 0); + ExpectIntEQ(DES_is_weak_key(NULL), 1); + + /* Test all weak keys. */ + for (i = 0; i < sizeof(weakKey) / sizeof(*weakKey); i++) { + ExpectIntEQ(DES_set_key_checked(&weakKey[i], &key), -2); + } + /* Test all semi-weak keys. */ + for (i = 0; i < sizeof(semiWeakKey) / sizeof(*semiWeakKey); i++) { + ExpectIntEQ(DES_set_key_checked(&semiWeakKey[i], &key), -2); + } + + /* check DES_key_sched API */ + XMEMSET(key, 1, sizeof(DES_key_schedule)); + ExpectIntEQ(DES_key_sched(&myDes, NULL), 0); + ExpectIntEQ(DES_key_sched(NULL, &key), 0); + ExpectIntEQ(DES_key_sched(&myDes, &key), 0); + /* compare arrays, should be the same */ + for (i = 0; i < sizeof(DES_key_schedule); i++) { + ExpectIntEQ(key[i], myDes[i]); + } + + + ExpectIntEQ((DES_cbc_cksum(NULL, NULL, 0, NULL, NULL)), 0); + ExpectIntEQ((DES_cbc_cksum(msg, NULL, 0, NULL, NULL)), 0); + ExpectIntEQ((DES_cbc_cksum(NULL, &key, 0, NULL, NULL)), 0); + ExpectIntEQ((DES_cbc_cksum(NULL, NULL, 0, &myDes, NULL)), 0); + ExpectIntEQ((DES_cbc_cksum(NULL, NULL, 0, NULL, &iv)), 0); + ExpectIntEQ((DES_cbc_cksum(NULL, &key, sizeof(msg), &myDes, &iv)), 0); + ExpectIntEQ((DES_cbc_cksum(msg, NULL, sizeof(msg), &myDes, &iv)), 0); + ExpectIntEQ((DES_cbc_cksum(msg, &key, sizeof(msg), NULL, &iv)), 0); + ExpectIntEQ((DES_cbc_cksum(msg, &key, sizeof(msg), &myDes, NULL)), 0); + /* DES_cbc_cksum should return the last 4 of the last 8 bytes after + * DES_cbc_encrypt on the input */ + XMEMSET(iv, 0, sizeof(DES_cblock)); + XMEMSET(myDes, 5, sizeof(DES_key_schedule)); + ExpectIntGT((dl = DES_cbc_cksum(msg, &key, sizeof(msg), &myDes, &iv)), 0); + ExpectIntEQ(dl, 480052723); +#endif /* defined(OPENSSL_EXTRA) && !defined(NO_DES3) */ + return EXPECT_RESULT(); +} + +static int test_wolfSSL_DES_ncbc(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && !defined(NO_DES3) + const_DES_cblock myDes; + DES_cblock iv = {1}; + DES_key_schedule key = {0}; + unsigned char msg[] = "hello wolfssl"; + unsigned char out[DES_BLOCK_SIZE * 2] = {0}; + unsigned char pln[DES_BLOCK_SIZE * 2] = {0}; + + unsigned char exp[] = {0x31, 0x98, 0x2F, 0x3A, 0x55, 0xBF, 0xD8, 0xC4}; + unsigned char exp2[] = {0xC7, 0x45, 0x8B, 0x28, 0x10, 0x53, 0xE0, 0x58}; + + /* partial block test */ + DES_set_key(&key, &myDes); + DES_ncbc_encrypt(msg, out, 3, &myDes, &iv, DES_ENCRYPT); + ExpectIntEQ(XMEMCMP(exp, out, DES_BLOCK_SIZE), 0); + ExpectIntEQ(XMEMCMP(exp, iv, DES_BLOCK_SIZE), 0); + + DES_set_key(&key, &myDes); + XMEMSET((byte*)&iv, 0, DES_BLOCK_SIZE); + *((byte*)&iv) = 1; + DES_ncbc_encrypt(out, pln, 3, &myDes, &iv, DES_DECRYPT); + ExpectIntEQ(XMEMCMP(msg, pln, 3), 0); + ExpectIntEQ(XMEMCMP(exp, iv, DES_BLOCK_SIZE), 0); + + /* full block test */ + DES_set_key(&key, &myDes); + XMEMSET(pln, 0, DES_BLOCK_SIZE); + XMEMSET((byte*)&iv, 0, DES_BLOCK_SIZE); + *((byte*)&iv) = 1; + DES_ncbc_encrypt(msg, out, 8, &myDes, &iv, DES_ENCRYPT); + ExpectIntEQ(XMEMCMP(exp2, out, DES_BLOCK_SIZE), 0); + ExpectIntEQ(XMEMCMP(exp2, iv, DES_BLOCK_SIZE), 0); + + DES_set_key(&key, &myDes); + XMEMSET((byte*)&iv, 0, DES_BLOCK_SIZE); + *((byte*)&iv) = 1; + DES_ncbc_encrypt(out, pln, 8, &myDes, &iv, DES_DECRYPT); + ExpectIntEQ(XMEMCMP(msg, pln, 8), 0); + ExpectIntEQ(XMEMCMP(exp2, iv, DES_BLOCK_SIZE), 0); +#endif + return EXPECT_RESULT(); +} + +static int test_wolfSSL_DES_ecb_encrypt(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && !defined(NO_DES3) && defined(WOLFSSL_DES_ECB) + WOLFSSL_DES_cblock input1, input2, output1, output2, back1, back2; + WOLFSSL_DES_key_schedule key; + + XMEMCPY(key, "12345678", sizeof(WOLFSSL_DES_key_schedule)); + XMEMCPY(input1, "Iamhuman", sizeof(WOLFSSL_DES_cblock)); + XMEMCPY(input2, "Whoisit?", sizeof(WOLFSSL_DES_cblock)); + XMEMSET(output1, 0, sizeof(WOLFSSL_DES_cblock)); + XMEMSET(output2, 0, sizeof(WOLFSSL_DES_cblock)); + XMEMSET(back1, 0, sizeof(WOLFSSL_DES_cblock)); + XMEMSET(back2, 0, sizeof(WOLFSSL_DES_cblock)); + + wolfSSL_DES_ecb_encrypt(NULL, NULL, NULL, DES_ENCRYPT); + wolfSSL_DES_ecb_encrypt(&input1, NULL, NULL, DES_ENCRYPT); + wolfSSL_DES_ecb_encrypt(NULL, &output1, NULL, DES_ENCRYPT); + wolfSSL_DES_ecb_encrypt(NULL, NULL, &key, DES_ENCRYPT); + wolfSSL_DES_ecb_encrypt(&input1, &output1, NULL, DES_ENCRYPT); + wolfSSL_DES_ecb_encrypt(&input1, NULL, &key, DES_ENCRYPT); + wolfSSL_DES_ecb_encrypt(NULL, &output1, &key, DES_ENCRYPT); + + /* Encrypt messages */ + wolfSSL_DES_ecb_encrypt(&input1, &output1, &key, DES_ENCRYPT); + wolfSSL_DES_ecb_encrypt(&input2, &output2, &key, DES_ENCRYPT); + + { + /* Decrypt messages */ + int ret1 = 0; + int ret2 = 0; + wolfSSL_DES_ecb_encrypt(&output1, &back1, &key, DES_DECRYPT); + ExpectIntEQ(ret1 = XMEMCMP((unsigned char *)back1, + (unsigned char *)input1, sizeof(WOLFSSL_DES_cblock)), 0); + wolfSSL_DES_ecb_encrypt(&output2, &back2, &key, DES_DECRYPT); + ExpectIntEQ(ret2 = XMEMCMP((unsigned char *)back2, + (unsigned char *)input2, sizeof(WOLFSSL_DES_cblock)), 0); + } +#endif + return EXPECT_RESULT(); +} + +static int test_wolfSSL_DES_ede3_cbc_encrypt(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && !defined(NO_DES3) + unsigned char input1[8], input2[8]; + unsigned char output1[8], output2[8]; + unsigned char back1[8], back2[8]; + WOLFSSL_DES_cblock iv1, iv2; + WOLFSSL_DES_key_schedule key1, key2, key3; + int i; + + XMEMCPY(key1, "12345678", sizeof(WOLFSSL_DES_key_schedule)); + XMEMCPY(key2, "23456781", sizeof(WOLFSSL_DES_key_schedule)); + XMEMCPY(key3, "34567823", sizeof(WOLFSSL_DES_key_schedule)); + XMEMCPY(input1, "Iamhuman", sizeof(input1)); + XMEMCPY(input2, "Whoisit?", sizeof(input2)); + + XMEMSET(output1, 0, sizeof(output1)); + XMEMSET(output2, 0, sizeof(output2)); + XMEMSET(back1, 0, sizeof(back1)); + XMEMSET(back2, 0, sizeof(back2)); + + XMEMCPY(iv1, "87654321", sizeof(WOLFSSL_DES_cblock)); + XMEMCPY(iv2, "98765432", sizeof(WOLFSSL_DES_cblock)); + /* Encrypt messages */ + wolfSSL_DES_ede3_cbc_encrypt(input1, output1, 8, &key1, &key2, &key3, &iv1, + DES_ENCRYPT); + wolfSSL_DES_ede3_cbc_encrypt(input2, output2, 8, &key1, &key2, &key3, &iv2, + DES_ENCRYPT); + + { + XMEMCPY(iv1, "87654321", sizeof(WOLFSSL_DES_cblock)); + XMEMCPY(iv2, "98765432", sizeof(WOLFSSL_DES_cblock)); + /* Decrypt messages */ + wolfSSL_DES_ede3_cbc_encrypt(output1, back1, 8, &key1, &key2, &key3, + &iv1, DES_DECRYPT); + ExpectIntEQ(XMEMCMP(back1, input1, sizeof(input1)), 0); + wolfSSL_DES_ede3_cbc_encrypt(output2, back2, 8, &key1, &key2, &key3, + &iv2, DES_DECRYPT); + ExpectIntEQ(XMEMCMP(back2, input2, sizeof(input2)), 0); + } + + for (i = 0; i < 8; i++) { + XMEMSET(output1, 0, sizeof(output1)); + XMEMSET(output2, 0, sizeof(output2)); + XMEMSET(back1, 0, sizeof(back1)); + XMEMSET(back2, 0, sizeof(back2)); + + XMEMCPY(iv1, "87654321", sizeof(WOLFSSL_DES_cblock)); + XMEMCPY(iv2, "98765432", sizeof(WOLFSSL_DES_cblock)); + /* Encrypt partial messages */ + wolfSSL_DES_ede3_cbc_encrypt(input1, output1, i, &key1, &key2, &key3, + &iv1, DES_ENCRYPT); + wolfSSL_DES_ede3_cbc_encrypt(input2, output2, i, &key1, &key2, &key3, + &iv2, DES_ENCRYPT); + + { + XMEMCPY(iv1, "87654321", sizeof(WOLFSSL_DES_cblock)); + XMEMCPY(iv2, "98765432", sizeof(WOLFSSL_DES_cblock)); + /* Decrypt messages */ + wolfSSL_DES_ede3_cbc_encrypt(output1, back1, i, &key1, &key2, + &key3, &iv1, DES_DECRYPT); + ExpectIntEQ(XMEMCMP(back1, input1, i), 0); + wolfSSL_DES_ede3_cbc_encrypt(output2, back2, i, &key1, &key2, + &key3, &iv2, DES_DECRYPT); + ExpectIntEQ(XMEMCMP(back2, input2, i), 0); + } + } +#endif + return EXPECT_RESULT(); +} + +static int test_wolfSSL_AES_encrypt(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && !defined(NO_AES) && defined(HAVE_AES_ECB) + AES_KEY enc; + AES_KEY dec; + const byte msg[] = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a + }; + const byte exp[] = { + 0xf3, 0xee, 0xd1, 0xbd, 0xb5, 0xd2, 0xa0, 0x3c, + 0x06, 0x4b, 0x5a, 0x7e, 0x3d, 0xb1, 0x81, 0xf8, + }; + const byte key[] = { + 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, + 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, + 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, + 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4 + }; + byte eout[sizeof(msg)]; + byte dout[sizeof(msg)]; + + ExpectIntEQ(AES_set_encrypt_key(key, sizeof(key)*8, &enc), 0); + ExpectIntEQ(AES_set_decrypt_key(key, sizeof(key)*8, &dec), 0); + + wolfSSL_AES_encrypt(NULL, NULL, NULL); + wolfSSL_AES_encrypt(msg, NULL, NULL); + wolfSSL_AES_encrypt(NULL, eout, NULL); + wolfSSL_AES_encrypt(NULL, NULL, &enc); + wolfSSL_AES_encrypt(msg, eout, NULL); + wolfSSL_AES_encrypt(msg, NULL, &enc); + wolfSSL_AES_encrypt(NULL, eout, &enc); + + wolfSSL_AES_decrypt(NULL, NULL, NULL); + wolfSSL_AES_decrypt(eout, NULL, NULL); + wolfSSL_AES_decrypt(NULL, dout, NULL); + wolfSSL_AES_decrypt(NULL, NULL, &dec); + wolfSSL_AES_decrypt(eout, dout, NULL); + wolfSSL_AES_decrypt(eout, NULL, &dec); + wolfSSL_AES_decrypt(NULL, dout, &dec); + + wolfSSL_AES_encrypt(msg, eout, &enc); + ExpectIntEQ(XMEMCMP(eout, exp, AES_BLOCK_SIZE), 0); + wolfSSL_AES_decrypt(eout, dout, &dec); + ExpectIntEQ(XMEMCMP(dout, msg, AES_BLOCK_SIZE), 0); +#endif + return EXPECT_RESULT(); +} + +static int test_wolfSSL_AES_ecb_encrypt(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && !defined(NO_AES) && defined(HAVE_AES_ECB) + AES_KEY aes; + const byte msg[] = + { + 0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96, + 0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a + }; + + const byte verify[] = + { + 0xf3,0xee,0xd1,0xbd,0xb5,0xd2,0xa0,0x3c, + 0x06,0x4b,0x5a,0x7e,0x3d,0xb1,0x81,0xf8 + }; + + const byte key[] = + { + 0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe, + 0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81, + 0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7, + 0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4 + }; + + + byte out[AES_BLOCK_SIZE]; + + ExpectIntEQ(AES_set_encrypt_key(key, sizeof(key)*8, &aes), 0); + XMEMSET(out, 0, AES_BLOCK_SIZE); + AES_ecb_encrypt(msg, out, &aes, AES_ENCRYPT); + ExpectIntEQ(XMEMCMP(out, verify, AES_BLOCK_SIZE), 0); + +#ifdef HAVE_AES_DECRYPT + ExpectIntEQ(AES_set_decrypt_key(key, sizeof(key)*8, &aes), 0); + XMEMSET(out, 0, AES_BLOCK_SIZE); + AES_ecb_encrypt(verify, out, &aes, AES_DECRYPT); + ExpectIntEQ(XMEMCMP(out, msg, AES_BLOCK_SIZE), 0); +#endif + + /* test bad arguments */ + AES_ecb_encrypt(NULL, out, &aes, AES_DECRYPT); + AES_ecb_encrypt(verify, NULL, &aes, AES_DECRYPT); + AES_ecb_encrypt(verify, out, NULL, AES_DECRYPT); +#endif + return EXPECT_RESULT(); +} + +static int test_wolfSSL_AES_cbc_encrypt(void) +{ + EXPECT_DECLS; +#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(OPENSSL_EXTRA) + AES_KEY aes; + AES_KEY* aesN = NULL; + size_t len = 0; + size_t lenB = 0; + int keySz0 = 0; + int keySzN = -1; + byte out[AES_BLOCK_SIZE] = {0}; + byte* outN = NULL; + + /* Test vectors retrieved from: + * + * https://csrc.nist.gov/ + * CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/ + * documents/aes/KAT_AES.zip + * + */ + const byte* pt128N = NULL; + byte* key128N = NULL; + byte* iv128N = NULL; + byte iv128tmp[AES_BLOCK_SIZE] = {0}; + + const byte pt128[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; + + const byte ct128[] = { 0x87,0x85,0xb1,0xa7,0x5b,0x0f,0x3b,0xd9, + 0x58,0xdc,0xd0,0xe2,0x93,0x18,0xc5,0x21 }; + + const byte iv128[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; + + byte key128[] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00 }; + + + len = sizeof(pt128); + + #define STRESS_T(a, b, c, d, e, f, g, h, i) \ + wolfSSL_AES_cbc_encrypt(a, b, c, d, e, f); \ + ExpectIntNE(XMEMCMP(b, g, h), i) + + #define RESET_IV(x, y) XMEMCPY(x, y, AES_BLOCK_SIZE) + + /* Stressing wolfSSL_AES_cbc_encrypt() */ + STRESS_T(pt128N, out, len, &aes, iv128tmp, 1, ct128, AES_BLOCK_SIZE, 0); + STRESS_T(pt128, out, len, &aes, iv128N, 1, ct128, AES_BLOCK_SIZE, 0); + + wolfSSL_AES_cbc_encrypt(pt128, outN, len, &aes, iv128tmp, AES_ENCRYPT); + ExpectIntNE(XMEMCMP(out, ct128, AES_BLOCK_SIZE), 0); + wolfSSL_AES_cbc_encrypt(pt128, out, len, aesN, iv128tmp, AES_ENCRYPT); + ExpectIntNE(XMEMCMP(out, ct128, AES_BLOCK_SIZE), 0); + + STRESS_T(pt128, out, lenB, &aes, iv128tmp, 1, ct128, AES_BLOCK_SIZE, 0); + + /* Stressing wolfSSL_AES_set_encrypt_key */ + ExpectIntNE(wolfSSL_AES_set_encrypt_key(key128N, sizeof(key128)*8, &aes),0); + ExpectIntNE(wolfSSL_AES_set_encrypt_key(key128, sizeof(key128)*8, aesN),0); + ExpectIntNE(wolfSSL_AES_set_encrypt_key(key128, keySz0, &aes), 0); + ExpectIntNE(wolfSSL_AES_set_encrypt_key(key128, keySzN, &aes), 0); + + /* Stressing wolfSSL_AES_set_decrypt_key */ + ExpectIntNE(wolfSSL_AES_set_decrypt_key(key128N, sizeof(key128)*8, &aes),0); + ExpectIntNE(wolfSSL_AES_set_decrypt_key(key128N, sizeof(key128)*8, aesN),0); + ExpectIntNE(wolfSSL_AES_set_decrypt_key(key128, keySz0, &aes), 0); + ExpectIntNE(wolfSSL_AES_set_decrypt_key(key128, keySzN, &aes), 0); + + #ifdef WOLFSSL_AES_128 + + /* wolfSSL_AES_cbc_encrypt() 128-bit */ + XMEMSET(out, 0, AES_BLOCK_SIZE); + RESET_IV(iv128tmp, iv128); + + ExpectIntEQ(wolfSSL_AES_set_encrypt_key(key128, sizeof(key128)*8, &aes), 0); + wolfSSL_AES_cbc_encrypt(pt128, out, len, &aes, iv128tmp, AES_ENCRYPT); + ExpectIntEQ(XMEMCMP(out, ct128, AES_BLOCK_SIZE), 0); + wc_AesFree((Aes*)&aes); + + #ifdef HAVE_AES_DECRYPT + + /* wolfSSL_AES_cbc_encrypt() 128-bit in decrypt mode */ + XMEMSET(out, 0, AES_BLOCK_SIZE); + RESET_IV(iv128tmp, iv128); + len = sizeof(ct128); + + ExpectIntEQ(wolfSSL_AES_set_decrypt_key(key128, sizeof(key128)*8, &aes), 0); + wolfSSL_AES_cbc_encrypt(ct128, out, len, &aes, iv128tmp, AES_DECRYPT); + ExpectIntEQ(XMEMCMP(out, pt128, AES_BLOCK_SIZE), 0); + wc_AesFree((Aes*)&aes); + + #endif + + #endif /* WOLFSSL_AES_128 */ + #ifdef WOLFSSL_AES_192 + { + /* Test vectors from NIST Special Publication 800-38A, 2001 Edition + * Appendix F.2.3 */ + + byte iv192tmp[AES_BLOCK_SIZE] = {0}; + + const byte pt192[] = { 0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96, + 0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a }; + + const byte ct192[] = { 0x4f,0x02,0x1d,0xb2,0x43,0xbc,0x63,0x3d, + 0x71,0x78,0x18,0x3a,0x9f,0xa0,0x71,0xe8 }; + + const byte iv192[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F }; + + byte key192[] = { 0x8e,0x73,0xb0,0xf7,0xda,0x0e,0x64,0x52, + 0xc8,0x10,0xf3,0x2b,0x80,0x90,0x79,0xe5, + 0x62,0xf8,0xea,0xd2,0x52,0x2c,0x6b,0x7b }; + + len = sizeof(pt192); + + /* wolfSSL_AES_cbc_encrypt() 192-bit */ + XMEMSET(out, 0, AES_BLOCK_SIZE); + RESET_IV(iv192tmp, iv192); + + ExpectIntEQ(wolfSSL_AES_set_encrypt_key(key192, sizeof(key192)*8, &aes), 0); + wolfSSL_AES_cbc_encrypt(pt192, out, len, &aes, iv192tmp, AES_ENCRYPT); + ExpectIntEQ(XMEMCMP(out, ct192, AES_BLOCK_SIZE), 0); + wc_AesFree((Aes*)&aes); + + #ifdef HAVE_AES_DECRYPT + + /* wolfSSL_AES_cbc_encrypt() 192-bit in decrypt mode */ + len = sizeof(ct192); + RESET_IV(iv192tmp, iv192); + XMEMSET(out, 0, AES_BLOCK_SIZE); + + ExpectIntEQ(wolfSSL_AES_set_decrypt_key(key192, sizeof(key192)*8, &aes), 0); + wolfSSL_AES_cbc_encrypt(ct192, out, len, &aes, iv192tmp, AES_DECRYPT); + ExpectIntEQ(XMEMCMP(out, pt192, AES_BLOCK_SIZE), 0); + wc_AesFree((Aes*)&aes); + + #endif + } + #endif /* WOLFSSL_AES_192 */ + #ifdef WOLFSSL_AES_256 + { + /* Test vectors from NIST Special Publication 800-38A, 2001 Edition, + * Appendix F.2.5 */ + byte iv256tmp[AES_BLOCK_SIZE] = {0}; + + const byte pt256[] = { 0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96, + 0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a }; + + const byte ct256[] = { 0xf5,0x8c,0x4c,0x04,0xd6,0xe5,0xf1,0xba, + 0x77,0x9e,0xab,0xfb,0x5f,0x7b,0xfb,0xd6 }; + + const byte iv256[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F }; + + byte key256[] = { 0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe, + 0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81, + 0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7, + 0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4 }; + + + len = sizeof(pt256); + + /* wolfSSL_AES_cbc_encrypt() 256-bit */ + XMEMSET(out, 0, AES_BLOCK_SIZE); + RESET_IV(iv256tmp, iv256); + + ExpectIntEQ(wolfSSL_AES_set_encrypt_key(key256, sizeof(key256)*8, &aes), 0); + wolfSSL_AES_cbc_encrypt(pt256, out, len, &aes, iv256tmp, AES_ENCRYPT); + ExpectIntEQ(XMEMCMP(out, ct256, AES_BLOCK_SIZE), 0); + wc_AesFree((Aes*)&aes); + + #ifdef HAVE_AES_DECRYPT + + /* wolfSSL_AES_cbc_encrypt() 256-bit in decrypt mode */ + len = sizeof(ct256); + RESET_IV(iv256tmp, iv256); + XMEMSET(out, 0, AES_BLOCK_SIZE); + + ExpectIntEQ(wolfSSL_AES_set_decrypt_key(key256, sizeof(key256)*8, &aes), 0); + wolfSSL_AES_cbc_encrypt(ct256, out, len, &aes, iv256tmp, AES_DECRYPT); + ExpectIntEQ(XMEMCMP(out, pt256, AES_BLOCK_SIZE), 0); + wc_AesFree((Aes*)&aes); + + #endif + + #if defined(HAVE_AES_KEYWRAP) && !defined(HAVE_FIPS) && \ + !defined(HAVE_SELFTEST) + { + byte wrapCipher[sizeof(key256) + KEYWRAP_BLOCK_SIZE] = { 0 }; + byte wrapPlain[sizeof(key256)] = { 0 }; + byte wrapIV[KEYWRAP_BLOCK_SIZE] = { 0 }; + + /* wolfSSL_AES_wrap_key() 256-bit NULL iv */ + ExpectIntEQ(wolfSSL_AES_set_encrypt_key(key256, sizeof(key256)*8, &aes), 0); + ExpectIntEQ(wolfSSL_AES_wrap_key(&aes, NULL, wrapCipher, key256, + 15), WOLFSSL_FAILURE); + ExpectIntEQ(wolfSSL_AES_wrap_key(&aes, NULL, wrapCipher, key256, + sizeof(key256)), sizeof(wrapCipher)); + wc_AesFree((Aes*)&aes); + + /* wolfSSL_AES_unwrap_key() 256-bit NULL iv */ + ExpectIntEQ(wolfSSL_AES_set_decrypt_key(key256, sizeof(key256)*8, &aes), 0); + ExpectIntEQ(wolfSSL_AES_unwrap_key(&aes, NULL, wrapPlain, wrapCipher, + 23), WOLFSSL_FAILURE); + ExpectIntEQ(wolfSSL_AES_unwrap_key(&aes, NULL, wrapPlain, wrapCipher, + sizeof(wrapCipher)), sizeof(wrapPlain)); + ExpectIntEQ(XMEMCMP(wrapPlain, key256, sizeof(key256)), 0); + XMEMSET(wrapCipher, 0, sizeof(wrapCipher)); + XMEMSET(wrapPlain, 0, sizeof(wrapPlain)); + wc_AesFree((Aes*)&aes); + + /* wolfSSL_AES_wrap_key() 256-bit custom iv */ + ExpectIntEQ(wolfSSL_AES_set_encrypt_key(key256, sizeof(key256)*8, &aes), 0); + ExpectIntEQ(wolfSSL_AES_wrap_key(&aes, wrapIV, wrapCipher, key256, + sizeof(key256)), sizeof(wrapCipher)); + wc_AesFree((Aes*)&aes); + + /* wolfSSL_AES_unwrap_key() 256-bit custom iv */ + ExpectIntEQ(wolfSSL_AES_set_decrypt_key(key256, sizeof(key256)*8, &aes), 0); + ExpectIntEQ(wolfSSL_AES_unwrap_key(&aes, wrapIV, wrapPlain, wrapCipher, + sizeof(wrapCipher)), sizeof(wrapPlain)); + ExpectIntEQ(XMEMCMP(wrapPlain, key256, sizeof(key256)), 0); + wc_AesFree((Aes*)&aes); + + ExpectIntEQ(wolfSSL_AES_wrap_key(NULL, NULL, NULL, NULL, 0), 0); + ExpectIntEQ(wolfSSL_AES_wrap_key(&aes, NULL, NULL, NULL, 0), 0); + ExpectIntEQ(wolfSSL_AES_wrap_key(NULL, wrapIV, NULL, NULL, 0), 0); + ExpectIntEQ(wolfSSL_AES_wrap_key(NULL, NULL, wrapCipher, NULL, 0), 0); + ExpectIntEQ(wolfSSL_AES_wrap_key(NULL, NULL, NULL, key256, 0), 0); + ExpectIntEQ(wolfSSL_AES_wrap_key(NULL, wrapIV, wrapCipher, key256, 0), 0); + ExpectIntEQ(wolfSSL_AES_wrap_key(&aes, NULL, wrapCipher, key256, 0), 0); + ExpectIntEQ(wolfSSL_AES_wrap_key(&aes, wrapIV, NULL, key256, 0), 0); + ExpectIntEQ(wolfSSL_AES_wrap_key(&aes, wrapIV, wrapCipher, NULL, 0), 0); + + ExpectIntEQ(wolfSSL_AES_unwrap_key(NULL, NULL, NULL, NULL, 0), 0); + ExpectIntEQ(wolfSSL_AES_unwrap_key(&aes, NULL, NULL, NULL, 0), 0); + ExpectIntEQ(wolfSSL_AES_unwrap_key(NULL, wrapIV, NULL, NULL, 0), 0); + ExpectIntEQ(wolfSSL_AES_unwrap_key(NULL, NULL, wrapPlain, NULL, 0), 0); + ExpectIntEQ(wolfSSL_AES_unwrap_key(NULL, NULL, NULL, wrapCipher, 0), 0); + ExpectIntEQ(wolfSSL_AES_unwrap_key(NULL, wrapIV, wrapPlain, wrapCipher, 0), + 0); + ExpectIntEQ(wolfSSL_AES_unwrap_key(&aes, NULL, wrapPlain, wrapCipher, 0), + 0); + ExpectIntEQ(wolfSSL_AES_unwrap_key(&aes, wrapIV, NULL, wrapCipher, 0), 0); + ExpectIntEQ(wolfSSL_AES_wrap_key(&aes, wrapIV, wrapPlain, NULL, 0), 0); + } + #endif /* HAVE_AES_KEYWRAP */ + } + #endif /* WOLFSSL_AES_256 */ +#endif + return EXPECT_RESULT(); +} + +static int test_wolfSSL_AES_cfb128_encrypt(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && !defined(NO_AES) && defined(WOLFSSL_AES_CFB) + AES_KEY aesEnc; + AES_KEY aesDec; + const byte msg[] = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a + }; + const byte exp[] = { + 0x16, 0xc9, 0x90, 0x6c, 0x04, 0x0c, 0xd1, 0x2f, + 0x84, 0x7b, 0x18, 0xed, 0xed, 0x6a, 0xb5, 0xfd + }; + const byte key[] = { + 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, + 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, + 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, + 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4 + }; + const byte ivData[] = { + 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, + 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, + }; + byte out[AES_BLOCK_SIZE]; + byte iv[AES_BLOCK_SIZE]; + word32 i; + int num; + + ExpectIntEQ(AES_set_encrypt_key(key, sizeof(key)*8, &aesEnc), 0); + XMEMCPY(iv, ivData, sizeof(iv)); + XMEMSET(out, 0, AES_BLOCK_SIZE); + AES_cfb128_encrypt(msg, out, sizeof(msg), &aesEnc, iv, NULL, AES_ENCRYPT); + ExpectIntEQ(XMEMCMP(out, exp, sizeof(msg)), 0); + ExpectIntNE(XMEMCMP(iv, ivData, sizeof(iv)), 0); + +#ifdef HAVE_AES_DECRYPT + ExpectIntEQ(AES_set_encrypt_key(key, sizeof(key)*8, &aesDec), 0); + XMEMCPY(iv, ivData, sizeof(iv)); + XMEMSET(out, 0, AES_BLOCK_SIZE); + AES_cfb128_encrypt(exp, out, sizeof(msg), &aesDec, iv, NULL, AES_DECRYPT); + ExpectIntEQ(XMEMCMP(out, msg, sizeof(msg)), 0); + ExpectIntNE(XMEMCMP(iv, ivData, sizeof(iv)), 0); +#endif + + for (i = 0; EXPECT_SUCCESS() && (i <= sizeof(msg)); i++) { + ExpectIntEQ(AES_set_encrypt_key(key, sizeof(key)*8, &aesEnc), 0); + XMEMCPY(iv, ivData, sizeof(iv)); + XMEMSET(out, 0, AES_BLOCK_SIZE); + AES_cfb128_encrypt(msg, out, i, &aesEnc, iv, &num, AES_ENCRYPT); + ExpectIntEQ(num, i % AES_BLOCK_SIZE); + ExpectIntEQ(XMEMCMP(out, exp, i), 0); + if (i == 0) { + ExpectIntEQ(XMEMCMP(iv, ivData, sizeof(iv)), 0); + } + else { + ExpectIntNE(XMEMCMP(iv, ivData, sizeof(iv)), 0); + } + + #ifdef HAVE_AES_DECRYPT + ExpectIntEQ(AES_set_encrypt_key(key, sizeof(key)*8, &aesDec), 0); + XMEMCPY(iv, ivData, sizeof(iv)); + XMEMSET(out, 0, AES_BLOCK_SIZE); + AES_cfb128_encrypt(exp, out, i, &aesDec, iv, &num, AES_DECRYPT); + ExpectIntEQ(num, i % AES_BLOCK_SIZE); + ExpectIntEQ(XMEMCMP(out, msg, i), 0); + if (i == 0) { + ExpectIntEQ(XMEMCMP(iv, ivData, sizeof(iv)), 0); + } + else { + ExpectIntNE(XMEMCMP(iv, ivData, sizeof(iv)), 0); + } + #endif + } + + if (EXPECT_SUCCESS()) { + /* test bad arguments */ + AES_cfb128_encrypt(NULL, NULL, 0, NULL, NULL, NULL, AES_DECRYPT); + AES_cfb128_encrypt(msg, NULL, 0, NULL, NULL, NULL, AES_DECRYPT); + AES_cfb128_encrypt(NULL, out, 0, NULL, NULL, NULL, AES_DECRYPT); + AES_cfb128_encrypt(NULL, NULL, 0, &aesDec, NULL, NULL, AES_DECRYPT); + AES_cfb128_encrypt(NULL, NULL, 0, NULL, iv, NULL, AES_DECRYPT); + AES_cfb128_encrypt(NULL, out, 0, &aesDec, iv, NULL, AES_DECRYPT); + AES_cfb128_encrypt(msg, NULL, 0, &aesDec, iv, NULL, AES_DECRYPT); + AES_cfb128_encrypt(msg, out, 0, NULL, iv, NULL, AES_DECRYPT); + AES_cfb128_encrypt(msg, out, 0, &aesDec, NULL, NULL, AES_DECRYPT); + } +#endif + return EXPECT_RESULT(); +} + +static int test_wolfSSL_CRYPTO_cts128(void) +{ + EXPECT_DECLS; +#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(OPENSSL_EXTRA) && \ + defined(HAVE_CTS) + byte tmp[64]; /* Largest vector size */ + /* Test vectors taken form RFC3962 Appendix B */ + const testVector vects[] = { + { + "\x49\x20\x77\x6f\x75\x6c\x64\x20\x6c\x69\x6b\x65\x20\x74\x68\x65" + "\x20", + "\xc6\x35\x35\x68\xf2\xbf\x8c\xb4\xd8\xa5\x80\x36\x2d\xa7\xff\x7f" + "\x97", + 17, 17 + }, + { + "\x49\x20\x77\x6f\x75\x6c\x64\x20\x6c\x69\x6b\x65\x20\x74\x68\x65" + "\x20\x47\x65\x6e\x65\x72\x61\x6c\x20\x47\x61\x75\x27\x73\x20", + "\xfc\x00\x78\x3e\x0e\xfd\xb2\xc1\xd4\x45\xd4\xc8\xef\xf7\xed\x22" + "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5", + 31, 31 + }, + { + "\x49\x20\x77\x6f\x75\x6c\x64\x20\x6c\x69\x6b\x65\x20\x74\x68\x65" + "\x20\x47\x65\x6e\x65\x72\x61\x6c\x20\x47\x61\x75\x27\x73\x20\x43", + "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8" + "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84", + 32, 32 + }, + { + "\x49\x20\x77\x6f\x75\x6c\x64\x20\x6c\x69\x6b\x65\x20\x74\x68\x65" + "\x20\x47\x65\x6e\x65\x72\x61\x6c\x20\x47\x61\x75\x27\x73\x20\x43" + "\x68\x69\x63\x6b\x65\x6e\x2c\x20\x70\x6c\x65\x61\x73\x65\x2c", + "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84" + "\xb3\xff\xfd\x94\x0c\x16\xa1\x8c\x1b\x55\x49\xd2\xf8\x38\x02\x9e" + "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5", + 47, 47 + }, + { + "\x49\x20\x77\x6f\x75\x6c\x64\x20\x6c\x69\x6b\x65\x20\x74\x68\x65" + "\x20\x47\x65\x6e\x65\x72\x61\x6c\x20\x47\x61\x75\x27\x73\x20\x43" + "\x68\x69\x63\x6b\x65\x6e\x2c\x20\x70\x6c\x65\x61\x73\x65\x2c\x20", + "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84" + "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8" + "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8", + 48, 48 + }, + { + "\x49\x20\x77\x6f\x75\x6c\x64\x20\x6c\x69\x6b\x65\x20\x74\x68\x65" + "\x20\x47\x65\x6e\x65\x72\x61\x6c\x20\x47\x61\x75\x27\x73\x20\x43" + "\x68\x69\x63\x6b\x65\x6e\x2c\x20\x70\x6c\x65\x61\x73\x65\x2c\x20" + "\x61\x6e\x64\x20\x77\x6f\x6e\x74\x6f\x6e\x20\x73\x6f\x75\x70\x2e", + "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84" + "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8" + "\x48\x07\xef\xe8\x36\xee\x89\xa5\x26\x73\x0d\xbc\x2f\x7b\xc8\x40" + "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8", + 64, 64 + } + }; + byte keyBytes[AES_128_KEY_SIZE] = { + 0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20, + 0x74, 0x65, 0x72, 0x69, 0x79, 0x61, 0x6b, 0x69 + }; + size_t i; + AES_KEY encKey; + byte iv[AES_IV_SIZE]; /* All-zero IV for all cases */ + + XMEMSET(tmp, 0, sizeof(tmp)); + + for (i = 0; i < sizeof(vects)/sizeof(vects[0]); i++) { + AES_KEY decKey; + + ExpectIntEQ(AES_set_encrypt_key(keyBytes, AES_128_KEY_SIZE * 8, + &encKey), 0); + ExpectIntEQ(AES_set_decrypt_key(keyBytes, AES_128_KEY_SIZE * 8, + &decKey), 0); + XMEMSET(iv, 0, sizeof(iv)); + ExpectIntEQ(CRYPTO_cts128_encrypt((const unsigned char*)vects[i].input, + tmp, vects[i].inLen, &encKey, iv, (cbc128_f)AES_cbc_encrypt), + vects[i].outLen); + ExpectIntEQ(XMEMCMP(tmp, vects[i].output, vects[i].outLen), 0); + XMEMSET(iv, 0, sizeof(iv)); + ExpectIntEQ(CRYPTO_cts128_decrypt((const unsigned char*)vects[i].output, + tmp, vects[i].outLen, &decKey, iv, (cbc128_f)AES_cbc_encrypt), + vects[i].inLen); + ExpectIntEQ(XMEMCMP(tmp, vects[i].input, vects[i].inLen), 0); + } + + ExpectIntEQ(CRYPTO_cts128_encrypt(NULL, NULL, 17, NULL, NULL, NULL), 0); + ExpectIntEQ(CRYPTO_cts128_encrypt(tmp, NULL, 17, NULL, NULL, NULL), 0); + ExpectIntEQ(CRYPTO_cts128_encrypt(NULL, tmp, 17, NULL, NULL, NULL), 0); + ExpectIntEQ(CRYPTO_cts128_encrypt(NULL, NULL, 17, &encKey, NULL, NULL), 0); + ExpectIntEQ(CRYPTO_cts128_encrypt(NULL, NULL, 17, NULL, iv, NULL), 0); + ExpectIntEQ(CRYPTO_cts128_encrypt(NULL, NULL, 17, NULL, NULL, + (cbc128_f)AES_cbc_encrypt), 0); + ExpectIntEQ(CRYPTO_cts128_encrypt(NULL, tmp, 17, &encKey, iv, + (cbc128_f)AES_cbc_encrypt), 0); + ExpectIntEQ(CRYPTO_cts128_encrypt(tmp, NULL, 17, &encKey, iv, + (cbc128_f)AES_cbc_encrypt), 0); + ExpectIntEQ(CRYPTO_cts128_encrypt(tmp, tmp, 17, NULL, iv, + (cbc128_f)AES_cbc_encrypt), 0); + ExpectIntEQ(CRYPTO_cts128_encrypt(tmp, tmp, 17, &encKey, NULL, + (cbc128_f)AES_cbc_encrypt), 0); + ExpectIntEQ(CRYPTO_cts128_encrypt(tmp, tmp, 17, &encKey, iv, NULL), 0); + /* Length too small. */ + ExpectIntEQ(CRYPTO_cts128_encrypt(tmp, tmp, 0, &encKey, iv, + (cbc128_f)AES_cbc_encrypt), 0); + + ExpectIntEQ(CRYPTO_cts128_decrypt(NULL, NULL, 17, NULL, NULL, NULL), 0); + ExpectIntEQ(CRYPTO_cts128_decrypt(tmp, NULL, 17, NULL, NULL, NULL), 0); + ExpectIntEQ(CRYPTO_cts128_decrypt(NULL, tmp, 17, NULL, NULL, NULL), 0); + ExpectIntEQ(CRYPTO_cts128_decrypt(NULL, NULL, 17, &encKey, NULL, NULL), 0); + ExpectIntEQ(CRYPTO_cts128_decrypt(NULL, NULL, 17, NULL, iv, NULL), 0); + ExpectIntEQ(CRYPTO_cts128_decrypt(NULL, NULL, 17, NULL, NULL, + (cbc128_f)AES_cbc_encrypt), 0); + ExpectIntEQ(CRYPTO_cts128_decrypt(NULL, tmp, 17, &encKey, iv, + (cbc128_f)AES_cbc_encrypt), 0); + ExpectIntEQ(CRYPTO_cts128_decrypt(tmp, NULL, 17, &encKey, iv, + (cbc128_f)AES_cbc_encrypt), 0); + ExpectIntEQ(CRYPTO_cts128_decrypt(tmp, tmp, 17, NULL, iv, + (cbc128_f)AES_cbc_encrypt), 0); + ExpectIntEQ(CRYPTO_cts128_decrypt(tmp, tmp, 17, &encKey, NULL, + (cbc128_f)AES_cbc_encrypt), 0); + ExpectIntEQ(CRYPTO_cts128_decrypt(tmp, tmp, 17, &encKey, iv, NULL), 0); + /* Length too small. */ + ExpectIntEQ(CRYPTO_cts128_decrypt(tmp, tmp, 0, &encKey, iv, + (cbc128_f)AES_cbc_encrypt), 0); +#endif /* !NO_AES && HAVE_AES_CBC && OPENSSL_EXTRA && HAVE_CTS */ + return EXPECT_RESULT(); +} + +static int test_wolfSSL_RC4(void) +{ + EXPECT_DECLS; +#if !defined(NO_RC4) && defined(OPENSSL_EXTRA) + WOLFSSL_RC4_KEY rc4Key; + unsigned char key[] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + }; + unsigned char data[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + }; + unsigned char enc[sizeof(data)]; + unsigned char dec[sizeof(data)]; + word32 i; + word32 j; + + wolfSSL_RC4_set_key(NULL, -1, NULL); + wolfSSL_RC4_set_key(&rc4Key, -1, NULL); + wolfSSL_RC4_set_key(NULL, 0, NULL); + wolfSSL_RC4_set_key(NULL, -1, key); + wolfSSL_RC4_set_key(&rc4Key, 0, NULL); + wolfSSL_RC4_set_key(&rc4Key, -1, key); + wolfSSL_RC4_set_key(NULL, 0, key); + + wolfSSL_RC4(NULL, 0, NULL, NULL); + wolfSSL_RC4(&rc4Key, 0, NULL, NULL); + wolfSSL_RC4(NULL, 0, data, NULL); + wolfSSL_RC4(NULL, 0, NULL, enc); + wolfSSL_RC4(&rc4Key, 0, data, NULL); + wolfSSL_RC4(&rc4Key, 0, NULL, enc); + wolfSSL_RC4(NULL, 0, data, enc); + + ExpectIntEQ(1, 1); + for (i = 0; EXPECT_SUCCESS() && (i <= sizeof(key)); i++) { + for (j = 0; EXPECT_SUCCESS() && (j <= sizeof(data)); j++) { + XMEMSET(enc, 0, sizeof(enc)); + XMEMSET(dec, 0, sizeof(dec)); + + /* Encrypt */ + wolfSSL_RC4_set_key(&rc4Key, i, key); + wolfSSL_RC4(&rc4Key, j, data, enc); + /* Decrypt */ + wolfSSL_RC4_set_key(&rc4Key, i, key); + wolfSSL_RC4(&rc4Key, j, enc, dec); + + ExpectIntEQ(XMEMCMP(dec, data, j), 0); + } + } +#endif + return EXPECT_RESULT(); +} static int test_wolfSSL_OBJ(void) { @@ -44080,27 +45961,6 @@ static int test_wolfSSL_sk_DIST_POINT(void) return EXPECT_RESULT(); } -static int test_wolfSSL_MD4(void) -{ - EXPECT_DECLS; -#if defined(OPENSSL_EXTRA) && !defined(NO_MD4) - MD4_CTX md4; - unsigned char out[16]; /* MD4_DIGEST_SIZE */ - const char* msg = "12345678901234567890123456789012345678901234567890123456" - "789012345678901234567890"; - const char* test = "\xe3\x3b\x4d\xdc\x9c\x38\xf2\x19\x9c\x3e\x7b\x16\x4f" - "\xcc\x05\x36"; - int msgSz = (int)XSTRLEN(msg); - - - XMEMSET(out, 0, sizeof(out)); - MD4_Init(&md4); - MD4_Update(&md4, (const void*)msg, (unsigned long)msgSz); - MD4_Final(out, &md4); - ExpectIntEQ(XMEMCMP(out, test, sizeof(out)), 0); -#endif - return EXPECT_RESULT(); -} static int test_wolfSSL_verify_mode(void) @@ -44218,188 +46078,6 @@ static int test_wolfSSL_verify_result(void) return EXPECT_RESULT(); } -#if defined(OPENSSL_EXTRA) && !defined(NO_HMAC) -/* helper function for test_wolfSSL_HMAC_CTX, digest size is expected to be a - * buffer of 64 bytes. - * - * returns the size of the digest buffer on success and a negative value on - * failure. - */ -static int test_HMAC_CTX_helper(const EVP_MD* type, unsigned char* digest, - int* sz) -{ - EXPECT_DECLS; - HMAC_CTX ctx1; - HMAC_CTX ctx2; - - unsigned char key[] = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" - "\x0b\x0b\x0b\x0b\x0b\x0b\x0b"; - unsigned char long_key[] = - "0123456789012345678901234567890123456789" - "0123456789012345678901234567890123456789" - "0123456789012345678901234567890123456789" - "0123456789012345678901234567890123456789"; - - unsigned char msg[] = "message to hash"; - unsigned int digestSz = 64; - int keySz = sizeof(key); - int long_keySz = sizeof(long_key); - int msgSz = sizeof(msg); - - unsigned char digest2[64]; - unsigned int digestSz2 = 64; - - HMAC_CTX_init(&ctx1); - - ExpectIntEQ(HMAC_Init(&ctx1, (const void*)key, keySz, type), SSL_SUCCESS); - ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS); - ExpectIntEQ(HMAC_CTX_copy(&ctx2, &ctx1), SSL_SUCCESS); - - ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS); - ExpectIntEQ(HMAC_Final(&ctx1, digest, &digestSz), SSL_SUCCESS); - HMAC_CTX_cleanup(&ctx1); - - ExpectIntEQ(HMAC_Update(&ctx2, msg, msgSz), SSL_SUCCESS); - ExpectIntEQ(HMAC_Final(&ctx2, digest2, &digestSz2), SSL_SUCCESS); - HMAC_CTX_cleanup(&ctx2); - - ExpectIntEQ(digestSz, digestSz2); - ExpectIntEQ(XMEMCMP(digest, digest2, digestSz), 0); - - /* test HMAC_Init with NULL key */ - - /* init after copy */ - HMAC_CTX_init(&ctx1); - ExpectIntEQ(HMAC_Init(&ctx1, (const void*)key, keySz, type), SSL_SUCCESS); - ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS); - ExpectIntEQ(HMAC_CTX_copy(&ctx2, &ctx1), SSL_SUCCESS); - - ExpectIntEQ(HMAC_Init(&ctx1, NULL, 0, NULL), SSL_SUCCESS); - ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS); - ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS); - ExpectIntEQ(HMAC_Final(&ctx1, digest, &digestSz), SSL_SUCCESS); - HMAC_CTX_cleanup(&ctx1); - - ExpectIntEQ(HMAC_Init(&ctx2, NULL, 0, NULL), SSL_SUCCESS); - ExpectIntEQ(HMAC_Update(&ctx2, msg, msgSz), SSL_SUCCESS); - ExpectIntEQ(HMAC_Update(&ctx2, msg, msgSz), SSL_SUCCESS); - ExpectIntEQ(HMAC_Final(&ctx2, digest2, &digestSz), SSL_SUCCESS); - HMAC_CTX_cleanup(&ctx2); - - ExpectIntEQ(digestSz, digestSz2); - ExpectIntEQ(XMEMCMP(digest, digest2, digestSz), 0); - - /* long key */ - HMAC_CTX_init(&ctx1); - ExpectIntEQ(HMAC_Init(&ctx1, (const void*)long_key, long_keySz, type), SSL_SUCCESS); - ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS); - ExpectIntEQ(HMAC_CTX_copy(&ctx2, &ctx1), SSL_SUCCESS); - - ExpectIntEQ(HMAC_Init(&ctx1, NULL, 0, NULL), SSL_SUCCESS); - ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS); - ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS); - ExpectIntEQ(HMAC_Final(&ctx1, digest, &digestSz), SSL_SUCCESS); - HMAC_CTX_cleanup(&ctx1); - - ExpectIntEQ(HMAC_Init(&ctx2, NULL, 0, NULL), SSL_SUCCESS); - ExpectIntEQ(HMAC_Update(&ctx2, msg, msgSz), SSL_SUCCESS); - ExpectIntEQ(HMAC_Update(&ctx2, msg, msgSz), SSL_SUCCESS); - ExpectIntEQ(HMAC_Final(&ctx2, digest2, &digestSz), SSL_SUCCESS); - HMAC_CTX_cleanup(&ctx2); - - ExpectIntEQ(digestSz, digestSz2); - ExpectIntEQ(XMEMCMP(digest, digest2, digestSz), 0); - - /* init before copy */ - HMAC_CTX_init(&ctx1); - ExpectIntEQ(HMAC_Init(&ctx1, (const void*)key, keySz, type), SSL_SUCCESS); - ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS); - ExpectIntEQ(HMAC_Init(&ctx1, NULL, 0, NULL), SSL_SUCCESS); - ExpectIntEQ(HMAC_CTX_copy(&ctx2, &ctx1), SSL_SUCCESS); - - ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS); - ExpectIntEQ(HMAC_Update(&ctx1, msg, msgSz), SSL_SUCCESS); - ExpectIntEQ(HMAC_Final(&ctx1, digest, &digestSz), SSL_SUCCESS); - HMAC_CTX_cleanup(&ctx1); - - ExpectIntEQ(HMAC_Update(&ctx2, msg, msgSz), SSL_SUCCESS); - ExpectIntEQ(HMAC_Update(&ctx2, msg, msgSz), SSL_SUCCESS); - ExpectIntEQ(HMAC_Final(&ctx2, digest2, &digestSz), SSL_SUCCESS); - HMAC_CTX_cleanup(&ctx2); - - ExpectIntEQ(digestSz, digestSz2); - ExpectIntEQ(XMEMCMP(digest, digest2, digestSz), 0); - - *sz = digestSz; - return EXPECT_RESULT(); -} -#endif /* defined(OPENSSL_EXTRA) && !defined(NO_HMAC) */ - -static int test_wolfSSL_HMAC_CTX(void) -{ - EXPECT_DECLS; -#if defined(OPENSSL_EXTRA) && !defined(NO_HMAC) - unsigned char digest[64]; - int digestSz; - - #ifndef NO_SHA - ExpectIntEQ((test_HMAC_CTX_helper(EVP_sha1(), digest, &digestSz)), - TEST_SUCCESS); - ExpectIntEQ(digestSz, 20); - ExpectIntEQ(XMEMCMP("\xD9\x68\x77\x23\x70\xFB\x53\x70\x53\xBA\x0E\xDC\xDA" - "\xBF\x03\x98\x31\x19\xB2\xCC", digest, digestSz), 0); - #endif /* !NO_SHA */ - #ifdef WOLFSSL_SHA224 - ExpectIntEQ((test_HMAC_CTX_helper(EVP_sha224(), digest, &digestSz)), - TEST_SUCCESS); - ExpectIntEQ(digestSz, 28); - ExpectIntEQ(XMEMCMP("\x57\xFD\xF4\xE1\x2D\xB0\x79\xD7\x4B\x25\x7E\xB1\x95" - "\x9C\x11\xAC\x2D\x1E\x78\x94\x4F\x3A\x0F\xED\xF8\xAD" - "\x02\x0E", digest, digestSz), 0); - #endif /* WOLFSSL_SHA224 */ - #ifndef NO_SHA256 - ExpectIntEQ((test_HMAC_CTX_helper(EVP_sha256(), digest, &digestSz)), - TEST_SUCCESS); - ExpectIntEQ(digestSz, 32); - ExpectIntEQ(XMEMCMP("\x13\xAB\x76\x91\x0C\x37\x86\x8D\xB3\x7E\x30\x0C\xFC" - "\xB0\x2E\x8E\x4A\xD7\xD4\x25\xCC\x3A\xA9\x0F\xA2\xF2" - "\x47\x1E\x62\x6F\x5D\xF2", digest, digestSz), 0); - #endif /* !NO_SHA256 */ - - #ifdef WOLFSSL_SHA384 - ExpectIntEQ((test_HMAC_CTX_helper(EVP_sha384(), digest, &digestSz)), - TEST_SUCCESS); - ExpectIntEQ(digestSz, 48); - ExpectIntEQ(XMEMCMP("\x9E\xCB\x07\x0C\x11\x76\x3F\x23\xC3\x25\x0E\xC4\xB7" - "\x28\x77\x95\x99\xD5\x9D\x7A\xBB\x1A\x9F\xB7\xFD\x25" - "\xC9\x72\x47\x9F\x8F\x86\x76\xD6\x20\x57\x87\xB7\xE7" - "\xCD\xFB\xC2\xCC\x9F\x2B\xC5\x41\xAB", - digest, digestSz), 0); - #endif /* WOLFSSL_SHA384 */ - #ifdef WOLFSSL_SHA512 - ExpectIntEQ((test_HMAC_CTX_helper(EVP_sha512(), digest, &digestSz)), - TEST_SUCCESS); - ExpectIntEQ(digestSz, 64); - ExpectIntEQ(XMEMCMP("\xD4\x21\x0C\x8B\x60\x6F\xF4\xBF\x07\x2F\x26\xCC\xAD" - "\xBC\x06\x0B\x34\x78\x8B\x4F\xD6\xC0\x42\xF1\x33\x10" - "\x6C\x4F\x1E\x55\x59\xDD\x2A\x9F\x15\x88\x62\xF8\x60" - "\xA3\x99\x91\xE2\x08\x7B\xF7\x95\x3A\xB0\x92\x48\x60" - "\x88\x8B\x5B\xB8\x5F\xE9\xB6\xB1\x96\xE3\xB5\xF0", - digest, digestSz), 0); - #endif /* WOLFSSL_SHA512 */ - - #if !defined(NO_MD5) && (!defined(HAVE_FIPS_VERSION) || \ - HAVE_FIPS_VERSION <= 2) - ExpectIntEQ((test_HMAC_CTX_helper(EVP_md5(), digest, &digestSz)), - TEST_SUCCESS); - ExpectIntEQ(digestSz, 16); - ExpectIntEQ(XMEMCMP("\xB7\x27\xC4\x41\xE5\x2E\x62\xBA\x54\xED\x72\x70\x9F" - "\xE4\x98\xDD", digest, digestSz), 0); - #endif /* !NO_MD5 */ -#endif - return EXPECT_RESULT(); -} - #if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(NO_WOLFSSL_CLIENT) static void sslMsgCb(int w, int version, int type, const void* buf, size_t sz, SSL* ssl, void* arg) @@ -44435,101 +46113,6 @@ static int test_wolfSSL_msg_callback(void) return EXPECT_RESULT(); } -static int test_wolfSSL_SHA(void) -{ - EXPECT_DECLS; -#if defined(OPENSSL_EXTRA) && !defined(HAVE_SELFTEST) - #if !defined(NO_SHA) && defined(NO_OLD_SHA_NAMES) && \ - (!defined(HAVE_FIPS) || \ - (defined(HAVE_FIPS_VERSION) && HAVE_FIPS_VERSION > 2)) - { - const unsigned char in[] = "abc"; - unsigned char expected[] = "\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E" - "\x25\x71\x78\x50\xC2\x6C\x9C\xD0\xD8\x9D"; - unsigned char out[WC_SHA_DIGEST_SIZE]; - - XMEMSET(out, 0, WC_SHA_DIGEST_SIZE); - ExpectNotNull(SHA1(in, XSTRLEN((char*)in), out)); - ExpectIntEQ(XMEMCMP(out, expected, WC_SHA_DIGEST_SIZE), 0); - - /* SHA interface test */ - XMEMSET(out, 0, WC_SHA_DIGEST_SIZE); - - ExpectNull(SHA(NULL, XSTRLEN((char*)in), out)); - ExpectNotNull(SHA(in, 0, out)); - ExpectNotNull(SHA(in, XSTRLEN((char*)in), NULL)); - ExpectNotNull(SHA(NULL, 0, out)); - ExpectNotNull(SHA(NULL, 0, NULL)); - - ExpectNotNull(SHA(in, XSTRLEN((char*)in), out)); - ExpectIntEQ(XMEMCMP(out, expected, WC_SHA_DIGEST_SIZE), 0); - } - #endif - - #if !defined(NO_SHA256) - { - const unsigned char in[] = "abc"; - unsigned char expected[] = - "\xBA\x78\x16\xBF\x8F\x01\xCF\xEA\x41\x41\x40\xDE\x5D\xAE\x22" - "\x23\xB0\x03\x61\xA3\x96\x17\x7A\x9C\xB4\x10\xFF\x61\xF2\x00" - "\x15\xAD"; - unsigned char out[WC_SHA256_DIGEST_SIZE]; - - XMEMSET(out, 0, WC_SHA256_DIGEST_SIZE); -#if !defined(NO_OLD_NAMES) && !defined(HAVE_FIPS) - ExpectNotNull(SHA256(in, XSTRLEN((char*)in), out)); -#else - ExpectNotNull(wolfSSL_SHA256(in, XSTRLEN((char*)in), out)); -#endif - ExpectIntEQ(XMEMCMP(out, expected, WC_SHA256_DIGEST_SIZE), 0); - } - #endif - - #if defined(WOLFSSL_SHA384) - { - const unsigned char in[] = "abc"; - unsigned char expected[] = - "\xcb\x00\x75\x3f\x45\xa3\x5e\x8b\xb5\xa0\x3d\x69\x9a\xc6\x50" - "\x07\x27\x2c\x32\xab\x0e\xde\xd1\x63\x1a\x8b\x60\x5a\x43\xff" - "\x5b\xed\x80\x86\x07\x2b\xa1\xe7\xcc\x23\x58\xba\xec\xa1\x34" - "\xc8\x25\xa7"; - unsigned char out[WC_SHA384_DIGEST_SIZE]; - - XMEMSET(out, 0, WC_SHA384_DIGEST_SIZE); -#if !defined(NO_OLD_NAMES) && !defined(HAVE_FIPS) - ExpectNotNull(SHA384(in, XSTRLEN((char*)in), out)); -#else - ExpectNotNull(wolfSSL_SHA384(in, XSTRLEN((char*)in), out)); -#endif - ExpectIntEQ(XMEMCMP(out, expected, WC_SHA384_DIGEST_SIZE), 0); - } - #endif - - #if defined(WOLFSSL_SHA512) - { - const unsigned char in[] = "abc"; - unsigned char expected[] = - "\xdd\xaf\x35\xa1\x93\x61\x7a\xba\xcc\x41\x73\x49\xae\x20\x41" - "\x31\x12\xe6\xfa\x4e\x89\xa9\x7e\xa2\x0a\x9e\xee\xe6\x4b\x55" - "\xd3\x9a\x21\x92\x99\x2a\x27\x4f\xc1\xa8\x36\xba\x3c\x23\xa3" - "\xfe\xeb\xbd\x45\x4d\x44\x23\x64\x3c\xe8\x0e\x2a\x9a\xc9\x4f" - "\xa5\x4c\xa4\x9f"; - unsigned char out[WC_SHA512_DIGEST_SIZE]; - - XMEMSET(out, 0, WC_SHA512_DIGEST_SIZE); -#if !defined(NO_OLD_NAMES) && !defined(HAVE_FIPS) - ExpectNotNull(SHA512(in, XSTRLEN((char*)in), out)); -#else - ExpectNotNull(wolfSSL_SHA512(in, XSTRLEN((char*)in), out)); -#endif - ExpectIntEQ(XMEMCMP(out, expected, WC_SHA512_DIGEST_SIZE), 0); - } - #endif -#endif - return EXPECT_RESULT(); -} - - /* test_EVP_Cipher_extra, Extra-test on EVP_CipherUpdate/Final. see also test.c */ #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)) &&\ (!defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128)) @@ -44829,462 +46412,6 @@ static int test_wolfSSL_PEM_read_DHparams(void) return EXPECT_RESULT(); } -static int test_wolfSSL_AES_ecb_encrypt(void) -{ - EXPECT_DECLS; -#if defined(OPENSSL_EXTRA) && !defined(NO_AES) && defined(HAVE_AES_ECB) - AES_KEY aes; - const byte msg[] = - { - 0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96, - 0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a - }; - - const byte verify[] = - { - 0xf3,0xee,0xd1,0xbd,0xb5,0xd2,0xa0,0x3c, - 0x06,0x4b,0x5a,0x7e,0x3d,0xb1,0x81,0xf8 - }; - - const byte key[] = - { - 0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe, - 0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81, - 0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7, - 0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4 - }; - - - byte out[AES_BLOCK_SIZE]; - - ExpectIntEQ(AES_set_encrypt_key(key, sizeof(key)*8, &aes), 0); - XMEMSET(out, 0, AES_BLOCK_SIZE); - AES_ecb_encrypt(msg, out, &aes, AES_ENCRYPT); - ExpectIntEQ(XMEMCMP(out, verify, AES_BLOCK_SIZE), 0); - -#ifdef HAVE_AES_DECRYPT - ExpectIntEQ(AES_set_decrypt_key(key, sizeof(key)*8, &aes), 0); - XMEMSET(out, 0, AES_BLOCK_SIZE); - AES_ecb_encrypt(verify, out, &aes, AES_DECRYPT); - ExpectIntEQ(XMEMCMP(out, msg, AES_BLOCK_SIZE), 0); -#endif - - /* test bad arguments */ - AES_ecb_encrypt(NULL, out, &aes, AES_DECRYPT); - AES_ecb_encrypt(verify, NULL, &aes, AES_DECRYPT); - AES_ecb_encrypt(verify, out, NULL, AES_DECRYPT); -#endif - return EXPECT_RESULT(); -} - -static int test_wolfSSL_MD5(void) -{ - EXPECT_DECLS; -#if defined(OPENSSL_EXTRA) && !defined(NO_MD5) - byte input1[] = ""; - byte input2[] = "message digest"; - byte hash[WC_MD5_DIGEST_SIZE]; - unsigned char output1[] = - "\xd4\x1d\x8c\xd9\x8f\x00\xb2\x04\xe9\x80\x09\x98\xec\xf8\x42\x7e"; - unsigned char output2[] = - "\xf9\x6b\x69\x7d\x7c\xb7\x93\x8d\x52\x5a\x2f\x31\xaa\xf1\x61\xd0"; - WOLFSSL_MD5_CTX md5; - - XMEMSET(&md5, 0, sizeof(md5)); - - /* Test cases for illegal parameters */ - ExpectIntEQ(MD5_Init(NULL), 0); - ExpectIntEQ(MD5_Init(&md5), 1); - ExpectIntEQ(MD5_Update(NULL, input1, 0), 0); - ExpectIntEQ(MD5_Update(NULL, NULL, 0), 0); - ExpectIntEQ(MD5_Update(&md5, NULL, 1), 0); - ExpectIntEQ(MD5_Final(NULL, &md5), 0); - ExpectIntEQ(MD5_Final(hash, NULL), 0); - ExpectIntEQ(MD5_Final(NULL, NULL), 0); - - /* Init MD5 CTX */ - ExpectIntEQ(wolfSSL_MD5_Init(&md5), 1); - ExpectIntEQ(wolfSSL_MD5_Update(&md5, input1, XSTRLEN((const char*)&input1)), - 1); - ExpectIntEQ(wolfSSL_MD5_Final(hash, &md5), 1); - ExpectIntEQ(XMEMCMP(&hash, output1, WC_MD5_DIGEST_SIZE), 0); - - /* Init MD5 CTX */ - ExpectIntEQ(wolfSSL_MD5_Init(&md5), 1); - ExpectIntEQ(wolfSSL_MD5_Update(&md5, input2, - (int)XSTRLEN((const char*)input2)), 1); - ExpectIntEQ(wolfSSL_MD5_Final(hash, &md5), 1); - ExpectIntEQ(XMEMCMP(&hash, output2, WC_MD5_DIGEST_SIZE), 0); -#if !defined(NO_OLD_NAMES) && \ - (!defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))) - ExpectPtrNE(MD5(NULL, 1, (byte*)&hash), &hash); - ExpectPtrEq(MD5(input1, 0, (byte*)&hash), &hash); - ExpectPtrNE(MD5(input1, 1, NULL), NULL); - ExpectPtrNE(MD5(NULL, 0, NULL), NULL); - - ExpectPtrEq(MD5(input1, (int)XSTRLEN((const char*)&input1), (byte*)&hash), - &hash); - ExpectIntEQ(XMEMCMP(&hash, output1, WC_MD5_DIGEST_SIZE), 0); - - ExpectPtrEq(MD5(input2, (int)XSTRLEN((const char*)&input2), (byte*)&hash), - &hash); - ExpectIntEQ(XMEMCMP(&hash, output2, WC_MD5_DIGEST_SIZE), 0); - { - byte data[] = "Data to be hashed."; - XMEMSET(hash, 0, WC_MD5_DIGEST_SIZE); - - ExpectNotNull(MD5(data, sizeof(data), NULL)); - ExpectNotNull(MD5(data, sizeof(data), hash)); - ExpectNotNull(MD5(NULL, 0, hash)); - ExpectNull(MD5(NULL, sizeof(data), hash)); - } -#endif -#endif - return EXPECT_RESULT(); -} - -static int test_wolfSSL_MD5_Transform(void) -{ - EXPECT_DECLS; -#if defined(OPENSSL_EXTRA) && !defined(NO_MD5) - byte input1[] = ""; - byte input2[] = "abc"; - byte local[WC_MD5_BLOCK_SIZE]; - word32 sLen = 0; -#ifdef BIG_ENDIAN_ORDER - unsigned char output1[] = - "\x03\x1f\x1d\xac\x6e\xa5\x8e\xd0\x1f\xab\x67\xb7\x74\x31\x77\x91"; - unsigned char output2[] = - "\xef\xd3\x79\x8d\x67\x17\x25\x90\xa4\x13\x79\xc7\xe3\xa7\x7b\xbc"; -#else - unsigned char output1[] = - "\xac\x1d\x1f\x03\xd0\x8e\xa5\x6e\xb7\x67\xab\x1f\x91\x77\x31\x74"; - unsigned char output2[] = - "\x8d\x79\xd3\xef\x90\x25\x17\x67\xc7\x79\x13\xa4\xbc\x7b\xa7\xe3"; -#endif - - union { - wc_Md5 native; - MD5_CTX compat; - } md5; - - XMEMSET(&md5.compat, 0, sizeof(md5.compat)); - XMEMSET(&local, 0, sizeof(local)); - - /* sanity check */ - ExpectIntEQ(MD5_Transform(NULL, NULL), 0); - ExpectIntEQ(MD5_Transform(NULL, (const byte*)&input1), 0); - ExpectIntEQ(MD5_Transform(&md5.compat, NULL), 0); - ExpectIntEQ(wc_Md5Transform(NULL, NULL), BAD_FUNC_ARG); - ExpectIntEQ(wc_Md5Transform(NULL, (const byte*)&input1), BAD_FUNC_ARG); - ExpectIntEQ(wc_Md5Transform(&md5.native, NULL), BAD_FUNC_ARG); - - /* Init MD5 CTX */ - ExpectIntEQ(wolfSSL_MD5_Init(&md5.compat), 1); - /* Do Transform*/ - sLen = (word32)XSTRLEN((char*)input1); - XMEMCPY(local, input1, sLen); - ExpectIntEQ(MD5_Transform(&md5.compat, (const byte*)&local[0]), 1); - - ExpectIntEQ(XMEMCMP(md5.native.digest, output1, WC_MD5_DIGEST_SIZE), 0); - - /* Init MD5 CTX */ - ExpectIntEQ(MD5_Init(&md5.compat), 1); - sLen = (word32)XSTRLEN((char*)input2); - XMEMSET(local, 0, WC_MD5_BLOCK_SIZE); - XMEMCPY(local, input2, sLen); - ExpectIntEQ(MD5_Transform(&md5.compat, (const byte*)&local[0]), 1); - ExpectIntEQ(XMEMCMP(md5.native.digest, output2, WC_MD5_DIGEST_SIZE), 0); -#endif - return EXPECT_RESULT(); -} - -static int test_wolfSSL_SHA224(void) -{ - EXPECT_DECLS; -#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SHA224) && \ - !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ - (defined(HAVE_FIPS_VERSION) && HAVE_FIPS_VERSION > 2)) - unsigned char input[] = - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; - unsigned char output[] = - "\x75\x38\x8b\x16\x51\x27\x76\xcc\x5d\xba\x5d\xa1\xfd\x89\x01" - "\x50\xb0\xc6\x45\x5c\xb4\xf5\x8b\x19\x52\x52\x25\x25"; - size_t inLen; - byte hash[WC_SHA224_DIGEST_SIZE]; - - inLen = XSTRLEN((char*)input); - - XMEMSET(hash, 0, WC_SHA224_DIGEST_SIZE); - - ExpectNull(SHA224(NULL, inLen, hash)); - ExpectNotNull(SHA224(input, 0, hash)); - ExpectNotNull(SHA224(input, inLen, NULL)); - ExpectNotNull(SHA224(NULL, 0, hash)); - ExpectNotNull(SHA224(NULL, 0, NULL)); - - ExpectNotNull(SHA224(input, inLen, hash)); - ExpectIntEQ(XMEMCMP(hash, output, WC_SHA224_DIGEST_SIZE), 0); -#endif - return EXPECT_RESULT(); -} -static int test_wolfSSL_SHA_Transform(void) -{ - EXPECT_DECLS; -#if defined(OPENSSL_EXTRA) && !defined(NO_SHA) -#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ - (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) - byte input1[] = ""; - byte input2[] = "abc"; - byte local[WC_SHA_BLOCK_SIZE]; - word32 sLen = 0; -#ifdef BIG_ENDIAN_ORDER - unsigned char output1[] = - "\x92\xb4\x04\xe5\x56\x58\x8c\xed\x6c\x1a\xcd\x4e\xbf\x05\x3f\x68" - "\x09\xf7\x3a\x93"; - unsigned char output2[] = - "\x97\xb2\x74\x8b\x4f\x5b\xbc\xca\x5b\xc0\xe6\xea\x2d\x40\xb4\xa0" - "\x7c\x6e\x08\xb8"; -#else - unsigned char output1[] = - "\xe5\x04\xb4\x92\xed\x8c\x58\x56\x4e\xcd\x1a\x6c\x68\x3f\x05\xbf" - "\x93\x3a\xf7\x09"; - unsigned char output2[] = - "\x8b\x74\xb2\x97\xca\xbc\x5b\x4f\xea\xe6\xc0\x5b\xa0\xb4\x40\x2d" - "\xb8\x08\x6e\x7c"; -#endif - - union { - wc_Sha native; - SHA_CTX compat; - } sha; - union { - wc_Sha native; - SHA_CTX compat; - } sha1; - - XMEMSET(&sha.compat, 0, sizeof(sha.compat)); - XMEMSET(&local, 0, sizeof(local)); - - /* sanity check */ - ExpectIntEQ(SHA_Transform(NULL, NULL), 0); - ExpectIntEQ(SHA_Transform(NULL, (const byte*)&input1), 0); - ExpectIntEQ(SHA_Transform(&sha.compat, NULL), 0); - ExpectIntEQ(SHA1_Transform(NULL, NULL), 0); - ExpectIntEQ(SHA1_Transform(NULL, (const byte*)&input1), 0); - ExpectIntEQ(SHA1_Transform(&sha.compat, NULL), 0); - ExpectIntEQ(wc_ShaTransform(NULL, NULL), BAD_FUNC_ARG); - ExpectIntEQ(wc_ShaTransform(NULL, (const byte*)&input1), BAD_FUNC_ARG); - ExpectIntEQ(wc_ShaTransform(&sha.native, NULL), BAD_FUNC_ARG); - - /* Init SHA CTX */ - ExpectIntEQ(SHA_Init(&sha.compat), 1); - /* Do Transform*/ - sLen = (word32)XSTRLEN((char*)input1); - XMEMCPY(local, input1, sLen); - ExpectIntEQ(SHA_Transform(&sha.compat, (const byte*)&local[0]), 1); - ExpectIntEQ(XMEMCMP(sha.native.digest, output1, WC_SHA_DIGEST_SIZE), 0); - ExpectIntEQ(SHA_Final(local, &sha.compat), 1); /* frees resources */ - - /* Init SHA CTX */ - ExpectIntEQ(SHA_Init(&sha.compat), 1); - sLen = (word32)XSTRLEN((char*)input2); - XMEMSET(local, 0, WC_SHA_BLOCK_SIZE); - XMEMCPY(local, input2, sLen); - ExpectIntEQ(SHA_Transform(&sha.compat, (const byte*)&local[0]), 1); - ExpectIntEQ(XMEMCMP(sha.native.digest, output2, WC_SHA_DIGEST_SIZE), 0); - ExpectIntEQ(SHA_Final(local, &sha.compat), 1); /* frees resources */ - - /* SHA1 */ - XMEMSET(local, 0, WC_SHA_BLOCK_SIZE); - /* Init SHA CTX */ - ExpectIntEQ(SHA1_Init(&sha1.compat), 1); - /* Do Transform*/ - sLen = (word32)XSTRLEN((char*)input1); - XMEMCPY(local, input1, sLen); - ExpectIntEQ(SHA1_Transform(&sha1.compat, (const byte*)&local[0]), 1); - ExpectIntEQ(XMEMCMP(sha1.native.digest, output1, WC_SHA_DIGEST_SIZE), 0); - ExpectIntEQ(SHA_Final(local, &sha1.compat), 1); /* frees resources */ - - /* Init SHA CTX */ - ExpectIntEQ(SHA1_Init(&sha1.compat), 1); - sLen = (word32)XSTRLEN((char*)input2); - XMEMSET(local, 0, WC_SHA_BLOCK_SIZE); - XMEMCPY(local, input2, sLen); - ExpectIntEQ(SHA1_Transform(&sha1.compat, (const byte*)&local[0]), 1); - ExpectIntEQ(XMEMCMP(sha1.native.digest, output2, WC_SHA_DIGEST_SIZE), 0); - ExpectIntEQ(SHA_Final(local, &sha1.compat), 1); /* frees resources */ -#endif -#endif - return EXPECT_RESULT(); -} - -static int test_wolfSSL_SHA256_Transform(void) -{ - EXPECT_DECLS; -#if defined(OPENSSL_EXTRA) && !defined(NO_SHA256) -#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ - (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) && \ - !defined(WOLFSSL_DEVCRYPTO_HASH) && !defined(WOLFSSL_AFALG_HASH) && \ - !defined(WOLFSSL_KCAPI_HASH) - byte input1[] = ""; - byte input2[] = "abc"; - byte local[WC_SHA256_BLOCK_SIZE]; - word32 sLen = 0; -#ifdef BIG_ENDIAN_ORDER - unsigned char output1[] = - "\xda\x56\x98\xbe\x17\xb9\xb4\x69\x62\x33\x57\x99\x77\x9f\xbe\xca" - "\x8c\xe5\xd4\x91\xc0\xd2\x62\x43\xba\xfe\xf9\xea\x18\x37\xa9\xd8"; - unsigned char output2[] = - "\x1d\x4e\xd4\x67\x67\x7c\x61\x67\x44\x10\x76\x26\x78\x10\xff\xb8" - "\x40\xc8\x9a\x39\x73\x16\x60\x8c\xa6\x61\xd6\x05\x91\xf2\x8c\x35"; -#else - unsigned char output1[] = - "\xbe\x98\x56\xda\x69\xb4\xb9\x17\x99\x57\x33\x62\xca\xbe\x9f\x77" - "\x91\xd4\xe5\x8c\x43\x62\xd2\xc0\xea\xf9\xfe\xba\xd8\xa9\x37\x18"; - unsigned char output2[] = - "\x67\xd4\x4e\x1d\x67\x61\x7c\x67\x26\x76\x10\x44\xb8\xff\x10\x78" - "\x39\x9a\xc8\x40\x8c\x60\x16\x73\x05\xd6\x61\xa6\x35\x8c\xf2\x91"; -#endif - union { - wc_Sha256 native; - SHA256_CTX compat; - } sha256; - - XMEMSET(&sha256.compat, 0, sizeof(sha256.compat)); - XMEMSET(&local, 0, sizeof(local)); - - /* sanity check */ - ExpectIntEQ(SHA256_Transform(NULL, NULL), 0); - ExpectIntEQ(SHA256_Transform(NULL, (const byte*)&input1), 0); - ExpectIntEQ(SHA256_Transform(&sha256.compat, NULL), 0); - ExpectIntEQ(wc_Sha256Transform(NULL, NULL), BAD_FUNC_ARG); - ExpectIntEQ(wc_Sha256Transform(NULL, (const byte*)&input1), BAD_FUNC_ARG); - ExpectIntEQ(wc_Sha256Transform(&sha256.native, NULL), BAD_FUNC_ARG); - - /* Init SHA256 CTX */ - ExpectIntEQ(SHA256_Init(&sha256.compat), 1); - /* Do Transform*/ - sLen = (word32)XSTRLEN((char*)input1); - XMEMCPY(local, input1, sLen); - ExpectIntEQ(SHA256_Transform(&sha256.compat, (const byte*)&local[0]), 1); - ExpectIntEQ(XMEMCMP(sha256.native.digest, output1, WC_SHA256_DIGEST_SIZE), - 0); - ExpectIntEQ(SHA256_Final(local, &sha256.compat), 1); /* frees resources */ - - /* Init SHA256 CTX */ - ExpectIntEQ(SHA256_Init(&sha256.compat), 1); - sLen = (word32)XSTRLEN((char*)input2); - XMEMSET(local, 0, WC_SHA256_BLOCK_SIZE); - XMEMCPY(local, input2, sLen); - ExpectIntEQ(SHA256_Transform(&sha256.compat, (const byte*)&local[0]), 1); - ExpectIntEQ(XMEMCMP(sha256.native.digest, output2, WC_SHA256_DIGEST_SIZE), - 0); - ExpectIntEQ(SHA256_Final(local, &sha256.compat), 1); /* frees resources */ -#endif -#endif - return EXPECT_RESULT(); -} - -static int test_wolfSSL_SHA256(void) -{ - EXPECT_DECLS; -#if defined(OPENSSL_EXTRA) && !defined(NO_SHA256) && \ - defined(NO_OLD_SHA_NAMES) && !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) - unsigned char input[] = - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; - unsigned char output[] = - "\x24\x8D\x6A\x61\xD2\x06\x38\xB8\xE5\xC0\x26\x93\x0C\x3E\x60" - "\x39\xA3\x3C\xE4\x59\x64\xFF\x21\x67\xF6\xEC\xED\xD4\x19\xDB" - "\x06\xC1"; - size_t inLen; - byte hash[WC_SHA256_DIGEST_SIZE]; - - inLen = XSTRLEN((char*)input); - - XMEMSET(hash, 0, WC_SHA256_DIGEST_SIZE); - ExpectNotNull(SHA256(input, inLen, hash)); - ExpectIntEQ(XMEMCMP(hash, output, WC_SHA256_DIGEST_SIZE), 0); -#endif - return EXPECT_RESULT(); -} - -static int test_wolfSSL_SHA512_Transform(void) -{ - EXPECT_DECLS; -#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SHA512) -#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ - (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) && \ - !defined(WOLFSSL_KCAPI_HASH) - byte input1[] = ""; - byte input2[] = "abc"; - byte local[WC_SHA512_BLOCK_SIZE]; - word32 sLen = 0; -#ifdef BIG_ENDIAN_ORDER - unsigned char output1[] = - "\xcf\x78\x81\xd5\x77\x4a\xcb\xe8\x53\x33\x62\xe0\xfb\xc7\x80\x70" - "\x02\x67\x63\x9d\x87\x46\x0e\xda\x30\x86\xcb\x40\xe8\x59\x31\xb0" - "\x71\x7d\xc9\x52\x88\xa0\x23\xa3\x96\xba\xb2\xc1\x4c\xe0\xb5\xe0" - "\x6f\xc4\xfe\x04\xea\xe3\x3e\x0b\x91\xf4\xd8\x0c\xbd\x66\x8b\xee"; - unsigned char output2[] = - "\x11\x10\x93\x4e\xeb\xa0\xcc\x0d\xfd\x33\x43\x9c\xfb\x04\xc8\x21" - "\xa9\xb4\x26\x3d\xca\xab\x31\x41\xe2\xc6\xaa\xaf\xe1\x67\xd7\xab" - "\x31\x8f\x2e\x54\x2c\xba\x4e\x83\xbe\x88\xec\x9d\x8f\x2b\x38\x98" - "\x14\xd2\x4e\x9d\x53\x8b\x5e\x4d\xde\x68\x6c\x69\xaf\x20\x96\xf0"; -#else - unsigned char output1[] = - "\xe8\xcb\x4a\x77\xd5\x81\x78\xcf\x70\x80\xc7\xfb\xe0\x62\x33\x53" - "\xda\x0e\x46\x87\x9d\x63\x67\x02\xb0\x31\x59\xe8\x40\xcb\x86\x30" - "\xa3\x23\xa0\x88\x52\xc9\x7d\x71\xe0\xb5\xe0\x4c\xc1\xb2\xba\x96" - "\x0b\x3e\xe3\xea\x04\xfe\xc4\x6f\xee\x8b\x66\xbd\x0c\xd8\xf4\x91"; - unsigned char output2[] = - "\x0d\xcc\xa0\xeb\x4e\x93\x10\x11\x21\xc8\x04\xfb\x9c\x43\x33\xfd" - "\x41\x31\xab\xca\x3d\x26\xb4\xa9\xab\xd7\x67\xe1\xaf\xaa\xc6\xe2" - "\x83\x4e\xba\x2c\x54\x2e\x8f\x31\x98\x38\x2b\x8f\x9d\xec\x88\xbe" - "\x4d\x5e\x8b\x53\x9d\x4e\xd2\x14\xf0\x96\x20\xaf\x69\x6c\x68\xde"; -#endif - union { - wc_Sha512 native; - SHA512_CTX compat; - } sha512; - - XMEMSET(&sha512.compat, 0, sizeof(sha512.compat)); - XMEMSET(&local, 0, sizeof(local)); - - /* sanity check */ - ExpectIntEQ(SHA512_Transform(NULL, NULL), 0); - ExpectIntEQ(SHA512_Transform(NULL, (const byte*)&input1), 0); - ExpectIntEQ(SHA512_Transform(&sha512.compat, NULL), 0); - ExpectIntEQ(wc_Sha512Transform(NULL, NULL), BAD_FUNC_ARG); - ExpectIntEQ(wc_Sha512Transform(NULL, (const byte*)&input1), BAD_FUNC_ARG); - ExpectIntEQ(wc_Sha512Transform(&sha512.native, NULL), BAD_FUNC_ARG); - - /* Init SHA512 CTX */ - ExpectIntEQ(wolfSSL_SHA512_Init(&sha512.compat), 1); - - /* Do Transform*/ - sLen = (word32)XSTRLEN((char*)input1); - XMEMCPY(local, input1, sLen); - ExpectIntEQ(SHA512_Transform(&sha512.compat, (const byte*)&local[0]), 1); - ExpectIntEQ(XMEMCMP(sha512.native.digest, output1, - WC_SHA512_DIGEST_SIZE), 0); - ExpectIntEQ(SHA512_Final(local, &sha512.compat), 1); /* frees resources */ - - /* Init SHA512 CTX */ - ExpectIntEQ(SHA512_Init(&sha512.compat), 1); - sLen = (word32)XSTRLEN((char*)input2); - XMEMSET(local, 0, WC_SHA512_BLOCK_SIZE); - XMEMCPY(local, input2, sLen); - ExpectIntEQ(SHA512_Transform(&sha512.compat, (const byte*)&local[0]), 1); - ExpectIntEQ(XMEMCMP(sha512.native.digest, output2, - WC_SHA512_DIGEST_SIZE), 0); - ExpectIntEQ(SHA512_Final(local, &sha512.compat), 1); /* frees resources */ - - (void)input1; -#endif -#endif - return EXPECT_RESULT(); -} static int test_wolfSSL_X509_get_serialNumber(void) { @@ -45677,373 +46804,6 @@ static int test_wolfSSL_X509_get_version(void) return EXPECT_RESULT(); } -static int test_wolfSSL_DES_ncbc(void) -{ - EXPECT_DECLS; -#if defined(OPENSSL_EXTRA) && !defined(NO_DES3) - const_DES_cblock myDes; - DES_cblock iv = {1}; - DES_key_schedule key = {0}; - unsigned char msg[] = "hello wolfssl"; - unsigned char out[DES_BLOCK_SIZE * 2] = {0}; - unsigned char pln[DES_BLOCK_SIZE * 2] = {0}; - - unsigned char exp[] = {0x31, 0x98, 0x2F, 0x3A, 0x55, 0xBF, 0xD8, 0xC4}; - unsigned char exp2[] = {0xC7, 0x45, 0x8B, 0x28, 0x10, 0x53, 0xE0, 0x58}; - - /* partial block test */ - DES_set_key(&key, &myDes); - DES_ncbc_encrypt(msg, out, 3, &myDes, &iv, DES_ENCRYPT); - ExpectIntEQ(XMEMCMP(exp, out, DES_BLOCK_SIZE), 0); - ExpectIntEQ(XMEMCMP(exp, iv, DES_BLOCK_SIZE), 0); - - DES_set_key(&key, &myDes); - XMEMSET((byte*)&iv, 0, DES_BLOCK_SIZE); - *((byte*)&iv) = 1; - DES_ncbc_encrypt(out, pln, 3, &myDes, &iv, DES_DECRYPT); - ExpectIntEQ(XMEMCMP(msg, pln, 3), 0); - ExpectIntEQ(XMEMCMP(exp, iv, DES_BLOCK_SIZE), 0); - - /* full block test */ - DES_set_key(&key, &myDes); - XMEMSET(pln, 0, DES_BLOCK_SIZE); - XMEMSET((byte*)&iv, 0, DES_BLOCK_SIZE); - *((byte*)&iv) = 1; - DES_ncbc_encrypt(msg, out, 8, &myDes, &iv, DES_ENCRYPT); - ExpectIntEQ(XMEMCMP(exp2, out, DES_BLOCK_SIZE), 0); - ExpectIntEQ(XMEMCMP(exp2, iv, DES_BLOCK_SIZE), 0); - - DES_set_key(&key, &myDes); - XMEMSET((byte*)&iv, 0, DES_BLOCK_SIZE); - *((byte*)&iv) = 1; - DES_ncbc_encrypt(out, pln, 8, &myDes, &iv, DES_DECRYPT); - ExpectIntEQ(XMEMCMP(msg, pln, 8), 0); - ExpectIntEQ(XMEMCMP(exp2, iv, DES_BLOCK_SIZE), 0); -#endif - return EXPECT_RESULT(); -} - -static int test_wolfSSL_AES_cbc_encrypt(void) -{ - EXPECT_DECLS; -#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(OPENSSL_EXTRA) - AES_KEY aes; - AES_KEY* aesN = NULL; - size_t len = 0; - size_t lenB = 0; - int keySz0 = 0; - int keySzN = -1; - byte out[AES_BLOCK_SIZE] = {0}; - byte* outN = NULL; - - /* Test vectors retrieved from: - * - * https://csrc.nist.gov/ - * CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/ - * documents/aes/KAT_AES.zip - * - */ - const byte* pt128N = NULL; - byte* key128N = NULL; - byte* iv128N = NULL; - byte iv128tmp[AES_BLOCK_SIZE] = {0}; - - const byte pt128[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; - - const byte ct128[] = { 0x87,0x85,0xb1,0xa7,0x5b,0x0f,0x3b,0xd9, - 0x58,0xdc,0xd0,0xe2,0x93,0x18,0xc5,0x21 }; - - const byte iv128[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; - - byte key128[] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00 }; - - - len = sizeof(pt128); - - #define STRESS_T(a, b, c, d, e, f, g, h, i) \ - wolfSSL_AES_cbc_encrypt(a, b, c, d, e, f); \ - ExpectIntNE(XMEMCMP(b, g, h), i) - - #define RESET_IV(x, y) XMEMCPY(x, y, AES_BLOCK_SIZE) - - /* Stressing wolfSSL_AES_cbc_encrypt() */ - STRESS_T(pt128N, out, len, &aes, iv128tmp, 1, ct128, AES_BLOCK_SIZE, 0); - STRESS_T(pt128, out, len, &aes, iv128N, 1, ct128, AES_BLOCK_SIZE, 0); - - wolfSSL_AES_cbc_encrypt(pt128, outN, len, &aes, iv128tmp, AES_ENCRYPT); - ExpectIntNE(XMEMCMP(out, ct128, AES_BLOCK_SIZE), 0); - wolfSSL_AES_cbc_encrypt(pt128, out, len, aesN, iv128tmp, AES_ENCRYPT); - ExpectIntNE(XMEMCMP(out, ct128, AES_BLOCK_SIZE), 0); - - STRESS_T(pt128, out, lenB, &aes, iv128tmp, 1, ct128, AES_BLOCK_SIZE, 0); - - /* Stressing wolfSSL_AES_set_encrypt_key */ - ExpectIntNE(wolfSSL_AES_set_encrypt_key(key128N, sizeof(key128)*8, &aes),0); - ExpectIntNE(wolfSSL_AES_set_encrypt_key(key128, sizeof(key128)*8, aesN),0); - ExpectIntNE(wolfSSL_AES_set_encrypt_key(key128, keySz0, &aes), 0); - ExpectIntNE(wolfSSL_AES_set_encrypt_key(key128, keySzN, &aes), 0); - - /* Stressing wolfSSL_AES_set_decrypt_key */ - ExpectIntNE(wolfSSL_AES_set_decrypt_key(key128N, sizeof(key128)*8, &aes),0); - ExpectIntNE(wolfSSL_AES_set_decrypt_key(key128N, sizeof(key128)*8, aesN),0); - ExpectIntNE(wolfSSL_AES_set_decrypt_key(key128, keySz0, &aes), 0); - ExpectIntNE(wolfSSL_AES_set_decrypt_key(key128, keySzN, &aes), 0); - - #ifdef WOLFSSL_AES_128 - - /* wolfSSL_AES_cbc_encrypt() 128-bit */ - XMEMSET(out, 0, AES_BLOCK_SIZE); - RESET_IV(iv128tmp, iv128); - - ExpectIntEQ(wolfSSL_AES_set_encrypt_key(key128, sizeof(key128)*8, &aes), 0); - wolfSSL_AES_cbc_encrypt(pt128, out, len, &aes, iv128tmp, AES_ENCRYPT); - ExpectIntEQ(XMEMCMP(out, ct128, AES_BLOCK_SIZE), 0); - wc_AesFree((Aes*)&aes); - - #ifdef HAVE_AES_DECRYPT - - /* wolfSSL_AES_cbc_encrypt() 128-bit in decrypt mode */ - XMEMSET(out, 0, AES_BLOCK_SIZE); - RESET_IV(iv128tmp, iv128); - len = sizeof(ct128); - - ExpectIntEQ(wolfSSL_AES_set_decrypt_key(key128, sizeof(key128)*8, &aes), 0); - wolfSSL_AES_cbc_encrypt(ct128, out, len, &aes, iv128tmp, AES_DECRYPT); - ExpectIntEQ(XMEMCMP(out, pt128, AES_BLOCK_SIZE), 0); - wc_AesFree((Aes*)&aes); - - #endif - - #endif /* WOLFSSL_AES_128 */ - #ifdef WOLFSSL_AES_192 - { - /* Test vectors from NIST Special Publication 800-38A, 2001 Edition - * Appendix F.2.3 */ - - byte iv192tmp[AES_BLOCK_SIZE] = {0}; - - const byte pt192[] = { 0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96, - 0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a }; - - const byte ct192[] = { 0x4f,0x02,0x1d,0xb2,0x43,0xbc,0x63,0x3d, - 0x71,0x78,0x18,0x3a,0x9f,0xa0,0x71,0xe8 }; - - const byte iv192[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, - 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F }; - - byte key192[] = { 0x8e,0x73,0xb0,0xf7,0xda,0x0e,0x64,0x52, - 0xc8,0x10,0xf3,0x2b,0x80,0x90,0x79,0xe5, - 0x62,0xf8,0xea,0xd2,0x52,0x2c,0x6b,0x7b }; - - len = sizeof(pt192); - - /* wolfSSL_AES_cbc_encrypt() 192-bit */ - XMEMSET(out, 0, AES_BLOCK_SIZE); - RESET_IV(iv192tmp, iv192); - - ExpectIntEQ(wolfSSL_AES_set_encrypt_key(key192, sizeof(key192)*8, &aes), 0); - wolfSSL_AES_cbc_encrypt(pt192, out, len, &aes, iv192tmp, AES_ENCRYPT); - ExpectIntEQ(XMEMCMP(out, ct192, AES_BLOCK_SIZE), 0); - wc_AesFree((Aes*)&aes); - - #ifdef HAVE_AES_DECRYPT - - /* wolfSSL_AES_cbc_encrypt() 192-bit in decrypt mode */ - len = sizeof(ct192); - RESET_IV(iv192tmp, iv192); - XMEMSET(out, 0, AES_BLOCK_SIZE); - - ExpectIntEQ(wolfSSL_AES_set_decrypt_key(key192, sizeof(key192)*8, &aes), 0); - wolfSSL_AES_cbc_encrypt(ct192, out, len, &aes, iv192tmp, AES_DECRYPT); - ExpectIntEQ(XMEMCMP(out, pt192, AES_BLOCK_SIZE), 0); - wc_AesFree((Aes*)&aes); - - #endif - } - #endif /* WOLFSSL_AES_192 */ - #ifdef WOLFSSL_AES_256 - { - /* Test vectors from NIST Special Publication 800-38A, 2001 Edition, - * Appendix F.2.5 */ - byte iv256tmp[AES_BLOCK_SIZE] = {0}; - - const byte pt256[] = { 0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96, - 0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a }; - - const byte ct256[] = { 0xf5,0x8c,0x4c,0x04,0xd6,0xe5,0xf1,0xba, - 0x77,0x9e,0xab,0xfb,0x5f,0x7b,0xfb,0xd6 }; - - const byte iv256[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, - 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F }; - - byte key256[] = { 0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe, - 0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81, - 0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7, - 0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4 }; - - - len = sizeof(pt256); - - /* wolfSSL_AES_cbc_encrypt() 256-bit */ - XMEMSET(out, 0, AES_BLOCK_SIZE); - RESET_IV(iv256tmp, iv256); - - ExpectIntEQ(wolfSSL_AES_set_encrypt_key(key256, sizeof(key256)*8, &aes), 0); - wolfSSL_AES_cbc_encrypt(pt256, out, len, &aes, iv256tmp, AES_ENCRYPT); - ExpectIntEQ(XMEMCMP(out, ct256, AES_BLOCK_SIZE), 0); - wc_AesFree((Aes*)&aes); - - #ifdef HAVE_AES_DECRYPT - - /* wolfSSL_AES_cbc_encrypt() 256-bit in decrypt mode */ - len = sizeof(ct256); - RESET_IV(iv256tmp, iv256); - XMEMSET(out, 0, AES_BLOCK_SIZE); - - ExpectIntEQ(wolfSSL_AES_set_decrypt_key(key256, sizeof(key256)*8, &aes), 0); - wolfSSL_AES_cbc_encrypt(ct256, out, len, &aes, iv256tmp, AES_DECRYPT); - ExpectIntEQ(XMEMCMP(out, pt256, AES_BLOCK_SIZE), 0); - wc_AesFree((Aes*)&aes); - - #endif - - #if defined(HAVE_AES_KEYWRAP) && !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) - { - byte wrapCipher[sizeof(key256) + KEYWRAP_BLOCK_SIZE] = { 0 }; - byte wrapPlain[sizeof(key256)] = { 0 }; - byte wrapIV[KEYWRAP_BLOCK_SIZE] = { 0 }; - - /* wolfSSL_AES_wrap_key() 256-bit NULL iv */ - ExpectIntEQ(wolfSSL_AES_set_encrypt_key(key256, sizeof(key256)*8, &aes), 0); - ExpectIntEQ(wolfSSL_AES_wrap_key(&aes, NULL, wrapCipher, key256, - 15), WOLFSSL_FAILURE); - ExpectIntEQ(wolfSSL_AES_wrap_key(&aes, NULL, wrapCipher, key256, - sizeof(key256)), sizeof(wrapCipher)); - wc_AesFree((Aes*)&aes); - - /* wolfSSL_AES_unwrap_key() 256-bit NULL iv */ - ExpectIntEQ(wolfSSL_AES_set_decrypt_key(key256, sizeof(key256)*8, &aes), 0); - ExpectIntEQ(wolfSSL_AES_unwrap_key(&aes, NULL, wrapPlain, wrapCipher, - 23), WOLFSSL_FAILURE); - ExpectIntEQ(wolfSSL_AES_unwrap_key(&aes, NULL, wrapPlain, wrapCipher, - sizeof(wrapCipher)), sizeof(wrapPlain)); - ExpectIntEQ(XMEMCMP(wrapPlain, key256, sizeof(key256)), 0); - XMEMSET(wrapCipher, 0, sizeof(wrapCipher)); - XMEMSET(wrapPlain, 0, sizeof(wrapPlain)); - wc_AesFree((Aes*)&aes); - - /* wolfSSL_AES_wrap_key() 256-bit custom iv */ - ExpectIntEQ(wolfSSL_AES_set_encrypt_key(key256, sizeof(key256)*8, &aes), 0); - ExpectIntEQ(wolfSSL_AES_wrap_key(&aes, wrapIV, wrapCipher, key256, - sizeof(key256)), sizeof(wrapCipher)); - wc_AesFree((Aes*)&aes); - - /* wolfSSL_AES_unwrap_key() 256-bit custom iv */ - ExpectIntEQ(wolfSSL_AES_set_decrypt_key(key256, sizeof(key256)*8, &aes), 0); - ExpectIntEQ(wolfSSL_AES_unwrap_key(&aes, wrapIV, wrapPlain, wrapCipher, - sizeof(wrapCipher)), sizeof(wrapPlain)); - ExpectIntEQ(XMEMCMP(wrapPlain, key256, sizeof(key256)), 0); - wc_AesFree((Aes*)&aes); - } - #endif /* HAVE_AES_KEYWRAP */ - } - #endif /* WOLFSSL_AES_256 */ -#endif - return EXPECT_RESULT(); -} - -static int test_wolfSSL_CRYPTO_cts128(void) -{ - EXPECT_DECLS; -#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(OPENSSL_EXTRA) && \ - defined(HAVE_CTS) - byte tmp[64]; /* Largest vector size */ - /* Test vectors taken form RFC3962 Appendix B */ - const testVector vects[] = { - { - "\x49\x20\x77\x6f\x75\x6c\x64\x20\x6c\x69\x6b\x65\x20\x74\x68\x65" - "\x20", - "\xc6\x35\x35\x68\xf2\xbf\x8c\xb4\xd8\xa5\x80\x36\x2d\xa7\xff\x7f" - "\x97", - 17, 17 - }, - { - "\x49\x20\x77\x6f\x75\x6c\x64\x20\x6c\x69\x6b\x65\x20\x74\x68\x65" - "\x20\x47\x65\x6e\x65\x72\x61\x6c\x20\x47\x61\x75\x27\x73\x20", - "\xfc\x00\x78\x3e\x0e\xfd\xb2\xc1\xd4\x45\xd4\xc8\xef\xf7\xed\x22" - "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5", - 31, 31 - }, - { - "\x49\x20\x77\x6f\x75\x6c\x64\x20\x6c\x69\x6b\x65\x20\x74\x68\x65" - "\x20\x47\x65\x6e\x65\x72\x61\x6c\x20\x47\x61\x75\x27\x73\x20\x43", - "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8" - "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84", - 32, 32 - }, - { - "\x49\x20\x77\x6f\x75\x6c\x64\x20\x6c\x69\x6b\x65\x20\x74\x68\x65" - "\x20\x47\x65\x6e\x65\x72\x61\x6c\x20\x47\x61\x75\x27\x73\x20\x43" - "\x68\x69\x63\x6b\x65\x6e\x2c\x20\x70\x6c\x65\x61\x73\x65\x2c", - "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84" - "\xb3\xff\xfd\x94\x0c\x16\xa1\x8c\x1b\x55\x49\xd2\xf8\x38\x02\x9e" - "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5", - 47, 47 - }, - { - "\x49\x20\x77\x6f\x75\x6c\x64\x20\x6c\x69\x6b\x65\x20\x74\x68\x65" - "\x20\x47\x65\x6e\x65\x72\x61\x6c\x20\x47\x61\x75\x27\x73\x20\x43" - "\x68\x69\x63\x6b\x65\x6e\x2c\x20\x70\x6c\x65\x61\x73\x65\x2c\x20", - "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84" - "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8" - "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8", - 48, 48 - }, - { - "\x49\x20\x77\x6f\x75\x6c\x64\x20\x6c\x69\x6b\x65\x20\x74\x68\x65" - "\x20\x47\x65\x6e\x65\x72\x61\x6c\x20\x47\x61\x75\x27\x73\x20\x43" - "\x68\x69\x63\x6b\x65\x6e\x2c\x20\x70\x6c\x65\x61\x73\x65\x2c\x20" - "\x61\x6e\x64\x20\x77\x6f\x6e\x74\x6f\x6e\x20\x73\x6f\x75\x70\x2e", - "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84" - "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8" - "\x48\x07\xef\xe8\x36\xee\x89\xa5\x26\x73\x0d\xbc\x2f\x7b\xc8\x40" - "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8", - 64, 64 - } - }; - byte keyBytes[AES_128_KEY_SIZE] = { - 0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20, - 0x74, 0x65, 0x72, 0x69, 0x79, 0x61, 0x6b, 0x69 - }; - size_t i; - - XMEMSET(tmp, 0, sizeof(tmp)); - for (i = 0; i < sizeof(vects)/sizeof(vects[0]); i++) { - AES_KEY encKey; - AES_KEY decKey; - byte iv[AES_IV_SIZE]; /* All-zero IV for all cases */ - XMEMSET(iv, 0, sizeof(iv)); - ExpectIntEQ(AES_set_encrypt_key(keyBytes, AES_128_KEY_SIZE * 8, - &encKey), 0); - ExpectIntEQ(AES_set_decrypt_key(keyBytes, AES_128_KEY_SIZE * 8, - &decKey), 0); - ExpectIntEQ(CRYPTO_cts128_encrypt((const unsigned char*)vects[i].input, - tmp, vects[i].inLen, &encKey, iv, (cbc128_f)AES_cbc_encrypt), - vects[i].outLen); - ExpectIntEQ(XMEMCMP(tmp, vects[i].output, vects[i].outLen), 0); - XMEMSET(iv, 0, sizeof(iv)); - ExpectIntEQ(CRYPTO_cts128_decrypt((const unsigned char*)vects[i].output, - tmp, vects[i].outLen, &decKey, iv, (cbc128_f)AES_cbc_encrypt), - vects[i].inLen); - ExpectIntEQ(XMEMCMP(tmp, vects[i].input, vects[i].inLen), 0); - } -#endif /* !NO_AES && HAVE_AES_CBC && OPENSSL_EXTRA && HAVE_CTS */ - return EXPECT_RESULT(); -} - #if defined(OPENSSL_ALL) static int test_wolfSSL_sk_CIPHER_description(void) { @@ -55130,12 +55890,6 @@ static int test_wolfSSL_dup_CA_list(void) #endif /* OPENSSL_ALL */ return res; } -/* include misc.c here regardless of NO_INLINE, because misc.c implementations - * have default (hidden) visibility, and in the absence of visibility, it's - * benign to mask out the library implementation. - */ -#define WOLFSSL_MISC_INCLUDED -#include static int test_ForceZero(void) { @@ -67841,7 +68595,6 @@ TEST_CASE testCases[] = { TEST_DECL(test_wolfSSL_lhash), TEST_DECL(test_wolfSSL_certs), - TEST_DECL(test_wolfSSL_DES), TEST_DECL(test_wolfSSL_private_keys), TEST_DECL(test_wolfSSL_PEM_read_PrivateKey), @@ -67919,6 +68672,7 @@ TEST_CASE testCases[] = { TEST_DECL(test_evp_cipher_aes_gcm), #endif + TEST_DECL(test_wolfssl_EVP_aria_gcm), TEST_DECL(test_wolfSSL_EVP_Cipher_extra), #ifdef OPENSSL_EXTRA TEST_DECL(test_wolfSSL_EVP_get_cipherbynid), @@ -68208,25 +68962,6 @@ TEST_CASE testCases[] = { TEST_DECL(test_wolfSSL_verify_result), TEST_DECL(test_wolfSSL_msg_callback), - TEST_DECL(test_wolfSSL_MD4), - TEST_DECL(test_wolfSSL_MD5), - TEST_DECL(test_wolfSSL_MD5_Transform), - TEST_DECL(test_wolfSSL_SHA), - TEST_DECL(test_wolfSSL_SHA_Transform), - TEST_DECL(test_wolfSSL_SHA224), - TEST_DECL(test_wolfSSL_SHA256), - TEST_DECL(test_wolfSSL_SHA256_Transform), - TEST_DECL(test_wolfSSL_SHA512_Transform), - TEST_DECL(test_wolfSSL_HMAC_CTX), - TEST_DECL(test_wolfSSL_HMAC), - TEST_DECL(test_wolfSSL_CMAC), - - TEST_DECL(test_wolfSSL_DES_ecb_encrypt), - TEST_DECL(test_wolfSSL_DES_ncbc), - TEST_DECL(test_wolfSSL_AES_ecb_encrypt), - TEST_DECL(test_wolfSSL_AES_cbc_encrypt), - TEST_DECL(test_wolfSSL_CRYPTO_cts128), - TEST_DECL(test_wolfssl_EVP_aria_gcm), TEST_DECL(test_wolfSSL_OCSP_id_get0_info), TEST_DECL(test_wolfSSL_i2d_OCSP_CERTID), TEST_DECL(test_wolfSSL_d2i_OCSP_CERTID), @@ -68269,6 +69004,36 @@ TEST_CASE testCases[] = { TEST_DECL(test_wolfSSL_CTX_use_certificate_ASN1), #endif /* (OPENSSL_ALL || WOLFSSL_ASIO) && !NO_RSA */ + /********************************* + * Crypto API tests + *********************************/ + + TEST_DECL(test_wolfSSL_MD4), + TEST_DECL(test_wolfSSL_MD5), + TEST_DECL(test_wolfSSL_MD5_Transform), + TEST_DECL(test_wolfSSL_SHA), + TEST_DECL(test_wolfSSL_SHA_Transform), + TEST_DECL(test_wolfSSL_SHA224), + TEST_DECL(test_wolfSSL_SHA256), + TEST_DECL(test_wolfSSL_SHA256_Transform), + TEST_DECL(test_wolfSSL_SHA512_Transform), + TEST_DECL(test_wolfSSL_SHA512_224_Transform), + TEST_DECL(test_wolfSSL_SHA512_256_Transform), + TEST_DECL(test_wolfSSL_HMAC_CTX), + TEST_DECL(test_wolfSSL_HMAC), + TEST_DECL(test_wolfSSL_CMAC), + + TEST_DECL(test_wolfSSL_DES), + TEST_DECL(test_wolfSSL_DES_ncbc), + TEST_DECL(test_wolfSSL_DES_ecb_encrypt), + TEST_DECL(test_wolfSSL_DES_ede3_cbc_encrypt), + TEST_DECL(test_wolfSSL_AES_encrypt), + TEST_DECL(test_wolfSSL_AES_ecb_encrypt), + TEST_DECL(test_wolfSSL_AES_cbc_encrypt), + TEST_DECL(test_wolfSSL_AES_cfb128_encrypt), + TEST_DECL(test_wolfSSL_CRYPTO_cts128), + TEST_DECL(test_wolfSSL_RC4), + TEST_DECL(test_wolfSSL_RSA), TEST_DECL(test_wolfSSL_RSA_DER), TEST_DECL(test_wolfSSL_RSA_print), diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 2b3f058c3..f92fb0492 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -4112,6 +4112,86 @@ const unsigned char* wolfSSL_EVP_PKEY_get0_hmac(const WOLFSSL_EVP_PKEY* pkey, return (const unsigned char*)pkey->pkey.ptr; } +static int wolfssl_evp_md_to_hash_type(const WOLFSSL_EVP_MD *type, + int* hashType) +{ + int ret = 0; + +#ifndef NO_SHA256 + if (XSTRCMP(type, "SHA256") == 0) { + *hashType = WC_SHA256; + } + else +#endif +#ifndef NO_SHA + if ((XSTRCMP(type, "SHA") == 0) || (XSTRCMP(type, "SHA1") == 0)) { + *hashType = WC_SHA; + } + else +#endif /* NO_SHA */ +#ifdef WOLFSSL_SHA224 + if (XSTRCMP(type, "SHA224") == 0) { + *hashType = WC_SHA224; + } + else +#endif +#ifdef WOLFSSL_SHA384 + if (XSTRCMP(type, "SHA384") == 0) { + *hashType = WC_SHA384; + } + else +#endif +#ifdef WOLFSSL_SHA512 + if (XSTRCMP(type, "SHA512") == 0) { + *hashType = WC_SHA512; + } + else +#endif +#ifdef WOLFSSL_SHA3 + #ifndef WOLFSSL_NOSHA3_224 + if (XSTRCMP(type, "SHA3_224") == 0) { + *hashType = WC_SHA3_224; + } + else + #endif + #ifndef WOLFSSL_NOSHA3_256 + if (XSTRCMP(type, "SHA3_256") == 0) { + *hashType = WC_SHA3_256; + } + else + #endif + #ifndef WOLFSSL_NOSHA3_384 + if (XSTRCMP(type, "SHA3_384") == 0) { + *hashType = WC_SHA3_384; + } + else + #endif + #ifndef WOLFSSL_NOSHA3_512 + if (XSTRCMP(type, "SHA3_512") == 0) { + *hashType = WC_SHA3_512; + } + else + #endif +#endif +#ifdef WOLFSSL_SM3 + if (XSTRCMP(type, "SM3") == 0) { + *hashType = WC_SM3; + } + else +#endif +#ifndef NO_MD5 + if (XSTRCMP(type, "MD5") == 0) { + *hashType = WC_MD5; + } + else +#endif + { + ret = BAD_FUNC_ARG; + } + + return ret; +} + /* Initialize an EVP_DigestSign/Verify operation. * Initialize a digest for RSA and ECC keys, or HMAC for HMAC key. */ @@ -4129,86 +4209,29 @@ static int wolfSSL_evp_digest_pk_init(WOLFSSL_EVP_MD_CTX *ctx, return WOLFSSL_FAILURE; } type = wolfSSL_EVP_get_digestbynid(default_digest); - if (!type) { + if (type == NULL) { return BAD_FUNC_ARG; } } if (pkey->type == EVP_PKEY_HMAC) { - int hashType; + int hashType; + int ret; + size_t keySz = 0; + const unsigned char* key; - #ifndef NO_SHA256 - if (XSTRCMP(type, "SHA256") == 0) { - hashType = WC_SHA256; - } else - #endif - #ifndef NO_SHA - if ((XSTRCMP(type, "SHA") == 0) || (XSTRCMP(type, "SHA1") == 0)) { - hashType = WC_SHA; - } else - #endif /* NO_SHA */ - #ifdef WOLFSSL_SHA224 - if (XSTRCMP(type, "SHA224") == 0) { - hashType = WC_SHA224; - } else - #endif - #ifdef WOLFSSL_SHA384 - if (XSTRCMP(type, "SHA384") == 0) { - hashType = WC_SHA384; - } else - #endif - #ifdef WOLFSSL_SHA512 - if (XSTRCMP(type, "SHA512") == 0) { - hashType = WC_SHA512; - } else - #endif -#ifdef WOLFSSL_SHA3 - #ifndef WOLFSSL_NOSHA3_224 - if (XSTRCMP(type, "SHA3_224") == 0) { - hashType = WC_SHA3_224; - } else - #endif - #ifndef WOLFSSL_NOSHA3_256 - if (XSTRCMP(type, "SHA3_256") == 0) { - hashType = WC_SHA3_256; - } else - #endif - #ifndef WOLFSSL_NOSHA3_384 - if (XSTRCMP(type, "SHA3_384") == 0) { - hashType = WC_SHA3_384; - } else - #endif - #ifndef WOLFSSL_NOSHA3_512 - if (XSTRCMP(type, "SHA3_512") == 0) { - hashType = WC_SHA3_512; - } else - #endif -#endif - #ifdef WOLFSSL_SM3 - if (XSTRCMP(type, "SM3") == 0) { - hashType = WC_SM3; - } else - #endif - #ifndef NO_MD5 - if (XSTRCMP(type, "MD5") == 0) { - hashType = WC_MD5; - } else - #endif - return BAD_FUNC_ARG; - - { - size_t keySz = 0; - const unsigned char* key; - - key = wolfSSL_EVP_PKEY_get0_hmac(pkey, &keySz); - - if (wc_HmacInit(&ctx->hash.hmac, NULL, INVALID_DEVID) != 0) - return WOLFSSL_FAILURE; - - if (wc_HmacSetKey(&ctx->hash.hmac, hashType, key, (word32)keySz) != 0) - return WOLFSSL_FAILURE; + ret = wolfssl_evp_md_to_hash_type(type, &hashType); + if (ret != 0) { + return ret; } + key = wolfSSL_EVP_PKEY_get0_hmac(pkey, &keySz); + if (wc_HmacInit(&ctx->hash.hmac, NULL, INVALID_DEVID) != 0) + return WOLFSSL_FAILURE; + + if (wc_HmacSetKey(&ctx->hash.hmac, hashType, key, (word32)keySz) != 0) + return WOLFSSL_FAILURE; + ctx->isHMAC = 1; } else if (wolfSSL_EVP_DigestInit(ctx, type) != 1) diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index b6c9fd79a..0f1131ee4 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -15369,7 +15369,7 @@ static void initDefaultName(void) WOLFSSL_SMALL_STACK_STATIC const char certKeyUsage[] = "digitalSignature,nonRepudiation"; #endif - #if defined(WOLFSSL_CERT_REQ) && !defined(NO_RSA) + #if defined(WOLFSSL_CERT_REQ) && !defined(NO_RSA) && !defined(NO_ASN_TIME) WOLFSSL_SMALL_STACK_STATIC const char certKeyUsage2[] = "digitalSignature,nonRepudiation,keyEncipherment,keyAgreement"; #endif