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 55db24ca50
commit 511bb84c60
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.
= mbed TLS 1.3.21 branch released 2017-08-10 = mbed TLS 1.3.21 branch released 2017-08-10

View File

@ -1325,10 +1325,11 @@ int rsa_rsassa_pss_verify_ext( rsa_context *ctx,
size_t siglen; size_t siglen;
unsigned char *p; unsigned char *p;
unsigned char buf[POLARSSL_MPI_MAX_SIZE]; unsigned char buf[POLARSSL_MPI_MAX_SIZE];
unsigned char *hash_start;
unsigned char result[POLARSSL_MD_MAX_SIZE]; unsigned char result[POLARSSL_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 md_info_t *md_info; const md_info_t *md_info;
md_context_t md_ctx; md_context_t md_ctx;
@ -1370,7 +1371,7 @@ int rsa_rsassa_pss_verify_ext( rsa_context *ctx,
hlen = md_get_size( md_info ); hlen = md_get_size( md_info );
if( siglen < hlen + 2 ) if( siglen < hlen + 2 )
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); return( POLARSSL_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 );
@ -1385,6 +1386,7 @@ int rsa_rsassa_pss_verify_ext( 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( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
@ -1395,25 +1397,24 @@ int rsa_rsassa_pss_verify_ext( 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 )
{ {
md_free( &md_ctx ); md_free( &md_ctx );
return( POLARSSL_ERR_RSA_INVALID_PADDING ); return( POLARSSL_ERR_RSA_INVALID_PADDING );
} }
/* Actual salt len */ observed_salt_len = hash_start - p;
slen -= p - buf;
if( expected_salt_len != RSA_SALT_LEN_ANY && if( expected_salt_len != RSA_SALT_LEN_ANY &&
slen != (size_t) expected_salt_len ) observed_salt_len != (size_t) expected_salt_len )
{ {
md_free( &md_ctx ); md_free( &md_ctx );
return( POLARSSL_ERR_RSA_INVALID_PADDING ); return( POLARSSL_ERR_RSA_INVALID_PADDING );
@ -1424,12 +1425,12 @@ int rsa_rsassa_pss_verify_ext( rsa_context *ctx,
md_starts( &md_ctx ); md_starts( &md_ctx );
md_update( &md_ctx, zeros, 8 ); md_update( &md_ctx, zeros, 8 );
md_update( &md_ctx, hash, hashlen ); md_update( &md_ctx, hash, hashlen );
md_update( &md_ctx, p, slen ); md_update( &md_ctx, p, observed_salt_len );
md_finish( &md_ctx, result ); md_finish( &md_ctx, result );
md_free( &md_ctx ); 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( POLARSSL_ERR_RSA_VERIFY_FAILED ); return( POLARSSL_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:POLARSSL_SHA512_C depends_on:POLARSSL_SHA512_C
pkcs1_rsassa_pss_verify_ext:521:16:"0131b69860f3cb9bf85ea358fdf2bd2990f1b77a80d6a4fdf817a43dd896bdf7dd26af8ac0237f526e0d33b105c971fdbd4ffa9ece99fc469f31ecf429e8f562c1c3":16:"010001":POLARSSL_MD_SHA512:POLARSSL_MD_SHA512:POLARSSL_MD_SHA512:0:"":"00471794655837da498cbf27242807b40593a353c707eb22fd2cc5a3259e728ac4f1df676043eeec8e16c1175b3d9ac8cae72ec1d5772dd69de71c5677f19031568e":POLARSSL_ERR_RSA_INVALID_PADDING:POLARSSL_ERR_RSA_INVALID_PADDING pkcs1_rsassa_pss_verify_ext:521:16:"0131b69860f3cb9bf85ea358fdf2bd2990f1b77a80d6a4fdf817a43dd896bdf7dd26af8ac0237f526e0d33b105c971fdbd4ffa9ece99fc469f31ecf429e8f562c1c3":16:"010001":POLARSSL_MD_SHA512:POLARSSL_MD_SHA512:POLARSSL_MD_SHA512:0:"":"00471794655837da498cbf27242807b40593a353c707eb22fd2cc5a3259e728ac4f1df676043eeec8e16c1175b3d9ac8cae72ec1d5772dd69de71c5677f19031568e":POLARSSL_ERR_RSA_INVALID_PADDING:POLARSSL_ERR_RSA_INVALID_PADDING
RSASSA-PSS verify ext, all-zero padding, automatic salt length
depends_on:POLARSSL_SHA256_C
pkcs1_rsassa_pss_verify_ext:512:16:"00b076d23250816f9aab02307e452b97f0cae7598369b41624e8afc7971a59a13892f64b07eaa6ec928c160b2d6ec8f9d0dd5b63c8b3ac0767b4f65c892f56c10f":16:"010001":POLARSSL_MD_NONE:POLARSSL_MD_SHA256:POLARSSL_MD_SHA256:RSA_SALT_LEN_ANY:"":"63a35294577c7e593170378175b7df27c293dae583ec2a971426eb2d66f2af483e897bfae5dc20300a9d61a3644e08c3aee61a463690a3498901563c46041056":POLARSSL_ERR_RSA_INVALID_PADDING:POLARSSL_ERR_RSA_INVALID_PADDING