From 642a65a34d82b74f9c33e86e579d3fb21e7d4aa2 Mon Sep 17 00:00:00 2001 From: night1rider Date: Sun, 15 Mar 2026 21:50:37 -0600 Subject: [PATCH] Add export hooks for ecc --- tests/api.c | 66 +++++++++++++++++++++---------------- wolfcrypt/src/ecc.c | 77 +++++++++++++++++++++++++++++++++++++++++++ wolfcrypt/test/test.c | 65 +++++++++++++++++++++--------------- 3 files changed, 153 insertions(+), 55 deletions(-) diff --git a/tests/api.c b/tests/api.c index 571e6e47d5..75502ad9f4 100644 --- a/tests/api.c +++ b/tests/api.c @@ -28580,37 +28580,47 @@ static int test_CryptoCb_Func(int thisDevId, wc_CryptoInfo* info, void* ctx) break; } - /* Export public key if available */ - if (src->type != ECC_PRIVATEKEY_ONLY) { - ret = wc_ecc_export_x963(src, pubBuf, &pubSz); - if (ret != 0) { - WC_FREE_VAR(pubBuf, NULL); - WC_FREE_VAR(privBuf, NULL); - break; - } - pubPtr = pubBuf; - } + /* Use software to export from src - prevent recursion */ + { + int savedDevId = src->devId; + src->devId = INVALID_DEVID; - /* Export private key if available */ - if (src->type != ECC_PUBLICKEY) { - ret = wc_ecc_export_private_only(src, privBuf, - &privSz); - if (ret != 0) { - WC_FREE_VAR(pubBuf, NULL); - WC_FREE_VAR(privBuf, NULL); - break; + /* Export public key if available */ + if (src->type != ECC_PRIVATEKEY_ONLY) { + ret = wc_ecc_export_x963(src, pubBuf, &pubSz); + if (ret != 0) { + src->devId = savedDevId; + WC_FREE_VAR(pubBuf, NULL); + WC_FREE_VAR(privBuf, NULL); + break; + } + pubPtr = pubBuf; } - curveId = wc_ecc_get_curve_id(src->idx); - ret = wc_ecc_import_private_key_ex(privBuf, privSz, - pubPtr, (pubPtr != NULL) ? pubSz : 0, - dst, curveId); - } - else { - /* Public key only */ - curveId = wc_ecc_get_curve_id(src->idx); - ret = wc_ecc_import_x963_ex2(pubBuf, pubSz, dst, - curveId, 0); + /* Export private key if available */ + if (src->type != ECC_PUBLICKEY) { + ret = wc_ecc_export_private_only(src, privBuf, + &privSz); + if (ret != 0) { + src->devId = savedDevId; + WC_FREE_VAR(pubBuf, NULL); + WC_FREE_VAR(privBuf, NULL); + break; + } + + curveId = wc_ecc_get_curve_id(src->idx); + ret = wc_ecc_import_private_key_ex(privBuf, privSz, + pubPtr, (pubPtr != NULL) ? pubSz : 0, + dst, curveId); + } + else { + /* Public key only */ + curveId = wc_ecc_get_curve_id(src->idx); + ret = wc_ecc_import_x963_ex2(pubBuf, pubSz, dst, + curveId, 0); + } + + src->devId = savedDevId; } WC_FREE_VAR(pubBuf, NULL); WC_FREE_VAR(privBuf, NULL); diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 18155f8bb6..c41037f739 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -9863,6 +9863,9 @@ int wc_ecc_export_x963(ecc_key* key, byte* out, word32* outLen) word32 numlen; WC_DECLARE_VAR(buf, byte, ECC_BUFSIZE, 0); word32 pubxlen, pubylen; +#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_EXPORT_KEY) + WC_DECLARE_VAR(tmpKey, ecc_key, 1, NULL); +#endif /* return length needed only */ if (key != NULL && out == NULL && outLen != NULL) { @@ -9878,6 +9881,41 @@ int wc_ecc_export_x963(ecc_key* key, byte* out, word32* outLen) if (key->type == ECC_PRIVATEKEY_ONLY) return ECC_PRIVATEONLY_E; +#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_EXPORT_KEY) + #ifndef WOLF_CRYPTO_CB_FIND + if (key->devId != INVALID_DEVID) + #endif + { + WC_ALLOC_VAR(tmpKey, ecc_key, 1, key->heap); + if (!WC_VAR_OK(tmpKey)) { + return MEMORY_E; + } + XMEMSET(tmpKey, 0, sizeof(ecc_key)); + + ret = wc_ecc_init_ex(tmpKey, key->heap, INVALID_DEVID); + if (ret != 0) { + WC_FREE_VAR(tmpKey, key->heap); + return ret; + } + + ret = wc_CryptoCb_ExportKey(key->devId, WC_PK_TYPE_ECDSA_SIGN, + (void*)key, tmpKey); + if (ret == 0) { + /* Recursive call on software tmpKey (INVALID_DEVID) */ + ret = wc_ecc_export_x963(tmpKey, out, outLen); + } + + wc_ecc_free(tmpKey); + WC_FREE_VAR(tmpKey, key->heap); + + if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) { + return ret; + } + /* CRYPTOCB_UNAVAILABLE: fall through to software export */ + ret = MP_OKAY; + } +#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_EXPORT_KEY */ + #if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM) /* check if public key in secure memory */ if (key->securePubKey > 0) { @@ -11145,11 +11183,50 @@ int wc_ecc_export_ex(ecc_key* key, byte* qx, word32* qxLen, { int err = 0; word32 keySz; +#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_EXPORT_KEY) + WC_DECLARE_VAR(tmpKey, ecc_key, 1, NULL); +#endif if (key == NULL) { return BAD_FUNC_ARG; } +#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_EXPORT_KEY) + #ifndef WOLF_CRYPTO_CB_FIND + if (key->devId != INVALID_DEVID) + #endif + { + WC_ALLOC_VAR(tmpKey, ecc_key, 1, key->heap); + if (!WC_VAR_OK(tmpKey)) { + return MEMORY_E; + } + XMEMSET(tmpKey, 0, sizeof(ecc_key)); + + err = wc_ecc_init_ex(tmpKey, key->heap, INVALID_DEVID); + if (err != 0) { + WC_FREE_VAR(tmpKey, key->heap); + return err; + } + + err = wc_CryptoCb_ExportKey(key->devId, WC_PK_TYPE_ECDSA_SIGN, + (void*)key, tmpKey); + if (err == 0) { + /* Recursive call on software tmpKey (INVALID_DEVID) */ + err = wc_ecc_export_ex(tmpKey, qx, qxLen, qy, qyLen, d, dLen, + encType); + } + + wc_ecc_free(tmpKey); + WC_FREE_VAR(tmpKey, key->heap); + + if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) { + return err; + } + /* CRYPTOCB_UNAVAILABLE: fall through to software export */ + err = 0; + } +#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_EXPORT_KEY */ + if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) { return ECC_BAD_ARG_E; } diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 82b4e5e46c..cfaba81a95 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -66935,36 +66935,47 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx) break; } - /* Export public key if available */ - if (src->type != ECC_PRIVATEKEY_ONLY) { - ret = wc_ecc_export_x963(src, pubBuf, &pubSz); - if (ret != 0) { - WC_FREE_VAR(pubBuf, NULL); - WC_FREE_VAR(privBuf, NULL); - break; - } - pubPtr = pubBuf; - } + /* Use software to export from src - prevent recursion */ + { + int savedDevId = src->devId; + src->devId = INVALID_DEVID; - /* Export private key if available */ - if (src->type != ECC_PUBLICKEY) { - ret = wc_ecc_export_private_only(src, privBuf, &privSz); - if (ret != 0) { - WC_FREE_VAR(pubBuf, NULL); - WC_FREE_VAR(privBuf, NULL); - break; + /* Export public key if available */ + if (src->type != ECC_PRIVATEKEY_ONLY) { + ret = wc_ecc_export_x963(src, pubBuf, &pubSz); + if (ret != 0) { + src->devId = savedDevId; + WC_FREE_VAR(pubBuf, NULL); + WC_FREE_VAR(privBuf, NULL); + break; + } + pubPtr = pubBuf; } - curveId = wc_ecc_get_curve_id(src->idx); - ret = wc_ecc_import_private_key_ex(privBuf, privSz, - pubPtr, (pubPtr != NULL) ? pubSz : 0, - dst, curveId); - } - else { - /* Public key only */ - curveId = wc_ecc_get_curve_id(src->idx); - ret = wc_ecc_import_x963_ex2(pubBuf, pubSz, dst, - curveId, 0); + /* Export private key if available */ + if (src->type != ECC_PUBLICKEY) { + ret = wc_ecc_export_private_only(src, privBuf, + &privSz); + if (ret != 0) { + src->devId = savedDevId; + WC_FREE_VAR(pubBuf, NULL); + WC_FREE_VAR(privBuf, NULL); + break; + } + + curveId = wc_ecc_get_curve_id(src->idx); + ret = wc_ecc_import_private_key_ex(privBuf, privSz, + pubPtr, (pubPtr != NULL) ? pubSz : 0, + dst, curveId); + } + else { + /* Public key only */ + curveId = wc_ecc_get_curve_id(src->idx); + ret = wc_ecc_import_x963_ex2(pubBuf, pubSz, dst, + curveId, 0); + } + + src->devId = savedDevId; } WC_FREE_VAR(pubBuf, NULL); WC_FREE_VAR(privBuf, NULL);