1#! /usr/bin/env perl 2# Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. 3# 4# Licensed under the Apache License 2.0 (the "License"). You may not use 5# this file except in compliance with the License. You can obtain a copy 6# in the file LICENSE in the source distribution or at 7# https://www.openssl.org/source/license.html 8 9 10# This flag makes the inner loop one cycle longer, but generates 11# code that runs %30 faster on the pentium pro/II, 44% faster 12# of PIII, while only %7 slower on the pentium. 13# By default, this flag is on. 14$ppro=1; 15 16$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; 17push(@INC,"${dir}","${dir}../../perlasm"); 18require "x86asm.pl"; 19require "cbc.pl"; 20 21$output=pop and open STDOUT,">$output"; 22 23&asm_init($ARGV[0],$ARGV[$#ARGV] eq "386"); 24 25$CAST_ROUNDS=16; 26$L="edi"; 27$R="esi"; 28$K="ebp"; 29$tmp1="ecx"; 30$tmp2="ebx"; 31$tmp3="eax"; 32$tmp4="edx"; 33$S1="CAST_S_table0"; 34$S2="CAST_S_table1"; 35$S3="CAST_S_table2"; 36$S4="CAST_S_table3"; 37 38@F1=("add","xor","sub"); 39@F2=("xor","sub","add"); 40@F3=("sub","add","xor"); 41 42&CAST_encrypt("CAST_encrypt",1); 43&CAST_encrypt("CAST_decrypt",0); 44&cbc("CAST_cbc_encrypt","CAST_encrypt","CAST_decrypt",1,4,5,3,-1,-1); 45 46&asm_finish(); 47 48close STDOUT or die "error closing STDOUT: $!"; 49 50sub CAST_encrypt { 51 local($name,$enc)=@_; 52 53 local($win_ex)=<<"EOF"; 54EXTERN _CAST_S_table0:DWORD 55EXTERN _CAST_S_table1:DWORD 56EXTERN _CAST_S_table2:DWORD 57EXTERN _CAST_S_table3:DWORD 58EOF 59 &main::external_label( 60 "CAST_S_table0", 61 "CAST_S_table1", 62 "CAST_S_table2", 63 "CAST_S_table3", 64 ); 65 66 &function_begin_B($name,$win_ex); 67 68 &comment(""); 69 70 &push("ebp"); 71 &push("ebx"); 72 &mov($tmp2,&wparam(0)); 73 &mov($K,&wparam(1)); 74 &push("esi"); 75 &push("edi"); 76 77 &comment("Load the 2 words"); 78 &mov($L,&DWP(0,$tmp2,"",0)); 79 &mov($R,&DWP(4,$tmp2,"",0)); 80 81 &comment('Get short key flag'); 82 &mov($tmp3,&DWP(128,$K,"",0)); 83 if($enc) { 84 &push($tmp3); 85 } else { 86 &or($tmp3,$tmp3); 87 &jnz(&label('cast_dec_skip')); 88 } 89 90 &xor($tmp3, $tmp3); 91 92 # encrypting part 93 94 if ($enc) { 95 &E_CAST( 0,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); 96 &E_CAST( 1,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); 97 &E_CAST( 2,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); 98 &E_CAST( 3,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); 99 &E_CAST( 4,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); 100 &E_CAST( 5,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); 101 &E_CAST( 6,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); 102 &E_CAST( 7,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); 103 &E_CAST( 8,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); 104 &E_CAST( 9,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); 105 &E_CAST(10,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); 106 &E_CAST(11,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); 107 &comment('test short key flag'); 108 &pop($tmp4); 109 &or($tmp4,$tmp4); 110 &jnz(&label('cast_enc_done')); 111 &E_CAST(12,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); 112 &E_CAST(13,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); 113 &E_CAST(14,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); 114 &E_CAST(15,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); 115 } else { 116 &E_CAST(15,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); 117 &E_CAST(14,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); 118 &E_CAST(13,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); 119 &E_CAST(12,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); 120 &set_label('cast_dec_skip'); 121 &E_CAST(11,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); 122 &E_CAST(10,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); 123 &E_CAST( 9,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); 124 &E_CAST( 8,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); 125 &E_CAST( 7,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); 126 &E_CAST( 6,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); 127 &E_CAST( 5,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); 128 &E_CAST( 4,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); 129 &E_CAST( 3,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); 130 &E_CAST( 2,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); 131 &E_CAST( 1,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); 132 &E_CAST( 0,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); 133 } 134 135 &set_label('cast_enc_done') if $enc; 136# Why the nop? - Ben 17/1/99 137 &nop(); 138 &mov($tmp3,&wparam(0)); 139 &mov(&DWP(4,$tmp3,"",0),$L); 140 &mov(&DWP(0,$tmp3,"",0),$R); 141 &function_end($name); 142} 143 144sub E_CAST { 145 local($i,$S,$L,$R,$K,$OP1,$OP2,$OP3,$tmp1,$tmp2,$tmp3,$tmp4)=@_; 146 # Ri needs to have 16 pre added. 147 148 &comment("round $i"); 149 &mov( $tmp4, &DWP($i*8,$K,"",1)); 150 151 &mov( $tmp1, &DWP($i*8+4,$K,"",1)); 152 &$OP1( $tmp4, $R); 153 154 &rotl( $tmp4, &LB($tmp1)); 155 156 if ($ppro) { 157 &xor( $tmp1, $tmp1); 158 &mov( $tmp2, 0xff); 159 160 &movb( &LB($tmp1), &HB($tmp4)); # A 161 &and( $tmp2, $tmp4); 162 163 &shr( $tmp4, 16); # 164 &xor( $tmp3, $tmp3); 165 } else { 166 &mov( $tmp2, $tmp4); # B 167 &movb( &LB($tmp1), &HB($tmp4)); # A # BAD BAD BAD 168 169 &shr( $tmp4, 16); # 170 &and( $tmp2, 0xff); 171 } 172 173 &movb( &LB($tmp3), &HB($tmp4)); # C # BAD BAD BAD 174 &and( $tmp4, 0xff); # D 175 176 &mov( $tmp1, &DWP($S1,"",$tmp1,4)); 177 &mov( $tmp2, &DWP($S2,"",$tmp2,4)); 178 179 &$OP2( $tmp1, $tmp2); 180 &mov( $tmp2, &DWP($S3,"",$tmp3,4)); 181 182 &$OP3( $tmp1, $tmp2); 183 &mov( $tmp2, &DWP($S4,"",$tmp4,4)); 184 185 &$OP1( $tmp1, $tmp2); 186 # XXX 187 188 &xor( $L, $tmp1); 189 # XXX 190} 191 192