RFC 9814

Use of the SLH-DSA Signature Algorithm in the Cryptographic Message Syntax (CMS)

πŸ“… published July 2025, from ietf

RFC 9814: Use of the SLH-DSA Signature Algorithm in the Cryptographic Message Syntax (CMS) πŸŽ€

okay bestie, this is the IETF's official rulebook (an RFC) for using SLH-DSA, a post-quantum signature algorithm, inside CMS ✨ it's super nerdy but so iconic πŸ¦‹

  • RFC number: 9814 πŸ’–
  • Category: Standards Track (this is a real, official internet standard πŸ‘‘)
  • Date: July 2025 🌸
  • ISSN: 2070-1721
  • Authors: R. Housley (Vigil Security), S. Fluhrer (Cisco Systems), P. Kampanakis (Amazon Web Services), and B. Westerbaan (Cloudflare) 🫢
  • Obsoletes or updates: the header doesn't list any other RFCs, so this one isn't replacing or patching anything else πŸ’…

Abstract

okay so the abstract is the TL;DR πŸ’œ SLH-DSA is a stateless hash-based signature algorithm, and this document says how to use it with the Cryptographic Message Syntax (CMS). It also gives the algorithm identifier and the public key syntax πŸ”₯


Status of This Memo

this is giving official paperwork πŸ“„βœ¨ It's an Internet Standards Track document. It's a product of the Internet Engineering Task Force (IETF) and represents the consensus of the IETF community. It got public review and was approved for publication by the Internet Engineering Steering Group (IESG). If you want more on Internet Standards, check Section 2 of RFC 7841 πŸŽ€

For the current status, any errata, and how to send feedback, go to https://www.rfc-editor.org/info/rfc9814 🌈


legal stuff time, but it matters πŸ™ˆ Copyright (c) 2025 IETF Trust and the persons identified as the document authors. All rights reserved.

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, since they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions, and they're provided without warranty as described in the Revised BSD License πŸ’–


Table of Contents

1.  Introduction
  1.1.  ASN.1
  1.2.  Motivation
  1.3.  Terminology
2.  SLH-DSA Hash-Based Signature Algorithm Overview
3.  SLH-DSA Public Key Identifier
4.  Signed-Data Conventions
5.  Security Considerations
6.  Operational Considerations
7.  IANA Considerations
8.  References
  8.1.  Normative References
  8.2.  Informative References
Appendix A.  ASN.1 Module
Acknowledgements
Authors' Addresses

1. Introduction ✨

okay so this document is all about using the SLH-DSA hash-based signature algorithm [FIPS205] with the Cryptographic Message Syntax (CMS) [RFC5652] signed-data content type πŸ¦‹

SLH-DSA comes in two signature modes: pure mode and pre-hash mode. SLH-DSA signature operations take a context string as input. The context string can be at most 255 bytes long, and by default it's the empty string. This document only specifies pure mode with an empty context string for the CMS signed-data content type. just the basics, bestie πŸ’…

SLH-DSA also has three security levels. The parameters for each level were picked to give 128 bits of security, 192 bits of security, and 256 bits of security. Each of those levels got its own algorithm identifier 🌸

SLH-DSA is a stateless hash-based signature algorithm. The other hash-based signature algorithms are stateful, like Hierarchical Signature System (HSS) / Leighton-Micali Signatures (LMS) [RFC8554] and eXtended Merkle Signature Scheme (XMSS) [RFC8391]. Since the signer doesn't have to keep track of state, SLH-DSA is way less fragile than the stateful ones πŸ™Œ

1.1. ASN.1

CMS values are generated with ASN.1 [X680] using the Basic Encoding Rules (BER) and the Distinguished Encoding Rules (DER) [X690] 🧚

1.2. Motivation

the crypto world has been moving fast πŸ”₯ there have been recent advances in cryptanalysis and in the development of quantum computers. Each of these advances poses a threat to widely deployed digital signature algorithms.

If Cryptographically Relevant Quantum Computers (CRQCs) ever get built, they'll be able to break a lot of the public key cryptosystems we use today, including RSA, DSA, Elliptic Curve Digital Signature Algorithm (ECDSA), and Edwards-curve Digital Signature Algorithm (EdDSA) 😭 A Post-Quantum Cryptosystem (PQC) is secure against quantum computers that have more than a trivial number of quantum bits (qu-bits). Nobody knows when it'll be feasible to build those machines, but it's smart to use algorithms that stay secure if a CRQC is invented. SLH-DSA is a PQC signature algorithm πŸ’œ

1.3. Terminology

this part is the rulebook for the rulebook πŸ€“ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here πŸŽ€


2. SLH-DSA Hash-Based Signature Algorithm Overview πŸ”₯

okay this is where it gets spicy, so grab a snack πŸ“

SLH-DSA is a stateless hash-based signature algorithm. It uses a few-time signature construction called Forest of Random Subsets (FORS), plus a hypertree. FORS signs a message with a private key. The matching FORS public keys are the leaves in k binary trees. The roots of those trees get hashed together to make a FORS root. SLH-DSA also uses a one-time signature scheme called Winternitz One-Time Signature Plus (WOTS+). The FORS tree roots get signed by a WOTS+ private key. The matching WOTS+ public keys form the leaves in d layers of Merkle subtrees in the SLH-DSA hypertree.

