Merge remote-tracking branch 'restricted/iotssl-1398' into development-restricted

* restricted/iotssl-1398:
  Add ChangeLog entry
  Ensure application data records are not kept when fully processed
  Add hard assertion to mbedtls_ssl_read_record_layer
  Fix mbedtls_ssl_read
  Simplify retaining of messages for future processing
diff --git a/ChangeLog b/ChangeLog
index 9dcc3f2..a042c4e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,6 @@
 mbed TLS ChangeLog (Sorted per branch, date)
 
-= mbed TLS 2.x.x branch released xxxx-xx-xx
+= mbed TLS 2.5.1 released xxxx-xx-xx
 
 Security
    * Fixed unlimited overread of heap-based buffer in mbedtls_ssl_read().
@@ -13,6 +13,8 @@
      option if needed.
    * Fixed offset in FALLBACK_SCSV parsing that caused TLS server to fail to
      detect it sometimes. Reported by Hugo Leisink. #810
+   * Tighten parsing of RSA PKCS#1 v1.5 signatures, to avoid a
+     potential Bleichenbacher/BERserk-style attack.
 
 Bugfix
    * Remove invalid use of size zero arrays in ECJPAKE test suite.
@@ -29,6 +31,12 @@
      to not annihilate fatal errors in authentication mode
      MBEDTLS_SSL_VERIFY_OPTIONAL and to reflect bad EC curves
      within verification result.
+   * Fix modular inversion function on invalid modulus 1.
+     Found by blaufish. Fixes #641.
+   * Fix incorrect sign computation in modular exponentiation
+     when dealing with negative MPI. Found by Guido Vranken.
+   * Fix potential stack underflow in mpi_read_file.
+     Found by Guido Vranken.
 
 Changes
    * Send fatal alerts in many more cases instead of dropping the connection.
diff --git a/include/mbedtls/bignum.h b/include/mbedtls/bignum.h
index aa51556..1a5b4b6 100644
--- a/include/mbedtls/bignum.h
+++ b/include/mbedtls/bignum.h
@@ -340,7 +340,7 @@
 
 #if defined(MBEDTLS_FS_IO)
 /**
- * \brief          Read X from an opened file
+ * \brief          Read MPI from a line in an opened file
  *
  * \param X        Destination MPI
  * \param radix    Input numeric base
@@ -349,6 +349,15 @@
  * \return         0 if successful, MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if
  *                 the file read buffer is too small or a
  *                 MBEDTLS_ERR_MPI_XXX error code
+ *
+ * \note           On success, this function advances the file stream
+ *                 to the end of the current line or to EOF.
+ *
+ *                 The function returns 0 on an empty line.
+ *
+ *                 Leading whitespaces are ignored, as is a
+ *                 '0x' prefix for radix 16.
+ *
  */
 int mbedtls_mpi_read_file( mbedtls_mpi *X, int radix, FILE *fin );
 
@@ -665,8 +674,8 @@
  *
  * \return         0 if successful,
  *                 MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
- *                 MBEDTLS_ERR_MPI_BAD_INPUT_DATA if N is negative or nil
-                   MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if A has no inverse mod N
+ *                 MBEDTLS_ERR_MPI_BAD_INPUT_DATA if N is <= 1,
+                   MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if A has no inverse mod N.
  */
 int mbedtls_mpi_inv_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N );
 
diff --git a/library/bignum.c b/library/bignum.c
index 8b9082c..d3a150c 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -616,11 +616,11 @@
     if( slen == sizeof( s ) - 2 )
         return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
 
-    if( s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; }
-    if( s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; }
+    if( slen > 0 && s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; }
+    if( slen > 0 && s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; }
 
     p = s + slen;
-    while( --p >= s )
+    while( p-- > s )
         if( mpi_get_digit( &d, radix, *p ) != 0 )
             break;
 
@@ -1790,7 +1790,7 @@
      */
     MBEDTLS_MPI_CHK( mpi_montred( X, N, mm, &T ) );
 
