From 2535075bf0bd1a599a7f483d06b3ef019104ee7c Mon Sep 17 00:00:00 2001 From: Daniel Hu Date: Mon, 14 Feb 2022 14:36:34 +0000 Subject: SM4 optimization for ARM by ASIMD This patch optimizes SM4 for ARM processor using ASIMD instruction It will improve performance if both of following conditions are met: 1) Input data equal to or more than 4 blocks 2) Cipher mode allows parallelism, including ECB,CTR,GCM or CBC decryption This patch implements SM4 SBOX lookup in vector registers, with the benefit of constant processing time over existing C implementation. It is only enabled for micro-architecture N1/V1. In the ideal scenario, performance can reach up to 2.7X When either of above two conditions is not met, e.g. single block input or CFB/OFB mode, CBC encryption, performance could drop about 50%. The assembly code has been reviewed internally by ARM engineer Fangming.Fang@arm.com Signed-off-by: Daniel Hu Reviewed-by: Paul Dale Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/17951) (cherry picked from commit 4908787f21f4f5fa24b721ed3ebbc4d3e93ef70c) --- crypto/evp/e_sm4.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'crypto/evp/e_sm4.c') diff --git a/crypto/evp/e_sm4.c b/crypto/evp/e_sm4.c index bff79ff197..c8e8cfe9c9 100644 --- a/crypto/evp/e_sm4.c +++ b/crypto/evp/e_sm4.c @@ -76,6 +76,17 @@ static int sm4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, dat->stream.ecb = (ecb128_f) HWSM4_ecb_encrypt; # endif } else +#endif +#ifdef VPSM4_CAPABLE + if (VPSM4_CAPABLE) { + vpsm4_set_decrypt_key(key, &dat->ks.ks); + dat->block = (block128_f) vpsm4_decrypt; + dat->stream.cbc = NULL; + if (mode == EVP_CIPH_CBC_MODE) + dat->stream.cbc = (cbc128_f) vpsm4_cbc_encrypt; + else if (mode == EVP_CIPH_ECB_MODE) + dat->stream.ecb = (ecb128_f) vpsm4_ecb_encrypt; + } else #endif { dat->block = (block128_f) ossl_sm4_decrypt; @@ -104,6 +115,19 @@ static int sm4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, # endif (void)0; /* terminate potentially open 'else' */ } else +#endif +#ifdef VPSM4_CAPABLE + if (VPSM4_CAPABLE) { + vpsm4_set_encrypt_key(key, &dat->ks.ks); + dat->block = (block128_f) vpsm4_encrypt; + dat->stream.cbc = NULL; + if (mode == EVP_CIPH_CBC_MODE) + dat->stream.cbc = (cbc128_f) vpsm4_cbc_encrypt; + else if (mode == EVP_CIPH_ECB_MODE) + dat->stream.ecb = (ecb128_f) vpsm4_ecb_encrypt; + else if (mode == EVP_CIPH_CTR_MODE) + dat->stream.ctr = (ctr128_f) vpsm4_ctr32_encrypt_blocks; + } else #endif { dat->block = (block128_f) ossl_sm4_encrypt; -- cgit v1.2.3