[Bug]: wc_HmacSetKey corrupts memory
Contact Details
No response
Version
5.4.0
Description
osx 12.4, clang 14.0.6, used with cmake, installed via brew https://formulae.brew.sh/formula/wolfssl
set(wolfSSL_DIR ${_OSX_HOMEBREW_PATH}/opt/wolfssl)
add_library(wolfssl UNKNOWN IMPORTED)
set_target_properties(
wolfssl
PROPERTIES
IMPORTED_LOCATION "${wolfSSL_DIR}/lib/libwolfssl.dylib"
INTERFACE_INCLUDE_DIRECTORIES "${wolfSSL_DIR}/include"
)
add_definitions(-DWC_NO_HARDEN -DLARGE_STATIC_BUFFERS)
for how formula is compiled / defined see https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/wolfssl.rb
Reproduction steps
I followed the example from: https://www.wolfssl.com/documentation/manuals/wolfssl/chapter10.html#hmac
#define CATCH_CONFIG_ENABLE_BENCHMARKING
#include <catch2/catch.hpp>
#include <wolfssl/version.h>
#include <wolfssl/wolfcrypt/sha256.h>
#include <wolfssl/wolfcrypt/hmac.h>
TEST_CASE("emotional damage", "[wolfssl]") {
std::string key = "abcdefgHV1TXd22_kjIaBXlYp_mwsaaakgvAwa19X";
std::string payload = "parent=mum&meal=dinner&lunch=dimsum";
Hmac hmac;
byte hmacDigest[SHA256_DIGEST_SIZE];
wc_HmacSetKey(&hmac, SHA256, reinterpret_cast<const byte *>(key.data()), key.size());
wc_HmacUpdate(&hmac, reinterpret_cast<const byte *>(payload.data()), payload.size());
wc_HmacFinal(&hmac, hmacDigest);
}
wc_HmacSetKey corrupts program memory causing segfaults
Relevant log output
Testing started at 12:04 ...
9: Failure:
fatal error
Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)
</Catch>
I traded this on the Amazon Linux 2, Clang 14.0.6 with libc++
<?xml version="1.0" encoding="UTF-8"?>
<Catch name="test" filters="emotional damage">
<Group name="test">
<TestCase name="emotional damage" tags="[wolfssl]" filename="file.cxx" line="6">
<FatalErrorCondition filename="file.cxx" line="6">
SIGSEGV - Segmentation violation signal
</FatalErrorCondition>
<OverallResult success="false" durationInSeconds="8.5e-05"/>
</TestCase>
<OverallResults successes="0" failures="1" expectedFailures="0"/>
<OverallResultsCases successes="0" failures="1" expectedFailures="0"/>
</Group>
<OverallResults successes="0" failures="1" expectedFailures="0"/>
<OverallResultsCases successes="0" failures="1" expectedFailures="0"/>
</Catch>Segmentation fault
Hi @Ziemien ,
The reason for the crash is the stack defined for Hmac structure does not match the size that wolfSSL expects.
It sounds like your application is not including the wolfssl/options.h file. This is a generated file containing the build settings used at compile-time. It is important your application also includes / defines the same build settings.
See the FAQ item 1 here: https://www.wolfssl.com/docs/frequently-asked-questions-faq/#How_do_I_manage_the_build_configuration_for_wolfSSL?
Thanks, David Garske, wolfSSL
thank you, is --enable-fips require to access SHA256?
this seems to compile but if used with SHA256 as the docs suggested - symbol is undefined
#include <wolfssl/options.h>
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/ssl.h>
#include <wolfssl/wolfcrypt/hmac.h>
wc_HmacSetKey(&hmac, WC_SHA256, ...);
error: no matching function for call to 'wc_HmacSetKey'
wc_HmacSetKey(&hmac, SHA256, reinterpret_cast<const byte *>(key.data()), key.size());
^~~~~~~~~~~~~
/opt/homebrew/opt/wolfssl/include/wolfssl/wolfcrypt/hmac.h:190:17: note: candidate function not viable: no known conversion from 'unsigned char *(const unsigned char *, size_t, unsigned char *)' (aka 'unsigned char *(const unsigned char *, unsigned long, unsigned char *)') to 'int' for 2nd argument
WOLFSSL_API int wc_HmacSetKey(Hmac* hmac, int type, const byte* key, word32 keySz);
options.h
/* wolfssl options.h
* generated from configure options
*
* Copyright (C) 2006-2022 wolfSSL Inc.
*
* This file is part of wolfSSL. (formerly known as CyaSSL)
*
*/
#ifndef WOLFSSL_OPTIONS_H
#define WOLFSSL_OPTIONS_H
#ifdef __cplusplus
extern "C" {
#endif
#undef HAVE_THREAD_LS
#define HAVE_THREAD_LS
#undef NO_DO178
#define NO_DO178
#undef USE_FAST_MATH
#define USE_FAST_MATH
#undef WOLFSSL_AARCH64_BUILD
#define WOLFSSL_AARCH64_BUILD
#ifndef WOLFSSL_OPTIONS_IGNORE_SYS
#undef _POSIX_THREADS
#define _POSIX_THREADS
#endif
#undef WOLFSSL_DTLS
#define WOLFSSL_DTLS
#undef TFM_TIMING_RESISTANT
#define TFM_TIMING_RESISTANT
#undef ECC_TIMING_RESISTANT
#define ECC_TIMING_RESISTANT
#undef WC_RSA_BLINDING
#define WC_RSA_BLINDING
#undef TEST_IPV6
#define TEST_IPV6
#undef WOLFSSL_IPV6
#define WOLFSSL_IPV6
#undef PERSIST_SESSION_CACHE
#define PERSIST_SESSION_CACHE
#undef PERSIST_CERT_CACHE
#define PERSIST_CERT_CACHE
#undef HAVE_AESCCM
#define HAVE_AESCCM
#undef WOLFSSL_USE_ALIGN
#define WOLFSSL_USE_ALIGN
#undef HAVE_CAMELLIA
#define HAVE_CAMELLIA
#undef WOLFSSL_RIPEMD
#define WOLFSSL_RIPEMD
#undef HAVE_BLAKE2
#define HAVE_BLAKE2
#undef HAVE_BLAKE2B
#define HAVE_BLAKE2B
#undef WOLFSSL_SHA224
#define WOLFSSL_SHA224
#undef WOLFSSL_SHA512
#define WOLFSSL_SHA512
#undef WOLFSSL_SHA384
#define WOLFSSL_SHA384
#undef SESSION_CERTS
#define SESSION_CERTS
#undef HAVE_HKDF
#define HAVE_HKDF
#undef NO_DSA
#define NO_DSA
#undef HAVE_ECC
#define HAVE_ECC
#undef TFM_ECC256
#define TFM_ECC256
#undef ECC_SHAMIR
#define ECC_SHAMIR
#undef HAVE_CURVE25519
#define HAVE_CURVE25519
#undef HAVE_ECC_ENCRYPT
#define HAVE_ECC_ENCRYPT
#undef WC_RSA_PSS
#define WC_RSA_PSS
#undef WOLFSSL_BASE64_ENCODE
#define WOLFSSL_BASE64_ENCODE
#undef WOLFSSL_SHA3
#define WOLFSSL_SHA3
#undef WOLFSSL_NO_SHAKE256
#define WOLFSSL_NO_SHAKE256
#undef HAVE_POLY1305
#define HAVE_POLY1305
#undef HAVE_CHACHA
#define HAVE_CHACHA
#undef HAVE_HASHDRBG
#define HAVE_HASHDRBG
#undef HAVE_OPENSSL_CMD
#define HAVE_OPENSSL_CMD
#undef HAVE_CRL
#define HAVE_CRL
#undef HAVE_CRL_MONITOR
#define HAVE_CRL_MONITOR
#undef HAVE_TLS_EXTENSIONS
#define HAVE_TLS_EXTENSIONS
#undef HAVE_SNI
#define HAVE_SNI
#undef HAVE_TLS_EXTENSIONS
#define HAVE_TLS_EXTENSIONS
#undef HAVE_ALPN
#define HAVE_ALPN
#undef HAVE_TLS_EXTENSIONS
#define HAVE_TLS_EXTENSIONS
#undef HAVE_SUPPORTED_CURVES
#define HAVE_SUPPORTED_CURVES
#undef HAVE_FFDHE_2048
#define HAVE_FFDHE_2048
#undef HAVE_SUPPORTED_CURVES
#define HAVE_SUPPORTED_CURVES
#undef WOLFSSL_TLS13
#define WOLFSSL_TLS13
#undef HAVE_TLS_EXTENSIONS
#define HAVE_TLS_EXTENSIONS
#undef HAVE_EXTENDED_MASTER
#define HAVE_EXTENDED_MASTER
#undef WOLFSSL_JNI
#define WOLFSSL_JNI
#undef HAVE_EX_DATA
#define HAVE_EX_DATA
#undef OPENSSL_EXTRA
#define OPENSSL_EXTRA
#undef OPENSSL_ALL
#define OPENSSL_ALL
#undef ATOMIC_USER
#define ATOMIC_USER
#undef HAVE_PK_CALLBACKS
#define HAVE_PK_CALLBACKS
#undef WOLFSSL_CERT_EXT
#define WOLFSSL_CERT_EXT
#undef NO_RC4
#define NO_RC4
#undef HAVE_ENCRYPT_THEN_MAC
#define HAVE_ENCRYPT_THEN_MAC
#undef NO_MD4
#define NO_MD4
#undef WOLFSSL_ENCRYPTED_KEYS
#define WOLFSSL_ENCRYPTED_KEYS
#undef WOLFSSL_HAVE_SP_RSA
#define WOLFSSL_HAVE_SP_RSA
#undef WOLFSSL_HAVE_SP_DH
#define WOLFSSL_HAVE_SP_DH
#undef WOLFSSL_SP_4096
#define WOLFSSL_SP_4096
#undef WOLFSSL_SP_LARGE_CODE
#define WOLFSSL_SP_LARGE_CODE
#undef WOLFSSL_HAVE_SP_ECC
#define WOLFSSL_HAVE_SP_ECC
#undef HAVE_ECC384
#define HAVE_ECC384
#undef WOLFSSL_SP_384
#define WOLFSSL_SP_384
#undef HAVE_ECC521
#define HAVE_ECC521
#undef WOLFSSL_SP_521
#define WOLFSSL_SP_521
#undef WC_NO_ASYNC_THREADING
#define WC_NO_ASYNC_THREADING
#undef HAVE_DH_DEFAULT_PARAMS
#define HAVE_DH_DEFAULT_PARAMS
#undef WOLFSSL_KEY_GEN
#define WOLFSSL_KEY_GEN
#undef WOLFSSL_CERT_REQ
#define WOLFSSL_CERT_REQ
#undef WOLFSSL_CERT_GEN
#define WOLFSSL_CERT_GEN
#undef WOLFSSL_CERT_EXT
#define WOLFSSL_CERT_EXT
#undef HAVE_ED25519
#define HAVE_ED25519
#undef HAVE_OCSP
#define HAVE_OCSP
#undef NO_ERROR_QUEUE
#define NO_ERROR_QUEUE
#undef OPENSSL_ALL
#define OPENSSL_ALL
#undef WOLFSSL_EITHER_SIDE
#define WOLFSSL_EITHER_SIDE
#undef WC_RSA_NO_PADDING
#define WC_RSA_NO_PADDING
#undef WC_RSA_PSS
#define WC_RSA_PSS
#undef WOLFSSL_PSS_LONG_SALT
#define WOLFSSL_PSS_LONG_SALT
#undef WOLFSSL_TICKET_HAVE_ID
#define WOLFSSL_TICKET_HAVE_ID
#undef WOLFSSL_ERROR_CODE_OPENSSL
#define WOLFSSL_ERROR_CODE_OPENSSL
#undef NO_MD5
#define NO_MD5
#undef NO_OLD_TLS
#define NO_OLD_TLS
#undef OPENSSL_EXTRA
#define OPENSSL_EXTRA
#undef WOLFSSL_ALWAYS_VERIFY_CB
#define WOLFSSL_ALWAYS_VERIFY_CB
#undef WOLFSSL_VERIFY_CB_ALL_CERTS
#define WOLFSSL_VERIFY_CB_ALL_CERTS
#undef WOLFSSL_EXTRA_ALERTS
#define WOLFSSL_EXTRA_ALERTS
#undef HAVE_EXT_CACHE
#define HAVE_EXT_CACHE
#undef WOLFSSL_FORCE_CACHE_ON_TICKET
#define WOLFSSL_FORCE_CACHE_ON_TICKET
#undef WOLFSSL_AKID_NAME
#define WOLFSSL_AKID_NAME
#undef HAVE_CTS
#define HAVE_CTS
#undef NO_DES3
#define NO_DES3
#undef GCM_TABLE_4BIT
#define GCM_TABLE_4BIT
#undef HAVE_AESGCM
#define HAVE_AESGCM
#undef HAVE_TLS_EXTENSIONS
#define HAVE_TLS_EXTENSIONS
#undef HAVE_SERVER_RENEGOTIATION_INFO
#define HAVE_SERVER_RENEGOTIATION_INFO
#undef TFM_SMALL_SET
#define TFM_SMALL_SET
#undef TFM_HUGE_SET
#define TFM_HUGE_SET
#undef HAVE___UINT128_T
#define HAVE___UINT128_T 1
#undef HAVE_WC_INTROSPECTION
#define HAVE_WC_INTROSPECTION
#ifdef __cplusplus
}
#endif
#endif /* WOLFSSL_OPTIONS_H */
Hi @Ziemien ,
The SHA256 is on by default unless --disable-sha256 or NO_SHA256 is used.
The issue you are seeing is a data type mismatch trying to call from C++ to C. Specifically the SHA256 to int.
Can you try using WC_SHA256 and casting to (int)? This value comes from an enum, so it is not an int. See sha256.h -> WC_SHA256 = WC_HASH_TYPE_SHA256,.
Thanks, David Garske, wolfSSL
WC_SHA256 works fine (at compile time) but not the SHA256 is suggested in the documentation
Hi @Ziemien ,
The SHA256 was the old / original name. The SHA256 is a macro that maps to WC_SHA256. For some older FIPS releases I think it still uses SHA256. Documentation has been updated here:
https://github.com/wolfSSL/wolfssl/pull/5454
Let me know if you have any additional feedback. Feel free to close this issue if there is nothing further.
Thanks, David Garske, wolfSSL
thank you David