2007-12-02 07:53:13

by Herbert Xu

[permalink] [raw]
Subject: [PATCH 4/4] [CRYPTO] authenc: Fix hash verification

[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 <[email protected]>
---

crypto/authenc.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/crypto/authenc.c b/crypto/authenc.c
--- a/crypto/authenc.c
+++ b/crypto/authenc.c
@@ -174,6 +174,11 @@ static int crypto_authenc_verify(struct
unsigned int authsize;
int err;

+ authsize = crypto_aead_authsize(authenc);
+ if (cryptlen < authsize)
+ return -EINVAL;
+ cryptlen -= authsize;
+
ohash = (u8 *)ALIGN((unsigned long)ohash + crypto_hash_alignmask(auth),
crypto_hash_alignmask(auth) + 1);
ihash = ohash + crypto_hash_digestsize(auth);
@@ -198,7 +203,6 @@ auth_unlock:
if (err)
return err;

- authsize = crypto_aead_authsize(authenc);
scatterwalk_map_and_copy(ihash, src, cryptlen, authsize, 0);
return memcmp(ihash, ohash, authsize) ? -EINVAL : 0;
}


2007-12-05 01:06:10

by Herbert Xu

[permalink] [raw]
Subject: Re: [PATCH 4/4] [CRYPTO] authenc: Fix hash verification

On Sun, Dec 02, 2007 at 06:53:11PM +1100, Herbert Xu wrote:
> [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 <[email protected]>

Heh that fix was incomplete since we need to exclude the ICV from
decryption too. Here's the corrected version.

Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
59e9d637797c1466bf86c5ac67140cee5f023c2e
diff --git a/crypto/authenc.c b/crypto/authenc.c
index a61dea1..82e03ff 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);