File lms.h

This file provides an API for the LMS post-quantum-safe stateful-hash 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).

Defines

MBEDTLS_ERR_LMS_BAD_INPUT_DATA

Bad data has been input to an LMS function

MBEDTLS_ERR_LMS_OUT_OF_PRIVATE_KEYS

Specified LMS key has utilised all of its private keys

MBEDTLS_ERR_LMS_VERIFY_FAILED

LMS signature verification failed

MBEDTLS_ERR_LMS_ALLOC_FAILED

LMS failed to allocate space for a private key

MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL

Input/output buffer is too small to contain requited data

MBEDTLS_LMOTS_N_HASH_LEN_MAX
MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT_MAX
MBEDTLS_LMOTS_N_HASH_LEN(type)
MBEDTLS_LMOTS_I_KEY_ID_LEN
MBEDTLS_LMOTS_Q_LEAF_ID_LEN
MBEDTLS_LMOTS_TYPE_LEN
MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT(type)
MBEDTLS_LMOTS_C_RANDOM_VALUE_LEN(type)
MBEDTLS_LMOTS_SIG_LEN(type)
MBEDTLS_LMS_TYPE_LEN
MBEDTLS_LMS_H_TREE_HEIGHT(type)
MBEDTLS_LMS_M_NODE_BYTES(type)
MBEDTLS_LMS_M_NODE_BYTES_MAX
MBEDTLS_LMS_SIG_LEN(type, otstype)
MBEDTLS_LMS_PUBLIC_KEY_LEN(type)

Enums

enum mbedtls_lms_algorithm_type_t

The Identifier of the LMS parameter set, as per https://www.iana.org/assignments/leighton-micali-signatures/leighton-micali-signatures.xhtml We are only implementing a subset of the types, particularly H10, for the sake of simplicity.

Values:

enumerator MBEDTLS_LMS_SHA256_M32_H10
enum mbedtls_lmots_algorithm_type_t

The Identifier of the LMOTS parameter set, as per https://www.iana.org/assignments/leighton-micali-signatures/leighton-micali-signatures.xhtml. We are only implementing a subset of the types, particularly N32_W8, for the sake of simplicity.

Values:

enumerator MBEDTLS_LMOTS_SHA256_N32_W8

Functions

void mbedtls_lms_public_init(mbedtls_lms_public_t *ctx)

This function initializes an LMS public context.

Parameters:

ctx – The uninitialized LMS context that will then be initialized.

void mbedtls_lms_public_free(mbedtls_lms_public_t *ctx)

This function uninitializes an LMS public context.

Parameters:

ctx – The initialized LMS context that will then be uninitialized.

int mbedtls_lms_import_public_key(mbedtls_lms_public_t *ctx, const unsigned char *key, size_t key_size)

This function imports an LMS public key into a public LMS context.

Note

Before this function is called, the context must have been initialized.

Note

See IETF RFC8554 for details of the encoding of this public key.

Parameters:
  • ctx – The initialized LMS context store the key in.

  • key – The buffer from which the key will be read. MBEDTLS_LMS_PUBLIC_KEY_LEN bytes will be read from this.

  • key_size – The size of the key being imported.

Returns:

0 on success.

Returns:

A non-zero error code on failure.

int mbedtls_lms_export_public_key(const mbedtls_lms_public_t *ctx, unsigned char *key, size_t key_size, size_t *key_len)

This function exports an LMS public key from a LMS public context that already contains a public key.

Note

Before this function is called, the context must have been initialized and the context must contain a public key.

Note

See IETF RFC8554 for details of the encoding of this public key.

Parameters:
  • ctx – The initialized LMS public context that contains the public key.

  • key – The buffer into which the key will be output. Must be at least MBEDTLS_LMS_PUBLIC_KEY_LEN in size.

  • key_size – The size of the key buffer.

  • key_len – If not NULL, will be written with the size of the key.

Returns:

0 on success.

Returns:

A non-zero error code on failure.

int mbedtls_lms_verify(const mbedtls_lms_public_t *ctx, const unsigned char *msg, size_t msg_size, const unsigned char *sig, size_t sig_size)

This function verifies a LMS signature, using a LMS context that contains a public key.

Note

Before this function is called, the context must have been initialized and must contain a public key (either by import or generation).

