/*
 *  The LMS stateful-hash public-key signature scheme
 *
 *  Copyright The Mbed TLS Contributors
 *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
 */

/*
 *  The following sources were referenced in the design of this implementation
 *  of the LMS algorithm:
 *
 *  [1] IETF RFC8554
 *      D. McGrew, M. Curcio, S.Fluhrer
 *      https://datatracker.ietf.org/doc/html/rfc8554
 *
 *  [2] NIST Special Publication 800-208
 *      David A. Cooper et. al.
 *      https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-208.pdf
 */

#include "common.h"

#if defined(MBEDTLS_LMS_C)

#include <string.h>

#include "lmots.h"

#include "psa/crypto.h"
#include "psa_util_internal.h"
#include "mbedtls/lms.h"
#include "mbedtls/error.h"
#include "mbedtls/platform_util.h"

#include "mbedtls/platform.h"

/* Define a local translating function to save code size by not using too many
 * arguments in each translating place. */
static int local_err_translation(psa_status_t status)
{
    return psa_status_to_mbedtls(status, psa_to_lms_errors,
                                 ARRAY_LENGTH(psa_to_lms_errors),
                                 psa_generic_status_to_mbedtls);
}
#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status)

#define SIG_Q_LEAF_ID_OFFSET     (0)
#define SIG_OTS_SIG_OFFSET       (SIG_Q_LEAF_ID_OFFSET + \
                                  MBEDTLS_LMOTS_Q_LEAF_ID_LEN)
#define SIG_TYPE_OFFSET(otstype) (SIG_OTS_SIG_OFFSET   + \
                                  MBEDTLS_LMOTS_SIG_LEN(otstype))
#define SIG_PATH_OFFSET(otstype) (SIG_TYPE_OFFSET(otstype) + \
                                  MBEDTLS_LMS_TYPE_LEN)

#define PUBLIC_KEY_TYPE_OFFSET      (0)
#define PUBLIC_KEY_OTSTYPE_OFFSET   (PUBLIC_KEY_TYPE_OFFSET + \
                                     MBEDTLS_LMS_TYPE_LEN)
#define PUBLIC_KEY_I_KEY_ID_OFFSET  (PUBLIC_KEY_OTSTYPE_OFFSET  + \
                                     MBEDTLS_LMOTS_TYPE_LEN)
#define PUBLIC_KEY_ROOT_NODE_OFFSET (PUBLIC_KEY_I_KEY_ID_OFFSET + \
                                     MBEDTLS_LMOTS_I_KEY_ID_LEN)


/* Currently only support H=10 */
#define H_TREE_HEIGHT_MAX                  10
#define MERKLE_TREE_NODE_AM(type)          ((size_t) 1 << (MBEDTLS_LMS_H_TREE_HEIGHT(type) + 1u))
#define MERKLE_TREE_LEAF_NODE_AM(type)     ((size_t) 1 << MBEDTLS_LMS_H_TREE_HEIGHT(type))
#define MERKLE_TREE_INTERNAL_NODE_AM(type) ((unsigned int) \
                                            (1u << MBEDTLS_LMS_H_TREE_HEIGHT(type)))

#define D_CONST_LEN           (2)
static const unsigned char D_LEAF_CONSTANT_BYTES[D_CONST_LEN] = { 0x82, 0x82 };
static const unsigned char D_INTR_CONSTANT_BYTES[D_CONST_LEN] = { 0x83, 0x83 };


/* Calculate the value of a leaf node of the Merkle tree (which is a hash of a
 * public key and some other parameters like the leaf index). This function
 * implements RFC8554 section 5.3, in the case where r >= 2^h.
 *
 *  params              The LMS parameter set, the underlying LMOTS
 *                      parameter set, and I value which describe the key
 *                      being used.
 *
 *  pub_key             The public key of the private whose index
 *                      corresponds to the index of this leaf node. This
 *                      is a hash output.
 *
 *  r_node_idx          The index of this node in the Merkle tree. Note
 *                      that the root node of the Merkle tree is
 *                      1-indexed.
 *
 *  out                 The output node value, which is a hash output.
 */
static int create_merkle_leaf_value(const mbedtls_lms_parameters_t *params,
                                    unsigned char *pub_key,
                                    unsigned int r_node_idx,
                                    unsigned char *out)
{
    psa_hash_operation_t op;
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
    size_t output_hash_len;
    unsigned char r_node_idx_bytes[4];

    op = psa_hash_operation_init();
    status = psa_hash_setup(&op, PSA_ALG_SHA_256);
    if (status != PSA_SUCCESS) {
        goto exit;
    }

    status = psa_hash_update(&op, params->I_key_identifier,
                             MBEDTLS_LMOTS_I_KEY_ID_LEN);
    if (status != PSA_SUCCESS) {
        goto exit;
    }

    MBEDTLS_PUT_UINT32_BE(r_node_idx, r_node_idx_bytes, 0);
    status = psa_hash_update(&op, r_node_idx_bytes, 4);
    if (status != PSA_SUCCESS) {
        goto exit;
    }

    status = psa_hash_update(&op, D_LEAF_CONSTANT_BYTES, D_CONST_LEN);
    if (status != PSA_SUCCESS) {
        goto exit;
    }

    status = psa_hash_update(&op, pub_key,
                             MBEDTLS_LMOTS_N_HASH_LEN(params->otstype));
    if (status != PSA_SUCCESS) {
        goto exit;
    }

    status = psa_hash_finish(&op, out, MBEDTLS_LMS_M_NODE_BYTES(params->type),
                             &output_hash_len);
    if (status != PSA_SUCCESS) {
        goto exit;
    }

exit:
    psa_hash_abort(&op);

    return PSA_TO_MBEDTLS_ERR(status);
}

/* Calculate the value of an internal node of the Merkle tree (which is a hash
 * of a public key and some other parameters like the node index). This function
 * implements RFC8554 section 5.3, in the case where r < 2^h.
 *
 *  params              The LMS parameter set, the underlying LMOTS
 *                      parameter set, and I value which describe the key
 *                      being used.
 *
 *  left_node           The value of the child of this node which is on
 *                      the left-hand side. As with all nodes on the
 *                      Merkle tree, this is a hash output.
 *
 *  right_node          The value of the child of this node which is on
 *                      the right-hand side. As with all nodes on the
 *                      Merkle tree, this is a hash output.
 *
 *  r_node_idx          The index of this node in the Merkle tree. Note
 *                      that the root node of the Merkle tree is
 *                      1-indexed.
 *
 *  out                 The output node value, which is a hash output.
 */
static int create_merkle_internal_value(const mbedtls_lms_parameters_t *params,
                                        const unsigned char *left_node,
                                        const unsigned char *right_node,
                                        unsigned int r_node_idx,
                                        unsigned char *out)
{
    psa_hash_operation_t op;
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
    size_t output_hash_len;
    unsigned char r_node_idx_bytes[4];

    op = psa_hash_operation_init();
    status = psa_hash_setup(&op, PSA_ALG_SHA_256);
    if (status != PSA_SUCCESS) {
        goto exit;
    }

    status = psa_hash_update(&op, params->I_key_identifier,
                             MBEDTLS_LMOTS_I_KEY_ID_LEN);
    if (status != PSA_SUCCESS) {
        goto exit;
    }

    MBEDTLS_PUT_UINT32_BE(r_node_idx, r_node_idx_bytes, 0);
    status = psa_hash_update(&op, r_node_idx_bytes, 4);
    if (status != PSA_SUCCESS) {
        goto exit;
    }

    status = psa_hash_update(&op, D_INTR_CONSTANT_BYTES, D_CONST_LEN);
    if (status != PSA_SUCCESS) {
        goto exit;
    }

    status = psa_hash_update(&op, left_node,
                             MBEDTLS_LMS_M_NODE_BYTES(params->type));
    if (status != PSA_SUCCESS) {
        goto exit;
    }

    status = psa_hash_update(&op, right_node,
                             MBEDTLS_LMS_M_NODE_BYTES(params->type));
    if (status != PSA_SUCCESS) {
        goto exit;
    }

    status = psa_hash_finish(&op, out, MBEDTLS_LMS_M_NODE_BYTES(params->type),
                             &output_hash_len);
    if (status != PSA_SUCCESS) {
        goto exit;
    }

exit:
    psa_hash_abort(&op);

    return PSA_TO_MBEDTLS_ERR(status);
}

void mbedtls_lms_public_init(mbedtls_lms_public_t *ctx)
{
    memset(ctx, 0, sizeof(*ctx));
}

void mbedtls_lms_public_free(mbedtls_lms_public_t *ctx)
{
    mbedtls_platform_zeroize(ctx, sizeof(*ctx));
}

int mbedtls_lms_import_public_key(mbedtls_lms_public_t *ctx,
                                  const unsigned char *key, size_t key_size)
{
    mbedtls_lms_algorithm_type_t type;
    mbedtls_lmots_algorithm_type_t otstype;

    type = (mbedtls_lms_algorithm_type_t) MBEDTLS_GET_UINT32_BE(key, PUBLIC_KEY_TYPE_OFFSET);
    if (type != MBEDTLS_LMS_SHA256_M32_H10) {
        return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
    }
    ctx->params.type = type;

    if (key_size != MBEDTLS_LMS_PUBLIC_KEY_LEN(ctx->params.type)) {
        return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
    }

    otstype = (mbedtls_lmots_algorithm_type_t)
              MBEDTLS_GET_UINT32_BE(key, PUBLIC_KEY_OTSTYPE_OFFSET);
    if (otstype != MBEDTLS_LMOTS_SHA256_N32_W8) {
        return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
    }
    ctx->params.otstype = otstype;

    memcpy(ctx->params.I_key_identifier,
           key + PUBLIC_KEY_I_KEY_ID_OFFSET,
           MBEDTLS_LMOTS_I_KEY_ID_LEN);
    memcpy(ctx->T_1_pub_key, key + PUBLIC_KEY_ROOT_NODE_OFFSET,
           MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type));

    ctx->have_public_key = 1;

    return 0;
}

