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 #if !defined(MBEDTLS_DEPRECATED_REMOVED) 48 /** 49 * \brief This function converts a \ref psa_status_t to a 50 * low-level LMS error code. 51 * 52 * \param status The psa_status_t to convert 53 * 54 * \return The corresponding LMS error code. 55 */ 56 int MBEDTLS_DEPRECATED mbedtls_lms_error_from_psa(psa_status_t status); 57 #endif 58 59 /** 60 * \brief This function initializes a public LMOTS context 61 * 62 * \param ctx The uninitialized LMOTS context that will then be 63 * initialized. 64 */ 65 void mbedtls_lmots_public_init(mbedtls_lmots_public_t *ctx); 66 67 /** 68 * \brief This function uninitializes a public LMOTS context 69 * 70 * \param ctx The initialized LMOTS context that will then be 71 * uninitialized. 72 */ 73 void mbedtls_lmots_public_free(mbedtls_lmots_public_t *ctx); 74 75 /** 76 * \brief This function imports an LMOTS public key into a 77 * LMOTS context. 78 * 79 * \note Before this function is called, the context must 80 * have been initialized. 81 * 82 * \note See IETF RFC8554 for details of the encoding of 83 * this public key. 84 * 85 * \param ctx The initialized LMOTS context store the key in. 86 * \param key The buffer from which the key will be read. 87 * #MBEDTLS_LMOTS_PUBLIC_KEY_LEN bytes will be read 88 * from this. 89 * 90 * \return \c 0 on success. 91 * \return A non-zero error code on failure. 92 */ 93 int mbedtls_lmots_import_public_key(mbedtls_lmots_public_t *ctx, 94 const unsigned char *key, size_t key_size); 95 96 /** 97 * \brief This function exports an LMOTS public key from a 98 * LMOTS context that already contains a public key. 99 * 100 * \note Before this function is called, the context must 101 * have been initialized and the context must contain 102 * a public key. 103 * 104 * \note See IETF RFC8554 for details of the encoding of 105 * this public key. 106 * 107 * \param ctx The initialized LMOTS context that contains the 108 * public key. 109 * \param key The buffer into which the key will be output. Must 110 * be at least #MBEDTLS_LMOTS_PUBLIC_KEY_LEN in size. 111 * 112 * \return \c 0 on success. 113 * \return A non-zero error code on failure. 114 */ 115 int mbedtls_lmots_export_public_key(const mbedtls_lmots_public_t *ctx, 116 unsigned char *key, size_t key_size, 117 size_t *key_len); 118 119 /** 120 * \brief This function creates a candidate public key from 121 * an LMOTS signature. This can then be compared to 122 * the real public key to determine the validity of 123 * the signature. 124 * 125 * \note This function is exposed publicly to be used in LMS 126 * signature verification, it is expected that 127 * mbedtls_lmots_verify will be used for LMOTS 128 * signature verification. 129 * 130 * \param params The LMOTS parameter set, q and I values as an 131 * mbedtls_lmots_parameters_t struct. 132 * \param msg The buffer from which the message will be read. 133 * \param msg_size The size of the message that will be read. 134 * \param sig The buffer from which the signature will be read. 135 * #MBEDTLS_LMOTS_SIG_LEN bytes will be read from 136 * this. 137 * \param out The buffer where the candidate public key will be 138 * stored. Must be at least #MBEDTLS_LMOTS_N_HASH_LEN 139 * bytes in size. 140 * 141 * \return \c 0 on success. 142 * \return A non-zero error code on failure. 143 */ 144 int mbedtls_lmots_calculate_public_key_candidate(const mbedtls_lmots_parameters_t *params, 145 const unsigned char *msg, 146 size_t msg_size, 147 const unsigned char *sig, 148 size_t sig_size, 149 unsigned char *out, 150 size_t out_size, 151 size_t *out_len); 152 153 /** 154 * \brief This function verifies a LMOTS signature, using a 155 * LMOTS context that contains a public key. 156 * 157 * \warning This function is **not intended for use in 158 * production**, due to as-yet unsolved problems with 159 * handling stateful keys. The API for this function 160 * may change considerably in future versions. 161 * 162 * \note Before this function is called, the context must 163 * have been initialized and must contain a public key 164 * (either by import or calculation from a private 165 * key). 166 * 167 * \param ctx The initialized LMOTS context from which the public 168 * key will be read. 169 * \param msg The buffer from which the message will be read. 170 * \param msg_size The size of the message that will be read. 171 * \param sig The buf from which the signature will be read. 172 * #MBEDTLS_LMOTS_SIG_LEN bytes will be read from 173 * this. 174 * 175 * \return \c 0 on successful verification. 176 * \return A non-zero error code on failure. 177 */ 178 int mbedtls_lmots_verify(const mbedtls_lmots_public_t *ctx, 179 const unsigned char *msg, 180 size_t msg_size, const unsigned char *sig, 181 size_t sig_size); 182 183 #if defined(MBEDTLS_LMS_PRIVATE) 184 185 /** 186 * \brief This function initializes a private LMOTS context 187 * 188 * \param ctx The uninitialized LMOTS context that will then be 189 * initialized. 190 */ 191 void mbedtls_lmots_private_init(mbedtls_lmots_private_t *ctx); 192 193 /** 194 * \brief This function uninitializes a private LMOTS context 195 * 196 * \param ctx The initialized LMOTS context that will then be 197 * uninitialized. 198 */ 199 void mbedtls_lmots_private_free(mbedtls_lmots_private_t *ctx); 200 201 /** 202 * \brief This function calculates an LMOTS private key, and 203 * stores in into an LMOTS context. 204 * 205 * \warning This function is **not intended for use in 206 * production**, due to as-yet unsolved problems with 207 * handling stateful keys. The API for this function 208 * may change considerably in future versions. 209 * 210 * \note The seed must have at least 256 bits of entropy. 211 * 212 * \param ctx The initialized LMOTS context to generate the key 213 * into. 214 * \param I_key_identifier The key identifier of the key, as a 16-byte string. 215 * \param q_leaf_identifier The leaf identifier of key. If this LMOTS key is 216 * not being used as part of an LMS key, this should 217 * be set to 0. 218 * \param seed The seed used to deterministically generate the 219 * key. 220 * \param seed_size The length of the seed. 221 * 222 * \return \c 0 on success. 223 * \return A non-zero error code on failure. 224 */ 225 int mbedtls_lmots_generate_private_key(mbedtls_lmots_private_t *ctx, 226 mbedtls_lmots_algorithm_type_t type, 227 const unsigned char I_key_identifier[MBEDTLS_LMOTS_I_KEY_ID_LEN], 228 uint32_t q_leaf_identifier, 229 const unsigned char *seed, 230 size_t seed_size); 231 232 /** 233 * \brief This function generates an LMOTS public key from a 234 * LMOTS context that already contains a private key. 235 * 236 * \note Before this function is called, the context must 237 * have been initialized and the context must contain 238 * a private key. 239 * 240 * \param ctx The initialized LMOTS context to generate the key 241 * from and store it into. 242 * 243 * \return \c 0 on success. 244 * \return A non-zero error code on failure. 245 */ 246 int mbedtls_lmots_calculate_public_key(mbedtls_lmots_public_t *ctx, 247 const mbedtls_lmots_private_t *priv_ctx); 248 249 /** 250 * \brief This function creates a LMOTS signature, using a 251 * LMOTS context that contains a private key. 252 * 253 * \note Before this function is called, the context must 254 * have been initialized and must contain a private 255 * key. 256 * 257 * \note LMOTS private keys can only be used once, otherwise 258 * attackers may be able to create forged signatures. 259 * If the signing operation is successful, the private 260 * key in the context will be erased, and no further 261 * signing will be possible until another private key 262 * is loaded 263 * 264 * \param ctx The initialized LMOTS context from which the 265 * private key will be read. 266 * \param f_rng The RNG function to be used for signature 267 * generation. 268 * \param p_rng The RNG context to be passed to f_rng 269 * \param msg The buffer from which the message will be read. 270 * \param msg_size The size of the message that will be read. 271 * \param sig The buf into which the signature will be stored. 272 * Must be at least #MBEDTLS_LMOTS_SIG_LEN in size. 273 * 274 * \return \c 0 on success. 275 * \return A non-zero error code on failure. 276 */ 277 int mbedtls_lmots_sign(mbedtls_lmots_private_t *ctx, 278 int (*f_rng)(void *, unsigned char *, size_t), 279 void *p_rng, const unsigned char *msg, size_t msg_size, 280 unsigned char *sig, size_t sig_size, size_t *sig_len); 281 282 #endif /* defined(MBEDTLS_LMS_PRIVATE) */ 283 284 #ifdef __cplusplus 285 } 286 #endif 287 288 #endif /* MBEDTLS_LMOTS_H */ 289