/* * Copyright 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 */ /* * Internal LMS/LM_OTS functions for other submodules, * not for application use */ #ifndef OSSL_CRYPTO_LMS_H #define OSSL_CRYPTO_LMS_H #pragma once #ifndef OPENSSL_NO_LMS #include "types.h" #include /* * Numeric identifiers associated with Leighton-Micali Signatures (LMS) * parameter sets are defined in * https://www.iana.org/assignments/leighton-micali-signatures/leighton-micali-signatures.xhtml * which is referenced from SP800-208. */ #define OSSL_LMS_TYPE_SHA256_N32_H5 0x00000005 #define OSSL_LMS_TYPE_SHA256_N32_H10 0x00000006 #define OSSL_LMS_TYPE_SHA256_N32_H15 0x00000007 #define OSSL_LMS_TYPE_SHA256_N32_H20 0x00000008 #define OSSL_LMS_TYPE_SHA256_N32_H25 0x00000009 #define OSSL_LMS_TYPE_SHA256_N24_H5 0x0000000A #define OSSL_LMS_TYPE_SHA256_N24_H10 0x0000000B #define OSSL_LMS_TYPE_SHA256_N24_H15 0x0000000C #define OSSL_LMS_TYPE_SHA256_N24_H20 0x0000000D #define OSSL_LMS_TYPE_SHA256_N24_H25 0x0000000E #define OSSL_LMS_TYPE_SHAKE_N32_H5 0x0000000F #define OSSL_LMS_TYPE_SHAKE_N32_H10 0x00000010 #define OSSL_LMS_TYPE_SHAKE_N32_H15 0x00000011 #define OSSL_LMS_TYPE_SHAKE_N32_H20 0x00000012 #define OSSL_LMS_TYPE_SHAKE_N32_H25 0x00000013 #define OSSL_LMS_TYPE_SHAKE_N24_H5 0x00000014 #define OSSL_LMS_TYPE_SHAKE_N24_H10 0x00000015 #define OSSL_LMS_TYPE_SHAKE_N24_H15 0x00000016 #define OSSL_LMS_TYPE_SHAKE_N24_H20 0x00000017 #define OSSL_LMS_TYPE_SHAKE_N24_H25 0x00000018 #define OSSL_LM_OTS_TYPE_SHA256_N32_W1 0x00000001 #define OSSL_LM_OTS_TYPE_SHA256_N32_W2 0x00000002 #define OSSL_LM_OTS_TYPE_SHA256_N32_W4 0x00000003 #define OSSL_LM_OTS_TYPE_SHA256_N32_W8 0x00000004 #define OSSL_LM_OTS_TYPE_SHA256_N24_W1 0x00000005 #define OSSL_LM_OTS_TYPE_SHA256_N24_W2 0x00000006 #define OSSL_LM_OTS_TYPE_SHA256_N24_W4 0x00000007 #define OSSL_LM_OTS_TYPE_SHA256_N24_W8 0x00000008 #define OSSL_LM_OTS_TYPE_SHAKE_N32_W1 0x00000009 #define OSSL_LM_OTS_TYPE_SHAKE_N32_W2 0x0000000A #define OSSL_LM_OTS_TYPE_SHAKE_N32_W4 0x0000000B #define OSSL_LM_OTS_TYPE_SHAKE_N32_W8 0x0000000C #define OSSL_LM_OTS_TYPE_SHAKE_N24_W1 0x0000000D #define OSSL_LM_OTS_TYPE_SHAKE_N24_W2 0x0000000E #define OSSL_LM_OTS_TYPE_SHAKE_N24_W4 0x0000000F #define OSSL_LM_OTS_TYPE_SHAKE_N24_W8 0x00000010 /* Constants used for verifying */ #define LMS_SIZE_q 4 /* XDR sizes when encoding and decoding */ #define LMS_SIZE_I 16 #define LMS_SIZE_LMS_TYPE 4 #define LMS_SIZE_OTS_TYPE 4 #define LMS_MAX_DIGEST_SIZE 32 #define LMS_MAX_PUBKEY \ (LMS_SIZE_LMS_TYPE + LMS_SIZE_OTS_TYPE + LMS_SIZE_I + LMS_MAX_DIGEST_SIZE) /* * Refer to RFC 8554 Section 4.1. * See also lm_ots_params[] */ typedef struct lm_ots_params_st { /* * The OTS type associates an id with a set of OTS parameters * e.g. OSSL_LM_OTS_TYPE_SHAKE_N32_W1 */ uint32_t lm_ots_type; uint32_t n; /* Hash output size in bytes (32 or 24) */ /* * The width of the Winternitz coefficients in bits. One of (1, 2, 4, 8) * Higher values of w are slower (~2^w computations) but have smaller * signatures. */ uint32_t w; /* * The number of n-byte elements used for an LMOTS signature. * One of (265, 133, 67, 34) for n = 32, for w=1,2,4,8 * One of (200, 101, 51, 26) for n = 24, for w=1,2,4,8 */ uint32_t p; /* * The size of the shift needed to move the checksum so * that it appears in the checksum digits. * See RFC 8554 Appendix B. LM-OTS Parameter Options */ uint32_t ls; const char *digestname; /* Hash Name */ } LM_OTS_PARAMS; /* See lms_params[] */ typedef struct lms_params_st { /* * The lms type associates an id with a set of parameters to define the * Digest and Height of a LMS tree. * e.g, OSSL_LMS_TYPE_SHA256_N24_H25 */ uint32_t lms_type; const char *digestname; /* One of SHA256, SHA256-192, or SHAKE256 */ uint32_t n; /* The Digest size (either 24 or 32), Useful for setting up SHAKE */ uint32_t h; /* The height of a LMS tree which is one of 5, 10, 15, 20, 25) */ } LMS_PARAMS; typedef struct lms_pub_key_st { /* * A buffer containing an encoded public key of the form * u32str(lmstype) || u32str(otstype) || I[16] || K[n] */ unsigned char *encoded; /* encoded public key data */ size_t encodedlen; /* * K is the LMS tree's root public key (Called T(1)) * It is n bytes long (the hash size). * It is a pointer into the encoded buffer */ unsigned char *K; } LMS_PUB_KEY; typedef struct lms_key_st { const LMS_PARAMS *lms_params; const LM_OTS_PARAMS *ots_params; OSSL_LIB_CTX *libctx; unsigned char *Id; /* A pointer to 16 bytes (I[16]) */ LMS_PUB_KEY pub; } LMS_KEY; const LMS_PARAMS *ossl_lms_params_get(uint32_t lms_type); const LM_OTS_PARAMS *ossl_lm_ots_params_get(uint32_t ots_type); LMS_KEY *ossl_lms_key_new(OSSL_LIB_CTX *libctx); void ossl_lms_key_free(LMS_KEY *lmskey); int ossl_lms_key_equal(const LMS_KEY *key1, const LMS_KEY *key2, int selection); int ossl_lms_key_valid(const LMS_KEY *key, int selection); int ossl_lms_key_has(const LMS_KEY *key, int selection); int ossl_lms_pubkey_from_params(const OSSL_PARAM *pub, LMS_KEY *lmskey); int ossl_lms_pubkey_decode(const unsigned char *pub, size_t publen, LMS_KEY *lmskey); size_t ossl_lms_pubkey_length(const unsigned char *data, size_t datalen); #endif /* OPENSSL_NO_LMS */ #endif /* OSSL_CRYPTO_LMS_H */