/*
 * The LM-OTS one-time public-key signature scheme
 *
 * Copyright The Mbed TLS Contributors
 *  SPDX-License-Identifier: Apache-2.0
 *
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may
 *  not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

/*
 *  The following sources were referenced in the design of this implementation
 *  of the LM-OTS 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 "mbedtls/lms.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/error.h"
#include "psa_util_internal.h"

#include "psa/crypto.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 PUBLIC_KEY_TYPE_OFFSET     (0)
#define PUBLIC_KEY_I_KEY_ID_OFFSET (PUBLIC_KEY_TYPE_OFFSET + \
                                    MBEDTLS_LMOTS_TYPE_LEN)
#define PUBLIC_KEY_Q_LEAF_ID_OFFSET (PUBLIC_KEY_I_KEY_ID_OFFSET + \
                                     MBEDTLS_LMOTS_I_KEY_ID_LEN)
#define PUBLIC_KEY_KEY_HASH_OFFSET (PUBLIC_KEY_Q_LEAF_ID_OFFSET + \
                                    MBEDTLS_LMOTS_Q_LEAF_ID_LEN)

/* We only support parameter sets that use 8-bit digits, as it does not require
 * translation logic between digits and bytes */
#define W_WINTERNITZ_PARAMETER (8u)
#define CHECKSUM_LEN           (2)
#define I_DIGIT_IDX_LEN        (2)
#define J_HASH_IDX_LEN         (1)
#define D_CONST_LEN            (2)

#define DIGIT_MAX_VALUE        ((1u << W_WINTERNITZ_PARAMETER) - 1u)

#define D_CONST_LEN            (2)
static const unsigned char D_PUBLIC_CONSTANT_BYTES[D_CONST_LEN] = { 0x80, 0x80 };
static const unsigned char D_MESSAGE_CONSTANT_BYTES[D_CONST_LEN] = { 0x81, 0x81 };

#if defined(MBEDTLS_TEST_HOOKS)
int (*mbedtls_lmots_sign_private_key_invalidated_hook)(unsigned char *) = NULL;
#endif /* defined(MBEDTLS_TEST_HOOKS) */

void mbedtls_lms_unsigned_int_to_network_bytes(unsigned int val, size_t len,
                                               unsigned char *bytes)
{
    size_t idx;

    for (idx = 0; idx < len; idx++) {
        bytes[idx] = (val >> ((len - 1 - idx) * 8)) & 0xFF;
    }
}

unsigned int mbedtls_lms_network_bytes_to_unsigned_int(size_t len,
                                                       const unsigned char *bytes)
{
    size_t idx;
    unsigned int val = 0;

    for (idx = 0; idx < len; idx++) {
        val |= ((unsigned int) bytes[idx]) << (8 * (len - 1 - idx));
    }

    return val;
}

/* Calculate the checksum digits that are appended to the end of the LMOTS digit
 * string. See NIST SP800-208 section 3.1 or RFC8554 Algorithm 2 for details of
 * the checksum algorithm.
 *
 *  params              The LMOTS parameter set, I and q values which
 *                      describe the key being used.
 *
 *  digest              The digit string to create the digest from. As
 *                      this does not contain a checksum, it is the same
 *                      size as a hash output.
 */
static unsigned short lmots_checksum_calculate(const mbedtls_lmots_parameters_t *params,
                                               const unsigned char *digest)
{
    size_t idx;
    unsigned sum = 0;

    for (idx = 0; idx < MBEDTLS_LMOTS_N_HASH_LEN(params->type); idx++) {
        sum += DIGIT_MAX_VALUE - digest[idx];
    }

    return sum;
}

/* Create the string of digest digits (in the base determined by the Winternitz
 * parameter with the checksum appended to the end (Q || cksm(Q)). See NIST
 * SP800-208 section 3.1 or RFC8554 Algorithm 3 step 5 (also used in Algorithm
 * 4b step 3) for details.
 *
 *  params              The LMOTS parameter set, I and q values which
 *                      describe the key being used.
 *
 *  msg                 The message that will be hashed to create the
 *                      digest.
 *
 *  msg_size            The size of the message.
 *
 *  C_random_value      The random value that will be combined with the
 *                      message digest. This is always the same size as a
 *                      hash output for whichever hash algorithm is
 *                      determined by the parameter set.
 *
 *  output              An output containing the digit string (+
 *                      checksum) of length P digits (in the case of
 *                      MBEDTLS_LMOTS_SHA256_N32_W8, this means it is of
 *                      size P bytes).
 */
