155714Skris#!/usr/local/bin/perl 255714Skris 355714Skris# define for pentium pro friendly version 455714Skris$ppro=1; 555714Skris 6238405Sjkim$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; 7238405Sjkimpush(@INC,"${dir}","${dir}../../perlasm"); 855714Skrisrequire "x86asm.pl"; 955714Skrisrequire "cbc.pl"; 1055714Skris 1155714Skris&asm_init($ARGV[0],"cast-586.pl",$ARGV[$#ARGV] eq "386"); 1255714Skris 1355714Skris$CAST_ROUNDS=16; 1455714Skris$L="edi"; 1555714Skris$R="esi"; 1655714Skris$K="ebp"; 1755714Skris$tmp1="ecx"; 1855714Skris$tmp2="ebx"; 1955714Skris$tmp3="eax"; 2055714Skris$tmp4="edx"; 2155714Skris$S1="CAST_S_table0"; 2255714Skris$S2="CAST_S_table1"; 2355714Skris$S3="CAST_S_table2"; 2455714Skris$S4="CAST_S_table3"; 2555714Skris 2655714Skris@F1=("add","xor","sub"); 2755714Skris@F2=("xor","sub","add"); 2855714Skris@F3=("sub","add","xor"); 2955714Skris 3055714Skris&CAST_encrypt("CAST_encrypt",1); 3155714Skris&CAST_encrypt("CAST_decrypt",0); 3255714Skris&cbc("CAST_cbc_encrypt","CAST_encrypt","CAST_decrypt",1,4,5,3,-1,-1); 3355714Skris 3455714Skris&asm_finish(); 3555714Skris 3655714Skrissub CAST_encrypt { 3755714Skris local($name,$enc)=@_; 3855714Skris 3955714Skris local($win_ex)=<<"EOF"; 4055714SkrisEXTERN _CAST_S_table0:DWORD 4155714SkrisEXTERN _CAST_S_table1:DWORD 4255714SkrisEXTERN _CAST_S_table2:DWORD 4355714SkrisEXTERN _CAST_S_table3:DWORD 4455714SkrisEOF 4555714Skris &main::external_label( 4655714Skris "CAST_S_table0", 4755714Skris "CAST_S_table1", 4855714Skris "CAST_S_table2", 4955714Skris "CAST_S_table3", 5055714Skris ); 5155714Skris 5255714Skris &function_begin_B($name,$win_ex); 5355714Skris 5455714Skris &comment(""); 5555714Skris 5655714Skris &push("ebp"); 5755714Skris &push("ebx"); 5855714Skris &mov($tmp2,&wparam(0)); 5955714Skris &mov($K,&wparam(1)); 6055714Skris &push("esi"); 6155714Skris &push("edi"); 6255714Skris 6355714Skris &comment("Load the 2 words"); 6455714Skris &mov($L,&DWP(0,$tmp2,"",0)); 6555714Skris &mov($R,&DWP(4,$tmp2,"",0)); 6655714Skris 6755714Skris &comment('Get short key flag'); 6855714Skris &mov($tmp3,&DWP(128,$K,"",0)); 6955714Skris if($enc) { 7055714Skris &push($tmp3); 7155714Skris } else { 7255714Skris &or($tmp3,$tmp3); 7355714Skris &jnz(&label('cast_dec_skip')); 7455714Skris } 7555714Skris 7655714Skris &xor($tmp3, $tmp3); 7755714Skris 7855714Skris # encrypting part 7955714Skris 8055714Skris if ($enc) { 8155714Skris &E_CAST( 0,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); 8255714Skris &E_CAST( 1,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); 8355714Skris &E_CAST( 2,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); 8455714Skris &E_CAST( 3,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); 8555714Skris &E_CAST( 4,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); 8655714Skris &E_CAST( 5,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); 8755714Skris &E_CAST( 6,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); 8855714Skris &E_CAST( 7,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); 8955714Skris &E_CAST( 8,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); 9055714Skris &E_CAST( 9,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); 9155714Skris &E_CAST(10,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); 9255714Skris &E_CAST(11,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); 9355714Skris &comment('test short key flag'); 9455714Skris &pop($tmp4); 9555714Skris &or($tmp4,$tmp4); 9655714Skris &jnz(&label('cast_enc_done')); 9755714Skris &E_CAST(12,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); 9855714Skris &E_CAST(13,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); 9955714Skris &E_CAST(14,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); 10055714Skris &E_CAST(15,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); 10155714Skris } else { 10255714Skris &E_CAST(15,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); 10355714Skris &E_CAST(14,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); 10455714Skris &E_CAST(13,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); 10555714Skris &E_CAST(12,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); 10655714Skris &set_label('cast_dec_skip'); 10755714Skris &E_CAST(11,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); 10855714Skris &E_CAST(10,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); 10955714Skris &E_CAST( 9,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); 11055714Skris &E_CAST( 8,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); 11155714Skris &E_CAST( 7,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); 11255714Skris &E_CAST( 6,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); 11355714Skris &E_CAST( 5,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); 11455714Skris &E_CAST( 4,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); 11555714Skris &E_CAST( 3,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); 11655714Skris &E_CAST( 2,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); 11755714Skris &E_CAST( 1,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); 11855714Skris &E_CAST( 0,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); 11955714Skris } 12055714Skris 12155714Skris &set_label('cast_enc_done') if $enc; 12255714Skris# Why the nop? - Ben 17/1/99 12355714Skris &nop(); 12455714Skris &mov($tmp3,&wparam(0)); 12555714Skris &mov(&DWP(4,$tmp3,"",0),$L); 12655714Skris &mov(&DWP(0,$tmp3,"",0),$R); 12755714Skris &function_end($name); 12855714Skris} 12955714Skris 13055714Skrissub E_CAST { 13155714Skris local($i,$S,$L,$R,$K,$OP1,$OP2,$OP3,$tmp1,$tmp2,$tmp3,$tmp4)=@_; 13255714Skris # Ri needs to have 16 pre added. 13355714Skris 13455714Skris &comment("round $i"); 13555714Skris &mov( $tmp4, &DWP($i*8,$K,"",1)); 13655714Skris 13755714Skris &mov( $tmp1, &DWP($i*8+4,$K,"",1)); 13855714Skris &$OP1( $tmp4, $R); 13955714Skris 14055714Skris &rotl( $tmp4, &LB($tmp1)); 14155714Skris 14255714Skris if ($ppro) { 14355714Skris &mov( $tmp2, $tmp4); # B 14455714Skris &xor( $tmp1, $tmp1); 14555714Skris 14655714Skris &movb( &LB($tmp1), &HB($tmp4)); # A 14755714Skris &and( $tmp2, 0xff); 14855714Skris 14955714Skris &shr( $tmp4, 16); # 15055714Skris &xor( $tmp3, $tmp3); 15155714Skris } else { 15255714Skris &mov( $tmp2, $tmp4); # B 15355714Skris &movb( &LB($tmp1), &HB($tmp4)); # A # BAD BAD BAD 15455714Skris 15555714Skris &shr( $tmp4, 16); # 15655714Skris &and( $tmp2, 0xff); 15755714Skris } 15855714Skris 15955714Skris &movb( &LB($tmp3), &HB($tmp4)); # C # BAD BAD BAD 16055714Skris &and( $tmp4, 0xff); # D 16155714Skris 16255714Skris &mov( $tmp1, &DWP($S1,"",$tmp1,4)); 16355714Skris &mov( $tmp2, &DWP($S2,"",$tmp2,4)); 16455714Skris 16555714Skris &$OP2( $tmp1, $tmp2); 16655714Skris &mov( $tmp2, &DWP($S3,"",$tmp3,4)); 16755714Skris 16855714Skris &$OP3( $tmp1, $tmp2); 16955714Skris &mov( $tmp2, &DWP($S4,"",$tmp4,4)); 17055714Skris 17155714Skris &$OP1( $tmp1, $tmp2); 17255714Skris # XXX 17355714Skris 17455714Skris &xor( $L, $tmp1); 17555714Skris # XXX 17655714Skris} 17755714Skris 178