Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion .github/workflows/os-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,14 @@ jobs:
'CPPFLAGS=-DNO_WOLFSSL_CLIENT',
'CPPFLAGS=-DNO_WOLFSSL_SERVER',
'--enable-lms=small,verify-only --enable-xmss=small,verify-only',
'--enable-curve25519=nonblock --enable-ecc=nonblock --enable-sp=yes,nonblock CPPFLAGS="-DWOLFSSL_PUBLIC_MP -DWOLFSSL_DEBUG_NONBLOCK"',
# Non-blocking ECC + Curve25519 + RSA + DH on the default SP word
# size for the host (sp_c64.c on x86_64). RSA/DH non-block require
# RSA_LOW_MEM (CRT path is not supported in non-block mode).
'--enable-curve25519=nonblock --enable-ecc=nonblock --enable-rsa=nonblock --enable-dh=nonblock --enable-sp=yes,nonblock CPPFLAGS="-DWOLFSSL_PUBLIC_MP -DWOLFSSL_DEBUG_NONBLOCK -DRSA_LOW_MEM"',
# Same configuration but force SP_WORD_SIZE=32 to exercise sp_c32.c
# on a 64-bit host. The two builds together cover both generated
# variants of mod_exp_<words>_nb / RSA / DH wrappers.
'--enable-curve25519=nonblock --enable-ecc=nonblock --enable-rsa=nonblock --enable-dh=nonblock --enable-sp=yes,nonblock CPPFLAGS="-DWOLFSSL_PUBLIC_MP -DWOLFSSL_DEBUG_NONBLOCK -DRSA_LOW_MEM -DSP_WORD_SIZE=32"',
'--enable-certreq --enable-certext --enable-certgen --disable-secure-renegotiation-info CPPFLAGS="-DNO_TLS"',
]
name: make check linux
Expand Down
1 change: 0 additions & 1 deletion .wolfssl_known_macro_extras
Original file line number Diff line number Diff line change
Expand Up @@ -666,7 +666,6 @@ WC_PROTECT_ENCRYPTED_MEM
WC_PUF_SHA3
WC_RNG_BANK_NO_DEFAULT_SUPPORT
WC_RNG_BLOCKING
WC_RSA_NONBLOCK
WC_RSA_NONBLOCK_TIME
WC_RSA_NO_FERMAT_CHECK
WC_RWLOCK_OPS_INLINE
Expand Down
29 changes: 27 additions & 2 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -4880,6 +4880,15 @@ then
test -z "$enable_asynccrypt_sw" && enable_asynccrypt_sw=yes
fi

# Handle RSA/DH nonblock - the SP non-blocking dispatch wants the same
# WOLFSSL_ASYNC_CRYPT_SW shim that ECC/Curve25519 nonblock use so the
# TLS layer can manage per-SSL nb contexts and yield MP_WOULDBLOCK.
if test "$enable_rsa" = "nonblock" || test "$enable_dh" = "nonblock"
then
test -z "$enable_asynccrypt" && enable_asynccrypt=yes
test -z "$enable_asynccrypt_sw" && enable_asynccrypt_sw=yes
fi

if test "$ENABLED_CURVE25519" = "no" && test "$ENABLED_QUIC" = "yes" && test "$ENABLED_FIPS" = "no"
then
ENABLED_CURVE25519=yes
Expand Down Expand Up @@ -5396,14 +5405,25 @@ fi

# RSA
AC_ARG_ENABLE([rsa],
[AS_HELP_STRING([--enable-rsa],[Enable RSA (default: enabled)])],
[AS_HELP_STRING([--enable-rsa],[Enable RSA (default: enabled). Set to "nonblock" to enable non-blocking RSA via TFM fp_exptmod_nb or SP small mod_exp_nb])],
[ ENABLED_RSA=$enableval ],
[ ENABLED_RSA=yes ]
)

if test "$ENABLED_RSA" = "no"
then
AM_CFLAGS="$AM_CFLAGS -DNO_RSA"
elif test "$ENABLED_RSA" = "nonblock"
then
AM_CFLAGS="$AM_CFLAGS -DWC_RSA_NONBLOCK"
ENABLED_RSA=yes
ENABLED_CERTS=yes
# asynccrypt + asynccrypt-sw are auto-enabled earlier in this file when
# --enable-rsa=nonblock is detected, so the TLS layer can pick up the
# per-SSL nb context and yield MP_WOULDBLOCK. RSA_LOW_MEM is left as a
# user choice - the SP non-block backend's compile-time check in
# wolfssl/wolfcrypt/rsa.h enforces it for SP, while the TFM (fastmath)
# backend supports the CRT path without it.
else
# turn off RSA if leanpsk or leantls on
if test "$ENABLED_LEANPSK" = "yes" || test "$ENABLED_LEANTLS" = "yes"
Expand Down Expand Up @@ -5483,7 +5503,7 @@ fi

