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