2018-04-25 15:20:46 +03:00
// SPDX-License-Identifier: GPL-2.0
# include <asm/neon.h>
# include <asm/simd.h>
2022-11-25 07:36:28 +03:00
# include <crypto/algapi.h>
2018-04-25 15:20:46 +03:00
# include <crypto/sm4.h>
2019-03-13 08:12:50 +03:00
# include <crypto/internal/simd.h>
2018-04-25 15:20:46 +03:00
# include <linux/module.h>
# include <linux/cpufeature.h>
# include <linux/types.h>
MODULE_ALIAS_CRYPTO ( " sm4 " ) ;
MODULE_ALIAS_CRYPTO ( " sm4-ce " ) ;
MODULE_DESCRIPTION ( " SM4 symmetric cipher using ARMv8 Crypto Extensions " ) ;
MODULE_AUTHOR ( " Ard Biesheuvel <ard.biesheuvel@linaro.org> " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;
asmlinkage void sm4_ce_do_crypt ( const u32 * rk , void * out , const void * in ) ;
2021-07-20 06:46:40 +03:00
static int sm4_ce_setkey ( struct crypto_tfm * tfm , const u8 * key ,
unsigned int key_len )
{
struct sm4_ctx * ctx = crypto_tfm_ctx ( tfm ) ;
return sm4_expandkey ( ctx , key , key_len ) ;
}
2018-04-25 15:20:46 +03:00
static void sm4_ce_encrypt ( struct crypto_tfm * tfm , u8 * out , const u8 * in )
{
2021-07-20 06:46:40 +03:00
const struct sm4_ctx * ctx = crypto_tfm_ctx ( tfm ) ;
2018-04-25 15:20:46 +03:00
2019-03-13 08:12:50 +03:00
if ( ! crypto_simd_usable ( ) ) {
2021-07-20 06:46:40 +03:00
sm4_crypt_block ( ctx - > rkey_enc , out , in ) ;
2018-04-25 15:20:46 +03:00
} else {
kernel_neon_begin ( ) ;
sm4_ce_do_crypt ( ctx - > rkey_enc , out , in ) ;
kernel_neon_end ( ) ;
}
}
static void sm4_ce_decrypt ( struct crypto_tfm * tfm , u8 * out , const u8 * in )
{
2021-07-20 06:46:40 +03:00
const struct sm4_ctx * ctx = crypto_tfm_ctx ( tfm ) ;
2018-04-25 15:20:46 +03:00
2019-03-13 08:12:50 +03:00
if ( ! crypto_simd_usable ( ) ) {
2021-07-20 06:46:40 +03:00
sm4_crypt_block ( ctx - > rkey_dec , out , in ) ;
2018-04-25 15:20:46 +03:00
} else {
kernel_neon_begin ( ) ;
sm4_ce_do_crypt ( ctx - > rkey_dec , out , in ) ;
kernel_neon_end ( ) ;
}
}
static struct crypto_alg sm4_ce_alg = {
. cra_name = " sm4 " ,
. cra_driver_name = " sm4-ce " ,
2022-03-15 12:44:52 +03:00
. cra_priority = 300 ,
2018-04-25 15:20:46 +03:00
. cra_flags = CRYPTO_ALG_TYPE_CIPHER ,
. cra_blocksize = SM4_BLOCK_SIZE ,
2021-07-20 06:46:40 +03:00
. cra_ctxsize = sizeof ( struct sm4_ctx ) ,
2018-04-25 15:20:46 +03:00
. cra_module = THIS_MODULE ,
. cra_u . cipher = {
. cia_min_keysize = SM4_KEY_SIZE ,
. cia_max_keysize = SM4_KEY_SIZE ,
2021-07-20 06:46:40 +03:00
. cia_setkey = sm4_ce_setkey ,
2018-04-25 15:20:46 +03:00
. cia_encrypt = sm4_ce_encrypt ,
. cia_decrypt = sm4_ce_decrypt
}
} ;
static int __init sm4_ce_mod_init ( void )
{
return crypto_register_alg ( & sm4_ce_alg ) ;
}
static void __exit sm4_ce_mod_fini ( void )
{
crypto_unregister_alg ( & sm4_ce_alg ) ;
}
2018-08-08 00:18:36 +03:00
module_cpu_feature_match ( SM4 , sm4_ce_mod_init ) ;
2018-04-25 15:20:46 +03:00
module_exit ( sm4_ce_mod_fini ) ;