1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * Glue Code for the AVX assembler implementation of the Cast6 Cipher |
4 | * |
5 | * Copyright (C) 2012 Johannes Goetzfried |
6 | * <Johannes.Goetzfried@informatik.stud.uni-erlangen.de> |
7 | * |
8 | * Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi> |
9 | */ |
10 | |
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 | |
19 | #include "ecb_cbc_helpers.h" |
20 | |
21 | #define CAST6_PARALLEL_BLOCKS 8 |
22 | |
23 | asmlinkage void cast6_ecb_enc_8way(const void *ctx, u8 *dst, const u8 *src); |
24 | asmlinkage void cast6_ecb_dec_8way(const void *ctx, u8 *dst, const u8 *src); |
25 | |
26 | asmlinkage void cast6_cbc_dec_8way(const void *ctx, u8 *dst, const u8 *src); |
27 | |
28 | static int cast6_setkey_skcipher(struct crypto_skcipher *tfm, |
29 | const u8 *key, unsigned int keylen) |
30 | { |
31 | return cast6_setkey(tfm: &tfm->base, key, keylen); |
32 | } |
33 | |
34 | static int ecb_encrypt(struct skcipher_request *req) |
35 | { |
36 | ECB_WALK_START(req, CAST6_BLOCK_SIZE, CAST6_PARALLEL_BLOCKS); |
37 | ECB_BLOCK(CAST6_PARALLEL_BLOCKS, cast6_ecb_enc_8way); |
38 | ECB_BLOCK(1, __cast6_encrypt); |
39 | ECB_WALK_END(); |
40 | } |
41 | |
42 | static int ecb_decrypt(struct skcipher_request *req) |
43 | { |
44 | ECB_WALK_START(req, CAST6_BLOCK_SIZE, CAST6_PARALLEL_BLOCKS); |
45 | ECB_BLOCK(CAST6_PARALLEL_BLOCKS, cast6_ecb_dec_8way); |
46 | ECB_BLOCK(1, __cast6_decrypt); |
47 | ECB_WALK_END(); |
48 | } |
49 | |
50 | static int cbc_encrypt(struct skcipher_request *req) |
51 | { |
52 | CBC_WALK_START(req, CAST6_BLOCK_SIZE, -1); |
53 | CBC_ENC_BLOCK(__cast6_encrypt); |
54 | CBC_WALK_END(); |
55 | } |
56 | |
57 | static int cbc_decrypt(struct skcipher_request *req) |
58 | { |
59 | CBC_WALK_START(req, CAST6_BLOCK_SIZE, CAST6_PARALLEL_BLOCKS); |
60 | CBC_DEC_BLOCK(CAST6_PARALLEL_BLOCKS, cast6_cbc_dec_8way); |
61 | CBC_DEC_BLOCK(1, __cast6_decrypt); |
62 | CBC_WALK_END(); |
63 | } |
64 | |
65 | static struct skcipher_alg cast6_algs[] = { |
66 | { |
67 | .base.cra_name = "__ecb(cast6)" , |
68 | .base.cra_driver_name = "__ecb-cast6-avx" , |
69 | .base.cra_priority = 200, |
70 | .base.cra_flags = CRYPTO_ALG_INTERNAL, |
71 | .base.cra_blocksize = CAST6_BLOCK_SIZE, |
72 | .base.cra_ctxsize = sizeof(struct cast6_ctx), |
73 | .base.cra_module = THIS_MODULE, |
74 | .min_keysize = CAST6_MIN_KEY_SIZE, |
75 | .max_keysize = CAST6_MAX_KEY_SIZE, |
76 | .setkey = cast6_setkey_skcipher, |
77 | .encrypt = ecb_encrypt, |
78 | .decrypt = ecb_decrypt, |
79 | }, { |
80 | .base.cra_name = "__cbc(cast6)" , |
81 | .base.cra_driver_name = "__cbc-cast6-avx" , |
82 | .base.cra_priority = 200, |
83 | .base.cra_flags = CRYPTO_ALG_INTERNAL, |
84 | .base.cra_blocksize = CAST6_BLOCK_SIZE, |
85 | .base.cra_ctxsize = sizeof(struct cast6_ctx), |
86 | .base.cra_module = THIS_MODULE, |
87 | .min_keysize = CAST6_MIN_KEY_SIZE, |
88 | .max_keysize = CAST6_MAX_KEY_SIZE, |
89 | .ivsize = CAST6_BLOCK_SIZE, |
90 | .setkey = cast6_setkey_skcipher, |
91 | .encrypt = cbc_encrypt, |
92 | .decrypt = cbc_decrypt, |
93 | }, |
94 | }; |
95 | |
96 | static struct simd_skcipher_alg *cast6_simd_algs[ARRAY_SIZE(cast6_algs)]; |
97 | |
98 | static int __init cast6_init(void) |
99 | { |
100 | const char *feature_name; |
101 | |
102 | if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, |
103 | feature_name: &feature_name)) { |
104 | pr_info("CPU feature '%s' is not supported.\n" , feature_name); |
105 | return -ENODEV; |
106 | } |
107 | |
108 | return simd_register_skciphers_compat(algs: cast6_algs, |
109 | ARRAY_SIZE(cast6_algs), |
110 | simd_algs: cast6_simd_algs); |
111 | } |
112 | |
113 | static void __exit cast6_exit(void) |
114 | { |
115 | simd_unregister_skciphers(algs: cast6_algs, ARRAY_SIZE(cast6_algs), |
116 | simd_algs: cast6_simd_algs); |
117 | } |
118 | |
119 | module_init(cast6_init); |
120 | module_exit(cast6_exit); |
121 | |
122 | MODULE_DESCRIPTION("Cast6 Cipher Algorithm, AVX optimized" ); |
123 | MODULE_LICENSE("GPL" ); |
124 | MODULE_ALIAS_CRYPTO("cast6" ); |
125 | |