了解OpenSSL的AES解密实现的汇编版本

时间:2017-10-23 07:17:39

标签: c linux assembly openssl aes

我正在尝试理解 OpenSSL如何使用汇编语言实现AES解密,并且我正在使用 gdb调试器

从非常基本的概念中理解 AES如何工作 - 如字节替换,混合列或如何执行查找表操作。我正在使用非常旧版本的OpenSSL-0.9.8.a作为它只包含一个汇编文件ax86-elf.s(从aes-586.pl生成),而最新的Openssl包含多个文件(支持AES-NI,SSE等)。

在了解Old OpenSSL之后,我可能会尝试研究最新的OpenSSL版本。

这是我到目前为止所做的工作。

可以在此处找到ax86-elf.s的生成汇编代码 https://pastebin.com/L3FsbqmK  它有全局标签AES_Td ,它指向一些长数据。我认为这些长数据是AES查找表数据。

.globl  AES_Td
.text
.globl  _x86_AES_decrypt
.type   _x86_AES_decrypt,@function
.align  16
_x86_AES_decrypt:
    movl    %edi,       12(%esp)
...
...
    .align  64
    AES_Td:
        .long   1353184337,1353184337
        .long   1399144830,1399144830
        .long   3282310938,3282310938
        .long   2522752826,2522752826
        .long   3412831035,3412831035
        .long   4047871263,4047871263
        .long   2874735276,2874735276
        .long   2466505547,2466505547
        .long   1442459680,1442459680

要调试openssl,我使用了gdb。

   gdb /usr/local/ssl/bin/openssl 

    (gdb) set args enc -d -aes-128-cbc -in ciphertext2.bin -out plaintext2.txt -K 0123456789abcdef0123456789abcdef -iv 00000000000000000000000000000000

(gdb) set logging on
Copying output to gdb.txt.

(gdb) b main
Breakpoint 1 at 0x8055591

(gdb) b _x86_AES_decrypt
Function "_x86_AES_decrypt" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y

(gdb) run
Starting program: /usr/local/ssl/bin/openssl enc -d -aes-128-cbc -in ciphertext2.bin -out plaintext2.txt -K 0123456789abcdef0123456789abcdef -iv 00000000000000000000000000000000

Breakpoint 1, 0x08055591 in main ()

(gdb) s
Single stepping until exit from function main,
which has no line number information.
__GI_getenv (name=0x8090a32 "OPENSSL_DEBUG_MEMORY") at getenv.c:35
35  getenv.c: No such file or directory.

(gdb) 
__x86.get_pc_thunk.bx () at ../sysdeps/i386/i686/multiarch/strcat.S:55
55  ../sysdeps/i386/i686/multiarch/strcat.S: No such file or directory.

(gdb) 
__GI_getenv (name=0x8090a32 "OPENSSL_DEBUG_MEMORY") at getenv.c:36
36  getenv.c: No such file or directory.

(gdb) 
__strlen_ia32 () at ../sysdeps/i386/i686/multiarch/../../i586/strlen.S:43
43  ../sysdeps/i386/i686/multiarch/../../i586/strlen.S: No such file or directory.

现在显示getenv.c被调用,然后调用../sysdeps/i386/i686/multiarch/../../i586/strlen.S(虽然我无法查看源代码,因为非-availablity)。

我想知道这样的方式我能够理解代码,因为它显示了很多源代码不可用的函数调用。

所以我遵循第二种方法,没有在主要方面设置任何断点。

    gdb /usr/local/ssl/bin/openssl 

    (gdb) set args enc -d -aes-128-cbc -in ciphertext2.bin -out plaintext2.txt -K 0123456789abcdef0123456789abcdef -iv 00000000000000000000000000000000
    (gdb) set logging on
    Copying output to gdb.txt.
    (gdb) b _x86_AES_decrypt
    Function "_x86_AES_decrypt" not defined.
    Make breakpoint pending on future shared library load? (y or [n]) y

    Breakpoint 1 (_x86_AES_decrypt) pending.
    (gdb) run
    Starting program: /usr/local/ssl/bin/openssl enc -d -aes-128-cbc -in ciphertext2.bin -out plaintext2.txt -K 0123456789abcdef0123456789abcdef -iv 00000000000000000000000000000000

    Breakpoint 1, 0xb7e57590 in _x86_AES_decrypt ()
       from /usr/local/ssl/lib/libcrypto.so.0.9.8
    (gdb) s
    Single stepping until exit from function _x86_AES_decrypt,
    which has no line number information.
    0xb7e586d0 in AES_cbc_encrypt () from /usr/local/ssl/lib/libcrypto.so.0.9.8
    (gdb) s
    Single stepping until exit from function AES_cbc_encrypt,
    which has no line number information.

    Breakpoint 1, 0xb7e57590 in _x86_AES_decrypt ()
       from /usr/local/ssl/lib/libcrypto.so.0.9.8
    (gdb) 
