diff --git a/.github/configs/os-check-linux.json b/.github/configs/os-check-linux.json index c979e340128..3593f4bce2f 100644 --- a/.github/configs/os-check-linux.json +++ b/.github/configs/os-check-linux.json @@ -1,4 +1,7 @@ [ +{"name": "all-static", "minutes": 8, + "comment": "Static-only build, so configure defines WOLFSSL_TEST_STATIC_BUILD and the tests that call WOLFSSL_LOCAL functions directly are compiled and run.", + "configure": ["--enable-all", "--enable-static", "--disable-shared"]}, {"name": "user-settings-all-compat", "minutes": 9.5, "comment": "user_settings_all.h with the compatibility layer enabled by flipping its \"#if 0\" block, as a build-dir copy.", "user_settings": "examples/configs/user_settings_all.h", diff --git a/.github/workflows/multi-compiler.yml b/.github/workflows/multi-compiler.yml index 7f22ac21ace..83192380505 100644 --- a/.github/workflows/multi-compiler.yml +++ b/.github/workflows/multi-compiler.yml @@ -101,7 +101,19 @@ jobs: "configure": ["CXX=clang++-19", "CFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference"], "check": false, - "run": [["make", "dist"]]} + "run": [["make", "dist"]]}, + {"name": "clang-19-unreachable-all", "minutes": 2, + "comment": "clang-only -Wunreachable-code-aggressive with --enable-all -- not otherwise tested.", + "cc": "ccache clang-19", + "configure": ["CXX=clang++-19", "--enable-all", + "CFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -Wunreachable-code-aggressive"], + "check": false}, + {"name": "clang-19-unreachable-all-crypto", "minutes": 1.3, + "comment": "As clang-19-unreachable-all, but enable-all-crypto instead of enable-all to exclude OPENSSL_EXTRA, adding coverage without WOLFSSL_SP_INT_NEGATIVE and other settings implicit to enable-all but not enable-all-crypto.", + "cc": "ccache clang-19", + "configure": ["CXX=clang++-19", "--enable-all-crypto", + "CFLAGS=-pedantic -Wdeclaration-after-statement -Wnull-dereference -Wunreachable-code-aggressive"], + "check": false} ] EOF .github/scripts/parallel-make-check.py \ diff --git a/.github/workflows/sanitizer-check.yml b/.github/workflows/sanitizer-check.yml new file mode 100644 index 00000000000..32e8d26956c --- /dev/null +++ b/.github/workflows/sanitizer-check.yml @@ -0,0 +1,80 @@ +name: Sanitized make check + +# START OF COMMON SECTION +on: + push: + branches: [ 'release/**' ] + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + branches: [ '*' ] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read +# END OF COMMON SECTION + +# ASAN/LSAN/UBSAN 'make check' on the full test suite. One runner per config: +# - all-sanitizer : --enable-all under ASAN/LSAN/UBSAN. +# - all-callbacks-sanitizer : ditto plus -DWOLFSSL_CALLBACKS (tested only here). +# +# NO_WOLFSSL_CIPHER_SUITE_TEST and the *_VERIFY_ONLY trio keep the sanitized +# runtime within runner budget, matching the nightly's sanitizer scenarios. + +jobs: + make_check: + strategy: + fail-fast: false + matrix: + include: + - name: all-sanitizer + extra_configure: '' + extra_cppflags: '' + - name: all-callbacks-sanitizer + # WOLFSSL_QUIC is declared incompatible with WOLFSSL_CALLBACKS + # (settings.h #error), and --enable-all enables QUIC. + extra_configure: '--disable-quic' + extra_cppflags: '-DWOLFSSL_CALLBACKS' + name: ${{ matrix.name }} + if: ${{ (github.repository_owner == 'wolfssl') && (github.event_name != 'pull_request' || github.event.pull_request.draft == false) }} + runs-on: ubuntu-24.04 + timeout-minutes: 45 + env: + SANITIZE_FLAGS: >- + -g -fno-omit-frame-pointer + -fsanitize=address,pointer-subtract,leak,undefined,float-cast-overflow,float-divide-by-zero,bounds-strict + -fno-sanitize-recover=all + ASAN_OPTIONS: 'halt_on_error=1:quarantine_size_mb=0:detect_stack_use_after_return=1:check_initialization_order=1:strict_string_checks=1:detect_invalid_pointer_pairs=2' + UBSAN_OPTIONS: 'halt_on_error=1:print_stacktrace=1' + LSAN_OPTIONS: 'halt_on_error=1' + steps: + - uses: actions/checkout@v5 + name: Checkout wolfSSL + + # gcc ASAN's fixed shadow offset can collide with the runner kernel's + # high-entropy mmap ASLR, SEGVing at startup; pin the historic entropy. + - name: Accommodate ASAN shadow memory vs high-entropy ASLR + run: sudo sysctl vm.mmap_rnd_bits=28 + + - name: Build and test + run: | + ./autogen.sh + ./configure --enable-all ${{ matrix.extra_configure }} \ + CFLAGS="$SANITIZE_FLAGS" LDFLAGS="$SANITIZE_FLAGS" \ + CPPFLAGS="-DNO_WOLFSSL_CIPHER_SUITE_TEST -DWOLFSSL_SLHDSA_VERIFY_ONLY -DWOLFSSL_XMSS_VERIFY_ONLY -DWOLFSSL_LMS_VERIFY_ONLY ${{ matrix.extra_cppflags }}" + make -j 4 + make check + + - name: Print errors + if: ${{ failure() }} + run: | + for file in scripts/*.log test-suite.log + do + if [ -f "$file" ]; then + echo "${file}:" + cat "$file" + echo "========================================================================" + fi + done diff --git a/.wolfssl_known_macro_extras b/.wolfssl_known_macro_extras index eda43d37c82..0f5c39a9208 100644 --- a/.wolfssl_known_macro_extras +++ b/.wolfssl_known_macro_extras @@ -969,7 +969,6 @@ WOLFSSL_C2000_ENTROPY_NO_LOCK WOLFSSL_CAAM_BLACK_KEY_AESCCM WOLFSSL_CAAM_BLACK_KEY_SM WOLFSSL_CAAM_NO_BLACK_KEY -WOLFSSL_CALLBACKS WOLFSSL_CHACHA20_AVX512_ALWAYS WOLFSSL_CHACHA20_AVX512_NEVER WOLFSSL_CHACHA20_POLY1305_FUSED_ALWAYS diff --git a/src/internal.c b/src/internal.c index 1bb7232e186..38ed1950295 100644 --- a/src/internal.c +++ b/src/internal.c @@ -3481,7 +3481,7 @@ void wolfSSL_CRYPTO_cleanup_ex_data(WOLFSSL_CRYPTO_EX_DATA* ex_data) #if defined(WOLFSSL_TLS13) && defined(HAVE_ECH) /* free all ech configs in the list */ -void FreeEchConfigs(WOLFSSL_EchConfig* configs, void* heap) +void wolfSSL_local_FreeEchConfigs(WOLFSSL_EchConfig* configs, void* heap) { WOLFSSL_EchConfig* working_config = configs; WOLFSSL_EchConfig* next_config; @@ -3714,7 +3714,7 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx) #endif #endif #if defined(WOLFSSL_TLS13) && defined(HAVE_ECH) - FreeEchConfigs(ctx->echConfigs, ctx->heap); + wolfSSL_local_FreeEchConfigs(ctx->echConfigs, ctx->heap); ctx->echConfigs = NULL; #endif (void)heapAtCTXInit; @@ -10656,6 +10656,14 @@ void wolfSSL_ResourceFree(WOLFSSL* ssl) FreeCiphers(ssl); FreeArrays(ssl, 0); +#ifdef WOLFSSL_CALLBACKS + /* Free buffers allocated by AddPacketInfo(). The _ex handshake entry + * points free them after invoking the timeout callback, but a session + * that records packet info via the msg callback (toInfoOn) without the + * _ex entry points reaches here still holding them. FreeTimeoutInfo() + * nulls the pointers, so the earlier free is safely repeated. */ + FreeTimeoutInfo(&ssl->timeoutInfo, ssl->heap); +#endif /* Defrag buffer for fragmented handshake messages. Lives in WOLFSSL (not * Arrays) so it survives FreeArrays()/FreeHandshakeResources() and can be * used to reassemble post-handshake messages; release it here. */ @@ -10703,11 +10711,11 @@ void wolfSSL_ResourceFree(WOLFSSL* ssl) #if defined(HAVE_ECH) if (ssl->echConfigs != NULL) { - FreeEchConfigs(ssl->echConfigs, ssl->heap); + wolfSSL_local_FreeEchConfigs(ssl->echConfigs, ssl->heap); ssl->echConfigs = NULL; } if (ssl->echRetryConfigs != NULL) { - FreeEchConfigs(ssl->echRetryConfigs, ssl->heap); + wolfSSL_local_FreeEchConfigs(ssl->echRetryConfigs, ssl->heap); ssl->echRetryConfigs = NULL; } #endif /* HAVE_ECH */ diff --git a/src/ssl_ech.c b/src/ssl_ech.c index 5149f51ebd1..923fa0b794d 100644 --- a/src/ssl_ech.c +++ b/src/ssl_ech.c @@ -245,9 +245,9 @@ int wolfSSL_CTX_SetEchConfigs(WOLFSSL_CTX* ctx, const byte* echConfigs, if (ctx == NULL || echConfigs == NULL || echConfigsLen == 0) return BAD_FUNC_ARG; - FreeEchConfigs(ctx->echConfigs, ctx->heap); + wolfSSL_local_FreeEchConfigs(ctx->echConfigs, ctx->heap); ctx->echConfigs = NULL; - ret = SetEchConfigsEx(&ctx->echConfigs, ctx->heap, echConfigs, + ret = wolfSSL_local_SetEchConfigsEx(&ctx->echConfigs, ctx->heap, echConfigs, echConfigsLen); if (ret == 0) @@ -266,7 +266,7 @@ int wolfSSL_CTX_GetEchConfigs(WOLFSSL_CTX* ctx, byte* output, if (ctx->echConfigs == NULL) return WOLFSSL_FATAL_ERROR; - return GetEchConfigsEx(ctx->echConfigs, output, outputLen); + return wolfSSL_local_GetEchConfigsEx(ctx->echConfigs, output, outputLen); } void wolfSSL_CTX_SetEchEnable(WOLFSSL_CTX* ctx, byte enable) @@ -275,7 +275,7 @@ void wolfSSL_CTX_SetEchEnable(WOLFSSL_CTX* ctx, byte enable) ctx->disableECH = !enable; if (ctx->disableECH) { TLSX_Remove(&ctx->extensions, TLSX_ECH, ctx->heap); - FreeEchConfigs(ctx->echConfigs, ctx->heap); + wolfSSL_local_FreeEchConfigs(ctx->echConfigs, ctx->heap); ctx->echConfigs = NULL; } } @@ -329,7 +329,7 @@ int wolfSSL_SetEchConfigs(WOLFSSL* ssl, const byte* echConfigs, return WOLFSSL_FATAL_ERROR; } - ret = SetEchConfigsEx(&ssl->echConfigs, ssl->heap, echConfigs, + ret = wolfSSL_local_SetEchConfigsEx(&ssl->echConfigs, ssl->heap, echConfigs, echConfigsLen); /* if we found valid configs */ @@ -342,7 +342,8 @@ int wolfSSL_SetEchConfigs(WOLFSSL* ssl, const byte* echConfigs, /* store retry configs received during ECH rejection * returns 0 on success, error otherwise */ -int SetRetryConfigs(WOLFSSL* ssl, const byte* echConfigs, word32 echConfigsLen) +int wolfSSL_local_SetRetryConfigs(WOLFSSL* ssl, const byte* echConfigs, + word32 echConfigsLen) { int ret; @@ -353,14 +354,15 @@ int SetRetryConfigs(WOLFSSL* ssl, const byte* echConfigs, word32 echConfigsLen) return WOLFSSL_FATAL_ERROR; } - ret = SetEchConfigsEx(&ssl->echRetryConfigs, ssl->heap, echConfigs, - echConfigsLen); + ret = wolfSSL_local_SetEchConfigsEx(&ssl->echRetryConfigs, ssl->heap, + echConfigs, echConfigsLen); return ret; } /* get the raw ech config from our struct */ -int GetEchConfig(WOLFSSL_EchConfig* config, byte* output, word32* outputLen) +int wolfSSL_local_GetEchConfig(WOLFSSL_EchConfig* config, byte* output, + word32* outputLen) { int i; word16 totalLen = 0; @@ -479,7 +481,7 @@ int wolfSSL_GetEchConfigs(WOLFSSL* ssl, byte* output, word32* outputLen) return WOLFSSL_FATAL_ERROR; } - return GetEchConfigsEx(ssl->echConfigs, output, outputLen); + return wolfSSL_local_GetEchConfigsEx(ssl->echConfigs, output, outputLen); } /* wrapper function to get retry configs @@ -494,7 +496,8 @@ int wolfSSL_GetEchRetryConfigs(WOLFSSL* ssl, byte* output, word32* outputLen) return WOLFSSL_FATAL_ERROR; } - return GetEchConfigsEx(ssl->echRetryConfigs, output, outputLen); + return wolfSSL_local_GetEchConfigsEx(ssl->echRetryConfigs, output, + outputLen); } void wolfSSL_SetEchEnable(WOLFSSL* ssl, byte enable) @@ -503,7 +506,7 @@ void wolfSSL_SetEchEnable(WOLFSSL* ssl, byte enable) ssl->options.disableECH = !enable; if (ssl->options.disableECH) { TLSX_Remove(&ssl->extensions, TLSX_ECH, ssl->heap); - FreeEchConfigs(ssl->echConfigs, ssl->heap); + wolfSSL_local_FreeEchConfigs(ssl->echConfigs, ssl->heap); ssl->echConfigs = NULL; } } @@ -603,7 +606,7 @@ static int EchConfigCheckExtensions(const byte* exts, word16 extsLen) /* Parse the ECH configs and output to the corresponding outputConfigs * return 0 on success, error otherwise */ -int SetEchConfigsEx(WOLFSSL_EchConfig** outputConfigs, void* heap, +int wolfSSL_local_SetEchConfigsEx(WOLFSSL_EchConfig** outputConfigs, void* heap, const byte* echConfigs, word32 echConfigsLen) { int ret = 0; @@ -850,7 +853,8 @@ int SetEchConfigsEx(WOLFSSL_EchConfig** outputConfigs, void* heap, } /* get the raw ech configs from our linked list of ech config structs */ -int GetEchConfigsEx(WOLFSSL_EchConfig* configs, byte* output, word32* outputLen) +int wolfSSL_local_GetEchConfigsEx(WOLFSSL_EchConfig* configs, byte* output, + word32* outputLen) { int ret = 0; WOLFSSL_EchConfig* workingConfig = NULL; @@ -877,7 +881,8 @@ int GetEchConfigsEx(WOLFSSL_EchConfig* configs, byte* output, word32* outputLen) while (workingConfig != NULL) { /* get this config */ - ret = GetEchConfig(workingConfig, output, &workingOutputLen); + ret = wolfSSL_local_GetEchConfig(workingConfig, output, + &workingOutputLen); if (output != NULL) output += workingOutputLen; diff --git a/src/tls.c b/src/tls.c index 77169d821d6..12d4f8aeb6f 100644 --- a/src/tls.c +++ b/src/tls.c @@ -14764,10 +14764,11 @@ static int TLSX_ECH_Write(WOLFSSL_ECH* ech, byte msgType, byte* writeBuf, return 0; if (ech->state == ECH_WRITE_RETRY_CONFIGS) { /* get size then write */ - ret = GetEchConfigsEx(ech->echConfig, NULL, &configsLen); + ret = wolfSSL_local_GetEchConfigsEx(ech->echConfig, NULL, &configsLen); if (ret != WC_NO_ERR_TRACE(LENGTH_ONLY_E)) return ret; - ret = GetEchConfigsEx(ech->echConfig, writeBuf, &configsLen); + ret = wolfSSL_local_GetEchConfigsEx(ech->echConfig, writeBuf, + &configsLen); if (ret != WOLFSSL_SUCCESS) return ret; *offset += configsLen; @@ -14895,7 +14896,7 @@ static int TLSX_ECH_GetSize(WOLFSSL_ECH* ech, byte msgType) } else if (ech->state == ECH_WRITE_RETRY_CONFIGS) { /* get the size of the raw configs */ - ret = GetEchConfigsEx(ech->echConfig, NULL, &size); + ret = wolfSSL_local_GetEchConfigsEx(ech->echConfig, NULL, &size); if (ret != WC_NO_ERR_TRACE(LENGTH_ONLY_E)) return ret; @@ -15419,7 +15420,7 @@ static int TLSX_ExtractEch(WOLFSSL* ssl, WOLFSSL_ECH* ech, } /* get the rawConfigLen */ if (ret == 0) - ret = GetEchConfig(echConfig, NULL, &rawConfigLen); + ret = wolfSSL_local_GetEchConfig(echConfig, NULL, &rawConfigLen); if (ret == WC_NO_ERR_TRACE(LENGTH_ONLY_E)) ret = 0; /* create info */ @@ -15432,7 +15433,7 @@ static int TLSX_ExtractEch(WOLFSSL* ssl, WOLFSSL_ECH* ech, else { XMEMCPY(info, (byte*)TLS_INFO_CONST_STRING, TLS_INFO_CONST_STRING_SZ + 1); - ret = GetEchConfig(echConfig, info + + ret = wolfSSL_local_GetEchConfig(echConfig, info + TLS_INFO_CONST_STRING_SZ + 1, &rawConfigLen); } } @@ -15519,7 +15520,7 @@ static int TLSX_ECH_Parse(WOLFSSL* ssl, const byte* readBuf, word16 size, return UNSUPPORTED_EXTENSION; } - ret = SetRetryConfigs(ssl, readBuf, (word32)size); + ret = wolfSSL_local_SetRetryConfigs(ssl, readBuf, (word32)size); if (ret == WC_NO_ERR_TRACE(UNSUPPORTED_SUITE) || ret == WC_NO_ERR_TRACE(UNSUPPORTED_PROTO_VERSION)) { WOLFSSL_MSG("ECH retry configs had 'bad version' or 'bad suite'"); @@ -15529,7 +15530,7 @@ static int TLSX_ECH_Parse(WOLFSSL* ssl, const byte* readBuf, word16 size, if (ssl->echConfigs == NULL) { /* on GREASE connection configs must be checked syntactically and * must not be saved (RFC 9849, Section 6.2.1) */ - FreeEchConfigs(ssl->echRetryConfigs, ssl->heap); + wolfSSL_local_FreeEchConfigs(ssl->echRetryConfigs, ssl->heap); ssl->echRetryConfigs = NULL; } diff --git a/tests/api/test_ssl_ext.c b/tests/api/test_ssl_ext.c index ccde7ad785d..8a1e25dc796 100644 --- a/tests/api/test_ssl_ext.c +++ b/tests/api/test_ssl_ext.c @@ -2761,8 +2761,7 @@ int test_ech_decision_coverage(void) { EXPECT_DECLS; #if defined(HAVE_ECH) && defined(WOLFSSL_TLS13) && \ - !defined(WOLFCRYPT_ONLY) && !defined(NO_WOLFSSL_CLIENT) && \ - defined(WOLFSSL_TEST_STATIC_BUILD) + !defined(WOLFCRYPT_ONLY) && !defined(NO_WOLFSSL_CLIENT) WOLFSSL_CTX* ctx = NULL; WOLFSSL* ssl = NULL; WOLFSSL_EchConfig cfg; @@ -2776,26 +2775,29 @@ int test_ech_decision_coverage(void) ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method())); ExpectNotNull(ssl = wolfSSL_new(ctx)); - /* --- 349:0/1/2 SetRetryConfigs: ssl==NULL || configs==NULL || len==0 -- */ - (void)SetRetryConfigs(NULL, buf, sizeof(buf)); - (void)SetRetryConfigs(ssl, NULL, sizeof(buf)); - (void)SetRetryConfigs(ssl, buf, 0); - (void)SetRetryConfigs(ssl, buf, sizeof(buf)); - - /* --- 370:0/1/2 GetEchConfig: config==NULL || (out==NULL&&outLen==NULL) */ - (void)GetEchConfig(NULL, out, &outLen); - (void)GetEchConfig(&cfg, NULL, NULL); - (void)GetEchConfig(&cfg, out, &outLen); - - /* --- 626:0/1/2 SetEchConfigsEx: outCfg==NULL || cfgs==NULL || len<2 --- */ - (void)SetEchConfigsEx(NULL, ssl->heap, buf, sizeof(buf)); - (void)SetEchConfigsEx(&outCfg, ssl->heap, NULL, sizeof(buf)); - (void)SetEchConfigsEx(&outCfg, ssl->heap, buf, 1); - - /* --- 861:0/1/2 GetEchConfigsEx: cfgs==NULL || outLen==NULL || too small */ - (void)GetEchConfigsEx(NULL, out, &outLen); - (void)GetEchConfigsEx(&cfg, out, NULL); - (void)GetEchConfigsEx(&cfg, out, &outLen); + if (ssl != NULL) { + /* wolfSSL_local_SetRetryConfigs: ssl==NULL || configs==NULL || len==0 */ + (void)wolfSSL_local_SetRetryConfigs(NULL, buf, sizeof(buf)); + (void)wolfSSL_local_SetRetryConfigs(ssl, NULL, sizeof(buf)); + (void)wolfSSL_local_SetRetryConfigs(ssl, buf, 0); + (void)wolfSSL_local_SetRetryConfigs(ssl, buf, sizeof(buf)); + + /* wolfSSL_local_GetEchConfig: config==NULL || (out==NULL&&outLen==NULL) */ + (void)wolfSSL_local_GetEchConfig(NULL, out, &outLen); + (void)wolfSSL_local_GetEchConfig(&cfg, NULL, NULL); + (void)wolfSSL_local_GetEchConfig(&cfg, out, &outLen); + + /* wolfSSL_local_SetEchConfigsEx: outCfg==NULL || cfgs==NULL || len<2 */ + (void)wolfSSL_local_SetEchConfigsEx(NULL, ssl->heap, buf, sizeof(buf)); + (void)wolfSSL_local_SetEchConfigsEx(&outCfg, ssl->heap, NULL, + sizeof(buf)); + (void)wolfSSL_local_SetEchConfigsEx(&outCfg, ssl->heap, buf, 1); + + /* wolfSSL_local_GetEchConfigsEx: cfgs==NULL || outLen==NULL || too small */ + (void)wolfSSL_local_GetEchConfigsEx(NULL, out, &outLen); + (void)wolfSSL_local_GetEchConfigsEx(&cfg, out, NULL); + (void)wolfSSL_local_GetEchConfigsEx(&cfg, out, &outLen); + } wolfSSL_free(ssl); wolfSSL_CTX_free(ctx); diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 0df1111b280..455e1f3f0fa 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2010,8 +2010,8 @@ WOLFSSL_LOCAL int NamedGroupIsPqcHybrid(int group); #define WOLFSSL_NAMED_GROUP_IS_PQC(group) NamedGroupIsPqc(group) #define WOLFSSL_NAMED_GROUP_IS_PQC_HYBRID(group) NamedGroupIsPqcHybrid(group) #else -#define WOLFSSL_NAMED_GROUP_IS_PQC(group) ((void)(group), 0) -#define WOLFSSL_NAMED_GROUP_IS_PQC_HYBRID(group) ((void)(group), 0) +#define WOLFSSL_NAMED_GROUP_IS_PQC(group) 0 +#define WOLFSSL_NAMED_GROUP_IS_PQC_HYBRID(group) 0 #endif /* WOLFSSL_HAVE_MLKEM */ /* minimum Downgrade Minor version */ @@ -3588,19 +3588,21 @@ WOLFSSL_TEST_VIS int TLSX_EchSwapExtensions(TLSX** sslExts, TLSX** echExts, WOLFSSL_TEST_VIS int TLSX_ServerECH_Use(TLSX** extensions, void* heap, WOLFSSL_EchConfig* configs); -WOLFSSL_LOCAL int SetEchConfigsEx(WOLFSSL_EchConfig** outputConfigs, void* heap, +WOLFSSL_TEST_VIS int wolfSSL_local_SetEchConfigsEx( + WOLFSSL_EchConfig** outputConfigs, void* heap, const byte* echConfigs, word32 echConfigsLen); -WOLFSSL_LOCAL int GetEchConfig(WOLFSSL_EchConfig* config, byte* output, - word32* outputLen); +WOLFSSL_TEST_VIS int wolfSSL_local_GetEchConfig(WOLFSSL_EchConfig* config, + byte* output, word32* outputLen); -WOLFSSL_LOCAL int GetEchConfigsEx(WOLFSSL_EchConfig* configs, +WOLFSSL_TEST_VIS int wolfSSL_local_GetEchConfigsEx(WOLFSSL_EchConfig* configs, byte* output, word32* outputLen); -WOLFSSL_LOCAL void FreeEchConfigs(WOLFSSL_EchConfig* configs, void* heap); +WOLFSSL_TEST_VIS void wolfSSL_local_FreeEchConfigs(WOLFSSL_EchConfig* configs, + void* heap); -WOLFSSL_LOCAL int SetRetryConfigs(WOLFSSL* ssl, const byte* echConfigs, - word32 echConfigsLen); +WOLFSSL_TEST_VIS int wolfSSL_local_SetRetryConfigs(WOLFSSL* ssl, + const byte* echConfigs, word32 echConfigsLen); WOLFSSL_LOCAL int EchRejected(const WOLFSSL* ssl); #endif