Implement and use MBEDTLS_STATIC_ASSERT()
Fixes #3693
Signed-off-by: Tom Cosgrove <tom.cosgrove@arm.com>
diff --git a/library/common.h b/library/common.h
index 2786c97..012044c 100644
--- a/library/common.h
+++ b/library/common.h
@@ -29,6 +29,7 @@
#include "mbedtls/config.h"
#endif
+#include <assert.h>
#include <stddef.h>
#include <stdint.h>
@@ -347,4 +348,34 @@
}
#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 d8a9940..bad7f46 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -47,7 +47,6 @@
#include "psa_crypto_random_impl.h"
-#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "mbedtls/platform.h"
@@ -1512,14 +1511,12 @@
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 @@
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 b660393..7bea10a 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 <assert.h>
#include <stdint.h>
#include <string.h>
@@ -315,10 +314,8 @@
}
/* 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;
}