Merge remote-tracking branch 'restricted/pr/670' into mbedtls-2.16-restricted

* restricted/pr/670:
  Parse HelloVerifyRequest buffer overread: add changelog entry
  Parse HelloVerifyRequest: avoid buffer overread at the start
  Parse HelloVerifyRequest: avoid buffer overread on the cookie
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index 485b541..c580443 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -1,8 +1,5 @@
 Notes:
-* Pull requests cannot be accepted until:
--  The submitter has [accepted the online agreement here with a click through](https://developer.mbed.org/contributor_agreement/) 
-   or for companies or those that do not wish to create an mbed account, a slightly different agreement can be found [here](https://www.mbed.com/en/about-mbed/contributor-license-agreements/)
-- The PR follows the [mbed TLS coding standards](https://tls.mbed.org/kb/development/mbedtls-coding-standards)
+* Pull requests cannot be accepted until the PR follows the [contributing guidelines](../CONTRIBUTING.md). In particular, each commit must have at least one `Signed-off-by:` line from the committer to certify that the contribution is made under the terms of the [Developer Certificate of Origin](../dco.txt).
 * This is just a template, so feel free to use/remove the unnecessary things
 ## Description
 A few sentences describing the overall goals of the pull request's commits.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 18851db..c1ae452 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -5,11 +5,6 @@
  - As with any open source project, contributions will be reviewed by the project team and community and may need some modifications to be accepted.
  - The contribution should not break API or ABI, unless there is a real justification for that. If there is an API change, the contribution, if accepted, will be merged only when there will be a major release.
 
-Contributor License Agreement (CLA)
------------------------------------
-- All contributions, whether large or small, require a Contributor's License Agreement (CLA) to be accepted. This is because source code can possibly fall under copyright law and we need your consent to share in the ownership of the copyright.
-- To accept the Contributor’s License Agreement (CLA), individual contributors can do this by creating an Mbed account and [accepting the online agreement here with a click through](https://developer.mbed.org/contributor_agreement/). Alternatively, for contributions from corporations, or those that do not wish to create an Mbed account, a slightly different agreement can be found [here](https://www.mbed.com/en/about-mbed/contributor-license-agreements/). This agreement should be signed and returned to Arm as described in the instructions given.
-
 Coding Standards
 ----------------
 - We would ask that contributions conform to [our coding standards](https://tls.mbed.org/kb/development/mbedtls-coding-standards), and that contributions are fully tested before submission, as mentioned in the [Tests](#tests) and [Continuous Integration](#continuous-integration-tests) sections.
@@ -24,7 +19,8 @@
 1. Write a test which shows that the bug was fixed or that the feature works as expected.
 1. Send a pull request (PR) and work with us until it gets merged and published. Contributions may need some modifications, so a few rounds of review and fixing may be necessary. We will include your name in the ChangeLog :)
 1. For quick merging, the contribution should be short, and concentrated on a single feature or topic. The larger the contribution is, the longer it would take to review it and merge it.
-1. Mbed TLS is released under the Apache license, and as such, all the added files should include the Apache license header.
+1. All new files should include the [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html) standard license header where possible.
+1. Ensure that each commit has at least one `Signed-off-by:` line from the committer. If anyone else contributes to the commit, they should also add their own `Signed-off-by:` line. By adding this line, contributor(s) certify that the contribution is made under the terms of the [Developer Certificate of Origin](dco.txt). The contribution licensing is described in the [License section of the README](README.md#License).
 
 API/ABI Compatibility
 ---------------------
@@ -46,18 +42,14 @@
 
 When backporting to these branches please observe the following rules:
 
- 1. Any change to the library which changes the API or ABI cannot be backported.
-
- 2. All bug fixes that correct a defect that is also present in an LTS branch must be backported to that LTS branch. If a bug fix introduces a change to the API such as a new function, the fix should be reworked to avoid the API change. API changes without very strong justification are unlikely to be accepted.
-
- 3. If a contribution is a new feature or enhancement, no backporting is required. Exceptions to this may be additional test cases or quality improvements such as changes to build or test scripts.
+1. Any change to the library which changes the API or ABI cannot be backported.
+1. All bug fixes that correct a defect that is also present in an LTS branch must be backported to that LTS branch. If a bug fix introduces a change to the API such as a new function, the fix should be reworked to avoid the API change. API changes without very strong justification are unlikely to be accepted.
+1. If a contribution is a new feature or enhancement, no backporting is required. Exceptions to this may be additional test cases or quality improvements such as changes to build or test scripts.
 
 It would be highly appreciated if contributions are backported to LTS branches in addition to the [development branch](https://github.com/ARMmbed/mbedtls/tree/development) by contributors.
 
 Currently maintained LTS branches are:
-
 1. [mbedtls-2.7](https://github.com/ARMmbed/mbedtls/tree/mbedtls-2.7)
-
 1. [mbedtls-2.16](https://github.com/ARMmbed/mbedtls/tree/mbedtls-2.16)
 
 
@@ -84,12 +76,7 @@
 Mbed TLS is well documented, but if you think documentation is needed, speak out!
 
 1. All interfaces should be documented through Doxygen. New APIs should introduce Doxygen documentation.
-
-2. Complex parts in the code should include comments.
-
-3. If needed, a Readme file is advised.
-
-4. If a [Knowledge Base (KB)](https://tls.mbed.org/kb) article should be added, write this as a comment in the PR description.
-
-5. A [ChangeLog](https://github.com/ARMmbed/mbedtls/blob/development/ChangeLog) entry should be added for this contribution.
-
+1. Complex parts in the code should include comments.
+1. If needed, a Readme file is advised.
+1. If a [Knowledge Base (KB)](https://tls.mbed.org/kb) article should be added, write this as a comment in the PR description.
+1. A [ChangeLog](https://github.com/ARMmbed/mbedtls/blob/development/ChangeLog) entry should be added for this contribution.
diff --git a/ChangeLog b/ChangeLog
index 762f761..dc2acf7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,44 @@
 mbed TLS ChangeLog (Sorted per branch, date)
 
-= mbed TLS 2.16.x branch released xxxx-xx-xx
+= mbed TLS x.x.x branch released xxxx-xx-xx
+
+Security
+   * Fix side channel in ECC code that allowed an adversary with access to
+     precise enough timing and memory access information (typically an
+     untrusted operating system attacking a secure enclave) to fully recover
+     an ECDSA private key. Found and reported by Alejandro Cabrera Aldaya,
+     Billy Brumley and Cesar Pereida Garcia. CVE-2020-10932
+   * Fix a potentially remotely exploitable buffer overread in a
+     DTLS client when parsing the Hello Verify Request message.
+
+Bugfix
+   * Fix compilation failure when both MBEDTLS_SSL_PROTO_DTLS and
+     MBEDTLS_SSL_HW_RECORD_ACCEL are enabled.
+
+= mbed TLS 2.16.5 branch released 2020-02-20
+
+Security
+   * Fix potential memory overread when performing an ECDSA signature
+     operation. The overread only happens with cryptographically low
+     probability (of the order of 2^-n where n is the bitsize of the curve)
+     unless the RNG is broken, and could result in information disclosure or
+     denial of service (application crash or extra resource consumption).
+     Found by Auke Zeilstra and Peter Schwabe, using static analysis.
+   * To avoid a side channel vulnerability when parsing an RSA private key,
+     read all the CRT parameters from the DER structure rather than
+     reconstructing them. Found by Alejandro Cabrera Aldaya and Billy Bob
+     Brumley. Reported and fix contributed by Jack Lloyd.
+     ARMmbed/mbed-crypto#352
+
+Bugfix
+   * Fix an unchecked call to mbedtls_md() in the x509write module.
+   * Fix a bug in mbedtls_pk_parse_key() that would cause it to accept some
+     RSA keys that would later be rejected by functions expecting private
+     keys. Found by Catena cyber using oss-fuzz (issue 20467).
+   * Fix a bug in mbedtls_pk_parse_key() that would cause it to accept some
+     RSA keys with invalid values by silently fixing those values.
+
+= mbed TLS 2.16.4 branch released 2020-01-15
 
 Security
    * Fix side channel vulnerability in ECDSA. Our bignum implementation is not
@@ -20,13 +58,19 @@
      timings on the comparison in the key generation enabled the attacker to
      learn leading bits of the ephemeral key used during ECDSA signatures and to
      recover the private key. Reported by Jeremy Dubeuf.
-   * Fix a potentially remotely exploitable buffer overread in a
-     DTLS client when parsing the Hello Verify Request message.
+   * Catch failure of AES functions in mbedtls_ctr_drbg_random(). Uncaught
+     failures could happen with alternative implementations of AES. Bug
+     reported and fix proposed by Johan Uppman Bruce and Christoffer Lauri,
+     Sectra.
 
 Bugfix
    * Remove redundant line for getting the bitlen of a bignum, since the variable
      holding the returned value is overwritten a line after.
      Found by irwir in #2377.
+   * Support mbedtls_hmac_drbg_set_entropy_len() and
+     mbedtls_ctr_drbg_set_entropy_len() before the DRBG is seeded. Before,
+     the initial seeding always reset the entropy length to the compile-time
+     default.
 
 Changes
    * Add unit tests for AES-GCM when called through mbedtls_cipher_auth_xxx()
diff --git a/README.md b/README.md
index 62dd4e2..a44b635 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,8 @@
 README for Mbed TLS
 ===================
 
+Mbed TLS is a C library that implements cryptographic primitives, X.509 certificate manipulation and the SSL/TLS and DTLS protocols. Its small code footprint makes it suitable for embedded systems.
+
 Configuration
 -------------
 
@@ -167,21 +169,12 @@
 -   [What external dependencies does Mbed TLS rely on?](https://tls.mbed.org/kb/development/what-external-dependencies-does-mbedtls-rely-on)
 -   [How do I configure Mbed TLS](https://tls.mbed.org/kb/compiling-and-building/how-do-i-configure-mbedtls)
 
+License
+-------
+
+Unless specifically indicated otherwise in a file, Mbed TLS files are provided under the [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html) license. See [here](./apache-2.0.txt) for the full text of this license. Contributors must accept that their contributions are made under both the Apache-2.0 AND [GPL-2.0-or-later](https://spdx.org/licenses/GPL-2.0-or-later.html) licenses. This enables LTS (Long Term Support) branches of the software to be provided under either the Apache-2.0 OR GPL-2.0-or-later licenses.
+
 Contributing
 ------------
 
-We gratefully accept bug reports and contributions from the community. There are some requirements we need to fulfill in order to be able to integrate contributions:
-
--   All contributions, whether large or small require a Contributor's License Agreement (CLA) to be accepted. This is because source code can possibly fall under copyright law and we need your consent to share in the ownership of the copyright.
--   We would ask that contributions conform to [our coding standards](https://tls.mbed.org/kb/development/mbedtls-coding-standards), and that contributions should be fully tested before submission.
--   As with any open source project, contributions will be reviewed by the project team and community and may need some modifications to be accepted.
-
-To accept the Contributor’s Licence Agreement (CLA), individual contributors can do this by creating an Mbed account and [accepting the online agreement here with a click through](https://os.mbed.com/contributor_agreement/). Alternatively, for contributions from corporations, or those that do not wish to create an Mbed account, a slightly different agreement can be found [here](https://www.mbed.com/en/about-mbed/contributor-license-agreements/). This agreement should be signed and returned to Arm as described in the instructions given.
-
-### Making a Contribution
-
-1.  [Check for open issues](https://github.com/ARMmbed/mbedtls/issues) or [start a discussion](https://forums.mbed.com/c/mbed-tls) around a feature idea or a bug.
-2.  Fork the [Mbed TLS repository on GitHub](https://github.com/ARMmbed/mbedtls) to start making your changes. As a general rule, you should use the "development" branch as a basis.
-3.  Write a test which shows that the bug was fixed or that the feature works as expected.
-4.  Send a pull request and bug us until it gets merged and published. Contributions may need some modifications, so work with us to get your change accepted. We will include your name in the ChangeLog :)
-
+We gratefully accept bug reports and contributions from the community. Please see the [contributing guidelines](CONTRIBUTING.md) for details on how to do this.
diff --git a/dco.txt b/dco.txt
new file mode 100644
index 0000000..8201f99
--- /dev/null
+++ b/dco.txt
@@ -0,0 +1,37 @@
+Developer Certificate of Origin
+Version 1.1
+
+Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
+1 Letterman Drive
+Suite D4700
+San Francisco, CA, 94129
+
+Everyone is permitted to copy and distribute verbatim copies of this
+license document, but changing it is not allowed.
+
+
+Developer's Certificate of Origin 1.1
+
+By making a contribution to this project, I certify that:
+
+(a) The contribution was created in whole or in part by me and I
+    have the right to submit it under the open source license
+    indicated in the file; or
+
+(b) The contribution is based upon previous work that, to the best
+    of my knowledge, is covered under an appropriate open source
+    license and I have the right under that license to submit that
+    work with modifications, whether created in whole or in part
+    by me, under the same open source license (unless I am
+    permitted to submit under a different license), as indicated
+    in the file; or
+
+(c) The contribution was provided directly to me by some other
+    person who certified (a), (b) or (c) and I have not modified
+    it.
+
+(d) I understand and agree that this project and the contribution
+    are public and that a record of the contribution (including all
+    personal information I submit with it, including my sign-off) is
+    maintained indefinitely and may be redistributed consistent with
+    this project or the open source license(s) involved.
diff --git a/doxygen/input/doc_mainpage.h b/doxygen/input/doc_mainpage.h
index a6126f3..bc55d13 100644
--- a/doxygen/input/doc_mainpage.h
+++ b/doxygen/input/doc_mainpage.h
@@ -24,7 +24,7 @@
  */
 
 /**
- * @mainpage mbed TLS v2.16.3 source code documentation
+ * @mainpage mbed TLS v2.16.5 source code documentation
  *
  * This documentation describes the internal structure of mbed TLS.  It was
  * automatically generated from specially formatted comment blocks in
diff --git a/doxygen/mbedtls.doxyfile b/doxygen/mbedtls.doxyfile
index 904c1e7..d0b1744 100644
--- a/doxygen/mbedtls.doxyfile
+++ b/doxygen/mbedtls.doxyfile
@@ -28,7 +28,7 @@
 # identify the project. Note that if you do not use Doxywizard you need
 # to put quotes around the project name if it contains spaces.
 
-PROJECT_NAME           = "mbed TLS v2.16.3"
+PROJECT_NAME           = "mbed TLS v2.16.5"
 
 # The PROJECT_NUMBER tag can be used to enter a project or revision number.
 # This could be handy for archiving the generated documentation or
diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h
index 766e647..e0b5ed9 100644
--- a/include/mbedtls/ctr_drbg.h
+++ b/include/mbedtls/ctr_drbg.h
@@ -214,11 +214,8 @@
  *   with mbedtls_entropy_init() (which registers the platform's default
  *   entropy sources).
  *
- * \p f_entropy is always called with a buffer size equal to the entropy
- * length. The entropy length is initially #MBEDTLS_CTR_DRBG_ENTROPY_LEN
- * and this value is always used for the initial seeding. You can change
- * the entropy length for subsequent seeding by calling
- * mbedtls_ctr_drbg_set_entropy_len() after this function.
+ * The entropy length is #MBEDTLS_CTR_DRBG_ENTROPY_LEN by default.
+ * You can override it by calling mbedtls_ctr_drbg_set_entropy_len().
  *
  * You can provide a personalization string in addition to the
  * entropy source, to make this instantiation as unique as possible.
@@ -252,9 +249,18 @@
 #endif
 /**
  * \param ctx           The CTR_DRBG context to seed.
+ *                      It must have been initialized with
+ *                      mbedtls_ctr_drbg_init().
+ *                      After a successful call to mbedtls_ctr_drbg_seed(),
+ *                      you may not call mbedtls_ctr_drbg_seed() again on
+ *                      the same context unless you call
+ *                      mbedtls_ctr_drbg_free() and mbedtls_ctr_drbg_init()
+ *                      again first.
  * \param f_entropy     The entropy callback, taking as arguments the
  *                      \p p_entropy context, the buffer to fill, and the
  *                      length of the buffer.
+ *                      \p f_entropy is always called with a buffer size
+ *                      equal to the entropy length.
  * \param p_entropy     The entropy context to pass to \p f_entropy.
  * \param custom        The personalization string.
  *                      This can be \c NULL, in which case the personalization
@@ -298,15 +304,10 @@
 
 /**
  * \brief               This function sets the amount of entropy grabbed on each
- *                      subsequent reseed.
+ *                      seed or reseed.
  *
  * The default value is #MBEDTLS_CTR_DRBG_ENTROPY_LEN.
  *
- * \note                mbedtls_ctr_drbg_seed() always sets the entropy length
- *                      to #MBEDTLS_CTR_DRBG_ENTROPY_LEN, so this function
- *                      only has an effect when it is called after
- *                      mbedtls_ctr_drbg_seed().
- *
  * \note                The security strength of CTR_DRBG is bounded by the
  *                      entropy length. Thus:
  *                      - When using AES-256
diff --git a/include/mbedtls/hmac_drbg.h b/include/mbedtls/hmac_drbg.h
index 20b29d9..7931c22 100644
--- a/include/mbedtls/hmac_drbg.h
+++ b/include/mbedtls/hmac_drbg.h
@@ -139,13 +139,11 @@
  *                      Note that SHA-256 is just as efficient as SHA-224.
  *                      The security strength can be reduced if a smaller
  *                      entropy length is set with
- *                      mbedtls_hmac_drbg_set_entropy_len() afterwards.
+ *                      mbedtls_hmac_drbg_set_entropy_len().
  *
- * \note                The entropy length for the initial seeding is
- *                      the security strength (converted from bits to bytes).
- *                      You can set a different entropy length for subsequent
- *                      seeding by calling mbedtls_hmac_drbg_set_entropy_len()
- *                      after this function.
+ * \note                The default entropy length is the security strength
+ *                      (converted from bits to bytes). You can override
+ *                      it by calling mbedtls_hmac_drbg_set_entropy_len().
  *
  * \note                During the initial seeding, this function calls
  *                      the entropy source to obtain a nonce
@@ -224,14 +222,9 @@
 
 /**
  * \brief               This function sets the amount of entropy grabbed on each
- *                      reseed.
+ *                      seed or reseed.
  *
- * The default value is set by mbedtls_hmac_drbg_seed().
- *
- * \note                mbedtls_hmac_drbg_seed() always sets the entropy length
- *                      to the default value based on the chosen MD algorithm,
- *                      so this function only has an effect if it is called
- *                      after mbedtls_hmac_drbg_seed().
+ * See the documentation of mbedtls_hmac_drbg_seed() for the default value.
  *
  * \param ctx           The HMAC_DRBG context.
  * \param len           The amount of entropy to grab, in bytes.
diff --git a/include/mbedtls/version.h b/include/mbedtls/version.h
index b4eef71..8e2ce03 100644
--- a/include/mbedtls/version.h
+++ b/include/mbedtls/version.h
@@ -40,16 +40,16 @@
  */
 #define MBEDTLS_VERSION_MAJOR  2
 #define MBEDTLS_VERSION_MINOR  16
-#define MBEDTLS_VERSION_PATCH  3
+#define MBEDTLS_VERSION_PATCH  5
 
 /**
  * The single version number has the following structure:
  *    MMNNPP00
  *    Major version | Minor version | Patch version
  */
-#define MBEDTLS_VERSION_NUMBER         0x02100300
-#define MBEDTLS_VERSION_STRING         "2.16.3"
-#define MBEDTLS_VERSION_STRING_FULL    "mbed TLS 2.16.3"
+#define MBEDTLS_VERSION_NUMBER         0x02100500
+#define MBEDTLS_VERSION_STRING         "2.16.5"
+#define MBEDTLS_VERSION_STRING_FULL    "mbed TLS 2.16.5"
 
 #if defined(MBEDTLS_VERSION_C)
 
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index 9330cff..5c67d5b 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -165,15 +165,15 @@
 
 if(USE_SHARED_MBEDTLS_LIBRARY)
     add_library(mbedcrypto SHARED ${src_crypto})
-    set_target_properties(mbedcrypto PROPERTIES VERSION 2.16.3 SOVERSION 3)
+    set_target_properties(mbedcrypto PROPERTIES VERSION 2.16.5 SOVERSION 3)
     target_link_libraries(mbedcrypto ${libs})
 
     add_library(mbedx509 SHARED ${src_x509})
-    set_target_properties(mbedx509 PROPERTIES VERSION 2.16.3 SOVERSION 0)
+    set_target_properties(mbedx509 PROPERTIES VERSION 2.16.5 SOVERSION 0)
     target_link_libraries(mbedx509 ${libs} mbedcrypto)
 
     add_library(mbedtls SHARED ${src_tls})
-    set_target_properties(mbedtls PROPERTIES VERSION 2.16.3 SOVERSION 12)
+    set_target_properties(mbedtls PROPERTIES VERSION 2.16.5 SOVERSION 12)
     target_link_libraries(mbedtls ${libs} mbedx509)
 
     install(TARGETS mbedtls mbedx509 mbedcrypto
diff --git a/library/bignum.c b/library/bignum.c
index 6713bcb..87ccf42 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -157,9 +157,10 @@
     if( nblimbs > MBEDTLS_MPI_MAX_LIMBS )
         return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
 
-    /* Actually resize up in this case */
+    /* Actually resize up if there are currently fewer than nblimbs limbs. */
     if( X->n <= nblimbs )
         return( mbedtls_mpi_grow( X, nblimbs ) );
+    /* After this point, then X->n > nblimbs and in particular X->n > 0. */
 
     for( i = X->n - 1; i > 0; i-- )
         if( X->p[i] != 0 )
@@ -198,7 +199,7 @@
     if( X == Y )
         return( 0 );
 
-    if( Y->p == NULL )
+    if( Y->n == 0 )
     {
         mbedtls_mpi_free( X );
         return( 0 );
diff --git a/library/cipher.c b/library/cipher.c
index 2739975..8d010b5 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -361,6 +361,10 @@
 
     *olen = 0;
     block_size = mbedtls_cipher_get_block_size( ctx );
+    if ( 0 == block_size )
+    {
+        return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT );
+    }
 
     if( ctx->cipher_info->mode == MBEDTLS_MODE_ECB )
     {
@@ -396,11 +400,6 @@
     }
 #endif
 
-    if ( 0 == block_size )
-    {
-        return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT );
-    }
-
     if( input == output &&
        ( ctx->unprocessed_len != 0 || ilen % block_size ) )
     {
@@ -459,11 +458,6 @@
          */
         if( 0 != ilen )
         {
-            if( 0 == block_size )
-            {
-                return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT );
-            }
-
             /* Encryption: only cache partial blocks
              * Decryption w/ padding: always keep at least one whole block
              * Decryption w/o padding: only cache partial blocks
diff --git a/library/ctr_drbg.c b/library/ctr_drbg.c
index fb12157..ad0a193 100644
--- a/library/ctr_drbg.c
+++ b/library/ctr_drbg.c
@@ -62,68 +62,6 @@
 #endif
 }
 
-/*
- * Non-public function wrapped by mbedtls_ctr_drbg_seed(). Necessary to allow
- * NIST tests to succeed (which require known length fixed entropy)
- */
-/* CTR_DRBG_Instantiate with derivation function (SP 800-90A &sect;10.2.1.3.2)
- * mbedtls_ctr_drbg_seed_entropy_len(ctx, f_entropy, p_entropy,
- *                                   custom, len, entropy_len)
- * implements
- * CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string,
- *                      security_strength) -> initial_working_state
- * with inputs
- *   custom[:len] = nonce || personalization_string
- * where entropy_input comes from f_entropy for entropy_len bytes
- * and with outputs
- *   ctx = initial_working_state
- */
-int mbedtls_ctr_drbg_seed_entropy_len(
-                   mbedtls_ctr_drbg_context *ctx,
-                   int (*f_entropy)(void *, unsigned char *, size_t),
-                   void *p_entropy,
-                   const unsigned char *custom,
-                   size_t len,
-                   size_t entropy_len )
-{
-    int ret;
-    unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
-
-    memset( key, 0, MBEDTLS_CTR_DRBG_KEYSIZE );
-
-    mbedtls_aes_init( &ctx->aes_ctx );
-
-    ctx->f_entropy = f_entropy;
-    ctx->p_entropy = p_entropy;
-
-    ctx->entropy_len = entropy_len;
-    ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
-
-    /*
-     * Initialize with an empty key
-     */
-    if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
-    {
-        return( ret );
-    }
-
-    if( ( ret = mbedtls_ctr_drbg_reseed( ctx, custom, len ) ) != 0 )
-    {
-        return( ret );
-    }
-    return( 0 );
-}
-
-int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
-                   int (*f_entropy)(void *, unsigned char *, size_t),
-                   void *p_entropy,
-                   const unsigned char *custom,
-                   size_t len )
-{
-    return( mbedtls_ctr_drbg_seed_entropy_len( ctx, f_entropy, p_entropy, custom, len,
-                                       MBEDTLS_CTR_DRBG_ENTROPY_LEN ) );
-}
-
 void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx )
 {
     if( ctx == NULL )
@@ -427,6 +365,63 @@
     return( ret );
 }
 
+/* CTR_DRBG_Instantiate with derivation function (SP 800-90A &sect;10.2.1.3.2)
+ * mbedtls_ctr_drbg_seed(ctx, f_entropy, p_entropy, custom, len)
+ * implements
+ * CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string,
+ *                      security_strength) -> initial_working_state
+ * with inputs
+ *   custom[:len] = nonce || personalization_string
+ * where entropy_input comes from f_entropy for ctx->entropy_len bytes
+ * and with outputs
+ *   ctx = initial_working_state
+ */
+int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
+                           int (*f_entropy)(void *, unsigned char *, size_t),
+                           void *p_entropy,
+                           const unsigned char *custom,
+                           size_t len )
+{
+    int ret;
+    unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
+
+    memset( key, 0, MBEDTLS_CTR_DRBG_KEYSIZE );
+
+    mbedtls_aes_init( &ctx->aes_ctx );
+
+    ctx->f_entropy = f_entropy;
+    ctx->p_entropy = p_entropy;
+
+    if( ctx->entropy_len == 0 )
+        ctx->entropy_len = MBEDTLS_CTR_DRBG_ENTROPY_LEN;
+    ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
+
+    /*
+     * Initialize with an empty key
+     */
+    if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    if( ( ret = mbedtls_ctr_drbg_reseed( ctx, custom, len ) ) != 0 )
+    {
+        return( ret );
+    }
+    return( 0 );
+}
+
+/* Backward compatibility wrapper */
+int mbedtls_ctr_drbg_seed_entropy_len(
+    mbedtls_ctr_drbg_context *ctx,
+    int (*f_entropy)(void *, unsigned char *, size_t), void *p_entropy,
+    const unsigned char *custom, size_t len,
+    size_t entropy_len )
+{
+    mbedtls_ctr_drbg_set_entropy_len( ctx, entropy_len );
+    return( mbedtls_ctr_drbg_seed( ctx, f_entropy, p_entropy, custom, len ) );
+}
+
 /* CTR_DRBG_Generate with derivation function (SP 800-90A &sect;10.2.1.5.2)
  * mbedtls_ctr_drbg_random_with_add(ctx, output, output_len, additional, add_len)
  * implements
@@ -517,7 +512,7 @@
 exit:
     mbedtls_platform_zeroize( add_input, sizeof( add_input ) );
     mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
-    return( 0 );
+    return( ret );
 }
 
 int mbedtls_ctr_drbg_random( void *p_rng, unsigned char *output, size_t output_len )
@@ -678,8 +673,11 @@
         mbedtls_printf( "  CTR_DRBG (PR = TRUE) : " );
 
     test_offset = 0;
-    CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy,
-                                (void *) entropy_source_pr, nonce_pers_pr, 16, 32 ) );
+    mbedtls_ctr_drbg_set_entropy_len( &ctx, 32 );
+    CHK( mbedtls_ctr_drbg_seed( &ctx,
+                                ctr_drbg_self_test_entropy,
+                                (void *) entropy_source_pr,
+                                nonce_pers_pr, 16 ) );
     mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );
     CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
     CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
@@ -699,8 +697,11 @@
     mbedtls_ctr_drbg_init( &ctx );
 
     test_offset = 0;
-    CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy,
-                            (void *) entropy_source_nopr, nonce_pers_nopr, 16, 32 ) );
+    mbedtls_ctr_drbg_set_entropy_len( &ctx, 32 );
+    CHK( mbedtls_ctr_drbg_seed( &ctx,
+                                ctr_drbg_self_test_entropy,
+                                (void *) entropy_source_nopr,
+                                nonce_pers_nopr, 16 ) );
     CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );
     CHK( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) );
     CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );
diff --git a/library/ecdsa.c b/library/ecdsa.c
index 3cf3d7c..6b72e0d 100644
--- a/library/ecdsa.c
+++ b/library/ecdsa.c
@@ -297,7 +297,7 @@
     *p_sign_tries = 0;
     do
     {
-        if( *p_sign_tries++ > 10 )
+        if( (*p_sign_tries)++ > 10 )
         {
             ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
             goto cleanup;
@@ -310,7 +310,7 @@
         *p_key_tries = 0;
         do
         {
-            if( *p_key_tries++ > 10 )
+            if( (*p_key_tries)++ > 10 )
             {
                 ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
                 goto cleanup;
diff --git a/library/ecp.c b/library/ecp.c
index 040c20b..725e176 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -1938,6 +1938,20 @@
 
 final_norm:
 #endif
+    /*
+     * Knowledge of the jacobian coordinates may leak the last few bits of the
+     * scalar [1], and since our MPI implementation isn't constant-flow,
+     * inversion (used for coordinate normalization) may leak the full value
+     * of its input via side-channels [2].
+     *
+     * [1] https://eprint.iacr.org/2003/191
+     * [2] https://eprint.iacr.org/2020/055
+     *
+     * Avoid the leak by randomizing coordinates before we normalize them.
+     */
+    if( f_rng != 0 )
+        MBEDTLS_MPI_CHK( ecp_randomize_jac( grp, RR, f_rng, p_rng ) );
+
     MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_INV );
     MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, RR ) );
 
@@ -2308,6 +2322,20 @@
         MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->Z, &RP.Z, b ) );
     }
 
+    /*
+     * Knowledge of the projective coordinates may leak the last few bits of the
+     * scalar [1], and since our MPI implementation isn't constant-flow,
+     * inversion (used for coordinate normalization) may leak the full value
+     * of its input via side-channels [2].
+     *
+     * [1] https://eprint.iacr.org/2003/191
+     * [2] https://eprint.iacr.org/2020/055
+     *
+     * Avoid the leak by randomizing coordinates before we normalize them.
+     */
+    if( f_rng != NULL )
+        MBEDTLS_MPI_CHK( ecp_randomize_mxz( grp, R, f_rng, p_rng ) );
+
     MBEDTLS_MPI_CHK( ecp_normalize_mxz( grp, R ) );
 
 cleanup:
diff --git a/library/hmac_drbg.c b/library/hmac_drbg.c
index 50d88bd..284c9b4 100644
--- a/library/hmac_drbg.c
+++ b/library/hmac_drbg.c
@@ -273,16 +273,19 @@
 
     ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
 
-    /*
-     * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
-     * each hash function, then according to SP800-90A rev1 10.1 table 2,
-     * min_entropy_len (in bits) is security_strength.
-     *
-     * (This also matches the sizes used in the NIST test vectors.)
-     */
-    ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
-                       md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
-                       32;  /* better (256+) -> 256 bits */
+    if( ctx->entropy_len == 0 )
+    {
+        /*
+         * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
+         * each hash function, then according to SP800-90A rev1 10.1 table 2,
+         * min_entropy_len (in bits) is security_strength.
+         *
+         * (This also matches the sizes used in the NIST test vectors.)
+         */
+        ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
+                           md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
+                           32;  /* better (256+) -> 256 bits */
+    }
 
     if( ( ret = hmac_drbg_reseed_core( ctx, custom, len,
                                        1 /* add nonce */ ) ) != 0 )
@@ -303,7 +306,7 @@
 }
 
 /*
- * Set entropy length grabbed for reseeds
+ * Set entropy length grabbed for seeding
  */
 void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len )
 {
diff --git a/library/pkparse.c b/library/pkparse.c
index ae210bc..d500457 100644
--- a/library/pkparse.c
+++ b/library/pkparse.c
@@ -678,6 +678,32 @@
 
 #if defined(MBEDTLS_RSA_C)
 /*
+ * Wrapper around mbedtls_asn1_get_mpi() that rejects zero.
+ *
+ * The value zero is:
+ * - never a valid value for an RSA parameter
+ * - interpreted as "omitted, please reconstruct" by mbedtls_rsa_complete().
+ *
+ * Since values can't be omitted in PKCS#1, passing a zero value to
+ * rsa_complete() would be incorrect, so reject zero values early.
+ */
+static int asn1_get_nonzero_mpi( unsigned char **p,
+                                 const unsigned char *end,
+                                 mbedtls_mpi *X )
+{
+    int ret;
+
+    ret = mbedtls_asn1_get_mpi( p, end, X );
+    if( ret != 0 )
+        return( ret );
+
+    if( mbedtls_mpi_cmp_int( X, 0 ) == 0 )
+        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
+
+    return( 0 );
+}
+
+/*
  * Parse a PKCS#1 encoded private RSA key
  */
 static int pk_parse_key_pkcs1_der( mbedtls_rsa_context *rsa,
@@ -729,54 +755,84 @@
     }
 
     /* Import N */
-    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
-                                      MBEDTLS_ASN1_INTEGER ) ) != 0 ||
-        ( ret = mbedtls_rsa_import_raw( rsa, p, len, NULL, 0, NULL, 0,
-                                        NULL, 0, NULL, 0 ) ) != 0 )
+    if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 ||
+        ( ret = mbedtls_rsa_import( rsa, &T, NULL, NULL,
+                                        NULL, NULL ) ) != 0 )
         goto cleanup;
-    p += len;
 
     /* Import E */
-    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
-                                      MBEDTLS_ASN1_INTEGER ) ) != 0 ||
-        ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, NULL, 0,
-                                        NULL, 0, p, len ) ) != 0 )
+    if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 ||
+        ( ret = mbedtls_rsa_import( rsa, NULL, NULL, NULL,
+                                        NULL, &T ) ) != 0 )
         goto cleanup;
-    p += len;
 
     /* Import D */
-    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
-                                      MBEDTLS_ASN1_INTEGER ) ) != 0 ||
-        ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, NULL, 0,
-                                        p, len, NULL, 0 ) ) != 0 )
+    if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 ||
+        ( ret = mbedtls_rsa_import( rsa, NULL, NULL, NULL,
+                                        &T, NULL ) ) != 0 )
         goto cleanup;
-    p += len;
 
     /* Import P */
-    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
-                                      MBEDTLS_ASN1_INTEGER ) ) != 0 ||
-        ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, p, len, NULL, 0,
-                                        NULL, 0, NULL, 0 ) ) != 0 )
+    if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 ||
+        ( ret = mbedtls_rsa_import( rsa, NULL, &T, NULL,
+                                        NULL, NULL ) ) != 0 )
         goto cleanup;
-    p += len;
 
     /* Import Q */
-    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
-                                      MBEDTLS_ASN1_INTEGER ) ) != 0 ||
-        ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, p, len,
-                                        NULL, 0, NULL, 0 ) ) != 0 )
-        goto cleanup;
-    p += len;
-
-    /* Complete the RSA private key */
-    if( ( ret = mbedtls_rsa_complete( rsa ) ) != 0 )
+    if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 ||
+        ( ret = mbedtls_rsa_import( rsa, NULL, NULL, &T,
+                                        NULL, NULL ) ) != 0 )
         goto cleanup;
 
-    /* Check optional parameters */
-    if( ( ret = mbedtls_asn1_get_mpi( &p, end, &T ) ) != 0 ||
-        ( ret = mbedtls_asn1_get_mpi( &p, end, &T ) ) != 0 ||
-        ( ret = mbedtls_asn1_get_mpi( &p, end, &T ) ) != 0 )
+#if !defined(MBEDTLS_RSA_NO_CRT) && !defined(MBEDTLS_RSA_ALT)
+    /*
+    * The RSA CRT parameters DP, DQ and QP are nominally redundant, in
+    * that they can be easily recomputed from D, P and Q. However by
+    * parsing them from the PKCS1 structure it is possible to avoid
+    * recalculating them which both reduces the overhead of loading
+    * RSA private keys into memory and also avoids side channels which
+    * can arise when computing those values, since all of D, P, and Q
+    * are secret. See https://eprint.iacr.org/2020/055 for a
+    * description of one such attack.
+    */
+
+    /* Import DP */
+    if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 ||
+        ( ret = mbedtls_mpi_copy( &rsa->DP, &T ) ) != 0 )
+       goto cleanup;
+
+    /* Import DQ */
+    if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 ||
+        ( ret = mbedtls_mpi_copy( &rsa->DQ, &T ) ) != 0 )
+       goto cleanup;
+
+    /* Import QP */
+    if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 ||
+        ( ret = mbedtls_mpi_copy( &rsa->QP, &T ) ) != 0 )
+       goto cleanup;
+
+#else
+    /* Verify existance of the CRT params */
+    if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 ||
+        ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 ||
+        ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 )
+       goto cleanup;
+#endif
+
+    /* rsa_complete() doesn't complete anything with the default
+     * implementation but is still called:
+     * - for the benefit of alternative implementation that may want to
+     *   pre-compute stuff beyond what's provided (eg Montgomery factors)
+     * - as is also sanity-checks the key
+     *
+     * Furthermore, we also check the public part for consistency with
+     * mbedtls_pk_parse_pubkey(), as it includes size minima for example.
+     */
+    if( ( ret = mbedtls_rsa_complete( rsa ) ) != 0 ||
+        ( ret = mbedtls_rsa_check_pubkey( rsa ) ) != 0 )
+    {
         goto cleanup;
+    }
 
     if( p != end )
     {
diff --git a/library/rsa.c b/library/rsa.c
index af1a878..09fd379 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -249,6 +249,9 @@
 {
     int ret = 0;
     int have_N, have_P, have_Q, have_D, have_E;
+#if !defined(MBEDTLS_RSA_NO_CRT)
+    int have_DP, have_DQ, have_QP;
+#endif
     int n_missing, pq_missing, d_missing, is_pub, is_priv;
 
     RSA_VALIDATE_RET( ctx != NULL );
@@ -259,6 +262,12 @@
     have_D = ( mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 );
     have_E = ( mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0 );
 
+#if !defined(MBEDTLS_RSA_NO_CRT)
+    have_DP = ( mbedtls_mpi_cmp_int( &ctx->DP, 0 ) != 0 );
+    have_DQ = ( mbedtls_mpi_cmp_int( &ctx->DQ, 0 ) != 0 );
+    have_QP = ( mbedtls_mpi_cmp_int( &ctx->QP, 0 ) != 0 );
+#endif
+
     /*
      * Check whether provided parameters are enough
      * to deduce all others. The following incomplete
@@ -324,7 +333,7 @@
      */
 
 #if !defined(MBEDTLS_RSA_NO_CRT)
-    if( is_priv )
+    if( is_priv && ! ( have_DP && have_DQ && have_QP ) )
     {
         ret = mbedtls_rsa_deduce_crt( &ctx->P,  &ctx->Q,  &ctx->D,
                                       &ctx->DP, &ctx->DQ, &ctx->QP );
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index b8f35fe..65f59fb 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -1004,8 +1004,6 @@
 #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
     if( mbedtls_ssl_hw_record_init != NULL )
     {
-        int ret = 0;
-
         MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_init()" ) );
 
         if( ( ret = mbedtls_ssl_hw_record_init( ssl, key1, key2, transform->keylen,
@@ -2885,15 +2883,18 @@
 /*
  * Swap transform_out and out_ctr with the alternative ones
  */
-static void ssl_swap_epochs( mbedtls_ssl_context *ssl )
+static int ssl_swap_epochs( mbedtls_ssl_context *ssl )
 {
     mbedtls_ssl_transform *tmp_transform;
     unsigned char tmp_out_ctr[8];
+#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
+    int ret;
+#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
 
     if( ssl->transform_out == ssl->handshake->alt_transform_out )
     {
         MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip swap epochs" ) );
-        return;
+        return( 0 );
     }
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "swap epochs" ) );
@@ -2920,7 +2921,9 @@
             return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
         }
     }
-#endif
+#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
+
+    return( 0 );
 }
 
 /*
@@ -2957,7 +2960,8 @@
 
         ssl->handshake->cur_msg = ssl->handshake->flight;
         ssl->handshake->cur_msg_p = ssl->handshake->flight->p + 12;
-        ssl_swap_epochs( ssl );
+        if( ( ret = ssl_swap_epochs( ssl ) ) != 0 )
+            return( ret );
 
         ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_SENDING;
     }
@@ -2980,7 +2984,8 @@
         if( is_finished && ssl->handshake->cur_msg_p == ( cur->p + 12 ) )
         {
             MBEDTLS_SSL_DEBUG_MSG( 2, ( "swap epochs to send finished message" ) );
-            ssl_swap_epochs( ssl );
+            if( ( ret = ssl_swap_epochs( ssl ) ) != 0 )
+                return( ret );
         }
 
         ret = ssl_get_remaining_payload_in_datagram( ssl );
@@ -3017,7 +3022,10 @@
             if( ( max_frag_len < 12 ) || ( max_frag_len == 12 && hs_len != 0 ) )
             {
                 if( is_finished )
-                    ssl_swap_epochs( ssl );
+                {
+                    if( ( ret = ssl_swap_epochs( ssl ) ) != 0 )
+                        return( ret );
+                }
 
                 if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
                     return( ret );
diff --git a/library/x509write_csr.c b/library/x509write_csr.c
index b65a11c..7406a97 100644
--- a/library/x509write_csr.c
+++ b/library/x509write_csr.c
@@ -226,7 +226,9 @@
     /*
      * Prepare signature
      */
-    mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, len, hash );
+    ret = mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, len, hash );
+    if( ret != 0 )
+        return( ret );
 
     if( ( ret = mbedtls_pk_sign( ctx->key, ctx->md_alg, hash, 0, sig, &sig_len,
                                  f_rng, p_rng ) ) != 0 )
diff --git a/programs/pkey/ecdsa.c b/programs/pkey/ecdsa.c
index b851c31..9feb160 100644
--- a/programs/pkey/ecdsa.c
+++ b/programs/pkey/ecdsa.c
@@ -189,7 +189,7 @@
                                        sig, &sig_len,
                                        mbedtls_ctr_drbg_random, &ctr_drbg ) ) != 0 )
     {
-        mbedtls_printf( " failed\n  ! mbedtls_ecdsa_genkey returned %d\n", ret );
+        mbedtls_printf( " failed\n  ! mbedtls_ecdsa_write_signature returned %d\n", ret );
         goto exit;
     }
     mbedtls_printf( " ok (signature length = %u)\n", (unsigned int) sig_len );
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index f95ca0c..13d0d17 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -115,6 +115,7 @@
 #define DFL_FALLBACK            -1
 #define DFL_EXTENDED_MS         -1
 #define DFL_ETM                 -1
