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