Update LMOTS signature use of temporary variables
Document them properly, and move random value to a temporary variable
Signed-off-by: Raef Coles <raef.coles@arm.com>
diff --git a/library/lmots.c b/library/lmots.c
index 50559e5..f5a2343 100644
--- a/library/lmots.c
+++ b/library/lmots.c
@@ -640,7 +640,15 @@
unsigned char *sig, size_t sig_size, size_t* sig_len )
{
unsigned char tmp_digit_array[MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT];
+ /* 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][MBEDTLS_LMOTS_N_HASH_LEN];
+ unsigned char tmp_c_random[MBEDTLS_LMOTS_C_RANDOM_VALUE_LEN];
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if ( msg == NULL && msg_size != 0 )
@@ -659,7 +667,7 @@
return( MBEDTLS_ERR_LMS_BAD_INPUT_DATA );
}
- ret = f_rng( p_rng, sig + MBEDTLS_LMOTS_SIG_C_RANDOM_OFFSET, MBEDTLS_LMOTS_N_HASH_LEN );
+ ret = f_rng( p_rng, tmp_c_random, MBEDTLS_LMOTS_N_HASH_LEN );
if ( ret )
{
return( ret );
@@ -667,7 +675,7 @@
ret = create_digit_array_with_checksum( &ctx->params,
msg, msg_size,
- sig + MBEDTLS_LMOTS_SIG_C_RANDOM_OFFSET,
+ tmp_c_random,
tmp_digit_array );
if ( ret )
{
@@ -693,8 +701,11 @@
mbedtls_platform_zeroize(ctx->private_key,
sizeof(ctx->private_key));
- memcpy(sig + MBEDTLS_LMOTS_SIG_SIGNATURE_OFFSET, tmp_sig,
- MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT * MBEDTLS_LMOTS_N_HASH_LEN);
+ memcpy( sig + MBEDTLS_LMOTS_SIG_C_RANDOM_OFFSET, tmp_c_random,
+ MBEDTLS_LMOTS_C_RANDOM_VALUE_LEN );
+
+ memcpy( sig + MBEDTLS_LMOTS_SIG_SIGNATURE_OFFSET, tmp_sig,
+ MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT * MBEDTLS_LMOTS_N_HASH_LEN );
if( sig_len != NULL )
{