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