Merge branch 'mbedtls-2.16-restricted' into mbedtls-2.16.10-rc
diff --git a/.gitignore b/.gitignore
index 789f57e..5fb0bde 100644
--- a/.gitignore
+++ b/.gitignore
@@ -40,4 +40,5 @@
 /GSYMS
 /GTAGS
 /TAGS
+/cscope*.out
 /tags
diff --git a/ChangeLog b/ChangeLog
index b765f6b..1ecfc8b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,138 @@
 mbed TLS ChangeLog (Sorted per branch, date)
 
+= mbed TLS 2.16.9 branch released 2020-12-11
+
+Security
+   * Limit the size of calculations performed by mbedtls_mpi_exp_mod to
+     MBEDTLS_MPI_MAX_SIZE to prevent a potential denial of service when
+     generating Diffie-Hellman key pairs. Credit to OSS-Fuzz.
+   * A failure of the random generator was ignored in mbedtls_mpi_fill_random(),
+     which is how most uses of randomization in asymmetric cryptography
+     (including key generation, intermediate value randomization and blinding)
+     are implemented. This could cause failures or the silent use of non-random
+     values. A random generator can fail if it needs reseeding and cannot not
+     obtain entropy, or due to an internal failure (which, for Mbed TLS's own
+     CTR_DRBG or HMAC_DRBG, can only happen due to a misconfiguration).
+   * Fix a compliance issue whereby we were not checking the tag on the
+     algorithm parameters (only the size) when comparing the signature in the
+     description part of the cert to the real signature. This meant that a
+     NULL algorithm parameters entry would look identical to an array of REAL
+     (size zero) to the library and thus the certificate would be considered
+     valid. However, if the parameters do not match in *any* way then the
+     certificate should be considered invalid, and indeed OpenSSL marks these
+     certs as invalid when mbedtls did not.
+     Many thanks to guidovranken who found this issue via differential fuzzing
+     and reported it in #3629.
+   * Zeroising of local buffers and variables which are used for calculations
+     in mbedtls_pkcs5_pbkdf2_hmac(), mbedtls_internal_sha*_process(),
+     mbedtls_internal_md*_process() and mbedtls_internal_ripemd160_process()
+     functions to erase sensitive data from memory. Reported by
+     Johan Malmgren and Johan Uppman Bruce from Sectra.
+
+Bugfix
+   * Fix an invalid (but nonzero) return code from mbedtls_pk_parse_subpubkey()
+     when the input has trailing garbage. Fixes #2512.
+   * Fix rsa_prepare_blinding() to retry when the blinding value is not
+     invertible (mod N), instead of returning MBEDTLS_ERR_RSA_RNG_FAILED. This
+     addresses a regression but is rare in practice (approx. 1 in 2/sqrt(N)).
+     Found by Synopsys Coverity, fix contributed by Peter Kolbus (Garmin).
+     Fixes #3647.
+   * Fix the build when the macro _GNU_SOURCE is defined to a non-empty value.
+     Fix #3432.
+   * Correct the default IV size for mbedtls_cipher_info_t structures using
+     MBEDTLS_MODE_ECB to 0, since ECB mode ciphers don't use IVs.
+   * Make arc4random_buf available on NetBSD and OpenBSD when _POSIX_C_SOURCE is
+     defined. Fix contributed in #3571. Adopted for LTS branch 2.16 in #3602.
+   * Fix build failures on GCC 11. Fixes #3782.
+   * Fix a memory leak in mbedtls_mpi_sub_abs() when the result was negative
+     (an error condition) and the second operand was aliased to the result.
+   * Fix a case in elliptic curve arithmetic where an out-of-memory condition
+     could go undetected, resulting in an incorrect result.
+   * In CTR_DRBG and HMAC_DRBG, don't reset the reseed interval in seed().
+     Fixes #2927.
+   * In PEM writing functions, fill the trailing part of the buffer with null
+     bytes. This guarantees that the corresponding parsing function can read
+     the buffer back, which was the case for mbedtls_x509write_{crt,csr}_pem
+     until this property was inadvertently broken in Mbed TLS 2.19.0.
+     Fixes #3682.
+   * Fix a build failure that occurred with the MBEDTLS_AES_SETKEY_DEC_ALT
+     option on. In this configuration key management methods that are required
+     for MBEDTLS_CIPHER_MODE_XTS were excluded from the build and made it fail.
+     Fixes #3818. Reported by John Stroebel.
+
+Changes
+   * Reduce stack usage significantly during sliding window exponentiation.
+     Reported in #3591 and fix contributed in #3592 by Daniel Otte.
+   * Remove the zeroization of a pointer variable in AES rounds. It was valid
+     but spurious and misleading since it looked like a mistaken attempt to
+     zeroize the pointed-to buffer. Reported by Antonio de la Piedra, CEA
+     Leti, France.
+
+= mbed TLS 2.16.8 branch released 2020-09-01
+
+Features
+   * Support building on e2k (Elbrus) architecture: correctly enable
+     -Wformat-signedness, and fix the code that causes signed-one-bit-field
+     and sign-compare warnings. Contributed by makise-homura (Igor Molchanov)
+     <akemi_homura@kurisa.ch>.
+
+Security
+   * When checking X.509 CRLs, a certificate was only considered as revoked if
+     its revocationDate was in the past according to the local clock if
+     available. In particular, on builds without MBEDTLS_HAVE_TIME_DATE,
+     certificates were never considered as revoked. On builds with
+     MBEDTLS_HAVE_TIME_DATE, an attacker able to control the local clock (for
+     example, an untrusted OS attacking a secure enclave) could prevent
+     revocation of certificates via CRLs. Fixed by no longer checking the
+     revocationDate field, in accordance with RFC 5280. Reported by
+     yuemonangong in #3340. Reported independently and fixed by
+     Raoul Strackx and Jethro Beekman in #3433.
+   * In (D)TLS record decryption, when using a CBC ciphersuites without the
+     Encrypt-then-Mac extension, use constant code flow memory access patterns
+     to extract and check the MAC. This is an improvement to the existing
+     countermeasure against Lucky 13 attacks. The previous countermeasure was
+     effective against network-based attackers, but less so against local
+     attackers. The new countermeasure defends against local attackers, even
+     if they have access to fine-grained measurements. In particular, this
+     fixes a local Lucky 13 cache attack found and reported by Tuba Yavuz,
+     Farhaan Fowze, Ken (Yihan) Bai, Grant Hernandez, and Kevin Butler
+     (University of Florida) and Dave Tian (Purdue University).
+   * Fix side channel in RSA private key operations and static (finite-field)
+     Diffie-Hellman. An adversary with precise enough timing and memory access
+     information (typically an untrusted operating system attacking a secure
+     enclave) could bypass an existing counter-measure (base blinding) and
+     potentially fully recover the private key.
+   * Fix a 1-byte buffer overread in mbedtls_x509_crl_parse_der().
+     Credit to OSS-Fuzz for detecting the problem and to Philippe Antoine
+     for pinpointing the problematic code.
+   * Zeroising of plaintext buffers in mbedtls_ssl_read() to erase unused
+     application data from memory. Reported in #689 by
+     Johan Uppman Bruce of Sectra.
+
+Bugfix
+   * Avoid use of statically sized stack buffers for certificate writing.
+     This previously limited the maximum size of DER encoded certificates
+     in mbedtls_x509write_crt_der() to 2Kb. Reported by soccerGB in #2631.
+   * Reduce the stack consumption of mbedtls_x509write_csr_der() which
+     previously could lead to stack overflow on constrained devices.
+     Contributed by Doru Gucea and Simon Leet in #3464.
+   * Use arc4random_buf on NetBSD instead of rand implementation with cyclical
+     lower bits. Fix contributed in #3540.
+   * Fix building library/net_sockets.c and the ssl_mail_client program on
+     NetBSD. NetBSD conditionals were added for the backport to avoid the risk
+     of breaking a platform. Original fix contributed by Nia Alarie in #3422.
+     Adapted for long-term support branch 2.16 in #3558.
+   * Fix bug in redirection of unit test outputs on platforms where stdout is
+     defined as a macro. First reported in #2311 and fix contributed in #3528.
+     Adopted for LTS branch 2.16 in #3601.
+
+Changes
+   * Update copyright notices to use Linux Foundation guidance. As a result,
+     the copyright of contributors other than Arm is now acknowledged, and the
+     years of publishing are no longer tracked in the source files. This also
+     eliminates the need for the lines declaring the files to be part of
+     MbedTLS. Fixes #3457.
+
 = mbed TLS 2.16.7 branch released 2020-07-01
 
 Security
diff --git a/ChangeLog.d/00README.md b/ChangeLog.d/00README.md
index b559e23..a2e096f 100644
--- a/ChangeLog.d/00README.md
+++ b/ChangeLog.d/00README.md
@@ -3,6 +3,29 @@
 This directory contains changelog entries that have not yet been merged
 to the changelog file ([`../ChangeLog`](../ChangeLog)).
 
+## What requires a changelog entry?
+
+Write a changelog entry if there is a user-visible change. This includes:
+
+* Bug fixes in the library or in sample programs: fixing a security hole,
+  fixing broken behavior, fixing the build in some configuration or on some
+  platform, etc.
+* New features in the library, new sample programs, or new platform support.
+* Changes in existing behavior. These should be rare. Changes in features
+  that are documented as experimental may or may not be announced, depending
+  on the extent of the change and how widely we expect the feature to be used.
+
+We generally don't include changelog entries for:
+
+* Documentation improvements.
+* Performance improvements, unless they are particularly significant.
+* Changes to parts of the code base that users don't interact with directly,
+  such as test code and test data.
+
+Until Mbed TLS 2.16.8, we required changelog entries in more cases.
+Looking at older changelog entries is good practice for how to write a
+changelog entry, but not for deciding whether to write one.
+
 ## Changelog entry file format
 
 A changelog entry file must have the extension `*.txt` and must have the
@@ -33,8 +56,7 @@
     Bugfix
     Changes
 
-Use “Changes” for anything that doesn't fit in the other categories, such as
-performance, documentation and test improvements.
+Use “Changes” for anything that doesn't fit in the other categories.
 
 ## How to write a changelog entry
 
@@ -49,8 +71,7 @@
 Mbed TLS issue. Add other external references such as CVE numbers where
 applicable.
 
-Credit the author of the contribution if the contribution is not a member of
-the Mbed TLS development team. Also credit bug reporters where applicable.
+Credit bug reporters where applicable.
 
 **Explain why, not how**. Remember that the audience is the users of the
 library, not its developers. In particular, for a bug fix, explain the
diff --git a/ChangeLog.d/bugfix_PR_2632.txt b/ChangeLog.d/bugfix_PR_2632.txt
deleted file mode 100644
index 1d54b4d..0000000
--- a/ChangeLog.d/bugfix_PR_2632.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Bugfix
-   * Avoid use of statically sized stack buffers for certificate writing.
-     This previously limited the maximum size of DER encoded certificates
-     in mbedtls_x509write_crt_der() to 2Kb. Reported by soccerGB in #2631.
diff --git a/ChangeLog.d/copyright.txt b/ChangeLog.d/copyright.txt
deleted file mode 100644
index aefc6bc..0000000
--- a/ChangeLog.d/copyright.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-Changes
-   * Update copyright notices to use Linux Foundation guidance. As a result,
-     the copyright of contributors other than Arm is now acknowledged, and the
-     years of publishing are no longer tracked in the source files. This also
-     eliminates the need for the lines declaring the files to be part of
-     MbedTLS. Fixes #3457.
diff --git a/ChangeLog.d/drbg-mutex.txt b/ChangeLog.d/drbg-mutex.txt
new file mode 100644
index 0000000..3ac5abf
--- /dev/null
+++ b/ChangeLog.d/drbg-mutex.txt
@@ -0,0 +1,5 @@
+Bugfix
+   * Fix a resource leak in CTR_DRBG and HMAC_DRBG when MBEDTLS_THREADING_C
+     is enabled, on platforms where initializing a mutex allocates resources.
+     This was a regression introduced in the previous release. Reported in
+     #4017, #4045 and #4071.
diff --git a/ChangeLog.d/e2k-support.txt b/ChangeLog.d/e2k-support.txt
deleted file mode 100644
index 023b188..0000000
--- a/ChangeLog.d/e2k-support.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Features
-   * Support building on e2k (Elbrus) architecture: correctly enable
-     -Wformat-signedness, and fix the code that causes signed-one-bit-field
-     and sign-compare warnings. Contributed by makise-homura (Igor Molchanov)
-     <akemi_homura@kurisa.ch>.
diff --git a/ChangeLog.d/fix-build-netbsd.txt b/ChangeLog.d/fix-build-netbsd.txt
deleted file mode 100644
index 000614e..0000000
--- a/ChangeLog.d/fix-build-netbsd.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Bugfix
-   * Fix building library/net_sockets.c and the ssl_mail_client program on
-     NetBSD. NetBSD conditionals were added for the backport to avoid the risk
-     of breaking a platform. Original fix contributed by Nia Alarie in #3422.
-     Adapted for long-term support branch 2.16 in #3558.
diff --git a/ChangeLog.d/issue4093.txt b/ChangeLog.d/issue4093.txt
new file mode 100644
index 0000000..b8d634b
--- /dev/null
+++ b/ChangeLog.d/issue4093.txt
@@ -0,0 +1,7 @@
+Security
+   * Fix an errorneous estimation for an internal buffer in
+     mbedtls_pk_write_key_pem(). If MBEDTLS_MPI_MAX_SIZE is set to an odd
+     value the function might fail to write a private RSA keys of the largest
+     supported size.
+     Found by Daniel Otte, reported in #4093 and fixed in #4094,
+     backported in #4100.
diff --git a/ChangeLog.d/limit_size_of_diffie_hellman_calculations.txt b/ChangeLog.d/limit_size_of_diffie_hellman_calculations.txt
deleted file mode 100644
index 2ba98d5..0000000
--- a/ChangeLog.d/limit_size_of_diffie_hellman_calculations.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Security
-   * Limit the size of calculations performed by mbedtls_mpi_exp_mod to
-     MBEDTLS_MPI_MAX_SIZE to prevent a potential denial of service when
-     generating Diffie-Hellman key pairs. Credit to OSS-Fuzz.
diff --git a/ChangeLog.d/local-lucky13.txt b/ChangeLog.d/local-lucky13.txt
deleted file mode 100644
index adf493a..0000000
--- a/ChangeLog.d/local-lucky13.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-Security
-   * In (D)TLS record decryption, when using a CBC ciphersuites without the
-     Encrypt-then-Mac extension, use constant code flow memory access patterns
-     to extract and check the MAC. This is an improvement to the existing
-     countermeasure against Lucky 13 attacks. The previous countermeasure was
-     effective against network-based attackers, but less so against local
-     attackers. The new countermeasure defends against local attackers, even
-     if they have access to fine-grained measurements. In particular, this
-     fixes a local Lucky 13 cache attack found and reported by Tuba Yavuz,
-     Farhaan Fowze, Ken (Yihan) Bai, Grant Hernandez, and Kevin Butler
-     (University of Florida) and Dave Tian (Purdue University).
diff --git a/ChangeLog.d/mpi_fill_random-rng_failure.txt b/ChangeLog.d/mpi_fill_random-rng_failure.txt
deleted file mode 100644
index 8addf18..0000000
--- a/ChangeLog.d/mpi_fill_random-rng_failure.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-Security
-   * A failure of the random generator was ignored in mbedtls_mpi_fill_random(),
-     which is how most uses of randomization in asymmetric cryptography
-     (including key generation, intermediate value randomization and blinding)
-     are implemented. This could cause failures or the silent use of non-random
-     values. A random generator can fail if it needs reseeding and cannot not
-     obtain entropy, or due to an internal failure (which, for Mbed TLS's own
-     CTR_DRBG or HMAC_DRBG, can only happen due to a misconfiguration).
diff --git a/ChangeLog.d/mpi_sub_abs.txt b/ChangeLog.d/mpi_sub_abs.txt
new file mode 100644
index 0000000..9f34ee7
--- /dev/null
+++ b/ChangeLog.d/mpi_sub_abs.txt
@@ -0,0 +1,7 @@
+Security
+   * Fix a buffer overflow in mbedtls_mpi_sub_abs() when calculating
+     |A| - |B| where |B| is larger than |A| and has more limbs (so the
+     function should return MBEDTLS_ERR_MPI_NEGATIVE_VALUE). Only
+     applications calling mbedtls_mpi_sub_abs() directly are affected:
+     all calls inside the library were safe since this function is
+     only called with |A| >= |B|. Reported by Guido Vranken in #4042.
diff --git a/ChangeLog.d/net_poll-fd_setsize.txt b/ChangeLog.d/net_poll-fd_setsize.txt
new file mode 100644
index 0000000..e4db8c7
--- /dev/null
+++ b/ChangeLog.d/net_poll-fd_setsize.txt
@@ -0,0 +1,4 @@
+Security
+   * Fix a stack buffer overflow with mbedtls_net_poll() and
+     mbedtls_net_recv_timeout() when given a file descriptor that is
+     beyond FD_SETSIZE. Reported by FigBug in #4169.
diff --git a/ChangeLog.d/netbsd-rand-arc4random_buf.txt b/ChangeLog.d/netbsd-rand-arc4random_buf.txt
deleted file mode 100644
index 8539d1f..0000000
--- a/ChangeLog.d/netbsd-rand-arc4random_buf.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Bugfix
-   * Use arc4random_buf on NetBSD instead of rand implementation with cyclical
-     lower bits. Fix contributed in #3540.
diff --git a/ChangeLog.d/protect-base-blinding.txt b/ChangeLog.d/protect-base-blinding.txt
deleted file mode 100644
index ca0600c..0000000
--- a/ChangeLog.d/protect-base-blinding.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-Security
-   * Fix side channel in RSA private key operations and static (finite-field)
-     Diffie-Hellman. An adversary with precise enough timing and memory access
-     information (typically an untrusted operating system attacking a secure
-     enclave) could bypass an existing counter-measure (base blinding) and
-     potentially fully recover the private key.
diff --git a/ChangeLog.d/rsa-mutex.txt b/ChangeLog.d/rsa-mutex.txt
new file mode 100644
index 0000000..2a477a9
--- /dev/null
+++ b/ChangeLog.d/rsa-mutex.txt
@@ -0,0 +1,13 @@
+Bugfix
+   * Ensure that calling mbedtls_rsa_free() or mbedtls_entropy_free()
+     twice is safe. This happens for RSA when some Mbed TLS library functions
+     fail. Such a double-free was not safe when MBEDTLS_THREADING_C was
+     enabled on platforms where freeing a mutex twice is not safe.
+   * Fix a resource leak in a bad-arguments case of mbedtls_rsa_gen_key()
+     when MBEDTLS_THREADING_C is enabled on platforms where initializing
+     a mutex allocates resources.
+
+Default behavior changes
+   * In mbedtls_rsa_context objects, the ver field was formerly documented
+     as always 0. It is now reserved for internal purposes and may take
+     different values.
diff --git a/ChangeLog.d/rsa_private-ret.txt b/ChangeLog.d/rsa_private-ret.txt
new file mode 100644
index 0000000..b965cea
--- /dev/null
+++ b/ChangeLog.d/rsa_private-ret.txt
@@ -0,0 +1,2 @@
+Bugfix
+   * Fix an incorrect error code if an RSA private operation glitched.
diff --git a/ChangeLog.d/stdout-macro.txt b/ChangeLog.d/stdout-macro.txt
deleted file mode 100644
index e77b0ad..0000000
--- a/ChangeLog.d/stdout-macro.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Bugfix
-   * Fix bug in redirection of unit test outputs on platforms where stdout is
-     defined as a macro. First reported in #2311 and fix contributed in #3528.
-     Adopted for LTS branch 2.16 in #3601.
diff --git a/ChangeLog.d/x509-add-tag-check-to-algorithm-params b/ChangeLog.d/x509-add-tag-check-to-algorithm-params
deleted file mode 100644
index f2c72b0..0000000
--- a/ChangeLog.d/x509-add-tag-check-to-algorithm-params
+++ /dev/null
@@ -1,11 +0,0 @@
-Security
-   * Fix a compliance issue whereby we were not checking the tag on the
-     algorithm parameters (only the size) when comparing the signature in the
-     description part of the cert to the real signature. This meant that a
-     NULL algorithm parameters entry would look identical to an array of REAL
-     (size zero) to the library and thus the certificate would be considered
-     valid. However, if the parameters do not match in *any* way then the
-     certificate should be considered invalid, and indeed OpenSSL marks these
-     certs as invalid when mbedtls did not.
-     Many thanks to guidovranken who found this issue via differential fuzzing
-     and reported it in #3629.
diff --git a/ChangeLog.d/x509parse_crl-empty_entry.txt b/ChangeLog.d/x509parse_crl-empty_entry.txt
deleted file mode 100644
index 483abb1..0000000
--- a/ChangeLog.d/x509parse_crl-empty_entry.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Security
-   * Fix a 1-byte buffer overread in mbedtls_x509_crl_parse_der().
-     Credit to OSS-Fuzz for detecting the problem and to Philippe Antoine
-     for pinpointing the problematic code.
diff --git a/ChangeLog.d/x509write_csr_heap_alloc.txt b/ChangeLog.d/x509write_csr_heap_alloc.txt
deleted file mode 100644
index 6223698..0000000
--- a/ChangeLog.d/x509write_csr_heap_alloc.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Bugfix
-   * Reduce the stack consumption of mbedtls_x509write_csr_der() which
-     previously could lead to stack overflow on constrained devices.
-     Contributed by Doru Gucea and Simon Leet in #3464.
diff --git a/ChangeLog.d/zeroising_of_plaintext_buffer.txt b/ChangeLog.d/zeroising_of_plaintext_buffer.txt
deleted file mode 100644
index f618beb..0000000
--- a/ChangeLog.d/zeroising_of_plaintext_buffer.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Security
-   * Zeroising of plaintext buffers in mbedtls_ssl_read() to erase unused
-     application data from memory. Reported in #689 by
-     Johan Uppman Bruce of Sectra.
diff --git a/ChangeLog.d/zeroizations_of_sensitive_data_in_PKCS5_and_SHA.txt b/ChangeLog.d/zeroizations_of_sensitive_data_in_PKCS5_and_SHA.txt
deleted file mode 100644
index 320bb0e..0000000
--- a/ChangeLog.d/zeroizations_of_sensitive_data_in_PKCS5_and_SHA.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-Security
-   * Zeroising of local buffers and variables which are used for calculations
-     in mbedtls_pkcs5_pbkdf2_hmac(), mbedtls_internal_sha*_process(),
-     mbedtls_internal_md*_process() and mbedtls_internal_ripemd160_process()
-     functions to erase sensitive data from memory. Reported by
-     Johan Malmgren and Johan Uppman Bruce from Sectra.
diff --git a/Makefile b/Makefile
index 24d529a..3942fbd 100644
--- a/Makefile
+++ b/Makefile
@@ -129,5 +129,10 @@
 	$(CTAGS) $@ $(C_SOURCE_FILES)
 TAGS: $(C_SOURCE_FILES)
 	etags -o $@ $(C_SOURCE_FILES)
+global: GPATH GRTAGS GSYMS GTAGS
 GPATH GRTAGS GSYMS GTAGS: $(C_SOURCE_FILES)
 	ls $(C_SOURCE_FILES) | gtags -f - --gtagsconf .globalrc
+cscope: cscope.in.out cscope.po.out cscope.out
+cscope.in.out cscope.po.out cscope.out: $(C_SOURCE_FILES)
+	cscope -bq -u -Iinclude -Ilibrary $(patsubst %,-I%,$(wildcard 3rdparty/*/include)) -Itests/include $(C_SOURCE_FILES)
+.PHONY: cscope global
diff --git a/doxygen/input/doc_mainpage.h b/doxygen/input/doc_mainpage.h
index 3faf41a..4fe1613 100644
--- a/doxygen/input/doc_mainpage.h
+++ b/doxygen/input/doc_mainpage.h
@@ -49,7 +49,7 @@
  */
 
 /**
- * @mainpage mbed TLS v2.16.7 source code documentation
+ * @mainpage mbed TLS v2.16.9 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 642c630..9197a4a 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.7"
+PROJECT_NAME           = "mbed TLS v2.16.9"
 
 # 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/bignum.h b/include/mbedtls/bignum.h
index 4bb9fa3..4d04b33 100644
--- a/include/mbedtls/bignum.h
+++ b/include/mbedtls/bignum.h
@@ -88,12 +88,12 @@
  * Maximum window size used for modular exponentiation. Default: 6
  * Minimum value: 1. Maximum value: 6.
  *
- * Result is an array of ( 2 << MBEDTLS_MPI_WINDOW_SIZE ) MPIs used
+ * Result is an array of ( 2 ** MBEDTLS_MPI_WINDOW_SIZE ) MPIs used
  * for the sliding window calculation. (So 64 by default)
  *
  * Reduction in size, reduces speed.
  */
-#define MBEDTLS_MPI_WINDOW_SIZE                           6        /**< Maximum windows size used. */
+#define MBEDTLS_MPI_WINDOW_SIZE                           6        /**< Maximum window size used. */
 #endif /* !MBEDTLS_MPI_WINDOW_SIZE */
 
 #if !defined(MBEDTLS_MPI_MAX_SIZE)
diff --git a/include/mbedtls/ccm.h b/include/mbedtls/ccm.h
index 3dcdc91..d50c6ec 100644
--- a/include/mbedtls/ccm.h
+++ b/include/mbedtls/ccm.h
@@ -175,7 +175,7 @@
  *                  than zero, \p output must be a writable buffer of at least
  *                  that length.
  * \param tag       The buffer holding the authentication field. This must be a
- *                  readable buffer of at least \p tag_len Bytes.
+ *                  writable buffer of at least \p tag_len Bytes.
  * \param tag_len   The length of the authentication field to generate in Bytes:
  *                  4, 6, 8, 10, 12, 14 or 16.
  *
@@ -220,7 +220,7 @@
  *                  than zero, \p output must be a writable buffer of at least
  *                  that length.
  * \param tag       The buffer holding the authentication field. This must be a
- *                  readable buffer of at least \p tag_len Bytes.
+ *                  writable buffer of at least \p tag_len Bytes.
  * \param tag_len   The length of the authentication field to generate in Bytes:
  *                  0, 4, 6, 8, 10, 12, 14 or 16.
  *
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index 90a9aaa..fff4240 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -1747,6 +1747,23 @@
 //#define MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT
 
 /**
+ * \def MBEDTLS_TEST_HOOKS
+ *
+ * Enable features for invasive testing such as introspection functions and
+ * hooks for fault injection. This enables additional unit tests.
+ *
+ * Merely enabling this feature should not change the behavior of the product.
+ * It only adds new code, and new branching points where the default behavior
+ * is the same as when this feature is disabled.
+ * However, this feature increases the attack surface: there is an added
+ * risk of vulnerabilities, and more gadgets that can make exploits easier.
+ * Therefore this feature must never be enabled in production.
+ *
+ * Uncomment to enable invasive tests.
+ */
+//#define MBEDTLS_TEST_HOOKS
+
+/**
  * \def MBEDTLS_THREADING_ALT
  *
  * Provide your own alternate threading implementation.
@@ -3126,7 +3143,7 @@
  */
 
 /* MPI / BIGNUM options */
-//#define MBEDTLS_MPI_WINDOW_SIZE            6 /**< Maximum windows size used. */
+//#define MBEDTLS_MPI_WINDOW_SIZE            6 /**< Maximum window size used. */
 //#define MBEDTLS_MPI_MAX_SIZE            1024 /**< Maximum number of bytes for usable MPIs. */
 
 /* CTR_DRBG options */
diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h
index 7e5f2e5..6c099ad 100644
--- a/include/mbedtls/ctr_drbg.h
+++ b/include/mbedtls/ctr_drbg.h
@@ -214,6 +214,13 @@
     void *p_entropy;            /*!< The context for the entropy function. */
 
 #if defined(MBEDTLS_THREADING_C)
+    /* Invariant: the mutex is initialized if and only if f_entropy != NULL.
+     * This means that the mutex is initialized during the initial seeding
+     * in mbedtls_ctr_drbg_seed() and freed in mbedtls_ctr_drbg_free().
+     *
+     * Note that this invariant may change without notice. Do not rely on it
+     * and do not access the mutex directly in application code.
+     */
     mbedtls_threading_mutex_t mutex;
 #endif
 }
@@ -224,6 +231,11 @@
  *                      and prepares it for mbedtls_ctr_drbg_seed()
  *                      or mbedtls_ctr_drbg_free().
  *
+ * \note                The reseed interval is
+ *                      #MBEDTLS_CTR_DRBG_RESEED_INTERVAL by default.
+ *                      You can override it by calling
+ *                      mbedtls_ctr_drbg_set_reseed_interval().
+ *
  * \param ctx           The CTR_DRBG context to initialize.
  */
 void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx );
@@ -272,6 +284,15 @@
  *                      device.
  */
 #endif
+#if defined(MBEDTLS_THREADING_C)
+/**
+ * \note                When Mbed TLS is built with threading support,
+ *                      after this function returns successfully,
+ *                      it is safe to call mbedtls_ctr_drbg_random()
+ *                      from multiple threads. Other operations, including
+ *                      reseeding, are not thread-safe.
+ */
+#endif /* MBEDTLS_THREADING_C */
 /**
  * \param ctx           The CTR_DRBG context to seed.
  *                      It must have been initialized with
@@ -281,6 +302,8 @@
  *                      the same context unless you call
  *                      mbedtls_ctr_drbg_free() and mbedtls_ctr_drbg_init()
  *                      again first.
+ *                      After a failed call to mbedtls_ctr_drbg_seed(),
+ *                      you must call mbedtls_ctr_drbg_free().
  * \param f_entropy     The entropy callback, taking as arguments the
  *                      \p p_entropy context, the buffer to fill, and the
  *                      length of the buffer.
@@ -305,7 +328,8 @@
                    size_t len );
 
 /**
- * \brief               This function clears CTR_CRBG context data.
+ * \brief               This function resets CTR_DRBG context to the state immediately
+ *                      after initial call of mbedtls_ctr_drbg_init().
  *
  * \param ctx           The CTR_DRBG context to clear.
  */
