Skip to content

Commit

Permalink
SM4 optimization for ARM by ASIMD
Browse files Browse the repository at this point in the history
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 #17951)

(cherry picked from commit 4908787)
  • Loading branch information
daniel-hu-arm authored and t8m committed Nov 21, 2022
1 parent 553e125 commit 2535075
Show file tree
Hide file tree
Showing 6 changed files with 1,206 additions and 2 deletions.
24 changes: 24 additions & 0 deletions crypto/evp/e_sm4.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 2535075

Please sign in to comment.