diff options
author | Daniel Hu <Daniel.Hu@arm.com> | 2022-02-14 15:36:34 +0100 |
---|---|---|
committer | Tomas Mraz <tomas@openssl.org> | 2022-04-12 10:37:42 +0200 |
commit | 4908787f21f4f5fa24b721ed3ebbc4d3e93ef70c (patch) | |
tree | ff233074dbc689698d6c458f9475edca6cdec723 /crypto/evp/e_sm4.c | |
parent | Fix -no-tls1_2 in tests (diff) | |
download | openssl-4908787f21f4f5fa24b721ed3ebbc4d3e93ef70c.tar.xz openssl-4908787f21f4f5fa24b721ed3ebbc4d3e93ef70c.zip |
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 <Daniel.Hu@arm.com>
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/17951)
Diffstat (limited to 'crypto/evp/e_sm4.c')
-rw-r--r-- | crypto/evp/e_sm4.c | 24 |
1 files changed, 24 insertions, 0 deletions
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 @@ -77,6 +77,17 @@ static int sm4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, # 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; ossl_sm4_set_key(key, EVP_CIPHER_CTX_get_cipher_data(ctx)); @@ -105,6 +116,19 @@ static int sm4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, (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; ossl_sm4_set_key(key, EVP_CIPHER_CTX_get_cipher_data(ctx)); |