aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTan Swee Heng <thesweeheng@gmail.com>2007-12-07 03:38:45 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2008-01-10 16:16:34 -0500
commiteb6f13eb9f812f5812ed5d14f241309da369dee6 (patch)
treeeb49b8f64333e9389852dcd99a38279a076150d6
parent7f6813786a6521380e1756ca5b4336bc63c5bf7d (diff)
[CRYPTO] salsa20_generic: Fix multi-page processing
This patch fixes the multi-page processing bug that affects large test vectors (the same bug that previously affected ctr.c). There is an optimization for the case walk.nbytes == nbytes. Also we now use crypto_xor() instead of adhoc XOR routines. Signed-off-by: Tan Swee Heng <thesweeheng@gmail.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--crypto/salsa20_generic.c34
1 files changed, 23 insertions, 11 deletions
diff --git a/crypto/salsa20_generic.c b/crypto/salsa20_generic.c
index b49328afcf0a..1fa4e4ddcab5 100644
--- a/crypto/salsa20_generic.c
+++ b/crypto/salsa20_generic.c
@@ -143,7 +143,6 @@ static void salsa20_encrypt_bytes(struct salsa20_ctx *ctx, u8 *dst,
143 const u8 *src, unsigned int bytes) 143 const u8 *src, unsigned int bytes)
144{ 144{
145 u8 buf[64]; 145 u8 buf[64];
146 int i;
147 146
148 if (dst != src) 147 if (dst != src)
149 memcpy(dst, src, bytes); 148 memcpy(dst, src, bytes);
@@ -156,15 +155,11 @@ static void salsa20_encrypt_bytes(struct salsa20_ctx *ctx, u8 *dst,
156 ctx->input[9] = PLUSONE(ctx->input[9]); 155 ctx->input[9] = PLUSONE(ctx->input[9]);
157 156
158 if (bytes <= 64) { 157 if (bytes <= 64) {
159 for (i = 0; i < bytes/4; ++i) 158 crypto_xor(dst, buf, bytes);
160 ((u32*)dst)[i] ^= ((u32*)buf)[i];
161 for (i = bytes - bytes % 4; i < bytes; ++i)
162 dst[i] ^= buf[i];
163 return; 159 return;
164 } 160 }
165 161
166 for (i = 0; i < 64/4; ++i) 162 crypto_xor(dst, buf, 64);
167 ((u32*)dst)[i] ^= ((u32*)buf)[i];
168 bytes -= 64; 163 bytes -= 64;
169 dst += 64; 164 dst += 64;
170 } 165 }
@@ -192,13 +187,30 @@ static int encrypt(struct blkcipher_desc *desc,
192 int err; 187 int err;
193 188
194 blkcipher_walk_init(&walk, dst, src, nbytes); 189 blkcipher_walk_init(&walk, dst, src, nbytes);
195 err = blkcipher_walk_virt(desc, &walk); 190 err = blkcipher_walk_virt_block(desc, &walk, 64);
196 191
197 salsa20_ivsetup(ctx, walk.iv); 192 salsa20_ivsetup(ctx, walk.iv);
198 salsa20_encrypt_bytes(ctx, walk.dst.virt.addr,
199 walk.src.virt.addr, nbytes);
200 193
201 err = blkcipher_walk_done(desc, &walk, 0); 194 if (likely(walk.nbytes == nbytes))
195 {
196 salsa20_encrypt_bytes(ctx, walk.dst.virt.addr,
197 walk.src.virt.addr, nbytes);
198 return blkcipher_walk_done(desc, &walk, 0);
199 }
200
201 while (walk.nbytes >= 64) {
202 salsa20_encrypt_bytes(ctx, walk.dst.virt.addr,
203 walk.src.virt.addr,
204 walk.nbytes - (walk.nbytes % 64));
205 err = blkcipher_walk_done(desc, &walk, walk.nbytes % 64);
206 }
207
208 if (walk.nbytes) {
209 salsa20_encrypt_bytes(ctx, walk.dst.virt.addr,
210 walk.src.virt.addr, walk.nbytes);
211 err = blkcipher_walk_done(desc, &walk, 0);
212 }
213
202 return err; 214 return err;
203} 215}
204 216