I'm getting differing results from AES_set_encrypt_key() depending on which architecture I'm compiling for. As far as I understand it, key expansion is deterministic which would mean that something else is wrong.
I've set up a simple print and compare with diff to easily verify differences.
If anyone has any ideas I would be very grateful
debug.sh:
#!/bin/bash
gcc -std=c99 -m32 bug.c -lssl -o test && ./test > m32.log && \
gcc -std=c99 -m64 bug.c -lssl -o test && ./test > m64.log && \
diff m32.log m64.log
bug.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/aes.h>
void
hexdump(FILE *f, const char *title, const unsigned char *s, int length)
{
for(int n = 0; n < length ; ++n) {
if((n%16) == 0)
fprintf(f, "\n%s %04x", title, n);
fprintf(f, " %02x", s[n]);
}
fprintf(f, "\n");
}
int main()
{
char *key = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
AES_KEY aes_key;
if(AES_set_encrypt_key((unsigned char*) key, 128, &aes_key) != 0)
return EXIT_FAILURE;
hexdump(stdout, "AES_KEY", (unsigned char*) &aes_key, sizeof(AES_KEY));
return EXIT_SUCCESS;
}
diff:
2,16c2,16
< AES_KEY 0000 65 72 6f 4c 70 69 20 6d 20 6d 75 73 6f 6c 6f 64
< AES_KEY 0010 26 da 3f e5 56 b3 1f 88 76 de 6a fb 19 b2 05 9f
< AES_KEY 0020 fd 0e 08 8c ab bd 17 04 dd 63 7d ff c4 d1 78 60
< AES_KEY 0030 2d 12 36 34 86 af 21 30 5b cc 5c cf 9f 1d 24 af
< AES_KEY 0040 54 c9 92 0a d2 66 b3 3a 89 aa ef f5 16 b7 cb 5a
< AES_KEY 0050 ea 8e 3b 05 38 e8 88 3f b1 42 67 ca a7 f5 ac 90
< AES_KEY 0060 8a d2 dd b4 b2 3a 55 8b 03 78 32 41 a4 8d 9e d1
< AES_KEY 0070 b4 9b 80 ff 06 a1 d5 74 05 d9 e7 35 a1 54 79 e4
< AES_KEY 0080 dd a9 a0 c9 db 08 75 bd de d1 92 88 7f 85 eb 6c
< AES_KEY 0090 8d 7b 37 3b 56 73 42 86 88 a2 d0 0e f7 27 3b 62
< AES_KEY 00a0 27 13 fb ef 71 60 b9 69 f9 c2 69 67 0e e5 52 05
< AES_KEY 00b0 88 fe 95 ff e5 2a 62 f7 00 00 00 00 f4 9f 04 08
< AES_KEY 00c0 98 fe 95 ff 44 84 04 08 90 ce 7d f7 f4 9f 04 08
< AES_KEY 00d0 c8 fe 95 ff 89 86 04 08 24 33 76 f7 f4 2f 76 f7
< AES_KEY 00e0 70 86 04 08 c8 fe 95 ff 65 b9 63 f7 90 ce 7d f7
---
> AES_KEY 0000 4c 6f 72 65 6d 20 69 70 73 75 6d 20 64 6f 6c 6f
> AES_KEY 0010 e5 3f da 26 88 1f b3 56 fb 6a de 76 9f 05 b2 19
> AES_KEY 0020 8c 08 0e fd 04 17 bd ab ff 7d 63 dd 60 78 d1 c4
> AES_KEY 0030 34 36 12 2d 30 21 af 86 cf 5c cc 5b af 24 1d 9f
> AES_KEY 0040 0a 92 c9 54 3a b3 66 d2 f5 ef aa 89 5a cb b7 16
> AES_KEY 0050 05 3b 8e ea 3f 88 e8 38 ca 67 42 b1 90 ac f5 a7
> AES_KEY 0060 b4 dd d2 8a 8b 55 3a b2 41 32 78 03 d1 9e 8d a4
> AES_KEY 0070 ff 80 9b b4 74 d5 a1 06 35 e7 d9 05 e4 79 54 a1
> AES_KEY 0080 c9 a0 a9 dd bd 75 08 db 88 92 d1 de 6c eb 85 7f
> AES_KEY 0090 3b 37 7b 8d 86 42 73 56 0e d0 a2 88 62 3b 27 f7
> AES_KEY 00a0 ef fb 13 27 69 b9 60 71 67 69 c2 f9 05 52 e5 0e
> AES_KEY 00b0 00 00 00 00 00 00 00 00 db 05 40 00 00 00 00 00
> AES_KEY 00c0 58 65 e0 e0 ff 7f 00 00 65 08 40 00 00 00 00 00
> AES_KEY 00d0 68 6b e6 0b e6 7f 00 00 20 08 40 00 00 00 00 00
> AES_KEY 00e0 00 00 00 00 00 00 00 00 30 06 40 00 00 00 00 00
gcc -Wl,-t -std=c99 -m32 bug.c -l ssl -o test
/usr/bin/ld: mode elf_i386
/usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib32/crt1.o
/usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib32/crti.o
/usr/lib/gcc/x86_64-linux-gnu/4.4.5/32/crtbegin.o
/tmp/ccppFYUU.o
-lssl (/lib/../lib32/libssl.so)
-lgcc_s (/usr/lib/gcc/x86_64-linux-gnu/4.4.5/32/libgcc_s.so)
/lib32/libc.so.6 (//lib32/libc.so.6)
(//usr/lib32/libc_nonshared.a)elf-init.oS
/lib32/ld-linux.so.2 (//lib32/ld-linux.so.2)
-lgcc_s (/usr/lib/gcc/x86_64-linux-gnu/4.4.5/32/libgcc_s.so)
/usr/lib/gcc/x86_64-linux-gnu/4.4.5/32/crtend.o
/usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib32/crtn.o
gcc -Wl,-t -std=c99 -m64 bug.c -l ssl -o test
/usr/bin/ld: mode elf_x86_64
/usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib/crt1.o
/usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib/crti.o
/usr/lib/gcc/x86_64-linux-gnu/4.4.5/crtbegin.o
/tmp/cclvw4XV.o
-lssl (/usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib/libssl.so)
-lgcc_s (/usr/lib/gcc/x86_64-linux-gnu/4.4.5/libgcc_s.so)
/lib/libc.so.6 (//lib/libc.so.6)
(//usr/lib/libc_nonshared.a)elf-init.oS
/lib/ld-linux-x86-64.so.2 (//lib/ld-linux-x86-64.so.2)
-lgcc_s (/usr/lib/gcc/x86_64-linux-gnu/4.4.5/libgcc_s.so)
/usr/lib/gcc/x86_64-linux-gnu/4.4.5/crtend.o
/usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib/crtn.o
You are comparing private binary representation of key inside openssl library. This implementation detail is not meant to be consistent across platforms. OpenSSL uses optimized assembly functions for encryption and decryption, and these optimized routines store key differently.
aes.h public header contains note in comment:
/* This should be a hidden type, but EVP requires that the size be known */
struct aes_key_st {
#ifdef AES_LONG
unsigned long rd_key[4 *(AES_MAXNR + 1)];
#else
unsigned int rd_key[4 *(AES_MAXNR + 1)];
#endif
int rounds;
};
typedef struct aes_key_st AES_KEY;
Please take a look yourself (paths from openssl source tarball):
Depending on cpu type you can get different results event on 32bit 386-compatible pc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With