diff --git a/CMakeLists.txt b/CMakeLists.txt index b9157ec0ab4..42b683d005c 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 1fe054b276f..fd6f0bee309 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 7a9ec151d13..e45e32bbac7 100644 --- a/configure.ac +++ b/configure.ac @@ -10512,6 +10512,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], diff --git a/src/tls13.c b/src/tls13.c index 794e3e068da..602aea32ac5 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -995,6 +995,19 @@ 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. + * The protocol length is included in the label. */ + if ((labelLen + protocolLen) > WOLFSSL_MAX_8BIT) + return BAD_FUNC_ARG; + switch (ssl->specs.mac_algorithm) { #ifndef NO_SHA256 case sha256_mac: @@ -1040,11 +1053,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) @@ -6046,7 +6054,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); @@ -6070,18 +6079,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; @@ -6148,6 +6151,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); @@ -15127,7 +15148,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;