int mbedtls_lms_export_public_key(const mbedtls_lms_public_t *ctx,
                                  unsigned char *key,
                                  size_t key_size, size_t *key_len)
{
    if (key_size < MBEDTLS_LMS_PUBLIC_KEY_LEN(ctx->params.type)) {
        return MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL;
    }

    if (!ctx->have_public_key) {
        return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
    }

    MBEDTLS_PUT_UINT32_BE(ctx->params.type, key, PUBLIC_KEY_TYPE_OFFSET);
    MBEDTLS_PUT_UINT32_BE(ctx->params.otstype, key, PUBLIC_KEY_OTSTYPE_OFFSET);
    memcpy(key + PUBLIC_KEY_I_KEY_ID_OFFSET,
           ctx->params.I_key_identifier,
           MBEDTLS_LMOTS_I_KEY_ID_LEN);
    memcpy(key +PUBLIC_KEY_ROOT_NODE_OFFSET,
           ctx->T_1_pub_key,
           MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type));

    if (key_len != NULL) {
        *key_len = MBEDTLS_LMS_PUBLIC_KEY_LEN(ctx->params.type);
    }

    return 0;
}

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)
{
    unsigned int q_leaf_identifier;
    unsigned char Kc_candidate_ots_pub_key[MBEDTLS_LMOTS_N_HASH_LEN_MAX];
    unsigned char Tc_candidate_root_node[MBEDTLS_LMS_M_NODE_BYTES_MAX];
    unsigned int height;
    unsigned int curr_node_id;
    unsigned int parent_node_id;
    const unsigned char *left_node;
    const unsigned char *right_node;
    mbedtls_lmots_parameters_t ots_params;
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;

    if (!ctx->have_public_key) {
        return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
    }

    if (ctx->params.type
        != MBEDTLS_LMS_SHA256_M32_H10) {
        return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
    }

    if (ctx->params.otstype
        != MBEDTLS_LMOTS_SHA256_N32_W8) {
        return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
    }

    if (sig_size != MBEDTLS_LMS_SIG_LEN(ctx->params.type, ctx->params.otstype)) {
        return MBEDTLS_ERR_LMS_VERIFY_FAILED;
    }

    if (sig_size < SIG_OTS_SIG_OFFSET + MBEDTLS_LMOTS_TYPE_LEN) {
        return MBEDTLS_ERR_LMS_VERIFY_FAILED;
    }

    if (MBEDTLS_GET_UINT32_BE(sig, SIG_OTS_SIG_OFFSET + MBEDTLS_LMOTS_SIG_TYPE_OFFSET)
        != MBEDTLS_LMOTS_SHA256_N32_W8) {
        return MBEDTLS_ERR_LMS_VERIFY_FAILED;
    }

    if (sig_size < SIG_TYPE_OFFSET(ctx->params.otstype) + MBEDTLS_LMS_TYPE_LEN) {
        return MBEDTLS_ERR_LMS_VERIFY_FAILED;
    }

    if (MBEDTLS_GET_UINT32_BE(sig, SIG_TYPE_OFFSET(ctx->params.otstype))
        != MBEDTLS_LMS_SHA256_M32_H10) {
        return MBEDTLS_ERR_LMS_VERIFY_FAILED;
    }


    q_leaf_identifier = MBEDTLS_GET_UINT32_BE(sig, SIG_Q_LEAF_ID_OFFSET);

    if (q_leaf_identifier >= MERKLE_TREE_LEAF_NODE_AM(ctx->params.type)) {
        return MBEDTLS_ERR_LMS_VERIFY_FAILED;
    }

    memcpy(ots_params.I_key_identifier,
           ctx->params.I_key_identifier,
           MBEDTLS_LMOTS_I_KEY_ID_LEN);
    MBEDTLS_PUT_UINT32_BE(q_leaf_identifier, ots_params.q_leaf_identifier, 0);
    ots_params.type = ctx->params.otstype;

    ret = mbedtls_lmots_calculate_public_key_candidate(&ots_params,
                                                       msg,
                                                       msg_size,
                                                       sig + SIG_OTS_SIG_OFFSET,
                                                       MBEDTLS_LMOTS_SIG_LEN(ctx->params.otstype),
                                                       Kc_candidate_ots_pub_key,
                                                       sizeof(Kc_candidate_ots_pub_key),
                                                       NULL);
    if (ret != 0) {
        return MBEDTLS_ERR_LMS_VERIFY_FAILED;
    }

    create_merkle_leaf_value(
        &ctx->params,
        Kc_candidate_ots_pub_key,
        MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type) + q_leaf_identifier,
        Tc_candidate_root_node);

    curr_node_id = MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type) +
                   q_leaf_identifier;

    for (height = 0; height < MBEDTLS_LMS_H_TREE_HEIGHT(ctx->params.type);
         height++) {
        parent_node_id = curr_node_id / 2;

        /* Left/right node ordering matters for the hash */
        if (curr_node_id & 1) {
            left_node = sig + SIG_PATH_OFFSET(ctx->params.otstype) +
                        height * MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type);
            right_node = Tc_candidate_root_node;
        } else {
            left_node = Tc_candidate_root_node;
            right_node = sig + SIG_PATH_OFFSET(ctx->params.otstype) +
                         height * MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type);
        }

        create_merkle_internal_value(&ctx->params, left_node, right_node,
                                     parent_node_id, Tc_candidate_root_node);

        curr_node_id /= 2;
    }

    if (memcmp(Tc_candidate_root_node, ctx->T_1_pub_key,
               MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type))) {
        return MBEDTLS_ERR_LMS_VERIFY_FAILED;
    }

    return 0;
}