@@ -371,6 +395,11 @@
  * \brief               This function reseeds the CTR_DRBG context, that is
  *                      extracts data from the entropy source.
  *
+ * \note                This function is not thread-safe. It is not safe
+ *                      to call this function if another thread might be
+ *                      concurrently obtaining random numbers from the same
+ *                      context or updating or reseeding the same context.
+ *
  * \param ctx           The CTR_DRBG context.
  * \param additional    Additional data to add to the state. Can be \c NULL.
  * \param len           The length of the additional data.
@@ -388,6 +417,11 @@
 /**
  * \brief              This function updates the state of the CTR_DRBG context.
  *
+ * \note               This function is not thread-safe. It is not safe
+ *                     to call this function if another thread might be
+ *                     concurrently obtaining random numbers from the same
+ *                     context or updating or reseeding the same context.
+ *
  * \param ctx          The CTR_DRBG context.
  * \param additional   The data to update the state with. This must not be
  *                     \c NULL unless \p add_len is \c 0.
@@ -411,6 +445,11 @@
  * This function automatically reseeds if the reseed counter is exceeded
  * or prediction resistance is enabled.
  *
+ * \note                This function is not thread-safe. It is not safe
+ *                      to call this function if another thread might be
+ *                      concurrently obtaining random numbers from the same
+ *                      context or updating or reseeding the same context.
+ *
  * \param p_rng         The CTR_DRBG context. This must be a pointer to a
  *                      #mbedtls_ctr_drbg_context structure.
  * \param output        The buffer to fill.
@@ -439,8 +478,16 @@
  *
  * This function automatically reseeds if the reseed counter is exceeded
  * or prediction resistance is enabled.
- *
- *
+ */
+#if defined(MBEDTLS_THREADING_C)
+/**
+ * \note                When Mbed TLS is built with threading support,
+ *                      it is safe to call mbedtls_ctr_drbg_random()
+ *                      from multiple threads. Other operations, including
+ *                      reseeding, are not thread-safe.
+ */
+#endif /* MBEDTLS_THREADING_C */
+/**
  * \param p_rng         The CTR_DRBG context. This must be a pointer to a
  *                      #mbedtls_ctr_drbg_context structure.
  * \param output        The buffer to fill.
diff --git a/include/mbedtls/entropy.h b/include/mbedtls/entropy.h
index 1e1d3f5..1d6e9b8 100644
--- a/include/mbedtls/entropy.h
+++ b/include/mbedtls/entropy.h
@@ -147,13 +147,15 @@
  */
 typedef struct mbedtls_entropy_context
 {
-    int accumulator_started;
+    int accumulator_started; /* 0 after init.
+                              * 1 after the first update.
+                              * -1 after free. */
 #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
     mbedtls_sha512_context  accumulator;
 #else
     mbedtls_sha256_context  accumulator;
 #endif
-    int             source_count;
+    int             source_count; /* Number of entries used in source. */
     mbedtls_entropy_source_state    source[MBEDTLS_ENTROPY_MAX_SOURCES];
 #if defined(MBEDTLS_HAVEGE_C)
     mbedtls_havege_state    havege_data;
diff --git a/include/mbedtls/gcm.h b/include/mbedtls/gcm.h
index 4e4434e..1201fbd 100644
--- a/include/mbedtls/gcm.h
+++ b/include/mbedtls/gcm.h
@@ -182,7 +182,7 @@
  *                  than zero, this must be a writable buffer of at least that
  *                  size in Bytes.
  * \param tag_len   The length of the tag to generate.
- * \param tag       The buffer for holding the tag. This must be a readable
+ * \param tag       The buffer for holding the tag. This must be a writable
  *                  buffer of at least \p tag_len Bytes.
  *
  * \return          \c 0 if the encryption or decryption was performed
@@ -310,7 +310,7 @@
  *                  tag. The tag can have a maximum length of 16 Bytes.
  *
  * \param ctx       The GCM context. This must be initialized.
- * \param tag       The buffer for holding the tag. This must be a readable
+ * \param tag       The buffer for holding the tag. This must be a writable
  *                  buffer of at least \p tag_len Bytes.
  * \param tag_len   The length of the tag to generate. This must be at least
  *                  four.
diff --git a/include/mbedtls/hmac_drbg.h b/include/mbedtls/hmac_drbg.h
index 6883678..5718e18 100644
--- a/include/mbedtls/hmac_drbg.h
+++ b/include/mbedtls/hmac_drbg.h
@@ -128,6 +128,14 @@
     void *p_entropy;            /*!< context for the entropy function        */
 
 #if defined(MBEDTLS_THREADING_C)
+    /* Invariant: the mutex is initialized if and only if
+     * md_ctx->md_info != NULL. This means that the mutex is initialized
+     * during the initial seeding in mbedtls_hmac_drbg_seed() or
+     * mbedtls_hmac_drbg_seed_buf() and freed in mbedtls_ctr_drbg_free().
+     *
+     * Note that this invariant may change without notice. Do not rely on it
+     * and do not access the mutex directly in application code.
+     */
     mbedtls_threading_mutex_t mutex;
 #endif
 } mbedtls_hmac_drbg_context;
@@ -138,6 +146,10 @@
  * This function makes the context ready for mbedtls_hmac_drbg_seed(),
  * mbedtls_hmac_drbg_seed_buf() or mbedtls_hmac_drbg_free().
  *
+ * \note                The reseed interval is #MBEDTLS_HMAC_DRBG_RESEED_INTERVAL
+ *                      by default. Override this value by calling
+ *                      mbedtls_hmac_drbg_set_reseed_interval().
+ *
  * \param ctx           HMAC_DRBG context to be initialized.
  */
 void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx );
@@ -173,7 +185,17 @@
  * \note                During the initial seeding, this function calls
  *                      the entropy source to obtain a nonce
  *                      whose length is half the entropy length.
- *
+ */
+#if defined(MBEDTLS_THREADING_C)
+/**
+ * \note                When Mbed TLS is built with threading support,
+ *                      after this function returns successfully,
+ *                      it is safe to call mbedtls_hmac_drbg_random()
+ *                      from multiple threads. Other operations, including
+ *                      reseeding, are not thread-safe.
+ */
+#endif /* MBEDTLS_THREADING_C */
+/**
  * \param ctx           HMAC_DRBG context to be seeded.
  * \param md_info       MD algorithm to use for HMAC_DRBG.
  * \param f_entropy     The entropy callback, taking as arguments the
@@ -212,7 +234,17 @@
  *
  * This function is meant for use in algorithms that need a pseudorandom
  * input such as deterministic ECDSA.
- *
+ */
+#if defined(MBEDTLS_THREADING_C)
+/**
+ * \note                When Mbed TLS is built with threading support,
+ *                      after this function returns successfully,
+ *                      it is safe to call mbedtls_hmac_drbg_random()
+ *                      from multiple threads. Other operations, including
+ *                      reseeding, are not thread-safe.
+ */
+#endif /* MBEDTLS_THREADING_C */
+/**
  * \param ctx           HMAC_DRBG context to be initialised.
  * \param md_info       MD algorithm to use for HMAC_DRBG.
  * \param data          Concatenation of the initial entropy string and
@@ -275,6 +307,11 @@
 /**
  * \brief               This function updates the state of the HMAC_DRBG context.
  *
+ * \note                This function is not thread-safe. It is not safe
+ *                      to call this function if another thread might be
+ *                      concurrently obtaining random numbers from the same
+ *                      context or updating or reseeding the same context.
+ *
  * \param ctx           The HMAC_DRBG context.
  * \param additional    The data to update the state with.
  *                      If this is \c NULL, there is no additional data.
@@ -291,6 +328,11 @@
  * \brief               This function reseeds the HMAC_DRBG context, that is
  *                      extracts data from the entropy source.
  *
+ * \note                This function is not thread-safe. It is not safe
+ *                      to call this function if another thread might be
+ *                      concurrently obtaining random numbers from the same
+ *                      context or updating or reseeding the same context.
+ *
  * \param ctx           The HMAC_DRBG context.
  * \param additional    Additional data to add to the state.
  *                      If this is \c NULL, there is no additional data
@@ -316,6 +358,11 @@
  * This function automatically reseeds if the reseed counter is exceeded
  * or prediction resistance is enabled.
  *
+ * \note                This function is not thread-safe. It is not safe
+ *                      to call this function if another thread might be
+ *                      concurrently obtaining random numbers from the same
+ *                      context or updating or reseeding the same context.
+ *
  * \param p_rng         The HMAC_DRBG context. This must be a pointer to a
  *                      #mbedtls_hmac_drbg_context structure.
  * \param output        The buffer to fill.
@@ -345,7 +392,16 @@
  *
  * This function automatically reseeds if the reseed counter is exceeded
  * or prediction resistance is enabled.
- *
+ */
+#if defined(MBEDTLS_THREADING_C)
+/**
+ * \note                When Mbed TLS is built with threading support,
+ *                      it is safe to call mbedtls_ctr_drbg_random()
+ *                      from multiple threads. Other operations, including
+ *                      reseeding, are not thread-safe.
+ */
+#endif /* MBEDTLS_THREADING_C */
+/**
  * \param p_rng         The HMAC_DRBG context. This must be a pointer to a
  *                      #mbedtls_hmac_drbg_context structure.
  * \param output        The buffer to fill.
@@ -361,7 +417,8 @@
 int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len );
 
 /**
- * \brief               Free an HMAC_DRBG context
+ * \brief               This function resets HMAC_DRBG context to the state immediately
+ *                      after initial call of mbedtls_hmac_drbg_init().
  *
  * \param ctx           The HMAC_DRBG context to free.
  */
diff --git a/include/mbedtls/net_sockets.h b/include/mbedtls/net_sockets.h
index 00fea7d..c6e1a02 100644
--- a/include/mbedtls/net_sockets.h
+++ b/include/mbedtls/net_sockets.h
@@ -151,6 +151,7 @@
  *
  * \return         0 if successful, or one of:
  *                      MBEDTLS_ERR_NET_SOCKET_FAILED,
+ *                      MBEDTLS_ERR_NET_UNKNOWN_HOST,
  *                      MBEDTLS_ERR_NET_BIND_FAILED,
  *                      MBEDTLS_ERR_NET_LISTEN_FAILED
  *
@@ -170,6 +171,8 @@
  *                  can be NULL if client_ip is null
  *
  * \return          0 if successful, or
+ *                  MBEDTLS_ERR_NET_SOCKET_FAILED,
+ *                  MBEDTLS_ERR_NET_BIND_FAILED,
  *                  MBEDTLS_ERR_NET_ACCEPT_FAILED, or
  *                  MBEDTLS_ERR_NET_BUFFER_TOO_SMALL if buf_size is too small,
  *                  MBEDTLS_ERR_SSL_WANT_READ if bind_fd was set to
@@ -182,6 +185,10 @@
 /**
  * \brief          Check and wait for the context to be ready for read/write
  *
+ * \note           The current implementation of this function uses
+ *                 select() and returns an error if the file descriptor
+ *                 is \c FD_SETSIZE or greater.
+ *
  * \param ctx      Socket to check
  * \param rw       Bitflag composed of MBEDTLS_NET_POLL_READ and
  *                 MBEDTLS_NET_POLL_WRITE specifying the events
@@ -263,16 +270,21 @@
  *                 'timeout' seconds. If no error occurs, the actual amount
  *                 read is returned.
  *
+ * \note           The current implementation of this function uses
+ *                 select() and returns an error if the file descriptor
+ *                 is \c FD_SETSIZE or greater.
+ *
  * \param ctx      Socket
  * \param buf      The buffer to write to
  * \param len      Maximum length of the buffer
  * \param timeout  Maximum number of milliseconds to wait for data
  *                 0 means no timeout (wait forever)
  *
- * \return         the number of bytes received,
- *                 or a non-zero error code:
- *                 MBEDTLS_ERR_SSL_TIMEOUT if the operation timed out,
+ * \return         The number of bytes received if successful.
+ *                 MBEDTLS_ERR_SSL_TIMEOUT if the operation timed out.
  *                 MBEDTLS_ERR_SSL_WANT_READ if interrupted by a signal.
+ *                 Another negative error code (MBEDTLS_ERR_NET_xxx)
+ *                 for other failures.
  *
  * \note           This function will block (until data becomes available or
  *                 timeout is reached) even if the socket is set to
diff --git a/include/mbedtls/rsa.h b/include/mbedtls/rsa.h
index 188c37c..b2f6533 100644
--- a/include/mbedtls/rsa.h
+++ b/include/mbedtls/rsa.h
@@ -124,7 +124,10 @@
  */
 typedef struct mbedtls_rsa_context
 {
-    int ver;                    /*!<  Always 0.*/
+    int ver;                    /*!<  Reserved for internal purposes.
+                                 *    Do not set this field in application
+                                 *    code. Its meaning might change without
+                                 *    notice. */
     size_t len;                 /*!<  The size of \p N in Bytes. */
 
     mbedtls_mpi N;              /*!<  The public modulus. */
@@ -154,6 +157,7 @@
                                      mask generating function used in the
                                      EME-OAEP and EMSA-PSS encodings. */
 #if defined(MBEDTLS_THREADING_C)
+    /* Invariant: the mutex is initialized iff ver != 0. */
     mbedtls_threading_mutex_t mutex;    /*!<  Thread-safety mutex. */
 #endif
 }
diff --git a/include/mbedtls/sha512.h b/include/mbedtls/sha512.h
index 9ff78ec..5e5a15e 100644
--- a/include/mbedtls/sha512.h
+++ b/include/mbedtls/sha512.h
@@ -152,8 +152,7 @@
 
 /**
  * \brief          This function finishes the SHA-512 operation, and writes
- *                 the result to the output buffer. This function is for
- *                 internal use only.
+ *                 the result to the output buffer.
  *
  * \param ctx      The SHA-512 context. This must be initialized
  *                 and have a hash operation started.
@@ -169,6 +168,7 @@
 /**
  * \brief          This function processes a single data block within
  *                 the ongoing SHA-512 computation.
+ *                 This function is for internal use only.
  *
  * \param ctx      The SHA-512 context. This must be initialized.
  * \param data     The buffer holding one block of data. This
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index d3ee3c4..fe33ac8 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -1409,7 +1409,7 @@
  * \note           For DTLS, you need to provide either a non-NULL
  *                 f_recv_timeout callback, or a f_recv that doesn't block.
  *
- * \note           See the documentations of \c mbedtls_ssl_sent_t,
+ * \note           See the documentations of \c mbedtls_ssl_send_t,
  *                 \c mbedtls_ssl_recv_t and \c mbedtls_ssl_recv_timeout_t for
  *                 the conventions those callbacks must follow.
  *
diff --git a/include/mbedtls/threading.h b/include/mbedtls/threading.h
index a8183a6..45161ce 100644
--- a/include/mbedtls/threading.h
+++ b/include/mbedtls/threading.h
@@ -73,6 +73,9 @@
 typedef struct mbedtls_threading_mutex_t
 {
     pthread_mutex_t mutex;
+    /* is_valid is 0 after a failed init or a free, and nonzero after a
+     * successful init. This field is not considered part of the public
+     * API of Mbed TLS and may change without notice. */
     char is_valid;
 } mbedtls_threading_mutex_t;
 #endif
diff --git a/include/mbedtls/version.h b/include/mbedtls/version.h
index a5725cc..5f0a8f1 100644
--- a/include/mbedtls/version.h
+++ b/include/mbedtls/version.h
@@ -65,16 +65,16 @@
  */
 #define MBEDTLS_VERSION_MAJOR  2
 #define MBEDTLS_VERSION_MINOR  16
-#define MBEDTLS_VERSION_PATCH  7
+#define MBEDTLS_VERSION_PATCH  9
 
 /**
  * The single version number has the following structure:
  *    MMNNPP00
  *    Major version | Minor version | Patch version
  */
-#define MBEDTLS_VERSION_NUMBER         0x02100700
-#define MBEDTLS_VERSION_STRING         "2.16.7"
-#define MBEDTLS_VERSION_STRING_FULL    "mbed TLS 2.16.7"
+#define MBEDTLS_VERSION_NUMBER         0x02100900
+#define MBEDTLS_VERSION_STRING         "2.16.9"
+#define MBEDTLS_VERSION_STRING_FULL    "mbed TLS 2.16.9"
 
 #if defined(MBEDTLS_VERSION_C)
 
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index fb4acd9..8002cdb 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.7 SOVERSION 3)
+    set_target_properties(mbedcrypto PROPERTIES VERSION 2.16.9 SOVERSION 3)
     target_link_libraries(mbedcrypto ${libs})
 
     add_library(mbedx509 SHARED ${src_x509})
-    set_target_properties(mbedx509 PROPERTIES VERSION 2.16.7 SOVERSION 0)
+    set_target_properties(mbedx509 PROPERTIES VERSION 2.16.9 SOVERSION 0)
     target_link_libraries(mbedx509 ${libs} mbedcrypto)
 
     add_library(mbedtls SHARED ${src_tls})
-    set_target_properties(mbedtls PROPERTIES VERSION 2.16.7 SOVERSION 12)
+    set_target_properties(mbedtls PROPERTIES VERSION 2.16.9 SOVERSION 12)
     target_link_libraries(mbedtls ${libs} mbedx509)
 
     install(TARGETS mbedtls mbedx509 mbedcrypto
diff --git a/library/aes.c b/library/aes.c
index 9b33750..da0e5b6 100644
--- a/library/aes.c
+++ b/library/aes.c
@@ -760,6 +760,7 @@
 
     return( ret );
 }
+#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
 
 #if defined(MBEDTLS_CIPHER_MODE_XTS)
 static int mbedtls_aes_xts_decode_keys( const unsigned char *key,
@@ -838,8 +839,6 @@
 }
 #endif /* MBEDTLS_CIPHER_MODE_XTS */
 
-#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
-
 #define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3)                     \
     do                                                          \
     {                                                           \
@@ -897,63 +896,56 @@
                                   unsigned char output[16] )
 {
     int i;
-    uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
+    uint32_t *RK = ctx->rk;
+    struct
+    {
+        uint32_t X[4];
+        uint32_t Y[4];
+    } t;
 
-    RK = ctx->rk;
-
-    GET_UINT32_LE( X0, input,  0 ); X0 ^= *RK++;
-    GET_UINT32_LE( X1, input,  4 ); X1 ^= *RK++;
-    GET_UINT32_LE( X2, input,  8 ); X2 ^= *RK++;
-    GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++;
+    GET_UINT32_LE( t.X[0], input,  0 ); t.X[0] ^= *RK++;
+    GET_UINT32_LE( t.X[1], input,  4 ); t.X[1] ^= *RK++;
+    GET_UINT32_LE( t.X[2], input,  8 ); t.X[2] ^= *RK++;
+    GET_UINT32_LE( t.X[3], input, 12 ); t.X[3] ^= *RK++;
 
     for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
     {
-        AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
-        AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
+        AES_FROUND( t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3] );
+        AES_FROUND( t.X[0], t.X[1], t.X[2], t.X[3], t.Y[0], t.Y[1], t.Y[2], t.Y[3] );
     }
 
-    AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
+    AES_FROUND( t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3] );
 
