1 /**
2  * \file lmots.h
3  *
4  * \brief This file provides an API for the LM-OTS post-quantum-safe one-time
5  *        public-key signature scheme as defined in RFC8554 and NIST.SP.200-208.
6  *        This implementation currently only supports a single parameter set
7  *        MBEDTLS_LMOTS_SHA256_N32_W8 in order to reduce complexity.
8  */
9 /*
10  *  Copyright The Mbed TLS Contributors
11  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
12  */
13 
14 #ifndef MBEDTLS_LMOTS_H
15 #define MBEDTLS_LMOTS_H
16 
17 #include "mbedtls/build_info.h"
18 
19 #include "psa/crypto.h"
20 
21 #include "mbedtls/lms.h"
22 
23 #include <stdint.h>
24 #include <stddef.h>
25 
26 
27 #define MBEDTLS_LMOTS_PUBLIC_KEY_LEN(type) (MBEDTLS_LMOTS_TYPE_LEN + \
28                                             MBEDTLS_LMOTS_I_KEY_ID_LEN + \
29                                             MBEDTLS_LMOTS_Q_LEAF_ID_LEN + \
30                                             MBEDTLS_LMOTS_N_HASH_LEN(type))
31 
32 #define MBEDTLS_LMOTS_SIG_TYPE_OFFSET       (0)
33 #define MBEDTLS_LMOTS_SIG_C_RANDOM_OFFSET (MBEDTLS_LMOTS_SIG_TYPE_OFFSET + \
34                                            MBEDTLS_LMOTS_TYPE_LEN)
35 #define MBEDTLS_LMOTS_SIG_SIGNATURE_OFFSET(type) (MBEDTLS_LMOTS_SIG_C_RANDOM_OFFSET + \
36                                                   MBEDTLS_LMOTS_C_RANDOM_VALUE_LEN(type))
37 
38 #ifdef __cplusplus
39 extern "C" {
40 #endif
41 
42 
43 #if defined(MBEDTLS_TEST_HOOKS)
44 extern int (*mbedtls_lmots_sign_private_key_invalidated_hook)(unsigned char *);
45 #endif /* defined(MBEDTLS_TEST_HOOKS) */
46 
47 /**
48  * \brief                    This function converts an unsigned int into a
49  *                           network-byte-order (big endian) string.
50  *
51  * \param val                The unsigned integer value
52  * \param len                The length of the string.
53  * \param bytes              The string to output into.
54  */
55 void mbedtls_lms_unsigned_int_to_network_bytes(unsigned int val, size_t len,
56                                                unsigned char *bytes);
57 
58 /**
59  * \brief                    This function converts a network-byte-order
60  *                           (big endian) string into an unsigned integer.
61  *
62  * \param len                The length of the string.
63  * \param bytes              The string.
64  *
65  * \return                   The corresponding LMS error code.
66  */
67 unsigned int mbedtls_lms_network_bytes_to_unsigned_int(size_t len,
68                                                        const unsigned char *bytes);
69 
70 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
71 /**
72  * \brief                    This function converts a \ref psa_status_t to a
73  *                           low-level LMS error code.
74  *
75  * \param status             The psa_status_t to convert
76  *
77  * \return                   The corresponding LMS error code.
78  */
79 int MBEDTLS_DEPRECATED mbedtls_lms_error_from_psa(psa_status_t status);
80 #endif
81 
82 /**
83  * \brief                    This function initializes a public LMOTS context
84  *
85  * \param ctx                The uninitialized LMOTS context that will then be
86  *                           initialized.
87  */
88 void mbedtls_lmots_public_init(mbedtls_lmots_public_t *ctx);
89 
90 /**
91  * \brief                    This function uninitializes a public LMOTS context
92  *
93  * \param ctx                The initialized LMOTS context that will then be
94  *                           uninitialized.
95  */
96 void mbedtls_lmots_public_free(mbedtls_lmots_public_t *ctx);
97 
98 /**
99  * \brief                    This function imports an LMOTS public key into a
100  *                           LMOTS context.
101  *
102  * \note                     Before this function is called, the context must
103  *                           have been initialized.
104  *
105  * \note                     See IETF RFC8554 for details of the encoding of
106  *                           this public key.
107  *
108  * \param ctx                The initialized LMOTS context store the key in.
109  * \param key                The buffer from which the key will be read.
110  *                           #MBEDTLS_LMOTS_PUBLIC_KEY_LEN bytes will be read
111  *                           from this.
112  *
113  * \return         \c 0 on success.
114  * \return         A non-zero error code on failure.
115  */
116 int mbedtls_lmots_import_public_key(mbedtls_lmots_public_t *ctx,
117                                     const unsigned char *key, size_t key_size);
118 
119 /**
120  * \brief                    This function exports an LMOTS public key from a
121  *                           LMOTS context that already contains a public key.
122  *
123  * \note                     Before this function is called, the context must
124  *                           have been initialized and the context must contain
125  *                           a public key.
126  *
127  * \note                     See IETF RFC8554 for details of the encoding of
128  *                           this public key.
129  *
130  * \param ctx                The initialized LMOTS context that contains the
131  *                           public key.
132  * \param key                The buffer into which the key will be output. Must
133  *                           be at least #MBEDTLS_LMOTS_PUBLIC_KEY_LEN in size.
134  *
135  * \return         \c 0 on success.
136  * \return         A non-zero error code on failure.
137  */
138 int mbedtls_lmots_export_public_key(const mbedtls_lmots_public_t *ctx,
139                                     unsigned char *key, size_t key_size,
140                                     size_t *key_len);
141 
142 /**
143  * \brief                    This function creates a candidate public key from
144  *                           an LMOTS signature. This can then be compared to
145  *                           the real public key to determine the validity of
146  *                           the signature.
147  *
148  * \note                     This function is exposed publicly to be used in LMS
149  *                           signature verification, it is expected that
150  *                           mbedtls_lmots_verify will be used for LMOTS
151  *                           signature verification.
152  *
153  * \param params             The LMOTS parameter set, q and I values as an
154  *                           mbedtls_lmots_parameters_t struct.
155  * \param msg                The buffer from which the message will be read.
156  * \param msg_size           The size of the message that will be read.
157  * \param sig                The buffer from which the signature will be read.
158  *                           #MBEDTLS_LMOTS_SIG_LEN bytes will be read from
159  *                           this.
160  * \param out                The buffer where the candidate public key will be
161  *                           stored. Must be at least #MBEDTLS_LMOTS_N_HASH_LEN
162  *                           bytes in size.
163  *
164  * \return         \c 0 on success.
165  * \return         A non-zero error code on failure.
166  */
167 int mbedtls_lmots_calculate_public_key_candidate(const mbedtls_lmots_parameters_t *params,
168                                                  const unsigned char *msg,
169                                                  size_t msg_size,
170                                                  const unsigned char *sig,
171                                                  size_t sig_size,
172                                                  unsigned char *out,
173                                                  size_t out_size,
174                                                  size_t *out_len);
175 
176 /**
177  * \brief                    This function verifies a LMOTS signature, using a
178  *                           LMOTS context that contains a public key.
179  *
180  * \warning                  This function is **not intended for use in
181  *                           production**, due to as-yet unsolved problems with
182  *                           handling stateful keys. The API for this function
183  *                           may change considerably in future versions.
184  *
185  * \note                     Before this function is called, the context must
186  *                           have been initialized and must contain a public key
187  *                           (either by import or calculation from a private
188  *                           key).
189  *
190  * \param ctx                The initialized LMOTS context from which the public
191  *                           key will be read.
192  * \param msg                The buffer from which the message will be read.
193  * \param msg_size           The size of the message that will be read.
194  * \param sig                The buf from which the signature will be read.
195  *                           #MBEDTLS_LMOTS_SIG_LEN bytes will be read from
196  *                           this.
197  *
198  * \return         \c 0 on successful verification.
199  * \return         A non-zero error code on failure.
200  */
201 int mbedtls_lmots_verify(const mbedtls_lmots_public_t *ctx,
202                          const unsigned char *msg,
203                          size_t msg_size, const unsigned char *sig,
204                          size_t sig_size);
205 
206 #if defined(MBEDTLS_LMS_PRIVATE)
207 
208 /**
209  * \brief                    This function initializes a private LMOTS context
210  *
211  * \param ctx                The uninitialized LMOTS context that will then be
212  *                           initialized.
213  */
214 void mbedtls_lmots_private_init(mbedtls_lmots_private_t *ctx);
215 
216 /**
217  * \brief                    This function uninitializes a private LMOTS context
218  *
219  * \param ctx                The initialized LMOTS context that will then be
220  *                           uninitialized.
221  */
222 void mbedtls_lmots_private_free(mbedtls_lmots_private_t *ctx);
223 
224 /**
225  * \brief                    This function calculates an LMOTS private key, and
226  *                           stores in into an LMOTS context.
227  *
228  * \warning                  This function is **not intended for use in
229  *                           production**, due to as-yet unsolved problems with
230  *                           handling stateful keys. The API for this function
231  *                           may change considerably in future versions.
232  *
233  * \note                     The seed must have at least 256 bits of entropy.
234  *
235  * \param ctx                The initialized LMOTS context to generate the key
236  *                           into.
237  * \param I_key_identifier   The key identifier of the key, as a 16-byte string.
238  * \param q_leaf_identifier  The leaf identifier of key. If this LMOTS key is
239  *                           not being used as part of an LMS key, this should
240  *                           be set to 0.
241  * \param seed               The seed used to deterministically generate the
242  *                           key.
243  * \param seed_size          The length of the seed.
244  *
245  * \return         \c 0 on success.
246  * \return         A non-zero error code on failure.
247  */
248 int mbedtls_lmots_generate_private_key(mbedtls_lmots_private_t *ctx,
249                                        mbedtls_lmots_algorithm_type_t type,
250                                        const unsigned char I_key_identifier[MBEDTLS_LMOTS_I_KEY_ID_LEN],
251                                        uint32_t q_leaf_identifier,
252                                        const unsigned char *seed,
253                                        size_t seed_size);
254 
255 /**
256  * \brief                    This function generates an LMOTS public key from a
257  *                           LMOTS context that already contains a private key.
258  *
259  * \note                     Before this function is called, the context must
260  *                           have been initialized and the context must contain
261  *                           a private key.
262  *
263  * \param ctx                The initialized LMOTS context to generate the key
264  *                           from and store it into.
265  *
266  * \return         \c 0 on success.
267  * \return         A non-zero error code on failure.
268  */
269 int mbedtls_lmots_calculate_public_key(mbedtls_lmots_public_t *ctx,
270                                        const mbedtls_lmots_private_t *priv_ctx);
271 
272 /**
273  * \brief                    This function creates a LMOTS signature, using a
274  *                           LMOTS context that contains a private key.
275  *
276  * \note                     Before this function is called, the context must
277  *                           have been initialized and must contain a private
278  *                           key.
279  *
280  * \note                     LMOTS private keys can only be used once, otherwise
281  *                           attackers may be able to create forged signatures.
282  *                           If the signing operation is successful, the private
283  *                           key in the context will be erased, and no further
284  *                           signing will be possible until another private key
285  *                           is loaded
286  *
287  * \param ctx                The initialized LMOTS context from which the
288  *                           private key will be read.
289  * \param f_rng              The RNG function to be used for signature
290  *                           generation.
291  * \param p_rng              The RNG context to be passed to f_rng
292  * \param msg                The buffer from which the message will be read.
293  * \param msg_size           The size of the message that will be read.
294  * \param sig                The buf into which the signature will be stored.
295  *                           Must be at least #MBEDTLS_LMOTS_SIG_LEN in size.
296  *
297  * \return         \c 0 on success.
298  * \return         A non-zero error code on failure.
299  */
300 int mbedtls_lmots_sign(mbedtls_lmots_private_t *ctx,
301                        int (*f_rng)(void *, unsigned char *, size_t),
302                        void *p_rng, const unsigned char *msg, size_t msg_size,
303                        unsigned char *sig, size_t sig_size, size_t *sig_len);
304 
305 #endif /* defined(MBEDTLS_LMS_PRIVATE) */
306 
307 #ifdef __cplusplus
308 }
309 #endif
310 
311 #endif /* MBEDTLS_LMOTS_H */
312