2 * Glue Code for 3-way parallel assembler optimized version of Twofish
4 * Copyright (c) 2011 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
23 #include <asm/processor.h>
24 #include <linux/crypto.h>
25 #include <linux/init.h>
26 #include <linux/module.h>
27 #include <linux/types.h>
28 #include <crypto/algapi.h>
29 #include <crypto/twofish.h>
30 #include <crypto/b128ops.h>
31 #include <asm/crypto/twofish.h>
32 #include <asm/crypto/glue_helper.h>
33 #include <crypto/lrw.h>
34 #include <crypto/xts.h>
36 EXPORT_SYMBOL_GPL(__twofish_enc_blk_3way
);
37 EXPORT_SYMBOL_GPL(twofish_dec_blk_3way
);
39 static inline void twofish_enc_blk_3way(struct twofish_ctx
*ctx
, u8
*dst
,
42 __twofish_enc_blk_3way(ctx
, dst
, src
, false);
45 static inline void twofish_enc_blk_xor_3way(struct twofish_ctx
*ctx
, u8
*dst
,
48 __twofish_enc_blk_3way(ctx
, dst
, src
, true);
51 void twofish_dec_blk_cbc_3way(void *ctx
, u128
*dst
, const u128
*src
)
58 twofish_dec_blk_3way(ctx
, (u8
*)dst
, (u8
*)src
);
60 u128_xor(&dst
[1], &dst
[1], &ivs
[0]);
61 u128_xor(&dst
[2], &dst
[2], &ivs
[1]);
63 EXPORT_SYMBOL_GPL(twofish_dec_blk_cbc_3way
);
65 void twofish_enc_blk_ctr(void *ctx
, u128
*dst
, const u128
*src
, le128
*iv
)
72 le128_to_be128(&ctrblk
, iv
);
75 twofish_enc_blk(ctx
, (u8
*)&ctrblk
, (u8
*)&ctrblk
);
76 u128_xor(dst
, dst
, (u128
*)&ctrblk
);
78 EXPORT_SYMBOL_GPL(twofish_enc_blk_ctr
);
80 void twofish_enc_blk_ctr_3way(void *ctx
, u128
*dst
, const u128
*src
,
91 le128_to_be128(&ctrblks
[0], iv
);
93 le128_to_be128(&ctrblks
[1], iv
);
95 le128_to_be128(&ctrblks
[2], iv
);
98 twofish_enc_blk_xor_3way(ctx
, (u8
*)dst
, (u8
*)ctrblks
);
100 EXPORT_SYMBOL_GPL(twofish_enc_blk_ctr_3way
);
102 static const struct common_glue_ctx twofish_enc
= {
104 .fpu_blocks_limit
= -1,
108 .fn_u
= { .ecb
= GLUE_FUNC_CAST(twofish_enc_blk_3way
) }
111 .fn_u
= { .ecb
= GLUE_FUNC_CAST(twofish_enc_blk
) }
115 static const struct common_glue_ctx twofish_ctr
= {
117 .fpu_blocks_limit
= -1,
121 .fn_u
= { .ecb
= GLUE_FUNC_CAST(twofish_enc_blk_ctr_3way
) }
124 .fn_u
= { .ecb
= GLUE_FUNC_CAST(twofish_enc_blk_ctr
) }
128 static const struct common_glue_ctx twofish_dec
= {
130 .fpu_blocks_limit
= -1,
134 .fn_u
= { .ecb
= GLUE_FUNC_CAST(twofish_dec_blk_3way
) }
137 .fn_u
= { .ecb
= GLUE_FUNC_CAST(twofish_dec_blk
) }
141 static const struct common_glue_ctx twofish_dec_cbc
= {
143 .fpu_blocks_limit
= -1,
147 .fn_u
= { .cbc
= GLUE_CBC_FUNC_CAST(twofish_dec_blk_cbc_3way
) }
150 .fn_u
= { .cbc
= GLUE_CBC_FUNC_CAST(twofish_dec_blk
) }
154 static int ecb_encrypt(struct blkcipher_desc
*desc
, struct scatterlist
*dst
,
155 struct scatterlist
*src
, unsigned int nbytes
)
157 return glue_ecb_crypt_128bit(&twofish_enc
, desc
, dst
, src
, nbytes
);
160 static int ecb_decrypt(struct blkcipher_desc
*desc
, struct scatterlist
*dst
,
161 struct scatterlist
*src
, unsigned int nbytes
)
163 return glue_ecb_crypt_128bit(&twofish_dec
, desc
, dst
, src
, nbytes
);
166 static int cbc_encrypt(struct blkcipher_desc
*desc
, struct scatterlist
*dst
,
167 struct scatterlist
*src
, unsigned int nbytes
)
169 return glue_cbc_encrypt_128bit(GLUE_FUNC_CAST(twofish_enc_blk
), desc
,
173 static int cbc_decrypt(struct blkcipher_desc
*desc
, struct scatterlist
*dst
,
174 struct scatterlist
*src
, unsigned int nbytes
)
176 return glue_cbc_decrypt_128bit(&twofish_dec_cbc
, desc
, dst
, src
,
180 static int ctr_crypt(struct blkcipher_desc
*desc
, struct scatterlist
*dst
,
181 struct scatterlist
*src
, unsigned int nbytes
)
183 return glue_ctr_crypt_128bit(&twofish_ctr
, desc
, dst
, src
, nbytes
);
186 static void encrypt_callback(void *priv
, u8
*srcdst
, unsigned int nbytes
)
188 const unsigned int bsize
= TF_BLOCK_SIZE
;
189 struct twofish_ctx
*ctx
= priv
;
192 if (nbytes
== 3 * bsize
) {
193 twofish_enc_blk_3way(ctx
, srcdst
, srcdst
);
197 for (i
= 0; i
< nbytes
/ bsize
; i
++, srcdst
+= bsize
)
198 twofish_enc_blk(ctx
, srcdst
, srcdst
);
201 static void decrypt_callback(void *priv
, u8
*srcdst
, unsigned int nbytes
)
203 const unsigned int bsize
= TF_BLOCK_SIZE
;
204 struct twofish_ctx
*ctx
= priv
;
207 if (nbytes
== 3 * bsize
) {
208 twofish_dec_blk_3way(ctx
, srcdst
, srcdst
);
212 for (i
= 0; i
< nbytes
/ bsize
; i
++, srcdst
+= bsize
)
213 twofish_dec_blk(ctx
, srcdst
, srcdst
);
216 int lrw_twofish_setkey(struct crypto_tfm
*tfm
, const u8
*key
,
219 struct twofish_lrw_ctx
*ctx
= crypto_tfm_ctx(tfm
);
222 err
= __twofish_setkey(&ctx
->twofish_ctx
, key
, keylen
- TF_BLOCK_SIZE
,
227 return lrw_init_table(&ctx
->lrw_table
, key
+ keylen
- TF_BLOCK_SIZE
);
229 EXPORT_SYMBOL_GPL(lrw_twofish_setkey
);
231 static int lrw_encrypt(struct blkcipher_desc
*desc
, struct scatterlist
*dst
,
232 struct scatterlist
*src
, unsigned int nbytes
)
234 struct twofish_lrw_ctx
*ctx
= crypto_blkcipher_ctx(desc
->tfm
);
236 struct lrw_crypt_req req
= {
238 .tbuflen
= sizeof(buf
),
240 .table_ctx
= &ctx
->lrw_table
,
241 .crypt_ctx
= &ctx
->twofish_ctx
,
242 .crypt_fn
= encrypt_callback
,
245 return lrw_crypt(desc
, dst
, src
, nbytes
, &req
);
248 static int lrw_decrypt(struct blkcipher_desc
*desc
, struct scatterlist
*dst
,
249 struct scatterlist
*src
, unsigned int nbytes
)
251 struct twofish_lrw_ctx
*ctx
= crypto_blkcipher_ctx(desc
->tfm
);
253 struct lrw_crypt_req req
= {
255 .tbuflen
= sizeof(buf
),
257 .table_ctx
= &ctx
->lrw_table
,
258 .crypt_ctx
= &ctx
->twofish_ctx
,
259 .crypt_fn
= decrypt_callback
,
262 return lrw_crypt(desc
, dst
, src
, nbytes
, &req
);
265 void lrw_twofish_exit_tfm(struct crypto_tfm
*tfm
)
267 struct twofish_lrw_ctx
*ctx
= crypto_tfm_ctx(tfm
);
269 lrw_free_table(&ctx
->lrw_table
);
271 EXPORT_SYMBOL_GPL(lrw_twofish_exit_tfm
);
273 int xts_twofish_setkey(struct crypto_tfm
*tfm
, const u8
*key
,
276 struct twofish_xts_ctx
*ctx
= crypto_tfm_ctx(tfm
);
277 u32
*flags
= &tfm
->crt_flags
;
280 err
= xts_check_key(tfm
, key
, keylen
);
284 /* first half of xts-key is for crypt */
285 err
= __twofish_setkey(&ctx
->crypt_ctx
, key
, keylen
/ 2, flags
);
289 /* second half of xts-key is for tweak */
290 return __twofish_setkey(&ctx
->tweak_ctx
, key
+ keylen
/ 2, keylen
/ 2,
293 EXPORT_SYMBOL_GPL(xts_twofish_setkey
);
295 static int xts_encrypt(struct blkcipher_desc
*desc
, struct scatterlist
*dst
,
296 struct scatterlist
*src
, unsigned int nbytes
)
298 struct twofish_xts_ctx
*ctx
= crypto_blkcipher_ctx(desc
->tfm
);
300 struct xts_crypt_req req
= {
302 .tbuflen
= sizeof(buf
),
304 .tweak_ctx
= &ctx
->tweak_ctx
,
305 .tweak_fn
= XTS_TWEAK_CAST(twofish_enc_blk
),
306 .crypt_ctx
= &ctx
->crypt_ctx
,
307 .crypt_fn
= encrypt_callback
,
310 return xts_crypt(desc
, dst
, src
, nbytes
, &req
);
313 static int xts_decrypt(struct blkcipher_desc
*desc
, struct scatterlist
*dst
,
314 struct scatterlist
*src
, unsigned int nbytes
)
316 struct twofish_xts_ctx
*ctx
= crypto_blkcipher_ctx(desc
->tfm
);
318 struct xts_crypt_req req
= {
320 .tbuflen
= sizeof(buf
),
322 .tweak_ctx
= &ctx
->tweak_ctx
,
323 .tweak_fn
= XTS_TWEAK_CAST(twofish_enc_blk
),
324 .crypt_ctx
= &ctx
->crypt_ctx
,
325 .crypt_fn
= decrypt_callback
,
328 return xts_crypt(desc
, dst
, src
, nbytes
, &req
);
331 static struct crypto_alg tf_algs
[5] = { {
332 .cra_name
= "ecb(twofish)",
333 .cra_driver_name
= "ecb-twofish-3way",
335 .cra_flags
= CRYPTO_ALG_TYPE_BLKCIPHER
,
336 .cra_blocksize
= TF_BLOCK_SIZE
,
337 .cra_ctxsize
= sizeof(struct twofish_ctx
),
339 .cra_type
= &crypto_blkcipher_type
,
340 .cra_module
= THIS_MODULE
,
343 .min_keysize
= TF_MIN_KEY_SIZE
,
344 .max_keysize
= TF_MAX_KEY_SIZE
,
345 .setkey
= twofish_setkey
,
346 .encrypt
= ecb_encrypt
,
347 .decrypt
= ecb_decrypt
,
351 .cra_name
= "cbc(twofish)",
352 .cra_driver_name
= "cbc-twofish-3way",
354 .cra_flags
= CRYPTO_ALG_TYPE_BLKCIPHER
,
355 .cra_blocksize
= TF_BLOCK_SIZE
,
356 .cra_ctxsize
= sizeof(struct twofish_ctx
),
358 .cra_type
= &crypto_blkcipher_type
,
359 .cra_module
= THIS_MODULE
,
362 .min_keysize
= TF_MIN_KEY_SIZE
,
363 .max_keysize
= TF_MAX_KEY_SIZE
,
364 .ivsize
= TF_BLOCK_SIZE
,
365 .setkey
= twofish_setkey
,
366 .encrypt
= cbc_encrypt
,
367 .decrypt
= cbc_decrypt
,
371 .cra_name
= "ctr(twofish)",
372 .cra_driver_name
= "ctr-twofish-3way",
374 .cra_flags
= CRYPTO_ALG_TYPE_BLKCIPHER
,
376 .cra_ctxsize
= sizeof(struct twofish_ctx
),
378 .cra_type
= &crypto_blkcipher_type
,
379 .cra_module
= THIS_MODULE
,
382 .min_keysize
= TF_MIN_KEY_SIZE
,
383 .max_keysize
= TF_MAX_KEY_SIZE
,
384 .ivsize
= TF_BLOCK_SIZE
,
385 .setkey
= twofish_setkey
,
386 .encrypt
= ctr_crypt
,
387 .decrypt
= ctr_crypt
,
391 .cra_name
= "lrw(twofish)",
392 .cra_driver_name
= "lrw-twofish-3way",
394 .cra_flags
= CRYPTO_ALG_TYPE_BLKCIPHER
,
395 .cra_blocksize
= TF_BLOCK_SIZE
,
396 .cra_ctxsize
= sizeof(struct twofish_lrw_ctx
),
398 .cra_type
= &crypto_blkcipher_type
,
399 .cra_module
= THIS_MODULE
,
400 .cra_exit
= lrw_twofish_exit_tfm
,
403 .min_keysize
= TF_MIN_KEY_SIZE
+ TF_BLOCK_SIZE
,
404 .max_keysize
= TF_MAX_KEY_SIZE
+ TF_BLOCK_SIZE
,
405 .ivsize
= TF_BLOCK_SIZE
,
406 .setkey
= lrw_twofish_setkey
,
407 .encrypt
= lrw_encrypt
,
408 .decrypt
= lrw_decrypt
,
412 .cra_name
= "xts(twofish)",
413 .cra_driver_name
= "xts-twofish-3way",
415 .cra_flags
= CRYPTO_ALG_TYPE_BLKCIPHER
,
416 .cra_blocksize
= TF_BLOCK_SIZE
,
417 .cra_ctxsize
= sizeof(struct twofish_xts_ctx
),
419 .cra_type
= &crypto_blkcipher_type
,
420 .cra_module
= THIS_MODULE
,
423 .min_keysize
= TF_MIN_KEY_SIZE
* 2,
424 .max_keysize
= TF_MAX_KEY_SIZE
* 2,
425 .ivsize
= TF_BLOCK_SIZE
,
426 .setkey
= xts_twofish_setkey
,
427 .encrypt
= xts_encrypt
,
428 .decrypt
= xts_decrypt
,
433 static bool is_blacklisted_cpu(void)
435 if (boot_cpu_data
.x86_vendor
!= X86_VENDOR_INTEL
)
438 if (boot_cpu_data
.x86
== 0x06 &&
439 (boot_cpu_data
.x86_model
== 0x1c ||
440 boot_cpu_data
.x86_model
== 0x26 ||
441 boot_cpu_data
.x86_model
== 0x36)) {
443 * On Atom, twofish-3way is slower than original assembler
444 * implementation. Twofish-3way trades off some performance in
445 * storing blocks in 64bit registers to allow three blocks to
446 * be processed parallel. Parallel operation then allows gaining
447 * more performance than was trade off, on out-of-order CPUs.
448 * However Atom does not benefit from this parallellism and
449 * should be blacklisted.
454 if (boot_cpu_data
.x86
== 0x0f) {
456 * On Pentium 4, twofish-3way is slower than original assembler
457 * implementation because excessive uses of 64bit rotate and
458 * left-shifts (which are really slow on P4) needed to store and
459 * handle 128bit block in two 64bit registers.
468 module_param(force
, int, 0);
469 MODULE_PARM_DESC(force
, "Force module load, ignore CPU blacklist");
471 static int __init
init(void)
473 if (!force
&& is_blacklisted_cpu()) {
475 "twofish-x86_64-3way: performance on this CPU "
476 "would be suboptimal: disabling "
477 "twofish-x86_64-3way.\n");
481 return crypto_register_algs(tf_algs
, ARRAY_SIZE(tf_algs
));
484 static void __exit
fini(void)
486 crypto_unregister_algs(tf_algs
, ARRAY_SIZE(tf_algs
));
492 MODULE_LICENSE("GPL");
493 MODULE_DESCRIPTION("Twofish Cipher Algorithm, 3-way parallel asm optimized");
494 MODULE_ALIAS_CRYPTO("twofish");
495 MODULE_ALIAS_CRYPTO("twofish-asm");