From bdd01a74ef4e345083c2220ea9684f0cf9ec382c Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Wed, 8 Mar 2023 14:19:51 +0000 Subject: [PATCH 1/2] Implement and use MBEDTLS_STATIC_ASSERT() Fixes #3693 Signed-off-by: Tom Cosgrove --- library/common.h | 31 +++++++++++++++++++++++++++++++ library/psa_crypto.c | 24 ++++++++++-------------- library/psa_crypto_se.c | 7 ++----- 3 files changed, 43 insertions(+), 19 deletions(-) diff --git a/library/common.h b/library/common.h index 2786c97d40e9..012044c68bde 100644 --- a/library/common.h +++ b/library/common.h @@ -29,6 +29,7 @@ #include "mbedtls/config.h" #endif +#include #include #include @@ -347,4 +348,34 @@ static inline const unsigned char *mbedtls_buffer_offset_const( } #endif +/* 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 d8a9940453db..bad7f469781b 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -47,7 +47,6 @@ #include "psa_crypto_random_impl.h" -#include #include #include #include "mbedtls/platform.h" @@ -1512,14 +1511,12 @@ psa_status_t psa_export_public_key(mbedtls_svc_key_id_t key, 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. * @@ -1782,11 +1779,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 b660393640d5..7bea10ad64ac 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 @@ -315,10 +314,8 @@ 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; } From 410594c002454d30904abdb6123c2c66be1cd3df Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Tue, 14 Mar 2023 12:03:47 +0000 Subject: [PATCH 2/2] Have MBEDTLS_STATIC_ASSERT() match current development more closely Signed-off-by: Tom Cosgrove --- library/common.h | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/library/common.h b/library/common.h index 012044c68bde..e162aa3cffe4 100644 --- a/library/common.h +++ b/library/common.h @@ -349,7 +349,7 @@ static inline const unsigned char *mbedtls_buffer_offset_const( #endif /* Always provide a static assert macro, so it can be used unconditionally. - * Note that it will expand to nothing on some systems. + * 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). @@ -358,22 +358,6 @@ static inline const unsigned char *mbedtls_buffer_offset_const( */ #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