Alexandre Savard | 1b09e31 | 2012-08-07 20:33:29 -0400 | [diff] [blame] | 1 | #!/usr/local/bin/perl |
| 2 | |
| 3 | $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; |
| 4 | push(@INC,"${dir}","${dir}../../perlasm"); |
| 5 | require "x86asm.pl"; |
| 6 | require "cbc.pl"; |
| 7 | |
| 8 | &asm_init($ARGV[0],"bf-586.pl",$ARGV[$#ARGV] eq "386"); |
| 9 | |
| 10 | $BF_ROUNDS=16; |
| 11 | $BF_OFF=($BF_ROUNDS+2)*4; |
| 12 | $L="edi"; |
| 13 | $R="esi"; |
| 14 | $P="ebp"; |
| 15 | $tmp1="eax"; |
| 16 | $tmp2="ebx"; |
| 17 | $tmp3="ecx"; |
| 18 | $tmp4="edx"; |
| 19 | |
| 20 | &BF_encrypt("BF_encrypt",1); |
| 21 | &BF_encrypt("BF_decrypt",0); |
| 22 | &cbc("BF_cbc_encrypt","BF_encrypt","BF_decrypt",1,4,5,3,-1,-1); |
| 23 | &asm_finish(); |
| 24 | |
| 25 | sub BF_encrypt |
| 26 | { |
| 27 | local($name,$enc)=@_; |
| 28 | |
| 29 | &function_begin_B($name,""); |
| 30 | |
| 31 | &comment(""); |
| 32 | |
| 33 | &push("ebp"); |
| 34 | &push("ebx"); |
| 35 | &mov($tmp2,&wparam(0)); |
| 36 | &mov($P,&wparam(1)); |
| 37 | &push("esi"); |
| 38 | &push("edi"); |
| 39 | |
| 40 | &comment("Load the 2 words"); |
| 41 | &mov($L,&DWP(0,$tmp2,"",0)); |
| 42 | &mov($R,&DWP(4,$tmp2,"",0)); |
| 43 | |
| 44 | &xor( $tmp1, $tmp1); |
| 45 | |
| 46 | # encrypting part |
| 47 | |
| 48 | if ($enc) |
| 49 | { |
| 50 | &mov($tmp2,&DWP(0,$P,"",0)); |
| 51 | &xor( $tmp3, $tmp3); |
| 52 | |
| 53 | &xor($L,$tmp2); |
| 54 | for ($i=0; $i<$BF_ROUNDS; $i+=2) |
| 55 | { |
| 56 | &comment(""); |
| 57 | &comment("Round $i"); |
| 58 | &BF_ENCRYPT($i+1,$R,$L,$P,$tmp1,$tmp2,$tmp3,$tmp4,1); |
| 59 | |
| 60 | &comment(""); |
| 61 | &comment("Round ".sprintf("%d",$i+1)); |
| 62 | &BF_ENCRYPT($i+2,$L,$R,$P,$tmp1,$tmp2,$tmp3,$tmp4,1); |
| 63 | } |
| 64 | # &mov($tmp1,&wparam(0)); In last loop |
| 65 | &mov($tmp4,&DWP(($BF_ROUNDS+1)*4,$P,"",0)); |
| 66 | } |
| 67 | else |
| 68 | { |
| 69 | &mov($tmp2,&DWP(($BF_ROUNDS+1)*4,$P,"",0)); |
| 70 | &xor( $tmp3, $tmp3); |
| 71 | |
| 72 | &xor($L,$tmp2); |
| 73 | for ($i=$BF_ROUNDS; $i>0; $i-=2) |
| 74 | { |
| 75 | &comment(""); |
| 76 | &comment("Round $i"); |
| 77 | &BF_ENCRYPT($i,$R,$L,$P,$tmp1,$tmp2,$tmp3,$tmp4,0); |
| 78 | &comment(""); |
| 79 | &comment("Round ".sprintf("%d",$i-1)); |
| 80 | &BF_ENCRYPT($i-1,$L,$R,$P,$tmp1,$tmp2,$tmp3,$tmp4,0); |
| 81 | } |
| 82 | # &mov($tmp1,&wparam(0)); In last loop |
| 83 | &mov($tmp4,&DWP(0,$P,"",0)); |
| 84 | } |
| 85 | |
| 86 | &xor($R,$tmp4); |
| 87 | &mov(&DWP(4,$tmp1,"",0),$L); |
| 88 | |
| 89 | &mov(&DWP(0,$tmp1,"",0),$R); |
| 90 | &function_end($name); |
| 91 | } |
| 92 | |
| 93 | sub BF_ENCRYPT |
| 94 | { |
| 95 | local($i,$L,$R,$P,$tmp1,$tmp2,$tmp3,$tmp4,$enc)=@_; |
| 96 | |
| 97 | &mov( $tmp4, &DWP(&n2a($i*4),$P,"",0)); # for next round |
| 98 | |
| 99 | &mov( $tmp2, $R); |
| 100 | &xor( $L, $tmp4); |
| 101 | |
| 102 | &shr( $tmp2, 16); |
| 103 | &mov( $tmp4, $R); |
| 104 | |
| 105 | &movb( &LB($tmp1), &HB($tmp2)); # A |
| 106 | &and( $tmp2, 0xff); # B |
| 107 | |
| 108 | &movb( &LB($tmp3), &HB($tmp4)); # C |
| 109 | &and( $tmp4, 0xff); # D |
| 110 | |
| 111 | &mov( $tmp1, &DWP(&n2a($BF_OFF+0x0000),$P,$tmp1,4)); |
| 112 | &mov( $tmp2, &DWP(&n2a($BF_OFF+0x0400),$P,$tmp2,4)); |
| 113 | |
| 114 | &add( $tmp2, $tmp1); |
| 115 | &mov( $tmp1, &DWP(&n2a($BF_OFF+0x0800),$P,$tmp3,4)); |
| 116 | |
| 117 | &xor( $tmp2, $tmp1); |
| 118 | &mov( $tmp4, &DWP(&n2a($BF_OFF+0x0C00),$P,$tmp4,4)); |
| 119 | |
| 120 | &add( $tmp2, $tmp4); |
| 121 | if (($enc && ($i != 16)) || ((!$enc) && ($i != 1))) |
| 122 | { &xor( $tmp1, $tmp1); } |
| 123 | else |
| 124 | { |
| 125 | &comment("Load parameter 0 ($i) enc=$enc"); |
| 126 | &mov($tmp1,&wparam(0)); |
| 127 | } # In last loop |
| 128 | |
| 129 | &xor( $L, $tmp2); |
| 130 | # delay |
| 131 | } |
| 132 | |
| 133 | sub n2a |
| 134 | { |
| 135 | sprintf("%d",$_[0]); |
| 136 | } |
| 137 | |