Add MBEDTLS_LMS_PRIVATE define
To enable private key operations
Signed-off-by: Raef Coles <raef.coles@arm.com>
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index 2921278..570d9db 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -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"
diff --git a/include/mbedtls/lms.h b/include/mbedtls/lms.h
index c463b2a..65b1b7e 100644
--- a/include/mbedtls/lms.h
+++ b/include/mbedtls/lms.h
@@ -106,6 +106,7 @@
} 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 @@
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 @@
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 (*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
}
diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h
index 8c833b1..c0caf75 100644
--- a/include/mbedtls/mbedtls_config.h
+++ b/include/mbedtls/mbedtls_config.h
@@ -2469,13 +2469,25 @@
* 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
*
* Enable the Key Wrapping mode for 128-bit block ciphers,
diff --git a/library/lmots.c b/library/lmots.c
index d92d385..bf66449 100644
--- a/library/lmots.c
+++ b/library/lmots.c
@@ -455,6 +455,8 @@
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 @@
return( 0 );
}
+#endif /* MBEDTLS_LMS_PRIVATE */
#endif /* MBEDTLS_LMS_C */
diff --git a/library/lmots.h b/library/lmots.h
index ca7d4bf..e784bf5 100644
--- a/library/lmots.h
+++ b/library/lmots.h
@@ -101,6 +101,7 @@
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 @@
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 @@
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 @@
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
}
diff --git a/library/lms.c b/library/lms.c
index 44d4c79..cb56cb3 100644
--- a/library/lms.c
+++ b/library/lms.c
@@ -177,74 +177,6 @@
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 @@
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 @@
return( 0 );
}
+#endif /* MBEDTLS_LMS_PRIVATE */
#endif /* MBEDTLS_LMS_C */
diff --git a/tests/suites/test_suite_lmots.function b/tests/suites/test_suite_lmots.function
index 4492daa..73c9aff 100644
--- a/tests/suites/test_suite_lmots.function
+++ b/tests/suites/test_suite_lmots.function
@@ -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
*/
diff --git a/tests/suites/test_suite_lms.function b/tests/suites/test_suite_lms.function
index 64ea900..22c8eb5 100644
--- a/tests/suites/test_suite_lms.function
+++ b/tests/suites/test_suite_lms.function
@@ -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
*/