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 /* key consists of keys of equal size concatenated, therefore
281 * the length must be even
284 *flags
|= CRYPTO_TFM_RES_BAD_KEY_LEN
;
288 /* first half of xts-key is for crypt */
289 err
= __twofish_setkey(&ctx
->crypt_ctx
, key
, keylen
/ 2, flags
);
293 /* second half of xts-key is for tweak */
294 return __twofish_setkey(&ctx
->tweak_ctx
, key
+ keylen
/ 2, keylen
/ 2,
297 EXPORT_SYMBOL_GPL(xts_twofish_setkey
);
299 static int xts_encrypt(struct blkcipher_desc
*desc
, struct scatterlist
*dst
,
300 struct scatterlist
*src
, unsigned int nbytes
)
302 struct twofish_xts_ctx
*ctx
= crypto_blkcipher_ctx(desc
->tfm
);
304 struct xts_crypt_req req
= {
306 .tbuflen
= sizeof(buf
),
308 .tweak_ctx
= &ctx
->tweak_ctx
,
309 .tweak_fn
= XTS_TWEAK_CAST(twofish_enc_blk
),
310 .crypt_ctx
= &ctx
->crypt_ctx
,
311 .crypt_fn
= encrypt_callback
,
314 return xts_crypt(desc
, dst
, src
, nbytes
, &req
);
317 static int xts_decrypt(struct blkcipher_desc
*desc
, struct scatterlist
*dst
,
318 struct scatterlist
*src
, unsigned int nbytes
)
320 struct twofish_xts_ctx
*ctx
= crypto_blkcipher_ctx(desc
->tfm
);
322 struct xts_crypt_req req
= {
324 .tbuflen
= sizeof(buf
),
326 .tweak_ctx
= &ctx
->tweak_ctx
,
327 .tweak_fn
= XTS_TWEAK_CAST(twofish_enc_blk
),
328 .crypt_ctx
= &ctx
->crypt_ctx
,
329 .crypt_fn
= decrypt_callback
,
332 return xts_crypt(desc
, dst
, src
, nbytes
, &req
);
335 static struct crypto_alg tf_algs
[5] = { {
336 .cra_name
= "ecb(twofish)",
337 .cra_driver_name
= "ecb-twofish-3way",
339 .cra_flags
= CRYPTO_ALG_TYPE_BLKCIPHER
,
340 .cra_blocksize
= TF_BLOCK_SIZE
,
341 .cra_ctxsize
= sizeof(struct twofish_ctx
),
343 .cra_type
= &crypto_blkcipher_type
,
344 .cra_module
= THIS_MODULE
,
347 .min_keysize
= TF_MIN_KEY_SIZE
,
348 .max_keysize
= TF_MAX_KEY_SIZE
,
349 .setkey
= twofish_setkey
,
350 .encrypt
= ecb_encrypt
,
351 .decrypt
= ecb_decrypt
,
355 .cra_name
= "cbc(twofish)",
356 .cra_driver_name
= "cbc-twofish-3way",
358 .cra_flags
= CRYPTO_ALG_TYPE_BLKCIPHER
,
359 .cra_blocksize
= TF_BLOCK_SIZE
,
360 .cra_ctxsize
= sizeof(struct twofish_ctx
),
362 .cra_type
= &crypto_blkcipher_type
,
363 .cra_module
= THIS_MODULE
,
366 .min_keysize
= TF_MIN_KEY_SIZE
,
367 .max_keysize
= TF_MAX_KEY_SIZE
,
368 .ivsize
= TF_BLOCK_SIZE
,
369 .setkey
= twofish_setkey
,
370 .encrypt
= cbc_encrypt
,
371 .decrypt
= cbc_decrypt
,
375 .cra_name
= "ctr(twofish)",
376 .cra_driver_name
= "ctr-twofish-3way",
378 .cra_flags
= CRYPTO_ALG_TYPE_BLKCIPHER
,
380 .cra_ctxsize
= sizeof(struct twofish_ctx
),
382 .cra_type
= &crypto_blkcipher_type
,
383 .cra_module
= THIS_MODULE
,
386 .min_keysize
= TF_MIN_KEY_SIZE
,
387 .max_keysize
= TF_MAX_KEY_SIZE
,
388 .ivsize
= TF_BLOCK_SIZE
,
389 .setkey
= twofish_setkey
,
390 .encrypt
= ctr_crypt
,
391 .decrypt
= ctr_crypt
,
395 .cra_name
= "lrw(twofish)",
396 .cra_driver_name
= "lrw-twofish-3way",
398 .cra_flags
= CRYPTO_ALG_TYPE_BLKCIPHER
,
399 .cra_blocksize
= TF_BLOCK_SIZE
,
400 .cra_ctxsize
= sizeof(struct twofish_lrw_ctx
),
402 .cra_type
= &crypto_blkcipher_type
,
403 .cra_module
= THIS_MODULE
,
404 .cra_exit
= lrw_twofish_exit_tfm
,
407 .min_keysize
= TF_MIN_KEY_SIZE
+ TF_BLOCK_SIZE
,
408 .max_keysize
= TF_MAX_KEY_SIZE
+ TF_BLOCK_SIZE
,
409 .ivsize
= TF_BLOCK_SIZE
,
410 .setkey
= lrw_twofish_setkey
,
411 .encrypt
= lrw_encrypt
,
412 .decrypt
= lrw_decrypt
,
416 .cra_name
= "xts(twofish)",
417 .cra_driver_name
= "xts-twofish-3way",
419 .cra_flags
= CRYPTO_ALG_TYPE_BLKCIPHER
,
420 .cra_blocksize
= TF_BLOCK_SIZE
,
421 .cra_ctxsize
= sizeof(struct twofish_xts_ctx
),
423 .cra_type
= &crypto_blkcipher_type
,
424 .cra_module
= THIS_MODULE
,
427 .min_keysize
= TF_MIN_KEY_SIZE
* 2,
428 .max_keysize
= TF_MAX_KEY_SIZE
* 2,
429 .ivsize
= TF_BLOCK_SIZE
,
430 .setkey
= xts_twofish_setkey
,
431 .encrypt
= xts_encrypt
,
432 .decrypt
= xts_decrypt
,
437 static bool is_blacklisted_cpu(void)
439 if (boot_cpu_data
.x86_vendor
!= X86_VENDOR_INTEL
)
442 if (boot_cpu_data
.x86
== 0x06 &&
443 (boot_cpu_data
.x86_model
== 0x1c ||
444 boot_cpu_data
.x86_model
== 0x26 ||
445 boot_cpu_data
.x86_model
== 0x36)) {
447 * On Atom, twofish-3way is slower than original assembler
448 * implementation. Twofish-3way trades off some performance in
449 * storing blocks in 64bit registers to allow three blocks to
450 * be processed parallel. Parallel operation then allows gaining
451 * more performance than was trade off, on out-of-order CPUs.
452 * However Atom does not benefit from this parallellism and
453 * should be blacklisted.
458 if (boot_cpu_data
.x86
== 0x0f) {
460 * On Pentium 4, twofish-3way is slower than original assembler
461 * implementation because excessive uses of 64bit rotate and
462 * left-shifts (which are really slow on P4) needed to store and
463 * handle 128bit block in two 64bit registers.
472 module_param(force
, int, 0);
473 MODULE_PARM_DESC(force
, "Force module load, ignore CPU blacklist");
475 static int __init
init(void)
477 if (!force
&& is_blacklisted_cpu()) {
479 "twofish-x86_64-3way: performance on this CPU "
480 "would be suboptimal: disabling "
481 "twofish-x86_64-3way.\n");
485 return crypto_register_algs(tf_algs
, ARRAY_SIZE(tf_algs
));
488 static void __exit
fini(void)
490 crypto_unregister_algs(tf_algs
, ARRAY_SIZE(tf_algs
));
496 MODULE_LICENSE("GPL");
497 MODULE_DESCRIPTION("Twofish Cipher Algorithm, 3-way parallel asm optimized");
498 MODULE_ALIAS("twofish");
499 MODULE_ALIAS("twofish-asm");