-    X0 = *RK++ ^ \
-            ( (uint32_t) FSb[ ( Y0       ) & 0xFF ]       ) ^
-            ( (uint32_t) FSb[ ( Y1 >>  8 ) & 0xFF ] <<  8 ) ^
-            ( (uint32_t) FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
-            ( (uint32_t) FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
+    t.X[0] = *RK++ ^ \
+            ( (uint32_t) FSb[ ( t.Y[0]       ) & 0xFF ]       ) ^
+            ( (uint32_t) FSb[ ( t.Y[1] >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) FSb[ ( t.Y[2] >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) FSb[ ( t.Y[3] >> 24 ) & 0xFF ] << 24 );
 
-    X1 = *RK++ ^ \
-            ( (uint32_t) FSb[ ( Y1       ) & 0xFF ]       ) ^
-            ( (uint32_t) FSb[ ( Y2 >>  8 ) & 0xFF ] <<  8 ) ^
-            ( (uint32_t) FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
-            ( (uint32_t) FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
+    t.X[1] = *RK++ ^ \
+            ( (uint32_t) FSb[ ( t.Y[1]       ) & 0xFF ]       ) ^
+            ( (uint32_t) FSb[ ( t.Y[2] >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) FSb[ ( t.Y[3] >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) FSb[ ( t.Y[0] >> 24 ) & 0xFF ] << 24 );
 
-    X2 = *RK++ ^ \
-            ( (uint32_t) FSb[ ( Y2       ) & 0xFF ]       ) ^
-            ( (uint32_t) FSb[ ( Y3 >>  8 ) & 0xFF ] <<  8 ) ^
-            ( (uint32_t) FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
-            ( (uint32_t) FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
+    t.X[2] = *RK++ ^ \
+            ( (uint32_t) FSb[ ( t.Y[2]       ) & 0xFF ]       ) ^
+            ( (uint32_t) FSb[ ( t.Y[3] >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) FSb[ ( t.Y[0] >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) FSb[ ( t.Y[1] >> 24 ) & 0xFF ] << 24 );
 
-    X3 = *RK++ ^ \
-            ( (uint32_t) FSb[ ( Y3       ) & 0xFF ]       ) ^
-            ( (uint32_t) FSb[ ( Y0 >>  8 ) & 0xFF ] <<  8 ) ^
-            ( (uint32_t) FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
-            ( (uint32_t) FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
+    t.X[3] = *RK++ ^ \
+            ( (uint32_t) FSb[ ( t.Y[3]       ) & 0xFF ]       ) ^
+            ( (uint32_t) FSb[ ( t.Y[0] >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) FSb[ ( t.Y[1] >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) FSb[ ( t.Y[2] >> 24 ) & 0xFF ] << 24 );
 
-    PUT_UINT32_LE( X0, output,  0 );
-    PUT_UINT32_LE( X1, output,  4 );
-    PUT_UINT32_LE( X2, output,  8 );
-    PUT_UINT32_LE( X3, output, 12 );
+    PUT_UINT32_LE( t.X[0], output,  0 );
+    PUT_UINT32_LE( t.X[1], output,  4 );
+    PUT_UINT32_LE( t.X[2], output,  8 );
+    PUT_UINT32_LE( t.X[3], output, 12 );
 
-    mbedtls_platform_zeroize( &X0, sizeof( X0 ) );
-    mbedtls_platform_zeroize( &X1, sizeof( X1 ) );
-    mbedtls_platform_zeroize( &X2, sizeof( X2 ) );
-    mbedtls_platform_zeroize( &X3, sizeof( X3 ) );
-
-    mbedtls_platform_zeroize( &Y0, sizeof( Y0 ) );
-    mbedtls_platform_zeroize( &Y1, sizeof( Y1 ) );
-    mbedtls_platform_zeroize( &Y2, sizeof( Y2 ) );
-    mbedtls_platform_zeroize( &Y3, sizeof( Y3 ) );
-
-    mbedtls_platform_zeroize( &RK, sizeof( RK ) );
+    mbedtls_platform_zeroize( &t, sizeof( t ) );
 
     return( 0 );
 }
@@ -977,63 +969,56 @@
                                   unsigned char output[16] )
 {
     int i;
-    uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
+    uint32_t *RK = ctx->rk;
+    struct
+    {
+        uint32_t X[4];
+        uint32_t Y[4];
+    } t;
 
-    RK = ctx->rk;
-
-    GET_UINT32_LE( X0, input,  0 ); X0 ^= *RK++;
-    GET_UINT32_LE( X1, input,  4 ); X1 ^= *RK++;
-    GET_UINT32_LE( X2, input,  8 ); X2 ^= *RK++;
-    GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++;
+    GET_UINT32_LE( t.X[0], input,  0 ); t.X[0] ^= *RK++;
+    GET_UINT32_LE( t.X[1], input,  4 ); t.X[1] ^= *RK++;
+    GET_UINT32_LE( t.X[2], input,  8 ); t.X[2] ^= *RK++;
+    GET_UINT32_LE( t.X[3], input, 12 ); t.X[3] ^= *RK++;
 
     for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
     {
-        AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
-        AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
+        AES_RROUND( t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3] );
+        AES_RROUND( t.X[0], t.X[1], t.X[2], t.X[3], t.Y[0], t.Y[1], t.Y[2], t.Y[3] );
     }
 
-    AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
+    AES_RROUND( t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3] );
 
-    X0 = *RK++ ^ \
-            ( (uint32_t) RSb[ ( Y0       ) & 0xFF ]       ) ^
-            ( (uint32_t) RSb[ ( Y3 >>  8 ) & 0xFF ] <<  8 ) ^
-            ( (uint32_t) RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
-            ( (uint32_t) RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
+    t.X[0] = *RK++ ^ \
+            ( (uint32_t) RSb[ ( t.Y[0]       ) & 0xFF ]       ) ^
+            ( (uint32_t) RSb[ ( t.Y[3] >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) RSb[ ( t.Y[2] >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) RSb[ ( t.Y[1] >> 24 ) & 0xFF ] << 24 );
 
-    X1 = *RK++ ^ \
-            ( (uint32_t) RSb[ ( Y1       ) & 0xFF ]       ) ^
-            ( (uint32_t) RSb[ ( Y0 >>  8 ) & 0xFF ] <<  8 ) ^
-            ( (uint32_t) RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
-            ( (uint32_t) RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
+    t.X[1] = *RK++ ^ \
+            ( (uint32_t) RSb[ ( t.Y[1]       ) & 0xFF ]       ) ^
+            ( (uint32_t) RSb[ ( t.Y[0] >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) RSb[ ( t.Y[3] >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) RSb[ ( t.Y[2] >> 24 ) & 0xFF ] << 24 );
 
-    X2 = *RK++ ^ \
-            ( (uint32_t) RSb[ ( Y2       ) & 0xFF ]       ) ^
-            ( (uint32_t) RSb[ ( Y1 >>  8 ) & 0xFF ] <<  8 ) ^
-            ( (uint32_t) RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
-            ( (uint32_t) RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
+    t.X[2] = *RK++ ^ \
+            ( (uint32_t) RSb[ ( t.Y[2]       ) & 0xFF ]       ) ^
+            ( (uint32_t) RSb[ ( t.Y[1] >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) RSb[ ( t.Y[0] >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) RSb[ ( t.Y[3] >> 24 ) & 0xFF ] << 24 );
 
-    X3 = *RK++ ^ \
-            ( (uint32_t) RSb[ ( Y3       ) & 0xFF ]       ) ^
-            ( (uint32_t) RSb[ ( Y2 >>  8 ) & 0xFF ] <<  8 ) ^
-            ( (uint32_t) RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
-            ( (uint32_t) RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
+    t.X[3] = *RK++ ^ \
+            ( (uint32_t) RSb[ ( t.Y[3]       ) & 0xFF ]       ) ^
+            ( (uint32_t) RSb[ ( t.Y[2] >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) RSb[ ( t.Y[1] >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) RSb[ ( t.Y[0] >> 24 ) & 0xFF ] << 24 );
 
-    PUT_UINT32_LE( X0, output,  0 );
-    PUT_UINT32_LE( X1, output,  4 );
-    PUT_UINT32_LE( X2, output,  8 );
-    PUT_UINT32_LE( X3, output, 12 );
+    PUT_UINT32_LE( t.X[0], output,  0 );
+    PUT_UINT32_LE( t.X[1], output,  4 );
+    PUT_UINT32_LE( t.X[2], output,  8 );
+    PUT_UINT32_LE( t.X[3], output, 12 );
 
-    mbedtls_platform_zeroize( &X0, sizeof( X0 ) );
-    mbedtls_platform_zeroize( &X1, sizeof( X1 ) );
-    mbedtls_platform_zeroize( &X2, sizeof( X2 ) );
-    mbedtls_platform_zeroize( &X3, sizeof( X3 ) );
-
-    mbedtls_platform_zeroize( &Y0, sizeof( Y0 ) );
-    mbedtls_platform_zeroize( &Y1, sizeof( Y1 ) );
-    mbedtls_platform_zeroize( &Y2, sizeof( Y2 ) );
-    mbedtls_platform_zeroize( &Y3, sizeof( Y3 ) );
-
-    mbedtls_platform_zeroize( &RK, sizeof( RK ) );
+    mbedtls_platform_zeroize( &t, sizeof( t ) );
 
     return( 0 );
 }
diff --git a/library/bignum.c b/library/bignum.c
index 55d9482..f133f6c 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -1354,6 +1354,12 @@
     for( n = B->n; n > 0; n-- )
         if( B->p[n - 1] != 0 )
             break;
+    if( n > A->n )
+    {
+        /* B >= (2^ciL)^n > A */
+        ret = MBEDTLS_ERR_MPI_NEGATIVE_VALUE;
+        goto cleanup;
+    }
 
     carry = mpi_sub_hlp( n, X->p, B->p );
     if( carry != 0 )
@@ -1364,7 +1370,10 @@
         /* If we ran out of space for the carry, it means that the result
          * is negative. */
         if( n == X->n )
-            return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE );
+        {
+            ret = MBEDTLS_ERR_MPI_NEGATIVE_VALUE;
+            goto cleanup;
+        }
         --X->p[n];
     }
 
@@ -2044,7 +2053,7 @@
     size_t i, j, nblimbs;
     size_t bufsize, nbits;
     mbedtls_mpi_uint ei, mm, state;
-    mbedtls_mpi RR, T, W[ 2 << MBEDTLS_MPI_WINDOW_SIZE ], Apos;
+    mbedtls_mpi RR, T, W[ 1 << MBEDTLS_MPI_WINDOW_SIZE ], Apos;
     int neg;
 
     MPI_VALIDATE_RET( X != NULL );
diff --git a/library/cipher_wrap.c b/library/cipher_wrap.c
index 1dcac21..5973ca6 100644
--- a/library/cipher_wrap.c
+++ b/library/cipher_wrap.c
@@ -779,7 +779,7 @@
     MBEDTLS_MODE_ECB,
     128,
     "CAMELLIA-128-ECB",
-    16,
+    0,
     0,
     16,
     &camellia_info
@@ -790,7 +790,7 @@
     MBEDTLS_MODE_ECB,
     192,
     "CAMELLIA-192-ECB",
-    16,
+    0,
     0,
     16,
     &camellia_info
@@ -801,7 +801,7 @@
     MBEDTLS_MODE_ECB,
     256,
     "CAMELLIA-256-ECB",
-    16,
+    0,
     0,
     16,
     &camellia_info
@@ -1155,7 +1155,7 @@
     MBEDTLS_MODE_ECB,
     128,
     "ARIA-128-ECB",
-    16,
+    0,
     0,
     16,
     &aria_info
@@ -1166,7 +1166,7 @@
     MBEDTLS_MODE_ECB,
     192,
     "ARIA-192-ECB",
-    16,
+    0,
     0,
     16,
     &aria_info
@@ -1177,7 +1177,7 @@
     MBEDTLS_MODE_ECB,
     256,
     "ARIA-256-ECB",
-    16,
+    0,
     0,
     16,
     &aria_info
@@ -1579,7 +1579,7 @@
     MBEDTLS_MODE_ECB,
     MBEDTLS_KEY_LENGTH_DES,
     "DES-ECB",
-    8,
+    0,
     0,
     8,
     &des_info
@@ -1630,7 +1630,7 @@
     MBEDTLS_MODE_ECB,
     MBEDTLS_KEY_LENGTH_DES_EDE,
     "DES-EDE-ECB",
-    8,
+    0,
     0,
     8,
     &des_ede_info
@@ -1681,7 +1681,7 @@
     MBEDTLS_MODE_ECB,
     MBEDTLS_KEY_LENGTH_DES_EDE3,
     "DES-EDE3-ECB",
-    8,
+    0,
     0,
     8,
     &des_ede3_info
@@ -1796,7 +1796,7 @@
     MBEDTLS_MODE_ECB,
     128,
     "BLOWFISH-ECB",
-    8,
+    0,
     MBEDTLS_CIPHER_VARIABLE_KEY_LEN,
     8,
     &blowfish_info
diff --git a/library/cmac.c b/library/cmac.c
index 1a1200b..409f679 100644
--- a/library/cmac.c
+++ b/library/cmac.c
@@ -450,7 +450,7 @@
  */
 int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_length,
                               const unsigned char *input, size_t in_len,
-                              unsigned char *output )
+                              unsigned char output[16] )
 {
     int ret;
     const mbedtls_cipher_info_t *cipher_info;
diff --git a/library/ctr_drbg.c b/library/ctr_drbg.c
index b98df29..90264e8 100644
--- a/library/ctr_drbg.c
+++ b/library/ctr_drbg.c
@@ -82,21 +82,26 @@
 {
     memset( ctx, 0, sizeof( mbedtls_ctr_drbg_context ) );
 
-#if defined(MBEDTLS_THREADING_C)
-    mbedtls_mutex_init( &ctx->mutex );
-#endif
+    ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
 }
 
+/*
+ *  This function resets CTR_DRBG context to the state immediately
+ *  after initial call of mbedtls_ctr_drbg_init().
+ */
 void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx )
 {
     if( ctx == NULL )
         return;
 
 #if defined(MBEDTLS_THREADING_C)
-    mbedtls_mutex_free( &ctx->mutex );
+    /* The mutex is initialized iff f_entropy is set. */
+    if( ctx->f_entropy != NULL )
+        mbedtls_mutex_free( &ctx->mutex );
 #endif
     mbedtls_aes_free( &ctx->aes_ctx );
     mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ctr_drbg_context ) );
+    ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
 }
 
 void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx, int resistance )
@@ -412,6 +417,11 @@
 
     memset( key, 0, MBEDTLS_CTR_DRBG_KEYSIZE );
 
+    /* The mutex is initialized iff f_entropy is set. */
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_mutex_init( &ctx->mutex );
+#endif
+
     mbedtls_aes_init( &ctx->aes_ctx );
 
     ctx->f_entropy = f_entropy;
@@ -419,7 +429,6 @@
 
     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
diff --git a/library/ecdsa.c b/library/ecdsa.c
index da8df9c..2456238 100644
--- a/library/ecdsa.c
+++ b/library/ecdsa.c
@@ -247,6 +247,9 @@
 
 #endif /* MBEDTLS_ECP_RESTARTABLE */
 
+#if defined(MBEDTLS_ECDSA_DETERMINISTIC) || \
+    !defined(MBEDTLS_ECDSA_SIGN_ALT)     || \
+    !defined(MBEDTLS_ECDSA_VERIFY_ALT)
 /*
  * Derive a suitable integer for group grp from a buffer of length len
  * SEC1 4.1.3 step 5 aka SEC1 4.1.4 step 3
@@ -269,6 +272,7 @@
 cleanup:
     return( ret );
 }
+#endif /* ECDSA_DETERMINISTIC || !ECDSA_SIGN_ALT || !ECDSA_VERIFY_ALT */
 
 #if !defined(MBEDTLS_ECDSA_SIGN_ALT)
 /*
@@ -780,6 +784,8 @@
     (void) md_alg;
 
 #if defined(MBEDTLS_ECDSA_SIGN_ALT)
+    (void) rs_ctx;
+
     MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ctx->grp, &r, &s, &ctx->d,
                          hash, hlen, f_rng, p_rng ) );
 #else
@@ -888,6 +894,8 @@
         goto cleanup;
     }
 #if defined(MBEDTLS_ECDSA_VERIFY_ALT)
+    (void) rs_ctx;
+
     if( ( ret = mbedtls_ecdsa_verify( &ctx->grp, hash, hlen,
                                       &ctx->Q, &r, &s ) ) != 0 )
         goto cleanup;
diff --git a/library/ecjpake.c b/library/ecjpake.c
index f6e2458..0532a29 100644
--- a/library/ecjpake.c
+++ b/library/ecjpake.c
@@ -850,6 +850,8 @@
     0x65, 0x73, 0x74
 };
 
+#if !defined(MBEDTLS_ECJPAKE_ALT)
+
 static const unsigned char ecjpake_test_x1[] = {
     0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
     0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
@@ -994,6 +996,8 @@
     return( ret );
 }
 
+#endif /* ! MBEDTLS_ECJPAKE_ALT */
+
 /* For tests we don't need a secure RNG;
  * use the LGC from Numerical Recipes for simplicity */
 static int ecjpake_lgc( void *p, unsigned char *out, size_t len )
@@ -1089,6 +1093,12 @@
     if( verbose != 0 )
         mbedtls_printf( "passed\n" );
 
+#if !defined(MBEDTLS_ECJPAKE_ALT)
+    /* 'reference handshake' tests can only be run against implementations
+     * for which we have 100% control over how the random ephemeral keys
+     * are generated. This is only the case for the internal mbed TLS
+     * implementation, so these tests are skipped in case the internal
+     * implementation is swapped out for an alternative one. */
     if( verbose != 0 )
         mbedtls_printf( "  ECJPAKE test #2 (reference handshake): " );
 
@@ -1137,6 +1147,7 @@
 
     if( verbose != 0 )
         mbedtls_printf( "passed\n" );
+#endif /* ! MBEDTLS_ECJPAKE_ALT */
 
 cleanup:
     mbedtls_ecjpake_free( &cli );
diff --git a/library/ecp_curves.c b/library/ecp_curves.c
index cc4c5b7..b04596b 100644
--- a/library/ecp_curves.c
+++ b/library/ecp_curves.c
@@ -1044,7 +1044,7 @@
     STORE32; i++;                               \
     cur = c > 0 ? c : 0; STORE32;               \
     cur = 0; while( ++i < MAX32 ) { STORE32; }  \
-    if( c < 0 ) fix_negative( N, c, &C, bits );
+    if( c < 0 ) MBEDTLS_MPI_CHK( fix_negative( N, c, &C, bits ) );
 
 /*
  * If the result is negative, we get it in the form
diff --git a/library/entropy.c b/library/entropy.c
index 666c556..c5f414a 100644
--- a/library/entropy.c
+++ b/library/entropy.c
@@ -146,6 +146,11 @@
 
 void mbedtls_entropy_free( mbedtls_entropy_context *ctx )
 {
+    /* If the context was already free, don't call free() again.
+     * This is important for mutexes which don't allow double-free. */
+    if( ctx->accumulator_started == -1 )
+        return;
+
 #if defined(MBEDTLS_HAVEGE_C)
     mbedtls_havege_free( &ctx->havege_data );
 #endif
@@ -162,7 +167,7 @@
 #endif
     ctx->source_count = 0;
     mbedtls_platform_zeroize( ctx->source, sizeof( ctx->source ) );
-    ctx->accumulator_started = 0;
+    ctx->accumulator_started = -1;
 }
 
 int mbedtls_entropy_add_source( mbedtls_entropy_context *ctx,
diff --git a/library/entropy_poll.c b/library/entropy_poll.c
index 4ad878e..d7062ea 100644
--- a/library/entropy_poll.c
+++ b/library/entropy_poll.c
@@ -44,7 +44,7 @@
  *  **********
  */
 
-#if defined(__linux__)
+#if defined(__linux__) && !defined(_GNU_SOURCE)
 /* Ensure that syscall() is available even when compiling with -std=c99 */
 #define _GNU_SOURCE
 #endif
diff --git a/library/error.c b/library/error.c
index eb52052..b83b8d1 100644
--- a/library/error.c
+++ b/library/error.c
@@ -51,20 +51,19 @@
 #endif
 
 #if defined(MBEDTLS_ERROR_C) || defined(MBEDTLS_ERROR_STRERROR_DUMMY)
+
 #include "mbedtls/error.h"
-#include <string.h>
-#endif
+
+#if defined(MBEDTLS_ERROR_C)
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
 #else
 #define mbedtls_snprintf snprintf
-#define mbedtls_time_t   time_t
 #endif
 
-#if defined(MBEDTLS_ERROR_C)
-
 #include <stdio.h>
+#include <string.h>
 
 #if defined(MBEDTLS_AES_C)
 #include "mbedtls/aes.h"
@@ -929,8 +928,6 @@
 
 #else /* MBEDTLS_ERROR_C */
 
-#if defined(MBEDTLS_ERROR_STRERROR_DUMMY)
-
 /*
  * Provide an non-function in case MBEDTLS_ERROR_C is not defined
  */
@@ -942,6 +939,6 @@
         buf[0] = '\0';
 }
 
-#endif /* MBEDTLS_ERROR_STRERROR_DUMMY */
-
 #endif /* MBEDTLS_ERROR_C */
+
+#endif /* MBEDTLS_ERROR_C || MBEDTLS_ERROR_STRERROR_DUMMY */
diff --git a/library/hmac_drbg.c b/library/hmac_drbg.c
index 9fbfc30..b45d616 100644
--- a/library/hmac_drbg.c
+++ b/library/hmac_drbg.c
@@ -83,9 +83,7 @@
 {
     memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) );
 
-#if defined(MBEDTLS_THREADING_C)
-    mbedtls_mutex_init( &ctx->mutex );
-#endif
+    ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
 }
 
 /*
@@ -157,6 +155,10 @@
     if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
         return( ret );
 
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_mutex_init( &ctx->mutex );
+#endif
+
     /*
      * Set initial working state.
      * Use the V memory location, which is currently all 0, to initialize the
@@ -282,6 +284,11 @@
     if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
         return( ret );
 
+    /* The mutex is initialized iff the md context is set up. */
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_mutex_init( &ctx->mutex );
+#endif
+
     md_size = mbedtls_md_get_size( md_info );
 
     /*
@@ -296,8 +303,6 @@
     ctx->f_entropy = f_entropy;
     ctx->p_entropy = p_entropy;
 
-    ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
-
     if( ctx->entropy_len == 0 )
     {
         /*
@@ -442,7 +447,8 @@
 }
 
 /*
- * Free an HMAC_DRBG context
+ *  This function resets HMAC_DRBG context to the state immediately
+ *  after initial call of mbedtls_hmac_drbg_init().
  */
 void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
 {
@@ -450,10 +456,13 @@
         return;
 
 #if defined(MBEDTLS_THREADING_C)
-    mbedtls_mutex_free( &ctx->mutex );
+    /* The mutex is initialized iff the md context is set up. */
+    if( ctx->md_ctx.md_info != NULL )
+        mbedtls_mutex_free( &ctx->mutex );
 #endif
     mbedtls_md_free( &ctx->md_ctx );
     mbedtls_platform_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
+    ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
 }
 
 #if defined(MBEDTLS_FS_IO)
diff --git a/library/net_sockets.c b/library/net_sockets.c
index 1130408..671115f 100644
--- a/library/net_sockets.c
+++ b/library/net_sockets.c
@@ -496,6 +496,13 @@
     if( fd < 0 )
         return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
 
+    /* A limitation of select() is that it only works with file descriptors
+     * that are strictly less than FD_SETSIZE. This is a limitation of the
+     * fd_set type. Error out early, because attempting to call FD_SET on a
+     * large file descriptor is a buffer overflow on typical platforms. */
+    if( fd >= FD_SETSIZE )
+        return( MBEDTLS_ERR_NET_POLL_FAILED );
+
 #if defined(__has_feature)
 #if __has_feature(memory_sanitizer)
     /* Ensure that memory sanitizers consider read_fds and write_fds as
@@ -615,6 +622,13 @@
     if( fd < 0 )
         return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
 
+    /* A limitation of select() is that it only works with file descriptors
+     * that are strictly less than FD_SETSIZE. This is a limitation of the
+     * fd_set type. Error out early, because attempting to call FD_SET on a
+     * large file descriptor is a buffer overflow on typical platforms. */
+    if( fd >= FD_SETSIZE )
+        return( MBEDTLS_ERR_NET_POLL_FAILED );
+
     FD_ZERO( &read_fds );
     FD_SET( fd, &read_fds );
 
diff --git a/library/pem.c b/library/pem.c
index a7a2f7f..50e663c 100644
--- a/library/pem.c
+++ b/library/pem.c
@@ -508,8 +508,12 @@
     *p++ = '\0';
     *olen = p - buf;
 
+     /* Clean any remaining data previously written to the buffer */
+    memset( buf + *olen, 0, buf_len - *olen );
+
     mbedtls_free( encode_buf );
     return( 0 );
 }
 #endif /* MBEDTLS_PEM_WRITE_C */
 #endif /* MBEDTLS_PEM_PARSE_C || MBEDTLS_PEM_WRITE_C */
+
diff --git a/library/pkparse.c b/library/pkparse.c
index 086807d..e410f3a 100644
--- a/library/pkparse.c
+++ b/library/pkparse.c
@@ -692,7 +692,7 @@
         ret = MBEDTLS_ERR_PK_UNKNOWN_PK_ALG;
 
     if( ret == 0 && *p != end )
-        ret = MBEDTLS_ERR_PK_INVALID_PUBKEY
+        ret = MBEDTLS_ERR_PK_INVALID_PUBKEY +
               MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
 
     if( ret != 0 )
diff --git a/library/pkwrite.c b/library/pkwrite.c
index 150626c..a770dfb 100644
--- a/library/pkwrite.c
+++ b/library/pkwrite.c
@@ -455,7 +455,7 @@
  *      publicExponent    INTEGER   -- e            1 + 3 + MPI_MAX + 1
  *  }
  */
-#define RSA_PUB_DER_MAX_BYTES   38 + 2 * MBEDTLS_MPI_MAX_SIZE
+#define RSA_PUB_DER_MAX_BYTES   ( 38 + 2 * MBEDTLS_MPI_MAX_SIZE )
 
 /*
  * RSA private keys:
@@ -472,10 +472,10 @@
  *      otherPrimeInfos   OtherPrimeInfos OPTIONAL  0 (not supported)
  *  }
  */
-#define MPI_MAX_SIZE_2          MBEDTLS_MPI_MAX_SIZE / 2 + \
-                                MBEDTLS_MPI_MAX_SIZE % 2
-#define RSA_PRV_DER_MAX_BYTES   47 + 3 * MBEDTLS_MPI_MAX_SIZE \
-                                   + 5 * MPI_MAX_SIZE_2
+#define MPI_MAX_SIZE_2          ( MBEDTLS_MPI_MAX_SIZE / 2 + \
+                                  MBEDTLS_MPI_MAX_SIZE % 2 )
+#define RSA_PRV_DER_MAX_BYTES   ( 47 + 3 * MBEDTLS_MPI_MAX_SIZE \
+                                   + 5 * MPI_MAX_SIZE_2 )
 
 #else /* MBEDTLS_RSA_C */
 
@@ -496,7 +496,7 @@
  *                                            + 2 * ECP_MAX (coords)    [1]
  *  }
  */
-#define ECP_PUB_DER_MAX_BYTES   30 + 2 * MBEDTLS_ECP_MAX_BYTES
+#define ECP_PUB_DER_MAX_BYTES   ( 30 + 2 * MBEDTLS_ECP_MAX_BYTES )
 
 /*
  * EC private keys:
@@ -507,7 +507,7 @@
  *      publicKey  [1] BIT STRING OPTIONAL      1 + 2 + [1] above
  *    }
  */
-#define ECP_PRV_DER_MAX_BYTES   29 + 3 * MBEDTLS_ECP_MAX_BYTES
+#define ECP_PRV_DER_MAX_BYTES   ( 29 + 3 * MBEDTLS_ECP_MAX_BYTES )
 
 #else /* MBEDTLS_ECP_C */
 
@@ -516,10 +516,10 @@
 
 #endif /* MBEDTLS_ECP_C */
 
-#define PUB_DER_MAX_BYTES   RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \
-                            RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES
-#define PRV_DER_MAX_BYTES   RSA_PRV_DER_MAX_BYTES > ECP_PRV_DER_MAX_BYTES ? \
-                            RSA_PRV_DER_MAX_BYTES : ECP_PRV_DER_MAX_BYTES
+#define PUB_DER_MAX_BYTES   ( RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \
+                              RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES )
+#define PRV_DER_MAX_BYTES   ( RSA_PRV_DER_MAX_BYTES > ECP_PRV_DER_MAX_BYTES ? \
+                              RSA_PRV_DER_MAX_BYTES : ECP_PRV_DER_MAX_BYTES )
 
 int mbedtls_pk_write_pubkey_pem( mbedtls_pk_context *key, unsigned char *buf, size_t size )
 {
diff --git a/library/platform_util.c b/library/platform_util.c
index 3ba2aea..c8cd52d 100644
--- a/library/platform_util.c
+++ b/library/platform_util.c
@@ -115,7 +115,7 @@
 
 #if !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) ||     \
        ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) &&                     \
-         _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) )
+         _POSIX_THREAD_SAFE_FUNCTIONS >= 200112L ) )
 /*
  * This is a convenience shorthand macro to avoid checking the long
  * preprocessor conditions above. Ideally, we could expose this macro in
@@ -129,7 +129,7 @@
 
 #endif /* !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) ||     \
              ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) &&                     \
-                _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) */
+                _POSIX_THREAD_SAFE_FUNCTIONS >= 200112L ) ) */
 
 struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt,
                                       struct tm *tm_buf )
diff --git a/library/rsa.c b/library/rsa.c
index 42becbf..c8c23db 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -520,6 +520,9 @@
     mbedtls_rsa_set_padding( ctx, padding, hash_id );
 
 #if defined(MBEDTLS_THREADING_C)
+    /* Set ctx->ver to nonzero to indicate that the mutex has been
+     * initialized and will need to be freed. */
+    ctx->ver = 1;
     mbedtls_mutex_init( &ctx->mutex );
 #endif
 }
@@ -567,9 +570,6 @@
     RSA_VALIDATE_RET( ctx != NULL );
     RSA_VALIDATE_RET( f_rng != NULL );
 
-    if( nbits < 128 || exponent < 3 || nbits % 2 != 0 )
-        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
-
     /*
      * If the modulus is 1024 bit long or shorter, then the security strength of
      * the RSA algorithm is less than or equal to 80 bits and therefore an error
@@ -582,6 +582,12 @@
     mbedtls_mpi_init( &G );
     mbedtls_mpi_init( &L );
 
+    if( nbits < 128 || exponent < 3 || nbits % 2 != 0 )
+    {
+        ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
+        goto cleanup;
+    }
+
     /*
      * find primes P and Q with Q < P so that:
      * 1.  |P-Q| > 2^( nbits / 2 - 100 )
@@ -659,7 +665,9 @@
     if( ret != 0 )
     {
         mbedtls_rsa_free( ctx );
-        return( MBEDTLS_ERR_RSA_KEY_GEN_FAILED + ret );
+        if( ( -ret & ~0x7f ) == 0 )
+            ret = MBEDTLS_ERR_RSA_KEY_GEN_FAILED + ret;
+        return( ret );
     }
 
     return( 0 );
@@ -841,15 +849,14 @@
          * which one, we just loop and choose new values for both of them.
          * (Each iteration succeeds with overwhelming probability.) */
         ret = mbedtls_mpi_inv_mod( &ctx->Vi, &ctx->Vi, &ctx->N );
-        if( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
-            continue;
-        if( ret != 0 )
+        if( ret != 0 && ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
             goto cleanup;
 
-        /* Finish the computation of Vf^-1 = R * (R Vf)^-1 */
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &R ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) );
-    } while( 0 );
+    } while( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
+
+    /* Finish the computation of Vf^-1 = R * (R Vf)^-1 */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &R ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) );
 
     /* Blinding value: Vi = Vf^(-e) mod N
      * (Vi already contains Vf^-1 at this point) */
@@ -1107,10 +1114,10 @@
     mbedtls_mpi_free( &C );
     mbedtls_mpi_free( &I );
 
-    if( ret != 0 )
+    if( ret != 0 && ret >= -0x007f )
         return( MBEDTLS_ERR_RSA_PRIVATE_FAILED + ret );
 
-    return( 0 );
+    return( ret );
 }
 
 #if defined(MBEDTLS_PKCS1_V21)
@@ -2503,7 +2510,6 @@
     RSA_VALIDATE_RET( dst != NULL );
     RSA_VALIDATE_RET( src != NULL );
 
-    dst->ver = src->ver;
     dst->len = src->len;
 
     MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->N, &src->N ) );
@@ -2562,7 +2568,12 @@
 #endif /* MBEDTLS_RSA_NO_CRT */
 
 #if defined(MBEDTLS_THREADING_C)
-    mbedtls_mutex_free( &ctx->mutex );
+    /* Free the mutex, but only if it hasn't been freed already. */
+    if( ctx->ver != 0 )
+    {
+        mbedtls_mutex_free( &ctx->mutex );
+        ctx->ver = 0;
+    }
 #endif
 }
 
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 97b7784..cbf6142 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -3587,11 +3587,12 @@
     /* In case of a failure in decryption, the decryption may write less than
      * 2 bytes of output, but we always read the first two bytes. It doesn't
      * matter in the end because diff will be nonzero in that case due to
-     * peer_pmslen being less than 48, and we only care whether diff is 0.
-     * But do initialize peer_pms for robustness anyway. This also makes
-     * memory analyzers happy (don't access uninitialized memory, even
-     * if it's an unsigned char). */
+     * ret being nonzero, and we only care whether diff is 0.
+     * But do initialize peer_pms and peer_pmslen for robustness anyway. This
+     * also makes memory analyzers happy (don't access uninitialized memory,
+     * even if it's an unsigned char). */
     peer_pms[0] = peer_pms[1] = ~0;
+    peer_pmslen = 0;
 
     ret = ssl_decrypt_encrypted_pms( ssl, p, end,
                                      peer_pms,
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 2471600..c749a86 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -621,7 +621,7 @@
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
 #if defined(MBEDTLS_SHA256_C)
 static void ssl_update_checksum_sha256( mbedtls_ssl_context *, const unsigned char *, size_t );
-static void ssl_calc_verify_tls_sha256( mbedtls_ssl_context *,unsigned char * );
+static void ssl_calc_verify_tls_sha256( mbedtls_ssl_context *, unsigned char * );
 static void ssl_calc_finished_tls_sha256( mbedtls_ssl_context *,unsigned char *, int );
 #endif
 
@@ -1142,7 +1142,7 @@
 }
 
 #if defined(MBEDTLS_SSL_PROTO_SSL3)
-void ssl_calc_verify_ssl( mbedtls_ssl_context *ssl, unsigned char hash[36] )
+void ssl_calc_verify_ssl( mbedtls_ssl_context *ssl, unsigned char *hash )
 {
     mbedtls_md5_context md5;
     mbedtls_sha1_context sha1;
@@ -1191,7 +1191,7 @@
 #endif /* MBEDTLS_SSL_PROTO_SSL3 */
 
 #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
-void ssl_calc_verify_tls( mbedtls_ssl_context *ssl, unsigned char hash[36] )
+void ssl_calc_verify_tls( mbedtls_ssl_context *ssl, unsigned char *hash )
 {
     mbedtls_md5_context md5;
     mbedtls_sha1_context sha1;
@@ -1219,7 +1219,7 @@
 
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
 #if defined(MBEDTLS_SHA256_C)
-void ssl_calc_verify_tls_sha256( mbedtls_ssl_context *ssl, unsigned char hash[32] )
+void ssl_calc_verify_tls_sha256( mbedtls_ssl_context *ssl, unsigned char *hash )
 {
     mbedtls_sha256_context sha256;
 
@@ -1240,7 +1240,7 @@
 #endif /* MBEDTLS_SHA256_C */
 
 #if defined(MBEDTLS_SHA512_C)
-void ssl_calc_verify_tls_sha384( mbedtls_ssl_context *ssl, unsigned char hash[48] )
+void ssl_calc_verify_tls_sha384( mbedtls_ssl_context *ssl, unsigned char *hash )
 {
     mbedtls_sha512_context sha512;
 
@@ -6363,6 +6363,9 @@
 #endif /* MBEDTLS_SHA256_C */
 
 #if defined(MBEDTLS_SHA512_C)
+
+typedef int (*finish_sha384_t)(mbedtls_sha512_context*, unsigned char*);
+
 static void ssl_calc_finished_tls_sha384(
                 mbedtls_ssl_context *ssl, unsigned char *buf, int from )
 {
@@ -6370,6 +6373,12 @@
     const char *sender;
     mbedtls_sha512_context sha512;
     unsigned char padbuf[48];
+    /*
+     * For SHA-384, we can save 16 bytes by keeping padbuf 48 bytes long.
+     * However, to avoid stringop-overflow warning in gcc, we have to cast
+     * mbedtls_sha512_finish_ret().
+     */
+    finish_sha384_t finish_sha384 = (finish_sha384_t)mbedtls_sha512_finish_ret;
 
     mbedtls_ssl_session *session = ssl->session_negotiate;
     if( !session )
@@ -6396,7 +6405,7 @@
              ? "client finished"
              : "server finished";
 
-    mbedtls_sha512_finish_ret( &sha512, padbuf );
+    finish_sha384( &sha512, padbuf );
 
     ssl->handshake->tls_prf( session->master, 48, sender,
                              padbuf, 48, buf, len );
diff --git a/library/threading.c b/library/threading.c
index 61c4b94..0dc5488 100644
--- a/library/threading.c
+++ b/library/threading.c
@@ -73,7 +73,7 @@
 
 #if !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) ||     \
        ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) &&                     \
-         _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) )
+         _POSIX_THREAD_SAFE_FUNCTIONS >= 200112L ) )
 /*
  * This is a convenience shorthand macro to avoid checking the long
  * preprocessor conditions above. Ideally, we could expose this macro in
@@ -88,7 +88,7 @@
 
 #endif /* !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) ||     \
              ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) &&                     \
-                _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) */
+                _POSIX_THREAD_SAFE_FUNCTIONS >= 200112L ) ) */
 
 #endif /* MBEDTLS_HAVE_TIME_DATE && !MBEDTLS_PLATFORM_GMTIME_R_ALT */
 
@@ -98,6 +98,12 @@
     if( mutex == NULL )
         return;
 
+    /* A nonzero value of is_valid indicates a successfully initialized
+     * mutex. This is a workaround for not being able to return an error
+     * code for this function. The lock/unlock functions return an error
+     * if is_valid is nonzero. The Mbed TLS unit test code uses this field
+     * to distinguish more states of the mutex; see helpers.function for
+     * details. */
     mutex->is_valid = pthread_mutex_init( &mutex->mutex, NULL ) == 0;
 }
 
diff --git a/library/version_features.c b/library/version_features.c
index cbf38dc..8c8e815 100644
--- a/library/version_features.c
+++ b/library/version_features.c
@@ -553,6 +553,9 @@
 #if defined(MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT)
     "MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT",
 #endif /* MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT */
+#if defined(MBEDTLS_TEST_HOOKS)
+    "MBEDTLS_TEST_HOOKS",
+#endif /* MBEDTLS_TEST_HOOKS */
 #if defined(MBEDTLS_THREADING_ALT)
     "MBEDTLS_THREADING_ALT",
 #endif /* MBEDTLS_THREADING_ALT */
diff --git a/library/x509_crt.c b/library/x509_crt.c
index fd89135..4b53d1a 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -1817,8 +1817,7 @@
         if( crt->serial.len == cur->serial.len &&
             memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
         {
-            if( mbedtls_x509_time_is_past( &cur->revocation_date ) )
-                return( 1 );
+            return( 1 );
         }
 
         cur = cur->next;
diff --git a/programs/ssl/CMakeLists.txt b/programs/ssl/CMakeLists.txt
index b3ef4f8..094543b 100644
--- a/programs/ssl/CMakeLists.txt
+++ b/programs/ssl/CMakeLists.txt
@@ -37,8 +37,8 @@
 add_executable(ssl_client1 ssl_client1.c)
 target_link_libraries(ssl_client1 ${libs})
 
-add_executable(ssl_client2 ssl_client2.c)
-target_sources(ssl_client2 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/query_config.c)
+add_executable(ssl_client2 ssl_client2.c
+               ${CMAKE_CURRENT_SOURCE_DIR}/query_config.c)
 target_link_libraries(ssl_client2 ${libs})
 
 add_executable(ssl_fork_server ssl_fork_server.c)
@@ -50,8 +50,8 @@
 add_executable(ssl_server ssl_server.c)
 target_link_libraries(ssl_server ${libs})
 
-add_executable(ssl_server2 ssl_server2.c)
-target_sources(ssl_server2 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/query_config.c)
+add_executable(ssl_server2 ssl_server2.c
+               ${CMAKE_CURRENT_SOURCE_DIR}/query_config.c)
 target_link_libraries(ssl_server2 ${libs})
 
 if(THREADS_FOUND)
diff --git a/programs/ssl/query_config.c b/programs/ssl/query_config.c
index 798c917..0a7eb1a 100644
--- a/programs/ssl/query_config.c
+++ b/programs/ssl/query_config.c
@@ -1475,6 +1475,14 @@
     }
 #endif /* MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT */
 
+#if defined(MBEDTLS_TEST_HOOKS)
+    if( strcmp( "MBEDTLS_TEST_HOOKS", config ) == 0 )
+    {
+        MACRO_EXPANSION_TO_STR( MBEDTLS_TEST_HOOKS );
+        return( 0 );
+    }
+#endif /* MBEDTLS_TEST_HOOKS */
+
 #if defined(MBEDTLS_THREADING_ALT)
     if( strcmp( "MBEDTLS_THREADING_ALT", config ) == 0 )
     {
diff --git a/programs/test/CMakeLists.txt b/programs/test/CMakeLists.txt
index 5feb317..a74db1e 100644
--- a/programs/test/CMakeLists.txt
+++ b/programs/test/CMakeLists.txt
@@ -27,8 +27,8 @@
 add_executable(zeroize zeroize.c)
 target_link_libraries(zeroize ${libs})
 
-add_executable(query_compile_time_config query_compile_time_config.c)
-target_sources(query_compile_time_config PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../ssl/query_config.c)
+add_executable(query_compile_time_config query_compile_time_config.c
+               ${CMAKE_CURRENT_SOURCE_DIR}/../ssl/query_config.c)
 target_link_libraries(query_compile_time_config ${libs})
 
 install(TARGETS selftest benchmark udp_proxy query_compile_time_config
diff --git a/programs/test/selftest.c b/programs/test/selftest.c
index 9bc9a9c..fe35bb1 100644
--- a/programs/test/selftest.c
+++ b/programs/test/selftest.c
@@ -185,7 +185,7 @@
 }
 #endif /* MBEDTLS_SELF_TEST */
 
-static int test_snprintf( size_t n, const char ref_buf[10], int ref_ret )
+static int test_snprintf( size_t n, const char *ref_buf, int ref_ret )
 {
     int ret;
     char buf[10] = "xxxxxxxxx";
diff --git a/programs/x509/cert_req.c b/programs/x509/cert_req.c
index c88050c..dc79603 100644
--- a/programs/x509/cert_req.c
+++ b/programs/x509/cert_req.c
@@ -127,9 +127,8 @@
     "                          Add NsCertType even if it is empty\n"    \
     "    md=%%s               default: SHA256\n"       \
     "                          possible values:\n"     \
-    "                          MD2, MD4, MD5, SHA1\n"  \
-    "                          SHA224, SHA256\n"       \
-    "                          SHA384, SHA512\n"       \
+    "                          MD2, MD4, MD5, RIPEMD160, SHA1,\n" \
+    "                          SHA224, SHA256, SHA384, SHA512\n" \
     "\n"
 
 
@@ -244,58 +243,14 @@
         }
         else if( strcmp( p, "md" ) == 0 )
         {
-            if( strcmp( q, "SHA256" ) == 0 )
+            const mbedtls_md_info_t *md_info =
+                mbedtls_md_info_from_string( q );
+            if( md_info == NULL )
             {
-                opt.md_alg = MBEDTLS_MD_SHA256;
-            }
-            else if( strcmp( q, "SHA224" ) == 0 )
-            {
-                opt.md_alg = MBEDTLS_MD_SHA224;
-            }
-            else
-#if defined(MBEDTLS_MD5_C)
-            if( strcmp( q, "MD5" ) == 0 )
-            {
-                opt.md_alg = MBEDTLS_MD_MD5;
-            }
-            else
-#endif /* MBEDTLS_MD5_C */
-#if defined(MBEDTLS_MD4_C)
-            if( strcmp( q, "MD4" ) == 0 )
-            {
-                opt.md_alg = MBEDTLS_MD_MD4;
-            }
-            else
-#endif /* MBEDTLS_MD5_C */
-#if defined(MBEDTLS_MD2_C)
-            if( strcmp( q, "MD2" ) == 0 )
-            {
-                opt.md_alg = MBEDTLS_MD_MD2;
-            }
-            else
-#endif /* MBEDTLS_MD2_C */
-#if defined(MBEDTLS_SHA1_C)
-            if( strcmp( q, "SHA1" ) == 0 )
-            {
-                opt.md_alg = MBEDTLS_MD_SHA1;
-            }
-            else
-#endif /* MBEDTLS_SHA1_C */
-#if defined(MBEDTLS_SHA512_C)
-            if( strcmp( q, "SHA384" ) == 0 )
-            {
-                opt.md_alg = MBEDTLS_MD_SHA384;
-            }
-            else
-            if( strcmp( q, "SHA512" ) == 0 )
-            {
-                opt.md_alg = MBEDTLS_MD_SHA512;
-            }
-            else
-#endif /* MBEDTLS_SHA512_C */
-            {
+                mbedtls_printf( "Invalid argument for option %s\n", p );
                 goto usage;
             }
+            opt.md_alg = mbedtls_md_get_type( md_info );
         }
         else if( strcmp( p, "key_usage" ) == 0 )
         {
diff --git a/programs/x509/cert_write.c b/programs/x509/cert_write.c
index bccc3b7..f0f044d 100644
--- a/programs/x509/cert_write.c
+++ b/programs/x509/cert_write.c
@@ -145,8 +145,9 @@
     "    is_ca=%%d                default: 0 (disabled)\n"  \
     "    max_pathlen=%%d          default: -1 (none)\n"     \
     "    md=%%s                   default: SHA256\n"        \
-    "                            Supported values:\n"       \
-    "                            MD2, MD4, MD5, SHA1, SHA256, SHA512\n"\
+    "                            Supported values (if enabled):\n"      \
+    "                            MD2, MD4, MD5, RIPEMD160, SHA1,\n" \
+    "                            SHA224, SHA256, SHA384, SHA512\n" \
     "    version=%%d              default: 3\n"            \
     "                            Possible values: 1, 2, 3\n"\
     "    subject_identifier=%%s   default: 1\n"             \
@@ -380,23 +381,14 @@
         }
         else if( strcmp( p, "md" ) == 0 )
         {
-            if( strcmp( q, "SHA1" ) == 0 )
-                opt.md = MBEDTLS_MD_SHA1;
-            else if( strcmp( q, "SHA256" ) == 0 )
-                opt.md = MBEDTLS_MD_SHA256;
-            else if( strcmp( q, "SHA512" ) == 0 )
-                opt.md = MBEDTLS_MD_SHA512;
-            else if( strcmp( q, "MD2" ) == 0 )
-                opt.md = MBEDTLS_MD_MD2;
-            else if( strcmp( q, "MD4" ) == 0 )
-                opt.md = MBEDTLS_MD_MD4;
-            else if( strcmp( q, "MD5" ) == 0 )
-                opt.md = MBEDTLS_MD_MD5;
-            else
+            const mbedtls_md_info_t *md_info =
+                mbedtls_md_info_from_string( q );
+            if( md_info == NULL )
             {
                 mbedtls_printf( "Invalid argument for option %s\n", p );
                 goto usage;
             }
+            opt.md = mbedtls_md_get_type( md_info );
         }
         else if( strcmp( p, "version" ) == 0 )
         {
diff --git a/scripts/data_files/error.fmt b/scripts/data_files/error.fmt
index 162d93b..c5c8707 100644
--- a/scripts/data_files/error.fmt
+++ b/scripts/data_files/error.fmt
@@ -51,20 +51,19 @@
 #endif
 
 #if defined(MBEDTLS_ERROR_C) || defined(MBEDTLS_ERROR_STRERROR_DUMMY)
+
 #include "mbedtls/error.h"
-#include <string.h>
-#endif
+
+#if defined(MBEDTLS_ERROR_C)
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
 #else
 #define mbedtls_snprintf snprintf
-#define mbedtls_time_t   time_t
 #endif
 
-#if defined(MBEDTLS_ERROR_C)
-
 #include <stdio.h>
+#include <string.h>
 
 HEADER_INCLUDED
 
@@ -130,8 +129,6 @@
 
 #else /* MBEDTLS_ERROR_C */
 
-#if defined(MBEDTLS_ERROR_STRERROR_DUMMY)
-
 /*
  * Provide an non-function in case MBEDTLS_ERROR_C is not defined
  */
@@ -143,6 +140,6 @@
         buf[0] = '\0';
 }
 
-#endif /* MBEDTLS_ERROR_STRERROR_DUMMY */
-
 #endif /* MBEDTLS_ERROR_C */
+
+#endif /* MBEDTLS_ERROR_C || MBEDTLS_ERROR_STRERROR_DUMMY */
diff --git a/tests/compat.sh b/tests/compat.sh
index 7796bd2..8905430 100755
--- a/tests/compat.sh
+++ b/tests/compat.sh
@@ -117,12 +117,12 @@
 print_usage() {
     echo "Usage: $0"
     printf "  -h|--help\tPrint this help.\n"
-    printf "  -f|--filter\tOnly matching ciphersuites are tested (Default: '$FILTER')\n"
-    printf "  -e|--exclude\tMatching ciphersuites are excluded (Default: '$EXCLUDE')\n"
-    printf "  -m|--modes\tWhich modes to perform (Default: '$MODES')\n"
-    printf "  -t|--types\tWhich key exchange type to perform (Default: '$TYPES')\n"
-    printf "  -V|--verify\tWhich verification modes to perform (Default: '$VERIFIES')\n"
-    printf "  -p|--peers\tWhich peers to use (Default: '$PEERS')\n"
+    printf "  -f|--filter\tOnly matching ciphersuites are tested (Default: '%s')\n" "$FILTER"
+    printf "  -e|--exclude\tMatching ciphersuites are excluded (Default: '%s')\n" "$EXCLUDE"
+    printf "  -m|--modes\tWhich modes to perform (Default: '%s')\n" "$MODES"
+    printf "  -t|--types\tWhich key exchange type to perform (Default: '%s')\n" "$TYPES"
+    printf "  -V|--verify\tWhich verification modes to perform (Default: '%s')\n" "$VERIFIES"
+    printf "  -p|--peers\tWhich peers to use (Default: '%s')\n" "$PEERS"
     printf "            \tAlso available: GnuTLS (needs v3.2.15 or higher)\n"
     printf "  -M|--memcheck\tCheck memory leaks and errors.\n"
     printf "  -v|--verbose\tSet verbose output.\n"
@@ -1134,7 +1134,7 @@
     VERIF=$(echo $VERIFY | tr '[:upper:]' '[:lower:]')
     TITLE="`echo $1 | head -c1`->`echo $SERVER_NAME | head -c1`"
     TITLE="$TITLE $MODE,$VERIF $2"
-    printf "$TITLE "
+    printf "%s " "$TITLE"
     LEN=$(( 72 - `echo "$TITLE" | wc -c` ))
     for i in `seq 1 $LEN`; do printf '.'; done; printf ' '
 
diff --git a/tests/data_files/Makefile b/tests/data_files/Makefile
index 6c9e245..db4ee3b 100644
--- a/tests/data_files/Makefile
+++ b/tests/data_files/Makefile
@@ -13,8 +13,10 @@
 ## Tools
 OPENSSL ?= openssl
 FAKETIME ?= faketime
-MBEDTLS_CERT_WRITE ?= $(PWD)/../../programs/x509/cert_write
-MBEDTLS_CERT_REQ ?= $(PWD)/../../programs/x509/cert_req
+
+TOP_DIR = ../..
+MBEDTLS_CERT_WRITE ?= $(TOP_DIR)/programs/x509/cert_write
+MBEDTLS_CERT_REQ ?= $(TOP_DIR)/programs/x509/cert_req
 
 ## Build the generated test data. Note that since the final outputs
 ## are committed to the repository, this target should do nothing on a
@@ -1007,7 +1009,10 @@
 crl.pem: $(test_ca_crt) $(test_ca_key_file_rsa) $(test_ca_config_file)
 	$(OPENSSL) ca -gencrl -batch -cert $(test_ca_crt) -keyfile $(test_ca_key_file_rsa) -key $(test_ca_pwd_rsa) -config $(test_ca_server1_config_file) -md sha1 -crldays 3653 -out $@
 
-server1_all: crl.pem server1.crt server1.noauthid.crt server1.crt.openssl server1.v1.crt server1.v1.crt.openssl server1.key_usage.crt server1.key_usage_noauthid.crt server1.key_usage.crt.openssl server1.cert_type.crt server1.cert_type_noauthid.crt server1.cert_type.crt.openssl server1.der server1.der.openssl server1.v1.der server1.v1.der.openssl server1.key_usage.der server1.key_usage.der.openssl server1.cert_type.der server1.cert_type.der.openssl
+crl-futureRevocationDate.pem: $(test_ca_crt) $(test_ca_key_file_rsa) $(test_ca_config_file) test-ca.server1.future-crl.db  test-ca.server1.future-crl.opensslconf
+	$(FAKETIME) '2028-12-31' $(OPENSSL) ca -gencrl -config test-ca.server1.future-crl.opensslconf -crldays 365 -passin "pass:$(test_ca_pwd_rsa)" -out $@
+
+server1_all: crl.pem crl-futureRevocationDate.pem server1.crt server1.noauthid.crt server1.crt.openssl server1.v1.crt server1.v1.crt.openssl server1.key_usage.crt server1.key_usage_noauthid.crt server1.key_usage.crt.openssl server1.cert_type.crt server1.cert_type_noauthid.crt server1.cert_type.crt.openssl server1.der server1.der.openssl server1.v1.der server1.v1.der.openssl server1.key_usage.der server1.key_usage.der.openssl server1.cert_type.der server1.cert_type.der.openssl
 
 # server2*
 
diff --git a/tests/data_files/Readme-x509.txt b/tests/data_files/Readme-x509.txt
index 6f54ed0..d07241a 100644
--- a/tests/data_files/Readme-x509.txt
+++ b/tests/data_files/Readme-x509.txt
@@ -111,7 +111,7 @@
 - crl-ec-sha*.pem: (2) server6.crt
 - crl-future.pem: (2) server6.crt + unknown
 - crl-rsa-pss-*.pem: (1) server9{,badsign,with-ca}.crt + cert_sha384.crt + unknown
-- crl.pem, crl_expired.pem: (1) server1{,.cert_type,.key_usage,.v1}.crt + unknown
+- crl.pem, crl-futureRevocationDate.pem, crl_expired.pem: (1) server1{,.cert_type,.key_usage,.v1}.crt + unknown
 - crl_md*.pem: crl_sha*.pem: (1) same as crl.pem
 - crt_cat_*.pem: (1+2) concatenations in various orders:
     ec = crl-ec-sha256.pem, ecfut = crl-future.pem
diff --git a/tests/data_files/cert_md2.csr b/tests/data_files/cert_md2.csr
new file mode 100644
index 0000000..a8c39bd
--- /dev/null
+++ b/tests/data_files/cert_md2.csr
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIICgTCCAWkCAQAwPDELMAkGA1UEBhMCTkwxETAPBgNVBAoMCFBvbGFyU1NMMRow
+GAYDVQQDDBFQb2xhclNTTCBDZXJ0IE1EMjCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBAMh0xMy5+bV56UXZFGCwfbuT8msenzOtDY+KPFZl5dxE2cxmhQfV
++CewSjXQY54Kbhu32vB+q+4MEJOGSRg086gq0lf1LtQvdymEYU2CUI+nlUhw9W5N
+stUTw9Ia7eZD6kIU63TqwO0f1FdOqfOo7dLgwTBxMDIw1dP2CNBWT0aO8l/5PWeR
+iDAuQrLfffvlDHf/7DHAeI+/wn/KrWwh1o3Zi2qOb+Cb+BBWzLOOExXmNARmx+75
+Ng5qlfYJmgZn9GVx+MqksSXg/jyLNQRnuuBPdoX8f/w2a7XpzS0DYk6zPQDPr3ag
+aVaDatKo1OdQcea1NgV3BW17yOTE/UzVIV8CAwEAAaAAMA0GCSqGSIb3DQEBAgUA
+A4IBAQBPUqodRcH2ZUa8A3fQX/nxrIwWiLmQ9BaOI6G7vzEWVE1sxmkrHP+pXgi9
+1eFceN9xUBKEd+LmUPmHpObZ4nwRSprFj3DeIXpn9aSBr+jGY8RaaC9cMkaSq5Mb
+q65THEJ1xemIfZvbhjvNi/ycXXu/v1Gpj62dpIFGbm+o4AXQF2ocYGEM+X1u2eVn
+mnuuvPAHTllGjB0daTSYoQtMy3luPUEj0Yct3iVR1pUeTrHchOs9p5ACDZcf6D3x
+sm9atH2ZIaXo1c9SqHzdk/uLt/CwxQrn1WU1inwOkzjim2Yq9vWgpQypfGZdScXV
+oHOmuGG901WMMemzZXjoLi+8ZpVL
+-----END CERTIFICATE REQUEST-----
diff --git a/tests/data_files/cert_md4.csr b/tests/data_files/cert_md4.csr
new file mode 100644
index 0000000..d8a3dbf
--- /dev/null
+++ b/tests/data_files/cert_md4.csr
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIICgTCCAWkCAQAwPDELMAkGA1UEBhMCTkwxETAPBgNVBAoMCFBvbGFyU1NMMRow
+GAYDVQQDDBFQb2xhclNTTCBDZXJ0IE1ENDCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBAMh0xMy5+bV56UXZFGCwfbuT8msenzOtDY+KPFZl5dxE2cxmhQfV
++CewSjXQY54Kbhu32vB+q+4MEJOGSRg086gq0lf1LtQvdymEYU2CUI+nlUhw9W5N
+stUTw9Ia7eZD6kIU63TqwO0f1FdOqfOo7dLgwTBxMDIw1dP2CNBWT0aO8l/5PWeR
+iDAuQrLfffvlDHf/7DHAeI+/wn/KrWwh1o3Zi2qOb+Cb+BBWzLOOExXmNARmx+75
+Ng5qlfYJmgZn9GVx+MqksSXg/jyLNQRnuuBPdoX8f/w2a7XpzS0DYk6zPQDPr3ag
+aVaDatKo1OdQcea1NgV3BW17yOTE/UzVIV8CAwEAAaAAMA0GCSqGSIb3DQEBAwUA
+A4IBAQAztRb+vAecvhelhszzCctzmhGs4TGmr9h4zddZoQ8dTdy1OCsnmU+yz3oh
+oiQjy7UPLt8DS2ZKhGhvwPvtwFh5icMWQVnv2kE4Evz8xJT12VRw+U6L5rfKmf/L
+mVNxsuk17MDyBcMlwuNk+CHrYVdrXhSWUH3UCQQUH1iqqBMKmNiPa1UGU0budZ9X
+HZjn9uqyyOGy8l3hffqjDxsDjZyBDf5aqKIdnvukdrUiacPdUYVF0fwK8d1/1PA9
+dA4JjTvz+tTK6mL9Ic9Pv+64v1vwMU4Qu8IJHk5x3I0e7KuK2A/lK6az2Vb6FAh6
+MkGpWB68T8FRBoVrWLOh+a9yNwyp
+-----END CERTIFICATE REQUEST-----
diff --git a/tests/data_files/cert_md5.crt b/tests/data_files/cert_md5.crt
index 8b4d089..d69b0b7 100644
--- a/tests/data_files/cert_md5.crt
+++ b/tests/data_files/cert_md5.crt
@@ -3,18 +3,18 @@
 MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN
 MTkwMjEwMTQ0NDA2WhcNMjkwMjEwMTQ0NDA2WjA8MQswCQYDVQQGEwJOTDERMA8G
 A1UECgwIUG9sYXJTU0wxGjAYBgNVBAMMEVBvbGFyU1NMIENlcnQgTUQ1MIIBIjAN
-BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqQIfPUBq1VVTi/027oJlLhVhXom/
-uOhFkNvuiBZS0/FDUEeWEllkh2v9K+BG+XO+3c+S4ZFb7Wagb4kpeUWA0INq1UFD
-d185fAkER4KwVzlw7aPsFRkeqDMIR8EFQqn9TMO0390GH00QUUBncxMPQPhtgSVf
-CrFTxjB+FTms+Vruf5KepgVb5xOXhbUjktnUJAbVCSWJdQfdphqPPwkZvq1lLGTr
-lZvc/kFeF6babFtpzAK6FCwWJJxK3M3Q91Jnc/EtoCP9fvQxyi1wyokLBNsupk9w
-bp7OvViJ4lNZnm5akmXiiD8MlBmj3eXonZUT7Snbq3AS3FrKaxerUoJUsQIDAQAB
-o00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBQfdNY/KcF0dEU7BRIsPai9Q1kCpjAf
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyHTEzLn5tXnpRdkUYLB9u5Pyax6f
+M60Nj4o8VmXl3ETZzGaFB9X4J7BKNdBjngpuG7fa8H6r7gwQk4ZJGDTzqCrSV/Uu
+1C93KYRhTYJQj6eVSHD1bk2y1RPD0hrt5kPqQhTrdOrA7R/UV06p86jt0uDBMHEw
+MjDV0/YI0FZPRo7yX/k9Z5GIMC5Cst99++UMd//sMcB4j7/Cf8qtbCHWjdmLao5v
+4Jv4EFbMs44TFeY0BGbH7vk2DmqV9gmaBmf0ZXH4yqSxJeD+PIs1BGe64E92hfx/
+/DZrtenNLQNiTrM9AM+vdqBpVoNq0qjU51Bx5rU2BXcFbXvI5MT9TNUhXwIDAQAB
+o00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBRxoQBzckAvVHZeM/xSj7zx3WtGITAf
 BgNVHSMEGDAWgBS0WuSls97SUva51aaVD+s+vMf9/zANBgkqhkiG9w0BAQQFAAOC
-AQEAPO/yXYVCQfm1gRzYoPP4T8Dd7jfpS0Yz5hAWMDi73aXufk9ltGdXauQxA4Pu
-NQLWBMFMtJyO2OUb0p+oPGCxQayLx1sIjS9Gfy70xHlL3jnZy4kLXtkiARz8ZptW
-krxzQh017mXIn8W2VGYWA1gCNrg/Xb3VtlxVCzPa2zGCkIJHKe/dqNtKY3xx/SEQ
-gsVvdT8lpI8HfeElBfWvFxGps77pvE2HDcAdrIkjrsBWoSIq6CqIQjyW7WSN7UgI
-bTczqejHkrggI8yWIIoDAiUX9OGT76Mv4wpmOPww8hqoVfpvvPQ2l6byVNJYPj/L
-oiUV6sDYenOgMJ3Tf7UzTR91MA==
+AQEANsxVCbbev5mngG0+PvQ4y/s0jNjz6i+tn4fTOtMNBOC77clNju65vlHWqD9Y
+rZP6wqGSzdYbOoojCq0l65T6os1CFcaygIpUSFF57MbfTiiwZaLF93qf9Jf+VHln
+CQA/tQolZJDjef8LXAYK68GVVxenZI9ITnMIg6Qd9vpHqK44a6xWU226pG7g+6ae
+97dhpLsYMxggv6t/ATFt7KiIXC4cOQBzQobRfsRcxWlaOxlFEXeCFoonQaHHaU9c
+KqLO1sqygLIhP7ZA2qmfodVLc5B3WxrogaupPCbpKNdieR43HvGZ+3ig/gLjyLg1
+L8qiSesxaHvjtkW9N7sjPxRS8Q==
 -----END CERTIFICATE-----
diff --git a/tests/data_files/cert_md5.csr b/tests/data_files/cert_md5.csr
new file mode 100644
index 0000000..dc6792d
--- /dev/null
+++ b/tests/data_files/cert_md5.csr
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIICgTCCAWkCAQAwPDELMAkGA1UEBhMCTkwxETAPBgNVBAoMCFBvbGFyU1NMMRow
+GAYDVQQDDBFQb2xhclNTTCBDZXJ0IE1ENTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBAMh0xMy5+bV56UXZFGCwfbuT8msenzOtDY+KPFZl5dxE2cxmhQfV
++CewSjXQY54Kbhu32vB+q+4MEJOGSRg086gq0lf1LtQvdymEYU2CUI+nlUhw9W5N
+stUTw9Ia7eZD6kIU63TqwO0f1FdOqfOo7dLgwTBxMDIw1dP2CNBWT0aO8l/5PWeR
+iDAuQrLfffvlDHf/7DHAeI+/wn/KrWwh1o3Zi2qOb+Cb+BBWzLOOExXmNARmx+75
+Ng5qlfYJmgZn9GVx+MqksSXg/jyLNQRnuuBPdoX8f/w2a7XpzS0DYk6zPQDPr3ag
+aVaDatKo1OdQcea1NgV3BW17yOTE/UzVIV8CAwEAAaAAMA0GCSqGSIb3DQEBBAUA
+A4IBAQBNEvxgn3Pc62hsMgMz33IdeNpazeK3ae2gwQQFgL7qMp/kskfpIKF4m8eB
+YrmjKn9cqszRD606/ZtWYDwINUUc6O7bQGmpGIFd7bSPm/pbsajc6R7kzA/tD/bk
+G5zqu9Bj0x92hEwdku0zY+Hx9PgT2dK8M72iFylHBwT3X1tNyXhh7xWJ9RlAfSvN
+KdS6s3kRjK4qcir0MnflV5f2HD6r1v9cSVyme6eVLvOmup89z0cihH7NDwDJaYbi
+oqcKXFbro8/2ruEzPUS6U8NA9cjlX9DW8buIu4cQACVx5YevlwKoayYfXcRRvIFo
+OLiPq14TuZj3c0+HFOxWj4UBAjvI
+-----END CERTIFICATE REQUEST-----
diff --git a/tests/data_files/crl-futureRevocationDate.pem b/tests/data_files/crl-futureRevocationDate.pem
new file mode 100644
index 0000000..f147a8f
--- /dev/null
+++ b/tests/data_files/crl-futureRevocationDate.pem
@@ -0,0 +1,11 @@
+-----BEGIN X509 CRL-----
+MIIBqzCBlDANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDERMA8GA1UECgwI
+UG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EXDTI4MTIzMDIzMDAw
+MFoXDTI5MTIzMDIzMDAwMFowKDASAgEBFw0yOTAxMDExMjQ0MDdaMBICAQMXDTI5
+MDEwMTEyNDQwN1owDQYJKoZIhvcNAQEFBQADggEBAKbL1mDpzCbLJmRZKM2KHPvK
+ijS4UMnanzzYpLAwom1NI69v2fE1/EfiXv0empE6mFqnLwOG4ZP8fECfxjMXO2Ee
+VhxYiRjly6q9hfIUk1e+N9ct8unNnLEBvf6Syfy9+FSO3Q/ahljpYlXsXxg62WXl
+9xp5b5Ok+/0sCv0eL5uFQKXQa8hS9dZo6py7jvFDQC+wVau1mXjQW85iXMLm7vik
+4lR+kfZloeq1jIbsx8cdMi32YVt7uccaqoFcjtrdrWfGmi0wvlDc8K5J0l4tIxZY
+9P+T4fzSgQLdqGZ3xADheEaGTRVL/5oe5L4zRH32BZONMFCijv+j1SpWLxHE8cM=
+-----END X509 CRL-----
diff --git a/tests/data_files/test-ca.server1.future-crl.db b/tests/data_files/test-ca.server1.future-crl.db
new file mode 100644
index 0000000..763aa12
--- /dev/null
+++ b/tests/data_files/test-ca.server1.future-crl.db
@@ -0,0 +1,2 @@
+R	210212144406Z	290101124407Z	01	unknown	/C=NL/O=PolarSSL/CN=PolarSSL Server 1
+R	210212144400Z	290101124407Z	03	unknown	/C=NL/O=PolarSSL/CN=PolarSSL Test CA
diff --git a/tests/data_files/test-ca.server1.future-crl.opensslconf b/tests/data_files/test-ca.server1.future-crl.opensslconf
new file mode 100644
index 0000000..e9ce754
--- /dev/null
+++ b/tests/data_files/test-ca.server1.future-crl.opensslconf
@@ -0,0 +1,18 @@
+ [ ca ]
+ default_ca             = test-ca
+
+ [ test-ca ]
+ certificate            = test-ca.crt
+ private_key            = test-ca.key
+ serial                 = test-ca.server1.serial
+ default_md             = sha1
+ default_startdate      = 110212144406Z
+ default_enddate        = 210212144406Z
+ new_certs_dir          = ./
+ database               = ./test-ca.server1.future-crl.db
+ policy                 = policy_match
+
+ [policy_match]
+ countryName            = supplied
+ organizationName       = supplied
+ commonName             = supplied
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 83299c9..1e56c3e 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -185,6 +185,9 @@
         export MAKEFLAGS="-j"
     fi
 
+    # Include more verbose output for failing tests run by CMake
+    export CTEST_OUTPUT_ON_FAILURE=1
+
     # CFLAGS and LDFLAGS for Asan builds that don't use CMake
     ASAN_CFLAGS='-Werror -Wall -Wextra -fsanitize=address,undefined -fno-sanitize-recover=all'
 
@@ -887,11 +890,21 @@
     CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
     make
 
-    msg "test: no HMAC_DRBG"
+    msg "test: Full minus HMAC_DRBG - main suites"
     make test
 
-    # No ssl-opt.sh/compat.sh as they never use HMAC_DRBG so far,
-    # so there's little value in running those lengthy tests here.
+    # Normally our ECDSA implementation uses deterministic ECDSA. But since
+    # HMAC_DRBG is disabled in this configuration, randomized ECDSA is used
+    # instead.
+    # Test SSL with non-deterministic ECDSA. Only test features that
+    # might be affected by how ECDSA signature is performed.
+    msg "test: Full minus HMAC_DRBG - ssl-opt.sh (subset)"
+    if_build_succeeded tests/ssl-opt.sh -f 'Default\|SSL async private: sign'
+
+    # To save time, only test one protocol version, since this part of
+    # the protocol is identical in (D)TLS up to 1.2.
+    msg "test: Full minus HMAC_DRBG - compat.sh (ECDSA)"
+    if_build_succeeded tests/compat.sh -m tls1_2 -t 'ECDSA'
 }
 
 component_test_no_drbg_all_hashes () {
@@ -1285,6 +1298,16 @@
     make test
 }
 
+component_test_no_date_time () {
+    msg "build: default config without MBEDTLS_HAVE_TIME_DATE"
+    scripts/config.pl unset MBEDTLS_HAVE_TIME_DATE
+    CC=gcc cmake
+    make
+
+    msg "test: !MBEDTLS_HAVE_TIME_DATE - main suites"
+    make test
+}
+
 component_test_platform_calloc_macro () {
     msg "build: MBEDTLS_PLATFORM_{CALLOC/FREE}_MACRO enabled (ASan build)"
     scripts/config.pl set MBEDTLS_PLATFORM_MEMORY
@@ -1301,7 +1324,7 @@
     msg "build: malloc(0) returns NULL (ASan+UBSan build)"
     scripts/config.pl full
     scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C
-    make CC=gcc CFLAGS="'-DMBEDTLS_CONFIG_FILE=\"$PWD/tests/configs/config-wrapper-malloc-0-null.h\"' -O -Werror -Wall -Wextra -fsanitize=address,undefined" LDFLAGS='-fsanitize=address,undefined'
+    make CC=gcc CFLAGS="'-DMBEDTLS_CONFIG_FILE=\"$PWD/tests/configs/config-wrapper-malloc-0-null.h\"' -O $ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS"
 
     msg "test: malloc(0) returns NULL (ASan+UBSan build)"
     make test
@@ -1488,6 +1511,20 @@
     make test
 }
 
+component_test_no_strings () {
+    msg "build: no strings" # ~10s
+    scripts/config.pl full
+    # Disable options that activate a large amount of string constants.
+    scripts/config.pl unset MBEDTLS_DEBUG_C
+    scripts/config.pl unset MBEDTLS_ERROR_C
+    scripts/config.pl set MBEDTLS_ERROR_STRERROR_DUMMY
+    scripts/config.pl unset MBEDTLS_VERSION_FEATURES
+    make CFLAGS='-Werror -Os'
+
+    msg "test: no strings" # ~ 10s
+    make test
+}
+
 component_build_arm_none_eabi_gcc () {
     msg "build: ${ARM_NONE_EABI_GCC_PREFIX}gcc -O1" # ~ 10s
     scripts/config.pl baremetal
diff --git a/tests/scripts/check-names.sh b/tests/scripts/check-names.sh
index 5f3b5a7..7c979bc 100755
--- a/tests/scripts/check-names.sh
+++ b/tests/scripts/check-names.sh
@@ -92,7 +92,7 @@
 diff macros identifiers | sed -n -e 's/< //p' > actual-macros
 
 for THING in actual-macros enum-consts; do
-    printf "Names of $THING: "
+    printf 'Names of %s: ' "$THING"
     test -r $THING
     BAD=$( grep -v '^MBEDTLS_[0-9A-Z_]*[0-9A-Z]$' $THING || true )
     if [ "x$BAD" = "x" ]; then
@@ -105,7 +105,7 @@
 done
 
 for THING in identifiers; do
-    printf "Names of $THING: "
+    printf 'Names of %s: ' "$THING"
     test -r $THING
     BAD=$( grep -v '^mbedtls_[0-9a-z_]*[0-9a-z]$' $THING || true )
     if [ "x$BAD" = "x" ]; then
diff --git a/tests/scripts/test-ref-configs.pl b/tests/scripts/test-ref-configs.pl
index a8bfa6e..94fc335 100755
--- a/tests/scripts/test-ref-configs.pl
+++ b/tests/scripts/test-ref-configs.pl
@@ -55,15 +55,17 @@
 use strict;
 
 my %configs = (
+    'config-ccm-psk-tls1_2.h' => {
+        'compat' => '-m tls1_2 -f \'^TLS-PSK-WITH-AES-...-CCM-8\'',
+    },
     'config-mini-tls1_1.h' => {
         'compat' => '-m tls1_1 -f \'^DES-CBC3-SHA$\|^TLS-RSA-WITH-3DES-EDE-CBC-SHA$\'',
     },
+    'config-no-entropy.h' => {
+    },
     'config-suite-b.h' => {
         'compat' => "-m tls1_2 -f 'ECDHE-ECDSA.*AES.*GCM' -p mbedTLS",
     },
-    'config-ccm-psk-tls1_2.h' => {
-        'compat' => '-m tls1_2 -f \'^TLS-PSK-WITH-AES-...-CCM-8\'',
-    },
     'config-thread.h' => {
         'opt' => '-f ECJPAKE.*nolog',
     },
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index af6b0af..b6c0322 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -130,8 +130,8 @@
     echo "Usage: $0 [options]"
     printf "  -h|--help\tPrint this help.\n"
     printf "  -m|--memcheck\tCheck memory leaks and errors.\n"
-    printf "  -f|--filter\tOnly matching tests are executed (BRE; default: '$FILTER')\n"
-    printf "  -e|--exclude\tMatching tests are excluded (BRE; default: '$EXCLUDE')\n"
+    printf "  -f|--filter\tOnly matching tests are executed (BRE)\n"
+    printf "  -e|--exclude\tMatching tests are excluded (BRE)\n"
     printf "  -n|--number\tExecute only numbered test (comma-separated, e.g. '245,256')\n"
     printf "  -s|--show-numbers\tShow test numbers in front of test names\n"
     printf "  -p|--preserve-logs\tPreserve logs of successful tests as well\n"
@@ -384,7 +384,7 @@
     fi
 
     LINE="$LINE$1"
-    printf "$LINE "
+    printf "%s " "$LINE"
     LEN=$(( 72 - `echo "$LINE" | wc -c` ))
     for i in `seq 1 $LEN`; do printf '.'; done
     printf ' '
@@ -662,12 +662,12 @@
         fi
 
         check_osrv_dtls
-        printf "# $NAME\n$SRV_CMD\n" > $SRV_OUT
+        printf '# %s\n%s\n' "$NAME" "$SRV_CMD" > $SRV_OUT
         provide_input | $SRV_CMD >> $SRV_OUT 2>&1 &
         SRV_PID=$!
         wait_server_start "$SRV_PORT" "$SRV_PID"
 
-        printf "# $NAME\n$CLI_CMD\n" > $CLI_OUT
+        printf '# %s\n%s\n' "$NAME" "$CLI_CMD" > $CLI_OUT
         eval "$CLI_CMD" >> $CLI_OUT 2>&1 &
         wait_client_done
 
@@ -676,6 +676,7 @@
         # terminate the server (and the proxy)
         kill $SRV_PID
         wait $SRV_PID
+        SRV_RET=$?
 
         if [ -n "$PXY_CMD" ]; then
             kill $PXY_PID >/dev/null 2>&1
@@ -709,9 +710,11 @@
         fi
     fi
 
-    # check server exit code
-    if [ $? != 0 ]; then
-        fail "server fail"
+    # Check server exit code (only for Mbed TLS: GnuTLS and OpenSSL don't
+    # exit with status 0 when interrupted by a signal, and we don't really
+    # care anyway), in case e.g. the server reports a memory leak.
+    if [ $SRV_RET != 0 ] && is_polar "$SRV_CMD"; then
+        fail "Server exited with status $SRV_RET"
         return
     fi
 
@@ -1877,12 +1880,12 @@
 # Tests for Max Fragment Length extension
 
 if [ "$MAX_CONTENT_LEN" -lt "4096" ]; then
-    printf "${CONFIG_H} defines MBEDTLS_SSL_MAX_CONTENT_LEN to be less than 4096. Fragment length tests will fail.\n"
+    printf '%s defines MBEDTLS_SSL_MAX_CONTENT_LEN to be less than 4096. Fragment length tests will fail.\n' "${CONFIG_H}"
     exit 1
 fi
 
 if [ $MAX_CONTENT_LEN -ne 16384 ]; then
-    printf "Using non-default maximum content length $MAX_CONTENT_LEN\n"
+    echo "Using non-default maximum content length $MAX_CONTENT_LEN"
 fi
 
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
@@ -2823,14 +2826,14 @@
 MAX_IM_CA_CONFIG=$( ../scripts/config.pl get MBEDTLS_X509_MAX_INTERMEDIATE_CA)
 
 if [ -n "$MAX_IM_CA_CONFIG" ] && [ "$MAX_IM_CA_CONFIG" -ne "$MAX_IM_CA" ]; then
-    printf "The ${CONFIG_H} file contains a value for the configuration of\n"
-    printf "MBEDTLS_X509_MAX_INTERMEDIATE_CA that is different from the script’s\n"
-    printf "test value of ${MAX_IM_CA}. \n"
-    printf "\n"
-    printf "The tests assume this value and if it changes, the tests in this\n"
-    printf "script should also be adjusted.\n"
-    printf "\n"
+    cat <<EOF
+${CONFIG_H} contains a value for the configuration of
+MBEDTLS_X509_MAX_INTERMEDIATE_CA that is different from the script's
+test value of ${MAX_IM_CA}.
 
+The tests assume this value and if it changes, the tests in this
+script should also be adjusted.
+EOF
     exit 1
 fi
 
diff --git a/tests/suites/helpers.function b/tests/suites/helpers.function
index 4f46ea9..ceac670 100644
--- a/tests/suites/helpers.function
+++ b/tests/suites/helpers.function
@@ -46,6 +46,12 @@
 #include <strings.h>
 #endif
 
+#if defined(MBEDTLS_THREADING_C) && defined(MBEDTLS_THREADING_PTHREAD) && \
+    defined(MBEDTLS_TEST_HOOKS)
+#include "mbedtls/threading.h"
+#define MBEDTLS_TEST_MUTEX_USAGE
+#endif
+
 /*
  * Define the two macros
  *
@@ -154,6 +160,27 @@
        }                                                    \
     } while( 0 )
 
+/** Compare two buffers and fail the test case if they differ.
+ *
+ * This macro expands to an instruction, not an expression.
+ * It may jump to the \c exit label.
+ *
+ * \param p1        Pointer to the start of the first buffer.
+ * \param size1     Size of the first buffer in bytes.
+ *                  This expression may be evaluated multiple times.
+ * \param p2        Pointer to the start of the second buffer.
+ * \param size2     Size of the second buffer in bytes.
+ *                  This expression may be evaluated multiple times.
+ */
+#define ASSERT_COMPARE( p1, size1, p2, size2 )                          \
+    do                                                                  \
+    {                                                                   \
+        TEST_ASSERT( ( size1 ) == ( size2 ) );                          \
+        if( ( size1 ) != 0 )                                            \
+            TEST_ASSERT( memcmp( ( p1 ), ( p2 ), ( size1 ) ) == 0 );    \
+    }                                                                   \
+    while( 0 )
+
 /**
  * \brief   This macro tests the expression passed to it and skips the
  *          running test if it doesn't evaluate to 'true'.
@@ -350,6 +377,9 @@
     const char *test;
     const char *filename;
     int line_no;
+#if defined(MBEDTLS_TEST_MUTEX_USAGE)
+    const char *mutex_usage_error;
+#endif
 }
 test_info;
 
@@ -382,6 +412,12 @@
 
 void test_fail( const char *test, int line_no, const char* filename )
 {
+    if( test_info.result == TEST_RESULT_FAILED )
+    {
+        /* We've already recorded the test as having failed. Don't
+         * overwrite any previous information about the failure. */
+        return;
+    }
     test_info.result = TEST_RESULT_FAILED;
     test_info.test = test;
     test_info.line_no = line_no;
@@ -732,7 +768,7 @@
     return( 0 );
 }
 
-int hexcmp( uint8_t * a, uint8_t * b, uint32_t a_len, uint32_t b_len )
+int mbedtls_test_hexcmp( uint8_t * a, uint8_t * b, uint32_t a_len, uint32_t b_len )
 {
     int ret = 0;
     uint32_t i = 0;
@@ -750,3 +786,202 @@
     }
     return ret;
 }