The bottom layer of that hypertree signs the FORS roots with WOTS+. The roots of those bottom Merkle subtrees are then signed with WOTS+, and the matching WOTS+ public keys become the leaves of the next subtree up. Each subtree root gets signed by the layer above it, all the way up to the top subtree. The top-layer subtree forms the hypertree root, and that root is the thing the verifier trusts ahead of time πŸ‘‘

An SLH-DSA signature is made of the randomization string, the FORS signature, the WOTS+ signature in each layer, and the path to the root of each subtree, up until you reach the root of the hypertree 🧚

To verify an SLH-DSA signature, you use the FORS signature, the WOTS+ signatures, and the path to the root of each subtree. When you reach the root of the hypertree, the signature only verifies if it hashes to the pre-trusted root of the SLH-DSA hypertree πŸ¦‹

Okay, here's the main reason it's so good πŸ’… Stateful hash-based schemes require that the WOTS+ private key (generated using a state index) never gets reused, or the scheme loses its security. FORS is used at the bottom of the SLH-DSA hypertree. Security goes down if the same private key signs two or more different messages, but it doesn't collapse the way it does in stateful hash-based algorithms. Since the signer doesn't need to keep state to make sure keys aren't reused, SLH-DSA is much less fragile πŸ™Œ

SLH-DSA was designed to sign up to 2^64 messages and offers three security levels. The parameters of the SLH-DSA hypertree include the security parameter, the hash function, the tree height, the number of layers of subtrees, the Winternitz parameter of WOTS+, and the number of FORS trees and leaves in each. The parameters for each security level were chosen to be at least as secure as a generic block cipher of 128, 192, or 256 bits 🌈

3. SLH-DSA Public Key Identifier ✨

okay bestie, this is where we pick our SLH-DSA identifier πŸŽ€ the AlgorithmIdentifier for an SLH-DSA public key MUST use one of the twelve id-slh-dsa object identifiers below. which one you get depends on three things: the security level used to generate the SLH-DSA hypertree, whether you want the small or fast version of the algorithm, and whether you're using SHA2 [FIPS180] or SHAKE [FIPS202] πŸ’œ for example, id-slh-dsa-shake-256s is the 256-bit security level, the small version, using SHAKE256. the parameters field of the AlgorithmIdentifier for the SLH-DSA public key MUST be absent. no extras, no cap 🫢

nistAlgorithms OBJECT IDENTIFIER ::= { joint-iso-itu-t(2)
  country(16) us(840) organization(1) gov(101) csor(3) 4 }

sigAlgs OBJECT IDENTIFIER ::= { nistAlgorithms 3 }

id-slh-dsa-sha2-128s OBJECT IDENTIFIER ::= { sigAlgs 20 }

id-slh-dsa-sha2-128f OBJECT IDENTIFIER ::= { sigAlgs 21 }

id-slh-dsa-sha2-192s OBJECT IDENTIFIER ::= { sigAlgs 22 }

id-slh-dsa-sha2-192f OBJECT IDENTIFIER ::= { sigAlgs 23 }

id-slh-dsa-sha2-256s OBJECT IDENTIFIER ::= { sigAlgs 24 }

id-slh-dsa-sha2-256f OBJECT IDENTIFIER ::= { sigAlgs 25 }

id-slh-dsa-shake-128s OBJECT IDENTIFIER ::= { sigAlgs 26 }

id-slh-dsa-shake-128f OBJECT IDENTIFIER ::= { sigAlgs 27 }

id-slh-dsa-shake-192s OBJECT IDENTIFIER ::= { sigAlgs 28 }

id-slh-dsa-shake-192f OBJECT IDENTIFIER ::= { sigAlgs 29 }

id-slh-dsa-shake-256s OBJECT IDENTIFIER ::= { sigAlgs 30 }

id-slh-dsa-shake-256f OBJECT IDENTIFIER ::= { sigAlgs 31 }

when this AlgorithmIdentifier shows up in the SubjectPublicKeyInfo field of an X.509 certificate [RFC5280] 🌸, the certificate key usage extension MAY contain digitalSignature, nonRepudiation, keyCertSign, and cRLSign. it MUST NOT contain any other values. no sneaking in extra usages, bestie πŸ™…β€β™€οΈ

pk-slh-dsa-sha2-128s PUBLIC-KEY ::= {
    IDENTIFIER id-slh-dsa-sha2-128s
    -- KEY no ASN.1 wrapping --
    CERT-KEY-USAGE
      { digitalSignature, nonRepudiation, keyCertSign, cRLSign }
    -- PRIVATE-KEY no ASN.1 wrapping -- }

pk-slh-dsa-sha2-128f PUBLIC-KEY ::= {
    IDENTIFIER id-slh-dsa-sha2-128f
    -- KEY no ASN.1 wrapping --
    CERT-KEY-USAGE
      { digitalSignature, nonRepudiation, keyCertSign, cRLSign }
    -- PRIVATE-KEY no ASN.1 wrapping -- }

pk-slh-dsa-sha2-192s PUBLIC-KEY ::= {
    IDENTIFIER id-slh-dsa-sha2-192s
    -- KEY no ASN.1 wrapping --
    CERT-KEY-USAGE
      { digitalSignature, nonRepudiation, keyCertSign, cRLSign }
    -- PRIVATE-KEY no ASN.1 wrapping -- }