# DH
AC_ARG_ENABLE([dh],
[AS_HELP_STRING([--enable-dh],[Enable DH (default: enabled)])],
[AS_HELP_STRING([--enable-dh],[Enable DH (default: enabled). Set to "nonblock" to enable non-blocking DH key agreement via SP small mod_exp_nb])],
[ ENABLED_DH=$enableval ],
[ ENABLED_DH=yes ]
)
Expand All @@ -5496,6 +5516,11 @@ fi
if test "$ENABLED_DH" = "no"
then
AM_CFLAGS="$AM_CFLAGS -DNO_DH"
elif test "$ENABLED_DH" = "nonblock"
then
AM_CFLAGS="$AM_CFLAGS -DWC_DH_NONBLOCK"
ENABLED_DH=yes
# asynccrypt + asynccrypt-sw are auto-enabled earlier in this file.
else
# turn off DH if leanpsk or leantls on
if test "$ENABLED_LEANPSK" = "yes" || test "$ENABLED_LEANTLS" = "yes"
Expand Down
66 changes: 66 additions & 0 deletions src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -8300,6 +8300,15 @@ void FreeKey(WOLFSSL* ssl, int type, void** pKey)
switch (type) {
#ifndef NO_RSA
case DYNAMIC_TYPE_RSA:
#if defined(WC_RSA_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
defined(WC_ASYNC_ENABLE_RSA)
if (((RsaKey*)*pKey)->nb != NULL) {
XFREE(((RsaKey*)*pKey)->nb, ssl->heap,
DYNAMIC_TYPE_TMP_BUFFER);
((RsaKey*)*pKey)->nb = NULL;
}
#endif /* WC_RSA_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW &&
WC_ASYNC_ENABLE_RSA */
wc_FreeRsaKey((RsaKey*)*pKey);
break;
#endif /* ! NO_RSA */
Expand Down Expand Up @@ -8355,6 +8364,15 @@ void FreeKey(WOLFSSL* ssl, int type, void** pKey)
#endif /* HAVE_DILITHIUM */
#ifndef NO_DH
case DYNAMIC_TYPE_DH:
#if defined(WC_DH_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
defined(WC_ASYNC_ENABLE_DH)
if (((DhKey*)*pKey)->nb != NULL) {
XFREE(((DhKey*)*pKey)->nb, ssl->heap,
DYNAMIC_TYPE_TMP_BUFFER);
((DhKey*)*pKey)->nb = NULL;
}
#endif /* WC_DH_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW &&
WC_ASYNC_ENABLE_DH */
wc_FreeDhKey((DhKey*)*pKey);
break;
#endif /* !NO_DH */
Expand Down Expand Up @@ -8385,6 +8403,14 @@ int AllocKey(WOLFSSL* ssl, int type, void** pKey)
#if defined(WC_X25519_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW)
x25519_nb_ctx_t* x25519NbCtx;
#endif /* WC_X25519_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW */
#if !defined(NO_RSA) && defined(WC_RSA_NONBLOCK) && \
defined(WOLFSSL_ASYNC_CRYPT_SW) && defined(WC_ASYNC_ENABLE_RSA)
RsaNb* rsaNb;
#endif
#if !defined(NO_DH) && defined(WC_DH_NONBLOCK) && \
defined(WOLFSSL_ASYNC_CRYPT_SW) && defined(WC_ASYNC_ENABLE_DH)
DhNb* dhNb;
#endif

if (ssl == NULL || pKey == NULL) {
return BAD_FUNC_ARG;
Expand Down Expand Up @@ -8464,6 +8490,26 @@ int AllocKey(WOLFSSL* ssl, int type, void** pKey)
#ifndef NO_RSA
case DYNAMIC_TYPE_RSA:
ret = wc_InitRsaKey_ex((RsaKey*)*pKey, ssl->heap, ssl->devId);
#if defined(WC_RSA_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
defined(WC_ASYNC_ENABLE_RSA)
/* Only set non-blocking context when async device is active. With
* INVALID_DEVID there is no async loop to retry on MP_WOULDBLOCK, so
* skip non-blocking setup and use blocking mode instead. */
if (ret == 0 && ssl->devId != INVALID_DEVID) {
rsaNb = (RsaNb*)XMALLOC(sizeof(RsaNb), ssl->heap,
DYNAMIC_TYPE_TMP_BUFFER);
if (rsaNb == NULL) {
ret = MEMORY_E;
}
else {
ret = wc_RsaSetNonBlock((RsaKey*)*pKey, rsaNb);
if (ret != 0) {
XFREE(rsaNb, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
}
}
}
#endif /* WC_RSA_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW &&
WC_ASYNC_ENABLE_RSA */
break;
#endif /* ! NO_RSA */
#ifdef HAVE_ECC
Expand Down Expand Up @@ -8551,6 +8597,26 @@ int AllocKey(WOLFSSL* ssl, int type, void** pKey)
#ifndef NO_DH
case DYNAMIC_TYPE_DH:
ret = wc_InitDhKey_ex((DhKey*)*pKey, ssl->heap, ssl->devId);
#if defined(WC_DH_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
defined(WC_ASYNC_ENABLE_DH)
/* Only set non-blocking context when async device is active. With
* INVALID_DEVID there is no async loop to retry on MP_WOULDBLOCK, so
* skip non-blocking setup and use blocking mode instead. */
if (ret == 0 && ssl->devId != INVALID_DEVID) {
dhNb = (DhNb*)XMALLOC(sizeof(DhNb), ssl->heap,
DYNAMIC_TYPE_TMP_BUFFER);
if (dhNb == NULL) {
ret = MEMORY_E;
}
else {
ret = wc_DhSetNonBlock((DhKey*)*pKey, dhNb);
if (ret != 0) {
XFREE(dhNb, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
}
}
}
#endif /* WC_DH_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW &&
WC_ASYNC_ENABLE_DH */
break;
#endif /* !NO_DH */
default:
Expand Down
69 changes: 67 additions & 2 deletions src/tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -8010,6 +8010,26 @@ static int TLSX_KeyShare_GenDhKey(WOLFSSL *ssl, KeyShareEntry* kse)
ret = wc_DhSetNamedKey(dhKey, kse->group);
#endif
}
#if defined(WC_DH_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
defined(WC_ASYNC_ENABLE_DH)
/* Only set non-blocking context when async device is active. With
* INVALID_DEVID there is no async loop to retry on MP_WOULDBLOCK, so
* skip non-blocking setup and use blocking mode instead. */
if (ret == 0 && ssl->devId != INVALID_DEVID) {
DhNb* dhNb = (DhNb*)XMALLOC(sizeof(DhNb), ssl->heap,
DYNAMIC_TYPE_TMP_BUFFER);
if (dhNb == NULL) {
ret = MEMORY_E;
}
else {
ret = wc_DhSetNonBlock((DhKey*)kse->key, dhNb);
if (ret != 0) {
XFREE(dhNb, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
}
}
}
Comment thread
dgarske marked this conversation as resolved.
#endif /* WC_DH_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW &&
WC_ASYNC_ENABLE_DH */
}

/* Allocate space for the private and public key */
Expand Down Expand Up @@ -8085,8 +8105,16 @@ static int TLSX_KeyShare_GenDhKey(WOLFSSL *ssl, KeyShareEntry* kse)

/* Always release the DH key to free up memory.
* The DhKey will be setup again in TLSX_KeyShare_ProcessDh */
if (dhKey != NULL)
if (dhKey != NULL) {
#if defined(WC_DH_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
defined(WC_ASYNC_ENABLE_DH)
if (dhKey->nb != NULL) {
XFREE(dhKey->nb, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
dhKey->nb = NULL;
}
#endif
wc_FreeDhKey(dhKey);
}
XFREE(kse->key, ssl->heap, DYNAMIC_TYPE_DH);
kse->key = NULL;

Expand Down Expand Up @@ -9051,6 +9079,15 @@ static void TLSX_KeyShare_FreeAll(KeyShareEntry* list, void* heap)
list = current->next;
if (WOLFSSL_NAMED_GROUP_IS_FFDHE(current->group)) {
#ifndef NO_DH
#if defined(WC_DH_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
defined(WC_ASYNC_ENABLE_DH)
if (current->key != NULL &&
((DhKey*)current->key)->nb != NULL) {
XFREE(((DhKey*)current->key)->nb, heap,
DYNAMIC_TYPE_TMP_BUFFER);
((DhKey*)current->key)->nb = NULL;
}
#endif
wc_FreeDhKey((DhKey*)current->key);
#endif
}
Expand Down Expand Up @@ -9297,6 +9334,26 @@ static int TLSX_KeyShare_ProcessDh(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
ret = wc_DhSetNamedKey(dhKey, keyShareEntry->group);
#endif
}
#if defined(WC_DH_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
defined(WC_ASYNC_ENABLE_DH)
/* Only set non-blocking context when async device is active. With
* INVALID_DEVID there is no async loop to retry on MP_WOULDBLOCK, so
* skip non-blocking setup and use blocking mode instead. */
if (ret == 0 && ssl->devId != INVALID_DEVID) {
DhNb* dhNb = (DhNb*)XMALLOC(sizeof(DhNb), ssl->heap,
DYNAMIC_TYPE_TMP_BUFFER);
if (dhNb == NULL) {
ret = MEMORY_E;
}
else {
ret = wc_DhSetNonBlock((DhKey*)keyShareEntry->key, dhNb);
if (ret != 0) {
XFREE(dhNb, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
}
}
}
Comment thread
dgarske marked this conversation as resolved.
#endif /* WC_DH_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW &&
WC_ASYNC_ENABLE_DH */
}

if (ret == 0
Expand Down Expand Up @@ -9337,8 +9394,16 @@ static int TLSX_KeyShare_ProcessDh(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
}

/* done with key share, release resources */
if (dhKey)
if (dhKey) {
#if defined(WC_DH_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
defined(WC_ASYNC_ENABLE_DH)
if (dhKey->nb != NULL) {
XFREE(dhKey->nb, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
dhKey->nb = NULL;
}
#endif
wc_FreeDhKey(dhKey);
}
XFREE(keyShareEntry->key, ssl->heap, DYNAMIC_TYPE_DH);
keyShareEntry->key = NULL;
if (keyShareEntry->privKey) {
Expand Down
Loading
Loading