Rename des_SPtrans to DES_SPtrans to differentiate from libdes and avoid certain...
[openssl.git] / crypto / des / asm / des686.pl
index efd9f592e978abaf3f1d49d68fddbb6e1a0faa48..d3ad5d5edd5f0507b18c1eabad66c274f1879d38 100644 (file)
 #!/usr/local/bin/perl
-\r
-$prog="des686.pl";\r
-\r
-# base code is in microsft\r
-# op dest, source\r
-# format.\r
-#\r
-\r
-# WILL NOT WORK ANYMORE WITH desboth.pl\r
-require "desboth.pl";\r
-\r
-if (   ($ARGV[0] eq "elf"))\r
-       { require "x86unix.pl"; }\r
-elsif (        ($ARGV[0] eq "a.out"))\r
-       { $aout=1; require "x86unix.pl"; }\r
-elsif (        ($ARGV[0] eq "sol"))\r
-       { $sol=1; require "x86unix.pl"; }\r
-elsif ( ($ARGV[0] eq "cpp"))\r
-       { $cpp=1; require "x86unix.pl"; }\r
-elsif (        ($ARGV[0] eq "win32"))\r
-       { require "x86ms.pl"; }\r
-else\r
-       {\r
-       print STDERR <<"EOF";\r
-Pick one target type from\r
-       elf     - linux, FreeBSD etc\r
-       a.out   - old linux\r
-       sol     - x86 solaris\r
-       cpp     - format so x86unix.cpp can be used\r
-       win32   - Windows 95/Windows NT\r
-EOF\r
-       exit(1);\r
-       }\r
-\r
-&comment("Don't even think of reading this code");\r
-&comment("It was automatically generated by $prog");\r
-&comment("Which is a perl program used to generate the x86 assember for");\r
-&comment("any of elf, a.out, Win32, or Solaris");\r
-&comment("It can be found in SSLeay 0.6.5+ or in libdes 3.26+");\r
-&comment("eric <eay\@cryptsoft.com>");\r
-&comment("");\r
-\r
-&file("dx86xxxx");\r
-\r
-$L="edi";\r
-$R="esi";\r
-\r
-&des_encrypt("des_encrypt",1);\r
-&des_encrypt("des_encrypt2",0);\r
-\r
-&des_encrypt3("des_encrypt3",1);\r
-&des_encrypt3("des_decrypt3",0);\r
-\r
-&file_end();\r
-\r
-sub des_encrypt\r
-       {\r
-       local($name,$do_ip)=@_;\r
-\r
-       &function_begin($name,3,"EXTRN   _des_SPtrans:DWORD");\r
-\r
-       &comment("");\r
-       &comment("Load the 2 words");\r
-       &mov("eax",&wparam(0));\r
-       &mov($L,&DWP(0,"eax","",0));\r
-       &mov($R,&DWP(4,"eax","",0));\r
-\r
-       $ksp=&wparam(1);\r
-\r
-       if ($do_ip)\r
-               {\r
-               &comment("");\r
-               &comment("IP");\r
-               &IP($L,$R,"eax");\r
-               }\r
-\r
-       &comment("");\r
-       &comment("fixup rotate");\r
-       &rotl($R,3);\r
-       &rotl($L,3);\r
-       &exch($L,$R);\r
-\r
-       &comment("");\r
-       &comment("load counter, key_schedule and enc flag");\r
-       &mov("eax",&wparam(2)); # get encrypt flag\r
-       &mov("ebp",&wparam(1)); # get ks\r
-       &cmp("eax","0");\r
-       &je(&label("start_decrypt"));\r
-\r
-       # encrypting part\r
-\r
-       for ($i=0; $i<16; $i+=2)\r
-               {\r
-               &comment("");\r
-               &comment("Round $i");\r
-               &D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");\r
-\r
-               &comment("");\r
-               &comment("Round ".sprintf("%d",$i+1));\r
-               &D_ENCRYPT($R,$L,($i+1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");\r
-               }\r
-       &jmp(&label("end"));\r
-\r
-       &set_label("start_decrypt");\r
-\r
-       for ($i=15; $i>0; $i-=2)\r
-               {\r
-               &comment("");\r
-               &comment("Round $i");\r
-               &D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");\r
-               &comment("");\r
-               &comment("Round ".sprintf("%d",$i-1));\r
-               &D_ENCRYPT($R,$L,($i-1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");\r
-               }\r
-\r
-       &set_label("end");\r
-\r
-       &comment("");\r
-       &comment("Fixup");\r
-       &rotr($L,3);            # r\r
-       &rotr($R,3);            # l\r
-\r
-       if ($do_ip)\r
-               {\r
-               &comment("");\r
-               &comment("FP");\r
-               &FP($R,$L,"eax");\r
-               }\r
-\r
-       &mov("eax",&wparam(0));\r
-       &mov(&DWP(0,"eax","",0),$L);\r
-       &mov(&DWP(4,"eax","",0),$R);\r
-\r
-       &function_end($name);\r
-       }\r
-\r
-\r
-# The logic is to load R into 2 registers and operate on both at the same time.\r
-# We also load the 2 R's into 2 more registers so we can do the 'move word down a byte'\r
-# while also masking the other copy and doing a lookup.  We then also accumulate the\r
-# L value in 2 registers then combine them at the end.\r
-sub D_ENCRYPT\r
-       {\r
-       local($L,$R,$S,$ks,$desSP,$u,$t,$tmp1,$tmp2,$tmp3)=@_;\r
-\r
-       &mov(   $u,             &DWP(&n2a($S*4),$ks,"",0));\r
-       &mov(   $t,             &DWP(&n2a(($S+1)*4),$ks,"",0));\r
-       &xor(   $u,             $R              );\r
-       &xor(   $t,             $R              );\r
-       &rotr(  $t,             4               );\r
-\r
-       # the numbers at the end of the line are origional instruction order\r
-       &mov(   $tmp2,          $u              );                      # 1 2\r
-       &mov(   $tmp1,          $t              );                      # 1 1\r
-       &and(   $tmp2,          "0xfc"          );                      # 1 4\r
-       &and(   $tmp1,          "0xfc"          );                      # 1 3\r
-       &shr(   $t,             8               );                      # 1 5\r
-       &xor(   $L,             &DWP("0x100+$desSP",$tmp1,"",0));       # 1 7\r
-       &shr(   $u,             8               );                      # 1 6\r
-       &mov(   $tmp1,          &DWP("      $desSP",$tmp2,"",0));       # 1 8\r
-\r
-       &mov(   $tmp2,          $u              );                      # 2 2\r
-       &xor(   $L,             $tmp1           );                      # 1 9\r
-       &and(   $tmp2,          "0xfc"          );                      # 2 4\r
-       &mov(   $tmp1,          $t              );                      # 2 1\r
-       &and(   $tmp1,          "0xfc"          );                      # 2 3\r
-       &shr(   $t,             8               );                      # 2 5\r
-       &xor(   $L,             &DWP("0x300+$desSP",$tmp1,"",0));       # 2 7\r
-       &shr(   $u,             8               );                      # 2 6\r
-       &mov(   $tmp1,          &DWP("0x200+$desSP",$tmp2,"",0));       # 2 8\r
-       &mov(   $tmp2,          $u              );                      # 3 2\r
-\r
-       &xor(   $L,             $tmp1           );                      # 2 9\r
-       &and(   $tmp2,          "0xfc"          );                      # 3 4\r
-\r
-       &mov(   $tmp1,          $t              );                      # 3 1 \r
-       &shr(   $u,             8               );                      # 3 6\r
-       &and(   $tmp1,          "0xfc"          );                      # 3 3\r
-       &shr(   $t,             8               );                      # 3 5\r
-       &xor(   $L,             &DWP("0x500+$desSP",$tmp1,"",0));       # 3 7\r
-       &mov(   $tmp1,          &DWP("0x400+$desSP",$tmp2,"",0));       # 3 8\r
-\r
-       &and(   $t,             "0xfc"          );                      # 4 1\r
-       &xor(   $L,             $tmp1           );                      # 3 9\r
-\r
-       &and(   $u,             "0xfc"          );                      # 4 2\r
-       &xor(   $L,             &DWP("0x700+$desSP",$t,"",0));          # 4 3\r
-       &xor(   $L,             &DWP("0x600+$desSP",$u,"",0));          # 4 4\r
-       }\r
-\r
-sub PERM_OP\r
-       {\r
-       local($a,$b,$tt,$shift,$mask)=@_;\r
-\r
-       &mov(   $tt,            $a              );\r
-       &shr(   $tt,            $shift          );\r
-       &xor(   $tt,            $b              );\r
-       &and(   $tt,            $mask           );\r
-       &xor(   $b,             $tt             );\r
-       &shl(   $tt,            $shift          );\r
-       &xor(   $a,             $tt             );\r
-       }\r
-\r
-sub IP\r
-       {\r
-       local($l,$r,$tt)=@_;\r
-\r
-       &PERM_OP($r,$l,$tt, 4,"0x0f0f0f0f");\r
-       &PERM_OP($l,$r,$tt,16,"0x0000ffff");\r
-       &PERM_OP($r,$l,$tt, 2,"0x33333333");\r
-       &PERM_OP($l,$r,$tt, 8,"0x00ff00ff");\r
-       &PERM_OP($r,$l,$tt, 1,"0x55555555");\r
-       }\r
-\r
-sub FP\r
-       {\r
-       local($l,$r,$tt)=@_;\r
-\r
-       &PERM_OP($l,$r,$tt, 1,"0x55555555");\r
-        &PERM_OP($r,$l,$tt, 8,"0x00ff00ff");\r
-        &PERM_OP($l,$r,$tt, 2,"0x33333333");\r
-        &PERM_OP($r,$l,$tt,16,"0x0000ffff");\r
-        &PERM_OP($l,$r,$tt, 4,"0x0f0f0f0f");\r
-       }\r
-\r
-sub n2a\r
-       {\r
-       sprintf("%d",$_[0]);\r
-       }\r
+
+$prog="des686.pl";
+
+# base code is in microsft
+# op dest, source
+# format.
+#
+
+# WILL NOT WORK ANYMORE WITH desboth.pl
+require "desboth.pl";
+
+if (   ($ARGV[0] eq "elf"))
+       { require "x86unix.pl"; }
+elsif (        ($ARGV[0] eq "a.out"))
+       { $aout=1; require "x86unix.pl"; }
+elsif (        ($ARGV[0] eq "sol"))
+       { $sol=1; require "x86unix.pl"; }
+elsif ( ($ARGV[0] eq "cpp"))
+       { $cpp=1; require "x86unix.pl"; }
+elsif (        ($ARGV[0] eq "win32"))
+       { require "x86ms.pl"; }
+else
+       {
+       print STDERR <<"EOF";
+Pick one target type from
+       elf     - linux, FreeBSD etc
+       a.out   - old linux
+       sol     - x86 solaris
+       cpp     - format so x86unix.cpp can be used
+       win32   - Windows 95/Windows NT
+EOF
+       exit(1);
+       }
+
+&comment("Don't even think of reading this code");
+&comment("It was automatically generated by $prog");
+&comment("Which is a perl program used to generate the x86 assember for");
+&comment("any of elf, a.out, Win32, or Solaris");
+&comment("It can be found in SSLeay 0.6.5+ or in libdes 3.26+");
+&comment("eric <eay\@cryptsoft.com>");
+&comment("");
+
+&file("dx86xxxx");
+
+$L="edi";
+$R="esi";
+
+&DES_encrypt("DES_encrypt1",1);
+&DES_encrypt("DES_encrypt2",0);
+
+&DES_encrypt3("DES_encrypt3",1);
+&DES_encrypt3("DES_decrypt3",0);
+
+&file_end();
+
+sub DES_encrypt
+       {
+       local($name,$do_ip)=@_;
+
+       &function_begin($name,"EXTRN   _DES_SPtrans:DWORD");
+
+       &comment("");
+       &comment("Load the 2 words");
+       &mov("eax",&wparam(0));
+       &mov($L,&DWP(0,"eax","",0));
+       &mov($R,&DWP(4,"eax","",0));
+
+       $ksp=&wparam(1);
+
+       if ($do_ip)
+               {
+               &comment("");
+               &comment("IP");
+               &IP_new($L,$R,"eax");
+               }
+
+       &comment("");
+       &comment("fixup rotate");
+       &rotl($R,3);
+       &rotl($L,3);
+       &exch($L,$R);
+
+       &comment("");
+       &comment("load counter, key_schedule and enc flag");
+       &mov("eax",&wparam(2)); # get encrypt flag
+       &mov("ebp",&wparam(1)); # get ks
+       &cmp("eax","0");
+       &je(&label("start_decrypt"));
+
+       # encrypting part
+
+       for ($i=0; $i<16; $i+=2)
+               {
+               &comment("");
+               &comment("Round $i");
+               &D_ENCRYPT($L,$R,$i*2,"ebp","DES_SPtrans","ecx","edx","eax","ebx");
+
+               &comment("");
+               &comment("Round ".sprintf("%d",$i+1));
+               &D_ENCRYPT($R,$L,($i+1)*2,"ebp","DES_SPtrans","ecx","edx","eax","ebx");
+               }
+       &jmp(&label("end"));
+
+       &set_label("start_decrypt");
+
+       for ($i=15; $i>0; $i-=2)
+               {
+               &comment("");
+               &comment("Round $i");
+               &D_ENCRYPT($L,$R,$i*2,"ebp","DES_SPtrans","ecx","edx","eax","ebx");
+               &comment("");
+               &comment("Round ".sprintf("%d",$i-1));
+               &D_ENCRYPT($R,$L,($i-1)*2,"ebp","DES_SPtrans","ecx","edx","eax","ebx");
+               }
+
+       &set_label("end");
+
+       &comment("");
+       &comment("Fixup");
+       &rotr($L,3);            # r
+       &rotr($R,3);            # l
+
+       if ($do_ip)
+               {
+               &comment("");
+               &comment("FP");
+               &FP_new($R,$L,"eax");
+               }
+
+       &mov("eax",&wparam(0));
+       &mov(&DWP(0,"eax","",0),$L);
+       &mov(&DWP(4,"eax","",0),$R);
+
+       &function_end($name);
+       }
+
+
+# The logic is to load R into 2 registers and operate on both at the same time.
+# We also load the 2 R's into 2 more registers so we can do the 'move word down a byte'
+# while also masking the other copy and doing a lookup.  We then also accumulate the
+# L value in 2 registers then combine them at the end.
+sub D_ENCRYPT
+       {
+       local($L,$R,$S,$ks,$desSP,$u,$t,$tmp1,$tmp2,$tmp3)=@_;
+
+       &mov(   $u,             &DWP(&n2a($S*4),$ks,"",0));
+       &mov(   $t,             &DWP(&n2a(($S+1)*4),$ks,"",0));
+       &xor(   $u,             $R              );
+       &xor(   $t,             $R              );
+       &rotr(  $t,             4               );
+
+       # the numbers at the end of the line are origional instruction order
+       &mov(   $tmp2,          $u              );                      # 1 2
+       &mov(   $tmp1,          $t              );                      # 1 1
+       &and(   $tmp2,          "0xfc"          );                      # 1 4
+       &and(   $tmp1,          "0xfc"          );                      # 1 3
+       &shr(   $t,             8               );                      # 1 5
+       &xor(   $L,             &DWP("0x100+$desSP",$tmp1,"",0));       # 1 7
+       &shr(   $u,             8               );                      # 1 6
+       &mov(   $tmp1,          &DWP("      $desSP",$tmp2,"",0));       # 1 8
+
+       &mov(   $tmp2,          $u              );                      # 2 2
+       &xor(   $L,             $tmp1           );                      # 1 9
+       &and(   $tmp2,          "0xfc"          );                      # 2 4
+       &mov(   $tmp1,          $t              );                      # 2 1
+       &and(   $tmp1,          "0xfc"          );                      # 2 3
+       &shr(   $t,             8               );                      # 2 5
+       &xor(   $L,             &DWP("0x300+$desSP",$tmp1,"",0));       # 2 7
+       &shr(   $u,             8               );                      # 2 6
+       &mov(   $tmp1,          &DWP("0x200+$desSP",$tmp2,"",0));       # 2 8
+       &mov(   $tmp2,          $u              );                      # 3 2
+
+       &xor(   $L,             $tmp1           );                      # 2 9
+       &and(   $tmp2,          "0xfc"          );                      # 3 4
+
+       &mov(   $tmp1,          $t              );                      # 3 1 
+       &shr(   $u,             8               );                      # 3 6
+       &and(   $tmp1,          "0xfc"          );                      # 3 3
+       &shr(   $t,             8               );                      # 3 5
+       &xor(   $L,             &DWP("0x500+$desSP",$tmp1,"",0));       # 3 7
+       &mov(   $tmp1,          &DWP("0x400+$desSP",$tmp2,"",0));       # 3 8
+
+       &and(   $t,             "0xfc"          );                      # 4 1
+       &xor(   $L,             $tmp1           );                      # 3 9
+
+       &and(   $u,             "0xfc"          );                      # 4 2
+       &xor(   $L,             &DWP("0x700+$desSP",$t,"",0));          # 4 3
+       &xor(   $L,             &DWP("0x600+$desSP",$u,"",0));          # 4 4
+       }
+
+sub PERM_OP
+       {
+       local($a,$b,$tt,$shift,$mask)=@_;
+
+       &mov(   $tt,            $a              );
+       &shr(   $tt,            $shift          );
+       &xor(   $tt,            $b              );
+       &and(   $tt,            $mask           );
+       &xor(   $b,             $tt             );
+       &shl(   $tt,            $shift          );
+       &xor(   $a,             $tt             );
+       }
+
+sub IP_new
+       {
+       local($l,$r,$tt)=@_;
+
+       &PERM_OP($r,$l,$tt, 4,"0x0f0f0f0f");
+       &PERM_OP($l,$r,$tt,16,"0x0000ffff");
+       &PERM_OP($r,$l,$tt, 2,"0x33333333");
+       &PERM_OP($l,$r,$tt, 8,"0x00ff00ff");
+       &PERM_OP($r,$l,$tt, 1,"0x55555555");
+       }
+
+sub FP_new
+       {
+       local($l,$r,$tt)=@_;
+
+       &PERM_OP($l,$r,$tt, 1,"0x55555555");
+        &PERM_OP($r,$l,$tt, 8,"0x00ff00ff");
+        &PERM_OP($l,$r,$tt, 2,"0x33333333");
+        &PERM_OP($r,$l,$tt,16,"0x0000ffff");
+        &PERM_OP($l,$r,$tt, 4,"0x0f0f0f0f");
+       }
+
+sub n2a
+       {
+       sprintf("%d",$_[0]);
+       }