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

📄 phelix86.asm

📁 phelix加密算法源代码,是一个开源的加密算法
💻 ASM
📖 第 1 页 / 共 3 页
字号:
;
;----------------------------------------------------------------
; Phelix encryption/authentication algorithm
; Author: Doug Whiting, Hifn. 2005.
;
; This source code is released to the public domain
;----------------------------------------------------------------
;
		.386
		.model	flat,c				;C naming convention (underscore prefix)
		.code
		
		include	strucmac.inc		;structured programming macros (_if/_else/_endif, etc)

		page	,128				;format things nicely in listing
;
PHELIX_INCREMENTAL_API	equ		1	;undef this to exclude incremental calls
;
;
; define a global label. Handle linking with and without underscore
C_global	macro	phelixName,ecryptName
  ifdef MIX_ASM
    public	 phelixName&_ASM
    public _&phelixName&_ASM
  phelixName&_ASM:
_&phelixName&_ASM:
  else
	public   phelixName
	public _&phelixName
	ifdef ECRYPT_API
	ifnb <ecryptName>
	  public   ecryptName
	  public _&ecryptName
	  ecryptName:
	_&ecryptName:
	endif
	endif
  endif
  phelixName:
_&phelixName:
endm
;
;
C_global _debugPhelix_				;ignored here, but must be defined for testPhelix.c
			dd		0

  ifdef ??version					;Borland TASM32 pre-defined constant
%tabsize	4						;format things pretty
AsmName		db		"TASM32 v"
			db		'0'+(??version/256),'.'
			db		'0'+(??version AND 0ffh)/16,'0'+(??version AND 0fh),0
  else
AsmName		db		"MASM v"
			db		'0'+((@version/100) mod 10),'.'
			db		'0'+((@version/10 ) mod 10),'0'+(@version mod 10),0
  endif
;
	align 4
C_global PhelixCompiler_Name			;show who assembled us
		lea		eax,AsmName
		ret
;
C_global PhelixInit,ECRYPT_init
		ret
;
;----------------------------------------------------------------
; Macros and definitions
;----------------------------------------------------------------
;
; Phelix rotation constants
ROT_0a			equ		 9
ROT_1a			equ		10
ROT_2a			equ		17
ROT_3a			equ		30
ROT_4a			equ		13
;
ROT_0b			equ		20
ROT_1b			equ		11
ROT_2b			equ		 5
ROT_3b			equ		15
ROT_4b			equ		25
;
Z0				equ		eax				;register assignments
Z1				equ		ebx
Z2				equ		ecx
Z3				equ		edx
Z4				equ		esi
t0				equ		ebp				;"temp" scratch registers
t1				equ		edi
oldZreg			equ		Z4
;
UNROLL_CNT		equ		 8				;how many blocks to unroll in inner loop
ZERO_INIT_CNT	equ		 8				;number of words of init
MAGIC_MAC_XOR	equ		912d94f1h		;special constants
MAGIC_AAD_XOR	equ	   0aadaadaah
;
;
;----------------------------------------------------------------
; pseudo-instruction (assemble-time)
;----------------------------------------------------------------
;
_ASM_Assert macro	cnd,msg
	if (cnd)
		;; all is well -- no error
	else
	  ifb <msg>
		.err "ASSERTION FAILURE:  cnd"
	  else
		.err "ASSERTION FAILURE:  msg"
	  endif
	endif
endm
;
_ASM_Assert	<UNROLL_CNT eq (UNROLL_CNT and not (UNROLL_CNT-1))>,<Unroll count must be a power of 2>
;
;----------------------------------------------------------------
;
; 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 can't use the assembler stack frame primitives.]
;
_maxPhelixStack_ =  0					;max locals usage in bytes
_stack_offs		 =	0					;current stack offset due to calls
_Phelix_LocalSize= 	0					;starting value: no locals allocated yet
;
_newLocal macro	wCnt,lName				;macro to define a local variable
		irp		_offs_,<%_Phelix_LocalSize>
lName	  equ	<dword ptr [esp + _offs_ + _stack_offs]>
lName&_Z4 equ	<dword ptr [Z4  + _offs_ - _cpOfs_    ]>
		endm
_Phelix_LocalSize = _Phelix_LocalSize + 4*(wCnt)
  ; keep running tabs on stack usage for locals
  if _maxPhelixStack_ lt _Phelix_LocalSize
	 _maxPhelixStack_  = _Phelix_LocalSize
  endif
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
;
;----------------------------------------------------------------
; Define caller's parameters on the stack, relative to esp
;
_cpOfs_	=		4+8*4+_Phelix_LocalSize	;caller parms offset from esp
_pOfs_	=		_cpOfs_
;
_newParm macro	_pp_
		irp		_offs_,<%_pOfs_>
_pp_	  equ	<dword ptr [esp + _offs_ + _stack_offs]>
_pp_&_Z4  equ	<dword ptr [Z4  + _offs_ - _cpOfs_]>	;allow "short ofset" access via Z4
		endm
_pOfs_	  =		_pOfs_+4
endm
;
		irp		 _pp_,<ctxt_Ptr,nonce_Ptr,aad_Ptr,aad_Len,src_Ptr,dst_Ptr,src_ByteCnt,mac_Ptr>
		_newParm _pp_
		endm
;
callerParms	equ	<ctxt_Ptr>
;----------------------------------------------------------------
; Phelix context structure definition
pCtxt	STRUCT
  keySize	dd		?			;size of raw key in bits
  macSize	dd		?			;size of mac tag in bits
  X_1_Bump	dd		?			;4*(keySize/8) + 256*(macSize mod 128)
  X_0		dd		8 dup (?)	;subkeys
  X_1		dd		8 dup (?)	;subkeys
	; internal cipher state
  old_Z		dd		4 dup (?)	;previous Z[4] values for output
  _Z_		dd		5 dup (?)	;5 internal state words
  blkNum	dd		?			;block number (i)
  aadLen	dd		2 dup (?)	;64-bit aadLen counter (LSW first)
  msgLen	dd		?			;32-bit msgLen counter (mod 2**32)
  aadXor	dd		?			;aad Xor constant
pCtxt	ENDS
;
;----------------------------------------------------------------
;
_o_		macro	op1,op2,op3,cond3		;shorthand: instantiate 1-3 opcodes
		op1
		op2
	ifb <cond3>
		op3
	elseif cond3
		op3
	endif
endm
;----------------------------------------------------------------
; adjust _stack_offs with push/pop operations
_push	macro	r0,r1,r2,r3,r4,r5,r6
	irp	_reg_,<r0,r1,r2,r3,r4,r5,r6>
	  ifnb <_reg_>
		push	_reg_
		_stack_offs	=	_stack_offs + 4
	  endif
	endm
endm
;
_pop	macro	r0,r1,r2,r3,r4,r5,r6
	irp	_reg_,<r0,r1,r2,r3,r4,r5,r6>
	  ifnb <_reg_>
		pop		_reg_
		_stack_offs	=	_stack_offs - 4
	  endif
	endm
endm
;
;----------------------------------------------------------------
; concatenate text together (useful in building names inside macros)
Concat	macro	aa,bb,cc,dd,ee,ff,gg,hh
aa&bb&cc&dd&ee&ff&gg&hh
endm
;
;----------------------------------------------------------------
; Init code, jump tables (for lblName = Encrypt/Decrypt)
;----------------------------------------------------------------
;
PhelixAlgo macro lblName
		; first, set up the stack frame
		pushad							;save all regs on stack
		lea		t0,lblName&_jmpTab		;handle the encrypt/decrypt difference
		jmp		Phelix_Main				;go run the algorithm
		;
		; the jump table for this operation
		;
		align	4
lblName&_jmpTab label dword
		;first, a list of "block boundary" targets within unrolled processing loop
	_blkNum_ = 0
	rept	UNROLL_CNT	
		Concat	<dd  offset &lblName&Blk_>,%_blkNum_
	_blkNum_ = _blkNum_ + 1
	endm
		; next, successive "control" targets within Phelix_Main
		irp		_targetName_,<OddBytes>
		Concat	&_targetName_,<_OFFS = >,<($-lblName&_jmpTab)>
		Concat	<dd	 offset &lblName>,<_>,&_targetName_
		endm

endm	;PhelixAlso
;
;----------------------------------------------------------------
; Common unrolled loop end code for encrypt/decrypt
;----------------------------------------------------------------
;
PhelixEndLoop macro	CNT
		add		srcPtr	   ,(CNT)*4		;bump the pointers
		add		dstPtr	   ,(CNT)*4
		add		_i_		   ,(CNT)		;bump the count
		sub		loopByteCnt,(CNT)*4		;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
;
PhelixEarlyExit macro	jTabReg,_bn_
	if _bn_ lt (UNROLL_CNT-1)			;don't need early exit at bottom of loop
		test jTabReg,jTabReg			;time to exit?
		_if  nz
		  mov oldZ[4*(_bn_ and 3)],oldZreg
		  jmp jTabReg					;go to "exit" address
		  ;align 4						;aligning -- doesn't seem to help!
		_endif
	endif
	mov oldZ[4*(_bn_ and 3)],oldZreg
endm
;
;****************************************************************
; start of actual code (i.e., end of macro definitions)
;****************************************************************
;
		align	4
INIT_ZEROES	dd		ZERO_INIT_CNT dup (0)
MASK_TAB	dd		0,0ffh,0ffffh,0ffffffh

_PhelixCodeStart_:

;
;----------------------------------------------------------------
; Common control path for Encrypt/Decrypt
;----------------------------------------------------------------
; In:	t0 --> (const) jump table (Encrypt_jmpTab or Decrypt_jmpTab)
; Out:	everything done
;
Phelix_Main:
_stack_offs		 = -_Phelix_LocalSize	;stack frame not built yet
		lea		Z4,callerParms			;point to callers first parameter (save code size below)
		sub		esp,_Phelix_LocalSize	;make room for locals on stack
