Merge branch 'mbedtls-1.3' into mbedtls-1.3-restricted
diff --git a/ChangeLog b/ChangeLog
index 854e86c..df48a2c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,10 +2,41 @@
 
 = mbed TLS 1.3.22 branch released 2017-xx-xx
 
+Security
+   * Fix heap corruption in implementation of truncated HMAC extension.
+     When the truncated HMAC extension is enabled and CBC is used,
+     sending a malicious application packet can be used to selectively
+     corrupt 6 bytes on the peer's heap, potentially leading to crash or
+     remote code execution. This can be triggered remotely from either
+     side.
+   * 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.
+   * Fix unsafe bounds check in ssl_parse_client_psk_identity() when adding
+     64kB to the address of the SSL buffer wraps around.
+   * Tighten should-be-constant-time memcmp against compiler optimizations.
+   * Ensure that buffers are cleared after use if they contain sensitive data.
+     Changes were introduced in multiple places in the library.
+   * Set PEM buffer to zero before freeing it, to avoid decoded private keys
+     being leaked to memory after release.
+   * Fix dhm_check_range() failing to detect trivial subgroups and potentially
+     leaking 1 bit of the private key. Reported by prashantkspatil.
+   * Make mpi_read_binary constant-time with respect to
+     the input data. Previously, trailing zero bytes were detected
+     and omitted for the sake of saving memory, but potentially
+     leading to slight timing differences.
+     Reported by Marco Macchetti, Kudelski Group.
+   * Wipe stack buffer temporarily holding EC private exponent
+     after keypair generation.
+
 Features
    * Allow comments in test data files.
 
 Bugfix
+   * Fix typo in ssl.h leading to a too small value of SSL_MAC_ADD
+     in case CBC is disabled but ARC4 is enabled.
    * Fix memory leak in ssl_set_hostname() when called multiple times.
      Found by projectgus and jethrogb, #836.
    * Fix usage help in ssl_server2 example. Found and fixed by Bei Lin.
@@ -17,6 +48,8 @@
    * Fix leap year calculation in x509_date_is_valid() to ensure that invalid
      dates on leap years with 100 and 400 intervals are handled correctly. Found
      by Nicholas Wilson. #694
+   * Fix some invalid RSA-PSS signatures with keys of size 8N+1 that were
+     accepted. Generating these signatures required the private key.
    * Fix out-of-memory problem when parsing 4096-bit PKCS8-encrypted RSA keys.
      Found independently by Florian in the mbed TLS forum and by Mishamax.
      #878, #1019.
diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h
index 9a3fb8a..fffc9a3 100644
--- a/include/polarssl/ssl.h
+++ b/include/polarssl/ssl.h
@@ -303,7 +303,7 @@
 #define SSL_COMPRESSION_ADD             0
 #endif
 
-#if defined(POLARSSL_RC4_C) || defined(POLARSSL_CIPHER_MODE_CBC)
+#if defined(POLARSSL_ARC4_C) || defined(POLARSSL_CIPHER_MODE_CBC)
 /* Ciphersuites using HMAC */
 #if defined(POLARSSL_SHA512_C)
 #define SSL_MAC_ADD                 48  /* SHA-384 used for HMAC */
@@ -2061,9 +2061,9 @@
 static inline int safer_memcmp( const void *a, const void *b, size_t n )
 {
     size_t i;
-    const unsigned char *A = (const unsigned char *) a;
-    const unsigned char *B = (const unsigned char *) b;
-    unsigned char diff = 0;
+    volatile const unsigned char *A = (volatile const unsigned char *) a;
+    volatile const unsigned char *B = (volatile const unsigned char *) b;
+    volatile unsigned char diff = 0;
 
     for( i = 0; i < n; i++ )
         diff |= A[i] ^ B[i];
diff --git a/library/bignum.c b/library/bignum.c
index 4829d91..0a95607 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -678,16 +678,20 @@
 int mpi_read_binary( mpi *X, const unsigned char *buf, size_t buflen )
 {
     int ret;
-    size_t i, j, n;
+    size_t i, j;
+    size_t const limbs = CHARS_TO_LIMBS( buflen );
 
-    for( n = 0; n < buflen; n++ )
-        if( buf[n] != 0 )
-            break;
+    /* Ensure that target MPI has exactly the necessary number of limbs */
+    if( X->n != limbs )
+    {
+        mpi_free( X );
+        mpi_init( X );
+        MPI_CHK( mpi_grow( X, limbs ) );
+    }
 
-    MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( buflen - n ) ) );
     MPI_CHK( mpi_lset( X, 0 ) );
 
-    for( i = buflen, j = 0; i > n; i--, j++ )
+    for( i = buflen, j = 0; i > 0; i--, j++ )
         X->p[j / ciL] |= ((t_uint) buf[i - 1]) << ((j % ciL) << 3);
 
 cleanup:
@@ -1880,6 +1884,7 @@
     MPI_CHK( mpi_read_binary( X, buf, size ) );
 
 cleanup:
+    polarssl_zeroize( buf, sizeof( buf ) );
     return( ret );
 }
 
diff --git a/library/ctr_drbg.c b/library/ctr_drbg.c
index 7b315e8..f66064f 100644
--- a/library/ctr_drbg.c
+++ b/library/ctr_drbg.c
@@ -402,20 +402,20 @@
         goto exit;
 
     if( fwrite( buf, 1, CTR_DRBG_MAX_INPUT, f ) != CTR_DRBG_MAX_INPUT )
-    {
         ret = POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR;
-        goto exit;
-    }
-
-    ret = 0;
+    else
+        ret = 0;
 
 exit:
+    polarssl_zeroize( buf, sizeof( buf ) );
+
     fclose( f );
     return( ret );
 }
 
 int ctr_drbg_update_seed_file( ctr_drbg_context *ctx, const char *path )
 {
+    int ret = 0;
     FILE *f;
     size_t n;
     unsigned char buf[ CTR_DRBG_MAX_INPUT ];
@@ -434,14 +434,16 @@
     }
 
     if( fread( buf, 1, n, f ) != n )
-    {
-        fclose( f );
-        return( POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR );
-    }
+        ret = POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR;
+    else
+        ctr_drbg_update( ctx, buf, n );
 
     fclose( f );
 
-    ctr_drbg_update( ctx, buf, n );
+    polarssl_zeroize( buf, sizeof( buf ) );
+
+    if( ret != 0 )
+        return( ret );
 
     return( ctr_drbg_write_seed_file( ctx, path ) );
 }
diff --git a/library/dhm.c b/library/dhm.c
index 48fba2a..85f362a 100644
--- a/library/dhm.c
+++ b/library/dhm.c
@@ -91,6 +91,9 @@
  *
  * Parameter should be: 2 <= public_param <= P - 2
  *
+ * This means that we need to return an error if
+ *              public_param < 2 or public_param > P-2
+ *
  * For more information on the attack, see:
  *  http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf
  *  http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643
