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

* restricted/IOTSSL-1366/mbedtls-2.1:
  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:26:06 +02:00
commit 63906d9200
2 changed files with 21 additions and 10 deletions

View file

@ -16,6 +16,8 @@ Security
option if needed. option if needed.
* Fixed offset in FALLBACK_SCSV parsing that caused TLS server to fail to * Fixed offset in FALLBACK_SCSV parsing that caused TLS server to fail to
detect it sometimes. Reported by Hugo Leisink. #810 detect it sometimes. Reported by Hugo Leisink. #810
* Tighten ASN.1 parsing of RSA PKCS#1 v1.5 signatures, to avoid a
potential Bleichenbacher-style attack.
Bugfix Bugfix
* Remove macros from compat-1.3.h that correspond to deleted items from most * Remove macros from compat-1.3.h that correspond to deleted items from most

View file

@ -1473,7 +1473,7 @@ int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_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[MBEDTLS_MPI_MAX_SIZE]; unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
mbedtls_md_type_t msg_md_alg; mbedtls_md_type_t msg_md_alg;
const mbedtls_md_info_t *md_info; const mbedtls_md_info_t *md_info;
@ -1524,24 +1524,30 @@ int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_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 = mbedtls_asn1_get_tag( &p, end, &asn1_len, if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
if( p != p0 + 2 || asn1_len + 2 != len )
if( asn1_len + 2 != len )
return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
p0 = p;
if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len, if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
if( p != p0 + 2 || asn1_len + 6 + hashlen != len )
if( asn1_len + 6 + hashlen != len )
return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
p0 = p;
if( ( ret = mbedtls_asn1_get_tag( &p, end, &oid.len, MBEDTLS_ASN1_OID ) ) != 0 ) if( ( ret = mbedtls_asn1_get_tag( &p, end, &oid.len, MBEDTLS_ASN1_OID ) ) != 0 )
return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
if( p != p0 + 2 )
return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
oid.p = p; oid.p = p;
p += oid.len; p += oid.len;
@ -1555,13 +1561,16 @@ int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx,
/* /*
* assume the algorithm parameters must be NULL * assume the algorithm parameters must be NULL
*/ */
p0 = p;
if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len, MBEDTLS_ASN1_NULL ) ) != 0 ) if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len, MBEDTLS_ASN1_NULL ) ) != 0 )
return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
if( p != p0 + 2 )
if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
if( asn1_len != hashlen ) p0 = p;
if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
if( p != p0 + 2 || asn1_len != hashlen )
return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
if( memcmp( p, hash, hashlen ) != 0 ) if( memcmp( p, hash, hashlen ) != 0 )