Skip to content

Commit 0585834

Browse files
committed
Add RSA/DH SP non-blocking support for C/Small 2048/3072/4096
1 parent 5ffdb9f commit 0585834

14 files changed

Lines changed: 4426 additions & 35 deletions

File tree

.github/workflows/os-check.yml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,14 @@ jobs:
106106
'CPPFLAGS=-DNO_WOLFSSL_CLIENT',
107107
'CPPFLAGS=-DNO_WOLFSSL_SERVER',
108108
'--enable-lms=small,verify-only --enable-xmss=small,verify-only',
109-
'--enable-curve25519=nonblock --enable-ecc=nonblock --enable-sp=yes,nonblock CPPFLAGS="-DWOLFSSL_PUBLIC_MP -DWOLFSSL_DEBUG_NONBLOCK"',
109+
# Non-blocking ECC + Curve25519 + RSA + DH on the default SP word
110+
# size for the host (sp_c64.c on x86_64). RSA/DH non-block require
111+
# RSA_LOW_MEM (CRT path is not supported in non-block mode).
112+
'--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"',
113+
# Same configuration but force SP_WORD_SIZE=32 to exercise sp_c32.c
114+
# on a 64-bit host. The two builds together cover both generated
115+
# variants of mod_exp_<words>_nb / RSA / DH wrappers.
116+
'--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"',
110117
'--enable-certreq --enable-certext --enable-certgen --disable-secure-renegotiation-info CPPFLAGS="-DNO_TLS"',
111118
]
112119
name: make check linux

.wolfssl_known_macro_extras

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -666,7 +666,6 @@ WC_PROTECT_ENCRYPTED_MEM
666666
WC_PUF_SHA3
667667
WC_RNG_BANK_NO_DEFAULT_SUPPORT
668668
WC_RNG_BLOCKING
669-
WC_RSA_NONBLOCK
670669
WC_RSA_NONBLOCK_TIME
671670
WC_RSA_NO_FERMAT_CHECK
672671
WC_RWLOCK_OPS_INLINE

configure.ac

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4880,6 +4880,15 @@ then
48804880
test -z "$enable_asynccrypt_sw" && enable_asynccrypt_sw=yes
48814881
fi
48824882

4883+
# Handle RSA/DH nonblock - the SP non-blocking dispatch wants the same
4884+
# WOLFSSL_ASYNC_CRYPT_SW shim that ECC/Curve25519 nonblock use so the
4885+
# TLS layer can manage per-SSL nb contexts and yield MP_WOULDBLOCK.
4886+
if test "$enable_rsa" = "nonblock" || test "$enable_dh" = "nonblock"
4887+
then
4888+
test -z "$enable_asynccrypt" && enable_asynccrypt=yes
4889+
test -z "$enable_asynccrypt_sw" && enable_asynccrypt_sw=yes
4890+
fi
4891+
48834892
if test "$ENABLED_CURVE25519" = "no" && test "$ENABLED_QUIC" = "yes" && test "$ENABLED_FIPS" = "no"
48844893
then
48854894
ENABLED_CURVE25519=yes
@@ -5396,14 +5405,25 @@ fi
53965405

53975406
# RSA
53985407
AC_ARG_ENABLE([rsa],
5399-
[AS_HELP_STRING([--enable-rsa],[Enable RSA (default: enabled)])],
5408+
[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])],
54005409
[ ENABLED_RSA=$enableval ],
54015410
[ ENABLED_RSA=yes ]
54025411
)
54035412

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

54845504
# DH
54855505
AC_ARG_ENABLE([dh],
5486-
[AS_HELP_STRING([--enable-dh],[Enable DH (default: enabled)])],
5506+
[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])],
54875507
[ ENABLED_DH=$enableval ],
54885508
[ ENABLED_DH=yes ]
54895509
)
@@ -5496,6 +5516,11 @@ fi
54965516
if test "$ENABLED_DH" = "no"
54975517
then
54985518
AM_CFLAGS="$AM_CFLAGS -DNO_DH"
5519+
elif test "$ENABLED_DH" = "nonblock"
5520+
then
5521+
AM_CFLAGS="$AM_CFLAGS -DWC_DH_NONBLOCK"
5522+
ENABLED_DH=yes
5523+
# asynccrypt + asynccrypt-sw are auto-enabled earlier in this file.
54995524
else
55005525
# turn off DH if leanpsk or leantls on
55015526
if test "$ENABLED_LEANPSK" = "yes" || test "$ENABLED_LEANTLS" = "yes"

