diff --git a/.github/workflows/cryptocb-only.yml b/.github/workflows/cryptocb-only.yml index ec1f5d09185..d692bab88fb 100644 --- a/.github/workflows/cryptocb-only.yml +++ b/.github/workflows/cryptocb-only.yml @@ -202,6 +202,9 @@ jobs: {"name": "only", "minutes": 6.0, "comment": "Same coverage as the \"all\" entry above, but driven by ./configure --enable-cryptocb=only instead of a hand-written CPPFLAGS list. This is the regression test for the configure option: it must emit exactly the WOLF_CRYPTO_CB_ONLY_* set that \"all\" passes by hand, for the algorithms enabled here. The \"all\" entry deliberately stays on explicit CPPFLAGS so a bug in the configure logic cannot silently weaken both. Note the base already passes --enable-cryptocb; this entry's flags are appended after the base, so --enable-cryptocb=only wins.", "configure": ["--enable-lms", "--enable-xmss", "--enable-cryptocb=only"]}, + {"name": "keygen-sw-fallback", "minutes": 4.0, + "comment": "WOLF_CRYPTO_CB_KEYGEN_SW_FALLBACK: an id or label key whose registered device declines key generation is generated in software again instead of failing with NO_VALID_DEVID. test_wc_ecc_make_key_id_dev checks that fallback here; every other entry builds the default, which refuses. No ONLY_* strip, so software key generation is available.", + "configure": ["CPPFLAGS=-DWOLF_CRYPTO_CB_KEYGEN_SW_FALLBACK"]}, {"name": "setkey", "minutes": 4.0, "comment": "--enable-cryptocbutils enables all cryptocb utilities (COPY/FREE/SETKEY/EXPORT_KEY/KEYSTORE); WOLF_CRYPTO_CB_SETKEY is what lets test_wc_CryptoCb_TLS_CBC_HMAC run -- a TLS 1.2 CBC MtE handshake whose record HMAC is computed by a key-owning callback, the only config exercising the TLS_hmac update/final routing. No ONLY_* strip, so the device's software HMAC keeps its providers.", "configure": ["--enable-cryptocbutils"]} diff --git a/.wolfssl_known_macro_extras b/.wolfssl_known_macro_extras index d3e40bbef91..ab031e19165 100644 --- a/.wolfssl_known_macro_extras +++ b/.wolfssl_known_macro_extras @@ -1303,6 +1303,7 @@ WOLFSSL_nRF5x_SDK_15_2 WOLF_ALLOW_BUILTIN WOLF_CONF_ASN_TIME WOLF_CRYPTO_CB_ASYNC_POLL +WOLF_CRYPTO_CB_KEYGEN_SW_FALLBACK WOLF_CRYPTO_CB_ONLY_SHA WOLF_CRYPTO_CB_SHAKE_XOF WOLF_CRYPTO_DEV diff --git a/doc/dox_comments/header_files/ecc.h b/doc/dox_comments/header_files/ecc.h index a89b057b485..d9148cf24d4 100644 --- a/doc/dox_comments/header_files/ecc.h +++ b/doc/dox_comments/header_files/ecc.h @@ -31,6 +31,10 @@ ecc key \return MP_MEM may be returned if there is an error while computing the ecc key + \return NO_VALID_DEVID if the key was initialized with an id or label and + its devId, or the device a WOLF_CRYPTO_CB_FIND callback picks for it, is a + registered device that did not generate it, unless + WOLF_CRYPTO_CB_KEYGEN_SW_FALLBACK is defined. \param rng pointer to an initialized RNG object with which to generate the key @@ -85,6 +89,10 @@ int wc_ecc_make_key(WC_RNG* rng, int keysize, ecc_key* key); ecc key \return MP_MEM may be returned if there is an error while computing the ecc key + \return NO_VALID_DEVID if the key was initialized with an id or label and + its devId, or the device a WOLF_CRYPTO_CB_FIND callback picks for it, is a + registered device that did not generate it, unless + WOLF_CRYPTO_CB_KEYGEN_SW_FALLBACK is defined. \param key Pointer to store the created key. \param keysize size of key to be created in bytes, set based on curveId @@ -2465,6 +2473,10 @@ const char* wc_ecc_get_name(int curve_id); \brief Makes ECC key with extended options. \return 0 on success + \return NO_VALID_DEVID if the key was initialized with an id or label and + its devId, or the device a WOLF_CRYPTO_CB_FIND callback picks for it, is a + registered device that did not generate it, unless + WOLF_CRYPTO_CB_KEYGEN_SW_FALLBACK is defined. \return negative on error \param rng Random number generator diff --git a/doc/dox_comments/header_files/ed25519.h b/doc/dox_comments/header_files/ed25519.h index 1391cb3b383..4e741c6e3e0 100644 --- a/doc/dox_comments/header_files/ed25519.h +++ b/doc/dox_comments/header_files/ed25519.h @@ -53,6 +53,10 @@ int wc_ed25519_make_public(ed25519_key* key, unsigned char* pubKey, specified key size is not 32 bytes (Ed25519 has 32 byte keys). \return MEMORY_E Returned if there is an error allocating memory during function execution. + \return NO_VALID_DEVID if the key was initialized with an id or label and + its devId, or the device a WOLF_CRYPTO_CB_FIND callback picks for it, is a + registered device that did not generate it, unless + WOLF_CRYPTO_CB_KEYGEN_SW_FALLBACK is defined. \param [in] rng Pointer to an initialized RNG object with which to generate the key. diff --git a/doc/dox_comments/header_files/ed448.h b/doc/dox_comments/header_files/ed448.h index 05f588fcba1..50f33a6775c 100644 --- a/doc/dox_comments/header_files/ed448.h +++ b/doc/dox_comments/header_files/ed448.h @@ -52,6 +52,10 @@ int wc_ed448_make_public(ed448_key* key, unsigned char* pubKey, specified key size is not 57 bytes (Ed448 has 57 byte keys). \return MEMORY_E Returned if there is an error allocating memory during function execution. + \return NO_VALID_DEVID if the key was initialized with an id or label and + its devId, or the device a WOLF_CRYPTO_CB_FIND callback picks for it, is a + registered device that did not generate it, unless + WOLF_CRYPTO_CB_KEYGEN_SW_FALLBACK is defined. \param [in] rng Pointer to an initialized RNG object with which to generate the key. diff --git a/doc/dox_comments/header_files/falcon.h b/doc/dox_comments/header_files/falcon.h index 2cf1533a0e4..6f94f6d8681 100644 --- a/doc/dox_comments/header_files/falcon.h +++ b/doc/dox_comments/header_files/falcon.h @@ -176,6 +176,10 @@ void wc_falcon_free(falcon_key* key); \return 0 on success. \return BAD_FUNC_ARG if key or rng is NULL or the level is unset. \return MEMORY_E on allocation failure. + \return NO_VALID_DEVID if the key was initialized with an id or label and + its devId, or the device a WOLF_CRYPTO_CB_FIND callback picks for it, is a + registered device that did not generate it, unless + WOLF_CRYPTO_CB_KEYGEN_SW_FALLBACK is defined. \param [in,out] key Pointer to an initialized falcon_key with a level set. \param [in] rng Pointer to an initialized WC_RNG. diff --git a/doc/dox_comments/header_files/rsa.h b/doc/dox_comments/header_files/rsa.h index bcab1a9147d..f6c29bf1dd5 100644 --- a/doc/dox_comments/header_files/rsa.h +++ b/doc/dox_comments/header_files/rsa.h @@ -1519,6 +1519,10 @@ int wc_RsaKeyToPublicDer_ex(RsaKey* key, byte* output, word32 outLen, library used while generating the RSA key \return MP_ZERO_E May be returned if there is an error in the math library used while generating the RSA key + \return NO_VALID_DEVID if the key was initialized with an id or label and + its devId, or the device a WOLF_CRYPTO_CB_FIND callback picks for it, is a + registered device that did not generate it, unless + WOLF_CRYPTO_CB_KEYGEN_SW_FALLBACK is defined. \param key pointer to the RsaKey structure in which to store the generated private key diff --git a/doc/dox_comments/header_files/wc_lms.h b/doc/dox_comments/header_files/wc_lms.h index 4ceb791e04f..c57f3ad08ef 100644 --- a/doc/dox_comments/header_files/wc_lms.h +++ b/doc/dox_comments/header_files/wc_lms.h @@ -319,6 +319,10 @@ int wc_LmsKey_SetContext(LmsKey* key, void* context); \return 0 on success. \return BAD_FUNC_ARG if any required pointer is NULL. \return MEMORY_E on allocation failure. + \return NO_VALID_DEVID if the key was initialized with an id or label and + its devId, or the device a WOLF_CRYPTO_CB_FIND callback picks for it, is a + registered device that did not generate it, unless + WOLF_CRYPTO_CB_KEYGEN_SW_FALLBACK is defined. \param [in,out] key Pointer to an LmsKey in state WC_LMS_STATE_PARMSET with callbacks set. diff --git a/doc/dox_comments/header_files/wc_mldsa.h b/doc/dox_comments/header_files/wc_mldsa.h index f55e32ec397..2719e1df060 100644 --- a/doc/dox_comments/header_files/wc_mldsa.h +++ b/doc/dox_comments/header_files/wc_mldsa.h @@ -226,6 +226,10 @@ void wc_MlDsaKey_Free(wc_MlDsaKey* key); \return 0 on success. \return BAD_FUNC_ARG if key or rng is NULL. \return MEMORY_E on allocation failure. + \return NO_VALID_DEVID if the key was initialized with an id or label and + its devId, or the device a WOLF_CRYPTO_CB_FIND callback picks for it, is a + registered device that did not generate it, unless + WOLF_CRYPTO_CB_KEYGEN_SW_FALLBACK is defined. \param [in,out] key Pointer to a wc_MlDsaKey with parameters set. \param [in] rng Pointer to an initialized WC_RNG. diff --git a/doc/dox_comments/header_files/wc_mlkem.h b/doc/dox_comments/header_files/wc_mlkem.h index 4eaabd18918..bd8d0ebd45b 100644 --- a/doc/dox_comments/header_files/wc_mlkem.h +++ b/doc/dox_comments/header_files/wc_mlkem.h @@ -176,6 +176,10 @@ int wc_MlKemKey_Init_Label(MlKemKey* key, int type, const char* label, \return 0 on success. \return BAD_FUNC_ARG if key or rng is NULL. \return MEMORY_E on allocation failure. + \return NO_VALID_DEVID if the key was initialized with an id or label and + its devId, or the device a WOLF_CRYPTO_CB_FIND callback picks for it, is a + registered device that did not generate it, unless + WOLF_CRYPTO_CB_KEYGEN_SW_FALLBACK is defined. \param [in,out] key Pointer to an initialized MlKemKey. \param [in] rng Pointer to an initialized WC_RNG. diff --git a/doc/dox_comments/header_files/wc_slhdsa.h b/doc/dox_comments/header_files/wc_slhdsa.h index 004990f90c4..a9f634afc45 100644 --- a/doc/dox_comments/header_files/wc_slhdsa.h +++ b/doc/dox_comments/header_files/wc_slhdsa.h @@ -168,6 +168,10 @@ void wc_SlhDsaKey_Free(SlhDsaKey* key); \return 0 on success. \return BAD_FUNC_ARG if key or rng is NULL, or key is not initialized. + \return NO_VALID_DEVID if the key was initialized with an id or label and + its devId, or the device a WOLF_CRYPTO_CB_FIND callback picks for it, is a + registered device that did not generate it, unless + WOLF_CRYPTO_CB_KEYGEN_SW_FALLBACK is defined. \param [in,out] key Pointer to an initialized SlhDsaKey. \param [in] rng Pointer to an initialized WC_RNG. diff --git a/doc/dox_comments/header_files/wc_xmss.h b/doc/dox_comments/header_files/wc_xmss.h index 014efedeeb0..17310989b2d 100644 --- a/doc/dox_comments/header_files/wc_xmss.h +++ b/doc/dox_comments/header_files/wc_xmss.h @@ -232,6 +232,10 @@ int wc_XmssKey_SetContext(XmssKey* key, void* context); \return 0 on success. \return BAD_FUNC_ARG if any required pointer is NULL. \return MEMORY_E on allocation failure. + \return NO_VALID_DEVID if the key was initialized with an id or label and + its devId, or the device a WOLF_CRYPTO_CB_FIND callback picks for it, is a + registered device that did not generate it, unless + WOLF_CRYPTO_CB_KEYGEN_SW_FALLBACK is defined. \param [in,out] key Pointer to an XmssKey in state WC_XMSS_STATE_PARMSET with callbacks set. diff --git a/tests/api.c b/tests/api.c index eba7bf436ae..b470384e61f 100644 --- a/tests/api.c +++ b/tests/api.c @@ -36372,15 +36372,7 @@ static int test_CryptoCb_Func(int thisDevId, wc_CryptoInfo* info, void* ctx) #endif /* ifdef WOLF_CRYPTO_CB_RSA_PAD */ #endif /* !NO_RSA */ #ifdef HAVE_ECC - if (info->pk.type == WC_PK_TYPE_EC_KEYGEN) { - /* mark this key as ephemeral */ - if (info->pk.eckg.key != NULL) { - XSTRNCPY(info->pk.eckg.key->label, "ephemeral", - sizeof(info->pk.eckg.key->label)); - info->pk.eckg.key->labelLen = (int)XSTRLEN(info->pk.eckg.key->label); - } - } - else if (info->pk.type == WC_PK_TYPE_ECDSA_SIGN) { + if (info->pk.type == WC_PK_TYPE_ECDSA_SIGN) { ecc_key key; /* perform software based ECC sign */ @@ -36389,11 +36381,11 @@ static int test_CryptoCb_Func(int thisDevId, wc_CryptoInfo* info, void* ctx) #endif if (info->pk.eccsign.key != NULL && - XSTRCMP(info->pk.eccsign.key->label, "ephemeral") == 0) { - /* this is an empheral key */ + info->pk.eccsign.key->type == ECC_PRIVATEKEY) { + /* skip keys generated in software */ #ifdef DEBUG_WOLFSSL fprintf(stderr, "test_CryptoCb_Func: skipping signing op on " - "ephemeral key\n"); + "software key\n"); #endif return CRYPTOCB_UNAVAILABLE; } diff --git a/tests/api/test_ecc.c b/tests/api/test_ecc.c index 2bfbc899c47..60717cdae5b 100644 --- a/tests/api/test_ecc.c +++ b/tests/api/test_ecc.c @@ -4819,3 +4819,196 @@ int test_wc_EccPublicKeyDecode_specifiedOverflow(void) #endif return EXPECT_RESULT(); } /* END test_wc_EccPublicKeyDecode_specifiedOverflow */ + +#if defined(HAVE_ECC) && defined(WOLF_CRYPTO_CB) && \ + defined(WOLF_PRIVATE_KEY_ID) && !defined(WC_NO_RNG) && \ + !defined(NO_ECC256) && !defined(NO_ECC_SECP) && \ + (!defined(ECC_MIN_KEY_SZ) || (ECC_MIN_KEY_SZ <= 256)) && \ + !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) + #define TEST_ECC_KEYGEN_ID +#endif + +#ifdef TEST_ECC_KEYGEN_ID +#define ECC_KEYGEN_ID_DEVID 2401 + +static int ecc_keygen_decline_cb(int devIdArg, wc_CryptoInfo* info, void* ctx) +{ + (void)devIdArg; + (void)info; + (void)ctx; + return WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); +} + +#ifdef WC_CRYPTOCB_KEYGEN_ID_CHECK +static int ecc_keygen_clear_cb(int devIdArg, wc_CryptoInfo* info, void* ctx) +{ + (void)devIdArg; + (void)ctx; + + if ((info->algo_type == WC_ALGO_TYPE_PK) && + (info->pk.type == WC_PK_TYPE_EC_KEYGEN)) { + info->pk.eckg.key->devId = INVALID_DEVID; + } + return WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); +} + +#ifdef WOLF_CRYPTO_CB_FIND +#ifdef WOLFSSL_SWDEV + #include +#endif +static int ecc_keygen_find_cb(int devIdArg, int algoType) +{ + if ((devIdArg == INVALID_DEVID) && (algoType == WC_ALGO_TYPE_PK)) + return ECC_KEYGEN_ID_DEVID; + return devIdArg; +} +#endif + +#if defined(HAVE_ECC_DHE) && !defined(WOLF_CRYPTO_CB_ONLY_ECC) && \ + !defined(WOLFSSL_ASYNC_CRYPT) +/* Generates in software on the caller's key, as many device callbacks do. */ +static int ecc_keygen_sw_cb(int devIdArg, wc_CryptoInfo* info, void* ctx) +{ + int ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); + + (void)ctx; + + if ((info->algo_type == WC_ALGO_TYPE_PK) && + (info->pk.type == WC_PK_TYPE_EC_KEYGEN)) { + info->pk.eckg.key->devId = INVALID_DEVID; + ret = wc_ecc_make_key_ex(info->pk.eckg.rng, info->pk.eckg.size, + info->pk.eckg.key, info->pk.eckg.curveId); + info->pk.eckg.key->devId = devIdArg; + } + return ret; +} +#endif +#endif /* WC_CRYPTOCB_KEYGEN_ID_CHECK */ +#endif /* TEST_ECC_KEYGEN_ID */ + +/* + * Testing wc_ecc_make_key() on an id or label key whose device declines keygen. + */ +int test_wc_ecc_make_key_id_dev(void) +{ + EXPECT_DECLS; +#if defined(TEST_ECC_KEYGEN_ID) && defined(WC_CRYPTOCB_KEYGEN_ID_CHECK) + int devId = ECC_KEYGEN_ID_DEVID; +#ifndef WOLF_CRYPTO_CB_ONLY_ECC + int ret; +#endif + ecc_key key; + WC_RNG rng; + byte id[] = { 0x01, 0x02, 0x03, 0x04 }; + + XMEMSET(&key, 0, sizeof(key)); + XMEMSET(&rng, 0, sizeof(rng)); + ExpectIntEQ(wc_InitRng(&rng), 0); + ExpectIntEQ(wc_CryptoCb_RegisterDevice(devId, ecc_keygen_decline_cb, NULL), + 0); + + ExpectIntEQ(wc_ecc_init_id(&key, id, (int)sizeof(id), NULL, devId), 0); + ExpectIntEQ(wc_ecc_make_key(&rng, 32, &key), + WC_NO_ERR_TRACE(NO_VALID_DEVID)); + wc_ecc_free(&key); + + ExpectIntEQ(wc_ecc_init_label(&key, "dev-key", NULL, devId), 0); + ExpectIntEQ(wc_ecc_make_key(&rng, 32, &key), + WC_NO_ERR_TRACE(NO_VALID_DEVID)); + wc_ecc_free(&key); + + ExpectIntEQ(wc_CryptoCb_RegisterDevice(devId + 300, ecc_keygen_clear_cb, + NULL), 0); + ExpectIntEQ(wc_ecc_init_id(&key, id, (int)sizeof(id), NULL, devId + 300), + 0); + ExpectIntEQ(wc_ecc_make_key(&rng, 32, &key), + WC_NO_ERR_TRACE(NO_VALID_DEVID)); + wc_ecc_free(&key); + wc_CryptoCb_UnRegisterDevice(devId + 300); + +#if !defined(WOLF_CRYPTO_CB_ONLY_ECC) + /* Without a registered device the key stays in software. */ + ExpectIntEQ(wc_ecc_init_id(&key, id, (int)sizeof(id), NULL, devId + 100), + 0); + ret = wc_ecc_make_key(&rng, 32, &key); +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_NONE); +#endif + ExpectIntEQ(ret, 0); + wc_ecc_free(&key); + + ExpectIntEQ(wc_ecc_init_ex(&key, NULL, devId), 0); + ret = wc_ecc_make_key(&rng, 32, &key); +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_NONE); +#endif + ExpectIntEQ(ret, 0); + wc_ecc_free(&key); +#endif + +#ifdef WOLF_CRYPTO_CB_FIND + wc_CryptoCb_SetDeviceFindCb(ecc_keygen_find_cb); + ExpectIntEQ(wc_ecc_init_id(&key, id, (int)sizeof(id), NULL, + INVALID_DEVID), 0); + ExpectIntEQ(wc_ecc_make_key(&rng, 32, &key), + WC_NO_ERR_TRACE(NO_VALID_DEVID)); + wc_ecc_free(&key); +#ifdef WOLFSSL_SWDEV + wc_CryptoCb_SetDeviceFindCb(wc_SwDev_FindCb); +#else + wc_CryptoCb_SetDeviceFindCb(NULL); +#endif +#endif + +#if defined(HAVE_ECC_DHE) && !defined(WOLF_CRYPTO_CB_ONLY_ECC) && \ + !defined(WOLFSSL_ASYNC_CRYPT) + ExpectIntEQ(wc_CryptoCb_RegisterDevice(devId + 200, ecc_keygen_sw_cb, + NULL), 0); + ExpectIntEQ(wc_ecc_init_id(&key, id, (int)sizeof(id), NULL, devId + 200), + 0); + ExpectIntEQ(wc_ecc_make_key(&rng, 32, &key), 0); + wc_ecc_free(&key); + wc_CryptoCb_UnRegisterDevice(devId + 200); +#endif + + wc_CryptoCb_UnRegisterDevice(devId); + DoExpectIntEQ(wc_FreeRng(&rng), 0); +#elif defined(TEST_ECC_KEYGEN_ID) + int devId = ECC_KEYGEN_ID_DEVID; + int ret; + ecc_key key; + WC_RNG rng; + byte id[] = { 0x01, 0x02, 0x03, 0x04 }; +#ifdef WOLF_CRYPTO_CB_ONLY_ECC + int expRet = WC_NO_ERR_TRACE(NO_VALID_DEVID); +#else + int expRet = 0; +#endif + + XMEMSET(&key, 0, sizeof(key)); + XMEMSET(&rng, 0, sizeof(rng)); + ExpectIntEQ(wc_InitRng(&rng), 0); + ExpectIntEQ(wc_CryptoCb_RegisterDevice(devId, ecc_keygen_decline_cb, NULL), + 0); + + ExpectIntEQ(wc_ecc_init_id(&key, id, (int)sizeof(id), NULL, devId), 0); + ret = wc_ecc_make_key(&rng, 32, &key); +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_NONE); +#endif + ExpectIntEQ(ret, expRet); + wc_ecc_free(&key); + + ExpectIntEQ(wc_ecc_init_label(&key, "dev-key", NULL, devId), 0); + ret = wc_ecc_make_key(&rng, 32, &key); +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_NONE); +#endif + ExpectIntEQ(ret, expRet); + wc_ecc_free(&key); + + wc_CryptoCb_UnRegisterDevice(devId); + DoExpectIntEQ(wc_FreeRng(&rng), 0); +#endif + return EXPECT_RESULT(); +} diff --git a/tests/api/test_ecc.h b/tests/api/test_ecc.h index 60bd0a70afe..3d6095df9dc 100644 --- a/tests/api/test_ecc.h +++ b/tests/api/test_ecc.h @@ -81,6 +81,7 @@ int test_wc_EccDecisionCoverage3(void); int test_wc_EccDecisionCoverage4(void); int test_wc_EccPublicKeyDecode_explicit_curve_size(void); int test_wc_EccPublicKeyDecode_specifiedOverflow(void); +int test_wc_ecc_make_key_id_dev(void); #define TEST_ECC_DECLS \ TEST_DECL_GROUP("ecc", test_wc_ecc_get_curve_size_from_name), \ @@ -140,6 +141,7 @@ int test_wc_EccPublicKeyDecode_specifiedOverflow(void); TEST_DECL_GROUP("ecc", test_wc_EccDecisionCoverage4), \ TEST_DECL_GROUP("ecc", \ test_wc_EccPublicKeyDecode_explicit_curve_size), \ - TEST_DECL_GROUP("ecc", test_wc_EccPublicKeyDecode_specifiedOverflow) + TEST_DECL_GROUP("ecc", test_wc_EccPublicKeyDecode_specifiedOverflow), \ + TEST_DECL_GROUP("ecc", test_wc_ecc_make_key_id_dev) #endif /* WOLFCRYPT_TEST_ECC_H */ diff --git a/tests/api/test_ed25519.c b/tests/api/test_ed25519.c index c41b07de1fb..3ee564ee03a 100644 --- a/tests/api/test_ed25519.c +++ b/tests/api/test_ed25519.c @@ -1604,3 +1604,65 @@ int test_wc_ed25519_make_public_dev_key(void) return EXPECT_RESULT(); } /* END test_wc_ed25519_make_public_dev_key */ +#if defined(HAVE_ED25519) && defined(HAVE_ED25519_MAKE_KEY) && \ + defined(WC_CRYPTOCB_KEYGEN_ID_CHECK) && !defined(WC_NO_RNG) && \ + !defined(HAVE_FIPS) +static int ed25519_keygen_decline_cb(int devIdArg, wc_CryptoInfo* info, + void* ctx) +{ + (void)devIdArg; + (void)info; + (void)ctx; + return WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); +} +#endif + +/* + * Testing wc_ed25519_make_key() on an id or label key whose device declines + * keygen. + */ +int test_wc_ed25519_make_key_id_dev(void) +{ + EXPECT_DECLS; +#if defined(HAVE_ED25519) && defined(HAVE_ED25519_MAKE_KEY) && \ + defined(WC_CRYPTOCB_KEYGEN_ID_CHECK) && !defined(WC_NO_RNG) && \ + !defined(HAVE_FIPS) + int devId = 2403; + ed25519_key key; + WC_RNG rng; + static const byte id[] = { 0x01, 0x02, 0x03, 0x04 }; + + XMEMSET(&key, 0, sizeof(key)); + XMEMSET(&rng, 0, sizeof(rng)); + ExpectIntEQ(wc_InitRng(&rng), 0); + ExpectIntEQ(wc_CryptoCb_RegisterDevice(devId, ed25519_keygen_decline_cb, + NULL), 0); + + ExpectIntEQ(wc_ed25519_init_id(&key, id, (int)sizeof(id), NULL, devId), 0); + ExpectIntEQ(wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &key), + WC_NO_ERR_TRACE(NO_VALID_DEVID)); + wc_ed25519_free(&key); + + ExpectIntEQ(wc_ed25519_init_label(&key, "dev-key", NULL, devId), 0); + ExpectIntEQ(wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &key), + WC_NO_ERR_TRACE(NO_VALID_DEVID)); + wc_ed25519_free(&key); + +#if !defined(WOLF_CRYPTO_CB_ONLY_ED25519) && \ + !defined(WOLF_CRYPTO_CB_ONLY_SHA512) + /* Without a registered device the key stays in software. */ + ExpectIntEQ(wc_ed25519_init_id(&key, id, (int)sizeof(id), NULL, + devId + 100), 0); + ExpectIntEQ(wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &key), 0); + wc_ed25519_free(&key); + + ExpectIntEQ(wc_ed25519_init_ex(&key, NULL, devId), 0); + ExpectIntEQ(wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &key), 0); + wc_ed25519_free(&key); +#endif + + wc_CryptoCb_UnRegisterDevice(devId); + DoExpectIntEQ(wc_FreeRng(&rng), 0); +#endif + return EXPECT_RESULT(); +} diff --git a/tests/api/test_ed25519.h b/tests/api/test_ed25519.h index 1f40c3c68c6..1fe607970b6 100644 --- a/tests/api/test_ed25519.h +++ b/tests/api/test_ed25519.h @@ -46,6 +46,7 @@ int test_wc_ed25519_check_key_edgecases(void); int test_wc_ed25519_import_variants(void); int test_wc_ed25519_make_public_argchecks(void); int test_wc_ed25519_make_public_dev_key(void); +int test_wc_ed25519_make_key_id_dev(void); #define TEST_ED25519_DECLS \ TEST_DECL_GROUP("ed25519", test_wc_ed25519_make_key), \ @@ -69,6 +70,7 @@ int test_wc_ed25519_make_public_dev_key(void); TEST_DECL_GROUP("ed25519", test_wc_ed25519_import_variants), \ TEST_DECL_GROUP("ed25519", test_wc_ed25519_make_public_argchecks), \ TEST_DECL_GROUP("ed25519", test_wc_ed25519_make_public_dev_key), \ - TEST_DECL_GROUP("ed25519", test_wc_Ed25519PrivateKeyDecode_ex) + TEST_DECL_GROUP("ed25519", test_wc_Ed25519PrivateKeyDecode_ex), \ + TEST_DECL_GROUP("ed25519", test_wc_ed25519_make_key_id_dev) #endif /* WOLFCRYPT_TEST_ED25519_H */ diff --git a/tests/api/test_ed448.c b/tests/api/test_ed448.c index 60578b5d455..15a5316336f 100644 --- a/tests/api/test_ed448.c +++ b/tests/api/test_ed448.c @@ -2125,3 +2125,60 @@ int test_wc_ed448_make_key_dev_error(void) #endif return EXPECT_RESULT(); } /* END test_wc_ed448_make_key_dev_error */ + +#if defined(HAVE_ED448) && defined(WC_CRYPTOCB_KEYGEN_ID_CHECK) && \ + !defined(WC_NO_RNG) && !defined(HAVE_FIPS) +static int ed448_keygen_decline_cb(int devIdArg, wc_CryptoInfo* info, void* ctx) +{ + (void)devIdArg; + (void)info; + (void)ctx; + return WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); +} +#endif + +/* + * Testing wc_ed448_make_key() on an id or label key whose device declines + * keygen. + */ +int test_wc_ed448_make_key_id_dev(void) +{ + EXPECT_DECLS; +#if defined(HAVE_ED448) && defined(WC_CRYPTOCB_KEYGEN_ID_CHECK) && \ + !defined(WC_NO_RNG) && !defined(HAVE_FIPS) + int devId = 2404; + ed448_key key; + WC_RNG rng; + static const byte id[] = { 0x01, 0x02, 0x03, 0x04 }; + + XMEMSET(&key, 0, sizeof(key)); + XMEMSET(&rng, 0, sizeof(rng)); + ExpectIntEQ(wc_InitRng(&rng), 0); + ExpectIntEQ(wc_CryptoCb_RegisterDevice(devId, ed448_keygen_decline_cb, + NULL), 0); + + ExpectIntEQ(wc_ed448_init_id(&key, id, (int)sizeof(id), NULL, devId), 0); + ExpectIntEQ(wc_ed448_make_key(&rng, ED448_KEY_SIZE, &key), + WC_NO_ERR_TRACE(NO_VALID_DEVID)); + wc_ed448_free(&key); + + ExpectIntEQ(wc_ed448_init_label(&key, "dev-key", NULL, devId), 0); + ExpectIntEQ(wc_ed448_make_key(&rng, ED448_KEY_SIZE, &key), + WC_NO_ERR_TRACE(NO_VALID_DEVID)); + wc_ed448_free(&key); + + /* Without a registered device the key stays in software. */ + ExpectIntEQ(wc_ed448_init_id(&key, id, (int)sizeof(id), NULL, devId + 100), + 0); + ExpectIntEQ(wc_ed448_make_key(&rng, ED448_KEY_SIZE, &key), 0); + wc_ed448_free(&key); + + ExpectIntEQ(wc_ed448_init_ex(&key, NULL, devId), 0); + ExpectIntEQ(wc_ed448_make_key(&rng, ED448_KEY_SIZE, &key), 0); + wc_ed448_free(&key); + + wc_CryptoCb_UnRegisterDevice(devId); + DoExpectIntEQ(wc_FreeRng(&rng), 0); +#endif + return EXPECT_RESULT(); +} diff --git a/tests/api/test_ed448.h b/tests/api/test_ed448.h index f82496a7c29..cf68a313287 100644 --- a/tests/api/test_ed448.h +++ b/tests/api/test_ed448.h @@ -50,6 +50,7 @@ int test_wc_ed448_check_key_decisions(void); int test_wc_ed448_cryptocb(void); int test_wc_ed448_make_public_dev_key(void); int test_wc_ed448_make_key_dev_error(void); +int test_wc_ed448_make_key_id_dev(void); #define TEST_ED448_DECLS \ TEST_DECL_GROUP("ed448", test_wc_ed448_make_key), \ @@ -77,6 +78,7 @@ int test_wc_ed448_make_key_dev_error(void); TEST_DECL_GROUP("ed448", test_wc_Ed448PrivateKeyDecode_ex), \ TEST_DECL_GROUP("ed448", test_wc_ed448_cryptocb), \ TEST_DECL_GROUP("ed448", test_wc_ed448_make_public_dev_key), \ - TEST_DECL_GROUP("ed448", test_wc_ed448_make_key_dev_error) + TEST_DECL_GROUP("ed448", test_wc_ed448_make_key_dev_error), \ + TEST_DECL_GROUP("ed448", test_wc_ed448_make_key_id_dev) #endif /* WOLFCRYPT_TEST_ED448_H */ diff --git a/tests/api/test_falcon.c b/tests/api/test_falcon.c index 3084477a5c2..a3831efc2b2 100644 --- a/tests/api/test_falcon.c +++ b/tests/api/test_falcon.c @@ -1969,3 +1969,69 @@ int test_falcon_verify_cb_res(void) #endif return EXPECT_RESULT(); } + +#if defined(HAVE_FALCON) && !defined(WOLFSSL_FALCON_VERIFY_ONLY) && \ + defined(WC_CRYPTOCB_KEYGEN_ID_CHECK) && \ + !defined(HAVE_FIPS) +static int falcon_keygen_decline_cb(int devIdArg, wc_CryptoInfo* info, + void* ctx) +{ + (void)devIdArg; + (void)info; + (void)ctx; + return WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); +} +#endif + +/* + * Testing wc_falcon_make_key() on an id or label key whose device declines + * keygen. + */ +int test_wc_falcon_make_key_id_dev(void) +{ + EXPECT_DECLS; +#if defined(HAVE_FALCON) && !defined(WOLFSSL_FALCON_VERIFY_ONLY) && \ + defined(WC_CRYPTOCB_KEYGEN_ID_CHECK) && \ + !defined(HAVE_FIPS) + int devId = 2407; + falcon_key key; + WC_RNG rng; + static const byte id[] = { 0x01, 0x02, 0x03, 0x04 }; + + XMEMSET(&key, 0, sizeof(key)); + XMEMSET(&rng, 0, sizeof(rng)); + ExpectIntEQ(wc_InitRng(&rng), 0); + ExpectIntEQ(wc_CryptoCb_RegisterDevice(devId, falcon_keygen_decline_cb, + NULL), 0); + + ExpectIntEQ(wc_falcon_init_id(&key, id, (int)sizeof(id), NULL, devId), 0); + ExpectIntEQ(wc_falcon_set_level(&key, falcon_levels[0]), 0); + ExpectIntEQ(wc_falcon_make_key(&key, &rng), + WC_NO_ERR_TRACE(NO_VALID_DEVID)); + wc_falcon_free(&key); + + ExpectIntEQ(wc_falcon_init_label(&key, "dev-key", NULL, devId), 0); + ExpectIntEQ(wc_falcon_set_level(&key, falcon_levels[0]), 0); + ExpectIntEQ(wc_falcon_make_key(&key, &rng), + WC_NO_ERR_TRACE(NO_VALID_DEVID)); + wc_falcon_free(&key); + +#if defined(WC_FALCON_HAVE_NATIVE_SIGN) && !defined(WOLF_CRYPTO_CB_ONLY_FALCON) + /* Without a registered device the key stays in software. */ + ExpectIntEQ(wc_falcon_init_id(&key, id, (int)sizeof(id), NULL, devId + 100), + 0); + ExpectIntEQ(wc_falcon_set_level(&key, falcon_levels[0]), 0); + ExpectIntEQ(wc_falcon_make_key(&key, &rng), 0); + wc_falcon_free(&key); + + ExpectIntEQ(wc_falcon_init_ex(&key, NULL, devId), 0); + ExpectIntEQ(wc_falcon_set_level(&key, falcon_levels[0]), 0); + ExpectIntEQ(wc_falcon_make_key(&key, &rng), 0); + wc_falcon_free(&key); +#endif + + wc_CryptoCb_UnRegisterDevice(devId); + DoExpectIntEQ(wc_FreeRng(&rng), 0); +#endif + return EXPECT_RESULT(); +} diff --git a/tests/api/test_falcon.h b/tests/api/test_falcon.h index 2c862e3a79f..ab8051022df 100644 --- a/tests/api/test_falcon.h +++ b/tests/api/test_falcon.h @@ -49,6 +49,7 @@ int test_wc_falcon_verify_oom(void); int test_wc_FalconDecisionCoverage(void); int test_falcon_cb_free(void); int test_falcon_verify_cb_res(void); +int test_wc_falcon_make_key_id_dev(void); #define TEST_FALCON_DECLS \ TEST_DECL_GROUP("falcon", test_wc_falcon_sizes), \ @@ -65,6 +66,7 @@ int test_falcon_verify_cb_res(void); TEST_DECL_GROUP("falcon", test_wc_falcon_verify_oom), \ TEST_DECL_GROUP("falcon", test_wc_FalconDecisionCoverage), \ TEST_DECL_GROUP("falcon", test_falcon_cb_free), \ - TEST_DECL_GROUP("falcon", test_falcon_verify_cb_res) + TEST_DECL_GROUP("falcon", test_falcon_verify_cb_res), \ + TEST_DECL_GROUP("falcon", test_wc_falcon_make_key_id_dev) #endif /* WOLFCRYPT_TEST_FALCON_H */ diff --git a/tests/api/test_lms_xmss.c b/tests/api/test_lms_xmss.c index 4a995ebfc14..664f7c02ae5 100644 --- a/tests/api/test_lms_xmss.c +++ b/tests/api/test_lms_xmss.c @@ -3103,3 +3103,84 @@ int test_wc_XmssFeatureCoverage(void) #endif /* WOLFSSL_HAVE_XMSS && !WOLFSSL_XMSS_VERIFY_ONLY */ return EXPECT_RESULT(); } + +/* + * Testing wc_LmsKey_MakeKey() on an id or label key whose device declines + * keygen. + */ +int test_wc_LmsKey_make_key_id_dev(void) +{ + EXPECT_DECLS; +#if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_VERIFY_ONLY) && \ + defined(WC_CRYPTOCB_KEYGEN_ID_CHECK) && \ + !defined(HAVE_FIPS) + LmsKey key; + WC_RNG rng; + static const byte id[] = { 0x01, 0x02, 0x03, 0x04 }; + + XMEMSET(&key, 0, sizeof(key)); + XMEMSET(&rng, 0, sizeof(rng)); + ExpectIntEQ(wc_InitRng(&rng), 0); + ExpectIntEQ(wc_CryptoCb_RegisterDevice(TEST_LMS_XMSS_CRYPTOCB_DEVID, + test_lms_xmss_verify_cryptocb, NULL), 0); + + ExpectIntEQ(wc_LmsKey_InitId(&key, id, (int)sizeof(id), NULL, + TEST_LMS_XMSS_CRYPTOCB_DEVID), 0); + ExpectIntEQ(test_lms_set_params(&key), 0); + ExpectIntEQ(wc_LmsKey_MakeKey(&key, &rng), + WC_NO_ERR_TRACE(NO_VALID_DEVID)); + wc_LmsKey_Free(&key); + + ExpectIntEQ(wc_LmsKey_InitLabel(&key, "dev-key", NULL, + TEST_LMS_XMSS_CRYPTOCB_DEVID), 0); + ExpectIntEQ(test_lms_set_params(&key), 0); + ExpectIntEQ(wc_LmsKey_MakeKey(&key, &rng), + WC_NO_ERR_TRACE(NO_VALID_DEVID)); + wc_LmsKey_Free(&key); + + wc_CryptoCb_UnRegisterDevice(TEST_LMS_XMSS_CRYPTOCB_DEVID); + DoExpectIntEQ(wc_FreeRng(&rng), 0); +#endif + return EXPECT_RESULT(); +} + +/* + * Testing wc_XmssKey_MakeKey() on an id or label key whose device declines + * keygen. + */ +int test_wc_XmssKey_make_key_id_dev(void) +{ + EXPECT_DECLS; +#if defined(WOLFSSL_HAVE_XMSS) && !defined(WOLFSSL_XMSS_VERIFY_ONLY) && \ + defined(WC_CRYPTOCB_KEYGEN_ID_CHECK) && \ + !defined(HAVE_FIPS) && \ + defined(TEST_XMSS_H10_AVAILABLE) + XmssKey key; + WC_RNG rng; + static const byte id[] = { 0x01, 0x02, 0x03, 0x04 }; + + XMEMSET(&key, 0, sizeof(key)); + XMEMSET(&rng, 0, sizeof(rng)); + ExpectIntEQ(wc_InitRng(&rng), 0); + ExpectIntEQ(wc_CryptoCb_RegisterDevice(TEST_LMS_XMSS_CRYPTOCB_DEVID, + test_lms_xmss_verify_cryptocb, NULL), 0); + + ExpectIntEQ(wc_XmssKey_InitId(&key, id, (int)sizeof(id), NULL, + TEST_LMS_XMSS_CRYPTOCB_DEVID), 0); + ExpectIntEQ(wc_XmssKey_SetParamStr(&key, "XMSS-SHA2_10_256"), 0); + ExpectIntEQ(wc_XmssKey_MakeKey(&key, &rng), + WC_NO_ERR_TRACE(NO_VALID_DEVID)); + wc_XmssKey_Free(&key); + + ExpectIntEQ(wc_XmssKey_InitLabel(&key, "dev-key", NULL, + TEST_LMS_XMSS_CRYPTOCB_DEVID), 0); + ExpectIntEQ(wc_XmssKey_SetParamStr(&key, "XMSS-SHA2_10_256"), 0); + ExpectIntEQ(wc_XmssKey_MakeKey(&key, &rng), + WC_NO_ERR_TRACE(NO_VALID_DEVID)); + wc_XmssKey_Free(&key); + + wc_CryptoCb_UnRegisterDevice(TEST_LMS_XMSS_CRYPTOCB_DEVID); + DoExpectIntEQ(wc_FreeRng(&rng), 0); +#endif + return EXPECT_RESULT(); +} diff --git a/tests/api/test_lms_xmss.h b/tests/api/test_lms_xmss.h index 63f8873a118..70ab9890fdb 100644 --- a/tests/api/test_lms_xmss.h +++ b/tests/api/test_lms_xmss.h @@ -51,6 +51,8 @@ int test_wc_LmsDecisionCoverage(void); int test_wc_LmsFeatureCoverage(void); int test_wc_XmssDecisionCoverage(void); int test_wc_XmssFeatureCoverage(void); +int test_wc_LmsKey_make_key_id_dev(void); +int test_wc_XmssKey_make_key_id_dev(void); /* LMS, and RFC 9802 (HSS/LMS and XMSS/XMSS^MT in X.509). */ #define TEST_LMS_XMSS_DECLS \ @@ -80,6 +82,8 @@ int test_wc_XmssFeatureCoverage(void); TEST_DECL_GROUP("lms", test_wc_LmsDecisionCoverage), \ TEST_DECL_GROUP("lms", test_wc_LmsFeatureCoverage), \ TEST_DECL_GROUP("xmss", test_wc_XmssDecisionCoverage), \ - TEST_DECL_GROUP("xmss", test_wc_XmssFeatureCoverage) + TEST_DECL_GROUP("xmss", test_wc_XmssFeatureCoverage), \ + TEST_DECL_GROUP("lms", test_wc_LmsKey_make_key_id_dev), \ + TEST_DECL_GROUP("xmss", test_wc_XmssKey_make_key_id_dev) #endif /* WOLFCRYPT_TEST_LMS_XMSS_H */ diff --git a/tests/api/test_mldsa.c b/tests/api/test_mldsa.c index de7d147f111..30629b3ae4a 100644 --- a/tests/api/test_mldsa.c +++ b/tests/api/test_mldsa.c @@ -32867,3 +32867,77 @@ int test_mldsa_make_key_rej_ntt_fail(void) #endif return EXPECT_RESULT(); } + +#if defined(WOLFSSL_HAVE_MLDSA) && !defined(WOLFSSL_MLDSA_NO_MAKE_KEY) && \ + defined(WC_CRYPTOCB_KEYGEN_ID_CHECK) && \ + !defined(HAVE_FIPS) +static int mldsa_keygen_decline_cb(int devIdArg, wc_CryptoInfo* info, void* ctx) +{ + (void)devIdArg; + (void)info; + (void)ctx; + return WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); +} +#endif + +/* + * Testing wc_MlDsaKey_MakeKey() on an id or label key whose device declines + * keygen. + */ +int test_mldsa_make_key_id_dev(void) +{ + EXPECT_DECLS; +#if defined(WOLFSSL_HAVE_MLDSA) && !defined(WOLFSSL_MLDSA_NO_MAKE_KEY) && \ + defined(WC_CRYPTOCB_KEYGEN_ID_CHECK) && \ + !defined(HAVE_FIPS) + int devId = 2405; + wc_MlDsaKey* key; + WC_RNG rng; + static const byte id[] = { 0x01, 0x02, 0x03, 0x04 }; +#ifndef WOLFSSL_NO_ML_DSA_44 + byte level = WC_ML_DSA_44; +#elif !defined(WOLFSSL_NO_ML_DSA_65) + byte level = WC_ML_DSA_65; +#else + byte level = WC_ML_DSA_87; +#endif + + key = (wc_MlDsaKey*)XMALLOC(sizeof(*key), NULL, DYNAMIC_TYPE_TMP_BUFFER); + ExpectNotNull(key); + XMEMSET(&rng, 0, sizeof(rng)); + ExpectIntEQ(wc_InitRng(&rng), 0); + ExpectIntEQ(wc_CryptoCb_RegisterDevice(devId, mldsa_keygen_decline_cb, + NULL), 0); + + ExpectIntEQ(wc_MlDsaKey_InitId(key, id, (int)sizeof(id), NULL, devId), 0); + ExpectIntEQ(wc_MlDsaKey_SetParams(key, level), 0); + ExpectIntEQ(wc_MlDsaKey_MakeKey(key, &rng), + WC_NO_ERR_TRACE(NO_VALID_DEVID)); + wc_MlDsaKey_Free(key); + + ExpectIntEQ(wc_MlDsaKey_InitLabel(key, "dev-key", NULL, devId), 0); + ExpectIntEQ(wc_MlDsaKey_SetParams(key, level), 0); + ExpectIntEQ(wc_MlDsaKey_MakeKey(key, &rng), + WC_NO_ERR_TRACE(NO_VALID_DEVID)); + wc_MlDsaKey_Free(key); + +#if defined(WC_MLDSA_HAVE_NATIVE) && !defined(WOLF_CRYPTO_CB_ONLY_MLDSA) + /* Without a registered device the key stays in software. */ + ExpectIntEQ(wc_MlDsaKey_InitId(key, id, (int)sizeof(id), NULL, devId + 100), + 0); + ExpectIntEQ(wc_MlDsaKey_SetParams(key, level), 0); + ExpectIntEQ(wc_MlDsaKey_MakeKey(key, &rng), 0); + wc_MlDsaKey_Free(key); + + ExpectIntEQ(wc_MlDsaKey_Init(key, NULL, devId), 0); + ExpectIntEQ(wc_MlDsaKey_SetParams(key, level), 0); + ExpectIntEQ(wc_MlDsaKey_MakeKey(key, &rng), 0); + wc_MlDsaKey_Free(key); +#endif + + wc_CryptoCb_UnRegisterDevice(devId); + DoExpectIntEQ(wc_FreeRng(&rng), 0); + XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return EXPECT_RESULT(); +} diff --git a/tests/api/test_mldsa.h b/tests/api/test_mldsa.h index 51f3b8f91cd..683926b9b3e 100644 --- a/tests/api/test_mldsa.h +++ b/tests/api/test_mldsa.h @@ -91,6 +91,7 @@ int test_mldsa_cb_free(void); int test_wc_MlDsaKey_seed_service_indicator(void); int test_wc_MlDsaKey_SetPrecompA(void); int test_mldsa_make_key_rej_ntt_fail(void); +int test_mldsa_make_key_id_dev(void); #define TEST_MLDSA_DECLS \ TEST_DECL_GROUP("mldsa", test_mldsa), \ TEST_DECL_GROUP("mldsa", test_mldsa_sign_pubonly_fails), \ @@ -133,6 +134,7 @@ int test_mldsa_make_key_rej_ntt_fail(void); TEST_DECL_GROUP("mldsa", test_wc_MldsaDerDecisionCoverage), \ TEST_DECL_GROUP("mldsa", test_mldsa_cb_free), \ TEST_DECL_GROUP("mldsa", test_wc_MlDsaKey_SetPrecompA), \ - TEST_DECL_GROUP("mldsa", test_mldsa_make_key_rej_ntt_fail) + TEST_DECL_GROUP("mldsa", test_mldsa_make_key_rej_ntt_fail), \ + TEST_DECL_GROUP("mldsa", test_mldsa_make_key_id_dev) #endif /* WOLFCRYPT_TEST_MLDSA_H */ diff --git a/tests/api/test_mlkem.c b/tests/api/test_mlkem.c index aa9923c3bea..d2fc6df953d 100644 --- a/tests/api/test_mlkem.c +++ b/tests/api/test_mlkem.c @@ -5532,3 +5532,70 @@ int test_wc_mlkem_decode_alloc_fail(void) #endif return EXPECT_RESULT(); } + +#if defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_NO_ML_KEM) && \ + !defined(WOLFSSL_MLKEM_NO_MAKE_KEY) && !defined(WOLFSSL_NO_ML_KEM_768) && \ + defined(WC_CRYPTOCB_KEYGEN_ID_CHECK) && \ + !defined(WC_NO_RNG) && !defined(HAVE_FIPS) +static int mlkem_keygen_decline_cb(int devIdArg, wc_CryptoInfo* info, void* ctx) +{ + (void)devIdArg; + (void)info; + (void)ctx; + return WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); +} +#endif + +/* + * Testing wc_MlKemKey_MakeKey() on an id or label key whose device declines + * keygen. + */ +int test_wc_mlkem_make_key_id_dev(void) +{ + EXPECT_DECLS; +#if defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_NO_ML_KEM) && \ + !defined(WOLFSSL_MLKEM_NO_MAKE_KEY) && !defined(WOLFSSL_NO_ML_KEM_768) && \ + defined(WC_CRYPTOCB_KEYGEN_ID_CHECK) && \ + !defined(WC_NO_RNG) && !defined(HAVE_FIPS) + int devId = 2406; + MlKemKey* key; + WC_RNG rng; + static const byte id[] = { 0x01, 0x02, 0x03, 0x04 }; + + key = (MlKemKey*)XMALLOC(sizeof(MlKemKey), NULL, DYNAMIC_TYPE_TMP_BUFFER); + ExpectNotNull(key); + XMEMSET(&rng, 0, sizeof(rng)); + ExpectIntEQ(wc_InitRng(&rng), 0); + ExpectIntEQ(wc_CryptoCb_RegisterDevice(devId, mlkem_keygen_decline_cb, + NULL), 0); + + ExpectIntEQ(wc_MlKemKey_Init_Id(key, WC_ML_KEM_768, id, (int)sizeof(id), + NULL, devId), 0); + ExpectIntEQ(wc_MlKemKey_MakeKey(key, &rng), + WC_NO_ERR_TRACE(NO_VALID_DEVID)); + wc_MlKemKey_Free(key); + + ExpectIntEQ(wc_MlKemKey_Init_Label(key, WC_ML_KEM_768, "dev-key", NULL, + devId), 0); + ExpectIntEQ(wc_MlKemKey_MakeKey(key, &rng), + WC_NO_ERR_TRACE(NO_VALID_DEVID)); + wc_MlKemKey_Free(key); + +#if defined(WC_MLKEM_HAVE_NATIVE) && !defined(WOLF_CRYPTO_CB_ONLY_MLKEM) + /* Without a registered device the key stays in software. */ + ExpectIntEQ(wc_MlKemKey_Init_Id(key, WC_ML_KEM_768, id, (int)sizeof(id), + NULL, devId + 100), 0); + ExpectIntEQ(wc_MlKemKey_MakeKey(key, &rng), 0); + wc_MlKemKey_Free(key); + + ExpectIntEQ(wc_MlKemKey_Init(key, WC_ML_KEM_768, NULL, devId), 0); + ExpectIntEQ(wc_MlKemKey_MakeKey(key, &rng), 0); + wc_MlKemKey_Free(key); +#endif + + wc_CryptoCb_UnRegisterDevice(devId); + DoExpectIntEQ(wc_FreeRng(&rng), 0); + XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return EXPECT_RESULT(); +} diff --git a/tests/api/test_mlkem.h b/tests/api/test_mlkem.h index cc23a838858..41e19de21f7 100644 --- a/tests/api/test_mlkem.h +++ b/tests/api/test_mlkem.h @@ -44,6 +44,7 @@ int test_wc_mlkem_encapsulate_id_key(void); int test_wc_mlkem_decode_pubkey_refused_save(void); int test_wc_mlkem_decode_reused_key(void); int test_wc_mlkem_decode_alloc_fail(void); +int test_wc_mlkem_make_key_id_dev(void); #define TEST_MLKEM_DECLS \ TEST_DECL_GROUP("mlkem", test_wc_mlkem_make_key_kats), \ @@ -65,6 +66,7 @@ int test_wc_mlkem_decode_alloc_fail(void); TEST_DECL_GROUP("mlkem", test_wc_mlkem_encapsulate_id_key), \ TEST_DECL_GROUP("mlkem", test_wc_mlkem_decode_pubkey_refused_save), \ TEST_DECL_GROUP("mlkem", test_wc_mlkem_decode_reused_key), \ - TEST_DECL_GROUP("mlkem", test_wc_mlkem_decode_alloc_fail) + TEST_DECL_GROUP("mlkem", test_wc_mlkem_decode_alloc_fail), \ + TEST_DECL_GROUP("mlkem", test_wc_mlkem_make_key_id_dev) #endif /* WOLFCRYPT_TEST_MLKEM_H */ diff --git a/tests/api/test_rsa.c b/tests/api/test_rsa.c index c02bb01ee9a..9ac9b5dae94 100644 --- a/tests/api/test_rsa.c +++ b/tests/api/test_rsa.c @@ -2558,3 +2558,75 @@ int test_wc_CryptoCb_RsaPssVerifyRecover(void) return EXPECT_RESULT(); } /* END test_wc_CryptoCb_RsaPssVerifyRecover */ +#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) && \ + defined(WC_CRYPTOCB_KEYGEN_ID_CHECK) && !defined(WC_NO_RNG) && \ + !defined(WOLF_CRYPTO_CB_ONLY_RSA) && !defined(WOLFSSL_MICROCHIP_TA100) && \ + (!defined(WOLFSSL_SE050) || defined(WOLFSSL_SE050_NO_RSA) || \ + defined(WOLFSSL_SE050_ONLY_KEY_ID)) && \ + !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) +static int rsa_keygen_decline_cb(int devIdArg, wc_CryptoInfo* info, void* ctx) +{ + (void)devIdArg; + (void)info; + (void)ctx; + return WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); +} +#endif + +/* + * Testing wc_MakeRsaKey() on an id or label key whose device declines keygen. + */ +int test_wc_MakeRsaKey_id_dev(void) +{ + EXPECT_DECLS; +#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) && \ + defined(WC_CRYPTOCB_KEYGEN_ID_CHECK) && !defined(WC_NO_RNG) && \ + !defined(WOLF_CRYPTO_CB_ONLY_RSA) && !defined(WOLFSSL_MICROCHIP_TA100) && \ + (!defined(WOLFSSL_SE050) || defined(WOLFSSL_SE050_NO_RSA) || \ + defined(WOLFSSL_SE050_ONLY_KEY_ID)) && \ + !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) + int devId = 2402; + int ret; + RsaKey key; + WC_RNG rng; + byte id[] = { 0x01, 0x02, 0x03, 0x04 }; + + XMEMSET(&key, 0, sizeof(key)); + XMEMSET(&rng, 0, sizeof(rng)); + ExpectIntEQ(wc_InitRng(&rng), 0); + ExpectIntEQ(wc_CryptoCb_RegisterDevice(devId, rsa_keygen_decline_cb, NULL), + 0); + + ExpectIntEQ(wc_InitRsaKey_Id(&key, id, (int)sizeof(id), NULL, devId), 0); + ExpectIntEQ(wc_MakeRsaKey(&key, TEST_RSA_BITS, WC_RSA_EXPONENT, &rng), + WC_NO_ERR_TRACE(NO_VALID_DEVID)); + DoExpectIntEQ(wc_FreeRsaKey(&key), 0); + + ExpectIntEQ(wc_InitRsaKey_Label(&key, "dev-key", NULL, devId), 0); + ExpectIntEQ(wc_MakeRsaKey(&key, TEST_RSA_BITS, WC_RSA_EXPONENT, &rng), + WC_NO_ERR_TRACE(NO_VALID_DEVID)); + DoExpectIntEQ(wc_FreeRsaKey(&key), 0); + + /* Without a registered device the key stays in software. */ + ExpectIntEQ(wc_InitRsaKey_Id(&key, id, (int)sizeof(id), NULL, devId + 100), + 0); + ret = wc_MakeRsaKey(&key, TEST_RSA_BITS, WC_RSA_EXPONENT, &rng); +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_NONE); +#endif + ExpectIntEQ(ret, 0); + DoExpectIntEQ(wc_FreeRsaKey(&key), 0); + + ExpectIntEQ(wc_InitRsaKey_ex(&key, NULL, devId), 0); + ret = wc_MakeRsaKey(&key, TEST_RSA_BITS, WC_RSA_EXPONENT, &rng); +#if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_NONE); +#endif + ExpectIntEQ(ret, 0); + DoExpectIntEQ(wc_FreeRsaKey(&key), 0); + + wc_CryptoCb_UnRegisterDevice(devId); + DoExpectIntEQ(wc_FreeRng(&rng), 0); +#endif + return EXPECT_RESULT(); +} diff --git a/tests/api/test_rsa.h b/tests/api/test_rsa.h index 54fc0bcfdd3..d3fc75f3385 100644 --- a/tests/api/test_rsa.h +++ b/tests/api/test_rsa.h @@ -51,6 +51,7 @@ int test_wc_RsaDecisionCoverage(void); int test_wc_RsaFeatureCoverage(void); int test_wc_CryptoCb_RsaPssVerify(void); int test_wc_CryptoCb_RsaPssVerifyRecover(void); +int test_wc_MakeRsaKey_id_dev(void); #define TEST_RSA_DECLS \ TEST_DECL_GROUP("rsa", test_wc_InitRsaKey), \ @@ -79,6 +80,7 @@ int test_wc_CryptoCb_RsaPssVerifyRecover(void); TEST_DECL_GROUP("rsa", test_wc_RsaDecisionCoverage), \ TEST_DECL_GROUP("rsa", test_wc_RsaFeatureCoverage), \ TEST_DECL_GROUP("rsa", test_wc_CryptoCb_RsaPssVerify), \ - TEST_DECL_GROUP("rsa", test_wc_CryptoCb_RsaPssVerifyRecover) + TEST_DECL_GROUP("rsa", test_wc_CryptoCb_RsaPssVerifyRecover), \ + TEST_DECL_GROUP("rsa", test_wc_MakeRsaKey_id_dev) #endif /* WOLFCRYPT_TEST_RSA_H */ diff --git a/tests/api/test_slhdsa.c b/tests/api/test_slhdsa.c index e642951e219..336c02ab9bb 100644 --- a/tests/api/test_slhdsa.c +++ b/tests/api/test_slhdsa.c @@ -3650,6 +3650,73 @@ int test_wc_SlhdsaFeatureCoverage(void) return EXPECT_RESULT(); } +#if defined(TEST_SLHDSA_DEFAULT_PARAM) && \ + !defined(WOLFSSL_SLHDSA_VERIFY_ONLY) && \ + defined(WC_CRYPTOCB_KEYGEN_ID_CHECK) && \ + !defined(WC_NO_RNG) && !defined(HAVE_FIPS) +static int slhdsa_keygen_decline_cb(int devIdArg, wc_CryptoInfo* info, + void* ctx) +{ + (void)devIdArg; + (void)info; + (void)ctx; + return WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); +} +#endif + +/* + * Testing wc_SlhDsaKey_MakeKey() on an id or label key whose device declines + * keygen. + */ +int test_wc_slhdsa_make_key_id_dev(void) +{ + EXPECT_DECLS; +#if defined(TEST_SLHDSA_DEFAULT_PARAM) && \ + !defined(WOLFSSL_SLHDSA_VERIFY_ONLY) && \ + defined(WC_CRYPTOCB_KEYGEN_ID_CHECK) && \ + !defined(WC_NO_RNG) && !defined(HAVE_FIPS) + int devId = 2410; + SlhDsaKey key; + WC_RNG rng; + static const byte id[] = { 0x01, 0x02, 0x03, 0x04 }; + enum SlhDsaParam param = TEST_SLHDSA_DEFAULT_PARAM; + + XMEMSET(&key, 0, sizeof(key)); + XMEMSET(&rng, 0, sizeof(rng)); + ExpectIntEQ(wc_InitRng(&rng), 0); + ExpectIntEQ(wc_CryptoCb_RegisterDevice(devId, slhdsa_keygen_decline_cb, + NULL), 0); + + ExpectIntEQ(wc_SlhDsaKey_Init_id(&key, param, id, (int)sizeof(id), NULL, + devId), 0); + ExpectIntEQ(wc_SlhDsaKey_MakeKey(&key, &rng), + WC_NO_ERR_TRACE(NO_VALID_DEVID)); + wc_SlhDsaKey_Free(&key); + + ExpectIntEQ(wc_SlhDsaKey_Init_label(&key, param, "dev-key", NULL, devId), + 0); + ExpectIntEQ(wc_SlhDsaKey_MakeKey(&key, &rng), + WC_NO_ERR_TRACE(NO_VALID_DEVID)); + wc_SlhDsaKey_Free(&key); + +#ifndef WOLF_CRYPTO_CB_ONLY_SLHDSA + /* Without a registered device the key stays in software. */ + ExpectIntEQ(wc_SlhDsaKey_Init_id(&key, param, id, (int)sizeof(id), NULL, + devId + 100), 0); + ExpectIntEQ(wc_SlhDsaKey_MakeKey(&key, &rng), 0); + wc_SlhDsaKey_Free(&key); + + ExpectIntEQ(wc_SlhDsaKey_Init(&key, param, NULL, devId), 0); + ExpectIntEQ(wc_SlhDsaKey_MakeKey(&key, &rng), 0); + wc_SlhDsaKey_Free(&key); +#endif + + wc_CryptoCb_UnRegisterDevice(devId); + DoExpectIntEQ(wc_FreeRng(&rng), 0); +#endif + return EXPECT_RESULT(); +} + #ifdef TEST_SLHDSA_DEFAULT_PARAM #undef TEST_SLHDSA_DEFAULT_PARAM #undef TEST_SLHDSA_DEFAULT_SIG_LEN diff --git a/tests/api/test_slhdsa.h b/tests/api/test_slhdsa.h index f24b8d63cdf..30b37054203 100644 --- a/tests/api/test_slhdsa.h +++ b/tests/api/test_slhdsa.h @@ -54,6 +54,7 @@ int test_slhdsa_dev_private_key(void); int test_slhdsa_tls13_certverify_bad_signature(void); int test_slhdsa_cb_free(void); int test_wc_slhdsa_sign_refused_save_clears_sig(void); +int test_wc_slhdsa_make_key_id_dev(void); #define TEST_SLHDSA_DECLS \ TEST_DECL_GROUP("slhdsa", test_wc_slhdsa), \ @@ -85,6 +86,7 @@ int test_wc_slhdsa_sign_refused_save_clears_sig(void); TEST_DECL_GROUP("slhdsa", test_slhdsa_dev_private_key), \ TEST_DECL_GROUP("slhdsa", test_slhdsa_tls13_certverify_bad_signature), \ TEST_DECL_GROUP("slhdsa", test_slhdsa_cb_free), \ - TEST_DECL_GROUP("slhdsa", test_wc_slhdsa_sign_refused_save_clears_sig) + TEST_DECL_GROUP("slhdsa", test_wc_slhdsa_sign_refused_save_clears_sig), \ + TEST_DECL_GROUP("slhdsa", test_wc_slhdsa_make_key_id_dev) #endif /* WOLFCRYPT_TEST_SLHDSA_H */ diff --git a/wolfcrypt/src/cryptocb.c b/wolfcrypt/src/cryptocb.c index 33bb6ed4b69..5b3864969e3 100644 --- a/wolfcrypt/src/cryptocb.c +++ b/wolfcrypt/src/cryptocb.c @@ -37,6 +37,8 @@ Crypto Callback Build Options: * WOLF_CRYPTO_CB_AES_SETKEY: Enable callback for AES key setup default: off * WOLF_CRYPTO_CB_RSA_PAD: Enable callback for RSA padding default: off * operations (custom padding handling). + * WOLF_CRYPTO_CB_KEYGEN_SW_FALLBACK: default: off + * Software keygen for id/label keys a device declines. * DEBUG_CRYPTOCB: Enable debug InfoString functions default: off * * Device ID options: @@ -518,6 +520,16 @@ static CryptoCb* wc_CryptoCb_FindDevice(int devId, int algoType) return wc_CryptoCb_GetDevice(localDevId); } +#ifdef WC_CRYPTOCB_KEYGEN_ID_CHECK +/* Returns 1 if public key operations on devId reach a registered device. */ +int wc_CryptoCb_HasPkDevice(int devId) +{ + CryptoCb* dev = wc_CryptoCb_FindDevice(devId, WC_ALGO_TYPE_PK); + + return (dev != NULL) && (dev->cb != NULL) && (dev->devId != INVALID_DEVID); +} +#endif + static CryptoCb* wc_CryptoCb_FindDeviceByIndex(int startIdx) { diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 2112b90cc83..a33ee3eb105 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -5957,6 +5957,10 @@ static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id, int flags) { int err = 0; +#ifdef WC_CRYPTOCB_KEYGEN_ID_CHECK + int idKey; + int idDevId; +#endif #if defined(WOLFSSL_HAVE_SP_ECC) && defined(WC_ECC_NONBLOCK) && \ defined(WC_ECC_NONBLOCK_ONLY) ecc_nb_ctx_t nb_ctx; @@ -5996,6 +6000,10 @@ static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, #endif key->flags = (byte)flags; +#ifdef WC_CRYPTOCB_KEYGEN_ID_CHECK + idKey = WC_CRYPTOCB_HAS_ID(key); + idDevId = key->devId; +#endif #if defined(WOLF_CRYPTO_CB) && defined(HAVE_ECC_DHE) #ifndef WOLF_CRYPTO_CB_FIND if (key->devId != INVALID_DEVID) @@ -6007,6 +6015,10 @@ static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, /* fall-through when unavailable */ } #endif +#ifdef WC_CRYPTOCB_KEYGEN_ID_CHECK + if (idKey && wc_CryptoCb_HasPkDevice(idDevId)) + return NO_VALID_DEVID; +#endif #ifdef WOLF_CRYPTO_CB_ONLY_ECC return NO_VALID_DEVID; diff --git a/wolfcrypt/src/ed25519.c b/wolfcrypt/src/ed25519.c index 279207aaf8f..8fcdda78794 100644 --- a/wolfcrypt/src/ed25519.c +++ b/wolfcrypt/src/ed25519.c @@ -436,6 +436,10 @@ int wc_ed25519_make_public(ed25519_key* key, unsigned char* pubKey, int wc_ed25519_make_key(WC_RNG* rng, int keySz, ed25519_key* key) { int ret; +#ifdef WC_CRYPTOCB_KEYGEN_ID_CHECK + int idKey = 0; + int idDevId = INVALID_DEVID; +#endif if (rng == NULL || key == NULL) return BAD_FUNC_ARG; @@ -447,6 +451,10 @@ int wc_ed25519_make_key(WC_RNG* rng, int keySz, ed25519_key* key) key->privKeySet = 0; key->pubKeySet = 0; +#ifdef WC_CRYPTOCB_KEYGEN_ID_CHECK + idKey = WC_CRYPTOCB_HAS_ID(key); + idDevId = key->devId; +#endif #ifdef WOLF_CRYPTO_CB #ifndef WOLF_CRYPTO_CB_FIND if (key->devId != INVALID_DEVID) @@ -457,6 +465,10 @@ int wc_ed25519_make_key(WC_RNG* rng, int keySz, ed25519_key* key) return ret; /* fall-through when unavailable */ } + #ifdef WC_CRYPTOCB_KEYGEN_ID_CHECK + if (idKey && wc_CryptoCb_HasPkDevice(idDevId)) + return NO_VALID_DEVID; + #endif #endif #ifdef WOLF_CRYPTO_CB_ONLY_ED25519 diff --git a/wolfcrypt/src/ed448.c b/wolfcrypt/src/ed448.c index 4f77505cde2..0fc8bf5dc88 100644 --- a/wolfcrypt/src/ed448.c +++ b/wolfcrypt/src/ed448.c @@ -464,6 +464,10 @@ int wc_ed448_make_public(ed448_key* key, unsigned char* pubKey, word32 pubKeySz) int wc_ed448_make_key(WC_RNG* rng, int keySz, ed448_key* key) { int ret = 0; +#ifdef WC_CRYPTOCB_KEYGEN_ID_CHECK + int idKey = 0; + int idDevId = INVALID_DEVID; +#endif if ((rng == NULL) || (key == NULL)) { ret = BAD_FUNC_ARG; @@ -479,6 +483,12 @@ int wc_ed448_make_key(WC_RNG* rng, int keySz, ed448_key* key) key->privKeySet = 0; } +#ifdef WC_CRYPTOCB_KEYGEN_ID_CHECK + if (ret == 0) { + idKey = WC_CRYPTOCB_HAS_ID(key); + idDevId = key->devId; + } +#endif #ifdef WOLF_CRYPTO_CB #ifndef WOLF_CRYPTO_CB_FIND if ((ret == 0) && (key->devId != INVALID_DEVID)) @@ -492,6 +502,10 @@ int wc_ed448_make_key(WC_RNG* rng, int keySz, ed448_key* key) /* fall-through when unavailable */ ret = 0; } + #ifdef WC_CRYPTOCB_KEYGEN_ID_CHECK + if ((ret == 0) && idKey && wc_CryptoCb_HasPkDevice(idDevId)) + ret = NO_VALID_DEVID; + #endif #endif if (ret == 0) { diff --git a/wolfcrypt/src/falcon.c b/wolfcrypt/src/falcon.c index 4a763d33c7f..08c8da0c76c 100644 --- a/wolfcrypt/src/falcon.c +++ b/wolfcrypt/src/falcon.c @@ -10697,6 +10697,10 @@ int falcon_native_verify_msg(const byte* sig, word32 sigLen, const byte* msg, int wc_falcon_make_key(falcon_key* key, WC_RNG* rng) { int ret = 0; +#ifdef WC_CRYPTOCB_KEYGEN_ID_CHECK + int idKey = 0; + int idDevId = INVALID_DEVID; +#endif if ((key == NULL) || (rng == NULL)) { return BAD_FUNC_ARG; @@ -10712,6 +10716,10 @@ int wc_falcon_make_key(falcon_key* key, WC_RNG* rng) falcon_cache_clear(key); #endif +#ifdef WC_CRYPTOCB_KEYGEN_ID_CHECK + idKey = WC_CRYPTOCB_HAS_ID(key); + idDevId = key->devId; +#endif #ifdef WOLF_CRYPTO_CB #ifndef WOLF_CRYPTO_CB_FIND if (key->devId != INVALID_DEVID) @@ -10724,6 +10732,10 @@ int wc_falcon_make_key(falcon_key* key, WC_RNG* rng) /* fall-through when unavailable */ ret = 0; } + #ifdef WC_CRYPTOCB_KEYGEN_ID_CHECK + if (idKey && wc_CryptoCb_HasPkDevice(idDevId)) + return NO_VALID_DEVID; + #endif #endif /* WOLF_CRYPTO_CB */ #ifdef WOLF_CRYPTO_CB_ONLY_FALCON diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index dd09ad8dbdb..8f5f10d4304 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -5601,6 +5601,10 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) /* RSA_MAX_SIZE is the size of n in bits. */ byte buf[RSA_MAX_SIZE/16]; #endif +#ifdef WC_CRYPTOCB_KEYGEN_ID_CHECK + int idKey = 0; + int idDevId = INVALID_DEVID; +#endif #endif /* !WOLFSSL_SE050 */ int err; @@ -5677,6 +5681,10 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) XMEMSET(tmp3, 0, sizeof(*tmp3)); #endif +#if defined(WC_CRYPTOCB_KEYGEN_ID_CHECK) && !defined(WOLF_CRYPTO_CB_ONLY_RSA) + idKey = WC_CRYPTOCB_HAS_ID(key); + idDevId = key->devId; +#endif #ifdef WOLF_CRYPTO_CB #ifndef WOLF_CRYPTO_CB_FIND if (key->devId != INVALID_DEVID) @@ -5700,6 +5708,13 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) err = NO_VALID_DEVID; } #endif + #if defined(WC_CRYPTOCB_KEYGEN_ID_CHECK) && \ + !defined(WOLF_CRYPTO_CB_ONLY_RSA) + if (idKey && wc_CryptoCb_HasPkDevice(idDevId)) { + err = NO_VALID_DEVID; + goto out; + } + #endif #endif #ifndef WOLF_CRYPTO_CB_ONLY_RSA diff --git a/wolfcrypt/src/wc_lms.c b/wolfcrypt/src/wc_lms.c index b3977a94ba7..d63aa89630b 100644 --- a/wolfcrypt/src/wc_lms.c +++ b/wolfcrypt/src/wc_lms.c @@ -1207,6 +1207,10 @@ int wc_LmsKey_SetContext(LmsKey* key, void* context) int wc_LmsKey_MakeKey(LmsKey* key, WC_RNG* rng) { int ret = 0; +#ifdef WC_CRYPTOCB_KEYGEN_ID_CHECK + int idKey = 0; + int idDevId = INVALID_DEVID; +#endif #ifndef WOLF_CRYPTO_CB_ONLY_LMS word32 priv_data_len = 0; #endif @@ -1221,6 +1225,12 @@ int wc_LmsKey_MakeKey(LmsKey* key, WC_RNG* rng) ret = BAD_STATE_E; } +#ifdef WC_CRYPTOCB_KEYGEN_ID_CHECK + if (ret == 0) { + idKey = WC_CRYPTOCB_HAS_ID(key); + idDevId = key->devId; + } +#endif #ifdef WOLF_CRYPTO_CB /* HSM-backed keys skip the software write/context callbacks because the * device owns the private state. On CRYPTOCB_UNAVAILABLE fall-through the @@ -1254,6 +1264,11 @@ int wc_LmsKey_MakeKey(LmsKey* key, WC_RNG* rng) } ret = 0; /* fall through to software path */ } + #ifdef WC_CRYPTOCB_KEYGEN_ID_CHECK + if ((ret == 0) && idKey && wc_CryptoCb_HasPkDevice(idDevId)) { + ret = NO_VALID_DEVID; + } + #endif #endif #ifdef WOLF_CRYPTO_CB_ONLY_LMS diff --git a/wolfcrypt/src/wc_mldsa.c b/wolfcrypt/src/wc_mldsa.c index 9e3c640113e..bccae07132b 100644 --- a/wolfcrypt/src/wc_mldsa.c +++ b/wolfcrypt/src/wc_mldsa.c @@ -12887,12 +12887,22 @@ static int mldsa_verify_ctx_hash(wc_MlDsaKey* key, const byte* ctx, int wc_MlDsaKey_MakeKey(wc_MlDsaKey* key, WC_RNG* rng) { int ret = 0; +#ifdef WC_CRYPTOCB_KEYGEN_ID_CHECK + int idKey = 0; + int idDevId = INVALID_DEVID; +#endif /* Validate parameters. */ if ((key == NULL) || (rng == NULL)) { ret = BAD_FUNC_ARG; } +#ifdef WC_CRYPTOCB_KEYGEN_ID_CHECK + if (ret == 0) { + idKey = WC_CRYPTOCB_HAS_ID(key); + idDevId = key->devId; + } +#endif #ifdef WOLF_CRYPTO_CB if (ret == 0) { #ifndef WOLF_CRYPTO_CB_FIND @@ -12907,6 +12917,11 @@ int wc_MlDsaKey_MakeKey(wc_MlDsaKey* key, WC_RNG* rng) ret = 0; } } + #ifdef WC_CRYPTOCB_KEYGEN_ID_CHECK + if ((ret == 0) && idKey && wc_CryptoCb_HasPkDevice(idDevId)) { + ret = NO_VALID_DEVID; + } + #endif #endif #ifdef WOLF_CRYPTO_CB_ONLY_MLDSA diff --git a/wolfcrypt/src/wc_mlkem.c b/wolfcrypt/src/wc_mlkem.c index c35f20c0879..afc097747c0 100644 --- a/wolfcrypt/src/wc_mlkem.c +++ b/wolfcrypt/src/wc_mlkem.c @@ -717,12 +717,22 @@ int wc_MlKemKey_MakeKey(MlKemKey* key, WC_RNG* rng) #ifndef WC_NO_RNG int ret = 0; unsigned char rand[WC_ML_KEM_MAKEKEY_RAND_SZ]; +#ifdef WC_CRYPTOCB_KEYGEN_ID_CHECK + int idKey = 0; + int idDevId = INVALID_DEVID; +#endif /* Validate parameters. */ if ((key == NULL) || (rng == NULL)) { ret = BAD_FUNC_ARG; } +#ifdef WC_CRYPTOCB_KEYGEN_ID_CHECK + if (ret == 0) { + idKey = WC_CRYPTOCB_HAS_ID(key); + idDevId = key->devId; + } +#endif #ifdef WOLF_CRYPTO_CB #ifndef WOLF_CRYPTO_CB_FIND if ((ret == 0) && (key->devId != INVALID_DEVID)) { @@ -738,6 +748,11 @@ int wc_MlKemKey_MakeKey(MlKemKey* key, WC_RNG* rng) /* fall-through when unavailable */ ret = 0; } +#ifdef WC_CRYPTOCB_KEYGEN_ID_CHECK + if ((ret == 0) && idKey && wc_CryptoCb_HasPkDevice(idDevId)) { + ret = NO_VALID_DEVID; + } +#endif #endif if (ret == 0) { diff --git a/wolfcrypt/src/wc_slhdsa.c b/wolfcrypt/src/wc_slhdsa.c index f60d92e1cce..03f62733d35 100644 --- a/wolfcrypt/src/wc_slhdsa.c +++ b/wolfcrypt/src/wc_slhdsa.c @@ -8994,12 +8994,22 @@ static void slhdsakey_set_ha_from_md(SlhDsaKey* key, const byte* md, int wc_SlhDsaKey_MakeKey(SlhDsaKey* key, WC_RNG* rng) { int ret = 0; +#ifdef WC_CRYPTOCB_KEYGEN_ID_CHECK + int idKey = 0; + int idDevId = INVALID_DEVID; +#endif /* Validate parameters. */ if ((key == NULL) || (key->params == NULL) || (rng == NULL)) { ret = BAD_FUNC_ARG; } +#ifdef WC_CRYPTOCB_KEYGEN_ID_CHECK + if (ret == 0) { + idKey = WC_CRYPTOCB_HAS_ID(key); + idDevId = key->devId; + } +#endif #ifdef WOLF_CRYPTO_CB if (ret == 0) { #ifndef WOLF_CRYPTO_CB_FIND @@ -9015,6 +9025,11 @@ int wc_SlhDsaKey_MakeKey(SlhDsaKey* key, WC_RNG* rng) ret = 0; } } + #ifdef WC_CRYPTOCB_KEYGEN_ID_CHECK + if ((ret == 0) && idKey && wc_CryptoCb_HasPkDevice(idDevId)) { + ret = NO_VALID_DEVID; + } + #endif #endif #ifdef WOLF_CRYPTO_CB_ONLY_SLHDSA diff --git a/wolfcrypt/src/wc_xmss.c b/wolfcrypt/src/wc_xmss.c index 37d0876996a..c69150ebb10 100644 --- a/wolfcrypt/src/wc_xmss.c +++ b/wolfcrypt/src/wc_xmss.c @@ -1235,6 +1235,10 @@ int wc_XmssKey_SetContext(XmssKey* key, void* context) int wc_XmssKey_MakeKey(XmssKey* key, WC_RNG* rng) { int ret = 0; +#ifdef WC_CRYPTOCB_KEYGEN_ID_CHECK + int idKey = 0; + int idDevId = INVALID_DEVID; +#endif #ifndef WOLF_CRYPTO_CB_ONLY_XMSS enum wc_XmssRc cb_rc = WC_XMSS_RC_NONE; #ifdef WOLFSSL_SMALL_STACK @@ -1253,6 +1257,12 @@ int wc_XmssKey_MakeKey(XmssKey* key, WC_RNG* rng) WOLFSSL_MSG("error: XmssKey not ready for generation"); ret = BAD_STATE_E; } +#ifdef WC_CRYPTOCB_KEYGEN_ID_CHECK + if (ret == 0) { + idKey = WC_CRYPTOCB_HAS_ID(key); + idDevId = key->devId; + } +#endif #ifdef WOLF_CRYPTO_CB /* HSM-backed keys skip the software write/context callbacks because the * device owns the private state. On CRYPTOCB_UNAVAILABLE fall-through the @@ -1276,6 +1286,11 @@ int wc_XmssKey_MakeKey(XmssKey* key, WC_RNG* rng) } ret = 0; /* fall through to software path */ } + #ifdef WC_CRYPTOCB_KEYGEN_ID_CHECK + if ((ret == 0) && idKey && wc_CryptoCb_HasPkDevice(idDevId)) { + ret = NO_VALID_DEVID; + } + #endif #endif #ifdef WOLF_CRYPTO_CB_ONLY_XMSS diff --git a/wolfssl/wolfcrypt/cryptocb.h b/wolfssl/wolfcrypt/cryptocb.h index 571adf397c3..34cf2212e65 100644 --- a/wolfssl/wolfcrypt/cryptocb.h +++ b/wolfssl/wolfcrypt/cryptocb.h @@ -1204,6 +1204,12 @@ WOLFSSL_API int wc_CryptoCb_UnRegisterDeviceEx(int devId); WOLFSSL_API int wc_CryptoCb_DefaultDevID(void); WOLFSSL_API int wc_CryptoCb_IsDeviceRegistered(int devId); +#if defined(WOLF_PRIVATE_KEY_ID) && !defined(WOLF_CRYPTO_CB_KEYGEN_SW_FALLBACK) +#define WC_CRYPTOCB_KEYGEN_ID_CHECK +WOLFSSL_LOCAL int wc_CryptoCb_HasPkDevice(int devId); +#define WC_CRYPTOCB_HAS_ID(key) (((key)->idLen > 0) || ((key)->labelLen > 0)) +#endif + #ifdef WOLF_CRYPTO_CB_FIND typedef int (*CryptoDevCallbackFind)(int devId, int algoType); WOLFSSL_API void wc_CryptoCb_SetDeviceFindCb(CryptoDevCallbackFind cb);