From 6ef9bb3d74b6c91183c32e6a4311f4c80453d56a Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Wed, 8 Mar 2023 14:19:51 +0000 Subject: [PATCH] Implement and use MBEDTLS_STATIC_ASSERT() Fixes #3693 Signed-off-by: Tom Cosgrove --- library/common.h | 31 +++++++++++++++++++++++++++++++ library/psa_crypto.c | 27 +++++++++++++-------------- library/psa_crypto_se.c | 8 +++----- library/ssl_tls.c | 10 +++------- library/ssl_tls12_server.c | 7 +++---- 5 files changed, 53 insertions(+), 30 deletions(-) diff --git a/library/common.h b/library/common.h index 46af79f0da..d42237b1c5 100644 --- a/library/common.h +++ b/library/common.h @@ -26,6 +26,7 @@ #include "mbedtls/build_info.h" #include "alignment.h" +#include #include #include #include @@ -149,4 +150,34 @@ inline void mbedtls_xor(unsigned char *r, const unsigned char *a, const unsigned #endif /* *INDENT-ON* */ +/* Always provide a static assert macro, so it can be used unconditionally. + * Note that it will expand to nothing on some systems. + * Can be used outside functions (but don't add a trailing ';' in that case: + * the semicolon is included here to avoid triggering -Wextra-semi when + * MBEDTLS_STATIC_ASSERT() expands to nothing). + * Can't use the C11-style `defined(static_assert)` on FreeBSD, since it + * defines static_assert even with -std=c99, but then complains about it. + */ +#if defined(static_assert) && !defined(__FreeBSD__) +#define MBEDTLS_STATIC_ASSERT(expr, msg) static_assert(expr, msg); +#elif defined(__COUNTER__) +/* gcc will say "size of array ‘mbedtls_static_assert_failedN’ is negative" + * (and with -pedantic will complain further); + * clang will say "'mbedtls_static_assert_failedN' declared as an array with a + * negative size"; + * Visual Studio will just say "error C2118: negative subscript" (without the + * mbedtls_static_assert_failedN part) + */ +#if defined(__GNUC__) +#define MBEDTLS_UNUSED __attribute__((unused)) +#else +#define MBEDTLS_UNUSED +#endif +#define MBEDTLS_STATIC_ASSERT2(expr, count) extern int MBEDTLS_UNUSED mbedtls_static_assert_failed ## count [2 * !!(expr) - 1]; +#define MBEDTLS_STATIC_ASSERT1(expr, count) MBEDTLS_STATIC_ASSERT2(expr, count) +#define MBEDTLS_STATIC_ASSERT(expr, msg) MBEDTLS_STATIC_ASSERT1(expr, __COUNTER__) +#else +#define MBEDTLS_STATIC_ASSERT(expr, msg) +#endif + #endif /* MBEDTLS_LIBRARY_COMMON_H */ diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 0efebb40ce..e01ee474fc 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -48,7 +48,6 @@ #include "psa_crypto_random_impl.h" -#include #include #include #include "mbedtls/platform.h" @@ -1471,14 +1470,15 @@ exit: return (status == PSA_SUCCESS) ? unlock_status : status; } -#if defined(static_assert) -static_assert((MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_DUAL_USE) == 0, - "One or more key attribute flag is listed as both external-only and dual-use"); -static_assert((PSA_KA_MASK_INTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_DUAL_USE) == 0, - "One or more key attribute flag is listed as both internal-only and dual-use"); -static_assert((PSA_KA_MASK_INTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY) == 0, - "One or more key attribute flag is listed as both internal-only and external-only"); -#endif +MBEDTLS_STATIC_ASSERT( + (MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_DUAL_USE) == 0, + "One or more key attribute flag is listed as both external-only and dual-use") +MBEDTLS_STATIC_ASSERT( + (PSA_KA_MASK_INTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_DUAL_USE) == 0, + "One or more key attribute flag is listed as both internal-only and dual-use") +MBEDTLS_STATIC_ASSERT( + (PSA_KA_MASK_INTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY) == 0, + "One or more key attribute flag is listed as both internal-only and external-only") /** Validate that a key policy is internally well-formed. * @@ -1742,11 +1742,10 @@ static psa_status_t psa_finish_key_creation( psa_key_slot_number_t slot_number = psa_key_slot_get_slot_number(slot); -#if defined(static_assert) - static_assert(sizeof(slot_number) == - sizeof(data.slot_number), - "Slot number size does not match psa_se_key_data_storage_t"); -#endif + MBEDTLS_STATIC_ASSERT(sizeof(slot_number) == + sizeof(data.slot_number), + "Slot number size does not match psa_se_key_data_storage_t"); + memcpy(&data.slot_number, &slot_number, sizeof(slot_number)); status = psa_save_persistent_key(&slot->attr, (uint8_t *) &data, diff --git a/library/psa_crypto_se.c b/library/psa_crypto_se.c index dee780f46e..9db3dedce9 100644 --- a/library/psa_crypto_se.c +++ b/library/psa_crypto_se.c @@ -22,7 +22,6 @@ #if defined(MBEDTLS_PSA_CRYPTO_SE_C) -#include #include #include @@ -313,10 +312,9 @@ psa_status_t psa_register_se_driver( } /* Driver table entries are 0-initialized. 0 is not a valid driver * location because it means a transparent key. */ -#if defined(static_assert) - static_assert(PSA_KEY_LOCATION_LOCAL_STORAGE == 0, - "Secure element support requires 0 to mean a local key"); -#endif + MBEDTLS_STATIC_ASSERT(PSA_KEY_LOCATION_LOCAL_STORAGE == 0, + "Secure element support requires 0 to mean a local key"); + if (location == PSA_KEY_LOCATION_LOCAL_STORAGE) { return PSA_ERROR_INVALID_ARGUMENT; } diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 19bd12788e..81e68f61fe 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -25,8 +25,6 @@ #if defined(MBEDTLS_SSL_TLS_C) -#include - #include "mbedtls/platform.h" #include "mbedtls/ssl.h" @@ -1196,11 +1194,9 @@ static int ssl_handshake_init(mbedtls_ssl_context *ssl) size_t sig_algs_len = 0; uint16_t *p; -#if defined(static_assert) - static_assert(MBEDTLS_SSL_MAX_SIG_ALG_LIST_LEN - <= (SIZE_MAX - (2 * sizeof(uint16_t))), - "MBEDTLS_SSL_MAX_SIG_ALG_LIST_LEN too big"); -#endif + MBEDTLS_STATIC_ASSERT(MBEDTLS_SSL_MAX_SIG_ALG_LIST_LEN + <= (SIZE_MAX - (2 * sizeof(uint16_t))), + "MBEDTLS_SSL_MAX_SIG_ALG_LIST_LEN too big"); for (md = sig_hashes; *md != MBEDTLS_MD_NONE; md++) { if (mbedtls_ssl_hash_from_md_alg(*md) == MBEDTLS_SSL_HASH_NONE) { diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c index 0806f7f5c8..631331d821 100644 --- a/library/ssl_tls12_server.c +++ b/library/ssl_tls12_server.c @@ -1510,10 +1510,9 @@ read_record_header: MBEDTLS_TLS_SIG_NONE }; -#if defined(static_assert) - static_assert(sizeof(default_sig_algs) / sizeof(default_sig_algs[0]) <= - MBEDTLS_RECEIVED_SIG_ALGS_SIZE, "default_sig_algs is too big"); -#endif + MBEDTLS_STATIC_ASSERT(sizeof(default_sig_algs) / sizeof(default_sig_algs[0]) + <= MBEDTLS_RECEIVED_SIG_ALGS_SIZE, + "default_sig_algs is too big"); memcpy(received_sig_algs, default_sig_algs, sizeof(default_sig_algs)); }