Skip to content

Added PKCS#11 3.2 ML-DSA multiple-part support in lib#867

Open
antoinelochet wants to merge 1 commit intosofthsm:mainfrom
antoinelochet:feature/ml-dsa-multi
Open

Added PKCS#11 3.2 ML-DSA multiple-part support in lib#867
antoinelochet wants to merge 1 commit intosofthsm:mainfrom
antoinelochet:feature/ml-dsa-multi

Conversation

@antoinelochet
Copy link
Copy Markdown
Contributor

@antoinelochet antoinelochet commented Apr 28, 2026

Adds the multiple-part support for ML-DSA.
Follow-up of #809

Summary by CodeRabbit

  • New Features

    • Enabled multipart ML‑DSA signing and verification. Init APIs accept mechanism-specific parameters and now log ML‑DSA context/hedge details when provided.
  • Tests

    • Added multipart ML‑DSA tests for streaming sign/verify flows, including a variant exercising additional context/hedge parameters.

@antoinelochet antoinelochet requested a review from a team as a code owner April 28, 2026 11:30
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 28, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Extended signInit/verifyInit APIs to accept an optional MechanismParam* across asymmetric backends and implemented stateful multipart sign/verify for ML‑DSA in the OSSLMLDSA backend, including buffering, cloning/storing mechanism parameters, and finalization that invokes one‑shot sign/verify over the accumulated message.

Changes

Cohort / File(s) Summary
Core interface
src/lib/crypto/AsymmetricAlgorithm.h, src/lib/crypto/AsymmetricAlgorithm.cpp
Added optional const MechanismParam* mechanismParam = NULL to signInit/verifyInit declarations and definitions.
Botan backends
src/lib/crypto/BotanDH.*, src/lib/crypto/BotanDSA.*, src/lib/crypto/BotanECDH.*, src/lib/crypto/BotanECDSA.*, src/lib/crypto/BotanEDDSA.*, src/lib/crypto/BotanGOST.*, src/lib/crypto/BotanRSA.*
Updated signInit/verifyInit signatures to accept mechanismParam; implementations currently do not use the new parameter.
OpenSSL (non‑MLDSA) backends
src/lib/crypto/OSSLDH.*, src/lib/crypto/OSSLDSA.*, src/lib/crypto/OSSLECDH.*, src/lib/crypto/OSSLECDSA.*, src/lib/crypto/OSSLEDDSA.*, src/lib/crypto/OSSLGOST.*, src/lib/crypto/OSSLRSA.*
Extended signInit/verifyInit signatures to include mechanismParam; code paths unchanged and parameter unused in these files.
ML‑DSA (OSSLMLDSA)
src/lib/crypto/OSSLMLDSA.h, src/lib/crypto/OSSLMLDSA.cpp
Implemented multipart flow: signInit/verifyInit validate & clone mechanismParam into internal storage; signUpdate/verifyUpdate append chunks and delegate updates; signFinal/verifyFinal call one‑shot sign/verify on accumulated message, free params and clear buffer; added state members and logging; added hex debug logging.
SoftHSM glue
src/lib/SoftHSM.cpp
Treats CKM_ML_DSA as allowing multipart ops, passes constructed mechanismParam into crypto signInit/verifyInit, and logs additional context/hedgeType when present.
Tests
src/lib/crypto/test/MLDSATests.h, src/lib/crypto/test/MLDSATests.cpp
Added two multipart ML‑DSA tests (one with HEDGE_PREFERRED context) and minor whitespace normalizations.

Sequence Diagram

sequenceDiagram
    participant App as Application
    participant SoftHSM
    participant OSSL as OSSLMLDSA
    participant Asym as AsymmetricAlgorithm

    App->>SoftHSM: C_SignInit (ML‑DSA, mechanismParam)
    SoftHSM->>OSSL: signInit(privateKey, mech, param, paramLen, mechanismParam)
    OSSL->>Asym: signInit(..., mechanismParam)
    Asym-->>OSSL: ok
    OSSL->>OSSL: clone mechanismParam\ninit message buffer
    OSSL-->>SoftHSM: ok
    SoftHSM-->>App: ok

    App->>SoftHSM: C_SignUpdate(chunk1)
    SoftHSM->>OSSL: signUpdate(chunk1)
    OSSL->>Asym: signUpdate(chunk1)
    Asym-->>OSSL: ok
    OSSL->>OSSL: append chunk1
    OSSL-->>SoftHSM: ok

    App->>SoftHSM: C_SignUpdate(chunk2)
    SoftHSM->>OSSL: signUpdate(chunk2)
    OSSL->>Asym: signUpdate(chunk2)
    Asym-->>OSSL: ok
    OSSL->>OSSL: append chunk2
    OSSL-->>SoftHSM: ok

    App->>SoftHSM: C_SignFinal
    SoftHSM->>OSSL: signFinal()
    OSSL->>OSSL: call one‑shot sign() on accumulated message
    OSSL->>Asym: signFinal()
    Asym-->>OSSL: signature
    OSSL->>OSSL: free mechanismParam\nclear buffer
    OSSL-->>SoftHSM: signature
    SoftHSM-->>App: signature
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • Added ML-DSA support #809 — Overlaps ML‑DSA multipart enablement and MechanismParam passthrough in ML‑DSA init/verify paths.

Suggested labels

enhancement

Suggested reviewers

  • jschlyter
  • bjosv
  • bukka

Poem

🐰 I nibbled bytes in two soft parts,

hopped them into tender arts,
MechanismParam kept snug and warm,
ML‑DSA stitched each little swarm,
A silver signature in my heart.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 43.37% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: adding PKCS#11 3.2 ML-DSA multiple-part support in the library.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/lib/SoftHSM.cpp (1)

5587-5590: ⚠️ Potential issue | 🔴 Critical

Enable multipart verify for CKM_ML_DSA.

Line 5589 still disables multipart mode. That makes C_VerifyUpdate/C_VerifyFinal unusable for ML-DSA, and Line 5780 never calls verifyInit to prepare backend state. The PR’s verify-side multipart path stays effectively off.

[suggested fix]

Patch
 		case CKM_ML_DSA:
 			mechanism = AsymMech::MLDSA;
-			bAllowMultiPartOp = false;
+			bAllowMultiPartOp = true;
 			isMLDSA = true;

Also applies to: 5780-5780

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/SoftHSM.cpp` around lines 5587 - 5590, The ML-DSA branch currently
disables multipart operations (setting bAllowMultiPartOp = false and isMLDSA =
true) which prevents C_VerifyUpdate/C_VerifyFinal and never triggers verifyInit;
change the CKM_ML_DSA handling so multipart is allowed (do not set
bAllowMultiPartOp = false — set it true or omit the false override) while
keeping AsymMech::MLDSA and isMLDSA handling, and ensure the verify-side flow
calls verifyInit when isMLDSA is set so the backend verify state is prepared
(verifyInit must be invoked on the verify path where other mechanisms initialize
multipart verify).
src/lib/crypto/OSSLMLDSA.cpp (1)

55-58: ⚠️ Potential issue | 🟠 Major

Uninitialized mechanismParameters member risks undefined behavior.

Looking at OSSLMLDSA.h (lines 55-58), the mechanismParameters member is not initialized. If signFinal/verifyFinal is called without a prior signInit/verifyInit, or if signInit/verifyInit is called with mechanismParam == NULL, the member remains uninitialized (or stays at its prior value). In signFinal/verifyFinal, delete mechanismParameters will then cause undefined behavior.

Initialize mechanismParameters to nullptr in a constructor or add initialization in signInit/verifyInit before conditionally cloning.

Proposed fix in OSSLMLDSA.h

Add a constructor to initialize members:

class OSSLMLDSA : public AsymmetricAlgorithm
{
public:
	// Constructor
	OSSLMLDSA() : parameters(nullptr), paramLength(0), mechanismParameters(nullptr) {}
	
	// Destructor
	virtual ~OSSLMLDSA() { }
	// ...

Or initialize mechanismParameters = nullptr at the start of signInit/verifyInit before the conditional clone:

 bool OSSLMLDSA::signInit(PrivateKey * privateKey, const AsymMech::Type mechanism,
 						 const void * param /* = NULL */ , const size_t paramLen /* = 0 */,
 					     const MechanismParam* mechanismParam /* = NULL */)
 {
+	mechanismParameters = nullptr;
+
 	if (!AsymmetricAlgorithm::signInit(privateKey, mechanism, param, paramLen))
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/crypto/OSSLMLDSA.cpp` around lines 55 - 58, OSSLMLDSA's
mechanismParameters member is not initialized which can lead to undefined
behavior when delete is called in signFinal/verifyFinal; fix by initializing
mechanismParameters to nullptr (either in a new/default constructor for class
OSSLMLDSA that sets parameters=nullptr, paramLength=0,
mechanismParameters=nullptr, or by explicitly setting mechanismParameters =
nullptr at the start of signInit and verifyInit before any conditional cloning)
so delete is only called on a valid pointer or nullptr.
🧹 Nitpick comments (8)
src/lib/crypto/test/MLDSATests.cpp (1)

455-455: Multipart verify path is not exercised by these new multipart tests.

Both tests currently do multipart sign + one-shot verify. Since this PR adds multipart ML-DSA support, please also cover verifyInit/verifyUpdate/verifyFinal.

🧪 Suggested coverage improvement
-		CPPUNIT_ASSERT(mldsa->verify(kp->getPublicKey(), all, sigMultiPart, AsymMech::MLDSA));
+		CPPUNIT_ASSERT(mldsa->verifyInit(kp->getPublicKey(), AsymMech::MLDSA));
+		CPPUNIT_ASSERT(mldsa->verifyUpdate(dataToSign));
+		CPPUNIT_ASSERT(mldsa->verifyUpdate(dataToSignMultipart));
+		CPPUNIT_ASSERT(mldsa->verifyFinal(sigMultiPart));

For the context test, mirror the same pattern and pass &context as the 5th argument to verifyInit.

Also applies to: 498-498

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/crypto/test/MLDSATests.cpp` at line 455, The tests currently perform
multipart signing but only one-shot verification; update both occurrences (the
existing CPPUNIT_ASSERT(mldsa->verify(..., AsymMech::MLDSA)) checks) to exercise
the multipart verify path by calling mldsa->verifyInit(..., AsymMech::MLDSA,
&context) (pass &context as the 5th argument for the context test), then feed
the same data chunks via mldsa->verifyUpdate(&context, chunk) calls, and finally
call mldsa->verifyFinal(&context, signature) and assert the result is true; do
this for both the non-context and context variants (mirror the sign multipart
pattern) so verifyInit/verifyUpdate/verifyFinal are covered.
src/lib/crypto/BotanDSA.cpp (1)

136-140: Forward mechanismParam into base signInit/verifyInit.

Both methods now take mechanismParam, but delegation still uses the old call shape. Passing it through avoids silent loss of caller-supplied mechanism context.

♻️ Proposed minimal refactor
-bool BotanDSA::signInit(PrivateKey* privateKey, const AsymMech::Type mechanism,
-			const void* param /* = NULL */, const size_t paramLen /* = 0 */,
-		     const MechanismParam* /* mechanismParam */)
+bool BotanDSA::signInit(PrivateKey* privateKey, const AsymMech::Type mechanism,
+			const void* param /* = NULL */, const size_t paramLen /* = 0 */,
+		     const MechanismParam* mechanismParam)
 {
-	if (!AsymmetricAlgorithm::signInit(privateKey, mechanism, param, paramLen))
+	if (!AsymmetricAlgorithm::signInit(privateKey, mechanism, param, paramLen, mechanismParam))
 	{
 		return false;
 	}
@@
-bool BotanDSA::verifyInit(PublicKey* publicKey, const AsymMech::Type mechanism,
-			  const void* param /* = NULL */, const size_t paramLen /* = 0 */,
-		     const MechanismParam* /* mechanismParam */)
+bool BotanDSA::verifyInit(PublicKey* publicKey, const AsymMech::Type mechanism,
+			  const void* param /* = NULL */, const size_t paramLen /* = 0 */,
+		     const MechanismParam* mechanismParam)
 {
-	if (!AsymmetricAlgorithm::verifyInit(publicKey, mechanism, param, paramLen))
+	if (!AsymmetricAlgorithm::verifyInit(publicKey, mechanism, param, paramLen, mechanismParam))
 	{
 		return false;
 	}

Also applies to: 352-356

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/crypto/BotanDSA.cpp` around lines 136 - 140, The delegation to the
base AsymmetricAlgorithm in BotanDSA::signInit (and the corresponding
BotanDSA::verifyInit) currently omits the new mechanismParam argument, causing
caller-supplied mechanism context to be dropped; update the calls to
AsymmetricAlgorithm::signInit and AsymmetricAlgorithm::verifyInit to pass the
mechanismParam (and paramLen if applicable) through so the base methods receive
the new parameter—search for BotanDSA::signInit and BotanDSA::verifyInit and
forward the mechanismParam into their AsymmetricAlgorithm::*init calls.
src/lib/crypto/OSSLGOST.cpp (1)

129-133: Forward mechanismParam to base init to avoid silent parameter drop.

Both init methods accept mechanismParam but currently ignore it when delegating to AsymmetricAlgorithm. Forwarding it keeps the API contract consistent with no behavior change for current GOST flows.

♻️ Proposed minimal refactor
-bool OSSLGOST::signInit(PrivateKey* privateKey, const AsymMech::Type mechanism,
-			const void* param /* = NULL */, const size_t paramLen /* = 0 */,
-		    const MechanismParam* /* mechanismParam */)
+bool OSSLGOST::signInit(PrivateKey* privateKey, const AsymMech::Type mechanism,
+			const void* param /* = NULL */, const size_t paramLen /* = 0 */,
+		    const MechanismParam* mechanismParam)
 {
-	if (!AsymmetricAlgorithm::signInit(privateKey, mechanism, param, paramLen))
+	if (!AsymmetricAlgorithm::signInit(privateKey, mechanism, param, paramLen, mechanismParam))
 	{
 		return false;
 	}
@@
-bool OSSLGOST::verifyInit(PublicKey* publicKey, const AsymMech::Type mechanism,
-			  const void* param /* = NULL */, const size_t paramLen /* = 0 */,
-		      const MechanismParam* /* mechanismParam */)
+bool OSSLGOST::verifyInit(PublicKey* publicKey, const AsymMech::Type mechanism,
+			  const void* param /* = NULL */, const size_t paramLen /* = 0 */,
+		      const MechanismParam* mechanismParam)
 {
-	if (!AsymmetricAlgorithm::verifyInit(publicKey, mechanism, param, paramLen))
+	if (!AsymmetricAlgorithm::verifyInit(publicKey, mechanism, param, paramLen, mechanismParam))
 	{
 		return false;
 	}

Also applies to: 315-320

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/crypto/OSSLGOST.cpp` around lines 129 - 133, The OSSLGOST::signInit
currently calls AsymmetricAlgorithm::signInit without forwarding the
MechanismParam*, causing silent parameter drop; update OSSLGOST::signInit to
pass the mechanismParam through to AsymmetricAlgorithm::signInit (i.e., include
the mechanismParam argument in the call) and make the same change for the
corresponding init method (the verify/init variant around lines 315-320) so both
OSSLGOST::signInit and the verify/init method preserve and forward the
mechanismParam to the base class.
src/lib/crypto/BotanGOST.cpp (1)

64-68: Please forward mechanismParam in both init delegations.

The new argument is accepted but discarded when calling AsymmetricAlgorithm. Forwarding keeps behavior consistent with the widened API surface.

♻️ Proposed minimal refactor
-bool BotanGOST::signInit(PrivateKey* privateKey, const AsymMech::Type mechanism,
-			 const void* param /* = NULL */, const size_t paramLen /* = 0 */,
-		     const MechanismParam* /* mechanismParam */)
+bool BotanGOST::signInit(PrivateKey* privateKey, const AsymMech::Type mechanism,
+			 const void* param /* = NULL */, const size_t paramLen /* = 0 */,
+		     const MechanismParam* mechanismParam)
 {
-	if (!AsymmetricAlgorithm::signInit(privateKey, mechanism, param, paramLen))
+	if (!AsymmetricAlgorithm::signInit(privateKey, mechanism, param, paramLen, mechanismParam))
 	{
 		return false;
 	}
@@
-bool BotanGOST::verifyInit(PublicKey* publicKey, const AsymMech::Type mechanism,
-			   const void* param /* = NULL */, const size_t paramLen /* = 0 */,
-		       const MechanismParam* /* mechanismParam */)
+bool BotanGOST::verifyInit(PublicKey* publicKey, const AsymMech::Type mechanism,
+			   const void* param /* = NULL */, const size_t paramLen /* = 0 */,
+		       const MechanismParam* mechanismParam)
 {
-	if (!AsymmetricAlgorithm::verifyInit(publicKey, mechanism, param, paramLen))
+	if (!AsymmetricAlgorithm::verifyInit(publicKey, mechanism, param, paramLen, mechanismParam))
 	{
 		return false;
 	}

Also applies to: 200-205

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/crypto/BotanGOST.cpp` around lines 64 - 68, The new mechanismParam
argument is accepted but not being forwarded to the base init calls; update
BotanGOST::signInit to pass mechanismParam through to
AsymmetricAlgorithm::signInit (and likewise update the corresponding verify/init
delegation around the other block referenced at lines 200-205) so the
AsymmetricAlgorithm::signInit/verifyInit calls receive the MechanismParam
pointer instead of being discarded; locate the calls to
AsymmetricAlgorithm::signInit and the matching verify/init wrapper in this file
and add mechanismParam as the final argument in those delegations.
src/lib/crypto/OSSLMLDSA.cpp (3)

179-183: Consider validating mechanismParam type before cloning.

In signInit, the code clones mechanismParam without validating its type. However, the one-shot sign() method (lines 65-70) validates that mechanismParam is of type MLDSAMechanismParam before use. If an invalid type is passed to signInit, it will be cloned and stored, but signFinal will fail later when sign() rejects it.

For consistency with the one-shot path and to fail fast, consider validating the type in signInit:

Suggested validation
 	DEBUG_MSG("signInit mechanismParam != NULL: %d", mechanismParam != NULL);
 	
 	if (mechanismParam != NULL) {
+		if (!mechanismParam->isOfType(MLDSAMechanismParam::type))
+		{
+			ERROR_MSG("Invalid mechanism parameter type supplied");
+			ByteString dummy;
+			AsymmetricAlgorithm::signFinal(dummy);
+			return false;
+		}
 		mechanismParameters = mechanismParam->clone();
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/crypto/OSSLMLDSA.cpp` around lines 179 - 183, In signInit, validate
the type of mechanismParam before cloning: if mechanismParam is non-NULL ensure
it is an instance of MLDSAMechanismParam (same check used in the one-shot sign()
path) and reject/return an error if it is not; only then assign
mechanismParameters = mechanismParam->clone(); update signInit to mirror the
one-shot validation so invalid types fail fast instead of being stored for later
failure in signFinal/sign().

373-375: Same type validation issue in verifyInit as in signInit.

The same concern applies here - mechanismParam is cloned without type validation. Consider adding the same validation as suggested for signInit.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/crypto/OSSLMLDSA.cpp` around lines 373 - 375, verifyInit clones
mechanismParam into mechanismParameters without validating its type, mirroring
the same bug from signInit; update verifyInit to perform the same
type-check/validation used in signInit before calling mechanismParam->clone()
(reject or throw if the mechanismParam type is unexpected) so only validated
mechanismParam objects are cloned and assigned to mechanismParameters.

33-33: Debug logging of potentially sensitive data.

The debug messages log the hex representation of data being signed/verified (lines 33, 195, 199, 227-228, 387, 389, 391). While useful for debugging, this could expose sensitive message content in debug logs. Consider whether this level of detail is appropriate for production builds.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/crypto/OSSLMLDSA.cpp` at line 33, The current DEBUG_MSG calls output
full hex of sensitive buffers (e.g., DEBUG_MSG with dataToSign and related debug
lines); remove or guard these prints by either omitting the hex payload in
production (log only length or a hash) or wrapping them behind a strict
sensitive-logging flag/compile-time check; specifically update usages of
DEBUG_MSG in OSSLMLDSA.cpp that print dataToSign, message bytes, or signature
bytes to instead emit non-sensitive metadata (e.g., data length or SHA256
digest) or be conditional on an explicit SENSITIVE_DEBUG enabled flag.
src/lib/crypto/OSSLMLDSA.h (1)

55-58: parameters and paramLength members appear unused.

The parameters (void*) and paramLength (size_t) members declared here are not used anywhere in the OSSLMLDSA.cpp implementation. The multipart flow uses mechanismParameters instead. Consider removing these if they are not needed.

Proposed cleanup
 private:
 	static int OSSL_RANDOM;
 	static int OSSL_DETERMINISTIC;
 	ByteString message;
-	void* parameters;
-	size_t paramLength;
 	const MechanismParam* mechanismParameters;
 };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/crypto/OSSLMLDSA.h` around lines 55 - 58, Remove the unused members
parameters (void*) and paramLength (size_t) from the OSSLMLDSA class/struct
declaration and strip any related handling in the implementation: remove any
constructor/destructor/initializer-list references, allocations, frees, copies,
or assignments for parameters/paramLength in OSSLMLDSA.cpp, and ensure multipart
flow continues to use mechanismParameters (const MechanismParam*) only; rebuild
to confirm no remaining references to these two symbols.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/lib/crypto/OSSLMLDSA.cpp`:
- Around line 387-391: The DEBUG_MSG calls inside the verifyUpdate
implementation currently log "signUpdate"; update those two debug strings to
correctly read "verifyUpdate" so the logs reflect the actual function (locate
the DEBUG_MSG calls that reference originalData and message inside verifyUpdate
and replace "signUpdate" with "verifyUpdate").

In `@src/lib/crypto/test/MLDSATests.cpp`:
- Line 493: The multipart init/verify calls pass the context in the wrong slot:
change the signInit and verifyInit calls (e.g., mldsa->signInit(...) and
mldsa->verifyInit(...)) so the third argument (param) is nullptr and the fourth
argument is the mechanismParam (pass &context there instead of as param),
ensuring AsymMech::MLDSA is invoked with mechanismParam set to &context for the
"with context" tests.
- Around line 488-490: The test leaks a ByteString by allocating it on the heap;
instead create a stack ByteString and pass it to MLDSAMechanismParam to avoid
mallocs and frees (e.g., replace "ByteString* contextBS = new ByteString(...);
MLDSAMechanismParam context = MLDSAMechanismParam(..., *contextBS);" with a
local ByteString variable and construct MLDSAMechanismParam from that local),
ensuring no manual delete is needed and the temporary context bytes are copied
or owned correctly by MLDSAMechanismParam.

In `@src/lib/SoftHSM.cpp`:
- Around line 4522-4523: The DEBUG_MSG is logging arbitrary binary data via %s
(mldsaParam.additionalContext / ckSignAdditionalContext->pContext), which can
read past buffers and leak data; change the log to not print raw bytes—use the
context length (ckSignAdditionalContext->ulContextLen or
mldsaParam.additionalContext.size()) or produce a bounded hex/snippet of the
first N bytes when needed, and update both occurrences (the DEBUG_MSG near
mldsaParam.additionalContext and the other occurrence around lines 5621-5622) to
use the safe form (e.g., "additionalContext.len=%zu" or "additionalContext=%s"
with a prior safe hex-encoding of up to N bytes).

---

Outside diff comments:
In `@src/lib/crypto/OSSLMLDSA.cpp`:
- Around line 55-58: OSSLMLDSA's mechanismParameters member is not initialized
which can lead to undefined behavior when delete is called in
signFinal/verifyFinal; fix by initializing mechanismParameters to nullptr
(either in a new/default constructor for class OSSLMLDSA that sets
parameters=nullptr, paramLength=0, mechanismParameters=nullptr, or by explicitly
setting mechanismParameters = nullptr at the start of signInit and verifyInit
before any conditional cloning) so delete is only called on a valid pointer or
nullptr.

In `@src/lib/SoftHSM.cpp`:
- Around line 5587-5590: The ML-DSA branch currently disables multipart
operations (setting bAllowMultiPartOp = false and isMLDSA = true) which prevents
C_VerifyUpdate/C_VerifyFinal and never triggers verifyInit; change the
CKM_ML_DSA handling so multipart is allowed (do not set bAllowMultiPartOp =
false — set it true or omit the false override) while keeping AsymMech::MLDSA
and isMLDSA handling, and ensure the verify-side flow calls verifyInit when
isMLDSA is set so the backend verify state is prepared (verifyInit must be
invoked on the verify path where other mechanisms initialize multipart verify).

---

Nitpick comments:
In `@src/lib/crypto/BotanDSA.cpp`:
- Around line 136-140: The delegation to the base AsymmetricAlgorithm in
BotanDSA::signInit (and the corresponding BotanDSA::verifyInit) currently omits
the new mechanismParam argument, causing caller-supplied mechanism context to be
dropped; update the calls to AsymmetricAlgorithm::signInit and
AsymmetricAlgorithm::verifyInit to pass the mechanismParam (and paramLen if
applicable) through so the base methods receive the new parameter—search for
BotanDSA::signInit and BotanDSA::verifyInit and forward the mechanismParam into
their AsymmetricAlgorithm::*init calls.

In `@src/lib/crypto/BotanGOST.cpp`:
- Around line 64-68: The new mechanismParam argument is accepted but not being
forwarded to the base init calls; update BotanGOST::signInit to pass
mechanismParam through to AsymmetricAlgorithm::signInit (and likewise update the
corresponding verify/init delegation around the other block referenced at lines
200-205) so the AsymmetricAlgorithm::signInit/verifyInit calls receive the
MechanismParam pointer instead of being discarded; locate the calls to
AsymmetricAlgorithm::signInit and the matching verify/init wrapper in this file
and add mechanismParam as the final argument in those delegations.

In `@src/lib/crypto/OSSLGOST.cpp`:
- Around line 129-133: The OSSLGOST::signInit currently calls
AsymmetricAlgorithm::signInit without forwarding the MechanismParam*, causing
silent parameter drop; update OSSLGOST::signInit to pass the mechanismParam
through to AsymmetricAlgorithm::signInit (i.e., include the mechanismParam
argument in the call) and make the same change for the corresponding init method
(the verify/init variant around lines 315-320) so both OSSLGOST::signInit and
the verify/init method preserve and forward the mechanismParam to the base
class.

In `@src/lib/crypto/OSSLMLDSA.cpp`:
- Around line 179-183: In signInit, validate the type of mechanismParam before
cloning: if mechanismParam is non-NULL ensure it is an instance of
MLDSAMechanismParam (same check used in the one-shot sign() path) and
reject/return an error if it is not; only then assign mechanismParameters =
mechanismParam->clone(); update signInit to mirror the one-shot validation so
invalid types fail fast instead of being stored for later failure in
signFinal/sign().
- Around line 373-375: verifyInit clones mechanismParam into mechanismParameters
without validating its type, mirroring the same bug from signInit; update
verifyInit to perform the same type-check/validation used in signInit before
calling mechanismParam->clone() (reject or throw if the mechanismParam type is
unexpected) so only validated mechanismParam objects are cloned and assigned to
mechanismParameters.
- Line 33: The current DEBUG_MSG calls output full hex of sensitive buffers
(e.g., DEBUG_MSG with dataToSign and related debug lines); remove or guard these
prints by either omitting the hex payload in production (log only length or a
hash) or wrapping them behind a strict sensitive-logging flag/compile-time
check; specifically update usages of DEBUG_MSG in OSSLMLDSA.cpp that print
dataToSign, message bytes, or signature bytes to instead emit non-sensitive
metadata (e.g., data length or SHA256 digest) or be conditional on an explicit
SENSITIVE_DEBUG enabled flag.

In `@src/lib/crypto/OSSLMLDSA.h`:
- Around line 55-58: Remove the unused members parameters (void*) and
paramLength (size_t) from the OSSLMLDSA class/struct declaration and strip any
related handling in the implementation: remove any
constructor/destructor/initializer-list references, allocations, frees, copies,
or assignments for parameters/paramLength in OSSLMLDSA.cpp, and ensure multipart
flow continues to use mechanismParameters (const MechanismParam*) only; rebuild
to confirm no remaining references to these two symbols.

In `@src/lib/crypto/test/MLDSATests.cpp`:
- Line 455: The tests currently perform multipart signing but only one-shot
verification; update both occurrences (the existing
CPPUNIT_ASSERT(mldsa->verify(..., AsymMech::MLDSA)) checks) to exercise the
multipart verify path by calling mldsa->verifyInit(..., AsymMech::MLDSA,
&context) (pass &context as the 5th argument for the context test), then feed
the same data chunks via mldsa->verifyUpdate(&context, chunk) calls, and finally
call mldsa->verifyFinal(&context, signature) and assert the result is true; do
this for both the non-context and context variants (mirror the sign multipart
pattern) so verifyInit/verifyUpdate/verifyFinal are covered.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f678e0b4-76d4-4396-9726-332d611c1bf0

📥 Commits

Reviewing files that changed from the base of the PR and between 6319797 and 9e04028.

📒 Files selected for processing (35)
  • src/lib/SoftHSM.cpp
  • src/lib/crypto/AsymmetricAlgorithm.cpp
  • src/lib/crypto/AsymmetricAlgorithm.h
  • src/lib/crypto/BotanDH.cpp
  • src/lib/crypto/BotanDH.h
  • src/lib/crypto/BotanDSA.cpp
  • src/lib/crypto/BotanDSA.h
  • src/lib/crypto/BotanECDH.cpp
  • src/lib/crypto/BotanECDH.h
  • src/lib/crypto/BotanECDSA.cpp
  • src/lib/crypto/BotanECDSA.h
  • src/lib/crypto/BotanEDDSA.cpp
  • src/lib/crypto/BotanEDDSA.h
  • src/lib/crypto/BotanGOST.cpp
  • src/lib/crypto/BotanGOST.h
  • src/lib/crypto/BotanRSA.cpp
  • src/lib/crypto/BotanRSA.h
  • src/lib/crypto/OSSLDH.cpp
  • src/lib/crypto/OSSLDH.h
  • src/lib/crypto/OSSLDSA.cpp
  • src/lib/crypto/OSSLDSA.h
  • src/lib/crypto/OSSLECDH.cpp
  • src/lib/crypto/OSSLECDH.h
  • src/lib/crypto/OSSLECDSA.cpp
  • src/lib/crypto/OSSLECDSA.h
  • src/lib/crypto/OSSLEDDSA.cpp
  • src/lib/crypto/OSSLEDDSA.h
  • src/lib/crypto/OSSLGOST.cpp
  • src/lib/crypto/OSSLGOST.h
  • src/lib/crypto/OSSLMLDSA.cpp
  • src/lib/crypto/OSSLMLDSA.h
  • src/lib/crypto/OSSLRSA.cpp
  • src/lib/crypto/OSSLRSA.h
  • src/lib/crypto/test/MLDSATests.cpp
  • src/lib/crypto/test/MLDSATests.h

Comment thread src/lib/crypto/OSSLMLDSA.cpp Outdated
Comment thread src/lib/crypto/test/MLDSATests.cpp Outdated
Comment thread src/lib/crypto/test/MLDSATests.cpp Outdated
Comment thread src/lib/SoftHSM.cpp Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lib/SoftHSM.cpp (1)

5587-5590: ⚠️ Potential issue | 🔴 Critical

Enable multipart for CKM_ML_DSA verify too.

Line 5589 still leaves bAllowMultiPartOp disabled, so Line 5780 never calls verifyInit(...). As a result, C_VerifyUpdate/C_VerifyFinal still cannot run for ML-DSA, which leaves half of this PR’s feature unavailable.

Suggested fix
 		case CKM_ML_DSA:
 			mechanism = AsymMech::MLDSA;
-			bAllowMultiPartOp = false;
+			bAllowMultiPartOp = true;
 			isMLDSA = true;

Also applies to: 5780-5780

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/SoftHSM.cpp` around lines 5587 - 5590, The CKM_ML_DSA branch
currently sets isMLDSA = true but leaves bAllowMultiPartOp false, preventing
verifyInit(...) from being called and disabling C_VerifyUpdate/C_VerifyFinal for
ML-DSA; update the CKM_ML_DSA case in the mechanism switch (where CKM_ML_DSA,
mechanism = AsymMech::MLDSA, isMLDSA are set) to set bAllowMultiPartOp = true
(or otherwise enable multipart ops for ML-DSA) so that the later verifyInit(...)
call path is exercised and C_VerifyUpdate/C_VerifyFinal work for ML-DSA.
♻️ Duplicate comments (2)
src/lib/crypto/OSSLMLDSA.cpp (1)

387-391: ⚠️ Potential issue | 🟡 Minor

Debug messages incorrectly say "signUpdate" in verifyUpdate.

The debug messages reference "signUpdate" but this is the verifyUpdate method - a copy-paste error.

Proposed fix
-	DEBUG_MSG("signUpdate originalData %s", originalData.hex_str().c_str());
+	DEBUG_MSG("verifyUpdate originalData %s", originalData.hex_str().c_str());

 	message += originalData;
 	
-	DEBUG_MSG("signUpdate message %s", message.hex_str().c_str());
+	DEBUG_MSG("verifyUpdate message %s", message.hex_str().c_str());

,

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/crypto/OSSLMLDSA.cpp` around lines 387 - 391, The debug lines in
verifyUpdate mistakenly print "signUpdate"; update the DEBUG_MSG calls inside
the verifyUpdate method to reference "verifyUpdate" instead of "signUpdate" so
logs correctly identify the method (look for the DEBUG_MSG calls that log
originalData.hex_str() and message.hex_str() near the verifyUpdate
implementation and update those format strings).
src/lib/crypto/test/MLDSATests.cpp (1)

492-503: ⚠️ Potential issue | 🟠 Major

Memory leak and incorrect mechanismParam argument slot.

Two issues remain from previous review:

  1. Memory leak (Line 493): contextBS is allocated on the heap but never freed.

  2. Context passed to wrong argument (Lines 498, 503): &context is passed as the param argument (3rd position), but the mechanismParam argument (5th position) remains NULL. This test does not actually validate the mechanism context plumbing for multipart operations.

Proposed fix
-		std::string contextStr = std::string("HEDGE_PREFERRED");
-		ByteString* contextBS = new ByteString((const unsigned char*)contextStr.c_str(), contextStr.size());
-
-		MLDSAMechanismParam context = MLDSAMechanismParam(Hedge::Type::HEDGE_PREFERRED, *contextBS);
+		const std::string contextStr("HEDGE_PREFERRED");
+		const ByteString contextBS((const unsigned char*)contextStr.data(), contextStr.size());
+		MLDSAMechanismParam context(Hedge::Type::HEDGE_PREFERRED, contextBS);

 		ByteString sigMultiPart;
-		CPPUNIT_ASSERT(mldsa->signInit(kp->getPrivateKey(), AsymMech::MLDSA, &context, sizeof(context)));
+		CPPUNIT_ASSERT(mldsa->signInit(kp->getPrivateKey(), AsymMech::MLDSA, NULL, 0UL, &context));
 		CPPUNIT_ASSERT(mldsa->signUpdate(dataToSign));
 		CPPUNIT_ASSERT(mldsa->signUpdate(dataToSignMultipart));
 		CPPUNIT_ASSERT(mldsa->signFinal(sigMultiPart));

-		CPPUNIT_ASSERT(mldsa->verify(kp->getPublicKey(), all, sigMultiPart, AsymMech::MLDSA, &context, sizeof(context)));
+		CPPUNIT_ASSERT(mldsa->verify(kp->getPublicKey(), all, sigMultiPart, AsymMech::MLDSA, NULL, 0UL, &context));

Based on learnings: SoftHSM ML‑DSA additional context: avoid transient malloc in SoftHSM::{AsymSignInit, AsymVerifyInit}.
,

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/crypto/test/MLDSATests.cpp` around lines 492 - 503, Free the heap
allocation for contextBS (delete contextBS) after the test finishes to avoid the
memory leak, and pass the MLDSAMechanismParam as the mechanismParam (5th
argument) rather than the param (3rd argument): call
mldsa->signInit(kp->getPrivateKey(), AsymMech::MLDSA, nullptr, 0, &context,
sizeof(context)) (or equivalent API where the 3rd/4th args are param/paramLen
and 5th/6th are mechanismParam/mechanismParamLen), and likewise pass nullptr for
the param and &context for the mechanismParam in mldsa->verify; keep the
MLDSAMechanismParam construction (MLDSAMechanismParam context = ...) and ensure
delete contextBS is executed after sign/verify.
🧹 Nitpick comments (4)
src/lib/crypto/OSSLMLDSA.cpp (4)

396-411: Set mechanismParameters to nullptr after deletion in verifyFinal.

Same concern as signFinal - the pointer should be nullified after deletion.

Suggested fix
 	delete mechanismParameters;
+	mechanismParameters = NULL;
 	message.resize(0);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/crypto/OSSLMLDSA.cpp` around lines 396 - 411, In
OSSLMLDSA::verifyFinal, after deleting the mechanismParameters pointer do not
leave a dangling pointer—set mechanismParameters to nullptr (same fix as in
signFinal): locate OSSLMLDSA::verifyFinal and after the delete
mechanismParameters statement assign mechanismParameters = nullptr so subsequent
checks (e.g., DEBUG_MSG or later logic) won't use a freed pointer.

159-186: Consider resetting mechanismParameters before cloning to prevent leaks.

If signInit is called twice without an intervening signFinal (e.g., in error recovery paths), the previous mechanismParameters would leak.

Suggested defensive fix
 	DEBUG_MSG("signInit mechanismParam != NULL: %d", mechanismParam != NULL);
 	
 	if (mechanismParam != NULL) {
+		delete mechanismParameters;  // safe even if nullptr
 		mechanismParameters = mechanismParam->clone();
+	} else {
+		delete mechanismParameters;
+		mechanismParameters = NULL;
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/crypto/OSSLMLDSA.cpp` around lines 159 - 186, OSSLMLDSA::signInit can
leak the previous mechanismParameters when called a second time because it
clones mechanismParam without clearing the existing member; before cloning,
safely release/reset the existing mechanismParameters (e.g., delete or reset the
smart pointer and set to nullptr) so the old object is freed, then clone
mechanismParam into mechanismParameters; keep the existing early-return/error
paths (like the invalid key branch that calls AsymmetricAlgorithm::signFinal)
unchanged.

204-219: Set mechanismParameters to nullptr after deletion.

After delete mechanismParameters, the pointer is not reset. While unlikely in normal flow, if the object is reused or if there's an error path that leads to another signFinal call, this could cause undefined behavior.

Suggested fix
 	delete mechanismParameters;
+	mechanismParameters = NULL;
 	message.resize(0);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/crypto/OSSLMLDSA.cpp` around lines 204 - 219, In OSSLMLDSA::signFinal
the raw pointer mechanismParameters is deleted but not reset, risking
use-after-free; after the delete mechanismParameters call set
mechanismParameters = nullptr to avoid dangling pointer use (locate in function
OSSLMLDSA::signFinal immediately after the delete), and ensure any subsequent
paths or early returns use the nullptr-checked logic already present.

351-378: Same potential leak concern as signInit.

Similar to signInit, if verifyInit is called twice without an intervening verifyFinal, the previous mechanismParameters would leak.

Suggested defensive fix
 	DEBUG_MSG("verifyInit mechanismParam != NULL: %d", mechanismParam != NULL);

 	if (mechanismParam != NULL) {
+		delete mechanismParameters;
 		mechanismParameters = mechanismParam->clone();
+	} else {
+		delete mechanismParameters;
+		mechanismParameters = NULL;
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/crypto/OSSLMLDSA.cpp` around lines 351 - 378, The verifyInit method
can leak the previous mechanismParameters if verifyInit is called twice; before
assigning mechanismParameters = mechanismParam->clone() check if
mechanismParameters is non-NULL and free it (e.g. delete mechanismParameters;
mechanismParameters = NULL) or call the appropriate cleanup method, then assign
the cloned value; also ensure the same defensive cleanup is applied in signInit
and any other init methods that clone mechanismParameters so repeated inits
don't leak.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/lib/crypto/OSSLMLDSA.h`:
- Around line 55-58: The mechanismParameters member is left uninitialized and
later deleted unconditionally, causing potential double-free/use-after-free; add
an explicit constructor for the OSSLMLDSA class that initializes
mechanismParameters to NULL, ensure signInit and verifyInit set
mechanismParameters only when mechanismParam is non-NULL, and after deleting
mechanismParameters in signFinal and verifyFinal assign mechanismParameters =
NULL to avoid dangling pointers and allow safe reuse of the instance.

---

Outside diff comments:
In `@src/lib/SoftHSM.cpp`:
- Around line 5587-5590: The CKM_ML_DSA branch currently sets isMLDSA = true but
leaves bAllowMultiPartOp false, preventing verifyInit(...) from being called and
disabling C_VerifyUpdate/C_VerifyFinal for ML-DSA; update the CKM_ML_DSA case in
the mechanism switch (where CKM_ML_DSA, mechanism = AsymMech::MLDSA, isMLDSA are
set) to set bAllowMultiPartOp = true (or otherwise enable multipart ops for
ML-DSA) so that the later verifyInit(...) call path is exercised and
C_VerifyUpdate/C_VerifyFinal work for ML-DSA.

---

Duplicate comments:
In `@src/lib/crypto/OSSLMLDSA.cpp`:
- Around line 387-391: The debug lines in verifyUpdate mistakenly print
"signUpdate"; update the DEBUG_MSG calls inside the verifyUpdate method to
reference "verifyUpdate" instead of "signUpdate" so logs correctly identify the
method (look for the DEBUG_MSG calls that log originalData.hex_str() and
message.hex_str() near the verifyUpdate implementation and update those format
strings).

In `@src/lib/crypto/test/MLDSATests.cpp`:
- Around line 492-503: Free the heap allocation for contextBS (delete contextBS)
after the test finishes to avoid the memory leak, and pass the
MLDSAMechanismParam as the mechanismParam (5th argument) rather than the param
(3rd argument): call mldsa->signInit(kp->getPrivateKey(), AsymMech::MLDSA,
nullptr, 0, &context, sizeof(context)) (or equivalent API where the 3rd/4th args
are param/paramLen and 5th/6th are mechanismParam/mechanismParamLen), and
likewise pass nullptr for the param and &context for the mechanismParam in
mldsa->verify; keep the MLDSAMechanismParam construction (MLDSAMechanismParam
context = ...) and ensure delete contextBS is executed after sign/verify.

---

Nitpick comments:
In `@src/lib/crypto/OSSLMLDSA.cpp`:
- Around line 396-411: In OSSLMLDSA::verifyFinal, after deleting the
mechanismParameters pointer do not leave a dangling pointer—set
mechanismParameters to nullptr (same fix as in signFinal): locate
OSSLMLDSA::verifyFinal and after the delete mechanismParameters statement assign
mechanismParameters = nullptr so subsequent checks (e.g., DEBUG_MSG or later
logic) won't use a freed pointer.
- Around line 159-186: OSSLMLDSA::signInit can leak the previous
mechanismParameters when called a second time because it clones mechanismParam
without clearing the existing member; before cloning, safely release/reset the
existing mechanismParameters (e.g., delete or reset the smart pointer and set to
nullptr) so the old object is freed, then clone mechanismParam into
mechanismParameters; keep the existing early-return/error paths (like the
invalid key branch that calls AsymmetricAlgorithm::signFinal) unchanged.
- Around line 204-219: In OSSLMLDSA::signFinal the raw pointer
mechanismParameters is deleted but not reset, risking use-after-free; after the
delete mechanismParameters call set mechanismParameters = nullptr to avoid
dangling pointer use (locate in function OSSLMLDSA::signFinal immediately after
the delete), and ensure any subsequent paths or early returns use the
nullptr-checked logic already present.
- Around line 351-378: The verifyInit method can leak the previous
mechanismParameters if verifyInit is called twice; before assigning
mechanismParameters = mechanismParam->clone() check if mechanismParameters is
non-NULL and free it (e.g. delete mechanismParameters; mechanismParameters =
NULL) or call the appropriate cleanup method, then assign the cloned value; also
ensure the same defensive cleanup is applied in signInit and any other init
methods that clone mechanismParameters so repeated inits don't leak.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2fde95d1-ae0d-4517-a3d7-50917fe99f8b

📥 Commits

Reviewing files that changed from the base of the PR and between 9e04028 and 3740390.

📒 Files selected for processing (35)
  • src/lib/SoftHSM.cpp
  • src/lib/crypto/AsymmetricAlgorithm.cpp
  • src/lib/crypto/AsymmetricAlgorithm.h
  • src/lib/crypto/BotanDH.cpp
  • src/lib/crypto/BotanDH.h
  • src/lib/crypto/BotanDSA.cpp
  • src/lib/crypto/BotanDSA.h
  • src/lib/crypto/BotanECDH.cpp
  • src/lib/crypto/BotanECDH.h
  • src/lib/crypto/BotanECDSA.cpp
  • src/lib/crypto/BotanECDSA.h
  • src/lib/crypto/BotanEDDSA.cpp
  • src/lib/crypto/BotanEDDSA.h
  • src/lib/crypto/BotanGOST.cpp
  • src/lib/crypto/BotanGOST.h
  • src/lib/crypto/BotanRSA.cpp
  • src/lib/crypto/BotanRSA.h
  • src/lib/crypto/OSSLDH.cpp
  • src/lib/crypto/OSSLDH.h
  • src/lib/crypto/OSSLDSA.cpp
  • src/lib/crypto/OSSLDSA.h
  • src/lib/crypto/OSSLECDH.cpp
  • src/lib/crypto/OSSLECDH.h
  • src/lib/crypto/OSSLECDSA.cpp
  • src/lib/crypto/OSSLECDSA.h
  • src/lib/crypto/OSSLEDDSA.cpp
  • src/lib/crypto/OSSLEDDSA.h
  • src/lib/crypto/OSSLGOST.cpp
  • src/lib/crypto/OSSLGOST.h
  • src/lib/crypto/OSSLMLDSA.cpp
  • src/lib/crypto/OSSLMLDSA.h
  • src/lib/crypto/OSSLRSA.cpp
  • src/lib/crypto/OSSLRSA.h
  • src/lib/crypto/test/MLDSATests.cpp
  • src/lib/crypto/test/MLDSATests.h
✅ Files skipped from review due to trivial changes (6)
  • src/lib/crypto/test/MLDSATests.h
  • src/lib/crypto/OSSLRSA.h
  • src/lib/crypto/AsymmetricAlgorithm.cpp
  • src/lib/crypto/BotanGOST.h
  • src/lib/crypto/OSSLGOST.cpp
  • src/lib/crypto/BotanDSA.h
🚧 Files skipped from review as they are similar to previous changes (10)
  • src/lib/crypto/OSSLDSA.cpp
  • src/lib/crypto/BotanECDSA.cpp
  • src/lib/crypto/BotanRSA.h
  • src/lib/crypto/BotanECDSA.h
  • src/lib/crypto/BotanDH.cpp
  • src/lib/crypto/OSSLDSA.h
  • src/lib/crypto/BotanGOST.cpp
  • src/lib/crypto/BotanEDDSA.h
  • src/lib/crypto/OSSLDH.h
  • src/lib/crypto/BotanEDDSA.cpp

Comment thread src/lib/crypto/OSSLMLDSA.h
@antoinelochet antoinelochet force-pushed the feature/ml-dsa-multi branch 2 times, most recently from 05770ac to 759b2b5 Compare April 28, 2026 11:54
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

♻️ Duplicate comments (1)
src/lib/crypto/OSSLMLDSA.h (1)

55-58: ⚠️ Potential issue | 🔴 Critical

Initialize and clear mechanismParameters to prevent invalid delete/use-after-free.

Line [58] introduces raw pointer state with no visible constructor initialization here. With conditional assignment in init paths, finalizers can delete an indeterminate/stale pointer unless lifecycle is explicitly initialized and reset.

🔧 Proposed fix
 class OSSLMLDSA : public AsymmetricAlgorithm
 {
 public:
+	OSSLMLDSA() : parameters(NULL), paramLength(0), mechanismParameters(NULL) { }
 	// Destructor
 	virtual ~OSSLMLDSA() { }
 bool OSSLMLDSA::signFinal(ByteString & signature)
 {
 	...
 	delete mechanismParameters;
+	mechanismParameters = NULL;
 	message.resize(0);
 	...
 }

 bool OSSLMLDSA::verifyFinal(const ByteString & signature)
 {
 	...
 	delete mechanismParameters;
+	mechanismParameters = NULL;
 	message.resize(0);
 	...
 }

Use this read-only check to confirm constructor/init/reset paths:

#!/bin/bash
set -euo pipefail

echo "=== OSSLMLDSA class declaration ==="
sed -n '/class OSSLMLDSA/,/^};/p' src/lib/crypto/OSSLMLDSA.h

echo
echo "=== Constructor and pointer lifecycle usage ==="
rg -n 'OSSLMLDSA::OSSLMLDSA|mechanismParameters|delete mechanismParameters|signInit|verifyInit|signFinal|verifyFinal' src/lib/crypto/OSSLMLDSA.cpp src/lib/crypto/OSSLMLDSA.h -C2
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/crypto/OSSLMLDSA.h` around lines 55 - 58, The member pointer
mechanismParameters in class OSSLMLDSA is not initialized or cleared, risking
use-after-free in destructor/reset paths; update the OSSLMLDSA constructor to
explicitly initialize mechanismParameters to nullptr, ensure any reset/cleanup
routine (and the destructor) checks for non-null before deleting and then sets
mechanismParameters back to nullptr, and audit all users (signInit, verifyInit,
signFinal, verifyFinal) to assign or copy into mechanismParameters only via safe
allocation paths so there is a single clear ownership and lifecycle for
mechanismParameters.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/lib/crypto/OSSLMLDSA.cpp`:
- Line 33: The DEBUG_MSG calls in OSSLMLDSA.cpp are printing full message
payloads (e.g., DEBUG_MSG("sign dataToSign: %s", dataToSign.hex_str().c_str()))
which leaks data and is expensive; replace these full hex-dumps with safe
diagnostics such as logging only the data length and a short deterministic
fingerprint (e.g., SHA-256 or truncated hash) or a redaction marker, and remove
any similar uses that call .hex_str() on message, signature, or multipart
buffers (search for DEBUG_MSG and dataToSign.hex_str(), signature.hex_str(), or
multipart accumulation calls in OSSLMLDSA.cpp). Ensure the log message includes
context (what field it refers to) and the computed fingerprint/length instead of
the raw contents.
- Around line 181-183: The code currently clones mechanismParam into
mechanismParameters but never resets mechanismParameters on init/final, leaving
dangling pointers after delete; update all init paths (where mechanismParam is
handled) to first delete and set mechanismParameters = NULL, then if
mechanismParam != NULL set mechanismParameters = mechanismParam->clone(); and in
all final/cleanup paths ensure you delete mechanismParameters and set it to
NULL; additionally audit signFinal and verifyFinal to treat mechanismParameters
as possibly NULL before use so multipart ops started without a mechanismParam
won’t reuse freed memory.

In `@src/lib/crypto/test/MLDSATests.cpp`:
- Around line 429-465: The test MLDSATests::testSigningMultiPartVerifying signs
data in multipart but only exercises the one-shot verify(kp->getPublicKey(),
all, sigMultiPart, AsymMech::MLDSA) path; add calls to
mldsa->verifyInit(kp->getPublicKey(), AsymMech::MLDSA), mldsa->verifyUpdate(...)
for each chunk (dataToSign and dataToSignMultipart) and
mldsa->verifyFinal(sigMultiPart) and assert the final verify result to cover the
multipart verify code path; locate these changes around the end of
testSigningMultiPartVerifying where sigMultiPart, all and kp are available and
replace or augment the existing one-shot verify assertion with the multipart
verifyInit/verifyUpdate/verifyFinal sequence.

---

Duplicate comments:
In `@src/lib/crypto/OSSLMLDSA.h`:
- Around line 55-58: The member pointer mechanismParameters in class OSSLMLDSA
is not initialized or cleared, risking use-after-free in destructor/reset paths;
update the OSSLMLDSA constructor to explicitly initialize mechanismParameters to
nullptr, ensure any reset/cleanup routine (and the destructor) checks for
non-null before deleting and then sets mechanismParameters back to nullptr, and
audit all users (signInit, verifyInit, signFinal, verifyFinal) to assign or copy
into mechanismParameters only via safe allocation paths so there is a single
clear ownership and lifecycle for mechanismParameters.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 04c675c6-6346-42ff-b1e4-5233ab0864cd

📥 Commits

Reviewing files that changed from the base of the PR and between 3740390 and 05770ac.

📒 Files selected for processing (35)
  • src/lib/SoftHSM.cpp
  • src/lib/crypto/AsymmetricAlgorithm.cpp
  • src/lib/crypto/AsymmetricAlgorithm.h
  • src/lib/crypto/BotanDH.cpp
  • src/lib/crypto/BotanDH.h
  • src/lib/crypto/BotanDSA.cpp
  • src/lib/crypto/BotanDSA.h
  • src/lib/crypto/BotanECDH.cpp
  • src/lib/crypto/BotanECDH.h
  • src/lib/crypto/BotanECDSA.cpp
  • src/lib/crypto/BotanECDSA.h
  • src/lib/crypto/BotanEDDSA.cpp
  • src/lib/crypto/BotanEDDSA.h
  • src/lib/crypto/BotanGOST.cpp
  • src/lib/crypto/BotanGOST.h
  • src/lib/crypto/BotanRSA.cpp
  • src/lib/crypto/BotanRSA.h
  • src/lib/crypto/OSSLDH.cpp
  • src/lib/crypto/OSSLDH.h
  • src/lib/crypto/OSSLDSA.cpp
  • src/lib/crypto/OSSLDSA.h
  • src/lib/crypto/OSSLECDH.cpp
  • src/lib/crypto/OSSLECDH.h
  • src/lib/crypto/OSSLECDSA.cpp
  • src/lib/crypto/OSSLECDSA.h
  • src/lib/crypto/OSSLEDDSA.cpp
  • src/lib/crypto/OSSLEDDSA.h
  • src/lib/crypto/OSSLGOST.cpp
  • src/lib/crypto/OSSLGOST.h
  • src/lib/crypto/OSSLMLDSA.cpp
  • src/lib/crypto/OSSLMLDSA.h
  • src/lib/crypto/OSSLRSA.cpp
  • src/lib/crypto/OSSLRSA.h
  • src/lib/crypto/test/MLDSATests.cpp
  • src/lib/crypto/test/MLDSATests.h
✅ Files skipped from review due to trivial changes (8)
  • src/lib/crypto/OSSLECDH.h
  • src/lib/crypto/BotanECDH.h
  • src/lib/crypto/BotanGOST.cpp
  • src/lib/crypto/OSSLDH.h
  • src/lib/crypto/AsymmetricAlgorithm.h
  • src/lib/crypto/OSSLGOST.h
  • src/lib/crypto/BotanDH.cpp
  • src/lib/crypto/BotanDH.h
🚧 Files skipped from review as they are similar to previous changes (10)
  • src/lib/crypto/test/MLDSATests.h
  • src/lib/crypto/BotanECDH.cpp
  • src/lib/crypto/OSSLEDDSA.h
  • src/lib/crypto/OSSLRSA.h
  • src/lib/crypto/BotanDSA.cpp
  • src/lib/crypto/BotanDSA.h
  • src/lib/crypto/OSSLRSA.cpp
  • src/lib/crypto/OSSLDSA.h
  • src/lib/crypto/OSSLDH.cpp
  • src/lib/SoftHSM.cpp

Comment thread src/lib/crypto/OSSLMLDSA.cpp
Comment thread src/lib/crypto/OSSLMLDSA.cpp Outdated
Comment thread src/lib/crypto/test/MLDSATests.cpp
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lib/SoftHSM.cpp (1)

5587-5590: ⚠️ Potential issue | 🔴 Critical

Enable multipart verify for CKM_ML_DSA.

Line 5589 still sets bAllowMultiPartOp to false, so Line 5780 never calls verifyInit(...) and the session is marked single-part only. C_VerifyUpdate/C_VerifyFinal will therefore reject ML-DSA, which breaks the feature this PR is adding.

🔧 Minimal fix
 		case CKM_ML_DSA:
 			mechanism = AsymMech::MLDSA;
-			bAllowMultiPartOp = false;
+			bAllowMultiPartOp = true;
 			isMLDSA = true;

Also applies to: 5779-5794

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/SoftHSM.cpp` around lines 5587 - 5590, In the CKM_ML_DSA case in the
switch (where mechanism is set to AsymMech::MLDSA and isMLDSA is set), change
the multipart allowance so bAllowMultiPartOp is true (instead of false) so the
code path will call verifyInit(...) later and the session will be treated as
multipart; this ensures C_VerifyUpdate/C_VerifyFinal accept ML-DSA. Verify the
same multipart flag logic around the verifyInit(...) call (lines that reference
verifyInit, C_VerifyUpdate, C_VerifyFinal and isMLDSA) is consistent so ML-DSA
sessions are not forced single-part.
♻️ Duplicate comments (1)
src/lib/crypto/test/MLDSATests.cpp (1)

460-460: ⚠️ Potential issue | 🟠 Major

Use multipart verify API in these multipart tests.

Line [460] and Line [503] still verify with one-shot verify(...), so the new multipart verify flow is not exercised by these tests.

✅ Proposed test update
-		CPPUNIT_ASSERT(mldsa->verify(kp->getPublicKey(), all, sigMultiPart, AsymMech::MLDSA));
+		CPPUNIT_ASSERT(mldsa->verifyInit(kp->getPublicKey(), AsymMech::MLDSA));
+		CPPUNIT_ASSERT(mldsa->verifyUpdate(dataToSign));
+		CPPUNIT_ASSERT(mldsa->verifyUpdate(dataToSignMultipart));
+		CPPUNIT_ASSERT(mldsa->verifyFinal(sigMultiPart));
-		CPPUNIT_ASSERT(mldsa->verify(kp->getPublicKey(), all, sigMultiPart, AsymMech::MLDSA, NULL, 0, &context));
+		CPPUNIT_ASSERT(mldsa->verifyInit(kp->getPublicKey(), AsymMech::MLDSA, NULL, 0, &context));
+		CPPUNIT_ASSERT(mldsa->verifyUpdate(dataToSign));
+		CPPUNIT_ASSERT(mldsa->verifyUpdate(dataToSignMultipart));
+		CPPUNIT_ASSERT(mldsa->verifyFinal(sigMultiPart));

Also applies to: 503-503

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/crypto/test/MLDSATests.cpp` at line 460, Tests still call the
one-shot verify(...) in multipart tests; replace those calls with the multipart
verify flow: call mldsa->verifyInit(kp->getPublicKey(), AsymMech::MLDSA) (or the
library's multipart-start API), feed each message chunk used to build
sigMultiPart via mldsa->verifyUpdate(...) in the same order (e.g. the pieces
that produced sigMultiPart instead of "all"), then finish with
mldsa->verifyFinal(sigMultiPart) (or verifyFinish/verifyComplete) and assert the
final result. Update the assertions that currently call
mldsa->verify(kp->getPublicKey(), all, sigMultiPart, AsymMech::MLDSA) to use the
init/update/final sequence so the multipart verify path is exercised (refer to
mldsa, kp->getPublicKey(), sigMultiPart, and the
verifyInit/verifyUpdate/verifyFinal methods).
🧹 Nitpick comments (1)
src/lib/crypto/OSSLMLDSA.h (1)

18-19: Initialize all newly added state members in the constructor.

parameters and paramLength are declared as persistent state but not explicitly initialized. Even if not used yet, initializing them avoids accidental UB in future paths.

💡 Suggested tweak
-	OSSLMLDSA() : mechanismParameters(NULL) { }
+	OSSLMLDSA() : parameters(NULL), paramLength(0), mechanismParameters(NULL) { }
Based on learnings: In C++11-compatible code, prefer explicit constructor/value initialization over relying on implicit defaults for class members.

Also applies to: 57-60

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/crypto/OSSLMLDSA.h` around lines 18 - 19, The constructor OSSLMLDSA()
currently only initializes mechanismParameters; explicitly initialize the newly
added persistent members parameters and paramLength in that constructor (and any
other constructors or initializers in the class) to safe defaults (e.g.,
parameters = nullptr and paramLength = 0) to avoid undefined behavior; update
OSSLMLDSA() and any other ctor or member initializer blocks that touch
parameters/paramLength to set these members alongside mechanismParameters.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/lib/crypto/OSSLMLDSA.cpp`:
- Around line 181-186: When detecting an invalid mechanism parameter type (the
check against MLDSAMechanismParam::type for variable mechanismParam), call the
asymmetric-operation finalizer to clear the operation state before returning
false — e.g. invoke AsymmetricAlgorithm::Final(...) (pass the current operation
handle/context member used by the class and ignore its return) so the init
failure does not leave the operation active; apply the same change to both
places where this check returns false (the mechanismParam checks around the two
reported blocks).

---

Outside diff comments:
In `@src/lib/SoftHSM.cpp`:
- Around line 5587-5590: In the CKM_ML_DSA case in the switch (where mechanism
is set to AsymMech::MLDSA and isMLDSA is set), change the multipart allowance so
bAllowMultiPartOp is true (instead of false) so the code path will call
verifyInit(...) later and the session will be treated as multipart; this ensures
C_VerifyUpdate/C_VerifyFinal accept ML-DSA. Verify the same multipart flag logic
around the verifyInit(...) call (lines that reference verifyInit,
C_VerifyUpdate, C_VerifyFinal and isMLDSA) is consistent so ML-DSA sessions are
not forced single-part.

---

Duplicate comments:
In `@src/lib/crypto/test/MLDSATests.cpp`:
- Line 460: Tests still call the one-shot verify(...) in multipart tests;
replace those calls with the multipart verify flow: call
mldsa->verifyInit(kp->getPublicKey(), AsymMech::MLDSA) (or the library's
multipart-start API), feed each message chunk used to build sigMultiPart via
mldsa->verifyUpdate(...) in the same order (e.g. the pieces that produced
sigMultiPart instead of "all"), then finish with
mldsa->verifyFinal(sigMultiPart) (or verifyFinish/verifyComplete) and assert the
final result. Update the assertions that currently call
mldsa->verify(kp->getPublicKey(), all, sigMultiPart, AsymMech::MLDSA) to use the
init/update/final sequence so the multipart verify path is exercised (refer to
mldsa, kp->getPublicKey(), sigMultiPart, and the
verifyInit/verifyUpdate/verifyFinal methods).

---

Nitpick comments:
In `@src/lib/crypto/OSSLMLDSA.h`:
- Around line 18-19: The constructor OSSLMLDSA() currently only initializes
mechanismParameters; explicitly initialize the newly added persistent members
parameters and paramLength in that constructor (and any other constructors or
initializers in the class) to safe defaults (e.g., parameters = nullptr and
paramLength = 0) to avoid undefined behavior; update OSSLMLDSA() and any other
ctor or member initializer blocks that touch parameters/paramLength to set these
members alongside mechanismParameters.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 095bc2f8-f4d3-4c99-9546-5bc71f87bebb

📥 Commits

Reviewing files that changed from the base of the PR and between 05770ac and 759b2b5.

📒 Files selected for processing (35)
  • src/lib/SoftHSM.cpp
  • src/lib/crypto/AsymmetricAlgorithm.cpp
  • src/lib/crypto/AsymmetricAlgorithm.h
  • src/lib/crypto/BotanDH.cpp
  • src/lib/crypto/BotanDH.h
  • src/lib/crypto/BotanDSA.cpp
  • src/lib/crypto/BotanDSA.h
  • src/lib/crypto/BotanECDH.cpp
  • src/lib/crypto/BotanECDH.h
  • src/lib/crypto/BotanECDSA.cpp
  • src/lib/crypto/BotanECDSA.h
  • src/lib/crypto/BotanEDDSA.cpp
  • src/lib/crypto/BotanEDDSA.h
  • src/lib/crypto/BotanGOST.cpp
  • src/lib/crypto/BotanGOST.h
  • src/lib/crypto/BotanRSA.cpp
  • src/lib/crypto/BotanRSA.h
  • src/lib/crypto/OSSLDH.cpp
  • src/lib/crypto/OSSLDH.h
  • src/lib/crypto/OSSLDSA.cpp
  • src/lib/crypto/OSSLDSA.h
  • src/lib/crypto/OSSLECDH.cpp
  • src/lib/crypto/OSSLECDH.h
  • src/lib/crypto/OSSLECDSA.cpp
  • src/lib/crypto/OSSLECDSA.h
  • src/lib/crypto/OSSLEDDSA.cpp
  • src/lib/crypto/OSSLEDDSA.h
  • src/lib/crypto/OSSLGOST.cpp
  • src/lib/crypto/OSSLGOST.h
  • src/lib/crypto/OSSLMLDSA.cpp
  • src/lib/crypto/OSSLMLDSA.h
  • src/lib/crypto/OSSLRSA.cpp
  • src/lib/crypto/OSSLRSA.h
  • src/lib/crypto/test/MLDSATests.cpp
  • src/lib/crypto/test/MLDSATests.h
✅ Files skipped from review due to trivial changes (11)
  • src/lib/crypto/BotanECDSA.h
  • src/lib/crypto/BotanDH.cpp
  • src/lib/crypto/BotanRSA.h
  • src/lib/crypto/BotanGOST.cpp
  • src/lib/crypto/OSSLECDSA.cpp
  • src/lib/crypto/OSSLECDH.h
  • src/lib/crypto/BotanRSA.cpp
  • src/lib/crypto/BotanECDH.cpp
  • src/lib/crypto/BotanDH.h
  • src/lib/crypto/BotanECDH.h
  • src/lib/crypto/BotanDSA.h
🚧 Files skipped from review as they are similar to previous changes (9)
  • src/lib/crypto/test/MLDSATests.h
  • src/lib/crypto/OSSLECDH.cpp
  • src/lib/crypto/AsymmetricAlgorithm.cpp
  • src/lib/crypto/BotanGOST.h
  • src/lib/crypto/BotanEDDSA.h
  • src/lib/crypto/OSSLRSA.cpp
  • src/lib/crypto/OSSLDH.h
  • src/lib/crypto/OSSLRSA.h
  • src/lib/crypto/OSSLDSA.h

Comment thread src/lib/crypto/OSSLMLDSA.cpp
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lib/SoftHSM.cpp (1)

5587-5625: ⚠️ Potential issue | 🔴 Critical

Enable multipart verification for CKM_ML_DSA.

bAllowMultiPartOp is still false here. That leaves C_VerifyUpdate/C_VerifyFinal unavailable for ML-DSA and also skips the new verifyInit(..., mechanismParam) path at Line 5780, so the PR only enables multipart signing.

Suggested fix
 		case CKM_ML_DSA:
 			mechanism = AsymMech::MLDSA;
-			bAllowMultiPartOp = false;
+			bAllowMultiPartOp = true;
 			isMLDSA = true;

Also applies to: 5779-5780

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/SoftHSM.cpp` around lines 5587 - 5625, The CKM_ML_DSA case currently
sets bAllowMultiPartOp = false which prevents C_VerifyUpdate/C_VerifyFinal and
skips the verifyInit(..., mechanismParam) multipart verification path; change
the logic in the CKM_ML_DSA branch (where isMLDSA is set and mechanismParam =
&mldsaParam) to set bAllowMultiPartOp = true so multipart verification is
allowed for ML-DSA, ensuring the same mechanismParam (mldsaParam) is passed into
the verifyInit(...) path (the new verifyInit call referenced around
verifyInit(..., mechanismParam)); keep existing parameter validation and
mldsaParam population unchanged.
♻️ Duplicate comments (1)
src/lib/crypto/test/MLDSATests.cpp (1)

455-460: ⚠️ Potential issue | 🟠 Major

Exercise multipart verify here as well.

Both new tests still finish with one-shot verify(...), so verifyInit/verifyUpdate/verifyFinal remains untested. Please switch the final assertions to the streaming verify flow.

🔧 Suggested update
-		CPPUNIT_ASSERT(mldsa->verify(kp->getPublicKey(), all, sigMultiPart, AsymMech::MLDSA));
+		CPPUNIT_ASSERT(mldsa->verifyInit(kp->getPublicKey(), AsymMech::MLDSA));
+		CPPUNIT_ASSERT(mldsa->verifyUpdate(dataToSign));
+		CPPUNIT_ASSERT(mldsa->verifyUpdate(dataToSignMultipart));
+		CPPUNIT_ASSERT(mldsa->verifyFinal(sigMultiPart));
-		CPPUNIT_ASSERT(mldsa->verify(kp->getPublicKey(), all, sigMultiPart, AsymMech::MLDSA, NULL, 0, &context));
+		CPPUNIT_ASSERT(mldsa->verifyInit(kp->getPublicKey(), AsymMech::MLDSA, NULL, 0, &context));
+		CPPUNIT_ASSERT(mldsa->verifyUpdate(dataToSign));
+		CPPUNIT_ASSERT(mldsa->verifyUpdate(dataToSignMultipart));
+		CPPUNIT_ASSERT(mldsa->verifyFinal(sigMultiPart));

Also applies to: 498-503

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/crypto/test/MLDSATests.cpp` around lines 455 - 460, The test
currently exercises multipart signing via mldsa->signInit/signUpdate/signFinal
but still calls the one-shot mldsa->verify(...) at the end; replace that final
one-shot verify with the streaming verify flow by calling
mldsa->verifyInit(kp->getPublicKey(), AsymMech::MLDSA), then feed the same
chunks with mldsa->verifyUpdate(dataToSign) and
mldsa->verifyUpdate(dataToSignMultipart) (or their equivalents), and finish with
mldsa->verifyFinal(all, sigMultiPart) to assert the multipart verification
succeeds; do the same replacement in the other occurrence around lines 498-503.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/lib/crypto/OSSLMLDSA.h`:
- Line 18: The OSSLMLDSA() constructor currently only initializes
mechanismParameters leaving members parameters and paramLength uninitialized;
update the OSSLMLDSA() constructor in class OSSLMLDSA to explicitly initialize
message (if present), set parameters to NULL (or nullptr) and paramLength to 0
alongside mechanismParameters to ensure defined state (e.g. initialize
message(), parameters(NULL), paramLength(0), mechanismParameters(NULL)).

---

Outside diff comments:
In `@src/lib/SoftHSM.cpp`:
- Around line 5587-5625: The CKM_ML_DSA case currently sets bAllowMultiPartOp =
false which prevents C_VerifyUpdate/C_VerifyFinal and skips the verifyInit(...,
mechanismParam) multipart verification path; change the logic in the CKM_ML_DSA
branch (where isMLDSA is set and mechanismParam = &mldsaParam) to set
bAllowMultiPartOp = true so multipart verification is allowed for ML-DSA,
ensuring the same mechanismParam (mldsaParam) is passed into the verifyInit(...)
path (the new verifyInit call referenced around verifyInit(...,
mechanismParam)); keep existing parameter validation and mldsaParam population
unchanged.

---

Duplicate comments:
In `@src/lib/crypto/test/MLDSATests.cpp`:
- Around line 455-460: The test currently exercises multipart signing via
mldsa->signInit/signUpdate/signFinal but still calls the one-shot
mldsa->verify(...) at the end; replace that final one-shot verify with the
streaming verify flow by calling mldsa->verifyInit(kp->getPublicKey(),
AsymMech::MLDSA), then feed the same chunks with mldsa->verifyUpdate(dataToSign)
and mldsa->verifyUpdate(dataToSignMultipart) (or their equivalents), and finish
with mldsa->verifyFinal(all, sigMultiPart) to assert the multipart verification
succeeds; do the same replacement in the other occurrence around lines 498-503.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9b93a7e2-7a90-43dd-b23e-c0b2d3e2c0ca

📥 Commits

Reviewing files that changed from the base of the PR and between 759b2b5 and 63e5433.

📒 Files selected for processing (35)
  • src/lib/SoftHSM.cpp
  • src/lib/crypto/AsymmetricAlgorithm.cpp
  • src/lib/crypto/AsymmetricAlgorithm.h
  • src/lib/crypto/BotanDH.cpp
  • src/lib/crypto/BotanDH.h
  • src/lib/crypto/BotanDSA.cpp
  • src/lib/crypto/BotanDSA.h
  • src/lib/crypto/BotanECDH.cpp
  • src/lib/crypto/BotanECDH.h
  • src/lib/crypto/BotanECDSA.cpp
  • src/lib/crypto/BotanECDSA.h
  • src/lib/crypto/BotanEDDSA.cpp
  • src/lib/crypto/BotanEDDSA.h
  • src/lib/crypto/BotanGOST.cpp
  • src/lib/crypto/BotanGOST.h
  • src/lib/crypto/BotanRSA.cpp
  • src/lib/crypto/BotanRSA.h
  • src/lib/crypto/OSSLDH.cpp
  • src/lib/crypto/OSSLDH.h
  • src/lib/crypto/OSSLDSA.cpp
  • src/lib/crypto/OSSLDSA.h
  • src/lib/crypto/OSSLECDH.cpp
  • src/lib/crypto/OSSLECDH.h
  • src/lib/crypto/OSSLECDSA.cpp
  • src/lib/crypto/OSSLECDSA.h
  • src/lib/crypto/OSSLEDDSA.cpp
  • src/lib/crypto/OSSLEDDSA.h
  • src/lib/crypto/OSSLGOST.cpp
  • src/lib/crypto/OSSLGOST.h
  • src/lib/crypto/OSSLMLDSA.cpp
  • src/lib/crypto/OSSLMLDSA.h
  • src/lib/crypto/OSSLRSA.cpp
  • src/lib/crypto/OSSLRSA.h
  • src/lib/crypto/test/MLDSATests.cpp
  • src/lib/crypto/test/MLDSATests.h
✅ Files skipped from review due to trivial changes (5)
  • src/lib/crypto/BotanGOST.h
  • src/lib/crypto/BotanRSA.h
  • src/lib/crypto/BotanECDH.h
  • src/lib/crypto/OSSLRSA.cpp
  • src/lib/crypto/BotanDSA.cpp
🚧 Files skipped from review as they are similar to previous changes (8)
  • src/lib/crypto/OSSLRSA.h
  • src/lib/crypto/OSSLDH.h
  • src/lib/crypto/OSSLDH.cpp
  • src/lib/crypto/AsymmetricAlgorithm.h
  • src/lib/crypto/OSSLEDDSA.cpp
  • src/lib/crypto/OSSLDSA.h
  • src/lib/crypto/OSSLMLDSA.cpp
  • src/lib/crypto/BotanEDDSA.h

Comment thread src/lib/crypto/OSSLMLDSA.h Outdated
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.

1 participant