155714Skris#!/usr/local/bin/perl
255714Skris
3238405Sjkim$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
4238405Sjkimpush(@INC,"${dir}","${dir}../../perlasm");
555714Skrisrequire "x86asm.pl";
655714Skrisrequire "cbc.pl";
755714Skris
855714Skris&asm_init($ARGV[0],"bf-586.pl",$ARGV[$#ARGV] eq "386");
955714Skris
1055714Skris$BF_ROUNDS=16;
1155714Skris$BF_OFF=($BF_ROUNDS+2)*4;
1255714Skris$L="edi";
1355714Skris$R="esi";
1455714Skris$P="ebp";
1555714Skris$tmp1="eax";
1655714Skris$tmp2="ebx";
1755714Skris$tmp3="ecx";
1855714Skris$tmp4="edx";
1955714Skris
2055714Skris&BF_encrypt("BF_encrypt",1);
2155714Skris&BF_encrypt("BF_decrypt",0);
2255714Skris&cbc("BF_cbc_encrypt","BF_encrypt","BF_decrypt",1,4,5,3,-1,-1);
2355714Skris&asm_finish();
2455714Skris
2555714Skrissub BF_encrypt
2655714Skris	{
2755714Skris	local($name,$enc)=@_;
2855714Skris
2955714Skris	&function_begin_B($name,"");
3055714Skris
3155714Skris	&comment("");
3255714Skris
3355714Skris	&push("ebp");
3455714Skris	&push("ebx");
3555714Skris	&mov($tmp2,&wparam(0));
3655714Skris	&mov($P,&wparam(1));
3755714Skris	&push("esi");
3855714Skris	&push("edi");
3955714Skris
4055714Skris	&comment("Load the 2 words");
4155714Skris	&mov($L,&DWP(0,$tmp2,"",0));
4255714Skris	&mov($R,&DWP(4,$tmp2,"",0));
4355714Skris
4455714Skris	&xor(	$tmp1,	$tmp1);
4555714Skris
4655714Skris	# encrypting part
4755714Skris
4855714Skris	if ($enc)
4955714Skris		{
5055714Skris		 &mov($tmp2,&DWP(0,$P,"",0));
5155714Skris		&xor(	$tmp3,	$tmp3);
5255714Skris
5355714Skris		&xor($L,$tmp2);
5455714Skris		for ($i=0; $i<$BF_ROUNDS; $i+=2)
5555714Skris			{
5655714Skris			&comment("");
5755714Skris			&comment("Round $i");
5855714Skris			&BF_ENCRYPT($i+1,$R,$L,$P,$tmp1,$tmp2,$tmp3,$tmp4,1);
5955714Skris
6055714Skris			&comment("");
6155714Skris			&comment("Round ".sprintf("%d",$i+1));
6255714Skris			&BF_ENCRYPT($i+2,$L,$R,$P,$tmp1,$tmp2,$tmp3,$tmp4,1);
6355714Skris			}
6455714Skris		# &mov($tmp1,&wparam(0)); In last loop
6555714Skris		&mov($tmp4,&DWP(($BF_ROUNDS+1)*4,$P,"",0));
6655714Skris		}
6755714Skris	else
6855714Skris		{
6955714Skris		 &mov($tmp2,&DWP(($BF_ROUNDS+1)*4,$P,"",0));
7055714Skris		&xor(	$tmp3,	$tmp3);
7155714Skris
7255714Skris		&xor($L,$tmp2);
7355714Skris		for ($i=$BF_ROUNDS; $i>0; $i-=2)
7455714Skris			{
7555714Skris			&comment("");
7655714Skris			&comment("Round $i");
7755714Skris			&BF_ENCRYPT($i,$R,$L,$P,$tmp1,$tmp2,$tmp3,$tmp4,0);
7855714Skris			&comment("");
7955714Skris			&comment("Round ".sprintf("%d",$i-1));
8055714Skris			&BF_ENCRYPT($i-1,$L,$R,$P,$tmp1,$tmp2,$tmp3,$tmp4,0);
8155714Skris			}
8255714Skris		# &mov($tmp1,&wparam(0)); In last loop
8355714Skris		&mov($tmp4,&DWP(0,$P,"",0));
8455714Skris		}
8555714Skris
8655714Skris	&xor($R,$tmp4);
8755714Skris	&mov(&DWP(4,$tmp1,"",0),$L);
8855714Skris
8955714Skris	&mov(&DWP(0,$tmp1,"",0),$R);
9055714Skris	&function_end($name);
9155714Skris	}
9255714Skris
9355714Skrissub BF_ENCRYPT
9455714Skris	{
9555714Skris	local($i,$L,$R,$P,$tmp1,$tmp2,$tmp3,$tmp4,$enc)=@_;
9655714Skris
9755714Skris	&mov(	$tmp4,		&DWP(&n2a($i*4),$P,"",0)); # for next round
9855714Skris
9955714Skris	&mov(	$tmp2,		$R);
10055714Skris	&xor(	$L,		$tmp4);
10155714Skris
10255714Skris	&shr(	$tmp2,		16);
10355714Skris	&mov(	$tmp4,		$R);
10455714Skris
10555714Skris	&movb(	&LB($tmp1),	&HB($tmp2));	# A
10655714Skris	&and(	$tmp2,		0xff);		# B
10755714Skris
10855714Skris	&movb(	&LB($tmp3),	&HB($tmp4));	# C
10955714Skris	&and(	$tmp4,		0xff);		# D
11055714Skris
11155714Skris	&mov(	$tmp1,		&DWP(&n2a($BF_OFF+0x0000),$P,$tmp1,4));
11255714Skris	&mov(	$tmp2,		&DWP(&n2a($BF_OFF+0x0400),$P,$tmp2,4));
11355714Skris
11455714Skris	&add(	$tmp2,		$tmp1);
11555714Skris	&mov(	$tmp1,		&DWP(&n2a($BF_OFF+0x0800),$P,$tmp3,4));
11655714Skris
11755714Skris	&xor(	$tmp2,		$tmp1);
11855714Skris	&mov(	$tmp4,		&DWP(&n2a($BF_OFF+0x0C00),$P,$tmp4,4));
11955714Skris
12055714Skris	&add(	$tmp2,		$tmp4);
12155714Skris	if (($enc && ($i != 16)) || ((!$enc) && ($i != 1)))
12255714Skris		{ &xor(	$tmp1,		$tmp1); }
12355714Skris	else
12455714Skris		{
12555714Skris		&comment("Load parameter 0 ($i) enc=$enc");
12655714Skris		&mov($tmp1,&wparam(0));
12755714Skris		} # In last loop
12855714Skris
12955714Skris	&xor(	$L,		$tmp2);
13055714Skris	# delay
13155714Skris	}
13255714Skris
13355714Skrissub n2a
13455714Skris	{
13555714Skris	sprintf("%d",$_[0]);
13655714Skris	}
13755714Skris
138