-    if( neg )
+    if( neg && E->n != 0 && ( E->p[0] & 1 ) != 0 )
     {
         X->s = -1;
         MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( X, N, X ) );
@@ -1893,7 +1893,7 @@
     int ret;
     mbedtls_mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
 
-    if( mbedtls_mpi_cmp_int( N, 0 ) <= 0 )
+    if( mbedtls_mpi_cmp_int( N, 1 ) <= 0 )
         return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
 
     mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TU ); mbedtls_mpi_init( &U1 ); mbedtls_mpi_init( &U2 );
diff --git a/library/rsa.c b/library/rsa.c
index 122bc13..bdd2538 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -1467,7 +1467,7 @@
 {
     int ret;
     size_t len, siglen, asn1_len;
-    unsigned char *p, *end;
+    unsigned char *p, *p0, *end;
     mbedtls_md_type_t msg_md_alg;
     const mbedtls_md_info_t *md_info;
     mbedtls_asn1_buf oid;
@@ -1499,7 +1499,11 @@
             return( MBEDTLS_ERR_RSA_INVALID_PADDING );
         p++;
     }
-    p++;
+    p++; /* skip 00 byte */
+
+    /* We've read: 00 01 PS 00 where PS must be at least 8 bytes */
+    if( p - buf < 11 )
+        return( MBEDTLS_ERR_RSA_INVALID_PADDING );
 
     len = siglen - ( p - buf );
 
@@ -1519,23 +1523,28 @@
     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,
             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
         return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
-
-    if( asn1_len + 2 != len )
+    if( p != p0 + 2 || asn1_len + 2 != len )
         return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
 
+    p0 = p;
     if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len,
             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
         return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
-
-    if( asn1_len + 6 + hashlen != len )
+    if( p != p0 + 2 || asn1_len + 6 + hashlen != len )
         return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
 
+    p0 = p;
     if( ( ret = mbedtls_asn1_get_tag( &p, end, &oid.len, MBEDTLS_ASN1_OID ) ) != 0 )
+        return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
+    if( p != p0 + 2 )
         return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
 
     oid.p = p;
@@ -1550,13 +1559,16 @@
     /*
      * assume the algorithm parameters must be NULL
      */
+    p0 = p;
     if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len, MBEDTLS_ASN1_NULL ) ) != 0 )
         return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
-
-    if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
+    if( p != p0 + 2 )
         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 );
 
     if( memcmp( p, hash, hashlen ) != 0 )
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index 688baa7..761655f 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -122,6 +122,13 @@
     fi
 }
 
+# skip next test if the flag is enabled in config.h
+requires_config_disabled() {
+    if grep "^#define $1" $CONFIG_H > /dev/null; then
+        SKIP_NEXT="YES"
+    fi
+}
+
 # skip next test if OpenSSL doesn't support FALLBACK_SCSV
 requires_openssl_with_fallback_scsv() {
     if [ -z "${OPENSSL_HAS_FBSCSV:-}" ]; then
@@ -714,11 +721,18 @@
 
 # Tests for SHA-1 support
 
+requires_config_disabled MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES
 run_test    "SHA-1 forbidden by default in server certificate" \
             "$P_SRV key_file=data_files/server2.key crt_file=data_files/server2.crt" \
             "$P_CLI debug_level=2 allow_sha1=0" \
             1 \
             -c "The certificate is signed with an unacceptable hash"
+
+requires_config_enabled MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES
+run_test    "SHA-1 forbidden by default in server certificate" \
+            "$P_SRV key_file=data_files/server2.key crt_file=data_files/server2.crt" \
+            "$P_CLI debug_level=2 allow_sha1=0" \
+            0
 
 run_test    "SHA-1 explicitly allowed in server certificate" \
             "$P_SRV key_file=data_files/server2.key crt_file=data_files/server2.crt" \
@@ -730,12 +744,19 @@
             "$P_CLI allow_sha1=0" \
             0
 
+requires_config_disabled MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES
 run_test    "SHA-1 forbidden by default in client certificate" \
             "$P_SRV auth_mode=required allow_sha1=0" \
             "$P_CLI key_file=data_files/cli-rsa.key crt_file=data_files/cli-rsa-sha1.crt" \
             1 \
             -s "The certificate is signed with an unacceptable hash"
 
+requires_config_enabled MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES
+run_test    "SHA-1 forbidden by default in client certificate" \
+            "$P_SRV auth_mode=required allow_sha1=0" \
+            "$P_CLI key_file=data_files/cli-rsa.key crt_file=data_files/cli-rsa-sha1.crt" \
+            0
+
 run_test    "SHA-1 explicitly allowed in client certificate" \
             "$P_SRV auth_mode=required allow_sha1=1" \
             "$P_CLI key_file=data_files/cli-rsa.key crt_file=data_files/cli-rsa-sha1.crt" \
diff --git a/tests/suites/test_suite_mpi.data b/tests/suites/test_suite_mpi.data
index da830fe..17cf350 100644
--- a/tests/suites/test_suite_mpi.data
+++ b/tests/suites/test_suite_mpi.data
@@ -521,7 +521,7 @@
 mbedtls_mpi_exp_mod:10:"433019240910377478217373572959560109819648647016096560523769010881172869083338285573756574557395862965095016483867813043663981946477698466501451832407592327356331263124555137732393938242285782144928753919588632679050799198937132922145084847":10:"5781538327977828897150909166778407659250458379645823062042492461576758526757490910073628008613977550546382774775570888130029763571528699574717583228939535960234464230882573615930384979100379102915657483866755371559811718767760594919456971354184113721":10:"583137007797276923956891216216022144052044091311388601652961409557516421612874571554415606746479105795833145583959622117418531166391184939066520869800857530421873250114773204354963864729386957427276448683092491947566992077136553066273207777134303397724679138833126700957":10:"":10:"114597449276684355144920670007147953232659436380163461553186940113929777196018164149703566472936578890991049344459204199888254907113495794730452699842273939581048142004834330369483813876618772578869083248061616444392091693787039636316845512292127097865026290173004860736":0
 
 Test mbedtls_mpi_exp_mod (Negative base)
-mbedtls_mpi_exp_mod:10:"-10000000000":10:"10000000000":10:"99999":10:"":10:"99998":0
+mbedtls_mpi_exp_mod:10:"-10000000000":10:"10000000000":10:"99999":10:"":10:"1":0
 
 Test mbedtls_mpi_exp_mod (Negative base)
 mbedtls_mpi_exp_mod:16:"-9f13012cd92aa72fb86ac8879d2fde4f7fd661aaae43a00971f081cc60ca277059d5c37e89652e2af2585d281d66ef6a9d38a117e9608e9e7574cd142dc55278838a2161dd56db9470d4c1da2d5df15a908ee2eb886aaa890f23be16de59386663a12f1afbb325431a3e835e3fd89b98b96a6f77382f458ef9a37e1f84a03045c8676ab55291a94c2228ea15448ee96b626b998":16:"40a54d1b9e86789f06d9607fb158672d64867665c73ee9abb545fc7a785634b354c7bae5b962ce8040cf45f2c1f3d3659b2ee5ede17534c8fc2ec85c815e8df1fe7048d12c90ee31b88a68a081f17f0d8ce5f4030521e9400083bcea73a429031d4ca7949c2000d597088e0c39a6014d8bf962b73bb2e8083bd0390a4e00b9b3":16:"eeaf0ab9adb38dd69c33f80afa8fc5e86072618775ff3c0b9ea2314c9c256576d674df7496ea81d3383b4813d692c6e0e0d5d8e250b98be48e495c1d6089dad15dc7d7b46154d6b6ce8ef4ad69b15d4982559b297bcf1885c529f566660e57ec68edbc3c05726cc02fd4cbf4976eaa9afd5138fe8376435b9fc61d2fc0eb06e3":16:"":16:"21acc7199e1b90f9b4844ffe12c19f00ec548c5d32b21c647d48b6015d8eb9ec9db05b4f3d44db4227a2b5659c1a7cceb9d5fa8fa60376047953ce7397d90aaeb7465e14e820734f84aa52ad0fc66701bcbb991d57715806a11531268e1e83dd48288c72b424a6287e9ce4e5cc4db0dd67614aecc23b0124a5776d36e5c89483":0
@@ -550,6 +550,9 @@
 Base test mbedtls_mpi_inv_mod #4
 mbedtls_mpi_inv_mod:10:"2":10:"4":10:"0":MBEDTLS_ERR_MPI_NOT_ACCEPTABLE
 
+Base test mbedtls_mpi_inv_mod #5
+mbedtls_mpi_inv_mod:10:"3":10:"1":10:"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
 Test mbedtls_mpi_inv_mod #1
 mbedtls_mpi_inv_mod:16:"aa4df5cb14b4c31237f98bd1faf527c283c2d0f3eec89718664ba33f9762907c":16:"fffbbd660b94412ae61ead9c2906a344116e316a256fd387874c6c675b1d587d":16:"8d6a5c1d7adeae3e94b9bcd2c47e0d46e778bc8804a2cc25c02d775dc3d05b0c":0
 
diff --git a/tests/suites/test_suite_rsa.data b/tests/suites/test_suite_rsa.data
index af16880..5013ac8 100644
--- a/tests/suites/test_suite_rsa.data
+++ b/tests/suites/test_suite_rsa.data
@@ -134,6 +134,10 @@
 depends_on:MBEDTLS_SHA512_C:MBEDTLS_PKCS1_V15
 mbedtls_rsa_pkcs1_verify:"59779fd2a39e56640c4fc1e67b60aeffcecd78aed7ad2bdfa464e93d04198d48466b8da7445f25bfa19db2844edd5c8f539cf772cc132b483169d390db28a43bc4ee0f038f6568ffc87447746cb72fefac2d6d90ee3143a915ac4688028805905a68eb8f8a96674b093c495eddd8704461eaa2b345efbb2ad6930acd8023f870":MBEDTLS_RSA_PKCS_V15:MBEDTLS_MD_SHA512:1536:16:"a59d9b7269b102b7be684ec5e28db79992e6d3231e77c90b78960c2638b35ef6dbdac1ac59e7249d96d426e7f99397eabc6b8903fe1942da580322b98bafacd81bb911c29666f83886a2a2864f3552044300e60cedd5a8c321c43e280413dc41673c39a11b98a885486f8187a70f270185c4c12bc48a1968305269776c070ef69d4913589a887c4d0f5e7dd58bd806d0d49a14a1762c38665cef4646ff13a0cd29c3a60460703c3d051d5b28c660bffb5f8bd43d495ffa64175f72b8abe5fddd":16:"11":"0b4d96f411c727a262d6d0ade34195b78603551061917d060f89add47b09dfe8715f4f9147d327dc25e91fe457e5d1a2f22cd8fe6fe8e29d2060658307c87a40640650fef3d4b289a6c3febc5a100b29a8b56623afb29fd3c13ea372bf3c638c1db25f8bd8c74c821beec7b5affcace1d05d056a6c2d3035926c7a268df4751a54bc20a6b8cfd729a7cba309ae817daccbef9950a482cf23950a8ca1d3a13ddb7d8d0f87ad5587d4d9ebe19fe93457597a7bdd056c2fd4cea7d31e4a0e595a7b":0
 
+RSA PKCS1 Verify v1.5 padding too short
+depends_on:MBEDTLS_SHA1_C:MBEDTLS_PKCS1_V15
+mbedtls_rsa_pkcs1_verify:"AABBCC03020100FFFFFFFFFF1122330A0B0CCCDDDDDDDDDD":MBEDTLS_RSA_PKCS_V15:MBEDTLS_MD_SHA1:1024:16:"9292758453063D803DD603D5E777D7888ED1D5BF35786190FA2F23EBC0848AEADDA92CA6C3D80B32C4D109BE0F36D6AE7130B9CED7ACDF54CFC7555AC14EEBAB93A89813FBF3C4F8066D2D800F7C38A81AE31942917403FF4946B0A83D3D3E05EE57C6F5F5606FB5D4BC6CD34EE0801A5E94BB77B07507233A0BC7BAC8F90F79":16:"10001":"6edd56f397d9bc6d176bbe3d80946fc352ad6127b85b1d67d849c0a38cbde7222c5fafbb18dcef791178a8e15f5c8cd91869f8ca4b758c46ce3e229bf666d2e3e296544351bcb5db7e0004f6c0800f76a432071297e405759d4324d1cf1c412758be93a39f834e03dee59e28ac571ce2b0b3c8fe639979f516223b54027340a5":MBEDTLS_ERR_RSA_INVALID_PADDING
+
 RSA PKCS1 Sign #1 (SHA512, 1536 bits RSA)
 depends_on:MBEDTLS_SHA512_C:MBEDTLS_PKCS1_V15
 mbedtls_rsa_pkcs1_sign:"59779fd2a39e56640c4fc1e67b60aeffcecd78aed7ad2bdfa464e93d04198d48466b8da7445f25bfa19db2844edd5c8f539cf772cc132b483169d390db28a43bc4ee0f038f6568ffc87447746cb72fefac2d6d90ee3143a915ac4688028805905a68eb8f8a96674b093c495eddd8704461eaa2b345efbb2ad6930acd8023f870":MBEDTLS_RSA_PKCS_V15:MBEDTLS_MD_SHA512:1536:16:"c8c67df894c882045ede26a9008ab09ea0672077d7bc71d412511cd93981ddde8f91b967da404056c39f105f7f239abdaff92923859920f6299e82b95bd5b8c959948f4a035cbd693ad83014294d349813d1ad57911a6355d0731fe3a034e9db":16:"f15147d0e7c04a1e3f37adde802cdc610999bf7ab0088434aaeda0c0ab3910b14d2ce56cb66bffd97552195fae8b061077e03920814d8b9cfb5a3958b3a82c2a7fc97e55db5978b47a922156eb8a3e55c06a54a45d1670abdfb995489c4d0051":16:"bd429bb7c3b00bbea19ba664c0f8172d1a73c3cfa05e2ed656d570c1590918bb7e372ed25e2cd71395ba0a9b1a30f3ee012ffb0546cab8e3581fe3e23f44ab57a8aee9717e71a936a580fa8572d450fb00339a6f6704b717df0c149a465bab768c61500cd93b61113ff3e4389167f7b2c8e3c0da2d4765286bee555b0bcb4998f59b14fad03180a17c8b4f69bcd1234f4ae85950137665ac2ba80b55cc9b1aafb454b83771aa755acd2a00e93ddb65e696dbed8bdca69fb5e0c5c2097b9cfe4b":16:"3":"93b6fa99485c116ca6efdd4202ea1cf49f4c6345fae692584413743ce5b65510e8e4690aee9a19ea1ff10d57f22aa3548d839f28a8525a34354e9e58e0f3947e056ce2554e21bf287e220b98db3b551258cd42b495e5d1a3bbc83c9d1a02f2a300ef6d866ea75108e44ebb3e16b47df2f6de28feb2be3874dbbf21599451082d86e9f2f462575a8185c69aa1f1fcb6a363c5d71aeba2103449eaf3845285291148d5f78d1646b8dc95cbcc4082f987d948b0e7d4e80b60595f8a7517584e1643":0