cast-586.pl 4.5 KB

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