790efcb6df3b244055b46ad79c6ca7355c1edae2
[linux-2.6-microblaze.git] / arch / x86 / crypto / cast6_avx_glue.c
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 #include <asm/crypto/glue_helper.h>
19
20 #define CAST6_PARALLEL_BLOCKS 8
21
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);
24
25 asmlinkage void cast6_cbc_dec_8way(const void *ctx, u8 *dst, const u8 *src);
26
27 static int cast6_setkey_skcipher(struct crypto_skcipher *tfm,
28                                  const u8 *key, unsigned int keylen)
29 {
30         return cast6_setkey(&tfm->base, key, keylen);
31 }
32
33 static const struct common_glue_ctx cast6_enc = {
34         .num_funcs = 2,
35         .fpu_blocks_limit = CAST6_PARALLEL_BLOCKS,
36
37         .funcs = { {
38                 .num_blocks = CAST6_PARALLEL_BLOCKS,
39                 .fn_u = { .ecb = cast6_ecb_enc_8way }
40         }, {
41                 .num_blocks = 1,
42                 .fn_u = { .ecb = __cast6_encrypt }
43         } }
44 };
45
46 static const struct common_glue_ctx cast6_dec = {
47         .num_funcs = 2,
48         .fpu_blocks_limit = CAST6_PARALLEL_BLOCKS,
49
50         .funcs = { {
51                 .num_blocks = CAST6_PARALLEL_BLOCKS,
52                 .fn_u = { .ecb = cast6_ecb_dec_8way }
53         }, {
54                 .num_blocks = 1,
55                 .fn_u = { .ecb = __cast6_decrypt }
56         } }
57 };
58
59 static const struct common_glue_ctx cast6_dec_cbc = {
60         .num_funcs = 2,
61         .fpu_blocks_limit = CAST6_PARALLEL_BLOCKS,
62
63         .funcs = { {
64                 .num_blocks = CAST6_PARALLEL_BLOCKS,
65                 .fn_u = { .cbc = cast6_cbc_dec_8way }
66         }, {
67                 .num_blocks = 1,
68                 .fn_u = { .cbc = __cast6_decrypt }
69         } }
70 };
71
72 static int ecb_encrypt(struct skcipher_request *req)
73 {
74         return glue_ecb_req_128bit(&cast6_enc, req);
75 }
76
77 static int ecb_decrypt(struct skcipher_request *req)
78 {
79         return glue_ecb_req_128bit(&cast6_dec, req);
80 }
81
82 static int cbc_encrypt(struct skcipher_request *req)
83 {
84         return glue_cbc_encrypt_req_128bit(__cast6_encrypt, req);
85 }
86
87 static int cbc_decrypt(struct skcipher_request *req)
88 {
89         return glue_cbc_decrypt_req_128bit(&cast6_dec_cbc, req);
90 }
91
92 static struct skcipher_alg cast6_algs[] = {
93         {
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,
106         }, {
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,
120         },
121 };
122
123 static struct simd_skcipher_alg *cast6_simd_algs[ARRAY_SIZE(cast6_algs)];
124
125 static int __init cast6_init(void)
126 {
127         const char *feature_name;
128
129         if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
130                                 &feature_name)) {
131                 pr_info("CPU feature '%s' is not supported.\n", feature_name);
132                 return -ENODEV;
133         }
134
135         return simd_register_skciphers_compat(cast6_algs,
136                                               ARRAY_SIZE(cast6_algs),
137                                               cast6_simd_algs);
138 }
139
140 static void __exit cast6_exit(void)
141 {
142         simd_unregister_skciphers(cast6_algs, ARRAY_SIZE(cast6_algs),
143                                   cast6_simd_algs);
144 }
145
146 module_init(cast6_init);
147 module_exit(cast6_exit);
148
149 MODULE_DESCRIPTION("Cast6 Cipher Algorithm, AVX optimized");
150 MODULE_LICENSE("GPL");
151 MODULE_ALIAS_CRYPTO("cast6");