📄 phelix86.s
字号:
##
##----------------------------------------------------------------
## Phelix encryption/authentication algorithm
## Author: Doug Whiting, Hifn. 2005.
##
## This source code is released to the public domain
##----------------------------------------------------------------
##
.file "phelix86.S"
.text
.align 4
#ifndef __ASSEMBLER__ /* using C pre-processor? */
.include "strucmac.S" ## structured programming macros
#else
#include "strucmac.S" /* follow C include path */
.set _isDefined_,1 ## useful for C defines
#ifdef ECRYPT_API /* with ECRYPT switch? */
#define _ECRYPT_API _isDefined_
#endif
#ifdef MIX_ASM
#define _MIX_ASM _isDefined_
#endif
#endif
##
## concatenate text together (useful in building names inside macros)
.macro strCat aa,bb,cc,dd,ee,ff,gg,hh
\aa\bb\cc\dd\ee\ff\gg\hh
.endm
##----------------------------------------------------------------
## define a global label. Handle linking with and without underscore
.macro C_global phelixName,ecryptName
\phelixName: #use both "genders" to work across linkage conventions
_\phelixName:
.ifdef _MIX_ASM # rename with _ASM suffix to allow linking of C & asm together
strCat ".global ",\phelixName,"_ASM"
strCat ".global _",\phelixName,"_ASM"
strCat " ",\phelixName,"_ASM:"
strCat "_",\phelixName,"_ASM:"
.else #
.global \phelixName
.global _\phelixName
.ifdef _ECRYPT_API # use ECRYPT names as well
.ifnc \ecryptName,
.global \ecryptName
.global _\ecryptName
\ecryptName:
_\ecryptName:
.endif
.endif
.endif
.endm
##
##################################################################
##
C_global _debugPhelix_
.long 0 #ignored here, but must be defined for testPhelix.c
AsmName: .ascii "gnu.as\0"
.align 4
##
C_global PhelixCompiler_Name #show who assembled us
lea AsmName,%eax
C_Global PhelixInit,ECRYPT_init #Init call does nothing
ret
##
##----------------------------------------------------------------
## Macros and definitions
##----------------------------------------------------------------
##
## Phelix rotation constants
.set ROT_0a, 9
.set ROT_1a, 10
.set ROT_2a, 17
.set ROT_3a, 30
.set ROT_4a, 13
.set ROT_0b, 20
.set ROT_1b, 11
.set ROT_2b, 5
.set ROT_3b, 15
.set ROT_4b, 25
.set UNROLL_CNT, 8 #how many blocks to unroll in inner loop
.set ZERO_INIT_CNT, 8 #number of words of init
.set MAGIC_MAC_XOR, 0x912d94f1 #special constants
.set MAGIC_AAD_XOR, 0xaadaadaa
##
##----- register assignments
## Z0 equ eax
## Z1 equ ebx
## Z2 equ ecx
## Z3 equ edx
## Z4 equ esi
## t0 equ ebp #"temp" scratch registers
## t1 equ edi
## oldZreg equ Z4
##
##----------------------------------------------------------------
##
## Allocate and define local variables on the stack
## [Note: We use esp for locals, not ebp, since we need ebp as a variable.
## Thus, we cannot use the assembler stack frame primitives.]
##
.set _maxLocalSize_ ,0 #max locals usage in bytes
.set _Phelix_LocalSize ,0 #starting value: no locals allocated yet
.set _SO_ ,0 #current stack offset due to calls
##
.macro _newLocal wCnt,lName #macro to define a local variable
.set \lName ,_Phelix_LocalSize
.set _Phelix_LocalSize,_Phelix_LocalSize+4*(\wCnt)
## keep running tabs on stack usage for locals
.if _maxLocalSize_<_Phelix_LocalSize
.set _maxLocalSize_,_Phelix_LocalSize
.endif
.endm
##
.macro _newParm wCnt,_pp_
.set \_pp_, _pOfs_
strCat ".set ",\_pp_,_LCL,",",(_pOfs_-_cpOfs_)
.set _pOfs_,_pOfs_+4*(\wCnt)
.endm
##
## now define local variables for the Encrypt/Decrypt functions
_newLocal 1,srcPtr #pointer to input data buffer
_newLocal 1,dstPtr #pointer to output data buffer
_newLocal 1,loopByteCnt #inner loop byte counter
_newLocal 1,jmpTabPtr #pointer to encrypt/decrypt jump table
_newLocal 8,X_i_0 #local copy of the key values
_newLocal 8,X_i_1
_newLocal 4,oldZ #"old" Z values
_newLocal 1,_i_ #block number (+8)
_newLocal UNROLL_CNT ,exitTab#local jump table for exiting unrolled loop
_newLocal UNROLL_CNT+4,tmpBuf #local buffer encryption/decryption blocks
_newLocal 1,aadLeft ## bytes of aad remaining
_newLocal 1,msgLen0 #initial value of src_ByteCnt
_newLocal 1,dstPtr0 #initial dst pointer
_newLocal 1,retAddr #local "return" address
.set _cpOfs_,4+8*4+_Phelix_LocalSize #caller parms offset from esp
.set retAddr_LCL,retAddr-_cpOfs_
.set dstPtr0_LCL,dstPtr0-_cpOfs_
.set msgLen0_LCL,msgLen0-_cpOfs_
.set tmpBuf_LCL, tmpBuf-_cpOfs_
##
##----------------------------------------------------------------
## Define caller parameters on the stack, relative to esp
##
.set _pOfs_,_cpOfs_
_newParm 0,callerParms #placeholder, no space allocated
_newParm 1,ctxt_Ptr
_newParm 1,nonce_Ptr
_newParm 1,aad_Ptr
_newParm 1,aad_Len
_newParm 1,src_Ptr
_newParm 1,dst_Ptr
_newParm 1,src_ByteCnt
_newParm 1,mac_Ptr
##
##----------------------------------------------------------------
## Phelix context structure definition
.set _pOfs_,0
_newParm 1,keySize #size of raw key in bits
_newParm 1,macSize #size of mac tag in bits
_newParm 1,X_1_Bump #4*(keySize/8) + 256*(macSize mod 128)
_newParm 8,X_0 #subkeys
_newParm 8,X_1 #subkeys
## internal cipher state
_newParm 4,old_Z #previous Z[4] values for output
_newParm 5,_Z_ #5 internal state words
_newParm 1,blkNum #block number (i)
_newParm 2,aadLen #64-bit aadLen counter (LSW first)
_newParm 1,msgLen #32-bit msgLen counter (mod 2**32)
_newParm 1,aadXor #aad Xor constant
##
##----------------------------------------------------------------
##
.macro _o_ op1,op2,op3,cond3 #shorthand: instantiate 1-3 opcodes
\op1
\op2
\op3
\cond3
.endm
##----------------------------------------------------------------
## adjust _SO_ with push/pop operations
.macro _stackOp op,reg,bump
.ifnc \reg, #only do something if reg is not blank
\op %\reg
.set _SO_,_SO_+\bump
.endif
.endm
.macro _push r0,r1,r2,r3,r4,r5,r6
_stackOp push,\r0,4
_stackOp push,\r1,4
_stackOp push,\r2,4
_stackOp push,\r3,4
_stackOp push,\r4,4
_stackOp push,\r5,4
_stackOp push,\r6,4
.endm
##
.macro _pop r0,r1,r2,r3,r4,r5,r6
_stackOp pop,\r0,-4
_stackOp pop,\r1,-4
_stackOp pop,\r2,-4
_stackOp pop,\r3,-4
_stackOp pop,\r4,-4
_stackOp pop,\r5,-4
_stackOp pop,\r6,-4
.endm
##
##----------------------------------------------------------------
## Init code, jump tables (for lblName = Encrypt/Decrypt)
##----------------------------------------------------------------
##
.macro PhelixAlgo lblName
## first, set up the stack frame
pushal #save all regs on stack
strCat "lea ",\lblName,"_jmpTab,%ebp" #handle the encrypt/decrypt difference
jmp Phelix_Main #go run the algorithm
##
## the jump table for this operation
##
.align 4
strCat \lblName,"_jmpTab:"
##first, a list of "block boundary" targets within unrolled processing loop
.irp xxx,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
.if \xxx < UNROLL_CNT
strCat " .long \lblName","Blk_",\xxx
strCat " .global \lblName","Blk_",\xxx
.endif
.endr
## next, successive "control" targets within Phelix_Main
strCat ".set OddBytes_OFFS,","(.-\lblName","_jmpTab)"
strCat ".long \lblName","_OddBytes"
.endm #PhelixAlgo
##
##----------------------------------------------------------------
## Common unrolled loop end code for encrypt/decrypt
##----------------------------------------------------------------
##
.macro PhelixEndLoop CNT
addl $(\CNT)*4,srcPtr(%esp) #bump the pointers
addl $(\CNT)*4,dstPtr(%esp)
addl $(\CNT) ,_i_ (%esp) #bump the count
subl $(\CNT)*4,loopByteCnt(%esp) #are we done yet?
.endm #leave here with flags set for loop jmp
##
##----------------------------------------------------------------
## Common "early exit" code for encrypt/decrypt inner loop
##----------------------------------------------------------------
## This functionality is required for splicing AAD/text/padding
##
.macro PhelixEarlyExit jTabReg,_bn_
.if \_bn_ < (UNROLL_CNT-1) #do not need early exit at bottom of loop
testl %\jTabReg,%\jTabReg #time to exit?
_if nz
movl %esi,oldZ+4*((\_bn_) & 3)+_SO_(%esp)
jmp *%\jTabReg #go to "exit" address
_endif
.endif
movl %esi,oldZ+4*((\_bn_)& 3)+_SO_(%esp)
.endm
##
##****************************************************************
## start of actual code (i.e., end of macro definitions)
##****************************************************************
##
.align 4
INIT_ZEROES:
.rept ZERO_INIT_CNT
.long 0
.endr
MASK_TAB: .long 0,0xff,0xffff,0xffffff
_PhelixCodeStart_:
##
##----------------------------------------------------------------
## Common control path for Encrypt/Decrypt
##----------------------------------------------------------------
## In: ebp --> (const) jump table (Encrypt_jmpTab or Decrypt_jmpTab)
## Out: everything done
##
Phelix_Main:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -