2012-06-25 41 views
4

根據我編譯的體系結構,我得到的AES_set_encrypt_key()結果不同。 據我瞭解,重點擴張是確定性的,這意味着其他事情是錯誤的。OpenSSL AES_set_encrypt_key根據編譯目標的不同而不同

我已經設置了一個簡單的打印並與diff進行比較以輕鬆驗證差異。

如果任何人有任何想法,我將非常感激

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測試

/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錯誤。 ç-l SSL -o測試

/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 
+0

如果差異(或日誌文件)不是很大,爲什麼不把它添加到您的問題?另外,由於您將庫放在源代碼之前('-lssl'應該出現在'bug.c'之後),所以我有點驚訝它正確鏈接。 –

+0

我加了輸出。並通過正確的順序進行測試,但沒有幫助。謝謝,但我錯過了。 –

回答

3

您正在比較openssl庫中的密鑰的私有二進制表示形式。此實現細節並不意味着跨平臺保持一致。 OpenSSL使用優化的彙編函數進行加密和解密,並且這些優化的例程以不同的方式存儲密鑰。

aes.h公共頭包含音符的評論:

/* 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; 

請看看你自己(從OpenSSL的源碼包路徑):

  • 加密/ AES/aes_misc.c:AES_set_encrypt_key電話private_AES_set_encrypt_key
  • crypto/aes/asm/{.pl | .S}:有private_AES_set_encrypt_key

的許多實現根據CPU的類型,你可以在32位386兼容PC得到不同的結果事件。

1

我檢查或控制您鏈接什麼*。即使用:

gcc -Wl,-t -std=c99 -m64 bug.c -l ssl 

並檢查你是否鏈接你認爲你是。或者使用'gcc -c ...'來創建一個bug.o並將其手動/明確地鏈接到您確定是正確的庫。 32位(65 72 6f 4c ...)是'正確'的。

Dw。

**:在大多數matuire平臺上,當搜索-lssl時,應該得到'/ usr/bin/ld:跳過不兼容。

+0

我使用gcc -Wl編譯成代碼,-t但輸出看起來正確。輸出被添加到帖子的底部。 –

+0

嗯 - 你的userKey顯然沒有被完全使用(從內存到字節32)。但你的時間更長。所以這應該沒問題。您並未將您的密鑰歸零 - 但這很好 - AES_set_encrypt_key()從您的用戶字符串的前32個字節開始將它初始化。所以我所能想到的是在你的64位庫中鏈接的東西中有趣的東西;或者它如何鏈接/對齊。 nm或ldd也不會顯示任何明顯的錯誤? –

3

這兩個AES_KEY s沒有那麼不同,它看起來很快。 兩者都會存儲4個字節的長整數,不同的是按字節順序排列。似乎另一個使用大端,另一個使用小端。

如果變化字節順序開始另一個AES_KEY的:

0000 65 72 6f 4c 

您將獲得:

0000 4c 6f 72 65 

這正是一樣的開始otherone的。

另一個區別在於這些AES_KEY值的結尾。 因爲您不使用最大密鑰大小,所以不需要全部AES。所以沒有必要初始化整個AES_KEY結構。所以最後4行hexdump可以從堆棧中初始化未初始化的垃圾。

+0

爲什麼這不是被批准的答案...? – geomaster

相關問題