[openssl-dev] [openssl.org #4491] [PATCH] VMX-crypto: Add XTS support
Paulo Flabiano Smorigo via RT
rt at openssl.org
Mon Mar 28 15:09:40 UTC 2016
Author: Leonidas Da Silva Barbosa <leosilva at linux.vnet.ibm.com>
ASM implementation
Signed-off-by: Paulo Flabiano Smorigo <pfsmorigo at linux.vnet.ibm.com>
Signed-off-by: Leonidas Da Silva Barbosa <leosilva at linux.vnet.ibm.com>
---
crypto/aes/asm/aesp8-ppc.pl | 237 +++++++++++++++++++++++++++++++++++++++++++-
crypto/evp/e_aes.c | 7 ++
2 files changed, 243 insertions(+), 1 deletion(-)
diff --git a/crypto/aes/asm/aesp8-ppc.pl b/crypto/aes/asm/aesp8-ppc.pl
index a1891cc..28ae77c 100755
--- a/crypto/aes/asm/aesp8-ppc.pl
+++ b/crypto/aes/asm/aesp8-ppc.pl
@@ -84,6 +84,19 @@ Lconsts:
.byte 0,12,0x14,0,0,0,0,0
.asciz "AES for PowerISA 2.07, CRYPTOGAMS by <appro\@openssl.org>"
+.align 7
+gf:
+.long 0x87000000, 0x00000000, 0x00000000, 0x00000000 ?rev
+Lgf:
+ mflr r0
+ bcl 20,21,\$+4
+ mflr r12
+ addi r12,r12,-24
+ mtlr r0
+ blr
+ .long 0
+ .byte 0,12,0x14,0,0,0,0,0
+
.globl .${prefix}_set_encrypt_key
.align 5
.${prefix}_set_encrypt_key:
@@ -1886,6 +1899,228 @@ Lctr32_enc8x_done:
.size .${prefix}_ctr32_encrypt_blocks,.-.${prefix}_ctr32_encrypt_blocks
___
}} }}}
+#######
+{{
+my ($inp,$out,$len,$key,$tweak,$enc,$rounds,$idx)=map("r$_",(3..10));
+my ($rndkey0, $rndkey1,$inout,$tmp)=map("v$_",(0..3));
+my ($intweak,$inptail,$inpperm,$outhead,$outperm,$outmask,$keyperm)=
+ map("v$_",(4..10));
+
+
+$code.=<<___;
+.globl .${prefix}_xts_encrypt
+.align 5
+.${prefix}_xts_encrypt:
+ ${UCMP}i $len,16
+ bltlr-
+
+ cmpwi $enc,0
+ lis r0,0xffe0
+ mfspr $vrsave,256
+ mtspr 256,r0
+
+ li $idx,15
+ vxor $rndkey0,$rndkey0,$rndkey0
+ le?vspltisb $tmp,0x0f
+
+ lvx $intweak,0,$tweak
+ lvsl $inpperm,0,$tweak
+ lvx $inptail,$idx,$tweak
+ le?vxor $inpperm,$inpperm,$tmp
+ vperm $intweak,$intweak,$inptail,$inpperm
+
+ neg r11,$inp
+ ?lvsl $keyperm,0,$key
+ lwz $rounds,240($key)
+
+ lvsr $inpperm,0,r11
+ lvx $inptail,0,$inp
+ addi $inp,$inp,15
+ le?vxor $inpperm,$inpperm,$tmp
+
+ ?lvsr $outperm,0,$out
+ vspltisb $outmask,-1
+ lvx $outhead,0,$out
+ ?vperm $outmask,$rndkey0,$outmask,$outperm
+ le?vxor $outperm,$outperm,$tmp
+
+ srwi $rounds,$rounds,1
+ li $idx,16
+ subi $rounds,$rounds,1
+
+ beq Lxts_dec #if enc = 0 is dec
+ b Lxts_enc #if not jump to enc
+
+Ltweak:
+ mflr r11
+ xor r12,r12,r12
+ addi r12,r12,0x1
+ lvsr v11,0,r12
+
+ bl Lgf
+ mtlr r11
+
+ vor v11,v4,v4
+ vspltisb v15,1 # create a mask 0101010...01
+ vsl v13,$intweak,v15 # shift tweak left 1 bit
+ vor $intweak,v13,v13
+ vand v13,v13,v15 # create a new mask to fix shift left
+
+ vxor v13,v4,v13 # apply mask to clean last bits at each byte
+ vxor v12,v12,v12
+ vsldoi v12,v11,v12,0xf
+
+ vspltisb v14,0x06
+ vspltisb v16,0x02
+ vsl v14,v16,v14 # create a mask of 808080..80 bytes to check carry bits
+ vspltisb v16,0x0f
+ vand v11,v11,v14 # create a mask to see if we have carry to xor
+
+ vsro v11,v11,v16 # shift 1byte back carry bit
+ vsr v11,v11,v16 # shift 7bits carry bit
+
+ vxor v13,v13,v11 # apply mask and finally we have a tweak shifted 1 bit
+ vor $intweak,v13,v13
+ vxor v13,v13,v13
+
+ vand v14,v12,v14 # if first byte in tweak has a carry we'll need to mult it
+ vxor v16,v16,v16
+ vcmpequb v16,v16,v14
+
+ lvx v11,0,r12
+
+ vspltisb v15, -1
+ vxor v16, v16,v15
+ vand v11,v16,v11
+ vxor $intweak,v11,$intweak
+
+ cmpwi $enc,0
+ beq Lxts_dec
+
+Lxts_enc:
+ vmr $inout,$inptail
+ lvx $inptail,0,$inp
+ addi $inp,$inp,16
+ mtctr $rounds
+ subi $len,$len,16
+
+ lvx $rndkey0,0,$key
+ vperm $inout,$inout,$inptail,$inpperm
+ lvx $rndkey1,$idx,$key
+ addi $idx,$idx,16
+ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm
+ vxor $inout,$inout,$rndkey0
+ lvx $rndkey0,$idx,$key
+ addi $idx,$idx,16
+ vxor $inout,$inout,$intweak #P = T xor PP
+
+Loop_xts_enc:
+ ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm
+ vcipher $inout,$inout,$rndkey1
+ lvx $rndkey1,$idx,$key
+
+ addi $idx,$idx,16
+ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm
+ vcipher $inout,$inout,$rndkey0
+ lvx $rndkey0,$idx,$key
+
+ addi $idx,$idx,16
+ bdnz Loop_xts_enc
+
+ ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm
+ vcipher $inout,$inout,$rndkey1
+ lvx $rndkey1,$idx,$key
+ li $idx,16
+ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm
+ vcipherlast $inout,$inout,$rndkey0
+ vxor $inout,$inout,$intweak #C = T xor CC
+ ${UCMP}i $len,16
+
+ vperm $tmp,$inout,$inout,$outperm
+ vsel $inout,$outhead,$tmp,$outmask
+ vmr $outhead,$tmp
+ stvx $inout,0,$out
+ addi $out,$out,16
+ bge Ltweak
+
+ b Lxts_done
+
+Lxts_dec:
+ vmr $inout,$inptail
+ lvx $inptail,0,$inp
+ addi $inp,$inp,16
+ mtctr $rounds
+ subi $len,$len,16
+
+ lvx $rndkey0,0,$key
+ vperm $inout,$inout,$inptail,$inpperm
+ lvx $rndkey1,$idx,$key
+ addi $idx,$idx,16
+ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm
+ vxor $inout,$inout,$rndkey0
+ lvx $rndkey0,$idx,$key
+ addi $idx,$idx,16
+ vxor $inout,$inout,$intweak #P = T xor PP
+
+Loop_xts_dec:
+ ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm
+ vncipher $inout,$inout,$rndkey1
+ lvx $rndkey1,$idx,$key
+
+ addi $idx,$idx,16
+ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm
+ vncipher $inout,$inout,$rndkey0
+ lvx $rndkey0,$idx,$key
+
+ addi $idx,$idx,16
+ bdnz Loop_xts_dec
+
+ ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm
+ vncipher $inout,$inout,$rndkey1
+ lvx $rndkey1,$idx,$key
+ li $idx,16
+ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm
+ vncipherlast $inout,$inout,$rndkey0
+ vxor $inout,$inout,$intweak #C = T xor CC
+ ${UCMP}i $len,16
+
+ vperm $tmp,$inout,$inout,$outperm
+ vsel $inout,$outhead,$tmp,$outmask
+ vmr $outhead,$tmp
+ stvx $inout,0,$out
+ addi $out,$out,16
+ bge Ltweak
+
+Lxts_done:
+ addi $out,$out,-1
+ lvx $inout,0,$out,
+ vsel $inout,$outhead,$inout,$outmask
+ stvx $inout,0,$out
+
+ neg $enc,$tweak
+ li $idx,15
+ vxor $rndkey0,$rndkey0,$rndkey0
+ vspltisb $outmask,-1
+ le?vspltisb $tmp,0x0f
+ ?lvsl $outperm,0,$enc
+ ?vperm $outmask,$rndkey0,$outmask,$outperm
+ le?vxor $outperm,$outperm,$tmp
+ lvx $outhead,0,$tweak
+ vperm $intweak,$intweak,$intweak,$outperm
+ vsel $inout,$outhead,$intweak,$outmask
+ lvx $inptail,$idx,$tweak
+ stvx $inout,0,$tweak
+ vsel $inout,$intweak,$inptail,$outmask
+ stvx $inout,$idx,$tweak
+
+ mtspr 256,$vrsave
+ blr
+ .long 0
+ .byte 0,12,0x14,0,0,0,6,0
+ .long 0
+.size .${prefix}_xts_encrypt,.-.${prefix}_xts_encrypt
+___
+}}
my $consts=1;
foreach(split("\n",$code)) {
@@ -1918,7 +2153,7 @@ foreach(split("\n",$code)) {
print ".byte\t",join(',',map (sprintf("0x%02x",$_), at bytes)),"\n";
next;
}
- $consts=0 if (m/Lconsts:/o); # end of table
+ $consts=0 if (m/Lgf:/o); # end of table
# instructions prefixed with '?' are endian-specific and need
# to be adjusted accordingly...
diff --git a/crypto/evp/e_aes.c b/crypto/evp/e_aes.c
index c906e6f..b83af7b 100644
--- a/crypto/evp/e_aes.c
+++ b/crypto/evp/e_aes.c
@@ -196,6 +196,7 @@ void AES_xts_decrypt(const char *inp, char *out, size_t len,
# define HWAES_encrypt aes_p8_encrypt
# define HWAES_decrypt aes_p8_decrypt
# define HWAES_cbc_encrypt aes_p8_cbc_encrypt
+# define HWAES_xts_encrypt aes_p8_xts_encrypt
# define HWAES_ctr32_encrypt_blocks aes_p8_ctr32_encrypt_blocks
# endif
@@ -1039,6 +1040,9 @@ void HWAES_decrypt(const unsigned char *in, unsigned char *out,
void HWAES_cbc_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
unsigned char *ivec, const int enc);
+void HWAES_xts_encrypt(const unsigned char *in, unsigned char *out,
+ size_t length, const AES_KEY *key,
+ unsigned char *ivec, const int enc);
void HWAES_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out,
size_t len, const AES_KEY *key,
const unsigned char ivec[16]);
@@ -1850,6 +1854,9 @@ static int aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
xctx->xts.block2 = (block128_f) HWAES_encrypt;
xctx->xts.key1 = &xctx->ks1;
+
+ if (HWAES_xts_encrypt)
+ xctx->stream = HWAES_xts_encrypt;
break;
} else
# endif
--
2.5.5
--
Paulo Flabiano Smorigo
IBM Linux Technology Center
--
Ticket here: http://rt.openssl.org/Ticket/Display.html?id=4491
Please log in as guest with password guest if prompted
More information about the openssl-dev
mailing list