ctr_encrypt ctr->pad not aligned
mkj opened this issue · comments
Description
Running under ubsan catches undefined behaviour in ctr_encrypt
. The problem is that ctr->pad isn't 16 byte aligned, but we have a cast to a ulong64
. I'm not sure how important it is for portability, I guess x64 works fine? Unsure the best way to fix it, other than just disabling LTC_FAST for that section - maybe the compiler will unroll it anyway...
ctr_encrypt.c:63 *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ctr->pad + x));
Steps to Reproduce
make CC=clang CFLAGS="-fsanitize=undefined -fno-sanitize-recover=undefined -DUSE_LTM -DLTM_DESC" EXTRALIBS="-ltommath" LD=clang++ LDFLAGS=-fsanitize=undefined test
./test
...
store_test..........src/modes/ctr/ctr_encrypt.c:57:60: runtime error: load of misaligned address 0x000000eae01c for type 'LTC_FAST_TYPE' (aka 'unsigned long long'), which requires 8 byte alignment
0x000000eae01c: note: pointer points here
00 00 00 00 9e 26 81 83 ff ee e7 0b 2e 07 2e 5c 68 ee e6 29 00 00 00 00 00 00 00 00 00 00 00 00
^
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior src/modes/ctr/ctr_encrypt.c:57:60 in
Version
v1.18.2-595-gcfbd7f8d
Ubuntu 20.04, x64
clang 10.0.0-4ubuntu1
It seems to come from an issue with the symmetric_CTR
definition, which defines 5 (32-bit) leading intergers, so the next 16-byte buffers end up aligned on a 32-bit boundary.
A quick & dirty workaround:
--- a/src/headers/tomcrypt_cipher.h
+++ b/src/headers/tomcrypt_cipher.h
@@ -290,6 +290,8 @@ typedef struct {
mode,
/** counter width */
ctrlen;
+ /** fix alignment issues with pad & LTC_FAST mode on 64-bit hosts */
+ int dummy;
/** The counter */
unsigned char ctr[MAXBLOCKSIZE],
@@ -306,7 +308,6 @@ typedef struct {
typedef struct {
/** The index of the cipher chosen (must be a 128-bit block cipher) */
but a proper fix would require to force the compiler to align the pad (and maybe other) buffers.
can you please check whether #560 solves this?
Ah, #560 fixes CTR->pad[]
but now pt
is also unaligned. You're right about "and maybe other buffers".
Failing as below where pt
comes from buf+z
// tests/store_test.c:56
for (z = 0; z < y; z++) {
/* fill y bytes with random */
yarrow_read(buf+z, y, &yarrow_prng);
store_test..........src/modes/ctr/ctr_encrypt.c:56:66: runtime error: load of misaligned address 0x7ffdb93ce3c1 for type 'LTC_FAST_TYPE' (aka 'unsigned long long'), which requires 8 byte alignment
0x7ffdb93ce3c1: note: pointer points here
00 00 00 13 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 5a cd 1c 49 51 5c ba a0 bd c2 32 54
^
#0 0x503e99 in s_ctr_encrypt /home/matt/src/libtomcrypt/src/modes/ctr/ctr_encrypt.c:56:66
#1 0x4e6974 in yarrow_read /home/matt/src/libtomcrypt/src/prngs/yarrow.c:231:8
#2 0x441685 in store_test /home/matt/src/libtomcrypt/tests/store_test.c:56:6
#3 0x441e1b in main /home/matt/src/libtomcrypt/tests/test.c:408:11