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