pk-slh-dsa-sha2-192f PUBLIC-KEY ::= {
    IDENTIFIER id-slh-dsa-sha2-192f
    -- KEY no ASN.1 wrapping --
    CERT-KEY-USAGE
      { digitalSignature, nonRepudiation, keyCertSign, cRLSign }
    -- PRIVATE-KEY no ASN.1 wrapping -- }

pk-slh-dsa-sha2-256s PUBLIC-KEY ::= {
    IDENTIFIER id-slh-dsa-sha2-256s
    -- KEY no ASN.1 wrapping --
    CERT-KEY-USAGE
      { digitalSignature, nonRepudiation, keyCertSign, cRLSign }
    -- PRIVATE-KEY no ASN.1 wrapping -- }

pk-slh-dsa-sha2-256f PUBLIC-KEY ::= {
    IDENTIFIER id-slh-dsa-sha2-256f
    -- KEY no ASN.1 wrapping --
    CERT-KEY-USAGE
      { digitalSignature, nonRepudiation, keyCertSign, cRLSign }
    -- PRIVATE-KEY no ASN.1 wrapping -- }

pk-slh-dsa-shake-128s PUBLIC-KEY ::= {
    IDENTIFIER id-slh-dsa-shake-128s
    -- KEY no ASN.1 wrapping --
    CERT-KEY-USAGE
      { digitalSignature, nonRepudiation, keyCertSign, cRLSign }
    -- PRIVATE-KEY no ASN.1 wrapping -- }

pk-slh-dsa-shake-128f PUBLIC-KEY ::= {
    IDENTIFIER id-slh-dsa-shake-128f
    -- KEY no ASN.1 wrapping --
    CERT-KEY-USAGE
      { digitalSignature, nonRepudiation, keyCertSign, cRLSign }
    -- PRIVATE-KEY no ASN.1 wrapping -- }

pk-slh-dsa-shake-192s PUBLIC-KEY ::= {
    IDENTIFIER id-slh-dsa-shake-192s
    -- KEY no ASN.1 wrapping --
    CERT-KEY-USAGE
      { digitalSignature, nonRepudiation, keyCertSign, cRLSign }
    -- PRIVATE-KEY no ASN.1 wrapping -- }

pk-slh-dsa-shake-192f PUBLIC-KEY ::= {
    IDENTIFIER id-slh-dsa-shake-192f
    -- KEY no ASN.1 wrapping --
    CERT-KEY-USAGE
      { digitalSignature, nonRepudiation, keyCertSign, cRLSign }
    -- PRIVATE-KEY no ASN.1 wrapping -- }

pk-slh-dsa-shake-256s PUBLIC-KEY ::= {
    IDENTIFIER id-slh-dsa-shake-256s
    -- KEY no ASN.1 wrapping --
    CERT-KEY-USAGE
      { digitalSignature, nonRepudiation, keyCertSign, cRLSign }
    -- PRIVATE-KEY no ASN.1 wrapping -- }

pk-slh-dsa-shake-256f PUBLIC-KEY ::= {
    IDENTIFIER id-slh-dsa-shake-256f
    -- KEY no ASN.1 wrapping --
    CERT-KEY-USAGE
      { digitalSignature, nonRepudiation, keyCertSign, cRLSign }
    -- PRIVATE-KEY no ASN.1 wrapping -- }

SLH-DSA-PublicKey ::= OCTET STRING (SIZE (32 | 48 | 64))

SLH-DSA-PrivateKey ::= OCTET STRING (SIZE (64 | 96 | 128))

no extra encoding gets applied to the SLH-DSA public key in the SubjectPublicKeyInfo field of an X.509 certificate [RFC5280] 🧁 same deal for the private key: no additional encoding in the PrivateKeyInfo field of the privateKey field of the OneAsymmetricKey type of an Asymmetric Key Package [RFC5958]. simple and clean ✨

if an SLH-DSA public key shows up outside of a SubjectPublicKeyInfo type, in an environment that uses ASN.1 encoding, you can encode it as an OCTET STRING using the SLH-DSA-PublicKey type πŸ¦‹. and if an SLH-DSA private key shows up outside of an Asymmetric Key Package in an ASN.1 environment, you can encode it as an OCTET STRING using the SLH-DSA-PrivateKey type πŸ”


4. Signed-Data Conventions πŸ’…

okay so, as CMS [RFC5652] lays out, the digital signature is made from the message digest and the signer's private key πŸ”‘ the signature gets computed over different values depending on whether signed attributes are absent or present. this part is kinda the main event, so pay attention πŸ‘€

when signed attributes are absent, the SLH-DSA (pure mode) signature is computed over the content. when signed attributes are present, a hash SHOULD be computed over the DER-encoded signed attributes, using the same hash function that's used in the SLH-DSA tree 🌈 the signed attributes MUST include a content-type attribute and a message-digest attribute. the message-digest attribute holds the hash value of the content. then the SLH-DSA signature is computed over the DER encoding of the set of signed attributes. the SLH-DSA signature-generation operation is called slh_sign, see Section 10.2.1 of [FIPS205]. in summary:

IF (signed attributes are absent)
THEN slh_sign(content)
ELSE signed attributes message-digest attribute = Hash(content);
     slh_sign(DER(SignedAttributes))

in some implementations, performance can get a major boost by signing and verifying DER(SignedAttributes) when the content is large πŸš€ like, passing a huge message straight into the signing function or the signature validation function can really hurt performance. when signed attributes are present, Section 5.3 of [RFC5652] requires the content-type attribute and the message-digest attribute to be included. other attributes can be included too πŸ’–