static int create_digit_array_with_checksum(const mbedtls_lmots_parameters_t *params,
                                            const unsigned char *msg,
                                            size_t msg_len,
                                            const unsigned char *C_random_value,
                                            unsigned char *out)
{
    psa_hash_operation_t op = PSA_HASH_OPERATION_INIT;
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
    size_t output_hash_len;
    unsigned short checksum;

    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;
    }

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

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

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

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

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

    checksum = lmots_checksum_calculate(params, out);
    mbedtls_lms_unsigned_int_to_network_bytes(checksum, CHECKSUM_LEN,
                                              out + MBEDTLS_LMOTS_N_HASH_LEN(params->type));

exit:
    psa_hash_abort(&op);

    return PSA_TO_MBEDTLS_ERR(status);
}

/* Hash each element of the string of digits (+ checksum), producing a hash
 * output for each element. This is used in several places (by varying the
 * hash_idx_min/max_values) in order to calculate a public key from a private
 * key (RFC8554 Algorithm 1 step 4), in order to sign a message (RFC8554
 * Algorithm 3 step 5), and to calculate a public key candidate from a
 * signature and message (RFC8554 Algorithm 4b step 3).
 *
 *  params              The LMOTS parameter set, I and q values which
 *                      describe the key being used.
 *
 *  x_digit_array       The array of digits (of size P, 34 in the case of
 *                      MBEDTLS_LMOTS_SHA256_N32_W8).
 *
 *  hash_idx_min_values An array of the starting values of the j iterator
 *                      for each of the members of the digit array. If
 *                      this value in NULL, then all iterators will start
 *                      at 0.
 *
 *  hash_idx_max_values An array of the upper bound values of the j
 *                      iterator for each of the members of the digit
 *                      array. If this value in NULL, then iterator is
 *                      bounded to be less than 2^w - 1 (255 in the case
 *                      of MBEDTLS_LMOTS_SHA256_N32_W8)
 *
 *  output              An array containing a hash output for each member
 *                      of the digit string P. In the case of
 *                      MBEDTLS_LMOTS_SHA256_N32_W8, this is of size 32 *
 *                      34.
 */
static int hash_digit_array(const mbedtls_lmots_parameters_t *params,
                            const unsigned char *x_digit_array,
                            const unsigned char *hash_idx_min_values,
                            const unsigned char *hash_idx_max_values,
                            unsigned char *output)
{
    unsigned int i_digit_idx;
    unsigned char i_digit_idx_bytes[I_DIGIT_IDX_LEN];
    unsigned int j_hash_idx;
    unsigned char j_hash_idx_bytes[J_HASH_IDX_LEN];
    unsigned int j_hash_idx_min;
    unsigned int j_hash_idx_max;
    psa_hash_operation_t op = PSA_HASH_OPERATION_INIT;
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
    size_t output_hash_len;
    unsigned char tmp_hash[MBEDTLS_LMOTS_N_HASH_LEN_MAX];

    for (i_digit_idx = 0;
         i_digit_idx < MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT(params->type);
         i_digit_idx++) {

        memcpy(tmp_hash,
               &x_digit_array[i_digit_idx * MBEDTLS_LMOTS_N_HASH_LEN(params->type)],
               MBEDTLS_LMOTS_N_HASH_LEN(params->type));

        j_hash_idx_min = hash_idx_min_values != NULL ?
                         hash_idx_min_values[i_digit_idx] : 0;
        j_hash_idx_max = hash_idx_max_values != NULL ?
                         hash_idx_max_values[i_digit_idx] : DIGIT_MAX_VALUE;

        for (j_hash_idx = j_hash_idx_min;
             j_hash_idx < j_hash_idx_max;
             j_hash_idx++) {
            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;
            }

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

            mbedtls_lms_unsigned_int_to_network_bytes(i_digit_idx,
                                                      I_DIGIT_IDX_LEN,
                                                      i_digit_idx_bytes);
            status = psa_hash_update(&op, i_digit_idx_bytes, I_DIGIT_IDX_LEN);
            if (status != PSA_SUCCESS) {
                goto exit;
            }

            mbedtls_lms_unsigned_int_to_network_bytes(j_hash_idx,
                                                      J_HASH_IDX_LEN,
                                                      j_hash_idx_bytes);
            status = psa_hash_update(&op, j_hash_idx_bytes, J_HASH_IDX_LEN);
            if (status != PSA_SUCCESS) {
                goto exit;
            }

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

            status = psa_hash_finish(&op, tmp_hash, sizeof(tmp_hash),
                                     &output_hash_len);
            if (status != PSA_SUCCESS) {
                goto exit;
            }

            psa_hash_abort(&op);
        }

        memcpy(&output[i_digit_idx * MBEDTLS_LMOTS_N_HASH_LEN(params->type)],
               tmp_hash, MBEDTLS_LMOTS_N_HASH_LEN(params->type));
    }

exit:
    psa_hash_abort(&op);
    mbedtls_platform_zeroize(tmp_hash, sizeof(tmp_hash));

    return PSA_TO_MBEDTLS_ERR(status);
}

/* Combine the hashes of the digit array into a public key. This is used in
 * in order to calculate a public key from a private key (RFC8554 Algorithm 1
 * step 4), and to calculate a public key candidate from a signature and message
 * (RFC8554 Algorithm 4b step 3).
 *
 *  params           The LMOTS parameter set, I and q values which describe
 *                   the key being used.
 *  y_hashed_digits  The array of hashes, one hash for each digit of the
 *                   symbol array (which is of size P, 34 in the case of
 *                   MBEDTLS_LMOTS_SHA256_N32_W8)
 *
 *  pub_key          The output public key (or candidate public key in
 *                   case this is being run as part of signature
 *                   verification), in the form of a hash output.
 */
static int public_key_from_hashed_digit_array(const mbedtls_lmots_parameters_t *params,
                                              const unsigned char *y_hashed_digits,
                                              unsigned char *pub_key)
{
    psa_hash_operation_t op = PSA_HASH_OPERATION_INIT;
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
    size_t output_hash_len;

    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;
    }

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

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

    status = psa_hash_update(&op, y_hashed_digits,
                             MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT(params->type) *
                             MBEDTLS_LMOTS_N_HASH_LEN(params->type));
    if (status != PSA_SUCCESS) {
        goto exit;
    }

    status = psa_hash_finish(&op, pub_key,
                             MBEDTLS_LMOTS_N_HASH_LEN(params->type),
                             &output_hash_len);
    if (status != PSA_SUCCESS) {

exit:
        psa_hash_abort(&op);
    }

    return PSA_TO_MBEDTLS_ERR(status);
}

#if !defined(MBEDTLS_DEPRECATED_REMOVED)
int mbedtls_lms_error_from_psa(psa_status_t status)
{
    switch (status) {
        case PSA_SUCCESS:
            return 0;
        case PSA_ERROR_HARDWARE_FAILURE:
            return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
        case PSA_ERROR_NOT_SUPPORTED:
            return MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
        case PSA_ERROR_BUFFER_TOO_SMALL:
            return MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL;
        case PSA_ERROR_INVALID_ARGUMENT:
            return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
        default:
            return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
    }
}
#endif /* !MBEDTLS_DEPRECATED_REMOVED */

void mbedtls_lmots_public_init(mbedtls_lmots_public_t *ctx)
{
    memset(ctx, 0, sizeof(*ctx));
}

void mbedtls_lmots_public_free(mbedtls_lmots_public_t *ctx)
{
    mbedtls_platform_zeroize(ctx, sizeof(*ctx));
}

int mbedtls_lmots_import_public_key(mbedtls_lmots_public_t *ctx,
                                    const unsigned char *key, size_t key_len)
{
    if (key_len < MBEDTLS_LMOTS_SIG_TYPE_OFFSET + MBEDTLS_LMOTS_TYPE_LEN) {
        return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
    }

    ctx->params.type =
        (mbedtls_lmots_algorithm_type_t) mbedtls_lms_network_bytes_to_unsigned_int(
            MBEDTLS_LMOTS_TYPE_LEN,
            key +
            MBEDTLS_LMOTS_SIG_TYPE_OFFSET);

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

    memcpy(ctx->params.I_key_identifier,
           key + PUBLIC_KEY_I_KEY_ID_OFFSET,
           MBEDTLS_LMOTS_I_KEY_ID_LEN);

    memcpy(ctx->params.q_leaf_identifier,
           key + PUBLIC_KEY_Q_LEAF_ID_OFFSET,
           MBEDTLS_LMOTS_Q_LEAF_ID_LEN);

    memcpy(ctx->public_key,
           key + PUBLIC_KEY_KEY_HASH_OFFSET,
           MBEDTLS_LMOTS_N_HASH_LEN(ctx->params.type));

    ctx->have_public_key = 1;

    return 0;
}

int mbedtls_lmots_export_public_key(const mbedtls_lmots_public_t *ctx,
                                    unsigned char *key, size_t key_size,
                                    size_t *key_len)
{
    if (key_size < MBEDTLS_LMOTS_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_lms_unsigned_int_to_network_bytes(ctx->params.type,
                                              MBEDTLS_LMOTS_TYPE_LEN,
                                              key + MBEDTLS_LMOTS_SIG_TYPE_OFFSET);

    memcpy(key + PUBLIC_KEY_I_KEY_ID_OFFSET,
           ctx->params.I_key_identifier,
           MBEDTLS_LMOTS_I_KEY_ID_LEN);

    memcpy(key + PUBLIC_KEY_Q_LEAF_ID_OFFSET,
           ctx->params.q_leaf_identifier,
           MBEDTLS_LMOTS_Q_LEAF_ID_LEN);

    memcpy(key + PUBLIC_KEY_KEY_HASH_OFFSET, ctx->public_key,
           MBEDTLS_LMOTS_N_HASH_LEN(ctx->params.type));

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

    return 0;
}

int mbedtls_lmots_calculate_public_key_candidate(const mbedtls_lmots_parameters_t *params,
                                                 const unsigned char  *msg,
                                                 size_t msg_size,
                                                 const unsigned char *sig,
                                                 size_t sig_size,
                                                 unsigned char *out,
                                                 size_t out_size,
                                                 size_t *out_len)
{
    unsigned char tmp_digit_array[MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT_MAX];
    unsigned char y_hashed_digits[MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT_MAX][MBEDTLS_LMOTS_N_HASH_LEN_MAX];
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;

    if (msg == NULL && msg_size != 0) {
        return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
    }

    if (sig_size != MBEDTLS_LMOTS_SIG_LEN(params->type) ||
        out_size < MBEDTLS_LMOTS_N_HASH_LEN(params->type)) {
        return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
    }

    ret = create_digit_array_with_checksum(params, msg, msg_size,
                                           sig + MBEDTLS_LMOTS_SIG_C_RANDOM_OFFSET,
                                           tmp_digit_array);
    if (ret) {
        return ret;
    }

    ret = hash_digit_array(params,
                           sig + MBEDTLS_LMOTS_SIG_SIGNATURE_OFFSET(params->type),
                           tmp_digit_array, NULL, (unsigned char *) y_hashed_digits);
    if (ret) {
        return ret;
    }

    ret = public_key_from_hashed_digit_array(params,
                                             (unsigned char *) y_hashed_digits,
                                             out);
    if (ret) {
        return ret;
    }

    if (out_len != NULL) {
        *out_len = MBEDTLS_LMOTS_N_HASH_LEN(params->type);
    }

    return 0;
}

int mbedtls_lmots_verify(const mbedtls_lmots_public_t *ctx,
                         const unsigned char *msg, size_t msg_size,
                         const unsigned char *sig, size_t sig_size)
{
    unsigned char Kc_public_key_candidate[MBEDTLS_LMOTS_N_HASH_LEN_MAX];
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;

    if (msg == NULL && msg_size != 0) {
        return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
    }

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

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

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

    if (mbedtls_lms_network_bytes_to_unsigned_int(MBEDTLS_LMOTS_TYPE_LEN,
                                                  sig + MBEDTLS_LMOTS_SIG_TYPE_OFFSET) !=
        MBEDTLS_LMOTS_SHA256_N32_W8) {
        return MBEDTLS_ERR_LMS_VERIFY_FAILED;
    }

    ret = mbedtls_lmots_calculate_public_key_candidate(&ctx->params,
                                                       msg, msg_size, sig, sig_size,
                                                       Kc_public_key_candidate,
                                                       MBEDTLS_LMOTS_N_HASH_LEN(ctx->params.type),
                                                       NULL);
    if (ret) {
        return MBEDTLS_ERR_LMS_VERIFY_FAILED;
    }

    if (memcmp(&Kc_public_key_candidate, ctx->public_key,
               sizeof(ctx->public_key))) {
        return MBEDTLS_ERR_LMS_VERIFY_FAILED;
    }

    return 0;
}

#if defined(MBEDTLS_LMS_PRIVATE)

void mbedtls_lmots_private_init(mbedtls_lmots_private_t *ctx)
{
    memset(ctx, 0, sizeof(*ctx));
}

void mbedtls_lmots_private_free(mbedtls_lmots_private_t *ctx)
{
    mbedtls_platform_zeroize(ctx,
                             sizeof(*ctx));
}

int mbedtls_lmots_generate_private_key(mbedtls_lmots_private_t *ctx,
                                       mbedtls_lmots_algorithm_type_t type,
                                       const unsigned char I_key_identifier[MBEDTLS_LMOTS_I_KEY_ID_LEN],
                                       uint32_t q_leaf_identifier,
                                       const unsigned char *seed,
                                       size_t seed_size)
{
    psa_hash_operation_t op = PSA_HASH_OPERATION_INIT;
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
    size_t output_hash_len;
    unsigned int i_digit_idx;
    unsigned char i_digit_idx_bytes[2];
    unsigned char const_bytes[1];

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

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

    ctx->params.type = type;

    memcpy(ctx->params.I_key_identifier,
           I_key_identifier,
           sizeof(ctx->params.I_key_identifier));

    mbedtls_lms_unsigned_int_to_network_bytes(q_leaf_identifier,
                                              MBEDTLS_LMOTS_Q_LEAF_ID_LEN,
                                              ctx->params.q_leaf_identifier);

    mbedtls_lms_unsigned_int_to_network_bytes(0xFF, sizeof(const_bytes),
                                              const_bytes);

    for (i_digit_idx = 0;
         i_digit_idx < MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT(ctx->params.type);
         i_digit_idx++) {
        status = psa_hash_setup(&op, PSA_ALG_SHA_256);
        if (status != PSA_SUCCESS) {
            goto exit;
        }

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

        status = psa_hash_update(&op,
                                 ctx->params.q_leaf_identifier,
                                 MBEDTLS_LMOTS_Q_LEAF_ID_LEN);
        if (status != PSA_SUCCESS) {
            goto exit;
        }

        mbedtls_lms_unsigned_int_to_network_bytes(i_digit_idx, I_DIGIT_IDX_LEN,
                                                  i_digit_idx_bytes);
        status = psa_hash_update(&op, i_digit_idx_bytes, I_DIGIT_IDX_LEN);
        if (status != PSA_SUCCESS) {
            goto exit;
        }

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

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

        status = psa_hash_finish(&op,
                                 ctx->private_key[i_digit_idx],
                                 MBEDTLS_LMOTS_N_HASH_LEN(ctx->params.type),
                                 &output_hash_len);
        if (status != PSA_SUCCESS) {
            goto exit;
        }

        psa_hash_abort(&op);
    }

    ctx->have_private_key = 1;

exit:
    psa_hash_abort(&op);

    return PSA_TO_MBEDTLS_ERR(status);
}

int mbedtls_lmots_calculate_public_key(mbedtls_lmots_public_t *ctx,
                                       const mbedtls_lmots_private_t *priv_ctx)
{
    unsigned char y_hashed_digits[MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT_MAX][MBEDTLS_LMOTS_N_HASH_LEN_MAX];
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;

    /* Check that a private key is loaded */
    if (!priv_ctx->have_private_key) {
        return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
    }

    ret = hash_digit_array(&priv_ctx->params,
                           (unsigned char *) priv_ctx->private_key, NULL,
                           NULL, (unsigned char *) y_hashed_digits);
    if (ret) {
        goto exit;
    }

    ret = public_key_from_hashed_digit_array(&priv_ctx->params,
                                             (unsigned char *) y_hashed_digits,
                                             ctx->public_key);
    if (ret) {
        goto exit;
    }

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

    ctx->have_public_key = 1;

exit:
    mbedtls_platform_zeroize(y_hashed_digits, sizeof(y_hashed_digits));

    return ret;
}

int mbedtls_lmots_sign(mbedtls_lmots_private_t *ctx,
                       int (*f_rng)(void *, unsigned char *, size_t),
                       void *p_rng, const unsigned char *msg, size_t msg_size,
                       unsigned char *sig, size_t sig_size, size_t *sig_len)
{
    unsigned char tmp_digit_array[MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT_MAX];
    /* Create a temporary buffer to prepare the signature in. This allows us to
     * finish creating a signature (ensuring the process doesn't fail), and then
     * erase the private key **before** writing any data into the sig parameter
     * buffer. If data were directly written into the sig buffer, it might leak
     * a partial signature on failure, which effectively compromises the private
     * key.
     */
    unsigned char tmp_sig[MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT_MAX][MBEDTLS_LMOTS_N_HASH_LEN_MAX];
    unsigned char tmp_c_random[MBEDTLS_LMOTS_N_HASH_LEN_MAX];
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;

    if (msg == NULL && msg_size != 0) {
        return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
    }

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

    /* Check that a private key is loaded */
    if (!ctx->have_private_key) {
        return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
    }

    ret = f_rng(p_rng, tmp_c_random,
                MBEDTLS_LMOTS_N_HASH_LEN(ctx->params.type));
    if (ret) {
        return ret;
    }

    ret = create_digit_array_with_checksum(&ctx->params,
                                           msg, msg_size,
                                           tmp_c_random,
                                           tmp_digit_array);
    if (ret) {
        goto exit;
    }

    ret = hash_digit_array(&ctx->params, (unsigned char *) ctx->private_key,
                           NULL, tmp_digit_array, (unsigned char *) tmp_sig);
    if (ret) {
        goto exit;
    }

    mbedtls_lms_unsigned_int_to_network_bytes(ctx->params.type,
                                              MBEDTLS_LMOTS_TYPE_LEN,
                                              sig + MBEDTLS_LMOTS_SIG_TYPE_OFFSET);

    /* Test hook to check if sig is being written to before we invalidate the
     * private key.
     */
#if defined(MBEDTLS_TEST_HOOKS)
    if (mbedtls_lmots_sign_private_key_invalidated_hook != NULL) {
        ret = (*mbedtls_lmots_sign_private_key_invalidated_hook)(sig);
        if (ret != 0) {
            return ret;
        }
    }
#endif /* defined(MBEDTLS_TEST_HOOKS) */

    /* We've got a valid signature now, so it's time to make sure the private
     * key can't be reused.
     */
    ctx->have_private_key = 0;
    mbedtls_platform_zeroize(ctx->private_key,
                             sizeof(ctx->private_key));

    memcpy(sig + MBEDTLS_LMOTS_SIG_C_RANDOM_OFFSET, tmp_c_random,
           MBEDTLS_LMOTS_C_RANDOM_VALUE_LEN(ctx->params.type));

    memcpy(sig + MBEDTLS_LMOTS_SIG_SIGNATURE_OFFSET(ctx->params.type), tmp_sig,
           MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT(ctx->params.type)
           * MBEDTLS_LMOTS_N_HASH_LEN(ctx->params.type));

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

    ret = 0;

exit:
    mbedtls_platform_zeroize(tmp_digit_array, sizeof(tmp_digit_array));
    mbedtls_platform_zeroize(tmp_sig, sizeof(tmp_sig));

    return ret;
}

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