diff --git a/ChangeLog b/ChangeLog index 55f637458..a88933729 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,6 +8,9 @@ Security https://arxiv.org/abs/1702.08719v2. Found and fix proposed by Michael Schwarz, Samuel Weiser, Daniel Gruss, Clémentine Maurice and Stefan Mangard. + * Wipe stack buffers in RSA private key operations + (rsa_rsaes_pkcs1_v15_decrypt(), rsa_rsaes_oaep_decrypt). + Found by Laurent Simon. Bugfix * Remove macros from compat-1.3.h that correspond to deleted items from most diff --git a/library/rsa.c b/library/rsa.c index a4afb2a5d..8d4da5349 100644 --- a/library/rsa.c +++ b/library/rsa.c @@ -60,6 +60,11 @@ #define mbedtls_free free #endif +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; +} + /* * Initialize an RSA context */ @@ -591,6 +596,8 @@ static void mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src, dlen -= use_len; } + + mbedtls_zeroize( mask, sizeof( mask ) ); } #endif /* MBEDTLS_PKCS1_V21 */ @@ -824,7 +831,7 @@ int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx, : mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf ); if( ret != 0 ) - return( ret ); + goto cleanup; /* * Unmask data and generate lHash @@ -833,7 +840,7 @@ int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx, if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 ) { mbedtls_md_free( &md_ctx ); - return( ret ); + goto cleanup; } @@ -884,15 +891,26 @@ int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx, * the different error conditions. */ if( bad != 0 ) - return( MBEDTLS_ERR_RSA_INVALID_PADDING ); + { + ret = MBEDTLS_ERR_RSA_INVALID_PADDING; + goto cleanup; + } if( ilen - ( p - buf ) > output_max_len ) - return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE ); + { + ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE; + goto cleanup; + } *olen = ilen - (p - buf); memcpy( output, p, *olen ); + ret = 0; - return( 0 ); +cleanup: + mbedtls_zeroize( buf, sizeof( buf ) ); + mbedtls_zeroize( lhash, sizeof( lhash ) ); + + return( ret ); } #endif /* MBEDTLS_PKCS1_V21 */ @@ -926,7 +944,7 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx, : mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf ); if( ret != 0 ) - return( ret ); + goto cleanup; p = buf; bad = 0; @@ -971,15 +989,25 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx, bad |= ( pad_count < 8 ); if( bad ) - return( MBEDTLS_ERR_RSA_INVALID_PADDING ); + { + ret = MBEDTLS_ERR_RSA_INVALID_PADDING; + goto cleanup; + } if( ilen - ( p - buf ) > output_max_len ) - return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE ); + { + ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE; + goto cleanup; + } *olen = ilen - (p - buf); memcpy( output, p, *olen ); + ret = 0; - return( 0 ); +cleanup: + mbedtls_zeroize( buf, sizeof( buf ) ); + + return( ret ); } #endif /* MBEDTLS_PKCS1_V15 */ @@ -1084,6 +1112,7 @@ int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx, if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 ) { mbedtls_md_free( &md_ctx ); + /* No need to zeroize salt: we didn't use it. */ return( ret ); } @@ -1094,6 +1123,7 @@ int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx, mbedtls_md_update( &md_ctx, hash, hashlen ); mbedtls_md_update( &md_ctx, salt, slen ); mbedtls_md_finish( &md_ctx, p ); + mbedtls_zeroize( salt, sizeof( salt ) ); // Compensate for boundary condition when applying mask //