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