@@ -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