From 226a8b676d47744eb1118ebaec67adc53dea360f Mon Sep 17 00:00:00 2001 From: Hayden Roche Date: Thu, 1 Sep 2022 16:47:43 -0700 Subject: [PATCH] Add support for non-blocking ECDHE/ECDSA in TLS/DTLS layer. This requires the async code. --- src/internal.c | 35 +++++++++++++++++++++++++++++++++- wolfcrypt/src/asn.c | 28 +++++++++++++++++++++++++++ wolfcrypt/src/ecc.c | 46 +++++++++++++++++++-------------------------- 3 files changed, 81 insertions(+), 28 deletions(-) diff --git a/src/internal.c b/src/internal.c index 6aa2cf751..2c90b220d 100644 --- a/src/internal.c +++ b/src/internal.c @@ -7071,6 +7071,14 @@ void FreeKey(WOLFSSL* ssl, int type, void** pKey) #endif /* ! NO_RSA */ #ifdef HAVE_ECC case DYNAMIC_TYPE_ECC: + #if defined(WC_ECC_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \ + defined(WC_ASYNC_ENABLE_ECC) + if (((ecc_key*)*pKey)->nb_ctx != NULL) { + XFREE(((ecc_key*)*pKey)->nb_ctx, ((ecc_key*)*pKey)->heap, + DYNAMIC_TYPE_TMP_BUFFER); + } + #endif /* WC_ECC_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW && + WC_ASYNC_ENABLE_ECC */ wc_ecc_free((ecc_key*)*pKey); break; #endif /* HAVE_ECC */ @@ -7125,6 +7133,13 @@ int AllocKey(WOLFSSL* ssl, int type, void** pKey) { int ret = BAD_FUNC_ARG; int sz = 0; +#ifdef HAVE_ECC + ecc_key* eccKey; +#endif /* HAVE_ECC */ +#if defined(WC_ECC_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \ + defined(WC_ASYNC_ENABLE_ECC) + ecc_nb_ctx_t* nbCtx; +#endif /* WC_ECC_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW && WC_ASYNC_ENABLE_ECC*/ if (ssl == NULL || pKey == NULL) { return BAD_FUNC_ARG; @@ -7204,7 +7219,25 @@ int AllocKey(WOLFSSL* ssl, int type, void** pKey) #endif /* ! NO_RSA */ #ifdef HAVE_ECC case DYNAMIC_TYPE_ECC: - ret = wc_ecc_init_ex((ecc_key*)*pKey, ssl->heap, ssl->devId); + eccKey = (ecc_key*)*pKey; + ret = wc_ecc_init_ex(eccKey, ssl->heap, ssl->devId); + if (ret == 0) { + #if defined(WC_ECC_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \ + defined(WC_ASYNC_ENABLE_ECC) + nbCtx = (ecc_nb_ctx_t*)XMALLOC(sizeof(ecc_nb_ctx_t), + eccKey->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (nbCtx == NULL) { + ret = MEMORY_E; + } + else { + ret = wc_ecc_set_nonblock(eccKey, nbCtx); + if (ret != 0) { + XFREE(nbCtx, eccKey->heap, DYNAMIC_TYPE_TMP_BUFFER); + } + } + #endif /* WC_ECC_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW && + WC_ASYNC_ENABLE_ECC */ + } break; #endif /* HAVE_ECC */ #ifdef HAVE_ED25519 diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 3e8aeb349..3c6898f11 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -15080,6 +15080,14 @@ void FreeSignatureCtx(SignatureCtx* sigCtx) #endif #ifdef HAVE_ECC case ECDSAk: + #if defined(WC_ECC_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \ + defined(WC_ASYNC_ENABLE_ECC) + if (sigCtx->key.ecc->nb_ctx != NULL) { + XFREE(sigCtx->key.ecc->nb_ctx, sigCtx->heap, + DYNAMIC_TYPE_TMP_BUFFER); + } + #endif /* WC_ECC_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW && + WC_ASYNC_ENABLE_ECC */ wc_ecc_free(sigCtx->key.ecc); XFREE(sigCtx->key.ecc, sigCtx->heap, DYNAMIC_TYPE_ECC); sigCtx->key.ecc = NULL; @@ -15568,6 +15576,11 @@ static int ConfirmSignature(SignatureCtx* sigCtx, case ECDSAk: { word32 idx = 0; + #if defined(WC_ECC_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \ + defined(WC_ASYNC_ENABLE_ECC) + ecc_nb_ctx_t* nbCtx; + #endif /* WC_ECC_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW && + WC_ASYNC_ENABLE_ECC */ sigCtx->verify = 0; sigCtx->key.ecc = (ecc_key*)XMALLOC(sizeof(ecc_key), @@ -15579,6 +15592,21 @@ static int ConfirmSignature(SignatureCtx* sigCtx, sigCtx->devId)) < 0) { goto exit_cs; } + #if defined(WC_ECC_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \ + defined(WC_ASYNC_ENABLE_ECC) + nbCtx = (ecc_nb_ctx_t*)XMALLOC(sizeof(ecc_nb_ctx_t), + sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (nbCtx == NULL) { + ERROR_OUT(MEMORY_E, exit_cs); + } + else { + ret = wc_ecc_set_nonblock(sigCtx->key.ecc, nbCtx); + if (ret != 0) { + goto exit_cs; + } + } + #endif /* WC_ECC_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW && + WC_ASYNC_ENABLE_ECC */ ret = wc_EccPublicKeyDecode(key, &idx, sigCtx->key.ecc, keySz); if (ret < 0) { diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index f947794bc..f7ed787bf 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -6389,12 +6389,25 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, } #endif + +#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \ + defined(WOLFSSL_ASYNC_CRYPT_SW) + if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) { + if (wc_AsyncSwInit(&key->asyncDev, ASYNC_SW_ECC_SIGN)) { + WC_ASYNC_SW* sw = &key->asyncDev.sw; + sw->eccSign.in = in; + sw->eccSign.inSz = inlen; + sw->eccSign.rng = rng; + sw->eccSign.key = key; + sw->eccSign.r = r; + sw->eccSign.s = s; + return WC_PENDING_E; + } + } +#endif + #if defined(WOLFSSL_HAVE_SP_ECC) - if (key->idx != ECC_CUSTOM_IDX - #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) - && key->asyncDev.marker != WOLFSSL_ASYNC_MARKER_ECC - #endif - ) { + if (key->idx != ECC_CUSTOM_IDX) { #if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) \ || defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \ defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT) @@ -6494,23 +6507,6 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, (void)inlen; #endif -#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \ - defined(WOLFSSL_ASYNC_CRYPT_SW) - if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) { - if (wc_AsyncSwInit(&key->asyncDev, ASYNC_SW_ECC_SIGN)) { - WC_ASYNC_SW* sw = &key->asyncDev.sw; - sw->eccSign.in = in; - sw->eccSign.inSz = inlen; - sw->eccSign.rng = rng; - sw->eccSign.key = key; - sw->eccSign.r = r; - sw->eccSign.s = s; - return WC_PENDING_E; - } - } -#endif - - #if !defined(WOLFSSL_SP_MATH) #if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V) @@ -8010,11 +8006,7 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, #endif #if defined(WOLFSSL_HAVE_SP_ECC) - if (key->idx != ECC_CUSTOM_IDX - #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) - && key->asyncDev.marker != WOLFSSL_ASYNC_MARKER_ECC - #endif - ) { + if (key->idx != ECC_CUSTOM_IDX) { #if defined(WC_ECC_NONBLOCK) && defined(WC_ECC_NONBLOCK_ONLY) /* perform blocking call to non-blocking function */ ecc_nb_ctx_t nb_ctx;