-
Notifications
You must be signed in to change notification settings - Fork 959
Setkey/Export callbacks #9851
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Setkey/Export callbacks #9851
Changes from all commits
d2183ee
8b092de
19d1e4a
94b248a
d2ce541
8b6972e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27974,6 +27974,35 @@ static int test_CryptoCb_Func(int thisDevId, wc_CryptoInfo* info, void* ctx) | |
| ret, *info->pk.eccsign.outlen); | ||
| #endif | ||
| } | ||
| else if (info->pk.type == WC_PK_TYPE_EC_GET_SIZE) { | ||
| WC_DECLARE_VAR(tmpEcc, ecc_key, 1, NULL); | ||
| WC_ALLOC_VAR(tmpEcc, ecc_key, 1, NULL); | ||
| if (!WC_VAR_OK(tmpEcc)) { | ||
| ret = MEMORY_E; | ||
| } | ||
| else { | ||
| XMEMCPY(tmpEcc, info->pk.ecc_get_size.key, sizeof(ecc_key)); | ||
| tmpEcc->devId = INVALID_DEVID; | ||
| *info->pk.ecc_get_size.keySize = wc_ecc_size(tmpEcc); | ||
| WC_FREE_VAR(tmpEcc, NULL); | ||
| ret = 0; | ||
| } | ||
| } | ||
| else if (info->pk.type == WC_PK_TYPE_EC_GET_SIG_SIZE) { | ||
| WC_DECLARE_VAR(tmpEcc, ecc_key, 1, NULL); | ||
| WC_ALLOC_VAR(tmpEcc, ecc_key, 1, NULL); | ||
| if (!WC_VAR_OK(tmpEcc)) { | ||
| ret = MEMORY_E; | ||
| } | ||
| else { | ||
| XMEMCPY(tmpEcc, info->pk.ecc_get_sig_size.key, | ||
| sizeof(ecc_key)); | ||
| tmpEcc->devId = INVALID_DEVID; | ||
| *info->pk.ecc_get_sig_size.sigSize = wc_ecc_sig_size(tmpEcc); | ||
| WC_FREE_VAR(tmpEcc, NULL); | ||
| ret = 0; | ||
| } | ||
| } | ||
| #endif /* HAVE_ECC */ | ||
| #ifdef HAVE_ED25519 | ||
| if (info->pk.type == WC_PK_TYPE_ED25519_SIGN) { | ||
|
|
@@ -28306,6 +28335,304 @@ static int test_CryptoCb_Func(int thisDevId, wc_CryptoInfo* info, void* ctx) | |
| } | ||
| } | ||
| #endif /* WOLF_CRYPTO_CB_FREE */ | ||
| #ifdef WOLF_CRYPTO_CB_SETKEY | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. MEDIUM-4: Significant code duplication between test callback implementations
Description: The SETKEY and EXPORT_KEY callback implementations in Recommendation: Consider extracting common callback helper functions into a shared test utility header, or use a common
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is currently no sharing code between The SETKEY/EXPORT_KEY handlers are the first significant duplication between them. Introducing a shared test utility header would be a new pattern for the repo. I can look at consolidating this in a follow-up if desired. |
||
| else if (info->algo_type == WC_ALGO_TYPE_SETKEY) { | ||
| #ifdef DEBUG_WOLFSSL | ||
| fprintf(stderr, "test_CryptoCb_Func: SetKey Type=%d\n", | ||
| info->setkey.type); | ||
| #endif | ||
| switch (info->setkey.type) { | ||
| #ifndef NO_AES | ||
| case WC_SETKEY_AES: | ||
| { | ||
| Aes* aes = (Aes*)info->setkey.obj; | ||
| aes->devId = INVALID_DEVID; | ||
| ret = wc_AesSetKey(aes, | ||
| (const byte*)info->setkey.key, info->setkey.keySz, | ||
| (const byte*)info->setkey.aux, info->setkey.flags); | ||
| aes->devId = thisDevId; | ||
| break; | ||
| } | ||
| #endif /* !NO_AES */ | ||
| #ifndef NO_HMAC | ||
| case WC_SETKEY_HMAC: | ||
| { | ||
| Hmac* hmac = (Hmac*)info->setkey.obj; | ||
| hmac->devId = INVALID_DEVID; | ||
| ret = wc_HmacSetKey(hmac, hmac->macType, | ||
| (const byte*)info->setkey.key, info->setkey.keySz); | ||
| hmac->devId = thisDevId; | ||
| break; | ||
| } | ||
| #endif /* !NO_HMAC */ | ||
| #if !defined(NO_RSA) && defined(WOLFSSL_KEY_TO_DER) | ||
| case WC_SETKEY_RSA_PUB: | ||
| { | ||
| RsaKey* rsaObj = (RsaKey*)info->setkey.obj; | ||
| RsaKey* rsaTmp = (RsaKey*)info->setkey.key; | ||
| int derSz; | ||
| word32 idx = 0; | ||
| byte* der = NULL; | ||
|
|
||
| derSz = wc_RsaPublicKeyDerSize(rsaTmp, 1); | ||
| if (derSz <= 0) { ret = derSz; break; } | ||
|
|
||
| der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); | ||
| if (der == NULL) { ret = MEMORY_E; break; } | ||
|
|
||
| derSz = wc_RsaKeyToPublicDer_ex(rsaTmp, der, | ||
| (word32)derSz, 1); | ||
| if (derSz <= 0) { | ||
| XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); | ||
| ret = derSz; break; | ||
| } | ||
|
|
||
| rsaObj->devId = INVALID_DEVID; | ||
| ret = wc_RsaPublicKeyDecode(der, &idx, rsaObj, | ||
| (word32)derSz); | ||
| rsaObj->devId = thisDevId; | ||
| XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); | ||
| break; | ||
| } | ||
| case WC_SETKEY_RSA_PRIV: | ||
| { | ||
| RsaKey* rsaObj = (RsaKey*)info->setkey.obj; | ||
| RsaKey* rsaTmp = (RsaKey*)info->setkey.key; | ||
| int derSz; | ||
| word32 idx = 0; | ||
| byte* der = NULL; | ||
|
|
||
| derSz = wc_RsaKeyToDer(rsaTmp, NULL, 0); | ||
| if (derSz <= 0) { ret = derSz; break; } | ||
|
|
||
| der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); | ||
| if (der == NULL) { ret = MEMORY_E; break; } | ||
|
|
||
| derSz = wc_RsaKeyToDer(rsaTmp, der, (word32)derSz); | ||
| if (derSz <= 0) { | ||
| XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); | ||
| ret = derSz; break; | ||
| } | ||
|
|
||
| rsaObj->devId = INVALID_DEVID; | ||
| ret = wc_RsaPrivateKeyDecode(der, &idx, rsaObj, | ||
| (word32)derSz); | ||
| rsaObj->devId = thisDevId; | ||
| XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); | ||
| break; | ||
| } | ||
| #endif /* !NO_RSA && WOLFSSL_KEY_TO_DER */ | ||
| #if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && \ | ||
| defined(HAVE_ECC_KEY_IMPORT) | ||
| case WC_SETKEY_ECC_PUB: | ||
| { | ||
| ecc_key* eccObj = (ecc_key*)info->setkey.obj; | ||
| ecc_key* eccTmp = (ecc_key*)info->setkey.key; | ||
| word32 bufSz = ECC_BUFSIZE; | ||
| int curveId; | ||
| WC_DECLARE_VAR(buf, byte, ECC_BUFSIZE, NULL); | ||
| WC_ALLOC_VAR(buf, byte, ECC_BUFSIZE, NULL); | ||
| if (!WC_VAR_OK(buf)) { | ||
| ret = MEMORY_E; | ||
| break; | ||
| } | ||
|
|
||
| ret = wc_ecc_export_x963(eccTmp, buf, &bufSz); | ||
| if (ret != 0) { | ||
| WC_FREE_VAR(buf, NULL); | ||
| break; | ||
| } | ||
|
|
||
| curveId = wc_ecc_get_curve_id(eccTmp->idx); | ||
| eccObj->devId = INVALID_DEVID; | ||
| ret = wc_ecc_import_x963_ex2(buf, bufSz, eccObj, curveId, 0); | ||
| eccObj->devId = thisDevId; | ||
|
|
||
| WC_FREE_VAR(buf, NULL); | ||
| break; | ||
| } | ||
| case WC_SETKEY_ECC_PRIV: | ||
| { | ||
| ecc_key* eccObj = (ecc_key*)info->setkey.obj; | ||
| ecc_key* eccTmp = (ecc_key*)info->setkey.key; | ||
| word32 pubSz = ECC_BUFSIZE; | ||
| word32 privSz = MAX_ECC_BYTES; | ||
| byte* pubPtr = NULL; | ||
| int curveId; | ||
| WC_DECLARE_VAR(pubBuf, byte, ECC_BUFSIZE, NULL); | ||
| WC_DECLARE_VAR(privBuf, byte, MAX_ECC_BYTES, NULL); | ||
| WC_ALLOC_VAR(pubBuf, byte, ECC_BUFSIZE, NULL); | ||
| WC_ALLOC_VAR(privBuf, byte, MAX_ECC_BYTES, NULL); | ||
| if (!WC_VAR_OK(pubBuf) || !WC_VAR_OK(privBuf)) { | ||
| WC_FREE_VAR(pubBuf, NULL); | ||
| WC_FREE_VAR(privBuf, NULL); | ||
| ret = MEMORY_E; | ||
| break; | ||
| } | ||
|
|
||
| /* Export public key from temp (if available) */ | ||
| if (eccTmp->type != ECC_PRIVATEKEY_ONLY) { | ||
| ret = wc_ecc_export_x963(eccTmp, pubBuf, &pubSz); | ||
| if (ret != 0) { | ||
| WC_FREE_VAR(pubBuf, NULL); | ||
| WC_FREE_VAR(privBuf, NULL); | ||
| break; | ||
| } | ||
| pubPtr = pubBuf; | ||
| } | ||
|
|
||
| ret = wc_ecc_export_private_only(eccTmp, privBuf, &privSz); | ||
| if (ret != 0) { | ||
| WC_FREE_VAR(pubBuf, NULL); | ||
| WC_FREE_VAR(privBuf, NULL); | ||
| break; | ||
| } | ||
|
|
||
| curveId = wc_ecc_get_curve_id(eccTmp->idx); | ||
| eccObj->devId = INVALID_DEVID; | ||
| ret = wc_ecc_import_private_key_ex(privBuf, privSz, | ||
| pubPtr, (pubPtr != NULL) ? pubSz : 0, | ||
| eccObj, curveId); | ||
| eccObj->devId = thisDevId; | ||
|
|
||
| WC_FREE_VAR(pubBuf, NULL); | ||
| WC_FREE_VAR(privBuf, NULL); | ||
| break; | ||
| } | ||
| #endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT && HAVE_ECC_KEY_IMPORT */ | ||
| default: | ||
| ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN); | ||
| break; | ||
| } | ||
| } | ||
| #endif /* WOLF_CRYPTO_CB_SETKEY */ | ||
| #ifdef WOLF_CRYPTO_CB_EXPORT_KEY | ||
| else if (info->algo_type == WC_ALGO_TYPE_EXPORT_KEY) { | ||
| #ifdef DEBUG_WOLFSSL | ||
| fprintf(stderr, "test_CryptoCb_Func: ExportKey Type=%d\n", | ||
| info->export_key.type); | ||
| #endif | ||
| switch (info->export_key.type) { | ||
| #if !defined(NO_RSA) && defined(WOLFSSL_KEY_TO_DER) | ||
| case WC_PK_TYPE_RSA: | ||
| { | ||
| RsaKey* src = (RsaKey*)info->export_key.obj; | ||
| RsaKey* dst = (RsaKey*)info->export_key.out; | ||
| int derSz; | ||
| word32 idx = 0; | ||
| byte* der = NULL; | ||
|
|
||
| /* Try private key export first, fall back to public */ | ||
| derSz = wc_RsaKeyToDer(src, NULL, 0); | ||
| if (derSz > 0) { | ||
| der = (byte*)XMALLOC(derSz, NULL, | ||
| DYNAMIC_TYPE_TMP_BUFFER); | ||
| if (der == NULL) { ret = MEMORY_E; break; } | ||
| derSz = wc_RsaKeyToDer(src, der, (word32)derSz); | ||
| if (derSz > 0) { | ||
| ret = wc_RsaPrivateKeyDecode(der, &idx, dst, | ||
| (word32)derSz); | ||
| } | ||
| else { | ||
| ret = derSz; | ||
| } | ||
| XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); | ||
| } | ||
| else { | ||
| /* Public key only */ | ||
| derSz = wc_RsaPublicKeyDerSize(src, 1); | ||
| if (derSz <= 0) { ret = derSz; break; } | ||
| der = (byte*)XMALLOC(derSz, NULL, | ||
| DYNAMIC_TYPE_TMP_BUFFER); | ||
| if (der == NULL) { ret = MEMORY_E; break; } | ||
| derSz = wc_RsaKeyToPublicDer_ex(src, der, | ||
| (word32)derSz, 1); | ||
| if (derSz > 0) { | ||
| ret = wc_RsaPublicKeyDecode(der, &idx, dst, | ||
| (word32)derSz); | ||
| } | ||
| else { | ||
| ret = derSz; | ||
| } | ||
| XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); | ||
| } | ||
| break; | ||
| } | ||
| #endif /* !NO_RSA && WOLFSSL_KEY_TO_DER */ | ||
| #if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && \ | ||
| defined(HAVE_ECC_KEY_IMPORT) | ||
| case WC_PK_TYPE_ECDSA_SIGN: /* ECC key */ | ||
| { | ||
| ecc_key* src = (ecc_key*)info->export_key.obj; | ||
| ecc_key* dst = (ecc_key*)info->export_key.out; | ||
| word32 pubSz = ECC_BUFSIZE; | ||
| word32 privSz = MAX_ECC_BYTES; | ||
| byte* pubPtr = NULL; | ||
| int curveId; | ||
| WC_DECLARE_VAR(pubBuf, byte, ECC_BUFSIZE, NULL); | ||
| WC_DECLARE_VAR(privBuf, byte, MAX_ECC_BYTES, NULL); | ||
| WC_ALLOC_VAR(pubBuf, byte, ECC_BUFSIZE, NULL); | ||
| WC_ALLOC_VAR(privBuf, byte, MAX_ECC_BYTES, NULL); | ||
| if (!WC_VAR_OK(pubBuf) || !WC_VAR_OK(privBuf)) { | ||
| WC_FREE_VAR(pubBuf, NULL); | ||
| WC_FREE_VAR(privBuf, NULL); | ||
| ret = MEMORY_E; | ||
| break; | ||
| } | ||
|
|
||
| /* Use software to export from src - prevent recursion */ | ||
| { | ||
| int savedDevId = src->devId; | ||
| src->devId = INVALID_DEVID; | ||
|
|
||
| /* 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; | ||
| } | ||
|
|
||
| /* 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); | ||
| break; | ||
| } | ||
| #endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT && HAVE_ECC_KEY_IMPORT */ | ||
| default: | ||
| ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN); | ||
| break; | ||
| } | ||
| } | ||
| #endif /* WOLF_CRYPTO_CB_EXPORT_KEY */ | ||
| (void)thisDevId; | ||
| (void)keyFormat; | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LOW-8: New CI test configurations don't cover WOLF_CRYPTO_CB_FIND interaction
.github/workflows/os-check.yml:87-92Description: Six new CI configurations test various
--enable-cryptocbutilscombinations but none test the interaction withWOLF_CRYPTO_CB_FIND. Several code paths have#ifndef WOLF_CRYPTO_CB_FINDguards that change behavior (e.g., skipping thedevId != INVALID_DEVIDcheck). Testing this combination would increase coverage of the new feature.Recommendation: Consider adding at least one CI config that combines
--enable-cryptocbutilswithWOLF_CRYPTO_CB_FIND.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'--enable-cryptocb --enable-keygen --enable-cryptocbutils=setkey,export CPPFLAGS="-DWOLF_CRYPTO_CB_FIND"'. Also fixed a pre-existing NULL pointer dereference inwc_RsaPrivateKeyDecode(asn.c) where*inOutIdxwas accessed in the SETKEY block before validatinginOutIdx != NULL. WithWOLF_CRYPTO_CB_FINDthe SETKEY block runs unconditionally, so the bad-args test case (which passes NULL) crashed. Added early NULL check forinputandinOutIdxparameters.