blob: 2de03f7ef6417da2b154b447a01c2cb664677e53 [file] [log] [blame]
Raef Coles8ff6df52021-07-21 12:42:15 +01001/**
2 * \file lms.h
3 *
4 * \brief This file provides an API for the LMS post-quantum-safe stateful-hash
5 * public-key signature scheme.
6 */
7/*
8 * Copyright The Mbed TLS Contributors
9 * SPDX-License-Identifier: Apache-2.0
10 *
11 * Licensed under the Apache License, Version 2.0 (the "License"); you may
12 * not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
14 *
15 * http://www.apache.org/licenses/LICENSE-2.0
16 *
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
19 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
22 */
23#ifndef MBEDTLS_LMS_H
24#define MBEDTLS_LMS_H
25
26#include <stdint.h>
27#include <stddef.h>
28
29#include "mbedtls/private_access.h"
30#include "mbedtls/lmots.h"
31
32#define MBEDTLS_ERR_LMS_BAD_INPUT_DATA -0x0011 /**< Bad data has been input to an LMS function */
33#define MBEDTLS_ERR_LMS_OUT_OF_PRIV_KEYS -0x0013 /**< Specified LMS key has utilised all of its private keys */
34#define MBEDTLS_ERR_LMS_VERIFY_FAILED -0x0015 /**< LMS signature verification failed */
35#define MBEDTLS_ERR_LMS_ALLOC_FAILED -0x0017 /**< LMS failed to allocate space for a private key */
36
37#define MBEDTLS_LMS_TYPE_LEN (4)
38#define MBEDTLS_LMS_H_TREE_HEIGHT (10)
39#define MBEDTLS_LMS_M_NODE_BYTES (32)
40
41#define MBEDTLS_LMS_SIG_LEN (MBEDTLS_LMOTS_Q_LEAF_ID_LEN + MBEDTLS_LMOTS_SIG_LEN + \
42 MBEDTLS_LMS_TYPE_LEN + MBEDTLS_LMS_H_TREE_HEIGHT * MBEDTLS_LMS_M_NODE_BYTES)
43
44#define MBEDTLS_LMS_PUBKEY_LEN (MBEDTLS_LMS_TYPE_LEN + MBEDTLS_LMOTS_TYPE_LEN + \
45 MBEDTLS_LMOTS_I_KEY_ID_LEN + MBEDTLS_LMS_M_NODE_BYTES)
46
47#define MBEDTLS_LMS_SIG_Q_LEAF_ID_OFFSET (0)
48#define MBEDTLS_LMS_SIG_OTS_SIG_OFFSET (MBEDTLS_LMS_SIG_Q_LEAF_ID_OFFSET + MBEDTLS_LMOTS_Q_LEAF_ID_LEN)
49#define MBEDTLS_LMS_SIG_TYPE_OFFSET (MBEDTLS_LMS_SIG_OTS_SIG_OFFSET + MBEDTLS_LMOTS_SIG_LEN)
50#define MBEDTLS_LMS_SIG_PATH_OFFSET (MBEDTLS_LMS_SIG_TYPE_OFFSET + MBEDTLS_LMS_TYPE_LEN)
51
52#define MBEDTLS_LMS_PUBKEY_TYPE_OFFSET (0)
53#define MBEDTLS_LMS_PUBKEY_OTSTYPE_OFFSET (MBEDTLS_LMS_PUBKEY_TYPE_OFFSET + MBEDTLS_LMS_TYPE_LEN)
54#define MBEDTLS_LMS_PUBKEY_I_KEY_ID_OFFSET (MBEDTLS_LMS_PUBKEY_OTSTYPE_OFFSET + MBEDTLS_LMOTS_TYPE_LEN)
55#define MBEDTLS_LMS_PUBKEY_ROOT_NODE_OFFSET (MBEDTLS_LMS_PUBKEY_I_KEY_ID_OFFSET + MBEDTLS_LMOTS_I_KEY_ID_LEN)
56
57#ifdef __cplusplus
58extern "C" {
59#endif
60
Raef Colesc4647462022-06-15 12:17:51 +010061/* https://www.iana.org/assignments/leighton-micali-signatures/leighton-micali-signatures.xhtml
62 * We are only implementing a subset of the types, particularly H10, for the sake of simplicty.
63 */
Raef Coles8ff6df52021-07-21 12:42:15 +010064typedef enum {
65 MBEDTLS_LMS_SHA256_M32_H10 = 0x6,
66} mbedtls_lms_algorithm_type_t;
67
68
69typedef struct {
Raef Colesc4647462022-06-15 12:17:51 +010070 unsigned char MBEDTLS_PRIVATE(have_privkey); /*!< Whether the context contains a private key.
71 Boolean values only. */
72 unsigned char MBEDTLS_PRIVATE(have_pubkey); /*!< Whether the context contains a public key.
73 Boolean values only. */
74 unsigned char MBEDTLS_PRIVATE(I_key_identifier)[MBEDTLS_LMOTS_I_KEY_ID_LEN]; /*!< The key
75 identifier. */
76 mbedtls_lms_algorithm_type_t MBEDTLS_PRIVATE(type); /*!< The LMS key type identifier as per
77 IANA. Only SHA256_M32_H10 is currently
78 supported. */
79 mbedtls_lmots_algorithm_type_t MBEDTLS_PRIVATE(otstype); /*!< The LM-OTS key type identifier as
80 per IANA. Only SHA256_N32_W8 is currently
81 supported. */
82 unsigned int MBEDTLS_PRIVATE(q_next_usable_key); /*!< The index of the next OTS key that has not
83 been used. */
84 mbedtls_lmots_context *MBEDTLS_PRIVATE(priv_keys); /*!< The private key material. One OTS key
85 for each leaf node in the merkle tree. */
86 unsigned char MBEDTLS_PRIVATE(T_1_pub_key)[MBEDTLS_LMS_M_NODE_BYTES]; /*!< The public key, in
87 the form of the merkle tree root node. */
Raef Coles8ff6df52021-07-21 12:42:15 +010088} mbedtls_lms_context;
89
90
91/**
92 * \brief This function initializes an LMS context
93 *
94 * \param ctx The uninitialized LMS context that will then be
95 * initialized.
96 */
97void mbedtls_lms_init( mbedtls_lms_context *ctx );
98
99/**
100 * \brief This function uninitializes an LMS context
101 *
102 * \param ctx The initialized LMS context that will then be
103 * uninitialized.
104 */
105void mbedtls_lms_free( mbedtls_lms_context *ctx );
106
107/**
108 * \brief This function sets the type of an LMS context
109 *
110 * \note The parameter set in the context will then be used
111 * for keygen operations etc.
112 *
113 * \param ctx The initialized LMS context.
114 * \param type The type that will be set in the context.
115 * \param otstype The type of the LMOTS implementation used by this
116 * context.
117 */
118int mbedtls_lms_set_algorithm_type( mbedtls_lms_context *ctx,
119 mbedtls_lms_algorithm_type_t type,
120 mbedtls_lmots_algorithm_type_t otstype);
121
122/**
123 * \brief This function creates a LMS signature, using a
124 * LMOTS context that contains a private key.
125 *
126 * \note Before this function is called, the context must
127 * have been initialized and must contain a private
128 * key.
129 *
130 * \note Each of the LMOTS private keys inside a LMS private
131 * key can only be used once. If they are reused, then
132 * attackers may be able to forge signatures with that
133 * key. This is all handled transparently, but it is
134 * important to not perform copy operations on LMS
135 * contexts that contain private key material.
136 *
137 * \param ctx The initialized LMS context from which the
138 * private key will be read.
139 * \param f_rng The RNG function to be used for signature
140 * generation.
141 * \param p_rng The RNG context to be passed to f_rng
142 * \param msg The buffer from which the message will be read.
143 * \param msg_len The size of the message that will be read.
144 * \param sig The buf into which the signature will be stored.
145 * Must be at least #MBEDTLS_LMOTS_SIG_LEN in size.
146 *
147 * \return \c 0 on success.
148 * \return A non-zero error code on failure.
149 */
150int mbedtls_lms_sign( mbedtls_lms_context *ctx,
151 int (*f_rng)(void *, unsigned char *, size_t),
152 void* p_rng, unsigned char *msg, unsigned int msg_len,
153 unsigned char *sig);
154
155/**
156 * \brief This function verifies a LMS signature, using a
157 * LMS context that contains a public key.
158 *
159 * \note Before this function is called, the context must
160 * have been initialized and must contain a public key
161 * (either by import or generation).
162 *
163 * \param ctx The initialized LMS context from which the public
164 * key will be read.
165 * \param msg The buffer from which the message will be read.
166 * \param msg_len The size of the message that will be read.
167 * \param sig The buf from which the signature will be read.
168 * #MBEDTLS_LMS_SIG_LEN bytes will be read from
169 * this.
170 *
171 * \return \c 0 on successful verification.
172 * \return A non-zero error code on failure.
173 */
174int mbedtls_lms_verify( const mbedtls_lms_context *ctx,
175 const unsigned char *msg, unsigned int msg_len,
176 const unsigned char *sig );
177
178/**
179 * \brief This function imports an LMOTS public key into a
180 * LMS context.
181 *
182 * \note Before this function is called, the context must
183 * have been initialized.
184 *
185 * \note See IETF RFC8554 for details of the encoding of
186 * this public key.
187 *
188 * \param ctx The initialized LMS context store the key in.
189 * \param key The buffer from which the key will be read.
190 * #MBEDTLS_LMS_PUBKEY_LEN bytes will be read from
191 * this.
192 *
193 * \return \c 0 on success.
194 * \return A non-zero error code on failure.
195 */
196int mbedtls_lms_import_pubkey( mbedtls_lms_context *ctx,
197 const unsigned char *key );
198
199/**
200 * \brief This function exports an LMOTS public key from a
201 * LMS context that already contains a public key.
202 *
203 * \note Before this function is called, the context must
204 * have been initialized and the context must contain
205 * a public key.
206 *
207 * \note See IETF RFC8554 for details of the encoding of
208 * this public key.
209 *
210 * \param ctx The initialized LMS context that contains the
211 * publc key.
212 * \param key The buffer into which the key will be output. Must
213 * be at least #MBEDTLS_LMS_PUBKEY_LEN in size.
214 *
215 * \return \c 0 on success.
216 * \return A non-zero error code on failure.
217 */
218int mbedtls_lms_export_pubkey( mbedtls_lms_context *ctx,
219 unsigned char *key );
220
221/**
222 * \brief This function generates an LMS public key from a
223 * LMS context that already contains a private key.
224 *
225 * \note Before this function is called, the context must
226 * have been initialized and the context must contain
227 * a private key.
228 *
229 * \param ctx The initialized LMS context to generate the key
230 * from and store it into.
231 *
232 * \return \c 0 on success.
233 * \return A non-zero error code on failure.
234 */
235int mbedtls_lms_gen_pubkey( mbedtls_lms_context *ctx );
236
237/**
238 * \brief This function generates an LMS private key, and
239 * stores in into an LMS context.
240 *
241 * \note Before this function is called, the context must
242 * have been initialized and the type of the LMS
243 * context set using mbedtls_lmots_set_algorithm_type
244 *
245 * \note The seed must have at least 256 bits of entropy.
246 *
247 * \param ctx The initialized LMOTS context to generate the key
248 * into.
249 * \param f_rng The RNG function to be used to generate the key ID.
250 * \param p_rng The RNG context to be passed to f_rng
251 * \param seed The seed used to deterministically generate the
252 * key.
253 * \param seed_len The length of the seed.
254 *
255 * \return \c 0 on success.
256 * \return A non-zero error code on failure.
257 */
258int mbedtls_lms_gen_privkey( mbedtls_lms_context *ctx,
259 int (*f_rng)(void *, unsigned char *, size_t),
260 void* p_rng, unsigned char *seed,
261 size_t seed_len );
262
263#ifdef __cplusplus
264}
265#endif
266
267#endif /* MBEDTLS_LMS_H */