Parameters:
  • ctx – The initialized LMS public context from which the public key will be read.

  • msg – The buffer from which the message will be read.

  • msg_size – The size of the message that will be read.

  • sig – The buf from which the signature will be read. MBEDTLS_LMS_SIG_LEN bytes will be read from this.

  • sig_size – The size of the signature to be verified.

Returns:

0 on successful verification.

Returns:

A non-zero error code on failure.

void mbedtls_lms_private_init(mbedtls_lms_private_t *ctx)

This function initializes an LMS private context.

Parameters:

ctx – The uninitialized LMS private context that will then be initialized.

void mbedtls_lms_private_free(mbedtls_lms_private_t *ctx)

This function uninitializes an LMS private context.

Parameters:

ctx – The initialized LMS private context that will then be uninitialized.

int mbedtls_lms_generate_private_key(mbedtls_lms_private_t *ctx, mbedtls_lms_algorithm_type_t type, mbedtls_lmots_algorithm_type_t otstype, int (*f_rng)(void*, unsigned char*, size_t), void *p_rng, const unsigned char *seed, size_t seed_size)

This function generates an LMS private key, and stores in into an LMS private context.

Note

The seed must have at least 256 bits of entropy.

Warning

This function is not intended for use in production, due to as-yet unsolved problems with handling stateful keys. The API for this function may change considerably in future versions.

Parameters:
  • ctx – The initialized LMOTS context to generate the key into.

  • type – The LMS parameter set identifier.

  • otstype – The LMOTS parameter set identifier.

  • f_rng – The RNG function to be used to generate the key ID.

  • p_rng – The RNG context to be passed to f_rng

  • seed – The seed used to deterministically generate the key.

  • seed_size – The length of the seed.

Returns:

0 on success.

Returns:

A non-zero error code on failure.

int mbedtls_lms_calculate_public_key(mbedtls_lms_public_t *ctx, const mbedtls_lms_private_t *priv_ctx)

This function calculates an LMS public key from a LMS context that already contains a private key.

Note

Before this function is called, the context must have been initialized and the context must contain a private key.

Parameters:
  • ctx – The initialized LMS public context to calculate the key from and store it into.

  • priv_ctx – The LMS private context to read the private key from. This must have been initialized and contain a private key.

Returns:

0 on success.

Returns:

A non-zero error code on failure.

int mbedtls_lms_sign(mbedtls_lms_private_t *ctx, int (*f_rng)(void*, unsigned char*, size_t), void *p_rng, const unsigned char *msg, unsigned int msg_size, unsigned char *sig, size_t sig_size, size_t *sig_len)

This function creates a LMS signature, using a LMS context that contains unused private keys.

Note

Before this function is called, the context must have been initialized and must contain a private key.

Note

Each of the LMOTS private keys inside a LMS private key can only be used once. If they are reused, then attackers may be able to forge signatures with that key. This is all handled transparently, but it is important to not perform copy operations on LMS contexts that contain private key material.

Warning

This function is not intended for use in production, due to as-yet unsolved problems with handling stateful keys. The API for this function may change considerably in future versions.

Parameters:
  • ctx – The initialized LMS private context from which the private key will be read.

  • f_rng – The RNG function to be used for signature generation.

  • p_rng – The RNG context to be passed to f_rng

  • msg – The buffer from which the message will be read.

  • msg_size – The size of the message that will be read.

  • sig – The buf into which the signature will be stored. Must be at least MBEDTLS_LMS_SIG_LEN in size.

  • sig_size – The size of the buffer the signature will be written into.

  • sig_len – If not NULL, will be written with the size of the signature.

Returns:

0 on success.

Returns:

A non-zero error code on failure.

struct mbedtls_lmots_parameters_t
#include <lms.h>

LMOTS parameters structure.

This contains the metadata associated with an LMOTS key, detailing the algorithm type, the key ID, and the leaf identifier should be key be part of a LMS key.

Public Members

unsigned char private_I_key_identifier[(16u)]

The key identifier.

unsigned char private_q_leaf_identifier[(4u)]

Which leaf of the LMS key this is. 0 if the key is not part of an LMS key.

mbedtls_lmots_algorithm_type_t private_type

The LM-OTS key type identifier as per IANA. Only SHA256_N32_W8 is currently supported.

struct mbedtls_lmots_public_t
#include <lms.h>

LMOTS public context structure.

A LMOTS public key is a hash output, and the applicable parameter set.

