feat: route configurable devId through key init calls#390
feat: route configurable devId through key init calls#390MarkAtwood wants to merge 1 commit intowolfSSL:masterfrom
Conversation
Adds int devId to WOLFPROV_CTX (initialized to INVALID_DEVID) and
exposes it as a settable OSSL_PARAM ("wolfprovider_devid") so callers
can route provider operations through a wolfHSM device callback.
Routes devId through:
- RSA: wc_InitRsaKey -> wc_InitRsaKey_ex
- ECC: wc_ecc_init_ex (was hardcoding INVALID_DEVID)
- DH: wc_InitDhKey_ex (was hardcoding INVALID_DEVID)
- ECX gen-context RNG: wc_InitRng -> wc_InitRng_ex
Known gap: ECX key init functions (wc_curve25519_init, wc_ed25519_init,
wc_ed448_init) use WP_ECX_INIT function pointers with no devId
parameter; fixing them requires a table-shape change tracked separately.
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Routes a configurable wolfCrypt devId through provider-managed key/RNG initialization to enable device callback routing (e.g., wolfHSM) instead of always using INVALID_DEVID.
Changes:
- Adds
devIdtoWOLFPROV_CTXand sets a default ofINVALID_DEVID. - Exposes
wolfprovider_devidvia providersettable_params/set_params. - Passes
devIdinto RSA/ECC/DH key init and ECX keygen RNG init.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| src/wp_wolfprov.c | Adds provider parameter plumbing and default devId in provider context. |
| src/wp_rsa_kmgmt.c | Uses provCtx->devId for RSA key init and RSA keygen RNG init. |
| src/wp_ecx_kmgmt.c | Uses provCtx->devId for ECX keygen RNG init (not ECX key init). |
| src/wp_ecc_kmgmt.c | Uses provCtx->devId for ECC key init. |
| src/wp_dh_kmgmt.c | Uses provCtx->devId for DH key init. |
| include/wolfprovider/internal.h | Adds devId to the provider context struct. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| OSSL_PARAM_DEFN(OSSL_PROV_PARAM_VERSION, OSSL_PARAM_UTF8_PTR, NULL, 0), | ||
| OSSL_PARAM_DEFN(OSSL_PROV_PARAM_BUILDINFO, OSSL_PARAM_UTF8_PTR, NULL, 0), | ||
| OSSL_PARAM_DEFN(OSSL_PROV_PARAM_STATUS, OSSL_PARAM_INTEGER, NULL, 0), | ||
| OSSL_PARAM_int("wolfprovider_devid", NULL), |
There was a problem hiding this comment.
wolfprovider_devid is being advertised as a gettable provider parameter via wolfssl_param_types, but this PR only adds support for setting it (wolfprov_set_params). This is an API contract mismatch: either implement returning the current value in wolfprov_get_params, or remove it from the gettable table and keep it only in wolfprov_settable_params.
| OSSL_PARAM_int("wolfprovider_devid", NULL), |
| static int wolfprov_set_params(void* provCtx, const OSSL_PARAM params[]) | ||
| { | ||
| int ok = 1; | ||
| const OSSL_PARAM* p; | ||
| WOLFPROV_CTX* ctx = (WOLFPROV_CTX*)provCtx; |
There was a problem hiding this comment.
ctx->devId becomes runtime-mutable via wolfprov_set_params, and is read concurrently in multiple algorithm init paths (RSA/ECC/DH/ECX RNG). In C, an unsynchronized read/write to the same non-atomic object across threads is a data race (undefined behavior). Consider making devId an atomic type (or guarding reads/writes with an existing/new mutex), or documenting/enforcing that wolfprovider_devid must only be set before any concurrent operations begin.
| p = OSSL_PARAM_locate_const(params, "wolfprovider_devid"); | ||
| if (p != NULL) { | ||
| if (!OSSL_PARAM_get_int(p, &ctx->devId)) { | ||
| ok = 0; | ||
| } | ||
| } |
There was a problem hiding this comment.
ctx->devId becomes runtime-mutable via wolfprov_set_params, and is read concurrently in multiple algorithm init paths (RSA/ECC/DH/ECX RNG). In C, an unsynchronized read/write to the same non-atomic object across threads is a data race (undefined behavior). Consider making devId an atomic type (or guarding reads/writes with an existing/new mutex), or documenting/enforcing that wolfprovider_devid must only be set before any concurrent operations begin.
| OSSL_PARAM_DEFN(OSSL_PROV_PARAM_VERSION, OSSL_PARAM_UTF8_PTR, NULL, 0), | ||
| OSSL_PARAM_DEFN(OSSL_PROV_PARAM_BUILDINFO, OSSL_PARAM_UTF8_PTR, NULL, 0), | ||
| OSSL_PARAM_DEFN(OSSL_PROV_PARAM_STATUS, OSSL_PARAM_INTEGER, NULL, 0), | ||
| OSSL_PARAM_int("wolfprovider_devid", NULL), |
There was a problem hiding this comment.
The parameter name string literal is duplicated in multiple places. To reduce the risk of typos and make future refactors easier, define a single constant/macro (e.g., #define WP_PARAM_DEVID "wolfprovider_devid") and use it consistently across the gettable/settable/set handlers.
| static const OSSL_PARAM* wolfprov_settable_params(void* provCtx) | ||
| { | ||
| static const OSSL_PARAM settable[] = { | ||
| OSSL_PARAM_int("wolfprovider_devid", NULL), |
There was a problem hiding this comment.
The parameter name string literal is duplicated in multiple places. To reduce the risk of typos and make future refactors easier, define a single constant/macro (e.g., #define WP_PARAM_DEVID "wolfprovider_devid") and use it consistently across the gettable/settable/set handlers.
|
|
||
| WOLFPROV_ENTER(WP_LOG_COMP_PROVIDER, "wolfprov_set_params"); | ||
|
|
||
| p = OSSL_PARAM_locate_const(params, "wolfprovider_devid"); |
There was a problem hiding this comment.
The parameter name string literal is duplicated in multiple places. To reduce the risk of typos and make future refactors easier, define a single constant/macro (e.g., #define WP_PARAM_DEVID "wolfprovider_devid") and use it consistently across the gettable/settable/set handlers.
Summary
wolfProvider currently hardcodes
INVALID_DEVIDin all key initializationcalls, silently bypassing wolfCrypt's device callback layer. This makes it
impossible to route OpenSSL operations through a wolfHSM server (or any
other wolfCrypt device callback) via the provider interface.
This PR closes that gap for RSA, ECC, and DH:
int devIdtoWOLFPROV_CTX, initialized toINVALID_DEVID(no behavior change for existing users)wolfprovider_devidas a settableOSSL_PARAMso callers can configure the device ID at runtimedevIdthrough RSA (wc_InitRsaKey_ex), ECC (wc_ecc_init_ex), and DH (wc_InitDhKey_ex) key init callsdevIdthrough the ECX gen-context RNG init (wc_InitRng_ex)Known gap
ECX key init functions (
wc_curve25519_init,wc_ed25519_init,wc_ed448_init) useWP_ECX_INITfunction pointers typed asint(*)(void*), which carry nodevIdparameter. Routing devId through ECX key init requires changing the table shape and all four call sites — that is a larger, separate change. The RNG used during ECX key generation does usedevIdafter this PR.wc_curve448_init_exdoes not exist in wolfCrypt as of wolfSSL 5.x, so curve448 cannot be fixed without a wolfCrypt change.Behavior for existing users
devIddefaults toINVALID_DEVID, so all existing behavior is unchanged unless the caller explicitly setswolfprovider_devidviaOSSL_PROVIDER_set_params.Test plan
wolfprovider_devidis set toWH_DEV_IDwolfprovider_devidis setwolfprovider_devidis setwolfprovider_devidtoINVALID_DEVIDrestores direct wolfCrypt behavior