Merge pull request #8546 from BrianX7c/development
[cipher.h] Arithmetic overflow in binary left shift operation
diff --git a/ChangeLog.d/8482.txt b/ChangeLog.d/8482.txt
new file mode 100644
index 0000000..a392232
--- /dev/null
+++ b/ChangeLog.d/8482.txt
@@ -0,0 +1,6 @@
+Changes
+ * PSA_WANT_ALG_CCM and PSA_WANT_ALG_CCM_STAR_NO_TAG are no more synonyms and
+ they are now treated separately. This means that they should be
+ individually enabled in order to enable respective support; also the
+ corresponding MBEDTLS_PSA_ACCEL symbol should be defined in case
+ acceleration is required.
diff --git a/ChangeLog.d/gnutls_anti_replay_fail.txt b/ChangeLog.d/gnutls_anti_replay_fail.txt
new file mode 100644
index 0000000..cb35284
--- /dev/null
+++ b/ChangeLog.d/gnutls_anti_replay_fail.txt
@@ -0,0 +1,5 @@
+Bugfix
+ * Switch to milliseconds as the unit for ticket creation and reception time
+ instead of seconds. That avoids rounding errors when computing the age of
+ tickets compared to peer using a millisecond clock (observed with GnuTLS).
+ Fixes #6623.
diff --git a/include/mbedtls/config_adjust_legacy_crypto.h b/include/mbedtls/config_adjust_legacy_crypto.h
index e4f6a27..c60e1e3 100644
--- a/include/mbedtls/config_adjust_legacy_crypto.h
+++ b/include/mbedtls/config_adjust_legacy_crypto.h
@@ -311,6 +311,26 @@
#define MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY
#endif
+/* Some internal helpers to determine which keys are availble. */
+#if (!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_AES_C)) || \
+ (defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_KEY_TYPE_AES))
+#define MBEDTLS_SSL_HAVE_AES
+#endif
+#if (!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_ARIA_C)) || \
+ (defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_KEY_TYPE_ARIA))
+#define MBEDTLS_SSL_HAVE_ARIA
+#endif
+#if (!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_CAMELLIA_C)) || \
+ (defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_KEY_TYPE_CAMELLIA))
+#define MBEDTLS_SSL_HAVE_CAMELLIA
+#endif
+
+/* Some internal helpers to determine which operation modes are availble. */
+#if (!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_CIPHER_MODE_CBC)) || \
+ (defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_CBC_NO_PADDING))
+#define MBEDTLS_SSL_HAVE_CBC
+#endif
+
#if (!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_GCM_C)) || \
(defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_GCM))
#define MBEDTLS_SSL_HAVE_GCM
diff --git a/include/mbedtls/config_adjust_legacy_from_psa.h b/include/mbedtls/config_adjust_legacy_from_psa.h
index 6356bdd..bf87c36 100644
--- a/include/mbedtls/config_adjust_legacy_from_psa.h
+++ b/include/mbedtls/config_adjust_legacy_from_psa.h
@@ -847,11 +847,20 @@
defined(PSA_HAVE_SOFT_KEY_TYPE_ARIA) || \
defined(PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA)
#define MBEDTLS_PSA_BUILTIN_ALG_CCM 1
-#define MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG 1
#define MBEDTLS_CCM_C
#endif
#endif /* PSA_WANT_ALG_CCM */
+#if defined(PSA_WANT_ALG_CCM_STAR_NO_TAG)
+#if !defined(MBEDTLS_PSA_ACCEL_ALG_CCM_STAR_NO_TAG) || \
+ defined(PSA_HAVE_SOFT_KEY_TYPE_AES) || \
+ defined(PSA_HAVE_SOFT_KEY_TYPE_ARIA) || \
+ defined(PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA)
+#define MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG 1
+#define MBEDTLS_CCM_C
+#endif
+#endif /* PSA_WANT_ALG_CCM_STAR_NO_TAG */
+
#if defined(PSA_WANT_ALG_GCM)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_GCM) || \
defined(PSA_HAVE_SOFT_KEY_TYPE_AES) || \
diff --git a/include/mbedtls/debug.h b/include/mbedtls/debug.h
index 0aef2ed..9a17488 100644
--- a/include/mbedtls/debug.h
+++ b/include/mbedtls/debug.h
@@ -120,7 +120,12 @@
/* (defined(__MINGW32__) && __USE_MINGW_ANSI_STDIO == 0) || (defined(_MSC_VER) && _MSC_VER < 1800) */
#if !defined(MBEDTLS_PRINTF_MS_TIME)
+#include <inttypes.h>
+#if !defined(PRId64)
+#define MBEDTLS_PRINTF_MS_TIME MBEDTLS_PRINTF_LONGLONG
+#else
#define MBEDTLS_PRINTF_MS_TIME PRId64
+#endif
#endif /* MBEDTLS_PRINTF_MS_TIME */
#ifdef __cplusplus
diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h
index d137f00..a4e90c5 100644
--- a/include/mbedtls/mbedtls_config.h
+++ b/include/mbedtls/mbedtls_config.h
@@ -4099,20 +4099,23 @@
/**
* \def MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE
*
- * Maximum time difference in milliseconds tolerated between the age of a
- * ticket from the server and client point of view.
- * From the client point of view, the age of a ticket is the time difference
- * between the time when the client proposes to the server to use the ticket
- * (time of writing of the Pre-Shared Key Extension including the ticket) and
- * the time the client received the ticket from the server.
- * From the server point of view, the age of a ticket is the time difference
- * between the time when the server receives a proposition from the client
- * to use the ticket and the time when the ticket was created by the server.
- * The server age is expected to be always greater than the client one and
- * MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE defines the
- * maximum difference tolerated for the server to accept the ticket.
- * This is not used in TLS 1.2.
+ * Maximum allowed ticket age difference in milliseconds tolerated between
+ * server and client. Default value is 6000. This is not used in TLS 1.2.
*
+ * - The client ticket age is the time difference between the time when the
+ * client proposes to the server to use the ticket and the time the client
+ * received the ticket from the server.
+ * - The server ticket age is the time difference between the time when the
+ * server receives a proposition from the client to use the ticket and the
+ * time when the ticket was created by the server.
+ *
+ * The ages might be different due to the client and server clocks not running
+ * at the same pace. The typical accuracy of an RTC crystal is ±100 to ±20 parts
+ * per million (360 to 72 milliseconds per hour). Default tolerance window is
+ * 6s, thus in the worst case clients and servers must sync up their system time
+ * every 6000/360/2~=8 hours.
+ *
+ * See section 8.3 of the TLS 1.3 specification(RFC 8446) for more information.
*/
//#define MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE 6000
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 30b8685..3c2696f 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -600,26 +600,6 @@
#define MBEDTLS_TLS_EXT_RENEGOTIATION_INFO 0xFF01
-/* Some internal helpers to determine which keys are availble. */
-#if (!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_AES_C)) || \
- (defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_KEY_TYPE_AES))
-#define MBEDTLS_SSL_HAVE_AES
-#endif
-#if (!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_CAMELLIA_C)) || \
- (defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_KEY_TYPE_CAMELLIA))
-#define MBEDTLS_SSL_HAVE_CAMELLIA
-#endif
-#if (!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_ARIA_C)) || \
- (defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_KEY_TYPE_ARIA))
-#define MBEDTLS_SSL_HAVE_ARIA
-#endif
-
-/* Some internal helpers to determine which operation modes are availble. */
-#if (!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_CIPHER_MODE_CBC)) || \
- (defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_CBC_NO_PADDING))
-#define MBEDTLS_SSL_HAVE_CBC
-#endif
-
/*
* Size defines
*/
@@ -1217,7 +1197,7 @@
mbedtls_ssl_protocol_version MBEDTLS_PRIVATE(tls_version);
#if defined(MBEDTLS_HAVE_TIME)
- mbedtls_time_t MBEDTLS_PRIVATE(start); /*!< starting time */
+ mbedtls_time_t MBEDTLS_PRIVATE(start); /*!< start time of current session */
#endif
int MBEDTLS_PRIVATE(ciphersuite); /*!< chosen ciphersuite */
size_t MBEDTLS_PRIVATE(id_len); /*!< session id length */
@@ -1254,12 +1234,21 @@
char *MBEDTLS_PRIVATE(hostname); /*!< host name binded with tickets */
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION && MBEDTLS_SSL_CLI_C */
-#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_CLI_C)
- mbedtls_time_t MBEDTLS_PRIVATE(ticket_received); /*!< time ticket was received */
-#endif /* MBEDTLS_HAVE_TIME && MBEDTLS_SSL_CLI_C */
+#if defined(MBEDTLS_HAVE_TIME)
+#if defined(MBEDTLS_SSL_CLI_C)
+ mbedtls_ms_time_t MBEDTLS_PRIVATE(ticket_reception_time); /*!< time when ticket was received. */
+#endif
+#if defined(MBEDTLS_SSL_SRV_C)
+ mbedtls_ms_time_t MBEDTLS_PRIVATE(ticket_creation_time); /*!< time when ticket was created. */
+#endif
+#endif /* MBEDTLS_HAVE_TIME */
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_SESSION_TICKETS */
+#if defined(MBEDTLS_SSL_EARLY_DATA)
+ uint32_t MBEDTLS_PRIVATE(max_early_data_size); /*!< maximum amount of early data in tickets */
+#endif
+
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
int MBEDTLS_PRIVATE(encrypt_then_mac); /*!< flag for EtM activation */
#endif
@@ -2046,6 +2035,10 @@
*
* \warning This interface is experimental and may change without notice.
*
+ * \warning This interface DOES NOT influence/limit the amount of early data
+ * that can be received through previously created and issued tickets,
+ * which clients may have stored.
+ *
*/
void mbedtls_ssl_conf_max_early_data_size(
mbedtls_ssl_config *conf, uint32_t max_early_data_size);
diff --git a/include/psa/crypto_adjust_config_synonyms.h b/include/psa/crypto_adjust_config_synonyms.h
index cf33465..332b622 100644
--- a/include/psa/crypto_adjust_config_synonyms.h
+++ b/include/psa/crypto_adjust_config_synonyms.h
@@ -24,12 +24,6 @@
#define PSA_WANT_ALG_ECDSA_ANY PSA_WANT_ALG_ECDSA
#endif
-#if defined(PSA_WANT_ALG_CCM_STAR_NO_TAG) && !defined(PSA_WANT_ALG_CCM)
-#define PSA_WANT_ALG_CCM PSA_WANT_ALG_CCM_STAR_NO_TAG
-#elif !defined(PSA_WANT_ALG_CCM_STAR_NO_TAG) && defined(PSA_WANT_ALG_CCM)
-#define PSA_WANT_ALG_CCM_STAR_NO_TAG PSA_WANT_ALG_CCM
-#endif
-
#if defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN_RAW) && !defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN)
#define PSA_WANT_ALG_RSA_PKCS1V15_SIGN PSA_WANT_ALG_RSA_PKCS1V15_SIGN_RAW
#elif !defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN_RAW) && defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN)
diff --git a/library/ssl_client.c b/library/ssl_client.c
index 7a78406..8d25e69 100644
--- a/library/ssl_client.c
+++ b/library/ssl_client.c
@@ -691,11 +691,6 @@
p_extensions_len, extensions_len);
}
-#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
- MBEDTLS_SSL_PRINT_EXTS(
- 3, MBEDTLS_SSL_HS_CLIENT_HELLO, handshake->sent_extensions);
-#endif
-
*out_len = p - buf;
return 0;
}
@@ -756,10 +751,9 @@
if (ssl->handshake->resume != 0 &&
session_negotiate->tls_version == MBEDTLS_SSL_VERSION_TLS1_3 &&
session_negotiate->ticket != NULL) {
- mbedtls_time_t now = mbedtls_time(NULL);
- uint64_t age = (uint64_t) (now - session_negotiate->ticket_received);
- if (session_negotiate->ticket_received > now ||
- age > session_negotiate->ticket_lifetime) {
+ mbedtls_ms_time_t now = mbedtls_ms_time();
+ mbedtls_ms_time_t age = now - session_negotiate->ticket_reception_time;
+ if (age < 0 || age > session_negotiate->ticket_lifetime * 1000) {
/* Without valid ticket, disable session resumption.*/
MBEDTLS_SSL_DEBUG_MSG(
3, ("Ticket expired, disable session resumption"));
@@ -1007,6 +1001,11 @@
#endif
}
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
+ MBEDTLS_SSL_PRINT_EXTS(
+ 3, MBEDTLS_SSL_HS_CLIENT_HELLO, ssl->handshake->sent_extensions);
+#endif
+
cleanup:
MBEDTLS_SSL_DEBUG_MSG(2, ("<= write client hello"));
diff --git a/library/ssl_misc.h b/library/ssl_misc.h
index 4ddd9c4..c636ad4 100644
--- a/library/ssl_misc.h
+++ b/library/ssl_misc.h
@@ -255,8 +255,7 @@
#if defined(MBEDTLS_SSL_HAVE_CBC) && \
(defined(MBEDTLS_SSL_HAVE_AES) || \
defined(MBEDTLS_SSL_HAVE_CAMELLIA) || \
- defined(MBEDTLS_SSL_HAVE_ARIA) || \
- defined(MBEDTLS_DES_C))
+ defined(MBEDTLS_SSL_HAVE_ARIA))
#define MBEDTLS_SSL_SOME_SUITES_USE_CBC
#endif
@@ -2766,6 +2765,9 @@
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS)
+
+#define MBEDTLS_SSL_TLS1_3_MAX_ALLOWED_TICKET_LIFETIME (604800)
+
static inline unsigned int mbedtls_ssl_session_get_ticket_flags(
mbedtls_ssl_session *session, unsigned int flags)
{
diff --git a/library/ssl_ticket.c b/library/ssl_ticket.c
index 875abcb..61c87be 100644
--- a/library/ssl_ticket.c
+++ b/library/ssl_ticket.c
@@ -495,7 +495,31 @@
}
#if defined(MBEDTLS_HAVE_TIME)
- {
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
+ if (session->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
+ /* Check for expiration */
+ mbedtls_ms_time_t ticket_age = -1;
+#if defined(MBEDTLS_SSL_SRV_C)
+ if (session->endpoint == MBEDTLS_SSL_IS_SERVER) {
+ ticket_age = mbedtls_ms_time() - session->ticket_creation_time;
+ }
+#endif
+#if defined(MBEDTLS_SSL_CLI_C)
+ if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) {
+ ticket_age = mbedtls_ms_time() - session->ticket_reception_time;
+ }
+#endif
+
+ mbedtls_ms_time_t ticket_lifetime = ctx->ticket_lifetime * 1000;
+
+ if (ticket_age < 0 || ticket_age > ticket_lifetime) {
+ ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED;
+ goto cleanup;
+ }
+ }
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+ if (session->tls_version == MBEDTLS_SSL_VERSION_TLS1_2) {
/* Check for expiration */
mbedtls_time_t current_time = mbedtls_time(NULL);
@@ -505,7 +529,8 @@
goto cleanup;
}
}
-#endif
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+#endif /* MBEDTLS_HAVE_TIME */
cleanup:
#if defined(MBEDTLS_THREADING_C)
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 4751d34..b163e93 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -2443,7 +2443,7 @@
*
* struct {
* opaque hostname<0..2^16-1>;
- * uint64 ticket_received;
+ * uint64 ticket_reception_time;
* uint32 ticket_lifetime;
* opaque ticket<1..2^16-1>;
* } ClientOnlyData;
@@ -2454,9 +2454,10 @@
* uint32 ticket_age_add;
* uint8 ticket_flags;
* opaque resumption_key<0..255>;
+ * uint32 max_early_data_size;
* select ( endpoint ) {
* case client: ClientOnlyData;
- * case server: uint64 start_time;
+ * case server: uint64 ticket_creation_time;
* };
* } serialized_session_tls13;
*
@@ -2486,8 +2487,12 @@
}
needed += session->resumption_key_len; /* resumption_key */
+#if defined(MBEDTLS_SSL_EARLY_DATA)
+ needed += 4; /* max_early_data_size */
+#endif
+
#if defined(MBEDTLS_HAVE_TIME)
- needed += 8; /* start_time or ticket_received */
+ needed += 8; /* ticket_creation_time or ticket_reception_time */
#endif
#if defined(MBEDTLS_SSL_CLI_C)
@@ -2525,9 +2530,14 @@
memcpy(p, session->resumption_key, session->resumption_key_len);
p += session->resumption_key_len;
+#if defined(MBEDTLS_SSL_EARLY_DATA)
+ MBEDTLS_PUT_UINT32_BE(session->max_early_data_size, p, 0);
+ p += 4;
+#endif
+
#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C)
if (session->endpoint == MBEDTLS_SSL_IS_SERVER) {
- MBEDTLS_PUT_UINT64_BE((uint64_t) session->start, p, 0);
+ MBEDTLS_PUT_UINT64_BE((uint64_t) session->ticket_creation_time, p, 0);
p += 8;
}
#endif /* MBEDTLS_HAVE_TIME */
@@ -2545,7 +2555,7 @@
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
#if defined(MBEDTLS_HAVE_TIME)
- MBEDTLS_PUT_UINT64_BE((uint64_t) session->ticket_received, p, 0);
+ MBEDTLS_PUT_UINT64_BE((uint64_t) session->ticket_reception_time, p, 0);
p += 8;
#endif
MBEDTLS_PUT_UINT32_BE(session->ticket_lifetime, p, 0);
@@ -2593,12 +2603,20 @@
memcpy(session->resumption_key, p, session->resumption_key_len);
p += session->resumption_key_len;
+#if defined(MBEDTLS_SSL_EARLY_DATA)
+ if (end - p < 4) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+ session->max_early_data_size = MBEDTLS_GET_UINT32_BE(p, 0);
+ p += 4;
+#endif
+
#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C)
if (session->endpoint == MBEDTLS_SSL_IS_SERVER) {
if (end - p < 8) {
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
- session->start = MBEDTLS_GET_UINT64_BE(p, 0);
+ session->ticket_creation_time = MBEDTLS_GET_UINT64_BE(p, 0);
p += 8;
}
#endif /* MBEDTLS_HAVE_TIME */
@@ -2633,7 +2651,7 @@
if (end - p < 8) {
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
- session->ticket_received = MBEDTLS_GET_UINT64_BE(p, 0);
+ session->ticket_reception_time = MBEDTLS_GET_UINT64_BE(p, 0);
p += 8;
#endif
if (end - p < 4) {
@@ -2697,132 +2715,185 @@
psa_key_type_t *key_type,
size_t *key_size)
{
+#if !defined(MBEDTLS_SSL_HAVE_CCM)
+ (void) taglen;
+#endif
switch (mbedtls_cipher_type) {
+#if defined(MBEDTLS_SSL_HAVE_AES) && defined(MBEDTLS_SSL_HAVE_CBC)
case MBEDTLS_CIPHER_AES_128_CBC:
*alg = PSA_ALG_CBC_NO_PADDING;
*key_type = PSA_KEY_TYPE_AES;
*key_size = 128;
break;
+#endif
+#if defined(MBEDTLS_SSL_HAVE_AES) && defined(MBEDTLS_SSL_HAVE_CCM)
case MBEDTLS_CIPHER_AES_128_CCM:
*alg = taglen ? PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, taglen) : PSA_ALG_CCM;
*key_type = PSA_KEY_TYPE_AES;
*key_size = 128;
break;
+#endif
+#if defined(MBEDTLS_SSL_HAVE_AES) && defined(MBEDTLS_SSL_HAVE_GCM)
case MBEDTLS_CIPHER_AES_128_GCM:
*alg = PSA_ALG_GCM;
*key_type = PSA_KEY_TYPE_AES;
*key_size = 128;
break;
+#endif
+#if defined(MBEDTLS_SSL_HAVE_AES) && defined(MBEDTLS_SSL_HAVE_CCM)
case MBEDTLS_CIPHER_AES_192_CCM:
*alg = taglen ? PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, taglen) : PSA_ALG_CCM;
*key_type = PSA_KEY_TYPE_AES;
*key_size = 192;
break;
+#endif
+#if defined(MBEDTLS_SSL_HAVE_AES) && defined(MBEDTLS_SSL_HAVE_GCM)
case MBEDTLS_CIPHER_AES_192_GCM:
*alg = PSA_ALG_GCM;
*key_type = PSA_KEY_TYPE_AES;
*key_size = 192;
break;
+#endif
+#if defined(MBEDTLS_SSL_HAVE_AES) && defined(MBEDTLS_SSL_HAVE_CBC)
case MBEDTLS_CIPHER_AES_256_CBC:
*alg = PSA_ALG_CBC_NO_PADDING;
*key_type = PSA_KEY_TYPE_AES;
*key_size = 256;
break;
+#endif
+#if defined(MBEDTLS_SSL_HAVE_AES) && defined(MBEDTLS_SSL_HAVE_CCM)
case MBEDTLS_CIPHER_AES_256_CCM:
*alg = taglen ? PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, taglen) : PSA_ALG_CCM;
*key_type = PSA_KEY_TYPE_AES;
*key_size = 256;
break;
+#endif
+#if defined(MBEDTLS_SSL_HAVE_AES) && defined(MBEDTLS_SSL_HAVE_GCM)
case MBEDTLS_CIPHER_AES_256_GCM:
*alg = PSA_ALG_GCM;
*key_type = PSA_KEY_TYPE_AES;
*key_size = 256;
break;
+#endif
+#if defined(MBEDTLS_SSL_HAVE_ARIA) && defined(MBEDTLS_SSL_HAVE_CBC)
case MBEDTLS_CIPHER_ARIA_128_CBC:
*alg = PSA_ALG_CBC_NO_PADDING;
*key_type = PSA_KEY_TYPE_ARIA;
*key_size = 128;
break;
+#endif
+#if defined(MBEDTLS_SSL_HAVE_ARIA) && defined(MBEDTLS_SSL_HAVE_CCM)
case MBEDTLS_CIPHER_ARIA_128_CCM:
*alg = taglen ? PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, taglen) : PSA_ALG_CCM;
*key_type = PSA_KEY_TYPE_ARIA;
*key_size = 128;
break;
+#endif
+#if defined(MBEDTLS_SSL_HAVE_ARIA) && defined(MBEDTLS_SSL_HAVE_GCM)
case MBEDTLS_CIPHER_ARIA_128_GCM:
*alg = PSA_ALG_GCM;
*key_type = PSA_KEY_TYPE_ARIA;
*key_size = 128;
break;
+#endif
+#if defined(MBEDTLS_SSL_HAVE_ARIA) && defined(MBEDTLS_SSL_HAVE_CCM)
case MBEDTLS_CIPHER_ARIA_192_CCM:
*alg = taglen ? PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, taglen) : PSA_ALG_CCM;
*key_type = PSA_KEY_TYPE_ARIA;
*key_size = 192;
break;
+#endif
+#if defined(MBEDTLS_SSL_HAVE_ARIA) && defined(MBEDTLS_SSL_HAVE_GCM)
case MBEDTLS_CIPHER_ARIA_192_GCM:
*alg = PSA_ALG_GCM;
*key_type = PSA_KEY_TYPE_ARIA;
*key_size = 192;
break;
+#endif
+#if defined(MBEDTLS_SSL_HAVE_ARIA) && defined(MBEDTLS_SSL_HAVE_CBC)
case MBEDTLS_CIPHER_ARIA_256_CBC:
*alg = PSA_ALG_CBC_NO_PADDING;
*key_type = PSA_KEY_TYPE_ARIA;
*key_size = 256;
break;
+#endif
+#if defined(MBEDTLS_SSL_HAVE_ARIA) && defined(MBEDTLS_SSL_HAVE_CCM)
case MBEDTLS_CIPHER_ARIA_256_CCM:
*alg = taglen ? PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, taglen) : PSA_ALG_CCM;
*key_type = PSA_KEY_TYPE_ARIA;
*key_size = 256;
break;
+#endif
+#if defined(MBEDTLS_SSL_HAVE_ARIA) && defined(MBEDTLS_SSL_HAVE_GCM)
case MBEDTLS_CIPHER_ARIA_256_GCM:
*alg = PSA_ALG_GCM;
*key_type = PSA_KEY_TYPE_ARIA;
*key_size = 256;
break;
+#endif
+#if defined(MBEDTLS_SSL_HAVE_CAMELLIA) && defined(MBEDTLS_SSL_HAVE_CBC)
case MBEDTLS_CIPHER_CAMELLIA_128_CBC:
*alg = PSA_ALG_CBC_NO_PADDING;
*key_type = PSA_KEY_TYPE_CAMELLIA;
*key_size = 128;
break;
+#endif
+#if defined(MBEDTLS_SSL_HAVE_CAMELLIA) && defined(MBEDTLS_SSL_HAVE_CCM)
case MBEDTLS_CIPHER_CAMELLIA_128_CCM:
*alg = taglen ? PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, taglen) : PSA_ALG_CCM;
*key_type = PSA_KEY_TYPE_CAMELLIA;
*key_size = 128;
break;
+#endif
+#if defined(MBEDTLS_SSL_HAVE_CAMELLIA) && defined(MBEDTLS_SSL_HAVE_GCM)
case MBEDTLS_CIPHER_CAMELLIA_128_GCM:
*alg = PSA_ALG_GCM;
*key_type = PSA_KEY_TYPE_CAMELLIA;
*key_size = 128;
break;
+#endif
+#if defined(MBEDTLS_SSL_HAVE_CAMELLIA) && defined(MBEDTLS_SSL_HAVE_CCM)
case MBEDTLS_CIPHER_CAMELLIA_192_CCM:
*alg = taglen ? PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, taglen) : PSA_ALG_CCM;
*key_type = PSA_KEY_TYPE_CAMELLIA;
*key_size = 192;
break;
+#endif
+#if defined(MBEDTLS_SSL_HAVE_CAMELLIA) && defined(MBEDTLS_SSL_HAVE_GCM)
case MBEDTLS_CIPHER_CAMELLIA_192_GCM:
*alg = PSA_ALG_GCM;
*key_type = PSA_KEY_TYPE_CAMELLIA;
*key_size = 192;
break;
+#endif
+#if defined(MBEDTLS_SSL_HAVE_CAMELLIA) && defined(MBEDTLS_SSL_HAVE_CBC)
case MBEDTLS_CIPHER_CAMELLIA_256_CBC:
*alg = PSA_ALG_CBC_NO_PADDING;
*key_type = PSA_KEY_TYPE_CAMELLIA;
*key_size = 256;
break;
+#endif
+#if defined(MBEDTLS_SSL_HAVE_CAMELLIA) && defined(MBEDTLS_SSL_HAVE_CCM)
case MBEDTLS_CIPHER_CAMELLIA_256_CCM:
*alg = taglen ? PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, taglen) : PSA_ALG_CCM;
*key_type = PSA_KEY_TYPE_CAMELLIA;
*key_size = 256;
break;
+#endif
+#if defined(MBEDTLS_SSL_HAVE_CAMELLIA) && defined(MBEDTLS_SSL_HAVE_GCM)
case MBEDTLS_CIPHER_CAMELLIA_256_GCM:
*alg = PSA_ALG_GCM;
*key_type = PSA_KEY_TYPE_CAMELLIA;
*key_size = 256;
break;
+#endif
+#if defined(MBEDTLS_SSL_HAVE_CHACHAPOLY)
case MBEDTLS_CIPHER_CHACHA20_POLY1305:
*alg = PSA_ALG_CHACHA20_POLY1305;
*key_type = PSA_KEY_TYPE_CHACHA20;
*key_size = 256;
break;
+#endif
case MBEDTLS_CIPHER_NULL:
*alg = MBEDTLS_SSL_NULL_CIPHER;
*key_type = 0;
diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c
index eac6326..44814b9 100644
--- a/library/ssl_tls13_client.c
+++ b/library/ssl_tls13_client.c
@@ -931,28 +931,14 @@
if (ssl_tls13_ticket_get_identity(
ssl, &hash_alg, &identity, &identity_len) == 0) {
#if defined(MBEDTLS_HAVE_TIME)
- mbedtls_time_t now = mbedtls_time(NULL);
+ mbedtls_ms_time_t now = mbedtls_ms_time();
mbedtls_ssl_session *session = ssl->session_negotiate;
+ /* The ticket age has been checked to be smaller than the
+ * `ticket_lifetime` in ssl_prepare_client_hello() which is smaller than
+ * 7 days (enforced in ssl_tls13_parse_new_session_ticket()) . Thus the
+ * cast to `uint32_t` of the ticket age is safe. */
uint32_t obfuscated_ticket_age =
- (uint32_t) (now - session->ticket_received);
-
- /*
- * The ticket timestamp is in seconds but the ticket age is in
- * milliseconds. If the ticket was received at the end of a second and
- * re-used here just at the beginning of the next second, the computed
- * age `now - session->ticket_received` is equal to 1s thus 1000 ms
- * while the actual age could be just a few milliseconds or tens of
- * milliseconds. If the server has more accurate ticket timestamps
- * (typically timestamps in milliseconds), as part of the processing of
- * the ClientHello, it may compute a ticket lifetime smaller than the
- * one computed here and potentially reject the ticket. To avoid that,
- * remove one second to the ticket age if possible.
- */
- if (obfuscated_ticket_age > 0) {
- obfuscated_ticket_age -= 1;
- }
-
- obfuscated_ticket_age *= 1000;
+ (uint32_t) (now - session->ticket_reception_time);
obfuscated_ticket_age += session->ticket_age_add;
ret = ssl_tls13_write_identity(ssl, p, end,
@@ -2762,6 +2748,11 @@
MBEDTLS_SSL_DEBUG_MSG(3,
("ticket_lifetime: %u",
(unsigned int) session->ticket_lifetime));
+ if (session->ticket_lifetime >
+ MBEDTLS_SSL_TLS1_3_MAX_ALLOWED_TICKET_LIFETIME) {
+ MBEDTLS_SSL_DEBUG_MSG(3, ("ticket_lifetime exceeds 7 days."));
+ return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
+ }
session->ticket_age_add = MBEDTLS_GET_UINT32_BE(p, 4);
MBEDTLS_SSL_DEBUG_MSG(3,
@@ -2837,7 +2828,7 @@
#if defined(MBEDTLS_HAVE_TIME)
/* Store ticket creation time */
- session->ticket_received = mbedtls_time(NULL);
+ session->ticket_reception_time = mbedtls_ms_time();
#endif
ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(session->ciphersuite);
diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c
index 061dcf7..d983a00 100644
--- a/library/ssl_tls13_server.c
+++ b/library/ssl_tls13_server.c
@@ -111,9 +111,10 @@
unsigned char *ticket_buffer;
unsigned int key_exchanges;
#if defined(MBEDTLS_HAVE_TIME)
- mbedtls_time_t now;
- uint64_t age_in_s;
- int64_t age_diff_in_ms;
+ mbedtls_ms_time_t now;
+ mbedtls_ms_time_t server_age;
+ uint32_t client_age;
+ mbedtls_ms_time_t age_diff;
#endif
((void) obfuscated_ticket_age);
@@ -190,17 +191,17 @@
ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED;
#if defined(MBEDTLS_HAVE_TIME)
- now = mbedtls_time(NULL);
+ now = mbedtls_ms_time();
- if (now < session->start) {
+ if (now < session->ticket_creation_time) {
MBEDTLS_SSL_DEBUG_MSG(
- 3, ("Invalid ticket start time ( now=%" MBEDTLS_PRINTF_LONGLONG
- ", start=%" MBEDTLS_PRINTF_LONGLONG " )",
- (long long) now, (long long) session->start));
+ 3, ("Invalid ticket creation time ( now = %" MBEDTLS_PRINTF_MS_TIME
+ ", creation_time = %" MBEDTLS_PRINTF_MS_TIME " )",
+ now, session->ticket_creation_time));
goto exit;
}
- age_in_s = (uint64_t) (now - session->start);
+ server_age = now - session->ticket_creation_time;
/* RFC 8446 section 4.6.1
*
@@ -211,12 +212,11 @@
* Clients MUST NOT attempt to use tickets which have ages greater than
* the "ticket_lifetime" value which was provided with the ticket.
*
- * For time being, the age MUST be less than 604800 seconds (7 days).
*/
- if (age_in_s > 604800) {
+ if (server_age > MBEDTLS_SSL_TLS1_3_MAX_ALLOWED_TICKET_LIFETIME * 1000) {
MBEDTLS_SSL_DEBUG_MSG(
- 3, ("Ticket age exceeds limitation ticket_age=%lu",
- (long unsigned int) age_in_s));
+ 3, ("Ticket age exceeds limitation ticket_age = %" MBEDTLS_PRINTF_MS_TIME,
+ server_age));
goto exit;
}
@@ -227,18 +227,19 @@
* ticket_age_add from PskIdentity.obfuscated_ticket_age modulo 2^32) is
* within a small tolerance of the time since the ticket was issued.
*
- * NOTE: When `now == session->start`, `age_diff_in_ms` may be negative
- * as the age units are different on the server (s) and in the
- * client (ms) side. Add a -1000 ms tolerance window to take this
- * into account.
+ * NOTE: The typical accuracy of an RTC crystal is ±100 to ±20 parts per
+ * million (360 to 72 milliseconds per hour). Default tolerance
+ * window is 6s, thus in the worst case clients and servers must
+ * sync up their system time every 6000/360/2~=8 hours.
*/
- age_diff_in_ms = age_in_s * 1000;
- age_diff_in_ms -= (obfuscated_ticket_age - session->ticket_age_add);
- if (age_diff_in_ms <= -1000 ||
- age_diff_in_ms > MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE) {
+ client_age = obfuscated_ticket_age - session->ticket_age_add;
+ age_diff = server_age - (mbedtls_ms_time_t) client_age;
+ if (age_diff < -MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE ||
+ age_diff > MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE) {
MBEDTLS_SSL_DEBUG_MSG(
- 3, ("Ticket age outside tolerance window ( diff=%d )",
- (int) age_diff_in_ms));
+ 3, ("Ticket age outside tolerance window ( diff = %"
+ MBEDTLS_PRINTF_MS_TIME ")",
+ age_diff));
goto exit;
}
@@ -472,6 +473,10 @@
}
memcpy(dst->resumption_key, src->resumption_key, src->resumption_key_len);
+#if defined(MBEDTLS_SSL_EARLY_DATA)
+ dst->max_early_data_size = src->max_early_data_size;
+#endif
+
return 0;
}
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
@@ -2873,7 +2878,7 @@
MBEDTLS_SSL_DEBUG_MSG(2, ("=> prepare NewSessionTicket msg"));
#if defined(MBEDTLS_HAVE_TIME)
- session->start = mbedtls_time(NULL);
+ session->ticket_creation_time = mbedtls_ms_time();
#endif
/* Set ticket_flags depends on the advertised psk key exchange mode */
@@ -3020,8 +3025,8 @@
* MAY treat a ticket as valid for a shorter period of time than what
* is stated in the ticket_lifetime.
*/
- if (ticket_lifetime > 604800) {
- ticket_lifetime = 604800;
+ if (ticket_lifetime > MBEDTLS_SSL_TLS1_3_MAX_ALLOWED_TICKET_LIFETIME) {
+ ticket_lifetime = MBEDTLS_SSL_TLS1_3_MAX_ALLOWED_TICKET_LIFETIME;
}
MBEDTLS_PUT_UINT32_BE(ticket_lifetime, p, 0);
MBEDTLS_SSL_DEBUG_MSG(3, ("ticket_lifetime: %u",
diff --git a/programs/.gitignore b/programs/.gitignore
index a641c31..e0c4987 100644
--- a/programs/.gitignore
+++ b/programs/.gitignore
@@ -38,6 +38,7 @@
psa/hmac_demo
psa/key_ladder_demo
psa/psa_constant_names
+psa/psa_hash
random/gen_entropy
random/gen_random_ctr_drbg
ssl/dtls_client
@@ -56,6 +57,7 @@
test/cpp_dummy_build.cpp
test/dlopen
test/ecp-bench
+test/metatest
test/query_compile_time_config
test/query_included_headers
test/selftest
diff --git a/programs/Makefile b/programs/Makefile
index 116883b..a3fa816 100644
--- a/programs/Makefile
+++ b/programs/Makefile
@@ -123,6 +123,7 @@
ssl/ssl_server \
ssl/ssl_server2 \
test/benchmark \
+ test/metatest \
test/query_compile_time_config \
test/query_included_headers \
test/selftest \
@@ -413,6 +414,10 @@
$(CC) $(LOCAL_CFLAGS) $(CFLAGS) test/dlopen.c $(LDFLAGS) $(DLOPEN_LDFLAGS) -o $@
endif
+test/metatest$(EXEXT): test/metatest.c $(DEP)
+ echo " CC test/metatest.c"
+ $(CC) $(LOCAL_CFLAGS) $(CFLAGS) -I ../library test/metatest.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
+
test/query_config.o: test/query_config.c test/query_config.h $(DEP)
echo " CC test/query_config.c"
$(CC) $(LOCAL_CFLAGS) $(CFLAGS) -c test/query_config.c -o $@
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 3e2360e..c96128b 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -1419,22 +1419,29 @@
return MBEDTLS_ERR_SSL_INVALID_MAC;
case 2:
return MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED;
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
case 3:
- session->start = mbedtls_time(NULL) + 10;
+ /* Creation time in the future. */
+ session->ticket_creation_time = mbedtls_ms_time() + 1000;
break;
case 4:
- session->start = mbedtls_time(NULL) - 10 - 7 * 24 * 3600;
+ /* Ticket has reached the end of lifetime. */
+ session->ticket_creation_time = mbedtls_ms_time() -
+ (7 * 24 * 3600 * 1000 + 1000);
break;
case 5:
- session->start = mbedtls_time(NULL) - 10;
+ /* Ticket is valid, but client age is below the lower bound of the tolerance window. */
+ session->ticket_age_add += MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE + 4 * 1000;
+ /* Make sure the execution time does not affect the result */
+ session->ticket_creation_time = mbedtls_ms_time();
break;
+
case 6:
- session->start = mbedtls_time(NULL);
-#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
- session->ticket_age_add -= 1000;
-#endif
+ /* Ticket is valid, but client age is beyond the upper bound of the tolerance window. */
+ session->ticket_age_add -= MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE + 4 * 1000;
+ /* Make sure the execution time does not affect the result */
+ session->ticket_creation_time = mbedtls_ms_time();
break;
-#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
case 7:
session->ticket_flags = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_NONE;
break;
diff --git a/programs/test/CMakeLists.txt b/programs/test/CMakeLists.txt
index a75f8d9..0778731 100644
--- a/programs/test/CMakeLists.txt
+++ b/programs/test/CMakeLists.txt
@@ -3,6 +3,7 @@
)
set(executables_libs
+ metatest
query_included_headers
selftest
udp_proxy
@@ -72,6 +73,7 @@
add_executable(${exe} ${exe}.c $<TARGET_OBJECTS:mbedtls_test>
${extra_sources})
target_include_directories(${exe} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../tests/include)
+ target_include_directories(${exe} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../library)
if(exe STREQUAL "query_compile_time_config")
target_include_directories(${exe} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
endif()
diff --git a/programs/test/metatest.c b/programs/test/metatest.c
new file mode 100644
index 0000000..2973cce
--- /dev/null
+++ b/programs/test/metatest.c
@@ -0,0 +1,351 @@
+/** \file metatest.c
+ *
+ * \brief Test features of the test framework.
+ *
+ * When you run this program, it runs a single "meta-test". A meta-test
+ * performs an operation which should be caught as a failure by our
+ * test framework. The meta-test passes if this program calls `exit` with
+ * a nonzero status, or aborts, or is terminated by a signal, or if the
+ * framework running the program considers the run an error (this happens
+ * with Valgrind for a memory leak). The non-success of the meta-test
+ * program means that the test failure has been caught correctly.
+ *
+ * Some failures are purely functional: the logic of the code causes the
+ * test result to be set to FAIL. Other failures come from extra
+ * instrumentation which is not present in a normal build; for example,
+ * Asan or Valgrind to detect memory leaks. This is reflected by the
+ * "platform" associated with each meta-test.
+ *
+ * Use the companion script `tests/scripts/run-metatests.sh` to run all
+ * the meta-tests for a given platform and validate that they trigger a
+ * detected failure as expected.
+ */
+
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+
+#define MBEDTLS_ALLOW_PRIVATE_ACCESS
+
+#include <mbedtls/platform.h>
+#include <mbedtls/platform_util.h>
+#include "test/helpers.h"
+#include "test/macros.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#if defined(MBEDTLS_THREADING_C)
+#include <mbedtls/threading.h>
+#endif
+
+
+/* This is an external variable, so the compiler doesn't know that we're never
+ * changing its value.
+ */
+volatile int false_but_the_compiler_does_not_know = 0;
+
+/* Set n bytes at the address p to all-bits-zero, in such a way that
+ * the compiler should not know that p is all-bits-zero. */
+static void set_to_zero_but_the_compiler_does_not_know(volatile void *p, size_t n)
+{
+ memset((void *) p, false_but_the_compiler_does_not_know, n);
+}
+
+
+/****************************************************************/
+/* Test framework features */
+/****************************************************************/
+
+void meta_test_fail(const char *name)
+{
+ (void) name;
+ mbedtls_test_fail("Forced test failure", __LINE__, __FILE__);
+}
+
+
+/****************************************************************/
+/* Platform features */
+/****************************************************************/
+
+void null_pointer_dereference(const char *name)
+{
+ (void) name;
+ volatile char *volatile p;
+ set_to_zero_but_the_compiler_does_not_know(&p, sizeof(p));
+ /* Undefined behavior (read from null data pointer) */
+ mbedtls_printf("%p -> %u\n", p, (unsigned) *p);
+}
+
+void null_pointer_call(const char *name)
+{
+ (void) name;
+ unsigned(*volatile p)(void);
+ set_to_zero_but_the_compiler_does_not_know(&p, sizeof(p));
+ /* Undefined behavior (execute null function pointer) */
+ /* The pointer representation may be truncated, but we don't care:
+ * the only point of printing it is to have some use of the pointer
+ * to dissuade the compiler from optimizing it away. */
+ mbedtls_printf("%lx() -> %u\n", (unsigned long) (uintptr_t) p, p());
+}
+
+
+/****************************************************************/
+/* Memory */
+/****************************************************************/
+
+void read_after_free(const char *name)
+{
+ (void) name;
+ volatile char *p = mbedtls_calloc(1, 1);
+ *p = 'a';
+ mbedtls_free((void *) p);
+ /* Undefined behavior (read after free) */
+ mbedtls_printf("%u\n", (unsigned) *p);
+}
+
+void double_free(const char *name)
+{
+ (void) name;
+ volatile char *p = mbedtls_calloc(1, 1);
+ *p = 'a';
+ mbedtls_free((void *) p);
+ /* Undefined behavior (double free) */
+ mbedtls_free((void *) p);
+}
+
+void read_uninitialized_stack(const char *name)
+{
+ (void) name;
+ char buf[1];
+ if (false_but_the_compiler_does_not_know) {
+ buf[0] = '!';
+ }
+ char *volatile p = buf;
+ if (*p != 0) {
+ /* Unspecified result (read from uninitialized memory) */
+ mbedtls_printf("%u\n", (unsigned) *p);
+ }
+}
+
+void memory_leak(const char *name)
+{
+ (void) name;
+ volatile char *p = mbedtls_calloc(1, 1);
+ mbedtls_printf("%u\n", (unsigned) *p);
+ /* Leak of a heap object */
+}
+
+
+/****************************************************************/
+/* Threading */
+/****************************************************************/
+
+void mutex_lock_not_initialized(const char *name)
+{
+ (void) name;
+#if defined(MBEDTLS_THREADING_C)
+ mbedtls_threading_mutex_t mutex;
+ memset(&mutex, 0, sizeof(mutex));
+ /* This mutex usage error is detected by our test framework's mutex usage
+ * verification framework. See tests/src/threading_helpers.c. Other
+ * threading implementations (e.g. pthread without our instrumentation)
+ * might consider this normal usage. */
+ TEST_ASSERT(mbedtls_mutex_lock(&mutex) == 0);
+exit:
+ ;
+#endif
+}
+
+void mutex_unlock_not_initialized(const char *name)
+{
+ (void) name;
+#if defined(MBEDTLS_THREADING_C)
+ mbedtls_threading_mutex_t mutex;
+ memset(&mutex, 0, sizeof(mutex));
+ /* This mutex usage error is detected by our test framework's mutex usage
+ * verification framework. See tests/src/threading_helpers.c. Other
+ * threading implementations (e.g. pthread without our instrumentation)
+ * might consider this normal usage. */
+ TEST_ASSERT(mbedtls_mutex_unlock(&mutex) == 0);
+exit:
+ ;
+#endif
+}
+
+void mutex_free_not_initialized(const char *name)
+{
+ (void) name;
+#if defined(MBEDTLS_THREADING_C)
+ mbedtls_threading_mutex_t mutex;
+ memset(&mutex, 0, sizeof(mutex));
+ /* This mutex usage error is detected by our test framework's mutex usage
+ * verification framework. See tests/src/threading_helpers.c. Other
+ * threading implementations (e.g. pthread without our instrumentation)
+ * might consider this normal usage. */
+ mbedtls_mutex_free(&mutex);
+#endif
+}
+
+void mutex_double_init(const char *name)
+{
+ (void) name;
+#if defined(MBEDTLS_THREADING_C)
+ mbedtls_threading_mutex_t mutex;
+ mbedtls_mutex_init(&mutex);
+ /* This mutex usage error is detected by our test framework's mutex usage
+ * verification framework. See tests/src/threading_helpers.c. Other
+ * threading implementations (e.g. pthread without our instrumentation)
+ * might consider this normal usage. */
+ mbedtls_mutex_init(&mutex);
+ mbedtls_mutex_free(&mutex);
+#endif
+}
+
+void mutex_double_free(const char *name)
+{
+ (void) name;
+#if defined(MBEDTLS_THREADING_C)
+ mbedtls_threading_mutex_t mutex;
+ mbedtls_mutex_init(&mutex);
+ mbedtls_mutex_free(&mutex);
+ /* This mutex usage error is detected by our test framework's mutex usage
+ * verification framework. See tests/src/threading_helpers.c. Other
+ * threading implementations (e.g. pthread without our instrumentation)
+ * might consider this normal usage. */
+ mbedtls_mutex_free(&mutex);
+#endif
+}
+
+void mutex_leak(const char *name)
+{
+ (void) name;
+#if defined(MBEDTLS_THREADING_C)
+ mbedtls_threading_mutex_t mutex;
+ mbedtls_mutex_init(&mutex);
+#endif
+ /* This mutex usage error is detected by our test framework's mutex usage
+ * verification framework. See tests/src/threading_helpers.c. Other
+ * threading implementations (e.g. pthread without our instrumentation)
+ * might consider this normal usage. */
+}
+
+
+/****************************************************************/
+/* Command line entry point */
+/****************************************************************/
+
+typedef struct {
+ /** Command line argument that will trigger that metatest.
+ *
+ * Conventionally matches "[a-z0-9_]+". */
+ const char *name;
+
+ /** Platform under which that metatest is valid.
+ *
+ * - "any": should work anywhere.
+ * - "asan": triggers ASan (Address Sanitizer).
+ * - "msan": triggers MSan (Memory Sanitizer).
+ * - "pthread": requires MBEDTLS_THREADING_PTHREAD and MBEDTLS_TEST_HOOKS,
+ * which enables MBEDTLS_TEST_MUTEX_USAGE internally in the test
+ * framework (see tests/src/threading_helpers.c).
+ */
+ const char *platform;
+
+ /** Function that performs the metatest.
+ *
+ * The function receives the name as an argument. This allows using the
+ * same function to perform multiple variants of a test based on the name.
+ *
+ * When executed on a conforming platform, the function is expected to
+ * either cause a test failure (mbedtls_test_fail()), or cause the
+ * program to abort in some way (e.g. by causing a segfault or by
+ * triggering a sanitizer).
+ *
+ * When executed on a non-conforming platform, the function may return
+ * normally or may have unpredictable behavior.
+ */
+ void (*entry_point)(const char *name);
+} metatest_t;
+
+/* The list of availble meta-tests. Remember to register new functions here!
+ *
+ * Note that we always compile all the functions, so that `metatest --list`
+ * will always list all the available meta-tests.
+ *
+ * See the documentation of metatest_t::platform for the meaning of
+ * platform values.
+ */
+metatest_t metatests[] = {
+ { "test_fail", "any", meta_test_fail },
+ { "null_dereference", "any", null_pointer_dereference },
+ { "null_call", "any", null_pointer_call },
+ { "read_after_free", "asan", read_after_free },
+ { "double_free", "asan", double_free },
+ { "read_uninitialized_stack", "msan", read_uninitialized_stack },
+ { "memory_leak", "asan", memory_leak },
+ { "mutex_lock_not_initialized", "pthread", mutex_lock_not_initialized },
+ { "mutex_unlock_not_initialized", "pthread", mutex_unlock_not_initialized },
+ { "mutex_free_not_initialized", "pthread", mutex_free_not_initialized },
+ { "mutex_double_init", "pthread", mutex_double_init },
+ { "mutex_double_free", "pthread", mutex_double_free },
+ { "mutex_leak", "pthread", mutex_leak },
+ { NULL, NULL, NULL }
+};
+
+static void help(FILE *out, const char *argv0)
+{
+ mbedtls_fprintf(out, "Usage: %s list|TEST\n", argv0);
+ mbedtls_fprintf(out, "Run a meta-test that should cause a test failure.\n");
+ mbedtls_fprintf(out, "With 'list', list the available tests and their platform requirement.\n");
+}
+
+int main(int argc, char *argv[])
+{
+ const char *argv0 = argc > 0 ? argv[0] : "metatest";
+ if (argc != 2) {
+ help(stderr, argv0);
+ mbedtls_exit(MBEDTLS_EXIT_FAILURE);
+ }
+
+ /* Support "-help", "--help", "--list", etc. */
+ const char *command = argv[1];
+ while (*command == '-') {
+ ++command;
+ }
+
+ if (strcmp(argv[1], "help") == 0) {
+ help(stdout, argv0);
+ mbedtls_exit(MBEDTLS_EXIT_SUCCESS);
+ }
+ if (strcmp(argv[1], "list") == 0) {
+ for (const metatest_t *p = metatests; p->name != NULL; p++) {
+ mbedtls_printf("%s %s\n", p->name, p->platform);
+ }
+ mbedtls_exit(MBEDTLS_EXIT_SUCCESS);
+ }
+
+#if defined(MBEDTLS_TEST_MUTEX_USAGE)
+ mbedtls_test_mutex_usage_init();
+#endif
+
+ for (const metatest_t *p = metatests; p->name != NULL; p++) {
+ if (strcmp(argv[1], p->name) == 0) {
+ mbedtls_printf("Running metatest %s...\n", argv[1]);
+ p->entry_point(argv[1]);
+#if defined(MBEDTLS_TEST_MUTEX_USAGE)
+ mbedtls_test_mutex_usage_check();
+#endif
+ mbedtls_printf("Running metatest %s... done, result=%d\n",
+ argv[1], (int) mbedtls_test_info.result);
+ mbedtls_exit(mbedtls_test_info.result == MBEDTLS_TEST_RESULT_SUCCESS ?
+ MBEDTLS_EXIT_SUCCESS :
+ MBEDTLS_EXIT_FAILURE);
+ }
+ }
+
+ mbedtls_fprintf(stderr, "%s: FATAL: No such metatest: %s\n",
+ argv0, command);
+ mbedtls_exit(MBEDTLS_EXIT_FAILURE);
+}
diff --git a/scripts/ci.requirements.txt b/scripts/ci.requirements.txt
index 7dbcfe8..69c2db0 100644
--- a/scripts/ci.requirements.txt
+++ b/scripts/ci.requirements.txt
@@ -18,3 +18,7 @@
# for mypy and pylint under Python 3.5, and we also get something good enough
# to run audit-validity-dates.py on Python >=3.6.
cryptography # >= 35.0.0
+
+# For building `tests/data_files/server9-bad-saltlen.crt` and check python
+# files.
+asn1crypto
diff --git a/scripts/generate_visualc_files.pl b/scripts/generate_visualc_files.pl
index 7f56098..96ade2f 100755
--- a/scripts/generate_visualc_files.pl
+++ b/scripts/generate_visualc_files.pl
@@ -144,6 +144,7 @@
my $guid = gen_app_guid( $path );
$path =~ s!/!\\!g;
(my $appname = $path) =~ s/.*\\//;
+ my $is_test_app = ($path =~ m/^test\\/);
my $srcs = "<ClCompile Include=\"..\\..\\programs\\$path.c\" \/>";
if( $appname eq "ssl_client2" or $appname eq "ssl_server2" or
@@ -158,7 +159,9 @@
$content =~ s/<SOURCES>/$srcs/g;
$content =~ s/<APPNAME>/$appname/g;
$content =~ s/<GUID>/$guid/g;
- $content =~ s/INCLUDE_DIRECTORIES\n/$include_directories/g;
+ $content =~ s/INCLUDE_DIRECTORIES\n/($is_test_app ?
+ $library_include_directories :
+ $include_directories)/ge;
content_to_file( $content, "$dir/$appname.$ext" );
}
diff --git a/tests/data_files/Makefile b/tests/data_files/Makefile
index 51a5d7e..a7035cb 100644
--- a/tests/data_files/Makefile
+++ b/tests/data_files/Makefile
@@ -206,10 +206,8 @@
$(OPENSSL) x509 -req -in test-ca2.req.sha256 -extfile $< \
-signkey $(test_ca_key_file_ec) -days 3653 -out $@
-all_final += test-ca2.ku-crl.crt \
- test-ca2.ku-crt.crt \
- test-ca2.ku-crt_crl.crt \
- test-ca2.ku-ds.crt
+all_final += test-ca2.ku-crl.crt test-ca2.ku-crt.crt test-ca2.ku-crt_crl.crt \
+ test-ca2.ku-ds.crt
test-ca2-future.crt: $(test_ca_key_file_ec) test-ca2.req.sha256
$(MBEDTLS_CERT_WRITE) is_ca=1 serial=13926223505202072808 request_file=test-ca2.req.sha256 selfsign=1 \
@@ -580,10 +578,6 @@
cat $^ > $@
all_final += server9-with-ca.crt
-# FIXME: This file needs special sequence. It should be update manually
-server9-bad-saltlen.crt: server9.csr $(test_ca_crt) $(test_ca_key_file_rsa)
- false
-
server9-bad-mgfhash.crt: server9.csr $(test_ca_crt) $(test_ca_key_file_rsa)
$(OPENSSL) x509 -req -extfile $(cli_crt_extensions_file) -extensions cli-rsa \
-passin "pass:$(test_ca_pwd_rsa)" -CA $(test_ca_crt) -CAkey $(test_ca_key_file_rsa) \
@@ -593,6 +587,16 @@
-in $< -out $@
all_final += server9-bad-mgfhash.crt
+server9-bad-saltlen.crt: server9.csr $(test_ca_crt) $(test_ca_key_file_rsa) \
+ opensslcnf/server9.crt.v3_ext \
+ ../scripts/generate_server9_bad_saltlen.py
+ ../scripts/generate_server9_bad_saltlen.py --ca-name test-ca \
+ --ca-password $(test_ca_pwd_rsa) --csr server9.csr \
+ --openssl-extfile opensslcnf/server9.crt.v3_ext \
+ --anounce_saltlen 0xde --actual_saltlen 0x20 \
+ --output $@
+all_final += server9-bad-saltlen.crt
+
# server10*
server10.crt: server10.key test-int-ca3.crt test-int-ca3.key
@@ -1545,9 +1549,9 @@
all_intermediate += server6-ss-child.csr
server6-ss-child.crt: server6-ss-child.csr server5-selfsigned.crt server5.key server6-ss-child.crt.openssl.v3_ext
$(OPENSSL) x509 -req -CA server5-selfsigned.crt -CAkey server5.key \
- -extfile server6-ss-child.crt.openssl.v3_ext \
- -set_serial 0x53a2cb5822399474a7ec79ec \
- -days 3650 -sha256 -in $< -out $@
+ -extfile server6-ss-child.crt.openssl.v3_ext \
+ -set_serial 0x53a2cb5822399474a7ec79ec \
+ -days 3650 -sha256 -in $< -out $@
all_final += server6-ss-child.crt
@@ -1714,9 +1718,9 @@
$(OPENSSL) ca -gencrl -batch -cert $(test_ca_crt) -keyfile $(test_ca_key_file_rsa) -key $(test_ca_pwd_rsa) -config $(test_ca_server1_config_file) -md sha1 -crldays 3653 -out $@
crl-futureRevocationDate.pem: $(test_ca_crt) $(test_ca_key_file_rsa) \
- $(test_ca_config_file) \
- test-ca.server1.future-crl.db \
- test-ca.server1.future-crl.opensslconf
+ $(test_ca_config_file) \
+ test-ca.server1.future-crl.db \
+ test-ca.server1.future-crl.opensslconf
$(FAKETIME) -f '+10y' $(OPENSSL) ca -gencrl \
-config test-ca.server1.future-crl.opensslconf -crldays 365 \
-passin "pass:$(test_ca_pwd_rsa)" -out $@
diff --git a/tests/data_files/opensslcnf/server9.crt.v3_ext b/tests/data_files/opensslcnf/server9.crt.v3_ext
new file mode 100644
index 0000000..f8d201b
--- /dev/null
+++ b/tests/data_files/opensslcnf/server9.crt.v3_ext
@@ -0,0 +1,4 @@
+basicConstraints = CA:false
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid:always,issuer:always
+
diff --git a/tests/include/test/drivers/crypto_config_test_driver_extension.h b/tests/include/test/drivers/crypto_config_test_driver_extension.h
index 5ee949a..768a9a6 100644
--- a/tests/include/test/drivers/crypto_config_test_driver_extension.h
+++ b/tests/include/test/drivers/crypto_config_test_driver_extension.h
@@ -537,6 +537,14 @@
#endif
#endif
+#if defined(PSA_WANT_ALG_CCM_STAR_NO_TAG)
+#if defined(MBEDTLS_PSA_ACCEL_ALG_CCM_STAR_NO_TAG)
+#undef MBEDTLS_PSA_ACCEL_ALG_CCM_STAR_NO_TAG
+#else
+#define MBEDTLS_PSA_ACCEL_ALG_CCM_STAR_NO_TAG 1
+#endif
+#endif
+
#if defined(PSA_WANT_ALG_CBC_MAC)
#if defined(MBEDTLS_PSA_ACCEL_ALG_CBC_MAC)
#undef MBEDTLS_PSA_ACCEL_ALG_CBC_MAC
diff --git a/tests/include/test/psa_exercise_key.h b/tests/include/test/psa_exercise_key.h
index 0f3ee3d..a658d17 100644
--- a/tests/include/test/psa_exercise_key.h
+++ b/tests/include/test/psa_exercise_key.h
@@ -46,12 +46,13 @@
*
* For simplicity's sake, stick to block ciphers with 16-byte blocks.
*/
-#if defined(MBEDTLS_AES_C)
+#if defined(PSA_WANT_KEY_TYPE_AES)
#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_AES
-#elif defined(MBEDTLS_ARIA_C)
+#elif defined(PSA_WANT_KEY_TYPE_ARIA)
#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_ARIA
-#elif defined(MBEDTLS_CAMELLIA_C)
+#elif defined(PSA_WANT_KEY_TYPE_CAMELLIA)
#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_CAMELLIA
+#else
#undef KNOWN_SUPPORTED_BLOCK_CIPHER
#endif
@@ -81,13 +82,13 @@
*
* This is used in some smoke tests.
*/
-#if defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CTR)
+#if defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(PSA_WANT_ALG_CTR)
#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CTR
-#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CBC)
+#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(PSA_WANT_ALG_CBC_NO_PADDING)
#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CBC_NO_PADDING
-#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CFB)
+#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(PSA_WANT_ALG_CFB)
#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CFB
-#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_OFB)
+#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(PSA_WANT_ALG_OFB)
#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_OFB
#else
#undef KNOWN_SUPPORTED_BLOCK_CIPHER_ALG
diff --git a/tests/opt-testcases/tls13-misc.sh b/tests/opt-testcases/tls13-misc.sh
index 3816a2b..9208384 100755
--- a/tests/opt-testcases/tls13-misc.sh
+++ b/tests/opt-testcases/tls13-misc.sh
@@ -86,7 +86,7 @@
-S "key exchange mode: psk$" \
-s "ticket is not authentic" \
-S "ticket is expired" \
- -S "Invalid ticket start time" \
+ -S "Invalid ticket creation time" \
-S "Ticket age exceeds limitation" \
-S "Ticket age outside tolerance window"
@@ -105,7 +105,7 @@
-S "key exchange mode: psk$" \
-S "ticket is not authentic" \
-s "ticket is expired" \
- -S "Invalid ticket start time" \
+ -S "Invalid ticket creation time" \
-S "Ticket age exceeds limitation" \
-S "Ticket age outside tolerance window"
@@ -124,7 +124,7 @@
-S "key exchange mode: psk$" \
-S "ticket is not authentic" \
-S "ticket is expired" \
- -s "Invalid ticket start time" \
+ -s "Invalid ticket creation time" \
-S "Ticket age exceeds limitation" \
-S "Ticket age outside tolerance window"
@@ -143,7 +143,7 @@
-S "key exchange mode: psk$" \
-S "ticket is not authentic" \
-S "ticket is expired" \
- -S "Invalid ticket start time" \
+ -S "Invalid ticket creation time" \
-s "Ticket age exceeds limitation" \
-S "Ticket age outside tolerance window"
@@ -162,7 +162,7 @@
-S "key exchange mode: psk$" \
-S "ticket is not authentic" \
-S "ticket is expired" \
- -S "Invalid ticket start time" \
+ -S "Invalid ticket creation time" \
-S "Ticket age exceeds limitation" \
-s "Ticket age outside tolerance window"
@@ -181,7 +181,7 @@
-S "key exchange mode: psk$" \
-S "ticket is not authentic" \
-S "ticket is expired" \
- -S "Invalid ticket start time" \
+ -S "Invalid ticket creation time" \
-S "Ticket age exceeds limitation" \
-s "Ticket age outside tolerance window"
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index dba8e78..929b093 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -1120,6 +1120,9 @@
msg "test: selftest (ASan build)" # ~ 10s
programs/test/selftest
+ msg "test: metatests (GCC, ASan build)"
+ tests/scripts/run-metatests.sh any asan
+
msg "test: ssl-opt.sh (ASan build)" # ~ 1 min
tests/ssl-opt.sh
@@ -1632,6 +1635,59 @@
common_test_full_no_cipher_with_psa_crypto 1 "full no CIPHER"
}
+component_test_full_no_ccm() {
+ msg "build: full no PSA_WANT_ALG_CCM"
+
+ # Full config enables:
+ # - USE_PSA_CRYPTO so that TLS code dispatches cipher/AEAD to PSA
+ # - CRYPTO_CONFIG so that PSA_WANT config symbols are evaluated
+ scripts/config.py full
+
+ # Disable PSA_WANT_ALG_CCM so that CCM is not supported in PSA. CCM_C is still
+ # enabled, but not used from TLS since USE_PSA is set.
+ # This is helpful to ensure that TLS tests below have proper dependencies.
+ #
+ # Note: also PSA_WANT_ALG_CCM_STAR_NO_TAG is enabled, but it does not cause
+ # PSA_WANT_ALG_CCM to be re-enabled.
+ scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CCM
+
+ make
+
+ msg "test: full no PSA_WANT_ALG_CCM"
+ make test
+}
+
+component_test_full_no_ccm_star_no_tag() {
+ msg "build: full no PSA_WANT_ALG_CCM_STAR_NO_TAG"
+
+ # Full config enables CRYPTO_CONFIG so that PSA_WANT config symbols are evaluated
+ scripts/config.py full
+
+ # Disable CCM_STAR_NO_TAG, which is the target of this test, as well as all
+ # other components that enable MBEDTLS_PSA_BUILTIN_CIPHER internal symbol.
+ # This basically disables all unauthenticated ciphers on the PSA side, while
+ # keeping AEADs enabled.
+ #
+ # Note: PSA_WANT_ALG_CCM is enabled, but it does not cause
+ # PSA_WANT_ALG_CCM_STAR_NO_TAG to be re-enabled.
+ scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CCM_STAR_NO_TAG
+ scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_STREAM_CIPHER
+ scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CTR
+ scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CFB
+ scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_OFB
+ scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_ECB_NO_PADDING
+ scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CBC_NO_PADDING
+ scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CBC_PKCS7
+
+ make
+
+ # Ensure MBEDTLS_PSA_BUILTIN_CIPHER was not enabled
+ not grep mbedtls_psa_cipher library/psa_crypto_cipher.o
+
+ msg "test: full no PSA_WANT_ALG_CCM_STAR_NO_TAG"
+ make test
+}
+
component_test_full_no_bignum () {
msg "build: full minus bignum"
scripts/config.py full
@@ -1885,6 +1941,9 @@
msg "test: Everest ECDH context - main suites (inc. selftests) (ASan build)" # ~ 50s
make test
+ msg "test: metatests (clang, ASan)"
+ tests/scripts/run-metatests.sh any asan
+
msg "test: Everest ECDH context - ECDH-related part of ssl-opt.sh (ASan build)" # ~ 5s
tests/ssl-opt.sh -f ECDH
@@ -1973,6 +2032,9 @@
msg "test: cpp_dummy_build (full config, clang)" # ~ 1s
programs/test/cpp_dummy_build
+ msg "test: metatests (clang)"
+ tests/scripts/run-metatests.sh any pthread
+
msg "program demos (full config, clang)" # ~10s
tests/scripts/run_demos.py
@@ -3640,6 +3702,9 @@
scripts/config.py unset MBEDTLS_CCM_C
scripts/config.py unset MBEDTLS_CHACHAPOLY_C
+ # Disable CCM_STAR_NO_TAG because this re-enables CCM_C.
+ scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CCM_STAR_NO_TAG
+
# Build
# -----
@@ -3682,10 +3747,10 @@
# are meant to be used together in analyze_outcomes.py script in order to test
# driver's coverage for ciphers and AEADs.
component_test_psa_crypto_config_accel_cipher_aead () {
- msg "build: crypto config with accelerated cipher and AEAD"
+ msg "build: full config with accelerated cipher and AEAD"
loc_accel_list="ALG_ECB_NO_PADDING ALG_CBC_NO_PADDING ALG_CBC_PKCS7 ALG_CTR ALG_CFB \
- ALG_OFB ALG_XTS ALG_STREAM_CIPHER \
+ ALG_OFB ALG_XTS ALG_STREAM_CIPHER ALG_CCM_STAR_NO_TAG \
ALG_GCM ALG_CCM ALG_CHACHA20_POLY1305 ALG_CMAC \
KEY_TYPE_DES KEY_TYPE_AES KEY_TYPE_ARIA KEY_TYPE_CHACHA20 KEY_TYPE_CAMELLIA"
@@ -3736,24 +3801,30 @@
# Run the tests
# -------------
- msg "test: crypto config with accelerated cipher and AEAD"
+ msg "test: full config with accelerated cipher and AEAD"
make test
- msg "ssl-opt: crypto config with accelerated cipher and AEAD"
+ msg "ssl-opt: full config with accelerated cipher and AEAD"
tests/ssl-opt.sh
+
+ msg "compat.sh: full config with accelerated cipher and AEAD"
+ tests/compat.sh -V NO -p mbedTLS
}
component_test_psa_crypto_config_reference_cipher_aead () {
- msg "build: crypto config with non-accelerated cipher and AEAD"
+ msg "build: full config with non-accelerated cipher and AEAD"
common_psa_crypto_config_accel_cipher_aead
make
- msg "test: crypto config with non-accelerated cipher and AEAD"
+ msg "test: full config with non-accelerated cipher and AEAD"
make test
- msg "ssl-opt: crypto config with non-accelerated cipher and AEAD"
+ msg "ssl-opt: full config with non-accelerated cipher and AEAD"
tests/ssl-opt.sh
+
+ msg "compat.sh: full config with non-accelerated cipher and AEAD"
+ tests/compat.sh -V NO -p mbedTLS
}
component_test_aead_chachapoly_disabled() {
@@ -5459,6 +5530,9 @@
msg "test: main suites (MSan)" # ~ 10s
make test
+ msg "test: metatests (MSan)"
+ tests/scripts/run-metatests.sh any msan
+
msg "program demos (MSan)" # ~20s
tests/scripts/run_demos.py
diff --git a/tests/scripts/generate_server9_bad_saltlen.py b/tests/scripts/generate_server9_bad_saltlen.py
new file mode 100755
index 0000000..9af4dd3
--- /dev/null
+++ b/tests/scripts/generate_server9_bad_saltlen.py
@@ -0,0 +1,87 @@
+#!/usr/bin/env python3
+"""Generate server9-bad-saltlen.crt
+
+Generate a certificate signed with RSA-PSS, with an incorrect salt length.
+"""
+
+# Copyright The Mbed TLS Contributors
+# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+import subprocess
+import argparse
+from asn1crypto import pem, x509, core #type: ignore #pylint: disable=import-error
+
+OPENSSL_RSA_PSS_CERT_COMMAND = r'''
+openssl x509 -req -CA {ca_name}.crt -CAkey {ca_name}.key -set_serial 24 {ca_password} \
+ {openssl_extfile} -days 3650 -outform DER -in {csr} \
+ -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:{anounce_saltlen} \
+ -sigopt rsa_mgf1_md:sha256
+'''
+SIG_OPT = \
+ r'-sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:{saltlen} -sigopt rsa_mgf1_md:sha256'
+OPENSSL_RSA_PSS_DGST_COMMAND = r'''openssl dgst -sign {ca_name}.key {ca_password} \
+ -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:{actual_saltlen} \
+ -sigopt rsa_mgf1_md:sha256'''
+
+
+def auto_int(x):
+ return int(x, 0)
+
+
+def build_argparser(parser):
+ """Build argument parser"""
+ parser.description = __doc__
+ parser.add_argument('--ca-name', type=str, required=True,
+ help='Basename of CA files')
+ parser.add_argument('--ca-password', type=str,
+ required=True, help='CA key file password')
+ parser.add_argument('--csr', type=str, required=True,
+ help='CSR file for generating certificate')
+ parser.add_argument('--openssl-extfile', type=str,
+ required=True, help='X905 v3 extension config file')
+ parser.add_argument('--anounce_saltlen', type=auto_int,
+ required=True, help='Announced salt length')
+ parser.add_argument('--actual_saltlen', type=auto_int,
+ required=True, help='Actual salt length')
+ parser.add_argument('--output', type=str, required=True)
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ build_argparser(parser)
+ args = parser.parse_args()
+
+ return generate(**vars(args))
+
+def generate(**kwargs):
+ """Generate different salt length certificate file."""
+ ca_password = kwargs.get('ca_password', '')
+ if ca_password:
+ kwargs['ca_password'] = r'-passin "pass:{ca_password}"'.format(
+ **kwargs)
+ else:
+ kwargs['ca_password'] = ''
+ extfile = kwargs.get('openssl_extfile', '')
+ if extfile:
+ kwargs['openssl_extfile'] = '-extfile {openssl_extfile}'.format(
+ **kwargs)
+ else:
+ kwargs['openssl_extfile'] = ''
+
+ cmd = OPENSSL_RSA_PSS_CERT_COMMAND.format(**kwargs)
+ der_bytes = subprocess.check_output(cmd, shell=True)
+ target_certificate = x509.Certificate.load(der_bytes)
+
+ cmd = OPENSSL_RSA_PSS_DGST_COMMAND.format(**kwargs)
+ #pylint: disable=unexpected-keyword-arg
+ der_bytes = subprocess.check_output(cmd,
+ input=target_certificate['tbs_certificate'].dump(),
+ shell=True)
+
+ with open(kwargs.get('output'), 'wb') as f:
+ target_certificate['signature_value'] = core.OctetBitString(der_bytes)
+ f.write(pem.armor('CERTIFICATE', target_certificate.dump()))
+
+
+if __name__ == '__main__':
+ main()
diff --git a/tests/scripts/run-metatests.sh b/tests/scripts/run-metatests.sh
new file mode 100755
index 0000000..22a302c
--- /dev/null
+++ b/tests/scripts/run-metatests.sh
@@ -0,0 +1,89 @@
+#!/bin/sh
+
+help () {
+ cat <<EOF
+Usage: $0 [OPTION] [PLATFORM]...
+Run all the metatests whose platform matches any of the given PLATFORM.
+A PLATFORM can contain shell wildcards.
+
+Expected output: a lot of scary-looking error messages, since each
+metatest is expected to report a failure. The final line should be
+"Ran N metatests, all good."
+
+If something goes wrong: the final line should be
+"Ran N metatests, X unexpected successes". Look for "Unexpected success"
+in the logs above.
+
+ -l List the available metatests, don't run them.
+EOF
+}
+
+# Copyright The Mbed TLS Contributors
+# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+set -e -u
+
+if [ -d programs ]; then
+ METATEST_PROGRAM=programs/test/metatest
+elif [ -d ../programs ]; then
+ METATEST_PROGRAM=../programs/test/metatest
+elif [ -d ../../programs ]; then
+ METATEST_PROGRAM=../../programs/test/metatest
+else
+ echo >&2 "$0: FATAL: programs/test/metatest not found"
+ exit 120
+fi
+
+LIST_ONLY=
+while getopts hl OPTLET; do
+ case $OPTLET in
+ h) help; exit;;
+ l) LIST_ONLY=1;;
+ \?) help >&2; exit 120;;
+ esac
+done
+shift $((OPTIND - 1))
+
+list_matches () {
+ while read name platform junk; do
+ for pattern in "$@"; do
+ case $platform in
+ $pattern) echo "$name"; break;;
+ esac
+ done
+ done
+}
+
+count=0
+errors=0
+run_metatest () {
+ ret=0
+ "$METATEST_PROGRAM" "$1" || ret=$?
+ if [ $ret -eq 0 ]; then
+ echo >&2 "$0: Unexpected success: $1"
+ errors=$((errors + 1))
+ fi
+ count=$((count + 1))
+}
+
+# Don't pipe the output of metatest so that if it fails, this script exits
+# immediately with a failure status.
+full_list=$("$METATEST_PROGRAM" list)
+matching_list=$(printf '%s\n' "$full_list" | list_matches "$@")
+
+if [ -n "$LIST_ONLY" ]; then
+ printf '%s\n' $matching_list
+ exit
+fi
+
+for name in $matching_list; do
+ run_metatest "$name"
+done
+
+if [ $errors -eq 0 ]; then
+ echo "Ran $count metatests, all good."
+ exit 0
+else
+ echo "Ran $count metatests, $errors unexpected successes."
+ exit 1
+fi
diff --git a/tests/src/test_helpers/ssl_helpers.c b/tests/src/test_helpers/ssl_helpers.c
index be2aede..d02d305 100644
--- a/tests/src/test_helpers/ssl_helpers.c
+++ b/tests/src/test_helpers/ssl_helpers.c
@@ -1633,6 +1633,7 @@
}
#endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
int mbedtls_test_ssl_tls12_populate_session(mbedtls_ssl_session *session,
int ticket_len,
const char *crt_file)
@@ -1729,6 +1730,7 @@
return 0;
}
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
int mbedtls_test_ssl_tls13_populate_session(mbedtls_ssl_session *session,
@@ -1746,16 +1748,20 @@
session->resumption_key_len = 32;
memset(session->resumption_key, 0x99, sizeof(session->resumption_key));
-#if defined(MBEDTLS_HAVE_TIME)
+#if defined(MBEDTLS_SSL_EARLY_DATA)
+ session->max_early_data_size = 0x87654321;
+#endif
+
+#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C)
if (session->endpoint == MBEDTLS_SSL_IS_SERVER) {
- session->start = mbedtls_time(NULL) - 42;
+ session->ticket_creation_time = mbedtls_ms_time() - 42;
}
#endif
#if defined(MBEDTLS_SSL_CLI_C)
if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) {
#if defined(MBEDTLS_HAVE_TIME)
- session->ticket_received = mbedtls_time(NULL) - 40;
+ session->ticket_reception_time = mbedtls_ms_time() - 40;
#endif
session->ticket_lifetime = 0xfedcba98;
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index ec8b0dc..42f9f5e 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -240,28 +240,28 @@
}
requires_all_configs_enabled() {
- if ! $P_QUERY -all $*
+ if ! $P_QUERY -all $* 2>&1 > /dev/null
then
SKIP_NEXT="YES"
fi
}
requires_all_configs_disabled() {
- if $P_QUERY -any $*
+ if $P_QUERY -any $* 2>&1 > /dev/null
then
SKIP_NEXT="YES"
fi
}
requires_any_configs_enabled() {
- if ! $P_QUERY -any $*
+ if ! $P_QUERY -any $* 2>&1 > /dev/null
then
SKIP_NEXT="YES"
fi
}
requires_any_configs_disabled() {
- if $P_QUERY -all $*
+ if $P_QUERY -all $* 2>&1 > /dev/null
then
SKIP_NEXT="YES"
fi
diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function
index a19e08a..85776cc 100644
--- a/tests/suites/test_suite_ssl.function
+++ b/tests/suites/test_suite_ssl.function
@@ -1943,16 +1943,21 @@
/* Prepare a dummy session to work on */
((void) endpoint_type);
((void) tls_version);
+ ((void) ticket_len);
+ ((void) crt_file);
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
if (tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
TEST_ASSERT(mbedtls_test_ssl_tls13_populate_session(
&original, 0, endpoint_type) == 0);
- } else
+ }
#endif
- {
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+ if (tls_version == MBEDTLS_SSL_VERSION_TLS1_2) {
TEST_ASSERT(mbedtls_test_ssl_tls12_populate_session(
&original, ticket_len, crt_file) == 0);
}
+#endif
/* Serialize it */
TEST_ASSERT(mbedtls_ssl_session_save(&original, NULL, 0, &len)
@@ -1968,8 +1973,27 @@
* Make sure both session structures are identical
*/
#if defined(MBEDTLS_HAVE_TIME)
- TEST_ASSERT(original.start == restored.start);
+ switch (tls_version) {
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SRV_C)
+ case MBEDTLS_SSL_VERSION_TLS1_3:
+ TEST_ASSERT(original.ticket_creation_time == restored.ticket_creation_time);
+ break;
#endif
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+ case MBEDTLS_SSL_VERSION_TLS1_2:
+ TEST_ASSERT(original.start == restored.start);
+ break;
+#endif
+
+ default:
+ /* should never happen */
+ TEST_ASSERT(0);
+ break;
+ }
+
+
+#endif
+
TEST_ASSERT(original.tls_version == restored.tls_version);
TEST_ASSERT(original.ciphersuite == restored.ciphersuite);
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
@@ -2041,15 +2065,21 @@
restored.resumption_key,
original.resumption_key_len) == 0);
}
+
+#if defined(MBEDTLS_SSL_EARLY_DATA)
+ TEST_ASSERT(
+ original.max_early_data_size == restored.max_early_data_size);
+#endif
+
#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C)
if (endpoint_type == MBEDTLS_SSL_IS_SERVER) {
- TEST_ASSERT(original.start == restored.start);
+ TEST_ASSERT(original.ticket_creation_time == restored.ticket_creation_time);
}
#endif
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
if (endpoint_type == MBEDTLS_SSL_IS_CLIENT) {
#if defined(MBEDTLS_HAVE_TIME)
- TEST_ASSERT(original.ticket_received == restored.ticket_received);
+ TEST_ASSERT(original.ticket_reception_time == restored.ticket_reception_time);
#endif
TEST_ASSERT(original.ticket_lifetime == restored.ticket_lifetime);
TEST_ASSERT(original.ticket_len == restored.ticket_len);
@@ -2090,16 +2120,27 @@
/* Prepare a dummy session to work on */
((void) endpoint_type);
- ((void) tls_version);
+ ((void) ticket_len);
+ ((void) crt_file);
+
+ switch (tls_version) {
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
- if (tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
- TEST_ASSERT(mbedtls_test_ssl_tls13_populate_session(
- &session, 0, endpoint_type) == 0);
- } else
+ case MBEDTLS_SSL_VERSION_TLS1_3:
+ TEST_ASSERT(mbedtls_test_ssl_tls13_populate_session(
+ &session, 0, endpoint_type) == 0);
+ break;
#endif
- {
- TEST_ASSERT(mbedtls_test_ssl_tls12_populate_session(
- &session, ticket_len, crt_file) == 0);
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+ case MBEDTLS_SSL_VERSION_TLS1_2:
+ TEST_ASSERT(mbedtls_test_ssl_tls12_populate_session(
+ &session, ticket_len, crt_file) == 0);
+ break;
+#endif
+ default:
+ /* should never happen */
+ TEST_ASSERT(0);
+ break;
}
/* Get desired buffer size for serializing */
@@ -2153,17 +2194,28 @@
/* Prepare dummy session and get serialized size */
((void) endpoint_type);
- ((void) tls_version);
+ ((void) ticket_len);
+ ((void) crt_file);
+
+ switch (tls_version) {
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
- if (tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
- TEST_ASSERT(mbedtls_test_ssl_tls13_populate_session(
- &session, 0, endpoint_type) == 0);
- } else
+ case MBEDTLS_SSL_VERSION_TLS1_3:
+ TEST_ASSERT(mbedtls_test_ssl_tls13_populate_session(
+ &session, 0, endpoint_type) == 0);
+ break;
#endif
- {
- TEST_ASSERT(mbedtls_test_ssl_tls12_populate_session(
- &session, ticket_len, crt_file) == 0);
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+ case MBEDTLS_SSL_VERSION_TLS1_2:
+ TEST_ASSERT(mbedtls_test_ssl_tls12_populate_session(
+ &session, ticket_len, crt_file) == 0);
+ break;
+#endif
+ default:
+ /* should never happen */
+ TEST_ASSERT(0);
+ break;
}
+
TEST_ASSERT(mbedtls_ssl_session_save(&session, NULL, 0, &good_len)
== MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL);
@@ -2202,17 +2254,30 @@
/* Prepare serialized session data */
((void) endpoint_type);
- ((void) tls_version);
+ ((void) ticket_len);
+ ((void) crt_file);
+
+ switch (tls_version) {
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
- if (tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
- TEST_ASSERT(mbedtls_test_ssl_tls13_populate_session(
- &session, 0, endpoint_type) == 0);
- } else
+ case MBEDTLS_SSL_VERSION_TLS1_3:
+ TEST_ASSERT(mbedtls_test_ssl_tls13_populate_session(
+ &session, 0, endpoint_type) == 0);
+ break;
#endif
- {
- TEST_ASSERT(mbedtls_test_ssl_tls12_populate_session(
- &session, ticket_len, crt_file) == 0);
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+ case MBEDTLS_SSL_VERSION_TLS1_2:
+ TEST_ASSERT(mbedtls_test_ssl_tls12_populate_session(
+ &session, ticket_len, crt_file) == 0);
+ break;
+#endif
+
+ default:
+ /* should never happen */
+ TEST_ASSERT(0);
+ break;
}
+
TEST_ASSERT(mbedtls_ssl_session_save(&session, NULL, 0, &good_len)
== MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL);
TEST_CALLOC(good_buf, good_len);
@@ -2261,16 +2326,26 @@
mbedtls_ssl_session_init(&session);
USE_PSA_INIT();
((void) endpoint_type);
- ((void) tls_version);
-#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
- if (tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
- TEST_ASSERT(mbedtls_test_ssl_tls13_populate_session(
- &session, 0, endpoint_type) == 0);
- } else
-#endif
- TEST_ASSERT(mbedtls_test_ssl_tls12_populate_session(
- &session, 0, NULL) == 0);
+ switch (tls_version) {
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
+ case MBEDTLS_SSL_VERSION_TLS1_3:
+ TEST_ASSERT(mbedtls_test_ssl_tls13_populate_session(
+ &session, 0, endpoint_type) == 0);
+ break;
+#endif
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+ case MBEDTLS_SSL_VERSION_TLS1_2:
+ TEST_ASSERT(mbedtls_test_ssl_tls12_populate_session(
+ &session, 0, NULL) == 0);
+
+ break;
+#endif
+ default:
+ /* should never happen */
+ TEST_ASSERT(0);
+ break;
+ }
/* Infer length of serialized session. */
TEST_ASSERT(mbedtls_ssl_session_save(&session,