【发布时间】:2018-04-23 15:59:57
【问题描述】:
我正在通过 AES 算法的汇编实现来了解 sbox 和查找表是如何实现/访问的。 理论上我知道,当密钥长度=128bits 时,AES 使用 10 轮。
有一个部分是执行一个循环的 200 行代码(表示 AES 轮次)。
_x86_64_AES_decrypt_compact:
.Ldec_loop_compact:
xorl 0(%r15),%eax
xorl 4(%r15),%ebx
xorl 8(%r15),%ecx
xorl 12(%r15),%edx
leaq 16(%r15),%r15
.
.
.
xorl %r12d,%ecx
movq 256(%r14),%r13
xorl %r8d,%ebx
xorl %r11d,%edx
jmp .Ldec_loop_compact
每次完成一轮 AES 时,我想将全局变量(即 round_var)的值增加 1。 因此,在 1 个块(16 字节)上的 AES 操作结束时,变量的值为 10 和 在 2 个块(2x16 字节)上的 AES 操作结束时,变量的值为 20。
.globl round_var
round_var:
.long 0
_x86_64_AES_decrypt_compact:
.Ldec_loop_compact:
.
.
.
;increase round_var by 1
.
.
.
jmp .Ldec_loop_compact
要将 round_var 增加 1 ,我尝试了以下方法
64bit :
movq round_var(%rip), %rax
addq $1, %rax
movq %rax, round_var(%rip)
32bit :
movl round_var(%rip), %eax
addl $1, %eax
movl %eax, round_var(%rip)
由于所有 eax、ebx、ecx、edx 都在该循环中使用,我只是在更新 %eax(或 %rax)寄存器之前添加了这些行,因此它不会影响 AES 操作。
添加这些行后,我可以成功执行以下命令来构建自定义的 openssl。这意味着在编译/汇编期间将这些行添加到正确的位置。
make
sudo make install
但是,我在尝试执行 AES 解密操作时遇到了分段错误。这表明这些行代码在运行时出现了问题。
我怀疑 movl round_var(%rip), %eax 的 %rip 导致了这个分段错误。
如果有人帮助我解决上述问题或使用汇编指令将全局变量 round_var 加 1,那就太好了?
我正在使用 Ubuntu-16.04、Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz 和 Openssl-1.0.2n
提前致谢。
【问题讨论】:
-
不要将变量放入
.text部分,因为它是只读的。另外,如果您使用的是 x86-64,为什么要将其标记为arm? -
@Jester,感谢您的及时回复。那么变量放在哪里呢?
-
@bholanath 如果已初始化则将它们放入
.data,否则放入.bss。 -
@fuz:
.bss是零初始化的,不是不确定的。您可以可靠地将它用于static int foo = 0;之类的变量,编译器当然会这样做。我不喜欢零初始化的“未初始化”一词,因为在其他上下文中(如 C 中的本地变量),同一个词用于表示不确定。例如"变量 bar 在函数 blah blah 中使用未初始化" -
@fuz,谢谢。当我试图修改在只读部分声明的变量时,出现上述错误。通过在 .bss 或 .data 部分声明变量可以解决问题。我做了如下 - .bss .global round_var round_var: .long 0 我不知道如何在 .data 部分声明全局初始化变量