Skip to content

feat(csharp): add ML-DSA (FIPS 204) detection rules for .NET 10#387

Open
Chennamma-Hotkar wants to merge 3 commits intocbomkit:mainfrom
Chennamma-Hotkar:feature/csharp-mldsa-rules
Open

feat(csharp): add ML-DSA (FIPS 204) detection rules for .NET 10#387
Chennamma-Hotkar wants to merge 3 commits intocbomkit:mainfrom
Chennamma-Hotkar:feature/csharp-mldsa-rules

Conversation

@Chennamma-Hotkar
Copy link
Copy Markdown

@Chennamma-Hotkar Chennamma-Hotkar commented May 2, 2026

Summary

Adds ML-DSA (FIPS 204) detection rules for .NET 10 System.Security.Cryptography.
Follows the same pattern as #385 (ML-KEM).

Changes

  • DotNetMLDsa.java: detect MLDsa.GenerateKey(MLDsaAlgorithm)
  • DotNetMLDsaTestFile.cs: C# test file using correct .NET 10 API
  • DotNetMLDsaTest.java: unit test verifying detection and translation
  • CSharpDetectionRules.java: registers DotNetMLDsa in rule aggregator
  • CSharpKeyContextTranslator.java: maps MLDSA kind to MLDSA model node

Testing

  • 21 tests pass (was 20 before)
  • mvn spotless:check passes
  • mvn -B clean package -pl csharp passes
Screenshot 2026-05-05 200939

Planned follow-up

  • MLDsaCng, MLDsaOpenSsl derived classes
  • SignData/VerifyData as depending rules
  • Import methods (ImportMLDsaPublicKey, ImportMLDsaPrivateKey)

Note: This PR branches from local main which includes #385 (ML-KEM).
Once #385 merges, this PR will show only the ML-DSA changes (5 files).

Signed-off-by: Chennamma <channuhotkar@gmail.com>
Signed-off-by: Chennamma <channuhotkar@gmail.com>
@Chennamma-Hotkar Chennamma-Hotkar requested a review from a team as a code owner May 2, 2026 17:51
@fynnth
Copy link
Copy Markdown
Contributor

fynnth commented May 5, 2026

Hey @Chennamma-Hotkar ,
thanks a lot for picking this up and contributing PQC detection! ML-KEM and ML-DSA are exactly the kind of algorithms this plugin should be catching, and I appreciate the effort. That said, I have some concerns before we can merge this, and I want to walk through them clearly.

The core issue: the class names don't exist in the .NET API

The detection rules target MLDsa44, MLDsa65, MLDsa87, MLKem512, MLKem768, and MLKem1024 as object types. As far as I can tell from the official System.Security.Cryptography documentation, these are not class names. The actual classes are MLDsa and MLKem (abstract base classes), and what you're referencing are static properties on the algorithm descriptor classes MLDsaAlgorithm and MLKemAlgorithm:

// This is the actual API:
using MLDsa key = MLDsa.GenerateKey(MLDsaAlgorithm.MLDsa65);
using MLKem key = MLKem.GenerateKey(MLKemAlgorithm.MLKem768);

// MLDsa44.GenerateKey() - this class does not exist to the best of my knowledge

Please correct me if I'm wrong here, but there are no MLDsa44 or MLKem512 concrete classes in the docs for .net 10: https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography?view=net-10.0
Also you mentioned that this should be for dotnet 9 but as far as i can tell the PQC algorithms were introduced in .net 10.

This also means the .withoutParameters() call will never match anything even if the class names were fixed -> GenerateKey always requires an MLDsaAlgorithm / MLKemAlgorithm argument. There is no parameterless overload.

Just to set expectations: the tests and detection rules currently in this C# branch are mostly placeholder / dummy coverage while the module is still being built out. Please don't use those as a model for correctness.
I'm attaching a possible full DotNetAES.java detection rule file and the corresponding DotNetAESTestFile.cs that i have written some time ago so you can see the approach end to end. A few things worth noting as you read through them:

  • The primary rules always target the actual class name as it appears in C# (Aes, AesManaged, AesCng, AesCryptoServiceProvider) -> not parameter set identifiers
  • Platform-specific derived classes (AesCng) get their own separate rules alongside the base class factory

Coverage goes beyond just object construction: depending rules capture encrypt/decrypt operations, mode/padding property setters, key generation, etc.
For ML-DSA the equivalent starting point would be targeting MLDsa, MLDsaCng, and MLDsaOpenSsl and for ML-KEM: MLKem, MLKemCng, and MLKemOpenSsl. Import methods (ImportMLDsaPublicKey, ImportFromPem, ImportPkcs8PrivateKey, etc.) should eventually be covered as well, similar to how the AES rules capture the full operation surface as depending rules.

Summary

  1. The object type names in the rules (MLDsa44, MLKem512 etc.) don't correspond to real .NET classes -> the rules would never fire
  2. .withoutParameters() won't match since GenerateKey always takes an algorithm parameter
  3. Coverage is missing for import methods and the platform-specific derived classes (MLDsaCng, MLDsaOpenSsl, MLKemCng, MLKemOpenSsl)

Happy to help get this into shape if you want to iterate -> the intent is absolutely right, it just needs to match the actual API structure.

Here some detection rule for AES in .net for reference. This is not yet approved or merged into sonar-cryptography so take it with a grain of salt, but i think it will get my point across:

possible detection rules.txt
PossibleTestfile.txt

@Chennamma-Hotkar
Copy link
Copy Markdown
Author

Hi @fynnth, thank you for the detailed review — this is exactly
the kind of feedback I needed.

You're completely right on all three points:

  1. I incorrectly used parameter set identifiers as class names
  2. GenerateKey always requires an MLDsaAlgorithm/MLKemAlgorithm argument
  3. These APIs are .NET 10, not .NET 9

I'll rework both PRs (#385 and #387) to target the correct API:

  • MLDsa.GenerateKey(MLDsaAlgorithm.MLDsa65)
  • MLKem.GenerateKey(MLKemAlgorithm.MLKem768)

Also downloading the reference files you attached now.
Will push corrected versions shortly.

Signed-off-by: Chennamma <channuhotkar@gmail.com>
@Chennamma-Hotkar Chennamma-Hotkar changed the title feat(csharp): add ML-DSA detection rules for .NET 9 feat(csharp): add ML-DSA (FIPS 204) detection rules for .NET 10 May 5, 2026
@Chennamma-Hotkar
Copy link
Copy Markdown
Author

@fynnth all three points addressed in the latest commit.

Switched the object types to MLKem and MLDsa since those are the actual abstract base classes — the algorithm descriptors like MLDsa65 are just static properties on MLDsaAlgorithm, not classes. Changed withoutParameters() to withMethodParameter(MethodMatcher.ANY) since GenerateKey always takes an algorithm argument. Test files now call MLDsa.GenerateKey(MLDsaAlgorithm.MLDsa65) which matches the real .NET 10 API.

Will follow up with MLDsaCng, MLDsaOpenSsl, MLKemCng, MLKemOpenSsl and the operation surface (SignData, VerifyData, Encapsulate, Decapsulate, import methods) in a separate PR once this lands.

@fynnth
Copy link
Copy Markdown
Contributor

fynnth commented May 6, 2026

Hey,
thanks for the quick turnaround
The fixes address the class name and parameter issues correctly.

One remaining problem though: all three rules for both ML-DSA and ML-KEM now have identical matchers with the same object type (MLDsa / MLKem), same method (GenerateKey), same parameter pattern (withMethodParameter(ANY)). The engine matches on types and counts, not on argument values, so all three rules fire on every single MLDsa.GenerateKey(...) call regardless of which MLDsaAlgorithm is passed. That means every usage produces three findings which isn't correct. I have not tested this but i think that is what should happen and it does not fail the test because you use assertThat(value.asString()).isIn("MLKEM512", "MLKEM768", "MLKEM1024"); so if multiple findings are thrown for each testcase that would still be valid and that is bad and should always be verified by also checking the finding count for a testcase.

Beyond that, I don't really see the value in detecting generic factory methods without proper argument-value differentiation and without depending detection rules for the operation surface (SignData, VerifyData, Encapsulate, Decapsulate, import methods etc.). If you'd like to contribute this properly I'd love to see a comprehensive PR that covers all of that end to end, but in its current form I won't be able to merge it.

There's also a practical constraint worth flagging: our current C# parser only guarantees correct parsing up to C# 7. ML-KEM and ML-DSA landed in .NET 10 with C# 13 syntax in practice. I'm currently working on a commit that brings full coverage up to C# 7, and I'll be working toward C# 10+ support from there. If the rules only target factory methods without the broader operation surface, the value added on top of that is fairly limited, so a comprehensive PR covering the full API surface of the PQC algorithms would be a much stronger contribution and worth the extra effort.

Happy to review once it's more complete! If you dont want to work on that i will definitely include it in my work on complete security.cryptography coverage. Porbably in the next few months there should be progress from my side in that regard.

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.

2 participants