+#define DFL_SKIP_CLOSE_NOTIFY   0
 
 #define GET_REQUEST "GET %s HTTP/1.0\r\nExtra-header: "
 #define GET_REQUEST_END "\r\n\r\n"
@@ -278,6 +279,7 @@
     "                        options: 1 (level-triggered, implies nbio=1),\n" \
     "    read_timeout=%%d     default: 0 ms (no timeout)\n"        \
     "    max_resend=%%d       default: 0 (no resend on timeout)\n" \
+    "    skip_close_notify=%%d default: 0 (send close_notify)\n" \
     "\n"                                                    \
     USAGE_DTLS                                              \
     "\n"                                                    \
@@ -376,6 +378,7 @@
     int dgram_packing;          /* allow/forbid datagram packing            */
     int extended_ms;            /* negotiate extended master secret?        */
     int etm;                    /* negotiate encrypt then mac?              */
+    int skip_close_notify;      /* skip sending the close_notify alert      */
 } opt;
 
 int query_config( const char *config );
@@ -653,6 +656,7 @@
     opt.extended_ms         = DFL_EXTENDED_MS;
     opt.etm                 = DFL_ETM;
     opt.dgram_packing       = DFL_DGRAM_PACKING;
+    opt.skip_close_notify   = DFL_SKIP_CLOSE_NOTIFY;
 
     for( i = 1; i < argc; i++ )
     {
@@ -993,6 +997,12 @@
         {
             return query_config( q );
         }
+        else if( strcmp( p, "skip_close_notify" ) == 0 )
+        {
+            opt.skip_close_notify = atoi( q );
+            if( opt.skip_close_notify < 0 || opt.skip_close_notify > 1 )
+                goto usage;
+        }
         else
             goto usage;
     }
@@ -2032,10 +2042,25 @@
     mbedtls_printf( "  . Closing the connection..." );
     fflush( stdout );
 
-    /* No error checking, the connection might be closed already */
-    do ret = mbedtls_ssl_close_notify( &ssl );
-    while( ret == MBEDTLS_ERR_SSL_WANT_WRITE );
-    ret = 0;
+    /*
+     * Most of the time sending a close_notify before closing is the right
+     * thing to do. However, when the server already knows how many messages
+     * are expected and closes the connection by itself, this alert becomes
+     * redundant. Sometimes with DTLS this redundancy becomes a problem by
+     * leading to a race condition where the server might close the connection
+     * before seeing the alert, and since UDP is connection-less when the
+     * alert arrives it will be seen as a new connection, which will fail as
+     * the alert is clearly not a valid ClientHello. This may cause spurious
+     * failures in tests that use DTLS and resumption with ssl_server2 in
+     * ssl-opt.sh, avoided by enabling skip_close_notify client-side.
+     */
+    if( opt.skip_close_notify == 0 )
+    {
+        /* No error checking, the connection might be closed already */
+        do ret = mbedtls_ssl_close_notify( &ssl );
+        while( ret == MBEDTLS_ERR_SSL_WANT_WRITE );
+        ret = 0;
+    }
 
     mbedtls_printf( " done\n" );
 
diff --git a/programs/test/benchmark.c b/programs/test/benchmark.c
index 2b86566..9c06d07 100644
--- a/programs/test/benchmark.c
+++ b/programs/test/benchmark.c
@@ -674,12 +674,13 @@
         mbedtls_ctr_drbg_context ctr_drbg;
 
         mbedtls_ctr_drbg_init( &ctr_drbg );
-
         if( mbedtls_ctr_drbg_seed( &ctr_drbg, myrand, NULL, NULL, 0 ) != 0 )
             mbedtls_exit(1);
         TIME_AND_TSC( "CTR_DRBG (NOPR)",
                 mbedtls_ctr_drbg_random( &ctr_drbg, buf, BUFSIZE ) );
+        mbedtls_ctr_drbg_free( &ctr_drbg );
 
+        mbedtls_ctr_drbg_init( &ctr_drbg );
         if( mbedtls_ctr_drbg_seed( &ctr_drbg, myrand, NULL, NULL, 0 ) != 0 )
             mbedtls_exit(1);
         mbedtls_ctr_drbg_set_prediction_resistance( &ctr_drbg, MBEDTLS_CTR_DRBG_PR_ON );
diff --git a/scripts/output_env.sh b/scripts/output_env.sh
index c809d46..04edc38 100755
--- a/scripts/output_env.sh
+++ b/scripts/output_env.sh
@@ -23,11 +23,15 @@
     shift
     ARGS="$1"
     shift
-    FAIL_MSG="$1"
+    VARIANT="$1"
     shift
 
-    if ! `type "$BIN" > /dev/null 2>&1`; then
-        echo "* $FAIL_MSG"
+    if [ -n "$VARIANT" ]; then
+        VARIANT=" ($VARIANT)"
+    fi
+
+    if ! type "$BIN" > /dev/null 2>&1; then
+        echo " * ${BIN##*/}$VARIANT: Not found."
         return 0
     fi
 
@@ -41,81 +45,127 @@
         VERSION_STR=`echo "$VERSION_STR" | $FILTER`
     done
 
-    echo "* ${BIN##*/}: $BIN: $VERSION_STR"
+    if [ -z "$VERSION_STR" ]; then
+        VERSION_STR="Version could not be determined."
+    fi
+
+    echo " * ${BIN##*/}$VARIANT: ${BIN} : ${VERSION_STR} "
 }
 
+echo "** Platform:"
+echo
+
+if [ `uname -s` = "Linux" ]; then
+    echo "Linux variant"
+    lsb_release -d -c
+else
+    echo "Unknown Unix variant"
+fi
+
+echo
+
 print_version "uname" "-a" ""
+
+echo
+echo
+echo "** Tool Versions:"
 echo
 
 if [ "${RUN_ARMCC:-1}" -ne 0 ]; then
     : "${ARMC5_CC:=armcc}"
-    print_version "$ARMC5_CC" "--vsn" "armcc not found!" "head -n 2"
+    print_version "$ARMC5_CC" "--vsn" "" "head -n 2"
     echo
 
     : "${ARMC6_CC:=armclang}"
-    print_version "$ARMC6_CC" "--vsn" "armclang not found!" "head -n 2"
+    print_version "$ARMC6_CC" "--vsn" "" "head -n 2"
     echo
 fi
 
-print_version "arm-none-eabi-gcc" "--version" "gcc-arm not found!" "head -n 1"
+print_version "arm-none-eabi-gcc" "--version" "" "head -n 1"
 echo
 
-print_version "gcc" "--version" "gcc not found!" "head -n 1"
+print_version "gcc" "--version" "" "head -n 1"
 echo
 
-print_version "clang" "--version" "clang not found" "head -n 2"
+print_version "clang" "--version" "" "head -n 2"
 echo
 
-print_version "ldd" "--version"                     \
-    "No ldd present: can't determine libc version!" \
-    "head -n 1"
+print_version "ldd" "--version" "" "head -n 1"
 echo
 
-print_version "valgrind" "--version" "valgrind not found!"
+print_version "valgrind" "--version" ""
+echo
+
+print_version "gdb" "--version" "" "head -n 1"
+echo
+
+print_version "perl" "--version" "" "head -n 2" "grep ."
+echo
+
+print_version "python" "--version" "" "head -n 1"
+echo
+
+# Find the installed version of Pylint. Installed as a distro package this can
+# be pylint3 and as a PEP egg, pylint. In test scripts We prefer pylint over
+# pylint3
+if type pylint >/dev/null 2>/dev/null; then
+    print_version "pylint" "--version" "" "sed /^.*config/d" "grep pylint"
+elif type pylint3 >/dev/null 2>/dev/null; then
+    print_version "pylint3" "--version" "" "sed /^.*config/d" "grep pylint"
+else
+    echo " * pylint or pylint3: Not found."
+fi
 echo
 
 : ${OPENSSL:=openssl}
-print_version "$OPENSSL" "version" "openssl not found!"
+print_version "$OPENSSL" "version" "default"
 echo
 
 if [ -n "${OPENSSL_LEGACY+set}" ]; then
-    print_version "$OPENSSL_LEGACY" "version" "openssl legacy version not found!"
-    echo
+    print_version "$OPENSSL_LEGACY" "version" "legacy"
+else
+    echo " * openssl (legacy): Not configured."
 fi
+echo
 
 if [ -n "${OPENSSL_NEXT+set}" ]; then
-    print_version "$OPENSSL_NEXT" "version" "openssl next version not found!"
-    echo
+    print_version "$OPENSSL_NEXT" "version" "next"
+else
+    echo " * openssl (next): Not configured."
 fi
+echo
 
 : ${GNUTLS_CLI:=gnutls-cli}
-print_version "$GNUTLS_CLI" "--version" "gnuTLS client not found!" "head -n 1"
+print_version "$GNUTLS_CLI" "--version" "default" "head -n 1"
 echo
 
 : ${GNUTLS_SERV:=gnutls-serv}
-print_version "$GNUTLS_SERV" "--version" "gnuTLS server not found!" "head -n 1"
+print_version "$GNUTLS_SERV" "--version" "default" "head -n 1"
 echo
 
 if [ -n "${GNUTLS_LEGACY_CLI+set}" ]; then
-    print_version "$GNUTLS_LEGACY_CLI" "--version" \
-        "gnuTLS client legacy version not found!"  \
-        "head -n 1"
-    echo
+    print_version "$GNUTLS_LEGACY_CLI" "--version" "legacy" "head -n 1"
+else
+     echo " * gnutls-cli (legacy): Not configured."
 fi
+echo
 
 if [ -n "${GNUTLS_LEGACY_SERV+set}" ]; then
-    print_version "$GNUTLS_LEGACY_SERV" "--version" \
-        "gnuTLS server legacy version not found!"   \
-        "head -n 1"
-    echo
-fi
-
-if `hash dpkg > /dev/null 2>&1`; then
-    echo "* asan:"
-    dpkg -s libasan2 2> /dev/null | grep -i version
-    dpkg -s libasan1 2> /dev/null | grep -i version
-    dpkg -s libasan0 2> /dev/null | grep -i version
+    print_version "$GNUTLS_LEGACY_SERV" "--version" "legacy" "head -n 1"
 else
-    echo "* No dpkg present: can't determine asan version!"
+    echo " * gnutls-serv (legacy): Not configured."
+fi
+echo
+
+echo " * Installed asan versions:"
+if type dpkg-query >/dev/null 2>/dev/null; then
+    if ! dpkg-query -f '${Status} ${Package}: ${Version}\n' -W 'libasan*' |
+         awk '$3 == "installed" && $4 !~ /-/ {print $4, $5}' |
+         grep .
+    then
+        echo "   No asan versions installed."
+    fi
+else
+    echo "  Unable to determine the asan version without dpkg."
 fi
 echo
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 8f25c6b..dd8f510 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -652,6 +652,45 @@
     if_build_succeeded tests/compat.sh
 }
 
+component_test_zlib_make() {
+    msg "build: zlib enabled, make"
+    scripts/config.pl set MBEDTLS_ZLIB_SUPPORT
+    make ZLIB=1 CFLAGS='-Werror -O1'
+
+    msg "test: main suites (zlib, make)"
+    make test
+
+    msg "test: ssl-opt.sh (zlib, make)"
+    if_build_succeeded tests/ssl-opt.sh
+}
+support_test_zlib_make () {
+    base=support_test_zlib_$$
+    cat <<'EOF' > ${base}.c
+#include "zlib.h"
+int main(void) { return 0; }
+EOF
+    gcc -o ${base}.exe ${base}.c -lz 2>/dev/null
+    ret=$?
+    rm -f ${base}.*
+    return $ret
+}
+
+component_test_zlib_cmake() {
+    msg "build: zlib enabled, cmake"
+    scripts/config.pl set MBEDTLS_ZLIB_SUPPORT
+    cmake -D ENABLE_ZLIB_SUPPORT=On -D CMAKE_BUILD_TYPE:String=Check .
+    make
+
+    msg "test: main suites (zlib, cmake)"
+    make test
+
+    msg "test: ssl-opt.sh (zlib, cmake)"
+    if_build_succeeded tests/ssl-opt.sh
+}
+support_test_zlib_cmake () {
+    support_test_zlib_make "$@"
+}
+
 component_test_ref_configs () {
     msg "test/build: ref-configs (ASan build)" # ~ 6 min 20s
     CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
@@ -880,8 +919,8 @@
     scripts/config.pl unset MBEDTLS_FS_IO
     # Note, _DEFAULT_SOURCE needs to be defined for platforms using glibc version >2.19,
     # to re-enable platform integration features otherwise disabled in C99 builds
-    make CC=gcc CFLAGS='-Werror -Wall -Wextra -std=c99 -pedantic -O0 -D_DEFAULT_SOURCE' lib programs
-    make CC=gcc CFLAGS='-Werror -Wall -Wextra -O0' test
+    make CC=gcc CFLAGS='-Werror -Wall -Wextra -std=c99 -pedantic -Os -D_DEFAULT_SOURCE' lib programs
+    make CC=gcc CFLAGS='-Werror -Wall -Wextra -Os' test
 }
 
 component_build_no_std_function () {
@@ -890,21 +929,21 @@
     scripts/config.pl full
     scripts/config.pl set MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
     scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED
-    make CC=gcc CFLAGS='-Werror -Wall -Wextra -O0'
+    make CC=gcc CFLAGS='-Werror -Wall -Wextra -Os'
 }
 
 component_build_no_ssl_srv () {
     msg "build: full config except ssl_srv.c, make, gcc" # ~ 30s
     scripts/config.pl full
     scripts/config.pl unset MBEDTLS_SSL_SRV_C
-    make CC=gcc CFLAGS='-Werror -Wall -Wextra -O0'
+    make CC=gcc CFLAGS='-Werror -Wall -Wextra -O1'
 }
 
 component_build_no_ssl_cli () {
     msg "build: full config except ssl_cli.c, make, gcc" # ~ 30s
     scripts/config.pl full
     scripts/config.pl unset MBEDTLS_SSL_CLI_C
-    make CC=gcc CFLAGS='-Werror -Wall -Wextra -O0'
+    make CC=gcc CFLAGS='-Werror -Wall -Wextra -O1'
 }
 
 component_build_no_sockets () {
@@ -914,7 +953,7 @@
     scripts/config.pl full
     scripts/config.pl unset MBEDTLS_NET_C # getaddrinfo() undeclared, etc.
     scripts/config.pl set MBEDTLS_NO_PLATFORM_ENTROPY # uses syscall() on GNU/Linux
-    make CC=gcc CFLAGS='-Werror -Wall -Wextra -O0 -std=c99 -pedantic' lib
+    make CC=gcc CFLAGS='-Werror -Wall -Wextra -O1 -std=c99 -pedantic' lib
 }
 
 component_test_memory_buffer_allocator_backtrace () {
@@ -1052,6 +1091,30 @@
     make test
 }
 
+test_build_opt () {
+    info=$1 cc=$2; shift 2
+    for opt in "$@"; do
+          msg "build/test: $cc $opt, $info" # ~ 30s
+          make CC="$cc" CFLAGS="$opt -Wall -Wextra -Werror"
+          # We're confident enough in compilers to not run _all_ the tests,
+          # but at least run the unit tests. In particular, runs with
+          # optimizations use inline assembly whereas runs with -O0
+          # skip inline assembly.
+          make test # ~30s
+          make clean
+    done
+}
+
+component_test_clang_opt () {
+    scripts/config.pl full
+    test_build_opt 'full config' clang -O0 -Os -O2
+}
+
+component_test_gcc_opt () {
+    scripts/config.pl full
+    test_build_opt 'full config' gcc -O0 -Os -O2
+}
+
 component_build_mbedtls_config_file () {
     msg "build: make with MBEDTLS_CONFIG_FILE" # ~40s
     # Use the full config so as to catch a maximum of places where
@@ -1220,6 +1283,12 @@
     armc6_build_test "--target=aarch64-arm-none-eabi -march=armv8.2-a"
 }
 
+component_build_ssl_hw_record_accel() {
+    msg "build: default config with MBEDTLS_SSL_HW_RECORD_ACCEL enabled"
+    scripts/config.pl set MBEDTLS_SSL_HW_RECORD_ACCEL
+    make CFLAGS='-Werror -O1'
+}
+
 component_test_allow_sha1 () {
     msg "build: allow SHA1 in certificates by default"
     scripts/config.pl set MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES
@@ -1341,7 +1410,13 @@
 }
 
 support_check_python_files () {
-    type pylint3 >/dev/null 2>/dev/null
+    # Find the installed version of Pylint. Installed as a distro package this can
+    # be pylint3 and as a PEP egg, pylint.
+    if type pylint >/dev/null 2>/dev/null || type pylint3 >/dev/null 2>/dev/null; then
+        true;
+    else
+        false;
+    fi
 }
 component_check_python_files () {
     msg "Lint: Python scripts"
diff --git a/tests/scripts/check-python-files.sh b/tests/scripts/check-python-files.sh
index 9290418..6b864d2 100755
--- a/tests/scripts/check-python-files.sh
+++ b/tests/scripts/check-python-files.sh
@@ -9,4 +9,15 @@
 # Run 'pylint' on Python files for programming errors and helps enforcing
 # PEP8 coding standards.
 
-pylint3 -j 2 scripts/*.py tests/scripts/*.py
+# Find the installed version of Pylint. Installed as a distro package this can
+# be pylint3 and as a PEP egg, pylint. We prefer pylint over pylint3
+if type pylint >/dev/null 2>/dev/null; then
+    PYLINT=pylint
+elif type pylint3 >/dev/null 2>/dev/null; then
+    PYLINT=pylint3
+else
+    echo 'Pylint was not found.'
+    exit 1
+fi
+
+$PYLINT -j 2 scripts/*.py tests/scripts/*.py
diff --git a/tests/scripts/mbedtls_test.py b/tests/scripts/mbedtls_test.py
index 6ac68a4..8f24435 100755
--- a/tests/scripts/mbedtls_test.py
+++ b/tests/scripts/mbedtls_test.py
@@ -310,7 +310,10 @@
 
         param_bytes, length = self.test_vector_to_bytes(function_id,
                                                         dependencies, args)
-        self.send_kv(''.join('{:02x}'.format(x) for x in length), ''.join('{:02x}'.format(x) for x in param_bytes))
+        self.send_kv(
+            ''.join('{:02x}'.format(x) for x in length),
+            ''.join('{:02x}'.format(x) for x in param_bytes)
+        )
 
     @staticmethod
     def get_result(value):
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index fa334c3..9fbf592 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -905,6 +905,18 @@
             -s "Protocol is DTLSv1.2" \
             -s "Ciphersuite is TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256"
 
+requires_config_enabled MBEDTLS_ZLIB_SUPPORT
+run_test    "Default (compression enabled)" \
+            "$P_SRV debug_level=3" \
+            "$P_CLI debug_level=3" \
+            0 \
+            -s "Allocating compression buffer" \
+            -c "Allocating compression buffer" \
+            -s "Record expansion is unknown (compression)" \
+            -c "Record expansion is unknown (compression)" \
+            -S "error" \
+            -C "error"
+
 # Test current time in ServerHello
 requires_config_enabled MBEDTLS_HAVE_TIME
 run_test    "ServerHello contains gmt_unix_time" \
@@ -1375,7 +1387,7 @@
             -s "dumping 'input payload after decrypt' (0 bytes)" \
             -c "0 bytes written in 1 fragments"
 
-run_test    "Default, no Encrypt then MAC: empty application data record" \
+run_test    "Encrypt then MAC: disabled, empty application data record" \
             "$P_SRV auth_mode=none debug_level=4 etm=0" \
             "$P_CLI auth_mode=none etm=0 request_size=0" \
             0 \
@@ -1390,7 +1402,7 @@
             -s "dumping 'input payload after decrypt' (0 bytes)" \
             -c "0 bytes written in 1 fragments"
 
-run_test    "Default, no Encrypt then MAC, DTLS: empty application data record" \
+run_test    "Encrypt then MAC, DTLS: disabled, empty application data record" \
             "$P_SRV auth_mode=none debug_level=4 etm=0 dtls=1" \
             "$P_CLI auth_mode=none etm=0 request_size=0 dtls=1" \
             0 \
@@ -1563,7 +1575,7 @@
 
 run_test    "Session resume using tickets, DTLS: basic" \
             "$P_SRV debug_level=3 dtls=1 tickets=1" \
-            "$P_CLI debug_level=3 dtls=1 tickets=1 reconnect=1" \
+            "$P_CLI debug_level=3 dtls=1 tickets=1 reconnect=1 skip_close_notify=1" \
             0 \
             -c "client hello, adding session ticket extension" \
             -s "found session ticket extension" \
@@ -1577,7 +1589,7 @@
 
 run_test    "Session resume using tickets, DTLS: cache disabled" \
             "$P_SRV debug_level=3 dtls=1 tickets=1 cache_max=0" \
-            "$P_CLI debug_level=3 dtls=1 tickets=1 reconnect=1" \
+            "$P_CLI debug_level=3 dtls=1 tickets=1 reconnect=1 skip_close_notify=1" \
             0 \
             -c "client hello, adding session ticket extension" \
             -s "found session ticket extension" \
@@ -1591,7 +1603,7 @@
 
 run_test    "Session resume using tickets, DTLS: timeout" \
             "$P_SRV debug_level=3 dtls=1 tickets=1 cache_max=0 ticket_timeout=1" \
-            "$P_CLI debug_level=3 dtls=1 tickets=1 reconnect=1 reco_delay=2" \
+            "$P_CLI debug_level=3 dtls=1 tickets=1 reconnect=1 skip_close_notify=1 reco_delay=2" \
             0 \
             -c "client hello, adding session ticket extension" \
             -s "found session ticket extension" \
@@ -1723,7 +1735,7 @@
 
 run_test    "Session resume using cache, DTLS: tickets enabled on client" \
             "$P_SRV dtls=1 debug_level=3 tickets=0" \
-            "$P_CLI dtls=1 debug_level=3 tickets=1 reconnect=1" \
+            "$P_CLI dtls=1 debug_level=3 tickets=1 reconnect=1 skip_close_notify=1" \
             0 \
             -c "client hello, adding session ticket extension" \
             -s "found session ticket extension" \
@@ -1737,7 +1749,7 @@
 
 run_test    "Session resume using cache, DTLS: tickets enabled on server" \
             "$P_SRV dtls=1 debug_level=3 tickets=1" \
-            "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1" \
+            "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 skip_close_notify=1" \
             0 \
             -C "client hello, adding session ticket extension" \
             -S "found session ticket extension" \
@@ -1751,7 +1763,7 @@
 
 run_test    "Session resume using cache, DTLS: cache_max=0" \
             "$P_SRV dtls=1 debug_level=3 tickets=0 cache_max=0" \
-            "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1" \
+            "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 skip_close_notify=1" \
             0 \
             -S "session successfully restored from cache" \
             -S "session successfully restored from ticket" \
@@ -1760,7 +1772,7 @@
 
 run_test    "Session resume using cache, DTLS: cache_max=1" \
             "$P_SRV dtls=1 debug_level=3 tickets=0 cache_max=1" \
-            "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1" \
+            "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 skip_close_notify=1" \
             0 \
             -s "session successfully restored from cache" \
             -S "session successfully restored from ticket" \
@@ -1769,7 +1781,7 @@
 
 run_test    "Session resume using cache, DTLS: timeout > delay" \
             "$P_SRV dtls=1 debug_level=3 tickets=0" \
-            "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 reco_delay=0" \
+            "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 skip_close_notify=1 reco_delay=0" \
             0 \
             -s "session successfully restored from cache" \
             -S "session successfully restored from ticket" \
@@ -1778,7 +1790,7 @@
 
 run_test    "Session resume using cache, DTLS: timeout < delay" \
             "$P_SRV dtls=1 debug_level=3 tickets=0 cache_timeout=1" \
-            "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 reco_delay=2" \
+            "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 skip_close_notify=1 reco_delay=2" \
             0 \
             -S "session successfully restored from cache" \
             -S "session successfully restored from ticket" \
@@ -1787,7 +1799,7 @@
 
 run_test    "Session resume using cache, DTLS: no timeout" \
             "$P_SRV dtls=1 debug_level=3 tickets=0 cache_timeout=0" \
-            "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 reco_delay=2" \
+            "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 skip_close_notify=1 reco_delay=2" \
             0 \
             -s "session successfully restored from cache" \
             -S "session successfully restored from ticket" \
@@ -3336,19 +3348,19 @@
 
 run_test    "Event-driven I/O, DTLS: ticket + client auth + resume" \
             "$P_SRV dtls=1 event=1 tickets=1 auth_mode=required" \
-            "$P_CLI dtls=1 event=1 tickets=1 reconnect=1" \
+            "$P_CLI dtls=1 event=1 tickets=1 reconnect=1 skip_close_notify=1" \
             0 \
             -c "Read from server: .* bytes read"
 
 run_test    "Event-driven I/O, DTLS: ticket + resume" \
             "$P_SRV dtls=1 event=1 tickets=1 auth_mode=none" \
-            "$P_CLI dtls=1 event=1 tickets=1 reconnect=1" \
+            "$P_CLI dtls=1 event=1 tickets=1 reconnect=1 skip_close_notify=1" \
             0 \
             -c "Read from server: .* bytes read"
 
 run_test    "Event-driven I/O, DTLS: session-id resume" \
             "$P_SRV dtls=1 event=1 tickets=0 auth_mode=none" \
-            "$P_CLI dtls=1 event=1 tickets=0 reconnect=1" \
+            "$P_CLI dtls=1 event=1 tickets=0 reconnect=1 skip_close_notify=1" \
             0 \
             -c "Read from server: .* bytes read"
 
@@ -3360,7 +3372,7 @@
 run_test    "Event-driven I/O, DTLS: session-id resume, UDP packing" \
             -p "$P_PXY pack=50" \
             "$P_SRV dtls=1 event=1 tickets=0 auth_mode=required" \
-            "$P_CLI dtls=1 event=1 tickets=0 reconnect=1" \
+            "$P_CLI dtls=1 event=1 tickets=0 reconnect=1 skip_close_notify=1" \
             0 \
             -c "Read from server: .* bytes read"
 
@@ -4059,15 +4071,8 @@
 # Test for ClientHello without extensions
 
 requires_gnutls
-run_test    "ClientHello without extensions, SHA-1 allowed" \
-            "$P_SRV debug_level=3 key_file=data_files/server2.key crt_file=data_files/server2.crt" \
-            "$G_CLI --priority=NORMAL:%NO_EXTENSIONS:%DISABLE_SAFE_RENEGOTIATION localhost" \
-            0 \
-            -s "dumping 'client hello extensions' (0 bytes)"
-
-requires_gnutls
-run_test    "ClientHello without extensions, SHA-1 forbidden in certificates on server" \
-            "$P_SRV debug_level=3 key_file=data_files/server2.key crt_file=data_files/server2.crt allow_sha1=0" \
+run_test    "ClientHello without extensions" \
+            "$P_SRV debug_level=3" \
             "$G_CLI --priority=NORMAL:%NO_EXTENSIONS:%DISABLE_SAFE_RENEGOTIATION localhost" \
             0 \
             -s "dumping 'client hello extensions' (0 bytes)"
@@ -6373,7 +6378,7 @@
              key_file=data_files/server8.key \
              hs_timeout=10000-60000 \
              force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
-             mtu=1450 reconnect=1 reco_delay=1" \
+             mtu=1450 reconnect=1 skip_close_notify=1 reco_delay=1" \
             0 \
             -S "autoreduction" \
             -s "found fragmented DTLS handshake message" \
@@ -7220,7 +7225,7 @@
             "$P_SRV dtls=1 dgram_packing=0 hs_timeout=500-10000 tickets=0 auth_mode=none \
              psk=abc123 debug_level=3" \
             "$P_CLI dtls=1 dgram_packing=0 hs_timeout=500-10000 tickets=0 psk=abc123 \
-             debug_level=3 reconnect=1 read_timeout=1000 max_resend=10 \
+             debug_level=3 reconnect=1 skip_close_notify=1 read_timeout=1000 max_resend=10 \
              force_ciphersuite=TLS-PSK-WITH-AES-128-CCM-8" \
             0 \
             -s "a session has been resumed" \
@@ -7234,7 +7239,7 @@
             "$P_SRV dtls=1 dgram_packing=0 hs_timeout=500-10000 tickets=0 auth_mode=none \
              psk=abc123 debug_level=3 nbio=2" \
             "$P_CLI dtls=1 dgram_packing=0 hs_timeout=500-10000 tickets=0 psk=abc123 \
-             debug_level=3 reconnect=1 read_timeout=1000 max_resend=10 \
+             debug_level=3 reconnect=1 skip_close_notify=1 read_timeout=1000 max_resend=10 \
              force_ciphersuite=TLS-PSK-WITH-AES-128-CCM-8 nbio=2" \
             0 \
             -s "a session has been resumed" \
diff --git a/tests/suites/host_test.function b/tests/suites/host_test.function
index 0f98d23..26a7be4 100644
--- a/tests/suites/host_test.function
+++ b/tests/suites/host_test.function
@@ -474,7 +474,7 @@
           testfile_index++ )
     {
         int unmet_dep_count = 0;
-        char *unmet_dependencies[20];
+        int unmet_dependencies[20];
 
         test_filename = test_files[ testfile_index ];
 
@@ -520,19 +520,7 @@
                     int dep_id = strtol( params[i], NULL, 10 );
                     if( dep_check( dep_id ) != DEPENDENCY_SUPPORTED )
                     {
-                        if( 0 == option_verbose )
-                        {
-                            /* Only one count is needed if not verbose */
-                            unmet_dep_count++;
-                            break;
-                        }
-
-                        unmet_dependencies[ unmet_dep_count ] = strdup( params[i] );
-                        if(  unmet_dependencies[ unmet_dep_count ] == NULL )
-                        {
-                            mbedtls_fprintf( stderr, "FATAL: Out of memory\n" );
-                            mbedtls_exit( MBEDTLS_EXIT_FAILURE );
-                        }
+                        unmet_dependencies[unmet_dep_count] = dep_id;
                         unmet_dep_count++;
                     }
                 }
@@ -599,9 +587,8 @@
                     mbedtls_fprintf( stdout, "\n   Unmet dependencies: " );
                     for( i = 0; i < unmet_dep_count; i++ )
                     {
-                        mbedtls_fprintf( stdout, "%s  ",
+                        mbedtls_fprintf( stdout, "%d ",
                                         unmet_dependencies[i] );
-                        free( unmet_dependencies[i] );
                     }
                 }
                 mbedtls_fprintf( stdout, "\n" );
@@ -646,10 +633,6 @@
                 total_errors++;
         }
         fclose( file );
-
-        /* In case we encounter early end of file */
-        for( i = 0; i < unmet_dep_count; i++ )
-            free( unmet_dependencies[i] );
     }
 
     mbedtls_fprintf( stdout, "\n----------------------------------------------------------------------------\n\n");
diff --git a/tests/suites/test_suite_ctr_drbg.function b/tests/suites/test_suite_ctr_drbg.function
index 4a97826..01050d9 100644
--- a/tests/suites/test_suite_ctr_drbg.function
+++ b/tests/suites/test_suite_ctr_drbg.function
@@ -44,11 +44,11 @@
 
     /* CTR_DRBG_Instantiate(entropy[:entropy->len], nonce, perso, <ignored>)
      * where nonce||perso = nonce[nonce->len] */
