Skip to content

Commit 6b8c222

Browse files
committed
New hash modes and features for PQ submission
1 parent e87e09a commit 6b8c222

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
@@ -1972,6 +1972,9 @@ do
19721972
sha256-192)
19731973
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_LMS_SHA256_192"
19741974
;;
1975+
shake256)
1976+
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_LMS_SHAKE256"
1977+
;;
19751978
*)
19761979
AC_MSG_ERROR([Invalid choice for LMS []: $ENABLED_LMS.])
19771980
break;;
@@ -6134,8 +6137,8 @@ AS_CASE([$FIPS_VERSION],
61346137
(test "$FIPS_VERSION" != "dev" || test "$enable_sha512" != "no")],
61356138
[ENABLED_SHA512="yes"; AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SHA512 -DWOLFSSL_SHA384"])
61366139
6137-
# SHA512-224 and SHA512-256 are SHA-2 algorithms not in our FIPS algorithm list
6138-
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NOSHA512_224 -DWOLFSSL_NOSHA512_256"
6140+
# SHA512-224 and SHA512-256 enabled for FIPS v7+ (needed for ML-DSA
6141+
# HashML-DSA ACVP test vectors with SHA2-512/224 and SHA2-512/256)
61396142
61406143
# Shake128 because we're testing SHAKE256
61416144
AS_IF([test "x$ENABLED_SHAKE128" = "xno" &&
@@ -6224,6 +6227,8 @@ AS_CASE([$FIPS_VERSION],
62246227
AS_IF([test "$ENABLED_LMS" != "yes" &&
62256228
(test "$FIPS_VERSION" != "dev" || test "$enable_lms" != "no")],
62266229
[ENABLED_LMS="yes"])
6230+
# LMS: enable SHA-256/192 and SHAKE256 parameter sets for FIPS v7
6231+
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_LMS_SHA256_192 -DWOLFSSL_LMS_SHAKE256"
62276232
62286233
# SHA-256 DRBG -- cannot be disabled at build time in FIPS mode
62296234
AS_IF([test "$enable_sha256_drbg" = "no"],
@@ -6356,8 +6361,7 @@ AS_CASE([$FIPS_VERSION],
63566361
(test "$FIPS_VERSION" != "dev" || test "$enable_sha512" != "no")],
63576362
[ENABLED_SHA512="yes"; AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SHA512 -DWOLFSSL_SHA384"])
63586363
6359-
# SHA512-224 and SHA512-256 are SHA-2 algorithms not in our FIPS algorithm list
6360-
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NOSHA512_224 -DWOLFSSL_NOSHA512_256"
6364+
# SHA512-224 and SHA512-256 are needed for HashML-DSA (FIPS 204)
63616365
63626366
# Shake128 because we're testing SHAKE256
63636367
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
@@ -11546,6 +11546,13 @@ static void bench_lms_sign_verify(enum wc_LmsParm parm, byte* pub)
1154611546
case WC_LMS_PARM_L4_H5_W4:
1154711547
case WC_LMS_PARM_L4_H10_W4:
1154811548
case WC_LMS_PARM_L4_H10_W8:
11549+
case WC_LMS_PARM_L1_H25_W1:
11550+
case WC_LMS_PARM_L1_H25_W2:
11551+
case WC_LMS_PARM_L1_H25_W4:
11552+
case WC_LMS_PARM_L1_H25_W8:
11553+
case WC_LMS_PARM_L1_H10_W1:
11554+
case WC_LMS_PARM_L1_H15_W1:
11555+
case WC_LMS_PARM_L1_H20_W1:
1154911556
#endif
1155011557

1155111558
#ifdef WOLFSSL_LMS_SHA256_192
@@ -11569,6 +11576,57 @@ static void bench_lms_sign_verify(enum wc_LmsParm parm, byte* pub)
1156911576
case WC_LMS_PARM_SHA256_192_L3_H5_W8:
1157011577
case WC_LMS_PARM_SHA256_192_L3_H10_W4:
1157111578
case WC_LMS_PARM_SHA256_192_L4_H5_W8:
11579+
case WC_LMS_PARM_SHA256_192_L1_H25_W1:
11580+
case WC_LMS_PARM_SHA256_192_L1_H25_W2:
11581+
case WC_LMS_PARM_SHA256_192_L1_H25_W4:
11582+
case WC_LMS_PARM_SHA256_192_L1_H25_W8:
11583+
case WC_LMS_PARM_SHA256_192_L1_H10_W1:
11584+
case WC_LMS_PARM_SHA256_192_L1_H15_W1:
11585+
case WC_LMS_PARM_SHA256_192_L1_H20_W1:
11586+
case WC_LMS_PARM_SHA256_192_L1_H15_W8:
11587+
#endif
11588+
11589+
#ifdef WOLFSSL_LMS_SHAKE256
11590+
case WC_LMS_PARM_SHAKE_L1_H5_W1:
11591+
case WC_LMS_PARM_SHAKE_L1_H5_W2:
11592+
case WC_LMS_PARM_SHAKE_L1_H5_W4:
11593+
case WC_LMS_PARM_SHAKE_L1_H5_W8:
11594+
case WC_LMS_PARM_SHAKE_L1_H10_W1:
11595+
case WC_LMS_PARM_SHAKE_L1_H10_W2:
11596+
case WC_LMS_PARM_SHAKE_L1_H10_W4:
11597+
case WC_LMS_PARM_SHAKE_L1_H10_W8:
11598+
case WC_LMS_PARM_SHAKE_L1_H15_W1:
11599+
case WC_LMS_PARM_SHAKE_L1_H15_W2:
11600+
case WC_LMS_PARM_SHAKE_L1_H15_W4:
11601+
case WC_LMS_PARM_SHAKE_L1_H15_W8:
11602+
case WC_LMS_PARM_SHAKE_L1_H20_W1:
11603+
case WC_LMS_PARM_SHAKE_L1_H20_W2:
11604+
case WC_LMS_PARM_SHAKE_L1_H20_W4:
11605+
case WC_LMS_PARM_SHAKE_L1_H20_W8:
11606+
case WC_LMS_PARM_SHAKE_L1_H25_W1:
11607+
case WC_LMS_PARM_SHAKE_L1_H25_W2:
11608+
case WC_LMS_PARM_SHAKE_L1_H25_W4:
11609+
case WC_LMS_PARM_SHAKE_L1_H25_W8:
11610+
case WC_LMS_PARM_SHAKE192_L1_H5_W1:
11611+
case WC_LMS_PARM_SHAKE192_L1_H5_W2:
11612+
case WC_LMS_PARM_SHAKE192_L1_H5_W4:
11613+
case WC_LMS_PARM_SHAKE192_L1_H5_W8:
11614+
case WC_LMS_PARM_SHAKE192_L1_H10_W1:
11615+
case WC_LMS_PARM_SHAKE192_L1_H10_W2:
11616+
case WC_LMS_PARM_SHAKE192_L1_H10_W4:
11617+
case WC_LMS_PARM_SHAKE192_L1_H10_W8:
11618+
case WC_LMS_PARM_SHAKE192_L1_H15_W1:
11619+
case WC_LMS_PARM_SHAKE192_L1_H15_W2:
11620+
case WC_LMS_PARM_SHAKE192_L1_H15_W4:
11621+
case WC_LMS_PARM_SHAKE192_L1_H15_W8:
11622+
case WC_LMS_PARM_SHAKE192_L1_H20_W1:
11623+
case WC_LMS_PARM_SHAKE192_L1_H20_W2:
11624+
case WC_LMS_PARM_SHAKE192_L1_H20_W4:
11625+
case WC_LMS_PARM_SHAKE192_L1_H20_W8:
11626+
case WC_LMS_PARM_SHAKE192_L1_H25_W1:
11627+
case WC_LMS_PARM_SHAKE192_L1_H25_W2:
11628+
case WC_LMS_PARM_SHAKE192_L1_H25_W4:
11629+
case WC_LMS_PARM_SHAKE192_L1_H25_W8:
1157211630
#endif
1157311631

1157411632
default:

wolfcrypt/src/asn.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4279,6 +4279,12 @@ static word32 SetBitString16Bit(word16 val, byte* output)
42794279
#ifndef WOLFSSL_NOSHA3_512
42804280
static const byte hashSha3_512hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 10};
42814281
#endif /* WOLFSSL_NOSHA3_512 */
4282+
#ifdef WOLFSSL_SHAKE128
4283+
static const byte hashShake128hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 11};
4284+
#endif /* WOLFSSL_SHAKE128 */
4285+
#ifdef WOLFSSL_SHAKE256
4286+
static const byte hashShake256hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 12};
4287+
#endif /* WOLFSSL_SHAKE256 */
42824288
#endif /* WOLFSSL_SHA3 */
42834289

42844290
/* hmacType */
@@ -5152,6 +5158,18 @@ const byte* OidFromId(word32 id, word32 type, word32* oidSz)
51525158
*oidSz = sizeof(hashSha3_512hOid);
51535159
break;
51545160
#endif /* WOLFSSL_NOSHA3_512 */
5161+
#ifdef WOLFSSL_SHAKE128
5162+
case SHAKE128h:
5163+
oid = hashShake128hOid;
5164+
*oidSz = sizeof(hashShake128hOid);
5165+
break;
5166+
#endif /* WOLFSSL_SHAKE128 */
5167+
#ifdef WOLFSSL_SHAKE256
5168+
case SHAKE256h:
5169+
oid = hashShake256hOid;
5170+
*oidSz = sizeof(hashShake256hOid);
5171+
break;
5172+
#endif /* WOLFSSL_SHAKE256 */
51555173
#endif /* WOLFSSL_SHA3 */
51565174
default:
51575175
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] = {
@@ -9347,7 +9356,7 @@ static void dilithium_make_pub_vec(dilithium_key* key, sword32* t1)
93479356
* @return MEMORY_E when memory allocation fails.
93489357
* @return Other negative when an error occurs.
93499358
*/
9350-
static int dilithium_verify_mu(dilithium_key* key, const byte* mu,
9359+
static int dilithium_verify_with_mu(dilithium_key* key, const byte* mu,
93519360
const byte* sig, word32 sigLen, int* res)
93529361
{
93539362
#ifndef WOLFSSL_DILITHIUM_VERIFY_SMALL_MEM
@@ -9806,7 +9815,7 @@ static int dilithium_verify_ctx_msg(dilithium_key* key, const byte* ctx,
98069815
ctx, (byte)ctxLen, msg, msgLen, mu, DILITHIUM_MU_SZ);
98079816
}
98089817
if (ret == 0) {
9809-
ret = dilithium_verify_mu(key, mu, sig, sigLen, res);
9818+
ret = dilithium_verify_with_mu(key, mu, sig, sigLen, res);
98109819
}
98119820

98129821
return ret;
@@ -9849,7 +9858,7 @@ static int dilithium_verify_msg(dilithium_key* key, const byte* msg,
98499858
mu, DILITHIUM_MU_SZ);
98509859
}
98519860
if (ret == 0) {
9852-
ret = dilithium_verify_mu(key, mu, sig, sigLen, res);
9861+
ret = dilithium_verify_with_mu(key, mu, sig, sigLen, res);
98539862
}
98549863

98559864
return ret;
@@ -9904,7 +9913,7 @@ static int dilithium_verify_ctx_hash(dilithium_key* key, const byte* ctx,
99049913
ctx, (byte)ctxLen, oidMsgHash, oidMsgHashLen, mu, DILITHIUM_MU_SZ);
99059914
}
99069915
if (ret == 0) {
9907-
ret = dilithium_verify_mu(key, mu, sig, sigLen, res);
9916+
ret = dilithium_verify_with_mu(key, mu, sig, sigLen, res);
99089917
}
99099918

99109919
return ret;
@@ -10475,6 +10484,53 @@ int wc_dilithium_sign_ctx_hash_with_seed(const byte* ctx, byte ctxLen,
1047510484

1047610485
return ret;
1047710486
}
10487+
10488+
/* Sign using the ML-DSA internal interface with a pre-computed mu value.
10489+
*
10490+
* This implements ML-DSA.Sign_internal from FIPS 204 Section 6.2.
10491+
* The caller provides mu directly (already computed from tr||M'), bypassing
10492+
* the external message hashing step. Used by ACVP internal interface tests.
10493+
*
10494+
* mu [in] Pre-computed mu value (64 bytes).
10495+
* muLen [in] Length of mu in bytes (must be 64).
10496+
* sig [out] Buffer to write signature into.
10497+
* sigLen [in/out] On in, size of buffer.
10498+
* On out, the length of the signature in bytes.
10499+
* key [in] Dilithium key to use when signing.
10500+
* seed [in] 32-byte random seed (rnd).
10501+
* returns BAD_FUNC_ARG when a parameter is NULL or muLen is not 64,
10502+
* BUFFER_E when sigLen is too small,
10503+
* 0 otherwise.
10504+
*/
10505+
int wc_dilithium_sign_mu_with_seed(const byte* mu, word32 muLen,
10506+
byte* sig, word32 *sigLen, dilithium_key* key, const byte* seed)
10507+
{
10508+
int ret = 0;
10509+
10510+
/* Validate parameters. */
10511+
if ((mu == NULL) || (sig == NULL) || (sigLen == NULL) || (key == NULL) ||
10512+
(seed == NULL)) {
10513+
ret = BAD_FUNC_ARG;
10514+
}
10515+
if ((ret == 0) && (muLen != DILITHIUM_MU_SZ)) {
10516+
ret = BAD_FUNC_ARG;
10517+
}
10518+
10519+
if (ret == 0) {
10520+
#ifdef WOLFSSL_WC_DILITHIUM
10521+
/* Build [seed||mu] buffer and call internal sign function. */
10522+
byte seedMu[DILITHIUM_RND_SZ + DILITHIUM_MU_SZ];
10523+
XMEMCPY(seedMu, seed, DILITHIUM_RND_SZ);
10524+
XMEMCPY(seedMu + DILITHIUM_RND_SZ, mu, DILITHIUM_MU_SZ);
10525+
ret = dilithium_sign_with_seed_mu(key, seedMu, sig, sigLen);
10526+
#elif defined(HAVE_LIBOQS)
10527+
ret = NOT_COMPILED_IN;
10528+
(void)muLen;
10529+
#endif
10530+
}
10531+
10532+
return ret;
10533+
}
1047810534
#endif /* !WOLFSSL_DILITHIUM_NO_SIGN */
1047910535

1048010536
#ifndef WOLFSSL_DILITHIUM_NO_VERIFY
@@ -10650,6 +10706,47 @@ int wc_dilithium_verify_ctx_hash(const byte* sig, word32 sigLen,
1065010706

1065110707
return ret;
1065210708
}
10709+
10710+
/* Verify using the ML-DSA internal interface with a pre-computed mu value.
10711+
*
10712+
* This implements ML-DSA.Verify_internal from FIPS 204 Section 6.3.
10713+
* The caller provides mu directly (already computed from tr||M'), bypassing
10714+
* the external message hashing step. Used by ACVP internal interface tests.
10715+
*
10716+
* sig [in] Signature to verify.
10717+
* sigLen [in] Size of signature in bytes.
10718+
* mu [in] Pre-computed mu value (64 bytes).
10719+
* muLen [in] Length of mu in bytes (must be 64).
10720+
* res [out] *res is set to 1 on successful verification.
10721+
* key [in] Dilithium key to use to verify.
10722+
* returns BAD_FUNC_ARG when a parameter is NULL or muLen is not 64,
10723+
* 0 otherwise.
10724+
*/
10725+
int wc_dilithium_verify_mu(const byte* sig, word32 sigLen, const byte* mu,
10726+
word32 muLen, int* res, dilithium_key* key)
10727+
{
10728+
int ret = 0;
10729+
10730+
/* Validate parameters. */
10731+
if ((key == NULL) || (sig == NULL) || (mu == NULL) || (res == NULL)) {
10732+
ret = BAD_FUNC_ARG;
10733+
}
10734+
if ((ret == 0) && (muLen != DILITHIUM_MU_SZ)) {
10735+
ret = BAD_FUNC_ARG;
10736+
}
10737+
10738+
if (ret == 0) {
10739+
#ifdef WOLFSSL_WC_DILITHIUM
10740+
ret = dilithium_verify_with_mu(key, mu, sig, sigLen, res);
10741+
#elif defined(HAVE_LIBOQS)
10742+
ret = NOT_COMPILED_IN;
10743+
(void)sigLen;
10744+
(void)muLen;
10745+
#endif
10746+
}
10747+
10748+
return ret;
10749+
}
1065310750
#endif /* WOLFSSL_DILITHIUM_NO_VERIFY */
1065410751

1065510752
#ifndef WC_NO_CONSTRUCTORS

0 commit comments

Comments
 (0)