lms.h 20 KB

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