when you're using SLH-DSA and signed attributes are present in the SignerInfo, the digestAlgorithms field in the SignedData MUST include the identifier for the one-way hash function used to compute the message digest 🫢

when using SLH-DSA, here's how the fields in the SignerInfo work πŸ‘‘

digestAlgorithm: The digestAlgorithm MUST identify a one-way hash function. when signed attributes are absent, the digestAlgorithm identifier SHOULD match the hash function used in the SLH-DSA tree (see the list below). it doesn't mean anything when signed attributes are absent, since it's not used to pre-hash the message πŸ™ˆ if you're worried about failures with legacy implementations that don't support every hash function, signers MAY choose to always use the SHA-256 algorithm identifier as the digestAlgorithm when signed attributes are absent. when signed attributes are present, the identified hash function MUST produce a hash value at least twice the size of the hash function used in the SLH-DSA tree, to keep collision resistance strong πŸ’ͺ the hash functions defined in [FIPS180] and [FIPS202] MUST be supported for use with the variants of SLH-DSA shown below:

id-slh-dsa-sha2-128s:  SHA-256
id-slh-dsa-sha2-128f:  SHA-256
id-slh-dsa-sha2-192s:  SHA-512
id-slh-dsa-sha2-192f:  SHA-512
id-slh-dsa-sha2-256s:  SHA-512
id-slh-dsa-sha2-256f:  SHA-512
id-slh-dsa-shake-128s: SHAKE128 with 256-bit output
id-slh-dsa-shake-128f: SHAKE128 with 256-bit output
id-slh-dsa-shake-192s: SHAKE256 with 512-bit output
id-slh-dsa-shake-192f: SHAKE256 with 512-bit output
id-slh-dsa-shake-256s: SHAKE256 with 512-bit output
id-slh-dsa-shake-256f: SHAKE256 with 512-bit output

the object identifiers for SHA-256 and SHA-512 are in [RFC5754]. the ones for SHAKE128 and SHAKE256 are in [RFC8702]. in all four of those cases, the AlgorithmIdentifier SHOULD NOT include parameters ✨

signatureAlgorithm: the signatureAlgorithm MUST contain one of the SLH-DSA algorithm identifiers, and the algorithm parameters field MUST be absent. the algorithm identifier MUST be one of the following πŸ¦‹

id-slh-dsa-sha2-128s,  id-slh-dsa-sha2-128f,
id-slh-dsa-sha2-192s,  id-slh-dsa-sha2-192f,
id-slh-dsa-sha2-256s,  id-slh-dsa-sha2-256f,
id-slh-dsa-shake-128s, id-slh-dsa-shake-128f,
id-slh-dsa-shake-192s, id-slh-dsa-shake-192f,
id-slh-dsa-shake-256s, id-slh-dsa-shake-256f.

signature: the signature holds the signature value from the SLH-DSA signing operation, using the parameters tied to the selected signatureAlgorithm πŸŽ€ the SLH-DSA signature-generation operation is in Section 10.2.1 of [FIPS205], and the SLH-DSA signature verification operation is in Section 10.3 of [FIPS205]. signature verification MUST include checking that the signatureAlgorithm field identifies SLH-DSA parameters that are consistent with the public key used to validate the signature. this one's a big deal, bestie, don't skip it πŸ™…β€β™€οΈπŸ”₯

5. Security Considerations ✨

Okay bestie, this section is SERIOUS, so let's get into it 🫢😭. Implementations MUST protect the private keys πŸ”. If somebody gets the private keys, they can forge signatures, and that is a whole disaster πŸ’€.

When you generate an SLH-DSA key pair, an implementation MUST generate each key pair independently of all other key pairs in the SLH-DSA hypertree 🌳. No sharing, no copy-pasting keys around, periodt πŸ’….

An SLH-DSA tree MUST NOT be used for more than 2^64 signing operations. That's a LOT of signing, but the rule is the rule πŸ™ˆ.

Random numbers are a huge deal when you're making private keys 🎲. If you use an inadequate Pseudorandom Number Generator (PRNG), you can end up with little or no security at all 😬. An attacker might find it way easier to recreate the PRNG environment that made the keys and then search through the resulting small pile of possibilities, instead of brute-forcing the whole key space 🫠. Getting quality random numbers is hard, and [RFC4086] has some really important guidance on this, so go read it πŸ“šπŸŒΈ.

To avoid algorithm-substitution attacks, the CMSAlgorithmProtection attribute defined in [RFC6211] SHOULD be included in signed attributes πŸ›‘οΈβœ¨. It's giving protection, no cap.

Implementers should think about their particular use cases πŸ€” and may choose to implement optional fault-attack countermeasures [CMP2018] [Ge2023] πŸ§ͺ. Verifying a signature before releasing the signature value is a typical fault-attack countermeasure, BUT this countermeasure is not effective for SLH-DSA [Ge2023] πŸ™…β€β™€οΈ. Redundancy, which means replicating the signature-generation process, MAY be used as an effective fault-attack countermeasure for SLH-DSA [Ge2023] πŸ”. The catch is that SLH-DSA signature generation is already considered slow 🐒, so... choose wisely πŸ’–.

Likewise, implementers should think about their particular use cases 🧠 and may choose to implement protections against passive power and emissions side-channel attacks [SLotH] βš‘πŸ¦‹.

6. Operational Considerations πŸŽ€

If slh_sign is implemented in a hardware device such as a Hardware Security Module (HSM) or a portable cryptographic token πŸ”‘, implementations can avoid sending the full content to the device πŸ“¦. By including signed attributes, which necessarily include the message-digest attribute and the content-type attribute as described in Section 5.3 of [RFC5652], only the much smaller set of signed attributes gets sent to the device for signing πŸͺ„. Main character energy for the small payload πŸ’œ.

By including signed attributes in the SignerInfo, you can get similar interface characteristics to SLH-DSA in pre-hash mode 🧚. With pre-hash mode, the hash of the content is passed to the SLH-DSA signature operation instead of the full message content πŸ”. By including signed attributes in the SignerInfo, a relatively small to-be-signed value is passed to the SLH-DSA signature operation πŸ“¨. For this reason, SLH-DSA pre-hash mode is not specified for use with the CMS SignedData 🚫. Also, note that SLH-DSA pre-hash mode always yields a different signature value than SLH-DSA pure mode, even if the to-be-signed content is the same πŸ‘€. Plot twist, but it's true 🫣.

When using SLH-DSA in pure mode, it is not possible to single-pass process the content to verify a SignedData message that does not contain signed attributes πŸŒ€. To help recipients that might use stream-based APIs, implementers SHOULD include signed attributes within any SignerInfo that uses SLH-DSA as its signature algorithm 🌊. Doing so lets the recipient implementation avoid keeping the signed content in memory 🧠✨. Recall that when signed attributes are present, they MUST contain a content-type attribute and a message-digest attribute, and they SHOULD contain a CMSAlgorithmProtection attribute πŸ“πŸ’….

7. IANA Considerations 🌈

For the ASN.1 Module in Appendix A, IANA has assigned an Object Identifier (OID) for the module identifier (81) with a Description of "id-mod-slh-dsa-2024" πŸ†”. The OID for the module has been allocated in the "SMI Security for S/MIME Module Identifier (1.2.840.113549.1.9.16.0)" registry πŸ—‚οΈπŸ¦‹.

8. References πŸ“š

8.1. Normative References

[FIPS180] National Institute of Standards and Technology (NIST), "Secure Hash Standard (SHS)", NIST FIPS 180-4, DOI 10.6028/NIST.FIPS.180-4, August 2015, <https://doi.org/10.6028/NIST.FIPS.180-4>.

[FIPS202] National Institute of Standards and Technology (NIST), "SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions", NIST FIPS 202, DOI 10.6028/NIST.FIPS.202, August 2015, <https://doi.org/10.6028/NIST.FIPS.202>.

[FIPS205] National Institute of Standards and Technology (NIST), "Stateless Hash-Based Digital Signature Standard", NIST FIPS 205, DOI 10.6028/NIST.FIPS.205, 13 August 2024, <https://doi.org/10.6028/NIST.FIPS.205>.

