Merge pull request #4044 from darrenkrahn/mbedtls-2.16

[Backport 2.16] Mark basic constraints critical as appropriate.
diff --git a/.gitignore b/.gitignore
index 5fb0bde..4837ebb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,6 +18,7 @@
 Coverage
 *.gcno
 *.gcda
+coverage-summary.txt
 
 # generated by scripts/memory.sh
 massif-*
diff --git a/.travis.yml b/.travis.yml
index 8789c44..0e85185 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -14,6 +14,8 @@
           - graphviz
           - gcc-arm-none-eabi
           - libnewlib-arm-none-eabi
+          - gcc-arm-linux-gnueabi
+          - libc6-dev-armel-cross
       language: python # Needed to get pip for Python 3
       python: 3.5 # version from Ubuntu 16.04
       install:
@@ -21,8 +23,8 @@
       script:
         - tests/scripts/all.sh -k 'check_*'
         - tests/scripts/all.sh -k test_default_out_of_box
-        - tests/scripts/test-ref-configs.pl
-        - tests/scripts/all.sh -k build_arm_none_eabi_gcc_arm5vte build_arm_none_eabi_gcc_m0plus
+        - tests/scripts/all.sh -k test_ref_configs
+        - tests/scripts/all.sh -k build_arm_linux_gnueabi_gcc_arm5vte build_arm_none_eabi_gcc_m0plus
 
     - name: full configuration
       script:
@@ -32,12 +34,6 @@
       script:
         - tests/scripts/all.sh -k 'test_depends_*' 'build_key_exchanges'
 
-    - name: macOS
-      os: osx
-      compiler: clang
-      script:
-        - tests/scripts/all.sh -k test_default_out_of_box
-
     - name: Windows
       os: windows
       script:
diff --git a/ChangeLog b/ChangeLog
index 1ecfc8b..47e2b5a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,144 @@
 mbed TLS ChangeLog (Sorted per branch, date)
 
+= mbed TLS 2.16.11 branch released 2021-07-07
+
+Security
+   * Fix a bias in the generation of finite-field Diffie-Hellman-Merkle (DHM)
+     private keys and of blinding values for DHM and elliptic curves (ECP)
+     computations. Reported by FlorianF89 in #4245.
+   * Fix a potential side channel vulnerability in ECDSA ephemeral key generation.
+     An adversary who is capable of very precise timing measurements could
+     learn partial information about the leading bits of the nonce used for the
+     signature, allowing the recovery of the private key after observing a
+     large number of signature operations. This completes a partial fix in
+     Mbed TLS 2.16.4.
+   * It was possible to configure MBEDTLS_ECP_MAX_BITS to a value that is
+     too small, leading to buffer overflows in ECC operations. Fail the build
+     in such a case.
+   * An adversary with access to precise enough information about memory
+     accesses (typically, an untrusted operating system attacking a secure
+     enclave) could recover an RSA private key after observing the victim
+     performing a single private-key operation. Found and reported by
+     Zili KOU, Wenjian HE, Sharad Sinha, and Wei ZHANG.
+   * An adversary with access to precise enough timing information (typically, a
+     co-located process) could recover a Curve25519 or Curve448 static ECDH key
+     after inputting a chosen public key and observing the victim performing the
+     corresponding private-key operation. Found and reported by Leila Batina,
+     Lukas Chmielewski, Björn Haase, Niels Samwel and Peter Schwabe.
+
+Bugfix
+   * Fix premature fopen() call in mbedtls_entropy_write_seed_file which may
+     lead to the seed file corruption in case if the path to the seed file is
+     equal to MBEDTLS_PLATFORM_STD_NV_SEED_FILE. Contributed by Victor
+     Krasnoshchok in #3616.
+   * Fix some cases in the bignum module where the library constructed an
+     unintended representation of the value 0 which was not processed
+     correctly by some bignum operations. This could happen when
+     mbedtls_mpi_read_string() was called on "-0", or when
+     mbedtls_mpi_mul_mpi() and mbedtls_mpi_mul_int() was called with one of
+     the arguments being negative and the other being 0. Fixes #4643.
+   * Fix a compilation error when MBEDTLS_ECP_RANDOMIZE_MXZ_ALT is
+     defined. Fixes #4217.
+   * Fix an incorrect error code when parsing a PKCS#8 private key.
+   * In a TLS client, enforce the Diffie-Hellman minimum parameter size
+     set with mbedtls_ssl_conf_dhm_min_bitlen() precisely. Before, the
+     minimum size was rounded down to the nearest multiple of 8.
+   * In library/net_sockets.c, _POSIX_C_SOURCE and _XOPEN_SOURCE are
+     defined to specific values.  If the code is used in a context
+     where these are already defined, this can result in a compilation
+     error.  Instead, assume that if they are defined, the values will
+     be adequate to build Mbed TLS.
+   * The cipher suite TLS-RSA-WITH-CAMELLIA-256-GCM-SHA384 was not available
+     when SHA-1 was disabled and was offered when SHA-1 was enabled but SHA-384
+     was disabled. Fix the dependency. Fixes #4472.
+   * Fix test suite code on platforms where int32_t is not int, such as
+     Arm Cortex-M. Fixes #4530.
+   * Fix some issues affecting MBEDTLS_ARIA_ALT implementations: a misplaced
+     directive in a header and a missing initialization in the self-test.
+   * Fix a missing initialization in the Camellia self-test, affecting
+     MBEDTLS_CAMELLIA_ALT implementations.
+   * Fix a regression introduced in 2.16.8 which broke (D)TLS CBC ciphersuites
+     (when the encrypt-then-MAC extension is not in use) with some ALT
+     implementations of the underlying hash (SHA-1, SHA-256, SHA-384), causing
+     the affected side to wrongly reject valid messages. Fixes #4118.
+   * Fix mbedtls_net_poll() and mbedtls_net_recv_timeout() often failing with
+     MBEDTLS_ERR_NET_POLL_FAILED on Windows. Fixes #4465.
+   * Fix a resource leak in a test suite with an alternative AES
+     implementation. Fixes #4176.
+   * Fix a crash in mbedtls_mpi_debug_mpi on a bignum having 0 limbs.
+     Reported by lhuang04 in #4578. Fixes #4608.
+   * Fix a null pointer dereference when mbedtls_mpi_exp_mod() was called with
+     A=0 represented with 0 limbs. This bug could not be triggered by code
+     that constructed A with one of the mbedtls_mpi_read_xxx functions
+     (including in particular TLS code) since those always built an mpi object
+     with at least one limb. Credit to OSS-Fuzz. Fixes #4641.
+   * Fix mbedtls_mpi_gcd(G,A,B) when the value of B is zero. This had no
+     effect on Mbed TLS's internal use of mbedtls_mpi_gcd(), but may affect
+     applications that call mbedtls_mpi_gcd() directly. Fixes #4642.
+   * mbedtls_pk_sign() and mbedtls_pk_verify() and their extended and
+     restartable variants now require at least the specified hash length if
+     nonzero. Before, for RSA, hash_len was ignored in favor of the length of
+     the specified hash algorithm.
+   * Fix which alert is sent in some cases to conform to the
+     applicable RFC: on an invalid Finished message value, an
+     invalid max_fragment_length extension, or an
+     unsupported extension used by the server.
+
+Changes
+   * Fix the setting of the read timeout in the DTLS sample programs.
+   * Remove the AES sample application programs/aes/aescrypt2 which shows
+     bad cryptographic practice. Fix #1906.
+   * When building the test suites with GNU make, invoke python3 or python, not
+     python2. The build still works with either Python 2.7 or 3.5+, but we
+     recommend using a version of Python that is supported upstream.
+
+= 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
diff --git a/ChangeLog.d/issue4630.txt b/ChangeLog.d/issue4630.txt
new file mode 100644
index 0000000..0bc4b99
--- /dev/null
+++ b/ChangeLog.d/issue4630.txt
@@ -0,0 +1,2 @@
+Bugfix
+   * Stop using reserved identifiers as local variables. Fixes #4630.
diff --git a/ChangeLog.d/makefile-python-windows.txt b/ChangeLog.d/makefile-python-windows.txt
new file mode 100644
index 0000000..57ccc1a
--- /dev/null
+++ b/ChangeLog.d/makefile-python-windows.txt
@@ -0,0 +1,4 @@
+Bugfix
+   * The GNU makefiles invoke python3 in preference to python except on Windows.
+     The check was accidentally not performed when cross-compiling for Windows
+     on Linux. Fix this. Fixes #4774.
diff --git a/ChangeLog.d/rsa_private-ret.txt b/ChangeLog.d/rsa_private-ret.txt
deleted file mode 100644
index b965cea..0000000
--- a/ChangeLog.d/rsa_private-ret.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Bugfix
-   * Fix an incorrect error code if an RSA private operation glitched.
diff --git a/Makefile b/Makefile
index 3942fbd..ffa3aa0 100644
--- a/Makefile
+++ b/Makefile
@@ -124,11 +124,11 @@
 ## Editor navigation files
 C_SOURCE_FILES = $(wildcard include/*/*.h library/*.[hc] programs/*/*.[hc] tests/suites/*.function)
 # Exuberant-ctags invocation. Other ctags implementations may require different options.
-CTAGS = ctags --langmap=c:+.h.function -o
+CTAGS = ctags --langmap=c:+.h.function --line-directives=no -o
 tags: $(C_SOURCE_FILES)
 	$(CTAGS) $@ $(C_SOURCE_FILES)
 TAGS: $(C_SOURCE_FILES)
-	etags -o $@ $(C_SOURCE_FILES)
+	etags --no-line-directive -o $@ $(C_SOURCE_FILES)
 global: GPATH GRTAGS GSYMS GTAGS
 GPATH GRTAGS GSYMS GTAGS: $(C_SOURCE_FILES)
 	ls $(C_SOURCE_FILES) | gtags -f - --gtagsconf .globalrc
diff --git a/doxygen/input/doc_mainpage.h b/doxygen/input/doc_mainpage.h
index 4fe1613..ff3af46 100644
--- a/doxygen/input/doc_mainpage.h
+++ b/doxygen/input/doc_mainpage.h
@@ -49,7 +49,7 @@
  */
 
 /**
- * @mainpage mbed TLS v2.16.9 source code documentation
+ * @mainpage mbed TLS v2.16.11 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 9197a4a..43b9b7b 100644
--- a/doxygen/mbedtls.doxyfile
+++ b/doxygen/mbedtls.doxyfile
@@ -28,7 +28,7 @@
 # identify the project. Note that if you do not use Doxywizard you need
 # to put quotes around the project name if it contains spaces.
 
-PROJECT_NAME           = "mbed TLS v2.16.9"
+PROJECT_NAME           = "mbed TLS v2.16.11"
 
 # 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/aes.h b/include/mbedtls/aes.h
index 4468b66..33a11a7 100644
--- a/include/mbedtls/aes.h
+++ b/include/mbedtls/aes.h
@@ -81,17 +81,22 @@
 #define MBEDTLS_AES_DECRYPT     0 /**< AES decryption. */
 
 /* Error codes in range 0x0020-0x0022 */
-#define MBEDTLS_ERR_AES_INVALID_KEY_LENGTH                -0x0020  /**< Invalid key length. */
-#define MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH              -0x0022  /**< Invalid data input length. */
+/** Invalid key length. */
+#define MBEDTLS_ERR_AES_INVALID_KEY_LENGTH                -0x0020
+/** Invalid data input length. */
+#define MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH              -0x0022
 
 /* Error codes in range 0x0021-0x0025 */
-#define MBEDTLS_ERR_AES_BAD_INPUT_DATA                    -0x0021  /**< Invalid input data. */
+/** Invalid input data. */
+#define MBEDTLS_ERR_AES_BAD_INPUT_DATA                    -0x0021
 
 /* MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE is deprecated and should not be used. */
-#define MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE               -0x0023  /**< Feature not available. For example, an unsupported AES key size. */
+/** Feature not available. For example, an unsupported AES key size. */
+#define MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE               -0x0023
 
 /* MBEDTLS_ERR_AES_HW_ACCEL_FAILED is deprecated and should not be used. */
-#define MBEDTLS_ERR_AES_HW_ACCEL_FAILED                   -0x0025  /**< AES hardware accelerator failed. */
+/** AES hardware accelerator failed. */
+#define MBEDTLS_ERR_AES_HW_ACCEL_FAILED                   -0x0025
 
 #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
     !defined(inline) && !defined(__cplusplus)
diff --git a/include/mbedtls/arc4.h b/include/mbedtls/arc4.h
index 6334a9c..cfe3aea 100644
--- a/include/mbedtls/arc4.h
+++ b/include/mbedtls/arc4.h
@@ -62,7 +62,8 @@
 #include <stddef.h>
 
 /* MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED is deprecated and should not be used. */
-#define MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED                  -0x0019  /**< ARC4 hardware accelerator failed. */
+/** ARC4 hardware accelerator failed. */
+#define MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED                  -0x0019
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/mbedtls/aria.h b/include/mbedtls/aria.h
index 13763d4..50bbc82 100644
--- a/include/mbedtls/aria.h
+++ b/include/mbedtls/aria.h
@@ -77,25 +77,29 @@
 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
 #define MBEDTLS_ERR_ARIA_INVALID_KEY_LENGTH   MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( -0x005C )
 #endif /* !MBEDTLS_DEPRECATED_REMOVED */
-#define MBEDTLS_ERR_ARIA_BAD_INPUT_DATA -0x005C /**< Bad input data. */
+/** Bad input data. */
+#define MBEDTLS_ERR_ARIA_BAD_INPUT_DATA -0x005C
 
-#define MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH -0x005E /**< Invalid data input length. */
+/** Invalid data input length. */
+#define MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH -0x005E
 
 /* MBEDTLS_ERR_ARIA_FEATURE_UNAVAILABLE is deprecated and should not be used.
  */
-#define MBEDTLS_ERR_ARIA_FEATURE_UNAVAILABLE  -0x005A  /**< Feature not available. For example, an unsupported ARIA key size. */
+/** Feature not available. For example, an unsupported ARIA key size. */
+#define MBEDTLS_ERR_ARIA_FEATURE_UNAVAILABLE  -0x005A
 
 /* MBEDTLS_ERR_ARIA_HW_ACCEL_FAILED is deprecated and should not be used. */
-#define MBEDTLS_ERR_ARIA_HW_ACCEL_FAILED      -0x0058  /**< ARIA hardware accelerator failed. */
-
-#if !defined(MBEDTLS_ARIA_ALT)
-// Regular implementation
-//
+/** ARIA hardware accelerator failed. */
+#define MBEDTLS_ERR_ARIA_HW_ACCEL_FAILED      -0x0058
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if !defined(MBEDTLS_ARIA_ALT)
+// Regular implementation
+//
+
 /**
  * \brief The ARIA context-type definition.
  */
diff --git a/include/mbedtls/asn1.h b/include/mbedtls/asn1.h
index 0e596bc..1fa7bfa 100644
--- a/include/mbedtls/asn1.h
+++ b/include/mbedtls/asn1.h
@@ -73,13 +73,20 @@
  * ASN1 is a standard to specify data structures.
  * \{
  */
-#define MBEDTLS_ERR_ASN1_OUT_OF_DATA                      -0x0060  /**< Out of data when parsing an ASN1 data structure. */
-#define MBEDTLS_ERR_ASN1_UNEXPECTED_TAG                   -0x0062  /**< ASN1 tag was of an unexpected value. */
-#define MBEDTLS_ERR_ASN1_INVALID_LENGTH                   -0x0064  /**< Error when trying to determine the length or invalid length. */
-#define MBEDTLS_ERR_ASN1_LENGTH_MISMATCH                  -0x0066  /**< Actual length differs from expected length. */
-#define MBEDTLS_ERR_ASN1_INVALID_DATA                     -0x0068  /**< Data is invalid. (not used) */
-#define MBEDTLS_ERR_ASN1_ALLOC_FAILED                     -0x006A  /**< Memory allocation failed */
-#define MBEDTLS_ERR_ASN1_BUF_TOO_SMALL                    -0x006C  /**< Buffer too small when writing ASN.1 data structure. */
+/** Out of data when parsing an ASN1 data structure. */
+#define MBEDTLS_ERR_ASN1_OUT_OF_DATA                      -0x0060
+/** ASN1 tag was of an unexpected value. */
+#define MBEDTLS_ERR_ASN1_UNEXPECTED_TAG                   -0x0062
+/** Error when trying to determine the length or invalid length. */
+#define MBEDTLS_ERR_ASN1_INVALID_LENGTH                   -0x0064
+/** Actual length differs from expected length. */
+#define MBEDTLS_ERR_ASN1_LENGTH_MISMATCH                  -0x0066
+/** Data is invalid. (not used) */
+#define MBEDTLS_ERR_ASN1_INVALID_DATA                     -0x0068
+/** Memory allocation failed */
+#define MBEDTLS_ERR_ASN1_ALLOC_FAILED                     -0x006A
+/** Buffer too small when writing ASN.1 data structure. */
+#define MBEDTLS_ERR_ASN1_BUF_TOO_SMALL                    -0x006C
 
 /* \} name */
 
diff --git a/include/mbedtls/base64.h b/include/mbedtls/base64.h
index cbed688..eaada6e 100644
--- a/include/mbedtls/base64.h
+++ b/include/mbedtls/base64.h
@@ -57,8 +57,10 @@
 
 #include <stddef.h>
 
-#define MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL               -0x002A  /**< Output buffer too small. */
-#define MBEDTLS_ERR_BASE64_INVALID_CHARACTER              -0x002C  /**< Invalid character in input. */
+/** Output buffer too small. */
+#define MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL               -0x002A
+/** Invalid character in input. */
+#define MBEDTLS_ERR_BASE64_INVALID_CHARACTER              -0x002C
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/mbedtls/bignum.h b/include/mbedtls/bignum.h
index 4d04b33..f7b86cb 100644
--- a/include/mbedtls/bignum.h
+++ b/include/mbedtls/bignum.h
@@ -62,14 +62,22 @@
 #include <stdio.h>
 #endif
 
-#define MBEDTLS_ERR_MPI_FILE_IO_ERROR                     -0x0002  /**< An error occurred while reading from or writing to a file. */
-#define MBEDTLS_ERR_MPI_BAD_INPUT_DATA                    -0x0004  /**< Bad input parameters to function. */
-#define MBEDTLS_ERR_MPI_INVALID_CHARACTER                 -0x0006  /**< There is an invalid character in the digit string. */
-#define MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL                  -0x0008  /**< The buffer is too small to write to. */
-#define MBEDTLS_ERR_MPI_NEGATIVE_VALUE                    -0x000A  /**< The input arguments are negative or result in illegal output. */
-#define MBEDTLS_ERR_MPI_DIVISION_BY_ZERO                  -0x000C  /**< The input argument for division is zero, which is not allowed. */
-#define MBEDTLS_ERR_MPI_NOT_ACCEPTABLE                    -0x000E  /**< The input arguments are not acceptable. */
-#define MBEDTLS_ERR_MPI_ALLOC_FAILED                      -0x0010  /**< Memory allocation failed. */
+/** An error occurred while reading from or writing to a file. */
+#define MBEDTLS_ERR_MPI_FILE_IO_ERROR                     -0x0002
+/** Bad input parameters to function. */
+#define MBEDTLS_ERR_MPI_BAD_INPUT_DATA                    -0x0004
+/** There is an invalid character in the digit string. */
+#define MBEDTLS_ERR_MPI_INVALID_CHARACTER                 -0x0006
+/** The buffer is too small to write to. */
+#define MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL                  -0x0008
+/** The input arguments are negative or result in illegal output. */
+#define MBEDTLS_ERR_MPI_NEGATIVE_VALUE                    -0x000A
+/** The input argument for division is zero, which is not allowed. */
+#define MBEDTLS_ERR_MPI_DIVISION_BY_ZERO                  -0x000C
+/** The input arguments are not acceptable. */
+#define MBEDTLS_ERR_MPI_NOT_ACCEPTABLE                    -0x000E
+/** Memory allocation failed. */
+#define MBEDTLS_ERR_MPI_ALLOC_FAILED                      -0x0010
 
 #define MBEDTLS_MPI_CHK(f)       \
     do                           \
@@ -821,14 +829,14 @@
  * \param E        The exponent MPI. This must point to an initialized MPI.
  * \param N        The base for the modular reduction. This must point to an
  *                 initialized MPI.
- * \param _RR      A helper MPI depending solely on \p N which can be used to
+ * \param prec_RR  A helper MPI depending solely on \p N which can be used to
  *                 speed-up multiple modular exponentiations for the same value
  *                 of \p N. This may be \c NULL. If it is not \c NULL, it must
  *                 point to an initialized MPI. If it hasn't been used after
  *                 the call to mbedtls_mpi_init(), this function will compute
- *                 the helper value and store it in \p _RR for reuse on
+ *                 the helper value and store it in \p prec_RR for reuse on
  *                 subsequent calls to this function. Otherwise, the function
- *                 will assume that \p _RR holds the helper value set by a
+ *                 will assume that \p prec_RR holds the helper value set by a
  *                 previous call to mbedtls_mpi_exp_mod(), and reuse it.
  *
  * \return         \c 0 if successful.
@@ -840,7 +848,7 @@
  */
 int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
                          const mbedtls_mpi *E, const mbedtls_mpi *N,
-                         mbedtls_mpi *_RR );
+                         mbedtls_mpi *prec_RR );
 
 /**
  * \brief          Fill an MPI with a number of random bytes.
diff --git a/include/mbedtls/blowfish.h b/include/mbedtls/blowfish.h
index 945bd42..86f7ce7 100644
--- a/include/mbedtls/blowfish.h
+++ b/include/mbedtls/blowfish.h
@@ -70,13 +70,16 @@
 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
 #define MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH   MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( -0x0016 )
 #endif /* !MBEDTLS_DEPRECATED_REMOVED */
-#define MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA -0x0016 /**< Bad input data. */
+/** Bad input data. */
+#define MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA -0x0016
 
-#define MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH -0x0018 /**< Invalid data input length. */
+/** Invalid data input length. */
+#define MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH -0x0018
 
 /* MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED is deprecated and should not be used.
  */
-#define MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED                   -0x0017  /**< Blowfish hardware accelerator failed. */
+/** Blowfish hardware accelerator failed. */
+#define MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED                   -0x0017
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/mbedtls/bn_mul.h b/include/mbedtls/bn_mul.h
index 9615090..6f1201b 100644
--- a/include/mbedtls/bn_mul.h
+++ b/include/mbedtls/bn_mul.h
@@ -71,6 +71,46 @@
 
 #include "bignum.h"
 
+
+/*
+ * Conversion macros for embedded constants:
+ * build lists of mbedtls_mpi_uint's from lists of unsigned char's grouped by 8, 4 or 2
+ */
+#if defined(MBEDTLS_HAVE_INT32)
+
+#define MBEDTLS_BYTES_TO_T_UINT_4( a, b, c, d )               \
+    ( (mbedtls_mpi_uint) (a) <<  0 ) |                        \
+    ( (mbedtls_mpi_uint) (b) <<  8 ) |                        \
+    ( (mbedtls_mpi_uint) (c) << 16 ) |                        \
+    ( (mbedtls_mpi_uint) (d) << 24 )
+
+#define MBEDTLS_BYTES_TO_T_UINT_2( a, b )                   \
+    MBEDTLS_BYTES_TO_T_UINT_4( a, b, 0, 0 )
+
+#define MBEDTLS_BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \
+    MBEDTLS_BYTES_TO_T_UINT_4( a, b, c, d ),                \
+    MBEDTLS_BYTES_TO_T_UINT_4( e, f, g, h )
+
+#else /* 64-bits */
+
+#define MBEDTLS_BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h )   \
+    ( (mbedtls_mpi_uint) (a) <<  0 ) |                        \
+    ( (mbedtls_mpi_uint) (b) <<  8 ) |                        \
+    ( (mbedtls_mpi_uint) (c) << 16 ) |                        \
+    ( (mbedtls_mpi_uint) (d) << 24 ) |                        \
+    ( (mbedtls_mpi_uint) (e) << 32 ) |                        \
+    ( (mbedtls_mpi_uint) (f) << 40 ) |                        \
+    ( (mbedtls_mpi_uint) (g) << 48 ) |                        \
+    ( (mbedtls_mpi_uint) (h) << 56 )
+
+#define MBEDTLS_BYTES_TO_T_UINT_4( a, b, c, d )             \
+    MBEDTLS_BYTES_TO_T_UINT_8( a, b, c, d, 0, 0, 0, 0 )
+
+#define MBEDTLS_BYTES_TO_T_UINT_2( a, b )                   \
+    MBEDTLS_BYTES_TO_T_UINT_8( a, b, 0, 0, 0, 0, 0, 0 )
+
+#endif /* bits in mbedtls_mpi_uint */
+
 #if defined(MBEDTLS_HAVE_ASM)
 
 #ifndef asm
diff --git a/include/mbedtls/camellia.h b/include/mbedtls/camellia.h
index 3887128..fe5ac37 100644
--- a/include/mbedtls/camellia.h
+++ b/include/mbedtls/camellia.h
@@ -66,13 +66,16 @@
 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
 #define MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH   MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( -0x0024 )
 #endif /* !MBEDTLS_DEPRECATED_REMOVED */
-#define MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA -0x0024 /**< Bad input data. */
+/** Bad input data. */
+#define MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA -0x0024
 
-#define MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH -0x0026 /**< Invalid data input length. */
+/** Invalid data input length. */
+#define MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH -0x0026
 
 /* MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED is deprecated and should not be used.
  */
-#define MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED              -0x0027  /**< Camellia hardware accelerator failed. */
+/** Camellia hardware accelerator failed. */
+#define MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED              -0x0027
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/mbedtls/ccm.h b/include/mbedtls/ccm.h
index d50c6ec..78c0ea4 100644
--- a/include/mbedtls/ccm.h
+++ b/include/mbedtls/ccm.h
@@ -82,11 +82,14 @@
 
 #include "cipher.h"
 
-#define MBEDTLS_ERR_CCM_BAD_INPUT       -0x000D /**< Bad input parameters to the function. */
-#define MBEDTLS_ERR_CCM_AUTH_FAILED     -0x000F /**< Authenticated decryption failed. */
+/** Bad input parameters to the function. */
+#define MBEDTLS_ERR_CCM_BAD_INPUT       -0x000D
+/** Authenticated decryption failed. */
+#define MBEDTLS_ERR_CCM_AUTH_FAILED     -0x000F
 
 /* MBEDTLS_ERR_CCM_HW_ACCEL_FAILED is deprecated and should not be used. */
-#define MBEDTLS_ERR_CCM_HW_ACCEL_FAILED -0x0011 /**< CCM hardware accelerator failed. */
+/** CCM hardware accelerator failed. */
+#define MBEDTLS_ERR_CCM_HW_ACCEL_FAILED -0x0011
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/mbedtls/chacha20.h b/include/mbedtls/chacha20.h
index 8c9c2af..f4073e3 100644
--- a/include/mbedtls/chacha20.h
+++ b/include/mbedtls/chacha20.h
@@ -68,15 +68,18 @@
 #include <stdint.h>
 #include <stddef.h>
 
-#define MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA         -0x0051 /**< Invalid input parameter(s). */
+/** Invalid input parameter(s). */
+#define MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA         -0x0051
 
 /* MBEDTLS_ERR_CHACHA20_FEATURE_UNAVAILABLE is deprecated and should not be
  * used. */
-#define MBEDTLS_ERR_CHACHA20_FEATURE_UNAVAILABLE    -0x0053 /**< Feature not available. For example, s part of the API is not implemented. */
+/** Feature not available. For example, s part of the API is not implemented. */
+#define MBEDTLS_ERR_CHACHA20_FEATURE_UNAVAILABLE    -0x0053
 
 /* MBEDTLS_ERR_CHACHA20_HW_ACCEL_FAILED is deprecated and should not be used.
  */
-#define MBEDTLS_ERR_CHACHA20_HW_ACCEL_FAILED        -0x0055  /**< Chacha20 hardware accelerator failed. */
+/** Chacha20 hardware accelerator failed. */
+#define MBEDTLS_ERR_CHACHA20_HW_ACCEL_FAILED        -0x0055
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/mbedtls/chachapoly.h b/include/mbedtls/chachapoly.h
index 5f6cb6e..436d173 100644
--- a/include/mbedtls/chachapoly.h
+++ b/include/mbedtls/chachapoly.h
@@ -68,8 +68,10 @@
 /* for shared error codes */
 #include "poly1305.h"
 
-#define MBEDTLS_ERR_CHACHAPOLY_BAD_STATE            -0x0054 /**< The requested operation is not permitted in the current state. */
-#define MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED          -0x0056 /**< Authenticated decryption failed: data was not authentic. */
+/** The requested operation is not permitted in the current state. */
+#define MBEDTLS_ERR_CHACHAPOLY_BAD_STATE            -0x0054
+/** Authenticated decryption failed: data was not authentic. */
+#define MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED          -0x0056
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index 2bbd7a8..b150b81 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -490,10 +490,6 @@
 #error "MBEDTLS_PLATFORM_STD_CALLOC defined, but not all prerequisites"
 #endif
 
-#if defined(MBEDTLS_PLATFORM_STD_CALLOC) && !defined(MBEDTLS_PLATFORM_MEMORY)
-#error "MBEDTLS_PLATFORM_STD_CALLOC defined, but not all prerequisites"
-#endif
-
 #if defined(MBEDTLS_PLATFORM_STD_FREE) && !defined(MBEDTLS_PLATFORM_MEMORY)
 #error "MBEDTLS_PLATFORM_STD_FREE defined, but not all prerequisites"
 #endif
diff --git a/include/mbedtls/cipher.h b/include/mbedtls/cipher.h
index 1f41b52..f485b17 100644
--- a/include/mbedtls/cipher.h
+++ b/include/mbedtls/cipher.h
@@ -81,16 +81,24 @@
 #define inline __inline
 #endif
 
-#define MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE  -0x6080  /**< The selected feature is not available. */
-#define MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA       -0x6100  /**< Bad input parameters. */
-#define MBEDTLS_ERR_CIPHER_ALLOC_FAILED         -0x6180  /**< Failed to allocate memory. */
-#define MBEDTLS_ERR_CIPHER_INVALID_PADDING      -0x6200  /**< Input data contains invalid padding and is rejected. */
-#define MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED  -0x6280  /**< Decryption of block requires a full block. */
-#define MBEDTLS_ERR_CIPHER_AUTH_FAILED          -0x6300  /**< Authentication failed (for AEAD modes). */
-#define MBEDTLS_ERR_CIPHER_INVALID_CONTEXT      -0x6380  /**< The context is invalid. For example, because it was freed. */
+/** The selected feature is not available. */
+#define MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE  -0x6080
+/** Bad input parameters. */
+#define MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA       -0x6100
+/** Failed to allocate memory. */
+#define MBEDTLS_ERR_CIPHER_ALLOC_FAILED         -0x6180
+/** Input data contains invalid padding and is rejected. */
+#define MBEDTLS_ERR_CIPHER_INVALID_PADDING      -0x6200
+/** Decryption of block requires a full block. */
+#define MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED  -0x6280
+/** Authentication failed (for AEAD modes). */
+#define MBEDTLS_ERR_CIPHER_AUTH_FAILED          -0x6300
+/** The context is invalid. For example, because it was freed. */
+#define MBEDTLS_ERR_CIPHER_INVALID_CONTEXT      -0x6380
 
 /* MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED is deprecated and should not be used. */
-#define MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED      -0x6400  /**< Cipher hardware accelerator failed. */
+/** Cipher hardware accelerator failed. */
+#define MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED      -0x6400
 
 #define MBEDTLS_CIPHER_VARIABLE_IV_LEN     0x01    /**< Cipher accepts IVs of variable length. */
 #define MBEDTLS_CIPHER_VARIABLE_KEY_LEN    0x02    /**< Cipher accepts keys of variable length. */
diff --git a/include/mbedtls/cmac.h b/include/mbedtls/cmac.h
index 5a7c9b2..7152dac 100644
--- a/include/mbedtls/cmac.h
+++ b/include/mbedtls/cmac.h
@@ -66,7 +66,8 @@
 #endif
 
 /* MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED is deprecated and should not be used. */
-#define MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED -0x007A  /**< CMAC hardware accelerator failed. */
+/** CMAC hardware accelerator failed. */
+#define MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED -0x007A
 
 #define MBEDTLS_AES_BLOCK_SIZE          16
 #define MBEDTLS_DES3_BLOCK_SIZE         8
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index 6b45021..b1d67f7 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -453,7 +453,7 @@
  *       be overridden, but the wrapper functions mbedtls_aes_decrypt and mbedtls_aes_encrypt
  *       must stay untouched.
  *
- * \note If you use the AES_xxx_ALT macros, then is is recommended to also set
+ * \note If you use the AES_xxx_ALT macros, then it is recommended to also set
  *       MBEDTLS_AES_ROM_TABLES in order to help the linker garbage-collect the AES
  *       tables.
  *
@@ -1747,6 +1747,23 @@
 //#define MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT
 
 /**
+ * \def MBEDTLS_TEST_HOOKS
+ *
+ * Enable features for invasive testing such as introspection functions and
+ * hooks for fault injection. This enables additional unit tests.
+ *
+ * Merely enabling this feature should not change the behavior of the product.
+ * It only adds new code, and new branching points where the default behavior
+ * is the same as when this feature is disabled.
+ * However, this feature increases the attack surface: there is an added
+ * risk of vulnerabilities, and more gadgets that can make exploits easier.
+ * Therefore this feature must never be enabled in production.
+ *
+ * Uncomment to enable invasive tests.
+ */
+//#define MBEDTLS_TEST_HOOKS
+
+/**
  * \def MBEDTLS_THREADING_ALT
  *
  * Provide your own alternate threading implementation.
diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h
index 278fbbb..892e3e3 100644
--- a/include/mbedtls/ctr_drbg.h
+++ b/include/mbedtls/ctr_drbg.h
@@ -96,10 +96,14 @@
 #include "threading.h"
 #endif
 
-#define MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED        -0x0034  /**< The entropy source failed. */
-#define MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG              -0x0036  /**< The requested random buffer length is too big. */
-#define MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG                -0x0038  /**< The input (entropy + additional data) is too large. */
-#define MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR                -0x003A  /**< Read or write error in file. */
+/** The entropy source failed. */
+#define MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED        -0x0034
+/** The requested random buffer length is too big. */
+#define MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG              -0x0036
+/** The input (entropy + additional data) is too large. */
+#define MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG                -0x0038
+/** Read or write error in file. */
+#define MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR                -0x003A
 
 #define MBEDTLS_CTR_DRBG_BLOCKSIZE          16 /**< The block size used by the cipher. */
 
@@ -214,6 +218,13 @@
     void *p_entropy;            /*!< The context for the entropy function. */
 
 #if defined(MBEDTLS_THREADING_C)
+    /* Invariant: the mutex is initialized if and only if f_entropy != NULL.
+     * This means that the mutex is initialized during the initial seeding
+     * in mbedtls_ctr_drbg_seed() and freed in mbedtls_ctr_drbg_free().
+     *
+     * Note that this invariant may change without notice. Do not rely on it
+     * and do not access the mutex directly in application code.
+     */
     mbedtls_threading_mutex_t mutex;
 #endif
 }
@@ -277,6 +288,15 @@
  *                      device.
  */
 #endif
+#if defined(MBEDTLS_THREADING_C)
+/**
+ * \note                When Mbed TLS is built with threading support,
+ *                      after this function returns successfully,
+ *                      it is safe to call mbedtls_ctr_drbg_random()
+ *                      from multiple threads. Other operations, including
+ *                      reseeding, are not thread-safe.
+ */
+#endif /* MBEDTLS_THREADING_C */
 /**
  * \param ctx           The CTR_DRBG context to seed.
  *                      It must have been initialized with
@@ -286,6 +306,8 @@
  *                      the same context unless you call
  *                      mbedtls_ctr_drbg_free() and mbedtls_ctr_drbg_init()
  *                      again first.
+ *                      After a failed call to mbedtls_ctr_drbg_seed(),
+ *                      you must call mbedtls_ctr_drbg_free().
  * \param f_entropy     The entropy callback, taking as arguments the
  *                      \p p_entropy context, the buffer to fill, and the
  *                      length of the buffer.
@@ -377,6 +399,11 @@
  * \brief               This function reseeds the CTR_DRBG context, that is
  *                      extracts data from the entropy source.
  *
+ * \note                This function is not thread-safe. It is not safe
+ *                      to call this function if another thread might be
+ *                      concurrently obtaining random numbers from the same
+ *                      context or updating or reseeding the same context.
+ *
  * \param ctx           The CTR_DRBG context.
  * \param additional    Additional data to add to the state. Can be \c NULL.
  * \param len           The length of the additional data.
@@ -394,6 +421,11 @@
 /**
  * \brief              This function updates the state of the CTR_DRBG context.
  *
+ * \note               This function is not thread-safe. It is not safe
+ *                     to call this function if another thread might be
+ *                     concurrently obtaining random numbers from the same
+ *                     context or updating or reseeding the same context.
+ *
  * \param ctx          The CTR_DRBG context.
  * \param additional   The data to update the state with. This must not be
  *                     \c NULL unless \p add_len is \c 0.
@@ -417,6 +449,11 @@
  * This function automatically reseeds if the reseed counter is exceeded
  * or prediction resistance is enabled.
  *
+ * \note                This function is not thread-safe. It is not safe
+ *                      to call this function if another thread might be
+ *                      concurrently obtaining random numbers from the same
+ *                      context or updating or reseeding the same context.
+ *
  * \param p_rng         The CTR_DRBG context. This must be a pointer to a
  *                      #mbedtls_ctr_drbg_context structure.
  * \param output        The buffer to fill.
@@ -445,8 +482,16 @@
  *
  * This function automatically reseeds if the reseed counter is exceeded
  * or prediction resistance is enabled.
- *
- *
+ */
+#if defined(MBEDTLS_THREADING_C)
+/**
+ * \note                When Mbed TLS is built with threading support,
+ *                      it is safe to call mbedtls_ctr_drbg_random()
+ *                      from multiple threads. Other operations, including
+ *                      reseeding, are not thread-safe.
+ */
+#endif /* MBEDTLS_THREADING_C */
+/**
  * \param p_rng         The CTR_DRBG context. This must be a pointer to a
  *                      #mbedtls_ctr_drbg_context structure.
  * \param output        The buffer to fill.
diff --git a/include/mbedtls/des.h b/include/mbedtls/des.h
index ee24f65..f689acb 100644
--- a/include/mbedtls/des.h
+++ b/include/mbedtls/des.h
@@ -66,10 +66,12 @@
 #define MBEDTLS_DES_ENCRYPT     1
 #define MBEDTLS_DES_DECRYPT     0
 
-#define MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH              -0x0032  /**< The data input has an invalid length. */
+/** The data input has an invalid length. */
+#define MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH              -0x0032
 
 /* MBEDTLS_ERR_DES_HW_ACCEL_FAILED is deprecated and should not be used. */
-#define MBEDTLS_ERR_DES_HW_ACCEL_FAILED                   -0x0033  /**< DES hardware accelerator failed. */
+/** DES hardware accelerator failed. */
+#define MBEDTLS_ERR_DES_HW_ACCEL_FAILED                   -0x0033
 
 #define MBEDTLS_DES_KEY_SIZE    8
 
diff --git a/include/mbedtls/dhm.h b/include/mbedtls/dhm.h
index 11042ef..3ddbf3f 100644
--- a/include/mbedtls/dhm.h
+++ b/include/mbedtls/dhm.h
@@ -100,20 +100,31 @@
 /*
  * DHM Error codes
  */
-#define MBEDTLS_ERR_DHM_BAD_INPUT_DATA                    -0x3080  /**< Bad input parameters. */
-#define MBEDTLS_ERR_DHM_READ_PARAMS_FAILED                -0x3100  /**< Reading of the DHM parameters failed. */
-#define MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED                -0x3180  /**< Making of the DHM parameters failed. */
-#define MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED                -0x3200  /**< Reading of the public values failed. */
-#define MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED                -0x3280  /**< Making of the public value failed. */
-#define MBEDTLS_ERR_DHM_CALC_SECRET_FAILED                -0x3300  /**< Calculation of the DHM secret failed. */
-#define MBEDTLS_ERR_DHM_INVALID_FORMAT                    -0x3380  /**< The ASN.1 data is not formatted correctly. */
-#define MBEDTLS_ERR_DHM_ALLOC_FAILED                      -0x3400  /**< Allocation of memory failed. */
-#define MBEDTLS_ERR_DHM_FILE_IO_ERROR                     -0x3480  /**< Read or write of file failed. */
+/** Bad input parameters. */
+#define MBEDTLS_ERR_DHM_BAD_INPUT_DATA                    -0x3080
+/** Reading of the DHM parameters failed. */
+#define MBEDTLS_ERR_DHM_READ_PARAMS_FAILED                -0x3100
+/** Making of the DHM parameters failed. */
+#define MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED                -0x3180
+/** Reading of the public values failed. */
+#define MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED                -0x3200
+/** Making of the public value failed. */
+#define MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED                -0x3280
+/** Calculation of the DHM secret failed. */
+#define MBEDTLS_ERR_DHM_CALC_SECRET_FAILED                -0x3300
+/** The ASN.1 data is not formatted correctly. */
+#define MBEDTLS_ERR_DHM_INVALID_FORMAT                    -0x3380
+/** Allocation of memory failed. */
+#define MBEDTLS_ERR_DHM_ALLOC_FAILED                      -0x3400
+/** Read or write of file failed. */
+#define MBEDTLS_ERR_DHM_FILE_IO_ERROR                     -0x3480
 
 /* MBEDTLS_ERR_DHM_HW_ACCEL_FAILED is deprecated and should not be used. */
-#define MBEDTLS_ERR_DHM_HW_ACCEL_FAILED                   -0x3500  /**< DHM hardware accelerator failed. */
+/** DHM hardware accelerator failed. */
+#define MBEDTLS_ERR_DHM_HW_ACCEL_FAILED                   -0x3500
 
-#define MBEDTLS_ERR_DHM_SET_GROUP_FAILED                  -0x3580  /**< Setting the modulus and generator failed. */
+/** Setting the modulus and generator failed. */
+#define MBEDTLS_ERR_DHM_SET_GROUP_FAILED                  -0x3580
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h
index bdc750e..18178c1 100644
--- a/include/mbedtls/ecp.h
+++ b/include/mbedtls/ecp.h
@@ -72,19 +72,29 @@
 /*
  * ECP error codes
  */
-#define MBEDTLS_ERR_ECP_BAD_INPUT_DATA                    -0x4F80  /**< Bad input parameters to function. */
-#define MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL                  -0x4F00  /**< The buffer is too small to write to. */
-#define MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE               -0x4E80  /**< The requested feature is not available, for example, the requested curve is not supported. */
-#define MBEDTLS_ERR_ECP_VERIFY_FAILED                     -0x4E00  /**< The signature is not valid. */
-#define MBEDTLS_ERR_ECP_ALLOC_FAILED                      -0x4D80  /**< Memory allocation failed. */
-#define MBEDTLS_ERR_ECP_RANDOM_FAILED                     -0x4D00  /**< Generation of random value, such as ephemeral key, failed. */
-#define MBEDTLS_ERR_ECP_INVALID_KEY                       -0x4C80  /**< Invalid private or public key. */
-#define MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH                  -0x4C00  /**< The buffer contains a valid signature followed by more data. */
+/** Bad input parameters to function. */
+#define MBEDTLS_ERR_ECP_BAD_INPUT_DATA                    -0x4F80
+/** The buffer is too small to write to. */
+#define MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL                  -0x4F00
+/** The requested feature is not available, for example, the requested curve is not supported. */
+#define MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE               -0x4E80
+/** The signature is not valid. */
+#define MBEDTLS_ERR_ECP_VERIFY_FAILED                     -0x4E00
+/** Memory allocation failed. */
+#define MBEDTLS_ERR_ECP_ALLOC_FAILED                      -0x4D80
+/** Generation of random value, such as ephemeral key, failed. */
+#define MBEDTLS_ERR_ECP_RANDOM_FAILED                     -0x4D00
+/** Invalid private or public key. */
+#define MBEDTLS_ERR_ECP_INVALID_KEY                       -0x4C80
+/** The buffer contains a valid signature followed by more data. */
+#define MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH                  -0x4C00
 
 /* MBEDTLS_ERR_ECP_HW_ACCEL_FAILED is deprecated and should not be used. */
-#define MBEDTLS_ERR_ECP_HW_ACCEL_FAILED                   -0x4B80  /**< The ECP hardware accelerator failed. */
+/** The ECP hardware accelerator failed. */
+#define MBEDTLS_ERR_ECP_HW_ACCEL_FAILED                   -0x4B80
 
-#define MBEDTLS_ERR_ECP_IN_PROGRESS                       -0x4B00  /**< Operation in progress, call again with the same parameters to continue. */
+/** Operation in progress, call again with the same parameters to continue. */
+#define MBEDTLS_ERR_ECP_IN_PROGRESS                       -0x4B00
 
 #ifdef __cplusplus
 extern "C" {
@@ -154,6 +164,40 @@
 }
 mbedtls_ecp_point;
 
+/* Determine the minimum safe value of MBEDTLS_ECP_MAX_BITS. */
+#if !defined(MBEDTLS_ECP_C)
+#define MBEDTLS_ECP_MAX_BITS_MIN 0
+/* Note: the curves must be listed in DECREASING size! */
+#elif defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
+#define MBEDTLS_ECP_MAX_BITS_MIN 521
+#elif defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
+#define MBEDTLS_ECP_MAX_BITS_MIN 512
+#elif defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
+#define MBEDTLS_ECP_MAX_BITS_MIN 448
+#elif defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
+#define MBEDTLS_ECP_MAX_BITS_MIN 384
+#elif defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
+#define MBEDTLS_ECP_MAX_BITS_MIN 384
+#elif defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
+#define MBEDTLS_ECP_MAX_BITS_MIN 256
+#elif defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
+#define MBEDTLS_ECP_MAX_BITS_MIN 256
+#elif defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
+#define MBEDTLS_ECP_MAX_BITS_MIN 256
+#elif defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
+#define MBEDTLS_ECP_MAX_BITS_MIN 255
+#elif defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
+#define MBEDTLS_ECP_MAX_BITS_MIN 225 // n is slightly above 2^224
+#elif defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
+#define MBEDTLS_ECP_MAX_BITS_MIN 224
+#elif defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
+#define MBEDTLS_ECP_MAX_BITS_MIN 192
+#elif defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
+#define MBEDTLS_ECP_MAX_BITS_MIN 192
+#else
+#error "MBEDTLS_ECP_C enabled, but no curve?"
+#endif
+
 #if !defined(MBEDTLS_ECP_ALT)
 /*
  * default mbed TLS elliptic curve arithmetic implementation
@@ -228,7 +272,13 @@
  * \{
  */
 
-#if !defined(MBEDTLS_ECP_MAX_BITS)
+#if defined(MBEDTLS_ECP_MAX_BITS)
+
+#if MBEDTLS_ECP_MAX_BITS < MBEDTLS_ECP_MAX_BITS_MIN
+#error "MBEDTLS_ECP_MAX_BITS is smaller than the largest supported curve"
+#endif
+
+#else
 /**
  * The maximum size of the groups, that is, of \c N and \c P.
  */
diff --git a/include/mbedtls/entropy.h b/include/mbedtls/entropy.h
index 1e1d3f5..ac977cf 100644
--- a/include/mbedtls/entropy.h
+++ b/include/mbedtls/entropy.h
@@ -75,11 +75,16 @@
 #include "havege.h"
 #endif
 
-#define MBEDTLS_ERR_ENTROPY_SOURCE_FAILED                 -0x003C  /**< Critical entropy source failure. */
-#define MBEDTLS_ERR_ENTROPY_MAX_SOURCES                   -0x003E  /**< No more sources can be added. */
-#define MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED            -0x0040  /**< No sources have been added to poll. */
-#define MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE              -0x003D  /**< No strong sources have been added to poll. */
-#define MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR                 -0x003F  /**< Read/write error in file. */
+/** Critical entropy source failure. */
+#define MBEDTLS_ERR_ENTROPY_SOURCE_FAILED                 -0x003C
+/** No more sources can be added. */
+#define MBEDTLS_ERR_ENTROPY_MAX_SOURCES                   -0x003E
+/** No sources have been added to poll. */
+#define MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED            -0x0040
+/** No strong sources have been added to poll. */
+#define MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE              -0x003D
+/** Read/write error in file. */
+#define MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR                 -0x003F
 
 /**
  * \name SECTION: Module settings
@@ -147,13 +152,15 @@
  */
 typedef struct mbedtls_entropy_context
 {
-    int accumulator_started;
+    int accumulator_started; /* 0 after init.
+                              * 1 after the first update.
+                              * -1 after free. */
 #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
     mbedtls_sha512_context  accumulator;
 #else
     mbedtls_sha256_context  accumulator;
 #endif
-    int             source_count;
+    int             source_count; /* Number of entries used in source. */
     mbedtls_entropy_source_state    source[MBEDTLS_ENTROPY_MAX_SOURCES];
 #if defined(MBEDTLS_HAVEGE_C)
     mbedtls_havege_state    havege_data;
diff --git a/include/mbedtls/gcm.h b/include/mbedtls/gcm.h
index 1201fbd..031e113 100644
--- a/include/mbedtls/gcm.h
+++ b/include/mbedtls/gcm.h
@@ -71,12 +71,15 @@
 #define MBEDTLS_GCM_ENCRYPT     1
 #define MBEDTLS_GCM_DECRYPT     0
 
-#define MBEDTLS_ERR_GCM_AUTH_FAILED                       -0x0012  /**< Authenticated decryption failed. */
+/** Authenticated decryption failed. */
+#define MBEDTLS_ERR_GCM_AUTH_FAILED                       -0x0012
 
 /* MBEDTLS_ERR_GCM_HW_ACCEL_FAILED is deprecated and should not be used. */
-#define MBEDTLS_ERR_GCM_HW_ACCEL_FAILED                   -0x0013  /**< GCM hardware accelerator failed. */
+/** GCM hardware accelerator failed. */
+#define MBEDTLS_ERR_GCM_HW_ACCEL_FAILED                   -0x0013
 
-#define MBEDTLS_ERR_GCM_BAD_INPUT                         -0x0014  /**< Bad input parameters to function. */
+/** Bad input parameters to function. */
+#define MBEDTLS_ERR_GCM_BAD_INPUT                         -0x0014
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/mbedtls/hkdf.h b/include/mbedtls/hkdf.h
index 07ffe83..3cfc5ae 100644
--- a/include/mbedtls/hkdf.h
+++ b/include/mbedtls/hkdf.h
@@ -64,7 +64,8 @@
  *  \name HKDF Error codes
  *  \{
  */
-#define MBEDTLS_ERR_HKDF_BAD_INPUT_DATA  -0x5F80  /**< Bad input parameters to function. */
+/** Bad input parameters to function. */
+#define MBEDTLS_ERR_HKDF_BAD_INPUT_DATA  -0x5F80
 /* \} name */
 
 #ifdef __cplusplus
diff --git a/include/mbedtls/hmac_drbg.h b/include/mbedtls/hmac_drbg.h
index 970c033..9f48a80 100644
--- a/include/mbedtls/hmac_drbg.h
+++ b/include/mbedtls/hmac_drbg.h
@@ -68,10 +68,14 @@
 /*
  * Error codes
  */
-#define MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG              -0x0003  /**< Too many random requested in single call. */
-#define MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG                -0x0005  /**< Input too large (Entropy + additional). */
-#define MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR                -0x0007  /**< Read/write error in file. */
-#define MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED        -0x0009  /**< The entropy source failed. */
+/** Too many random requested in single call. */
+#define MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG              -0x0003
+/** Input too large (Entropy + additional). */
+#define MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG                -0x0005
+/** Read/write error in file. */
+#define MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR                -0x0007
+/** The entropy source failed. */
+#define MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED        -0x0009
 
 /**
  * \name SECTION: Module settings
@@ -128,6 +132,14 @@
     void *p_entropy;            /*!< context for the entropy function        */
 
 #if defined(MBEDTLS_THREADING_C)
+    /* Invariant: the mutex is initialized if and only if
+     * md_ctx->md_info != NULL. This means that the mutex is initialized
+     * during the initial seeding in mbedtls_hmac_drbg_seed() or
+     * mbedtls_hmac_drbg_seed_buf() and freed in mbedtls_ctr_drbg_free().
+     *
+     * Note that this invariant may change without notice. Do not rely on it
+     * and do not access the mutex directly in application code.
+     */
     mbedtls_threading_mutex_t mutex;
 #endif
 } mbedtls_hmac_drbg_context;
@@ -177,7 +189,17 @@
  * \note                During the initial seeding, this function calls
  *                      the entropy source to obtain a nonce
  *                      whose length is half the entropy length.
- *
+ */
+#if defined(MBEDTLS_THREADING_C)
+/**
+ * \note                When Mbed TLS is built with threading support,
+ *                      after this function returns successfully,
+ *                      it is safe to call mbedtls_hmac_drbg_random()
+ *                      from multiple threads. Other operations, including
+ *                      reseeding, are not thread-safe.
+ */
+#endif /* MBEDTLS_THREADING_C */
+/**
  * \param ctx           HMAC_DRBG context to be seeded.
  * \param md_info       MD algorithm to use for HMAC_DRBG.
  * \param f_entropy     The entropy callback, taking as arguments the
@@ -216,7 +238,17 @@
  *
  * This function is meant for use in algorithms that need a pseudorandom
  * input such as deterministic ECDSA.
- *
+ */
+#if defined(MBEDTLS_THREADING_C)
+/**
+ * \note                When Mbed TLS is built with threading support,
+ *                      after this function returns successfully,
+ *                      it is safe to call mbedtls_hmac_drbg_random()
+ *                      from multiple threads. Other operations, including
+ *                      reseeding, are not thread-safe.
+ */
+#endif /* MBEDTLS_THREADING_C */
+/**
  * \param ctx           HMAC_DRBG context to be initialised.
  * \param md_info       MD algorithm to use for HMAC_DRBG.
  * \param data          Concatenation of the initial entropy string and
@@ -279,6 +311,11 @@
 /**
  * \brief               This function updates the state of the HMAC_DRBG context.
  *
+ * \note                This function is not thread-safe. It is not safe
+ *                      to call this function if another thread might be
+ *                      concurrently obtaining random numbers from the same
+ *                      context or updating or reseeding the same context.
+ *
  * \param ctx           The HMAC_DRBG context.
  * \param additional    The data to update the state with.
  *                      If this is \c NULL, there is no additional data.
@@ -295,6 +332,11 @@
  * \brief               This function reseeds the HMAC_DRBG context, that is
  *                      extracts data from the entropy source.
  *
+ * \note                This function is not thread-safe. It is not safe
+ *                      to call this function if another thread might be
+ *                      concurrently obtaining random numbers from the same
+ *                      context or updating or reseeding the same context.
+ *
  * \param ctx           The HMAC_DRBG context.
  * \param additional    Additional data to add to the state.
  *                      If this is \c NULL, there is no additional data
@@ -320,6 +362,11 @@
  * This function automatically reseeds if the reseed counter is exceeded
  * or prediction resistance is enabled.
  *
+ * \note                This function is not thread-safe. It is not safe
+ *                      to call this function if another thread might be
+ *                      concurrently obtaining random numbers from the same
+ *                      context or updating or reseeding the same context.
+ *
  * \param p_rng         The HMAC_DRBG context. This must be a pointer to a
  *                      #mbedtls_hmac_drbg_context structure.
  * \param output        The buffer to fill.
@@ -349,7 +396,16 @@
  *
  * This function automatically reseeds if the reseed counter is exceeded
  * or prediction resistance is enabled.
- *
+ */
+#if defined(MBEDTLS_THREADING_C)
+/**
+ * \note                When Mbed TLS is built with threading support,
+ *                      it is safe to call mbedtls_ctr_drbg_random()
+ *                      from multiple threads. Other operations, including
+ *                      reseeding, are not thread-safe.
+ */
+#endif /* MBEDTLS_THREADING_C */
+/**
  * \param p_rng         The HMAC_DRBG context. This must be a pointer to a
  *                      #mbedtls_hmac_drbg_context structure.
  * \param output        The buffer to fill.
diff --git a/include/mbedtls/md.h b/include/mbedtls/md.h
index 2ba8d9e..ebbe565 100644
--- a/include/mbedtls/md.h
+++ b/include/mbedtls/md.h
@@ -60,13 +60,18 @@
 #include MBEDTLS_CONFIG_FILE
 #endif
 
-#define MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE                -0x5080  /**< The selected feature is not available. */
-#define MBEDTLS_ERR_MD_BAD_INPUT_DATA                     -0x5100  /**< Bad input parameters to function. */
-#define MBEDTLS_ERR_MD_ALLOC_FAILED                       -0x5180  /**< Failed to allocate memory. */
-#define MBEDTLS_ERR_MD_FILE_IO_ERROR                      -0x5200  /**< Opening or reading of file failed. */
+/** The selected feature is not available. */
+#define MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE                -0x5080
+/** Bad input parameters to function. */
+#define MBEDTLS_ERR_MD_BAD_INPUT_DATA                     -0x5100
+/** Failed to allocate memory. */
+#define MBEDTLS_ERR_MD_ALLOC_FAILED                       -0x5180
+/** Opening or reading of file failed. */
+#define MBEDTLS_ERR_MD_FILE_IO_ERROR                      -0x5200
 
 /* MBEDTLS_ERR_MD_HW_ACCEL_FAILED is deprecated and should not be used. */
-#define MBEDTLS_ERR_MD_HW_ACCEL_FAILED                    -0x5280  /**< MD hardware accelerator failed. */
+/** MD hardware accelerator failed. */
+#define MBEDTLS_ERR_MD_HW_ACCEL_FAILED                    -0x5280
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/mbedtls/md2.h b/include/mbedtls/md2.h
index 9607df6..7298200 100644
--- a/include/mbedtls/md2.h
+++ b/include/mbedtls/md2.h
@@ -63,7 +63,8 @@
 #include <stddef.h>
 
 /* MBEDTLS_ERR_MD2_HW_ACCEL_FAILED is deprecated and should not be used. */
-#define MBEDTLS_ERR_MD2_HW_ACCEL_FAILED                   -0x002B  /**< MD2 hardware accelerator failed */
+/** MD2 hardware accelerator failed */
+#define MBEDTLS_ERR_MD2_HW_ACCEL_FAILED                   -0x002B
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/mbedtls/md4.h b/include/mbedtls/md4.h
index 6ceaf7a..1ea9f6c 100644
--- a/include/mbedtls/md4.h
+++ b/include/mbedtls/md4.h
@@ -64,7 +64,8 @@
 #include <stdint.h>
 
 /* MBEDTLS_ERR_MD4_HW_ACCEL_FAILED is deprecated and should not be used. */
-#define MBEDTLS_ERR_MD4_HW_ACCEL_FAILED                   -0x002D  /**< MD4 hardware accelerator failed */
+/** MD4 hardware accelerator failed */
+#define MBEDTLS_ERR_MD4_HW_ACCEL_FAILED                   -0x002D
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/mbedtls/md5.h b/include/mbedtls/md5.h
index b9d0ca9..fa60dd4 100644
--- a/include/mbedtls/md5.h
+++ b/include/mbedtls/md5.h
@@ -63,7 +63,8 @@
 #include <stdint.h>
 
 /* MBEDTLS_ERR_MD5_HW_ACCEL_FAILED is deprecated and should not be used. */
-#define MBEDTLS_ERR_MD5_HW_ACCEL_FAILED                   -0x002F  /**< MD5 hardware accelerator failed */
+/** MD5 hardware accelerator failed */
+#define MBEDTLS_ERR_MD5_HW_ACCEL_FAILED                   -0x002F
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/mbedtls/net_sockets.h b/include/mbedtls/net_sockets.h
index 00fea7d..66eb4f4 100644
--- a/include/mbedtls/net_sockets.h
+++ b/include/mbedtls/net_sockets.h
@@ -76,19 +76,32 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#define MBEDTLS_ERR_NET_SOCKET_FAILED                     -0x0042  /**< Failed to open a socket. */
-#define MBEDTLS_ERR_NET_CONNECT_FAILED                    -0x0044  /**< The connection to the given server / port failed. */
-#define MBEDTLS_ERR_NET_BIND_FAILED                       -0x0046  /**< Binding of the socket failed. */
-#define MBEDTLS_ERR_NET_LISTEN_FAILED                     -0x0048  /**< Could not listen on the socket. */
-#define MBEDTLS_ERR_NET_ACCEPT_FAILED                     -0x004A  /**< Could not accept the incoming connection. */
-#define MBEDTLS_ERR_NET_RECV_FAILED                       -0x004C  /**< Reading information from the socket failed. */
-#define MBEDTLS_ERR_NET_SEND_FAILED                       -0x004E  /**< Sending information through the socket failed. */
-#define MBEDTLS_ERR_NET_CONN_RESET                        -0x0050  /**< Connection was reset by peer. */
-#define MBEDTLS_ERR_NET_UNKNOWN_HOST                      -0x0052  /**< Failed to get an IP address for the given hostname. */
-#define MBEDTLS_ERR_NET_BUFFER_TOO_SMALL                  -0x0043  /**< Buffer is too small to hold the data. */
-#define MBEDTLS_ERR_NET_INVALID_CONTEXT                   -0x0045  /**< The context is invalid, eg because it was free()ed. */
-#define MBEDTLS_ERR_NET_POLL_FAILED                       -0x0047  /**< Polling the net context failed. */
-#define MBEDTLS_ERR_NET_BAD_INPUT_DATA                    -0x0049  /**< Input invalid. */
+/** Failed to open a socket. */
+#define MBEDTLS_ERR_NET_SOCKET_FAILED                     -0x0042
+/** The connection to the given server / port failed. */
+#define MBEDTLS_ERR_NET_CONNECT_FAILED                    -0x0044
+/** Binding of the socket failed. */
+#define MBEDTLS_ERR_NET_BIND_FAILED                       -0x0046
+/** Could not listen on the socket. */
+#define MBEDTLS_ERR_NET_LISTEN_FAILED                     -0x0048
+/** Could not accept the incoming connection. */
+#define MBEDTLS_ERR_NET_ACCEPT_FAILED                     -0x004A
+/** Reading information from the socket failed. */
+#define MBEDTLS_ERR_NET_RECV_FAILED                       -0x004C
+/** Sending information through the socket failed. */
+#define MBEDTLS_ERR_NET_SEND_FAILED                       -0x004E
+/** Connection was reset by peer. */
+#define MBEDTLS_ERR_NET_CONN_RESET                        -0x0050
+/** Failed to get an IP address for the given hostname. */
+#define MBEDTLS_ERR_NET_UNKNOWN_HOST                      -0x0052
+/** Buffer is too small to hold the data. */
+#define MBEDTLS_ERR_NET_BUFFER_TOO_SMALL                  -0x0043
+/** The context is invalid, eg because it was free()ed. */
+#define MBEDTLS_ERR_NET_INVALID_CONTEXT                   -0x0045
+/** Polling the net context failed. */
+#define MBEDTLS_ERR_NET_POLL_FAILED                       -0x0047
+/** Input invalid. */
+#define MBEDTLS_ERR_NET_BAD_INPUT_DATA                    -0x0049
 
 #define MBEDTLS_NET_LISTEN_BACKLOG         10 /**< The backlog that listen() should use. */
 
@@ -151,6 +164,7 @@
  *
  * \return         0 if successful, or one of:
  *                      MBEDTLS_ERR_NET_SOCKET_FAILED,
+ *                      MBEDTLS_ERR_NET_UNKNOWN_HOST,
  *                      MBEDTLS_ERR_NET_BIND_FAILED,
  *                      MBEDTLS_ERR_NET_LISTEN_FAILED
  *
@@ -170,6 +184,8 @@
  *                  can be NULL if client_ip is null
  *
  * \return          0 if successful, or
+ *                  MBEDTLS_ERR_NET_SOCKET_FAILED,
+ *                  MBEDTLS_ERR_NET_BIND_FAILED,
  *                  MBEDTLS_ERR_NET_ACCEPT_FAILED, or
  *                  MBEDTLS_ERR_NET_BUFFER_TOO_SMALL if buf_size is too small,
  *                  MBEDTLS_ERR_SSL_WANT_READ if bind_fd was set to
@@ -182,6 +198,10 @@
 /**
  * \brief          Check and wait for the context to be ready for read/write
  *
+ * \note           The current implementation of this function uses
+ *                 select() and returns an error if the file descriptor
+ *                 is \c FD_SETSIZE or greater.
+ *
  * \param ctx      Socket to check
  * \param rw       Bitflag composed of MBEDTLS_NET_POLL_READ and
  *                 MBEDTLS_NET_POLL_WRITE specifying the events
@@ -263,16 +283,21 @@
  *                 'timeout' seconds. If no error occurs, the actual amount
  *                 read is returned.
  *
+ * \note           The current implementation of this function uses
+ *                 select() and returns an error if the file descriptor
+ *                 is \c FD_SETSIZE or greater.
+ *
  * \param ctx      Socket
  * \param buf      The buffer to write to
  * \param len      Maximum length of the buffer
  * \param timeout  Maximum number of milliseconds to wait for data
  *                 0 means no timeout (wait forever)
  *
- * \return         the number of bytes received,
- *                 or a non-zero error code:
- *                 MBEDTLS_ERR_SSL_TIMEOUT if the operation timed out,
+ * \return         The number of bytes received if successful.
+ *                 MBEDTLS_ERR_SSL_TIMEOUT if the operation timed out.
  *                 MBEDTLS_ERR_SSL_WANT_READ if interrupted by a signal.
+ *                 Another negative error code (MBEDTLS_ERR_NET_xxx)
+ *                 for other failures.
  *
  * \note           This function will block (until data becomes available or
  *                 timeout is reached) even if the socket is set to
diff --git a/include/mbedtls/oid.h b/include/mbedtls/oid.h
index 4a7e3b4..6d3d3ee 100644
--- a/include/mbedtls/oid.h
+++ b/include/mbedtls/oid.h
@@ -72,8 +72,10 @@
 #include "x509.h"
 #endif
 
-#define MBEDTLS_ERR_OID_NOT_FOUND                         -0x002E  /**< OID is not found. */
-#define MBEDTLS_ERR_OID_BUF_TOO_SMALL                     -0x000B  /**< output buffer is too small */
+/** OID is not found. */
+#define MBEDTLS_ERR_OID_NOT_FOUND                         -0x002E
+/** output buffer is too small */
+#define MBEDTLS_ERR_OID_BUF_TOO_SMALL                     -0x000B
 
 /*
  * Top level OID tuples
diff --git a/include/mbedtls/padlock.h b/include/mbedtls/padlock.h
index d8246e2..83d6f4a 100644
--- a/include/mbedtls/padlock.h
+++ b/include/mbedtls/padlock.h
@@ -61,7 +61,8 @@
 
 #include "aes.h"
 
-#define MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED               -0x0030  /**< Input data should be aligned. */
+/** Input data should be aligned. */
+#define MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED               -0x0030
 
 #if defined(__has_feature)
 #if __has_feature(address_sanitizer)
@@ -98,7 +99,7 @@
  *
  * \param feature  The feature to detect
  *
- * \return         1 if CPU has support for the feature, 0 otherwise
+ * \return         non-zero if CPU has support for the feature, 0 otherwise
  */
 int mbedtls_padlock_has_support( int feature );
 
diff --git a/include/mbedtls/pem.h b/include/mbedtls/pem.h
index c9df7ca..bfa3059 100644
--- a/include/mbedtls/pem.h
+++ b/include/mbedtls/pem.h
@@ -63,15 +63,24 @@
  * PEM data.
  * \{
  */
-#define MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT          -0x1080  /**< No PEM header or footer found. */
-#define MBEDTLS_ERR_PEM_INVALID_DATA                      -0x1100  /**< PEM string is not as expected. */
-#define MBEDTLS_ERR_PEM_ALLOC_FAILED                      -0x1180  /**< Failed to allocate memory. */
-#define MBEDTLS_ERR_PEM_INVALID_ENC_IV                    -0x1200  /**< RSA IV is not in hex-format. */
-#define MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG                   -0x1280  /**< Unsupported key encryption algorithm. */
-#define MBEDTLS_ERR_PEM_PASSWORD_REQUIRED                 -0x1300  /**< Private key password can't be empty. */
-#define MBEDTLS_ERR_PEM_PASSWORD_MISMATCH                 -0x1380  /**< Given private key password does not allow for correct decryption. */
-#define MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE               -0x1400  /**< Unavailable feature, e.g. hashing/encryption combination. */
-#define MBEDTLS_ERR_PEM_BAD_INPUT_DATA                    -0x1480  /**< Bad input parameters to function. */
+/** No PEM header or footer found. */
+#define MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT          -0x1080
+/** PEM string is not as expected. */
+#define MBEDTLS_ERR_PEM_INVALID_DATA                      -0x1100
+/** Failed to allocate memory. */
+#define MBEDTLS_ERR_PEM_ALLOC_FAILED                      -0x1180
+/** RSA IV is not in hex-format. */
+#define MBEDTLS_ERR_PEM_INVALID_ENC_IV                    -0x1200
+/** Unsupported key encryption algorithm. */
+#define MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG                   -0x1280
+/** Private key password can't be empty. */
+#define MBEDTLS_ERR_PEM_PASSWORD_REQUIRED                 -0x1300
+/** Given private key password does not allow for correct decryption. */
+#define MBEDTLS_ERR_PEM_PASSWORD_MISMATCH                 -0x1380
+/** Unavailable feature, e.g. hashing/encryption combination. */
+#define MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE               -0x1400
+/** Bad input parameters to function. */
+#define MBEDTLS_ERR_PEM_BAD_INPUT_DATA                    -0x1480
 /* \} name */
 
 #ifdef __cplusplus
diff --git a/include/mbedtls/pk.h b/include/mbedtls/pk.h
index 20d51d4..1f30339 100644
--- a/include/mbedtls/pk.h
+++ b/include/mbedtls/pk.h
@@ -75,23 +75,38 @@
 #define inline __inline
 #endif
 
-#define MBEDTLS_ERR_PK_ALLOC_FAILED        -0x3F80  /**< Memory allocation failed. */
-#define MBEDTLS_ERR_PK_TYPE_MISMATCH       -0x3F00  /**< Type mismatch, eg attempt to encrypt with an ECDSA key */
-#define MBEDTLS_ERR_PK_BAD_INPUT_DATA      -0x3E80  /**< Bad input parameters to function. */
-#define MBEDTLS_ERR_PK_FILE_IO_ERROR       -0x3E00  /**< Read/write of file failed. */
-#define MBEDTLS_ERR_PK_KEY_INVALID_VERSION -0x3D80  /**< Unsupported key version */
-#define MBEDTLS_ERR_PK_KEY_INVALID_FORMAT  -0x3D00  /**< Invalid key tag or value. */
-#define MBEDTLS_ERR_PK_UNKNOWN_PK_ALG      -0x3C80  /**< Key algorithm is unsupported (only RSA and EC are supported). */
-#define MBEDTLS_ERR_PK_PASSWORD_REQUIRED   -0x3C00  /**< Private key password can't be empty. */
-#define MBEDTLS_ERR_PK_PASSWORD_MISMATCH   -0x3B80  /**< Given private key password does not allow for correct decryption. */
-#define MBEDTLS_ERR_PK_INVALID_PUBKEY      -0x3B00  /**< The pubkey tag or value is invalid (only RSA and EC are supported). */
-#define MBEDTLS_ERR_PK_INVALID_ALG         -0x3A80  /**< The algorithm tag or value is invalid. */
-#define MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE -0x3A00  /**< Elliptic curve is unsupported (only NIST curves are supported). */
-#define MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE -0x3980  /**< Unavailable feature, e.g. RSA disabled for RSA key. */
-#define MBEDTLS_ERR_PK_SIG_LEN_MISMATCH    -0x3900  /**< The buffer contains a valid signature followed by more data. */
+/** Memory allocation failed. */
+#define MBEDTLS_ERR_PK_ALLOC_FAILED        -0x3F80
+/** Type mismatch, eg attempt to encrypt with an ECDSA key */
+#define MBEDTLS_ERR_PK_TYPE_MISMATCH       -0x3F00
+/** Bad input parameters to function. */
+#define MBEDTLS_ERR_PK_BAD_INPUT_DATA      -0x3E80
+/** Read/write of file failed. */
+#define MBEDTLS_ERR_PK_FILE_IO_ERROR       -0x3E00
+/** Unsupported key version */
+#define MBEDTLS_ERR_PK_KEY_INVALID_VERSION -0x3D80
+/** Invalid key tag or value. */
+#define MBEDTLS_ERR_PK_KEY_INVALID_FORMAT  -0x3D00
+/** Key algorithm is unsupported (only RSA and EC are supported). */
+#define MBEDTLS_ERR_PK_UNKNOWN_PK_ALG      -0x3C80
+/** Private key password can't be empty. */
+#define MBEDTLS_ERR_PK_PASSWORD_REQUIRED   -0x3C00
+/** Given private key password does not allow for correct decryption. */
+#define MBEDTLS_ERR_PK_PASSWORD_MISMATCH   -0x3B80
+/** The pubkey tag or value is invalid (only RSA and EC are supported). */
+#define MBEDTLS_ERR_PK_INVALID_PUBKEY      -0x3B00
+/** The algorithm tag or value is invalid. */
+#define MBEDTLS_ERR_PK_INVALID_ALG         -0x3A80
+/** Elliptic curve is unsupported (only NIST curves are supported). */
+#define MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE -0x3A00
+/** Unavailable feature, e.g. RSA disabled for RSA key. */
+#define MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE -0x3980
+/** The buffer contains a valid signature followed by more data. */
+#define MBEDTLS_ERR_PK_SIG_LEN_MISMATCH    -0x3900
 
 /* MBEDTLS_ERR_PK_HW_ACCEL_FAILED is deprecated and should not be used. */
-#define MBEDTLS_ERR_PK_HW_ACCEL_FAILED     -0x3880  /**< PK hardware accelerator failed. */
+/** PK hardware accelerator failed. */
+#define MBEDTLS_ERR_PK_HW_ACCEL_FAILED     -0x3880
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/mbedtls/pkcs12.h b/include/mbedtls/pkcs12.h
index 9cbcb17..eb85aca 100644
--- a/include/mbedtls/pkcs12.h
+++ b/include/mbedtls/pkcs12.h
@@ -61,10 +61,14 @@
 
 #include <stddef.h>
 
-#define MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA                 -0x1F80  /**< Bad input parameters to function. */
-#define MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE            -0x1F00  /**< Feature not available, e.g. unsupported encryption scheme. */
-#define MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT             -0x1E80  /**< PBE ASN.1 data not as expected. */
-#define MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH              -0x1E00  /**< Given private key password does not allow for correct decryption. */
+/** Bad input parameters to function. */
+#define MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA                 -0x1F80
+/** Feature not available, e.g. unsupported encryption scheme. */
+#define MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE            -0x1F00
+/** PBE ASN.1 data not as expected. */
+#define MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT             -0x1E80
+/** Given private key password does not allow for correct decryption. */
+#define MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH              -0x1E00
 
 #define MBEDTLS_PKCS12_DERIVE_KEY       1   /**< encryption/decryption key */
 #define MBEDTLS_PKCS12_DERIVE_IV        2   /**< initialization vector     */
diff --git a/include/mbedtls/pkcs5.h b/include/mbedtls/pkcs5.h
index 328633c..9b97d62 100644
--- a/include/mbedtls/pkcs5.h
+++ b/include/mbedtls/pkcs5.h
@@ -63,10 +63,14 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#define MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA                  -0x2f80  /**< Bad input parameters to function. */
-#define MBEDTLS_ERR_PKCS5_INVALID_FORMAT                  -0x2f00  /**< Unexpected ASN.1 data. */
-#define MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE             -0x2e80  /**< Requested encryption or digest alg not available. */
-#define MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH               -0x2e00  /**< Given private key password does not allow for correct decryption. */
+/** Bad input parameters to function. */
+#define MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA                  -0x2f80
+/** Unexpected ASN.1 data. */
+#define MBEDTLS_ERR_PKCS5_INVALID_FORMAT                  -0x2f00
+/** Requested encryption or digest alg not available. */
+#define MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE             -0x2e80
+/** Given private key password does not allow for correct decryption. */
+#define MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH               -0x2e00
 
 #define MBEDTLS_PKCS5_DECRYPT      0
 #define MBEDTLS_PKCS5_ENCRYPT      1
diff --git a/include/mbedtls/platform.h b/include/mbedtls/platform.h
index 689cfc6..f6ccd1c 100644
--- a/include/mbedtls/platform.h
+++ b/include/mbedtls/platform.h
@@ -68,8 +68,10 @@
 #include "platform_time.h"
 #endif
 
-#define MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED     -0x0070 /**< Hardware accelerator failed */
-#define MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED -0x0072 /**< The requested feature is not supported by the platform */
+/** Hardware accelerator failed */
+#define MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED     -0x0070
+/** The requested feature is not supported by the platform */
+#define MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED -0x0072
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/mbedtls/poly1305.h b/include/mbedtls/poly1305.h
index b337aa8..ea69dba 100644
--- a/include/mbedtls/poly1305.h
+++ b/include/mbedtls/poly1305.h
@@ -68,15 +68,18 @@
 #include <stdint.h>
 #include <stddef.h>
 
-#define MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA         -0x0057 /**< Invalid input parameter(s). */
+/** Invalid input parameter(s). */
+#define MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA         -0x0057
 
 /* MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE is deprecated and should not be
  * used. */
-#define MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE    -0x0059 /**< Feature not available. For example, s part of the API is not implemented. */
+/** Feature not available. For example, s part of the API is not implemented. */
+#define MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE    -0x0059
 
 /* MBEDTLS_ERR_POLY1305_HW_ACCEL_FAILED is deprecated and should not be used.
  */
-#define MBEDTLS_ERR_POLY1305_HW_ACCEL_FAILED        -0x005B  /**< Poly1305 hardware accelerator failed. */
+/** Poly1305 hardware accelerator failed. */
+#define MBEDTLS_ERR_POLY1305_HW_ACCEL_FAILED        -0x005B
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/mbedtls/ripemd160.h b/include/mbedtls/ripemd160.h
index 31c6637..415c897 100644
--- a/include/mbedtls/ripemd160.h
+++ b/include/mbedtls/ripemd160.h
@@ -60,7 +60,8 @@
 
 /* MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED is deprecated and should not be used.
  */
-#define MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED             -0x0031  /**< RIPEMD160 hardware accelerator failed */
+/** RIPEMD160 hardware accelerator failed */
+#define MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED             -0x0031
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/mbedtls/rsa.h b/include/mbedtls/rsa.h
index 188c37c..9b5da67 100644
--- a/include/mbedtls/rsa.h
+++ b/include/mbedtls/rsa.h
@@ -71,22 +71,33 @@
 /*
  * RSA Error codes
  */
-#define MBEDTLS_ERR_RSA_BAD_INPUT_DATA                    -0x4080  /**< Bad input parameters to function. */
-#define MBEDTLS_ERR_RSA_INVALID_PADDING                   -0x4100  /**< Input data contains invalid padding and is rejected. */
-#define MBEDTLS_ERR_RSA_KEY_GEN_FAILED                    -0x4180  /**< Something failed during generation of a key. */
-#define MBEDTLS_ERR_RSA_KEY_CHECK_FAILED                  -0x4200  /**< Key failed to pass the validity check of the library. */
-#define MBEDTLS_ERR_RSA_PUBLIC_FAILED                     -0x4280  /**< The public key operation failed. */
-#define MBEDTLS_ERR_RSA_PRIVATE_FAILED                    -0x4300  /**< The private key operation failed. */
-#define MBEDTLS_ERR_RSA_VERIFY_FAILED                     -0x4380  /**< The PKCS#1 verification failed. */
-#define MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE                  -0x4400  /**< The output buffer for decryption is not large enough. */
-#define MBEDTLS_ERR_RSA_RNG_FAILED                        -0x4480  /**< The random generator failed to generate non-zeros. */
+/** Bad input parameters to function. */
+#define MBEDTLS_ERR_RSA_BAD_INPUT_DATA                    -0x4080
+/** Input data contains invalid padding and is rejected. */
+#define MBEDTLS_ERR_RSA_INVALID_PADDING                   -0x4100
+/** Something failed during generation of a key. */
+#define MBEDTLS_ERR_RSA_KEY_GEN_FAILED                    -0x4180
+/** Key failed to pass the validity check of the library. */
+#define MBEDTLS_ERR_RSA_KEY_CHECK_FAILED                  -0x4200
+/** The public key operation failed. */
+#define MBEDTLS_ERR_RSA_PUBLIC_FAILED                     -0x4280
+/** The private key operation failed. */
+#define MBEDTLS_ERR_RSA_PRIVATE_FAILED                    -0x4300
+/** The PKCS#1 verification failed. */
+#define MBEDTLS_ERR_RSA_VERIFY_FAILED                     -0x4380
+/** The output buffer for decryption is not large enough. */
+#define MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE                  -0x4400
+/** The random generator failed to generate non-zeros. */
+#define MBEDTLS_ERR_RSA_RNG_FAILED                        -0x4480
 
 /* MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION is deprecated and should not be used.
  */
-#define MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION             -0x4500  /**< The implementation does not offer the requested operation, for example, because of security violations or lack of functionality. */
+/** The implementation does not offer the requested operation, for example, because of security violations or lack of functionality. */
+#define MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION             -0x4500
 
 /* MBEDTLS_ERR_RSA_HW_ACCEL_FAILED is deprecated and should not be used. */
-#define MBEDTLS_ERR_RSA_HW_ACCEL_FAILED                   -0x4580  /**< RSA hardware accelerator failed. */
+/** RSA hardware accelerator failed. */
+#define MBEDTLS_ERR_RSA_HW_ACCEL_FAILED                   -0x4580
 
 /*
  * RSA constants
@@ -124,7 +135,10 @@
  */
 typedef struct mbedtls_rsa_context
 {
-    int ver;                    /*!<  Always 0.*/
+    int ver;                    /*!<  Reserved for internal purposes.
+                                 *    Do not set this field in application
+                                 *    code. Its meaning might change without
+                                 *    notice. */
     size_t len;                 /*!<  The size of \p N in Bytes. */
 
     mbedtls_mpi N;              /*!<  The public modulus. */
@@ -154,6 +168,7 @@
                                      mask generating function used in the
                                      EME-OAEP and EMSA-PSS encodings. */
 #if defined(MBEDTLS_THREADING_C)
+    /* Invariant: the mutex is initialized iff ver != 0. */
     mbedtls_threading_mutex_t mutex;    /*!<  Thread-safety mutex. */
 #endif
 }
diff --git a/include/mbedtls/sha1.h b/include/mbedtls/sha1.h
index 60c514a..969b5dc 100644
--- a/include/mbedtls/sha1.h
+++ b/include/mbedtls/sha1.h
@@ -66,8 +66,10 @@
 #include <stdint.h>
 
 /* MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED is deprecated and should not be used. */
-#define MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED                  -0x0035  /**< SHA-1 hardware accelerator failed */
-#define MBEDTLS_ERR_SHA1_BAD_INPUT_DATA                   -0x0073  /**< SHA-1 input data was malformed. */
+/** SHA-1 hardware accelerator failed */
+#define MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED                  -0x0035
+/** SHA-1 input data was malformed. */
+#define MBEDTLS_ERR_SHA1_BAD_INPUT_DATA                   -0x0073
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/mbedtls/sha256.h b/include/mbedtls/sha256.h
index b1881e1..c55177d 100644
--- a/include/mbedtls/sha256.h
+++ b/include/mbedtls/sha256.h
@@ -62,8 +62,10 @@
 #include <stdint.h>
 
 /* MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED is deprecated and should not be used. */
-#define MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED                -0x0037  /**< SHA-256 hardware accelerator failed */
-#define MBEDTLS_ERR_SHA256_BAD_INPUT_DATA                 -0x0074  /**< SHA-256 input data was malformed. */
+/** SHA-256 hardware accelerator failed */
+#define MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED                -0x0037
+/** SHA-256 input data was malformed. */
+#define MBEDTLS_ERR_SHA256_BAD_INPUT_DATA                 -0x0074
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/mbedtls/sha512.h b/include/mbedtls/sha512.h
index 5e5a15e..353ad7a 100644
--- a/include/mbedtls/sha512.h
+++ b/include/mbedtls/sha512.h
@@ -61,8 +61,10 @@
 #include <stdint.h>
 
 /* MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED is deprecated and should not be used. */
-#define MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED                -0x0039  /**< SHA-512 hardware accelerator failed */
-#define MBEDTLS_ERR_SHA512_BAD_INPUT_DATA                 -0x0075  /**< SHA-512 input data was malformed. */
+/** SHA-512 hardware accelerator failed */
+#define MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED                -0x0039
+/** SHA-512 input data was malformed. */
+#define MBEDTLS_ERR_SHA512_BAD_INPUT_DATA                 -0x0075
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index fe33ac8..cdceed8 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -93,62 +93,118 @@
 /*
  * SSL Error codes
  */
-#define MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE               -0x7080  /**< The requested feature is not available. */
-#define MBEDTLS_ERR_SSL_BAD_INPUT_DATA                    -0x7100  /**< Bad input parameters to function. */
-#define MBEDTLS_ERR_SSL_INVALID_MAC                       -0x7180  /**< Verification of the message MAC failed. */
-#define MBEDTLS_ERR_SSL_INVALID_RECORD                    -0x7200  /**< An invalid SSL record was received. */
-#define MBEDTLS_ERR_SSL_CONN_EOF                          -0x7280  /**< The connection indicated an EOF. */
-#define MBEDTLS_ERR_SSL_UNKNOWN_CIPHER                    -0x7300  /**< An unknown cipher was received. */
-#define MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN                  -0x7380  /**< The server has no ciphersuites in common with the client. */
-#define MBEDTLS_ERR_SSL_NO_RNG                            -0x7400  /**< No RNG was provided to the SSL module. */
-#define MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE             -0x7480  /**< No client certification received from the client, but required by the authentication mode. */
-#define MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE             -0x7500  /**< Our own certificate(s) is/are too large to send in an SSL message. */
-#define MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED              -0x7580  /**< The own certificate is not set, but needed by the server. */
-#define MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED              -0x7600  /**< The own private key or pre-shared key is not set, but needed. */
-#define MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED                 -0x7680  /**< No CA Chain is set, but required to operate. */
-#define MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE                -0x7700  /**< An unexpected message was received from our peer. */
-#define MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE               -0x7780  /**< A fatal alert message was received from our peer. */
-#define MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED                -0x7800  /**< Verification of our peer failed. */
-#define MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY                 -0x7880  /**< The peer notified us that the connection is going to be closed. */
-#define MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO               -0x7900  /**< Processing of the ClientHello handshake message failed. */
-#define MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO               -0x7980  /**< Processing of the ServerHello handshake message failed. */
-#define MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE                -0x7A00  /**< Processing of the Certificate handshake message failed. */
-#define MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST        -0x7A80  /**< Processing of the CertificateRequest handshake message failed. */
-#define MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE        -0x7B00  /**< Processing of the ServerKeyExchange handshake message failed. */
-#define MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE          -0x7B80  /**< Processing of the ServerHelloDone handshake message failed. */
-#define MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE        -0x7C00  /**< Processing of the ClientKeyExchange handshake message failed. */
-#define MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP     -0x7C80  /**< Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Read Public. */
-#define MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS     -0x7D00  /**< Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Calculate Secret. */
-#define MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY         -0x7D80  /**< Processing of the CertificateVerify handshake message failed. */
-#define MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC         -0x7E00  /**< Processing of the ChangeCipherSpec handshake message failed. */
-#define MBEDTLS_ERR_SSL_BAD_HS_FINISHED                   -0x7E80  /**< Processing of the Finished handshake message failed. */
-#define MBEDTLS_ERR_SSL_ALLOC_FAILED                      -0x7F00  /**< Memory allocation failed */
-#define MBEDTLS_ERR_SSL_HW_ACCEL_FAILED                   -0x7F80  /**< Hardware acceleration function returned with error */
-#define MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH              -0x6F80  /**< Hardware acceleration function skipped / left alone data */
-#define MBEDTLS_ERR_SSL_COMPRESSION_FAILED                -0x6F00  /**< Processing of the compression / decompression failed */
-#define MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION           -0x6E80  /**< Handshake protocol not within min/max boundaries */
-#define MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET         -0x6E00  /**< Processing of the NewSessionTicket handshake message failed. */
-#define MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED            -0x6D80  /**< Session ticket has expired. */
-#define MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH                  -0x6D00  /**< Public key type mismatch (eg, asked for RSA key exchange and presented EC key) */
-#define MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY                  -0x6C80  /**< Unknown identity received (eg, PSK identity) */
-#define MBEDTLS_ERR_SSL_INTERNAL_ERROR                    -0x6C00  /**< Internal error (eg, unexpected failure in lower-level module) */
-#define MBEDTLS_ERR_SSL_COUNTER_WRAPPING                  -0x6B80  /**< A counter would wrap (eg, too many messages exchanged). */
-#define MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO       -0x6B00  /**< Unexpected message at ServerHello in renegotiation. */
-#define MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED             -0x6A80  /**< DTLS client must retry for hello verification */
-#define MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL                  -0x6A00  /**< A buffer is too small to receive or write a message */
-#define MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE             -0x6980  /**< None of the common ciphersuites is usable (eg, no suitable certificate, see debug messages). */
-#define MBEDTLS_ERR_SSL_WANT_READ                         -0x6900  /**< No data of requested type currently available on underlying transport. */
-#define MBEDTLS_ERR_SSL_WANT_WRITE                        -0x6880  /**< Connection requires a write call. */
-#define MBEDTLS_ERR_SSL_TIMEOUT                           -0x6800  /**< The operation timed out. */
-#define MBEDTLS_ERR_SSL_CLIENT_RECONNECT                  -0x6780  /**< The client initiated a reconnect from the same port. */
-#define MBEDTLS_ERR_SSL_UNEXPECTED_RECORD                 -0x6700  /**< Record header looks valid but is not expected. */
-#define MBEDTLS_ERR_SSL_NON_FATAL                         -0x6680  /**< The alert message received indicates a non-fatal error. */
-#define MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH               -0x6600  /**< Couldn't set the hash for verifying CertificateVerify */
-#define MBEDTLS_ERR_SSL_CONTINUE_PROCESSING               -0x6580  /**< Internal-only message signaling that further message-processing should be done */
-#define MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS                 -0x6500  /**< The asynchronous operation is not completed yet. */
-#define MBEDTLS_ERR_SSL_EARLY_MESSAGE                     -0x6480  /**< Internal-only message signaling that a message arrived early. */
-#define MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS                -0x7000  /**< A cryptographic operation is in progress. Try again later. */
-#define MBEDTLS_ERR_SSL_BAD_CONFIG                        -0x5E80  /**< Invalid value in SSL config */
+/** The requested feature is not available. */
+#define MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE               -0x7080
+/** Bad input parameters to function. */
+#define MBEDTLS_ERR_SSL_BAD_INPUT_DATA                    -0x7100
+/** Verification of the message MAC failed. */
+#define MBEDTLS_ERR_SSL_INVALID_MAC                       -0x7180
+/** An invalid SSL record was received. */
+#define MBEDTLS_ERR_SSL_INVALID_RECORD                    -0x7200
+/** The connection indicated an EOF. */
+#define MBEDTLS_ERR_SSL_CONN_EOF                          -0x7280
+/** An unknown cipher was received. */
+#define MBEDTLS_ERR_SSL_UNKNOWN_CIPHER                    -0x7300
+/** The server has no ciphersuites in common with the client. */
+#define MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN                  -0x7380
+/** No RNG was provided to the SSL module. */
+#define MBEDTLS_ERR_SSL_NO_RNG                            -0x7400
+/** No client certification received from the client, but required by the authentication mode. */
+#define MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE             -0x7480
+/** Our own certificate(s) is/are too large to send in an SSL message. */
+#define MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE             -0x7500
+/** The own certificate is not set, but needed by the server. */
+#define MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED              -0x7580
+/** The own private key or pre-shared key is not set, but needed. */
+#define MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED              -0x7600
+/** No CA Chain is set, but required to operate. */
+#define MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED                 -0x7680
+/** An unexpected message was received from our peer. */
+#define MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE                -0x7700
+/** A fatal alert message was received from our peer. */
+#define MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE               -0x7780
+/** Verification of our peer failed. */
+#define MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED                -0x7800
+/** The peer notified us that the connection is going to be closed. */
+#define MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY                 -0x7880
+/** Processing of the ClientHello handshake message failed. */
+#define MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO               -0x7900
+/** Processing of the ServerHello handshake message failed. */
+#define MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO               -0x7980
+/** Processing of the Certificate handshake message failed. */
+#define MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE                -0x7A00
+/** Processing of the CertificateRequest handshake message failed. */
+#define MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST        -0x7A80
+/** Processing of the ServerKeyExchange handshake message failed. */
+#define MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE        -0x7B00
+/** Processing of the ServerHelloDone handshake message failed. */
+#define MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE          -0x7B80
+/** Processing of the ClientKeyExchange handshake message failed. */
+#define MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE        -0x7C00
+/** Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Read Public. */
+#define MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP     -0x7C80
+/** Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Calculate Secret. */
+#define MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS     -0x7D00
+/** Processing of the CertificateVerify handshake message failed. */
+#define MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY         -0x7D80
+/** Processing of the ChangeCipherSpec handshake message failed. */
+#define MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC         -0x7E00
+/** Processing of the Finished handshake message failed. */
+#define MBEDTLS_ERR_SSL_BAD_HS_FINISHED                   -0x7E80
+/** Memory allocation failed */
+#define MBEDTLS_ERR_SSL_ALLOC_FAILED                      -0x7F00
+/** Hardware acceleration function returned with error */
+#define MBEDTLS_ERR_SSL_HW_ACCEL_FAILED                   -0x7F80
+/** Hardware acceleration function skipped / left alone data */
+#define MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH              -0x6F80
+/** Processing of the compression / decompression failed */
+#define MBEDTLS_ERR_SSL_COMPRESSION_FAILED                -0x6F00
+/** Handshake protocol not within min/max boundaries */
+#define MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION           -0x6E80
+/** Processing of the NewSessionTicket handshake message failed. */
+#define MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET         -0x6E00
+/** Session ticket has expired. */
+#define MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED            -0x6D80
+/** Public key type mismatch (eg, asked for RSA key exchange and presented EC key) */
+#define MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH                  -0x6D00
+/** Unknown identity received (eg, PSK identity) */
+#define MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY                  -0x6C80
+/** Internal error (eg, unexpected failure in lower-level module) */
+#define MBEDTLS_ERR_SSL_INTERNAL_ERROR                    -0x6C00
+/** A counter would wrap (eg, too many messages exchanged). */
+#define MBEDTLS_ERR_SSL_COUNTER_WRAPPING                  -0x6B80
+/** Unexpected message at ServerHello in renegotiation. */
+#define MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO       -0x6B00
+/** DTLS client must retry for hello verification */
+#define MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED             -0x6A80
+/** A buffer is too small to receive or write a message */
+#define MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL                  -0x6A00
+/** None of the common ciphersuites is usable (eg, no suitable certificate, see debug messages). */
+#define MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE             -0x6980
+/** No data of requested type currently available on underlying transport. */
+#define MBEDTLS_ERR_SSL_WANT_READ                         -0x6900
+/** Connection requires a write call. */
+#define MBEDTLS_ERR_SSL_WANT_WRITE                        -0x6880
+/** The operation timed out. */
+#define MBEDTLS_ERR_SSL_TIMEOUT                           -0x6800
+/** The client initiated a reconnect from the same port. */
+#define MBEDTLS_ERR_SSL_CLIENT_RECONNECT                  -0x6780
+/** Record header looks valid but is not expected. */
+#define MBEDTLS_ERR_SSL_UNEXPECTED_RECORD                 -0x6700
+/** The alert message received indicates a non-fatal error. */
+#define MBEDTLS_ERR_SSL_NON_FATAL                         -0x6680
+/** Couldn't set the hash for verifying CertificateVerify */
+#define MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH               -0x6600
+/** Internal-only message signaling that further message-processing should be done */
+#define MBEDTLS_ERR_SSL_CONTINUE_PROCESSING               -0x6580
+/** The asynchronous operation is not completed yet. */
+#define MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS                 -0x6500
+/** Internal-only message signaling that a message arrived early. */
+#define MBEDTLS_ERR_SSL_EARLY_MESSAGE                     -0x6480
+/** A cryptographic operation is in progress. Try again later. */
+#define MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS                -0x7000
+/** Invalid value in SSL config */
+#define MBEDTLS_ERR_SSL_BAD_CONFIG                        -0x5E80
 
 /*
  * Various constants
@@ -506,10 +562,11 @@
  * \param buf      Buffer to write the received data to
  * \param len      Length of the receive buffer
  *
- * \return         The callback must return the number of bytes received,
- *                 or a non-zero error code.
- *                 If performing non-blocking I/O, \c MBEDTLS_ERR_SSL_WANT_READ
+ * \returns        If data has been received, the positive number of bytes received.
+ * \returns        \c 0 if the connection has been closed.
+ * \returns        If performing non-blocking I/O, \c MBEDTLS_ERR_SSL_WANT_READ
  *                 must be returned when the operation would block.
+ * \returns        Another negative error code on other kinds of failures.
  *
  * \note           The callback may receive fewer bytes than the length of the
  *                 buffer. It must always return the number of bytes actually
@@ -2237,7 +2294,7 @@
 #if defined(MBEDTLS_ECP_C)
 /**
  * \brief          Set the allowed curves in order of preference.
- *                 (Default: all defined curves.)
+ *                 (Default: all defined curves in order of decreasing size.)
  *
  *                 On server: this only affects selection of the ECDHE curve;
  *                 the curves used for ECDH and ECDSA are determined by the
@@ -2269,7 +2326,9 @@
 #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
 /**
  * \brief          Set the allowed hashes for signatures during the handshake.
- *                 (Default: all available hashes except MD5.)
+ *                 (Default: all SHA-2 hashes, largest first. Also SHA-1 if
+ *                 the compile-time option
+ *                 `MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE` is enabled.)
  *
  * \note           This only affects which hashes are offered and can be used
  *                 for signatures during the handshake. Hashes for message
diff --git a/include/mbedtls/ssl_ticket.h b/include/mbedtls/ssl_ticket.h
index a10a434..a83f5e6 100644
--- a/include/mbedtls/ssl_ticket.h
+++ b/include/mbedtls/ssl_ticket.h
@@ -124,7 +124,7 @@
  *                  Recommended value: 86400 (one day).
  *
  * \note            It is highly recommended to select a cipher that is at
- *                  least as strong as the the strongest ciphersuite
+ *                  least as strong as the strongest ciphersuite
  *                  supported. Usually that means a 256-bit key.
  *
  * \note            The lifetime of the keys is twice the lifetime of tickets.
diff --git a/include/mbedtls/threading.h b/include/mbedtls/threading.h
index a8183a6..2cf0716 100644
--- a/include/mbedtls/threading.h
+++ b/include/mbedtls/threading.h
@@ -63,16 +63,22 @@
 
 /* MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE is deprecated and should not be
  * used. */
-#define MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE         -0x001A  /**< The selected feature is not available. */
+/** The selected feature is not available. */
+#define MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE         -0x001A
 
-#define MBEDTLS_ERR_THREADING_BAD_INPUT_DATA              -0x001C  /**< Bad input parameters to function. */
-#define MBEDTLS_ERR_THREADING_MUTEX_ERROR                 -0x001E  /**< Locking / unlocking / free failed with error code. */
+/** Bad input parameters to function. */
+#define MBEDTLS_ERR_THREADING_BAD_INPUT_DATA              -0x001C
+/** Locking / unlocking / free failed with error code. */
+#define MBEDTLS_ERR_THREADING_MUTEX_ERROR                 -0x001E
 
 #if defined(MBEDTLS_THREADING_PTHREAD)
 #include <pthread.h>
 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 5f0a8f1..49cbeb0 100644
--- a/include/mbedtls/version.h
+++ b/include/mbedtls/version.h
@@ -65,16 +65,16 @@
  */
 #define MBEDTLS_VERSION_MAJOR  2
 #define MBEDTLS_VERSION_MINOR  16
-#define MBEDTLS_VERSION_PATCH  9
+#define MBEDTLS_VERSION_PATCH  11
 
 /**
  * The single version number has the following structure:
  *    MMNNPP00
  *    Major version | Minor version | Patch version
  */
-#define MBEDTLS_VERSION_NUMBER         0x02100900
-#define MBEDTLS_VERSION_STRING         "2.16.9"
-#define MBEDTLS_VERSION_STRING_FULL    "mbed TLS 2.16.9"
+#define MBEDTLS_VERSION_NUMBER         0x02100B00
+#define MBEDTLS_VERSION_STRING         "2.16.11"
+#define MBEDTLS_VERSION_STRING_FULL    "mbed TLS 2.16.11"
 
 #if defined(MBEDTLS_VERSION_C)
 
diff --git a/include/mbedtls/x509.h b/include/mbedtls/x509.h
index 5bb9b00..fea4357 100644
--- a/include/mbedtls/x509.h
+++ b/include/mbedtls/x509.h
@@ -83,26 +83,46 @@
  * \name X509 Error codes
  * \{
  */
-#define MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE              -0x2080  /**< Unavailable feature, e.g. RSA hashing/encryption combination. */
-#define MBEDTLS_ERR_X509_UNKNOWN_OID                      -0x2100  /**< Requested OID is unknown. */
-#define MBEDTLS_ERR_X509_INVALID_FORMAT                   -0x2180  /**< The CRT/CRL/CSR format is invalid, e.g. different type expected. */
-#define MBEDTLS_ERR_X509_INVALID_VERSION                  -0x2200  /**< The CRT/CRL/CSR version element is invalid. */
-#define MBEDTLS_ERR_X509_INVALID_SERIAL                   -0x2280  /**< The serial tag or value is invalid. */
-#define MBEDTLS_ERR_X509_INVALID_ALG                      -0x2300  /**< The algorithm tag or value is invalid. */
-#define MBEDTLS_ERR_X509_INVALID_NAME                     -0x2380  /**< The name tag or value is invalid. */
-#define MBEDTLS_ERR_X509_INVALID_DATE                     -0x2400  /**< The date tag or value is invalid. */
-#define MBEDTLS_ERR_X509_INVALID_SIGNATURE                -0x2480  /**< The signature tag or value invalid. */
-#define MBEDTLS_ERR_X509_INVALID_EXTENSIONS               -0x2500  /**< The extension tag or value is invalid. */
-#define MBEDTLS_ERR_X509_UNKNOWN_VERSION                  -0x2580  /**< CRT/CRL/CSR has an unsupported version number. */
-#define MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG                  -0x2600  /**< Signature algorithm (oid) is unsupported. */
-#define MBEDTLS_ERR_X509_SIG_MISMATCH                     -0x2680  /**< Signature algorithms do not match. (see \c ::mbedtls_x509_crt sig_oid) */
-#define MBEDTLS_ERR_X509_CERT_VERIFY_FAILED               -0x2700  /**< Certificate verification failed, e.g. CRL, CA or signature check failed. */
-#define MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT              -0x2780  /**< Format not recognized as DER or PEM. */
-#define MBEDTLS_ERR_X509_BAD_INPUT_DATA                   -0x2800  /**< Input invalid. */
-#define MBEDTLS_ERR_X509_ALLOC_FAILED                     -0x2880  /**< Allocation of memory failed. */
-#define MBEDTLS_ERR_X509_FILE_IO_ERROR                    -0x2900  /**< Read/write of file failed. */
-#define MBEDTLS_ERR_X509_BUFFER_TOO_SMALL                 -0x2980  /**< Destination buffer is too small. */
-#define MBEDTLS_ERR_X509_FATAL_ERROR                      -0x3000  /**< A fatal error occurred, eg the chain is too long or the vrfy callback failed. */
+/** Unavailable feature, e.g. RSA hashing/encryption combination. */
+#define MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE              -0x2080
+/** Requested OID is unknown. */
+#define MBEDTLS_ERR_X509_UNKNOWN_OID                      -0x2100
+/** The CRT/CRL/CSR format is invalid, e.g. different type expected. */
+#define MBEDTLS_ERR_X509_INVALID_FORMAT                   -0x2180
+/** The CRT/CRL/CSR version element is invalid. */
+#define MBEDTLS_ERR_X509_INVALID_VERSION                  -0x2200
+/** The serial tag or value is invalid. */
+#define MBEDTLS_ERR_X509_INVALID_SERIAL                   -0x2280
+/** The algorithm tag or value is invalid. */
+#define MBEDTLS_ERR_X509_INVALID_ALG                      -0x2300
+/** The name tag or value is invalid. */
+#define MBEDTLS_ERR_X509_INVALID_NAME                     -0x2380
+/** The date tag or value is invalid. */
+#define MBEDTLS_ERR_X509_INVALID_DATE                     -0x2400
+/** The signature tag or value invalid. */
+#define MBEDTLS_ERR_X509_INVALID_SIGNATURE                -0x2480
+/** The extension tag or value is invalid. */
+#define MBEDTLS_ERR_X509_INVALID_EXTENSIONS               -0x2500
+/** CRT/CRL/CSR has an unsupported version number. */
+#define MBEDTLS_ERR_X509_UNKNOWN_VERSION                  -0x2580
+/** Signature algorithm (oid) is unsupported. */
+#define MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG                  -0x2600
+/** Signature algorithms do not match. (see \c ::mbedtls_x509_crt sig_oid) */
+#define MBEDTLS_ERR_X509_SIG_MISMATCH                     -0x2680
+/** Certificate verification failed, e.g. CRL, CA or signature check failed. */
+#define MBEDTLS_ERR_X509_CERT_VERIFY_FAILED               -0x2700
+/** Format not recognized as DER or PEM. */
+#define MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT              -0x2780
+/** Input invalid. */
+#define MBEDTLS_ERR_X509_BAD_INPUT_DATA                   -0x2800
+/** Allocation of memory failed. */
+#define MBEDTLS_ERR_X509_ALLOC_FAILED                     -0x2880
+/** Read/write of file failed. */
+#define MBEDTLS_ERR_X509_FILE_IO_ERROR                    -0x2900
+/** Destination buffer is too small. */
+#define MBEDTLS_ERR_X509_BUFFER_TOO_SMALL                 -0x2980
+/** A fatal error occurred, eg the chain is too long or the vrfy callback failed. */
+#define MBEDTLS_ERR_X509_FATAL_ERROR                      -0x3000
 /* \} name */
 
 /**
diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h
index c38e0c0..30da190 100644
--- a/include/mbedtls/x509_crt.h
+++ b/include/mbedtls/x509_crt.h
@@ -229,12 +229,21 @@
 /**
  * Default security profile. Should provide a good balance between security
  * and compatibility with current deployments.
+ *
+ * This profile permits:
+ * - SHA2 hashes.
+ * - All supported elliptic curves.
+ * - RSA with 2048 bits and above.
+ *
+ * New minor versions of Mbed TLS may extend this profile, for example if
+ * new curves are added to the library. New minor versions of Mbed TLS will
+ * not reduce this profile unless serious security concerns require it.
  */
 extern const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default;
 
 /**
  * Expected next default profile. Recommended for new deployments.
- * Currently targets a 128-bit security level, except for RSA-2048.
+ * Currently targets a 128-bit security level, except for allowing RSA-2048.
  */
 extern const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_next;
 
diff --git a/include/mbedtls/xtea.h b/include/mbedtls/xtea.h
index cd6d375..41a1bc8 100644
--- a/include/mbedtls/xtea.h
+++ b/include/mbedtls/xtea.h
@@ -61,10 +61,12 @@
 #define MBEDTLS_XTEA_ENCRYPT     1
 #define MBEDTLS_XTEA_DECRYPT     0
 
-#define MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH             -0x0028  /**< The data input has an invalid length. */
+/** The data input has an invalid length. */
+#define MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH             -0x0028
 
 /* MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED is deprecated and should not be used. */
-#define MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED                  -0x0029  /**< XTEA hardware accelerator failed. */
+/** XTEA hardware accelerator failed. */
+#define MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED                  -0x0029
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index 8002cdb..0afdde7 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -165,15 +165,15 @@
 
 if(USE_SHARED_MBEDTLS_LIBRARY)
     add_library(mbedcrypto SHARED ${src_crypto})
-    set_target_properties(mbedcrypto PROPERTIES VERSION 2.16.9 SOVERSION 3)
+    set_target_properties(mbedcrypto PROPERTIES VERSION 2.16.11 SOVERSION 3)
     target_link_libraries(mbedcrypto ${libs})
 
     add_library(mbedx509 SHARED ${src_x509})
-    set_target_properties(mbedx509 PROPERTIES VERSION 2.16.9 SOVERSION 0)
+    set_target_properties(mbedx509 PROPERTIES VERSION 2.16.11 SOVERSION 0)
     target_link_libraries(mbedx509 ${libs} mbedcrypto)
 
     add_library(mbedtls SHARED ${src_tls})
-    set_target_properties(mbedtls PROPERTIES VERSION 2.16.9 SOVERSION 12)
+    set_target_properties(mbedtls PROPERTIES VERSION 2.16.11 SOVERSION 12)
     target_link_libraries(mbedtls ${libs} mbedx509)
 
     install(TARGETS mbedtls mbedx509 mbedcrypto
diff --git a/library/aria.c b/library/aria.c
index ef0392f..50ccb91 100644
--- a/library/aria.c
+++ b/library/aria.c
@@ -952,7 +952,7 @@
         {                                   \
             if( verbose )                   \
                 mbedtls_printf( "failed\n" );       \
-            return( 1 );                    \
+            goto exit;                              \
         } else {                            \
             if( verbose )                   \
                 mbedtls_printf( "passed\n" );       \
@@ -966,6 +966,7 @@
     int i;
     uint8_t blk[MBEDTLS_ARIA_BLOCKSIZE];
     mbedtls_aria_context ctx;
+    int ret = 1;
 
 #if (defined(MBEDTLS_CIPHER_MODE_CFB) || defined(MBEDTLS_CIPHER_MODE_CTR))
     size_t j;
@@ -977,6 +978,8 @@
     uint8_t buf[48], iv[MBEDTLS_ARIA_BLOCKSIZE];
 #endif
 
+    mbedtls_aria_init( &ctx );
+
     /*
      * Test set 1
      */
@@ -1096,7 +1099,11 @@
         mbedtls_printf( "\n" );
 #endif /* MBEDTLS_CIPHER_MODE_CTR */
 
-    return( 0 );
+    ret = 0;
+
+exit:
+    mbedtls_aria_free( &ctx );
+    return( ret );
 }
 
 #endif /* MBEDTLS_SELF_TEST */
diff --git a/library/base64.c b/library/base64.c
index bfafb05..692e11e 100644
--- a/library/base64.c
+++ b/library/base64.c
@@ -97,6 +97,99 @@
 #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
  */
 int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
@@ -136,10 +229,17 @@
         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 @@
         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 @@
     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 @@
         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 @@
         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 2feb727..3df9052 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -267,6 +267,36 @@
     memcpy(  Y, &T, sizeof( mbedtls_mpi ) );
 }
 
+/**
+ * Select between two sign values in constant-time.
+ *
+ * This is functionally equivalent to second ? a : b but uses only bit
+ * operations in order to avoid branches.
+ *
+ * \param[in] a         The first sign; must be either +1 or -1.
+ * \param[in] b         The second sign; must be either +1 or -1.
+ * \param[in] second    Must be either 1 (return b) or 0 (return a).
+ *
+ * \return The selected sign value.
+ */
+static int mpi_safe_cond_select_sign( int a, int b, unsigned char second )
+{
+    /* In order to avoid questions about what we can reasonnably assume about
+     * the representations of signed integers, move everything to unsigned
+     * by taking advantage of the fact that a and b are either +1 or -1. */
+    unsigned ua = a + 1;
+    unsigned ub = b + 1;
+
+    /* second was 0 or 1, mask is 0 or 2 as are ua and ub */
+    const unsigned mask = second << 1;
+
+    /* select ua or ub */
+    unsigned ur = ( ua & ~mask ) | ( ub & mask );
+
+    /* ur is now 0 or 2, convert back to -1 or +1 */
+    return( (int) ur - 1 );
+}
+
 /*
  * Conditionally assign dest = src, without leaking information
  * about whether the assignment was made or not.
@@ -279,8 +309,23 @@
                                   unsigned char assign )
 {
     size_t i;
+
+    /* 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
+
+    /* all-bits 1 if assign is 1, all-bits 0 if assign is 0 */
+    const mbedtls_mpi_uint mask = -assign;
+
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+
     for( i = 0; i < n; i++ )
-        dest[i] = dest[i] * ( 1 - assign ) + src[i] * assign;
+        dest[i] = ( src[i] & mask ) | ( dest[i] & ~mask );
 }
 
 /*
@@ -292,20 +337,34 @@
 {
     int ret = 0;
     size_t i;
+    mbedtls_mpi_uint limb_mask;
     MPI_VALIDATE_RET( X != NULL );
     MPI_VALIDATE_RET( Y != NULL );
 
+    /* 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
+
     /* make sure assign is 0 or 1 in a time-constant manner */
-    assign = (assign | (unsigned char)-assign) >> 7;
+    assign = (assign | (unsigned char)-assign) >> (sizeof( assign ) * 8 - 1);
+    /* all-bits 1 if assign is 1, all-bits 0 if assign is 0 */
+    limb_mask = -assign;
+
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
 
     MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
 
-    X->s = X->s * ( 1 - assign ) + Y->s * assign;
+    X->s = mpi_safe_cond_select_sign( X->s, Y->s, assign );
 
     mpi_safe_cond_assign( Y->n, X->p, Y->p, assign );
 
     for( i = Y->n; i < X->n; i++ )
-        X->p[i] *= ( 1 - assign );
+        X->p[i] &= ~limb_mask;
 
 cleanup:
     return( ret );
@@ -321,6 +380,7 @@
 {
     int ret, s;
     size_t i;
+    mbedtls_mpi_uint limb_mask;
     mbedtls_mpi_uint tmp;
     MPI_VALIDATE_RET( X != NULL );
     MPI_VALIDATE_RET( Y != NULL );
@@ -328,22 +388,35 @@
     if( X == Y )
         return( 0 );
 
+    /* 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
+
     /* make sure swap is 0 or 1 in a time-constant manner */
-    swap = (swap | (unsigned char)-swap) >> 7;
+    swap = (swap | (unsigned char)-swap) >> (sizeof( swap ) * 8 - 1);
+    /* all-bits 1 if swap is 1, all-bits 0 if swap is 0 */
+    limb_mask = -swap;
+
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
 
     MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
     MBEDTLS_MPI_CHK( mbedtls_mpi_grow( Y, X->n ) );
 
     s = X->s;
-    X->s = X->s * ( 1 - swap ) + Y->s * swap;
-    Y->s = Y->s * ( 1 - swap ) +    s * swap;
+    X->s = mpi_safe_cond_select_sign( X->s, Y->s, swap );
+    Y->s = mpi_safe_cond_select_sign( Y->s, s, swap );
 
 
     for( i = 0; i < X->n; i++ )
     {
         tmp = X->p[i];
-        X->p[i] = X->p[i] * ( 1 - swap ) + Y->p[i] * swap;
-        Y->p[i] = Y->p[i] * ( 1 - swap ) +     tmp * swap;
+        X->p[i] = ( X->p[i] & ~limb_mask ) | ( Y->p[i] & limb_mask );
+        Y->p[i] = ( Y->p[i] & ~limb_mask ) | (     tmp & limb_mask );
     }
 
 cleanup:
@@ -500,6 +573,7 @@
 {
     int ret;
     size_t i, j, slen, n;
+    int sign = 1;
     mbedtls_mpi_uint d;
     mbedtls_mpi T;
     MPI_VALIDATE_RET( X != NULL );
@@ -510,6 +584,12 @@
 
     mbedtls_mpi_init( &T );
 
+    if( s[0] == '-' )
+    {
+        ++s;
+        sign = -1;
+    }
+
     slen = strlen( s );
 
     if( radix == 16 )
@@ -524,12 +604,6 @@
 
         for( i = slen, j = 0; i > 0; i--, j++ )
         {
-            if( i == 1 && s[i - 1] == '-' )
-            {
-                X->s = -1;
-                break;
-            }
-
             MBEDTLS_MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) );
             X->p[j / ( 2 * ciL )] |= d << ( ( j % ( 2 * ciL ) ) << 2 );
         }
@@ -540,26 +614,15 @@
 
         for( i = 0; i < slen; i++ )
         {
-            if( i == 0 && s[i] == '-' )
-            {
-                X->s = -1;
-                continue;
-            }
-
             MBEDTLS_MPI_CHK( mpi_get_digit( &d, radix, s[i] ) );
             MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T, X, radix ) );
-
-            if( X->s == 1 )
-            {
-                MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, &T, d ) );
-            }
-            else
-            {
-                MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( X, &T, d ) );
-            }
+            MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, &T, d ) );
         }
     }
 
+    if( sign < 0 && mbedtls_mpi_bitlen( X ) != 0 )
+        X->s = -1;
+
 cleanup:
 
     mbedtls_mpi_free( &T );
@@ -1354,6 +1417,12 @@
     for( n = B->n; n > 0; n-- )
         if( B->p[n - 1] != 0 )
             break;
+    if( n > A->n )
+    {
+        /* B >= (2^ciL)^n > A */
+        ret = MBEDTLS_ERR_MPI_NEGATIVE_VALUE;
+        goto cleanup;
+    }
 
     carry = mpi_sub_hlp( n, X->p, B->p );
     if( carry != 0 )
@@ -1453,17 +1522,17 @@
  */
 int mbedtls_mpi_add_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b )
 {
-    mbedtls_mpi _B;
+    mbedtls_mpi B;
     mbedtls_mpi_uint p[1];
     MPI_VALIDATE_RET( X != NULL );
     MPI_VALIDATE_RET( A != NULL );
 
     p[0] = ( b < 0 ) ? -b : b;
-    _B.s = ( b < 0 ) ? -1 : 1;
-    _B.n = 1;
-    _B.p = p;
+    B.s = ( b < 0 ) ? -1 : 1;
+    B.n = 1;
+    B.p = p;
 
-    return( mbedtls_mpi_add_mpi( X, A, &_B ) );
+    return( mbedtls_mpi_add_mpi( X, A, &B ) );
 }
 
 /*
@@ -1471,17 +1540,17 @@
  */
 int mbedtls_mpi_sub_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b )
 {
-    mbedtls_mpi _B;
+    mbedtls_mpi B;
     mbedtls_mpi_uint p[1];
     MPI_VALIDATE_RET( X != NULL );
     MPI_VALIDATE_RET( A != NULL );
 
     p[0] = ( b < 0 ) ? -b : b;
-    _B.s = ( b < 0 ) ? -1 : 1;
-    _B.n = 1;
-    _B.p = p;
+    B.s = ( b < 0 ) ? -1 : 1;
+    B.n = 1;
+    B.p = p;
 
-    return( mbedtls_mpi_sub_mpi( X, A, &_B ) );
+    return( mbedtls_mpi_sub_mpi( X, A, &B ) );
 }
 
 /*
@@ -1564,6 +1633,7 @@
     int ret;
     size_t i, j;
     mbedtls_mpi TA, TB;
+    int result_is_zero = 0;
     MPI_VALIDATE_RET( X != NULL );
     MPI_VALIDATE_RET( A != NULL );
     MPI_VALIDATE_RET( B != NULL );
@@ -1576,10 +1646,14 @@
     for( i = A->n; i > 0; i-- )
         if( A->p[i - 1] != 0 )
             break;
+    if( i == 0 )
+        result_is_zero = 1;
 
     for( j = B->n; j > 0; j-- )
         if( B->p[j - 1] != 0 )
             break;
+    if( j == 0 )
+        result_is_zero = 1;
 
     MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i + j ) );
     MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
@@ -1587,7 +1661,14 @@
     for( ; j > 0; j-- )
         mpi_mul_hlp( i, A->p, X->p + j - 1, B->p[j - 1] );
 
-    X->s = A->s * B->s;
+    /* If the result is 0, we don't shortcut the operation, which reduces
+     * but does not eliminate side channels leaking the zero-ness. We do
+     * need to take care to set the sign bit properly since the library does
+     * not fully support an MPI object with a value of 0 and s == -1. */
+    if( result_is_zero )
+        X->s = 1;
+    else
+        X->s = A->s * B->s;
 
 cleanup:
 
@@ -1601,17 +1682,17 @@
  */
 int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint b )
 {
-    mbedtls_mpi _B;
+    mbedtls_mpi B;
     mbedtls_mpi_uint p[1];
     MPI_VALIDATE_RET( X != NULL );
     MPI_VALIDATE_RET( A != NULL );
 
-    _B.s = 1;
-    _B.n = 1;
-    _B.p = p;
+    B.s = 1;
+    B.n = 1;
+    B.p = p;
     p[0] = b;
 
-    return( mbedtls_mpi_mul_mpi( X, A, &_B ) );
+    return( mbedtls_mpi_mul_mpi( X, A, &B ) );
 }
 
 /*
@@ -1835,16 +1916,16 @@
                          const mbedtls_mpi *A,
                          mbedtls_mpi_sint b )
 {
-    mbedtls_mpi _B;
+    mbedtls_mpi B;
     mbedtls_mpi_uint p[1];
     MPI_VALIDATE_RET( A != NULL );
 
     p[0] = ( b < 0 ) ? -b : b;
-    _B.s = ( b < 0 ) ? -1 : 1;
-    _B.n = 1;
-    _B.p = p;
+    B.s = ( b < 0 ) ? -1 : 1;
+    B.n = 1;
+    B.p = p;
 
-    return( mbedtls_mpi_div_mpi( Q, R, A, &_B ) );
+    return( mbedtls_mpi_div_mpi( Q, R, A, &B ) );
 }
 
 /*
@@ -2036,18 +2117,84 @@
 }
 
 /*
+ * Constant-flow boolean "equal" comparison:
+ * return x == y
+ *
+ * This function can be used to write constant-time code by replacing branches
+ * with bit operations - it can be used in conjunction with
+ * mbedtls_ssl_cf_mask_from_bit().
+ *
+ * This function is implemented without using comparison operators, as those
+ * might be translated to branches by some compilers on some platforms.
+ */
+static size_t mbedtls_mpi_cf_bool_eq( size_t x, size_t y )
+{
+    /* diff = 0 if x == y, non-zero otherwise */
+    const size_t diff = x ^ y;
+
+    /* 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
+
+    /* diff_msb's most significant bit is equal to x != y */
+    const size_t diff_msb = ( diff | (size_t) -diff );
+
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+
+    /* diff1 = (x != y) ? 1 : 0 */
+    const size_t diff1 = diff_msb >> ( sizeof( diff_msb ) * 8 - 1 );
+
+    return( 1 ^ diff1 );
+}
+
+/**
+ * Select an MPI from a table without leaking the index.
+ *
+ * This is functionally equivalent to mbedtls_mpi_copy(R, T[idx]) except it
+ * reads the entire table in order to avoid leaking the value of idx to an
+ * attacker able to observe memory access patterns.
+ *
+ * \param[out] R        Where to write the selected MPI.
+ * \param[in] T         The table to read from.
+ * \param[in] T_size    The number of elements in the table.
+ * \param[in] idx       The index of the element to select;
+ *                      this must satisfy 0 <= idx < T_size.
+ *
+ * \return \c 0 on success, or a negative error code.
+ */
+static int mpi_select( mbedtls_mpi *R, const mbedtls_mpi *T, size_t T_size, size_t idx )
+{
+    int ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
+    size_t i;
+
+    for( i = 0; i < T_size; i++ )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( R, &T[i],
+                        (unsigned char) mbedtls_mpi_cf_bool_eq( i, idx ) ) );
+    }
+
+cleanup:
+    return( ret );
+}
+
+/*
  * Sliding-window exponentiation: X = A^E mod N  (HAC 14.85)
  */
 int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
                          const mbedtls_mpi *E, const mbedtls_mpi *N,
-                         mbedtls_mpi *_RR )
+                         mbedtls_mpi *prec_RR )
 {
     int ret;
     size_t wbits, wsize, one = 1;
     size_t i, j, nblimbs;
     size_t bufsize, nbits;
     mbedtls_mpi_uint ei, mm, state;
-    mbedtls_mpi RR, T, W[ 1 << MBEDTLS_MPI_WINDOW_SIZE ], Apos;
+    mbedtls_mpi RR, T, W[ 1 << MBEDTLS_MPI_WINDOW_SIZE ], WW, Apos;
     int neg;
 
     MPI_VALIDATE_RET( X != NULL );
@@ -2071,6 +2218,7 @@
     mpi_montg_init( &mm, N );
     mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &T );
     mbedtls_mpi_init( &Apos );
+    mbedtls_mpi_init( &WW );
     memset( W, 0, sizeof( W ) );
 
     i = mbedtls_mpi_bitlen( E );
@@ -2084,6 +2232,11 @@
 #endif
 
     j = N->n + 1;
+    /* All W[i] and X must have at least N->n limbs for the mpi_montmul()
+     * and mpi_montred() calls later. Here we ensure that W[1] and X are
+     * large enough, and later we'll grow other W[i] to the same length.
+     * They must not be shrunk midway through this function!
+     */
     MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) );
     MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[1],  j ) );
     MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T, j * 2 ) );
@@ -2102,17 +2255,17 @@
     /*
      * If 1st call, pre-compute R^2 mod N
      */
-    if( _RR == NULL || _RR->p == NULL )
+    if( prec_RR == NULL || prec_RR->p == NULL )
     {
         MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &RR, 1 ) );
         MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &RR, N->n * 2 * biL ) );
         MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &RR, &RR, N ) );
 
-        if( _RR != NULL )
-            memcpy( _RR, &RR, sizeof( mbedtls_mpi ) );
+        if( prec_RR != NULL )
+            memcpy( prec_RR, &RR, sizeof( mbedtls_mpi ) );
     }
     else
-        memcpy( &RR, _RR, sizeof( mbedtls_mpi ) );
+        memcpy( &RR, prec_RR, sizeof( mbedtls_mpi ) );
 
     /*
      * W[1] = A * R^2 * R^-1 mod N = A * R mod N
@@ -2121,6 +2274,10 @@
         MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &W[1], A, N ) );
     else
         MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[1], A ) );
+    /* Re-grow W[1] if necessary. This should be only necessary in one corner
+     * case: when A == 0 represented with A.n == 0, mbedtls_mpi_copy shrinks
+     * W[1] to 0 limbs. */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[1], N->n +1 ) );
 
     mpi_montmul( &W[1], &RR, N, mm, &T );
 
@@ -2211,7 +2368,8 @@
             /*
              * X = X * W[wbits] R^-1 mod N
              */
-            mpi_montmul( X, &W[wbits], N, mm, &T );
+            MBEDTLS_MPI_CHK( mpi_select( &WW, W, (size_t) 1 << wsize, wbits ) );
+            mpi_montmul( X, &WW, N, mm, &T );
 
             state--;
             nbits = 0;
@@ -2249,8 +2407,9 @@
         mbedtls_mpi_free( &W[i] );
 
     mbedtls_mpi_free( &W[1] ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &Apos );
+    mbedtls_mpi_free( &WW );
 
-    if( _RR == NULL || _RR->p == NULL )
+    if( prec_RR == NULL || prec_RR->p == NULL )
         mbedtls_mpi_free( &RR );
 
     return( ret );
@@ -2277,6 +2436,16 @@
     lz = mbedtls_mpi_lsb( &TA );
     lzt = mbedtls_mpi_lsb( &TB );
 
+    /* The loop below gives the correct result when A==0 but not when B==0.
+     * So have a special case for B==0. Leverage the fact that we just
+     * calculated the lsb and lsb(B)==0 iff B is odd or 0 to make the test
+     * slightly more efficient than cmp_int(). */
+    if( lzt == 0 && mbedtls_mpi_get_bit( &TB, 0 ) == 0 )
+    {
+        ret = mbedtls_mpi_copy( G, A );
+        goto cleanup;
+    }
+
     if( lzt < lz )
         lz = lzt;
 
@@ -2285,11 +2454,52 @@
 
     TA.s = TB.s = 1;
 
+    /* We mostly follow the procedure described in HAC 14.54, but with some
+     * minor differences:
+     * - Sequences of multiplications or divisions by 2 are grouped into a
+     *   single shift operation.
+     * - The procedure in HAC assumes that 0 < TB <= TA.
+     *     - The condition TB <= TA is not actually necessary for correctness.
+     *       TA and TB have symmetric roles except for the loop termination
+     *       condition, and the shifts at the beginning of the loop body
+     *       remove any significance from the ordering of TA vs TB before
+     *       the shifts.
+     *     - If TA = 0, the loop goes through 0 iterations and the result is
+     *       correctly TB.
+     *     - The case TB = 0 was short-circuited above.
+     *
+     * For the correctness proof below, decompose the original values of
+     * A and B as
+     *   A = sa * 2^a * A' with A'=0 or A' odd, and sa = +-1
+     *   B = sb * 2^b * B' with B'=0 or B' odd, and sb = +-1
+     * Then gcd(A, B) = 2^{min(a,b)} * gcd(A',B'),
+     * and gcd(A',B') is odd or 0.
+     *
+     * At the beginning, we have TA = |A|/2^a and TB = |B|/2^b.
+     * The code maintains the following invariant:
+     *     gcd(A,B) = 2^k * gcd(TA,TB) for some k   (I)
+     */
+
+    /* Proof that the loop terminates:
+     * At each iteration, either the right-shift by 1 is made on a nonzero
+     * value and the nonnegative integer bitlen(TA) + bitlen(TB) decreases
+     * by at least 1, or the right-shift by 1 is made on zero and then
+     * TA becomes 0 which ends the loop (TB cannot be 0 if it is right-shifted
+     * since in that case TB is calculated from TB-TA with the condition TB>TA).
+     */
     while( mbedtls_mpi_cmp_int( &TA, 0 ) != 0 )
     {
+        /* Divisions by 2 preserve the invariant (I). */
         MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, mbedtls_mpi_lsb( &TA ) ) );
         MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, mbedtls_mpi_lsb( &TB ) ) );
 
+        /* Set either TA or TB to |TA-TB|/2. Since TA and TB are both odd,
+         * TA-TB is even so the division by 2 has an integer result.
+         * Invariant (I) is preserved since any odd divisor of both TA and TB
+         * also divides |TA-TB|/2, and any odd divisor of both TA and |TA-TB|/2
+         * also divides TB, and any odd divisior of both TB and |TA-TB|/2 also
+         * divides TA.
+         */
         if( mbedtls_mpi_cmp_mpi( &TA, &TB ) >= 0 )
         {
             MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &TA, &TA, &TB ) );
@@ -2300,8 +2510,18 @@
             MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &TB, &TB, &TA ) );
             MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, 1 ) );
         }
+        /* Note that one of TA or TB is still odd. */
     }
 
+    /* By invariant (I), gcd(A,B) = 2^k * gcd(TA,TB) for some k.
+     * At the loop exit, TA = 0, so gcd(TA,TB) = TB.
+     * - If there was at least one loop iteration, then one of TA or TB is odd,
+     *   and TA = 0, so TB is odd and gcd(TA,TB) = gcd(A',B'). In this case,
+     *   lz = min(a,b) so gcd(A,B) = 2^lz * TB.
+     * - If there was no loop iteration, then A was 0, and gcd(A,B) = B.
+     *   In this case, lz = 0 and B = TB so gcd(A,B) = B = 2^lz * TB as well.
+     */
+
     MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &TB, lz ) );
     MBEDTLS_MPI_CHK( mbedtls_mpi_copy( G, &TB ) );
 
diff --git a/library/camellia.c b/library/camellia.c
index 40d6212..6cf265e 100644
--- a/library/camellia.c
+++ b/library/camellia.c
@@ -973,9 +973,11 @@
     unsigned char nonce_counter[16];
     unsigned char stream_block[16];
 #endif
+    int ret = 1;
 
     mbedtls_camellia_context ctx;
 
+    mbedtls_camellia_init( &ctx );
     memset( key, 0, 32 );
 
     for( j = 0; j < 6; j++ ) {
@@ -1005,8 +1007,7 @@
         {
             if( verbose != 0 )
                 mbedtls_printf( "failed\n" );
-
-            return( 1 );
+            goto exit;
         }
     }
 
@@ -1058,8 +1059,7 @@
             {
                 if( verbose != 0 )
                     mbedtls_printf( "failed\n" );
-
-                return( 1 );
+                goto exit;
             }
         }
 
@@ -1102,8 +1102,7 @@
             {
                 if( verbose != 0 )
                     mbedtls_printf( "failed\n" );
-
-                return( 1 );
+                goto exit;
             }
         }
         else
@@ -1118,8 +1117,7 @@
             {
                 if( verbose != 0 )
                     mbedtls_printf( "failed\n" );
-
-                return( 1 );
+                goto exit;
             }
         }
 
@@ -1131,7 +1129,11 @@
         mbedtls_printf( "\n" );
 #endif /* MBEDTLS_CIPHER_MODE_CTR */
 
-    return( 0 );
+    ret = 0;
+
+exit:
+    mbedtls_camellia_free( &ctx );
+    return( ret );
 }
 
 #endif /* MBEDTLS_SELF_TEST */
diff --git a/library/ctr_drbg.c b/library/ctr_drbg.c
index e92008b..90264e8 100644
--- a/library/ctr_drbg.c
+++ b/library/ctr_drbg.c
@@ -83,10 +83,6 @@
     memset( ctx, 0, sizeof( mbedtls_ctr_drbg_context ) );
 
     ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
-
-#if defined(MBEDTLS_THREADING_C)
-    mbedtls_mutex_init( &ctx->mutex );
-#endif
 }
 
 /*
@@ -99,14 +95,13 @@
         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;
-#if defined(MBEDTLS_THREADING_C)
-    mbedtls_mutex_init( &ctx->mutex );
-#endif
 }
 
 void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx, int resistance )
@@ -422,6 +417,11 @@
 
     memset( key, 0, MBEDTLS_CTR_DRBG_KEYSIZE );
 
+    /* The mutex is initialized iff f_entropy is set. */
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_mutex_init( &ctx->mutex );
+#endif
+
     mbedtls_aes_init( &ctx->aes_ctx );
 
     ctx->f_entropy = f_entropy;
diff --git a/library/debug.c b/library/debug.c
index 5f06d0d..9caa361 100644
--- a/library/debug.c
+++ b/library/debug.c
@@ -261,8 +261,8 @@
                       const char *text, const mbedtls_mpi *X )
 {
     char str[DEBUG_BUF_SIZE];
-    int j, k, zeros = 1;
-    size_t i, n, idx = 0;
+    size_t bitlen;
+    size_t idx = 0;
 
     if( NULL == ssl              ||
         NULL == ssl->conf        ||
@@ -273,55 +273,43 @@
         return;
     }
 
-    for( n = X->n - 1; n > 0; n-- )
-        if( X->p[n] != 0 )
-            break;
+    bitlen = mbedtls_mpi_bitlen( X );
 
-    for( j = ( sizeof(mbedtls_mpi_uint) << 3 ) - 1; j >= 0; j-- )
-        if( ( ( X->p[n] >> j ) & 1 ) != 0 )
-            break;
-
-    mbedtls_snprintf( str + idx, sizeof( str ) - idx, "value of '%s' (%d bits) is:\n",
-              text, (int) ( ( n * ( sizeof(mbedtls_mpi_uint) << 3 ) ) + j + 1 ) );
-
+    mbedtls_snprintf( str, sizeof( str ), "value of '%s' (%u bits) is:\n",
+                      text, (unsigned) bitlen );
     debug_send_line( ssl, level, file, line, str );
 
-    idx = 0;
-    for( i = n + 1, j = 0; i > 0; i-- )
+    if( bitlen == 0 )
     {
-        if( zeros && X->p[i - 1] == 0 )
-            continue;
-
-        for( k = sizeof( mbedtls_mpi_uint ) - 1; k >= 0; k-- )
+        str[0] = ' '; str[1] = '0'; str[2] = '0';
+        idx = 3;
+    }
+    else
+    {
+        int n;
+        for( n = (int) ( ( bitlen - 1 ) / 8 ); n >= 0; n-- )
         {
-            if( zeros && ( ( X->p[i - 1] >> ( k << 3 ) ) & 0xFF ) == 0 )
-                continue;
-            else
-                zeros = 0;
-
-            if( j % 16 == 0 )
+            size_t limb_offset = n / sizeof( mbedtls_mpi_uint );
+            size_t offset_in_limb = n % sizeof( mbedtls_mpi_uint );
+            unsigned char octet =
+                ( X->p[limb_offset] >> ( offset_in_limb * 8 ) ) & 0xff;
+            mbedtls_snprintf( str + idx, sizeof( str ) - idx, " %02x", octet );
+            idx += 3;
+            /* Wrap lines after 16 octets that each take 3 columns */
+            if( idx >= 3 * 16 )
             {
-                if( j > 0 )
-                {
-                    mbedtls_snprintf( str + idx, sizeof( str ) - idx, "\n" );
-                    debug_send_line( ssl, level, file, line, str );
-                    idx = 0;
-                }
+                mbedtls_snprintf( str + idx, sizeof( str ) - idx, "\n" );
+                debug_send_line( ssl, level, file, line, str );
+                idx = 0;
             }
-
-            idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, " %02x", (unsigned int)
-                             ( X->p[i - 1] >> ( k << 3 ) ) & 0xFF );
-
-            j++;
         }
-
     }
 
-    if( zeros == 1 )
-        idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, " 00" );
-
-    mbedtls_snprintf( str + idx, sizeof( str ) - idx, "\n" );
-    debug_send_line( ssl, level, file, line, str );
+    if( idx != 0 )
+    {
+        mbedtls_snprintf( str + idx, sizeof( str ) - idx, "\n" );
+        debug_send_line( ssl, level, file, line, str );
+    }
 }
 #endif /* MBEDTLS_BIGNUM_C */
 
diff --git a/library/dhm.c b/library/dhm.c
index d652cf0..535b698 100644
--- a/library/dhm.c
+++ b/library/dhm.c
@@ -130,22 +130,21 @@
  */
 static int dhm_check_range( const mbedtls_mpi *param, const mbedtls_mpi *P )
 {
-    mbedtls_mpi L, U;
+    mbedtls_mpi U;
     int ret = 0;
 
-    mbedtls_mpi_init( &L ); mbedtls_mpi_init( &U );
+    mbedtls_mpi_init( &U );
 
-    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &L, 2 ) );
     MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &U, P, 2 ) );
 
-    if( mbedtls_mpi_cmp_mpi( param, &L ) < 0 ||
+    if( mbedtls_mpi_cmp_int( param, 2 ) < 0 ||
         mbedtls_mpi_cmp_mpi( param, &U ) > 0 )
     {
         ret = MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
     }
 
 cleanup:
-    mbedtls_mpi_free( &L ); mbedtls_mpi_free( &U );
+    mbedtls_mpi_free( &U );
     return( ret );
 }
 
@@ -181,38 +180,54 @@
 }
 
 /*
- * Setup and write the ServerKeyExchange parameters
+ * Pick a random R in the range [2, M-2] for blinding or key generation.
  */
-int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
-                     unsigned char *output, size_t *olen,
-                     int (*f_rng)(void *, unsigned char *, size_t),
-                     void *p_rng )
+static int dhm_random_below( mbedtls_mpi *R, const mbedtls_mpi *M,
+                int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
 {
-    int ret, count = 0;
-    size_t n1, n2, n3;
-    unsigned char *p;
-    DHM_VALIDATE_RET( ctx != NULL );
-    DHM_VALIDATE_RET( output != NULL );
-    DHM_VALIDATE_RET( olen != NULL );
-    DHM_VALIDATE_RET( f_rng != NULL );
+    int ret, count;
+    size_t m_size = mbedtls_mpi_size( M );
+    size_t m_bitlen = mbedtls_mpi_bitlen( M );
+
+    count = 0;
+    do
+    {
+        if( count++ > 30 )
+            return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
+
+        MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( R, m_size, f_rng, p_rng ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( R, ( m_size * 8 ) - m_bitlen ) );
+    }
+    while( dhm_check_range( R, M ) != 0 );
+
+cleanup:
+    return( ret );
+}
+
+static int dhm_make_common( mbedtls_dhm_context *ctx, int x_size,
+                            int (*f_rng)(void *, unsigned char *, size_t),
+                            void *p_rng )
+{
+    int ret = 0;
 
     if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 )
         return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
+    if( x_size < 0 )
+        return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
 
-    /*
-     * Generate X as large as possible ( < P )
-     */
-    do
+    if( (unsigned) x_size < mbedtls_mpi_size( &ctx->P ) )
     {
         MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ) );
-
-        while( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 )
-            MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->X, 1 ) );
-
-        if( count++ > 10 )
-            return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED );
     }
-    while( dhm_check_range( &ctx->X, &ctx->P ) != 0 );
+    else
+    {
+        /* Generate X as large as possible ( <= P - 2 ) */
+        ret = dhm_random_below( &ctx->X, &ctx->P, f_rng, p_rng );
+        if( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
+            return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED );
+        if( ret != 0 )
+            return( ret );
+    }
 
     /*
      * Calculate GX = G^X mod P
@@ -223,8 +238,33 @@
     if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 )
         return( ret );
 
+cleanup:
+    return( ret );
+}
+
+/*
+ * Setup and write the ServerKeyExchange parameters
+ */
+int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
+                     unsigned char *output, size_t *olen,
+                     int (*f_rng)(void *, unsigned char *, size_t),
+                     void *p_rng )
+{
+    int ret;
+    size_t n1, n2, n3;
+    unsigned char *p;
+    DHM_VALIDATE_RET( ctx != NULL );
+    DHM_VALIDATE_RET( output != NULL );
+    DHM_VALIDATE_RET( olen != NULL );
+    DHM_VALIDATE_RET( f_rng != NULL );
+
+    ret = dhm_make_common( ctx, x_size, f_rng, p_rng );
+    if( ret != 0 )
+        goto cleanup;
+
     /*
-     * export P, G, GX
+     * Export P, G, GX. RFC 5246 §4.4 states that "leading zero octets are
+     * not required". We omit leading zeros for compactness.
      */
 #define DHM_MPI_EXPORT( X, n )                                          \
     do {                                                                \
@@ -250,11 +290,9 @@
     ctx->len = n1;
 
 cleanup:
-
-    if( ret != 0 )
+    if( ret != 0 && ret > -128 )
         return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED + ret );
-
-    return( 0 );
+    return( ret );
 }
 
 /*
@@ -306,7 +344,7 @@
                      int (*f_rng)(void *, unsigned char *, size_t),
                      void *p_rng )
 {
-    int ret, count = 0;
+    int ret;
     DHM_VALIDATE_RET( ctx != NULL );
     DHM_VALIDATE_RET( output != NULL );
     DHM_VALIDATE_RET( f_rng != NULL );
@@ -314,62 +352,18 @@
     if( olen < 1 || olen > ctx->len )
         return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
 
-    if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 )
-        return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
-
-    /*
-     * generate X and calculate GX = G^X mod P
-     */
-    do
-    {
-        MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ) );
-
-        while( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 )
-            MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->X, 1 ) );
-
-        if( count++ > 10 )
-            return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED );
-    }
-    while( dhm_check_range( &ctx->X, &ctx->P ) != 0 );
-
-    MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X,
-                          &ctx->P , &ctx->RP ) );
-
-    if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 )
-        return( ret );
+    ret = dhm_make_common( ctx, x_size, f_rng, p_rng );
+    if( ret == MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED )
+        return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED );
+    if( ret != 0 )
+        goto cleanup;
 
     MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->GX, output, olen ) );
 
 cleanup:
-
-    if( ret != 0 )
+    if( ret != 0 && ret > -128 )
         return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED + ret );
 
-    return( 0 );
-}
-
-/*
- * Pick a random R in the range [2, M) for blinding purposes
- */
-static int dhm_random_below( mbedtls_mpi *R, const mbedtls_mpi *M,
-                int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
-{
-    int ret, count;
-
-    count = 0;
-    do
-    {
-        MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( R, mbedtls_mpi_size( M ), f_rng, p_rng ) );
-
-        while( mbedtls_mpi_cmp_mpi( R, M ) >= 0 )
-            MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( R, 1 ) );
-
-        if( count++ > 10 )
-            return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
-    }
-    while( mbedtls_mpi_cmp_int( R, 1 ) <= 0 );
-
-cleanup:
     return( ret );
 }
 
@@ -420,7 +414,7 @@
      * We need to generate blinding values from scratch
      */
 
-    /* Vi = random( 2, P-1 ) */
+    /* Vi = random( 2, P-2 ) */
     MBEDTLS_MPI_CHK( dhm_random_below( &ctx->Vi, &ctx->P, f_rng, p_rng ) );
 
     /* Vf = Vi^-X mod P
@@ -484,8 +478,9 @@
         MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->K, &ctx->K, &ctx->P ) );
     }
 
+    /* Output the secret without any leading zero byte. This is mandatory
+     * for TLS per RFC 5246 §8.1.2. */
     *olen = mbedtls_mpi_size( &ctx->K );
-
     MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->K, output, *olen ) );
 
 cleanup:
diff --git a/library/ecdsa.c b/library/ecdsa.c
index da8df9c..2456238 100644
--- a/library/ecdsa.c
+++ b/library/ecdsa.c
@@ -247,6 +247,9 @@
 
 #endif /* MBEDTLS_ECP_RESTARTABLE */
 
+#if defined(MBEDTLS_ECDSA_DETERMINISTIC) || \
+    !defined(MBEDTLS_ECDSA_SIGN_ALT)     || \
+    !defined(MBEDTLS_ECDSA_VERIFY_ALT)
 /*
  * Derive a suitable integer for group grp from a buffer of length len
  * SEC1 4.1.3 step 5 aka SEC1 4.1.4 step 3
@@ -269,6 +272,7 @@
 cleanup:
     return( ret );
 }
+#endif /* ECDSA_DETERMINISTIC || !ECDSA_SIGN_ALT || !ECDSA_VERIFY_ALT */
 
 #if !defined(MBEDTLS_ECDSA_SIGN_ALT)
 /*
@@ -780,6 +784,8 @@
     (void) md_alg;
 
 #if defined(MBEDTLS_ECDSA_SIGN_ALT)
+    (void) rs_ctx;
+
     MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ctx->grp, &r, &s, &ctx->d,
                          hash, hlen, f_rng, p_rng ) );
 #else
@@ -888,6 +894,8 @@
         goto cleanup;
     }
 #if defined(MBEDTLS_ECDSA_VERIFY_ALT)
+    (void) rs_ctx;
+
     if( ( ret = mbedtls_ecdsa_verify( &ctx->grp, hash, hlen,
                                       &ctx->Q, &r, &s ) ) != 0 )
         goto cleanup;
diff --git a/library/ecjpake.c b/library/ecjpake.c
index f6e2458..0532a29 100644
--- a/library/ecjpake.c
+++ b/library/ecjpake.c
@@ -850,6 +850,8 @@
     0x65, 0x73, 0x74
 };
 
+#if !defined(MBEDTLS_ECJPAKE_ALT)
+
 static const unsigned char ecjpake_test_x1[] = {
     0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
     0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
@@ -994,6 +996,8 @@
     return( ret );
 }
 
+#endif /* ! MBEDTLS_ECJPAKE_ALT */
+
 /* For tests we don't need a secure RNG;
  * use the LGC from Numerical Recipes for simplicity */
 static int ecjpake_lgc( void *p, unsigned char *out, size_t len )
@@ -1089,6 +1093,12 @@
     if( verbose != 0 )
         mbedtls_printf( "passed\n" );
 
+#if !defined(MBEDTLS_ECJPAKE_ALT)
+    /* 'reference handshake' tests can only be run against implementations
+     * for which we have 100% control over how the random ephemeral keys
+     * are generated. This is only the case for the internal mbed TLS
+     * implementation, so these tests are skipped in case the internal
+     * implementation is swapped out for an alternative one. */
     if( verbose != 0 )
         mbedtls_printf( "  ECJPAKE test #2 (reference handshake): " );
 
@@ -1137,6 +1147,7 @@
 
     if( verbose != 0 )
         mbedtls_printf( "passed\n" );
+#endif /* ! MBEDTLS_ECJPAKE_ALT */
 
 cleanup:
     mbedtls_ecjpake_free( &cli );
diff --git a/library/ecp.c b/library/ecp.c
index fe41b41..a7486c1 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -106,6 +106,7 @@
 #include "mbedtls/ecp.h"
 #include "mbedtls/threading.h"
 #include "mbedtls/platform_util.h"
+#include "mbedtls/bn_mul.h"
 
 #include <string.h>
 
@@ -1738,18 +1739,17 @@
     /* Generate l such that 1 < l < p */
     do
     {
-        MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &l, p_size, f_rng, p_rng ) );
-
-        while( mbedtls_mpi_cmp_mpi( &l, &grp->P ) >= 0 )
-            MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &l, 1 ) );
-
-        if( count++ > 10 )
+        if( count++ > 30 )
         {
             ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
             goto cleanup;
         }
+
+        MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &l, p_size, f_rng, p_rng ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &l, ( p_size * 8 ) - grp->pbits ) );
     }
-    while( mbedtls_mpi_cmp_int( &l, 1 ) <= 0 );
+    while( ( mbedtls_mpi_cmp_int( &l, 1 ) <= 0 ) ||
+           ( mbedtls_mpi_cmp_mpi( &l, &grp->P ) >= 0 ) );
 
     /* Z = l * Z */
     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Z,   &pt->Z,     &l  ) ); MOD_MUL( pt->Z );
@@ -2505,7 +2505,7 @@
 
 #if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT)
     if( mbedtls_internal_ecp_grp_capable( grp ) )
-        return( mbedtls_internal_ecp_randomize_mxz( grp, P, f_rng, p_rng );
+        return( mbedtls_internal_ecp_randomize_mxz( grp, P, f_rng, p_rng ) );
 #endif /* MBEDTLS_ECP_RANDOMIZE_MXZ_ALT */
 
     p_size = ( grp->pbits + 7 ) / 8;
@@ -2514,18 +2514,17 @@
     /* Generate l such that 1 < l < p */
     do
     {
-        MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &l, p_size, f_rng, p_rng ) );
-
-        while( mbedtls_mpi_cmp_mpi( &l, &grp->P ) >= 0 )
-            MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &l, 1 ) );
-
-        if( count++ > 10 )
+        if( count++ > 30 )
         {
             ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
             goto cleanup;
         }
+
+        MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &l, p_size, f_rng, p_rng ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &l, ( p_size * 8 ) - grp->pbits ) );
     }
-    while( mbedtls_mpi_cmp_int( &l, 1 ) <= 0 );
+    while( ( mbedtls_mpi_cmp_int( &l, 1 ) <= 0 ) ||
+           ( mbedtls_mpi_cmp_mpi( &l, &grp->P ) >= 0 ) );
 
     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &P->X, &P->X, &l ) ); MOD_MUL( P->X );
     MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &P->Z, &P->Z, &l ) ); MOD_MUL( P->Z );
@@ -2970,6 +2969,97 @@
 }
 
 #if defined(ECP_MONTGOMERY)
+#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
+#define ECP_MPI_INIT(s, n, p) {s, (n), (mbedtls_mpi_uint *)(p)}
+#define ECP_MPI_INIT_ARRAY(x)   \
+    ECP_MPI_INIT(1, sizeof(x) / sizeof(mbedtls_mpi_uint), x)
+/*
+ * Constants for the two points other than 0, 1, -1 (mod p) in
+ * https://cr.yp.to/ecdh.html#validate
+ * See ecp_check_pubkey_x25519().
+ */
+static const mbedtls_mpi_uint x25519_bad_point_1[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x16, 0x56, 0xe3, 0xfa, 0xf1, 0x9f, 0xc4, 0x6a ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, 0xb1, 0xfd ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00 ),
+};
+static const mbedtls_mpi_uint x25519_bad_point_2[] = {
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5f, 0x9c, 0x95, 0xbc, 0xa3, 0x50, 0x8c, 0x24 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xb1, 0xd0, 0xb1, 0x55, 0x9c, 0x83, 0xef, 0x5b ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x04, 0x44, 0x5c, 0xc4, 0x58, 0x1c, 0x8e, 0x86 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xd8, 0x22, 0x4e, 0xdd, 0xd0, 0x9f, 0x11, 0x57 ),
+};
+static const mbedtls_mpi ecp_x25519_bad_point_1 = ECP_MPI_INIT_ARRAY(
+        x25519_bad_point_1 );
+static const mbedtls_mpi ecp_x25519_bad_point_2 = ECP_MPI_INIT_ARRAY(
+        x25519_bad_point_2 );
+#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
+
+/*
+ * Check that the input point is not one of the low-order points.
+ * This is recommended by the "May the Fourth" paper:
+ * https://eprint.iacr.org/2017/806.pdf
+ * Those points are never sent by an honest peer.
+ */
+static int ecp_check_bad_points_mx( const mbedtls_mpi *X, const mbedtls_mpi *P,
+                                    const mbedtls_ecp_group_id grp_id )
+{
+    int ret;
+    mbedtls_mpi XmP;
+
+    mbedtls_mpi_init( &XmP );
+
+    /* Reduce X mod P so that we only need to check values less than P.
+     * We know X < 2^256 so we can proceed by subtraction. */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &XmP, X ) );
+    while( mbedtls_mpi_cmp_mpi( &XmP, P ) >= 0 )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &XmP, &XmP, P ) );
+
+    /* Check against the known bad values that are less than P. For Curve448
+     * these are 0, 1 and -1. For Curve25519 we check the values less than P
+     * from the following list: https://cr.yp.to/ecdh.html#validate */
+    if( mbedtls_mpi_cmp_int( &XmP, 1 ) <= 0 ) /* takes care of 0 and 1 */
+    {
+        ret = MBEDTLS_ERR_ECP_INVALID_KEY;
+        goto cleanup;
+    }
+
+#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
+    if( grp_id == MBEDTLS_ECP_DP_CURVE25519 )
+    {
+        if( mbedtls_mpi_cmp_mpi( &XmP, &ecp_x25519_bad_point_1 ) == 0 )
+        {
+            ret = MBEDTLS_ERR_ECP_INVALID_KEY;
+            goto cleanup;
+        }
+
+        if( mbedtls_mpi_cmp_mpi( &XmP, &ecp_x25519_bad_point_2 ) == 0 )
+        {
+            ret = MBEDTLS_ERR_ECP_INVALID_KEY;
+            goto cleanup;
+        }
+    }
+#else
+    (void) grp_id;
+#endif
+
+    /* Final check: check if XmP + 1 is P (final because it changes XmP!) */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &XmP, &XmP, 1 ) );
+    if( mbedtls_mpi_cmp_mpi( &XmP, P ) == 0 )
+    {
+        ret = MBEDTLS_ERR_ECP_INVALID_KEY;
+        goto cleanup;
+    }
+
+    ret = 0;
+
+cleanup:
+    mbedtls_mpi_free( &XmP );
+
+    return( ret );
+}
+
 /*
  * Check validity of a public key for Montgomery curves with x-only schemes
  */
@@ -2981,7 +3071,13 @@
     if( mbedtls_mpi_size( &pt->X ) > ( grp->nbits + 7 ) / 8 )
         return( MBEDTLS_ERR_ECP_INVALID_KEY );
 
-    return( 0 );
+    /* Implicit in all standards (as they don't consider negative numbers):
+     * X must be non-negative. This is normally ensured by the way it's
+     * encoded for transmission, but let's be extra sure. */
+    if( mbedtls_mpi_cmp_int( &pt->X, 0 ) < 0 )
+        return( MBEDTLS_ERR_ECP_INVALID_KEY );
+
+    return( ecp_check_bad_points_mx( &pt->X, &grp->P, grp->id ) );
 }
 #endif /* ECP_MONTGOMERY */
 
@@ -3059,6 +3155,11 @@
 {
     int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
     size_t n_size;
+#if defined(ECP_SHORTWEIERSTRASS)
+    mbedtls_mpi one;
+
+    mbedtls_mpi_init( &one );
+#endif
 
     ECP_VALIDATE_RET( grp   != NULL );
     ECP_VALIDATE_RET( d     != NULL );
@@ -3099,7 +3200,10 @@
     {
         /* SEC1 3.2.1: Generate d such that 1 <= n < N */
         int count = 0;
-        unsigned cmp = 0;
+        unsigned lt_lower = 1, lt_upper = 0;
+
+        MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &one, grp->N.n ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &one, 1 ) );
 
         /*
          * Match the procedure given in RFC 6979 (deterministic ECDSA):
@@ -3123,19 +3227,22 @@
              * such as secp224k1 are actually very close to the worst case.
              */
             if( ++count > 30 )
-                return( MBEDTLS_ERR_ECP_RANDOM_FAILED );
-
-            ret = mbedtls_mpi_lt_mpi_ct( d, &grp->N, &cmp );
-            if( ret != 0 )
             {
+                ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
                 goto cleanup;
             }
+
+            MBEDTLS_MPI_CHK( mbedtls_mpi_lt_mpi_ct( d, &grp->N, &lt_upper ) );
+            MBEDTLS_MPI_CHK( mbedtls_mpi_lt_mpi_ct( d, &one, &lt_lower ) );
         }
-        while( mbedtls_mpi_cmp_int( d, 1 ) < 0 || cmp != 1 );
+        while( lt_lower != 0 || lt_upper == 0 );
     }
 #endif /* ECP_SHORTWEIERSTRASS */
 
 cleanup:
+#if defined(ECP_SHORTWEIERSTRASS)
+    mbedtls_mpi_free( &one );
+#endif
     return( ret );
 }
 
diff --git a/library/ecp_curves.c b/library/ecp_curves.c
index b04596b..afa3b63 100644
--- a/library/ecp_curves.c
+++ b/library/ecp_curves.c
@@ -54,6 +54,7 @@
 
 #include "mbedtls/ecp.h"
 #include "mbedtls/platform_util.h"
+#include "mbedtls/bn_mul.h"
 
 #include <string.h>
 
@@ -70,44 +71,10 @@
 #define inline __inline
 #endif
 
-/*
- * Conversion macros for embedded constants:
- * build lists of mbedtls_mpi_uint's from lists of unsigned char's grouped by 8, 4 or 2
- */
-#if defined(MBEDTLS_HAVE_INT32)
+#define ECP_MPI_INIT(s, n, p) {s, (n), (mbedtls_mpi_uint *)(p)}
 
-#define BYTES_TO_T_UINT_4( a, b, c, d )                       \
-    ( (mbedtls_mpi_uint) (a) <<  0 ) |                        \
-    ( (mbedtls_mpi_uint) (b) <<  8 ) |                        \
-    ( (mbedtls_mpi_uint) (c) << 16 ) |                        \
-    ( (mbedtls_mpi_uint) (d) << 24 )
-
-#define BYTES_TO_T_UINT_2( a, b )                   \
-    BYTES_TO_T_UINT_4( a, b, 0, 0 )
-
-#define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \
-    BYTES_TO_T_UINT_4( a, b, c, d ),                \
-    BYTES_TO_T_UINT_4( e, f, g, h )
-
-#else /* 64-bits */
-
-#define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \
-    ( (mbedtls_mpi_uint) (a) <<  0 ) |                        \
-    ( (mbedtls_mpi_uint) (b) <<  8 ) |                        \
-    ( (mbedtls_mpi_uint) (c) << 16 ) |                        \
-    ( (mbedtls_mpi_uint) (d) << 24 ) |                        \
-    ( (mbedtls_mpi_uint) (e) << 32 ) |                        \
-    ( (mbedtls_mpi_uint) (f) << 40 ) |                        \
-    ( (mbedtls_mpi_uint) (g) << 48 ) |                        \
-    ( (mbedtls_mpi_uint) (h) << 56 )
-
-#define BYTES_TO_T_UINT_4( a, b, c, d )             \
-    BYTES_TO_T_UINT_8( a, b, c, d, 0, 0, 0, 0 )
-
-#define BYTES_TO_T_UINT_2( a, b )                   \
-    BYTES_TO_T_UINT_8( a, b, 0, 0, 0, 0, 0, 0 )
-
-#endif /* bits in mbedtls_mpi_uint */
+#define ECP_MPI_INIT_ARRAY(x)   \
+    ECP_MPI_INIT(1, sizeof(x) / sizeof(mbedtls_mpi_uint), x)
 
 /*
  * Note: the constants are in little-endian order
@@ -119,29 +86,29 @@
  */
 #if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
 static const mbedtls_mpi_uint secp192r1_p[] = {
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
 };
 static const mbedtls_mpi_uint secp192r1_b[] = {
-    BYTES_TO_T_UINT_8( 0xB1, 0xB9, 0x46, 0xC1, 0xEC, 0xDE, 0xB8, 0xFE ),
-    BYTES_TO_T_UINT_8( 0x49, 0x30, 0x24, 0x72, 0xAB, 0xE9, 0xA7, 0x0F ),
-    BYTES_TO_T_UINT_8( 0xE7, 0x80, 0x9C, 0xE5, 0x19, 0x05, 0x21, 0x64 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB1, 0xB9, 0x46, 0xC1, 0xEC, 0xDE, 0xB8, 0xFE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x49, 0x30, 0x24, 0x72, 0xAB, 0xE9, 0xA7, 0x0F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE7, 0x80, 0x9C, 0xE5, 0x19, 0x05, 0x21, 0x64 ),
 };
 static const mbedtls_mpi_uint secp192r1_gx[] = {
-    BYTES_TO_T_UINT_8( 0x12, 0x10, 0xFF, 0x82, 0xFD, 0x0A, 0xFF, 0xF4 ),
-    BYTES_TO_T_UINT_8( 0x00, 0x88, 0xA1, 0x43, 0xEB, 0x20, 0xBF, 0x7C ),
-    BYTES_TO_T_UINT_8( 0xF6, 0x90, 0x30, 0xB0, 0x0E, 0xA8, 0x8D, 0x18 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x12, 0x10, 0xFF, 0x82, 0xFD, 0x0A, 0xFF, 0xF4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x88, 0xA1, 0x43, 0xEB, 0x20, 0xBF, 0x7C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF6, 0x90, 0x30, 0xB0, 0x0E, 0xA8, 0x8D, 0x18 ),
 };
 static const mbedtls_mpi_uint secp192r1_gy[] = {
-    BYTES_TO_T_UINT_8( 0x11, 0x48, 0x79, 0x1E, 0xA1, 0x77, 0xF9, 0x73 ),
-    BYTES_TO_T_UINT_8( 0xD5, 0xCD, 0x24, 0x6B, 0xED, 0x11, 0x10, 0x63 ),
-    BYTES_TO_T_UINT_8( 0x78, 0xDA, 0xC8, 0xFF, 0x95, 0x2B, 0x19, 0x07 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x11, 0x48, 0x79, 0x1E, 0xA1, 0x77, 0xF9, 0x73 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD5, 0xCD, 0x24, 0x6B, 0xED, 0x11, 0x10, 0x63 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x78, 0xDA, 0xC8, 0xFF, 0x95, 0x2B, 0x19, 0x07 ),
 };
 static const mbedtls_mpi_uint secp192r1_n[] = {
-    BYTES_TO_T_UINT_8( 0x31, 0x28, 0xD2, 0xB4, 0xB1, 0xC9, 0x6B, 0x14 ),
-    BYTES_TO_T_UINT_8( 0x36, 0xF8, 0xDE, 0x99, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x31, 0x28, 0xD2, 0xB4, 0xB1, 0xC9, 0x6B, 0x14 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x36, 0xF8, 0xDE, 0x99, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
 };
 #endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
 
@@ -150,34 +117,34 @@
  */
 #if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
 static const mbedtls_mpi_uint secp224r1_p[] = {
-    BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
-    BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
 };
 static const mbedtls_mpi_uint secp224r1_b[] = {
-    BYTES_TO_T_UINT_8( 0xB4, 0xFF, 0x55, 0x23, 0x43, 0x39, 0x0B, 0x27 ),
-    BYTES_TO_T_UINT_8( 0xBA, 0xD8, 0xBF, 0xD7, 0xB7, 0xB0, 0x44, 0x50 ),
-    BYTES_TO_T_UINT_8( 0x56, 0x32, 0x41, 0xF5, 0xAB, 0xB3, 0x04, 0x0C ),
-    BYTES_TO_T_UINT_4( 0x85, 0x0A, 0x05, 0xB4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB4, 0xFF, 0x55, 0x23, 0x43, 0x39, 0x0B, 0x27 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBA, 0xD8, 0xBF, 0xD7, 0xB7, 0xB0, 0x44, 0x50 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x56, 0x32, 0x41, 0xF5, 0xAB, 0xB3, 0x04, 0x0C ),
+    MBEDTLS_BYTES_TO_T_UINT_4( 0x85, 0x0A, 0x05, 0xB4 ),
 };
 static const mbedtls_mpi_uint secp224r1_gx[] = {
-    BYTES_TO_T_UINT_8( 0x21, 0x1D, 0x5C, 0x11, 0xD6, 0x80, 0x32, 0x34 ),
-    BYTES_TO_T_UINT_8( 0x22, 0x11, 0xC2, 0x56, 0xD3, 0xC1, 0x03, 0x4A ),
-    BYTES_TO_T_UINT_8( 0xB9, 0x90, 0x13, 0x32, 0x7F, 0xBF, 0xB4, 0x6B ),
-    BYTES_TO_T_UINT_4( 0xBD, 0x0C, 0x0E, 0xB7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x21, 0x1D, 0x5C, 0x11, 0xD6, 0x80, 0x32, 0x34 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x22, 0x11, 0xC2, 0x56, 0xD3, 0xC1, 0x03, 0x4A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB9, 0x90, 0x13, 0x32, 0x7F, 0xBF, 0xB4, 0x6B ),
+    MBEDTLS_BYTES_TO_T_UINT_4( 0xBD, 0x0C, 0x0E, 0xB7 ),
 };
 static const mbedtls_mpi_uint secp224r1_gy[] = {
-    BYTES_TO_T_UINT_8( 0x34, 0x7E, 0x00, 0x85, 0x99, 0x81, 0xD5, 0x44 ),
-    BYTES_TO_T_UINT_8( 0x64, 0x47, 0x07, 0x5A, 0xA0, 0x75, 0x43, 0xCD ),
-    BYTES_TO_T_UINT_8( 0xE6, 0xDF, 0x22, 0x4C, 0xFB, 0x23, 0xF7, 0xB5 ),
-    BYTES_TO_T_UINT_4( 0x88, 0x63, 0x37, 0xBD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x34, 0x7E, 0x00, 0x85, 0x99, 0x81, 0xD5, 0x44 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x64, 0x47, 0x07, 0x5A, 0xA0, 0x75, 0x43, 0xCD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE6, 0xDF, 0x22, 0x4C, 0xFB, 0x23, 0xF7, 0xB5 ),
+    MBEDTLS_BYTES_TO_T_UINT_4( 0x88, 0x63, 0x37, 0xBD ),
 };
 static const mbedtls_mpi_uint secp224r1_n[] = {
-    BYTES_TO_T_UINT_8( 0x3D, 0x2A, 0x5C, 0x5C, 0x45, 0x29, 0xDD, 0x13 ),
-    BYTES_TO_T_UINT_8( 0x3E, 0xF0, 0xB8, 0xE0, 0xA2, 0x16, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3D, 0x2A, 0x5C, 0x5C, 0x45, 0x29, 0xDD, 0x13 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3E, 0xF0, 0xB8, 0xE0, 0xA2, 0x16, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ),
 };
 #endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
 
@@ -186,34 +153,34 @@
  */
 #if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
 static const mbedtls_mpi_uint secp256r1_p[] = {
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
-    BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
-    BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
 };
 static const mbedtls_mpi_uint secp256r1_b[] = {
-    BYTES_TO_T_UINT_8( 0x4B, 0x60, 0xD2, 0x27, 0x3E, 0x3C, 0xCE, 0x3B ),
-    BYTES_TO_T_UINT_8( 0xF6, 0xB0, 0x53, 0xCC, 0xB0, 0x06, 0x1D, 0x65 ),
-    BYTES_TO_T_UINT_8( 0xBC, 0x86, 0x98, 0x76, 0x55, 0xBD, 0xEB, 0xB3 ),
-    BYTES_TO_T_UINT_8( 0xE7, 0x93, 0x3A, 0xAA, 0xD8, 0x35, 0xC6, 0x5A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4B, 0x60, 0xD2, 0x27, 0x3E, 0x3C, 0xCE, 0x3B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF6, 0xB0, 0x53, 0xCC, 0xB0, 0x06, 0x1D, 0x65 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBC, 0x86, 0x98, 0x76, 0x55, 0xBD, 0xEB, 0xB3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE7, 0x93, 0x3A, 0xAA, 0xD8, 0x35, 0xC6, 0x5A ),
 };
 static const mbedtls_mpi_uint secp256r1_gx[] = {
-    BYTES_TO_T_UINT_8( 0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4 ),
-    BYTES_TO_T_UINT_8( 0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77 ),
-    BYTES_TO_T_UINT_8( 0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8 ),
-    BYTES_TO_T_UINT_8( 0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B ),
 };
 static const mbedtls_mpi_uint secp256r1_gy[] = {
-    BYTES_TO_T_UINT_8( 0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB ),
-    BYTES_TO_T_UINT_8( 0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B ),
-    BYTES_TO_T_UINT_8( 0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E ),
-    BYTES_TO_T_UINT_8( 0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F ),
 };
 static const mbedtls_mpi_uint secp256r1_n[] = {
-    BYTES_TO_T_UINT_8( 0x51, 0x25, 0x63, 0xFC, 0xC2, 0xCA, 0xB9, 0xF3 ),
-    BYTES_TO_T_UINT_8( 0x84, 0x9E, 0x17, 0xA7, 0xAD, 0xFA, 0xE6, 0xBC ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x51, 0x25, 0x63, 0xFC, 0xC2, 0xCA, 0xB9, 0xF3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x84, 0x9E, 0x17, 0xA7, 0xAD, 0xFA, 0xE6, 0xBC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
 };
 #endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
 
@@ -222,44 +189,44 @@
  */
 #if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
 static const mbedtls_mpi_uint secp384r1_p[] = {
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
-    BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
 };
 static const mbedtls_mpi_uint secp384r1_b[] = {
-    BYTES_TO_T_UINT_8( 0xEF, 0x2A, 0xEC, 0xD3, 0xED, 0xC8, 0x85, 0x2A ),
-    BYTES_TO_T_UINT_8( 0x9D, 0xD1, 0x2E, 0x8A, 0x8D, 0x39, 0x56, 0xC6 ),
-    BYTES_TO_T_UINT_8( 0x5A, 0x87, 0x13, 0x50, 0x8F, 0x08, 0x14, 0x03 ),
-    BYTES_TO_T_UINT_8( 0x12, 0x41, 0x81, 0xFE, 0x6E, 0x9C, 0x1D, 0x18 ),
-    BYTES_TO_T_UINT_8( 0x19, 0x2D, 0xF8, 0xE3, 0x6B, 0x05, 0x8E, 0x98 ),
-    BYTES_TO_T_UINT_8( 0xE4, 0xE7, 0x3E, 0xE2, 0xA7, 0x2F, 0x31, 0xB3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEF, 0x2A, 0xEC, 0xD3, 0xED, 0xC8, 0x85, 0x2A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9D, 0xD1, 0x2E, 0x8A, 0x8D, 0x39, 0x56, 0xC6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5A, 0x87, 0x13, 0x50, 0x8F, 0x08, 0x14, 0x03 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x12, 0x41, 0x81, 0xFE, 0x6E, 0x9C, 0x1D, 0x18 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x19, 0x2D, 0xF8, 0xE3, 0x6B, 0x05, 0x8E, 0x98 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE4, 0xE7, 0x3E, 0xE2, 0xA7, 0x2F, 0x31, 0xB3 ),
 };
 static const mbedtls_mpi_uint secp384r1_gx[] = {
-    BYTES_TO_T_UINT_8( 0xB7, 0x0A, 0x76, 0x72, 0x38, 0x5E, 0x54, 0x3A ),
-    BYTES_TO_T_UINT_8( 0x6C, 0x29, 0x55, 0xBF, 0x5D, 0xF2, 0x02, 0x55 ),
-    BYTES_TO_T_UINT_8( 0x38, 0x2A, 0x54, 0x82, 0xE0, 0x41, 0xF7, 0x59 ),
-    BYTES_TO_T_UINT_8( 0x98, 0x9B, 0xA7, 0x8B, 0x62, 0x3B, 0x1D, 0x6E ),
-    BYTES_TO_T_UINT_8( 0x74, 0xAD, 0x20, 0xF3, 0x1E, 0xC7, 0xB1, 0x8E ),
-    BYTES_TO_T_UINT_8( 0x37, 0x05, 0x8B, 0xBE, 0x22, 0xCA, 0x87, 0xAA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB7, 0x0A, 0x76, 0x72, 0x38, 0x5E, 0x54, 0x3A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6C, 0x29, 0x55, 0xBF, 0x5D, 0xF2, 0x02, 0x55 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x38, 0x2A, 0x54, 0x82, 0xE0, 0x41, 0xF7, 0x59 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x98, 0x9B, 0xA7, 0x8B, 0x62, 0x3B, 0x1D, 0x6E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x74, 0xAD, 0x20, 0xF3, 0x1E, 0xC7, 0xB1, 0x8E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x37, 0x05, 0x8B, 0xBE, 0x22, 0xCA, 0x87, 0xAA ),
 };
 static const mbedtls_mpi_uint secp384r1_gy[] = {
-    BYTES_TO_T_UINT_8( 0x5F, 0x0E, 0xEA, 0x90, 0x7C, 0x1D, 0x43, 0x7A ),
-    BYTES_TO_T_UINT_8( 0x9D, 0x81, 0x7E, 0x1D, 0xCE, 0xB1, 0x60, 0x0A ),
-    BYTES_TO_T_UINT_8( 0xC0, 0xB8, 0xF0, 0xB5, 0x13, 0x31, 0xDA, 0xE9 ),
-    BYTES_TO_T_UINT_8( 0x7C, 0x14, 0x9A, 0x28, 0xBD, 0x1D, 0xF4, 0xF8 ),
-    BYTES_TO_T_UINT_8( 0x29, 0xDC, 0x92, 0x92, 0xBF, 0x98, 0x9E, 0x5D ),
-    BYTES_TO_T_UINT_8( 0x6F, 0x2C, 0x26, 0x96, 0x4A, 0xDE, 0x17, 0x36 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5F, 0x0E, 0xEA, 0x90, 0x7C, 0x1D, 0x43, 0x7A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9D, 0x81, 0x7E, 0x1D, 0xCE, 0xB1, 0x60, 0x0A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC0, 0xB8, 0xF0, 0xB5, 0x13, 0x31, 0xDA, 0xE9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7C, 0x14, 0x9A, 0x28, 0xBD, 0x1D, 0xF4, 0xF8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x29, 0xDC, 0x92, 0x92, 0xBF, 0x98, 0x9E, 0x5D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6F, 0x2C, 0x26, 0x96, 0x4A, 0xDE, 0x17, 0x36 ),
 };
 static const mbedtls_mpi_uint secp384r1_n[] = {
-    BYTES_TO_T_UINT_8( 0x73, 0x29, 0xC5, 0xCC, 0x6A, 0x19, 0xEC, 0xEC ),
-    BYTES_TO_T_UINT_8( 0x7A, 0xA7, 0xB0, 0x48, 0xB2, 0x0D, 0x1A, 0x58 ),
-    BYTES_TO_T_UINT_8( 0xDF, 0x2D, 0x37, 0xF4, 0x81, 0x4D, 0x63, 0xC7 ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x73, 0x29, 0xC5, 0xCC, 0x6A, 0x19, 0xEC, 0xEC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7A, 0xA7, 0xB0, 0x48, 0xB2, 0x0D, 0x1A, 0x58 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDF, 0x2D, 0x37, 0xF4, 0x81, 0x4D, 0x63, 0xC7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
 };
 #endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
 
@@ -268,154 +235,154 @@
  */
 #if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
 static const mbedtls_mpi_uint secp521r1_p[] = {
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_2( 0xFF, 0x01 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_2( 0xFF, 0x01 ),
 };
 static const mbedtls_mpi_uint secp521r1_b[] = {
-    BYTES_TO_T_UINT_8( 0x00, 0x3F, 0x50, 0x6B, 0xD4, 0x1F, 0x45, 0xEF ),
-    BYTES_TO_T_UINT_8( 0xF1, 0x34, 0x2C, 0x3D, 0x88, 0xDF, 0x73, 0x35 ),
-    BYTES_TO_T_UINT_8( 0x07, 0xBF, 0xB1, 0x3B, 0xBD, 0xC0, 0x52, 0x16 ),
-    BYTES_TO_T_UINT_8( 0x7B, 0x93, 0x7E, 0xEC, 0x51, 0x39, 0x19, 0x56 ),
-    BYTES_TO_T_UINT_8( 0xE1, 0x09, 0xF1, 0x8E, 0x91, 0x89, 0xB4, 0xB8 ),
-    BYTES_TO_T_UINT_8( 0xF3, 0x15, 0xB3, 0x99, 0x5B, 0x72, 0xDA, 0xA2 ),
-    BYTES_TO_T_UINT_8( 0xEE, 0x40, 0x85, 0xB6, 0xA0, 0x21, 0x9A, 0x92 ),
-    BYTES_TO_T_UINT_8( 0x1F, 0x9A, 0x1C, 0x8E, 0x61, 0xB9, 0x3E, 0x95 ),
-    BYTES_TO_T_UINT_2( 0x51, 0x00 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x3F, 0x50, 0x6B, 0xD4, 0x1F, 0x45, 0xEF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF1, 0x34, 0x2C, 0x3D, 0x88, 0xDF, 0x73, 0x35 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x07, 0xBF, 0xB1, 0x3B, 0xBD, 0xC0, 0x52, 0x16 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7B, 0x93, 0x7E, 0xEC, 0x51, 0x39, 0x19, 0x56 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE1, 0x09, 0xF1, 0x8E, 0x91, 0x89, 0xB4, 0xB8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF3, 0x15, 0xB3, 0x99, 0x5B, 0x72, 0xDA, 0xA2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEE, 0x40, 0x85, 0xB6, 0xA0, 0x21, 0x9A, 0x92 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1F, 0x9A, 0x1C, 0x8E, 0x61, 0xB9, 0x3E, 0x95 ),
+    MBEDTLS_BYTES_TO_T_UINT_2( 0x51, 0x00 ),
 };
 static const mbedtls_mpi_uint secp521r1_gx[] = {
-    BYTES_TO_T_UINT_8( 0x66, 0xBD, 0xE5, 0xC2, 0x31, 0x7E, 0x7E, 0xF9 ),
-    BYTES_TO_T_UINT_8( 0x9B, 0x42, 0x6A, 0x85, 0xC1, 0xB3, 0x48, 0x33 ),
-    BYTES_TO_T_UINT_8( 0xDE, 0xA8, 0xFF, 0xA2, 0x27, 0xC1, 0x1D, 0xFE ),
-    BYTES_TO_T_UINT_8( 0x28, 0x59, 0xE7, 0xEF, 0x77, 0x5E, 0x4B, 0xA1 ),
-    BYTES_TO_T_UINT_8( 0xBA, 0x3D, 0x4D, 0x6B, 0x60, 0xAF, 0x28, 0xF8 ),
-    BYTES_TO_T_UINT_8( 0x21, 0xB5, 0x3F, 0x05, 0x39, 0x81, 0x64, 0x9C ),
-    BYTES_TO_T_UINT_8( 0x42, 0xB4, 0x95, 0x23, 0x66, 0xCB, 0x3E, 0x9E ),
-    BYTES_TO_T_UINT_8( 0xCD, 0xE9, 0x04, 0x04, 0xB7, 0x06, 0x8E, 0x85 ),
-    BYTES_TO_T_UINT_2( 0xC6, 0x00 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x66, 0xBD, 0xE5, 0xC2, 0x31, 0x7E, 0x7E, 0xF9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9B, 0x42, 0x6A, 0x85, 0xC1, 0xB3, 0x48, 0x33 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDE, 0xA8, 0xFF, 0xA2, 0x27, 0xC1, 0x1D, 0xFE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0x59, 0xE7, 0xEF, 0x77, 0x5E, 0x4B, 0xA1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBA, 0x3D, 0x4D, 0x6B, 0x60, 0xAF, 0x28, 0xF8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x21, 0xB5, 0x3F, 0x05, 0x39, 0x81, 0x64, 0x9C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x42, 0xB4, 0x95, 0x23, 0x66, 0xCB, 0x3E, 0x9E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCD, 0xE9, 0x04, 0x04, 0xB7, 0x06, 0x8E, 0x85 ),
+    MBEDTLS_BYTES_TO_T_UINT_2( 0xC6, 0x00 ),
 };
 static const mbedtls_mpi_uint secp521r1_gy[] = {
-    BYTES_TO_T_UINT_8( 0x50, 0x66, 0xD1, 0x9F, 0x76, 0x94, 0xBE, 0x88 ),
-    BYTES_TO_T_UINT_8( 0x40, 0xC2, 0x72, 0xA2, 0x86, 0x70, 0x3C, 0x35 ),
-    BYTES_TO_T_UINT_8( 0x61, 0x07, 0xAD, 0x3F, 0x01, 0xB9, 0x50, 0xC5 ),
-    BYTES_TO_T_UINT_8( 0x40, 0x26, 0xF4, 0x5E, 0x99, 0x72, 0xEE, 0x97 ),
-    BYTES_TO_T_UINT_8( 0x2C, 0x66, 0x3E, 0x27, 0x17, 0xBD, 0xAF, 0x17 ),
-    BYTES_TO_T_UINT_8( 0x68, 0x44, 0x9B, 0x57, 0x49, 0x44, 0xF5, 0x98 ),
-    BYTES_TO_T_UINT_8( 0xD9, 0x1B, 0x7D, 0x2C, 0xB4, 0x5F, 0x8A, 0x5C ),
-    BYTES_TO_T_UINT_8( 0x04, 0xC0, 0x3B, 0x9A, 0x78, 0x6A, 0x29, 0x39 ),
-    BYTES_TO_T_UINT_2( 0x18, 0x01 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x50, 0x66, 0xD1, 0x9F, 0x76, 0x94, 0xBE, 0x88 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x40, 0xC2, 0x72, 0xA2, 0x86, 0x70, 0x3C, 0x35 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x61, 0x07, 0xAD, 0x3F, 0x01, 0xB9, 0x50, 0xC5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x40, 0x26, 0xF4, 0x5E, 0x99, 0x72, 0xEE, 0x97 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2C, 0x66, 0x3E, 0x27, 0x17, 0xBD, 0xAF, 0x17 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x68, 0x44, 0x9B, 0x57, 0x49, 0x44, 0xF5, 0x98 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD9, 0x1B, 0x7D, 0x2C, 0xB4, 0x5F, 0x8A, 0x5C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x04, 0xC0, 0x3B, 0x9A, 0x78, 0x6A, 0x29, 0x39 ),
+    MBEDTLS_BYTES_TO_T_UINT_2( 0x18, 0x01 ),
 };
 static const mbedtls_mpi_uint secp521r1_n[] = {
-    BYTES_TO_T_UINT_8( 0x09, 0x64, 0x38, 0x91, 0x1E, 0xB7, 0x6F, 0xBB ),
-    BYTES_TO_T_UINT_8( 0xAE, 0x47, 0x9C, 0x89, 0xB8, 0xC9, 0xB5, 0x3B ),
-    BYTES_TO_T_UINT_8( 0xD0, 0xA5, 0x09, 0xF7, 0x48, 0x01, 0xCC, 0x7F ),
-    BYTES_TO_T_UINT_8( 0x6B, 0x96, 0x2F, 0xBF, 0x83, 0x87, 0x86, 0x51 ),
-    BYTES_TO_T_UINT_8( 0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_2( 0xFF, 0x01 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x09, 0x64, 0x38, 0x91, 0x1E, 0xB7, 0x6F, 0xBB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAE, 0x47, 0x9C, 0x89, 0xB8, 0xC9, 0xB5, 0x3B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD0, 0xA5, 0x09, 0xF7, 0x48, 0x01, 0xCC, 0x7F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6B, 0x96, 0x2F, 0xBF, 0x83, 0x87, 0x86, 0x51 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_2( 0xFF, 0x01 ),
 };
 #endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
 
 #if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
 static const mbedtls_mpi_uint secp192k1_p[] = {
-    BYTES_TO_T_UINT_8( 0x37, 0xEE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x37, 0xEE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
 };
 static const mbedtls_mpi_uint secp192k1_a[] = {
-    BYTES_TO_T_UINT_2( 0x00, 0x00 ),
+    MBEDTLS_BYTES_TO_T_UINT_2( 0x00, 0x00 ),
 };
 static const mbedtls_mpi_uint secp192k1_b[] = {
-    BYTES_TO_T_UINT_2( 0x03, 0x00 ),
+    MBEDTLS_BYTES_TO_T_UINT_2( 0x03, 0x00 ),
 };
 static const mbedtls_mpi_uint secp192k1_gx[] = {
-    BYTES_TO_T_UINT_8( 0x7D, 0x6C, 0xE0, 0xEA, 0xB1, 0xD1, 0xA5, 0x1D ),
-    BYTES_TO_T_UINT_8( 0x34, 0xF4, 0xB7, 0x80, 0x02, 0x7D, 0xB0, 0x26 ),
-    BYTES_TO_T_UINT_8( 0xAE, 0xE9, 0x57, 0xC0, 0x0E, 0xF1, 0x4F, 0xDB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7D, 0x6C, 0xE0, 0xEA, 0xB1, 0xD1, 0xA5, 0x1D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x34, 0xF4, 0xB7, 0x80, 0x02, 0x7D, 0xB0, 0x26 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAE, 0xE9, 0x57, 0xC0, 0x0E, 0xF1, 0x4F, 0xDB ),
 };
 static const mbedtls_mpi_uint secp192k1_gy[] = {
-    BYTES_TO_T_UINT_8( 0x9D, 0x2F, 0x5E, 0xD9, 0x88, 0xAA, 0x82, 0x40 ),
-    BYTES_TO_T_UINT_8( 0x34, 0x86, 0xBE, 0x15, 0xD0, 0x63, 0x41, 0x84 ),
-    BYTES_TO_T_UINT_8( 0xA7, 0x28, 0x56, 0x9C, 0x6D, 0x2F, 0x2F, 0x9B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x9D, 0x2F, 0x5E, 0xD9, 0x88, 0xAA, 0x82, 0x40 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x34, 0x86, 0xBE, 0x15, 0xD0, 0x63, 0x41, 0x84 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0x28, 0x56, 0x9C, 0x6D, 0x2F, 0x2F, 0x9B ),
 };
 static const mbedtls_mpi_uint secp192k1_n[] = {
-    BYTES_TO_T_UINT_8( 0x8D, 0xFD, 0xDE, 0x74, 0x6A, 0x46, 0x69, 0x0F ),
-    BYTES_TO_T_UINT_8( 0x17, 0xFC, 0xF2, 0x26, 0xFE, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8D, 0xFD, 0xDE, 0x74, 0x6A, 0x46, 0x69, 0x0F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x17, 0xFC, 0xF2, 0x26, 0xFE, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
 };
 #endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
 
 #if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
 static const mbedtls_mpi_uint secp224k1_p[] = {
-    BYTES_TO_T_UINT_8( 0x6D, 0xE5, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6D, 0xE5, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ),
 };
 static const mbedtls_mpi_uint secp224k1_a[] = {
-    BYTES_TO_T_UINT_2( 0x00, 0x00 ),
+    MBEDTLS_BYTES_TO_T_UINT_2( 0x00, 0x00 ),
 };
 static const mbedtls_mpi_uint secp224k1_b[] = {
-    BYTES_TO_T_UINT_2( 0x05, 0x00 ),
+    MBEDTLS_BYTES_TO_T_UINT_2( 0x05, 0x00 ),
 };
 static const mbedtls_mpi_uint secp224k1_gx[] = {
-    BYTES_TO_T_UINT_8( 0x5C, 0xA4, 0xB7, 0xB6, 0x0E, 0x65, 0x7E, 0x0F ),
-    BYTES_TO_T_UINT_8( 0xA9, 0x75, 0x70, 0xE4, 0xE9, 0x67, 0xA4, 0x69 ),
-    BYTES_TO_T_UINT_8( 0xA1, 0x28, 0xFC, 0x30, 0xDF, 0x99, 0xF0, 0x4D ),
-    BYTES_TO_T_UINT_4( 0x33, 0x5B, 0x45, 0xA1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5C, 0xA4, 0xB7, 0xB6, 0x0E, 0x65, 0x7E, 0x0F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA9, 0x75, 0x70, 0xE4, 0xE9, 0x67, 0xA4, 0x69 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA1, 0x28, 0xFC, 0x30, 0xDF, 0x99, 0xF0, 0x4D ),
+    MBEDTLS_BYTES_TO_T_UINT_4( 0x33, 0x5B, 0x45, 0xA1 ),
 };
 static const mbedtls_mpi_uint secp224k1_gy[] = {
-    BYTES_TO_T_UINT_8( 0xA5, 0x61, 0x6D, 0x55, 0xDB, 0x4B, 0xCA, 0xE2 ),
-    BYTES_TO_T_UINT_8( 0x59, 0xBD, 0xB0, 0xC0, 0xF7, 0x19, 0xE3, 0xF7 ),
-    BYTES_TO_T_UINT_8( 0xD6, 0xFB, 0xCA, 0x82, 0x42, 0x34, 0xBA, 0x7F ),
-    BYTES_TO_T_UINT_4( 0xED, 0x9F, 0x08, 0x7E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA5, 0x61, 0x6D, 0x55, 0xDB, 0x4B, 0xCA, 0xE2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x59, 0xBD, 0xB0, 0xC0, 0xF7, 0x19, 0xE3, 0xF7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD6, 0xFB, 0xCA, 0x82, 0x42, 0x34, 0xBA, 0x7F ),
+    MBEDTLS_BYTES_TO_T_UINT_4( 0xED, 0x9F, 0x08, 0x7E ),
 };
 static const mbedtls_mpi_uint secp224k1_n[] = {
-    BYTES_TO_T_UINT_8( 0xF7, 0xB1, 0x9F, 0x76, 0x71, 0xA9, 0xF0, 0xCA ),
-    BYTES_TO_T_UINT_8( 0x84, 0x61, 0xEC, 0xD2, 0xE8, 0xDC, 0x01, 0x00 ),
-    BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
-    BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF7, 0xB1, 0x9F, 0x76, 0x71, 0xA9, 0xF0, 0xCA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x84, 0x61, 0xEC, 0xD2, 0xE8, 0xDC, 0x01, 0x00 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ),
 };
 #endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
 
 #if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
 static const mbedtls_mpi_uint secp256k1_p[] = {
-    BYTES_TO_T_UINT_8( 0x2F, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x2F, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
 };
 static const mbedtls_mpi_uint secp256k1_a[] = {
-    BYTES_TO_T_UINT_2( 0x00, 0x00 ),
+    MBEDTLS_BYTES_TO_T_UINT_2( 0x00, 0x00 ),
 };
 static const mbedtls_mpi_uint secp256k1_b[] = {
-    BYTES_TO_T_UINT_2( 0x07, 0x00 ),
+    MBEDTLS_BYTES_TO_T_UINT_2( 0x07, 0x00 ),
 };
 static const mbedtls_mpi_uint secp256k1_gx[] = {
-    BYTES_TO_T_UINT_8( 0x98, 0x17, 0xF8, 0x16, 0x5B, 0x81, 0xF2, 0x59 ),
-    BYTES_TO_T_UINT_8( 0xD9, 0x28, 0xCE, 0x2D, 0xDB, 0xFC, 0x9B, 0x02 ),
-    BYTES_TO_T_UINT_8( 0x07, 0x0B, 0x87, 0xCE, 0x95, 0x62, 0xA0, 0x55 ),
-    BYTES_TO_T_UINT_8( 0xAC, 0xBB, 0xDC, 0xF9, 0x7E, 0x66, 0xBE, 0x79 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x98, 0x17, 0xF8, 0x16, 0x5B, 0x81, 0xF2, 0x59 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD9, 0x28, 0xCE, 0x2D, 0xDB, 0xFC, 0x9B, 0x02 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x07, 0x0B, 0x87, 0xCE, 0x95, 0x62, 0xA0, 0x55 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAC, 0xBB, 0xDC, 0xF9, 0x7E, 0x66, 0xBE, 0x79 ),
 };
 static const mbedtls_mpi_uint secp256k1_gy[] = {
-    BYTES_TO_T_UINT_8( 0xB8, 0xD4, 0x10, 0xFB, 0x8F, 0xD0, 0x47, 0x9C ),
-    BYTES_TO_T_UINT_8( 0x19, 0x54, 0x85, 0xA6, 0x48, 0xB4, 0x17, 0xFD ),
-    BYTES_TO_T_UINT_8( 0xA8, 0x08, 0x11, 0x0E, 0xFC, 0xFB, 0xA4, 0x5D ),
-    BYTES_TO_T_UINT_8( 0x65, 0xC4, 0xA3, 0x26, 0x77, 0xDA, 0x3A, 0x48 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB8, 0xD4, 0x10, 0xFB, 0x8F, 0xD0, 0x47, 0x9C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x19, 0x54, 0x85, 0xA6, 0x48, 0xB4, 0x17, 0xFD ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA8, 0x08, 0x11, 0x0E, 0xFC, 0xFB, 0xA4, 0x5D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x65, 0xC4, 0xA3, 0x26, 0x77, 0xDA, 0x3A, 0x48 ),
 };
 static const mbedtls_mpi_uint secp256k1_n[] = {
-    BYTES_TO_T_UINT_8( 0x41, 0x41, 0x36, 0xD0, 0x8C, 0x5E, 0xD2, 0xBF ),
-    BYTES_TO_T_UINT_8( 0x3B, 0xA0, 0x48, 0xAF, 0xE6, 0xDC, 0xAE, 0xBA ),
-    BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
-    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x41, 0x41, 0x36, 0xD0, 0x8C, 0x5E, 0xD2, 0xBF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x3B, 0xA0, 0x48, 0xAF, 0xE6, 0xDC, 0xAE, 0xBA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
 };
 #endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
 
@@ -424,40 +391,40 @@
  */
 #if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
 static const mbedtls_mpi_uint brainpoolP256r1_p[] = {
-    BYTES_TO_T_UINT_8( 0x77, 0x53, 0x6E, 0x1F, 0x1D, 0x48, 0x13, 0x20 ),
-    BYTES_TO_T_UINT_8( 0x28, 0x20, 0x26, 0xD5, 0x23, 0xF6, 0x3B, 0x6E ),
-    BYTES_TO_T_UINT_8( 0x72, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ),
-    BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x77, 0x53, 0x6E, 0x1F, 0x1D, 0x48, 0x13, 0x20 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0x20, 0x26, 0xD5, 0x23, 0xF6, 0x3B, 0x6E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x72, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ),
 };
 static const mbedtls_mpi_uint brainpoolP256r1_a[] = {
-    BYTES_TO_T_UINT_8( 0xD9, 0xB5, 0x30, 0xF3, 0x44, 0x4B, 0x4A, 0xE9 ),
-    BYTES_TO_T_UINT_8( 0x6C, 0x5C, 0xDC, 0x26, 0xC1, 0x55, 0x80, 0xFB ),
-    BYTES_TO_T_UINT_8( 0xE7, 0xFF, 0x7A, 0x41, 0x30, 0x75, 0xF6, 0xEE ),
-    BYTES_TO_T_UINT_8( 0x57, 0x30, 0x2C, 0xFC, 0x75, 0x09, 0x5A, 0x7D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD9, 0xB5, 0x30, 0xF3, 0x44, 0x4B, 0x4A, 0xE9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6C, 0x5C, 0xDC, 0x26, 0xC1, 0x55, 0x80, 0xFB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE7, 0xFF, 0x7A, 0x41, 0x30, 0x75, 0xF6, 0xEE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x57, 0x30, 0x2C, 0xFC, 0x75, 0x09, 0x5A, 0x7D ),
 };
 static const mbedtls_mpi_uint brainpoolP256r1_b[] = {
-    BYTES_TO_T_UINT_8( 0xB6, 0x07, 0x8C, 0xFF, 0x18, 0xDC, 0xCC, 0x6B ),
-    BYTES_TO_T_UINT_8( 0xCE, 0xE1, 0xF7, 0x5C, 0x29, 0x16, 0x84, 0x95 ),
-    BYTES_TO_T_UINT_8( 0xBF, 0x7C, 0xD7, 0xBB, 0xD9, 0xB5, 0x30, 0xF3 ),
-    BYTES_TO_T_UINT_8( 0x44, 0x4B, 0x4A, 0xE9, 0x6C, 0x5C, 0xDC, 0x26 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB6, 0x07, 0x8C, 0xFF, 0x18, 0xDC, 0xCC, 0x6B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCE, 0xE1, 0xF7, 0x5C, 0x29, 0x16, 0x84, 0x95 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBF, 0x7C, 0xD7, 0xBB, 0xD9, 0xB5, 0x30, 0xF3 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x44, 0x4B, 0x4A, 0xE9, 0x6C, 0x5C, 0xDC, 0x26 ),
 };
 static const mbedtls_mpi_uint brainpoolP256r1_gx[] = {
-    BYTES_TO_T_UINT_8( 0x62, 0x32, 0xCE, 0x9A, 0xBD, 0x53, 0x44, 0x3A ),
-    BYTES_TO_T_UINT_8( 0xC2, 0x23, 0xBD, 0xE3, 0xE1, 0x27, 0xDE, 0xB9 ),
-    BYTES_TO_T_UINT_8( 0xAF, 0xB7, 0x81, 0xFC, 0x2F, 0x48, 0x4B, 0x2C ),
-    BYTES_TO_T_UINT_8( 0xCB, 0x57, 0x7E, 0xCB, 0xB9, 0xAE, 0xD2, 0x8B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x62, 0x32, 0xCE, 0x9A, 0xBD, 0x53, 0x44, 0x3A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC2, 0x23, 0xBD, 0xE3, 0xE1, 0x27, 0xDE, 0xB9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAF, 0xB7, 0x81, 0xFC, 0x2F, 0x48, 0x4B, 0x2C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCB, 0x57, 0x7E, 0xCB, 0xB9, 0xAE, 0xD2, 0x8B ),
 };
 static const mbedtls_mpi_uint brainpoolP256r1_gy[] = {
-    BYTES_TO_T_UINT_8( 0x97, 0x69, 0x04, 0x2F, 0xC7, 0x54, 0x1D, 0x5C ),
-    BYTES_TO_T_UINT_8( 0x54, 0x8E, 0xED, 0x2D, 0x13, 0x45, 0x77, 0xC2 ),
-    BYTES_TO_T_UINT_8( 0xC9, 0x1D, 0x61, 0x14, 0x1A, 0x46, 0xF8, 0x97 ),
-    BYTES_TO_T_UINT_8( 0xFD, 0xC4, 0xDA, 0xC3, 0x35, 0xF8, 0x7E, 0x54 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x97, 0x69, 0x04, 0x2F, 0xC7, 0x54, 0x1D, 0x5C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x54, 0x8E, 0xED, 0x2D, 0x13, 0x45, 0x77, 0xC2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC9, 0x1D, 0x61, 0x14, 0x1A, 0x46, 0xF8, 0x97 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFD, 0xC4, 0xDA, 0xC3, 0x35, 0xF8, 0x7E, 0x54 ),
 };
 static const mbedtls_mpi_uint brainpoolP256r1_n[] = {
-    BYTES_TO_T_UINT_8( 0xA7, 0x56, 0x48, 0x97, 0x82, 0x0E, 0x1E, 0x90 ),
-    BYTES_TO_T_UINT_8( 0xF7, 0xA6, 0x61, 0xB5, 0xA3, 0x7A, 0x39, 0x8C ),
-    BYTES_TO_T_UINT_8( 0x71, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ),
-    BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0x56, 0x48, 0x97, 0x82, 0x0E, 0x1E, 0x90 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF7, 0xA6, 0x61, 0xB5, 0xA3, 0x7A, 0x39, 0x8C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x71, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ),
 };
 #endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
 
@@ -466,52 +433,52 @@
  */
 #if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
 static const mbedtls_mpi_uint brainpoolP384r1_p[] = {
-    BYTES_TO_T_UINT_8( 0x53, 0xEC, 0x07, 0x31, 0x13, 0x00, 0x47, 0x87 ),
-    BYTES_TO_T_UINT_8( 0x71, 0x1A, 0x1D, 0x90, 0x29, 0xA7, 0xD3, 0xAC ),
-    BYTES_TO_T_UINT_8( 0x23, 0x11, 0xB7, 0x7F, 0x19, 0xDA, 0xB1, 0x12 ),
-    BYTES_TO_T_UINT_8( 0xB4, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ),
-    BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ),
-    BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x53, 0xEC, 0x07, 0x31, 0x13, 0x00, 0x47, 0x87 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x71, 0x1A, 0x1D, 0x90, 0x29, 0xA7, 0xD3, 0xAC ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x23, 0x11, 0xB7, 0x7F, 0x19, 0xDA, 0xB1, 0x12 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB4, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ),
 };
 static const mbedtls_mpi_uint brainpoolP384r1_a[] = {
-    BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ),
-    BYTES_TO_T_UINT_8( 0xEB, 0xD4, 0x3A, 0x50, 0x4A, 0x81, 0xA5, 0x8A ),
-    BYTES_TO_T_UINT_8( 0x0F, 0xF9, 0x91, 0xBA, 0xEF, 0x65, 0x91, 0x13 ),
-    BYTES_TO_T_UINT_8( 0x87, 0x27, 0xB2, 0x4F, 0x8E, 0xA2, 0xBE, 0xC2 ),
-    BYTES_TO_T_UINT_8( 0xA0, 0xAF, 0x05, 0xCE, 0x0A, 0x08, 0x72, 0x3C ),
-    BYTES_TO_T_UINT_8( 0x0C, 0x15, 0x8C, 0x3D, 0xC6, 0x82, 0xC3, 0x7B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEB, 0xD4, 0x3A, 0x50, 0x4A, 0x81, 0xA5, 0x8A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0F, 0xF9, 0x91, 0xBA, 0xEF, 0x65, 0x91, 0x13 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x87, 0x27, 0xB2, 0x4F, 0x8E, 0xA2, 0xBE, 0xC2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA0, 0xAF, 0x05, 0xCE, 0x0A, 0x08, 0x72, 0x3C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0C, 0x15, 0x8C, 0x3D, 0xC6, 0x82, 0xC3, 0x7B ),
 };
 static const mbedtls_mpi_uint brainpoolP384r1_b[] = {
-    BYTES_TO_T_UINT_8( 0x11, 0x4C, 0x50, 0xFA, 0x96, 0x86, 0xB7, 0x3A ),
-    BYTES_TO_T_UINT_8( 0x94, 0xC9, 0xDB, 0x95, 0x02, 0x39, 0xB4, 0x7C ),
-    BYTES_TO_T_UINT_8( 0xD5, 0x62, 0xEB, 0x3E, 0xA5, 0x0E, 0x88, 0x2E ),
-    BYTES_TO_T_UINT_8( 0xA6, 0xD2, 0xDC, 0x07, 0xE1, 0x7D, 0xB7, 0x2F ),
-    BYTES_TO_T_UINT_8( 0x7C, 0x44, 0xF0, 0x16, 0x54, 0xB5, 0x39, 0x8B ),
-    BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x11, 0x4C, 0x50, 0xFA, 0x96, 0x86, 0xB7, 0x3A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x94, 0xC9, 0xDB, 0x95, 0x02, 0x39, 0xB4, 0x7C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xD5, 0x62, 0xEB, 0x3E, 0xA5, 0x0E, 0x88, 0x2E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA6, 0xD2, 0xDC, 0x07, 0xE1, 0x7D, 0xB7, 0x2F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x7C, 0x44, 0xF0, 0x16, 0x54, 0xB5, 0x39, 0x8B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ),
 };
 static const mbedtls_mpi_uint brainpoolP384r1_gx[] = {
-    BYTES_TO_T_UINT_8( 0x1E, 0xAF, 0xD4, 0x47, 0xE2, 0xB2, 0x87, 0xEF ),
-    BYTES_TO_T_UINT_8( 0xAA, 0x46, 0xD6, 0x36, 0x34, 0xE0, 0x26, 0xE8 ),
-    BYTES_TO_T_UINT_8( 0xE8, 0x10, 0xBD, 0x0C, 0xFE, 0xCA, 0x7F, 0xDB ),
-    BYTES_TO_T_UINT_8( 0xE3, 0x4F, 0xF1, 0x7E, 0xE7, 0xA3, 0x47, 0x88 ),
-    BYTES_TO_T_UINT_8( 0x6B, 0x3F, 0xC1, 0xB7, 0x81, 0x3A, 0xA6, 0xA2 ),
-    BYTES_TO_T_UINT_8( 0xFF, 0x45, 0xCF, 0x68, 0xF0, 0x64, 0x1C, 0x1D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1E, 0xAF, 0xD4, 0x47, 0xE2, 0xB2, 0x87, 0xEF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAA, 0x46, 0xD6, 0x36, 0x34, 0xE0, 0x26, 0xE8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE8, 0x10, 0xBD, 0x0C, 0xFE, 0xCA, 0x7F, 0xDB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE3, 0x4F, 0xF1, 0x7E, 0xE7, 0xA3, 0x47, 0x88 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x6B, 0x3F, 0xC1, 0xB7, 0x81, 0x3A, 0xA6, 0xA2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0x45, 0xCF, 0x68, 0xF0, 0x64, 0x1C, 0x1D ),
 };
 static const mbedtls_mpi_uint brainpoolP384r1_gy[] = {
-    BYTES_TO_T_UINT_8( 0x15, 0x53, 0x3C, 0x26, 0x41, 0x03, 0x82, 0x42 ),
-    BYTES_TO_T_UINT_8( 0x11, 0x81, 0x91, 0x77, 0x21, 0x46, 0x46, 0x0E ),
-    BYTES_TO_T_UINT_8( 0x28, 0x29, 0x91, 0xF9, 0x4F, 0x05, 0x9C, 0xE1 ),
-    BYTES_TO_T_UINT_8( 0x64, 0x58, 0xEC, 0xFE, 0x29, 0x0B, 0xB7, 0x62 ),
-    BYTES_TO_T_UINT_8( 0x52, 0xD5, 0xCF, 0x95, 0x8E, 0xEB, 0xB1, 0x5C ),
-    BYTES_TO_T_UINT_8( 0xA4, 0xC2, 0xF9, 0x20, 0x75, 0x1D, 0xBE, 0x8A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x15, 0x53, 0x3C, 0x26, 0x41, 0x03, 0x82, 0x42 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x11, 0x81, 0x91, 0x77, 0x21, 0x46, 0x46, 0x0E ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0x29, 0x91, 0xF9, 0x4F, 0x05, 0x9C, 0xE1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x64, 0x58, 0xEC, 0xFE, 0x29, 0x0B, 0xB7, 0x62 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x52, 0xD5, 0xCF, 0x95, 0x8E, 0xEB, 0xB1, 0x5C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA4, 0xC2, 0xF9, 0x20, 0x75, 0x1D, 0xBE, 0x8A ),
 };
 static const mbedtls_mpi_uint brainpoolP384r1_n[] = {
-    BYTES_TO_T_UINT_8( 0x65, 0x65, 0x04, 0xE9, 0x02, 0x32, 0x88, 0x3B ),
-    BYTES_TO_T_UINT_8( 0x10, 0xC3, 0x7F, 0x6B, 0xAF, 0xB6, 0x3A, 0xCF ),
-    BYTES_TO_T_UINT_8( 0xA7, 0x25, 0x04, 0xAC, 0x6C, 0x6E, 0x16, 0x1F ),
-    BYTES_TO_T_UINT_8( 0xB3, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ),
-    BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ),
-    BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x65, 0x65, 0x04, 0xE9, 0x02, 0x32, 0x88, 0x3B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x10, 0xC3, 0x7F, 0x6B, 0xAF, 0xB6, 0x3A, 0xCF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0x25, 0x04, 0xAC, 0x6C, 0x6E, 0x16, 0x1F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB3, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ),
 };
 #endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
 
@@ -520,64 +487,64 @@
  */
 #if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
 static const mbedtls_mpi_uint brainpoolP512r1_p[] = {
-    BYTES_TO_T_UINT_8( 0xF3, 0x48, 0x3A, 0x58, 0x56, 0x60, 0xAA, 0x28 ),
-    BYTES_TO_T_UINT_8( 0x85, 0xC6, 0x82, 0x2D, 0x2F, 0xFF, 0x81, 0x28 ),
-    BYTES_TO_T_UINT_8( 0xE6, 0x80, 0xA3, 0xE6, 0x2A, 0xA1, 0xCD, 0xAE ),
-    BYTES_TO_T_UINT_8( 0x42, 0x68, 0xC6, 0x9B, 0x00, 0x9B, 0x4D, 0x7D ),
-    BYTES_TO_T_UINT_8( 0x71, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ),
-    BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ),
-    BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ),
-    BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xF3, 0x48, 0x3A, 0x58, 0x56, 0x60, 0xAA, 0x28 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x85, 0xC6, 0x82, 0x2D, 0x2F, 0xFF, 0x81, 0x28 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xE6, 0x80, 0xA3, 0xE6, 0x2A, 0xA1, 0xCD, 0xAE ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x42, 0x68, 0xC6, 0x9B, 0x00, 0x9B, 0x4D, 0x7D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x71, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ),
 };
 static const mbedtls_mpi_uint brainpoolP512r1_a[] = {
-    BYTES_TO_T_UINT_8( 0xCA, 0x94, 0xFC, 0x77, 0x4D, 0xAC, 0xC1, 0xE7 ),
-    BYTES_TO_T_UINT_8( 0xB9, 0xC7, 0xF2, 0x2B, 0xA7, 0x17, 0x11, 0x7F ),
-    BYTES_TO_T_UINT_8( 0xB5, 0xC8, 0x9A, 0x8B, 0xC9, 0xF1, 0x2E, 0x0A ),
-    BYTES_TO_T_UINT_8( 0xA1, 0x3A, 0x25, 0xA8, 0x5A, 0x5D, 0xED, 0x2D ),
-    BYTES_TO_T_UINT_8( 0xBC, 0x63, 0x98, 0xEA, 0xCA, 0x41, 0x34, 0xA8 ),
-    BYTES_TO_T_UINT_8( 0x10, 0x16, 0xF9, 0x3D, 0x8D, 0xDD, 0xCB, 0x94 ),
-    BYTES_TO_T_UINT_8( 0xC5, 0x4C, 0x23, 0xAC, 0x45, 0x71, 0x32, 0xE2 ),
-    BYTES_TO_T_UINT_8( 0x89, 0x3B, 0x60, 0x8B, 0x31, 0xA3, 0x30, 0x78 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCA, 0x94, 0xFC, 0x77, 0x4D, 0xAC, 0xC1, 0xE7 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB9, 0xC7, 0xF2, 0x2B, 0xA7, 0x17, 0x11, 0x7F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xB5, 0xC8, 0x9A, 0x8B, 0xC9, 0xF1, 0x2E, 0x0A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA1, 0x3A, 0x25, 0xA8, 0x5A, 0x5D, 0xED, 0x2D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xBC, 0x63, 0x98, 0xEA, 0xCA, 0x41, 0x34, 0xA8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x10, 0x16, 0xF9, 0x3D, 0x8D, 0xDD, 0xCB, 0x94 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC5, 0x4C, 0x23, 0xAC, 0x45, 0x71, 0x32, 0xE2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x89, 0x3B, 0x60, 0x8B, 0x31, 0xA3, 0x30, 0x78 ),
 };
 static const mbedtls_mpi_uint brainpoolP512r1_b[] = {
-    BYTES_TO_T_UINT_8( 0x23, 0xF7, 0x16, 0x80, 0x63, 0xBD, 0x09, 0x28 ),
-    BYTES_TO_T_UINT_8( 0xDD, 0xE5, 0xBA, 0x5E, 0xB7, 0x50, 0x40, 0x98 ),
-    BYTES_TO_T_UINT_8( 0x67, 0x3E, 0x08, 0xDC, 0xCA, 0x94, 0xFC, 0x77 ),
-    BYTES_TO_T_UINT_8( 0x4D, 0xAC, 0xC1, 0xE7, 0xB9, 0xC7, 0xF2, 0x2B ),
-    BYTES_TO_T_UINT_8( 0xA7, 0x17, 0x11, 0x7F, 0xB5, 0xC8, 0x9A, 0x8B ),
-    BYTES_TO_T_UINT_8( 0xC9, 0xF1, 0x2E, 0x0A, 0xA1, 0x3A, 0x25, 0xA8 ),
-    BYTES_TO_T_UINT_8( 0x5A, 0x5D, 0xED, 0x2D, 0xBC, 0x63, 0x98, 0xEA ),
-    BYTES_TO_T_UINT_8( 0xCA, 0x41, 0x34, 0xA8, 0x10, 0x16, 0xF9, 0x3D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x23, 0xF7, 0x16, 0x80, 0x63, 0xBD, 0x09, 0x28 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDD, 0xE5, 0xBA, 0x5E, 0xB7, 0x50, 0x40, 0x98 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x67, 0x3E, 0x08, 0xDC, 0xCA, 0x94, 0xFC, 0x77 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x4D, 0xAC, 0xC1, 0xE7, 0xB9, 0xC7, 0xF2, 0x2B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0x17, 0x11, 0x7F, 0xB5, 0xC8, 0x9A, 0x8B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC9, 0xF1, 0x2E, 0x0A, 0xA1, 0x3A, 0x25, 0xA8 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5A, 0x5D, 0xED, 0x2D, 0xBC, 0x63, 0x98, 0xEA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xCA, 0x41, 0x34, 0xA8, 0x10, 0x16, 0xF9, 0x3D ),
 };
 static const mbedtls_mpi_uint brainpoolP512r1_gx[] = {
-    BYTES_TO_T_UINT_8( 0x22, 0xF8, 0xB9, 0xBC, 0x09, 0x22, 0x35, 0x8B ),
-    BYTES_TO_T_UINT_8( 0x68, 0x5E, 0x6A, 0x40, 0x47, 0x50, 0x6D, 0x7C ),
-    BYTES_TO_T_UINT_8( 0x5F, 0x7D, 0xB9, 0x93, 0x7B, 0x68, 0xD1, 0x50 ),
-    BYTES_TO_T_UINT_8( 0x8D, 0xD4, 0xD0, 0xE2, 0x78, 0x1F, 0x3B, 0xFF ),
-    BYTES_TO_T_UINT_8( 0x8E, 0x09, 0xD0, 0xF4, 0xEE, 0x62, 0x3B, 0xB4 ),
-    BYTES_TO_T_UINT_8( 0xC1, 0x16, 0xD9, 0xB5, 0x70, 0x9F, 0xED, 0x85 ),
-    BYTES_TO_T_UINT_8( 0x93, 0x6A, 0x4C, 0x9C, 0x2E, 0x32, 0x21, 0x5A ),
-    BYTES_TO_T_UINT_8( 0x64, 0xD9, 0x2E, 0xD8, 0xBD, 0xE4, 0xAE, 0x81 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x22, 0xF8, 0xB9, 0xBC, 0x09, 0x22, 0x35, 0x8B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x68, 0x5E, 0x6A, 0x40, 0x47, 0x50, 0x6D, 0x7C ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5F, 0x7D, 0xB9, 0x93, 0x7B, 0x68, 0xD1, 0x50 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8D, 0xD4, 0xD0, 0xE2, 0x78, 0x1F, 0x3B, 0xFF ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8E, 0x09, 0xD0, 0xF4, 0xEE, 0x62, 0x3B, 0xB4 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xC1, 0x16, 0xD9, 0xB5, 0x70, 0x9F, 0xED, 0x85 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x93, 0x6A, 0x4C, 0x9C, 0x2E, 0x32, 0x21, 0x5A ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x64, 0xD9, 0x2E, 0xD8, 0xBD, 0xE4, 0xAE, 0x81 ),
 };
 static const mbedtls_mpi_uint brainpoolP512r1_gy[] = {
-    BYTES_TO_T_UINT_8( 0x92, 0x08, 0xD8, 0x3A, 0x0F, 0x1E, 0xCD, 0x78 ),
-    BYTES_TO_T_UINT_8( 0x06, 0x54, 0xF0, 0xA8, 0x2F, 0x2B, 0xCA, 0xD1 ),
-    BYTES_TO_T_UINT_8( 0xAE, 0x63, 0x27, 0x8A, 0xD8, 0x4B, 0xCA, 0x5B ),
-    BYTES_TO_T_UINT_8( 0x5E, 0x48, 0x5F, 0x4A, 0x49, 0xDE, 0xDC, 0xB2 ),
-    BYTES_TO_T_UINT_8( 0x11, 0x81, 0x1F, 0x88, 0x5B, 0xC5, 0x00, 0xA0 ),
-    BYTES_TO_T_UINT_8( 0x1A, 0x7B, 0xA5, 0x24, 0x00, 0xF7, 0x09, 0xF2 ),
-    BYTES_TO_T_UINT_8( 0xFD, 0x22, 0x78, 0xCF, 0xA9, 0xBF, 0xEA, 0xC0 ),
-    BYTES_TO_T_UINT_8( 0xEC, 0x32, 0x63, 0x56, 0x5D, 0x38, 0xDE, 0x7D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x92, 0x08, 0xD8, 0x3A, 0x0F, 0x1E, 0xCD, 0x78 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x06, 0x54, 0xF0, 0xA8, 0x2F, 0x2B, 0xCA, 0xD1 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xAE, 0x63, 0x27, 0x8A, 0xD8, 0x4B, 0xCA, 0x5B ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x5E, 0x48, 0x5F, 0x4A, 0x49, 0xDE, 0xDC, 0xB2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x11, 0x81, 0x1F, 0x88, 0x5B, 0xC5, 0x00, 0xA0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x1A, 0x7B, 0xA5, 0x24, 0x00, 0xF7, 0x09, 0xF2 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xFD, 0x22, 0x78, 0xCF, 0xA9, 0xBF, 0xEA, 0xC0 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xEC, 0x32, 0x63, 0x56, 0x5D, 0x38, 0xDE, 0x7D ),
 };
 static const mbedtls_mpi_uint brainpoolP512r1_n[] = {
-    BYTES_TO_T_UINT_8( 0x69, 0x00, 0xA9, 0x9C, 0x82, 0x96, 0x87, 0xB5 ),
-    BYTES_TO_T_UINT_8( 0xDD, 0xDA, 0x5D, 0x08, 0x81, 0xD3, 0xB1, 0x1D ),
-    BYTES_TO_T_UINT_8( 0x47, 0x10, 0xAC, 0x7F, 0x19, 0x61, 0x86, 0x41 ),
-    BYTES_TO_T_UINT_8( 0x19, 0x26, 0xA9, 0x4C, 0x41, 0x5C, 0x3E, 0x55 ),
-    BYTES_TO_T_UINT_8( 0x70, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ),
-    BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ),
-    BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ),
-    BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x69, 0x00, 0xA9, 0x9C, 0x82, 0x96, 0x87, 0xB5 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0xDD, 0xDA, 0x5D, 0x08, 0x81, 0xD3, 0xB1, 0x1D ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x47, 0x10, 0xAC, 0x7F, 0x19, 0x61, 0x86, 0x41 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x19, 0x26, 0xA9, 0x4C, 0x41, 0x5C, 0x3E, 0x55 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x70, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ),
+    MBEDTLS_BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ),
 };
 #endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
 
@@ -689,6 +656,13 @@
                             G ## _n,  sizeof( G ## _n  ) )
 
 #if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
+/* Constants used by ecp_use_curve25519() */
+static const mbedtls_mpi_sint curve25519_a24 = 0x01DB42;
+static const unsigned char curve25519_part_of_n[] = {
+    0x14, 0xDE, 0xF9, 0xDE, 0xA2, 0xF7, 0x9C, 0xD6,
+    0x58, 0x12, 0x63, 0x1A, 0x5C, 0xF5, 0xD3, 0xED,
+};
+
 /*
  * Specialized function for creating the Curve25519 group
  */
@@ -697,7 +671,7 @@
     int ret;
 
     /* Actually ( A + 2 ) / 4 */
-    MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &grp->A, 16, "01DB42" ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->A, curve25519_a24 ) );
 
     /* P = 2^255 - 19 */
     MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->P, 1 ) );
@@ -706,8 +680,8 @@
     grp->pbits = mbedtls_mpi_bitlen( &grp->P );
 
     /* N = 2^252 + 27742317777372353535851937790883648493 */
-    MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &grp->N, 16,
-                                              "14DEF9DEA2F79CD65812631A5CF5D3ED" ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &grp->N,
+                     curve25519_part_of_n, sizeof( curve25519_part_of_n ) ) );
     MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &grp->N, 252, 1 ) );
 
     /* Y intentionally not set, since we use x/z coordinates.
@@ -728,6 +702,15 @@
 #endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
 
 #if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
+/* Constants used by ecp_use_curve448() */
+static const mbedtls_mpi_sint curve448_a24 = 0x98AA;
+static const unsigned char curve448_part_of_n[] = {
+    0x83, 0x35, 0xDC, 0x16, 0x3B, 0xB1, 0x24,
+    0xB6, 0x51, 0x29, 0xC9, 0x6F, 0xDE, 0x93,
+    0x3D, 0x8D, 0x72, 0x3A, 0x70, 0xAA, 0xDC,
+    0x87, 0x3D, 0x6D, 0x54, 0xA7, 0xBB, 0x0D,
+};
+
 /*
  * Specialized function for creating the Curve448 group
  */
@@ -739,7 +722,7 @@
     mbedtls_mpi_init( &Ns );
 
     /* Actually ( A + 2 ) / 4 */
-    MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &grp->A, 16, "98AA" ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->A, curve448_a24 ) );
 
     /* P = 2^448 - 2^224 - 1 */
     MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->P, 1 ) );
@@ -757,8 +740,8 @@
 
     /* N = 2^446 - 13818066809895115352007386748515426880336692474882178609894547503885 */
     MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &grp->N, 446, 1 ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &Ns, 16,
-                                              "8335DC163BB124B65129C96FDE933D8D723A70AADC873D6D54A7BB0D" ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &Ns,
+                        curve448_part_of_n, sizeof( curve448_part_of_n ) ) );
     MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &grp->N, &grp->N, &Ns ) );
 
     /* Actually, the required msb for private keys */
@@ -1048,13 +1031,13 @@
 
 /*
  * If the result is negative, we get it in the form
- * c * 2^(bits + 32) + N, with c negative and N positive shorter than 'bits'
+ * c * 2^bits + N, with c negative and N positive shorter than 'bits'
  */
 static inline int fix_negative( mbedtls_mpi *N, signed char c, mbedtls_mpi *C, size_t bits )
 {
     int ret;
 
-    /* C = - c * 2^(bits + 32) */
+    /* C = - c * 2^bits */
 #if !defined(MBEDTLS_HAVE_INT64)
     ((void) bits);
 #else
@@ -1452,9 +1435,11 @@
 static int ecp_mod_p192k1( mbedtls_mpi *N )
 {
     static mbedtls_mpi_uint Rp[] = {
-        BYTES_TO_T_UINT_8( 0xC9, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) };
+        MBEDTLS_BYTES_TO_T_UINT_8( 0xC9, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00,
+                                   0x00 ) };
 
-    return( ecp_mod_koblitz( N, Rp, 192 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) );
+    return( ecp_mod_koblitz( N, Rp, 192 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0,
+                             0 ) );
 }
 #endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
 
@@ -1466,12 +1451,14 @@
 static int ecp_mod_p224k1( mbedtls_mpi *N )
 {
     static mbedtls_mpi_uint Rp[] = {
-        BYTES_TO_T_UINT_8( 0x93, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) };
+        MBEDTLS_BYTES_TO_T_UINT_8( 0x93, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x00,
+                                   0x00 ) };
 
 #if defined(MBEDTLS_HAVE_INT64)
     return( ecp_mod_koblitz( N, Rp, 4, 1, 32, 0xFFFFFFFF ) );
 #else
-    return( ecp_mod_koblitz( N, Rp, 224 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) );
+    return( ecp_mod_koblitz( N, Rp, 224 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0,
+                             0 ) );
 #endif
 }
 
@@ -1485,8 +1472,10 @@
 static int ecp_mod_p256k1( mbedtls_mpi *N )
 {
     static mbedtls_mpi_uint Rp[] = {
-        BYTES_TO_T_UINT_8( 0xD1, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) };
-    return( ecp_mod_koblitz( N, Rp, 256 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) );
+        MBEDTLS_BYTES_TO_T_UINT_8( 0xD1, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00,
+                                   0x00 ) };
+    return( ecp_mod_koblitz( N, Rp, 256 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0,
+                             0 ) );
 }
 #endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
 
diff --git a/library/entropy.c b/library/entropy.c
index 666c556..9f1a32b 100644
--- a/library/entropy.c
+++ b/library/entropy.c
@@ -146,6 +146,11 @@
 
 void mbedtls_entropy_free( mbedtls_entropy_context *ctx )
 {
+    /* If the context was already free, don't call free() again.
+     * This is important for mutexes which don't allow double-free. */
+    if( ctx->accumulator_started == -1 )
+        return;
+
 #if defined(MBEDTLS_HAVEGE_C)
     mbedtls_havege_free( &ctx->havege_data );
 #endif
@@ -162,7 +167,7 @@
 #endif
     ctx->source_count = 0;
     mbedtls_platform_zeroize( ctx->source, sizeof( ctx->source ) );
-    ctx->accumulator_started = 0;
+    ctx->accumulator_started = -1;
 }
 
 int mbedtls_entropy_add_source( mbedtls_entropy_context *ctx,
@@ -489,14 +494,20 @@
 int mbedtls_entropy_write_seed_file( mbedtls_entropy_context *ctx, const char *path )
 {
     int ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
-    FILE *f;
+    FILE *f = NULL;
     unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
 
-    if( ( f = fopen( path, "wb" ) ) == NULL )
-        return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR );
-
     if( ( ret = mbedtls_entropy_func( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 )
+    {
+        ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
         goto exit;
+    }
+
+    if( ( f = fopen( path, "wb" ) ) == NULL )
+    {
+        ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
+        goto exit;
+    }
 
     if( fwrite( buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f ) != MBEDTLS_ENTROPY_BLOCK_SIZE )
     {
@@ -509,7 +520,9 @@
 exit:
     mbedtls_platform_zeroize( buf, sizeof( buf ) );
 
-    fclose( f );
+    if( f != NULL )
+        fclose( f );
+
     return( ret );
 }
 
diff --git a/library/hmac_drbg.c b/library/hmac_drbg.c
index 10cbd46..b45d616 100644
--- a/library/hmac_drbg.c
+++ b/library/hmac_drbg.c
@@ -84,10 +84,6 @@
     memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) );
 
     ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
-
-#if defined(MBEDTLS_THREADING_C)
-    mbedtls_mutex_init( &ctx->mutex );
-#endif
 }
 
 /*
@@ -159,6 +155,10 @@
     if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
         return( ret );
 
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_mutex_init( &ctx->mutex );
+#endif
+
     /*
      * Set initial working state.
      * Use the V memory location, which is currently all 0, to initialize the
@@ -284,6 +284,11 @@
     if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
         return( ret );
 
+    /* The mutex is initialized iff the md context is set up. */
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_mutex_init( &ctx->mutex );
+#endif
+
     md_size = mbedtls_md_get_size( md_info );
 
     /*
@@ -451,14 +456,13 @@
         return;
 
 #if defined(MBEDTLS_THREADING_C)
-    mbedtls_mutex_free( &ctx->mutex );
+    /* The mutex is initialized iff the md context is set up. */
+    if( ctx->md_ctx.md_info != NULL )
+        mbedtls_mutex_free( &ctx->mutex );
 #endif
     mbedtls_md_free( &ctx->md_ctx );
     mbedtls_platform_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
     ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
-#if defined(MBEDTLS_THREADING_C)
-    mbedtls_mutex_init( &ctx->mutex );
-#endif
 }
 
 #if defined(MBEDTLS_FS_IO)
diff --git a/library/md2.c b/library/md2.c
index fdcb630..58bd6d8 100644
--- a/library/md2.c
+++ b/library/md2.c
@@ -320,8 +320,7 @@
     { "message digest" },
     { "abcdefghijklmnopqrstuvwxyz" },
     { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
-    { "12345678901234567890123456789012345678901234567890123456789012"
-      "345678901234567890" }
+    { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" }
 };
 
 static const size_t md2_test_strlen[7] =
diff --git a/library/md4.c b/library/md4.c
index 95e893e..9a82532 100644
--- a/library/md4.c
+++ b/library/md4.c
@@ -444,8 +444,7 @@
     { "message digest" },
     { "abcdefghijklmnopqrstuvwxyz" },
     { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
-    { "12345678901234567890123456789012345678901234567890123456789012"
-      "345678901234567890" }
+    { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" }
 };
 
 static const size_t md4_test_strlen[7] =
diff --git a/library/md5.c b/library/md5.c
index d2b634f..a2e1ca7 100644
--- a/library/md5.c
+++ b/library/md5.c
@@ -458,8 +458,7 @@
     { "message digest" },
     { "abcdefghijklmnopqrstuvwxyz" },
     { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
-    { "12345678901234567890123456789012345678901234567890123456789012"
-      "345678901234567890" }
+    { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" }
 };
 
 static const size_t md5_test_buflen[7] =
diff --git a/library/net_sockets.c b/library/net_sockets.c
index 1130408..1e701a5 100644
--- a/library/net_sockets.c
+++ b/library/net_sockets.c
@@ -47,11 +47,15 @@
 /* Enable definition of getaddrinfo() even when compiling with -std=c99. Must
  * be set before config.h, which pulls in glibc's features.h indirectly.
  * Harmless on other platforms. */
+#ifndef _POSIX_C_SOURCE
 #define _POSIX_C_SOURCE 200112L
+#endif
 
 #if defined(__NetBSD__)
+#ifndef _XOPEN_SOURCE
 #define _XOPEN_SOURCE 600 /* sockaddr_storage */
 #endif
+#endif
 
 #if !defined(MBEDTLS_CONFIG_FILE)
 #include "mbedtls/config.h"
@@ -163,6 +167,31 @@
 }
 
 /*
+ * Return 0 if the file descriptor is valid, an error otherwise.
+ * If for_select != 0, check whether the file descriptor is within the range
+ * allowed for fd_set used for the FD_xxx macros and the select() function.
+ */
+static int check_fd( int fd, int for_select )
+{
+    if( fd < 0 )
+        return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
+
+#if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \
+    !defined(EFI32)
+    (void) for_select;
+#else
+    /* 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( for_select && fd >= FD_SETSIZE )
+        return( MBEDTLS_ERR_NET_POLL_FAILED );
+#endif
+
+    return( 0 );
+}
+
+/*
  * Initialize a context
  */
 void mbedtls_net_init( mbedtls_net_context *ctx )
@@ -493,8 +522,9 @@
 
     int fd = ctx->fd;
 
-    if( fd < 0 )
-        return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
+    ret = check_fd( fd, 1 );
+    if( ret != 0 )
+        return( ret );
 
 #if defined(__has_feature)
 #if __has_feature(memory_sanitizer)
@@ -573,8 +603,9 @@
     int ret;
     int fd = ((mbedtls_net_context *) ctx)->fd;
 
-    if( fd < 0 )
-        return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
+    ret = check_fd( fd, 0 );
+    if( ret != 0 )
+        return( ret );
 
     ret = (int) read( fd, buf, len );
 
@@ -612,8 +643,9 @@
     fd_set read_fds;
     int fd = ((mbedtls_net_context *) ctx)->fd;
 
-    if( fd < 0 )
-        return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
+    ret = check_fd( fd, 1 );
+    if( ret != 0 )
+        return( ret );
 
     FD_ZERO( &read_fds );
     FD_SET( fd, &read_fds );
@@ -653,8 +685,9 @@
     int ret;
     int fd = ((mbedtls_net_context *) ctx)->fd;
 
-    if( fd < 0 )
-        return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
+    ret = check_fd( fd, 0 );
+    if( ret != 0 )
+        return( ret );
 
     ret = (int) write( fd, buf, len );
 
diff --git a/library/nist_kw.c b/library/nist_kw.c
index 8341ff1..278b7e9 100644
--- a/library/nist_kw.c
+++ b/library/nist_kw.c
@@ -219,8 +219,6 @@
     uint64_t t = 0;
     unsigned char outbuff[KW_SEMIBLOCK_LENGTH * 2];
     unsigned char inbuff[KW_SEMIBLOCK_LENGTH * 2];
-    unsigned char *R2 = output + KW_SEMIBLOCK_LENGTH;
-    unsigned char *A = output;
 
     *out_len = 0;
     /*
@@ -296,6 +294,9 @@
     }
     else
     {
+        unsigned char *R2 = output + KW_SEMIBLOCK_LENGTH;
+        unsigned char *A = output;
+
         /*
          * Do the wrapping function W, as defined in RFC 3394 section 2.2.1
          */
@@ -359,7 +360,7 @@
     uint64_t t = 0;
     unsigned char outbuff[KW_SEMIBLOCK_LENGTH * 2];
     unsigned char inbuff[KW_SEMIBLOCK_LENGTH * 2];
-    unsigned char *R = output + ( semiblocks - 2 ) * KW_SEMIBLOCK_LENGTH;
+    unsigned char *R = NULL;
     *out_len = 0;
 
     if( semiblocks < MIN_SEMIBLOCKS_COUNT )
@@ -369,6 +370,7 @@
 
     memcpy( A, input, KW_SEMIBLOCK_LENGTH );
     memmove( output, input + KW_SEMIBLOCK_LENGTH, ( semiblocks - 1 ) * KW_SEMIBLOCK_LENGTH );
+    R = output + ( semiblocks - 2 ) * KW_SEMIBLOCK_LENGTH;
 
     /* Calculate intermediate values */
     for( t = s; t >= 1; t-- )
diff --git a/library/pk.c b/library/pk.c
index 81cfdbf..8998271 100644
--- a/library/pk.c
+++ b/library/pk.c
@@ -225,12 +225,15 @@
 {
     const mbedtls_md_info_t *md_info;
 
-    if( *hash_len != 0 )
+    if( *hash_len != 0 && md_alg == MBEDTLS_MD_NONE )
         return( 0 );
 
     if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL )
         return( -1 );
 
+    if ( *hash_len != 0 && *hash_len < mbedtls_md_get_size( md_info ) )
+        return ( -1 );
+
     *hash_len = mbedtls_md_get_size( md_info );
     return( 0 );
 }
diff --git a/library/pkparse.c b/library/pkparse.c
index e410f3a..2622351 100644
--- a/library/pkparse.c
+++ b/library/pkparse.c
@@ -1070,7 +1070,7 @@
         return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION + ret );
 
     if( ( ret = pk_get_pk_alg( &p, end, &pk_alg, &params ) ) != 0 )
-        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+        return( ret );
 
     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
         return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
diff --git a/library/pkwrite.c b/library/pkwrite.c
index 150626c..a770dfb 100644
--- a/library/pkwrite.c
+++ b/library/pkwrite.c
@@ -455,7 +455,7 @@
  *      publicExponent    INTEGER   -- e            1 + 3 + MPI_MAX + 1
  *  }
  */
-#define RSA_PUB_DER_MAX_BYTES   38 + 2 * MBEDTLS_MPI_MAX_SIZE
+#define RSA_PUB_DER_MAX_BYTES   ( 38 + 2 * MBEDTLS_MPI_MAX_SIZE )
 
 /*
  * RSA private keys:
@@ -472,10 +472,10 @@
  *      otherPrimeInfos   OtherPrimeInfos OPTIONAL  0 (not supported)
  *  }
  */
-#define MPI_MAX_SIZE_2          MBEDTLS_MPI_MAX_SIZE / 2 + \
-                                MBEDTLS_MPI_MAX_SIZE % 2
-#define RSA_PRV_DER_MAX_BYTES   47 + 3 * MBEDTLS_MPI_MAX_SIZE \
-                                   + 5 * MPI_MAX_SIZE_2
+#define MPI_MAX_SIZE_2          ( MBEDTLS_MPI_MAX_SIZE / 2 + \
+                                  MBEDTLS_MPI_MAX_SIZE % 2 )
+#define RSA_PRV_DER_MAX_BYTES   ( 47 + 3 * MBEDTLS_MPI_MAX_SIZE \
+                                   + 5 * MPI_MAX_SIZE_2 )
 
 #else /* MBEDTLS_RSA_C */
 
@@ -496,7 +496,7 @@
  *                                            + 2 * ECP_MAX (coords)    [1]
  *  }
  */
-#define ECP_PUB_DER_MAX_BYTES   30 + 2 * MBEDTLS_ECP_MAX_BYTES
+#define ECP_PUB_DER_MAX_BYTES   ( 30 + 2 * MBEDTLS_ECP_MAX_BYTES )
 
 /*
  * EC private keys:
@@ -507,7 +507,7 @@
  *      publicKey  [1] BIT STRING OPTIONAL      1 + 2 + [1] above
  *    }
  */
-#define ECP_PRV_DER_MAX_BYTES   29 + 3 * MBEDTLS_ECP_MAX_BYTES
+#define ECP_PRV_DER_MAX_BYTES   ( 29 + 3 * MBEDTLS_ECP_MAX_BYTES )
 
 #else /* MBEDTLS_ECP_C */
 
@@ -516,10 +516,10 @@
 
 #endif /* MBEDTLS_ECP_C */
 
-#define PUB_DER_MAX_BYTES   RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \
-                            RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES
-#define PRV_DER_MAX_BYTES   RSA_PRV_DER_MAX_BYTES > ECP_PRV_DER_MAX_BYTES ? \
-                            RSA_PRV_DER_MAX_BYTES : ECP_PRV_DER_MAX_BYTES
+#define PUB_DER_MAX_BYTES   ( RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \
+                              RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES )
+#define PRV_DER_MAX_BYTES   ( RSA_PRV_DER_MAX_BYTES > ECP_PRV_DER_MAX_BYTES ? \
+                              RSA_PRV_DER_MAX_BYTES : ECP_PRV_DER_MAX_BYTES )
 
 int mbedtls_pk_write_pubkey_pem( mbedtls_pk_context *key, unsigned char *buf, size_t size )
 {
diff --git a/library/ripemd160.c b/library/ripemd160.c
index d6ee933..c090c8f 100644
--- a/library/ripemd160.c
+++ b/library/ripemd160.c
@@ -514,8 +514,7 @@
     { "abcdefghijklmnopqrstuvwxyz" },
     { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
     { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
-    { "12345678901234567890123456789012345678901234567890123456789012"
-      "345678901234567890" },
+    { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" },
 };
 
 static const size_t ripemd160_test_strlen[TESTS] =
diff --git a/library/rsa.c b/library/rsa.c
index 0007546..c8c23db 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -520,6 +520,9 @@
     mbedtls_rsa_set_padding( ctx, padding, hash_id );
 
 #if defined(MBEDTLS_THREADING_C)
+    /* Set ctx->ver to nonzero to indicate that the mutex has been
+     * initialized and will need to be freed. */
+    ctx->ver = 1;
     mbedtls_mutex_init( &ctx->mutex );
 #endif
 }
@@ -567,9 +570,6 @@
     RSA_VALIDATE_RET( ctx != NULL );
     RSA_VALIDATE_RET( f_rng != NULL );
 
-    if( nbits < 128 || exponent < 3 || nbits % 2 != 0 )
-        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
-
     /*
      * If the modulus is 1024 bit long or shorter, then the security strength of
      * the RSA algorithm is less than or equal to 80 bits and therefore an error
@@ -582,6 +582,12 @@
     mbedtls_mpi_init( &G );
     mbedtls_mpi_init( &L );
 
+    if( nbits < 128 || exponent < 3 || nbits % 2 != 0 )
+    {
+        ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
+        goto cleanup;
+    }
+
     /*
      * find primes P and Q with Q < P so that:
      * 1.  |P-Q| > 2^( nbits / 2 - 100 )
@@ -659,7 +665,9 @@
     if( ret != 0 )
     {
         mbedtls_rsa_free( ctx );
-        return( MBEDTLS_ERR_RSA_KEY_GEN_FAILED + ret );
+        if( ( -ret & ~0x7f ) == 0 )
+            ret = MBEDTLS_ERR_RSA_KEY_GEN_FAILED + ret;
+        return( ret );
     }
 
     return( 0 );
@@ -2502,7 +2510,6 @@
     RSA_VALIDATE_RET( dst != NULL );
     RSA_VALIDATE_RET( src != NULL );
 
-    dst->ver = src->ver;
     dst->len = src->len;
 
     MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->N, &src->N ) );
@@ -2561,7 +2568,12 @@
 #endif /* MBEDTLS_RSA_NO_CRT */
 
 #if defined(MBEDTLS_THREADING_C)
-    mbedtls_mutex_free( &ctx->mutex );
+    /* Free the mutex, but only if it hasn't been freed already. */
+    if( ctx->ver != 0 )
+    {
+        mbedtls_mutex_free( &ctx->mutex );
+        ctx->ver = 0;
+    }
 #endif
 }
 
diff --git a/library/sha512.c b/library/sha512.c
index 986037a..3347afe 100644
--- a/library/sha512.c
+++ b/library/sha512.c
@@ -527,8 +527,7 @@
 static const unsigned char sha512_test_buf[3][113] =
 {
     { "abc" },
-    { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
-      "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
+    { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
     { "" }
 };
 
diff --git a/library/ssl_ciphersuites.c b/library/ssl_ciphersuites.c
index 090040e..01df17a 100644
--- a/library/ssl_ciphersuites.c
+++ b/library/ssl_ciphersuites.c
@@ -918,13 +918,13 @@
       0 },
 #endif /* MBEDTLS_SHA256_C */
 
-#if defined(MBEDTLS_SHA1_C)
+#if defined(MBEDTLS_SHA512_C)
     { MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-RSA-WITH-CAMELLIA-256-GCM-SHA384",
       MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
       0 },
-#endif /* MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_SHA512_C */
 #endif /* MBEDTLS_GCM_C */
 #endif /* MBEDTLS_CAMELLIA_C */
 
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index bd7f281..b977e5b 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -1318,7 +1318,7 @@
         mbedtls_ssl_send_alert_message(
             ssl,
             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+            MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
     }
 
@@ -1365,7 +1365,7 @@
         mbedtls_ssl_send_alert_message(
             ssl,
             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+            MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT );
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
     }
 
@@ -1391,7 +1391,7 @@
         mbedtls_ssl_send_alert_message(
             ssl,
             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+            MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT );
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
     }
 
@@ -1416,7 +1416,7 @@
         mbedtls_ssl_send_alert_message(
             ssl,
             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+            MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT );
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
     }
 
@@ -1522,7 +1522,7 @@
         mbedtls_ssl_send_alert_message(
             ssl,
             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+            MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT );
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
     }
 
@@ -2209,6 +2209,7 @@
                                        unsigned char *end )
 {
     int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
+    size_t dhm_actual_bitlen;
 
     /*
      * Ephemeral DH parameters:
@@ -2226,10 +2227,11 @@
         return( ret );
     }
 
-    if( ssl->handshake->dhm_ctx.len * 8 < ssl->conf->dhm_min_bitlen )
+    dhm_actual_bitlen = mbedtls_mpi_bitlen( &ssl->handshake->dhm_ctx.P );
+    if( dhm_actual_bitlen < ssl->conf->dhm_min_bitlen )
     {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "DHM prime too short: %d < %d",
-                                    ssl->handshake->dhm_ctx.len * 8,
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "DHM prime too short: %u < %u",
+                                    (unsigned) dhm_actual_bitlen,
                                     ssl->conf->dhm_min_bitlen ) );
         return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
     }
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index c749a86..3c1e917 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -1895,6 +1895,9 @@
             MD_CHK( mbedtls_md_update( ctx, data + offset, 1 ) );
     }
 
+    /* The context needs to finish() before it starts() again */
+    MD_CHK( mbedtls_md_finish( ctx, aux_out ) );
+
     /* Now compute HASH(okey + inner_hash) */
     MD_CHK( mbedtls_md_starts( ctx ) );
     MD_CHK( mbedtls_md_update( ctx, okey, block_size ) );
@@ -6364,8 +6367,6 @@
 
 #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 )
 {
@@ -6373,12 +6374,6 @@
     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 )
@@ -6404,8 +6399,19 @@
     sender = ( from == MBEDTLS_SSL_IS_CLIENT )
              ? "client finished"
              : "server finished";
-
-    finish_sha384( &sha512, padbuf );
+    /* mbedtls_sha512_finish_ret's output parameter is declared as a
+     * 64-byte buffer, but sice we're using SHA-384, we know that the
+     * output fits in 48 bytes. This is correct C, but GCC 11.1 warns
+     * about it.
+     */
+#if defined(__GNUC__) && __GNUC__ >= 11
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wstringop-overflow"
+#endif
+    mbedtls_sha512_finish_ret( &sha512, padbuf );
+#if defined(__GNUC__) && __GNUC__ >= 11
+#pragma GCC diagnostic pop
+#endif
 
     ssl->handshake->tls_prf( session->master, 48, sender,
                              padbuf, 48, buf, len );
@@ -6678,7 +6684,7 @@
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
         mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
-                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+                                        MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR );
         return( MBEDTLS_ERR_SSL_BAD_HS_FINISHED );
     }
 
diff --git a/library/threading.c b/library/threading.c
index f4f29cf..0dc5488 100644
--- a/library/threading.c
+++ b/library/threading.c
@@ -98,6 +98,12 @@
     if( mutex == NULL )
         return;
 
+    /* A nonzero value of is_valid indicates a successfully initialized
+     * mutex. This is a workaround for not being able to return an error
+     * code for this function. The lock/unlock functions return an error
+     * if is_valid is nonzero. The Mbed TLS unit test code uses this field
+     * to distinguish more states of the mutex; see helpers.function for
+     * details. */
     mutex->is_valid = pthread_mutex_init( &mutex->mutex, NULL ) == 0;
 }
 
diff --git a/library/version_features.c b/library/version_features.c
index cbf38dc..8c8e815 100644
--- a/library/version_features.c
+++ b/library/version_features.c
@@ -553,6 +553,9 @@
 #if defined(MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT)
     "MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT",
 #endif /* MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT */
+#if defined(MBEDTLS_TEST_HOOKS)
+    "MBEDTLS_TEST_HOOKS",
+#endif /* MBEDTLS_TEST_HOOKS */
 #if defined(MBEDTLS_THREADING_ALT)
     "MBEDTLS_THREADING_ALT",
 #endif /* MBEDTLS_THREADING_ALT */
diff --git a/library/x509_crt.c b/library/x509_crt.c
index 4b53d1a..14c53fc 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -116,9 +116,8 @@
  */
 #define X509_MAX_VERIFY_CHAIN_SIZE    ( MBEDTLS_X509_MAX_INTERMEDIATE_CA + 2 )
 
-/*
- * Default profile
- */
+/* Default profile. Do not remove items unless there are serious security
+ * concerns. */
 const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default =
 {
 #if defined(MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES)
diff --git a/programs/.gitignore b/programs/.gitignore
index 4d78930..d9ca31c 100644
--- a/programs/.gitignore
+++ b/programs/.gitignore
@@ -2,7 +2,6 @@
 *.sln
 *.vcxproj
 
-aes/aescrypt2
 aes/crypt_and_hash
 hash/generic_sum
 hash/hello
diff --git a/programs/Makefile b/programs/Makefile
index d09949b..d5ebfd7 100644
--- a/programs/Makefile
+++ b/programs/Makefile
@@ -47,7 +47,7 @@
 LOCAL_LDFLAGS += -lz
 endif
 
-APPS =	aes/aescrypt2$(EXEXT)		aes/crypt_and_hash$(EXEXT)	\
+APPS =	aes/crypt_and_hash$(EXEXT)	\
 	hash/hello$(EXEXT)		hash/generic_sum$(EXEXT)	\
 					pkey/dh_client$(EXEXT)		\
 	pkey/dh_genprime$(EXEXT)	pkey/dh_server$(EXEXT)		\
@@ -93,10 +93,6 @@
 $(DEP):
 	$(MAKE) -C ../library
 
-aes/aescrypt2$(EXEXT): aes/aescrypt2.c $(DEP)
-	echo "  CC    aes/aescrypt2.c"
-	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) aes/aescrypt2.c    $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
-
 aes/crypt_and_hash$(EXEXT): aes/crypt_and_hash.c $(DEP)
 	echo "  CC    aes/crypt_and_hash.c"
 	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) aes/crypt_and_hash.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
diff --git a/programs/README.md b/programs/README.md
index d26349d..e9e9f57 100644
--- a/programs/README.md
+++ b/programs/README.md
@@ -5,9 +5,6 @@
 
 ## Symmetric cryptography (AES) examples
 
-* [`aes/aescrypt2.c`](aes/aescrypt2.c): file encryption and authentication with a key derived from a low-entropy secret, demonstrating the low-level AES interface, the digest interface and HMAC.  
-  Warning: this program illustrates how to use low-level functions in the library. It should not be taken as an example of how to build a secure encryption mechanism. To derive a key from a low-entropy secret such as a password, use a standard key stretching mechanism such as PBKDF2 (provided by the `pkcs5` module). To encrypt and authenticate data, use a standard mode such as GCM or CCM (both available as library module).
-
 * [`aes/crypt_and_hash.c`](aes/crypt_and_hash.c): file encryption and authentication, demonstrating the generic cipher interface and the generic hash interface.
 
 ## Hash (digest) examples
diff --git a/programs/aes/CMakeLists.txt b/programs/aes/CMakeLists.txt
index f5a0caa..ac70de8 100644
--- a/programs/aes/CMakeLists.txt
+++ b/programs/aes/CMakeLists.txt
@@ -1,9 +1,6 @@
-add_executable(aescrypt2 aescrypt2.c)
-target_link_libraries(aescrypt2 mbedtls)
-
 add_executable(crypt_and_hash crypt_and_hash.c)
 target_link_libraries(crypt_and_hash mbedtls)
 
-install(TARGETS aescrypt2 crypt_and_hash
+install(TARGETS crypt_and_hash
         DESTINATION "bin"
         PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
diff --git a/programs/aes/aescrypt2.c b/programs/aes/aescrypt2.c
deleted file mode 100644
index 8b44aad..0000000
--- a/programs/aes/aescrypt2.c
+++ /dev/null
@@ -1,495 +0,0 @@
-/*
- *  AES-256 file encryption program
- *
- *  Copyright The Mbed TLS Contributors
- *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- *  This file is provided under the Apache License 2.0, or the
- *  GNU General Public License v2.0 or later.
- *
- *  **********
- *  Apache License 2.0:
- *
- *  Licensed under the Apache License, Version 2.0 (the "License"); you may
- *  not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- *  **********
- *
- *  **********
- *  GNU General Public License v2.0 or later:
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *  **********
- */
-
-/* Enable definition of fileno() even when compiling with -std=c99. Must be
- * set before config.h, which pulls in glibc's features.h indirectly.
- * Harmless on other platforms. */
-#define _POSIX_C_SOURCE 1
-
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
-
-#if defined(MBEDTLS_PLATFORM_C)
-#include "mbedtls/platform.h"
-#else
-#include <stdio.h>
-#include <stdlib.h>
-#define mbedtls_fprintf         fprintf
-#define mbedtls_printf          printf
-#define mbedtls_exit            exit
-#define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
-#define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
-#endif /* MBEDTLS_PLATFORM_C */
-
-#include "mbedtls/aes.h"
-#include "mbedtls/md.h"
-#include "mbedtls/platform_util.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#if defined(_WIN32)
-#include <windows.h>
-#if !defined(_WIN32_WCE)
-#include <io.h>
-#endif
-#else
-#include <sys/types.h>
-#include <unistd.h>
-#endif
-
-#define MODE_ENCRYPT    0
-#define MODE_DECRYPT    1
-
-#define USAGE   \
-    "\n  aescrypt2 <mode> <input filename> <output filename> <key>\n" \
-    "\n   <mode>: 0 = encrypt, 1 = decrypt\n" \
-    "\n  example: aescrypt2 0 file file.aes hex:E76B2413958B00E193\n" \
-    "\n"
-
-#if !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_SHA256_C) || \
-    !defined(MBEDTLS_FS_IO) || !defined(MBEDTLS_MD_C)
-int main( void )
-{
-    mbedtls_printf("MBEDTLS_AES_C and/or MBEDTLS_SHA256_C "
-                    "and/or MBEDTLS_FS_IO and/or MBEDTLS_MD_C "
-                    "not defined.\n");
-    mbedtls_exit( 0 );
-}
-#else
-
-
-int main( int argc, char *argv[] )
-{
-    int ret = 0;
-    int exit_code = MBEDTLS_EXIT_FAILURE;
-
-    unsigned int i, n;
-    int mode, lastn;
-    size_t keylen;
-    FILE *fkey, *fin = NULL, *fout = NULL;
-
-    char *p;
-
-    unsigned char IV[16];
-    unsigned char tmp[16];
-    unsigned char key[512];
-    unsigned char digest[32];
-    unsigned char buffer[1024];
-    unsigned char diff;
-
-    mbedtls_aes_context aes_ctx;
-    mbedtls_md_context_t sha_ctx;
-
-#if defined(_WIN32_WCE)
-    long filesize, offset;
-#elif defined(_WIN32)
-       LARGE_INTEGER li_size;
-    __int64 filesize, offset;
-#else
-      off_t filesize, offset;
-#endif
-
-    mbedtls_aes_init( &aes_ctx );
-    mbedtls_md_init( &sha_ctx );
-
-    ret = mbedtls_md_setup( &sha_ctx, mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ), 1 );
-    if( ret != 0 )
-    {
-        mbedtls_printf( "  ! mbedtls_md_setup() returned -0x%04x\n", -ret );
-        goto exit;
-    }
-
-    /*
-     * Parse the command-line arguments.
-     */
-    if( argc != 5 )
-    {
-        mbedtls_printf( USAGE );
-
-#if defined(_WIN32)
-        mbedtls_printf( "\n  Press Enter to exit this program.\n" );
-        fflush( stdout ); getchar();
-#endif
-
-        goto exit;
-    }
-
-    mode = atoi( argv[1] );
-    memset( IV,     0, sizeof( IV ) );
-    memset( key,    0, sizeof( key ) );
-    memset( digest, 0, sizeof( digest ) );
-    memset( buffer, 0, sizeof( buffer ) );
-
-    if( mode != MODE_ENCRYPT && mode != MODE_DECRYPT )
-    {
-        mbedtls_fprintf( stderr, "invalide operation mode\n" );
-        goto exit;
-    }
-
-    if( strcmp( argv[2], argv[3] ) == 0 )
-    {
-        mbedtls_fprintf( stderr, "input and output filenames must differ\n" );
-        goto exit;
-    }
-
-    if( ( fin = fopen( argv[2], "rb" ) ) == NULL )
-    {
-        mbedtls_fprintf( stderr, "fopen(%s,rb) failed\n", argv[2] );
-        goto exit;
-    }
-
-    if( ( fout = fopen( argv[3], "wb+" ) ) == NULL )
-    {
-        mbedtls_fprintf( stderr, "fopen(%s,wb+) failed\n", argv[3] );
-        goto exit;
-    }
-
-    /*
-     * Read the secret key from file or command line
-     */
-    if( ( fkey = fopen( argv[4], "rb" ) ) != NULL )
-    {
-        keylen = fread( key, 1, sizeof( key ), fkey );
-        fclose( fkey );
-    }
-    else
-    {
-        if( memcmp( argv[4], "hex:", 4 ) == 0 )
-        {
-            p = &argv[4][4];
-            keylen = 0;
-
-            while( sscanf( p, "%02X", &n ) > 0 &&
-                   keylen < (int) sizeof( key ) )
-            {
-                key[keylen++] = (unsigned char) n;
-                p += 2;
-            }
-        }
-        else
-        {
-            keylen = strlen( argv[4] );
-
-            if( keylen > (int) sizeof( key ) )
-                keylen = (int) sizeof( key );
-
-            memcpy( key, argv[4], keylen );
-        }
-    }
-
-#if defined(_WIN32_WCE)
-    filesize = fseek( fin, 0L, SEEK_END );
-#else
-#if defined(_WIN32)
-    /*
-     * Support large files (> 2Gb) on Win32
-     */
-    li_size.QuadPart = 0;
-    li_size.LowPart  =
-        SetFilePointer( (HANDLE) _get_osfhandle( _fileno( fin ) ),
-                        li_size.LowPart, &li_size.HighPart, FILE_END );
-
-    if( li_size.LowPart == 0xFFFFFFFF && GetLastError() != NO_ERROR )
-    {
-        mbedtls_fprintf( stderr, "SetFilePointer(0,FILE_END) failed\n" );
-        goto exit;
-    }
-
-    filesize = li_size.QuadPart;
-#else
-    if( ( filesize = lseek( fileno( fin ), 0, SEEK_END ) ) < 0 )
-    {
-        perror( "lseek" );
-        goto exit;
-    }
-#endif
-#endif
-
-    if( fseek( fin, 0, SEEK_SET ) < 0 )
-    {
-        mbedtls_fprintf( stderr, "fseek(0,SEEK_SET) failed\n" );
-        goto exit;
-    }
-
-    if( mode == MODE_ENCRYPT )
-    {
-        /*
-         * Generate the initialization vector as:
-         * IV = SHA-256( filesize || filename )[0..15]
-         */
-        for( i = 0; i < 8; i++ )
-            buffer[i] = (unsigned char)( filesize >> ( i << 3 ) );
-
-        p = argv[2];
-
-        mbedtls_md_starts( &sha_ctx );
-        mbedtls_md_update( &sha_ctx, buffer, 8 );
-        mbedtls_md_update( &sha_ctx, (unsigned char *) p, strlen( p ) );
-        mbedtls_md_finish( &sha_ctx, digest );
-
-        memcpy( IV, digest, 16 );
-
-        /*
-         * The last four bits in the IV are actually used
-         * to store the file size modulo the AES block size.
-         */
-        lastn = (int)( filesize & 0x0F );
-
-        IV[15] = (unsigned char)
-            ( ( IV[15] & 0xF0 ) | lastn );
-
-        /*
-         * Append the IV at the beginning of the output.
-         */
-        if( fwrite( IV, 1, 16, fout ) != 16 )
-        {
-            mbedtls_fprintf( stderr, "fwrite(%d bytes) failed\n", 16 );
-            goto exit;
-        }
-
-        /*
-         * Hash the IV and the secret key together 8192 times
-         * using the result to setup the AES context and HMAC.
-         */
-        memset( digest, 0,  32 );
-        memcpy( digest, IV, 16 );
-
-        for( i = 0; i < 8192; i++ )
-        {
-            mbedtls_md_starts( &sha_ctx );
-            mbedtls_md_update( &sha_ctx, digest, 32 );
-            mbedtls_md_update( &sha_ctx, key, keylen );
-            mbedtls_md_finish( &sha_ctx, digest );
-        }
-
-        mbedtls_aes_setkey_enc( &aes_ctx, digest, 256 );
-        mbedtls_md_hmac_starts( &sha_ctx, digest, 32 );
-
-        /*
-         * Encrypt and write the ciphertext.
-         */
-        for( offset = 0; offset < filesize; offset += 16 )
-        {
-            n = ( filesize - offset > 16 ) ? 16 : (int)
-                ( filesize - offset );
-
-            if( fread( buffer, 1, n, fin ) != (size_t) n )
-            {
-                mbedtls_fprintf( stderr, "fread(%d bytes) failed\n", n );
-                goto exit;
-            }
-
-            for( i = 0; i < 16; i++ )
-                buffer[i] = (unsigned char)( buffer[i] ^ IV[i] );
-
-            mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, buffer, buffer );
-            mbedtls_md_hmac_update( &sha_ctx, buffer, 16 );
-
-            if( fwrite( buffer, 1, 16, fout ) != 16 )
-            {
-                mbedtls_fprintf( stderr, "fwrite(%d bytes) failed\n", 16 );
-                goto exit;
-            }
-
-            memcpy( IV, buffer, 16 );
-        }
-
-        /*
-         * Finally write the HMAC.
-         */
-        mbedtls_md_hmac_finish( &sha_ctx, digest );
-
-        if( fwrite( digest, 1, 32, fout ) != 32 )
-        {
-            mbedtls_fprintf( stderr, "fwrite(%d bytes) failed\n", 16 );
-            goto exit;
-        }
-    }
-
-    if( mode == MODE_DECRYPT )
-    {
-        /*
-         *  The encrypted file must be structured as follows:
-         *
-         *        00 .. 15              Initialization Vector
-         *        16 .. 31              AES Encrypted Block #1
-         *           ..
-         *      N*16 .. (N+1)*16 - 1    AES Encrypted Block #N
-         *  (N+1)*16 .. (N+1)*16 + 32   HMAC-SHA-256(ciphertext)
-         */
-        if( filesize < 48 )
-        {
-            mbedtls_fprintf( stderr, "File too short to be encrypted.\n" );
-            goto exit;
-        }
-
-        if( ( filesize & 0x0F ) != 0 )
-        {
-            mbedtls_fprintf( stderr, "File size not a multiple of 16.\n" );
-            goto exit;
-        }
-
-        /*
-         * Subtract the IV + HMAC length.
-         */
-        filesize -= ( 16 + 32 );
-
-        /*
-         * Read the IV and original filesize modulo 16.
-         */
-        if( fread( buffer, 1, 16, fin ) != 16 )
-        {
-            mbedtls_fprintf( stderr, "fread(%d bytes) failed\n", 16 );
-            goto exit;
-        }
-
-        memcpy( IV, buffer, 16 );
-        lastn = IV[15] & 0x0F;
-
-        /*
-         * Hash the IV and the secret key together 8192 times
-         * using the result to setup the AES context and HMAC.
-         */
-        memset( digest, 0,  32 );
-        memcpy( digest, IV, 16 );
-
-        for( i = 0; i < 8192; i++ )
-        {
-            mbedtls_md_starts( &sha_ctx );
-            mbedtls_md_update( &sha_ctx, digest, 32 );
-            mbedtls_md_update( &sha_ctx, key, keylen );
-            mbedtls_md_finish( &sha_ctx, digest );
-        }
-
-        mbedtls_aes_setkey_dec( &aes_ctx, digest, 256 );
-        mbedtls_md_hmac_starts( &sha_ctx, digest, 32 );
-
-        /*
-         * Decrypt and write the plaintext.
-         */
-        for( offset = 0; offset < filesize; offset += 16 )
-        {
-            if( fread( buffer, 1, 16, fin ) != 16 )
-            {
-                mbedtls_fprintf( stderr, "fread(%d bytes) failed\n", 16 );
-                goto exit;
-            }
-
-            memcpy( tmp, buffer, 16 );
-
-            mbedtls_md_hmac_update( &sha_ctx, buffer, 16 );
-            mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_DECRYPT, buffer, buffer );
-
-            for( i = 0; i < 16; i++ )
-                buffer[i] = (unsigned char)( buffer[i] ^ IV[i] );
-
-            memcpy( IV, tmp, 16 );
-
-            n = ( lastn > 0 && offset == filesize - 16 )
-                ? lastn : 16;
-
-            if( fwrite( buffer, 1, n, fout ) != (size_t) n )
-            {
-                mbedtls_fprintf( stderr, "fwrite(%d bytes) failed\n", n );
-                goto exit;
-            }
-        }
-
-        /*
-         * Verify the message authentication code.
-         */
-        mbedtls_md_hmac_finish( &sha_ctx, digest );
-
-        if( fread( buffer, 1, 32, fin ) != 32 )
-        {
-            mbedtls_fprintf( stderr, "fread(%d bytes) failed\n", 32 );
-            goto exit;
-        }
-
-        /* Use constant-time buffer comparison */
-        diff = 0;
-        for( i = 0; i < 32; i++ )
-            diff |= digest[i] ^ buffer[i];
-
-        if( diff != 0 )
-        {
-            mbedtls_fprintf( stderr, "HMAC check failed: wrong key, "
-                             "or file corrupted.\n" );
-            goto exit;
-        }
-    }
-
-    exit_code = MBEDTLS_EXIT_SUCCESS;
-
-exit:
-    if( fin )
-        fclose( fin );
-    if( fout )
-        fclose( fout );
-
-    /* Zeroize all command line arguments to also cover
-       the case when the user has missed or reordered some,
-       in which case the key might not be in argv[4]. */
-    for( i = 0; i < (unsigned int) argc; i++ )
-        mbedtls_platform_zeroize( argv[i], strlen( argv[i] ) );
-
-    mbedtls_platform_zeroize( IV,     sizeof( IV ) );
-    mbedtls_platform_zeroize( key,    sizeof( key ) );
-    mbedtls_platform_zeroize( tmp,    sizeof( tmp ) );
-    mbedtls_platform_zeroize( buffer, sizeof( buffer ) );
-    mbedtls_platform_zeroize( digest, sizeof( digest ) );
-
-    mbedtls_aes_free( &aes_ctx );
-    mbedtls_md_free( &sha_ctx );
-
-    mbedtls_exit( exit_code );
-}
-#endif /* MBEDTLS_AES_C && MBEDTLS_SHA256_C && MBEDTLS_FS_IO */
diff --git a/programs/ssl/dtls_client.c b/programs/ssl/dtls_client.c
index 69d4f33..fa7a087 100644
--- a/programs/ssl/dtls_client.c
+++ b/programs/ssl/dtls_client.c
@@ -218,6 +218,7 @@
     mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL );
     mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
     mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
+    mbedtls_ssl_conf_read_timeout( &conf, READ_TIMEOUT_MS );
 
     if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
     {
diff --git a/programs/ssl/dtls_server.c b/programs/ssl/dtls_server.c
index 8339d9d..cebeffa 100644
--- a/programs/ssl/dtls_server.c
+++ b/programs/ssl/dtls_server.c
@@ -114,7 +114,7 @@
 #include "mbedtls/ssl_cache.h"
 #endif
 
-#define READ_TIMEOUT_MS 10000   /* 5 seconds */
+#define READ_TIMEOUT_MS 10000   /* 10 seconds */
 #define DEBUG_LEVEL 0
 
 
@@ -250,6 +250,7 @@
 
     mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
     mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
+    mbedtls_ssl_conf_read_timeout( &conf, READ_TIMEOUT_MS );
 
 #if defined(MBEDTLS_SSL_CACHE_C)
     mbedtls_ssl_conf_session_cache( &conf, &cache,
diff --git a/programs/ssl/query_config.c b/programs/ssl/query_config.c
index 798c917..0a7eb1a 100644
--- a/programs/ssl/query_config.c
+++ b/programs/ssl/query_config.c
@@ -1475,6 +1475,14 @@
     }
 #endif /* MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT */
 
+#if defined(MBEDTLS_TEST_HOOKS)
+    if( strcmp( "MBEDTLS_TEST_HOOKS", config ) == 0 )
+    {
+        MACRO_EXPANSION_TO_STR( MBEDTLS_TEST_HOOKS );
+        return( 0 );
+    }
+#endif /* MBEDTLS_TEST_HOOKS */
+
 #if defined(MBEDTLS_THREADING_ALT)
     if( strcmp( "MBEDTLS_THREADING_ALT", config ) == 0 )
     {
diff --git a/programs/test/udp_proxy.c b/programs/test/udp_proxy.c
index 66ead4a..d7146b1 100644
--- a/programs/test/udp_proxy.c
+++ b/programs/test/udp_proxy.c
@@ -671,26 +671,21 @@
 }
 
 /*
- * Avoid dropping or delaying a packet that was already dropped twice: this
- * only results in uninteresting timeouts. We can't rely on type to identify
- * packets, since during renegotiation they're all encrypted.  So, rely on
- * size mod 2048 (which is usually just size).
- */
-static unsigned char dropped[2048] = { 0 };
-#define DROP_MAX 2
-
-/* We only drop packets at the level of entire datagrams, not at the level
+ * Avoid dropping or delaying a packet that was already dropped or delayed
+ * ("held") twice: this only results in uninteresting timeouts. We can't rely
+ * on type to identify packets, since during renegotiation they're all
+ * encrypted. So, rely on size mod 2048 (which is usually just size).
+ *
+ * We only hold packets at the level of entire datagrams, not at the level
  * of records. In particular, if the peer changes the way it packs multiple
  * records into a single datagram, we don't necessarily count the number of
- * times a record has been dropped correctly. However, the only known reason
+ * times a record has been held correctly. However, the only known reason
  * why a peer would change datagram packing is disabling the latter on
- * retransmission, in which case we'd drop involved records at most
- * DROP_MAX + 1 times. */
-void update_dropped( const packet *p )
-{
-    size_t id = p->len % sizeof( dropped );
-    ++dropped[id];
-}
+ * retransmission, in which case we'd hold involved records at most
+ * HOLD_MAX + 1 times.
+ */
+static unsigned char held[2048] = { 0 };
+#define HOLD_MAX 2
 
 int handle_message( const char *way,
                     mbedtls_net_context *dst,
@@ -717,7 +712,7 @@
     cur.dst  = dst;
     print_packet( &cur, NULL );
 
-    id = cur.len % sizeof( dropped );
+    id = cur.len % sizeof( held );
 
     if( strcmp( way, "S <- C" ) == 0 )
     {
@@ -758,10 +753,10 @@
           ! ( opt.protect_hvr &&
               strcmp( cur.type, "HelloVerifyRequest" ) == 0 ) &&
           cur.len != (size_t) opt.protect_len &&
-          dropped[id] < DROP_MAX &&
+          held[id] < HOLD_MAX &&
           rand() % opt.drop == 0 ) )
     {
-        update_dropped( &cur );
+        ++held[id];
     }
     else if( ( opt.delay_ccs == 1 &&
                strcmp( cur.type, "ChangeCipherSpec" ) == 0 ) ||
@@ -770,9 +765,10 @@
                ! ( opt.protect_hvr &&
                    strcmp( cur.type, "HelloVerifyRequest" ) == 0 ) &&
                cur.len != (size_t) opt.protect_len &&
-               dropped[id] < DROP_MAX &&
+               held[id] < HOLD_MAX &&
                rand() % opt.delay == 0 ) )
     {
+        ++held[id];
         delay_packet( &cur );
     }
     else
@@ -883,7 +879,7 @@
      * 3. Forward packets forever (kill the process to terminate it)
      */
     clear_pending();
-    memset( dropped, 0, sizeof( dropped ) );
+    memset( held, 0, sizeof( held ) );
 
     nb_fds = client_fd.fd;
     if( nb_fds < server_fd.fd )
@@ -991,8 +987,8 @@
 
     for( delay_idx = 0; delay_idx < MAX_DELAYED_HS; delay_idx++ )
     {
-        mbedtls_free( opt.delay_cli + delay_idx );
-        mbedtls_free( opt.delay_srv + delay_idx );
+        mbedtls_free( opt.delay_cli[delay_idx] );
+        mbedtls_free( opt.delay_srv[delay_idx] );
     }
 
     mbedtls_net_free( &client_fd );
diff --git a/scripts/assemble_changelog.py b/scripts/assemble_changelog.py
index 02bae25..b7dee47 100755
--- a/scripts/assemble_changelog.py
+++ b/scripts/assemble_changelog.py
@@ -101,6 +101,9 @@
     b'Changes',
 )
 
+# The maximum line length for an entry
+MAX_LINE_LENGTH = 80
+
 CategoryContent = namedtuple('CategoryContent', [
     'name', 'title_line', # Title text and line number of the title
     'body', 'body_line', # Body text and starting line number of the body
@@ -225,6 +228,8 @@
     # a version that is not yet released. Something like "3.1a" is accepted.
     _version_number_re = re.compile(br'[0-9]+\.[0-9A-Za-z.]+')
     _incomplete_version_number_re = re.compile(br'.*\.[A-Za-z]')
+    _only_url_re = re.compile(br'^\s*\w+://\S+\s*$')
+    _has_url_re = re.compile(br'.*://.*')
 
     def add_categories_from_text(self, filename, line_offset,
                                  text, allow_unknown_category):
@@ -241,6 +246,21 @@
                                        line_offset + category.title_line,
                                        'Unknown category: "{}"',
                                        category.name.decode('utf8'))
+
+            body_split = category.body.splitlines()
+
+            for line_number, line in enumerate(body_split, 1):
+                if not self._only_url_re.match(line) and \
+                   len(line) > MAX_LINE_LENGTH:
+                    long_url_msg = '. URL exceeding length limit must be alone in its line.' \
+                        if self._has_url_re.match(line) else ""
+                    raise InputFormatError(filename,
+                                           category.body_line + line_number,
+                                           'Line is longer than allowed: '
+                                           'Length {} (Max {}){}',
+                                           len(line), MAX_LINE_LENGTH,
+                                           long_url_msg)
+
             self.categories[category.name] += category.body
 
     def __init__(self, input_stream, changelog_format):
diff --git a/scripts/config.pl b/scripts/config.pl
index e5cc697..35a0af2 100755
--- a/scripts/config.pl
+++ b/scripts/config.pl
@@ -66,8 +66,9 @@
 #
 # The baremetal configuration excludes options that require a library or
 # operating system feature that is typically not present on bare metal
-# systems. Features that are excluded from "full" won't be in "baremetal"
-# either.
+# systems. It also excludes debugging features that increase the code size
+# of other modules.
+# Features that are excluded from "full" won't be in "baremetal" either.
 
 use warnings;
 use strict;
@@ -136,6 +137,7 @@
 
 # Things that should be disabled in "baremetal"
 my @excluded_baremetal = qw(
+MBEDTLS_DEBUG_C
 MBEDTLS_ENTROPY_NV_SEED
 MBEDTLS_FS_IO
 MBEDTLS_HAVEGE_C
@@ -147,6 +149,7 @@
 MBEDTLS_PLATFORM_FPRINTF_ALT
 MBEDTLS_PLATFORM_NV_SEED_ALT
 MBEDTLS_PLATFORM_TIME_ALT
+MBEDTLS_TEST_HOOKS
 MBEDTLS_THREADING_C
 MBEDTLS_THREADING_PTHREAD
 MBEDTLS_TIMING_C
diff --git a/scripts/generate_errors.pl b/scripts/generate_errors.pl
index a2ff4f6..1239adb 100755
--- a/scripts/generate_errors.pl
+++ b/scripts/generate_errors.pl
@@ -48,6 +48,7 @@
 # **********
 
 use strict;
+use warnings;
 
 my ($include_dir, $data_dir, $error_file);
 
@@ -80,26 +81,54 @@
                              PEM PK PKCS12 PKCS5
                              RSA SSL X509 );
 
-my $line_separator = $/;
 undef $/;
 
 open(FORMAT_FILE, "$error_format_file") or die "Opening error format file '$error_format_file': $!";
 my $error_format = <FORMAT_FILE>;
 close(FORMAT_FILE);
 
-$/ = $line_separator;
-
 my @files = <$include_dir/*.h>;
 my @necessary_include_files;
 my @matches;
 foreach my $file (@files) {
     open(FILE, "$file");
-    my @grep_res = grep(/^\s*#define\s+MBEDTLS_ERR_\w+\s+\-0x[0-9A-Fa-f]+/, <FILE>);
-    push(@matches, @grep_res);
+    my $content = <FILE>;
     close FILE;
-    my $include_name = $file;
-    $include_name =~ s!.*/!!;
-    push @necessary_include_files, $include_name if @grep_res;
+    my $found = 0;
+    while ($content =~ m[
+            # Both the before-comment and the after-comment are optional.
+            # Only the comment content is a regex capture group. The comment
+            # start and end parts are outside the capture group.
+            (?:/\*[*!](?!<)             # Doxygen before-comment start
+                ((?:[^*]|\*+[^*/])*)    # $1: Comment content (no */ inside)
+                \*/)?                   # Comment end
+            \s*\#\s*define\s+(MBEDTLS_ERR_\w+)  # $2: name
+            \s+\-(0[Xx][0-9A-Fa-f]+)\s*         # $3: value (without the sign)
+            (?:/\*[*!]<                 # Doxygen after-comment start
+                ((?:[^*]|\*+[^*/])*)    # $4: Comment content (no */ inside)
+                \*/)?                   # Comment end
+    ]gsx) {
+        my ($before, $name, $value, $after) = ($1, $2, $3, $4);
+        # Discard Doxygen comments that are coincidentally present before
+        # an error definition but not attached to it. This is ad hoc, based
+        # on what actually matters (or mattered at some point).
+        undef $before if defined($before) && $before =~ /\s*\\name\s/s;
+        die "Description neither before nor after $name in $file\n"
+          if !defined($before) && !defined($after);
+        die "Description both before and after $name in $file\n"
+          if defined($before) && defined($after);
+        my $description = (defined($before) ? $before : $after);
+        $description =~ s/^\s+//;
+        $description =~ s/\n( *\*)? */ /g;
+        $description =~ s/\.?\s+$//;
+        push @matches, [$name, $value, $description];
+        ++$found;
+    }
+    if ($found) {
+        my $include_name = $file;
+        $include_name =~ s!.*/!!;
+        push @necessary_include_files, $include_name;
+    }
 }
 
 my $ll_old_define = "";
@@ -113,20 +142,14 @@
 
 my %error_codes_seen;
 
-foreach my $line (@matches)
+foreach my $match (@matches)
 {
-    next if ($line =~ /compat-1.2.h/);
-    my ($error_name, $error_code) = $line =~ /(MBEDTLS_ERR_\w+)\s+\-(0x\w+)/;
-    my ($description) = $line =~ /\/\*\*< (.*?)\.? \*\//;
+    my ($error_name, $error_code, $description) = @$match;
 
     die "Duplicated error code: $error_code ($error_name)\n"
         if( $error_codes_seen{$error_code}++ );
 
     $description =~ s/\\/\\\\/g;
-    if ($description eq "") {
-        $description = "DESCRIPTION MISSING";
-        warn "Missing description for $error_name\n";
-    }
 
     my ($module_name) = $error_name =~ /^MBEDTLS_ERR_([^_]+)/;
 
diff --git a/tests/Makefile b/tests/Makefile
index 1555b55..99c89a3 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -39,13 +39,16 @@
 ifdef SHARED
 SHARED_SUFFIX=.$(DLEXT)
 endif
-PYTHON ?= python
 else
 DLEXT ?= so
 EXEXT=
 SHARED_SUFFIX=
-# python2 for POSIX since FreeBSD has only python2 as default.
-PYTHON ?= python2
+endif
+
+ifdef WINDOWS
+PYTHON ?= python
+else
+PYTHON ?= $(shell if type python3 >/dev/null 2>/dev/null; then echo python3; else echo python; fi)
 endif
 
 # Zlib shared library extensions:
@@ -63,7 +66,7 @@
 
 .SILENT:
 
-.PHONY: all check test clean
+.PHONY: all c_files check test clean
 
 all: $(BINARIES)
 
@@ -71,6 +74,7 @@
 	$(MAKE) -C ../library
 
 C_FILES := $(addsuffix .c,$(APPS))
+c_files: $(C_FILES)
 
 # Wildcard target for test code generation:
 # A .c file is generated for each .data file in the suites/ directory. Each .c
diff --git a/tests/compat.sh b/tests/compat.sh
index 8905430..f2598b7 100755
--- a/tests/compat.sh
+++ b/tests/compat.sh
@@ -932,10 +932,23 @@
     fi
 
     M_SERVER_ARGS="server_port=$PORT server_addr=0.0.0.0 force_version=$MODE arc4=1"
-    O_SERVER_ARGS="-accept $PORT -cipher NULL,ALL -$MODE -dhparam data_files/dhparams.pem"
+    O_SERVER_ARGS="-accept $PORT -cipher NULL,ALL -$MODE"
     G_SERVER_ARGS="-p $PORT --http $G_MODE"
     G_SERVER_PRIO="NORMAL:${G_PRIO_CCM}+ARCFOUR-128:+NULL:+MD5:+PSK:+DHE-PSK:+ECDHE-PSK:+SHA256:+SHA384:+RSA-PSK:-VERS-TLS-ALL:$G_PRIO_MODE"
 
+    # The default prime for `openssl s_server` depends on the version:
+    # * OpenSSL <= 1.0.2a: 512-bit
+    # * OpenSSL 1.0.2b to 1.1.1b: 1024-bit
+    # * OpenSSL >= 1.1.1c: 2048-bit
+    # Mbed TLS wants >=1024, so force that for older versions. Don't force
+    # it for newer versions, which reject a 1024-bit prime. Indifferently
+    # force it or not for intermediate versions.
+    case $($OPENSSL_CMD version) in
+        "OpenSSL 1.0"*)
+            O_SERVER_ARGS="$O_SERVER_ARGS -dhparam data_files/dhparams.pem"
+            ;;
+    esac
+
     # with OpenSSL 1.0.1h, -www, -WWW and -HTTP break DTLS handshakes
     if is_dtls "$MODE"; then
         O_SERVER_ARGS="$O_SERVER_ARGS"
diff --git a/tests/data_files/Makefile b/tests/data_files/Makefile
index 883f123..d3e4476 100644
--- a/tests/data_files/Makefile
+++ b/tests/data_files/Makefile
@@ -1061,6 +1061,16 @@
 all_final += cert_md5.crt
 
 ################################################################
+#### Diffie-Hellman parameters
+################################################################
+
+dh.998.pem:
+	$(OPENSSL) dhparam -out $@ -text 998
+
+dh.999.pem:
+	$(OPENSSL) dhparam -out $@ -text 999
+
+################################################################
 #### Meta targets
 ################################################################
 
diff --git a/tests/data_files/dh.998.pem b/tests/data_files/dh.998.pem
new file mode 100644
index 0000000..96d6cf2
--- /dev/null
+++ b/tests/data_files/dh.998.pem
@@ -0,0 +1,17 @@
+    DH Parameters: (998 bit)
+        prime:
+            39:5f:30:c0:7b:06:b7:6a:49:c6:c0:81:1f:39:77:
+            b3:35:e2:8d:66:fc:6a:6e:94:f3:df:97:f2:89:31:
+            6c:75:39:08:16:d1:a4:b8:0c:68:c5:63:21:61:eb:
+            48:2d:77:99:08:1d:67:38:37:0a:cd:cf:39:b6:3c:
+            9d:8a:e5:85:3c:71:e3:4b:3e:1e:b9:80:e3:cc:7a:
+            fd:84:05:b0:df:36:15:29:4e:3e:23:3b:c3:ae:6b:
+            c7:11:b9:64:43:40:75:c7:4a:ef:a7:2d:00:e2:62:
+            8f:93:78:96:8f:2c:25:8d:7d:1f:eb:5c:3c:bf:51:
+            de:f8:08:25:db
+        generator: 2 (0x2)
+-----BEGIN DH PARAMETERS-----
+MIGCAn05XzDAewa3aknGwIEfOXezNeKNZvxqbpTz35fyiTFsdTkIFtGkuAxoxWMh
+YetILXeZCB1nODcKzc85tjydiuWFPHHjSz4euYDjzHr9hAWw3zYVKU4+IzvDrmvH
+EblkQ0B1x0rvpy0A4mKPk3iWjywljX0f61w8v1He+Agl2wIBAg==
+-----END DH PARAMETERS-----
diff --git a/tests/data_files/dh.999.pem b/tests/data_files/dh.999.pem
new file mode 100644
index 0000000..6e3ceb3
--- /dev/null
+++ b/tests/data_files/dh.999.pem
@@ -0,0 +1,17 @@
+    DH Parameters: (999 bit)
+        prime:
+            4f:b8:d2:d8:3c:b3:02:c9:64:f5:99:fe:61:cc:b3:
+            69:1c:ba:bb:a2:33:db:38:2f:85:87:b7:12:fb:69:
+            6e:a5:32:3e:ff:24:df:c4:61:07:0c:e1:88:72:fa:
+            14:d4:22:65:18:66:09:7e:43:35:c4:5a:62:f7:0a:
+            69:be:45:71:6e:ac:c5:56:d8:22:9e:c4:9c:23:2b:
+            bd:6d:3b:b6:02:4f:5d:12:a7:ac:90:b8:9e:be:93:
+            82:bc:09:7c:cd:e1:09:21:1e:3d:69:2a:76:41:00:
+            68:6d:b7:e8:e8:df:d6:1b:82:93:d9:21:4a:ea:71:
+            f2:e6:c4:94:03
+        generator: 2 (0x2)
+-----BEGIN DH PARAMETERS-----
+MIGCAn1PuNLYPLMCyWT1mf5hzLNpHLq7ojPbOC+Fh7cS+2lupTI+/yTfxGEHDOGI
+cvoU1CJlGGYJfkM1xFpi9wppvkVxbqzFVtginsScIyu9bTu2Ak9dEqeskLievpOC
+vAl8zeEJIR49aSp2QQBobbfo6N/WG4KT2SFK6nHy5sSUAwIBAg==
+-----END DH PARAMETERS-----
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index a2a26b4..f7e5a73 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -179,6 +179,7 @@
     : ${ARMC5_BIN_DIR:=/usr/bin}
     : ${ARMC6_BIN_DIR:=/usr/bin}
     : ${ARM_NONE_EABI_GCC_PREFIX:=arm-none-eabi-}
+    : ${ARM_LINUX_GNUEABI_GCC_PREFIX:=arm-linux-gnueabi-}
 
     # if MAKEFLAGS is not set add the -j option to speed up invocations of make
     if [ -z "${MAKEFLAGS+set}" ]; then
@@ -247,6 +248,9 @@
      --arm-none-eabi-gcc-prefix=<string>
                         Prefix for a cross-compiler for arm-none-eabi
                         (default: "${ARM_NONE_EABI_GCC_PREFIX}")
+     --arm-linux-gnueabi-gcc-prefix=<string>
+                        Prefix for a cross-compiler for arm-linux-gnueabi
+                        (default: "${ARM_LINUX_GNUEABI_GCC_PREFIX}")
      --armcc            Run ARM Compiler builds (on by default).
      --except           Exclude the COMPONENTs listed on the command line,
                         instead of running only those.
@@ -378,6 +382,7 @@
     while [ $# -gt 0 ]; do
         case "$1" in
             --arm-none-eabi-gcc-prefix) shift; ARM_NONE_EABI_GCC_PREFIX="$1";;
+            --arm-linux-gnueabi-gcc-prefix) shift; ARM_LINUX_GNUEABI_GCC_PREFIX="$1";;
             --armcc) no_armcc=;;
             --armc5-bin-dir) shift; ARMC5_BIN_DIR="$1";;
             --armc6-bin-dir) shift; ARMC6_BIN_DIR="$1";;
@@ -691,6 +696,18 @@
     record_status tests/scripts/doxygen.sh
 }
 
+component_check_python2 () {
+    # Check that what used to work with Python 2 still works with Python 2.
+    msg "check: python2 compatibility"
+    mkdir -p tests/with_python2 tests/with_python3
+    make -C tests PYTHON=python2 c_files
+    mv tests/test_suite_*.c tests/with_python2/
+    make -C tests PYTHON=python3 c_files
+    mv tests/test_suite_*.c tests/with_python3/
+    diff -r tests/with_python2 tests/with_python3
+    rm -rf tests/with_python2 tests/with_python3
+}
+
 
 
 ################################################################
@@ -890,11 +907,21 @@
     CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
     make
 
-    msg "test: no HMAC_DRBG"
+    msg "test: Full minus HMAC_DRBG - main suites"
     make test
 
-    # No ssl-opt.sh/compat.sh as they never use HMAC_DRBG so far,
-    # so there's little value in running those lengthy tests here.
+    # Normally our ECDSA implementation uses deterministic ECDSA. But since
+    # HMAC_DRBG is disabled in this configuration, randomized ECDSA is used
+    # instead.
+    # Test SSL with non-deterministic ECDSA. Only test features that
+    # might be affected by how ECDSA signature is performed.
+    msg "test: Full minus HMAC_DRBG - ssl-opt.sh (subset)"
+    if_build_succeeded tests/ssl-opt.sh -f 'Default\|SSL async private: sign'
+
+    # To save time, only test one protocol version, since this part of
+    # the protocol is identical in (D)TLS up to 1.2.
+    msg "test: Full minus HMAC_DRBG - compat.sh (ECDSA)"
+    if_build_succeeded tests/compat.sh -m tls1_2 -t 'ECDSA'
 }
 
 component_test_no_drbg_all_hashes () {
@@ -1314,7 +1341,7 @@
     msg "build: malloc(0) returns NULL (ASan+UBSan build)"
     scripts/config.pl full
     scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C
-    make CC=gcc CFLAGS="'-DMBEDTLS_CONFIG_FILE=\"$PWD/tests/configs/config-wrapper-malloc-0-null.h\"' -O -Werror -Wall -Wextra -fsanitize=address,undefined" LDFLAGS='-fsanitize=address,undefined'
+    make CC=gcc CFLAGS="'-DMBEDTLS_CONFIG_FILE=\"$PWD/tests/configs/config-wrapper-malloc-0-null.h\"' -O $ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS"
 
     msg "test: malloc(0) returns NULL (ASan+UBSan build)"
     make test
@@ -1524,15 +1551,30 @@
     ${ARM_NONE_EABI_GCC_PREFIX}size library/*.o
 }
 
-component_build_arm_none_eabi_gcc_arm5vte () {
-    msg "build: ${ARM_NONE_EABI_GCC_PREFIX}gcc -march=arm5vte" # ~ 10s
+component_build_arm_linux_gnueabi_gcc_arm5vte () {
+    msg "build: ${ARM_LINUX_GNUEABI_GCC_PREFIX}gcc -march=arm5vte" # ~ 10s
     scripts/config.pl baremetal
     # Build for a target platform that's close to what Debian uses
     # for its "armel" distribution (https://wiki.debian.org/ArmEabiPort).
     # See https://github.com/ARMmbed/mbedtls/pull/2169 and comments.
-    # It would be better to build with arm-linux-gnueabi-gcc but
-    # we don't have that on our CI at this time.
-    make CC="${ARM_NONE_EABI_GCC_PREFIX}gcc" AR="${ARM_NONE_EABI_GCC_PREFIX}ar" CFLAGS='-Werror -Wall -Wextra -march=armv5te -O1' LDFLAGS='-march=armv5te' SHELL='sh -x' lib
+    # Build everything including programs, see for example
+    # https://github.com/ARMmbed/mbedtls/pull/3449#issuecomment-675313720
+    make CC="${ARM_LINUX_GNUEABI_GCC_PREFIX}gcc" AR="${ARM_LINUX_GNUEABI_GCC_PREFIX}ar" CFLAGS='-Werror -Wall -Wextra -march=armv5te -O1' LDFLAGS='-march=armv5te'
+
+    msg "size: ${ARM_LINUX_GNUEABI_GCC_PREFIX}gcc -march=armv5te -O1"
+    ${ARM_LINUX_GNUEABI_GCC_PREFIX}size library/*.o
+}
+support_build_arm_linux_gnueabi_gcc_arm5vte () {
+    type ${ARM_LINUX_GNUEABI_GCC_PREFIX}gcc >/dev/null 2>&1
+}
+
+component_build_arm_none_eabi_gcc_arm5vte () {
+    msg "build: ${ARM_NONE_EABI_GCC_PREFIX}gcc -march=arm5vte" # ~ 10s
+    scripts/config.pl baremetal
+    # This is an imperfect substitute for
+    # component_build_arm_linux_gnueabi_gcc_arm5vte
+    # in case the gcc-arm-linux-gnueabi toolchain is not available
+    make CC="${ARM_NONE_EABI_GCC_PREFIX}gcc" AR="${ARM_NONE_EABI_GCC_PREFIX}ar" CFLAGS='-std=c99 -Werror -Wall -Wextra -march=armv5te -O1' LDFLAGS='-march=armv5te' SHELL='sh -x' lib
 
     msg "size: ${ARM_NONE_EABI_GCC_PREFIX}gcc -march=armv5te -O1"
     ${ARM_NONE_EABI_GCC_PREFIX}size library/*.o
diff --git a/tests/scripts/basic-build-test.sh b/tests/scripts/basic-build-test.sh
index b8f6242..6781284 100755
--- a/tests/scripts/basic-build-test.sh
+++ b/tests/scripts/basic-build-test.sh
@@ -89,6 +89,11 @@
 : ${SEED:=1}
 export SEED
 
+# if MAKEFLAGS is not set add the -j option to speed up invocations of make
+if [ -z "${MAKEFLAGS+set}" ]; then
+    export MAKEFLAGS="-j"
+fi
+
 # To avoid setting OpenSSL and GnuTLS for each call to compat.sh and ssl-opt.sh
 # we just export the variables they require
 export OPENSSL_CMD="$OPENSSL"
@@ -113,7 +118,7 @@
 make clean
 cp "$CONFIG_H" "$CONFIG_BAK"
 scripts/config.pl full
-make -j
+make
 
 
 # Step 2 - Execute the tests
@@ -123,28 +128,44 @@
 if [ ! -f "seedfile" ]; then
     dd if=/dev/urandom of="seedfile" bs=64 count=1
 fi
+echo
 
 # Step 2a - Unit Tests (keep going even if some tests fail)
+echo '################ Unit tests ################'
 perl scripts/run-test-suites.pl -v 2 |tee unit-test-$TEST_OUTPUT
+echo '^^^^^^^^^^^^^^^^ Unit tests ^^^^^^^^^^^^^^^^'
 echo
 
 # Step 2b - System Tests (keep going even if some tests fail)
+echo
+echo '################ ssl-opt.sh ################'
+echo "ssl-opt.sh will use SEED=$SEED for udp_proxy"
 sh ssl-opt.sh |tee sys-test-$TEST_OUTPUT
+echo '^^^^^^^^^^^^^^^^ ssl-opt.sh ^^^^^^^^^^^^^^^^'
 echo
 
 # Step 2c - Compatibility tests (keep going even if some tests fail)
-sh compat.sh -m 'tls1 tls1_1 tls1_2 dtls1 dtls1_2' | \
-    tee compat-test-$TEST_OUTPUT
-OPENSSL_CMD="$OPENSSL_LEGACY"                               \
-    sh compat.sh -m 'ssl3' |tee -a compat-test-$TEST_OUTPUT
-OPENSSL_CMD="$OPENSSL_LEGACY"                                       \
-    GNUTLS_CLI="$GNUTLS_LEGACY_CLI"                                 \
-    GNUTLS_SERV="$GNUTLS_LEGACY_SERV"                               \
-    sh compat.sh -e '^$' -f 'NULL\|DES\|RC4\|ARCFOUR'         |     \
-    tee -a compat-test-$TEST_OUTPUT
-OPENSSL_CMD="$OPENSSL_NEXT"                     \
-    sh compat.sh -e '^$' -f 'ARIA\|CHACHA' |    \
-    tee -a compat-test-$TEST_OUTPUT
+echo '################ compat.sh ################'
+{
+    echo '#### compat.sh: Default versions'
+    sh compat.sh -m 'tls1 tls1_1 tls1_2 dtls1 dtls1_2'
+    echo
+
+    echo '#### compat.sh: legacy (SSLv3)'
+    OPENSSL_CMD="$OPENSSL_LEGACY" sh compat.sh -m 'ssl3'
+    echo
+
+    echo '#### compat.sh: legacy (null, DES, RC4)'
+    OPENSSL_CMD="$OPENSSL_LEGACY" \
+    GNUTLS_CLI="$GNUTLS_LEGACY_CLI" GNUTLS_SERV="$GNUTLS_LEGACY_SERV" \
+    sh compat.sh -e '^$' -f 'NULL\|DES\|RC4\|ARCFOUR'
+    echo
+
+    echo '#### compat.sh: next (ARIA, ChaCha)'
+    OPENSSL_CMD="$OPENSSL_NEXT" sh compat.sh -e '^$' -f 'ARIA\|CHACHA'
+    echo
+} | tee compat-test-$TEST_OUTPUT
+echo '^^^^^^^^^^^^^^^^ compat.sh ^^^^^^^^^^^^^^^^'
 echo
 
 # Step 3 - Process the coverage report
@@ -166,116 +187,126 @@
 echo "Test Report Summary"
 echo
 
-cd tests
+# A failure of the left-hand side of a pipe is ignored (this is a limitation
+# of sh). We'll use the presence of this file as a marker that the generation
+# of the report succeeded.
+rm -f "tests/basic-build-test-$$.ok"
 
-# Step 4a - Unit tests
-echo "Unit tests - tests/scripts/run-test-suites.pl"
+{
 
-PASSED_TESTS=$(tail -n6 unit-test-$TEST_OUTPUT|sed -n -e 's/test cases passed :[\t]*\([0-9]*\)/\1/p'| tr -d ' ')
-SKIPPED_TESTS=$(tail -n6 unit-test-$TEST_OUTPUT|sed -n -e 's/skipped :[ \t]*\([0-9]*\)/\1/p'| tr -d ' ')
-TOTAL_SUITES=$(tail -n6 unit-test-$TEST_OUTPUT|sed -n -e 's/.* (\([0-9]*\) .*, [0-9]* tests run)/\1/p'| tr -d ' ')
-FAILED_TESTS=$(tail -n6 unit-test-$TEST_OUTPUT|sed -n -e 's/failed :[\t]*\([0-9]*\)/\1/p' |tr -d ' ')
+    cd tests
 
-echo "No test suites     : $TOTAL_SUITES"
-echo "Passed             : $PASSED_TESTS"
-echo "Failed             : $FAILED_TESTS"
-echo "Skipped            : $SKIPPED_TESTS"
-echo "Total exec'd tests : $(($PASSED_TESTS + $FAILED_TESTS))"
-echo "Total avail tests  : $(($PASSED_TESTS + $FAILED_TESTS + $SKIPPED_TESTS))"
-echo
+    # Step 4a - Unit tests
+    echo "Unit tests - tests/scripts/run-test-suites.pl"
 
-TOTAL_PASS=$PASSED_TESTS
-TOTAL_FAIL=$FAILED_TESTS
-TOTAL_SKIP=$SKIPPED_TESTS
-TOTAL_AVAIL=$(($PASSED_TESTS + $FAILED_TESTS + $SKIPPED_TESTS))
-TOTAL_EXED=$(($PASSED_TESTS + $FAILED_TESTS))
+    PASSED_TESTS=$(tail -n6 unit-test-$TEST_OUTPUT|sed -n -e 's/test cases passed :[\t]*\([0-9]*\)/\1/p'| tr -d ' ')
+    SKIPPED_TESTS=$(tail -n6 unit-test-$TEST_OUTPUT|sed -n -e 's/skipped :[ \t]*\([0-9]*\)/\1/p'| tr -d ' ')
+    TOTAL_SUITES=$(tail -n6 unit-test-$TEST_OUTPUT|sed -n -e 's/.* (\([0-9]*\) .*, [0-9]* tests run)/\1/p'| tr -d ' ')
+    FAILED_TESTS=$(tail -n6 unit-test-$TEST_OUTPUT|sed -n -e 's/failed :[\t]*\([0-9]*\)/\1/p' |tr -d ' ')
 
-# Step 4b - TLS Options tests
-echo "TLS Options tests - tests/ssl-opt.sh"
+    echo "No test suites     : $TOTAL_SUITES"
+    echo "Passed             : $PASSED_TESTS"
+    echo "Failed             : $FAILED_TESTS"
+    echo "Skipped            : $SKIPPED_TESTS"
+    echo "Total exec'd tests : $(($PASSED_TESTS + $FAILED_TESTS))"
+    echo "Total avail tests  : $(($PASSED_TESTS + $FAILED_TESTS + $SKIPPED_TESTS))"
+    echo
 
-PASSED_TESTS=$(tail -n5 sys-test-$TEST_OUTPUT|sed -n -e 's/.* (\([0-9]*\) \/ [0-9]* tests ([0-9]* skipped))$/\1/p')
-SKIPPED_TESTS=$(tail -n5 sys-test-$TEST_OUTPUT|sed -n -e 's/.* ([0-9]* \/ [0-9]* tests (\([0-9]*\) skipped))$/\1/p')
-TOTAL_TESTS=$(tail -n5 sys-test-$TEST_OUTPUT|sed -n -e 's/.* ([0-9]* \/ \([0-9]*\) tests ([0-9]* skipped))$/\1/p')
-FAILED_TESTS=$(($TOTAL_TESTS - $PASSED_TESTS))
+    TOTAL_PASS=$PASSED_TESTS
+    TOTAL_FAIL=$FAILED_TESTS
+    TOTAL_SKIP=$SKIPPED_TESTS
+    TOTAL_AVAIL=$(($PASSED_TESTS + $FAILED_TESTS + $SKIPPED_TESTS))
+    TOTAL_EXED=$(($PASSED_TESTS + $FAILED_TESTS))
 
-echo "Passed             : $PASSED_TESTS"
-echo "Failed             : $FAILED_TESTS"
-echo "Skipped            : $SKIPPED_TESTS"
-echo "Total exec'd tests : $TOTAL_TESTS"
-echo "Total avail tests  : $(($TOTAL_TESTS + $SKIPPED_TESTS))"
-echo
+    # Step 4b - TLS Options tests
+    echo "TLS Options tests - tests/ssl-opt.sh"
 
-TOTAL_PASS=$(($TOTAL_PASS+$PASSED_TESTS))
-TOTAL_FAIL=$(($TOTAL_FAIL+$FAILED_TESTS))
-TOTAL_SKIP=$(($TOTAL_SKIP+$SKIPPED_TESTS))
-TOTAL_AVAIL=$(($TOTAL_AVAIL + $TOTAL_TESTS + $SKIPPED_TESTS))
-TOTAL_EXED=$(($TOTAL_EXED + $TOTAL_TESTS))
+    PASSED_TESTS=$(tail -n5 sys-test-$TEST_OUTPUT|sed -n -e 's/.* (\([0-9]*\) \/ [0-9]* tests ([0-9]* skipped))$/\1/p')
+    SKIPPED_TESTS=$(tail -n5 sys-test-$TEST_OUTPUT|sed -n -e 's/.* ([0-9]* \/ [0-9]* tests (\([0-9]*\) skipped))$/\1/p')
+    TOTAL_TESTS=$(tail -n5 sys-test-$TEST_OUTPUT|sed -n -e 's/.* ([0-9]* \/ \([0-9]*\) tests ([0-9]* skipped))$/\1/p')
+    FAILED_TESTS=$(($TOTAL_TESTS - $PASSED_TESTS))
+
+    echo "Passed             : $PASSED_TESTS"
+    echo "Failed             : $FAILED_TESTS"
+    echo "Skipped            : $SKIPPED_TESTS"
+    echo "Total exec'd tests : $TOTAL_TESTS"
+    echo "Total avail tests  : $(($TOTAL_TESTS + $SKIPPED_TESTS))"
+    echo
+
+    TOTAL_PASS=$(($TOTAL_PASS+$PASSED_TESTS))
+    TOTAL_FAIL=$(($TOTAL_FAIL+$FAILED_TESTS))
+    TOTAL_SKIP=$(($TOTAL_SKIP+$SKIPPED_TESTS))
+    TOTAL_AVAIL=$(($TOTAL_AVAIL + $TOTAL_TESTS + $SKIPPED_TESTS))
+    TOTAL_EXED=$(($TOTAL_EXED + $TOTAL_TESTS))
 
 
-# Step 4c - System Compatibility tests
-echo "System/Compatibility tests - tests/compat.sh"
+    # Step 4c - System Compatibility tests
+    echo "System/Compatibility tests - tests/compat.sh"
 
-PASSED_TESTS=$(cat compat-test-$TEST_OUTPUT | sed -n -e 's/.* (\([0-9]*\) \/ [0-9]* tests ([0-9]* skipped))$/\1/p' | awk 'BEGIN{ s = 0 } { s += $1 } END{ print s }')
-SKIPPED_TESTS=$(cat compat-test-$TEST_OUTPUT | sed -n -e 's/.* ([0-9]* \/ [0-9]* tests (\([0-9]*\) skipped))$/\1/p' | awk 'BEGIN{ s = 0 } { s += $1 } END{ print s }')
-EXED_TESTS=$(cat compat-test-$TEST_OUTPUT | sed -n -e 's/.* ([0-9]* \/ \([0-9]*\) tests ([0-9]* skipped))$/\1/p' | awk 'BEGIN{ s = 0 } { s += $1 } END{ print s }')
-FAILED_TESTS=$(($EXED_TESTS - $PASSED_TESTS))
+    PASSED_TESTS=$(cat compat-test-$TEST_OUTPUT | sed -n -e 's/.* (\([0-9]*\) \/ [0-9]* tests ([0-9]* skipped))$/\1/p' | awk 'BEGIN{ s = 0 } { s += $1 } END{ print s }')
+    SKIPPED_TESTS=$(cat compat-test-$TEST_OUTPUT | sed -n -e 's/.* ([0-9]* \/ [0-9]* tests (\([0-9]*\) skipped))$/\1/p' | awk 'BEGIN{ s = 0 } { s += $1 } END{ print s }')
+    EXED_TESTS=$(cat compat-test-$TEST_OUTPUT | sed -n -e 's/.* ([0-9]* \/ \([0-9]*\) tests ([0-9]* skipped))$/\1/p' | awk 'BEGIN{ s = 0 } { s += $1 } END{ print s }')
+    FAILED_TESTS=$(($EXED_TESTS - $PASSED_TESTS))
 
-echo "Passed             : $PASSED_TESTS"
-echo "Failed             : $FAILED_TESTS"
-echo "Skipped            : $SKIPPED_TESTS"
-echo "Total exec'd tests : $EXED_TESTS"
-echo "Total avail tests  : $(($EXED_TESTS + $SKIPPED_TESTS))"
-echo
+    echo "Passed             : $PASSED_TESTS"
+    echo "Failed             : $FAILED_TESTS"
+    echo "Skipped            : $SKIPPED_TESTS"
+    echo "Total exec'd tests : $EXED_TESTS"
+    echo "Total avail tests  : $(($EXED_TESTS + $SKIPPED_TESTS))"
+    echo
 
-TOTAL_PASS=$(($TOTAL_PASS+$PASSED_TESTS))
-TOTAL_FAIL=$(($TOTAL_FAIL+$FAILED_TESTS))
-TOTAL_SKIP=$(($TOTAL_SKIP+$SKIPPED_TESTS))
-TOTAL_AVAIL=$(($TOTAL_AVAIL + $EXED_TESTS + $SKIPPED_TESTS))
-TOTAL_EXED=$(($TOTAL_EXED + $EXED_TESTS))
+    TOTAL_PASS=$(($TOTAL_PASS+$PASSED_TESTS))
+    TOTAL_FAIL=$(($TOTAL_FAIL+$FAILED_TESTS))
+    TOTAL_SKIP=$(($TOTAL_SKIP+$SKIPPED_TESTS))
+    TOTAL_AVAIL=$(($TOTAL_AVAIL + $EXED_TESTS + $SKIPPED_TESTS))
+    TOTAL_EXED=$(($TOTAL_EXED + $EXED_TESTS))
 
 
-# Step 4d - Grand totals
-echo "-------------------------------------------------------------------------"
-echo "Total tests"
+    # Step 4d - Grand totals
+    echo "-------------------------------------------------------------------------"
+    echo "Total tests"
 
-echo "Total Passed       : $TOTAL_PASS"
-echo "Total Failed       : $TOTAL_FAIL"
-echo "Total Skipped      : $TOTAL_SKIP"
-echo "Total exec'd tests : $TOTAL_EXED"
-echo "Total avail tests  : $TOTAL_AVAIL"
-echo
+    echo "Total Passed       : $TOTAL_PASS"
+    echo "Total Failed       : $TOTAL_FAIL"
+    echo "Total Skipped      : $TOTAL_SKIP"
+    echo "Total exec'd tests : $TOTAL_EXED"
+    echo "Total avail tests  : $TOTAL_AVAIL"
+    echo
 
 
-# Step 4e - Coverage
-echo "Coverage"
+    # Step 4e - Coverage
+    echo "Coverage"
 
-LINES_TESTED=$(tail -n4 cov-$TEST_OUTPUT|sed -n -e 's/  lines......: [0-9]*.[0-9]% (\([0-9]*\) of [0-9]* lines)/\1/p')
-LINES_TOTAL=$(tail -n4 cov-$TEST_OUTPUT|sed -n -e 's/  lines......: [0-9]*.[0-9]% ([0-9]* of \([0-9]*\) lines)/\1/p')
-FUNCS_TESTED=$(tail -n4 cov-$TEST_OUTPUT|sed -n -e 's/  functions..: [0-9]*.[0-9]% (\([0-9]*\) of [0-9]* functions)$/\1/p')
-FUNCS_TOTAL=$(tail -n4 cov-$TEST_OUTPUT|sed -n -e 's/  functions..: [0-9]*.[0-9]% ([0-9]* of \([0-9]*\) functions)$/\1/p')
-BRANCHES_TESTED=$(tail -n4 cov-$TEST_OUTPUT|sed -n -e 's/  branches...: [0-9]*.[0-9]% (\([0-9]*\) of [0-9]* branches)$/\1/p')
-BRANCHES_TOTAL=$(tail -n4 cov-$TEST_OUTPUT|sed -n -e 's/  branches...: [0-9]*.[0-9]% ([0-9]* of \([0-9]*\) branches)$/\1/p')
+    LINES_TESTED=$(tail -n4 cov-$TEST_OUTPUT|sed -n -e 's/  lines......: [0-9]*.[0-9]% (\([0-9]*\) of [0-9]* lines)/\1/p')
+    LINES_TOTAL=$(tail -n4 cov-$TEST_OUTPUT|sed -n -e 's/  lines......: [0-9]*.[0-9]% ([0-9]* of \([0-9]*\) lines)/\1/p')
+    FUNCS_TESTED=$(tail -n4 cov-$TEST_OUTPUT|sed -n -e 's/  functions..: [0-9]*.[0-9]% (\([0-9]*\) of [0-9]* functions)$/\1/p')
+    FUNCS_TOTAL=$(tail -n4 cov-$TEST_OUTPUT|sed -n -e 's/  functions..: [0-9]*.[0-9]% ([0-9]* of \([0-9]*\) functions)$/\1/p')
+    BRANCHES_TESTED=$(tail -n4 cov-$TEST_OUTPUT|sed -n -e 's/  branches...: [0-9]*.[0-9]% (\([0-9]*\) of [0-9]* branches)$/\1/p')
+    BRANCHES_TOTAL=$(tail -n4 cov-$TEST_OUTPUT|sed -n -e 's/  branches...: [0-9]*.[0-9]% ([0-9]* of \([0-9]*\) branches)$/\1/p')
 
-LINES_PERCENT=$((1000*$LINES_TESTED/$LINES_TOTAL))
-LINES_PERCENT="$(($LINES_PERCENT/10)).$(($LINES_PERCENT-($LINES_PERCENT/10)*10))"
+    LINES_PERCENT=$((1000*$LINES_TESTED/$LINES_TOTAL))
+    LINES_PERCENT="$(($LINES_PERCENT/10)).$(($LINES_PERCENT-($LINES_PERCENT/10)*10))"
 
-FUNCS_PERCENT=$((1000*$FUNCS_TESTED/$FUNCS_TOTAL))
-FUNCS_PERCENT="$(($FUNCS_PERCENT/10)).$(($FUNCS_PERCENT-($FUNCS_PERCENT/10)*10))"
+    FUNCS_PERCENT=$((1000*$FUNCS_TESTED/$FUNCS_TOTAL))
+    FUNCS_PERCENT="$(($FUNCS_PERCENT/10)).$(($FUNCS_PERCENT-($FUNCS_PERCENT/10)*10))"
 
-BRANCHES_PERCENT=$((1000*$BRANCHES_TESTED/$BRANCHES_TOTAL))
-BRANCHES_PERCENT="$(($BRANCHES_PERCENT/10)).$(($BRANCHES_PERCENT-($BRANCHES_PERCENT/10)*10))"
+    BRANCHES_PERCENT=$((1000*$BRANCHES_TESTED/$BRANCHES_TOTAL))
+    BRANCHES_PERCENT="$(($BRANCHES_PERCENT/10)).$(($BRANCHES_PERCENT-($BRANCHES_PERCENT/10)*10))"
 
-echo "Lines Tested       : $LINES_TESTED of $LINES_TOTAL $LINES_PERCENT%"
-echo "Functions Tested   : $FUNCS_TESTED of $FUNCS_TOTAL $FUNCS_PERCENT%"
-echo "Branches Tested    : $BRANCHES_TESTED of $BRANCHES_TOTAL $BRANCHES_PERCENT%"
-echo
+    rm unit-test-$TEST_OUTPUT
+    rm sys-test-$TEST_OUTPUT
+    rm compat-test-$TEST_OUTPUT
+    rm cov-$TEST_OUTPUT
 
-rm unit-test-$TEST_OUTPUT
-rm sys-test-$TEST_OUTPUT
-rm compat-test-$TEST_OUTPUT
-rm cov-$TEST_OUTPUT
+    echo "Lines Tested       : $LINES_TESTED of $LINES_TOTAL $LINES_PERCENT%"
+    echo "Functions Tested   : $FUNCS_TESTED of $FUNCS_TOTAL $FUNCS_PERCENT%"
+    echo "Branches Tested    : $BRANCHES_TESTED of $BRANCHES_TOTAL $BRANCHES_PERCENT%"
+    echo
 
-cd ..
+    # Mark the report generation as having succeeded. This must be the
+    # last thing in the report generation.
+    touch "basic-build-test-$$.ok"
+} | tee coverage-summary.txt
 
 make clean
 
@@ -283,6 +314,7 @@
     mv "$CONFIG_BAK" "$CONFIG_H"
 fi
 
-if [ $TOTAL_FAIL -ne 0 ]; then
-    exit 1
-fi
+# The file must exist, otherwise it means something went wrong while generating
+# the coverage report. If something did go wrong, rm will complain so this
+# script will exit with a failure status.
+rm "tests/basic-build-test-$$.ok"
diff --git a/tests/scripts/check-names.sh b/tests/scripts/check-names.sh
index 7c979bc..c6a2008 100755
--- a/tests/scripts/check-names.sh
+++ b/tests/scripts/check-names.sh
@@ -55,11 +55,6 @@
     exit
 fi
 
-if grep --version|head -n1|grep GNU >/dev/null; then :; else
-    echo "This script requires GNU grep.">&2
-    exit 1
-fi
-
 trace=
 if [ $# -ne 0 ] && [ "$1" = "-v" ]; then
   shift
diff --git a/tests/scripts/generate_test_code.py b/tests/scripts/generate_test_code.py
index f452b37..b74ed55 100755
--- a/tests/scripts/generate_test_code.py
+++ b/tests/scripts/generate_test_code.py
@@ -1,4 +1,7 @@
 #!/usr/bin/env python3
+
+# This script should still be compatible with Python 2 in Mbed TLS 2.16.x.
+
 # Test suites code generator.
 #
 # Copyright The Mbed TLS Contributors
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index b9652ef..6fa85f7 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -130,8 +130,8 @@
     echo "Usage: $0 [options]"
     printf "  -h|--help\tPrint this help.\n"
     printf "  -m|--memcheck\tCheck memory leaks and errors.\n"
-    printf "  -f|--filter\tOnly matching tests are executed (BRE)\n"
-    printf "  -e|--exclude\tMatching tests are excluded (BRE)\n"
+    printf "  -f|--filter\tOnly matching tests are executed (substring or BRE)\n"
+    printf "  -e|--exclude\tMatching tests are excluded (substring or 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"
@@ -184,6 +184,14 @@
     done
 }
 
+# Read boolean configuration options from config.h for easy and quick
+# testing. Skip non-boolean options (with something other than spaces
+# and a comment after "#define SYMBOL"). The variable contains a
+# space-separated list of symbols.
+CONFIGS_ENABLED=" $(<"$CONFIG_H" \
+                    sed -n 's!^ *#define  *\([A-Za-z][0-9A-Z_a-z]*\) *\(/*\)*!\1!p' |
+                    tr '\n' ' ')"
+
 # Skip next test; use this macro to skip tests which are legitimate
 # in theory and expected to be re-introduced at some point, but
 # aren't expected to succeed at the moment due to problems outside
@@ -194,16 +202,17 @@
 
 # skip next test if the flag is not enabled in config.h
 requires_config_enabled() {
-    if grep "^#define $1" $CONFIG_H > /dev/null; then :; else
-        SKIP_NEXT="YES"
-    fi
+    case $CONFIGS_ENABLED in
+        *" $1 "*) :;;
+        *) SKIP_NEXT="YES";;
+    esac
 }
 
 # skip next test if the flag is enabled in config.h
 requires_config_disabled() {
-    if grep "^#define $1" $CONFIG_H > /dev/null; then
-        SKIP_NEXT="YES"
-    fi
+    case $CONFIGS_ENABLED in
+        *" $1 "*) SKIP_NEXT="YES";;
+    esac
 }
 
 get_config_value_or_default() {
@@ -239,6 +248,17 @@
     fi
 }
 
+requires_config_value_equals() {
+    VAL=$( get_config_value_or_default "$1" )
+    if [ -z "$VAL" ]; then
+        # Should never happen
+        echo "Mbed TLS configuration $1 is not defined"
+        exit 1
+    elif [ "$VAL" -ne "$2" ]; then
+       SKIP_NEXT="YES"
+    fi
+}
+
 # skip next test if OpenSSL doesn't support FALLBACK_SCSV
 requires_openssl_with_fallback_scsv() {
     if [ -z "${OPENSSL_HAS_FBSCSV:-}" ]; then
@@ -254,6 +274,12 @@
     fi
 }
 
+# skip next test if either IN_CONTENT_LEN or MAX_CONTENT_LEN are below a value
+requires_max_content_len() {
+    requires_config_value_at_least "MBEDTLS_SSL_IN_CONTENT_LEN" $1
+    requires_config_value_at_least "MBEDTLS_SSL_OUT_CONTENT_LEN" $1
+}
+
 # skip next test if GnuTLS isn't available
 requires_gnutls() {
     if [ -z "${GNUTLS_AVAILABLE:-}" ]; then
@@ -332,10 +358,11 @@
 }
 
 # Calculate the input & output maximum content lengths set in the config
-MAX_CONTENT_LEN=$( ../scripts/config.pl get MBEDTLS_SSL_MAX_CONTENT_LEN || echo "16384")
-MAX_IN_LEN=$( ../scripts/config.pl get MBEDTLS_SSL_IN_CONTENT_LEN || echo "$MAX_CONTENT_LEN")
-MAX_OUT_LEN=$( ../scripts/config.pl get MBEDTLS_SSL_OUT_CONTENT_LEN || echo "$MAX_CONTENT_LEN")
+MAX_CONTENT_LEN=$( get_config_value_or_default "MBEDTLS_SSL_MAX_CONTENT_LEN" )
+MAX_IN_LEN=$( get_config_value_or_default "MBEDTLS_SSL_IN_CONTENT_LEN" )
+MAX_OUT_LEN=$( get_config_value_or_default "MBEDTLS_SSL_OUT_CONTENT_LEN" )
 
+# Calculate the maximum content length that fits both
 if [ "$MAX_IN_LEN" -lt "$MAX_CONTENT_LEN" ]; then
     MAX_CONTENT_LEN="$MAX_IN_LEN"
 fi
@@ -422,17 +449,21 @@
 
 # is_polar <cmd_line>
 is_polar() {
-    echo "$1" | grep 'ssl_server2\|ssl_client2' > /dev/null
+    case "$1" in
+        *ssl_client2*) true;;
+        *ssl_server2*) true;;
+        *) false;;
+    esac
 }
 
 # openssl s_server doesn't have -www with DTLS
 check_osrv_dtls() {
-    if echo "$SRV_CMD" | grep 's_server.*-dtls' >/dev/null; then
-        NEEDS_INPUT=1
-        SRV_CMD="$( echo $SRV_CMD | sed s/-www// )"
-    else
-        NEEDS_INPUT=0
-    fi
+    case "$SRV_CMD" in
+        *s_server*-dtls*)
+            NEEDS_INPUT=1
+            SRV_CMD="$( echo $SRV_CMD | sed s/-www// )";;
+        *) NEEDS_INPUT=0;;
+    esac
 }
 
 # provide input to commands that need it
@@ -548,11 +579,10 @@
 
 # check if the given command uses dtls and sets global variable DTLS
 detect_dtls() {
-    if echo "$1" | grep 'dtls=1\|-dtls1\|-u' >/dev/null; then
-        DTLS=1
-    else
-        DTLS=0
-    fi
+    case "$1" in
+        *dtls=1*|-dtls|-u) DTLS=1;;
+        *) DTLS=0;;
+    esac
 }
 
 # Usage: run_test name [-p proxy_cmd] srv_cmd cli_cmd cli_exit [option [...]]
@@ -568,8 +598,7 @@
     NAME="$1"
     shift 1
 
-    if echo "$NAME" | grep "$FILTER" | grep -v "$EXCLUDE" >/dev/null; then :
-    else
+    if is_excluded "$NAME"; then
         SKIP_NEXT="NO"
         return
     fi
@@ -577,10 +606,11 @@
     print_name "$NAME"
 
     # Do we only run numbered tests?
-    if [ "X$RUN_TEST_NUMBER" = "X" ]; then :
-    elif echo ",$RUN_TEST_NUMBER," | grep ",$TESTS," >/dev/null; then :
-    else
-        SKIP_NEXT="YES"
+    if [ -n "$RUN_TEST_NUMBER" ]; then
+        case ",$RUN_TEST_NUMBER," in
+            *",$TESTS,"*) :;;
+            *) SKIP_NEXT="YES";;
+        esac
     fi
 
     # should we skip?
@@ -606,10 +636,10 @@
     shift 3
 
     # Check if test uses files
-    TEST_USES_FILES=$(echo "$SRV_CMD $CLI_CMD" | grep "\.\(key\|crt\|pem\)" )
-    if [ ! -z "$TEST_USES_FILES" ]; then
-       requires_config_enabled MBEDTLS_FS_IO
-    fi
+    case "$SRV_CMD $CLI_CMD" in
+        *data_files/*)
+            requires_config_enabled MBEDTLS_FS_IO;;
+    esac
 
     # should we skip?
     if [ "X$SKIP_NEXT" = "XYES" ]; then
@@ -676,6 +706,7 @@
         # terminate the server (and the proxy)
         kill $SRV_PID
         wait $SRV_PID
+        SRV_RET=$?
 
         if [ -n "$PXY_CMD" ]; then
             kill $PXY_PID >/dev/null 2>&1
@@ -709,9 +740,11 @@
         fi
     fi
 
-    # check server exit code
-    if [ $? != 0 ]; then
-        fail "server fail"
+    # Check server exit code (only for Mbed TLS: GnuTLS and OpenSSL don't
+    # exit with status 0 when interrupted by a signal, and we don't really
+    # care anyway), in case e.g. the server reports a memory leak.
+    if [ $SRV_RET != 0 ] && is_polar "$SRV_CMD"; then
+        fail "Server exited with status $SRV_RET"
         return
     fi
 
@@ -837,6 +870,46 @@
 
 get_options "$@"
 
+# Optimize filters: if $FILTER and $EXCLUDE can be expressed as shell
+# patterns rather than regular expressions, use a case statement instead
+# of calling grep. To keep the optimizer simple, it is incomplete and only
+# detects simple cases: plain substring, everything, nothing.
+#
+# As an exception, the character '.' is treated as an ordinary character
+# if it is the only special character in the string. This is because it's
+# rare to need "any one character", but needing a literal '.' is common
+# (e.g. '-f "DTLS 1.2"').
+need_grep=
+case "$FILTER" in
+    '^$') simple_filter=;;
+    '.*') simple_filter='*';;
+    *[][$+*?\\^{\|}]*) # Regexp special characters (other than .), we need grep
+        need_grep=1;;
+    *) # No regexp or shell-pattern special character
+        simple_filter="*$FILTER*";;
+esac
+case "$EXCLUDE" in
+    '^$') simple_exclude=;;
+    '.*') simple_exclude='*';;
+    *[][$+*?\\^{\|}]*) # Regexp special characters (other than .), we need grep
+        need_grep=1;;
+    *) # No regexp or shell-pattern special character
+        simple_exclude="*$EXCLUDE*";;
+esac
+if [ -n "$need_grep" ]; then
+    is_excluded () {
+        ! echo "$1" | grep "$FILTER" | grep -q -v "$EXCLUDE"
+    }
+else
+    is_excluded () {
+        case "$1" in
+            $simple_exclude) true;;
+            $simple_filter) false;;
+            *) true;;
+        esac
+    }
+fi
+
 # sanity checks, avoid an avalanche of errors
 P_SRV_BIN="${P_SRV%%[  ]*}"
 P_CLI_BIN="${P_CLI%%[  ]*}"
@@ -897,7 +970,7 @@
 P_SRV="$P_SRV server_addr=127.0.0.1 server_port=$SRV_PORT"
 P_CLI="$P_CLI server_addr=127.0.0.1 server_port=+SRV_PORT"
 P_PXY="$P_PXY server_addr=127.0.0.1 server_port=$SRV_PORT listen_addr=127.0.0.1 listen_port=$PXY_PORT ${SEED:+"seed=$SEED"}"
-O_SRV="$O_SRV -accept $SRV_PORT -dhparam data_files/dhparams.pem"
+O_SRV="$O_SRV -accept $SRV_PORT"
 O_CLI="$O_CLI -connect localhost:+SRV_PORT"
 G_SRV="$G_SRV -p $SRV_PORT"
 G_CLI="$G_CLI -p +SRV_PORT"
@@ -1876,15 +1949,6 @@
 
 # Tests for Max Fragment Length extension
 
-if [ "$MAX_CONTENT_LEN" -lt "4096" ]; then
-    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
-    echo "Using non-default maximum content length $MAX_CONTENT_LEN"
-fi
-
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
 run_test    "Max fragment length: enabled, default" \
             "$P_SRV debug_level=3" \
@@ -1941,7 +2005,7 @@
             -s "1 bytes read"
 
 requires_config_disabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
-run_test    "Max fragment length DTLS: disabled, larger message" \
+run_test    "Max fragment length, DTLS: disabled, larger message" \
             "$P_SRV debug_level=3 dtls=1" \
             "$P_CLI debug_level=3 dtls=1 request_size=$(( $MAX_CONTENT_LEN + 1))" \
             1 \
@@ -1949,6 +2013,7 @@
             -S "Maximum fragment length is 16384" \
             -c "fragment larger than.*maximum "
 
+requires_max_content_len 4096
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
 run_test    "Max fragment length: used by client" \
             "$P_SRV debug_level=3" \
@@ -1961,6 +2026,7 @@
             -s "server hello, max_fragment_length extension" \
             -c "found max_fragment_length extension"
 
+requires_max_content_len 4096
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
 run_test    "Max fragment length: used by server" \
             "$P_SRV debug_level=3 max_frag_len=4096" \
@@ -1973,6 +2039,7 @@
             -S "server hello, max_fragment_length extension" \
             -C "found max_fragment_length extension"
 
+requires_max_content_len 4096
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
 requires_gnutls
 run_test    "Max fragment length: gnutls server" \
@@ -1983,6 +2050,7 @@
             -c "client hello, adding max_fragment_length extension" \
             -c "found max_fragment_length extension"
 
+requires_max_content_len 2048
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
 run_test    "Max fragment length: client, message just fits" \
             "$P_SRV debug_level=3" \
@@ -1997,6 +2065,7 @@
             -c "2048 bytes written in 1 fragments" \
             -s "2048 bytes read"
 
+requires_max_content_len 2048
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
 run_test    "Max fragment length: client, larger message" \
             "$P_SRV debug_level=3" \
@@ -2012,6 +2081,7 @@
             -s "2048 bytes read" \
             -s "297 bytes read"
 
+requires_max_content_len 2048
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
 run_test    "Max fragment length: DTLS client, larger message" \
             "$P_SRV debug_level=3 dtls=1" \
@@ -2816,24 +2886,17 @@
             -C "! mbedtls_ssl_handshake returned" \
             -S "X509 - Certificate verification failed"
 
-# The "max_int chain" tests assume that MAX_INTERMEDIATE_CA is set to its
-# default value (8)
+# This script assumes that MBEDTLS_X509_MAX_INTERMEDIATE_CA has its default
+# value, defined here as MAX_IM_CA. Some test cases will be skipped if the
+# library is configured with a different value.
 
 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
-    cat <<EOF
-${CONFIG_H} contains a value for the configuration of
-MBEDTLS_X509_MAX_INTERMEDIATE_CA that is different from the script's
-test value of ${MAX_IM_CA}.
-
-The tests assume this value and if it changes, the tests in this
-script should also be adjusted.
-EOF
-    exit 1
-fi
-
+# The tests for the max_int tests can pass with any number higher than MAX_IM_CA
+# because only a chain of MAX_IM_CA length is tested. Equally, the max_int+1
+# tests can pass with any number less than MAX_IM_CA. However, stricter preconditions
+# are in place so that the semantics are consistent with the test description.
+requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA
 requires_full_size_output_buffer
 run_test    "Authentication: server max_int chain, client default" \
             "$P_SRV crt_file=data_files/dir-maxpath/c09.pem \
@@ -2842,6 +2905,7 @@
             0 \
             -C "X509 - A fatal error occurred"
 
+requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA
 requires_full_size_output_buffer
 run_test    "Authentication: server max_int+1 chain, client default" \
             "$P_SRV crt_file=data_files/dir-maxpath/c10.pem \
@@ -2850,6 +2914,7 @@
             1 \
             -c "X509 - A fatal error occurred"
 
+requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA
 requires_full_size_output_buffer
 run_test    "Authentication: server max_int+1 chain, client optional" \
             "$P_SRV crt_file=data_files/dir-maxpath/c10.pem \
@@ -2859,6 +2924,7 @@
             1 \
             -c "X509 - A fatal error occurred"
 
+requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA
 requires_full_size_output_buffer
 run_test    "Authentication: server max_int+1 chain, client none" \
             "$P_SRV crt_file=data_files/dir-maxpath/c10.pem \
@@ -2868,6 +2934,7 @@
             0 \
             -C "X509 - A fatal error occurred"
 
+requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA
 requires_full_size_output_buffer
 run_test    "Authentication: client max_int+1 chain, server default" \
             "$P_SRV ca_file=data_files/dir-maxpath/00.crt" \
@@ -2876,6 +2943,7 @@
             0 \
             -S "X509 - A fatal error occurred"
 
+requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA
 requires_full_size_output_buffer
 run_test    "Authentication: client max_int+1 chain, server optional" \
             "$P_SRV ca_file=data_files/dir-maxpath/00.crt auth_mode=optional" \
@@ -2884,6 +2952,7 @@
             1 \
             -s "X509 - A fatal error occurred"
 
+requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA
 requires_full_size_output_buffer
 run_test    "Authentication: client max_int+1 chain, server required" \
             "$P_SRV ca_file=data_files/dir-maxpath/00.crt auth_mode=required" \
@@ -2892,6 +2961,7 @@
             1 \
             -s "X509 - A fatal error occurred"
 
+requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA
 requires_full_size_output_buffer
 run_test    "Authentication: client max_int chain, server required" \
             "$P_SRV ca_file=data_files/dir-maxpath/00.crt auth_mode=required" \
@@ -3905,6 +3975,20 @@
             0 \
             -C "DHM prime too short:"
 
+run_test    "DHM size: server 999, client 999, OK" \
+            "$P_SRV dhm_file=data_files/dh.999.pem" \
+            "$P_CLI force_ciphersuite=TLS-DHE-RSA-WITH-AES-128-CBC-SHA \
+                    debug_level=1 dhmlen=999" \
+            0 \
+            -C "DHM prime too short:"
+
+run_test    "DHM size: server 1000, client 1000, OK" \
+            "$P_SRV dhm_file=data_files/dh.1000.pem" \
+            "$P_CLI force_ciphersuite=TLS-DHE-RSA-WITH-AES-128-CBC-SHA \
+                    debug_level=1 dhmlen=1000" \
+            0 \
+            -C "DHM prime too short:"
+
 run_test    "DHM size: server 1000, client default, rejected" \
             "$P_SRV dhm_file=data_files/dh.1000.pem" \
             "$P_CLI force_ciphersuite=TLS-DHE-RSA-WITH-AES-128-CBC-SHA \
@@ -3912,6 +3996,27 @@
             1 \
             -c "DHM prime too short:"
 
+run_test    "DHM size: server 1000, client 1001, rejected" \
+            "$P_SRV dhm_file=data_files/dh.1000.pem" \
+            "$P_CLI force_ciphersuite=TLS-DHE-RSA-WITH-AES-128-CBC-SHA \
+                    debug_level=1 dhmlen=1001" \
+            1 \
+            -c "DHM prime too short:"
+
+run_test    "DHM size: server 999, client 1000, rejected" \
+            "$P_SRV dhm_file=data_files/dh.999.pem" \
+            "$P_CLI force_ciphersuite=TLS-DHE-RSA-WITH-AES-128-CBC-SHA \
+                    debug_level=1 dhmlen=1000" \
+            1 \
+            -c "DHM prime too short:"
+
+run_test    "DHM size: server 998, client 999, rejected" \
+            "$P_SRV dhm_file=data_files/dh.998.pem" \
+            "$P_CLI force_ciphersuite=TLS-DHE-RSA-WITH-AES-128-CBC-SHA \
+                    debug_level=1 dhmlen=999" \
+            1 \
+            -c "DHM prime too short:"
+
 run_test    "DHM size: server default, client 2049, rejected" \
             "$P_SRV" \
             "$P_CLI force_ciphersuite=TLS-DHE-RSA-WITH-AES-128-CBC-SHA \
@@ -4033,7 +4138,7 @@
             -S "SSL - Verification of the message MAC failed"
 
 server_needs_more_time 1
-requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
 run_test    "ECJPAKE: password mismatch, TLS" \
             "$P_SRV debug_level=3 ecjpake_pw=bla" \
             "$P_CLI debug_level=3 ecjpake_pw=bad \
@@ -4042,7 +4147,7 @@
             -C "re-using cached ecjpake parameters" \
             -s "SSL - Verification of the message MAC failed"
 
-requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
 run_test    "ECJPAKE: working, DTLS" \
             "$P_SRV debug_level=3 dtls=1 ecjpake_pw=bla" \
             "$P_CLI debug_level=3 dtls=1 ecjpake_pw=bla \
@@ -4051,7 +4156,7 @@
             -c "re-using cached ecjpake parameters" \
             -S "SSL - Verification of the message MAC failed"
 
-requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
 run_test    "ECJPAKE: working, DTLS, no cookie" \
             "$P_SRV debug_level=3 dtls=1 ecjpake_pw=bla cookies=0" \
             "$P_CLI debug_level=3 dtls=1 ecjpake_pw=bla \
@@ -4061,7 +4166,7 @@
             -S "SSL - Verification of the message MAC failed"
 
 server_needs_more_time 1
-requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
 run_test    "ECJPAKE: password mismatch, DTLS" \
             "$P_SRV debug_level=3 dtls=1 ecjpake_pw=bla" \
             "$P_CLI debug_level=3 dtls=1 ecjpake_pw=bad \
@@ -4071,7 +4176,7 @@
             -s "SSL - Verification of the message MAC failed"
 
 # for tests with configs/config-thread.h
-requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
 run_test    "ECJPAKE: working, DTLS, nolog" \
             "$P_SRV dtls=1 ecjpake_pw=bla" \
             "$P_CLI dtls=1 ecjpake_pw=bla \
@@ -4718,7 +4823,7 @@
             -c "Read from server: 1 bytes read"
 
 # A test for extensions in SSLv3
-
+requires_max_content_len 4096
 requires_config_enabled MBEDTLS_SSL_PROTO_SSL3
 run_test    "SSLv3 with extensions, server side" \
             "$P_SRV min_version=ssl3 debug_level=3" \
@@ -4968,6 +5073,7 @@
             -s "Read from client: $MAX_CONTENT_LEN bytes read"
 
 # Test for large server packets
+# The tests below fail when the server's OUT_CONTENT_LEN is less than 16384.
 requires_config_enabled MBEDTLS_SSL_PROTO_SSL3
 run_test    "Large server packet SSLv3 StreamCipher" \
             "$P_SRV response_size=16384 min_version=ssl3 arc4=1 force_ciphersuite=TLS-RSA-WITH-RC4-128-SHA" \
@@ -5989,6 +6095,7 @@
 requires_config_enabled MBEDTLS_RSA_C
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+requires_max_content_len 4096
 run_test    "DTLS fragmenting: none (for reference)" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
@@ -6009,6 +6116,7 @@
 requires_config_enabled MBEDTLS_RSA_C
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: server only (max_frag_len)" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
@@ -6033,6 +6141,7 @@
 requires_config_enabled MBEDTLS_RSA_C
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+requires_max_content_len 4096
 run_test    "DTLS fragmenting: server only (more) (max_frag_len)" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
@@ -6053,6 +6162,7 @@
 requires_config_enabled MBEDTLS_RSA_C
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: client-initiated, server only (max_frag_len)" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=none \
              crt_file=data_files/server7_int-ca.crt \
@@ -6080,6 +6190,7 @@
 requires_config_enabled MBEDTLS_RSA_C
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: client-initiated, server only (max_frag_len), proxy MTU" \
             -p "$P_PXY mtu=1110" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=none \
@@ -6101,6 +6212,7 @@
 requires_config_enabled MBEDTLS_RSA_C
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: client-initiated, both (max_frag_len)" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
@@ -6128,6 +6240,7 @@
 requires_config_enabled MBEDTLS_RSA_C
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: client-initiated, both (max_frag_len), proxy MTU" \
             -p "$P_PXY mtu=1110" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -6148,6 +6261,7 @@
 requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
 requires_config_enabled MBEDTLS_RSA_C
 requires_config_enabled MBEDTLS_ECDSA_C
+requires_max_content_len 4096
 run_test    "DTLS fragmenting: none (for reference) (MTU)" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
@@ -6167,6 +6281,7 @@
 requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
 requires_config_enabled MBEDTLS_RSA_C
 requires_config_enabled MBEDTLS_ECDSA_C
+requires_max_content_len 4096
 run_test    "DTLS fragmenting: client (MTU)" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
@@ -6186,6 +6301,7 @@
 requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
 requires_config_enabled MBEDTLS_RSA_C
 requires_config_enabled MBEDTLS_ECDSA_C
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: server (MTU)" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
              crt_file=data_files/server7_int-ca.crt \
@@ -6205,6 +6321,7 @@
 requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
 requires_config_enabled MBEDTLS_RSA_C
 requires_config_enabled MBEDTLS_ECDSA_C
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: both (MTU=1024)" \
             -p "$P_PXY mtu=1024" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -6227,9 +6344,10 @@
 requires_config_enabled MBEDTLS_RSA_C
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SHA256_C
-requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
 requires_config_enabled MBEDTLS_AES_C
 requires_config_enabled MBEDTLS_GCM_C
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: both (MTU=512)" \
             -p "$P_PXY mtu=512" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -6258,9 +6376,10 @@
 requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
 requires_config_enabled MBEDTLS_RSA_C
 requires_config_enabled MBEDTLS_ECDSA_C
-requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
 requires_config_enabled MBEDTLS_AES_C
 requires_config_enabled MBEDTLS_GCM_C
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: proxy MTU: auto-reduction" \
             -p "$P_PXY mtu=508" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -6282,9 +6401,10 @@
 requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
 requires_config_enabled MBEDTLS_RSA_C
 requires_config_enabled MBEDTLS_ECDSA_C
-requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
 requires_config_enabled MBEDTLS_AES_C
 requires_config_enabled MBEDTLS_GCM_C
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: proxy MTU: auto-reduction" \
             -p "$P_PXY mtu=508" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -6308,6 +6428,7 @@
 requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
 requires_config_enabled MBEDTLS_RSA_C
 requires_config_enabled MBEDTLS_ECDSA_C
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: proxy MTU, simple handshake (MTU=1024)" \
             -p "$P_PXY mtu=1024" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -6334,9 +6455,10 @@
 requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
 requires_config_enabled MBEDTLS_RSA_C
 requires_config_enabled MBEDTLS_ECDSA_C
-requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
 requires_config_enabled MBEDTLS_AES_C
 requires_config_enabled MBEDTLS_GCM_C
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: proxy MTU, simple handshake (MTU=512)" \
             -p "$P_PXY mtu=512" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -6360,6 +6482,7 @@
 requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
 requires_config_enabled MBEDTLS_RSA_C
 requires_config_enabled MBEDTLS_ECDSA_C
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: proxy MTU, simple handshake, nbio (MTU=1024)" \
             -p "$P_PXY mtu=1024" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -6383,9 +6506,10 @@
 requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
 requires_config_enabled MBEDTLS_RSA_C
 requires_config_enabled MBEDTLS_ECDSA_C
-requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
 requires_config_enabled MBEDTLS_AES_C
 requires_config_enabled MBEDTLS_GCM_C
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: proxy MTU, simple handshake, nbio (MTU=512)" \
             -p "$P_PXY mtu=512" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -6419,9 +6543,10 @@
 requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
 requires_config_enabled MBEDTLS_RSA_C
 requires_config_enabled MBEDTLS_ECDSA_C
-requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
 requires_config_enabled MBEDTLS_AES_C
 requires_config_enabled MBEDTLS_GCM_C
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: proxy MTU, resumed handshake" \
             -p "$P_PXY mtu=1450" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -6448,9 +6573,10 @@
 requires_config_enabled MBEDTLS_RSA_C
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SHA256_C
-requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
 requires_config_enabled MBEDTLS_CHACHAPOLY_C
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: proxy MTU, ChachaPoly renego" \
             -p "$P_PXY mtu=512" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -6479,10 +6605,11 @@
 requires_config_enabled MBEDTLS_RSA_C
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SHA256_C
-requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
 requires_config_enabled MBEDTLS_AES_C
 requires_config_enabled MBEDTLS_GCM_C
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: proxy MTU, AES-GCM renego" \
             -p "$P_PXY mtu=512" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -6511,10 +6638,11 @@
 requires_config_enabled MBEDTLS_RSA_C
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SHA256_C
-requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
 requires_config_enabled MBEDTLS_AES_C
 requires_config_enabled MBEDTLS_CCM_C
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: proxy MTU, AES-CCM renego" \
             -p "$P_PXY mtu=1024" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -6543,11 +6671,12 @@
 requires_config_enabled MBEDTLS_RSA_C
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SHA256_C
-requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
 requires_config_enabled MBEDTLS_AES_C
 requires_config_enabled MBEDTLS_CIPHER_MODE_CBC
 requires_config_enabled MBEDTLS_SSL_ENCRYPT_THEN_MAC
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: proxy MTU, AES-CBC EtM renego" \
             -p "$P_PXY mtu=1024" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -6576,10 +6705,11 @@
 requires_config_enabled MBEDTLS_RSA_C
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SHA256_C
-requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
 requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
 requires_config_enabled MBEDTLS_AES_C
 requires_config_enabled MBEDTLS_CIPHER_MODE_CBC
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: proxy MTU, AES-CBC non-EtM renego" \
             -p "$P_PXY mtu=1024" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -6605,10 +6735,11 @@
 requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
 requires_config_enabled MBEDTLS_RSA_C
 requires_config_enabled MBEDTLS_ECDSA_C
-requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
 requires_config_enabled MBEDTLS_AES_C
 requires_config_enabled MBEDTLS_GCM_C
 client_needs_more_time 2
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: proxy MTU + 3d" \
             -p "$P_PXY mtu=512 drop=8 delay=8 duplicate=8" \
             "$P_SRV dgram_packing=0 dtls=1 debug_level=2 auth_mode=required \
@@ -6629,10 +6760,11 @@
 requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
 requires_config_enabled MBEDTLS_RSA_C
 requires_config_enabled MBEDTLS_ECDSA_C
-requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA
+requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
 requires_config_enabled MBEDTLS_AES_C
 requires_config_enabled MBEDTLS_GCM_C
 client_needs_more_time 2
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: proxy MTU + 3d, nbio" \
             -p "$P_PXY mtu=512 drop=8 delay=8 duplicate=8" \
             "$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -6658,6 +6790,7 @@
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_gnutls
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: gnutls server, DTLS 1.2" \
             "$G_SRV -u" \
             "$P_CLI dtls=1 debug_level=2 \
@@ -6673,6 +6806,7 @@
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_1
 requires_gnutls
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: gnutls server, DTLS 1.0" \
             "$G_SRV -u" \
             "$P_CLI dtls=1 debug_level=2 \
@@ -6696,6 +6830,7 @@
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 requires_gnutls
 requires_not_i686
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: gnutls client, DTLS 1.2" \
             "$P_SRV dtls=1 debug_level=2 \
              crt_file=data_files/server7_int-ca.crt \
@@ -6712,6 +6847,7 @@
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_1
 requires_gnutls
 requires_not_i686
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: gnutls client, DTLS 1.0" \
             "$P_SRV dtls=1 debug_level=2 \
              crt_file=data_files/server7_int-ca.crt \
@@ -6725,6 +6861,7 @@
 requires_config_enabled MBEDTLS_RSA_C
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: openssl server, DTLS 1.2" \
             "$O_SRV -dtls1_2 -verify 10" \
             "$P_CLI dtls=1 debug_level=2 \
@@ -6739,6 +6876,7 @@
 requires_config_enabled MBEDTLS_RSA_C
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_1
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: openssl server, DTLS 1.0" \
             "$O_SRV -dtls1 -verify 10" \
             "$P_CLI dtls=1 debug_level=2 \
@@ -6753,6 +6891,7 @@
 requires_config_enabled MBEDTLS_RSA_C
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: openssl client, DTLS 1.2" \
             "$P_SRV dtls=1 debug_level=2 \
              crt_file=data_files/server7_int-ca.crt \
@@ -6766,6 +6905,7 @@
 requires_config_enabled MBEDTLS_RSA_C
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_1
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: openssl client, DTLS 1.0" \
             "$P_SRV dtls=1 debug_level=2 \
              crt_file=data_files/server7_int-ca.crt \
@@ -6785,6 +6925,7 @@
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 client_needs_more_time 4
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: 3d, gnutls server, DTLS 1.2" \
             -p "$P_PXY drop=8 delay=8 duplicate=8" \
             "$G_NEXT_SRV -u" \
@@ -6802,6 +6943,7 @@
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_1
 client_needs_more_time 4
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: 3d, gnutls server, DTLS 1.0" \
             -p "$P_PXY drop=8 delay=8 duplicate=8" \
             "$G_NEXT_SRV -u" \
@@ -6819,6 +6961,7 @@
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 client_needs_more_time 4
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: 3d, gnutls client, DTLS 1.2" \
             -p "$P_PXY drop=8 delay=8 duplicate=8" \
             "$P_SRV dtls=1 debug_level=2 \
@@ -6835,6 +6978,7 @@
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_1
 client_needs_more_time 4
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: 3d, gnutls client, DTLS 1.0" \
             -p "$P_PXY drop=8 delay=8 duplicate=8" \
             "$P_SRV dtls=1 debug_level=2 \
@@ -6856,6 +7000,7 @@
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 client_needs_more_time 4
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: 3d, openssl server, DTLS 1.2" \
             -p "$P_PXY drop=8 delay=8 duplicate=8" \
             "$O_SRV -dtls1_2 -verify 10" \
@@ -6873,6 +7018,7 @@
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_1
 client_needs_more_time 4
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: 3d, openssl server, DTLS 1.0" \
             -p "$P_PXY drop=8 delay=8 duplicate=8" \
             "$O_SRV -dtls1 -verify 10" \
@@ -6890,6 +7036,7 @@
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
 client_needs_more_time 4
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: 3d, openssl client, DTLS 1.2" \
             -p "$P_PXY drop=8 delay=8 duplicate=8" \
             "$P_SRV dtls=1 debug_level=2 \
@@ -6908,6 +7055,7 @@
 requires_config_enabled MBEDTLS_ECDSA_C
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_1
 client_needs_more_time 4
+requires_max_content_len 2048
 run_test    "DTLS fragmenting: 3d, openssl client, DTLS 1.0" \
             -p "$P_PXY drop=8 delay=8 duplicate=8" \
             "$P_SRV dgram_packing=0 dtls=1 debug_level=2 \
diff --git a/tests/suites/helpers.function b/tests/suites/helpers.function
index 9403d99..5a8e211 100644
--- a/tests/suites/helpers.function
+++ b/tests/suites/helpers.function
@@ -46,6 +46,16 @@
 #include <strings.h>
 #endif
 
+#if defined(MBEDTLS_BIGNUM_C)
+#include "mbedtls/bignum.h"
+#endif
+
+#if defined(MBEDTLS_THREADING_C) && defined(MBEDTLS_THREADING_PTHREAD) && \
+    defined(MBEDTLS_TEST_HOOKS)
+#include "mbedtls/threading.h"
+#define MBEDTLS_TEST_MUTEX_USAGE
+#endif
+
 /*
  * Define the two macros
  *
@@ -154,6 +164,66 @@
        }                                                    \
     } while( 0 )
 
+/** Evaluate two expressions and fail the test case if they have different
+ * values.
+ *
+ * \param expr1     An expression to evaluate.
+ * \param expr2     The expected value of \p expr1. This can be any
+ *                  expression, but it is typically a constant.
+ */
+#define TEST_EQUAL( expr1, expr2 )              \
+    TEST_ASSERT( ( expr1 ) == ( expr2 ) )
+
+/** Allocate memory dynamically and fail the test case if this fails.
+ * The allocated memory will be filled with zeros.
+ *
+ * You must set \p pointer to \c NULL before calling this macro and
+ * put `mbedtls_free( pointer )` in the test's cleanup code.
+ *
+ * If \p length is zero, the resulting \p pointer will be \c NULL.
+ * This is usually what we want in tests since API functions are
+ * supposed to accept null pointers when a buffer size is zero.
+ *
+ * This macro expands to an instruction, not an expression.
+ * It may jump to the \c exit label.
+ *
+ * \param pointer   An lvalue where the address of the allocated buffer
+ *                  will be stored.
+ *                  This expression may be evaluated multiple times.
+ * \param length    Number of elements to allocate.
+ *                  This expression may be evaluated multiple times.
+ *
+ */
+#define ASSERT_ALLOC( pointer, length )                           \
+    do                                                            \
+    {                                                             \
+        TEST_ASSERT( ( pointer ) == NULL );                       \
+        if( ( length ) != 0 )                                     \
+        {                                                         \
+            ( pointer ) = mbedtls_calloc( sizeof( *( pointer ) ), \
+                                          ( length ) );           \
+            TEST_ASSERT( ( pointer ) != NULL );                   \
+        }                                                         \
+    }                                                             \
+    while( 0 )
+
+/** Allocate memory dynamically. If the allocation fails, skip the test case.
+ *
+ * This macro behaves like #ASSERT_ALLOC, except that if the allocation
+ * fails, it marks the test as skipped rather than failed.
+ */
+#define ASSERT_ALLOC_WEAK( pointer, length )                      \
+    do                                                            \
+    {                                                             \
+        TEST_ASSERT( ( pointer ) == NULL );                       \
+        if( ( length ) != 0 )                                     \
+        {                                                         \
+            ( pointer ) = mbedtls_calloc( sizeof( *( pointer ) ), \
+                                          ( length ) );           \
+            TEST_ASSUME( ( pointer ) != NULL );                   \
+        }                                                         \
+    }                                                             \
+    while( 0 )
 /** Compare two buffers and fail the test case if they differ.
  *
  * This macro expands to an instruction, not an expression.
@@ -371,6 +441,9 @@
     const char *test;
     const char *filename;
     int line_no;
+#if defined(MBEDTLS_TEST_MUTEX_USAGE)
+    const char *mutex_usage_error;
+#endif
 }
 test_info;
 
@@ -777,3 +850,217 @@
     }
     return ret;
 }
+
+#if defined(MBEDTLS_BIGNUM_C)
+int mbedtls_test_read_mpi( mbedtls_mpi *X, int radix, const char *s )
+{
+    /* mbedtls_mpi_read_string() currently retains leading zeros.
+     * It always allocates at least one limb for the value 0. */
+    if( s[0] == 0 )
+    {
+        mbedtls_mpi_free( X );
+        return( 0 );
+    }
+    else
+        return( mbedtls_mpi_read_string( X, radix, s ) );
+}
+#endif /* MBEDTLS_BIGNUM_C */
+
+#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 1178135..781bb77 100644
--- a/tests/suites/host_test.function
+++ b/tests/suites/host_test.function
@@ -33,7 +33,7 @@
  *
  * \return      0 if success else 1
  */
-int verify_int( char *str, int *value )
+int verify_int( char *str, int32_t *value )
 {
     size_t i;
     int minus = 0;
@@ -238,7 +238,7 @@
  *
  * \return      0 for success else 1
  */
-static int convert_params( size_t cnt , char ** params , int * int_params_store )
+static int convert_params( size_t cnt , char ** params , int32_t * int_params_store )
 {
     char ** cur = params;
     char ** out = params;
@@ -400,7 +400,7 @@
     char buf[5000];
     char *params[50];
     /* Store for proccessed integer params. */
-    int int_params[50];
+    int32_t int_params[50];
     void *pointer;
 #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
     int stdout_fd = -1;
@@ -412,6 +412,10 @@
     mbedtls_memory_buffer_alloc_init( alloc_buf, sizeof( alloc_buf ) );
 #endif
 
+#if defined(MBEDTLS_TEST_MUTEX_USAGE)
+    mbedtls_test_mutex_usage_init( );
+#endif
+
     /*
      * The C standard doesn't guarantee that all-bits-0 is the representation
      * of a NULL pointer. We do however use that in our code for initializing
diff --git a/tests/suites/main_test.function b/tests/suites/main_test.function
index 9f36690..2aecf81 100644
--- a/tests/suites/main_test.function
+++ b/tests/suites/main_test.function
@@ -176,6 +176,10 @@
 #else
     fp( params );
 #endif
+
+#if defined(MBEDTLS_TEST_MUTEX_USAGE)
+    mbedtls_test_mutex_usage_check( );
+#endif /* MBEDTLS_TEST_MUTEX_USAGE */
 }
 
 /**
diff --git a/tests/suites/test_suite_aes.function b/tests/suites/test_suite_aes.function
index 23bf83d..1b7e5db 100644
--- a/tests/suites/test_suite_aes.function
+++ b/tests/suites/test_suite_aes.function
@@ -208,6 +208,8 @@
     /* Valid pointers are passed for builds with MBEDTLS_CHECK_PARAMS, as
      * otherwise we wouldn't get to the size check we're interested in. */
     TEST_ASSERT( mbedtls_aes_crypt_xts( &ctx, MBEDTLS_AES_ENCRYPT, length, data_unit, src, output ) == retval );
+exit:
+    mbedtls_aes_xts_free( &ctx );
 }
 /* END_CASE */
 
diff --git a/tests/suites/test_suite_base64.data b/tests/suites/test_suite_base64.data
index da99ffa..3a892f4 100644
--- a/tests/suites/test_suite_base64.data
+++ b/tests/suites/test_suite_base64.data
@@ -151,6 +151,20 @@
 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 #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 3a8bf43..0185f3b 100644
--- a/tests/suites/test_suite_base64.function
+++ b/tests/suites/test_suite_base64.function
@@ -13,13 +13,22 @@
 {
     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 @@
 
     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_ccm.function b/tests/suites/test_suite_ccm.function
index 1bba531..1b3a25f 100644
--- a/tests/suites/test_suite_ccm.function
+++ b/tests/suites/test_suite_ccm.function
@@ -200,12 +200,11 @@
     unsigned char iv[13];
     unsigned char result[50];
     mbedtls_ccm_context ctx;
-    size_t i, iv_len, tag_len;
+    size_t iv_len, tag_len;
     int ret;
 
     mbedtls_ccm_init( &ctx );
 
-    memset( iv, 0x00, sizeof( iv ) );
     memset( result, 0x00, sizeof( result ) );
 
     if( sec_level % 4 == 0)
@@ -213,12 +212,10 @@
     else
         tag_len = 1 << ( sec_level % 4 + 1);
 
-    for( i = 0; i < source_address->len; i++ )
-        iv[i] = source_address->x[i];
-
-    for( i = 0; i < frame_counter->len; i++ )
-        iv[source_address->len + i] = frame_counter->x[i];
-
+    TEST_ASSERT( source_address->len == 8 );
+    TEST_ASSERT( frame_counter->len == 4 );
+    memcpy( iv, source_address->x, source_address->len );
+    memcpy( iv + source_address->len, frame_counter->x, frame_counter->len );
     iv[source_address->len + frame_counter->len] = sec_level;
     iv_len = sizeof( iv );
 
@@ -253,7 +250,7 @@
     unsigned char iv[13];
     unsigned char result[50];
     mbedtls_ccm_context ctx;
-    size_t i, iv_len, tag_len;
+    size_t iv_len, tag_len;
     int ret;
 
     mbedtls_ccm_init( &ctx );
@@ -266,12 +263,10 @@
     else
         tag_len = 1 << ( sec_level % 4 + 1);
 
-    for( i = 0; i < source_address->len; i++ )
-        iv[i] = source_address->x[i];
-
-    for( i = 0; i < frame_counter->len; i++ )
-        iv[source_address->len + i] = frame_counter->x[i];
-
+    TEST_ASSERT( source_address->len == 8 );
+    TEST_ASSERT( frame_counter->len == 4 );
+    memcpy( iv, source_address->x, source_address->len );
+    memcpy( iv + source_address->len, frame_counter->x, frame_counter->len );
     iv[source_address->len + frame_counter->len] = sec_level;
     iv_len = sizeof( iv );
 
diff --git a/tests/suites/test_suite_debug.data b/tests/suites/test_suite_debug.data
index eb99b79..6d57442 100644
--- a/tests/suites/test_suite_debug.data
+++ b/tests/suites/test_suite_debug.data
@@ -37,6 +37,27 @@
 Debug print buffer #5
 mbedtls_debug_print_buf:"MyFile":999:"Test return value":"000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F30":"MyFile(0999)\: dumping 'Test return value' (49 bytes)\nMyFile(0999)\: 0000\:  00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f  ................\nMyFile(0999)\: 0010\:  10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f  ................\nMyFile(0999)\: 0020\:  20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f   !"#$%&'()*+,-./\nMyFile(0999)\: 0030\:  30                                               0\n"
 
+Debug print mbedtls_mpi: 0 (empty representation)
+mbedtls_debug_print_mpi:16:"":"MyFile":999:"VALUE":"MyFile(0999)\: value of 'VALUE' (0 bits) is\:\nMyFile(0999)\:  00\n"
+
+Debug print mbedtls_mpi: 0 (non-empty representation)
+mbedtls_debug_print_mpi:16:"00000000000000":"MyFile":999:"VALUE":"MyFile(0999)\: value of 'VALUE' (0 bits) is\:\nMyFile(0999)\:  00\n"
+
+Debug print mbedtls_mpi #2: 3 bits
+mbedtls_debug_print_mpi:16:"00000000000007":"MyFile":999:"VALUE":"MyFile(0999)\: value of 'VALUE' (3 bits) is\:\nMyFile(0999)\:  07\n"
+
+Debug print mbedtls_mpi: 49 bits
+mbedtls_debug_print_mpi:16:"01020304050607":"MyFile":999:"VALUE":"MyFile(0999)\: value of 'VALUE' (49 bits) is\:\nMyFile(0999)\:  01 02 03 04 05 06 07\n"
+
+Debug print mbedtls_mpi: 759 bits
+mbedtls_debug_print_mpi:16:"0000000000000000000000000000000000000000000000000000000041379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":"MyFile":999:"VALUE":"MyFile(0999)\: value of 'VALUE' (759 bits) is\:\nMyFile(0999)\:  41 37 9d 00 fe d1 49 1f e1 5d f2 84 df de 4a 14\nMyFile(0999)\:  2f 68 aa 8d 41 20 23 19 5c ee 66 88 3e 62 90 ff\nMyFile(0999)\:  e7 03 f4 ea 59 63 bf 21 27 13 ce e4 6b 10 7c 09\nMyFile(0999)\:  18 2b 5e dc d9 55 ad ac 41 8b f4 91 8e 28 89 af\nMyFile(0999)\:  48 e1 09 9d 51 38 30 ce c8 5c 26 ac 1e 15 8b 52\nMyFile(0999)\:  62 0e 33 ba 86 92 f8 93 ef bb 2f 95 8b 44 24\n"
+
+Debug print mbedtls_mpi: 764 bits #1
+mbedtls_debug_print_mpi:16:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":"MyFile":999:"VALUE":"MyFile(0999)\: value of 'VALUE' (764 bits) is\:\nMyFile(0999)\:  09 41 37 9d 00 fe d1 49 1f e1 5d f2 84 df de 4a\nMyFile(0999)\:  14 2f 68 aa 8d 41 20 23 19 5c ee 66 88 3e 62 90\nMyFile(0999)\:  ff e7 03 f4 ea 59 63 bf 21 27 13 ce e4 6b 10 7c\nMyFile(0999)\:  09 18 2b 5e dc d9 55 ad ac 41 8b f4 91 8e 28 89\nMyFile(0999)\:  af 48 e1 09 9d 51 38 30 ce c8 5c 26 ac 1e 15 8b\nMyFile(0999)\:  52 62 0e 33 ba 86 92 f8 93 ef bb 2f 95 8b 44 24\n"
+
+Debug print mbedtls_mpi: 764 bits #2
+mbedtls_debug_print_mpi:16:"0000000000000000000000000000000000000000000000000000000941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":"MyFile":999:"VALUE":"MyFile(0999)\: value of 'VALUE' (764 bits) is\:\nMyFile(0999)\:  09 41 37 9d 00 fe d1 49 1f e1 5d f2 84 df de 4a\nMyFile(0999)\:  14 2f 68 aa 8d 41 20 23 19 5c ee 66 88 3e 62 90\nMyFile(0999)\:  ff e7 03 f4 ea 59 63 bf 21 27 13 ce e4 6b 10 7c\nMyFile(0999)\:  09 18 2b 5e dc d9 55 ad ac 41 8b f4 91 8e 28 89\nMyFile(0999)\:  af 48 e1 09 9d 51 38 30 ce c8 5c 26 ac 1e 15 8b\nMyFile(0999)\:  52 62 0e 33 ba 86 92 f8 93 ef bb 2f 95 8b 44 24\n"
+
 Debug print certificate #1 (RSA)
 depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_BASE64_C:MBEDTLS_RSA_C:MBEDTLS_SHA1_C
 mbedtls_debug_print_crt:"data_files/server1.crt":"MyFile":999:"PREFIX_":"MyFile(0999)\: PREFIX_ #1\:\nMyFile(0999)\: cert. version     \: 3\nMyFile(0999)\: serial number     \: 01\nMyFile(0999)\: issuer name       \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nMyFile(0999)\: subject name      \: C=NL, O=PolarSSL, CN=PolarSSL Server 1\nMyFile(0999)\: issued  on        \: 2019-02-10 14\:44\:06\nMyFile(0999)\: expires on        \: 2029-02-10 14\:44\:06\nMyFile(0999)\: signed using      \: RSA with SHA1\nMyFile(0999)\: RSA key size      \: 2048 bits\nMyFile(0999)\: basic constraints \: CA=false\nMyFile(0999)\: value of 'crt->rsa.N' (2048 bits) is\:\nMyFile(0999)\:  a9 02 1f 3d 40 6a d5 55 53 8b fd 36 ee 82 65 2e\nMyFile(0999)\:  15 61 5e 89 bf b8 e8 45 90 db ee 88 16 52 d3 f1\nMyFile(0999)\:  43 50 47 96 12 59 64 87 6b fd 2b e0 46 f9 73 be\nMyFile(0999)\:  dd cf 92 e1 91 5b ed 66 a0 6f 89 29 79 45 80 d0\nMyFile(0999)\:  83 6a d5 41 43 77 5f 39 7c 09 04 47 82 b0 57 39\nMyFile(0999)\:  70 ed a3 ec 15 19 1e a8 33 08 47 c1 05 42 a9 fd\nMyFile(0999)\:  4c c3 b4 df dd 06 1f 4d 10 51 40 67 73 13 0f 40\nMyFile(0999)\:  f8 6d 81 25 5f 0a b1 53 c6 30 7e 15 39 ac f9 5a\nMyFile(0999)\:  ee 7f 92 9e a6 05 5b e7 13 97 85 b5 23 92 d9 d4\nMyFile(0999)\:  24 06 d5 09 25 89 75 07 dd a6 1a 8f 3f 09 19 be\nMyFile(0999)\:  ad 65 2c 64 eb 95 9b dc fe 41 5e 17 a6 da 6c 5b\nMyFile(0999)\:  69 cc 02 ba 14 2c 16 24 9c 4a dc cd d0 f7 52 67\nMyFile(0999)\:  73 f1 2d a0 23 fd 7e f4 31 ca 2d 70 ca 89 0b 04\nMyFile(0999)\:  db 2e a6 4f 70 6e 9e ce bd 58 89 e2 53 59 9e 6e\nMyFile(0999)\:  5a 92 65 e2 88 3f 0c 94 19 a3 dd e5 e8 9d 95 13\nMyFile(0999)\:  ed 29 db ab 70 12 dc 5a ca 6b 17 ab 52 82 54 b1\nMyFile(0999)\: value of 'crt->rsa.E' (17 bits) is\:\nMyFile(0999)\:  01 00 01\n"
@@ -44,21 +65,3 @@
 Debug print certificate #2 (EC)
 depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_BASE64_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_SHA256_C
 mbedtls_debug_print_crt:"data_files/test-ca2.crt":"MyFile":999:"PREFIX_":"MyFile(0999)\: PREFIX_ #1\:\nMyFile(0999)\: cert. version     \: 3\nMyFile(0999)\: serial number     \: C1\:43\:E2\:7E\:62\:43\:CC\:E8\nMyFile(0999)\: issuer name       \: C=NL, O=PolarSSL, CN=Polarssl Test EC CA\nMyFile(0999)\: subject name      \: C=NL, O=PolarSSL, CN=Polarssl Test EC CA\nMyFile(0999)\: issued  on        \: 2019-02-10 14\:44\:00\nMyFile(0999)\: expires on        \: 2029-02-10 14\:44\:00\nMyFile(0999)\: signed using      \: ECDSA with SHA256\nMyFile(0999)\: EC key size       \: 384 bits\nMyFile(0999)\: basic constraints \: CA=true\nMyFile(0999)\: value of 'crt->eckey.Q(X)' (384 bits) is\:\nMyFile(0999)\:  c3 da 2b 34 41 37 58 2f 87 56 fe fc 89 ba 29 43\nMyFile(0999)\:  4b 4e e0 6e c3 0e 57 53 33 39 58 d4 52 b4 91 95\nMyFile(0999)\:  39 0b 23 df 5f 17 24 62 48 fc 1a 95 29 ce 2c 2d\nMyFile(0999)\: value of 'crt->eckey.Q(Y)' (384 bits) is\:\nMyFile(0999)\:  87 c2 88 52 80 af d6 6a ab 21 dd b8 d3 1c 6e 58\nMyFile(0999)\:  b8 ca e8 b2 69 8e f3 41 ad 29 c3 b4 5f 75 a7 47\nMyFile(0999)\:  6f d5 19 29 55 69 9a 53 3b 20 b4 66 16 60 33 1e\n"
-
-Debug print mbedtls_mpi #1
-mbedtls_debug_print_mpi:16:"01020304050607":"MyFile":999:"VALUE":"MyFile(0999)\: value of 'VALUE' (49 bits) is\:\nMyFile(0999)\:  01 02 03 04 05 06 07\n"
-
-Debug print mbedtls_mpi #2
-mbedtls_debug_print_mpi:16:"00000000000007":"MyFile":999:"VALUE":"MyFile(0999)\: value of 'VALUE' (3 bits) is\:\nMyFile(0999)\:  07\n"
-
-Debug print mbedtls_mpi #3
-mbedtls_debug_print_mpi:16:"00000000000000":"MyFile":999:"VALUE":"MyFile(0999)\: value of 'VALUE' (0 bits) is\:\nMyFile(0999)\:  00\n"
-
-Debug print mbedtls_mpi #4
-mbedtls_debug_print_mpi:16:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":"MyFile":999:"VALUE":"MyFile(0999)\: value of 'VALUE' (764 bits) is\:\nMyFile(0999)\:  09 41 37 9d 00 fe d1 49 1f e1 5d f2 84 df de 4a\nMyFile(0999)\:  14 2f 68 aa 8d 41 20 23 19 5c ee 66 88 3e 62 90\nMyFile(0999)\:  ff e7 03 f4 ea 59 63 bf 21 27 13 ce e4 6b 10 7c\nMyFile(0999)\:  09 18 2b 5e dc d9 55 ad ac 41 8b f4 91 8e 28 89\nMyFile(0999)\:  af 48 e1 09 9d 51 38 30 ce c8 5c 26 ac 1e 15 8b\nMyFile(0999)\:  52 62 0e 33 ba 86 92 f8 93 ef bb 2f 95 8b 44 24\n"
-
-Debug print mbedtls_mpi #5
-mbedtls_debug_print_mpi:16:"0000000000000000000000000000000000000000000000000000000941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":"MyFile":999:"VALUE":"MyFile(0999)\: value of 'VALUE' (764 bits) is\:\nMyFile(0999)\:  09 41 37 9d 00 fe d1 49 1f e1 5d f2 84 df de 4a\nMyFile(0999)\:  14 2f 68 aa 8d 41 20 23 19 5c ee 66 88 3e 62 90\nMyFile(0999)\:  ff e7 03 f4 ea 59 63 bf 21 27 13 ce e4 6b 10 7c\nMyFile(0999)\:  09 18 2b 5e dc d9 55 ad ac 41 8b f4 91 8e 28 89\nMyFile(0999)\:  af 48 e1 09 9d 51 38 30 ce c8 5c 26 ac 1e 15 8b\nMyFile(0999)\:  52 62 0e 33 ba 86 92 f8 93 ef bb 2f 95 8b 44 24\n"
-
-Debug print mbedtls_mpi #6
-mbedtls_debug_print_mpi:16:"0000000000000000000000000000000000000000000000000000000041379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":"MyFile":999:"VALUE":"MyFile(0999)\: value of 'VALUE' (759 bits) is\:\nMyFile(0999)\:  41 37 9d 00 fe d1 49 1f e1 5d f2 84 df de 4a 14\nMyFile(0999)\:  2f 68 aa 8d 41 20 23 19 5c ee 66 88 3e 62 90 ff\nMyFile(0999)\:  e7 03 f4 ea 59 63 bf 21 27 13 ce e4 6b 10 7c 09\nMyFile(0999)\:  18 2b 5e dc d9 55 ad ac 41 8b f4 91 8e 28 89 af\nMyFile(0999)\:  48 e1 09 9d 51 38 30 ce c8 5c 26 ac 1e 15 8b 52\nMyFile(0999)\:  62 0e 33 ba 86 92 f8 93 ef bb 2f 95 8b 44 24\n"
diff --git a/tests/suites/test_suite_debug.function b/tests/suites/test_suite_debug.function
index 377d630..fe5549a 100644
--- a/tests/suites/test_suite_debug.function
+++ b/tests/suites/test_suite_debug.function
@@ -179,7 +179,7 @@
 
     TEST_ASSERT( mbedtls_ssl_setup( &ssl, &conf ) == 0 );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &val, radix, value ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &val, radix, value ) == 0 );
 
     mbedtls_ssl_conf_dbg( &conf, string_debug, &buffer);
 
diff --git a/tests/suites/test_suite_dhm.data b/tests/suites/test_suite_dhm.data
index c4795b6..e198bc6 100644
--- a/tests/suites/test_suite_dhm.data
+++ b/tests/suites/test_suite_dhm.data
@@ -1,26 +1,110 @@
+Diffie-Hellman full exchange: tiny x_size
+dhm_do_dhm:10:"93450983094850938450983409623":1:10:"9345098304850938450983409622":0
+
 Diffie-Hellman parameter validation
 dhm_invalid_params:
 
-Diffie-Hellman full exchange #1
-dhm_do_dhm:10:"23":10:"5":0
+Diffie-Hellman full exchange: 5-bit, x_size=3
+dhm_do_dhm:10:"23":3:10:"5":0
 
-Diffie-Hellman full exchange #2
-dhm_do_dhm:10:"93450983094850938450983409623":10:"9345098304850938450983409622":0
+Diffie-Hellman full exchange: 5-bit, x_size=2
+dhm_do_dhm:10:"23":2:10:"5":0
 
-Diffie-Hellman full exchange #3
-dhm_do_dhm:10:"93450983094850938450983409623982317398171298719873918739182739712938719287391879381271":10:"9345098309485093845098340962223981329819812792137312973297123912791271":0
+## Repeat this test case and a few similar ones several times. The RNG state
+## changes, so we get to exercise the code with a few different values.
+Diffie-Hellman full exchange: 5-bit #1
+dhm_do_dhm:10:"23":1:10:"5":0
 
-Diffie-Hellman trivial subgroup #1
-dhm_do_dhm:10:"23":10:"1":MBEDTLS_ERR_DHM_BAD_INPUT_DATA
+Diffie-Hellman full exchange: 5-bit #2
+dhm_do_dhm:10:"23":1:10:"5":0
 
-Diffie-Hellman trivial subgroup #2
-dhm_do_dhm:10:"23":10:"-1":MBEDTLS_ERR_DHM_BAD_INPUT_DATA
+Diffie-Hellman full exchange: 5-bit #3
+dhm_do_dhm:10:"23":1:10:"5":0
+
+Diffie-Hellman full exchange: 5-bit #4
+dhm_do_dhm:10:"23":1:10:"5":0
+
+Diffie-Hellman full exchange: 5-bit #5
+dhm_do_dhm:10:"23":1:10:"5":0
+
+## This is x_size = P_size + 1. Arguably x_size > P_size makes no sense,
+## but it's the current undocumented behavior to treat it the same as when
+## x_size = P_size. If this behavior changes in the future, change the expected
+## return status from 0 to MBEDTLS_ERR_DHM_BAD_INPUT_DATA.
+Diffie-Hellman full exchange: 97-bit, x_size=14
+dhm_do_dhm:10:"93450983094850938450983409623":14:10:"9345098304850938450983409622":0
+
+Diffie-Hellman full exchange: 97-bit #1
+dhm_do_dhm:10:"93450983094850938450983409623":13:10:"9345098304850938450983409622":0
+
+Diffie-Hellman full exchange: 97-bit #2
+dhm_do_dhm:10:"93450983094850938450983409623":13:10:"9345098304850938450983409622":0
+
+Diffie-Hellman full exchange: 97-bit #3
+dhm_do_dhm:10:"93450983094850938450983409623":13:10:"9345098304850938450983409622":0
+
+Diffie-Hellman full exchange: 97-bit #4
+dhm_do_dhm:10:"93450983094850938450983409623":13:10:"9345098304850938450983409622":0
+
+Diffie-Hellman full exchange: 97-bit #5
+dhm_do_dhm:10:"93450983094850938450983409623":13:10:"9345098304850938450983409622":0
+
+Diffie-Hellman full exchange: 97-bit, x_size=12
+dhm_do_dhm:10:"93450983094850938450983409623":12:10:"9345098304850938450983409622":0
+
+Diffie-Hellman full exchange: 97-bit, x_size=11
+dhm_do_dhm:10:"93450983094850938450983409623":11:10:"9345098304850938450983409622":0
+
+Diffie-Hellman full exchange: 97-bit, x_size=1 #1
+dhm_do_dhm:10:"93450983094850938450983409623":1:10:"9345098304850938450983409622":0
+
+Diffie-Hellman full exchange: 97-bit, x_size=1 #2
+dhm_do_dhm:10:"93450983094850938450983409623":1:10:"9345098304850938450983409622":0
+
+Diffie-Hellman full exchange: 97-bit, x_size=1 #3
+dhm_do_dhm:10:"93450983094850938450983409623":1:10:"9345098304850938450983409622":0
+
+Diffie-Hellman full exchange: 97-bit, x_size=1 #4
+dhm_do_dhm:10:"93450983094850938450983409623":1:10:"9345098304850938450983409622":0
+
+Diffie-Hellman full exchange: 97-bit, x_size=1 #5
+dhm_do_dhm:10:"93450983094850938450983409623":1:10:"9345098304850938450983409622":0
+
+Diffie-Hellman full exchange: 286-bit
+dhm_do_dhm:10:"93450983094850938450983409623982317398171298719873918739182739712938719287391879381271":36:10:"9345098309485093845098340962223981329819812792137312973297123912791271":0
 
 Diffie-Hellman small modulus
-dhm_do_dhm:10:"3":10:"5":MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED
+dhm_do_dhm:10:"3":1: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
+dhm_do_dhm:10:"0":1:10:"5":MBEDTLS_ERR_DHM_BAD_INPUT_DATA
+
+Diffie-Hellman: x_size < 0
+dhm_do_dhm:10:"93450983094850938450983409623":-1:10:"9345098304850938450983409622":MBEDTLS_ERR_DHM_BAD_INPUT_DATA
+
+Diffie-Hellman with G=0
+dhm_do_dhm:10:"93450983094850938450983409623":13:10:"0":MBEDTLS_ERR_DHM_BAD_INPUT_DATA
+
+Diffie-Hellman with G=1
+dhm_do_dhm:10:"93450983094850938450983409623":13:10:"1":MBEDTLS_ERR_DHM_BAD_INPUT_DATA
+
+Diffie-Hellman with G=-1
+dhm_do_dhm:10:"93450983094850938450983409623":13:10:"-1":MBEDTLS_ERR_DHM_BAD_INPUT_DATA
+
+Diffie-Hellman with G=P-1
+dhm_do_dhm:10:"93450983094850938450983409623":13:10:"93450983094850938450983409622":MBEDTLS_ERR_DHM_BAD_INPUT_DATA
+
+Diffie-Hellman with G=P-2
+dhm_do_dhm:10:"93450983094850938450983409623":13:10:"93450983094850938450983409621":0
+
+Diffie-Hellman with G=P
+dhm_do_dhm:10:"93450983094850938450983409623":13:10:"93450983094850938450983409623":MBEDTLS_ERR_DHM_BAD_INPUT_DATA
+
+Diffie-Hellman with G=P+1
+dhm_do_dhm:10:"93450983094850938450983409623":13:10:"93450983094850938450983409624":MBEDTLS_ERR_DHM_BAD_INPUT_DATA
+
+Diffie-Hellman with G=P+2
+dhm_do_dhm:10:"93450983094850938450983409623":13:10:"93450983094850938450983409625":0
 
 Diffie-Hellman MPI_MAX_SIZE modulus
 dhm_make_public:MBEDTLS_MPI_MAX_SIZE:10:"5":0
diff --git a/tests/suites/test_suite_dhm.function b/tests/suites/test_suite_dhm.function
index 6ec1e7e8..5eb601f 100644
--- a/tests/suites/test_suite_dhm.function
+++ b/tests/suites/test_suite_dhm.function
@@ -1,5 +1,66 @@
 /* BEGIN_HEADER */
 #include "mbedtls/dhm.h"
+
+/* Sanity checks on a Diffie-Hellman parameter: check the length-value
+ * syntax and check that the value is the expected one (taken from the
+ * DHM context by the caller). */
+static int check_dhm_param_output( const mbedtls_mpi *expected,
+                                   const unsigned char *buffer,
+                                   size_t size,
+                                   size_t *offset )
+{
+    size_t n;
+    mbedtls_mpi actual;
+    int ok = 0;
+    mbedtls_mpi_init( &actual );
+
+    TEST_ASSERT( size >= *offset + 2 );
+    n = ( buffer[*offset] << 8 ) | buffer[*offset + 1];
+    *offset += 2;
+    /* The DHM param output from Mbed TLS has leading zeros stripped, as
+     * permitted but not required by RFC 5246 \S4.4. */
+    TEST_EQUAL( n, mbedtls_mpi_size( expected ) );
+    TEST_ASSERT( size >= *offset + n );
+    TEST_EQUAL( 0, mbedtls_mpi_read_binary( &actual, buffer + *offset, n ) );
+    TEST_EQUAL( 0, mbedtls_mpi_cmp_mpi( expected, &actual ) );
+    *offset += n;
+
+    ok = 1;
+exit:
+    mbedtls_mpi_free( &actual );
+    return( ok );
+}
+
+/* Sanity checks on Diffie-Hellman parameters: syntax, range, and comparison
+ * against the context. */
+static int check_dhm_params( const mbedtls_dhm_context *ctx,
+                             size_t x_size,
+                             const unsigned char *ske, size_t ske_len )
+{
+    size_t offset = 0;
+
+    /* Check that ctx->X and ctx->GX are within range. */
+    TEST_ASSERT( mbedtls_mpi_cmp_int( &ctx->X, 1 ) > 0 );
+    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->P ) < 0 );
+    TEST_ASSERT( mbedtls_mpi_size( &ctx->X ) <= x_size );
+    TEST_ASSERT( mbedtls_mpi_cmp_int( &ctx->GX, 1 ) > 0 );
+    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &ctx->GX, &ctx->P ) < 0 );
+
+    /* Check ske: it must contain P, G and G^X, each prefixed with a
+     * 2-byte size. */
+    if( !check_dhm_param_output( &ctx->P, ske, ske_len, &offset ) )
+        goto exit;
+    if( !check_dhm_param_output( &ctx->G, ske, ske_len, &offset ) )
+        goto exit;
+    if( !check_dhm_param_output( &ctx->GX, ske, ske_len, &offset ) )
+        goto exit;
+    TEST_EQUAL( offset, ske_len );
+
+    return( 1 );
+exit:
+    return( 0 );
+}
+
 /* END_HEADER */
 
 /* BEGIN_DEPENDENCIES
@@ -115,7 +176,7 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void dhm_do_dhm( int radix_P, char *input_P,
+void dhm_do_dhm( int radix_P, char *input_P, int x_size,
                  int radix_G, char *input_G, int result )
 {
     mbedtls_dhm_context ctx_srv;
@@ -129,7 +190,7 @@
     size_t pub_cli_len = 0;
     size_t sec_srv_len;
     size_t sec_cli_len;
-    int x_size, i;
+    int i;
     rnd_pseudo_info rnd_info;
 
     mbedtls_dhm_init( &ctx_srv );
@@ -143,17 +204,20 @@
     /*
      * Set params
      */
-    TEST_ASSERT( mbedtls_mpi_read_string( &ctx_srv.P, radix_P, input_P ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &ctx_srv.G, radix_G, input_G ) == 0 );
-    x_size = mbedtls_mpi_size( &ctx_srv.P );
-    pub_cli_len = x_size;
+    TEST_ASSERT( mbedtls_test_read_mpi( &ctx_srv.P, radix_P, input_P ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &ctx_srv.G, radix_G, input_G ) == 0 );
+    pub_cli_len = mbedtls_mpi_size( &ctx_srv.P );
 
     /*
      * First key exchange
      */
-    TEST_ASSERT( mbedtls_dhm_make_params( &ctx_srv, x_size, ske, &ske_len, &rnd_pseudo_rand, &rnd_info ) == result );
+    TEST_ASSERT( mbedtls_dhm_make_params( &ctx_srv, x_size, ske, &ske_len,
+                                          &rnd_pseudo_rand,
+                                          &rnd_info ) == result );
     if ( result != 0 )
         goto exit;
+    if( !check_dhm_params( &ctx_srv, x_size, ske, ske_len ) )
+        goto exit;
 
     ske[ske_len++] = 0;
     ske[ske_len++] = 0;
@@ -185,7 +249,11 @@
      */
     p = ske;
 
-    TEST_ASSERT( mbedtls_dhm_make_params( &ctx_srv, x_size, ske, &ske_len, &rnd_pseudo_rand, &rnd_info ) == 0 );
+    TEST_ASSERT( mbedtls_dhm_make_params( &ctx_srv, x_size, ske, &ske_len,
+                                          &rnd_pseudo_rand,
+                                          &rnd_info ) == 0 );
+    if( !check_dhm_params( &ctx_srv, x_size, ske, ske_len ) )
+        goto exit;
     ske[ske_len++] = 0;
     ske[ske_len++] = 0;
     TEST_ASSERT( mbedtls_dhm_read_params( &ctx_cli, &p, ske + ske_len ) == 0 );
@@ -221,7 +289,7 @@
     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_test_read_mpi( &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 ),
@@ -245,8 +313,8 @@
     mbedtls_dhm_init( &ctx );
     mbedtls_mpi_init( &P ); mbedtls_mpi_init( &G );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &P, 16, p ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &G, 16, g ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &P, 16, p ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &G, 16, g ) == 0 );
 
     TEST_ASSERT( mbedtls_dhm_parse_dhmfile( &ctx, filename ) == 0 );
 
diff --git a/tests/suites/test_suite_ecdh.function b/tests/suites/test_suite_ecdh.function
index 32d41e6..7ccd871 100644
--- a/tests/suites/test_suite_ecdh.function
+++ b/tests/suites/test_suite_ecdh.function
@@ -272,20 +272,20 @@
     TEST_ASSERT( mbedtls_ecdh_gen_public( &grp, &dA, &qA,
                                   rnd_buffer_rand, &rnd_info_A ) == 0 );
     TEST_ASSERT( ! mbedtls_ecp_is_zero( &qA ) );
-    TEST_ASSERT( mbedtls_mpi_read_string( &check, 16, xA_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &check, 16, xA_str ) == 0 );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &qA.X, &check ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &check, 16, yA_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &check, 16, yA_str ) == 0 );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &qA.Y, &check ) == 0 );
 
     TEST_ASSERT( mbedtls_ecdh_gen_public( &grp, &dB, &qB,
                                   rnd_buffer_rand, &rnd_info_B ) == 0 );
     TEST_ASSERT( ! mbedtls_ecp_is_zero( &qB ) );
-    TEST_ASSERT( mbedtls_mpi_read_string( &check, 16, xB_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &check, 16, xB_str ) == 0 );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &qB.X, &check ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &check, 16, yB_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &check, 16, yB_str ) == 0 );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &qB.Y, &check ) == 0 );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &check, 16, z_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &check, 16, z_str ) == 0 );
     TEST_ASSERT( mbedtls_ecdh_compute_shared( &grp, &zA, &qB, &dA, NULL, NULL ) == 0 );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &zA, &check ) == 0 );
     TEST_ASSERT( mbedtls_ecdh_compute_shared( &grp, &zB, &qA, &dB, NULL, NULL ) == 0 );
diff --git a/tests/suites/test_suite_ecdsa.function b/tests/suites/test_suite_ecdsa.function
index 7b1718f..06d9fb6 100644
--- a/tests/suites/test_suite_ecdsa.function
+++ b/tests/suites/test_suite_ecdsa.function
@@ -277,9 +277,9 @@
 
     TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
     TEST_ASSERT( mbedtls_ecp_point_read_string( &Q, 16, xQ_str, yQ_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &d, 16, d_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &r_check, 16, r_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &s_check, 16, s_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &d, 16, d_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &r_check, 16, r_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &s_check, 16, s_str ) == 0 );
     rnd_info.buf = rnd_buf->x;
     rnd_info.length = rnd_buf->len;
 
@@ -340,9 +340,9 @@
     memset( hash, 0, sizeof( hash ) );
 
     TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &d, 16, d_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &r_check, 16, r_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &s_check, 16, s_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &d, 16, d_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &r_check, 16, r_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &s_check, 16, s_str ) == 0 );
 
     md_info = mbedtls_md_info_from_type( md_alg );
     TEST_ASSERT( md_info != NULL );
@@ -513,7 +513,7 @@
     memset( sig, 0, sizeof( sig ) );
 
     TEST_ASSERT( mbedtls_ecp_group_load( &ctx.grp, id ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &ctx.d, 16, d_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &ctx.d, 16, d_str ) == 0 );
 
     md_info = mbedtls_md_info_from_type( md_alg );
     TEST_ASSERT( md_info != NULL );
diff --git a/tests/suites/test_suite_ecp.data b/tests/suites/test_suite_ecp.data
index 2c25cd7..fdbec16 100644
--- a/tests/suites/test_suite_ecp.data
+++ b/tests/suites/test_suite_ecp.data
@@ -36,13 +36,133 @@
 depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED
 mbedtls_ecp_curve_info:MBEDTLS_ECP_DP_SECP192R1:19:192:"secp192r1"
 
-ECP check pubkey Montgomery #1 (too big)
+ECP check pubkey Curve25519 #1 (biggest)
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF":"0":"1":0
+
+ECP check pubkey Curve25519 #2 (too big)
 depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
 ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"010000000000000000000000000000000000000000000000000000000000000000":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
 
-ECP check pubkey Montgomery #2 (biggest)
+ECP check pubkey Curve25519 #3 (DoS big)
 depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
-ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF":"0":"1":0
+ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"0100000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
+
+ECP check pubkey Curve25519 y ignored
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"2":"-1":"1":0
+
+ECP check pubkey Curve25519 z is not 1
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"2":"0":"2":MBEDTLS_ERR_ECP_INVALID_KEY
+
+ECP check pubkey Curve25519 x negative
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"-2":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
+
+# see https://cr.yp.to/ecdh.html#validate
+ECP check pubkey Curve25519 low-order point #1
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"0":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
+
+# see https://cr.yp.to/ecdh.html#validate
+ECP check pubkey Curve25519 low-order point #2
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"1":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
+
+# see https://cr.yp.to/ecdh.html#validate
+ECP check pubkey Curve25519 low-order point #3 (let's call this u)
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"b8495f16056286fdb1329ceb8d09da6ac49ff1fae35616aeb8413b7c7aebe0":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
+
+# see https://cr.yp.to/ecdh.html#validate
+ECP check pubkey Curve25519 low-order point #4 (let's call this v)
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"57119fd0dd4e22d8868e1c58c45c44045bef839c55b1d0b1248c50a3bc959c5f":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
+
+# see https://cr.yp.to/ecdh.html#validate
+ECP check pubkey Curve25519 low-order point #5 p-1
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
+
+# see https://cr.yp.to/ecdh.html#validate
+ECP check pubkey Curve25519 low-order point #6 p
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
+
+# see https://cr.yp.to/ecdh.html#validate
+ECP check pubkey Curve25519 low-order point #7 p+1
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
+
+# see https://cr.yp.to/ecdh.html#validate
+ECP check pubkey Curve25519 low-order point #8 p+u
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"80b8495f16056286fdb1329ceb8d09da6ac49ff1fae35616aeb8413b7c7aebcd":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
+
+# see https://cr.yp.to/ecdh.html#validate
+ECP check pubkey Curve25519 low-order point #9 p+v
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"d7119fd0dd4e22d8868e1c58c45c44045bef839c55b1d0b1248c50a3bc959c4c":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
+
+# see https://cr.yp.to/ecdh.html#validate
+ECP check pubkey Curve25519 low-order point #10 2p-1
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd9":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
+
+# see https://cr.yp.to/ecdh.html#validate
+ECP check pubkey Curve25519 low-order point #11 2p
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffda":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
+
+# see https://cr.yp.to/ecdh.html#validate
+ECP check pubkey Curve25519 low-order point #12 2p+1
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdb":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
+
+ECP check pubkey Curve448 #1 (biggest)
+depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
+ecp_check_pub:MBEDTLS_ECP_DP_CURVE448:"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF":"0":"1":0
+
+ECP check pubkey Curve448 #2 (too big)
+depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
+ecp_check_pub:MBEDTLS_ECP_DP_CURVE448:"01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
+
+ECP check pubkey Curve448 #3 (DoS big)
+depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
+ecp_check_pub:MBEDTLS_ECP_DP_CURVE448:"0100000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
+
+ECP check pubkey Curve448 y ignored
+depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
+ecp_check_pub:MBEDTLS_ECP_DP_CURVE448:"2":"-1":"1":0
+
+ECP check pubkey Curve448 z is not 1
+depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
+ecp_check_pub:MBEDTLS_ECP_DP_CURVE448:"2":"0":"2":MBEDTLS_ERR_ECP_INVALID_KEY
+
+ECP check pubkey Curve448 x negative
+depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
+ecp_check_pub:MBEDTLS_ECP_DP_CURVE448:"-2":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
+
+ECP check pubkey Curve448 low-order point #1
+depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
+ecp_check_pub:MBEDTLS_ECP_DP_CURVE448:"0":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
+
+ECP check pubkey Curve448 low-order point #2
+depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
+ecp_check_pub:MBEDTLS_ECP_DP_CURVE448:"1":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
+
+ECP check pubkey Curve448 low-order point #3 p-1
+depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
+ecp_check_pub:MBEDTLS_ECP_DP_CURVE448:"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
+
+ECP check pubkey Curve448 low-order point #4 p
+depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
+ecp_check_pub:MBEDTLS_ECP_DP_CURVE448:"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
+
+ECP check pubkey Curve448 low-order point #5 p+1
+depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
+ecp_check_pub:MBEDTLS_ECP_DP_CURVE448:"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000000000000":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
 
 ECP check pubkey Koblitz #1 (point not on curve)
 depends_on:MBEDTLS_ECP_DP_SECP224K1_ENABLED
@@ -344,6 +464,14 @@
 depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
 ecp_test_mul_rng:MBEDTLS_ECP_DP_CURVE25519:"5AC99F33632E5A768DE7E81BF854C27C46E3FBF2ABBACD29EC4AFF517369C660"
 
+ECP point muladd secp256r1 #1
+depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+ecp_muladd:MBEDTLS_ECP_DP_SECP256R1:"01":"04e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e0e1ff20e1ffe120e1e1e173287170a761308491683e345cacaebb500c96e1a7bbd37772968b2c951f0579":"01":"04e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1ffffffff20e120e1e1e1e13a4e135157317b79d4ecf329fed4f9eb00dc67dbddae33faca8b6d8a0255b5ce":"04fab65e09aa5dd948320f86246be1d3fc571e7f799d9005170ed5cc868b67598431a668f96aa9fd0b0eb15f0edf4c7fe1be2885eadcb57e3db4fdd093585d3fa6"
+
+ECP point muladd secp256r1 #2
+depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+ecp_muladd:MBEDTLS_ECP_DP_SECP256R1:"01":"04e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1ffffffff20e120e1e1e1e13a4e135157317b79d4ecf329fed4f9eb00dc67dbddae33faca8b6d8a0255b5ce":"01":"04e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e0e1ff20e1ffe120e1e1e173287170a761308491683e345cacaebb500c96e1a7bbd37772968b2c951f0579":"04fab65e09aa5dd948320f86246be1d3fc571e7f799d9005170ed5cc868b67598431a668f96aa9fd0b0eb15f0edf4c7fe1be2885eadcb57e3db4fdd093585d3fa6"
+
 ECP test vectors secp192k1
 depends_on:MBEDTLS_ECP_DP_SECP192K1_ENABLED
 ecp_test_vect:MBEDTLS_ECP_DP_SECP192K1:"D1E13A359F6E0F0698791938E6D60246030AE4B0D8D4E9DE":"281BCA982F187ED30AD5E088461EBE0A5FADBB682546DF79":"3F68A8E9441FB93A4DD48CB70B504FCC9AA01902EF5BE0F3":"BE97C5D2A1A94D081E3FACE53E65A27108B7467BDF58DE43":"5EB35E922CD693F7947124F5920022C4891C04F6A8B8DCB2":"60ECF73D0FC43E0C42E8E155FFE39F9F0B531F87B34B6C3C":"372F5C5D0E18313C82AEF940EC3AFEE26087A46F1EBAE923":"D5A9F9182EC09CEAEA5F57EA10225EC77FA44174511985FD"
diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function
index e37a017..3662b75 100644
--- a/tests/suites/test_suite_ecp.function
+++ b/tests/suites/test_suite_ecp.function
@@ -1,6 +1,25 @@
 /* BEGIN_HEADER */
 #include "mbedtls/ecp.h"
 
+/* Backported from Mbed TLS 2.x for test dependencies. */
+#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \
+    defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
+    defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
+    defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \
+    defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \
+    defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \
+    defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \
+    defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) || \
+    defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
+    defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
+    defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
+#define MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED
+#endif
+#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || \
+    defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
+#define MBEDTLS_ECP_MONTGOMERY_ENABLED
+#endif
+
 #define ECP_PF_UNKNOWN     -1
 
 #define ECP_PT_RESET( x )           \
@@ -374,6 +393,8 @@
     TEST_ASSERT( by_id == by_name );
 
     TEST_ASSERT( by_id->bit_size == size );
+    TEST_ASSERT( size <= MBEDTLS_ECP_MAX_BITS );
+    TEST_ASSERT( size <= MBEDTLS_ECP_MAX_BYTES * 8 );
 }
 /* END_CASE */
 
@@ -389,9 +410,9 @@
 
     TEST_ASSERT( mbedtls_ecp_group_load( &grp, grp_id ) == 0 );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &P.X, 16, x_hex ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &P.Y, 16, y_hex ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &P.Z, 16, z_hex ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &P.X, 16, x_hex ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &P.Y, 16, y_hex ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &P.Z, 16, z_hex ) == 0 );
 
     TEST_ASSERT( mbedtls_ecp_check_pubkey( &grp, &P ) == ret );
 
@@ -440,13 +461,13 @@
 
     TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &dA, 16, dA_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &xA, 16, xA_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &yA, 16, yA_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &dA, 16, dA_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &xA, 16, xA_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &yA, 16, yA_str ) == 0 );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &dB, 16, dB_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &xZ, 16, xZ_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &yZ, 16, yZ_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &dB, 16, dB_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &xZ, 16, xZ_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &yZ, 16, yZ_str ) == 0 );
 
     mbedtls_ecp_set_max_ops( (unsigned) max_ops );
 
@@ -524,13 +545,13 @@
 
     TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &u1, 16, u1_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &u2, 16, u2_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &xR, 16, xR_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &yR, 16, yR_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &u1, 16, u1_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &u2, 16, u2_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &xR, 16, xR_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &yR, 16, yR_str ) == 0 );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &Q.X, 16, xQ_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Q.Y, 16, yQ_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Q.X, 16, xQ_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Q.Y, 16, yQ_str ) == 0 );
     TEST_ASSERT( mbedtls_mpi_lset( &Q.Z, 1 ) == 0 );
 
     mbedtls_ecp_set_max_ops( (unsigned) max_ops );
@@ -587,14 +608,14 @@
 
     TEST_ASSERT( mbedtls_ecp_check_pubkey( &grp, &grp.G ) == 0 );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &dA, 16, dA_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &xA, 16, xA_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &yA, 16, yA_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &dB, 16, dB_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &xB, 16, xB_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &yB, 16, yB_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &xZ, 16, xZ_str ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &yZ, 16, yZ_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &dA, 16, dA_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &xA, 16, xA_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &yA, 16, yA_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &dB, 16, dB_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &xB, 16, xB_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &yB, 16, yB_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &xZ, 16, xZ_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &yZ, 16, yZ_str ) == 0 );
 
     TEST_ASSERT( mbedtls_ecp_mul( &grp, &R, &dA, &grp.G,
                           &rnd_pseudo_rand, &rnd_info ) == 0 );
@@ -642,11 +663,11 @@
 
     TEST_ASSERT( mbedtls_ecp_check_pubkey( &grp, &grp.G ) == 0 );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &dA, 16, dA_hex ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &dB, 16, dB_hex ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &xA, 16, xA_hex ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &xB, 16, xB_hex ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &xS, 16, xS_hex ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &dA, 16, dA_hex ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &dB, 16, dB_hex ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &xA, 16, xA_hex ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &xB, 16, xB_hex ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &xS, 16, xS_hex ) == 0 );
 
     TEST_ASSERT( mbedtls_ecp_mul( &grp, &R, &dA, &grp.G,
                           &rnd_pseudo_rand, &rnd_info ) == 0 );
@@ -699,6 +720,53 @@
 }
 /* END_CASE */
 
+/* BEGIN_CASE depends_on:MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
+void ecp_muladd( int id,
+                 data_t *u1_bin, data_t *P1_bin,
+                 data_t *u2_bin, data_t *P2_bin,
+                 data_t *expected_result )
+{
+    /* Compute R = u1 * P1 + u2 * P2 */
+    mbedtls_ecp_group grp;
+    mbedtls_ecp_point P1, P2, R;
+    mbedtls_mpi u1, u2;
+    uint8_t actual_result[MBEDTLS_ECP_MAX_PT_LEN];
+    size_t len;
+
+    mbedtls_ecp_group_init( &grp );
+    mbedtls_ecp_point_init( &P1 );
+    mbedtls_ecp_point_init( &P2 );
+    mbedtls_ecp_point_init( &R );
+    mbedtls_mpi_init( &u1 );
+    mbedtls_mpi_init( &u2 );
+
+    TEST_EQUAL( 0, mbedtls_ecp_group_load( &grp, id ) );
+    TEST_EQUAL( 0, mbedtls_mpi_read_binary( &u1, u1_bin->x, u1_bin->len ) );
+    TEST_EQUAL( 0, mbedtls_mpi_read_binary( &u2, u2_bin->x, u2_bin->len ) );
+    TEST_EQUAL( 0, mbedtls_ecp_point_read_binary( &grp, &P1,
+                                                  P1_bin->x, P1_bin->len ) );
+    TEST_EQUAL( 0, mbedtls_ecp_point_read_binary( &grp, &P2,
+                                                  P2_bin->x, P2_bin->len ) );
+
+    TEST_EQUAL( 0, mbedtls_ecp_muladd( &grp, &R, &u1, &P1, &u2, &P2 ) );
+    TEST_EQUAL( 0, mbedtls_ecp_point_write_binary(
+                    &grp, &R, MBEDTLS_ECP_PF_UNCOMPRESSED,
+                    &len, actual_result, sizeof( actual_result ) ) );
+    TEST_ASSERT( len <= MBEDTLS_ECP_MAX_PT_LEN );
+
+    ASSERT_COMPARE( expected_result->x, expected_result->len,
+                    actual_result, len );
+
+exit:
+    mbedtls_ecp_group_free( &grp );
+    mbedtls_ecp_point_free( &P1 );
+    mbedtls_ecp_point_free( &P2 );
+    mbedtls_ecp_point_free( &R );
+    mbedtls_mpi_free( &u1 );
+    mbedtls_mpi_free( &u2 );
+}
+/* END_CASE */
+
 /* BEGIN_CASE */
 void ecp_fast_mod( int id, char * N_str )
 {
@@ -708,7 +776,7 @@
     mbedtls_mpi_init( &N ); mbedtls_mpi_init( &R );
     mbedtls_ecp_group_init( &grp );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, 16, N_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, 16, N_str ) == 0 );
     TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
     TEST_ASSERT( grp.modp != NULL );
 
@@ -747,15 +815,16 @@
 
     TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &P.X, 16, x ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &P.Y, 16, y ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &P.Z, 16, z ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &P.X, 16, x ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &P.Y, 16, y ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &P.Z, 16, z ) == 0 );
 
     TEST_ASSERT( mbedtls_ecp_point_write_binary( &grp, &P, format,
                                    &olen, buf, blen ) == ret );
 
     if( ret == 0 )
     {
+        TEST_ASSERT( olen <= MBEDTLS_ECP_MAX_PT_LEN );
         TEST_ASSERT( mbedtls_test_hexcmp( buf, out->x, olen, out->len ) == 0 );
     }
 
@@ -778,9 +847,9 @@
 
     TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, 16, x ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Y, 16, y ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Z, 16, z ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, 16, x ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y, 16, y ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Z, 16, z ) == 0 );
 
     TEST_ASSERT( mbedtls_ecp_point_read_binary( &grp, &P, buf->x, buf->len ) == ret );
 
@@ -812,9 +881,9 @@
 
     TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, 16, x ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Y, 16, y ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Z, 16, z ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, 16, x ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y, 16, y ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Z, 16, z ) == 0 );
 
     TEST_ASSERT( mbedtls_ecp_tls_read_point( &grp, &P, &vbuf, buf->len ) == ret );
 
@@ -949,7 +1018,7 @@
     mbedtls_mpi_init( &d );
 
     TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &d, 16, key_hex ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &d, 16, key_hex ) == 0 );
 
     TEST_ASSERT( mbedtls_ecp_check_privkey( &grp, &d ) == ret );
 
@@ -976,7 +1045,7 @@
     if( id != MBEDTLS_ECP_DP_NONE )
         TEST_ASSERT( mbedtls_ecp_group_load( &prv.grp, id ) == 0 );
     TEST_ASSERT( mbedtls_ecp_point_read_string( &prv.Q, 16, Qx, Qy ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &prv.d, 16, d ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &prv.d, 16, d ) == 0 );
 
     TEST_ASSERT( mbedtls_ecp_check_pub_priv( &pub, &prv ) == ret );
 
diff --git a/tests/suites/test_suite_entropy.data b/tests/suites/test_suite_entropy.data
index 5cff399..25fd57f 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:
 
@@ -7,6 +13,9 @@
 Entropy write/update seed file
 entropy_seed_file:"no_such_dir/file":MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR
 
+Entropy write/update seed file: base NV seed file
+entropy_write_base_seed_file:0
+
 Entropy too many sources
 entropy_too_many_sources:
 
diff --git a/tests/suites/test_suite_entropy.function b/tests/suites/test_suite_entropy.function
index 889d3bc..6aa8dd3 100644
--- a/tests/suites/test_suite_entropy.function
+++ b/tests/suites/test_suite_entropy.function
@@ -125,6 +125,28 @@
  * END_DEPENDENCIES
  */
 
+/* BEGIN_CASE */
+void entropy_init_free( int reinit )
+{
+    mbedtls_entropy_context ctx;
+
+    /* Double free is not explicitly documented to work, but it is convenient
+     * to call mbedtls_entropy_free() unconditionally on an error path without
+     * checking whether it has already been called in the success path. */
+
+    mbedtls_entropy_init( &ctx );
+    mbedtls_entropy_free( &ctx );
+
+    if( reinit )
+        mbedtls_entropy_init( &ctx );
+    mbedtls_entropy_free( &ctx );
+
+    /* This test case always succeeds, functionally speaking. A plausible
+     * bug might trigger an invalid pointer dereference or a memory leak. */
+    goto exit;
+}
+/* END_CASE */
+
 /* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
 void entropy_seed_file( char * path, int ret )
 {
@@ -140,6 +162,21 @@
 }
 /* END_CASE */
 
+/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
+void entropy_write_base_seed_file( int ret )
+{
+    mbedtls_entropy_context ctx;
+
+    mbedtls_entropy_init( &ctx );
+
+    TEST_ASSERT( mbedtls_entropy_write_seed_file( &ctx, MBEDTLS_PLATFORM_STD_NV_SEED_FILE ) == ret );
+    TEST_ASSERT( mbedtls_entropy_update_seed_file( &ctx, MBEDTLS_PLATFORM_STD_NV_SEED_FILE ) == ret );
+
+exit:
+    mbedtls_entropy_free( &ctx );
+}
+/* END_CASE */
+
 /* BEGIN_CASE */
 void entropy_too_many_sources(  )
 {
@@ -191,6 +228,9 @@
 
     for( j = len; j < sizeof( buf ); j++ )
         TEST_ASSERT( acc[j] == 0 );
+
+exit:
+    mbedtls_entropy_free( &ctx );
 }
 /* END_CASE */
 
diff --git a/tests/suites/test_suite_mpi.data b/tests/suites/test_suite_mpi.data
index 6c520eb..d1d6908 100644
--- a/tests/suites/test_suite_mpi.data
+++ b/tests/suites/test_suite_mpi.data
@@ -10,21 +10,39 @@
 Base test mpi_read_write_string #1
 mpi_read_write_string:10:"128":10:"128":100:0:0
 
+Base test mpi_read_write_string #1 (Leading 0)
+mpi_read_write_string:10:"0128":10:"128":100:0:0
+
 Base test mpi_read_write_string #2
 mpi_read_write_string:10:"128":16:"80":100:0:0
 
-Base test mpi_read_write_string #3 (Read zero)
+Base test mpi_read_write_string #3 (Read zero decimal)
 mpi_read_write_string:10:"0":10:"0":100:0:0
 
+Base test mpi_read_write_string #3 (Read zero hex)
+mpi_read_write_string:16:"0":16:"00":100:0:0
+
+Base test mpi_read_write_string #3 (Read minus zero decimal)
+mpi_read_write_string:10:"-0":10:"0":100:0:0
+
+Base test mpi_read_write_string #3 (Read minus zero hex)
+mpi_read_write_string:16:"-0":16:"00":100:0:0
+
 Base test mpi_read_write_string #3 (Negative decimal)
 mpi_read_write_string:10:"-23":10:"-23":100:0:0
 
-Base test mpi_read_write_string #3 (Negative hex)
+Base test mpi_read_write_string #3 (Negative decimal, leading 0)
+mpi_read_write_string:10:"-023":10:"-23":100:0:0
+
+Base test mpi_read_write_string #3 (Negative hex -> decimal)
 mpi_read_write_string:16:"-20":10:"-32":100:0:0
 
-Base test mpi_read_write_string #3 (Negative decimal)
+Base test mpi_read_write_string #3 (Negative hex)
 mpi_read_write_string:16:"-23":16:"-23":100:0:0
 
+Base test mpi_read_write_string #3 (Negative hex, leading 0)
+mpi_read_write_string:16:"-023":16:"-23":100:0:0
+
 Base test mpi_read_write_string #4 (Buffer just fits)
 mpi_read_write_string:16:"-4":4:"-10":4:0:0
 
@@ -49,12 +67,18 @@
 Test mpi_read_write_string #7
 mpi_read_write_string:10:"56125680981752282334141896320372489490613963693556392520816017892111350604111697682705498319512049040516698827829292076808006940873974979584527073481012636016353913462376755556720019831187364993587901952757307830896531678727717924":16:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":200:0:0
 
-Test mpi_read_write_string #8 (Empty MPI -> hex)
+Test mpi_read_write_string #8 (Empty MPI hex -> hex)
 mpi_read_write_string:16:"":16:"00":4:0:0
 
-Test mpi_read_write_string #9 (Empty MPI -> dec)
+Test mpi_read_write_string #9 (Empty MPI hex -> dec)
 mpi_read_write_string:16:"":10:"0":4:0:0
 
+Test mpi_read_write_string #8 (Empty MPI dec -> hex)
+mpi_read_write_string:10:"":16:"00":4:0:0
+
+Test mpi_read_write_string #9 (Empty MPI dec -> dec)
+mpi_read_write_string:10:"":10:"0":4:0:0
+
 Test mpi_write_string #10 (Negative hex with odd number of digits)
 mpi_read_write_string:16:"-1":16:"":3:0:MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL
 
@@ -85,6 +109,12 @@
 Base test mbedtls_mpi_write_file #1
 mbedtls_mpi_write_file:10:"56125680981752282334141896320372489490613963693556392520816017892111350604111697682705498319512049040516698827829292076808006940873974979584527073481012636016353913462376755556720019831187364993587901952757307830896531678727717924":16:"data_files/mpi_write"
 
+Test mbedtls_mpi_lsb: 0 (null)
+mbedtls_mpi_lsb:16:"":0
+
+Test mbedtls_mpi_lsb: 0 (1 limb)
+mbedtls_mpi_lsb:16:"0":0
+
 Base test mbedtls_mpi_lsb #1
 mbedtls_mpi_lsb:10:"56125680981752282334141896320372489490613963693556392520816017892111350604111697682705498319512049040516698827829292076808006940873974979584527073481012636016353913462376755556720019831187364993587901952757307830896531678727717924":2
 
@@ -115,7 +145,10 @@
 Base test mbedtls_mpi_bitlen #6
 mbedtls_mpi_bitlen:10:"10":4
 
-Base test mbedtls_mpi_bitlen #7
+Base test mbedtls_mpi_bitlen: 0 (null)
+mbedtls_mpi_bitlen:10:"":0
+
+Base test mbedtls_mpi_bitlen: 0 (1 limb)
 mbedtls_mpi_bitlen:10:"0":0
 
 Base test mbedtls_mpi_cmp_int #1
@@ -163,6 +196,90 @@
 Base test mbedtls_mpi_cmp_mpi (Mixed values) #6
 mbedtls_mpi_cmp_mpi:10:"-2":10:"31231231289798":-1
 
+Test mbedtls_mpi_cmp_mpi: 0 (null) = 0 (null)
+mbedtls_mpi_cmp_mpi:10:"":10:"":0
+
+Test mbedtls_mpi_cmp_mpi: 0 (null) = 0 (1 limb)
+mbedtls_mpi_cmp_mpi:10:"":10:"0":0
+
+Test mbedtls_mpi_cmp_mpi: 0 (1 limb) = 0 (null)
+mbedtls_mpi_cmp_mpi:10:"0":10:"":0
+
+Test mbedtls_mpi_cmp_mpi: 0 (1 limb) = 0 (1 limb)
+mbedtls_mpi_cmp_mpi:10:"0":10:"0":0
+
+Test mbedtls_mpi_cmp_mpi: 0 (null) < positive
+mbedtls_mpi_cmp_mpi:10:"":10:"123":-1
+
+Test mbedtls_mpi_cmp_mpi: 0 (1 limb) < positive
+mbedtls_mpi_cmp_mpi:10:"0":10:"123":-1
+
+Test mbedtls_mpi_cmp_mpi: 0 (null) > negative
+mbedtls_mpi_cmp_mpi:10:"":10:"-123":1
+
+Test mbedtls_mpi_cmp_mpi: 0 (1 limb) > negative
+mbedtls_mpi_cmp_mpi:10:"0":10:"-123":1
+
+Test mbedtls_mpi_cmp_mpi: positive > 0 (null)
+mbedtls_mpi_cmp_mpi:10:"123":10:"":1
+
+Test mbedtls_mpi_cmp_mpi: positive > 0 (1 limb)
+mbedtls_mpi_cmp_mpi:10:"123":10:"0":1
+
+Test mbedtls_mpi_cmp_mpi: negative < 0 (null)
+mbedtls_mpi_cmp_mpi:10:"-123":10:"":-1
+
+Test mbedtls_mpi_cmp_mpi: negative < 0 (1 limb)
+mbedtls_mpi_cmp_mpi:10:"-123":10:"0":-1
+
+Test mbedtls_mpi_cmp_mpi: 0 (null) < positive with leading zero limb
+mbedtls_mpi_cmp_mpi:16:"":16:"0000000000000000123":-1
+
+Test mbedtls_mpi_cmp_mpi: 0 (1 limb) < positive with leading zero limb
+mbedtls_mpi_cmp_mpi:16:"0":16:"0000000000000000123":-1
+
+Test mbedtls_mpi_cmp_mpi: 0 (null) > negative with leading zero limb
+mbedtls_mpi_cmp_mpi:16:"":16:"-0000000000000000123":1
+
+Test mbedtls_mpi_cmp_mpi: 0 (1 limb) > negative with leading zero limb
+mbedtls_mpi_cmp_mpi:16:"0":16:"-0000000000000000123":1
+
+Test mbedtls_mpi_cmp_mpi: positive with leading zero limb > 0 (null)
+mbedtls_mpi_cmp_mpi:16:"0000000000000000123":16:"":1
+
+Test mbedtls_mpi_cmp_mpi: positive with leading zero limb > 0 (1 limb)
+mbedtls_mpi_cmp_mpi:16:"0000000000000000123":16:"0":1
+
+Test mbedtls_mpi_cmp_mpi: negative with leading zero limb < 0 (null)
+mbedtls_mpi_cmp_mpi:16:"-0000000000000000123":16:"":-1
+
+Test mbedtls_mpi_cmp_mpi: negative with leading zero limb < 0 (1 limb)
+mbedtls_mpi_cmp_mpi:16:"-0000000000000000123":16:"0":-1
+
+Test mbedtls_mpi_cmp_mpi: 0 (null) < large positive
+mbedtls_mpi_cmp_mpi:16:"":16:"1230000000000000000":-1
+
+Test mbedtls_mpi_cmp_mpi: 0 (1 limb) < large positive
+mbedtls_mpi_cmp_mpi:16:"0":16:"1230000000000000000":-1
+
+Test mbedtls_mpi_cmp_mpi: 0 (null) > large negative
+mbedtls_mpi_cmp_mpi:16:"":16:"-1230000000000000000":1
+
+Test mbedtls_mpi_cmp_mpi: 0 (1 limb) > large negative
+mbedtls_mpi_cmp_mpi:16:"0":16:"-1230000000000000000":1
+
+Test mbedtls_mpi_cmp_mpi: large positive > 0 (null)
+mbedtls_mpi_cmp_mpi:16:"1230000000000000000":16:"":1
+
+Test mbedtls_mpi_cmp_mpi: large positive > 0 (1 limb)
+mbedtls_mpi_cmp_mpi:16:"1230000000000000000":16:"0":1
+
+Test mbedtls_mpi_cmp_mpi: large negative < 0 (null)
+mbedtls_mpi_cmp_mpi:16:"-1230000000000000000":16:"":-1
+
+Test mbedtls_mpi_cmp_mpi: large negative < 0 (1 limb)
+mbedtls_mpi_cmp_mpi:16:"-1230000000000000000":16:"0":-1
+
 Base test mbedtls_mpi_lt_mpi_ct #1
 mbedtls_mpi_lt_mpi_ct:1:"2B5":1:"2B5":0:0
 
@@ -196,6 +313,9 @@
 Base test mbedtls_mpi_lt_mpi_ct (Y is longer in storage)
 mbedtls_mpi_lt_mpi_ct:3:"2B5":4:"2B5":0:MBEDTLS_ERR_MPI_BAD_INPUT_DATA
 
+Base test mbedtls_mpi_lt_mpi_ct (length=0)
+mbedtls_mpi_lt_mpi_ct:0:"":0:"":0:0
+
 Base test mbedtls_mpi_lt_mpi_ct (corner case - 64 bit) #1
 mbedtls_mpi_lt_mpi_ct:2:"7FFFFFFFFFFFFFFF":2:"FF":0:0
 
@@ -268,7 +388,16 @@
 Base test mbedtls_mpi_cmp_abs (Negative values) #3
 mbedtls_mpi_cmp_abs:10:"-2":10:"-1":1
 
-Base test mbedtls_mpi_cmp_abs (Zero and Zero) #4
+Test mbedtls_mpi_cmp_abs: 0 (null) = 0 (null)
+mbedtls_mpi_cmp_abs:10:"":10:"":0
+
+Test mbedtls_mpi_cmp_abs: 0 (null) = 0 (1 limb)
+mbedtls_mpi_cmp_abs:10:"":10:"0":0
+
+Test mbedtls_mpi_cmp_abs: 0 (1 limb) = 0 (null)
+mbedtls_mpi_cmp_abs:10:"0":10:"":0
+
+Test mbedtls_mpi_cmp_abs: 0 (1 limb) = 0 (1 limb)
 mbedtls_mpi_cmp_abs:10:"0":10:"0":0
 
 Base test mbedtls_mpi_cmp_abs (Mix values) #1
@@ -280,84 +409,261 @@
 Base test mbedtls_mpi_cmp_abs (Mix values) #3
 mbedtls_mpi_cmp_abs:10:"-2":10:"1":1
 
-Copy zero (1 limb) to positive (1 limb)
-mbedtls_mpi_copy_sint:0:1500
+Copy large negative to large negative
+mbedtls_mpi_copy:"-ca5cadedb01dfaceacc01ade":"-face1e55ca11ab1ecab005e5"
 
-Copy zero (1 limb) to negative (1 limb)
-mbedtls_mpi_copy_sint:0:-1500
+Copy large negative to large positive
+mbedtls_mpi_copy:"-ca5cadedb01dfaceacc01ade":"face1e55ca11ab1ecab005e5"
 
-Copy positive (1 limb) to zero (1 limb)
-mbedtls_mpi_copy_sint:1500:0
+Copy large negative to small negative
+mbedtls_mpi_copy:"-ca5cadedb01dfaceacc01ade":"-beef"
 
-Copy negative (1 limb) to zero (1 limb)
-mbedtls_mpi_copy_sint:-1500:0
+Copy large negative to small positive
+mbedtls_mpi_copy:"-ca5cadedb01dfaceacc01ade":"beef"
 
-Copy positive (1 limb) to negative (1 limb)
-mbedtls_mpi_copy_sint:1500:-42
+Copy large negative to zero (1 limb)
+mbedtls_mpi_copy:"-ca5cadedb01dfaceacc01ade":"0"
 
-Copy negative (1 limb) to positive (1 limb)
-mbedtls_mpi_copy_sint:-42:1500
+Copy large negative to zero (null)
+mbedtls_mpi_copy:"-ca5cadedb01dfaceacc01ade":""
+
+Copy large positive to large negative
+mbedtls_mpi_copy:"ca5cadedb01dfaceacc01ade":"-face1e55ca11ab1ecab005e5"
+
+Copy large positive to large positive
+mbedtls_mpi_copy:"ca5cadedb01dfaceacc01ade":"face1e55ca11ab1ecab005e5"
+
+Copy large positive to small negative
+mbedtls_mpi_copy:"ca5cadedb01dfaceacc01ade":"-beef"
+
+Copy large positive to small positive
+mbedtls_mpi_copy:"ca5cadedb01dfaceacc01ade":"beef"
+
+Copy large positive to zero (1 limb)
+mbedtls_mpi_copy:"ca5cadedb01dfaceacc01ade":"0"
+
+Copy large positive to zero (null)
+mbedtls_mpi_copy:"ca5cadedb01dfaceacc01ade":""
+
+Copy small negative to large negative
+mbedtls_mpi_copy:"-bead":"-face1e55ca11ab1ecab005e5"
+
+Copy small negative to large positive
+mbedtls_mpi_copy:"-bead":"face1e55ca11ab1ecab005e5"
+
+Copy small negative to small negative
+mbedtls_mpi_copy:"-bead":"-beef"
+
+Copy small negative to small positive
+mbedtls_mpi_copy:"-bead":"beef"
+
+Copy small negative to zero (1 limb)
+mbedtls_mpi_copy:"-bead":"0"
+
+Copy small negative to zero (null)
+mbedtls_mpi_copy:"-bead":""
+
+Copy small positive to large negative
+mbedtls_mpi_copy:"bead":"-face1e55ca11ab1ecab005e5"
+
+Copy small positive to large positive
+mbedtls_mpi_copy:"bead":"face1e55ca11ab1ecab005e5"
+
+Copy small positive to small negative
+mbedtls_mpi_copy:"bead":"-beef"
+
+Copy small positive to small positive
+mbedtls_mpi_copy:"bead":"beef"
+
+Copy small positive to zero (1 limb)
+mbedtls_mpi_copy:"bead":"0"
+
+Copy small positive to zero (null)
+mbedtls_mpi_copy:"bead":""
+
+Copy zero (1 limb) to large negative
+mbedtls_mpi_copy:"0":"-face1e55ca11ab1ecab005e5"
+
+Copy zero (1 limb) to large positive
+mbedtls_mpi_copy:"0":"face1e55ca11ab1ecab005e5"
+
+Copy zero (1 limb) to small negative
+mbedtls_mpi_copy:"0":"-beef"
+
+Copy zero (1 limb) to small positive
+mbedtls_mpi_copy:"0":"beef"
+
+Copy zero (1 limb) to zero (1 limb)
+mbedtls_mpi_copy:"0":"0"
+
+Copy zero (1 limb) to zero (null)
+mbedtls_mpi_copy:"0":""
+
+Copy zero (null) to large negative
+mbedtls_mpi_copy:"":"-face1e55ca11ab1ecab005e5"
+
+Copy zero (null) to large positive
+mbedtls_mpi_copy:"":"face1e55ca11ab1ecab005e5"
+
+Copy zero (null) to small negative
+mbedtls_mpi_copy:"":"-beef"
+
+Copy zero (null) to small positive
+mbedtls_mpi_copy:"":"beef"
+
+Copy zero (null) to zero (1 limb)
+mbedtls_mpi_copy:"":"0"
 
 Copy zero (null) to zero (null)
-mbedtls_mpi_copy_binary:"":""
+mbedtls_mpi_copy:"":""
 
-Copy zero (null) to positive (1 limb)
-mbedtls_mpi_copy_binary:"":"1234"
+Copy self: large negative
+mpi_copy_self:"-ca5cadedb01dfaceacc01ade"
 
-Copy positive (1 limb) to zero (null)
-mbedtls_mpi_copy_binary:"1234":""
+Copy self: large positive
+mpi_copy_self:"ca5cadedb01dfaceacc01ade"
 
-Copy positive to larger
-mbedtls_mpi_copy_binary:"bead":"ca5cadedb01dfaceacc01ade"
+Copy self: small negative
+mpi_copy_self:"-bead"
 
-Copy positive to smaller
-mbedtls_mpi_copy_binary:"ca5cadedb01dfaceacc01ade":"bead"
-
-Copy self: positive (1 limb)
-mpi_copy_self:14
+Copy self: small positive
+mpi_copy_self:"bead"
 
 Copy self: zero (1 limb)
-mpi_copy_self:0
+mpi_copy_self:"0"
 
-Swap zero (1 limb) with positive (1 limb)
-mbedtls_mpi_swap_sint:0:1500
+Copy self: zero (null)
+mpi_copy_self:""
 
-Swap zero (1 limb) with negative (1 limb)
-mbedtls_mpi_swap_sint:0:-1500
+Swap large negative with large negative
+mbedtls_mpi_swap:"-ca5cadedb01dfaceacc01ade":"-face1e55ca11ab1ecab005e5"
 
-Swap positive (1 limb) with zero (1 limb)
-mbedtls_mpi_swap_sint:1500:0
+Swap large negative with large positive
+mbedtls_mpi_swap:"-ca5cadedb01dfaceacc01ade":"face1e55ca11ab1ecab005e5"
 
-Swap negative (1 limb) with zero (1 limb)
-mbedtls_mpi_swap_sint:-1500:0
+Swap large negative with small negative
+mbedtls_mpi_swap:"-ca5cadedb01dfaceacc01ade":"-beef"
 
-Swap positive (1 limb) with negative (1 limb)
-mbedtls_mpi_swap_sint:1500:-42
+Swap large negative with small positive
+mbedtls_mpi_swap:"-ca5cadedb01dfaceacc01ade":"beef"
 
-Swap negative (1 limb) with positive (1 limb)
-mbedtls_mpi_swap_sint:-42:1500
+Swap large negative with zero (1 limb)
+mbedtls_mpi_swap:"-ca5cadedb01dfaceacc01ade":"0"
+
+Swap large negative with zero (null)
+mbedtls_mpi_swap:"-ca5cadedb01dfaceacc01ade":""
+
+Swap large positive with large negative
+mbedtls_mpi_swap:"ca5cadedb01dfaceacc01ade":"-face1e55ca11ab1ecab005e5"
+
+Swap large positive with large positive
+mbedtls_mpi_swap:"ca5cadedb01dfaceacc01ade":"face1e55ca11ab1ecab005e5"
+
+Swap large positive with small negative
+mbedtls_mpi_swap:"ca5cadedb01dfaceacc01ade":"-beef"
+
+Swap large positive with small positive
+mbedtls_mpi_swap:"ca5cadedb01dfaceacc01ade":"beef"
+
+Swap large positive with zero (1 limb)
+mbedtls_mpi_swap:"ca5cadedb01dfaceacc01ade":"0"
+
+Swap large positive with zero (null)
+mbedtls_mpi_swap:"ca5cadedb01dfaceacc01ade":""
+
+Swap small negative with large negative
+mbedtls_mpi_swap:"-bead":"-face1e55ca11ab1ecab005e5"
+
+Swap small negative with large positive
+mbedtls_mpi_swap:"-bead":"face1e55ca11ab1ecab005e5"
+
+Swap small negative with small negative
+mbedtls_mpi_swap:"-bead":"-beef"
+
+Swap small negative with small positive
+mbedtls_mpi_swap:"-bead":"beef"
+
+Swap small negative with zero (1 limb)
+mbedtls_mpi_swap:"-bead":"0"
+
+Swap small negative with zero (null)
+mbedtls_mpi_swap:"-bead":""
+
+Swap small positive with large negative
+mbedtls_mpi_swap:"bead":"-face1e55ca11ab1ecab005e5"
+
+Swap small positive with large positive
+mbedtls_mpi_swap:"bead":"face1e55ca11ab1ecab005e5"
+
+Swap small positive with small negative
+mbedtls_mpi_swap:"bead":"-beef"
+
+Swap small positive with small positive
+mbedtls_mpi_swap:"bead":"beef"
+
+Swap small positive with zero (1 limb)
+mbedtls_mpi_swap:"bead":"0"
+
+Swap small positive with zero (null)
+mbedtls_mpi_swap:"bead":""
+
+Swap zero (1 limb) with large negative
+mbedtls_mpi_swap:"0":"-face1e55ca11ab1ecab005e5"
+
+Swap zero (1 limb) with large positive
+mbedtls_mpi_swap:"0":"face1e55ca11ab1ecab005e5"
+
+Swap zero (1 limb) with small negative
+mbedtls_mpi_swap:"0":"-beef"
+
+Swap zero (1 limb) with small positive
+mbedtls_mpi_swap:"0":"beef"
+
+Swap zero (1 limb) with zero (1 limb)
+mbedtls_mpi_swap:"0":"0"
+
+Swap zero (1 limb) with zero (null)
+mbedtls_mpi_swap:"0":""
+
+Swap zero (null) with large negative
+mbedtls_mpi_swap:"":"-face1e55ca11ab1ecab005e5"
+
+Swap zero (null) with large positive
+mbedtls_mpi_swap:"":"face1e55ca11ab1ecab005e5"
+
+Swap zero (null) with small negative
+mbedtls_mpi_swap:"":"-beef"
+
+Swap zero (null) with small positive
+mbedtls_mpi_swap:"":"beef"
+
+Swap zero (null) with zero (1 limb)
+mbedtls_mpi_swap:"":"0"
 
 Swap zero (null) with zero (null)
-mbedtls_mpi_swap_binary:"":""
+mbedtls_mpi_swap:"":""
 
-Swap zero (null) with positive (1 limb)
-mbedtls_mpi_swap_binary:"":"1234"
+Swap self: large negative
+mpi_swap_self:"-ca5cadedb01dfaceacc01ade"
 
-Swap positive (1 limb) with zero (null)
-mbedtls_mpi_swap_binary:"1234":""
+Swap self: large positive
+mpi_swap_self:"ca5cadedb01dfaceacc01ade"
 
-Swap positive with larger
-mbedtls_mpi_swap_binary:"bead":"ca5cadedb01dfaceacc01ade"
+Swap self: small negative
+mpi_swap_self:"-bead"
 
-Swap positive with smaller
-mbedtls_mpi_swap_binary:"ca5cadedb01dfaceacc01ade":"bead"
+Swap self: small positive
+mpi_swap_self:"bead"
 
-Swap self: 1 limb
-mpi_swap_self:"face"
+Swap self: zero (1 limb)
+mpi_swap_self:"0"
 
-Swap self: null
+Swap self: zero (null)
 mpi_swap_self:""
 
+Shrink 0 limbs in a buffer of size 0 to 0
+mbedtls_mpi_shrink:0:0:0:0
+
 Shrink 2 limbs in a buffer of size 2 to 4
 mbedtls_mpi_shrink:2:2:4:4
 
@@ -382,42 +688,6 @@
 Shrink 0 limbs in a buffer of size 4 to 0 yielding 1
 mbedtls_mpi_shrink:4:0:0:1
 
-Test mbedtls_mpi_safe_cond_assign #1
-mbedtls_mpi_safe_cond_assign:+1:"01":+1:"02"
-
-Test mbedtls_mpi_safe_cond_assign #2
-mbedtls_mpi_safe_cond_assign:+1:"FF000000000000000001":+1:"02"
-
-Test mbedtls_mpi_safe_cond_assign #3
-mbedtls_mpi_safe_cond_assign:+1:"01":+1:"FF000000000000000002"
-
-Test mbedtls_mpi_safe_cond_assign #4
-mbedtls_mpi_safe_cond_assign:+1:"01":-1:"02"
-
-Test mbedtls_mpi_safe_cond_assign #5
-mbedtls_mpi_safe_cond_assign:-1:"01":+1:"02"
-
-Test mbedtls_mpi_safe_cond_assign #6
-mbedtls_mpi_safe_cond_assign:-1:"01":-1:"02"
-
-Test mbedtls_mpi_safe_cond_swap #1
-mbedtls_mpi_safe_cond_swap:+1:"01":+1:"02"
-
-Test mbedtls_mpi_safe_cond_swap #2
-mbedtls_mpi_safe_cond_swap:+1:"FF000000000000000001":+1:"02"
-
-Test mbedtls_mpi_safe_cond_swap #3
-mbedtls_mpi_safe_cond_swap:+1:"01":+1:"FF000000000000000002"
-
-Test mbedtls_mpi_safe_cond_swap #4
-mbedtls_mpi_safe_cond_swap:+1:"01":-1:"02"
-
-Test mbedtls_mpi_safe_cond_swap #5
-mbedtls_mpi_safe_cond_swap:-1:"01":+1:"02"
-
-Test mbedtls_mpi_safe_cond_swap #6
-mbedtls_mpi_safe_cond_swap:-1:"01":-1:"02"
-
 Base test mbedtls_mpi_add_abs #1
 mbedtls_mpi_add_abs:10:"12345678":10:"642531":10:"12988209"
 
@@ -430,6 +700,15 @@
 Base test mbedtls_mpi_add_abs #4
 mbedtls_mpi_add_abs:10:"-12345678":10:"-642531":10:"12988209"
 
+Test mbedtls_mpi_add_abs: 0 (null) + 0 (null)
+mbedtls_mpi_add_abs:16:"":16:"":16:"0"
+
+Test mbedtls_mpi_add_abs: 0 (null) + 1
+mbedtls_mpi_add_abs:16:"":16:"01":16:"01"
+
+Test mbedtls_mpi_add_abs: 1 + 0 (null)
+mbedtls_mpi_add_abs:16:"01":16:"":16:"01"
+
 Test mbedtls_mpi_add_abs #1
 mbedtls_mpi_add_abs:10:"-643808006803554439230129854961492699151386107534013432918073439524138264842370630061369715394739134090922937332590384720397133335969549256322620979036686633213903952966175107096769180017646161851573147596390153":10:"56125680981752282333498088313568935051383833838594899821664631784577337171193624243181360054669678410455329112434552942717084003541384594864129940145043086760031292483340068923506115878221189886491132772739661669044958531131327771":10:"56125680981752282334141896320372489490613963693556392520816017892111350604111697682705498319512049040516698827829292076808006940873974979584527073481012636016353913462376755556720019831187364993587901952757307830896531678727717924"
 
@@ -451,6 +730,21 @@
 Base test mbedtls_mpi_add_mpi #4
 mbedtls_mpi_add_mpi:10:"-12345678":10:"-642531":10:"-12988209"
 
+Test mbedtls_mpi_add_mpi: 0 (null) + 0 (null)
+mbedtls_mpi_add_mpi:16:"":16:"":16:"0"
+
+Test mbedtls_mpi_add_mpi: 0 (null) + 1
+mbedtls_mpi_add_mpi:16:"":16:"01":16:"01"
+
+Test mbedtls_mpi_add_mpi: 1 + 0 (null)
+mbedtls_mpi_add_mpi:16:"01":16:"":16:"01"
+
+Test mbedtls_mpi_add_mpi: 0 (null) + -1
+mbedtls_mpi_add_mpi:16:"":16:"-01":16:"-01"
+
+Test mbedtls_mpi_add_mpi: -1 + 0 (null)
+mbedtls_mpi_add_mpi:16:"-01":16:"":16:"-01"
+
 Test mbedtls_mpi_add_mpi #1
 mbedtls_mpi_add_mpi:10:"203956878356401977405765866929034577280193993314348263094772646453283062722701277632936616063144088173312372882677123879538709400158306567338328279154499698366071906766440037074217117805690872792848149112022286332144876183376326512083574821647933992961249917319836219304274280243803104015000563790123":10:"531872289054204184185084734375133399408303613982130856645299464930952178606045848877129147820387996428175564228204785846141207532462936339834139412401975338705794646595487324365194792822189473092273993580587964571659678084484152603881094176995594813302284232006001752128168901293560051833646881436219":10:"735829167410606161590850601304167976688497607296479119740072111384235241328747126510065763883532084601487937110881909725679916932621242907172467691556475037071866553361927361439411910627880345885122142692610250903804554267860479115964668998643528806263534149325837971432443181537363155848647445226342"
 
@@ -472,18 +766,36 @@
 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)
+Test mbedtls_mpi_add_int: 0 (null) + 0
+mbedtls_mpi_add_int:16:"":0:16:"0"
+
+Test mbedtls_mpi_add_int: 0 (null) + 1
+mbedtls_mpi_add_int:16:"":1:16:"1"
+
+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
 
@@ -496,6 +808,24 @@
 Base test mbedtls_mpi_sub_abs #4
 mbedtls_mpi_sub_abs:10:"7":10:"-5":10:"2":0
 
+Test mbedtls_mpi_sub_abs: 0 (null) - 0 (null)
+mbedtls_mpi_sub_abs:16:"":16:"":16:"":0
+
+Test mbedtls_mpi_sub_abs: 0 (null) - 0 (1 limb)
+mbedtls_mpi_sub_abs:16:"":16:"00":16:"":0
+
+Test mbedtls_mpi_sub_abs: 0 (1 limb) - 0 (null)
+mbedtls_mpi_sub_abs:16:"00":16:"":16:"":0
+
+Test mbedtls_mpi_sub_abs: 0 (1 limb) - 0 (1 limb)
+mbedtls_mpi_sub_abs:16:"00":16:"00":16:"":0
+
+Test mbedtls_mpi_sub_abs: 1 - 0 (null)
+mbedtls_mpi_sub_abs:16:"01":16:"":16:"01":0
+
+Test mbedtls_mpi_sub_abs: 0 (null) - 1
+mbedtls_mpi_sub_abs:16:"":16:"01":16:"":MBEDTLS_ERR_MPI_NEGATIVE_VALUE
+
 Test mbedtls_mpi_sub_abs #1
 mbedtls_mpi_sub_abs:16:"FFFFFFFFFF":16:"01":16:"FFFFFFFFFE":0
 
@@ -520,6 +850,27 @@
 Base test mbedtls_mpi_sub_mpi #4 (Test with negative subtraction)
 mbedtls_mpi_sub_mpi:10:"5":10:"-7":10:"12"
 
+Test mbedtls_mpi_sub_mpi: 0 (null) - 0 (null)
+mbedtls_mpi_sub_mpi:16:"":16:"":16:"0"
+
+Test mbedtls_mpi_sub_mpi: 0 (null) - 0 (1 limb)
+mbedtls_mpi_sub_mpi:16:"":16:"00":16:"0"
+
+Test mbedtls_mpi_sub_mpi: 0 (null) - 1
+mbedtls_mpi_sub_mpi:16:"":16:"1":16:"-1"
+
+Test mbedtls_mpi_sub_mpi: 0 (null) - -1
+mbedtls_mpi_sub_mpi:16:"":16:"-1":16:"1"
+
+Test mbedtls_mpi_sub_mpi: 0 (1 limb) - 0 (null)
+mbedtls_mpi_sub_mpi:16:"00":16:"":16:"0"
+
+Test mbedtls_mpi_sub_mpi: 1 - 0 (null)
+mbedtls_mpi_sub_mpi:16:"1":16:"":16:"1"
+
+Test mbedtls_mpi_sub_mpi: -1 - 0 (null)
+mbedtls_mpi_sub_mpi:16:"-1":16:"":16:"-1"
+
 Test mbedtls_mpi_sub_mpi #1
 mbedtls_mpi_sub_mpi:10:"531872289054204184185084734375133399408303613982130856645299464930952178606045848877129147820387996428175564228204785846141207532462936339834139412401975338705794646595487324365194792822189473092273993580587964571659678084484152603881094176995594813302284232006001752128168901293560051833646881436219":10:"203956878356401977405765866929034577280193993314348263094772646453283062722701277632936616063144088173312372882677123879538709400158306567338328279154499698366071906766440037074217117805690872792848149112022286332144876183376326512083574821647933992961249917319836219304274280243803104015000563790123":10:"327915410697802206779318867446098822128109620667782593550526818477669115883344571244192531757243908254863191345527661966602498132304629772495811133247475640339722739829047287290977675016498600299425844468565678239514801901107826091797519355347660820341034314686165532823894621049756947818646317646096"
 
@@ -532,12 +883,30 @@
 Test mbedtls_mpi_sub_int #2
 mbedtls_mpi_sub_int:10:"2039568783564019774057658669290345772801939933143482630947726464532830627227012776329":9871232:10:"2039568783564019774057658669290345772801939933143482630947726464532830627227002905097"
 
+Test mbedtls_mpi_sub_int: 0 (null) - 0
+mbedtls_mpi_sub_int:16:"":0:16:"0"
+
+Test mbedtls_mpi_sub_int: 0 (null) - 1
+mbedtls_mpi_sub_int:16:"":1:16:"-1"
+
+Test mbedtls_mpi_sub_int: 0 (null) - -1
+mbedtls_mpi_sub_int:16:"":-1:16:"1"
+
 Test mbedtls_mpi_shift_l #1
 mbedtls_mpi_shift_l:10:"64":1:10:"128"
 
 Test mbedtls_mpi_shift_l #2
 mbedtls_mpi_shift_l:10:"658385546911733550164516088405238961461880256029834598831972039469421755117818013653494814438931957316403111689187691446941406788869098983929874080332195117465344344350008880118042764943201875870917468833709791733282363323948005998269792207":37:10:"90487820548639020691922304619723076305400961610119884872723190678642804168382367856686134531865643066983017249846286450251272364365605022750900439437595355052945035915579216557330505438734955340526145476988250171181404966718289259743378883640981192704"
 
+Test mbedtls_mpi_shift_l: 0 (null) <<= 0
+mbedtls_mpi_shift_l:16:"":0:16:"0"
+
+Test mbedtls_mpi_shift_l: 0 (null) <<= 1
+mbedtls_mpi_shift_l:16:"":1:16:"0"
+
+Test mbedtls_mpi_shift_l: 0 (null) <<= 64
+mbedtls_mpi_shift_l:16:"":64:16:"0"
+
 Test mbedtls_mpi_shift_r #1
 mbedtls_mpi_shift_r:10:"128":1:10:"64"
 
@@ -556,6 +925,15 @@
 Test mbedtls_mpi_shift_r #7
 mbedtls_mpi_shift_r:16:"FFFFFFFFFFFFFFFF":128:16:"00"
 
+Test mbedtls_mpi_shift_r: 0 (null) >>= 0
+mbedtls_mpi_shift_r:16:"":0:16:"0"
+
+Test mbedtls_mpi_shift_r: 0 (null) >>= 1
+mbedtls_mpi_shift_r:16:"":1:16:"0"
+
+Test mbedtls_mpi_shift_r: 0 (null) >>= 64
+mbedtls_mpi_shift_r:16:"":64:16:"0"
+
 Base test mbedtls_mpi_mul_mpi #1
 mbedtls_mpi_mul_mpi:10:"5":10:"7":10:"35"
 
@@ -568,8 +946,131 @@
 Base test mbedtls_mpi_mul_mpi #4
 mbedtls_mpi_mul_mpi:10:"-5":10:"-7":10:"35"
 
+Test mbedtls_mpi_mul_mpi: 0 (null) * 0 (null)
+mbedtls_mpi_mul_mpi:16:"":16:"":16:"0"
+
+Test mbedtls_mpi_mul_mpi: 0 (null) * 0 (1 limb)
+mbedtls_mpi_mul_mpi:16:"":16:"00":16:"0"
+
+Test mbedtls_mpi_mul_mpi: 0 (null) * 1
+mbedtls_mpi_mul_mpi:16:"":16:"01":16:"0"
+
+Test mbedtls_mpi_mul_mpi: 0 (null) * -1
+mbedtls_mpi_mul_mpi:16:"":16:"-01":16:"0"
+
+Test mbedtls_mpi_mul_mpi: 0 (1 limb) * -1
+mbedtls_mpi_mul_mpi:16:"00":16:"-01":16:"0"
+
+Test mbedtls_mpi_mul_mpi: 0 (1 limb) * 0 (null)
+mbedtls_mpi_mul_mpi:16:"00":16:"":16:"0"
+
+Test mbedtls_mpi_mul_mpi: 1 * 0 (null)
+mbedtls_mpi_mul_mpi:16:"01":16:"":16:"0"
+
+Test mbedtls_mpi_mul_mpi: -1 * 0 (null)
+mbedtls_mpi_mul_mpi:16:"-01":16:"":16:"0"
+
+Test mbedtls_mpi_mul_mpi: -1 * 0 (1 limb)
+mbedtls_mpi_mul_mpi:16:"-01":16:"00":16:"0"
+
 Test mbedtls_mpi_mul_mpi #1
-mbedtls_mpi_mul_mpi:10:"28911710017320205966167820725313234361535259163045867986277478145081076845846493521348693253530011243988160148063424837895971948244167867236923919506962312185829914482993478947657472351461336729641485069323635424692930278888923450060546465883490944265147851036817433970984747733020522259537":10:"16471581891701794764704009719057349996270239948993452268812975037240586099924712715366967486587417803753916334331355573776945238871512026832810626226164346328807407669366029926221415383560814338828449642265377822759768011406757061063524768140567867350208554439342320410551341675119078050953":10:"476221599179424887669515829231223263939342135681791605842540429321038144633323941248706405375723482912535192363845116154236465184147599697841273424891410002781967962186252583311115708128167171262206919514587899883547279647025952837516324649656913580411611297312678955801899536937577476819667861053063432906071315727948826276092545739432005962781562403795455162483159362585281248265005441715080197800335757871588045959754547836825977169125866324128449699877076762316768127816074587766799018626179199776188490087103869164122906791440101822594139648973454716256383294690817576188761"
+mbedtls_mpi_mul_mpi:16:"02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb59"
+
+Test mbedtls_mpi_mul_mpi #1, leading 0 limb in B
+mbedtls_mpi_mul_mpi:16:"02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"000000000000000001b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb59"
+
+Test mbedtls_mpi_mul_mpi #1, leading 0 limb in B, A < 0
+mbedtls_mpi_mul_mpi:16:"-02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"000000000000000001b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"-0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb59"
+
+Test mbedtls_mpi_mul_mpi #1, leading 0 limb in B, B < 0
+mbedtls_mpi_mul_mpi:16:"02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"-000000000000000001b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"-0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb59"
+
+Test mbedtls_mpi_mul_mpi #1, leading 0 limb in B, A < 0, B < 0
+mbedtls_mpi_mul_mpi:16:"-02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"-000000000000000001b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb59"
+
+Test mbedtls_mpi_mul_mpi #1, leading 0 limb in A
+mbedtls_mpi_mul_mpi:16:"000000000000000002f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb59"
+
+Test mbedtls_mpi_mul_mpi #1, leading 0 limb in A, A < 0
+mbedtls_mpi_mul_mpi:16:"-000000000000000002f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"-0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb59"
+
+Test mbedtls_mpi_mul_mpi #1, leading 0 limb in A, B < 0
+mbedtls_mpi_mul_mpi:16:"000000000000000002f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"-01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"-0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb59"
+
+Test mbedtls_mpi_mul_mpi #1, leading 0 limb in A, A < 0, B < 0
+mbedtls_mpi_mul_mpi:16:"-000000000000000002f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"-01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb59"
+
+Test mbedtls_mpi_mul_mpi #1, leading 0 limb in A and B
+mbedtls_mpi_mul_mpi:16:"000000000000000002f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"000000000000000001b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb59"
+
+Test mbedtls_mpi_mul_mpi #1, leading 0 limb in A and B, A < 0
+mbedtls_mpi_mul_mpi:16:"-000000000000000002f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"000000000000000001b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"-0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb59"
+
+Test mbedtls_mpi_mul_mpi #1, leading 0 limb in A and B, B < 0
+mbedtls_mpi_mul_mpi:16:"000000000000000002f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"-000000000000000001b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"-0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb59"
+
+Test mbedtls_mpi_mul_mpi #1, leading 0 limb in A and B, A < 0, B < 0
+mbedtls_mpi_mul_mpi:16:"-000000000000000002f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"-000000000000000001b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb59"
+
+Test mbedtls_mpi_mul_mpi #2, trailing 0 limb in A
+mbedtls_mpi_mul_mpi:16:"02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf24510000000000000000":16:"01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb590000000000000000"
+
+Test mbedtls_mpi_mul_mpi #2, trailing 0 limb in A, A < 0
+mbedtls_mpi_mul_mpi:16:"-02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf24510000000000000000":16:"01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"-0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb590000000000000000"
+
+Test mbedtls_mpi_mul_mpi #2, trailing 0 limb in A, B < 0
+mbedtls_mpi_mul_mpi:16:"02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf24510000000000000000":16:"-01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"-0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb590000000000000000"
+
+Test mbedtls_mpi_mul_mpi #2, trailing 0 limb in A, A < 0, B < 0
+mbedtls_mpi_mul_mpi:16:"-02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf24510000000000000000":16:"-01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb590000000000000000"
+
+Test mbedtls_mpi_mul_mpi #2, trailing 0 limb in B
+mbedtls_mpi_mul_mpi:16:"02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c890000000000000000":16:"0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb590000000000000000"
+
+Test mbedtls_mpi_mul_mpi #2, trailing 0 limb in B, A < 0
+mbedtls_mpi_mul_mpi:16:"-02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c890000000000000000":16:"-0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb590000000000000000"
+
+Test mbedtls_mpi_mul_mpi #2, trailing 0 limb in B, B < 0
+mbedtls_mpi_mul_mpi:16:"02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"-01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c890000000000000000":16:"-0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb590000000000000000"
+
+Test mbedtls_mpi_mul_mpi #2, trailing 0 limb in B, A < 0, B < 0
+mbedtls_mpi_mul_mpi:16:"-02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"-01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c890000000000000000":16:"0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb590000000000000000"
+
+Test mbedtls_mpi_mul_mpi #2, trailing 0 limb in A and B
+mbedtls_mpi_mul_mpi:16:"02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf24510000000000000000":16:"01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c890000000000000000":16:"0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb5900000000000000000000000000000000"
+
+Test mbedtls_mpi_mul_mpi #2, trailing 0 limb in A and B, A < 0
+mbedtls_mpi_mul_mpi:16:"-02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf24510000000000000000":16:"01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c890000000000000000":16:"-0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb5900000000000000000000000000000000"
+
+Test mbedtls_mpi_mul_mpi #2, trailing 0 limb in A and B, B < 0
+mbedtls_mpi_mul_mpi:16:"02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf24510000000000000000":16:"-01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c890000000000000000":16:"-0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb5900000000000000000000000000000000"
+
+Test mbedtls_mpi_mul_mpi #2, trailing 0 limb in A and B, A < 0, B < 0
+mbedtls_mpi_mul_mpi:16:"-02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf24510000000000000000":16:"-01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c890000000000000000":16:"0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb5900000000000000000000000000000000"
+
+Test mbedtls_mpi_mul_mpi #3, trailing 0 limbs in A
+mbedtls_mpi_mul_mpi:16:"02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf245100000000000000000000000000000000":16:"01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb5900000000000000000000000000000000"
+
+Test mbedtls_mpi_mul_mpi #3, trailing 0 limbs in A, A < 0
+mbedtls_mpi_mul_mpi:16:"-02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf245100000000000000000000000000000000":16:"01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"-0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb5900000000000000000000000000000000"
+
+Test mbedtls_mpi_mul_mpi #3, trailing 0 limbs in A, B < 0
+mbedtls_mpi_mul_mpi:16:"02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf245100000000000000000000000000000000":16:"-01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"-0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb5900000000000000000000000000000000"
+
+Test mbedtls_mpi_mul_mpi #3, trailing 0 limbs in A, A < 0, B < 0
+mbedtls_mpi_mul_mpi:16:"-02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf245100000000000000000000000000000000":16:"-01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c89":16:"0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb5900000000000000000000000000000000"
+
+Test mbedtls_mpi_mul_mpi #3, trailing 0 limbs in B
+mbedtls_mpi_mul_mpi:16:"02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c8900000000000000000000000000000000":16:"0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb5900000000000000000000000000000000"
+
+Test mbedtls_mpi_mul_mpi #3, trailing 0 limbs in B, A < 0
+mbedtls_mpi_mul_mpi:16:"-02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c8900000000000000000000000000000000":16:"-0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb5900000000000000000000000000000000"
+
+Test mbedtls_mpi_mul_mpi #3, trailing 0 limbs in B, B < 0
+mbedtls_mpi_mul_mpi:16:"02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"-01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c8900000000000000000000000000000000":16:"-0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb5900000000000000000000000000000000"
+
+Test mbedtls_mpi_mul_mpi #3, trailing 0 limbs in B, A < 0, B < 0
+mbedtls_mpi_mul_mpi:16:"-02f77b94b179d4a51360f04fa56e2c0784ce3b8a742280b016904896a5605fbe9e0f0683f82c439d979ab14e11b34e05ae96232b18fb2e0d1319f4942732d7eadf92ae90cb8c68ec8ece154d334f553564b6f6db185b33b8d3635598c3d128acde8bbb7b13697e48d1a542e5f9168d2d83a8dd05ae1eaf2451":16:"-01b0b14c432710cde936e3fc100515e95dca61e10b8a68d9632bfa0546a9731a1ce6bebc6cb5fe6f5fd7e57b25f737f6a0ce5402e216b8b81c06f0c5ccce447d7f5631d14bff9dfa16f7cc72c56c84b636d00a5f35199d17ee9bf3f8746f44374ffd4ae22cf84089f04a9f7f356d6dc9f8cf8ef208a9b88c8900000000000000000000000000000000":16:"0503ae899d35ae5b7706b067aed7cb2952da37a5d4ad58f05f69abe14e8aaae88eab2baed858177cb4595c0edc92e5ac13c2bba2bfa23276dd023e9e52f547d4c9edb138d86aad329d7afb01e15eab7281e181cb249fc91bf09d621d86561301edda156f80e3bbff853a312852fe9e3d0541cb86801390aff1dc3c05bcb592c266f625b70e419b4c7e7e85399bb06c0e50b099b4292f9eaff4d869681faa1f745b5fcb3349ed93c572739a31dcf76b43370cf9f86cc54e982dfac9467bde915c697e60554e0d698be6bb2dd1f8bc64659f6baee7641b51f4b5ed7010c04600fcd382db84a93fe3d4d86e86a459c6cebb5900000000000000000000000000000000"
 
 Test mbedtls_mpi_mul_int #1
 mbedtls_mpi_mul_int:10:"2039568783564019774057658669290345772801939933143482630947726464532830627227012776329":9871232:10:"20133056642518226042310730101376278483547239130123806338055387803943342738063359782107667328":"=="
@@ -583,15 +1084,45 @@
 Test mbedtls_mpi_mul_int #4 (Unsigned, thus failure)
 mbedtls_mpi_mul_int:10:"-2039568783564019774057658669290345772801939933143482630947726464532830627227012776329":-9871232:10:"20133056642518226042310730101376278483547239130123806338055387803943342738063359782107667328":"!="
 
+Test mbedtls_mpi_mul_int: 0 (null) * 0
+mbedtls_mpi_mul_int:16:"":0:16:"":"=="
+
+Test mbedtls_mpi_mul_int: 0 (null) * 1
+mbedtls_mpi_mul_int:16:"":1:16:"":"=="
+
+Test mbedtls_mpi_mul_int: 0 (null) * 0x1234
+mbedtls_mpi_mul_int:16:"":0x1234:16:"":"=="
+
 Base test mbedtls_mpi_div_mpi #1
 mbedtls_mpi_div_mpi:10:"1000":10:"13":10:"76":10:"12":0
 
-Base test mbedtls_mpi_div_mpi #2 (Divide by zero)
+Base test mbedtls_mpi_div_mpi #2 (Divide by zero (1 limb))
 mbedtls_mpi_div_mpi:10:"1000":10:"0":10:"1":10:"1":MBEDTLS_ERR_MPI_DIVISION_BY_ZERO
 
+Base test mbedtls_mpi_div_mpi #2 (Divide by zero (null))
+mbedtls_mpi_div_mpi:10:"1000":10:"":10:"1":10:"1":MBEDTLS_ERR_MPI_DIVISION_BY_ZERO
+
 Base test mbedtls_mpi_div_mpi #3
 mbedtls_mpi_div_mpi:10:"1000":10:"-13":10:"-76":10:"12":0
 
+Test mbedtls_mpi_div_mpi: 0 (null) / 0 (null)
+mbedtls_mpi_div_mpi:16:"":16:"":16:"":16:"":MBEDTLS_ERR_MPI_DIVISION_BY_ZERO
+
+Test mbedtls_mpi_div_mpi: 0 (null) / 0 (1 limb)
+mbedtls_mpi_div_mpi:16:"":16:"0":16:"":16:"":MBEDTLS_ERR_MPI_DIVISION_BY_ZERO
+
+Test mbedtls_mpi_div_mpi: 0 (1 limb) / 0 (null)
+mbedtls_mpi_div_mpi:16:"0":16:"":16:"":16:"":MBEDTLS_ERR_MPI_DIVISION_BY_ZERO
+
+Test mbedtls_mpi_div_mpi: 0 (1 limb) / 0 (1 limb)
+mbedtls_mpi_div_mpi:16:"0":16:"0":16:"":16:"":MBEDTLS_ERR_MPI_DIVISION_BY_ZERO
+
+Test mbedtls_mpi_div_mpi: 0 (null) / 1
+mbedtls_mpi_div_mpi:16:"":16:"1":16:"":16:"":0
+
+Test mbedtls_mpi_div_mpi: 0 (null) / -1
+mbedtls_mpi_div_mpi:16:"":16:"-1":16:"":16:"":0
+
 Test mbedtls_mpi_div_mpi #1
 mbedtls_mpi_div_mpi:10:"20133056642518226042310730101376278483547239130123806338055387803943342738063359782107667328":10:"34":10:"592148724779947824773845002981655249516095268533053127589864347174804198178334111238460803":10:"26":0
 
@@ -619,10 +1150,22 @@
 Test mbedtls_mpi_div_int #2
 mbedtls_mpi_div_int:10:"20133056642518226042310730101376278483547239130123806338055387803943342738063359782107667328":-34:10:"-592148724779947824773845002981655249516095268533053127589864347174804198178334111238460803":10:"26":0
 
+Test mbedtls_mpi_div_int: 0 (null) / 0
+mbedtls_mpi_div_int:16:"":0:16:"":16:"":MBEDTLS_ERR_MPI_DIVISION_BY_ZERO
+
+Test mbedtls_mpi_div_int: 0 (1 limb) / 0
+mbedtls_mpi_div_int:16:"00":0:16:"":16:"":MBEDTLS_ERR_MPI_DIVISION_BY_ZERO
+
+Test mbedtls_mpi_div_int: 0 (null) / 1
+mbedtls_mpi_div_int:16:"":1:16:"":16:"":0
+
 Base test mbedtls_mpi_mod_mpi #1
 mbedtls_mpi_mod_mpi:10:"1000":10:"13":10:"12":0
 
-Base test mbedtls_mpi_mod_mpi #2 (Divide by zero)
+Base test mbedtls_mpi_mod_mpi #2 (Divide by zero (null))
+mbedtls_mpi_mod_mpi:10:"1000":10:"":10:"0":MBEDTLS_ERR_MPI_DIVISION_BY_ZERO
+
+Base test mbedtls_mpi_mod_mpi #2 (Divide by zero (1 limb))
 mbedtls_mpi_mod_mpi:10:"1000":10:"0":10:"0":MBEDTLS_ERR_MPI_DIVISION_BY_ZERO
 
 Base test mbedtls_mpi_mod_mpi #3
@@ -634,6 +1177,12 @@
 Base test mbedtls_mpi_mod_mpi #5 (Negative modulo)
 mbedtls_mpi_mod_mpi:10:"-1000":10:"-13":10:"-12":MBEDTLS_ERR_MPI_NEGATIVE_VALUE
 
+Test mbedtls_mpi_mod_mpi: 0 (null) % 1
+mbedtls_mpi_mod_mpi:16:"":16:"1":16:"":0
+
+Test mbedtls_mpi_mod_mpi: 0 (null) % -1
+mbedtls_mpi_mod_mpi:16:"":16:"-1":16:"":MBEDTLS_ERR_MPI_NEGATIVE_VALUE
+
 Base test mbedtls_mpi_mod_int #1
 mbedtls_mpi_mod_int:10:"1000":13:12:0
 
@@ -658,23 +1207,74 @@
 Base test mbedtls_mpi_mod_int #8 (By 2)
 mbedtls_mpi_mod_int:10:"1000":2:0:0
 
+Test mbedtls_mpi_mod_int: 0 (null) % 1
+mbedtls_mpi_mod_int:16:"":1:0:0
+
+Test mbedtls_mpi_mod_int: 0 (null) % -1
+mbedtls_mpi_mod_int:16:"":-1:0:MBEDTLS_ERR_MPI_NEGATIVE_VALUE
+
 Base test mbedtls_mpi_exp_mod #1
-mbedtls_mpi_exp_mod:10:"23":10:"13":10:"29":10:"":10:"24":0
+mbedtls_mpi_exp_mod:10:"23":10:"13":10:"29":10:"24":0
 
 Base test mbedtls_mpi_exp_mod #2 (Even N)
-mbedtls_mpi_exp_mod:10:"23":10:"13":10:"30":10:"":10:"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+mbedtls_mpi_exp_mod:10:"23":10:"13":10:"30":10:"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
+Base test mbedtls_mpi_exp_mod #2 (N = 0 (null))
+mbedtls_mpi_exp_mod:10:"23":10:"13":10:"":10:"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
 
 Base test mbedtls_mpi_exp_mod #3 (Negative N)
-mbedtls_mpi_exp_mod:10:"23":10:"13":10:"-29":10:"":10:"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+mbedtls_mpi_exp_mod:10:"23":10:"13":10:"-29":10:"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
 
 Base test mbedtls_mpi_exp_mod #4 (Negative base)
-mbedtls_mpi_exp_mod:10:"-23":10:"13":10:"29":10:"":10:"5":0
+mbedtls_mpi_exp_mod:10:"-23":10:"13":10:"29":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
+mbedtls_mpi_exp_mod:10:"23":10:"-13":10:"29":10:"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
 
 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
+mbedtls_mpi_exp_mod:10:"-23":10:"-13":10:"29":10:"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
+Test mbedtls_mpi_exp_mod: 0 (null) ^ 0 (null) mod 9
+mbedtls_mpi_exp_mod:16:"":16:"":16:"09":16:"1":0
+
+Test mbedtls_mpi_exp_mod: 0 (null) ^ 0 (1 limb) mod 9
+mbedtls_mpi_exp_mod:16:"":16:"00":16:"09":16:"1":0
+
+Test mbedtls_mpi_exp_mod: 0 (null) ^ 1 mod 9
+mbedtls_mpi_exp_mod:16:"":16:"01":16:"09":16:"":0
+
+Test mbedtls_mpi_exp_mod: 0 (null) ^ 2 mod 9
+mbedtls_mpi_exp_mod:16:"":16:"02":16:"09":16:"":0
+
+Test mbedtls_mpi_exp_mod: 0 (1 limb) ^ 0 (null) mod 9
+mbedtls_mpi_exp_mod:16:"00":16:"":16:"09":16:"1":0
+
+Test mbedtls_mpi_exp_mod: 0 (1 limb) ^ 0 (1 limb) mod 9
+mbedtls_mpi_exp_mod:16:"00":16:"00":16:"09":16:"1":0
+
+Test mbedtls_mpi_exp_mod: 0 (1 limb) ^ 1 mod 9
+mbedtls_mpi_exp_mod:16:"00":16:"01":16:"09":16:"":0
+
+Test mbedtls_mpi_exp_mod: 0 (1 limb) ^ 2 mod 9
+mbedtls_mpi_exp_mod:16:"00":16:"02":16:"09":16:"":0
+
+Test mbedtls_mpi_exp_mod: 1 ^ 0 (null) mod 9
+mbedtls_mpi_exp_mod:16:"01":16:"":16:"09":16:"1":0
+
+Test mbedtls_mpi_exp_mod: 4 ^ 0 (null) mod 9
+mbedtls_mpi_exp_mod:16:"04":16:"":16:"09":16:"1":0
+
+Test mbedtls_mpi_exp_mod: 10 ^ 0 (null) mod 9
+mbedtls_mpi_exp_mod:16:"0a":16:"":16:"09":16:"1":0
+
+Test mbedtls_mpi_exp_mod: 1 ^ 0 (1 limb) mod 9
+mbedtls_mpi_exp_mod:16:"01":16:"00":16:"09":16:"1":0
+
+Test mbedtls_mpi_exp_mod: 4 ^ 0 (1 limb) mod 9
+mbedtls_mpi_exp_mod:16:"04":16:"00":16:"09":16:"1":0
+
+Test mbedtls_mpi_exp_mod: 10 ^ 0 (1 limb) mod 9
+mbedtls_mpi_exp_mod:16:"0a":16:"00":16:"09":16:"1":0
 
 Test mbedtls_mpi_exp_mod: MAX_SIZE exponent
 mbedtls_mpi_exp_mod_size:2:MBEDTLS_MPI_MAX_SIZE:10:10:"":0
@@ -696,14 +1296,14 @@
 
 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
+mbedtls_mpi_exp_mod:10:"433019240910377478217373572959560109819648647016096560523769010881172869083338285573756574557395862965095016483867813043663981946477698466501451832407592327356331263124555137732393938242285782144928753919588632679050799198937132922145084847":10:"5781538327977828897150909166778407659250458379645823062042492461576758526757490910073628008613977550546382774775570888130029763571528699574717583228939535960234464230882573615930384979100379102915657483866755371559811718767760594919456971354184113721":10:"583137007797276923956891216216022144052044091311388601652961409557516421612874571554415606746479105795833145583959622117418531166391184939066520869800857530421873250114773204354963864729386957427276448683092491947566992077136553066273207777134303397724679138833126700957":10:"114597449276684355144920670007147953232659436380163461553186940113929777196018164149703566472936578890991049344459204199888254907113495794730452699842273939581048142004834330369483813876618772578869083248061616444392091693787039636316845512292127097865026290173004860736":0
 
 Test mbedtls_mpi_exp_mod (Negative base)
-mbedtls_mpi_exp_mod:10:"-10000000000":10:"10000000000":10:"99999":10:"":10:"1":0
+mbedtls_mpi_exp_mod:10:"-10000000000":10:"10000000000":10:"99999":10:"1":0
 
 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
+mbedtls_mpi_exp_mod:16:"-9f13012cd92aa72fb86ac8879d2fde4f7fd661aaae43a00971f081cc60ca277059d5c37e89652e2af2585d281d66ef6a9d38a117e9608e9e7574cd142dc55278838a2161dd56db9470d4c1da2d5df15a908ee2eb886aaa890f23be16de59386663a12f1afbb325431a3e835e3fd89b98b96a6f77382f458ef9a37e1f84a03045c8676ab55291a94c2228ea15448ee96b626b998":16:"40a54d1b9e86789f06d9607fb158672d64867665c73ee9abb545fc7a785634b354c7bae5b962ce8040cf45f2c1f3d3659b2ee5ede17534c8fc2ec85c815e8df1fe7048d12c90ee31b88a68a081f17f0d8ce5f4030521e9400083bcea73a429031d4ca7949c2000d597088e0c39a6014d8bf962b73bb2e8083bd0390a4e00b9b3":16:"eeaf0ab9adb38dd69c33f80afa8fc5e86072618775ff3c0b9ea2314c9c256576d674df7496ea81d3383b4813d692c6e0e0d5d8e250b98be48e495c1d6089dad15dc7d7b46154d6b6ce8ef4ad69b15d4982559b297bcf1885c529f566660e57ec68edbc3c05726cc02fd4cbf4976eaa9afd5138fe8376435b9fc61d2fc0eb06e3":16:"21acc7199e1b90f9b4844ffe12c19f00ec548c5d32b21c647d48b6015d8eb9ec9db05b4f3d44db4227a2b5659c1a7cceb9d5fa8fa60376047953ce7397d90aaeb7465e14e820734f84aa52ad0fc66701bcbb991d57715806a11531268e1e83dd48288c72b424a6287e9ce4e5cc4db0dd67614aecc23b0124a5776d36e5c89483":0
 
 Base test GCD #1
 mbedtls_mpi_gcd:10:"693":10:"609":10:"21"
@@ -714,24 +1314,105 @@
 Base test GCD #3
 mbedtls_mpi_gcd:10:"768454923":10:"542167814":10:"1"
 
-Test GCD #1
+Test GCD: 0 (null), 0 (null)
+mbedtls_mpi_gcd:16:"":16:"":16:"0"
+
+Test GCD: 0 (null), 0 (1 limb)
+mbedtls_mpi_gcd:16:"":16:"00":16:"0"
+
+Test GCD: 0 (null), 3
+mbedtls_mpi_gcd:16:"":16:"03":16:"3"
+
+Test GCD: 0 (null), 6
+mbedtls_mpi_gcd:16:"":16:"06":16:"6"
+
+Test GCD: 0 (1 limb), 0 (null)
+mbedtls_mpi_gcd:16:"00":16:"":16:"0"
+
+Test GCD: 0 (1 limb), 3
+mbedtls_mpi_gcd:16:"00":16:"03":16:"3"
+
+Test GCD: 0 (1 limb), 6
+mbedtls_mpi_gcd:16:"00":16:"06":16:"6"
+
+Test GCD: 3, 0 (null)
+mbedtls_mpi_gcd:16:"03":16:"":16:"3"
+
+Test GCD: 3, 0 (1 limb)
+mbedtls_mpi_gcd:16:"03":16:"00":16:"3"
+
+Test GCD: 6, 0 (null)
+mbedtls_mpi_gcd:16:"06":16:"":16:"6"
+
+Test GCD: 6, 0 (1 limb)
+mbedtls_mpi_gcd:16:"06":16:"00":16:"6"
+
+Test GCD: gcd=1, 0 < A < B
 mbedtls_mpi_gcd:10:"433019240910377478217373572959560109819648647016096560523769010881172869083338285573756574557395862965095016483867813043663981946477698466501451832407592327356331263124555137732393938242285782144928753919588632679050799198937132922145084847":10:"5781538327977828897150909166778407659250458379645823062042492461576758526757490910073628008613977550546382774775570888130029763571528699574717583228939535960234464230882573615930384979100379102915657483866755371559811718767760594919456971354184113721":10:"1"
 
+Test GCD: gcd=1, 0 < B < A
+mbedtls_mpi_gcd:10:"5781538327977828897150909166778407659250458379645823062042492461576758526757490910073628008613977550546382774775570888130029763571528699574717583228939535960234464230882573615930384979100379102915657483866755371559811718767760594919456971354184113721":10:"433019240910377478217373572959560109819648647016096560523769010881172869083338285573756574557395862965095016483867813043663981946477698466501451832407592327356331263124555137732393938242285782144928753919588632679050799198937132922145084847":10:"1"
+
+Test GCD: gcd=1, A > 0, B < 0
+mbedtls_mpi_gcd:10:"433019240910377478217373572959560109819648647016096560523769010881172869083338285573756574557395862965095016483867813043663981946477698466501451832407592327356331263124555137732393938242285782144928753919588632679050799198937132922145084847":10:"-5781538327977828897150909166778407659250458379645823062042492461576758526757490910073628008613977550546382774775570888130029763571528699574717583228939535960234464230882573615930384979100379102915657483866755371559811718767760594919456971354184113721":10:"1"
+
+Test GCD: gcd=1, A < 0 < B, |A| < |B|
+mbedtls_mpi_gcd:10:"-433019240910377478217373572959560109819648647016096560523769010881172869083338285573756574557395862965095016483867813043663981946477698466501451832407592327356331263124555137732393938242285782144928753919588632679050799198937132922145084847":10:"5781538327977828897150909166778407659250458379645823062042492461576758526757490910073628008613977550546382774775570888130029763571528699574717583228939535960234464230882573615930384979100379102915657483866755371559811718767760594919456971354184113721":10:"1"
+
+Test GCD: gcd=1, B < A < 0
+mbedtls_mpi_gcd:10:"-433019240910377478217373572959560109819648647016096560523769010881172869083338285573756574557395862965095016483867813043663981946477698466501451832407592327356331263124555137732393938242285782144928753919588632679050799198937132922145084847":10:"-5781538327977828897150909166778407659250458379645823062042492461576758526757490910073628008613977550546382774775570888130029763571528699574717583228939535960234464230882573615930384979100379102915657483866755371559811718767760594919456971354184113721":10:"1"
+
+Test GCD: gcd=2, 0 < A < B
+mbedtls_mpi_gcd:10:"866038481820754956434747145919120219639297294032193121047538021762345738166676571147513149114791725930190032967735626087327963892955396933002903664815184654712662526249110275464787876484571564289857507839177265358101598397874265844290169694":10:"11563076655955657794301818333556815318500916759291646124084984923153517053514981820147256017227955101092765549551141776260059527143057399149435166457879071920468928461765147231860769958200758205831314967733510743119623437535521189838913942708368227442":10:"2"
+
+Test GCD: gcd=2, 0 < B < A
+mbedtls_mpi_gcd:10:"11563076655955657794301818333556815318500916759291646124084984923153517053514981820147256017227955101092765549551141776260059527143057399149435166457879071920468928461765147231860769958200758205831314967733510743119623437535521189838913942708368227442":10:"866038481820754956434747145919120219639297294032193121047538021762345738166676571147513149114791725930190032967735626087327963892955396933002903664815184654712662526249110275464787876484571564289857507839177265358101598397874265844290169694":10:"2"
+
+Test GCD: gcd=3, 0 < A < B
+mbedtls_mpi_gcd:10:"1299057722731132434652120718878680329458945941048289681571307032643518607250014856721269723672187588895285049451603439130991945839433095399504355497222776982068993789373665413197181814726857346434786261758765898037152397596811398766435254541":10:"17344614983933486691452727500335222977751375138937469186127477384730275580272472730220884025841932651639148324326712664390089290714586098724152749686818607880703392692647720847791154937301137308746972451600266114679435156303281784758370914062552341163":10:"3"
+
+Test GCD: gcd=3, 0 < B < A
+mbedtls_mpi_gcd:10:"17344614983933486691452727500335222977751375138937469186127477384730275580272472730220884025841932651639148324326712664390089290714586098724152749686818607880703392692647720847791154937301137308746972451600266114679435156303281784758370914062552341163":10:"1299057722731132434652120718878680329458945941048289681571307032643518607250014856721269723672187588895285049451603439130991945839433095399504355497222776982068993789373665413197181814726857346434786261758765898037152397596811398766435254541":10:"3"
+
+Test GCD: gcd=4, 0 < A < B
+mbedtls_mpi_gcd:10:"1732076963641509912869494291838240439278594588064386242095076043524691476333353142295026298229583451860380065935471252174655927785910793866005807329630369309425325052498220550929575752969143128579715015678354530716203196795748531688580339388":10:"23126153311911315588603636667113630637001833518583292248169969846307034107029963640294512034455910202185531099102283552520119054286114798298870332915758143840937856923530294463721539916401516411662629935467021486239246875071042379677827885416736454884":10:"4"
+
+Test GCD: gcd=4, 0 < B < A
+mbedtls_mpi_gcd:10:"23126153311911315588603636667113630637001833518583292248169969846307034107029963640294512034455910202185531099102283552520119054286114798298870332915758143840937856923530294463721539916401516411662629935467021486239246875071042379677827885416736454884":10:"1732076963641509912869494291838240439278594588064386242095076043524691476333353142295026298229583451860380065935471252174655927785910793866005807329630369309425325052498220550929575752969143128579715015678354530716203196795748531688580339388":10:"4"
+
+Test GCD: gcd=6, 0 < A < B
+mbedtls_mpi_gcd:10:"2598115445462264869304241437757360658917891882096579363142614065287037214500029713442539447344375177790570098903206878261983891678866190799008710994445553964137987578747330826394363629453714692869572523517531796074304795193622797532870509082":10:"34689229967866973382905455000670445955502750277874938372254954769460551160544945460441768051683865303278296648653425328780178581429172197448305499373637215761406785385295441695582309874602274617493944903200532229358870312606563569516741828125104682326":10:"6"
+
+Test GCD: gcd=6, 0 < B < A
+mbedtls_mpi_gcd:10:"34689229967866973382905455000670445955502750277874938372254954769460551160544945460441768051683865303278296648653425328780178581429172197448305499373637215761406785385295441695582309874602274617493944903200532229358870312606563569516741828125104682326":10:"2598115445462264869304241437757360658917891882096579363142614065287037214500029713442539447344375177790570098903206878261983891678866190799008710994445553964137987578747330826394363629453714692869572523517531796074304795193622797532870509082":10:"6"
+
+Test GCD: 0 < A = B
+mbedtls_mpi_gcd:10:"433019240910377478217373572959560109819648647016096560523769010881172869083338285573756574557395862965095016483867813043663981946477698466501451832407592327356331263124555137732393938242285782144928753919588632679050799198937132922145084847":10:"433019240910377478217373572959560109819648647016096560523769010881172869083338285573756574557395862965095016483867813043663981946477698466501451832407592327356331263124555137732393938242285782144928753919588632679050799198937132922145084847":10:"433019240910377478217373572959560109819648647016096560523769010881172869083338285573756574557395862965095016483867813043663981946477698466501451832407592327356331263124555137732393938242285782144928753919588632679050799198937132922145084847"
+
 Base test mbedtls_mpi_inv_mod #1
 mbedtls_mpi_inv_mod:10:"3":10:"11":10:"4":0
 
-Base test mbedtls_mpi_inv_mod #2
+Test mbedtls_mpi_inv_mod: mod 0 (null)
+mbedtls_mpi_inv_mod:10:"3":10:"":10:"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
+Test mbedtls_mpi_inv_mod: mod 0 (1 limb)
 mbedtls_mpi_inv_mod:10:"3":10:"0":10:"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
 
-Base test mbedtls_mpi_inv_mod #3
+Test mbedtls_mpi_inv_mod: mod negative
 mbedtls_mpi_inv_mod:10:"3":10:"-11":10:"4":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
 
-Base test mbedtls_mpi_inv_mod #4
+Test mbedtls_mpi_inv_mod: 2^-1 mod 4
 mbedtls_mpi_inv_mod:10:"2":10:"4":10:"0":MBEDTLS_ERR_MPI_NOT_ACCEPTABLE
 
-Base test mbedtls_mpi_inv_mod #5
+Test mbedtls_mpi_inv_mod: mod 1
 mbedtls_mpi_inv_mod:10:"3":10:"1":10:"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
 
+Test mbedtls_mpi_inv_mod: 0 (null) ^-1
+mbedtls_mpi_inv_mod:16:"":16:"11":16:"":MBEDTLS_ERR_MPI_NOT_ACCEPTABLE
+
+Test mbedtls_mpi_inv_mod: 0 (1 limb) ^-1
+mbedtls_mpi_inv_mod:16:"00":16:"11":16:"":MBEDTLS_ERR_MPI_NOT_ACCEPTABLE
+
 Test mbedtls_mpi_inv_mod #1
 mbedtls_mpi_inv_mod:16:"aa4df5cb14b4c31237f98bd1faf527c283c2d0f3eec89718664ba33f9762907c":16:"fffbbd660b94412ae61ead9c2906a344116e316a256fd387874c6c675b1d587d":16:"8d6a5c1d7adeae3e94b9bcd2c47e0d46e778bc8804a2cc25c02d775dc3d05b0c":0
 
@@ -916,6 +1597,9 @@
 Test bit getting (Larger and non-existing limb)
 mbedtls_mpi_get_bit:10:"49979687":500:0
 
+Test bit getting in 0 (null)
+mbedtls_mpi_get_bit:10:"":500:0
+
 Test bit getting (Value bit 24)
 mbedtls_mpi_get_bit:10:"49979687":24:0
 
@@ -934,6 +1618,12 @@
 Test bit set (Add above existing limbs with a 1)
 mbedtls_mpi_set_bit:10:"49979687":80:1:10:"1208925819614629224685863":0
 
+Test bit set (Add to 0 (null) with a 0)
+mbedtls_mpi_set_bit:16:"":65:0:16:"":0
+
+Test bit set (Add to 0 (null) with a 1)
+mbedtls_mpi_set_bit:16:"":65:1:16:"020000000000000000":0
+
 Test bit set (Bit index larger than 31 with a 0)
 mbedtls_mpi_set_bit:16:"FFFFFFFFFFFFFFFF":32:0:16:"FFFFFFFEFFFFFFFF":0
 
diff --git a/tests/suites/test_suite_mpi.function b/tests/suites/test_suite_mpi.function
index 2384d12..e3a0b46 100644
--- a/tests/suites/test_suite_mpi.function
+++ b/tests/suites/test_suite_mpi.function
@@ -6,6 +6,18 @@
 #define MPI_MAX_BITS_LARGER_THAN_792
 #endif
 
+/* Check the validity of the sign bit in an MPI object. Reject representations
+ * that are not supported by the rest of the library and indicate a bug when
+ * constructing the value. */
+static int sign_is_valid( const mbedtls_mpi *X )
+{
+    if( X->s != 1 && X->s != -1 )
+        return( 0 ); // invalid sign bit, e.g. 0
+    if( mbedtls_mpi_bitlen( X ) == 0 && X->s != 1 )
+        return( 0 ); // negative zero
+    return( 1 );
+}
+
 typedef struct mbedtls_test_mpi_random
 {
     data_t *data;
@@ -320,6 +332,7 @@
     TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == result_read );
     if( result_read == 0 )
     {
+        TEST_ASSERT( sign_is_valid( &X ) );
         TEST_ASSERT( mbedtls_mpi_write_string( &X, radix_A, str, output_size, &len ) == result_write );
         if( result_write == 0 )
         {
@@ -344,6 +357,7 @@
 
 
     TEST_ASSERT( mbedtls_mpi_read_binary( &X, buf->x, buf->len ) == 0 );
+    TEST_ASSERT( sign_is_valid( &X ) );
     TEST_ASSERT( mbedtls_mpi_write_string( &X, radix_A, (char *) str, sizeof( str ), &len ) == 0 );
     TEST_ASSERT( strcmp( (char *) str, input_A ) == 0 );
 
@@ -365,7 +379,7 @@
 
     mbedtls_mpi_init( &X );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
 
     buflen = mbedtls_mpi_size( &X );
     if( buflen > (size_t) output_size )
@@ -406,6 +420,7 @@
 
     if( result == 0 )
     {
+        TEST_ASSERT( sign_is_valid( &X ) );
         buflen = mbedtls_mpi_size( &X );
         TEST_ASSERT( mbedtls_mpi_write_binary( &X, buf, buflen ) == 0 );
 
@@ -429,7 +444,7 @@
 
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
 
     file_out = fopen( output_file, "w" );
     TEST_ASSERT( file_out != NULL );
@@ -455,7 +470,7 @@
 {
     mbedtls_mpi X;
     mbedtls_mpi_init( &X );
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
     TEST_ASSERT( mbedtls_mpi_get_bit( &X, pos ) == val );
 
 exit:
@@ -470,12 +485,13 @@
     mbedtls_mpi X, Y;
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Y, radix_Y, output_Y ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, output_Y ) == 0 );
     TEST_ASSERT( mbedtls_mpi_set_bit( &X, pos, val ) == result );
 
     if( result == 0 )
     {
+        TEST_ASSERT( sign_is_valid( &X ) );
         TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 );
     }
 
@@ -490,7 +506,7 @@
     mbedtls_mpi X;
     mbedtls_mpi_init( &X );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
     TEST_ASSERT( mbedtls_mpi_lsb( &X ) == (size_t) nr_bits );
 
 exit:
@@ -504,7 +520,7 @@
     mbedtls_mpi X;
     mbedtls_mpi_init( &X );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
     TEST_ASSERT( mbedtls_mpi_bitlen( &X ) == (size_t) nr_bits );
 
 exit:
@@ -519,10 +535,11 @@
     mbedtls_mpi A, X, Y, Z;
     mbedtls_mpi_init( &A ); mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z );
 
-    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 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
     TEST_ASSERT( mbedtls_mpi_gcd( &Z, &X, &Y ) == 0 );
+    TEST_ASSERT( sign_is_valid( &Z ) );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
 
 exit:
@@ -551,8 +568,8 @@
     mbedtls_mpi X, Y;
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
 
-    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_test_read_mpi( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == input_A );
 
 exit:
@@ -570,8 +587,8 @@
     mbedtls_mpi X, Y;
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, 16, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Y, 16, input_Y ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, 16, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y, 16, input_Y ) == 0 );
 
     TEST_ASSERT( mbedtls_mpi_grow( &X, size_X ) == 0 );
     TEST_ASSERT( mbedtls_mpi_grow( &Y, size_Y ) == 0 );
@@ -592,8 +609,8 @@
     mbedtls_mpi X, Y;
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
 
-    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_test_read_mpi( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
     TEST_ASSERT( mbedtls_mpi_cmp_abs( &X, &Y ) == input_A );
 
 exit:
@@ -602,55 +619,125 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void mbedtls_mpi_copy_sint( int input_X, int input_Y )
+void mbedtls_mpi_copy( char *src_hex, char *dst_hex )
 {
-    mbedtls_mpi X, Y;
+    mbedtls_mpi src, dst, ref;
+    mbedtls_mpi_init( &src );
+    mbedtls_mpi_init( &dst );
+    mbedtls_mpi_init( &ref );
+
+    TEST_ASSERT( mbedtls_test_read_mpi( &src, 16, src_hex ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &ref, 16, dst_hex ) == 0 );
+
+    /* mbedtls_mpi_copy() */
+    TEST_ASSERT( mbedtls_test_read_mpi( &dst, 16, dst_hex ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_copy( &dst, &src ) == 0 );
+    TEST_ASSERT( sign_is_valid( &dst ) );
+    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &src ) == 0 );
+
+    /* mbedtls_mpi_safe_cond_assign(), assignment done */
+    mbedtls_mpi_free( &dst );
+    TEST_ASSERT( mbedtls_test_read_mpi( &dst, 16, dst_hex ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &dst, &src, 1 ) == 0 );
+    TEST_ASSERT( sign_is_valid( &dst ) );
+    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &src ) == 0 );
+
+    /* mbedtls_mpi_safe_cond_assign(), assignment not done */
+    mbedtls_mpi_free( &dst );
+    TEST_ASSERT( mbedtls_test_read_mpi( &dst, 16, dst_hex ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &dst, &src, 0 ) == 0 );
+    TEST_ASSERT( sign_is_valid( &dst ) );
+    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &ref ) == 0 );
+
+exit:
+    mbedtls_mpi_free( &src );
+    mbedtls_mpi_free( &dst );
+    mbedtls_mpi_free( &ref );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void mpi_copy_self( char *input_X )
+{
+    mbedtls_mpi X, A;
+    mbedtls_mpi_init( &A );
+    mbedtls_mpi_init( &X );
+
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, 16, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_copy( &X, &X ) == 0 );
+
+    TEST_ASSERT( mbedtls_test_read_mpi( &A, 16, input_X ) == 0 );
+    TEST_ASSERT( sign_is_valid( &X ) );
+    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
+
+exit:
+    mbedtls_mpi_free( &A );
+    mbedtls_mpi_free( &X );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void mbedtls_mpi_swap( char *X_hex, char *Y_hex )
+{
+    mbedtls_mpi X, Y, X0, Y0;
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
+    mbedtls_mpi_init( &X0 ); mbedtls_mpi_init( &Y0 );
 
-    TEST_ASSERT( mbedtls_mpi_lset( &X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_lset( &Y, input_Y ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X0, 16, X_hex ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y0, 16, Y_hex ) == 0 );
 
-    TEST_ASSERT( mbedtls_mpi_copy( &Y, &X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_int( &X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_int( &Y, input_X ) == 0 );
+    /* mbedtls_mpi_swap() */
+    TEST_ASSERT( mbedtls_test_read_mpi( &X,  16, X_hex ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y,  16, Y_hex ) == 0 );
+    mbedtls_mpi_swap( &X, &Y );
+    TEST_ASSERT( sign_is_valid( &X ) );
+    TEST_ASSERT( sign_is_valid( &Y ) );
+    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
+
+    /* mbedtls_mpi_safe_cond_swap(), swap done */
+    mbedtls_mpi_free( &X );
+    mbedtls_mpi_free( &Y );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X,  16, X_hex ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y,  16, Y_hex ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 1 ) == 0 );
+    TEST_ASSERT( sign_is_valid( &X ) );
+    TEST_ASSERT( sign_is_valid( &Y ) );
+    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
+
+    /* mbedtls_mpi_safe_cond_swap(), swap not done */
+    mbedtls_mpi_free( &X );
+    mbedtls_mpi_free( &Y );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X,  16, X_hex ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y,  16, Y_hex ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 0 ) == 0 );
+    TEST_ASSERT( sign_is_valid( &X ) );
+    TEST_ASSERT( sign_is_valid( &Y ) );
+    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
+    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &Y0 ) == 0 );
 
 exit:
     mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
+    mbedtls_mpi_free( &X0 ); mbedtls_mpi_free( &Y0 );
 }
 /* END_CASE */
 
 /* BEGIN_CASE */
-void mbedtls_mpi_copy_binary( data_t *input_X, data_t *input_Y )
+void mpi_swap_self( char *X_hex )
 {
-    mbedtls_mpi X, Y, X0;
-    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &X0 );
+    mbedtls_mpi X, X0;
+    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &X0 );
 
-    TEST_ASSERT( mbedtls_mpi_read_binary( &X, input_X->x, input_X->len ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_binary( &Y, input_Y->x, input_Y->len ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_binary( &X0, input_X->x, input_X->len ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X,  16, X_hex ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X0, 16, X_hex ) == 0 );
+
+    mbedtls_mpi_swap( &X, &X );
+    TEST_ASSERT( sign_is_valid( &X ) );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
 
-    TEST_ASSERT( mbedtls_mpi_copy( &Y, &X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
-
 exit:
-    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &X0 );
-}
-/* END_CASE */
-
-/* BEGIN_CASE */
-void mpi_copy_self( int input_X )
-{
-    mbedtls_mpi X;
-    mbedtls_mpi_init( &X );
-
-    TEST_ASSERT( mbedtls_mpi_lset( &X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_copy( &X, &X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_int( &X, input_X ) == 0 );
-
-exit:
-    mbedtls_mpi_free( &X );
+    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &X0 );
 }
 /* END_CASE */
 
@@ -661,10 +748,14 @@
     mbedtls_mpi_init( &X );
 
     TEST_ASSERT( mbedtls_mpi_grow( &X, before ) == 0 );
-    TEST_ASSERT( used <= before );
-    memset( X.p, 0x2a, used * sizeof( mbedtls_mpi_uint ) );
+    if( used > 0 )
+    {
+        size_t used_bit_count = used * 8 * sizeof( mbedtls_mpi_uint );
+        TEST_ASSERT( mbedtls_mpi_set_bit( &X, used_bit_count - 1, 1 ) == 0 );
+    }
+    TEST_EQUAL( X.n, (size_t) before );
     TEST_ASSERT( mbedtls_mpi_shrink( &X, min ) == 0 );
-    TEST_ASSERT( X.n == (size_t) after );
+    TEST_EQUAL( X.n, (size_t) after );
 
 exit:
     mbedtls_mpi_free( &X );
@@ -672,139 +763,28 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void mbedtls_mpi_safe_cond_assign( int x_sign, char * x_str, int y_sign,
-                                   char * y_str )
-{
-    mbedtls_mpi X, Y, XX;
-    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &XX );
-
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, 16, x_str ) == 0 );
-    X.s = x_sign;
-    TEST_ASSERT( mbedtls_mpi_read_string( &Y, 16, y_str ) == 0 );
-    Y.s = y_sign;
-    TEST_ASSERT( mbedtls_mpi_copy( &XX, &X ) == 0 );
-
-    TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &X, &Y, 0 ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &XX ) == 0 );
-
-    TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &X, &Y, 1 ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 );
-
-exit:
-    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &XX );
-}
-/* END_CASE */
-
-/* BEGIN_CASE */
-void mbedtls_mpi_safe_cond_swap( int x_sign, char * x_str, int y_sign,
-                                 char * y_str )
-{
-    mbedtls_mpi X, Y, XX, YY;
-
-    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
-    mbedtls_mpi_init( &XX ); mbedtls_mpi_init( &YY );
-
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, 16, x_str ) == 0 );
-    X.s = x_sign;
-    TEST_ASSERT( mbedtls_mpi_read_string( &Y, 16, y_str ) == 0 );
-    Y.s = y_sign;
-
-    TEST_ASSERT( mbedtls_mpi_copy( &XX, &X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_copy( &YY, &Y ) == 0 );
-
-    TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 0 ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &XX ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &YY ) == 0 );
-
-    TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 1 ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &XX ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &YY ) == 0 );
-
-exit:
-    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
-    mbedtls_mpi_free( &XX ); mbedtls_mpi_free( &YY );
-}
-/* END_CASE */
-
-/* BEGIN_CASE */
-void mbedtls_mpi_swap_sint( int input_X, int input_Y )
-{
-    mbedtls_mpi X, Y;
-    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
-
-    TEST_ASSERT( mbedtls_mpi_lset( &X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_lset( &Y, input_Y ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_int( &X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_int( &Y, input_Y ) == 0 );
-
-    mbedtls_mpi_swap( &X, &Y );
-    TEST_ASSERT( mbedtls_mpi_cmp_int( &X, input_Y ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_int( &Y, input_X ) == 0 );
-
-exit:
-    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
-}
-/* END_CASE */
-
-/* BEGIN_CASE */
-void mbedtls_mpi_swap_binary( data_t *input_X, data_t *input_Y )
-{
-    mbedtls_mpi X, Y, X0, Y0;
-    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
-    mbedtls_mpi_init( &X0 ); mbedtls_mpi_init( &Y0 );
-
-    TEST_ASSERT( mbedtls_mpi_read_binary( &X, input_X->x, input_X->len ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_binary( &Y, input_Y->x, input_Y->len ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_binary( &X0, input_X->x, input_X->len ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_binary( &Y0, input_Y->x, input_Y->len ) == 0 );
-
-    mbedtls_mpi_swap( &X, &Y );
-    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
-
-exit:
-    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
-    mbedtls_mpi_free( &X0 ); mbedtls_mpi_free( &Y0 );
-}
-/* END_CASE */
-
-/* BEGIN_CASE */
-void mpi_swap_self( data_t *input_X )
-{
-    mbedtls_mpi X, X0;
-    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &X0 );
-
-    TEST_ASSERT( mbedtls_mpi_read_binary( &X, input_X->x, input_X->len ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_binary( &X0, input_X->x, input_X->len ) == 0 );
-
-    mbedtls_mpi_swap( &X, &X );
-    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
-
-exit:
-    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &X0 );
-}
-/* END_CASE */
-
-/* BEGIN_CASE */
 void mbedtls_mpi_add_mpi( int radix_X, char * input_X, int radix_Y,
                           char * input_Y, int radix_A, char * input_A )
 {
     mbedtls_mpi X, Y, Z, A;
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); 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 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
     TEST_ASSERT( mbedtls_mpi_add_mpi( &Z, &X, &Y ) == 0 );
+    TEST_ASSERT( sign_is_valid( &Z ) );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
 
     /* result == first operand */
     TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &Y ) == 0 );
+    TEST_ASSERT( sign_is_valid( &X ) );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
 
     /* result == second operand */
     TEST_ASSERT( mbedtls_mpi_add_mpi( &Y, &X, &Y ) == 0 );
+    TEST_ASSERT( sign_is_valid( &Y ) );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
 
 exit:
@@ -819,18 +799,21 @@
     mbedtls_mpi X, A;
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &A, radix_A, input_A ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
     TEST_ASSERT( mbedtls_mpi_sub_abs( &X, &X, &X ) == 0 );
     TEST_ASSERT( mbedtls_mpi_cmp_int( &X, 0 ) == 0 );
+    TEST_ASSERT( sign_is_valid( &X ) );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
     TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &X ) == 0 );
+    TEST_ASSERT( sign_is_valid( &X ) );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
     TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &X ) == 0 );
+    TEST_ASSERT( sign_is_valid( &X ) );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
 
 exit:
@@ -846,19 +829,22 @@
     mbedtls_mpi X, Y, Z, A;
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); 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 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
     TEST_ASSERT( mbedtls_mpi_add_abs( &Z, &X, &Y ) == 0 );
+    TEST_ASSERT( sign_is_valid( &Z ) );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
 
     /* result == first operand */
     TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &Y ) == 0 );
+    TEST_ASSERT( sign_is_valid( &X ) );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
 
     /* result == second operand */
     TEST_ASSERT( mbedtls_mpi_add_abs( &Y, &X, &Y ) == 0 );
+    TEST_ASSERT( sign_is_valid( &Y ) );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
 
 exit:
@@ -873,9 +859,10 @@
     mbedtls_mpi X, Z, A;
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &A, radix_A, input_A ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
     TEST_ASSERT( mbedtls_mpi_add_int( &Z, &X, input_Y ) == 0 );
+    TEST_ASSERT( sign_is_valid( &Z ) );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
 
 exit:
@@ -890,19 +877,22 @@
     mbedtls_mpi X, Y, Z, A;
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); 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 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
     TEST_ASSERT( mbedtls_mpi_sub_mpi( &Z, &X, &Y ) == 0 );
+    TEST_ASSERT( sign_is_valid( &Z ) );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
 
     /* result == first operand */
     TEST_ASSERT( mbedtls_mpi_sub_mpi( &X, &X, &Y ) == 0 );
+    TEST_ASSERT( sign_is_valid( &X ) );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
 
     /* result == second operand */
     TEST_ASSERT( mbedtls_mpi_sub_mpi( &Y, &X, &Y ) == 0 );
+    TEST_ASSERT( sign_is_valid( &Y ) );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
 
 exit:
@@ -919,23 +909,26 @@
     int res;
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); 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 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
 
     res = mbedtls_mpi_sub_abs( &Z, &X, &Y );
     TEST_ASSERT( res == sub_result );
+    TEST_ASSERT( sign_is_valid( &Z ) );
     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 );
+    TEST_ASSERT( sign_is_valid( &X ) );
     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 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
 
     /* result == second operand */
     TEST_ASSERT( mbedtls_mpi_sub_abs( &Y, &X, &Y ) == sub_result );
+    TEST_ASSERT( sign_is_valid( &Y ) );
     if( sub_result == 0 )
         TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
 
@@ -951,9 +944,10 @@
     mbedtls_mpi X, Z, A;
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &A, radix_A, input_A ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
     TEST_ASSERT( mbedtls_mpi_sub_int( &Z, &X, input_Y ) == 0 );
+    TEST_ASSERT( sign_is_valid( &Z ) );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
 
 exit:
@@ -968,10 +962,11 @@
     mbedtls_mpi X, Y, Z, A;
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); 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 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
     TEST_ASSERT( mbedtls_mpi_mul_mpi( &Z, &X, &Y ) == 0 );
+    TEST_ASSERT( sign_is_valid( &Z ) );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
 
 exit:
@@ -987,9 +982,10 @@
     mbedtls_mpi X, Z, A;
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &A, radix_A, input_A ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
     TEST_ASSERT( mbedtls_mpi_mul_int( &Z, &X, input_Y ) == 0 );
+    TEST_ASSERT( sign_is_valid( &Z ) );
     if( strcmp( result_comparison, "==" ) == 0 )
         TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
     else if( strcmp( result_comparison, "!=" ) == 0 )
@@ -1012,14 +1008,16 @@
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &R );
     mbedtls_mpi_init( &A ); mbedtls_mpi_init( &B );
 
-    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 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &B, radix_B, input_B ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &B, radix_B, input_B ) == 0 );
     res = mbedtls_mpi_div_mpi( &Q, &R, &X, &Y );
     TEST_ASSERT( res == div_result );
     if( res == 0 )
     {
+        TEST_ASSERT( sign_is_valid( &Q ) );
+        TEST_ASSERT( sign_is_valid( &R ) );
         TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Q, &A ) == 0 );
         TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &B ) == 0 );
     }
@@ -1040,13 +1038,15 @@
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &R ); mbedtls_mpi_init( &A );
     mbedtls_mpi_init( &B );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &A, radix_A, input_A ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &B, radix_B, input_B ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &B, radix_B, input_B ) == 0 );
     res = mbedtls_mpi_div_int( &Q, &R, &X, input_Y );
     TEST_ASSERT( res == div_result );
     if( res == 0 )
     {
+        TEST_ASSERT( sign_is_valid( &Q ) );
+        TEST_ASSERT( sign_is_valid( &R ) );
         TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Q, &A ) == 0 );
         TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &B ) == 0 );
     }
@@ -1066,13 +1066,14 @@
     int res;
     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 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
     res = mbedtls_mpi_mod_mpi( &X, &X, &Y );
     TEST_ASSERT( res == div_result );
     if( res == 0 )
     {
+        TEST_ASSERT( sign_is_valid( &X ) );
         TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
     }
 
@@ -1090,7 +1091,7 @@
     mbedtls_mpi_uint r;
     mbedtls_mpi_init( &X );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
     res = mbedtls_mpi_mod_int( &r, &X, input_Y );
     TEST_ASSERT( res == div_result );
     if( res == 0 )
@@ -1106,26 +1107,41 @@
 /* BEGIN_CASE */
 void mbedtls_mpi_exp_mod( int radix_A, char * input_A, int radix_E,
                           char * input_E, int radix_N, char * input_N,
-                          int radix_RR, char * input_RR, int radix_X,
-                          char * input_X, int div_result )
+                          int radix_X, char * input_X, int exp_result )
 {
     mbedtls_mpi A, E, N, RR, Z, X;
     int res;
     mbedtls_mpi_init( &A  ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N );
     mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &X );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &A, radix_A, input_A ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
 
-    if( strlen( input_RR ) )
-        TEST_ASSERT( mbedtls_mpi_read_string( &RR, radix_RR, input_RR ) == 0 );
-
-    res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR );
-    TEST_ASSERT( res == div_result );
+    res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, NULL );
+    TEST_ASSERT( res == exp_result );
     if( res == 0 )
     {
+        TEST_ASSERT( sign_is_valid( &Z ) );
+        TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
+    }
+
+    /* Now test again with the speed-up parameter supplied as an output. */
+    res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR );
+    TEST_ASSERT( res == exp_result );
+    if( res == 0 )
+    {
+        TEST_ASSERT( sign_is_valid( &Z ) );
+        TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
+    }
+
+    /* Now test again with the speed-up parameter supplied in calculated form. */
+    res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR );
+    TEST_ASSERT( res == exp_result );
+    if( res == 0 )
+    {
+        TEST_ASSERT( sign_is_valid( &Z ) );
         TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
     }
 
@@ -1159,7 +1175,7 @@
     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_test_read_mpi( &RR, radix_RR, input_RR ) == 0 );
 
     TEST_ASSERT( mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR ) == exp_result );
 
@@ -1178,13 +1194,14 @@
     int res;
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); 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 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
     res = mbedtls_mpi_inv_mod( &Z, &X, &Y );
     TEST_ASSERT( res == div_result );
     if( res == 0 )
     {
+        TEST_ASSERT( sign_is_valid( &Z ) );
         TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
     }
 
@@ -1200,7 +1217,7 @@
     int res;
     mbedtls_mpi_init( &X );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
     res = mbedtls_mpi_is_prime_ext( &X, 40, rnd_std_rand, NULL );
     TEST_ASSERT( res == div_result );
 
@@ -1259,6 +1276,7 @@
 
         TEST_ASSERT( actual_bits >= (size_t) bits );
         TEST_ASSERT( actual_bits <= (size_t) bits + 1 );
+        TEST_ASSERT( sign_is_valid( &X ) );
 
         TEST_ASSERT( mbedtls_mpi_is_prime_ext( &X, 40, rnd_std_rand, NULL )
                      == 0 );
@@ -1283,9 +1301,10 @@
     mbedtls_mpi X, A;
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &A, radix_A, input_A ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
     TEST_ASSERT( mbedtls_mpi_shift_l( &X, shift_X ) == 0 );
+    TEST_ASSERT( sign_is_valid( &X ) );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
 
 exit:
@@ -1300,9 +1319,10 @@
     mbedtls_mpi X, A;
     mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &A, radix_A, input_A ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
     TEST_ASSERT( mbedtls_mpi_shift_r( &X, shift_X ) == 0 );
+    TEST_ASSERT( sign_is_valid( &X ) );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
 
 exit:
@@ -1334,6 +1354,7 @@
         TEST_ASSERT( mbedtls_mpi_size( &X ) + leading_zeros ==
                      (size_t) wanted_bytes );
         TEST_ASSERT( (int) bytes_left == rng_bytes - wanted_bytes );
+        TEST_ASSERT( sign_is_valid( &X ) );
     }
 
 exit:
diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function
index 18f5ef8..a0bbabc 100644
--- a/tests/suites/test_suite_pk.function
+++ b/tests/suites/test_suite_pk.function
@@ -569,8 +569,8 @@
     rsa = mbedtls_pk_rsa( pk );
 
     rsa->len = mod / 8;
-    TEST_ASSERT( mbedtls_mpi_read_string( &rsa->N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &rsa->E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &rsa->N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &rsa->E, radix_E, input_E ) == 0 );
 
 
     if( mbedtls_md_info_from_type( digest ) != NULL )
@@ -612,8 +612,8 @@
     rsa = mbedtls_pk_rsa( pk );
 
     rsa->len = mod / 8;
-    TEST_ASSERT( mbedtls_mpi_read_string( &rsa->N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &rsa->E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &rsa->N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &rsa->E, radix_E, input_E ) == 0 );
 
 
     if( digest != MBEDTLS_MD_NONE )
@@ -698,7 +698,7 @@
 
     TEST_ASSERT( mbedtls_pk_setup( &prv, mbedtls_pk_info_from_type( pk_type ) ) == 0 );
     TEST_ASSERT( mbedtls_ecp_group_load( &mbedtls_pk_ec( prv )->grp, grp_id ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &mbedtls_pk_ec( prv )->d, 16, d_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &mbedtls_pk_ec( prv )->d, 16, d_str ) == 0 );
 
     TEST_ASSERT( mbedtls_pk_setup( &pub, mbedtls_pk_info_from_type( pk_type ) ) == 0 );
     TEST_ASSERT( mbedtls_ecp_group_load( &mbedtls_pk_ec( pub )->grp, grp_id ) == 0 );
@@ -869,8 +869,8 @@
     rsa = mbedtls_pk_rsa( pk );
 
     rsa->len = mod / 8;
-    TEST_ASSERT( mbedtls_mpi_read_string( &rsa->N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &rsa->E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &rsa->N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &rsa->E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_pk_encrypt( &pk, message->x, message->len,
                              output, &olen, sizeof( output ),
@@ -908,12 +908,12 @@
     rsa = mbedtls_pk_rsa( pk );
 
     /* load public key */
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
 
     /* load private key */
-    TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &P, radix_P, input_P ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Q, radix_Q, input_Q ) == 0 );
     TEST_ASSERT( mbedtls_rsa_import( rsa, &N, &P, &Q, NULL, &E ) == 0 );
     TEST_ASSERT( mbedtls_rsa_get_len( rsa ) == (size_t) ( mod / 8 ) );
     TEST_ASSERT( mbedtls_rsa_complete( rsa ) == 0 );
diff --git a/tests/suites/test_suite_pkcs1_v15.function b/tests/suites/test_suite_pkcs1_v15.function
index a1e11f7..856c36c 100644
--- a/tests/suites/test_suite_pkcs1_v15.function
+++ b/tests/suites/test_suite_pkcs1_v15.function
@@ -26,8 +26,8 @@
     mbedtls_rsa_init( &ctx, MBEDTLS_RSA_PKCS_V15, hash );
     memset( output, 0x00, sizeof( output ) );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 );
     TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( ( mod + 7 ) / 8 ) );
     TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == 0 );
@@ -68,10 +68,10 @@
     memset( output, 0x00, sizeof( output ) );
     memset( &rnd_info, 0, sizeof( rnd_pseudo_info ) );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &P, radix_P, input_P ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Q, radix_Q, input_Q ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, &P, &Q, NULL, &E ) == 0 );
     TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( ( mod + 7 ) / 8 ) );
@@ -264,10 +264,10 @@
     memset( hash_result, 0x00, sizeof( hash_result ) );
     memset( output, 0x00, sizeof( output ) );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &P, radix_P, input_P ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Q, radix_Q, input_Q ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, &P, &Q, NULL, &E ) == 0 );
     TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( ( mod + 7 ) / 8 ) );
@@ -308,8 +308,8 @@
     mbedtls_rsa_init( &ctx, MBEDTLS_RSA_PKCS_V15, hash );
     memset( hash_result, 0x00, sizeof( hash_result ) );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 );
     TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( ( mod + 7 ) / 8 ) );
     TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == 0 );
diff --git a/tests/suites/test_suite_pkcs1_v21.function b/tests/suites/test_suite_pkcs1_v21.function
index a4119a2..4db0abc 100644
--- a/tests/suites/test_suite_pkcs1_v21.function
+++ b/tests/suites/test_suite_pkcs1_v21.function
@@ -26,8 +26,8 @@
     mbedtls_rsa_init( &ctx, MBEDTLS_RSA_PKCS_V21, hash );
     memset( output, 0x00, sizeof( output ) );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 );
     TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( ( mod + 7 ) / 8 ) );
     TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == 0 );
@@ -69,10 +69,10 @@
     memset( output, 0x00, sizeof( output ) );
     memset( &rnd_info, 0, sizeof( rnd_pseudo_info ) );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &P, radix_P, input_P ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Q, radix_Q, input_Q ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, &P, &Q, NULL, &E ) == 0 );
     TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( ( mod + 7 ) / 8 ) );
@@ -120,10 +120,10 @@
     memset( hash_result, 0x00, sizeof( hash_result ) );
     memset( output, 0x00, sizeof( output ) );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &P, radix_P, input_P ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Q, radix_Q, input_Q ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, &P, &Q, NULL, &E ) == 0 );
     TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( ( mod + 7 ) / 8 ) );
@@ -165,8 +165,8 @@
     mbedtls_rsa_init( &ctx, MBEDTLS_RSA_PKCS_V21, hash );
     memset( hash_result, 0x00, sizeof( hash_result ) );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 );
     TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( ( mod + 7 ) / 8 ) );
@@ -202,8 +202,8 @@
     mbedtls_rsa_init( &ctx, MBEDTLS_RSA_PKCS_V21, ctx_hash );
     memset( hash_result, 0x00, sizeof( hash_result ) );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 );
     TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( ( mod + 7 ) / 8 ) );
diff --git a/tests/suites/test_suite_pkparse.data b/tests/suites/test_suite_pkparse.data
index cd842cf..d4a0e44 100644
--- a/tests/suites/test_suite_pkparse.data
+++ b/tests/suites/test_suite_pkparse.data
@@ -989,7 +989,7 @@
 pk_parse_public_keyfile_ec:"data_files/ec_bp512_pub.pem":0
 
 Parse EC Key #1 (SEC1 DER)
-depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP192R1_ENABLED
+depends_on:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP192R1_ENABLED
 pk_parse_keyfile_ec:"data_files/ec_prv.sec1.der":"NULL":0
 
 Parse EC Key #2 (SEC1 PEM)
@@ -1005,15 +1005,15 @@
 pk_parse_keyfile_ec:"data_files/ec_prv.pk8.der":"NULL":0
 
 Parse EC Key #4a (PKCS8 DER, no public key)
-depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+depends_on:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
 pk_parse_keyfile_ec:"data_files/ec_prv.pk8nopub.der":"NULL":0
 
 Parse EC Key #4b (PKCS8 DER, no public key, with parameters)
-depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+depends_on:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
 pk_parse_keyfile_ec:"data_files/ec_prv.pk8nopubparam.der":"NULL":0
 
 Parse EC Key #4c (PKCS8 DER, with parameters)
-depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+depends_on:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
 pk_parse_keyfile_ec:"data_files/ec_prv.pk8param.der":"NULL":0
 
 Parse EC Key #5 (PKCS8 PEM)
@@ -1069,7 +1069,7 @@
 pk_parse_keyfile_ec:"data_files/ec_bp512_prv.pem":"NULL":0
 
 Parse EC Key #15 (SEC1 DER, secp256k1, SpecifiedECDomain)
-depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256K1_ENABLED:MBEDTLS_PK_PARSE_EC_EXTENDED
+depends_on:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256K1_ENABLED:MBEDTLS_PK_PARSE_EC_EXTENDED
 pk_parse_keyfile_ec:"data_files/ec_prv.specdom.der":"NULL":0
 
 Key ASN1 (No data)
diff --git a/tests/suites/test_suite_rsa.data b/tests/suites/test_suite_rsa.data
index 5e4de17..803b027 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
@@ -375,12 +381,18 @@
 RSA Private (Data larger than N)
 mbedtls_rsa_private:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":2048:16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":"605baf947c0de49e4f6a0dfb94a43ae318d5df8ed20ba4ba5a37a73fb009c5c9e5cce8b70a25b1c7580f389f0d7092485cdfa02208b70d33482edf07a7eafebdc54862ca0e0396a5a7d09991b9753eb1ffb6091971bb5789c6b121abbcd0a3cbaa39969fa7c28146fce96c6d03272e3793e5be8f5abfa9afcbebb986d7b3050604a2af4d3a40fa6c003781a539a60259d1e84f13322da9e538a49c369b83e7286bf7d30b64bbb773506705da5d5d5483a563a1ffacc902fb75c9a751b1e83cdc7a6db0470056883f48b5a5446b43b1d180ea12ba11a6a8d93b3b32a30156b6084b7fb142998a2a0d28014b84098ece7d9d5e4d55cc342ca26f5a0167a679dec8":MBEDTLS_ERR_RSA_PRIVATE_FAILED + MBEDTLS_ERR_MPI_BAD_INPUT_DATA
 
+RSA Private (Data = 0 )
+mbedtls_rsa_private:"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":2048:16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":16:"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":0
+
 RSA Public (Correct)
 mbedtls_rsa_public:"59779fd2a39e56640c4fc1e67b60aeffcecd78aed7ad2bdfa464e93d04198d48466b8da7445f25bfa19db2844edd5c8f539cf772cc132b483169d390db28a43bc4ee0f038f6568ffc87447746cb72fefac2d6d90ee3143a915ac4688028805905a68eb8f8a96674b093c495eddd8704461eaa2b345efbb2ad6930acd8023f8700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":2048:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":"1f5e927c13ff231090b0f18c8c3526428ed0f4a7561457ee5afe4d22d5d9220c34ef5b9a34d0c07f7248a1f3d57f95d10f7936b3063e40660b3a7ca3e73608b013f85a6e778ac7c60d576e9d9c0c5a79ad84ceea74e4722eb3553bdb0c2d7783dac050520cb27ca73478b509873cb0dcbd1d51dd8fccb96c29ad314f36d67cc57835d92d94defa0399feb095fd41b9f0b2be10f6041079ed4290040449f8a79aba50b0a1f8cf83c9fb8772b0686ec1b29cb1814bb06f9c024857db54d395a8da9a2c6f9f53b94bec612a0cb306a3eaa9fc80992e85d9d232e37a50cabe48c9343f039601ff7d95d60025e582aec475d031888310e8ec3833b394a5cf0599101e":0
 
 RSA Public (Data larger than N)
 mbedtls_rsa_public:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":2048:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":"605baf947c0de49e4f6a0dfb94a43ae318d5df8ed20ba4ba5a37a73fb009c5c9e5cce8b70a25b1c7580f389f0d7092485cdfa02208b70d33482edf07a7eafebdc54862ca0e0396a5a7d09991b9753eb1ffb6091971bb5789c6b121abbcd0a3cbaa39969fa7c28146fce96c6d03272e3793e5be8f5abfa9afcbebb986d7b3050604a2af4d3a40fa6c003781a539a60259d1e84f13322da9e538a49c369b83e7286bf7d30b64bbb773506705da5d5d5483a563a1ffacc902fb75c9a751b1e83cdc7a6db0470056883f48b5a5446b43b1d180ea12ba11a6a8d93b3b32a30156b6084b7fb142998a2a0d28014b84098ece7d9d5e4d55cc342ca26f5a0167a679dec8":MBEDTLS_ERR_RSA_PUBLIC_FAILED + MBEDTLS_ERR_MPI_BAD_INPUT_DATA
 
+RSA Public (Data = 0)
+mbedtls_rsa_public:"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":2048:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":0
+
 RSA Generate Key - 128bit key
 mbedtls_rsa_gen_key:128:3:0
 
diff --git a/tests/suites/test_suite_rsa.function b/tests/suites/test_suite_rsa.function
index f8a2dad..eaee7b3 100644
--- a/tests/suites/test_suite_rsa.function
+++ b/tests/suites/test_suite_rsa.function
@@ -466,6 +466,29 @@
 /* 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,
@@ -486,10 +509,10 @@
     memset( output, 0x00, sizeof( output ) );
     memset( &rnd_info, 0, sizeof( rnd_pseudo_info ) );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &P, radix_P, input_P ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Q, radix_Q, input_Q ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, &P, &Q, NULL, &E ) == 0 );
     TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod / 8 ) );
@@ -532,8 +555,8 @@
     mbedtls_rsa_init( &ctx, padding_mode, 0 );
     memset( hash_result, 0x00, sizeof( hash_result ) );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 );
     TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod / 8 ) );
     TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == 0 );
@@ -570,10 +593,10 @@
     memset( output, 0x00, sizeof( output ) );
     memset( &rnd_info, 0, sizeof( rnd_pseudo_info ) );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &P, radix_P, input_P ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Q, radix_Q, input_Q ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, &P, &Q, NULL, &E ) == 0 );
     TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod / 8 ) );
@@ -640,8 +663,8 @@
     mbedtls_rsa_init( &ctx, padding_mode, 0 );
     memset( output, 0x00, sizeof( output ) );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 );
     TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod / 8 ) );
@@ -704,8 +727,8 @@
     mbedtls_rsa_init( &ctx, padding_mode, 0 );
     memset( output, 0x00, sizeof( output ) );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 );
     TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod / 8 ) );
@@ -743,8 +766,8 @@
     mbedtls_rsa_init( &ctx, padding_mode, 0 );
     memset( output, 0x00, sizeof( output ) );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 );
     TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod / 8 ) );
@@ -790,10 +813,10 @@
     memset( &rnd_info, 0, sizeof( rnd_pseudo_info ) );
 
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &P, radix_P, input_P ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Q, radix_Q, input_Q ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, &P, &Q, NULL, &E ) == 0 );
     TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod / 8 ) );
@@ -833,14 +856,16 @@
     mbedtls_rsa_init( &ctx2, MBEDTLS_RSA_PKCS_V15, 0 );
     memset( output, 0x00, sizeof( output ) );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 );
+
+    /* Check test data consistency */
+    TEST_ASSERT( message_str->len == (size_t) ( mod / 8 ) );
     TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod / 8 ) );
     TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == 0 );
 
-
     TEST_ASSERT( mbedtls_rsa_public( &ctx, message_str->x, output ) == result );
     if( result == 0 )
     {
@@ -892,17 +917,19 @@
 
     memset( &rnd_info, 0, sizeof( rnd_pseudo_info ) );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &P, radix_P, input_P ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Q, radix_Q, input_Q ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, &P, &Q, NULL, &E ) == 0 );
+
+    /* Check test data consistency */
+    TEST_ASSERT( message_str->len == (size_t) ( mod / 8 ) );
     TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod / 8 ) );
     TEST_ASSERT( mbedtls_rsa_complete( &ctx ) == 0 );
     TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx ) == 0 );
 
-
     /* repeat three times to test updating of blinding values */
     for( i = 0; i < 3; i++ )
     {
@@ -966,11 +993,11 @@
 
     if( strlen( input_N ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
     }
     if( strlen( input_E ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
     }
 
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 );
@@ -998,36 +1025,36 @@
     ctx.len = mod / 8;
     if( strlen( input_P ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &ctx.P, radix_P, input_P ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &ctx.P, radix_P, input_P ) == 0 );
     }
     if( strlen( input_Q ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &ctx.Q, radix_Q, input_Q ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &ctx.Q, radix_Q, input_Q ) == 0 );
     }
     if( strlen( input_N ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &ctx.N, radix_N, input_N ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &ctx.N, radix_N, input_N ) == 0 );
     }
     if( strlen( input_E ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &ctx.E, radix_E, input_E ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &ctx.E, radix_E, input_E ) == 0 );
     }
     if( strlen( input_D ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &ctx.D, radix_D, input_D ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &ctx.D, radix_D, input_D ) == 0 );
     }
 #if !defined(MBEDTLS_RSA_NO_CRT)
     if( strlen( input_DP ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &ctx.DP, radix_DP, input_DP ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &ctx.DP, radix_DP, input_DP ) == 0 );
     }
     if( strlen( input_DQ ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &ctx.DQ, radix_DQ, input_DQ ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &ctx.DQ, radix_DQ, input_DQ ) == 0 );
     }
     if( strlen( input_QP ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &ctx.QP, radix_QP, input_QP ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &ctx.QP, radix_QP, input_QP ) == 0 );
     }
 #else
     ((void) radix_DP); ((void) input_DP);
@@ -1062,45 +1089,45 @@
 
     if( strlen( input_Npub ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &pub.N, radix_Npub, input_Npub ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &pub.N, radix_Npub, input_Npub ) == 0 );
     }
     if( strlen( input_Epub ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &pub.E, radix_Epub, input_Epub ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &pub.E, radix_Epub, input_Epub ) == 0 );
     }
 
     if( strlen( input_P ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &prv.P, radix_P, input_P ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &prv.P, radix_P, input_P ) == 0 );
     }
     if( strlen( input_Q ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &prv.Q, radix_Q, input_Q ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &prv.Q, radix_Q, input_Q ) == 0 );
     }
     if( strlen( input_N ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &prv.N, radix_N, input_N ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &prv.N, radix_N, input_N ) == 0 );
     }
     if( strlen( input_E ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &prv.E, radix_E, input_E ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &prv.E, radix_E, input_E ) == 0 );
     }
     if( strlen( input_D ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &prv.D, radix_D, input_D ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &prv.D, radix_D, input_D ) == 0 );
     }
 #if !defined(MBEDTLS_RSA_NO_CRT)
     if( strlen( input_DP ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &prv.DP, radix_DP, input_DP ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &prv.DP, radix_DP, input_DP ) == 0 );
     }
     if( strlen( input_DQ ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &prv.DQ, radix_DQ, input_DQ ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &prv.DQ, radix_DQ, input_DQ ) == 0 );
     }
     if( strlen( input_QP ) )
     {
-        TEST_ASSERT( mbedtls_mpi_read_string( &prv.QP, radix_QP, input_QP ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &prv.QP, radix_QP, input_QP ) == 0 );
     }
 #else
     ((void) radix_DP); ((void) input_DP);
@@ -1161,11 +1188,11 @@
     mbedtls_mpi_init( &Pp ); mbedtls_mpi_init( &Qp );
     mbedtls_mpi_init( &D ); mbedtls_mpi_init( &E );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &D, radix_D, input_D ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Qp, radix_P, output_P ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Pp, radix_Q, output_Q ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &D, radix_D, input_D ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Qp, radix_P, output_P ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Pp, radix_Q, output_Q ) == 0 );
 
     if( corrupt )
         TEST_ASSERT( mbedtls_mpi_add_int( &D, &D, 2 ) == 0 );
@@ -1202,10 +1229,10 @@
     mbedtls_mpi_init( &E );
     mbedtls_mpi_init( &R ); mbedtls_mpi_init( &Rp );
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
-    TEST_ASSERT( mbedtls_mpi_read_string( &Dp, radix_D, output_D ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &P, radix_P, input_P ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Q, radix_Q, input_Q ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &Dp, radix_D, output_D ) == 0 );
 
     if( corrupt )
     {
@@ -1288,19 +1315,19 @@
                                 (const unsigned char *) pers, strlen( pers ) ) == 0 );
 
     if( have_N )
-        TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
 
     if( have_P )
-        TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &P, radix_P, input_P ) == 0 );
 
     if( have_Q )
-        TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &Q, radix_Q, input_Q ) == 0 );
 
     if( have_D )
-        TEST_ASSERT( mbedtls_mpi_read_string( &D, radix_D, input_D ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &D, radix_D, input_D ) == 0 );
 
     if( have_E )
-        TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
 
     if( !successive )
     {
@@ -1432,19 +1459,19 @@
     /* Setup RSA context */
 
     if( have_N )
-        TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
 
     if( have_P )
-        TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &P, radix_P, input_P ) == 0 );
 
     if( have_Q )
-        TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &Q, radix_Q, input_Q ) == 0 );
 
     if( have_D )
-        TEST_ASSERT( mbedtls_mpi_read_string( &D, radix_D, input_D ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &D, radix_D, input_D ) == 0 );
 
     if( have_E )
-        TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_rsa_import( &ctx,
                                      strlen( input_N ) ? &N : NULL,
@@ -1552,19 +1579,19 @@
                                         strlen( pers ) ) == 0 );
 
     if( have_N )
-        TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
 
     if( have_P )
-        TEST_ASSERT( mbedtls_mpi_read_string( &P, radix_P, input_P ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &P, radix_P, input_P ) == 0 );
 
     if( have_Q )
-        TEST_ASSERT( mbedtls_mpi_read_string( &Q, radix_Q, input_Q ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &Q, radix_Q, input_Q ) == 0 );
 
     if( have_D )
-        TEST_ASSERT( mbedtls_mpi_read_string( &D, radix_D, input_D ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &D, radix_D, input_D ) == 0 );
 
     if( have_E )
-        TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
+        TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_rsa_validate_params( have_N ? &N : NULL,
                                         have_P ? &P : NULL,
diff --git a/tests/suites/test_suite_version.data b/tests/suites/test_suite_version.data
index d43ddad..3aa2523 100644
--- a/tests/suites/test_suite_version.data
+++ b/tests/suites/test_suite_version.data
@@ -1,8 +1,8 @@
 Check compiletime library version
-check_compiletime_version:"2.16.9"
+check_compiletime_version:"2.16.11"
 
 Check runtime library version
-check_runtime_version:"2.16.9"
+check_runtime_version:"2.16.11"
 
 Check for MBEDTLS_VERSION_C
 check_feature:"MBEDTLS_VERSION_C":0
diff --git a/tests/suites/test_suite_x509write.function b/tests/suites/test_suite_x509write.function
index f7d686a..0ed35db 100644
--- a/tests/suites/test_suite_x509write.function
+++ b/tests/suites/test_suite_x509write.function
@@ -154,7 +154,7 @@
     (void) rsa_alt;
 #endif
 
-    TEST_ASSERT( mbedtls_mpi_read_string( &serial, 10, serial_str ) == 0 );
+    TEST_ASSERT( mbedtls_test_read_mpi( &serial, 10, serial_str ) == 0 );
 
     if( ver != -1 )
         mbedtls_x509write_crt_set_version( &crt, ver );
diff --git a/visualc/VS2010/aescrypt2.vcxproj b/visualc/VS2010/aescrypt2.vcxproj
deleted file mode 100644
index 1d608db..0000000
--- a/visualc/VS2010/aescrypt2.vcxproj
+++ /dev/null
@@ -1,173 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup Label="ProjectConfigurations">

-    <ProjectConfiguration Include="Debug|Win32">

-      <Configuration>Debug</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Debug|x64">

-      <Configuration>Debug</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release|Win32">

-      <Configuration>Release</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release|x64">

-      <Configuration>Release</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-  </ItemGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\programs\aes\aescrypt2.c" />

-  </ItemGroup>

-  <ItemGroup>

-    <ProjectReference Include="mbedTLS.vcxproj">

-      <Project>{46cf2d25-6a36-4189-b59c-e4815388e554}</Project>

-      <LinkLibraryDependencies>true</LinkLibraryDependencies>

-    </ProjectReference>

-  </ItemGroup>

-  <PropertyGroup Label="Globals">

-    <ProjectGuid>{7A851DBD-7D57-E8F4-85E5-CCA72AEA7DF8}</ProjectGuid>

-    <Keyword>Win32Proj</Keyword>

-    <RootNamespace>aescrypt2</RootNamespace>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

-  <ImportGroup Label="ExtensionSettings">

-  </ImportGroup>

-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <PropertyGroup Label="UserMacros" />

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <LinkIncremental>true</LinkIncremental>

-    <IntDir>$(Configuration)\$(TargetName)\</IntDir>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <LinkIncremental>true</LinkIncremental>

-    <IntDir>$(Configuration)\$(TargetName)\</IntDir>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">

-    <LinkIncremental>false</LinkIncremental>

-    <IntDir>$(Configuration)\$(TargetName)\</IntDir>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">

-    <LinkIncremental>false</LinkIncremental>

-    <IntDir>$(Configuration)\$(TargetName)\</IntDir>

-  </PropertyGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <ClCompile>

-      <PrecompiledHeader>

-      </PrecompiledHeader>

-      <WarningLevel>Level3</WarningLevel>

-      <Optimization>Disabled</Optimization>

-      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <GenerateDebugInformation>true</GenerateDebugInformation>

-      <ShowProgress>NotSet</ShowProgress>

-      <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>

-      <AdditionalLibraryDirectories>Debug</AdditionalLibraryDirectories>

-    </Link>

-    <ProjectReference>

-      <LinkLibraryDependencies>false</LinkLibraryDependencies>

-    </ProjectReference>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <ClCompile>

-      <PrecompiledHeader>

-      </PrecompiledHeader>

-      <WarningLevel>Level3</WarningLevel>

-      <Optimization>Disabled</Optimization>

-      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <GenerateDebugInformation>true</GenerateDebugInformation>

-      <ShowProgress>NotSet</ShowProgress>

-      <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>

-      <AdditionalLibraryDirectories>Debug</AdditionalLibraryDirectories>

-    </Link>

-    <ProjectReference>

-      <LinkLibraryDependencies>false</LinkLibraryDependencies>

-    </ProjectReference>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">

-    <ClCompile>

-      <WarningLevel>Level3</WarningLevel>

-      <PrecompiledHeader>

-      </PrecompiledHeader>

-      <Optimization>MaxSpeed</Optimization>

-      <FunctionLevelLinking>true</FunctionLevelLinking>

-      <IntrinsicFunctions>true</IntrinsicFunctions>

-      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <GenerateDebugInformation>true</GenerateDebugInformation>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <OptimizeReferences>true</OptimizeReferences>

-      <AdditionalLibraryDirectories>Release</AdditionalLibraryDirectories>

-      <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>

-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">

-    <ClCompile>

-      <WarningLevel>Level3</WarningLevel>

-      <PrecompiledHeader>

-      </PrecompiledHeader>

-      <Optimization>MaxSpeed</Optimization>

-      <FunctionLevelLinking>true</FunctionLevelLinking>

-      <IntrinsicFunctions>true</IntrinsicFunctions>

-      <PreprocessorDefinitions>WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <GenerateDebugInformation>true</GenerateDebugInformation>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <OptimizeReferences>true</OptimizeReferences>

-      <AdditionalLibraryDirectories>Release</AdditionalLibraryDirectories>

-      <AdditionalDependencies>%(AdditionalDependencies);</AdditionalDependencies>

-    </Link>

-  </ItemDefinitionGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

-  <ImportGroup Label="ExtensionTargets">

-  </ImportGroup>

-</Project>

diff --git a/visualc/VS2010/mbedTLS.sln b/visualc/VS2010/mbedTLS.sln
index 61f30bb..57a8d4d 100644
--- a/visualc/VS2010/mbedTLS.sln
+++ b/visualc/VS2010/mbedTLS.sln
@@ -3,11 +3,6 @@
 # Visual C++ Express 2010

 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mbedTLS", "mbedTLS.vcxproj", "{46CF2D25-6A36-4189-B59C-E4815388E554}"

 EndProject

-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "aescrypt2", "aescrypt2.vcxproj", "{7A851DBD-7D57-E8F4-85E5-CCA72AEA7DF8}"

-	ProjectSection(ProjectDependencies) = postProject

-		{46CF2D25-6A36-4189-B59C-E4815388E554} = {46CF2D25-6A36-4189-B59C-E4815388E554}

-	EndProjectSection

-EndProject

 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "crypt_and_hash", "crypt_and_hash.vcxproj", "{5DBB9FC3-6FD6-CA8D-E0FA-35F1E75EFAE7}"

 	ProjectSection(ProjectDependencies) = postProject

 		{46CF2D25-6A36-4189-B59C-E4815388E554} = {46CF2D25-6A36-4189-B59C-E4815388E554}

@@ -259,14 +254,6 @@
 		{46CF2D25-6A36-4189-B59C-E4815388E554}.Release|Win32.Build.0 = Release|Win32

 		{46CF2D25-6A36-4189-B59C-E4815388E554}.Release|x64.ActiveCfg = Release|x64

 		{46CF2D25-6A36-4189-B59C-E4815388E554}.Release|x64.Build.0 = Release|x64

-		{7A851DBD-7D57-E8F4-85E5-CCA72AEA7DF8}.Debug|Win32.ActiveCfg = Debug|Win32

-		{7A851DBD-7D57-E8F4-85E5-CCA72AEA7DF8}.Debug|Win32.Build.0 = Debug|Win32

-		{7A851DBD-7D57-E8F4-85E5-CCA72AEA7DF8}.Debug|x64.ActiveCfg = Debug|x64

-		{7A851DBD-7D57-E8F4-85E5-CCA72AEA7DF8}.Debug|x64.Build.0 = Debug|x64

-		{7A851DBD-7D57-E8F4-85E5-CCA72AEA7DF8}.Release|Win32.ActiveCfg = Release|Win32

-		{7A851DBD-7D57-E8F4-85E5-CCA72AEA7DF8}.Release|Win32.Build.0 = Release|Win32

-		{7A851DBD-7D57-E8F4-85E5-CCA72AEA7DF8}.Release|x64.ActiveCfg = Release|x64

-		{7A851DBD-7D57-E8F4-85E5-CCA72AEA7DF8}.Release|x64.Build.0 = Release|x64

 		{5DBB9FC3-6FD6-CA8D-E0FA-35F1E75EFAE7}.Debug|Win32.ActiveCfg = Debug|Win32

 		{5DBB9FC3-6FD6-CA8D-E0FA-35F1E75EFAE7}.Debug|Win32.Build.0 = Debug|Win32

 		{5DBB9FC3-6FD6-CA8D-E0FA-35F1E75EFAE7}.Debug|x64.ActiveCfg = Debug|x64