_stack_offs		 =	0					;now at the "base" esp value
		mov		jmpTabPtr,t0			;save jump table pointer
		call	InitNonce
		;
		;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
		; Finally ready to start running Phelix on some data
		;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
		; First, process the initialization zeroes (loopByteCnt == 0 from PhelixInit)
		;
		_ASM_Assert <UNROLL_CNT ge ZERO_INIT_CNT>
		mov		exitTab[4*(ZERO_INIT_CNT-1)],offset _ret_InitZeroDone
		jmp		EncryptBlk_0
		;
		; "local" function
_stack_offs		=	4
InitNonce:
		; first, init the local keys on the stack
		mov		t0,ctxt_Ptr_Z4			;point to context structure
		mov		t1,[t0].pCtxt.X_1_Bump	;t1=4*(keySize/8)+256*(macSize mod 128)
		mov		Z3,nonce_Ptr_Z4			;(const) pointer to nonce words
		_push	Z4						;save Z4  (push/pop = smaller than lea Z4,callerParms)
		xor		Z4,Z4					;use Z4 as the variable i in SetTwoKeys
		inc		Z4						;start with i = 1, since t1 = X'_1 = 4*L(U) already
		call	SetTwoKeys				;set X_1_n, X_5_n, for n=0,1  [return w/t1 == 0]
		call	SetTwoKeys				;set X_2_n, X_6_n, for n=0,1
		call	SetTwoKeys				;set X_3_n, X_7_n, for n=0,1
		xor		Z4,Z4					;wrap to i = 0
		call	SetTwoKeys				;set X_0_n, X_4_n, for n=0,1
		_pop	Z4						;restore pointer to callerParms

		;set up for initialization phase
		xor		Z2,Z2	
		lea		t0,INIT_ZEROES			;use all zero input words, for i= -8 .. -1
		lea		t1,tmpBuf				;discard output
		mov		loopByteCnt,Z2			;initialize loop byte count counter = 0
		mov		_i_,Z2					;initialize i = 0 (block number + 8)
		mov		srcPtr,t0
		mov		dstPtr,t1

		; now initialize the Zn register values
		mov		t0,ctxt_Ptr_Z4
		mov		t1,nonce_Ptr_Z4
		irp		zNum,<0,1,2,3,4>
		  mov	Z&zNum,[t0+4*(3+zNum)].pCtxt.X_0
		endm
		irp		zNum,<0,1,2,3>
		  xor	Z&zNum,[t1+4*zNum]
		endm
		ret
_stack_offs		=	0
		;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
		; done with the initial zeroes.
_ret_InitZeroDone:
	if UNROLL_CNT gt ZERO_INIT_CNT		;do we need to clear out the return point?
		xor		t0,t0					;(only if it's not already at the end)
		mov		exitTab[4*(ZERO_INIT_CNT-1)],t0
	endif
		;;;;;;;;;;;;;;;;;
		; handle AAD here, looping if needed
		xor		Z1,MAGIC_AAD_XOR
		mov		t0,aad_Len
		test	t0,t0
	_if nz,far							;if nothing there, skip all aad processing
		mov		t1,aad_Ptr
		mov		aadLeft,t0
		mov		srcPtr,t1				;src will come from aad_Ptr
_aad_Loop:								;here with t0 == aad_Len
		lea		t1,tmpBuf				;always use tmpBuf for aad dst (discard)
		mov		dstPtr,t1
		mov		t0,aadLeft
		sub		t0,4*UNROLL_CNT			;only do one unrolled loop each time
		_if ae							;(since we use tmpBuf to discard ciphertext)
		  mov	aadLeft,t0
		  xor	t1,t1
		  mov	loopByteCnt,t1
		  mov	exitTab[4*(UNROLL_CNT-1)],offset _aad_Loop
		  jmp	EncryptBlk_0
		_endif
		; here to handle final partial loop
_aad_PartialLoop:
		and		t0,4*(UNROLL_CNT-1)
		mov		loopByteCnt,t0
		cmp		t0,4
		_if ae
		  mov		exitTab[t0-4],offset _ret_aad_1
		  jmp		EncryptBlk_0
		_ret_aad_1:
		  mov		t0,loopByteCnt
		  xor		t1,t1
		  mov		exitTab[t0-4],t1		;clear the entry
		_endif
		; here to handle final partial word of AAD
		mov		t0,aadLeft
		mov		t1,t0
		and		t1,3					;any odd bytes?
		_ifbrk	z						;if not, we're done with AAD
		add		t0,4
		and		t0,4*(UNROLL_CNT-1)
		mov		loopByteCnt,t0
		_push	Z4
		sub		t0,4
		and		t0,4*(UNROLL_CNT-1)
		mov		Z4,srcPtr
		mov		Z4,[Z4+t0]				;get the last AAD word

⌨️ 快捷键说明

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