Home | History | Annotate | Download | only in perlasm
      1 #!/usr/local/bin/perl
      2 
      3 # void des_ncbc_encrypt(input, output, length, schedule, ivec, enc)
      4 # des_cblock (*input);
      5 # des_cblock (*output);
      6 # long length;
      7 # des_key_schedule schedule;
      8 # des_cblock (*ivec);
      9 # int enc;
     10 #
     11 # calls 
     12 # des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
     13 #
     14 
     15 #&cbc("des_ncbc_encrypt","des_encrypt",0);
     16 #&cbc("BF_cbc_encrypt","BF_encrypt","BF_encrypt",
     17 #	1,4,5,3,5,-1);
     18 #&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",
     19 #	0,4,5,3,5,-1);
     20 #&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",
     21 #	0,6,7,3,4,5);
     22 #
     23 # When doing a cipher that needs bigendian order,
     24 # for encrypt, the iv is kept in bigendian form,
     25 # while for decrypt, it is kept in little endian.
     26 sub cbc
     27 	{
     28 	local($name,$enc_func,$dec_func,$swap,$iv_off,$enc_off,$p1,$p2,$p3)=@_;
     29 	# name is the function name
     30 	# enc_func and dec_func and the functions to call for encrypt/decrypt
     31 	# swap is true if byte order needs to be reversed
     32 	# iv_off is parameter number for the iv 
     33 	# enc_off is parameter number for the encrypt/decrypt flag
     34 	# p1,p2,p3 are the offsets for parameters to be passed to the
     35 	# underlying calls.
     36 
     37 	&function_begin_B($name,"");
     38 	&comment("");
     39 
     40 	$in="esi";
     41 	$out="edi";
     42 	$count="ebp";
     43 
     44 	&push("ebp");
     45 	&push("ebx");
     46 	&push("esi");
     47 	&push("edi");
     48 
     49 	$data_off=4;
     50 	$data_off+=4 if ($p1 > 0);
     51 	$data_off+=4 if ($p2 > 0);
     52 	$data_off+=4 if ($p3 > 0);
     53 
     54 	&mov($count,	&wparam(2));	# length
     55 
     56 	&comment("getting iv ptr from parameter $iv_off");
     57 	&mov("ebx",	&wparam($iv_off));	# Get iv ptr
     58 
     59 	&mov($in,	&DWP(0,"ebx","",0));#	iv[0]
     60 	&mov($out,	&DWP(4,"ebx","",0));#	iv[1]
     61 
     62 	&push($out);
     63 	&push($in);
     64 	&push($out);	# used in decrypt for iv[1]
     65 	&push($in);	# used in decrypt for iv[0]
     66 
     67 	&mov("ebx",	"esp");		# This is the address of tin[2]
     68 
     69 	&mov($in,	&wparam(0));	# in
     70 	&mov($out,	&wparam(1));	# out
     71 
     72 	# We have loaded them all, how lets push things
     73 	&comment("getting encrypt flag from parameter $enc_off");
     74 	&mov("ecx",	&wparam($enc_off));	# Get enc flag
     75 	if ($p3 > 0)
     76 		{
     77 		&comment("get and push parameter $p3");
     78 		if ($enc_off != $p3)
     79 			{ &mov("eax",	&wparam($p3)); &push("eax"); }
     80 		else	{ &push("ecx"); }
     81 		}
     82 	if ($p2 > 0)
     83 		{
     84 		&comment("get and push parameter $p2");
     85 		if ($enc_off != $p2)
     86 			{ &mov("eax",	&wparam($p2)); &push("eax"); }
     87 		else	{ &push("ecx"); }
     88 		}
     89 	if ($p1 > 0)
     90 		{
     91 		&comment("get and push parameter $p1");
     92 		if ($enc_off != $p1)
     93 			{ &mov("eax",	&wparam($p1)); &push("eax"); }
     94 		else	{ &push("ecx"); }
     95 		}
     96 	&push("ebx");		# push data/iv
     97 
     98 	&cmp("ecx",0);
     99 	&jz(&label("decrypt"));
    100 
    101 	&and($count,0xfffffff8);
    102 	&mov("eax",	&DWP($data_off,"esp","",0));	# load iv[0]
    103 	&mov("ebx",	&DWP($data_off+4,"esp","",0));	# load iv[1]
    104 
    105 	&jz(&label("encrypt_finish"));
    106 
    107 	#############################################################
    108 
    109 	&set_label("encrypt_loop");
    110 	# encrypt start 
    111 	# "eax" and "ebx" hold iv (or the last cipher text)
    112 
    113 	&mov("ecx",	&DWP(0,$in,"",0));	# load first 4 bytes
    114 	&mov("edx",	&DWP(4,$in,"",0));	# second 4 bytes
    115 
    116 	&xor("eax",	"ecx");
    117 	&xor("ebx",	"edx");
    118 
    119 	&bswap("eax")	if $swap;
    120 	&bswap("ebx")	if $swap;
    121 
    122 	&mov(&DWP($data_off,"esp","",0),	"eax");	# put in array for call
    123 	&mov(&DWP($data_off+4,"esp","",0),	"ebx");	#
    124 
    125 	&call($enc_func);
    126 
    127 	&mov("eax",	&DWP($data_off,"esp","",0));
    128 	&mov("ebx",	&DWP($data_off+4,"esp","",0));
    129 
    130 	&bswap("eax")	if $swap;
    131 	&bswap("ebx")	if $swap;
    132 
    133 	&mov(&DWP(0,$out,"",0),"eax");
    134 	&mov(&DWP(4,$out,"",0),"ebx");
    135 
    136 	# eax and ebx are the next iv.
    137 
    138 	&add($in,	8);
    139 	&add($out,	8);
    140 
    141 	&sub($count,	8);
    142 	&jnz(&label("encrypt_loop"));
    143 
    144 ###################################################################3
    145 	&set_label("encrypt_finish");
    146 	&mov($count,	&wparam(2));	# length
    147 	&and($count,	7);
    148 	&jz(&label("finish"));
    149 	&call(&label("PIC_point"));
    150 &set_label("PIC_point");
    151 	&blindpop("edx");
    152 	&lea("ecx",&DWP(&label("cbc_enc_jmp_table")."-".&label("PIC_point"),"edx"));
    153 	&mov($count,&DWP(0,"ecx",$count,4));
    154 	&add($count,"edx");
    155 	&xor("ecx","ecx");
    156 	&xor("edx","edx");
    157 	#&mov($count,&DWP(&label("cbc_enc_jmp_table"),"",$count,4));
    158 	&jmp_ptr($count);
    159 
    160 &set_label("ej7");
    161 	&movb(&HB("edx"),	&BP(6,$in,"",0));
    162 	&shl("edx",8);
    163 &set_label("ej6");
    164 	&movb(&HB("edx"),	&BP(5,$in,"",0));
    165 &set_label("ej5");
    166 	&movb(&LB("edx"),	&BP(4,$in,"",0));
    167 &set_label("ej4");
    168 	&mov("ecx",		&DWP(0,$in,"",0));
    169 	&jmp(&label("ejend"));
    170 &set_label("ej3");
    171 	&movb(&HB("ecx"),	&BP(2,$in,"",0));
    172 	&shl("ecx",8);
    173 &set_label("ej2");
    174 	&movb(&HB("ecx"),	&BP(1,$in,"",0));
    175 &set_label("ej1");
    176 	&movb(&LB("ecx"),	&BP(0,$in,"",0));
    177 &set_label("ejend");
    178 
    179 	&xor("eax",	"ecx");
    180 	&xor("ebx",	"edx");
    181 
    182 	&bswap("eax")	if $swap;
    183 	&bswap("ebx")	if $swap;
    184 
    185 	&mov(&DWP($data_off,"esp","",0),	"eax");	# put in array for call
    186 	&mov(&DWP($data_off+4,"esp","",0),	"ebx");	#
    187 
    188 	&call($enc_func);
    189 
    190 	&mov("eax",	&DWP($data_off,"esp","",0));
    191 	&mov("ebx",	&DWP($data_off+4,"esp","",0));
    192 
    193 	&bswap("eax")	if $swap;
    194 	&bswap("ebx")	if $swap;
    195 
    196 	&mov(&DWP(0,$out,"",0),"eax");
    197 	&mov(&DWP(4,$out,"",0),"ebx");
    198 
    199 	&jmp(&label("finish"));
    200 
    201 	#############################################################
    202 	#############################################################
    203 	&set_label("decrypt",1);
    204 	# decrypt start 
    205 	&and($count,0xfffffff8);
    206 	# The next 2 instructions are only for if the jz is taken
    207 	&mov("eax",	&DWP($data_off+8,"esp","",0));	# get iv[0]
    208 	&mov("ebx",	&DWP($data_off+12,"esp","",0));	# get iv[1]
    209 	&jz(&label("decrypt_finish"));
    210 
    211 	&set_label("decrypt_loop");
    212 	&mov("eax",	&DWP(0,$in,"",0));	# load first 4 bytes
    213 	&mov("ebx",	&DWP(4,$in,"",0));	# second 4 bytes
    214 
    215 	&bswap("eax")	if $swap;
    216 	&bswap("ebx")	if $swap;
    217 
    218 	&mov(&DWP($data_off,"esp","",0),	"eax");	# put back
    219 	&mov(&DWP($data_off+4,"esp","",0),	"ebx");	#
    220 
    221 	&call($dec_func);
    222 
    223 	&mov("eax",	&DWP($data_off,"esp","",0));	# get return
    224 	&mov("ebx",	&DWP($data_off+4,"esp","",0));	#
    225 
    226 	&bswap("eax")	if $swap;
    227 	&bswap("ebx")	if $swap;
    228 
    229 	&mov("ecx",	&DWP($data_off+8,"esp","",0));	# get iv[0]
    230 	&mov("edx",	&DWP($data_off+12,"esp","",0));	# get iv[1]
    231 
    232 	&xor("ecx",	"eax");
    233 	&xor("edx",	"ebx");
    234 
    235 	&mov("eax",	&DWP(0,$in,"",0));	# get old cipher text,
    236 	&mov("ebx",	&DWP(4,$in,"",0));	# next iv actually
    237 
    238 	&mov(&DWP(0,$out,"",0),"ecx");
    239 	&mov(&DWP(4,$out,"",0),"edx");
    240 
    241 	&mov(&DWP($data_off+8,"esp","",0),	"eax");	# save iv
    242 	&mov(&DWP($data_off+12,"esp","",0),	"ebx");	#
    243 
    244 	&add($in,	8);
    245 	&add($out,	8);
    246 
    247 	&sub($count,	8);
    248 	&jnz(&label("decrypt_loop"));
    249 ############################ ENDIT #######################3
    250 	&set_label("decrypt_finish");
    251 	&mov($count,	&wparam(2));	# length
    252 	&and($count,	7);
    253 	&jz(&label("finish"));
    254 
    255 	&mov("eax",	&DWP(0,$in,"",0));	# load first 4 bytes
    256 	&mov("ebx",	&DWP(4,$in,"",0));	# second 4 bytes
    257 
    258 	&bswap("eax")	if $swap;
    259 	&bswap("ebx")	if $swap;
    260 
    261 	&mov(&DWP($data_off,"esp","",0),	"eax");	# put back
    262 	&mov(&DWP($data_off+4,"esp","",0),	"ebx");	#
    263 
    264 	&call($dec_func);
    265 
    266 	&mov("eax",	&DWP($data_off,"esp","",0));	# get return
    267 	&mov("ebx",	&DWP($data_off+4,"esp","",0));	#
    268 
    269 	&bswap("eax")	if $swap;
    270 	&bswap("ebx")	if $swap;
    271 
    272 	&mov("ecx",	&DWP($data_off+8,"esp","",0));	# get iv[0]
    273 	&mov("edx",	&DWP($data_off+12,"esp","",0));	# get iv[1]
    274 
    275 	&xor("ecx",	"eax");
    276 	&xor("edx",	"ebx");
    277 
    278 	# this is for when we exit
    279 	&mov("eax",	&DWP(0,$in,"",0));	# get old cipher text,
    280 	&mov("ebx",	&DWP(4,$in,"",0));	# next iv actually
    281 
    282 &set_label("dj7");
    283 	&rotr("edx",	16);
    284 	&movb(&BP(6,$out,"",0),	&LB("edx"));
    285 	&shr("edx",16);
    286 &set_label("dj6");
    287 	&movb(&BP(5,$out,"",0),	&HB("edx"));
    288 &set_label("dj5");
    289 	&movb(&BP(4,$out,"",0),	&LB("edx"));
    290 &set_label("dj4");
    291 	&mov(&DWP(0,$out,"",0),	"ecx");
    292 	&jmp(&label("djend"));
    293 &set_label("dj3");
    294 	&rotr("ecx",	16);
    295 	&movb(&BP(2,$out,"",0),	&LB("ecx"));
    296 	&shl("ecx",16);
    297 &set_label("dj2");
    298 	&movb(&BP(1,$in,"",0),	&HB("ecx"));
    299 &set_label("dj1");
    300 	&movb(&BP(0,$in,"",0),	&LB("ecx"));
    301 &set_label("djend");
    302 
    303 	# final iv is still in eax:ebx
    304 	&jmp(&label("finish"));
    305 
    306 
    307 ############################ FINISH #######################3
    308 	&set_label("finish",1);
    309 	&mov("ecx",	&wparam($iv_off));	# Get iv ptr
    310 
    311 	#################################################
    312 	$total=16+4;
    313 	$total+=4 if ($p1 > 0);
    314 	$total+=4 if ($p2 > 0);
    315 	$total+=4 if ($p3 > 0);
    316 	&add("esp",$total);
    317 
    318 	&mov(&DWP(0,"ecx","",0),	"eax");	# save iv
    319 	&mov(&DWP(4,"ecx","",0),	"ebx");	# save iv
    320 
    321 	&function_end_A($name);
    322 
    323 	&align(64);
    324 	&set_label("cbc_enc_jmp_table");
    325 	&data_word("0");
    326 	&data_word(&label("ej1")."-".&label("PIC_point"));
    327 	&data_word(&label("ej2")."-".&label("PIC_point"));
    328 	&data_word(&label("ej3")."-".&label("PIC_point"));
    329 	&data_word(&label("ej4")."-".&label("PIC_point"));
    330 	&data_word(&label("ej5")."-".&label("PIC_point"));
    331 	&data_word(&label("ej6")."-".&label("PIC_point"));
    332 	&data_word(&label("ej7")."-".&label("PIC_point"));
    333 	# not used
    334 	#&set_label("cbc_dec_jmp_table",1);
    335 	#&data_word("0");
    336 	#&data_word(&label("dj1")."-".&label("PIC_point"));
    337 	#&data_word(&label("dj2")."-".&label("PIC_point"));
    338 	#&data_word(&label("dj3")."-".&label("PIC_point"));
    339 	#&data_word(&label("dj4")."-".&label("PIC_point"));
    340 	#&data_word(&label("dj5")."-".&label("PIC_point"));
    341 	#&data_word(&label("dj6")."-".&label("PIC_point"));
    342 	#&data_word(&label("dj7")."-".&label("PIC_point"));
    343 	&align(64);
    344 
    345 	&function_end_B($name);
    346 	
    347 	}
    348 
    349 1;
    350