rc4-586.pl revision 55714
1#!/usr/local/bin/perl
2
3# define for pentium pro friendly version
4
5push(@INC,"perlasm","../../perlasm");
6require "x86asm.pl";
7
8&asm_init($ARGV[0],"rc4-586.pl");
9
10$tx="eax";
11$ty="ebx";
12$x="ecx";
13$y="edx";
14$in="esi";
15$out="edi";
16$d="ebp";
17
18&RC4("RC4");
19
20&asm_finish();
21
22sub RC4_loop
23	{
24	local($n,$p,$char)=@_;
25
26	&comment("Round $n");
27
28	if ($char)
29		{
30		if ($p >= 0)
31			{
32			 &mov($ty,	&swtmp(2));
33			&cmp($ty,	$in);
34			 &jle(&label("finished"));
35			&inc($in);
36			}
37		else
38			{
39			&add($ty,	8);
40			 &inc($in);
41			&cmp($ty,	$in);
42			 &jl(&label("finished"));
43			&mov(&swtmp(2),	$ty);
44			}
45		}
46	# Moved out
47	# &mov(	$tx,		&DWP(0,$d,$x,4)) if $p < 0;
48
49	 &add(	$y,		$tx);
50	&and(	$y,		0xff);
51	 &inc(	$x);			# NEXT ROUND
52	&mov(	$ty,		&DWP(0,$d,$y,4));
53	 # XXX
54	&mov(	&DWP(-4,$d,$x,4),$ty);			# AGI
55	 &add(	$ty,		$tx);
56	&and(	$x,		0xff);	# NEXT ROUND
57	 &and(	$ty,		0xff);
58	&mov(	&DWP(0,$d,$y,4),$tx);
59	 &nop();
60	&mov(	$ty,		&DWP(0,$d,$ty,4));
61	 &mov(	$tx,		&DWP(0,$d,$x,4)) if $p < 1; # NEXT ROUND
62	 # XXX
63
64	if (!$char)
65		{
66		#moved up into last round
67		if ($p >= 1)
68			{
69			&add(	$out,	8)
70			}
71		&movb(	&BP($n,"esp","",0),	&LB($ty));
72		}
73	else
74		{
75		# Note in+=8 has occured
76		&movb(	&HB($ty),	&BP(-1,$in,"",0));
77		 # XXX
78		&xorb(&LB($ty),		&HB($ty));
79		 # XXX
80		&movb(&BP($n,$out,"",0),&LB($ty));
81		}
82	}
83
84
85sub RC4
86	{
87	local($name)=@_;
88
89	&function_begin_B($name,"");
90
91	&comment("");
92
93	&push("ebp");
94	 &push("ebx");
95	&mov(	$d,	&wparam(0));	# key
96	 &mov(	$ty,	&wparam(1));	# num
97	&push("esi");
98	 &push("edi");
99
100	&mov(	$x,	&DWP(0,$d,"",1));
101	 &mov(	$y,	&DWP(4,$d,"",1));
102
103	&mov(	$in,	&wparam(2));
104	 &inc(	$x);
105
106	&stack_push(3);	# 3 temp variables
107	 &add(	$d,	8);
108	&and(	$x,		0xff);
109
110	 &lea(	$ty,	&DWP(-8,$ty,$in));
111
112	# check for 0 length input
113
114	&mov(	$out,	&wparam(3));
115	 &mov(	&swtmp(2),	$ty);	# this is now address to exit at
116	&mov(	$tx,	&DWP(0,$d,$x,4));
117
118	 &cmp(	$ty,	$in);
119	&jl(	&label("end")); # less than 8 bytes
120
121	&set_label("start");
122
123	# filling DELAY SLOT
124	&add(	$in,	8);
125
126	&RC4_loop(0,-1,0);
127	&RC4_loop(1,0,0);
128	&RC4_loop(2,0,0);
129	&RC4_loop(3,0,0);
130	&RC4_loop(4,0,0);
131	&RC4_loop(5,0,0);
132	&RC4_loop(6,0,0);
133	&RC4_loop(7,1,0);
134
135	&comment("apply the cipher text");
136	# xor the cipher data with input
137
138	#&add(	$out,	8); #moved up into last round
139
140	&mov(	$tx,	&swtmp(0));
141	 &mov(	$ty,	&DWP(-8,$in,"",0));
142	&xor(	$tx,	$ty);
143	 &mov(	$ty,	&DWP(-4,$in,"",0));
144	&mov(	&DWP(-8,$out,"",0),	$tx);
145	 &mov(	$tx,	&swtmp(1));
146	&xor(	$tx,	$ty);
147	 &mov(	$ty,	&swtmp(2));	# load end ptr;
148	&mov(	&DWP(-4,$out,"",0),	$tx);
149	 &mov(	$tx,		&DWP(0,$d,$x,4));
150	&cmp($in,	$ty);
151	 &jle(&label("start"));
152
153	&set_label("end");
154
155	# There is quite a bit of extra crap in RC4_loop() for this
156	# first round
157	&RC4_loop(0,-1,1);
158	&RC4_loop(1,0,1);
159	&RC4_loop(2,0,1);
160	&RC4_loop(3,0,1);
161	&RC4_loop(4,0,1);
162	&RC4_loop(5,0,1);
163	&RC4_loop(6,1,1);
164
165	&set_label("finished");
166	&dec(	$x);
167	 &stack_pop(3);
168	&mov(	&DWP(-4,$d,"",0),$y);
169	 &movb(	&BP(-8,$d,"",0),&LB($x));
170
171	&function_end($name);
172	}
173
174