Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

crypto: ahash - Only save callback and data in ahash_save_req

As unaligned operations are supported by the underlying algorithm,
ahash_save_req and ahash_restore_req can be greatly simplified to
only preserve the callback and data.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

+35 -65
+35 -62
crypto/ahash.c
··· 41 41 struct scatterlist *sg; 42 42 }; 43 43 44 + struct ahash_save_req_state { 45 + struct ahash_request *req; 46 + crypto_completion_t compl; 47 + void *data; 48 + }; 49 + 44 50 static int hash_walk_next(struct crypto_hash_walk *walk) 45 51 { 46 52 unsigned int offset = walk->offset; ··· 285 279 } 286 280 EXPORT_SYMBOL_GPL(crypto_ahash_init); 287 281 288 - static int ahash_save_req(struct ahash_request *req, crypto_completion_t cplt, 289 - bool has_state) 282 + static int ahash_save_req(struct ahash_request *req, crypto_completion_t cplt) 290 283 { 291 - struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); 292 - unsigned int ds = crypto_ahash_digestsize(tfm); 293 - struct ahash_request *subreq; 294 - unsigned int subreq_size; 295 - unsigned int reqsize; 296 - u8 *result; 284 + struct ahash_save_req_state *state; 297 285 gfp_t gfp; 298 286 u32 flags; 299 287 300 - subreq_size = sizeof(*subreq); 301 - reqsize = crypto_ahash_reqsize(tfm); 302 - reqsize = ALIGN(reqsize, crypto_tfm_ctx_alignment()); 303 - subreq_size += reqsize; 304 - subreq_size += ds; 305 - 306 288 flags = ahash_request_flags(req); 307 289 gfp = (flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? GFP_KERNEL : GFP_ATOMIC; 308 - subreq = kmalloc(subreq_size, gfp); 309 - if (!subreq) 290 + state = kmalloc(sizeof(*state), gfp); 291 + if (!state) 310 292 return -ENOMEM; 311 293 312 - ahash_request_set_tfm(subreq, tfm); 313 - ahash_request_set_callback(subreq, flags, cplt, req); 314 - 315 - result = (u8 *)(subreq + 1) + reqsize; 316 - 317 - ahash_request_set_crypt(subreq, req->src, result, req->nbytes); 318 - 319 - if (has_state) { 320 - void *state; 321 - 322 - state = kmalloc(crypto_ahash_statesize(tfm), gfp); 323 - if (!state) { 324 - kfree(subreq); 325 - return -ENOMEM; 326 - } 327 - 328 - crypto_ahash_export(req, state); 329 - crypto_ahash_import(subreq, state); 330 - kfree_sensitive(state); 331 - } 332 - 333 - req->priv = subreq; 294 + state->compl = req->base.complete; 295 + state->data = req->base.data; 296 + req->base.complete = cplt; 297 + req->base.data = state; 298 + state->req = req; 334 299 335 300 return 0; 336 301 } 337 302 338 - static void ahash_restore_req(struct ahash_request *req, int err) 303 + static void ahash_restore_req(struct ahash_request *req) 339 304 { 340 - struct ahash_request *subreq = req->priv; 305 + struct ahash_save_req_state *state = req->base.data; 341 306 342 - if (!err) 343 - memcpy(req->result, subreq->result, 344 - crypto_ahash_digestsize(crypto_ahash_reqtfm(req))); 345 - 346 - req->priv = NULL; 347 - 348 - kfree_sensitive(subreq); 307 + req->base.complete = state->compl; 308 + req->base.data = state->data; 309 + kfree(state); 349 310 } 350 311 351 312 int crypto_ahash_update(struct ahash_request *req) ··· 364 391 365 392 static void ahash_def_finup_done2(void *data, int err) 366 393 { 367 - struct ahash_request *areq = data; 394 + struct ahash_save_req_state *state = data; 395 + struct ahash_request *areq = state->req; 368 396 369 397 if (err == -EINPROGRESS) 370 398 return; 371 399 372 - ahash_restore_req(areq, err); 373 - 400 + ahash_restore_req(areq); 374 401 ahash_request_complete(areq, err); 375 402 } 376 403 377 404 static int ahash_def_finup_finish1(struct ahash_request *req, int err) 378 405 { 379 - struct ahash_request *subreq = req->priv; 380 - 381 406 if (err) 382 407 goto out; 383 408 384 - subreq->base.complete = ahash_def_finup_done2; 409 + req->base.complete = ahash_def_finup_done2; 385 410 386 - err = crypto_ahash_alg(crypto_ahash_reqtfm(req))->final(subreq); 411 + err = crypto_ahash_alg(crypto_ahash_reqtfm(req))->final(req); 387 412 if (err == -EINPROGRESS || err == -EBUSY) 388 413 return err; 389 414 390 415 out: 391 - ahash_restore_req(req, err); 416 + ahash_restore_req(req); 392 417 return err; 393 418 } 394 419 395 420 static void ahash_def_finup_done1(void *data, int err) 396 421 { 397 - struct ahash_request *areq = data; 398 - struct ahash_request *subreq; 422 + struct ahash_save_req_state *state0 = data; 423 + struct ahash_save_req_state state; 424 + struct ahash_request *areq; 399 425 426 + state = *state0; 427 + areq = state.req; 400 428 if (err == -EINPROGRESS) 401 429 goto out; 402 430 403 - subreq = areq->priv; 404 - subreq->base.flags &= CRYPTO_TFM_REQ_MAY_BACKLOG; 431 + areq->base.flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; 405 432 406 433 err = ahash_def_finup_finish1(areq, err); 407 434 if (err == -EINPROGRESS || err == -EBUSY) 408 435 return; 409 436 410 437 out: 411 - ahash_request_complete(areq, err); 438 + state.compl(state.data, err); 412 439 } 413 440 414 441 static int ahash_def_finup(struct ahash_request *req) ··· 416 443 struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); 417 444 int err; 418 445 419 - err = ahash_save_req(req, ahash_def_finup_done1, true); 446 + err = ahash_save_req(req, ahash_def_finup_done1); 420 447 if (err) 421 448 return err; 422 449 423 - err = crypto_ahash_alg(tfm)->update(req->priv); 450 + err = crypto_ahash_alg(tfm)->update(req); 424 451 if (err == -EINPROGRESS || err == -EBUSY) 425 452 return err; 426 453
-3
include/crypto/hash.h
··· 55 55 struct scatterlist *src; 56 56 u8 *result; 57 57 58 - /* This field may only be used by the ahash API code. */ 59 - void *priv; 60 - 61 58 void *__ctx[] CRYPTO_MINALIGN_ATTR; 62 59 }; 63 60