+
+#if defined(MBEDTLS_TEST_MUTEX_USAGE)
+/** Mutex usage verification framework.
+ *
+ * The mutex usage verification code below aims to detect bad usage of
+ * Mbed TLS's mutex abstraction layer at runtime. Note that this is solely
+ * about the use of the mutex itself, not about checking whether the mutex
+ * correctly protects whatever it is supposed to protect.
+ *
+ * The normal usage of a mutex is:
+ * ```
+ * digraph mutex_states {
+ *   "UNINITIALIZED"; // the initial state
+ *   "IDLE";
+ *   "FREED";
+ *   "LOCKED";
+ *   "UNINITIALIZED" -> "IDLE" [label="init"];
+ *   "FREED" -> "IDLE" [label="init"];
+ *   "IDLE" -> "LOCKED" [label="lock"];
+ *   "LOCKED" -> "IDLE" [label="unlock"];
+ *   "IDLE" -> "FREED" [label="free"];
+ * }
+ * ```
+ *
+ * All bad transitions that can be unambiguously detected are reported.
+ * An attempt to use an uninitialized mutex cannot be detected in general
+ * since the memory content may happen to denote a valid state. For the same
+ * reason, a double init cannot be detected.
+ * All-bits-zero is the state of a freed mutex, which is distinct from an
+ * initialized mutex, so attempting to use zero-initialized memory as a mutex
+ * without calling the init function is detected.
+ *
+ * The framework attempts to detect missing calls to init and free by counting
+ * calls to init and free. If there are more calls to init than free, this
+ * means that a mutex is not being freed somewhere, which is a memory leak
+ * on platforms where a mutex consumes resources other than the
+ * mbedtls_threading_mutex_t object itself. If there are more calls to free
+ * than init, this indicates a missing init, which is likely to be detected
+ * by an attempt to lock the mutex as well. A limitation of this framework is
+ * that it cannot detect scenarios where there is exactly the same number of
+ * calls to init and free but the calls don't match. A bug like this is
+ * unlikely to happen uniformly throughout the whole test suite though.
+ *
+ * If an error is detected, this framework will report what happened and the
+ * test case will be marked as failed. Unfortunately, the error report cannot
+ * indicate the exact location of the problematic call. To locate the error,
+ * use a debugger and set a breakpoint on mbedtls_test_mutex_usage_error().
+ */
+enum value_of_mutex_is_valid_field
+{
+    /* Potential values for the is_valid field of mbedtls_threading_mutex_t.
+     * Note that MUTEX_FREED must be 0 and MUTEX_IDLE must be 1 for
+     * compatibility with threading_mutex_init_pthread() and
+     * threading_mutex_free_pthread(). MUTEX_LOCKED could be any nonzero
+     * value. */
+    MUTEX_FREED = 0, //!< Set by threading_mutex_free_pthread
+    MUTEX_IDLE = 1, //!< Set by threading_mutex_init_pthread and by our unlock
+    MUTEX_LOCKED = 2, //!< Set by our lock
+};
+
+typedef struct
+{
+    void (*init)( mbedtls_threading_mutex_t * );
+    void (*free)( mbedtls_threading_mutex_t * );
+    int (*lock)( mbedtls_threading_mutex_t * );
+    int (*unlock)( mbedtls_threading_mutex_t * );
+} mutex_functions_t;
+static mutex_functions_t mutex_functions;
+
+/** The total number of calls to mbedtls_mutex_init(), minus the total number
+ * of calls to mbedtls_mutex_free().
+ *
+ * Reset to 0 after each test case.
+ */
+static int live_mutexes;
+
+static void mbedtls_test_mutex_usage_error( mbedtls_threading_mutex_t *mutex,
+                                            const char *msg )
+{
+    (void) mutex;
+    if( test_info.mutex_usage_error == NULL )
+        test_info.mutex_usage_error = msg;
+    mbedtls_fprintf( stdout, "[mutex: %s] ", msg );
+    /* Don't mark the test as failed yet. This way, if the test fails later
+     * for a functional reason, the test framework will report the message
+     * and location for this functional reason. If the test passes,
+     * mbedtls_test_mutex_usage_check() will mark it as failed. */
+}
+
+static void mbedtls_test_wrap_mutex_init( mbedtls_threading_mutex_t *mutex )
+{
+    mutex_functions.init( mutex );
+    if( mutex->is_valid )
+        ++live_mutexes;
+}
+
+static void mbedtls_test_wrap_mutex_free( mbedtls_threading_mutex_t *mutex )
+{
+    switch( mutex->is_valid )
+    {
+        case MUTEX_FREED:
+            mbedtls_test_mutex_usage_error( mutex, "free without init or double free" );
+            break;
+        case MUTEX_IDLE:
+            /* Do nothing. The underlying free function will reset is_valid
+             * to 0. */
+            break;
+        case MUTEX_LOCKED:
+            mbedtls_test_mutex_usage_error( mutex, "free without unlock" );
+            break;
+        default:
+            mbedtls_test_mutex_usage_error( mutex, "corrupted state" );
+            break;
+    }
+    if( mutex->is_valid )
+        --live_mutexes;
+    mutex_functions.free( mutex );
+}
+
+static int mbedtls_test_wrap_mutex_lock( mbedtls_threading_mutex_t *mutex )
+{
+    int ret = mutex_functions.lock( mutex );
+    switch( mutex->is_valid )
+    {
+        case MUTEX_FREED:
+            mbedtls_test_mutex_usage_error( mutex, "lock without init" );
+            break;
+        case MUTEX_IDLE:
+            if( ret == 0 )
+                mutex->is_valid = 2;
+            break;
+        case MUTEX_LOCKED:
+            mbedtls_test_mutex_usage_error( mutex, "double lock" );
+            break;
+        default:
+            mbedtls_test_mutex_usage_error( mutex, "corrupted state" );
+            break;
+    }
+    return( ret );
+}
+
+static int mbedtls_test_wrap_mutex_unlock( mbedtls_threading_mutex_t *mutex )
+{
+    int ret = mutex_functions.unlock( mutex );
+    switch( mutex->is_valid )
+    {
+        case MUTEX_FREED:
+            mbedtls_test_mutex_usage_error( mutex, "unlock without init" );
+            break;
+        case MUTEX_IDLE:
+            mbedtls_test_mutex_usage_error( mutex, "unlock without lock" );
+            break;
+        case MUTEX_LOCKED:
+            if( ret == 0 )
+                mutex->is_valid = MUTEX_IDLE;
+            break;
+        default:
+            mbedtls_test_mutex_usage_error( mutex, "corrupted state" );
+            break;
+    }
+    return( ret );
+}
+
+static void mbedtls_test_mutex_usage_init( void )
+{
+    mutex_functions.init = mbedtls_mutex_init;
+    mutex_functions.free = mbedtls_mutex_free;
+    mutex_functions.lock = mbedtls_mutex_lock;
+    mutex_functions.unlock = mbedtls_mutex_unlock;
+    mbedtls_mutex_init = &mbedtls_test_wrap_mutex_init;
+    mbedtls_mutex_free = &mbedtls_test_wrap_mutex_free;
+    mbedtls_mutex_lock = &mbedtls_test_wrap_mutex_lock;
+    mbedtls_mutex_unlock = &mbedtls_test_wrap_mutex_unlock;
+}
+
+static void mbedtls_test_mutex_usage_check( void )
+{
+    if( live_mutexes != 0 )
+    {
+        /* A positive number (more init than free) means that a mutex resource
+         * is leaking (on platforms where a mutex consumes more than the
+         * mbedtls_threading_mutex_t object itself). The rare case of a
+         * negative number means a missing init somewhere. */
+        mbedtls_fprintf( stdout, "[mutex: %d leaked] ", live_mutexes );
+        live_mutexes = 0;
+        if( test_info.mutex_usage_error == NULL )
+            test_info.mutex_usage_error = "missing free";
+    }
+    if( test_info.mutex_usage_error != NULL &&
+        test_info.result != TEST_RESULT_FAILED )
+    {
+        /* Functionally, the test passed. But there was a mutex usage error,
+         * so mark the test as failed after all. */
+        test_fail( "Mutex usage error", __LINE__, __FILE__ );
+    }
+    test_info.mutex_usage_error = NULL;
+}
+
+#endif /* MBEDTLS_TEST_MUTEX_USAGE */
diff --git a/tests/suites/host_test.function b/tests/suites/host_test.function
index ca51e7b..3f8a945 100644
--- a/tests/suites/host_test.function
+++ b/tests/suites/host_test.function
@@ -330,7 +330,7 @@
 #if defined(__GNUC__)
 __attribute__((__noinline__))
 #endif
-static int test_snprintf( size_t n, const char ref_buf[10], int ref_ret )
+static int test_snprintf( size_t n, const char *ref_buf, int ref_ret )
 {
     int ret;
     char buf[10] = "xxxxxxxxx";
@@ -412,6 +412,10 @@
     mbedtls_memory_buffer_alloc_init( alloc_buf, sizeof( alloc_buf ) );
 #endif
 
+#if defined(MBEDTLS_TEST_MUTEX_USAGE)
+    mbedtls_test_mutex_usage_init( );
+#endif
+
     /*
      * The C standard doesn't guarantee that all-bits-0 is the representation
      * of a NULL pointer. We do however use that in our code for initializing
diff --git a/tests/suites/main_test.function b/tests/suites/main_test.function
index f516d2c..2aecf81 100644
--- a/tests/suites/main_test.function
+++ b/tests/suites/main_test.function
@@ -23,6 +23,15 @@
 #endif
 #endif
 
+/*
+ * for arc4random_buf() from <stdlib.h>
+ */
+#if defined(__NetBSD__)
+#define _NETBSD_SOURCE 1
+#elif defined(__OpenBSD__)
+#define _BSD_SOURCE 1
+#endif
+
 #if !defined(MBEDTLS_CONFIG_FILE)
 #include <mbedtls/config.h>
 #else
@@ -167,6 +176,10 @@
 #else
     fp( params );
 #endif
+
+#if defined(MBEDTLS_TEST_MUTEX_USAGE)
+    mbedtls_test_mutex_usage_check( );
+#endif /* MBEDTLS_TEST_MUTEX_USAGE */
 }
 
 /**
diff --git a/tests/suites/test_suite_aes.function b/tests/suites/test_suite_aes.function
index 3374a07..23bf83d 100644
--- a/tests/suites/test_suite_aes.function
+++ b/tests/suites/test_suite_aes.function
@@ -9,7 +9,7 @@
 
 /* BEGIN_CASE */
 void aes_encrypt_ecb( data_t * key_str, data_t * src_str,
-                      data_t * hex_dst_string, int setkey_result )
+                      data_t * dst, int setkey_result )
 {
     unsigned char output[100];
     mbedtls_aes_context ctx;
@@ -23,7 +23,7 @@
     {
         TEST_ASSERT( mbedtls_aes_crypt_ecb( &ctx, MBEDTLS_AES_ENCRYPT, src_str->x, output ) == 0 );
 
-        TEST_ASSERT( hexcmp( output, hex_dst_string->x, 16, hex_dst_string->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 16, dst->len ) == 0 );
     }
 
 exit:
@@ -33,7 +33,7 @@
 
 /* BEGIN_CASE */
 void aes_decrypt_ecb( data_t * key_str, data_t * src_str,
-                      data_t * hex_dst_string, int setkey_result )
+                      data_t * dst, int setkey_result )
 {
     unsigned char output[100];
     mbedtls_aes_context ctx;
@@ -47,7 +47,7 @@
     {
         TEST_ASSERT( mbedtls_aes_crypt_ecb( &ctx, MBEDTLS_AES_DECRYPT, src_str->x, output ) == 0 );
 
-        TEST_ASSERT( hexcmp( output, hex_dst_string->x, 16, hex_dst_string->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 16, dst->len ) == 0 );
     }
 
 exit:
@@ -57,7 +57,7 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
 void aes_encrypt_cbc( data_t * key_str, data_t * iv_str,
-                      data_t * src_str, data_t * hex_dst_string,
+                      data_t * src_str, data_t * dst,
                       int cbc_result )
 {
     unsigned char output[100];
@@ -72,7 +72,8 @@
     if( cbc_result == 0 )
     {
 
-        TEST_ASSERT( hexcmp( output, hex_dst_string->x, src_str->len, hex_dst_string->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x,
+                                          src_str->len, dst->len ) == 0 );
     }
 
 exit:
@@ -82,7 +83,7 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
 void aes_decrypt_cbc( data_t * key_str, data_t * iv_str,
-                      data_t * src_str, data_t * hex_dst_string,
+                      data_t * src_str, data_t * dst,
                       int cbc_result )
 {
     unsigned char output[100];
@@ -96,7 +97,8 @@
     if( cbc_result == 0)
     {
 
-        TEST_ASSERT( hexcmp( output, hex_dst_string->x, src_str->len, hex_dst_string->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x,
+                                          src_str->len, dst->len ) == 0 );
     }
 
 exit:
@@ -228,7 +230,7 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CFB */
 void aes_encrypt_cfb128( data_t * key_str, data_t * iv_str,
-                         data_t * src_str, data_t * hex_dst_string )
+                         data_t * src_str, data_t * dst )
 {
     unsigned char output[100];
     mbedtls_aes_context ctx;
@@ -241,7 +243,7 @@
     mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 );
     TEST_ASSERT( mbedtls_aes_crypt_cfb128( &ctx, MBEDTLS_AES_ENCRYPT, 16, &iv_offset, iv_str->x, src_str->x, output ) == 0 );
 
-    TEST_ASSERT( hexcmp( output, hex_dst_string->x, 16, hex_dst_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 16, dst->len ) == 0 );
 
 exit:
     mbedtls_aes_free( &ctx );
@@ -250,7 +252,7 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CFB */
 void aes_decrypt_cfb128( data_t * key_str, data_t * iv_str,
-                         data_t * src_str, data_t * hex_dst_string )
+                         data_t * src_str, data_t * dst )
 {
     unsigned char output[100];
     mbedtls_aes_context ctx;
@@ -263,7 +265,7 @@
     mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 );
     TEST_ASSERT( mbedtls_aes_crypt_cfb128( &ctx, MBEDTLS_AES_DECRYPT, 16, &iv_offset, iv_str->x, src_str->x, output ) == 0 );
 
-    TEST_ASSERT( hexcmp( output, hex_dst_string->x, 16, hex_dst_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 16, dst->len ) == 0 );
 
 exit:
     mbedtls_aes_free( &ctx );
@@ -272,7 +274,7 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CFB */
 void aes_encrypt_cfb8( data_t * key_str, data_t * iv_str,
-                       data_t * src_str, data_t * hex_dst_string )
+                       data_t * src_str, data_t * dst )
 {
     unsigned char output[100];
     mbedtls_aes_context ctx;
@@ -284,7 +286,8 @@
     mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 );
     TEST_ASSERT( mbedtls_aes_crypt_cfb8( &ctx, MBEDTLS_AES_ENCRYPT, src_str->len, iv_str->x, src_str->x, output ) == 0 );
 
-    TEST_ASSERT( hexcmp( output, hex_dst_string->x, src_str->len, hex_dst_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x,
+                                      src_str->len, dst->len ) == 0 );
 
 exit:
     mbedtls_aes_free( &ctx );
@@ -293,7 +296,7 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CFB */
 void aes_decrypt_cfb8( data_t * key_str, data_t * iv_str,
-                       data_t * src_str, data_t * hex_dst_string )
+                       data_t * src_str, data_t * dst )
 {
     unsigned char output[100];
     mbedtls_aes_context ctx;
@@ -305,7 +308,8 @@
     mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 );
     TEST_ASSERT( mbedtls_aes_crypt_cfb8( &ctx, MBEDTLS_AES_DECRYPT, src_str->len, iv_str->x, src_str->x, output ) == 0 );
 
-    TEST_ASSERT( hexcmp( output, hex_dst_string->x, src_str->len, hex_dst_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x,
+                                      src_str->len, dst->len ) == 0 );
 
 exit:
     mbedtls_aes_free( &ctx );
@@ -315,17 +319,15 @@
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_OFB */
 void aes_encrypt_ofb( int fragment_size, data_t *key_str,
                       data_t *iv_str, data_t *src_str,
-                      char *expected_output_string)
+                      data_t *expected_output )
 {
     unsigned char output[32];
-    unsigned char output_string[65];
     mbedtls_aes_context ctx;
     size_t iv_offset = 0;
     int in_buffer_len;
     unsigned char* src_str_next;
 
     memset( output, 0x00, sizeof( output ) );
-    memset( output_string, 0x00, sizeof( output_string ) );
     mbedtls_aes_init( &ctx );
 
     TEST_ASSERT( (size_t)fragment_size < sizeof( output ) );
@@ -340,12 +342,10 @@
         TEST_ASSERT( mbedtls_aes_crypt_ofb( &ctx, fragment_size, &iv_offset,
                                             iv_str->x, src_str_next, output ) == 0 );
 
-        mbedtls_test_hexify( output_string, output, fragment_size );
-        TEST_ASSERT( strncmp( (char *) output_string, expected_output_string,
-                              ( 2 * fragment_size ) ) == 0 );
+        TEST_ASSERT( memcmp( output, expected_output->x, fragment_size ) == 0 );
 
         in_buffer_len -= fragment_size;
-        expected_output_string += ( fragment_size * 2 );
+        expected_output->x += fragment_size;
         src_str_next += fragment_size;
 
         if( in_buffer_len < fragment_size )
diff --git a/tests/suites/test_suite_arc4.function b/tests/suites/test_suite_arc4.function
index ae3b032..c1e2386 100644
--- a/tests/suites/test_suite_arc4.function
+++ b/tests/suites/test_suite_arc4.function
@@ -8,8 +8,7 @@
  */
 
 /* BEGIN_CASE */
-void mbedtls_arc4_crypt( data_t * src_str, data_t * key_str,
-                         data_t * hex_dst_string )
+void mbedtls_arc4_crypt( data_t * src_str, data_t * key_str, data_t * dst )
 {
     unsigned char dst_str[1000];
     mbedtls_arc4_context ctx;
@@ -19,9 +18,11 @@
 
 
     mbedtls_arc4_setup(&ctx, key_str->x, key_str->len);
-    TEST_ASSERT( mbedtls_arc4_crypt(&ctx, src_str->len, src_str->x, dst_str ) == 0 );
+    TEST_ASSERT( mbedtls_arc4_crypt(&ctx, src_str->len,
+                                    src_str->x, dst_str ) == 0 );
 
-    TEST_ASSERT( hexcmp( dst_str, hex_dst_string->x, src_str->len, hex_dst_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( dst_str, dst->x,
+                                      src_str->len, dst->len ) == 0 );
 
 exit:
     mbedtls_arc4_free( &ctx );
diff --git a/tests/suites/test_suite_aria.function b/tests/suites/test_suite_aria.function
index d08c39d..6d6a203 100644
--- a/tests/suites/test_suite_aria.function
+++ b/tests/suites/test_suite_aria.function
@@ -207,14 +207,12 @@
 
 /* BEGIN_CASE */
 void aria_encrypt_ecb( data_t *key_str, data_t *src_str,
-                       char *hex_dst_string, int setkey_result )
+                       data_t *expected_output, int setkey_result )
 {
-    unsigned char dst_str[ARIA_MAX_DATA_STR];
     unsigned char output[ARIA_MAX_DATASIZE];
     mbedtls_aria_context ctx;
     size_t i;
 
-    memset( dst_str, 0x00, sizeof( dst_str ) );
     memset( output, 0x00, sizeof( output ) );
     mbedtls_aria_init( &ctx );
 
@@ -227,9 +225,9 @@
             TEST_ASSERT( mbedtls_aria_crypt_ecb( &ctx, src_str->x + i,
                                                  output + i ) == 0 );
         }
-        mbedtls_test_hexify( dst_str, output, src_str->len );
 
-        TEST_ASSERT( strcasecmp( (char *) dst_str, hex_dst_string ) == 0 );
+        ASSERT_COMPARE( output, expected_output->len,
+                        expected_output->x, expected_output->len );
     }
 
 exit:
@@ -239,14 +237,12 @@
 
 /* BEGIN_CASE */
 void aria_decrypt_ecb( data_t *key_str, data_t *src_str,
-                       char *hex_dst_string, int setkey_result )
+                       data_t *expected_output, int setkey_result )
 {
-    unsigned char dst_str[ARIA_MAX_DATA_STR];
     unsigned char output[ARIA_MAX_DATASIZE];
     mbedtls_aria_context ctx;
     size_t i;
 
-    memset( dst_str, 0x00, sizeof( dst_str ) );
     memset( output, 0x00, sizeof( output ) );
     mbedtls_aria_init( &ctx );
 
@@ -259,9 +255,9 @@
             TEST_ASSERT( mbedtls_aria_crypt_ecb( &ctx, src_str->x + i,
                                                  output + i ) == 0 );
         }
-        mbedtls_test_hexify( dst_str, output, src_str->len );
 
-        TEST_ASSERT( strcasecmp( (char *) dst_str, hex_dst_string ) == 0 );
+        ASSERT_COMPARE( output, expected_output->len,
+                        expected_output->x, expected_output->len );
     }
 
 exit:
@@ -271,14 +267,12 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
 void aria_encrypt_cbc( data_t *key_str, data_t *iv_str,
-                       data_t *src_str, char *hex_dst_string,
+                       data_t *src_str, data_t *expected_output,
                        int cbc_result )
 {
-    unsigned char dst_str[ARIA_MAX_DATA_STR];
     unsigned char output[ARIA_MAX_DATASIZE];
     mbedtls_aria_context ctx;
 
-    memset( dst_str, 0x00, sizeof( dst_str ) );
     memset( output, 0x00, sizeof( output ) );
     mbedtls_aria_init( &ctx );
 
@@ -288,9 +282,8 @@
                                          output ) == cbc_result );
     if( cbc_result == 0 )
     {
-        mbedtls_test_hexify( dst_str, output, src_str->len );
-
-        TEST_ASSERT( strcasecmp( (char *) dst_str, hex_dst_string ) == 0 );
+        ASSERT_COMPARE( output, expected_output->len,
+                        expected_output->x, expected_output->len );
     }
 
 exit:
@@ -300,14 +293,12 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
 void aria_decrypt_cbc( data_t *key_str, data_t *iv_str,
-                       data_t *src_str, char *hex_dst_string,
+                       data_t *src_str, data_t *expected_output,
                        int cbc_result )
 {
-    unsigned char dst_str[ARIA_MAX_DATA_STR];
     unsigned char output[ARIA_MAX_DATASIZE];
     mbedtls_aria_context ctx;
 
-    memset( dst_str, 0x00, sizeof( dst_str ) );
     memset( output, 0x00, sizeof( output ) );
     mbedtls_aria_init( &ctx );
 
@@ -317,9 +308,8 @@
                                          output ) == cbc_result );
     if( cbc_result == 0 )
     {
-        mbedtls_test_hexify( dst_str, output, src_str->len );
-
-        TEST_ASSERT( strcasecmp( (char *) dst_str, hex_dst_string ) == 0 );
+        ASSERT_COMPARE( output, expected_output->len,
+                        expected_output->x, expected_output->len );
     }
 
 exit:
@@ -329,15 +319,13 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CFB */
 void aria_encrypt_cfb128( data_t *key_str, data_t *iv_str,
-                          data_t *src_str, char *hex_dst_string,
+                          data_t *src_str, data_t *expected_output,
                           int result )
 {
-    unsigned char dst_str[ARIA_MAX_DATA_STR];
     unsigned char output[ARIA_MAX_DATASIZE];
     mbedtls_aria_context ctx;
     size_t iv_offset = 0;
 
-    memset( dst_str, 0x00, sizeof( dst_str ) );
     memset( output, 0x00, sizeof( output ) );
     mbedtls_aria_init( &ctx );
 
@@ -346,9 +334,9 @@
                                             src_str->len, &iv_offset,
                                             iv_str->x, src_str->x, output )
                  == result );
-    mbedtls_test_hexify( dst_str, output, src_str->len );
 
-    TEST_ASSERT( strcasecmp( (char *) dst_str, hex_dst_string ) == 0 );
+    ASSERT_COMPARE( output, expected_output->len,
+                    expected_output->x, expected_output->len );
 
 exit:
     mbedtls_aria_free( &ctx );
@@ -357,15 +345,13 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CFB */
 void aria_decrypt_cfb128( data_t *key_str, data_t *iv_str,
-                          data_t *src_str, char *hex_dst_string,
+                          data_t *src_str, data_t *expected_output,
                           int result  )
 {
-    unsigned char dst_str[ARIA_MAX_DATA_STR];
     unsigned char output[ARIA_MAX_DATASIZE];
     mbedtls_aria_context ctx;
     size_t iv_offset = 0;
 
-    memset( dst_str, 0x00, sizeof( dst_str ) );
     memset( output, 0x00, sizeof( output ) );
     mbedtls_aria_init( &ctx );
 
@@ -374,9 +360,9 @@
                                             src_str->len, &iv_offset,
                                             iv_str->x, src_str->x, output )
                  == result );
-    mbedtls_test_hexify( dst_str, output, src_str->len );
 
-    TEST_ASSERT( strcasecmp( (char *) dst_str, hex_dst_string ) == 0 );
+    ASSERT_COMPARE( output, expected_output->len,
+                    expected_output->x, expected_output->len );
 
 exit:
     mbedtls_aria_free( &ctx );
@@ -385,16 +371,14 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CTR */
 void aria_encrypt_ctr( data_t *key_str, data_t *iv_str,
-                       data_t *src_str, char *hex_dst_string,
+                       data_t *src_str, data_t *expected_output,
                        int result )
 {
-    unsigned char dst_str[ARIA_MAX_DATA_STR];
     unsigned char output[ARIA_MAX_DATASIZE];
     unsigned char blk[MBEDTLS_ARIA_BLOCKSIZE];
     mbedtls_aria_context ctx;
     size_t iv_offset = 0;
 
-    memset( dst_str, 0x00, sizeof( dst_str ) );
     memset( output, 0x00, sizeof( output ) );
     mbedtls_aria_init( &ctx );
 
@@ -402,9 +386,9 @@
     TEST_ASSERT( mbedtls_aria_crypt_ctr( &ctx, src_str->len, &iv_offset,
                                          iv_str->x, blk, src_str->x, output )
                  == result );
-    mbedtls_test_hexify( dst_str, output, src_str->len );
 
-    TEST_ASSERT( strcasecmp( (char *) dst_str, hex_dst_string ) == 0 );
+    ASSERT_COMPARE( output, expected_output->len,
+                    expected_output->x, expected_output->len );
 
 exit:
     mbedtls_aria_free( &ctx );
@@ -413,16 +397,14 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CTR */
 void aria_decrypt_ctr( data_t *key_str, data_t *iv_str,
-                       data_t *src_str, char *hex_dst_string,
+                       data_t *src_str, data_t *expected_output,
                        int result )
 {
-    unsigned char dst_str[ARIA_MAX_DATA_STR];
     unsigned char output[ARIA_MAX_DATASIZE];
     unsigned char blk[MBEDTLS_ARIA_BLOCKSIZE];
     mbedtls_aria_context ctx;
     size_t iv_offset = 0;
 
-    memset( dst_str, 0x00, sizeof( dst_str ) );
     memset( output, 0x00, sizeof( output ) );
     mbedtls_aria_init( &ctx );
 
@@ -430,9 +412,9 @@
     TEST_ASSERT( mbedtls_aria_crypt_ctr( &ctx, src_str->len, &iv_offset,
                                          iv_str->x, blk, src_str->x, output )
                  == result );
-    mbedtls_test_hexify( dst_str, output, src_str->len );
 
-    TEST_ASSERT( strcasecmp( (char *) dst_str, hex_dst_string ) == 0 );
+    ASSERT_COMPARE( output, expected_output->len,
+                    expected_output->x, expected_output->len );
 
 exit:
     mbedtls_aria_free( &ctx );
diff --git a/tests/suites/test_suite_blowfish.function b/tests/suites/test_suite_blowfish.function
index 7a93cd1..f89353c 100644
--- a/tests/suites/test_suite_blowfish.function
+++ b/tests/suites/test_suite_blowfish.function
@@ -167,7 +167,7 @@
 
 /* BEGIN_CASE */
 void blowfish_encrypt_ecb( data_t * key_str, data_t * src_str,
-                           data_t * hex_dst_string, int setkey_result )
+                           data_t * dst, int setkey_result )
 {
     unsigned char output[100];
     mbedtls_blowfish_context ctx;
@@ -181,7 +181,7 @@
     {
         TEST_ASSERT( mbedtls_blowfish_crypt_ecb( &ctx, MBEDTLS_BLOWFISH_ENCRYPT, src_str->x, output ) == 0 );
 
-        TEST_ASSERT( hexcmp( output, hex_dst_string->x, 8, hex_dst_string->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 8, dst->len ) == 0 );
     }
 
 exit:
@@ -191,7 +191,7 @@
 
 /* BEGIN_CASE */
 void blowfish_decrypt_ecb( data_t * key_str, data_t * src_str,
-                           data_t * hex_dst_string, int setkey_result )
+                           data_t * dst, int setkey_result )
 {
     unsigned char output[100];
     mbedtls_blowfish_context ctx;
@@ -205,7 +205,7 @@
     {
         TEST_ASSERT( mbedtls_blowfish_crypt_ecb( &ctx, MBEDTLS_BLOWFISH_DECRYPT, src_str->x, output ) == 0 );
 
-        TEST_ASSERT( hexcmp( output, hex_dst_string->x, 8, hex_dst_string->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 8, dst->len ) == 0 );
     }
 
 exit:
@@ -215,7 +215,7 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
 void blowfish_encrypt_cbc( data_t * key_str, data_t * iv_str,
-                           data_t * src_str, data_t * hex_dst_string,
+                           data_t * src_str, data_t * dst,
                            int cbc_result )
 {
     unsigned char output[100];
@@ -231,7 +231,8 @@
     if( cbc_result == 0 )
     {
 
-        TEST_ASSERT( hexcmp( output, hex_dst_string->x, src_str->len, hex_dst_string->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x,
+                                          src_str->len, dst->len ) == 0 );
     }
 
 exit:
@@ -241,7 +242,7 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
 void blowfish_decrypt_cbc( data_t * key_str, data_t * iv_str,
-                           data_t * src_str, data_t * hex_dst_string,
+                           data_t * src_str, data_t * dst,
                            int cbc_result )
 {
     unsigned char output[100];
@@ -256,7 +257,8 @@
     if( cbc_result == 0)
     {
 
-        TEST_ASSERT( hexcmp( output, hex_dst_string->x, src_str->len, hex_dst_string->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, src_str->len,
+                                          dst->len ) == 0 );
     }
 
 exit:
@@ -266,8 +268,7 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CFB */
 void blowfish_encrypt_cfb64( data_t * key_str, data_t * iv_str,
-                             data_t * src_str, data_t * hex_dst_string
-                             )
+                             data_t * src_str, data_t * dst )
 {
     unsigned char output[100];
     mbedtls_blowfish_context ctx;
@@ -280,7 +281,8 @@
     mbedtls_blowfish_setkey( &ctx, key_str->x, key_str->len * 8 );
     TEST_ASSERT( mbedtls_blowfish_crypt_cfb64( &ctx, MBEDTLS_BLOWFISH_ENCRYPT, src_str->len, &iv_offset, iv_str->x, src_str->x, output ) == 0 );
 
-    TEST_ASSERT( hexcmp( output, hex_dst_string->x, src_str->len, hex_dst_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, src_str->len,
+                                      dst->len ) == 0 );
 
 exit:
     mbedtls_blowfish_free( &ctx );
@@ -289,8 +291,7 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CFB */
 void blowfish_decrypt_cfb64( data_t * key_str, data_t * iv_str,
-                             data_t * src_str, data_t * hex_dst_string
-                             )
+                             data_t * src_str, data_t * dst )
 {
     unsigned char output[100];
     mbedtls_blowfish_context ctx;
@@ -303,7 +304,8 @@
     mbedtls_blowfish_setkey( &ctx, key_str->x, key_str->len * 8 );
     TEST_ASSERT( mbedtls_blowfish_crypt_cfb64( &ctx, MBEDTLS_BLOWFISH_DECRYPT, src_str->len, &iv_offset, iv_str->x, src_str->x, output ) == 0 );
 
-    TEST_ASSERT( hexcmp( output, hex_dst_string->x, src_str->len, hex_dst_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, src_str->len,
+                                      dst->len ) == 0 );
 
 exit:
     mbedtls_blowfish_free( &ctx );
@@ -312,7 +314,7 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CTR */
 void blowfish_encrypt_ctr( data_t * key_str, data_t * iv_str,
-                           data_t * src_str, data_t * hex_dst_string )
+                           data_t * src_str, data_t * dst )
 {
     unsigned char stream_str[100];
     unsigned char output[100];
@@ -327,7 +329,8 @@
     mbedtls_blowfish_setkey( &ctx, key_str->x, key_str->len * 8 );
     TEST_ASSERT( mbedtls_blowfish_crypt_ctr( &ctx, src_str->len, &iv_offset, iv_str->x, stream_str, src_str->x, output ) == 0 );
 
-    TEST_ASSERT( hexcmp( output, hex_dst_string->x, src_str->len, hex_dst_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, src_str->len,
+                                      dst->len ) == 0 );
 
 exit:
     mbedtls_blowfish_free( &ctx );
diff --git a/tests/suites/test_suite_camellia.function b/tests/suites/test_suite_camellia.function
index 9408348..312495c 100644
--- a/tests/suites/test_suite_camellia.function
+++ b/tests/suites/test_suite_camellia.function
@@ -175,7 +175,7 @@
 
 /* BEGIN_CASE */
 void camellia_encrypt_ecb( data_t * key_str, data_t * src_str,
-                           data_t * hex_dst_string, int setkey_result )
+                           data_t * dst, int setkey_result )
 {
     unsigned char output[100];
     mbedtls_camellia_context ctx;
@@ -189,7 +189,7 @@
     {
         TEST_ASSERT( mbedtls_camellia_crypt_ecb( &ctx, MBEDTLS_CAMELLIA_ENCRYPT, src_str->x, output ) == 0 );
 
-        TEST_ASSERT( hexcmp( output, hex_dst_string->x, 16, hex_dst_string->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 16, dst->len ) == 0 );
     }
 
 exit:
@@ -199,7 +199,7 @@
 
 /* BEGIN_CASE */
 void camellia_decrypt_ecb( data_t * key_str, data_t * src_str,
-                           data_t * hex_dst_string, int setkey_result )
+                           data_t * dst, int setkey_result )
 {
     unsigned char output[100];
     mbedtls_camellia_context ctx;
@@ -213,7 +213,7 @@
     {
         TEST_ASSERT( mbedtls_camellia_crypt_ecb( &ctx, MBEDTLS_CAMELLIA_DECRYPT, src_str->x, output ) == 0 );
 
-        TEST_ASSERT( hexcmp( output, hex_dst_string->x, 16, hex_dst_string->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 16, dst->len ) == 0 );
     }
 
 exit:
@@ -223,8 +223,7 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
 void camellia_encrypt_cbc( data_t * key_str, data_t * iv_str,
-                           data_t * src_str, data_t * hex_dst_string,
-                           int cbc_result )
+                           data_t * src_str, data_t * dst, int cbc_result )
 {
     unsigned char output[100];
     mbedtls_camellia_context ctx;
@@ -238,7 +237,8 @@
     if( cbc_result == 0 )
     {
 
-        TEST_ASSERT( hexcmp( output, hex_dst_string->x, src_str->len, hex_dst_string->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, src_str->len,
+                                          dst->len ) == 0 );
     }
 
 exit:
@@ -248,7 +248,7 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
 void camellia_decrypt_cbc( data_t * key_str, data_t * iv_str,
-                           data_t * src_str, data_t * hex_dst_string,
+                           data_t * src_str, data_t * dst,
                            int cbc_result )
 {
     unsigned char output[100];
@@ -263,7 +263,8 @@
     if( cbc_result == 0 )
     {
 
-        TEST_ASSERT( hexcmp( output, hex_dst_string->x, src_str->len, hex_dst_string->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, src_str->len,
+                                          dst->len ) == 0 );
     }
 
 exit:
@@ -273,8 +274,7 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CFB */
 void camellia_encrypt_cfb128( data_t * key_str, data_t * iv_str,
-                              data_t * src_str,
-                              data_t * hex_dst_string )
+                              data_t * src_str, data_t * dst )
 {
     unsigned char output[100];
     mbedtls_camellia_context ctx;
@@ -287,7 +287,7 @@
     mbedtls_camellia_setkey_enc( &ctx, key_str->x, key_str->len * 8 );
     TEST_ASSERT( mbedtls_camellia_crypt_cfb128( &ctx, MBEDTLS_CAMELLIA_ENCRYPT, 16, &iv_offset, iv_str->x, src_str->x, output ) == 0 );
 
-    TEST_ASSERT( hexcmp( output, hex_dst_string->x, 16, hex_dst_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 16, dst->len ) == 0 );
 
 exit:
     mbedtls_camellia_free( &ctx );
@@ -297,7 +297,7 @@
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CFB */
 void camellia_decrypt_cfb128( data_t * key_str, data_t * iv_str,
                               data_t * src_str,
-                              data_t * hex_dst_string )
+                              data_t * dst )
 {
     unsigned char output[100];
     mbedtls_camellia_context ctx;
@@ -310,7 +310,7 @@
     mbedtls_camellia_setkey_enc( &ctx, key_str->x, key_str->len * 8 );
     TEST_ASSERT( mbedtls_camellia_crypt_cfb128( &ctx, MBEDTLS_CAMELLIA_DECRYPT, 16, &iv_offset, iv_str->x, src_str->x, output ) == 0 );
 
-    TEST_ASSERT( hexcmp( output, hex_dst_string->x, 16, hex_dst_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 16, dst->len ) == 0 );
 
 exit:
     mbedtls_camellia_free( &ctx );
diff --git a/tests/suites/test_suite_ccm.function b/tests/suites/test_suite_ccm.function
index a04583b..1b3a25f 100644
--- a/tests/suites/test_suite_ccm.function
+++ b/tests/suites/test_suite_ccm.function
@@ -152,7 +152,7 @@
 void mbedtls_ccm_auth_decrypt( int cipher_id, data_t * key,
                                data_t * msg, data_t * iv,
                                data_t * add, int tag_len, int result,
-                               data_t * hex_msg )
+                               data_t * expected_msg )
 {
     unsigned char tag[16];
     mbedtls_ccm_context ctx;
@@ -172,7 +172,7 @@
 
     if( result == 0 )
     {
-        TEST_ASSERT( memcmp( msg->x, hex_msg->x, hex_msg->len ) == 0 );
+        TEST_ASSERT( memcmp( msg->x, expected_msg->x, expected_msg->len ) == 0 );
     }
     else
     {
@@ -200,12 +200,11 @@
     unsigned char iv[13];
     unsigned char result[50];
     mbedtls_ccm_context ctx;
-    size_t i, iv_len, tag_len;
+    size_t iv_len, tag_len;
     int ret;
 
     mbedtls_ccm_init( &ctx );
 
-    memset( iv, 0x00, sizeof( iv ) );
     memset( result, 0x00, sizeof( result ) );
 
     if( sec_level % 4 == 0)
@@ -213,12 +212,10 @@
     else
         tag_len = 1 << ( sec_level % 4 + 1);
 
-    for( i = 0; i < source_address->len; i++ )
-        iv[i] = source_address->x[i];
-
-    for( i = 0; i < frame_counter->len; i++ )
-        iv[source_address->len + i] = frame_counter->x[i];
-
+    TEST_ASSERT( source_address->len == 8 );
+    TEST_ASSERT( frame_counter->len == 4 );
+    memcpy( iv, source_address->x, source_address->len );
+    memcpy( iv + source_address->len, frame_counter->x, frame_counter->len );
     iv[source_address->len + frame_counter->len] = sec_level;
     iv_len = sizeof( iv );
 
@@ -253,7 +250,7 @@
     unsigned char iv[13];
     unsigned char result[50];
     mbedtls_ccm_context ctx;
-    size_t i, iv_len, tag_len;
+    size_t iv_len, tag_len;
     int ret;
 
     mbedtls_ccm_init( &ctx );
@@ -266,12 +263,10 @@
     else
         tag_len = 1 << ( sec_level % 4 + 1);
 
-    for( i = 0; i < source_address->len; i++ )
-        iv[i] = source_address->x[i];
-
-    for( i = 0; i < frame_counter->len; i++ )
-        iv[source_address->len + i] = frame_counter->x[i];
-
+    TEST_ASSERT( source_address->len == 8 );
+    TEST_ASSERT( frame_counter->len == 4 );
+    memcpy( iv, source_address->x, source_address->len );
+    memcpy( iv + source_address->len, frame_counter->x, frame_counter->len );
     iv[source_address->len + frame_counter->len] = sec_level;
     iv_len = sizeof( iv );
 
diff --git a/tests/suites/test_suite_chacha20.function b/tests/suites/test_suite_chacha20.function
index afe2418..67c8de2 100644
--- a/tests/suites/test_suite_chacha20.function
+++ b/tests/suites/test_suite_chacha20.function
@@ -17,13 +17,6 @@
     unsigned char output[375];
     mbedtls_chacha20_context ctx;
 
-    /*
-     * Buffers to store the ASCII string representation of output and
-     * expected_output_str.
-     */
-    unsigned char output_string[751] = { '\0' };
-    unsigned char expected_output_string[751] = { '\0' };
-
     memset( output, 0x00, sizeof( output ) );
 
     TEST_ASSERT( src_str->len   == expected_output_str->len );
@@ -35,12 +28,8 @@
      */
     TEST_ASSERT( mbedtls_chacha20_crypt( key_str->x, nonce_str->x, counter, src_str->len, src_str->x, output ) == 0 );
 
-    mbedtls_test_hexify( expected_output_string,
-                         expected_output_str->x,
-                         expected_output_str->len);
-    mbedtls_test_hexify( output_string, output, src_str->len );
-    TEST_ASSERT( strcmp( (char *)output_string,
-                         (char *)expected_output_string ) == 0 );
+    ASSERT_COMPARE( output, expected_output_str->len,
+                    expected_output_str->x, expected_output_str->len );
 
     /*
      * Test the streaming API
@@ -54,9 +43,8 @@
     memset( output, 0x00, sizeof( output ) );
     TEST_ASSERT( mbedtls_chacha20_update( &ctx, src_str->len, src_str->x, output ) == 0 );
 
-    mbedtls_test_hexify( output_string, output, src_str->len );
-    TEST_ASSERT( strcmp( (char *)output_string,
-                         (char *)expected_output_string ) == 0 );
+    ASSERT_COMPARE( output, expected_output_str->len,
+                    expected_output_str->x, expected_output_str->len );
 
     /*
      * Test the streaming API again, piecewise
@@ -71,9 +59,8 @@
     TEST_ASSERT( mbedtls_chacha20_update( &ctx, src_str->len - 1,
                                           src_str->x + 1, output + 1 ) == 0 );
 
-    mbedtls_test_hexify( output_string, output, src_str->len );
-    TEST_ASSERT( strcmp( (char *)output_string,
-                         (char *)expected_output_string ) == 0 );
+    ASSERT_COMPARE( output, expected_output_str->len,
+                    expected_output_str->x, expected_output_str->len );
 
     mbedtls_chacha20_free( &ctx );
 }
diff --git a/tests/suites/test_suite_ctr_drbg.function b/tests/suites/test_suite_ctr_drbg.function
index 01050d9..d6cf828 100644
--- a/tests/suites/test_suite_ctr_drbg.function
+++ b/tests/suites/test_suite_ctr_drbg.function
@@ -206,13 +206,16 @@
     memset( out, 0, sizeof( out ) );
     memset( add, 0, sizeof( add ) );
 
+    /* Set reseed interval before seed */
+    mbedtls_ctr_drbg_set_reseed_interval( &ctx, 2 * reps );
+
     /* Init must use entropy */
     last_idx = test_offset_idx;
     TEST_ASSERT( mbedtls_ctr_drbg_seed( &ctx, mbedtls_test_entropy_func, entropy, NULL, 0 ) == 0 );
     TEST_ASSERT( last_idx < test_offset_idx );
 
-    /* By default, PR is off and reseed_interval is large,
-     * so the next few calls should not use entropy */
+    /* By default, PR is off, and reseed interval was set to
+     * 2 * reps so the next few calls should not use entropy */
     last_idx = test_offset_idx;
     for( i = 0; i < reps; i++ )
     {
@@ -228,15 +231,16 @@
     TEST_ASSERT( out[sizeof( out ) - 2] == 0 );
     TEST_ASSERT( out[sizeof( out ) - 1] == 0 );
 
-    /* Set reseed_interval to the number of calls done,
-     * so the next call should reseed */
-    mbedtls_ctr_drbg_set_reseed_interval( &ctx, 2 * reps );
+    /* There have been 2 * reps calls to random. The next call should reseed */
     TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
     TEST_ASSERT( last_idx < test_offset_idx );
 
-    /* The new few calls should not reseed */
+    /* Set reseed interval after seed */
+    mbedtls_ctr_drbg_set_reseed_interval( &ctx, 4 * reps + 1 );
+
+    /* The next few calls should not reseed */
     last_idx = test_offset_idx;
-    for( i = 0; i < reps / 2; i++ )
+    for( i = 0; i < (2 * reps); i++ )
     {
         TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
         TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx, out, sizeof( out ) ,
diff --git a/tests/suites/test_suite_des.function b/tests/suites/test_suite_des.function
index b5acb7b..5b24935 100644
--- a/tests/suites/test_suite_des.function
+++ b/tests/suites/test_suite_des.function
@@ -15,8 +15,7 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void des_encrypt_ecb( data_t * key_str, data_t * src_str,
-                      data_t * hex_dst_string )
+void des_encrypt_ecb( data_t * key_str, data_t * src_str, data_t * dst )
 {
     unsigned char output[100];
     mbedtls_des_context ctx;
@@ -28,7 +27,7 @@
     mbedtls_des_setkey_enc( &ctx, key_str->x );
     TEST_ASSERT( mbedtls_des_crypt_ecb( &ctx, src_str->x, output ) == 0 );
 
-    TEST_ASSERT( hexcmp( output, hex_dst_string->x, 8, hex_dst_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 8, dst->len ) == 0 );
 
 exit:
     mbedtls_des_free( &ctx );
@@ -36,8 +35,7 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void des_decrypt_ecb( data_t * key_str, data_t * src_str,
-                      data_t * hex_dst_string )
+void des_decrypt_ecb( data_t * key_str, data_t * src_str, data_t * dst )
 {
     unsigned char output[100];
     mbedtls_des_context ctx;
@@ -49,7 +47,7 @@
     mbedtls_des_setkey_dec( &ctx, key_str->x );
     TEST_ASSERT( mbedtls_des_crypt_ecb( &ctx, src_str->x, output ) == 0 );
 
-    TEST_ASSERT( hexcmp( output, hex_dst_string->x, 8, hex_dst_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 8, dst->len ) == 0 );
 
 exit:
     mbedtls_des_free( &ctx );
@@ -58,8 +56,7 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
 void des_encrypt_cbc( data_t * key_str, data_t * iv_str,
-                      data_t * src_str, data_t * hex_dst_string,
-                      int cbc_result )
+                      data_t * src_str, data_t * dst, int cbc_result )
 {
     unsigned char output[100];
     mbedtls_des_context ctx;
@@ -73,7 +70,8 @@
     if( cbc_result == 0 )
     {
 
-        TEST_ASSERT( hexcmp( output, hex_dst_string->x, src_str->len, hex_dst_string->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, src_str->len,
+                                          dst->len ) == 0 );
     }
 
 exit:
@@ -83,7 +81,7 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
 void des_decrypt_cbc( data_t * key_str, data_t * iv_str,
-                      data_t * src_str, data_t * hex_dst_string,
+                      data_t * src_str, data_t * dst,
                       int cbc_result )
 {
     unsigned char output[100];
@@ -98,7 +96,8 @@
     if( cbc_result == 0 )
     {
 
-        TEST_ASSERT( hexcmp( output, hex_dst_string->x, src_str->len, hex_dst_string->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, src_str->len,
+                                          dst->len ) == 0 );
     }
 
 exit:
@@ -108,7 +107,7 @@
 
 /* BEGIN_CASE */
 void des3_encrypt_ecb( int key_count, data_t * key_str,
-                       data_t * src_str, data_t * hex_dst_string )
+                       data_t * src_str, data_t * dst )
 {
     unsigned char output[100];
     mbedtls_des3_context ctx;
@@ -126,7 +125,7 @@
 
     TEST_ASSERT( mbedtls_des3_crypt_ecb( &ctx, src_str->x, output ) == 0 );
 
-    TEST_ASSERT( hexcmp( output, hex_dst_string->x, 8, hex_dst_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 8, dst->len ) == 0 );
 
 exit:
     mbedtls_des3_free( &ctx );
@@ -135,7 +134,7 @@
 
 /* BEGIN_CASE */
 void des3_decrypt_ecb( int key_count, data_t * key_str,
-                       data_t * src_str, data_t * hex_dst_string )
+                       data_t * src_str, data_t * dst )
 {
     unsigned char output[100];
     mbedtls_des3_context ctx;
@@ -153,7 +152,7 @@
 
     TEST_ASSERT( mbedtls_des3_crypt_ecb( &ctx, src_str->x, output ) == 0 );
 
-    TEST_ASSERT( hexcmp( output, hex_dst_string->x, 8, hex_dst_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 8, dst->len ) == 0 );
 
 exit:
     mbedtls_des3_free( &ctx );
@@ -163,7 +162,7 @@
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
 void des3_encrypt_cbc( int key_count, data_t * key_str,
                        data_t * iv_str, data_t * src_str,
-                       data_t * hex_dst_string, int cbc_result )
+                       data_t * dst, int cbc_result )
 {
     unsigned char output[100];
     mbedtls_des3_context ctx;
@@ -184,7 +183,8 @@
     if( cbc_result == 0 )
     {
 
-        TEST_ASSERT( hexcmp( output, hex_dst_string->x, src_str->len, hex_dst_string->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x,
+                                          src_str->len, dst->len ) == 0 );
     }
 
 exit:
@@ -195,7 +195,7 @@
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
 void des3_decrypt_cbc( int key_count, data_t * key_str,
                        data_t * iv_str, data_t * src_str,
-                       data_t * hex_dst_string, int cbc_result )
+                       data_t * dst, int cbc_result )
 {
     unsigned char output[100];
     mbedtls_des3_context ctx;
@@ -216,7 +216,8 @@
     if( cbc_result == 0 )
     {
 
-        TEST_ASSERT( hexcmp( output, hex_dst_string->x, src_str->len, hex_dst_string->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, src_str->len,
+                                          dst->len ) == 0 );
     }
 
 exit:
diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function
index 850b77c..e37a017 100644
--- a/tests/suites/test_suite_ecp.function
+++ b/tests/suites/test_suite_ecp.function
@@ -756,7 +756,7 @@
 
     if( ret == 0 )
     {
-        TEST_ASSERT( hexcmp( buf, out->x, olen, out->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( buf, out->x, olen, out->len ) == 0 );
     }
 
 exit:
diff --git a/tests/suites/test_suite_entropy.data b/tests/suites/test_suite_entropy.data
index 5cff399..8ad8760 100644
--- a/tests/suites/test_suite_entropy.data
+++ b/tests/suites/test_suite_entropy.data
@@ -1,3 +1,9 @@
+Entropy init-free-free
+entropy_init_free:0
+
+Entropy init-free-init-free
+entropy_init_free:1
+
 Create NV seed_file
 nv_seed_file_create:
 
diff --git a/tests/suites/test_suite_entropy.function b/tests/suites/test_suite_entropy.function
index 889d3bc..f4f9693 100644
--- a/tests/suites/test_suite_entropy.function
+++ b/tests/suites/test_suite_entropy.function
@@ -125,6 +125,28 @@
  * END_DEPENDENCIES
  */
 
+/* BEGIN_CASE */
+void entropy_init_free( int reinit )
+{
+    mbedtls_entropy_context ctx;
+
+    /* Double free is not explicitly documented to work, but it is convenient
+     * to call mbedtls_entropy_free() unconditionally on an error path without
+     * checking whether it has already been called in the success path. */
+
+    mbedtls_entropy_init( &ctx );
+    mbedtls_entropy_free( &ctx );
+
+    if( reinit )
+        mbedtls_entropy_init( &ctx );
+    mbedtls_entropy_free( &ctx );
+
+    /* This test case always succeeds, functionally speaking. A plausible
+     * bug might trigger an invalid pointer dereference or a memory leak. */
+    goto exit;
+}
+/* END_CASE */
+
 /* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
 void entropy_seed_file( char * path, int ret )
 {
@@ -191,6 +213,9 @@
 
     for( j = len; j < sizeof( buf ); j++ )
         TEST_ASSERT( acc[j] == 0 );
+
+exit:
+    mbedtls_entropy_free( &ctx );
 }
 /* END_CASE */
 
diff --git a/tests/suites/test_suite_gcm.function b/tests/suites/test_suite_gcm.function
index 1fcb681..9b7b0ee 100644
--- a/tests/suites/test_suite_gcm.function
+++ b/tests/suites/test_suite_gcm.function
@@ -35,8 +35,8 @@
 /* BEGIN_CASE */
 void gcm_encrypt_and_tag( int cipher_id, data_t * key_str,
                           data_t * src_str, data_t * iv_str,
-                          data_t * add_str, data_t * hex_dst_string,
-                          int tag_len_bits, data_t * hex_tag_string,
+                          data_t * add_str, data_t * dst,
+                          int tag_len_bits, data_t * tag,
                           int init_result )
 {
     unsigned char output[128];
@@ -55,8 +55,10 @@
     {
         TEST_ASSERT( mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT, src_str->len, iv_str->x, iv_str->len, add_str->x, add_str->len, src_str->x, output, tag_len, tag_output ) == 0 );
 
-        TEST_ASSERT( hexcmp( output, hex_dst_string->x, src_str->len, hex_dst_string->len ) == 0 );
-        TEST_ASSERT( hexcmp( tag_output, hex_tag_string->x, tag_len, hex_tag_string->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x,
+                                          src_str->len, dst->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( tag_output, tag->x,
+                                          tag_len, tag->len ) == 0 );
     }
 
 exit:
@@ -94,7 +96,9 @@
         {
             TEST_ASSERT( ret == 0 );
 
-            TEST_ASSERT( hexcmp( output, pt_result->x, src_str->len, pt_result->len ) == 0 );
+            TEST_ASSERT( mbedtls_test_hexcmp( output, pt_result->x,
+                                              src_str->len,
+                                              pt_result->len ) == 0 );
         }
     }
 
diff --git a/tests/suites/test_suite_hkdf.function b/tests/suites/test_suite_hkdf.function
index ddd64fa..af871e1 100644
--- a/tests/suites/test_suite_hkdf.function
+++ b/tests/suites/test_suite_hkdf.function
@@ -14,13 +14,6 @@
 {
     int ret;
     unsigned char okm[128] = { '\0' };
-    /*
-     * okm_string and expected_okm_string are the ASCII string representations
-     * of km and expected_okm, so their size should be twice the size of
-     * okm and expected_okm, and an extra null-termination.
-     */
-    unsigned char okm_string[257] = { '\0' };
-    unsigned char expected_okm_string[257] = { '\0' };
 
     const mbedtls_md_info_t *md = mbedtls_md_info_from_type( md_alg );
     TEST_ASSERT( md != NULL );
@@ -31,14 +24,8 @@
                         info->x, info->len, okm, expected_okm->len );
     TEST_ASSERT( ret == 0 );
 
-    /*
-     * Run mbedtls_test_hexify on okm and expected_okm so that it looks nicer
-     * if the assertion fails.
-     */
-    mbedtls_test_hexify( okm_string, okm, expected_okm->len );
-    mbedtls_test_hexify( expected_okm_string,
-                         expected_okm->x, expected_okm->len );
-    TEST_ASSERT( !strcmp( (char *)okm_string, (char *)expected_okm_string ) );
+    ASSERT_COMPARE( okm            , expected_okm->len,
+                    expected_okm->x, expected_okm->len );
 }
 /* END_CASE */
 
@@ -62,12 +49,11 @@
     ikm = unhexify_alloc( hex_ikm_string, &ikm_len );
     salt = unhexify_alloc( hex_salt_string, &salt_len );
     prk = unhexify_alloc( hex_prk_string, &prk_len );
-    TEST_ASSERT( prk_len == output_prk_len );
 
     ret = mbedtls_hkdf_extract( md, salt, salt_len, ikm, ikm_len, output_prk );
     TEST_ASSERT( ret == 0 );
 
-    TEST_ASSERT( !memcmp( output_prk, prk, prk_len ) );
+    ASSERT_COMPARE( output_prk, output_prk_len, prk, prk_len );
 
 exit:
     mbedtls_free(ikm);
@@ -103,7 +89,7 @@
     ret = mbedtls_hkdf_expand( md, prk, prk_len, info, info_len,
                                output_okm, OKM_LEN );
     TEST_ASSERT( ret == 0 );
-    TEST_ASSERT( !memcmp( output_okm, okm, okm_len ) );
+    ASSERT_COMPARE( output_okm, okm_len, okm, okm_len );
 
 exit:
     mbedtls_free(info);
diff --git a/tests/suites/test_suite_hmac_drbg.function b/tests/suites/test_suite_hmac_drbg.function
index 13bc400..fbbb1bd 100644
--- a/tests/suites/test_suite_hmac_drbg.function
+++ b/tests/suites/test_suite_hmac_drbg.function
@@ -49,14 +49,17 @@
     md_info = mbedtls_md_info_from_type( md_alg );
     TEST_ASSERT( md_info != NULL );
 
+    /* Set reseed interval before seed */
+    mbedtls_hmac_drbg_set_reseed_interval( &ctx, 2 * reps );
+
     /* Init must use entropy */
     last_len = entropy.len;
     TEST_ASSERT( mbedtls_hmac_drbg_seed( &ctx, md_info, mbedtls_test_entropy_func, &entropy,
                                  NULL, 0 ) == 0 );
     TEST_ASSERT( entropy.len < last_len );
 
-    /* By default, PR is off and reseed_interval is large,
-     * so the next few calls should not use entropy */
+    /* By default, PR is off, and reseed interval was set to
+     * 2 * reps so the next few calls should not use entropy */
     last_len = entropy.len;
     for( i = 0; i < reps; i++ )
     {
@@ -72,15 +75,16 @@
     TEST_ASSERT( out[sizeof( out ) - 2] == 0 );
     TEST_ASSERT( out[sizeof( out ) - 1] == 0 );
 
-    /* Set reseed_interval to the number of calls done,
-     * so the next call should reseed */
-    mbedtls_hmac_drbg_set_reseed_interval( &ctx, 2 * reps );
+    /* There have been 2 * reps calls to random. The next call should reseed */
     TEST_ASSERT( mbedtls_hmac_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
     TEST_ASSERT( entropy.len < last_len );
 
+    /* Set reseed interval after seed */
+    mbedtls_hmac_drbg_set_reseed_interval( &ctx, 4 * reps + 1);
+
     /* The new few calls should not reseed */
     last_len = entropy.len;
-    for( i = 0; i < reps / 2; i++ )
+    for( i = 0; i < (2 * reps); i++ )
     {
         TEST_ASSERT( mbedtls_hmac_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
         TEST_ASSERT( mbedtls_hmac_drbg_random_with_add( &ctx, out, sizeof( out ) ,
@@ -189,7 +193,7 @@
     TEST_ASSERT( mbedtls_hmac_drbg_random_with_add( &ctx, my_output, output->len,
                                             add2->x, add2->len ) == 0 );
 
-    /* clear for second run */
+    /* Reset context for second run */
     mbedtls_hmac_drbg_free( &ctx );
 
     TEST_ASSERT( memcmp( my_output, output->x, output->len ) == 0 );
diff --git a/tests/suites/test_suite_md.function b/tests/suites/test_suite_md.function
index 11cf88a..d918ce3 100644
--- a/tests/suites/test_suite_md.function
+++ b/tests/suites/test_suite_md.function
@@ -127,7 +127,7 @@
 
 /* BEGIN_CASE */
 void md_text( char * text_md_name, char * text_src_string,
-              data_t * hex_hash_string )
+              data_t * hash )
 {
     char md_name[100];
     unsigned char src_str[1000];
@@ -145,13 +145,14 @@
 
     TEST_ASSERT ( 0 == mbedtls_md( md_info, src_str, strlen( (char *) src_str ), output ) );
 
-    TEST_ASSERT( hexcmp( output, hex_hash_string->x, mbedtls_md_get_size( md_info ), hex_hash_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x,
+                                      mbedtls_md_get_size( md_info ),
+                                      hash->len ) == 0 );
 }
 /* END_CASE */
 
 /* BEGIN_CASE */
-void md_hex( char * text_md_name, data_t * src_str,
-             data_t * hex_hash_string )
+void md_hex( char * text_md_name, data_t * src_str, data_t * hash )
 {
     char md_name[100];
     unsigned char output[100];
@@ -167,14 +168,15 @@
     TEST_ASSERT ( 0 == mbedtls_md( md_info, src_str->x, src_str->len, output ) );
 
 
-    TEST_ASSERT( hexcmp( output, hex_hash_string->x,
-                 mbedtls_md_get_size( md_info ), hex_hash_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x,
+                                      mbedtls_md_get_size( md_info ),
+                                      hash->len ) == 0 );
 }
 /* END_CASE */
 
 /* BEGIN_CASE */
 void md_text_multi( char * text_md_name, char * text_src_string,
-                    data_t * hex_hash_string )
+                    data_t * hash )
 {
     char md_name[100];
     unsigned char src_str[1000];
@@ -208,15 +210,18 @@
 
     TEST_ASSERT ( 0 == mbedtls_md_update( &ctx, src_str + halfway, len - halfway ) );
     TEST_ASSERT ( 0 == mbedtls_md_finish( &ctx, output ) );
-    TEST_ASSERT( hexcmp( output, hex_hash_string->x,
-                 mbedtls_md_get_size( md_info ), hex_hash_string->len) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x,
+                                      mbedtls_md_get_size( md_info ),
+                                      hash->len) == 0 );
 
     /* Test clone */
     memset( output, 0x00, 100 );
 
     TEST_ASSERT ( 0 == mbedtls_md_update( &ctx_copy, src_str + halfway, len - halfway ) );
     TEST_ASSERT ( 0 == mbedtls_md_finish( &ctx_copy, output ) );
-    TEST_ASSERT( hexcmp( output, hex_hash_string->x, mbedtls_md_get_size( md_info ), hex_hash_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x,
+                                      mbedtls_md_get_size( md_info ),
+                                      hash->len ) == 0 );
 
 exit:
     mbedtls_md_free( &ctx );
@@ -225,8 +230,7 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void md_hex_multi( char * text_md_name, data_t * src_str,
-                   data_t * hex_hash_string )
+void md_hex_multi( char * text_md_name, data_t * src_str, data_t * hash )
 {
     char md_name[100];
     unsigned char output[100];
@@ -255,14 +259,18 @@
 
     TEST_ASSERT ( 0 == mbedtls_md_update( &ctx, src_str->x + halfway, src_str->len - halfway) );
     TEST_ASSERT ( 0 == mbedtls_md_finish( &ctx, output ) );
-    TEST_ASSERT( hexcmp( output, hex_hash_string->x, mbedtls_md_get_size( md_info ), hex_hash_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x,
+                                      mbedtls_md_get_size( md_info ),
+                                      hash->len ) == 0 );
 
     /* Test clone */
     memset( output, 0x00, 100 );
 
     TEST_ASSERT ( 0 == mbedtls_md_update( &ctx_copy, src_str->x + halfway, src_str->len - halfway ) );
     TEST_ASSERT ( 0 == mbedtls_md_finish( &ctx_copy, output ) );
-    TEST_ASSERT( hexcmp( output, hex_hash_string->x, mbedtls_md_get_size( md_info ), hex_hash_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x,
+                                      mbedtls_md_get_size( md_info ),
+                                      hash->len ) == 0 );
 
 exit:
     mbedtls_md_free( &ctx );
@@ -273,7 +281,7 @@
 /* BEGIN_CASE */
 void mbedtls_md_hmac( char * text_md_name, int trunc_size,
                       data_t * key_str, data_t * src_str,
-                      data_t * hex_hash_string )
+                      data_t * hash )
 {
     char md_name[100];
     unsigned char output[100];
@@ -289,13 +297,14 @@
 
     TEST_ASSERT ( mbedtls_md_hmac( md_info, key_str->x, key_str->len, src_str->x, src_str->len, output ) == 0 );
 
-    TEST_ASSERT( hexcmp( output, hex_hash_string->x, trunc_size, hex_hash_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x,
+                                      trunc_size, hash->len ) == 0 );
 }
 /* END_CASE */
 
 /* BEGIN_CASE */
 void md_hmac_multi( char * text_md_name, int trunc_size, data_t * key_str,
-                    data_t * src_str, data_t * hex_hash_string )
+                    data_t * src_str, data_t * hash )
 {
     char md_name[100];
     unsigned char output[100];
@@ -321,7 +330,8 @@
     TEST_ASSERT ( 0 == mbedtls_md_hmac_update( &ctx, src_str->x + halfway, src_str->len - halfway ) );
     TEST_ASSERT ( 0 == mbedtls_md_hmac_finish( &ctx, output ) );
 
-    TEST_ASSERT( hexcmp( output, hex_hash_string->x, trunc_size, hex_hash_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x,
+                                      trunc_size, hash->len ) == 0 );
 
     /* Test again, for reset() */
     memset( output, 0x00, 100 );
@@ -331,7 +341,8 @@
     TEST_ASSERT ( 0 == mbedtls_md_hmac_update( &ctx, src_str->x + halfway, src_str->len - halfway ) );
     TEST_ASSERT ( 0 == mbedtls_md_hmac_finish( &ctx, output ) );
 
-    TEST_ASSERT( hexcmp( output, hex_hash_string->x, trunc_size, hex_hash_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x,
+                                      trunc_size, hash->len ) == 0 );
 
 exit:
     mbedtls_md_free( &ctx );
@@ -340,7 +351,7 @@
 
 /* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
 void mbedtls_md_file( char * text_md_name, char * filename,
-                      data_t * hex_hash_string )
+                      data_t * hash )
 {
     char md_name[100];
     unsigned char output[100];
@@ -355,6 +366,8 @@
 
     TEST_ASSERT( mbedtls_md_file( md_info, filename, output ) == 0 );
 
-    TEST_ASSERT( hexcmp( output, hex_hash_string->x, mbedtls_md_get_size( md_info ), hex_hash_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x,
+                                      mbedtls_md_get_size( md_info ),
+                                      hash->len ) == 0 );
 }
 /* END_CASE */
diff --git a/tests/suites/test_suite_mdx.function b/tests/suites/test_suite_mdx.function
index 02004ef..aa35c58 100644
--- a/tests/suites/test_suite_mdx.function
+++ b/tests/suites/test_suite_mdx.function
@@ -6,7 +6,7 @@
 /* END_HEADER */
 
 /* BEGIN_CASE depends_on:MBEDTLS_MD2_C */
-void md2_text( char * text_src_string, data_t * hex_hash_string )
+void md2_text( char * text_src_string, data_t * hash )
 {
     int ret;
     unsigned char src_str[100];
@@ -20,12 +20,13 @@
     ret = mbedtls_md2_ret( src_str, strlen( (char *) src_str ), output );
     TEST_ASSERT( ret == 0 ) ;
 
-    TEST_ASSERT( hexcmp( output, hex_hash_string->x, sizeof  output, hex_hash_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x,
+                                      sizeof  output, hash->len ) == 0 );
 }
 /* END_CASE */
 
 /* BEGIN_CASE depends_on:MBEDTLS_MD4_C */
-void md4_text( char * text_src_string, data_t * hex_hash_string )
+void md4_text( char * text_src_string, data_t * hash )
 {
     int ret;
     unsigned char src_str[100];
@@ -39,12 +40,13 @@
     ret = mbedtls_md4_ret( src_str, strlen( (char *) src_str ), output );
     TEST_ASSERT( ret == 0 );
 
-    TEST_ASSERT( hexcmp( output, hex_hash_string->x, sizeof  output, hex_hash_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x,
+                                      sizeof  output, hash->len ) == 0 );
 }
 /* END_CASE */
 
 /* BEGIN_CASE depends_on:MBEDTLS_MD5_C */
-void md5_text( char * text_src_string, data_t * hex_hash_string )
+void md5_text( char * text_src_string, data_t * hash )
 {
     int ret;
     unsigned char src_str[100];
@@ -58,12 +60,13 @@
     ret = mbedtls_md5_ret( src_str, strlen( (char *) src_str ), output );
     TEST_ASSERT( ret == 0 );
 
-    TEST_ASSERT( hexcmp( output, hex_hash_string->x, sizeof  output, hex_hash_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x,
+                                      sizeof  output, hash->len ) == 0 );
 }
 /* END_CASE */
 
 /* BEGIN_CASE depends_on:MBEDTLS_RIPEMD160_C */
-void ripemd160_text( char * text_src_string, data_t * hex_hash_string )
+void ripemd160_text( char * text_src_string, data_t * hash )
 {
     int ret;
     unsigned char src_str[100];
@@ -77,7 +80,8 @@
     ret = mbedtls_ripemd160_ret( src_str, strlen( (char *) src_str ), output );
     TEST_ASSERT( ret == 0 );
 
-    TEST_ASSERT( hexcmp( output, hex_hash_string->x, sizeof output, hex_hash_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x,
+                                      sizeof output, hash->len ) == 0 );
 }
 /* END_CASE */
 
diff --git a/tests/suites/test_suite_mpi.data b/tests/suites/test_suite_mpi.data
index 1298689..5229253 100644
--- a/tests/suites/test_suite_mpi.data
+++ b/tests/suites/test_suite_mpi.data
@@ -433,12 +433,6 @@
 Test mbedtls_mpi_add_abs #1
 mbedtls_mpi_add_abs:10:"-643808006803554439230129854961492699151386107534013432918073439524138264842370630061369715394739134090922937332590384720397133335969549256322620979036686633213903952966175107096769180017646161851573147596390153":10:"56125680981752282333498088313568935051383833838594899821664631784577337171193624243181360054669678410455329112434552942717084003541384594864129940145043086760031292483340068923506115878221189886491132772739661669044958531131327771":10:"56125680981752282334141896320372489490613963693556392520816017892111350604111697682705498319512049040516698827829292076808006940873974979584527073481012636016353913462376755556720019831187364993587901952757307830896531678727717924"
 
-Test mbedtls_mpi_add_abs #2 (add to first value)
-mpi_add_abs_add_first:10:"123123":10:"123123":10:"246246"
-
-Test mbedtls_mpi_add_abs #3 (add to second value)
-mpi_add_abs_add_second:10:"123123":10:"123123":10:"246246"
-
 Regression mbedtls_mpi_add_abs (add small to very large MPI with carry rollover)
 mbedtls_mpi_add_abs:16:"FFFFFFFFFFFFFFFFFFFFFFFFFFFFF8":16:"08":16:"1000000000000000000000000000000"
 
@@ -478,18 +472,30 @@
 Test mbedtls_mpi_add_int #2
 mbedtls_mpi_add_int:10:"2039568783564019774057658669290345772801939933143482630947726464532830627227012776329":-9871232:10:"2039568783564019774057658669290345772801939933143482630947726464532830627227002905097"
 
-Base test mbedtls_mpi_sub_abs #1 (Test with larger second input)
+Base test mbedtls_mpi_sub_abs #1 (|B| > |A|)
 mbedtls_mpi_sub_abs:10:"5":10:"7":10:"0":MBEDTLS_ERR_MPI_NEGATIVE_VALUE
 
-Base test mbedtls_mpi_sub_abs #2 (Test with larger second input)
+Base test mbedtls_mpi_sub_abs #2 (|B| > |A|)
 mbedtls_mpi_sub_abs:10:"-5":10:"-7":10:"0":MBEDTLS_ERR_MPI_NEGATIVE_VALUE
 
-Base test mbedtls_mpi_sub_abs #3 (Test with larger second input)
+Base test mbedtls_mpi_sub_abs #3 (|B| > |A|)
 mbedtls_mpi_sub_abs:10:"-5":10:"7":10:"0":MBEDTLS_ERR_MPI_NEGATIVE_VALUE
 
-Base test mbedtls_mpi_sub_abs #4 (Test with larger second input)
+Base test mbedtls_mpi_sub_abs #4 (|B| > |A|)
 mbedtls_mpi_sub_abs:10:"5":10:"-7":10:"0":MBEDTLS_ERR_MPI_NEGATIVE_VALUE
 
+Base test mbedtls_mpi_sub_abs #1 (|B| >> |A| with more limbs)
+mbedtls_mpi_sub_abs:10:"5":16:"123456789abcdef01":10:"0":MBEDTLS_ERR_MPI_NEGATIVE_VALUE
+
+Base test mbedtls_mpi_sub_abs #2 (|B| >> |A| with more limbs)
+mbedtls_mpi_sub_abs:10:"-5":16:"-123456789abcdef01":10:"0":MBEDTLS_ERR_MPI_NEGATIVE_VALUE
+
+Base test mbedtls_mpi_sub_abs #3 (|B| >> |A| with more limbs)
+mbedtls_mpi_sub_abs:10:"-5":16:"123456789abcdef01":10:"0":MBEDTLS_ERR_MPI_NEGATIVE_VALUE
+
+Base test mbedtls_mpi_sub_abs #4 (|B| >> |A| with more limbs)
+mbedtls_mpi_sub_abs:10:"5":16:"-123456789abcdef01":10:"0":MBEDTLS_ERR_MPI_NEGATIVE_VALUE
+
 Base test mbedtls_mpi_sub_abs #1
 mbedtls_mpi_sub_abs:10:"7":10:"5":10:"2":0
 
diff --git a/tests/suites/test_suite_mpi.function b/tests/suites/test_suite_mpi.function
index ffda605..2384d12 100644
--- a/tests/suites/test_suite_mpi.function
+++ b/tests/suites/test_suite_mpi.function
@@ -375,7 +375,8 @@
     if( result == 0)
     {
 
-        TEST_ASSERT( hexcmp( buf, input_A->x, buflen, input_A->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
+                                          buflen, input_A->len ) == 0 );
     }
 
 exit:
@@ -409,7 +410,8 @@
         TEST_ASSERT( mbedtls_mpi_write_binary( &X, buf, buflen ) == 0 );
 
 
-        TEST_ASSERT( hexcmp( buf, input_A->x, buflen, input_A->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
+                                          buflen, input_A->len ) == 0 );
     }
 
 exit:
@@ -563,7 +565,7 @@
                             int size_Y, char * input_Y,
                             int input_ret, int input_err )
 {
-    unsigned ret;
+    unsigned ret = -1;
     unsigned input_uret = input_ret;
     mbedtls_mpi X, Y;
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
@@ -796,6 +798,15 @@
     TEST_ASSERT( mbedtls_mpi_add_mpi( &Z, &X, &Y ) == 0 );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
 
+    /* result == first operand */
+    TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &Y ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
+
+    /* result == second operand */
+    TEST_ASSERT( mbedtls_mpi_add_mpi( &Y, &X, &Y ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
+
 exit:
     mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
 }
@@ -841,44 +852,17 @@
     TEST_ASSERT( mbedtls_mpi_add_abs( &Z, &X, &Y ) == 0 );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
 
-exit:
-    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
-}
-/* END_CASE */
-
-/* BEGIN_CASE */
-void mpi_add_abs_add_first( int radix_X, char * input_X, int radix_Y,
-                            char * input_Y, int radix_A, char * input_A )
-{
-    mbedtls_mpi X, Y, A;
-    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &A );
-
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Y, radix_Y, input_Y ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &A, radix_A, input_A ) == 0 );
+    /* result == first operand */
     TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &Y ) == 0 );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
-
-exit:
-    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &A );
-}
-/* END_CASE */
-
-/* BEGIN_CASE */
-void mpi_add_abs_add_second( int radix_X, char * input_X, int radix_Y,
-                             char * input_Y, int radix_A, char * input_A )
-{
-    mbedtls_mpi X, Y, A;
-    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &A );
-
     TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Y, radix_Y, input_Y ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &A, radix_A, input_A ) == 0 );
+
+    /* result == second operand */
     TEST_ASSERT( mbedtls_mpi_add_abs( &Y, &X, &Y ) == 0 );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
 
 exit:
-    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &A );
+    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
 }
 /* END_CASE */
 
@@ -912,6 +896,15 @@
     TEST_ASSERT( mbedtls_mpi_sub_mpi( &Z, &X, &Y ) == 0 );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
 
+    /* result == first operand */
+    TEST_ASSERT( mbedtls_mpi_sub_mpi( &X, &X, &Y ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
+
+    /* result == second operand */
+    TEST_ASSERT( mbedtls_mpi_sub_mpi( &Y, &X, &Y ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
+
 exit:
     mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
 }
@@ -935,6 +928,17 @@
     if( res == 0 )
         TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
 
+    /* result == first operand */
+    TEST_ASSERT( mbedtls_mpi_sub_abs( &X, &X, &Y ) == sub_result );
+    if( sub_result == 0 )
+        TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
+
+    /* result == second operand */
+    TEST_ASSERT( mbedtls_mpi_sub_abs( &Y, &X, &Y ) == sub_result );
+    if( sub_result == 0 )
+        TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
+
 exit:
     mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
 }
diff --git a/tests/suites/test_suite_pkcs1_v15.function b/tests/suites/test_suite_pkcs1_v15.function
index 08f590b..a1e11f7 100644
--- a/tests/suites/test_suite_pkcs1_v15.function
+++ b/tests/suites/test_suite_pkcs1_v15.function
@@ -12,7 +12,7 @@
 void pkcs1_rsaes_v15_encrypt( int mod, int radix_N, char * input_N,
                               int radix_E, char * input_E, int hash,
                               data_t * message_str, data_t * rnd_buf,
-                              data_t * result_hex_str, int result )
+                              data_t * result_str, int result )
 {
     unsigned char output[128];
     mbedtls_rsa_context ctx;
@@ -36,8 +36,8 @@
     TEST_ASSERT( mbedtls_rsa_pkcs1_encrypt( &ctx, &rnd_buffer_rand, &info, MBEDTLS_RSA_PUBLIC, message_str->len, message_str->x, output ) == result );
     if( result == 0 )
     {
-
-        TEST_ASSERT( hexcmp( output, result_hex_str->x, ctx.len, result_hex_str->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, result_str->x,
+                                          ctx.len, result_str->len ) == 0 );
     }
 
 exit:
@@ -50,7 +50,7 @@
 void pkcs1_rsaes_v15_decrypt( int mod, int radix_P, char * input_P,
                               int radix_Q, char * input_Q, int radix_N,
                               char * input_N, int radix_E, char * input_E,
-                              int hash, data_t * result_hex_str,
+                              int hash, data_t * result_str,
                               char * seed, data_t * message_str,
                               int result )
 {
@@ -78,12 +78,12 @@
     TEST_ASSERT( mbedtls_rsa_complete( &ctx ) == 0 );
     TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx ) == 0 );
 
-
     TEST_ASSERT( mbedtls_rsa_pkcs1_decrypt( &ctx, &rnd_pseudo_rand, &rnd_info, MBEDTLS_RSA_PRIVATE, &output_len, message_str->x, output, 1000 ) == result );
     if( result == 0 )
     {
-
-        TEST_ASSERT( hexcmp( output, result_hex_str->x, output_len, result_hex_str->len) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, result_str->x,
+                                          output_len,
+                                          result_str->len) == 0 );
     }
 
 exit:
@@ -246,7 +246,7 @@
                             char * input_Q, int radix_N, char * input_N,
                             int radix_E, char * input_E, int digest, int hash,
                             data_t * message_str, data_t * rnd_buf,
-                            data_t * result_hex_str, int result )
+                            data_t * result_str, int result )
 {
     unsigned char hash_result[MBEDTLS_MD_MAX_SIZE];
     unsigned char output[128];
@@ -282,7 +282,8 @@
     if( result == 0 )
     {
 
-        TEST_ASSERT( hexcmp( output, result_hex_str->x, ctx.len, result_hex_str->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, result_str->x,
+                                          ctx.len, result_str->len ) == 0 );
     }
 
 exit:
diff --git a/tests/suites/test_suite_pkcs1_v21.function b/tests/suites/test_suite_pkcs1_v21.function
index 3cd3903..a4119a2 100644
--- a/tests/suites/test_suite_pkcs1_v21.function
+++ b/tests/suites/test_suite_pkcs1_v21.function
@@ -12,7 +12,7 @@
 void pkcs1_rsaes_oaep_encrypt( int mod, int radix_N, char * input_N,
                                int radix_E, char * input_E, int hash,
                                data_t * message_str, data_t * rnd_buf,
-                               data_t * result_hex_str, int result )
+                               data_t * result_str, int result )
 {
     unsigned char output[256];
     mbedtls_rsa_context ctx;
@@ -36,8 +36,8 @@
     TEST_ASSERT( mbedtls_rsa_pkcs1_encrypt( &ctx, &rnd_buffer_rand, &info, MBEDTLS_RSA_PUBLIC, message_str->len, message_str->x, output ) == result );
     if( result == 0 )
     {
-
-        TEST_ASSERT( hexcmp( output, result_hex_str->x, ctx.len, result_hex_str->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, result_str->x,
+                                          ctx.len, result_str->len ) == 0 );
     }
 
 exit:
@@ -50,7 +50,7 @@
 void pkcs1_rsaes_oaep_decrypt( int mod, int radix_P, char * input_P,
                                int radix_Q, char * input_Q, int radix_N,
                                char * input_N, int radix_E, char * input_E,
-                               int hash, data_t * result_hex_str,
+                               int hash, data_t * result_str,
                                char * seed, data_t * message_str,
                                int result )
 {
@@ -85,7 +85,9 @@
                                             sizeof( output ) ) == result );
     if( result == 0 )
     {
-        TEST_ASSERT( hexcmp( output, result_hex_str->x, output_len, result_hex_str->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, result_str->x,
+                                          output_len,
+                                          result_str->len ) == 0 );
     }
 
 exit:
@@ -100,7 +102,7 @@
                             char * input_Q, int radix_N, char * input_N,
                             int radix_E, char * input_E, int digest, int hash,
                             data_t * message_str, data_t * rnd_buf,
-                            data_t * result_hex_str, int result )
+                            data_t * result_str, int result )
 {
     unsigned char hash_result[MBEDTLS_MD_MAX_SIZE];
     unsigned char output[256];
@@ -137,7 +139,8 @@
     if( result == 0 )
     {
 
-        TEST_ASSERT( hexcmp( output, result_hex_str->x, ctx.len, result_hex_str->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, result_str->x,
+                                          ctx.len, result_str->len ) == 0 );
     }
 
 exit:
diff --git a/tests/suites/test_suite_pkcs5.function b/tests/suites/test_suite_pkcs5.function
index 26f1d33..a525282 100644
--- a/tests/suites/test_suite_pkcs5.function
+++ b/tests/suites/test_suite_pkcs5.function
@@ -24,7 +24,8 @@
     TEST_ASSERT( mbedtls_pkcs5_pbkdf2_hmac( &ctx, pw_str->x, pw_str->len, salt_str->x, salt_str->len,
                                      it_cnt, key_len, key ) == 0 );
 
-    TEST_ASSERT( hexcmp( key, result_key_string->x, key_len, result_key_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( key, result_key_string->x,
+                                      key_len, result_key_string->len ) == 0 );
 
 exit:
     mbedtls_md_free( &ctx );
diff --git a/tests/suites/test_suite_pkwrite.function b/tests/suites/test_suite_pkwrite.function
index 43c275e..2bad4ed 100644
--- a/tests/suites/test_suite_pkwrite.function
+++ b/tests/suites/test_suite_pkwrite.function
@@ -17,7 +17,7 @@
     unsigned char check_buf[5000];
     int ret;
     FILE *f;
-    size_t ilen;
+    size_t ilen, pem_len, buf_index;
 
     memset( buf, 0, sizeof( buf ) );
     memset( check_buf, 0, sizeof( check_buf ) );
@@ -28,12 +28,20 @@
     ret = mbedtls_pk_write_pubkey_pem( &key, buf, sizeof( buf ));
     TEST_ASSERT( ret == 0 );
 
+    pem_len = strlen( (char *) buf );
+
+    // check that the rest of the buffer remains clear
+    for( buf_index = pem_len; buf_index < sizeof( buf ); ++buf_index )
+    {
+        TEST_ASSERT( buf[buf_index] == 0 );
+    }
+
     f = fopen( key_file, "r" );
     TEST_ASSERT( f != NULL );
     ilen = fread( check_buf, 1, sizeof( check_buf ), f );
     fclose( f );
 
-    TEST_ASSERT( ilen == strlen( (char *) buf ) );
+    TEST_ASSERT( ilen == pem_len );
     TEST_ASSERT( memcmp( (char *) buf, (char *) check_buf, ilen ) == 0 );
 
 exit:
@@ -49,7 +57,7 @@
     unsigned char check_buf[5000];
     int ret;
     FILE *f;
-    size_t ilen;
+    size_t ilen, pem_len, buf_index;
 
     memset( buf, 0, sizeof( buf ) );
     memset( check_buf, 0, sizeof( check_buf ) );
@@ -60,6 +68,14 @@
     ret = mbedtls_pk_write_key_pem( &key, buf, sizeof( buf ));
     TEST_ASSERT( ret == 0 );
 
+    pem_len = strlen( (char *) buf );
+
+    // check that the rest of the buffer remains clear
+    for( buf_index = pem_len; buf_index < sizeof( buf ); ++buf_index )
+    {
+        TEST_ASSERT( buf[buf_index] == 0 );
+    }
+
     f = fopen( key_file, "r" );
     TEST_ASSERT( f != NULL );
     ilen = fread( check_buf, 1, sizeof( check_buf ), f );
diff --git a/tests/suites/test_suite_poly1305.function b/tests/suites/test_suite_poly1305.function
index 44617d9..4b8995b 100644
--- a/tests/suites/test_suite_poly1305.function
+++ b/tests/suites/test_suite_poly1305.function
@@ -9,14 +9,12 @@
  */
 
 /* BEGIN_CASE */
-void mbedtls_poly1305( data_t *key, char *hex_mac_string, data_t *src_str )
+void mbedtls_poly1305( data_t *key, data_t *expected_mac, data_t *src_str )
 {
     unsigned char mac[16]; /* size set by the standard */
-    unsigned char mac_str[33]; /* hex expansion of the above */
     mbedtls_poly1305_context ctx;
 
-    memset( mac_str, 0x00, sizeof( mac_str ) );
-    memset( mac,     0x00, sizeof( mac ) );
+    memset( mac, 0x00, sizeof( mac ) );
 
     /*
      * Test the integrated API
@@ -24,8 +22,8 @@
     TEST_ASSERT( mbedtls_poly1305_mac( key->x, src_str->x,
                                        src_str->len, mac ) == 0 );
 
-    mbedtls_test_hexify( mac_str, mac, 16 );
-    TEST_ASSERT( strcmp( (char *) mac_str, hex_mac_string ) == 0 );
+    ASSERT_COMPARE( mac, expected_mac->len,
+                    expected_mac->x, expected_mac->len );
 
     /*
      * Test the streaming API
@@ -38,8 +36,8 @@
 
     TEST_ASSERT( mbedtls_poly1305_finish( &ctx, mac ) == 0 );
 
-    mbedtls_test_hexify( mac_str, mac, 16 );
-    TEST_ASSERT( strcmp( (char *) mac_str, hex_mac_string ) == 0 );
+    ASSERT_COMPARE( mac, expected_mac->len,
+                    expected_mac->x, expected_mac->len );
 
     /*
      * Test the streaming API again, piecewise
@@ -56,8 +54,8 @@
 
         TEST_ASSERT( mbedtls_poly1305_finish( &ctx, mac ) == 0 );
 
-        mbedtls_test_hexify( mac_str, mac, 16 );
-        TEST_ASSERT( strcmp( (char *) mac_str, hex_mac_string ) == 0 );
+        ASSERT_COMPARE( mac, expected_mac->len,
+                        expected_mac->x, expected_mac->len );
     }
 
     /*
@@ -73,8 +71,8 @@
 
         TEST_ASSERT( mbedtls_poly1305_finish( &ctx, mac ) == 0 );
 
-        mbedtls_test_hexify( mac_str, mac, 16 );
-        TEST_ASSERT( strcmp( (char *) mac_str, hex_mac_string ) == 0 );
+        ASSERT_COMPARE( mac, expected_mac->len,
+                        expected_mac->x, expected_mac->len );
     }
 
     mbedtls_poly1305_free( &ctx );
diff --git a/tests/suites/test_suite_rsa.data b/tests/suites/test_suite_rsa.data
index 5e4de17..4ed8339 100644
--- a/tests/suites/test_suite_rsa.data
+++ b/tests/suites/test_suite_rsa.data
@@ -1,6 +1,12 @@
 RSA parameter validation
 rsa_invalid_param:
 
+RSA init-free-free
+rsa_init_free:0
+
+RSA init-free-init-free
+rsa_init_free:1
+
 RSA PKCS1 Verify v1.5 CAVS #1
 depends_on:MBEDTLS_SHA1_C:MBEDTLS_PKCS1_V15
 # Good padding but wrong hash
diff --git a/tests/suites/test_suite_rsa.function b/tests/suites/test_suite_rsa.function
index 9a3b583..89b419f 100644
--- a/tests/suites/test_suite_rsa.function
+++ b/tests/suites/test_suite_rsa.function
@@ -466,11 +466,34 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
+void rsa_init_free( int reinit )
+{
+    mbedtls_rsa_context ctx;
+
+    /* Double free is not explicitly documented to work, but we rely on it
+     * even inside the library so that you can call mbedtls_rsa_free()
+     * unconditionally on an error path without checking whether it has
+     * already been called in the success path. */
+
+    mbedtls_rsa_init( &ctx, 0, 0 );
+    mbedtls_rsa_free( &ctx );
+
+    if( reinit )
+        mbedtls_rsa_init( &ctx, 0, 0 );
+    mbedtls_rsa_free( &ctx );
+
+    /* This test case always succeeds, functionally speaking. A plausible
+     * bug might trigger an invalid pointer dereference or a memory leak. */
+    goto exit;
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
 void mbedtls_rsa_pkcs1_sign( data_t * message_str, int padding_mode,
                              int digest, int mod, int radix_P, char * input_P,
                              int radix_Q, char * input_Q, int radix_N,
                              char * input_N, int radix_E, char * input_E,
-                             data_t * result_hex_str, int result )
+                             data_t * result_str, int result )
 {
     unsigned char hash_result[MBEDTLS_MD_MAX_SIZE];
     unsigned char output[256];
@@ -506,7 +529,8 @@
     if( result == 0 )
     {
 
-        TEST_ASSERT( hexcmp( output, result_hex_str->x, ctx.len, result_hex_str->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, result_str->x,
+                                          ctx.len, result_str->len ) == 0 );
     }
 
 exit:
@@ -555,7 +579,7 @@
                          int padding_mode, int mod, int radix_P,
                          char * input_P, int radix_Q, char * input_Q,
                          int radix_N, char * input_N, int radix_E,
-                         char * input_E, data_t * result_hex_str )
+                         char * input_E, data_t * result_str )
 {
     unsigned char output[256];
     mbedtls_rsa_context ctx;
@@ -586,7 +610,8 @@
                                          output ) == 0 );
 
 
