⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ace_modes.asm

📁 AES高级加密标准的C代码
💻 ASM
📖 第 1 页 / 共 3 页
字号:

; ---------------------------------------------------------------------------
; 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 + -