1132718Skan#!/usr/local/bin/perl 2169689Skan 3132718Skanpush(@INC,"perlasm","../../perlasm"); 4132718Skanrequire "x86asm.pl"; 5132718Skanrequire "cbc.pl"; 6132718Skan 7132718Skan&asm_init($ARGV[0],"bf-686.pl"); 8132718Skan 9132718Skan$BF_ROUNDS=16; 10132718Skan$BF_OFF=($BF_ROUNDS+2)*4; 11132718Skan$L="ecx"; 12132718Skan$R="edx"; 13132718Skan$P="edi"; 14132718Skan$tot="esi"; 15132718Skan$tmp1="eax"; 16132718Skan$tmp2="ebx"; 17132718Skan$tmp3="ebp"; 18132718Skan 19132718Skan&des_encrypt("BF_encrypt",1); 20132718Skan&des_encrypt("BF_decrypt",0); 21169689Skan&cbc("BF_cbc_encrypt","BF_encrypt","BF_decrypt",1,4,5,3,-1,-1); 22169689Skan 23132718Skan&asm_finish(); 24132718Skan 25132718Skan&file_end(); 26132718Skan 27132718Skansub des_encrypt 28169689Skan { 29169689Skan local($name,$enc)=@_; 30132718Skan 31132718Skan &function_begin($name,""); 32132718Skan 33132718Skan &comment(""); 34132718Skan &comment("Load the 2 words"); 35169689Skan &mov("eax",&wparam(0)); 36132718Skan &mov($L,&DWP(0,"eax","",0)); 37132718Skan &mov($R,&DWP(4,"eax","",0)); 38132718Skan 39132718Skan &comment(""); 40132718Skan &comment("P pointer, s and enc flag"); 41132718Skan &mov($P,&wparam(1)); 42132718Skan 43132718Skan &xor( $tmp1, $tmp1); 44132718Skan &xor( $tmp2, $tmp2); 45132718Skan 46132718Skan # encrypting part 47132718Skan 48132718Skan if ($enc) 49132718Skan { 50132718Skan &xor($L,&DWP(0,$P,"",0)); 51132718Skan for ($i=0; $i<$BF_ROUNDS; $i+=2) 52132718Skan { 53169689Skan &comment(""); 54132718Skan &comment("Round $i"); 55169689Skan &BF_ENCRYPT($i+1,$R,$L,$P,$tot,$tmp1,$tmp2,$tmp3); 56169689Skan 57132718Skan &comment(""); 58169689Skan &comment("Round ".sprintf("%d",$i+1)); 59169689Skan &BF_ENCRYPT($i+2,$L,$R,$P,$tot,$tmp1,$tmp2,$tmp3); 60132718Skan } 61169689Skan &xor($R,&DWP(($BF_ROUNDS+1)*4,$P,"",0)); 62169689Skan 63169689Skan &mov("eax",&wparam(0)); 64169689Skan &mov(&DWP(0,"eax","",0),$R); 65169689Skan &mov(&DWP(4,"eax","",0),$L); 66169689Skan &function_end_A($name); 67132718Skan } 68132718Skan else 69132718Skan { 70132718Skan &xor($L,&DWP(($BF_ROUNDS+1)*4,$P,"",0)); 71132718Skan for ($i=$BF_ROUNDS; $i>0; $i-=2) 72132718Skan { 73132718Skan &comment(""); 74132718Skan &comment("Round $i"); 75132718Skan &BF_ENCRYPT($i,$R,$L,$P,$tot,$tmp1,$tmp2,$tmp3); 76132718Skan &comment(""); 77132718Skan &comment("Round ".sprintf("%d",$i-1)); 78132718Skan &BF_ENCRYPT($i-1,$L,$R,$P,$tot,$tmp1,$tmp2,$tmp3); 79169689Skan } 80169689Skan &xor($R,&DWP(0,$P,"",0)); 81169689Skan 82132718Skan &mov("eax",&wparam(0)); 83132718Skan &mov(&DWP(0,"eax","",0),$R); 84169689Skan &mov(&DWP(4,"eax","",0),$L); 85132718Skan &function_end_A($name); 86169689Skan } 87132718Skan 88169689Skan &function_end_B($name); 89169689Skan } 90132718Skan 91169689Skansub BF_ENCRYPT 92169689Skan { 93169689Skan local($i,$L,$R,$P,$tot,$tmp1,$tmp2,$tmp3)=@_; 94132718Skan 95132718Skan &rotr( $R, 16); 96132718Skan &mov( $tot, &DWP(&n2a($i*4),$P,"",0)); 97132718Skan 98169689Skan &movb( &LB($tmp1), &HB($R)); 99169689Skan &movb( &LB($tmp2), &LB($R)); 100169689Skan 101146895Skan &rotr( $R, 16); 102169689Skan &xor( $L, $tot); 103169689Skan 104169689Skan &mov( $tot, &DWP(&n2a($BF_OFF+0x0000),$P,$tmp1,4)); 105169689Skan &mov( $tmp3, &DWP(&n2a($BF_OFF+0x0400),$P,$tmp2,4)); 106169689Skan 107132718Skan &movb( &LB($tmp1), &HB($R)); 108132718Skan &movb( &LB($tmp2), &LB($R)); 109132718Skan 110132718Skan &add( $tot, $tmp3); 111169689Skan &mov( $tmp1, &DWP(&n2a($BF_OFF+0x0800),$P,$tmp1,4)); # delay 112169689Skan 113169689Skan &xor( $tot, $tmp1); 114169689Skan &mov( $tmp3, &DWP(&n2a($BF_OFF+0x0C00),$P,$tmp2,4)); 115169689Skan 116169689Skan &add( $tot, $tmp3); 117132718Skan &xor( $tmp1, $tmp1); 118132718Skan 119132718Skan &xor( $L, $tot); 120169689Skan # delay 121169689Skan } 122169689Skan 123169689Skansub n2a 124132718Skan { 125169689Skan sprintf("%d",$_[0]); 126169689Skan } 127169689Skan 128169689Skan