diff --git a/.gitignore b/.gitignore
index 789f57ee0f1c65cdcf311471ff849a3ac86f5615..5fb0bdebf8d871385b61ec06d1e073368fc994f4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -40,4 +40,5 @@ massif-*
 /GSYMS
 /GTAGS
 /TAGS
+/cscope*.out
 /tags
diff --git a/ChangeLog b/ChangeLog
index c68bd1b65b79c8d09f15b42b3a41067170e57b96..fe7aecd27b0b3c5af906accee197e322a41f351b 100755
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,120 @@
 mbed TLS ChangeLog (Sorted per branch, date)
 
+= mbed TLS 2.16.10 branch released 2021-03-12
+
+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.
+
+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.
+   * 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.
+   * 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.
+   * Guard against strong local side channel attack against base64 tables by
+     making access aceess to them use constant flow code.
+
+Bugfix
+   * Fix an incorrect error code if an RSA private operation glitched.
+   * 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.
+   * 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.
+   * This change makes 'mbedtls_x509write_crt_set_basic_constraints'
+     consistent with RFC 5280 4.2.1.9 which says: "Conforming CAs MUST
+     include this extension in all CA certificates that contain public keys
+     used to validate digital signatures on certificates and MUST mark the
+     extension as critical in such certificates." Previous to this change,
+     the extension was always marked as non-critical. This was fixed by
+     #4044.
+
+= 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
diff --git a/ChangeLog.d/00README.md b/ChangeLog.d/00README.md
index b559e2336cbe198f4f7eabcca525a37ee77f7030..a2e096f4e80b1b40b94ac79be10f3e52b088f2fc 100755
--- 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 @@ The permitted changelog entry categories are as follows:
     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 @@ Include GitHub issue numbers where relevant. Use the format “#1234” for an
 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/Makefile b/Makefile
index 24d529a5474f04eb2fb062bcb700f6688175cdf5..3942fbd3d598101617e6723ef2256828e08ecb6a 100755
--- a/Makefile
+++ b/Makefile
@@ -129,5 +129,10 @@ tags: $(C_SOURCE_FILES)
 	$(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/OAT.xml b/OAT.xml
new file mode 100644
index 0000000000000000000000000000000000000000..661a826da459ed2766fd4cf70203f69f98a69dc9
--- /dev/null
+++ b/OAT.xml
@@ -0,0 +1,57 @@
+
+
+
+
+    
+        LICENSE
+        
+            
+                
+            
+        
+    
+
diff --git a/doxygen/input/doc_mainpage.h b/doxygen/input/doc_mainpage.h
index acd8be1f7d0764ea255fd4e6337be87931aad74a..e640c7bbdc02e05c0d873894216df1e919213881 100755
--- a/doxygen/input/doc_mainpage.h
+++ b/doxygen/input/doc_mainpage.h
@@ -49,7 +49,7 @@
  */
 
 /**
- * @mainpage mbed TLS v2.16.8 source code documentation
+ * @mainpage mbed TLS v2.16.10 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 45398b70c9568302a08e90924bd15ce39412a0cc..61a42c48ac6841fc3e512632e53bae5a4a9e3c4f 100755
--- a/doxygen/mbedtls.doxyfile
+++ b/doxygen/mbedtls.doxyfile
@@ -28,7 +28,7 @@ DOXYFILE_ENCODING      = UTF-8
 # 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.8"
+PROJECT_NAME           = "mbed TLS v2.16.10"
 
 # 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 4bb9fa3d435b83469fac8460487aa7f764414584..4d04b336e7a65cab1e7e3ceaef319563f9db29a3 100755
--- 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 3dcdc9189470e7d5c9d6d0a23b73d5bf2d6e60fb..d50c6ec9939874844b272a415c1f3ae5d8af105d 100755
--- a/include/mbedtls/ccm.h
+++ b/include/mbedtls/ccm.h
@@ -175,7 +175,7 @@ void mbedtls_ccm_free( mbedtls_ccm_context *ctx );
  *                  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 @@ int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
  *                  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 4acbadc498695420ce4cd4152872819c79c4ad84..6e0d9e982e02935fb1bfb213df35b7f3643f616d 100755
--- 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
  *
diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h
index 7e5f2e5769ba47f3cc11016af00fbfa159972068..6c099adf4d33011ace380f45c5eb2bb392dc64aa 100755
--- a/include/mbedtls/ctr_drbg.h
+++ b/include/mbedtls/ctr_drbg.h
@@ -214,6 +214,13 @@ typedef struct mbedtls_ctr_drbg_context
     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 @@ mbedtls_ctr_drbg_context;
  *                      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 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx );
  *                      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 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx );
  *                      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 @@ int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
                    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 @@ void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx,
  * \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 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
 /**
  * \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 @@ int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx,
  * 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 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng,
  *
  * 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 1e1d3f56ec63fd728dd9bf4d5fda377bcdef92be..1d6e9b821bf7c90ed4fa342d061798f1720cc7f3 100755
--- a/include/mbedtls/entropy.h
+++ b/include/mbedtls/entropy.h
@@ -147,13 +147,15 @@ mbedtls_entropy_source_state;
  */
 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 4e4434ed4dfd1ce6686dd589547fb4b59fcd6526..1201fbd4f10c7e2f075109c1941dd14e2d1331f0 100755
--- a/include/mbedtls/gcm.h
+++ b/include/mbedtls/gcm.h
@@ -182,7 +182,7 @@ int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
  *                  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 @@ int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
  *                  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 68836782043d057ba612e1e36cef32debd14828b..5718e187a9f799e5dc0f5b8fca8a7052b1fd766c 100755
--- a/include/mbedtls/hmac_drbg.h
+++ b/include/mbedtls/hmac_drbg.h
@@ -128,6 +128,14 @@ typedef struct mbedtls_hmac_drbg_context
     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 @@ typedef struct mbedtls_hmac_drbg_context
  * 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 @@ void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx );
  * \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 @@ int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
  *
  * 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 @@ void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx,
 /**
  * \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 @@ int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
  * \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 @@ int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
  * 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 @@ int mbedtls_hmac_drbg_random_with_add( void *p_rng,
  *
  * 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_with_add( void *p_rng,
 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 00fea7db197be8cbcd69a0b116559b9b18652e43..c6e1a0270e855c6ff92af7fcebf4f3b00f151d41 100755
--- a/include/mbedtls/net_sockets.h
+++ b/include/mbedtls/net_sockets.h
@@ -151,6 +151,7 @@ int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host, const char
  *
  * \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 @@ int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char
  *                  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 @@ int mbedtls_net_accept( mbedtls_net_context *bind_ctx,
 /**
  * \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 @@ int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len );
  *                 '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 188c37cf3aa9291c5fa8c353321d350e6d18860a..b2f65334fe74d99312440dd74df7527828b3eb17 100755
--- a/include/mbedtls/rsa.h
+++ b/include/mbedtls/rsa.h
@@ -124,7 +124,10 @@ extern "C" {
  */
 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 @@ typedef struct mbedtls_rsa_context
                                      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 9ff78ecf41801eba4b9c95fad41fd2088be740cf..5e5a15e0008c055411304ff9992883f20c07df9d 100755
--- a/include/mbedtls/sha512.h
+++ b/include/mbedtls/sha512.h
@@ -152,8 +152,7 @@ int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
 
 /**
  * \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 @@ int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
 /**
  * \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 d3ee3c4e6f62fb7fddde9ea36fb7bac8138deb60..fe33ac8d576bc866f47246d6af9d1e3988f87242 100755
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -1409,7 +1409,7 @@ void mbedtls_ssl_conf_dbg( mbedtls_ssl_config *conf,
  * \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 a8183a6ef48ec310277bc54030142f203a3218a3..45161ce467c5eae5727a467292a6cac2d9f4d18c 100755
--- a/include/mbedtls/threading.h
+++ b/include/mbedtls/threading.h
@@ -73,6 +73,9 @@ extern "C" {
 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 d09b45002d59d80460d8c02d4b33d60ee760a7d1..bd5c730c1d5857a1ca99cd4e6cef8d94d73d4917 100755
--- 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  8
+#define MBEDTLS_VERSION_PATCH  10
 
 /**
  * The single version number has the following structure:
  *    MMNNPP00
  *    Major version | Minor version | Patch version
  */
-#define MBEDTLS_VERSION_NUMBER         0x02100800
-#define MBEDTLS_VERSION_STRING         "2.16.8"
-#define MBEDTLS_VERSION_STRING_FULL    "mbed TLS 2.16.8"
+#define MBEDTLS_VERSION_NUMBER         0x02100A00
+#define MBEDTLS_VERSION_STRING         "2.16.10"
+#define MBEDTLS_VERSION_STRING_FULL    "mbed TLS 2.16.10"
 
 #if defined(MBEDTLS_VERSION_C)
 
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index beec785d1f30a0c9231531609351fde51c50d628..4f61f9994e87760dd9bfd0c6b0b25a38bcac5331 100755
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -165,15 +165,15 @@ endif(USE_STATIC_MBEDTLS_LIBRARY)
 
 if(USE_SHARED_MBEDTLS_LIBRARY)
     add_library(mbedcrypto SHARED ${src_crypto})
-    set_target_properties(mbedcrypto PROPERTIES VERSION 2.16.8 SOVERSION 3)
+    set_target_properties(mbedcrypto PROPERTIES VERSION 2.16.10 SOVERSION 3)
     target_link_libraries(mbedcrypto ${libs})
 
     add_library(mbedx509 SHARED ${src_x509})
-    set_target_properties(mbedx509 PROPERTIES VERSION 2.16.8 SOVERSION 0)
+    set_target_properties(mbedx509 PROPERTIES VERSION 2.16.10 SOVERSION 0)
     target_link_libraries(mbedx509 ${libs} mbedcrypto)
 
     add_library(mbedtls SHARED ${src_tls})
-    set_target_properties(mbedtls PROPERTIES VERSION 2.16.8 SOVERSION 12)
+    set_target_properties(mbedtls PROPERTIES VERSION 2.16.10 SOVERSION 12)
     target_link_libraries(mbedtls ${libs} mbedx509)
 
     install(TARGETS mbedtls mbedx509 mbedcrypto
diff --git a/library/aes.c b/library/aes.c
index 9b337505fd15c8152650ab098681e66804853b95..da0e5b6bdced4dc3d1556fecf0dd633b69021552 100755
--- a/library/aes.c
+++ b/library/aes.c
@@ -760,6 +760,7 @@ exit:
 
     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 @@ int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
 }
 #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 @@ int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
                                   unsigned char output[16] )
 {
     int i;
-    uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
-
-    RK = ctx->rk;
+    uint32_t *RK = ctx->rk;
+    struct
+    {
+        uint32_t X[4];
+        uint32_t Y[4];
+    } t;
 
-    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 );
-
-    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 );
-
-    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 );
-
-    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 );
-
-    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 );
-
-    PUT_UINT32_LE( X0, output,  0 );
-    PUT_UINT32_LE( X1, output,  4 );
-    PUT_UINT32_LE( X2, output,  8 );
-    PUT_UINT32_LE( X3, 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 ) );
+    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] );
+
+    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 );
+
+    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 );
+
+    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 );
+
+    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( 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( &t, sizeof( t ) );
 
     return( 0 );
 }
@@ -977,63 +969,56 @@ int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
                                   unsigned char output[16] )
 {
     int i;
-    uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
-
-    RK = ctx->rk;
+    uint32_t *RK = ctx->rk;
+    struct
+    {
+        uint32_t X[4];
+        uint32_t Y[4];
+    } t;
 
-    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 );
-
-    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 );
-
-    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 );
-
-    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 );
-
-    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 );
-
-    PUT_UINT32_LE( X0, output,  0 );
-    PUT_UINT32_LE( X1, output,  4 );
-    PUT_UINT32_LE( X2, output,  8 );
-    PUT_UINT32_LE( X3, 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 ) );
+    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] );
+
+    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 );
+
+    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 );
+
+    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 );
+
+    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( 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( &t, sizeof( t ) );
 
     return( 0 );
 }
diff --git a/library/base64.c b/library/base64.c
index bfafb05353cbc02402a726c9bfa60ca3a02dc86d..692e11e3fae70f3f58027cff4f5f3d51ef0ae890 100755
--- a/library/base64.c
+++ b/library/base64.c
@@ -96,6 +96,99 @@ static const unsigned char base64_dec_map[128] =
 
 #define BASE64_SIZE_T_MAX   ( (size_t) -1 ) /* SIZE_T_MAX is not standard */
 
+/*
+ * Constant flow conditional assignment to unsigned char
+ */
+static void mbedtls_base64_cond_assign_uchar( unsigned char * dest, const unsigned char * const src,
+                                       unsigned char condition )
+{
+    /* MSVC has a warning about unary minus on unsigned integer types,
+     * but this is well-defined and precisely what we want to do here. */
+#if defined(_MSC_VER)
+#pragma warning( push )
+#pragma warning( disable : 4146 )
+#endif
+
+    /* Generate bitmask from condition, mask will either be 0xFF or 0 */
+    unsigned char mask = ( condition | -condition );
+    mask >>= 7;
+    mask = -mask;
+
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+
+    *dest = ( ( *src ) & mask ) | ( ( *dest ) & ~mask );
+}
+
+/*
+ * Constant flow conditional assignment to uint_32
+ */
+static void mbedtls_base64_cond_assign_uint32( uint32_t * dest, const uint32_t src,
+                                       uint32_t condition )
+{
+    /* MSVC has a warning about unary minus on unsigned integer types,
+     * but this is well-defined and precisely what we want to do here. */
+#if defined(_MSC_VER)
+#pragma warning( push )
+#pragma warning( disable : 4146 )
+#endif
+
+    /* Generate bitmask from condition, mask will either be 0xFFFFFFFF or 0 */
+    uint32_t mask = ( condition | -condition );
+    mask >>= 31;
+    mask = -mask;
+
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+
+    *dest = ( src & mask ) | ( ( *dest ) & ~mask );
+}
+
+/*
+ * Constant flow check for equality
+ */
+static unsigned char mbedtls_base64_eq( size_t in_a, size_t in_b )
+{
+    size_t difference = in_a ^ in_b;
+
+    /* MSVC has a warning about unary minus on unsigned integer types,
+     * but this is well-defined and precisely what we want to do here. */
+#if defined(_MSC_VER)
+#pragma warning( push )
+#pragma warning( disable : 4146 )
+#endif
+
+    difference |= -difference;
+
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+
+    /* cope with the varying size of size_t per platform */
+    difference >>= ( sizeof( difference ) * 8 - 1 );
+
+    return (unsigned char) ( 1 ^ difference );
+}
+
+/*
+ * Constant flow lookup into table.
+ */
+static unsigned char mbedtls_base64_table_lookup( const unsigned char * const table,
+                                                 const size_t table_size, const size_t table_index )
+{
+    size_t i;
+    unsigned char result = 0;
+
+    for( i = 0; i < table_size; ++i )
+    {
+        mbedtls_base64_cond_assign_uchar( &result, &table[i], mbedtls_base64_eq( i, table_index ) );
+    }
+
+    return result;
+}
+
 /*
  * Encode a buffer into base64 format
  */
@@ -136,10 +229,17 @@ int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
         C2 = *src++;
         C3 = *src++;
 
-        *p++ = base64_enc_map[(C1 >> 2) & 0x3F];
-        *p++ = base64_enc_map[(((C1 &  3) << 4) + (C2 >> 4)) & 0x3F];
-        *p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F];
-        *p++ = base64_enc_map[C3 & 0x3F];
+        *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
+                                            ( ( C1 >> 2 ) & 0x3F ) );
+
+        *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
+                                            ( ( ( ( C1 &  3 ) << 4 ) + ( C2 >> 4 ) ) & 0x3F ) );
+
+        *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
+                                            ( ( ( ( C2 & 15 ) << 2 ) + ( C3 >> 6 ) ) & 0x3F ) );
+
+        *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
+                                            ( C3 & 0x3F ) );
     }
 
     if( i < slen )
@@ -147,11 +247,15 @@ int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
         C1 = *src++;
         C2 = ( ( i + 1 ) < slen ) ? *src++ : 0;
 
-        *p++ = base64_enc_map[(C1 >> 2) & 0x3F];
-        *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
+        *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
+                                            ( ( C1 >> 2 ) & 0x3F ) );
+
+        *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
+                                            ( ( ( ( C1 & 3 ) << 4 ) + ( C2 >> 4 ) ) & 0x3F ) );
 
         if( ( i + 1 ) < slen )
-             *p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F];
+             *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
+                                                 ( ( ( C2 & 15 ) << 2 ) & 0x3F ) );
         else *p++ = '=';
 
         *p++ = '=';
@@ -172,6 +276,7 @@ int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
     size_t i, n;
     uint32_t j, x;
     unsigned char *p;
+    unsigned char dec_map_lookup;
 
     /* First pass: check for validity and get output length */
     for( i = n = j = 0; i < slen; i++ )
@@ -202,10 +307,12 @@ int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
         if( src[i] == '=' && ++j > 2 )
             return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
 
-        if( src[i] > 127 || base64_dec_map[src[i]] == 127 )
+        dec_map_lookup = mbedtls_base64_table_lookup( base64_dec_map, sizeof( base64_dec_map ), src[i] );
+
+        if( src[i] > 127 || dec_map_lookup == 127 )
             return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
 
-        if( base64_dec_map[src[i]] < 64 && j != 0 )
+        if( dec_map_lookup < 64 && j != 0 )
             return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
 
         n++;
@@ -235,8 +342,10 @@ int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
         if( *src == '\r' || *src == '\n' || *src == ' ' )
             continue;
 
-        j -= ( base64_dec_map[*src] == 64 );
-        x  = ( x << 6 ) | ( base64_dec_map[*src] & 0x3F );
+        dec_map_lookup = mbedtls_base64_table_lookup( base64_dec_map, sizeof( base64_dec_map ), *src );
+
+        mbedtls_base64_cond_assign_uint32( &j, j - 1, mbedtls_base64_eq( dec_map_lookup, 64 ) );
+        x  = ( x << 6 ) | ( dec_map_lookup & 0x3F );
 
         if( ++n == 4 )
         {
diff --git a/library/bignum.c b/library/bignum.c
index dfe976d6489fe54368b34e5ad9b025c6316a9223..f133f6c13c23c5c00815e2ad34864b45eb5a0ada 100755
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -1354,6 +1354,12 @@ int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
     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 @@ int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
         /* 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 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
     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 );
@@ -2058,6 +2067,10 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
     if( mbedtls_mpi_cmp_int( E, 0 ) < 0 )
         return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
 
+    if( mbedtls_mpi_bitlen( E ) > MBEDTLS_MPI_MAX_BITS ||
+        mbedtls_mpi_bitlen( N ) > MBEDTLS_MPI_MAX_BITS )
+        return ( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+
     /*
      * Init temps and window size
      */
@@ -2334,7 +2347,7 @@ int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size,
     MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
 
     Xp = (unsigned char*) X->p;
-    f_rng( p_rng, Xp + overhead, size );
+    MBEDTLS_MPI_CHK( f_rng( p_rng, Xp + overhead, size ) );
 
     mpi_bigendian_to_host( X->p, limbs );
 
diff --git a/library/cipher_wrap.c b/library/cipher_wrap.c
index 1dcac21be1a5bc610286f24b2045b84adce78b45..5973ca6ba25fbfd4349b95d76867e5252a30a054 100755
--- a/library/cipher_wrap.c
+++ b/library/cipher_wrap.c
@@ -779,7 +779,7 @@ static const mbedtls_cipher_info_t camellia_128_ecb_info = {
     MBEDTLS_MODE_ECB,
     128,
     "CAMELLIA-128-ECB",
-    16,
+    0,
     0,
     16,
     &camellia_info
@@ -790,7 +790,7 @@ static const mbedtls_cipher_info_t camellia_192_ecb_info = {
     MBEDTLS_MODE_ECB,
     192,
     "CAMELLIA-192-ECB",
-    16,
+    0,
     0,
     16,
     &camellia_info
@@ -801,7 +801,7 @@ static const mbedtls_cipher_info_t camellia_256_ecb_info = {
     MBEDTLS_MODE_ECB,
     256,
     "CAMELLIA-256-ECB",
-    16,
+    0,
     0,
     16,
     &camellia_info
@@ -1155,7 +1155,7 @@ static const mbedtls_cipher_info_t aria_128_ecb_info = {
     MBEDTLS_MODE_ECB,
     128,
     "ARIA-128-ECB",
-    16,
+    0,
     0,
     16,
     &aria_info
@@ -1166,7 +1166,7 @@ static const mbedtls_cipher_info_t aria_192_ecb_info = {
     MBEDTLS_MODE_ECB,
     192,
     "ARIA-192-ECB",
-    16,
+    0,
     0,
     16,
     &aria_info
@@ -1177,7 +1177,7 @@ static const mbedtls_cipher_info_t aria_256_ecb_info = {
     MBEDTLS_MODE_ECB,
     256,
     "ARIA-256-ECB",
-    16,
+    0,
     0,
     16,
     &aria_info
@@ -1579,7 +1579,7 @@ static const mbedtls_cipher_info_t des_ecb_info = {
     MBEDTLS_MODE_ECB,
     MBEDTLS_KEY_LENGTH_DES,
     "DES-ECB",
-    8,
+    0,
     0,
     8,
     &des_info
@@ -1630,7 +1630,7 @@ static const mbedtls_cipher_info_t des_ede_ecb_info = {
     MBEDTLS_MODE_ECB,
     MBEDTLS_KEY_LENGTH_DES_EDE,
     "DES-EDE-ECB",
-    8,
+    0,
     0,
     8,
     &des_ede_info
@@ -1681,7 +1681,7 @@ static const mbedtls_cipher_info_t des_ede3_ecb_info = {
     MBEDTLS_MODE_ECB,
     MBEDTLS_KEY_LENGTH_DES_EDE3,
     "DES-EDE3-ECB",
-    8,
+    0,
     0,
     8,
     &des_ede3_info
@@ -1796,7 +1796,7 @@ static const mbedtls_cipher_info_t blowfish_ecb_info = {
     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 1a1200b52bc2535b9d3cb21b4e896910d5c4b4c9..409f67958e9e34cea2098ba0f009f6fb9e25881a 100755
--- a/library/cmac.c
+++ b/library/cmac.c
@@ -450,7 +450,7 @@ exit:
  */
 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 b98df29a9b429826744dfc86e237bd39e02e56a1..90264e844a4daed40c9c0ec649a431bc5d92d25c 100755
--- a/library/ctr_drbg.c
+++ b/library/ctr_drbg.c
@@ -82,21 +82,26 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx )
 {
     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 @@ int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
 
     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 @@ int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
 
     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 da8df9cde2f9dafe5f2a52d1f643157c64126205..2456238b1774fda168d56cafa3c86a89f94562cc 100755
--- a/library/ecdsa.c
+++ b/library/ecdsa.c
@@ -247,6 +247,9 @@ static void ecdsa_restart_det_free( mbedtls_ecdsa_restart_det_ctx *ctx )
 
 #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 @@ static int derive_mpi( const mbedtls_ecp_group *grp, mbedtls_mpi *x,
 cleanup:
     return( ret );
 }
+#endif /* ECDSA_DETERMINISTIC || !ECDSA_SIGN_ALT || !ECDSA_VERIFY_ALT */
 
 #if !defined(MBEDTLS_ECDSA_SIGN_ALT)
 /*
@@ -780,6 +784,8 @@ int mbedtls_ecdsa_write_signature_restartable( mbedtls_ecdsa_context *ctx,
     (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 @@ int mbedtls_ecdsa_read_signature_restartable( mbedtls_ecdsa_context *ctx,
         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 f6e24580c72e719ccc704a5847329d34e9604273..0532a295e6d04a6cf330230ae0ff898fa9354543 100755
--- a/library/ecjpake.c
+++ b/library/ecjpake.c
@@ -850,6 +850,8 @@ static const unsigned char ecjpake_test_password[] = {
     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 @@ cleanup:
     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 @@ int mbedtls_ecjpake_self_test( int verbose )
     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 @@ int mbedtls_ecjpake_self_test( int verbose )
 
     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 cc4c5b71c045d2c4830f9debd2962547fd21f48d..b04596b561b49f633f395eee8142654a2064d173 100755
--- a/library/ecp_curves.c
+++ b/library/ecp_curves.c
@@ -1044,7 +1044,7 @@ static inline void sub32( uint32_t *dst, uint32_t src, signed char *carry )
     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 666c55654cc9abbdfa5fa92553d21ef943c0c2cf..c5f414a0102ac114742f86ac07f9aee8ee22e97a 100755
--- a/library/entropy.c
+++ b/library/entropy.c
@@ -146,6 +146,11 @@ void mbedtls_entropy_init( mbedtls_entropy_context *ctx )
 
 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 @@ void mbedtls_entropy_free( mbedtls_entropy_context *ctx )
 #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 476c9f0a0f9866a2d5e22c87ae93b47e953bada5..d7062ea5dca03d45c4878813710f6c816cf32053 100755
--- 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
@@ -140,12 +140,12 @@ static int getrandom_wrapper( void *buf, size_t buflen, unsigned int flags )
 #endif /* __linux__ */
 
 #include 
-#include 
-#include 
 
 int mbedtls_platform_entropy_poll( void *data,
                            unsigned char *output, size_t len, size_t *olen )
 {
+    FILE *file;
+    size_t read_len;
     int ret;
     ((void) data);
 
@@ -165,18 +165,18 @@ int mbedtls_platform_entropy_poll( void *data,
 
     *olen = 0;
 
-    int fd = open("/dev/urandom", O_RDONLY);
-    if (fd == -1)
+    file = fopen( "/dev/urandom", "rb" );
+    if( file == NULL )
         return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
 
-    ssize_t read_len = read(fd, output, len);
-    if ((read_len == -1) || ((size_t)read_len != len))
+    read_len = fread( output, 1, len, file );
+    if( read_len != len )
     {
-        close(fd);
+        fclose( file );
         return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
     }
 
-    close(fd);
+    fclose( file );
     *olen = len;
 
     return( 0 );
diff --git a/library/error.c b/library/error.c
index eb52052b51e3844f77727eb9bd629501c12b1360..b83b8d1f1ba86a8ff9793be181b12439ac87e33d 100755
--- 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 
-#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 
+#include 
 
 #if defined(MBEDTLS_AES_C)
 #include "mbedtls/aes.h"
@@ -929,8 +928,6 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
 
 #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 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
         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 9fbfc30660672897d28acc56d509be818e06b302..b45d61616f222cd2b4636f3638d56fb39bdbbde3 100755
--- a/library/hmac_drbg.c
+++ b/library/hmac_drbg.c
@@ -83,9 +83,7 @@ void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx )
 {
     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 @@ int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
     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 @@ int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
     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 @@ int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
     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 @@ int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len
 }
 
 /*
- * 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 @@ void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
         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/md2.c b/library/md2.c
index cbdaaabdc75e0cf9ced6c01dadd403fa57fe356c..fdcb630a1f417528b019ee8311122c08dbbc646e 100755
--- a/library/md2.c
+++ b/library/md2.c
@@ -177,6 +177,9 @@ int mbedtls_internal_md2_process( mbedtls_md2_context *ctx )
         t  = ctx->cksum[i];
     }
 
+    /* Zeroise variables to clear sensitive data from memory. */
+    mbedtls_platform_zeroize( &t, sizeof( t ) );
+
     return( 0 );
 }
 
diff --git a/library/md4.c b/library/md4.c
index cb16dce54a96c070600e13a0d5d6d8faf615915f..95e893e65406c64f6d61bf8752a63a76969fbc2b 100755
--- a/library/md4.c
+++ b/library/md4.c
@@ -143,31 +143,34 @@ void mbedtls_md4_starts( mbedtls_md4_context *ctx )
 int mbedtls_internal_md4_process( mbedtls_md4_context *ctx,
                                   const unsigned char data[64] )
 {
-    uint32_t X[16], A, B, C, D;
-
-    GET_UINT32_LE( X[ 0], data,  0 );
-    GET_UINT32_LE( X[ 1], data,  4 );
-    GET_UINT32_LE( X[ 2], data,  8 );
-    GET_UINT32_LE( X[ 3], data, 12 );
-    GET_UINT32_LE( X[ 4], data, 16 );
-    GET_UINT32_LE( X[ 5], data, 20 );
-    GET_UINT32_LE( X[ 6], data, 24 );
-    GET_UINT32_LE( X[ 7], data, 28 );
-    GET_UINT32_LE( X[ 8], data, 32 );
-    GET_UINT32_LE( X[ 9], data, 36 );
-    GET_UINT32_LE( X[10], data, 40 );
-    GET_UINT32_LE( X[11], data, 44 );
-    GET_UINT32_LE( X[12], data, 48 );
-    GET_UINT32_LE( X[13], data, 52 );
-    GET_UINT32_LE( X[14], data, 56 );
-    GET_UINT32_LE( X[15], data, 60 );
+    struct
+    {
+        uint32_t X[16], A, B, C, D;
+    } local;
+
+    GET_UINT32_LE( local.X[ 0], data,  0 );
+    GET_UINT32_LE( local.X[ 1], data,  4 );
+    GET_UINT32_LE( local.X[ 2], data,  8 );
+    GET_UINT32_LE( local.X[ 3], data, 12 );
+    GET_UINT32_LE( local.X[ 4], data, 16 );
+    GET_UINT32_LE( local.X[ 5], data, 20 );
+    GET_UINT32_LE( local.X[ 6], data, 24 );
+    GET_UINT32_LE( local.X[ 7], data, 28 );
+    GET_UINT32_LE( local.X[ 8], data, 32 );
+    GET_UINT32_LE( local.X[ 9], data, 36 );
+    GET_UINT32_LE( local.X[10], data, 40 );
+    GET_UINT32_LE( local.X[11], data, 44 );
+    GET_UINT32_LE( local.X[12], data, 48 );
+    GET_UINT32_LE( local.X[13], data, 52 );
+    GET_UINT32_LE( local.X[14], data, 56 );
+    GET_UINT32_LE( local.X[15], data, 60 );
 
 #define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n))))
 
-    A = ctx->state[0];
-    B = ctx->state[1];
-    C = ctx->state[2];
-    D = ctx->state[3];
+    local.A = ctx->state[0];
+    local.B = ctx->state[1];
+    local.C = ctx->state[2];
+    local.D = ctx->state[3];
 
 #define F(x, y, z) (((x) & (y)) | ((~(x)) & (z)))
 #define P(a,b,c,d,x,s)                           \
@@ -178,22 +181,22 @@ int mbedtls_internal_md4_process( mbedtls_md4_context *ctx,
     } while( 0 )
 
 
-    P( A, B, C, D, X[ 0],  3 );
-    P( D, A, B, C, X[ 1],  7 );
-    P( C, D, A, B, X[ 2], 11 );
-    P( B, C, D, A, X[ 3], 19 );
-    P( A, B, C, D, X[ 4],  3 );
-    P( D, A, B, C, X[ 5],  7 );
-    P( C, D, A, B, X[ 6], 11 );
-    P( B, C, D, A, X[ 7], 19 );
-    P( A, B, C, D, X[ 8],  3 );
-    P( D, A, B, C, X[ 9],  7 );
-    P( C, D, A, B, X[10], 11 );
-    P( B, C, D, A, X[11], 19 );
-    P( A, B, C, D, X[12],  3 );
-    P( D, A, B, C, X[13],  7 );
-    P( C, D, A, B, X[14], 11 );
-    P( B, C, D, A, X[15], 19 );
+    P( local.A, local.B, local.C, local.D, local.X[ 0],  3 );
+    P( local.D, local.A, local.B, local.C, local.X[ 1],  7 );
+    P( local.C, local.D, local.A, local.B, local.X[ 2], 11 );
+    P( local.B, local.C, local.D, local.A, local.X[ 3], 19 );
+    P( local.A, local.B, local.C, local.D, local.X[ 4],  3 );
+    P( local.D, local.A, local.B, local.C, local.X[ 5],  7 );
+    P( local.C, local.D, local.A, local.B, local.X[ 6], 11 );
+    P( local.B, local.C, local.D, local.A, local.X[ 7], 19 );
+    P( local.A, local.B, local.C, local.D, local.X[ 8],  3 );
+    P( local.D, local.A, local.B, local.C, local.X[ 9],  7 );
+    P( local.C, local.D, local.A, local.B, local.X[10], 11 );
+    P( local.B, local.C, local.D, local.A, local.X[11], 19 );
+    P( local.A, local.B, local.C, local.D, local.X[12],  3 );
+    P( local.D, local.A, local.B, local.C, local.X[13],  7 );
+    P( local.C, local.D, local.A, local.B, local.X[14], 11 );
+    P( local.B, local.C, local.D, local.A, local.X[15], 19 );
 
 #undef P
 #undef F
@@ -206,22 +209,22 @@ int mbedtls_internal_md4_process( mbedtls_md4_context *ctx,
         (a) = S((a),(s));                               \
     } while( 0 )
 
-    P( A, B, C, D, X[ 0],  3 );
-    P( D, A, B, C, X[ 4],  5 );
-    P( C, D, A, B, X[ 8],  9 );
-    P( B, C, D, A, X[12], 13 );
-    P( A, B, C, D, X[ 1],  3 );
-    P( D, A, B, C, X[ 5],  5 );
-    P( C, D, A, B, X[ 9],  9 );
-    P( B, C, D, A, X[13], 13 );
-    P( A, B, C, D, X[ 2],  3 );
-    P( D, A, B, C, X[ 6],  5 );
-    P( C, D, A, B, X[10],  9 );
-    P( B, C, D, A, X[14], 13 );
-    P( A, B, C, D, X[ 3],  3 );
-    P( D, A, B, C, X[ 7],  5 );
-    P( C, D, A, B, X[11],  9 );
-    P( B, C, D, A, X[15], 13 );
+    P( local.A, local.B, local.C, local.D, local.X[ 0],  3 );
+    P( local.D, local.A, local.B, local.C, local.X[ 4],  5 );
+    P( local.C, local.D, local.A, local.B, local.X[ 8],  9 );
+    P( local.B, local.C, local.D, local.A, local.X[12], 13 );
+    P( local.A, local.B, local.C, local.D, local.X[ 1],  3 );
+    P( local.D, local.A, local.B, local.C, local.X[ 5],  5 );
+    P( local.C, local.D, local.A, local.B, local.X[ 9],  9 );
+    P( local.B, local.C, local.D, local.A, local.X[13], 13 );
+    P( local.A, local.B, local.C, local.D, local.X[ 2],  3 );
+    P( local.D, local.A, local.B, local.C, local.X[ 6],  5 );
+    P( local.C, local.D, local.A, local.B, local.X[10],  9 );
+    P( local.B, local.C, local.D, local.A, local.X[14], 13 );
+    P( local.A, local.B, local.C, local.D, local.X[ 3],  3 );
+    P( local.D, local.A, local.B, local.C, local.X[ 7],  5 );
+    P( local.C, local.D, local.A, local.B, local.X[11],  9 );
+    P( local.B, local.C, local.D, local.A, local.X[15], 13 );
 
 #undef P
 #undef F
@@ -234,30 +237,33 @@ int mbedtls_internal_md4_process( mbedtls_md4_context *ctx,
         (a) = S((a),(s));                               \
     } while( 0 )
 
-    P( A, B, C, D, X[ 0],  3 );
-    P( D, A, B, C, X[ 8],  9 );
-    P( C, D, A, B, X[ 4], 11 );
-    P( B, C, D, A, X[12], 15 );
-    P( A, B, C, D, X[ 2],  3 );
-    P( D, A, B, C, X[10],  9 );
-    P( C, D, A, B, X[ 6], 11 );
-    P( B, C, D, A, X[14], 15 );
-    P( A, B, C, D, X[ 1],  3 );
-    P( D, A, B, C, X[ 9],  9 );
-    P( C, D, A, B, X[ 5], 11 );
-    P( B, C, D, A, X[13], 15 );
-    P( A, B, C, D, X[ 3],  3 );
-    P( D, A, B, C, X[11],  9 );
-    P( C, D, A, B, X[ 7], 11 );
-    P( B, C, D, A, X[15], 15 );
+    P( local.A, local.B, local.C, local.D, local.X[ 0],  3 );
+    P( local.D, local.A, local.B, local.C, local.X[ 8],  9 );
+    P( local.C, local.D, local.A, local.B, local.X[ 4], 11 );
+    P( local.B, local.C, local.D, local.A, local.X[12], 15 );
+    P( local.A, local.B, local.C, local.D, local.X[ 2],  3 );
+    P( local.D, local.A, local.B, local.C, local.X[10],  9 );
+    P( local.C, local.D, local.A, local.B, local.X[ 6], 11 );
+    P( local.B, local.C, local.D, local.A, local.X[14], 15 );
+    P( local.A, local.B, local.C, local.D, local.X[ 1],  3 );
+    P( local.D, local.A, local.B, local.C, local.X[ 9],  9 );
+    P( local.C, local.D, local.A, local.B, local.X[ 5], 11 );
+    P( local.B, local.C, local.D, local.A, local.X[13], 15 );
+    P( local.A, local.B, local.C, local.D, local.X[ 3],  3 );
+    P( local.D, local.A, local.B, local.C, local.X[11],  9 );
+    P( local.C, local.D, local.A, local.B, local.X[ 7], 11 );
+    P( local.B, local.C, local.D, local.A, local.X[15], 15 );
 
 #undef F
 #undef P
 
-    ctx->state[0] += A;
-    ctx->state[1] += B;
-    ctx->state[2] += C;
-    ctx->state[3] += D;
+    ctx->state[0] += local.A;
+    ctx->state[1] += local.B;
+    ctx->state[2] += local.C;
+    ctx->state[3] += local.D;
+
+    /* Zeroise variables to clear sensitive data from memory. */
+    mbedtls_platform_zeroize( &local, sizeof( local ) );
 
     return( 0 );
 }
diff --git a/library/md5.c b/library/md5.c
index fe25925214f89c50e5eb709f7553f3cfcad53b5f..d2b634fbb104efc759e77720f1a30986b0a4e12e 100755
--- a/library/md5.c
+++ b/library/md5.c
@@ -142,128 +142,134 @@ void mbedtls_md5_starts( mbedtls_md5_context *ctx )
 int mbedtls_internal_md5_process( mbedtls_md5_context *ctx,
                                   const unsigned char data[64] )
 {
-    uint32_t X[16], A, B, C, D;
-
-    GET_UINT32_LE( X[ 0], data,  0 );
-    GET_UINT32_LE( X[ 1], data,  4 );
-    GET_UINT32_LE( X[ 2], data,  8 );
-    GET_UINT32_LE( X[ 3], data, 12 );
-    GET_UINT32_LE( X[ 4], data, 16 );
-    GET_UINT32_LE( X[ 5], data, 20 );
-    GET_UINT32_LE( X[ 6], data, 24 );
-    GET_UINT32_LE( X[ 7], data, 28 );
-    GET_UINT32_LE( X[ 8], data, 32 );
-    GET_UINT32_LE( X[ 9], data, 36 );
-    GET_UINT32_LE( X[10], data, 40 );
-    GET_UINT32_LE( X[11], data, 44 );
-    GET_UINT32_LE( X[12], data, 48 );
-    GET_UINT32_LE( X[13], data, 52 );
-    GET_UINT32_LE( X[14], data, 56 );
-    GET_UINT32_LE( X[15], data, 60 );
+    struct
+    {
+        uint32_t X[16], A, B, C, D;
+    } local;
+
+    GET_UINT32_LE( local.X[ 0], data,  0 );
+    GET_UINT32_LE( local.X[ 1], data,  4 );
+    GET_UINT32_LE( local.X[ 2], data,  8 );
+    GET_UINT32_LE( local.X[ 3], data, 12 );
+    GET_UINT32_LE( local.X[ 4], data, 16 );
+    GET_UINT32_LE( local.X[ 5], data, 20 );
+    GET_UINT32_LE( local.X[ 6], data, 24 );
+    GET_UINT32_LE( local.X[ 7], data, 28 );
+    GET_UINT32_LE( local.X[ 8], data, 32 );
+    GET_UINT32_LE( local.X[ 9], data, 36 );
+    GET_UINT32_LE( local.X[10], data, 40 );
+    GET_UINT32_LE( local.X[11], data, 44 );
+    GET_UINT32_LE( local.X[12], data, 48 );
+    GET_UINT32_LE( local.X[13], data, 52 );
+    GET_UINT32_LE( local.X[14], data, 56 );
+    GET_UINT32_LE( local.X[15], data, 60 );
 
 #define S(x,n)                                                          \
     ( ( (x) << (n) ) | ( ( (x) & 0xFFFFFFFF) >> ( 32 - (n) ) ) )
 
-#define P(a,b,c,d,k,s,t)                                        \
-    do                                                          \
-    {                                                           \
-        (a) += F((b),(c),(d)) + X[(k)] + (t);                   \
-        (a) = S((a),(s)) + (b);                                 \
+#define P(a,b,c,d,k,s,t)                                                \
+    do                                                                  \
+    {                                                                   \
+        (a) += F((b),(c),(d)) + local.X[(k)] + (t);                     \
+        (a) = S((a),(s)) + (b);                                         \
     } while( 0 )
 
-    A = ctx->state[0];
-    B = ctx->state[1];
-    C = ctx->state[2];
-    D = ctx->state[3];
+    local.A = ctx->state[0];
+    local.B = ctx->state[1];
+    local.C = ctx->state[2];
+    local.D = ctx->state[3];
 
 #define F(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
 
-    P( A, B, C, D,  0,  7, 0xD76AA478 );
-    P( D, A, B, C,  1, 12, 0xE8C7B756 );
-    P( C, D, A, B,  2, 17, 0x242070DB );
-    P( B, C, D, A,  3, 22, 0xC1BDCEEE );
-    P( A, B, C, D,  4,  7, 0xF57C0FAF );
-    P( D, A, B, C,  5, 12, 0x4787C62A );
-    P( C, D, A, B,  6, 17, 0xA8304613 );
-    P( B, C, D, A,  7, 22, 0xFD469501 );
-    P( A, B, C, D,  8,  7, 0x698098D8 );
-    P( D, A, B, C,  9, 12, 0x8B44F7AF );
-    P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
-    P( B, C, D, A, 11, 22, 0x895CD7BE );
-    P( A, B, C, D, 12,  7, 0x6B901122 );
-    P( D, A, B, C, 13, 12, 0xFD987193 );
-    P( C, D, A, B, 14, 17, 0xA679438E );
-    P( B, C, D, A, 15, 22, 0x49B40821 );
+    P( local.A, local.B, local.C, local.D,  0,  7, 0xD76AA478 );
+    P( local.D, local.A, local.B, local.C,  1, 12, 0xE8C7B756 );
+    P( local.C, local.D, local.A, local.B,  2, 17, 0x242070DB );
+    P( local.B, local.C, local.D, local.A,  3, 22, 0xC1BDCEEE );
+    P( local.A, local.B, local.C, local.D,  4,  7, 0xF57C0FAF );
+    P( local.D, local.A, local.B, local.C,  5, 12, 0x4787C62A );
+    P( local.C, local.D, local.A, local.B,  6, 17, 0xA8304613 );
+    P( local.B, local.C, local.D, local.A,  7, 22, 0xFD469501 );
+    P( local.A, local.B, local.C, local.D,  8,  7, 0x698098D8 );
+    P( local.D, local.A, local.B, local.C,  9, 12, 0x8B44F7AF );
+    P( local.C, local.D, local.A, local.B, 10, 17, 0xFFFF5BB1 );
+    P( local.B, local.C, local.D, local.A, 11, 22, 0x895CD7BE );
+    P( local.A, local.B, local.C, local.D, 12,  7, 0x6B901122 );
+    P( local.D, local.A, local.B, local.C, 13, 12, 0xFD987193 );
+    P( local.C, local.D, local.A, local.B, 14, 17, 0xA679438E );
+    P( local.B, local.C, local.D, local.A, 15, 22, 0x49B40821 );
 
 #undef F
 
 #define F(x,y,z) ((y) ^ ((z) & ((x) ^ (y))))
 
-    P( A, B, C, D,  1,  5, 0xF61E2562 );
-    P( D, A, B, C,  6,  9, 0xC040B340 );
-    P( C, D, A, B, 11, 14, 0x265E5A51 );
-    P( B, C, D, A,  0, 20, 0xE9B6C7AA );
-    P( A, B, C, D,  5,  5, 0xD62F105D );
-    P( D, A, B, C, 10,  9, 0x02441453 );
-    P( C, D, A, B, 15, 14, 0xD8A1E681 );
-    P( B, C, D, A,  4, 20, 0xE7D3FBC8 );
-    P( A, B, C, D,  9,  5, 0x21E1CDE6 );
-    P( D, A, B, C, 14,  9, 0xC33707D6 );
-    P( C, D, A, B,  3, 14, 0xF4D50D87 );
-    P( B, C, D, A,  8, 20, 0x455A14ED );
-    P( A, B, C, D, 13,  5, 0xA9E3E905 );
-    P( D, A, B, C,  2,  9, 0xFCEFA3F8 );
-    P( C, D, A, B,  7, 14, 0x676F02D9 );
-    P( B, C, D, A, 12, 20, 0x8D2A4C8A );
+    P( local.A, local.B, local.C, local.D,  1,  5, 0xF61E2562 );
+    P( local.D, local.A, local.B, local.C,  6,  9, 0xC040B340 );
+    P( local.C, local.D, local.A, local.B, 11, 14, 0x265E5A51 );
+    P( local.B, local.C, local.D, local.A,  0, 20, 0xE9B6C7AA );
+    P( local.A, local.B, local.C, local.D,  5,  5, 0xD62F105D );
+    P( local.D, local.A, local.B, local.C, 10,  9, 0x02441453 );
+    P( local.C, local.D, local.A, local.B, 15, 14, 0xD8A1E681 );
+    P( local.B, local.C, local.D, local.A,  4, 20, 0xE7D3FBC8 );
+    P( local.A, local.B, local.C, local.D,  9,  5, 0x21E1CDE6 );
+    P( local.D, local.A, local.B, local.C, 14,  9, 0xC33707D6 );
+    P( local.C, local.D, local.A, local.B,  3, 14, 0xF4D50D87 );
+    P( local.B, local.C, local.D, local.A,  8, 20, 0x455A14ED );
+    P( local.A, local.B, local.C, local.D, 13,  5, 0xA9E3E905 );
+    P( local.D, local.A, local.B, local.C,  2,  9, 0xFCEFA3F8 );
+    P( local.C, local.D, local.A, local.B,  7, 14, 0x676F02D9 );
+    P( local.B, local.C, local.D, local.A, 12, 20, 0x8D2A4C8A );
 
 #undef F
 
 #define F(x,y,z) ((x) ^ (y) ^ (z))
 
-    P( A, B, C, D,  5,  4, 0xFFFA3942 );
-    P( D, A, B, C,  8, 11, 0x8771F681 );
-    P( C, D, A, B, 11, 16, 0x6D9D6122 );
-    P( B, C, D, A, 14, 23, 0xFDE5380C );
-    P( A, B, C, D,  1,  4, 0xA4BEEA44 );
-    P( D, A, B, C,  4, 11, 0x4BDECFA9 );
-    P( C, D, A, B,  7, 16, 0xF6BB4B60 );
-    P( B, C, D, A, 10, 23, 0xBEBFBC70 );
-    P( A, B, C, D, 13,  4, 0x289B7EC6 );
-    P( D, A, B, C,  0, 11, 0xEAA127FA );
-    P( C, D, A, B,  3, 16, 0xD4EF3085 );
-    P( B, C, D, A,  6, 23, 0x04881D05 );
-    P( A, B, C, D,  9,  4, 0xD9D4D039 );
-    P( D, A, B, C, 12, 11, 0xE6DB99E5 );
-    P( C, D, A, B, 15, 16, 0x1FA27CF8 );
-    P( B, C, D, A,  2, 23, 0xC4AC5665 );
+    P( local.A, local.B, local.C, local.D,  5,  4, 0xFFFA3942 );
+    P( local.D, local.A, local.B, local.C,  8, 11, 0x8771F681 );
+    P( local.C, local.D, local.A, local.B, 11, 16, 0x6D9D6122 );
+    P( local.B, local.C, local.D, local.A, 14, 23, 0xFDE5380C );
+    P( local.A, local.B, local.C, local.D,  1,  4, 0xA4BEEA44 );
+    P( local.D, local.A, local.B, local.C,  4, 11, 0x4BDECFA9 );
+    P( local.C, local.D, local.A, local.B,  7, 16, 0xF6BB4B60 );
+    P( local.B, local.C, local.D, local.A, 10, 23, 0xBEBFBC70 );
+    P( local.A, local.B, local.C, local.D, 13,  4, 0x289B7EC6 );
+    P( local.D, local.A, local.B, local.C,  0, 11, 0xEAA127FA );
+    P( local.C, local.D, local.A, local.B,  3, 16, 0xD4EF3085 );
+    P( local.B, local.C, local.D, local.A,  6, 23, 0x04881D05 );
+    P( local.A, local.B, local.C, local.D,  9,  4, 0xD9D4D039 );
+    P( local.D, local.A, local.B, local.C, 12, 11, 0xE6DB99E5 );
+    P( local.C, local.D, local.A, local.B, 15, 16, 0x1FA27CF8 );
+    P( local.B, local.C, local.D, local.A,  2, 23, 0xC4AC5665 );
 
 #undef F
 
 #define F(x,y,z) ((y) ^ ((x) | ~(z)))
 
-    P( A, B, C, D,  0,  6, 0xF4292244 );
-    P( D, A, B, C,  7, 10, 0x432AFF97 );
-    P( C, D, A, B, 14, 15, 0xAB9423A7 );
-    P( B, C, D, A,  5, 21, 0xFC93A039 );
-    P( A, B, C, D, 12,  6, 0x655B59C3 );
-    P( D, A, B, C,  3, 10, 0x8F0CCC92 );
-    P( C, D, A, B, 10, 15, 0xFFEFF47D );
-    P( B, C, D, A,  1, 21, 0x85845DD1 );
-    P( A, B, C, D,  8,  6, 0x6FA87E4F );
-    P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
-    P( C, D, A, B,  6, 15, 0xA3014314 );
-    P( B, C, D, A, 13, 21, 0x4E0811A1 );
-    P( A, B, C, D,  4,  6, 0xF7537E82 );
-    P( D, A, B, C, 11, 10, 0xBD3AF235 );
-    P( C, D, A, B,  2, 15, 0x2AD7D2BB );
-    P( B, C, D, A,  9, 21, 0xEB86D391 );
+    P( local.A, local.B, local.C, local.D,  0,  6, 0xF4292244 );
+    P( local.D, local.A, local.B, local.C,  7, 10, 0x432AFF97 );
+    P( local.C, local.D, local.A, local.B, 14, 15, 0xAB9423A7 );
+    P( local.B, local.C, local.D, local.A,  5, 21, 0xFC93A039 );
+    P( local.A, local.B, local.C, local.D, 12,  6, 0x655B59C3 );
+    P( local.D, local.A, local.B, local.C,  3, 10, 0x8F0CCC92 );
+    P( local.C, local.D, local.A, local.B, 10, 15, 0xFFEFF47D );
+    P( local.B, local.C, local.D, local.A,  1, 21, 0x85845DD1 );
+    P( local.A, local.B, local.C, local.D,  8,  6, 0x6FA87E4F );
+    P( local.D, local.A, local.B, local.C, 15, 10, 0xFE2CE6E0 );
+    P( local.C, local.D, local.A, local.B,  6, 15, 0xA3014314 );
+    P( local.B, local.C, local.D, local.A, 13, 21, 0x4E0811A1 );
+    P( local.A, local.B, local.C, local.D,  4,  6, 0xF7537E82 );
+    P( local.D, local.A, local.B, local.C, 11, 10, 0xBD3AF235 );
+    P( local.C, local.D, local.A, local.B,  2, 15, 0x2AD7D2BB );
+    P( local.B, local.C, local.D, local.A,  9, 21, 0xEB86D391 );
 
 #undef F
 
-    ctx->state[0] += A;
-    ctx->state[1] += B;
-    ctx->state[2] += C;
-    ctx->state[3] += D;
+    ctx->state[0] += local.A;
+    ctx->state[1] += local.B;
+    ctx->state[2] += local.C;
+    ctx->state[3] += local.D;
+
+    /* Zeroise variables to clear sensitive data from memory. */
+    mbedtls_platform_zeroize( &local, sizeof( local ) );
 
     return( 0 );
 }
diff --git a/library/net_sockets.c b/library/net_sockets.c
index 11304082635183af045a766b650faf4d11d15766..671115f15f100ab79487c4118bc7334b6432af6b 100755
--- a/library/net_sockets.c
+++ b/library/net_sockets.c
@@ -496,6 +496,13 @@ int mbedtls_net_poll( mbedtls_net_context *ctx, uint32_t rw, uint32_t timeout )
     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 @@ int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf,
     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 a7a2f7f5cf9567f9a8cecae6ffa36ed17a7f189d..50e663ccdb880b5b5f25b3485069ae750aca0275 100755
--- a/library/pem.c
+++ b/library/pem.c
@@ -508,8 +508,12 @@ int mbedtls_pem_write_buffer( const char *header, const char *footer,
     *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/pkcs5.c b/library/pkcs5.c
index 8a80aa5d05c58e253e8b561c070a5a50ba1d315d..c4447f154675c7dc32593c9d7e94bfc9143829ac 100755
--- a/library/pkcs5.c
+++ b/library/pkcs5.c
@@ -247,7 +247,7 @@ int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *p
                        unsigned int iteration_count,
                        uint32_t key_length, unsigned char *output )
 {
-    int ret, j;
+    int ret = 0, j;
     unsigned int i;
     unsigned char md1[MBEDTLS_MD_MAX_SIZE];
     unsigned char work[MBEDTLS_MD_MAX_SIZE];
@@ -269,16 +269,16 @@ int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *p
         // U1 ends up in work
         //
         if( ( ret = mbedtls_md_hmac_starts( ctx, password, plen ) ) != 0 )
-            return( ret );
+            goto cleanup;
 
         if( ( ret = mbedtls_md_hmac_update( ctx, salt, slen ) ) != 0 )
-            return( ret );
+            goto cleanup;
 
         if( ( ret = mbedtls_md_hmac_update( ctx, counter, 4 ) ) != 0 )
-            return( ret );
+            goto cleanup;
 
         if( ( ret = mbedtls_md_hmac_finish( ctx, work ) ) != 0 )
-            return( ret );
+            goto cleanup;
 
         memcpy( md1, work, md_size );
 
@@ -287,13 +287,13 @@ int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *p
             // U2 ends up in md1
             //
             if( ( ret = mbedtls_md_hmac_starts( ctx, password, plen ) ) != 0 )
-                return( ret );
+                goto cleanup;
 
             if( ( ret = mbedtls_md_hmac_update( ctx, md1, md_size ) ) != 0 )
-                return( ret );
+                goto cleanup;
 
             if( ( ret = mbedtls_md_hmac_finish( ctx, md1 ) ) != 0 )
-                return( ret );
+                goto cleanup;
 
             // U1 xor U2
             //
@@ -312,7 +312,12 @@ int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *p
                 break;
     }
 
-    return( 0 );
+cleanup:
+    /* Zeroise buffers to clear sensitive data from memory. */
+    mbedtls_platform_zeroize( work, MBEDTLS_MD_MAX_SIZE );
+    mbedtls_platform_zeroize( md1, MBEDTLS_MD_MAX_SIZE );
+
+    return( ret );
 }
 
 #if defined(MBEDTLS_SELF_TEST)
diff --git a/library/pkparse.c b/library/pkparse.c
index 086807d836379d27636e928fbb867a129da259b3..e410f3aae1c8db5dbad7e36d51f5cb77385e9ea6 100755
--- a/library/pkparse.c
+++ b/library/pkparse.c
@@ -692,7 +692,7 @@ int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end,
         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 150626c1478f496c98e90d9a5c142b914efc6060..a770dfb93ecec04cc219869b4ee75c57c6be33fc 100755
--- a/library/pkwrite.c
+++ b/library/pkwrite.c
@@ -455,7 +455,7 @@ int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_
  *      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 @@ int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_
  *      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 @@ int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_
  *                                            + 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 @@ int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_
  *      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 @@ int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_
 
 #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 3ba2aead12541ba2539cd8ed799d851089240a9a..c8cd52d52a0d67f6f17462527574db362e080909 100755
--- a/library/platform_util.c
+++ b/library/platform_util.c
@@ -115,7 +115,7 @@ void mbedtls_platform_zeroize( void *buf, size_t len )
 
 #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 @@ void mbedtls_platform_zeroize( void *buf, size_t len )
 
 #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/ripemd160.c b/library/ripemd160.c
index 0b6efcb5742eb931084bb4489a421f482b0bcd97..d6ee933b2ed107337852f96888ac501701496150 100755
--- a/library/ripemd160.c
+++ b/library/ripemd160.c
@@ -147,30 +147,33 @@ void mbedtls_ripemd160_starts( mbedtls_ripemd160_context *ctx )
 int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
                                         const unsigned char data[64] )
 {
-    uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
-
-    GET_UINT32_LE( X[ 0], data,  0 );
-    GET_UINT32_LE( X[ 1], data,  4 );
-    GET_UINT32_LE( X[ 2], data,  8 );
-    GET_UINT32_LE( X[ 3], data, 12 );
-    GET_UINT32_LE( X[ 4], data, 16 );
-    GET_UINT32_LE( X[ 5], data, 20 );
-    GET_UINT32_LE( X[ 6], data, 24 );
-    GET_UINT32_LE( X[ 7], data, 28 );
-    GET_UINT32_LE( X[ 8], data, 32 );
-    GET_UINT32_LE( X[ 9], data, 36 );
-    GET_UINT32_LE( X[10], data, 40 );
-    GET_UINT32_LE( X[11], data, 44 );
-    GET_UINT32_LE( X[12], data, 48 );
-    GET_UINT32_LE( X[13], data, 52 );
-    GET_UINT32_LE( X[14], data, 56 );
-    GET_UINT32_LE( X[15], data, 60 );
-
-    A = Ap = ctx->state[0];
-    B = Bp = ctx->state[1];
-    C = Cp = ctx->state[2];
-    D = Dp = ctx->state[3];
-    E = Ep = ctx->state[4];
+    struct
+    {
+        uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
+    } local;
+
+    GET_UINT32_LE( local.X[ 0], data,  0 );
+    GET_UINT32_LE( local.X[ 1], data,  4 );
+    GET_UINT32_LE( local.X[ 2], data,  8 );
+    GET_UINT32_LE( local.X[ 3], data, 12 );
+    GET_UINT32_LE( local.X[ 4], data, 16 );
+    GET_UINT32_LE( local.X[ 5], data, 20 );
+    GET_UINT32_LE( local.X[ 6], data, 24 );
+    GET_UINT32_LE( local.X[ 7], data, 28 );
+    GET_UINT32_LE( local.X[ 8], data, 32 );
+    GET_UINT32_LE( local.X[ 9], data, 36 );
+    GET_UINT32_LE( local.X[10], data, 40 );
+    GET_UINT32_LE( local.X[11], data, 44 );
+    GET_UINT32_LE( local.X[12], data, 48 );
+    GET_UINT32_LE( local.X[13], data, 52 );
+    GET_UINT32_LE( local.X[14], data, 56 );
+    GET_UINT32_LE( local.X[15], data, 60 );
+
+    local.A = local.Ap = ctx->state[0];
+    local.B = local.Bp = ctx->state[1];
+    local.C = local.Cp = ctx->state[2];
+    local.D = local.Dp = ctx->state[3];
+    local.E = local.Ep = ctx->state[4];
 
 #define F1( x, y, z )   ( (x) ^ (y) ^ (z) )
 #define F2( x, y, z )   ( ( (x) & (y) ) | ( ~(x) & (z) ) )
@@ -180,12 +183,12 @@ int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
 
 #define S( x, n ) ( ( (x) << (n) ) | ( (x) >> (32 - (n)) ) )
 
-#define P( a, b, c, d, e, r, s, f, k )                \
-    do                                                \
-    {                                                 \
-        (a) += f( (b), (c), (d) ) + X[r] + (k);       \
-        (a) = S( (a), (s) ) + (e);                    \
-        (c) = S( (c), 10 );                           \
+#define P( a, b, c, d, e, r, s, f, k )                      \
+    do                                                      \
+    {                                                       \
+        (a) += f( (b), (c), (d) ) + local.X[r] + (k);       \
+        (a) = S( (a), (s) ) + (e);                          \
+        (c) = S( (c), 10 );                                 \
     } while( 0 )
 
 #define P2( a, b, c, d, e, r, s, rp, sp )                               \
@@ -200,22 +203,22 @@ int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
 #define K   0x00000000
 #define Fp  F5
 #define Kp  0x50A28BE6
-    P2( A, B, C, D, E,  0, 11,  5,  8 );
-    P2( E, A, B, C, D,  1, 14, 14,  9 );
-    P2( D, E, A, B, C,  2, 15,  7,  9 );
-    P2( C, D, E, A, B,  3, 12,  0, 11 );
-    P2( B, C, D, E, A,  4,  5,  9, 13 );
-    P2( A, B, C, D, E,  5,  8,  2, 15 );
-    P2( E, A, B, C, D,  6,  7, 11, 15 );
-    P2( D, E, A, B, C,  7,  9,  4,  5 );
-    P2( C, D, E, A, B,  8, 11, 13,  7 );
-    P2( B, C, D, E, A,  9, 13,  6,  7 );
-    P2( A, B, C, D, E, 10, 14, 15,  8 );
-    P2( E, A, B, C, D, 11, 15,  8, 11 );
-    P2( D, E, A, B, C, 12,  6,  1, 14 );
-    P2( C, D, E, A, B, 13,  7, 10, 14 );
-    P2( B, C, D, E, A, 14,  9,  3, 12 );
-    P2( A, B, C, D, E, 15,  8, 12,  6 );
+    P2( local.A, local.B, local.C, local.D, local.E,  0, 11,  5,  8 );
+    P2( local.E, local.A, local.B, local.C, local.D,  1, 14, 14,  9 );
+    P2( local.D, local.E, local.A, local.B, local.C,  2, 15,  7,  9 );
+    P2( local.C, local.D, local.E, local.A, local.B,  3, 12,  0, 11 );
+    P2( local.B, local.C, local.D, local.E, local.A,  4,  5,  9, 13 );
+    P2( local.A, local.B, local.C, local.D, local.E,  5,  8,  2, 15 );
+    P2( local.E, local.A, local.B, local.C, local.D,  6,  7, 11, 15 );
+    P2( local.D, local.E, local.A, local.B, local.C,  7,  9,  4,  5 );
+    P2( local.C, local.D, local.E, local.A, local.B,  8, 11, 13,  7 );
+    P2( local.B, local.C, local.D, local.E, local.A,  9, 13,  6,  7 );
+    P2( local.A, local.B, local.C, local.D, local.E, 10, 14, 15,  8 );
+    P2( local.E, local.A, local.B, local.C, local.D, 11, 15,  8, 11 );
+    P2( local.D, local.E, local.A, local.B, local.C, 12,  6,  1, 14 );
+    P2( local.C, local.D, local.E, local.A, local.B, 13,  7, 10, 14 );
+    P2( local.B, local.C, local.D, local.E, local.A, 14,  9,  3, 12 );
+    P2( local.A, local.B, local.C, local.D, local.E, 15,  8, 12,  6 );
 #undef F
 #undef K
 #undef Fp
@@ -225,22 +228,22 @@ int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
 #define K   0x5A827999
 #define Fp  F4
 #define Kp  0x5C4DD124
-    P2( E, A, B, C, D,  7,  7,  6,  9 );
-    P2( D, E, A, B, C,  4,  6, 11, 13 );
-    P2( C, D, E, A, B, 13,  8,  3, 15 );
-    P2( B, C, D, E, A,  1, 13,  7,  7 );
-    P2( A, B, C, D, E, 10, 11,  0, 12 );
-    P2( E, A, B, C, D,  6,  9, 13,  8 );
-    P2( D, E, A, B, C, 15,  7,  5,  9 );
-    P2( C, D, E, A, B,  3, 15, 10, 11 );
-    P2( B, C, D, E, A, 12,  7, 14,  7 );
-    P2( A, B, C, D, E,  0, 12, 15,  7 );
-    P2( E, A, B, C, D,  9, 15,  8, 12 );
-    P2( D, E, A, B, C,  5,  9, 12,  7 );
-    P2( C, D, E, A, B,  2, 11,  4,  6 );
-    P2( B, C, D, E, A, 14,  7,  9, 15 );
-    P2( A, B, C, D, E, 11, 13,  1, 13 );
-    P2( E, A, B, C, D,  8, 12,  2, 11 );
+    P2( local.E, local.A, local.B, local.C, local.D,  7,  7,  6,  9 );
+    P2( local.D, local.E, local.A, local.B, local.C,  4,  6, 11, 13 );
+    P2( local.C, local.D, local.E, local.A, local.B, 13,  8,  3, 15 );
+    P2( local.B, local.C, local.D, local.E, local.A,  1, 13,  7,  7 );
+    P2( local.A, local.B, local.C, local.D, local.E, 10, 11,  0, 12 );
+    P2( local.E, local.A, local.B, local.C, local.D,  6,  9, 13,  8 );
+    P2( local.D, local.E, local.A, local.B, local.C, 15,  7,  5,  9 );
+    P2( local.C, local.D, local.E, local.A, local.B,  3, 15, 10, 11 );
+    P2( local.B, local.C, local.D, local.E, local.A, 12,  7, 14,  7 );
+    P2( local.A, local.B, local.C, local.D, local.E,  0, 12, 15,  7 );
+    P2( local.E, local.A, local.B, local.C, local.D,  9, 15,  8, 12 );
+    P2( local.D, local.E, local.A, local.B, local.C,  5,  9, 12,  7 );
+    P2( local.C, local.D, local.E, local.A, local.B,  2, 11,  4,  6 );
+    P2( local.B, local.C, local.D, local.E, local.A, 14,  7,  9, 15 );
+    P2( local.A, local.B, local.C, local.D, local.E, 11, 13,  1, 13 );
+    P2( local.E, local.A, local.B, local.C, local.D,  8, 12,  2, 11 );
 #undef F
 #undef K
 #undef Fp
@@ -250,22 +253,22 @@ int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
 #define K   0x6ED9EBA1
 #define Fp  F3
 #define Kp  0x6D703EF3
-    P2( D, E, A, B, C,  3, 11, 15,  9 );
-    P2( C, D, E, A, B, 10, 13,  5,  7 );
-    P2( B, C, D, E, A, 14,  6,  1, 15 );
-    P2( A, B, C, D, E,  4,  7,  3, 11 );
-    P2( E, A, B, C, D,  9, 14,  7,  8 );
-    P2( D, E, A, B, C, 15,  9, 14,  6 );
-    P2( C, D, E, A, B,  8, 13,  6,  6 );
-    P2( B, C, D, E, A,  1, 15,  9, 14 );
-    P2( A, B, C, D, E,  2, 14, 11, 12 );
-    P2( E, A, B, C, D,  7,  8,  8, 13 );
-    P2( D, E, A, B, C,  0, 13, 12,  5 );
-    P2( C, D, E, A, B,  6,  6,  2, 14 );
-    P2( B, C, D, E, A, 13,  5, 10, 13 );
-    P2( A, B, C, D, E, 11, 12,  0, 13 );
-    P2( E, A, B, C, D,  5,  7,  4,  7 );
-    P2( D, E, A, B, C, 12,  5, 13,  5 );
+    P2( local.D, local.E, local.A, local.B, local.C,  3, 11, 15,  9 );
+    P2( local.C, local.D, local.E, local.A, local.B, 10, 13,  5,  7 );
+    P2( local.B, local.C, local.D, local.E, local.A, 14,  6,  1, 15 );
+    P2( local.A, local.B, local.C, local.D, local.E,  4,  7,  3, 11 );
+    P2( local.E, local.A, local.B, local.C, local.D,  9, 14,  7,  8 );
+    P2( local.D, local.E, local.A, local.B, local.C, 15,  9, 14,  6 );
+    P2( local.C, local.D, local.E, local.A, local.B,  8, 13,  6,  6 );
+    P2( local.B, local.C, local.D, local.E, local.A,  1, 15,  9, 14 );
+    P2( local.A, local.B, local.C, local.D, local.E,  2, 14, 11, 12 );
+    P2( local.E, local.A, local.B, local.C, local.D,  7,  8,  8, 13 );
+    P2( local.D, local.E, local.A, local.B, local.C,  0, 13, 12,  5 );
+    P2( local.C, local.D, local.E, local.A, local.B,  6,  6,  2, 14 );
+    P2( local.B, local.C, local.D, local.E, local.A, 13,  5, 10, 13 );
+    P2( local.A, local.B, local.C, local.D, local.E, 11, 12,  0, 13 );
+    P2( local.E, local.A, local.B, local.C, local.D,  5,  7,  4,  7 );
+    P2( local.D, local.E, local.A, local.B, local.C, 12,  5, 13,  5 );
 #undef F
 #undef K
 #undef Fp
@@ -275,22 +278,22 @@ int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
 #define K   0x8F1BBCDC
 #define Fp  F2
 #define Kp  0x7A6D76E9
-    P2( C, D, E, A, B,  1, 11,  8, 15 );
-    P2( B, C, D, E, A,  9, 12,  6,  5 );
-    P2( A, B, C, D, E, 11, 14,  4,  8 );
-    P2( E, A, B, C, D, 10, 15,  1, 11 );
-    P2( D, E, A, B, C,  0, 14,  3, 14 );
-    P2( C, D, E, A, B,  8, 15, 11, 14 );
-    P2( B, C, D, E, A, 12,  9, 15,  6 );
-    P2( A, B, C, D, E,  4,  8,  0, 14 );
-    P2( E, A, B, C, D, 13,  9,  5,  6 );
-    P2( D, E, A, B, C,  3, 14, 12,  9 );
-    P2( C, D, E, A, B,  7,  5,  2, 12 );
-    P2( B, C, D, E, A, 15,  6, 13,  9 );
-    P2( A, B, C, D, E, 14,  8,  9, 12 );
-    P2( E, A, B, C, D,  5,  6,  7,  5 );
-    P2( D, E, A, B, C,  6,  5, 10, 15 );
-    P2( C, D, E, A, B,  2, 12, 14,  8 );
+    P2( local.C, local.D, local.E, local.A, local.B,  1, 11,  8, 15 );
+    P2( local.B, local.C, local.D, local.E, local.A,  9, 12,  6,  5 );
+    P2( local.A, local.B, local.C, local.D, local.E, 11, 14,  4,  8 );
+    P2( local.E, local.A, local.B, local.C, local.D, 10, 15,  1, 11 );
+    P2( local.D, local.E, local.A, local.B, local.C,  0, 14,  3, 14 );
+    P2( local.C, local.D, local.E, local.A, local.B,  8, 15, 11, 14 );
+    P2( local.B, local.C, local.D, local.E, local.A, 12,  9, 15,  6 );
+    P2( local.A, local.B, local.C, local.D, local.E,  4,  8,  0, 14 );
+    P2( local.E, local.A, local.B, local.C, local.D, 13,  9,  5,  6 );
+    P2( local.D, local.E, local.A, local.B, local.C,  3, 14, 12,  9 );
+    P2( local.C, local.D, local.E, local.A, local.B,  7,  5,  2, 12 );
+    P2( local.B, local.C, local.D, local.E, local.A, 15,  6, 13,  9 );
+    P2( local.A, local.B, local.C, local.D, local.E, 14,  8,  9, 12 );
+    P2( local.E, local.A, local.B, local.C, local.D,  5,  6,  7,  5 );
+    P2( local.D, local.E, local.A, local.B, local.C,  6,  5, 10, 15 );
+    P2( local.C, local.D, local.E, local.A, local.B,  2, 12, 14,  8 );
 #undef F
 #undef K
 #undef Fp
@@ -300,33 +303,36 @@ int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
 #define K   0xA953FD4E
 #define Fp  F1
 #define Kp  0x00000000
-    P2( B, C, D, E, A,  4,  9, 12,  8 );
-    P2( A, B, C, D, E,  0, 15, 15,  5 );
-    P2( E, A, B, C, D,  5,  5, 10, 12 );
-    P2( D, E, A, B, C,  9, 11,  4,  9 );
-    P2( C, D, E, A, B,  7,  6,  1, 12 );
-    P2( B, C, D, E, A, 12,  8,  5,  5 );
-    P2( A, B, C, D, E,  2, 13,  8, 14 );
-    P2( E, A, B, C, D, 10, 12,  7,  6 );
-    P2( D, E, A, B, C, 14,  5,  6,  8 );
-    P2( C, D, E, A, B,  1, 12,  2, 13 );
-    P2( B, C, D, E, A,  3, 13, 13,  6 );
-    P2( A, B, C, D, E,  8, 14, 14,  5 );
-    P2( E, A, B, C, D, 11, 11,  0, 15 );
-    P2( D, E, A, B, C,  6,  8,  3, 13 );
-    P2( C, D, E, A, B, 15,  5,  9, 11 );
-    P2( B, C, D, E, A, 13,  6, 11, 11 );
+    P2( local.B, local.C, local.D, local.E, local.A,  4,  9, 12,  8 );
+    P2( local.A, local.B, local.C, local.D, local.E,  0, 15, 15,  5 );
+    P2( local.E, local.A, local.B, local.C, local.D,  5,  5, 10, 12 );
+    P2( local.D, local.E, local.A, local.B, local.C,  9, 11,  4,  9 );
+    P2( local.C, local.D, local.E, local.A, local.B,  7,  6,  1, 12 );
+    P2( local.B, local.C, local.D, local.E, local.A, 12,  8,  5,  5 );
+    P2( local.A, local.B, local.C, local.D, local.E,  2, 13,  8, 14 );
+    P2( local.E, local.A, local.B, local.C, local.D, 10, 12,  7,  6 );
+    P2( local.D, local.E, local.A, local.B, local.C, 14,  5,  6,  8 );
+    P2( local.C, local.D, local.E, local.A, local.B,  1, 12,  2, 13 );
+    P2( local.B, local.C, local.D, local.E, local.A,  3, 13, 13,  6 );
+    P2( local.A, local.B, local.C, local.D, local.E,  8, 14, 14,  5 );
+    P2( local.E, local.A, local.B, local.C, local.D, 11, 11,  0, 15 );
+    P2( local.D, local.E, local.A, local.B, local.C,  6,  8,  3, 13 );
+    P2( local.C, local.D, local.E, local.A, local.B, 15,  5,  9, 11 );
+    P2( local.B, local.C, local.D, local.E, local.A, 13,  6, 11, 11 );
 #undef F
 #undef K
 #undef Fp
 #undef Kp
 
-    C             = ctx->state[1] + C + Dp;
-    ctx->state[1] = ctx->state[2] + D + Ep;
-    ctx->state[2] = ctx->state[3] + E + Ap;
-    ctx->state[3] = ctx->state[4] + A + Bp;
-    ctx->state[4] = ctx->state[0] + B + Cp;
-    ctx->state[0] = C;
+    local.C       = ctx->state[1] + local.C + local.Dp;
+    ctx->state[1] = ctx->state[2] + local.D + local.Ep;
+    ctx->state[2] = ctx->state[3] + local.E + local.Ap;
+    ctx->state[3] = ctx->state[4] + local.A + local.Bp;
+    ctx->state[4] = ctx->state[0] + local.B + local.Cp;
+    ctx->state[0] = local.C;
+
+    /* Zeroise variables to clear sensitive data from memory. */
+    mbedtls_platform_zeroize( &local, sizeof( local ) );
 
     return( 0 );
 }
diff --git a/library/rsa.c b/library/rsa.c
index 42becbf17bf4d8f2559f711e070a066a65e0363f..c8c23dba8cec597387cc639a9d8a7601f2867e09 100755
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -520,6 +520,9 @@ void mbedtls_rsa_init( mbedtls_rsa_context *ctx,
     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 @@ int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
     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 @@ int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
     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 @@ cleanup:
     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 @@ static int rsa_prepare_blinding( mbedtls_rsa_context *ctx,
          * 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 @@ cleanup:
     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 @@ int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src )
     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 @@ void mbedtls_rsa_free( mbedtls_rsa_context *ctx )
 #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/sha1.c b/library/sha1.c
index 8682abd740b32483edd4c1303cf82ca9af0a0a63..e99a5e86356277031cf5f480033cfe6ed92a1c02 100755
--- a/library/sha1.c
+++ b/library/sha1.c
@@ -155,35 +155,40 @@ void mbedtls_sha1_starts( mbedtls_sha1_context *ctx )
 int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx,
                                    const unsigned char data[64] )
 {
-    uint32_t temp, W[16], A, B, C, D, E;
+    struct
+    {
+        uint32_t temp, W[16], A, B, C, D, E;
+    } local;
 
     SHA1_VALIDATE_RET( ctx != NULL );
     SHA1_VALIDATE_RET( (const unsigned char *)data != NULL );
 
-    GET_UINT32_BE( W[ 0], data,  0 );
-    GET_UINT32_BE( W[ 1], data,  4 );
-    GET_UINT32_BE( W[ 2], data,  8 );
-    GET_UINT32_BE( W[ 3], data, 12 );
-    GET_UINT32_BE( W[ 4], data, 16 );
-    GET_UINT32_BE( W[ 5], data, 20 );
-    GET_UINT32_BE( W[ 6], data, 24 );
-    GET_UINT32_BE( W[ 7], data, 28 );
-    GET_UINT32_BE( W[ 8], data, 32 );
-    GET_UINT32_BE( W[ 9], data, 36 );
-    GET_UINT32_BE( W[10], data, 40 );
-    GET_UINT32_BE( W[11], data, 44 );
-    GET_UINT32_BE( W[12], data, 48 );
-    GET_UINT32_BE( W[13], data, 52 );
-    GET_UINT32_BE( W[14], data, 56 );
-    GET_UINT32_BE( W[15], data, 60 );
+    GET_UINT32_BE( local.W[ 0], data,  0 );
+    GET_UINT32_BE( local.W[ 1], data,  4 );
+    GET_UINT32_BE( local.W[ 2], data,  8 );
+    GET_UINT32_BE( local.W[ 3], data, 12 );
+    GET_UINT32_BE( local.W[ 4], data, 16 );
+    GET_UINT32_BE( local.W[ 5], data, 20 );
+    GET_UINT32_BE( local.W[ 6], data, 24 );
+    GET_UINT32_BE( local.W[ 7], data, 28 );
+    GET_UINT32_BE( local.W[ 8], data, 32 );
+    GET_UINT32_BE( local.W[ 9], data, 36 );
+    GET_UINT32_BE( local.W[10], data, 40 );
+    GET_UINT32_BE( local.W[11], data, 44 );
+    GET_UINT32_BE( local.W[12], data, 48 );
+    GET_UINT32_BE( local.W[13], data, 52 );
+    GET_UINT32_BE( local.W[14], data, 56 );
+    GET_UINT32_BE( local.W[15], data, 60 );
 
 #define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n))))
 
 #define R(t)                                                    \
     (                                                           \
-        temp = W[( (t) -  3 ) & 0x0F] ^ W[( (t) - 8 ) & 0x0F] ^ \
-               W[( (t) - 14 ) & 0x0F] ^ W[  (t)       & 0x0F],  \
-        ( W[(t) & 0x0F] = S(temp,1) )                           \
+        local.temp = local.W[( (t) -  3 ) & 0x0F] ^             \
+                     local.W[( (t) -  8 ) & 0x0F] ^             \
+                     local.W[( (t) - 14 ) & 0x0F] ^             \
+                     local.W[  (t)        & 0x0F],              \
+        ( local.W[(t) & 0x0F] = S(local.temp,1) )               \
     )
 
 #define P(a,b,c,d,e,x)                                          \
@@ -193,35 +198,35 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx,
         (b) = S((b),30);                                        \
     } while( 0 )
 
-    A = ctx->state[0];
-    B = ctx->state[1];
-    C = ctx->state[2];
-    D = ctx->state[3];
-    E = ctx->state[4];
+    local.A = ctx->state[0];
+    local.B = ctx->state[1];
+    local.C = ctx->state[2];
+    local.D = ctx->state[3];
+    local.E = ctx->state[4];
 
 #define F(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
 #define K 0x5A827999
 
-    P( A, B, C, D, E, W[0]  );
-    P( E, A, B, C, D, W[1]  );
-    P( D, E, A, B, C, W[2]  );
-    P( C, D, E, A, B, W[3]  );
-    P( B, C, D, E, A, W[4]  );
-    P( A, B, C, D, E, W[5]  );
-    P( E, A, B, C, D, W[6]  );
-    P( D, E, A, B, C, W[7]  );
-    P( C, D, E, A, B, W[8]  );
-    P( B, C, D, E, A, W[9]  );
-    P( A, B, C, D, E, W[10] );
-    P( E, A, B, C, D, W[11] );
-    P( D, E, A, B, C, W[12] );
-    P( C, D, E, A, B, W[13] );
-    P( B, C, D, E, A, W[14] );
-    P( A, B, C, D, E, W[15] );
-    P( E, A, B, C, D, R(16) );
-    P( D, E, A, B, C, R(17) );
-    P( C, D, E, A, B, R(18) );
-    P( B, C, D, E, A, R(19) );
+    P( local.A, local.B, local.C, local.D, local.E, local.W[0]  );
+    P( local.E, local.A, local.B, local.C, local.D, local.W[1]  );
+    P( local.D, local.E, local.A, local.B, local.C, local.W[2]  );
+    P( local.C, local.D, local.E, local.A, local.B, local.W[3]  );
+    P( local.B, local.C, local.D, local.E, local.A, local.W[4]  );
+    P( local.A, local.B, local.C, local.D, local.E, local.W[5]  );
+    P( local.E, local.A, local.B, local.C, local.D, local.W[6]  );
+    P( local.D, local.E, local.A, local.B, local.C, local.W[7]  );
+    P( local.C, local.D, local.E, local.A, local.B, local.W[8]  );
+    P( local.B, local.C, local.D, local.E, local.A, local.W[9]  );
+    P( local.A, local.B, local.C, local.D, local.E, local.W[10] );
+    P( local.E, local.A, local.B, local.C, local.D, local.W[11] );
+    P( local.D, local.E, local.A, local.B, local.C, local.W[12] );
+    P( local.C, local.D, local.E, local.A, local.B, local.W[13] );
+    P( local.B, local.C, local.D, local.E, local.A, local.W[14] );
+    P( local.A, local.B, local.C, local.D, local.E, local.W[15] );
+    P( local.E, local.A, local.B, local.C, local.D, R(16) );
+    P( local.D, local.E, local.A, local.B, local.C, R(17) );
+    P( local.C, local.D, local.E, local.A, local.B, R(18) );
+    P( local.B, local.C, local.D, local.E, local.A, R(19) );
 
 #undef K
 #undef F
@@ -229,26 +234,26 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx,
 #define F(x,y,z) ((x) ^ (y) ^ (z))
 #define K 0x6ED9EBA1
 
-    P( A, B, C, D, E, R(20) );
-    P( E, A, B, C, D, R(21) );
-    P( D, E, A, B, C, R(22) );
-    P( C, D, E, A, B, R(23) );
-    P( B, C, D, E, A, R(24) );
-    P( A, B, C, D, E, R(25) );
-    P( E, A, B, C, D, R(26) );
-    P( D, E, A, B, C, R(27) );
-    P( C, D, E, A, B, R(28) );
-    P( B, C, D, E, A, R(29) );
-    P( A, B, C, D, E, R(30) );
-    P( E, A, B, C, D, R(31) );
-    P( D, E, A, B, C, R(32) );
-    P( C, D, E, A, B, R(33) );
-    P( B, C, D, E, A, R(34) );
-    P( A, B, C, D, E, R(35) );
-    P( E, A, B, C, D, R(36) );
-    P( D, E, A, B, C, R(37) );
-    P( C, D, E, A, B, R(38) );
-    P( B, C, D, E, A, R(39) );
+    P( local.A, local.B, local.C, local.D, local.E, R(20) );
+    P( local.E, local.A, local.B, local.C, local.D, R(21) );
+    P( local.D, local.E, local.A, local.B, local.C, R(22) );
+    P( local.C, local.D, local.E, local.A, local.B, R(23) );
+    P( local.B, local.C, local.D, local.E, local.A, R(24) );
+    P( local.A, local.B, local.C, local.D, local.E, R(25) );
+    P( local.E, local.A, local.B, local.C, local.D, R(26) );
+    P( local.D, local.E, local.A, local.B, local.C, R(27) );
+    P( local.C, local.D, local.E, local.A, local.B, R(28) );
+    P( local.B, local.C, local.D, local.E, local.A, R(29) );
+    P( local.A, local.B, local.C, local.D, local.E, R(30) );
+    P( local.E, local.A, local.B, local.C, local.D, R(31) );
+    P( local.D, local.E, local.A, local.B, local.C, R(32) );
+    P( local.C, local.D, local.E, local.A, local.B, R(33) );
+    P( local.B, local.C, local.D, local.E, local.A, R(34) );
+    P( local.A, local.B, local.C, local.D, local.E, R(35) );
+    P( local.E, local.A, local.B, local.C, local.D, R(36) );
+    P( local.D, local.E, local.A, local.B, local.C, R(37) );
+    P( local.C, local.D, local.E, local.A, local.B, R(38) );
+    P( local.B, local.C, local.D, local.E, local.A, R(39) );
 
 #undef K
 #undef F
@@ -256,26 +261,26 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx,
 #define F(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
 #define K 0x8F1BBCDC
 
-    P( A, B, C, D, E, R(40) );
-    P( E, A, B, C, D, R(41) );
-    P( D, E, A, B, C, R(42) );
-    P( C, D, E, A, B, R(43) );
-    P( B, C, D, E, A, R(44) );
-    P( A, B, C, D, E, R(45) );
-    P( E, A, B, C, D, R(46) );
-    P( D, E, A, B, C, R(47) );
-    P( C, D, E, A, B, R(48) );
-    P( B, C, D, E, A, R(49) );
-    P( A, B, C, D, E, R(50) );
-    P( E, A, B, C, D, R(51) );
-    P( D, E, A, B, C, R(52) );
-    P( C, D, E, A, B, R(53) );
-    P( B, C, D, E, A, R(54) );
-    P( A, B, C, D, E, R(55) );
-    P( E, A, B, C, D, R(56) );
-    P( D, E, A, B, C, R(57) );
-    P( C, D, E, A, B, R(58) );
-    P( B, C, D, E, A, R(59) );
+    P( local.A, local.B, local.C, local.D, local.E, R(40) );
+    P( local.E, local.A, local.B, local.C, local.D, R(41) );
+    P( local.D, local.E, local.A, local.B, local.C, R(42) );
+    P( local.C, local.D, local.E, local.A, local.B, R(43) );
+    P( local.B, local.C, local.D, local.E, local.A, R(44) );
+    P( local.A, local.B, local.C, local.D, local.E, R(45) );
+    P( local.E, local.A, local.B, local.C, local.D, R(46) );
+    P( local.D, local.E, local.A, local.B, local.C, R(47) );
+    P( local.C, local.D, local.E, local.A, local.B, R(48) );
+    P( local.B, local.C, local.D, local.E, local.A, R(49) );
+    P( local.A, local.B, local.C, local.D, local.E, R(50) );
+    P( local.E, local.A, local.B, local.C, local.D, R(51) );
+    P( local.D, local.E, local.A, local.B, local.C, R(52) );
+    P( local.C, local.D, local.E, local.A, local.B, R(53) );
+    P( local.B, local.C, local.D, local.E, local.A, R(54) );
+    P( local.A, local.B, local.C, local.D, local.E, R(55) );
+    P( local.E, local.A, local.B, local.C, local.D, R(56) );
+    P( local.D, local.E, local.A, local.B, local.C, R(57) );
+    P( local.C, local.D, local.E, local.A, local.B, R(58) );
+    P( local.B, local.C, local.D, local.E, local.A, R(59) );
 
 #undef K
 #undef F
@@ -283,35 +288,38 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx,
 #define F(x,y,z) ((x) ^ (y) ^ (z))
 #define K 0xCA62C1D6
 
-    P( A, B, C, D, E, R(60) );
-    P( E, A, B, C, D, R(61) );
-    P( D, E, A, B, C, R(62) );
-    P( C, D, E, A, B, R(63) );
-    P( B, C, D, E, A, R(64) );
-    P( A, B, C, D, E, R(65) );
-    P( E, A, B, C, D, R(66) );
-    P( D, E, A, B, C, R(67) );
-    P( C, D, E, A, B, R(68) );
-    P( B, C, D, E, A, R(69) );
-    P( A, B, C, D, E, R(70) );
-    P( E, A, B, C, D, R(71) );
-    P( D, E, A, B, C, R(72) );
-    P( C, D, E, A, B, R(73) );
-    P( B, C, D, E, A, R(74) );
-    P( A, B, C, D, E, R(75) );
-    P( E, A, B, C, D, R(76) );
-    P( D, E, A, B, C, R(77) );
-    P( C, D, E, A, B, R(78) );
-    P( B, C, D, E, A, R(79) );
+    P( local.A, local.B, local.C, local.D, local.E, R(60) );
+    P( local.E, local.A, local.B, local.C, local.D, R(61) );
+    P( local.D, local.E, local.A, local.B, local.C, R(62) );
+    P( local.C, local.D, local.E, local.A, local.B, R(63) );
+    P( local.B, local.C, local.D, local.E, local.A, R(64) );
+    P( local.A, local.B, local.C, local.D, local.E, R(65) );
+    P( local.E, local.A, local.B, local.C, local.D, R(66) );
+    P( local.D, local.E, local.A, local.B, local.C, R(67) );
+    P( local.C, local.D, local.E, local.A, local.B, R(68) );
+    P( local.B, local.C, local.D, local.E, local.A, R(69) );
+    P( local.A, local.B, local.C, local.D, local.E, R(70) );
+    P( local.E, local.A, local.B, local.C, local.D, R(71) );
+    P( local.D, local.E, local.A, local.B, local.C, R(72) );
+    P( local.C, local.D, local.E, local.A, local.B, R(73) );
+    P( local.B, local.C, local.D, local.E, local.A, R(74) );
+    P( local.A, local.B, local.C, local.D, local.E, R(75) );
+    P( local.E, local.A, local.B, local.C, local.D, R(76) );
+    P( local.D, local.E, local.A, local.B, local.C, R(77) );
+    P( local.C, local.D, local.E, local.A, local.B, R(78) );
+    P( local.B, local.C, local.D, local.E, local.A, R(79) );
 
 #undef K
 #undef F
 
-    ctx->state[0] += A;
-    ctx->state[1] += B;
-    ctx->state[2] += C;
-    ctx->state[3] += D;
-    ctx->state[4] += E;
+    ctx->state[0] += local.A;
+    ctx->state[1] += local.B;
+    ctx->state[2] += local.C;
+    ctx->state[3] += local.D;
+    ctx->state[4] += local.E;
+
+    /* Zeroise buffers and variables to clear sensitive data from memory. */
+    mbedtls_platform_zeroize( &local, sizeof( local ) );
 
     return( 0 );
 }
diff --git a/library/sha256.c b/library/sha256.c
index 5169584b684d3b09cd469a2b50d98fadbb2fa4c1..75a8f8a2b25f81c87654c6a8b7835ca82d696296 100755
--- a/library/sha256.c
+++ b/library/sha256.c
@@ -209,77 +209,104 @@ static const uint32_t K[] =
 #define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
 #define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
 
-#define R(t)                                    \
-    (                                           \
-        W[t] = S1(W[(t) -  2]) + W[(t) -  7] +  \
-               S0(W[(t) - 15]) + W[(t) - 16]    \
+#define R(t)                                                        \
+    (                                                               \
+        local.W[t] = S1(local.W[(t) -  2]) + local.W[(t) -  7] +    \
+                     S0(local.W[(t) - 15]) + local.W[(t) - 16]      \
     )
 
-#define P(a,b,c,d,e,f,g,h,x,K)                          \
-    do                                                  \
-    {                                                   \
-        temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x);      \
-        temp2 = S2(a) + F0((a),(b),(c));                        \
-        (d) += temp1; (h) = temp1 + temp2;              \
+#define P(a,b,c,d,e,f,g,h,x,K)                                      \
+    do                                                              \
+    {                                                               \
+        local.temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x);    \
+        local.temp2 = S2(a) + F0((a),(b),(c));                      \
+        (d) += local.temp1; (h) = local.temp1 + local.temp2;        \
     } while( 0 )
 
 int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
                                 const unsigned char data[64] )
 {
-    uint32_t temp1, temp2, W[64];
-    uint32_t A[8];
+    struct
+    {
+        uint32_t temp1, temp2, W[64];
+        uint32_t A[8];
+    } local;
+
     unsigned int i;
 
     SHA256_VALIDATE_RET( ctx != NULL );
     SHA256_VALIDATE_RET( (const unsigned char *)data != NULL );
 
     for( i = 0; i < 8; i++ )
-        A[i] = ctx->state[i];
+        local.A[i] = ctx->state[i];
 
 #if defined(MBEDTLS_SHA256_SMALLER)
     for( i = 0; i < 64; i++ )
     {
         if( i < 16 )
-            GET_UINT32_BE( W[i], data, 4 * i );
+            GET_UINT32_BE( local.W[i], data, 4 * i );
         else
             R( i );
 
-        P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] );
+        P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
+           local.A[5], local.A[6], local.A[7], local.W[i], K[i] );
 
-        temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3];
-        A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1;
+        local.temp1 = local.A[7]; local.A[7] = local.A[6];
+        local.A[6] = local.A[5]; local.A[5] = local.A[4];
+        local.A[4] = local.A[3]; local.A[3] = local.A[2];
+        local.A[2] = local.A[1]; local.A[1] = local.A[0];
+        local.A[0] = local.temp1;
     }
 #else /* MBEDTLS_SHA256_SMALLER */
     for( i = 0; i < 16; i++ )
-        GET_UINT32_BE( W[i], data, 4 * i );
+        GET_UINT32_BE( local.W[i], data, 4 * i );
 
     for( i = 0; i < 16; i += 8 )
     {
-        P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i+0], K[i+0] );
-        P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i+1], K[i+1] );
-        P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i+2], K[i+2] );
-        P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i+3], K[i+3] );
-        P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i+4], K[i+4] );
-        P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i+5], K[i+5] );
-        P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i+6], K[i+6] );
-        P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i+7], K[i+7] );
+        P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
+           local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0] );
+        P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
+           local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1] );
+        P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
+           local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2] );
+        P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
+           local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3] );
+        P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
+           local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4] );
+        P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
+           local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5] );
+        P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
+           local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6] );
+        P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
+           local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7] );
     }
 
     for( i = 16; i < 64; i += 8 )
     {
-        P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(i+0), K[i+0] );
-        P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(i+1), K[i+1] );
-        P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(i+2), K[i+2] );
-        P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(i+3), K[i+3] );
-        P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(i+4), K[i+4] );
-        P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(i+5), K[i+5] );
-        P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(i+6), K[i+6] );
-        P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(i+7), K[i+7] );
+        P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
+           local.A[5], local.A[6], local.A[7], R(i+0), K[i+0] );
+        P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
+           local.A[4], local.A[5], local.A[6], R(i+1), K[i+1] );
+        P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
+           local.A[3], local.A[4], local.A[5], R(i+2), K[i+2] );
+        P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
+           local.A[2], local.A[3], local.A[4], R(i+3), K[i+3] );
+        P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
+           local.A[1], local.A[2], local.A[3], R(i+4), K[i+4] );
+        P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
+           local.A[0], local.A[1], local.A[2], R(i+5), K[i+5] );
+        P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
+           local.A[7], local.A[0], local.A[1], R(i+6), K[i+6] );
+        P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
+           local.A[6], local.A[7], local.A[0], R(i+7), K[i+7] );
     }
 #endif /* MBEDTLS_SHA256_SMALLER */
 
     for( i = 0; i < 8; i++ )
-        ctx->state[i] += A[i];
+        ctx->state[i] += local.A[i];
+
+    /* Zeroise buffers and variables to clear sensitive data from memory. */
+    mbedtls_platform_zeroize( &local, sizeof( local ) );
 
     return( 0 );
 }
diff --git a/library/sha512.c b/library/sha512.c
index 36d5d96146fbdb9eb5aec15bc49e49fe83e00f31..986037ab7c95853e20b54ad8dca691b6ce24d837 100755
--- a/library/sha512.c
+++ b/library/sha512.c
@@ -243,8 +243,11 @@ int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
                                      const unsigned char data[128] )
 {
     int i;
-    uint64_t temp1, temp2, W[80];
-    uint64_t A, B, C, D, E, F, G, H;
+    struct
+    {
+        uint64_t temp1, temp2, W[80];
+        uint64_t A, B, C, D, E, F, G, H;
+    } local;
 
     SHA512_VALIDATE_RET( ctx != NULL );
     SHA512_VALIDATE_RET( (const unsigned char *)data != NULL );
@@ -261,56 +264,67 @@ int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
 #define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
 #define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
 
-#define P(a,b,c,d,e,f,g,h,x,K)                                  \
-    do                                                          \
-    {                                                           \
-        temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x);      \
-        temp2 = S2(a) + F0((a),(b),(c));                        \
-        (d) += temp1; (h) = temp1 + temp2;                      \
+#define P(a,b,c,d,e,f,g,h,x,K)                                      \
+    do                                                              \
+    {                                                               \
+        local.temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x);    \
+        local.temp2 = S2(a) + F0((a),(b),(c));                      \
+        (d) += local.temp1; (h) = local.temp1 + local.temp2;        \
     } while( 0 )
 
     for( i = 0; i < 16; i++ )
     {
-        GET_UINT64_BE( W[i], data, i << 3 );
+        GET_UINT64_BE( local.W[i], data, i << 3 );
     }
 
     for( ; i < 80; i++ )
     {
-        W[i] = S1(W[i -  2]) + W[i -  7] +
-               S0(W[i - 15]) + W[i - 16];
+        local.W[i] = S1(local.W[i -  2]) + local.W[i -  7] +
+                     S0(local.W[i - 15]) + local.W[i - 16];
     }
 
-    A = ctx->state[0];
-    B = ctx->state[1];
-    C = ctx->state[2];
-    D = ctx->state[3];
-    E = ctx->state[4];
-    F = ctx->state[5];
-    G = ctx->state[6];
-    H = ctx->state[7];
+    local.A = ctx->state[0];
+    local.B = ctx->state[1];
+    local.C = ctx->state[2];
+    local.D = ctx->state[3];
+    local.E = ctx->state[4];
+    local.F = ctx->state[5];
+    local.G = ctx->state[6];
+    local.H = ctx->state[7];
     i = 0;
 
     do
     {
-        P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
-        P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
-        P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
-        P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
-        P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
-        P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
-        P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
-        P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
+        P( local.A, local.B, local.C, local.D, local.E,
+           local.F, local.G, local.H, local.W[i], K[i] ); i++;
+        P( local.H, local.A, local.B, local.C, local.D,
+           local.E, local.F, local.G, local.W[i], K[i] ); i++;
+        P( local.G, local.H, local.A, local.B, local.C,
+           local.D, local.E, local.F, local.W[i], K[i] ); i++;
+        P( local.F, local.G, local.H, local.A, local.B,
+           local.C, local.D, local.E, local.W[i], K[i] ); i++;
+        P( local.E, local.F, local.G, local.H, local.A,
+           local.B, local.C, local.D, local.W[i], K[i] ); i++;
+        P( local.D, local.E, local.F, local.G, local.H,
+           local.A, local.B, local.C, local.W[i], K[i] ); i++;
+        P( local.C, local.D, local.E, local.F, local.G,
+           local.H, local.A, local.B, local.W[i], K[i] ); i++;
+        P( local.B, local.C, local.D, local.E, local.F,
+           local.G, local.H, local.A, local.W[i], K[i] ); i++;
     }
     while( i < 80 );
 
