[PATCH v2 2/2] fips: Fix self-check compiled with clang
Clemens Lang
cllang at redhat.com
Mon Feb 14 18:50:00 CET 2022
* src/fips.c [ENABLE_HMAC_BINARY_CHECK] (hmac256_check): Prevent
constant propagation of a 0 HMAC value.
--
clang 13 assumes that the static const unsigned char[32]
hmac_for_the_implementation is zero, propagates this constant into its
use in hmac256_check and replaces with invocation of memcmp(3) with
assembly instructions that compare the computed digest with 0.
clang is able to make this assumption, because a 0-initialized static
const variable should never change its value, but this assumption is
invalid as soon as objcpy(1) changes the HMAC in the binary.
Apply a suggestion from [1] to prevent this optimization.
[1]: https://bugzilla.redhat.com/show_bug.cgi?id=2034320#c22
Signed-off-by: Clemens Lang <cllang at redhat.com>
---
src/Makefile.am | 4 ++--
src/fips.c | 11 ++++++++++-
2 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/src/Makefile.am b/src/Makefile.am
index b0a196a3..b799e52d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -143,14 +143,14 @@ if USE_HMAC_BINARY_CHECK
CLEANFILES += libgcrypt.so.hmac
libgcrypt.la.done: libgcrypt.so.hmac
- $(OBJCOPY) --update-section .rodata1=libgcrypt.so.hmac \
+ $(OBJCOPY) --update-section .rodata_fips_hmac=libgcrypt.so.hmac \
.libs/libgcrypt.so .libs/libgcrypt.so.new
mv -f .libs/libgcrypt.so.new .libs/libgcrypt.so.*.*
@touch libgcrypt.la.done
libgcrypt.so.hmac: hmac256 libgcrypt.la
dd if=/dev/zero of=libgcrypt.so.hmac.empty bs=32 count=1
- $(OBJCOPY) --update-section .rodata1=libgcrypt.so.hmac.empty \
+ $(OBJCOPY) --update-section .rodata_fips_hmac=libgcrypt.so.hmac.empty \
.libs/libgcrypt.so .libs/libgcrypt.so.empty-hmac
./hmac256 --stdkey --binary .libs/libgcrypt.so.empty-hmac > $@
$(RM) libgcrypt.so.hmac.empty .libs/libgcrypt.so.empty-hmac
diff --git a/src/fips.c b/src/fips.c
index c40274d9..35546b8c 100644
--- a/src/fips.c
+++ b/src/fips.c
@@ -593,9 +593,18 @@ run_random_selftests (void)
# endif
#define HMAC_LEN 32
-static const unsigned char __attribute__ ((section (".rodata1")))
+extern const unsigned char __attribute__ ((visibility ("hidden")))
hmac_for_the_implementation[HMAC_LEN];
+__asm (".hidden hmac_for_the_implementation\n\t"
+ ".type hmac_for_the_implementation, %object\n\t"
+ ".size hmac_for_the_implementation, 32\n\t"
+ ".section .rodata_fips_hmac,\"a\"\n\t"
+ ".balign 16\n"
+ "hmac_for_the_implementation:\n\t"
+ ".zero 32\n\t"
+ ".previous");
+
/**
* Determine the offset of the given virtual address in the ELF file opened as
* fp and return it in offset. Rewinds fp to the beginning on success.
--
2.35.1
More information about the Gcrypt-devel
mailing list