14f1aef9bSTianjia Zhang /* SPDX-License-Identifier: GPL-2.0-or-later */ 24f1aef9bSTianjia Zhang /* 34f1aef9bSTianjia Zhang * SM4 Cipher Algorithm, using ARMv8 NEON 44f1aef9bSTianjia Zhang * as specified in 54f1aef9bSTianjia Zhang * https://tools.ietf.org/id/draft-ribose-cfrg-sm4-10.html 64f1aef9bSTianjia Zhang * 74f1aef9bSTianjia Zhang * Copyright (C) 2022, Alibaba Group. 84f1aef9bSTianjia Zhang * Copyright (C) 2022 Tianjia Zhang <tianjia.zhang@linux.alibaba.com> 94f1aef9bSTianjia Zhang */ 104f1aef9bSTianjia Zhang 114f1aef9bSTianjia Zhang #include <linux/module.h> 124f1aef9bSTianjia Zhang #include <linux/crypto.h> 134f1aef9bSTianjia Zhang #include <linux/kernel.h> 144f1aef9bSTianjia Zhang #include <linux/cpufeature.h> 154f1aef9bSTianjia Zhang #include <asm/neon.h> 164f1aef9bSTianjia Zhang #include <asm/simd.h> 174f1aef9bSTianjia Zhang #include <crypto/internal/simd.h> 184f1aef9bSTianjia Zhang #include <crypto/internal/skcipher.h> 194f1aef9bSTianjia Zhang #include <crypto/sm4.h> 204f1aef9bSTianjia Zhang 21*62508017STianjia Zhang asmlinkage void sm4_neon_crypt(const u32 *rkey, u8 *dst, const u8 *src, 22*62508017STianjia Zhang unsigned int nblocks); 23*62508017STianjia Zhang asmlinkage void sm4_neon_cbc_dec(const u32 *rkey_dec, u8 *dst, const u8 *src, 24*62508017STianjia Zhang u8 *iv, unsigned int nblocks); 25*62508017STianjia Zhang asmlinkage void sm4_neon_cfb_dec(const u32 *rkey_enc, u8 *dst, const u8 *src, 26*62508017STianjia Zhang u8 *iv, unsigned int nblocks); 27*62508017STianjia Zhang asmlinkage void sm4_neon_ctr_crypt(const u32 *rkey_enc, u8 *dst, const u8 *src, 28*62508017STianjia Zhang u8 *iv, unsigned int nblocks); 294f1aef9bSTianjia Zhang 304f1aef9bSTianjia Zhang static int sm4_setkey(struct crypto_skcipher *tfm, const u8 *key, 314f1aef9bSTianjia Zhang unsigned int key_len) 324f1aef9bSTianjia Zhang { 334f1aef9bSTianjia Zhang struct sm4_ctx *ctx = crypto_skcipher_ctx(tfm); 344f1aef9bSTianjia Zhang 354f1aef9bSTianjia Zhang return sm4_expandkey(ctx, key, key_len); 364f1aef9bSTianjia Zhang } 374f1aef9bSTianjia Zhang 384f1aef9bSTianjia Zhang static int sm4_ecb_do_crypt(struct skcipher_request *req, const u32 *rkey) 394f1aef9bSTianjia Zhang { 404f1aef9bSTianjia Zhang struct skcipher_walk walk; 414f1aef9bSTianjia Zhang unsigned int nbytes; 424f1aef9bSTianjia Zhang int err; 434f1aef9bSTianjia Zhang 444f1aef9bSTianjia Zhang err = skcipher_walk_virt(&walk, req, false); 454f1aef9bSTianjia Zhang 464f1aef9bSTianjia Zhang while ((nbytes = walk.nbytes) > 0) { 474f1aef9bSTianjia Zhang const u8 *src = walk.src.virt.addr; 484f1aef9bSTianjia Zhang u8 *dst = walk.dst.virt.addr; 49*62508017STianjia Zhang unsigned int nblocks; 504f1aef9bSTianjia Zhang 51*62508017STianjia Zhang nblocks = nbytes / SM4_BLOCK_SIZE; 52*62508017STianjia Zhang if (nblocks) { 534f1aef9bSTianjia Zhang kernel_neon_begin(); 544f1aef9bSTianjia Zhang 55*62508017STianjia Zhang sm4_neon_crypt(rkey, dst, src, nblocks); 564f1aef9bSTianjia Zhang 574f1aef9bSTianjia Zhang kernel_neon_end(); 58*62508017STianjia Zhang } 594f1aef9bSTianjia Zhang 60*62508017STianjia Zhang err = skcipher_walk_done(&walk, nbytes % SM4_BLOCK_SIZE); 614f1aef9bSTianjia Zhang } 624f1aef9bSTianjia Zhang 634f1aef9bSTianjia Zhang return err; 644f1aef9bSTianjia Zhang } 654f1aef9bSTianjia Zhang 664f1aef9bSTianjia Zhang static int sm4_ecb_encrypt(struct skcipher_request *req) 674f1aef9bSTianjia Zhang { 684f1aef9bSTianjia Zhang struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 694f1aef9bSTianjia Zhang struct sm4_ctx *ctx = crypto_skcipher_ctx(tfm); 704f1aef9bSTianjia Zhang 714f1aef9bSTianjia Zhang return sm4_ecb_do_crypt(req, ctx->rkey_enc); 724f1aef9bSTianjia Zhang } 734f1aef9bSTianjia Zhang 744f1aef9bSTianjia Zhang static int sm4_ecb_decrypt(struct skcipher_request *req) 754f1aef9bSTianjia Zhang { 764f1aef9bSTianjia Zhang struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 774f1aef9bSTianjia Zhang struct sm4_ctx *ctx = crypto_skcipher_ctx(tfm); 784f1aef9bSTianjia Zhang 794f1aef9bSTianjia Zhang return sm4_ecb_do_crypt(req, ctx->rkey_dec); 804f1aef9bSTianjia Zhang } 814f1aef9bSTianjia Zhang 824f1aef9bSTianjia Zhang static int sm4_cbc_encrypt(struct skcipher_request *req) 834f1aef9bSTianjia Zhang { 844f1aef9bSTianjia Zhang struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 854f1aef9bSTianjia Zhang struct sm4_ctx *ctx = crypto_skcipher_ctx(tfm); 864f1aef9bSTianjia Zhang struct skcipher_walk walk; 874f1aef9bSTianjia Zhang unsigned int nbytes; 884f1aef9bSTianjia Zhang int err; 894f1aef9bSTianjia Zhang 904f1aef9bSTianjia Zhang err = skcipher_walk_virt(&walk, req, false); 914f1aef9bSTianjia Zhang 924f1aef9bSTianjia Zhang while ((nbytes = walk.nbytes) > 0) { 934f1aef9bSTianjia Zhang const u8 *iv = walk.iv; 944f1aef9bSTianjia Zhang const u8 *src = walk.src.virt.addr; 954f1aef9bSTianjia Zhang u8 *dst = walk.dst.virt.addr; 964f1aef9bSTianjia Zhang 974f1aef9bSTianjia Zhang while (nbytes >= SM4_BLOCK_SIZE) { 984f1aef9bSTianjia Zhang crypto_xor_cpy(dst, src, iv, SM4_BLOCK_SIZE); 994f1aef9bSTianjia Zhang sm4_crypt_block(ctx->rkey_enc, dst, dst); 1004f1aef9bSTianjia Zhang iv = dst; 1014f1aef9bSTianjia Zhang src += SM4_BLOCK_SIZE; 1024f1aef9bSTianjia Zhang dst += SM4_BLOCK_SIZE; 1034f1aef9bSTianjia Zhang nbytes -= SM4_BLOCK_SIZE; 1044f1aef9bSTianjia Zhang } 1054f1aef9bSTianjia Zhang if (iv != walk.iv) 1064f1aef9bSTianjia Zhang memcpy(walk.iv, iv, SM4_BLOCK_SIZE); 1074f1aef9bSTianjia Zhang 1084f1aef9bSTianjia Zhang err = skcipher_walk_done(&walk, nbytes); 1094f1aef9bSTianjia Zhang } 1104f1aef9bSTianjia Zhang 1114f1aef9bSTianjia Zhang return err; 1124f1aef9bSTianjia Zhang } 1134f1aef9bSTianjia Zhang 1144f1aef9bSTianjia Zhang static int sm4_cbc_decrypt(struct skcipher_request *req) 1154f1aef9bSTianjia Zhang { 1164f1aef9bSTianjia Zhang struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 1174f1aef9bSTianjia Zhang struct sm4_ctx *ctx = crypto_skcipher_ctx(tfm); 1184f1aef9bSTianjia Zhang struct skcipher_walk walk; 1194f1aef9bSTianjia Zhang unsigned int nbytes; 1204f1aef9bSTianjia Zhang int err; 1214f1aef9bSTianjia Zhang 1224f1aef9bSTianjia Zhang err = skcipher_walk_virt(&walk, req, false); 1234f1aef9bSTianjia Zhang 1244f1aef9bSTianjia Zhang while ((nbytes = walk.nbytes) > 0) { 1254f1aef9bSTianjia Zhang const u8 *src = walk.src.virt.addr; 1264f1aef9bSTianjia Zhang u8 *dst = walk.dst.virt.addr; 127*62508017STianjia Zhang unsigned int nblocks; 1284f1aef9bSTianjia Zhang 129*62508017STianjia Zhang nblocks = nbytes / SM4_BLOCK_SIZE; 130*62508017STianjia Zhang if (nblocks) { 1314f1aef9bSTianjia Zhang kernel_neon_begin(); 1324f1aef9bSTianjia Zhang 133*62508017STianjia Zhang sm4_neon_cbc_dec(ctx->rkey_dec, dst, src, 134*62508017STianjia Zhang walk.iv, nblocks); 1354f1aef9bSTianjia Zhang 1364f1aef9bSTianjia Zhang kernel_neon_end(); 137*62508017STianjia Zhang } 1384f1aef9bSTianjia Zhang 139*62508017STianjia Zhang err = skcipher_walk_done(&walk, nbytes % SM4_BLOCK_SIZE); 1404f1aef9bSTianjia Zhang } 1414f1aef9bSTianjia Zhang 1424f1aef9bSTianjia Zhang return err; 1434f1aef9bSTianjia Zhang } 1444f1aef9bSTianjia Zhang 1454f1aef9bSTianjia Zhang static int sm4_cfb_encrypt(struct skcipher_request *req) 1464f1aef9bSTianjia Zhang { 1474f1aef9bSTianjia Zhang struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 1484f1aef9bSTianjia Zhang struct sm4_ctx *ctx = crypto_skcipher_ctx(tfm); 1494f1aef9bSTianjia Zhang struct skcipher_walk walk; 1504f1aef9bSTianjia Zhang unsigned int nbytes; 1514f1aef9bSTianjia Zhang int err; 1524f1aef9bSTianjia Zhang 1534f1aef9bSTianjia Zhang err = skcipher_walk_virt(&walk, req, false); 1544f1aef9bSTianjia Zhang 1554f1aef9bSTianjia Zhang while ((nbytes = walk.nbytes) > 0) { 1564f1aef9bSTianjia Zhang u8 keystream[SM4_BLOCK_SIZE]; 1574f1aef9bSTianjia Zhang const u8 *iv = walk.iv; 1584f1aef9bSTianjia Zhang const u8 *src = walk.src.virt.addr; 1594f1aef9bSTianjia Zhang u8 *dst = walk.dst.virt.addr; 1604f1aef9bSTianjia Zhang 1614f1aef9bSTianjia Zhang while (nbytes >= SM4_BLOCK_SIZE) { 1624f1aef9bSTianjia Zhang sm4_crypt_block(ctx->rkey_enc, keystream, iv); 1634f1aef9bSTianjia Zhang crypto_xor_cpy(dst, src, keystream, SM4_BLOCK_SIZE); 1644f1aef9bSTianjia Zhang iv = dst; 1654f1aef9bSTianjia Zhang src += SM4_BLOCK_SIZE; 1664f1aef9bSTianjia Zhang dst += SM4_BLOCK_SIZE; 1674f1aef9bSTianjia Zhang nbytes -= SM4_BLOCK_SIZE; 1684f1aef9bSTianjia Zhang } 1694f1aef9bSTianjia Zhang if (iv != walk.iv) 1704f1aef9bSTianjia Zhang memcpy(walk.iv, iv, SM4_BLOCK_SIZE); 1714f1aef9bSTianjia Zhang 1724f1aef9bSTianjia Zhang /* tail */ 1734f1aef9bSTianjia Zhang if (walk.nbytes == walk.total && nbytes > 0) { 1744f1aef9bSTianjia Zhang sm4_crypt_block(ctx->rkey_enc, keystream, walk.iv); 1754f1aef9bSTianjia Zhang crypto_xor_cpy(dst, src, keystream, nbytes); 1764f1aef9bSTianjia Zhang nbytes = 0; 1774f1aef9bSTianjia Zhang } 1784f1aef9bSTianjia Zhang 1794f1aef9bSTianjia Zhang err = skcipher_walk_done(&walk, nbytes); 1804f1aef9bSTianjia Zhang } 1814f1aef9bSTianjia Zhang 1824f1aef9bSTianjia Zhang return err; 1834f1aef9bSTianjia Zhang } 1844f1aef9bSTianjia Zhang 1854f1aef9bSTianjia Zhang static int sm4_cfb_decrypt(struct skcipher_request *req) 1864f1aef9bSTianjia Zhang { 1874f1aef9bSTianjia Zhang struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 1884f1aef9bSTianjia Zhang struct sm4_ctx *ctx = crypto_skcipher_ctx(tfm); 1894f1aef9bSTianjia Zhang struct skcipher_walk walk; 1904f1aef9bSTianjia Zhang unsigned int nbytes; 1914f1aef9bSTianjia Zhang int err; 1924f1aef9bSTianjia Zhang 1934f1aef9bSTianjia Zhang err = skcipher_walk_virt(&walk, req, false); 1944f1aef9bSTianjia Zhang 1954f1aef9bSTianjia Zhang while ((nbytes = walk.nbytes) > 0) { 1964f1aef9bSTianjia Zhang const u8 *src = walk.src.virt.addr; 1974f1aef9bSTianjia Zhang u8 *dst = walk.dst.virt.addr; 198*62508017STianjia Zhang unsigned int nblocks; 1994f1aef9bSTianjia Zhang 200*62508017STianjia Zhang nblocks = nbytes / SM4_BLOCK_SIZE; 201*62508017STianjia Zhang if (nblocks) { 2024f1aef9bSTianjia Zhang kernel_neon_begin(); 2034f1aef9bSTianjia Zhang 204*62508017STianjia Zhang sm4_neon_cfb_dec(ctx->rkey_enc, dst, src, 205*62508017STianjia Zhang walk.iv, nblocks); 2064f1aef9bSTianjia Zhang 2074f1aef9bSTianjia Zhang kernel_neon_end(); 2084f1aef9bSTianjia Zhang 209*62508017STianjia Zhang dst += nblocks * SM4_BLOCK_SIZE; 210*62508017STianjia Zhang src += nblocks * SM4_BLOCK_SIZE; 211*62508017STianjia Zhang nbytes -= nblocks * SM4_BLOCK_SIZE; 212*62508017STianjia Zhang } 213*62508017STianjia Zhang 2144f1aef9bSTianjia Zhang /* tail */ 2154f1aef9bSTianjia Zhang if (walk.nbytes == walk.total && nbytes > 0) { 2164f1aef9bSTianjia Zhang u8 keystream[SM4_BLOCK_SIZE]; 2174f1aef9bSTianjia Zhang 2184f1aef9bSTianjia Zhang sm4_crypt_block(ctx->rkey_enc, keystream, walk.iv); 2194f1aef9bSTianjia Zhang crypto_xor_cpy(dst, src, keystream, nbytes); 2204f1aef9bSTianjia Zhang nbytes = 0; 2214f1aef9bSTianjia Zhang } 2224f1aef9bSTianjia Zhang 2234f1aef9bSTianjia Zhang err = skcipher_walk_done(&walk, nbytes); 2244f1aef9bSTianjia Zhang } 2254f1aef9bSTianjia Zhang 2264f1aef9bSTianjia Zhang return err; 2274f1aef9bSTianjia Zhang } 2284f1aef9bSTianjia Zhang 2294f1aef9bSTianjia Zhang static int sm4_ctr_crypt(struct skcipher_request *req) 2304f1aef9bSTianjia Zhang { 2314f1aef9bSTianjia Zhang struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 2324f1aef9bSTianjia Zhang struct sm4_ctx *ctx = crypto_skcipher_ctx(tfm); 2334f1aef9bSTianjia Zhang struct skcipher_walk walk; 2344f1aef9bSTianjia Zhang unsigned int nbytes; 2354f1aef9bSTianjia Zhang int err; 2364f1aef9bSTianjia Zhang 2374f1aef9bSTianjia Zhang err = skcipher_walk_virt(&walk, req, false); 2384f1aef9bSTianjia Zhang 2394f1aef9bSTianjia Zhang while ((nbytes = walk.nbytes) > 0) { 2404f1aef9bSTianjia Zhang const u8 *src = walk.src.virt.addr; 2414f1aef9bSTianjia Zhang u8 *dst = walk.dst.virt.addr; 242*62508017STianjia Zhang unsigned int nblocks; 2434f1aef9bSTianjia Zhang 244*62508017STianjia Zhang nblocks = nbytes / SM4_BLOCK_SIZE; 245*62508017STianjia Zhang if (nblocks) { 2464f1aef9bSTianjia Zhang kernel_neon_begin(); 2474f1aef9bSTianjia Zhang 248*62508017STianjia Zhang sm4_neon_ctr_crypt(ctx->rkey_enc, dst, src, 249*62508017STianjia Zhang walk.iv, nblocks); 2504f1aef9bSTianjia Zhang 2514f1aef9bSTianjia Zhang kernel_neon_end(); 2524f1aef9bSTianjia Zhang 253*62508017STianjia Zhang dst += nblocks * SM4_BLOCK_SIZE; 254*62508017STianjia Zhang src += nblocks * SM4_BLOCK_SIZE; 255*62508017STianjia Zhang nbytes -= nblocks * SM4_BLOCK_SIZE; 256*62508017STianjia Zhang } 257*62508017STianjia Zhang 2584f1aef9bSTianjia Zhang /* tail */ 2594f1aef9bSTianjia Zhang if (walk.nbytes == walk.total && nbytes > 0) { 2604f1aef9bSTianjia Zhang u8 keystream[SM4_BLOCK_SIZE]; 2614f1aef9bSTianjia Zhang 2624f1aef9bSTianjia Zhang sm4_crypt_block(ctx->rkey_enc, keystream, walk.iv); 2634f1aef9bSTianjia Zhang crypto_inc(walk.iv, SM4_BLOCK_SIZE); 2644f1aef9bSTianjia Zhang crypto_xor_cpy(dst, src, keystream, nbytes); 2654f1aef9bSTianjia Zhang nbytes = 0; 2664f1aef9bSTianjia Zhang } 2674f1aef9bSTianjia Zhang 2684f1aef9bSTianjia Zhang err = skcipher_walk_done(&walk, nbytes); 2694f1aef9bSTianjia Zhang } 2704f1aef9bSTianjia Zhang 2714f1aef9bSTianjia Zhang return err; 2724f1aef9bSTianjia Zhang } 2734f1aef9bSTianjia Zhang 2744f1aef9bSTianjia Zhang static struct skcipher_alg sm4_algs[] = { 2754f1aef9bSTianjia Zhang { 2764f1aef9bSTianjia Zhang .base = { 2774f1aef9bSTianjia Zhang .cra_name = "ecb(sm4)", 2784f1aef9bSTianjia Zhang .cra_driver_name = "ecb-sm4-neon", 2794f1aef9bSTianjia Zhang .cra_priority = 200, 2804f1aef9bSTianjia Zhang .cra_blocksize = SM4_BLOCK_SIZE, 2814f1aef9bSTianjia Zhang .cra_ctxsize = sizeof(struct sm4_ctx), 2824f1aef9bSTianjia Zhang .cra_module = THIS_MODULE, 2834f1aef9bSTianjia Zhang }, 2844f1aef9bSTianjia Zhang .min_keysize = SM4_KEY_SIZE, 2854f1aef9bSTianjia Zhang .max_keysize = SM4_KEY_SIZE, 2864f1aef9bSTianjia Zhang .setkey = sm4_setkey, 2874f1aef9bSTianjia Zhang .encrypt = sm4_ecb_encrypt, 2884f1aef9bSTianjia Zhang .decrypt = sm4_ecb_decrypt, 2894f1aef9bSTianjia Zhang }, { 2904f1aef9bSTianjia Zhang .base = { 2914f1aef9bSTianjia Zhang .cra_name = "cbc(sm4)", 2924f1aef9bSTianjia Zhang .cra_driver_name = "cbc-sm4-neon", 2934f1aef9bSTianjia Zhang .cra_priority = 200, 2944f1aef9bSTianjia Zhang .cra_blocksize = SM4_BLOCK_SIZE, 2954f1aef9bSTianjia Zhang .cra_ctxsize = sizeof(struct sm4_ctx), 2964f1aef9bSTianjia Zhang .cra_module = THIS_MODULE, 2974f1aef9bSTianjia Zhang }, 2984f1aef9bSTianjia Zhang .min_keysize = SM4_KEY_SIZE, 2994f1aef9bSTianjia Zhang .max_keysize = SM4_KEY_SIZE, 3004f1aef9bSTianjia Zhang .ivsize = SM4_BLOCK_SIZE, 3014f1aef9bSTianjia Zhang .setkey = sm4_setkey, 3024f1aef9bSTianjia Zhang .encrypt = sm4_cbc_encrypt, 3034f1aef9bSTianjia Zhang .decrypt = sm4_cbc_decrypt, 3044f1aef9bSTianjia Zhang }, { 3054f1aef9bSTianjia Zhang .base = { 3064f1aef9bSTianjia Zhang .cra_name = "cfb(sm4)", 3074f1aef9bSTianjia Zhang .cra_driver_name = "cfb-sm4-neon", 3084f1aef9bSTianjia Zhang .cra_priority = 200, 3094f1aef9bSTianjia Zhang .cra_blocksize = 1, 3104f1aef9bSTianjia Zhang .cra_ctxsize = sizeof(struct sm4_ctx), 3114f1aef9bSTianjia Zhang .cra_module = THIS_MODULE, 3124f1aef9bSTianjia Zhang }, 3134f1aef9bSTianjia Zhang .min_keysize = SM4_KEY_SIZE, 3144f1aef9bSTianjia Zhang .max_keysize = SM4_KEY_SIZE, 3154f1aef9bSTianjia Zhang .ivsize = SM4_BLOCK_SIZE, 3164f1aef9bSTianjia Zhang .chunksize = SM4_BLOCK_SIZE, 3174f1aef9bSTianjia Zhang .setkey = sm4_setkey, 3184f1aef9bSTianjia Zhang .encrypt = sm4_cfb_encrypt, 3194f1aef9bSTianjia Zhang .decrypt = sm4_cfb_decrypt, 3204f1aef9bSTianjia Zhang }, { 3214f1aef9bSTianjia Zhang .base = { 3224f1aef9bSTianjia Zhang .cra_name = "ctr(sm4)", 3234f1aef9bSTianjia Zhang .cra_driver_name = "ctr-sm4-neon", 3244f1aef9bSTianjia Zhang .cra_priority = 200, 3254f1aef9bSTianjia Zhang .cra_blocksize = 1, 3264f1aef9bSTianjia Zhang .cra_ctxsize = sizeof(struct sm4_ctx), 3274f1aef9bSTianjia Zhang .cra_module = THIS_MODULE, 3284f1aef9bSTianjia Zhang }, 3294f1aef9bSTianjia Zhang .min_keysize = SM4_KEY_SIZE, 3304f1aef9bSTianjia Zhang .max_keysize = SM4_KEY_SIZE, 3314f1aef9bSTianjia Zhang .ivsize = SM4_BLOCK_SIZE, 3324f1aef9bSTianjia Zhang .chunksize = SM4_BLOCK_SIZE, 3334f1aef9bSTianjia Zhang .setkey = sm4_setkey, 3344f1aef9bSTianjia Zhang .encrypt = sm4_ctr_crypt, 3354f1aef9bSTianjia Zhang .decrypt = sm4_ctr_crypt, 3364f1aef9bSTianjia Zhang } 3374f1aef9bSTianjia Zhang }; 3384f1aef9bSTianjia Zhang 3394f1aef9bSTianjia Zhang static int __init sm4_init(void) 3404f1aef9bSTianjia Zhang { 3414f1aef9bSTianjia Zhang return crypto_register_skciphers(sm4_algs, ARRAY_SIZE(sm4_algs)); 3424f1aef9bSTianjia Zhang } 3434f1aef9bSTianjia Zhang 3444f1aef9bSTianjia Zhang static void __exit sm4_exit(void) 3454f1aef9bSTianjia Zhang { 3464f1aef9bSTianjia Zhang crypto_unregister_skciphers(sm4_algs, ARRAY_SIZE(sm4_algs)); 3474f1aef9bSTianjia Zhang } 3484f1aef9bSTianjia Zhang 3494f1aef9bSTianjia Zhang module_init(sm4_init); 3504f1aef9bSTianjia Zhang module_exit(sm4_exit); 3514f1aef9bSTianjia Zhang 3524f1aef9bSTianjia Zhang MODULE_DESCRIPTION("SM4 ECB/CBC/CFB/CTR using ARMv8 NEON"); 3534f1aef9bSTianjia Zhang MODULE_ALIAS_CRYPTO("sm4-neon"); 3544f1aef9bSTianjia Zhang MODULE_ALIAS_CRYPTO("sm4"); 3554f1aef9bSTianjia Zhang MODULE_ALIAS_CRYPTO("ecb(sm4)"); 3564f1aef9bSTianjia Zhang MODULE_ALIAS_CRYPTO("cbc(sm4)"); 3574f1aef9bSTianjia Zhang MODULE_ALIAS_CRYPTO("cfb(sm4)"); 3584f1aef9bSTianjia Zhang MODULE_ALIAS_CRYPTO("ctr(sm4)"); 3594f1aef9bSTianjia Zhang MODULE_AUTHOR("Tianjia Zhang <tianjia.zhang@linux.alibaba.com>"); 3604f1aef9bSTianjia Zhang MODULE_LICENSE("GPL v2"); 361