EVP_SIGNATURE-SLH-DSA(7ossl)

πŸ“¦ version 3.5.0, in opensuse-leap 16.0

✨ NAME ✨

Bestie, gather round β€” this page is all about EVP_SIGNATURE-SLH-DSA and its whole gorgeous little friend group:

  • EVP_SIGNATURE-SLH-DSA
  • EVP_SIGNATURE-SLH-DSA-SHA2-128s
  • EVP_SIGNATURE-SLH-DSA-SHA2-128f
  • EVP_SIGNATURE-SLH-DSA-SHA2-192s
  • EVP_SIGNATURE-SLH-DSA-SHA2-192f
  • EVP_SIGNATURE-SLH-DSA-SHA2-256s
  • EVP_SIGNATURE-SLH-DSA-SHA2-256f
  • EVP_SIGNATURE-SLH-DSA-SHAKE-128s
  • EVP_SIGNATURE-SLH-DSA-SHAKE-128f
  • EVP_SIGNATURE-SLH-DSA-SHAKE-192s
  • EVP_SIGNATURE-SLH-DSA-SHAKE-192f
  • EVP_SIGNATURE-SLH-DSA-SHAKE-256s
  • EVP_SIGNATURE-SLH-DSA-SHAKE-256f

…and what they all do is give you EVP_PKEY SLH-DSA support πŸ’…


🌸 DESCRIPTION 🌸

Okay so picture this: these EVP_PKEY implementations β€” SLH-DSA-SHA2-128s, EVP_PKEY-SLH-DSA-SHA2-128f, SLH-DSA-SHA2-192s, EVP_PKEY-SLH-DSA-SHA2-192f, SLH-DSA-SHA2-256s, EVP_PKEY-SLH-DSA-SHA2-256f, SLH-DSA-SHAKE-128s, EVP_PKEY-SLH-DSA-SHAKE-128f, SLH-DSA-SHAKE-192s, EVP_PKEY-SLH-DSA-SHAKE-192f, SLH-DSA-SHAKE-256s and EVP_PKEY-SLH-DSA-SHAKE-256f β€” they support key generation, one-shot sign and verify, using the SLH-DSA signature schemes described in FIPS 205. Iconic behavior only πŸ”₯

The different algorithm names correspond to the parameter sets defined in FIPS 205 Section 11 Table 2. The "s" types have smaller signature sizes, and the "f" variants are faster β€” the signatures range from ~8K to ~50K depending on the type you choose, no cap. And there are 3 different security categories, also depending on the type πŸ‘‘

You can use EVP_SIGNATURE_fetch(3) to explicitly fetch one of the 12 algorithms, which then gets used with EVP_PKEY_sign_message_init(3), EVP_PKEY_sign(3), EVP_PKEY_verify_message_init(3), and EVP_PKEY_verify(3) to do one-shot message signing or verification. Slay.

The normal signing process β€” the one called Pure SLH-DSA Signature Generation β€” encodes the message internally as:

0x00 || len(ctx) || ctx || message

where ctx is some optional value of size 0x00..0xFF. OpenSSL also lets you not encode the message, which is required for testing. OpenSSL does not support Pre Hash SLH-DSA Signature Generation β€” but you can totally do it yourself by doing the pre-hash encoding externally and then choosing the option to not encode the message 🫢

πŸŽ€ SLH-DSA Signature Parameters πŸŽ€

The "context-string" parameter (described right below) works for both signing and verification. You set it by passing an OSSL_PARAM array to EVP_PKEY_sign_init_ex2(3) or EVP_PKEY_verify_init_ex2(3).

  • "context-string" (OSSL_SIGNATURE_PARAM_CONTEXT_STRING) <octet string> β€” a string of octets with length at most 255. By default it is the empty string.

The following parameters can be used when signing β€” set them by passing an OSSL_PARAM array to EVP_PKEY_sign_init_ex2(3):

  • "message-encoding" (OSSL_SIGNATURE_PARAM_MESSAGE_ENCODING) <integer> β€” the default value of 1 uses 'Pure SLH-DSA Signature Generation' as described above. Setting it to 0 does not encode the message, which is used for testing, but can also be used for 'Pre Hash SLH-DSA Signature Generation'.
  • "test-entropy" (OSSL_SIGNATURE_PARAM_TEST_ENTROPY) <octet string> β€” used for testing to pass an optional random value.
  • "deterministic" (OSSL_SIGNATURE_PARAM_DETERMINISTIC) <integer> β€” the default value of 0 generates a random value (using a DRBG) which is used when processing the message. Setting this to 1 causes the private key seed to be used instead. This value is ignored if "test-entropy" is set.
Heads up bestie: see EVP_PKEY-SLH-DSA(7) for all the info related to SLH-DSA keys πŸ”‘

πŸ¦‹ NOTES πŸ¦‹

For backwards compatibility reasons, EVP_DigestSignInit_ex(), EVP_DigestSign(), EVP_DigestVerifyInit_ex() and EVP_DigestVerify() may also be used β€” but the digest passed in mdname must be NULL. Literally has to be NULL, don't come at me 😭


⭐ EXAMPLES ⭐

To sign a message using an SLH-DSA EVP_PKEY structure:

void do_sign(EVP_PKEY *key, unsigned char *msg, size_t msg_len)
{
    size_t sig_len;
    unsigned char *sig = NULL;
    const OSSL_PARAM params[] = {
        OSSL_PARAM_octet_string("context-string", (unsigned char *)"A context string", 33),
        OSSL_PARAM_END
    };
    EVP_PKEY_CTX *sctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL);
    EVP_SIGNATURE *sig_alg = EVP_SIGNATURE_fetch(NULL, "SLH-DSA-SHA2-128s", NULL);

    EVP_PKEY_sign_message_init(sctx, sig_alg, params);
    /* Calculate the required size for the signature by passing a NULL buffer. */
    EVP_PKEY_sign(sctx, NULL, &sig_len, msg, msg_len);
    sig = OPENSSL_zalloc(sig_len);
    EVP_PKEY_sign(sctx, sig, &sig_len, msg, msg_len);
    ...
    OPENSSL_free(sig);
    EVP_SIGNATURE(sig_alg);
    EVP_PKEY_CTX_free(sctx);
}

πŸ‘‘ SEE ALSO πŸ‘‘

EVP_PKEY-SLH-DSA(7) provider-signature(7), EVP_PKEY_sign(3), EVP_PKEY_verify(3)


🌈 HISTORY 🌈

This functionality was added in OpenSSL 3.5. New era fr fr ✨


Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved.

Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy in the file LICENSE in the source distribution or at <https://www.openssl.org/source/license.html>.


Okay that's the whole page, bestie β€” version 3.5.0, dated 2026-09-25, and it's the EVP_SIGNATURE-SLH-DSA(7ossl) page signing off πŸŽ€πŸ’…πŸ«Ά

πŸ“¦ where this page comes from