summaryrefslogtreecommitdiff
path: root/crypto/authenc.c
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2007-12-04 20:04:21 +1100
committerHerbert Xu <herbert@gondor.apana.org.au>2008-01-11 08:16:30 +1100
commit7e676d8b0348623cec6ea62e8d5edd1af2abd8b0 (patch)
tree9d9c68d161ba00eaf2611cf7263645bf35c929de /crypto/authenc.c
parente54956d332fd129de3584fea08112642b1e269a7 (diff)
downloadlinux-crypto-7e676d8b0348623cec6ea62e8d5edd1af2abd8b0.tar.gz
linux-crypto-7e676d8b0348623cec6ea62e8d5edd1af2abd8b0.zip
[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 a61dea1c..82e03ffa 100644
--- a/crypto/authenc.c
+++ b/crypto/authenc.c
@@ -158,7 +158,8 @@ static int crypto_authenc_encrypt(struct aead_request *req)
return crypto_authenc_hash(req);
}
-static int crypto_authenc_verify(struct aead_request *req)
+static int crypto_authenc_verify(struct aead_request *req,
+ unsigned int cryptlen)
{
struct crypto_aead *authenc = crypto_aead_reqtfm(req);
struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
@@ -170,7 +171,6 @@ static int crypto_authenc_verify(struct aead_request *req)
u8 *ohash = aead_request_ctx(req);
u8 *ihash;
struct scatterlist *src = req->src;
- unsigned int cryptlen = req->cryptlen;
unsigned int authsize;
int err;
@@ -214,16 +214,22 @@ static int crypto_authenc_decrypt(struct aead_request *req)
struct crypto_aead *authenc = crypto_aead_reqtfm(req);
struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
struct ablkcipher_request *abreq = aead_request_ctx(req);
+ unsigned int cryptlen = req->cryptlen;
+ unsigned int authsize = crypto_aead_authsize(authenc);
int err;
- err = crypto_authenc_verify(req);
+ if (cryptlen < authsize)
+ return -EINVAL;
+ cryptlen -= authsize;
+
+ err = crypto_authenc_verify(req, cryptlen);
if (err)
return err;
ablkcipher_request_set_tfm(abreq, ctx->enc);
ablkcipher_request_set_callback(abreq, aead_request_flags(req),
crypto_authenc_decrypt_done, req);
- ablkcipher_request_set_crypt(abreq, req->src, req->dst, req->cryptlen,
+ ablkcipher_request_set_crypt(abreq, req->src, req->dst, cryptlen,
req->iv);
return crypto_ablkcipher_decrypt(abreq);