From 1c022a698303431dbc0c3cd1693f5db5b8fafbca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 17 Nov 2014 12:24:41 +0100 Subject: [PATCH] Fix memory leaks in PKCS#5 and PKCS#12 --- ChangeLog | 1 + library/pkcs12.c | 33 +++++++++++++++++++++------------ library/pkcs5.c | 22 ++++++++++++++++------ 3 files changed, 38 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index 436b0708c..cae9e01a6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -17,6 +17,7 @@ Security Bugfix * Fix potential undefined behaviour in Camellia. + * Fix memory leaks in PKCS#5 and PKCS#12. Changes * Blind RSA private operations even when POLARSSL_RSA_NO_CRT is defined. diff --git a/library/pkcs12.c b/library/pkcs12.c index 2ee9c5ea2..649541ec7 100644 --- a/library/pkcs12.c +++ b/library/pkcs12.c @@ -190,21 +190,27 @@ int pkcs12_pbe( asn1_buf *pbe_params, int mode, return( ret ); if( ( ret = cipher_setkey( &cipher_ctx, key, keylen, mode ) ) != 0 ) - return( ret ); + goto cleanup; if( ( ret = cipher_reset( &cipher_ctx, iv ) ) != 0 ) - return( ret ); + goto cleanup; if( ( ret = cipher_update( &cipher_ctx, data, len, output, &olen ) ) != 0 ) { - return( ret ); + goto cleanup; } if( ( ret = cipher_finish( &cipher_ctx, output + olen, &olen ) ) != 0 ) - return( POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH ); + { + ret = POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH; + goto cleanup; + } - return( 0 ); +cleanup: + cipher_free_ctx( &cipher_ctx ); + + return( ret ); } static void pkcs12_fill_buffer( unsigned char *data, size_t data_len, @@ -268,25 +274,25 @@ int pkcs12_derivation( unsigned char *data, size_t datalen, { // Calculate hash( diversifier || salt_block || pwd_block ) if( ( ret = md_starts( &md_ctx ) ) != 0 ) - return( ret ); + goto cleanup; if( ( ret = md_update( &md_ctx, diversifier, v ) ) != 0 ) - return( ret ); + goto cleanup; if( ( ret = md_update( &md_ctx, salt_block, v ) ) != 0 ) - return( ret ); + goto cleanup; if( ( ret = md_update( &md_ctx, pwd_block, v ) ) != 0 ) - return( ret ); + goto cleanup; if( ( ret = md_finish( &md_ctx, hash_output ) ) != 0 ) - return( ret ); + goto cleanup; // Perform remaining ( iterations - 1 ) recursive hash calculations for( i = 1; i < iterations; i++ ) { if( ( ret = md( md_info, hash_output, hlen, hash_output ) ) != 0 ) - return( ret ); + goto cleanup; } use_len = ( datalen > hlen ) ? hlen : datalen; @@ -324,7 +330,10 @@ int pkcs12_derivation( unsigned char *data, size_t datalen, } } - return( 0 ); +cleanup: + md_free_ctx( &md_ctx ); + + return( ret ); } #endif /* POLARSSL_PKCS12_C */ diff --git a/library/pkcs5.c b/library/pkcs5.c index 9826c5db7..969f4dc61 100644 --- a/library/pkcs5.c +++ b/library/pkcs5.c @@ -214,30 +214,40 @@ int pkcs5_pbes2( asn1_buf *pbe_params, int mode, return( ret ); if( ( ret = cipher_init_ctx( &cipher_ctx, cipher_info ) ) != 0 ) + { + md_free_ctx( &md_ctx ); return( ret ); + } if ( ( ret = pkcs5_pbkdf2_hmac( &md_ctx, pwd, pwdlen, salt.p, salt.len, iterations, keylen, key ) ) != 0 ) { - return( ret ); + goto cleanup; } if( ( ret = cipher_setkey( &cipher_ctx, key, keylen, mode ) ) != 0 ) - return( ret ); + goto cleanup; if( ( ret = cipher_reset( &cipher_ctx, iv ) ) != 0 ) - return( ret ); + goto cleanup; if( ( ret = cipher_update( &cipher_ctx, data, datalen, output, &olen ) ) != 0 ) { - return( ret ); + goto cleanup; } if( ( ret = cipher_finish( &cipher_ctx, output + olen, &olen ) ) != 0 ) - return( POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH ); + { + ret = POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH; + goto cleanup; + } - return( 0 ); +cleanup: + md_free_ctx( &md_ctx ); + cipher_free_ctx( &cipher_ctx ); + + return( ret ); } int pkcs5_pbkdf2_hmac( md_context_t *ctx, const unsigned char *password,