1#!/usr/local/bin/perl
2
3# define for pentium pro friendly version
4$ppro=1;
5
6$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
7push(@INC,"${dir}","${dir}../../perlasm");
8require "x86asm.pl";
9require "cbc.pl";
10
11&asm_init($ARGV[0],"cast-586.pl",$ARGV[$#ARGV] eq "386");
12
13$CAST_ROUNDS=16;
14$L="edi";
15$R="esi";
16$K="ebp";
17$tmp1="ecx";
18$tmp2="ebx";
19$tmp3="eax";
20$tmp4="edx";
21$S1="CAST_S_table0";
22$S2="CAST_S_table1";
23$S3="CAST_S_table2";
24$S4="CAST_S_table3";
25
26@F1=("add","xor","sub");
27@F2=("xor","sub","add");
28@F3=("sub","add","xor");
29
30&CAST_encrypt("CAST_encrypt",1);
31&CAST_encrypt("CAST_decrypt",0);
32&cbc("CAST_cbc_encrypt","CAST_encrypt","CAST_decrypt",1,4,5,3,-1,-1);
33
34&asm_finish();
35
36sub CAST_encrypt {
37    local($name,$enc)=@_;
38
39    local($win_ex)=<<"EOF";
40EXTERN	_CAST_S_table0:DWORD
41EXTERN	_CAST_S_table1:DWORD
42EXTERN	_CAST_S_table2:DWORD
43EXTERN	_CAST_S_table3:DWORD
44EOF
45    &main::external_label(
46			  "CAST_S_table0",
47			  "CAST_S_table1",
48			  "CAST_S_table2",
49			  "CAST_S_table3",
50			  );
51
52    &function_begin_B($name,$win_ex);
53
54    &comment("");
55
56    &push("ebp");
57    &push("ebx");
58    &mov($tmp2,&wparam(0));
59    &mov($K,&wparam(1));
60    &push("esi");
61    &push("edi");
62
63    &comment("Load the 2 words");
64    &mov($L,&DWP(0,$tmp2,"",0));
65    &mov($R,&DWP(4,$tmp2,"",0));
66
67    &comment('Get short key flag');
68    &mov($tmp3,&DWP(128,$K,"",0));
69    if($enc) {
70	&push($tmp3);
71    } else {
72	&or($tmp3,$tmp3);
73	&jnz(&label('cast_dec_skip'));
74    }
75
76    &xor($tmp3,	$tmp3);
77
78    # encrypting part
79
80    if ($enc) {
81	&E_CAST( 0,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
82	&E_CAST( 1,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
83	&E_CAST( 2,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
84	&E_CAST( 3,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
85	&E_CAST( 4,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
86	&E_CAST( 5,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
87	&E_CAST( 6,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
88	&E_CAST( 7,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
89	&E_CAST( 8,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
90	&E_CAST( 9,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
91	&E_CAST(10,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
92	&E_CAST(11,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
93	&comment('test short key flag');
94	&pop($tmp4);
95	&or($tmp4,$tmp4);
96	&jnz(&label('cast_enc_done'));
97	&E_CAST(12,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
98	&E_CAST(13,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
99	&E_CAST(14,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
100	&E_CAST(15,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
101    } else {
102	&E_CAST(15,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
103	&E_CAST(14,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
104	&E_CAST(13,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
105	&E_CAST(12,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
106	&set_label('cast_dec_skip');
107	&E_CAST(11,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
108	&E_CAST(10,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
109	&E_CAST( 9,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
110	&E_CAST( 8,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
111	&E_CAST( 7,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
112	&E_CAST( 6,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
113	&E_CAST( 5,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
114	&E_CAST( 4,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
115	&E_CAST( 3,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
116	&E_CAST( 2,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
117	&E_CAST( 1,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
118	&E_CAST( 0,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
119    }
120
121    &set_label('cast_enc_done') if $enc;
122# Why the nop? - Ben 17/1/99
123    &nop();
124    &mov($tmp3,&wparam(0));
125    &mov(&DWP(4,$tmp3,"",0),$L);
126    &mov(&DWP(0,$tmp3,"",0),$R);
127    &function_end($name);
128}
129
130sub E_CAST {
131    local($i,$S,$L,$R,$K,$OP1,$OP2,$OP3,$tmp1,$tmp2,$tmp3,$tmp4)=@_;
132    # Ri needs to have 16 pre added.
133
134    &comment("round $i");
135    &mov(	$tmp4,		&DWP($i*8,$K,"",1));
136
137    &mov(	$tmp1,		&DWP($i*8+4,$K,"",1));
138    &$OP1(	$tmp4,		$R);
139
140    &rotl(	$tmp4,		&LB($tmp1));
141
142    if ($ppro) {
143	&mov(	$tmp2,		$tmp4);		# B
144	&xor(	$tmp1,		$tmp1);
145
146	&movb(	&LB($tmp1),	&HB($tmp4));	# A
147	&and(	$tmp2,		0xff);
148
149	&shr(	$tmp4,		16); 		#
150	&xor(	$tmp3,		$tmp3);
151    } else {
152	&mov(	$tmp2,		$tmp4);		# B
153	&movb(	&LB($tmp1),	&HB($tmp4));	# A	# BAD BAD BAD
154
155	&shr(	$tmp4,		16); 		#
156	&and(	$tmp2,		0xff);
157    }
158
159    &movb(	&LB($tmp3),	&HB($tmp4));	# C	# BAD BAD BAD
160    &and(	$tmp4,		0xff);		# D
161
162    &mov(	$tmp1,		&DWP($S1,"",$tmp1,4));
163    &mov(	$tmp2,		&DWP($S2,"",$tmp2,4));
164
165    &$OP2(	$tmp1,		$tmp2);
166    &mov(	$tmp2,		&DWP($S3,"",$tmp3,4));
167
168    &$OP3(	$tmp1,		$tmp2);
169    &mov(	$tmp2,		&DWP($S4,"",$tmp4,4));
170
171    &$OP1(	$tmp1,		$tmp2);
172    # XXX
173
174    &xor(	$L,		$tmp1);
175    # XXX
176}
177
178