diff --git a/.wolfssl_known_macro_extras b/.wolfssl_known_macro_extras index 7f8cc3f886..54aa491c71 100644 --- a/.wolfssl_known_macro_extras +++ b/.wolfssl_known_macro_extras @@ -909,6 +909,7 @@ WOLFSSL_SHA512_HASHTYPE WOLFSSL_SHUTDOWNONCE WOLFSSL_SILABS_TRNG WOLFSSL_SLHDSA_FULL_HASH +WOLFSSL_SLHDSA_NO_VERIFY_ONLY WOLFSSL_SNIFFER_NO_RECOVERY WOLFSSL_SP_ARM32_UDIV WOLFSSL_SP_FAST_NCT_EXPTMOD diff --git a/tests/api/test_slhdsa.c b/tests/api/test_slhdsa.c index fc40bed9c7..4d54bb6929 100644 --- a/tests/api/test_slhdsa.c +++ b/tests/api/test_slhdsa.c @@ -42,7 +42,7 @@ int test_wc_slhdsa(void) { EXPECT_DECLS; -#ifdef WOLFSSL_HAVE_SLHDSA +#if defined(WOLFSSL_HAVE_SLHDSA) && !defined(WOLFSSL_SLHDSA_NO_SHAKE) SlhDsaKey key; /* Test NULL parameter handling for init. */ @@ -84,7 +84,7 @@ int test_wc_slhdsa(void) wc_SlhDsaKey_Free(&key); #endif -#endif /* WOLFSSL_HAVE_SLHDSA */ +#endif /* WOLFSSL_HAVE_SLHDSA && !WOLFSSL_SLHDSA_NO_SHAKE */ return EXPECT_RESULT(); } @@ -94,7 +94,7 @@ int test_wc_slhdsa(void) int test_wc_slhdsa_sizes(void) { EXPECT_DECLS; -#ifdef WOLFSSL_HAVE_SLHDSA +#if defined(WOLFSSL_HAVE_SLHDSA) && !defined(WOLFSSL_SLHDSA_NO_SHAKE) SlhDsaKey key; /* Test NULL parameter handling for size functions. */ @@ -226,7 +226,7 @@ int test_wc_slhdsa_sizes(void) WC_SLHDSA_SHAKE256F_SIG_LEN); #endif -#endif /* WOLFSSL_HAVE_SLHDSA */ +#endif /* WOLFSSL_HAVE_SLHDSA && !WOLFSSL_SLHDSA_NO_SHAKE */ return EXPECT_RESULT(); } diff --git a/wolfcrypt/src/wc_slhdsa.c b/wolfcrypt/src/wc_slhdsa.c index 402b484746..4adc829799 100644 --- a/wolfcrypt/src/wc_slhdsa.c +++ b/wolfcrypt/src/wc_slhdsa.c @@ -752,6 +752,7 @@ static int slhdsakey_hash_f_sha2(SlhDsaKey* key, const byte* pk_seed, return ret; } +#ifndef WOLFSSL_SLHDSA_VERIFY_ONLY /* SHA2 H function. * * FIPS 205. Section 11.2. @@ -820,6 +821,7 @@ static int slhdsakey_hash_h_sha2(SlhDsaKey* key, const byte* pk_seed, return ret; } +#endif /* !WOLFSSL_SLHDSA_VERIFY_ONLY */ /* SHA2 H function with two separate n-byte halves. * @@ -895,6 +897,7 @@ static int slhdsakey_hash_h_2_sha2(SlhDsaKey* key, const byte* pk_seed, return ret; } +#ifndef WOLFSSL_SLHDSA_VERIFY_ONLY /* SHA2 PRF function. * * FIPS 205. Section 11.2. @@ -938,6 +941,7 @@ static int slhdsakey_hash_prf_sha2(SlhDsaKey* key, const byte* pk_seed, return ret; } +#endif /* !WOLFSSL_SLHDSA_VERIFY_ONLY */ /* SHA2 T_l streaming: start with address. * @@ -1106,6 +1110,7 @@ static int slhdsakey_mgf1_sha2(SlhDsaKey* key, const byte* seed, return ret; } +#ifndef WOLFSSL_SLHDSA_VERIFY_ONLY /* SHA2 PRF_msg function. * * FIPS 205. Section 11.2. @@ -1167,6 +1172,7 @@ static int slhdsakey_prf_msg_sha2(SlhDsaKey* key, const byte* sk_prf, return ret; } +#endif /* !WOLFSSL_SLHDSA_VERIFY_ONLY */ /* SHA2 H_msg function. * @@ -1301,6 +1307,7 @@ static int slhdsakey_hash_f_shake(SlhDsaKey* key, const byte* pk_seed, #endif } +#ifndef WOLFSSL_SLHDSA_VERIFY_ONLY static int slhdsakey_hash_h_shake(SlhDsaKey* key, const byte* pk_seed, const word32* adrs, const byte* node, byte n, byte* hash) { @@ -1312,6 +1319,7 @@ static int slhdsakey_hash_h_shake(SlhDsaKey* key, const byte* pk_seed, 2 * n, NULL, 0, hash, n); #endif } +#endif /* !WOLFSSL_SLHDSA_VERIFY_ONLY */ static int slhdsakey_hash_h_2_shake(SlhDsaKey* key, const byte* pk_seed, const word32* adrs, const byte* m1, const byte* m2, byte n, byte* hash) @@ -1320,6 +1328,7 @@ static int slhdsakey_hash_h_2_shake(SlhDsaKey* key, const byte* pk_seed, n, m2, n, hash, n); } +#ifndef WOLFSSL_SLHDSA_VERIFY_ONLY static int slhdsakey_hash_prf_shake(SlhDsaKey* key, const byte* pk_seed, const byte* sk_seed, const word32* adrs, byte n, byte* hash) { @@ -1331,6 +1340,7 @@ static int slhdsakey_hash_prf_shake(SlhDsaKey* key, const byte* pk_seed, sk_seed, n, NULL, 0, hash, n); #endif } +#endif /* !WOLFSSL_SLHDSA_VERIFY_ONLY */ #define HASH_PRF(k, pk_seed, sk_seed, adrs, n, o) \ (SLHDSA_IS_SHA2((k)->params->param) ? \ @@ -1928,7 +1938,7 @@ static int slhdsakey_shake256_set_seed_ha_hash_x4(word64* state, return ret; } -#endif +#endif /* WOLFSSL_SLHDSA_VERIFY_ONLY */ /* Get the four SHAKE-256 n-byte hash results. * @@ -1963,7 +1973,7 @@ do { \ ((word8*)((state) + (o) - 2))[3] = (a) + 2; \ ((word8*)((state) + (o) - 1))[3] = (a) + 3; \ } while (0) -#endif +#endif /* !WOLFSSL_SLHDSA_VERIFY_ONLY */ /* Set the chain address indices into the SHAKE-256 x4 state. * @@ -2007,7 +2017,7 @@ do { \ c32toa((ti) + 2, (byte*)&((word32*)((state) + (o) - 2))[1]); \ c32toa((ti) + 3, (byte*)&((word32*)((state) + (o) - 1))[1]); \ } while (0) -#endif +#endif /* !WOLFSSL_SLHDSA_VERIFY_ONLY */ /* Set the tree indices into the SHAKE-256 x4 state. * @@ -2349,7 +2359,7 @@ static int slhdsakey_chain_x4_16(byte* sk, const byte* pk_seed, byte* addr, WC_FREE_VAR_EX(fixed, heap, DYNAMIC_TYPE_SLHDSA); return ret; } -#endif +#endif /* !WOLFSSL_SLHDSA_VERIFY_ONLY */ #if !defined(WOLFSSL_SLHDSA_PARAM_NO_192) /* Iterate the hash function 15 times with 4 hashes when n=24. @@ -3886,10 +3896,6 @@ static int slhdsakey_wots_pk_from_sig_x4(SlhDsaKey* key, const byte* sig, const byte* msg, const byte* pk_seed, word32* adrs, byte* pk_sig) { int ret = 0; - byte idx[4] = {0}; - int i; - byte ii; - sword8 j; HashAddress wotspk_adrs; byte n = key->params->n; byte len = key->params->len; @@ -3899,7 +3905,10 @@ static int slhdsakey_wots_pk_from_sig_x4(SlhDsaKey* key, const byte* sig, DYNAMIC_TYPE_SLHDSA, ret = MEMORY_E); #if !defined(WOLFSSL_SLHDSA_PARAM_NO_128) if ((ret == 0) && (n == WC_SLHDSA_N_128)) { - ii = 0; + int i; + sword8 j; + byte ii = 0; + byte idx[4] = {0}; for (j = 0; j <= SLHDSA_WM1; j++) { for (i = 0; i < len; i++) { if ((sword8)msg[i] == j) { @@ -3926,7 +3935,10 @@ static int slhdsakey_wots_pk_from_sig_x4(SlhDsaKey* key, const byte* sig, #endif #if !defined(WOLFSSL_SLHDSA_PARAM_NO_192) if ((ret == 0) && (n == 24)) { - ii = 0; + int i; + sword8 j; + byte ii = 0; + byte idx[4] = {0}; for (j = 0; j <= SLHDSA_WM1; j++) { for (i = 0; i < len; i++) { if ((sword8)msg[i] == j) { @@ -3953,7 +3965,10 @@ static int slhdsakey_wots_pk_from_sig_x4(SlhDsaKey* key, const byte* sig, #endif #if !defined(WOLFSSL_SLHDSA_PARAM_NO_256) if ((ret == 0) && (n == 32)) { - ii = 0; + int i; + sword8 j; + byte ii = 0; + byte idx[4] = {0}; for (j = 0; j <= SLHDSA_WM1; j++) { for (i = 0; i < len; i++) { if ((sword8)msg[i] == j) { @@ -3978,9 +3993,14 @@ static int slhdsakey_wots_pk_from_sig_x4(SlhDsaKey* key, const byte* sig, } else #endif - if (ret == 0) { - ret = NOT_COMPILED_IN; + { + (void)msg; + (void)key; + if (ret == 0) { + ret = NOT_COMPILED_IN; + } } + if (ret == 0) { HA_Copy(wotspk_adrs, adrs); HA_SetTypeAndClearNotKPA(wotspk_adrs, HA_WOTS_PK); @@ -4457,7 +4477,7 @@ static int slhdsakey_xmss_sign(SlhDsaKey* key, const byte* m, return ret; } -#endif +#endif /* !WOLFSSL_SLHDSA_VERIFY_ONLY */ /* Compute XMSS public key from XMSS signature. * @@ -4651,7 +4671,7 @@ static int slhdsakey_ht_sign(SlhDsaKey* key, const byte* pk_fors, return ret; } -#endif +#endif /* !WOLFSSL_SLHDSA_VERIFY_ONLY */ /* Verify hypertree signature. * @@ -5680,7 +5700,7 @@ static int slhdsakey_fors_sign(SlhDsaKey* key, const byte* md, return ret; } -#endif +#endif /* !WOLFSSL_SLHDSA_VERIFY_ONLY */ #if defined(USE_INTEL_SPEEDUP) && !defined(WOLFSSL_WC_SLHDSA_SMALL) /* F hash 4 simultaneously. @@ -7112,7 +7132,7 @@ int wc_SlhDsaKey_SignMsgWithRandom(SlhDsaKey* key, const byte* mprime, addRnd); } -#endif +#endif /* !WOLFSSL_SLHDSA_VERIFY_ONLY */ /* Verify SLH-DSA signature. * @@ -7857,7 +7877,7 @@ int wc_SlhDsaKey_SignHash(SlhDsaKey* key, const byte* ctx, byte ctxSz, return ret; } -#endif +#endif /* !WOLFSSL_SLHDSA_VERIFY_ONLY */ /* Verify SLH-DSA signature. * @@ -8044,7 +8064,7 @@ int wc_SlhDsaKey_ImportPrivate(SlhDsaKey* key, const byte* priv, word32 privLen) return ret; } -#endif +#endif /* !WOLFSSL_SLHDSA_VERIFY_ONLY */ /* Import public key from data. * @@ -8157,7 +8177,7 @@ int wc_SlhDsaKey_ExportPrivate(SlhDsaKey* key, byte* priv, word32* privLen) return ret; } -#endif +#endif /* !WOLFSSL_SLHDSA_VERIFY_ONLY */ /* Export the public key. * @@ -8215,7 +8235,7 @@ int wc_SlhDsaKey_PrivateSize(SlhDsaKey* key) return ret; } -#endif +#endif /* !WOLFSSL_SLHDSA_VERIFY_ONLY */ /* Return the size of the public key for the parameters. * @@ -8318,7 +8338,7 @@ int wc_SlhDsaKey_PrivateSizeFromParam(enum SlhDsaParam param) return ret; } -#endif +#endif /* !WOLFSSL_SLHDSA_VERIFY_ONLY */ /* Return the size of the public key for the parameters. * diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 914f9ab22b..57d224d92e 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -54233,9 +54233,7 @@ static wc_test_ret_t slhdsa_test_param(enum SlhDsaParam param) wc_test_ret_t slhdsa_test(void) { -#if !defined(WOLFSSL_SLHDSA_VERIFY_ONLY) || defined(WOLFSSL_SLHDSA_PARAM_128S) - int ret; -#endif + int ret = 0; #ifdef WOLFSSL_SLHDSA_PARAM_128S WC_DECLARE_VAR(key_vfy, SlhDsaKey, 1, HEAP_HINT); #ifndef WOLFSSL_SLHDSA_VERIFY_ONLY @@ -55954,9 +55952,7 @@ wc_test_ret_t slhdsa_test(void) } } #endif -#endif /* !WOLFSSL_SLHDSA_VERIFY_ONLY */ -#ifndef WOLFSSL_SLHDSA_VERIFY_ONLY #ifdef WOLFSSL_SLHDSA_PARAM_128S ret = slhdsa_test_param(SLHDSA_SHAKE128S); if (ret != 0) { @@ -56041,10 +56037,17 @@ wc_test_ret_t slhdsa_test(void) goto out; } #endif -#endif + +#endif /* !WOLFSSL_SLHDSA_VERIFY_ONLY */ + +#if defined(WOLFSSL_SLHDSA_VERIFY_ONLY) || \ + defined(WOLFSSL_SLHDSA_PARAM_128S) out: +#endif + +#ifdef WOLFSSL_SLHDSA_PARAM_128S #ifdef WC_DECLARE_VAR_IS_HEAP_ALLOC if (key_vfy) #endif @@ -56052,6 +56055,7 @@ wc_test_ret_t slhdsa_test(void) wc_SlhDsaKey_Free(key_vfy); } WC_FREE_VAR_EX(key_vfy, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); +#endif #ifndef WOLFSSL_SLHDSA_VERIFY_ONLY #ifdef WC_DECLARE_VAR_IS_HEAP_ALLOC if (key) diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 1dfc05a909..b56fc5e190 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -4042,6 +4042,14 @@ extern void uITRON4_free(void *p) ; #undef WOLFSSL_GENERAL_ALIGNMENT #define WOLFSSL_GENERAL_ALIGNMENT SIZEOF_LONG #endif + + /* SLH-DSA signature generation is too computationally intensive to be + * appropriate in typical kernel deployments. + */ + #if !defined(WOLFSSL_SLHDSA_VERIFY_ONLY) && \ + !defined(WOLFSSL_SLHDSA_NO_VERIFY_ONLY) + #define WOLFSSL_SLHDSA_VERIFY_ONLY + #endif #endif /* WOLFSSL_KERNEL_MODE */ #if defined(WC_SYM_RELOC_TABLES) && defined(HAVE_FIPS) && \ diff --git a/wolfssl/wolfcrypt/wc_slhdsa.h b/wolfssl/wolfcrypt/wc_slhdsa.h index 7153143d27..eb34c73bd8 100644 --- a/wolfssl/wolfcrypt/wc_slhdsa.h +++ b/wolfssl/wolfcrypt/wc_slhdsa.h @@ -39,6 +39,16 @@ #ifdef WOLFSSL_HAVE_SLHDSA /* ======== SHAKE parameter guards ======== */ +#ifdef WOLFSSL_SLHDSA_NO_SHAKE + + #define WOLFSSL_SLHDSA_PARAM_NO_128S + #define WOLFSSL_SLHDSA_PARAM_NO_128F + #define WOLFSSL_SLHDSA_PARAM_NO_192S + #define WOLFSSL_SLHDSA_PARAM_NO_192F + #define WOLFSSL_SLHDSA_PARAM_NO_256S + #define WOLFSSL_SLHDSA_PARAM_NO_256F + +#else /* !WOLFSSL_SLHDSA_NO_SHAKE */ /* When a bits/opt is defined then ensure 'NO' defines are off. */ #ifdef WOLFSSL_SLHDSA_PARAM_128S @@ -72,6 +82,8 @@ #undef WOLFSSL_SLHDSA_PARAM_NO_FAST #endif +#endif /* !WOLFSSL_SLHDSA_NO_SHAKE */ + /* When 'NO' defines are on then define no parameter set. */ #if defined(WOLFSSL_SLHDSA_PARAM_NO_128S) && \ defined(WOLFSSL_SLHDSA_PARAM_NO_128F) @@ -167,6 +179,12 @@ #define WOLFSSL_SLHDSA_PARAM_NO_256 #endif +#if defined(WOLFSSL_SLHDSA_PARAM_NO_128) && \ + defined(WOLFSSL_SLHDSA_PARAM_NO_192) && \ + defined(WOLFSSL_SLHDSA_PARAM_NO_256) + #define WOLFSSL_SLHDSA_NO_SHAKE +#endif + /* ======== SHA2 parameter guards ======== */ #ifdef WOLFSSL_SLHDSA_SHA2 @@ -298,7 +316,11 @@ #define WOLFSSL_SLHDSA_PARAM_NO_SHA2_256 #endif -#endif /* WOLFSSL_SLHDSA_SHA2 */ +#else /* !WOLFSSL_SLHDSA_SHA2 */ + + #define WOLFSSL_SLHDSA_NO_SHA2 + +#endif /* !WOLFSSL_SLHDSA_SHA2 */ /* ======== Security parameter (n) per FIPS 205 Table 2 ======== */ @@ -474,26 +496,50 @@ !defined(WOLFSSL_SLHDSA_PARAM_NO_FAST) /* Maximum signature length. */ #define WC_SLHDSA_MAX_SIG_LEN WC_SLHDSA_SHAKE256F_SIG_LEN +#elif !defined(WOLFSSL_SLHDSA_PARAM_NO_SHA2_256) && \ + !defined(WOLFSSL_SLHDSA_PARAM_NO_SHA2_FAST) + /* Maximum signature length. */ + #define WC_SLHDSA_MAX_SIG_LEN WC_SLHDSA_SHA2_256F_SIG_LEN #elif !defined(WOLFSSL_SLHDSA_PARAM_NO_192) && \ !defined(WOLFSSL_SLHDSA_PARAM_NO_FAST) /* Maximum signature length. */ #define WC_SLHDSA_MAX_SIG_LEN WC_SLHDSA_SHAKE192F_SIG_LEN +#elif !defined(WOLFSSL_SLHDSA_PARAM_NO_SHA2_192) && \ + !defined(WOLFSSL_SLHDSA_PARAM_NO_SHA2_FAST) + /* Maximum signature length. */ + #define WC_SLHDSA_MAX_SIG_LEN WC_SLHDSA_SHA2_192F_SIG_LEN #elif !defined(WOLFSSL_SLHDSA_PARAM_NO_256) && \ !defined(WOLFSSL_SLHDSA_PARAM_NO_SMALL) /* Maximum signature length. */ #define WC_SLHDSA_MAX_SIG_LEN WC_SLHDSA_SHAKE256S_SIG_LEN +#elif !defined(WOLFSSL_SLHDSA_PARAM_NO_SHA2_256) && \ + !defined(WOLFSSL_SLHDSA_PARAM_NO_SHA2_SMALL) + /* Maximum signature length. */ + #define WC_SLHDSA_MAX_SIG_LEN WC_SLHDSA_SHA2_256S_SIG_LEN #elif !defined(WOLFSSL_SLHDSA_PARAM_NO_128) && \ !defined(WOLFSSL_SLHDSA_PARAM_NO_FAST) /* Maximum signature length. */ #define WC_SLHDSA_MAX_SIG_LEN WC_SLHDSA_SHAKE128F_SIG_LEN +#elif !defined(WOLFSSL_SLHDSA_PARAM_NO_SHA2_128) && \ + !defined(WOLFSSL_SLHDSA_PARAM_NO_SHA2_FAST) + /* Maximum signature length. */ + #define WC_SLHDSA_MAX_SIG_LEN WC_SLHDSA_SHA2_128F_SIG_LEN #elif !defined(WOLFSSL_SLHDSA_PARAM_NO_192) && \ !defined(WOLFSSL_SLHDSA_PARAM_NO_SMALL) /* Maximum signature length. */ #define WC_SLHDSA_MAX_SIG_LEN WC_SLHDSA_SHAKE192S_SIG_LEN +#elif !defined(WOLFSSL_SLHDSA_PARAM_NO_SHA2_192) && \ + !defined(WOLFSSL_SLHDSA_PARAM_NO_SHA2_SMALL) + /* Maximum signature length. */ + #define WC_SLHDSA_MAX_SIG_LEN WC_SLHDSA_SHA2_192S_SIG_LEN #elif !defined(WOLFSSL_SLHDSA_PARAM_NO_128) && \ !defined(WOLFSSL_SLHDSA_PARAM_NO_SMALL) /* Maximum signature length. */ #define WC_SLHDSA_MAX_SIG_LEN WC_SLHDSA_SHAKE128S_SIG_LEN +#elif !defined(WOLFSSL_SLHDSA_PARAM_NO_SHA2_128) && \ + !defined(WOLFSSL_SLHDSA_PARAM_NO_SHA2_SMALL) + /* Maximum signature length. */ + #define WC_SLHDSA_MAX_SIG_LEN WC_SLHDSA_SHA2_128S_SIG_LEN #else #error "No parameters defined" #endif @@ -520,7 +566,7 @@ enum SlhDsaParam { #ifdef WOLFSSL_SLHDSA_SHA2 #define SLHDSA_IS_SHA2(p) ((p) >= SLHDSA_SHA2_128S) #else - #define SLHDSA_IS_SHA2(p) (0) + #define SLHDSA_IS_SHA2(p) 0 #endif /* Pre-defined parameter values. */