Merge pull request #9638 from gilles-peskine-arm/ssl-opt-sample-programs-dev

Test sample programs in ssl-opt.sh
diff --git a/programs/ssl/dtls_client.c b/programs/ssl/dtls_client.c
index ddb3c34..f7f417f 100644
--- a/programs/ssl/dtls_client.c
+++ b/programs/ssl/dtls_client.c
@@ -9,18 +9,17 @@
 
 #include "mbedtls/platform.h"
 
-#if !defined(MBEDTLS_SSL_CLI_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) ||    \
-    !defined(MBEDTLS_NET_C)  || !defined(MBEDTLS_TIMING_C) ||             \
-    !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_CTR_DRBG_C) ||        \
-    !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_RSA_C) ||      \
-    !defined(MBEDTLS_PEM_PARSE_C)
+#if !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_CTR_DRBG_C) ||      \
+    !defined(MBEDTLS_NET_C) || !defined(MBEDTLS_SSL_CLI_C) ||           \
+    !defined(MBEDTLS_TIMING_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) ||   \
+    !defined(MBEDTLS_PEM_PARSE_C) || !defined(MBEDTLS_X509_CRT_PARSE_C)
 int main(void)
 {
-    mbedtls_printf("MBEDTLS_SSL_CLI_C and/or MBEDTLS_SSL_PROTO_DTLS and/or "
-                   "MBEDTLS_NET_C and/or MBEDTLS_TIMING_C and/or "
-                   "MBEDTLS_ENTROPY_C and/or MBEDTLS_CTR_DRBG_C and/or "
-                   "MBEDTLS_X509_CRT_PARSE_C and/or MBEDTLS_RSA_C and/or "
-                   "MBEDTLS_PEM_PARSE_C not defined.\n");
+    mbedtls_printf("MBEDTLS_ENTROPY_C and/or MBEDTLS_CTR_DRBG_C and/or "
+                   "MBEDTLS_NET_C and/or MBEDTLS_SSL_CLI_C and/or "
+                   "MBEDTLS_TIMING_C and/or MBEDTLS_SSL_PROTO_DTLS and/or "
+                   "MBEDTLS_PEM_PARSE_C and/or MBEDTLS_X509_CRT_PARSE_C "
+                   "not defined.\n");
     mbedtls_exit(0);
 }
 #else
@@ -45,7 +44,7 @@
 #ifdef FORCE_IPV4
 #define SERVER_ADDR "127.0.0.1"     /* Forces IPv4 */
 #else
-#define SERVER_ADDR "::1"
+#define SERVER_ADDR SERVER_NAME
 #endif
 
 #define MESSAGE     "Echo this"
@@ -99,7 +98,6 @@
     mbedtls_ctr_drbg_init(&ctr_drbg);
     mbedtls_entropy_init(&entropy);
 
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
     psa_status_t status = psa_crypto_init();
     if (status != PSA_SUCCESS) {
         mbedtls_fprintf(stderr, "Failed to initialize PSA Crypto implementation: %d\n",
@@ -107,7 +105,6 @@
         ret = MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
         goto exit;
     }
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
 
     mbedtls_printf("\n  . Seeding the random number generator...");
     fflush(stdout);
@@ -326,9 +323,7 @@
     mbedtls_ssl_config_free(&conf);
     mbedtls_ctr_drbg_free(&ctr_drbg);
     mbedtls_entropy_free(&entropy);
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
     mbedtls_psa_crypto_free();
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
 
     /* Shell can not handle large exit numbers -> 1 for errors */
     if (ret < 0) {
@@ -337,6 +332,5 @@
 
     mbedtls_exit(ret);
 }
-#endif /* MBEDTLS_SSL_CLI_C && MBEDTLS_SSL_PROTO_DTLS && MBEDTLS_NET_C &&
-          MBEDTLS_TIMING_C && MBEDTLS_ENTROPY_C && MBEDTLS_CTR_DRBG_C &&
-          MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_RSA_C && MBEDTLS_PEM_PARSE_C */
+
+#endif /* configuration allows running this program */
diff --git a/programs/ssl/dtls_server.c b/programs/ssl/dtls_server.c
index 732625e..20e53d3 100644
--- a/programs/ssl/dtls_server.c
+++ b/programs/ssl/dtls_server.c
@@ -18,19 +18,19 @@
 #define BIND_IP     "::"
 #endif
 
-#if !defined(MBEDTLS_SSL_SRV_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) ||    \
-    !defined(MBEDTLS_SSL_COOKIE_C) || !defined(MBEDTLS_NET_C) ||          \
-    !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_CTR_DRBG_C) ||        \
-    !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_RSA_C) ||      \
-    !defined(MBEDTLS_PEM_PARSE_C) || !defined(MBEDTLS_TIMING_C)
-
+#if !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_CTR_DRBG_C) ||      \
+    !defined(MBEDTLS_NET_C) || !defined(MBEDTLS_SSL_SRV_C) ||           \
+    !defined(MBEDTLS_TIMING_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) ||   \
+    !defined(MBEDTLS_SSL_COOKIE_C) ||                                   \
+    !defined(MBEDTLS_PEM_PARSE_C) || !defined(MBEDTLS_X509_CRT_PARSE_C)
 int main(void)
 {
-    printf("MBEDTLS_SSL_SRV_C and/or MBEDTLS_SSL_PROTO_DTLS and/or "
-           "MBEDTLS_SSL_COOKIE_C and/or MBEDTLS_NET_C and/or "
-           "MBEDTLS_ENTROPY_C and/or MBEDTLS_CTR_DRBG_C and/or "
-           "MBEDTLS_X509_CRT_PARSE_C and/or MBEDTLS_RSA_C and/or "
-           "MBEDTLS_PEM_PARSE_C and/or MBEDTLS_TIMING_C not defined.\n");
+    mbedtls_printf("MBEDTLS_ENTROPY_C and/or MBEDTLS_CTR_DRBG_C and/or "
+                   "MBEDTLS_NET_C and/or MBEDTLS_SSL_SRV_C and/or "
+                   "MBEDTLS_TIMING_C and/or MBEDTLS_SSL_PROTO_DTLS and/or "
+                   "MBEDTLS_SSL_COOKIE_C and/or "
+                   "MBEDTLS_PEM_PARSE_C and/or MBEDTLS_X509_CRT_PARSE_C "
+                   "not defined.\n");
     mbedtls_exit(0);
 }
 #else
