Import of old SSLeay release: SSLeay 0.8.1b
[openssl.git] / crypto / des / asm / des686.pl
1 #!/usr/local/bin/perl
2 \r
3 $prog="des686.pl";\r
4 \r
5 # base code is in microsft\r
6 # op dest, source\r
7 # format.\r
8 #\r
9 \r
10 # WILL NOT WORK ANYMORE WITH desboth.pl\r
11 require "desboth.pl";\r
12 \r
13 if (    ($ARGV[0] eq "elf"))\r
14         { require "x86unix.pl"; }\r
15 elsif ( ($ARGV[0] eq "a.out"))\r
16         { $aout=1; require "x86unix.pl"; }\r
17 elsif ( ($ARGV[0] eq "sol"))\r
18         { $sol=1; require "x86unix.pl"; }\r
19 elsif ( ($ARGV[0] eq "cpp"))\r
20         { $cpp=1; require "x86unix.pl"; }\r
21 elsif ( ($ARGV[0] eq "win32"))\r
22         { require "x86ms.pl"; }\r
23 else\r
24         {\r
25         print STDERR <<"EOF";\r
26 Pick one target type from\r
27         elf     - linux, FreeBSD etc\r
28         a.out   - old linux\r
29         sol     - x86 solaris\r
30         cpp     - format so x86unix.cpp can be used\r
31         win32   - Windows 95/Windows NT\r
32 EOF\r
33         exit(1);\r
34         }\r
35 \r
36 &comment("Don't even think of reading this code");\r
37 &comment("It was automatically generated by $prog");\r
38 &comment("Which is a perl program used to generate the x86 assember for");\r
39 &comment("any of elf, a.out, Win32, or Solaris");\r
40 &comment("It can be found in SSLeay 0.6.5+ or in libdes 3.26+");\r
41 &comment("eric <eay\@cryptsoft.com>");\r
42 &comment("");\r
43 \r
44 &file("dx86xxxx");\r
45 \r
46 $L="edi";\r
47 $R="esi";\r
48 \r
49 &des_encrypt("des_encrypt",1);\r
50 &des_encrypt("des_encrypt2",0);\r
51 \r
52 &des_encrypt3("des_encrypt3",1);\r
53 &des_encrypt3("des_decrypt3",0);\r
54 \r
55 &file_end();\r
56 \r
57 sub des_encrypt\r
58         {\r
59         local($name,$do_ip)=@_;\r
60 \r
61         &function_begin($name,3,"EXTRN   _des_SPtrans:DWORD");\r
62 \r
63         &comment("");\r
64         &comment("Load the 2 words");\r
65         &mov("eax",&wparam(0));\r
66         &mov($L,&DWP(0,"eax","",0));\r
67         &mov($R,&DWP(4,"eax","",0));\r
68 \r
69         $ksp=&wparam(1);\r
70 \r
71         if ($do_ip)\r
72                 {\r
73                 &comment("");\r
74                 &comment("IP");\r
75                 &IP($L,$R,"eax");\r
76                 }\r
77 \r
78         &comment("");\r
79         &comment("fixup rotate");\r
80         &rotl($R,3);\r
81         &rotl($L,3);\r
82         &exch($L,$R);\r
83 \r
84         &comment("");\r
85         &comment("load counter, key_schedule and enc flag");\r
86         &mov("eax",&wparam(2)); # get encrypt flag\r
87         &mov("ebp",&wparam(1)); # get ks\r
88         &cmp("eax","0");\r
89         &je(&label("start_decrypt"));\r
90 \r
91         # encrypting part\r
92 \r
93         for ($i=0; $i<16; $i+=2)\r
94                 {\r
95                 &comment("");\r
96                 &comment("Round $i");\r
97                 &D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");\r
98 \r
99                 &comment("");\r
100                 &comment("Round ".sprintf("%d",$i+1));\r
101                 &D_ENCRYPT($R,$L,($i+1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");\r
102                 }\r
103         &jmp(&label("end"));\r
104 \r
105         &set_label("start_decrypt");\r
106 \r
107         for ($i=15; $i>0; $i-=2)\r
108                 {\r
109                 &comment("");\r
110                 &comment("Round $i");\r
111                 &D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");\r
112                 &comment("");\r
113                 &comment("Round ".sprintf("%d",$i-1));\r
114                 &D_ENCRYPT($R,$L,($i-1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");\r
115                 }\r
116 \r
117         &set_label("end");\r
118 \r
119         &comment("");\r
120         &comment("Fixup");\r
121         &rotr($L,3);            # r\r
122         &rotr($R,3);            # l\r
123 \r
124         if ($do_ip)\r
125                 {\r
126                 &comment("");\r
127                 &comment("FP");\r
128                 &FP($R,$L,"eax");\r
129                 }\r
130 \r
131         &mov("eax",&wparam(0));\r
132         &mov(&DWP(0,"eax","",0),$L);\r
133         &mov(&DWP(4,"eax","",0),$R);\r
134 \r
135         &function_end($name);\r
136         }\r
137 \r
138 \r
139 # The logic is to load R into 2 registers and operate on both at the same time.\r
140 # We also load the 2 R's into 2 more registers so we can do the 'move word down a byte'\r
141 # while also masking the other copy and doing a lookup.  We then also accumulate the\r
142 # L value in 2 registers then combine them at the end.\r
143 sub D_ENCRYPT\r
144         {\r
145         local($L,$R,$S,$ks,$desSP,$u,$t,$tmp1,$tmp2,$tmp3)=@_;\r
146 \r
147         &mov(   $u,             &DWP(&n2a($S*4),$ks,"",0));\r
148         &mov(   $t,             &DWP(&n2a(($S+1)*4),$ks,"",0));\r
149         &xor(   $u,             $R              );\r
150         &xor(   $t,             $R              );\r
151         &rotr(  $t,             4               );\r
152 \r
153         # the numbers at the end of the line are origional instruction order\r
154         &mov(   $tmp2,          $u              );                      # 1 2\r
155         &mov(   $tmp1,          $t              );                      # 1 1\r
156         &and(   $tmp2,          "0xfc"          );                      # 1 4\r
157         &and(   $tmp1,          "0xfc"          );                      # 1 3\r
158         &shr(   $t,             8               );                      # 1 5\r
159         &xor(   $L,             &DWP("0x100+$desSP",$tmp1,"",0));       # 1 7\r
160         &shr(   $u,             8               );                      # 1 6\r
161         &mov(   $tmp1,          &DWP("      $desSP",$tmp2,"",0));       # 1 8\r
162 \r
163         &mov(   $tmp2,          $u              );                      # 2 2\r
164         &xor(   $L,             $tmp1           );                      # 1 9\r
165         &and(   $tmp2,          "0xfc"          );                      # 2 4\r
166         &mov(   $tmp1,          $t              );                      # 2 1\r
167         &and(   $tmp1,          "0xfc"          );                      # 2 3\r
168         &shr(   $t,             8               );                      # 2 5\r
169         &xor(   $L,             &DWP("0x300+$desSP",$tmp1,"",0));       # 2 7\r
170         &shr(   $u,             8               );                      # 2 6\r
171         &mov(   $tmp1,          &DWP("0x200+$desSP",$tmp2,"",0));       # 2 8\r
172         &mov(   $tmp2,          $u              );                      # 3 2\r
173 \r
174         &xor(   $L,             $tmp1           );                      # 2 9\r
175         &and(   $tmp2,          "0xfc"          );                      # 3 4\r
176 \r
177         &mov(   $tmp1,          $t              );                      # 3 1 \r
178         &shr(   $u,             8               );                      # 3 6\r
179         &and(   $tmp1,          "0xfc"          );                      # 3 3\r
180         &shr(   $t,             8               );                      # 3 5\r
181         &xor(   $L,             &DWP("0x500+$desSP",$tmp1,"",0));       # 3 7\r
182         &mov(   $tmp1,          &DWP("0x400+$desSP",$tmp2,"",0));       # 3 8\r
183 \r
184         &and(   $t,             "0xfc"          );                      # 4 1\r
185         &xor(   $L,             $tmp1           );                      # 3 9\r
186 \r
187         &and(   $u,             "0xfc"          );                      # 4 2\r
188         &xor(   $L,             &DWP("0x700+$desSP",$t,"",0));          # 4 3\r
189         &xor(   $L,             &DWP("0x600+$desSP",$u,"",0));          # 4 4\r
190         }\r
191 \r
192 sub PERM_OP\r
193         {\r
194         local($a,$b,$tt,$shift,$mask)=@_;\r
195 \r
196         &mov(   $tt,            $a              );\r
197         &shr(   $tt,            $shift          );\r
198         &xor(   $tt,            $b              );\r
199         &and(   $tt,            $mask           );\r
200         &xor(   $b,             $tt             );\r
201         &shl(   $tt,            $shift          );\r
202         &xor(   $a,             $tt             );\r
203         }\r
204 \r
205 sub IP\r
206         {\r
207         local($l,$r,$tt)=@_;\r
208 \r
209         &PERM_OP($r,$l,$tt, 4,"0x0f0f0f0f");\r
210         &PERM_OP($l,$r,$tt,16,"0x0000ffff");\r
211         &PERM_OP($r,$l,$tt, 2,"0x33333333");\r
212         &PERM_OP($l,$r,$tt, 8,"0x00ff00ff");\r
213         &PERM_OP($r,$l,$tt, 1,"0x55555555");\r
214         }\r
215 \r
216 sub FP\r
217         {\r
218         local($l,$r,$tt)=@_;\r
219 \r
220         &PERM_OP($l,$r,$tt, 1,"0x55555555");\r
221         &PERM_OP($r,$l,$tt, 8,"0x00ff00ff");\r
222         &PERM_OP($l,$r,$tt, 2,"0x33333333");\r
223         &PERM_OP($r,$l,$tt,16,"0x0000ffff");\r
224         &PERM_OP($l,$r,$tt, 4,"0x0f0f0f0f");\r
225         }\r
226 \r
227 sub n2a\r
228         {\r
229         sprintf("%d",$_[0]);\r
230         }\r