AES-NI asm update from master.

(Imported from upstream's 5572bc4e2fb485c0d85bd5b4ec430ae0af65f7ea)
This commit is contained in:
Adam Langley 2014-06-20 12:00:00 -07:00
parent 5c6ca976c8
commit 7b29449086
2 changed files with 1251 additions and 967 deletions

View File

@ -1,7 +1,7 @@
#!/usr/bin/env perl
# ====================================================================
# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
# project. The module is, however, dual licensed under OpenSSL and
# CRYPTOGAMS licenses depending on where you obtain it. For further
# details see http://www.openssl.org/~appro/cryptogams/.
@ -54,8 +54,8 @@ require "x86asm.pl";
&asm_init($ARGV[0],$0);
if ($PREFIX eq "aesni") { $movekey=*movups; }
else { $movekey=*movups; }
if ($PREFIX eq "aesni") { $movekey=\&movups; }
else { $movekey=\&movups; }
$len="eax";
$rounds="ecx";
@ -208,25 +208,26 @@ sub aesni_generate3
&function_begin_B("_aesni_${p}rypt3");
&$movekey ($rndkey0,&QWP(0,$key));
&shr ($rounds,1);
&shl ($rounds,4);
&$movekey ($rndkey1,&QWP(16,$key));
&lea ($key,&DWP(32,$key));
&xorps ($inout0,$rndkey0);
&pxor ($inout1,$rndkey0);
&pxor ($inout2,$rndkey0);
&$movekey ($rndkey0,&QWP(0,$key));
&$movekey ($rndkey0,&QWP(32,$key));
&lea ($key,&DWP(32,$key,$rounds));
&neg ($rounds);
&add ($rounds,16);
&set_label("${p}3_loop");
eval"&aes${p} ($inout0,$rndkey1)";
eval"&aes${p} ($inout1,$rndkey1)";
&dec ($rounds);
eval"&aes${p} ($inout2,$rndkey1)";
&$movekey ($rndkey1,&QWP(16,$key));
&$movekey ($rndkey1,&QWP(0,$key,$rounds));
&add ($rounds,32);
eval"&aes${p} ($inout0,$rndkey0)";
eval"&aes${p} ($inout1,$rndkey0)";
&lea ($key,&DWP(32,$key));
eval"&aes${p} ($inout2,$rndkey0)";
&$movekey ($rndkey0,&QWP(0,$key));
&$movekey ($rndkey0,&QWP(-16,$key,$rounds));
&jnz (&label("${p}3_loop"));
eval"&aes${p} ($inout0,$rndkey1)";
eval"&aes${p} ($inout1,$rndkey1)";
@ -248,27 +249,29 @@ sub aesni_generate4
&function_begin_B("_aesni_${p}rypt4");
&$movekey ($rndkey0,&QWP(0,$key));
&$movekey ($rndkey1,&QWP(16,$key));
&shr ($rounds,1);
&lea ($key,&DWP(32,$key));
&shl ($rounds,4);
&xorps ($inout0,$rndkey0);
&pxor ($inout1,$rndkey0);
&pxor ($inout2,$rndkey0);
&pxor ($inout3,$rndkey0);
&$movekey ($rndkey0,&QWP(0,$key));
&$movekey ($rndkey0,&QWP(32,$key));
&lea ($key,&DWP(32,$key,$rounds));
&neg ($rounds);
&data_byte (0x0f,0x1f,0x40,0x00);
&add ($rounds,16);
&set_label("${p}4_loop");
eval"&aes${p} ($inout0,$rndkey1)";
eval"&aes${p} ($inout1,$rndkey1)";
&dec ($rounds);
eval"&aes${p} ($inout2,$rndkey1)";
eval"&aes${p} ($inout3,$rndkey1)";
&$movekey ($rndkey1,&QWP(16,$key));
&$movekey ($rndkey1,&QWP(0,$key,$rounds));
&add ($rounds,32);
eval"&aes${p} ($inout0,$rndkey0)";
eval"&aes${p} ($inout1,$rndkey0)";
&lea ($key,&DWP(32,$key));
eval"&aes${p} ($inout2,$rndkey0)";
eval"&aes${p} ($inout3,$rndkey0)";
&$movekey ($rndkey0,&QWP(0,$key));
&$movekey ($rndkey0,&QWP(-16,$key,$rounds));
&jnz (&label("${p}4_loop"));
eval"&aes${p} ($inout0,$rndkey1)";
@ -289,43 +292,43 @@ sub aesni_generate6
&function_begin_B("_aesni_${p}rypt6");
&static_label("_aesni_${p}rypt6_enter");
&$movekey ($rndkey0,&QWP(0,$key));
&shr ($rounds,1);
&shl ($rounds,4);
&$movekey ($rndkey1,&QWP(16,$key));
&lea ($key,&DWP(32,$key));
&xorps ($inout0,$rndkey0);
&pxor ($inout1,$rndkey0); # pxor does better here
eval"&aes${p} ($inout0,$rndkey1)";
&pxor ($inout2,$rndkey0);
eval"&aes${p} ($inout1,$rndkey1)";
eval"&aes${p} ($inout0,$rndkey1)";
&pxor ($inout3,$rndkey0);
&dec ($rounds);
eval"&aes${p} ($inout2,$rndkey1)";
&pxor ($inout4,$rndkey0);
eval"&aes${p} ($inout3,$rndkey1)";
eval"&aes${p} ($inout1,$rndkey1)";
&lea ($key,&DWP(32,$key,$rounds));
&neg ($rounds);
eval"&aes${p} ($inout2,$rndkey1)";
&pxor ($inout5,$rndkey0);
&add ($rounds,16);
eval"&aes${p} ($inout3,$rndkey1)";
eval"&aes${p} ($inout4,$rndkey1)";
&$movekey ($rndkey0,&QWP(0,$key));
eval"&aes${p} ($inout5,$rndkey1)";
&$movekey ($rndkey0,&QWP(-16,$key,$rounds));
&jmp (&label("_aesni_${p}rypt6_enter"));
&set_label("${p}6_loop",16);
eval"&aes${p} ($inout0,$rndkey1)";
eval"&aes${p} ($inout1,$rndkey1)";
&dec ($rounds);
eval"&aes${p} ($inout2,$rndkey1)";
eval"&aes${p} ($inout3,$rndkey1)";
eval"&aes${p} ($inout4,$rndkey1)";
eval"&aes${p} ($inout5,$rndkey1)";
&set_label("_aesni_${p}rypt6_enter",16);
&$movekey ($rndkey1,&QWP(16,$key));
&set_label("_aesni_${p}rypt6_enter");
&$movekey ($rndkey1,&QWP(0,$key,$rounds));
&add ($rounds,32);
eval"&aes${p} ($inout0,$rndkey0)";
eval"&aes${p} ($inout1,$rndkey0)";
&lea ($key,&DWP(32,$key));
eval"&aes${p} ($inout2,$rndkey0)";
eval"&aes${p} ($inout3,$rndkey0)";
eval"&aes${p} ($inout4,$rndkey0)";
eval"&aes${p} ($inout5,$rndkey0)";
&$movekey ($rndkey0,&QWP(0,$key));
&$movekey ($rndkey0,&QWP(-16,$key,$rounds));
&jnz (&label("${p}6_loop"));
eval"&aes${p} ($inout0,$rndkey1)";
@ -610,11 +613,13 @@ if ($PREFIX eq "aesni") {
&mov (&DWP(24,"esp"),$key_);
&mov (&DWP(28,"esp"),$key_);
&shr ($rounds,1);
&shl ($rounds,4);
&mov ($rounds_,16);
&lea ($key_,&DWP(0,$key));
&movdqa ($inout3,&QWP(0,"esp"));
&movdqa ($inout0,$ivec);
&mov ($rounds_,$rounds);
&lea ($key,&DWP(32,$key,$rounds));
&sub ($rounds_,$rounds);
&pshufb ($ivec,$inout3);
&set_label("ccm64_enc_outer");
@ -625,33 +630,31 @@ if ($PREFIX eq "aesni") {
&xorps ($inout0,$rndkey0);
&$movekey ($rndkey1,&QWP(16,$key_));
&xorps ($rndkey0,$in0);
&lea ($key,&DWP(32,$key_));
&xorps ($cmac,$rndkey0); # cmac^=inp
&$movekey ($rndkey0,&QWP(0,$key));
&$movekey ($rndkey0,&QWP(32,$key_));
&set_label("ccm64_enc2_loop");
&aesenc ($inout0,$rndkey1);
&dec ($rounds);
&aesenc ($cmac,$rndkey1);
&$movekey ($rndkey1,&QWP(16,$key));
&$movekey ($rndkey1,&QWP(0,$key,$rounds));
&add ($rounds,32);
&aesenc ($inout0,$rndkey0);
&lea ($key,&DWP(32,$key));
&aesenc ($cmac,$rndkey0);
&$movekey ($rndkey0,&QWP(0,$key));
&$movekey ($rndkey0,&QWP(-16,$key,$rounds));
&jnz (&label("ccm64_enc2_loop"));
&aesenc ($inout0,$rndkey1);
&aesenc ($cmac,$rndkey1);
&paddq ($ivec,&QWP(16,"esp"));
&dec ($len);
&aesenclast ($inout0,$rndkey0);
&aesenclast ($cmac,$rndkey0);
&dec ($len);
&lea ($inp,&DWP(16,$inp));
&xorps ($in0,$inout0); # inp^=E(ivec)
&movdqa ($inout0,$ivec);
&movups (&QWP(0,$out),$in0); # save output
&lea ($out,&DWP(16,$out));
&pshufb ($inout0,$inout3);
&lea ($out,&DWP(16,$out));
&jnz (&label("ccm64_enc_outer"));
&mov ("esp",&DWP(48,"esp"));
@ -700,15 +703,19 @@ if ($PREFIX eq "aesni") {
{ &aesni_inline_generate1("enc"); }
else
{ &call ("_aesni_encrypt1"); }
&shl ($rounds_,4);
&mov ($rounds,16);
&movups ($in0,&QWP(0,$inp)); # load inp
&paddq ($ivec,&QWP(16,"esp"));
&lea ($inp,&QWP(16,$inp));
&sub ($rounds,$rounds_);
&lea ($key,&DWP(32,$key_,$rounds_));
&mov ($rounds_,$rounds);
&jmp (&label("ccm64_dec_outer"));
&set_label("ccm64_dec_outer",16);
&xorps ($in0,$inout0); # inp ^= E(ivec)
&movdqa ($inout0,$ivec);
&mov ($rounds,$rounds_);
&movups (&QWP(0,$out),$in0); # save output
&lea ($out,&DWP(16,$out));
&pshufb ($inout0,$inout3);
@ -717,34 +724,33 @@ if ($PREFIX eq "aesni") {
&jz (&label("ccm64_dec_break"));
&$movekey ($rndkey0,&QWP(0,$key_));
&shr ($rounds,1);
&mov ($rounds,$rounds_);
&$movekey ($rndkey1,&QWP(16,$key_));
&xorps ($in0,$rndkey0);
&lea ($key,&DWP(32,$key_));
&xorps ($inout0,$rndkey0);
&xorps ($cmac,$in0); # cmac^=out
&$movekey ($rndkey0,&QWP(0,$key));
&$movekey ($rndkey0,&QWP(32,$key_));
&set_label("ccm64_dec2_loop");
&aesenc ($inout0,$rndkey1);
&dec ($rounds);
&aesenc ($cmac,$rndkey1);
&$movekey ($rndkey1,&QWP(16,$key));
&$movekey ($rndkey1,&QWP(0,$key,$rounds));
&add ($rounds,32);
&aesenc ($inout0,$rndkey0);
&lea ($key,&DWP(32,$key));
&aesenc ($cmac,$rndkey0);
&$movekey ($rndkey0,&QWP(0,$key));
&$movekey ($rndkey0,&QWP(-16,$key,$rounds));
&jnz (&label("ccm64_dec2_loop"));
&movups ($in0,&QWP(0,$inp)); # load inp
&paddq ($ivec,&QWP(16,"esp"));
&aesenc ($inout0,$rndkey1);
&aesenc ($cmac,$rndkey1);
&lea ($inp,&QWP(16,$inp));
&aesenclast ($inout0,$rndkey0);
&aesenclast ($cmac,$rndkey0);
&lea ($inp,&QWP(16,$inp));
&jmp (&label("ccm64_dec_outer"));
&set_label("ccm64_dec_break",16);
&mov ($rounds,&DWP(240,$key_));
&mov ($key,$key_);
if ($inline)
{ &aesni_inline_generate1("enc",$cmac,$in0); }
@ -763,7 +769,7 @@ if ($PREFIX eq "aesni") {
# const char *ivec);
#
# Handles only complete blocks, operates on 32-bit counter and
# does not update *ivec! (see engine/eng_aesni.c for details)
# does not update *ivec! (see crypto/modes/ctr128.c for details)
#
# stack layout:
# 0 pshufb mask
@ -810,66 +816,61 @@ if ($PREFIX eq "aesni") {
# compose 2 vectors of 3x32-bit counters
&bswap ($rounds_);
&pxor ($rndkey1,$rndkey1);
&pxor ($rndkey0,$rndkey0);
&pxor ($rndkey1,$rndkey1);
&movdqa ($inout0,&QWP(0,"esp")); # load byte-swap mask
&pinsrd ($rndkey1,$rounds_,0);
&pinsrd ($rndkey0,$rounds_,0);
&lea ($key_,&DWP(3,$rounds_));
&pinsrd ($rndkey0,$key_,0);
&pinsrd ($rndkey1,$key_,0);
&inc ($rounds_);
&pinsrd ($rndkey1,$rounds_,1);
&pinsrd ($rndkey0,$rounds_,1);
&inc ($key_);
&pinsrd ($rndkey0,$key_,1);
&pinsrd ($rndkey1,$key_,1);
&inc ($rounds_);
&pinsrd ($rndkey1,$rounds_,2);
&pinsrd ($rndkey0,$rounds_,2);
&inc ($key_);
&pinsrd ($rndkey0,$key_,2);
&movdqa (&QWP(48,"esp"),$rndkey1); # save 1st triplet
&pshufb ($rndkey1,$inout0); # byte swap
&movdqa (&QWP(64,"esp"),$rndkey0); # save 2nd triplet
&pinsrd ($rndkey1,$key_,2);
&movdqa (&QWP(48,"esp"),$rndkey0); # save 1st triplet
&pshufb ($rndkey0,$inout0); # byte swap
&movdqu ($inout4,&QWP(0,$key)); # key[0]
&movdqa (&QWP(64,"esp"),$rndkey1); # save 2nd triplet
&pshufb ($rndkey1,$inout0); # byte swap
&pshufd ($inout0,$rndkey1,3<<6); # place counter to upper dword
&pshufd ($inout1,$rndkey1,2<<6);
&pshufd ($inout0,$rndkey0,3<<6); # place counter to upper dword
&pshufd ($inout1,$rndkey0,2<<6);
&cmp ($len,6);
&jb (&label("ctr32_tail"));
&movdqa (&QWP(32,"esp"),$inout5); # save counter-less ivec
&shr ($rounds,1);
&pxor ($inout5,$inout4); # counter-less ivec^key[0]
&shl ($rounds,4);
&mov ($rounds_,16);
&movdqa (&QWP(32,"esp"),$inout5); # save counter-less ivec^key[0]
&mov ($key_,$key); # backup $key
&mov ($rounds_,$rounds); # backup $rounds
&sub ($rounds_,$rounds); # backup twisted $rounds
&lea ($key,&DWP(32,$key,$rounds));
&sub ($len,6);
&jmp (&label("ctr32_loop6"));
&set_label("ctr32_loop6",16);
&pshufd ($inout2,$rndkey1,1<<6);
&movdqa ($rndkey1,&QWP(32,"esp")); # pull counter-less ivec
&pshufd ($inout3,$rndkey0,3<<6);
&por ($inout0,$rndkey1); # merge counter-less ivec
&pshufd ($inout4,$rndkey0,2<<6);
&por ($inout1,$rndkey1);
&pshufd ($inout5,$rndkey0,1<<6);
&por ($inout2,$rndkey1);
&por ($inout3,$rndkey1);
&por ($inout4,$rndkey1);
&por ($inout5,$rndkey1);
# inlining _aesni_encrypt6's prologue gives ~4% improvement...
&$movekey ($rndkey0,&QWP(0,$key_));
&$movekey ($rndkey1,&QWP(16,$key_));
&lea ($key,&DWP(32,$key_));
&dec ($rounds);
&pxor ($inout0,$rndkey0);
# inlining _aesni_encrypt6's prologue gives ~6% improvement...
&pshufd ($inout2,$rndkey0,1<<6);
&movdqa ($rndkey0,&QWP(32,"esp")); # pull counter-less ivec
&pshufd ($inout3,$rndkey1,3<<6);
&pxor ($inout0,$rndkey0); # merge counter-less ivec
&pshufd ($inout4,$rndkey1,2<<6);
&pxor ($inout1,$rndkey0);
&aesenc ($inout0,$rndkey1);
&pshufd ($inout5,$rndkey1,1<<6);
&$movekey ($rndkey1,&QWP(16,$key_));
&pxor ($inout2,$rndkey0);
&aesenc ($inout1,$rndkey1);
&pxor ($inout3,$rndkey0);
&aesenc ($inout2,$rndkey1);
&aesenc ($inout0,$rndkey1);
&pxor ($inout4,$rndkey0);
&aesenc ($inout3,$rndkey1);
&pxor ($inout5,$rndkey0);
&aesenc ($inout1,$rndkey1);
&$movekey ($rndkey0,&QWP(32,$key_));
&mov ($rounds,$rounds_);
&aesenc ($inout2,$rndkey1);
&aesenc ($inout3,$rndkey1);
&aesenc ($inout4,$rndkey1);
&$movekey ($rndkey0,&QWP(0,$key));
&aesenc ($inout5,$rndkey1);
&call (&label("_aesni_encrypt6_enter"));
@ -882,12 +883,12 @@ if ($PREFIX eq "aesni") {
&movups (&QWP(0,$out),$inout0);
&movdqa ($rndkey0,&QWP(16,"esp")); # load increment
&xorps ($inout2,$rndkey1);
&movdqa ($rndkey1,&QWP(48,"esp")); # load 1st triplet
&movdqa ($rndkey1,&QWP(64,"esp")); # load 2nd triplet
&movups (&QWP(0x10,$out),$inout1);
&movups (&QWP(0x20,$out),$inout2);
&paddd ($rndkey1,$rndkey0); # 1st triplet increment
&paddd ($rndkey0,&QWP(64,"esp")); # 2nd triplet increment
&paddd ($rndkey1,$rndkey0); # 2nd triplet increment
&paddd ($rndkey0,&QWP(48,"esp")); # 1st triplet increment
&movdqa ($inout0,&QWP(0,"esp")); # load byte swap mask
&movups ($inout1,&QWP(0x30,$inp));
@ -895,44 +896,44 @@ if ($PREFIX eq "aesni") {
&xorps ($inout3,$inout1);
&movups ($inout1,&QWP(0x50,$inp));
&lea ($inp,&DWP(0x60,$inp));
&movdqa (&QWP(48,"esp"),$rndkey1); # save 1st triplet
&pshufb ($rndkey1,$inout0); # byte swap
&movdqa (&QWP(48,"esp"),$rndkey0); # save 1st triplet
&pshufb ($rndkey0,$inout0); # byte swap
&xorps ($inout4,$inout2);
&movups (&QWP(0x30,$out),$inout3);
&xorps ($inout5,$inout1);
&movdqa (&QWP(64,"esp"),$rndkey0); # save 2nd triplet
&pshufb ($rndkey0,$inout0); # byte swap
&movdqa (&QWP(64,"esp"),$rndkey1); # save 2nd triplet
&pshufb ($rndkey1,$inout0); # byte swap
&movups (&QWP(0x40,$out),$inout4);
&pshufd ($inout0,$rndkey1,3<<6);
&pshufd ($inout0,$rndkey0,3<<6);
&movups (&QWP(0x50,$out),$inout5);
&lea ($out,&DWP(0x60,$out));
&mov ($rounds,$rounds_);
&pshufd ($inout1,$rndkey1,2<<6);
&pshufd ($inout1,$rndkey0,2<<6);
&sub ($len,6);
&jnc (&label("ctr32_loop6"));
&add ($len,6);
&jz (&label("ctr32_ret"));
&movdqu ($inout5,&QWP(0,$key_));
&mov ($key,$key_);
&lea ($rounds,&DWP(1,"",$rounds,2)); # restore $rounds
&movdqa ($inout5,&QWP(32,"esp")); # pull count-less ivec
&pxor ($inout5,&QWP(32,"esp")); # restore count-less ivec
&mov ($rounds,&DWP(240,$key_)); # restore $rounds
&set_label("ctr32_tail");
&por ($inout0,$inout5);
&cmp ($len,2);
&jb (&label("ctr32_one"));
&pshufd ($inout2,$rndkey1,1<<6);
&pshufd ($inout2,$rndkey0,1<<6);
&por ($inout1,$inout5);
&je (&label("ctr32_two"));
&pshufd ($inout3,$rndkey0,3<<6);
&pshufd ($inout3,$rndkey1,3<<6);
&por ($inout2,$inout5);
&cmp ($len,4);
&jb (&label("ctr32_three"));
&pshufd ($inout4,$rndkey0,2<<6);
&pshufd ($inout4,$rndkey1,2<<6);
&por ($inout3,$inout5);
&je (&label("ctr32_four"));
@ -1057,8 +1058,10 @@ if ($PREFIX eq "aesni") {
&sub ($len,16*6);
&jc (&label("xts_enc_short"));
&shr ($rounds,1);
&mov ($rounds_,$rounds);
&shl ($rounds,4);
&mov ($rounds_,16);
&sub ($rounds_,$rounds);
&lea ($key,&DWP(32,$key,$rounds));
&jmp (&label("xts_enc_loop6"));
&set_label("xts_enc_loop6",16);
@ -1080,6 +1083,7 @@ if ($PREFIX eq "aesni") {
&pxor ($inout5,$tweak);
# inline _aesni_encrypt6 prologue and flip xor with tweak and key[0]
&mov ($rounds,$rounds_); # restore $rounds
&movdqu ($inout1,&QWP(16*1,$inp));
&xorps ($inout0,$rndkey0); # input^=rndkey[0]
&movdqu ($inout2,&QWP(16*2,$inp));
@ -1096,19 +1100,17 @@ if ($PREFIX eq "aesni") {
&pxor ($inout5,$rndkey1);
&$movekey ($rndkey1,&QWP(16,$key_));
&lea ($key,&DWP(32,$key_));
&pxor ($inout1,&QWP(16*1,"esp"));
&aesenc ($inout0,$rndkey1);
&pxor ($inout2,&QWP(16*2,"esp"));
&aesenc ($inout1,$rndkey1);
&aesenc ($inout0,$rndkey1);
&pxor ($inout3,&QWP(16*3,"esp"));
&dec ($rounds);
&aesenc ($inout2,$rndkey1);
&pxor ($inout4,&QWP(16*4,"esp"));
&aesenc ($inout3,$rndkey1);
&aesenc ($inout1,$rndkey1);
&pxor ($inout5,$rndkey0);
&$movekey ($rndkey0,&QWP(32,$key_));
&aesenc ($inout2,$rndkey1);
&aesenc ($inout3,$rndkey1);
&aesenc ($inout4,$rndkey1);
&$movekey ($rndkey0,&QWP(0,$key));
&aesenc ($inout5,$rndkey1);
&call (&label("_aesni_encrypt6_enter"));
@ -1135,13 +1137,12 @@ if ($PREFIX eq "aesni") {
&paddq ($tweak,$tweak); # &psllq($tweak,1);
&pand ($twres,$twmask); # isolate carry and residue
&pcmpgtd($twtmp,$tweak); # broadcast upper bits
&mov ($rounds,$rounds_); # restore $rounds
&pxor ($tweak,$twres);
&sub ($len,16*6);
&jnc (&label("xts_enc_loop6"));
&lea ($rounds,&DWP(1,"",$rounds,2)); # restore $rounds
&mov ($rounds,&DWP(240,$key_)); # restore $rounds
&mov ($key,$key_); # restore $key
&mov ($rounds_,$rounds);
@ -1399,8 +1400,10 @@ if ($PREFIX eq "aesni") {
&sub ($len,16*6);
&jc (&label("xts_dec_short"));
&shr ($rounds,1);
&mov ($rounds_,$rounds);
&shl ($rounds,4);
&mov ($rounds_,16);
&sub ($rounds_,$rounds);
&lea ($key,&DWP(32,$key,$rounds));
&jmp (&label("xts_dec_loop6"));
&set_label("xts_dec_loop6",16);
@ -1422,6 +1425,7 @@ if ($PREFIX eq "aesni") {
&pxor ($inout5,$tweak);
# inline _aesni_encrypt6 prologue and flip xor with tweak and key[0]
&mov ($rounds,$rounds_);
&movdqu ($inout1,&QWP(16*1,$inp));
&xorps ($inout0,$rndkey0); # input^=rndkey[0]
&movdqu ($inout2,&QWP(16*2,$inp));
@ -1438,19 +1442,17 @@ if ($PREFIX eq "aesni") {
&pxor ($inout5,$rndkey1);
&$movekey ($rndkey1,&QWP(16,$key_));
&lea ($key,&DWP(32,$key_));
&pxor ($inout1,&QWP(16*1,"esp"));
&aesdec ($inout0,$rndkey1);
&pxor ($inout2,&QWP(16*2,"esp"));
&aesdec ($inout1,$rndkey1);
&aesdec ($inout0,$rndkey1);
&pxor ($inout3,&QWP(16*3,"esp"));
&dec ($rounds);
&aesdec ($inout2,$rndkey1);
&pxor ($inout4,&QWP(16*4,"esp"));
&aesdec ($inout3,$rndkey1);
&aesdec ($inout1,$rndkey1);
&pxor ($inout5,$rndkey0);
&$movekey ($rndkey0,&QWP(32,$key_));
&aesdec ($inout2,$rndkey1);
&aesdec ($inout3,$rndkey1);
&aesdec ($inout4,$rndkey1);
&$movekey ($rndkey0,&QWP(0,$key));
&aesdec ($inout5,$rndkey1);
&call (&label("_aesni_decrypt6_enter"));
@ -1477,13 +1479,12 @@ if ($PREFIX eq "aesni") {
&paddq ($tweak,$tweak); # &psllq($tweak,1);
&pand ($twres,$twmask); # isolate carry and residue
&pcmpgtd($twtmp,$tweak); # broadcast upper bits
&mov ($rounds,$rounds_); # restore $rounds
&pxor ($tweak,$twres);
&sub ($len,16*6);
&jnc (&label("xts_dec_loop6"));
&lea ($rounds,&DWP(1,"",$rounds,2)); # restore $rounds
&mov ($rounds,&DWP(240,$key_)); # restore $rounds
&mov ($key,$key_); # restore $key
&mov ($rounds_,$rounds);
@ -1816,7 +1817,7 @@ if ($PREFIX eq "aesni") {
&movups (&QWP(0x10,$out),$inout1);
&lea ($inp,&DWP(0x60,$inp));
&movups (&QWP(0x20,$out),$inout2);
&mov ($rounds,$rounds_) # restore $rounds
&mov ($rounds,$rounds_); # restore $rounds
&movups (&QWP(0x30,$out),$inout3);
&mov ($key,$key_); # restore $key
&movups (&QWP(0x40,$out),$inout4);
@ -2015,7 +2016,7 @@ if ($PREFIX eq "aesni") {
&set_label("12rounds",16);
&movq ("xmm2",&QWP(16,"eax")); # remaining 1/3 of *userKey
&mov ($rounds,11);
&$movekey (&QWP(-16,$key),"xmm0") # round 0
&$movekey (&QWP(-16,$key),"xmm0"); # round 0
&aeskeygenassist("xmm1","xmm2",0x01); # round 1,2
&call (&label("key_192a_cold"));
&aeskeygenassist("xmm1","xmm2",0x02); # round 2,3
@ -2152,7 +2153,7 @@ if ($PREFIX eq "aesni") {
&mov ($key,&wparam(2));
&call ("_aesni_set_encrypt_key");
&mov ($key,&wparam(2));
&shl ($rounds,4) # rounds-1 after _aesni_set_encrypt_key
&shl ($rounds,4); # rounds-1 after _aesni_set_encrypt_key
&test ("eax","eax");
&jnz (&label("dec_key_ret"));
&lea ("eax",&DWP(16,$key,$rounds)); # end of key schedule

File diff suppressed because it is too large Load Diff