@@ -107,7 +107,6 @@
     mbedtls_entropy_init(&entropy);
     mbedtls_ctr_drbg_init(&ctr_drbg);
 
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
     psa_status_t status = psa_crypto_init();
     if (status != PSA_SUCCESS) {
         mbedtls_fprintf(stderr, "Failed to initialize PSA Crypto implementation: %d\n",
@@ -115,7 +114,6 @@
         ret = MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
         goto exit;
     }
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
 
 #if defined(MBEDTLS_DEBUG_C)
     mbedtls_debug_set_threshold(DEBUG_LEVEL);
@@ -391,9 +389,7 @@
 #endif
     mbedtls_ctr_drbg_free(&ctr_drbg);
     mbedtls_entropy_free(&entropy);
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
     mbedtls_psa_crypto_free();
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
 
     /* Shell can not handle large exit numbers -> 1 for errors */
     if (ret < 0) {
@@ -402,7 +398,5 @@
 
     mbedtls_exit(ret);
 }
-#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_PROTO_DTLS &&
-          MBEDTLS_SSL_COOKIE_C && MBEDTLS_NET_C && MBEDTLS_ENTROPY_C &&
-          MBEDTLS_CTR_DRBG_C && MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_RSA_C
-          && MBEDTLS_PEM_PARSE_C && MBEDTLS_TIMING_C */
+
+#endif /* configuration allows running this program */
diff --git a/programs/ssl/mini_client.c b/programs/ssl/mini_client.c
index ba0195c..cac630e 100644
--- a/programs/ssl/mini_client.c
+++ b/programs/ssl/mini_client.c
@@ -165,13 +165,11 @@
 #endif
     mbedtls_entropy_init(&entropy);
 
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
     psa_status_t status = psa_crypto_init();
     if (status != PSA_SUCCESS) {
         ret = MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
         goto exit;
     }
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
 
     if (mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
                               (const unsigned char *) pers, strlen(pers)) != 0) {
@@ -265,9 +263,7 @@
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
     mbedtls_x509_crt_free(&ca);
 #endif
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
     mbedtls_psa_crypto_free();
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
 
     mbedtls_exit(ret);
 }
diff --git a/programs/ssl/ssl_client1.c b/programs/ssl/ssl_client1.c
index ee734b1..a6ab858 100644
--- a/programs/ssl/ssl_client1.c
+++ b/programs/ssl/ssl_client1.c
@@ -9,17 +9,14 @@
 
 #include "mbedtls/platform.h"
 
-#if !defined(MBEDTLS_BIGNUM_C) || !defined(MBEDTLS_ENTROPY_C) ||     \
-    !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_CLI_C) ||    \
-    !defined(MBEDTLS_NET_C) || !defined(MBEDTLS_RSA_C) ||            \
-    !defined(MBEDTLS_PEM_PARSE_C) || !defined(MBEDTLS_CTR_DRBG_C) || \
-    !defined(MBEDTLS_X509_CRT_PARSE_C)
+#if !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_CTR_DRBG_C) ||      \
+    !defined(MBEDTLS_NET_C) || !defined(MBEDTLS_SSL_CLI_C) ||           \
+    !defined(MBEDTLS_PEM_PARSE_C) || !defined(MBEDTLS_X509_CRT_PARSE_C)
 int main(void)
 {
-    mbedtls_printf("MBEDTLS_BIGNUM_C and/or MBEDTLS_ENTROPY_C and/or "
-                   "MBEDTLS_SSL_TLS_C and/or MBEDTLS_SSL_CLI_C and/or "
-                   "MBEDTLS_NET_C and/or MBEDTLS_RSA_C and/or "
-                   "MBEDTLS_CTR_DRBG_C and/or MBEDTLS_X509_CRT_PARSE_C "
+    mbedtls_printf("MBEDTLS_ENTROPY_C and/or MBEDTLS_CTR_DRBG_C and/or "
+                   "MBEDTLS_NET_C and/or MBEDTLS_SSL_CLI_C and/or "
+                   "MBEDTLS_PEM_PARSE_C and/or MBEDTLS_X509_CRT_PARSE_C "
                    "not defined.\n");
     mbedtls_exit(0);
 }
@@ -81,14 +78,12 @@
     mbedtls_ctr_drbg_init(&ctr_drbg);
     mbedtls_entropy_init(&entropy);
 
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
     psa_status_t status = psa_crypto_init();
     if (status != PSA_SUCCESS) {
         mbedtls_fprintf(stderr, "Failed to initialize PSA Crypto implementation: %d\n",
                         (int) status);
         goto exit;
     }
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
 
     mbedtls_printf("\n  . Seeding the random number generator...");
     fflush(stdout);
@@ -240,6 +235,9 @@
         }
 
         if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
+            mbedtls_printf("The return value %d from mbedtls_ssl_read() means that the server\n"
+                           "closed the connection first. We're ok with that.\n",
+                           MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY);
             break;
         }
 
@@ -259,7 +257,9 @@
 
     mbedtls_ssl_close_notify(&ssl);
 
-    exit_code = MBEDTLS_EXIT_SUCCESS;
+    if (ret == 0 || ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
+        exit_code = MBEDTLS_EXIT_SUCCESS;
+    }
 
 exit:
 
@@ -277,12 +277,9 @@
     mbedtls_ssl_config_free(&conf);
     mbedtls_ctr_drbg_free(&ctr_drbg);
     mbedtls_entropy_free(&entropy);
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
     mbedtls_psa_crypto_free();
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
 
     mbedtls_exit(exit_code);
 }
-#endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ENTROPY_C && MBEDTLS_SSL_TLS_C &&
-          MBEDTLS_SSL_CLI_C && MBEDTLS_NET_C && MBEDTLS_RSA_C &&
-          MBEDTLS_PEM_PARSE_C && MBEDTLS_CTR_DRBG_C && MBEDTLS_X509_CRT_PARSE_C */
+
+#endif /* configuration allows running this program */
diff --git a/programs/ssl/ssl_context_info.c b/programs/ssl/ssl_context_info.c
index 51e8781..cbe9c6d 100644
--- a/programs/ssl/ssl_context_info.c
+++ b/programs/ssl/ssl_context_info.c
@@ -925,14 +925,12 @@
     size_t ssl_max_len = SSL_INIT_LEN;
     size_t ssl_len = 0;
 
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
     psa_status_t status = psa_crypto_init();
     if (status != PSA_SUCCESS) {
         mbedtls_fprintf(stderr, "Failed to initialize PSA Crypto implementation: %d\n",
                         (int) status);
         return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
     }
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
 
     /* The 'b64_file' is opened when parsing arguments to check that the
      * file name is correct */
@@ -1002,9 +1000,7 @@
         printf("Finished. No valid base64 code found\n");
     }
 
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
     mbedtls_psa_crypto_free();
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
 
     return 0;
 }
diff --git a/programs/ssl/ssl_fork_server.c b/programs/ssl/ssl_fork_server.c
index f4822b7..9b36507 100644
--- a/programs/ssl/ssl_fork_server.c
+++ b/programs/ssl/ssl_fork_server.c
@@ -9,22 +9,15 @@
 
 #include "mbedtls/platform.h"
 