[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, <https://www.rfc-editor.org/info/rfc2119>.

[RFC5280] Cooper, D., Santesson, S., Farrell, S., Boeyen, S., Housley, R., and W. Polk, "Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile", RFC 5280, DOI 10.17487/RFC5280, May 2008, <https://www.rfc-editor.org/info/rfc5280>.

[RFC5652] Housley, R., "Cryptographic Message Syntax (CMS)", STD 70, RFC 5652, DOI 10.17487/RFC5652, September 2009, <https://www.rfc-editor.org/info/rfc5652>.

[RFC5754] Turner, S., "Using SHA2 Algorithms with Cryptographic Message Syntax", RFC 5754, DOI 10.17487/RFC5754, January 2010, <https://www.rfc-editor.org/info/rfc5754>.

[RFC5958] Turner, S., "Asymmetric Key Packages", RFC 5958, DOI 10.17487/RFC5958, August 2010, <https://www.rfc-editor.org/info/rfc5958>.

[RFC6211] Schaad, J., "Cryptographic Message Syntax (CMS) Algorithm Identifier Protection Attribute", RFC 6211, DOI 10.17487/RFC6211, April 2011, <https://www.rfc-editor.org/info/rfc6211>.

[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, <https://www.rfc-editor.org/info/rfc8174>.

[RFC8702] Kampanakis, P. and Q. Dang, "Use of the SHAKE One-Way Hash Functions in the Cryptographic Message Syntax (CMS)", RFC 8702, DOI 10.17487/RFC8702, January 2020, <https://www.rfc-editor.org/info/rfc8702>.

[X680] ITU-T, "Information technology -- Abstract Syntax Notation One (ASN.1): Specification of basic notation", ITU-T Recommendation X.680, ISO/IEC 8824-1:2021, February 2021, <https://www.itu.int/rec/T-REC-X.680>.

[X690] ITU-T, "Information technology -- ASN.1 encoding rules: Specification of Basic Encoding Rules (BER), Canonical Encoding Rules (CER) and Distinguished Encoding Rules (DER)", ITU-T Recommendation X.690, ISO/IEC 8825-1-2021, February 2021, <https://www.itu.int/rec/T-REC-X.690>.

8.2. Informative References

[CMP2018] Castelnovi, L., Martinelli, A., and T. Prest, "Grafting Trees: A Fault Attack Against the SPHINCS Framework", Post-Quantum Cryptography (PQCrypto 2018), Lecture Notes in Computer Science, vol. 10786, pp. 165-184, DOI 10.1007/978-3-319-79063-3_8, 2018, <https://link.springer.com/chapter/10.1007/978-3-319-79063-3_8>.

[Ge2023] GenΓͺt, A., "On Protecting SPHINCS+ Against Fault Attacks", IACR Transactions on Cryptographic Hardware and Embedded Systems, vol. 2023, no. 2, pp. 80-114, DOI 10.46586/tches.v2023.i2.80-114, 2023, <https://tches.iacr.org/index.php/TCHES/article/view/10278/9726>.

[RFC4086] Eastlake 3rd, D., Schiller, J., and S. Crocker, "Randomness Requirements for Security", BCP 106, RFC 4086, DOI 10.17487/RFC4086, June 2005, <https://www.rfc-editor.org/info/rfc4086>.

[RFC5911] Hoffman, P. and J. Schaad, "New ASN.1 Modules for Cryptographic Message Syntax (CMS) and S/MIME", RFC 5911, DOI 10.17487/RFC5911, June 2010, <https://www.rfc-editor.org/info/rfc5911>.

[RFC8391] Huelsing, A., Butin, D., Gazdag, S., Rijneveld, J., and A. Mohaisen, "XMSS: eXtended Merkle Signature Scheme", RFC 8391, DOI 10.17487/RFC8391, May 2018, <https://www.rfc-editor.org/info/rfc8391>.

[RFC8554] McGrew, D., Curcio, M., and S. Fluhrer, "Leighton-Micali Hash-Based Signatures", RFC 8554, DOI 10.17487/RFC8554, April 2019, <https://www.rfc-editor.org/info/rfc8554>.

[SLotH] Saarinen, M.-J., "Accelerating SLH-DSA by Two Orders of Magnitude with a Single Hash Unit", Cryptology ePrint Archive, Paper 2024/367, 2024, <https://eprint.iacr.org/2024/367.pdf>.

Acknowledgements 🫢

A huge thank you to Mike Ounsworth, Tomas Gustavsson, Daniel Van Geest, Carl Wallace, Phillip Hallam-Baker, Dieter Bratko, Vijay Gurbani, Paul Wouters, and Roman Danyliw for their careful review and constructive comments. The whole doc is better because of you, bestie πŸ’–βœ¨

Appendix A. ASN.1 Module πŸŽ€

This ASN.1 Module builds upon the conventions established in [RFC5911]. Here's the whole thing, so you can see exactly how every SLH-DSA algorithm gets wired into the ASN.1 world 🧚

<CODE BEGINS>

SLH-DSA-Module-2024
  { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9)
    id-smime(16) id-mod(0) id-mod-slh-dsa-2024(81) }

DEFINITIONS IMPLICIT TAGS ::= BEGIN

EXPORTS ALL;

IMPORTS
  PUBLIC-KEY, SIGNATURE-ALGORITHM, SMIME-CAPS
    FROM AlgorithmInformation-2009  -- in [RFC5911]
    { iso(1) identified-organization(3) dod(6) internet(1)
      security(5) mechanisms(5) pkix(7) id-mod(0)
      id-mod-algorithmInformation-02(58) } ;

--
-- Object Identifiers
--

nistAlgorithms OBJECT IDENTIFIER ::= { joint-iso-itu-t(2)
  country(16) us(840) organization(1) gov(101) csor(3) 4 }

sigAlgs OBJECT IDENTIFIER ::= { nistAlgorithms 3 }

id-slh-dsa-sha2-128s OBJECT IDENTIFIER ::= { sigAlgs 20 }

id-slh-dsa-sha2-128f OBJECT IDENTIFIER ::= { sigAlgs 21 }

id-slh-dsa-sha2-192s OBJECT IDENTIFIER ::= { sigAlgs 22 }

id-slh-dsa-sha2-192f OBJECT IDENTIFIER ::= { sigAlgs 23 }

id-slh-dsa-sha2-256s OBJECT IDENTIFIER ::= { sigAlgs 24 }

id-slh-dsa-sha2-256f OBJECT IDENTIFIER ::= { sigAlgs 25 }

id-slh-dsa-shake-128s OBJECT IDENTIFIER ::= { sigAlgs 26 }

id-slh-dsa-shake-128f OBJECT IDENTIFIER ::= { sigAlgs 27 }

id-slh-dsa-shake-192s OBJECT IDENTIFIER ::= { sigAlgs 28 }

id-slh-dsa-shake-192f OBJECT IDENTIFIER ::= { sigAlgs 29 }

id-slh-dsa-shake-256s OBJECT IDENTIFIER ::= { sigAlgs 30 }

id-slh-dsa-shake-256f OBJECT IDENTIFIER ::= { sigAlgs 31 }

--
-- Signature Algorithm, Public Key, and Private Key
--

sa-slh-dsa-sha2-128s SIGNATURE-ALGORITHM ::= {
    IDENTIFIER id-slh-dsa-sha2-128s
    PARAMS ARE absent
    PUBLIC-KEYS { pk-slh-dsa-sha2-128s }
    SMIME-CAPS { IDENTIFIED BY id-slh-dsa-sha2-128s } }

sa-slh-dsa-sha2-128f SIGNATURE-ALGORITHM ::= {
    IDENTIFIER id-slh-dsa-sha2-128f
    PARAMS ARE absent
    PUBLIC-KEYS { pk-slh-dsa-sha2-128f }
    SMIME-CAPS { IDENTIFIED BY id-slh-dsa-sha2-128f } }

sa-slh-dsa-sha2-192s SIGNATURE-ALGORITHM ::= {
    IDENTIFIER id-slh-dsa-sha2-192s
    PARAMS ARE absent
    PUBLIC-KEYS { pk-slh-dsa-sha2-192s }
    SMIME-CAPS { IDENTIFIED BY id-slh-dsa-sha2-192s } }

sa-slh-dsa-sha2-192f SIGNATURE-ALGORITHM ::= {
    IDENTIFIER id-slh-dsa-sha2-192f
    PARAMS ARE absent
    PUBLIC-KEYS { pk-slh-dsa-sha2-192f }
    SMIME-CAPS { IDENTIFIED BY id-slh-dsa-sha2-192f } }

sa-slh-dsa-sha2-256s SIGNATURE-ALGORITHM ::= {
    IDENTIFIER id-slh-dsa-sha2-256s
    PARAMS ARE absent
    PUBLIC-KEYS { pk-slh-dsa-sha2-256s }
    SMIME-CAPS { IDENTIFIED BY id-slh-dsa-sha2-256s } }

sa-slh-dsa-sha2-256f SIGNATURE-ALGORITHM ::= {
    IDENTIFIER id-slh-dsa-sha2-256f
    PARAMS ARE absent
    PUBLIC-KEYS { pk-slh-dsa-sha2-256f }
    SMIME-CAPS { IDENTIFIED BY id-slh-dsa-sha2-256f } }

sa-slh-dsa-shake-128s SIGNATURE-ALGORITHM ::= {
    IDENTIFIER id-slh-dsa-shake-128s
    PARAMS ARE absent
    PUBLIC-KEYS { pk-slh-dsa-shake-128s }
    SMIME-CAPS { IDENTIFIED BY id-slh-dsa-shake-128s } }

sa-slh-dsa-shake-128f SIGNATURE-ALGORITHM ::= {
    IDENTIFIER id-slh-dsa-shake-128f
    PARAMS ARE absent
    PUBLIC-KEYS { pk-slh-dsa-shake-128f }
    SMIME-CAPS { IDENTIFIED BY id-slh-dsa-shake-128f } }

sa-slh-dsa-shake-192s SIGNATURE-ALGORITHM ::= {
    IDENTIFIER id-slh-dsa-shake-192s
    PARAMS ARE absent
    PUBLIC-KEYS { pk-slh-dsa-shake-192s }
    SMIME-CAPS { IDENTIFIED BY id-slh-dsa-shake-192s } }

sa-slh-dsa-shake-192f SIGNATURE-ALGORITHM ::= {
    IDENTIFIER id-slh-dsa-shake-192f
    PARAMS ARE absent
    PUBLIC-KEYS { pk-slh-dsa-shake-192f }
    SMIME-CAPS { IDENTIFIED BY id-slh-dsa-shake-192f } }

sa-slh-dsa-shake-256s SIGNATURE-ALGORITHM ::= {
    IDENTIFIER id-slh-dsa-shake-256s
    PARAMS ARE absent
    PUBLIC-KEYS { pk-slh-dsa-shake-256s }
    SMIME-CAPS { IDENTIFIED BY id-slh-dsa-shake-256s } }

sa-slh-dsa-shake-256f SIGNATURE-ALGORITHM ::= {
    IDENTIFIER id-slh-dsa-shake-256f
    PARAMS ARE absent
    PUBLIC-KEYS { pk-slh-dsa-shake-256f }
    SMIME-CAPS { IDENTIFIED BY id-slh-dsa-shake-256f } }

pk-slh-dsa-sha2-128s PUBLIC-KEY ::= {
    IDENTIFIER id-slh-dsa-sha2-128s
    -- KEY no ASN.1 wrapping --
    CERT-KEY-USAGE
      { digitalSignature, nonRepudiation, keyCertSign, cRLSign }
    -- PRIVATE-KEY no ASN.1 wrapping -- }

pk-slh-dsa-sha2-128f PUBLIC-KEY ::= {
    IDENTIFIER id-slh-dsa-sha2-128f
    -- KEY no ASN.1 wrapping --
    CERT-KEY-USAGE
      { digitalSignature, nonRepudiation, keyCertSign, cRLSign }
    -- PRIVATE-KEY no ASN.1 wrapping -- }

pk-slh-dsa-sha2-192s PUBLIC-KEY ::= {
    IDENTIFIER id-slh-dsa-sha2-192s
    -- KEY no ASN.1 wrapping --
    CERT-KEY-USAGE
      { digitalSignature, nonRepudiation, keyCertSign, cRLSign }
    -- PRIVATE-KEY no ASN.1 wrapping -- }

pk-slh-dsa-sha2-192f PUBLIC-KEY ::= {
    IDENTIFIER id-slh-dsa-sha2-192f
    -- KEY no ASN.1 wrapping --
    CERT-KEY-USAGE
      { digitalSignature, nonRepudiation, keyCertSign, cRLSign }
    -- PRIVATE-KEY no ASN.1 wrapping -- }

pk-slh-dsa-sha2-256s PUBLIC-KEY ::= {
    IDENTIFIER id-slh-dsa-sha2-256s
    -- KEY no ASN.1 wrapping --
    CERT-KEY-USAGE
      { digitalSignature, nonRepudiation, keyCertSign, cRLSign }
    -- PRIVATE-KEY no ASN.1 wrapping -- }

pk-slh-dsa-sha2-256f PUBLIC-KEY ::= {
    IDENTIFIER id-slh-dsa-sha2-256f
    -- KEY no ASN.1 wrapping --
    CERT-KEY-USAGE
      { digitalSignature, nonRepudiation, keyCertSign, cRLSign }
    -- PRIVATE-KEY no ASN.1 wrapping -- }

pk-slh-dsa-shake-128s PUBLIC-KEY ::= {
    IDENTIFIER id-slh-dsa-shake-128s
    -- KEY no ASN.1 wrapping --
    CERT-KEY-USAGE
      { digitalSignature, nonRepudiation, keyCertSign, cRLSign }
    -- PRIVATE-KEY no ASN.1 wrapping -- }

pk-slh-dsa-shake-128f PUBLIC-KEY ::= {
    IDENTIFIER id-slh-dsa-shake-128f
    -- KEY no ASN.1 wrapping --
    CERT-KEY-USAGE
      { digitalSignature, nonRepudiation, keyCertSign, cRLSign }
    -- PRIVATE-KEY no ASN.1 wrapping -- }

pk-slh-dsa-shake-192s PUBLIC-KEY ::= {
    IDENTIFIER id-slh-dsa-shake-192s
    -- KEY no ASN.1 wrapping --
    CERT-KEY-USAGE
      { digitalSignature, nonRepudiation, keyCertSign, cRLSign }
    -- PRIVATE-KEY no ASN.1 wrapping -- }

pk-slh-dsa-shake-192f PUBLIC-KEY ::= {
    IDENTIFIER id-slh-dsa-shake-192f
    -- KEY no ASN.1 wrapping --
    CERT-KEY-USAGE
      { digitalSignature, nonRepudiation, keyCertSign, cRLSign }
    -- PRIVATE-KEY no ASN.1 wrapping -- }

pk-slh-dsa-shake-256s PUBLIC-KEY ::= {
    IDENTIFIER id-slh-dsa-shake-256s
    -- KEY no ASN.1 wrapping --
    CERT-KEY-USAGE
      { digitalSignature, nonRepudiation, keyCertSign, cRLSign }
    -- PRIVATE-KEY no ASN.1 wrapping -- }

pk-slh-dsa-shake-256f PUBLIC-KEY ::= {
    IDENTIFIER id-slh-dsa-shake-256f
    -- KEY no ASN.1 wrapping --
    CERT-KEY-USAGE
      { digitalSignature, nonRepudiation, keyCertSign, cRLSign }
    -- PRIVATE-KEY no ASN.1 wrapping -- }

SLH-DSA-PublicKey ::= OCTET STRING (SIZE (32 | 48 | 64))

SLH-DSA-PrivateKey ::= OCTET STRING (SIZE (64 | 96 | 128))

--
-- Expand the signature algorithm set used by CMS [RFC5911]
--

SignatureAlgorithmSet SIGNATURE-ALGORITHM ::=
    { sa-slh-dsa-sha2-128s |
      sa-slh-dsa-sha2-128f |
      sa-slh-dsa-sha2-192s |
      sa-slh-dsa-sha2-192f |
      sa-slh-dsa-sha2-256s |
      sa-slh-dsa-sha2-256f |
      sa-slh-dsa-shake-128s |
      sa-slh-dsa-shake-128f |
      sa-slh-dsa-shake-192s |
      sa-slh-dsa-shake-192f |
      sa-slh-dsa-shake-256s |
      sa-slh-dsa-shake-256f,
      ... }

--
-- Expand the S/MIME capabilities set used by CMS [RFC5911]
--

SMimeCaps SMIME-CAPS ::=
    { sa-slh-dsa-sha2-128s.&smimeCaps |
      sa-slh-dsa-sha2-128f.&smimeCaps |
      sa-slh-dsa-sha2-192s.&smimeCaps |
      sa-slh-dsa-sha2-192f.&smimeCaps |
      sa-slh-dsa-sha2-256s.&smimeCaps |
      sa-slh-dsa-sha2-256f.&smimeCaps |
      sa-slh-dsa-shake-128s.&smimeCaps |
      sa-slh-dsa-shake-128f.&smimeCaps |
      sa-slh-dsa-shake-192s.&smimeCaps |
      sa-slh-dsa-shake-192f.&smimeCaps |
      sa-slh-dsa-shake-256s.&smimeCaps |
      sa-slh-dsa-shake-256f.&smimeCaps,
      ... }

END

<CODE ENDS>

That's the whole module, bestie. Every sig alg, every public key, and both size constraints are right there, so it's giving complete ✨

Authors' Addresses πŸ¦‹

Russ Housley
Vigil Security, LLC
Email: housley@vigilsec.com

Scott Fluhrer
Cisco Systems
Email: sfluhrer@cisco.com

Panos Kampanakis
Amazon Web Services
Email: kpanos@amazon.com

Bas Westerbaan
Cloudflare
Email: bas@westerbaan.name

And that's a wrap on RFC 9814! πŸ’…πŸŒˆ Hope you've got the vibe now, bestie 🫢

πŸ“¦ where this page comes from