📄 aeskn.asm
字号:
; ---------------------------------------------------------------------------
; Copyright (c) 2005, Dr Brian Gladman, Worcester, UK. All rights reserved.
;
; LICENSE TERMS
;
; The free distribution and use of this software in both source and binary
; form is allowed (with or without changes) provided that:
;
; 1. distributions of this source code include the above copyright
; notice, this list of conditions and the following disclaimer;
;
; 2. distributions in binary form include the above copyright
; notice, this list of conditions and the following disclaimer
; in the documentation and/or other associated materials;
;
; 3. the copyright holder's name is not used to endorse products
; built using this software without specific written permission.
;
; ALTERNATIVELY, provided that this notice is retained in full, this product
; may be distributed under the terms of the GNU General Public License (GPL),
; in which case the provisions of the GPL apply INSTEAD OF those given above.
;
; DISCLAIMER
;
; This software is provided 'as is' with no explicit or implied warranties
; in respect of its properties, including, but not limited to, correctness
; and/or fitness for purpose.
; ---------------------------------------------------------------------------
; Issue 01/05/2005
; An x86 assembler implementation of AES with minimum tables, a 128 bit key
; and 'on the fly' key generation. This implementation uses the YASM or NASM
; assemblers and Intel syntax. I acknowledge Daniel Bernstein's contribution
; to ideas used in this code.
;
; The current API is as follows:
;
; void aes_kn(
; unsigned char out_blk[16],
; const unsigned char key[16],
; const unsigned char in_blk[16]);
;
; but parameter order in the API can be changed using the following defines:
%define out_blk 4 ; output byte array address parameter
%define key 8 ; key array (128-bit only)
%define in_blk 12 ; input byte array address parameter
%define parms 12 ; the space to pop of the stack in the DLL version
; The DLL interface must use the _stdcall convention in which the number
; of bytes of parameter space is added to the subroutine's name after an @
; character. Use the following define for the Dynamic Link Library version.
;%define BUILD_DLL
; the DLL has to implement the _stdcall calling interface on return
; In this case we have to take our parameters (3 4-byte pointers)
; off the stack
%macro do_name 1-2 parms
%ifndef BUILD_DLL
align 32
global %1
%1:
%else
align 32
global %1@%2
export %1@%2
%1@%2:
%endif
%endmacro
%macro do_call 1-2 parms
%ifndef BUILD_DLL
call %1
add esp,%2
%else
call %1@%2
%endif
%endmacro
%macro do_exit 0-1 parms
%ifdef BUILD_DLL
ret %1
%else
ret
%endif
%endmacro
extern _aes_etab
; finite field multiplies by {02}, {04} and {08}
%define f2(x) ((x<<1)^(((x>>7)&1)*0x11b))
%define f4(x) ((x<<2)^(((x>>6)&1)*0x11b)^(((x>>6)&2)*0x11b))
%define f8(x) ((x<<3)^(((x>>5)&1)*0x11b)^(((x>>5)&2)*0x11b)^(((x>>5)&4)*0x11b))
%define etab_0(x) [_aes_etab+4+8*x]
%define etab_1(x) [_aes_etab+3+8*x]
%define etab_2(x) [_aes_etab+2+8*x]
%define etab_3(x) [_aes_etab+1+8*x]
%define etab_b(x) byte [_aes_etab+1+8*x] ; used with movzx for 0x000000xx
%define etab_w(x) word [_aes_etab+8*x] ; used with movzx for 0x0000xx00
%define btab_0(x) [_aes_etab+6+8*x]
%define btab_1(x) [_aes_etab+5+8*x]
%define btab_2(x) [_aes_etab+4+8*x]
%define btab_3(x) [_aes_etab+3+8*x]
; ROUND FUNCTION. Build column[2] on ESI and column[3] on EDI that have the
; round keys pre-loaded. Build column[0] in EBP and column[1] in EBX.
;
; Input:
;
; EAX column[0]
; EBX column[1]
; ECX column[2]
; EDX column[3]
; ESI column key[round][2]
; EDI column key[round][3]
; EBP scratch
;
; Output:
;
; EBP column[0] unkeyed
; EBX column[1] unkeyed
; ESI column[2] keyed
; EDI column[3] keyed
; EAX scratch
; ECX scratch
; EDX scratch
%macro rnd_fun 2
rol ebx,16
%1 esi, cl, 0, ebp
%1 esi, dh, 1, ebp
%1 esi, bh, 3, ebp
%1 edi, dl, 0, ebp
%1 edi, ah, 1, ebp
%1 edi, bl, 2, ebp
%2 ebp, al, 0, ebp
shr ebx,16
and eax,0xffff0000
or eax,ebx
shr edx,16
%1 ebp, ah, 1, ebx
%1 ebp, dh, 3, ebx
%2 ebx, dl, 2, ebx
%1 ebx, ch, 1, edx
%1 ebx, al, 0, edx
shr eax,16
shr ecx,16
%1 ebp, cl, 2, edx
%1 edi, ch, 3, edx
%1 esi, al, 2, edx
%1 ebx, ah, 3, edx
%endmacro
; Basic MOV and XOR Operations for normal rounds
%macro nr_xor 4
movzx %4,%2
xor %1,etab_%3(%4)
%endmacro
%macro nr_mov 4
movzx %4,%2
mov %1,etab_%3(%4)
%endmacro
; Basic MOV and XOR Operations for last round
%if 1
%macro lr_xor 4
movzx %4,%2
movzx %4,etab_b(%4)
%if %3 != 0
shl %4,8*%3
%endif
xor %1,%4
%endmacro
%macro lr_mov 4
movzx %4,%2
movzx %1,etab_b(%4)
%if %3 != 0
shl %1,8*%3
%endif
%endmacro
%else
%macro lr_xor 4
movzx %4,%2
mov %4,btab_%3(%4)
and %4,0x000000ff << 8 * %3
xor %1,%4
%endmacro
%macro lr_mov 4
movzx %4,%2
mov %1,btab_%3(%4)
and %1,0x000000ff << 8 * %3
%endmacro
%endif
; Apply S-Box to the 4 bytes in a 32-bit word and rotate left 3 byte positions
;
; %1 : output is xored into this register
; %2 : input: a => eax; b => ebx; c => ecx; d => edx
; %3 : scratch register
%macro l3s_col 3
lr_xor %1,%2h,0,%3
lr_xor %1,%2l,3,%3
shr e%2x,16
lr_xor %1,%2h,2,%3
lr_xor %1,%2l,1,%3
%endmacro
%macro round 0
rnd_fun nr_xor, nr_mov
%endmacro
%macro last_round 0
rnd_fun lr_xor, lr_mov
%endmacro
; KEY STEP Operation:
;
; Input:
;
; EBP column[0] unkeyed
; EBX column[1] unkeyed
; ESI column[2] keyed
; EDI column[3] keyed
; EAX scratch
; ECX scratch
; EDX scratch
;
; Output:
;
; 1. EAX = column[0] (EBP in) ^ key[0]
; 2. EBX = column[1] (EBX in) ^ key[1]
; 3. ECX = column[2] (ESI in)
; 4. EDX = column[3] (EDI in)
; 6. key[0] = key[0] ^ ls_box[key_3]
; 7. key[1] = key[1] ^ key[0]
; 8. key[2] = key[2] ^ key[1] => ESI
; 9. key[3] = key[3] ^ key[2] => EDI
%macro step_key 0
mov eax,[esp+key_0]
mov ecx,eax
xor eax,ebp ; do LAST round key[0] and put column[0] in EAX
mov edx,[esp+key_3]
l3s_col ecx,d,ebp
xor ecx,rc_val
mov [esp+key_0],ecx
mov edx,[esp+key_1]
xor ebx,edx ; do LAST round key[1] for column[1] in EBX
xor edx,ecx
mov [esp+key_1],edx
mov ecx,esi ; put column[2] in ECX
mov esi,[esp+key_2]
xor esi,edx
mov [esp+key_2],esi
mov edx,edi ; put column[3] in EDX
mov edi,[esp+key_3]
xor edi,esi ; leave NEXT round key[2] in ESI
mov [esp+key_3],edi ; and NEXT round key[3] in EDI
%assign rc_val f2(rc_val)
%endmacro
%define key_0 0 ; on the fly round key in 4 32-bit words
%define key_1 4
%define key_2 8
%define key_3 12
%define ebx_save 16 ; register save area
%define edi_save 20
%define esi_save 24
%define ebp_save 28
%define stk_offset 32 ; the stack offset used to avoid cache conflicts
%define stk_spc 40 ; total stack space claimed for locals
; AES Encryption Subroutine
%assign rc_val 1
section .text align=32
align 32
do_name _aes_kn
mov eax,esp
sub eax,_aes_etab
and eax,4095
add eax,stk_spc
sub esp,eax
mov [esp+stk_offset],eax
mov [esp+ebp_save],ebp
mov [esp+ebx_save],ebx
mov [esp+esi_save],esi
mov [esp+edi_save],edi
mov ecx,[esp+eax+in_blk]
mov edx,[esp+eax+key]
mov ebp,[ecx]
mov ebx,[ecx+4]
mov esi,[ecx+8]
mov edi,[ecx+12]
mov eax,[edx]
mov ecx,[edx+4]
mov [esp+key_0],eax
mov [esp+key_1],ecx
mov eax,[edx+8]
mov ecx,[edx+12]
mov [esp+key_2],eax
mov [esp+key_3],ecx
xor esi,eax
xor edi,ecx
step_key
round
step_key
round
step_key
round
step_key
round
step_key
round
step_key
round
step_key
round
step_key
round
step_key
round
step_key
last_round
xor ebp,[esp+key_0]
xor ebx,[esp+key_1]
mov eax,[esp+stk_offset]
mov edx,[esp+eax+out_blk]
mov [edx],ebp
mov [edx+4],ebx
mov [edx+8],esi
mov [edx+12],edi
mov edi,[esp+edi_save]
mov esi,[esp+esi_save]
mov ebx,[esp+ebx_save]
mov ebp,[esp+ebp_save]
add esp,eax
do_exit
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -