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