1 /** 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 as defined in RFC8554 and NIST.SP.200-208. 6 * This implementation currently only supports a single parameter set 7 * MBEDTLS_LMS_SHA256_M32_H10 in order to reduce complexity. This is one 8 * of the signature schemes recommended by the IETF draft SUIT standard 9 * for IOT firmware upgrades (RFC9019). 10 */ 11 /* 12 * Copyright The Mbed TLS Contributors 13 * SPDX-License-Identifier: Apache-2.0 14 * 15 * Licensed under the Apache License, Version 2.0 (the "License"); you may 16 * not use this file except in compliance with the License. 17 * You may obtain a copy of the License at 18 * 19 * http://www.apache.org/licenses/LICENSE-2.0 20 * 21 * Unless required by applicable law or agreed to in writing, software 22 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 23 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 24 * See the License for the specific language governing permissions and 25 * limitations under the License. 26 */ 27 #ifndef MBEDTLS_LMS_H 28 #define MBEDTLS_LMS_H 29 30 #include <stdint.h> 31 #include <stddef.h> 32 33 #include "mbedtls/private_access.h" 34 #include "mbedtls/build_info.h" 35 36 #define MBEDTLS_ERR_LMS_BAD_INPUT_DATA -0x0011 /**< Bad data has been input to an LMS function */ 37 #define MBEDTLS_ERR_LMS_OUT_OF_PRIVATE_KEYS -0x0013 /**< Specified LMS key has utilised all of its private keys */ 38 #define MBEDTLS_ERR_LMS_VERIFY_FAILED -0x0015 /**< LMS signature verification failed */ 39 #define MBEDTLS_ERR_LMS_ALLOC_FAILED -0x0017 /**< LMS failed to allocate space for a private key */ 40 #define MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL -0x0019 /**< Input/output buffer is too small to contain requited data */ 41 42 /* Currently only defined for SHA256, 32 is the max hash output size */ 43 #define MBEDTLS_LMOTS_N_HASH_LEN_MAX (32u) 44 #define MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT_MAX (34u) 45 #define MBEDTLS_LMOTS_N_HASH_LEN(type) ((type) == MBEDTLS_LMOTS_SHA256_N32_W8 ? 32u : 0) 46 #define MBEDTLS_LMOTS_I_KEY_ID_LEN (16u) 47 #define MBEDTLS_LMOTS_Q_LEAF_ID_LEN (4u) 48 #define MBEDTLS_LMOTS_TYPE_LEN (4u) 49 #define MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT(type) ((type) == MBEDTLS_LMOTS_SHA256_N32_W8 ? 34u : 0) 50 #define MBEDTLS_LMOTS_C_RANDOM_VALUE_LEN(type) (MBEDTLS_LMOTS_N_HASH_LEN(type)) 51 52 #define MBEDTLS_LMOTS_SIG_LEN(type) (MBEDTLS_LMOTS_TYPE_LEN + \ 53 MBEDTLS_LMOTS_C_RANDOM_VALUE_LEN(type) + \ 54 (MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT(type) * \ 55 MBEDTLS_LMOTS_N_HASH_LEN(type))) 56 57 58 #define MBEDTLS_LMS_TYPE_LEN (4) 59 #define MBEDTLS_LMS_H_TREE_HEIGHT(type) ((type) == MBEDTLS_LMS_SHA256_M32_H10 ? 10u : 0) 60 61 /* The length of a hash output, Currently only implemented for SHA256. 62 * Max is 32 bytes. 63 */ 64 #define MBEDTLS_LMS_M_NODE_BYTES(type) ((type) == MBEDTLS_LMS_SHA256_M32_H10 ? 32 : 0) 65 #define MBEDTLS_LMS_M_NODE_BYTES_MAX 32 66 67 #define MBEDTLS_LMS_SIG_LEN(type, otstype) (MBEDTLS_LMOTS_Q_LEAF_ID_LEN + \ 68 MBEDTLS_LMOTS_SIG_LEN(otstype) + \ 69 MBEDTLS_LMS_TYPE_LEN + \ 70 (MBEDTLS_LMS_H_TREE_HEIGHT(type) * \ 71 MBEDTLS_LMS_M_NODE_BYTES(type))) 72 73 #define MBEDTLS_LMS_PUBLIC_KEY_LEN(type) (MBEDTLS_LMS_TYPE_LEN + \ 74 MBEDTLS_LMOTS_TYPE_LEN + \ 75 MBEDTLS_LMOTS_I_KEY_ID_LEN + \ 76 MBEDTLS_LMS_M_NODE_BYTES(type)) 77 78 79 #ifdef __cplusplus 80 extern "C" { 81 #endif 82 83 /** The Identifier of the LMS parameter set, as per 84 * https://www.iana.org/assignments/leighton-micali-signatures/leighton-micali-signatures.xhtml 85 * We are only implementing a subset of the types, particularly H10, for the sake of simplicity. 86 */ 87 typedef enum { 88 MBEDTLS_LMS_SHA256_M32_H10 = 0x6, 89 } mbedtls_lms_algorithm_type_t; 90 91 /** The Identifier of the LMOTS parameter set, as per 92 * https://www.iana.org/assignments/leighton-micali-signatures/leighton-micali-signatures.xhtml. 93 * We are only implementing a subset of the types, particularly N32_W8, for the sake of simplicity. 94 */ 95 typedef enum { 96 MBEDTLS_LMOTS_SHA256_N32_W8 = 4 97 } mbedtls_lmots_algorithm_type_t; 98 99 /** LMOTS parameters structure. 100 * 101 * This contains the metadata associated with an LMOTS key, detailing the 102 * algorithm type, the key ID, and the leaf identifier should be key be part of 103 * a LMS key. 104 */ 105 typedef struct { 106 unsigned char MBEDTLS_PRIVATE(I_key_identifier[MBEDTLS_LMOTS_I_KEY_ID_LEN]); /*!< The key 107 identifier. */ 108 unsigned char MBEDTLS_PRIVATE(q_leaf_identifier[MBEDTLS_LMOTS_Q_LEAF_ID_LEN]); /*!< Which 109 leaf of the LMS key this is. 110 0 if the key is not part of an LMS key. */ 111 mbedtls_lmots_algorithm_type_t MBEDTLS_PRIVATE(type); /*!< The LM-OTS key type identifier as 112 per IANA. Only SHA256_N32_W8 is 113 currently supported. */ 114 } mbedtls_lmots_parameters_t; 115 116 /** LMOTS public context structure. 117 * 118 * A LMOTS public key is a hash output, and the applicable parameter set. 119 * 120 * The context must be initialized before it is used. A public key must either 121 * be imported or generated from a private context. 122 * 123 * \dot 124 * digraph lmots_public_t { 125 * UNINITIALIZED -> INIT [label="init"]; 126 * HAVE_PUBLIC_KEY -> INIT [label="free"]; 127 * INIT -> HAVE_PUBLIC_KEY [label="import_public_key"]; 128 * INIT -> HAVE_PUBLIC_KEY [label="calculate_public_key from private key"]; 129 * HAVE_PUBLIC_KEY -> HAVE_PUBLIC_KEY [label="export_public_key"]; 130 * } 131 * \enddot 132 */ 133 typedef struct { 134 mbedtls_lmots_parameters_t MBEDTLS_PRIVATE(params); 135 unsigned char MBEDTLS_PRIVATE(public_key)[MBEDTLS_LMOTS_N_HASH_LEN_MAX]; 136 unsigned char MBEDTLS_PRIVATE(have_public_key); /*!< Whether the context contains a public key. 137 Boolean values only. */ 138 } mbedtls_lmots_public_t; 139 140 #if defined(MBEDTLS_LMS_PRIVATE) 141 /** LMOTS private context structure. 142 * 143 * A LMOTS private key is one hash output for each of digit of the digest + 144 * checksum, and the applicable parameter set. 145 * 146 * The context must be initialized before it is used. A public key must either 147 * be imported or generated from a private context. 148 * 149 * \dot 150 * digraph lmots_public_t { 151 * UNINITIALIZED -> INIT [label="init"]; 152 * HAVE_PRIVATE_KEY -> INIT [label="free"]; 153 * INIT -> HAVE_PRIVATE_KEY [label="generate_private_key"]; 154 * HAVE_PRIVATE_KEY -> INIT [label="sign"]; 155 * } 156 * \enddot 157 */ 158 typedef struct { 159 mbedtls_lmots_parameters_t MBEDTLS_PRIVATE(params); 160 unsigned char MBEDTLS_PRIVATE(private_key)[MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT_MAX][MBEDTLS_LMOTS_N_HASH_LEN_MAX]; 161 unsigned char MBEDTLS_PRIVATE(have_private_key); /*!< Whether the context contains a private key. 162 Boolean values only. */ 163 } mbedtls_lmots_private_t; 164 #endif /* defined(MBEDTLS_LMS_PRIVATE) */ 165 166 167 /** LMS parameters structure. 168 * 169 * This contains the metadata associated with an LMS key, detailing the 170 * algorithm type, the type of the underlying OTS algorithm, and the key ID. 171 */ 172 typedef struct { 173 unsigned char MBEDTLS_PRIVATE(I_key_identifier[MBEDTLS_LMOTS_I_KEY_ID_LEN]); /*!< The key 174 identifier. */ 175 mbedtls_lmots_algorithm_type_t MBEDTLS_PRIVATE(otstype); /*!< The LM-OTS key type identifier as 176 per IANA. Only SHA256_N32_W8 is 177 currently supported. */ 178 mbedtls_lms_algorithm_type_t MBEDTLS_PRIVATE(type); /*!< The LMS key type identifier as per 179 IANA. Only SHA256_M32_H10 is currently 180 supported. */ 181 } mbedtls_lms_parameters_t; 182 183 /** LMS public context structure. 184 * 185 *A LMS public key is the hash output that is the root of the Merkle tree, and 186 * the applicable parameter set 187 * 188 * The context must be initialized before it is used. A public key must either 189 * be imported or generated from a private context. 190 * 191 * \dot 192 * digraph lms_public_t { 193 * UNINITIALIZED -> INIT [label="init"]; 194 * HAVE_PUBLIC_KEY -> INIT [label="free"]; 195 * INIT -> HAVE_PUBLIC_KEY [label="import_public_key"]; 196 * INIT -> HAVE_PUBLIC_KEY [label="calculate_public_key from private key"]; 197 * HAVE_PUBLIC_KEY -> HAVE_PUBLIC_KEY [label="export_public_key"]; 198 * } 199 * \enddot 200 */ 201 typedef struct { 202 mbedtls_lms_parameters_t MBEDTLS_PRIVATE(params); 203 unsigned char MBEDTLS_PRIVATE(T_1_pub_key)[MBEDTLS_LMS_M_NODE_BYTES_MAX]; /*!< The public key, in 204 the form of the Merkle tree root node. */ 205 unsigned char MBEDTLS_PRIVATE(have_public_key); /*!< Whether the context contains a public key. 206 Boolean values only. */ 207 } mbedtls_lms_public_t; 208 209 210 #if defined(MBEDTLS_LMS_PRIVATE) 211 /** LMS private context structure. 212 * 213 * A LMS private key is a set of LMOTS private keys, an index to the next usable 214 * key, and the applicable parameter set. 215 * 216 * The context must be initialized before it is used. A public key must either 217 * be imported or generated from a private context. 218 * 219 * \dot 220 * digraph lms_public_t { 221 * UNINITIALIZED -> INIT [label="init"]; 222 * HAVE_PRIVATE_KEY -> INIT [label="free"]; 223 * INIT -> HAVE_PRIVATE_KEY [label="generate_private_key"]; 224 * } 225 * \enddot 226 */ 227 typedef struct { 228 mbedtls_lms_parameters_t MBEDTLS_PRIVATE(params); 229 uint32_t MBEDTLS_PRIVATE(q_next_usable_key); /*!< The index of the next OTS key that has not 230 been used. */ 231 mbedtls_lmots_private_t *MBEDTLS_PRIVATE(ots_private_keys); /*!< The private key material. One OTS key 232 for each leaf node in the Merkle tree. NULL 233 when have_private_key is 0 and non-NULL otherwise. 234 is 2^MBEDTLS_LMS_H_TREE_HEIGHT(type) in length. */ 235 mbedtls_lmots_public_t *MBEDTLS_PRIVATE(ots_public_keys); /*!< The OTS key public keys, used to 236 build the Merkle tree. NULL 237 when have_private_key is 0 and 238 non-NULL otherwise. 239 Is 2^MBEDTLS_LMS_H_TREE_HEIGHT(type) 240 in length. */ 241 unsigned char MBEDTLS_PRIVATE(have_private_key); /*!< Whether the context contains a private key. 242 Boolean values only. */ 243 } mbedtls_lms_private_t; 244 #endif /* defined(MBEDTLS_LMS_PRIVATE) */ 245 246 /** 247 * \brief This function initializes an LMS public context 248 * 249 * \param ctx The uninitialized LMS context that will then be 250 * initialized. 251 */ 252 void mbedtls_lms_public_init( mbedtls_lms_public_t *ctx ); 253 254 /** 255 * \brief This function uninitializes an LMS public context 256 * 257 * \param ctx The initialized LMS context that will then be 258 * uninitialized. 259 */ 260 void mbedtls_lms_public_free( mbedtls_lms_public_t *ctx ); 261 262 /** 263 * \brief This function imports an LMS public key into a 264 * public LMS context. 265 * 266 * \note Before this function is called, the context must 267 * have been initialized. 268 * 269 * \note See IETF RFC8554 for details of the encoding of 270 * this public key. 271 * 272 * \param ctx The initialized LMS context store the key in. 273 * \param key The buffer from which the key will be read. 274 * #MBEDTLS_LMS_PUBLIC_KEY_LEN bytes will be read from 275 * this. 276 * \param key_size The size of the key being imported. 277 * 278 * \return \c 0 on success. 279 * \return A non-zero error code on failure. 280 */ 281 int mbedtls_lms_import_public_key( mbedtls_lms_public_t *ctx, 282 const unsigned char *key, size_t key_size ); 283 284 /** 285 * \brief This function exports an LMS public key from a 286 * LMS public context that already contains a public 287 * key. 288 * 289 * \note Before this function is called, the context must 290 * have been initialized and the context must contain 291 * a public key. 292 * 293 * \note See IETF RFC8554 for details of the encoding of 294 * this public key. 295 * 296 * \param ctx The initialized LMS public context that contains 297 * the public key. 298 * \param key The buffer into which the key will be output. Must 299 * be at least #MBEDTLS_LMS_PUBLIC_KEY_LEN in size. 300 * \param key_size The size of the key buffer. 301 * \param key_len If not NULL, will be written with the size of the 302 * key. 303 * 304 * \return \c 0 on success. 305 * \return A non-zero error code on failure. 306 */ 307 int mbedtls_lms_export_public_key( const mbedtls_lms_public_t *ctx, 308 unsigned char *key, size_t key_size, 309 size_t *key_len ); 310 311 /** 312 * \brief This function verifies a LMS signature, using a 313 * LMS context that contains a public key. 314 * 315 * \note Before this function is called, the context must 316 * have been initialized and must contain a public key 317 * (either by import or generation). 318 * 319 * \param ctx The initialized LMS public context from which the 320 * public key will be read. 321 * \param msg The buffer from which the message will be read. 322 * \param msg_size The size of the message that will be read. 323 * \param sig The buf from which the signature will be read. 324 * #MBEDTLS_LMS_SIG_LEN bytes will be read from 325 * this. 326 * \param sig_size The size of the signature to be verified. 327 * 328 * \return \c 0 on successful verification. 329 * \return A non-zero error code on failure. 330 */ 331 int mbedtls_lms_verify( const mbedtls_lms_public_t *ctx, 332 const unsigned char *msg, size_t msg_size, 333 const unsigned char *sig, size_t sig_size ); 334 335 #if defined(MBEDTLS_LMS_PRIVATE) 336 /** 337 * \brief This function initializes an LMS private context 338 * 339 * \param ctx The uninitialized LMS private context that will 340 * then be initialized. */ 341 void mbedtls_lms_private_init( mbedtls_lms_private_t *ctx ); 342 343 /** 344 * \brief This function uninitializes an LMS private context 345 * 346 * \param ctx The initialized LMS private context that will then 347 * be uninitialized. 348 */ 349 void mbedtls_lms_private_free( mbedtls_lms_private_t *ctx ); 350 351 /** 352 * \brief This function generates an LMS private key, and 353 * stores in into an LMS private context. 354 * 355 * \warning This function is **not intended for use in 356 * production**, due to as-yet unsolved problems with 357 * handling stateful keys. The API for this function 358 * may change considerably in future versions. 359 * 360 * \note The seed must have at least 256 bits of entropy. 361 * 362 * \param ctx The initialized LMOTS context to generate the key 363 * into. 364 * \param type The LMS parameter set identifier. 365 * \param otstype The LMOTS parameter set identifier. 366 * \param f_rng The RNG function to be used to generate the key ID. 367 * \param p_rng The RNG context to be passed to f_rng 368 * \param seed The seed used to deterministically generate the 369 * key. 370 * \param seed_size The length of the seed. 371 * 372 * \return \c 0 on success. 373 * \return A non-zero error code on failure. 374 */ 375 int mbedtls_lms_generate_private_key( mbedtls_lms_private_t *ctx, 376 mbedtls_lms_algorithm_type_t type, 377 mbedtls_lmots_algorithm_type_t otstype, 378 int (*f_rng)(void *, unsigned char *, size_t), 379 void* p_rng, const unsigned char *seed, 380 size_t seed_size ); 381 382 /** 383 * \brief This function calculates an LMS public key from a 384 * LMS context that already contains a private key. 385 * 386 * \note Before this function is called, the context must 387 * have been initialized and the context must contain 388 * a private key. 389 * 390 * \param ctx The initialized LMS public context to calculate the key 391 * from and store it into. 392 * 393 * \param priv_ctx The LMS private context to read the private key 394 * from. This must have been initialized and contain a 395 * private key. 396 * 397 * \return \c 0 on success. 398 * \return A non-zero error code on failure. 399 */ 400 int mbedtls_lms_calculate_public_key( mbedtls_lms_public_t *ctx, 401 const mbedtls_lms_private_t *priv_ctx ); 402 403 /** 404 * \brief This function creates a LMS signature, using a 405 * LMS context that contains unused private keys. 406 * 407 * \warning This function is **not intended for use in 408 * production**, due to as-yet unsolved problems with 409 * handling stateful keys. The API for this function 410 * may change considerably in future versions. 411 * 412 * \note Before this function is called, the context must 413 * have been initialized and must contain a private 414 * key. 415 * 416 * \note Each of the LMOTS private keys inside a LMS private 417 * key can only be used once. If they are reused, then 418 * attackers may be able to forge signatures with that 419 * key. This is all handled transparently, but it is 420 * important to not perform copy operations on LMS 421 * contexts that contain private key material. 422 * 423 * \param ctx The initialized LMS private context from which the 424 * private key will be read. 425 * \param f_rng The RNG function to be used for signature 426 * generation. 427 * \param p_rng The RNG context to be passed to f_rng 428 * \param msg The buffer from which the message will be read. 429 * \param msg_size The size of the message that will be read. 430 * \param sig The buf into which the signature will be stored. 431 * Must be at least #MBEDTLS_LMS_SIG_LEN in size. 432 * \param sig_size The size of the buffer the signature will be 433 * written into. 434 * \param sig_len If not NULL, will be written with the size of the 435 * signature. 436 * 437 * \return \c 0 on success. 438 * \return A non-zero error code on failure. 439 */ 440 int mbedtls_lms_sign( mbedtls_lms_private_t *ctx, 441 int (*f_rng)(void *, unsigned char *, size_t), 442 void* p_rng, const unsigned char *msg, 443 unsigned int msg_size, unsigned char *sig, size_t sig_size, 444 size_t *sig_len ); 445 #endif /* defined(MBEDTLS_LMS_PRIVATE) */ 446 447 #ifdef __cplusplus 448 } 449 #endif 450 451 #endif /* MBEDTLS_LMS_H */ 452