-#if !defined(MBEDTLS_BIGNUM_C) || !defined(MBEDTLS_ENTROPY_C) ||          \
-    !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_SRV_C) ||         \
-    !defined(MBEDTLS_NET_C) || !defined(MBEDTLS_RSA_C) ||                 \
-    !defined(MBEDTLS_CTR_DRBG_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \
-    !defined(MBEDTLS_TIMING_C) || !defined(MBEDTLS_FS_IO) ||              \
-    !defined(MBEDTLS_PEM_PARSE_C)
-int main(int argc, char *argv[])
+#if !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_CTR_DRBG_C) ||      \
+    !defined(MBEDTLS_NET_C) || !defined(MBEDTLS_SSL_SRV_C) ||           \
+    !defined(MBEDTLS_PEM_PARSE_C) || !defined(MBEDTLS_X509_CRT_PARSE_C)
+int main(void)
 {
-    ((void) argc);
-    ((void) argv);
-
-    mbedtls_printf("MBEDTLS_BIGNUM_C and/or MBEDTLS_ENTROPY_C "
-                   "and/or MBEDTLS_SSL_TLS_C and/or MBEDTLS_SSL_SRV_C and/or "
-                   "MBEDTLS_NET_C and/or MBEDTLS_RSA_C and/or "
-                   "MBEDTLS_CTR_DRBG_C and/or MBEDTLS_X509_CRT_PARSE_C and/or "
-                   "MBEDTLS_TIMING_C and/or MBEDTLS_PEM_PARSE_C not defined.\n");
+    mbedtls_printf("MBEDTLS_ENTROPY_C and/or MBEDTLS_CTR_DRBG_C and/or "
+                   "MBEDTLS_NET_C and/or MBEDTLS_SSL_SRV_C and/or "
+                   "MBEDTLS_PEM_PARSE_C and/or MBEDTLS_X509_CRT_PARSE_C "
+                   "not defined.\n");
     mbedtls_exit(0);
 }
 #elif defined(_WIN32)
@@ -93,14 +86,12 @@
     mbedtls_x509_crt_init(&srvcert);
     mbedtls_ctr_drbg_init(&ctr_drbg);
 
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
     psa_status_t status = psa_crypto_init();
     if (status != PSA_SUCCESS) {
         mbedtls_fprintf(stderr, "Failed to initialize PSA Crypto implementation: %d\n",
                         (int) status);
         goto exit;
     }
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
 
     signal(SIGCHLD, SIG_IGN);
 
@@ -225,6 +216,7 @@
         if (pid != 0) {
             mbedtls_printf(" ok\n");
             mbedtls_net_close(&client_fd);
+            fflush(stdout);
 
             if ((ret = mbedtls_ctr_drbg_reseed(&ctr_drbg,
                                                (const unsigned char *) "parent",
@@ -282,6 +274,7 @@
         }
 
         mbedtls_printf("pid %d: SSL handshake ok\n", pid);
+        fflush(stdout);
 
         /*
          * 6. Read the HTTP Request
@@ -312,12 +305,14 @@
                         mbedtls_printf("pid %d: mbedtls_ssl_read returned %d\n", pid, ret);
                         break;
                 }
+                fflush(stdout);
 
                 break;
             }
 
             len = ret;
             mbedtls_printf("pid %d: %d bytes read\n\n%s", pid, len, (char *) buf);
+            fflush(stdout);
 
             if (ret > 0) {
                 break;
@@ -333,7 +328,7 @@
         len = sprintf((char *) buf, HTTP_RESPONSE,
                       mbedtls_ssl_get_ciphersuite(&ssl));
 
-        while (cnt++ < 100) {
+        while (cnt++ < 10) {
             while ((ret = mbedtls_ssl_write(&ssl, buf, len)) <= 0) {
                 if (ret == MBEDTLS_ERR_NET_CONN_RESET) {
                     mbedtls_printf(
@@ -349,12 +344,16 @@
                 }
             }
             len = ret;
-            mbedtls_printf("pid %d: %d bytes written\n\n%s\n", pid, len, (char *) buf);
+            mbedtls_printf("pid %d: %d bytes written (cnt=%d)\n\n%s\n",
+                           pid, len, cnt, (char *) buf);
+            fflush(stdout);
 
             mbedtls_net_usleep(1000000);
         }
 
         mbedtls_ssl_close_notify(&ssl);
+        mbedtls_printf("pid %d: shutting down\n", pid);
+        fflush(stdout);
         goto exit;
     }
 
@@ -369,9 +368,7 @@
     mbedtls_ssl_config_free(&conf);
     mbedtls_ctr_drbg_free(&ctr_drbg);
     mbedtls_entropy_free(&entropy);
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
     mbedtls_psa_crypto_free();
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
 
     mbedtls_exit(exit_code);
 }
diff --git a/programs/ssl/ssl_mail_client.c b/programs/ssl/ssl_mail_client.c
index e3ed697..bdeef9b 100644
--- a/programs/ssl/ssl_mail_client.c
+++ b/programs/ssl/ssl_mail_client.c
@@ -359,14 +359,12 @@
     mbedtls_ctr_drbg_init(&ctr_drbg);
     mbedtls_entropy_init(&entropy);
 
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
     psa_status_t status = psa_crypto_init();
     if (status != PSA_SUCCESS) {
         mbedtls_fprintf(stderr, "Failed to initialize PSA Crypto implementation: %d\n",
                         (int) status);
         goto exit;
     }
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
 
     if (argc < 2) {
 usage:
@@ -806,9 +804,7 @@
     mbedtls_ssl_config_free(&conf);
     mbedtls_ctr_drbg_free(&ctr_drbg);
     mbedtls_entropy_free(&entropy);
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
     mbedtls_psa_crypto_free();
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
 
     mbedtls_exit(exit_code);
 }
diff --git a/programs/ssl/ssl_pthread_server.c b/programs/ssl/ssl_pthread_server.c
index fcb8f2f..d8213cb 100644
--- a/programs/ssl/ssl_pthread_server.c
+++ b/programs/ssl/ssl_pthread_server.c
@@ -10,20 +10,21 @@
 
 #include "mbedtls/platform.h"
 
-#if !defined(MBEDTLS_BIGNUM_C)  || !defined(MBEDTLS_ENTROPY_C) ||         \
-    !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_SRV_C) ||         \
-    !defined(MBEDTLS_NET_C) || !defined(MBEDTLS_RSA_C) ||                 \
-    !defined(MBEDTLS_CTR_DRBG_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \
-    !defined(MBEDTLS_FS_IO) || !defined(MBEDTLS_THREADING_C) ||           \
-    !defined(MBEDTLS_THREADING_PTHREAD) || !defined(MBEDTLS_PEM_PARSE_C)
+#if !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_CTR_DRBG_C) ||      \
+    !defined(MBEDTLS_NET_C) || !defined(MBEDTLS_SSL_SRV_C) ||           \
+    !defined(MBEDTLS_PEM_PARSE_C) || !defined(MBEDTLS_X509_CRT_PARSE_C)
 int main(void)
 {
-    mbedtls_printf("MBEDTLS_BIGNUM_C and/or MBEDTLS_ENTROPY_C "
-                   "and/or MBEDTLS_SSL_TLS_C and/or MBEDTLS_SSL_SRV_C and/or "
-                   "MBEDTLS_NET_C and/or MBEDTLS_RSA_C and/or "
-                   "MBEDTLS_CTR_DRBG_C and/or MBEDTLS_X509_CRT_PARSE_C and/or "
-                   "MBEDTLS_THREADING_C and/or MBEDTLS_THREADING_PTHREAD "
-                   "and/or MBEDTLS_PEM_PARSE_C not defined.\n");
+    mbedtls_printf("MBEDTLS_ENTROPY_C and/or MBEDTLS_CTR_DRBG_C and/or "
+                   "MBEDTLS_NET_C and/or MBEDTLS_SSL_SRV_C and/or "
+                   "MBEDTLS_PEM_PARSE_C and/or MBEDTLS_X509_CRT_PARSE_C "
+                   "not defined.\n");
+    mbedtls_exit(0);
+}
+#elif !defined(MBEDTLS_THREADING_C) || !defined(MBEDTLS_THREADING_PTHREAD)
+int main(void)
+{
+    mbedtls_printf("MBEDTLS_THREADING_PTHREAD not defined.\n");
     mbedtls_exit(0);
 }
 #else
@@ -123,6 +124,7 @@
      * 5. Handshake
      */
     mbedtls_printf("  [ #%ld ]  Performing the SSL/TLS handshake\n", thread_id);
+    fflush(stdout);
 
     while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) {
         if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
@@ -138,6 +140,7 @@
      * 6. Read the HTTP Request
      */
     mbedtls_printf("  [ #%ld ]  < Read from client\n", thread_id);
+    fflush(stdout);
 
     do {
         len = sizeof(buf) - 1;
@@ -170,6 +173,7 @@
         len = ret;
         mbedtls_printf("  [ #%ld ]  %d bytes read\n=====\n%s\n=====\n",
                        thread_id, len, (char *) buf);
+        fflush(stdout);
 
         if (ret > 0) {
             break;
@@ -180,6 +184,7 @@
      * 7. Write the 200 Response
      */
     mbedtls_printf("  [ #%ld ]  > Write to client:\n", thread_id);
+    fflush(stdout);
 
     len = sprintf((char *) buf, HTTP_RESPONSE,
                   mbedtls_ssl_get_ciphersuite(&ssl));
@@ -201,6 +206,7 @@
     len = ret;
     mbedtls_printf("  [ #%ld ]  %d bytes written\n=====\n%s\n=====\n",
                    thread_id, len, (char *) buf);
+    fflush(stdout);
 
     mbedtls_printf("  [ #%ld ]  . Closing the connection...", thread_id);
 
@@ -214,6 +220,7 @@
     }
 
     mbedtls_printf(" ok\n");
+    fflush(stdout);
 
     ret = 0;
 
@@ -320,7 +327,6 @@
      */
     mbedtls_entropy_init(&entropy);
 
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
     psa_status_t status = psa_crypto_init();
     if (status != PSA_SUCCESS) {
         mbedtls_fprintf(stderr, "Failed to initialize PSA Crypto implementation: %d\n",
@@ -328,7 +334,6 @@
         ret = MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
         goto exit;
     }
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
 
     /*
      * 1a. Seed the random number generator
@@ -442,6 +447,7 @@
      * 3. Wait until a client connects
      */
     mbedtls_printf("  [ main ]  Waiting for a remote connection\n");
+    fflush(stdout);
 
     if ((ret = mbedtls_net_accept(&listen_fd, &client_fd,
                                   NULL, 0, NULL)) != 0) {
@@ -476,14 +482,9 @@
 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
     mbedtls_memory_buffer_alloc_free();
 #endif
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
     mbedtls_psa_crypto_free();
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
 
     mbedtls_exit(ret);
 }
 
-#endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ENTROPY_C &&
-          MBEDTLS_SSL_TLS_C && MBEDTLS_SSL_SRV_C && MBEDTLS_NET_C &&
-          MBEDTLS_RSA_C && MBEDTLS_CTR_DRBG_C && MBEDTLS_THREADING_C &&
-          MBEDTLS_THREADING_PTHREAD && MBEDTLS_PEM_PARSE_C */
+#endif /* configuration allows running this program */
diff --git a/programs/ssl/ssl_server.c b/programs/ssl/ssl_server.c
index 6becf8d..9a90d1d 100644
--- a/programs/ssl/ssl_server.c
+++ b/programs/ssl/ssl_server.c
@@ -9,18 +9,15 @@
 
 #include "mbedtls/platform.h"
 
-#if !defined(MBEDTLS_BIGNUM_C) || !defined(MBEDTLS_PEM_PARSE_C) || \
-    !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_SSL_TLS_C) ||  \
-    !defined(MBEDTLS_SSL_SRV_C) || !defined(MBEDTLS_NET_C) ||      \
-    !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_CTR_DRBG_C) ||     \
-    !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_FS_IO)
+#if !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_CTR_DRBG_C) ||      \
+    !defined(MBEDTLS_NET_C) || !defined(MBEDTLS_SSL_SRV_C) ||           \
+    !defined(MBEDTLS_PEM_PARSE_C) || !defined(MBEDTLS_X509_CRT_PARSE_C)
 int main(void)
 {
-    mbedtls_printf("MBEDTLS_BIGNUM_C and/or MBEDTLS_ENTROPY_C "
-                   "and/or MBEDTLS_SSL_TLS_C and/or MBEDTLS_SSL_SRV_C and/or "
-                   "MBEDTLS_NET_C and/or MBEDTLS_RSA_C and/or "
-                   "MBEDTLS_CTR_DRBG_C and/or MBEDTLS_X509_CRT_PARSE_C "
-                   "and/or MBEDTLS_PEM_PARSE_C not defined.\n");
+    mbedtls_printf("MBEDTLS_ENTROPY_C and/or MBEDTLS_CTR_DRBG_C and/or "
+                   "MBEDTLS_NET_C and/or MBEDTLS_SSL_SRV_C and/or "
+                   "MBEDTLS_PEM_PARSE_C and/or MBEDTLS_X509_CRT_PARSE_C "
+                   "not defined.\n");
     mbedtls_exit(0);
 }
 #else
@@ -92,7 +89,6 @@
     mbedtls_entropy_init(&entropy);
     mbedtls_ctr_drbg_init(&ctr_drbg);
 
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
     psa_status_t status = psa_crypto_init();
     if (status != PSA_SUCCESS) {
         mbedtls_fprintf(stderr, "Failed to initialize PSA Crypto implementation: %d\n",
@@ -100,7 +96,6 @@
         ret = MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
         goto exit;
     }
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
 
 #if defined(MBEDTLS_DEBUG_C)
     mbedtls_debug_set_threshold(DEBUG_LEVEL);
@@ -315,16 +310,19 @@
     mbedtls_printf(" %d bytes written\n\n%s\n", len, (char *) buf);
 
     mbedtls_printf("  . Closing the connection...");
+    fflush(stdout);
 
     while ((ret = mbedtls_ssl_close_notify(&ssl)) < 0) {
         if (ret != MBEDTLS_ERR_SSL_WANT_READ &&
-            ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
+            ret != MBEDTLS_ERR_SSL_WANT_WRITE &&
+            ret != MBEDTLS_ERR_NET_CONN_RESET) {
             mbedtls_printf(" failed\n  ! mbedtls_ssl_close_notify returned %d\n\n", ret);
             goto reset;
         }
     }
 
     mbedtls_printf(" ok\n");
+    fflush(stdout);
 
     ret = 0;
     goto reset;
@@ -350,13 +348,9 @@
 #endif
     mbedtls_ctr_drbg_free(&ctr_drbg);
     mbedtls_entropy_free(&entropy);
-#if defined(MBEDTLS_USE_PSA_CRYPTO)
     mbedtls_psa_crypto_free();
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
 
     mbedtls_exit(ret);
 }
-#endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ENTROPY_C &&
-          MBEDTLS_SSL_TLS_C && MBEDTLS_SSL_SRV_C && MBEDTLS_NET_C &&
-          MBEDTLS_RSA_C && MBEDTLS_CTR_DRBG_C && MBEDTLS_X509_CRT_PARSE_C
-          && MBEDTLS_FS_IO && MBEDTLS_PEM_PARSE_C */
+
+#endif /* configuration allows running this program */
diff --git a/tests/opt-testcases/sample.sh b/tests/opt-testcases/sample.sh
new file mode 100644
index 0000000..e2eaf24
--- /dev/null
+++ b/tests/opt-testcases/sample.sh
@@ -0,0 +1,391 @@
+# Test that SSL sample programs can interoperate with each other
+# and with OpenSSL and GnuTLS.
+
+# Copyright The Mbed TLS Contributors
+# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+: ${PROGRAMS_DIR:=../programs/ssl}
+
+# Disable session tickets for ssl_client1 when potentially using TLS 1.3
+# until https://github.com/Mbed-TLS/mbedtls/issues/6640 is resolved
+# and (if relevant) implemented in ssl_client1.
+run_test    "Sample: ssl_client1, ssl_server2" \
+            -P 4433 \
+            "$PROGRAMS_DIR/ssl_server2 tickets=0" \
+            "$PROGRAMS_DIR/ssl_client1" \
+            0 \
+            -s "[1-9][0-9]* bytes read" \
+            -s "[1-9][0-9]* bytes written" \
+            -c "[1-9][0-9]* bytes read" \
+            -c "[1-9][0-9]* bytes written" \
+            -S "error" \
+            -C "error"
+
+requires_protocol_version tls12
+run_test    "Sample: ssl_client1, openssl server, TLS 1.2" \
+            -P 4433 \
+            "$O_SRV -tls1_2" \
+            "$PROGRAMS_DIR/ssl_client1" \
+            0 \
+            -c "Protocol.*TLSv1.2" \
+            -S "ERROR" \
+            -C "error"
+
+requires_protocol_version tls12
+run_test    "Sample: ssl_client1, gnutls server, TLS 1.2" \
+            -P 4433 \
+            "$G_SRV --priority=NORMAL:-VERS-TLS-ALL:+VERS-TLS1.2" \
+            "$PROGRAMS_DIR/ssl_client1" \
+            0 \
+            -s "Version: TLS1.2" \
+            -c "<TD>Protocol version:</TD><TD>TLS1.2</TD>" \
+            -S "Error" \
+            -C "error"
+
+# Disable session tickets for ssl_client1 when using TLS 1.3
+# until https://github.com/Mbed-TLS/mbedtls/issues/6640 is resolved
+# and (if relevant) implemented in ssl_client1.
+requires_protocol_version tls13
+requires_openssl_tls1_3
+run_test    "Sample: ssl_client1, openssl server, TLS 1.3" \
+            -P 4433 \
+            "$O_NEXT_SRV -tls1_3 -num_tickets 0" \
+            "$PROGRAMS_DIR/ssl_client1" \
+            0 \
+            -c "New, TLSv1.3, Cipher is" \
+            -S "ERROR" \
+            -C "error"
+
+# Disable session tickets for ssl_client1 when using TLS 1.3
+# until https://github.com/Mbed-TLS/mbedtls/issues/6640 is resolved
+# and (if relevant) implemented in ssl_client1.
+requires_protocol_version tls13
+requires_gnutls_tls1_3
+run_test    "Sample: ssl_client1, gnutls server, TLS 1.3" \
+            -P 4433 \
+            "$G_NEXT_SRV --priority=NORMAL:-VERS-TLS-ALL:+VERS-TLS1.3 --noticket" \
+            "$PROGRAMS_DIR/ssl_client1" \
+            0 \
+            -s "Version: TLS1.3" \
+            -c "<TD>Protocol version:</TD><TD>TLS1.3</TD>" \
+            -S "Error" \
+            -C "error"
+
+# The server complains of extra data after it closes the connection
+# because the client keeps sending data, so the server receives
+# more application data when it expects a new handshake. We consider
+# the test a success if both sides have sent and received application
+# data, no matter what happens afterwards.
+run_test    "Sample: dtls_client, ssl_server2" \
+            -P 4433 \
+            "$PROGRAMS_DIR/ssl_server2 dtls=1 server_addr=localhost" \
+            "$PROGRAMS_DIR/dtls_client" \
+            0 \
+            -s "[1-9][0-9]* bytes read" \
+            -s "[1-9][0-9]* bytes written" \
+            -c "[1-9][0-9]* bytes read" \
+            -c "[1-9][0-9]* bytes written" \
+            -C "error"
+
+# The dtls_client program connects to localhost. This test case fails on
+# systems where the name "localhost" resolves to an IPv6 address, but
+# the IPv6 connection is not possible. Possible reasons include:
+# * OpenSSL is too old (IPv6 support was added in 1.1.0).
+# * OpenSSL was built without IPv6 support.
+# * A firewall blocks IPv6.
+#
+# To facilitate working with this test case, have it run with $OPENSSL_NEXT
+# which is at least 1.1.1a. At the time it was introduced, this test case
+# passed with OpenSSL 1.0.2g on an environment where IPv6 is disabled.
+requires_protocol_version dtls12
+run_test    "Sample: dtls_client, openssl server, DTLS 1.2" \
+            -P 4433 \
+            "$O_NEXT_SRV -dtls1_2" \
+            "$PROGRAMS_DIR/dtls_client" \
+            0 \
+            -s "Echo this" \
+            -c "Echo this" \
+            -c "[1-9][0-9]* bytes written" \
+            -c "[1-9][0-9]* bytes read" \
+            -S "ERROR" \
+            -C "error"
+
+requires_protocol_version dtls12
+run_test    "Sample: dtls_client, gnutls server, DTLS 1.2" \
+            -P 4433 \
+            "$G_SRV -u --echo --priority=NORMAL:-VERS-TLS-ALL:+VERS-TLS1.2" \
+            "$PROGRAMS_DIR/dtls_client" \
+            0 \
+            -s "Server listening" \
+            -s "[1-9][0-9]* bytes command:" \
+            -c "Echo this" \
+            -c "[1-9][0-9]* bytes written" \
+            -c "[1-9][0-9]* bytes read" \
+            -S "Error" \
+            -C "error"
+
+run_test    "Sample: ssl_server, ssl_client2" \
+            -P 4433 \
+            "$PROGRAMS_DIR/ssl_server" \
+            "$PROGRAMS_DIR/ssl_client2" \
+            0 \
+            -s "[1-9][0-9]* bytes read" \
+            -s "[1-9][0-9]* bytes written" \
+            -c "[1-9][0-9]* bytes read" \
+            -c "[1-9][0-9]* bytes written" \
+            -S "error" \
+            -C "error"
+
+run_test    "Sample: ssl_client1 with ssl_server" \
+            -P 4433 \
+            "$PROGRAMS_DIR/ssl_server" \
+            "$PROGRAMS_DIR/ssl_client1" \
+            0 \
+            -s "[1-9][0-9]* bytes read" \
+            -s "[1-9][0-9]* bytes written" \
+            -c "[1-9][0-9]* bytes read" \
+            -c "[1-9][0-9]* bytes written" \
+            -S "error" \
+            -C "error"
+
+requires_protocol_version tls12
+run_test    "Sample: ssl_server, openssl client, TLS 1.2" \
+            -P 4433 \
+            "$PROGRAMS_DIR/ssl_server" \
+            "$O_CLI -tls1_2" \
+            0 \
+            -s "Successful connection using: TLS-" \
+            -c "Protocol.*TLSv1.2" \
+            -S "error" \
+            -C "ERROR"
+
+requires_protocol_version tls12
+run_test    "Sample: ssl_server, gnutls client, TLS 1.2" \
+            -P 4433 \
+            "$PROGRAMS_DIR/ssl_server" \
+            "$G_CLI --priority=NORMAL:-VERS-TLS-ALL:+VERS-TLS1.2 localhost" \
+            0 \
+            -s "Successful connection using: TLS-" \
+            -c "Description:.*TLS1.2" \
+            -S "error" \
+            -C "ERROR"
+
+requires_protocol_version tls13
+requires_openssl_tls1_3
+run_test    "Sample: ssl_server, openssl client, TLS 1.3" \
+            -P 4433 \
+            "$PROGRAMS_DIR/ssl_server" \
+            "$O_NEXT_CLI -tls1_3" \
+            0 \
+            -s "Successful connection using: TLS1-3-" \
+            -c "New, TLSv1.3, Cipher is" \
+            -S "error" \
+            -C "ERROR"
+
+requires_protocol_version tls13
+requires_gnutls_tls1_3
+run_test    "Sample: ssl_server, gnutls client, TLS 1.3" \
+            -P 4433 \
+            "$PROGRAMS_DIR/ssl_server" \
+            "$G_NEXT_CLI --priority=NORMAL:-VERS-TLS-ALL:+VERS-TLS1.3 localhost" \
+            0 \
+            -s "Successful connection using: TLS1-3-" \
+            -c "Description:.*TLS1.3" \
+            -S "error" \
+            -C "ERROR"
+
+run_test    "Sample: ssl_fork_server, ssl_client2" \
+            -P 4433 \
+            "$PROGRAMS_DIR/ssl_fork_server" \
+            "$PROGRAMS_DIR/ssl_client2" \
+            0 \
+            -s "[1-9][0-9]* bytes read" \
+            -s "[1-9][0-9]* bytes written" \
+            -c "[1-9][0-9]* bytes read" \
+            -c "[1-9][0-9]* bytes written" \
+            -S "error" \
+            -C "error"
+
+run_test    "Sample: ssl_client1 with ssl_fork_server" \
+            -P 4433 \
+            "$PROGRAMS_DIR/ssl_fork_server" \
+            "$PROGRAMS_DIR/ssl_client1" \
+            0 \
+            -s "[1-9][0-9]* bytes read" \
+            -s "[1-9][0-9]* bytes written" \
+            -c "[1-9][0-9]* bytes read" \
+            -c "[1-9][0-9]* bytes written" \
+            -S "error" \
+            -C "error"
+
+requires_protocol_version tls12
+run_test    "Sample: ssl_fork_server, openssl client, TLS 1.2" \
+            -P 4433 \
+            "$PROGRAMS_DIR/ssl_fork_server" \
+            "$O_CLI -tls1_2" \
+            0 \
+            -s "Successful connection using: TLS-" \
+            -c "Protocol.*TLSv1.2" \
+            -S "error" \
+            -C "ERROR"
+
+requires_protocol_version tls12
+run_test    "Sample: ssl_fork_server, gnutls client, TLS 1.2" \
+            -P 4433 \
+            "$PROGRAMS_DIR/ssl_fork_server" \
+            "$G_CLI --priority=NORMAL:-VERS-TLS-ALL:+VERS-TLS1.2 localhost" \
+            0 \
+            -s "Successful connection using: TLS-" \
+            -c "Description:.*TLS1.2" \
+            -S "error" \
+            -C "ERROR"
+
+requires_protocol_version tls13
+requires_openssl_tls1_3
+run_test    "Sample: ssl_fork_server, openssl client, TLS 1.3" \
+            -P 4433 \
+            "$PROGRAMS_DIR/ssl_fork_server" \
+            "$O_NEXT_CLI -tls1_3" \
+            0 \
+            -s "Successful connection using: TLS1-3-" \
+            -c "New, TLSv1.3, Cipher is" \
+            -S "error" \
+            -C "ERROR"
+
+requires_protocol_version tls13
+requires_gnutls_tls1_3
+run_test    "Sample: ssl_fork_server, gnutls client, TLS 1.3" \
+            -P 4433 \
+            "$PROGRAMS_DIR/ssl_fork_server" \
+            "$G_NEXT_CLI --priority=NORMAL:-VERS-TLS-ALL:+VERS-TLS1.3 localhost" \
+            0 \
+            -s "Successful connection using: TLS1-3-" \
+            -c "Description:.*TLS1.3" \
+            -S "error" \
+            -C "ERROR"
+
+run_test    "Sample: ssl_pthread_server, ssl_client2" \
+            -P 4433 \
+            "$PROGRAMS_DIR/ssl_pthread_server" \
+            "$PROGRAMS_DIR/ssl_client2" \
+            0 \
+            -s "[1-9][0-9]* bytes read" \
+            -s "[1-9][0-9]* bytes written" \
+            -c "[1-9][0-9]* bytes read" \
+            -c "[1-9][0-9]* bytes written" \
+            -S "error" \
+            -C "error"
+
+run_test    "Sample: ssl_client1 with ssl_pthread_server" \
+            -P 4433 \
+            "$PROGRAMS_DIR/ssl_pthread_server" \
+            "$PROGRAMS_DIR/ssl_client1" \
+            0 \
+            -s "[1-9][0-9]* bytes read" \
+            -s "[1-9][0-9]* bytes written" \
+            -c "[1-9][0-9]* bytes read" \
+            -c "[1-9][0-9]* bytes written" \
+            -S "error" \
+            -C "error"
+
+requires_protocol_version tls12
+run_test    "Sample: ssl_pthread_server, openssl client, TLS 1.2" \
+            -P 4433 \
+            "$PROGRAMS_DIR/ssl_pthread_server" \
+            "$O_CLI -tls1_2" \
+            0 \
+            -s "Successful connection using: TLS-" \
+            -c "Protocol.*TLSv1.2" \
+            -S "error" \
+            -C "ERROR"
+
+requires_protocol_version tls12
+run_test    "Sample: ssl_pthread_server, gnutls client, TLS 1.2" \
+            -P 4433 \
+            "$PROGRAMS_DIR/ssl_pthread_server" \
+            "$G_CLI --priority=NORMAL:-VERS-TLS-ALL:+VERS-TLS1.2 localhost" \
+            0 \
+            -s "Successful connection using: TLS-" \
+            -c "Description:.*TLS1.2" \
+            -S "error" \
+            -C "ERROR"
+
+requires_protocol_version tls13
+requires_openssl_tls1_3
+run_test    "Sample: ssl_pthread_server, openssl client, TLS 1.3" \
+            -P 4433 \
+            "$PROGRAMS_DIR/ssl_pthread_server" \
+            "$O_NEXT_CLI -tls1_3" \
+            0 \
+            -s "Successful connection using: TLS1-3-" \
+            -c "New, TLSv1.3, Cipher is" \
+            -S "error" \
+            -C "ERROR"
+
+requires_protocol_version tls13
+requires_gnutls_tls1_3
+run_test    "Sample: ssl_pthread_server, gnutls client, TLS 1.3" \
+            -P 4433 \
+            "$PROGRAMS_DIR/ssl_pthread_server" \
+            "$G_NEXT_CLI --priority=NORMAL:-VERS-TLS-ALL:+VERS-TLS1.3 localhost" \
+            0 \
+            -s "Successful connection using: TLS1-3-" \
+            -c "Description:.*TLS1.3" \
+            -S "error" \
+            -C "ERROR"
+
+# The server complains of extra data after it closes the connection
+# because the client keeps sending data, so the server receives
+# more application data when it expects a new handshake. We consider
+# the test a success if both sides have sent and received application
+# data, no matter what happens afterwards.
+run_test    "Sample: dtls_client with dtls_server" \
+            -P 4433 \
+            "$PROGRAMS_DIR/dtls_server" \
+            "$PROGRAMS_DIR/dtls_client" \
+            0 \
+            -s "[1-9][0-9]* bytes read" \
+            -s "[1-9][0-9]* bytes written" \
+            -c "[1-9][0-9]* bytes read" \
+            -c "[1-9][0-9]* bytes written" \
+            -C "error"
+
+# The server complains of extra data after it closes the connection
+# because the client keeps sending data, so the server receives
+# more application data when it expects a new handshake. We consider
+# the test a success if both sides have sent and received application
+# data, no matter what happens afterwards.
+run_test    "Sample: ssl_client2, dtls_server" \
+            -P 4433 \
+            "$PROGRAMS_DIR/dtls_server" \
+            "$PROGRAMS_DIR/ssl_client2 dtls=1" \
+            0 \
+            -s "[1-9][0-9]* bytes read" \
+            -s "[1-9][0-9]* bytes written" \
+            -c "[1-9][0-9]* bytes read" \
+            -c "[1-9][0-9]* bytes written" \
+            -C "error"
+
+requires_protocol_version dtls12
+run_test    "Sample: dtls_server, openssl client, DTLS 1.2" \
+            -P 4433 \
+            "$PROGRAMS_DIR/dtls_server" \
+            "$O_CLI -dtls1_2" \
+            0 \
+            -s "[1-9][0-9]* bytes read" \
+            -s "[1-9][0-9]* bytes written" \
+            -c "Protocol.*TLSv1.2" \
+            -S "error" \
+            -C "ERROR"
+
+requires_protocol_version dtls12
+run_test    "Sample: dtls_server, gnutls client, DTLS 1.2" \
+            -P 4433 \
+            "$PROGRAMS_DIR/dtls_server" \
+            "$G_CLI -u --priority=NORMAL:-VERS-TLS-ALL:+VERS-TLS1.2 localhost" \
+            0 \
+            -s "[1-9][0-9]* bytes read" \
+            -s "[1-9][0-9]* bytes written" \
+            -c "Description:.*DTLS1.2" \
+            -S "error" \
+            -C "ERROR"
diff --git a/tests/scripts/components-configuration.sh b/tests/scripts/components-configuration.sh
index 9f563a9..683ac84 100644
--- a/tests/scripts/components-configuration.sh
+++ b/tests/scripts/components-configuration.sh
@@ -229,40 +229,6 @@
     ! grep -q -F time.h /usr/include/x86_64-linux-gnu/sys/types.h
 }
 
-component_test_no_psa_crypto_full_cmake_asan () {
-    # full minus MBEDTLS_PSA_CRYPTO_C: run the same set of tests as basic-build-test.sh
-    msg "build: cmake, full config minus PSA crypto, ASan"
-    scripts/config.py full
-    scripts/config.py unset MBEDTLS_PSA_CRYPTO_C
-    scripts/config.py unset MBEDTLS_PSA_CRYPTO_CLIENT
-    scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
-    scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3
-    scripts/config.py unset MBEDTLS_PSA_ITS_FILE_C
-    scripts/config.py unset MBEDTLS_PSA_CRYPTO_SE_C
-    scripts/config.py unset MBEDTLS_PSA_CRYPTO_STORAGE_C
-    scripts/config.py unset MBEDTLS_LMS_C
-    scripts/config.py unset MBEDTLS_LMS_PRIVATE
-    CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
-    make
-
-    msg "test: main suites (full minus PSA crypto)"
-    make test
-
-    # Note: ssl-opt.sh has some test cases that depend on
-    # MBEDTLS_ECP_RESTARTABLE && !MBEDTLS_USE_PSA_CRYPTO
-    # This is the only component where those tests are not skipped.
-    msg "test: ssl-opt.sh (full minus PSA crypto)"
-    tests/ssl-opt.sh
-
-    # Note: the next two invocations cover all compat.sh test cases.
-    # We should use the same here and in basic-build-test.sh.
-    msg "test: compat.sh: default version (full minus PSA crypto)"
-    tests/compat.sh -e 'ARIA\|CHACHA'
-
-    msg "test: compat.sh: next: ARIA, Chacha (full minus PSA crypto)"
-    env OPENSSL="$OPENSSL_NEXT" tests/compat.sh -e '^$' -f 'ARIA\|CHACHA'
-}
-
 component_build_tfm () {
     # Check that the TF-M configuration can build cleanly with various
     # warning flags enabled. We don't build or run tests, since the
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index 6f59963..e7eef1a 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -491,6 +491,37 @@
             requires_certificate_authentication;;
     esac
 
+    case " $CMD_LINE " in
+        *"programs/ssl/dtls_client "*|\
+        *"programs/ssl/ssl_client1 "*)
+            requires_config_enabled MBEDTLS_CTR_DRBG_C
+            requires_config_enabled MBEDTLS_ENTROPY_C
+            requires_config_enabled MBEDTLS_PEM_PARSE_C
+            requires_config_enabled MBEDTLS_SSL_CLI_C
+            requires_certificate_authentication
+            ;;
+        *"programs/ssl/dtls_server "*|\
+        *"programs/ssl/ssl_fork_server "*|\
+        *"programs/ssl/ssl_pthread_server "*|\
+        *"programs/ssl/ssl_server "*)
+            requires_config_enabled MBEDTLS_CTR_DRBG_C
+            requires_config_enabled MBEDTLS_ENTROPY_C
+            requires_config_enabled MBEDTLS_PEM_PARSE_C
+            requires_config_enabled MBEDTLS_SSL_SRV_C
+            requires_certificate_authentication
+            # The actual minimum depends on the configuration since it's
+            # mostly about the certificate size.
+            # In config-suite-b.h, for the test certificates (server5.crt),
+            # 1024 is not enough.
+            requires_config_value_at_least MBEDTLS_SSL_OUT_CONTENT_LEN 2000
+            ;;
+    esac
+
+    case " $CMD_LINE " in
+        *"programs/ssl/ssl_pthread_server "*)
+            requires_config_enabled MBEDTLS_THREADING_PTHREAD;;
+    esac
+
     case "$CMD_LINE" in
         *[-_\ =]psk*|*[-_\ =]PSK*) :;; # No certificate requirement with PSK
         */server5*|\
