aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJussi Kivilinna <jussi.kivilinna@mbnet.fi>2012-06-18 07:07:34 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2012-06-27 02:42:02 -0400
commit414cb5e7cc6e258fe36e2c3cc3ef1ff2e246c0e3 (patch)
treebce5793f8d0e9791ea60d09192d74b482b9a6cfd
parent964263afdcbf9d1e85c021acfff0cc68dd168475 (diff)
crypto: twofish-x86_64-3way - remove duplicated glue code and use shared glue code from glue_helper
Now that shared glue code is available, convert twofish-x86_64-3way to use it. 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_glue_3way.c365
-rw-r--r--crypto/Kconfig1
2 files changed, 94 insertions, 272 deletions
diff --git a/arch/x86/crypto/twofish_glue_3way.c b/arch/x86/crypto/twofish_glue_3way.c
index 77e4e55a2660..25bf5e9b0067 100644
--- a/arch/x86/crypto/twofish_glue_3way.c
+++ b/arch/x86/crypto/twofish_glue_3way.c
@@ -3,11 +3,6 @@
3 * 3 *
4 * Copyright (c) 2011 Jussi Kivilinna <jussi.kivilinna@mbnet.fi> 4 * Copyright (c) 2011 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
5 * 5 *
6 * CBC & ECB parts based on code (crypto/cbc.c,ecb.c) by:
7 * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
8 * CTR part based on code (crypto/ctr.c) by:
9 * (C) Copyright IBM Corp. 2007 - Joy Latten <latten@us.ibm.com>
10 *
11 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or 8 * the Free Software Foundation; either version 2 of the License, or
@@ -33,6 +28,7 @@
33#include <crypto/algapi.h> 28#include <crypto/algapi.h>
34#include <crypto/twofish.h> 29#include <crypto/twofish.h>
35#include <crypto/b128ops.h> 30#include <crypto/b128ops.h>
31#include <asm/crypto/glue_helper.h>
36#include <crypto/lrw.h> 32#include <crypto/lrw.h>
37#include <crypto/xts.h> 33#include <crypto/xts.h>
38 34
@@ -62,311 +58,136 @@ static inline void twofish_enc_blk_xor_3way(struct twofish_ctx *ctx, u8 *dst,
62 __twofish_enc_blk_3way(ctx, dst, src, true); 58 __twofish_enc_blk_3way(ctx, dst, src, true);
63} 59}
64 60
65static int ecb_crypt(struct blkcipher_desc *desc, struct blkcipher_walk *walk, 61static void twofish_dec_blk_cbc_3way(void *ctx, u128 *dst, const u128 *src)
66 void (*fn)(struct twofish_ctx *, u8 *, const u8 *),
67 void (*fn_3way)(struct twofish_ctx *, u8 *, const u8 *))
68{ 62{
69 struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); 63 u128 ivs[2];
70 unsigned int bsize = TF_BLOCK_SIZE;
71 unsigned int nbytes;
72 int err;
73
74 err = blkcipher_walk_virt(desc, walk);
75
76 while ((nbytes = walk->nbytes)) {
77 u8 *wsrc = walk->src.virt.addr;
78 u8 *wdst = walk->dst.virt.addr;
79
80 /* Process three block batch */
81 if (nbytes >= bsize * 3) {
82 do {
83 fn_3way(ctx, wdst, wsrc);
84 64
85 wsrc += bsize * 3; 65 ivs[0] = src[0];
86 wdst += bsize * 3; 66 ivs[1] = src[1];
87 nbytes -= bsize * 3;
88 } while (nbytes >= bsize * 3);
89 67
90 if (nbytes < bsize) 68 twofish_dec_blk_3way(ctx, (u8 *)dst, (u8 *)src);
91 goto done;
92 }
93
94 /* Handle leftovers */
95 do {
96 fn(ctx, wdst, wsrc);
97
98 wsrc += bsize;
99 wdst += bsize;
100 nbytes -= bsize;
101 } while (nbytes >= bsize);
102
103done:
104 err = blkcipher_walk_done(desc, walk, nbytes);
105 }
106 69
107 return err; 70 u128_xor(&dst[1], &dst[1], &ivs[0]);
71 u128_xor(&dst[2], &dst[2], &ivs[1]);
108} 72}
109 73
110static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, 74static void twofish_enc_blk_ctr(void *ctx, u128 *dst, const u128 *src, u128 *iv)
111 struct scatterlist *src, unsigned int nbytes)
112{ 75{
113 struct blkcipher_walk walk; 76 be128 ctrblk;
114 77
115 blkcipher_walk_init(&walk, dst, src, nbytes); 78 if (dst != src)
116 return ecb_crypt(desc, &walk, twofish_enc_blk, twofish_enc_blk_3way); 79 *dst = *src;
117}
118 80
119static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, 81 u128_to_be128(&ctrblk, iv);
120 struct scatterlist *src, unsigned int nbytes) 82 u128_inc(iv);
121{
122 struct blkcipher_walk walk;
123 83
124 blkcipher_walk_init(&walk, dst, src, nbytes); 84 twofish_enc_blk(ctx, (u8 *)&ctrblk, (u8 *)&ctrblk);
125 return ecb_crypt(desc, &walk, twofish_dec_blk, twofish_dec_blk_3way); 85 u128_xor(dst, dst, (u128 *)&ctrblk);
126} 86}
127 87
128static unsigned int __cbc_encrypt(struct blkcipher_desc *desc, 88static void twofish_enc_blk_ctr_3way(void *ctx, u128 *dst, const u128 *src,
129 struct blkcipher_walk *walk) 89 u128 *iv)
130{ 90{
131 struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); 91 be128 ctrblks[3];
132 unsigned int bsize = TF_BLOCK_SIZE;
133 unsigned int nbytes = walk->nbytes;
134 u128 *src = (u128 *)walk->src.virt.addr;
135 u128 *dst = (u128 *)walk->dst.virt.addr;
136 u128 *iv = (u128 *)walk->iv;
137
138 do {
139 u128_xor(dst, src, iv);
140 twofish_enc_blk(ctx, (u8 *)dst, (u8 *)dst);
141 iv = dst;
142
143 src += 1;
144 dst += 1;
145 nbytes -= bsize;
146 } while (nbytes >= bsize);
147
148 u128_xor((u128 *)walk->iv, (u128 *)walk->iv, iv);
149 return nbytes;
150}
151 92
152static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, 93 if (dst != src) {
153 struct scatterlist *src, unsigned int nbytes) 94 dst[0] = src[0];
154{ 95 dst[1] = src[1];
155 struct blkcipher_walk walk; 96 dst[2] = src[2];
156 int err;
157
158 blkcipher_walk_init(&walk, dst, src, nbytes);
159 err = blkcipher_walk_virt(desc, &walk);
160
161 while ((nbytes = walk.nbytes)) {
162 nbytes = __cbc_encrypt(desc, &walk);
163 err = blkcipher_walk_done(desc, &walk, nbytes);
164 }
165
166 return err;
167}
168
169static unsigned int __cbc_decrypt(struct blkcipher_desc *desc,
170 struct blkcipher_walk *walk)
171{
172 struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
173 unsigned int bsize = TF_BLOCK_SIZE;
174 unsigned int nbytes = walk->nbytes;
175 u128 *src = (u128 *)walk->src.virt.addr;
176 u128 *dst = (u128 *)walk->dst.virt.addr;
177 u128 ivs[3 - 1];
178 u128 last_iv;
179
180 /* Start of the last block. */
181 src += nbytes / bsize - 1;
182 dst += nbytes / bsize - 1;
183
184 last_iv = *src;
185
186 /* Process three block batch */
187 if (nbytes >= bsize * 3) {
188 do {
189 nbytes -= bsize * (3 - 1);
190 src -= 3 - 1;
191 dst -= 3 - 1;
192
193 ivs[0] = src[0];
194 ivs[1] = src[1];
195
196 twofish_dec_blk_3way(ctx, (u8 *)dst, (u8 *)src);
197
198 u128_xor(dst + 1, dst + 1, ivs + 0);
199 u128_xor(dst + 2, dst + 2, ivs + 1);
200
201 nbytes -= bsize;
202 if (nbytes < bsize)
203 goto done;
204
205 u128_xor(dst, dst, src - 1);