Skip to content

Commit 6043ac5

Browse files
committed
New hash modes and features for PQ submission
1 parent 9e0e11f commit 6043ac5

16 files changed

Lines changed: 1894 additions & 325 deletions

File tree

configure.ac

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1962,6 +1962,9 @@ do
19621962
sha256-192)
19631963
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_LMS_SHA256_192"
19641964
;;
1965+
shake256)
1966+
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_LMS_SHAKE256"
1967+
;;
19651968
*)
19661969
AC_MSG_ERROR([Invalid choice for LMS []: $ENABLED_LMS.])
19671970
break;;
@@ -6061,8 +6064,8 @@ AS_CASE([$FIPS_VERSION],
60616064
(test "$FIPS_VERSION" != "dev" || test "$enable_sha512" != "no")],
60626065
[ENABLED_SHA512="yes"; AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SHA512 -DWOLFSSL_SHA384"])
60636066
6064-
# SHA512-224 and SHA512-256 are SHA-2 algorithms not in our FIPS algorithm list
6065-
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NOSHA512_224 -DWOLFSSL_NOSHA512_256"
6067+
# SHA512-224 and SHA512-256 enabled for FIPS v7+ (needed for ML-DSA
6068+
# HashML-DSA ACVP test vectors with SHA2-512/224 and SHA2-512/256)
60666069
60676070
# Shake128 because we're testing SHAKE256
60686071
AS_IF([test "x$ENABLED_SHAKE128" = "xno" &&
@@ -6151,6 +6154,8 @@ AS_CASE([$FIPS_VERSION],
61516154
AS_IF([test "$ENABLED_LMS" != "yes" &&
61526155
(test "$FIPS_VERSION" != "dev" || test "$enable_lms" != "no")],
61536156
[ENABLED_LMS="yes"])
6157+
# LMS: enable SHA-256/192 and SHAKE256 parameter sets for FIPS v7
6158+
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_LMS_SHA256_192 -DWOLFSSL_LMS_SHAKE256"
61546159
61556160
# SHA-256 DRBG -- cannot be disabled at build time in FIPS mode
61566161
AS_IF([test "$enable_sha256_drbg" = "no"],
@@ -6283,8 +6288,7 @@ AS_CASE([$FIPS_VERSION],
62836288
(test "$FIPS_VERSION" != "dev" || test "$enable_sha512" != "no")],
62846289
[ENABLED_SHA512="yes"; AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SHA512 -DWOLFSSL_SHA384"])
62856290
6286-
# SHA512-224 and SHA512-256 are SHA-2 algorithms not in our FIPS algorithm list
6287-
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NOSHA512_224 -DWOLFSSL_NOSHA512_256"
6291+
# SHA512-224 and SHA512-256 are needed for HashML-DSA (FIPS 204)
62886292
62896293
# Shake128 because we're testing SHAKE256
62906294
AS_IF([test "x$ENABLED_SHAKE128" = "xno" &&

wolfcrypt/benchmark/benchmark.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11485,6 +11485,13 @@ static void bench_lms_sign_verify(enum wc_LmsParm parm, byte* pub)
1148511485
case WC_LMS_PARM_L4_H5_W4:
1148611486
case WC_LMS_PARM_L4_H10_W4:
1148711487
case WC_LMS_PARM_L4_H10_W8:
11488+
case WC_LMS_PARM_L1_H25_W1:
11489+
case WC_LMS_PARM_L1_H25_W2:
11490+
case WC_LMS_PARM_L1_H25_W4:
11491+
case WC_LMS_PARM_L1_H25_W8:
11492+
case WC_LMS_PARM_L1_H10_W1:
11493+
case WC_LMS_PARM_L1_H15_W1:
11494+
case WC_LMS_PARM_L1_H20_W1:
1148811495
#endif
1148911496

1149011497
#ifdef WOLFSSL_LMS_SHA256_192
@@ -11508,6 +11515,57 @@ static void bench_lms_sign_verify(enum wc_LmsParm parm, byte* pub)
1150811515
case WC_LMS_PARM_SHA256_192_L3_H5_W8:
1150911516
case WC_LMS_PARM_SHA256_192_L3_H10_W4:
1151011517
case WC_LMS_PARM_SHA256_192_L4_H5_W8:
11518+
case WC_LMS_PARM_SHA256_192_L1_H25_W1:
11519+
case WC_LMS_PARM_SHA256_192_L1_H25_W2:
11520+
case WC_LMS_PARM_SHA256_192_L1_H25_W4:
11521+
case WC_LMS_PARM_SHA256_192_L1_H25_W8:
11522+
case WC_LMS_PARM_SHA256_192_L1_H10_W1:
11523+
case WC_LMS_PARM_SHA256_192_L1_H15_W1:
11524+
case WC_LMS_PARM_SHA256_192_L1_H20_W1:
11525+
case WC_LMS_PARM_SHA256_192_L1_H15_W8:
11526+
#endif
11527+
11528+
#ifdef WOLFSSL_LMS_SHAKE256
11529+
case WC_LMS_PARM_SHAKE_L1_H5_W1:
11530+
case WC_LMS_PARM_SHAKE_L1_H5_W2:
11531+
case WC_LMS_PARM_SHAKE_L1_H5_W4:
11532+
case WC_LMS_PARM_SHAKE_L1_H5_W8:
11533+
case WC_LMS_PARM_SHAKE_L1_H10_W1:
11534+
case WC_LMS_PARM_SHAKE_L1_H10_W2:
11535+
case WC_LMS_PARM_SHAKE_L1_H10_W4:
11536+
case WC_LMS_PARM_SHAKE_L1_H10_W8:
11537+
case WC_LMS_PARM_SHAKE_L1_H15_W1:
11538+
case WC_LMS_PARM_SHAKE_L1_H15_W2:
11539+
case WC_LMS_PARM_SHAKE_L1_H15_W4:
11540+
case WC_LMS_PARM_SHAKE_L1_H15_W8:
11541+
case WC_LMS_PARM_SHAKE_L1_H20_W1:
11542+
case WC_LMS_PARM_SHAKE_L1_H20_W2:
11543+
case WC_LMS_PARM_SHAKE_L1_H20_W4:
11544+
case WC_LMS_PARM_SHAKE_L1_H20_W8:
11545+
case WC_LMS_PARM_SHAKE_L1_H25_W1:
11546+
case WC_LMS_PARM_SHAKE_L1_H25_W2:
11547+
case WC_LMS_PARM_SHAKE_L1_H25_W4:
11548+
case WC_LMS_PARM_SHAKE_L1_H25_W8:
11549+
case WC_LMS_PARM_SHAKE192_L1_H5_W1:
11550+
case WC_LMS_PARM_SHAKE192_L1_H5_W2:
11551+
case WC_LMS_PARM_SHAKE192_L1_H5_W4:
11552+
case WC_LMS_PARM_SHAKE192_L1_H5_W8:
11553+
case WC_LMS_PARM_SHAKE192_L1_H10_W1:
11554+
case WC_LMS_PARM_SHAKE192_L1_H10_W2:
11555+
case WC_LMS_PARM_SHAKE192_L1_H10_W4:
11556+
case WC_LMS_PARM_SHAKE192_L1_H10_W8:
11557+
case WC_LMS_PARM_SHAKE192_L1_H15_W1:
11558+
case WC_LMS_PARM_SHAKE192_L1_H15_W2:
11559+
case WC_LMS_PARM_SHAKE192_L1_H15_W4:
11560+
case WC_LMS_PARM_SHAKE192_L1_H15_W8:
11561+
case WC_LMS_PARM_SHAKE192_L1_H20_W1:
11562+
case WC_LMS_PARM_SHAKE192_L1_H20_W2:
11563+
case WC_LMS_PARM_SHAKE192_L1_H20_W4:
11564+
case WC_LMS_PARM_SHAKE192_L1_H20_W8:
11565+
case WC_LMS_PARM_SHAKE192_L1_H25_W1:
11566+
case WC_LMS_PARM_SHAKE192_L1_H25_W2:
11567+
case WC_LMS_PARM_SHAKE192_L1_H25_W4:
11568+
case WC_LMS_PARM_SHAKE192_L1_H25_W8:
1151111569
#endif
1151211570

1151311571
default:

wolfcrypt/src/asn.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4252,6 +4252,12 @@ static word32 SetBitString16Bit(word16 val, byte* output)
42524252
#ifndef WOLFSSL_NOSHA3_512
42534253
static const byte hashSha3_512hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 10};
42544254
#endif /* WOLFSSL_NOSHA3_512 */
4255+
#ifdef WOLFSSL_SHAKE128
4256+
static const byte hashShake128hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 11};
4257+
#endif /* WOLFSSL_SHAKE128 */
4258+
#ifdef WOLFSSL_SHAKE256
4259+
static const byte hashShake256hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 12};
4260+
#endif /* WOLFSSL_SHAKE256 */
42554261
#endif /* WOLFSSL_SHA3 */
42564262

42574263
/* hmacType */
@@ -5125,6 +5131,18 @@ const byte* OidFromId(word32 id, word32 type, word32* oidSz)
51255131
*oidSz = sizeof(hashSha3_512hOid);
51265132
break;
51275133
#endif /* WOLFSSL_NOSHA3_512 */
5134+
#ifdef WOLFSSL_SHAKE128
5135+
case SHAKE128h:
5136+
oid = hashShake128hOid;
5137+
*oidSz = sizeof(hashShake128hOid);
5138+
break;
5139+
#endif /* WOLFSSL_SHAKE128 */
5140+
#ifdef WOLFSSL_SHAKE256
5141+
case SHAKE256h:
5142+
oid = hashShake256hOid;
5143+
*oidSz = sizeof(hashShake256hOid);
5144+
break;
5145+
#endif /* WOLFSSL_SHAKE256 */
51285146
#endif /* WOLFSSL_SHA3 */
51295147
default:
51305148
break;

wolfcrypt/src/dh.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,6 +1063,11 @@ static int CheckDhLN(word32 modLen, word32 divLen)
10631063
if (divLen == 224 || divLen == 256)
10641064
ret = 0;
10651065
break;
1066+
/* Per SP 800-56Ar3 Table 2 */
1067+
case 3072:
1068+
if (divLen == 256)
1069+
ret = 0;
1070+
break;
10661071
default:
10671072
break;
10681073
}

wolfcrypt/src/dilithium.c

Lines changed: 101 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,15 @@ static int dilithium_get_hash_oid(int hash, byte* oidBuffer, word32* oidLen)
739739
oid = sha512Oid;
740740
}
741741
else
742+
#ifndef WOLFSSL_NOSHA512_224
743+
if (hash == WC_HASH_TYPE_SHA512_224) {
744+
static byte sha512_224Oid[DILITHIUM_HASH_OID_LEN] = {
745+
0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x05
746+
};
747+
oid = sha512_224Oid;
748+
}
749+
else
750+
#endif
742751
#ifndef WOLFSSL_NOSHA512_256
743752
if (hash == WC_HASH_TYPE_SHA512_256) {
744753
static byte sha512_256Oid[DILITHIUM_HASH_OID_LEN] = {
@@ -9308,7 +9317,7 @@ static void dilithium_make_pub_vec(dilithium_key* key, sword32* t1)
93089317
* @return MEMORY_E when memory allocation fails.
93099318
* @return Other negative when an error occurs.
93109319
*/
9311-
static int dilithium_verify_mu(dilithium_key* key, const byte* mu,
9320+
static int dilithium_verify_with_mu(dilithium_key* key, const byte* mu,
93129321
const byte* sig, word32 sigLen, int* res)
93139322
{
93149323
#ifndef WOLFSSL_DILITHIUM_VERIFY_SMALL_MEM
@@ -9767,7 +9776,7 @@ static int dilithium_verify_ctx_msg(dilithium_key* key, const byte* ctx,
97679776
ctx, (byte)ctxLen, msg, msgLen, mu, DILITHIUM_MU_SZ);
97689777
}
97699778
if (ret == 0) {
9770-
ret = dilithium_verify_mu(key, mu, sig, sigLen, res);
9779+
ret = dilithium_verify_with_mu(key, mu, sig, sigLen, res);
97719780
}
97729781

97739782
return ret;
@@ -9810,7 +9819,7 @@ static int dilithium_verify_msg(dilithium_key* key, const byte* msg,
98109819
mu, DILITHIUM_MU_SZ);
98119820
}
98129821
if (ret == 0) {
9813-
ret = dilithium_verify_mu(key, mu, sig, sigLen, res);
9822+
ret = dilithium_verify_with_mu(key, mu, sig, sigLen, res);
98149823
}
98159824

98169825
return ret;
@@ -9865,7 +9874,7 @@ static int dilithium_verify_ctx_hash(dilithium_key* key, const byte* ctx,
98659874
ctx, (byte)ctxLen, oidMsgHash, oidMsgHashLen, mu, DILITHIUM_MU_SZ);
98669875
}
98679876
if (ret == 0) {
9868-
ret = dilithium_verify_mu(key, mu, sig, sigLen, res);
9877+
ret = dilithium_verify_with_mu(key, mu, sig, sigLen, res);
98699878
}
98709879

98719880
return ret;
@@ -10436,6 +10445,53 @@ int wc_dilithium_sign_ctx_hash_with_seed(const byte* ctx, byte ctxLen,
1043610445

1043710446
return ret;
1043810447
}
10448+
10449+
/* Sign using the ML-DSA internal interface with a pre-computed mu value.
10450+
*
10451+
* This implements ML-DSA.Sign_internal from FIPS 204 Section 6.2.
10452+
* The caller provides mu directly (already computed from tr||M'), bypassing
10453+
* the external message hashing step. Used by ACVP internal interface tests.
10454+
*
10455+
* mu [in] Pre-computed mu value (64 bytes).
10456+
* muLen [in] Length of mu in bytes (must be 64).
10457+
* sig [out] Buffer to write signature into.
10458+
* sigLen [in/out] On in, size of buffer.
10459+
* On out, the length of the signature in bytes.
10460+
* key [in] Dilithium key to use when signing.
10461+
* seed [in] 32-byte random seed (rnd).
10462+
* returns BAD_FUNC_ARG when a parameter is NULL or muLen is not 64,
10463+
* BUFFER_E when sigLen is too small,
10464+
* 0 otherwise.
10465+
*/
10466+
int wc_dilithium_sign_mu_with_seed(const byte* mu, word32 muLen,
10467+
byte* sig, word32 *sigLen, dilithium_key* key, const byte* seed)
10468+
{
10469+
int ret = 0;
10470+
10471+
/* Validate parameters. */
10472+
if ((mu == NULL) || (sig == NULL) || (sigLen == NULL) || (key == NULL) ||
10473+
(seed == NULL)) {
10474+
ret = BAD_FUNC_ARG;
10475+
}
10476+
if ((ret == 0) && (muLen != DILITHIUM_MU_SZ)) {
10477+
ret = BAD_FUNC_ARG;
10478+
}
10479+
10480+
if (ret == 0) {
10481+
#ifdef WOLFSSL_WC_DILITHIUM
10482+
/* Build [seed||mu] buffer and call internal sign function. */
10483+
byte seedMu[DILITHIUM_RND_SZ + DILITHIUM_MU_SZ];
10484+
XMEMCPY(seedMu, seed, DILITHIUM_RND_SZ);
10485+
XMEMCPY(seedMu + DILITHIUM_RND_SZ, mu, DILITHIUM_MU_SZ);
10486+
ret = dilithium_sign_with_seed_mu(key, seedMu, sig, sigLen);
10487+
#elif defined(HAVE_LIBOQS)
10488+
ret = NOT_COMPILED_IN;
10489+
(void)muLen;
10490+
#endif
10491+
}
10492+
10493+
return ret;
10494+
}
1043910495
#endif /* !WOLFSSL_DILITHIUM_NO_SIGN */
1044010496

1044110497
#ifndef WOLFSSL_DILITHIUM_NO_VERIFY
@@ -10611,6 +10667,47 @@ int wc_dilithium_verify_ctx_hash(const byte* sig, word32 sigLen,
1061110667

1061210668
return ret;
1061310669
}
10670+
10671+
/* Verify using the ML-DSA internal interface with a pre-computed mu value.
10672+
*
10673+
* This implements ML-DSA.Verify_internal from FIPS 204 Section 6.3.
10674+
* The caller provides mu directly (already computed from tr||M'), bypassing
10675+
* the external message hashing step. Used by ACVP internal interface tests.
10676+
*
10677+
* sig [in] Signature to verify.
10678+
* sigLen [in] Size of signature in bytes.
10679+
* mu [in] Pre-computed mu value (64 bytes).
10680+
* muLen [in] Length of mu in bytes (must be 64).
10681+
* res [out] *res is set to 1 on successful verification.
10682+
* key [in] Dilithium key to use to verify.
10683+
* returns BAD_FUNC_ARG when a parameter is NULL or muLen is not 64,
10684+
* 0 otherwise.
10685+
*/
10686+
int wc_dilithium_verify_mu(const byte* sig, word32 sigLen, const byte* mu,
10687+
word32 muLen, int* res, dilithium_key* key)
10688+
{
10689+
int ret = 0;
10690+
10691+
/* Validate parameters. */
10692+
if ((key == NULL) || (sig == NULL) || (mu == NULL) || (res == NULL)) {
10693+
ret = BAD_FUNC_ARG;
10694+
}
10695+
if ((ret == 0) && (muLen != DILITHIUM_MU_SZ)) {
10696+
ret = BAD_FUNC_ARG;
10697+
}
10698+
10699+
if (ret == 0) {
10700+
#ifdef WOLFSSL_WC_DILITHIUM
10701+
ret = dilithium_verify_with_mu(key, mu, sig, sigLen, res);
10702+
#elif defined(HAVE_LIBOQS)
10703+
ret = NOT_COMPILED_IN;
10704+
(void)sigLen;
10705+
(void)muLen;
10706+
#endif
10707+
}
10708+
10709+
return ret;
10710+
}
1061410711
#endif /* WOLFSSL_DILITHIUM_NO_VERIFY */
1061510712

1061610713
#ifndef WC_NO_CONSTRUCTORS

0 commit comments

Comments
 (0)