Skip to content

Conversation

@jakemas
Copy link
Collaborator

@jakemas jakemas commented Nov 18, 2025

Issues:

Resolves #N/A

Description of changes:

When signing/verifying in ML-DSA the caller provides mlen the the length of the message m that is being signed/verified. Currently, we do no validation on the size of mlen when in pre-hash mode (called "external mu" in ML-DSA). Since the pre-hash is the output of a SHAKE256 hash function, it is of fixed size ML_DSA_CRHBYTES. This adds validation to check that, returning -1 if not true to match the case where the context ctx has length too large.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license.

@jakemas jakemas requested a review from a team as a code owner November 18, 2025 19:16
else {
// When external_mu is true, m is expected to be exactly ML_DSA_CRHBYTES
if (mlen != ML_DSA_CRHBYTES) {
return -1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you'll skip the destruction of intermediate values with this.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, great spot, added in 2185013

else {
// When external_mu is true, m is expected to be exactly ML_DSA_CRHBYTES
if (mlen != ML_DSA_CRHBYTES) {
return -1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, great spot, added in 2185013

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

SHAKE_Absorb(&state, tr, ML_DSA_TRBYTES);
SHAKE_Absorb(&state, pre, prelen);
SHAKE_Absorb(&state, m, mlen);
SHAKE_Final(mu, &state, ML_DSA_CRHBYTES);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: call to undeclared function 'SHAKE_Final'; ISO C99 and later do not support implicit function declarations [clang-diagnostic-implicit-function-declaration]

    SHAKE_Final(mu, &state, ML_DSA_CRHBYTES);
    ^
Additional context

crypto/fipsmodule/ml_dsa/ml_dsa_ref/sign.c:204: did you mean 'SHA1_Final'?

    SHAKE_Final(mu, &state, ML_DSA_CRHBYTES);
    ^

include/openssl/sha.h:84: 'SHA1_Final' declared here

OPENSSL_EXPORT int SHA1_Final(uint8_t out[SHA_DIGEST_LENGTH], SHA_CTX *sha);
                   ^

SHAKE_Absorb(&state, tr, ML_DSA_TRBYTES);
SHAKE_Absorb(&state, pre, prelen);
SHAKE_Absorb(&state, m, mlen);
SHAKE_Final(mu, &state, ML_DSA_CRHBYTES);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: use of undeclared identifier 'state' [clang-diagnostic-error]

    SHAKE_Final(mu, &state, ML_DSA_CRHBYTES);
                     ^

@codecov-commenter
Copy link

codecov-commenter commented Nov 18, 2025

Codecov Report

❌ Patch coverage is 75.00000% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 78.24%. Comparing base (60e61bc) to head (f4128f8).

Files with missing lines Patch % Lines
crypto/fipsmodule/ml_dsa/ml_dsa_ref/sign.c 75.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2841      +/-   ##
==========================================
- Coverage   78.24%   78.24%   -0.01%     
==========================================
  Files         683      683              
  Lines      117354   117358       +4     
  Branches    16492    16492              
==========================================
- Hits        91826    91822       -4     
- Misses      24640    24648       +8     
  Partials      888      888              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@manastasova manastasova self-requested a review November 18, 2025 20:18
Copy link
Contributor

@manastasova manastasova left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not checking for the correctness of the length at the beginning of these two functions and, thus, avoid the memory allocations and function calls?

@jakemas
Copy link
Collaborator Author

jakemas commented Nov 18, 2025

Why not checking for the correctness of the length at the beginning of these two functions and, thus, avoid the memory allocations and function calls?

Ahh yeah that could work too, follow the exisiting siglen check with an mlen check... I'm happy with either

  if(siglen != params->bytes) {
    return -1;
  }
  
  if (mlen != ML_DSA_CRHBYTES) {
      return -1;
  }

@manastasova
Copy link
Contributor

I can see it being at the very beginning of the functions (along with the external mu check):

if (external_mu && mlen != ML_DSA_CRHBYTES) {
       return -1;
}

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

polyvecl mat[ML_DSA_K_MAX], s1, y, z;
polyveck t0, s2, w1, w0, h;
ml_dsa_poly cp;
KECCAK1600_CTX state;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: use of undeclared identifier 'KECCAK1600_CTX' [clang-diagnostic-error]

  KECCAK1600_CTX state;
  ^

dkostic
dkostic previously approved these changes Nov 19, 2025
* - int external_mu: indicates input message m is to be processed as mu
*
* Returns 0 (success) or -1 (context string too long)
* Returns 0 (success) or -1 (context string or mlen too long)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or too short? I could not see where the length of context is checked.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed in 5b1c5a5

}

if (external_mu && mlen != ML_DSA_CRHBYTES) {
return -1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alignment here is off

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ty fixed in ff7fbb9

polyveck t1, w1, h;
KECCAK1600_CTX state;

if(siglen != params->bytes) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could add space here if <space> ( ....

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a mix of if's with and without -- for now I can live with this

dkostic
dkostic previously approved these changes Nov 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants