Merge pull request #7260 from daverodgman/test-macro-cleanup

Remove duplicate test macros
diff --git a/ChangeLog.d/driver-only-ecdsa.txt b/ChangeLog.d/driver-only-ecdsa.txt
new file mode 100644
index 0000000..645a723
--- /dev/null
+++ b/ChangeLog.d/driver-only-ecdsa.txt
@@ -0,0 +1,7 @@
+Features
+   * When a PSA driver for ECDSA is present, it is now possible to disable
+     MBEDTLS_ECDSA_C in the build in order to save code size. For PK, X.509
+     and TLS to fully work, this requires MBEDTLS_USE_PSA_CRYPTO to be enabled.
+     Restartable/interruptible ECDSA operations in PK, X.509 and TLS are not
+     supported in those builds yet, as driver support for interruptible ECDSA
+     operations is not present yet.
diff --git a/ChangeLog.d/mbedtls_ssl_read_undefined_behavior.txt b/ChangeLog.d/mbedtls_ssl_read_undefined_behavior.txt
new file mode 100644
index 0000000..1f2c563
--- /dev/null
+++ b/ChangeLog.d/mbedtls_ssl_read_undefined_behavior.txt
@@ -0,0 +1,3 @@
+Bugfix
+   * Fix undefined behavior in mbedtls_ssl_read() and mbedtls_ssl_write() if
+     len argument is 0 and buffer is NULL.
diff --git a/docs/use-psa-crypto.md b/docs/use-psa-crypto.md
index fc5317a..c63e65a 100644
--- a/docs/use-psa-crypto.md
+++ b/docs/use-psa-crypto.md
@@ -11,12 +11,15 @@
 `psa_crypto_init()` before calling any function from the SSL/TLS, X.509 or PK
 module.
 
-**Scope:** `MBEDTLS_USE_PSA_CRYPTO` has no effect on the parts of the code that
-are specific to TLS 1.3; those parts always use PSA Crypto. The parts of the
-TLS 1.3 code that are common with TLS 1.2, however, follow this option;
-currently this is the record protection code, computation of the running
-handshake hash, and X.509. You need to enable `MBEDTLS_USE_PSA_CRYPTO` if you
-want TLS 1.3 to use PSA everywhere.
+**Scope:** `MBEDTLS_USE_PSA_CRYPTO` has no effect on the most of the TLS 1.3
+code, which always uses PSA crypto. The parts of the TLS 1.3 code that will
+use PSA Crypto or not depending on the value of this option are:
+- record protection;
+- running handshake hash;
+- asymmetric signature verification & generation;
+- X.509 certificate chain verification.
+You need to enable `MBEDTLS_USE_PSA_CRYPTO` if you want TLS 1.3 to use PSA
+everywhere.
 
 New APIs / API extensions
 -------------------------
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index 2e02e9a..ca60a9d 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -279,9 +279,20 @@
 #error "MBEDTLS_HMAC_DRBG_C defined, but not all prerequisites"
 #endif
 
+/* Helper for ECDSA dependencies, will be undefined at the end of the file */
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#if defined(PSA_HAVE_FULL_ECDSA)
+#define MBEDTLS_PK_HAVE_ECDSA
+#endif
+#else /* MBEDTLS_USE_PSA_CRYPTO */
+#if defined(MBEDTLS_ECDSA_C)
+#define MBEDTLS_PK_HAVE_ECDSA
+#endif
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
 #if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) &&                 \
     ( !defined(MBEDTLS_ECDH_C) ||                                       \
-      !(defined(MBEDTLS_ECDSA_C) || defined(PSA_HAVE_FULL_ECDSA)) ||     \
+      !defined(MBEDTLS_PK_HAVE_ECDSA) ||                                \
       !defined(MBEDTLS_X509_CRT_PARSE_C) )
 #error "MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED defined, but not all prerequisites"
 #endif
@@ -313,9 +324,9 @@
 #error "MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED defined, but not all prerequisites"
 #endif
 
-#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) &&                 \
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) &&                \
     ( !defined(MBEDTLS_ECDH_C) ||                                       \
-      !(defined(MBEDTLS_ECDSA_C) || defined(PSA_HAVE_FULL_ECDSA)) ||     \
+      !defined(MBEDTLS_PK_HAVE_ECDSA) ||                                \
       !defined(MBEDTLS_X509_CRT_PARSE_C) )
 #error "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED defined, but not all prerequisites"
 #endif
@@ -772,7 +783,7 @@
 
 #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
 #if !( defined(MBEDTLS_ECDH_C) && defined(MBEDTLS_X509_CRT_PARSE_C) && \
-       ( defined(MBEDTLS_ECDSA_C) || defined(MBEDTLS_PKCS1_V21) ) )
+       ( defined(MBEDTLS_PK_HAVE_ECDSA) || defined(MBEDTLS_PKCS1_V21) ) )
 #error "MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED defined, but not all prerequisites"
 #endif
 #endif
@@ -1068,6 +1079,9 @@
 #error  "MBEDTLS_PKCS7_C is defined, but not all prerequisites"
 #endif
 
+/* Undefine helper symbols */
+#undef MBEDTLS_PK_HAVE_ECDSA
+
 /*
  * Avoid warning from -pedantic. This is a convenient place for this
  * workaround since this is included by every single file before the
diff --git a/include/mbedtls/config_psa.h b/include/mbedtls/config_psa.h
index 77cb1a9..568d8c2 100644
--- a/include/mbedtls/config_psa.h
+++ b/include/mbedtls/config_psa.h
@@ -310,11 +310,6 @@
 #define PSA_HAVE_SOFT_BLOCK_AEAD 1
 #endif
 
-#if defined(PSA_WANT_ALG_ECDSA) && defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR) && \
-    defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
-#define PSA_HAVE_FULL_ECDSA 1
-#endif
-
 #if defined(PSA_WANT_KEY_TYPE_AES)
 #if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_AES)
 #define PSA_HAVE_SOFT_KEY_TYPE_AES 1
@@ -848,6 +843,11 @@
 
 #endif /* MBEDTLS_PSA_CRYPTO_CONFIG */
 
+#if defined(PSA_WANT_ALG_ECDSA) && defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR) && \
+    defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
+#define PSA_HAVE_FULL_ECDSA 1
+#endif
+
 /* These features are always enabled. */
 #define PSA_WANT_KEY_TYPE_DERIVE 1
 #define PSA_WANT_KEY_TYPE_PASSWORD 1
diff --git a/library/ssl_msg.c b/library/ssl_msg.c
index 1cad588..18c19f9 100644
--- a/library/ssl_msg.c
+++ b/library/ssl_msg.c
@@ -5599,8 +5599,10 @@
     n = (len < ssl->in_msglen)
         ? len : ssl->in_msglen;
 
-    memcpy(buf, ssl->in_offt, n);
-    ssl->in_msglen -= n;
+    if (len != 0) {
+        memcpy(buf, ssl->in_offt, n);
+        ssl->in_msglen -= n;
+    }
 
     /* Zeroising the plaintext buffer to erase unused application data
        from the memory. */
@@ -5676,7 +5678,9 @@
          */
         ssl->out_msglen  = len;
         ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA;
-        memcpy(ssl->out_msg, buf, len);
+        if (len > 0) {
+            memcpy(ssl->out_msg, buf, len);
+        }
 
         if ((ret = mbedtls_ssl_write_record(ssl, SSL_FORCE_FLUSH)) != 0) {
             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_record", ret);
diff --git a/tests/data_files/Makefile b/tests/data_files/Makefile
index 80bdd25..e638caf 100644
--- a/tests/data_files/Makefile
+++ b/tests/data_files/Makefile
@@ -1306,6 +1306,11 @@
 	$(FAKETIME) -f -3650d $(OPENSSL) req -x509 -subj="/C=NL/O=PKCS7/CN=PKCS7 Cert Expired" -sha256 -nodes -days 365  -newkey rsa:2048 -keyout pkcs7-rsa-expired.key -out pkcs7-rsa-expired.crt
 all_final += pkcs7-rsa-expired.crt
 
+# File with an otherwise valid signature signed with an expired cert
+pkcs7_data_rsa_expired.der: pkcs7-rsa-expired.key pkcs7-rsa-expired.crt pkcs7_data.bin
+	$(OPENSSL) smime -sign -binary -in pkcs7_data.bin -out $@ -md sha256 -inkey pkcs7-rsa-expired.key -signer pkcs7-rsa-expired.crt -noattr -outform DER -out $@
+all_final += pkcs7_data_rsa_expired.der
+
 # Convert signing certs to DER for testing PEM-free builds
 pkcs7-rsa-sha256-1.der: $(pkcs7_test_cert_1)
 	$(OPENSSL) x509 -in pkcs7-rsa-sha256-1.crt -out $@ -outform DER
@@ -1315,6 +1320,10 @@
 	$(OPENSSL) x509 -in pkcs7-rsa-sha256-2.crt -out $@ -outform DER
 all_final += pkcs7-rsa-sha256-2.der
 
+pkcs7-rsa-expired.der: pkcs7-rsa-expired.crt
+	$(OPENSSL) x509 -in pkcs7-rsa-expired.crt -out $@ -outform DER
+all_final += pkcs7-rsa-expired.der
+
 # pkcs7 signature file over zero-len data
 pkcs7_zerolendata_detached.der: pkcs7_zerolendata.bin pkcs7-rsa-sha256-1.key pkcs7-rsa-sha256-1.crt
 	$(OPENSSL) smime -sign -md sha256 -nocerts -noattr -in pkcs7_zerolendata.bin -inkey pkcs7-rsa-sha256-1.key -outform DER -binary -signer pkcs7-rsa-sha256-1.crt -out pkcs7_zerolendata_detached.der
diff --git a/tests/data_files/pkcs7-rsa-expired.der b/tests/data_files/pkcs7-rsa-expired.der
new file mode 100644
index 0000000..508ec5c
--- /dev/null
+++ b/tests/data_files/pkcs7-rsa-expired.der
Binary files differ
diff --git a/tests/data_files/pkcs7_data_no_signers.der b/tests/data_files/pkcs7_data_no_signers.der
new file mode 100644
index 0000000..b75c991
--- /dev/null
+++ b/tests/data_files/pkcs7_data_no_signers.der
Binary files differ
diff --git a/tests/data_files/pkcs7_data_rsa_expired.der b/tests/data_files/pkcs7_data_rsa_expired.der
new file mode 100644
index 0000000..63af49d
--- /dev/null
+++ b/tests/data_files/pkcs7_data_rsa_expired.der
Binary files differ
diff --git a/tests/suites/test_suite_pkcs7.data b/tests/suites/test_suite_pkcs7.data
index ffeec49..89c223d 100644
--- a/tests/suites/test_suite_pkcs7.data
+++ b/tests/suites/test_suite_pkcs7.data
@@ -10,6 +10,10 @@
 depends_on:MBEDTLS_SHA256_C
 pkcs7_parse:"data_files/pkcs7_data_without_cert_signed.der":MBEDTLS_PKCS7_SIGNED_DATA
 
+PKCS7 Signed Data Parse with zero signers
+depends_on:MBEDTLS_SHA256_C
+pkcs7_parse:"data_files/pkcs7_data_no_signers.der":MBEDTLS_PKCS7_SIGNED_DATA
+
 PKCS7 Signed Data Parse Fail with multiple certs #4
 depends_on:MBEDTLS_SHA256_C:MBEDTLS_RSA_C
 pkcs7_parse:"data_files/pkcs7_data_multiple_certs_signed.der":MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE
@@ -130,10 +134,22 @@
 depends_on:MBEDTLS_SHA256_C:MBEDTLS_SHA512_C
 pkcs7_verify:"data_files/pkcs7_data_multiple_signed.der":"data_files/pkcs7-rsa-sha256-1.crt data_files/pkcs7-rsa-sha256-2.crt":"data_files/pkcs7_data.bin":MBEDTLS_MD_SHA512:MBEDTLS_ERR_PKCS7_VERIFY_FAIL
 
-PKCS7 Signed Data Verify Fail Expired Cert #19
-depends_on:MBEDTLS_SHA256_C
+PKCS7 Signed Data Verify Pass Expired Cert #19 no TIME_DATE
+depends_on:MBEDTLS_SHA256_C:!MBEDTLS_HAVE_TIME_DATE
+pkcs7_verify:"data_files/pkcs7_data_rsa_expired.der":"data_files/pkcs7-rsa-expired.crt":"data_files/pkcs7_data.bin":0:0
+
+PKCS7 Signed Data Verify Fail Expired Cert #19 have DATE_TIME
+depends_on:MBEDTLS_SHA256_C:MBEDTLS_HAVE_TIME_DATE
 pkcs7_verify:"data_files/pkcs7_data_cert_signed_sha256.der":"data_files/pkcs7-rsa-expired.crt":"data_files/pkcs7_data.bin":0:MBEDTLS_ERR_PKCS7_CERT_DATE_INVALID
 
+PKCS7 Signed Data Verify Fail Expired Cert #19 no DATE_TIME 1
+depends_on:MBEDTLS_SHA256_C:!MBEDTLS_HAVE_TIME_DATE
+pkcs7_verify:"data_files/pkcs7_data_cert_signed_sha256.der":"data_files/pkcs7-rsa-expired.crt":"data_files/pkcs7_data.bin":0:MBEDTLS_ERR_RSA_VERIFY_FAILED
+
+PKCS7 Signed Data Verify Fail Expired Cert #19 no TIME_DATE 2
+depends_on:MBEDTLS_SHA256_C:!MBEDTLS_HAVE_TIME_DATE
+pkcs7_verify:"data_files/pkcs7_data_rsa_expired.der":"data_files/pkcs7-rsa-expired.crt":"data_files/pkcs7_data_1.bin":0:MBEDTLS_ERR_RSA_VERIFY_FAILED
+
 PKCS7 Parse Failure Invalid ASN1: Add null byte to start #20.0
 depends_on:MBEDTLS_SHA256_C
 pkcs7_asn1_fail:"003082050006092a864886f70d010702a08204f1308204ed020101310f300d06096086480165030402010500300b06092a864886f70d010701a082034d3082034930820231a00302010202147bdeddd2444cd1cdfe5c41a8102c89b7df2e6cbf300d06092a864886f70d01010b05003034310b3009060355040613024e4c310e300c060355040a0c05504b4353373115301306035504030c0c504b43533720436572742031301e170d3232313032383136313035365a170d3233313032383136313035365a3034310b3009060355040613024e4c310e300c060355040a0c05504b4353373115301306035504030c0c504b4353372043657274203130820122300d06092a864886f70d01010105000382010f003082010a0282010100c8b6cf69899cd1f0ebb4ca645c05e70e0d2efeddcc61d089cbd515a39a3579b92343b61ec750060fb4ed37876332400e425f1d376c7e75c2973314edf4bb30c8f8dd03b9fcff955a245d49137ad6e60056cac19552a865d52187187cc042c9c49e3e3a9c17a534b453cdabc0cb113b4f63f5b3174b9ee9902b1910d11496a279a74326adcfee10bfd9e7ebafbb377be9b63959165d13dd5751171cadad3c1d3adac68bc8011d61b54cf60178be36839a89ac91ab419e3ca37d6ba881d25518c4db68bca6f7c83602f699a86b17fb1e773bcbe74bb93a49b251ae86428b5740e1868bb1d6fab9e28712e98ec319ad8fca4d73010c4b09c4b80458961e7cf083530203010001a3533051301d0603551d0e041604148aeee5947cc67c5dd515a76e2a7ecd31ee52fdc8301f0603551d230418301680148aeee5947cc67c5dd515a76e2a7ecd31ee52fdc8300f0603551d130101ff040530030101ff300d06092a864886f70d01010b05000382010100821d6b98cd457debd2b081aca27ebecd4f93acc828443b39eabffa9fa4e9e4543b46fcc31e2b5b48177903dea6969ac4a2cc6570650390f1b08d43a4c2f975c7ed8bf3356c7218380212451a8f11de46553cbcd65b4254ddb8f66834eb21dda2a8f33b581e1484557aca1b94ee8931ddf16037b7a7171321a91936afc27ffce395de75d5f70cb8b5aee05ff507088d65af1e43966cd42cbe6f7facf8dae055dd8222b1696521723f81245178595c985ae917fd4b3998773e1a97b7bd10085446f4259bcc09a454929282c1b89b71ed587a775e0a3d4536341f45dae969e806c96fefc71067776c02ba22122b9199b14c0c28c04487509070b97f3dd2d6d972733182017730820173020101304c3034310b3009060355040613024e4c310e300c060355040a0c05504b4353373115301306035504030c0c504b4353372043657274203102147bdeddd2444cd1cdfe5c41a8102c89b7df2e6cbf300d06096086480165030402010500300d06092a864886f70d0101010500048201005becd87195c1deff90c24c91269b55b3f069bc225c326c314c1a51786ffe14c830be4e4bc73cba36c97677b44168279be91e7cdf7c19386ae21862719d13a3a0fff0803d460962f2cda8371484873252c3d7054db8143e2b081a3816ed0804ca5099ae5fece83d5c2c3783b1988b4b46dc94e55587a107ea1546bf22d28a097f652a4066dc2965269069af2f5176bb8ce9ca6d11f96757f03204f756703587d00ad424796c92fc7aeb6f494431999eda30990e4f5773632ed258fe0276673599da6fce35cdad7726a0bb024cad996b88e0cb98854ceb5c0b6ec748d9f9ce6a6cd437858bacb814618a272ff3a415c6e07f3db0988777fdec845a97bf7d102dd0"
diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function
index f486021..9dfb7ed 100644
--- a/tests/suites/test_suite_ssl.function
+++ b/tests/suites/test_suite_ssl.function
@@ -1165,6 +1165,12 @@
                                int buf_len, int *written,
                                const int expected_fragments)
 {
+    /* Verify that calling mbedtls_ssl_write with a NULL buffer and zero length is
+     * a valid no-op for TLS connections. */
+    if (ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
+        TEST_ASSERT(mbedtls_ssl_write(ssl, NULL, 0) == 0);
+    }
+
     int ret = mbedtls_ssl_write(ssl, buf + *written, buf_len - *written);
     if (ret > 0) {
         *written += ret;
@@ -1203,6 +1209,12 @@
                               int buf_len, int *read,
                               int *fragments, const int expected_fragments)
 {
+    /* Verify that calling mbedtls_ssl_write with a NULL buffer and zero length is
+     * a valid no-op for TLS connections. */
+    if (ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
+        TEST_ASSERT(mbedtls_ssl_read(ssl, NULL, 0) == 0);
+    }
+
     int ret = mbedtls_ssl_read(ssl, buf + *read, buf_len - *read);
     if (ret > 0) {
         (*fragments)++;