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.
diff --git a/ChangeLog b/ChangeLog
index 24835cd..51c002c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,6 +6,8 @@
    * Fix buffer overflow in RSA-PSS verification when the hash is too
      large for the key size. Found by Seth Terashima, Qualcomm Product
      Security Initiative, Qualcomm Technologies Inc.
+   * Fix buffer overflow in RSA-PSS verification when the unmasked
+     data is all zeros.
 
 Bugfix
    * Fix ssl_parse_record_header() to silently discard invalid DTLS records
diff --git a/library/rsa.c b/library/rsa.c
index db078d9..9e05b4b 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -1326,10 +1326,11 @@
     size_t siglen;
     unsigned char *p;
     unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
+    unsigned char *hash_start;
     unsigned char result[MBEDTLS_MD_MAX_SIZE];
     unsigned char zeros[8];
     unsigned int hlen;
-    size_t slen, msb;
+    size_t observed_salt_len, msb;
     const mbedtls_md_info_t *md_info;
     mbedtls_md_context_t md_ctx;
 
@@ -1371,7 +1372,7 @@
     hlen = mbedtls_md_get_size( md_info );
     if( siglen < hlen + 2 )
         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 );
 
@@ -1386,6 +1387,7 @@
         p++;
         siglen -= 1;
     }
+    else
     if( buf[0] >> ( 8 - siglen * 8 + msb ) )
         return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
 
@@ -1396,25 +1398,24 @@
         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 );
 
-    while( p < buf + siglen && *p == 0 )
+    while( p < hash_start - 1 && *p == 0 )
         p++;
 
-    if( p == buf + siglen ||
+    if( p == hash_start ||
         *p++ != 0x01 )
     {
         mbedtls_md_free( &md_ctx );
         return( MBEDTLS_ERR_RSA_INVALID_PADDING );
     }
 
-    /* Actual salt len */
-    slen -= p - buf;
+    observed_salt_len = hash_start - p;
 
     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 );
         return( MBEDTLS_ERR_RSA_INVALID_PADDING );
@@ -1425,12 +1426,12 @@
     mbedtls_md_starts( &md_ctx );
     mbedtls_md_update( &md_ctx, zeros, 8 );
     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_free( &md_ctx );
 
-    if( memcmp( p + slen, result, hlen ) == 0 )
+    if( memcmp( hash_start, result, hlen ) == 0 )
         return( 0 );
     else
         return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
diff --git a/tests/suites/test_suite_pkcs1_v21.data b/tests/suites/test_suite_pkcs1_v21.data
index 6d31494..7c202e9 100644
--- a/tests/suites/test_suite_pkcs1_v21.data
+++ b/tests/suites/test_suite_pkcs1_v21.data
@@ -819,3 +819,7 @@
 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
 
+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
+