Update LMS/LMOTS documentation

Signed-off-by: Raef Coles <raef.coles@arm.com>
This commit is contained in:
Raef Coles 2022-08-24 13:33:35 +01:00
parent 0aa18e041f
commit 2ad6e611f0
No known key found for this signature in database
GPG Key ID: 1AAF1B43DF2086F4
3 changed files with 85 additions and 20 deletions

View File

@ -1,12 +1,11 @@
Features Features
* Add the LMS post-quantum-safe stateful-hash asymmetric signature scheme * Add the LMS post-quantum-safe stateful-hash asymmetric signature scheme.
as defined in RFC8554 and NIST.SP.200-208. This currently only supports Signature verification is production-ready, but generation is for testing
one parameter set (LMS_SHA256_M32_H10), meaning that each private key can purposes only. This currently only supports one parameter set
be used to sign 1024 messages. As such, it is not intended for use in TLS, (LMS_SHA256_M32_H10), meaning that each private key can be used to sign
but instead for verification of assets transmitted over an insecure 1024 messages. As such, it is not intended for use in TLS, but instead for
channel, particularly firmware images. This is one of the signature verification of assets transmitted over an insecure channel, particularly
schemes recommended by the IETF draft SUIT standard for IOT firmware firmware images.
upgrades (RFC9019).
* Add the LM-OTS post-quantum-safe one-time signature scheme, which is * Add the LM-OTS post-quantum-safe one-time signature scheme, which is
required for LMS. This can be used independently, but each key can only be required for LMS. This can be used independently, but each key can only be
used to sign one message so is impractical for most circumstances. used to sign one message so is impractical for most circumstances.

View File

