xref: /onnv-gate/usr/src/common/openssl/crypto/perlasm/cbc.pl (revision 2139:6243c3338933)
10Sstevel@tonic-gate#!/usr/local/bin/perl
20Sstevel@tonic-gate
30Sstevel@tonic-gate# void des_ncbc_encrypt(input, output, length, schedule, ivec, enc)
40Sstevel@tonic-gate# des_cblock (*input);
50Sstevel@tonic-gate# des_cblock (*output);
60Sstevel@tonic-gate# long length;
70Sstevel@tonic-gate# des_key_schedule schedule;
80Sstevel@tonic-gate# des_cblock (*ivec);
90Sstevel@tonic-gate# int enc;
100Sstevel@tonic-gate#
110Sstevel@tonic-gate# calls
120Sstevel@tonic-gate# des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
130Sstevel@tonic-gate#
140Sstevel@tonic-gate
150Sstevel@tonic-gate#&cbc("des_ncbc_encrypt","des_encrypt",0);
160Sstevel@tonic-gate#&cbc("BF_cbc_encrypt","BF_encrypt","BF_encrypt",
170Sstevel@tonic-gate#	1,4,5,3,5,-1);
180Sstevel@tonic-gate#&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",
190Sstevel@tonic-gate#	0,4,5,3,5,-1);
200Sstevel@tonic-gate#&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",
210Sstevel@tonic-gate#	0,6,7,3,4,5);
220Sstevel@tonic-gate#
230Sstevel@tonic-gate# When doing a cipher that needs bigendian order,
240Sstevel@tonic-gate# for encrypt, the iv is kept in bigendian form,
250Sstevel@tonic-gate# while for decrypt, it is kept in little endian.
260Sstevel@tonic-gatesub cbc
270Sstevel@tonic-gate	{
280Sstevel@tonic-gate	local($name,$enc_func,$dec_func,$swap,$iv_off,$enc_off,$p1,$p2,$p3)=@_;
290Sstevel@tonic-gate	# name is the function name
300Sstevel@tonic-gate	# enc_func and dec_func and the functions to call for encrypt/decrypt
310Sstevel@tonic-gate	# swap is true if byte order needs to be reversed
320Sstevel@tonic-gate	# iv_off is parameter number for the iv
330Sstevel@tonic-gate	# enc_off is parameter number for the encrypt/decrypt flag
340Sstevel@tonic-gate	# p1,p2,p3 are the offsets for parameters to be passed to the
350Sstevel@tonic-gate	# underlying calls.
360Sstevel@tonic-gate
370Sstevel@tonic-gate	&function_begin_B($name,"");
380Sstevel@tonic-gate	&comment("");
390Sstevel@tonic-gate
400Sstevel@tonic-gate	$in="esi";
410Sstevel@tonic-gate	$out="edi";
420Sstevel@tonic-gate	$count="ebp";
430Sstevel@tonic-gate
440Sstevel@tonic-gate	&push("ebp");
450Sstevel@tonic-gate	&push("ebx");
460Sstevel@tonic-gate	&push("esi");
470Sstevel@tonic-gate	&push("edi");
480Sstevel@tonic-gate
490Sstevel@tonic-gate	$data_off=4;
500Sstevel@tonic-gate	$data_off+=4 if ($p1 > 0);
510Sstevel@tonic-gate	$data_off+=4 if ($p2 > 0);
520Sstevel@tonic-gate	$data_off+=4 if ($p3 > 0);
530Sstevel@tonic-gate
540Sstevel@tonic-gate	&mov($count,	&wparam(2));	# length
550Sstevel@tonic-gate
560Sstevel@tonic-gate	&comment("getting iv ptr from parameter $iv_off");
570Sstevel@tonic-gate	&mov("ebx",	&wparam($iv_off));	# Get iv ptr
580Sstevel@tonic-gate
590Sstevel@tonic-gate	&mov($in,	&DWP(0,"ebx","",0));#	iv[0]
600Sstevel@tonic-gate	&mov($out,	&DWP(4,"ebx","",0));#	iv[1]
610Sstevel@tonic-gate
620Sstevel@tonic-gate	&push($out);
630Sstevel@tonic-gate	&push($in);
640Sstevel@tonic-gate	&push($out);	# used in decrypt for iv[1]
650Sstevel@tonic-gate	&push($in);	# used in decrypt for iv[0]
660Sstevel@tonic-gate
670Sstevel@tonic-gate	&mov("ebx",	"esp");		# This is the address of tin[2]
680Sstevel@tonic-gate
690Sstevel@tonic-gate	&mov($in,	&wparam(0));	# in
700Sstevel@tonic-gate	&mov($out,	&wparam(1));	# out
710Sstevel@tonic-gate
720Sstevel@tonic-gate	# We have loaded them all, how lets push things
730Sstevel@tonic-gate	&comment("getting encrypt flag from parameter $enc_off");
740Sstevel@tonic-gate	&mov("ecx",	&wparam($enc_off));	# Get enc flag
750Sstevel@tonic-gate	if ($p3 > 0)
760Sstevel@tonic-gate		{
770Sstevel@tonic-gate		&comment("get and push parameter $p3");
780Sstevel@tonic-gate		if ($enc_off != $p3)
790Sstevel@tonic-gate			{ &mov("eax",	&wparam($p3)); &push("eax"); }
800Sstevel@tonic-gate		else	{ &push("ecx"); }
810Sstevel@tonic-gate		}
820Sstevel@tonic-gate	if ($p2 > 0)
830Sstevel@tonic-gate		{
840Sstevel@tonic-gate		&comment("get and push parameter $p2");
850Sstevel@tonic-gate		if ($enc_off != $p2)
860Sstevel@tonic-gate			{ &mov("eax",	&wparam($p2)); &push("eax"); }
870Sstevel@tonic-gate		else	{ &push("ecx"); }
880Sstevel@tonic-gate		}
890Sstevel@tonic-gate	if ($p1 > 0)
900Sstevel@tonic-gate		{
910Sstevel@tonic-gate		&comment("get and push parameter $p1");
920Sstevel@tonic-gate		if ($enc_off != $p1)
930Sstevel@tonic-gate			{ &mov("eax",	&wparam($p1)); &push("eax"); }
940Sstevel@tonic-gate		else	{ &push("ecx"); }
950Sstevel@tonic-gate		}
960Sstevel@tonic-gate	&push("ebx");		# push data/iv
970Sstevel@tonic-gate
980Sstevel@tonic-gate	&cmp("ecx",0);
990Sstevel@tonic-gate	&jz(&label("decrypt"));
1000Sstevel@tonic-gate
1010Sstevel@tonic-gate	&and($count,0xfffffff8);
1020Sstevel@tonic-gate	&mov("eax",	&DWP($data_off,"esp","",0));	# load iv[0]
1030Sstevel@tonic-gate	&mov("ebx",	&DWP($data_off+4,"esp","",0));	# load iv[1]
1040Sstevel@tonic-gate
1050Sstevel@tonic-gate	&jz(&label("encrypt_finish"));
1060Sstevel@tonic-gate
1070Sstevel@tonic-gate	#############################################################
1080Sstevel@tonic-gate
1090Sstevel@tonic-gate	&set_label("encrypt_loop");
1100Sstevel@tonic-gate	# encrypt start
1110Sstevel@tonic-gate	# "eax" and "ebx" hold iv (or the last cipher text)
1120Sstevel@tonic-gate
1130Sstevel@tonic-gate	&mov("ecx",	&DWP(0,$in,"",0));	# load first 4 bytes
1140Sstevel@tonic-gate	&mov("edx",	&DWP(4,$in,"",0));	# second 4 bytes
1150Sstevel@tonic-gate
1160Sstevel@tonic-gate	&xor("eax",	"ecx");
1170Sstevel@tonic-gate	&xor("ebx",	"edx");
1180Sstevel@tonic-gate
1190Sstevel@tonic-gate	&bswap("eax")	if $swap;
1200Sstevel@tonic-gate	&bswap("ebx")	if $swap;
1210Sstevel@tonic-gate
1220Sstevel@tonic-gate	&mov(&DWP($data_off,"esp","",0),	"eax");	# put in array for call
1230Sstevel@tonic-gate	&mov(&DWP($data_off+4,"esp","",0),	"ebx");	#
1240Sstevel@tonic-gate
1250Sstevel@tonic-gate	&call($enc_func);
1260Sstevel@tonic-gate
1270Sstevel@tonic-gate	&mov("eax",	&DWP($data_off,"esp","",0));
1280Sstevel@tonic-gate	&mov("ebx",	&DWP($data_off+4,"esp","",0));
1290Sstevel@tonic-gate
1300Sstevel@tonic-gate	&bswap("eax")	if $swap;
1310Sstevel@tonic-gate	&bswap("ebx")	if $swap;
1320Sstevel@tonic-gate
1330Sstevel@tonic-gate	&mov(&DWP(0,$out,"",0),"eax");
1340Sstevel@tonic-gate	&mov(&DWP(4,$out,"",0),"ebx");
1350Sstevel@tonic-gate
1360Sstevel@tonic-gate	# eax and ebx are the next iv.
1370Sstevel@tonic-gate
1380Sstevel@tonic-gate	&add($in,	8);
1390Sstevel@tonic-gate	&add($out,	8);
1400Sstevel@tonic-gate
1410Sstevel@tonic-gate	&sub($count,	8);
1420Sstevel@tonic-gate	&jnz(&label("encrypt_loop"));
1430Sstevel@tonic-gate
1440Sstevel@tonic-gate###################################################################3
1450Sstevel@tonic-gate	&set_label("encrypt_finish");
1460Sstevel@tonic-gate	&mov($count,	&wparam(2));	# length
1470Sstevel@tonic-gate	&and($count,	7);
1480Sstevel@tonic-gate	&jz(&label("finish"));
1490Sstevel@tonic-gate	&call(&label("PIC_point"));
1500Sstevel@tonic-gate&set_label("PIC_point");
1510Sstevel@tonic-gate	&blindpop("edx");
1520Sstevel@tonic-gate	&lea("ecx",&DWP(&label("cbc_enc_jmp_table")."-".&label("PIC_point"),"edx"));
1530Sstevel@tonic-gate	&mov($count,&DWP(0,"ecx",$count,4))
1540Sstevel@tonic-gate	&add($count,"edx");
1550Sstevel@tonic-gate	&xor("ecx","ecx");
1560Sstevel@tonic-gate	&xor("edx","edx");
1570Sstevel@tonic-gate	#&mov($count,&DWP(&label("cbc_enc_jmp_table"),"",$count,4));
1580Sstevel@tonic-gate	&jmp_ptr($count);
1590Sstevel@tonic-gate
1600Sstevel@tonic-gate&set_label("ej7");
1610Sstevel@tonic-gate	&xor("edx",		"edx") if $ppro; # ppro friendly
1620Sstevel@tonic-gate	&movb(&HB("edx"),	&BP(6,$in,"",0));
1630Sstevel@tonic-gate	&shl("edx",8);
1640Sstevel@tonic-gate&set_label("ej6");
1650Sstevel@tonic-gate	&movb(&HB("edx"),	&BP(5,$in,"",0));
1660Sstevel@tonic-gate&set_label("ej5");
1670Sstevel@tonic-gate	&movb(&LB("edx"),	&BP(4,$in,"",0));
1680Sstevel@tonic-gate&set_label("ej4");
1690Sstevel@tonic-gate	&mov("ecx",		&DWP(0,$in,"",0));
1700Sstevel@tonic-gate	&jmp(&label("ejend"));
1710Sstevel@tonic-gate&set_label("ej3");
1720Sstevel@tonic-gate	&movb(&HB("ecx"),	&BP(2,$in,"",0));
1730Sstevel@tonic-gate	&xor("ecx",		"ecx") if $ppro; # ppro friendly
1740Sstevel@tonic-gate	&shl("ecx",8);
1750Sstevel@tonic-gate&set_label("ej2");
1760Sstevel@tonic-gate	&movb(&HB("ecx"),	&BP(1,$in,"",0));
1770Sstevel@tonic-gate&set_label("ej1");
1780Sstevel@tonic-gate	&movb(&LB("ecx"),	&BP(0,$in,"",0));
1790Sstevel@tonic-gate&set_label("ejend");
1800Sstevel@tonic-gate
1810Sstevel@tonic-gate	&xor("eax",	"ecx");
1820Sstevel@tonic-gate	&xor("ebx",	"edx");
1830Sstevel@tonic-gate
1840Sstevel@tonic-gate	&bswap("eax")	if $swap;
1850Sstevel@tonic-gate	&bswap("ebx")	if $swap;
1860Sstevel@tonic-gate
1870Sstevel@tonic-gate	&mov(&DWP($data_off,"esp","",0),	"eax");	# put in array for call
1880Sstevel@tonic-gate	&mov(&DWP($data_off+4,"esp","",0),	"ebx");	#
1890Sstevel@tonic-gate
1900Sstevel@tonic-gate	&call($enc_func);
1910Sstevel@tonic-gate
1920Sstevel@tonic-gate	&mov("eax",	&DWP($data_off,"esp","",0));
1930Sstevel@tonic-gate	&mov("ebx",	&DWP($data_off+4,"esp","",0));
1940Sstevel@tonic-gate
1950Sstevel@tonic-gate	&bswap("eax")	if $swap;
1960Sstevel@tonic-gate	&bswap("ebx")	if $swap;
1970Sstevel@tonic-gate
1980Sstevel@tonic-gate	&mov(&DWP(0,$out,"",0),"eax");
1990Sstevel@tonic-gate	&mov(&DWP(4,$out,"",0),"ebx");
2000Sstevel@tonic-gate
2010Sstevel@tonic-gate	&jmp(&label("finish"));
2020Sstevel@tonic-gate
2030Sstevel@tonic-gate	#############################################################
2040Sstevel@tonic-gate	#############################################################
2050Sstevel@tonic-gate	&set_label("decrypt",1);
2060Sstevel@tonic-gate	# decrypt start
2070Sstevel@tonic-gate	&and($count,0xfffffff8);
2080Sstevel@tonic-gate	# The next 2 instructions are only for if the jz is taken
2090Sstevel@tonic-gate	&mov("eax",	&DWP($data_off+8,"esp","",0));	# get iv[0]
2100Sstevel@tonic-gate	&mov("ebx",	&DWP($data_off+12,"esp","",0));	# get iv[1]
2110Sstevel@tonic-gate	&jz(&label("decrypt_finish"));
2120Sstevel@tonic-gate
2130Sstevel@tonic-gate	&set_label("decrypt_loop");
2140Sstevel@tonic-gate	&mov("eax",	&DWP(0,$in,"",0));	# load first 4 bytes
2150Sstevel@tonic-gate	&mov("ebx",	&DWP(4,$in,"",0));	# second 4 bytes
2160Sstevel@tonic-gate
2170Sstevel@tonic-gate	&bswap("eax")	if $swap;
2180Sstevel@tonic-gate	&bswap("ebx")	if $swap;
2190Sstevel@tonic-gate
2200Sstevel@tonic-gate	&mov(&DWP($data_off,"esp","",0),	"eax");	# put back
2210Sstevel@tonic-gate	&mov(&DWP($data_off+4,"esp","",0),	"ebx");	#
2220Sstevel@tonic-gate
2230Sstevel@tonic-gate	&call($dec_func);
2240Sstevel@tonic-gate
2250Sstevel@tonic-gate	&mov("eax",	&DWP($data_off,"esp","",0));	# get return
2260Sstevel@tonic-gate	&mov("ebx",	&DWP($data_off+4,"esp","",0));	#
2270Sstevel@tonic-gate
2280Sstevel@tonic-gate	&bswap("eax")	if $swap;
2290Sstevel@tonic-gate	&bswap("ebx")	if $swap;
2300Sstevel@tonic-gate
2310Sstevel@tonic-gate	&mov("ecx",	&DWP($data_off+8,"esp","",0));	# get iv[0]
2320Sstevel@tonic-gate	&mov("edx",	&DWP($data_off+12,"esp","",0));	# get iv[1]
2330Sstevel@tonic-gate
2340Sstevel@tonic-gate	&xor("ecx",	"eax");
2350Sstevel@tonic-gate	&xor("edx",	"ebx");
2360Sstevel@tonic-gate
2370Sstevel@tonic-gate	&mov("eax",	&DWP(0,$in,"",0));	# get old cipher text,
2380Sstevel@tonic-gate	&mov("ebx",	&DWP(4,$in,"",0));	# next iv actually
2390Sstevel@tonic-gate
2400Sstevel@tonic-gate	&mov(&DWP(0,$out,"",0),"ecx");
2410Sstevel@tonic-gate	&mov(&DWP(4,$out,"",0),"edx");
2420Sstevel@tonic-gate
2430Sstevel@tonic-gate	&mov(&DWP($data_off+8,"esp","",0),	"eax");	# save iv
2440Sstevel@tonic-gate	&mov(&DWP($data_off+12,"esp","",0),	"ebx");	#
2450Sstevel@tonic-gate
2460Sstevel@tonic-gate	&add($in,	8);
2470Sstevel@tonic-gate	&add($out,	8);
2480Sstevel@tonic-gate
2490Sstevel@tonic-gate	&sub($count,	8);
2500Sstevel@tonic-gate	&jnz(&label("decrypt_loop"));
2510Sstevel@tonic-gate############################ ENDIT #######################3
2520Sstevel@tonic-gate	&set_label("decrypt_finish");
2530Sstevel@tonic-gate	&mov($count,	&wparam(2));	# length
2540Sstevel@tonic-gate	&and($count,	7);
2550Sstevel@tonic-gate	&jz(&label("finish"));
2560Sstevel@tonic-gate
2570Sstevel@tonic-gate	&mov("eax",	&DWP(0,$in,"",0));	# load first 4 bytes
2580Sstevel@tonic-gate	&mov("ebx",	&DWP(4,$in,"",0));	# second 4 bytes
2590Sstevel@tonic-gate
2600Sstevel@tonic-gate	&bswap("eax")	if $swap;
2610Sstevel@tonic-gate	&bswap("ebx")	if $swap;
2620Sstevel@tonic-gate
2630Sstevel@tonic-gate	&mov(&DWP($data_off,"esp","",0),	"eax");	# put back
2640Sstevel@tonic-gate	&mov(&DWP($data_off+4,"esp","",0),	"ebx");	#
2650Sstevel@tonic-gate
2660Sstevel@tonic-gate	&call($dec_func);
2670Sstevel@tonic-gate
2680Sstevel@tonic-gate	&mov("eax",	&DWP($data_off,"esp","",0));	# get return
2690Sstevel@tonic-gate	&mov("ebx",	&DWP($data_off+4,"esp","",0));	#
2700Sstevel@tonic-gate
2710Sstevel@tonic-gate	&bswap("eax")	if $swap;
2720Sstevel@tonic-gate	&bswap("ebx")	if $swap;
2730Sstevel@tonic-gate
2740Sstevel@tonic-gate	&mov("ecx",	&DWP($data_off+8,"esp","",0));	# get iv[0]
2750Sstevel@tonic-gate	&mov("edx",	&DWP($data_off+12,"esp","",0));	# get iv[1]
2760Sstevel@tonic-gate
2770Sstevel@tonic-gate	&xor("ecx",	"eax");
2780Sstevel@tonic-gate	&xor("edx",	"ebx");
2790Sstevel@tonic-gate
2800Sstevel@tonic-gate	# this is for when we exit
2810Sstevel@tonic-gate	&mov("eax",	&DWP(0,$in,"",0));	# get old cipher text,
2820Sstevel@tonic-gate	&mov("ebx",	&DWP(4,$in,"",0));	# next iv actually
2830Sstevel@tonic-gate
2840Sstevel@tonic-gate&set_label("dj7");
2850Sstevel@tonic-gate	&rotr("edx",	16);
2860Sstevel@tonic-gate	&movb(&BP(6,$out,"",0),	&LB("edx"));
2870Sstevel@tonic-gate	&shr("edx",16);
2880Sstevel@tonic-gate&set_label("dj6");
2890Sstevel@tonic-gate	&movb(&BP(5,$out,"",0),	&HB("edx"));
2900Sstevel@tonic-gate&set_label("dj5");
2910Sstevel@tonic-gate	&movb(&BP(4,$out,"",0),	&LB("edx"));
2920Sstevel@tonic-gate&set_label("dj4");
2930Sstevel@tonic-gate	&mov(&DWP(0,$out,"",0),	"ecx");
2940Sstevel@tonic-gate	&jmp(&label("djend"));
2950Sstevel@tonic-gate&set_label("dj3");
2960Sstevel@tonic-gate	&rotr("ecx",	16);
2970Sstevel@tonic-gate	&movb(&BP(2,$out,"",0),	&LB("ecx"));
2980Sstevel@tonic-gate	&shl("ecx",16);
2990Sstevel@tonic-gate&set_label("dj2");
3000Sstevel@tonic-gate	&movb(&BP(1,$in,"",0),	&HB("ecx"));
3010Sstevel@tonic-gate&set_label("dj1");
3020Sstevel@tonic-gate	&movb(&BP(0,$in,"",0),	&LB("ecx"));
3030Sstevel@tonic-gate&set_label("djend");
3040Sstevel@tonic-gate
3050Sstevel@tonic-gate	# final iv is still in eax:ebx
3060Sstevel@tonic-gate	&jmp(&label("finish"));
3070Sstevel@tonic-gate
3080Sstevel@tonic-gate
3090Sstevel@tonic-gate############################ FINISH #######################3
3100Sstevel@tonic-gate	&set_label("finish",1);
3110Sstevel@tonic-gate	&mov("ecx",	&wparam($iv_off));	# Get iv ptr
3120Sstevel@tonic-gate
3130Sstevel@tonic-gate	#################################################
3140Sstevel@tonic-gate	$total=16+4;
3150Sstevel@tonic-gate	$total+=4 if ($p1 > 0);
3160Sstevel@tonic-gate	$total+=4 if ($p2 > 0);
3170Sstevel@tonic-gate	$total+=4 if ($p3 > 0);
3180Sstevel@tonic-gate	&add("esp",$total);
3190Sstevel@tonic-gate
3200Sstevel@tonic-gate	&mov(&DWP(0,"ecx","",0),	"eax");	# save iv
3210Sstevel@tonic-gate	&mov(&DWP(4,"ecx","",0),	"ebx");	# save iv
3220Sstevel@tonic-gate
3230Sstevel@tonic-gate	&function_end_A($name);
3240Sstevel@tonic-gate
325*2139Sjp161948	&align(64);
326*2139Sjp161948	&set_label("cbc_enc_jmp_table");
3270Sstevel@tonic-gate	&data_word("0");
3280Sstevel@tonic-gate	&data_word(&label("ej1")."-".&label("PIC_point"));
3290Sstevel@tonic-gate	&data_word(&label("ej2")."-".&label("PIC_point"));
3300Sstevel@tonic-gate	&data_word(&label("ej3")."-".&label("PIC_point"));
3310Sstevel@tonic-gate	&data_word(&label("ej4")."-".&label("PIC_point"));
3320Sstevel@tonic-gate	&data_word(&label("ej5")."-".&label("PIC_point"));
3330Sstevel@tonic-gate	&data_word(&label("ej6")."-".&label("PIC_point"));
3340Sstevel@tonic-gate	&data_word(&label("ej7")."-".&label("PIC_point"));
3350Sstevel@tonic-gate	# not used
3360Sstevel@tonic-gate	#&set_label("cbc_dec_jmp_table",1);
3370Sstevel@tonic-gate	#&data_word("0");
3380Sstevel@tonic-gate	#&data_word(&label("dj1")."-".&label("PIC_point"));
3390Sstevel@tonic-gate	#&data_word(&label("dj2")."-".&label("PIC_point"));
3400Sstevel@tonic-gate	#&data_word(&label("dj3")."-".&label("PIC_point"));
3410Sstevel@tonic-gate	#&data_word(&label("dj4")."-".&label("PIC_point"));
3420Sstevel@tonic-gate	#&data_word(&label("dj5")."-".&label("PIC_point"));
3430Sstevel@tonic-gate	#&data_word(&label("dj6")."-".&label("PIC_point"));
3440Sstevel@tonic-gate	#&data_word(&label("dj7")."-".&label("PIC_point"));
345*2139Sjp161948	&align(64);
3460Sstevel@tonic-gate
3470Sstevel@tonic-gate	&function_end_B($name);
3480Sstevel@tonic-gate
3490Sstevel@tonic-gate	}
3500Sstevel@tonic-gate
3510Sstevel@tonic-gate1;
352