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][ 161 MBEDTLS_LMOTS_N_HASH_LEN_MAX]; 162 unsigned char MBEDTLS_PRIVATE(have_private_key); /*!< Whether the context contains a private key. 163 Boolean values only. */ 164 } mbedtls_lmots_private_t; 165 #endif /* defined(MBEDTLS_LMS_PRIVATE) */ 166 167 168 /** LMS parameters structure. 169 * 170 * This contains the metadata associated with an LMS key, detailing the 171 * algorithm type, the type of the underlying OTS algorithm, and the key ID. 172 */ 173 typedef struct { 174 unsigned char MBEDTLS_PRIVATE(I_key_identifier[MBEDTLS_LMOTS_I_KEY_ID_LEN]); /*!< The key 175 identifier. */ 176 mbedtls_lmots_algorithm_type_t MBEDTLS_PRIVATE(otstype); /*!< The LM-OTS key type identifier as 177 per IANA. Only SHA256_N32_W8 is 178 currently supported. */ 179 mbedtls_lms_algorithm_type_t MBEDTLS_PRIVATE(type); /*!< The LMS key type identifier as per 180 IANA. Only SHA256_M32_H10 is currently 181 supported. */ 182 } mbedtls_lms_parameters_t; 183 184 /** LMS public context structure. 185 * 186 * A LMS public key is the hash output that is the root of the Merkle tree, and 187 * the applicable parameter set 188 * 189 * The context must be initialized before it is used. A public key must either 190 * be imported or generated from a private context. 191 * 192 * \dot 193 * digraph lms_public_t { 194 * UNINITIALIZED -> INIT [label="init"]; 195 * HAVE_PUBLIC_KEY -> INIT [label="free"]; 196 * INIT -> HAVE_PUBLIC_KEY [label="import_public_key"]; 197 * INIT -> HAVE_PUBLIC_KEY [label="calculate_public_key from private key"]; 198 * HAVE_PUBLIC_KEY -> HAVE_PUBLIC_KEY [label="export_public_key"]; 199 * } 200 * \enddot 201 */ 202 typedef struct { 203 mbedtls_lms_parameters_t MBEDTLS_PRIVATE(params); 204 unsigned char MBEDTLS_PRIVATE(T_1_pub_key)[MBEDTLS_LMS_M_NODE_BYTES_MAX]; /*!< The public key, in 205 the form of the Merkle tree root node. */ 206 unsigned char MBEDTLS_PRIVATE(have_public_key); /*!< Whether the context contains a public key. 207 Boolean values only. */ 208 } mbedtls_lms_public_t; 209 210 211 #if defined(MBEDTLS_LMS_PRIVATE) 212 /** LMS private context structure. 213 * 214 * A LMS private key is a set of LMOTS private keys, an index to the next usable 215 * key, and the applicable parameter set. 216 * 217 * The context must be initialized before it is used. A public key must either 218 * be imported or generated from a private context. 219 * 220 * \dot 221 * digraph lms_public_t { 222 * UNINITIALIZED -> INIT [label="init"]; 223 * HAVE_PRIVATE_KEY -> INIT [label="free"]; 224 * INIT -> HAVE_PRIVATE_KEY [label="generate_private_key"]; 225 * } 226 * \enddot 227 */ 228 typedef struct { 229 mbedtls_lms_parameters_t MBEDTLS_PRIVATE(params); 230 uint32_t MBEDTLS_PRIVATE(q_next_usable_key); /*!< The index of the next OTS key that has not 231 been used. */ 232 mbedtls_lmots_private_t *MBEDTLS_PRIVATE(ots_private_keys); /*!< The private key material. One OTS key 233 for each leaf node in the Merkle tree. NULL 234 when have_private_key is 0 and non-NULL otherwise. 235 is 2^MBEDTLS_LMS_H_TREE_HEIGHT(type) in length. */ 236 mbedtls_lmots_public_t *MBEDTLS_PRIVATE(ots_public_keys); /*!< The OTS key public keys, used to 237 build the Merkle tree. NULL 238 when have_private_key is 0 and 239 non-NULL otherwise. 240 Is 2^MBEDTLS_LMS_H_TREE_HEIGHT(type) 241 in length. */ 242 unsigned char MBEDTLS_PRIVATE(have_private_key); /*!< Whether the context contains a private key. 243 Boolean values only. */ 244 } mbedtls_lms_private_t; 245 #endif /* defined(MBEDTLS_LMS_PRIVATE) */ 246 247 /** 248 * \brief This function initializes an LMS public context 249 * 250 * \param ctx The uninitialized LMS context that will then be 251 * initialized. 252 */ 253 void mbedtls_lms_public_init(mbedtls_lms_public_t *ctx); 254 255 /** 256 * \brief This function uninitializes an LMS public context 257 * 258 * \param ctx The initialized LMS context that will then be 259 * uninitialized. 260 */ 261 void mbedtls_lms_public_free(mbedtls_lms_public_t *ctx); 262 263 /** 264 * \brief This function imports an LMS public key into a 265 * public LMS context. 266 * 267 * \note Before this function is called, the context must 268 * have been initialized. 269 * 270 * \note See IETF RFC8554 for details of the encoding of 271 * this public key. 272 * 273 * \param ctx The initialized LMS context store the key in. 274 * \param key The buffer from which the key will be read. 275 * #MBEDTLS_LMS_PUBLIC_KEY_LEN bytes will be read from 276 * this. 277 * \param key_size The size of the key being imported. 278 * 279 * \return \c 0 on success. 280 * \return A non-zero error code on failure. 281 */ 282 int mbedtls_lms_import_public_key(mbedtls_lms_public_t *ctx, 283 const unsigned char *key, size_t key_size); 284 285 /** 286 * \brief This function exports an LMS public key from a 287 * LMS public context that already contains a public 288 * key. 289 * 290 * \note Before this function is called, the context must 291 * have been initialized and the context must contain 292 * a public key. 293 * 294 * \note See IETF RFC8554 for details of the encoding of 295 * this public key. 296 * 297 * \param ctx The initialized LMS public context that contains 298 * the public key. 299 * \param key The buffer into which the key will be output. Must 300 * be at least #MBEDTLS_LMS_PUBLIC_KEY_LEN in size. 301 * \param key_size The size of the key buffer. 302 * \param key_len If not NULL, will be written with the size of the 303 * key. 304 * 305 * \return \c 0 on success. 306 * \return A non-zero error code on failure. 307 */ 308 int mbedtls_lms_export_public_key(const mbedtls_lms_public_t *ctx, 309 unsigned char *key, size_t key_size, 310 size_t *key_len); 311 312 /** 313 * \brief This function verifies a LMS signature, using a 314 * LMS context that contains a public key. 315 * 316 * \note Before this function is called, the context must 317 * have been initialized and must contain a public key 318 * (either by import or generation). 319 * 320 * \param ctx The initialized LMS public context from which the 321 * public key will be read. 322 * \param msg The buffer from which the message will be read. 323 * \param msg_size The size of the message that will be read. 324 * \param sig The buf from which the signature will be read. 325 * #MBEDTLS_LMS_SIG_LEN bytes will be read from 326 * this. 327 * \param sig_size The size of the signature to be verified. 328 * 329 * \return \c 0 on successful verification. 330 * \return A non-zero error code on failure. 331 */ 332 int mbedtls_lms_verify(const mbedtls_lms_public_t *ctx, 333 const unsigned char *msg, size_t msg_size, 334 const unsigned char *sig, size_t sig_size); 335 336 #if defined(MBEDTLS_LMS_PRIVATE) 337 /** 338 * \brief This function initializes an LMS private context 339 * 340 * \param ctx The uninitialized LMS private context that will 341 * then be initialized. */ 342 void mbedtls_lms_private_init(mbedtls_lms_private_t *ctx); 343 344 /** 345 * \brief This function uninitializes an LMS private context 346 * 347 * \param ctx The initialized LMS private context that will then 348 * be uninitialized. 349 */ 350 void mbedtls_lms_private_free(mbedtls_lms_private_t *ctx); 351 352 /** 353 * \brief This function generates an LMS private key, and 354 * stores in into an LMS private context. 355 * 356 * \warning This function is **not intended for use in 357 * production**, due to as-yet unsolved problems with 358 * handling stateful keys. The API for this function 359 * may change considerably in future versions. 360 * 361 * \note The seed must have at least 256 bits of entropy. 362 * 363 * \param ctx The initialized LMOTS context to generate the key 364 * into. 365 * \param type The LMS parameter set identifier. 366 * \param otstype The LMOTS parameter set identifier. 367 * \param f_rng The RNG function to be used to generate the key ID. 368 * \param p_rng The RNG context to be passed to f_rng 369 * \param seed The seed used to deterministically generate the 370 * key. 371 * \param seed_size The length of the seed. 372 * 373 * \return \c 0 on success. 374 * \return A non-zero error code on failure. 375 */ 376 int mbedtls_lms_generate_private_key(mbedtls_lms_private_t *ctx, 377 mbedtls_lms_algorithm_type_t type, 378 mbedtls_lmots_algorithm_type_t otstype, 379 int (*f_rng)(void *, unsigned char *, size_t), 380 void *p_rng, const unsigned char *seed, 381 size_t seed_size); 382 383 /** 384 * \brief This function calculates an LMS public key from a 385 * LMS context that already contains a private key. 386 * 387 * \note Before this function is called, the context must 388 * have been initialized and the context must contain 389 * a private key. 390 * 391 * \param ctx The initialized LMS public context to calculate the key 392 * from and store it into. 393 * 394 * \param priv_ctx The LMS private context to read the private key 395 * from. This must have been initialized and contain a 396 * private key. 397 * 398 * \return \c 0 on success. 399 * \return A non-zero error code on failure. 400 */ 401 int mbedtls_lms_calculate_public_key(mbedtls_lms_public_t *ctx, 402 const mbedtls_lms_private_t *priv_ctx); 403 404 /** 405 * \brief This function creates a LMS signature, using a 406 * LMS context that contains unused private keys. 407 * 408 * \warning This function is **not intended for use in 409 * production**, due to as-yet unsolved problems with 410 * handling stateful keys. The API for this function 411 * may change considerably in future versions. 412 * 413 * \note Before this function is called, the context must 414 * have been initialized and must contain a private 415 * key. 416 * 417 * \note Each of the LMOTS private keys inside a LMS private 418 * key can only be used once. If they are reused, then 419 * attackers may be able to forge signatures with that 420 * key. This is all handled transparently, but it is 421 * important to not perform copy operations on LMS 422 * contexts that contain private key material. 423 * 424 * \param ctx The initialized LMS private context from which the 425 * private key will be read. 426 * \param f_rng The RNG function to be used for signature 427 * generation. 428 * \param p_rng The RNG context to be passed to f_rng 429 * \param msg The buffer from which the message will be read. 430 * \param msg_size The size of the message that will be read. 431 * \param sig The buf into which the signature will be stored. 432 * Must be at least #MBEDTLS_LMS_SIG_LEN in size. 433 * \param sig_size The size of the buffer the signature will be 434 * written into. 435 * \param sig_len If not NULL, will be written with the size of the 436 * signature. 437 * 438 * \return \c 0 on success. 439 * \return A non-zero error code on failure. 440 */ 441 int mbedtls_lms_sign(mbedtls_lms_private_t *ctx, 442 int (*f_rng)(void *, unsigned char *, size_t), 443 void *p_rng, const unsigned char *msg, 444 unsigned int msg_size, unsigned char *sig, size_t sig_size, 445 size_t *sig_len); 446 #endif /* defined(MBEDTLS_LMS_PRIVATE) */ 447 448 #ifdef __cplusplus 449 } 450 #endif 451 452 #endif /* MBEDTLS_LMS_H */ 453