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
sm4_setkey(struct crypto_skcipher * tfm,const u8 * key,unsigned int key_len)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
sm4_ecb_do_crypt(struct skcipher_request * req,const u32 * rkey)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
sm4_ecb_encrypt(struct skcipher_request * req)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
sm4_ecb_decrypt(struct skcipher_request * req)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
sm4_cbc_encrypt(struct skcipher_request * req)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
sm4_cbc_decrypt(struct skcipher_request * req)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
sm4_cfb_encrypt(struct skcipher_request * req)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
sm4_cfb_decrypt(struct skcipher_request * req)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
sm4_ctr_crypt(struct skcipher_request * req)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
sm4_init(void)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
sm4_exit(void)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