aboutsummaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2009-01-12 19:26:18 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2009-01-14 23:33:49 -0500
commit29b37f42127f7da511560a40ea74f5047da40c13 (patch)
treefa6cbeb329cc0d564511a3bd6f4d7172d468494b /crypto
parent5393f780277165f282a37ed82dd878159ec9dad5 (diff)
crypto: authenc - Fix zero-length IV crash
As it is if an algorithm with a zero-length IV is used (e.g., NULL encryption) with authenc, authenc may generate an SG entry of length zero, which will trigger a BUG check in the hash layer. This patch fixes it by skipping the IV SG generation if the IV size is zero. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto')
-rw-r--r--crypto/authenc.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/crypto/authenc.c b/crypto/authenc.c
index 40b6e9ec9e3a..5793b64c81a8 100644
--- a/crypto/authenc.c
+++ b/crypto/authenc.c
@@ -158,16 +158,19 @@ static int crypto_authenc_genicv(struct aead_request *req, u8 *iv,
158 dstp = sg_page(dst); 158 dstp = sg_page(dst);
159 vdst = PageHighMem(dstp) ? NULL : page_address(dstp) + dst->offset; 159 vdst = PageHighMem(dstp) ? NULL : page_address(dstp) + dst->offset;
160 160
161 sg_init_table(cipher, 2); 161 if (ivsize) {
162 sg_set_buf(cipher, iv, ivsize); 162 sg_init_table(cipher, 2);
163 authenc_chain(cipher, dst, vdst == iv + ivsize); 163 sg_set_buf(cipher, iv, ivsize);
164 authenc_chain(cipher, dst, vdst == iv + ivsize);
165 dst = cipher;
166 }
164 167
165 cryptlen = req->cryptlen + ivsize; 168 cryptlen = req->cryptlen + ivsize;
166 hash = crypto_authenc_hash(req, flags, cipher, cryptlen); 169 hash = crypto_authenc_hash(req, flags, dst, cryptlen);
167 if (IS_ERR(hash)) 170 if (IS_ERR(hash))
168 return PTR_ERR(hash); 171 return PTR_ERR(hash);
169 172
170 scatterwalk_map_and_copy(hash, cipher, cryptlen, 173 scatterwalk_map_and_copy(hash, dst, cryptlen,
171 crypto_aead_authsize(authenc), 1); 174 crypto_aead_authsize(authenc), 1);
172 return 0; 175 return 0;
173} 176}
@@ -285,11 +288,14 @@ static int crypto_authenc_iverify(struct aead_request *req, u8 *iv,
285 srcp = sg_page(src); 288 srcp = sg_page(src);
286 vsrc = PageHighMem(srcp) ? NULL : page_address(srcp) + src->offset; 289 vsrc = PageHighMem(srcp) ? NULL : page_address(srcp) + src->offset;
287 290
288 sg_init_table(cipher, 2); 291 if (ivsize) {
289 sg_set_buf(cipher, iv, ivsize); 292 sg_init_table(cipher, 2);
290 authenc_chain(cipher, src, vsrc == iv + ivsize); 293 sg_set_buf(cipher, iv, ivsize);
294 authenc_chain(cipher, src, vsrc == iv + ivsize);
295 src = cipher;
296 }
291 297
292 return crypto_authenc_verify(req, cipher, cryptlen + ivsize); 298 return crypto_authenc_verify(req, src, cryptlen + ivsize);
293} 299}
294 300
295static int crypto_authenc_decrypt(struct aead_request *req) 301static int crypto_authenc_decrypt(struct aead_request *req)