155714Skris#!/usr/local/bin/perl 255714Skris 355714Skrispush(@INC,"perlasm","../../perlasm"); 455714Skrisrequire "x86asm.pl"; 555714Skrisrequire "cbc.pl"; 655714Skris 755714Skris&asm_init($ARGV[0],"bf-686.pl"); 855714Skris 955714Skris$BF_ROUNDS=16; 1055714Skris$BF_OFF=($BF_ROUNDS+2)*4; 1155714Skris$L="ecx"; 1255714Skris$R="edx"; 1355714Skris$P="edi"; 1455714Skris$tot="esi"; 1555714Skris$tmp1="eax"; 1655714Skris$tmp2="ebx"; 1755714Skris$tmp3="ebp"; 1855714Skris 1955714Skris&des_encrypt("BF_encrypt",1); 2055714Skris&des_encrypt("BF_decrypt",0); 2155714Skris&cbc("BF_cbc_encrypt","BF_encrypt","BF_decrypt",1,4,5,3,-1,-1); 2255714Skris 2355714Skris&asm_finish(); 2455714Skris 2555714Skris&file_end(); 2655714Skris 2755714Skrissub des_encrypt 2855714Skris { 2955714Skris local($name,$enc)=@_; 3055714Skris 3155714Skris &function_begin($name,""); 3255714Skris 3355714Skris &comment(""); 3455714Skris &comment("Load the 2 words"); 3555714Skris &mov("eax",&wparam(0)); 3655714Skris &mov($L,&DWP(0,"eax","",0)); 3755714Skris &mov($R,&DWP(4,"eax","",0)); 3855714Skris 3955714Skris &comment(""); 4055714Skris &comment("P pointer, s and enc flag"); 4155714Skris &mov($P,&wparam(1)); 4255714Skris 4355714Skris &xor( $tmp1, $tmp1); 4455714Skris &xor( $tmp2, $tmp2); 4555714Skris 4655714Skris # encrypting part 4755714Skris 4855714Skris if ($enc) 4955714Skris { 5055714Skris &xor($L,&DWP(0,$P,"",0)); 5155714Skris for ($i=0; $i<$BF_ROUNDS; $i+=2) 5255714Skris { 5355714Skris &comment(""); 5455714Skris &comment("Round $i"); 5555714Skris &BF_ENCRYPT($i+1,$R,$L,$P,$tot,$tmp1,$tmp2,$tmp3); 5655714Skris 5755714Skris &comment(""); 5855714Skris &comment("Round ".sprintf("%d",$i+1)); 5955714Skris &BF_ENCRYPT($i+2,$L,$R,$P,$tot,$tmp1,$tmp2,$tmp3); 6055714Skris } 6155714Skris &xor($R,&DWP(($BF_ROUNDS+1)*4,$P,"",0)); 6255714Skris 6355714Skris &mov("eax",&wparam(0)); 6455714Skris &mov(&DWP(0,"eax","",0),$R); 6555714Skris &mov(&DWP(4,"eax","",0),$L); 6655714Skris &function_end_A($name); 6755714Skris } 6855714Skris else 6955714Skris { 7055714Skris &xor($L,&DWP(($BF_ROUNDS+1)*4,$P,"",0)); 7155714Skris for ($i=$BF_ROUNDS; $i>0; $i-=2) 7255714Skris { 7355714Skris &comment(""); 7455714Skris &comment("Round $i"); 7555714Skris &BF_ENCRYPT($i,$R,$L,$P,$tot,$tmp1,$tmp2,$tmp3); 7655714Skris &comment(""); 7755714Skris &comment("Round ".sprintf("%d",$i-1)); 7855714Skris &BF_ENCRYPT($i-1,$L,$R,$P,$tot,$tmp1,$tmp2,$tmp3); 7955714Skris } 8055714Skris &xor($R,&DWP(0,$P,"",0)); 8155714Skris 8255714Skris &mov("eax",&wparam(0)); 8355714Skris &mov(&DWP(0,"eax","",0),$R); 8455714Skris &mov(&DWP(4,"eax","",0),$L); 8555714Skris &function_end_A($name); 8655714Skris } 8755714Skris 8855714Skris &function_end_B($name); 8955714Skris } 9055714Skris 9155714Skrissub BF_ENCRYPT 9255714Skris { 9355714Skris local($i,$L,$R,$P,$tot,$tmp1,$tmp2,$tmp3)=@_; 9455714Skris 9555714Skris &rotr( $R, 16); 9655714Skris &mov( $tot, &DWP(&n2a($i*4),$P,"",0)); 9755714Skris 9855714Skris &movb( &LB($tmp1), &HB($R)); 9955714Skris &movb( &LB($tmp2), &LB($R)); 10055714Skris 10155714Skris &rotr( $R, 16); 10255714Skris &xor( $L, $tot); 10355714Skris 10455714Skris &mov( $tot, &DWP(&n2a($BF_OFF+0x0000),$P,$tmp1,4)); 10555714Skris &mov( $tmp3, &DWP(&n2a($BF_OFF+0x0400),$P,$tmp2,4)); 10655714Skris 10755714Skris &movb( &LB($tmp1), &HB($R)); 10855714Skris &movb( &LB($tmp2), &LB($R)); 10955714Skris 11055714Skris &add( $tot, $tmp3); 11155714Skris &mov( $tmp1, &DWP(&n2a($BF_OFF+0x0800),$P,$tmp1,4)); # delay 11255714Skris 11355714Skris &xor( $tot, $tmp1); 11455714Skris &mov( $tmp3, &DWP(&n2a($BF_OFF+0x0C00),$P,$tmp2,4)); 11555714Skris 11655714Skris &add( $tot, $tmp3); 11755714Skris &xor( $tmp1, $tmp1); 11855714Skris 11955714Skris &xor( $L, $tot); 12055714Skris # delay 12155714Skris } 12255714Skris 12355714Skrissub n2a 12455714Skris { 12555714Skris sprintf("%d",$_[0]); 12655714Skris } 12755714Skris 128