@@ -1252,7 +1283,7 @@
 # check if the given command uses dtls and sets global variable DTLS
 detect_dtls() {
     case "$1" in
-        *dtls=1*|*-dtls*|*-u*) DTLS=1;;
+        *dtls=1*|*-dtls*|*-u*|*/dtls_*) DTLS=1;;
         *) DTLS=0;;
     esac
 }
@@ -1372,9 +1403,13 @@
 # Outputs:
 # * $CLI_CMD, $PXY_CMD, $SRV_CMD: may be tweaked.
 analyze_test_commands() {
-    # if the test uses DTLS but no custom proxy, add a simple proxy
-    # as it provides timing info that's useful to debug failures
-    if [ -z "$PXY_CMD" ] && [ "$DTLS" -eq 1 ]; then
+    # If the test uses DTLS, does not force a specific port, and does not
+    # specify a custom proxy, add a simple proxy.
+    # It provides timing info that's useful to debug failures.
+    if [ "$DTLS" -eq 1 ] &&
+       [ "$THIS_SRV_PORT" = "$SRV_PORT" ] &&
+       [ -z "$PXY_CMD" ]
+    then
         PXY_CMD="$P_PXY"
         case " $SRV_CMD " in
             *' server_addr=::1 '*)
@@ -1410,7 +1445,20 @@
     if [ -n "$PXY_CMD" ]; then
         CLI_CMD=$( echo "$CLI_CMD" | sed s/+SRV_PORT/$PXY_PORT/g )
     else