-    TEST_ASSERT( hexcmp( output, result_hex_str->x, ctx.len, result_hex_str->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, result_str->x,
+                                      ctx.len, result_str->len ) == 0 );
 
 #if defined(MBEDTLS_PKCS1_V15)
     /* For PKCS#1 v1.5, there is an alternative way to generate signatures */
@@ -608,7 +633,9 @@
 
         if( res == 0 )
         {
-            TEST_ASSERT( hexcmp( output, result_hex_str->x, ctx.len, result_hex_str->len ) == 0 );
+            TEST_ASSERT( mbedtls_test_hexcmp( output, result_str->x,
+                                              ctx.len,
+                                              result_str->len ) == 0 );
         }
     }
 #endif /* MBEDTLS_PKCS1_V15 */
@@ -686,7 +713,7 @@
 void mbedtls_rsa_pkcs1_encrypt( data_t * message_str, int padding_mode,
                                 int mod, int radix_N, char * input_N,
                                 int radix_E, char * input_E,
-                                data_t * result_hex_str, int result )
+                                data_t * result_str, int result )
 {
     unsigned char output[256];
     mbedtls_rsa_context ctx;
@@ -714,7 +741,8 @@
     if( result == 0 )
     {
 
-        TEST_ASSERT( hexcmp( output, result_hex_str->x, ctx.len, result_hex_str->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, result_str->x,
+                                          ctx.len, result_str->len ) == 0 );
     }
 
 exit:
@@ -727,7 +755,7 @@
 void rsa_pkcs1_encrypt_bad_rng( data_t * message_str, int padding_mode,
                                 int mod, int radix_N, char * input_N,
                                 int radix_E, char * input_E,
-                                data_t * result_hex_str, int result )
+                                data_t * result_str, int result )
 {
     unsigned char output[256];
     mbedtls_rsa_context ctx;
@@ -752,7 +780,8 @@
     if( result == 0 )
     {
 
-        TEST_ASSERT( hexcmp( output, result_hex_str->x, ctx.len, result_hex_str->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, result_str->x,
+                                          ctx.len, result_str->len ) == 0 );
     }
 
 exit:
@@ -766,7 +795,7 @@
                                 int mod, int radix_P, char * input_P,
                                 int radix_Q, char * input_Q, int radix_N,
                                 char * input_N, int radix_E, char * input_E,
-                                int max_output, data_t * result_hex_str,
+                                int max_output, data_t * result_str,
                                 int result )
 {
     unsigned char output[32];
@@ -800,7 +829,9 @@
     if( result == 0 )
     {
 
-        TEST_ASSERT( hexcmp( output, result_hex_str->x, output_len, result_hex_str->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, result_str->x,
+                                          output_len,
+                                          result_str->len ) == 0 );
     }
 
 exit:
@@ -813,7 +844,7 @@
 /* BEGIN_CASE */
 void mbedtls_rsa_public( data_t * message_str, int mod, int radix_N,
                          char * input_N, int radix_E, char * input_E,
-                         data_t * result_hex_str, int result )
+                         data_t * result_str, int result )
 {
     unsigned char output[256];
     mbedtls_rsa_context ctx, ctx2; /* Also test mbedtls_rsa_copy() while at it */
@@ -837,7 +868,8 @@
     if( result == 0 )
     {
 
-        TEST_ASSERT( hexcmp( output, result_hex_str->x, ctx.len, result_hex_str->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, result_str->x,
+                                          ctx.len, result_str->len ) == 0 );
     }
 
     /* And now with the copy */
@@ -852,7 +884,8 @@
     if( result == 0 )
     {
 
-        TEST_ASSERT( hexcmp( output, result_hex_str->x, ctx.len, result_hex_str->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, result_str->x,
+                                          ctx.len, result_str->len ) == 0 );
     }
 
 exit:
@@ -866,7 +899,7 @@
 void mbedtls_rsa_private( data_t * message_str, int mod, int radix_P,
                           char * input_P, int radix_Q, char * input_Q,
                           int radix_N, char * input_N, int radix_E,
-                          char * input_E, data_t * result_hex_str,
+                          char * input_E, data_t * result_str,
                           int result )
 {
     unsigned char output[256];
@@ -902,7 +935,9 @@
         if( result == 0 )
         {
 
-            TEST_ASSERT( hexcmp( output, result_hex_str->x, ctx.len, result_hex_str->len ) == 0 );
+            TEST_ASSERT( mbedtls_test_hexcmp( output, result_str->x,
+                                              ctx.len,
+                                              result_str->len ) == 0 );
         }
     }
 
@@ -919,7 +954,9 @@
     if( result == 0 )
     {
 
-        TEST_ASSERT( hexcmp( output, result_hex_str->x, ctx2.len, result_hex_str->len ) == 0 );
+        TEST_ASSERT( mbedtls_test_hexcmp( output, result_str->x,
+                                          ctx2.len,
+                                          result_str->len ) == 0 );
     }
 
 exit:
diff --git a/tests/suites/test_suite_shax.function b/tests/suites/test_suite_shax.function
index e621f49..f3477ec 100644
--- a/tests/suites/test_suite_shax.function
+++ b/tests/suites/test_suite_shax.function
@@ -52,7 +52,7 @@
 /* END_CASE */
 
 /* BEGIN_CASE depends_on:MBEDTLS_SHA1_C */
-void mbedtls_sha1( data_t * src_str, data_t * hex_hash_string )
+void mbedtls_sha1( data_t * src_str, data_t * hash )
 {
     unsigned char output[41];
 
@@ -61,7 +61,7 @@
 
     TEST_ASSERT( mbedtls_sha1_ret( src_str->x, src_str->len, output ) == 0 );
 
-    TEST_ASSERT( hexcmp( output, hex_hash_string->x, 20, hex_hash_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x, 20, hash->len ) == 0 );
 }
 /* END_CASE */
 
@@ -122,7 +122,7 @@
 /* END_CASE */
 
 /* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
-void sha224( data_t * src_str, data_t * hex_hash_string )
+void sha224( data_t * src_str, data_t * hash )
 {
     unsigned char output[57];
 
@@ -131,12 +131,12 @@
 
     TEST_ASSERT( mbedtls_sha256_ret( src_str->x, src_str->len, output, 1 ) == 0 );
 
-    TEST_ASSERT( hexcmp( output, hex_hash_string->x, 28, hex_hash_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x, 28, hash->len ) == 0 );
 }
 /* END_CASE */
 
 /* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
-void mbedtls_sha256( data_t * src_str, data_t * hex_hash_string )
+void mbedtls_sha256( data_t * src_str, data_t * hash )
 {
     unsigned char output[65];
 
@@ -145,7 +145,7 @@
 
     TEST_ASSERT( mbedtls_sha256_ret( src_str->x, src_str->len, output, 0 ) == 0 );
 
-    TEST_ASSERT( hexcmp( output, hex_hash_string->x, 32, hex_hash_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x, 32, hash->len ) == 0 );
 }
 /* END_CASE */
 
@@ -206,7 +206,7 @@
 /* END_CASE */
 
 /* BEGIN_CASE depends_on:MBEDTLS_SHA512_C */
-void sha384( data_t * src_str, data_t * hex_hash_string )
+void sha384( data_t * src_str, data_t * hash )
 {
     unsigned char output[97];
 
@@ -215,12 +215,12 @@
 
     TEST_ASSERT( mbedtls_sha512_ret( src_str->x, src_str->len, output, 1 ) == 0 );
 
-    TEST_ASSERT( hexcmp( output, hex_hash_string->x, 48, hex_hash_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x, 48, hash->len ) == 0 );
 }
 /* END_CASE */
 
 /* BEGIN_CASE depends_on:MBEDTLS_SHA512_C */
-void mbedtls_sha512( data_t * src_str, data_t * hex_hash_string )
+void mbedtls_sha512( data_t * src_str, data_t * hash )
 {
     unsigned char output[129];
 
@@ -229,7 +229,7 @@
 
     TEST_ASSERT( mbedtls_sha512_ret( src_str->x, src_str->len, output, 0 ) == 0 );
 
-    TEST_ASSERT( hexcmp( output, hex_hash_string->x, 64, hex_hash_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, hash->x, 64, hash->len ) == 0 );
 }
 /* END_CASE */
 
diff --git a/tests/suites/test_suite_version.data b/tests/suites/test_suite_version.data
index 6a0ac0b..d43ddad 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.7"
+check_compiletime_version:"2.16.9"
 
 Check runtime library version
-check_runtime_version:"2.16.7"
+check_runtime_version:"2.16.9"
 
 Check for MBEDTLS_VERSION_C
 check_feature:"MBEDTLS_VERSION_C":0
diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data
index 14ba0de..2d1aeca 100644
--- a/tests/suites/test_suite_x509parse.data
+++ b/tests/suites/test_suite_x509parse.data
@@ -843,6 +843,14 @@
 depends_on:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_ECDSA_C:MBEDTLS_SHA1_C
 x509_verify:"data_files/cert_sha256.crt":"data_files/test-ca.crt":"data_files/crl-ec-sha256.pem":"NULL":0:0:"next":"NULL"
 
+X509 CRT verification #98 (Revoked Cert, revocation date in the future, _with_ MBEDTLS_HAVE_TIME_DATE)
+depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_SHA1_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_HAVE_TIME_DATE
+x509_verify:"data_files/server1.crt":"data_files/test-ca.crt":"data_files/crl-futureRevocationDate.pem":"NULL":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_REVOKED|MBEDTLS_X509_BADCRL_FUTURE:"compat":"NULL"
+
+X509 CRT verification #99 (Revoked Cert, revocation date in the future, _without_ MBEDTLS_HAVE_TIME_DATE)
+depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_SHA1_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:!MBEDTLS_HAVE_TIME_DATE
+x509_verify:"data_files/server1.crt":"data_files/test-ca.crt":"data_files/crl-futureRevocationDate.pem":"NULL":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_REVOKED:"compat":"NULL"
+
 X509 Certificate verification: domain identical to IPv4 in SubjectAltName
 depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_SHA256_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_RSA_C
 x509_verify:"data_files/server5-tricky-ip-san.crt":"data_files/server5-tricky-ip-san.crt":"data_files/crl_sha256.pem":"abcd":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_CN_MISMATCH:"":"NULL"
diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function
index e6b1b47..664aac7 100644
--- a/tests/suites/test_suite_x509parse.function
+++ b/tests/suites/test_suite_x509parse.function
@@ -804,21 +804,21 @@
 /* END_CASE */
 
 /* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C:MBEDTLS_X509_RSASSA_PSS_SUPPORT */
-void x509_parse_rsassa_pss_params( data_t * hex_params, int params_tag,
+void x509_parse_rsassa_pss_params( data_t * params, int params_tag,
                                    int ref_msg_md, int ref_mgf_md,
                                    int ref_salt_len, int ref_ret )
 {
     int my_ret;
-    mbedtls_x509_buf params;
+    mbedtls_x509_buf buf;
     mbedtls_md_type_t my_msg_md, my_mgf_md;
     int my_salt_len;
 
-    params.p = hex_params->x;
-    params.len = hex_params->len;
-    params.tag = params_tag;
+    buf.p = params->x;
+    buf.len = params->len;
+    buf.tag = params_tag;
 
-    my_ret = mbedtls_x509_get_rsassa_pss_params( &params, &my_msg_md, &my_mgf_md,
-                                         &my_salt_len );
+    my_ret = mbedtls_x509_get_rsassa_pss_params( &buf, &my_msg_md, &my_mgf_md,
+                                                 &my_salt_len );
 
     TEST_ASSERT( my_ret == ref_ret );
 
diff --git a/tests/suites/test_suite_x509write.function b/tests/suites/test_suite_x509write.function
index 535807e..40bccd6 100644
--- a/tests/suites/test_suite_x509write.function
+++ b/tests/suites/test_suite_x509write.function
@@ -45,7 +45,7 @@
     unsigned char buf[4096];
     unsigned char check_buf[4000];
     int ret;
-    size_t olen = 0, pem_len = 0;
+    size_t olen = 0, pem_len = 0, buf_index;
     int der_len = -1;
     FILE *f;
     const char *subject_name = "C=NL,O=PolarSSL,CN=PolarSSL Server 1";
@@ -71,6 +71,11 @@
 
     pem_len = strlen( (char *) buf );
 
+    for( buf_index = pem_len; buf_index < sizeof( buf ); ++buf_index )
+    {
+        TEST_ASSERT( buf[buf_index] == 0 );
+    }
+
     f = fopen( cert_req_check_file, "r" );
     TEST_ASSERT( f != NULL );
     olen = fread( check_buf, 1, sizeof( check_buf ), f );
@@ -113,7 +118,7 @@
     unsigned char check_buf[5000];
     mbedtls_mpi serial;
     int ret;
-    size_t olen = 0, pem_len = 0;
+    size_t olen = 0, pem_len = 0, buf_index = 0;
     int der_len = -1;
     FILE *f;
     rnd_pseudo_info rnd_info;
@@ -182,6 +187,12 @@
 
     pem_len = strlen( (char *) buf );
 
+    // check that the rest of the buffer remains clear
+    for( buf_index = pem_len; buf_index < sizeof( buf ); ++buf_index )
+    {
+        TEST_ASSERT( buf[buf_index] == 0 );
+    }
+
     f = fopen( cert_check_file, "r" );
     TEST_ASSERT( f != NULL );
     olen = fread( check_buf, 1, sizeof( check_buf ), f );
diff --git a/tests/suites/test_suite_xtea.function b/tests/suites/test_suite_xtea.function
index a24a420..1d5b29b 100644
--- a/tests/suites/test_suite_xtea.function
+++ b/tests/suites/test_suite_xtea.function
@@ -9,7 +9,7 @@
 
 /* BEGIN_CASE */
 void xtea_encrypt_ecb( data_t * key_str, data_t * src_str,
-                       data_t * hex_dst_string )
+                       data_t * dst )
 {
     unsigned char output[100];
     mbedtls_xtea_context ctx;
@@ -20,13 +20,12 @@
     mbedtls_xtea_setup( &ctx, key_str->x );
     TEST_ASSERT( mbedtls_xtea_crypt_ecb( &ctx, MBEDTLS_XTEA_ENCRYPT, src_str->x, output ) == 0 );
 
-    TEST_ASSERT( hexcmp( output, hex_dst_string->x, 8, hex_dst_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 8, dst->len ) == 0 );
 }
 /* END_CASE */
 
 /* BEGIN_CASE */
-void xtea_decrypt_ecb( data_t * key_str, data_t * src_str,
-                       data_t * hex_dst_string )
+void xtea_decrypt_ecb( data_t * key_str, data_t * src_str, data_t * dst )
 {
     unsigned char output[100];
     mbedtls_xtea_context ctx;
@@ -37,13 +36,13 @@
     mbedtls_xtea_setup( &ctx, key_str->x );
     TEST_ASSERT( mbedtls_xtea_crypt_ecb( &ctx, MBEDTLS_XTEA_DECRYPT, src_str->x, output ) == 0 );
 
-    TEST_ASSERT( hexcmp( output, hex_dst_string->x, 8, hex_dst_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 8, dst->len ) == 0 );
 }
 /* END_CASE */
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
 void xtea_encrypt_cbc( data_t * key_str, data_t * iv_str,
-                       data_t * src_str, data_t * hex_dst_string )
+                       data_t * src_str, data_t * dst )
 {
     unsigned char output[100];
     mbedtls_xtea_context ctx;
@@ -55,13 +54,14 @@
     TEST_ASSERT( mbedtls_xtea_crypt_cbc( &ctx, MBEDTLS_XTEA_ENCRYPT, src_str->len, iv_str->x,
                                  src_str->x, output ) == 0 );
 
-    TEST_ASSERT( hexcmp( output, hex_dst_string->x, src_str->len, hex_dst_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x,
+                                      src_str->len, dst->len ) == 0 );
 }
 /* END_CASE */
 
 /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
 void xtea_decrypt_cbc( data_t * key_str, data_t * iv_str,
-                       data_t * src_str, data_t * hex_dst_string )
+                       data_t * src_str, data_t * dst )
 {
     unsigned char output[100];
     mbedtls_xtea_context ctx;
@@ -73,7 +73,8 @@
     TEST_ASSERT( mbedtls_xtea_crypt_cbc( &ctx, MBEDTLS_XTEA_DECRYPT, src_str->len, iv_str->x,
                                  src_str->x, output ) == 0 );
 
-    TEST_ASSERT( hexcmp( output, hex_dst_string->x, src_str->len, hex_dst_string->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x,
+                                      src_str->len, dst->len ) == 0 );
 }
 /* END_CASE */