-    ctx->state[0] += A;
-    ctx->state[1] += B;
-    ctx->state[2] += C;
-    ctx->state[3] += D;
-    ctx->state[4] += E;
-    ctx->state[5] += F;
-    ctx->state[6] += G;
-    ctx->state[7] += H;
+    ctx->state[0] += local.A;
+    ctx->state[1] += local.B;
+    ctx->state[2] += local.C;
+    ctx->state[3] += local.D;
+    ctx->state[4] += local.E;
+    ctx->state[5] += local.F;
+    ctx->state[6] += local.G;
+    ctx->state[7] += local.H;
+
+    /* Zeroise buffers and variables to clear sensitive data from memory. */
+    mbedtls_platform_zeroize( &local, sizeof( local ) );
 
     return( 0 );
 }
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 97b778452c81be0c6aa95b6b0a73cd8dcbb5549f..cbf6142ac204a198ef998e7adc7531bbdbef473f 100755
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -3587,11 +3587,12 @@ static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl,
     /* 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 2471600c9a18c5590669e429798b7196ce0b743d..c749a8611c43dea0e59c7fdd41bddb408819fc8c 100755
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -621,7 +621,7 @@ static void ssl_calc_finished_tls( mbedtls_ssl_context *, unsigned char *, int )
 #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 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
 }
 
 #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 @@ void ssl_calc_verify_ssl( mbedtls_ssl_context *ssl, unsigned char hash[36] )
 #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 @@ void ssl_calc_verify_tls( mbedtls_ssl_context *ssl, unsigned char hash[36] )
 
 #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 @@ void ssl_calc_verify_tls_sha256( mbedtls_ssl_context *ssl, unsigned char hash[32
 #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 @@ static void ssl_calc_finished_tls_sha256(
 #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 @@ static void ssl_calc_finished_tls_sha384(
     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 @@ static void ssl_calc_finished_tls_sha384(
              ? "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 61c4b94041f265adb007a3d24a3043fa4e75049a..0dc5488c1a988f95d5ea3d4e899444c4fe5f1511 100755
--- 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 @@ static void threading_mutex_init_pthread( mbedtls_threading_mutex_t *mutex )
     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 cbf38dc2c29ac3198286c34664e700c74efb0959..8c8e815e9d5d0e465a40f9380062ba98533e89d0 100755
--- a/library/version_features.c
+++ b/library/version_features.c
@@ -553,6 +553,9 @@ static const char *features[] = {
 #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 fadd28eff2c81dc182b88b19b84b0d06e505149b..4b53d1a8c5e66785ad9c0f242e2e018c3d0252ce 100755
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -1088,6 +1088,7 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *
 
     if( crt->sig_oid.len != sig_oid2.len ||
         memcmp( crt->sig_oid.p, sig_oid2.p, crt->sig_oid.len ) != 0 ||
+        sig_params1.tag != sig_params2.tag ||
         sig_params1.len != sig_params2.len ||
         ( sig_params1.len != 0 &&
           memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) )
diff --git a/programs/ssl/CMakeLists.txt b/programs/ssl/CMakeLists.txt
index b3ef4f8e991eac998ba5dc8204de107c8f90f33f..094543bdcb2cf23bf058a9428bd7c8f2a5d77bee 100755
--- a/programs/ssl/CMakeLists.txt
+++ b/programs/ssl/CMakeLists.txt
@@ -37,8 +37,8 @@ target_link_libraries(mini_client ${libs})
 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 @@ target_link_libraries(ssl_mail_client ${libs})
 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 798c9178f89e7c082c4dc71fdc07c09da9948f87..0a7eb1aeccf9d45c520181079a196a82894ad764 100755
--- a/programs/ssl/query_config.c
+++ b/programs/ssl/query_config.c
@@ -1475,6 +1475,14 @@ int query_config( const char *config )
     }
 #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 5feb31773b1f9d52be6d01a69efdda0a815f8bb7..a74db1e0834b67320949f897a0aa92698d31ec52 100755
--- a/programs/test/CMakeLists.txt
+++ b/programs/test/CMakeLists.txt
@@ -27,8 +27,8 @@ target_link_libraries(udp_proxy ${libs})
 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 9bc9a9c6ba26540f4dfde6162f41b64f9b596095..fe35bb15af4636857a286d128cbe64427ba1b4d1 100755
--- a/programs/test/selftest.c
+++ b/programs/test/selftest.c
@@ -185,7 +185,7 @@ static int calloc_self_test( int verbose )
 }
 #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 c88050cde7f81d8e9730669d5850bd63125897e9..dc796034ca6ee0d15063760d8c3801c3e1a29b90 100755
--- a/programs/x509/cert_req.c
+++ b/programs/x509/cert_req.c
@@ -127,9 +127,8 @@ int main( void )
     "                          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 @@ int main( int argc, char *argv[] )
         }
         else if( strcmp( p, "md" ) == 0 )
         {
-            if( strcmp( q, "SHA256" ) == 0 )
-            {
-                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 */
+            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_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 bccc3b7b438a34cdd2a2ff348e4f844dc8bcb26e..f0f044de79b2fe0bfda8472f41bd0202350cde69 100755
--- a/programs/x509/cert_write.c
+++ b/programs/x509/cert_write.c
@@ -145,8 +145,9 @@ int main( void )
     "    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 @@ int main( int argc, char *argv[] )
         }
         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 162d93b45c4592da58477c7a3ffb4c809d31e8d8..c5c8707dcc7b3a75fe96d31d3c7b4a9e06bfde6b 100755
