From 1929dc5a0a7c1dc3967513520eeba437d5eb6c20 Mon Sep 17 00:00:00 2001 From: Kareem Date: Thu, 7 May 2026 15:55:27 -0700 Subject: [PATCH 1/5] In Tls13_Exporter, check all length arguments before casting and using them. Thanks to Cal Page for the report. --- src/tls13.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/tls13.c b/src/tls13.c index 794e3e068d..803bcf77fe 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -995,6 +995,18 @@ int Tls13_Exporter(WOLFSSL* ssl, unsigned char *out, size_t outLen, } #endif /* WOLFSSL_DTLS13 */ + /* Sanity check contextLen to prevent truncation when cast to word32. */ + if (contextLen > WOLFSSL_MAX_32BIT) + return BAD_FUNC_ARG; + /* RFC 8446 HkdfLabel encodes the output length as a uint16, so requested + * lengths > 65535 cannot be represented and must be rejected. */ + if (outLen > WOLFSSL_MAX_16BIT) + return BAD_FUNC_ARG; + /* RFC 8446 HkdfLabel encodes the label length in a single byte, so + * anything > 255 cannot be represented and must be rejected. */ + if (labelLen > (WOLFSSL_MAX_8BIT - protocolLen)) + return BAD_FUNC_ARG; + switch (ssl->specs.mac_algorithm) { #ifndef NO_SHA256 case sha256_mac: @@ -1040,11 +1052,6 @@ int Tls13_Exporter(WOLFSSL* ssl, unsigned char *out, size_t outLen, if (ret != 0) return ret; - /* Sanity check contextLen to prevent truncation when cast to word32. */ - if (contextLen > WOLFSSL_MAX_32BIT) { - return BAD_FUNC_ARG; - } - /* Hash(context_value) */ ret = wc_Hash(hashType, context, (word32)contextLen, hashOut, WC_MAX_DIGEST_SIZE); if (ret != 0) From e4a8723501ab580031deea05f72465d3f8923ada Mon Sep 17 00:00:00 2001 From: Kareem Date: Thu, 7 May 2026 15:56:52 -0700 Subject: [PATCH 2/5] In DoTls13CertificateRequest, avoid assigned the CertReqCtx to the SSL object until the function has finished. This avoids ssl->certReqCtx being set when the function returns an error. Thanks to Cal Page for the report. --- src/tls13.c | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/src/tls13.c b/src/tls13.c index 803bcf77fe..ca62390c81 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -6053,7 +6053,8 @@ static int DoTls13CertificateRequest(WOLFSSL* ssl, const byte* input, int ret = 0; Suites peerSuites; #ifdef WOLFSSL_POST_HANDSHAKE_AUTH - CertReqCtx* certReqCtx; + word16 reqCtxLen; + const byte* reqCtxData; #endif WOLFSSL_START(WC_FUNC_CERTIFICATE_REQUEST_DO); @@ -6077,18 +6078,12 @@ static int DoTls13CertificateRequest(WOLFSSL* ssl, const byte* input, return BUFFER_ERROR; #ifdef WOLFSSL_POST_HANDSHAKE_AUTH - /* CertReqCtx has one byte at end for context value. - * Increase size to handle other implementations sending more than one byte. - * That is, allocate extra space, over one byte, to hold the context value. + /* Remember the request context bytes; the CertReqCtx allocation and + * linking into ssl->certReqCtx is deferred until after the rest of the + * message has been validated. */ - certReqCtx = (CertReqCtx*)XMALLOC(sizeof(CertReqCtx) + (len == 0 ? 0 : len - 1), ssl->heap, - DYNAMIC_TYPE_TMP_BUFFER); - if (certReqCtx == NULL) - return MEMORY_E; - certReqCtx->next = ssl->certReqCtx; - certReqCtx->len = len; - XMEMCPY(&certReqCtx->ctx, input + *inOutIdx, len); - ssl->certReqCtx = certReqCtx; + reqCtxLen = len; + reqCtxData = input + *inOutIdx; #endif *inOutIdx += len; @@ -6155,6 +6150,24 @@ static int DoTls13CertificateRequest(WOLFSSL* ssl, const byte* input, /* This message is always encrypted so add encryption padding. */ *inOutIdx += ssl->keys.padSz; +#ifdef WOLFSSL_POST_HANDSHAKE_AUTH + { + /* CertReqCtx has one byte at end for context value. + * Increase size to handle other implementations sending more than one byte. + * That is, allocate extra space, over one byte, to hold the context value. + */ + CertReqCtx* certReqCtx = (CertReqCtx*)XMALLOC( + sizeof(CertReqCtx) + (reqCtxLen == 0 ? 0 : reqCtxLen - 1), + ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (certReqCtx == NULL) + return MEMORY_E; + certReqCtx->next = ssl->certReqCtx; + certReqCtx->len = reqCtxLen; + XMEMCPY(&certReqCtx->ctx, reqCtxData, reqCtxLen); + ssl->certReqCtx = certReqCtx; + } +#endif + WOLFSSL_LEAVE("DoTls13CertificateRequest", ret); WOLFSSL_END(WC_FUNC_CERTIFICATE_REQUEST_DO); From 3851fad1f04d11904ac70a98155d9db5ff911b2d Mon Sep 17 00:00:00 2001 From: Kareem Date: Thu, 7 May 2026 15:57:47 -0700 Subject: [PATCH 3/5] NULL check wolfSSL_get_cipher_name_by_hash arguments. Thanks to Cal Page for the report. --- src/tls13.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/tls13.c b/src/tls13.c index ca62390c81..35f1e4dd15 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -15147,7 +15147,15 @@ const char* wolfSSL_get_cipher_name_by_hash(WOLFSSL* ssl, const char* hash) const char* name = NULL; byte mac = no_mac; int i; - const Suites* suites = WOLFSSL_SUITES(ssl); + const Suites* suites; + + if (hash == NULL || ssl == NULL || + (ssl->suites == NULL && ssl->ctx == NULL)) + return NULL; + + suites = WOLFSSL_SUITES(ssl); + if (suites == NULL) + return NULL; if (XSTRCMP(hash, "SHA256") == 0) { mac = sha256_mac; From 2d8d51154082a19e654642068a1784c42d2bdc48 Mon Sep 17 00:00:00 2001 From: Kareem Date: Thu, 7 May 2026 16:10:47 -0700 Subject: [PATCH 4/5] Add configure and CMake options for WOLF_CRYPTO_CB_RSA_PAD. Fixes #10271. --- CMakeLists.txt | 11 +++++++++++ cmake/options.h.in | 2 ++ configure.ac | 18 ++++++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index b9157ec0ab..42b683d005 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2243,6 +2243,10 @@ add_option("WOLFSSL_CRYPTOCB_NO_SW_TEST" "Disable crypto callback SW testing (default: disabled)" "no" "yes;no") +add_option("WOLFSSL_CRYPTOCB_RSA_PAD" + "Enable RSA padding aware crypto callbacks (default: disabled)" + "no" "yes;no") + add_option("WOLFSSL_PKCALLBACKS" "Enable public key callbacks (default: disabled)" "no" "yes;no") @@ -2475,6 +2479,13 @@ if(WOLFSSL_CRYPTOCB_NO_SW_TEST) list(APPEND WOLFSSL_DEFINITIONS "-DWC_TEST_NO_CRYPTOCB_SW_TEST") endif() +if(WOLFSSL_CRYPTOCB_RSA_PAD) + if(NOT WOLFSSL_CRYPTOCB) + message(FATAL_ERROR "WOLFSSL_CRYPTOCB_RSA_PAD requires WOLFSSL_CRYPTOCB") + endif() + list(APPEND WOLFSSL_DEFINITIONS "-DWOLF_CRYPTO_CB_RSA_PAD") +endif() + # Public Key Callbacks if(WOLFSSL_PKCALLBACKS) list(APPEND WOLFSSL_DEFINITIONS "-DHAVE_PK_CALLBACKS") diff --git a/cmake/options.h.in b/cmake/options.h.in index 1fe054b276..fd6f0bee30 100644 --- a/cmake/options.h.in +++ b/cmake/options.h.in @@ -258,6 +258,8 @@ extern "C" { #cmakedefine WC_RSA_PSS #undef WOLF_CRYPTO_CB #cmakedefine WOLF_CRYPTO_CB +#undef WOLF_CRYPTO_CB_RSA_PAD +#cmakedefine WOLF_CRYPTO_CB_RSA_PAD #undef WOLFSSL_AARCH64_BUILD #cmakedefine WOLFSSL_AARCH64_BUILD #undef WOLFSSL_AES_CFB diff --git a/configure.ac b/configure.ac index 13ef19b886..6d8d186757 100644 --- a/configure.ac +++ b/configure.ac @@ -10622,6 +10622,24 @@ if test "$ENABLED_CRYPTOCB_UTILS" != "no"; then fi fi +# Crypto callback RSA padding support +# When enabled, the RSA crypto callback args struct exposes the RsaPadding +# parameters so the callback can perform RSA padding/unpadding itself or +# offload it together with the modular exponentiation. +AC_ARG_ENABLE([cryptocb-rsa-pad], + [AS_HELP_STRING([--enable-cryptocb-rsa-pad],[Enable RSA padding aware crypto callbacks (default: disabled). Requires --enable-cryptocb])], + [ ENABLED_CRYPTOCB_RSA_PAD=$enableval ], + [ ENABLED_CRYPTOCB_RSA_PAD=no ] + ) + +if test "$ENABLED_CRYPTOCB_RSA_PAD" = "yes" +then + if test "x$ENABLED_CRYPTOCB" = "xno"; then + AC_MSG_ERROR([--enable-cryptocb-rsa-pad requires --enable-cryptocb]) + fi + AM_CFLAGS="$AM_CFLAGS -DWOLF_CRYPTO_CB_RSA_PAD" +fi + # Asynchronous Crypto AC_ARG_ENABLE([asynccrypt], From 28de528dcee91abc3214942348e20f817e7b45b6 Mon Sep 17 00:00:00 2001 From: Kareem Date: Thu, 7 May 2026 16:38:18 -0700 Subject: [PATCH 5/5] Code review feedback --- src/tls13.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/tls13.c b/src/tls13.c index 35f1e4dd15..602aea32ac 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -1003,8 +1003,9 @@ int Tls13_Exporter(WOLFSSL* ssl, unsigned char *out, size_t outLen, if (outLen > WOLFSSL_MAX_16BIT) return BAD_FUNC_ARG; /* RFC 8446 HkdfLabel encodes the label length in a single byte, so - * anything > 255 cannot be represented and must be rejected. */ - if (labelLen > (WOLFSSL_MAX_8BIT - protocolLen)) + * anything > 255 cannot be represented and must be rejected. + * The protocol length is included in the label. */ + if ((labelLen + protocolLen) > WOLFSSL_MAX_8BIT) return BAD_FUNC_ARG; switch (ssl->specs.mac_algorithm) {