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