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

📄 aesctre.asm

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

; ---------------------------------------------------------------------------
; 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/08/2005
;
; I acknowledge Daniel Bernstein's contribution to ideas used in this code.
;
; An AES implementation of CTR encryption with minimum tables and 'on the fly'
; key generation.  It only opeartes with complete blocks and leaves the 
; counter updated for the next block.  The counter is incremented after each
; block using a 32-bit value with no overflow into other parts of the buffer
; It will operate with either a BIG or LITTLE endian counter as determined by
; the define below. This implementation uses the YASM (or NASM) Intel assembler 
; syntax
;
; The paramters for the C API calls are:
;
; void aes_ctr_encrypt_128(
;        const unsigned char *ibuf, unsigned char *obuf, unsigned int blocks, 
;        const unsigned char *key, unsigned char *ctr);
; void aes_ctr_encrypt_192(
;        const unsigned char *ibuf, unsigned char *obuf, unsigned int blocks, 
;        const unsigned char *key, unsigned char *ctr);
; void aes_ctr_encrypt_256(
;        const unsigned char *ibuf, unsigned char *obuf, unsigned int blocks, 
;        const unsigned char *key, unsigned char *ctr);
;
; but these can be changed by modifying the following equates that define
; the parameter offsets on the stack. The IV is updated after the operation 
; to allow incremental use using multiple calls.

%define BIG_ENDIAN_CTR

in_blk  equ     4   ; input byte array address parameter
out_blk equ     8   ; output byte array address parameter
n_block equ    12   ; the number of blocks to encrypt
key     equ    16   ; the 128 bit key
ctr     equ    20   ; the 128 bit key
parms   equ    20   ; the space to pop of the stack in the DLL version

; Use the following define for the Dynamic Link Library version.
;
; %define BUILD_DLL

; define the key lengths needed
;
%define AES_128
%define AES_192
%define AES_256

; 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. In this case we have to take our parameters 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 1
    mov		esi,[esp+exp_key+24+16*%1]
    mov		edi,[esp+exp_key+28+16*%1]
    rnd_fun	nr_xor, nr_mov
    mov		eax,ebp
    xor		eax,[esp+exp_key+16+16*%1]
    xor		ebx,[esp+exp_key+20+16*%1]
    mov		ecx,esi
    mov		edx,edi	
%endmacro

%macro  last_round 1
    mov		esi,[esp+exp_key+24+16*%1]
    mov		edi,[esp+exp_key+28+16*%1]
    rnd_fun	lr_xor, lr_mov
    mov		eax,ebp
    xor		eax,[esp+exp_key+16+16*%1]
    xor		ebx,[esp+exp_key+20+16*%1]
    mov		ecx,esi
    mov		edx,edi	
%endmacro

; On entry to key_step the registers contain:
;
;  eax : last key from previous round
;  ecx : key_0
;  edx : key_1
;  esi : key_2
;  edi : key_3
;  ebx, ebp are free for scratch use

%macro step_key 2
                                        ; apply S-box to bytes in 32-bit word
    l3s_col	ecx,a,ebp					; and rotate right one byte position
    xor		ecx,rc_val					; add in the round constant

    mov		[esp+exp_key+%1*%2],ecx
    xor		edx,ecx
    mov		[esp+exp_key+%1*%2+4],edx
    xor		esi,edx
    mov		[esp+exp_key+%1*%2+8],esi
    xor		edi,esi
    mov		[esp+exp_key+%1*%2+12],edi
    mov		eax,edi
%if %2 == 24
%if %1 < 8
    xor		eax,[esp+exp_key+%1*%2-8]
    mov		[esp+exp_key+%1*%2+16],eax
    xor		eax,[esp+exp_key+%1*%2-4]
    mov		[esp+exp_key+%1*%2+20],eax
%endif
%elif %2 == 32
%if %1 < 7
    rol		eax,8
    xor		ebx,ebx
    l3s_col	ebx,a,ebp
    mov		eax,ebx
    xor		eax,[esp+exp_key+%1*%2-16]
    mov		[esp+exp_key+%1*%2+16],eax
    xor		eax,[esp+exp_key+%1*%2-12]
    mov		[esp+exp_key+%1*%2+20],eax
    xor		eax,[esp+exp_key+%1*%2-8]
    mov		[esp+exp_key+%1*%2+24],eax
    xor		eax,[esp+exp_key+%1*%2-4]
    mov		[esp+exp_key+%1*%2+28],eax
%endif
%endif

%assign rc_val f2(rc_val)               ; move to next round constant

%endmacro

    section .text align=32

; AES Encryption Subroutine (128 bit key)

%ifdef AES_128

%assign rc_val                  1   ; start value for the round constant
%assign exp_key                 0   ; stack offset to expanded key
%assign ks_len            11 * 16   ; length of expanded key
%assign ebx_save           ks_len
%assign edi_save     ebx_save + 4
%assign esi_save     edi_save + 4
%assign ebp_save     esi_save + 4
%assign stk_offset   ebp_save + 4   ; stack offset used to avoid cache conflicts
%assign stx_spc       ks_len + 32   ; stack space needed for locals

    do_name _aes_ctr_encrypt_128

    mov      eax,esp				; use Daniel Bernstein's technique for
    sub      eax,_aes_etab			; positioning stack based variables
    and      eax,4095
    add      eax,stx_spc
    sub      esp,eax

    mov		[esp+stk_offset],eax	; save stack offset
    mov     [esp+ebp_save],ebp
    mov     [esp+ebx_save],ebx
    mov     [esp+esi_save],esi
    mov     [esp+edi_save],edi

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -