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