#if defined(MBEDTLS_LMS_PRIVATE)

/* Calculate a full Merkle tree based on a private key. This function
 * implements RFC8554 section 5.3, and is used to generate a public key (as the
 * public key is the root node of the Merkle tree).
 *
 *  ctx                 The LMS private context, containing a parameter
 *                      set and private key material consisting of both
 *                      public and private OTS.
 *
 *  tree                The output tree, which is 2^(H + 1) hash outputs.
 *                      In the case of H=10 we have 2048 tree nodes (of
 *                      which 1024 of them are leaf nodes). Note that
 *                      because the Merkle tree root is 1-indexed, the 0
 *                      index tree node is never used.
 */
static int calculate_merkle_tree(const mbedtls_lms_private_t *ctx,
                                 unsigned char *tree)
{
    unsigned int priv_key_idx;
    unsigned int r_node_idx;
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;

    /* First create the leaf nodes, in ascending order */
    for (priv_key_idx = 0;
         priv_key_idx < MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type);
         priv_key_idx++) {
        r_node_idx = MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type) + priv_key_idx;

        ret = create_merkle_leaf_value(&ctx->params,
                                       ctx->ots_public_keys[priv_key_idx].public_key,
                                       r_node_idx,
                                       &tree[r_node_idx * MBEDTLS_LMS_M_NODE_BYTES(
                                                 ctx->params.type)]);
        if (ret != 0) {
            return ret;
        }
    }

    /* Then the internal nodes, in reverse order so that we can guarantee the
     * parent has been created */
    for (r_node_idx = MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type) - 1;
         r_node_idx > 0;
         r_node_idx--) {
        ret = create_merkle_internal_value(&ctx->params,
                                           &tree[(r_node_idx * 2) *
                                                 MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type)],
                                           &tree[(r_node_idx * 2 + 1) *
                                                 MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type)],
                                           r_node_idx,
                                           &tree[r_node_idx *
                                                 MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type)]);
        if (ret != 0) {
            return ret;
        }
    }

    return 0;
}

/* Calculate a path from a leaf node of the Merkle tree to the root of the tree,
 * and return the full path. This function implements RFC8554 section 5.4.1, as
 * the Merkle path is the main component of an LMS signature.
 *
 *  ctx                 The LMS private context, containing a parameter
 *                      set and private key material consisting of both
 *                      public and private OTS.
 *
 *  leaf_node_id        Which leaf node to calculate the path from.
 *
 *  path                The output path, which is H hash outputs.
 */
static int get_merkle_path(mbedtls_lms_private_t *ctx,
                           unsigned int leaf_node_id,
                           unsigned char *path)
{
    const size_t node_bytes = MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type);
    unsigned int curr_node_id = leaf_node_id;
    unsigned int adjacent_node_id;
    unsigned char *tree = NULL;
    unsigned int height;
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;

    tree = mbedtls_calloc((size_t) MERKLE_TREE_NODE_AM(ctx->params.type),
                          node_bytes);
    if (tree == NULL) {
        return MBEDTLS_ERR_LMS_ALLOC_FAILED;
    }

    ret = calculate_merkle_tree(ctx, tree);
    if (ret != 0) {
        goto exit;
    }

    for (height = 0; height < MBEDTLS_LMS_H_TREE_HEIGHT(ctx->params.type);
         height++) {
        adjacent_node_id = curr_node_id ^ 1;

        memcpy(&path[height * node_bytes],
               &tree[adjacent_node_id * node_bytes], node_bytes);

        curr_node_id >>= 1;
    }

    ret = 0;

