18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Glue Code for the AVX assembler implementation of the Cast5 Cipher 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2012 Johannes Goetzfried 68c2ecf20Sopenharmony_ci * <Johannes.Goetzfried@informatik.stud.uni-erlangen.de> 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include <asm/crypto/glue_helper.h> 108c2ecf20Sopenharmony_ci#include <crypto/algapi.h> 118c2ecf20Sopenharmony_ci#include <crypto/cast5.h> 128c2ecf20Sopenharmony_ci#include <crypto/internal/simd.h> 138c2ecf20Sopenharmony_ci#include <linux/crypto.h> 148c2ecf20Sopenharmony_ci#include <linux/err.h> 158c2ecf20Sopenharmony_ci#include <linux/module.h> 168c2ecf20Sopenharmony_ci#include <linux/types.h> 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#define CAST5_PARALLEL_BLOCKS 16 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ciasmlinkage void cast5_ecb_enc_16way(struct cast5_ctx *ctx, u8 *dst, 218c2ecf20Sopenharmony_ci const u8 *src); 228c2ecf20Sopenharmony_ciasmlinkage void cast5_ecb_dec_16way(struct cast5_ctx *ctx, u8 *dst, 238c2ecf20Sopenharmony_ci const u8 *src); 248c2ecf20Sopenharmony_ciasmlinkage void cast5_cbc_dec_16way(struct cast5_ctx *ctx, u8 *dst, 258c2ecf20Sopenharmony_ci const u8 *src); 268c2ecf20Sopenharmony_ciasmlinkage void cast5_ctr_16way(struct cast5_ctx *ctx, u8 *dst, const u8 *src, 278c2ecf20Sopenharmony_ci __be64 *iv); 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_cistatic int cast5_setkey_skcipher(struct crypto_skcipher *tfm, const u8 *key, 308c2ecf20Sopenharmony_ci unsigned int keylen) 318c2ecf20Sopenharmony_ci{ 328c2ecf20Sopenharmony_ci return cast5_setkey(&tfm->base, key, keylen); 338c2ecf20Sopenharmony_ci} 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_cistatic inline bool cast5_fpu_begin(bool fpu_enabled, struct skcipher_walk *walk, 368c2ecf20Sopenharmony_ci unsigned int nbytes) 378c2ecf20Sopenharmony_ci{ 388c2ecf20Sopenharmony_ci return glue_fpu_begin(CAST5_BLOCK_SIZE, CAST5_PARALLEL_BLOCKS, 398c2ecf20Sopenharmony_ci walk, fpu_enabled, nbytes); 408c2ecf20Sopenharmony_ci} 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_cistatic inline void cast5_fpu_end(bool fpu_enabled) 438c2ecf20Sopenharmony_ci{ 448c2ecf20Sopenharmony_ci return glue_fpu_end(fpu_enabled); 458c2ecf20Sopenharmony_ci} 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_cistatic int ecb_crypt(struct skcipher_request *req, bool enc) 488c2ecf20Sopenharmony_ci{ 498c2ecf20Sopenharmony_ci bool fpu_enabled = false; 508c2ecf20Sopenharmony_ci struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 518c2ecf20Sopenharmony_ci struct cast5_ctx *ctx = crypto_skcipher_ctx(tfm); 528c2ecf20Sopenharmony_ci struct skcipher_walk walk; 538c2ecf20Sopenharmony_ci const unsigned int bsize = CAST5_BLOCK_SIZE; 548c2ecf20Sopenharmony_ci unsigned int nbytes; 558c2ecf20Sopenharmony_ci void (*fn)(struct cast5_ctx *ctx, u8 *dst, const u8 *src); 568c2ecf20Sopenharmony_ci int err; 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci err = skcipher_walk_virt(&walk, req, false); 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci while ((nbytes = walk.nbytes)) { 618c2ecf20Sopenharmony_ci u8 *wsrc = walk.src.virt.addr; 628c2ecf20Sopenharmony_ci u8 *wdst = walk.dst.virt.addr; 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci fpu_enabled = cast5_fpu_begin(fpu_enabled, &walk, nbytes); 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci /* Process multi-block batch */ 678c2ecf20Sopenharmony_ci if (nbytes >= bsize * CAST5_PARALLEL_BLOCKS) { 688c2ecf20Sopenharmony_ci fn = (enc) ? cast5_ecb_enc_16way : cast5_ecb_dec_16way; 698c2ecf20Sopenharmony_ci do { 708c2ecf20Sopenharmony_ci fn(ctx, wdst, wsrc); 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci wsrc += bsize * CAST5_PARALLEL_BLOCKS; 738c2ecf20Sopenharmony_ci wdst += bsize * CAST5_PARALLEL_BLOCKS; 748c2ecf20Sopenharmony_ci nbytes -= bsize * CAST5_PARALLEL_BLOCKS; 758c2ecf20Sopenharmony_ci } while (nbytes >= bsize * CAST5_PARALLEL_BLOCKS); 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci if (nbytes < bsize) 788c2ecf20Sopenharmony_ci goto done; 798c2ecf20Sopenharmony_ci } 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci fn = (enc) ? __cast5_encrypt : __cast5_decrypt; 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci /* Handle leftovers */ 848c2ecf20Sopenharmony_ci do { 858c2ecf20Sopenharmony_ci fn(ctx, wdst, wsrc); 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci wsrc += bsize; 888c2ecf20Sopenharmony_ci wdst += bsize; 898c2ecf20Sopenharmony_ci nbytes -= bsize; 908c2ecf20Sopenharmony_ci } while (nbytes >= bsize); 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_cidone: 938c2ecf20Sopenharmony_ci err = skcipher_walk_done(&walk, nbytes); 948c2ecf20Sopenharmony_ci } 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci cast5_fpu_end(fpu_enabled); 978c2ecf20Sopenharmony_ci return err; 988c2ecf20Sopenharmony_ci} 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_cistatic int ecb_encrypt(struct skcipher_request *req) 1018c2ecf20Sopenharmony_ci{ 1028c2ecf20Sopenharmony_ci return ecb_crypt(req, true); 1038c2ecf20Sopenharmony_ci} 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_cistatic int ecb_decrypt(struct skcipher_request *req) 1068c2ecf20Sopenharmony_ci{ 1078c2ecf20Sopenharmony_ci return ecb_crypt(req, false); 1088c2ecf20Sopenharmony_ci} 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_cistatic int cbc_encrypt(struct skcipher_request *req) 1118c2ecf20Sopenharmony_ci{ 1128c2ecf20Sopenharmony_ci const unsigned int bsize = CAST5_BLOCK_SIZE; 1138c2ecf20Sopenharmony_ci struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 1148c2ecf20Sopenharmony_ci struct cast5_ctx *ctx = crypto_skcipher_ctx(tfm); 1158c2ecf20Sopenharmony_ci struct skcipher_walk walk; 1168c2ecf20Sopenharmony_ci unsigned int nbytes; 1178c2ecf20Sopenharmony_ci int err; 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci err = skcipher_walk_virt(&walk, req, false); 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci while ((nbytes = walk.nbytes)) { 1228c2ecf20Sopenharmony_ci u64 *src = (u64 *)walk.src.virt.addr; 1238c2ecf20Sopenharmony_ci u64 *dst = (u64 *)walk.dst.virt.addr; 1248c2ecf20Sopenharmony_ci u64 *iv = (u64 *)walk.iv; 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci do { 1278c2ecf20Sopenharmony_ci *dst = *src ^ *iv; 1288c2ecf20Sopenharmony_ci __cast5_encrypt(ctx, (u8 *)dst, (u8 *)dst); 1298c2ecf20Sopenharmony_ci iv = dst; 1308c2ecf20Sopenharmony_ci src++; 1318c2ecf20Sopenharmony_ci dst++; 1328c2ecf20Sopenharmony_ci nbytes -= bsize; 1338c2ecf20Sopenharmony_ci } while (nbytes >= bsize); 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci *(u64 *)walk.iv = *iv; 1368c2ecf20Sopenharmony_ci err = skcipher_walk_done(&walk, nbytes); 1378c2ecf20Sopenharmony_ci } 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci return err; 1408c2ecf20Sopenharmony_ci} 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_cistatic unsigned int __cbc_decrypt(struct cast5_ctx *ctx, 1438c2ecf20Sopenharmony_ci struct skcipher_walk *walk) 1448c2ecf20Sopenharmony_ci{ 1458c2ecf20Sopenharmony_ci const unsigned int bsize = CAST5_BLOCK_SIZE; 1468c2ecf20Sopenharmony_ci unsigned int nbytes = walk->nbytes; 1478c2ecf20Sopenharmony_ci u64 *src = (u64 *)walk->src.virt.addr; 1488c2ecf20Sopenharmony_ci u64 *dst = (u64 *)walk->dst.virt.addr; 1498c2ecf20Sopenharmony_ci u64 last_iv; 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci /* Start of the last block. */ 1528c2ecf20Sopenharmony_ci src += nbytes / bsize - 1; 1538c2ecf20Sopenharmony_ci dst += nbytes / bsize - 1; 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ci last_iv = *src; 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci /* Process multi-block batch */ 1588c2ecf20Sopenharmony_ci if (nbytes >= bsize * CAST5_PARALLEL_BLOCKS) { 1598c2ecf20Sopenharmony_ci do { 1608c2ecf20Sopenharmony_ci nbytes -= bsize * (CAST5_PARALLEL_BLOCKS - 1); 1618c2ecf20Sopenharmony_ci src -= CAST5_PARALLEL_BLOCKS - 1; 1628c2ecf20Sopenharmony_ci dst -= CAST5_PARALLEL_BLOCKS - 1; 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_ci cast5_cbc_dec_16way(ctx, (u8 *)dst, (u8 *)src); 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci nbytes -= bsize; 1678c2ecf20Sopenharmony_ci if (nbytes < bsize) 1688c2ecf20Sopenharmony_ci goto done; 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci *dst ^= *(src - 1); 1718c2ecf20Sopenharmony_ci src -= 1; 1728c2ecf20Sopenharmony_ci dst -= 1; 1738c2ecf20Sopenharmony_ci } while (nbytes >= bsize * CAST5_PARALLEL_BLOCKS); 1748c2ecf20Sopenharmony_ci } 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci /* Handle leftovers */ 1778c2ecf20Sopenharmony_ci for (;;) { 1788c2ecf20Sopenharmony_ci __cast5_decrypt(ctx, (u8 *)dst, (u8 *)src); 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_ci nbytes -= bsize; 1818c2ecf20Sopenharmony_ci if (nbytes < bsize) 1828c2ecf20Sopenharmony_ci break; 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci *dst ^= *(src - 1); 1858c2ecf20Sopenharmony_ci src -= 1; 1868c2ecf20Sopenharmony_ci dst -= 1; 1878c2ecf20Sopenharmony_ci } 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_cidone: 1908c2ecf20Sopenharmony_ci *dst ^= *(u64 *)walk->iv; 1918c2ecf20Sopenharmony_ci *(u64 *)walk->iv = last_iv; 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_ci return nbytes; 1948c2ecf20Sopenharmony_ci} 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_cistatic int cbc_decrypt(struct skcipher_request *req) 1978c2ecf20Sopenharmony_ci{ 1988c2ecf20Sopenharmony_ci struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 1998c2ecf20Sopenharmony_ci struct cast5_ctx *ctx = crypto_skcipher_ctx(tfm); 2008c2ecf20Sopenharmony_ci bool fpu_enabled = false; 2018c2ecf20Sopenharmony_ci struct skcipher_walk walk; 2028c2ecf20Sopenharmony_ci unsigned int nbytes; 2038c2ecf20Sopenharmony_ci int err; 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_ci err = skcipher_walk_virt(&walk, req, false); 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ci while ((nbytes = walk.nbytes)) { 2088c2ecf20Sopenharmony_ci fpu_enabled = cast5_fpu_begin(fpu_enabled, &walk, nbytes); 2098c2ecf20Sopenharmony_ci nbytes = __cbc_decrypt(ctx, &walk); 2108c2ecf20Sopenharmony_ci err = skcipher_walk_done(&walk, nbytes); 2118c2ecf20Sopenharmony_ci } 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_ci cast5_fpu_end(fpu_enabled); 2148c2ecf20Sopenharmony_ci return err; 2158c2ecf20Sopenharmony_ci} 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_cistatic void ctr_crypt_final(struct skcipher_walk *walk, struct cast5_ctx *ctx) 2188c2ecf20Sopenharmony_ci{ 2198c2ecf20Sopenharmony_ci u8 *ctrblk = walk->iv; 2208c2ecf20Sopenharmony_ci u8 keystream[CAST5_BLOCK_SIZE]; 2218c2ecf20Sopenharmony_ci u8 *src = walk->src.virt.addr; 2228c2ecf20Sopenharmony_ci u8 *dst = walk->dst.virt.addr; 2238c2ecf20Sopenharmony_ci unsigned int nbytes = walk->nbytes; 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ci __cast5_encrypt(ctx, keystream, ctrblk); 2268c2ecf20Sopenharmony_ci crypto_xor_cpy(dst, keystream, src, nbytes); 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_ci crypto_inc(ctrblk, CAST5_BLOCK_SIZE); 2298c2ecf20Sopenharmony_ci} 2308c2ecf20Sopenharmony_ci 2318c2ecf20Sopenharmony_cistatic unsigned int __ctr_crypt(struct skcipher_walk *walk, 2328c2ecf20Sopenharmony_ci struct cast5_ctx *ctx) 2338c2ecf20Sopenharmony_ci{ 2348c2ecf20Sopenharmony_ci const unsigned int bsize = CAST5_BLOCK_SIZE; 2358c2ecf20Sopenharmony_ci unsigned int nbytes = walk->nbytes; 2368c2ecf20Sopenharmony_ci u64 *src = (u64 *)walk->src.virt.addr; 2378c2ecf20Sopenharmony_ci u64 *dst = (u64 *)walk->dst.virt.addr; 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_ci /* Process multi-block batch */ 2408c2ecf20Sopenharmony_ci if (nbytes >= bsize * CAST5_PARALLEL_BLOCKS) { 2418c2ecf20Sopenharmony_ci do { 2428c2ecf20Sopenharmony_ci cast5_ctr_16way(ctx, (u8 *)dst, (u8 *)src, 2438c2ecf20Sopenharmony_ci (__be64 *)walk->iv); 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_ci src += CAST5_PARALLEL_BLOCKS; 2468c2ecf20Sopenharmony_ci dst += CAST5_PARALLEL_BLOCKS; 2478c2ecf20Sopenharmony_ci nbytes -= bsize * CAST5_PARALLEL_BLOCKS; 2488c2ecf20Sopenharmony_ci } while (nbytes >= bsize * CAST5_PARALLEL_BLOCKS); 2498c2ecf20Sopenharmony_ci 2508c2ecf20Sopenharmony_ci if (nbytes < bsize) 2518c2ecf20Sopenharmony_ci goto done; 2528c2ecf20Sopenharmony_ci } 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_ci /* Handle leftovers */ 2558c2ecf20Sopenharmony_ci do { 2568c2ecf20Sopenharmony_ci u64 ctrblk; 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_ci if (dst != src) 2598c2ecf20Sopenharmony_ci *dst = *src; 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_ci ctrblk = *(u64 *)walk->iv; 2628c2ecf20Sopenharmony_ci be64_add_cpu((__be64 *)walk->iv, 1); 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_ci __cast5_encrypt(ctx, (u8 *)&ctrblk, (u8 *)&ctrblk); 2658c2ecf20Sopenharmony_ci *dst ^= ctrblk; 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_ci src += 1; 2688c2ecf20Sopenharmony_ci dst += 1; 2698c2ecf20Sopenharmony_ci nbytes -= bsize; 2708c2ecf20Sopenharmony_ci } while (nbytes >= bsize); 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_cidone: 2738c2ecf20Sopenharmony_ci return nbytes; 2748c2ecf20Sopenharmony_ci} 2758c2ecf20Sopenharmony_ci 2768c2ecf20Sopenharmony_cistatic int ctr_crypt(struct skcipher_request *req) 2778c2ecf20Sopenharmony_ci{ 2788c2ecf20Sopenharmony_ci struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 2798c2ecf20Sopenharmony_ci struct cast5_ctx *ctx = crypto_skcipher_ctx(tfm); 2808c2ecf20Sopenharmony_ci bool fpu_enabled = false; 2818c2ecf20Sopenharmony_ci struct skcipher_walk walk; 2828c2ecf20Sopenharmony_ci unsigned int nbytes; 2838c2ecf20Sopenharmony_ci int err; 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_ci err = skcipher_walk_virt(&walk, req, false); 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci while ((nbytes = walk.nbytes) >= CAST5_BLOCK_SIZE) { 2888c2ecf20Sopenharmony_ci fpu_enabled = cast5_fpu_begin(fpu_enabled, &walk, nbytes); 2898c2ecf20Sopenharmony_ci nbytes = __ctr_crypt(&walk, ctx); 2908c2ecf20Sopenharmony_ci err = skcipher_walk_done(&walk, nbytes); 2918c2ecf20Sopenharmony_ci } 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_ci cast5_fpu_end(fpu_enabled); 2948c2ecf20Sopenharmony_ci 2958c2ecf20Sopenharmony_ci if (walk.nbytes) { 2968c2ecf20Sopenharmony_ci ctr_crypt_final(&walk, ctx); 2978c2ecf20Sopenharmony_ci err = skcipher_walk_done(&walk, 0); 2988c2ecf20Sopenharmony_ci } 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_ci return err; 3018c2ecf20Sopenharmony_ci} 3028c2ecf20Sopenharmony_ci 3038c2ecf20Sopenharmony_cistatic struct skcipher_alg cast5_algs[] = { 3048c2ecf20Sopenharmony_ci { 3058c2ecf20Sopenharmony_ci .base.cra_name = "__ecb(cast5)", 3068c2ecf20Sopenharmony_ci .base.cra_driver_name = "__ecb-cast5-avx", 3078c2ecf20Sopenharmony_ci .base.cra_priority = 200, 3088c2ecf20Sopenharmony_ci .base.cra_flags = CRYPTO_ALG_INTERNAL, 3098c2ecf20Sopenharmony_ci .base.cra_blocksize = CAST5_BLOCK_SIZE, 3108c2ecf20Sopenharmony_ci .base.cra_ctxsize = sizeof(struct cast5_ctx), 3118c2ecf20Sopenharmony_ci .base.cra_module = THIS_MODULE, 3128c2ecf20Sopenharmony_ci .min_keysize = CAST5_MIN_KEY_SIZE, 3138c2ecf20Sopenharmony_ci .max_keysize = CAST5_MAX_KEY_SIZE, 3148c2ecf20Sopenharmony_ci .setkey = cast5_setkey_skcipher, 3158c2ecf20Sopenharmony_ci .encrypt = ecb_encrypt, 3168c2ecf20Sopenharmony_ci .decrypt = ecb_decrypt, 3178c2ecf20Sopenharmony_ci }, { 3188c2ecf20Sopenharmony_ci .base.cra_name = "__cbc(cast5)", 3198c2ecf20Sopenharmony_ci .base.cra_driver_name = "__cbc-cast5-avx", 3208c2ecf20Sopenharmony_ci .base.cra_priority = 200, 3218c2ecf20Sopenharmony_ci .base.cra_flags = CRYPTO_ALG_INTERNAL, 3228c2ecf20Sopenharmony_ci .base.cra_blocksize = CAST5_BLOCK_SIZE, 3238c2ecf20Sopenharmony_ci .base.cra_ctxsize = sizeof(struct cast5_ctx), 3248c2ecf20Sopenharmony_ci .base.cra_module = THIS_MODULE, 3258c2ecf20Sopenharmony_ci .min_keysize = CAST5_MIN_KEY_SIZE, 3268c2ecf20Sopenharmony_ci .max_keysize = CAST5_MAX_KEY_SIZE, 3278c2ecf20Sopenharmony_ci .ivsize = CAST5_BLOCK_SIZE, 3288c2ecf20Sopenharmony_ci .setkey = cast5_setkey_skcipher, 3298c2ecf20Sopenharmony_ci .encrypt = cbc_encrypt, 3308c2ecf20Sopenharmony_ci .decrypt = cbc_decrypt, 3318c2ecf20Sopenharmony_ci }, { 3328c2ecf20Sopenharmony_ci .base.cra_name = "__ctr(cast5)", 3338c2ecf20Sopenharmony_ci .base.cra_driver_name = "__ctr-cast5-avx", 3348c2ecf20Sopenharmony_ci .base.cra_priority = 200, 3358c2ecf20Sopenharmony_ci .base.cra_flags = CRYPTO_ALG_INTERNAL, 3368c2ecf20Sopenharmony_ci .base.cra_blocksize = 1, 3378c2ecf20Sopenharmony_ci .base.cra_ctxsize = sizeof(struct cast5_ctx), 3388c2ecf20Sopenharmony_ci .base.cra_module = THIS_MODULE, 3398c2ecf20Sopenharmony_ci .min_keysize = CAST5_MIN_KEY_SIZE, 3408c2ecf20Sopenharmony_ci .max_keysize = CAST5_MAX_KEY_SIZE, 3418c2ecf20Sopenharmony_ci .ivsize = CAST5_BLOCK_SIZE, 3428c2ecf20Sopenharmony_ci .chunksize = CAST5_BLOCK_SIZE, 3438c2ecf20Sopenharmony_ci .setkey = cast5_setkey_skcipher, 3448c2ecf20Sopenharmony_ci .encrypt = ctr_crypt, 3458c2ecf20Sopenharmony_ci .decrypt = ctr_crypt, 3468c2ecf20Sopenharmony_ci } 3478c2ecf20Sopenharmony_ci}; 3488c2ecf20Sopenharmony_ci 3498c2ecf20Sopenharmony_cistatic struct simd_skcipher_alg *cast5_simd_algs[ARRAY_SIZE(cast5_algs)]; 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_cistatic int __init cast5_init(void) 3528c2ecf20Sopenharmony_ci{ 3538c2ecf20Sopenharmony_ci const char *feature_name; 3548c2ecf20Sopenharmony_ci 3558c2ecf20Sopenharmony_ci if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, 3568c2ecf20Sopenharmony_ci &feature_name)) { 3578c2ecf20Sopenharmony_ci pr_info("CPU feature '%s' is not supported.\n", feature_name); 3588c2ecf20Sopenharmony_ci return -ENODEV; 3598c2ecf20Sopenharmony_ci } 3608c2ecf20Sopenharmony_ci 3618c2ecf20Sopenharmony_ci return simd_register_skciphers_compat(cast5_algs, 3628c2ecf20Sopenharmony_ci ARRAY_SIZE(cast5_algs), 3638c2ecf20Sopenharmony_ci cast5_simd_algs); 3648c2ecf20Sopenharmony_ci} 3658c2ecf20Sopenharmony_ci 3668c2ecf20Sopenharmony_cistatic void __exit cast5_exit(void) 3678c2ecf20Sopenharmony_ci{ 3688c2ecf20Sopenharmony_ci simd_unregister_skciphers(cast5_algs, ARRAY_SIZE(cast5_algs), 3698c2ecf20Sopenharmony_ci cast5_simd_algs); 3708c2ecf20Sopenharmony_ci} 3718c2ecf20Sopenharmony_ci 3728c2ecf20Sopenharmony_cimodule_init(cast5_init); 3738c2ecf20Sopenharmony_cimodule_exit(cast5_exit); 3748c2ecf20Sopenharmony_ci 3758c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Cast5 Cipher Algorithm, AVX optimized"); 3768c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 3778c2ecf20Sopenharmony_ciMODULE_ALIAS_CRYPTO("cast5"); 378