The context must be initialized before it is used. A public key must either be imported or generated from a private context.

digraph lmots_public_t { UNINITIALIZED -> INIT [label="init"]; HAVE_PUBLIC_KEY -> INIT [label="free"]; INIT -> HAVE_PUBLIC_KEY [label="import_public_key"]; INIT -> HAVE_PUBLIC_KEY [label="calculate_public_key from private key"]; HAVE_PUBLIC_KEY -> HAVE_PUBLIC_KEY [label="export_public_key"]; }

Public Members

mbedtls_lmots_parameters_t private_params
unsigned char private_public_key[MBEDTLS_LMOTS_N_HASH_LEN_MAX]
unsigned char private_have_public_key

Whether the context contains a public key. Boolean values only.

struct mbedtls_lmots_private_t
#include <lms.h>

LMOTS private context structure.

A LMOTS private key is one hash output for each of digit of the digest + checksum, and the applicable parameter set.

The context must be initialized before it is used. A public key must either be imported or generated from a private context.

digraph lmots_public_t { UNINITIALIZED -> INIT [label="init"]; HAVE_PRIVATE_KEY -> INIT [label="free"]; INIT -> HAVE_PRIVATE_KEY [label="generate_private_key"]; HAVE_PRIVATE_KEY -> INIT [label="sign"]; }

Public Members

mbedtls_lmots_parameters_t private_params
unsigned char private_private_key[MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT_MAX][MBEDTLS_LMOTS_N_HASH_LEN_MAX]
unsigned char private_have_private_key

Whether the context contains a private key. Boolean values only.

struct mbedtls_lms_parameters_t
#include <lms.h>

LMS parameters structure.

This contains the metadata associated with an LMS key, detailing the algorithm type, the type of the underlying OTS algorithm, and the key ID.

Public Members

unsigned char private_I_key_identifier[(16u)]

The key identifier.

mbedtls_lmots_algorithm_type_t private_otstype

The LM-OTS key type identifier as per IANA. Only SHA256_N32_W8 is currently supported.

mbedtls_lms_algorithm_type_t private_type

The LMS key type identifier as per IANA. Only SHA256_M32_H10 is currently supported.

struct mbedtls_lms_public_t
#include <lms.h>

LMS public context structure.

A LMS public key is the hash output that is the root of the Merkle tree, and the applicable parameter set

The context must be initialized before it is used. A public key must either be imported or generated from a private context.

digraph lms_public_t { UNINITIALIZED -> INIT [label="init"]; HAVE_PUBLIC_KEY -> INIT [label="free"]; INIT -> HAVE_PUBLIC_KEY [label="import_public_key"]; INIT -> HAVE_PUBLIC_KEY [label="calculate_public_key from private key"]; HAVE_PUBLIC_KEY -> HAVE_PUBLIC_KEY [label="export_public_key"]; }

Public Members

mbedtls_lms_parameters_t private_params
unsigned char private_T_1_pub_key[MBEDTLS_LMS_M_NODE_BYTES_MAX]

The public key, in the form of the Merkle tree root node.

unsigned char private_have_public_key

Whether the context contains a public key. Boolean values only.

struct mbedtls_lms_private_t
#include <lms.h>

LMS private context structure.

A LMS private key is a set of LMOTS private keys, an index to the next usable key, and the applicable parameter set.

The context must be initialized before it is used. A public key must either be imported or generated from a private context.

digraph lms_public_t { UNINITIALIZED -> INIT [label="init"]; HAVE_PRIVATE_KEY -> INIT [label="free"]; INIT -> HAVE_PRIVATE_KEY [label="generate_private_key"]; }

Public Members

mbedtls_lms_parameters_t private_params
uint32_t private_q_next_usable_key

The index of the next OTS key that has not been used.

mbedtls_lmots_private_t *private_ots_private_keys

The private key material. One OTS key for each leaf node in the Merkle tree. NULL when have_private_key is 0 and non-NULL otherwise. is 2^MBEDTLS_LMS_H_TREE_HEIGHT(type) in length.

mbedtls_lmots_public_t *private_ots_public_keys

The OTS key public keys, used to build the Merkle tree. NULL when have_private_key is 0 and non-NULL otherwise. Is 2^MBEDTLS_LMS_H_TREE_HEIGHT(type) in length.

unsigned char private_have_private_key

Whether the context contains a private key. Boolean values only.