Commit 481f34ae752ac74c4cbd88a9954dd4ed10e84f81

Authored by Herbert Xu
1 parent e236d4a89a

[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>

Showing 1 changed file with 10 additions and 4 deletions Side-by-side Diff

... ... @@ -158,7 +158,8 @@
158 158 return crypto_authenc_hash(req);
159 159 }
160 160  
161   -static int crypto_authenc_verify(struct aead_request *req)
  161 +static int crypto_authenc_verify(struct aead_request *req,
  162 + unsigned int cryptlen)
162 163 {
163 164 struct crypto_aead *authenc = crypto_aead_reqtfm(req);
164 165 struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
... ... @@ -170,7 +171,6 @@
170 171 u8 *ohash = aead_request_ctx(req);
171 172 u8 *ihash;
172 173 struct scatterlist *src = req->src;
173   - unsigned int cryptlen = req->cryptlen;
174 174 unsigned int authsize;
175 175 int err;
176 176  
177 177  
178 178  
... ... @@ -214,16 +214,22 @@
214 214 struct crypto_aead *authenc = crypto_aead_reqtfm(req);
215 215 struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
216 216 struct ablkcipher_request *abreq = aead_request_ctx(req);
  217 + unsigned int cryptlen = req->cryptlen;
  218 + unsigned int authsize = crypto_aead_authsize(authenc);
217 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 226 if (err)
221 227 return err;
222 228  
223 229 ablkcipher_request_set_tfm(abreq, ctx->enc);
224 230 ablkcipher_request_set_callback(abreq, aead_request_flags(req),
225 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 233 req->iv);
228 234  
229 235 return crypto_ablkcipher_decrypt(abreq);