Linux Audio

Check our new training course

Loading...
v6.13.7
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * Glue Code for AVX assembler version of Twofish 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/internal/simd.h>
 17#include <crypto/twofish.h>
 18
 19#include "twofish.h"
 20#include "ecb_cbc_helpers.h"
 21
 22#define TWOFISH_PARALLEL_BLOCKS 8
 23
 24/* 8-way parallel cipher functions */
 25asmlinkage void twofish_ecb_enc_8way(const void *ctx, u8 *dst, const u8 *src);
 26asmlinkage void twofish_ecb_dec_8way(const void *ctx, u8 *dst, const u8 *src);
 27
 28asmlinkage void twofish_cbc_dec_8way(const void *ctx, u8 *dst, const u8 *src);
 
 
 
 
 
 
 
 29
 30static int twofish_setkey_skcipher(struct crypto_skcipher *tfm,
 31				   const u8 *key, unsigned int keylen)
 32{
 33	return twofish_setkey(&tfm->base, key, keylen);
 34}
 35
 36static inline void twofish_enc_blk_3way(const void *ctx, u8 *dst, const u8 *src)
 37{
 38	__twofish_enc_blk_3way(ctx, dst, src, false);
 39}
 40
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 41static int ecb_encrypt(struct skcipher_request *req)
 42{
 43	ECB_WALK_START(req, TF_BLOCK_SIZE, TWOFISH_PARALLEL_BLOCKS);
 44	ECB_BLOCK(TWOFISH_PARALLEL_BLOCKS, twofish_ecb_enc_8way);
 45	ECB_BLOCK(3, twofish_enc_blk_3way);
 46	ECB_BLOCK(1, twofish_enc_blk);
 47	ECB_WALK_END();
 48}
 49
 50static int ecb_decrypt(struct skcipher_request *req)
 51{
 52	ECB_WALK_START(req, TF_BLOCK_SIZE, TWOFISH_PARALLEL_BLOCKS);
 53	ECB_BLOCK(TWOFISH_PARALLEL_BLOCKS, twofish_ecb_dec_8way);
 54	ECB_BLOCK(3, twofish_dec_blk_3way);
 55	ECB_BLOCK(1, twofish_dec_blk);
 56	ECB_WALK_END();
 57}
 58
 59static int cbc_encrypt(struct skcipher_request *req)
 60{
 61	CBC_WALK_START(req, TF_BLOCK_SIZE, -1);
 62	CBC_ENC_BLOCK(twofish_enc_blk);
 63	CBC_WALK_END();
 64}
 65
 66static int cbc_decrypt(struct skcipher_request *req)
 67{
 68	CBC_WALK_START(req, TF_BLOCK_SIZE, TWOFISH_PARALLEL_BLOCKS);
 69	CBC_DEC_BLOCK(TWOFISH_PARALLEL_BLOCKS, twofish_cbc_dec_8way);
 70	CBC_DEC_BLOCK(3, twofish_dec_blk_cbc_3way);
 71	CBC_DEC_BLOCK(1, twofish_dec_blk);
 72	CBC_WALK_END();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 73}
 74
 75static struct skcipher_alg twofish_algs[] = {
 76	{
 77		.base.cra_name		= "__ecb(twofish)",
 78		.base.cra_driver_name	= "__ecb-twofish-avx",
 79		.base.cra_priority	= 400,
 80		.base.cra_flags		= CRYPTO_ALG_INTERNAL,
 81		.base.cra_blocksize	= TF_BLOCK_SIZE,
 82		.base.cra_ctxsize	= sizeof(struct twofish_ctx),
 83		.base.cra_module	= THIS_MODULE,
 84		.min_keysize		= TF_MIN_KEY_SIZE,
 85		.max_keysize		= TF_MAX_KEY_SIZE,
 86		.setkey			= twofish_setkey_skcipher,
 87		.encrypt		= ecb_encrypt,
 88		.decrypt		= ecb_decrypt,
 89	}, {
 90		.base.cra_name		= "__cbc(twofish)",
 91		.base.cra_driver_name	= "__cbc-twofish-avx",
 92		.base.cra_priority	= 400,
 93		.base.cra_flags		= CRYPTO_ALG_INTERNAL,
 94		.base.cra_blocksize	= TF_BLOCK_SIZE,
 95		.base.cra_ctxsize	= sizeof(struct twofish_ctx),
 96		.base.cra_module	= THIS_MODULE,
 97		.min_keysize		= TF_MIN_KEY_SIZE,
 98		.max_keysize		= TF_MAX_KEY_SIZE,
 99		.ivsize			= TF_BLOCK_SIZE,
100		.setkey			= twofish_setkey_skcipher,
101		.encrypt		= cbc_encrypt,
102		.decrypt		= cbc_decrypt,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103	},
104};
105
106static struct simd_skcipher_alg *twofish_simd_algs[ARRAY_SIZE(twofish_algs)];
107
108static int __init twofish_init(void)
109{
110	const char *feature_name;
111
112	if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, &feature_name)) {
113		pr_info("CPU feature '%s' is not supported.\n", feature_name);
114		return -ENODEV;
115	}
116
117	return simd_register_skciphers_compat(twofish_algs,
118					      ARRAY_SIZE(twofish_algs),
119					      twofish_simd_algs);
120}
121
122static void __exit twofish_exit(void)
123{
124	simd_unregister_skciphers(twofish_algs, ARRAY_SIZE(twofish_algs),
125				  twofish_simd_algs);
126}
127
128module_init(twofish_init);
129module_exit(twofish_exit);
130
131MODULE_DESCRIPTION("Twofish Cipher Algorithm, AVX optimized");
132MODULE_LICENSE("GPL");
133MODULE_ALIAS_CRYPTO("twofish");
v5.9
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * Glue Code for AVX assembler version of Twofish 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/internal/simd.h>
 17#include <crypto/twofish.h>
 18#include <crypto/xts.h>
 19#include <asm/crypto/glue_helper.h>
 20#include <asm/crypto/twofish.h>
 21
 22#define TWOFISH_PARALLEL_BLOCKS 8
 23
 24/* 8-way parallel cipher functions */
 25asmlinkage void twofish_ecb_enc_8way(const void *ctx, u8 *dst, const u8 *src);
 26asmlinkage void twofish_ecb_dec_8way(const void *ctx, u8 *dst, const u8 *src);
 27
 28asmlinkage void twofish_cbc_dec_8way(const void *ctx, u8 *dst, const u8 *src);
 29asmlinkage void twofish_ctr_8way(const void *ctx, u8 *dst, const u8 *src,
 30				 le128 *iv);
 31
 32asmlinkage void twofish_xts_enc_8way(const void *ctx, u8 *dst, const u8 *src,
 33				     le128 *iv);
 34asmlinkage void twofish_xts_dec_8way(const void *ctx, u8 *dst, const u8 *src,
 35				     le128 *iv);
 36
 37static int twofish_setkey_skcipher(struct crypto_skcipher *tfm,
 38				   const u8 *key, unsigned int keylen)
 39{
 40	return twofish_setkey(&tfm->base, key, keylen);
 41}
 42
 43static inline void twofish_enc_blk_3way(const void *ctx, u8 *dst, const u8 *src)
 44{
 45	__twofish_enc_blk_3way(ctx, dst, src, false);
 46}
 47
 48static void twofish_xts_enc(const void *ctx, u8 *dst, const u8 *src, le128 *iv)
 49{
 50	glue_xts_crypt_128bit_one(ctx, dst, src, iv, twofish_enc_blk);
 51}
 52
 53static void twofish_xts_dec(const void *ctx, u8 *dst, const u8 *src, le128 *iv)
 54{
 55	glue_xts_crypt_128bit_one(ctx, dst, src, iv, twofish_dec_blk);
 56}
 57
 58struct twofish_xts_ctx {
 59	struct twofish_ctx tweak_ctx;
 60	struct twofish_ctx crypt_ctx;
 61};
 62
 63static int xts_twofish_setkey(struct crypto_skcipher *tfm, const u8 *key,
 64			      unsigned int keylen)
 65{
 66	struct twofish_xts_ctx *ctx = crypto_skcipher_ctx(tfm);
 67	int err;
 68
 69	err = xts_verify_key(tfm, key, keylen);
 70	if (err)
 71		return err;
 72
 73	/* first half of xts-key is for crypt */
 74	err = __twofish_setkey(&ctx->crypt_ctx, key, keylen / 2);
 75	if (err)
 76		return err;
 77
 78	/* second half of xts-key is for tweak */
 79	return __twofish_setkey(&ctx->tweak_ctx, key + keylen / 2, keylen / 2);
 80}
 81
 82static const struct common_glue_ctx twofish_enc = {
 83	.num_funcs = 3,
 84	.fpu_blocks_limit = TWOFISH_PARALLEL_BLOCKS,
 85
 86	.funcs = { {
 87		.num_blocks = TWOFISH_PARALLEL_BLOCKS,
 88		.fn_u = { .ecb = twofish_ecb_enc_8way }
 89	}, {
 90		.num_blocks = 3,
 91		.fn_u = { .ecb = twofish_enc_blk_3way }
 92	}, {
 93		.num_blocks = 1,
 94		.fn_u = { .ecb = twofish_enc_blk }
 95	} }
 96};
 97
 98static const struct common_glue_ctx twofish_ctr = {
 99	.num_funcs = 3,
100	.fpu_blocks_limit = TWOFISH_PARALLEL_BLOCKS,
101
102	.funcs = { {
103		.num_blocks = TWOFISH_PARALLEL_BLOCKS,
104		.fn_u = { .ctr = twofish_ctr_8way }
105	}, {
106		.num_blocks = 3,
107		.fn_u = { .ctr = twofish_enc_blk_ctr_3way }
108	}, {
109		.num_blocks = 1,
110		.fn_u = { .ctr = twofish_enc_blk_ctr }
111	} }
112};
113
114static const struct common_glue_ctx twofish_enc_xts = {
115	.num_funcs = 2,
116	.fpu_blocks_limit = TWOFISH_PARALLEL_BLOCKS,
117
118	.funcs = { {
119		.num_blocks = TWOFISH_PARALLEL_BLOCKS,
120		.fn_u = { .xts = twofish_xts_enc_8way }
121	}, {
122		.num_blocks = 1,
123		.fn_u = { .xts = twofish_xts_enc }
124	} }
125};
126
127static const struct common_glue_ctx twofish_dec = {
128	.num_funcs = 3,
129	.fpu_blocks_limit = TWOFISH_PARALLEL_BLOCKS,
130
131	.funcs = { {
132		.num_blocks = TWOFISH_PARALLEL_BLOCKS,
133		.fn_u = { .ecb = twofish_ecb_dec_8way }
134	}, {
135		.num_blocks = 3,
136		.fn_u = { .ecb = twofish_dec_blk_3way }
137	}, {
138		.num_blocks = 1,
139		.fn_u = { .ecb = twofish_dec_blk }
140	} }
141};
142
143static const struct common_glue_ctx twofish_dec_cbc = {
144	.num_funcs = 3,
145	.fpu_blocks_limit = TWOFISH_PARALLEL_BLOCKS,
146
147	.funcs = { {
148		.num_blocks = TWOFISH_PARALLEL_BLOCKS,
149		.fn_u = { .cbc = twofish_cbc_dec_8way }
150	}, {
151		.num_blocks = 3,
152		.fn_u = { .cbc = twofish_dec_blk_cbc_3way }
153	}, {
154		.num_blocks = 1,
155		.fn_u = { .cbc = twofish_dec_blk }
156	} }
157};
158
159static const struct common_glue_ctx twofish_dec_xts = {
160	.num_funcs = 2,
161	.fpu_blocks_limit = TWOFISH_PARALLEL_BLOCKS,
162
163	.funcs = { {
164		.num_blocks = TWOFISH_PARALLEL_BLOCKS,
165		.fn_u = { .xts = twofish_xts_dec_8way }
166	}, {
167		.num_blocks = 1,
168		.fn_u = { .xts = twofish_xts_dec }
169	} }
170};
171
172static int ecb_encrypt(struct skcipher_request *req)
173{
174	return glue_ecb_req_128bit(&twofish_enc, req);
 
 
 
 
175}
176
177static int ecb_decrypt(struct skcipher_request *req)
178{
179	return glue_ecb_req_128bit(&twofish_dec, req);
 
 
 
 
180}
181
182static int cbc_encrypt(struct skcipher_request *req)
183{
184	return glue_cbc_encrypt_req_128bit(twofish_enc_blk, req);
 
 
185}
186
187static int cbc_decrypt(struct skcipher_request *req)
188{
189	return glue_cbc_decrypt_req_128bit(&twofish_dec_cbc, req);
190}
191
192static int ctr_crypt(struct skcipher_request *req)
193{
194	return glue_ctr_req_128bit(&twofish_ctr, req);
195}
196
197static int xts_encrypt(struct skcipher_request *req)
198{
199	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
200	struct twofish_xts_ctx *ctx = crypto_skcipher_ctx(tfm);
201
202	return glue_xts_req_128bit(&twofish_enc_xts, req, twofish_enc_blk,
203				   &ctx->tweak_ctx, &ctx->crypt_ctx, false);
204}
205
206static int xts_decrypt(struct skcipher_request *req)
207{
208	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
209	struct twofish_xts_ctx *ctx = crypto_skcipher_ctx(tfm);
210
211	return glue_xts_req_128bit(&twofish_dec_xts, req, twofish_enc_blk,
212				   &ctx->tweak_ctx, &ctx->crypt_ctx, true);
213}
214
215static struct skcipher_alg twofish_algs[] = {
216	{
217		.base.cra_name		= "__ecb(twofish)",
218		.base.cra_driver_name	= "__ecb-twofish-avx",
219		.base.cra_priority	= 400,
220		.base.cra_flags		= CRYPTO_ALG_INTERNAL,
221		.base.cra_blocksize	= TF_BLOCK_SIZE,
222		.base.cra_ctxsize	= sizeof(struct twofish_ctx),
223		.base.cra_module	= THIS_MODULE,
224		.min_keysize		= TF_MIN_KEY_SIZE,
225		.max_keysize		= TF_MAX_KEY_SIZE,
226		.setkey			= twofish_setkey_skcipher,
227		.encrypt		= ecb_encrypt,
228		.decrypt		= ecb_decrypt,
229	}, {
230		.base.cra_name		= "__cbc(twofish)",
231		.base.cra_driver_name	= "__cbc-twofish-avx",
232		.base.cra_priority	= 400,
233		.base.cra_flags		= CRYPTO_ALG_INTERNAL,
234		.base.cra_blocksize	= TF_BLOCK_SIZE,
235		.base.cra_ctxsize	= sizeof(struct twofish_ctx),
236		.base.cra_module	= THIS_MODULE,
237		.min_keysize		= TF_MIN_KEY_SIZE,
238		.max_keysize		= TF_MAX_KEY_SIZE,
239		.ivsize			= TF_BLOCK_SIZE,
240		.setkey			= twofish_setkey_skcipher,
241		.encrypt		= cbc_encrypt,
242		.decrypt		= cbc_decrypt,
243	}, {
244		.base.cra_name		= "__ctr(twofish)",
245		.base.cra_driver_name	= "__ctr-twofish-avx",
246		.base.cra_priority	= 400,
247		.base.cra_flags		= CRYPTO_ALG_INTERNAL,
248		.base.cra_blocksize	= 1,
249		.base.cra_ctxsize	= sizeof(struct twofish_ctx),
250		.base.cra_module	= THIS_MODULE,
251		.min_keysize		= TF_MIN_KEY_SIZE,
252		.max_keysize		= TF_MAX_KEY_SIZE,
253		.ivsize			= TF_BLOCK_SIZE,
254		.chunksize		= TF_BLOCK_SIZE,
255		.setkey			= twofish_setkey_skcipher,
256		.encrypt		= ctr_crypt,
257		.decrypt		= ctr_crypt,
258	}, {
259		.base.cra_name		= "__xts(twofish)",
260		.base.cra_driver_name	= "__xts-twofish-avx",
261		.base.cra_priority	= 400,
262		.base.cra_flags		= CRYPTO_ALG_INTERNAL,
263		.base.cra_blocksize	= TF_BLOCK_SIZE,
264		.base.cra_ctxsize	= sizeof(struct twofish_xts_ctx),
265		.base.cra_module	= THIS_MODULE,
266		.min_keysize		= 2 * TF_MIN_KEY_SIZE,
267		.max_keysize		= 2 * TF_MAX_KEY_SIZE,
268		.ivsize			= TF_BLOCK_SIZE,
269		.setkey			= xts_twofish_setkey,
270		.encrypt		= xts_encrypt,
271		.decrypt		= xts_decrypt,
272	},
273};
274
275static struct simd_skcipher_alg *twofish_simd_algs[ARRAY_SIZE(twofish_algs)];
276
277static int __init twofish_init(void)
278{
279	const char *feature_name;
280
281	if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, &feature_name)) {
282		pr_info("CPU feature '%s' is not supported.\n", feature_name);
283		return -ENODEV;
284	}
285
286	return simd_register_skciphers_compat(twofish_algs,
287					      ARRAY_SIZE(twofish_algs),
288					      twofish_simd_algs);
289}
290
291static void __exit twofish_exit(void)
292{
293	simd_unregister_skciphers(twofish_algs, ARRAY_SIZE(twofish_algs),
294				  twofish_simd_algs);
295}
296
297module_init(twofish_init);
298module_exit(twofish_exit);
299
300MODULE_DESCRIPTION("Twofish Cipher Algorithm, AVX optimized");
301MODULE_LICENSE("GPL");
302MODULE_ALIAS_CRYPTO("twofish");