1#!/usr/local/bin/perl 2 3push(@INC,"perlasm","../../perlasm"); 4require "x86asm.pl"; 5require "cbc.pl"; 6 7&asm_init($ARGV[0],"rc5-586.pl"); 8 9$RC5_MAX_ROUNDS=16; 10$RC5_32_OFF=($RC5_MAX_ROUNDS+2)*4; 11$A="edi"; 12$B="esi"; 13$S="ebp"; 14$tmp1="eax"; 15$r="ebx"; 16$tmpc="ecx"; 17$tmp4="edx"; 18 19&RC5_32_encrypt("RC5_32_encrypt",1); 20&RC5_32_encrypt("RC5_32_decrypt",0); 21&cbc("RC5_32_cbc_encrypt","RC5_32_encrypt","RC5_32_decrypt",0,4,5,3,-1,-1); 22&asm_finish(); 23 24sub RC5_32_encrypt 25 { 26 local($name,$enc)=@_; 27 28 &function_begin_B($name,""); 29 30 &comment(""); 31 32 &push("ebp"); 33 &push("esi"); 34 &push("edi"); 35 &mov($tmp4,&wparam(0)); 36 &mov($S,&wparam(1)); 37 38 &comment("Load the 2 words"); 39 &mov($A,&DWP(0,$tmp4,"",0)); 40 &mov($B,&DWP(4,$tmp4,"",0)); 41 42 &push($r); 43 &mov($r, &DWP(0,$S,"",0)); 44 45 # encrypting part 46 47 if ($enc) 48 { 49 &add($A, &DWP(4+0,$S,"",0)); 50 &add($B, &DWP(4+4,$S,"",0)); 51 52 for ($i=0; $i<$RC5_MAX_ROUNDS; $i++) 53 { 54 &xor($A, $B); 55 &mov($tmp1, &DWP(12+$i*8,$S,"",0)); 56 &mov($tmpc, $B); 57 &rotl($A, &LB("ecx")); 58 &add($A, $tmp1); 59 60 &xor($B, $A); 61 &mov($tmp1, &DWP(16+$i*8,$S,"",0)); 62 &mov($tmpc, $A); 63 &rotl($B, &LB("ecx")); 64 &add($B, $tmp1); 65 if (($i == 7) || ($i == 11)) 66 { 67 &cmp($r, $i+1); 68 &je(&label("rc5_exit")); 69 } 70 } 71 } 72 else 73 { 74 &cmp($r, 12); 75 &je(&label("rc5_dec_12")); 76 &cmp($r, 8); 77 &je(&label("rc5_dec_8")); 78 for ($i=$RC5_MAX_ROUNDS; $i > 0; $i--) 79 { 80 &set_label("rc5_dec_$i") if ($i == 12) || ($i == 8); 81 &mov($tmp1, &DWP($i*8+8,$S,"",0)); 82 &sub($B, $tmp1); 83 &mov($tmpc, $A); 84 &rotr($B, &LB("ecx")); 85 &xor($B, $A); 86 87 &mov($tmp1, &DWP($i*8+4,$S,"",0)); 88 &sub($A, $tmp1); 89 &mov($tmpc, $B); 90 &rotr($A, &LB("ecx")); 91 &xor($A, $B); 92 } 93 &sub($B, &DWP(4+4,$S,"",0)); 94 &sub($A, &DWP(4+0,$S,"",0)); 95 } 96 97 &set_label("rc5_exit"); 98 &mov(&DWP(0,$tmp4,"",0),$A); 99 &mov(&DWP(4,$tmp4,"",0),$B); 100 101 &pop("ebx"); 102 &pop("edi"); 103 &pop("esi"); 104 &pop("ebp"); 105 &ret(); 106 &function_end_B($name); 107 } 108 109 110