--- 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 
-#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 
+#include 
 
 HEADER_INCLUDED
 
@@ -130,8 +129,6 @@ LOW_LEVEL_CODE_CHECKS
 
 #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 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
         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 7796bd2faf6ded26d833fcd81b0120a0983a203e..8905430c76d7e28f5145fdb5d848d8769007a482 100755
--- a/tests/compat.sh
+++ b/tests/compat.sh
@@ -117,12 +117,12 @@ PEERS="OpenSSL$PEER_GNUTLS mbedTLS"
 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 @@ run_client() {
     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 a4d124c9c838dd48933fb55f471dec4ab7cddaca..db4ee3b3dc0929275d8a3bf21867f6e8b8f6c6ce 100755
--- 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
@@ -155,7 +157,11 @@ cli-rsa-sha256.crt.der: cli-rsa-sha256.crt
 	$(OPENSSL) x509 -in $< -out $@ -inform PEM -outform DER
 all_final += cli-rsa-sha256.crt.der
 
- cli-rsa.key.der: $(cli_crt_key_file_rsa)
+cli-rsa-sha256-badalg.crt.der: cli-rsa-sha256.crt.der
+	hexdump -ve '1/1 "%.2X"' $< | sed "s/06092A864886F70D01010B0500/06092A864886F70D01010B0900/2" | xxd -r -p > $@
+all_final += cli-rsa-sha256-badalg.crt.der
+
+cli-rsa.key.der: $(cli_crt_key_file_rsa)
 	$(OPENSSL) pkey -in $< -out $@ -inform PEM -outform DER
 all_final += cli-rsa.key.der
 
diff --git a/tests/data_files/cert_md2.csr b/tests/data_files/cert_md2.csr
new file mode 100644
index 0000000000000000000000000000000000000000..a8c39bdb32c113c3867424e327a82990ca3c2332
--- /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 0000000000000000000000000000000000000000..d8a3dbf203c5535ab186c534c3927be28e79a2a5
--- /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 8b4d089bb4c7692a168fac77b88ac7effe97748c..d69b0b7757c3339cf0b1a81a446cc2eee270fc29 100644
--- a/tests/data_files/cert_md5.crt
+++ b/tests/data_files/cert_md5.crt
@@ -3,18 +3,18 @@ MIIDPzCCAiegAwIBAgIBBjANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJOTDER
 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 0000000000000000000000000000000000000000..dc6792d386a00ab07ef0b5d0a2a6571485615d24
--- /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/cli-rsa-sha256-badalg.crt.der b/tests/data_files/cli-rsa-sha256-badalg.crt.der
new file mode 100644
index 0000000000000000000000000000000000000000..c40ba2a44b4c7a6d511eb40815cd9be1729619ce
Binary files /dev/null and b/tests/data_files/cli-rsa-sha256-badalg.crt.der differ
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 1184119e7e41462172fb45bec72d0bff5939963b..1e56c3e62a74f7b12bcdc531554c9647713db51e 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -185,6 +185,9 @@ pre_initialize_variables () {
         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 @@ component_test_no_hmac_drbg () {
     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 () {
@@ -1311,7 +1324,7 @@ component_test_malloc_0_null () {
     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
@@ -1498,6 +1511,20 @@ component_test_no_64bit_multiplication () {
     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 5f3b5a719740e07c4cd3866bd196fbdc2f72aa30..7c979bcd81a3815252fe73ce1207d723e750ba57 100755
--- a/tests/scripts/check-names.sh
+++ b/tests/scripts/check-names.sh
@@ -92,7 +92,7 @@ fi
 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 @@ for THING in actual-macros enum-consts; do
 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 a8bfa6e904fbf6c0fd635946e1573126eafba022..94fc3351e7032cf3f92a94a505e06941c3c07ca5 100755
--- a/tests/scripts/test-ref-configs.pl
+++ b/tests/scripts/test-ref-configs.pl
@@ -55,15 +55,17 @@ use warnings;
 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 af6b0af8ba07eefc507c3bcf9018a584d6bb1b74..b6c03224efd0c1ad1b9be26fd85e228abf372e02 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -130,8 +130,8 @@ print_usage() {
     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 @@ print_name() {
     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 @@ run_test() {
         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 @@ run_test() {
         # 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 @@ run_test() {
         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 @@ run_test    "Session resume using cache, DTLS: openssl server" \
 # 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='8'
 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 <
 #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 @@ typedef enum
        }                                                    \
     } 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 @@ static struct
     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 @@ jmp_buf jmp_tmp;
 
 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 @@ int rnd_pseudo_rand( void *rng_state, unsigned char *output, size_t len )
     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 @@ int hexcmp( uint8_t * a, uint8_t * b, uint32_t a_len, uint32_t b_len )
     }
     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 ca51e7b2850c52669a184c9940a724e6248ccc9c..3f8a945ea34a436b640509e7cf3171dcab83112f 100755
--- a/tests/suites/host_test.function
+++ b/tests/suites/host_test.function
@@ -330,7 +330,7 @@ static int convert_params( size_t cnt , char ** params , int * int_params_store
 #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 @@ int execute_tests( int argc , const char ** argv )
     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 f516d2caa12db19f8017b0145086e148bcddc767..2aecf8142f85a131e1d3ed6eb7c015dcc9c5e92f 100755
--- a/tests/suites/main_test.function
+++ b/tests/suites/main_test.function
@@ -23,6 +23,15 @@
 #endif
 #endif
 
+/*
+ * for arc4random_buf() from 
+ */
+#if defined(__NetBSD__)
+#define _NETBSD_SOURCE 1
+#elif defined(__OpenBSD__)
+#define _BSD_SOURCE 1
+#endif
+
 #if !defined(MBEDTLS_CONFIG_FILE)
 #include 
 #else
@@ -167,6 +176,10 @@ void execute_function_ptr(TestWrapper_t fp, void **params)
 #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 3374a07e423341ea448a2eddadc4d04becbecc7e..23bf83d0931b0ade7ec2edd0fa324edb3f2e6913 100755
--- 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 @@ void aes_encrypt_ecb( data_t * key_str, data_t * src_str,
     {
         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 @@ exit:
 
 /* 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 @@ void aes_decrypt_ecb( data_t * key_str, data_t * src_str,
     {
         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 @@ exit:
 
 /* 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 @@ void aes_encrypt_cbc( data_t * key_str, data_t * iv_str,
     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 @@ exit:
 
 /* 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 @@ void aes_decrypt_cbc( data_t * key_str, data_t * iv_str,
     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 @@ exit:
 
 /* 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 @@ void aes_encrypt_cfb128( data_t * key_str, data_t * iv_str,
     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 @@ exit:
 
 /* 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 @@ void aes_decrypt_cfb128( data_t * key_str, data_t * iv_str,
     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 @@ exit:
 
 /* 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 @@ void aes_encrypt_cfb8( data_t * key_str, data_t * iv_str,
     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 @@ exit:
 
 /* 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 @@ void aes_decrypt_cfb8( data_t * key_str, data_t * iv_str,
     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 @@ exit:
 /* 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 @@ void aes_encrypt_ofb( int fragment_size, data_t *key_str,
         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 ae3b032b3b833b3c17b3ba8460dfcc58254c9ab3..c1e2386656ad6d80710c6dea00557c7f3032a7f1 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 @@ void mbedtls_arc4_crypt( data_t * src_str, data_t * key_str,
 
 
     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 d08c39dc66b511e45ff78592d22f66680d29a5c1..6d6a203356e487a29e7d383a60cf2f274e278c84 100755
--- a/tests/suites/test_suite_aria.function
+++ b/tests/suites/test_suite_aria.function
@@ -207,14 +207,12 @@ exit:
 
 /* 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 @@ void aria_encrypt_ecb( data_t *key_str, data_t *src_str,
             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 @@ exit:
 
 /* 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 @@ void aria_decrypt_ecb( data_t *key_str, data_t *src_str,
             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 @@ exit:
 
 /* 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 @@ void aria_encrypt_cbc( data_t *key_str, data_t *iv_str,
                                          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 @@ exit:
 
 /* 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 @@ void aria_decrypt_cbc( data_t *key_str, data_t *iv_str,
                                          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 @@ exit:
 
 /* 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 @@ void aria_encrypt_cfb128( data_t *key_str, data_t *iv_str,
                                             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 @@ exit:
 
 /* 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 @@ void aria_decrypt_cfb128( data_t *key_str, data_t *iv_str,
                                             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 @@ exit:
 
 /* 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 @@ void aria_encrypt_ctr( data_t *key_str, data_t *iv_str,
     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 @@ exit:
 
 /* 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 @@ void aria_decrypt_ctr( data_t *key_str, data_t *iv_str,
     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_base64.data b/tests/suites/test_suite_base64.data
index da99ffa8794fc026174f51b18c4f97bb254af619..3a892f4792a0d2a29f5adbc26ddbf69b9cfa0631 100644
--- a/tests/suites/test_suite_base64.data
+++ b/tests/suites/test_suite_base64.data
@@ -151,6 +151,20 @@ base64_encode_hex:"0102030405060708":"AQIDBAUGBwg=":13:0
 Base64 encode hex #4
 base64_encode_hex:"01020304050607":"AQIDBAUGBw==":13:0
 
+# Rotate the bytes around so that they end up at each offset modulo 3 in
+# successive test cases.
+Base64 encode hex all valid input bytes #0
+base64_encode_hex:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w==":345:0
+
+Base64 encode hex all valid input bytes #1
+base64_encode_hex:"0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff00":"AQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2Nzg5Ojs8PT4/QEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXp7fH1+f4CBgoOEhYaHiImKi4yNjo+QkZKTlJWWl5iZmpucnZ6foKGio6SlpqeoqaqrrK2ur7CxsrO0tba3uLm6u7y9vr/AwcLDxMXGx8jJysvMzc7P0NHS09TV1tfY2drb3N3e3+Dh4uPk5ebn6Onq6+zt7u/w8fLz9PX29/j5+vv8/f7/AA==":345:0
+
+Base64 encode hex all valid input bytes #2
+base64_encode_hex:"02030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff0001":"AgMEBQYHCAkKCwwNDg8QERITFBUWFxgZGhscHR4fICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj9AQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVpbXF1eX2BhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ent8fX5/gIGCg4SFhoeIiYqLjI2Oj5CRkpOUlZaXmJmam5ydnp+goaKjpKWmp6ipqqusra6vsLGys7S1tre4ubq7vL2+v8DBwsPExcbHyMnKy8zNzs/Q0dLT1NXW19jZ2tvc3d7f4OHi4+Tl5ufo6err7O3u7/Dx8vP09fb3+Pn6+/z9/v8AAQ==":345:0
+
+Base64 encode all valid output characters at all offsets
+base64_encode_hex:"00108310518720928b30d38f41149351559761969b71d79f8218a39259a7a29aabb2dbafc31cb3d35db7e39ebbf3dfbff800420c41461c824a2cc34e3d04524d45565d865a6dc75e7e08628e49669e8a6aaecb6ebf0c72cf4d76df8e7aefcf7effe00108310518720928b30d38f41149351559761969b71d79f8218a39259a7a29aabb2dbafc31cb3d35db7e39ebbf3dfbff800420c41461c824a2cc34e3d04524d45565d865a6dc75e7e08628e49669e8a6aaecb6ebf0c72cf4d76df8e7aefcf7efd0":"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/+ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/+ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/+ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/Q":261:0
+
 Base64 decode hex #1
 base64_decode_hex:"AQIDBAUGBwgJ":"010203040506070809":9:0
 
@@ -166,6 +180,9 @@ base64_decode_hex:"AQIDBAUGBw==":"01020304050607":7:0
 Base64 decode hex #5 (buffer too small)
 base64_decode_hex:"AQIDBAUGBw==":"01020304050607":6:MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL
 
+Base64 decode all valid input characters at all offsets
+base64_decode_hex:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/+ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/+ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/+ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/Q":"00108310518720928b30d38f41149351559761969b71d79f8218a39259a7a29aabb2dbafc31cb3d35db7e39ebbf3dfbff800420c41461c824a2cc34e3d04524d45565d865a6dc75e7e08628e49669e8a6aaecb6ebf0c72cf4d76df8e7aefcf7effe00108310518720928b30d38f41149351559761969b71d79f8218a39259a7a29aabb2dbafc31cb3d35db7e39ebbf3dfbff800420c41461c824a2cc34e3d04524d45565d865a6dc75e7e08628e49669e8a6aaecb6ebf0c72cf4d76df8e7aefcf7efd0":195:0
+
 Base64 Selftest
 depends_on:MBEDTLS_SELF_TEST
 base64_selftest:
diff --git a/tests/suites/test_suite_base64.function b/tests/suites/test_suite_base64.function
index 3a8bf430f388a35e94db1580cd036f156fc2eb17..0185f3b2435224162a1b1410f427ad28749a997b 100644
--- a/tests/suites/test_suite_base64.function
+++ b/tests/suites/test_suite_base64.function
@@ -13,13 +13,22 @@ void mbedtls_base64_encode( char * src_string, char * dst_string,
 {
     unsigned char src_str[1000];
     unsigned char dst_str[1000];
-    size_t len;
+    size_t len, src_len;
 
     memset(src_str, 0x00, 1000);
     memset(dst_str, 0x00, 1000);
 
     strncpy( (char *) src_str, src_string, sizeof(src_str) - 1 );
-    TEST_ASSERT( mbedtls_base64_encode( dst_str, dst_buf_size, &len, src_str, strlen( (char *) src_str ) ) == result );
+    src_len = strlen( (char *) src_str );
+
+    TEST_CF_SECRET( src_str, sizeof( src_str ) );
+    TEST_ASSERT( mbedtls_base64_encode( dst_str, dst_buf_size, &len, src_str, src_len) == result );
+    TEST_CF_PUBLIC( src_str, sizeof( src_str ) );
+
+    /* dest_str will have had tainted data copied to it, prevent the TEST_ASSERT below from triggering
+       CF failures by unmarking it. */
+    TEST_CF_PUBLIC( dst_str, len );
+
     if( result == 0 )
     {
         TEST_ASSERT( strcmp( (char *) dst_str, dst_string ) == 0 );
@@ -57,7 +66,14 @@ void base64_encode_hex( data_t * src, char * dst, int dst_buf_size,
 
     res = zero_alloc( dst_buf_size );
 
+    TEST_CF_SECRET( src->x, src->len );
     TEST_ASSERT( mbedtls_base64_encode( res, dst_buf_size, &len, src->x, src->len ) == result );
+    TEST_CF_PUBLIC( src->x, src->len );
+
+    /* res will have had tainted data copied to it, prevent the TEST_ASSERT below from triggering
+       CF failures by unmarking it. */
+    TEST_CF_PUBLIC( res, len );
+
     if( result == 0 )
     {
         TEST_ASSERT( len == strlen( dst ) );
diff --git a/tests/suites/test_suite_blowfish.function b/tests/suites/test_suite_blowfish.function
index 7a93cd1395dcf3730687c0270336e24e41c4ec87..f89353ce9520538affa18646a868a9a66735eb56 100644
--- a/tests/suites/test_suite_blowfish.function
+++ b/tests/suites/test_suite_blowfish.function
@@ -167,7 +167,7 @@ exit:
 
 /* 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 @@ void blowfish_encrypt_ecb( data_t * key_str, data_t * src_str,
     {
         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 @@ exit:
 
 /* 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 @@ void blowfish_decrypt_ecb( data_t * key_str, data_t * src_str,
     {
         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 @@ exit:
 
 /* 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 @@ void blowfish_encrypt_cbc( data_t * key_str, data_t * iv_str,
     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 @@ exit:
 
 /* 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 @@ void blowfish_decrypt_cbc( data_t * key_str, data_t * iv_str,
     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 @@ exit:
 
 /* 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 @@ void blowfish_encrypt_cfb64( data_t * key_str, data_t * iv_str,
     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 @@ exit:
 
 /* 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 @@ void blowfish_decrypt_cfb64( data_t * key_str, data_t * iv_str,
     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 @@ exit:
 
 /* 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 @@ void blowfish_encrypt_ctr( data_t * key_str, data_t * iv_str,
     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 9408348151e90590edc023b73772b47e989f25ea..312495c9ae2b5fbcc5d83c0df1fe89819eb08a0b 100644
--- a/tests/suites/test_suite_camellia.function
+++ b/tests/suites/test_suite_camellia.function
@@ -175,7 +175,7 @@ exit:
 
 /* 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 @@ void camellia_encrypt_ecb( data_t * key_str, data_t * src_str,
     {
         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 @@ exit:
 
 /* 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 @@ void camellia_decrypt_ecb( data_t * key_str, data_t * src_str,
     {
         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 @@ exit:
 
 /* 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 @@ void camellia_encrypt_cbc( data_t * key_str, data_t * iv_str,
     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 @@ exit:
 
 /* 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 @@ void camellia_decrypt_cbc( data_t * key_str, data_t * iv_str,
     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 @@ exit:
 
 /* 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 @@ void camellia_encrypt_cfb128( data_t * key_str, data_t * iv_str,
     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 @@ exit:
 /* 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 @@ void camellia_decrypt_cfb128( data_t * key_str, data_t * iv_str,
     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 a04583b7ee2ce3ec135232329121b92a27ae8f99..1b3a25f0a4df4dbfe07c2bb0ac7ef19b95b6be5a 100755
--- a/tests/suites/test_suite_ccm.function
+++ b/tests/suites/test_suite_ccm.function
@@ -152,7 +152,7 @@ exit:
 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 @@ void mbedtls_ccm_auth_decrypt( int cipher_id, data_t * key,
 
     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 @@ void mbedtls_ccm_star_encrypt_and_tag( int cipher_id,
     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 @@ void mbedtls_ccm_star_encrypt_and_tag( int cipher_id,
     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 @@ void mbedtls_ccm_star_auth_decrypt( int cipher_id,
     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 @@ void mbedtls_ccm_star_auth_decrypt( int cipher_id,
     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 afe24183a30f9a16b5b9322a779f5bcb0ff58fca..67c8de2ec1b68f3d31df939f74a86a4456719471 100755
--- a/tests/suites/test_suite_chacha20.function
+++ b/tests/suites/test_suite_chacha20.function
@@ -17,13 +17,6 @@ void chacha20_crypt( data_t *key_str,
     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 @@ void chacha20_crypt( data_t *key_str,
      */
     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 @@ void chacha20_crypt( data_t *key_str,
     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 @@ void chacha20_crypt( data_t *key_str,
     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 01050d92d01a21cad65eaf14f2338fcf870a0899..d6cf82865221b49c17d8b8ee777055c049c5bfc1 100644
--- a/tests/suites/test_suite_ctr_drbg.function
+++ b/tests/suites/test_suite_ctr_drbg.function
@@ -206,13 +206,16 @@ void ctr_drbg_entropy_usage(  )
     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 @@ void ctr_drbg_entropy_usage(  )
     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 b5acb7b0ff01f68578a0a505af91e46caa2f0b2b..5b249355b66903b64547b6fe5a9570c8f3b18184 100644
--- a/tests/suites/test_suite_des.function
+++ b/tests/suites/test_suite_des.function
@@ -15,8 +15,7 @@ void des_check_weak( data_t * key, int ret )
 /* 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 @@ void des_encrypt_ecb( data_t * key_str, data_t * src_str,
     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 @@ exit:
 /* 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 @@ void des_decrypt_ecb( data_t * key_str, data_t * src_str,
     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 @@ exit:
 
 /* 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 @@ void des_encrypt_cbc( data_t * key_str, data_t * iv_str,
     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 @@ exit:
 
 /* 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 @@ void des_decrypt_cbc( data_t * key_str, data_t * iv_str,
     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 @@ exit:
 
 /* 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 @@ void des3_encrypt_ecb( int key_count, data_t * key_str,
 
     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 @@ exit:
 
 /* 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 @@ void des3_decrypt_ecb( int key_count, data_t * key_str,
 
     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 @@ exit:
 /* 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 @@ void des3_encrypt_cbc( int key_count, data_t * key_str,
     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 @@ exit:
 /* 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 @@ void des3_decrypt_cbc( int key_count, data_t * key_str,
     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_dhm.data b/tests/suites/test_suite_dhm.data
index edebce087c2f06c367e116976cd21442af14dd18..c4795b6d345a4203b5a3696a2fa7d02965ba9962 100644
--- a/tests/suites/test_suite_dhm.data
+++ b/tests/suites/test_suite_dhm.data
@@ -22,10 +22,16 @@ dhm_do_dhm:10:"3":10:"5":MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED
 Diffie-Hellman zero modulus
 dhm_do_dhm:10:"0":10:"5":MBEDTLS_ERR_DHM_BAD_INPUT_DATA
 
-Diffie-Hellman load parameters from file
+Diffie-Hellman MPI_MAX_SIZE modulus
+dhm_make_public:MBEDTLS_MPI_MAX_SIZE:10:"5":0
+
+Diffie-Hellman MPI_MAX_SIZE + 1 modulus
+dhm_make_public:MBEDTLS_MPI_MAX_SIZE + 1:10:"5":MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED+MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
+Diffie-Hellman load parameters from file [#1]
 dhm_file:"data_files/dhparams.pem":"9e35f430443a09904f3a39a979797d070df53378e79c2438bef4e761f3c714553328589b041c809be1d6c6b5f1fc9f47d3a25443188253a992a56818b37ba9de5a40d362e56eff0be5417474c125c199272c8fe41dea733df6f662c92ae76556e755d10c64e6a50968f67fc6ea73d0dca8569be2ba204e23580d8bca2f4975b3":"02":128
 
-Diffie-Hellman load parameters from file
+Diffie-Hellman load parameters from file [#2]
 dhm_file:"data_files/dh.optlen.pem":"b3126aeaf47153c7d67f403030b292b5bd5a6c9eae1c137af34087fce2a36a578d70c5c560ad2bdb924c4a4dbee20a1671be7103ce87defa76908936803dbeca60c33e1289c1a03ac2c6c4e49405e5902fa0596a1cbaa895cc402d5213ed4a5f1f5ba8b5e1ed3da951a4c475afeb0ca660b7368c38c8e809f382d96ae19e60dc984e61cb42b5dfd723322acf327f9e413cda6400c15c5b2ea1fa34405d83982fba40e6d852da3d91019bf23511314254dc211a90833e5b1798ee52a78198c555644729ad92f060367c74ded37704adfc273a4a33fec821bd2ebd3bc051730e97a4dd14d2b766062592f5eec09d16bb50efebf2cc00dd3e0e3418e60ec84870f7":"800abfe7dc667aa17bcd7c04614bc221a65482ccc04b604602b0e131908a938ea11b48dc515dab7abcbb1e0c7fd66511edc0d86551b7632496e03df94357e1c4ea07a7ce1e381a2fcafdff5f5bf00df828806020e875c00926e4d011f88477a1b01927d73813cad4847c6396b9244621be2b00b63c659253318413443cd244215cd7fd4cbe796e82c6cf70f89cc0c528fb8e344809b31876e7ef739d5160d095c9684188b0c8755c7a468d47f56d6db9ea012924ecb0556fb71312a8d7c93bb2898ea08ee54eeb594548285f06a973cbbe2a0cb02e90f323fe045521f34c68354a6d3e95dbfff1eb64692edc0a44f3d3e408d0e479a541e779a6054259e2d854":256
 
 Diffie-Hellman selftest
diff --git a/tests/suites/test_suite_dhm.function b/tests/suites/test_suite_dhm.function
index 8a05a38dfbcec46c4c3216530b2574079375a1ee..6ec1e7e882d9d118d46f4cda4f7e4b56f02cddba 100644
--- a/tests/suites/test_suite_dhm.function
+++ b/tests/suites/test_suite_dhm.function
@@ -206,6 +206,36 @@ exit:
 }
 /* END_CASE */
 
+/* BEGIN_CASE */
+void dhm_make_public( int P_bytes, int radix_G, char *input_G, int result )
+{
+    mbedtls_mpi P, G;
+    mbedtls_dhm_context ctx;
+    unsigned char output[MBEDTLS_MPI_MAX_SIZE];
+
+    mbedtls_mpi_init( &P );
+    mbedtls_mpi_init( &G );
+    mbedtls_dhm_init( &ctx );
+
+    TEST_ASSERT( mbedtls_mpi_lset( &P, 1 ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_shift_l( &P, ( P_bytes * 8 ) - 1 ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_set_bit( &P, 0, 1 ) == 0 );
+
+    TEST_ASSERT( mbedtls_mpi_read_string( &G, radix_G, input_G ) == 0 );
+
+    TEST_ASSERT( mbedtls_dhm_set_group( &ctx, &P, &G ) == 0 );
+    TEST_ASSERT( mbedtls_dhm_make_public( &ctx, (int) mbedtls_mpi_size( &P ),
+                                          output, sizeof(output),
+                                          &rnd_pseudo_rand,
+                                          NULL ) == result );
+
+exit:
+    mbedtls_mpi_free( &P );
+    mbedtls_mpi_free( &G );
+    mbedtls_dhm_free( &ctx );
+}
+/* END_CASE */
+
 /* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
 void dhm_file( char * filename, char * p, char * g, int len )
 {
diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function
index 850b77cecda680d74f8766c56c12e70ea9c11262..e37a017a6f7bf96625e2326ecf11bddd95d1ed1b 100755
--- a/tests/suites/test_suite_ecp.function
+++ b/tests/suites/test_suite_ecp.function
@@ -756,7 +756,7 @@ void ecp_write_binary( int id, char * x, char * y, char * z, int format,
 
     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 5cff39984908c27b020a3cd07e669cab38397b1d..8ad8760e21c43146bf221674563928ee99766fb7 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 889d3bca7ebe99319f304002172c9db5c9617e9b..f4f9693fbdec8f80d75adabcb6ed34f575c6be1f 100755
--- a/tests/suites/test_suite_entropy.function
+++ b/tests/suites/test_suite_entropy.function
@@ -125,6 +125,28 @@ int read_nv_seed( unsigned char *buf, size_t buf_len )
  * 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 @@ void entropy_func_len( int len, int ret )
 
     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 1fcb681b98bf17193cddf06e41c598e893a6eff3..9b7b0ee14cc43190334507e046c565bf496b158b 100644
--- a/tests/suites/test_suite_gcm.function
+++ b/tests/suites/test_suite_gcm.function
@@ -35,8 +35,8 @@ exit:
 /* 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 @@ void gcm_encrypt_and_tag( int cipher_id, data_t * key_str,
     {
         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 @@ void gcm_decrypt_and_verify( int cipher_id, data_t * key_str,
         {
             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 ddd64fae4d8eafdd429b0d8896dce0d9e7700821..af871e1b331328c0bcc40933da895c0c816ac517 100755
--- a/tests/suites/test_suite_hkdf.function
+++ b/tests/suites/test_suite_hkdf.function
@@ -14,13 +14,6 @@ void test_hkdf( int md_alg, data_t *ikm, data_t *salt, data_t *info,
 {
     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 @@ void test_hkdf( int md_alg, data_t *ikm, data_t *salt, data_t *info,
                         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 @@ void test_hkdf_extract( int md_alg, char *hex_ikm_string,
     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 @@ void test_hkdf_expand( int md_alg, char *hex_info_string,
     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 13bc40062328ba62f640dfe8d65e4311f3698fa1..fbbb1bd212a03fad2a5a285a75d6ee0c9978464b 100644
--- a/tests/suites/test_suite_hmac_drbg.function
+++ b/tests/suites/test_suite_hmac_drbg.function
@@ -49,14 +49,17 @@ void hmac_drbg_entropy_usage( int md_alg )
     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 @@ void hmac_drbg_entropy_usage( int md_alg )
     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 @@ void hmac_drbg_no_reseed( int md_alg, data_t * entropy,
     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 11cf88ae7710f09ff2ce45be7e15eaa4d3f05dfa..d918ce3b960de74c4042b57710ec2578b18eeb96 100644
--- a/tests/suites/test_suite_md.function
+++ b/tests/suites/test_suite_md.function
@@ -127,7 +127,7 @@ void md_info( int md_type, char * md_name, int md_size )
 
 /* 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 @@ void md_text( char * text_md_name, char * text_src_string,
 
     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 @@ void md_hex( char * text_md_name, data_t * src_str,
     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 @@ void md_text_multi( char * text_md_name, char * text_src_string,
 
     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 @@ exit:
 /* 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 @@ void md_hex_multi( char * text_md_name, data_t * src_str,
 
     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 @@ exit:
 /* 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 @@ void mbedtls_md_hmac( char * text_md_name, int trunc_size,
 
     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 @@ void md_hmac_multi( char * text_md_name, int trunc_size, data_t * key_str,
     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 @@ void md_hmac_multi( char * text_md_name, int trunc_size, data_t * key_str,
     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 @@ exit:
 
 /* 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 @@ void mbedtls_md_file( char * text_md_name, char * filename,
 
     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 02004efa84b8fb217065110868d5c0a07b9ccb46..aa35c583eb463ce3b65b7c08c92630cd6a9ee7c2 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 @@ void md2_text( char * text_src_string, data_t * hex_hash_string )
     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 @@ void md4_text( char * text_src_string, data_t * hex_hash_string )
     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 @@ void md5_text( char * text_src_string, data_t * hex_hash_string )
     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 @@ void ripemd160_text( char * text_src_string, data_t * hex_hash_string )
     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 00926ff9710e3a24cdf8b6facba8c6cd9f9b3a41..5229253f6758d934e15104f2a1805420a0738ec1 100644
--- a/tests/suites/test_suite_mpi.data
+++ b/tests/suites/test_suite_mpi.data
@@ -433,12 +433,6 @@ mbedtls_mpi_add_abs:10:"-12345678":10:"-642531":10:"12988209"
 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 @@ mbedtls_mpi_add_int:10:"20395687835640197740576586692903457728019399331434826309
 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
 
@@ -679,16 +685,36 @@ mbedtls_mpi_exp_mod:10:"-23":10:"13":10:"29":10:"":10:"5":0
 Base test mbedtls_mpi_exp_mod #5 (Negative exponent)
 mbedtls_mpi_exp_mod:10:"23":10:"-13":10:"29":10:"":10:"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
 
-Base test mbedtls_mpi_exp_mod #7 (Negative base + exponent)
+Base test mbedtls_mpi_exp_mod #6 (Negative base + exponent)
 mbedtls_mpi_exp_mod:10:"-23":10:"-13":10:"29":10:"":10:"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
 
+Test mbedtls_mpi_exp_mod: MAX_SIZE exponent
+mbedtls_mpi_exp_mod_size:2:MBEDTLS_MPI_MAX_SIZE:10:10:"":0
+
+Test mbedtls_mpi_exp_mod: MAX_SIZE + 1 exponent
+mbedtls_mpi_exp_mod_size:2:MBEDTLS_MPI_MAX_SIZE + 1:10:10:"":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
+Test mbedtls_mpi_exp_mod: MAX_SIZE modulus
+mbedtls_mpi_exp_mod_size:2:2:MBEDTLS_MPI_MAX_SIZE:10:"":0
+
+Test mbedtls_mpi_exp_mod: MAX_SIZE + 1 modulus
+mbedtls_mpi_exp_mod_size:2:2:MBEDTLS_MPI_MAX_SIZE + 1:10:"":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
+Test mbedtls_mpi_exp_mod: MAX_SIZE exponent and modulus
+mbedtls_mpi_exp_mod_size:2:MBEDTLS_MPI_MAX_SIZE:MBEDTLS_MPI_MAX_SIZE:10:"":0
+
+Test mbedtls_mpi_exp_mod: MAX_SIZE + 1 exponent and modulus
+mbedtls_mpi_exp_mod_size:2:MBEDTLS_MPI_MAX_SIZE + 1:MBEDTLS_MPI_MAX_SIZE + 1:10:"":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
 Test mbedtls_mpi_exp_mod #1
+depends_on:MPI_MAX_BITS_LARGER_THAN_792
 mbedtls_mpi_exp_mod:10:"433019240910377478217373572959560109819648647016096560523769010881172869083338285573756574557395862965095016483867813043663981946477698466501451832407592327356331263124555137732393938242285782144928753919588632679050799198937132922145084847":10:"5781538327977828897150909166778407659250458379645823062042492461576758526757490910073628008613977550546382774775570888130029763571528699574717583228939535960234464230882573615930384979100379102915657483866755371559811718767760594919456971354184113721":10:"583137007797276923956891216216022144052044091311388601652961409557516421612874571554415606746479105795833145583959622117418531166391184939066520869800857530421873250114773204354963864729386957427276448683092491947566992077136553066273207777134303397724679138833126700957":10:"":10:"114597449276684355144920670007147953232659436380163461553186940113929777196018164149703566472936578890991049344459204199888254907113495794730452699842273939581048142004834330369483813876618772578869083248061616444392091693787039636316845512292127097865026290173004860736":0
 
 Test mbedtls_mpi_exp_mod (Negative base)
 mbedtls_mpi_exp_mod:10:"-10000000000":10:"10000000000":10:"99999":10:"":10:"1":0
 
-Test mbedtls_mpi_exp_mod (Negative base)
+Test mbedtls_mpi_exp_mod (Negative base) [#2]
+depends_on:MPI_MAX_BITS_LARGER_THAN_792
 mbedtls_mpi_exp_mod:16:"-9f13012cd92aa72fb86ac8879d2fde4f7fd661aaae43a00971f081cc60ca277059d5c37e89652e2af2585d281d66ef6a9d38a117e9608e9e7574cd142dc55278838a2161dd56db9470d4c1da2d5df15a908ee2eb886aaa890f23be16de59386663a12f1afbb325431a3e835e3fd89b98b96a6f77382f458ef9a37e1f84a03045c8676ab55291a94c2228ea15448ee96b626b998":16:"40a54d1b9e86789f06d9607fb158672d64867665c73ee9abb545fc7a785634b354c7bae5b962ce8040cf45f2c1f3d3659b2ee5ede17534c8fc2ec85c815e8df1fe7048d12c90ee31b88a68a081f17f0d8ce5f4030521e9400083bcea73a429031d4ca7949c2000d597088e0c39a6014d8bf962b73bb2e8083bd0390a4e00b9b3":16:"eeaf0ab9adb38dd69c33f80afa8fc5e86072618775ff3c0b9ea2314c9c256576d674df7496ea81d3383b4813d692c6e0e0d5d8e250b98be48e495c1d6089dad15dc7d7b46154d6b6ce8ef4ad69b15d4982559b297bcf1885c529f566660e57ec68edbc3c05726cc02fd4cbf4976eaa9afd5138fe8376435b9fc61d2fc0eb06e3":16:"":16:"21acc7199e1b90f9b4844ffe12c19f00ec548c5d32b21c647d48b6015d8eb9ec9db05b4f3d44db4227a2b5659c1a7cceb9d5fa8fa60376047953ce7397d90aaeb7465e14e820734f84aa52ad0fc66701bcbb991d57715806a11531268e1e83dd48288c72b424a6287e9ce4e5cc4db0dd67614aecc23b0124a5776d36e5c89483":0
 
 Base test GCD #1
@@ -929,6 +955,48 @@ mbedtls_mpi_set_bit:16:"00":32:1:16:"0100000000":0
 Test bit set (Invalid bit value)
 mbedtls_mpi_set_bit:16:"00":5:2:16:"00":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
 
+Fill random: 0 bytes
+mpi_fill_random:0:0:0
+
+Fill random: 1 byte, good
+mpi_fill_random:1:1:0
+
+Fill random: 2 bytes, good, no leading zero
+mpi_fill_random:2:2:0
+
+Fill random: 2 bytes, good, 1 leading zero
+mpi_fill_random:2:256:0
+
+Fill random: MAX_SIZE - 7, good
+mpi_fill_random:MBEDTLS_MPI_MAX_SIZE - 7:MBEDTLS_MPI_MAX_SIZE - 7:0
+
+Fill random: MAX_SIZE, good
+mpi_fill_random:MBEDTLS_MPI_MAX_SIZE:MBEDTLS_MPI_MAX_SIZE:0
+
+Fill random: 1 byte, RNG failure
+mpi_fill_random:1:0:MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
+
+Fill random: 2 bytes, RNG failure after 1 byte
+mpi_fill_random:2:1:MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
+
+Fill random: 4 bytes, RNG failure after 3 bytes
+mpi_fill_random:4:3:MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
+
+Fill random: 8 bytes, RNG failure after 7 bytes
+mpi_fill_random:8:7:MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
+
+Fill random: 16 bytes, RNG failure after 1 bytes
+mpi_fill_random:16:1:MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
+
+Fill random: 16 bytes, RNG failure after 8 bytes
+mpi_fill_random:16:8:MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
+
+Fill random: 16 bytes, RNG failure after 15 bytes
+mpi_fill_random:16:15:MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
+
+Fill random: MAX_SIZE bytes, RNG failure after MAX_SIZE-1 bytes
+mpi_fill_random:MBEDTLS_MPI_MAX_SIZE:MBEDTLS_MPI_MAX_SIZE-1:MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
+
 MPI Selftest
 depends_on:MBEDTLS_SELF_TEST
 mpi_selftest:
diff --git a/tests/suites/test_suite_mpi.function b/tests/suites/test_suite_mpi.function
index f2702f12b2148477c8af3217371a732365164653..2384d128b2666bfaf8b8e66e68b3af350100fb13 100644
--- a/tests/suites/test_suite_mpi.function
+++ b/tests/suites/test_suite_mpi.function
@@ -1,5 +1,10 @@
 /* BEGIN_HEADER */
 #include "mbedtls/bignum.h"
+#include "mbedtls/entropy.h"
+
+#if MBEDTLS_MPI_MAX_BITS > 792
+#define MPI_MAX_BITS_LARGER_THAN_792
+#endif
 
 typedef struct mbedtls_test_mpi_random
 {
@@ -43,6 +48,22 @@ int mbedtls_test_mpi_miller_rabin_determinizer( void* state,
 
     return( 0 );
 }
+
+/* Random generator that is told how many bytes to return. */
+static int f_rng_bytes_left( void *state, unsigned char *buf, size_t len )
+{
+    size_t *bytes_left = state;
+    size_t i;
+    for( i = 0; i < len; i++ )
+    {
+        if( *bytes_left == 0 )
+            return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
+        buf[i] = *bytes_left & 0xff;
+        --( *bytes_left );
+    }
+    return( 0 );
+}
+
 /* END_HEADER */
 
 /* BEGIN_DEPENDENCIES
@@ -354,7 +375,8 @@ void mbedtls_mpi_write_binary( int radix_X, char * input_X,
     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:
@@ -388,7 +410,8 @@ void mbedtls_mpi_read_file( int radix_X, char * input_file,
         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:
@@ -542,7 +565,7 @@ void mbedtls_mpi_lt_mpi_ct( int size_X, char * input_X,
                             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 );
@@ -775,6 +798,15 @@ void mbedtls_mpi_add_mpi( int radix_X, char * input_X, int radix_Y,
     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 );
 }
@@ -820,44 +852,17 @@ void mbedtls_mpi_add_abs( int radix_X, char * input_X, int radix_Y,
     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 */
 
@@ -891,6 +896,15 @@ void mbedtls_mpi_sub_mpi( int radix_X, char * input_X, int radix_Y,
     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 );
 }
@@ -914,6 +928,17 @@ void mbedtls_mpi_sub_abs( int radix_X, char * input_X, int radix_Y,
     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 );
 }
@@ -1110,6 +1135,40 @@ exit:
 }
 /* END_CASE */
 
+/* BEGIN_CASE */
+void mbedtls_mpi_exp_mod_size( int A_bytes, int E_bytes, int N_bytes,
+                               int radix_RR, char * input_RR, int exp_result )
+{
+    mbedtls_mpi A, E, N, RR, Z;
+    mbedtls_mpi_init( &A  ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N );
+    mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &Z );
+
+    /* Set A to 2^(A_bytes - 1) + 1 */
+    TEST_ASSERT( mbedtls_mpi_lset( &A, 1 ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_shift_l( &A, ( A_bytes * 8 ) - 1 ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_set_bit( &A, 0, 1 ) == 0 );
+
+    /* Set E to 2^(E_bytes - 1) + 1 */
+    TEST_ASSERT( mbedtls_mpi_lset( &E, 1 ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_shift_l( &E, ( E_bytes * 8 ) - 1 ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_set_bit( &E, 0, 1 ) == 0 );
+
+    /* Set N to 2^(N_bytes - 1) + 1 */
+    TEST_ASSERT( mbedtls_mpi_lset( &N, 1 ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_shift_l( &N, ( N_bytes * 8 ) - 1 ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_set_bit( &N, 0, 1 ) == 0 );
+
+    if( strlen( input_RR ) )
+        TEST_ASSERT( mbedtls_mpi_read_string( &RR, radix_RR, input_RR ) == 0 );
+
+    TEST_ASSERT( mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR ) == exp_result );
+
+exit:
+    mbedtls_mpi_free( &A  ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N );
+    mbedtls_mpi_free( &RR ); mbedtls_mpi_free( &Z );
+}
+/* END_CASE */
+
 /* BEGIN_CASE */
 void mbedtls_mpi_inv_mod( int radix_X, char * input_X, int radix_Y,
                           char * input_Y, int radix_A, char * input_A,
@@ -1251,6 +1310,37 @@ exit:
 }
 /* END_CASE */
 
+/* BEGIN_CASE */
+void mpi_fill_random( int wanted_bytes, int rng_bytes, int expected_ret )
+{
+    mbedtls_mpi X;
+    int ret;
+    size_t bytes_left = rng_bytes;
+    mbedtls_mpi_init( &X );
+
+    ret = mbedtls_mpi_fill_random( &X, wanted_bytes,
+                                   f_rng_bytes_left, &bytes_left );
+    TEST_ASSERT( ret == expected_ret );
+
+    if( expected_ret == 0 )
+    {
+        /* mbedtls_mpi_fill_random is documented to use bytes from the RNG
+         * as a big-endian representation of the number. We know when
+         * our RNG function returns null bytes, so we know how many
+         * leading zero bytes the number has. */
+        size_t leading_zeros = 0;
+        if( wanted_bytes > 0 && rng_bytes % 256 == 0 )
+            leading_zeros = 1;
+        TEST_ASSERT( mbedtls_mpi_size( &X ) + leading_zeros ==
+                     (size_t) wanted_bytes );
+        TEST_ASSERT( (int) bytes_left == rng_bytes - wanted_bytes );
+    }
+
+exit:
+    mbedtls_mpi_free( &X );
+}
+/* END_CASE */
+
 /* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
 void mpi_selftest(  )
 {
diff --git a/tests/suites/test_suite_pkcs1_v15.function b/tests/suites/test_suite_pkcs1_v15.function
index 08f590bc7d54a19be5bd4cb30f731ce9ffcabb6a..a1e11f7b4be1b03a5348322f647acdf8df1c0e59 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 @@ void pkcs1_rsaes_v15_encrypt( int mod, int radix_N, char * input_N,
     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 @@ exit:
 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 @@ void pkcs1_rsaes_v15_decrypt( int mod, int radix_P, char * input_P,
     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 @@ void pkcs1_rsassa_v15_sign( 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 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 @@ void pkcs1_rsassa_v15_sign( int mod, int radix_P, char * input_P, int radix_Q,
     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 3cd3903c3a68e03fd7741adc5fb9f5f38e9986bd..a4119a208a70f8bf72caf6e4b956b1b269876a15 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 @@ void pkcs1_rsaes_oaep_encrypt( int mod, int radix_N, char * input_N,
     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 @@ exit:
 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 @@ void pkcs1_rsaes_oaep_decrypt( int mod, int radix_P, char * input_P,
                                             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 @@ void pkcs1_rsassa_pss_sign( 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 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 @@ void pkcs1_rsassa_pss_sign( int mod, int radix_P, char * input_P, int radix_Q,
     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 26f1d33312e7ab8942a9514563b926b32b6684ee..a5252826b1745d73a049142437724ffdddee85aa 100644
--- a/tests/suites/test_suite_pkcs5.function
+++ b/tests/suites/test_suite_pkcs5.function
@@ -24,7 +24,8 @@ void pbkdf2_hmac( int hash, data_t * pw_str, data_t * salt_str,
     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 43c275ef255c36da6ba1a57490474a012c256248..2bad4ed1370ad7274d30921f748cb26da5fa1bbc 100644
--- a/tests/suites/test_suite_pkwrite.function
+++ b/tests/suites/test_suite_pkwrite.function
@@ -17,7 +17,7 @@ void pk_write_pubkey_check( char * key_file )
     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 @@ void pk_write_pubkey_check( char * key_file )
     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 @@ void pk_write_key_check( char * key_file )
     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 @@ void pk_write_key_check( char * key_file )
     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 44617d98ef9455f05d2ae8677d9f9ada1f5d5e6e..4b8995b6099f78b7fd288770762e40169406f912 100755
--- 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 @@ void mbedtls_poly1305( data_t *key, char *hex_mac_string, data_t *src_str )
     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 @@ void mbedtls_poly1305( data_t *key, char *hex_mac_string, data_t *src_str )
 
     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 @@ void mbedtls_poly1305( data_t *key, char *hex_mac_string, data_t *src_str )
 
         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 @@ void mbedtls_poly1305( data_t *key, char *hex_mac_string, data_t *src_str )
 
         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 5e4de17e2b5a9ac6ed88a474c40b6ccc21d4e0e9..4ed833903cbe91119352d284a3b7c6b0cc22f9bf 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 9a3b5837cad4255b49a08a44617370fbf46f94fd..89b419fbda28540ff3cac99e6fb716b058546de7 100755
--- a/tests/suites/test_suite_rsa.function
+++ b/tests/suites/test_suite_rsa.function
@@ -465,12 +465,35 @@ exit:
 }
 /* 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 @@ void mbedtls_rsa_pkcs1_sign( data_t * message_str, int padding_mode,
     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 @@ void rsa_pkcs1_sign_raw( data_t * hash_result,
                          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 @@ void rsa_pkcs1_sign_raw( data_t * hash_result,
                                          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 @@ void rsa_pkcs1_sign_raw( data_t * hash_result,
 
         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 @@ exit:
 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 @@ void mbedtls_rsa_pkcs1_encrypt( data_t * message_str, int padding_mode,
     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 @@ exit:
 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 @@ void rsa_pkcs1_encrypt_bad_rng( data_t * message_str, int padding_mode,
     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 @@ void mbedtls_rsa_pkcs1_decrypt( data_t * message_str, 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,
-                                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 @@ void mbedtls_rsa_pkcs1_decrypt( data_t * message_str, int padding_mode,
     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 @@ exit:
 /* 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 @@ void mbedtls_rsa_public( data_t * message_str, int mod, int radix_N,
     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 @@ void mbedtls_rsa_public( data_t * message_str, int mod, int radix_N,
     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 @@ exit:
 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 @@ void mbedtls_rsa_private( data_t * message_str, int mod, int radix_P,
         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 @@ void mbedtls_rsa_private( data_t * message_str, int mod, int radix_P,
     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 e621f49cdbaee6551cb1f7488dce0780a75458bc..f3477ec78eca9a345fc5558ce4d4eb7c91e49ff4 100644
--- a/tests/suites/test_suite_shax.function
+++ b/tests/suites/test_suite_shax.function
@@ -52,7 +52,7 @@ exit:
 /* 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 @@ void mbedtls_sha1( data_t * src_str, data_t * hex_hash_string )
 
     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 @@ exit:
 /* 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 @@ void sha224( data_t * src_str, data_t * hex_hash_string )
 
     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 @@ void mbedtls_sha256( data_t * src_str, data_t * hex_hash_string )
 
     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 @@ exit:
 /* 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 @@ void sha384( data_t * src_str, data_t * hex_hash_string )
 
     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 @@ void mbedtls_sha512( data_t * src_str, data_t * hex_hash_string )
 
     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 cc907b6841b124f7401d6b01a0582940bfa7057f..66ee453f4cb3ce765091164a5b989e944dcadbe8 100755
--- 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.8"
+check_compiletime_version:"2.16.10"
 
 Check runtime library version
-check_runtime_version:"2.16.8"
+check_runtime_version:"2.16.10"
 
 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 fe844746894e3a5e9e5d269c04cb011600b22dbf..2d1aecacc5e746a43a285abafcd0938408e1f43e 100755
--- a/tests/suites/test_suite_x509parse.data
+++ b/tests/suites/test_suite_x509parse.data
@@ -1884,6 +1884,10 @@ X509 File parse (trailing spaces, OK)
 depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_RSA_C
 x509parse_crt_file:"data_files/server7_trailing_space.crt":0
 
+X509 File parse (Algorithm Params Tag mismatch)
+depends_on:MBEDTLS_SHA256_C:MBEDTLS_RSA_C
+x509parse_crt_file:"data_files/cli-rsa-sha256-badalg.crt.der":MBEDTLS_ERR_X509_SIG_MISMATCH
+
 X509 Get time (UTC no issues)
 depends_on:MBEDTLS_X509_USE_C
 x509_get_time:MBEDTLS_ASN1_UTC_TIME:"500101000000Z":0:1950:1:1:0:0:0
diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function
index e6b1b4783cdeed85c07cbaeba2944d8f968c551c..664aac7db4190a8aa170b17abc1bec9559628bce 100644
--- a/tests/suites/test_suite_x509parse.function
+++ b/tests/suites/test_suite_x509parse.function
@@ -804,21 +804,21 @@ void x509_get_time( int tag, char * time_str, int ret, int year, int mon,
 /* 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( ¶ms, &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 535807e3a289cad10e99af6ff603be175ad711db..40bccd69dacda494858ef64ff24809bc50ec1630 100644
--- a/tests/suites/test_suite_x509write.function
+++ b/tests/suites/test_suite_x509write.function
@@ -45,7 +45,7 @@ void x509_csr_check( char * key_file, char * cert_req_check_file, int md_type,
     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 @@ void x509_csr_check( char * key_file, char * cert_req_check_file, int md_type,
 
     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 @@ void x509_crt_check( char *subject_key_file, char *subject_pwd,
     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 @@ void x509_crt_check( char *subject_key_file, char *subject_pwd,
 
     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 a24a4206570c449def931fff4f26db3ae9760a5d..1d5b29b8ab2b3dcc6fb7c9c031610087d5afc7b5 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 @@ void xtea_encrypt_ecb( data_t * key_str, data_t * src_str,
     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 @@ void xtea_decrypt_ecb( data_t * key_str, data_t * src_str,
     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 @@ void xtea_encrypt_cbc( data_t * key_str, data_t * iv_str,
     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 @@ void xtea_decrypt_cbc( data_t * key_str, data_t * iv_str,
     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 */