diff --git a/ChangeLog.d/issue665.txt b/ChangeLog.d/issue665.txt new file mode 100644 index 0000000000..7d3da9ebce --- /dev/null +++ b/ChangeLog.d/issue665.txt @@ -0,0 +1,6 @@ +Bugfix + * Fix a bug that caused GCM tag calculations to fail, so that data was + correctly encrypted but could not be authenticated. The bug was only + observed with GCC 10.0 to 14.2 inclusive, when compiling with -O3, and + running without AESNI or AESCE. + Fixes #665. diff --git a/library/alignment.h b/library/alignment.h index a17001dd91..3c107d8695 100644 --- a/library/alignment.h +++ b/library/alignment.h @@ -15,6 +15,7 @@ #include #include +#if !defined(MBEDTLS_ALIGNMENT_DISABLE_EFFICENT_UNALIGNED_ACCESS) //no-check-names /* * Define MBEDTLS_EFFICIENT_UNALIGNED_ACCESS for architectures where unaligned memory * accesses are known to be efficient. @@ -35,7 +36,9 @@ * device memory). */ #define MBEDTLS_EFFICIENT_UNALIGNED_ACCESS -#endif +#endif /* __ARM_FEATURE_UNALIGNED || MBEDTLS_ARCH_IS_X86 || MBEDTLS_ARCH_IS_X64 || + * MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64 */ +#endif /* MBEDTLS_ALIGNMENT_DISABLE_EFFICENT_UNALIGNED_ACCESS */ //no-check-names #if defined(__IAR_SYSTEMS_ICC__) && \ (defined(MBEDTLS_ARCH_IS_ARM64) || defined(MBEDTLS_ARCH_IS_ARM32) \ @@ -85,13 +88,13 @@ typedef uint64_t __packed mbedtls_uint64_unaligned_t; #define UINT_UNALIGNED_STRUCT typedef struct { uint16_t x; -} __attribute__((packed)) mbedtls_uint16_unaligned_t; +} __attribute__((packed, may_alias)) mbedtls_uint16_unaligned_t; typedef struct { uint32_t x; -} __attribute__((packed)) mbedtls_uint32_unaligned_t; +} __attribute__((packed, may_alias)) mbedtls_uint32_unaligned_t; typedef struct { uint64_t x; -} __attribute__((packed)) mbedtls_uint64_unaligned_t; +} __attribute__((packed, may_alias)) mbedtls_uint64_unaligned_t; #endif /* diff --git a/tests/scripts/components-compiler.sh b/tests/scripts/components-compiler.sh index 1eac64f54d..b764247380 100644 --- a/tests/scripts/components-compiler.sh +++ b/tests/scripts/components-compiler.sh @@ -172,3 +172,45 @@ component_test_zeroize () { done done } + +# This originated from an issue (https://github.com/Mbed-TLS/TF-PSA-Crypto/issues/665) found +# in GCM when the library is built with GCC "10.0 <= version <= 14.2" on platforms other than +# x86 and ARM64. +component_test_tf_psa_crypto_optimized_alignment() { + msg "build: verify alignment with O3 optimizations in GCC" + + # Disable optimizations for x86 (and ARM64) so that alignment related problems in + # "alignment.h" can be tested also on standard PC. + scripts/config.py unset MBEDTLS_AESNI_C + scripts/config.py unset MBEDTLS_AESCE_C + + # "-O3" is the optimization level that causes issues: the compiler tries to + # optimize operations order and if memory dependencies are not respected + # (as it happens in issue tf-psa-crypto#665) this completely messes up results. + EXTRA_C_FLAGS="-O3" + # Forcedly ignore "MBEDTLS_EFFICIENT_UNALIGNED_ACCESS" on x86 so that we + # can test the problematic case, i.e. the case where uint64 integers are + # accessed through "mbedtls_uint64_unaligned_t" structs. + EXTRA_C_FLAGS="$EXTRA_C_FLAGS -DMBEDTLS_ALIGNMENT_DISABLE_EFFICENT_UNALIGNED_ACCESS" + # Adding '-g3' flag doesn't affect testing, BUT it allows to dump the generated + # assembly code for "gcm.o" module for inspection. To do this use the + # following command: + # > objdump -S --disassemble out_of_source_build/drivers/builtin/CMakeFiles/builtin.dir/src/gcm.c.o > gcm.s + # A file named "gcm.s" will be generated containing a mix of C and corresponding + # assembly code. + EXTRA_C_FLAGS="$EXTRA_C_FLAGS -g3" + + make CC=gcc CFLAGS="$EXTRA_C_FLAGS" + + msg "test: verify alignment with O3 optimizations in GCC" + make test +} + +support_test_tf_psa_crypto_optimized_alignment() { + case $(gcc -dumpfullversion 2>/dev/null) in + ""|?.*) false;; # too old + 10.*|11.*|12.*|13.*) true;; + 14.[012].*) true;; + *) false;; # too recent + esac +}