11a59d1b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
24ea1277dSJohannes Goetzfried /*
3a97673a1SIngo Molnar * Glue Code for the AVX assembler implementation of the Cast6 Cipher
44ea1277dSJohannes Goetzfried *
54ea1277dSJohannes Goetzfried * Copyright (C) 2012 Johannes Goetzfried
64ea1277dSJohannes Goetzfried * <Johannes.Goetzfried@informatik.stud.uni-erlangen.de>
74ea1277dSJohannes Goetzfried *
870177286SJussi Kivilinna * Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
94ea1277dSJohannes Goetzfried */
104ea1277dSJohannes Goetzfried
114ea1277dSJohannes Goetzfried #include <linux/module.h>
124ea1277dSJohannes Goetzfried #include <linux/types.h>
134ea1277dSJohannes Goetzfried #include <linux/crypto.h>
144ea1277dSJohannes Goetzfried #include <linux/err.h>
154ea1277dSJohannes Goetzfried #include <crypto/algapi.h>
164ea1277dSJohannes Goetzfried #include <crypto/cast6.h>
174bd96924SEric Biggers #include <crypto/internal/simd.h>
18*ea55cfc3SArd Biesheuvel
19*ea55cfc3SArd Biesheuvel #include "ecb_cbc_helpers.h"
204ea1277dSJohannes Goetzfried
214ea1277dSJohannes Goetzfried #define CAST6_PARALLEL_BLOCKS 8
224ea1277dSJohannes Goetzfried
239c1e8836SKees Cook asmlinkage void cast6_ecb_enc_8way(const void *ctx, u8 *dst, const u8 *src);
249c1e8836SKees Cook asmlinkage void cast6_ecb_dec_8way(const void *ctx, u8 *dst, const u8 *src);
254ea1277dSJohannes Goetzfried
269c1e8836SKees Cook asmlinkage void cast6_cbc_dec_8way(const void *ctx, u8 *dst, const u8 *src);
274ea1277dSJohannes Goetzfried
cast6_setkey_skcipher(struct crypto_skcipher * tfm,const u8 * key,unsigned int keylen)284bd96924SEric Biggers static int cast6_setkey_skcipher(struct crypto_skcipher *tfm,
294bd96924SEric Biggers const u8 *key, unsigned int keylen)
304bd96924SEric Biggers {
314bd96924SEric Biggers return cast6_setkey(&tfm->base, key, keylen);
324bd96924SEric Biggers }
334bd96924SEric Biggers
ecb_encrypt(struct skcipher_request * req)344bd96924SEric Biggers static int ecb_encrypt(struct skcipher_request *req)
354ea1277dSJohannes Goetzfried {
36*ea55cfc3SArd Biesheuvel ECB_WALK_START(req, CAST6_BLOCK_SIZE, CAST6_PARALLEL_BLOCKS);
37*ea55cfc3SArd Biesheuvel ECB_BLOCK(CAST6_PARALLEL_BLOCKS, cast6_ecb_enc_8way);
38*ea55cfc3SArd Biesheuvel ECB_BLOCK(1, __cast6_encrypt);
39*ea55cfc3SArd Biesheuvel ECB_WALK_END();
404ea1277dSJohannes Goetzfried }
414ea1277dSJohannes Goetzfried
ecb_decrypt(struct skcipher_request * req)424bd96924SEric Biggers static int ecb_decrypt(struct skcipher_request *req)
434ea1277dSJohannes Goetzfried {
44*ea55cfc3SArd Biesheuvel ECB_WALK_START(req, CAST6_BLOCK_SIZE, CAST6_PARALLEL_BLOCKS);
45*ea55cfc3SArd Biesheuvel ECB_BLOCK(CAST6_PARALLEL_BLOCKS, cast6_ecb_dec_8way);
46*ea55cfc3SArd Biesheuvel ECB_BLOCK(1, __cast6_decrypt);
47*ea55cfc3SArd Biesheuvel ECB_WALK_END();
484ea1277dSJohannes Goetzfried }
494ea1277dSJohannes Goetzfried
cbc_encrypt(struct skcipher_request * req)504bd96924SEric Biggers static int cbc_encrypt(struct skcipher_request *req)
514ea1277dSJohannes Goetzfried {
52*ea55cfc3SArd Biesheuvel CBC_WALK_START(req, CAST6_BLOCK_SIZE, -1);
53*ea55cfc3SArd Biesheuvel CBC_ENC_BLOCK(__cast6_encrypt);
54*ea55cfc3SArd Biesheuvel CBC_WALK_END();
554ea1277dSJohannes Goetzfried }
564ea1277dSJohannes Goetzfried
cbc_decrypt(struct skcipher_request * req)574bd96924SEric Biggers static int cbc_decrypt(struct skcipher_request *req)
584ea1277dSJohannes Goetzfried {
59*ea55cfc3SArd Biesheuvel CBC_WALK_START(req, CAST6_BLOCK_SIZE, CAST6_PARALLEL_BLOCKS);
60*ea55cfc3SArd Biesheuvel CBC_DEC_BLOCK(CAST6_PARALLEL_BLOCKS, cast6_cbc_dec_8way);
61*ea55cfc3SArd Biesheuvel CBC_DEC_BLOCK(1, __cast6_decrypt);
62*ea55cfc3SArd Biesheuvel CBC_WALK_END();
634ea1277dSJohannes Goetzfried }
644ea1277dSJohannes Goetzfried
654bd96924SEric Biggers static struct skcipher_alg cast6_algs[] = {
664bd96924SEric Biggers {
674bd96924SEric Biggers .base.cra_name = "__ecb(cast6)",
684bd96924SEric Biggers .base.cra_driver_name = "__ecb-cast6-avx",
694bd96924SEric Biggers .base.cra_priority = 200,
704bd96924SEric Biggers .base.cra_flags = CRYPTO_ALG_INTERNAL,
714bd96924SEric Biggers .base.cra_blocksize = CAST6_BLOCK_SIZE,
724bd96924SEric Biggers .base.cra_ctxsize = sizeof(struct cast6_ctx),
734bd96924SEric Biggers .base.cra_module = THIS_MODULE,
744ea1277dSJohannes Goetzfried .min_keysize = CAST6_MIN_KEY_SIZE,
754ea1277dSJohannes Goetzfried .max_keysize = CAST6_MAX_KEY_SIZE,
764bd96924SEric Biggers .setkey = cast6_setkey_skcipher,
774ea1277dSJohannes Goetzfried .encrypt = ecb_encrypt,
784ea1277dSJohannes Goetzfried .decrypt = ecb_decrypt,
794ea1277dSJohannes Goetzfried }, {
804bd96924SEric Biggers .base.cra_name = "__cbc(cast6)",
814bd96924SEric Biggers .base.cra_driver_name = "__cbc-cast6-avx",
824bd96924SEric Biggers .base.cra_priority = 200,
834bd96924SEric Biggers .base.cra_flags = CRYPTO_ALG_INTERNAL,
844bd96924SEric Biggers .base.cra_blocksize = CAST6_BLOCK_SIZE,
854bd96924SEric Biggers .base.cra_ctxsize = sizeof(struct cast6_ctx),
864bd96924SEric Biggers .base.cra_module = THIS_MODULE,
874ea1277dSJohannes Goetzfried .min_keysize = CAST6_MIN_KEY_SIZE,
884ea1277dSJohannes Goetzfried .max_keysize = CAST6_MAX_KEY_SIZE,
894ea1277dSJohannes Goetzfried .ivsize = CAST6_BLOCK_SIZE,
904bd96924SEric Biggers .setkey = cast6_setkey_skcipher,
914bd96924SEric Biggers .encrypt = cbc_encrypt,
924bd96924SEric Biggers .decrypt = cbc_decrypt,
934ea1277dSJohannes Goetzfried },
944bd96924SEric Biggers };
954bd96924SEric Biggers
964bd96924SEric Biggers static struct simd_skcipher_alg *cast6_simd_algs[ARRAY_SIZE(cast6_algs)];
974ea1277dSJohannes Goetzfried
cast6_init(void)984ea1277dSJohannes Goetzfried static int __init cast6_init(void)
994ea1277dSJohannes Goetzfried {
1001debf7dbSIngo Molnar const char *feature_name;
1014ea1277dSJohannes Goetzfried
102d91cab78SDave Hansen if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
103d91cab78SDave Hansen &feature_name)) {
1041debf7dbSIngo Molnar pr_info("CPU feature '%s' is not supported.\n", feature_name);
1054ea1277dSJohannes Goetzfried return -ENODEV;
1064ea1277dSJohannes Goetzfried }
1074ea1277dSJohannes Goetzfried
1084bd96924SEric Biggers return simd_register_skciphers_compat(cast6_algs,
1094bd96924SEric Biggers ARRAY_SIZE(cast6_algs),
1104bd96924SEric Biggers cast6_simd_algs);
1114ea1277dSJohannes Goetzfried }
1124ea1277dSJohannes Goetzfried
cast6_exit(void)1134ea1277dSJohannes Goetzfried static void __exit cast6_exit(void)
1144ea1277dSJohannes Goetzfried {
1154bd96924SEric Biggers simd_unregister_skciphers(cast6_algs, ARRAY_SIZE(cast6_algs),
1164bd96924SEric Biggers cast6_simd_algs);
1174ea1277dSJohannes Goetzfried }
1184ea1277dSJohannes Goetzfried
1194ea1277dSJohannes Goetzfried module_init(cast6_init);
1204ea1277dSJohannes Goetzfried module_exit(cast6_exit);
1214ea1277dSJohannes Goetzfried
1224ea1277dSJohannes Goetzfried MODULE_DESCRIPTION("Cast6 Cipher Algorithm, AVX optimized");
1234ea1277dSJohannes Goetzfried MODULE_LICENSE("GPL");
1245d26a105SKees Cook MODULE_ALIAS_CRYPTO("cast6");
125