1#!/usr/local/bin/perl
2#
3# The inner loop instruction sequence and the IP/FP modifications are from
4# Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>
5# I've added the stuff needed for crypt() but I've not worried about making
6# things perfect.
7#
8
9$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
10push(@INC,"${dir}","${dir}../../perlasm");
11require "x86asm.pl";
12
13&asm_init($ARGV[0],"crypt586.pl");
14
15$L="edi";
16$R="esi";
17
18&external_label("DES_SPtrans");
19&fcrypt_body("fcrypt_body");
20&asm_finish();
21
22sub fcrypt_body
23	{
24	local($name,$do_ip)=@_;
25
26	&function_begin($name);
27
28	&comment("");
29	&comment("Load the 2 words");
30	$trans="ebp";
31
32	&xor(	$L,	$L);
33	&xor(	$R,	$R);
34
35	# PIC-ification:-)
36	&picmeup("edx","DES_SPtrans");
37	#if ($cpp)	{ &picmeup("edx","DES_SPtrans");   }
38	#else		{ &lea("edx",&DWP("DES_SPtrans")); }
39	&push("edx");	# becomes &swtmp(1)
40	#
41	&mov($trans,&wparam(1)); # reloaded with DES_SPtrans in D_ENCRYPT
42
43	&push(&DWC(25)); # add a variable
44
45	&set_label("start");
46	for ($i=0; $i<16; $i+=2)
47		{
48		&comment("");
49		&comment("Round $i");
50		&D_ENCRYPT($i,$L,$R,$i*2,$trans,"eax","ebx","ecx","edx");
51
52		&comment("");
53		&comment("Round ".sprintf("%d",$i+1));
54		&D_ENCRYPT($i+1,$R,$L,($i+1)*2,$trans,"eax","ebx","ecx","edx");
55		}
56	 &mov("ebx",	&swtmp(0));
57	&mov("eax",	$L);
58	 &dec("ebx");
59	&mov($L,	$R);
60	 &mov($R,	"eax");
61	&mov(&swtmp(0),	"ebx");
62	 &jnz(&label("start"));
63
64	&comment("");
65	&comment("FP");
66	&mov("edx",&wparam(0));
67
68	&FP_new($R,$L,"eax",3);
69	&mov(&DWP(0,"edx","",0),"eax");
70	&mov(&DWP(4,"edx","",0),$L);
71
72	&add("esp",8);	# remove variables
73
74	&function_end($name);
75	}
76
77sub D_ENCRYPT
78	{
79	local($r,$L,$R,$S,$trans,$u,$tmp1,$tmp2,$t)=@_;
80
81	&mov(	$u,		&wparam(2));			# 2
82	&mov(	$t,		$R);
83	&shr(	$t,		16);				# 1
84	&mov(	$tmp2,		&wparam(3));			# 2
85	&xor(	$t,		$R);				# 1
86
87	&and(	$u,		$t);				# 2
88	&and(	$t,		$tmp2);				# 2
89
90	&mov(	$tmp1,		$u);
91	&shl(	$tmp1,		16); 				# 1
92	&mov(	$tmp2,		$t);
93	&shl(	$tmp2,		16); 				# 1
94	&xor(	$u,		$tmp1);				# 2
95	&xor(	$t,		$tmp2);				# 2
96	&mov(	$tmp1,		&DWP(&n2a($S*4),$trans,"",0));	# 2
97	&xor(	$u,		$tmp1);
98	&mov(	$tmp2,		&DWP(&n2a(($S+1)*4),$trans,"",0));	# 2
99	&xor(	$u,		$R);
100	&xor(	$t,		$R);
101	&xor(	$t,		$tmp2);
102
103	&and(	$u,		"0xfcfcfcfc"	);		# 2
104	&xor(	$tmp1,		$tmp1);				# 1
105	&and(	$t,		"0xcfcfcfcf"	);		# 2
106	&xor(	$tmp2,		$tmp2);
107	&movb(	&LB($tmp1),	&LB($u)	);
108	&movb(	&LB($tmp2),	&HB($u)	);
109	&rotr(	$t,		4		);
110	&mov(	$trans,		&swtmp(1));
111	&xor(	$L,		&DWP("     ",$trans,$tmp1,0));
112	&movb(	&LB($tmp1),	&LB($t)	);
113	&xor(	$L,		&DWP("0x200",$trans,$tmp2,0));
114	&movb(	&LB($tmp2),	&HB($t)	);
115	&shr(	$u,		16);
116	&xor(	$L,		&DWP("0x100",$trans,$tmp1,0));
117	&movb(	&LB($tmp1),	&HB($u)	);
118	&shr(	$t,		16);
119	&xor(	$L,		&DWP("0x300",$trans,$tmp2,0));
120	&movb(	&LB($tmp2),	&HB($t)	);
121	&and(	$u,		"0xff"	);
122	&and(	$t,		"0xff"	);
123	&mov(	$tmp1,		&DWP("0x600",$trans,$tmp1,0));
124	&xor(	$L,		$tmp1);
125	&mov(	$tmp1,		&DWP("0x700",$trans,$tmp2,0));
126	&xor(	$L,		$tmp1);
127	&mov(	$tmp1,		&DWP("0x400",$trans,$u,0));
128	&xor(	$L,		$tmp1);
129	&mov(	$tmp1,		&DWP("0x500",$trans,$t,0));
130	&xor(	$L,		$tmp1);
131	&mov(	$trans,		&wparam(1));
132	}
133
134sub n2a
135	{
136	sprintf("%d",$_[0]);
137	}
138
139# now has a side affect of rotating $a by $shift
140sub R_PERM_OP
141	{
142	local($a,$b,$tt,$shift,$mask,$last)=@_;
143
144	&rotl(	$a,		$shift		) if ($shift != 0);
145	&mov(	$tt,		$a		);
146	&xor(	$a,		$b		);
147	&and(	$a,		$mask		);
148	if ($notlast eq $b)
149		{
150		&xor(	$b,		$a		);
151		&xor(	$tt,		$a		);
152		}
153	else
154		{
155		&xor(	$tt,		$a		);
156		&xor(	$b,		$a		);
157		}
158	&comment("");
159	}
160
161sub IP_new
162	{
163	local($l,$r,$tt,$lr)=@_;
164
165	&R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l);
166	&R_PERM_OP($r,$tt,$l,20,"0xfff0000f",$l);
167	&R_PERM_OP($l,$tt,$r,14,"0x33333333",$r);
168	&R_PERM_OP($tt,$r,$l,22,"0x03fc03fc",$r);
169	&R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r);
170
171	if ($lr != 3)
172		{
173		if (($lr-3) < 0)
174			{ &rotr($tt,	3-$lr); }
175		else	{ &rotl($tt,	$lr-3); }
176		}
177	if ($lr != 2)
178		{
179		if (($lr-2) < 0)
180			{ &rotr($r,	2-$lr); }
181		else	{ &rotl($r,	$lr-2); }
182		}
183	}
184
185sub FP_new
186	{
187	local($l,$r,$tt,$lr)=@_;
188
189	if ($lr != 2)
190		{
191		if (($lr-2) < 0)
192			{ &rotl($r,	2-$lr); }
193		else	{ &rotr($r,	$lr-2); }
194		}
195	if ($lr != 3)
196		{
197		if (($lr-3) < 0)
198			{ &rotl($l,	3-$lr); }
199		else	{ &rotr($l,	$lr-3); }
200		}
201
202	&R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r);
203	&R_PERM_OP($tt,$r,$l,23,"0x03fc03fc",$r);
204	&R_PERM_OP($l,$r,$tt,10,"0x33333333",$l);
205	&R_PERM_OP($r,$tt,$l,18,"0xfff0000f",$l);
206	&R_PERM_OP($l,$tt,$r,12,"0xf0f0f0f0",$r);
207	&rotr($tt	, 4);
208	}
209
210