aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/authenc.c
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2007-12-04 04:04:21 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2008-01-10 16:16:30 -0500
commit481f34ae752ac74c4cbd88a9954dd4ed10e84f81 (patch)
tree1c158f9600b189220fb5943b6263750367d10265 /crypto/authenc.c
parente236d4a89a2ffbc8aa18064161f4f159c4d89b4a (diff)
[CRYPTO] authenc: Fix hash verification
The previous code incorrectly included the hash in the verification which also meant that we'd crash and burn when it comes to actually verifying the hash since we'd go past the end of the SG list. This patch fixes that by subtracting authsize from cryptlen at the start. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto/authenc.c')
-rw-r--r--crypto/authenc.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/crypto/authenc.c b/crypto/authenc.c
index a61dea1c2fe6..82e03ffa6245 100644
--- a/crypto/authenc.c
+++ b/crypto/authenc.c
@@ -158,7 +158,8 @@ static int crypto_authenc_encrypt(struct aead_request *req)
158 return crypto_authenc_hash(req); 158 return crypto_authenc_hash(req);
159} 159}
160 160
161static int crypto_authenc_verify(struct aead_request *req) 161static int crypto_authenc_verify(struct aead_request *req,
162 unsigned int cryptlen)
162{ 163{
163 struct crypto_aead *authenc = crypto_aead_reqtfm(req); 164 struct crypto_aead *authenc = crypto_aead_reqtfm(req);
164 struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc); 165 struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
@@ -170,7 +171,6 @@ static int crypto_authenc_verify(struct aead_request *req)
170 u8 *ohash = aead_request_ctx(req); 171 u8 *ohash = aead_request_ctx(req);
171 u8 *ihash; 172 u8 *ihash;
172 struct scatterlist *src = req->src; 173 struct scatterlist *src = req->src;
173 unsigned int cryptlen = req->cryptlen;
174 unsigned int authsize; 174 unsigned int authsize;
175 int err; 175 int err;
176 176
@@ -214,16 +214,22 @@ static int crypto_authenc_decrypt(struct aead_request *req)
214 struct crypto_aead *authenc = crypto_aead_reqtfm(req); 214 struct crypto_aead *authenc = crypto_aead_reqtfm(req);
215 struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc); 215 struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
216 struct ablkcipher_request *abreq = aead_request_ctx(req); 216 struct ablkcipher_request *abreq = aead_request_ctx(req);
217 unsigned int cryptlen = req->cryptlen;
218 unsigned int authsize = crypto_aead_authsize(authenc);
217 int err; 219 int err;
218 220
219 err = crypto_authenc_verify(req); 221 if (cryptlen < authsize)
222 return -EINVAL;
223 cryptlen -= authsize;
224
225 err = crypto_authenc_verify(req, cryptlen);
220 if (err) 226 if (err)
221 return err; 227 return err;
222 228
223 ablkcipher_request_set_tfm(abreq, ctx->enc); 229 ablkcipher_request_set_tfm(abreq, ctx->enc);
224 ablkcipher_request_set_callback(abreq, aead_request_flags(req), 230 ablkcipher_request_set_callback(abreq, aead_request_flags(req),
225 crypto_authenc_decrypt_done, req); 231 crypto_authenc_decrypt_done, req);
226 ablkcipher_request_set_crypt(abreq, req->src, req->dst, req->cryptlen, 232 ablkcipher_request_set_crypt(abreq, req->src, req->dst, cryptlen,
227 req->iv); 233 req->iv);
228 234
229 return crypto_ablkcipher_decrypt(abreq); 235 return crypto_ablkcipher_decrypt(abreq);