crypt586.pl revision 55714
155714Skris#!/usr/local/bin/perl
255714Skris#
355714Skris# The inner loop instruction sequence and the IP/FP modifications are from
455714Skris# Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>
555714Skris# I've added the stuff needed for crypt() but I've not worried about making
655714Skris# things perfect.
755714Skris#
855714Skris
955714Skrispush(@INC,"perlasm","../../perlasm");
1055714Skrisrequire "x86asm.pl";
1155714Skris
1255714Skris&asm_init($ARGV[0],"crypt586.pl");
1355714Skris
1455714Skris$L="edi";
1555714Skris$R="esi";
1655714Skris
1755714Skris&external_label("des_SPtrans");
1855714Skris&fcrypt_body("fcrypt_body");
1955714Skris&asm_finish();
2055714Skris
2155714Skrissub fcrypt_body
2255714Skris	{
2355714Skris	local($name,$do_ip)=@_;
2455714Skris
2555714Skris	&function_begin($name,"EXTRN   _des_SPtrans:DWORD");
2655714Skris
2755714Skris	&comment("");
2855714Skris	&comment("Load the 2 words");
2955714Skris	$ks="ebp";
3055714Skris
3155714Skris	&xor(	$L,	$L);
3255714Skris	&xor(	$R,	$R);
3355714Skris	&mov($ks,&wparam(1));
3455714Skris
3555714Skris	&push(&DWC(25)); # add a variable
3655714Skris
3755714Skris	&set_label("start");
3855714Skris	for ($i=0; $i<16; $i+=2)
3955714Skris		{
4055714Skris		&comment("");
4155714Skris		&comment("Round $i");
4255714Skris		&D_ENCRYPT($i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
4355714Skris
4455714Skris		&comment("");
4555714Skris		&comment("Round ".sprintf("%d",$i+1));
4655714Skris		&D_ENCRYPT($i+1,$R,$L,($i+1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
4755714Skris		}
4855714Skris	 &mov("ebx",	&swtmp(0));
4955714Skris	&mov("eax",	$L);
5055714Skris	 &dec("ebx");
5155714Skris	&mov($L,	$R);
5255714Skris	 &mov($R,	"eax");
5355714Skris	&mov(&swtmp(0),	"ebx");
5455714Skris	 &jnz(&label("start"));
5555714Skris
5655714Skris	&comment("");
5755714Skris	&comment("FP");
5855714Skris	&mov("edx",&wparam(0));
5955714Skris
6055714Skris	&FP_new($R,$L,"eax",3);
6155714Skris	&mov(&DWP(0,"edx","",0),"eax");
6255714Skris	&mov(&DWP(4,"edx","",0),$L);
6355714Skris
6455714Skris	&pop("ecx");	# remove variable
6555714Skris
6655714Skris	&function_end($name);
6755714Skris	}
6855714Skris
6955714Skrissub D_ENCRYPT
7055714Skris	{
7155714Skris	local($r,$L,$R,$S,$ks,$desSP,$u,$tmp1,$tmp2,$t)=@_;
7255714Skris
7355714Skris	&mov(	$u,		&wparam(2));			# 2
7455714Skris	&mov(	$t,		$R);
7555714Skris	&shr(	$t,		16);				# 1
7655714Skris	&mov(	$tmp2,		&wparam(3));			# 2
7755714Skris	&xor(	$t,		$R);				# 1
7855714Skris
7955714Skris	&and(	$u,		$t);				# 2
8055714Skris	&and(	$t,		$tmp2);				# 2
8155714Skris
8255714Skris	&mov(	$tmp1,		$u);
8355714Skris	&shl(	$tmp1,		16); 				# 1
8455714Skris	&mov(	$tmp2,		$t);
8555714Skris	&shl(	$tmp2,		16); 				# 1
8655714Skris	&xor(	$u,		$tmp1);				# 2
8755714Skris	&xor(	$t,		$tmp2);				# 2
8855714Skris	&mov(	$tmp1,		&DWP(&n2a($S*4),$ks,"",0));	# 2
8955714Skris	&xor(	$u,		$tmp1);
9055714Skris	&mov(	$tmp2,		&DWP(&n2a(($S+1)*4),$ks,"",0));	# 2
9155714Skris	&xor(	$u,		$R);
9255714Skris	&xor(	$t,		$R);
9355714Skris	&xor(	$t,		$tmp2);
9455714Skris
9555714Skris	&and(	$u,		"0xfcfcfcfc"	);		# 2
9655714Skris	&xor(	$tmp1,		$tmp1);				# 1
9755714Skris	&and(	$t,		"0xcfcfcfcf"	);		# 2
9855714Skris	&xor(	$tmp2,		$tmp2);
9955714Skris	&movb(	&LB($tmp1),	&LB($u)	);
10055714Skris	&movb(	&LB($tmp2),	&HB($u)	);
10155714Skris	&rotr(	$t,		4		);
10255714Skris	&mov(	$ks,		&DWP("      $desSP",$tmp1,"",0));
10355714Skris	&movb(	&LB($tmp1),	&LB($t)	);
10455714Skris	&xor(	$L,		$ks);
10555714Skris	&mov(	$ks,		&DWP("0x200+$desSP",$tmp2,"",0));
10655714Skris	&xor(	$L,		$ks);
10755714Skris	&movb(	&LB($tmp2),	&HB($t)	);
10855714Skris	&shr(	$u,		16);
10955714Skris	&mov(	$ks,		&DWP("0x100+$desSP",$tmp1,"",0));
11055714Skris	&xor(	$L,		$ks);
11155714Skris	&movb(	&LB($tmp1),	&HB($u)	);
11255714Skris	&shr(	$t,		16);
11355714Skris	&mov(	$ks,		&DWP("0x300+$desSP",$tmp2,"",0));
11455714Skris	&xor(	$L,		$ks);
11555714Skris	&mov(	$ks,		&wparam(1));
11655714Skris	&movb(	&LB($tmp2),	&HB($t)	);
11755714Skris	&and(	$u,		"0xff"	);
11855714Skris	&and(	$t,		"0xff"	);
11955714Skris	&mov(	$tmp1,		&DWP("0x600+$desSP",$tmp1,"",0));
12055714Skris	&xor(	$L,		$tmp1);
12155714Skris	&mov(	$tmp1,		&DWP("0x700+$desSP",$tmp2,"",0));
12255714Skris	&xor(	$L,		$tmp1);
12355714Skris	&mov(	$tmp1,		&DWP("0x400+$desSP",$u,"",0));
12455714Skris	&xor(	$L,		$tmp1);
12555714Skris	&mov(	$tmp1,		&DWP("0x500+$desSP",$t,"",0));
12655714Skris	&xor(	$L,		$tmp1);
12755714Skris	}
12855714Skris
12955714Skrissub n2a
13055714Skris	{
13155714Skris	sprintf("%d",$_[0]);
13255714Skris	}
13355714Skris
13455714Skris# now has a side affect of rotating $a by $shift
13555714Skrissub R_PERM_OP
13655714Skris	{
13755714Skris	local($a,$b,$tt,$shift,$mask,$last)=@_;
13855714Skris
13955714Skris	&rotl(	$a,		$shift		) if ($shift != 0);
14055714Skris	&mov(	$tt,		$a		);
14155714Skris	&xor(	$a,		$b		);
14255714Skris	&and(	$a,		$mask		);
14355714Skris	if ($notlast eq $b)
14455714Skris		{
14555714Skris		&xor(	$b,		$a		);
14655714Skris		&xor(	$tt,		$a		);
14755714Skris		}
14855714Skris	else
14955714Skris		{
15055714Skris		&xor(	$tt,		$a		);
15155714Skris		&xor(	$b,		$a		);
15255714Skris		}
15355714Skris	&comment("");
15455714Skris	}
15555714Skris
15655714Skrissub IP_new
15755714Skris	{
15855714Skris	local($l,$r,$tt,$lr)=@_;
15955714Skris
16055714Skris	&R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l);
16155714Skris	&R_PERM_OP($r,$tt,$l,20,"0xfff0000f",$l);
16255714Skris	&R_PERM_OP($l,$tt,$r,14,"0x33333333",$r);
16355714Skris	&R_PERM_OP($tt,$r,$l,22,"0x03fc03fc",$r);
16455714Skris	&R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r);
16555714Skris
16655714Skris	if ($lr != 3)
16755714Skris		{
16855714Skris		if (($lr-3) < 0)
16955714Skris			{ &rotr($tt,	3-$lr); }
17055714Skris		else	{ &rotl($tt,	$lr-3); }
17155714Skris		}
17255714Skris	if ($lr != 2)
17355714Skris		{
17455714Skris		if (($lr-2) < 0)
17555714Skris			{ &rotr($r,	2-$lr); }
17655714Skris		else	{ &rotl($r,	$lr-2); }
17755714Skris		}
17855714Skris	}
17955714Skris
18055714Skrissub FP_new
18155714Skris	{
18255714Skris	local($l,$r,$tt,$lr)=@_;
18355714Skris
18455714Skris	if ($lr != 2)
18555714Skris		{
18655714Skris		if (($lr-2) < 0)
18755714Skris			{ &rotl($r,	2-$lr); }
18855714Skris		else	{ &rotr($r,	$lr-2); }
18955714Skris		}
19055714Skris	if ($lr != 3)
19155714Skris		{
19255714Skris		if (($lr-3) < 0)
19355714Skris			{ &rotl($l,	3-$lr); }
19455714Skris		else	{ &rotr($l,	$lr-3); }
19555714Skris		}
19655714Skris
19755714Skris	&R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r);
19855714Skris	&R_PERM_OP($tt,$r,$l,23,"0x03fc03fc",$r);
19955714Skris	&R_PERM_OP($l,$r,$tt,10,"0x33333333",$l);
20055714Skris	&R_PERM_OP($r,$tt,$l,18,"0xfff0000f",$l);
20155714Skris	&R_PERM_OP($l,$tt,$r,12,"0xf0f0f0f0",$r);
20255714Skris	&rotr($tt	, 4);
20355714Skris	}
20455714Skris
205