-    TEST_ASSERT( mbedtls_ctr_drbg_seed_entropy_len(
+    mbedtls_ctr_drbg_set_entropy_len( &ctx, entropy_chunk_len );
+    TEST_ASSERT( mbedtls_ctr_drbg_seed(
                      &ctx,
                      mbedtls_test_entropy_func, entropy->x,
-                     nonce->x, nonce->len,
-                     entropy_chunk_len ) == 0 );
+                     nonce->x, nonce->len ) == 0 );
     if( reseed_mode == RESEED_ALWAYS )
         mbedtls_ctr_drbg_set_prediction_resistance(
             &ctx,
diff --git a/tests/suites/test_suite_ecdsa.function b/tests/suites/test_suite_ecdsa.function
index 0e7283b..2844bea 100644
--- a/tests/suites/test_suite_ecdsa.function
+++ b/tests/suites/test_suite_ecdsa.function
@@ -527,7 +527,9 @@
     TEST_ASSERT( md_info != NULL );
 
     hlen = mbedtls_md_get_size( md_info );
-    mbedtls_md( md_info, (const unsigned char *) msg, strlen( msg ), hash );
+    TEST_ASSERT( mbedtls_md( md_info,
+                             (const unsigned char *) msg, strlen( msg ),
+                             hash ) == 0 );
 
     mbedtls_ecp_set_max_ops( max_ops );
 
diff --git a/tests/suites/test_suite_memory_buffer_alloc.data b/tests/suites/test_suite_memory_buffer_alloc.data
index d59f113..d780fd4 100644
--- a/tests/suites/test_suite_memory_buffer_alloc.data
+++ b/tests/suites/test_suite_memory_buffer_alloc.data
@@ -16,8 +16,8 @@
 Memory buffer alloc - Out of Memory test
 memory_buffer_alloc_oom_test:
 
-Memory buffer small buffer
-memory_buffer_small_buffer:
+Memory buffer: heap too small (header verification should fail)
+memory_buffer_heap_too_small:
 
-Memory buffer underalloc
+Memory buffer: attempt to allocate SIZE_MAX
 memory_buffer_underalloc:
diff --git a/tests/suites/test_suite_memory_buffer_alloc.function b/tests/suites/test_suite_memory_buffer_alloc.function
index bc03436..cc884c2 100644
--- a/tests/suites/test_suite_memory_buffer_alloc.function
+++ b/tests/suites/test_suite_memory_buffer_alloc.function
@@ -29,7 +29,7 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE depends_on:MBEDTLS_MEMORY_DEBUG */
+/* BEGIN_CASE */
 void memory_buffer_alloc_free_alloc( int a_bytes, int b_bytes, int c_bytes,
                                      int d_bytes, int free_a, int free_b,
                                      int free_c, int free_d, int e_bytes,
@@ -39,8 +39,11 @@
     unsigned char *ptr_a = NULL, *ptr_b = NULL, *ptr_c = NULL, *ptr_d = NULL,
                     *ptr_e = NULL, *ptr_f = NULL;
 
+#if defined(MBEDTLS_MEMORY_DEBUG)
     size_t reported_blocks;
-    size_t allocated_bytes = 0, reported_bytes;
+    size_t reported_bytes;
+#endif
+    size_t allocated_bytes = 0;
 
     mbedtls_memory_buffer_alloc_init( buf, sizeof( buf ) );
 
@@ -78,8 +81,10 @@
         allocated_bytes += d_bytes * sizeof(char);
     }
 
+#if defined(MBEDTLS_MEMORY_DEBUG)
     mbedtls_memory_buffer_alloc_cur_get( &reported_bytes, &reported_blocks );
     TEST_ASSERT( reported_bytes == allocated_bytes );
+#endif
 
     if( free_a )
     {
@@ -117,8 +122,10 @@
         allocated_bytes -= d_bytes * sizeof(char);
     }
 
+#if defined(MBEDTLS_MEMORY_DEBUG)
     mbedtls_memory_buffer_alloc_cur_get( &reported_bytes, &reported_blocks );
     TEST_ASSERT( reported_bytes == allocated_bytes );
+#endif
 
     if( e_bytes > 0 )
     {
@@ -178,8 +185,10 @@
         ptr_f = NULL;
     }
 
+#if defined(MBEDTLS_MEMORY_DEBUG)
     mbedtls_memory_buffer_alloc_cur_get( &reported_bytes, &reported_blocks );
     TEST_ASSERT( reported_bytes == 0 );
+#endif
 
     TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() == 0 );
 
@@ -188,12 +197,14 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE depends_on:MBEDTLS_MEMORY_DEBUG */
+/* BEGIN_CASE */
 void memory_buffer_alloc_oom_test(  )
 {
     unsigned char buf[1024];
     unsigned char *ptr_a = NULL, *ptr_b = NULL, *ptr_c = NULL;
+#if defined(MBEDTLS_MEMORY_DEBUG)
     size_t reported_blocks, reported_bytes;
+#endif
 
     (void)ptr_c;
 
@@ -210,8 +221,10 @@
     ptr_c = mbedtls_calloc( 431, sizeof(char) );
     TEST_ASSERT( ptr_c == NULL );
 
+#if defined(MBEDTLS_MEMORY_DEBUG)
     mbedtls_memory_buffer_alloc_cur_get( &reported_bytes, &reported_blocks );
     TEST_ASSERT( reported_bytes >= 864 && reported_bytes <= sizeof(buf) );
+#endif
 
     mbedtls_free( ptr_a );
     ptr_a = NULL;
@@ -221,8 +234,10 @@
     ptr_b = NULL;
     TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() == 0 );
 
+#if defined(MBEDTLS_MEMORY_DEBUG)
     mbedtls_memory_buffer_alloc_cur_get( &reported_bytes, &reported_blocks );
     TEST_ASSERT( reported_bytes == 0 );
+#endif
 
     TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() == 0 );
 
@@ -231,17 +246,20 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE depends_on:MBEDTLS_MEMORY_DEBUG */
-void memory_buffer_small_buffer( )
+/* BEGIN_CASE */
+void memory_buffer_heap_too_small( )
 {
     unsigned char buf[1];
 
     mbedtls_memory_buffer_alloc_init( buf, sizeof( buf ) );
+    /* With MBEDTLS_MEMORY_DEBUG enabled, this prints a message
+     * "FATAL: verification of first header failed".
+     */
     TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() != 0 );
 }
 /* END_CASE */
 
