Annotation of truecrypt/crypto/aessmall_x86.asm, revision 1.1

1.1     ! root        1: 
        !             2: ; ---------------------------------------------------------------------------
        !             3: ; Copyright (c) 1998-2007, Brian Gladman, Worcester, UK. All rights reserved.
        !             4: ; 
        !             5: ; LICENSE TERMS
        !             6: ; 
        !             7: ; The free distribution and use of this software is allowed (with or without
        !             8: ; changes) provided that:
        !             9: ; 
        !            10: ;  1. source code distributions include the above copyright notice, this
        !            11: ;     list of conditions and the following disclaimer;
        !            12: ; 
        !            13: ;  2. binary distributions include the above copyright notice, this list
        !            14: ;     of conditions and the following disclaimer in their documentation;
        !            15: ; 
        !            16: ;  3. the name of the copyright holder is not used to endorse products
        !            17: ;     built using this software without specific written permission.
        !            18: ; 
        !            19: ; DISCLAIMER
        !            20: ; 
        !            21: ; This software is provided 'as is' with no explicit or implied warranties
        !            22: ; in respect of its properties, including, but not limited to, correctness
        !            23: ; and/or fitness for purpose.
        !            24: ; ---------------------------------------------------------------------------
        !            25: ; Issue 20/12/2007
        !            26: ;
        !            27: ; This code requires either ASM_X86_V2 or ASM_X86_V2C to be set in aesopt.h
        !            28: ; and the same define to be set here as well. If AES_V2C is set this file
        !            29: ; requires the C files aeskey.c and aestab.c for support.
        !            30: 
        !            31: ; An AES implementation for x86 processors using the YASM (or NASM) assembler.
        !            32: ; This is a full assembler implementation covering encryption, decryption and
        !            33: ; key scheduling. It uses 2k bytes of tables but its encryption and decryption
        !            34: ; performance is very close to that obtained using large tables.  Key schedule
        !            35: ; expansion is slower for both encryption and decryption but this is likely to
        !            36: ; be offset by the much smaller load that this version places on the processor
        !            37: ; cache. I acknowledge the contribution made by Daniel Bernstein to aspects of
        !            38: ; the design of the AES round function used here.
        !            39: ;
        !            40: ; This code provides the standard AES block size (128 bits, 16 bytes) and the
        !            41: ; three standard AES key sizes (128, 192 and 256 bits). It has the same call
        !            42: ; interface as my C implementation. The ebx, esi, edi and ebp registers are
        !            43: ; preserved across calls but eax, ecx and edx and the artihmetic status flags
        !            44: ; are not.  Although this is a full assembler implementation, it can be used
        !            45: ; in conjunction with my C code which provides faster key scheduling using
        !            46: ; large tables. In this case aeskey.c should be compiled with ASM_X86_V2C
        !            47: ; defined.  It is also important that the defines below match those used in the
        !            48: ; C code.  This code uses the VC++ register saving conentions; if it is used
        !            49: ; with another compiler, conventions for using and saving registers may need
        !            50: ; to be checked (and calling conventions).  The YASM command line for the VC++
        !            51: ; custom build step is:
        !            52: ;
        !            53: ;    yasm -Xvc -f win32 -D <Z> -o "$(TargetDir)\$(InputName).obj" "$(InputPath)"
        !            54: ;
        !            55: ; For the cryptlib build this is (pcg):
        !            56: ;
        !            57: ;      yasm -Xvc -f win32 -D ASM_X86_V2C -o aescrypt2.obj aes_x86_v2.asm
        !            58: ;
        !            59: ; where <Z> is ASM_X86_V2 or ASM_X86_V2C.  The calling intefaces are:
        !            60: ;
        !            61: ;     AES_RETURN aes_encrypt(const unsigned char in_blk[],
        !            62: ;                   unsigned char out_blk[], const aes_encrypt_ctx cx[1]);
        !            63: ;
        !            64: ;     AES_RETURN aes_decrypt(const unsigned char in_blk[],
        !            65: ;                   unsigned char out_blk[], const aes_decrypt_ctx cx[1]);
        !            66: ;
        !            67: ;     AES_RETURN aes_encrypt_key<NNN>(const unsigned char key[],
        !            68: ;                                            const aes_encrypt_ctx cx[1]);
        !            69: ;
        !            70: ;     AES_RETURN aes_decrypt_key<NNN>(const unsigned char key[],
        !            71: ;                                            const aes_decrypt_ctx cx[1]);
        !            72: ;
        !            73: ;     AES_RETURN aes_encrypt_key(const unsigned char key[],
        !            74: ;                           unsigned int len, const aes_decrypt_ctx cx[1]);
        !            75: ;
        !            76: ;     AES_RETURN aes_decrypt_key(const unsigned char key[],
        !            77: ;                           unsigned int len, const aes_decrypt_ctx cx[1]);
        !            78: ;
        !            79: ; where <NNN> is 128, 102 or 256.  In the last two calls the length can be in
        !            80: ; either bits or bytes.
        !            81: 
        !            82: ; The DLL interface must use the _stdcall convention in which the number
        !            83: ; of bytes of parameter space is added after an @ to the sutine's name.
        !            84: ; We must also remove our parameters from the stack before return (see
        !            85: ; the do_exit macro). Define DLL_EXPORT for the Dynamic Link Library version.
        !            86: 
        !            87: ;
        !            88: ; Adapted for TrueCrypt by the TrueCrypt Foundation:
        !            89: ; - All tables generated at run-time
        !            90: ; - Adapted for 16-bit environment
        !            91: ;
        !            92: 
        !            93: CPU 386
        !            94: USE16
        !            95: SEGMENT _TEXT PUBLIC CLASS=CODE USE16
        !            96: SEGMENT _DATA PUBLIC CLASS=DATA USE16
        !            97: 
        !            98: GROUP DGROUP _TEXT _DATA
        !            99: 
        !           100: extern _aes_dec_tab            ; Aestab.c
        !           101: extern _aes_enc_tab
        !           102: 
        !           103: ; %define DLL_EXPORT
        !           104: 
        !           105: ; The size of the code can be reduced by using functions for the encryption
        !           106: ; and decryption rounds in place of macro expansion
        !           107: 
        !           108: %define REDUCE_CODE_SIZE
        !           109: 
        !           110: ; Comment in/out the following lines to obtain the desired subroutines. These
        !           111: ; selections MUST match those in the C header file aes.h
        !           112: 
        !           113: ; %define AES_128                 ; define if AES with 128 bit keys is needed
        !           114: ; %define AES_192                 ; define if AES with 192 bit keys is needed
        !           115: %define AES_256                 ; define if AES with 256 bit keys is needed
        !           116: ; %define AES_VAR                 ; define if a variable key size is needed
        !           117: %define ENCRYPTION              ; define if encryption is needed
        !           118: %define DECRYPTION              ; define if decryption is needed
        !           119: ; %define AES_REV_DKS             ; define if key decryption schedule is reversed
        !           120: 
        !           121: %ifndef ASM_X86_V2C
        !           122: %define ENCRYPTION_KEY_SCHEDULE ; define if encryption key expansion is needed
        !           123: %define DECRYPTION_KEY_SCHEDULE ; define if decryption key expansion is needed
        !           124: %endif
        !           125: 
        !           126: ; The encryption key schedule has the following in memory layout where N is the
        !           127: ; number of rounds (10, 12 or 14):
        !           128: ;
        !           129: ; lo: | input key (round 0)  |  ; each round is four 32-bit words
        !           130: ;     | encryption round 1   |
        !           131: ;     | encryption round 2   |
        !           132: ;     ....
        !           133: ;     | encryption round N-1 |
        !           134: ; hi: | encryption round N   |
        !           135: ;
        !           136: ; The decryption key schedule is normally set up so that it has the same
        !           137: ; layout as above by actually reversing the order of the encryption key
        !           138: ; schedule in memory (this happens when AES_REV_DKS is set):
        !           139: ;
        !           140: ; lo: | decryption round 0   | =              | encryption round N   |
        !           141: ;     | decryption round 1   | = INV_MIX_COL[ | encryption round N-1 | ]
        !           142: ;     | decryption round 2   | = INV_MIX_COL[ | encryption round N-2 | ]
        !           143: ;     ....                       ....
        !           144: ;     | decryption round N-1 | = INV_MIX_COL[ | encryption round 1   | ]
        !           145: ; hi: | decryption round N   | =              | input key (round 0)  |
        !           146: ;
        !           147: ; with rounds except the first and last modified using inv_mix_column()
        !           148: ; But if AES_REV_DKS is NOT set the order of keys is left as it is for
        !           149: ; encryption so that it has to be accessed in reverse when used for
        !           150: ; decryption (although the inverse mix column modifications are done)
        !           151: ;
        !           152: ; lo: | decryption round 0   | =              | input key (round 0)  |
        !           153: ;     | decryption round 1   | = INV_MIX_COL[ | encryption round 1   | ]
        !           154: ;     | decryption round 2   | = INV_MIX_COL[ | encryption round 2   | ]
        !           155: ;     ....                       ....
        !           156: ;     | decryption round N-1 | = INV_MIX_COL[ | encryption round N-1 | ]
        !           157: ; hi: | decryption round N   | =              | encryption round N   |
        !           158: ;
        !           159: ; This layout is faster when the assembler key scheduling provided here
        !           160: ; is used.
        !           161: ;
        !           162: ; End of user defines
        !           163: 
        !           164: %ifdef AES_VAR
        !           165: %ifndef AES_128
        !           166: %define AES_128
        !           167: %endif
        !           168: %ifndef AES_192
        !           169: %define AES_192
        !           170: %endif
        !           171: %ifndef AES_256
        !           172: %define AES_256
        !           173: %endif
        !           174: %endif
        !           175: 
        !           176: %ifdef AES_VAR
        !           177: %define KS_LENGTH       60
        !           178: %elifdef AES_256
        !           179: %define KS_LENGTH       60
        !           180: %elifdef AES_192
        !           181: %define KS_LENGTH       52
        !           182: %else
        !           183: %define KS_LENGTH       44
        !           184: %endif
        !           185: 
        !           186: ; These macros implement stack based local variables
        !           187: 
        !           188: %macro  save 2
        !           189:     mov     [esp+4*%1],%2
        !           190: %endmacro
        !           191: 
        !           192: %macro  restore 2
        !           193:     mov     %1,[esp+4*%2]
        !           194: %endmacro
        !           195: 
        !           196: %ifdef  REDUCE_CODE_SIZE
        !           197:     %macro mf_call 1
        !           198:         call %1
        !           199:     %endmacro
        !           200: %else
        !           201:     %macro mf_call 1
        !           202:         %1
        !           203:     %endmacro
        !           204: %endif
        !           205: 
        !           206: ; the DLL has to implement the _stdcall calling interface on return
        !           207: ; In this case we have to take our parameters (3 4-byte pointers)
        !           208: ; off the stack
        !           209: 
        !           210: %define parms 12
        !           211: 
        !           212: %macro  do_name 1-2 parms
        !           213: %ifndef DLL_EXPORT
        !           214:     global  %1
        !           215: %1:
        !           216: %else
        !           217:     global  %1@%2
        !           218:     export  %1@%2
        !           219: %1@%2:
        !           220: %endif
        !           221: %endmacro
        !           222: 
        !           223: %macro  do_call 1-2 parms
        !           224: %ifndef DLL_EXPORT
        !           225:     call    %1
        !           226:     add     esp,%2
        !           227: %else
        !           228:     call    %1@%2
        !           229: %endif
        !           230: %endmacro
        !           231: 
        !           232: %macro  do_exit  0-1 parms
        !           233: %ifdef DLL_EXPORT
        !           234:     ret %1
        !           235: %else
        !           236:     ret
        !           237: %endif
        !           238: %endmacro
        !           239: 
        !           240: ; finite field multiplies by {02}, {04} and {08}
        !           241: 
        !           242: %define f2(x)   ((x<<1)^(((x>>7)&1)*0x11b))
        !           243: %define f4(x)   ((x<<2)^(((x>>6)&1)*0x11b)^(((x>>6)&2)*0x11b))
        !           244: %define f8(x)   ((x<<3)^(((x>>5)&1)*0x11b)^(((x>>5)&2)*0x11b)^(((x>>5)&4)*0x11b))
        !           245: 
        !           246: ; finite field multiplies required in table generation
        !           247: 
        !           248: %define f3(x)   (f2(x) ^ x)
        !           249: %define f9(x)   (f8(x) ^ x)
        !           250: %define fb(x)   (f8(x) ^ f2(x) ^ x)
        !           251: %define fd(x)   (f8(x) ^ f4(x) ^ x)
        !           252: %define fe(x)   (f8(x) ^ f4(x) ^ f2(x))
        !           253: 
        !           254: %define etab_0(x)   [_aes_enc_tab+4+8*x]
        !           255: %define etab_1(x)   [_aes_enc_tab+3+8*x]
        !           256: %define etab_2(x)   [_aes_enc_tab+2+8*x]
        !           257: %define etab_3(x)   [_aes_enc_tab+1+8*x]
        !           258: %define etab_b(x)   byte [_aes_enc_tab+1+8*x] ; used with movzx for 0x000000xx
        !           259: %define etab_w(x)   word [_aes_enc_tab+8*x]   ; used with movzx for 0x0000xx00
        !           260: 
        !           261: %define btab_0(x)   [_aes_enc_tab+6+8*x]
        !           262: %define btab_1(x)   [_aes_enc_tab+5+8*x]
        !           263: %define btab_2(x)   [_aes_enc_tab+4+8*x]
        !           264: %define btab_3(x)   [_aes_enc_tab+3+8*x]
        !           265: 
        !           266: ; ROUND FUNCTION.  Build column[2] on ESI and column[3] on EDI that have the
        !           267: ; round keys pre-loaded. Build column[0] in EBP and column[1] in EBX.
        !           268: ;
        !           269: ; Input:
        !           270: ;
        !           271: ;   EAX     column[0]
        !           272: ;   EBX     column[1]
        !           273: ;   ECX     column[2]
        !           274: ;   EDX     column[3]
        !           275: ;   ESI     column key[round][2]
        !           276: ;   EDI     column key[round][3]
        !           277: ;   EBP     scratch
        !           278: ;
        !           279: ; Output:
        !           280: ;
        !           281: ;   EBP     column[0]   unkeyed
        !           282: ;   EBX     column[1]   unkeyed
        !           283: ;   ESI     column[2]   keyed
        !           284: ;   EDI     column[3]   keyed
        !           285: ;   EAX     scratch
        !           286: ;   ECX     scratch
        !           287: ;   EDX     scratch
        !           288: 
        !           289: %macro rnd_fun 2
        !           290: 
        !           291:     rol     ebx,16
        !           292:     %1      esi, cl, 0, ebp
        !           293:     %1      esi, dh, 1, ebp
        !           294:     %1      esi, bh, 3, ebp
        !           295:     %1      edi, dl, 0, ebp
        !           296:     %1      edi, ah, 1, ebp
        !           297:     %1      edi, bl, 2, ebp
        !           298:     %2      ebp, al, 0, ebp
        !           299:     shr     ebx,16
        !           300:     and     eax,0xffff0000
        !           301:     or      eax,ebx
        !           302:     shr     edx,16
        !           303:     %1      ebp, ah, 1, ebx
        !           304:     %1      ebp, dh, 3, ebx
        !           305:     %2      ebx, dl, 2, ebx
        !           306:     %1      ebx, ch, 1, edx
        !           307:     %1      ebx, al, 0, edx
        !           308:     shr     eax,16
        !           309:     shr     ecx,16
        !           310:     %1      ebp, cl, 2, edx
        !           311:     %1      edi, ch, 3, edx
        !           312:     %1      esi, al, 2, edx
        !           313:     %1      ebx, ah, 3, edx
        !           314: 
        !           315: %endmacro
        !           316: 
        !           317: ; Basic MOV and XOR Operations for normal rounds
        !           318: 
        !           319: %macro  nr_xor  4
        !           320:     movzx   %4,%2
        !           321:     xor     %1,etab_%3(%4)
        !           322: %endmacro
        !           323: 
        !           324: %macro  nr_mov  4
        !           325:     movzx   %4,%2
        !           326:     mov     %1,etab_%3(%4)
        !           327: %endmacro
        !           328: 
        !           329: ; Basic MOV and XOR Operations for last round
        !           330: 
        !           331: %if 1
        !           332: 
        !           333:     %macro  lr_xor  4
        !           334:         movzx   %4,%2
        !           335:         movzx   %4,etab_b(%4)
        !           336:     %if %3 != 0
        !           337:         shl     %4,8*%3
        !           338:     %endif
        !           339:         xor     %1,%4
        !           340:     %endmacro
        !           341: 
        !           342:     %macro  lr_mov  4
        !           343:         movzx   %4,%2
        !           344:         movzx   %1,etab_b(%4)
        !           345:     %if %3 != 0
        !           346:         shl     %1,8*%3
        !           347:     %endif
        !           348:     %endmacro
        !           349: 
        !           350: %else       ; less effective but worth leaving as an option
        !           351: 
        !           352:     %macro  lr_xor  4
        !           353:         movzx   %4,%2
        !           354:         mov     %4,btab_%3(%4)
        !           355:         and     %4,0x000000ff << 8 * %3
        !           356:         xor     %1,%4
        !           357:     %endmacro
        !           358: 
        !           359:     %macro  lr_mov  4
        !           360:         movzx   %4,%2
        !           361:         mov     %1,btab_%3(%4)
        !           362:         and     %1,0x000000ff << 8 * %3
        !           363:     %endmacro
        !           364: 
        !           365: %endif
        !           366: 
        !           367: ; Apply S-Box to the 4 bytes in a 32-bit word and rotate byte positions
        !           368: 
        !           369: %ifdef REDUCE_CODE_SIZE
        !           370:     
        !           371: l3s_col:
        !           372:     movzx   ecx,al              ; in      eax
        !           373:     movzx   ecx, etab_b(ecx)    ; out     eax
        !           374:     xor     edx,ecx             ; scratch ecx,edx
        !           375:     movzx   ecx,ah
        !           376:     movzx   ecx, etab_b(ecx)
        !           377:     shl     ecx,8
        !           378:     xor     edx,ecx
        !           379:     shr     eax,16
        !           380:     movzx   ecx,al
        !           381:     movzx   ecx, etab_b(ecx)
        !           382:     shl     ecx,16
        !           383:     xor     edx,ecx
        !           384:     movzx   ecx,ah
        !           385:     movzx   ecx, etab_b(ecx)
        !           386:     shl     ecx,24
        !           387:     xor     edx,ecx
        !           388:     mov     eax,edx
        !           389:     ret
        !           390: 
        !           391: %else
        !           392: 
        !           393: %macro l3s_col 0
        !           394: 
        !           395:     movzx   ecx,al              ; in      eax
        !           396:     movzx   ecx, etab_b(ecx)    ; out     eax
        !           397:     xor     edx,ecx             ; scratch ecx,edx
        !           398:     movzx   ecx,ah
        !           399:     movzx   ecx, etab_b(ecx)
        !           400:     shl     ecx,8
        !           401:     xor     edx,ecx
        !           402:     shr     eax,16
        !           403:     movzx   ecx,al
        !           404:     movzx   ecx, etab_b(ecx)
        !           405:     shl     ecx,16
        !           406:     xor     edx,ecx
        !           407:     movzx   ecx,ah
        !           408:     movzx   ecx, etab_b(ecx)
        !           409:     shl     ecx,24
        !           410:     xor     edx,ecx
        !           411:     mov     eax,edx
        !           412: 
        !           413: %endmacro
        !           414: 
        !           415: %endif
        !           416:     
        !           417: ; offsets to parameters
        !           418: 
        !           419: in_blk  equ     2   ; input byte array address parameter
        !           420: out_blk equ     4   ; output byte array address parameter
        !           421: ctx     equ     6   ; AES context structure
        !           422: stk_spc equ    20   ; stack space
        !           423: 
        !           424: %ifdef  ENCRYPTION
        !           425: 
        !           426: ; %define ENCRYPTION_TABLE
        !           427: 
        !           428: %ifdef REDUCE_CODE_SIZE
        !           429: 
        !           430: enc_round:
        !           431:        sub             sp, 2
        !           432:     add     ebp,16
        !           433:     save    1,ebp
        !           434:     mov     esi,[ebp+8]
        !           435:     mov     edi,[ebp+12]
        !           436: 
        !           437:     rnd_fun nr_xor, nr_mov
        !           438: 
        !           439:     mov     eax,ebp
        !           440:     mov     ecx,esi
        !           441:     mov     edx,edi
        !           442:     restore ebp,1
        !           443:     xor     eax,[ebp]
        !           444:     xor     ebx,[ebp+4]
        !           445:        add             sp, 2
        !           446:     ret
        !           447:     
        !           448: %else
        !           449: 
        !           450: %macro enc_round 0
        !           451: 
        !           452:     add     ebp,16
        !           453:     save    0,ebp
        !           454:     mov     esi,[ebp+8]
        !           455:     mov     edi,[ebp+12]
        !           456: 
        !           457:     rnd_fun nr_xor, nr_mov
        !           458: 
        !           459:     mov     eax,ebp
        !           460:     mov     ecx,esi
        !           461:     mov     edx,edi
        !           462:     restore ebp,0
        !           463:     xor     eax,[ebp]
        !           464:     xor     ebx,[ebp+4]
        !           465: 
        !           466: %endmacro
        !           467: 
        !           468: %endif
        !           469: 
        !           470: %macro enc_last_round 0
        !           471: 
        !           472:     add     ebp,16
        !           473:     save    0,ebp
        !           474:     mov     esi,[ebp+8]
        !           475:     mov     edi,[ebp+12]
        !           476: 
        !           477:     rnd_fun lr_xor, lr_mov
        !           478: 
        !           479:     mov     eax,ebp
        !           480:     restore ebp,0
        !           481:     xor     eax,[ebp]
        !           482:     xor     ebx,[ebp+4]
        !           483: 
        !           484: %endmacro
        !           485: 
        !           486:     section _TEXT
        !           487: 
        !           488: ; AES Encryption Subroutine
        !           489: 
        !           490:     do_name _aes_encrypt,12
        !           491: 
        !           492:        mov             ax, sp
        !           493:        movzx   esp, ax
        !           494: 
        !           495:     sub     esp,stk_spc
        !           496:     mov     [esp+16],ebp
        !           497:     mov     [esp+12],ebx
        !           498:     mov     [esp+ 8],esi
        !           499:     mov     [esp+ 4],edi
        !           500: 
        !           501:     movzx   esi,word [esp+in_blk+stk_spc] ; input pointer
        !           502:     mov     eax,[esi   ]
        !           503:     mov     ebx,[esi+ 4]
        !           504:     mov     ecx,[esi+ 8]
        !           505:     mov     edx,[esi+12]
        !           506: 
        !           507:     movzx   ebp,word [esp+ctx+stk_spc]    ; key pointer
        !           508:     movzx   edi,byte [ebp+4*KS_LENGTH]
        !           509:     xor     eax,[ebp   ]
        !           510:     xor     ebx,[ebp+ 4]
        !           511:     xor     ecx,[ebp+ 8]
        !           512:     xor     edx,[ebp+12]
        !           513: 
        !           514: ; determine the number of rounds
        !           515: 
        !           516: %ifndef AES_256
        !           517:     cmp     edi,10*16
        !           518:     je      .3
        !           519:     cmp     edi,12*16
        !           520:     je      .2
        !           521:     cmp     edi,14*16
        !           522:     je      .1
        !           523:     mov     eax,-1
        !           524:     jmp     .5
        !           525: %endif
        !           526: 
        !           527: .1: mf_call enc_round
        !           528:     mf_call enc_round
        !           529: .2: mf_call enc_round
        !           530:     mf_call enc_round
        !           531: .3: mf_call enc_round
        !           532:     mf_call enc_round
        !           533:     mf_call enc_round
        !           534:     mf_call enc_round
        !           535:     mf_call enc_round
        !           536:     mf_call enc_round
        !           537:     mf_call enc_round
        !           538:     mf_call enc_round
        !           539:     mf_call enc_round
        !           540:     enc_last_round
        !           541: 
        !           542:     movzx   edx,word [esp+out_blk+stk_spc]
        !           543:     mov     [edx],eax
        !           544:     mov     [edx+4],ebx
        !           545:     mov     [edx+8],esi
        !           546:     mov     [edx+12],edi
        !           547:     xor     eax,eax
        !           548: 
        !           549: .5: mov     ebp,[esp+16]
        !           550:     mov     ebx,[esp+12]
        !           551:     mov     esi,[esp+ 8]
        !           552:     mov     edi,[esp+ 4]
        !           553:     add     esp,stk_spc
        !           554:     do_exit 12
        !           555: 
        !           556: %endif
        !           557: 
        !           558: %macro f_key 2
        !           559: 
        !           560:     push    ecx
        !           561:     push    edx
        !           562:     mov     edx,esi
        !           563:     ror     eax,8
        !           564:     mf_call l3s_col
        !           565:     mov     esi,eax
        !           566:     pop     edx
        !           567:     pop     ecx
        !           568:     xor     esi,rc_val
        !           569: 
        !           570:     mov     [ebp+%1*%2],esi
        !           571:     xor     edi,esi
        !           572:     mov     [ebp+%1*%2+4],edi
        !           573:     xor     ecx,edi
        !           574:     mov     [ebp+%1*%2+8],ecx
        !           575:     xor     edx,ecx
        !           576:     mov     [ebp+%1*%2+12],edx
        !           577:     mov     eax,edx
        !           578: 
        !           579: %if %2 == 24
        !           580: 
        !           581: %if %1 < 7
        !           582:     xor     eax,[ebp+%1*%2+16-%2]
        !           583:     mov     [ebp+%1*%2+16],eax
        !           584:     xor     eax,[ebp+%1*%2+20-%2]
        !           585:     mov     [ebp+%1*%2+20],eax
        !           586: %endif
        !           587: 
        !           588: %elif %2 == 32
        !           589: 
        !           590: %if %1 < 6
        !           591:     push    ecx
        !           592:     push    edx
        !           593:     mov     edx,[ebp+%1*%2+16-%2]
        !           594:     mf_call l3s_col
        !           595:     pop     edx
        !           596:     pop     ecx
        !           597:     mov     [ebp+%1*%2+16],eax
        !           598:     xor     eax,[ebp+%1*%2+20-%2]
        !           599:     mov     [ebp+%1*%2+20],eax
        !           600:     xor     eax,[ebp+%1*%2+24-%2]
        !           601:     mov     [ebp+%1*%2+24],eax
        !           602:     xor     eax,[ebp+%1*%2+28-%2]
        !           603:     mov     [ebp+%1*%2+28],eax
        !           604: %endif
        !           605: 
        !           606: %endif
        !           607: 
        !           608: %assign rc_val f2(rc_val)
        !           609: 
        !           610: %endmacro
        !           611: 
        !           612: %ifdef ENCRYPTION_KEY_SCHEDULE
        !           613: 
        !           614: %ifdef  AES_128
        !           615: 
        !           616: %ifndef ENCRYPTION_TABLE
        !           617: ; %define ENCRYPTION_TABLE
        !           618: %endif
        !           619: 
        !           620: %assign rc_val  1
        !           621: 
        !           622:     do_name _aes_encrypt_key128,8
        !           623: 
        !           624:     push    ebp
        !           625:     push    ebx
        !           626:     push    esi
        !           627:     push    edi
        !           628: 
        !           629:     mov     ebp,[esp+24]
        !           630:     mov     [ebp+4*KS_LENGTH],dword 10*16
        !           631:     mov     ebx,[esp+20]
        !           632: 
        !           633:     mov     esi,[ebx]
        !           634:     mov     [ebp],esi
        !           635:     mov     edi,[ebx+4]
        !           636:     mov     [ebp+4],edi
        !           637:     mov     ecx,[ebx+8]
        !           638:     mov     [ebp+8],ecx
        !           639:     mov     edx,[ebx+12]
        !           640:     mov     [ebp+12],edx
        !           641:     add     ebp,16
        !           642:     mov     eax,edx
        !           643: 
        !           644:     f_key   0,16        ; 11 * 4 = 44 unsigned longs
        !           645:     f_key   1,16        ; 4 + 4 * 10 generated = 44
        !           646:     f_key   2,16
        !           647:     f_key   3,16
        !           648:     f_key   4,16
        !           649:     f_key   5,16
        !           650:     f_key   6,16
        !           651:     f_key   7,16
        !           652:     f_key   8,16
        !           653:     f_key   9,16
        !           654: 
        !           655:     pop     edi
        !           656:     pop     esi
        !           657:     pop     ebx
        !           658:     pop     ebp
        !           659:     xor     eax,eax
        !           660:     do_exit  8
        !           661: 
        !           662: %endif
        !           663: 
        !           664: %ifdef  AES_192
        !           665: 
        !           666: %ifndef ENCRYPTION_TABLE
        !           667: ; %define ENCRYPTION_TABLE
        !           668: %endif
        !           669: 
        !           670: %assign rc_val  1
        !           671: 
        !           672:     do_name _aes_encrypt_key192,8
        !           673: 
        !           674:     push    ebp
        !           675:     push    ebx
        !           676:     push    esi
        !           677:     push    edi
        !           678: 
        !           679:     mov     ebp,[esp+24]
        !           680:     mov     [ebp+4*KS_LENGTH],dword 12 * 16
        !           681:     mov     ebx,[esp+20]
        !           682: 
        !           683:     mov     esi,[ebx]
        !           684:     mov     [ebp],esi
        !           685:     mov     edi,[ebx+4]
        !           686:     mov     [ebp+4],edi
        !           687:     mov     ecx,[ebx+8]
        !           688:     mov     [ebp+8],ecx
        !           689:     mov     edx,[ebx+12]
        !           690:     mov     [ebp+12],edx
        !           691:     mov     eax,[ebx+16]
        !           692:     mov     [ebp+16],eax
        !           693:     mov     eax,[ebx+20]
        !           694:     mov     [ebp+20],eax
        !           695:     add     ebp,24
        !           696: 
        !           697:     f_key   0,24        ; 13 * 4 = 52 unsigned longs
        !           698:     f_key   1,24        ; 6 + 6 * 8 generated = 54
        !           699:     f_key   2,24
        !           700:     f_key   3,24
        !           701:     f_key   4,24
        !           702:     f_key   5,24
        !           703:     f_key   6,24
        !           704:     f_key   7,24
        !           705: 
        !           706:     pop     edi
        !           707:     pop     esi
        !           708:     pop     ebx
        !           709:     pop     ebp
        !           710:     xor     eax,eax
        !           711:     do_exit  8
        !           712: 
        !           713: %endif
        !           714: 
        !           715: %ifdef  AES_256
        !           716: 
        !           717: %ifndef ENCRYPTION_TABLE
        !           718: ; %define ENCRYPTION_TABLE
        !           719: %endif
        !           720: 
        !           721: %assign rc_val  1
        !           722: 
        !           723:     do_name _aes_encrypt_key256,8
        !           724: 
        !           725:        mov             ax, sp
        !           726:        movzx   esp, ax
        !           727:        
        !           728:     push    ebp
        !           729:     push    ebx
        !           730:     push    esi
        !           731:     push    edi
        !           732: 
        !           733:     movzx   ebp, word [esp+20] ; ks
        !           734:     mov     [ebp+4*KS_LENGTH],dword 14 * 16
        !           735:     movzx   ebx, word [esp+18] ; key
        !           736: 
        !           737:     mov     esi,[ebx]
        !           738:     mov     [ebp],esi
        !           739:     mov     edi,[ebx+4]
        !           740:     mov     [ebp+4],edi
        !           741:     mov     ecx,[ebx+8]
        !           742:     mov     [ebp+8],ecx
        !           743:     mov     edx,[ebx+12]
        !           744:     mov     [ebp+12],edx
        !           745:     mov     eax,[ebx+16]
        !           746:     mov     [ebp+16],eax
        !           747:     mov     eax,[ebx+20]
        !           748:     mov     [ebp+20],eax
        !           749:     mov     eax,[ebx+24]
        !           750:     mov     [ebp+24],eax
        !           751:     mov     eax,[ebx+28]
        !           752:     mov     [ebp+28],eax
        !           753:     add     ebp,32
        !           754: 
        !           755:     f_key   0,32        ; 15 * 4 = 60 unsigned longs
        !           756:     f_key   1,32        ; 8 + 8 * 7 generated = 64
        !           757:     f_key   2,32
        !           758:     f_key   3,32
        !           759:     f_key   4,32
        !           760:     f_key   5,32
        !           761:     f_key   6,32
        !           762: 
        !           763:     pop     edi
        !           764:     pop     esi
        !           765:     pop     ebx
        !           766:     pop     ebp
        !           767:     xor     eax,eax
        !           768:     do_exit  8
        !           769: 
        !           770: %endif
        !           771: 
        !           772: %ifdef  AES_VAR
        !           773: 
        !           774: %ifndef ENCRYPTION_TABLE
        !           775: ; %define ENCRYPTION_TABLE
        !           776: %endif
        !           777: 
        !           778:     do_name _aes_encrypt_key,12
        !           779: 
        !           780:     mov     ecx,[esp+4]
        !           781:     mov     eax,[esp+8]
        !           782:     mov     edx,[esp+12]
        !           783:     push    edx
        !           784:     push    ecx
        !           785: 
        !           786:     cmp     eax,16
        !           787:     je      .1
        !           788:     cmp     eax,128
        !           789:     je      .1
        !           790: 
        !           791:     cmp     eax,24
        !           792:     je      .2
        !           793:     cmp     eax,192
        !           794:     je      .2
        !           795: 
        !           796:     cmp     eax,32
        !           797:     je      .3
        !           798:     cmp     eax,256
        !           799:     je      .3
        !           800:     mov     eax,-1
        !           801:     add     esp,8
        !           802:     do_exit 12
        !           803: 
        !           804: .1: do_call _aes_encrypt_key128,8
        !           805:     do_exit 12
        !           806: .2: do_call _aes_encrypt_key192,8
        !           807:     do_exit 12
        !           808: .3: do_call _aes_encrypt_key256,8
        !           809:     do_exit 12
        !           810: 
        !           811: %endif
        !           812: 
        !           813: %endif
        !           814: 
        !           815: %ifdef ENCRYPTION_TABLE
        !           816: 
        !           817: ; S-box data - 256 entries
        !           818: 
        !           819:     section _DATA
        !           820: 
        !           821: %define u8(x)   0, x, x, f3(x), f2(x), x, x, f3(x)
        !           822: 
        !           823: _aes_enc_tab:
        !           824:     db  u8(0x63),u8(0x7c),u8(0x77),u8(0x7b),u8(0xf2),u8(0x6b),u8(0x6f),u8(0xc5)
        !           825:     db  u8(0x30),u8(0x01),u8(0x67),u8(0x2b),u8(0xfe),u8(0xd7),u8(0xab),u8(0x76)
        !           826:     db  u8(0xca),u8(0x82),u8(0xc9),u8(0x7d),u8(0xfa),u8(0x59),u8(0x47),u8(0xf0)
        !           827:     db  u8(0xad),u8(0xd4),u8(0xa2),u8(0xaf),u8(0x9c),u8(0xa4),u8(0x72),u8(0xc0)
        !           828:     db  u8(0xb7),u8(0xfd),u8(0x93),u8(0x26),u8(0x36),u8(0x3f),u8(0xf7),u8(0xcc)
        !           829:     db  u8(0x34),u8(0xa5),u8(0xe5),u8(0xf1),u8(0x71),u8(0xd8),u8(0x31),u8(0x15)
        !           830:     db  u8(0x04),u8(0xc7),u8(0x23),u8(0xc3),u8(0x18),u8(0x96),u8(0x05),u8(0x9a)
        !           831:     db  u8(0x07),u8(0x12),u8(0x80),u8(0xe2),u8(0xeb),u8(0x27),u8(0xb2),u8(0x75)
        !           832:     db  u8(0x09),u8(0x83),u8(0x2c),u8(0x1a),u8(0x1b),u8(0x6e),u8(0x5a),u8(0xa0)
        !           833:     db  u8(0x52),u8(0x3b),u8(0xd6),u8(0xb3),u8(0x29),u8(0xe3),u8(0x2f),u8(0x84)
        !           834:     db  u8(0x53),u8(0xd1),u8(0x00),u8(0xed),u8(0x20),u8(0xfc),u8(0xb1),u8(0x5b)
        !           835:     db  u8(0x6a),u8(0xcb),u8(0xbe),u8(0x39),u8(0x4a),u8(0x4c),u8(0x58),u8(0xcf)
        !           836:     db  u8(0xd0),u8(0xef),u8(0xaa),u8(0xfb),u8(0x43),u8(0x4d),u8(0x33),u8(0x85)
        !           837:     db  u8(0x45),u8(0xf9),u8(0x02),u8(0x7f),u8(0x50),u8(0x3c),u8(0x9f),u8(0xa8)
        !           838:     db  u8(0x51),u8(0xa3),u8(0x40),u8(0x8f),u8(0x92),u8(0x9d),u8(0x38),u8(0xf5)
        !           839:     db  u8(0xbc),u8(0xb6),u8(0xda),u8(0x21),u8(0x10),u8(0xff),u8(0xf3),u8(0xd2)
        !           840:     db  u8(0xcd),u8(0x0c),u8(0x13),u8(0xec),u8(0x5f),u8(0x97),u8(0x44),u8(0x17)
        !           841:     db  u8(0xc4),u8(0xa7),u8(0x7e),u8(0x3d),u8(0x64),u8(0x5d),u8(0x19),u8(0x73)
        !           842:     db  u8(0x60),u8(0x81),u8(0x4f),u8(0xdc),u8(0x22),u8(0x2a),u8(0x90),u8(0x88)
        !           843:     db  u8(0x46),u8(0xee),u8(0xb8),u8(0x14),u8(0xde),u8(0x5e),u8(0x0b),u8(0xdb)
        !           844:     db  u8(0xe0),u8(0x32),u8(0x3a),u8(0x0a),u8(0x49),u8(0x06),u8(0x24),u8(0x5c)
        !           845:     db  u8(0xc2),u8(0xd3),u8(0xac),u8(0x62),u8(0x91),u8(0x95),u8(0xe4),u8(0x79)
        !           846:     db  u8(0xe7),u8(0xc8),u8(0x37),u8(0x6d),u8(0x8d),u8(0xd5),u8(0x4e),u8(0xa9)
        !           847:     db  u8(0x6c),u8(0x56),u8(0xf4),u8(0xea),u8(0x65),u8(0x7a),u8(0xae),u8(0x08)
        !           848:     db  u8(0xba),u8(0x78),u8(0x25),u8(0x2e),u8(0x1c),u8(0xa6),u8(0xb4),u8(0xc6)
        !           849:     db  u8(0xe8),u8(0xdd),u8(0x74),u8(0x1f),u8(0x4b),u8(0xbd),u8(0x8b),u8(0x8a)
        !           850:     db  u8(0x70),u8(0x3e),u8(0xb5),u8(0x66),u8(0x48),u8(0x03),u8(0xf6),u8(0x0e)
        !           851:     db  u8(0x61),u8(0x35),u8(0x57),u8(0xb9),u8(0x86),u8(0xc1),u8(0x1d),u8(0x9e)
        !           852:     db  u8(0xe1),u8(0xf8),u8(0x98),u8(0x11),u8(0x69),u8(0xd9),u8(0x8e),u8(0x94)
        !           853:     db  u8(0x9b),u8(0x1e),u8(0x87),u8(0xe9),u8(0xce),u8(0x55),u8(0x28),u8(0xdf)
        !           854:     db  u8(0x8c),u8(0xa1),u8(0x89),u8(0x0d),u8(0xbf),u8(0xe6),u8(0x42),u8(0x68)
        !           855:     db  u8(0x41),u8(0x99),u8(0x2d),u8(0x0f),u8(0xb0),u8(0x54),u8(0xbb),u8(0x16)
        !           856: 
        !           857: %endif
        !           858: 
        !           859: %ifdef  DECRYPTION
        !           860: 
        !           861: ; %define DECRYPTION_TABLE
        !           862: 
        !           863: %define dtab_0(x)   [_aes_dec_tab+  8*x]
        !           864: %define dtab_1(x)   [_aes_dec_tab+3+8*x]
        !           865: %define dtab_2(x)   [_aes_dec_tab+2+8*x]
        !           866: %define dtab_3(x)   [_aes_dec_tab+1+8*x]
        !           867: %define dtab_x(x)   byte [_aes_dec_tab+7+8*x]
        !           868: 
        !           869: %macro irn_fun 2
        !           870: 
        !           871:     rol eax,16
        !           872:     %1      esi, cl, 0, ebp
        !           873:     %1      esi, bh, 1, ebp
        !           874:     %1      esi, al, 2, ebp
        !           875:     %1      edi, dl, 0, ebp
        !           876:     %1      edi, ch, 1, ebp
        !           877:     %1      edi, ah, 3, ebp
        !           878:     %2      ebp, bl, 0, ebp
        !           879:     shr     eax,16
        !           880:     and     ebx,0xffff0000
        !           881:     or      ebx,eax
        !           882:     shr     ecx,16
        !           883:     %1      ebp, bh, 1, eax
        !           884:     %1      ebp, ch, 3, eax
        !           885:     %2      eax, cl, 2, ecx
        !           886:     %1      eax, bl, 0, ecx
        !           887:     %1      eax, dh, 1, ecx
        !           888:     shr     ebx,16
        !           889:     shr     edx,16
        !           890:     %1      esi, dh, 3, ecx
        !           891:     %1      ebp, dl, 2, ecx
        !           892:     %1      eax, bh, 3, ecx
        !           893:     %1      edi, bl, 2, ecx
        !           894: 
        !           895: %endmacro
        !           896: 
        !           897: ; Basic MOV and XOR Operations for normal rounds
        !           898: 
        !           899: %macro  ni_xor  4
        !           900:     movzx   %4,%2
        !           901:     xor     %1,dtab_%3(%4)
        !           902: %endmacro
        !           903: 
        !           904: %macro  ni_mov  4
        !           905:     movzx   %4,%2
        !           906:     mov     %1,dtab_%3(%4)
        !           907: %endmacro
        !           908: 
        !           909: ; Basic MOV and XOR Operations for last round
        !           910: 
        !           911: %macro  li_xor  4
        !           912:     movzx   %4,%2
        !           913:     movzx   %4,dtab_x(%4)
        !           914: %if %3 != 0
        !           915:     shl     %4,8*%3
        !           916: %endif
        !           917:     xor     %1,%4
        !           918: %endmacro
        !           919: 
        !           920: %macro  li_mov  4
        !           921:     movzx   %4,%2
        !           922:     movzx   %1,dtab_x(%4)
        !           923: %if %3 != 0
        !           924:     shl     %1,8*%3
        !           925: %endif
        !           926: %endmacro
        !           927: 
        !           928: %ifdef REDUCE_CODE_SIZE
        !           929: 
        !           930: dec_round:
        !           931:        sub             sp, 2
        !           932: %ifdef AES_REV_DKS
        !           933:     add     ebp,16
        !           934: %else
        !           935:     sub     ebp,16
        !           936: %endif
        !           937:     save    1,ebp
        !           938:     mov     esi,[ebp+8]
        !           939:     mov     edi,[ebp+12]
        !           940: 
        !           941:     irn_fun ni_xor, ni_mov
        !           942: 
        !           943:     mov     ebx,ebp
        !           944:     mov     ecx,esi
        !           945:     mov     edx,edi
        !           946:     restore ebp,1
        !           947:     xor     eax,[ebp]
        !           948:     xor     ebx,[ebp+4]
        !           949:        add             sp, 2
        !           950:     ret
        !           951: 
        !           952: %else
        !           953: 
        !           954: %macro dec_round 0
        !           955: 
        !           956: %ifdef AES_REV_DKS
        !           957:     add     ebp,16
        !           958: %else
        !           959:     sub     ebp,16
        !           960: %endif
        !           961:     save    0,ebp
        !           962:     mov     esi,[ebp+8]
        !           963:     mov     edi,[ebp+12]
        !           964: 
        !           965:     irn_fun ni_xor, ni_mov
        !           966: 
        !           967:     mov     ebx,ebp
        !           968:     mov     ecx,esi
        !           969:     mov     edx,edi
        !           970:     restore ebp,0
        !           971:     xor     eax,[ebp]
        !           972:     xor     ebx,[ebp+4]
        !           973: 
        !           974: %endmacro
        !           975: 
        !           976: %endif
        !           977: 
        !           978: %macro dec_last_round 0
        !           979: 
        !           980: %ifdef AES_REV_DKS
        !           981:     add     ebp,16
        !           982: %else
        !           983:     sub     ebp,16
        !           984: %endif
        !           985:     save    0,ebp
        !           986:     mov     esi,[ebp+8]
        !           987:     mov     edi,[ebp+12]
        !           988: 
        !           989:     irn_fun li_xor, li_mov
        !           990: 
        !           991:     mov     ebx,ebp
        !           992:     restore ebp,0
        !           993:     xor     eax,[ebp]
        !           994:     xor     ebx,[ebp+4]
        !           995: 
        !           996: %endmacro
        !           997: 
        !           998:     section _TEXT
        !           999: 
        !          1000: ; AES Decryption Subroutine
        !          1001: 
        !          1002:     do_name _aes_decrypt,12
        !          1003:     
        !          1004:        mov             ax, sp
        !          1005:        movzx   esp, ax
        !          1006: 
        !          1007:     sub     esp,stk_spc
        !          1008:     mov     [esp+16],ebp
        !          1009:     mov     [esp+12],ebx
        !          1010:     mov     [esp+ 8],esi
        !          1011:     mov     [esp+ 4],edi
        !          1012: 
        !          1013: ; input four columns and xor in first round key
        !          1014: 
        !          1015:     movzx   esi,word [esp+in_blk+stk_spc] ; input pointer
        !          1016:     mov     eax,[esi   ]
        !          1017:     mov     ebx,[esi+ 4]
        !          1018:     mov     ecx,[esi+ 8]
        !          1019:     mov     edx,[esi+12]
        !          1020:     lea     esi,[esi+16]
        !          1021: 
        !          1022:     movzx   ebp, word [esp+ctx+stk_spc]    ; key pointer
        !          1023:     movzx   edi,byte[ebp+4*KS_LENGTH]
        !          1024: %ifndef  AES_REV_DKS        ; if decryption key schedule is not reversed
        !          1025:     lea     ebp,[ebp+edi] ; we have to access it from the top down
        !          1026: %endif
        !          1027:     xor     eax,[ebp   ]  ; key schedule
        !          1028:     xor     ebx,[ebp+ 4]
        !          1029:     xor     ecx,[ebp+ 8]
        !          1030:     xor     edx,[ebp+12]
        !          1031: 
        !          1032: ; determine the number of rounds
        !          1033: 
        !          1034: %ifndef AES_256
        !          1035:     cmp     edi,10*16
        !          1036:     je      .3
        !          1037:     cmp     edi,12*16
        !          1038:     je      .2
        !          1039:     cmp     edi,14*16
        !          1040:     je      .1
        !          1041:     mov     eax,-1
        !          1042:     jmp     .5
        !          1043: %endif
        !          1044: 
        !          1045: .1: mf_call dec_round
        !          1046:     mf_call dec_round
        !          1047: .2: mf_call dec_round
        !          1048:     mf_call dec_round
        !          1049: .3: mf_call dec_round
        !          1050:     mf_call dec_round
        !          1051:     mf_call dec_round
        !          1052:     mf_call dec_round
        !          1053:     mf_call dec_round
        !          1054:     mf_call dec_round
        !          1055:     mf_call dec_round
        !          1056:     mf_call dec_round
        !          1057:     mf_call dec_round
        !          1058:     dec_last_round
        !          1059: 
        !          1060: ; move final values to the output array.
        !          1061: 
        !          1062:     movzx   ebp,word [esp+out_blk+stk_spc]
        !          1063:     mov     [ebp],eax
        !          1064:     mov     [ebp+4],ebx
        !          1065:     mov     [ebp+8],esi
        !          1066:     mov     [ebp+12],edi
        !          1067:     xor     eax,eax
        !          1068: 
        !          1069: .5: mov     ebp,[esp+16]
        !          1070:     mov     ebx,[esp+12]
        !          1071:     mov     esi,[esp+ 8]
        !          1072:     mov     edi,[esp+ 4]
        !          1073:     add     esp,stk_spc
        !          1074:     do_exit 12
        !          1075: 
        !          1076: %endif
        !          1077: 
        !          1078: %ifdef REDUCE_CODE_SIZE
        !          1079: 
        !          1080: inv_mix_col:
        !          1081:     movzx   ecx,dl          ; input  eax, edx
        !          1082:     movzx   ecx,etab_b(ecx) ; output eax
        !          1083:     mov     eax,dtab_0(ecx) ; used   ecx
        !          1084:     movzx   ecx,dh
        !          1085:     shr     edx,16
        !          1086:     movzx   ecx,etab_b(ecx)
        !          1087:     xor     eax,dtab_1(ecx)
        !          1088:     movzx   ecx,dl
        !          1089:     movzx   ecx,etab_b(ecx)
        !          1090:     xor     eax,dtab_2(ecx)
        !          1091:     movzx   ecx,dh
        !          1092:     movzx   ecx,etab_b(ecx)
        !          1093:     xor     eax,dtab_3(ecx)
        !          1094:     ret
        !          1095: 
        !          1096: %else
        !          1097: 
        !          1098: %macro  inv_mix_col 0   
        !          1099: 
        !          1100:     movzx   ecx,dl          ; input  eax, edx
        !          1101:     movzx   ecx,etab_b(ecx) ; output eax
        !          1102:     mov     eax,dtab_0(ecx) ; used   ecx
        !          1103:     movzx   ecx,dh
        !          1104:     shr     edx,16
        !          1105:     movzx   ecx,etab_b(ecx)
        !          1106:     xor     eax,dtab_1(ecx)
        !          1107:     movzx   ecx,dl
        !          1108:     movzx   ecx,etab_b(ecx)
        !          1109:     xor     eax,dtab_2(ecx)
        !          1110:     movzx   ecx,dh
        !          1111:     movzx   ecx,etab_b(ecx)
        !          1112:     xor     eax,dtab_3(ecx)
        !          1113: 
        !          1114: %endmacro
        !          1115: 
        !          1116: %endif
        !          1117: 
        !          1118: %ifdef DECRYPTION_KEY_SCHEDULE
        !          1119: 
        !          1120: %ifdef AES_128
        !          1121: 
        !          1122: %ifndef DECRYPTION_TABLE
        !          1123: ; %define DECRYPTION_TABLE
        !          1124: %endif
        !          1125: 
        !          1126:     do_name _aes_decrypt_key128,8
        !          1127: 
        !          1128:     push    ebp
        !          1129:     push    ebx
        !          1130:     push    esi
        !          1131:     push    edi
        !          1132:     mov     eax,[esp+24]    ; context
        !          1133:     mov     edx,[esp+20]    ; key
        !          1134:     push    eax
        !          1135:     push    edx
        !          1136:     do_call _aes_encrypt_key128,8   ; generate expanded encryption key
        !          1137:     mov     eax,10*16
        !          1138:     mov     esi,[esp+24]    ; pointer to first round key
        !          1139:     lea     edi,[esi+eax]   ; pointer to last round key
        !          1140:     add     esi,32
        !          1141:                             ; the inverse mix column transformation
        !          1142:     mov     edx,[esi-16]    ; needs to be applied to all round keys
        !          1143:     mf_call inv_mix_col     ; except first and last. Hence start by
        !          1144:     mov     [esi-16],eax    ; transforming the four sub-keys in the
        !          1145:     mov     edx,[esi-12]    ; second round key
        !          1146:     mf_call inv_mix_col
        !          1147:     mov     [esi-12],eax    ; transformations for subsequent rounds
        !          1148:     mov     edx,[esi-8]     ; can then be made more efficient by
        !          1149:     mf_call inv_mix_col     ; noting that for three of the four sub-keys
        !          1150:     mov     [esi-8],eax     ; in the encryption round key ek[r]:
        !          1151:     mov     edx,[esi-4]     ;
        !          1152:     mf_call inv_mix_col     ;   ek[r][n] = ek[r][n-1] ^ ek[r-1][n]
        !          1153:     mov     [esi-4],eax     ;
        !          1154:                             ; where n is 1..3. Hence the corresponding
        !          1155: .0: mov     edx,[esi]       ; subkeys in the decryption round key dk[r]
        !          1156:     mf_call inv_mix_col     ; also obey since inv_mix_col is linear in
        !          1157:     mov     [esi],eax       ; GF(256):
        !          1158:     xor     eax,[esi-12]    ;
        !          1159:     mov     [esi+4],eax     ;   dk[r][n] = dk[r][n-1] ^ dk[r-1][n]
        !          1160:     xor     eax,[esi-8]     ;
        !          1161:     mov     [esi+8],eax     ; So we only need one inverse mix column
        !          1162:     xor     eax,[esi-4]     ; operation (n = 0) for each four word cycle
        !          1163:     mov     [esi+12],eax    ; in the expanded key.
        !          1164:     add     esi,16
        !          1165:     cmp     edi,esi
        !          1166:     jg      .0
        !          1167:     jmp     dec_end
        !          1168: 
        !          1169: %endif
        !          1170: 
        !          1171: %ifdef AES_192
        !          1172: 
        !          1173: %ifndef DECRYPTION_TABLE
        !          1174: ; %define DECRYPTION_TABLE
        !          1175: %endif
        !          1176: 
        !          1177:     do_name _aes_decrypt_key192,8
        !          1178: 
        !          1179:     push    ebp
        !          1180:     push    ebx
        !          1181:     push    esi
        !          1182:     push    edi
        !          1183:     mov     eax,[esp+24]    ; context
        !          1184:     mov     edx,[esp+20]    ; key
        !          1185:     push    eax
        !          1186:     push    edx
        !          1187:     do_call _aes_encrypt_key192,8   ; generate expanded encryption key
        !          1188:     mov     eax,12*16
        !          1189:     mov     esi,[esp+24]    ; first round key
        !          1190:     lea     edi,[esi+eax]   ; last round key
        !          1191:     add     esi,48          ; the first 6 words are the key, of
        !          1192:                             ; which the top 2 words are part of
        !          1193:     mov     edx,[esi-32]    ; the second round key and hence
        !          1194:     mf_call inv_mix_col     ; need to be modified. After this we
        !          1195:     mov     [esi-32],eax    ; need to do a further six values prior
        !          1196:     mov     edx,[esi-28]    ; to using a more efficient technique
        !          1197:     mf_call inv_mix_col     ; based on:
        !          1198:     mov     [esi-28],eax    ;
        !          1199:                             ; dk[r][n] = dk[r][n-1] ^ dk[r-1][n]
        !          1200:     mov     edx,[esi-24]    ;
        !          1201:     mf_call inv_mix_col     ; for n = 1 .. 5 where the key expansion
        !          1202:     mov     [esi-24],eax    ; cycle is now 6 words long
        !          1203:     mov     edx,[esi-20]
        !          1204:     mf_call inv_mix_col
        !          1205:     mov     [esi-20],eax
        !          1206:     mov     edx,[esi-16]
        !          1207:     mf_call inv_mix_col
        !          1208:     mov     [esi-16],eax
        !          1209:     mov     edx,[esi-12]
        !          1210:     mf_call inv_mix_col
        !          1211:     mov     [esi-12],eax
        !          1212:     mov     edx,[esi-8]
        !          1213:     mf_call inv_mix_col
        !          1214:     mov     [esi-8],eax
        !          1215:     mov     edx,[esi-4]
        !          1216:     mf_call inv_mix_col
        !          1217:     mov     [esi-4],eax
        !          1218: 
        !          1219: .0: mov     edx,[esi]       ; the expanded key is 13 * 4 = 44 32-bit words
        !          1220:     mf_call inv_mix_col     ; of which 11 * 4 = 44 have to be modified
        !          1221:     mov     [esi],eax       ; using inv_mix_col.  We have already done 8
        !          1222:     xor     eax,[esi-20]    ; of these so 36 are left - hence we need
        !          1223:     mov     [esi+4],eax     ; exactly 6 loops of six here
        !          1224:     xor     eax,[esi-16]
        !          1225:     mov     [esi+8],eax
        !          1226:     xor     eax,[esi-12]
        !          1227:     mov     [esi+12],eax
        !          1228:     xor     eax,[esi-8]
        !          1229:     mov     [esi+16],eax
        !          1230:     xor     eax,[esi-4]
        !          1231:     mov     [esi+20],eax
        !          1232:     add     esi,24
        !          1233:     cmp     edi,esi
        !          1234:     jg      .0
        !          1235:     jmp     dec_end
        !          1236: 
        !          1237: %endif
        !          1238: 
        !          1239: %ifdef AES_256
        !          1240: 
        !          1241: %ifndef DECRYPTION_TABLE
        !          1242: ; %define DECRYPTION_TABLE
        !          1243: %endif
        !          1244: 
        !          1245:     do_name _aes_decrypt_key256,8
        !          1246:     
        !          1247:     mov                ax, sp
        !          1248:        movzx   esp, ax
        !          1249:     push    ebp
        !          1250:     push    ebx
        !          1251:     push    esi
        !          1252:     push    edi
        !          1253:     
        !          1254:     movzx   eax, word [esp+20] ; ks
        !          1255:     movzx   edx, word [esp+18] ; key
        !          1256:     push    ax
        !          1257:     push    dx
        !          1258:     do_call _aes_encrypt_key256,4   ; generate expanded encryption key
        !          1259:     mov     eax,14*16
        !          1260:     movzx   esi, word [esp+20] ; ks
        !          1261:     lea     edi,[esi+eax]
        !          1262:     add     esi,64
        !          1263: 
        !          1264:     mov     edx,[esi-48]    ; the primary key is 8 words, of which
        !          1265:     mf_call inv_mix_col     ; the top four require modification
        !          1266:     mov     [esi-48],eax
        !          1267:     mov     edx,[esi-44]
        !          1268:     mf_call inv_mix_col
        !          1269:     mov     [esi-44],eax
        !          1270:     mov     edx,[esi-40]
        !          1271:     mf_call inv_mix_col
        !          1272:     mov     [esi-40],eax
        !          1273:     mov     edx,[esi-36]
        !          1274:     mf_call inv_mix_col
        !          1275:     mov     [esi-36],eax
        !          1276: 
        !          1277:     mov     edx,[esi-32]    ; the encryption key expansion cycle is
        !          1278:     mf_call inv_mix_col     ; now eight words long so we need to
        !          1279:     mov     [esi-32],eax    ; start by doing one complete block
        !          1280:     mov     edx,[esi-28]
        !          1281:     mf_call inv_mix_col
        !          1282:     mov     [esi-28],eax
        !          1283:     mov     edx,[esi-24]
        !          1284:     mf_call inv_mix_col
        !          1285:     mov     [esi-24],eax
        !          1286:     mov     edx,[esi-20]
        !          1287:     mf_call inv_mix_col
        !          1288:     mov     [esi-20],eax
        !          1289:     mov     edx,[esi-16]
        !          1290:     mf_call inv_mix_col
        !          1291:     mov     [esi-16],eax
        !          1292:     mov     edx,[esi-12]
        !          1293:     mf_call inv_mix_col
        !          1294:     mov     [esi-12],eax
        !          1295:     mov     edx,[esi-8]
        !          1296:     mf_call inv_mix_col
        !          1297:     mov     [esi-8],eax
        !          1298:     mov     edx,[esi-4]
        !          1299:     mf_call inv_mix_col
        !          1300:     mov     [esi-4],eax
        !          1301: 
        !          1302: .0: mov     edx,[esi]       ; we can now speed up the remaining
        !          1303:     mf_call inv_mix_col     ; rounds by using the technique
        !          1304:     mov     [esi],eax       ; outlined earlier.  But note that
        !          1305:     xor     eax,[esi-28]    ; there is one extra inverse mix
        !          1306:     mov     [esi+4],eax     ; column operation as the 256 bit
        !          1307:     xor     eax,[esi-24]    ; key has an extra non-linear step
        !          1308:     mov     [esi+8],eax     ; for the midway element.
        !          1309:     xor     eax,[esi-20]
        !          1310:     mov     [esi+12],eax    ; the expanded key is 15 * 4 = 60
        !          1311:     mov     edx,[esi+16]    ; 32-bit words of which 52 need to
        !          1312:     mf_call inv_mix_col     ; be modified.  We have already done
        !          1313:     mov     [esi+16],eax    ; 12 so 40 are left - which means
        !          1314:     xor     eax,[esi-12]    ; that we need exactly 5 loops of 8
        !          1315:     mov     [esi+20],eax
        !          1316:     xor     eax,[esi-8]
        !          1317:     mov     [esi+24],eax
        !          1318:     xor     eax,[esi-4]
        !          1319:     mov     [esi+28],eax
        !          1320:     add     esi,32
        !          1321:     cmp     edi,esi
        !          1322:     jg      .0
        !          1323: 
        !          1324: %endif
        !          1325: 
        !          1326: dec_end:
        !          1327: 
        !          1328: %ifdef AES_REV_DKS
        !          1329: 
        !          1330:     movzx   esi,word [esp+20]  ; this reverses the order of the
        !          1331: .1: mov     eax,[esi]                  ; round keys if required
        !          1332:     mov     ebx,[esi+4]
        !          1333:     mov     ebp,[edi]
        !          1334:     mov     edx,[edi+4]
        !          1335:     mov     [esi],ebp
        !          1336:     mov     [esi+4],edx
        !          1337:     mov     [edi],eax
        !          1338:     mov     [edi+4],ebx
        !          1339: 
        !          1340:     mov     eax,[esi+8]
        !          1341:     mov     ebx,[esi+12]
        !          1342:     mov     ebp,[edi+8]
        !          1343:     mov     edx,[edi+12]
        !          1344:     mov     [esi+8],ebp
        !          1345:     mov     [esi+12],edx
        !          1346:     mov     [edi+8],eax
        !          1347:     mov     [edi+12],ebx
        !          1348: 
        !          1349:     add     esi,16
        !          1350:     sub     edi,16
        !          1351:     cmp     edi,esi
        !          1352:     jg      .1
        !          1353: 
        !          1354: %endif
        !          1355: 
        !          1356:     pop     edi
        !          1357:     pop     esi
        !          1358:     pop     ebx
        !          1359:     pop     ebp
        !          1360:     xor     eax,eax
        !          1361:     do_exit  8
        !          1362: 
        !          1363: %ifdef AES_VAR
        !          1364: 
        !          1365:     do_name _aes_decrypt_key,12
        !          1366: 
        !          1367:     mov     ecx,[esp+4]
        !          1368:     mov     eax,[esp+8]
        !          1369:     mov     edx,[esp+12]
        !          1370:     push    edx
        !          1371:     push    ecx
        !          1372: 
        !          1373:     cmp     eax,16
        !          1374:     je      .1
        !          1375:     cmp     eax,128
        !          1376:     je      .1
        !          1377: 
        !          1378:     cmp     eax,24
        !          1379:     je      .2
        !          1380:     cmp     eax,192
        !          1381:     je      .2
        !          1382: 
        !          1383:     cmp     eax,32
        !          1384:     je      .3
        !          1385:     cmp     eax,256
        !          1386:     je      .3
        !          1387:     mov     eax,-1
        !          1388:     add     esp,8
        !          1389:     do_exit 12
        !          1390: 
        !          1391: .1: do_call _aes_decrypt_key128,8
        !          1392:     do_exit 12
        !          1393: .2: do_call _aes_decrypt_key192,8
        !          1394:     do_exit 12
        !          1395: .3: do_call _aes_decrypt_key256,8
        !          1396:     do_exit 12
        !          1397: 
        !          1398: %endif
        !          1399: 
        !          1400: %endif
        !          1401: 
        !          1402: %ifdef DECRYPTION_TABLE
        !          1403: 
        !          1404: ; Inverse S-box data - 256 entries
        !          1405: 
        !          1406:     section _DATA
        !          1407: 
        !          1408: %define v8(x)   fe(x), f9(x), fd(x), fb(x), fe(x), f9(x), fd(x), x
        !          1409: 
        !          1410: _aes_dec_tab:
        !          1411:     db  v8(0x52),v8(0x09),v8(0x6a),v8(0xd5),v8(0x30),v8(0x36),v8(0xa5),v8(0x38)
        !          1412:     db  v8(0xbf),v8(0x40),v8(0xa3),v8(0x9e),v8(0x81),v8(0xf3),v8(0xd7),v8(0xfb)
        !          1413:     db  v8(0x7c),v8(0xe3),v8(0x39),v8(0x82),v8(0x9b),v8(0x2f),v8(0xff),v8(0x87)
        !          1414:     db  v8(0x34),v8(0x8e),v8(0x43),v8(0x44),v8(0xc4),v8(0xde),v8(0xe9),v8(0xcb)
        !          1415:     db  v8(0x54),v8(0x7b),v8(0x94),v8(0x32),v8(0xa6),v8(0xc2),v8(0x23),v8(0x3d)
        !          1416:     db  v8(0xee),v8(0x4c),v8(0x95),v8(0x0b),v8(0x42),v8(0xfa),v8(0xc3),v8(0x4e)
        !          1417:     db  v8(0x08),v8(0x2e),v8(0xa1),v8(0x66),v8(0x28),v8(0xd9),v8(0x24),v8(0xb2)
        !          1418:     db  v8(0x76),v8(0x5b),v8(0xa2),v8(0x49),v8(0x6d),v8(0x8b),v8(0xd1),v8(0x25)
        !          1419:     db  v8(0x72),v8(0xf8),v8(0xf6),v8(0x64),v8(0x86),v8(0x68),v8(0x98),v8(0x16)
        !          1420:     db  v8(0xd4),v8(0xa4),v8(0x5c),v8(0xcc),v8(0x5d),v8(0x65),v8(0xb6),v8(0x92)
        !          1421:     db  v8(0x6c),v8(0x70),v8(0x48),v8(0x50),v8(0xfd),v8(0xed),v8(0xb9),v8(0xda)
        !          1422:     db  v8(0x5e),v8(0x15),v8(0x46),v8(0x57),v8(0xa7),v8(0x8d),v8(0x9d),v8(0x84)
        !          1423:     db  v8(0x90),v8(0xd8),v8(0xab),v8(0x00),v8(0x8c),v8(0xbc),v8(0xd3),v8(0x0a)
        !          1424:     db  v8(0xf7),v8(0xe4),v8(0x58),v8(0x05),v8(0xb8),v8(0xb3),v8(0x45),v8(0x06)
        !          1425:     db  v8(0xd0),v8(0x2c),v8(0x1e),v8(0x8f),v8(0xca),v8(0x3f),v8(0x0f),v8(0x02)
        !          1426:     db  v8(0xc1),v8(0xaf),v8(0xbd),v8(0x03),v8(0x01),v8(0x13),v8(0x8a),v8(0x6b)
        !          1427:     db  v8(0x3a),v8(0x91),v8(0x11),v8(0x41),v8(0x4f),v8(0x67),v8(0xdc),v8(0xea)
        !          1428:     db  v8(0x97),v8(0xf2),v8(0xcf),v8(0xce),v8(0xf0),v8(0xb4),v8(0xe6),v8(0x73)
        !          1429:     db  v8(0x96),v8(0xac),v8(0x74),v8(0x22),v8(0xe7),v8(0xad),v8(0x35),v8(0x85)
        !          1430:     db  v8(0xe2),v8(0xf9),v8(0x37),v8(0xe8),v8(0x1c),v8(0x75),v8(0xdf),v8(0x6e)
        !          1431:     db  v8(0x47),v8(0xf1),v8(0x1a),v8(0x71),v8(0x1d),v8(0x29),v8(0xc5),v8(0x89)
        !          1432:     db  v8(0x6f),v8(0xb7),v8(0x62),v8(0x0e),v8(0xaa),v8(0x18),v8(0xbe),v8(0x1b)
        !          1433:     db  v8(0xfc),v8(0x56),v8(0x3e),v8(0x4b),v8(0xc6),v8(0xd2),v8(0x79),v8(0x20)
        !          1434:     db  v8(0x9a),v8(0xdb),v8(0xc0),v8(0xfe),v8(0x78),v8(0xcd),v8(0x5a),v8(0xf4)
        !          1435:     db  v8(0x1f),v8(0xdd),v8(0xa8),v8(0x33),v8(0x88),v8(0x07),v8(0xc7),v8(0x31)
        !          1436:     db  v8(0xb1),v8(0x12),v8(0x10),v8(0x59),v8(0x27),v8(0x80),v8(0xec),v8(0x5f)
        !          1437:     db  v8(0x60),v8(0x51),v8(0x7f),v8(0xa9),v8(0x19),v8(0xb5),v8(0x4a),v8(0x0d)
        !          1438:     db  v8(0x2d),v8(0xe5),v8(0x7a),v8(0x9f),v8(0x93),v8(0xc9),v8(0x9c),v8(0xef)
        !          1439:     db  v8(0xa0),v8(0xe0),v8(0x3b),v8(0x4d),v8(0xae),v8(0x2a),v8(0xf5),v8(0xb0)
        !          1440:     db  v8(0xc8),v8(0xeb),v8(0xbb),v8(0x3c),v8(0x83),v8(0x53),v8(0x99),v8(0x61)
        !          1441:     db  v8(0x17),v8(0x2b),v8(0x04),v8(0x7e),v8(0xba),v8(0x77),v8(0xd6),v8(0x26)
        !          1442:     db  v8(0xe1),v8(0x69),v8(0x14),v8(0x63),v8(0x55),v8(0x21),v8(0x0c),v8(0x7d)
        !          1443: 
        !          1444: %endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.