-        CLI_CMD=$( echo "$CLI_CMD" | sed s/+SRV_PORT/$SRV_PORT/g )
+        CLI_CMD=$( echo "$CLI_CMD" | sed s/+SRV_PORT/$THIS_SRV_PORT/g )
+    fi
+
+    # If the test forces a specific port and the server is OpenSSL or
+    # GnuTLS, override its port specification.
+    if [ "$THIS_SRV_PORT" != "$SRV_PORT" ]; then
+        case "$SRV_CMD" in
+            "$G_SRV"*|"$G_NEXT_SRV"*)
+                SRV_CMD=$(
+                    printf %s "$SRV_CMD " |
+                    sed -e "s/ -p $SRV_PORT / -p $THIS_SRV_PORT /"
+                );;
+            "$O_SRV"*|"$O_NEXT_SRV"*) SRV_CMD="$SRV_CMD -accept $THIS_SRV_PORT";;
+        esac
     fi
 
     # prepend valgrind to our commands if active
@@ -1609,7 +1657,7 @@
     printf '# %s\n%s\n' "$NAME" "$SRV_CMD" > $SRV_OUT
     provide_input | $SRV_CMD >> $SRV_OUT 2>&1 &
     SRV_PID=$!
-    wait_server_start "$SRV_PORT" "$SRV_PID"
+    wait_server_start "$THIS_SRV_PORT" "$SRV_PID"
 
     printf '# %s\n%s\n' "$NAME" "$CLI_CMD" > $CLI_OUT
     # The client must be a subprocess of the script in order for killing it to
@@ -1732,7 +1780,7 @@
         esac
     fi
 
-    # does this test use a proxy?
+    # Does this test specify a proxy?
     if [ "X$1" = "X-p" ]; then
         PXY_CMD="$2"
         shift 2
@@ -1740,6 +1788,14 @@
         PXY_CMD=""
     fi
 
+    # Does this test force a specific port?
+    if [ "$1" = "-P" ]; then
+        THIS_SRV_PORT="$2"
+        shift 2
+    else
+        THIS_SRV_PORT="$SRV_PORT"
+    fi
+
     # get commands and client output
     SRV_CMD="$1"
     CLI_CMD="$2"
@@ -1761,7 +1817,10 @@
     # Check if we are trying to use an external tool which does not support ECDH
     EXT_WO_ECDH=$(use_ext_tool_without_ecdh_support "$SRV_CMD" "$CLI_CMD")
 
-    # Guess the TLS version which is going to be used
+    # Guess the TLS version which is going to be used.
+    # Note that this detection is wrong in some cases, which causes unduly
+    # skipped test cases in builds with TLS 1.3 but not TLS 1.2.
+    # https://github.com/Mbed-TLS/mbedtls/issues/9560
     if [ "$EXT_WO_ECDH" = "no" ]; then
         TLS_VERSION=$(get_tls_version "$SRV_CMD" "$CLI_CMD")
     else