📄 ace_modes.asm
字号:
; ---------------------------------------------------------------------------
; Copyright (c) 2002, 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/08/2005
; This code implements the AES encryption modes defined in aes_modes.h using
; the VIA ACE, which is assumed to be both present and enabled. This code
; does not assume 16 byte buffer alignment it but DOES assume that the AES
; contexts are aligned in this way. This code uses the VC++ register saving
; conentions; if it is used with another compiler, its conventions for using
; and saving registers will need to be checked (and calling conventions). The
; NASM command line for the VC++ custom build step is:
;
; nasm -O2 -f win32 -o "$(TargetDir)\$(InputName).obj" "$(InputPath)"
; set the type of key scheduling to use
%define KEY_TYPE NEH_HYBRID
; define the number of blocks to buffer locally
%define buf_blocks 8
; The DLL interface must use the _stdcall convention in which the number
; of bytes of parameter space is added after an @ to the subroutine's name.
; We must also remove our parameters from the stack before return (see
; the do_exit macro). Define BUILD_DLL for the Dynamic Link Library version.
;%define BUILD_DLL
; Comment in/out the following lines to obtain the desired subroutines. These
; selections MUST match those in the C header file aes.h
%define AES_128 ; define if AES with 128 bit keys is needed
%define AES_192 ; define if AES with 192 bit keys is needed
%define AES_256 ; define if AES with 256 bit keys is needed
%define AES_VAR ; define if a variable key size is needed
%define ENCRYPTION ; define if encryption is needed
%define DECRYPTION ; define if decryption is needed
; End of user defines
%ifdef AES_VAR
%define KS_LENGTH 60
%elifdef AES_256
%define KS_LENGTH 60
%elifdef AES_192
%define KS_LENGTH 52
%else
%define KS_LENGTH 44
%endif
%define NEH_GEN_KEY 0x00000000
%define NEH_LOAD_KEY 0x00000080
%define NEH_KEY_TYPE 0x00000000
%define NEH_ENCRYPT 0x00000000
%define NEH_DECRYPT 0x00000200
%define NEH_KEY128 0x00000000+10
%define NEH_KEY192 0x00000400+12
%define NEH_KEY256 0x00000800+14
%define NEH_GENERATE 1 ; generate keys for all key sizes
%define NEH_LOAD 2 ; load keys for all key sizes
%define NEH_HYBRID 3 ; generate 128 bit keys, load other sizes
ibuf: equ 20
obuf: equ 24
len: equ 28
ecb_ctx:equ 32
iv: equ 32
ctx: equ 36
ctr_ctr equ 32
ctr_fn equ 36
ctr_ctx equ 40
%macro neh_rekey 0
pushfd
popfd
%endmacro
%macro neh_ecb 0
db 0xf3, 0x0f, 0xa7, 0xc8
%endmacro
%macro neh_cbc 0
db 0xf3, 0x0f, 0xa7, 0xd0
%endmacro
%macro neh_cfb 0
db 0xf3, 0x0f, 0xa7, 0xe0
%endmacro
%macro neh_ofb 0
db 0xf3, 0x0f, 0xa7, 0xe8
%endmacro
%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
section .data align=16
global _enc_gen_table
global _enc_load_table
global _enc_hybrid_table
global _dec_gen_table
global _dec_load_table
global _dec_hybrid_table
_enc_gen_table:
dd (NEH_ENCRYPT | NEH_KEY128 | NEH_GEN_KEY), 0, 0, 0
dd (NEH_ENCRYPT | NEH_KEY192 | NEH_GEN_KEY), 0, 0, 0
dd (NEH_ENCRYPT | NEH_KEY256 | NEH_GEN_KEY), 0, 0, 0
_enc_load_table:
dd (NEH_ENCRYPT | NEH_KEY128 | NEH_LOAD_KEY), 0, 0, 0
dd (NEH_ENCRYPT | NEH_KEY192 | NEH_LOAD_KEY), 0, 0, 0
dd (NEH_ENCRYPT | NEH_KEY256 | NEH_LOAD_KEY), 0, 0, 0
_enc_hybrid_table:
dd (NEH_ENCRYPT | NEH_KEY128 | NEH_GEN_KEY), 0, 0, 0
dd (NEH_ENCRYPT | NEH_KEY192 | NEH_LOAD_KEY), 0, 0, 0
dd (NEH_ENCRYPT | NEH_KEY256 | NEH_LOAD_KEY), 0, 0, 0
_dec_gen_table:
dd (NEH_DECRYPT | NEH_KEY128 | NEH_GEN_KEY), 0, 0, 0
dd (NEH_DECRYPT | NEH_KEY192 | NEH_GEN_KEY), 0, 0, 0
dd (NEH_DECRYPT | NEH_KEY256 | NEH_GEN_KEY), 0, 0, 0
_dec_load_table:
dd (NEH_DECRYPT | NEH_KEY128 | NEH_LOAD_KEY), 0, 0, 0
dd (NEH_DECRYPT | NEH_KEY192 | NEH_LOAD_KEY), 0, 0, 0
dd (NEH_DECRYPT | NEH_KEY256 | NEH_LOAD_KEY), 0, 0, 0
_dec_hybrid_table:
dd (NEH_DECRYPT | NEH_KEY128 | NEH_GEN_KEY), 0, 0, 0
dd (NEH_DECRYPT | NEH_KEY192 | NEH_LOAD_KEY), 0, 0, 0
dd (NEH_DECRYPT | NEH_KEY256 | NEH_LOAD_KEY), 0, 0, 0
section .text align=16
; void aes_mode_reset(aes_encrypt_ctx cx[1]);
do_name _aes_mode_reset,4
mov eax,[esp+4]
mov byte[eax+4*KS_LENGTH+2],0
xor eax,eax
do_exit 4
; aes_rval aes_ecb_encrypt(const unsigned char *in, unsigned char *out,
; int len, const aes_encrypt_ctx cx[1]);
do_name _aes_ecb_encrypt,16
push ebp
push ebx
push esi
push edi
mov ebp,esp
; claim stack space for 'buf_blocks' 16 byte blocks and
; extra space to allow for adjusting the base address
; for a 16 byte alignment (4 byte alignment is assumed
; so a maximum of 12 bytes extra is needed). The top 4
; bytes (at [ebp-4]) are hence used to store the aligned
; buffer address
sub esp,16 * buf_blocks + 16
mov edx,esp
add edx,12 ; move up 20 bytes, align the
and edx,~0x0000000f ; resulting address and store
mov [ebp-4],edx ; the resulting value
mov eax,[ebp+len] ; get the data length
and eax,eax
je .6 ; exit if zero
shr eax,4 ; convert to blocks
neh_rekey
.1: mov [ebp+len],eax ; store remaining blocks
mov ecx,buf_blocks
cmp eax,ecx ; remaining blocks >= buffer Blocks
jae .2
mov ecx,eax ; no - process only remaining
.2: mov eax,ecx ; save block count in eax
mov esi,[ebp+ibuf] ; source data address
mov edi,[ebp-4] ; destination buffer address
.3: movups xmm0,[esi] ; unaligned move to xmm0
movaps [edi],xmm0 ; aligned move into buffer
add esi,16 ; addjust source and
add edi,16 ; destination addresses
sub ecx,1 ; reduce block count
jne short .3 ; until all blocks have been moved
mov [ebp+ibuf],esi ; update input buffer position
mov ebx,[ebp+ecb_ctx] ; get key address -> ebx
movzx ecx,byte[ebx+4*KS_LENGTH]
shr ecx,1 ; get control word address ->edx
%if (KEY_TYPE = NEH_LOAD)
lea edx,[_enc_load_table-80+ecx]
%elif (KEY_TYPE = NEH_GENERATE)
lea edx,[_enc_gen_table-80+ecx]
%else
lea edx,[_enc_hybrid_table-80+ecx]
%endif
mov esi,[ebp-4] ; source address (our local buffer)
mov edi,esi ; destination address (our buffer)
mov ecx,eax ; restore block count into ecx
neh_ecb ; execute VIA ACE operation
mov eax,[ebp+len] ; recover number of blocks remaining
mov ecx,buf_blocks ; blocks in buffer
cmp eax,ecx ; remaining blocks >= blocks in buffer
jae .4
mov ecx,eax ; no - move only remaining blocks
.4: sub eax,ecx ; compute new remaining block count
mov esi,[ebp-4] ; load local buffer address
mov edi,[ebp+obuf] ; load output address
.5: movaps xmm0,[esi] ; aligned move to xmm0
movups [edi],xmm0 ; unaligned move to output buffer
add esi,16 ; adjust source and destination
add edi,16 ; addresses
sub ecx,1 ; decrement block count
jne .5 ; and continue if some remain
mov [ebp+obuf],edi ; update output buffer position
and eax,eax ; test remaining block count
jne .1 ; and continue if some remain
.6: mov esp,ebp
pop edi
pop esi
pop ebx
pop ebp
do_exit 16
; aes_rval aes_ecb_decrypt(const unsigned char *in, unsigned char *out,
; int len, const aes_decrypt_ctx cx[1]);
do_name _aes_ecb_decrypt,16
push ebp
push ebx
push esi
push edi
mov ebp,esp
; claim stack space for 'buf_blocks' 16 byte blocks and
; extra space to allow for adjusting the base address
; for a 16 byte alignment (4 byte alignment is assumed
; so a maximum of 12 bytes extra is needed). The top 4
; bytes (at [ebp-4]) are hence used to store the aligned
; buffer address
sub esp,16 * buf_blocks + 16
mov edx,esp
add edx,12 ; move up 20 bytes, align the
and edx,~0x0000000f ; resulting address and store
mov [ebp-4],edx ; the resulting value
mov eax,[ebp+len] ; get the data length
and eax,eax
je .7 ; exit if zero
shr eax,4 ; convert to blocks
neh_rekey
.1: mov [ebp+len],eax ; store remaining blocks
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -