1#!/usr/local/bin/perl 2 3# define for pentium pro friendly version 4$ppro=1; 5 6$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; 7push(@INC,"${dir}","${dir}../../perlasm"); 8require "x86asm.pl"; 9require "cbc.pl"; 10 11&asm_init($ARGV[0],"cast-586.pl",$ARGV[$#ARGV] eq "386"); 12 13$CAST_ROUNDS=16; 14$L="edi"; 15$R="esi"; 16$K="ebp"; 17$tmp1="ecx"; 18$tmp2="ebx"; 19$tmp3="eax"; 20$tmp4="edx"; 21$S1="CAST_S_table0"; 22$S2="CAST_S_table1"; 23$S3="CAST_S_table2"; 24$S4="CAST_S_table3"; 25 26@F1=("add","xor","sub"); 27@F2=("xor","sub","add"); 28@F3=("sub","add","xor"); 29 30&CAST_encrypt("CAST_encrypt",1); 31&CAST_encrypt("CAST_decrypt",0); 32&cbc("CAST_cbc_encrypt","CAST_encrypt","CAST_decrypt",1,4,5,3,-1,-1); 33 34&asm_finish(); 35 36sub CAST_encrypt { 37 local($name,$enc)=@_; 38 39 local($win_ex)=<<"EOF"; 40EXTERN _CAST_S_table0:DWORD 41EXTERN _CAST_S_table1:DWORD 42EXTERN _CAST_S_table2:DWORD 43EXTERN _CAST_S_table3:DWORD 44EOF 45 &main::external_label( 46 "CAST_S_table0", 47 "CAST_S_table1", 48 "CAST_S_table2", 49 "CAST_S_table3", 50 ); 51 52 &function_begin_B($name,$win_ex); 53 54 &comment(""); 55 56 &push("ebp"); 57 &push("ebx"); 58 &mov($tmp2,&wparam(0)); 59 &mov($K,&wparam(1)); 60 &push("esi"); 61 &push("edi"); 62 63 &comment("Load the 2 words"); 64 &mov($L,&DWP(0,$tmp2,"",0)); 65 &mov($R,&DWP(4,$tmp2,"",0)); 66 67 &comment('Get short key flag'); 68 &mov($tmp3,&DWP(128,$K,"",0)); 69 if($enc) { 70 &push($tmp3); 71 } else { 72 &or($tmp3,$tmp3); 73 &jnz(&label('cast_dec_skip')); 74 } 75 76 &xor($tmp3, $tmp3); 77 78 # encrypting part 79 80 if ($enc) { 81 &E_CAST( 0,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); 82 &E_CAST( 1,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); 83 &E_CAST( 2,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); 84 &E_CAST( 3,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); 85 &E_CAST( 4,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); 86 &E_CAST( 5,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); 87 &E_CAST( 6,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); 88 &E_CAST( 7,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); 89 &E_CAST( 8,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); 90 &E_CAST( 9,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); 91 &E_CAST(10,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); 92 &E_CAST(11,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); 93 &comment('test short key flag'); 94 &pop($tmp4); 95 &or($tmp4,$tmp4); 96 &jnz(&label('cast_enc_done')); 97 &E_CAST(12,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); 98 &E_CAST(13,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); 99 &E_CAST(14,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); 100 &E_CAST(15,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); 101 } else { 102 &E_CAST(15,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); 103 &E_CAST(14,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); 104 &E_CAST(13,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); 105 &E_CAST(12,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); 106 &set_label('cast_dec_skip'); 107 &E_CAST(11,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); 108 &E_CAST(10,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); 109 &E_CAST( 9,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); 110 &E_CAST( 8,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); 111 &E_CAST( 7,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); 112 &E_CAST( 6,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); 113 &E_CAST( 5,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); 114 &E_CAST( 4,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); 115 &E_CAST( 3,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); 116 &E_CAST( 2,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); 117 &E_CAST( 1,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); 118 &E_CAST( 0,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); 119 } 120 121 &set_label('cast_enc_done') if $enc; 122# Why the nop? - Ben 17/1/99 123 &nop(); 124 &mov($tmp3,&wparam(0)); 125 &mov(&DWP(4,$tmp3,"",0),$L); 126 &mov(&DWP(0,$tmp3,"",0),$R); 127 &function_end($name); 128} 129 130sub E_CAST { 131 local($i,$S,$L,$R,$K,$OP1,$OP2,$OP3,$tmp1,$tmp2,$tmp3,$tmp4)=@_; 132 # Ri needs to have 16 pre added. 133 134 &comment("round $i"); 135 &mov( $tmp4, &DWP($i*8,$K,"",1)); 136 137 &mov( $tmp1, &DWP($i*8+4,$K,"",1)); 138 &$OP1( $tmp4, $R); 139 140 &rotl( $tmp4, &LB($tmp1)); 141 142 if ($ppro) { 143 &mov( $tmp2, $tmp4); # B 144 &xor( $tmp1, $tmp1); 145 146 &movb( &LB($tmp1), &HB($tmp4)); # A 147 &and( $tmp2, 0xff); 148 149 &shr( $tmp4, 16); # 150 &xor( $tmp3, $tmp3); 151 } else { 152 &mov( $tmp2, $tmp4); # B 153 &movb( &LB($tmp1), &HB($tmp4)); # A # BAD BAD BAD 154 155 &shr( $tmp4, 16); # 156 &and( $tmp2, 0xff); 157 } 158 159 &movb( &LB($tmp3), &HB($tmp4)); # C # BAD BAD BAD 160 &and( $tmp4, 0xff); # D 161 162 &mov( $tmp1, &DWP($S1,"",$tmp1,4)); 163 &mov( $tmp2, &DWP($S2,"",$tmp2,4)); 164 165 &$OP2( $tmp1, $tmp2); 166 &mov( $tmp2, &DWP($S3,"",$tmp3,4)); 167 168 &$OP3( $tmp1, $tmp2); 169 &mov( $tmp2, &DWP($S4,"",$tmp4,4)); 170 171 &$OP1( $tmp1, $tmp2); 172 # XXX 173 174 &xor( $L, $tmp1); 175 # XXX 176} 177 178