Merge remote-tracking branch 'restricted/IOTSSL-1366/mbedtls-1.3' into mbedtls-1.3-restricted

* restricted/IOTSSL-1366/mbedtls-1.3:
  More length checks in RSA PKCS1v15 verify
  More length checks in RSA PKCS1v15 verify
This commit is contained in:
Manuel Pégourié-Gonnard 2017-06-08 20:27:19 +02:00
commit 9105b18f72
2 changed files with 21 additions and 10 deletions

View file

@ -8,6 +8,8 @@ Security
https://arxiv.org/abs/1702.08719v2. https://arxiv.org/abs/1702.08719v2.
Found and fix proposed by Michael Schwarz, Samuel Weiser, Daniel Gruss, Found and fix proposed by Michael Schwarz, Samuel Weiser, Daniel Gruss,
Clémentine Maurice and Stefan Mangard. Clémentine Maurice and Stefan Mangard.
* Tighten ASN.1 parsing of RSA PKCS#1 v1.5 signatures, to avoid a
potential Bleichenbacher-style attack.
Bugfix Bugfix
* Fix insufficient support for signature-hash-algorithm extension, * Fix insufficient support for signature-hash-algorithm extension,

View file

@ -1472,7 +1472,7 @@ int rsa_rsassa_pkcs1_v15_verify( rsa_context *ctx,
{ {
int ret; int ret;
size_t len, siglen, asn1_len; size_t len, siglen, asn1_len;
unsigned char *p, *end; unsigned char *p, *p0, *end;
unsigned char buf[POLARSSL_MPI_MAX_SIZE]; unsigned char buf[POLARSSL_MPI_MAX_SIZE];
md_type_t msg_md_alg; md_type_t msg_md_alg;
const md_info_t *md_info; const md_info_t *md_info;
@ -1523,24 +1523,30 @@ int rsa_rsassa_pkcs1_v15_verify( rsa_context *ctx,
end = p + len; end = p + len;
// Parse the ASN.1 structure inside the PKCS#1 v1.5 structure /*
// * Parse the ASN.1 structure inside the PKCS#1 v1.5 structure.
* Insist on 2-byte length tags, to protect against variants of
* Bleichenbacher's forgery attack against lax PKCS#1v1.5 verification.
*/
p0 = p;
if( ( ret = asn1_get_tag( &p, end, &asn1_len, if( ( ret = asn1_get_tag( &p, end, &asn1_len,
ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
return( POLARSSL_ERR_RSA_VERIFY_FAILED ); return( POLARSSL_ERR_RSA_VERIFY_FAILED );
if( p != p0 + 2 || asn1_len + 2 != len )
if( asn1_len + 2 != len )
return( POLARSSL_ERR_RSA_VERIFY_FAILED ); return( POLARSSL_ERR_RSA_VERIFY_FAILED );
p0 = p;
if( ( ret = asn1_get_tag( &p, end, &asn1_len, if( ( ret = asn1_get_tag( &p, end, &asn1_len,
ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
return( POLARSSL_ERR_RSA_VERIFY_FAILED ); return( POLARSSL_ERR_RSA_VERIFY_FAILED );
if( p != p0 + 2 || asn1_len + 6 + hashlen != len )
if( asn1_len + 6 + hashlen != len )
return( POLARSSL_ERR_RSA_VERIFY_FAILED ); return( POLARSSL_ERR_RSA_VERIFY_FAILED );
p0 = p;
if( ( ret = asn1_get_tag( &p, end, &oid.len, ASN1_OID ) ) != 0 ) if( ( ret = asn1_get_tag( &p, end, &oid.len, ASN1_OID ) ) != 0 )
return( POLARSSL_ERR_RSA_VERIFY_FAILED ); return( POLARSSL_ERR_RSA_VERIFY_FAILED );
if( p != p0 + 2 )
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
oid.p = p; oid.p = p;
p += oid.len; p += oid.len;
@ -1554,13 +1560,16 @@ int rsa_rsassa_pkcs1_v15_verify( rsa_context *ctx,
/* /*
* assume the algorithm parameters must be NULL * assume the algorithm parameters must be NULL
*/ */
p0 = p;
if( ( ret = asn1_get_tag( &p, end, &asn1_len, ASN1_NULL ) ) != 0 ) if( ( ret = asn1_get_tag( &p, end, &asn1_len, ASN1_NULL ) ) != 0 )
return( POLARSSL_ERR_RSA_VERIFY_FAILED ); return( POLARSSL_ERR_RSA_VERIFY_FAILED );
if( p != p0 + 2 )
if( ( ret = asn1_get_tag( &p, end, &asn1_len, ASN1_OCTET_STRING ) ) != 0 )
return( POLARSSL_ERR_RSA_VERIFY_FAILED ); return( POLARSSL_ERR_RSA_VERIFY_FAILED );
if( asn1_len != hashlen ) p0 = p;
if( ( ret = asn1_get_tag( &p, end, &asn1_len, ASN1_OCTET_STRING ) ) != 0 )
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
if( p != p0 + 2 || asn1_len != hashlen )
return( POLARSSL_ERR_RSA_VERIFY_FAILED ); return( POLARSSL_ERR_RSA_VERIFY_FAILED );
if( memcmp( p, hash, hashlen ) != 0 ) if( memcmp( p, hash, hashlen ) != 0 )