/*
 * 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/crypto.h"

#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( mbedtls_lms_error_from_psa( 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( mbedtls_lms_error_from_psa( 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( mbedtls_lms_error_from_psa( status ) );
}

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

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_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 ( mbedtls_lms_error_from_psa( 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) */