@@ -98,17 +101,17 @@
 static int dhm_check_range( const mpi *param, const mpi *P )
 {
     mpi L, U;
-    int ret = POLARSSL_ERR_DHM_BAD_INPUT_DATA;
+    int ret = 0;
 
     mpi_init( &L ); mpi_init( &U );
 
     MPI_CHK( mpi_lset( &L, 2 ) );
     MPI_CHK( mpi_sub_int( &U, P, 2 ) );
 
-    if( mpi_cmp_mpi( param, &L ) >= 0 &&
-        mpi_cmp_mpi( param, &U ) <= 0 )
+    if( mpi_cmp_mpi( param, &L ) < 0 ||
+        mpi_cmp_mpi( param, &U ) > 0 )
     {
-        ret = 0;
+        ret = POLARSSL_ERR_DHM_BAD_INPUT_DATA;
     }
 
 cleanup:
@@ -532,7 +535,10 @@
     if( fread( *buf, 1, *n, f ) != *n )
     {
         fclose( f );
+
+        polarssl_zeroize( *buf, *n + 1 );
         polarssl_free( *buf );
+
         return( POLARSSL_ERR_DHM_FILE_IO_ERROR );
     }
 
diff --git a/library/ecp.c b/library/ecp.c
index 79066dc..f39e7eb 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -1854,7 +1854,6 @@
     {
         /* SEC1 3.2.1: Generate d such that 1 <= n < N */
         int count = 0;
-        unsigned char rnd[POLARSSL_ECP_MAX_BYTES];
 
         /*
          * Match the procedure given in RFC 6979 (deterministic ECDSA):
@@ -1865,8 +1864,7 @@
          */
         do
         {
-            MPI_CHK( f_rng( p_rng, rnd, n_size ) );
-            MPI_CHK( mpi_read_binary( d, rnd, n_size ) );
+            MPI_CHK( mpi_fill_random( d, n_size, f_rng, p_rng ) );
             MPI_CHK( mpi_shift_r( d, 8 * n_size - grp->nbits ) );
 
             /*
diff --git a/library/entropy.c b/library/entropy.c
index edd5721..e5e4b46 100644
--- a/library/entropy.c
+++ b/library/entropy.c
@@ -169,6 +169,8 @@
     sha256_update( &ctx->accumulator, p, use_len );
 #endif
 
+    polarssl_zeroize( tmp, sizeof( tmp ) );
+
     return( 0 );
 }
 
@@ -197,13 +199,11 @@
  */
 static int entropy_gather_internal( entropy_context *ctx )
 {
-    int ret, i;
+    int ret = POLARSSL_ERR_ENTROPY_NO_SOURCES_DEFINED;
+    int i;
     unsigned char buf[ENTROPY_MAX_GATHER];
     size_t olen;
 
-    if( ctx->source_count == 0 )
-        return( POLARSSL_ERR_ENTROPY_NO_SOURCES_DEFINED );
-
     /*
      * Run through our entropy sources
      */
@@ -213,7 +213,7 @@
         if( ( ret = ctx->source[i].f_source( ctx->source[i].p_source,
                         buf, ENTROPY_MAX_GATHER, &olen ) ) != 0 )
         {
-            return( ret );
+            goto cleanup;
         }
 
         /*
@@ -226,7 +226,10 @@
         }
     }
 
-    return( 0 );
+cleanup:
+    polarssl_zeroize( buf, sizeof( buf ) );
+
+    return( ret );
 }
 
 /*
@@ -327,6 +330,8 @@
     ret = 0;
 
 exit:
+    polarssl_zeroize( buf, sizeof( buf ) );
+
 #if defined(POLARSSL_THREADING_C)
     if( polarssl_mutex_unlock( &ctx->mutex ) != 0 )
         return( POLARSSL_ERR_THREADING_MUTEX_ERROR );
@@ -357,12 +362,15 @@
     ret = 0;
 
 exit:
+    polarssl_zeroize( buf, sizeof( buf ) );
+
     fclose( f );
     return( ret );
 }
 
 int entropy_update_seed_file( entropy_context *ctx, const char *path )
 {
+    int ret = 0;
     FILE *f;
     size_t n;
     unsigned char buf[ ENTROPY_MAX_SEED_SIZE ];
@@ -378,14 +386,16 @@
         n = ENTROPY_MAX_SEED_SIZE;
 
     if( fread( buf, 1, n, f ) != n )
-    {
-        fclose( f );
-        return( POLARSSL_ERR_ENTROPY_FILE_IO_ERROR );
-    }
+        ret = POLARSSL_ERR_ENTROPY_FILE_IO_ERROR;
+    else
+        ret = entropy_update_manual( ctx, buf, n );
 
     fclose( f );
 
-    entropy_update_manual( ctx, buf, n );
+    polarssl_zeroize( buf, sizeof( buf ) );
+
+    if( ret != 0 )
+        return( ret );
 
     return( entropy_write_seed_file( ctx, path ) );
 }
diff --git a/library/hmac_drbg.c b/library/hmac_drbg.c
index c7904d0..eece389 100644
--- a/library/hmac_drbg.c
+++ b/library/hmac_drbg.c
@@ -342,11 +342,14 @@
 
 exit:
     fclose( f );
+    polarssl_zeroize( buf, sizeof( buf ) );
+
     return( ret );
 }
 
 int hmac_drbg_update_seed_file( hmac_drbg_context *ctx, const char *path )
 {
+    int ret = 0;
     FILE *f;
     size_t n;
     unsigned char buf[ POLARSSL_HMAC_DRBG_MAX_INPUT ];
@@ -365,14 +368,16 @@
     }
 
     if( fread( buf, 1, n, f ) != n )
-    {
-        fclose( f );
-        return( POLARSSL_ERR_HMAC_DRBG_FILE_IO_ERROR );
-    }
+        ret = POLARSSL_ERR_HMAC_DRBG_FILE_IO_ERROR;
+    else
+        hmac_drbg_update( ctx, buf, n );
 
     fclose( f );
 
-    hmac_drbg_update( ctx, buf, n );
+    polarssl_zeroize( buf, sizeof( buf ) );
+
+    if( ret != 0 )
+        return( ret );
 
     return( hmac_drbg_write_seed_file( ctx, path ) );
 }
diff --git a/library/md2.c b/library/md2.c
index 2ac7eba..2d6123f 100644
--- a/library/md2.c
+++ b/library/md2.c
@@ -217,6 +217,7 @@
  */
 int md2_file( const char *path, unsigned char output[16] )
 {
+    int ret = 0;
     FILE *f;
     size_t n;
     md2_context ctx;
@@ -231,17 +232,16 @@
     while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
         md2_update( &ctx, buf, n );
 
-    md2_finish( &ctx, output );
-    md2_free( &ctx );
-
     if( ferror( f ) != 0 )
-    {
-        fclose( f );
-        return( POLARSSL_ERR_MD2_FILE_IO_ERROR );
-    }
+        ret = POLARSSL_ERR_MD2_FILE_IO_ERROR;
+    else
+        md2_finish( &ctx, output );
 
+    md2_free( &ctx );
+    polarssl_zeroize( buf, sizeof( buf ) );
     fclose( f );
-    return( 0 );
+
+    return( ret );
 }
 #endif /* POLARSSL_FS_IO */
 
diff --git a/library/md4.c b/library/md4.c
index 8754d2f..9c4a9b8 100644
--- a/library/md4.c
+++ b/library/md4.c
@@ -313,6 +313,7 @@
  */
 int md4_file( const char *path, unsigned char output[16] )
 {
+    int ret = 0;
     FILE *f;
     size_t n;
     md4_context ctx;
@@ -327,17 +328,16 @@
     while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
         md4_update( &ctx, buf, n );
 
-    md4_finish( &ctx, output );
-    md4_free( &ctx );
-
     if( ferror( f ) != 0 )
-    {
-        fclose( f );
-        return( POLARSSL_ERR_MD4_FILE_IO_ERROR );
-    }
+        ret = POLARSSL_ERR_MD4_FILE_IO_ERROR;
+    else
+        md4_finish( &ctx, output );
 
+    md4_free( &ctx );
+    polarssl_zeroize( buf, sizeof( buf ) );
     fclose( f );
-    return( 0 );
+
+    return( ret );
 }
 #endif /* POLARSSL_FS_IO */
 
diff --git a/library/md5.c b/library/md5.c
index 8c7ed1f..4a0f251 100644
--- a/library/md5.c
+++ b/library/md5.c
@@ -330,6 +330,7 @@
  */
 int md5_file( const char *path, unsigned char output[16] )
 {
+    int ret = 0;
     FILE *f;
     size_t n;
     md5_context ctx;
@@ -344,17 +345,16 @@
     while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
         md5_update( &ctx, buf, n );
 
-    md5_finish( &ctx, output );
-    md5_free( &ctx );
-
     if( ferror( f ) != 0 )
-    {
-        fclose( f );
-        return( POLARSSL_ERR_MD5_FILE_IO_ERROR );
-    }
+        ret = POLARSSL_ERR_MD5_FILE_IO_ERROR;
+    else
+        md5_finish( &ctx, output );
 
+    md5_free( &ctx );
+    polarssl_zeroize( buf, sizeof( buf ) );
     fclose( f );
-    return( 0 );
+
+    return( ret );
 }
 #endif /* POLARSSL_FS_IO */
 
diff --git a/library/pem.c b/library/pem.c
index 08c182f..1305bb4 100644
--- a/library/pem.c
+++ b/library/pem.c
@@ -345,6 +345,7 @@
 
     if( ( ret = base64_decode( buf, &len, s1, s2 - s1 ) ) != 0 )
     {
+        polarssl_zeroize( buf, len );
         polarssl_free( buf );
         return( POLARSSL_ERR_PEM_INVALID_DATA + ret );
     }
@@ -355,6 +356,7 @@
     ( defined(POLARSSL_DES_C) || defined(POLARSSL_AES_C) )
         if( pwd == NULL )
         {
+            polarssl_zeroize( buf, len );
             polarssl_free( buf );
             return( POLARSSL_ERR_PEM_PASSWORD_REQUIRED );
         }
@@ -391,10 +393,12 @@
          */
         if( len <= 2 || buf[0] != 0x30 || buf[1] > 0x83 )
         {
+            polarssl_zeroize( buf, len );
             polarssl_free( buf );
             return( POLARSSL_ERR_PEM_PASSWORD_MISMATCH );
         }
 #else
+        polarssl_zeroize( buf, len );
         polarssl_free( buf );
         return( POLARSSL_ERR_PEM_FEATURE_UNAVAILABLE );
 #endif /* POLARSSL_MD5_C && POLARSSL_CIPHER_MODE_CBC &&
@@ -409,6 +413,8 @@
 
 void pem_free( pem_context *ctx )
 {
+    if ( ctx->buf != NULL )
+        polarssl_zeroize( ctx->buf, ctx->buflen );
     polarssl_free( ctx->buf );
     polarssl_free( ctx->info );
 
diff --git a/library/pkparse.c b/library/pkparse.c
index 5786db7..8c184d1 100644
--- a/library/pkparse.c
+++ b/library/pkparse.c
@@ -101,7 +101,10 @@
     if( fread( *buf, 1, *n, f ) != *n )
     {
         fclose( f );
+
+        polarssl_zeroize( *buf, *n );
         polarssl_free( *buf );
+
         return( POLARSSL_ERR_PK_FILE_IO_ERROR );
     }
 
diff --git a/library/ripemd160.c b/library/ripemd160.c
index 2c196f4..7b5d02e 100644
--- a/library/ripemd160.c
+++ b/library/ripemd160.c
@@ -388,6 +388,7 @@
  */
 int ripemd160_file( const char *path, unsigned char output[20] )
 {
+    int ret = 0;
     FILE *f;
     size_t n;
     ripemd160_context ctx;
@@ -402,17 +403,16 @@
     while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
         ripemd160_update( &ctx, buf, n );
 
-    ripemd160_finish( &ctx, output );
-    ripemd160_free( &ctx );
-
     if( ferror( f ) != 0 )
-    {
-        fclose( f );
-        return( POLARSSL_ERR_RIPEMD160_FILE_IO_ERROR );
-    }
+        ret = POLARSSL_ERR_RIPEMD160_FILE_IO_ERROR;
+    else
+        ripemd160_finish( &ctx, output );
 
+    ripemd160_free( &ctx );
+    polarssl_zeroize( buf, sizeof( buf ) );
     fclose( f );
-    return( 0 );
+
+    return( ret );
 }
 #endif /* POLARSSL_FS_IO */
 
diff --git a/library/rsa.c b/library/rsa.c
index ca8f688..bbb0286 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -1325,10 +1325,11 @@
     size_t siglen;
     unsigned char *p;
     unsigned char buf[POLARSSL_MPI_MAX_SIZE];
+    unsigned char *hash_start;
     unsigned char result[POLARSSL_MD_MAX_SIZE];
     unsigned char zeros[8];
     unsigned int hlen;
-    size_t slen, msb;
+    size_t observed_salt_len, msb;
     const md_info_t *md_info;
     md_context_t md_ctx;
 
@@ -1368,7 +1369,6 @@
         return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
 
     hlen = md_get_size( md_info );
-    slen = siglen - hlen - 1; /* Currently length of salt + padding */
 
     memset( zeros, 0, 8 );
 
@@ -1376,6 +1376,9 @@
     //
     msb = mpi_msb( &ctx->N ) - 1;
 
+    if( buf[0] >> ( 8 - siglen * 8 + msb ) )
+        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
     // Compensate for boundary condition when applying mask
     //
     if( msb % 8 == 0 )
@@ -1383,8 +1386,10 @@
         p++;
         siglen -= 1;
     }
-    if( buf[0] >> ( 8 - siglen * 8 + msb ) )
+
+    if( siglen < hlen + 2 )
         return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+    hash_start = p + siglen - hlen - 1;
 
     md_init( &md_ctx );
     if( ( ret = md_init_ctx( &md_ctx, md_info ) ) != 0 )
@@ -1393,25 +1398,23 @@
         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 ||
-        *p++ != 0x01 )
+    if( *p++ != 0x01 )
     {
         md_free( &md_ctx );
         return( POLARSSL_ERR_RSA_INVALID_PADDING );
     }
 
-    /* Actual salt len */
-    slen -= p - buf;
+    observed_salt_len = hash_start - p;
 
     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 );
         return( POLARSSL_ERR_RSA_INVALID_PADDING );
@@ -1422,12 +1425,12 @@
     md_starts( &md_ctx );
     md_update( &md_ctx, zeros, 8 );
     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_free( &md_ctx );
 
-    if( memcmp( p + slen, result, hlen ) == 0 )
+    if( memcmp( hash_start, result, hlen ) == 0 )
         return( 0 );
     else
         return( POLARSSL_ERR_RSA_VERIFY_FAILED );
diff --git a/library/sha1.c b/library/sha1.c
index 44de872..a5a235b 100644
--- a/library/sha1.c
+++ b/library/sha1.c
@@ -363,6 +363,7 @@
  */
 int sha1_file( const char *path, unsigned char output[20] )
 {
+    int ret = 0;
     FILE *f;
     size_t n;
     sha1_context ctx;
@@ -377,17 +378,16 @@
     while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
         sha1_update( &ctx, buf, n );
 
-    sha1_finish( &ctx, output );
-    sha1_free( &ctx );
-
     if( ferror( f ) != 0 )
-    {
-        fclose( f );
-        return( POLARSSL_ERR_SHA1_FILE_IO_ERROR );
-    }
+        ret = POLARSSL_ERR_SHA1_FILE_IO_ERROR;
+    else
+        sha1_finish( &ctx, output );
 
+    sha1_free( &ctx );
+    polarssl_zeroize( buf, sizeof( buf ) );
     fclose( f );
-    return( 0 );
+
+    return( ret );
 }
 #endif /* POLARSSL_FS_IO */
 
diff --git a/library/sha256.c b/library/sha256.c
index 674fdf2..caae79f 100644
--- a/library/sha256.c
+++ b/library/sha256.c
@@ -366,6 +366,7 @@
  */
 int sha256_file( const char *path, unsigned char output[32], int is224 )
 {
+    int ret = 0;
     FILE *f;
     size_t n;
     sha256_context ctx;
@@ -380,17 +381,16 @@
     while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
         sha256_update( &ctx, buf, n );
 
-    sha256_finish( &ctx, output );
-    sha256_free( &ctx );
-
     if( ferror( f ) != 0 )
-    {
-        fclose( f );
-        return( POLARSSL_ERR_SHA256_FILE_IO_ERROR );
-    }
+        ret = POLARSSL_ERR_SHA256_FILE_IO_ERROR;
+    else
+        sha256_finish( &ctx, output );
 
+    sha256_free( &ctx );
+    polarssl_zeroize( buf, sizeof( buf ) );
     fclose( f );
-    return( 0 );
+
+    return( ret );
 }
 #endif /* POLARSSL_FS_IO */
 
diff --git a/library/sha512.c b/library/sha512.c
index bd607e0..5e51f7f 100644
--- a/library/sha512.c
+++ b/library/sha512.c
@@ -370,6 +370,7 @@
  */
 int sha512_file( const char *path, unsigned char output[64], int is384 )
 {
+    int ret = 0;
     FILE *f;
     size_t n;
     sha512_context ctx;
@@ -384,17 +385,16 @@
     while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
         sha512_update( &ctx, buf, n );
 
-    sha512_finish( &ctx, output );
-    sha512_free( &ctx );
-
     if( ferror( f ) != 0 )
-    {
-        fclose( f );
-        return( POLARSSL_ERR_SHA512_FILE_IO_ERROR );
-    }
+        ret = POLARSSL_ERR_SHA512_FILE_IO_ERROR;
+    else
+        sha512_finish( &ctx, output );
 
+    sha512_free( &ctx );
+    polarssl_zeroize( buf, sizeof( buf ) );
     fclose( f );
-    return( 0 );
+
+    return( ret );
 }
 #endif /* POLARSSL_FS_IO */
 
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index d141b05..dd6397c 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -3141,7 +3141,7 @@
     /*
      * Receive client pre-shared key identity name
      */
-    if( *p + 2 > end )
+    if( end - *p < 2 )
     {
         SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
         return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
@@ -3150,7 +3150,7 @@
     n = ( (*p)[0] << 8 ) | (*p)[1];
     *p += 2;
 
-    if( n < 1 || n > 65535 || *p + n > end )
+    if( n < 1 || n > 65535 || n > (size_t) ( end - *p ) )
     {
         SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
         return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index ee87bc0..855872b 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -1050,9 +1050,12 @@
 /*
  * SSLv3.0 MAC functions
  */
-static void ssl_mac( md_context_t *md_ctx, unsigned char *secret,
-                     unsigned char *buf, size_t len,
-                     unsigned char *ctr, int type )
+#define SSL_MAC_MAX_BYTES   20  /* MD-5 or SHA-1 */
+static void ssl_mac( md_context_t *md_ctx,
+                     const unsigned char *secret,
+                     const unsigned char *buf, size_t len,
+                     const unsigned char *ctr, int type,
+                     unsigned char out[SSL_MAC_MAX_BYTES] )
 {
     unsigned char header[11];
     unsigned char padding[48];
@@ -1077,14 +1080,14 @@
     md_update( md_ctx, padding, padlen  );
     md_update( md_ctx, header,  11      );
     md_update( md_ctx, buf,     len     );
-    md_finish( md_ctx, buf +    len     );
+    md_finish( md_ctx, out              );
 
     memset( padding, 0x5C, padlen );
     md_starts( md_ctx );
     md_update( md_ctx, secret,    md_size );
     md_update( md_ctx, padding,   padlen  );
-    md_update( md_ctx, buf + len, md_size );
-    md_finish( md_ctx, buf + len          );
+    md_update( md_ctx, out,       md_size );
+    md_finish( md_ctx, out                );
 }
 #endif /* POLARSSL_SSL_PROTO_SSL3 */
 
@@ -1130,10 +1133,15 @@
 #if defined(POLARSSL_SSL_PROTO_SSL3)
         if( ssl->minor_ver == SSL_MINOR_VERSION_0 )
         {
+            unsigned char mac[SSL_MAC_MAX_BYTES];
+
             ssl_mac( &ssl->transform_out->md_ctx_enc,
                       ssl->transform_out->mac_enc,
                       ssl->out_msg, ssl->out_msglen,
-                      ssl->out_ctr, ssl->out_msgtype );
+                      ssl->out_ctr, ssl->out_msgtype,
+                      mac );
+
+            memcpy( ssl->out_msg + ssl->out_msglen, mac, ssl->transform_out->maclen );
         }
         else
 #endif
@@ -1141,12 +1149,16 @@
         defined(POLARSSL_SSL_PROTO_TLS1_2)
         if( ssl->minor_ver >= SSL_MINOR_VERSION_1 )
         {
+            unsigned char mac[SSL_MAC_ADD];
+
             md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_ctr, 13 );
             md_hmac_update( &ssl->transform_out->md_ctx_enc,
                              ssl->out_msg, ssl->out_msglen );
-            md_hmac_finish( &ssl->transform_out->md_ctx_enc,
-                             ssl->out_msg + ssl->out_msglen );
+            md_hmac_finish( &ssl->transform_out->md_ctx_enc, mac );
             md_hmac_reset( &ssl->transform_out->md_ctx_enc );
+
+            memcpy( ssl->out_msg + ssl->out_msglen, mac,
+                    ssl->transform_out->maclen );
         }
         else
 #endif
@@ -1155,7 +1167,7 @@
             return( POLARSSL_ERR_SSL_INTERNAL_ERROR );
         }
 
-        SSL_DEBUG_BUF( 4, "computed mac",
+        SSL_DEBUG_BUF( 4, "expected mac",
                        ssl->out_msg + ssl->out_msglen,
                        ssl->transform_out->maclen );
 
@@ -1419,8 +1431,6 @@
     return( 0 );
 }
 
-#define POLARSSL_SSL_MAX_MAC_SIZE   48
-
 static int ssl_decrypt_buf( ssl_context *ssl )
 {
     size_t i;
@@ -1588,7 +1598,7 @@
 #if defined(POLARSSL_SSL_ENCRYPT_THEN_MAC)
         if( ssl->session_in->encrypt_then_mac == SSL_ETM_ENABLED )
         {
-            unsigned char computed_mac[POLARSSL_SSL_MAX_MAC_SIZE];
+            unsigned char mac_expect[SSL_MAC_ADD];
             unsigned char pseudo_hdr[13];
 
             SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) );
@@ -1606,15 +1616,15 @@
             md_hmac_update( &ssl->transform_in->md_ctx_dec, pseudo_hdr, 13 );
             md_hmac_update( &ssl->transform_in->md_ctx_dec,
                              ssl->in_iv, ssl->in_msglen );
-            md_hmac_finish( &ssl->transform_in->md_ctx_dec, computed_mac );
+            md_hmac_finish( &ssl->transform_in->md_ctx_dec, mac_expect );
             md_hmac_reset( &ssl->transform_in->md_ctx_dec );
 
             SSL_DEBUG_BUF( 4, "message  mac", ssl->in_iv + ssl->in_msglen,
                                               ssl->transform_in->maclen );
-            SSL_DEBUG_BUF( 4, "computed mac", computed_mac,
+            SSL_DEBUG_BUF( 4, "expected mac", mac_expect,
                                               ssl->transform_in->maclen );
 
-            if( safer_memcmp( ssl->in_iv + ssl->in_msglen, computed_mac,
+            if( safer_memcmp( ssl->in_iv + ssl->in_msglen, mac_expect,
                               ssl->transform_in->maclen ) != 0 )
             {
                 SSL_DEBUG_MSG( 1, ( "message mac does not match" ) );
@@ -1775,22 +1785,21 @@
 #if defined(POLARSSL_SOME_MODES_USE_MAC)
     if( auth_done == 0 )
     {
-        unsigned char tmp[POLARSSL_SSL_MAX_MAC_SIZE];
+        unsigned char mac_expect[SSL_MAC_ADD];
 
         ssl->in_msglen -= ssl->transform_in->maclen;
 
         ssl->in_hdr[3] = (unsigned char)( ssl->in_msglen >> 8 );
         ssl->in_hdr[4] = (unsigned char)( ssl->in_msglen      );
 
-        memcpy( tmp, ssl->in_msg + ssl->in_msglen, ssl->transform_in->maclen );
-
 #if defined(POLARSSL_SSL_PROTO_SSL3)
         if( ssl->minor_ver == SSL_MINOR_VERSION_0 )
         {
             ssl_mac( &ssl->transform_in->md_ctx_dec,
                       ssl->transform_in->mac_dec,
                       ssl->in_msg, ssl->in_msglen,
-                      ssl->in_ctr, ssl->in_msgtype );
+                      ssl->in_ctr, ssl->in_msgtype,
+                      mac_expect );
         }
         else
 #endif /* POLARSSL_SSL_PROTO_SSL3 */
@@ -1820,8 +1829,8 @@
             md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_ctr, 13 );
             md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_msg,
                              ssl->in_msglen );
-            md_hmac_finish( &ssl->transform_in->md_ctx_dec,
-                             ssl->in_msg + ssl->in_msglen );
+            md_hmac_finish( &ssl->transform_in->md_ctx_dec, mac_expect );
+
             /* Call md_process at least once due to cache attacks */
             for( j = 0; j < extra_run + 1; j++ )
                 md_process( &ssl->transform_in->md_ctx_dec, ssl->in_msg );
@@ -1836,11 +1845,11 @@
             return( POLARSSL_ERR_SSL_INTERNAL_ERROR );
         }
 
-        SSL_DEBUG_BUF( 4, "message  mac", tmp, ssl->transform_in->maclen );
-        SSL_DEBUG_BUF( 4, "computed mac", ssl->in_msg + ssl->in_msglen,
+        SSL_DEBUG_BUF( 4, "expected mac", mac_expect, ssl->transform_in->maclen );
+        SSL_DEBUG_BUF( 4, "message  mac", ssl->in_msg + ssl->in_msglen,
                        ssl->transform_in->maclen );
 
-        if( safer_memcmp( tmp, ssl->in_msg + ssl->in_msglen,
+        if( safer_memcmp( ssl->in_msg + ssl->in_msglen, mac_expect,
                          ssl->transform_in->maclen ) != 0 )
         {
 #if defined(POLARSSL_SSL_DEBUG_ALL)
@@ -4140,12 +4149,19 @@
         return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
     }
 
-    if( ssl->psk != NULL || ssl->psk_identity != NULL )
+    if( ssl->psk != NULL )
     {
+        polarssl_zeroize( ssl->psk, ssl->psk_len );
+
         polarssl_free( ssl->psk );
-        polarssl_free( ssl->psk_identity );
         ssl->psk = NULL;
+        ssl->psk_len = 0;
+    }
+    if( ssl->psk_identity != NULL )
+    {
+        polarssl_free( ssl->psk_identity );
         ssl->psk_identity = NULL;
+        ssl->psk_identity_len = 0;
     }
 
     if( ( ssl->psk = polarssl_malloc( psk_len ) ) == NULL ||
diff --git a/tests/data_files/rsa512.key b/tests/data_files/rsa512.key
new file mode 100644
index 0000000..1fd7987
--- /dev/null
+++ b/tests/data_files/rsa512.key
@@ -0,0 +1,9 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIBOwIBAAJBALB20jJQgW+aqwIwfkUrl/DK51mDabQWJOivx5caWaE4kvZLB+qm
+7JKMFgstbsj50N1bY8izrAdntPZciS9WwQ8CAwEAAQJAKYfNcIoB7II6PQmsrhrU
+Z5dZW3fSKNANX7X/A1DwR0DlF8uZnpWsWbYcRoXX7QjvepZqc54wryhW55Wlm6yI
+AQIhAOJIaLjSpbHjzzcJQ7mylxn2WGIlbJPPzJ9OaFZCZQvxAiEAx6OEAvl6JKa6
+6a+N2Wvhtcgb4qqR6UHQGJQYGJz5nP8CIAvgoR6ScAAWZRoOcm+c4DGMrLb6H+ji
+T2tNQkzEz2kBAiEAmw34GStU36STpa6RGJ4+tyZN6jWakDVqf7x+HpfFE1cCIQDc
+KzXIxec2taye4OeIa1v4W/MigMmYE9w93Uw/Qi3azA==
+-----END RSA PRIVATE KEY-----
diff --git a/tests/data_files/rsa521.key b/tests/data_files/rsa521.key
new file mode 100644
index 0000000..0b940aa
--- /dev/null
+++ b/tests/data_files/rsa521.key
@@ -0,0 +1,9 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIBPQIBAAJCATG2mGDzy5v4XqNY/fK9KZDxt3qA1qT9+BekPdiWvffdJq+KwCN/
+Um4NM7EFyXH9vU/6ns6Z/EafMez0Kej1YsHDAgMBAAECQCdoYjwdMSHp4kksL5Aa
+0kDc58ni0chy9IgXo+FHjTVmR9DkaZANrwfVvYMJxqYCZo0im1Dw7ZJBUDJQNXnl
+ZokCIRiSk66I24AWa7XGUFvatVwXWi2ACE4QEKqzWQe1mQ24/wIhDHD1TCKpqucA
+XDI+1N7EHs+fN4CfTSWe8FPGiK6q3VM9AiESrKKLi/q011U4KeS8SfR2blDcL2cg
+XFkuQWqxzzLoGOUCIQmgl5E0+Ypwe0zc7NYZFDarf4+ZjqxKQnXCvk0irMHcGQIh
+EVPli6RQb3Gcx7vXJHltzSTno7NElzBDRMBVUlBmVxAJ
+-----END RSA PRIVATE KEY-----
diff --git a/tests/data_files/rsa522.key b/tests/data_files/rsa522.key
new file mode 100644
index 0000000..18fbe70
--- /dev/null
+++ b/tests/data_files/rsa522.key
@@ -0,0 +1,9 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIBPgIBAAJCAtMCdT492ij0L02fkshkdCDqb7yXwQ+EmLlmqVPzV2mNZYEGDf4y
+yKuY20vFzirN8MHm5ASnWhMoJVDBqjfTzci/AgMBAAECQU05ffxf7uVg74yC9tKg
+qCa746NpMh3OM+HZrUxiOXv0sJMRXNEPD5HNLtgcNY6MI5NYbUvkOXktnFZpxWYP
+TH7BAiEeFJGs5Z6gRd2v/IbYLMFDHgjqho04INGTOvnyI7lGVKUCIRgJM7moFuoM
+UrKTmJK1uOzauWEykCKgc6BGH6TGZoEWkwIhBzQn2v82qO1ydOYGKRk2w2sa+Yd1
+pH5/kkHqf+m8QjKdAiEQ9eVW+4J30wxD0JyX4b1E/S5UpN5KYNhWX0US+6D3NBsC
+IRxePzdQlutZWg0Cnku3QE1tOLBCFlP7QVVl5FbKcY5H5w==
+-----END RSA PRIVATE KEY-----
diff --git a/tests/data_files/rsa528.key b/tests/data_files/rsa528.key
new file mode 100644
index 0000000..fd463b5
--- /dev/null
+++ b/tests/data_files/rsa528.key
@@ -0,0 +1,9 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIBRQIBAAJDAOMcJG1GSFmEJh/RdMqz1DVzRGAuzXk8R9vlQlLTe7NQvGNDWbGV
+FVQggORySktnIpG+V8dkj1Finq7yNOhH2ZzGXwIDAQABAkMAsWYyLglQSlwnS4NZ
+L1z4zieTqW3lomWr2+BgxkHbxl2w0Rx4L+Ezp+YK6mhtIQWNkoytPvWJJMS7Jrkg
+agMAHQJBAiIA+F1y5GO0Bv+igsNLXwwtbCqs8hAkavU9W8egt/oDbhzbAiIA6hds
+PZp/s1X7n7dwfmebSs+3vLZFuQfifN8XZLw0CXHNAiEuEzgDQrPdMIN3er96zImI
+rYoUBgabiQ9u/WPFfa4xOU0CIgDDYC089Tfjy72pPgcr2PkpZVhqro5esg/8PI5f
+yxx7TXkCIgCYoE8Y5IxomtL1ub1AQzPe9UyyUGzQB1yWeiloJh6LjxA=
+-----END RSA PRIVATE KEY-----
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index b82f18e..c027bc0 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -510,40 +510,40 @@
             "$P_SRV debug_level=4" \
             "$P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA" \
             0 \
-            -s "dumping 'computed mac' (20 bytes)" \
-            -S "dumping 'computed mac' (10 bytes)"
+            -s "dumping 'expected mac' (20 bytes)" \
+            -S "dumping 'expected mac' (10 bytes)"
 
 run_test    "Truncated HMAC: client disabled, server default" \
             "$P_SRV debug_level=4" \
             "$P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA \
              trunc_hmac=0" \
             0 \
-            -s "dumping 'computed mac' (20 bytes)" \
-            -S "dumping 'computed mac' (10 bytes)"
+            -s "dumping 'expected mac' (20 bytes)" \
+            -S "dumping 'expected mac' (10 bytes)"
 
 run_test    "Truncated HMAC: client enabled, server default" \
             "$P_SRV debug_level=4" \
             "$P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA \
              trunc_hmac=1" \
             0 \
-            -S "dumping 'computed mac' (20 bytes)" \
-            -s "dumping 'computed mac' (10 bytes)"
+            -S "dumping 'expected mac' (20 bytes)" \
+            -s "dumping 'expected mac' (10 bytes)"
 
 run_test    "Truncated HMAC: client enabled, server disabled" \
             "$P_SRV debug_level=4 trunc_hmac=0" \
             "$P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA \
              trunc_hmac=1" \
             0 \
-            -s "dumping 'computed mac' (20 bytes)" \
-            -S "dumping 'computed mac' (10 bytes)"
+            -s "dumping 'expected mac' (20 bytes)" \
+            -S "dumping 'expected mac' (10 bytes)"
 
 run_test    "Truncated HMAC: client enabled, server enabled" \
             "$P_SRV debug_level=4 trunc_hmac=1" \
             "$P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA \
              trunc_hmac=1" \
             0 \
-            -S "dumping 'computed mac' (20 bytes)" \
-            -s "dumping 'computed mac' (10 bytes)"
+            -S "dumping 'expected mac' (20 bytes)" \
+            -s "dumping 'expected mac' (10 bytes)"
 
 # Tests for Encrypt-then-MAC extension
 
diff --git a/tests/suites/test_suite_dhm.data b/tests/suites/test_suite_dhm.data
index f2cdeff..5dbe4c8 100644
--- a/tests/suites/test_suite_dhm.data
+++ b/tests/suites/test_suite_dhm.data
@@ -1,11 +1,23 @@
 Diffie-Hellman full exchange #1
-dhm_do_dhm:10:"23":10:"5"
+dhm_do_dhm:10:"23":10:"5":0
 
 Diffie-Hellman full exchange #2
-dhm_do_dhm:10:"93450983094850938450983409623":10:"9345098304850938450983409622"
+dhm_do_dhm:10:"93450983094850938450983409623":10:"9345098304850938450983409622":0
 
 Diffie-Hellman full exchange #3
-dhm_do_dhm:10:"93450983094850938450983409623982317398171298719873918739182739712938719287391879381271":10:"9345098309485093845098340962223981329819812792137312973297123912791271"
+dhm_do_dhm:10:"93450983094850938450983409623982317398171298719873918739182739712938719287391879381271":10:"9345098309485093845098340962223981329819812792137312973297123912791271":0
+
+Diffie-Hellman trivial subgroup #1
+dhm_do_dhm:10:"23":10:"1":POLARSSL_ERR_DHM_BAD_INPUT_DATA
+
+Diffie-Hellman trivial subgroup #2
+dhm_do_dhm:10:"23":10:"-1":POLARSSL_ERR_DHM_BAD_INPUT_DATA
+
+Diffie-Hellman small modulus
+dhm_do_dhm:10:"3":10:"5":POLARSSL_ERR_DHM_MAKE_PARAMS_FAILED
+
+Diffie-Hellman zero modulus
+dhm_do_dhm:10:"0":10:"5":POLARSSL_ERR_DHM_BAD_INPUT_DATA
 
 Diffie-Hallman load parameters from file
 dhm_file:"data_files/dhparams.pem":"9e35f430443a09904f3a39a979797d070df53378e79c2438bef4e761f3c714553328589b041c809be1d6c6b5f1fc9f47d3a25443188253a992a56818b37ba9de5a40d362e56eff0be5417474c125c199272c8fe41dea733df6f662c92ae76556e755d10c64e6a50968f67fc6ea73d0dca8569be2ba204e23580d8bca2f4975b3":"02":128
diff --git a/tests/suites/test_suite_dhm.function b/tests/suites/test_suite_dhm.function
index d7cabf4..f21e6e6 100644
--- a/tests/suites/test_suite_dhm.function
+++ b/tests/suites/test_suite_dhm.function
@@ -9,7 +9,7 @@
 
 /* BEGIN_CASE */
 void dhm_do_dhm( int radix_P, char *input_P,
-                 int radix_G, char *input_G )
+                 int radix_G, char *input_G, int result )
 {
     dhm_context ctx_srv;
     dhm_context ctx_cli;
@@ -44,7 +44,10 @@
     /*
      * First key exchange
      */
-    TEST_ASSERT( dhm_make_params( &ctx_srv, x_size, ske, &ske_len, &rnd_pseudo_rand, &rnd_info ) == 0 );
+    TEST_ASSERT( dhm_make_params( &ctx_srv, x_size, ske, &ske_len, &rnd_pseudo_rand, &rnd_info ) == result );
+    if ( result != 0 )
+        goto exit;
+
     ske[ske_len++] = 0;
     ske[ske_len++] = 0;
     TEST_ASSERT( dhm_read_params( &ctx_cli, &p, ske + ske_len ) == 0 );
diff --git a/tests/suites/test_suite_pkcs1_v21.data b/tests/suites/test_suite_pkcs1_v21.data
index a5b382f..85fb6c0 100644
--- a/tests/suites/test_suite_pkcs1_v21.data
+++ b/tests/suites/test_suite_pkcs1_v21.data
@@ -787,3 +787,47 @@
 depends_on:POLARSSL_SHA256_C
 pkcs1_rsassa_pss_verify_ext:1024:16:"00dd118a9f99bab068ca2aea3b6a6d5997ed4ec954e40deecea07da01eaae80ec2bb1340db8a128e891324a5c5f5fad8f590d7c8cacbc5fe931dafda1223735279461abaa0572b761631b3a8afe7389b088b63993a0a25ee45d21858bab9931aedd4589a631b37fcf714089f856549f359326dd1e0e86dde52ed66b4a90bda4095":16:"010001":POLARSSL_MD_NONE:POLARSSL_MD_SHA256:POLARSSL_MD_SHA1:RSA_SALT_LEN_ANY:"c0719e9a8d5d838d861dc6f675c899d2b309a3a65bb9fe6b11e5afcbf9a2c0b1":"7fc506d26ca3b22922a1ce39faaedd273161b82d9443c56f1a034f131ae4a18cae1474271cb4b66a17d9707ca58b0bdbd3c406b7e65bbcc9bbbce94dc45de807b4989b23b3e4db74ca29298137837eb90cc83d3219249bc7d480fceaf075203a86e54c4ecfa4e312e39f8f69d76534089a36ed9049ca9cfd5ab1db1fa75fe5c8":0:POLARSSL_ERR_RSA_INVALID_PADDING
 
+RSASSA-PSS verify ext, 512-bit key, empty salt, good signature
+depends_on:POLARSSL_SHA256_C
+pkcs1_rsassa_pss_verify_ext:512:16:"00b076d23250816f9aab02307e452b97f0cae7598369b41624e8afc7971a59a13892f64b07eaa6ec928c160b2d6ec8f9d0dd5b63c8b3ac0767b4f65c892f56c10f":16:"010001":POLARSSL_MD_SHA256:POLARSSL_MD_SHA256:POLARSSL_MD_SHA256:0:"":"ace8b03347da1b9a7a5e94a0d76359bb39c819bb170bef38ea84995ed653446c0ae87ede434cdf9d0cb2d7bf164cf427892363e6855a1d24d0ce5dd72acaf246":0:0
+
+RSASSA-PSS verify ext, 512-bit key, empty salt, bad signature
+depends_on:POLARSSL_SHA256_C
+pkcs1_rsassa_pss_verify_ext:512:16:"00b076d23250816f9aab02307e452b97f0cae7598369b41624e8afc7971a59a13892f64b07eaa6ec928c160b2d6ec8f9d0dd5b63c8b3ac0767b4f65c892f56c10f":16:"010001":POLARSSL_MD_SHA256:POLARSSL_MD_SHA256:POLARSSL_MD_SHA256:0:"":"ace8b03347da1b9a7a5e94a0d76359bb39c819bb170bef38ea84995ed653446c0ae87ede434cdf9d0cb2d7bf164cf427892363e6855a1d24d0ce5dd72acaf247":POLARSSL_ERR_RSA_INVALID_PADDING:POLARSSL_ERR_RSA_INVALID_PADDING
+
+RSASSA-PSS verify ext, 522-bit key, SHA-512, empty salt, good signature
+depends_on:POLARSSL_SHA512_C
+pkcs1_rsassa_pss_verify_ext:522:16:"02d302753e3dda28f42f4d9f92c8647420ea6fbc97c10f8498b966a953f357698d6581060dfe32c8ab98db4bc5ce2acdf0c1e6e404a75a13282550c1aa37d3cdc8bf":16:"010001":POLARSSL_MD_SHA512:POLARSSL_MD_SHA512:POLARSSL_MD_SHA512:0:"":"016752ae0b5dfbade6bbd3dd37868d48c8d741f92dca41c360aeda553204c2212a117b1a3d77e0d3f48723503c46e16c8a64de00f1dee3e37e478417452630859486":0:0
+
+RSASSA-PSS verify ext, 528-bit key, SHA-512, saltlen=64, good signature with saltlen=0
+depends_on:POLARSSL_SHA512_C
+pkcs1_rsassa_pss_verify_ext:528:16:"00e31c246d46485984261fd174cab3d4357344602ecd793c47dbe54252d37bb350bc634359b19515542080e4724a4b672291be57c7648f51629eaef234e847d99cc65f":16:"010001":POLARSSL_MD_SHA512:POLARSSL_MD_SHA512:POLARSSL_MD_SHA512:64:"":"a9ad7994ba3a1071124153486924448cc67a5af3a5d34e9261d53770782cc85f58e2edde5f7004652a645e3e9606530eb57de41df7298ae2be9dec69cc0d613ab629":0:POLARSSL_ERR_RSA_INVALID_PADDING
+
+RSASSA-PSS verify ext, 528-bit key, SHA-512, empty salt, good signature
+depends_on:POLARSSL_SHA512_C
+pkcs1_rsassa_pss_verify_ext:528:16:"00e31c246d46485984261fd174cab3d4357344602ecd793c47dbe54252d37bb350bc634359b19515542080e4724a4b672291be57c7648f51629eaef234e847d99cc65f":16:"010001":POLARSSL_MD_SHA512:POLARSSL_MD_SHA512:POLARSSL_MD_SHA512:0:"":"a9ad7994ba3a1071124153486924448cc67a5af3a5d34e9261d53770782cc85f58e2edde5f7004652a645e3e9606530eb57de41df7298ae2be9dec69cc0d613ab629":0:0
+
+RSASSA-PSS verify ext, 528-bit key, SHA-512, saltlen=64, good signature with saltlen=0
+depends_on:POLARSSL_SHA512_C
+pkcs1_rsassa_pss_verify_ext:528:16:"00e31c246d46485984261fd174cab3d4357344602ecd793c47dbe54252d37bb350bc634359b19515542080e4724a4b672291be57c7648f51629eaef234e847d99cc65f":16:"010001":POLARSSL_MD_SHA512:POLARSSL_MD_SHA512:POLARSSL_MD_SHA512:64:"":"a9ad7994ba3a1071124153486924448cc67a5af3a5d34e9261d53770782cc85f58e2edde5f7004652a645e3e9606530eb57de41df7298ae2be9dec69cc0d613ab629":0:POLARSSL_ERR_RSA_INVALID_PADDING
+
+RSASSA-PSS verify ext, 512-bit key, SHA-512 (hash too large)
+depends_on:POLARSSL_SHA512_C
+pkcs1_rsassa_pss_verify_ext:512:16:"00b076d23250816f9aab02307e452b97f0cae7598369b41624e8afc7971a59a13892f64b07eaa6ec928c160b2d6ec8f9d0dd5b63c8b3ac0767b4f65c892f56c10f":16:"010001":POLARSSL_MD_SHA512:POLARSSL_MD_SHA512:POLARSSL_MD_SHA512:0:"":"ace8b03347da1b9a7a5e94a0d76359bb39c819bb170bef38ea84995ed653446c0ae87ede434cdf9d0cb2d7bf164cf427892363e6855a1d24d0ce5dd72acaf246":POLARSSL_ERR_RSA_BAD_INPUT_DATA:POLARSSL_ERR_RSA_BAD_INPUT_DATA
+
+RSASSA-PSS verify ext, 521-bit key, SHA-512, empty salt, bad signature
+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_BAD_INPUT_DATA:POLARSSL_ERR_RSA_BAD_INPUT_DATA
+
+RSASSA-PSS verify ext, 521-bit key, SHA-256, empty salt, good signature
+depends_on:POLARSSL_SHA256_C
+pkcs1_rsassa_pss_verify_ext:521:16:"0131b69860f3cb9bf85ea358fdf2bd2990f1b77a80d6a4fdf817a43dd896bdf7dd26af8ac0237f526e0d33b105c971fdbd4ffa9ece99fc469f31ecf429e8f562c1c3":16:"010001":POLARSSL_MD_SHA256:POLARSSL_MD_SHA256:POLARSSL_MD_SHA256:0:"41":"009c4941157fa36288e467310b198ab0c615c40963d611ffeef03000549ded809235955ecc57adba44782e9497c004f480ba2b3d58db8335fe0b391075c02c843a6d":0:0
+
+RSASSA-PSS verify ext, 521-bit key, SHA-256, empty salt, flipped-highest-bit signature
+depends_on:POLARSSL_SHA256_C
+pkcs1_rsassa_pss_verify_ext:521:16:"0131b69860f3cb9bf85ea358fdf2bd2990f1b77a80d6a4fdf817a43dd896bdf7dd26af8ac0237f526e0d33b105c971fdbd4ffa9ece99fc469f31ecf429e8f562c1c3":16:"010001":POLARSSL_MD_SHA256:POLARSSL_MD_SHA256:POLARSSL_MD_SHA256:0:"41":"00e11a2403df681c44a1f73f014b6c9ad17847d0b673f7c2a801cee208d10ab5792c10cd0cd495a4b331aaa521409fca7cb1b0d978b3a84cd67e28078b98753e9466":POLARSSL_ERR_RSA_BAD_INPUT_DATA:POLARSSL_ERR_RSA_BAD_INPUT_DATA
+
+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
+