Fixes and tests for async and crypto callbacks#9784
Fixes and tests for async and crypto callbacks#9784dgarske wants to merge 2 commits intowolfSSL:masterfrom
Conversation
71f9210 to
7f50626
Compare
|
This appears to update only the examples and the workflow. How does this solve the ZD ticket @dgarske ? |
Thanks for your interest in my work @padelsbach ... it doesn't solve it yet. I'm still working with the customer. |
7f50626 to
0dffc8a
Compare
There was a problem hiding this comment.
Pull request overview
This PR improves async + crypto-callback behavior and strengthens the async examples/CI coverage for both software async and crypto-callback simulated pending flows.
Changes:
- Fix/clarify async pending handling for crypto/PK callbacks and clear stale async device state after popping events.
- Update async examples to support
ASYNC_MODE(sw vs cryptocb), including registration of crypto callbacks and updated docs. - Extend GitHub Actions to build/run async examples in both modes.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| wolfcrypt/src/cryptocb.c | Fix %p logging by casting ctx pointers to void*. |
| wolfcrypt/src/async.c | Document callback-driven pending/retry behavior in the polling loop. |
| src/internal.c | Clear stale async event state after event removal to enable clean retries. |
| examples/async/user_settings.h | Adjust example settings and document mutually exclusive async modes. |
| examples/async/async_tls.c | Update include flow for user settings; narrow simulated pending operations in callback. |
| examples/async/async_server.c | Register/unregister crypto callback device and improve error logging. |
| examples/async/async_client.c | Register/unregister crypto callback device and improve error logging. |
| examples/async/README.md | Document build modes and how to run async examples. |
| examples/async/Makefile | Add ASYNC_MODE switch controlling WOLFSSL_ASYNC_CRYPT_SW vs WOLF_CRYPTO_CB. |
| .github/workflows/async-examples.yml | Build/run CI matrix for both async modes and adjust pending-count validation. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| #else | ||
| #include <wolfssl/options.h> | ||
| #endif |
There was a problem hiding this comment.
wolfssl/options.h is the canonical entry point that applies library configuration/feature macros; skipping it when WOLFSSL_USER_SETTINGS is defined can break builds or produce inconsistent configuration across translation units. Prefer always including <wolfssl/options.h> (it will include the user settings when WOLFSSL_USER_SETTINGS is defined), or include user_settings.h and then include <wolfssl/options.h> so the normal options processing still occurs.
| #else | |
| #include <wolfssl/options.h> | |
| #endif | |
| #endif | |
| #include <wolfssl/options.h> |
| * 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 || |
There was a problem hiding this comment.
The comment says "signing only", but the condition still includes WC_PK_TYPE_RSA, which may cover multiple RSA operations depending on how WC_PK_TYPE_RSA is used in the callback path (not necessarily sign-only). Either narrow the condition to explicit RSA signing type(s) (if available), or update the comment to match the actual set of operations that can return WC_PENDING_E.
| if (info->pk.type == WC_PK_TYPE_RSA || | |
| if ((info->pk.type == WC_PK_TYPE_RSA && | |
| info->pk.rsa.type == RSA_PRIVATE_ENCRYPT) || |
| #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"); | ||
| goto exit; | ||
| } | ||
| #endif |
There was a problem hiding this comment.
On the wc_CryptoCb_RegisterDevice failure path you goto exit, but exit later unconditionally calls wc_CryptoCb_UnRegisterDevice(devId) under #ifdef WOLF_CRYPTO_CB. This can unregister an ID that was never registered (and in this block devId may have been forced to 1). Track whether registration succeeded (e.g., a cryptoCbRegistered flag) and only unregister when true.
| #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"); | ||
| goto out; | ||
| } | ||
| #endif |
There was a problem hiding this comment.
Similar to the server, on registration failure you goto out but out later unconditionally calls wc_CryptoCb_UnRegisterDevice(devId) under #ifdef WOLF_CRYPTO_CB. This may attempt to unregister an unregistered device ID (and could be the forced 1). Add a success flag and only unregister when registration completed successfully.
| fprintf(stderr, "ERROR: wolfSSL_read failed: %d (%s)\n", | ||
| err, wolfSSL_ERR_reason_error_string(err)); |
There was a problem hiding this comment.
wolfSSL_ERR_reason_error_string() expects an OpenSSL-style packed error code (typically obtained via wolfSSL_ERR_get_error()), not the wolfSSL_get_error() return value stored in err. This will likely print an incorrect/null reason string. Prefer printing err numerically (or mapping it via an SSL-error helper if available), and if you want a reason string use wolfSSL_ERR_get_error() + wolfSSL_ERR_error_string()/wolfSSL_ERR_reason_error_string() appropriately.
| fprintf(stderr, "ERROR: wolfSSL_write failed: %d (%s)\n", | ||
| err, wolfSSL_ERR_reason_error_string(err)); |
There was a problem hiding this comment.
Same issue as server: err here is the wolfSSL_get_error() code, but wolfSSL_ERR_reason_error_string() expects a packed lib error from wolfSSL_ERR_get_error(). Adjust the logging to either convert the SSL error code properly or fetch the library error queue value and stringify that.
| fprintf(stderr, "ERROR: wolfSSL_read failed: %d (%s)\n", | ||
| err, wolfSSL_ERR_reason_error_string(err)); |
There was a problem hiding this comment.
Same incorrect error-string API usage as above; wolfSSL_ERR_reason_error_string(err) is not meaningful when err is from wolfSSL_get_error(). Use the error-queue API (wolfSSL_ERR_get_error() + stringify) or log the wolfSSL_get_error() code with an appropriate mapping.
Description
Fixes and tests for async and crypto callbacks
Fixes ZD 21071
Testing
How did you test?
Checklist