1 /*
2  * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9 
10 /*
11  * Internal LMS/LM_OTS functions for other submodules,
12  * not for application use
13  */
14 
15 #ifndef OSSL_CRYPTO_LMS_H
16 # define OSSL_CRYPTO_LMS_H
17 # pragma once
18 # ifndef OPENSSL_NO_LMS
19 #  include "types.h"
20 #  include <openssl/params.h>
21 
22 /*
23  * Numeric identifiers associated with Leighton-Micali Signatures (LMS)
24  * parameter sets are defined in
25  * https://www.iana.org/assignments/leighton-micali-signatures/leighton-micali-signatures.xhtml
26  * which is referenced from SP800-208.
27  */
28 #  define OSSL_LMS_TYPE_SHA256_N32_H5   0x00000005
29 #  define OSSL_LMS_TYPE_SHA256_N32_H10  0x00000006
30 #  define OSSL_LMS_TYPE_SHA256_N32_H15  0x00000007
31 #  define OSSL_LMS_TYPE_SHA256_N32_H20  0x00000008
32 #  define OSSL_LMS_TYPE_SHA256_N32_H25  0x00000009
33 #  define OSSL_LMS_TYPE_SHA256_N24_H5   0x0000000A
34 #  define OSSL_LMS_TYPE_SHA256_N24_H10  0x0000000B
35 #  define OSSL_LMS_TYPE_SHA256_N24_H15  0x0000000C
36 #  define OSSL_LMS_TYPE_SHA256_N24_H20  0x0000000D
37 #  define OSSL_LMS_TYPE_SHA256_N24_H25  0x0000000E
38 #  define OSSL_LMS_TYPE_SHAKE_N32_H5    0x0000000F
39 #  define OSSL_LMS_TYPE_SHAKE_N32_H10   0x00000010
40 #  define OSSL_LMS_TYPE_SHAKE_N32_H15   0x00000011
41 #  define OSSL_LMS_TYPE_SHAKE_N32_H20   0x00000012
42 #  define OSSL_LMS_TYPE_SHAKE_N32_H25   0x00000013
43 #  define OSSL_LMS_TYPE_SHAKE_N24_H5    0x00000014
44 #  define OSSL_LMS_TYPE_SHAKE_N24_H10   0x00000015
45 #  define OSSL_LMS_TYPE_SHAKE_N24_H15   0x00000016
46 #  define OSSL_LMS_TYPE_SHAKE_N24_H20   0x00000017
47 #  define OSSL_LMS_TYPE_SHAKE_N24_H25   0x00000018
48 
49 #  define OSSL_LM_OTS_TYPE_SHA256_N32_W1 0x00000001
50 #  define OSSL_LM_OTS_TYPE_SHA256_N32_W2 0x00000002
51 #  define OSSL_LM_OTS_TYPE_SHA256_N32_W4 0x00000003
52 #  define OSSL_LM_OTS_TYPE_SHA256_N32_W8 0x00000004
53 #  define OSSL_LM_OTS_TYPE_SHA256_N24_W1 0x00000005
54 #  define OSSL_LM_OTS_TYPE_SHA256_N24_W2 0x00000006
55 #  define OSSL_LM_OTS_TYPE_SHA256_N24_W4 0x00000007
56 #  define OSSL_LM_OTS_TYPE_SHA256_N24_W8 0x00000008
57 #  define OSSL_LM_OTS_TYPE_SHAKE_N32_W1  0x00000009
58 #  define OSSL_LM_OTS_TYPE_SHAKE_N32_W2  0x0000000A
59 #  define OSSL_LM_OTS_TYPE_SHAKE_N32_W4  0x0000000B
60 #  define OSSL_LM_OTS_TYPE_SHAKE_N32_W8  0x0000000C
61 #  define OSSL_LM_OTS_TYPE_SHAKE_N24_W1  0x0000000D
62 #  define OSSL_LM_OTS_TYPE_SHAKE_N24_W2  0x0000000E
63 #  define OSSL_LM_OTS_TYPE_SHAKE_N24_W4  0x0000000F
64 #  define OSSL_LM_OTS_TYPE_SHAKE_N24_W8  0x00000010
65 
66 /* Constants used for verifying */
67 #  define LMS_SIZE_q 4
68 
69 /* XDR sizes when encoding and decoding */
70 #  define LMS_SIZE_I 16
71 #  define LMS_SIZE_LMS_TYPE 4
72 #  define LMS_SIZE_OTS_TYPE 4
73 #  define LMS_MAX_DIGEST_SIZE 32
74 #  define LMS_MAX_PUBKEY \
75     (LMS_SIZE_LMS_TYPE + LMS_SIZE_OTS_TYPE + LMS_SIZE_I + LMS_MAX_DIGEST_SIZE)
76 
77 /*
78  * Refer to RFC 8554 Section 4.1.
79  * See also lm_ots_params[]
80  */
81 typedef struct lm_ots_params_st {
82     /*
83      * The OTS type associates an id with a set of OTS parameters
84      * e.g. OSSL_LM_OTS_TYPE_SHAKE_N32_W1
85      */
86     uint32_t lm_ots_type;
87     uint32_t n;              /* Hash output size in bytes (32 or 24) */
88     /*
89      * The width of the Winternitz coefficients in bits. One of (1, 2, 4, 8)
90      * Higher values of w are slower (~2^w computations) but have smaller
91      * signatures.
92      */
93     uint32_t w;
94     /*
95      * The number of n-byte elements used for an LMOTS signature.
96      * One of (265, 133, 67, 34) for n = 32, for w=1,2,4,8
97      * One of (200, 101, 51, 26) for n = 24, for w=1,2,4,8
98      */
99     uint32_t p;
100     /*
101      * The size of the shift needed to move the checksum so
102      * that it appears in the checksum digits.
103      * See RFC 8554 Appendix B.  LM-OTS Parameter Options
104      */
105     uint32_t ls;
106     const char *digestname; /* Hash Name */
107 } LM_OTS_PARAMS;
108 
109 /* See lms_params[] */
110 typedef struct lms_params_st {
111     /*
112      * The lms type associates an id with a set of parameters to define the
113      * Digest and Height of a LMS tree.
114      * e.g, OSSL_LMS_TYPE_SHA256_N24_H25
115      */
116     uint32_t lms_type;
117     const char *digestname; /* One of SHA256, SHA256-192, or SHAKE256 */
118     uint32_t n; /* The Digest size (either 24 or 32), Useful for setting up SHAKE */
119     uint32_t h; /* The height of a LMS tree which is one of 5, 10, 15, 20, 25) */
120 } LMS_PARAMS;
121 
122 typedef struct lms_pub_key_st {
123     /*
124      * A buffer containing an encoded public key of the form
125      * u32str(lmstype) || u32str(otstype) || I[16] || K[n]
126      */
127     unsigned char *encoded;         /* encoded public key data */
128     size_t encodedlen;
129     /*
130      * K is the LMS tree's root public key (Called T(1))
131      * It is n bytes long (the hash size).
132      * It is a pointer into the encoded buffer
133      */
134     unsigned char *K;
135 } LMS_PUB_KEY;
136 
137 typedef struct lms_key_st {
138     const LMS_PARAMS *lms_params;
139     const LM_OTS_PARAMS *ots_params;
140     OSSL_LIB_CTX *libctx;
141     unsigned char *Id;        /* A pointer to 16 bytes (I[16]) */
142     LMS_PUB_KEY pub;
143 } LMS_KEY;
144 
145 const LMS_PARAMS *ossl_lms_params_get(uint32_t lms_type);
146 const LM_OTS_PARAMS *ossl_lm_ots_params_get(uint32_t ots_type);
147 
148 LMS_KEY *ossl_lms_key_new(OSSL_LIB_CTX *libctx);
149 void ossl_lms_key_free(LMS_KEY *lmskey);
150 int ossl_lms_key_equal(const LMS_KEY *key1, const LMS_KEY *key2, int selection);
151 int ossl_lms_key_valid(const LMS_KEY *key, int selection);
152 int ossl_lms_key_has(const LMS_KEY *key, int selection);
153 
154 int ossl_lms_pubkey_from_params(const OSSL_PARAM params[], LMS_KEY *lmskey);
155 int ossl_lms_pubkey_decode(const unsigned char *pub, size_t publen,
156                            LMS_KEY *lmskey);
157 size_t ossl_lms_pubkey_length(const unsigned char *data, size_t datalen);
158 
159 # endif /* OPENSSL_NO_LMS */
160 #endif /* OSSL_CRYPTO_LMS_H */
161