📄 2fish_86.asm
字号:
shr ebx,16
mov edi,S32_2[SBS*edi]
xor esi,ecx
mov edx,S32_1[SBS*edx]
movzx ecx,ah
movzx eax,al
if (KEY_MODE and (KM_FULL or KM_COMPILE)) eq 0
doSbox keySize,cpuName,ecx,eax,3,2
endif
mov ecx,S32_3[SBS*ecx]
xor edi,edx
movzx edx,bh
mov eax,S32_2[SBS*eax]
movzx ebx,bl
xor esi,ecx
if (KEY_MODE and (KM_FULL or KM_COMPILE)) eq 0
doSbox keySize,cpuName,edx,ebx,0,3
endif
mov edx,S32_0[SBS*edx]
xor esi,eax
mov ebx,S32_3[SBS*ebx]
xor edi,edx
if (KEY_MODE and KM_COMPILE) eq 0
GetSubkey lbl,eax,S_INDEX
xor edi,ebx
GetSubkey lbl,ebx,S_INDEX+4
add esi,edi ;first half of the PHT
add edi,esi ;complete the PHT
add esi,eax ;add in the round subkeys
mov eax,z2 ;load z2,z3 to update them
add edi,ebx
mov ebx,z3
ifdif <lbl>,<Enc>
rol eax,1 ;Decryption: z2=ROL(z2,1)
xor ebx,edi ;complete the Feistel xor
ror ebx,1 ;Decryption: z3=ROR(z3,1)
xor eax,esi ;half of Feistel xor
else
xor eax,esi ;half of Feistel xor
rol ebx,1 ;Encryption: z3=ROL(z3,1)
ror eax,1 ;Encryption: z2=ROR(z2,1)
xor ebx,edi ;complete Feistel. eax,ebx=new z2,z3
endif
else ;---"Compiled" constants code here
ifdif <lbl>,<Enc> ;---do Decryption first
xor edi,ebx ;compute edi=final value of t1
mov eax,z2 ;eax=x[2]
mov ebx,z3
lea edx,[esi+2*edi+12345678h] ;no AGI!
concat Dec_SK_,%((S_INDEX+4)/4),<_>,cpuName,<:> ;label so we can "patch" code
rol eax,1 ;Decryption: z2=ROL(z2,1)
lea ecx,[esi+edi+12345678h+4]
concat Dec_SK_,%((S_INDEX+0)/4),<_>,cpuName,<:>
xor ebx,edx ;complete the Feistel xor
ror ebx,1 ;Decryption: z3=ROR(z3,1)
xor eax,ecx ;half of Feistel xor
else ;--- handle Encryption compilation here
xor edi,ebx
mov ebx,z3
mov eax,z2
lea ecx,[esi+edi+12345678h+4] ;no AGI!
concat Enc_SK_,%((S_INDEX+0)/4),<_>,cpuName,<:>
rol ebx,1 ;Encryption: z3=ROL(z3,1)
lea edx,[esi+2*edi+12345678h]
concat Enc_SK_,%((S_INDEX+4)/4),<_>,cpuName,<:>
xor eax,ecx ;half of Feistel xor
ror eax,1 ;Encryption: z2=ROR(z2,1)
xor ebx,edx ;complete Feistel. eax,ebx=new z2,z3
endif
endif
endif
endm
SetSboxK8 macro cpuName
ifidn <cpuName>,<PentiumPro> ;split SboxKey into bytes...
if KEY_MODE and KM_MIN ;and store as dwords
mov edx,ks.sboxKeys[0]
movzx eax,dl
movzx ebx,dh
mov sboxK8,eax
shr edx,16
movzx eax,dh
mov sboxK8+4,ebx
movzx edx,dl
mov sboxK8+12,eax
mov sboxK8+8,edx
endif
endif
endm
x0 equ <x[0]>
x1 equ <x[4]>
x2 equ <x[8]>
x3 equ <x[12]>
; do two rounds (subKeys are in reverse order)
Encrypt2Rounds macro roundNum,cpuName ;__TRANSPARENT__
RoundFunc ,Enc,cpuName,x0,x1,x2,x3,%(roundNum) ,%(ROUND_SUBKEYS+8*(MAX_ROUNDS-roundNum-1))
RoundFunc ,Enc,cpuName,x2,x3,x0,x1,%(roundNum+1),%(ROUND_SUBKEYS+8*(MAX_ROUNDS-roundNum-2))
endm
; do two rounds
Decrypt2Rounds macro roundNum,cpuName ;__TRANSPARENT__
RoundFunc ,Dec,cpuName,x2,x3,x0,x1,%(roundNum+1),%(ROUND_SUBKEYS+8*roundNum+8))
RoundFunc ,Dec,cpuName,x0,x1,x2,x3,%(roundNum) ,%(ROUND_SUBKEYS+8*roundNum))
endm
;
;----------------------------------------------------------------------------------
; Encryption
;----------------------------------------------------------------------------------
;
varOffs = 0
alloc x,dword,BLOCK_SIZE/8 ;local copy of text
if KEY_MODE and KM_MIN
alloc sboxK8,dword,4*4 ;for Pentium Pro MIN_KEY mode
endif
if KEY_MODE and KM_ZERO
alloc roundNum,dword,4 ;"soft" round number
alloc roundJmpPtr,dword,4 ;dispatch based on key size
endif
alloc IVptr,dword,4 ;ptr to CBC IV (NULL --> ECB)
localSize = varOffs
alloc regs,dword,8*4 ;pushad puts regs here
alloc retAddr,dword,4 ;esp --> here on entry
alloc cipherPtr,dword,4 ;pointer to cipher (includes mode)
alloc ksPtr,dword,4 ;pointer to initialized key schedule
alloc inputPtr,dword,4 ;pointer to plaintext to encrypt
alloc inputLen,dword,4 ;# bits to encrypt
alloc outBuffer,dword,4 ;where to put ciphertext
retVal equ regs[28]
cipherProc macro cpuName ;instantiate encrypt/decrypt functions
cipherProcStart_&cpuName:
TwoFishEncrypt_&cpuName proc
pushad ;save all regs
sub esp,localSize ;set up local stack frame
mov ebp,ksPtr
mov edx,cipherPtr
mov esi,inputPtr ;is the text "in-place"?
mov edi,outBuffer
mov ecx,inputLen
cmp esi,edi
mov retVal,ecx ;save length as return value
iff nz ;if not, make it so
shr ecx,5 ;convert from bits to dwords
ifdif <cpuName>,<PentiumPro>
mov eax,[edi] ;load some cache lines (for Pentium)
mov ebx,[edi+32]
endif
rep movsd ;put the text in place
endi
biasEBP ;point EBP to Sbox
mov al,[edx].mode ;figure out if we are in CBC mode
cmp al,MODE_CBC ;if so, make local copy of IV
iff z
lea edi,[edx+IV32] ;point edi directly to IV32
elsef
xor edi,edi ;NULL IVptr --> ECB mode
endi
SetSboxK8 cpuName
if KEY_MODE and KM_ZERO
mov eax,ks.keyLen
shr eax,6 ;divide by 64
mov eax,encJmpTab_&cpuName[4*eax-4]
mov roundJmpPtr,eax ;save dispatch address
endif
mov esi,outBuffer ;set up for loop
mov IVptr,edi ;save IV ptr
or edi,edi
iff nz
;read plaintext block to x, add input whitening and IV input
;edi == IVptr here
Enc_CBC_&cpuName:
Xor8 Enc_CBC,cpuName,x+8,[esi+8],INPUT_WHITEN+8,[edi+8]
Xor8 Enc_CBC,cpuName, ,[esi] ,INPUT_WHITEN ,[edi]
elsef
align 4
Enc_ECB_&cpuName:
;read plaintext block to x, add input whitening
Xor8 Enc,cpuName,x+8,[esi+8],INPUT_WHITEN+8
Xor8 Enc,cpuName, ,[esi] ,INPUT_WHITEN
endi
;whitening/IV merged in. Now we're ready to encrypt
;eax=x0, ebx=x1. (already loaded from INPUT_WHITEN xor)
ifdif <cpuName>,<PentiumPro>
xor ecx,ecx ;zero out high bits
if EDX_ADJUST
mov edx,EDX_ADJUST
else
xor edx,edx
endif
endif
if KEY_MODE and KM_ZERO
mov roundNum,14
jmp roundJmpPtr ;dispatch to appropriate handler
irp _kSize,<256,192,128>
concat <encLoop_>,%(_kSize),<_>,cpuName:
RoundFunc _kSize,Enc,cpuName,x0,x1,x2,x3,0,8
RoundFunc _kSize,Enc,cpuName,x2,x3,x0,x1,1,0
sub roundNum,2
concat <jae encLoop_>,%(_kSize),<_>,cpuName
if _kSize ne 128
jmp encDone_&cpuName
endif
endm
encDone_&cpuName:
else
Encrypt2Rounds 0,cpuName
Encrypt2Rounds 2,cpuName
Encrypt2Rounds 4,cpuName
Encrypt2Rounds 6,cpuName
Encrypt2Rounds 8,cpuName
Encrypt2Rounds 10,cpuName
Encrypt2Rounds 12,cpuName
Encrypt2Rounds 14,cpuName
endif
; here with eax=x0,ebx=x1, **unstored**.
; done with encryption. Add output whitening
mov edi,IVptr ;get ready to test CBC mode below
mov esi,outBuffer
Xor8 Enc,cpuName,[esi+8], ,OUTPUT_WHITEN+8
Xor8 Enc,cpuName,[esi] ,x+8,OUTPUT_WHITEN
add esi,BLOCK_SIZE/8
mov ecx,inputLen
mov outBuffer,esi ;save updated buffer ptr
sub ecx,BLOCK_SIZE ;are we done yet?
mov inputLen,ecx ;save updated length
or edi,edi ;are we in CBC mode?
iff z
or ecx,ecx
jg Enc_ECB_&cpuName ;we can only do 2Gbits per call!
elsef
Copy8 [edi] ;if so, save new IV for next time
Copy8 [edi+8],[esi-8] ;[esi-8] because we just added 16 to esi
or ecx,ecx
jg Enc_CBC_&cpuName
endi
; clean up stack and return
add esp,localSize
popad ;restore regs, including retVal to eax
ret
if KEY_MODE and KM_ZERO
encJmpTab_&cpuName label dword
dd encLoop_128_&cpuName,encLoop_128_&cpuName
dd encLoop_192_&cpuName,encLoop_256_&cpuName
endif
if KEY_MODE and KM_COMPILE ;make a subkey compilation "patch" list
PatchList_Enc_&cpuName label dword
QQ=0
rept 8
irp SKn,<%QQ>
concat < dd Enc_SK_>,%(QQ),<_>,cpuName,<-4>
endm
QQ=QQ+1
endm
QQ=0
rept TOTAL_SUBKEYS-8
irp SKn,<%QQ>
concat < dd Enc_SK_>,%((39-QQ) xor 1),<_>,cpuName,<-4>
endm
QQ=QQ+1
endm
endif
irp cby,<%($-TwoFishEncrypt_&cpuName)> ;display code size at assemble time
%out --- Encrypt assembly code size == cby bytes (cpuName)
endm
TwoFishEncrypt_&cpuName endp
;
;----------------------------------------------------------------------------------
; Decryption
;----------------------------------------------------------------------------------
;
; use same parameters and locals as blockEncrypt_86
TwoFishDecrypt_&cpuName proc
pushad ;save all regs
sub esp,localSize ;set up local stack frame
mov ebp,ksPtr
mov edx,cipherPtr
mov esi,inputPtr ;is the text "in-place"?
mov edi,outBuffer
mov ecx,inputLen
cmp esi,edi
mov retVal,ecx ;save length as return value
iff nz ;if not, make it so
shr ecx,5 ;convert from bits to dwords
ifdif <cpuName>,<PentiumPro>
mov eax,[edi] ;load some cache lines (for Pentium)
mov ebx,[edi+32]
endif
rep movsd ;put the text in place
endi
biasEBP ;point EBP to Sbox
mov al,[edx].mode ;figure out if we are in CBC mode
cmp al,MODE_CBC ;if so, make local copy of IV
iff z
add edx,IV32 ;point edx directly to IV32
elsef
xor edx,edx ;NULL --> in ECB mode
endi
mov esi,outBuffer
mov IVptr,edx
SetSboxK8 cpuName
if KEY_MODE and KM_ZERO
mov eax,ks.keyLen
shr eax,6 ;divide by 64
mov eax,decJmpTab_&cpuName[4*eax-4]
mov roundJmpPtr,eax ;save dispatch address
endif
; --- main Decryption block loop ---
decryptLoop_&cpuName:
Xor8 Dec,cpuName,x,[esi+8],OUTPUT_WHITEN+8
Xor8 Dec,cpuName, ,[esi] ,OUTPUT_WHITEN
ifdif <cpuName>,<PentiumPro>
xor ecx,ecx ;zero out high bits
if EDX_ADJUST
mov edx,EDX_ADJUST
else
xor edx,edx
endif
endif
if KEY_MODE and KM_ZERO
mov roundNum,14
jmp roundJmpPtr ;dispatch to appropriate handler
irp _kSize,<256,192,128>
concat decLoop_,%(_kSize),<_>,cpuName,<:>
RoundFunc _kSize,Dec,cpuName,x2,x3,x0,x1,0,8
RoundFunc _kSize,Dec,cpuName,x0,x1,x2,x3,1,0
sub roundNum,2
concat <jae decLoop_>,%(_kSize),<_>,cpuName
if _kSize ne 128
jmp decDone_&cpuName
endif
endm
decDone_&cpuName:
else
Decrypt2Rounds 14,cpuName ;do rounds in reverse order
Decrypt2Rounds 12,cpuName
Decrypt2Rounds 10,cpuName
Decrypt2Rounds 8,cpuName
Decrypt2Rounds 6,cpuName
Decrypt2Rounds 4,cpuName
Decrypt2Rounds 2,cpuName
Decrypt2Rounds 0,cpuName
endif
mov edi,IVptr
mov esi,outBuffer ;remove input whitening, store plaintext
or edi,edi ;are we in CBC mode?
iff nz
Xor8 Dec_CBC,cpuName,[esi+8], ,INPUT_WHITEN+8,[edi+8],[edi+8]
Xor8 Dec_CBC,cpuName,[esi] ,x ,INPUT_WHITEN ,[edi] ,[edi]
elsef
Xor8 Dec,cpuName,[esi+8], ,INPUT_WHITEN+8
Xor8 Dec,cpuName,[esi] ,x ,INPUT_WHITEN
endi
add esi,BLOCK_SIZE/8
mov edi,inputLen
mov outBuffer,esi
sub edi,BLOCK_SIZE
mov inputLen,edi ;save updated length
ja decryptLoop_&cpuName ;are we done? if not, go back for more
; clean up stack and return
add esp,localSize
popad ;restore regs, including retVal to eax
ret
if KEY_MODE and KM_ZERO
decJmpTab_&cpuName label dword
dd decLoop_128_&cpuName,decLoop_128_&cpuName
dd decLoop_192_&cpuName,decLoop_256_&cpuName
endif
irp cby,<%($-TwoFishDecrypt_&cpuName)> ;display code size at assemble time
%out --- Decrypt assembly code size == cby bytes (cpuName)
endm
cipherProcEnd_&cpuName label byte
if KEY_MODE and KM_COMPILE ;make a subkey compilation "patch" list
PatchList_Dec_&cpuName label dword
QQ=0
rept TOTAL_SUBKEYS
irp SKn,<%QQ>
concat < dd Dec_SK_>,%(QQ),<_>,cpuName,<-4>
endm
QQ=QQ+1
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -