des-586.pl revision 109998
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#
6
7push(@INC,"perlasm","../../perlasm");
8require "x86asm.pl";
9require "cbc.pl";
10require "desboth.pl";
11
12# base code is in microsft
13# op dest, source
14# format.
15#
16
17&asm_init($ARGV[0],"des-586.pl");
18
19$L="edi";
20$R="esi";
21
22&external_label("DES_SPtrans");
23&DES_encrypt("DES_encrypt1",1);
24&DES_encrypt("DES_encrypt2",0);
25&DES_encrypt3("DES_encrypt3",1);
26&DES_encrypt3("DES_decrypt3",0);
27&cbc("DES_ncbc_encrypt","DES_encrypt1","DES_encrypt1",0,4,5,3,5,-1);
28&cbc("DES_ede3_cbc_encrypt","DES_encrypt3","DES_decrypt3",0,6,7,3,4,5);
29
30&asm_finish();
31
32sub DES_encrypt
33	{
34	local($name,$do_ip)=@_;
35
36	&function_begin_B($name,"EXTRN   _DES_SPtrans:DWORD");
37
38	&push("esi");
39	&push("edi");
40
41	&comment("");
42	&comment("Load the 2 words");
43	$trans="ebp";
44
45	if ($do_ip)
46		{
47		&mov($R,&wparam(0));
48		 &xor(	"ecx",		"ecx"		);
49
50		&push("ebx");
51		&push("ebp");
52
53		&mov("eax",&DWP(0,$R,"",0));
54		 &mov("ebx",&wparam(2));	# get encrypt flag
55		&mov($L,&DWP(4,$R,"",0));
56		&comment("");
57		&comment("IP");
58		&IP_new("eax",$L,$R,3);
59		}
60	else
61		{
62		&mov("eax",&wparam(0));
63		 &xor(	"ecx",		"ecx"		);
64
65		&push("ebx");
66		&push("ebp");
67
68		&mov($R,&DWP(0,"eax","",0));
69		 &mov("ebx",&wparam(2));	# get encrypt flag
70		&rotl($R,3);
71		&mov($L,&DWP(4,"eax","",0));
72		&rotl($L,3);
73		}
74
75	# PIC-ification:-)
76	if ($cpp)	{ &picmeup($trans,"DES_SPtrans");   }
77	else		{ &lea($trans,&DWP("DES_SPtrans")); }
78
79	&mov(	"ecx",	&wparam(1)	);
80	&cmp("ebx","0");
81	&je(&label("start_decrypt"));
82
83	for ($i=0; $i<16; $i+=2)
84		{
85		&comment("");
86		&comment("Round $i");
87		&D_ENCRYPT($i,$L,$R,$i*2,$trans,"eax","ebx","ecx","edx");
88
89		&comment("");
90		&comment("Round ".sprintf("%d",$i+1));
91		&D_ENCRYPT($i+1,$R,$L,($i+1)*2,$trans,"eax","ebx","ecx","edx");
92		}
93	&jmp(&label("end"));
94
95	&set_label("start_decrypt");
96
97	for ($i=15; $i>0; $i-=2)
98		{
99		&comment("");
100		&comment("Round $i");
101		&D_ENCRYPT(15-$i,$L,$R,$i*2,$trans,"eax","ebx","ecx","edx");
102		&comment("");
103		&comment("Round ".sprintf("%d",$i-1));
104		&D_ENCRYPT(15-$i+1,$R,$L,($i-1)*2,$trans,"eax","ebx","ecx","edx");
105		}
106
107	&set_label("end");
108
109	if ($do_ip)
110		{
111		&comment("");
112		&comment("FP");
113		&mov("edx",&wparam(0));
114		&FP_new($L,$R,"eax",3);
115
116		&mov(&DWP(0,"edx","",0),"eax");
117		&mov(&DWP(4,"edx","",0),$R);
118		}
119	else
120		{
121		&comment("");
122		&comment("Fixup");
123		&rotr($L,3);		# r
124		 &mov("eax",&wparam(0));
125		&rotr($R,3);		# l
126		 &mov(&DWP(0,"eax","",0),$L);
127		 &mov(&DWP(4,"eax","",0),$R);
128		}
129
130	&pop("ebp");
131	&pop("ebx");
132	&pop("edi");
133	&pop("esi");
134	&ret();
135
136	&function_end_B($name);
137	}
138
139sub D_ENCRYPT
140	{
141	local($r,$L,$R,$S,$trans,$u,$tmp1,$tmp2,$t)=@_;
142
143	 &mov(	$u,		&DWP(&n2a($S*4),$tmp2,"",0));
144	&xor(	$tmp1,		$tmp1);
145	 &mov(	$t,		&DWP(&n2a(($S+1)*4),$tmp2,"",0));
146	&xor(	$u,		$R);
147	&xor(	$tmp2,		$tmp2);
148	 &xor(	$t,		$R);
149	&and(	$u,		"0xfcfcfcfc"	);
150	 &and(	$t,		"0xcfcfcfcf"	);
151	&movb(	&LB($tmp1),	&LB($u)	);
152	 &movb(	&LB($tmp2),	&HB($u)	);
153	&rotr(	$t,		4		);
154	&xor(	$L,		&DWP("     ",$trans,$tmp1,0));
155	 &movb(	&LB($tmp1),	&LB($t)	);
156	 &xor(	$L,		&DWP("0x200",$trans,$tmp2,0));
157	 &movb(	&LB($tmp2),	&HB($t)	);
158	&shr(	$u,		16);
159	 &xor(	$L,		&DWP("0x100",$trans,$tmp1,0));
160	 &movb(	&LB($tmp1),	&HB($u)	);
161	&shr(	$t,		16);
162	 &xor(	$L,		&DWP("0x300",$trans,$tmp2,0));
163	&movb(	&LB($tmp2),	&HB($t)	);
164	 &and(	$u,		"0xff"	);
165	&and(	$t,		"0xff"	);
166	 &xor(	$L,		&DWP("0x600",$trans,$tmp1,0));
167	 &xor(	$L,		&DWP("0x700",$trans,$tmp2,0));
168	&mov(	$tmp2,		&wparam(1)	);
169	 &xor(	$L,		&DWP("0x400",$trans,$u,0));
170	 &xor(	$L,		&DWP("0x500",$trans,$t,0));
171	}
172
173sub n2a
174	{
175	sprintf("%d",$_[0]);
176	}
177
178# now has a side affect of rotating $a by $shift
179sub R_PERM_OP
180	{
181	local($a,$b,$tt,$shift,$mask,$last)=@_;
182
183	&rotl(	$a,		$shift		) if ($shift != 0);
184	&mov(	$tt,		$a		);
185	&xor(	$a,		$b		);
186	&and(	$a,		$mask		);
187	# This can never succeed, and besides it is difficult to see what the
188	# idea was - Ben 13 Feb 99
189	if (!$last eq $b)
190		{
191		&xor(	$b,		$a		);
192		&xor(	$tt,		$a		);
193		}
194	else
195		{
196		&xor(	$tt,		$a		);
197		&xor(	$b,		$a		);
198		}
199	&comment("");
200	}
201
202sub IP_new
203	{
204	local($l,$r,$tt,$lr)=@_;
205
206	&R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l);
207	&R_PERM_OP($r,$tt,$l,20,"0xfff0000f",$l);
208	&R_PERM_OP($l,$tt,$r,14,"0x33333333",$r);
209	&R_PERM_OP($tt,$r,$l,22,"0x03fc03fc",$r);
210	&R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r);
211
212	if ($lr != 3)
213		{
214		if (($lr-3) < 0)
215			{ &rotr($tt,	3-$lr); }
216		else	{ &rotl($tt,	$lr-3); }
217		}
218	if ($lr != 2)
219		{
220		if (($lr-2) < 0)
221			{ &rotr($r,	2-$lr); }
222		else	{ &rotl($r,	$lr-2); }
223		}
224	}
225
226sub FP_new
227	{
228	local($l,$r,$tt,$lr)=@_;
229
230	if ($lr != 2)
231		{
232		if (($lr-2) < 0)
233			{ &rotl($r,	2-$lr); }
234		else	{ &rotr($r,	$lr-2); }
235		}
236	if ($lr != 3)
237		{
238		if (($lr-3) < 0)
239			{ &rotl($l,	3-$lr); }
240		else	{ &rotr($l,	$lr-3); }
241		}
242
243	&R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r);
244	&R_PERM_OP($tt,$r,$l,23,"0x03fc03fc",$r);
245	&R_PERM_OP($l,$r,$tt,10,"0x33333333",$l);
246	&R_PERM_OP($r,$tt,$l,18,"0xfff0000f",$l);
247	&R_PERM_OP($l,$tt,$r,12,"0xf0f0f0f0",$r);
248	&rotr($tt	, 4);
249	}
250
251