@ -2,7 +2,9 @@
* \file lmots.h * \file lmots.h
* *
* \brief This file provides an API for the LM-OTS post-quantum-safe one-time * \brief This file provides an API for the LM-OTS post-quantum-safe one-time
* public-key signature scheme. * public-key signature scheme as defined in RFC8554 and NIST.SP.200-208.
* This implementation currently only supports a single parameter set
* MBEDTLS_LMOTS_SHA256_N32_W8 in order to reduce complexity.
*/ */
/* /*
* Copyright The Mbed TLS Contributors * Copyright The Mbed TLS Contributors
@ -67,6 +69,33 @@ typedef enum {
} mbedtls_lmots_algorithm_type_t; } mbedtls_lmots_algorithm_type_t;
/** LMOTS context structure.
*
* The context must be initialized before it is used. A public key must either
* be imported, or an algorithm type set, a private key generated and the public
* key calculated from it. A context that does not contain a public key cannot
* verify, and a context that does not contain a private key cannot sign.
* Signing a message will remove the private key from the context, as private
* keys can only be used a single time.
*
* \dot
* digraph lmots {
* UNINITIALIZED -> INIT [label="init"];
* TYPE_SET -> INIT [label="free"];
* PRIVATE -> INIT [label="free"];
* PUBLIC -> INIT [label="free"];
* "PRIVATE+PUBLIC" -> INIT [label="free"];
* INIT -> TYPE_SET [label="set_algorithm_type"];
* PRIVATE -> TYPE_SET [label="sign"];
* "PRIVATE+PUBLIC" -> PUBLIC [label="sign"];
* INIT -> PUBLIC [label="import_public"];
* PUBLIC -> PUBLIC [label="export_pubkey"];
* "PRIVATE+PUBLIC" -> "PRIVATE+PUBLIC" [label="export_pubkey"];
* PRIVATE -> "PRIVATE+PUBLIC" [label="gen_pubkey"];
* TYPE_SET -> PRIVATE [label="gen_privkey"];
* }
* \enddot
*/
typedef struct { typedef struct {
unsigned char MBEDTLS_PRIVATE(have_privkey); /*!< Whether the context contains a private key. unsigned char MBEDTLS_PRIVATE(have_privkey); /*!< Whether the context contains a private key.
Boolean values only. */ Boolean values only. */
@ -129,15 +158,14 @@ int mbedtls_lmots_set_algorithm_type( mbedtls_lmots_context *ctx,
* mbedtls_lmots_verify will be used for LMOTS * mbedtls_lmots_verify will be used for LMOTS
* signature verification. * signature verification.
* *
* \param I_key_identifier The key identifier of the key, as a 16 byte * \param I_key_identifier The key identifier of the key, as a 16-byte string.
* bytestring.
* \param q_leaf_identifier The leaf identifier of key. If this LMOTS key is * \param q_leaf_identifier The leaf identifier of key. If this LMOTS key is
* not being used as part of an LMS key, this should * not being used as part of an LMS key, this should
* be set to 0. * be set to 0.
* \param msg The buffer from which the message will be read. * \param msg The buffer from which the message will be read.
* \param msg_len The size of the message that will be read. * \param msg_len The size of the message that will be read.
* \param sig The buff from which the signature will be read. * \param sig The buffer from which the signature will be read.
* MBEDTLS_LMOTS_SIG_LEN bytes will be read from this. * #MBEDTLS_LMOTS_SIG_LEN bytes will be read from this.
* \param out The buffer where the candidate public key will be * \param out The buffer where the candidate public key will be
* stored. Must be at least #MBEDTLS_LMOTS_N_HASH_LEN * stored. Must be at least #MBEDTLS_LMOTS_N_HASH_LEN
* bytes in size. * bytes in size.
@ -189,6 +217,10 @@ int mbedtls_lmots_sign( mbedtls_lmots_context *ctx,
* \brief This function verifies a LMOTS signature, using a * \brief This function verifies a LMOTS signature, using a
* LMOTS context that contains a public key. * LMOTS context that contains a public key.
* *
* \warning This function is **not intended for use in
* production**, due to as-yet unsolved problems with
* handling stateful keys.
*
* \note Before this function is called, the context must * \note Before this function is called, the context must
* have been initialized and must contain a public key * have been initialized and must contain a public key
* (either by import or generation). * (either by import or generation).
@ -270,6 +302,10 @@ int mbedtls_lmots_gen_pubkey( mbedtls_lmots_context *ctx );
* \brief This function generates an LMOTS private key, and * \brief This function generates an LMOTS private key, and
* stores in into an LMOTS context. * stores in into an LMOTS context.
* *
* \warning This function is **not intended for use in
* production**, due to as-yet unsolved problems with
* handling stateful keys.
*
* \note Before this function is called, the context must * \note Before this function is called, the context must
* have been initialized and the type of the LMOTS * have been initialized and the type of the LMOTS
* context set using mbedtls_lmots_set_algorithm_type * context set using mbedtls_lmots_set_algorithm_type
@ -278,8 +314,7 @@ int mbedtls_lmots_gen_pubkey( mbedtls_lmots_context *ctx );
* *
* \param ctx The initialized LMOTS context to generate the key * \param ctx The initialized LMOTS context to generate the key
* into. * into.
* \param I_key_identifier The key identifier of the key, as a 16 byte * \param I_key_identifier The key identifier of the key, as a 16-byte string.
* bytestring.
* \param q_leaf_identifier The leaf identifier of key. If this LMOTS key is * \param q_leaf_identifier The leaf identifier of key. If this LMOTS key is
* not being used as part of an LMS key, this should * not being used as part of an LMS key, this should
* be set to 0. * be set to 0.

View File

@ -2,7 +2,11 @@
* \file lms.h * \file lms.h
* *
* \brief This file provides an API for the LMS post-quantum-safe stateful-hash * \brief This file provides an API for the LMS post-quantum-safe stateful-hash
* public-key signature scheme. public-key signature scheme as defined in RFC8554 and NIST.SP.200-208.
* This implementation currently only supports a single parameter set
* MBEDTLS_LMS_SHA256_M32_H10 in order to reduce complexity. This is one
* of the signature schemes recommended by the IETF draft SUIT standard
* for IOT firmware upgrades (RFC9019).
*/ */
/* /*
* Copyright The Mbed TLS Contributors * Copyright The Mbed TLS Contributors
@ -36,7 +40,7 @@
#define MBEDTLS_LMS_TYPE_LEN (4) #define MBEDTLS_LMS_TYPE_LEN (4)
#define MBEDTLS_LMS_H_TREE_HEIGHT (10) #define MBEDTLS_LMS_H_TREE_HEIGHT (10)
#define MBEDTLS_LMS_M_NODE_BYTES (32) #define MBEDTLS_LMS_M_NODE_BYTES (32) /* The length of a hash output, 32 for SHA256 */
#define MBEDTLS_LMS_SIG_LEN (MBEDTLS_LMOTS_Q_LEAF_ID_LEN + MBEDTLS_LMOTS_SIG_LEN + \ #define MBEDTLS_LMS_SIG_LEN (MBEDTLS_LMOTS_Q_LEAF_ID_LEN + MBEDTLS_LMOTS_SIG_LEN + \
MBEDTLS_LMS_TYPE_LEN + MBEDTLS_LMS_H_TREE_HEIGHT * MBEDTLS_LMS_M_NODE_BYTES) MBEDTLS_LMS_TYPE_LEN + MBEDTLS_LMS_H_TREE_HEIGHT * MBEDTLS_LMS_M_NODE_BYTES)
@ -66,6 +70,29 @@ typedef enum {
} mbedtls_lms_algorithm_type_t; } mbedtls_lms_algorithm_type_t;
/** LMS context structure.
*
* The context must be initialized before it is used. A public key must either
* be imported, or an algorithm type set, a private key generated and the public
* key calculated from it. A context that does not contain a public key cannot
* verify, and a context that does not contain a private key cannot sign.
*
* \dot
* digraph lmots {
* UNINITIALIZED -> INIT [label="init"];
* TYPE_SET -> INIT [label="free"];
* PRIVATE -> INIT [label="free"];
* PUBLIC -> INIT [label="free"];
* "PRIVATE+PUBLIC" -> INIT [label="free"];
* INIT -> TYPE_SET [label="set_algorithm_type"];
* INIT -> PUBLIC [label="import_public"];
* PUBLIC -> PUBLIC [label="export_pubkey"];
* "PRIVATE+PUBLIC" -> "PRIVATE+PUBLIC" [label="export_pubkey"];
* PRIVATE -> "PRIVATE+PUBLIC" [label="gen_pubkey"];
* TYPE_SET -> PRIVATE [label="gen_privkey"];
* }
* \enddot
*/
typedef struct { typedef struct {
unsigned char MBEDTLS_PRIVATE(have_privkey); /*!< Whether the context contains a private key. unsigned char MBEDTLS_PRIVATE(have_privkey); /*!< Whether the context contains a private key.
Boolean values only. */ Boolean values only. */
@ -123,9 +150,9 @@ int mbedtls_lms_set_algorithm_type( mbedtls_lms_context *ctx,
* \brief This function creates a LMS signature, using a * \brief This function creates a LMS signature, using a
* LMOTS context that contains a private key. * LMOTS context that contains a private key.
* *
* \note This function is intended for _testing purposes * \warning This function is **not intended for use in
* only_, due to complexities around updating stateful * production**, due to as-yet unsolved problems with
* keys. * handling stateful keys.
* *
* \note Before this function is called, the context must * \note Before this function is called, the context must
* have been initialized and must contain a private * have been initialized and must contain a private
@ -242,6 +269,10 @@ int mbedtls_lms_gen_pubkey( mbedtls_lms_context *ctx );
* \brief This function generates an LMS private key, and * \brief This function generates an LMS private key, and
* stores in into an LMS context. * stores in into an LMS context.
* *
* \warning This function is **not intended for use in
* production**, due to as-yet unsolved problems with
* handling stateful keys.
*
* \note Before this function is called, the context must * \note Before this function is called, the context must
* have been initialized and the type of the LMS * have been initialized and the type of the LMS
* context set using mbedtls_lmots_set_algorithm_type * context set using mbedtls_lmots_set_algorithm_type