From 94b1074836cef931e43d99cc6f20b2b7a1cc4b72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Frauenschl=C3=A4ger?= Date: Wed, 21 Oct 2026 09:13:33 +0200 Subject: [PATCH] Pair HashML-DSA-65 with SHA-384 in the unit tests wolfSSL master now rejects a HashML-DSA pre-hash weaker than the ML-DSA parameter set (wolfSSL PR #11668, FIPS 204 section 5.4), so ML-DSA-65 with a SHA-256 pre-hash fails with PSA_ERROR_INVALID_ARGUMENT. That broke psa_mldsa_test and psa_sign_context_test on the wolfSSL master CI lane. Switch both ML-DSA-65 cases to SHA-384, which matches the 192-bit parameter set and passes against wolfSSL master and v5.9.4-stable. SHA-256 HashML-DSA stays covered with ML-DSA-44 in psa_mldsa_any_hash_test, psa_mldsa_det_sign_test and psa_copy_key_narrowing_test. --- test/psa_server/psa_mldsa_test.c | 14 +++++++------- test/psa_server/psa_sign_context_test.c | 18 +++++++++--------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/test/psa_server/psa_mldsa_test.c b/test/psa_server/psa_mldsa_test.c index bb5d871..e662548 100644 --- a/test/psa_server/psa_mldsa_test.c +++ b/test/psa_server/psa_mldsa_test.c @@ -27,7 +27,7 @@ * 3. Import public key with bits=0 (inference from length); verify with it * 4. Deterministic vs hedged: same message, deterministic produces identical * signatures, hedged produces different ones - * 5. HashML-DSA(SHA-256): sign_message + verify_message; cross-path + * 5. HashML-DSA(SHA-384): sign_message + verify_message; cross-path * verify_hash (caller-hashes) and sign_hash + verify_message * 6. psa_sign_hash with PSA_ALG_ML_DSA -> PSA_ERROR_INVALID_ARGUMENT * 7. Import seed with bits=0 -> PSA_ERROR_INVALID_ARGUMENT; with bits=192 -> @@ -435,9 +435,9 @@ static int test_deterministic_vs_hedged(void) } /* ------------------------------------------------------------------------- - * Case 5: HashML-DSA(SHA-256): cross-path interop + * Case 5: HashML-DSA(SHA-384): cross-path interop * a) sign_message -> verify_message - * b) psa_hash_compute(SHA-256) -> verify_hash with the same sig + * b) psa_hash_compute(SHA-384) -> verify_hash with the same sig * c) sign_hash -> verify_message * ---------------------------------------------------------------------- */ @@ -448,7 +448,7 @@ static int test_hash_mldsa_interop(void) return 0; #else static const psa_algorithm_t alg = - PSA_ALG_HASH_ML_DSA(PSA_ALG_SHA_256); + PSA_ALG_HASH_ML_DSA(PSA_ALG_SHA_384); static const psa_key_usage_t usage = PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH; @@ -459,7 +459,7 @@ static int test_hash_mldsa_interop(void) uint8_t sig_msg[3309]; /* ML-DSA-65 max sig */ uint8_t sig_hash[3309]; size_t sig_msg_len = 0, sig_hash_len = 0; - uint8_t digest[32]; /* SHA-256 */ + uint8_t digest[PSA_HASH_LENGTH(PSA_ALG_SHA_384)]; size_t digest_len = 0; psa_status_t st; @@ -483,9 +483,9 @@ static int test_hash_mldsa_interop(void) } /* 5b: compute digest, then verify_hash (caller-hashes path) */ - st = psa_hash_compute(PSA_ALG_SHA_256, msg, sizeof(msg) - 1, + st = psa_hash_compute(PSA_ALG_SHA_384, msg, sizeof(msg) - 1, digest, sizeof(digest), &digest_len); - if (check_status(st, "SHA-256 hash_compute for HashML-DSA") != 0) { + if (check_status(st, "SHA-384 hash_compute for HashML-DSA") != 0) { (void)psa_destroy_key(key); return 1; } diff --git a/test/psa_server/psa_sign_context_test.c b/test/psa_server/psa_sign_context_test.c index 9f71d19..c28b8e5 100644 --- a/test/psa_server/psa_sign_context_test.c +++ b/test/psa_server/psa_sign_context_test.c @@ -391,8 +391,8 @@ static int test_overlong_context_rejected(void) /* * Test 6: HashML-DSA — psa_sign_hash_with_context / psa_verify_hash_with_context. - * - Key policy: PSA_ALG_HASH_ML_DSA(PSA_ALG_SHA_256). - * - Compute SHA-256 digest, sign_hash_with_context("abc"). + * - Key policy: PSA_ALG_HASH_ML_DSA(PSA_ALG_SHA_384). + * - Compute SHA-384 digest, sign_hash_with_context("abc"). * - verify_hash_with_context same context → PSA_SUCCESS. * - verify_hash_with_context different context → PSA_ERROR_INVALID_SIGNATURE. */ @@ -403,7 +403,7 @@ static int test_hash_mldsa65_context(void) psa_status_t st; uint8_t sig[MLDSA_65_SIG_SIZE]; size_t sig_len = 0; - uint8_t hash[PSA_HASH_LENGTH(PSA_ALG_SHA_256)]; + uint8_t hash[PSA_HASH_LENGTH(PSA_ALG_SHA_384)]; size_t hash_len = 0; static const uint8_t ctx[] = "abc"; static const uint8_t ctx_other[] = "xyz"; @@ -414,7 +414,7 @@ static int test_hash_mldsa65_context(void) psa_set_key_usage_flags(&attrs, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE); - psa_set_key_algorithm(&attrs, PSA_ALG_HASH_ML_DSA(PSA_ALG_SHA_256)); + psa_set_key_algorithm(&attrs, PSA_ALG_HASH_ML_DSA(PSA_ALG_SHA_384)); st = psa_generate_key(&attrs, &key_id); if (st == PSA_ERROR_NOT_SUPPORTED) { @@ -424,8 +424,8 @@ static int test_hash_mldsa65_context(void) if (expect_status("hash_mldsa65: generate_key", st, PSA_SUCCESS) != 0) return 1; - /* Compute SHA-256 digest of the message */ - st = psa_hash_compute(PSA_ALG_SHA_256, + /* Compute SHA-384 digest of the message */ + st = psa_hash_compute(PSA_ALG_SHA_384, g_msg, sizeof(g_msg) - 1, hash, sizeof(hash), &hash_len); if (expect_status("hash_mldsa65: psa_hash_compute", st, @@ -436,7 +436,7 @@ static int test_hash_mldsa65_context(void) /* Sign hash with context "abc" */ st = psa_sign_hash_with_context(key_id, - PSA_ALG_HASH_ML_DSA(PSA_ALG_SHA_256), + PSA_ALG_HASH_ML_DSA(PSA_ALG_SHA_384), hash, hash_len, ctx, sizeof(ctx) - 1, sig, sizeof(sig), &sig_len); @@ -448,7 +448,7 @@ static int test_hash_mldsa65_context(void) /* Verify same context → OK */ st = psa_verify_hash_with_context(key_id, - PSA_ALG_HASH_ML_DSA(PSA_ALG_SHA_256), + PSA_ALG_HASH_ML_DSA(PSA_ALG_SHA_384), hash, hash_len, ctx, sizeof(ctx) - 1, sig, sig_len); @@ -460,7 +460,7 @@ static int test_hash_mldsa65_context(void) /* Verify different context → INVALID_SIGNATURE */ st = psa_verify_hash_with_context(key_id, - PSA_ALG_HASH_ML_DSA(PSA_ALG_SHA_256), + PSA_ALG_HASH_ML_DSA(PSA_ALG_SHA_384), hash, hash_len, ctx_other, sizeof(ctx_other) - 1, sig, sig_len);