RSA: Fix another buffer overflow in PSS signature verification

Fix buffer overflow in RSA-PSS signature verification when the masking
operation results in an all-zero buffer. This could happen at any key size.
This commit is contained in:
Gilles Peskine 2017-10-17 19:02:13 +02:00
parent 28a0c72795
commit 6a54b0240d
3 changed files with 17 additions and 10 deletions

View File

@ -6,6 +6,8 @@ Security
* Fix buffer overflow in RSA-PSS verification when the hash is too * Fix buffer overflow in RSA-PSS verification when the hash is too
large for the key size. Found by Seth Terashima, Qualcomm Product large for the key size. Found by Seth Terashima, Qualcomm Product
Security Initiative, Qualcomm Technologies Inc. Security Initiative, Qualcomm Technologies Inc.
* Fix buffer overflow in RSA-PSS verification when the unmasked
data is all zeros.
Features Features
* Allow comments in test data files. * Allow comments in test data files.

View File

@ -1319,10 +1319,11 @@ int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,
int ret; int ret;
size_t siglen; size_t siglen;
unsigned char *p; unsigned char *p;
unsigned char *hash_start;
unsigned char result[MBEDTLS_MD_MAX_SIZE]; unsigned char result[MBEDTLS_MD_MAX_SIZE];
unsigned char zeros[8]; unsigned char zeros[8];
unsigned int hlen; unsigned int hlen;
size_t slen, msb; size_t observed_salt_len, msb;
const mbedtls_md_info_t *md_info; const mbedtls_md_info_t *md_info;
mbedtls_md_context_t md_ctx; mbedtls_md_context_t md_ctx;
unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
@ -1364,7 +1365,7 @@ int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,
hlen = mbedtls_md_get_size( md_info ); hlen = mbedtls_md_get_size( md_info );
if( siglen < hlen + 2 ) if( siglen < hlen + 2 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
slen = siglen - hlen - 1; /* Currently length of salt + padding */ hash_start = buf + siglen - hlen - 1;
memset( zeros, 0, 8 ); memset( zeros, 0, 8 );
@ -1379,6 +1380,7 @@ int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,
p++; p++;
siglen -= 1; siglen -= 1;
} }
else
if( buf[0] >> ( 8 - siglen * 8 + msb ) ) if( buf[0] >> ( 8 - siglen * 8 + msb ) )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@ -1389,25 +1391,24 @@ int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,
return( ret ); return( ret );
} }
mgf_mask( p, siglen - hlen - 1, p + siglen - hlen - 1, hlen, &md_ctx ); mgf_mask( p, siglen - hlen - 1, hash_start, hlen, &md_ctx );
buf[0] &= 0xFF >> ( siglen * 8 - msb ); buf[0] &= 0xFF >> ( siglen * 8 - msb );
while( p < buf + siglen && *p == 0 ) while( p < hash_start - 1 && *p == 0 )
p++; p++;
if( p == buf + siglen || if( p == hash_start ||
*p++ != 0x01 ) *p++ != 0x01 )
{ {
mbedtls_md_free( &md_ctx ); mbedtls_md_free( &md_ctx );
return( MBEDTLS_ERR_RSA_INVALID_PADDING ); return( MBEDTLS_ERR_RSA_INVALID_PADDING );
} }
/* Actual salt len */ observed_salt_len = hash_start - p;
slen -= p - buf;
if( expected_salt_len != MBEDTLS_RSA_SALT_LEN_ANY && if( expected_salt_len != MBEDTLS_RSA_SALT_LEN_ANY &&
slen != (size_t) expected_salt_len ) observed_salt_len != (size_t) expected_salt_len )
{ {
mbedtls_md_free( &md_ctx ); mbedtls_md_free( &md_ctx );
return( MBEDTLS_ERR_RSA_INVALID_PADDING ); return( MBEDTLS_ERR_RSA_INVALID_PADDING );
@ -1419,12 +1420,12 @@ int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,
mbedtls_md_starts( &md_ctx ); mbedtls_md_starts( &md_ctx );
mbedtls_md_update( &md_ctx, zeros, 8 ); mbedtls_md_update( &md_ctx, zeros, 8 );
mbedtls_md_update( &md_ctx, hash, hashlen ); mbedtls_md_update( &md_ctx, hash, hashlen );
mbedtls_md_update( &md_ctx, p, slen ); mbedtls_md_update( &md_ctx, p, observed_salt_len );
mbedtls_md_finish( &md_ctx, result ); mbedtls_md_finish( &md_ctx, result );
mbedtls_md_free( &md_ctx ); mbedtls_md_free( &md_ctx );
if( memcmp( p + slen, result, hlen ) == 0 ) if( memcmp( hash_start, result, hlen ) == 0 )
return( 0 ); return( 0 );
else else
return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); return( MBEDTLS_ERR_RSA_VERIFY_FAILED );

View File

@ -819,3 +819,7 @@ RSASSA-PSS verify ext, 521-bit key, SHA-512, empty salt, bad signature
depends_on:MBEDTLS_SHA512_C depends_on:MBEDTLS_SHA512_C
pkcs1_rsassa_pss_verify_ext:521:16:"0131b69860f3cb9bf85ea358fdf2bd2990f1b77a80d6a4fdf817a43dd896bdf7dd26af8ac0237f526e0d33b105c971fdbd4ffa9ece99fc469f31ecf429e8f562c1c3":16:"010001":MBEDTLS_MD_SHA512:MBEDTLS_MD_SHA512:MBEDTLS_MD_SHA512:0:"":"00471794655837da498cbf27242807b40593a353c707eb22fd2cc5a3259e728ac4f1df676043eeec8e16c1175b3d9ac8cae72ec1d5772dd69de71c5677f19031568e":MBEDTLS_ERR_RSA_INVALID_PADDING:MBEDTLS_ERR_RSA_INVALID_PADDING pkcs1_rsassa_pss_verify_ext:521:16:"0131b69860f3cb9bf85ea358fdf2bd2990f1b77a80d6a4fdf817a43dd896bdf7dd26af8ac0237f526e0d33b105c971fdbd4ffa9ece99fc469f31ecf429e8f562c1c3":16:"010001":MBEDTLS_MD_SHA512:MBEDTLS_MD_SHA512:MBEDTLS_MD_SHA512:0:"":"00471794655837da498cbf27242807b40593a353c707eb22fd2cc5a3259e728ac4f1df676043eeec8e16c1175b3d9ac8cae72ec1d5772dd69de71c5677f19031568e":MBEDTLS_ERR_RSA_INVALID_PADDING:MBEDTLS_ERR_RSA_INVALID_PADDING
RSASSA-PSS verify ext, all-zero padding, automatic salt length
depends_on:MBEDTLS_SHA256_C
pkcs1_rsassa_pss_verify_ext:512:16:"00b076d23250816f9aab02307e452b97f0cae7598369b41624e8afc7971a59a13892f64b07eaa6ec928c160b2d6ec8f9d0dd5b63c8b3ac0767b4f65c892f56c10f":16:"010001":MBEDTLS_MD_NONE:MBEDTLS_MD_SHA256:MBEDTLS_MD_SHA256:MBEDTLS_RSA_SALT_LEN_ANY:"":"63a35294577c7e593170378175b7df27c293dae583ec2a971426eb2d66f2af483e897bfae5dc20300a9d61a3644e08c3aee61a463690a3498901563c46041056":MBEDTLS_ERR_RSA_INVALID_PADDING:MBEDTLS_ERR_RSA_INVALID_PADDING