From a6a94ad599351ac1fc208ab5d9a4a1248e8fe2a2 Mon Sep 17 00:00:00 2001 From: Moritz Fischer Date: Sat, 12 Nov 2022 08:28:04 -0800 Subject: [PATCH] lms: Move merkle tree generation to heap allocation Larger height (e.g. H=20) trees cannot be put on the stack. Allocate memory for them based on need using mbedtls_calloc(). Signed-off-by: Moritz Fischer --- library/lms.c | 47 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/library/lms.c b/library/lms.c index 46ea567f2f24..78c7d2666336 100644 --- a/library/lms.c +++ b/library/lms.c @@ -65,10 +65,9 @@ /* Currently only support H=10 */ #define H_TREE_HEIGHT_MAX 10 -#define MERKLE_TREE_NODE_AM_MAX (1u << (H_TREE_HEIGHT_MAX + 1u)) -#define MERKLE_TREE_NODE_AM(type) (1u << (MBEDTLS_LMS_H_TREE_HEIGHT(type) + 1u)) -#define MERKLE_TREE_LEAF_NODE_AM(type) (1u << MBEDTLS_LMS_H_TREE_HEIGHT(type)) -#define MERKLE_TREE_INTERNAL_NODE_AM(type) (1u << MBEDTLS_LMS_H_TREE_HEIGHT(type)) +#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) ((size_t) 1 << MBEDTLS_LMS_H_TREE_HEIGHT(type)) #define D_CONST_LEN (2) static const unsigned char D_LEAF_CONSTANT_BYTES[D_CONST_LEN] = {0x82, 0x82}; @@ -499,13 +498,21 @@ static int get_merkle_path( mbedtls_lms_private_t *ctx, unsigned int leaf_node_id, unsigned char *path ) { - unsigned char tree[MERKLE_TREE_NODE_AM_MAX][MBEDTLS_LMS_M_NODE_BYTES_MAX]; + 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; - ret = calculate_merkle_tree( ctx, ( unsigned char * )tree ); + tree = mbedtls_calloc( 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; @@ -516,9 +523,8 @@ static int get_merkle_path( mbedtls_lms_private_t *ctx, { adjacent_node_id = curr_node_id ^ 1; - memcpy( &path[height * MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type)], - &tree[adjacent_node_id], - MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type) ); + memcpy( &path[height * node_bytes], + &tree[adjacent_node_id * node_bytes], node_bytes ); curr_node_id >>=1; } @@ -526,7 +532,9 @@ static int get_merkle_path( mbedtls_lms_private_t *ctx, ret = 0; exit: - mbedtls_platform_zeroize( tree, sizeof( tree ) ); + mbedtls_platform_zeroize( tree, node_bytes * + MERKLE_TREE_NODE_AM(ctx->params.type) ); + mbedtls_free ( tree ); return( ret ); } @@ -659,8 +667,9 @@ int mbedtls_lms_generate_private_key( mbedtls_lms_private_t *ctx, int mbedtls_lms_calculate_public_key( mbedtls_lms_public_t *ctx, const mbedtls_lms_private_t *priv_ctx ) { - unsigned char tree[MERKLE_TREE_NODE_AM_MAX][MBEDTLS_LMS_M_NODE_BYTES_MAX]; + 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 ) { @@ -679,25 +688,33 @@ int mbedtls_lms_calculate_public_key( mbedtls_lms_public_t *ctx, return( MBEDTLS_ERR_LMS_BAD_INPUT_DATA ); } + tree = mbedtls_calloc( 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, ( unsigned char * )tree ); + 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[1], - MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type) ); + memcpy( ctx->T_1_pub_key, &tree[node_bytes], node_bytes ); ctx->have_public_key = 1; ret = 0; exit: - mbedtls_platform_zeroize( tree, sizeof( tree ) ); + mbedtls_platform_zeroize( tree, node_bytes * + MERKLE_TREE_NODE_AM(priv_ctx->params.type) ); + mbedtls_free ( tree ); return( ret ); }