(gdb) 
Single stepping until exit from function _x86_AES_decrypt,
which has no line number information.
0xb7e586d0 in AES_cbc_encrypt () from /usr/local/ssl/lib/libcrypto.so.0.9.8
(gdb) 
Single stepping until exit from function AES_cbc_encrypt,
which has no line number information.
0xb7ea380e in aes_128_cbc_cipher () from /usr/local/ssl/lib/libcrypto.so.0.9.8
(gdb) 
Single stepping until exit from function aes_128_cbc_cipher,
which has no line number information.
0xb7ea182d in EVP_EncryptUpdate () from /usr/local/ssl/lib/libcrypto.so.0.9.8
(gdb) 
Single stepping until exit from function EVP_EncryptUpdate,
which has no line number information.
0xb7ea1a39 in EVP_DecryptUpdate () from /usr/local/ssl/lib/libcrypto.so.0.9.8
(gdb) 
Single stepping until exit from function EVP_DecryptUpdate,
which has no line number information.
__memcpy_ssse3_rep () at ../sysdeps/i386/i686/multiarch/memcpy-ssse3-rep.S:111
111 ../sysdeps/i386/i686/multiarch/memcpy-ssse3-rep.S: No such file or directory.

我有以下疑虑 -

  1. 我无法理解AES LOOKUP表操作的执行位置?如何找到它们?

  2. 为什么我会在执行解密操作时调用AES_cbc_encrypt,EVP_EncryptUpdate函数?

  3. 如何调试函数EVP_DecryptUpdate()以了解函数的执行方式?简单地将断点放在像b EVP_DecryptUpdate这样的函数上并没有给出任何见解。

  4. 这是我在放置断点时得到的内容

    (gdb) b EVP_DecryptUpdate
    Breakpoint 3 at 0xb7ea19e0
    (gdb) run
    
    Breakpoint 3, 0xb7ea19e0 in EVP_DecryptUpdate ()
       from /usr/local/ssl/lib/libcrypto.so.0.9.8
    (gdb) si
    0xb7ea19e1 in EVP_DecryptUpdate () from /usr/local/ssl/lib/libcrypto.so.0.9.8
    (gdb) si
    0xb7ea19e2 in EVP_DecryptUpdate () from /usr/local/ssl/lib/libcrypto.so.0.9.8
    (gdb) 
    0xb7ea19e3 in EVP_DecryptUpdate () from /usr/local/ssl/lib/libcrypto.so.0.9.8
    (gdb) 
    0xb7ea19e4 in EVP_DecryptUpdate () from /usr/local/ssl/lib/libcrypto.so.0.9.8
    (gdb) 
    0xb7e372c0 in __x86.get_pc_thunk.bx ()
       from /usr/local/ssl/lib/libcrypto.so.0.9.8
    (gdb) 
    0xb7e372c3 in __x86.get_pc_thunk.bx ()
       from /usr/local/ssl/lib/libcrypto.so.0.9.8
    (gdb) 
    0xb7ea19e9 in EVP_DecryptUpdate () from /usr/local/ssl/lib/libcrypto.so.0.9.8
    (gdb) 
    0xb7ea19ef in EVP_DecryptUpdate () from /usr/local/ssl/lib/libcrypto.so.0.9.8
    (gdb) 
    
    
    EVP_DecryptUpdate() function is defined inside crypto/evp/evp_enc.c
    
    int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
                 const unsigned char *in, int inl)
    {
    

    如何在使用gdb进行调试时显示相应的C指令?

    我不确定,但OpenSSL可能使用各种C程序以及汇编来解密AES加密密文。如何找到评估流程?

    我使用的是Debian linux,32bit,gdb。

    任何帮助理解上述流程或任何理解的链接都将是一个很大的帮助。提前谢谢。

0 个答案:

没有答案