-/* BEGIN_CASE depends_on:MBEDTLS_MEMORY_DEBUG */
+/* BEGIN_CASE */
 void memory_buffer_underalloc( )
 {
     unsigned char buf[100];
diff --git a/tests/suites/test_suite_mpi.data b/tests/suites/test_suite_mpi.data
index 4d46ca7..00926ff 100644
--- a/tests/suites/test_suite_mpi.data
+++ b/tests/suites/test_suite_mpi.data
@@ -280,37 +280,106 @@
 Base test mbedtls_mpi_cmp_abs (Mix values) #3
 mbedtls_mpi_cmp_abs:10:"-2":10:"1":1
 
-Base test mbedtls_mpi_copy #1
-mbedtls_mpi_copy:0:1500
+Copy zero (1 limb) to positive (1 limb)
+mbedtls_mpi_copy_sint:0:1500
 
-Base test mpi_copy_self #1
+Copy zero (1 limb) to negative (1 limb)
+mbedtls_mpi_copy_sint:0:-1500
+
+Copy positive (1 limb) to zero (1 limb)
+mbedtls_mpi_copy_sint:1500:0
+
+Copy negative (1 limb) to zero (1 limb)
+mbedtls_mpi_copy_sint:-1500:0
+
+Copy positive (1 limb) to negative (1 limb)
+mbedtls_mpi_copy_sint:1500:-42
+
+Copy negative (1 limb) to positive (1 limb)
+mbedtls_mpi_copy_sint:-42:1500
+
+Copy zero (null) to zero (null)
+mbedtls_mpi_copy_binary:"":""
+
+Copy zero (null) to positive (1 limb)
+mbedtls_mpi_copy_binary:"":"1234"
+
+Copy positive (1 limb) to zero (null)
+mbedtls_mpi_copy_binary:"1234":""
+
+Copy positive to larger
+mbedtls_mpi_copy_binary:"bead":"ca5cadedb01dfaceacc01ade"
+
+Copy positive to smaller
+mbedtls_mpi_copy_binary:"ca5cadedb01dfaceacc01ade":"bead"
+
+Copy self: positive (1 limb)
 mpi_copy_self:14
 
-Base test mbedtls_mpi_swap #1
-mbedtls_mpi_swap:0:1500
+Copy self: zero (1 limb)
+mpi_copy_self:0
 
-Test mbedtls_mpi_shrink #1
+Swap zero (1 limb) with positive (1 limb)
+mbedtls_mpi_swap_sint:0:1500
+
+Swap zero (1 limb) with negative (1 limb)
+mbedtls_mpi_swap_sint:0:-1500
+
+Swap positive (1 limb) with zero (1 limb)
+mbedtls_mpi_swap_sint:1500:0
+
+Swap negative (1 limb) with zero (1 limb)
+mbedtls_mpi_swap_sint:-1500:0
+
+Swap positive (1 limb) with negative (1 limb)
+mbedtls_mpi_swap_sint:1500:-42
+
+Swap negative (1 limb) with positive (1 limb)
+mbedtls_mpi_swap_sint:-42:1500
+
+Swap zero (null) with zero (null)
+mbedtls_mpi_swap_binary:"":""
+
+Swap zero (null) with positive (1 limb)
+mbedtls_mpi_swap_binary:"":"1234"
+
+Swap positive (1 limb) with zero (null)
+mbedtls_mpi_swap_binary:"1234":""
+
+Swap positive with larger
+mbedtls_mpi_swap_binary:"bead":"ca5cadedb01dfaceacc01ade"
+
+Swap positive with smaller
+mbedtls_mpi_swap_binary:"ca5cadedb01dfaceacc01ade":"bead"
+
+Swap self: 1 limb
+mpi_swap_self:"face"
+
+Swap self: null
+mpi_swap_self:""
+
+Shrink 2 limbs in a buffer of size 2 to 4
 mbedtls_mpi_shrink:2:2:4:4
 
-Test mbedtls_mpi_shrink #2
+Shrink 2 limbs in a buffer of size 4 to 4
 mbedtls_mpi_shrink:4:2:4:4
 
-Test mbedtls_mpi_shrink #3
+Shrink 2 limbs in a buffer of size 8 to 4
 mbedtls_mpi_shrink:8:2:4:4
 
-Test mbedtls_mpi_shrink #4
+Shrink 4 limbs in a buffer of size 8 to 4
 mbedtls_mpi_shrink:8:4:4:4
 
-Test mbedtls_mpi_shrink #5
+Shrink 6 limbs in a buffer of size 8 to 4 yielding 6
 mbedtls_mpi_shrink:8:6:4:6
 
-Test mbedtls_mpi_shrink #6
+Shrink 2 limbs in a buffer of size 4 to 0 yielding 2
 mbedtls_mpi_shrink:4:2:0:2
 
-Test mbedtls_mpi_shrink #7
+Shrink 1 limbs in a buffer of size 4 to 0 yielding 1
 mbedtls_mpi_shrink:4:1:0:1
 
-Test mbedtls_mpi_shrink #8
+Shrink 0 limbs in a buffer of size 4 to 0 yielding 1
 mbedtls_mpi_shrink:4:0:0:1
 
 Test mbedtls_mpi_safe_cond_assign #1
diff --git a/tests/suites/test_suite_mpi.function b/tests/suites/test_suite_mpi.function
index 97c338b..f2702f1 100644
--- a/tests/suites/test_suite_mpi.function
+++ b/tests/suites/test_suite_mpi.function
@@ -550,8 +550,8 @@
     TEST_ASSERT( mbedtls_mpi_read_string( &X, 16, input_X ) == 0 );
     TEST_ASSERT( mbedtls_mpi_read_string( &Y, 16, input_Y ) == 0 );
 
-    mbedtls_mpi_grow( &X, size_X );
-    mbedtls_mpi_grow( &Y, size_Y );
+    TEST_ASSERT( mbedtls_mpi_grow( &X, size_X ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_grow( &Y, size_Y ) == 0 );
 
     TEST_ASSERT( mbedtls_mpi_lt_mpi_ct( &X, &Y, &ret ) == input_err );
     if( input_err == 0 )
@@ -579,22 +579,40 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void mbedtls_mpi_copy( int input_X, int input_A )
+void mbedtls_mpi_copy_sint( int input_X, int input_Y )
 {
-    mbedtls_mpi X, Y, A;
-    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &A );
+    mbedtls_mpi X, Y;
+    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
 
     TEST_ASSERT( mbedtls_mpi_lset( &X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_lset( &Y, input_A ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_lset( &A, input_A ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) != 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_lset( &Y, input_Y ) == 0 );
+
     TEST_ASSERT( mbedtls_mpi_copy( &Y, &X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) != 0 );
+    TEST_ASSERT( mbedtls_mpi_cmp_int( &X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_cmp_int( &Y, input_X ) == 0 );
 
 exit:
-    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &A );
+    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void mbedtls_mpi_copy_binary( data_t *input_X, data_t *input_Y )
+{
+    mbedtls_mpi X, Y, X0;
+    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &X0 );
+
+    TEST_ASSERT( mbedtls_mpi_read_binary( &X, input_X->x, input_X->len ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_read_binary( &Y, input_Y->x, input_Y->len ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_read_binary( &X0, input_X->x, input_X->len ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
+
+    TEST_ASSERT( mbedtls_mpi_copy( &Y, &X ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
+
+exit:
+    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &X0 );
 }
 /* END_CASE */
 
@@ -686,22 +704,61 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void mbedtls_mpi_swap( int input_X, int input_Y )
+void mbedtls_mpi_swap_sint( int input_X, int input_Y )
 {
-    mbedtls_mpi X, Y, A;
-    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &A );
+    mbedtls_mpi X, Y;
+    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
 
     TEST_ASSERT( mbedtls_mpi_lset( &X, input_X ) == 0 );
     TEST_ASSERT( mbedtls_mpi_lset( &Y, input_Y ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_lset( &A, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) != 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_cmp_int( &X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_cmp_int( &Y, input_Y ) == 0 );
+
     mbedtls_mpi_swap( &X, &Y );
-    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) != 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_cmp_int( &X, input_Y ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_cmp_int( &Y, input_X ) == 0 );
 
 exit:
-    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &A );
+    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void mbedtls_mpi_swap_binary( data_t *input_X, data_t *input_Y )
+{
+    mbedtls_mpi X, Y, X0, Y0;
+    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
+    mbedtls_mpi_init( &X0 ); mbedtls_mpi_init( &Y0 );
+
+    TEST_ASSERT( mbedtls_mpi_read_binary( &X, input_X->x, input_X->len ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_read_binary( &Y, input_Y->x, input_Y->len ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_read_binary( &X0, input_X->x, input_X->len ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_read_binary( &Y0, input_Y->x, input_Y->len ) == 0 );
+
+    mbedtls_mpi_swap( &X, &Y );
+    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
+
+exit:
+    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
+    mbedtls_mpi_free( &X0 ); mbedtls_mpi_free( &Y0 );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void mpi_swap_self( data_t *input_X )
+{
+    mbedtls_mpi X, X0;
+    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &X0 );
+
+    TEST_ASSERT( mbedtls_mpi_read_binary( &X, input_X->x, input_X->len ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_read_binary( &X0, input_X->x, input_X->len ) == 0 );
+
+    mbedtls_mpi_swap( &X, &X );
+    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
+
+exit:
+    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &X0 );
 }
 /* END_CASE */
 
diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function
index 342405e..b57fe19 100644
--- a/tests/suites/test_suite_pk.function
+++ b/tests/suites/test_suite_pk.function
@@ -712,7 +712,9 @@
     TEST_ASSERT( md_info != NULL );
 
     hlen = mbedtls_md_get_size( md_info );
-    mbedtls_md( md_info, (const unsigned char *) msg, strlen( msg ), hash );
+    TEST_ASSERT( mbedtls_md( md_info,
+                             (const unsigned char *) msg, strlen( msg ),
+                             hash ) == 0 );
 
     mbedtls_ecp_set_max_ops( max_ops );
 
diff --git a/tests/suites/test_suite_pkparse.data b/tests/suites/test_suite_pkparse.data
index 4add252..cd842cf 100644
--- a/tests/suites/test_suite_pkparse.data
+++ b/tests/suites/test_suite_pkparse.data
@@ -1072,33 +1072,84 @@
 depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256K1_ENABLED:MBEDTLS_PK_PARSE_EC_EXTENDED
 pk_parse_keyfile_ec:"data_files/ec_prv.specdom.der":"NULL":0
 
-Key ASN1 (Incorrect first tag)
-pk_parse_key:"":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+Key ASN1 (No data)
+pk_parse_key:"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Key ASN1 (First tag not Sequence)
+pk_parse_key:"020100":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
 
 Key ASN1 (RSAPrivateKey, incorrect version tag)
 depends_on:MBEDTLS_RSA_C
-pk_parse_key:"300100":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+pk_parse_key:"300100":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
 
 Key ASN1 (RSAPrivateKey, version tag missing)
 depends_on:MBEDTLS_RSA_C
-pk_parse_key:"3000":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+pk_parse_key:"3000":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
 
 Key ASN1 (RSAPrivateKey, invalid version)
 depends_on:MBEDTLS_RSA_C
-pk_parse_key:"3003020101":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+pk_parse_key:"3003020101":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
 
 Key ASN1 (RSAPrivateKey, correct version, incorrect tag)
 depends_on:MBEDTLS_RSA_C
-pk_parse_key:"300402010000":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+pk_parse_key:"300402010000":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
 
-Key ASN1 (RSAPrivateKey, values present, length mismatch)
+Key ASN1 (RSAPrivateKey, correct format+values, minimal modulus size (128 bit))
 depends_on:MBEDTLS_RSA_C
-pk_parse_key:"301c02010002010102010102010102010102010102010102010102010100":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+pk_parse_key:"3063020100021100cc8ab070369ede72920e5a51523c857102030100010211009a6318982a7231de1894c54aa4909201020900f3058fd8dc484d61020900d7770dbd8b78a2110209009471f14c26428401020813425f060c4b72210208052b93d01747a87c":0
 
-Key ASN1 (RSAPrivateKey, values present, check_privkey fails)
+Key ASN1 (RSAPrivateKey, correct format, modulus too small (127 bit))
 depends_on:MBEDTLS_RSA_C
-pk_parse_key:"301b020100020102020101020101020101020101020101020101020101":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+pk_parse_key:"30630201000211007c8ab070369ede72920e5a51523c857102030100010211009a6318982a7231de1894c54aa4909201020900f3058fd8dc484d61020900d7770dbd8b78a2110209009471f14c26428401020813425f060c4b72210208052b93d01747a87c":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Key ASN1 (RSAPrivateKey, correct format, modulus even)
+depends_on:MBEDTLS_RSA_C
+pk_parse_key:"3063020100021100cc8ab070369ede72920e5a51523c857002030100010211009a6318982a7231de1894c54aa4909201020900f3058fd8dc484d61020900d7770dbd8b78a2110209009471f14c26428401020813425f060c4b72210208052b93d01747a87c":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Key ASN1 (RSAPrivateKey, correct format, d == 0)
+depends_on:MBEDTLS_RSA_C
+pk_parse_key:"30630201000211007c8ab070369ede72920e5a51523c8571020301000102110000000000000000000000000000000000020900f3058fd8dc484d61020900d7770dbd8b78a2110209009471f14c26428401020813425f060c4b72210208052b93d01747a87c":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Key ASN1 (RSAPrivateKey, correct format, d == p == q == 0)
+depends_on:MBEDTLS_RSA_C
+pk_parse_key:"3063020100021100cc8ab070369ede72920e5a51523c8571020301000102110000000000000000000000000000000000020900000000000000000002090000000000000000000209009471f14c26428401020813425f060c4b72210208052b93d01747a87c":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Key ASN1 (RSAPrivateKey, correct values, trailing garbage)
+depends_on:MBEDTLS_RSA_C
+pk_parse_key:"3064020100021100cc8ab070369ede72920e5a51523c857102030100010211009a6318982a7231de1894c54aa4909201020900f3058fd8dc484d61020900d7770dbd8b78a2110209009471f14c26428401020813425f060c4b72210208052b93d01747a87c00":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Key ASN1 (RSAPrivateKey, correct values, n wrong tag)
+depends_on:MBEDTLS_RSA_C
+pk_parse_key:"3063020100FF1100cc8ab070369ede72920e5a51523c857102030100010211009a6318982a7231de1894c54aa4909201020900f3058fd8dc484d61020900d7770dbd8b78a2110209009471f14c26428401020813425f060c4b72210208052b93d01747a87c":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Key ASN1 (RSAPrivateKey, correct values, e wrong tag)
+depends_on:MBEDTLS_RSA_C
+pk_parse_key:"3063020100021100cc8ab070369ede72920e5a51523c8571FF030100010211009a6318982a7231de1894c54aa4909201020900f3058fd8dc484d61020900d7770dbd8b78a2110209009471f14c26428401020813425f060c4b72210208052b93d01747a87c":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Key ASN1 (RSAPrivateKey, correct values, d wrong tag)
+depends_on:MBEDTLS_RSA_C
+pk_parse_key:"3063020100021100cc8ab070369ede72920e5a51523c85710203010001FF11009a6318982a7231de1894c54aa4909201020900f3058fd8dc484d61020900d7770dbd8b78a2110209009471f14c26428401020813425f060c4b72210208052b93d01747a87c":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Key ASN1 (RSAPrivateKey, correct values, p wrong tag)
+depends_on:MBEDTLS_RSA_C
+pk_parse_key:"3063020100021100cc8ab070369ede72920e5a51523c857102030100010211009a6318982a7231de1894c54aa4909201FF0900f3058fd8dc484d61020900d7770dbd8b78a2110209009471f14c26428401020813425f060c4b72210208052b93d01747a87c":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Key ASN1 (RSAPrivateKey, correct values, q wrong tag)
+depends_on:MBEDTLS_RSA_C
+pk_parse_key:"3063020100021100cc8ab070369ede72920e5a51523c857102030100010211009a6318982a7231de1894c54aa4909201020900f3058fd8dc484d61FF0900d7770dbd8b78a2110209009471f14c26428401020813425f060c4b72210208052b93d01747a87c":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Key ASN1 (RSAPrivateKey, correct values, dp wrong tag)
+depends_on:MBEDTLS_RSA_C
+pk_parse_key:"3063020100021100cc8ab070369ede72920e5a51523c857102030100010211009a6318982a7231de1894c54aa4909201020900f3058fd8dc484d61020900d7770dbd8b78a211FF09009471f14c26428401020813425f060c4b72210208052b93d01747a87c":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Key ASN1 (RSAPrivateKey, correct values, dq wrong tag)
+depends_on:MBEDTLS_RSA_C
+pk_parse_key:"3063020100021100cc8ab070369ede72920e5a51523c857102030100010211009a6318982a7231de1894c54aa4909201020900f3058fd8dc484d61020900d7770dbd8b78a2110209009471f14c26428401FF0813425f060c4b72210208052b93d01747a87c":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Key ASN1 (RSAPrivateKey, correct values, qp wrong tag)
+depends_on:MBEDTLS_RSA_C
+pk_parse_key:"3063020100021100cc8ab070369ede72920e5a51523c857102030100010211009a6318982a7231de1894c54aa4909201020900f3058fd8dc484d61020900d7770dbd8b78a2110209009471f14c26428401020813425f060c4b7221FF08052b93d01747a87c":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
 
 Key ASN1 (ECPrivateKey, empty parameters)
 depends_on:MBEDTLS_ECP_C
-pk_parse_key:"30070201010400a000":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+pk_parse_key:"30070201010400a000":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
diff --git a/tests/suites/test_suite_pkparse.function b/tests/suites/test_suite_pkparse.function
index 3eb0397..4650d33 100644
--- a/tests/suites/test_suite_pkparse.function
+++ b/tests/suites/test_suite_pkparse.function
@@ -113,23 +113,14 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE depends_on:MBEDTLS_RSA_C */
-void pk_parse_key( data_t * buf, char * result_str, int result )
+/* BEGIN_CASE */
+void pk_parse_key( data_t * buf, int result )
 {
     mbedtls_pk_context pk;
-    unsigned char output[2000];
-    ((void) result_str);
 
     mbedtls_pk_init( &pk );
 
-    memset( output, 0, 2000 );
-
-
-    TEST_ASSERT( mbedtls_pk_parse_key( &pk, buf->x, buf->len, NULL, 0 ) == ( result ) );
-    if( ( result ) == 0 )
-    {
-        TEST_ASSERT( 1 );
-    }
+    TEST_ASSERT( mbedtls_pk_parse_key( &pk, buf->x, buf->len, NULL, 0 ) == result );
 
 exit:
     mbedtls_pk_free( &pk );
diff --git a/tests/suites/test_suite_version.data b/tests/suites/test_suite_version.data
index c3189c8..f8a2918 100644
--- a/tests/suites/test_suite_version.data
+++ b/tests/suites/test_suite_version.data
@@ -1,8 +1,8 @@
 Check compiletime library version
-check_compiletime_version:"2.16.3"
+check_compiletime_version:"2.16.5"
 
 Check runtime library version
-check_runtime_version:"2.16.3"
+check_runtime_version:"2.16.5"
 
 Check for MBEDTLS_VERSION_C
 check_feature:"MBEDTLS_VERSION_C":0