Merge pull request #6717 from tom-cosgrove-arm/fix-typos-2212

Fix typos prior to release
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index 94fb020..50a4901 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -14,6 +14,6 @@
 
 ## Notes for the submitter
 
-Please refer to the [contributing guidelines](../CONTRIBUTING.md), especially the
+Please refer to the [contributing guidelines](https://github.com/Mbed-TLS/mbedtls/blob/development/CONTRIBUTING.md), especially the
 checklist for PR contributors.
 
diff --git a/ChangeLog.d/LMS.txt b/ChangeLog.d/LMS.txt
index 6de374f..785bfcf 100644
--- a/ChangeLog.d/LMS.txt
+++ b/ChangeLog.d/LMS.txt
@@ -3,9 +3,9 @@
       Signature verification is production-ready, but generation is for testing
       purposes only. This currently only supports one parameter set
       (LMS_SHA256_M32_H10), meaning that each private key can be used to sign
-      1024 messages. As such, it is not intended for use in TLS, but instead for
-      verification of assets transmitted over an insecure channel, particularly
-      firmware images.
+      1024 messages. As such, it is not intended for use in TLS, but instead
+      for verification of assets transmitted over an insecure channel,
+      particularly firmware images.
     * Add the LM-OTS post-quantum-safe one-time signature scheme, which is
-      required for LMS. This can be used independently, but each key can only be
-      used to sign one message so is impractical for most circumstances.
+      required for LMS. This can be used independently, but each key can only
+      be used to sign one message so is impractical for most circumstances.
diff --git a/ChangeLog.d/add-rsa-pss-rsae-support-for-tls12.txt b/ChangeLog.d/add-rsa-pss-rsae-support-for-tls12.txt
index f88eb9e..0d40968 100644
--- a/ChangeLog.d/add-rsa-pss-rsae-support-for-tls12.txt
+++ b/ChangeLog.d/add-rsa-pss-rsae-support-for-tls12.txt
@@ -1,8 +1,8 @@
 Features
-   * When GnuTLS/Openssl server is configured in TLS 1.2 mode with a certificate
-     declaring an RSA public key and Mbed TLS is configured in hybrid mode, if
-     `rsa_pss_rsae_*` algorithms are before `rsa_pkcs1_*` ones in this list then
-     the GnuTLS/Openssl server chooses an `rsa_pss_rsae_*` signature algorithm
-     for its signature in the key exchange message. As Mbed TLS 1.2 does not
-     support them, the handshake fails. Add `rsa_pss_rsae_*` support for TLS 1.2
-     to resolve the compitablity issue.
+   * Support rsa_pss_rsae_* signature algorithms in TLS 1.2.
+Bugfix
+   * Fix an interoperability failure between an Mbed TLS client with both
+     TLS 1.2 and TLS 1.3 support, and a TLS 1.2 server that supports
+     rsa_pss_rsae_* signature algorithms. This failed because Mbed TLS
+     advertised support for PSS in both TLS 1.2 and 1.3, but only
+     actually supported PSS in TLS 1.3.
diff --git a/ChangeLog.d/dtls-connection-id.txt b/ChangeLog.d/dtls-connection-id.txt
index eb9e216..840f837 100644
--- a/ChangeLog.d/dtls-connection-id.txt
+++ b/ChangeLog.d/dtls-connection-id.txt
@@ -3,14 +3,15 @@
      MBEDTLS_SSL_DTLS_CONNECTION_ID (enabled by default) and configured with
      mbedtls_ssl_set_cid().
 
-Changes
+Default behavior changes
    * Previously the macro MBEDTLS_SSL_DTLS_CONNECTION_ID implemented version 05
-     of the draft, and was marked experimental and disabled by default. It is
-     now no longer experimental, and implements the final version from RFC 9146,
-     which is not interoperable with the draft-05 version. If you need to
-     communicate with peers that use earlier versions of Mbed TLS, you
-     need to define MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT to 1, but then you
-     won't be able to communicate with peers that use the standard (non-draft)
-     version. If you need to interoperate with both classes of peers with the
+     of the IETF draft, and was marked experimental and disabled by default.
+     It is now no longer experimental, and implements the final version from
+     RFC 9146, which is not interoperable with the draft-05 version.
+     If you need to communicate with peers that use earlier versions of
+     Mbed TLS, then you need to define MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT
+     to 1, but then you won't be able to communicate with peers that use the
+     standard (non-draft) version.
+     If you need to interoperate with both classes of peers with the
      same build of Mbed TLS, please let us know about your situation on the
      mailing list or GitHub.
diff --git a/ChangeLog.d/extend-query_compile_time_config-to-psa_want.txt b/ChangeLog.d/extend-query_compile_time_config-to-psa_want.txt
index b268fd4..99b2ec4 100644
--- a/ChangeLog.d/extend-query_compile_time_config-to-psa_want.txt
+++ b/ChangeLog.d/extend-query_compile_time_config-to-psa_want.txt
@@ -1,2 +1,2 @@
 Changes
-   * Add the ability to query PSA_WANT_xxx macros to query_compile_time_config
+   * Add the ability to query PSA_WANT_xxx macros to query_compile_time_config.
diff --git a/ChangeLog.d/fix-tls12server-sent-sigalgs.txt b/ChangeLog.d/fix-tls12server-sent-sigalgs.txt
index 9abde2b..b74c6ec 100644
--- a/ChangeLog.d/fix-tls12server-sent-sigalgs.txt
+++ b/ChangeLog.d/fix-tls12server-sent-sigalgs.txt
@@ -1,5 +1,5 @@
 Bugfix
-    * Fix a bug whereby the the list of signature algorithms sent as part of the
-      TLS 1.2 server certificate request would get corrupted, meaning the first
-      algorithm would not get sent and an entry consisting of two random bytes
-      would be sent instead. Found by Serban Bejan and Dudek Sebastian.
+    * Fix a bug whereby the list of signature algorithms sent as part of
+      the TLS 1.2 server certificate request would get corrupted, meaning the
+      first algorithm would not get sent and an entry consisting of two random
+      bytes would be sent instead. Found by Serban Bejan and Dudek Sebastian.
diff --git a/ChangeLog.d/fix_build_error_for_mbedtls_deprecated_removed.txt b/ChangeLog.d/fix_build_error_for_mbedtls_deprecated_removed.txt
index a70521a..f0fa000 100644
--- a/ChangeLog.d/fix_build_error_for_mbedtls_deprecated_removed.txt
+++ b/ChangeLog.d/fix_build_error_for_mbedtls_deprecated_removed.txt
@@ -1,3 +1,3 @@
 Bugfix
-    * Fix build error due to missing prototype
-      warning when MBEDTLS_DEPRECATED_REMOVED is enabled
+    * Fix a build error due to a missing prototype warning when
+      MBEDTLS_DEPRECATED_REMOVED is enabled.
diff --git a/ChangeLog.d/fix_build_tls1_2_with_single_encryption_type.txt b/ChangeLog.d/fix_build_tls1_2_with_single_encryption_type.txt
index bac4910..c7d2691 100644
--- a/ChangeLog.d/fix_build_tls1_2_with_single_encryption_type.txt
+++ b/ChangeLog.d/fix_build_tls1_2_with_single_encryption_type.txt
@@ -1,4 +1,3 @@
 Bugfix
-    * Fix bugs and missing dependencies when
-      building and testing configurations with
-      only one encryption type enabled in TLS 1.2.
+    * Fix bugs and missing dependencies when building and testing
+      configurations with only one encryption type enabled in TLS 1.2.
diff --git a/ChangeLog.d/fix_cmake_gen_files b/ChangeLog.d/fix_cmake_gen_files
deleted file mode 100644
index 3b2c099..0000000
--- a/ChangeLog.d/fix_cmake_gen_files
+++ /dev/null
@@ -1,3 +0,0 @@
-Bugfix
-   * Fix an issue in releases with GEN_FILES turned off whereby missing
-     generated files could be turned into symlinks to themselves.
diff --git a/ChangeLog.d/fix_cmake_gen_files.txt b/ChangeLog.d/fix_cmake_gen_files.txt
new file mode 100644
index 0000000..cdec6e8
--- /dev/null
+++ b/ChangeLog.d/fix_cmake_gen_files.txt
@@ -0,0 +1,4 @@
+Bugfix
+   * Fix an issue with in-tree CMake builds in releases with GEN_FILES
+     turned off: if a shipped file was missing from the working directory,
+     it could be turned into a symbolic link to itself.
diff --git a/ChangeLog.d/fix_cmake_using_iar_toolchain.txt b/ChangeLog.d/fix_cmake_using_iar_toolchain.txt
index ecc09c2..9ec6e0d 100644
--- a/ChangeLog.d/fix_cmake_using_iar_toolchain.txt
+++ b/ChangeLog.d/fix_cmake_using_iar_toolchain.txt
@@ -1,3 +1,3 @@
 Bugfix
-   * Fixed an issue that cause compile error using CMake IAR toolchain.
+   * Fix a compilation error when using CMake with an IAR toolchain.
      Fixes #5964.
diff --git a/ChangeLog.d/fix_hard_link_across_drives b/ChangeLog.d/fix_hard_link_across_drives
deleted file mode 100644
index 0c55c30..0000000
--- a/ChangeLog.d/fix_hard_link_across_drives
+++ /dev/null
@@ -1,3 +0,0 @@
-Bugfix
-   * Fix a build issue on Windows where the source and build directory could not be on
-     different drives (#5751).
diff --git a/ChangeLog.d/fix_hard_link_across_drives.txt b/ChangeLog.d/fix_hard_link_across_drives.txt
new file mode 100644
index 0000000..46d05c0
--- /dev/null
+++ b/ChangeLog.d/fix_hard_link_across_drives.txt
@@ -0,0 +1,3 @@
+Bugfix
+   * Fix a build issue on Windows using CMake where the source and build
+     directories could not be on different drives. Fixes #5751.
diff --git a/ChangeLog.d/fix_tls13_session_resumption_fail_when_hostname_is_not_localhost.txt b/ChangeLog.d/fix_tls13_session_resumption_fail_when_hostname_is_not_localhost.txt
index 5797f48..9f5c649 100644
--- a/ChangeLog.d/fix_tls13_session_resumption_fail_when_hostname_is_not_localhost.txt
+++ b/ChangeLog.d/fix_tls13_session_resumption_fail_when_hostname_is_not_localhost.txt
@@ -1,4 +1,4 @@
 Bugfix
-    * Fix TLS 1.3 session resumption fail. Fixes #6488.
-    * Add configuration check to exclude TLS 1.3 optional authentication of
-      client.
+    * Fix TLS 1.3 session resumption. Fixes #6488.
+    * Add a configuration check to exclude optional client authentication
+      in TLS 1.3 (where it is forbidden).
diff --git a/ChangeLog.d/fix_zeroization.txt b/ChangeLog.d/fix_zeroization.txt
index ad74d9c..8b00dcc 100644
--- a/ChangeLog.d/fix_zeroization.txt
+++ b/ChangeLog.d/fix_zeroization.txt
@@ -1,3 +1,3 @@
 Bugfix
-   * Fix possible crash in TLS PRF code, if a failure to allocate memory occurs.
-     Reported by Michael Madsen in #6516.
+   * Fix a possible null pointer dereference if a memory allocation fails
+     in TLS PRF code. Reported by Michael Madsen in #6516.
diff --git a/ChangeLog.d/mbedtls_asn1_type_free.txt b/ChangeLog.d/mbedtls_asn1_type_free.txt
index 81f3a20..3459bbe 100644
--- a/ChangeLog.d/mbedtls_asn1_type_free.txt
+++ b/ChangeLog.d/mbedtls_asn1_type_free.txt
@@ -1,6 +1,8 @@
 Features
-   * Shared code to free x509 structs like mbedtls_x509_named_data
+   * The new functions mbedtls_asn1_free_named_data_list() and
+     mbedtls_asn1_free_named_data_list_shallow() simplify the management
+     of memory in named data lists in X.509 structures.
 New deprecations
    * Deprecate mbedtls_asn1_free_named_data().
      Use mbedtls_asn1_free_named_data_list()
-     or mbedtls_asn1_free_named_data_list_shallow()
+     or mbedtls_asn1_free_named_data_list_shallow().
diff --git a/ChangeLog.d/pkcs7-parser.txt b/ChangeLog.d/pkcs7-parser.txt
deleted file mode 100644
index 7f85f0c..0000000
--- a/ChangeLog.d/pkcs7-parser.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-Features
-   * Added partial support for parsing the PKCS7 cryptographic message syntax,
-     as defined in RFC 2315. Currently, support is limited to the following:
-     - Only the signed data content type, version 1 is supported.
-     - Only DER encoding is supported.
-     - Only a single digest algorithm per message is supported.
-     - Only 0 or 1, certificate is supported per message, which must be in
-       X509 format.
-     - There is no support for certificate-revocation lists.
-     - The authenticated and unauthenticated attribute fields of SignerInfo
-       must be empty.
-     Many thanks to Daniel Axtens, Nayna Jain, and Nick Child from IBM for
-     contributing this feature.
diff --git a/ChangeLog.d/psa_crypto_code_gen_1_1.txt b/ChangeLog.d/psa_crypto_code_gen_1_1.txt
index 2c18e6f..e10a81c 100644
--- a/ChangeLog.d/psa_crypto_code_gen_1_1.txt
+++ b/ChangeLog.d/psa_crypto_code_gen_1_1.txt
@@ -1,6 +1,13 @@
 Features
-    * Brought in PSA code geneneration JSON driver list.
-      Added auto generated templating support for key management.
-      Added Support for transparent and opaque keys (import/export/copy).
-      Included some general JSON validation for the given entry points.
-      Addresses version 1.1 of #5137.
+    * The PSA driver wrapper generator generate_driver_wrappers.py now
+      supports a subset of the driver description language, including
+      the following entry points: import_key, export_key, export_public_key,
+      get_builtin_key, copy_key.
+
+Requirement changes
+   * When building with PSA drivers using generate_driver_wrappers.py, or
+     when building the library from the development branch rather than
+     from a release, the Python module jsonschema is now necessary, in
+     addition to jinja2. The official list of required Python modules is
+     maintained in scripts/basic.requirements.txt and may change again
+     in the future.
diff --git a/ChangeLog.d/remove_ssl_session_compression.txt b/ChangeLog.d/remove_ssl_session_compression.txt
deleted file mode 100644
index dc59f1c..0000000
--- a/ChangeLog.d/remove_ssl_session_compression.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Removals
-   * Remove compression property from SSL session struct.
-     MBEDTLS_SSL_COMPRESS_NULL is now the only supported
-     compression option and can be used for compatibility
-     reasons. Changes requested in #4223.
diff --git a/ChangeLog.d/tls13-misc.txt b/ChangeLog.d/tls13-misc.txt
index 497ed38..6733173 100644
--- a/ChangeLog.d/tls13-misc.txt
+++ b/ChangeLog.d/tls13-misc.txt
@@ -1,9 +1,8 @@
 Features
-   * Mbed TLS supports TLS 1.3 key establishment via pre-shared keys,
-     pre-shared keys provisioned externally or via the ticket mechanism
-     (session resumption).
-     The MBEDTLS_SSL_SESSION_TICKETS configuration option controls the support
-     for the ticket mechanism.
-     MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_xxx_ENABLED configuration options
-     have been introduced to control the support for the three possible
-     TLS 1.3 key exchange modes.
+   * Mbed TLS now supports TLS 1.3 key establishment via pre-shared keys.
+     The pre-shared keys can be provisioned externally or via the ticket
+     mechanism (session resumption).
+     The ticket mechanism is supported when the configuration option
+     MBEDTLS_SSL_SESSION_TICKETS is enabled.
+     New options MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_xxx_ENABLED
+     control the support for the three possible TLS 1.3 key exchange modes.
diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h
index f65034d..6b2e280 100644
--- a/include/mbedtls/mbedtls_config.h
+++ b/include/mbedtls/mbedtls_config.h
@@ -2817,6 +2817,10 @@
 /**
  * \def MBEDTLS_PKCS7_C
  *
+ * This feature is a work in progress and not ready for production. Testing and
+ * validation is incomplete, and handling of malformed inputs may not be robust.
+ * The API may change.
+ *
  * Enable PKCS7 core for using PKCS7 formatted signatures.
  * RFC Link - https://tools.ietf.org/html/rfc2315
  *
@@ -2828,7 +2832,7 @@
  *
  * This module is required for the PKCS7 parsing modules.
  */
-#define MBEDTLS_PKCS7_C
+//#define MBEDTLS_PKCS7_C
 
 /**
  * \def MBEDTLS_PKCS12_C
diff --git a/include/mbedtls/pkcs7.h b/include/mbedtls/pkcs7.h
index 12a9cd6..bf61a63 100644
--- a/include/mbedtls/pkcs7.h
+++ b/include/mbedtls/pkcs7.h
@@ -22,6 +22,11 @@
  */
 
 /**
+ * This feature is a work in progress and not ready for production. The API may
+ * change. Furthermore, please note that the implementation has only been
+ * validated with well-formed inputs, not yet with untrusted inputs (which is
+ * almost always the case in practice).
+ *
  * Note: For the time being, this implementation of the PKCS7 cryptographic
  * message syntax is a partial implementation of RFC 2315.
  * Differences include:
@@ -179,7 +184,7 @@
  *
  * \param pkcs7    The pkcs7 structure to be filled by parser for the output.
  * \param buf      The buffer holding the DER encoded pkcs7.
- * \param buflen   The size in Bytes of \p buf.
+ * \param buflen   The size in bytes of \p buf.
  *
  * \note           This function makes an internal copy of the PKCS7 buffer
  *                 \p buf. In particular, \p buf may be destroyed or reused
@@ -192,7 +197,18 @@
                              const size_t buflen );
 
 /**
- * \brief          Verification of PKCS7 signature.
+ * \brief          Verification of PKCS7 signature against a caller-supplied
+ *                 certificate.
+ *
+ *                 For each signer in the PKCS structure, this function computes
+ *                 a signature over the supplied data, using the supplied
+ *                 certificate and the same digest algorithm as specified by the
+ *                 signer. It then compares this signature against the
+ *                 signer's signature; verification succeeds if any comparison
+ *                 matches.
+ *
+ *                 This function does not use the certificates held within the
+ *                 PKCS7 structure itself.
  *
  * \param pkcs7    PKCS7 structure containing signature.
  * \param cert     Certificate containing key to verify signature.
@@ -202,7 +218,7 @@
  * \note           This function internally calculates the hash on the supplied
  *                 plain data for signature verification.
  *
- * \return         A negative error code on failure.
+ * \return         0 if the signature verifies, or a negative error code on failure.
  */
 int mbedtls_pkcs7_signed_data_verify( mbedtls_pkcs7 *pkcs7,
                                       const mbedtls_x509_crt *cert,
@@ -210,7 +226,18 @@
                                       size_t datalen );
 
 /**
- * \brief          Verification of PKCS7 signature.
+ * \brief          Verification of PKCS7 signature against a caller-supplied
+ *                 certificate.
+ *
+ *                 For each signer in the PKCS structure, this function computes
+ *                 a signature over the supplied hash, using the supplied
+ *                 certificate and the same digest algorithm as specified by the
+ *                 signer. It then compares this signature against the
+ *                 signer's signature; verification succeeds if any comparison
+ *                 matches.
+ *
+ *                 This function does not use the certificates held within the
+ *                 PKCS7 structure itself.
  *
  * \param pkcs7    PKCS7 structure containing signature.
  * \param cert     Certificate containing key to verify signature.
@@ -220,7 +247,7 @@
  * \note           This function is different from mbedtls_pkcs7_signed_data_verify()
  *                 in a way that it directly receives the hash of the data.
  *
- * \return         A negative error code on failure.
+ * \return         0 if the signature verifies, or a negative error code on failure.
  */
 int mbedtls_pkcs7_signed_hash_verify( mbedtls_pkcs7 *pkcs7,
                                       const mbedtls_x509_crt *cert,
diff --git a/library/bignum_mod.c b/library/bignum_mod.c
index 7a5539d..7cf2fb2 100644
--- a/library/bignum_mod.c
+++ b/library/bignum_mod.c
@@ -179,7 +179,18 @@
 /* END MERGE SLOT 2 */
 
 /* BEGIN MERGE SLOT 3 */
+int mbedtls_mpi_mod_sub( mbedtls_mpi_mod_residue *X,
+                         const mbedtls_mpi_mod_residue *A,
+                         const mbedtls_mpi_mod_residue *B,
+                         const mbedtls_mpi_mod_modulus *N )
+{
+    if( X->limbs != N->limbs || A->limbs != N->limbs || B->limbs != N->limbs )
+        return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
 
+    mbedtls_mpi_mod_raw_sub( X->p, A->p, B->p, N );
+
+    return( 0 );
+}
 /* END MERGE SLOT 3 */
 
 /* BEGIN MERGE SLOT 4 */
diff --git a/library/bignum_mod.h b/library/bignum_mod.h
index d92f21e..0a8f4d3 100644
--- a/library/bignum_mod.h
+++ b/library/bignum_mod.h
@@ -163,7 +163,35 @@
 /* END MERGE SLOT 2 */
 
 /* BEGIN MERGE SLOT 3 */
-
+/**
+ * \brief Perform a fixed-size modular subtraction.
+ *
+ * Calculate `A - B modulo N`.
+ *
+ * \p A, \p B and \p X must all have the same number of limbs as \p N.
+ *
+ * \p X may be aliased to \p A or \p B, or even both, but may not overlap
+ * either otherwise.
+ *
+ * \note This function does not check that \p A or \p B are in canonical
+ *       form (that is, are < \p N) - that will have been done by
+ *       mbedtls_mpi_mod_residue_setup().
+ *
+ * \param[out] X    The address of the result MPI. Must be initialized.
+ *                  Must have the same number of limbs as the modulus \p N.
+ * \param[in]  A    The address of the first MPI.
+ * \param[in]  B    The address of the second MPI.
+ * \param[in]  N    The address of the modulus. Used to perform a modulo
+ *                  operation on the result of the subtraction.
+ *
+ * \return          \c 0 if successful.
+ * \return          #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if the given MPIs do not
+ *                  have the correct number of limbs.
+ */
+int mbedtls_mpi_mod_sub( mbedtls_mpi_mod_residue *X,
+                         const mbedtls_mpi_mod_residue *A,
+                         const mbedtls_mpi_mod_residue *B,
+                         const mbedtls_mpi_mod_modulus *N );
 /* END MERGE SLOT 3 */
 
 /* BEGIN MERGE SLOT 4 */
diff --git a/scripts/mbedtls_dev/bignum_mod.py b/scripts/mbedtls_dev/bignum_mod.py
index 81ece07..aa06fe8 100644
--- a/scripts/mbedtls_dev/bignum_mod.py
+++ b/scripts/mbedtls_dev/bignum_mod.py
@@ -34,6 +34,20 @@
 
 # BEGIN MERGE SLOT 3
 
+class BignumModSub(bignum_common.ModOperationCommon, BignumModTarget):
+    """Test cases for bignum mpi_mod_sub()."""
+    symbol = "-"
+    test_function = "mpi_mod_sub"
+    test_name = "mbedtls_mpi_mod_sub"
+    input_style = "fixed"
+    arity = 2
+
+    def result(self) -> List[str]:
+        result = (self.int_a - self.int_b) % self.int_n
+        # To make negative tests easier, append 0 for success to the
+        # generated cases
+        return [self.format_result(result), "0"]
+
 # END MERGE SLOT 3
 
 # BEGIN MERGE SLOT 4
diff --git a/tests/suites/test_suite_bignum_mod.data b/tests/suites/test_suite_bignum_mod.data
index 2ea4a58..501d9d7 100644
--- a/tests/suites/test_suite_bignum_mod.data
+++ b/tests/suites/test_suite_bignum_mod.data
@@ -17,6 +17,27 @@
 
 # BEGIN MERGE SLOT 3
 
+mpi_mod_sub base case for negative testing (N, a, b all >= 1 limb)
+mpi_mod_sub:"014320a022ccb75bdf470ddf25":"000000025a55a46e5da99c71c7":"00033b2e3c9fd0803ce8000f93":"013fe57440828b4a0008aa4159":0
+
+mpi_mod_sub with modulus too long/both inputs too short
+mpi_mod_sub:"0000000014320a022ccb75bdf470ddf25":"000000025a55a46e5da99c71c7":"00033b2e3c9fd0803ce8000f93":"00":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
+mpi_mod_sub with first input too long
+mpi_mod_sub:"014320a022ccb75bdf470ddf25":"0000000000000025a55a46e5da99c71c7":"00033b2e3c9fd0803ce8000f93":"00":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
+mpi_mod_sub with second input too long
+mpi_mod_sub:"014320a022ccb75bdf470ddf25":"000000025a55a46e5da99c71c7":"000000000033b2e3c9fd0803ce8000f93":"00":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
+mpi_mod_sub with both inputs too long
+mpi_mod_sub:"014320a022ccb75bdf470ddf25":"0000000000000025a55a46e5da99c71c7":"000000000033b2e3c9fd0803ce8000f93":"00":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
+mpi_mod_sub with first input too short
+mpi_mod_sub:"014320a022ccb75bdf470ddf25":"a99c71c7":"00033b2e3c9fd0803ce8000f93":"00":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
+mpi_mod_sub with second input too short
+mpi_mod_sub:"014320a022ccb75bdf470ddf25":"000000025a55a46e5da99c71c7":"e8000f93":"00":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
 # END MERGE SLOT 3
 
 # BEGIN MERGE SLOT 4
diff --git a/tests/suites/test_suite_bignum_mod.function b/tests/suites/test_suite_bignum_mod.function
index a941cb6..0d2e232 100644
--- a/tests/suites/test_suite_bignum_mod.function
+++ b/tests/suites/test_suite_bignum_mod.function
@@ -4,6 +4,47 @@
 #include "bignum_mod.h"
 #include "constant_time_internal.h"
 #include "test/constant_flow.h"
+
+#define TEST_COMPARE_MPI_RESIDUES( a, b ) \
+            ASSERT_COMPARE( (a).p, (a).limbs * sizeof(mbedtls_mpi_uint), \
+                            (b).p, (b).limbs * sizeof(mbedtls_mpi_uint) )
+
+static int test_read_modulus( mbedtls_mpi_mod_modulus *m,
+                              mbedtls_mpi_mod_rep_selector int_rep,
+                              char *input )
+{
+    mbedtls_mpi_uint *p = NULL;
+    size_t limbs;
+
+    int ret = mbedtls_test_read_mpi_core( &p, &limbs, input );
+    if( ret != 0 )
+        return( ret );
+
+    return( mbedtls_mpi_mod_modulus_setup( m, p, limbs, int_rep ) );
+}
+
+static int test_read_residue( mbedtls_mpi_mod_residue *r,
+                              const mbedtls_mpi_mod_modulus *m,
+                              char *input,
+                              int skip_limbs_and_value_checks )
+{
+    mbedtls_mpi_uint *p = NULL;
+    size_t limbs;
+
+    int ret = mbedtls_test_read_mpi_core( &p, &limbs, input );
+    if( ret != 0 )
+        return( ret );
+
+    if( skip_limbs_and_value_checks )
+    {
+        r->p = p;
+        r->limbs = limbs;
+        return( 0 );
+    }
+
+    /* mbedtls_mpi_mod_residue_setup() checks limbs, and that value < m */
+    return( mbedtls_mpi_mod_residue_setup( r, m, p, limbs ) );
+}
 /* END_HEADER */
 
 /* BEGIN_DEPENDENCIES
@@ -64,7 +105,104 @@
 /* END MERGE SLOT 2 */
 
 /* BEGIN MERGE SLOT 3 */
+/* BEGIN_CASE */
+void mpi_mod_sub( char * input_N,
+                  char * input_A, char * input_B,
+                  char * input_D, int oret )
+{
+    mbedtls_mpi_mod_residue a = { NULL, 0 };
+    mbedtls_mpi_mod_residue b = { NULL, 0 };
+    mbedtls_mpi_mod_residue d = { NULL, 0 };
+    mbedtls_mpi_mod_residue x = { NULL, 0 };
+    mbedtls_mpi_uint *X_raw = NULL;
 
+    mbedtls_mpi_mod_modulus m;
+    mbedtls_mpi_mod_modulus_init( &m );
+
+    TEST_EQUAL( 0,
+        test_read_modulus( &m, MBEDTLS_MPI_MOD_REP_MONTGOMERY, input_N ) );
+
+    /* test_read_residue() normally checks that inputs have the same number of
+     * limbs as the modulus. For negative testing we can ask it to skip this
+     * with a non-zero final parameter. */
+    TEST_EQUAL( 0, test_read_residue( &a, &m, input_A, oret != 0 ) );
+    TEST_EQUAL( 0, test_read_residue( &b, &m, input_B, oret != 0 ) );
+    TEST_EQUAL( 0, test_read_residue( &d, &m, input_D, oret != 0 ) );
+
+    size_t limbs = m.limbs;
+    size_t bytes = limbs * sizeof( *X_raw );
+
+    /* One spare limb for negative testing */
+    ASSERT_ALLOC( X_raw, limbs + 1 );
+
+    if( oret == 0 )
+    {
+        /* Sneak in a couple of negative tests on known-good data */
+
+        /* First, negative test with too many limbs in output */
+        x.p = X_raw;
+        x.limbs = limbs + 1;
+        TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                    mbedtls_mpi_mod_sub( &x, &a, &b, &m ) );
+
+        /* Then negative test with too few limbs in output */
+        if( limbs > 1 )
+        {
+            x.p = X_raw;
+            x.limbs = limbs - 1;
+            TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
+                        mbedtls_mpi_mod_sub( &x, &a, &b, &m ) );
+        }
+
+        /* Negative testing with too many/too few limbs in a and b is covered by
+         * manually-written test cases with oret != 0. */
+
+        /* Back to the normally-scheduled programme */
+    }
+
+    TEST_EQUAL( 0, mbedtls_mpi_mod_residue_setup( &x, &m, X_raw, limbs ) );
+
+    /* a - b => Correct result, or expected error */
+    TEST_EQUAL( oret, mbedtls_mpi_mod_sub( &x, &a, &b, &m ) );
+    if( oret != 0 )
+        goto exit;
+
+    TEST_COMPARE_MPI_RESIDUES( x, d );
+
+    /* a - b: alias x to a => Correct result */
+    memcpy( x.p, a.p, bytes );
+    TEST_EQUAL( 0, mbedtls_mpi_mod_sub( &x, &x, &b, &m ) );
+    TEST_COMPARE_MPI_RESIDUES( x, d );
+
+    /* a - b: alias x to b => Correct result */
+    memcpy( x.p, b.p, bytes );
+    TEST_EQUAL( 0, mbedtls_mpi_mod_sub( &x, &a, &x, &m ) );
+    TEST_COMPARE_MPI_RESIDUES( x, d );
+
+    if ( memcmp( a.p, b.p, bytes ) == 0 )
+    {
+        /* a == b: alias a and b */
+
+        /* a - a => Correct result */
+        TEST_EQUAL( 0, mbedtls_mpi_mod_sub( &x, &a, &a, &m ) );
+        TEST_COMPARE_MPI_RESIDUES( x, d );
+
+        /* a - a: x, a, b all aliased together => Correct result */
+        memcpy( x.p, a.p, bytes );
+        TEST_EQUAL( 0, mbedtls_mpi_mod_sub( &x, &x, &x, &m ) );
+        TEST_COMPARE_MPI_RESIDUES( x, d );
+    }
+
+exit:
+    mbedtls_free( (void *)m.p ); /* mbedtls_mpi_mod_modulus_free() sets m.p = NULL */
+    mbedtls_mpi_mod_modulus_free( &m );
+
+    mbedtls_free( a.p );
+    mbedtls_free( b.p );
+    mbedtls_free( d.p );
+    mbedtls_free( X_raw );
+}
+/* END_CASE */
 /* END MERGE SLOT 3 */
 
 /* BEGIN MERGE SLOT 4 */