2

我正在尝试使用英特尔 AES 指令集实现 AES 加密,在将 xmm 寄存器的内容移动到内存时遇到了一个奇怪的问题。我正在尝试将 %xmm1 的内容移动到 %rsi 中的堆栈地址。这是我的代码:

movdqa (%rdi), %xmm1
movdqa %xmm1, (%rsi)

(%rdi) 的内容按预期移动到 xmm1,但是当将它们移动到 (%rsi) 时,第一个 dword 被清零并且最后一个 dword 不被复制:

(lldb) mem read $rdi -c 0x10
0x7ffeefbff3a0: 30 28 00 00 00 00 00 00 42 42 42 42 41 41 41 41  0(......BBBBAAAA
(lldb) mem read $rsi -c 0x10
0x7ffeefbff2f0: 00 00 00 00 00 00 00 00 20 71 4e 00 00 00 00 00  ........ qN.....
(lldb) s
(lldb) reg read xmm1
    xmm1 = {0x30 0x28 0x00 0x00 0x00 0x00 0x00 0x00 0x42 0x42 0x42 0x42 0x41 0x41 0x41 0x41}
(lldb) s
(lldb) mem read $rsi -c 0x10
0x7ffeefbff2f0: 00 00 00 00 00 00 00 00 42 42 42 42 00 00 00 00  ........BBBB....

即使内存是 16 字节对齐的,我也尝试了 movdqu 指令并得到了相同的结果。有谁知道这种行为的原因,或者有解决方法的想法?

这是我的代码,问题出现在 copy_aes_key_schedule 的第 3 行。我正在用 Xcode 编译和调试它。

在 main.c 中:

#include <stdio.h>

extern void encrypt_function_call(uint64_t functionID, uint64_t returnAddress, uint64_t opcodes, uint8_t result[0x10]);

int main(int argc, const char * argv[]) {
    // insert code here...
    
    uint32_t encrypted[4];
    encrypt_function_call(0xd67f1567, 0x2830, 0x4141414142424242, encrypted);
    
    return 0;
}

在 es 中:

.globl _encrypt_function_call

key_expansion_128:
pshufd $0xff, %xmm2, %xmm2
vpslldq $4, %xmm1, %xmm3
pxor %xmm3, %xmm1
vpslldq $4, %xmm1, %xmm3
pxor %xmm3, %xmm1
vpslldq $4, %xmm1, %xmm3
pxor %xmm3, %xmm1
pxor %xmm2, %xmm1
movdqu %xmm1, (%rcx)
add $0x10, %rcx
ret

copy_aes_key_schedule:
push %rcx
movdqa (%rdi), %xmm1
movdqa %xmm1, (%rsi)
lea 0x10(%rsi), %rcx // Untested from here on
aeskeygenassist $1, %xmm1, %xmm2
call key_expansion_128
aeskeygenassist $2, %xmm1, %xmm2
call key_expansion_128
aeskeygenassist $4, %xmm1, %xmm2
call key_expansion_128
aeskeygenassist $8, %xmm1, %xmm2
call key_expansion_128
aeskeygenassist $0x10, %xmm1, %xmm2
call key_expansion_128
aeskeygenassist $0x20, %xmm1, %xmm2
call key_expansion_128
aeskeygenassist $0x40, %xmm1, %xmm2
call key_expansion_128
aeskeygenassist $0x80, %xmm1, %xmm2
call key_expansion_128
aeskeygenassist $0x1b, %xmm1, %xmm2
call key_expansion_128
aeskeygenassist $0x36, %xmm1, %xmm2
call key_expansion_128
pop %rcx
ret

_encrypt_function_call:
push %rbp
mov %rsp, %rbp
push %r12
push %r13
push %r14
push %r15
mov %rcx, %r15
lea -0x30(%rbp), %r10 // data
mov %rdi, (%r10)
rdrand %r12
mov %r12, 8(%r10)
rdrand %r12d
mov %r12d, 4(%r10)
lea -0x40(%rbp), %rdi // key
mov %rsi, (%rdi)
mov %rdx, 8(%rdi)
lea -0xf0(%rbp), %rsi
call copy_aes_key_schedule
call _abort // untested from here on
movdqu (%r10), %xmm15
movdqu (%rsi), %xmm0
pxor %xmm0, %xmm15
movdqu 0x10(%rsi), %xmm0
aesenc %xmm0, %xmm15
movdqu 0x20(%rsi), %xmm0
aesenc %xmm0, %xmm15
movdqu 0x30(%rsi), %xmm0
aesenc %xmm0, %xmm15
movdqu 0x40(%rsi), %xmm0
aesenc %xmm0, %xmm15
movdqu 0x50(%rsi), %xmm0
aesenc %xmm0, %xmm15
movdqu 0x60(%rsi), %xmm0
aesenc %xmm0, %xmm15
movdqu 0x70(%rsi), %xmm0
aesenc %xmm0, %xmm15
movdqu 0x80(%rsi), %xmm0
aesenc %xmm0, %xmm15
movdqu 0x90(%rsi), %xmm0
aesenc %xmm0, %xmm15
movdqu 0xa0(%rsi), %xmm0
aesenclast %xmm0, %xmm15
movdqu %xmm15, (%r15)
pop %r15
pop %r14
pop %r13
pop %r12
pop %rbp
ret
4

1 回答 1

0

经过进一步调查和更奇怪的行为,我通过将保存 AES 密钥调度结果的堆栈变量的大小增加到 0xf0 字节来解决问题,即使实际的密钥调度只有 0xb0 字节。

于 2020-12-19T14:46:07.580 回答