Skip to content

Added ML-DSA support, policy and validation (resolver-only) - #70

Draft
zbalkan wants to merge 2 commits into
TechnitiumSoftware:masterfrom
zbalkan:feat/pqc
Draft

zbalkan wants to merge 2 commits into
TechnitiumSoftware:masterfrom
zbalkan:feat/pqc

Conversation

@zbalkan

@zbalkan zbalkan commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

ML-DSA-44 DNSSEC support

TechnitiumLibrary implements resolver-side ML-DSA-44 using DNSSEC algorithm number 18. The wire profile follows draft-westerbaan-dnssec-mldsa:

Item Value
DNSKEY public key 1,312 octets
RRSIG signature 2,420 octets
ML-DSA variant Pure ML-DSA-44
Context Empty
Signed message RFC 4034 section 3.1.8.1 data to be signed

The implementation does not prehash the DNSSEC signing input. HashML-DSA and non-empty contexts are not part of this profile. Authoritative key generation and signing are intentionally outside the scope of this library.

Validation policy

Ordinary algorithm support means that algorithm-18 DNSKEY, DS, and RRSIG records can be decoded and used by the normal DNSSEC validation path.

In addition, the resolver applies stronger downgrade protection when an algorithm-18 DS record in the parent DS RRset has already been authenticated. The child must then provide a matching ML-DSA SEP DNSKEY, the DNSKEY RRset must validate through ML-DSA, and RRsets below that zone must validate with ML-DSA. A conventional signature cannot satisfy this requirement. An algorithm-18 DS record whose DNSSEC status is not Secure does not activate the policy. This strong policy is mandatory whenever its authenticated signal is present; it is not a process-wide optional mode.

Transport and resource behavior

ML-DSA signatures normally exceed common UDP payload sizes. A truncated UDP DNSSEC response is discarded and retried over TCP by the existing DNS client fallback path; the truncated response is not returned for validation or normal caching.

DNSKEY and RRSIG parsing rejects algorithm-18 values whose lengths differ from the sizes above. In addition to the existing KeyTrap limits, ML-DSA verification has a dedicated per-response budget. Exhausting it produces the TooManyCryptoValidations extended DNS error rather than continuing expensive path exploration.

Cache compatibility

Algorithm numbers are stored in DNS RDATA as their numeric byte value. Existing cache entries containing a correctly encoded algorithm-18 DNSKEY or RRSIG are therefore read using the new implementation without a persistence format change. The authenticated-DS requirement is deliberately not persisted as an independent trust assertion: it is reconstructed from the authenticated parent DS chain. When that requirement is active, the resolver does not reuse a DNSKEY cache answer that predates enforcement.

Malformed algorithm-18 keys and signatures are rejected even if they were previously retained as unsupported data. This is required to keep malformed wire values away from the cryptographic provider.

Observability

DnssecMetrics exposes process-wide, thread-safe counters for:

  • ML-DSA verification attempts;
  • ML-DSA verification failures;
  • ML-DSA resource-limit failures;
  • authenticated-DS downgrade-policy failures;
  • cryptographic-provider failures; and
  • DNSSEC UDP-to-TCP fallbacks.

These counters are cumulative for the lifetime of the process. They do not log individual keys, signatures, or queried names.


P.S: Utilized ChatGPT for PR description.

@zbalkan
zbalkan marked this pull request as draft September 13, 2026 19:29
@zbalkan

zbalkan commented Sep 13, 2026

Copy link
Copy Markdown
Contributor Author

I'll keep it as a draft until RFC is approved. I will maintain this with the changes periodically.

Signed-off-by: Zafer Balkan <zafer@zaferbalkan.com>
Signed-off-by: Zafer Balkan <zafer@zaferbalkan.com>
@zbalkan zbalkan changed the title Added ML-DSA support, policy and validation Added ML-DSA support, policy and validation (resolver-only) Sep 15, 2026
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