Add MBEDTLS_LMS_PRIVATE define
To enable private key operations Signed-off-by: Raef Coles <raef.coles@arm.com>
This commit is contained in:
parent
ebd35b5b80
commit
ab4f87413a
8 changed files with 104 additions and 72 deletions
|
@ -358,6 +358,11 @@
|
|||
#error "MBEDTLS_LMS_C requires MBEDTLS_PSA_CRYPTO_C"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_LMS_PRIVATE) && \
|
||||
( !defined(MBEDTLS_LMS_C) )
|
||||
#error "MBEDTLS_LMS_PRIVATE requires MBEDTLS_LMS_C"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \
|
||||
( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) )
|
||||
#error "MBEDTLS_MEMORY_BUFFER_ALLOC_C defined, but not all prerequisites"
|
||||
|
|
|
@ -106,6 +106,7 @@ typedef struct {
|
|||
} mbedtls_lms_public_t;
|
||||
|
||||
|
||||
#ifdef MBEDTLS_LMS_PRIVATE
|
||||
/** LMS private context structure.
|
||||
*
|
||||
* A LMS private key is a set of LMOTS private keys, an index to the next usable
|
||||
|
@ -133,6 +134,7 @@ typedef struct {
|
|||
unsigned char MBEDTLS_PRIVATE(have_private_key); /*!< Whether the context contains a private key.
|
||||
Boolean values only. */
|
||||
} mbedtls_lms_private_t;
|
||||
#endif /* MBEDTLS_LMS_PRIVATE */
|
||||
|
||||
/**
|
||||
* \brief This function initializes an LMS public context
|
||||
|
@ -196,6 +198,7 @@ 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 );
|
||||
|
||||
#ifdef MBEDTLS_LMS_PRIVATE
|
||||
/**
|
||||
* \brief This function initializes an LMS private context
|
||||
*
|
||||
|
@ -328,6 +331,7 @@ int mbedtls_lms_sign( mbedtls_lms_private_t *ctx,
|
|||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void* p_rng, unsigned char *msg, unsigned int msg_size,
|
||||
unsigned char *sig, size_t sig_size, size_t *sig_len);
|
||||
#endif /* MBEDTLS_LMS_PRIVATE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -2469,12 +2469,24 @@
|
|||
* Module: library/lms.c
|
||||
* Caller:
|
||||
*
|
||||
* Requires: MBEDTLS_MD_C
|
||||
* Requires: MBEDTLS_PSA_CRYPTO_C
|
||||
*
|
||||
* Uncomment to enable the LMS signature algorithm.
|
||||
* Uncomment to enable the LMS verification algorithm and public key operations.
|
||||
*/
|
||||
#define MBEDTLS_LMS_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_LMS_PRIVATE
|
||||
*
|
||||
* Enable LMS private-key operations and signing code. Functions enabled by this
|
||||
* option are experimental, and should not be used in production.
|
||||
*
|
||||
* Requires: MBEDTLS_LMS_C
|
||||
*
|
||||
* Uncomment to enable the LMS signature algorithm and private key operations.
|
||||
*/
|
||||
// #define MBEDTLS_LMS_PRIVATE
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_NIST_KW_C
|
||||
*
|
||||
|
|
|
@ -455,6 +455,8 @@ int mbedtls_lmots_verify( mbedtls_lmots_public_t *ctx, const unsigned char *msg,
|
|||
return( 0 );
|
||||
}
|
||||
|
||||
#ifdef MBEDTLS_LMS_PRIVATE
|
||||
|
||||
void mbedtls_lmots_init_private( mbedtls_lmots_private_t *ctx )
|
||||
{
|
||||
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_lmots_private_t ) ) ;
|
||||
|
@ -716,4 +718,5 @@ int mbedtls_lmots_sign( mbedtls_lmots_private_t *ctx,
|
|||
return( 0 );
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_LMS_PRIVATE */
|
||||
#endif /* MBEDTLS_LMS_C */
|
||||
|
|
|
@ -101,6 +101,7 @@ typedef struct {
|
|||
Boolean values only. */
|
||||
} mbedtls_lmots_public_t;
|
||||
|
||||
#ifdef MBEDTLS_LMS_PRIVATE
|
||||
/** LMOTS private context structure.
|
||||
*
|
||||
* A LMOTS private key is one hash output for each of digit of the digest +
|
||||
|
@ -124,6 +125,7 @@ typedef struct {
|
|||
unsigned char MBEDTLS_PRIVATE(have_private_key); /*!< Whether the context contains a private key.
|
||||
Boolean values only. */
|
||||
} mbedtls_lmots_private_t;
|
||||
#endif /* MBEDTLS_LMS_PRIVATE */
|
||||
|
||||
/**
|
||||
* \brief This function converts an unsigned int into a
|
||||
|
@ -256,6 +258,8 @@ int mbedtls_lmots_verify( mbedtls_lmots_public_t *ctx, const unsigned char *msg,
|
|||
size_t msg_size, const unsigned char *sig,
|
||||
size_t sig_size );
|
||||
|
||||
#ifdef MBEDTLS_LMS_PRIVATE
|
||||
|
||||
/**
|
||||
* \brief This function initializes a private LMOTS context
|
||||
*
|
||||
|
@ -375,6 +379,7 @@ int mbedtls_lmots_sign( mbedtls_lmots_private_t *ctx,
|
|||
void *p_rng, const unsigned char *msg, size_t msg_size,
|
||||
unsigned char *sig, size_t sig_size, size_t* sig_len );
|
||||
|
||||
#endif /* MBEDTLS_LMS_PRIVATE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
139
library/lms.c
139
library/lms.c
|
@ -177,74 +177,6 @@ exit:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int calculate_merkle_tree( mbedtls_lms_private_t *ctx,
|
||||
unsigned char tree[MERKLE_TREE_NODE_AM][MBEDTLS_LMS_M_NODE_BYTES] )
|
||||
{
|
||||
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;
|
||||
priv_key_idx++ )
|
||||
{
|
||||
r_node_idx = MERKLE_TREE_INTERNAL_NODE_AM + priv_key_idx;
|
||||
|
||||
ret = create_merkle_leaf_value(
|
||||
ctx->params.I_key_identifier,
|
||||
ctx->ots_public_keys[priv_key_idx].public_key,
|
||||
r_node_idx, tree[r_node_idx] );
|
||||
if( ret )
|
||||
{
|
||||
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 - 1; r_node_idx > 0;
|
||||
r_node_idx-- )
|
||||
{
|
||||
ret = create_merkle_internal_value(
|
||||
ctx->params.I_key_identifier,
|
||||
tree[(r_node_idx * 2)], tree[(r_node_idx * 2 + 1)], r_node_idx, tree[r_node_idx] );
|
||||
if( ret )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int get_merkle_path( mbedtls_lms_private_t *ctx,
|
||||
unsigned int leaf_node_id,
|
||||
unsigned char path[MBEDTLS_LMS_H_TREE_HEIGHT][MBEDTLS_LMS_M_NODE_BYTES] )
|
||||
{
|
||||
unsigned char tree[MERKLE_TREE_NODE_AM][MBEDTLS_LMS_M_NODE_BYTES];
|
||||
unsigned int curr_node_id = leaf_node_id;
|
||||
unsigned int adjacent_node_id;
|
||||
unsigned int height;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
ret = calculate_merkle_tree( ctx, tree);
|
||||
if( ret )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
for( height = 0; height < MBEDTLS_LMS_H_TREE_HEIGHT; height++ )
|
||||
{
|
||||
adjacent_node_id = curr_node_id ^ 1;
|
||||
|
||||
memcpy( &path[height], &tree[adjacent_node_id], MBEDTLS_LMOTS_N_HASH_LEN );
|
||||
|
||||
curr_node_id >>=1;
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
void mbedtls_lms_init_public( mbedtls_lms_public_t *ctx )
|
||||
{
|
||||
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_lms_public_t ) ) ;
|
||||
|
@ -409,6 +341,76 @@ int mbedtls_lms_verify( const mbedtls_lms_public_t *ctx,
|
|||
return( 0 );
|
||||
}
|
||||
|
||||
#ifdef MBEDTLS_LMS_PRIVATE
|
||||
|
||||
static int calculate_merkle_tree( mbedtls_lms_private_t *ctx,
|
||||
unsigned char tree[MERKLE_TREE_NODE_AM][MBEDTLS_LMS_M_NODE_BYTES] )
|
||||
{
|
||||
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;
|
||||
priv_key_idx++ )
|
||||
{
|
||||
r_node_idx = MERKLE_TREE_INTERNAL_NODE_AM + priv_key_idx;
|
||||
|
||||
ret = create_merkle_leaf_value(
|
||||
ctx->params.I_key_identifier,
|
||||
ctx->ots_public_keys[priv_key_idx].public_key,
|
||||
r_node_idx, tree[r_node_idx] );
|
||||
if( ret )
|
||||
{
|
||||
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 - 1; r_node_idx > 0;
|
||||
r_node_idx-- )
|
||||
{
|
||||
ret = create_merkle_internal_value(
|
||||
ctx->params.I_key_identifier,
|
||||
tree[(r_node_idx * 2)], tree[(r_node_idx * 2 + 1)], r_node_idx, tree[r_node_idx] );
|
||||
if( ret )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int get_merkle_path( mbedtls_lms_private_t *ctx,
|
||||
unsigned int leaf_node_id,
|
||||
unsigned char path[MBEDTLS_LMS_H_TREE_HEIGHT][MBEDTLS_LMS_M_NODE_BYTES] )
|
||||
{
|
||||
unsigned char tree[MERKLE_TREE_NODE_AM][MBEDTLS_LMS_M_NODE_BYTES];
|
||||
unsigned int curr_node_id = leaf_node_id;
|
||||
unsigned int adjacent_node_id;
|
||||
unsigned int height;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
ret = calculate_merkle_tree( ctx, tree);
|
||||
if( ret )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
for( height = 0; height < MBEDTLS_LMS_H_TREE_HEIGHT; height++ )
|
||||
{
|
||||
adjacent_node_id = curr_node_id ^ 1;
|
||||
|
||||
memcpy( &path[height], &tree[adjacent_node_id], MBEDTLS_LMOTS_N_HASH_LEN );
|
||||
|
||||
curr_node_id >>=1;
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
void mbedtls_lms_init_private( mbedtls_lms_private_t *ctx )
|
||||
{
|
||||
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_lms_public_t ) ) ;
|
||||
|
@ -668,4 +670,5 @@ int mbedtls_lms_sign( mbedtls_lms_private_t *ctx,
|
|||
return( 0 );
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_LMS_PRIVATE */
|
||||
#endif /* MBEDTLS_LMS_C */
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
/* END_HEADER */
|
||||
|
||||
/* BEGIN_DEPENDENCIES
|
||||
* depends_on:MBEDTLS_LMS_C:MBEDTLS_PSA_CRYPTO_C:MBEDTLS_CTR_DRBG_C
|
||||
* depends_on:MBEDTLS_LMS_C:MBEDTLS_LMS_PRIVATE:MBEDTLS_PSA_CRYPTO_C:MBEDTLS_CTR_DRBG_C
|
||||
* END_DEPENDENCIES
|
||||
*/
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
/* END_HEADER */
|
||||
|
||||
/* BEGIN_DEPENDENCIES
|
||||
* depends_on:MBEDTLS_LMS_C:MBEDTLS_PSA_CRYPTO_C:MBEDTLS_CTR_DRBG_C
|
||||
* depends_on:MBEDTLS_LMS_C:MBEDTLS_LMS_PRIVATE:MBEDTLS_PSA_CRYPTO_C:MBEDTLS_CTR_DRBG_C
|
||||
* END_DEPENDENCIES
|
||||
*/
|
||||
|
||||
|
|
Loading…
Reference in a new issue