src/internal.c

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8300,6 +8300,15 @@ void FreeKey(WOLFSSL* ssl, int type, void** pKey)
83008300
switch (type) {
83018301
#ifndef NO_RSA
83028302
case DYNAMIC_TYPE_RSA:
8303+
#if defined(WC_RSA_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
8304+
defined(WC_ASYNC_ENABLE_RSA)
8305+
if (((RsaKey*)*pKey)->nb != NULL) {
8306+
XFREE(((RsaKey*)*pKey)->nb, ssl->heap,
8307+
DYNAMIC_TYPE_TMP_BUFFER);
8308+
((RsaKey*)*pKey)->nb = NULL;
8309+
}
8310+
#endif /* WC_RSA_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW &&
8311+
WC_ASYNC_ENABLE_RSA */
83038312
wc_FreeRsaKey((RsaKey*)*pKey);
83048313
break;
83058314
#endif /* ! NO_RSA */
@@ -8355,6 +8364,15 @@ void FreeKey(WOLFSSL* ssl, int type, void** pKey)
83558364
#endif /* HAVE_DILITHIUM */
83568365
#ifndef NO_DH
83578366
case DYNAMIC_TYPE_DH:
8367+
#if defined(WC_DH_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
8368+
defined(WC_ASYNC_ENABLE_DH)
8369+
if (((DhKey*)*pKey)->nb != NULL) {
8370+
XFREE(((DhKey*)*pKey)->nb, ssl->heap,
8371+
DYNAMIC_TYPE_TMP_BUFFER);
8372+
((DhKey*)*pKey)->nb = NULL;
8373+
}
8374+
#endif /* WC_DH_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW &&
8375+
WC_ASYNC_ENABLE_DH */
83588376
wc_FreeDhKey((DhKey*)*pKey);
83598377
break;
83608378
#endif /* !NO_DH */
@@ -8385,6 +8403,14 @@ int AllocKey(WOLFSSL* ssl, int type, void** pKey)
83858403
#if defined(WC_X25519_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW)
83868404
x25519_nb_ctx_t* x25519NbCtx;
83878405
#endif /* WC_X25519_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW */
8406+
#if !defined(NO_RSA) && defined(WC_RSA_NONBLOCK) && \
8407+
defined(WOLFSSL_ASYNC_CRYPT_SW) && defined(WC_ASYNC_ENABLE_RSA)
8408+
RsaNb* rsaNb;
8409+
#endif
8410+
#if !defined(NO_DH) && defined(WC_DH_NONBLOCK) && \
8411+
defined(WOLFSSL_ASYNC_CRYPT_SW) && defined(WC_ASYNC_ENABLE_DH)
8412+
DhNb* dhNb;
8413+
#endif
83888414

83898415
if (ssl == NULL || pKey == NULL) {
83908416
return BAD_FUNC_ARG;
@@ -8464,6 +8490,26 @@ int AllocKey(WOLFSSL* ssl, int type, void** pKey)
84648490
#ifndef NO_RSA
84658491
case DYNAMIC_TYPE_RSA:
84668492
ret = wc_InitRsaKey_ex((RsaKey*)*pKey, ssl->heap, ssl->devId);
8493+
#if defined(WC_RSA_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
8494+
defined(WC_ASYNC_ENABLE_RSA)
8495+
/* Only set non-blocking context when async device is active. With
8496+
* INVALID_DEVID there is no async loop to retry on MP_WOULDBLOCK, so
8497+
* skip non-blocking setup and use blocking mode instead. */
8498+
if (ret == 0 && ssl->devId != INVALID_DEVID) {
8499+
rsaNb = (RsaNb*)XMALLOC(sizeof(RsaNb), ssl->heap,
8500+
DYNAMIC_TYPE_TMP_BUFFER);
8501+
if (rsaNb == NULL) {
8502+
ret = MEMORY_E;
8503+
}
8504+
else {
8505+
ret = wc_RsaSetNonBlock((RsaKey*)*pKey, rsaNb);
8506+
if (ret != 0) {
8507+
XFREE(rsaNb, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
8508+
}
8509+
}
8510+
}
8511+
#endif /* WC_RSA_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW &&
8512+
WC_ASYNC_ENABLE_RSA */
84678513
break;
84688514
#endif /* ! NO_RSA */
84698515
#ifdef HAVE_ECC
@@ -8551,6 +8597,26 @@ int AllocKey(WOLFSSL* ssl, int type, void** pKey)
85518597
#ifndef NO_DH
85528598
case DYNAMIC_TYPE_DH:
85538599
ret = wc_InitDhKey_ex((DhKey*)*pKey, ssl->heap, ssl->devId);
8600+
#if defined(WC_DH_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
8601+
defined(WC_ASYNC_ENABLE_DH)
8602+
/* Only set non-blocking context when async device is active. With
8603+
* INVALID_DEVID there is no async loop to retry on MP_WOULDBLOCK, so
8604+
* skip non-blocking setup and use blocking mode instead. */
8605+
if (ret == 0 && ssl->devId != INVALID_DEVID) {
8606+
dhNb = (DhNb*)XMALLOC(sizeof(DhNb), ssl->heap,
8607+
DYNAMIC_TYPE_TMP_BUFFER);
8608+
if (dhNb == NULL) {
8609+
ret = MEMORY_E;
8610+
}
8611+
else {
8612+
ret = wc_DhSetNonBlock((DhKey*)*pKey, dhNb);
8613+
if (ret != 0) {
8614+
XFREE(dhNb, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
8615+
}
8616+
}
8617+
}
8618+
#endif /* WC_DH_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW &&
8619+
WC_ASYNC_ENABLE_DH */
85548620
break;
85558621
#endif /* !NO_DH */
85568622
default:

src/tls.c

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8010,6 +8010,26 @@ static int TLSX_KeyShare_GenDhKey(WOLFSSL *ssl, KeyShareEntry* kse)
80108010
ret = wc_DhSetNamedKey(dhKey, kse->group);
80118011
#endif
80128012
}
8013+
#if defined(WC_DH_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
8014+
defined(WC_ASYNC_ENABLE_DH)
8015+
/* Only set non-blocking context when async device is active. With
8016+
* INVALID_DEVID there is no async loop to retry on MP_WOULDBLOCK, so
8017+
* skip non-blocking setup and use blocking mode instead. */
8018+
if (ret == 0 && ssl->devId != INVALID_DEVID) {
8019+
DhNb* dhNb = (DhNb*)XMALLOC(sizeof(DhNb), ssl->heap,
8020+
DYNAMIC_TYPE_TMP_BUFFER);
8021+
if (dhNb == NULL) {
8022+
ret = MEMORY_E;
8023+
}
8024+
else {
8025+
ret = wc_DhSetNonBlock((DhKey*)kse->key, dhNb);
8026+
if (ret != 0) {
8027+
XFREE(dhNb, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
8028+
}
8029+
}
8030+
}
8031+
#endif /* WC_DH_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW &&
8032+
WC_ASYNC_ENABLE_DH */
80138033
}
80148034

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

80868106
/* Always release the DH key to free up memory.
80878107
* The DhKey will be setup again in TLSX_KeyShare_ProcessDh */
8088-
if (dhKey != NULL)
8108+
if (dhKey != NULL) {
8109+
#if defined(WC_DH_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
8110+
defined(WC_ASYNC_ENABLE_DH)
8111+
if (dhKey->nb != NULL) {
8112+
XFREE(dhKey->nb, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
8113+
dhKey->nb = NULL;
8114+
}
8115+
#endif
80898116
wc_FreeDhKey(dhKey);
8117+
}
80908118
XFREE(kse->key, ssl->heap, DYNAMIC_TYPE_DH);
80918119
kse->key = NULL;
80928120

@@ -9051,6 +9079,15 @@ static void TLSX_KeyShare_FreeAll(KeyShareEntry* list, void* heap)
90519079
list = current->next;
90529080
if (WOLFSSL_NAMED_GROUP_IS_FFDHE(current->group)) {
90539081
#ifndef NO_DH
9082+
#if defined(WC_DH_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
9083+
defined(WC_ASYNC_ENABLE_DH)
9084+
if (current->key != NULL &&
9085+
((DhKey*)current->key)->nb != NULL) {
9086+
XFREE(((DhKey*)current->key)->nb, heap,
9087+
DYNAMIC_TYPE_TMP_BUFFER);
9088+
((DhKey*)current->key)->nb = NULL;
9089+
}
9090+
#endif
90549091
wc_FreeDhKey((DhKey*)current->key);
90559092
#endif
90569093
}
@@ -9297,6 +9334,26 @@ static int TLSX_KeyShare_ProcessDh(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
92979334
ret = wc_DhSetNamedKey(dhKey, keyShareEntry->group);
92989335
#endif
92999336
}
9337+
#if defined(WC_DH_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
9338+
defined(WC_ASYNC_ENABLE_DH)
9339+
/* Only set non-blocking context when async device is active. With
9340+
* INVALID_DEVID there is no async loop to retry on MP_WOULDBLOCK, so
9341+
* skip non-blocking setup and use blocking mode instead. */
9342+
if (ret == 0 && ssl->devId != INVALID_DEVID) {
9343+
DhNb* dhNb = (DhNb*)XMALLOC(sizeof(DhNb), ssl->heap,
9344+
DYNAMIC_TYPE_TMP_BUFFER);
9345+
if (dhNb == NULL) {
9346+
ret = MEMORY_E;
9347+
}
9348+
else {
9349+
ret = wc_DhSetNonBlock((DhKey*)keyShareEntry->key, dhNb);
9350+
if (ret != 0) {
9351+
XFREE(dhNb, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
9352+
}
9353+
}
9354+
}
9355+
#endif /* WC_DH_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW &&
9356+
WC_ASYNC_ENABLE_DH */
93009357
}
93019358

93029359
if (ret == 0
@@ -9337,8 +9394,16 @@ static int TLSX_KeyShare_ProcessDh(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
93379394
}
93389395

93399396
/* done with key share, release resources */
9340-
if (dhKey)
9397+
if (dhKey) {
9398+
#if defined(WC_DH_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
9399+
defined(WC_ASYNC_ENABLE_DH)
9400+
if (dhKey->nb != NULL) {
9401+
XFREE(dhKey->nb, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
9402+
dhKey->nb = NULL;
9403+
}
9404+
#endif
93419405
wc_FreeDhKey(dhKey);
9406+
}
93429407
XFREE(keyShareEntry->key, ssl->heap, DYNAMIC_TYPE_DH);
93439408
keyShareEntry->key = NULL;
93449409
if (keyShareEntry->privKey) {

0 commit comments

Comments
 (0)