Commit 62c5593aea4b71d61dc0f37fea96c556c158a042
Committed by
Herbert Xu
1 parent
e8edb3cbd7
Exists in
master
and in
7 other branches
crypto: gcm - fix another complete call in complete fuction
The flow of the complete function (xxx_done) in gcm.c is as follow: void complete(struct crypto_async_request *areq, int err) { struct aead_request *req = areq->data; if (!err) { err = async_next_step(); if (err == -EINPROGRESS || err == -EBUSY) return; } complete_for_next_step(areq, err); } But *areq may be destroyed in async_next_step(), this makes complete_for_next_step() can not work properly. To fix this, one of following methods is used for each complete function. - Add a __complete() for each complete(), which accept struct aead_request *req instead of areq, so avoid using areq after it is destroyed. - Expand complete_for_next_step(). The fixing method is based on the idea of Herbert Xu. Signed-off-by: Huang Ying <ying.huang@intel.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Showing 1 changed file with 73 additions and 34 deletions Side-by-side Diff
crypto/gcm.c
... | ... | @@ -40,7 +40,7 @@ |
40 | 40 | struct crypto_gcm_ghash_ctx { |
41 | 41 | unsigned int cryptlen; |
42 | 42 | struct scatterlist *src; |
43 | - crypto_completion_t complete; | |
43 | + void (*complete)(struct aead_request *req, int err); | |
44 | 44 | }; |
45 | 45 | |
46 | 46 | struct crypto_gcm_req_priv_ctx { |
47 | 47 | |
48 | 48 | |
49 | 49 | |
50 | 50 | |
... | ... | @@ -267,23 +267,26 @@ |
267 | 267 | return crypto_ahash_final(ahreq); |
268 | 268 | } |
269 | 269 | |
270 | -static void gcm_hash_final_done(struct crypto_async_request *areq, | |
271 | - int err) | |
270 | +static void __gcm_hash_final_done(struct aead_request *req, int err) | |
272 | 271 | { |
273 | - struct aead_request *req = areq->data; | |
274 | 272 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
275 | 273 | struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx; |
276 | 274 | |
277 | 275 | if (!err) |
278 | 276 | crypto_xor(pctx->auth_tag, pctx->iauth_tag, 16); |
279 | 277 | |
280 | - gctx->complete(areq, err); | |
278 | + gctx->complete(req, err); | |
281 | 279 | } |
282 | 280 | |
283 | -static void gcm_hash_len_done(struct crypto_async_request *areq, | |
284 | - int err) | |
281 | +static void gcm_hash_final_done(struct crypto_async_request *areq, int err) | |
285 | 282 | { |
286 | 283 | struct aead_request *req = areq->data; |
284 | + | |
285 | + __gcm_hash_final_done(req, err); | |
286 | +} | |
287 | + | |
288 | +static void __gcm_hash_len_done(struct aead_request *req, int err) | |
289 | +{ | |
287 | 290 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
288 | 291 | |
289 | 292 | if (!err) { |
290 | 293 | |
291 | 294 | |
... | ... | @@ -292,13 +295,18 @@ |
292 | 295 | return; |
293 | 296 | } |
294 | 297 | |
295 | - gcm_hash_final_done(areq, err); | |
298 | + __gcm_hash_final_done(req, err); | |
296 | 299 | } |
297 | 300 | |
298 | -static void gcm_hash_crypt_remain_done(struct crypto_async_request *areq, | |
299 | - int err) | |
301 | +static void gcm_hash_len_done(struct crypto_async_request *areq, int err) | |
300 | 302 | { |
301 | 303 | struct aead_request *req = areq->data; |
304 | + | |
305 | + __gcm_hash_len_done(req, err); | |
306 | +} | |
307 | + | |
308 | +static void __gcm_hash_crypt_remain_done(struct aead_request *req, int err) | |
309 | +{ | |
302 | 310 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
303 | 311 | |
304 | 312 | if (!err) { |
305 | 313 | |
306 | 314 | |
... | ... | @@ -307,13 +315,19 @@ |
307 | 315 | return; |
308 | 316 | } |
309 | 317 | |
310 | - gcm_hash_len_done(areq, err); | |
318 | + __gcm_hash_len_done(req, err); | |
311 | 319 | } |
312 | 320 | |
313 | -static void gcm_hash_crypt_done(struct crypto_async_request *areq, | |
314 | - int err) | |
321 | +static void gcm_hash_crypt_remain_done(struct crypto_async_request *areq, | |
322 | + int err) | |
315 | 323 | { |
316 | 324 | struct aead_request *req = areq->data; |
325 | + | |
326 | + __gcm_hash_crypt_remain_done(req, err); | |
327 | +} | |
328 | + | |
329 | +static void __gcm_hash_crypt_done(struct aead_request *req, int err) | |
330 | +{ | |
317 | 331 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
318 | 332 | struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx; |
319 | 333 | unsigned int remain; |
320 | 334 | |
321 | 335 | |
... | ... | @@ -327,13 +341,18 @@ |
327 | 341 | return; |
328 | 342 | } |
329 | 343 | |
330 | - gcm_hash_crypt_remain_done(areq, err); | |
344 | + __gcm_hash_crypt_remain_done(req, err); | |
331 | 345 | } |
332 | 346 | |
333 | -static void gcm_hash_assoc_remain_done(struct crypto_async_request *areq, | |
334 | - int err) | |
347 | +static void gcm_hash_crypt_done(struct crypto_async_request *areq, int err) | |
335 | 348 | { |
336 | 349 | struct aead_request *req = areq->data; |
350 | + | |
351 | + __gcm_hash_crypt_done(req, err); | |
352 | +} | |
353 | + | |
354 | +static void __gcm_hash_assoc_remain_done(struct aead_request *req, int err) | |
355 | +{ | |
337 | 356 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
338 | 357 | struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx; |
339 | 358 | crypto_completion_t complete; |
340 | 359 | |
341 | 360 | |
342 | 361 | |
... | ... | @@ -350,15 +369,21 @@ |
350 | 369 | } |
351 | 370 | |
352 | 371 | if (remain) |
353 | - gcm_hash_crypt_done(areq, err); | |
372 | + __gcm_hash_crypt_done(req, err); | |
354 | 373 | else |
355 | - gcm_hash_crypt_remain_done(areq, err); | |
374 | + __gcm_hash_crypt_remain_done(req, err); | |
356 | 375 | } |
357 | 376 | |
358 | -static void gcm_hash_assoc_done(struct crypto_async_request *areq, | |
359 | - int err) | |
377 | +static void gcm_hash_assoc_remain_done(struct crypto_async_request *areq, | |
378 | + int err) | |
360 | 379 | { |
361 | 380 | struct aead_request *req = areq->data; |
381 | + | |
382 | + __gcm_hash_assoc_remain_done(req, err); | |
383 | +} | |
384 | + | |
385 | +static void __gcm_hash_assoc_done(struct aead_request *req, int err) | |
386 | +{ | |
362 | 387 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
363 | 388 | unsigned int remain; |
364 | 389 | |
365 | 390 | |
366 | 391 | |
... | ... | @@ -371,13 +396,18 @@ |
371 | 396 | return; |
372 | 397 | } |
373 | 398 | |
374 | - gcm_hash_assoc_remain_done(areq, err); | |
399 | + __gcm_hash_assoc_remain_done(req, err); | |
375 | 400 | } |
376 | 401 | |
377 | -static void gcm_hash_init_done(struct crypto_async_request *areq, | |
378 | - int err) | |
402 | +static void gcm_hash_assoc_done(struct crypto_async_request *areq, int err) | |
379 | 403 | { |
380 | 404 | struct aead_request *req = areq->data; |
405 | + | |
406 | + __gcm_hash_assoc_done(req, err); | |
407 | +} | |
408 | + | |
409 | +static void __gcm_hash_init_done(struct aead_request *req, int err) | |
410 | +{ | |
381 | 411 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
382 | 412 | crypto_completion_t complete; |
383 | 413 | unsigned int remain = 0; |
384 | 414 | |
385 | 415 | |
... | ... | @@ -393,11 +423,18 @@ |
393 | 423 | } |
394 | 424 | |
395 | 425 | if (remain) |
396 | - gcm_hash_assoc_done(areq, err); | |
426 | + __gcm_hash_assoc_done(req, err); | |
397 | 427 | else |
398 | - gcm_hash_assoc_remain_done(areq, err); | |
428 | + __gcm_hash_assoc_remain_done(req, err); | |
399 | 429 | } |
400 | 430 | |
431 | +static void gcm_hash_init_done(struct crypto_async_request *areq, int err) | |
432 | +{ | |
433 | + struct aead_request *req = areq->data; | |
434 | + | |
435 | + __gcm_hash_init_done(req, err); | |
436 | +} | |
437 | + | |
401 | 438 | static int gcm_hash(struct aead_request *req, |
402 | 439 | struct crypto_gcm_req_priv_ctx *pctx) |
403 | 440 | { |
404 | 441 | |
... | ... | @@ -457,10 +494,8 @@ |
457 | 494 | crypto_aead_authsize(aead), 1); |
458 | 495 | } |
459 | 496 | |
460 | -static void gcm_enc_hash_done(struct crypto_async_request *areq, | |
461 | - int err) | |
497 | +static void gcm_enc_hash_done(struct aead_request *req, int err) | |
462 | 498 | { |
463 | - struct aead_request *req = areq->data; | |
464 | 499 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
465 | 500 | |
466 | 501 | if (!err) |
... | ... | @@ -469,8 +504,7 @@ |
469 | 504 | aead_request_complete(req, err); |
470 | 505 | } |
471 | 506 | |
472 | -static void gcm_encrypt_done(struct crypto_async_request *areq, | |
473 | - int err) | |
507 | +static void gcm_encrypt_done(struct crypto_async_request *areq, int err) | |
474 | 508 | { |
475 | 509 | struct aead_request *req = areq->data; |
476 | 510 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
477 | 511 | |
... | ... | @@ -479,9 +513,13 @@ |
479 | 513 | err = gcm_hash(req, pctx); |
480 | 514 | if (err == -EINPROGRESS || err == -EBUSY) |
481 | 515 | return; |
516 | + else if (!err) { | |
517 | + crypto_xor(pctx->auth_tag, pctx->iauth_tag, 16); | |
518 | + gcm_enc_copy_hash(req, pctx); | |
519 | + } | |
482 | 520 | } |
483 | 521 | |
484 | - gcm_enc_hash_done(areq, err); | |
522 | + aead_request_complete(req, err); | |
485 | 523 | } |
486 | 524 | |
487 | 525 | static int crypto_gcm_encrypt(struct aead_request *req) |
488 | 526 | |
... | ... | @@ -538,9 +576,8 @@ |
538 | 576 | aead_request_complete(req, err); |
539 | 577 | } |
540 | 578 | |
541 | -static void gcm_dec_hash_done(struct crypto_async_request *areq, int err) | |
579 | +static void gcm_dec_hash_done(struct aead_request *req, int err) | |
542 | 580 | { |
543 | - struct aead_request *req = areq->data; | |
544 | 581 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
545 | 582 | struct ablkcipher_request *abreq = &pctx->u.abreq; |
546 | 583 | struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx; |
547 | 584 | |
... | ... | @@ -552,9 +589,11 @@ |
552 | 589 | err = crypto_ablkcipher_decrypt(abreq); |
553 | 590 | if (err == -EINPROGRESS || err == -EBUSY) |
554 | 591 | return; |
592 | + else if (!err) | |
593 | + err = crypto_gcm_verify(req, pctx); | |
555 | 594 | } |
556 | 595 | |
557 | - gcm_decrypt_done(areq, err); | |
596 | + aead_request_complete(req, err); | |
558 | 597 | } |
559 | 598 | |
560 | 599 | static int crypto_gcm_decrypt(struct aead_request *req) |