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 <crypto/xts.h>
19 #include <asm/crypto/glue_helper.h>
21 #define CAST6_PARALLEL_BLOCKS 8
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
);
26 asmlinkage
void cast6_cbc_dec_8way(const void *ctx
, u8
*dst
, const u8
*src
);
27 asmlinkage
void cast6_ctr_8way(const void *ctx
, u8
*dst
, const u8
*src
,
30 asmlinkage
void cast6_xts_enc_8way(const void *ctx
, u8
*dst
, const u8
*src
,
32 asmlinkage
void cast6_xts_dec_8way(const void *ctx
, u8
*dst
, const u8
*src
,
35 static int cast6_setkey_skcipher(struct crypto_skcipher
*tfm
,
36 const u8
*key
, unsigned int keylen
)
38 return cast6_setkey(&tfm
->base
, key
, keylen
);
41 static void cast6_xts_enc(const void *ctx
, u8
*dst
, const u8
*src
, le128
*iv
)
43 glue_xts_crypt_128bit_one(ctx
, dst
, src
, iv
, __cast6_encrypt
);
46 static void cast6_xts_dec(const void *ctx
, u8
*dst
, const u8
*src
, le128
*iv
)
48 glue_xts_crypt_128bit_one(ctx
, dst
, src
, iv
, __cast6_decrypt
);
51 static void cast6_crypt_ctr(const void *ctx
, u8
*d
, const u8
*s
, le128
*iv
)
54 u128
*dst
= (u128
*)d
;
55 const u128
*src
= (const u128
*)s
;
57 le128_to_be128(&ctrblk
, iv
);
60 __cast6_encrypt(ctx
, (u8
*)&ctrblk
, (u8
*)&ctrblk
);
61 u128_xor(dst
, src
, (u128
*)&ctrblk
);
64 static const struct common_glue_ctx cast6_enc
= {
66 .fpu_blocks_limit
= CAST6_PARALLEL_BLOCKS
,
69 .num_blocks
= CAST6_PARALLEL_BLOCKS
,
70 .fn_u
= { .ecb
= cast6_ecb_enc_8way
}
73 .fn_u
= { .ecb
= __cast6_encrypt
}
77 static const struct common_glue_ctx cast6_ctr
= {
79 .fpu_blocks_limit
= CAST6_PARALLEL_BLOCKS
,
82 .num_blocks
= CAST6_PARALLEL_BLOCKS
,
83 .fn_u
= { .ctr
= cast6_ctr_8way
}
86 .fn_u
= { .ctr
= cast6_crypt_ctr
}
90 static const struct common_glue_ctx cast6_enc_xts
= {
92 .fpu_blocks_limit
= CAST6_PARALLEL_BLOCKS
,
95 .num_blocks
= CAST6_PARALLEL_BLOCKS
,
96 .fn_u
= { .xts
= cast6_xts_enc_8way
}
99 .fn_u
= { .xts
= cast6_xts_enc
}
103 static const struct common_glue_ctx cast6_dec
= {
105 .fpu_blocks_limit
= CAST6_PARALLEL_BLOCKS
,
108 .num_blocks
= CAST6_PARALLEL_BLOCKS
,
109 .fn_u
= { .ecb
= cast6_ecb_dec_8way
}
112 .fn_u
= { .ecb
= __cast6_decrypt
}
116 static const struct common_glue_ctx cast6_dec_cbc
= {
118 .fpu_blocks_limit
= CAST6_PARALLEL_BLOCKS
,
121 .num_blocks
= CAST6_PARALLEL_BLOCKS
,
122 .fn_u
= { .cbc
= cast6_cbc_dec_8way
}
125 .fn_u
= { .cbc
= __cast6_decrypt
}
129 static const struct common_glue_ctx cast6_dec_xts
= {
131 .fpu_blocks_limit
= CAST6_PARALLEL_BLOCKS
,
134 .num_blocks
= CAST6_PARALLEL_BLOCKS
,
135 .fn_u
= { .xts
= cast6_xts_dec_8way
}
138 .fn_u
= { .xts
= cast6_xts_dec
}
142 static int ecb_encrypt(struct skcipher_request
*req
)
144 return glue_ecb_req_128bit(&cast6_enc
, req
);
147 static int ecb_decrypt(struct skcipher_request
*req
)
149 return glue_ecb_req_128bit(&cast6_dec
, req
);
152 static int cbc_encrypt(struct skcipher_request
*req
)
154 return glue_cbc_encrypt_req_128bit(__cast6_encrypt
, req
);
157 static int cbc_decrypt(struct skcipher_request
*req
)
159 return glue_cbc_decrypt_req_128bit(&cast6_dec_cbc
, req
);
162 static int ctr_crypt(struct skcipher_request
*req
)
164 return glue_ctr_req_128bit(&cast6_ctr
, req
);
167 struct cast6_xts_ctx
{
168 struct cast6_ctx tweak_ctx
;
169 struct cast6_ctx crypt_ctx
;
172 static int xts_cast6_setkey(struct crypto_skcipher
*tfm
, const u8
*key
,
175 struct cast6_xts_ctx
*ctx
= crypto_skcipher_ctx(tfm
);
178 err
= xts_verify_key(tfm
, key
, keylen
);
182 /* first half of xts-key is for crypt */
183 err
= __cast6_setkey(&ctx
->crypt_ctx
, key
, keylen
/ 2);
187 /* second half of xts-key is for tweak */
188 return __cast6_setkey(&ctx
->tweak_ctx
, key
+ keylen
/ 2, keylen
/ 2);
191 static int xts_encrypt(struct skcipher_request
*req
)
193 struct crypto_skcipher
*tfm
= crypto_skcipher_reqtfm(req
);
194 struct cast6_xts_ctx
*ctx
= crypto_skcipher_ctx(tfm
);
196 return glue_xts_req_128bit(&cast6_enc_xts
, req
, __cast6_encrypt
,
197 &ctx
->tweak_ctx
, &ctx
->crypt_ctx
, false);
200 static int xts_decrypt(struct skcipher_request
*req
)
202 struct crypto_skcipher
*tfm
= crypto_skcipher_reqtfm(req
);
203 struct cast6_xts_ctx
*ctx
= crypto_skcipher_ctx(tfm
);
205 return glue_xts_req_128bit(&cast6_dec_xts
, req
, __cast6_encrypt
,
206 &ctx
->tweak_ctx
, &ctx
->crypt_ctx
, true);
209 static struct skcipher_alg cast6_algs
[] = {
211 .base
.cra_name
= "__ecb(cast6)",
212 .base
.cra_driver_name
= "__ecb-cast6-avx",
213 .base
.cra_priority
= 200,
214 .base
.cra_flags
= CRYPTO_ALG_INTERNAL
,
215 .base
.cra_blocksize
= CAST6_BLOCK_SIZE
,
216 .base
.cra_ctxsize
= sizeof(struct cast6_ctx
),
217 .base
.cra_module
= THIS_MODULE
,
218 .min_keysize
= CAST6_MIN_KEY_SIZE
,
219 .max_keysize
= CAST6_MAX_KEY_SIZE
,
220 .setkey
= cast6_setkey_skcipher
,
221 .encrypt
= ecb_encrypt
,
222 .decrypt
= ecb_decrypt
,
224 .base
.cra_name
= "__cbc(cast6)",
225 .base
.cra_driver_name
= "__cbc-cast6-avx",
226 .base
.cra_priority
= 200,
227 .base
.cra_flags
= CRYPTO_ALG_INTERNAL
,
228 .base
.cra_blocksize
= CAST6_BLOCK_SIZE
,
229 .base
.cra_ctxsize
= sizeof(struct cast6_ctx
),
230 .base
.cra_module
= THIS_MODULE
,
231 .min_keysize
= CAST6_MIN_KEY_SIZE
,
232 .max_keysize
= CAST6_MAX_KEY_SIZE
,
233 .ivsize
= CAST6_BLOCK_SIZE
,
234 .setkey
= cast6_setkey_skcipher
,
235 .encrypt
= cbc_encrypt
,
236 .decrypt
= cbc_decrypt
,
238 .base
.cra_name
= "__ctr(cast6)",
239 .base
.cra_driver_name
= "__ctr-cast6-avx",
240 .base
.cra_priority
= 200,
241 .base
.cra_flags
= CRYPTO_ALG_INTERNAL
,
242 .base
.cra_blocksize
= 1,
243 .base
.cra_ctxsize
= sizeof(struct cast6_ctx
),
244 .base
.cra_module
= THIS_MODULE
,
245 .min_keysize
= CAST6_MIN_KEY_SIZE
,
246 .max_keysize
= CAST6_MAX_KEY_SIZE
,
247 .ivsize
= CAST6_BLOCK_SIZE
,
248 .chunksize
= CAST6_BLOCK_SIZE
,
249 .setkey
= cast6_setkey_skcipher
,
250 .encrypt
= ctr_crypt
,
251 .decrypt
= ctr_crypt
,
253 .base
.cra_name
= "__xts(cast6)",
254 .base
.cra_driver_name
= "__xts-cast6-avx",
255 .base
.cra_priority
= 200,
256 .base
.cra_flags
= CRYPTO_ALG_INTERNAL
,
257 .base
.cra_blocksize
= CAST6_BLOCK_SIZE
,
258 .base
.cra_ctxsize
= sizeof(struct cast6_xts_ctx
),
259 .base
.cra_module
= THIS_MODULE
,
260 .min_keysize
= 2 * CAST6_MIN_KEY_SIZE
,
261 .max_keysize
= 2 * CAST6_MAX_KEY_SIZE
,
262 .ivsize
= CAST6_BLOCK_SIZE
,
263 .setkey
= xts_cast6_setkey
,
264 .encrypt
= xts_encrypt
,
265 .decrypt
= xts_decrypt
,
269 static struct simd_skcipher_alg
*cast6_simd_algs
[ARRAY_SIZE(cast6_algs
)];
271 static int __init
cast6_init(void)
273 const char *feature_name
;
275 if (!cpu_has_xfeatures(XFEATURE_MASK_SSE
| XFEATURE_MASK_YMM
,
277 pr_info("CPU feature '%s' is not supported.\n", feature_name
);
281 return simd_register_skciphers_compat(cast6_algs
,
282 ARRAY_SIZE(cast6_algs
),
286 static void __exit
cast6_exit(void)
288 simd_unregister_skciphers(cast6_algs
, ARRAY_SIZE(cast6_algs
),
292 module_init(cast6_init
);
293 module_exit(cast6_exit
);
295 MODULE_DESCRIPTION("Cast6 Cipher Algorithm, AVX optimized");
296 MODULE_LICENSE("GPL");
297 MODULE_ALIAS_CRYPTO("cast6");