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