From 0dffc8abffc47364f5df884ed179a7dfdad853ca Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 27 Feb 2026 14:08:17 -0800 Subject: [PATCH] Fixes for async and crypto callbacks --- examples/async/async_client.c | 8 ++++++++ examples/async/async_server.c | 6 ++++++ examples/async/async_tls.c | 15 ++++++++++----- src/internal.c | 5 ++++- wolfcrypt/src/async.c | 6 +++++- wolfcrypt/src/cryptocb.c | 8 ++++---- 6 files changed, 37 insertions(+), 11 deletions(-) diff --git a/examples/async/async_client.c b/examples/async/async_client.c index 476231405d..c94a208d4d 100644 --- a/examples/async/async_client.c +++ b/examples/async/async_client.c @@ -286,6 +286,10 @@ int client_async_test(int argc, char** argv) } #endif #ifdef WOLF_CRYPTO_CB + /* Crypto callbacks require a valid devId. When no hardware async driver + * sets one (e.g. Cavium/Intel QA/SW), assign one explicitly. */ + if (devId == INVALID_DEVID) + devId = 1; XMEMSET(&cryptoCbCtx, 0, sizeof(cryptoCbCtx)); if (wc_CryptoCb_RegisterDevice(devId, AsyncTlsCryptoCb, &cryptoCbCtx) != 0) { fprintf(stderr, "ERROR: wc_CryptoCb_RegisterDevice failed\n"); @@ -497,6 +501,8 @@ int client_async_test(int argc, char** argv) } continue; } + fprintf(stderr, "ERROR: wolfSSL_write failed: %d (%s)\n", + err, wolfSSL_ERR_reason_error_string(err)); goto out; } @@ -529,6 +535,8 @@ int client_async_test(int argc, char** argv) } continue; } + fprintf(stderr, "ERROR: wolfSSL_read failed: %d (%s)\n", + err, wolfSSL_ERR_reason_error_string(err)); goto out; } diff --git a/examples/async/async_server.c b/examples/async/async_server.c index 576b6858f7..0c7b936fab 100644 --- a/examples/async/async_server.c +++ b/examples/async/async_server.c @@ -291,6 +291,10 @@ int server_async_test(int argc, char** argv) } #endif #ifdef WOLF_CRYPTO_CB + /* Crypto callbacks require a valid devId. When no hardware async driver + * sets one (e.g. Cavium/Intel QA/SW), assign one explicitly. */ + if (devId == INVALID_DEVID) + devId = 1; XMEMSET(&cryptoCbCtx, 0, sizeof(cryptoCbCtx)); if (wc_CryptoCb_RegisterDevice(devId, AsyncTlsCryptoCb, &cryptoCbCtx) != 0) { fprintf(stderr, "ERROR: wc_CryptoCb_RegisterDevice failed\n"); @@ -526,6 +530,8 @@ int server_async_test(int argc, char** argv) } continue; } + fprintf(stderr, "ERROR: wolfSSL_read failed: %d (%s)\n", + err, wolfSSL_ERR_reason_error_string(err)); goto exit; } diff --git a/examples/async/async_tls.c b/examples/async/async_tls.c index e7eafd39af..e073703049 100644 --- a/examples/async/async_tls.c +++ b/examples/async/async_tls.c @@ -178,12 +178,17 @@ int AsyncTlsCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx) if (info->algo_type == WC_ALGO_TYPE_PK) { #ifdef WOLFSSL_ASYNC_CRYPT - /* Test pending response */ + /* Simulate async pending for signing only. + * This matches a typical hardware crypto scenario (e.g., TPM) where + * only signing is offloaded to hardware. Keygen, verify, and ECDH + * are performed synchronously in software. + * Note: WOLFSSL_ASYNC_CRYPT + WOLF_CRYPTO_CB pending simulation + * requires operations whose TLS state machines properly handle retry + * via wolfSSL_AsyncPop. ECC keygen in TLSX_KeyShare_GenEccKey does + * not support this because the keygen call is inside the key + * allocation guard (kse->key == NULL) which is skipped on retry. */ if (info->pk.type == WC_PK_TYPE_RSA || - info->pk.type == WC_PK_TYPE_EC_KEYGEN || - info->pk.type == WC_PK_TYPE_ECDSA_SIGN || - info->pk.type == WC_PK_TYPE_ECDSA_VERIFY || - info->pk.type == WC_PK_TYPE_ECDH) + info->pk.type == WC_PK_TYPE_ECDSA_SIGN) { if (myCtx->pendingCount++ < TEST_PEND_COUNT) return WC_PENDING_E; myCtx->pendingCount = 0; diff --git a/src/internal.c b/src/internal.c index 2034f107d8..497fff547f 100644 --- a/src/internal.c +++ b/src/internal.c @@ -41789,7 +41789,10 @@ int wolfSSL_AsyncPop(WOLFSSL* ssl, byte* state) * the completion is not detected in the poll like Intel QAT or * Nitrox */ ret = wolfEventQueue_Remove(&ssl->ctx->event_queue, event); - + /* Clear async device so stale pending state from + * wolfSSL_AsyncInit does not confuse subsequent operations */ + XMEMSET(&asyncDev->event, 0, sizeof(WOLF_EVENT)); + ssl->asyncDev = NULL; } #endif } diff --git a/wolfcrypt/src/async.c b/wolfcrypt/src/async.c index ce14a6c58d..5048ddc439 100644 --- a/wolfcrypt/src/async.c +++ b/wolfcrypt/src/async.c @@ -705,7 +705,11 @@ int wolfAsync_EventQueuePoll(WOLF_EVENT_QUEUE* queue, void* context_filter, event->ret = wolfAsync_DoSw(asyncDev); } #elif defined(WOLF_CRYPTO_CB) || defined(HAVE_PK_CALLBACKS) - /* Use crypto or PK callbacks */ + /* Crypto/PK callbacks manage their own retry state. + * Leave event->ret as WC_PENDING_E so that + * wolfSSL_AsyncPop can detect the pending state and + * remove the event, allowing the operation to be + * retried with a fresh callback invocation. */ #else #warning No async crypt device defined! diff --git a/wolfcrypt/src/cryptocb.c b/wolfcrypt/src/cryptocb.c index f9df067264..8db4f6c908 100644 --- a/wolfcrypt/src/cryptocb.c +++ b/wolfcrypt/src/cryptocb.c @@ -219,7 +219,7 @@ void wc_CryptoCb_InfoString(wc_CryptoInfo* info) printf("Crypto CB: %s %s (%d) (%p ctx)\n", GetAlgoTypeStr(info->algo_type), GetCipherTypeStr(info->cipher.type), - info->cipher.type, info->cipher.ctx); + info->cipher.type, (void*)info->cipher.ctx); } #endif /* !NO_AES || !NO_DES3 */ #if !defined(NO_SHA) || !defined(NO_SHA256) || \ @@ -228,7 +228,7 @@ void wc_CryptoCb_InfoString(wc_CryptoInfo* info) printf("Crypto CB: %s %s (%d) (%p ctx) %s\n", GetAlgoTypeStr(info->algo_type), GetHashTypeStr(info->hash.type), - info->hash.type, info->hash.ctx, + info->hash.type, (void*)info->hash.ctx, (info->hash.in != NULL) ? "Update" : "Final"); } #endif @@ -237,7 +237,7 @@ void wc_CryptoCb_InfoString(wc_CryptoInfo* info) printf("Crypto CB: %s %s (%d) (%p ctx) %s\n", GetAlgoTypeStr(info->algo_type), GetHashTypeStr(info->hmac.macType), - info->hmac.macType, info->hmac.hmac, + info->hmac.macType, (void*)info->hmac.hmac, (info->hmac.in != NULL) ? "Update" : "Final"); } #endif @@ -246,7 +246,7 @@ void wc_CryptoCb_InfoString(wc_CryptoInfo* info) printf("Crypto CB: %s %s (%d) (%p ctx) %s %s %s\n", GetAlgoTypeStr(info->algo_type), GetCmacTypeStr(info->cmac.type), - info->cmac.type, info->cmac.cmac, + info->cmac.type, (void*)info->cmac.cmac, (info->cmac.key != NULL) ? "Init " : "", (info->cmac.in != NULL) ? "Update " : "", (info->cmac.out != NULL) ? "Final" : "");