aboutsummaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorJoy Latten <latten@austin.ibm.com>2008-04-02 02:36:09 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2008-04-02 02:36:09 -0400
commit1edcf2e1ee2babb011cfca80ad9d202e9c491669 (patch)
treeaaa1f44829044d590d13e1bdf1c3165ed1dbd801 /crypto
parent0e81a8ae37687845f7cdfa2adce14ea6a5f1dd34 (diff)
[CRYPTO] xcbc: Fix crash when ipsec uses xcbc-mac with big data chunk
The kernel crashes when ipsec passes a udp packet of about 14XX bytes of data to aes-xcbc-mac. It seems the first xxxx bytes of the data are in first sg entry, and remaining xx bytes are in next sg entry. But we don't check next sg entry to see if we need to go look the page up. I noticed in hmac.c, we do a scatterwalk_sg_next(), to do this check and possible lookup, thus xcbc.c needs to use this routine too. A 15-hour run of an ipsec stress test sending streams of tcp and udp packets of various sizes, using this patch and aes-xcbc-mac completed successfully, so hopefully this fixes the problem. Signed-off-by: Joy Latten <latten@austin.ibm.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto')
-rw-r--r--crypto/xcbc.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/crypto/xcbc.c b/crypto/xcbc.c
index 2feb0f239c38..b63b633e549c 100644
--- a/crypto/xcbc.c
+++ b/crypto/xcbc.c
@@ -116,13 +116,11 @@ static int crypto_xcbc_digest_update2(struct hash_desc *pdesc,
116 struct crypto_xcbc_ctx *ctx = crypto_hash_ctx_aligned(parent); 116 struct crypto_xcbc_ctx *ctx = crypto_hash_ctx_aligned(parent);
117 struct crypto_cipher *tfm = ctx->child; 117 struct crypto_cipher *tfm = ctx->child;
118 int bs = crypto_hash_blocksize(parent); 118 int bs = crypto_hash_blocksize(parent);
119 unsigned int i = 0;
120 119
121 do { 120 for (;;) {
122 121 struct page *pg = sg_page(sg);
123 struct page *pg = sg_page(&sg[i]); 122 unsigned int offset = sg->offset;
124 unsigned int offset = sg[i].offset; 123 unsigned int slen = sg->length;
125 unsigned int slen = sg[i].length;
126 124
127 if (unlikely(slen > nbytes)) 125 if (unlikely(slen > nbytes))
128 slen = nbytes; 126 slen = nbytes;
@@ -182,8 +180,11 @@ static int crypto_xcbc_digest_update2(struct hash_desc *pdesc,
182 offset = 0; 180 offset = 0;
183 pg++; 181 pg++;
184 } 182 }
185 i++; 183
186 } while (nbytes>0); 184 if (!nbytes)
185 break;
186 sg = scatterwalk_sg_next(sg);
187 }
187 188
188 return 0; 189 return 0;
189} 190}