exit:
    mbedtls_zeroize_and_free(tree, node_bytes *
                             (size_t) MERKLE_TREE_NODE_AM(ctx->params.type));

    return ret;
}

void mbedtls_lms_private_init(mbedtls_lms_private_t *ctx)
{
    memset(ctx, 0, sizeof(*ctx));
}

void mbedtls_lms_private_free(mbedtls_lms_private_t *ctx)
{
    unsigned int idx;

    if (ctx->have_private_key) {
        if (ctx->ots_private_keys != NULL) {
            for (idx = 0; idx < MERKLE_TREE_LEAF_NODE_AM(ctx->params.type); idx++) {
                mbedtls_lmots_private_free(&ctx->ots_private_keys[idx]);
            }
        }

        if (ctx->ots_public_keys != NULL) {
            for (idx = 0; idx < MERKLE_TREE_LEAF_NODE_AM(ctx->params.type); idx++) {
                mbedtls_lmots_public_free(&ctx->ots_public_keys[idx]);
            }
        }

        mbedtls_free(ctx->ots_private_keys);
        mbedtls_free(ctx->ots_public_keys);
    }

    mbedtls_platform_zeroize(ctx, sizeof(*ctx));
}


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)
{
    unsigned int idx = 0;
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;

    if (type != MBEDTLS_LMS_SHA256_M32_H10) {
        return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
    }

    if (otstype != MBEDTLS_LMOTS_SHA256_N32_W8) {
        return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
    }

    if (ctx->have_private_key) {
        return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
    }

    ctx->params.type = type;
    ctx->params.otstype = otstype;
    ctx->have_private_key = 1;

    ret = f_rng(p_rng,
                ctx->params.I_key_identifier,
                MBEDTLS_LMOTS_I_KEY_ID_LEN);
    if (ret != 0) {
        goto exit;
    }

    /* Requires a cast to size_t to avoid an implicit cast warning on certain
     * platforms (particularly Windows) */
    ctx->ots_private_keys = mbedtls_calloc((size_t) MERKLE_TREE_LEAF_NODE_AM(ctx->params.type),
                                           sizeof(*ctx->ots_private_keys));
    if (ctx->ots_private_keys == NULL) {
        ret = MBEDTLS_ERR_LMS_ALLOC_FAILED;
        goto exit;
    }

    /* Requires a cast to size_t to avoid an implicit cast warning on certain
     * platforms (particularly Windows) */
    ctx->ots_public_keys = mbedtls_calloc((size_t) MERKLE_TREE_LEAF_NODE_AM(ctx->params.type),
                                          sizeof(*ctx->ots_public_keys));
    if (ctx->ots_public_keys == NULL) {
        ret = MBEDTLS_ERR_LMS_ALLOC_FAILED;
        goto exit;
    }

    for (idx = 0; idx < MERKLE_TREE_LEAF_NODE_AM(ctx->params.type); idx++) {
        mbedtls_lmots_private_init(&ctx->ots_private_keys[idx]);
        mbedtls_lmots_public_init(&ctx->ots_public_keys[idx]);
    }


    for (idx = 0; idx < MERKLE_TREE_LEAF_NODE_AM(ctx->params.type); idx++) {
        ret = mbedtls_lmots_generate_private_key(&ctx->ots_private_keys[idx],
                                                 otstype,
                                                 ctx->params.I_key_identifier,
                                                 idx, seed, seed_size);
        if (ret != 0) {
            goto exit;
        }

        ret = mbedtls_lmots_calculate_public_key(&ctx->ots_public_keys[idx],
                                                 &ctx->ots_private_keys[idx]);
        if (ret != 0) {
            goto exit;
        }
    }

    ctx->q_next_usable_key = 0;

exit:
    if (ret != 0) {
        mbedtls_lms_private_free(ctx);
    }

    return ret;
}

