1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Glue Code for the AVX assembler implementation of the Cast6 Cipher
5 * Copyright (C) 2012 Johannes Goetzfried
6 * <Johannes.Goetzfried@informatik.stud.uni-erlangen.de>
8 * Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
11 #include <linux/module.h>
12 #include <linux/types.h>
13 #include <linux/crypto.h>
14 #include <linux/err.h>
15 #include <crypto/algapi.h>
16 #include <crypto/cast6.h>
17 #include <crypto/internal/simd.h>
18 #include <asm/crypto/glue_helper.h>
20 #define CAST6_PARALLEL_BLOCKS 8
22 asmlinkage void cast6_ecb_enc_8way(const void *ctx, u8 *dst, const u8 *src);
23 asmlinkage void cast6_ecb_dec_8way(const void *ctx, u8 *dst, const u8 *src);
25 asmlinkage void cast6_cbc_dec_8way(const void *ctx, u8 *dst, const u8 *src);
27 static int cast6_setkey_skcipher(struct crypto_skcipher *tfm,
28 const u8 *key, unsigned int keylen)
30 return cast6_setkey(&tfm->base, key, keylen);
33 static const struct common_glue_ctx cast6_enc = {
35 .fpu_blocks_limit = CAST6_PARALLEL_BLOCKS,
38 .num_blocks = CAST6_PARALLEL_BLOCKS,
39 .fn_u = { .ecb = cast6_ecb_enc_8way }
42 .fn_u = { .ecb = __cast6_encrypt }
46 static const struct common_glue_ctx cast6_dec = {
48 .fpu_blocks_limit = CAST6_PARALLEL_BLOCKS,
51 .num_blocks = CAST6_PARALLEL_BLOCKS,
52 .fn_u = { .ecb = cast6_ecb_dec_8way }
55 .fn_u = { .ecb = __cast6_decrypt }
59 static const struct common_glue_ctx cast6_dec_cbc = {
61 .fpu_blocks_limit = CAST6_PARALLEL_BLOCKS,
64 .num_blocks = CAST6_PARALLEL_BLOCKS,
65 .fn_u = { .cbc = cast6_cbc_dec_8way }
68 .fn_u = { .cbc = __cast6_decrypt }
72 static int ecb_encrypt(struct skcipher_request *req)
74 return glue_ecb_req_128bit(&cast6_enc, req);
77 static int ecb_decrypt(struct skcipher_request *req)
79 return glue_ecb_req_128bit(&cast6_dec, req);
82 static int cbc_encrypt(struct skcipher_request *req)
84 return glue_cbc_encrypt_req_128bit(__cast6_encrypt, req);
87 static int cbc_decrypt(struct skcipher_request *req)
89 return glue_cbc_decrypt_req_128bit(&cast6_dec_cbc, req);
92 static struct skcipher_alg cast6_algs[] = {
94 .base.cra_name = "__ecb(cast6)",
95 .base.cra_driver_name = "__ecb-cast6-avx",
96 .base.cra_priority = 200,
97 .base.cra_flags = CRYPTO_ALG_INTERNAL,
98 .base.cra_blocksize = CAST6_BLOCK_SIZE,
99 .base.cra_ctxsize = sizeof(struct cast6_ctx),
100 .base.cra_module = THIS_MODULE,
101 .min_keysize = CAST6_MIN_KEY_SIZE,
102 .max_keysize = CAST6_MAX_KEY_SIZE,
103 .setkey = cast6_setkey_skcipher,
104 .encrypt = ecb_encrypt,
105 .decrypt = ecb_decrypt,
107 .base.cra_name = "__cbc(cast6)",
108 .base.cra_driver_name = "__cbc-cast6-avx",
109 .base.cra_priority = 200,
110 .base.cra_flags = CRYPTO_ALG_INTERNAL,
111 .base.cra_blocksize = CAST6_BLOCK_SIZE,
112 .base.cra_ctxsize = sizeof(struct cast6_ctx),
113 .base.cra_module = THIS_MODULE,
114 .min_keysize = CAST6_MIN_KEY_SIZE,
115 .max_keysize = CAST6_MAX_KEY_SIZE,
116 .ivsize = CAST6_BLOCK_SIZE,
117 .setkey = cast6_setkey_skcipher,
118 .encrypt = cbc_encrypt,
119 .decrypt = cbc_decrypt,
123 static struct simd_skcipher_alg *cast6_simd_algs[ARRAY_SIZE(cast6_algs)];
125 static int __init cast6_init(void)
127 const char *feature_name;
129 if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
131 pr_info("CPU feature '%s' is not supported.\n", feature_name);
135 return simd_register_skciphers_compat(cast6_algs,
136 ARRAY_SIZE(cast6_algs),
140 static void __exit cast6_exit(void)
142 simd_unregister_skciphers(cast6_algs, ARRAY_SIZE(cast6_algs),
146 module_init(cast6_init);
147 module_exit(cast6_exit);
149 MODULE_DESCRIPTION("Cast6 Cipher Algorithm, AVX optimized");
150 MODULE_LICENSE("GPL");
151 MODULE_ALIAS_CRYPTO("cast6");