aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJussi Kivilinna <jussi.kivilinna@mbnet.fi>2012-06-18 07:07:39 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2012-06-27 02:42:02 -0400
commita7378d4e552ac139ae1cbbdfebfeaa9b18c948d0 (patch)
treedc8960d5ce50ac27f05e02151c7744bb313286b4
parent414cb5e7cc6e258fe36e2c3cc3ef1ff2e246c0e3 (diff)
crypto: twofish-avx - remove duplicated glue code and use shared glue code from glue_helper
Now that shared glue code is available, convert twofish-avx to use it. Cc: Johannes Goetzfried <Johannes.Goetzfried@informatik.stud.uni-erlangen.de> Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--arch/x86/crypto/twofish_avx_glue.c556
-rw-r--r--arch/x86/crypto/twofish_glue_3way.c46
-rw-r--r--arch/x86/include/asm/crypto/twofish.h46
-rw-r--r--crypto/Kconfig1
4 files changed, 162 insertions, 487 deletions
diff --git a/arch/x86/crypto/twofish_avx_glue.c b/arch/x86/crypto/twofish_avx_glue.c
index cabe058eba14..782b67ddaf6a 100644
--- a/arch/x86/crypto/twofish_avx_glue.c
+++ b/arch/x86/crypto/twofish_avx_glue.c
@@ -4,9 +4,6 @@
4 * Copyright (C) 2012 Johannes Goetzfried 4 * Copyright (C) 2012 Johannes Goetzfried
5 * <Johannes.Goetzfried@informatik.stud.uni-erlangen.de> 5 * <Johannes.Goetzfried@informatik.stud.uni-erlangen.de>
6 * 6 *
7 * Glue code based on serpent_sse2_glue.c by:
8 * Copyright (C) 2011 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
9 *
10 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or 9 * the Free Software Foundation; either version 2 of the License, or
@@ -39,38 +36,21 @@
39#include <asm/i387.h> 36#include <asm/i387.h>
40#include <asm/xcr.h> 37#include <asm/xcr.h>
41#include <asm/xsave.h> 38#include <asm/xsave.h>
39#include <asm/crypto/twofish.h>
42#include <asm/crypto/ablk_helper.h> 40#include <asm/crypto/ablk_helper.h>
41#include <asm/crypto/glue_helper.h>
43#include <crypto/scatterwalk.h> 42#include <crypto/scatterwalk.h>
44#include <linux/workqueue.h> 43#include <linux/workqueue.h>
45#include <linux/spinlock.h> 44#include <linux/spinlock.h>
46 45
47
48#define TWOFISH_PARALLEL_BLOCKS 8 46#define TWOFISH_PARALLEL_BLOCKS 8
49 47
50/* regular block cipher functions from twofish_x86_64 module */
51asmlinkage void twofish_enc_blk(struct twofish_ctx *ctx, u8 *dst,
52 const u8 *src);
53asmlinkage void twofish_dec_blk(struct twofish_ctx *ctx, u8 *dst,
54 const u8 *src);
55
56/* 3-way parallel cipher functions from twofish_x86_64-3way module */
57asmlinkage void __twofish_enc_blk_3way(struct twofish_ctx *ctx, u8 *dst,
58 const u8 *src, bool xor);
59asmlinkage void twofish_dec_blk_3way(struct twofish_ctx *ctx, u8 *dst,
60 const u8 *src);
61
62static inline void twofish_enc_blk_3way(struct twofish_ctx *ctx, u8 *dst, 48static inline void twofish_enc_blk_3way(struct twofish_ctx *ctx, u8 *dst,
63 const u8 *src) 49 const u8 *src)
64{ 50{
65 __twofish_enc_blk_3way(ctx, dst, src, false); 51 __twofish_enc_blk_3way(ctx, dst, src, false);
66} 52}
67 53
68static inline void twofish_enc_blk_3way_xor(struct twofish_ctx *ctx, u8 *dst,
69 const u8 *src)
70{
71 __twofish_enc_blk_3way(ctx, dst, src, true);
72}
73
74/* 8-way parallel cipher functions */ 54/* 8-way parallel cipher functions */
75asmlinkage void __twofish_enc_blk_8way(struct twofish_ctx *ctx, u8 *dst, 55asmlinkage void __twofish_enc_blk_8way(struct twofish_ctx *ctx, u8 *dst,
76 const u8 *src, bool xor); 56 const u8 *src, bool xor);
@@ -95,423 +75,142 @@ static inline void twofish_dec_blk_xway(struct twofish_ctx *ctx, u8 *dst,
95 twofish_dec_blk_8way(ctx, dst, src); 75 twofish_dec_blk_8way(ctx, dst, src);
96} 76}
97 77
98 78static void twofish_dec_blk_cbc_xway(void *ctx, u128 *dst, const u128 *src)
99static inline bool twofish_fpu_begin(bool fpu_enabled, unsigned int nbytes)
100{ 79{
101 if (fpu_enabled) 80 u128 ivs[TWOFISH_PARALLEL_BLOCKS - 1];
102 return true; 81 unsigned int j;
103 82
104 /* AVX is only used when chunk to be processed is large enough, so 83 for (j = 0; j < TWOFISH_PARALLEL_BLOCKS - 1; j++)
105 * do not enable FPU until it is necessary. 84 ivs[j] = src[j];
106 */
107 if (nbytes < TF_BLOCK_SIZE * TWOFISH_PARALLEL_BLOCKS)
108 return false;
109 85
110 kernel_fpu_begin(); 86 twofish_dec_blk_xway(ctx, (u8 *)dst, (u8 *)src);
111 return true;
112}
113 87
114static inline void twofish_fpu_end(bool fpu_enabled) 88 for (j = 0; j < TWOFISH_PARALLEL_BLOCKS - 1; j++)
115{ 89 u128_xor(dst + (j + 1), dst + (j + 1), ivs + j);
116 if (fpu_enabled)
117 kernel_fpu_end();
118} 90}
119 91
120static int ecb_crypt(struct blkcipher_desc *desc, struct blkcipher_walk *walk, 92static void twofish_enc_blk_ctr_xway(void *ctx, u128 *dst, const u128 *src,
121 bool enc) 93 u128 *iv)
122{ 94{
123 bool fpu_enabled = false; 95 be128 ctrblks[TWOFISH_PARALLEL_BLOCKS];
124 struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); 96 unsigned int i;
125 const unsigned int bsize = TF_BLOCK_SIZE;
126 unsigned int nbytes;
127 int err;
128 97
129 err = blkcipher_walk_virt(desc, walk); 98 for (i = 0; i < TWOFISH_PARALLEL_BLOCKS; i++) {
130 desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; 99 if (dst != src)
100 dst[i] = src[i];
131 101
132 while ((nbytes = walk->nbytes)) { 102 u128_to_be128(&ctrblks[i], iv);
133 u8 *wsrc = walk->src.virt.addr; 103 u128_inc(iv);
134 u8 *wdst = walk->dst.virt.addr;
135
136 fpu_enabled = twofish_fpu_begin(fpu_enabled, nbytes);
137
138 /* Process multi-block batch */
139 if (nbytes >= bsize * TWOFISH_PARALLEL_BLOCKS) {
140 do {
141 if (enc)
142 twofish_enc_blk_xway(ctx, wdst, wsrc);
143 else
144 twofish_dec_blk_xway(ctx, wdst, wsrc);
145
146 wsrc += bsize * TWOFISH_PARALLEL_BLOCKS;
147 wdst += bsize * TWOFISH_PARALLEL_BLOCKS;
148 nbytes -= bsize * TWOFISH_PARALLEL_BLOCKS;
149 } while (nbytes >= bsize * TWOFISH_PARALLEL_BLOCKS);
150
151 if (nbytes < bsize)
152 goto done;
153 }
154
155 /* Process three block batch */
156 if (nbytes >= bsize * 3) {
157 do {
158 if (enc)
159 twofish_enc_blk_3way(ctx, wdst, wsrc);
160 else
161 twofish_dec_blk_3way(ctx, wdst, wsrc);
162
163 wsrc += bsize * 3;
164 wdst += bsize * 3;
165 nbytes -= bsize * 3;
166 } while (nbytes >= bsize * 3);
167
168 if (nbytes < bsize)
169 goto done;
170 }
171
172 /* Handle leftovers */
173 do {
174 if (enc)
175 twofish_enc_blk(ctx, wdst, wsrc);
176 else
177 twofish_dec_blk(ctx, wdst, wsrc);
178
179 wsrc += bsize;
180 wdst += bsize;
181 nbytes -= bsize;
182 } while (nbytes >= bsize);
183
184done:
185 err = blkcipher_walk_done(desc, walk, nbytes);
186 } 104 }
187 105
188 twofish_fpu_end(fpu_enabled); 106 twofish_enc_blk_xway_xor(ctx, (u8 *)dst, (u8 *)ctrblks);
189 return err;
190} 107}
191 108
109static const struct common_glue_ctx twofish_enc = {
110 .num_funcs = 3,
111 .fpu_blocks_limit = TWOFISH_PARALLEL_BLOCKS,
112
113 .funcs = { {
114 .num_blocks = TWOFISH_PARALLEL_BLOCKS,
115 .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_enc_blk_xway) }
116 }, {
117 .num_blocks = 3,
118 .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_enc_blk_3way) }
119 }, {