mirror of https://github.com/wolfSSL/wolfssl.git
Falcon: crypto callback (WOLF_CRYPTO_CB) interface + CB_ONLY
Wire Falcon into the crypto callback framework like the other algorithms:
- wc_falcon_make_key now dispatches to wc_CryptoCb_MakePqcSignatureKey
(WC_PQC_SIG_TYPE_FALCON); wc_falcon_sign_msg / wc_falcon_verify_msg already
dispatched to wc_CryptoCb_PqcSign / PqcVerify. All three fall through to the
software implementation when the callback is unavailable.
- Add WOLF_CRYPTO_CB_ONLY_FALCON (mirrors WOLF_CRYPTO_CB_ONLY_RSA/ECC): the
callback becomes authoritative (no software fallback; returns NO_VALID_DEVID
when no device is registered) and the native core (wc_falcon*.c) is compiled
out entirely. WC_FALCON_HAVE_NATIVE_SIGN and the falcon_native_* prototypes
are gated off in that build.
Tests (test.c):
- myCryptoDevCb gains a Falcon branch for PQC keygen/sign/verify.
- falcon_test / falcon_verify_kat now use the global test devId, so
cryptocb_test drives every Falcon operation through the callback and asserts
(via the exampleVar hit counter) that the cb path was actually taken.
- Under WOLF_CRYPTO_CB_ONLY_FALCON, falcon_test instead confirms the API
returns NO_VALID_DEVID with no device registered, and the KAT data/verifier
(software-only) are compiled out.
Verified: default (no cryptocb), --enable-cryptocb, and
-DWOLF_CRYPTO_CB_ONLY_FALCON all build and pass testwolfcrypt (falcon_test +
crypto callback test); the CB_ONLY library contains no falcon_native_* symbols.
pull/10827/head
parent
509b29bc9c
commit
debc59f70b
|
|
@ -67,7 +67,7 @@ static void falcon_store_pub_behind_priv(falcon_key* key)
|
|||
*/
|
||||
int wc_falcon_make_key(falcon_key* key, WC_RNG* rng)
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
if ((key == NULL) || (rng == NULL)) {
|
||||
return BAD_FUNC_ARG;
|
||||
|
|
@ -76,10 +76,29 @@ int wc_falcon_make_key(falcon_key* key, WC_RNG* rng)
|
|||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
#ifdef WOLF_CRYPTO_CB
|
||||
#ifndef WOLF_CRYPTO_CB_FIND
|
||||
if (key->devId != INVALID_DEVID)
|
||||
#endif
|
||||
{
|
||||
ret = wc_CryptoCb_MakePqcSignatureKey(rng, WC_PQC_SIG_TYPE_FALCON,
|
||||
key->level, key);
|
||||
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
|
||||
return ret;
|
||||
/* fall-through when unavailable */
|
||||
ret = 0;
|
||||
}
|
||||
#endif /* WOLF_CRYPTO_CB */
|
||||
|
||||
#ifdef WOLF_CRYPTO_CB_ONLY_FALCON
|
||||
/* No software fallback: only a crypto callback can service the request. */
|
||||
ret = NO_VALID_DEVID;
|
||||
#else
|
||||
ret = falcon_native_make_key(key, rng);
|
||||
if (ret == 0) {
|
||||
falcon_store_pub_behind_priv(key);
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
#endif /* !WOLFSSL_FALCON_VERIFY_ONLY */
|
||||
|
|
@ -119,9 +138,14 @@ int wc_falcon_sign_msg(const byte* in, word32 inLen,
|
|||
/* fall-through when unavailable */
|
||||
ret = 0;
|
||||
}
|
||||
#endif
|
||||
#endif /* WOLF_CRYPTO_CB */
|
||||
|
||||
#ifndef WOLFSSL_FALCON_VERIFY_ONLY
|
||||
#ifdef WOLF_CRYPTO_CB_ONLY_FALCON
|
||||
/* No software fallback: only a crypto callback can service the request. */
|
||||
ret = NO_VALID_DEVID;
|
||||
#elif defined(WOLFSSL_FALCON_VERIFY_ONLY)
|
||||
ret = NOT_COMPILED_IN;
|
||||
#else
|
||||
if ((ret == 0) && (!key->prvKeySet)) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
|
|
@ -129,8 +153,6 @@ int wc_falcon_sign_msg(const byte* in, word32 inLen,
|
|||
if (ret == 0) {
|
||||
ret = falcon_native_sign_msg(in, inLen, out, outLen, key, rng);
|
||||
}
|
||||
#else
|
||||
ret = NOT_COMPILED_IN;
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -168,8 +190,12 @@ int wc_falcon_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
|
|||
/* fall-through when unavailable */
|
||||
ret = 0;
|
||||
}
|
||||
#endif
|
||||
#endif /* WOLF_CRYPTO_CB */
|
||||
|
||||
#ifdef WOLF_CRYPTO_CB_ONLY_FALCON
|
||||
/* No software fallback: only a crypto callback can service the request. */
|
||||
ret = NO_VALID_DEVID;
|
||||
#else
|
||||
if ((ret == 0) && (!key->pubKeySet)) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
|
|
@ -177,6 +203,7 @@ int wc_falcon_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
|
|||
if (ret == 0) {
|
||||
ret = falcon_native_verify_msg(sig, sigLen, msg, msgLen, res, key);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
|
||||
|
||||
#if defined(HAVE_FALCON)
|
||||
#if defined(HAVE_FALCON) && !defined(WOLF_CRYPTO_CB_ONLY_FALCON)
|
||||
|
||||
#include <wolfssl/wolfcrypt/falcon.h>
|
||||
#include <wolfssl/wolfcrypt/error-crypt.h>
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
|
||||
|
||||
#if defined(HAVE_FALCON) && !defined(WOLFSSL_FALCON_VERIFY_ONLY)
|
||||
#if defined(HAVE_FALCON) && !defined(WOLFSSL_FALCON_VERIFY_ONLY) && !defined(WOLF_CRYPTO_CB_ONLY_FALCON)
|
||||
|
||||
#include <wolfssl/wolfcrypt/wc_falcon_bigint.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
|
||||
|
||||
#if defined(HAVE_FALCON) && !defined(WOLFSSL_FALCON_VERIFY_ONLY)
|
||||
#if defined(HAVE_FALCON) && !defined(WOLFSSL_FALCON_VERIFY_ONLY) && !defined(WOLF_CRYPTO_CB_ONLY_FALCON)
|
||||
|
||||
#include <wolfssl/wolfcrypt/falcon.h>
|
||||
#include <wolfssl/wolfcrypt/wc_falcon_codec.h>
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
|
||||
|
||||
#if defined(HAVE_FALCON) && !defined(WOLFSSL_FALCON_VERIFY_ONLY)
|
||||
#if defined(HAVE_FALCON) && !defined(WOLFSSL_FALCON_VERIFY_ONLY) && !defined(WOLF_CRYPTO_CB_ONLY_FALCON)
|
||||
|
||||
#include <wolfssl/wolfcrypt/wc_falcon_fft.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@
|
|||
|
||||
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
|
||||
|
||||
#if defined(HAVE_FALCON) && !defined(WOLFSSL_FALCON_VERIFY_ONLY) && \
|
||||
#if defined(HAVE_FALCON) && !defined(WOLF_CRYPTO_CB_ONLY_FALCON) && !defined(WOLFSSL_FALCON_VERIFY_ONLY) && \
|
||||
defined(WOLFSSL_FALCON_FFT_AVX2)
|
||||
|
||||
#include <wolfssl/wolfcrypt/wc_falcon_fft.h>
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
|
||||
|
||||
#if defined(HAVE_FALCON)
|
||||
#if defined(HAVE_FALCON) && !defined(WOLF_CRYPTO_CB_ONLY_FALCON)
|
||||
|
||||
#include <wolfssl/wolfcrypt/wc_falcon_fpr.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
|
||||
|
||||
#if defined(HAVE_FALCON) && !defined(WOLFSSL_FALCON_VERIFY_ONLY)
|
||||
#if defined(HAVE_FALCON) && !defined(WOLFSSL_FALCON_VERIFY_ONLY) && !defined(WOLF_CRYPTO_CB_ONLY_FALCON)
|
||||
|
||||
#include <wolfssl/wolfcrypt/wc_falcon_keygen.h>
|
||||
#include <wolfssl/wolfcrypt/wc_falcon_bigint.h>
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
|
||||
|
||||
#if defined(HAVE_FALCON) && !defined(WOLFSSL_FALCON_VERIFY_ONLY)
|
||||
#if defined(HAVE_FALCON) && !defined(WOLFSSL_FALCON_VERIFY_ONLY) && !defined(WOLF_CRYPTO_CB_ONLY_FALCON)
|
||||
|
||||
#include <wolfssl/wolfcrypt/wc_falcon_poly.h>
|
||||
#include <wolfssl/wolfcrypt/wc_falcon_fft.h> /* falcon_gm_tab */
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@
|
|||
|
||||
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
|
||||
|
||||
#if defined(HAVE_FALCON) && !defined(WOLFSSL_FALCON_VERIFY_ONLY)
|
||||
#if defined(HAVE_FALCON) && !defined(WOLFSSL_FALCON_VERIFY_ONLY) && !defined(WOLF_CRYPTO_CB_ONLY_FALCON)
|
||||
|
||||
#include <wolfssl/wolfcrypt/wc_falcon_sampler.h>
|
||||
#include <wolfssl/wolfcrypt/wc_falcon_fpr.h>
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
|
||||
|
||||
#if defined(HAVE_FALCON) && !defined(WOLFSSL_FALCON_VERIFY_ONLY)
|
||||
#if defined(HAVE_FALCON) && !defined(WOLFSSL_FALCON_VERIFY_ONLY) && !defined(WOLF_CRYPTO_CB_ONLY_FALCON)
|
||||
|
||||
#include <wolfssl/wolfcrypt/wc_falcon_sign.h>
|
||||
#include <wolfssl/wolfcrypt/wc_falcon_fpr.h>
|
||||
|
|
|
|||
|
|
@ -57713,6 +57713,9 @@ static wc_test_ret_t mldsa_decode_test(void)
|
|||
* then drop pk / sig / siglen into the arrays below. (liboqs >= 0.11 API.)
|
||||
*/
|
||||
|
||||
/* The KAT vectors and their verifier exercise the software verify path, which
|
||||
* is not present in a WOLF_CRYPTO_CB_ONLY_FALCON build. */
|
||||
#ifndef WOLF_CRYPTO_CB_ONLY_FALCON
|
||||
#define FALCON_KAT_MSG "wolfSSL FN-DSA differential KAT"
|
||||
|
||||
static const byte FALCON512_pk[] = {
|
||||
|
|
@ -58125,7 +58128,9 @@ static wc_test_ret_t falcon_verify_kat(byte level, const byte* pk, word32 pkLen,
|
|||
const byte* msg = (const byte*)FALCON_KAT_MSG;
|
||||
word32 msgLen = (word32)XSTRLEN(FALCON_KAT_MSG);
|
||||
|
||||
ret = wc_falcon_init(&key);
|
||||
/* Use the global test devId so that, when cryptocb_test() has registered a
|
||||
* device, verification is routed through the crypto callback. */
|
||||
ret = wc_falcon_init_ex(&key, HEAP_HINT, devId);
|
||||
if (ret != 0)
|
||||
return WC_TEST_RET_ENC_EC(ret);
|
||||
|
||||
|
|
@ -58135,7 +58140,7 @@ static wc_test_ret_t falcon_verify_kat(byte level, const byte* pk, word32 pkLen,
|
|||
ret = wc_falcon_import_public(pk, pkLen, &key);
|
||||
if (ret != 0) { ret = WC_TEST_RET_ENC_EC(ret); goto out; }
|
||||
|
||||
/* A genuine liboqs-produced signature must verify (res == 1). */
|
||||
/* A genuine reference-produced signature must verify (res == 1). */
|
||||
res = 0;
|
||||
ret = wc_falcon_verify_msg(sig, sigLen, msg, msgLen, &res, &key);
|
||||
if (ret != 0) { ret = WC_TEST_RET_ENC_EC(ret); goto out; }
|
||||
|
|
@ -58157,11 +58162,13 @@ out:
|
|||
wc_falcon_free(&key);
|
||||
return ret;
|
||||
}
|
||||
#endif /* !WOLF_CRYPTO_CB_ONLY_FALCON */
|
||||
|
||||
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t falcon_test(void)
|
||||
{
|
||||
wc_test_ret_t ret;
|
||||
|
||||
#ifndef WOLF_CRYPTO_CB_ONLY_FALCON
|
||||
ret = falcon_verify_kat(FALCON_LEVEL1, FALCON512_pk,
|
||||
(word32)sizeof(FALCON512_pk), FALCON512_sig, FALCON512_SIGLEN);
|
||||
if (ret != 0)
|
||||
|
|
@ -58190,7 +58197,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t falcon_test(void)
|
|||
word32 siglen = (word32)sizeof(sig);
|
||||
int res = 0;
|
||||
|
||||
ret = wc_falcon_init(&k);
|
||||
ret = wc_falcon_init_ex(&k, HEAP_HINT, devId);
|
||||
if (ret == 0)
|
||||
ret = wc_falcon_set_level(&k, falconLvls[li]);
|
||||
if (ret == 0)
|
||||
|
|
@ -58220,6 +58227,29 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t falcon_test(void)
|
|||
wc_FreeRng(&rng);
|
||||
}
|
||||
#endif /* WC_FALCON_HAVE_NATIVE_SIGN */
|
||||
#else /* WOLF_CRYPTO_CB_ONLY_FALCON */
|
||||
/* Software Falcon is compiled out. Confirm the public API refuses an
|
||||
* operation when no crypto-callback device is available (INVALID_DEVID),
|
||||
* rather than silently doing nothing. */
|
||||
{
|
||||
falcon_key k;
|
||||
int res = 0;
|
||||
int r;
|
||||
|
||||
ret = wc_falcon_init(&k);
|
||||
if (ret == 0)
|
||||
ret = wc_falcon_set_level(&k, FALCON_LEVEL1);
|
||||
if (ret == 0) {
|
||||
r = wc_falcon_verify_msg((const byte*)"m", 1, (const byte*)"m", 1,
|
||||
&res, &k);
|
||||
if (r != WC_NO_ERR_TRACE(NO_VALID_DEVID))
|
||||
ret = WC_TEST_RET_ENC_NC;
|
||||
}
|
||||
wc_falcon_free(&k);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
#endif /* !WOLF_CRYPTO_CB_ONLY_FALCON */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -77679,6 +77709,45 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
|
|||
}
|
||||
}
|
||||
#endif /* WOLFSSL_HAVE_SLHDSA */
|
||||
#if defined(HAVE_FALCON) && !defined(WOLF_CRYPTO_CB_ONLY_FALCON)
|
||||
#ifndef WOLFSSL_FALCON_VERIFY_ONLY
|
||||
if (info->pk.type == WC_PK_TYPE_PQC_SIG_KEYGEN &&
|
||||
info->pk.pqc_sig_kg.type == WC_PQC_SIG_TYPE_FALCON) {
|
||||
falcon_key* fk = (falcon_key*)info->pk.pqc_sig_kg.key;
|
||||
/* set devId invalid so the software path is used (no recursion) */
|
||||
fk->devId = INVALID_DEVID;
|
||||
ret = wc_falcon_make_key(fk, info->pk.pqc_sig_kg.rng);
|
||||
fk->devId = devIdArg;
|
||||
myCtx->exampleVar++;
|
||||
}
|
||||
else if (info->pk.type == WC_PK_TYPE_PQC_SIG_SIGN &&
|
||||
info->pk.pqc_sign.type == WC_PQC_SIG_TYPE_FALCON) {
|
||||
falcon_key* fk = (falcon_key*)info->pk.pqc_sign.key;
|
||||
fk->devId = INVALID_DEVID;
|
||||
ret = wc_falcon_sign_msg(info->pk.pqc_sign.in,
|
||||
info->pk.pqc_sign.inlen, info->pk.pqc_sign.out,
|
||||
info->pk.pqc_sign.outlen, fk, info->pk.pqc_sign.rng);
|
||||
fk->devId = devIdArg;
|
||||
myCtx->exampleVar++;
|
||||
}
|
||||
else
|
||||
#endif /* !WOLFSSL_FALCON_VERIFY_ONLY */
|
||||
if (info->pk.type == WC_PK_TYPE_PQC_SIG_VERIFY &&
|
||||
info->pk.pqc_verify.type == WC_PQC_SIG_TYPE_FALCON) {
|
||||
falcon_key* fk = (falcon_key*)info->pk.pqc_verify.key;
|
||||
int verifyRet;
|
||||
fk->devId = INVALID_DEVID;
|
||||
verifyRet = wc_falcon_verify_msg(info->pk.pqc_verify.sig,
|
||||
info->pk.pqc_verify.siglen, info->pk.pqc_verify.msg,
|
||||
info->pk.pqc_verify.msglen, info->pk.pqc_verify.res, fk);
|
||||
fk->devId = devIdArg;
|
||||
/* SIG_VERIFY_E is a validity signal, not a crypto error. */
|
||||
if (verifyRet == WC_NO_ERR_TRACE(SIG_VERIFY_E))
|
||||
verifyRet = 0;
|
||||
ret = verifyRet;
|
||||
myCtx->exampleVar++;
|
||||
}
|
||||
#endif /* HAVE_FALCON && !WOLF_CRYPTO_CB_ONLY_FALCON */
|
||||
#ifdef WOLFSSL_HAVE_MLKEM
|
||||
if (info->pk.type == WC_PK_TYPE_PQC_KEM_KEYGEN) {
|
||||
if ((info->pk.pqc_kem_kg.type == WC_PQC_KEM_TYPE_MLKEM) &&
|
||||
|
|
@ -79639,6 +79708,20 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cryptocb_test(void)
|
|||
myCtx.exampleVar = baseline;
|
||||
}
|
||||
#endif
|
||||
#if defined(HAVE_FALCON) && !defined(WOLF_CRYPTO_CB_ONLY_FALCON)
|
||||
if (ret == 0) {
|
||||
/* Route Falcon through the crypto callback (global devId is set) and
|
||||
* confirm the cb path was actually exercised via the hit counter, so a
|
||||
* silent software fallback can't mask a dispatch regression. Both the
|
||||
* KAT verify and (when built) the native keygen/sign/verify round-trip
|
||||
* use the test devId. */
|
||||
int baseline = myCtx.exampleVar;
|
||||
ret = falcon_test();
|
||||
if ((ret == 0) && (myCtx.exampleVar == baseline))
|
||||
ret = WC_TEST_RET_ENC_NC;
|
||||
myCtx.exampleVar = baseline;
|
||||
}
|
||||
#endif
|
||||
#if defined(WOLFSSL_HAVE_XMSS) && !defined(WOLFSSL_XMSS_VERIFY_ONLY)
|
||||
if (ret == 0)
|
||||
ret = xmss_test();
|
||||
|
|
|
|||
|
|
@ -213,7 +213,10 @@ WOLFSSL_API int wc_Falcon_PublicKeyToDer(falcon_key* key, byte* output,
|
|||
word32 inLen, int withAlg);
|
||||
|
||||
/* Native implementation core (internal). The public wc_falcon_* functions in
|
||||
* falcon.c wrap these with cryptocb dispatch and argument checking. */
|
||||
* falcon.c wrap these with cryptocb dispatch and argument checking. With
|
||||
* WOLF_CRYPTO_CB_ONLY_FALCON the native core is not compiled: all operations go
|
||||
* through the crypto callback. */
|
||||
#ifndef WOLF_CRYPTO_CB_ONLY_FALCON
|
||||
#ifndef WOLFSSL_FALCON_VERIFY_ONLY
|
||||
/* Signals that native signing and key generation are available. */
|
||||
#define WC_FALCON_HAVE_NATIVE_SIGN
|
||||
|
|
@ -223,6 +226,7 @@ WOLFSSL_LOCAL int falcon_native_sign_msg(const byte* in, word32 inLen,
|
|||
#endif
|
||||
WOLFSSL_LOCAL int falcon_native_verify_msg(const byte* sig, word32 sigLen,
|
||||
const byte* msg, word32 msgLen, int* res, falcon_key* key);
|
||||
#endif /* !WOLF_CRYPTO_CB_ONLY_FALCON */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
|
|
|||
Loading…
Reference in New Issue