int mbedtls_lms_calculate_public_key(mbedtls_lms_public_t *ctx,
                                     const mbedtls_lms_private_t *priv_ctx)
{
    const size_t node_bytes = MBEDTLS_LMS_M_NODE_BYTES(priv_ctx->params.type);
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    unsigned char *tree = NULL;

    if (!priv_ctx->have_private_key) {
        return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
    }

    if (priv_ctx->params.type
        != MBEDTLS_LMS_SHA256_M32_H10) {
        return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
    }

    if (priv_ctx->params.otstype
        != MBEDTLS_LMOTS_SHA256_N32_W8) {
        return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
    }

    tree = mbedtls_calloc((size_t) MERKLE_TREE_NODE_AM(priv_ctx->params.type),
                          node_bytes);
    if (tree == NULL) {
        return MBEDTLS_ERR_LMS_ALLOC_FAILED;
    }

    memcpy(&ctx->params, &priv_ctx->params,
           sizeof(mbedtls_lmots_parameters_t));

    ret = calculate_merkle_tree(priv_ctx, tree);
    if (ret != 0) {
        goto exit;
    }

    /* Root node is always at position 1, due to 1-based indexing */
    memcpy(ctx->T_1_pub_key, &tree[node_bytes], node_bytes);

    ctx->have_public_key = 1;

    ret = 0;

exit:
    mbedtls_zeroize_and_free(tree, node_bytes *
                             (size_t) MERKLE_TREE_NODE_AM(priv_ctx->params.type));

    return ret;
}


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)
{
    uint32_t q_leaf_identifier;
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;

    if (!ctx->have_private_key) {
        return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
    }

    if (sig_size < MBEDTLS_LMS_SIG_LEN(ctx->params.type, ctx->params.otstype)) {
        return MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL;
    }

    if (ctx->params.type != MBEDTLS_LMS_SHA256_M32_H10) {
        return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
    }

    if (ctx->params.otstype
        != MBEDTLS_LMOTS_SHA256_N32_W8) {
        return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
    }

    if (ctx->q_next_usable_key >= MERKLE_TREE_LEAF_NODE_AM(ctx->params.type)) {
        return MBEDTLS_ERR_LMS_OUT_OF_PRIVATE_KEYS;
    }


    q_leaf_identifier = ctx->q_next_usable_key;
    /* This new value must _always_ be written back to the disk before the
     * signature is returned.
     */
    ctx->q_next_usable_key += 1;

    if (MBEDTLS_LMS_SIG_LEN(ctx->params.type, ctx->params.otstype)
        < SIG_OTS_SIG_OFFSET) {
        return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
    }

    ret = mbedtls_lmots_sign(&ctx->ots_private_keys[q_leaf_identifier],
                             f_rng,
                             p_rng,
                             msg,
                             msg_size,
                             sig + SIG_OTS_SIG_OFFSET,
                             MBEDTLS_LMS_SIG_LEN(ctx->params.type,
                                                 ctx->params.otstype) - SIG_OTS_SIG_OFFSET,
                             NULL);
    if (ret != 0) {
        return ret;
    }

    MBEDTLS_PUT_UINT32_BE(ctx->params.type, sig, SIG_TYPE_OFFSET(ctx->params.otstype));
    MBEDTLS_PUT_UINT32_BE(q_leaf_identifier, sig, SIG_Q_LEAF_ID_OFFSET);

    ret = get_merkle_path(ctx,
                          MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type) + q_leaf_identifier,
                          sig + SIG_PATH_OFFSET(ctx->params.otstype));
    if (ret != 0) {
        return ret;
    }

    if (sig_len != NULL) {
        *sig_len = MBEDTLS_LMS_SIG_LEN(ctx->params.type, ctx->params.otstype);
    }


    return 0;
}

#endif /* defined(MBEDTLS_LMS_PRIVATE) */
#endif /* defined(MBEDTLS_LMS_C) */
